@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.
- package/.vscode/settings.json +3 -3
- package/CHANGELOG.md +43 -0
- package/README.md +2 -18
- package/biome.json +45 -35
- package/dist/picoflow.js +856 -1530
- package/dist/types/api/base/flowDisposable.d.ts +41 -0
- package/dist/types/api/base/flowDisposable.d.ts.map +1 -0
- package/dist/types/api/base/flowObservable.d.ts +27 -0
- package/dist/types/api/base/flowObservable.d.ts.map +1 -0
- package/dist/types/api/base/flowSubscribable.d.ts +79 -0
- package/dist/types/api/base/flowSubscribable.d.ts.map +1 -0
- package/dist/types/api/base/flowTracker.d.ts +8 -0
- package/dist/types/api/base/flowTracker.d.ts.map +1 -0
- package/dist/types/api/base/index.d.ts +5 -0
- package/dist/types/api/base/index.d.ts.map +1 -0
- package/dist/types/api/index.d.ts +3 -0
- package/dist/types/api/index.d.ts.map +1 -0
- package/dist/types/api/nodes/async/flowConstantAsync.d.ts +31 -0
- package/dist/types/api/nodes/async/flowConstantAsync.d.ts.map +1 -0
- package/dist/types/api/nodes/async/flowDerivationAsync.d.ts +37 -0
- package/dist/types/api/nodes/async/flowDerivationAsync.d.ts.map +1 -0
- package/dist/types/api/nodes/async/flowStateAsync.d.ts +41 -0
- package/dist/types/api/nodes/async/flowStateAsync.d.ts.map +1 -0
- package/dist/types/api/nodes/async/flowWritableDerivationAsync.d.ts +30 -0
- package/dist/types/api/nodes/async/flowWritableDerivationAsync.d.ts.map +1 -0
- package/dist/types/{flow → api}/nodes/async/index.d.ts +1 -2
- package/dist/types/api/nodes/async/index.d.ts.map +1 -0
- package/dist/types/api/nodes/collections/flowArray.d.ts +134 -0
- package/dist/types/api/nodes/collections/flowArray.d.ts.map +1 -0
- package/dist/types/api/nodes/collections/flowMap.d.ts +98 -0
- package/dist/types/api/nodes/collections/flowMap.d.ts.map +1 -0
- package/dist/types/api/nodes/collections/index.d.ts.map +1 -0
- package/dist/types/api/nodes/flowEffect.d.ts +28 -0
- package/dist/types/api/nodes/flowEffect.d.ts.map +1 -0
- package/dist/types/api/nodes/flowSignal.d.ts +25 -0
- package/dist/types/api/nodes/flowSignal.d.ts.map +1 -0
- package/dist/types/api/nodes/flowValue.d.ts +35 -0
- package/dist/types/api/nodes/flowValue.d.ts.map +1 -0
- package/dist/types/api/nodes/index.d.ts +8 -0
- package/dist/types/api/nodes/index.d.ts.map +1 -0
- package/dist/types/api/nodes/sync/flowConstant.d.ts +29 -0
- package/dist/types/api/nodes/sync/flowConstant.d.ts.map +1 -0
- package/dist/types/api/nodes/sync/flowDerivation.d.ts +36 -0
- package/dist/types/api/nodes/sync/flowDerivation.d.ts.map +1 -0
- package/dist/types/api/nodes/sync/flowState.d.ts +39 -0
- package/dist/types/api/nodes/sync/flowState.d.ts.map +1 -0
- package/dist/types/api/nodes/sync/flowWritableDerivation.d.ts +28 -0
- package/dist/types/api/nodes/sync/flowWritableDerivation.d.ts.map +1 -0
- package/dist/types/{flow → api}/nodes/sync/index.d.ts +1 -2
- package/dist/types/api/nodes/sync/index.d.ts.map +1 -0
- package/dist/types/api/nodes/utils.d.ts +22 -0
- package/dist/types/api/nodes/utils.d.ts.map +1 -0
- package/dist/types/base/disposable.d.ts +11 -0
- package/dist/types/base/disposable.d.ts.map +1 -0
- package/dist/types/base/executionStack.d.ts +14 -0
- package/dist/types/base/executionStack.d.ts.map +1 -0
- package/dist/types/base/index.d.ts +6 -0
- package/dist/types/base/index.d.ts.map +1 -0
- package/dist/types/base/node.d.ts +27 -0
- package/dist/types/base/node.d.ts.map +1 -0
- package/dist/types/base/observable.d.ts +37 -0
- package/dist/types/base/observable.d.ts.map +1 -0
- package/dist/types/base/observer.d.ts +25 -0
- package/dist/types/base/observer.d.ts.map +1 -0
- package/dist/types/converters/index.d.ts +2 -0
- package/dist/types/converters/index.d.ts.map +1 -0
- package/dist/types/converters/solid.d.ts +46 -0
- package/dist/types/converters/solid.d.ts.map +1 -0
- package/dist/types/index.d.ts +2 -63
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/nodes/arrayNode.d.ts +2 -0
- package/dist/types/nodes/arrayNode.d.ts.map +1 -0
- package/dist/types/nodes/effectNode.d.ts +2 -0
- package/dist/types/nodes/effectNode.d.ts.map +1 -0
- package/dist/types/nodes/index.d.ts +9 -0
- package/dist/types/nodes/index.d.ts.map +1 -0
- package/dist/types/nodes/mapNode.d.ts +2 -0
- package/dist/types/nodes/mapNode.d.ts.map +1 -0
- package/dist/types/nodes/signalNode.d.ts +2 -0
- package/dist/types/nodes/signalNode.d.ts.map +1 -0
- package/dist/types/nodes/valueAsyncNode.d.ts +2 -0
- package/dist/types/nodes/valueAsyncNode.d.ts.map +1 -0
- package/dist/types/nodes/valueNode.d.ts +2 -0
- package/dist/types/nodes/valueNode.d.ts.map +1 -0
- package/dist/types/nodes/valueSyncNode.d.ts +2 -0
- package/dist/types/nodes/valueSyncNode.d.ts.map +1 -0
- package/dist/types/schedulers/asyncResolver.d.ts +2 -0
- package/dist/types/schedulers/asyncResolver.d.ts.map +1 -0
- package/dist/types/schedulers/asyncScheduler.d.ts +2 -0
- package/dist/types/schedulers/asyncScheduler.d.ts.map +1 -0
- package/dist/types/schedulers/index.d.ts +5 -0
- package/dist/types/schedulers/index.d.ts.map +1 -0
- package/dist/types/schedulers/pendingError.d.ts +2 -0
- package/dist/types/schedulers/pendingError.d.ts.map +1 -0
- package/dist/types/schedulers/scheduler.d.ts +2 -0
- package/dist/types/schedulers/scheduler.d.ts.map +1 -0
- package/dist/types/schedulers/syncResolver.d.ts +2 -0
- package/dist/types/schedulers/syncResolver.d.ts.map +1 -0
- package/dist/types/schedulers/syncScheduler.d.ts +2 -0
- package/dist/types/schedulers/syncScheduler.d.ts.map +1 -0
- package/docs/.vitepress/config.mts +128 -93
- package/docs/api/functions/array.md +14 -37
- package/docs/api/functions/constant.md +13 -25
- package/docs/api/functions/constantAsync.md +69 -0
- package/docs/api/functions/derivation.md +14 -33
- package/docs/api/functions/derivationAsync.md +34 -0
- package/docs/api/functions/from.md +62 -153
- package/docs/api/functions/isDisposable.md +8 -30
- package/docs/api/functions/map.md +15 -36
- package/docs/api/functions/signal.md +8 -23
- package/docs/api/functions/state.md +43 -23
- package/docs/api/functions/stateAsync.md +69 -0
- package/docs/api/functions/subscribe.md +40 -0
- package/docs/api/functions/writableDerivation.md +33 -0
- package/docs/api/functions/writableDerivationAsync.md +34 -0
- package/docs/api/index.md +45 -102
- package/docs/api/interfaces/FlowArray.md +439 -0
- package/docs/api/interfaces/FlowConstant.md +220 -0
- package/docs/api/interfaces/FlowConstantAsync.md +221 -0
- package/docs/api/interfaces/FlowDerivation.md +241 -0
- package/docs/api/interfaces/FlowDerivationAsync.md +242 -0
- package/docs/api/interfaces/FlowDisposable.md +32 -38
- package/docs/api/interfaces/FlowEffect.md +64 -0
- package/docs/api/interfaces/FlowMap.md +374 -0
- package/docs/api/interfaces/FlowObservable.md +155 -0
- package/docs/api/interfaces/FlowSignal.md +156 -0
- package/docs/api/interfaces/FlowState.md +269 -0
- package/docs/api/interfaces/FlowStateAsync.md +268 -0
- package/docs/api/interfaces/FlowSubscribable.md +55 -0
- package/docs/api/interfaces/FlowTracker.md +61 -0
- package/docs/api/interfaces/FlowValue.md +222 -0
- package/docs/api/interfaces/FlowWritableDerivation.md +292 -0
- package/docs/api/interfaces/FlowWritableDerivationAsync.md +293 -0
- package/docs/api/type-aliases/DerivationFunction.md +28 -0
- package/docs/api/type-aliases/DerivationFunctionAsync.md +28 -0
- package/docs/api/type-aliases/FlowArrayAction.md +19 -8
- package/docs/api/type-aliases/FlowDataTracker.md +33 -0
- package/docs/api/type-aliases/FlowMapAction.md +48 -0
- package/docs/api/type-aliases/FlowOnDataListener.md +33 -0
- package/docs/api/type-aliases/FlowOnErrorListener.md +27 -0
- package/docs/api/type-aliases/FlowOnPendingListener.md +21 -0
- package/docs/api/type-aliases/FlowReadonly.md +22 -0
- package/docs/api/type-aliases/InitFunction.md +21 -0
- package/docs/api/type-aliases/InitFunctionAsync.md +21 -0
- package/docs/api/type-aliases/NotPromise.md +6 -3
- package/docs/api/type-aliases/UpdateFunction.md +27 -0
- package/docs/api/type-aliases/UpdateFunctionAsync.md +27 -0
- package/docs/api/typedoc-sidebar.json +1 -81
- package/docs/examples/examples.md +0 -2
- package/docs/guide/advanced/architecture.md +1234 -0
- package/docs/guide/advanced/migration-v2.md +204 -0
- package/docs/guide/advanced/solidjs.md +2 -88
- package/docs/guide/introduction/concepts.md +4 -3
- package/docs/guide/introduction/conventions.md +2 -33
- package/docs/guide/introduction/getting-started.md +28 -23
- package/docs/guide/introduction/lifecycle.md +16 -19
- package/docs/guide/primitives/array.md +102 -216
- package/docs/guide/primitives/constant.md +39 -212
- package/docs/guide/primitives/derivations.md +55 -122
- package/docs/guide/primitives/effects.md +155 -241
- package/docs/guide/primitives/map.md +64 -186
- package/docs/guide/primitives/overview.md +45 -128
- package/docs/guide/primitives/signal.md +51 -88
- package/docs/guide/primitives/state.md +34 -130
- package/package.json +56 -60
- package/src/api/base/flowDisposable.ts +44 -0
- package/src/api/base/flowObservable.ts +28 -0
- package/src/api/base/flowSubscribable.ts +87 -0
- package/src/api/base/flowTracker.ts +7 -0
- package/src/api/base/index.ts +4 -0
- package/src/{flow → api}/index.ts +0 -1
- package/src/api/nodes/async/flowConstantAsync.ts +36 -0
- package/src/api/nodes/async/flowDerivationAsync.ts +42 -0
- package/src/api/nodes/async/flowStateAsync.ts +47 -0
- package/src/api/nodes/async/flowWritableDerivationAsync.ts +33 -0
- package/src/{flow → api}/nodes/async/index.ts +1 -2
- package/src/api/nodes/collections/flowArray.ts +155 -0
- package/src/api/nodes/collections/flowMap.ts +115 -0
- package/src/api/nodes/flowEffect.ts +42 -0
- package/src/api/nodes/flowSignal.ts +28 -0
- package/src/api/nodes/flowValue.ts +36 -0
- package/src/api/nodes/index.ts +7 -0
- package/src/api/nodes/sync/flowConstant.ts +33 -0
- package/src/api/nodes/sync/flowDerivation.ts +41 -0
- package/src/api/nodes/sync/flowState.ts +45 -0
- package/src/api/nodes/sync/flowWritableDerivation.ts +31 -0
- package/src/{flow → api}/nodes/sync/index.ts +1 -2
- package/src/api/nodes/utils.ts +22 -0
- package/src/base/disposable.ts +18 -0
- package/src/base/executionStack.ts +42 -0
- package/src/base/index.ts +5 -0
- package/src/base/node.ts +98 -0
- package/src/base/observable.ts +87 -0
- package/src/base/observer.ts +51 -0
- package/src/converters/index.ts +1 -0
- package/src/converters/solid.ts +109 -0
- package/src/index.ts +2 -64
- package/src/nodes/arrayNode.ts +172 -0
- package/src/nodes/effectNode.ts +59 -0
- package/src/nodes/index.ts +8 -0
- package/src/nodes/mapNode.ts +127 -0
- package/src/nodes/signalNode.ts +21 -0
- package/src/nodes/valueAsyncNode.ts +88 -0
- package/src/nodes/valueNode.ts +144 -0
- package/src/nodes/valueSyncNode.ts +128 -0
- package/src/schedulers/asyncResolver.ts +78 -0
- package/src/schedulers/asyncScheduler.ts +66 -0
- package/src/schedulers/index.ts +4 -0
- package/src/schedulers/pendingError.ts +13 -0
- package/src/schedulers/scheduler.ts +9 -0
- package/src/schedulers/syncResolver.ts +69 -0
- package/src/schedulers/syncScheduler.ts +55 -0
- package/test/base/pendingError.test.ts +67 -0
- package/test/converters/solid.derivation.browser.test.tsx +69 -0
- package/test/converters/solid.node.test.ts +654 -0
- package/test/converters/solid.state.browser.test.tsx +1592 -0
- package/test/reactivity/flowSignal.test.ts +226 -0
- package/test/reactivity/nodes/async/asyncScheduler/asyncResolver.test.ts +593 -0
- package/test/reactivity/nodes/async/asyncScheduler/asyncScheduler.test.ts +317 -0
- package/test/reactivity/nodes/async/flowConstantAsync.test.ts +652 -0
- package/test/reactivity/nodes/async/flowDerivation.test.ts +898 -0
- package/test/reactivity/nodes/async/flowDerivationAsync.test.ts +1716 -0
- package/test/reactivity/nodes/async/flowStateAsync.test.ts +708 -0
- package/test/reactivity/nodes/async/flowWritableDerivationAsync.test.ts +614 -0
- package/test/reactivity/nodes/collections/flowArray.asyncStates.test.ts +1289 -0
- package/test/reactivity/nodes/collections/flowArray.scalars.test.ts +961 -0
- package/test/reactivity/nodes/collections/flowArray.states.test.ts +1035 -0
- package/test/reactivity/nodes/collections/flowMap.asyncStates.test.ts +960 -0
- package/test/reactivity/nodes/collections/flowMap.scalars.test.ts +775 -0
- package/test/reactivity/nodes/collections/flowMap.states.test.ts +958 -0
- package/test/reactivity/nodes/sync/flowConstant.test.ts +377 -0
- package/test/reactivity/nodes/sync/flowDerivation.test.ts +896 -0
- package/test/reactivity/nodes/sync/flowState.test.ts +341 -0
- package/test/reactivity/nodes/sync/flowWritableDerivation.test.ts +603 -0
- package/test/vitest.d.ts +10 -0
- package/tsconfig.json +31 -20
- package/typedoc.json +35 -35
- package/vite.config.ts +25 -23
- package/vitest.browser.config.ts +21 -0
- package/vitest.config.ts +12 -12
- package/.cursor/plans/unifier-flowresource-avec-flowderivation-c9506e24.plan.md +0 -372
- package/.cursor/plans/update-js-e795d61b.plan.md +0 -567
- package/dist/types/flow/base/flowDisposable.d.ts +0 -67
- package/dist/types/flow/base/flowDisposable.d.ts.map +0 -1
- package/dist/types/flow/base/flowEffect.d.ts +0 -127
- package/dist/types/flow/base/flowEffect.d.ts.map +0 -1
- package/dist/types/flow/base/flowGraph.d.ts +0 -97
- package/dist/types/flow/base/flowGraph.d.ts.map +0 -1
- package/dist/types/flow/base/flowSignal.d.ts +0 -134
- package/dist/types/flow/base/flowSignal.d.ts.map +0 -1
- package/dist/types/flow/base/flowTracker.d.ts +0 -15
- package/dist/types/flow/base/flowTracker.d.ts.map +0 -1
- package/dist/types/flow/base/index.d.ts +0 -7
- package/dist/types/flow/base/index.d.ts.map +0 -1
- package/dist/types/flow/base/utils.d.ts +0 -20
- package/dist/types/flow/base/utils.d.ts.map +0 -1
- package/dist/types/flow/collections/flowArray.d.ts +0 -148
- package/dist/types/flow/collections/flowArray.d.ts.map +0 -1
- package/dist/types/flow/collections/flowMap.d.ts +0 -224
- package/dist/types/flow/collections/flowMap.d.ts.map +0 -1
- package/dist/types/flow/collections/index.d.ts.map +0 -1
- package/dist/types/flow/index.d.ts +0 -4
- package/dist/types/flow/index.d.ts.map +0 -1
- package/dist/types/flow/nodes/async/flowConstantAsync.d.ts +0 -137
- package/dist/types/flow/nodes/async/flowConstantAsync.d.ts.map +0 -1
- package/dist/types/flow/nodes/async/flowDerivationAsync.d.ts +0 -137
- package/dist/types/flow/nodes/async/flowDerivationAsync.d.ts.map +0 -1
- package/dist/types/flow/nodes/async/flowNodeAsync.d.ts +0 -343
- package/dist/types/flow/nodes/async/flowNodeAsync.d.ts.map +0 -1
- package/dist/types/flow/nodes/async/flowReadonlyAsync.d.ts +0 -81
- package/dist/types/flow/nodes/async/flowReadonlyAsync.d.ts.map +0 -1
- package/dist/types/flow/nodes/async/flowStateAsync.d.ts +0 -111
- package/dist/types/flow/nodes/async/flowStateAsync.d.ts.map +0 -1
- package/dist/types/flow/nodes/async/index.d.ts.map +0 -1
- package/dist/types/flow/nodes/index.d.ts +0 -3
- package/dist/types/flow/nodes/index.d.ts.map +0 -1
- package/dist/types/flow/nodes/sync/flowConstant.d.ts +0 -108
- package/dist/types/flow/nodes/sync/flowConstant.d.ts.map +0 -1
- package/dist/types/flow/nodes/sync/flowDerivation.d.ts +0 -100
- package/dist/types/flow/nodes/sync/flowDerivation.d.ts.map +0 -1
- package/dist/types/flow/nodes/sync/flowNode.d.ts +0 -314
- package/dist/types/flow/nodes/sync/flowNode.d.ts.map +0 -1
- package/dist/types/flow/nodes/sync/flowReadonly.d.ts +0 -57
- package/dist/types/flow/nodes/sync/flowReadonly.d.ts.map +0 -1
- package/dist/types/flow/nodes/sync/flowState.d.ts +0 -96
- package/dist/types/flow/nodes/sync/flowState.d.ts.map +0 -1
- package/dist/types/flow/nodes/sync/index.d.ts.map +0 -1
- package/dist/types/solid/converters.d.ts +0 -57
- package/dist/types/solid/converters.d.ts.map +0 -1
- package/dist/types/solid/index.d.ts +0 -3
- package/dist/types/solid/index.d.ts.map +0 -1
- package/dist/types/solid/primitives.d.ts +0 -181
- package/dist/types/solid/primitives.d.ts.map +0 -1
- package/docs/api/classes/FlowArray.md +0 -489
- package/docs/api/classes/FlowConstant.md +0 -350
- package/docs/api/classes/FlowDerivation.md +0 -334
- package/docs/api/classes/FlowEffect.md +0 -100
- package/docs/api/classes/FlowMap.md +0 -512
- package/docs/api/classes/FlowObservable.md +0 -306
- package/docs/api/classes/FlowResource.md +0 -380
- package/docs/api/classes/FlowResourceAsync.md +0 -362
- package/docs/api/classes/FlowSignal.md +0 -160
- package/docs/api/classes/FlowState.md +0 -368
- package/docs/api/classes/FlowStream.md +0 -367
- package/docs/api/classes/FlowStreamAsync.md +0 -364
- package/docs/api/classes/SolidDerivation.md +0 -75
- package/docs/api/classes/SolidResource.md +0 -91
- package/docs/api/classes/SolidState.md +0 -71
- package/docs/api/classes/TrackingContext.md +0 -33
- package/docs/api/functions/effect.md +0 -49
- package/docs/api/functions/resource.md +0 -52
- package/docs/api/functions/resourceAsync.md +0 -50
- package/docs/api/functions/stream.md +0 -53
- package/docs/api/functions/streamAsync.md +0 -50
- package/docs/api/interfaces/SolidObservable.md +0 -19
- package/docs/api/type-aliases/FlowStreamDisposer.md +0 -15
- package/docs/api/type-aliases/FlowStreamSetter.md +0 -27
- package/docs/api/type-aliases/FlowStreamUpdater.md +0 -32
- package/docs/api/type-aliases/SolidGetter.md +0 -17
- package/docs/guide/primitives/resources.md +0 -858
- package/docs/guide/primitives/streams.md +0 -931
- package/src/flow/base/flowDisposable.ts +0 -71
- package/src/flow/base/flowEffect.ts +0 -171
- package/src/flow/base/flowGraph.ts +0 -288
- package/src/flow/base/flowSignal.ts +0 -207
- package/src/flow/base/flowTracker.ts +0 -17
- package/src/flow/base/index.ts +0 -6
- package/src/flow/base/utils.ts +0 -19
- package/src/flow/collections/flowArray.ts +0 -409
- package/src/flow/collections/flowMap.ts +0 -398
- package/src/flow/nodes/async/flowConstantAsync.ts +0 -142
- package/src/flow/nodes/async/flowDerivationAsync.ts +0 -143
- package/src/flow/nodes/async/flowNodeAsync.ts +0 -474
- package/src/flow/nodes/async/flowReadonlyAsync.ts +0 -81
- package/src/flow/nodes/async/flowStateAsync.ts +0 -116
- package/src/flow/nodes/await/advanced/index.ts +0 -5
- package/src/flow/nodes/await/advanced/resource.ts +0 -134
- package/src/flow/nodes/await/advanced/resourceAsync.ts +0 -109
- package/src/flow/nodes/await/advanced/stream.ts +0 -188
- package/src/flow/nodes/await/advanced/streamAsync.ts +0 -176
- package/src/flow/nodes/await/flowConstantAwait.ts +0 -154
- package/src/flow/nodes/await/flowDerivationAwait.ts +0 -154
- package/src/flow/nodes/await/flowNodeAwait.ts +0 -508
- package/src/flow/nodes/await/flowReadonlyAwait.ts +0 -89
- package/src/flow/nodes/await/flowStateAwait.ts +0 -130
- package/src/flow/nodes/await/index.ts +0 -5
- package/src/flow/nodes/index.ts +0 -3
- package/src/flow/nodes/sync/flowConstant.ts +0 -111
- package/src/flow/nodes/sync/flowDerivation.ts +0 -105
- package/src/flow/nodes/sync/flowNode.ts +0 -439
- package/src/flow/nodes/sync/flowReadonly.ts +0 -57
- package/src/flow/nodes/sync/flowState.ts +0 -101
- package/src/solid/converters.ts +0 -148
- package/src/solid/index.ts +0 -2
- package/src/solid/primitives.ts +0 -215
- package/test/base/flowEffect.test.ts +0 -108
- package/test/base/flowGraph.test.ts +0 -485
- package/test/base/flowSignal.test.ts +0 -372
- package/test/collections/flowArray.asyncStates.test.ts +0 -1553
- package/test/collections/flowArray.scalars.test.ts +0 -1129
- package/test/collections/flowArray.states.test.ts +0 -1365
- package/test/collections/flowMap.asyncStates.test.ts +0 -1105
- package/test/collections/flowMap.scalars.test.ts +0 -877
- package/test/collections/flowMap.states.test.ts +0 -1097
- package/test/nodes/async/flowConstantAsync.test.ts +0 -860
- package/test/nodes/async/flowDerivationAsync.test.ts +0 -1517
- package/test/nodes/async/flowStateAsync.test.ts +0 -1387
- package/test/nodes/await/advanced/resource.test.ts +0 -129
- package/test/nodes/await/advanced/resourceAsync.test.ts +0 -108
- package/test/nodes/await/advanced/stream.test.ts +0 -198
- package/test/nodes/await/advanced/streamAsync.test.ts +0 -196
- package/test/nodes/await/flowConstantAwait.test.ts +0 -643
- package/test/nodes/await/flowDerivationAwait.test.ts +0 -1583
- package/test/nodes/await/flowStateAwait.test.ts +0 -999
- package/test/nodes/mixed/derivation.test.ts +0 -1527
- package/test/nodes/sync/flowConstant.test.ts +0 -620
- package/test/nodes/sync/flowDerivation.test.ts +0 -1373
- package/test/nodes/sync/flowState.test.ts +0 -945
- package/test/solid/converters.test.ts +0 -721
- package/test/solid/primitives.test.ts +0 -1031
- /package/dist/types/{flow → api/nodes}/collections/index.d.ts +0 -0
- /package/docs/guide/advanced/{upgrading.md → migration-v1.md} +0 -0
- /package/src/{flow → api/nodes}/collections/index.ts +0 -0
|
@@ -1,398 +0,0 @@
|
|
|
1
|
-
import { FlowGraph, isDisposable } from "../base";
|
|
2
|
-
import { FlowNode, type FlowState, state } from "../nodes";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Represents the actions that can be performed on a FlowMap.
|
|
6
|
-
* @public
|
|
7
|
-
*/
|
|
8
|
-
export type FlowMapAction<K, V> =
|
|
9
|
-
| {
|
|
10
|
-
type: "set";
|
|
11
|
-
map: Map<K, V>;
|
|
12
|
-
}
|
|
13
|
-
| {
|
|
14
|
-
type: "add";
|
|
15
|
-
key: K;
|
|
16
|
-
value: V;
|
|
17
|
-
}
|
|
18
|
-
| {
|
|
19
|
-
type: "update";
|
|
20
|
-
key: K;
|
|
21
|
-
value: V;
|
|
22
|
-
}
|
|
23
|
-
| {
|
|
24
|
-
type: "delete";
|
|
25
|
-
key: K;
|
|
26
|
-
value: V;
|
|
27
|
-
}
|
|
28
|
-
| {
|
|
29
|
-
type: "clear";
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Represents a reactive map that extends {@link FlowState} for tracking key-value pairs.
|
|
34
|
-
*
|
|
35
|
-
* @remarks
|
|
36
|
-
* FlowMap wraps a native JavaScript Map and provides reactive tracking at multiple granularity levels.
|
|
37
|
-
* Unlike plain reactive state, FlowMap offers fine-grained reactivity that lets you track:
|
|
38
|
-
*
|
|
39
|
-
* 1. **Whole map changes**: Via `get(t)` or `pick()` on the FlowMap itself
|
|
40
|
-
* 2. **Last action**: Via the `$lastAction` signal, track the most recent operation performed on the map
|
|
41
|
-
*
|
|
42
|
-
* **Reactive Signals:**
|
|
43
|
-
* - **$lastAction**: A FlowState containing a {@link FlowMapAction} that describes the most recent operation
|
|
44
|
-
* (set, add, update, delete, or clear) performed on the map
|
|
45
|
-
*
|
|
46
|
-
* These signals enable fine-grained reactivity patterns where effects can respond to specific
|
|
47
|
-
* map operations without re-processing the entire map.
|
|
48
|
-
*
|
|
49
|
-
* **Use Cases:**
|
|
50
|
-
* - Entity stores where you want to track additions/removals separately
|
|
51
|
-
* - Cache implementations with granular invalidation
|
|
52
|
-
* - Collections where operations on individual keys matter
|
|
53
|
-
* - UI state where you want to animate specific additions or removals
|
|
54
|
-
*
|
|
55
|
-
* @example
|
|
56
|
-
* ```typescript
|
|
57
|
-
* const $users = map<string, User>();
|
|
58
|
-
*
|
|
59
|
-
* // Track the whole map
|
|
60
|
-
* effect((t) => {
|
|
61
|
-
* const users = $users.get(t);
|
|
62
|
-
* console.log(`Total users: ${users.size}`);
|
|
63
|
-
* });
|
|
64
|
-
*
|
|
65
|
-
* // Track last action
|
|
66
|
-
* effect((t) => {
|
|
67
|
-
* const action = $users.$lastAction.get(t);
|
|
68
|
-
* switch (action.type) {
|
|
69
|
-
* case 'add':
|
|
70
|
-
* console.log(`User ${action.key} was added:`, action.value);
|
|
71
|
-
* break;
|
|
72
|
-
* case 'update':
|
|
73
|
-
* console.log(`User ${action.key} was updated:`, action.value);
|
|
74
|
-
* break;
|
|
75
|
-
* case 'delete':
|
|
76
|
-
* console.log(`User ${action.key} was deleted:`, action.value);
|
|
77
|
-
* break;
|
|
78
|
-
* case 'set':
|
|
79
|
-
* console.log('Map was replaced');
|
|
80
|
-
* break;
|
|
81
|
-
* case 'clear':
|
|
82
|
-
* console.log('Map was cleared');
|
|
83
|
-
* break;
|
|
84
|
-
* }
|
|
85
|
-
* });
|
|
86
|
-
*
|
|
87
|
-
* // Modify the map
|
|
88
|
-
* $users.add('user1', { name: 'John', age: 30 });
|
|
89
|
-
* $users.add('user2', { name: 'Jane', age: 25 });
|
|
90
|
-
* $users.update('user1', { name: 'John', age: 31 });
|
|
91
|
-
* $users.delete('user1');
|
|
92
|
-
* $users.clear();
|
|
93
|
-
* ```
|
|
94
|
-
*
|
|
95
|
-
* @typeParam K - The type of the map keys.
|
|
96
|
-
* @typeParam V - The type of the map values.
|
|
97
|
-
*
|
|
98
|
-
* @public
|
|
99
|
-
*/
|
|
100
|
-
export class FlowMap<K, V> extends FlowNode<Map<K, V>> {
|
|
101
|
-
/**
|
|
102
|
-
* Last action performed on the FlowMap.
|
|
103
|
-
* @public
|
|
104
|
-
*/
|
|
105
|
-
public $lastAction: FlowState<FlowMapAction<K, V>>;
|
|
106
|
-
protected declare _value: Map<K, V>;
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Creates an instance of FlowMap.
|
|
110
|
-
* @param value - Initial map value.
|
|
111
|
-
* @public
|
|
112
|
-
*/
|
|
113
|
-
constructor(value: Map<K, V> = new Map()) {
|
|
114
|
-
super(value);
|
|
115
|
-
this.$lastAction = state<FlowMapAction<K, V>>({
|
|
116
|
-
type: "set",
|
|
117
|
-
map: value,
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Adds a new key-value pair to the map.
|
|
123
|
-
*
|
|
124
|
-
* @param key - The key to add.
|
|
125
|
-
* @param value - The value to associate with the key.
|
|
126
|
-
* @throws If the FlowMap instance is disposed.
|
|
127
|
-
* @throws If the key already exists in the map.
|
|
128
|
-
*
|
|
129
|
-
* @remarks
|
|
130
|
-
* Adds a new entry to the internal map, emits the key-value pair via {@link FlowMap.$lastAction},
|
|
131
|
-
* and notifies all subscribers of the change.
|
|
132
|
-
*
|
|
133
|
-
* @public
|
|
134
|
-
*/
|
|
135
|
-
public async add(key: K, value: V): Promise<void> {
|
|
136
|
-
if (this._disposed) throw new Error("[PicoFlow] Primitive is disposed");
|
|
137
|
-
|
|
138
|
-
const update = () => {
|
|
139
|
-
// get value
|
|
140
|
-
const currentValue = this._value.get(key);
|
|
141
|
-
if (currentValue) {
|
|
142
|
-
throw new Error("[PicoFlow] Key already exists");
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// add key
|
|
146
|
-
this._value.set(key, value);
|
|
147
|
-
|
|
148
|
-
// emit last action
|
|
149
|
-
this.$lastAction.set({ type: "add", key, value });
|
|
150
|
-
|
|
151
|
-
// return value changed check
|
|
152
|
-
return true;
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
const notify = () => {
|
|
156
|
-
// call super method to avoid setting dirty flag back to true
|
|
157
|
-
super._notify();
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
return FlowGraph.requestWrite(notify, update);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Updates an existing key-value pair in the map.
|
|
165
|
-
*
|
|
166
|
-
* @param key - The key to update.
|
|
167
|
-
* @param value - The new value to associate with the key.
|
|
168
|
-
* @throws If the FlowMap instance is disposed.
|
|
169
|
-
* @throws If the key does not exist in the map.
|
|
170
|
-
*
|
|
171
|
-
* @remarks
|
|
172
|
-
* Updates an existing entry in the internal map, emits the key-value pair via {@link FlowMap.$lastAction},
|
|
173
|
-
* and notifies all subscribers of the change.
|
|
174
|
-
*
|
|
175
|
-
* @public
|
|
176
|
-
*/
|
|
177
|
-
public async update(key: K, value: V): Promise<void> {
|
|
178
|
-
if (this._disposed) throw new Error("[PicoFlow] Primitive is disposed");
|
|
179
|
-
|
|
180
|
-
const update = () => {
|
|
181
|
-
// get value
|
|
182
|
-
const currentValue = this._value.get(key);
|
|
183
|
-
if (!currentValue) throw new Error("[PicoFlow] Key does not exist");
|
|
184
|
-
|
|
185
|
-
if (currentValue !== value) {
|
|
186
|
-
// dispose value
|
|
187
|
-
if (isDisposable(currentValue)) currentValue.dispose({ self: true });
|
|
188
|
-
|
|
189
|
-
// update key
|
|
190
|
-
this._value.set(key, value);
|
|
191
|
-
|
|
192
|
-
// emit last action
|
|
193
|
-
this.$lastAction.set({ type: "update", key, value });
|
|
194
|
-
|
|
195
|
-
// return value changed check
|
|
196
|
-
return true;
|
|
197
|
-
}
|
|
198
|
-
return false;
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
const notify = () => {
|
|
202
|
-
// call super method to avoid setting dirty flag back to true
|
|
203
|
-
super._notify();
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
return FlowGraph.requestWrite(notify, update);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Deletes the value at the specified key from the underlying map.
|
|
211
|
-
*
|
|
212
|
-
* @param key - The key to delete.
|
|
213
|
-
* @throws If the FlowMap instance is disposed.
|
|
214
|
-
*
|
|
215
|
-
* @remarks
|
|
216
|
-
* Removes the key from the internal map, emits the deleted key and its value via {@link FlowMap.$lastAction},
|
|
217
|
-
* and notifies all subscribers of the change.
|
|
218
|
-
*
|
|
219
|
-
* @public
|
|
220
|
-
*/
|
|
221
|
-
public async delete(key: K): Promise<void> {
|
|
222
|
-
if (this._disposed) throw new Error("[PicoFlow] Primitive is disposed");
|
|
223
|
-
|
|
224
|
-
const update = () => {
|
|
225
|
-
// get value
|
|
226
|
-
const value = this._value.get(key);
|
|
227
|
-
if (value === undefined) throw new Error("[PicoFlow] Key does not exist");
|
|
228
|
-
|
|
229
|
-
// dispose value
|
|
230
|
-
if (isDisposable(value)) value.dispose({ self: true });
|
|
231
|
-
|
|
232
|
-
// delete key
|
|
233
|
-
this._value.delete(key);
|
|
234
|
-
|
|
235
|
-
// emit last action
|
|
236
|
-
this.$lastAction.set({ type: "delete", key, value });
|
|
237
|
-
|
|
238
|
-
// return value changed check
|
|
239
|
-
return true;
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
const notify = () => {
|
|
243
|
-
// call super method to avoid setting dirty flag back to true
|
|
244
|
-
super._notify();
|
|
245
|
-
};
|
|
246
|
-
|
|
247
|
-
return FlowGraph.requestWrite(notify, update);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Replaces the entire map with new entries.
|
|
252
|
-
*
|
|
253
|
-
* @param map - The new map of entries.
|
|
254
|
-
* @throws If the FlowMap instance is disposed.
|
|
255
|
-
*
|
|
256
|
-
* @remarks
|
|
257
|
-
* Replaces all entries in the internal map, disposes the old values (if they are disposable),
|
|
258
|
-
* emits the new map via {@link FlowMap.$lastAction}, and notifies all subscribers of the change.
|
|
259
|
-
*
|
|
260
|
-
* @public
|
|
261
|
-
*/
|
|
262
|
-
override async set(map: Map<K, V>): Promise<void> {
|
|
263
|
-
if (this._disposed) throw new Error("[PicoFlow] Primitive is disposed");
|
|
264
|
-
const update = () => {
|
|
265
|
-
// compute current value
|
|
266
|
-
const currentValue = this._value;
|
|
267
|
-
|
|
268
|
-
// dispose old values
|
|
269
|
-
if (currentValue !== map) {
|
|
270
|
-
currentValue.forEach((item) => {
|
|
271
|
-
if (isDisposable(item)) item.dispose({ self: true });
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// assign new map
|
|
276
|
-
this._value = map;
|
|
277
|
-
|
|
278
|
-
// emit last action
|
|
279
|
-
if (currentValue !== map) {
|
|
280
|
-
this.$lastAction.set({ type: "set", map: map });
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
// return value changed check
|
|
284
|
-
return currentValue !== map;
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
const notify = () => {
|
|
288
|
-
// call super method to avoid setting dirty flag back to true
|
|
289
|
-
super._notify();
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
return FlowGraph.requestWrite(notify, update);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Clears all entries from the map.
|
|
297
|
-
*
|
|
298
|
-
* @throws If the FlowMap instance is disposed.
|
|
299
|
-
*
|
|
300
|
-
* @remarks
|
|
301
|
-
* Removes all entries from the internal map, disposes the removed values (if they are disposable),
|
|
302
|
-
* emits a clear action via {@link FlowMap.$lastAction}, and notifies all subscribers of the change.
|
|
303
|
-
*
|
|
304
|
-
* @public
|
|
305
|
-
*/
|
|
306
|
-
public async clear(): Promise<void> {
|
|
307
|
-
if (this._disposed) throw new Error("[PicoFlow] Primitive is disposed");
|
|
308
|
-
|
|
309
|
-
const update = () => {
|
|
310
|
-
// dispose old values
|
|
311
|
-
const items = [...this._value.values()];
|
|
312
|
-
items.forEach((item) => {
|
|
313
|
-
if (isDisposable(item)) item.dispose({ self: true });
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
// clear map
|
|
317
|
-
this._value.clear();
|
|
318
|
-
|
|
319
|
-
// emit last action
|
|
320
|
-
this.$lastAction.set({ type: "clear" });
|
|
321
|
-
|
|
322
|
-
// return value changed check
|
|
323
|
-
return true;
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
const notify = () => {
|
|
327
|
-
// call super method to avoid setting dirty flag back to true
|
|
328
|
-
super._notify();
|
|
329
|
-
};
|
|
330
|
-
|
|
331
|
-
return FlowGraph.requestWrite(notify, update);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* Disposes the FlowMap and its values.
|
|
336
|
-
* @param options - Disposal options.
|
|
337
|
-
* @public
|
|
338
|
-
*/
|
|
339
|
-
override dispose(options?: { self: boolean }): void {
|
|
340
|
-
super.dispose(options);
|
|
341
|
-
this._value.forEach((item) => {
|
|
342
|
-
if (isDisposable(item)) item.dispose(options);
|
|
343
|
-
});
|
|
344
|
-
this._value.clear();
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
/**
|
|
349
|
-
* Creates a new reactive map state with fine-grained tracking of operations.
|
|
350
|
-
*
|
|
351
|
-
* @typeParam K - The type of the keys.
|
|
352
|
-
* @typeParam V - The type of the values.
|
|
353
|
-
* @param initial - An optional record of key-value pairs or a Map to initialize the map.
|
|
354
|
-
* @returns A new instance of {@link FlowMap}.
|
|
355
|
-
*
|
|
356
|
-
* @remarks
|
|
357
|
-
* A reactive map wraps a native JavaScript Map and provides multiple levels of reactivity:
|
|
358
|
-
* tracking the entire map, tracking individual set operations, and tracking individual
|
|
359
|
-
* delete operations. The initial record (if provided) is converted to a native Map.
|
|
360
|
-
* If a Map is provided, it is used directly.
|
|
361
|
-
*
|
|
362
|
-
* @example
|
|
363
|
-
* ```typescript
|
|
364
|
-
* const $users = map<string, User>({
|
|
365
|
-
* 'user1': { name: 'John', age: 30 }
|
|
366
|
-
* });
|
|
367
|
-
*
|
|
368
|
-
* // Or with a Map
|
|
369
|
-
* const $users2 = map<string, User>(new Map([['user1', { name: 'John', age: 30 }]]));
|
|
370
|
-
*
|
|
371
|
-
* // Track the whole map
|
|
372
|
-
* effect((t) => {
|
|
373
|
-
* console.log('Users:', $users.get(t).size);
|
|
374
|
-
* });
|
|
375
|
-
*
|
|
376
|
-
* // Track last action
|
|
377
|
-
* effect((t) => {
|
|
378
|
-
* const action = $users.$lastAction.get(t);
|
|
379
|
-
* if (action.type === 'add') {
|
|
380
|
-
* console.log(`Added: ${action.key}`);
|
|
381
|
-
* }
|
|
382
|
-
* });
|
|
383
|
-
*
|
|
384
|
-
* $users.add('user2', { name: 'Jane', age: 25 });
|
|
385
|
-
* ```
|
|
386
|
-
*
|
|
387
|
-
* @public
|
|
388
|
-
*/
|
|
389
|
-
export function map<K extends string | number | symbol, V>(
|
|
390
|
-
initial?: Record<K, V> | Map<K, V>,
|
|
391
|
-
): FlowMap<K, V> {
|
|
392
|
-
if (initial instanceof Map) {
|
|
393
|
-
return new FlowMap<K, V>(initial);
|
|
394
|
-
}
|
|
395
|
-
return new FlowMap<K, V>(
|
|
396
|
-
new Map<K, V>(initial ? (Object.entries(initial) as [K, V][]) : []),
|
|
397
|
-
);
|
|
398
|
-
}
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import { FlowNodeAsync } from "./flowNodeAsync";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Represents a constant value that can be computed lazily upon first access, with asynchronous values.
|
|
5
|
-
*
|
|
6
|
-
* @typeParam T - The type of the constant value (not the Promise itself).
|
|
7
|
-
*
|
|
8
|
-
* @remarks
|
|
9
|
-
* `FlowConstantAsync` is a type alias based on {@link FlowNodeAsync} with the `set()` and `refresh()`
|
|
10
|
-
* methods removed, making it immutable. It provides all the reactive capabilities of `FlowNodeAsync`
|
|
11
|
-
* (lazy computation, caching, dependency tracking) but prevents value mutation after initialization.
|
|
12
|
-
*
|
|
13
|
-
* Unlike {@link FlowStateAsync}, which is mutable via the `set()` method, a constant's value never
|
|
14
|
-
* changes after it's computed. This makes it ideal for values that should remain stable throughout
|
|
15
|
-
* the application lifecycle.
|
|
16
|
-
*
|
|
17
|
-
* **Asynchronous Nature:**
|
|
18
|
-
* All values in FlowConstantAsync are Promises. When you call `get()` or `pick()`, you receive a
|
|
19
|
-
* `Promise<T>` that you must await to get the actual value. This allows for seamless integration
|
|
20
|
-
* with async/await patterns and asynchronous data sources.
|
|
21
|
-
*
|
|
22
|
-
* **Lazy Computation:**
|
|
23
|
-
* Constants are created using the `constantAsync()` factory function, which accepts either a
|
|
24
|
-
* `Promise<T>` or a function returning `Promise<T>`. The computation doesn't run immediately
|
|
25
|
-
* upon creation when using a function. It executes only when:
|
|
26
|
-
* - The value is first read via `get()` or `pick()`
|
|
27
|
-
* - The constant is watched via `watch()`
|
|
28
|
-
* This allows you to defer expensive async computations until they're actually needed.
|
|
29
|
-
*
|
|
30
|
-
* **Initialization Patterns:**
|
|
31
|
-
* - **Constant Promise**: Pass a `Promise<T>` directly; it's stored immediately and can be accessed
|
|
32
|
-
* right away. The Promise resolves to the value of type T.
|
|
33
|
-
* - **Lazy initialization**: Pass a function `() => Promise<T>`; it's called only when the value
|
|
34
|
-
* is first accessed via `get()` or `pick()`. This is useful for expensive async operations that
|
|
35
|
-
* may not be needed immediately.
|
|
36
|
-
*
|
|
37
|
-
* **Caching:**
|
|
38
|
-
* Once computed (either immediately or lazily), the Promise is cached permanently. All subsequent
|
|
39
|
-
* accesses return the cached Promise without re-computation, ensuring the value remains constant
|
|
40
|
-
* and the computation runs only once.
|
|
41
|
-
*
|
|
42
|
-
* **Use Cases:**
|
|
43
|
-
* - Configuration values loaded asynchronously that don't change
|
|
44
|
-
* - Expensive async computations that should only run once
|
|
45
|
-
* - Initialization values for other reactive primitives
|
|
46
|
-
* - Values derived from external async sources that shouldn't be modified
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```typescript
|
|
50
|
-
* // Constant Promise - initialized immediately
|
|
51
|
-
* const $config = constantAsync(Promise.resolve({ apiUrl: 'https://api.example.com' }));
|
|
52
|
-
* const config = await $config.pick(); // Resolves immediately
|
|
53
|
-
*
|
|
54
|
-
* // Lazy initialization - computed on first access
|
|
55
|
-
* const $expensiveValue = constantAsync(async () => {
|
|
56
|
-
* console.log('Computing...');
|
|
57
|
-
* return await performExpensiveAsyncCalculation();
|
|
58
|
-
* });
|
|
59
|
-
*
|
|
60
|
-
* // First access triggers computation
|
|
61
|
-
* const value1 = await $expensiveValue.pick(); // Logs: "Computing..."
|
|
62
|
-
*
|
|
63
|
-
* // Subsequent accesses return cached Promise
|
|
64
|
-
* const value2 = await $expensiveValue.pick(); // No log - returns cached value
|
|
65
|
-
*
|
|
66
|
-
* // Value cannot be changed (set() method is not available)
|
|
67
|
-
* // $expensiveValue.set(Promise.resolve(100)); // TypeScript error: Property 'set' does not exist
|
|
68
|
-
* ```
|
|
69
|
-
*
|
|
70
|
-
* @public
|
|
71
|
-
*/
|
|
72
|
-
export type FlowConstantAsync<T> = Omit<FlowNodeAsync<T>, "set" | "refresh">;
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Creates a new reactive constant with lazy initialization support.
|
|
76
|
-
*
|
|
77
|
-
* @typeParam T - The type of the constant value (not the Promise itself).
|
|
78
|
-
*
|
|
79
|
-
* @param value - Either a `Promise<T>` for immediate initialization, or a function `() => Promise<T>`
|
|
80
|
-
* for lazy initialization. The function will be called only when the value is first accessed.
|
|
81
|
-
*
|
|
82
|
-
* @returns A new instance of {@link FlowConstantAsync} that provides reactive access to the computed value.
|
|
83
|
-
*
|
|
84
|
-
* @remarks
|
|
85
|
-
* Constants are immutable reactive values that are computed once and cached permanently. Unlike
|
|
86
|
-
* states (created with `stateAsync()`), constants cannot be modified after initialization - they don't
|
|
87
|
-
* have a `set()` method.
|
|
88
|
-
*
|
|
89
|
-
* **Asynchronous Nature:**
|
|
90
|
-
* All values are Promises. When you access the constant via `get(t)` or `pick()`, you receive a
|
|
91
|
-
* `Promise<T>` that you must await to get the actual value. This allows for seamless integration
|
|
92
|
-
* with async/await patterns and asynchronous data sources.
|
|
93
|
-
*
|
|
94
|
-
* **Lazy Computation:**
|
|
95
|
-
* When you provide a function, the computation is not executed immediately upon creation. It runs only when:
|
|
96
|
-
* - The value is first read via `get(t)` or `pick()`
|
|
97
|
-
* - The constant is watched via `watch()`
|
|
98
|
-
*
|
|
99
|
-
* This lazy computation is useful for:
|
|
100
|
-
* - Expensive async computations that may not be needed immediately
|
|
101
|
-
* - Values that depend on resources not available at construction time
|
|
102
|
-
* - Deferring async operations until the value is actually needed
|
|
103
|
-
*
|
|
104
|
-
* **When to Use Constants:**
|
|
105
|
-
* - Use `constantAsync()` for values that should never change after initialization
|
|
106
|
-
* - Use `stateAsync()` for mutable values that can be updated
|
|
107
|
-
* - Use `derivationAsync()` for values that recompute when dependencies change
|
|
108
|
-
*
|
|
109
|
-
* @example
|
|
110
|
-
* ```typescript
|
|
111
|
-
* // Eager initialization with Promise
|
|
112
|
-
* const $config = constantAsync(Promise.resolve({
|
|
113
|
-
* apiUrl: 'https://api.example.com'
|
|
114
|
-
* }));
|
|
115
|
-
* const config = await $config.pick();
|
|
116
|
-
*
|
|
117
|
-
* // Lazy initialization with async function
|
|
118
|
-
* const $expensiveValue = constantAsync(async () => {
|
|
119
|
-
* return await loadConfigurationFromFile();
|
|
120
|
-
* });
|
|
121
|
-
*
|
|
122
|
-
* // Computation hasn't run yet
|
|
123
|
-
* // First access triggers it
|
|
124
|
-
* const value = await $expensiveValue.pick();
|
|
125
|
-
*
|
|
126
|
-
* // Subsequent accesses return cached Promise
|
|
127
|
-
* const value2 = await $expensiveValue.pick();
|
|
128
|
-
*
|
|
129
|
-
* // Use in reactive context
|
|
130
|
-
* effect(async (t) => {
|
|
131
|
-
* const cfg = await $config.get(t);
|
|
132
|
-
* console.log(`API URL: ${cfg.apiUrl}`);
|
|
133
|
-
* });
|
|
134
|
-
* ```
|
|
135
|
-
*
|
|
136
|
-
* @public
|
|
137
|
-
*/
|
|
138
|
-
export function constantAsync<T>(
|
|
139
|
-
value: Promise<T> | (() => Promise<T>),
|
|
140
|
-
): FlowConstantAsync<T> {
|
|
141
|
-
return new FlowNodeAsync(value);
|
|
142
|
-
}
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import type { FlowTracker } from "../../base";
|
|
2
|
-
import { FlowNodeAsync } from "./flowNodeAsync";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Represents a reactive derivation whose value is computed based on other reactive signals, with asynchronous values.
|
|
6
|
-
*
|
|
7
|
-
* @typeParam T - The type of the computed value (not the Promise itself).
|
|
8
|
-
*
|
|
9
|
-
* @remarks
|
|
10
|
-
* `FlowDerivationAsync` is a type alias based on {@link FlowNodeAsync} with the `set()` method removed,
|
|
11
|
-
* making it immutable. It provides all the reactive capabilities of `FlowNodeAsync` (dependency tracking,
|
|
12
|
-
* lazy computation, caching) but prevents value mutation after initialization.
|
|
13
|
-
*
|
|
14
|
-
* Unlike {@link FlowConstantAsync}, which computes its value once and never changes, derivations
|
|
15
|
-
* automatically recompute when any tracked dependency changes. This makes them ideal for
|
|
16
|
-
* creating derived state that stays in sync with its sources.
|
|
17
|
-
*
|
|
18
|
-
* **Asynchronous Nature:**
|
|
19
|
-
* All values in FlowDerivationAsync are Promises. When you call `get()` or `pick()`, you receive a
|
|
20
|
-
* `Promise<T>` that you must await to get the actual value. The compute function must return a
|
|
21
|
-
* `Promise<T>`. This allows for seamless integration with async/await patterns and asynchronous
|
|
22
|
-
* data sources.
|
|
23
|
-
*
|
|
24
|
-
* **Lazy Computation:**
|
|
25
|
-
* The compute function doesn't run immediately upon creation. It executes only when:
|
|
26
|
-
* - The value is first read via `get()` or `pick()`
|
|
27
|
-
* - The derivation is watched via `watch()`
|
|
28
|
-
* This allows you to defer expensive async computations until they're actually needed.
|
|
29
|
-
*
|
|
30
|
-
* **Automatic Recomputation:**
|
|
31
|
-
* When a tracked dependency changes, the derivation is marked as "dirty" but doesn't recompute
|
|
32
|
-
* immediately. Recomputation happens lazily on the next value access. This prevents unnecessary
|
|
33
|
-
* computations when multiple dependencies change in quick succession. The Promise is cached until
|
|
34
|
-
* dependencies change, ensuring efficient access patterns. You can also force recomputation using
|
|
35
|
-
* the `refresh()` method.
|
|
36
|
-
*
|
|
37
|
-
* **Dynamic Dependencies:**
|
|
38
|
-
* Dependencies are tracked dynamically during each computation. If the compute function
|
|
39
|
-
* conditionally tracks different observables, the dependency graph updates automatically.
|
|
40
|
-
* When accessing async dependencies via `.get(t)`, you must await the returned Promise.
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* ```typescript
|
|
44
|
-
* const $firstName = stateAsync(Promise.resolve('John'));
|
|
45
|
-
* const $lastName = stateAsync(Promise.resolve('Doe'));
|
|
46
|
-
*
|
|
47
|
-
* const $fullName = derivationAsync(async (t) => {
|
|
48
|
-
* const first = await $firstName.get(t);
|
|
49
|
-
* const last = await $lastName.get(t);
|
|
50
|
-
* return `${first} ${last}`;
|
|
51
|
-
* });
|
|
52
|
-
*
|
|
53
|
-
* // Compute function hasn't run yet (lazy)
|
|
54
|
-
* const name = await $fullName.pick(); // Now it computes: "John Doe"
|
|
55
|
-
*
|
|
56
|
-
* // When dependencies change, derivation recomputes automatically
|
|
57
|
-
* await $firstName.set(Promise.resolve('Jane'));
|
|
58
|
-
* const newName = await $fullName.pick(); // "Jane Doe" (recomputed)
|
|
59
|
-
* ```
|
|
60
|
-
*
|
|
61
|
-
* @public
|
|
62
|
-
*/
|
|
63
|
-
|
|
64
|
-
export type FlowDerivationAsync<T> = Omit<FlowNodeAsync<T>, "set">;
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Creates a new reactive derivation whose value is computed based on other reactive signals.
|
|
68
|
-
*
|
|
69
|
-
* @typeParam T - The type of the derived value (not the Promise itself).
|
|
70
|
-
*
|
|
71
|
-
* @param fn - A function that computes the derived value using a tracking context. The function
|
|
72
|
-
* receives a tracking context (`t`) that should be used to access dependencies via `.get(t)`.
|
|
73
|
-
* The function must return a `Promise<T>`. The function is not executed immediately; it runs
|
|
74
|
-
* lazily on first access.
|
|
75
|
-
*
|
|
76
|
-
* @returns A new instance of {@link FlowDerivationAsync} that provides reactive access to the computed value.
|
|
77
|
-
*
|
|
78
|
-
* @remarks
|
|
79
|
-
* A derivation is a computed reactive value that automatically tracks its dependencies and
|
|
80
|
-
* recomputes when they change. The computation is lazy - it runs only when the value is
|
|
81
|
-
* accessed, not on construction. Use derivations to create derived state without manual
|
|
82
|
-
* dependency management.
|
|
83
|
-
*
|
|
84
|
-
* **Asynchronous Nature:**
|
|
85
|
-
* All values are Promises. When you access the derivation via `get(t)` or `pick()`, you receive a
|
|
86
|
-
* `Promise<T>` that you must await to get the actual value. The compute function must return a
|
|
87
|
-
* `Promise<T>`. When accessing async dependencies within the compute function, you must await
|
|
88
|
-
* the Promises returned by `.get(t)`.
|
|
89
|
-
*
|
|
90
|
-
* **Lazy Computation:**
|
|
91
|
-
* The compute function is not executed immediately upon creation. It runs only when:
|
|
92
|
-
* - The value is first read via `get(t)` or `pick()`
|
|
93
|
-
* - The derivation is watched via `watch()`
|
|
94
|
-
*
|
|
95
|
-
* This lazy computation is useful for:
|
|
96
|
-
* - Expensive async computations that may not be needed immediately
|
|
97
|
-
* - Values that depend on async resources
|
|
98
|
-
* - Deferring async operations until the value is actually needed
|
|
99
|
-
*
|
|
100
|
-
* **Automatic Recomputation:**
|
|
101
|
-
* When any tracked dependency changes, the derivation automatically recomputes on the next access.
|
|
102
|
-
* This ensures the derived value always stays in sync with its sources.
|
|
103
|
-
*
|
|
104
|
-
* **When to Use Derivations:**
|
|
105
|
-
* - Use `derivationAsync()` for values that should recompute when dependencies change
|
|
106
|
-
* - Use `constantAsync()` for values that compute once and never change
|
|
107
|
-
* - Use `stateAsync()` for mutable values that can be updated directly
|
|
108
|
-
*
|
|
109
|
-
* @example
|
|
110
|
-
* ```typescript
|
|
111
|
-
* const $firstName = stateAsync(Promise.resolve('John'));
|
|
112
|
-
* const $lastName = stateAsync(Promise.resolve('Doe'));
|
|
113
|
-
*
|
|
114
|
-
* const $fullName = derivationAsync(async (t) => {
|
|
115
|
-
* const first = await $firstName.get(t);
|
|
116
|
-
* const last = await $lastName.get(t);
|
|
117
|
-
* return `${first} ${last}`;
|
|
118
|
-
* });
|
|
119
|
-
*
|
|
120
|
-
* // Use in reactive context
|
|
121
|
-
* effect(async (t) => {
|
|
122
|
-
* const name = await $fullName.get(t);
|
|
123
|
-
* console.log(name); // Logs: "John Doe"
|
|
124
|
-
* });
|
|
125
|
-
*
|
|
126
|
-
* // When dependencies change, derivation recomputes automatically
|
|
127
|
-
* await $firstName.set(Promise.resolve('Jane')); // Logs: "Jane Doe"
|
|
128
|
-
*
|
|
129
|
-
* // Async data fetching example
|
|
130
|
-
* const $userId = stateAsync(Promise.resolve(1));
|
|
131
|
-
* const $user = derivationAsync(async (t) => {
|
|
132
|
-
* const id = await $userId.get(t);
|
|
133
|
-
* return await fetchUser(id);
|
|
134
|
-
* });
|
|
135
|
-
* ```
|
|
136
|
-
*
|
|
137
|
-
* @public
|
|
138
|
-
*/
|
|
139
|
-
export function derivationAsync<T>(
|
|
140
|
-
fn: (t: FlowTracker) => Promise<T>,
|
|
141
|
-
): FlowDerivationAsync<T> {
|
|
142
|
-
return new FlowNodeAsync(fn);
|
|
143
|
-
}
|