@ersbeth/picoflow 1.1.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (383) hide show
  1. package/.vscode/settings.json +3 -3
  2. package/CHANGELOG.md +43 -0
  3. package/README.md +2 -18
  4. package/biome.json +45 -35
  5. package/dist/picoflow.js +856 -1530
  6. package/dist/types/api/base/flowDisposable.d.ts +41 -0
  7. package/dist/types/api/base/flowDisposable.d.ts.map +1 -0
  8. package/dist/types/api/base/flowObservable.d.ts +27 -0
  9. package/dist/types/api/base/flowObservable.d.ts.map +1 -0
  10. package/dist/types/api/base/flowSubscribable.d.ts +79 -0
  11. package/dist/types/api/base/flowSubscribable.d.ts.map +1 -0
  12. package/dist/types/api/base/flowTracker.d.ts +8 -0
  13. package/dist/types/api/base/flowTracker.d.ts.map +1 -0
  14. package/dist/types/api/base/index.d.ts +5 -0
  15. package/dist/types/api/base/index.d.ts.map +1 -0
  16. package/dist/types/api/index.d.ts +3 -0
  17. package/dist/types/api/index.d.ts.map +1 -0
  18. package/dist/types/api/nodes/async/flowConstantAsync.d.ts +31 -0
  19. package/dist/types/api/nodes/async/flowConstantAsync.d.ts.map +1 -0
  20. package/dist/types/api/nodes/async/flowDerivationAsync.d.ts +37 -0
  21. package/dist/types/api/nodes/async/flowDerivationAsync.d.ts.map +1 -0
  22. package/dist/types/api/nodes/async/flowStateAsync.d.ts +41 -0
  23. package/dist/types/api/nodes/async/flowStateAsync.d.ts.map +1 -0
  24. package/dist/types/api/nodes/async/flowWritableDerivationAsync.d.ts +30 -0
  25. package/dist/types/api/nodes/async/flowWritableDerivationAsync.d.ts.map +1 -0
  26. package/dist/types/{flow → api}/nodes/async/index.d.ts +1 -2
  27. package/dist/types/api/nodes/async/index.d.ts.map +1 -0
  28. package/dist/types/api/nodes/collections/flowArray.d.ts +134 -0
  29. package/dist/types/api/nodes/collections/flowArray.d.ts.map +1 -0
  30. package/dist/types/api/nodes/collections/flowMap.d.ts +98 -0
  31. package/dist/types/api/nodes/collections/flowMap.d.ts.map +1 -0
  32. package/dist/types/api/nodes/collections/index.d.ts.map +1 -0
  33. package/dist/types/api/nodes/flowEffect.d.ts +28 -0
  34. package/dist/types/api/nodes/flowEffect.d.ts.map +1 -0
  35. package/dist/types/api/nodes/flowSignal.d.ts +25 -0
  36. package/dist/types/api/nodes/flowSignal.d.ts.map +1 -0
  37. package/dist/types/api/nodes/flowValue.d.ts +35 -0
  38. package/dist/types/api/nodes/flowValue.d.ts.map +1 -0
  39. package/dist/types/api/nodes/index.d.ts +8 -0
  40. package/dist/types/api/nodes/index.d.ts.map +1 -0
  41. package/dist/types/api/nodes/sync/flowConstant.d.ts +29 -0
  42. package/dist/types/api/nodes/sync/flowConstant.d.ts.map +1 -0
  43. package/dist/types/api/nodes/sync/flowDerivation.d.ts +36 -0
  44. package/dist/types/api/nodes/sync/flowDerivation.d.ts.map +1 -0
  45. package/dist/types/api/nodes/sync/flowState.d.ts +39 -0
  46. package/dist/types/api/nodes/sync/flowState.d.ts.map +1 -0
  47. package/dist/types/api/nodes/sync/flowWritableDerivation.d.ts +28 -0
  48. package/dist/types/api/nodes/sync/flowWritableDerivation.d.ts.map +1 -0
  49. package/dist/types/{flow → api}/nodes/sync/index.d.ts +1 -2
  50. package/dist/types/api/nodes/sync/index.d.ts.map +1 -0
  51. package/dist/types/api/nodes/utils.d.ts +22 -0
  52. package/dist/types/api/nodes/utils.d.ts.map +1 -0
  53. package/dist/types/base/disposable.d.ts +11 -0
  54. package/dist/types/base/disposable.d.ts.map +1 -0
  55. package/dist/types/base/executionStack.d.ts +14 -0
  56. package/dist/types/base/executionStack.d.ts.map +1 -0
  57. package/dist/types/base/index.d.ts +6 -0
  58. package/dist/types/base/index.d.ts.map +1 -0
  59. package/dist/types/base/node.d.ts +27 -0
  60. package/dist/types/base/node.d.ts.map +1 -0
  61. package/dist/types/base/observable.d.ts +37 -0
  62. package/dist/types/base/observable.d.ts.map +1 -0
  63. package/dist/types/base/observer.d.ts +25 -0
  64. package/dist/types/base/observer.d.ts.map +1 -0
  65. package/dist/types/converters/index.d.ts +2 -0
  66. package/dist/types/converters/index.d.ts.map +1 -0
  67. package/dist/types/converters/solid.d.ts +46 -0
  68. package/dist/types/converters/solid.d.ts.map +1 -0
  69. package/dist/types/index.d.ts +2 -63
  70. package/dist/types/index.d.ts.map +1 -1
  71. package/dist/types/nodes/arrayNode.d.ts +2 -0
  72. package/dist/types/nodes/arrayNode.d.ts.map +1 -0
  73. package/dist/types/nodes/effectNode.d.ts +2 -0
  74. package/dist/types/nodes/effectNode.d.ts.map +1 -0
  75. package/dist/types/nodes/index.d.ts +9 -0
  76. package/dist/types/nodes/index.d.ts.map +1 -0
  77. package/dist/types/nodes/mapNode.d.ts +2 -0
  78. package/dist/types/nodes/mapNode.d.ts.map +1 -0
  79. package/dist/types/nodes/signalNode.d.ts +2 -0
  80. package/dist/types/nodes/signalNode.d.ts.map +1 -0
  81. package/dist/types/nodes/valueAsyncNode.d.ts +2 -0
  82. package/dist/types/nodes/valueAsyncNode.d.ts.map +1 -0
  83. package/dist/types/nodes/valueNode.d.ts +2 -0
  84. package/dist/types/nodes/valueNode.d.ts.map +1 -0
  85. package/dist/types/nodes/valueSyncNode.d.ts +2 -0
  86. package/dist/types/nodes/valueSyncNode.d.ts.map +1 -0
  87. package/dist/types/schedulers/asyncResolver.d.ts +2 -0
  88. package/dist/types/schedulers/asyncResolver.d.ts.map +1 -0
  89. package/dist/types/schedulers/asyncScheduler.d.ts +2 -0
  90. package/dist/types/schedulers/asyncScheduler.d.ts.map +1 -0
  91. package/dist/types/schedulers/index.d.ts +5 -0
  92. package/dist/types/schedulers/index.d.ts.map +1 -0
  93. package/dist/types/schedulers/pendingError.d.ts +2 -0
  94. package/dist/types/schedulers/pendingError.d.ts.map +1 -0
  95. package/dist/types/schedulers/scheduler.d.ts +2 -0
  96. package/dist/types/schedulers/scheduler.d.ts.map +1 -0
  97. package/dist/types/schedulers/syncResolver.d.ts +2 -0
  98. package/dist/types/schedulers/syncResolver.d.ts.map +1 -0
  99. package/dist/types/schedulers/syncScheduler.d.ts +2 -0
  100. package/dist/types/schedulers/syncScheduler.d.ts.map +1 -0
  101. package/docs/.vitepress/config.mts +128 -93
  102. package/docs/api/functions/array.md +14 -37
  103. package/docs/api/functions/constant.md +13 -25
  104. package/docs/api/functions/constantAsync.md +69 -0
  105. package/docs/api/functions/derivation.md +14 -33
  106. package/docs/api/functions/derivationAsync.md +34 -0
  107. package/docs/api/functions/from.md +62 -153
  108. package/docs/api/functions/isDisposable.md +8 -30
  109. package/docs/api/functions/map.md +15 -36
  110. package/docs/api/functions/signal.md +8 -23
  111. package/docs/api/functions/state.md +43 -23
  112. package/docs/api/functions/stateAsync.md +69 -0
  113. package/docs/api/functions/subscribe.md +40 -0
  114. package/docs/api/functions/writableDerivation.md +33 -0
  115. package/docs/api/functions/writableDerivationAsync.md +34 -0
  116. package/docs/api/index.md +45 -102
  117. package/docs/api/interfaces/FlowArray.md +439 -0
  118. package/docs/api/interfaces/FlowConstant.md +220 -0
  119. package/docs/api/interfaces/FlowConstantAsync.md +221 -0
  120. package/docs/api/interfaces/FlowDerivation.md +241 -0
  121. package/docs/api/interfaces/FlowDerivationAsync.md +242 -0
  122. package/docs/api/interfaces/FlowDisposable.md +32 -38
  123. package/docs/api/interfaces/FlowEffect.md +64 -0
  124. package/docs/api/interfaces/FlowMap.md +374 -0
  125. package/docs/api/interfaces/FlowObservable.md +155 -0
  126. package/docs/api/interfaces/FlowSignal.md +156 -0
  127. package/docs/api/interfaces/FlowState.md +269 -0
  128. package/docs/api/interfaces/FlowStateAsync.md +268 -0
  129. package/docs/api/interfaces/FlowSubscribable.md +55 -0
  130. package/docs/api/interfaces/FlowTracker.md +61 -0
  131. package/docs/api/interfaces/FlowValue.md +222 -0
  132. package/docs/api/interfaces/FlowWritableDerivation.md +292 -0
  133. package/docs/api/interfaces/FlowWritableDerivationAsync.md +293 -0
  134. package/docs/api/type-aliases/DerivationFunction.md +28 -0
  135. package/docs/api/type-aliases/DerivationFunctionAsync.md +28 -0
  136. package/docs/api/type-aliases/FlowArrayAction.md +19 -8
  137. package/docs/api/type-aliases/FlowDataTracker.md +33 -0
  138. package/docs/api/type-aliases/FlowMapAction.md +48 -0
  139. package/docs/api/type-aliases/FlowOnDataListener.md +33 -0
  140. package/docs/api/type-aliases/FlowOnErrorListener.md +27 -0
  141. package/docs/api/type-aliases/FlowOnPendingListener.md +21 -0
  142. package/docs/api/type-aliases/FlowReadonly.md +22 -0
  143. package/docs/api/type-aliases/InitFunction.md +21 -0
  144. package/docs/api/type-aliases/InitFunctionAsync.md +21 -0
  145. package/docs/api/type-aliases/NotPromise.md +6 -3
  146. package/docs/api/type-aliases/UpdateFunction.md +27 -0
  147. package/docs/api/type-aliases/UpdateFunctionAsync.md +27 -0
  148. package/docs/api/typedoc-sidebar.json +1 -81
  149. package/docs/examples/examples.md +0 -2
  150. package/docs/guide/advanced/architecture.md +1234 -0
  151. package/docs/guide/advanced/migration-v2.md +204 -0
  152. package/docs/guide/advanced/solidjs.md +2 -88
  153. package/docs/guide/introduction/concepts.md +4 -3
  154. package/docs/guide/introduction/conventions.md +2 -33
  155. package/docs/guide/introduction/getting-started.md +28 -23
  156. package/docs/guide/introduction/lifecycle.md +16 -19
  157. package/docs/guide/primitives/array.md +102 -216
  158. package/docs/guide/primitives/constant.md +39 -212
  159. package/docs/guide/primitives/derivations.md +55 -122
  160. package/docs/guide/primitives/effects.md +155 -241
  161. package/docs/guide/primitives/map.md +64 -186
  162. package/docs/guide/primitives/overview.md +45 -128
  163. package/docs/guide/primitives/signal.md +51 -88
  164. package/docs/guide/primitives/state.md +34 -130
  165. package/package.json +56 -60
  166. package/src/api/base/flowDisposable.ts +44 -0
  167. package/src/api/base/flowObservable.ts +28 -0
  168. package/src/api/base/flowSubscribable.ts +87 -0
  169. package/src/api/base/flowTracker.ts +7 -0
  170. package/src/api/base/index.ts +4 -0
  171. package/src/{flow → api}/index.ts +0 -1
  172. package/src/api/nodes/async/flowConstantAsync.ts +36 -0
  173. package/src/api/nodes/async/flowDerivationAsync.ts +42 -0
  174. package/src/api/nodes/async/flowStateAsync.ts +47 -0
  175. package/src/api/nodes/async/flowWritableDerivationAsync.ts +33 -0
  176. package/src/{flow → api}/nodes/async/index.ts +1 -2
  177. package/src/api/nodes/collections/flowArray.ts +155 -0
  178. package/src/api/nodes/collections/flowMap.ts +115 -0
  179. package/src/api/nodes/flowEffect.ts +42 -0
  180. package/src/api/nodes/flowSignal.ts +28 -0
  181. package/src/api/nodes/flowValue.ts +36 -0
  182. package/src/api/nodes/index.ts +7 -0
  183. package/src/api/nodes/sync/flowConstant.ts +33 -0
  184. package/src/api/nodes/sync/flowDerivation.ts +41 -0
  185. package/src/api/nodes/sync/flowState.ts +45 -0
  186. package/src/api/nodes/sync/flowWritableDerivation.ts +31 -0
  187. package/src/{flow → api}/nodes/sync/index.ts +1 -2
  188. package/src/api/nodes/utils.ts +22 -0
  189. package/src/base/disposable.ts +18 -0
  190. package/src/base/executionStack.ts +42 -0
  191. package/src/base/index.ts +5 -0
  192. package/src/base/node.ts +98 -0
  193. package/src/base/observable.ts +87 -0
  194. package/src/base/observer.ts +51 -0
  195. package/src/converters/index.ts +1 -0
  196. package/src/converters/solid.ts +109 -0
  197. package/src/index.ts +2 -64
  198. package/src/nodes/arrayNode.ts +172 -0
  199. package/src/nodes/effectNode.ts +59 -0
  200. package/src/nodes/index.ts +8 -0
  201. package/src/nodes/mapNode.ts +127 -0
  202. package/src/nodes/signalNode.ts +21 -0
  203. package/src/nodes/valueAsyncNode.ts +88 -0
  204. package/src/nodes/valueNode.ts +144 -0
  205. package/src/nodes/valueSyncNode.ts +128 -0
  206. package/src/schedulers/asyncResolver.ts +78 -0
  207. package/src/schedulers/asyncScheduler.ts +66 -0
  208. package/src/schedulers/index.ts +4 -0
  209. package/src/schedulers/pendingError.ts +13 -0
  210. package/src/schedulers/scheduler.ts +9 -0
  211. package/src/schedulers/syncResolver.ts +69 -0
  212. package/src/schedulers/syncScheduler.ts +55 -0
  213. package/test/base/pendingError.test.ts +67 -0
  214. package/test/converters/solid.derivation.browser.test.tsx +69 -0
  215. package/test/converters/solid.node.test.ts +654 -0
  216. package/test/converters/solid.state.browser.test.tsx +1592 -0
  217. package/test/reactivity/flowSignal.test.ts +226 -0
  218. package/test/reactivity/nodes/async/asyncScheduler/asyncResolver.test.ts +593 -0
  219. package/test/reactivity/nodes/async/asyncScheduler/asyncScheduler.test.ts +317 -0
  220. package/test/reactivity/nodes/async/flowConstantAsync.test.ts +652 -0
  221. package/test/reactivity/nodes/async/flowDerivation.test.ts +898 -0
  222. package/test/reactivity/nodes/async/flowDerivationAsync.test.ts +1716 -0
  223. package/test/reactivity/nodes/async/flowStateAsync.test.ts +708 -0
  224. package/test/reactivity/nodes/async/flowWritableDerivationAsync.test.ts +614 -0
  225. package/test/reactivity/nodes/collections/flowArray.asyncStates.test.ts +1289 -0
  226. package/test/reactivity/nodes/collections/flowArray.scalars.test.ts +961 -0
  227. package/test/reactivity/nodes/collections/flowArray.states.test.ts +1035 -0
  228. package/test/reactivity/nodes/collections/flowMap.asyncStates.test.ts +960 -0
  229. package/test/reactivity/nodes/collections/flowMap.scalars.test.ts +775 -0
  230. package/test/reactivity/nodes/collections/flowMap.states.test.ts +958 -0
  231. package/test/reactivity/nodes/sync/flowConstant.test.ts +377 -0
  232. package/test/reactivity/nodes/sync/flowDerivation.test.ts +896 -0
  233. package/test/reactivity/nodes/sync/flowState.test.ts +341 -0
  234. package/test/reactivity/nodes/sync/flowWritableDerivation.test.ts +603 -0
  235. package/test/vitest.d.ts +10 -0
  236. package/tsconfig.json +31 -20
  237. package/typedoc.json +35 -35
  238. package/vite.config.ts +25 -23
  239. package/vitest.browser.config.ts +21 -0
  240. package/vitest.config.ts +12 -12
  241. package/.cursor/plans/unifier-flowresource-avec-flowderivation-c9506e24.plan.md +0 -372
  242. package/.cursor/plans/update-js-e795d61b.plan.md +0 -567
  243. package/dist/types/flow/base/flowDisposable.d.ts +0 -67
  244. package/dist/types/flow/base/flowDisposable.d.ts.map +0 -1
  245. package/dist/types/flow/base/flowEffect.d.ts +0 -127
  246. package/dist/types/flow/base/flowEffect.d.ts.map +0 -1
  247. package/dist/types/flow/base/flowGraph.d.ts +0 -97
  248. package/dist/types/flow/base/flowGraph.d.ts.map +0 -1
  249. package/dist/types/flow/base/flowSignal.d.ts +0 -134
  250. package/dist/types/flow/base/flowSignal.d.ts.map +0 -1
  251. package/dist/types/flow/base/flowTracker.d.ts +0 -15
  252. package/dist/types/flow/base/flowTracker.d.ts.map +0 -1
  253. package/dist/types/flow/base/index.d.ts +0 -7
  254. package/dist/types/flow/base/index.d.ts.map +0 -1
  255. package/dist/types/flow/base/utils.d.ts +0 -20
  256. package/dist/types/flow/base/utils.d.ts.map +0 -1
  257. package/dist/types/flow/collections/flowArray.d.ts +0 -148
  258. package/dist/types/flow/collections/flowArray.d.ts.map +0 -1
  259. package/dist/types/flow/collections/flowMap.d.ts +0 -224
  260. package/dist/types/flow/collections/flowMap.d.ts.map +0 -1
  261. package/dist/types/flow/collections/index.d.ts.map +0 -1
  262. package/dist/types/flow/index.d.ts +0 -4
  263. package/dist/types/flow/index.d.ts.map +0 -1
  264. package/dist/types/flow/nodes/async/flowConstantAsync.d.ts +0 -137
  265. package/dist/types/flow/nodes/async/flowConstantAsync.d.ts.map +0 -1
  266. package/dist/types/flow/nodes/async/flowDerivationAsync.d.ts +0 -137
  267. package/dist/types/flow/nodes/async/flowDerivationAsync.d.ts.map +0 -1
  268. package/dist/types/flow/nodes/async/flowNodeAsync.d.ts +0 -343
  269. package/dist/types/flow/nodes/async/flowNodeAsync.d.ts.map +0 -1
  270. package/dist/types/flow/nodes/async/flowReadonlyAsync.d.ts +0 -81
  271. package/dist/types/flow/nodes/async/flowReadonlyAsync.d.ts.map +0 -1
  272. package/dist/types/flow/nodes/async/flowStateAsync.d.ts +0 -111
  273. package/dist/types/flow/nodes/async/flowStateAsync.d.ts.map +0 -1
  274. package/dist/types/flow/nodes/async/index.d.ts.map +0 -1
  275. package/dist/types/flow/nodes/index.d.ts +0 -3
  276. package/dist/types/flow/nodes/index.d.ts.map +0 -1
  277. package/dist/types/flow/nodes/sync/flowConstant.d.ts +0 -108
  278. package/dist/types/flow/nodes/sync/flowConstant.d.ts.map +0 -1
  279. package/dist/types/flow/nodes/sync/flowDerivation.d.ts +0 -100
  280. package/dist/types/flow/nodes/sync/flowDerivation.d.ts.map +0 -1
  281. package/dist/types/flow/nodes/sync/flowNode.d.ts +0 -314
  282. package/dist/types/flow/nodes/sync/flowNode.d.ts.map +0 -1
  283. package/dist/types/flow/nodes/sync/flowReadonly.d.ts +0 -57
  284. package/dist/types/flow/nodes/sync/flowReadonly.d.ts.map +0 -1
  285. package/dist/types/flow/nodes/sync/flowState.d.ts +0 -96
  286. package/dist/types/flow/nodes/sync/flowState.d.ts.map +0 -1
  287. package/dist/types/flow/nodes/sync/index.d.ts.map +0 -1
  288. package/dist/types/solid/converters.d.ts +0 -57
  289. package/dist/types/solid/converters.d.ts.map +0 -1
  290. package/dist/types/solid/index.d.ts +0 -3
  291. package/dist/types/solid/index.d.ts.map +0 -1
  292. package/dist/types/solid/primitives.d.ts +0 -181
  293. package/dist/types/solid/primitives.d.ts.map +0 -1
  294. package/docs/api/classes/FlowArray.md +0 -489
  295. package/docs/api/classes/FlowConstant.md +0 -350
  296. package/docs/api/classes/FlowDerivation.md +0 -334
  297. package/docs/api/classes/FlowEffect.md +0 -100
  298. package/docs/api/classes/FlowMap.md +0 -512
  299. package/docs/api/classes/FlowObservable.md +0 -306
  300. package/docs/api/classes/FlowResource.md +0 -380
  301. package/docs/api/classes/FlowResourceAsync.md +0 -362
  302. package/docs/api/classes/FlowSignal.md +0 -160
  303. package/docs/api/classes/FlowState.md +0 -368
  304. package/docs/api/classes/FlowStream.md +0 -367
  305. package/docs/api/classes/FlowStreamAsync.md +0 -364
  306. package/docs/api/classes/SolidDerivation.md +0 -75
  307. package/docs/api/classes/SolidResource.md +0 -91
  308. package/docs/api/classes/SolidState.md +0 -71
  309. package/docs/api/classes/TrackingContext.md +0 -33
  310. package/docs/api/functions/effect.md +0 -49
  311. package/docs/api/functions/resource.md +0 -52
  312. package/docs/api/functions/resourceAsync.md +0 -50
  313. package/docs/api/functions/stream.md +0 -53
  314. package/docs/api/functions/streamAsync.md +0 -50
  315. package/docs/api/interfaces/SolidObservable.md +0 -19
  316. package/docs/api/type-aliases/FlowStreamDisposer.md +0 -15
  317. package/docs/api/type-aliases/FlowStreamSetter.md +0 -27
  318. package/docs/api/type-aliases/FlowStreamUpdater.md +0 -32
  319. package/docs/api/type-aliases/SolidGetter.md +0 -17
  320. package/docs/guide/primitives/resources.md +0 -858
  321. package/docs/guide/primitives/streams.md +0 -931
  322. package/src/flow/base/flowDisposable.ts +0 -71
  323. package/src/flow/base/flowEffect.ts +0 -171
  324. package/src/flow/base/flowGraph.ts +0 -288
  325. package/src/flow/base/flowSignal.ts +0 -207
  326. package/src/flow/base/flowTracker.ts +0 -17
  327. package/src/flow/base/index.ts +0 -6
  328. package/src/flow/base/utils.ts +0 -19
  329. package/src/flow/collections/flowArray.ts +0 -409
  330. package/src/flow/collections/flowMap.ts +0 -398
  331. package/src/flow/nodes/async/flowConstantAsync.ts +0 -142
  332. package/src/flow/nodes/async/flowDerivationAsync.ts +0 -143
  333. package/src/flow/nodes/async/flowNodeAsync.ts +0 -474
  334. package/src/flow/nodes/async/flowReadonlyAsync.ts +0 -81
  335. package/src/flow/nodes/async/flowStateAsync.ts +0 -116
  336. package/src/flow/nodes/await/advanced/index.ts +0 -5
  337. package/src/flow/nodes/await/advanced/resource.ts +0 -134
  338. package/src/flow/nodes/await/advanced/resourceAsync.ts +0 -109
  339. package/src/flow/nodes/await/advanced/stream.ts +0 -188
  340. package/src/flow/nodes/await/advanced/streamAsync.ts +0 -176
  341. package/src/flow/nodes/await/flowConstantAwait.ts +0 -154
  342. package/src/flow/nodes/await/flowDerivationAwait.ts +0 -154
  343. package/src/flow/nodes/await/flowNodeAwait.ts +0 -508
  344. package/src/flow/nodes/await/flowReadonlyAwait.ts +0 -89
  345. package/src/flow/nodes/await/flowStateAwait.ts +0 -130
  346. package/src/flow/nodes/await/index.ts +0 -5
  347. package/src/flow/nodes/index.ts +0 -3
  348. package/src/flow/nodes/sync/flowConstant.ts +0 -111
  349. package/src/flow/nodes/sync/flowDerivation.ts +0 -105
  350. package/src/flow/nodes/sync/flowNode.ts +0 -439
  351. package/src/flow/nodes/sync/flowReadonly.ts +0 -57
  352. package/src/flow/nodes/sync/flowState.ts +0 -101
  353. package/src/solid/converters.ts +0 -148
  354. package/src/solid/index.ts +0 -2
  355. package/src/solid/primitives.ts +0 -215
  356. package/test/base/flowEffect.test.ts +0 -108
  357. package/test/base/flowGraph.test.ts +0 -485
  358. package/test/base/flowSignal.test.ts +0 -372
  359. package/test/collections/flowArray.asyncStates.test.ts +0 -1553
  360. package/test/collections/flowArray.scalars.test.ts +0 -1129
  361. package/test/collections/flowArray.states.test.ts +0 -1365
  362. package/test/collections/flowMap.asyncStates.test.ts +0 -1105
  363. package/test/collections/flowMap.scalars.test.ts +0 -877
  364. package/test/collections/flowMap.states.test.ts +0 -1097
  365. package/test/nodes/async/flowConstantAsync.test.ts +0 -860
  366. package/test/nodes/async/flowDerivationAsync.test.ts +0 -1517
  367. package/test/nodes/async/flowStateAsync.test.ts +0 -1387
  368. package/test/nodes/await/advanced/resource.test.ts +0 -129
  369. package/test/nodes/await/advanced/resourceAsync.test.ts +0 -108
  370. package/test/nodes/await/advanced/stream.test.ts +0 -198
  371. package/test/nodes/await/advanced/streamAsync.test.ts +0 -196
  372. package/test/nodes/await/flowConstantAwait.test.ts +0 -643
  373. package/test/nodes/await/flowDerivationAwait.test.ts +0 -1583
  374. package/test/nodes/await/flowStateAwait.test.ts +0 -999
  375. package/test/nodes/mixed/derivation.test.ts +0 -1527
  376. package/test/nodes/sync/flowConstant.test.ts +0 -620
  377. package/test/nodes/sync/flowDerivation.test.ts +0 -1373
  378. package/test/nodes/sync/flowState.test.ts +0 -945
  379. package/test/solid/converters.test.ts +0 -721
  380. package/test/solid/primitives.test.ts +0 -1031
  381. /package/dist/types/{flow → api/nodes}/collections/index.d.ts +0 -0
  382. /package/docs/guide/advanced/{upgrading.md → migration-v1.md} +0 -0
  383. /package/src/{flow → api/nodes}/collections/index.ts +0 -0
