@ersbeth/picoflow 1.1.1 → 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 +857 -1528
  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 -53
  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 -139
  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
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Contract for resources that can be explicitly released to prevent memory leaks.
3
+ *
4
+ * All reactive primitives in PicoFlow implement this interface, allowing manual cleanup of subscriptions
5
+ * and dependencies. Once disposed, the resource cannot be reused and will throw errors on further access.
6
+ * Call `dispose()` when you no longer need a reactive primitive to free its resources.
7
+ *
8
+ * @public
9
+ */
10
+ export interface FlowDisposable {
11
+ /**
12
+ * Indicates whether this resource has been disposed.
13
+ *
14
+ * Returns `true` if `dispose()` has been called, `false` otherwise. Once disposed,
15
+ * the resource is no longer usable and any operations on it will throw errors.
16
+ */
17
+ get disposed(): boolean;
18
+
19
+ /**
20
+ * Releases all resources held by this disposable object.
21
+ *
22
+ * Cleans up all subscriptions, dependencies, and internal state. After calling this method,
23
+ * the resource enters a disposed state and cannot be reused. Any subsequent operations will
24
+ * throw errors. This method should be called when you no longer need the reactive primitive
25
+ * to prevent memory leaks.
26
+ */
27
+ dispose(): void;
28
+ }
29
+
30
+ /**
31
+ * Type guard to check if an object implements the FlowDisposable interface.
32
+ *
33
+ * Useful for conditionally disposing objects that may or may not be disposable,
34
+ * such as when cleaning up mixed collections of values. Returns true if the object
35
+ * has a `dispose` method, providing type-safe access to disposal functionality.
36
+ *
37
+ * @param obj - The object to check
38
+ * @returns True if the object implements FlowDisposable, false otherwise
39
+ *
40
+ * @public
41
+ */
42
+ export function isDisposable(obj: unknown): obj is FlowDisposable {
43
+ return obj !== null && obj !== undefined && typeof (obj as FlowDisposable).dispose === "function";
44
+ }
@@ -0,0 +1,28 @@
1
+ import type { FlowDisposable } from "./flowDisposable";
2
+ import type { FlowSubscribable } from "./flowSubscribable";
3
+ import type { FlowTracker } from "./flowTracker";
4
+
5
+ /**
6
+ * Contract for reactive primitives that emit changes and notify their dependents in the reactivity graph.
7
+ * @public
8
+ */
9
+ export interface FlowObservable<T> extends FlowDisposable, FlowSubscribable<T> {
10
+ /**
11
+ * Establishes a reactive dependency without reading the value.
12
+ *
13
+ * Registers this observable as a dependency of the given tracker, allowing it to be notified
14
+ * when changes occur. This enables dependency tracking without accessing the actual value.
15
+ *
16
+ * @param tracker - Tracker that records this observable as a dependency
17
+ */
18
+ watch(tracker: FlowTracker): void;
19
+
20
+ /**
21
+ * Manually triggers notifications to all dependents.
22
+ *
23
+ * Forces all dependents of this observable to be notified and re-executed, even if the
24
+ * value hasn't actually changed. Useful for imperatively triggering updates when the
25
+ * reactive system cannot detect changes automatically.
26
+ */
27
+ trigger(): void;
28
+ }
@@ -0,0 +1,87 @@
1
+ import type { FlowEffect } from "../nodes";
2
+ import type { FlowTracker } from "./flowTracker";
3
+
4
+ /**
5
+ * Function that tracks reactive dependencies and returns data.
6
+ *
7
+ * This function is called during effect execution with a tracker parameter that automatically
8
+ * records any reactive values accessed. The tracker enables automatic dependency tracking without
9
+ * explicit subscriptions. The returned data is passed to the `onData` callback.
10
+ *
11
+ * @param t - Tracker object that records dependencies when reactive values are accessed
12
+ * @returns The computed data of type T
13
+ *
14
+ * @public
15
+ */
16
+ export type FlowDataTracker<T> = (t: FlowTracker) => T;
17
+
18
+ /**
19
+ * Callback invoked when new data is available.
20
+ *
21
+ * This callback runs each time the effect executes successfully, receiving the data returned
22
+ * by the tracker function. It's called immediately on effect creation and then on every reactive
23
+ * re-execution. Use this callback to perform side effects with the computed data.
24
+ *
25
+ * @param data - The computed data from the tracker function
26
+ * @returns Always returns undefined (callbacks are for side effects)
27
+ *
28
+ * @public
29
+ */
30
+ export type FlowOnDataListener<T> = (data: T) => undefined;
31
+
32
+ /**
33
+ * Callback invoked when an error occurs during effect execution.
34
+ *
35
+ * If provided, this callback handles any errors thrown by the tracker function (except PendingError).
36
+ * Without this callback, errors propagate and may crash the application. Use this for error logging,
37
+ * recovery, or user feedback. The effect remains active and will retry on the next reactive trigger.
38
+ *
39
+ * @param error - The error that occurred, always normalized to an Error instance
40
+ * @returns Always returns undefined (callbacks are for side effects)
41
+ *
42
+ * @public
43
+ */
44
+ export type FlowOnErrorListener = (error: Error) => undefined;
45
+
46
+ /**
47
+ * Callback invoked when an async computation is pending.
48
+ *
49
+ * This callback is triggered when the tracker function throws a PendingError, indicating that
50
+ * async dependencies are still resolving. Use this to show loading states or pending indicators.
51
+ * The effect will automatically re-execute once the async values settle.
52
+ *
53
+ * @returns Always returns undefined (callbacks are for side effects)
54
+ *
55
+ * @public
56
+ */
57
+ export type FlowOnPendingListener = () => undefined;
58
+
59
+ /**
60
+ * Contract for observables that can be subscribed to with lifecycle callbacks.
61
+ *
62
+ * This interface enables imperative subscription to reactive values, allowing manual control over
63
+ * when effects run. The subscribe method returns a disposal function to stop the subscription.
64
+ * Useful for integrating with non-reactive code or frameworks that manage subscriptions differently.
65
+ *
66
+ * @public
67
+ */
68
+ export interface FlowSubscribable<T> {
69
+ /**
70
+ * Subscribes to this observable with lifecycle callbacks.
71
+ *
72
+ * Creates an active subscription that executes immediately and then re-executes whenever
73
+ * the observable's dependencies change. The subscription remains active until the returned
74
+ * disposal function is called. The `onData` callback receives the computed value, while
75
+ * `onError` handles errors and `onPending` signals async operations in progress.
76
+ *
77
+ * @param onData - Callback invoked with the computed data on each execution
78
+ * @param onError - Optional callback for handling errors during execution
79
+ * @param onPending - Optional callback invoked when async dependencies are pending
80
+ * @returns A function to dispose the subscription and stop receiving updates
81
+ */
82
+ subscribe(
83
+ onData: FlowOnDataListener<T>,
84
+ onError?: FlowOnErrorListener,
85
+ onPending?: FlowOnPendingListener,
86
+ ): FlowEffect;
87
+ }
@@ -0,0 +1,7 @@
1
+ import type { FlowDisposable } from "./flowDisposable";
2
+
3
+ /**
4
+ * Contract for reactive computations that track dependencies and react to changes in the reactivity graph.
5
+ * @public
6
+ */
7
+ export interface FlowTracker extends FlowDisposable {}
@@ -0,0 +1,4 @@
1
+ export * from "./flowDisposable";
2
+ export * from "./flowObservable";
3
+ export * from "./flowSubscribable";
4
+ export * from "./flowTracker";
@@ -1,3 +1,2 @@
1
1
  export * from "./base";
