@e280/strata 0.2.7 → 0.3.0-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/LICENSE +1 -1
- package/README.md +56 -47
- package/package.json +3 -3
- package/s/index.ts +0 -1
- package/s/prism/prism.test.ts +2 -1
- package/s/prism/prism.ts +1 -1
- package/s/signals/derived/class.ts +34 -0
- package/s/signals/derived/fn.ts +36 -0
- package/s/signals/{tests/derived.test.ts → derived/test.ts} +13 -14
- package/s/signals/effect/effect.ts +7 -0
- package/s/signals/effect/test.ts +172 -0
- package/s/signals/effect/watch.ts +32 -0
- package/s/signals/index.ts +11 -7
- package/s/signals/lazy/class.ts +74 -0
- package/s/signals/lazy/fn.ts +22 -0
- package/s/signals/{tests/lazy.test.ts → lazy/test.ts} +23 -12
- package/s/signals/signal/class.ts +77 -0
- package/s/signals/signal/fn.ts +31 -0
- package/s/signals/{tests/signal.test.ts → signal/test.ts} +56 -59
- package/s/signals/signals.test.ts +8 -8
- package/s/signals/types.ts +4 -23
- package/s/signals/utils/default-compare.ts +1 -1
- package/s/signals/utils/symbols.ts +9 -0
- package/s/tests.test.ts +1 -57
- package/s/tracker/bindings/react.ts +42 -0
- package/s/tracker/index.ts +1 -0
- package/x/index.d.ts +0 -1
- package/x/index.js +0 -1
- package/x/index.js.map +1 -1
- package/x/prism/prism.js.map +1 -1
- package/x/prism/prism.test.js +1 -1
- package/x/prism/prism.test.js.map +1 -1
- package/x/signals/derived/class.d.ts +14 -0
- package/x/signals/derived/class.js +23 -0
- package/x/signals/derived/class.js.map +1 -0
- package/x/signals/derived/fn.d.ts +3 -0
- package/x/signals/derived/fn.js +28 -0
- package/x/signals/derived/fn.js.map +1 -0
- package/x/signals/{tests/derived.test.d.ts → derived/test.d.ts} +1 -3
- package/x/signals/{tests/derived.test.js → derived/test.js} +14 -15
- package/x/signals/derived/test.js.map +1 -0
- package/x/signals/effect/effect.d.ts +1 -0
- package/x/signals/effect/effect.js +5 -0
- package/x/signals/effect/effect.js.map +1 -0
- package/x/signals/{tests/effect.test.d.ts → effect/test.d.ts} +7 -0
- package/x/signals/effect/test.js +132 -0
- package/x/signals/effect/test.js.map +1 -0
- package/x/signals/effect/watch.d.ts +4 -0
- package/x/signals/effect/watch.js +25 -0
- package/x/signals/effect/watch.js.map +1 -0
- package/x/signals/index.d.ts +8 -7
- package/x/signals/index.js +8 -7
- package/x/signals/index.js.map +1 -1
- package/x/signals/lazy/class.d.ts +19 -0
- package/x/signals/lazy/class.js +59 -0
- package/x/signals/lazy/class.js.map +1 -0
- package/x/signals/lazy/fn.d.ts +3 -0
- package/x/signals/lazy/fn.js +17 -0
- package/x/signals/lazy/fn.js.map +1 -0
- package/x/signals/{tests/lazy.test.d.ts → lazy/test.d.ts} +2 -3
- package/x/signals/{tests/lazy.test.js → lazy/test.js} +23 -13
- package/x/signals/lazy/test.js.map +1 -0
- package/x/signals/signal/class.d.ts +20 -0
- package/x/signals/signal/class.js +57 -0
- package/x/signals/signal/class.js.map +1 -0
- package/x/signals/signal/fn.d.ts +7 -0
- package/x/signals/signal/fn.js +23 -0
- package/x/signals/signal/fn.js.map +1 -0
- package/x/signals/{tests/signal.test.d.ts → signal/test.d.ts} +8 -7
- package/x/signals/{tests/signal.test.js → signal/test.js} +50 -46
- package/x/signals/signal/test.js.map +1 -0
- package/x/signals/signals.test.d.ts +25 -20
- package/x/signals/signals.test.js +8 -8
- package/x/signals/signals.test.js.map +1 -1
- package/x/signals/types.d.ts +4 -19
- package/x/signals/utils/default-compare.js +1 -1
- package/x/signals/utils/default-compare.js.map +1 -1
- package/x/signals/utils/symbols.d.ts +7 -0
- package/x/signals/utils/symbols.js +8 -0
- package/x/signals/utils/symbols.js.map +1 -0
- package/x/tests.test.js +1 -45
- package/x/tests.test.js.map +1 -1
- package/x/tracker/bindings/react.d.ts +10 -0
- package/x/tracker/bindings/react.js +29 -0
- package/x/tracker/bindings/react.js.map +1 -0
- package/x/tracker/index.d.ts +1 -0
- package/x/tracker/index.js +1 -0
- package/x/tracker/index.js.map +1 -1
- package/s/signals/core/derived.ts +0 -65
- package/s/signals/core/effect.ts +0 -31
- package/s/signals/core/lazy.ts +0 -78
- package/s/signals/core/parts/reactive.ts +0 -12
- package/s/signals/core/parts/readable.ts +0 -16
- package/s/signals/core/signal.ts +0 -101
- package/s/signals/porcelain.ts +0 -30
- package/s/signals/tests/effect.test.ts +0 -89
- package/s/tree/index.ts +0 -7
- package/s/tree/parts/branch.ts +0 -55
- package/s/tree/parts/chronobranch.ts +0 -86
- package/s/tree/parts/persistence.ts +0 -31
- package/s/tree/parts/trunk.ts +0 -70
- package/s/tree/parts/types.ts +0 -70
- package/s/tree/parts/utils/immute.ts +0 -43
- package/s/tree/parts/utils/process-options.ts +0 -7
- package/s/tree/parts/utils/setup.ts +0 -40
- package/s/tree/tree.test.ts +0 -366
- package/x/signals/core/derived.d.ts +0 -10
- package/x/signals/core/derived.js +0 -52
- package/x/signals/core/derived.js.map +0 -1
- package/x/signals/core/effect.d.ts +0 -5
- package/x/signals/core/effect.js +0 -17
- package/x/signals/core/effect.js.map +0 -1
- package/x/signals/core/lazy.d.ts +0 -11
- package/x/signals/core/lazy.js +0 -60
- package/x/signals/core/lazy.js.map +0 -1
- package/x/signals/core/parts/reactive.d.ts +0 -5
- package/x/signals/core/parts/reactive.js +0 -9
- package/x/signals/core/parts/reactive.js.map +0 -1
- package/x/signals/core/parts/readable.d.ts +0 -6
- package/x/signals/core/parts/readable.js +0 -15
- package/x/signals/core/parts/readable.js.map +0 -1
- package/x/signals/core/signal.d.ts +0 -13
- package/x/signals/core/signal.js +0 -77
- package/x/signals/core/signal.js.map +0 -1
- package/x/signals/porcelain.d.ts +0 -8
- package/x/signals/porcelain.js +0 -15
- package/x/signals/porcelain.js.map +0 -1
- package/x/signals/tests/derived.test.js.map +0 -1
- package/x/signals/tests/effect.test.js +0 -72
- package/x/signals/tests/effect.test.js.map +0 -1
- package/x/signals/tests/lazy.test.js.map +0 -1
- package/x/signals/tests/signal.test.js.map +0 -1
- package/x/tree/index.d.ts +0 -5
- package/x/tree/index.js +0 -6
- package/x/tree/index.js.map +0 -1
- package/x/tree/parts/branch.d.ts +0 -14
- package/x/tree/parts/branch.js +0 -42
- package/x/tree/parts/branch.js.map +0 -1
- package/x/tree/parts/chronobranch.d.ts +0 -25
- package/x/tree/parts/chronobranch.js +0 -75
- package/x/tree/parts/chronobranch.js.map +0 -1
- package/x/tree/parts/persistence.d.ts +0 -2
- package/x/tree/parts/persistence.js +0 -23
- package/x/tree/parts/persistence.js.map +0 -1
- package/x/tree/parts/trunk.d.ts +0 -19
- package/x/tree/parts/trunk.js +0 -57
- package/x/tree/parts/trunk.js.map +0 -1
- package/x/tree/parts/types.d.ts +0 -28
- package/x/tree/parts/types.js +0 -2
- package/x/tree/parts/types.js.map +0 -1
- package/x/tree/parts/utils/immute.d.ts +0 -11
- package/x/tree/parts/utils/immute.js +0 -33
- package/x/tree/parts/utils/immute.js.map +0 -1
- package/x/tree/parts/utils/process-options.d.ts +0 -2
- package/x/tree/parts/utils/process-options.js +0 -4
- package/x/tree/parts/utils/process-options.js.map +0 -1
- package/x/tree/parts/utils/setup.d.ts +0 -8
- package/x/tree/parts/utils/setup.js +0 -24
- package/x/tree/parts/utils/setup.js.map +0 -1
- package/x/tree/tree.test.d.ts +0 -40
- package/x/tree/tree.test.js +0 -325
- package/x/tree/tree.test.js.map +0 -1
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { signal } from "./fn.js";
|
|
2
|
+
import { tracker } from "../../tracker/tracker.js";
|
|
3
|
+
import { _compare, _lock } from "../utils/symbols.js";
|
|
4
|
+
export class Signal {
|
|
5
|
+
sneak;
|
|
6
|
+
on;
|
|
7
|
+
[_lock];
|
|
8
|
+
[_compare];
|
|
9
|
+
constructor(value, options) {
|
|
10
|
+
if (new.target !== Signal)
|
|
11
|
+
throw new Error("Signal cannot be subclassed");
|
|
12
|
+
return signal(value, options);
|
|
13
|
+
}
|
|
14
|
+
get value() {
|
|
15
|
+
return this.get();
|
|
16
|
+
}
|
|
17
|
+
set value(value) {
|
|
18
|
+
void this.set(value);
|
|
19
|
+
}
|
|
20
|
+
get() {
|
|
21
|
+
tracker.notifyRead(this);
|
|
22
|
+
return this.sneak;
|
|
23
|
+
}
|
|
24
|
+
async set(value, forcePublish = false) {
|
|
25
|
+
const previous = this.sneak;
|
|
26
|
+
this.sneak = value;
|
|
27
|
+
if (forcePublish || !this[_compare](previous, value))
|
|
28
|
+
await this.publish();
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
async publish() {
|
|
32
|
+
// only wizards are allowed beyond this point.
|
|
33
|
+
// - the implementation is subtle
|
|
34
|
+
// - it looks wrong, but it's right
|
|
35
|
+
// - tarnished alchemists, take heed: lock engages only for sync activity of the async fns (think of the value setter!)
|
|
36
|
+
if (this[_lock])
|
|
37
|
+
throw new Error("forbid circularity");
|
|
38
|
+
const value = this.sneak;
|
|
39
|
+
let promise = Promise.resolve();
|
|
40
|
+
try {
|
|
41
|
+
this[_lock] = true;
|
|
42
|
+
promise = Promise.all([
|
|
43
|
+
tracker.notifyWrite(this),
|
|
44
|
+
this.on.pub(value),
|
|
45
|
+
]);
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
this[_lock] = false;
|
|
49
|
+
}
|
|
50
|
+
await promise;
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
toString() {
|
|
54
|
+
return `($signal "${String(this.get())}")`;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=class.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"class.js","sourceRoot":"","sources":["../../../s/signals/signal/class.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,MAAM,EAAC,MAAM,SAAS,CAAA;AAE9B,OAAO,EAAC,OAAO,EAAC,MAAM,0BAA0B,CAAA;AAChD,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,qBAAqB,CAAA;AAOnD,MAAM,OAAO,MAAM;IAClB,KAAK,CAAQ;IACb,EAAE,CAED;IAAA,CAAC,KAAK,CAAC,CACP;IAAA,CAAC,QAAQ,CAAC,CAA8B;IAEzC,YAAY,KAAY,EAAE,OAAgC;QACzD,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAA;QACzE,OAAO,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IAC9B,CAAC;IAED,IAAI,KAAK;QACR,OAAQ,IAAoB,CAAC,GAAG,EAAE,CAAA;IACnC,CAAC;IAED,IAAI,KAAK,CAAC,KAAU;QACnB,KAAM,IAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IACtC,CAAC;IAED,GAAG;QACF,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;QACxB,OAAO,IAAI,CAAC,KAAK,CAAA;IAClB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAAY,EAAE,YAAY,GAAG,KAAK;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAA;QAC3B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,YAAY,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC;YACnD,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;QACrB,OAAO,KAAK,CAAA;IACb,CAAC;IAED,KAAK,CAAC,OAAO;QACZ,8CAA8C;QAC9C,iCAAiC;QACjC,mCAAmC;QACnC,uHAAuH;QAEvH,IAAI,IAAI,CAAC,KAAK,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAA;QAEtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QACxB,IAAI,OAAO,GAAiB,OAAO,CAAC,OAAO,EAAE,CAAA;QAE7C,IAAI,CAAC;YACJ,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;YAClB,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC;gBACrB,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC;gBACzB,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;aAClB,CAAC,CAAA;QACH,CAAC;gBACO,CAAC;YACR,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,CAAA;QACpB,CAAC;QAED,MAAM,OAAO,CAAA;QACb,OAAO,KAAK,CAAA;IACb,CAAC;IAED,QAAQ;QACP,OAAO,aAAa,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAA;IAC3C,CAAC;CACD"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Signal } from "./class.js";
|
|
2
|
+
import { SignalOptions } from "../types.js";
|
|
3
|
+
export declare function signal<Value>(value: Value, options?: Partial<SignalOptions>): Signal<Value>;
|
|
4
|
+
export declare namespace signal {
|
|
5
|
+
var derived: typeof import("../derived/fn.js").derived;
|
|
6
|
+
var lazy: typeof import("../lazy/fn.js").lazy;
|
|
7
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { sub } from "@e280/stz";
|
|
2
|
+
import { Signal } from "./class.js";
|
|
3
|
+
import { lazy } from "../lazy/fn.js";
|
|
4
|
+
import { derived } from "../derived/fn.js";
|
|
5
|
+
import { _compare, _lock } from "../utils/symbols.js";
|
|
6
|
+
import { defaultCompare } from "../utils/default-compare.js";
|
|
7
|
+
export function signal(value, options) {
|
|
8
|
+
function fn(_value) {
|
|
9
|
+
const self = fn;
|
|
10
|
+
return (arguments.length === 0)
|
|
11
|
+
? self.get()
|
|
12
|
+
: self.set(arguments[0]);
|
|
13
|
+
}
|
|
14
|
+
Object.setPrototypeOf(fn, Signal.prototype);
|
|
15
|
+
fn.sneak = value;
|
|
16
|
+
fn.on = sub();
|
|
17
|
+
fn[_lock] = false;
|
|
18
|
+
fn[_compare] = options?.compare ?? defaultCompare;
|
|
19
|
+
return fn;
|
|
20
|
+
}
|
|
21
|
+
signal.derived = derived;
|
|
22
|
+
signal.lazy = lazy;
|
|
23
|
+
//# sourceMappingURL=fn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fn.js","sourceRoot":"","sources":["../../../s/signals/signal/fn.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,GAAG,EAAC,MAAM,WAAW,CAAA;AAC7B,OAAO,EAAC,MAAM,EAAC,MAAM,YAAY,CAAA;AACjC,OAAO,EAAC,IAAI,EAAC,MAAM,eAAe,CAAA;AAElC,OAAO,EAAC,OAAO,EAAC,MAAM,kBAAkB,CAAA;AACxC,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAC,cAAc,EAAC,MAAM,6BAA6B,CAAA;AAE1D,MAAM,UAAU,MAAM,CAAQ,KAAY,EAAE,OAAgC;IAG3E,SAAS,EAAE,CAAC,MAAc;QACzB,MAAM,IAAI,GAAG,EAAmB,CAAA;QAChC,OAAO,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC;YAC9B,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;YACZ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAA;IAC1B,CAAC;IAED,MAAM,CAAC,cAAc,CAAC,EAAE,EAAE,MAAM,CAAC,SAAS,CAAC,CAAA;IAC3C,EAAE,CAAC,KAAK,GAAG,KAAK,CAAA;IAChB,EAAE,CAAC,EAAE,GAAG,GAAG,EAAW,CAAA;IACtB,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,CAAA;IACjB,EAAE,CAAC,QAAQ,CAAC,GAAG,OAAO,EAAE,OAAO,IAAI,cAAc,CAAA;IAEjD,OAAO,EAAmB,CAAA;AAC3B,CAAC;AAED,MAAM,CAAC,OAAO,GAAG,OAAO,CAAA;AACxB,MAAM,CAAC,IAAI,GAAG,IAAI,CAAA"}
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { Science } from "@e280/science";
|
|
2
2
|
declare const _default: {
|
|
3
|
-
"get
|
|
3
|
+
"get() and set()": Science.Test;
|
|
4
|
+
".value": Science.Test;
|
|
5
|
+
"count() and count(1)": Science.Test;
|
|
4
6
|
"set with forcePublish returns value": Science.Test;
|
|
5
7
|
"syntax interop": Science.Test;
|
|
8
|
+
"class magic": {
|
|
9
|
+
"signal instanceof Signal": Science.Test;
|
|
10
|
+
"new Signal": Science.Test;
|
|
11
|
+
"subclassing Signal is forbidden": Science.Test;
|
|
12
|
+
};
|
|
6
13
|
on: {
|
|
7
14
|
"on is not debounced": Science.Test;
|
|
8
15
|
"on only fires on change": Science.Test;
|
|
9
16
|
"on circularity forbidden": Science.Test;
|
|
10
17
|
};
|
|
11
|
-
"hipster syntax": {
|
|
12
|
-
"get and set": Science.Test;
|
|
13
|
-
"old get and set still work": Science.Test;
|
|
14
|
-
interop: Science.Test;
|
|
15
|
-
".on 'this' interrogation": Science.Test;
|
|
16
|
-
};
|
|
17
18
|
};
|
|
18
19
|
export default _default;
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { Science, test, expect } from "@e280/science";
|
|
2
|
-
import { signal } from "
|
|
2
|
+
import { signal } from "./fn.js";
|
|
3
|
+
import { Signal } from "./class.js";
|
|
3
4
|
export default Science.suite({
|
|
4
|
-
"get
|
|
5
|
+
"get() and set()": test(async () => {
|
|
6
|
+
const count = signal(0);
|
|
7
|
+
expect(count.get()).is(0);
|
|
8
|
+
await count.set(1);
|
|
9
|
+
expect(count.get()).is(1);
|
|
10
|
+
count.set(2);
|
|
11
|
+
expect(count.get()).is(2);
|
|
12
|
+
}),
|
|
13
|
+
".value": test(async () => {
|
|
5
14
|
const count = signal(0);
|
|
6
15
|
expect(count.value).is(0);
|
|
7
16
|
count.value++;
|
|
@@ -9,6 +18,14 @@ export default Science.suite({
|
|
|
9
18
|
count.value = 5;
|
|
10
19
|
expect(count.value).is(5);
|
|
11
20
|
}),
|
|
21
|
+
"count() and count(1)": test(async () => {
|
|
22
|
+
const count = signal(0);
|
|
23
|
+
expect(count()).is(0);
|
|
24
|
+
await count(1);
|
|
25
|
+
expect(count()).is(1);
|
|
26
|
+
count(2);
|
|
27
|
+
expect(count()).is(2);
|
|
28
|
+
}),
|
|
12
29
|
"set with forcePublish returns value": test(async () => {
|
|
13
30
|
const count = signal(0);
|
|
14
31
|
expect(count.value).is(0);
|
|
@@ -17,10 +34,37 @@ export default Science.suite({
|
|
|
17
34
|
}),
|
|
18
35
|
"syntax interop": test(async () => {
|
|
19
36
|
const count = signal(0);
|
|
20
|
-
count
|
|
37
|
+
count(1);
|
|
38
|
+
expect(count()).is(1);
|
|
21
39
|
expect(count.get()).is(1);
|
|
40
|
+
expect(count.value).is(1);
|
|
41
|
+
count.set(2);
|
|
42
|
+
expect(count()).is(2);
|
|
43
|
+
expect(count.get()).is(2);
|
|
44
|
+
expect(count.value).is(2);
|
|
45
|
+
count.value = 3;
|
|
46
|
+
expect(count()).is(3);
|
|
47
|
+
expect(count.get()).is(3);
|
|
48
|
+
expect(count.value).is(3);
|
|
22
49
|
}),
|
|
23
|
-
"
|
|
50
|
+
"class magic": {
|
|
51
|
+
"signal instanceof Signal": test(async () => {
|
|
52
|
+
const count = signal(0);
|
|
53
|
+
expect(count instanceof Signal).ok();
|
|
54
|
+
}),
|
|
55
|
+
"new Signal": test(async () => {
|
|
56
|
+
const count = new Signal(0);
|
|
57
|
+
expect(count instanceof Signal).ok();
|
|
58
|
+
expect(count()).is(0);
|
|
59
|
+
await count(1);
|
|
60
|
+
expect(count.value).is(1);
|
|
61
|
+
}),
|
|
62
|
+
"subclassing Signal is forbidden": test(async () => {
|
|
63
|
+
expect(() => new class extends Signal {
|
|
64
|
+
}(0)).throws();
|
|
65
|
+
}),
|
|
66
|
+
},
|
|
67
|
+
"on": {
|
|
24
68
|
"on is not debounced": test(async () => {
|
|
25
69
|
const count = signal(1);
|
|
26
70
|
let runs = 0;
|
|
@@ -49,46 +93,6 @@ export default Science.suite({
|
|
|
49
93
|
}).throwsAsync();
|
|
50
94
|
expect(runs).is(0);
|
|
51
95
|
}),
|
|
52
|
-
}
|
|
53
|
-
"hipster syntax": Science.suite({
|
|
54
|
-
"get and set": test(async () => {
|
|
55
|
-
const count = signal(0);
|
|
56
|
-
expect(count()).is(0);
|
|
57
|
-
count(count() + 1);
|
|
58
|
-
expect(count()).is(1);
|
|
59
|
-
}),
|
|
60
|
-
"old get and set still work": test(async () => {
|
|
61
|
-
const count = signal(0);
|
|
62
|
-
expect(count.get()).is(0);
|
|
63
|
-
count.set(count.get() + 1);
|
|
64
|
-
expect(count.get()).is(1);
|
|
65
|
-
}),
|
|
66
|
-
"interop": test(async () => {
|
|
67
|
-
const count = signal(0);
|
|
68
|
-
count(1);
|
|
69
|
-
expect(count()).is(1);
|
|
70
|
-
expect(count.get()).is(1);
|
|
71
|
-
expect(count.value).is(1);
|
|
72
|
-
count.set(2);
|
|
73
|
-
expect(count()).is(2);
|
|
74
|
-
expect(count.get()).is(2);
|
|
75
|
-
expect(count.value).is(2);
|
|
76
|
-
count.value = 3;
|
|
77
|
-
expect(count()).is(3);
|
|
78
|
-
expect(count.get()).is(3);
|
|
79
|
-
expect(count.value).is(3);
|
|
80
|
-
}),
|
|
81
|
-
".on 'this' interrogation": test(async () => {
|
|
82
|
-
const count = signal(0);
|
|
83
|
-
expect(count()).is(0);
|
|
84
|
-
let reported = count();
|
|
85
|
-
count.on(x => { reported = x; });
|
|
86
|
-
count(1);
|
|
87
|
-
expect(reported).is(1);
|
|
88
|
-
count.on.clear();
|
|
89
|
-
count(2);
|
|
90
|
-
expect(reported).is(1);
|
|
91
|
-
}),
|
|
92
|
-
}),
|
|
96
|
+
},
|
|
93
97
|
});
|
|
94
|
-
//# sourceMappingURL=
|
|
98
|
+
//# sourceMappingURL=test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../../s/signals/signal/test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,28 +1,21 @@
|
|
|
1
1
|
import { Science } from "@e280/science";
|
|
2
2
|
declare const _default: {
|
|
3
|
-
effect: {
|
|
4
|
-
"tracks signal changes": Science.Test;
|
|
5
|
-
"is only called when signal actually changes": Science.Test;
|
|
6
|
-
debounced: Science.Test;
|
|
7
|
-
"can be disposed": Science.Test;
|
|
8
|
-
"signal set promise waits for effects": Science.Test;
|
|
9
|
-
"only runs on change": Science.Test;
|
|
10
|
-
};
|
|
11
3
|
signal: {
|
|
12
|
-
"get
|
|
4
|
+
"get() and set()": Science.Test;
|
|
5
|
+
".value": Science.Test;
|
|
6
|
+
"count() and count(1)": Science.Test;
|
|
13
7
|
"set with forcePublish returns value": Science.Test;
|
|
14
8
|
"syntax interop": Science.Test;
|
|
9
|
+
"class magic": {
|
|
10
|
+
"signal instanceof Signal": Science.Test;
|
|
11
|
+
"new Signal": Science.Test;
|
|
12
|
+
"subclassing Signal is forbidden": Science.Test;
|
|
13
|
+
};
|
|
15
14
|
on: {
|
|
16
15
|
"on is not debounced": Science.Test;
|
|
17
16
|
"on only fires on change": Science.Test;
|
|
18
17
|
"on circularity forbidden": Science.Test;
|
|
19
18
|
};
|
|
20
|
-
"hipster syntax": {
|
|
21
|
-
"get and set": Science.Test;
|
|
22
|
-
"old get and set still work": Science.Test;
|
|
23
|
-
interop: Science.Test;
|
|
24
|
-
".on 'this' interrogation": Science.Test;
|
|
25
|
-
};
|
|
26
19
|
};
|
|
27
20
|
derived: {
|
|
28
21
|
basic: Science.Test;
|
|
@@ -30,17 +23,29 @@ declare const _default: {
|
|
|
30
23
|
"effect doesn't overreact to derived": Science.Test;
|
|
31
24
|
"derived.on": Science.Test;
|
|
32
25
|
"derived.on not called if result doesn't change": Science.Test;
|
|
33
|
-
"hipster
|
|
34
|
-
basic: Science.Test;
|
|
35
|
-
};
|
|
26
|
+
"hipster syntax": Science.Test;
|
|
36
27
|
};
|
|
37
28
|
lazy: {
|
|
38
29
|
"lazy values": Science.Test;
|
|
39
30
|
"lazy is lazy": Science.Test;
|
|
31
|
+
"lazy handles changing deps": Science.Test;
|
|
40
32
|
"lazy syntax": Science.Test;
|
|
41
|
-
"hipster
|
|
42
|
-
|
|
33
|
+
"lazy hipster syntax": Science.Test;
|
|
34
|
+
};
|
|
35
|
+
effect: {
|
|
36
|
+
watch: {
|
|
37
|
+
"responder gets value": Science.Test;
|
|
38
|
+
"responder not called until change": Science.Test;
|
|
39
|
+
"watch updates dynamic dependencies": Science.Test;
|
|
43
40
|
};
|
|
41
|
+
"tracks signal changes": Science.Test;
|
|
42
|
+
"correct signal effect order": Science.Test;
|
|
43
|
+
"simple effect called the correct number of times": Science.Test;
|
|
44
|
+
"is only called when signal actually changes": Science.Test;
|
|
45
|
+
debounced: Science.Test;
|
|
46
|
+
"can be disposed": Science.Test;
|
|
47
|
+
"signal set promise waits for effects": Science.Test;
|
|
48
|
+
"only runs on change": Science.Test;
|
|
44
49
|
};
|
|
45
50
|
};
|
|
46
51
|
export default _default;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Science } from "@e280/science";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
2
|
+
import signal from "./signal/test.js";
|
|
3
|
+
import derived from "./derived/test.js";
|
|
4
|
+
import lazy from "./lazy/test.js";
|
|
5
|
+
import effect from "./effect/test.js";
|
|
6
6
|
export default Science.suite({
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
signal,
|
|
8
|
+
derived,
|
|
9
|
+
lazy,
|
|
10
|
+
effect,
|
|
11
11
|
});
|
|
12
12
|
//# sourceMappingURL=signals.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signals.test.js","sourceRoot":"","sources":["../../s/signals/signals.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,EAAC,MAAM,eAAe,CAAA;AAErC,OAAO,
|
|
1
|
+
{"version":3,"file":"signals.test.js","sourceRoot":"","sources":["../../s/signals/signals.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,EAAC,MAAM,eAAe,CAAA;AAErC,OAAO,MAAM,MAAM,kBAAkB,CAAA;AACrC,OAAO,OAAO,MAAM,mBAAmB,CAAA;AACvC,OAAO,IAAI,MAAM,gBAAgB,CAAA;AACjC,OAAO,MAAM,MAAM,kBAAkB,CAAA;AAErC,eAAe,OAAO,CAAC,KAAK,CAAC;IAC5B,MAAM;IACN,OAAO;IACP,IAAI;IACJ,MAAM;CACN,CAAC,CAAA"}
|
package/x/signals/types.d.ts
CHANGED
|
@@ -1,22 +1,7 @@
|
|
|
1
|
-
import { Lazy } from "./
|
|
2
|
-
import { Signal } from "./
|
|
3
|
-
import { Derived } from "./
|
|
4
|
-
export type Signaly<
|
|
5
|
-
export type SignalyFn<V> = SignalFn<V> | DerivedFn<V> | LazyFn<V>;
|
|
1
|
+
import { Lazy } from "./lazy/class.js";
|
|
2
|
+
import { Signal } from "./signal/class.js";
|
|
3
|
+
import { Derived } from "./derived/class.js";
|
|
4
|
+
export type Signaly<Value> = Signal<Value> | Derived<Value> | Lazy<Value>;
|
|
6
5
|
export type SignalOptions = {
|
|
7
6
|
compare: (a: any, b: any) => boolean;
|
|
8
7
|
};
|
|
9
|
-
export type SignalFn<V> = {
|
|
10
|
-
(): V;
|
|
11
|
-
(v: V): Promise<V>;
|
|
12
|
-
(v?: V): V | Promise<V>;
|
|
13
|
-
core: Signal<V>;
|
|
14
|
-
} & Signal<V>;
|
|
15
|
-
export type LazyFn<V> = {
|
|
16
|
-
(): V;
|
|
17
|
-
core: Lazy<V>;
|
|
18
|
-
} & Lazy<V>;
|
|
19
|
-
export type DerivedFn<V> = {
|
|
20
|
-
(): V;
|
|
21
|
-
core: Derived<V>;
|
|
22
|
-
} & Derived<V>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-compare.js","sourceRoot":"","sources":["../../../s/signals/utils/default-compare.ts"],"names":[],"mappings":"AACA,MAAM,UAAU,cAAc,CAAC,CAAM,EAAE,CAAM;IAC5C,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"default-compare.js","sourceRoot":"","sources":["../../../s/signals/utils/default-compare.ts"],"names":[],"mappings":"AACA,MAAM,UAAU,cAAc,CAAC,CAAM,EAAE,CAAM;IAC5C,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACvB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const _lock: unique symbol;
|
|
2
|
+
export declare const _dirty: unique symbol;
|
|
3
|
+
export declare const _effect: unique symbol;
|
|
4
|
+
export declare const _collect: unique symbol;
|
|
5
|
+
export declare const _compare: unique symbol;
|
|
6
|
+
export declare const _formula: unique symbol;
|
|
7
|
+
export declare const _disposers: unique symbol;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const _lock = Symbol();
|
|
2
|
+
export const _dirty = Symbol();
|
|
3
|
+
export const _effect = Symbol();
|
|
4
|
+
export const _collect = Symbol();
|
|
5
|
+
export const _compare = Symbol();
|
|
6
|
+
export const _formula = Symbol();
|
|
7
|
+
export const _disposers = Symbol();
|
|
8
|
+
//# sourceMappingURL=symbols.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"symbols.js","sourceRoot":"","sources":["../../../s/signals/utils/symbols.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,KAAK,GAAG,MAAM,EAAE,CAAA;AAC7B,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAA;AAC9B,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAA;AAC/B,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAA;AAChC,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAA;AAChC,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAA;AAChC,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,EAAE,CAAA"}
|
package/x/tests.test.js
CHANGED
|
@@ -1,54 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import tree from "./tree/tree.test.js";
|
|
1
|
+
import { Science } from "@e280/science";
|
|
3
2
|
import prism from "./prism/prism.test.js";
|
|
4
3
|
import signals from "./signals/signals.test.js";
|
|
5
4
|
import tracker from "./tracker/tracker.test.js";
|
|
6
|
-
import { signal } from "./signals/porcelain.js";
|
|
7
|
-
import { effect } from "./signals/core/effect.js";
|
|
8
|
-
import { Trunk } from "./tree/parts/trunk.js";
|
|
9
5
|
await Science.run({
|
|
10
|
-
tree,
|
|
11
6
|
prism,
|
|
12
7
|
signals,
|
|
13
8
|
tracker,
|
|
14
|
-
interop: Science.suite.skip({
|
|
15
|
-
"effect responds to trunk change": test(async () => {
|
|
16
|
-
const trunk = new Trunk({ count: 1 });
|
|
17
|
-
let copy = 0;
|
|
18
|
-
expect(copy).is(0);
|
|
19
|
-
effect(() => copy = trunk.state.count);
|
|
20
|
-
expect(copy).is(1);
|
|
21
|
-
await trunk.mutate(s => s.count++);
|
|
22
|
-
expect(copy).is(2);
|
|
23
|
-
}),
|
|
24
|
-
"signal.set participates in flush": test(async () => {
|
|
25
|
-
let order = [];
|
|
26
|
-
const count = signal(0);
|
|
27
|
-
effect(() => {
|
|
28
|
-
if (count.value)
|
|
29
|
-
order.push("effect");
|
|
30
|
-
});
|
|
31
|
-
order.push("before");
|
|
32
|
-
await count.set(1);
|
|
33
|
-
order.push("after");
|
|
34
|
-
expect(order.length).is(3);
|
|
35
|
-
expect(order[0]).is("before");
|
|
36
|
-
expect(order[1]).is("effect");
|
|
37
|
-
expect(order[2]).is("after");
|
|
38
|
-
}),
|
|
39
|
-
"branch can include signal value": test(async () => {
|
|
40
|
-
const bingus = signal(101);
|
|
41
|
-
const trunk = new Trunk({ count: 1 });
|
|
42
|
-
const branch = trunk.branch(s => ({
|
|
43
|
-
count: s.count,
|
|
44
|
-
bingus: bingus.value,
|
|
45
|
-
}));
|
|
46
|
-
expect(branch.state.count).is(1);
|
|
47
|
-
expect(branch.state.bingus).is(101);
|
|
48
|
-
await bingus.set(102);
|
|
49
|
-
expect(branch.state.count).is(1);
|
|
50
|
-
expect(branch.state.bingus).is(102);
|
|
51
|
-
}),
|
|
52
|
-
}),
|
|
53
9
|
});
|
|
54
10
|
//# sourceMappingURL=tests.test.js.map
|
package/x/tests.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tests.test.js","sourceRoot":"","sources":["../s/tests.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"tests.test.js","sourceRoot":"","sources":["../s/tests.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,EAAC,MAAM,eAAe,CAAA;AAErC,OAAO,KAAK,MAAM,uBAAuB,CAAA;AACzC,OAAO,OAAO,MAAM,2BAA2B,CAAA;AAC/C,OAAO,OAAO,MAAM,2BAA2B,CAAA;AAE/C,MAAM,OAAO,CAAC,GAAG,CAAC;IACjB,KAAK;IACL,OAAO;IACP,OAAO;CACP,CAAC,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function react(react: {
|
|
2
|
+
useState: <X>(x: X) => [value: X, set: (fn: (x: X) => void) => void];
|
|
3
|
+
useEffect: (fn: () => void) => void;
|
|
4
|
+
}): {
|
|
5
|
+
component: <P extends object, R>(render: (props: P) => R) => {
|
|
6
|
+
(props: P): R;
|
|
7
|
+
displayName: any;
|
|
8
|
+
};
|
|
9
|
+
useStrata: <X>(fn: () => X) => X;
|
|
10
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { tracker } from "../tracker.js";
|
|
2
|
+
export function react(react) {
|
|
3
|
+
const useStrata = (fn) => {
|
|
4
|
+
const [, setTick] = react.useState(0);
|
|
5
|
+
const { seen, result } = tracker.observe(fn);
|
|
6
|
+
react.useEffect(() => {
|
|
7
|
+
const rerender = async () => setTick(tick => tick + 1);
|
|
8
|
+
const stoppers = [...seen].map(item => tracker.subscribe(item, rerender));
|
|
9
|
+
return () => stoppers.forEach(stop => stop());
|
|
10
|
+
});
|
|
11
|
+
return result;
|
|
12
|
+
};
|
|
13
|
+
const component = (render) => {
|
|
14
|
+
function c(props) {
|
|
15
|
+
const [, setTick] = react.useState(0);
|
|
16
|
+
const { seen, result } = tracker.observe(() => render(props));
|
|
17
|
+
react.useEffect(() => {
|
|
18
|
+
const rerender = async () => setTick(tick => tick + 1);
|
|
19
|
+
const stoppers = [...seen].map(item => tracker.subscribe(item, rerender));
|
|
20
|
+
return () => stoppers.forEach(stop => stop());
|
|
21
|
+
});
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
c.displayName = render.displayName ?? render.name ?? "Component";
|
|
25
|
+
return c;
|
|
26
|
+
};
|
|
27
|
+
return { component, useStrata };
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=react.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.js","sourceRoot":"","sources":["../../../s/tracker/bindings/react.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,EAAC,MAAM,eAAe,CAAA;AAErC,MAAM,UAAU,KAAK,CAAC,KAGpB;IAED,MAAM,SAAS,GAAG,CAAI,EAAW,EAAE,EAAE;QACpC,MAAM,CAAC,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;QACrC,MAAM,EAAC,IAAI,EAAE,MAAM,EAAC,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAE1C,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;YACpB,MAAM,QAAQ,GAAG,KAAK,IAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAA;YACrD,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAA;YACzE,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAA;QAC9C,CAAC,CAAC,CAAA;QAEF,OAAO,MAAM,CAAA;IACd,CAAC,CAAA;IAED,MAAM,SAAS,GAAG,CAAsB,MAAuB,EAAE,EAAE;QAClE,SAAS,CAAC,CAAC,KAAQ;YAClB,MAAM,CAAC,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;YACrC,MAAM,EAAC,IAAI,EAAE,MAAM,EAAC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;YAE3D,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;gBACpB,MAAM,QAAQ,GAAG,KAAK,IAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAA;gBACrD,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAA;gBACzE,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAA;YAC9C,CAAC,CAAC,CAAA;YAEF,OAAO,MAAM,CAAA;QACd,CAAC;QAED,CAAC,CAAC,WAAW,GAAI,MAAc,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,IAAI,WAAW,CAAA;QACzE,OAAO,CAAC,CAAA;IACT,CAAC,CAAA;IAED,OAAO,EAAC,SAAS,EAAE,SAAS,EAAC,CAAA;AAC9B,CAAC"}
|
package/x/tracker/index.d.ts
CHANGED
package/x/tracker/index.js
CHANGED
package/x/tracker/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../s/tracker/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../s/tracker/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAA"}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import {collectorEffect} from "./effect.js"
|
|
3
|
-
import {Reactive} from "./parts/reactive.js"
|
|
4
|
-
import {tracker} from "../../tracker/tracker.js"
|
|
5
|
-
import {DerivedFn, SignalOptions} from "../types.js"
|
|
6
|
-
import {defaultCompare} from "../utils/default-compare.js"
|
|
7
|
-
|
|
8
|
-
export class Derived<V> extends Reactive<V> {
|
|
9
|
-
#dispose: () => void
|
|
10
|
-
|
|
11
|
-
constructor(formula: () => V, options?: Partial<SignalOptions>) {
|
|
12
|
-
const compare = options?.compare ?? defaultCompare
|
|
13
|
-
const {result, dispose} = collectorEffect(formula, async() => {
|
|
14
|
-
const value = formula()
|
|
15
|
-
const isChanged = !compare(this.sneak, value)
|
|
16
|
-
if (isChanged) {
|
|
17
|
-
this.sneak = value
|
|
18
|
-
await Promise.all([
|
|
19
|
-
tracker.notifyWrite(this),
|
|
20
|
-
this.on.pub(value),
|
|
21
|
-
])
|
|
22
|
-
}
|
|
23
|
-
})
|
|
24
|
-
super(result)
|
|
25
|
-
this.#dispose = dispose
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
toString() {
|
|
29
|
-
return `(derived "${String(this.get())}")`
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
dispose() {
|
|
33
|
-
super.dispose()
|
|
34
|
-
this.#dispose()
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
get core() {
|
|
38
|
-
return this
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
fn() {
|
|
42
|
-
const that = this as Derived<V>
|
|
43
|
-
|
|
44
|
-
function f(): V {
|
|
45
|
-
return that.get()
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
f.core = that
|
|
49
|
-
f.get = that.get.bind(that)
|
|
50
|
-
f.on = that.on
|
|
51
|
-
f.dispose = that.dispose.bind(that)
|
|
52
|
-
f.fn = that.fn.bind(that)
|
|
53
|
-
|
|
54
|
-
Object.defineProperty(f, "value", {
|
|
55
|
-
get: () => that.value,
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
Object.defineProperty(f, "sneak", {
|
|
59
|
-
get: () => that.sneak,
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
return f as DerivedFn<V>
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
package/s/signals/core/effect.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import {microbounce} from "@e280/stz"
|
|
3
|
-
import {tracker} from "../../tracker/tracker.js"
|
|
4
|
-
|
|
5
|
-
export function effect(
|
|
6
|
-
collector: () => void,
|
|
7
|
-
responder: () => void = collector,
|
|
8
|
-
) {
|
|
9
|
-
|
|
10
|
-
return collectorEffect(collector, responder).dispose
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function collectorEffect<C = void>(
|
|
14
|
-
collector: () => C,
|
|
15
|
-
responder: () => void = collector,
|
|
16
|
-
) {
|
|
17
|
-
|
|
18
|
-
const {seen, result} = tracker.observe(collector)
|
|
19
|
-
const fn = microbounce(responder)
|
|
20
|
-
|
|
21
|
-
const disposers: (() => void)[] = []
|
|
22
|
-
const dispose = () => disposers.forEach(d => d())
|
|
23
|
-
|
|
24
|
-
for (const saw of seen) {
|
|
25
|
-
const dispose = tracker.subscribe(saw, fn)
|
|
26
|
-
disposers.push(dispose)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return {result, dispose}
|
|
30
|
-
}
|
|
31
|
-
|