@ersbeth/picoflow 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/plans/unifier-flowresource-avec-flowderivation-c9506e24.plan.md +372 -0
- package/README.md +25 -171
- package/biome.json +4 -1
- package/dist/picoflow.js +1129 -661
- package/dist/types/flow/base/flowDisposable.d.ts +67 -0
- package/dist/types/flow/base/flowDisposable.d.ts.map +1 -0
- package/dist/types/flow/base/flowEffect.d.ts +127 -0
- package/dist/types/flow/base/flowEffect.d.ts.map +1 -0
- package/dist/types/flow/base/flowGraph.d.ts +97 -0
- package/dist/types/flow/base/flowGraph.d.ts.map +1 -0
- package/dist/types/flow/base/flowSignal.d.ts +134 -0
- package/dist/types/flow/base/flowSignal.d.ts.map +1 -0
- package/dist/types/flow/base/flowTracker.d.ts +15 -0
- package/dist/types/flow/base/flowTracker.d.ts.map +1 -0
- package/dist/types/flow/base/index.d.ts +7 -0
- package/dist/types/flow/base/index.d.ts.map +1 -0
- package/dist/types/flow/base/utils.d.ts +20 -0
- package/dist/types/flow/base/utils.d.ts.map +1 -0
- package/dist/types/{advanced/array.d.ts → flow/collections/flowArray.d.ts} +50 -12
- package/dist/types/flow/collections/flowArray.d.ts.map +1 -0
- package/dist/types/flow/collections/flowMap.d.ts +224 -0
- package/dist/types/flow/collections/flowMap.d.ts.map +1 -0
- package/dist/types/flow/collections/index.d.ts +3 -0
- package/dist/types/flow/collections/index.d.ts.map +1 -0
- package/dist/types/flow/index.d.ts +4 -0
- package/dist/types/flow/index.d.ts.map +1 -0
- package/dist/types/flow/nodes/async/flowConstantAsync.d.ts +137 -0
- package/dist/types/flow/nodes/async/flowConstantAsync.d.ts.map +1 -0
- package/dist/types/flow/nodes/async/flowDerivationAsync.d.ts +137 -0
- package/dist/types/flow/nodes/async/flowDerivationAsync.d.ts.map +1 -0
- package/dist/types/flow/nodes/async/flowNodeAsync.d.ts +343 -0
- package/dist/types/flow/nodes/async/flowNodeAsync.d.ts.map +1 -0
- package/dist/types/flow/nodes/async/flowReadonlyAsync.d.ts +81 -0
- package/dist/types/flow/nodes/async/flowReadonlyAsync.d.ts.map +1 -0
- package/dist/types/flow/nodes/async/flowStateAsync.d.ts +111 -0
- package/dist/types/flow/nodes/async/flowStateAsync.d.ts.map +1 -0
- package/dist/types/flow/nodes/async/index.d.ts +6 -0
- package/dist/types/flow/nodes/async/index.d.ts.map +1 -0
- package/dist/types/flow/nodes/index.d.ts +3 -0
- package/dist/types/flow/nodes/index.d.ts.map +1 -0
- package/dist/types/flow/nodes/sync/flowConstant.d.ts +108 -0
- package/dist/types/flow/nodes/sync/flowConstant.d.ts.map +1 -0
- package/dist/types/flow/nodes/sync/flowDerivation.d.ts +100 -0
- package/dist/types/flow/nodes/sync/flowDerivation.d.ts.map +1 -0
- package/dist/types/flow/nodes/sync/flowNode.d.ts +314 -0
- package/dist/types/flow/nodes/sync/flowNode.d.ts.map +1 -0
- package/dist/types/flow/nodes/sync/flowReadonly.d.ts +57 -0
- package/dist/types/flow/nodes/sync/flowReadonly.d.ts.map +1 -0
- package/dist/types/flow/nodes/sync/flowState.d.ts +96 -0
- package/dist/types/flow/nodes/sync/flowState.d.ts.map +1 -0
- package/dist/types/flow/nodes/sync/index.d.ts +6 -0
- package/dist/types/flow/nodes/sync/index.d.ts.map +1 -0
- package/dist/types/index.d.ts +1 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/solid/converters.d.ts +34 -44
- package/dist/types/solid/converters.d.ts.map +1 -1
- package/dist/types/solid/primitives.d.ts +1 -0
- package/dist/types/solid/primitives.d.ts.map +1 -1
- package/docs/.vitepress/config.mts +1 -1
- package/docs/api/typedoc-sidebar.json +81 -1
- package/package.json +60 -58
- package/src/flow/base/flowDisposable.ts +71 -0
- package/src/flow/base/flowEffect.ts +171 -0
- package/src/flow/base/flowGraph.ts +288 -0
- package/src/flow/base/flowSignal.ts +207 -0
- package/src/flow/base/flowTracker.ts +17 -0
- package/src/flow/base/index.ts +6 -0
- package/src/flow/base/utils.ts +19 -0
- package/src/flow/collections/flowArray.ts +409 -0
- package/src/flow/collections/flowMap.ts +398 -0
- package/src/flow/collections/index.ts +2 -0
- package/src/flow/index.ts +3 -0
- package/src/flow/nodes/async/flowConstantAsync.ts +142 -0
- package/src/flow/nodes/async/flowDerivationAsync.ts +143 -0
- package/src/flow/nodes/async/flowNodeAsync.ts +474 -0
- package/src/flow/nodes/async/flowReadonlyAsync.ts +81 -0
- package/src/flow/nodes/async/flowStateAsync.ts +116 -0
- package/src/flow/nodes/async/index.ts +5 -0
- package/src/flow/nodes/await/advanced/index.ts +5 -0
- package/src/{advanced → flow/nodes/await/advanced}/resource.ts +37 -3
- package/src/{advanced → flow/nodes/await/advanced}/resourceAsync.ts +35 -3
- package/src/{advanced → flow/nodes/await/advanced}/stream.ts +40 -2
- package/src/{advanced → flow/nodes/await/advanced}/streamAsync.ts +38 -3
- package/src/flow/nodes/await/flowConstantAwait.ts +154 -0
- package/src/flow/nodes/await/flowDerivationAwait.ts +154 -0
- package/src/flow/nodes/await/flowNodeAwait.ts +508 -0
- package/src/flow/nodes/await/flowReadonlyAwait.ts +89 -0
- package/src/flow/nodes/await/flowStateAwait.ts +130 -0
- package/src/flow/nodes/await/index.ts +5 -0
- package/src/flow/nodes/index.ts +3 -0
- package/src/flow/nodes/sync/flowConstant.ts +111 -0
- package/src/flow/nodes/sync/flowDerivation.ts +105 -0
- package/src/flow/nodes/sync/flowNode.ts +439 -0
- package/src/flow/nodes/sync/flowReadonly.ts +57 -0
- package/src/flow/nodes/sync/flowState.ts +101 -0
- package/src/flow/nodes/sync/index.ts +5 -0
- package/src/index.ts +1 -47
- package/src/solid/converters.ts +59 -198
- package/src/solid/primitives.ts +4 -0
- package/test/base/flowEffect.test.ts +108 -0
- package/test/base/flowGraph.test.ts +485 -0
- package/test/base/flowSignal.test.ts +372 -0
- package/test/collections/flowArray.asyncStates.test.ts +1553 -0
- package/test/collections/flowArray.scalars.test.ts +1129 -0
- package/test/collections/flowArray.states.test.ts +1365 -0
- package/test/collections/flowMap.asyncStates.test.ts +1105 -0
- package/test/collections/flowMap.scalars.test.ts +877 -0
- package/test/collections/flowMap.states.test.ts +1097 -0
- package/test/nodes/async/flowConstantAsync.test.ts +860 -0
- package/test/nodes/async/flowDerivationAsync.test.ts +1517 -0
- package/test/nodes/async/flowStateAsync.test.ts +1387 -0
- package/test/{resource.test.ts → nodes/await/advanced/resource.test.ts} +21 -19
- package/test/{resourceAsync.test.ts → nodes/await/advanced/resourceAsync.test.ts} +3 -1
- package/test/{stream.test.ts → nodes/await/advanced/stream.test.ts} +30 -28
- package/test/{streamAsync.test.ts → nodes/await/advanced/streamAsync.test.ts} +16 -14
- package/test/nodes/await/flowConstantAwait.test.ts +643 -0
- package/test/nodes/await/flowDerivationAwait.test.ts +1583 -0
- package/test/nodes/await/flowStateAwait.test.ts +999 -0
- package/test/nodes/mixed/derivation.test.ts +1527 -0
- package/test/nodes/sync/flowConstant.test.ts +620 -0
- package/test/nodes/sync/flowDerivation.test.ts +1373 -0
- package/test/nodes/sync/flowState.test.ts +945 -0
- package/test/solid/converters.test.ts +721 -0
- package/test/solid/primitives.test.ts +1031 -0
- package/tsconfig.json +2 -1
- package/vitest.config.ts +7 -1
- package/IMPLEMENTATION_GUIDE.md +0 -1578
- package/dist/types/advanced/array.d.ts.map +0 -1
- package/dist/types/advanced/index.d.ts +0 -9
- package/dist/types/advanced/index.d.ts.map +0 -1
- package/dist/types/advanced/map.d.ts +0 -166
- package/dist/types/advanced/map.d.ts.map +0 -1
- package/dist/types/advanced/resource.d.ts +0 -78
- package/dist/types/advanced/resource.d.ts.map +0 -1
- package/dist/types/advanced/resourceAsync.d.ts +0 -56
- package/dist/types/advanced/resourceAsync.d.ts.map +0 -1
- package/dist/types/advanced/stream.d.ts +0 -117
- package/dist/types/advanced/stream.d.ts.map +0 -1
- package/dist/types/advanced/streamAsync.d.ts +0 -97
- package/dist/types/advanced/streamAsync.d.ts.map +0 -1
- package/dist/types/basic/constant.d.ts +0 -60
- package/dist/types/basic/constant.d.ts.map +0 -1
- package/dist/types/basic/derivation.d.ts +0 -89
- package/dist/types/basic/derivation.d.ts.map +0 -1
- package/dist/types/basic/disposable.d.ts +0 -82
- package/dist/types/basic/disposable.d.ts.map +0 -1
- package/dist/types/basic/effect.d.ts +0 -67
- package/dist/types/basic/effect.d.ts.map +0 -1
- package/dist/types/basic/index.d.ts +0 -10
- package/dist/types/basic/index.d.ts.map +0 -1
- package/dist/types/basic/observable.d.ts +0 -83
- package/dist/types/basic/observable.d.ts.map +0 -1
- package/dist/types/basic/signal.d.ts +0 -69
- package/dist/types/basic/signal.d.ts.map +0 -1
- package/dist/types/basic/state.d.ts +0 -47
- package/dist/types/basic/state.d.ts.map +0 -1
- package/dist/types/basic/trackingContext.d.ts +0 -33
- package/dist/types/basic/trackingContext.d.ts.map +0 -1
- package/dist/types/creators.d.ts +0 -340
- package/dist/types/creators.d.ts.map +0 -1
- package/src/advanced/array.ts +0 -222
- package/src/advanced/index.ts +0 -12
- package/src/advanced/map.ts +0 -193
- package/src/basic/constant.ts +0 -97
- package/src/basic/derivation.ts +0 -147
- package/src/basic/disposable.ts +0 -86
- package/src/basic/effect.ts +0 -104
- package/src/basic/index.ts +0 -9
- package/src/basic/observable.ts +0 -109
- package/src/basic/signal.ts +0 -145
- package/src/basic/state.ts +0 -60
- package/src/basic/trackingContext.ts +0 -45
- package/src/creators.ts +0 -395
- package/test/array.test.ts +0 -600
- package/test/constant.test.ts +0 -44
- package/test/derivation.test.ts +0 -539
- package/test/effect.test.ts +0 -29
- package/test/map.test.ts +0 -240
- package/test/signal.test.ts +0 -72
- package/test/state.test.ts +0 -212
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { effect, signal } from "#package";
|
|
3
|
+
|
|
4
|
+
describe("FlowSignal", () => {
|
|
5
|
+
describe("unit", () => {
|
|
6
|
+
describe("disposal", () => {
|
|
7
|
+
it("should have disposed property set to false initially and true after disposal", () => {
|
|
8
|
+
const $signal = signal();
|
|
9
|
+
expect($signal.disposed).toBe(false);
|
|
10
|
+
$signal.dispose();
|
|
11
|
+
expect($signal.disposed).toBe(true);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("should throw error when disposed twice", () => {
|
|
15
|
+
const $signal = signal();
|
|
16
|
+
$signal.dispose();
|
|
17
|
+
expect(() => $signal.dispose()).toThrow(
|
|
18
|
+
"[PicoFlow] Primitive is disposed",
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("should dispose signal successfully", () => {
|
|
23
|
+
const $signal = signal();
|
|
24
|
+
expect(() => $signal.dispose()).not.toThrow();
|
|
25
|
+
expect($signal.disposed).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("should accept self option without throwing", () => {
|
|
29
|
+
const $signal = signal();
|
|
30
|
+
expect(() => $signal.dispose({ self: true })).not.toThrow();
|
|
31
|
+
expect($signal.disposed).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("should accept default options without throwing", () => {
|
|
35
|
+
const $signal = signal();
|
|
36
|
+
expect(() => $signal.dispose()).not.toThrow();
|
|
37
|
+
expect($signal.disposed).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe("trigger", () => {
|
|
42
|
+
it("should return a promise when triggered", () => {
|
|
43
|
+
const $signal = signal();
|
|
44
|
+
const result = $signal.trigger();
|
|
45
|
+
expect(result).toBeInstanceOf(Promise);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("should throw error when trigger is called after disposal", async () => {
|
|
49
|
+
const $signal = signal();
|
|
50
|
+
$signal.dispose();
|
|
51
|
+
await expect($signal.trigger()).rejects.toThrow(
|
|
52
|
+
"[PicoFlow] Primitive is disposed",
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("should allow multiple triggers", async () => {
|
|
57
|
+
const $signal = signal();
|
|
58
|
+
const promise1 = $signal.trigger();
|
|
59
|
+
const promise2 = $signal.trigger();
|
|
60
|
+
const promise3 = $signal.trigger();
|
|
61
|
+
|
|
62
|
+
expect(promise1).toBeInstanceOf(Promise);
|
|
63
|
+
expect(promise2).toBeInstanceOf(Promise);
|
|
64
|
+
expect(promise3).toBeInstanceOf(Promise);
|
|
65
|
+
|
|
66
|
+
await Promise.all([promise1, promise2, promise3]);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe("watch", () => {
|
|
71
|
+
it("should throw error when watch is called after disposal", () => {
|
|
72
|
+
const $signal = signal();
|
|
73
|
+
const $tracker = signal(); // Use another signal as FlowTracker
|
|
74
|
+
$signal.dispose();
|
|
75
|
+
expect(() => $signal.watch($tracker)).toThrow(
|
|
76
|
+
"[PicoFlow] Primitive is disposed",
|
|
77
|
+
);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe("integration", () => {
|
|
83
|
+
describe("with effects", () => {
|
|
84
|
+
describe("watch", () => {
|
|
85
|
+
it("should register effect when watch is called", async () => {
|
|
86
|
+
const $signal = signal();
|
|
87
|
+
const effectFn = vi.fn();
|
|
88
|
+
effect((t) => {
|
|
89
|
+
$signal.watch(t);
|
|
90
|
+
effectFn();
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(1));
|
|
94
|
+
expect(effectFn).toHaveBeenCalledTimes(1);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("should throw error when watch is called after signal disposal", async () => {
|
|
98
|
+
const $signal = signal();
|
|
99
|
+
const effectFn = vi.fn();
|
|
100
|
+
effect((t) => {
|
|
101
|
+
$signal.watch(t);
|
|
102
|
+
effectFn();
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(1));
|
|
106
|
+
|
|
107
|
+
$signal.dispose();
|
|
108
|
+
|
|
109
|
+
effect((t) => {
|
|
110
|
+
expect(() => $signal.watch(t)).toThrow(
|
|
111
|
+
"[PicoFlow] Primitive is disposed",
|
|
112
|
+
);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
await expect($signal.trigger()).rejects.toThrow(
|
|
116
|
+
"[PicoFlow] Primitive is disposed",
|
|
117
|
+
);
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
describe("trigger", () => {
|
|
122
|
+
it("should notify effects when triggered", async () => {
|
|
123
|
+
const $signal = signal();
|
|
124
|
+
const effectFn = vi.fn();
|
|
125
|
+
effect((t) => {
|
|
126
|
+
$signal.watch(t);
|
|
127
|
+
effectFn();
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(1));
|
|
131
|
+
|
|
132
|
+
$signal.trigger();
|
|
133
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(2));
|
|
134
|
+
|
|
135
|
+
$signal.trigger();
|
|
136
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(3));
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it("should notify multiple effects when triggered", async () => {
|
|
140
|
+
const $signal = signal();
|
|
141
|
+
const effectFn1 = vi.fn();
|
|
142
|
+
const effectFn2 = vi.fn();
|
|
143
|
+
const effectFn3 = vi.fn();
|
|
144
|
+
|
|
145
|
+
effect((t) => {
|
|
146
|
+
$signal.watch(t);
|
|
147
|
+
effectFn1();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
effect((t) => {
|
|
151
|
+
$signal.watch(t);
|
|
152
|
+
effectFn2();
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
effect((t) => {
|
|
156
|
+
$signal.watch(t);
|
|
157
|
+
effectFn3();
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
await vi.waitFor(() => {
|
|
161
|
+
expect(effectFn1).toHaveBeenCalledTimes(1);
|
|
162
|
+
expect(effectFn2).toHaveBeenCalledTimes(1);
|
|
163
|
+
expect(effectFn3).toHaveBeenCalledTimes(1);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
$signal.trigger();
|
|
167
|
+
await vi.waitFor(() => {
|
|
168
|
+
expect(effectFn1).toHaveBeenCalledTimes(2);
|
|
169
|
+
expect(effectFn2).toHaveBeenCalledTimes(2);
|
|
170
|
+
expect(effectFn3).toHaveBeenCalledTimes(2);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it("should not notify effects after they are disposed", async () => {
|
|
175
|
+
const $signal = signal();
|
|
176
|
+
const effectFn = vi.fn();
|
|
177
|
+
const $effect = effect((t) => {
|
|
178
|
+
$signal.watch(t);
|
|
179
|
+
effectFn();
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(1));
|
|
183
|
+
|
|
184
|
+
$signal.trigger();
|
|
185
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(2));
|
|
186
|
+
|
|
187
|
+
$effect.dispose();
|
|
188
|
+
|
|
189
|
+
$signal.trigger();
|
|
190
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(2));
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it("should notify effects multiple times on multiple triggers", async () => {
|
|
194
|
+
const $signal = signal();
|
|
195
|
+
const effectFn = vi.fn();
|
|
196
|
+
effect((t) => {
|
|
197
|
+
$signal.watch(t);
|
|
198
|
+
effectFn();
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(1));
|
|
202
|
+
|
|
203
|
+
$signal.trigger();
|
|
204
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(2));
|
|
205
|
+
|
|
206
|
+
$signal.trigger();
|
|
207
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(3));
|
|
208
|
+
|
|
209
|
+
$signal.trigger();
|
|
210
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(4));
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it("should await trigger promise before effects complete", async () => {
|
|
214
|
+
const $signal = signal();
|
|
215
|
+
const executionOrder: string[] = [];
|
|
216
|
+
const effectFn = vi.fn();
|
|
217
|
+
|
|
218
|
+
effect((t) => {
|
|
219
|
+
$signal.watch(t);
|
|
220
|
+
executionOrder.push("effect-executed");
|
|
221
|
+
effectFn();
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(1));
|
|
225
|
+
executionOrder.push("after-initial-effect");
|
|
226
|
+
|
|
227
|
+
const triggerPromise = $signal.trigger();
|
|
228
|
+
executionOrder.push("trigger-called");
|
|
229
|
+
|
|
230
|
+
await triggerPromise;
|
|
231
|
+
executionOrder.push("trigger-resolved");
|
|
232
|
+
|
|
233
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(2));
|
|
234
|
+
|
|
235
|
+
expect(executionOrder).toEqual([
|
|
236
|
+
"effect-executed",
|
|
237
|
+
"after-initial-effect",
|
|
238
|
+
"effect-executed",
|
|
239
|
+
"trigger-called",
|
|
240
|
+
"trigger-resolved",
|
|
241
|
+
]);
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
describe("dispose", () => {
|
|
246
|
+
it("should dispose effects when signal is disposed", async () => {
|
|
247
|
+
const $signal = signal();
|
|
248
|
+
const effectFn = vi.fn();
|
|
249
|
+
const $effect = effect((t) => {
|
|
250
|
+
$signal.watch(t);
|
|
251
|
+
effectFn();
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(1));
|
|
255
|
+
expect($effect.disposed).toBe(false);
|
|
256
|
+
|
|
257
|
+
$signal.dispose();
|
|
258
|
+
|
|
259
|
+
expect($effect.disposed).toBe(true);
|
|
260
|
+
|
|
261
|
+
await expect($signal.trigger()).rejects.toThrow(
|
|
262
|
+
"[PicoFlow] Primitive is disposed",
|
|
263
|
+
);
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
it("should not dispose effects when signal is disposed with self option", async () => {
|
|
267
|
+
const $signal = signal();
|
|
268
|
+
const effectFn = vi.fn();
|
|
269
|
+
const $effect = effect((t) => {
|
|
270
|
+
$signal.watch(t);
|
|
271
|
+
effectFn();
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(1));
|
|
275
|
+
expect($effect.disposed).toBe(false);
|
|
276
|
+
|
|
277
|
+
$signal.dispose({ self: true });
|
|
278
|
+
|
|
279
|
+
expect($effect.disposed).toBe(false);
|
|
280
|
+
expect($signal.disposed).toBe(true);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
it("should unregister effects when signal is disposed with self option", async () => {
|
|
284
|
+
const $signal = signal();
|
|
285
|
+
const effectFn = vi.fn();
|
|
286
|
+
const $effect = effect((t) => {
|
|
287
|
+
$signal.watch(t);
|
|
288
|
+
effectFn();
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(1));
|
|
292
|
+
|
|
293
|
+
$signal.dispose({ self: true });
|
|
294
|
+
|
|
295
|
+
// Effect should still be active but not notified
|
|
296
|
+
expect($effect.disposed).toBe(false);
|
|
297
|
+
|
|
298
|
+
// But signal is disposed so trigger will fail
|
|
299
|
+
await expect($signal.trigger()).rejects.toThrow(
|
|
300
|
+
"[PicoFlow] Primitive is disposed",
|
|
301
|
+
);
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
describe("signal chaining", () => {
|
|
307
|
+
it("should notify listener signals when triggered", async () => {
|
|
308
|
+
const $signal1 = signal();
|
|
309
|
+
const $signal2 = signal();
|
|
310
|
+
const effectFn = vi.fn();
|
|
311
|
+
|
|
312
|
+
// signal2 watches signal1
|
|
313
|
+
effect((t) => {
|
|
314
|
+
$signal1.watch(t);
|
|
315
|
+
$signal2.trigger();
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
// effect watches signal2
|
|
319
|
+
effect((t) => {
|
|
320
|
+
$signal2.watch(t);
|
|
321
|
+
effectFn();
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(1));
|
|
325
|
+
|
|
326
|
+
$signal1.trigger();
|
|
327
|
+
await vi.waitFor(() => expect(effectFn).toHaveBeenCalledTimes(2));
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
// TODO: Fix this test
|
|
331
|
+
it.skip("should notify chained signals in correct order", async () => {
|
|
332
|
+
const $signal1 = signal();
|
|
333
|
+
const $signal2 = signal();
|
|
334
|
+
const $signal3 = signal();
|
|
335
|
+
const executionOrder: string[] = [];
|
|
336
|
+
|
|
337
|
+
effect((t) => {
|
|
338
|
+
$signal1.watch(t);
|
|
339
|
+
executionOrder.push("signal1-triggered");
|
|
340
|
+
$signal2.trigger();
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
effect((t) => {
|
|
344
|
+
$signal2.watch(t);
|
|
345
|
+
executionOrder.push("signal2-triggered");
|
|
346
|
+
$signal3.trigger();
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
effect((t) => {
|
|
350
|
+
$signal3.watch(t);
|
|
351
|
+
executionOrder.push("signal3-triggered");
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
await vi.waitFor(() =>
|
|
355
|
+
expect(executionOrder.length).toBeGreaterThan(0),
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
executionOrder.length = 0; // Clear initial execution
|
|
359
|
+
|
|
360
|
+
$signal1.trigger();
|
|
361
|
+
await vi.waitFor(() => expect(executionOrder.length).toBe(5));
|
|
362
|
+
console.log(executionOrder);
|
|
363
|
+
|
|
364
|
+
expect(executionOrder).toEqual([
|
|
365
|
+
"signal1-triggered",
|
|
366
|
+
"signal2-triggered",
|
|
367
|
+
"signal3-triggered",
|
|
368
|
+
]);
|
|
369
|
+
});
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
});
|