@ersbeth/picoflow 2.0.2 → 2.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 (244) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +25 -0
  3. package/SKILL.md +106 -0
  4. package/dist/picoflow.js +204 -60
  5. package/dist/types/api/base/flowObservable.d.ts +3 -3
  6. package/dist/types/api/base/flowObservable.d.ts.map +1 -1
  7. package/dist/types/api/base/flowSubscribable.d.ts +2 -2
  8. package/dist/types/api/base/flowSubscribable.d.ts.map +1 -1
  9. package/dist/types/api/base/flowTracker.d.ts +1 -1
  10. package/dist/types/api/base/flowTracker.d.ts.map +1 -1
  11. package/dist/types/api/base/index.d.ts +4 -4
  12. package/dist/types/api/base/index.d.ts.map +1 -1
  13. package/dist/types/api/index.d.ts +2 -2
  14. package/dist/types/api/index.d.ts.map +1 -1
  15. package/dist/types/api/nodes/async/flowConstantAsync.d.ts +1 -1
  16. package/dist/types/api/nodes/async/flowConstantAsync.d.ts.map +1 -1
  17. package/dist/types/api/nodes/async/flowDerivationAsync.d.ts +3 -3
  18. package/dist/types/api/nodes/async/flowDerivationAsync.d.ts.map +1 -1
  19. package/dist/types/api/nodes/async/flowStateAsync.d.ts +3 -3
  20. package/dist/types/api/nodes/async/flowStateAsync.d.ts.map +1 -1
  21. package/dist/types/api/nodes/async/flowWritableDerivationAsync.d.ts +2 -2
  22. package/dist/types/api/nodes/async/flowWritableDerivationAsync.d.ts.map +1 -1
  23. package/dist/types/api/nodes/async/index.d.ts +4 -4
  24. package/dist/types/api/nodes/async/index.d.ts.map +1 -1
  25. package/dist/types/api/nodes/collections/flowArray.d.ts +7 -4
  26. package/dist/types/api/nodes/collections/flowArray.d.ts.map +1 -1
  27. package/dist/types/api/nodes/collections/flowMap.d.ts +3 -2
  28. package/dist/types/api/nodes/collections/flowMap.d.ts.map +1 -1
  29. package/dist/types/api/nodes/collections/index.d.ts +2 -2
  30. package/dist/types/api/nodes/collections/index.d.ts.map +1 -1
  31. package/dist/types/api/nodes/flowEffect.d.ts +2 -2
  32. package/dist/types/api/nodes/flowEffect.d.ts.map +1 -1
  33. package/dist/types/api/nodes/flowSignal.d.ts +1 -1
  34. package/dist/types/api/nodes/flowSignal.d.ts.map +1 -1
  35. package/dist/types/api/nodes/flowValue.d.ts +2 -2
  36. package/dist/types/api/nodes/flowValue.d.ts.map +1 -1
  37. package/dist/types/api/nodes/index.d.ts +7 -7
  38. package/dist/types/api/nodes/index.d.ts.map +1 -1
  39. package/dist/types/api/nodes/sync/flowConstant.d.ts +2 -2
  40. package/dist/types/api/nodes/sync/flowConstant.d.ts.map +1 -1
  41. package/dist/types/api/nodes/sync/flowDerivation.d.ts +3 -3
  42. package/dist/types/api/nodes/sync/flowDerivation.d.ts.map +1 -1
  43. package/dist/types/api/nodes/sync/flowState.d.ts +3 -3
  44. package/dist/types/api/nodes/sync/flowState.d.ts.map +1 -1
  45. package/dist/types/api/nodes/sync/flowWritableDerivation.d.ts +2 -2
  46. package/dist/types/api/nodes/sync/flowWritableDerivation.d.ts.map +1 -1
  47. package/dist/types/api/nodes/sync/index.d.ts +4 -4
  48. package/dist/types/api/nodes/sync/index.d.ts.map +1 -1
  49. package/dist/types/api/nodes/utils.d.ts +1 -1
  50. package/dist/types/api/nodes/utils.d.ts.map +1 -1
  51. package/dist/types/base/disposable.d.ts +1 -1
  52. package/dist/types/base/disposable.d.ts.map +1 -1
  53. package/dist/types/base/executionStack.d.ts +22 -1
  54. package/dist/types/base/executionStack.d.ts.map +1 -1
  55. package/dist/types/base/index.d.ts +5 -5
  56. package/dist/types/base/index.d.ts.map +1 -1
  57. package/dist/types/base/node.d.ts +4 -4
  58. package/dist/types/base/node.d.ts.map +1 -1
  59. package/dist/types/base/observable.d.ts +3 -3
  60. package/dist/types/base/observable.d.ts.map +1 -1
  61. package/dist/types/base/observer.d.ts +2 -2
  62. package/dist/types/base/observer.d.ts.map +1 -1
  63. package/dist/types/converters/index.d.ts +1 -1
  64. package/dist/types/converters/index.d.ts.map +1 -1
  65. package/dist/types/converters/solid.d.ts +12 -8
  66. package/dist/types/converters/solid.d.ts.map +1 -1
  67. package/dist/types/index.d.ts +2 -2
  68. package/dist/types/index.d.ts.map +1 -1
  69. package/dist/types/nodes/actionNode.d.ts +23 -0
  70. package/dist/types/nodes/actionNode.d.ts.map +1 -0
  71. package/dist/types/nodes/arrayNode.d.ts +4 -3
  72. package/dist/types/nodes/arrayNode.d.ts.map +1 -1
  73. package/dist/types/nodes/effectNode.d.ts +18 -2
  74. package/dist/types/nodes/effectNode.d.ts.map +1 -1
  75. package/dist/types/nodes/index.d.ts +8 -7
  76. package/dist/types/nodes/index.d.ts.map +1 -1
  77. package/dist/types/nodes/mapNode.d.ts +4 -3
  78. package/dist/types/nodes/mapNode.d.ts.map +1 -1
  79. package/dist/types/nodes/signalNode.d.ts +2 -2
  80. package/dist/types/nodes/signalNode.d.ts.map +1 -1
  81. package/dist/types/nodes/valueAsyncNode.d.ts +3 -3
  82. package/dist/types/nodes/valueAsyncNode.d.ts.map +1 -1
  83. package/dist/types/nodes/valueNode.d.ts +3 -3
  84. package/dist/types/nodes/valueNode.d.ts.map +1 -1
  85. package/dist/types/nodes/valueSyncNode.d.ts +3 -3
  86. package/dist/types/nodes/valueSyncNode.d.ts.map +1 -1
  87. package/dist/types/schedulers/asyncScheduler.d.ts +2 -1
  88. package/dist/types/schedulers/asyncScheduler.d.ts.map +1 -1
  89. package/dist/types/schedulers/index.d.ts +4 -4
  90. package/dist/types/schedulers/index.d.ts.map +1 -1
  91. package/dist/types/schedulers/syncResolver.d.ts +1 -2
  92. package/dist/types/schedulers/syncResolver.d.ts.map +1 -1
  93. package/dist/types/schedulers/syncScheduler.d.ts +1 -1
  94. package/dist/types/schedulers/syncScheduler.d.ts.map +1 -1
  95. package/package.json +24 -1
  96. package/.gitlab-ci.yml +0 -24
  97. package/.vscode/settings.json +0 -5
  98. package/CHANGELOG.md +0 -94
  99. package/biome.json +0 -47
  100. package/docs/.vitepress/config.mts +0 -145
  101. package/docs/api/functions/array.md +0 -35
  102. package/docs/api/functions/constant.md +0 -33
  103. package/docs/api/functions/constantAsync.md +0 -69
  104. package/docs/api/functions/derivation.md +0 -34
  105. package/docs/api/functions/derivationAsync.md +0 -34
  106. package/docs/api/functions/from.md +0 -129
  107. package/docs/api/functions/isDisposable.md +0 -27
  108. package/docs/api/functions/map.md +0 -36
  109. package/docs/api/functions/signal.md +0 -21
  110. package/docs/api/functions/state.md +0 -67
  111. package/docs/api/functions/stateAsync.md +0 -69
  112. package/docs/api/functions/subscribe.md +0 -40
  113. package/docs/api/functions/writableDerivation.md +0 -33
  114. package/docs/api/functions/writableDerivationAsync.md +0 -34
  115. package/docs/api/index.md +0 -61
  116. package/docs/api/interfaces/FlowArray.md +0 -439
  117. package/docs/api/interfaces/FlowConstant.md +0 -220
  118. package/docs/api/interfaces/FlowConstantAsync.md +0 -221
  119. package/docs/api/interfaces/FlowDerivation.md +0 -241
  120. package/docs/api/interfaces/FlowDerivationAsync.md +0 -242
  121. package/docs/api/interfaces/FlowDisposable.md +0 -59
  122. package/docs/api/interfaces/FlowEffect.md +0 -64
  123. package/docs/api/interfaces/FlowMap.md +0 -374
  124. package/docs/api/interfaces/FlowObservable.md +0 -155
  125. package/docs/api/interfaces/FlowSignal.md +0 -156
  126. package/docs/api/interfaces/FlowState.md +0 -269
  127. package/docs/api/interfaces/FlowStateAsync.md +0 -268
  128. package/docs/api/interfaces/FlowSubscribable.md +0 -55
  129. package/docs/api/interfaces/FlowTracker.md +0 -61
  130. package/docs/api/interfaces/FlowValue.md +0 -222
  131. package/docs/api/interfaces/FlowWritableDerivation.md +0 -292
  132. package/docs/api/interfaces/FlowWritableDerivationAsync.md +0 -293
  133. package/docs/api/type-aliases/DerivationFunction.md +0 -28
  134. package/docs/api/type-aliases/DerivationFunctionAsync.md +0 -28
  135. package/docs/api/type-aliases/FlowArrayAction.md +0 -60
  136. package/docs/api/type-aliases/FlowDataTracker.md +0 -33
  137. package/docs/api/type-aliases/FlowMapAction.md +0 -48
  138. package/docs/api/type-aliases/FlowOnDataListener.md +0 -33
  139. package/docs/api/type-aliases/FlowOnErrorListener.md +0 -27
  140. package/docs/api/type-aliases/FlowOnPendingListener.md +0 -21
  141. package/docs/api/type-aliases/FlowReadonly.md +0 -22
  142. package/docs/api/type-aliases/InitFunction.md +0 -21
  143. package/docs/api/type-aliases/InitFunctionAsync.md +0 -21
  144. package/docs/api/type-aliases/NotPromise.md +0 -21
  145. package/docs/api/type-aliases/UpdateFunction.md +0 -27
  146. package/docs/api/type-aliases/UpdateFunctionAsync.md +0 -27
  147. package/docs/api/typedoc-sidebar.json +0 -65
  148. package/docs/examples/examples.md +0 -2311
  149. package/docs/examples/patterns.md +0 -649
  150. package/docs/guide/advanced/architecture.md +0 -1234
  151. package/docs/guide/advanced/disposal.md +0 -426
  152. package/docs/guide/advanced/migration-v1.md +0 -464
  153. package/docs/guide/advanced/migration-v2.md +0 -204
  154. package/docs/guide/advanced/solidjs.md +0 -135
  155. package/docs/guide/introduction/concepts.md +0 -57
  156. package/docs/guide/introduction/conventions.md +0 -30
  157. package/docs/guide/introduction/getting-started.md +0 -139
  158. package/docs/guide/introduction/lifecycle.md +0 -368
  159. package/docs/guide/primitives/array.md +0 -286
  160. package/docs/guide/primitives/constant.md +0 -207
  161. package/docs/guide/primitives/derivations.md +0 -281
  162. package/docs/guide/primitives/effects.md +0 -372
  163. package/docs/guide/primitives/map.md +0 -265
  164. package/docs/guide/primitives/overview.md +0 -92
  165. package/docs/guide/primitives/signal.md +0 -222
  166. package/docs/guide/primitives/state.md +0 -272
  167. package/docs/index.md +0 -47
  168. package/docs/public/logo.svg +0 -1
  169. package/src/api/base/flowDisposable.ts +0 -44
  170. package/src/api/base/flowObservable.ts +0 -28
  171. package/src/api/base/flowSubscribable.ts +0 -87
  172. package/src/api/base/flowTracker.ts +0 -7
  173. package/src/api/base/index.ts +0 -4
  174. package/src/api/index.ts +0 -2
  175. package/src/api/nodes/async/flowConstantAsync.ts +0 -36
  176. package/src/api/nodes/async/flowDerivationAsync.ts +0 -42
  177. package/src/api/nodes/async/flowStateAsync.ts +0 -47
  178. package/src/api/nodes/async/flowWritableDerivationAsync.ts +0 -33
  179. package/src/api/nodes/async/index.ts +0 -4
  180. package/src/api/nodes/collections/flowArray.ts +0 -155
  181. package/src/api/nodes/collections/flowMap.ts +0 -115
  182. package/src/api/nodes/collections/index.ts +0 -2
  183. package/src/api/nodes/flowEffect.ts +0 -42
  184. package/src/api/nodes/flowSignal.ts +0 -28
  185. package/src/api/nodes/flowValue.ts +0 -37
  186. package/src/api/nodes/index.ts +0 -7
  187. package/src/api/nodes/sync/flowConstant.ts +0 -33
  188. package/src/api/nodes/sync/flowDerivation.ts +0 -41
  189. package/src/api/nodes/sync/flowState.ts +0 -45
  190. package/src/api/nodes/sync/flowWritableDerivation.ts +0 -31
  191. package/src/api/nodes/sync/index.ts +0 -4
  192. package/src/api/nodes/utils.ts +0 -24
  193. package/src/base/disposable.ts +0 -18
  194. package/src/base/executionStack.ts +0 -42
  195. package/src/base/index.ts +0 -5
  196. package/src/base/node.ts +0 -98
  197. package/src/base/observable.ts +0 -92
  198. package/src/base/observer.ts +0 -51
  199. package/src/converters/index.ts +0 -1
  200. package/src/converters/solid.ts +0 -109
  201. package/src/index.ts +0 -2
  202. package/src/nodes/arrayNode.ts +0 -180
  203. package/src/nodes/effectNode.ts +0 -58
  204. package/src/nodes/index.ts +0 -7
  205. package/src/nodes/mapNode.ts +0 -125
  206. package/src/nodes/signalNode.ts +0 -19
  207. package/src/nodes/valueAsyncNode.ts +0 -85
  208. package/src/nodes/valueNode.ts +0 -148
  209. package/src/nodes/valueSyncNode.ts +0 -125
  210. package/src/schedulers/asyncResolver.ts +0 -78
  211. package/src/schedulers/asyncScheduler.ts +0 -66
  212. package/src/schedulers/index.ts +0 -4
  213. package/src/schedulers/pendingError.ts +0 -13
  214. package/src/schedulers/scheduler.ts +0 -9
  215. package/src/schedulers/syncResolver.ts +0 -69
  216. package/src/schedulers/syncScheduler.ts +0 -55
  217. package/test/base/pendingError.test.ts +0 -67
  218. package/test/converters/solid.derivation.browser.test.tsx +0 -69
  219. package/test/converters/solid.node.test.ts +0 -654
  220. package/test/converters/solid.state.browser.test.tsx +0 -1592
  221. package/test/reactivity/flowSignal.test.ts +0 -226
  222. package/test/reactivity/nodes/async/asyncScheduler/asyncResolver.test.ts +0 -593
  223. package/test/reactivity/nodes/async/asyncScheduler/asyncScheduler.test.ts +0 -317
  224. package/test/reactivity/nodes/async/flowConstantAsync.test.ts +0 -652
  225. package/test/reactivity/nodes/async/flowDerivation.test.ts +0 -898
  226. package/test/reactivity/nodes/async/flowDerivationAsync.test.ts +0 -1716
  227. package/test/reactivity/nodes/async/flowStateAsync.test.ts +0 -708
  228. package/test/reactivity/nodes/async/flowWritableDerivationAsync.test.ts +0 -614
  229. package/test/reactivity/nodes/collections/flowArray.asyncStates.test.ts +0 -1289
  230. package/test/reactivity/nodes/collections/flowArray.scalars.test.ts +0 -961
  231. package/test/reactivity/nodes/collections/flowArray.states.test.ts +0 -1035
  232. package/test/reactivity/nodes/collections/flowMap.asyncStates.test.ts +0 -960
  233. package/test/reactivity/nodes/collections/flowMap.scalars.test.ts +0 -775
  234. package/test/reactivity/nodes/collections/flowMap.states.test.ts +0 -958
  235. package/test/reactivity/nodes/sync/flowConstant.test.ts +0 -377
  236. package/test/reactivity/nodes/sync/flowDerivation.test.ts +0 -896
  237. package/test/reactivity/nodes/sync/flowState.test.ts +0 -341
  238. package/test/reactivity/nodes/sync/flowWritableDerivation.test.ts +0 -603
  239. package/test/vitest.d.ts +0 -10
  240. package/tsconfig.json +0 -37
  241. package/typedoc.json +0 -37
  242. package/vite.config.ts +0 -31
  243. package/vitest.browser.config.ts +0 -21
  244. 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
- }