@bodil/signal 0.2.2 → 0.3.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/dist/index.d.ts CHANGED
@@ -1,31 +1,34 @@
1
1
  import { Signal } from "signal-polyfill";
2
2
  import { type Disposifiable } from "@bodil/disposable";
3
- interface ReadableSignal<A> {
3
+ interface ISignal<A> {
4
4
  readonly value: A;
5
- map<B>(fn: (value: A) => B): ComputedSignal<B>;
5
+ map<B>(fn: (value: A) => B): Computed<B>;
6
6
  on(callback: (value: A) => void): Disposable;
7
7
  }
8
- export declare class StateSignal<A> extends Signal.State<A> implements ReadableSignal<A> {
8
+ declare class State<A> extends Signal.State<A> implements ISignal<A> {
9
9
  get value(): A;
10
10
  set value(value: A);
11
11
  update(fn: (value: A) => A): void;
12
- readOnly(): ComputedSignal<A>;
13
- map<B>(fn: (value: A) => B): ComputedSignal<B>;
12
+ readOnly(): Computed<A>;
13
+ map<B>(fn: (value: A) => B): Computed<B>;
14
14
  on(callback: (value: A) => void): Disposable;
15
+ static is(v: unknown): v is State<unknown>;
15
16
  }
16
- export declare class ComputedSignal<A> extends Signal.Computed<A> implements ReadableSignal<A> {
17
+ declare class Computed<A> extends Signal.Computed<A> implements ISignal<A> {
17
18
  get value(): A;
18
- map<B>(fn: (value: A) => B): ComputedSignal<B>;
19
+ map<B>(fn: (value: A) => B): Computed<B>;
19
20
  on(callback: (value: A) => void): Disposable;
21
+ static is(v: unknown): v is Computed<unknown>;
20
22
  }
21
- type AnySignal<A> = StateSignal<A> | ComputedSignal<A>;
22
- export type { AnySignal as Signal };
23
- export declare const subtle: typeof Signal.subtle;
24
- export declare function isStateSignal(v: unknown): v is StateSignal<unknown>;
25
- export declare function isComputedSignal(v: unknown): v is ComputedSignal<unknown>;
26
- export declare function isSignal(v: unknown): v is AnySignal<unknown>;
27
- export declare function signal<A>(value: A, options?: Signal.Options<A>): StateSignal<A>;
28
- export declare function computed<A>(fn: (this: ComputedSignal<A>) => A, options?: Signal.Options<A>): ComputedSignal<A>;
29
- export declare function effect(fn: () => Disposifiable | void): Disposable;
30
- export declare function subscribe<A>(signal: ReadableSignal<A>, callback: (value: A) => void): Disposable;
31
- export declare function asyncComputed<A>(fn: (abort: AbortSignal) => Promise<A>, options?: Signal.Options<A>): Promise<ComputedSignal<A>>;
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;
28
+ 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;
32
+ subtle: typeof Signal.subtle;
33
+ };
34
+ export { AnySignal as Signal };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Signal } from "signal-polyfill";
2
2
  import { toDisposable } from "@bodil/disposable";
3
3
  import { Err, Ok, Async } from "@bodil/core";
4
- export class StateSignal extends Signal.State {
4
+ class State extends Signal.State {
5
5
  get value() {
6
6
  return this.get();
7
7
  }
@@ -12,41 +12,31 @@ export class StateSignal extends Signal.State {
12
12
  this.set(Signal.subtle.untrack(() => fn(this.get())));
13
13
  }
14
14
  readOnly() {
15
- return computed(() => this.get());
15
+ return AnySignal.computed(() => this.get());
16
16
  }
17
17
  map(fn) {
18
- return computed(() => fn(this.get()));
18
+ return AnySignal.computed(() => fn(this.get()));
19
19
  }
20
20
  on(callback) {
21
- return subscribe(this, callback);
21
+ return AnySignal.subscribe(this, callback);
22
+ }
23
+ static is(v) {
24
+ return v instanceof State;
22
25
  }
23
26
  }
24
- export class ComputedSignal extends Signal.Computed {
27
+ class Computed extends Signal.Computed {
25
28
  get value() {
26
29
  return this.get();
27
30
  }
28
31
  map(fn) {
29
- return computed(() => fn(this.get()));
32
+ return AnySignal.computed(() => fn(this.get()));
30
33
  }
31
34
  on(callback) {
32
- return subscribe(this, callback);
35
+ return AnySignal.subscribe(this, callback);
36
+ }
37
+ static is(v) {
38
+ return v instanceof Computed;
33
39
  }
34
- }
35
- export const subtle = Signal.subtle;
36
- export function isStateSignal(v) {
37
- return v instanceof StateSignal;
38
- }
39
- export function isComputedSignal(v) {
40
- return v instanceof ComputedSignal;
41
- }
42
- export function isSignal(v) {
43
- return isStateSignal(v) || isComputedSignal(v);
44
- }
45
- export function signal(value, options) {
46
- return new StateSignal(value, options);
47
- }
48
- export function computed(fn, options) {
49
- return new ComputedSignal(fn, options);
50
40
  }
51
41
  let effectNeedsEnqueue = true;
52
42
  const effectWatcher = new Signal.subtle.Watcher(() => {
@@ -62,55 +52,69 @@ function effectProcess() {
62
52
  }
63
53
  effectWatcher.watch();
64
54
  }
65
- export function effect(fn) {
66
- let cleanup;
67
- const computed = new ComputedSignal(() => {
68
- if (cleanup !== undefined) {
69
- cleanup[Symbol.dispose]();
70
- }
71
- const result = fn();
72
- cleanup = result !== undefined ? toDisposable(result) : undefined;
73
- });
74
- effectWatcher.watch(computed);
75
- computed.get();
76
- return toDisposable(() => {
77
- effectWatcher.unwatch(computed);
78
- if (cleanup !== undefined) {
79
- cleanup[Symbol.dispose]();
80
- }
81
- });
82
- }
83
- export function subscribe(signal, callback) {
84
- return effect(() => callback(signal.value));
85
- }
86
- export function asyncComputed(fn, options) {
87
- const result = Promise.withResolvers();
88
- const stream = computed(() => Async.abortable(fn));
89
- const sig = signal(Err(new Error()));
90
- let job = undefined;
91
- let resolved = false;
92
- const resolve = () => {
93
- if (!resolved) {
94
- resolved = true;
95
- result.resolve(computed(() => sig.get().unwrapExact(), options));
96
- }
97
- };
98
- effect(() => {
99
- if (job !== undefined) {
100
- job.abort();
101
- }
102
- job = stream.get();
103
- job.result.then((next) => {
104
- sig.set(Ok(next));
105
- resolve();
106
- }, (error) => {
107
- if (job?.signal.aborted === true) {
108
- return;
55
+ const AnySignal = Object.assign(function (value, options) {
56
+ return new State(value, options);
57
+ }, {
58
+ is(v) {
59
+ return State.is(v) || Computed.is(v);
60
+ },
61
+ computed(fn, options) {
62
+ return new Computed(fn, options);
63
+ },
64
+ subscribe(signal, callback) {
65
+ return AnySignal.effect(() => callback(signal.value));
66
+ },
67
+ effect(fn) {
68
+ let cleanup;
69
+ const computed = new Computed(() => {
70
+ if (cleanup !== undefined) {
71
+ cleanup[Symbol.dispose]();
109
72
  }
110
- sig.set(Err(error));
111
- resolve();
73
+ const result = fn();
74
+ cleanup = result !== undefined ? toDisposable(result) : undefined;
112
75
  });
113
- });
114
- return result.promise;
115
- }
76
+ effectWatcher.watch(computed);
77
+ computed.get();
78
+ return toDisposable(() => {
79
+ effectWatcher.unwatch(computed);
80
+ if (cleanup !== undefined) {
81
+ cleanup[Symbol.dispose]();
82
+ }
83
+ });
84
+ },
85
+ asyncComputed(fn, options) {
86
+ const result = Promise.withResolvers();
87
+ const stream = AnySignal.computed(() => Async.abortable(fn));
88
+ const sig = AnySignal(Err(new Error()));
89
+ let job = undefined;
90
+ let resolved = false;
91
+ const resolve = () => {
92
+ if (!resolved) {
93
+ resolved = true;
94
+ result.resolve(AnySignal.computed(() => sig.get().unwrapExact(), options));
95
+ }
96
+ };
97
+ AnySignal.effect(() => {
98
+ if (job !== undefined) {
99
+ job.abort();
100
+ }
101
+ job = stream.get();
102
+ job.result.then((next) => {
103
+ sig.set(Ok(next));
104
+ resolve();
105
+ }, (error) => {
106
+ if (job?.signal.aborted === true) {
107
+ return;
108
+ }
109
+ sig.set(Err(error));
110
+ resolve();
111
+ });
112
+ });
113
+ return result.promise;
114
+ },
115
+ State,
116
+ Computed,
117
+ subtle: Signal.subtle,
118
+ });
119
+ export { AnySignal as Signal };
116
120
  //# 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":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,YAAY,EAAsB,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAe,KAAK,EAAE,MAAM,aAAa,CAAC;AAQ1D,MAAM,OAAO,WAAe,SAAQ,MAAM,CAAC,KAAQ;IAC/C,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC;IACtB,CAAC;IAED,IAAI,KAAK,CAAC,KAAQ;QACd,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,CAAC,EAAmB;QACtB,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,QAAQ;QACJ,OAAO,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACtC,CAAC;IAED,GAAG,CAAI,EAAmB;QACtB,OAAO,QAAQ,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED,EAAE,CAAC,QAA4B;QAC3B,OAAO,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC;CACJ;AAED,MAAM,OAAO,cAAkB,SAAQ,MAAM,CAAC,QAAW;IACrD,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC;IACtB,CAAC;IAED,GAAG,CAAI,EAAmB;QACtB,OAAO,QAAQ,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED,EAAE,CAAC,QAA4B;QAC3B,OAAO,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC;CACJ;AAMD,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AAEpC,MAAM,UAAU,aAAa,CAAC,CAAU;IACpC,OAAO,CAAC,YAAY,WAAW,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,CAAU;IACvC,OAAO,CAAC,YAAY,cAAc,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,CAAU;IAC/B,OAAO,aAAa,CAAC,CAAC,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,MAAM,CAAI,KAAQ,EAAE,OAA2B;IAC3D,OAAO,IAAI,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,QAAQ,CACpB,EAAkC,EAClC,OAA2B;IAE3B,OAAO,IAAI,cAAc,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,IAAI,kBAAkB,GAAG,IAAI,CAAC;AAC9B,MAAM,aAAa,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE;IACjD,IAAI,kBAAkB,EAAE,CAAC;QACrB,kBAAkB,GAAG,KAAK,CAAC;QAC3B,cAAc,CAAC,aAAa,CAAC,CAAC;IAClC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,SAAS,aAAa;IAClB,kBAAkB,GAAG,IAAI,CAAC;IAC1B,KAAK,MAAM,GAAG,IAAI,aAAa,CAAC,UAAU,EAAE,EAAE,CAAC;QAC3C,GAAG,CAAC,GAAG,EAAE,CAAC;IACd,CAAC;IACD,aAAa,CAAC,KAAK,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,EAA8B;IACjD,IAAI,OAA+B,CAAC;IACpC,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,GAAG,EAAE;QACrC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9B,CAAC;QACD,MAAM,MAAM,GAAG,EAAE,EAAE,CAAC;QACpB,OAAO,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACtE,CAAC,CAAC,CAAC;IACH,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,CAAC;IACf,OAAO,YAAY,CAAC,GAAG,EAAE;QACrB,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAChC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9B,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,UAAU,SAAS,CAAI,MAAyB,EAAE,QAA4B;IAChF,OAAO,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,aAAa,CACzB,EAAsC,EACtC,OAA2B;IAE3B,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,EAAqB,CAAC;IAC1D,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;IACnD,MAAM,GAAG,GAAkC,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC;IACpE,IAAI,GAAG,GAAsC,SAAS,CAAC;IACvD,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,MAAM,OAAO,GAAG,GAAG,EAAE;QACjB,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,QAAQ,GAAG,IAAI,CAAC;YAChB,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;QACrE,CAAC;IACL,CAAC,CAAC;IACF,MAAM,CAAC,GAAG,EAAE;QACR,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACpB,GAAG,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;QACD,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;QACnB,GAAG,CAAC,MAAM,CAAC,IAAI,CACX,CAAC,IAAI,EAAE,EAAE;YACL,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;YAClB,OAAO,EAAE,CAAC;QACd,CAAC,EACD,CAAC,KAAK,EAAE,EAAE;YACN,IAAI,GAAG,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;gBAC/B,OAAO;YACX,CAAC;YACD,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;YACpB,OAAO,EAAE,CAAC;QACd,CAAC,CACJ,CAAC;IACN,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,OAAO,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  import { sleep } from "@bodil/core/async";
2
2
  import { expect, test } from "vitest";
3
- import { asyncComputed, computed, effect, isComputedSignal, isSignal, isStateSignal, signal, } from ".";
3
+ import { Signal } from ".";
4
4
  test("Signal", async () => {
5
- const sig = signal(0);
5
+ const sig = Signal(0);
6
6
  const result = [];
7
- effect(() => void result.push(sig.value));
7
+ Signal.effect(() => void result.push(sig.value));
8
8
  expect(result).toEqual([0]);
9
9
  sig.value = 1;
10
10
  sig.value = 2;
@@ -24,8 +24,8 @@ test("Signal", async () => {
24
24
  });
25
25
  test("signal equality", async () => {
26
26
  const result = [];
27
- const sig = signal(0);
28
- effect(() => void result.push(sig.value));
27
+ const sig = Signal(0);
28
+ Signal.effect(() => void result.push(sig.value));
29
29
  expect(result).toEqual([0]);
30
30
  sig.value = 1;
31
31
  await sleep(1);
@@ -50,11 +50,11 @@ test("signal equality", async () => {
50
50
  expect(result).toEqual([0, 1, 2, 3, 2]);
51
51
  });
52
52
  test("asyncComputed", async () => {
53
- const s = signal(1);
54
- const c = await asyncComputed(() => Promise.resolve(s.value + 1));
53
+ const s = Signal(1);
54
+ const c = await Signal.asyncComputed(() => Promise.resolve(s.value + 1));
55
55
  expect(c.value).toEqual(2);
56
56
  try {
57
- await asyncComputed(() => {
57
+ await Signal.asyncComputed(() => {
58
58
  throw new Error("welp!");
59
59
  });
60
60
  throw new Error("computed error failed to throw");
@@ -75,14 +75,14 @@ test("asyncComputed", async () => {
75
75
  expect(c.value).toEqual(4);
76
76
  });
77
77
  test("isSignal", () => {
78
- const s1 = signal(1);
79
- expect(isSignal(s1)).toBeTruthy();
80
- expect(isStateSignal(s1)).toBeTruthy();
81
- expect(isComputedSignal(s1)).toBeFalsy();
82
- const s2 = computed(() => 2);
83
- expect(isSignal(s2)).toBeTruthy();
84
- expect(isStateSignal(s2)).toBeFalsy();
85
- expect(isComputedSignal(s2)).toBeTruthy();
86
- expect(isSignal("wibble")).toBeFalsy();
78
+ const s1 = Signal(1);
79
+ expect(Signal.is(s1)).toBeTruthy();
80
+ expect(Signal.State.is(s1)).toBeTruthy();
81
+ expect(Signal.Computed.is(s1)).toBeFalsy();
82
+ const s2 = Signal.computed(() => 2);
83
+ expect(Signal.is(s2)).toBeTruthy();
84
+ expect(Signal.State.is(s2)).toBeFalsy();
85
+ expect(Signal.Computed.is(s2)).toBeTruthy();
86
+ expect(Signal.is("wibble")).toBeFalsy();
87
87
  });
88
88
  //# 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,7 +1,7 @@
1
1
  {
2
2
  "name": "@bodil/signal",
3
- "version": "0.2.2",
4
- "description": "Preact Signals like signal implementation built on the TC39 Signals Proposal",
3
+ "version": "0.3.0",
4
+ "description": "Signal implementation built on the TC39 Signals Proposal",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/bodil/signal.git"
package/src/index.ts CHANGED
@@ -2,13 +2,13 @@ import { Signal } from "signal-polyfill";
2
2
  import { toDisposable, type Disposifiable } from "@bodil/disposable";
3
3
  import { Err, Ok, type Result, Async } from "@bodil/core";
4
4
 
5
- interface ReadableSignal<A> {
5
+ interface ISignal<A> {
6
6
  readonly value: A;
7
- map<B>(fn: (value: A) => B): ComputedSignal<B>;
7
+ map<B>(fn: (value: A) => B): Computed<B>;
8
8
  on(callback: (value: A) => void): Disposable;
9
9
  }
10
10
 
11
- export class StateSignal<A> extends Signal.State<A> implements ReadableSignal<A> {
11
+ class State<A> extends Signal.State<A> implements ISignal<A> {
12
12
  get value(): A {
13
13
  return this.get();
14
14
  }
@@ -21,60 +21,39 @@ export class StateSignal<A> extends Signal.State<A> implements ReadableSignal<A>
21
21
  this.set(Signal.subtle.untrack(() => fn(this.get())));
22
22
  }
23
23
 
24
- readOnly(): ComputedSignal<A> {
25
- return computed(() => this.get());
24
+ readOnly(): Computed<A> {
25
+ return AnySignal.computed(() => this.get());
26
26
  }
27
27
 
28
- map<B>(fn: (value: A) => B): ComputedSignal<B> {
29
- return computed(() => fn(this.get()));
28
+ map<B>(fn: (value: A) => B): Computed<B> {
29
+ return AnySignal.computed(() => fn(this.get()));
30
30
  }
31
31
 
32
32
  on(callback: (value: A) => void): Disposable {
33
- return subscribe(this, callback);
33
+ return AnySignal.subscribe(this, callback);
34
+ }
35
+
36
+ static is(v: unknown): v is State<unknown> {
37
+ return v instanceof State;
34
38
  }
35
39
  }
36
40
 
37
- export class ComputedSignal<A> extends Signal.Computed<A> implements ReadableSignal<A> {
41
+ class Computed<A> extends Signal.Computed<A> implements ISignal<A> {
38
42
  get value(): A {
39
43
  return this.get();
40
44
  }
41
45
 
42
- map<B>(fn: (value: A) => B): ComputedSignal<B> {
43
- return computed(() => fn(this.get()));
46
+ map<B>(fn: (value: A) => B): Computed<B> {
47
+ return AnySignal.computed(() => fn(this.get()));
44
48
  }
45
49
 
46
50
  on(callback: (value: A) => void): Disposable {
47
- return subscribe(this, callback);
51
+ return AnySignal.subscribe(this, callback);
48
52
  }
49
- }
50
-
51
- type AnySignal<A> = StateSignal<A> | ComputedSignal<A>;
52
53
 
53
- export type { AnySignal as Signal };
54
-
55
- export const subtle = Signal.subtle;
56
-
57
- export function isStateSignal(v: unknown): v is StateSignal<unknown> {
58
- return v instanceof StateSignal;
59
- }
60
-
61
- export function isComputedSignal(v: unknown): v is ComputedSignal<unknown> {
62
- return v instanceof ComputedSignal;
63
- }
64
-
65
- export function isSignal(v: unknown): v is AnySignal<unknown> {
66
- return isStateSignal(v) || isComputedSignal(v);
67
- }
68
-
69
- export function signal<A>(value: A, options?: Signal.Options<A>): StateSignal<A> {
70
- return new StateSignal(value, options);
71
- }
72
-
73
- export function computed<A>(
74
- fn: (this: ComputedSignal<A>) => A,
75
- options?: Signal.Options<A>
76
- ): ComputedSignal<A> {
77
- return new ComputedSignal(fn, options);
54
+ static is(v: unknown): v is Computed<unknown> {
55
+ return v instanceof Computed;
56
+ }
78
57
  }
79
58
 
80
59
  let effectNeedsEnqueue = true;
@@ -93,62 +72,85 @@ function effectProcess(): void {
93
72
  effectWatcher.watch();
94
73
  }
95
74
 
96
- export function effect(fn: () => Disposifiable | void): Disposable {
97
- let cleanup: Disposable | undefined;
98
- const computed = new ComputedSignal(() => {
99
- if (cleanup !== undefined) {
100
- cleanup[Symbol.dispose]();
101
- }
102
- const result = fn();
103
- cleanup = result !== undefined ? toDisposable(result) : undefined;
104
- });
105
- effectWatcher.watch(computed);
106
- computed.get();
107
- return toDisposable(() => {
108
- effectWatcher.unwatch(computed);
109
- if (cleanup !== undefined) {
110
- cleanup[Symbol.dispose]();
111
- }
112
- });
113
- }
114
-
115
- export function subscribe<A>(signal: ReadableSignal<A>, callback: (value: A) => void): Disposable {
116
- return effect(() => callback(signal.value));
117
- }
118
-
119
- export function asyncComputed<A>(
120
- fn: (abort: AbortSignal) => Promise<A>,
121
- options?: Signal.Options<A>
122
- ): Promise<ComputedSignal<A>> {
123
- const result = Promise.withResolvers<ComputedSignal<A>>();
124
- const stream = computed(() => Async.abortable(fn));
125
- const sig: StateSignal<Result<A, Error>> = signal(Err(new Error()));
126
- let job: Async.AbortableJob<A> | undefined = undefined;
127
- let resolved = false;
128
- const resolve = () => {
129
- if (!resolved) {
130
- resolved = true;
131
- result.resolve(computed(() => sig.get().unwrapExact(), options));
132
- }
133
- };
134
- effect(() => {
135
- if (job !== undefined) {
136
- job.abort();
137
- }
138
- job = stream.get();
139
- job.result.then(
140
- (next) => {
141
- sig.set(Ok(next));
142
- resolve();
143
- },
144
- (error) => {
145
- if (job?.signal.aborted === true) {
146
- return;
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);
80
+ },
81
+ {
82
+ is(v: unknown): v is AnySignal<unknown> {
83
+ return State.is(v) || Computed.is(v);
84
+ },
85
+
86
+ computed<A>(fn: (this: Computed<A>) => A, options?: Signal.Options<A>): Computed<A> {
87
+ return new Computed(fn, options);
88
+ },
89
+
90
+ subscribe<A>(signal: ISignal<A>, callback: (value: A) => void): Disposable {
91
+ return AnySignal.effect(() => callback(signal.value));
92
+ },
93
+
94
+ effect(fn: () => Disposifiable | void): Disposable {
95
+ let cleanup: Disposable | undefined;
96
+ const computed = new Computed(() => {
97
+ if (cleanup !== undefined) {
98
+ cleanup[Symbol.dispose]();
147
99
  }
148
- sig.set(Err(error));
149
- resolve();
150
- }
151
- );
152
- });
153
- return result.promise;
154
- }
100
+ const result = fn();
101
+ cleanup = result !== undefined ? toDisposable(result) : undefined;
102
+ });
103
+ effectWatcher.watch(computed);
104
+ computed.get();
105
+ return toDisposable(() => {
106
+ effectWatcher.unwatch(computed);
107
+ if (cleanup !== undefined) {
108
+ cleanup[Symbol.dispose]();
109
+ }
110
+ });
111
+ },
112
+
113
+ asyncComputed<A>(
114
+ fn: (abort: AbortSignal) => Promise<A>,
115
+ 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()));
120
+ let job: Async.AbortableJob<A> | undefined = undefined;
121
+ let resolved = false;
122
+ const resolve = () => {
123
+ if (!resolved) {
124
+ resolved = true;
125
+ result.resolve(AnySignal.computed(() => sig.get().unwrapExact(), options));
126
+ }
127
+ };
128
+ AnySignal.effect(() => {
129
+ if (job !== undefined) {
130
+ job.abort();
131
+ }
132
+ job = stream.get();
133
+ job.result.then(
134
+ (next) => {
135
+ sig.set(Ok(next));
136
+ resolve();
137
+ },
138
+ (error) => {
139
+ if (job?.signal.aborted === true) {
140
+ return;
141
+ }
142
+ sig.set(Err(error));
143
+ resolve();
144
+ }
145
+ );
146
+ });
147
+ return result.promise;
148
+ },
149
+
150
+ State,
151
+ Computed,
152
+ subtle: Signal.subtle,
153
+ }
154
+ );
155
+
156
+ export { AnySignal as Signal };
@@ -1,19 +1,11 @@
1
1
  import { sleep } from "@bodil/core/async";
2
2
  import { expect, test } from "vitest";
3
- import {
4
- asyncComputed,
5
- computed,
6
- effect,
7
- isComputedSignal,
8
- isSignal,
9
- isStateSignal,
10
- signal,
11
- } from ".";
3
+ import { Signal } from ".";
12
4
 
13
5
  test("Signal", async () => {
14
- const sig = signal(0);
6
+ const sig = Signal(0);
15
7
  const result: Array<number> = [];
16
- effect(() => void result.push(sig.value));
8
+ Signal.effect(() => void result.push(sig.value));
17
9
  expect(result).toEqual([0]);
18
10
  sig.value = 1;
19
11
  sig.value = 2;
@@ -33,8 +25,8 @@ test("Signal", async () => {
33
25
 
34
26
  test("signal equality", async () => {
35
27
  const result: Array<number> = [];
36
- const sig = signal(0);
37
- effect(() => void result.push(sig.value));
28
+ const sig = Signal(0);
29
+ Signal.effect(() => void result.push(sig.value));
38
30
  expect(result).toEqual([0]);
39
31
  sig.value = 1;
40
32
  await sleep(1);
@@ -60,11 +52,11 @@ test("signal equality", async () => {
60
52
  });
61
53
 
62
54
  test("asyncComputed", async () => {
63
- const s = signal(1);
64
- const c = await asyncComputed(() => Promise.resolve(s.value + 1));
55
+ const s = Signal(1);
56
+ const c = await Signal.asyncComputed(() => Promise.resolve(s.value + 1));
65
57
  expect(c.value).toEqual(2);
66
58
  try {
67
- await asyncComputed(() => {
59
+ await Signal.asyncComputed(() => {
68
60
  throw new Error("welp!");
69
61
  });
70
62
  throw new Error("computed error failed to throw");
@@ -85,15 +77,15 @@ test("asyncComputed", async () => {
85
77
  });
86
78
 
87
79
  test("isSignal", () => {
88
- const s1 = signal(1);
89
- expect(isSignal(s1)).toBeTruthy();
90
- expect(isStateSignal(s1)).toBeTruthy();
91
- expect(isComputedSignal(s1)).toBeFalsy();
80
+ const s1 = Signal(1);
81
+ expect(Signal.is(s1)).toBeTruthy();
82
+ expect(Signal.State.is(s1)).toBeTruthy();
83
+ expect(Signal.Computed.is(s1)).toBeFalsy();
92
84
 
93
- const s2 = computed(() => 2);
94
- expect(isSignal(s2)).toBeTruthy();
95
- expect(isStateSignal(s2)).toBeFalsy();
96
- expect(isComputedSignal(s2)).toBeTruthy();
85
+ const s2 = Signal.computed(() => 2);
86
+ expect(Signal.is(s2)).toBeTruthy();
87
+ expect(Signal.State.is(s2)).toBeFalsy();
88
+ expect(Signal.Computed.is(s2)).toBeTruthy();
97
89
 
98
- expect(isSignal("wibble")).toBeFalsy();
90
+ expect(Signal.is("wibble")).toBeFalsy();
99
91
  });