package/src/index.ts CHANGED
@@ -1,64 +1,2 @@
1
- /**
2
- * @packageDocumentation
3
- *
4
- * # PicoFlow
5
- *
6
- * PicoFlow is a lightweight reactive dataflow library that provides a comprehensive set of
7
- * reactive primitives for building reactive applications with explicit dependency tracking.
8
- *
9
- * ## Core Concepts
10
- *
11
- * **Reactive Primitives:**
12
- * - {@link FlowSignal}: Event-like notifications without values
13
- * - {@link FlowState}: Mutable reactive values
14
- * - {@link FlowConstant}: Immutable reactive values (computed once)
15
- * - {@link FlowDerivation}: Computed values that track dependencies
16
- * - {@link FlowEffect}: Side effects that run when dependencies change
17
- *
18
- * **Advanced Primitives:**
19
- * - {@link FlowArray}: Reactive arrays with mutation tracking
20
- * - {@link FlowMap}: Reactive maps with operation tracking
21
- * - {@link FlowResource}: Async data fetching returning `T | undefined`
22
- * - {@link FlowResourceAsync}: Async data fetching returning `Promise<T>`
23
- * - {@link FlowStream}: Event streams from external sources
24
- * - {@link FlowStreamAsync}: Async event streams returning Promises
25
- *
26
- * **Tracking Context:**
27
- * - {@link TrackingContext}: The core mechanism for explicit dependency tracking
28
- * - Use `observable.get(t)` to read with tracking
29
- * - Use `observable.pick()` to read without tracking
30
- * - Use `signal.watch(t)` to track signals without values
31
- *
32
- * ## Key Features
33
- *
34
- * - **Explicit tracking**: Full control over what triggers re-execution via TrackingContext
35
- * - **Lazy evaluation**: Derivations compute only when accessed
36
- * - **Fine-grained reactivity**: Track specific operations on collections
37
- * - **Resource management**: Automatic cleanup with dispose patterns
38
- * - **SolidJS integration**: Seamless bridge to SolidJS primitives
39
- *
40
- * ## Basic Usage
41
- *
42
- * ```typescript
43
- * import { state, effect, derivation } from 'picoflow';
44
- *
45
- * // Create reactive state
46
- * const $count = state(0);
47
- *
48
- * // Create derived value
49
- * const $double = derivation((t) => $count.get(t) * 2);
50
- *
51
- * // Create effect
52
- * effect((t) => {
53
- * console.log('Count:', $count.get(t), 'Double:', $double.get(t));
54
- * });
55
- *
56
- * // Update state
57
- * $count.set(1); // Logs: "Count: 1 Double: 2"
58
- * ```
59
- *
60
- * @see {@link https://github.com/yourusername/picoflow | GitHub Repository}
61
- */
62
-
63
- export * from "./flow";
64
- export * from "./solid";
1
+ export * from "./api";
2
+ export * from "./converters";
@@ -0,0 +1,172 @@
1
+ import type { FlowArray, FlowArrayAction } from "~/api/nodes/collections/flowArray";
2
+ import type { UpdateFunction } from "~/api/nodes/sync/flowState";
3
+ import type { NotPromise } from "~/api/nodes/utils";
4
+ import { Disposable } from "~/base";
5
+ import { ValueSyncNode } from "./valueSyncNode";
6
+
7
+ /**
8
+ * Internal implementation of reactive array with mutation tracking.
9
+ * @internal
10
+ */
11
+ export class ArrayNode<T> extends ValueSyncNode<T[]> implements FlowArray<T> {
12
+ $lastAction: ValueSyncNode<FlowArrayAction<T>>;
13
+ protected declare _value: T[];
14
+
15
+ constructor(value: T[] = []) {
16
+ super(value);
17
+ this.$lastAction = new ValueSyncNode<FlowArrayAction<T>>({
18
+ type: "set",
19
+ setItems: value,
20
+ clearedItems: [],
21
+ });
22
+ }
23
+
24
+ get length(): number {
25
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
26
+ return this._value.length;
27
+ }
28
+
29
+ override set(items: NotPromise<T[]>): T[];
30
+ override set(updater: UpdateFunction<T[]>): T[];
31
+ override set(itemsOrUpdater: NotPromise<T[]> | UpdateFunction<T[]>): T[] {
32
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
33
+
34
+ // compute previous value
35
+ const previousValue = this._value;
36
+
37
+ // set new value
38
+ // @ts-expect-error - we know that this._value is an array
39
+ super.set(itemsOrUpdater);
40
+
41
+ // emit last action
42
+ this.$lastAction.set({
43
+ type: "set",
44
+ setItems: this._value,
45
+ clearedItems: previousValue,
46
+ });
47
+
48
+ // return previous value
49
+ return previousValue;
50
+ }
51
+
52
+ update(index: number, item: T): T | undefined {
53
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
54
+
55
+ if (index < 0 || index >= this._value.length) {
56
+ throw new Error("[PicoFlow] Index out of bounds");
57
+ }
58
+
59
+ // compute previous value
60
+ const previousValue = this._value[index];
61
+
62
+ // update item
63
+ this._value[index] = item;
64
+ this.notifyDependents();
65
+
66
+ // emit last action
67
+ this.$lastAction.set({
68
+ type: "update",
69
+ index: index,
70
+ setItem: item,
71
+ clearedItem: previousValue,
72
+ });
73
+
74
+ // return previous value
75
+ return previousValue;
76
+ }
77
+
78
+ push(item: T): void {
79
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
80
+
81
+ // push item
82
+ this._value.push(item);
83
+ this.notifyDependents();
84
+
85
+ // emit last action
86
+ this.$lastAction.set({ type: "push", addedItem: item });
87
+ }
88
+
89
+ pop(): T | undefined {
90
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
91
+
92
+ // pop item
93
+ const item = this._value.pop();
94
+ this.notifyDependents();
95
+
96
+ // emit last action
97
+ this.$lastAction.set({ type: "pop", removedItem: item });
98
+
99
+ // return previous value
100
+ return item;
101
+ }
102
+
103
+ unshift(item: T): void {
104
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
105
+
106
+ // unshift item
107
+ this._value.unshift(item);
108
+ this.notifyDependents();
109
+
110
+ // emit last action
111
+ this.$lastAction.set({ type: "unshift", addedItem: item });
112
+ }
113
+
114
+ shift(): T | undefined {
115
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
116
+
117
+ // shift item
118
+ const item = this._value.shift();
119
+ this.notifyDependents();
120
+
121
+ // emit last action
122
+ this.$lastAction.set({ type: "shift", removedItem: item });
123
+
124
+ // return previous value
125
+ return item;
126
+ }
127
+
128
+ splice(start: number, deleteCount: number, ...newItems: T[]): T[] {
129
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
130
+
131
+ // splice items
132
+ const items = this._value.splice(start, deleteCount, ...newItems);
133
+ this.notifyDependents();
134
+
135
+ // emit last action
136
+ this.$lastAction.set({
137
+ type: "splice",
138
+ start: start,
139
+ deleteCount: deleteCount,
140
+ addedItems: newItems,
141
+ removedItems: items,
142
+ });
143
+
144
+ // return value changed check
145
+ return items;
146
+ }
147
+
148
+ clear(): T[] {
149
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
150
+
151
+ // compute previous value
152
+ const previousValue = [...this._value];
153
+
154
+ // clear array
155
+ this._value = [];
156
+ this.notifyDependents();
157
+
158
+ // emit last action
159
+ this.$lastAction.set({ type: "clear", clearedItems: previousValue });
160
+
161
+ // return value changed check
162
+ return previousValue;
163
+ }
164
+
165
+ override dispose(): void {
166
+ super.dispose();
167
+ this._value.forEach((item) => {
168
+ if (item instanceof Disposable) item.dispose();
169
+ });
170
+ this._value = [];
171
+ }
172
+ }
@@ -0,0 +1,59 @@
1
+ import type {
2
+ FlowDataTracker,
3
+ FlowOnDataListener,
4
+ FlowOnErrorListener,
5
+ FlowOnPendingListener,
6
+ } from "~/api/base/flowSubscribable";
7
+ import type { FlowEffect } from "~/api/nodes/flowEffect";
8
+ import { ExecutionStack } from "~/base";
9
+ import { Observer } from "~/base/";
10
+ import { PendingError } from "~/schedulers";
11
+
12
+ /**
13
+ * Reactive effect that automatically re-executes when its dependencies change.
14
+ * @internal
15
+ */
16
+ export class EffectNode<T> extends Observer implements FlowEffect {
17
+ private _data: FlowDataTracker<T>;
18
+ private _onData: FlowOnDataListener<T>;
19
+ private _onError?: FlowOnErrorListener;
20
+ private _onPending?: FlowOnPendingListener;
21
+
22
+ constructor(
23
+ data: FlowDataTracker<T>,
24
+ onData: FlowOnDataListener<T>,
25
+ onError?: FlowOnErrorListener,
26
+ onPending?: FlowOnPendingListener,
27
+ ) {
28
+ super();
29
+ this._data = data;
30
+ this._onData = onData;
31
+ this._onError = onError;
32
+ this._onPending = onPending;
33
+ this.execute();
34
+ }
35
+
36
+ notify(): void {
37
+ if (this._disposed) throw new Error("[PicoFlow] Primitive is disposed");
38
+ ExecutionStack.pushEffect(this as unknown as EffectNode<unknown>);
39
+ }
40
+
41
+ execute(): void {
42
+ try {
43
+ if (this._disposed) throw new Error("[PicoFlow] Primitive is disposed");
44
+ this.clearDependencies();
45
+ const data = this._data(this);
46
+ this._onData(data);
47
+ } catch (error) {
48
+ if (error instanceof PendingError) {
49
+ this._onPending?.();
50
+ } else {
51
+ if (this._onError) {
52
+ this._onError(error instanceof Error ? error : new Error(String(error)));
53
+ } else {
54
+ throw error;
55
+ }
56
+ }
57
+ }
58
+ }
59
+ }
@@ -0,0 +1,8 @@
1
+ export * from "../base/executionStack";
2
+ export * from "./arrayNode";
3
+ export * from "./effectNode";
4
+ export * from "./mapNode";
5
+ export * from "./signalNode";
6
+ export * from "./valueAsyncNode";
7
+ export * from "./valueNode";
8
+ export * from "./valueSyncNode";
@@ -0,0 +1,127 @@
1
+ import type { FlowMap, FlowMapAction } from "~/api/nodes/collections/flowMap";
2
+ import type { UpdateFunction } from "~/api/nodes/sync/flowState";
3
+ import type { NotPromise } from "~/api/nodes/utils";
4
+ import { Disposable } from "~/base";
5
+ import { ValueSyncNode } from "./valueSyncNode";
6
+
7
+ /**
8
+ * Internal implementation of reactive map with mutation tracking.
9
+ * @internal
10
+ */
11
+ export class MapNode<K, V> extends ValueSyncNode<Map<K, V>> implements FlowMap<K, V> {
12
+ public $lastAction: ValueSyncNode<FlowMapAction<K, V>>;
13
+ protected declare _value: Map<K, V>;
14
+
15
+ constructor(value: Map<K, V> = new Map()) {
16
+ super(value);
17
+ this.$lastAction = new ValueSyncNode<FlowMapAction<K, V>>({
18
+ type: "set",
19
+ setMap: value,
20
+ clearedMap: new Map(),
21
+ });
22
+ }
23
+
24
+ add(key: K, value: V) {
25
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
26
+
27
+ // get value
28
+ const previousValue = this._value.get(key);
29
+ if (previousValue) {
30
+ throw new Error("[PicoFlow] Key already exists");
31
+ }
32
+
33
+ // add key
34
+ this._value.set(key, value);
35
+ this.notifyDependents();
36
+
37
+ // emit last action
38
+ this.$lastAction.set({ type: "add", key, addedValue: value });
39
+ }
40
+
41
+ update(key: K, value: V): V {
42
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
43
+
44
+ // get value
45
+ const previousValue = this._value.get(key);
46
+ if (!previousValue) throw new Error("[PicoFlow] Key does not exist");
47
+
48
+ // update key
49
+ this._value.set(key, value);
50
+ this.notifyDependents();
51
+
52
+ // emit last action
53
+ this.$lastAction.set({
54
+ type: "update",
55
+ key,
56
+ setValue: value,
57
+ clearedValue: previousValue,
58
+ });
59
+
60
+ // return previous value
61
+ return previousValue;
62
+ }
63
+
64
+ delete(key: K): V {
65
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
66
+
67
+ // get value
68
+ const value = this._value.get(key);
69
+ if (value === undefined) throw new Error("[PicoFlow] Key does not exist");
70
+
71
+ // delete key
72
+ this._value.delete(key);
73
+ this.notifyDependents();
74
+
75
+ // emit last action
76
+ this.$lastAction.set({ type: "delete", key, removedValue: value });
77
+
78
+ // return previous value
79
+ return value;
80
+ }
81
+
82
+ override set(map: NotPromise<Map<K, V>>): Map<K, V>;
83
+ override set(updater: UpdateFunction<Map<K, V>>): Map<K, V>;
84
+ override set(mapOrUpdater: NotPromise<Map<K, V>> | UpdateFunction<Map<K, V>>): Map<K, V> {
85
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
86
+ // compute current value
87
+ const previousValue = this._value;
88
+
89
+ // @ts-expect-error - we know that this._value is a Map
90
+ super.set(mapOrUpdater);
91
+
92
+ // emit last action
93
+ this.$lastAction.set({
94
+ type: "set",
95
+ setMap: this._value,
96
+ clearedMap: previousValue,
97
+ });
98
+
99
+ // return previous value
100
+ return previousValue;
101
+ }
102
+
103
+ clear(): Map<K, V> {
104
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
105
+
106
+ // compute previous value
107
+ const previousValue = this._value;
108
+
109
+ // clear map
110
+ this._value = new Map();
111
+ this.notifyDependents();
112
+
113
+ // emit last action
114
+ this.$lastAction.set({ type: "clear", clearedMap: previousValue });
115
+
116
+ // return value changed check
117
+ return previousValue;
118
+ }
119
+
120
+ override dispose(): void {
121
+ super.dispose();
122
+ this._value.forEach((item) => {
123
+ if (item instanceof Disposable) item.dispose();
124
+ });
125
+ this._value.clear();
126
+ }
127
+ }
@@ -0,0 +1,21 @@
1
+ import type { FlowEffect } from "~/api";
2
+ import type { FlowOnDataListener, FlowOnErrorListener, FlowOnPendingListener } from "~/api/base/flowSubscribable";
3
+ import type { FlowSignal } from "~/api/nodes/flowSignal";
4
+ import { Observable, type Observer } from "~/base/";
5
+ import { EffectNode } from "./effectNode";
6
+
7
+ /**
8
+ * Manual trigger that notifies subscribers without carrying data.
9
+ * @internal
10
+ */
11
+ export class SignalNode extends Observable<void> implements FlowSignal {
12
+ subscribe(
13
+ onTrigger: FlowOnDataListener<void>,
14
+ onError?: FlowOnErrorListener,
15
+ onPending?: FlowOnPendingListener,
16
+ ): FlowEffect {
17
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
18
+ const effect = new EffectNode<void>((t) => this.watch(t as unknown as Observer), onTrigger, onError, onPending);
19
+ return effect;
20
+ }
21
+ }
@@ -0,0 +1,88 @@
1
+ import type { InitFunctionAsync } from "~/api/nodes/async/flowConstantAsync";
2
+ import type { DerivationFunctionAsync } from "~/api/nodes/async/flowDerivationAsync";
3
+ import type { UpdateFunctionAsync } from "~/api/nodes/async/flowStateAsync";
4
+ import type { NotPromise } from "~/api/nodes/utils";
5
+ import { AsyncScheduler } from "~/schedulers";
6
+ import { ValueNode } from "./valueNode";
7
+
8
+ /**
9
+ * Function that computes a value asynchronously (either initialization or derivation).
10
+ * @internal
11
+ */
12
+ export type ComputeFunctionAsync<T> = InitFunctionAsync<T> | DerivationFunctionAsync<T>;
13
+ /**
14
+ * Asynchronous reactive value that resolves promises and propagates results when settled.
15
+ * @internal
16
+ */
17
+ export class ValueAsyncNode<T extends NotPromise<unknown>> extends ValueNode<T> {
18
+ protected _scheduler: AsyncScheduler<T>;
19
+ private _compute: () => Promise<T>;
20
+
21
+ constructor(promiseOrCompute: Promise<T> | ComputeFunctionAsync<T>) {
22
+ super();
23
+ if (typeof promiseOrCompute === "function") {
24
+ // compute is a function
25
+ this._compute = () => promiseOrCompute(this, this._value);
26
+ } else {
27
+ // compute is a promise
28
+ this._compute = () => promiseOrCompute;
29
+ }
30
+ this.status = "dirty";
31
+ this._scheduler = new AsyncScheduler(
32
+ () => this._compute(),
33
+ (value) => this._onResolve(value as NotPromise<T>),
34
+ (error) => this._onReject(error),
35
+ );
36
+ }
37
+
38
+ private _onResolve(value: NotPromise<T>) {
39
+ this.status = "resolved";
40
+ this._value = value;
41
+ this._error = undefined;
42
+ this.notifyDependents();
43
+ }
44
+
45
+ private _onReject(error: unknown) {
46
+ this.status = "error";
47
+ this._error = error;
48
+ this.notifyDependents();
49
+ }
50
+
51
+ set(promise: Promise<T>): void;
52
+ set(updater: UpdateFunctionAsync<T>): void;
53
+ set(promiseOrUpdater: Promise<T> | UpdateFunctionAsync<T>): void {
54
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
55
+
56
+ if (typeof promiseOrUpdater === "function") {
57
+ const updater = promiseOrUpdater as UpdateFunctionAsync<T>;
58
+ switch (this.status) {
59
+ case "resolved": {
60
+ this.status = "pending";
61
+ this._scheduler.overwrite(updater(this._value));
62
+ this.notifyDependents();
63
+ return;
64
+ }
65
+ case "pending":
66
+ case "error":
67
+ case "dirty": {
68
+ // TODO: For now we use latest value to compute the next value
69
+ // Maybe we should throw instead ?
70
+ this.status = "pending";
71
+ this._scheduler.overwrite(updater(this._value));
72
+ this.notifyDependents();
73
+ return;
74
+ }
75
+ }
76
+ } else {
77
+ this.status = "pending";
78
+ const promise = promiseOrUpdater;
79
+ this._scheduler.overwrite(promise);
80
+ this.notifyDependents();
81
+ }
82
+ }
83
+
84
+ refresh(): void {
85
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
86
+ this.execute();
87
+ }
88
+ }
@@ -0,0 +1,144 @@
1
+ import type { FlowEffect } from "~/api";
2
+ import type { FlowOnDataListener, FlowOnErrorListener, FlowOnPendingListener } from "~/api/base/flowSubscribable";
3
+ import type { FlowTracker } from "~/api/base/flowTracker";
4
+ import type { NotPromise } from "~/api/nodes/utils";
5
+ import { ExecutionStack, Node, type ObservableStatus, type Observer } from "~/base";
6
+ import { PendingError, type Scheduler } from "~/schedulers";
7
+ import { EffectNode } from "./effectNode";
8
+
9
+ /**
10
+ * Base class for reactive values that compute, cache, and propagate changes through the dependency graph.
11
+ * @internal
12
+ */
13
+ export abstract class ValueNode<T> extends Node<T> {
14
+ protected abstract _scheduler: Scheduler;
15
+ protected _value?: NotPromise<T>;
16
+ protected _error?: unknown;
17
+
18
+ override watch(tracker: FlowTracker): void {
19
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
20
+ super.watch(tracker as unknown as Observer);
21
+
22
+ switch (this.status as ObservableStatus) {
23
+ case "resolved":
24
+ return;
25
+ case "error":
26
+ throw this._error;
27
+ case "pending": {
28
+ throw new PendingError(this._scheduler.settled);
29
+ }
30
+ case "dirty": {
31
+ this.execute();
32
+ switch (this.status as ObservableStatus) {
33
+ case "pending":
34
+ throw new PendingError(this._scheduler.settled);
35
+ case "resolved":
36
+ return;
37
+ case "error":
38
+ throw this._error;
39
+ case "dirty": {
40
+ throw new Error("[PicoFlow] Internal error");
41
+ }
42
+ }
43
+ }
44
+ }
45
+ }
46
+
47
+ override notify(): void {
48
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
49
+ if (this.status === "dirty") return;
50
+ if (this.status === "pending") {
51
+ ExecutionStack.pushPending(this);
52
+ }
53
+ this.status = "dirty";
54
+ this.notifyDependents();
55
+ }
56
+
57
+ override dispose(): void {
58
+ super.dispose();
59
+ this._scheduler.dispose();
60
+ }
61
+
62
+ get(tracker: FlowTracker): T {
63
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
64
+ super.watch(tracker);
65
+
66
+ switch (this.status as ObservableStatus) {
67
+ case "resolved":
68
+ return this._value as T;
69
+ case "error":
70
+ throw this._error;
71
+ case "pending": {
72
+ throw new PendingError(this._scheduler.settled);
73
+ }
74
+ case "dirty": {
75
+ this.execute();
76
+ switch (this.status as ObservableStatus) {
77
+ case "resolved":
78
+ return this._value as T;
79
+ case "error":
80
+ throw this._error;
81
+ case "pending": {
82
+ throw new PendingError(this._scheduler.settled);
83
+ }
84
+ case "dirty": {
85
+ throw new Error("[PicoFlow] Internal error");
86
+ }
87
+ }
88
+ }
89
+ }
90
+ }
91
+
92
+ async pick(): Promise<T> {
93
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
94
+ switch (this.status) {
95
+ case "resolved":
96
+ return this._value as T;
97
+ case "pending": {
98
+ await this._scheduler.settled;
99
+ if ((this.status as ObservableStatus) === "resolved") return this._value as T;
100
+ if ((this.status as ObservableStatus) === "error") throw this._error;
101
+ throw new Error("[PicoFlow] Internal error");
102
+ }
103
+ case "error":
104
+ throw this._error;
105
+ case "dirty": {
106
+ this.execute();
107
+ switch (this.status as ObservableStatus) {
108
+ case "resolved":
109
+ return this._value as T;
110
+ case "pending": {
111
+ await this._scheduler.settled;
112
+ if ((this.status as ObservableStatus) === "resolved") return this._value as T;
113
+ if ((this.status as ObservableStatus) === "error") throw this._error;
114
+ throw new Error("[PicoFlow] Internal error");
115
+ }
116
+ case "error":
117
+ throw this._error;
118
+ case "dirty": {
119
+ throw new Error("[PicoFlow] Internal error");
120
+ }
121
+ }
122
+ }
123
+ }
124
+ }
125
+
126
+ execute(): void {
127
+ // TODO: Should we throw instead ?
128
+ if (this.disposed) return;
129
+
130
+ this.clearDependencies();
131
+ this.status = "pending";
132
+ this._scheduler.compute();
133
+ }
134
+
135
+ subscribe(
136
+ onValue: FlowOnDataListener<T>,
137
+ onError?: FlowOnErrorListener,
138
+ onPending?: FlowOnPendingListener,
139
+ ): FlowEffect {
140
+ if (this.disposed) throw new Error("[PicoFlow] Primitive is disposed");
141
+ const effect = new EffectNode((t) => this.get(t), onValue, onError, onPending);
142
+ return effect;
143
+ }
144
+ }