2
- export * from "./collections";
3
2
  export * from "./nodes";
@@ -0,0 +1,36 @@
1
+ import { ValueAsyncNode } from "~/nodes";
2
+ import type { FlowValue } from "../flowValue";
3
+
4
+ /** Function that initializes a value asynchronously. */
5
+ export type InitFunctionAsync<T> = () => Promise<T>;
6
+
7
+ /**
8
+ * Read-only reactive value that resolves once from a promise or async initializer.
9
+ *
10
+ * Async constants provide lazy initialization for asynchronous values. The promise or async initializer
11
+ * runs once on first access, and the resolved value is cached forever. While pending, accessing the value
12
+ * throws PendingError. Use for async operations that only need to run once, such as loading remote configuration,
13
+ * fetching initial data, or computing expensive async resources.
14
+ *
15
+ * @public
16
+ */
17
+ export interface FlowConstantAsync<T> extends FlowValue<T> {}
18
+
19
+ /**
20
+ * Creates a constant reactive value from a promise or async initializer that resolves once and never recomputes.
21
+ *
22
+ * The promise or async initializer executes once on first access, and the resolved value is cached permanently.
23
+ * While the promise is pending, any reactive computation that accesses the value will receive PendingError and
24
+ * automatically retry once the promise resolves. Use for one-time async operations that don't depend on other
25
+ * reactive values, such as loading configuration or fetching initial data.
26
+ *
27
+ * @param value - Promise to resolve, or async function that returns a promise on first access
28
+ * @returns A FlowConstantAsync that provides read-only access to the resolved value
29
+ *
30
+ * @public
31
+ */
32
+ export function constantAsync<T>(value: Promise<T>): FlowConstantAsync<T>;
33
+ export function constantAsync<T>(initializer: InitFunctionAsync<T>): FlowConstantAsync<T>;
34
+ export function constantAsync<T>(valueOrInitializer: Promise<T> | InitFunctionAsync<T>): FlowConstantAsync<T> {
35
+ return new ValueAsyncNode(valueOrInitializer);
36
+ }
@@ -0,0 +1,42 @@
1
+ import type { FlowTracker } from "~/api/base";
2
+ import { ValueAsyncNode } from "~/nodes";
3
+ import type { FlowValue } from "../flowValue";
4
+ import type { NotPromise } from "../utils";
5
+
6
+ /** Function that derives a value asynchronously from dependencies and optionally the previous value. */
7
+ export type DerivationFunctionAsync<T> = (tracker: FlowTracker, previous?: NotPromise<T> | undefined) => Promise<T>;
8
+
9
+ /**
10
+ * Read-only reactive value that recomputes asynchronously when dependencies change.
11
+ *
12
+ * Async derivations track reactive values accessed during computation and automatically recompute when any
13
+ * tracked dependency changes. The compute function returns a promise, and the resolved value is cached until
14
+ * dependencies change. While recomputing, accessing the value throws PendingError. Use for values derived from
15
+ * async operations like API calls, database queries, or any computation that depends on reactive state and
16
+ * requires async work.
17
+ *
18
+ * @public
19
+ */
20
+ export interface FlowDerivationAsync<T> extends FlowValue<T> {
21
+ /**
22
+ * Forces the derivation to recompute even if dependencies haven't changed.
23
+ */
24
+ refresh(): void;
25
+ }
26
+
27
+ /**
28
+ * Creates an async derived value that automatically recomputes when dependencies change.
29
+ *
30
+ * The async compute function tracks dependencies and returns a promise. When any tracked dependency changes,
31
+ * the function runs again and returns a new promise. The resolved value is cached until the next change.
32
+ * While the promise is pending, reactive computations that access this value receive PendingError and automatically
33
+ * retry once resolved. Use for derived data from async sources like filtered API results or computed database queries.
34
+ *
35
+ * @param compute - Async function that accesses dependencies and returns a promise of the derived value
36
+ * @returns A FlowDerivationAsync that provides read-only access to the resolved computed value
37
+ *
38
+ * @public
39
+ */
40
+ export function derivationAsync<T>(compute: DerivationFunctionAsync<T>): FlowDerivationAsync<T> {
41
+ return new ValueAsyncNode(compute);
42
+ }
@@ -0,0 +1,47 @@
1
+ import { ValueAsyncNode } from "~/nodes";
2
+ import type { FlowValue } from "../flowValue";
3
+ import type { NotPromise } from "../utils";
4
+ import type { InitFunctionAsync } from "./flowConstantAsync";
5
+
6
+ /** Function that updates a value asynchronously based on the previous value. */
7
+ export type UpdateFunctionAsync<T> = (previous: NotPromise<T> | undefined) => Promise<T>;
8
+
9
+ /**
10
+ * Writable reactive value that resolves promises and can be updated with new promises.
11
+ *
12
+ * Async state is the async equivalent of regular state. Unlike sync state, it accepts promises instead of
13
+ * direct values. Set new promises or async updater functions to update the state. While a promise is pending,
14
+ * accessing the value throws PendingError. Use for async data that changes imperatively, such as user-triggered
15
+ * API calls, async form submissions, or any async operation that updates based on user actions.
16
+ *
17
+ * @public
18
+ */
19
+ export interface FlowStateAsync<T> extends FlowValue<T> {
20
+ /**
21
+ * Updates the state with a new promise or via an async updater function.
22
+ * Notifies all dependents immediately (they will receive PendingError until resolved).
23
+ *
24
+ * @param promise - New promise to resolve, or async function that receives current value and returns a promise
25
+ */
26
+ set(promise: Promise<T>): void;
27
+ set(updater: UpdateFunctionAsync<T>): void;
28
+ }
29
+
30
+ /**
31
+ * Creates a mutable async reactive state that resolves promises and can be updated imperatively.
32
+ *
33
+ * State can be initialized with a direct promise or a lazy async initializer function. Update the state by
34
+ * calling `set()` with a new promise or an async updater function. Changes propagate automatically to all
35
+ * reactive computations that depend on this state. Use for async data that changes through user actions or
36
+ * application logic, such as loading user profiles, fetching search results, or any async state updates.
37
+ *
38
+ * @param value - Initial promise to resolve, or lazy async initializer function
39
+ * @returns A FlowStateAsync that can be read and modified with promises
40
+ *
41
+ * @public
42
+ */
43
+ export function stateAsync<T>(value: Promise<T>): FlowStateAsync<T>;
44
+ export function stateAsync<T>(initializer: InitFunctionAsync<T>): FlowStateAsync<T>;
45
+ export function stateAsync<T>(valueOrInitializer: Promise<T> | InitFunctionAsync<T>): FlowStateAsync<T> {
46
+ return new ValueAsyncNode(valueOrInitializer);
47
+ }
@@ -0,0 +1,33 @@
1
+ import { ValueAsyncNode } from "~/nodes";
2
+ import type { DerivationFunctionAsync, FlowDerivationAsync } from "./flowDerivationAsync";
3
+ import type { FlowStateAsync } from "./flowStateAsync";
4
+
5
+ /**
6
+ * Writable reactive value that recomputes asynchronously when dependencies change, but can be manually overridden.
7
+ *
8
+ * Async writable derivations combine reactive async computation with manual control. They track dependencies and
9
+ * recompute asynchronously like regular async derivations, but you can also call `set()` to override the computed
10
+ * value with a new promise. While recomputing or pending, accessing the value throws PendingError. Use for computed
11
+ * async values that users can edit, such as formatted async fields, calculated async totals that can be adjusted,
12
+ * or any async value that is usually derived but sometimes needs manual correction.
13
+ *
14
+ * @public
15
+ */
16
+ export interface FlowWritableDerivationAsync<T> extends FlowStateAsync<T>, FlowDerivationAsync<T> {}
17
+
18
+ /**
19
+ * Creates an async derived value that recomputes automatically but can also be manually overridden.
20
+ *
21
+ * The async compute function tracks dependencies and returns a promise. When any tracked dependency changes,
22
+ * the function runs again and returns a new promise. However, you can also call `set()` to override the computed
23
+ * value with a new promise. Use for async values that are normally derived but need occasional manual adjustments,
24
+ * such as editable async calculated fields or user-correctable async totals.
25
+ *
26
+ * @param compute - Async function that accesses dependencies and returns a promise of the derived value
27
+ * @returns A FlowWritableDerivationAsync that provides both reactive async computation and manual control
28
+ *
29
+ * @public
30
+ */
31
+ export function writableDerivationAsync<T>(compute: DerivationFunctionAsync<T>): FlowWritableDerivationAsync<T> {
32
+ return new ValueAsyncNode(compute);
33
+ }
@@ -1,5 +1,4 @@
1
1
  export * from "./flowConstantAsync";
