@bodil/signal 0.3.1 → 0.3.2
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/dist/index.d.ts +88 -9
- package/dist/index.js +77 -6
- package/dist/index.js.map +1 -1
- package/dist/signal.test.js.map +1 -1
- package/package.json +22 -15
- package/src/index.ts +103 -16
- package/src/signal.test.ts +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,38 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A signal library built on the [TC39 Signals
|
|
3
|
+
* Proposal](https://github.com/tc39/proposal-signals).
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
1
6
|
import { Signal } from "signal-polyfill";
|
|
2
7
|
import { type Disposifiable } from "@bodil/disposable";
|
|
3
8
|
interface ISignal<A> {
|
|
9
|
+
/**
|
|
10
|
+
* The current value of the signal.
|
|
11
|
+
*
|
|
12
|
+
* When this is read inside a computation function or an effect function,
|
|
13
|
+
* this signal is automatically added to the effect or computed signal as a
|
|
14
|
+
* dependency.
|
|
15
|
+
*/
|
|
4
16
|
readonly value: A;
|
|
5
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Construct a {@link Signal.Computed} signal using a mapping function over
|
|
19
|
+
* the current value of this signal.
|
|
20
|
+
*/
|
|
21
|
+
map<B>(fn: (value: A) => B): SignalGlobal.Computed<B>;
|
|
22
|
+
/**
|
|
23
|
+
* Subscribe to changes to the value of this signal.
|
|
24
|
+
*/
|
|
6
25
|
on(callback: (value: A) => void): Disposable;
|
|
7
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* A writable state signal.
|
|
29
|
+
*/
|
|
8
30
|
declare class StateSignal<A> extends Signal.State<A> implements ISignal<A> {
|
|
9
31
|
get value(): A;
|
|
10
32
|
set value(value: A);
|
|
33
|
+
/**
|
|
34
|
+
* Update the current value of this signal using a function.
|
|
35
|
+
*/
|
|
11
36
|
update(fn: (value: A) => A): void;
|
|
12
|
-
|
|
13
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Get a read only version of this signal.
|
|
39
|
+
*/
|
|
40
|
+
readOnly(): SignalGlobal.Computed<A>;
|
|
41
|
+
map<B>(fn: (value: A) => B): SignalGlobal.Computed<B>;
|
|
14
42
|
on(callback: (value: A) => void): Disposable;
|
|
15
|
-
static is(v: unknown): v is
|
|
43
|
+
static is(v: unknown): v is SignalGlobal.State<unknown>;
|
|
16
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* A read only signal computed from the values of other signals.
|
|
47
|
+
*/
|
|
17
48
|
declare class ComputedSignal<A> extends Signal.Computed<A> implements ISignal<A> {
|
|
18
49
|
get value(): A;
|
|
19
|
-
map<B>(fn: (value: A) => B):
|
|
50
|
+
map<B>(fn: (value: A) => B): SignalGlobal.Computed<B>;
|
|
20
51
|
on(callback: (value: A) => void): Disposable;
|
|
21
|
-
static is(v: unknown): v is
|
|
52
|
+
static is(v: unknown): v is SignalGlobal.Computed<unknown>;
|
|
22
53
|
}
|
|
23
|
-
type SignalGlobal<A> =
|
|
54
|
+
type SignalGlobal<A> = SignalGlobal.State<A> | SignalGlobal.Computed<A>;
|
|
24
55
|
declare const SignalGlobal: (<A>(value: A, options?: Signal.Options<A>) => SignalGlobal.State<A>) & {
|
|
56
|
+
/**
|
|
57
|
+
* Test whether the given value is a signal.
|
|
58
|
+
*/
|
|
25
59
|
is(v: unknown): v is SignalGlobal<unknown>;
|
|
26
|
-
|
|
27
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Construct a new {@link Signal.Computed} signal using the provided
|
|
62
|
+
* computation function.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* const sig1 = Signal(2);
|
|
66
|
+
* const sig2 = Signal(3);
|
|
67
|
+
* const sum = Signal.computed(() => sig1.get() + sig2.get());
|
|
68
|
+
* assert(sum.get() === 5);
|
|
69
|
+
*/
|
|
70
|
+
computed<A>(fn: (this: SignalGlobal.Computed<A>) => A, options?: Signal.Options<A>): SignalGlobal.Computed<A>;
|
|
71
|
+
/**
|
|
72
|
+
* Suscribe to a signal.
|
|
73
|
+
*
|
|
74
|
+
* The provided callback will be called every time the value of the
|
|
75
|
+
* signal changes.
|
|
76
|
+
*/
|
|
77
|
+
subscribe<A>(signal: SignalGlobal<A>, callback: (value: A) => void): Disposable;
|
|
78
|
+
/**
|
|
79
|
+
* Create an effect responding to signal changes.
|
|
80
|
+
*
|
|
81
|
+
* The provided function will be called immediately, and again every
|
|
82
|
+
* time a signal that was read by the function changes.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* const sig = Signal("Hello Joe!");
|
|
86
|
+
* effect(() => console.log("Signal value is:", sig.get()));
|
|
87
|
+
* // prints "Signal value is: Hello Joe!"
|
|
88
|
+
* sig.set("Hello Mike!");
|
|
89
|
+
* // prints "Signal value is: Hello Mike!"
|
|
90
|
+
*/
|
|
28
91
|
effect(fn: () => Disposifiable | void): Disposable;
|
|
92
|
+
/**
|
|
93
|
+
* Construct a new {@link Signal.Computed} signal using an async
|
|
94
|
+
* computation function.
|
|
95
|
+
*
|
|
96
|
+
* This returns a promise which will resolve to a
|
|
97
|
+
* {@link Signal.Computed} signal once the promise returned by the
|
|
98
|
+
* computation function resolves, and will update itself whenever
|
|
99
|
+
* subsequent calls to the computation function resolve.
|
|
100
|
+
*
|
|
101
|
+
* The function is provided with an {@link AbortSignal} which any async
|
|
102
|
+
* jobs started from it should abide by. If a signal dependency changes
|
|
103
|
+
* while the job is running, the {@link AbortSignal} will be triggered
|
|
104
|
+
* and the job restarted.
|
|
105
|
+
*/
|
|
29
106
|
asyncComputed<A>(fn: (abort: AbortSignal) => Promise<A>, options?: Signal.Options<A>): Promise<SignalGlobal.Computed<A>>;
|
|
30
107
|
State: typeof StateSignal;
|
|
31
108
|
Computed: typeof ComputedSignal;
|
|
32
109
|
subtle: typeof Signal.subtle;
|
|
33
110
|
};
|
|
34
111
|
declare namespace SignalGlobal {
|
|
112
|
+
/** @interface */
|
|
35
113
|
type State<A> = StateSignal<A>;
|
|
114
|
+
/** @interface */
|
|
36
115
|
type Computed<A> = ComputedSignal<A>;
|
|
37
116
|
}
|
|
38
117
|
export { SignalGlobal as Signal };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A signal library built on the [TC39 Signals
|
|
3
|
+
* Proposal](https://github.com/tc39/proposal-signals).
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
1
6
|
import { Signal } from "signal-polyfill";
|
|
2
7
|
import { toDisposable } from "@bodil/disposable";
|
|
3
|
-
import
|
|
8
|
+
import * as Async from "@bodil/core/async";
|
|
9
|
+
import { Err, Ok } from "@bodil/opt";
|
|
10
|
+
/**
|
|
11
|
+
* A writable state signal.
|
|
12
|
+
*/
|
|
4
13
|
class StateSignal extends Signal.State {
|
|
5
14
|
get value() {
|
|
6
15
|
return this.get();
|
|
@@ -8,9 +17,15 @@ class StateSignal extends Signal.State {
|
|
|
8
17
|
set value(value) {
|
|
9
18
|
this.set(value);
|
|
10
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Update the current value of this signal using a function.
|
|
22
|
+
*/
|
|
11
23
|
update(fn) {
|
|
12
24
|
this.set(Signal.subtle.untrack(() => fn(this.get())));
|
|
13
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Get a read only version of this signal.
|
|
28
|
+
*/
|
|
14
29
|
readOnly() {
|
|
15
30
|
return SignalGlobal.computed(() => this.get());
|
|
16
31
|
}
|
|
@@ -24,6 +39,9 @@ class StateSignal extends Signal.State {
|
|
|
24
39
|
return v instanceof StateSignal;
|
|
25
40
|
}
|
|
26
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* A read only signal computed from the values of other signals.
|
|
44
|
+
*/
|
|
27
45
|
class ComputedSignal extends Signal.Computed {
|
|
28
46
|
get value() {
|
|
29
47
|
return this.get();
|
|
@@ -52,21 +70,60 @@ function effectProcess() {
|
|
|
52
70
|
}
|
|
53
71
|
effectWatcher.watch();
|
|
54
72
|
}
|
|
55
|
-
const SignalGlobal = Object.assign(
|
|
56
|
-
|
|
73
|
+
const SignalGlobal = Object.assign(
|
|
74
|
+
/**
|
|
75
|
+
* Construct a new {@link Signal.State} signal containing the provided value.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* const sig = Signal("Hello Joe!");
|
|
79
|
+
*/
|
|
80
|
+
function (value, options) {
|
|
81
|
+
return new SignalGlobal.State(value, options);
|
|
57
82
|
}, {
|
|
83
|
+
/**
|
|
84
|
+
* Test whether the given value is a signal.
|
|
85
|
+
*/
|
|
58
86
|
is(v) {
|
|
59
|
-
return
|
|
87
|
+
return SignalGlobal.State.is(v) || SignalGlobal.Computed.is(v);
|
|
60
88
|
},
|
|
89
|
+
/**
|
|
90
|
+
* Construct a new {@link Signal.Computed} signal using the provided
|
|
91
|
+
* computation function.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* const sig1 = Signal(2);
|
|
95
|
+
* const sig2 = Signal(3);
|
|
96
|
+
* const sum = Signal.computed(() => sig1.get() + sig2.get());
|
|
97
|
+
* assert(sum.get() === 5);
|
|
98
|
+
*/
|
|
61
99
|
computed(fn, options) {
|
|
62
|
-
return new
|
|
100
|
+
return new SignalGlobal.Computed(fn, options);
|
|
63
101
|
},
|
|
102
|
+
/**
|
|
103
|
+
* Suscribe to a signal.
|
|
104
|
+
*
|
|
105
|
+
* The provided callback will be called every time the value of the
|
|
106
|
+
* signal changes.
|
|
107
|
+
*/
|
|
64
108
|
subscribe(signal, callback) {
|
|
65
109
|
return SignalGlobal.effect(() => callback(signal.value));
|
|
66
110
|
},
|
|
111
|
+
/**
|
|
112
|
+
* Create an effect responding to signal changes.
|
|
113
|
+
*
|
|
114
|
+
* The provided function will be called immediately, and again every
|
|
115
|
+
* time a signal that was read by the function changes.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* const sig = Signal("Hello Joe!");
|
|
119
|
+
* effect(() => console.log("Signal value is:", sig.get()));
|
|
120
|
+
* // prints "Signal value is: Hello Joe!"
|
|
121
|
+
* sig.set("Hello Mike!");
|
|
122
|
+
* // prints "Signal value is: Hello Mike!"
|
|
123
|
+
*/
|
|
67
124
|
effect(fn) {
|
|
68
125
|
let cleanup;
|
|
69
|
-
const computed = new
|
|
126
|
+
const computed = new SignalGlobal.Computed(() => {
|
|
70
127
|
if (cleanup !== undefined) {
|
|
71
128
|
cleanup[Symbol.dispose]();
|
|
72
129
|
}
|
|
@@ -82,6 +139,20 @@ const SignalGlobal = Object.assign(function (value, options) {
|
|
|
82
139
|
}
|
|
83
140
|
});
|
|
84
141
|
},
|
|
142
|
+
/**
|
|
143
|
+
* Construct a new {@link Signal.Computed} signal using an async
|
|
144
|
+
* computation function.
|
|
145
|
+
*
|
|
146
|
+
* This returns a promise which will resolve to a
|
|
147
|
+
* {@link Signal.Computed} signal once the promise returned by the
|
|
148
|
+
* computation function resolves, and will update itself whenever
|
|
149
|
+
* subsequent calls to the computation function resolve.
|
|
150
|
+
*
|
|
151
|
+
* The function is provided with an {@link AbortSignal} which any async
|
|
152
|
+
* jobs started from it should abide by. If a signal dependency changes
|
|
153
|
+
* while the job is running, the {@link AbortSignal} will be triggered
|
|
154
|
+
* and the job restarted.
|
|
155
|
+
*/
|
|
85
156
|
asyncComputed(fn, options) {
|
|
86
157
|
const result = Promise.withResolvers();
|
|
87
158
|
const stream = SignalGlobal.computed(() => Async.abortable(fn));
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,YAAY,EAAsB,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAe,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/signal.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signal.test.js","sourceRoot":"","sources":["../src/signal.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"signal.test.js","sourceRoot":"","sources":["../src/signal.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bodil/signal",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Signal implementation built on the TC39 Signals Proposal",
|
|
5
|
+
"homepage": "https://codeberg.org/bodil/signal",
|
|
5
6
|
"repository": {
|
|
6
7
|
"type": "git",
|
|
7
|
-
"url": "git+https://
|
|
8
|
+
"url": "git+https://codeberg.org/bodil/signal.git"
|
|
8
9
|
},
|
|
9
10
|
"license": "EUPL-1.2+",
|
|
10
11
|
"module": "dist/index.js",
|
|
@@ -25,27 +26,33 @@
|
|
|
25
26
|
"access": "public"
|
|
26
27
|
},
|
|
27
28
|
"dependencies": {
|
|
28
|
-
"@bodil/core": "^0.
|
|
29
|
-
"@bodil/disposable": "^0.1.
|
|
29
|
+
"@bodil/core": "^0.3.0",
|
|
30
|
+
"@bodil/disposable": "^0.1.5",
|
|
31
|
+
"@bodil/opt": "^0.4.1",
|
|
30
32
|
"signal-polyfill": "^0.2.2"
|
|
31
33
|
},
|
|
32
34
|
"devDependencies": {
|
|
33
|
-
"@bodil/opt-vitest": "^1.
|
|
34
|
-
"@eslint/eslintrc": "^3.3.
|
|
35
|
-
"@eslint/js": "^9.
|
|
36
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
37
|
-
"@typescript-eslint/parser": "^8.
|
|
38
|
-
"eslint": "^9.
|
|
39
|
-
"eslint-config-prettier": "^10.
|
|
40
|
-
"eslint-plugin-jsdoc": "^
|
|
41
|
-
"globals": "^16.
|
|
42
|
-
"
|
|
43
|
-
"
|
|
35
|
+
"@bodil/opt-vitest": "^1.1.0",
|
|
36
|
+
"@eslint/eslintrc": "^3.3.1",
|
|
37
|
+
"@eslint/js": "^9.33.0",
|
|
38
|
+
"@typescript-eslint/eslint-plugin": "^8.39.1",
|
|
39
|
+
"@typescript-eslint/parser": "^8.39.1",
|
|
40
|
+
"eslint": "^9.33.0",
|
|
41
|
+
"eslint-config-prettier": "^10.1.8",
|
|
42
|
+
"eslint-plugin-jsdoc": "^54.0.0",
|
|
43
|
+
"globals": "^16.3.0",
|
|
44
|
+
"typedoc": "^0.28.10",
|
|
45
|
+
"typedoc-plugin-extras": "^4.0.1",
|
|
46
|
+
"typedoc-plugin-mdn-links": "^5.0.8",
|
|
47
|
+
"typescript": "^5.9.2",
|
|
48
|
+
"vitest": "^3.2.4"
|
|
44
49
|
},
|
|
45
50
|
"scripts": {
|
|
46
51
|
"build": "tsc",
|
|
47
52
|
"test": "vitest --run",
|
|
48
53
|
"lint": "eslint src",
|
|
54
|
+
"doc": "typedoc",
|
|
55
|
+
"doc:readthedocs": "typedoc --out $READTHEDOCS_OUTPUT/html",
|
|
49
56
|
"prepublish": "tsc"
|
|
50
57
|
}
|
|
51
58
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,13 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A signal library built on the [TC39 Signals
|
|
3
|
+
* Proposal](https://github.com/tc39/proposal-signals).
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
import { Signal } from "signal-polyfill";
|
|
2
8
|
import { toDisposable, type Disposifiable } from "@bodil/disposable";
|
|
3
|
-
import
|
|
9
|
+
import * as Async from "@bodil/core/async";
|
|
10
|
+
import { Err, Ok, type Result } from "@bodil/opt";
|
|
4
11
|
|
|
5
12
|
interface ISignal<A> {
|
|
13
|
+
/**
|
|
14
|
+
* The current value of the signal.
|
|
15
|
+
*
|
|
16
|
+
* When this is read inside a computation function or an effect function,
|
|
17
|
+
* this signal is automatically added to the effect or computed signal as a
|
|
18
|
+
* dependency.
|
|
19
|
+
*/
|
|
6
20
|
readonly value: A;
|
|
7
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Construct a {@link Signal.Computed} signal using a mapping function over
|
|
23
|
+
* the current value of this signal.
|
|
24
|
+
*/
|
|
25
|
+
map<B>(fn: (value: A) => B): SignalGlobal.Computed<B>;
|
|
26
|
+
/**
|
|
27
|
+
* Subscribe to changes to the value of this signal.
|
|
28
|
+
*/
|
|
8
29
|
on(callback: (value: A) => void): Disposable;
|
|
9
30
|
}
|
|
10
31
|
|
|
32
|
+
/**
|
|
33
|
+
* A writable state signal.
|
|
34
|
+
*/
|
|
11
35
|
class StateSignal<A> extends Signal.State<A> implements ISignal<A> {
|
|
12
36
|
get value(): A {
|
|
13
37
|
return this.get();
|
|
@@ -17,15 +41,21 @@ class StateSignal<A> extends Signal.State<A> implements ISignal<A> {
|
|
|
17
41
|
this.set(value);
|
|
18
42
|
}
|
|
19
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Update the current value of this signal using a function.
|
|
46
|
+
*/
|
|
20
47
|
update(fn: (value: A) => A): void {
|
|
21
48
|
this.set(Signal.subtle.untrack(() => fn(this.get())));
|
|
22
49
|
}
|
|
23
50
|
|
|
24
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Get a read only version of this signal.
|
|
53
|
+
*/
|
|
54
|
+
readOnly(): SignalGlobal.Computed<A> {
|
|
25
55
|
return SignalGlobal.computed(() => this.get());
|
|
26
56
|
}
|
|
27
57
|
|
|
28
|
-
map<B>(fn: (value: A) => B):
|
|
58
|
+
map<B>(fn: (value: A) => B): SignalGlobal.Computed<B> {
|
|
29
59
|
return SignalGlobal.computed(() => fn(this.get()));
|
|
30
60
|
}
|
|
31
61
|
|
|
@@ -33,17 +63,20 @@ class StateSignal<A> extends Signal.State<A> implements ISignal<A> {
|
|
|
33
63
|
return SignalGlobal.subscribe(this, callback);
|
|
34
64
|
}
|
|
35
65
|
|
|
36
|
-
static is(v: unknown): v is
|
|
66
|
+
static is(v: unknown): v is SignalGlobal.State<unknown> {
|
|
37
67
|
return v instanceof StateSignal;
|
|
38
68
|
}
|
|
39
69
|
}
|
|
40
70
|
|
|
71
|
+
/**
|
|
72
|
+
* A read only signal computed from the values of other signals.
|
|
73
|
+
*/
|
|
41
74
|
class ComputedSignal<A> extends Signal.Computed<A> implements ISignal<A> {
|
|
42
75
|
get value(): A {
|
|
43
76
|
return this.get();
|
|
44
77
|
}
|
|
45
78
|
|
|
46
|
-
map<B>(fn: (value: A) => B):
|
|
79
|
+
map<B>(fn: (value: A) => B): SignalGlobal.Computed<B> {
|
|
47
80
|
return SignalGlobal.computed(() => fn(this.get()));
|
|
48
81
|
}
|
|
49
82
|
|
|
@@ -51,7 +84,7 @@ class ComputedSignal<A> extends Signal.Computed<A> implements ISignal<A> {
|
|
|
51
84
|
return SignalGlobal.subscribe(this, callback);
|
|
52
85
|
}
|
|
53
86
|
|
|
54
|
-
static is(v: unknown): v is
|
|
87
|
+
static is(v: unknown): v is SignalGlobal.Computed<unknown> {
|
|
55
88
|
return v instanceof ComputedSignal;
|
|
56
89
|
}
|
|
57
90
|
}
|
|
@@ -72,31 +105,69 @@ function effectProcess(): void {
|
|
|
72
105
|
effectWatcher.watch();
|
|
73
106
|
}
|
|
74
107
|
|
|
75
|
-
type SignalGlobal<A> =
|
|
108
|
+
type SignalGlobal<A> = SignalGlobal.State<A> | SignalGlobal.Computed<A>;
|
|
76
109
|
|
|
77
110
|
const SignalGlobal = Object.assign(
|
|
111
|
+
/**
|
|
112
|
+
* Construct a new {@link Signal.State} signal containing the provided value.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* const sig = Signal("Hello Joe!");
|
|
116
|
+
*/
|
|
78
117
|
function <A>(value: A, options?: Signal.Options<A>): SignalGlobal.State<A> {
|
|
79
|
-
return new
|
|
118
|
+
return new SignalGlobal.State(value, options);
|
|
80
119
|
},
|
|
81
120
|
{
|
|
121
|
+
/**
|
|
122
|
+
* Test whether the given value is a signal.
|
|
123
|
+
*/
|
|
82
124
|
is(v: unknown): v is SignalGlobal<unknown> {
|
|
83
|
-
return
|
|
125
|
+
return SignalGlobal.State.is(v) || SignalGlobal.Computed.is(v);
|
|
84
126
|
},
|
|
85
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Construct a new {@link Signal.Computed} signal using the provided
|
|
130
|
+
* computation function.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* const sig1 = Signal(2);
|
|
134
|
+
* const sig2 = Signal(3);
|
|
135
|
+
* const sum = Signal.computed(() => sig1.get() + sig2.get());
|
|
136
|
+
* assert(sum.get() === 5);
|
|
137
|
+
*/
|
|
86
138
|
computed<A>(
|
|
87
|
-
fn: (this:
|
|
139
|
+
fn: (this: SignalGlobal.Computed<A>) => A,
|
|
88
140
|
options?: Signal.Options<A>
|
|
89
141
|
): SignalGlobal.Computed<A> {
|
|
90
|
-
return new
|
|
142
|
+
return new SignalGlobal.Computed(fn, options);
|
|
91
143
|
},
|
|
92
144
|
|
|
93
|
-
|
|
145
|
+
/**
|
|
146
|
+
* Suscribe to a signal.
|
|
147
|
+
*
|
|
148
|
+
* The provided callback will be called every time the value of the
|
|
149
|
+
* signal changes.
|
|
150
|
+
*/
|
|
151
|
+
subscribe<A>(signal: SignalGlobal<A>, callback: (value: A) => void): Disposable {
|
|
94
152
|
return SignalGlobal.effect(() => callback(signal.value));
|
|
95
153
|
},
|
|
96
154
|
|
|
155
|
+
/**
|
|
156
|
+
* Create an effect responding to signal changes.
|
|
157
|
+
*
|
|
158
|
+
* The provided function will be called immediately, and again every
|
|
159
|
+
* time a signal that was read by the function changes.
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* const sig = Signal("Hello Joe!");
|
|
163
|
+
* effect(() => console.log("Signal value is:", sig.get()));
|
|
164
|
+
* // prints "Signal value is: Hello Joe!"
|
|
165
|
+
* sig.set("Hello Mike!");
|
|
166
|
+
* // prints "Signal value is: Hello Mike!"
|
|
167
|
+
*/
|
|
97
168
|
effect(fn: () => Disposifiable | void): Disposable {
|
|
98
169
|
let cleanup: Disposable | undefined;
|
|
99
|
-
const computed = new
|
|
170
|
+
const computed = new SignalGlobal.Computed(() => {
|
|
100
171
|
if (cleanup !== undefined) {
|
|
101
172
|
cleanup[Symbol.dispose]();
|
|
102
173
|
}
|
|
@@ -113,13 +184,27 @@ const SignalGlobal = Object.assign(
|
|
|
113
184
|
});
|
|
114
185
|
},
|
|
115
186
|
|
|
187
|
+
/**
|
|
188
|
+
* Construct a new {@link Signal.Computed} signal using an async
|
|
189
|
+
* computation function.
|
|
190
|
+
*
|
|
191
|
+
* This returns a promise which will resolve to a
|
|
192
|
+
* {@link Signal.Computed} signal once the promise returned by the
|
|
193
|
+
* computation function resolves, and will update itself whenever
|
|
194
|
+
* subsequent calls to the computation function resolve.
|
|
195
|
+
*
|
|
196
|
+
* The function is provided with an {@link AbortSignal} which any async
|
|
197
|
+
* jobs started from it should abide by. If a signal dependency changes
|
|
198
|
+
* while the job is running, the {@link AbortSignal} will be triggered
|
|
199
|
+
* and the job restarted.
|
|
200
|
+
*/
|
|
116
201
|
asyncComputed<A>(
|
|
117
202
|
fn: (abort: AbortSignal) => Promise<A>,
|
|
118
203
|
options?: Signal.Options<A>
|
|
119
204
|
): Promise<SignalGlobal.Computed<A>> {
|
|
120
|
-
const result = Promise.withResolvers<
|
|
205
|
+
const result = Promise.withResolvers<SignalGlobal.Computed<A>>();
|
|
121
206
|
const stream = SignalGlobal.computed(() => Async.abortable(fn));
|
|
122
|
-
const sig:
|
|
207
|
+
const sig: SignalGlobal.State<Result<A, Error>> = SignalGlobal(Err(new Error()));
|
|
123
208
|
let job: Async.AbortableJob<A> | undefined = undefined;
|
|
124
209
|
let resolved = false;
|
|
125
210
|
const resolve = () => {
|
|
@@ -157,7 +242,9 @@ const SignalGlobal = Object.assign(
|
|
|
157
242
|
);
|
|
158
243
|
|
|
159
244
|
declare namespace SignalGlobal {
|
|
245
|
+
/** @interface */
|
|
160
246
|
export type State<A> = StateSignal<A>;
|
|
247
|
+
/** @interface */
|
|
161
248
|
export type Computed<A> = ComputedSignal<A>;
|
|
162
249
|
}
|
|
163
250
|
|
package/src/signal.test.ts
CHANGED