Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
9a5a144
WIP
gordonbrander May 31, 2024
3d58db2
More progress toward cell and stream types
gordonbrander May 31, 2024
3d3f053
Add notes on FRP libs and papers
gordonbrander May 31, 2024
40414f0
More notes
gordonbrander Jun 1, 2024
5d8a679
More notes
gordonbrander Jun 1, 2024
2c92508
More notes
gordonbrander Jun 1, 2024
6880092
Working on read-only signals and computed cells
gordonbrander Jun 2, 2024
1b3db09
Microtask queue-based topological sort
gordonbrander Jun 4, 2024
09689af
More notes
gordonbrander Jun 4, 2024
50a75f3
Simplified impl
gordonbrander Jun 4, 2024
257c227
Remove dead code
gordonbrander Jun 4, 2024
f9c57a3
First pass on transaction-based push-pull FRP
gordonbrander Jun 5, 2024
07fae2c
Update type sig of generateStream
gordonbrander Jun 5, 2024
0d1e2e5
Add typescript overloads for createComputed
gordonbrander Jun 5, 2024
3b0ae76
Better types
gordonbrander Jun 5, 2024
d0541d9
Add separate stream phase to transaction
gordonbrander Jun 5, 2024
32e3799
Clear streams after commit
gordonbrander Jun 5, 2024
897e5f1
Update notes
gordonbrander Jun 6, 2024
7403aec
Add note
gordonbrander Jun 6, 2024
ced4cf5
Add notes
gordonbrander Jun 6, 2024
7574281
Implement signals and streams w separate timelines
gordonbrander Jun 6, 2024
bce9c41
Add pipe and operators
gordonbrander Jun 6, 2024
4df5930
Separate sink/effect from type
gordonbrander Jun 6, 2024
ab6957e
Update notes
gordonbrander Jun 6, 2024
9b7ade8
Add select operator
gordonbrander Jun 6, 2024
ab5531b
Update package
gordonbrander Jun 6, 2024
780fbb6
Update tsconfig
gordonbrander Jun 6, 2024
ad55d54
Fix select operator
gordonbrander Jun 6, 2024
18704d9
Remove index (not used rn)
gordonbrander Jun 6, 2024
9a319a9
Rename publisher
gordonbrander Jun 6, 2024
614e9a8
Merge remote-tracking branch 'origin/main' into 2024-05-30-common-frp
gordonbrander Jun 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add pipe and operators
  • Loading branch information
gordonbrander committed Jun 6, 2024
commit bce9c4136fa0279c4af8b703b8d62d20b37a8ab4
4 changes: 2 additions & 2 deletions sketches/2024-05-30-common-frp/src/dom.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { stream } from './index'
import { createStream } from './stream'