2
2
  export * from "./flowDerivationAsync";
3
- export * from "./flowNodeAsync";
4
- export * from "./flowReadonlyAsync";
5
3
  export * from "./flowStateAsync";
4
+ export * from "./flowWritableDerivationAsync";
@@ -0,0 +1,155 @@
1
+ import { ArrayNode } from "~/nodes";
2
+ import type { FlowState } from "../sync/flowState";
3
+
4
+ /**
5
+ * Discriminated union representing all possible array mutation operations.
6
+ *
7
+ * Each mutation on a FlowArray emits an action describing what changed. This enables fine-grained
8
+ * reactive tracking - you can observe the array itself or subscribe to `$lastAction` to react only
9
+ * to specific mutations. Use this for optimized rendering, undo/redo systems, or any scenario where
10
+ * you need to know exactly what changed rather than just that something changed.
11
+ *
12
+ * @public
13
+ */
14
+ export type FlowArrayAction<T> =
15
+ | {
16
+ type: "set";
17
+ setItems: T[];
18
+ clearedItems: T[];
19
+ }
20
+ | {
21
+ type: "update";
22
+ index: number;
23
+ setItem: T;
24
+ clearedItem: T | undefined;
25
+ }
26
+ | {
27
+ type: "push";
28
+ addedItem: T;
29
+ }
30
+ | {
31
+ type: "pop";
32
+ removedItem: T | undefined;
33
+ }
34
+ | {
35
+ type: "unshift";
36
+ addedItem: T;
37
+ }
38
+ | {
39
+ type: "shift";
40
+ removedItem: T | undefined;
41
+ }
42
+ | {
43
+ type: "splice";
44
+ start: number;
45
+ deleteCount: number;
46
+ addedItems: T[];
47
+ removedItems: T[];
48
+ }
49
+ | {
50
+ type: "clear";
51
+ clearedItems: T[];
52
+ };
53
+
54
+ /**
55
+ * Reactive array with standard mutation methods and fine-grained change tracking.
56
+ *
57
+ * FlowArray behaves like a regular array but notifies dependents on mutations. It provides all standard
58
+ * array mutation methods (push, pop, splice, etc.) and tracks each operation via the `$lastAction` signal.
59
+ * This enables both coarse-grained reactivity (reacting to any change) and fine-grained reactivity (reacting
60
+ * only to specific mutations). Use for lists that need reactive updates, such as todo lists, data tables,
61
+ * or any collection that changes over time.
62
+ *
63
+ * @public
64
+ */
65
+ export interface FlowArray<T> extends FlowState<T[]> {
66
+ /**
67
+ * Replaces an item at a specific index.
68
+ * Emits an "update" action to $lastAction.
69
+ *
70
+ * @param index - The index of the item to replace
71
+ * @param item - The new item
72
+ * @returns The previous item at that index
73
+ */
74
+ update(index: number, item: T): T | undefined;
75
+
76
+ /**
77
+ * Appends an item to the end of the array.
78
+ * Emits a "push" action to $lastAction.
79
+ *
80
+ * @param item - The item to append
81
+ */
82
+ push(item: T): void;
83
+
84
+ /**
85
+ * Removes and returns the last item from the array.
86
+ * Emits a "pop" action to $lastAction.
87
+ *
88
+ * @returns The removed item, or undefined if the array was empty
89
+ */
90
+ pop(): T | undefined;
91
+
92
+ /**
93
+ * Inserts an item at the beginning of the array.
94
+ * Emits an "unshift" action to $lastAction.
95
+ *
96
+ * @param item - The item to insert
97
+ */
98
+ unshift(item: T): void;
99
+
100
+ /**
101
+ * Removes and returns the first item from the array.
102
+ * Emits a "shift" action to $lastAction.
103
+ *
104
+ * @returns The removed item, or undefined if the array was empty
105
+ */
106
+ shift(): T | undefined;
107
+
108
+ /**
109
+ * Changes the content of the array by removing, replacing, or adding items.
110
+ * Emits a "splice" action to $lastAction.
111
+ *
112
+ * @param start - The starting index
113
+ * @param deleteCount - Number of items to remove
114
+ * @param newItems - New items to add at the start position
115
+ * @returns Array of removed items
116
+ */
117
+ splice(start: number, deleteCount: number, ...newItems: T[]): T[];
118
+
119
+ /**
120
+ * Removes all items from the array.
121
+ * Emits a "clear" action to $lastAction.
122
+ *
123
+ * @returns Array of all removed items
124
+ */
125
+ clear(): T[];
126
+
127
+ /**
128
+ * The current length of the array.
129
+ */
130
+ length: number;
131
+
132
+ /**
133
+ * Reactive state containing the last mutation operation performed on the array.
134
+ * Subscribe to this for fine-grained reactivity to specific mutation types.
135
+ */
136
+ $lastAction: FlowState<FlowArrayAction<T>>;
137
+ }
138
+
139
+ /**
140
+ * Creates a reactive array with mutation methods and fine-grained action tracking.
141
+ *
142
+ * The array starts with the provided initial items (or empty if none provided). All mutation methods
143
+ * (push, pop, splice, etc.) notify dependents and emit detailed action information to `$lastAction`.
144
+ * Use the array itself for coarse-grained reactivity, or subscribe to `$lastAction` for fine-grained
145
+ * reactivity to specific mutation types. Useful for reactive lists, collections, or any data that
146
+ * needs array-like operations with automatic change propagation.
147
+ *
148
+ * @param initial - Optional initial array of items
149
+ * @returns A FlowArray with reactive mutation methods
150
+ *
151
+ * @public
152
+ */
153
+ export function array<T>(initial?: T[]): FlowArray<T> {
154
+ return new ArrayNode<T>(initial);
155
+ }
@@ -0,0 +1,115 @@
1
+ import { MapNode } from "~/nodes";
2
+ import type { FlowState } from "../sync/flowState";
3
+
4
+ /**
5
+ * Discriminated union representing all possible map mutation operations.
6
+ *
7
+ * Each mutation on a FlowMap emits an action describing what changed. This enables fine-grained
8
+ * reactive tracking - you can observe the map itself or subscribe to `$lastAction` to react only
9
+ * to specific mutations. Use this for optimized updates, undo/redo systems, or any scenario where
10
+ * you need to know exactly what changed rather than just that something changed.
11
+ *
12
+ * @public
13
+ */
14
+ export type FlowMapAction<K, V> =
15
+ | {
16
+ type: "set";
17
+ setMap: Map<K, V>;
18
+ clearedMap: Map<K, V>;
19
+ }
20
+ | {
21
+ type: "add";
22
+ key: K;
23
+ addedValue: V;
24
+ }
25
+ | {
26
+ type: "update";
27
+ key: K;
28
+ setValue: V;
29
+ clearedValue: V;
30
+ }
31
+ | {
32
+ type: "delete";
33
+ key: K;
34
+ removedValue: V;
35
+ }
36
+ | {
37
+ type: "clear";
38
+ clearedMap: Map<K, V>;
39
+ };
40
+
41
+ /**
42
+ * Reactive map with standard mutation methods and fine-grained change tracking.
43
+ *
44
+ * FlowMap behaves like a regular Map but notifies dependents on mutations. It provides standard
45
+ * map operations (add, update, delete) and tracks each operation via the `$lastAction` signal.
46
+ * This enables both coarse-grained reactivity (reacting to any change) and fine-grained reactivity
47
+ * (reacting only to specific mutations). Use for key-value collections that need reactive updates,
48
+ * such as entity stores, lookup tables, or any map-based data that changes over time.
49
+ *
50
+ * @public
51
+ */
52
+ export interface FlowMap<K, V> extends FlowState<Map<K, V>> {
53
+ /**
54
+ * Removes a key-value pair from the map.
55
+ * Emits a "delete" action to $lastAction.
56
+ *
57
+ * @param key - The key to delete
58
+ * @returns The deleted value
59
+ */
60
+ delete(key: K): V;
61
+
62
+ /**
63
+ * Updates an existing key-value pair in the map.
64
+ * Emits an "update" action to $lastAction.
65
+ *
66
+ * @param key - The key to update (must exist)
67
+ * @param value - The new value
68
+ * @returns The previous value
69
+ */
70
+ update(key: K, value: V): V | undefined;
71
+
72
+ /**
73
+ * Adds a new key-value pair to the map.
74
+ * Emits an "add" action to $lastAction.
75
+ *
76
+ * @param key - The key to add (must not exist)
77
+ * @param value - The value to associate with the key
78
+ */
79
+ add(key: K, value: V): void;
80
+
81
+ /**
82
+ * Removes all entries from the map.
83
+ * Emits a "clear" action to $lastAction.
84
+ *
85
+ * @returns Map of all removed entries
86
+ */
87
+ clear(): Map<K, V>;
88
+
89
+ /**
90
+ * Reactive state containing the last mutation operation performed on the map.
91
+ * Subscribe to this for fine-grained reactivity to specific mutation types.
92
+ */
93
+ $lastAction: FlowState<FlowMapAction<K, V>>;
94
+ }
95
+
96
+ /**
97
+ * Creates a reactive map with mutation methods and fine-grained action tracking.
98
+ *
99
+ * The map starts with the provided initial entries (or empty if none provided). All mutation methods
100
+ * (add, update, delete) notify dependents and emit detailed action information to `$lastAction`.
101
+ * Use the map itself for coarse-grained reactivity, or subscribe to `$lastAction` for fine-grained
102
+ * reactivity to specific mutation types. Useful for entity stores, lookup tables, or any key-value
103
+ * data that needs reactive updates.
104
+ *
105
+ * @param initial - Optional initial entries as a Record or Map
106
+ * @returns A FlowMap with reactive mutation methods
107
+ *
108
+ * @public
109
+ */
110
+ export function map<K extends string | number | symbol, V>(initial?: Record<K, V> | Map<K, V>): FlowMap<K, V> {
111
+ if (initial instanceof Map) {
112
+ return new MapNode<K, V>(initial);
113
+ }
114
+ return new MapNode<K, V>(new Map<K, V>(initial ? (Object.entries(initial) as [K, V][]) : []));
115
+ }
@@ -0,0 +1,42 @@
1
+ import type {
2
+ FlowDataTracker,
3
+ FlowDisposable,
4
+ FlowOnDataListener,
5
+ FlowOnErrorListener,
6
+ FlowOnPendingListener,
7
+ } from "~/api/base";
8
+ import { EffectNode } from "~/nodes";
9
+
10
+ /**
11
+ * Handle to a reactive effect that automatically tracks dependencies and re-executes when they change.
12
+ *
13
+ * Effects run immediately upon creation and then reactively respond to changes in any reactive values
14
+ * accessed during execution. Call `dispose()` to stop the effect and clean up its subscriptions.
15
+ *
16
+ * @public
17
+ */
18
+ export interface FlowEffect extends FlowDisposable {}
19
+
20
+ /**
21
+ * Creates a reactive effect that runs immediately and automatically re-runs when dependencies change.
22
+ *
23
+ * The effect function tracks any reactive values accessed and subscribes to their changes.
24
+ * When any tracked value changes, the effect re-executes with the new values.
25
+ * Optional callbacks handle errors and pending async states.
26
+ *
27
+ * @param data - Function that accesses reactive dependencies and returns data
28
+ * @param onData - Callback invoked with the computed data on each execution
29
+ * @param onError - Optional callback for handling errors during execution
30
+ * @param onPending - Optional callback invoked when async dependencies are pending
31
+ * @returns A FlowEffect handle with a `dispose()` method to stop the effect
32
+ *
33
+ * @public
34
+ */
35
+ export function subscribe<T>(
36
+ data: FlowDataTracker<T>,
37
+ onData: FlowOnDataListener<T>,
38
+ onError?: FlowOnErrorListener,
39
+ onPending?: FlowOnPendingListener,
40
+ ): FlowEffect {
41
+ return new EffectNode(data, onData, onError, onPending);
42
+ }