@ersbeth/picoflow 2.0.1 → 2.0.3
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/README.md +10 -0
- package/SKILL.md +106 -0
- package/dist/types/api/base/flowSubscribable.d.ts +3 -3
- package/dist/types/api/base/flowSubscribable.d.ts.map +1 -1
- package/package.json +5 -1
- package/.gitlab-ci.yml +0 -24
- package/.vscode/settings.json +0 -5
- package/CHANGELOG.md +0 -94
- package/biome.json +0 -47
- package/docs/.vitepress/config.mts +0 -145
- package/docs/api/functions/array.md +0 -35
- package/docs/api/functions/constant.md +0 -33
- package/docs/api/functions/constantAsync.md +0 -69
- package/docs/api/functions/derivation.md +0 -34
- package/docs/api/functions/derivationAsync.md +0 -34
- package/docs/api/functions/from.md +0 -129
- package/docs/api/functions/isDisposable.md +0 -27
- package/docs/api/functions/map.md +0 -36
- package/docs/api/functions/signal.md +0 -21
- package/docs/api/functions/state.md +0 -67
- package/docs/api/functions/stateAsync.md +0 -69
- package/docs/api/functions/subscribe.md +0 -40
- package/docs/api/functions/writableDerivation.md +0 -33
- package/docs/api/functions/writableDerivationAsync.md +0 -34
- package/docs/api/index.md +0 -61
- package/docs/api/interfaces/FlowArray.md +0 -439
- package/docs/api/interfaces/FlowConstant.md +0 -220
- package/docs/api/interfaces/FlowConstantAsync.md +0 -221
- package/docs/api/interfaces/FlowDerivation.md +0 -241
- package/docs/api/interfaces/FlowDerivationAsync.md +0 -242
- package/docs/api/interfaces/FlowDisposable.md +0 -59
- package/docs/api/interfaces/FlowEffect.md +0 -64
- package/docs/api/interfaces/FlowMap.md +0 -374
- package/docs/api/interfaces/FlowObservable.md +0 -155
- package/docs/api/interfaces/FlowSignal.md +0 -156
- package/docs/api/interfaces/FlowState.md +0 -269
- package/docs/api/interfaces/FlowStateAsync.md +0 -268
- package/docs/api/interfaces/FlowSubscribable.md +0 -55
- package/docs/api/interfaces/FlowTracker.md +0 -61
- package/docs/api/interfaces/FlowValue.md +0 -222
- package/docs/api/interfaces/FlowWritableDerivation.md +0 -292
- package/docs/api/interfaces/FlowWritableDerivationAsync.md +0 -293
- package/docs/api/type-aliases/DerivationFunction.md +0 -28
- package/docs/api/type-aliases/DerivationFunctionAsync.md +0 -28
- package/docs/api/type-aliases/FlowArrayAction.md +0 -60
- package/docs/api/type-aliases/FlowDataTracker.md +0 -33
- package/docs/api/type-aliases/FlowMapAction.md +0 -48
- package/docs/api/type-aliases/FlowOnDataListener.md +0 -33
- package/docs/api/type-aliases/FlowOnErrorListener.md +0 -27
- package/docs/api/type-aliases/FlowOnPendingListener.md +0 -21
- package/docs/api/type-aliases/FlowReadonly.md +0 -22
- package/docs/api/type-aliases/InitFunction.md +0 -21
- package/docs/api/type-aliases/InitFunctionAsync.md +0 -21
- package/docs/api/type-aliases/NotPromise.md +0 -21
- package/docs/api/type-aliases/UpdateFunction.md +0 -27
- package/docs/api/type-aliases/UpdateFunctionAsync.md +0 -27
- package/docs/api/typedoc-sidebar.json +0 -65
- package/docs/examples/examples.md +0 -2311
- package/docs/examples/patterns.md +0 -649
- package/docs/guide/advanced/architecture.md +0 -1234
- package/docs/guide/advanced/disposal.md +0 -426
- package/docs/guide/advanced/migration-v1.md +0 -464
- package/docs/guide/advanced/migration-v2.md +0 -204
- package/docs/guide/advanced/solidjs.md +0 -135
- package/docs/guide/introduction/concepts.md +0 -57
- package/docs/guide/introduction/conventions.md +0 -30
- package/docs/guide/introduction/getting-started.md +0 -139
- package/docs/guide/introduction/lifecycle.md +0 -368
- package/docs/guide/primitives/array.md +0 -286
- package/docs/guide/primitives/constant.md +0 -207
- package/docs/guide/primitives/derivations.md +0 -281
- package/docs/guide/primitives/effects.md +0 -372
- package/docs/guide/primitives/map.md +0 -265
- package/docs/guide/primitives/overview.md +0 -92
- package/docs/guide/primitives/signal.md +0 -222
- package/docs/guide/primitives/state.md +0 -272
- package/docs/index.md +0 -47
- package/docs/public/logo.svg +0 -1
- package/src/api/base/flowDisposable.ts +0 -44
- package/src/api/base/flowObservable.ts +0 -28
- package/src/api/base/flowSubscribable.ts +0 -87
- package/src/api/base/flowTracker.ts +0 -7
- package/src/api/base/index.ts +0 -4
- package/src/api/index.ts +0 -2
- package/src/api/nodes/async/flowConstantAsync.ts +0 -36
- package/src/api/nodes/async/flowDerivationAsync.ts +0 -42
- package/src/api/nodes/async/flowStateAsync.ts +0 -47
- package/src/api/nodes/async/flowWritableDerivationAsync.ts +0 -33
- package/src/api/nodes/async/index.ts +0 -4
- package/src/api/nodes/collections/flowArray.ts +0 -155
- package/src/api/nodes/collections/flowMap.ts +0 -115
- package/src/api/nodes/collections/index.ts +0 -2
- package/src/api/nodes/flowEffect.ts +0 -42
- package/src/api/nodes/flowSignal.ts +0 -28
- package/src/api/nodes/flowValue.ts +0 -37
- package/src/api/nodes/index.ts +0 -7
- package/src/api/nodes/sync/flowConstant.ts +0 -33
- package/src/api/nodes/sync/flowDerivation.ts +0 -41
- package/src/api/nodes/sync/flowState.ts +0 -45
- package/src/api/nodes/sync/flowWritableDerivation.ts +0 -31
- package/src/api/nodes/sync/index.ts +0 -4
- package/src/api/nodes/utils.ts +0 -24
- package/src/base/disposable.ts +0 -18
- package/src/base/executionStack.ts +0 -42
- package/src/base/index.ts +0 -5
- package/src/base/node.ts +0 -98
- package/src/base/observable.ts +0 -92
- package/src/base/observer.ts +0 -51
- package/src/converters/index.ts +0 -1
- package/src/converters/solid.ts +0 -109
- package/src/index.ts +0 -2
- package/src/nodes/arrayNode.ts +0 -180
- package/src/nodes/effectNode.ts +0 -58
- package/src/nodes/index.ts +0 -7
- package/src/nodes/mapNode.ts +0 -125
- package/src/nodes/signalNode.ts +0 -19
- package/src/nodes/valueAsyncNode.ts +0 -85
- package/src/nodes/valueNode.ts +0 -148
- package/src/nodes/valueSyncNode.ts +0 -125
- package/src/schedulers/asyncResolver.ts +0 -78
- package/src/schedulers/asyncScheduler.ts +0 -66
- package/src/schedulers/index.ts +0 -4
- package/src/schedulers/pendingError.ts +0 -13
- package/src/schedulers/scheduler.ts +0 -9
- package/src/schedulers/syncResolver.ts +0 -69
- package/src/schedulers/syncScheduler.ts +0 -55
- package/test/base/pendingError.test.ts +0 -67
- package/test/converters/solid.derivation.browser.test.tsx +0 -69
- package/test/converters/solid.node.test.ts +0 -654
- package/test/converters/solid.state.browser.test.tsx +0 -1592
- package/test/reactivity/flowSignal.test.ts +0 -226
- package/test/reactivity/nodes/async/asyncScheduler/asyncResolver.test.ts +0 -593
- package/test/reactivity/nodes/async/asyncScheduler/asyncScheduler.test.ts +0 -317
- package/test/reactivity/nodes/async/flowConstantAsync.test.ts +0 -652
- package/test/reactivity/nodes/async/flowDerivation.test.ts +0 -898
- package/test/reactivity/nodes/async/flowDerivationAsync.test.ts +0 -1716
- package/test/reactivity/nodes/async/flowStateAsync.test.ts +0 -708
- package/test/reactivity/nodes/async/flowWritableDerivationAsync.test.ts +0 -614
- package/test/reactivity/nodes/collections/flowArray.asyncStates.test.ts +0 -1289
- package/test/reactivity/nodes/collections/flowArray.scalars.test.ts +0 -961
- package/test/reactivity/nodes/collections/flowArray.states.test.ts +0 -1035
- package/test/reactivity/nodes/collections/flowMap.asyncStates.test.ts +0 -960
- package/test/reactivity/nodes/collections/flowMap.scalars.test.ts +0 -775
- package/test/reactivity/nodes/collections/flowMap.states.test.ts +0 -958
- package/test/reactivity/nodes/sync/flowConstant.test.ts +0 -377
- package/test/reactivity/nodes/sync/flowDerivation.test.ts +0 -896
- package/test/reactivity/nodes/sync/flowState.test.ts +0 -341
- package/test/reactivity/nodes/sync/flowWritableDerivation.test.ts +0 -603
- package/test/vitest.d.ts +0 -10
- package/tsconfig.json +0 -37
- package/typedoc.json +0 -37
- package/vite.config.ts +0 -31
- package/vitest.browser.config.ts +0 -21
- package/vitest.config.ts +0 -17
|
@@ -1,603 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from "vitest";
|
|
2
|
-
import { derivation, signal, state, subscribe, writableDerivation } from "~";
|
|
3
|
-
|
|
4
|
-
describe("flowWritableDerivation", () => {
|
|
5
|
-
describe("unit", () => {
|
|
6
|
-
describe("set on derivation", () => {
|
|
7
|
-
it("should override computed value when set is called", async () => {
|
|
8
|
-
const $state = state(1);
|
|
9
|
-
const $writableDerivation = writableDerivation((t) => $state.get(t) * 2);
|
|
10
|
-
|
|
11
|
-
expect(await $writableDerivation.pick()).toBe(2);
|
|
12
|
-
|
|
13
|
-
$writableDerivation.set(100);
|
|
14
|
-
expect(await $writableDerivation.pick()).toBe(100);
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it("should notify dependents when set overrides computed value", async () => {
|
|
18
|
-
const $state = state(1);
|
|
19
|
-
const $writableDerivation = writableDerivation((t) => $state.get(t) * 2);
|
|
20
|
-
const onData = vi.fn();
|
|
21
|
-
|
|
22
|
-
$writableDerivation.subscribe(onData);
|
|
23
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
24
|
-
expect(onData).toHaveBeenLastCalledWith(2);
|
|
25
|
-
|
|
26
|
-
$writableDerivation.set(100);
|
|
27
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
28
|
-
expect(onData).toHaveBeenLastCalledWith(100);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it("should work with updater function on writableDerivation with dependencies", async () => {
|
|
32
|
-
const $state = state(5);
|
|
33
|
-
const $writableDerivation = writableDerivation((t) => $state.get(t) * 2);
|
|
34
|
-
const onData = vi.fn();
|
|
35
|
-
|
|
36
|
-
$writableDerivation.subscribe(onData);
|
|
37
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
38
|
-
expect(onData).toHaveBeenLastCalledWith(10);
|
|
39
|
-
|
|
40
|
-
$writableDerivation.set((current) => (current ?? 0) + 5);
|
|
41
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
42
|
-
expect(onData).toHaveBeenLastCalledWith(15);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it("should not notify when set with same value on writableDerivation", async () => {
|
|
46
|
-
const $state = state(1);
|
|
47
|
-
const $writableDerivation = writableDerivation((t) => $state.get(t) * 2);
|
|
48
|
-
const onData = vi.fn();
|
|
49
|
-
|
|
50
|
-
$writableDerivation.subscribe(onData);
|
|
51
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
52
|
-
expect(onData).toHaveBeenLastCalledWith(2);
|
|
53
|
-
|
|
54
|
-
$writableDerivation.set(2);
|
|
55
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
56
|
-
expect(onData).toHaveBeenCalledTimes(1);
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
describe("set and reactive dependencies", () => {
|
|
61
|
-
it("should recompute when dependency changes after set", async () => {
|
|
62
|
-
const $state = state(1);
|
|
63
|
-
const $writableDerivation = writableDerivation((t) => $state.get(t) * 2);
|
|
64
|
-
|
|
65
|
-
expect(await $writableDerivation.pick()).toBe(2);
|
|
66
|
-
|
|
67
|
-
$writableDerivation.set(100);
|
|
68
|
-
expect(await $writableDerivation.pick()).toBe(100);
|
|
69
|
-
|
|
70
|
-
$state.set(5);
|
|
71
|
-
// When dependency changes, derivation is marked dirty and recomputes on access
|
|
72
|
-
expect(await $writableDerivation.pick()).toBe(10);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it("should override set value when dependency changes and derivation is accessed", async () => {
|
|
76
|
-
const $state = state(1);
|
|
77
|
-
const computeFn = vi.fn((t) => $state.get(t) * 2);
|
|
78
|
-
const $writableDerivation = writableDerivation(computeFn);
|
|
79
|
-
|
|
80
|
-
expect(await $writableDerivation.pick()).toBe(2);
|
|
81
|
-
expect(computeFn).toHaveBeenCalledTimes(1);
|
|
82
|
-
|
|
83
|
-
$writableDerivation.set(100);
|
|
84
|
-
expect(await $writableDerivation.pick()).toBe(100);
|
|
85
|
-
expect(computeFn).toHaveBeenCalledTimes(1);
|
|
86
|
-
|
|
87
|
-
$state.set(5);
|
|
88
|
-
// When accessed, it should recompute because dependency changed
|
|
89
|
-
expect(await $writableDerivation.pick()).toBe(10);
|
|
90
|
-
expect(computeFn).toHaveBeenCalledTimes(2);
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it("should handle set after dependency change", async () => {
|
|
94
|
-
const $state = state(1);
|
|
95
|
-
const $writableDerivation = writableDerivation((t) => $state.get(t) * 2);
|
|
96
|
-
const onData = vi.fn();
|
|
97
|
-
|
|
98
|
-
$writableDerivation.subscribe(onData);
|
|
99
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
100
|
-
expect(onData).toHaveBeenLastCalledWith(2);
|
|
101
|
-
|
|
102
|
-
$state.set(5);
|
|
103
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
104
|
-
expect(onData).toHaveBeenLastCalledWith(10);
|
|
105
|
-
|
|
106
|
-
$writableDerivation.set(200);
|
|
107
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(3));
|
|
108
|
-
expect(onData).toHaveBeenLastCalledWith(200);
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it("should handle set then dependency change then refresh", async () => {
|
|
112
|
-
const $state = state(1);
|
|
113
|
-
const computeFn = vi.fn((t) => $state.get(t) * 2);
|
|
114
|
-
const $writableDerivation = writableDerivation(computeFn);
|
|
115
|
-
|
|
116
|
-
expect(await $writableDerivation.pick()).toBe(2);
|
|
117
|
-
expect(computeFn).toHaveBeenCalledTimes(1);
|
|
118
|
-
|
|
119
|
-
$writableDerivation.set(100);
|
|
120
|
-
expect(await $writableDerivation.pick()).toBe(100);
|
|
121
|
-
expect(computeFn).toHaveBeenCalledTimes(1);
|
|
122
|
-
|
|
123
|
-
$state.set(5);
|
|
124
|
-
$writableDerivation.refresh();
|
|
125
|
-
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
126
|
-
expect(computeFn).toHaveBeenCalledTimes(2);
|
|
127
|
-
expect(await $writableDerivation.pick()).toBe(10);
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
describe("set with different statuses", () => {
|
|
132
|
-
it("should work when set is called on dirty derivation", async () => {
|
|
133
|
-
const $state = state(1);
|
|
134
|
-
const $writableDerivation = writableDerivation((t) => $state.get(t) * 2);
|
|
135
|
-
|
|
136
|
-
await $writableDerivation.pick();
|
|
137
|
-
$state.set(5);
|
|
138
|
-
// Now derivation is dirty
|
|
139
|
-
|
|
140
|
-
$writableDerivation.set(100);
|
|
141
|
-
expect(await $writableDerivation.pick()).toBe(100);
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
it("should work when set is called on pending derivation", async () => {
|
|
145
|
-
const $state = state(1);
|
|
146
|
-
const promise = Promise.resolve(2);
|
|
147
|
-
const $writableDerivation = writableDerivation((t) => {
|
|
148
|
-
const value = $state.get(t);
|
|
149
|
-
if (value === 2) {
|
|
150
|
-
throw promise;
|
|
151
|
-
}
|
|
152
|
-
return value * 2;
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
expect(await $writableDerivation.pick()).toBe(2);
|
|
156
|
-
|
|
157
|
-
$state.set(2);
|
|
158
|
-
// Now derivation is pending
|
|
159
|
-
|
|
160
|
-
$writableDerivation.set(100);
|
|
161
|
-
expect(await $writableDerivation.pick()).toBe(100);
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
it("should work when set is called on error derivation", async () => {
|
|
165
|
-
const $state = state(1);
|
|
166
|
-
const error = new Error("Compute error");
|
|
167
|
-
const $writableDerivation = writableDerivation((t) => {
|
|
168
|
-
const value = $state.get(t);
|
|
169
|
-
if (value > 1) {
|
|
170
|
-
throw error;
|
|
171
|
-
}
|
|
172
|
-
return value * 2;
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
expect(await $writableDerivation.pick()).toBe(2);
|
|
176
|
-
|
|
177
|
-
$state.set(2);
|
|
178
|
-
// Now derivation is in error state
|
|
179
|
-
|
|
180
|
-
$writableDerivation.set(100);
|
|
181
|
-
expect(await $writableDerivation.pick()).toBe(100);
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
it("should work when set is called on resolved derivation with dependencies", async () => {
|
|
185
|
-
const $state = state(1);
|
|
186
|
-
const $writableDerivation = writableDerivation((t) => $state.get(t) * 2);
|
|
187
|
-
|
|
188
|
-
await $writableDerivation.pick();
|
|
189
|
-
// Now derivation is resolved
|
|
190
|
-
|
|
191
|
-
$writableDerivation.set(100);
|
|
192
|
-
expect(await $writableDerivation.pick()).toBe(100);
|
|
193
|
-
});
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
describe("set and refresh interaction", () => {
|
|
197
|
-
it("should override set value when refresh is called", async () => {
|
|
198
|
-
const $state = state(5);
|
|
199
|
-
const $writableDerivation = writableDerivation((t) => $state.get(t) * 2);
|
|
200
|
-
const onData = vi.fn();
|
|
201
|
-
|
|
202
|
-
$writableDerivation.subscribe(onData);
|
|
203
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
204
|
-
expect(onData).toHaveBeenLastCalledWith(10);
|
|
205
|
-
|
|
206
|
-
$writableDerivation.set(100);
|
|
207
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
208
|
-
expect(onData).toHaveBeenLastCalledWith(100);
|
|
209
|
-
|
|
210
|
-
$writableDerivation.refresh();
|
|
211
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(3));
|
|
212
|
-
expect(onData).toHaveBeenLastCalledWith(10);
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
it("should override refresh value when set is called after refresh", async () => {
|
|
216
|
-
const $state = state(5);
|
|
217
|
-
const $writableDerivation = writableDerivation((t) => $state.get(t) * 2);
|
|
218
|
-
const onData = vi.fn();
|
|
219
|
-
|
|
220
|
-
$writableDerivation.subscribe(onData);
|
|
221
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
222
|
-
expect(onData).toHaveBeenLastCalledWith(10);
|
|
223
|
-
|
|
224
|
-
$writableDerivation.refresh();
|
|
225
|
-
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
226
|
-
|
|
227
|
-
$writableDerivation.set(200);
|
|
228
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
229
|
-
expect(onData).toHaveBeenLastCalledWith(200);
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
it("should handle set then refresh then dependency change", async () => {
|
|
233
|
-
const $state = state(1);
|
|
234
|
-
const computeFn = vi.fn((t) => $state.get(t) * 2);
|
|
235
|
-
const $writableDerivation = writableDerivation(computeFn);
|
|
236
|
-
|
|
237
|
-
expect(await $writableDerivation.pick()).toBe(2);
|
|
238
|
-
expect(computeFn).toHaveBeenCalledTimes(1);
|
|
239
|
-
|
|
240
|
-
$writableDerivation.set(100);
|
|
241
|
-
expect(await $writableDerivation.pick()).toBe(100);
|
|
242
|
-
expect(computeFn).toHaveBeenCalledTimes(1);
|
|
243
|
-
|
|
244
|
-
$writableDerivation.refresh();
|
|
245
|
-
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
246
|
-
expect(computeFn).toHaveBeenCalledTimes(2);
|
|
247
|
-
expect(await $writableDerivation.pick()).toBe(2);
|
|
248
|
-
|
|
249
|
-
$state.set(5);
|
|
250
|
-
expect(await $writableDerivation.pick()).toBe(10);
|
|
251
|
-
expect(computeFn).toHaveBeenCalledTimes(3);
|
|
252
|
-
});
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
describe("set with computed dependencies", () => {
|
|
256
|
-
it("should work with set on writableDerivation depending on another derivation", async () => {
|
|
257
|
-
const $state = state(1);
|
|
258
|
-
const $derivation1 = derivation((t) => $state.get(t) * 2);
|
|
259
|
-
const $writableDerivation = writableDerivation((t) => $derivation1.get(t) * 2);
|
|
260
|
-
const onData = vi.fn();
|
|
261
|
-
|
|
262
|
-
$writableDerivation.subscribe(onData);
|
|
263
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
264
|
-
expect(onData).toHaveBeenLastCalledWith(4);
|
|
265
|
-
|
|
266
|
-
$writableDerivation.set(100);
|
|
267
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
268
|
-
expect(onData).toHaveBeenLastCalledWith(100);
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
it("should work with set on writableDerivation depending on state", async () => {
|
|
272
|
-
const $state = state(1);
|
|
273
|
-
const $writableDerivation = writableDerivation((t) => $state.get(t) * 2);
|
|
274
|
-
const onData = vi.fn();
|
|
275
|
-
|
|
276
|
-
$writableDerivation.subscribe(onData);
|
|
277
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
278
|
-
expect(onData).toHaveBeenLastCalledWith(2);
|
|
279
|
-
|
|
280
|
-
$writableDerivation.set(50);
|
|
281
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
282
|
-
expect(onData).toHaveBeenLastCalledWith(50);
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
it("should work with set on writableDerivation depending on signal", async () => {
|
|
286
|
-
const $signal = signal();
|
|
287
|
-
const $state = state(0);
|
|
288
|
-
const $writableDerivation = writableDerivation((t) => {
|
|
289
|
-
$signal.watch(t);
|
|
290
|
-
return $state.get(t);
|
|
291
|
-
});
|
|
292
|
-
const onData = vi.fn();
|
|
293
|
-
|
|
294
|
-
$writableDerivation.subscribe(onData);
|
|
295
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
296
|
-
expect(onData).toHaveBeenLastCalledWith(0);
|
|
297
|
-
|
|
298
|
-
$writableDerivation.set(99);
|
|
299
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
300
|
-
expect(onData).toHaveBeenLastCalledWith(99);
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
it("should work with set on writableDerivation with multiple dependencies", async () => {
|
|
304
|
-
const $state1 = state(1);
|
|
305
|
-
const $state2 = state(2);
|
|
306
|
-
const $writableDerivation = writableDerivation((t) => $state1.get(t) + $state2.get(t));
|
|
307
|
-
const onData = vi.fn();
|
|
308
|
-
|
|
309
|
-
$writableDerivation.subscribe(onData);
|
|
310
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
311
|
-
expect(onData).toHaveBeenLastCalledWith(3);
|
|
312
|
-
|
|
313
|
-
$writableDerivation.set(999);
|
|
314
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
315
|
-
expect(onData).toHaveBeenLastCalledWith(999);
|
|
316
|
-
});
|
|
317
|
-
});
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
describe("with effect", () => {
|
|
321
|
-
describe("set in reactive context", () => {
|
|
322
|
-
it("should work when effect does set on writableDerivation with dependencies", async () => {
|
|
323
|
-
const $state = state(1);
|
|
324
|
-
const $writableDerivation = writableDerivation((t) => $state.get(t) * 2);
|
|
325
|
-
const onData = vi.fn();
|
|
326
|
-
|
|
327
|
-
subscribe(
|
|
328
|
-
(t) => $writableDerivation.get(t),
|
|
329
|
-
(data) => {
|
|
330
|
-
if (data === 2) {
|
|
331
|
-
$writableDerivation.set(100);
|
|
332
|
-
}
|
|
333
|
-
onData(data);
|
|
334
|
-
},
|
|
335
|
-
);
|
|
336
|
-
|
|
337
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
338
|
-
expect(onData).toHaveBeenNthCalledWith(1, 2);
|
|
339
|
-
expect(onData).toHaveBeenNthCalledWith(2, 100);
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
it("should work when one effect observes and another effect does set", async () => {
|
|
343
|
-
const $state = state(1);
|
|
344
|
-
const $writableDerivation = writableDerivation((t) => $state.get(t) * 2);
|
|
345
|
-
const observerFn = vi.fn();
|
|
346
|
-
const setterFn = vi.fn();
|
|
347
|
-
|
|
348
|
-
subscribe(
|
|
349
|
-
(t) => $writableDerivation.get(t),
|
|
350
|
-
(data) => observerFn(data),
|
|
351
|
-
);
|
|
352
|
-
|
|
353
|
-
subscribe(
|
|
354
|
-
() => undefined,
|
|
355
|
-
() => {
|
|
356
|
-
$writableDerivation.set(200);
|
|
357
|
-
setterFn();
|
|
358
|
-
},
|
|
359
|
-
);
|
|
360
|
-
|
|
361
|
-
await vi.waitFor(() => expect(observerFn).toHaveBeenCalledTimes(2));
|
|
362
|
-
expect(observerFn).toHaveBeenNthCalledWith(1, 2);
|
|
363
|
-
expect(observerFn).toHaveBeenNthCalledWith(2, 200);
|
|
364
|
-
expect(setterFn).toHaveBeenCalledTimes(1);
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
it("should work when dependency changes then set is done", async () => {
|
|
368
|
-
const $state = state(1);
|
|
369
|
-
const $writableDerivation = writableDerivation((t) => $state.get(t) * 2);
|
|
370
|
-
const onData = vi.fn();
|
|
371
|
-
|
|
372
|
-
subscribe(
|
|
373
|
-
(t) => $writableDerivation.get(t),
|
|
374
|
-
(data) => {
|
|
375
|
-
if (data === 4) {
|
|
376
|
-
$writableDerivation.set(300);
|
|
377
|
-
}
|
|
378
|
-
onData(data);
|
|
379
|
-
},
|
|
380
|
-
);
|
|
381
|
-
|
|
382
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
383
|
-
expect(onData).toHaveBeenLastCalledWith(2);
|
|
384
|
-
|
|
385
|
-
$state.set(2);
|
|
386
|
-
// Effect runs when dependency changes (value 4), set(300) is called in the effect
|
|
387
|
-
// The set may not trigger another effect run in the same execution cycle
|
|
388
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
389
|
-
expect(onData).toHaveBeenNthCalledWith(2, 4);
|
|
390
|
-
// Verify that set was applied
|
|
391
|
-
expect(await $writableDerivation.pick()).toBe(300);
|
|
392
|
-
});
|
|
393
|
-
});
|
|
394
|
-
|
|
395
|
-
describe("set and dependency changes", () => {
|
|
396
|
-
it("should handle dependency change then set", async () => {
|
|
397
|
-
const $state = state(1);
|
|
398
|
-
const $writableDerivation = writableDerivation((t) => $state.get(t) * 2);
|
|
399
|
-
const onData = vi.fn();
|
|
400
|
-
|
|
401
|
-
subscribe(
|
|
402
|
-
(t) => $writableDerivation.get(t),
|
|
403
|
-
(data) => onData(data),
|
|
404
|
-
);
|
|
405
|
-
|
|
406
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
407
|
-
expect(onData).toHaveBeenLastCalledWith(2);
|
|
408
|
-
|
|
409
|
-
$state.set(5);
|
|
410
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
411
|
-
expect(onData).toHaveBeenLastCalledWith(10);
|
|
412
|
-
|
|
413
|
-
$writableDerivation.set(400);
|
|
414
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(3));
|
|
415
|
-
expect(onData).toHaveBeenLastCalledWith(400);
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
it("should handle set then dependency change", async () => {
|
|
419
|
-
const $state = state(1);
|
|
420
|
-
const $writableDerivation = writableDerivation((t) => $state.get(t) * 2);
|
|
421
|
-
const onData = vi.fn();
|
|
422
|
-
|
|
423
|
-
subscribe(
|
|
424
|
-
(t) => $writableDerivation.get(t),
|
|
425
|
-
(data) => onData(data),
|
|
426
|
-
);
|
|
427
|
-
|
|
428
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
429
|
-
expect(onData).toHaveBeenLastCalledWith(2);
|
|
430
|
-
|
|
431
|
-
$writableDerivation.set(500);
|
|
432
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
433
|
-
expect(onData).toHaveBeenLastCalledWith(500);
|
|
434
|
-
|
|
435
|
-
$state.set(10);
|
|
436
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(3));
|
|
437
|
-
expect(onData).toHaveBeenLastCalledWith(20);
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
it("should handle set then dependency change then refresh", async () => {
|
|
441
|
-
const $state = state(1);
|
|
442
|
-
const $writableDerivation = writableDerivation((t) => $state.get(t) * 2);
|
|
443
|
-
const onData = vi.fn();
|
|
444
|
-
|
|
445
|
-
subscribe(
|
|
446
|
-
(t) => $writableDerivation.get(t),
|
|
447
|
-
(data) => onData(data),
|
|
448
|
-
);
|
|
449
|
-
|
|
450
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
451
|
-
expect(onData).toHaveBeenLastCalledWith(2);
|
|
452
|
-
|
|
453
|
-
$writableDerivation.set(600);
|
|
454
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
455
|
-
expect(onData).toHaveBeenLastCalledWith(600);
|
|
456
|
-
|
|
457
|
-
$state.set(20);
|
|
458
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(3));
|
|
459
|
-
expect(onData).toHaveBeenLastCalledWith(40);
|
|
460
|
-
|
|
461
|
-
$writableDerivation.refresh();
|
|
462
|
-
// Refresh may not trigger notification if value is same
|
|
463
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
464
|
-
// Value should still be 40 after refresh
|
|
465
|
-
expect(await $writableDerivation.pick()).toBe(40);
|
|
466
|
-
});
|
|
467
|
-
});
|
|
468
|
-
|
|
469
|
-
describe("nested writable derivations", () => {
|
|
470
|
-
it("should work with writableDerivation depending on another writableDerivation", async () => {
|
|
471
|
-
const $state = state(1);
|
|
472
|
-
const $writableDerivation1 = writableDerivation((t) => $state.get(t) * 2);
|
|
473
|
-
const $writableDerivation2 = writableDerivation((t) => $writableDerivation1.get(t) * 2);
|
|
474
|
-
const onData = vi.fn();
|
|
475
|
-
|
|
476
|
-
subscribe((t) => $writableDerivation2.get(t), onData);
|
|
477
|
-
|
|
478
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
479
|
-
expect(onData).toHaveBeenLastCalledWith(4);
|
|
480
|
-
|
|
481
|
-
$writableDerivation1.set(10);
|
|
482
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
483
|
-
expect(onData).toHaveBeenLastCalledWith(20);
|
|
484
|
-
});
|
|
485
|
-
|
|
486
|
-
it("should work with set on parent writableDerivation", async () => {
|
|
487
|
-
const $state = state(1);
|
|
488
|
-
const $writableDerivation1 = writableDerivation((t) => $state.get(t) * 2);
|
|
489
|
-
const $writableDerivation2 = writableDerivation((t) => $writableDerivation1.get(t) * 2);
|
|
490
|
-
const onData = vi.fn();
|
|
491
|
-
|
|
492
|
-
subscribe((t) => $writableDerivation2.get(t), onData);
|
|
493
|
-
|
|
494
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
495
|
-
expect(onData).toHaveBeenLastCalledWith(4);
|
|
496
|
-
|
|
497
|
-
$writableDerivation1.set(50);
|
|
498
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
499
|
-
expect(onData).toHaveBeenLastCalledWith(100);
|
|
500
|
-
});
|
|
501
|
-
|
|
502
|
-
it("should work with set on child writableDerivation", async () => {
|
|
503
|
-
const $state = state(1);
|
|
504
|
-
const $writableDerivation1 = writableDerivation((t) => $state.get(t) * 2);
|
|
505
|
-
const $writableDerivation2 = writableDerivation((t) => $writableDerivation1.get(t) * 2);
|
|
506
|
-
const onData1 = vi.fn();
|
|
507
|
-
const onData2 = vi.fn();
|
|
508
|
-
|
|
509
|
-
subscribe((t) => $writableDerivation1.get(t), onData1);
|
|
510
|
-
subscribe((t) => $writableDerivation2.get(t), onData2);
|
|
511
|
-
|
|
512
|
-
await vi.waitFor(() => {
|
|
513
|
-
expect(onData1).toHaveBeenCalledTimes(1);
|
|
514
|
-
expect(onData2).toHaveBeenCalledTimes(1);
|
|
515
|
-
});
|
|
516
|
-
expect(onData1).toHaveBeenLastCalledWith(2);
|
|
517
|
-
expect(onData2).toHaveBeenLastCalledWith(4);
|
|
518
|
-
|
|
519
|
-
$writableDerivation2.set(999);
|
|
520
|
-
await vi.waitFor(() => {
|
|
521
|
-
expect(onData1).toHaveBeenCalledTimes(1);
|
|
522
|
-
expect(onData2).toHaveBeenCalledTimes(2);
|
|
523
|
-
});
|
|
524
|
-
expect(onData2).toHaveBeenLastCalledWith(999);
|
|
525
|
-
});
|
|
526
|
-
});
|
|
527
|
-
|
|
528
|
-
describe("complex patterns with set", () => {
|
|
529
|
-
it("should handle diamond pattern with writableDerivations and set", async () => {
|
|
530
|
-
const $stateA = state(1);
|
|
531
|
-
const $aMult3 = writableDerivation((t) => $stateA.get(t) * 3);
|
|
532
|
-
const $aMult2 = writableDerivation((t) => $stateA.get(t) * 2);
|
|
533
|
-
const $addAmult3Amult2 = writableDerivation((t) => $aMult3.get(t) + $aMult2.get(t));
|
|
534
|
-
const onData = vi.fn();
|
|
535
|
-
|
|
536
|
-
subscribe((t) => $addAmult3Amult2.get(t), onData);
|
|
537
|
-
|
|
538
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
539
|
-
expect(onData).toHaveBeenLastCalledWith(5);
|
|
540
|
-
|
|
541
|
-
$aMult3.set(100);
|
|
542
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
543
|
-
expect(onData).toHaveBeenLastCalledWith(102);
|
|
544
|
-
});
|
|
545
|
-
|
|
546
|
-
it("should handle writableDerivation with conditional dependencies and set", async () => {
|
|
547
|
-
const $state1 = state(1);
|
|
548
|
-
const $state2 = state(10);
|
|
549
|
-
const $cond = state(true);
|
|
550
|
-
const $writableDerivation = writableDerivation((t) => {
|
|
551
|
-
if ($cond.get(t)) {
|
|
552
|
-
return $state1.get(t) * 2;
|
|
553
|
-
}
|
|
554
|
-
return $state2.get(t) * 2;
|
|
555
|
-
});
|
|
556
|
-
const onData = vi.fn();
|
|
557
|
-
|
|
558
|
-
subscribe((t) => $writableDerivation.get(t), onData);
|
|
559
|
-
|
|
560
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
561
|
-
expect(onData).toHaveBeenLastCalledWith(2);
|
|
562
|
-
|
|
563
|
-
$writableDerivation.set(777);
|
|
564
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
565
|
-
expect(onData).toHaveBeenLastCalledWith(777);
|
|
566
|
-
|
|
567
|
-
$cond.set(false);
|
|
568
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(3));
|
|
569
|
-
expect(onData).toHaveBeenLastCalledWith(20);
|
|
570
|
-
});
|
|
571
|
-
|
|
572
|
-
it("should handle set on writableDerivation in complex pattern", async () => {
|
|
573
|
-
const $stateA = state(1);
|
|
574
|
-
const $stateB = state(2);
|
|
575
|
-
const $addAB = writableDerivation((t) => {
|
|
576
|
-
const a = $stateA.get(t);
|
|
577
|
-
const b = $stateB.get(t);
|
|
578
|
-
return a + b;
|
|
579
|
-
});
|
|
580
|
-
const $multiplyAB = writableDerivation((t) => {
|
|
581
|
-
const a = $stateA.get(t);
|
|
582
|
-
const b = $stateB.get(t);
|
|
583
|
-
return a * b;
|
|
584
|
-
});
|
|
585
|
-
const $addAndMultiply = writableDerivation((t) => {
|
|
586
|
-
const add = $addAB.get(t);
|
|
587
|
-
const multiply = $multiplyAB.get(t);
|
|
588
|
-
return add * multiply;
|
|
589
|
-
});
|
|
590
|
-
const onData = vi.fn();
|
|
591
|
-
|
|
592
|
-
subscribe((t) => $addAndMultiply.get(t), onData);
|
|
593
|
-
|
|
594
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(1));
|
|
595
|
-
expect(onData).toHaveBeenLastCalledWith(6);
|
|
596
|
-
|
|
597
|
-
$addAB.set(100);
|
|
598
|
-
await vi.waitFor(() => expect(onData).toHaveBeenCalledTimes(2));
|
|
599
|
-
expect(onData).toHaveBeenLastCalledWith(200);
|
|
600
|
-
});
|
|
601
|
-
});
|
|
602
|
-
});
|
|
603
|
-
});
|
package/test/vitest.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// biome-ignore lint/correctness/noUnusedImports: we need to extend the ExpectStatic interface to override the element matcher
|
|
2
|
-
import type { ExpectStatic } from "vitest";
|
|
3
|
-
|
|
4
|
-
declare module "vitest" {
|
|
5
|
-
interface ExpectStatic {
|
|
6
|
-
element(element: Element | null): {
|
|
7
|
-
toBeInTheDocument(): Promise<void>;
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"rootDir": ".",
|
|
4
|
-
"target": "ESNext",
|
|
5
|
-
|
|
6
|
-
"module": "ESNext",
|
|
7
|
-
"moduleResolution": "Bundler",
|
|
8
|
-
"skipLibCheck": true,
|
|
9
|
-
|
|
10
|
-
"declaration": true,
|
|
11
|
-
"declarationMap": true,
|
|
12
|
-
"outDir": "dist/types",
|
|
13
|
-
|
|
14
|
-
"isolatedModules": true,
|
|
15
|
-
"allowSyntheticDefaultImports": true,
|
|
16
|
-
"esModuleInterop": true,
|
|
17
|
-
|
|
18
|
-
"jsx": "preserve",
|
|
19
|
-
"jsxImportSource": "solid-js",
|
|
20
|
-
|
|
21
|
-
"strict": true,
|
|
22
|
-
"verbatimModuleSyntax": true,
|
|
23
|
-
"noUnusedLocals": true,
|
|
24
|
-
"noUnusedParameters": true,
|
|
25
|
-
"noFallthroughCasesInSwitch": true,
|
|
26
|
-
"noImplicitOverride": true,
|
|
27
|
-
"noImplicitReturns": true,
|
|
28
|
-
|
|
29
|
-
// "stripInternal": true,
|
|
30
|
-
|
|
31
|
-
"paths": {
|
|
32
|
-
"~": ["./src"],
|
|
33
|
-
"~/*": ["./src/*"]
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
"include": ["./src/**/*", "./test/**/*"]
|
|
37
|
-
}
|
package/typedoc.json
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://typedoc.org/schema.json",
|
|
3
|
-
"entryPoints": ["src/index.ts"],
|
|
4
|
-
"entryPointStrategy": "resolve",
|
|
5
|
-
"out": "docs/api",
|
|
6
|
-
"docsRoot": "docs",
|
|
7
|
-
"plugin": ["typedoc-plugin-markdown", "typedoc-vitepress-theme"],
|
|
8
|
-
"readme": "none",
|
|
9
|
-
"hideGenerator": true,
|
|
10
|
-
"cleanOutputDir": true,
|
|
11
|
-
"excludePrivate": true,
|
|
12
|
-
"excludeProtected": true,
|
|
13
|
-
"excludeExternals": true,
|
|
14
|
-
"excludeInternal": true,
|
|
15
|
-
"entryFileName": "index.md",
|
|
16
|
-
"hidePageHeader": true,
|
|
17
|
-
"hideBreadcrumbs": false,
|
|
18
|
-
"useCodeBlocks": true,
|
|
19
|
-
"expandObjects": true,
|
|
20
|
-
"parametersFormat": "table",
|
|
21
|
-
"propertiesFormat": "table",
|
|
22
|
-
"enumMembersFormat": "table",
|
|
23
|
-
"typeDeclarationFormat": "table",
|
|
24
|
-
"indexFormat": "table",
|
|
25
|
-
"outputFileStrategy": "members",
|
|
26
|
-
"flattenOutputFiles": false,
|
|
27
|
-
"fileExtension": ".md",
|
|
28
|
-
"publicPath": "/api/",
|
|
29
|
-
"textContentMappings": {
|
|
30
|
-
"header.title": "API Reference"
|
|
31
|
-
},
|
|
32
|
-
"externalSymbolLinkMappings": {
|
|
33
|
-
"@ersbeth/picoflow": {
|
|
34
|
-
"FlowObservable._getRaw": "#"
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|