@bodil/signal 0.3.0 → 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 CHANGED
@@ -1,34 +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
- map<B>(fn: (value: A) => B): Computed<B>;
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
  }
8
- declare class State<A> extends Signal.State<A> implements ISignal<A> {
27
+ /**
28
+ * A writable state signal.
29
+ */
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
- readOnly(): Computed<A>;
13
- map<B>(fn: (value: A) => B): Computed<B>;
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 State<unknown>;
43
+ static is(v: unknown): v is SignalGlobal.State<unknown>;
16
44
  }
17
- declare class Computed<A> extends Signal.Computed<A> implements ISignal<A> {
45
+ /**
46
+ * A read only signal computed from the values of other signals.
47
+ */
48
+ declare class ComputedSignal<A> extends Signal.Computed<A> implements ISignal<A> {
18
49
  get value(): A;
19
- map<B>(fn: (value: A) => B): Computed<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 Computed<unknown>;
52
+ static is(v: unknown): v is SignalGlobal.Computed<unknown>;
22
53
  }
23
- type AnySignal<A> = State<A> | Computed<A>;
24
- declare const AnySignal: (<A>(value: A, options?: Signal.Options<A>) => State<A>) & {
25
- is(v: unknown): v is AnySignal<unknown>;
26
- computed<A>(fn: (this: Computed<A>) => A, options?: Signal.Options<A>): Computed<A>;
27
- subscribe<A>(signal: ISignal<A>, callback: (value: A) => void): Disposable;
54
+ type SignalGlobal<A> = SignalGlobal.State<A> | SignalGlobal.Computed<A>;
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
+ */
59
+ is(v: unknown): v is SignalGlobal<unknown>;
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;
29
- asyncComputed<A>(fn: (abort: AbortSignal) => Promise<A>, options?: Signal.Options<A>): Promise<Computed<A>>;
30
- State: typeof State;
31
- Computed: typeof Computed;
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
+ */
106
+ asyncComputed<A>(fn: (abort: AbortSignal) => Promise<A>, options?: Signal.Options<A>): Promise<SignalGlobal.Computed<A>>;
107
+ State: typeof StateSignal;
108
+ Computed: typeof ComputedSignal;
32
109
  subtle: typeof Signal.subtle;
33
110
  };
34
- export { AnySignal as Signal };
111
+ declare namespace SignalGlobal {
112
+ /** @interface */
113
+ type State<A> = StateSignal<A>;
114
+ /** @interface */
115
+ type Computed<A> = ComputedSignal<A>;
116
+ }
117
+ export { SignalGlobal as Signal };
package/dist/index.js CHANGED
@@ -1,41 +1,59 @@
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 { Err, Ok, Async } from "@bodil/core";
4
- class State extends Signal.State {
8
+ import * as Async from "@bodil/core/async";
9
+ import { Err, Ok } from "@bodil/opt";
10
+ /**
11
+ * A writable state signal.
12
+ */
13
+ class StateSignal extends Signal.State {
5
14
  get value() {
6
15
  return this.get();
7
16
  }
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
- return AnySignal.computed(() => this.get());
30
+ return SignalGlobal.computed(() => this.get());
16
31
  }
17
32
  map(fn) {
18
- return AnySignal.computed(() => fn(this.get()));
33
+ return SignalGlobal.computed(() => fn(this.get()));
19
34
  }
20
35
  on(callback) {
21
- return AnySignal.subscribe(this, callback);
36
+ return SignalGlobal.subscribe(this, callback);
22
37
  }
23
38
  static is(v) {
24
- return v instanceof State;
39
+ return v instanceof StateSignal;
25
40
  }
26
41
  }
27
- class Computed extends Signal.Computed {
42
+ /**
43
+ * A read only signal computed from the values of other signals.
44
+ */
45
+ class ComputedSignal extends Signal.Computed {
28
46
  get value() {
29
47
  return this.get();
30
48
  }
31
49
  map(fn) {
32
- return AnySignal.computed(() => fn(this.get()));
50
+ return SignalGlobal.computed(() => fn(this.get()));
33
51
  }
34
52
  on(callback) {
35
- return AnySignal.subscribe(this, callback);
53
+ return SignalGlobal.subscribe(this, callback);
36
54
  }
37
55
  static is(v) {
38
- return v instanceof Computed;
56
+ return v instanceof ComputedSignal;
39
57
  }
40
58
  }
41
59
  let effectNeedsEnqueue = true;
@@ -52,21 +70,60 @@ function effectProcess() {
52
70
  }
53
71
  effectWatcher.watch();
54
72
  }
55
- const AnySignal = Object.assign(function (value, options) {
56
- return new State(value, options);
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 State.is(v) || Computed.is(v);
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 Computed(fn, options);
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
- return AnySignal.effect(() => callback(signal.value));
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 Computed(() => {
126
+ const computed = new SignalGlobal.Computed(() => {
70
127
  if (cleanup !== undefined) {
71
128
  cleanup[Symbol.dispose]();
72
129
  }
@@ -82,19 +139,33 @@ const AnySignal = 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
- const stream = AnySignal.computed(() => Async.abortable(fn));
88
- const sig = AnySignal(Err(new Error()));
158
+ const stream = SignalGlobal.computed(() => Async.abortable(fn));
159
+ const sig = SignalGlobal(Err(new Error()));
89
160
  let job = undefined;
90
161
  let resolved = false;
91
162
  const resolve = () => {
92
163
  if (!resolved) {
93
164
  resolved = true;
94
- result.resolve(AnySignal.computed(() => sig.get().unwrapExact(), options));
165
+ result.resolve(SignalGlobal.computed(() => sig.get().unwrapExact(), options));
95
166
  }
96
167
  };
97
- AnySignal.effect(() => {
168
+ SignalGlobal.effect(() => {
98
169
  if (job !== undefined) {
99
170
  job.abort();
100
171
  }
@@ -112,9 +183,9 @@ const AnySignal = Object.assign(function (value, options) {
112
183
  });
113
184
  return result.promise;
114
185
  },
115
- State,
116
- Computed,
186
+ State: StateSignal,
187
+ Computed: ComputedSignal,
117
188
  subtle: Signal.subtle,
118
189
  });
119
- export { AnySignal as Signal };
190
+ export { SignalGlobal as Signal };
120
191
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -85,4 +85,14 @@ test("isSignal", () => {
85
85
  expect(Signal.Computed.is(s2)).toBeTruthy();
86
86
  expect(Signal.is("wibble")).toBeFalsy();
87
87
  });
88
+ test("Signal types", () => {
89
+ const s1 = Signal(1);
90
+ const s2 = Signal.computed(() => s1.get());
91
+ function foo(_signal) {
92
+ // ensure Signal<A> is an accessible type
93
+ // and that it accepts both concrete signal types.
94
+ }
95
+ foo(s1);
96
+ foo(s2);
97
+ });
88
98
  //# sourceMappingURL=signal.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"signal.test.js","sourceRoot":"","sources":["../src/signal.test.ts"],"names":[],"mappings":"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"}
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.0",
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://github.com/bodil/signal.git"
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.1.1",
29
- "@bodil/disposable": "^0.1.2",
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.0.0",
34
- "@eslint/eslintrc": "^3.3.0",
35
- "@eslint/js": "^9.21.0",
36
- "@typescript-eslint/eslint-plugin": "^8.25.0",
37
- "@typescript-eslint/parser": "^8.25.0",
38
- "eslint": "^9.21.0",
39
- "eslint-config-prettier": "^10.0.2",
40
- "eslint-plugin-jsdoc": "^50.6.3",
41
- "globals": "^16.0.0",
42
- "typescript": "^5.7.3",
43
- "vitest": "^3.0.7"
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,14 +1,38 @@
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 { Err, Ok, type Result, Async } from "@bodil/core";
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
- map<B>(fn: (value: A) => B): Computed<B>;
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
 
11
- class State<A> extends Signal.State<A> implements ISignal<A> {
32
+ /**
33
+ * A writable state signal.
34
+ */
35
+ class StateSignal<A> extends Signal.State<A> implements ISignal<A> {
12
36
  get value(): A {
13
37
  return this.get();
14
38
  }
@@ -17,42 +41,51 @@ class State<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
- readOnly(): Computed<A> {
25
- return AnySignal.computed(() => this.get());
51
+ /**
52
+ * Get a read only version of this signal.
53
+ */
54
+ readOnly(): SignalGlobal.Computed<A> {
55
+ return SignalGlobal.computed(() => this.get());
26
56
  }
27
57
 
28
- map<B>(fn: (value: A) => B): Computed<B> {
29
- return AnySignal.computed(() => fn(this.get()));
58
+ map<B>(fn: (value: A) => B): SignalGlobal.Computed<B> {
59
+ return SignalGlobal.computed(() => fn(this.get()));
30
60
  }
31
61
 
32
62
  on(callback: (value: A) => void): Disposable {
33
- return AnySignal.subscribe(this, callback);
63
+ return SignalGlobal.subscribe(this, callback);
34
64
  }
35
65
 
36
- static is(v: unknown): v is State<unknown> {
37
- return v instanceof State;
66
+ static is(v: unknown): v is SignalGlobal.State<unknown> {
67
+ return v instanceof StateSignal;
38
68
  }
39
69
  }
40
70
 
41
- class Computed<A> extends Signal.Computed<A> implements ISignal<A> {
71
+ /**
72
+ * A read only signal computed from the values of other signals.
73
+ */
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): Computed<B> {
47
- return AnySignal.computed(() => fn(this.get()));
79
+ map<B>(fn: (value: A) => B): SignalGlobal.Computed<B> {
80
+ return SignalGlobal.computed(() => fn(this.get()));
48
81
  }
49
82
 
50
83
  on(callback: (value: A) => void): Disposable {
51
- return AnySignal.subscribe(this, callback);
84
+ return SignalGlobal.subscribe(this, callback);
52
85
  }
53
86
 
54
- static is(v: unknown): v is Computed<unknown> {
55
- return v instanceof Computed;
87
+ static is(v: unknown): v is SignalGlobal.Computed<unknown> {
88
+ return v instanceof ComputedSignal;
56
89
  }
57
90
  }
58
91
 
@@ -72,28 +105,69 @@ function effectProcess(): void {
72
105
  effectWatcher.watch();
73
106
  }
74
107
 
75
- type AnySignal<A> = State<A> | Computed<A>;
76
-
77
- const AnySignal = Object.assign(
78
- function <A>(value: A, options?: Signal.Options<A>): State<A> {
79
- return new State(value, options);
108
+ type SignalGlobal<A> = SignalGlobal.State<A> | SignalGlobal.Computed<A>;
109
+
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
+ */
117
+ function <A>(value: A, options?: Signal.Options<A>): SignalGlobal.State<A> {
118
+ return new SignalGlobal.State(value, options);
80
119
  },
81
120
  {
82
- is(v: unknown): v is AnySignal<unknown> {
83
- return State.is(v) || Computed.is(v);
121
+ /**
122
+ * Test whether the given value is a signal.
123
+ */
124
+ is(v: unknown): v is SignalGlobal<unknown> {
125
+ return SignalGlobal.State.is(v) || SignalGlobal.Computed.is(v);
84
126
  },
85
127
 
86
- computed<A>(fn: (this: Computed<A>) => A, options?: Signal.Options<A>): Computed<A> {
87
- return new Computed(fn, options);
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
+ */
138
+ computed<A>(
139
+ fn: (this: SignalGlobal.Computed<A>) => A,
140
+ options?: Signal.Options<A>
141
+ ): SignalGlobal.Computed<A> {
142
+ return new SignalGlobal.Computed(fn, options);
88
143
  },
89
144
 
90
- subscribe<A>(signal: ISignal<A>, callback: (value: A) => void): Disposable {
91
- return AnySignal.effect(() => callback(signal.value));
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 {
152
+ return SignalGlobal.effect(() => callback(signal.value));
92
153
  },
93
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
+ */
94
168
  effect(fn: () => Disposifiable | void): Disposable {
95
169
  let cleanup: Disposable | undefined;
96
- const computed = new Computed(() => {
170
+ const computed = new SignalGlobal.Computed(() => {
97
171
  if (cleanup !== undefined) {
98
172
  cleanup[Symbol.dispose]();
99
173
  }
@@ -110,22 +184,36 @@ const AnySignal = Object.assign(
110
184
  });
111
185
  },
112
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
+ */
113
201
  asyncComputed<A>(
114
202
  fn: (abort: AbortSignal) => Promise<A>,
115
203
  options?: Signal.Options<A>
116
- ): Promise<Computed<A>> {
117
- const result = Promise.withResolvers<Computed<A>>();
118
- const stream = AnySignal.computed(() => Async.abortable(fn));
119
- const sig: State<Result<A, Error>> = AnySignal(Err(new Error()));
204
+ ): Promise<SignalGlobal.Computed<A>> {
205
+ const result = Promise.withResolvers<SignalGlobal.Computed<A>>();
206
+ const stream = SignalGlobal.computed(() => Async.abortable(fn));
207
+ const sig: SignalGlobal.State<Result<A, Error>> = SignalGlobal(Err(new Error()));
120
208
  let job: Async.AbortableJob<A> | undefined = undefined;
121
209
  let resolved = false;
122
210
  const resolve = () => {
123
211
  if (!resolved) {
124
212
  resolved = true;
125
- result.resolve(AnySignal.computed(() => sig.get().unwrapExact(), options));
213
+ result.resolve(SignalGlobal.computed(() => sig.get().unwrapExact(), options));
126
214
  }
127
215
  };
128
- AnySignal.effect(() => {
216
+ SignalGlobal.effect(() => {
129
217
  if (job !== undefined) {
130
218
  job.abort();
131
219
  }
@@ -147,10 +235,17 @@ const AnySignal = Object.assign(
147
235
  return result.promise;
148
236
  },
149
237
 
150
- State,
151
- Computed,
238
+ State: StateSignal,
239
+ Computed: ComputedSignal,
152
240
  subtle: Signal.subtle,
153
241
  }
154
242
  );
155
243
 
156
- export { AnySignal as Signal };
244
+ declare namespace SignalGlobal {
245
+ /** @interface */
246
+ export type State<A> = StateSignal<A>;
247
+ /** @interface */
248
+ export type Computed<A> = ComputedSignal<A>;
249
+ }
250
+
251
+ export { SignalGlobal as Signal };
@@ -77,7 +77,7 @@ test("asyncComputed", async () => {
77
77
  });
78
78
 
79
79
  test("isSignal", () => {
80
- const s1 = Signal(1);
80
+ const s1: Signal.State<number> = Signal(1);
81
81
  expect(Signal.is(s1)).toBeTruthy();
82
82
  expect(Signal.State.is(s1)).toBeTruthy();
83
83
  expect(Signal.Computed.is(s1)).toBeFalsy();
@@ -89,3 +89,15 @@ test("isSignal", () => {
89
89
 
90
90
  expect(Signal.is("wibble")).toBeFalsy();
91
91
  });
92
+
93
+ test("Signal types", () => {
94
+ const s1: Signal.State<number> = Signal(1);
95
+ const s2: Signal.Computed<number> = Signal.computed(() => s1.get());
96
+
97
+ function foo(_signal: Signal<unknown>) {
98
+ // ensure Signal<A> is an accessible type
99
+ // and that it accepts both concrete signal types.
100
+ }
101
+ foo(s1);
102
+ foo(s2);
103
+ });