@ersbeth/picoflow 1.0.1 → 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.
Files changed (180) hide show
  1. package/.cursor/plans/unifier-flowresource-avec-flowderivation-c9506e24.plan.md +372 -0
  2. package/README.md +17 -1
  3. package/biome.json +4 -1
  4. package/dist/picoflow.js +1129 -661
  5. package/dist/types/flow/base/flowDisposable.d.ts +67 -0
  6. package/dist/types/flow/base/flowDisposable.d.ts.map +1 -0
  7. package/dist/types/flow/base/flowEffect.d.ts +127 -0
  8. package/dist/types/flow/base/flowEffect.d.ts.map +1 -0
  9. package/dist/types/flow/base/flowGraph.d.ts +97 -0
  10. package/dist/types/flow/base/flowGraph.d.ts.map +1 -0
  11. package/dist/types/flow/base/flowSignal.d.ts +134 -0
  12. package/dist/types/flow/base/flowSignal.d.ts.map +1 -0
  13. package/dist/types/flow/base/flowTracker.d.ts +15 -0
  14. package/dist/types/flow/base/flowTracker.d.ts.map +1 -0
  15. package/dist/types/flow/base/index.d.ts +7 -0
  16. package/dist/types/flow/base/index.d.ts.map +1 -0
  17. package/dist/types/flow/base/utils.d.ts +20 -0
  18. package/dist/types/flow/base/utils.d.ts.map +1 -0
  19. package/dist/types/{advanced/array.d.ts → flow/collections/flowArray.d.ts} +50 -12
  20. package/dist/types/flow/collections/flowArray.d.ts.map +1 -0
  21. package/dist/types/flow/collections/flowMap.d.ts +224 -0
  22. package/dist/types/flow/collections/flowMap.d.ts.map +1 -0
  23. package/dist/types/flow/collections/index.d.ts +3 -0
  24. package/dist/types/flow/collections/index.d.ts.map +1 -0
  25. package/dist/types/flow/index.d.ts +4 -0
  26. package/dist/types/flow/index.d.ts.map +1 -0
  27. package/dist/types/flow/nodes/async/flowConstantAsync.d.ts +137 -0
  28. package/dist/types/flow/nodes/async/flowConstantAsync.d.ts.map +1 -0
  29. package/dist/types/flow/nodes/async/flowDerivationAsync.d.ts +137 -0
  30. package/dist/types/flow/nodes/async/flowDerivationAsync.d.ts.map +1 -0
  31. package/dist/types/flow/nodes/async/flowNodeAsync.d.ts +343 -0
  32. package/dist/types/flow/nodes/async/flowNodeAsync.d.ts.map +1 -0
  33. package/dist/types/flow/nodes/async/flowReadonlyAsync.d.ts +81 -0
  34. package/dist/types/flow/nodes/async/flowReadonlyAsync.d.ts.map +1 -0
  35. package/dist/types/flow/nodes/async/flowStateAsync.d.ts +111 -0
  36. package/dist/types/flow/nodes/async/flowStateAsync.d.ts.map +1 -0
  37. package/dist/types/flow/nodes/async/index.d.ts +6 -0
  38. package/dist/types/flow/nodes/async/index.d.ts.map +1 -0
  39. package/dist/types/flow/nodes/index.d.ts +3 -0
  40. package/dist/types/flow/nodes/index.d.ts.map +1 -0
  41. package/dist/types/flow/nodes/sync/flowConstant.d.ts +108 -0
  42. package/dist/types/flow/nodes/sync/flowConstant.d.ts.map +1 -0
  43. package/dist/types/flow/nodes/sync/flowDerivation.d.ts +100 -0
  44. package/dist/types/flow/nodes/sync/flowDerivation.d.ts.map +1 -0
  45. package/dist/types/flow/nodes/sync/flowNode.d.ts +314 -0
  46. package/dist/types/flow/nodes/sync/flowNode.d.ts.map +1 -0
  47. package/dist/types/flow/nodes/sync/flowReadonly.d.ts +57 -0
  48. package/dist/types/flow/nodes/sync/flowReadonly.d.ts.map +1 -0
  49. package/dist/types/flow/nodes/sync/flowState.d.ts +96 -0
  50. package/dist/types/flow/nodes/sync/flowState.d.ts.map +1 -0
  51. package/dist/types/flow/nodes/sync/index.d.ts +6 -0
  52. package/dist/types/flow/nodes/sync/index.d.ts.map +1 -0
  53. package/dist/types/index.d.ts +1 -4
  54. package/dist/types/index.d.ts.map +1 -1
  55. package/dist/types/solid/converters.d.ts +34 -44
  56. package/dist/types/solid/converters.d.ts.map +1 -1
  57. package/dist/types/solid/primitives.d.ts +1 -0
  58. package/dist/types/solid/primitives.d.ts.map +1 -1
  59. package/docs/.vitepress/config.mts +1 -1
  60. package/docs/api/typedoc-sidebar.json +81 -1
  61. package/package.json +60 -58
  62. package/src/flow/base/flowDisposable.ts +71 -0
  63. package/src/flow/base/flowEffect.ts +171 -0
  64. package/src/flow/base/flowGraph.ts +288 -0
  65. package/src/flow/base/flowSignal.ts +207 -0
  66. package/src/flow/base/flowTracker.ts +17 -0
  67. package/src/flow/base/index.ts +6 -0
  68. package/src/flow/base/utils.ts +19 -0
  69. package/src/flow/collections/flowArray.ts +409 -0
  70. package/src/flow/collections/flowMap.ts +398 -0
  71. package/src/flow/collections/index.ts +2 -0
  72. package/src/flow/index.ts +3 -0
  73. package/src/flow/nodes/async/flowConstantAsync.ts +142 -0
  74. package/src/flow/nodes/async/flowDerivationAsync.ts +143 -0
  75. package/src/flow/nodes/async/flowNodeAsync.ts +474 -0
  76. package/src/flow/nodes/async/flowReadonlyAsync.ts +81 -0
  77. package/src/flow/nodes/async/flowStateAsync.ts +116 -0
  78. package/src/flow/nodes/async/index.ts +5 -0
  79. package/src/flow/nodes/await/advanced/index.ts +5 -0
  80. package/src/{advanced → flow/nodes/await/advanced}/resource.ts +37 -3
  81. package/src/{advanced → flow/nodes/await/advanced}/resourceAsync.ts +35 -3
  82. package/src/{advanced → flow/nodes/await/advanced}/stream.ts +40 -2
  83. package/src/{advanced → flow/nodes/await/advanced}/streamAsync.ts +38 -3
  84. package/src/flow/nodes/await/flowConstantAwait.ts +154 -0
  85. package/src/flow/nodes/await/flowDerivationAwait.ts +154 -0
  86. package/src/flow/nodes/await/flowNodeAwait.ts +508 -0
  87. package/src/flow/nodes/await/flowReadonlyAwait.ts +89 -0
  88. package/src/flow/nodes/await/flowStateAwait.ts +130 -0
  89. package/src/flow/nodes/await/index.ts +5 -0
  90. package/src/flow/nodes/index.ts +3 -0
  91. package/src/flow/nodes/sync/flowConstant.ts +111 -0
  92. package/src/flow/nodes/sync/flowDerivation.ts +105 -0
  93. package/src/flow/nodes/sync/flowNode.ts +439 -0
  94. package/src/flow/nodes/sync/flowReadonly.ts +57 -0
  95. package/src/flow/nodes/sync/flowState.ts +101 -0
  96. package/src/flow/nodes/sync/index.ts +5 -0
  97. package/src/index.ts +1 -47
  98. package/src/solid/converters.ts +59 -198
  99. package/src/solid/primitives.ts +4 -0
  100. package/test/base/flowEffect.test.ts +108 -0
  101. package/test/base/flowGraph.test.ts +485 -0
  102. package/test/base/flowSignal.test.ts +372 -0
  103. package/test/collections/flowArray.asyncStates.test.ts +1553 -0
  104. package/test/collections/flowArray.scalars.test.ts +1129 -0
  105. package/test/collections/flowArray.states.test.ts +1365 -0
  106. package/test/collections/flowMap.asyncStates.test.ts +1105 -0
  107. package/test/collections/flowMap.scalars.test.ts +877 -0
  108. package/test/collections/flowMap.states.test.ts +1097 -0
  109. package/test/nodes/async/flowConstantAsync.test.ts +860 -0
  110. package/test/nodes/async/flowDerivationAsync.test.ts +1517 -0
  111. package/test/nodes/async/flowStateAsync.test.ts +1387 -0
  112. package/test/{resource.test.ts → nodes/await/advanced/resource.test.ts} +21 -19
  113. package/test/{resourceAsync.test.ts → nodes/await/advanced/resourceAsync.test.ts} +3 -1
  114. package/test/{stream.test.ts → nodes/await/advanced/stream.test.ts} +30 -28
  115. package/test/{streamAsync.test.ts → nodes/await/advanced/streamAsync.test.ts} +16 -14
  116. package/test/nodes/await/flowConstantAwait.test.ts +643 -0
  117. package/test/nodes/await/flowDerivationAwait.test.ts +1583 -0
  118. package/test/nodes/await/flowStateAwait.test.ts +999 -0
  119. package/test/nodes/mixed/derivation.test.ts +1527 -0
  120. package/test/nodes/sync/flowConstant.test.ts +620 -0
  121. package/test/nodes/sync/flowDerivation.test.ts +1373 -0
  122. package/test/nodes/sync/flowState.test.ts +945 -0
  123. package/test/solid/converters.test.ts +721 -0
  124. package/test/solid/primitives.test.ts +1031 -0
  125. package/tsconfig.json +2 -1
  126. package/vitest.config.ts +7 -1
  127. package/IMPLEMENTATION_GUIDE.md +0 -1578
  128. package/dist/types/advanced/array.d.ts.map +0 -1
  129. package/dist/types/advanced/index.d.ts +0 -9
  130. package/dist/types/advanced/index.d.ts.map +0 -1
  131. package/dist/types/advanced/map.d.ts +0 -166
  132. package/dist/types/advanced/map.d.ts.map +0 -1
  133. package/dist/types/advanced/resource.d.ts +0 -78
  134. package/dist/types/advanced/resource.d.ts.map +0 -1
  135. package/dist/types/advanced/resourceAsync.d.ts +0 -56
  136. package/dist/types/advanced/resourceAsync.d.ts.map +0 -1
  137. package/dist/types/advanced/stream.d.ts +0 -117
  138. package/dist/types/advanced/stream.d.ts.map +0 -1
  139. package/dist/types/advanced/streamAsync.d.ts +0 -97
  140. package/dist/types/advanced/streamAsync.d.ts.map +0 -1
  141. package/dist/types/basic/constant.d.ts +0 -60
  142. package/dist/types/basic/constant.d.ts.map +0 -1
  143. package/dist/types/basic/derivation.d.ts +0 -89
  144. package/dist/types/basic/derivation.d.ts.map +0 -1
  145. package/dist/types/basic/disposable.d.ts +0 -82
  146. package/dist/types/basic/disposable.d.ts.map +0 -1
  147. package/dist/types/basic/effect.d.ts +0 -67
  148. package/dist/types/basic/effect.d.ts.map +0 -1
  149. package/dist/types/basic/index.d.ts +0 -10
  150. package/dist/types/basic/index.d.ts.map +0 -1
  151. package/dist/types/basic/observable.d.ts +0 -83
  152. package/dist/types/basic/observable.d.ts.map +0 -1
  153. package/dist/types/basic/signal.d.ts +0 -69
  154. package/dist/types/basic/signal.d.ts.map +0 -1
  155. package/dist/types/basic/state.d.ts +0 -47
  156. package/dist/types/basic/state.d.ts.map +0 -1
  157. package/dist/types/basic/trackingContext.d.ts +0 -33
  158. package/dist/types/basic/trackingContext.d.ts.map +0 -1
  159. package/dist/types/creators.d.ts +0 -340
  160. package/dist/types/creators.d.ts.map +0 -1
  161. package/src/advanced/array.ts +0 -222
  162. package/src/advanced/index.ts +0 -12
  163. package/src/advanced/map.ts +0 -193
  164. package/src/basic/constant.ts +0 -97
  165. package/src/basic/derivation.ts +0 -147
  166. package/src/basic/disposable.ts +0 -86
  167. package/src/basic/effect.ts +0 -104
  168. package/src/basic/index.ts +0 -9
  169. package/src/basic/observable.ts +0 -109
  170. package/src/basic/signal.ts +0 -145
  171. package/src/basic/state.ts +0 -60
  172. package/src/basic/trackingContext.ts +0 -45
  173. package/src/creators.ts +0 -395
  174. package/test/array.test.ts +0 -600
  175. package/test/constant.test.ts +0 -44
  176. package/test/derivation.test.ts +0 -539
  177. package/test/effect.test.ts +0 -29
  178. package/test/map.test.ts +0 -240
  179. package/test/signal.test.ts +0 -72
  180. package/test/state.test.ts +0 -212