export const events = (
element: HTMLElement,
name: string
) => stream.create((send: (value: Event) => void) => {
) => createStream((send: (value: Event) => void) => {
element.addEventListener(name, send)
return () => element.removeEventListener(name, send)
})
111 changes: 111 additions & 0 deletions sketches/2024-05-30-common-frp/src/operators.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import {
map as mapStream,
filter as filterStream,
zip as zipStreams,
scan as scanStream,
hold as holdStream,
Stream
} from './stream'

export type UnaryFn<A, B> = (a: A) => B

export type Pipe = {
<A, B, C>(
value: A,
a2b: UnaryFn<A, B>,
b2c: UnaryFn<B, C>
): C

<A, B, C, D>(
value: A,
a2b: UnaryFn<A, B>,
b2c: UnaryFn<B, C>,
c2d: UnaryFn<C, D>
): D

<A, B, C, D, E>(
value: A,
a2b: UnaryFn<A, B>,
b2c: UnaryFn<B, C>,
c2d: UnaryFn<C, D>,
d2e: UnaryFn<D, E>
): E

<A, B, C, D, E, F>(
value: A,
a2b: UnaryFn<A, B>,
b2c: UnaryFn<B, C>,
c2d: UnaryFn<C, D>,
d2e: UnaryFn<D, E>,
e2f: UnaryFn<E, F>
): F

<A, B, C, D, E, F, G>(
value: A,
a2b: UnaryFn<A, B>,
b2c: UnaryFn<B, C>,
c2d: UnaryFn<C, D>,
d2e: UnaryFn<D, E>,
e2f: UnaryFn<E, F>,
f2g: UnaryFn<F, G>
): G

<A, B, C, D, E, F, G, H>(
value: A,
a2b: UnaryFn<A, B>,
b2c: UnaryFn<B, C>,
c2d: UnaryFn<C, D>,
d2e: UnaryFn<D, E>,
e2f: UnaryFn<E, F>,
f2g: UnaryFn<F, G>,
g2h: UnaryFn<G, H>
): H

<A, B, C, D, E, F, G, H, I>(
value: A,
a2b: UnaryFn<A, B>,
b2c: UnaryFn<B, C>,
c2d: UnaryFn<C, D>,
d2e: UnaryFn<D, E>,
e2f: UnaryFn<E, F>,
f2g: UnaryFn<F, G>,
g2h: UnaryFn<G, H>,
h2i: UnaryFn<H, I>
): I
}

/** Pipe a value through a series of functions */
export const pipe: Pipe = (
value: any,
...fns: [(value: any) => any]
): any => fns.reduce((value: any, fn: UnaryFn<any, any>) => fn(value), value)

/** Map a stream of values */
export const map = <T, U>(
transform: UnaryFn<T, U>
) => (stream: Stream<T>) => mapStream(stream, transform)

/** Filter a stream of values using a predicate function. */
export const filter = <T>(
predicate: UnaryFn<T, boolean>
) => (stream: Stream<T>) => filterStream(stream, predicate)

/** Scan a stream, accumulating step state in a cell */
export const scan = <T, U>(
step: (state: U, value: T) => U, initial: U
) => (stream: Stream<T>) => scanStream(stream, step, initial)

export const hold = <T>(
initial: T
) => (stream: Stream<T>) => holdStream(stream, initial)

export const zip = <T, U, V>(
right: Stream<U>
) => (
left: Stream<T>,
combine: (left: T, right: U) => V,
) => zipStreams(
left,
right,
combine
)
6 changes: 3 additions & 3 deletions sketches/2024-05-30-common-frp/src/signal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ const sample = <T>(container: Gettable<T>) => container.get()
export type Signal<T> = Gettable<T> & Updates<void> & Sink<T> & Unsubscribable
export type SignalSubject<T> = Gettable<T> & Updates<void> & Sink<T> & Subject<T>

export const create = <T>(initial: T) => {
export const createSignal = <T>(initial: T) => {
const updates = createPublisher<void>()

let state = initial
Expand Down Expand Up @@ -121,7 +121,7 @@ export const create = <T>(initial: T) => {
}
}

export type computed = {
export type createComputed = {
<A, B, Z>(
upstreams: [Signal<A>, Signal<B>],
compute: (a: A, b: B) => Z
Expand Down Expand Up @@ -181,7 +181,7 @@ export type computed = {
): Signal<Z>
}

export const computed: computed = (
export const computed: createComputed = (
upstreams: Array<Signal<any>>,
compute: (...values: Array<any>) => any
): Signal<any> => {
Expand Down
12 changes: 6 additions & 6 deletions sketches/2024-05-30-common-frp/src/stream.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { debug } from "./shared"
import { createPublisher, Send, Cancel, combineCancels } from "./publisher"
import { create as createSignal, Signal, __updates__ } from "./signal"
import { createSignal as createSignal, Signal, __updates__ } from "./signal"

export type Stream<T> = {
sink: (subscriber: Send<T>) => Cancel
cancel?: Cancel
}

export const create = <T>(
export const createStream = <T>(
generate: (send: Send<T>) => Cancel|undefined
): Stream<T> => {
const {pub, sub: sink} = createPublisher<T>()
Expand All @@ -18,14 +18,14 @@ export const create = <T>(
export const map = <T, U>(
stream: Stream<T>,
transform: (value: T) => U
) => create<U>(send => {
) => createStream<U>(send => {
return stream.sink((value: T) => send(transform(value)))
})

export const filter = <T>(
stream: Stream<T>,
predicate: (value: T) => boolean
) => create<T>(send => {
) => createStream<T>(send => {
return stream.sink(value => {
if (predicate(value)) {
send(value)
Expand All @@ -37,7 +37,7 @@ export const zip = <T, U, V>(
left: Stream<T>,
right: Stream<U>,
combine: (left: T, right: U) => V
) => create<V>(send => {
) => createStream<V>(send => {
const leftQueue: Array<T> = []
const rightQueue: Array<U> = []

Expand Down Expand Up @@ -84,6 +84,6 @@ export const scan = <T, U>(
* Hold the latest value from a stream in a cell.
*/
export const hold = <T>(
stream: Signal<T>,
stream: Stream<T>,
initial: T
) => scan(stream, (_, value) => value, initial)