@effectionx/signals 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +119 -0
- package/esm/array.d.ts +44 -0
- package/esm/array.d.ts.map +1 -0
- package/esm/array.js +59 -0
- package/esm/boolean.d.ts +6 -0
- package/esm/boolean.d.ts.map +1 -0
- package/esm/boolean.js +29 -0
- package/esm/helpers.d.ts +10 -0
- package/esm/helpers.d.ts.map +1 -0
- package/esm/helpers.js +20 -0
- package/esm/mod.d.ts +5 -0
- package/esm/mod.d.ts.map +1 -0
- package/esm/mod.js +4 -0
- package/esm/package.json +3 -0
- package/esm/set.d.ts +39 -0
- package/esm/set.d.ts.map +1 -0
- package/esm/set.js +55 -0
- package/esm/types.d.ts +25 -0
- package/esm/types.d.ts.map +1 -0
- package/esm/types.js +1 -0
- package/package.json +26 -0
- package/script/array.d.ts +44 -0
- package/script/array.d.ts.map +1 -0
- package/script/array.js +62 -0
- package/script/boolean.d.ts +6 -0
- package/script/boolean.d.ts.map +1 -0
- package/script/boolean.js +32 -0
- package/script/helpers.d.ts +10 -0
- package/script/helpers.d.ts.map +1 -0
- package/script/helpers.js +23 -0
- package/script/mod.d.ts +5 -0
- package/script/mod.d.ts.map +1 -0
- package/script/mod.js +20 -0
- package/script/package.json +3 -0
- package/script/set.d.ts +39 -0
- package/script/set.d.ts.map +1 -0
- package/script/set.js +58 -0
- package/script/types.d.ts +25 -0
- package/script/types.d.ts.map +1 -0
- package/script/types.js +2 -0
package/README.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Signals
|
|
2
|
+
|
|
3
|
+
Collection of immutable state containers for primitive data types.
|
|
4
|
+
|
|
5
|
+
## About
|
|
6
|
+
|
|
7
|
+
One way to think about Effection operation is as composable components of
|
|
8
|
+
asyncrony. They are conceptually similar to React components in that they're
|
|
9
|
+
functions that invoke other functions. As with React's component tree, Effection
|
|
10
|
+
operations are arranged into an operation tree. React components are designed to
|
|
11
|
+
make it easier to compose DOM where Effection operations are designed to make it
|
|
12
|
+
easier to compose asynchrony. Because of their simularities, it should come as
|
|
13
|
+
no surpise that they would share patterns for state management. React Context
|
|
14
|
+
and Effection Context is one example of this, but the benefits that
|
|
15
|
+
[unidirectional data flow](https://en.wikipedia.org/wiki/Unidirectional_data_flow)
|
|
16
|
+
provide to composition is another.
|
|
17
|
+
|
|
18
|
+
The Flux pattern, in tools like Redux and others, are "classic" ways to
|
|
19
|
+
implement one directional data from in React applications. Over the years, these
|
|
20
|
+
patterns involved into Signals which where implemented in variety of UI
|
|
21
|
+
frameworks. The design of Signals in the JavaScript ecosystem assume that they
|
|
22
|
+
will be integrated into some UI framework. Effection provides the necessary
|
|
23
|
+
components to have robust yet simple implementation of Signals that doesn't
|
|
24
|
+
require a UI framework.
|
|
25
|
+
|
|
26
|
+
### Included in this package
|
|
27
|
+
|
|
28
|
+
The collection of Signals included in this package rely on Effection's Signal
|
|
29
|
+
interface to provide immutable value streams with some operations. Each Signal
|
|
30
|
+
includes `set`, `update` and `valueOf` methods. Each data type also includes
|
|
31
|
+
methods provided by the primitive version of that data type. For example,
|
|
32
|
+
ArraySignal provides `push` and `shift`, while Set provides `difference`. We
|
|
33
|
+
don't implement all methods, mostly because haven't needed all of the methods.
|
|
34
|
+
If you need a method that we didn't implement but it's available in the
|
|
35
|
+
promitive type, please create a PR. If you need something else, use the `update`
|
|
36
|
+
method.
|
|
37
|
+
|
|
38
|
+
### Boolean Signal
|
|
39
|
+
|
|
40
|
+
The Boolean Signal provides a stream for a boolean value. You can set the value
|
|
41
|
+
which will cause the new value to be sent to the stream.
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import { each, run, spawn } from "effection";
|
|
45
|
+
import { createBooleanSignal } from "@effectionx/signals";
|
|
46
|
+
|
|
47
|
+
await run(function* () {
|
|
48
|
+
const boolean = yield* createBooleanSignal(true);
|
|
49
|
+
|
|
50
|
+
yield* spawn(function* () {
|
|
51
|
+
for (const update of yield* each(boolean)) {
|
|
52
|
+
console.log(update);
|
|
53
|
+
yield* each.next();
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
boolean.set(false); // this will send false to the stream
|
|
58
|
+
boolean.set(true); // this will send true to the stream
|
|
59
|
+
boolean.set(true); // this won't send anything since the value hasn't changed
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
For an example of Boolean Signal in action, checkout the
|
|
64
|
+
[faucet](https://github.com/thefrontside/effectionx/blob/main/stream-helpers/test-helpers/faucet.ts)
|
|
65
|
+
|
|
66
|
+
### Array Signal
|
|
67
|
+
|
|
68
|
+
The Array Signal provides a stream for the value of the array. The value is
|
|
69
|
+
considered immutable - you shouldn't modify the value that comes through the
|
|
70
|
+
stream, instead invoke methods on the signal to cause a new value to be sent.
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import { each, run, spawn } from "effection";
|
|
74
|
+
import { createArraySignal } from "@effectionx/signals";
|
|
75
|
+
|
|
76
|
+
await run(function* () {
|
|
77
|
+
const array = yield* createArraySignal<number>([]);
|
|
78
|
+
|
|
79
|
+
yield* spawn(function* () {
|
|
80
|
+
for (const update of yield* each(array)) {
|
|
81
|
+
console.log(update);
|
|
82
|
+
yield* each.next();
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
array.push(1, 2, 3); // this will be a single update
|
|
87
|
+
});
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
For an example of Array Signl, checkout the
|
|
91
|
+
[valve](https://github.com/thefrontside/effectionx/blob/main/stream-helpers/valve.ts)
|
|
92
|
+
and
|
|
93
|
+
[batch](https://github.com/thefrontside/effectionx/blob/main/stream-helpers/batch.ts)
|
|
94
|
+
stream helpers.
|
|
95
|
+
|
|
96
|
+
## Helpers
|
|
97
|
+
|
|
98
|
+
### is
|
|
99
|
+
|
|
100
|
+
`is` helper returns an operation that completes when the value of the stream
|
|
101
|
+
matches the predicate. It's useful when you want to wait for a signal to enter a
|
|
102
|
+
specific state. Some of the common use cases are waiting for an array to reach a
|
|
103
|
+
given length or for a boolean signal to become true or false.
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { run, spawn } from "effection";
|
|
107
|
+
import { createBooleanSignal, is } from "@effectionx/signals";
|
|
108
|
+
|
|
109
|
+
await run(function* () {
|
|
110
|
+
const open = yield* createBooleanSignal(false);
|
|
111
|
+
|
|
112
|
+
yield* spawn(function* () {
|
|
113
|
+
yield* is(open, (open) => open === true);
|
|
114
|
+
console.log("floodgates are open!");
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
open.set(true);
|
|
118
|
+
});
|
|
119
|
+
```
|
package/esm/array.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type Operation } from "effection";
|
|
2
|
+
import type { ValueSignal } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Interface for return value of {@link createArraySignal}.
|
|
5
|
+
*/
|
|
6
|
+
export interface ArraySignal<T> extends ValueSignal<T[]> {
|
|
7
|
+
/**
|
|
8
|
+
* Pushes a new value onto the end of the array.
|
|
9
|
+
*
|
|
10
|
+
* @param item - The value to push onto the array.
|
|
11
|
+
* @returns The new length of the array.
|
|
12
|
+
*/
|
|
13
|
+
push(item: T): number;
|
|
14
|
+
/**
|
|
15
|
+
* Removes the first value from the array and returns it.
|
|
16
|
+
* If the array is empty, the operation will block until a value is available.
|
|
17
|
+
*
|
|
18
|
+
* @returns The first value from the array.
|
|
19
|
+
*/
|
|
20
|
+
shift(): Operation<T>;
|
|
21
|
+
/**
|
|
22
|
+
* Returns the current value of the array.
|
|
23
|
+
*
|
|
24
|
+
* @returns The current value of the array.
|
|
25
|
+
*/
|
|
26
|
+
valueOf(): Readonly<T[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Returns the length of the array.
|
|
29
|
+
*
|
|
30
|
+
* @returns The length of the array.
|
|
31
|
+
*/
|
|
32
|
+
get length(): number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A signal for an immutable array value. The stream emits the
|
|
36
|
+
* current value of the array and new values when the array is updated. The array
|
|
37
|
+
* is immutable and cannot be changed. Instead, the value is replaced with a new
|
|
38
|
+
* value.
|
|
39
|
+
*
|
|
40
|
+
* @param initial - The initial value of the signal.
|
|
41
|
+
* @returns A stream of immutable array values.
|
|
42
|
+
*/
|
|
43
|
+
export declare function createArraySignal<T>(initial: Iterable<T>): Operation<ArraySignal<T>>;
|
|
44
|
+
//# sourceMappingURL=array.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../src/array.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,SAAS,EAAY,MAAM,WAAW,CAAC;AAInE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,CAAE,SAAQ,WAAW,CAAC,CAAC,EAAE,CAAC;IACtD;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC;IACtB;;;;;OAKG;IACH,KAAK,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC;IACtB;;;;OAIG;IACH,OAAO,IAAI,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;IACzB;;;;OAIG;IACH,IAAI,MAAM,IAAI,MAAM,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,GACnB,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAiD3B"}
|
package/esm/array.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { createSignal, resource } from "effection";
|
|
2
|
+
import { List } from "immutable";
|
|
3
|
+
import { is } from "./helpers.js";
|
|
4
|
+
/**
|
|
5
|
+
* A signal for an immutable array value. The stream emits the
|
|
6
|
+
* current value of the array and new values when the array is updated. The array
|
|
7
|
+
* is immutable and cannot be changed. Instead, the value is replaced with a new
|
|
8
|
+
* value.
|
|
9
|
+
*
|
|
10
|
+
* @param initial - The initial value of the signal.
|
|
11
|
+
* @returns A stream of immutable array values.
|
|
12
|
+
*/
|
|
13
|
+
export function createArraySignal(initial) {
|
|
14
|
+
return resource(function* (provide) {
|
|
15
|
+
const signal = createSignal();
|
|
16
|
+
const ref = {
|
|
17
|
+
current: List.of(...initial),
|
|
18
|
+
};
|
|
19
|
+
function set(value) {
|
|
20
|
+
if (ref.current.equals(List.of(...value))) {
|
|
21
|
+
return ref.current.toArray();
|
|
22
|
+
}
|
|
23
|
+
ref.current = List.of(...value);
|
|
24
|
+
signal.send(ref.current.toArray());
|
|
25
|
+
return ref.current.toArray();
|
|
26
|
+
}
|
|
27
|
+
const array = {
|
|
28
|
+
[Symbol.iterator]: signal[Symbol.iterator],
|
|
29
|
+
set,
|
|
30
|
+
update(updater) {
|
|
31
|
+
return set(updater(ref.current.toArray()));
|
|
32
|
+
},
|
|
33
|
+
push(...args) {
|
|
34
|
+
ref.current = ref.current.push(...args);
|
|
35
|
+
signal.send(ref.current.toArray());
|
|
36
|
+
return ref.current.size;
|
|
37
|
+
},
|
|
38
|
+
*shift() {
|
|
39
|
+
yield* is(array, (array) => array.length > 0);
|
|
40
|
+
let value = ref.current.first();
|
|
41
|
+
ref.current = ref.current.shift();
|
|
42
|
+
signal.send(ref.current.toArray());
|
|
43
|
+
return value;
|
|
44
|
+
},
|
|
45
|
+
valueOf() {
|
|
46
|
+
return ref.current.toArray();
|
|
47
|
+
},
|
|
48
|
+
get length() {
|
|
49
|
+
return ref.current.size;
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
try {
|
|
53
|
+
yield* provide(array);
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
signal.close();
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
package/esm/boolean.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type Operation } from "effection";
|
|
2
|
+
import type { ValueSignal } from "./types.js";
|
|
3
|
+
export interface BooleanSignal extends ValueSignal<boolean> {
|
|
4
|
+
}
|
|
5
|
+
export declare function createBooleanSignal(initial?: boolean): Operation<BooleanSignal>;
|
|
6
|
+
//# sourceMappingURL=boolean.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boolean.d.ts","sourceRoot":"","sources":["../src/boolean.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,SAAS,EAAY,MAAM,WAAW,CAAC;AAEnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,WAAW,aAAc,SAAQ,WAAW,CAAC,OAAO,CAAC;CAAG;AAE9D,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,OAAe,GACvB,SAAS,CAAC,aAAa,CAAC,CA+B1B"}
|
package/esm/boolean.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { createSignal, resource } from "effection";
|
|
2
|
+
export function createBooleanSignal(initial = false) {
|
|
3
|
+
return resource(function* (provide) {
|
|
4
|
+
const signal = createSignal();
|
|
5
|
+
const ref = { current: initial };
|
|
6
|
+
function set(value) {
|
|
7
|
+
if (value !== ref.current) {
|
|
8
|
+
ref.current = value;
|
|
9
|
+
signal.send(ref.current);
|
|
10
|
+
}
|
|
11
|
+
return ref.current;
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
yield* provide({
|
|
15
|
+
[Symbol.iterator]: signal[Symbol.iterator],
|
|
16
|
+
set,
|
|
17
|
+
update(updater) {
|
|
18
|
+
return set(updater(ref.current));
|
|
19
|
+
},
|
|
20
|
+
valueOf() {
|
|
21
|
+
return ref.current;
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
finally {
|
|
26
|
+
signal.close();
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
package/esm/helpers.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Operation } from "effection";
|
|
2
|
+
import type { ValueSignal } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Returns an operation that will wait until the value of the stream matches the predicate.
|
|
5
|
+
* @param stream - The stream to check.
|
|
6
|
+
* @param predicate - The predicate to check the value against.
|
|
7
|
+
* @returns An operation that will wait until the value of the stream matches the predicate.
|
|
8
|
+
*/
|
|
9
|
+
export declare function is<T>(stream: ValueSignal<T>, predicate: (item: T) => boolean): Operation<void>;
|
|
10
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;GAKG;AACH,wBAAiB,EAAE,CAAC,CAAC,EACnB,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EACtB,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,GAC9B,SAAS,CAAC,IAAI,CAAC,CAYjB"}
|
package/esm/helpers.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { each } from "effection";
|
|
2
|
+
/**
|
|
3
|
+
* Returns an operation that will wait until the value of the stream matches the predicate.
|
|
4
|
+
* @param stream - The stream to check.
|
|
5
|
+
* @param predicate - The predicate to check the value against.
|
|
6
|
+
* @returns An operation that will wait until the value of the stream matches the predicate.
|
|
7
|
+
*/
|
|
8
|
+
export function* is(stream, predicate) {
|
|
9
|
+
const result = predicate(stream.valueOf());
|
|
10
|
+
if (result) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
for (const value of yield* each(stream)) {
|
|
14
|
+
const result = predicate(value);
|
|
15
|
+
if (result) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
yield* each.next();
|
|
19
|
+
}
|
|
20
|
+
}
|
package/esm/mod.d.ts
ADDED
package/esm/mod.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC"}
|
package/esm/mod.js
ADDED
package/esm/package.json
ADDED
package/esm/set.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type Operation } from "effection";
|
|
2
|
+
import type { ValueSignal } from "./types.js";
|
|
3
|
+
import { Set } from "immutable";
|
|
4
|
+
/**
|
|
5
|
+
* A signal that represents a Set.
|
|
6
|
+
*/
|
|
7
|
+
export interface SetSignal<T> extends ValueSignal<Set<T>> {
|
|
8
|
+
/**
|
|
9
|
+
* Adds an item to the Set.
|
|
10
|
+
* @param item - The item to add to the Set.
|
|
11
|
+
* @returns The Set.
|
|
12
|
+
*/
|
|
13
|
+
add(item: T): Set<T>;
|
|
14
|
+
/**
|
|
15
|
+
* Removes an item from the Set.
|
|
16
|
+
* @param item - The item to remove from the Set.
|
|
17
|
+
* @returns `true` if the item was removed, `false` otherwise.
|
|
18
|
+
*/
|
|
19
|
+
delete(item: T): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Returns a new Set with the items that are in the current Set but not in the given iterable.
|
|
22
|
+
* @param items - The items to remove from the Set.
|
|
23
|
+
* @returns A new Set with the items that are in the current Set but not in the given iterable.
|
|
24
|
+
*/
|
|
25
|
+
difference(items: Iterable<T>): Set<T>;
|
|
26
|
+
/**
|
|
27
|
+
* Returns the Set value
|
|
28
|
+
* @returns The Set.
|
|
29
|
+
*/
|
|
30
|
+
valueOf(): Set<T>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Creates a signal that represents a set. Adding and removing items from the set will
|
|
34
|
+
* push a new value through the stream.
|
|
35
|
+
* @param initial - The initial value of the set.
|
|
36
|
+
* @returns A signal that represents a set.
|
|
37
|
+
*/
|
|
38
|
+
export declare function createSetSignal<T>(initial?: Array<T>): Operation<SetSignal<T>>;
|
|
39
|
+
//# sourceMappingURL=set.d.ts.map
|
package/esm/set.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../src/set.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,SAAS,EAAY,MAAM,WAAW,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAM,GAAG,EAAE,MAAM,WAAW,CAAC;AAEpC;;GAEG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC,CAAE,SAAQ,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACvD;;;;OAIG;IACH,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC;IACzB;;;;OAIG;IACH,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IACvC;;;OAGG;IACH,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,OAAO,GAAE,KAAK,CAAC,CAAC,CAAM,GACrB,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAgDzB"}
|
package/esm/set.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { createSignal, resource } from "effection";
|
|
2
|
+
import { is, Set } from "immutable";
|
|
3
|
+
/**
|
|
4
|
+
* Creates a signal that represents a set. Adding and removing items from the set will
|
|
5
|
+
* push a new value through the stream.
|
|
6
|
+
* @param initial - The initial value of the set.
|
|
7
|
+
* @returns A signal that represents a set.
|
|
8
|
+
*/
|
|
9
|
+
export function createSetSignal(initial = []) {
|
|
10
|
+
return resource(function* (provide) {
|
|
11
|
+
const signal = createSignal();
|
|
12
|
+
const ref = { current: Set.of(...initial) };
|
|
13
|
+
function set(value) {
|
|
14
|
+
if (is(ref.current, value)) {
|
|
15
|
+
return ref.current;
|
|
16
|
+
}
|
|
17
|
+
ref.current = Set.of(...value);
|
|
18
|
+
signal.send(ref.current);
|
|
19
|
+
return ref.current;
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
yield* provide({
|
|
23
|
+
[Symbol.iterator]: signal[Symbol.iterator],
|
|
24
|
+
set,
|
|
25
|
+
update(updater) {
|
|
26
|
+
return set(updater(ref.current));
|
|
27
|
+
},
|
|
28
|
+
add(item) {
|
|
29
|
+
ref.current = ref.current.add(item);
|
|
30
|
+
signal.send(ref.current);
|
|
31
|
+
return ref.current;
|
|
32
|
+
},
|
|
33
|
+
difference(items) {
|
|
34
|
+
ref.current = ref.current.subtract(items);
|
|
35
|
+
signal.send(ref.current);
|
|
36
|
+
return ref.current;
|
|
37
|
+
},
|
|
38
|
+
delete(item) {
|
|
39
|
+
if (ref.current.has(item)) {
|
|
40
|
+
ref.current = ref.current.delete(item);
|
|
41
|
+
signal.send(ref.current);
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
45
|
+
},
|
|
46
|
+
valueOf() {
|
|
47
|
+
return ref.current.toSet();
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
signal.close();
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
package/esm/types.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Stream } from "effection";
|
|
2
|
+
/**
|
|
3
|
+
* A signal is a stream with set, update, and valueOf methods.
|
|
4
|
+
* Subscribing to a signal will yield the current value of the signal.
|
|
5
|
+
*/
|
|
6
|
+
export interface ValueSignal<T> extends Stream<T, void> {
|
|
7
|
+
/**
|
|
8
|
+
* Set the value of the signal.
|
|
9
|
+
* @param value - The value to set the signal to.
|
|
10
|
+
* @returns The value of the signal.
|
|
11
|
+
*/
|
|
12
|
+
set(value: T): T;
|
|
13
|
+
/**
|
|
14
|
+
* Update the value of the signal.
|
|
15
|
+
* @param updater - The updater function.
|
|
16
|
+
* @returns The value of the signal.
|
|
17
|
+
*/
|
|
18
|
+
update(updater: (value: T) => T): T;
|
|
19
|
+
/**
|
|
20
|
+
* Get the current value of the signal.
|
|
21
|
+
* @returns The current value of the signal.
|
|
22
|
+
*/
|
|
23
|
+
valueOf(): Readonly<T>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC;;;GAGG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,CAAE,SAAQ,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC;IACrD;;;;OAIG;IACH,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;IACjB;;;;OAIG;IACH,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC;;;OAGG;IACH,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;CACxB"}
|
package/esm/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@effectionx/signals",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"author": "engineering@frontside.com",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/thefrontside/effectionx.git"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/thefrontside/effectionx/issues"
|
|
12
|
+
},
|
|
13
|
+
"main": "./script/mod.js",
|
|
14
|
+
"module": "./esm/mod.js",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"import": "./esm/mod.js",
|
|
18
|
+
"require": "./script/mod.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">= 16"
|
|
23
|
+
},
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"_generatedBy": "dnt@dev"
|
|
26
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type Operation } from "effection";
|
|
2
|
+
import type { ValueSignal } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Interface for return value of {@link createArraySignal}.
|
|
5
|
+
*/
|
|
6
|
+
export interface ArraySignal<T> extends ValueSignal<T[]> {
|
|
7
|
+
/**
|
|
8
|
+
* Pushes a new value onto the end of the array.
|
|
9
|
+
*
|
|
10
|
+
* @param item - The value to push onto the array.
|
|
11
|
+
* @returns The new length of the array.
|
|
12
|
+
*/
|
|
13
|
+
push(item: T): number;
|
|
14
|
+
/**
|
|
15
|
+
* Removes the first value from the array and returns it.
|
|
16
|
+
* If the array is empty, the operation will block until a value is available.
|
|
17
|
+
*
|
|
18
|
+
* @returns The first value from the array.
|
|
19
|
+
*/
|
|
20
|
+
shift(): Operation<T>;
|
|
21
|
+
/**
|
|
22
|
+
* Returns the current value of the array.
|
|
23
|
+
*
|
|
24
|
+
* @returns The current value of the array.
|
|
25
|
+
*/
|
|
26
|
+
valueOf(): Readonly<T[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Returns the length of the array.
|
|
29
|
+
*
|
|
30
|
+
* @returns The length of the array.
|
|
31
|
+
*/
|
|
32
|
+
get length(): number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A signal for an immutable array value. The stream emits the
|
|
36
|
+
* current value of the array and new values when the array is updated. The array
|
|
37
|
+
* is immutable and cannot be changed. Instead, the value is replaced with a new
|
|
38
|
+
* value.
|
|
39
|
+
*
|
|
40
|
+
* @param initial - The initial value of the signal.
|
|
41
|
+
* @returns A stream of immutable array values.
|
|
42
|
+
*/
|
|
43
|
+
export declare function createArraySignal<T>(initial: Iterable<T>): Operation<ArraySignal<T>>;
|
|
44
|
+
//# sourceMappingURL=array.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../src/array.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,SAAS,EAAY,MAAM,WAAW,CAAC;AAInE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,CAAE,SAAQ,WAAW,CAAC,CAAC,EAAE,CAAC;IACtD;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC;IACtB;;;;;OAKG;IACH,KAAK,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC;IACtB;;;;OAIG;IACH,OAAO,IAAI,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;IACzB;;;;OAIG;IACH,IAAI,MAAM,IAAI,MAAM,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,GACnB,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAiD3B"}
|
package/script/array.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createArraySignal = createArraySignal;
|
|
4
|
+
const effection_1 = require("effection");
|
|
5
|
+
const immutable_1 = require("immutable");
|
|
6
|
+
const helpers_js_1 = require("./helpers.js");
|
|
7
|
+
/**
|
|
8
|
+
* A signal for an immutable array value. The stream emits the
|
|
9
|
+
* current value of the array and new values when the array is updated. The array
|
|
10
|
+
* is immutable and cannot be changed. Instead, the value is replaced with a new
|
|
11
|
+
* value.
|
|
12
|
+
*
|
|
13
|
+
* @param initial - The initial value of the signal.
|
|
14
|
+
* @returns A stream of immutable array values.
|
|
15
|
+
*/
|
|
16
|
+
function createArraySignal(initial) {
|
|
17
|
+
return (0, effection_1.resource)(function* (provide) {
|
|
18
|
+
const signal = (0, effection_1.createSignal)();
|
|
19
|
+
const ref = {
|
|
20
|
+
current: immutable_1.List.of(...initial),
|
|
21
|
+
};
|
|
22
|
+
function set(value) {
|
|
23
|
+
if (ref.current.equals(immutable_1.List.of(...value))) {
|
|
24
|
+
return ref.current.toArray();
|
|
25
|
+
}
|
|
26
|
+
ref.current = immutable_1.List.of(...value);
|
|
27
|
+
signal.send(ref.current.toArray());
|
|
28
|
+
return ref.current.toArray();
|
|
29
|
+
}
|
|
30
|
+
const array = {
|
|
31
|
+
[Symbol.iterator]: signal[Symbol.iterator],
|
|
32
|
+
set,
|
|
33
|
+
update(updater) {
|
|
34
|
+
return set(updater(ref.current.toArray()));
|
|
35
|
+
},
|
|
36
|
+
push(...args) {
|
|
37
|
+
ref.current = ref.current.push(...args);
|
|
38
|
+
signal.send(ref.current.toArray());
|
|
39
|
+
return ref.current.size;
|
|
40
|
+
},
|
|
41
|
+
*shift() {
|
|
42
|
+
yield* (0, helpers_js_1.is)(array, (array) => array.length > 0);
|
|
43
|
+
let value = ref.current.first();
|
|
44
|
+
ref.current = ref.current.shift();
|
|
45
|
+
signal.send(ref.current.toArray());
|
|
46
|
+
return value;
|
|
47
|
+
},
|
|
48
|
+
valueOf() {
|
|
49
|
+
return ref.current.toArray();
|
|
50
|
+
},
|
|
51
|
+
get length() {
|
|
52
|
+
return ref.current.size;
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
try {
|
|
56
|
+
yield* provide(array);
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
signal.close();
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type Operation } from "effection";
|
|
2
|
+
import type { ValueSignal } from "./types.js";
|
|
3
|
+
export interface BooleanSignal extends ValueSignal<boolean> {
|
|
4
|
+
}
|
|
5
|
+
export declare function createBooleanSignal(initial?: boolean): Operation<BooleanSignal>;
|
|
6
|
+
//# sourceMappingURL=boolean.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boolean.d.ts","sourceRoot":"","sources":["../src/boolean.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,SAAS,EAAY,MAAM,WAAW,CAAC;AAEnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,WAAW,aAAc,SAAQ,WAAW,CAAC,OAAO,CAAC;CAAG;AAE9D,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,OAAe,GACvB,SAAS,CAAC,aAAa,CAAC,CA+B1B"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createBooleanSignal = createBooleanSignal;
|
|
4
|
+
const effection_1 = require("effection");
|
|
5
|
+
function createBooleanSignal(initial = false) {
|
|
6
|
+
return (0, effection_1.resource)(function* (provide) {
|
|
7
|
+
const signal = (0, effection_1.createSignal)();
|
|
8
|
+
const ref = { current: initial };
|
|
9
|
+
function set(value) {
|
|
10
|
+
if (value !== ref.current) {
|
|
11
|
+
ref.current = value;
|
|
12
|
+
signal.send(ref.current);
|
|
13
|
+
}
|
|
14
|
+
return ref.current;
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
yield* provide({
|
|
18
|
+
[Symbol.iterator]: signal[Symbol.iterator],
|
|
19
|
+
set,
|
|
20
|
+
update(updater) {
|
|
21
|
+
return set(updater(ref.current));
|
|
22
|
+
},
|
|
23
|
+
valueOf() {
|
|
24
|
+
return ref.current;
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
signal.close();
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Operation } from "effection";
|
|
2
|
+
import type { ValueSignal } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Returns an operation that will wait until the value of the stream matches the predicate.
|
|
5
|
+
* @param stream - The stream to check.
|
|
6
|
+
* @param predicate - The predicate to check the value against.
|
|
7
|
+
* @returns An operation that will wait until the value of the stream matches the predicate.
|
|
8
|
+
*/
|
|
9
|
+
export declare function is<T>(stream: ValueSignal<T>, predicate: (item: T) => boolean): Operation<void>;
|
|
10
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;GAKG;AACH,wBAAiB,EAAE,CAAC,CAAC,EACnB,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EACtB,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,GAC9B,SAAS,CAAC,IAAI,CAAC,CAYjB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.is = is;
|
|
4
|
+
const effection_1 = require("effection");
|
|
5
|
+
/**
|
|
6
|
+
* Returns an operation that will wait until the value of the stream matches the predicate.
|
|
7
|
+
* @param stream - The stream to check.
|
|
8
|
+
* @param predicate - The predicate to check the value against.
|
|
9
|
+
* @returns An operation that will wait until the value of the stream matches the predicate.
|
|
10
|
+
*/
|
|
11
|
+
function* is(stream, predicate) {
|
|
12
|
+
const result = predicate(stream.valueOf());
|
|
13
|
+
if (result) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
for (const value of yield* (0, effection_1.each)(stream)) {
|
|
17
|
+
const result = predicate(value);
|
|
18
|
+
if (result) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
yield* effection_1.each.next();
|
|
22
|
+
}
|
|
23
|
+
}
|
package/script/mod.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC"}
|
package/script/mod.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./boolean.js"), exports);
|
|
18
|
+
__exportStar(require("./array.js"), exports);
|
|
19
|
+
__exportStar(require("./set.js"), exports);
|
|
20
|
+
__exportStar(require("./helpers.js"), exports);
|
package/script/set.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type Operation } from "effection";
|
|
2
|
+
import type { ValueSignal } from "./types.js";
|
|
3
|
+
import { Set } from "immutable";
|
|
4
|
+
/**
|
|
5
|
+
* A signal that represents a Set.
|
|
6
|
+
*/
|
|
7
|
+
export interface SetSignal<T> extends ValueSignal<Set<T>> {
|
|
8
|
+
/**
|
|
9
|
+
* Adds an item to the Set.
|
|
10
|
+
* @param item - The item to add to the Set.
|
|
11
|
+
* @returns The Set.
|
|
12
|
+
*/
|
|
13
|
+
add(item: T): Set<T>;
|
|
14
|
+
/**
|
|
15
|
+
* Removes an item from the Set.
|
|
16
|
+
* @param item - The item to remove from the Set.
|
|
17
|
+
* @returns `true` if the item was removed, `false` otherwise.
|
|
18
|
+
*/
|
|
19
|
+
delete(item: T): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Returns a new Set with the items that are in the current Set but not in the given iterable.
|
|
22
|
+
* @param items - The items to remove from the Set.
|
|
23
|
+
* @returns A new Set with the items that are in the current Set but not in the given iterable.
|
|
24
|
+
*/
|
|
25
|
+
difference(items: Iterable<T>): Set<T>;
|
|
26
|
+
/**
|
|
27
|
+
* Returns the Set value
|
|
28
|
+
* @returns The Set.
|
|
29
|
+
*/
|
|
30
|
+
valueOf(): Set<T>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Creates a signal that represents a set. Adding and removing items from the set will
|
|
34
|
+
* push a new value through the stream.
|
|
35
|
+
* @param initial - The initial value of the set.
|
|
36
|
+
* @returns A signal that represents a set.
|
|
37
|
+
*/
|
|
38
|
+
export declare function createSetSignal<T>(initial?: Array<T>): Operation<SetSignal<T>>;
|
|
39
|
+
//# sourceMappingURL=set.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../src/set.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,SAAS,EAAY,MAAM,WAAW,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAM,GAAG,EAAE,MAAM,WAAW,CAAC;AAEpC;;GAEG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC,CAAE,SAAQ,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACvD;;;;OAIG;IACH,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC;IACzB;;;;OAIG;IACH,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IACvC;;;OAGG;IACH,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,OAAO,GAAE,KAAK,CAAC,CAAC,CAAM,GACrB,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAgDzB"}
|
package/script/set.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createSetSignal = createSetSignal;
|
|
4
|
+
const effection_1 = require("effection");
|
|
5
|
+
const immutable_1 = require("immutable");
|
|
6
|
+
/**
|
|
7
|
+
* Creates a signal that represents a set. Adding and removing items from the set will
|
|
8
|
+
* push a new value through the stream.
|
|
9
|
+
* @param initial - The initial value of the set.
|
|
10
|
+
* @returns A signal that represents a set.
|
|
11
|
+
*/
|
|
12
|
+
function createSetSignal(initial = []) {
|
|
13
|
+
return (0, effection_1.resource)(function* (provide) {
|
|
14
|
+
const signal = (0, effection_1.createSignal)();
|
|
15
|
+
const ref = { current: immutable_1.Set.of(...initial) };
|
|
16
|
+
function set(value) {
|
|
17
|
+
if ((0, immutable_1.is)(ref.current, value)) {
|
|
18
|
+
return ref.current;
|
|
19
|
+
}
|
|
20
|
+
ref.current = immutable_1.Set.of(...value);
|
|
21
|
+
signal.send(ref.current);
|
|
22
|
+
return ref.current;
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
yield* provide({
|
|
26
|
+
[Symbol.iterator]: signal[Symbol.iterator],
|
|
27
|
+
set,
|
|
28
|
+
update(updater) {
|
|
29
|
+
return set(updater(ref.current));
|
|
30
|
+
},
|
|
31
|
+
add(item) {
|
|
32
|
+
ref.current = ref.current.add(item);
|
|
33
|
+
signal.send(ref.current);
|
|
34
|
+
return ref.current;
|
|
35
|
+
},
|
|
36
|
+
difference(items) {
|
|
37
|
+
ref.current = ref.current.subtract(items);
|
|
38
|
+
signal.send(ref.current);
|
|
39
|
+
return ref.current;
|
|
40
|
+
},
|
|
41
|
+
delete(item) {
|
|
42
|
+
if (ref.current.has(item)) {
|
|
43
|
+
ref.current = ref.current.delete(item);
|
|
44
|
+
signal.send(ref.current);
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
},
|
|
49
|
+
valueOf() {
|
|
50
|
+
return ref.current.toSet();
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
signal.close();
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Stream } from "effection";
|
|
2
|
+
/**
|
|
3
|
+
* A signal is a stream with set, update, and valueOf methods.
|
|
4
|
+
* Subscribing to a signal will yield the current value of the signal.
|
|
5
|
+
*/
|
|
6
|
+
export interface ValueSignal<T> extends Stream<T, void> {
|
|
7
|
+
/**
|
|
8
|
+
* Set the value of the signal.
|
|
9
|
+
* @param value - The value to set the signal to.
|
|
10
|
+
* @returns The value of the signal.
|
|
11
|
+
*/
|
|
12
|
+
set(value: T): T;
|
|
13
|
+
/**
|
|
14
|
+
* Update the value of the signal.
|
|
15
|
+
* @param updater - The updater function.
|
|
16
|
+
* @returns The value of the signal.
|
|
17
|
+
*/
|
|
18
|
+
update(updater: (value: T) => T): T;
|
|
19
|
+
/**
|
|
20
|
+
* Get the current value of the signal.
|
|
21
|
+
* @returns The current value of the signal.
|
|
22
|
+
*/
|
|
23
|
+
valueOf(): Readonly<T>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC;;;GAGG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,CAAE,SAAQ,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC;IACrD;;;;OAIG;IACH,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;IACjB;;;;OAIG;IACH,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC;;;OAGG;IACH,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;CACxB"}
|
package/script/types.js
ADDED