@@ -1,600 +0,0 @@
1
- import { describe, expect, test, vi } from "vitest";
2
- import { array, effect, type FlowState, state } from "#package";
3
-
4
- describe("array", () => {
5
- test("is initialized", () => {
6
- const $array = array([state(1), state(2), state(3)]);
7
-
8
- expect($array.pick().map((state) => state.pick())).toEqual([1, 2, 3]);
9
- });
10
-
11
- test("is updated (set)", () => {
12
- const $array = array<FlowState<number>>([state(0), state(1), state(2)]);
13
- expect($array.pick().map((state) => state.pick())).toEqual([0, 1, 2]);
14
-
15
- $array.set([state(1), state(2), state(3)]);
16
- expect($array.pick().map((state) => state.pick())).toEqual([1, 2, 3]);
17
- });
18
-
19
- test("is updated (setItem)", () => {
20
- const $array = array<FlowState<number>>([state(0), state(1), state(2)]);
21
- expect($array.pick().map((state) => state.pick())).toEqual([0, 1, 2]);
22
-
23
- $array.setItem(0, state(1));
24
- expect($array.pick().map((state) => state.pick())).toEqual([1, 1, 2]);
25
-
26
- $array.setItem(1, state(2));
27
- expect($array.pick().map((state) => state.pick())).toEqual([1, 2, 2]);
28
-
29
- $array.setItem(2, state(3));
30
- expect($array.pick().map((state) => state.pick())).toEqual([1, 2, 3]);
31
- });
32
-
33
- test("is updated (push/pop)", () => {
34
- const $array = array<FlowState<number>>();
35
- expect($array.pick()).toEqual([]);
36
-
37
- $array.push(state(0));
38
- expect($array.pick().map((state) => state.pick())).toEqual([0]);
39
-
40
- $array.push(state(1));
41
- expect($array.pick().map((state) => state.pick())).toEqual([0, 1]);
42
-
43
- $array.push(state(2));
44
- expect($array.pick().map((state) => state.pick())).toEqual([0, 1, 2]);
45
-
46
- $array.pop();
47
- expect($array.pick().map((state) => state.pick())).toEqual([0, 1]);
48
-
49
- $array.pop();
50
- expect($array.pick().map((state) => state.pick())).toEqual([0]);
51
-
52
- $array.pop();
53
- expect($array.pick().map((state) => state.pick())).toEqual([]);
54
- });
55
-
56
- test("is updated (unshift/shift)", () => {
57
- const $array = array<FlowState<number>>();
58
- expect($array.pick()).toEqual([]);
59
-
60
- $array.unshift(state(0));
61
- expect($array.pick().map((state) => state.pick())).toEqual([0]);
62
-
63
- $array.unshift(state(1));
64
- expect($array.pick().map((state) => state.pick())).toEqual([1, 0]);
65
-
66
- $array.unshift(state(2));
67
- expect($array.pick().map((state) => state.pick())).toEqual([2, 1, 0]);
68
-
69
- $array.shift();
70
- expect($array.pick().map((state) => state.pick())).toEqual([1, 0]);
71
-
72
- $array.shift();
73
- expect($array.pick().map((state) => state.pick())).toEqual([0]);
74
-
75
- $array.shift();
76
- expect($array.pick().map((state) => state.pick())).toEqual([]);
77
- });
78
-
79
- test("is updated (splice)", () => {
80
- const $array = array<FlowState<number>>([
81
- state(0),
82
- state(1),
83
- state(2),
84
- state(3),
85
- state(4),
86
- ]);
87
- expect($array.pick().map((state) => state.pick())).toEqual([0, 1, 2, 3, 4]);
88
-
89
- $array.splice(1, 2);
90
- expect($array.pick().map((state) => state.pick())).toEqual([0, 3, 4]);
91
-
92
- $array.splice(1, 0, state(1), state(2));
93
- expect($array.pick().map((state) => state.pick())).toEqual([0, 1, 2, 3, 4]);
94
- });
95
-
96
- test("is updated (clear)", () => {
97
- const $array = array<FlowState<number>>([
98
- state(0),
99
- state(1),
100
- state(2),
101
- state(3),
102
- state(4),
103
- ]);
104
- expect($array.pick().map((state) => state.pick())).toEqual([0, 1, 2, 3, 4]);
105
-
106
- $array.clear();
107
- expect($array.pick().map((state) => state.pick())).toEqual([]);
108
- });
109
-
110
- test("is item updated", () => {
111
- const $array = array<FlowState<number>>([
112
- state(0),
113
- state(1),
114
- state(2),
115
- state(3),
116
- state(4),
117
- ]);
118
- expect($array.pick().map((state) => state.pick())).toEqual([0, 1, 2, 3, 4]);
119
-
120
- $array.pick()[0].set(1);
121
- expect($array.pick().map((state) => state.pick())).toEqual([1, 1, 2, 3, 4]);
122
-
123
- $array.pick()[1].set(2);
124
- expect($array.pick().map((state) => state.pick())).toEqual([1, 2, 2, 3, 4]);
125
-
126
- $array.pick()[2].set(3);
127
- expect($array.pick().map((state) => state.pick())).toEqual([1, 2, 3, 3, 4]);
128
-
129
- $array.pick()[3].set(4);
130
- expect($array.pick().map((state) => state.pick())).toEqual([1, 2, 3, 4, 4]);
131
-
132
- $array.pick()[4].set(5);
133
- expect($array.pick().map((state) => state.pick())).toEqual([1, 2, 3, 4, 5]);
134
- });
135
-
136
- test("throws when disposed (get)", () => {
137
- const $array = array([state(1), state(2), state(3)]);
138
- $array.dispose();
139
- expect(() => $array.pick()).toThrowError(
140
- "[PicoFlow] Primitive is disposed",
141
- );
142
- });
143
-
144
- test("throws when disposed (set)", () => {
145
- const $array = array([state(1), state(2), state(3)]);
146
- $array.dispose();
147
- expect(() => $array.set([state(1)])).toThrowError(
148
- "[PicoFlow] Primitive is disposed",
149
- );
150
- });
151
-
152
- test("throws when disposed (setItem)", () => {
153
- const $array = array([state(1), state(2), state(3)]);
154
- $array.dispose();
155
- expect(() => $array.setItem(0, state(3))).toThrowError(
156
- "[PicoFlow] Primitive is disposed",
157
- );
158
- });
159
-
160
- test("throws when disposed (push)", () => {
161
- const $array = array([state(1), state(2), state(3)]);
162
- $array.dispose();
163
- expect(() => $array.push(state(3))).toThrowError(
164
- "[PicoFlow] Primitive is disposed",
165
- );
166
- });
167
-
168
- test("throws when disposed (pop)", () => {
169
- const $array = array([state(1), state(2), state(3)]);
170
- $array.dispose();
171
- expect(() => $array.pop()).toThrowError("[PicoFlow] Primitive is disposed");
172
- });
173
-
174
- test("throws when disposed (unshift)", () => {
175
- const $array = array([state(1), state(2), state(3)]);
176
- $array.dispose();
177
- expect(() => $array.unshift(state(3))).toThrowError(
178
- "[PicoFlow] Primitive is disposed",
179
- );
180
- });
181
-
182
- test("throws when disposed (shift)", () => {
183
- const $array = array([state(1), state(2), state(3)]);
184
- $array.dispose();
185
- expect(() => $array.shift()).toThrowError(
186
- "[PicoFlow] Primitive is disposed",
187
- );
188
- });
189
-
190
- test("throws when disposed (splice)", () => {
191
- const $array = array<FlowState<number>>([
192
- state(0),
193
- state(1),
194
- state(2),
195
- state(3),
196
- state(4),
197
- ]);
198
- $array.dispose();
199
- expect(() => $array.splice(1, 2)).toThrowError(
200
- "[PicoFlow] Primitive is disposed",
201
- );
202
- });
203
- });
204
-
205
- describe("effect", () => {
206
- test("called when initialized", () => {
207
- const $array = array([state(1), state(2), state(3)]);
208
- const effectFn = vi.fn();
209
- effect((t) => effectFn($array.get(t).map((state) => state.get(t))));
210
-
211
- expect(effectFn).toHaveBeenCalledTimes(1);
212
- expect(effectFn).toHaveBeenLastCalledWith([1, 2, 3]);
213
- });
214
-
215
- test("called when updated (set)", () => {
216
- const $array = array<FlowState<number>>([state(0), state(1), state(2)]);
217
- const effectFn = vi.fn();
218
- effect((t) => effectFn($array.get(t).map((state) => state.get(t))));
219
-
220
- expect(effectFn).toHaveBeenCalledTimes(1);
221
- expect(effectFn).toHaveBeenLastCalledWith([0, 1, 2]);
222
-
223
- $array.set([state(1), state(2), state(3)]);
224
- expect(effectFn).toHaveBeenLastCalledWith([1, 2, 3]);
225
- });
226
-
227
- test("called when updated (push/pop)", () => {
228
- const $array = array<FlowState<number>>();
229
- const effectFn = vi.fn();
230
- effect((t) => effectFn($array.get(t).map((state) => state.get(t))));
231
-
232
- expect(effectFn).toHaveBeenCalledTimes(1);
233
- expect(effectFn).toHaveBeenLastCalledWith([]);
234
-
235
- $array.push(state(0));
236
- expect(effectFn).toHaveBeenCalledTimes(2);
237
- expect(effectFn).toHaveBeenLastCalledWith([0]);
238
-
239
- $array.push(state(1));
240
- expect(effectFn).toHaveBeenCalledTimes(3);
241
- expect(effectFn).toHaveBeenLastCalledWith([0, 1]);
242
-
243
- $array.push(state(2));
244
- expect(effectFn).toHaveBeenCalledTimes(4);
245
- expect(effectFn).toHaveBeenLastCalledWith([0, 1, 2]);
246
-
247
- $array.pop();
248
- expect(effectFn).toHaveBeenCalledTimes(5);
249
- expect(effectFn).toHaveBeenLastCalledWith([0, 1]);
250
-
251
- $array.pop();
252
- expect(effectFn).toHaveBeenCalledTimes(6);
253
- expect(effectFn).toHaveBeenLastCalledWith([0]);
254
-
255
- $array.pop();
256
- expect(effectFn).toHaveBeenCalledTimes(7);
257
- expect(effectFn).toHaveBeenLastCalledWith([]);
258
- });
259
-
260
- test("called when updated (unshift/shift)", () => {
261
- const $array = array<FlowState<number>>();
262
- const effectFn = vi.fn();
263
- effect((t) => effectFn($array.get(t).map((state) => state.get(t))));
264
-
265
- expect(effectFn).toHaveBeenCalledTimes(1);
266
- expect(effectFn).toHaveBeenLastCalledWith([]);
267
-
268
- $array.unshift(state(0));
269
- expect(effectFn).toHaveBeenCalledTimes(2);
270
- expect(effectFn).toHaveBeenLastCalledWith([0]);
271
-
272
- $array.unshift(state(1));
273
- expect(effectFn).toHaveBeenCalledTimes(3);
274
- expect(effectFn).toHaveBeenLastCalledWith([1, 0]);
275
-
276
- $array.unshift(state(2));
277
- expect(effectFn).toHaveBeenCalledTimes(4);
278
- expect(effectFn).toHaveBeenLastCalledWith([2, 1, 0]);
279
-
280
- $array.shift();
281
- expect(effectFn).toHaveBeenCalledTimes(5);
282
- expect(effectFn).toHaveBeenLastCalledWith([1, 0]);
283
-
284
- $array.shift();
285
- expect(effectFn).toHaveBeenCalledTimes(6);
286
- expect(effectFn).toHaveBeenLastCalledWith([0]);
287
-
288
- $array.shift();
289
- expect(effectFn).toHaveBeenCalledTimes(7);
290
- expect(effectFn).toHaveBeenLastCalledWith([]);
291
- });
292
-
293
- test("called when updated (splice)", () => {
294
- const $array = array<FlowState<number>>([
295
- state(0),
296
- state(1),
297
- state(2),
298
- state(3),
299
- state(4),
300
- ]);
301
- const effectFn = vi.fn();
302
- effect((t) => effectFn($array.get(t).map((state) => state.get(t))));
303
-
304
- expect(effectFn).toHaveBeenCalledTimes(1);
305
- expect(effectFn).toHaveBeenLastCalledWith([0, 1, 2, 3, 4]);
306
-
307
- $array.splice(1, 2);
308
- expect(effectFn).toHaveBeenCalledTimes(2);
309
- expect(effectFn).toHaveBeenLastCalledWith([0, 3, 4]);
310
-
311
- $array.splice(1, 0, state(1), state(2));
312
- expect(effectFn).toHaveBeenCalledTimes(3);
313
- expect(effectFn).toHaveBeenLastCalledWith([0, 1, 2, 3, 4]);
314
- });
315
-
316
- test("called when updated (clear)", () => {
317
- const $array = array<FlowState<number>>([
318
- state(0),
319
- state(1),
320
- state(2),
321
- state(3),
322
- state(4),
323
- ]);
324
- const effectFn = vi.fn();
325
- effect((t) => effectFn($array.get(t).map((state) => state.get(t))));
326
-
327
- expect(effectFn).toHaveBeenCalledTimes(1);
328
- expect(effectFn).toHaveBeenLastCalledWith([0, 1, 2, 3, 4]);
329
-
330
- $array.clear();
331
- expect(effectFn).toHaveBeenCalledTimes(2);
332
- expect(effectFn).toHaveBeenLastCalledWith([]);
333
- });
334
-
335
- test("called when item updated", () => {
336
- const $array = array<FlowState<number>>([state(0), state(1), state(2)]);
337
- const effectFn = vi.fn();
338
- const effect0Fn = vi.fn();
339
- const effect1Fn = vi.fn();
340
- const effect2Fn = vi.fn();
341
-
342
- effect((t) => effectFn($array.get(t).map((state) => state.get(t))));
343
- effect((t) => effect0Fn($array.get(t)[0].get(t)));
344
- effect((t) => effect1Fn($array.get(t)[1].get(t)));
345
- effect((t) => effect2Fn($array.get(t)[2].get(t)));
346
-
347
- expect(effectFn).toHaveBeenCalledTimes(1);
348
- expect(effectFn).toHaveBeenLastCalledWith([0, 1, 2]);
349
- expect(effect0Fn).toHaveBeenCalledTimes(1);
350
- expect(effect0Fn).toHaveBeenLastCalledWith(0);
351
- expect(effect1Fn).toHaveBeenCalledTimes(1);
352
- expect(effect1Fn).toHaveBeenLastCalledWith(1);
353
- expect(effect2Fn).toHaveBeenCalledTimes(1);
354
- expect(effect2Fn).toHaveBeenLastCalledWith(2);
355
-
356
- $array.pick()[0].set(1);
357
- expect(effectFn).toHaveBeenCalledTimes(2);
358
- expect(effectFn).toHaveBeenLastCalledWith([1, 1, 2]);
359
- expect(effect0Fn).toHaveBeenCalledTimes(2);
360
- expect(effect0Fn).toHaveBeenLastCalledWith(1);
361
- expect(effect1Fn).toHaveBeenCalledTimes(1);
362
- expect(effect1Fn).toHaveBeenLastCalledWith(1);
363
- expect(effect2Fn).toHaveBeenCalledTimes(1);
364
- expect(effect2Fn).toHaveBeenLastCalledWith(2);
365
-
366
- $array.pick()[1].set(2);
367
- expect(effectFn).toHaveBeenCalledTimes(3);
368
- expect(effectFn).toHaveBeenLastCalledWith([1, 2, 2]);
369
- expect(effect0Fn).toHaveBeenCalledTimes(2);
370
- expect(effect0Fn).toHaveBeenLastCalledWith(1);
371
- expect(effect1Fn).toHaveBeenCalledTimes(2);
372
- expect(effect1Fn).toHaveBeenLastCalledWith(2);
373
- expect(effect2Fn).toHaveBeenCalledTimes(1);
374
- expect(effect2Fn).toHaveBeenLastCalledWith(2);
375
-
376
- $array.pick()[2].set(3);
377
- expect(effectFn).toHaveBeenCalledTimes(4);
378
- expect(effectFn).toHaveBeenLastCalledWith([1, 2, 3]);
379
- expect(effect0Fn).toHaveBeenCalledTimes(2);
380
- expect(effect0Fn).toHaveBeenLastCalledWith(1);
381
- expect(effect1Fn).toHaveBeenCalledTimes(2);
382
- expect(effect1Fn).toHaveBeenLastCalledWith(2);
383
- expect(effect2Fn).toHaveBeenCalledTimes(2);
384
- expect(effect2Fn).toHaveBeenLastCalledWith(3);
385
- });
386
-
387
- test("called when item replaced", () => {
388
- const $array = array<FlowState<number>>([state(0), state(1), state(2)]);
389
- const effectFn = vi.fn();
390
- const effect0Fn = vi.fn();
391
-
392
- effect((t) => effectFn($array.get(t).map((state) => state.get(t))));
393
- effect((t) => effect0Fn($array.get(t)[0].get(t)));
394
-
395
- expect(effectFn).toHaveBeenCalledTimes(1);
396
- expect(effectFn).toHaveBeenLastCalledWith([0, 1, 2]);
397
- expect(effect0Fn).toHaveBeenCalledTimes(1);
398
- expect(effect0Fn).toHaveBeenLastCalledWith(0);
399
-
400
- $array.setItem(0, state(3));
401
- expect(effectFn).toHaveBeenCalledTimes(2);
402
- expect(effectFn).toHaveBeenLastCalledWith([3, 1, 2]);
403
- expect(effect0Fn).toHaveBeenCalledTimes(2);
404
- expect(effect0Fn).toHaveBeenLastCalledWith(3);
405
-
406
- $array.shift();
407
- expect(effectFn).toHaveBeenCalledTimes(3);
408
- expect(effectFn).toHaveBeenLastCalledWith([1, 2]);
409
- expect(effect0Fn).toHaveBeenCalledTimes(3);
410
- expect(effect0Fn).toHaveBeenLastCalledWith(1);
411
-
412
- $array.unshift(state(4));
413
- expect(effectFn).toHaveBeenCalledTimes(4);
414
- expect(effectFn).toHaveBeenLastCalledWith([4, 1, 2]);
415
- expect(effect0Fn).toHaveBeenCalledTimes(4);
416
- expect(effect0Fn).toHaveBeenLastCalledWith(4);
417
- });
418
-
419
- describe("lastAction", () => {
420
- test("called when initialized", () => {
421
- const $array = array([1, 2, 3]);
422
- const effectFn = vi.fn();
423
- effect((t) => effectFn($array.$lastAction.get(t)));
424
-
425
- expect(effectFn).toHaveBeenCalledTimes(1);
426
- expect(effectFn).toHaveBeenLastCalledWith({
427
- type: "set",
428
- items: [1, 2, 3],
429
- });
430
- });
431
-
432
- test("called when updated (set)", () => {
433
- const $array = array([0, 1, 2]);
434
- const effectFn = vi.fn();
435
- effect((t) => effectFn($array.$lastAction.get(t)));
436
-
437
- expect(effectFn).toHaveBeenCalledTimes(1);
438
- expect(effectFn).toHaveBeenLastCalledWith({
439
- type: "set",
440
- items: [0, 1, 2],
441
- });
442
- $array.set([1, 2, 3]);
443
- expect(effectFn).toHaveBeenCalledTimes(2);
444
- expect(effectFn).toHaveBeenLastCalledWith({
445
- type: "set",
446
- items: [1, 2, 3],
447
- });
448
- });
449
-
450
- test("called when updated (push/pop)", () => {
451
- const $array = array<number>();
452
- const effectFn = vi.fn();
453
- effect((t) => effectFn($array.$lastAction.get(t)));
454
-
455
- expect(effectFn).toHaveBeenCalledTimes(1);
456
- expect(effectFn).toHaveBeenLastCalledWith({
457
- type: "set",
458
- items: [],
459
- });
460
-
461
- $array.push(0);
462
- expect(effectFn).toHaveBeenCalledTimes(2);
463
- expect(effectFn).toHaveBeenLastCalledWith({
464
- type: "push",
465
- item: 0,
466
- });
467
-
468
- $array.push(1);
469
- expect(effectFn).toHaveBeenCalledTimes(3);
470
- expect(effectFn).toHaveBeenLastCalledWith({
471
- type: "push",
472
- item: 1,
473
- });
474
-
475
- $array.push(2);
476
- expect(effectFn).toHaveBeenCalledTimes(4);
477
- expect(effectFn).toHaveBeenLastCalledWith({
478
- type: "push",
479
- item: 2,
480
- });
481
-
482
- $array.pop();
483
- expect(effectFn).toHaveBeenCalledTimes(5);
484
- expect(effectFn).toHaveBeenLastCalledWith({
485
- type: "pop",
486
- });
487
-
488
- $array.pop();
489
- expect(effectFn).toHaveBeenCalledTimes(6);
490
- expect(effectFn).toHaveBeenLastCalledWith({
491
- type: "pop",
492
- });
493
-
494
- $array.pop();
495
- expect(effectFn).toHaveBeenCalledTimes(7);
496
- expect(effectFn).toHaveBeenLastCalledWith({
497
- type: "pop",
498
- });
499
- });
500
-
501
- test("called when updated (unshift/shift)", () => {
502
- const $array = array<number>();
503
- const effectFn = vi.fn();
504
- effect((t) => effectFn($array.$lastAction.get(t)));
505
-
506
- expect(effectFn).toHaveBeenCalledTimes(1);
507
- expect(effectFn).toHaveBeenLastCalledWith({
508
- type: "set",
509
- items: [],
510
- });
511
-
512
- $array.unshift(0);
513
- expect(effectFn).toHaveBeenCalledTimes(2);
514
- expect(effectFn).toHaveBeenLastCalledWith({
515
- type: "unshift",
516
- item: 0,
517
- });
518
-
519
- $array.unshift(1);
520
- expect(effectFn).toHaveBeenCalledTimes(3);
521
- expect(effectFn).toHaveBeenLastCalledWith({
522
- type: "unshift",
523
- item: 1,
524
- });
525
-
526
- $array.unshift(2);
527
- expect(effectFn).toHaveBeenCalledTimes(4);
528
- expect(effectFn).toHaveBeenLastCalledWith({
529
- type: "unshift",
530
- item: 2,
531
- });
532
-
533
- $array.shift();
534
- expect(effectFn).toHaveBeenCalledTimes(5);
535
- expect(effectFn).toHaveBeenLastCalledWith({
536
- type: "shift",
537
- });
538
-
539
- $array.shift();
540
- expect(effectFn).toHaveBeenCalledTimes(6);
541
- expect(effectFn).toHaveBeenLastCalledWith({
542
- type: "shift",
543
- });
544
-
545
- $array.shift();
546
- expect(effectFn).toHaveBeenCalledTimes(7);
547
- expect(effectFn).toHaveBeenLastCalledWith({
548
- type: "shift",
549
- });
550
- });
551
-
552
- test("called when updated (splice)", () => {
553
- const $array = array<number>([0, 1, 2, 3, 4]);
554
- const effectFn = vi.fn();
555
- effect((t) => effectFn($array.$lastAction.get(t)));
556
-
557
- expect(effectFn).toHaveBeenCalledTimes(1);
558
- expect(effectFn).toHaveBeenLastCalledWith({
559
- type: "set",
560
- items: [0, 1, 2, 3, 4],
561
- });
562
-
563
- $array.splice(1, 2);
564
- expect(effectFn).toHaveBeenCalledTimes(2);
565
- expect(effectFn).toHaveBeenLastCalledWith({
566
- type: "splice",
567
- start: 1,
568
- deleteCount: 2,
569
- items: [],
570
- });
571
-
572
- $array.splice(1, 0, 1, 2);
573
- expect(effectFn).toHaveBeenCalledTimes(3);
574
- expect(effectFn).toHaveBeenLastCalledWith({
575
- type: "splice",
576
- start: 1,
577
- deleteCount: 0,
578
- items: [1, 2],
579
- });
580
- });
581
-
582
- test("called when updated (clear)", () => {
583
- const $array = array<number>([0, 1, 2, 3, 4]);
584
- const effectFn = vi.fn();
585
- effect((t) => effectFn($array.$lastAction.get(t)));
586
-
587
- expect(effectFn).toHaveBeenCalledTimes(1);
588
- expect(effectFn).toHaveBeenLastCalledWith({
589
- type: "set",
590
- items: [0, 1, 2, 3, 4],
591
- });
592
-
593
- $array.clear();
594
- expect(effectFn).toHaveBeenCalledTimes(2);
595
- expect(effectFn).toHaveBeenLastCalledWith({
596
- type: "clear",
597
- });
598
- });
599
- });
600
- });
@@ -1,44 +0,0 @@
1
- import { describe, expect, test, vi } from "vitest";
2
- import { constant, effect } from "#package";
3
-
4
- describe("constant", () => {
5
- test("is initialized", () => {
6
- const $constant = constant(1);
7
- expect($constant.pick()).toBe(1);
8
- });
9
-
10
- test("is lazy initialized", () => {
11
- const $constant = constant(() => 1);
12
- expect($constant.pick()).toBe(1);
13
- });
14
-
15
- test("get throws when disposed", () => {
16
- const $constant = constant(1);
17
-
18
- expect($constant.pick()).toBe(1);
19
-
20
- $constant.dispose();
21
-
22
- expect(() => $constant.pick()).toThrow("[PicoFlow] Primitive is disposed");
23
- });
24
- });
25
-
26
- describe("effect", () => {
27
- test("called with init value", () => {
28
- const $constant = constant(1);
29
- const effectFn = vi.fn();
30
- effect((t) => effectFn($constant.get(t)));
31
-
32
- expect(effectFn).toHaveBeenCalledTimes(1);
33
- expect(effectFn).toHaveBeenLastCalledWith(1);
34
- });
35
-
36
- test("called with lazy init value", () => {
37
- const $constant = constant(() => 1);
38
- const effectFn = vi.fn();
39
- effect((t) => effectFn($constant.get(t)));
40
-
41
- expect(effectFn).toHaveBeenCalledTimes(1);
42
- expect(effectFn).toHaveBeenLastCalledWith(1);
43
- });
44
- });