@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,134 +0,0 @@
|
|
|
1
|
-
import { FlowObservableAsync } from "../async";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Represents a reactive resource that asynchronously fetches its value and returns `T | undefined`.
|
|
5
|
-
*
|
|
6
|
-
* @remarks
|
|
7
|
-
* FlowResource extends FlowObservable to manage asynchronous data fetching with reactive updates.
|
|
8
|
-
* Unlike {@link FlowResourceAsync} which always returns a Promise, FlowResource returns the resolved
|
|
9
|
-
* value directly (or `undefined` if not yet fetched), making it more convenient for synchronous access
|
|
10
|
-
* patterns in effects and derivations.
|
|
11
|
-
*
|
|
12
|
-
* **Key Characteristics:**
|
|
13
|
-
* - The value is `undefined` initially, before the first fetch
|
|
14
|
-
* - Call `fetch()` to trigger the asynchronous fetch operation
|
|
15
|
-
* - When fetched, the value is compared to the current value; only different values trigger updates
|
|
16
|
-
* - Reading via `get(t)` or `pick()` returns the current value (possibly `undefined`) without triggering a fetch
|
|
17
|
-
*
|
|
18
|
-
* **Fetch Behavior:**
|
|
19
|
-
* The fetch function is NOT called automatically on construction. You must explicitly call the
|
|
20
|
-
* `fetch()` method to retrieve the resource. This gives you control over when network requests
|
|
21
|
-
* or expensive async operations occur.
|
|
22
|
-
*
|
|
23
|
-
* **Use Cases:**
|
|
24
|
-
* - API data fetching where you want synchronous access to the cached value
|
|
25
|
-
* - Lazy-loaded data that shouldn't fetch on construction
|
|
26
|
-
* - Resources that need manual refresh control
|
|
27
|
-
* - Data that may or may not be available (hence `T | undefined`)
|
|
28
|
-
*
|
|
29
|
-
* @example
|
|
30
|
-
* ```typescript
|
|
31
|
-
* const $user = resource(() => fetchUserFromAPI());
|
|
32
|
-
*
|
|
33
|
-
* // Initially undefined
|
|
34
|
-
* console.log($user.pick()); // undefined
|
|
35
|
-
*
|
|
36
|
-
* // Trigger the fetch
|
|
37
|
-
* await $user.fetch();
|
|
38
|
-
* console.log($user.pick()); // { id: 1, name: 'John' }
|
|
39
|
-
*
|
|
40
|
-
* // Use in an effect
|
|
41
|
-
* effect((t) => {
|
|
42
|
-
* const user = $user.get(t);
|
|
43
|
-
* if (user) {
|
|
44
|
-
* console.log(`Hello, ${user.name}`);
|
|
45
|
-
* }
|
|
46
|
-
* });
|
|
47
|
-
*
|
|
48
|
-
* // Refetch to update
|
|
49
|
-
* await $user.fetch();
|
|
50
|
-
* ```
|
|
51
|
-
*
|
|
52
|
-
* @typeParam T - The type of the resource value (not including the undefined case).
|
|
53
|
-
*
|
|
54
|
-
* @public
|
|
55
|
-
*/
|
|
56
|
-
export class FlowResource<T> extends FlowObservableAsync<T | undefined> {
|
|
57
|
-
/**
|
|
58
|
-
* Creates a new FlowResource.
|
|
59
|
-
*
|
|
60
|
-
* @param fetch - An asynchronous function that retrieves the resource's value.
|
|
61
|
-
* This function is not invoked on construction; you must call the `fetch()` method
|
|
62
|
-
* to execute it.
|
|
63
|
-
*
|
|
64
|
-
* @public
|
|
65
|
-
*/
|
|
66
|
-
constructor(fetch: () => Promise<T>) {
|
|
67
|
-
super();
|
|
68
|
-
this._fetch = fetch;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Internal method to get the raw value.
|
|
73
|
-
* @internal
|
|
74
|
-
*/
|
|
75
|
-
protected _getRaw(): T | undefined {
|
|
76
|
-
if (this._disposed) throw new Error("[PicoFlow] Primitive is disposed");
|
|
77
|
-
return this._value;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Asynchronously fetches a new value for the resource.
|
|
82
|
-
* @remarks
|
|
83
|
-
* Executes the internal fetch function. If the fetched value differs from the current one,
|
|
84
|
-
* updates the resource's value and notifies subscribers.
|
|
85
|
-
* @returns A Promise that resolves when the fetch operation is complete.
|
|
86
|
-
* @throws Error if the resource is disposed.
|
|
87
|
-
* @public
|
|
88
|
-
*/
|
|
89
|
-
public async fetch(): Promise<void> {
|
|
90
|
-
if (this._disposed) throw new Error("[PicoFlow] Primitive is disposed");
|
|
91
|
-
const value = await this._fetch();
|
|
92
|
-
if (value === this._value) return;
|
|
93
|
-
this._value = value;
|
|
94
|
-
this.trigger();
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/* INTERNAL ------------------------------------------------ */
|
|
98
|
-
|
|
99
|
-
private _fetch: () => Promise<T>;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Creates a new reactive resource that asynchronously fetches its value, returning `T | undefined`.
|
|
104
|
-
*
|
|
105
|
-
* @typeParam T - The type of the resource value.
|
|
106
|
-
* @param fn - An asynchronous function that fetches the resource value.
|
|
107
|
-
* @returns A new instance of {@link FlowResource}.
|
|
108
|
-
*
|
|
109
|
-
* @remarks
|
|
110
|
-
* A resource manages async data fetching with reactive updates. Unlike {@link resourceAsync},
|
|
111
|
-
* this returns the resolved value directly (or `undefined` if not fetched yet), making it
|
|
112
|
-
* easier to work with in synchronous contexts. Call `fetch()` to trigger the async operation.
|
|
113
|
-
*
|
|
114
|
-
* @example
|
|
115
|
-
* ```typescript
|
|
116
|
-
* const $user = resource(() => fetch('/api/user').then(r => r.json()));
|
|
117
|
-
*
|
|
118
|
-
* // Trigger fetch
|
|
119
|
-
* await $user.fetch();
|
|
120
|
-
*
|
|
121
|
-
* // Use in effect
|
|
122
|
-
* effect((t) => {
|
|
123
|
-
* const user = $user.get(t);
|
|
124
|
-
* if (user) {
|
|
125
|
-
* console.log(user.name);
|
|
126
|
-
* }
|
|
127
|
-
* });
|
|
128
|
-
* ```
|
|
129
|
-
*
|
|
130
|
-
* @public
|
|
131
|
-
*/
|
|
132
|
-
export function resource<T>(fn: () => Promise<T>): FlowResource<T> {
|
|
133
|
-
return new FlowResource(fn);
|
|
134
|
-
}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { FlowObservableAsync } from "../async";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Represents a reactive resource that asynchronously fetches its value and always returns a Promise.
|
|
5
|
-
*
|
|
6
|
-
* @remarks
|
|
7
|
-
* FlowResourceAsync extends FlowObservable and encapsulates an asynchronous fetch function.
|
|
8
|
-
* Unlike {@link FlowResource} which returns `T | undefined`, FlowResourceAsync always returns
|
|
9
|
-
* a `Promise<T>`, making it suitable for async/await patterns.
|
|
10
|
-
*
|
|
11
|
-
* **Key Characteristics:**
|
|
12
|
-
* - The first call to `get()` or `pick()` creates and caches a Promise
|
|
13
|
-
* - Subsequent calls return the same Promise until `fetch()` is called
|
|
14
|
-
* - Calling `fetch()` creates a new Promise and notifies subscribers
|
|
15
|
-
* - The Promise resolves to the fetched value of type T
|
|
16
|
-
*
|
|
17
|
-
* **Lazy Promise Creation:**
|
|
18
|
-
* The fetch function doesn't execute until the resource's value is first accessed.
|
|
19
|
-
* This allows you to define resources without immediately triggering network requests.
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```typescript
|
|
23
|
-
* const $user = resourceAsync(() => fetchUserFromAPI());
|
|
24
|
-
*
|
|
25
|
-
* effect(async (t) => {
|
|
26
|
-
* const user = await $user.get(t); // Tracked, effect re-runs on fetch()
|
|
27
|
-
* console.log(user.name);
|
|
28
|
-
* });
|
|
29
|
-
*
|
|
30
|
-
* // Trigger a refetch
|
|
31
|
-
* await $user.fetch();
|
|
32
|
-
* ```
|
|
33
|
-
*
|
|
34
|
-
* @typeParam T - The type of the resource value (not the Promise itself).
|
|
35
|
-
*
|
|
36
|
-
* @public
|
|
37
|
-
*/
|
|
38
|
-
export class FlowResourceAsync<T> extends FlowObservableAsync<Promise<T>> {
|
|
39
|
-
/**
|
|
40
|
-
* Creates a new FlowResource.
|
|
41
|
-
* @param fetch - An asynchronous function that retrieves the resource's value.
|
|
42
|
-
* @public
|
|
43
|
-
*/
|
|
44
|
-
constructor(fetch: () => Promise<T>) {
|
|
45
|
-
super();
|
|
46
|
-
this._fetch = fetch;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Internal method to get the raw value.
|
|
51
|
-
* @internal
|
|
52
|
-
*/
|
|
53
|
-
protected _getRaw(): Promise<T> {
|
|
54
|
-
if (this._disposed) throw new Error("[PicoFlow] Primitive is disposed");
|
|
55
|
-
if (!this._value) this._value = this._fetch();
|
|
56
|
-
return this._value;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Asynchronously fetches a new value for the resource.
|
|
61
|
-
* @remarks
|
|
62
|
-
* Executes the internal fetch function. If the fetched value differs from the current one,
|
|
63
|
-
* updates the resource's value and notifies subscribers.
|
|
64
|
-
* @returns A Promise that resolves when the fetch operation is complete.
|
|
65
|
-
* @throws Error if the resource is disposed.
|
|
66
|
-
* @public
|
|
67
|
-
*/
|
|
68
|
-
public async fetch(): Promise<void> {
|
|
69
|
-
if (this._disposed) throw new Error("[PicoFlow] Primitive is disposed");
|
|
70
|
-
this._value = this._fetch();
|
|
71
|
-
this.trigger();
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/* INTERNAL ------------------------------------------------ */
|
|
75
|
-
|
|
76
|
-
private _fetch: () => Promise<T>;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Creates a new reactive asynchronous resource that always returns a Promise.
|
|
81
|
-
*
|
|
82
|
-
* @typeParam T - The type of the resource value.
|
|
83
|
-
* @param fn - An asynchronous function that fetches the resource value.
|
|
84
|
-
* @returns A new instance of {@link FlowResourceAsync}.
|
|
85
|
-
*
|
|
86
|
-
* @remarks
|
|
87
|
-
* An async resource manages async data fetching and always returns a Promise, making it
|
|
88
|
-
* ideal for async/await patterns. Unlike {@link resource}, the Promise is created lazily
|
|
89
|
-
* on first access and cached. Call `fetch()` to create a new Promise and trigger a refetch.
|
|
90
|
-
*
|
|
91
|
-
* @example
|
|
92
|
-
* ```typescript
|
|
93
|
-
* const $data = resourceAsync(() => fetch('/api/data').then(r => r.json()));
|
|
94
|
-
*
|
|
95
|
-
* // Use with async/await
|
|
96
|
-
* effect(async (t) => {
|
|
97
|
-
* const data = await $data.get(t);
|
|
98
|
-
* console.log(data);
|
|
99
|
-
* });
|
|
100
|
-
*
|
|
101
|
-
* // Refetch
|
|
102
|
-
* await $data.fetch();
|
|
103
|
-
* ```
|
|
104
|
-
*
|
|
105
|
-
* @public
|
|
106
|
-
*/
|
|
107
|
-
export function resourceAsync<T>(fn: () => Promise<T>): FlowResourceAsync<T> {
|
|
108
|
-
return new FlowResourceAsync(fn);
|
|
109
|
-
}
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
import { FlowObservable } from "../sync";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* A function type that sets a new value for the reactive stream.
|
|
5
|
-
* @typeParam T - The type of the value.
|
|
6
|
-
* @public
|
|
7
|
-
*/
|
|
8
|
-
export type FlowStreamSetter<T> = (value: T) => void;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* A function type that disposes of a resource.
|
|
12
|
-
* @public
|
|
13
|
-
*/
|
|
14
|
-
export type FlowStreamDisposer = () => void;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* A function type that updates a stream and returns a disposer for cleanup.
|
|
18
|
-
* @remarks
|
|
19
|
-
* The updater receives a setter function to update the stream's value.
|
|
20
|
-
* It should return a disposer function to release any resources or subscriptions.
|
|
21
|
-
* @typeParam T - The type of the stream value.
|
|
22
|
-
* @public
|
|
23
|
-
*/
|
|
24
|
-
export type FlowStreamUpdater<T> = (
|
|
25
|
-
set: FlowStreamSetter<T>,
|
|
26
|
-
) => FlowStreamDisposer;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Represents a reactive stream that updates its value based on an external updater function.
|
|
30
|
-
*
|
|
31
|
-
* @remarks
|
|
32
|
-
* FlowStream extends FlowObservable to bridge external event sources with PicoFlow's reactive
|
|
33
|
-
* system. It's designed for integrating with event emitters, WebSocket connections, timers,
|
|
34
|
-
* or any push-based data source that sends updates over time.
|
|
35
|
-
*
|
|
36
|
-
* **How It Works:**
|
|
37
|
-
* 1. You provide an updater function that receives a setter callback
|
|
38
|
-
* 2. The updater sets up subscriptions to external events and calls the setter with new values
|
|
39
|
-
* 3. When the setter is called, the stream notifies all dependent effects and derivations
|
|
40
|
-
* 4. The updater returns a disposer function for cleanup
|
|
41
|
-
*
|
|
42
|
-
* **Initial Value:**
|
|
43
|
-
* The stream's value is `undefined` until the first time the setter is called. This allows
|
|
44
|
-
* you to check if any data has been received yet.
|
|
45
|
-
*
|
|
46
|
-
* **Change Detection:**
|
|
47
|
-
* The stream only notifies subscribers when the new value differs from the current value
|
|
48
|
-
* (using strict equality `===`). This prevents unnecessary updates for duplicate values.
|
|
49
|
-
*
|
|
50
|
-
* **Resource Management:**
|
|
51
|
-
* The disposer function returned by your updater is automatically called when the stream
|
|
52
|
-
* is disposed. Use it to clean up subscriptions, close connections, or clear timers.
|
|
53
|
-
*
|
|
54
|
-
* **Use Cases:**
|
|
55
|
-
* - WebSocket message streams
|
|
56
|
-
* - DOM event listeners
|
|
57
|
-
* - setInterval/setTimeout timers
|
|
58
|
-
* - Server-sent events (SSE)
|
|
59
|
-
* - Observable subscriptions from other libraries
|
|
60
|
-
* - Any push-based data source
|
|
61
|
-
*
|
|
62
|
-
* @example
|
|
63
|
-
* ```typescript
|
|
64
|
-
* // WebSocket stream
|
|
65
|
-
* const $messages = stream<string>((set) => {
|
|
66
|
-
* const ws = new WebSocket('ws://example.com');
|
|
67
|
-
* ws.onmessage = (event) => set(event.data);
|
|
68
|
-
* return () => ws.close();
|
|
69
|
-
* });
|
|
70
|
-
*
|
|
71
|
-
* // Timer stream
|
|
72
|
-
* const $tick = stream<number>((set) => {
|
|
73
|
-
* let count = 0;
|
|
74
|
-
* const id = setInterval(() => set(count++), 1000);
|
|
75
|
-
* return () => clearInterval(id);
|
|
76
|
-
* });
|
|
77
|
-
*
|
|
78
|
-
* // DOM event stream
|
|
79
|
-
* const $clicks = stream<MouseEvent>((set) => {
|
|
80
|
-
* const handler = (e: MouseEvent) => set(e);
|
|
81
|
-
* document.addEventListener('click', handler);
|
|
82
|
-
* return () => document.removeEventListener('click', handler);
|
|
83
|
-
* });
|
|
84
|
-
*
|
|
85
|
-
* // Use in an effect
|
|
86
|
-
* effect((t) => {
|
|
87
|
-
* const message = $messages.get(t);
|
|
88
|
-
* if (message) {
|
|
89
|
-
* console.log('Received:', message);
|
|
90
|
-
* }
|
|
91
|
-
* });
|
|
92
|
-
* ```
|
|
93
|
-
*
|
|
94
|
-
* @typeParam T - The type of the values emitted by the stream.
|
|
95
|
-
* @public
|
|
96
|
-
*/
|
|
97
|
-
export class FlowStream<T> extends FlowObservable<T | undefined> {
|
|
98
|
-
/**
|
|
99
|
-
* Creates a new FlowStream.
|
|
100
|
-
*
|
|
101
|
-
* @param updater - A function that receives a setter callback and returns a disposer.
|
|
102
|
-
* The setter should be called whenever new data is available. The disposer will be
|
|
103
|
-
* invoked when the stream is disposed to clean up resources.
|
|
104
|
-
*
|
|
105
|
-
* @remarks
|
|
106
|
-
* The updater is invoked immediately during construction. Make sure to return a proper
|
|
107
|
-
* cleanup function to avoid resource leaks.
|
|
108
|
-
*
|
|
109
|
-
* @public
|
|
110
|
-
*/
|
|
111
|
-
constructor(updater: FlowStreamUpdater<T>) {
|
|
112
|
-
super();
|
|
113
|
-
this._disposer = updater((value: T) => {
|
|
114
|
-
this._set(value);
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Internal method to get the raw value.
|
|
120
|
-
* @internal
|
|
121
|
-
*/
|
|
122
|
-
protected _getRaw(): T | undefined {
|
|
123
|
-
if (this._disposed) throw new Error("[PicoFlow] Primitive is disposed");
|
|
124
|
-
return this._value;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Disposes the stream, releasing all resources.
|
|
129
|
-
* @remarks
|
|
130
|
-
* In addition to disposing the underlying observable, this method calls the disposer
|
|
131
|
-
* returned by the updater.
|
|
132
|
-
* @public
|
|
133
|
-
*/
|
|
134
|
-
public override dispose(): void {
|
|
135
|
-
super.dispose();
|
|
136
|
-
this._disposer();
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/* INTERNAL ------------------------------------------------------ */
|
|
140
|
-
|
|
141
|
-
private _disposer: FlowStreamDisposer;
|
|
142
|
-
|
|
143
|
-
private _set(value: T): void {
|
|
144
|
-
/* v8 ignore next */
|
|
145
|
-
if (this._disposed) throw new Error("[PicoFlow] Primitive is disposed");
|
|
146
|
-
if (value === this._value) return;
|
|
147
|
-
this._value = value;
|
|
148
|
-
this.trigger();
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Creates a new reactive stream that bridges external event sources with PicoFlow's reactive system.
|
|
154
|
-
*
|
|
155
|
-
* @typeParam T - The type of the stream value.
|
|
156
|
-
* @param updater - A function that receives a setter to update the stream's value.
|
|
157
|
-
* It should return a disposer function to clean up resources.
|
|
158
|
-
* @returns A new instance of {@link FlowStream}.
|
|
159
|
-
*
|
|
160
|
-
* @remarks
|
|
161
|
-
* Streams are ideal for integrating push-based data sources like WebSockets, DOM events,
|
|
162
|
-
* timers, or any event emitter. The updater sets up subscriptions and calls the setter
|
|
163
|
-
* when new data arrives. The returned disposer is called on cleanup.
|
|
164
|
-
*
|
|
165
|
-
* @example
|
|
166
|
-
* ```typescript
|
|
167
|
-
* // WebSocket stream
|
|
168
|
-
* const $messages = stream<string>((set) => {
|
|
169
|
-
* const ws = new WebSocket('ws://example.com');
|
|
170
|
-
* ws.onmessage = (e) => set(e.data);
|
|
171
|
-
* return () => ws.close();
|
|
172
|
-
* });
|
|
173
|
-
*
|
|
174
|
-
* // Timer stream
|
|
175
|
-
* const $tick = stream<number>((set) => {
|
|
176
|
-
* let count = 0;
|
|
177
|
-
* const id = setInterval(() => set(count++), 1000);
|
|
178
|
-
* return () => clearInterval(id);
|
|
179
|
-
* });
|
|
180
|
-
* ```
|
|
181
|
-
*
|
|
182
|
-
* @public
|
|
183
|
-
*/
|
|
184
|
-
export function stream<T>(
|
|
185
|
-
updater: (set: (value: T) => void) => () => void,
|
|
186
|
-
): FlowStream<T> {
|
|
187
|
-
return new FlowStream(updater);
|
|
188
|
-
}
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import { FlowObservable } from "../sync";
|
|
2
|
-
import type { FlowStreamDisposer, FlowStreamUpdater } from "./stream";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Represents an asynchronous reactive stream that always returns a Promise and updates based on an updater function.
|
|
6
|
-
*
|
|
7
|
-
* @remarks
|
|
8
|
-
* FlowStreamAsync extends FlowObservable to bridge external async event sources with PicoFlow's
|
|
9
|
-
* reactive system. Unlike {@link FlowStream} which returns `T | undefined`, FlowStreamAsync always
|
|
10
|
-
* returns a `Promise<T>`, making it suitable for use with async/await patterns.
|
|
11
|
-
*
|
|
12
|
-
* **How It Works:**
|
|
13
|
-
* 1. On construction, creates an initial Promise that resolves when the first value arrives
|
|
14
|
-
* 2. Your updater function receives a setter callback and sets up event subscriptions
|
|
15
|
-
* 3. When the setter is called with a value, the Promise resolves (first call) or a new Promise is created (subsequent calls)
|
|
16
|
-
* 4. The updater returns a disposer function for cleanup
|
|
17
|
-
*
|
|
18
|
-
* **Promise Behavior:**
|
|
19
|
-
* - **First call to setter**: Resolves the initial Promise created at construction
|
|
20
|
-
* - **Subsequent calls**: Creates a new `Promise.resolve(value)` for immediate resolution
|
|
21
|
-
* - **Reading the value**: Always returns a Promise, either pending (initial) or resolved
|
|
22
|
-
*
|
|
23
|
-
* **Change Detection:**
|
|
24
|
-
* After the first value is set, the stream only notifies subscribers when the new value
|
|
25
|
-
* differs from the previous value (using strict equality `===`). This prevents unnecessary
|
|
26
|
-
* updates for duplicate values.
|
|
27
|
-
*
|
|
28
|
-
* **Resource Management:**
|
|
29
|
-
* The disposer function returned by your updater is automatically called when the stream
|
|
30
|
-
* is disposed. Use it to clean up subscriptions, close connections, or clear timers.
|
|
31
|
-
*
|
|
32
|
-
* **Use Cases:**
|
|
33
|
-
* - Async WebSocket message streams
|
|
34
|
-
* - Server-sent events that you want to await
|
|
35
|
-
* - Async event handlers
|
|
36
|
-
* - Integration with async iterators
|
|
37
|
-
* - Any push-based async data source
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
* ```typescript
|
|
41
|
-
* // Async WebSocket stream
|
|
42
|
-
* const $messages = streamAsync<string>((set) => {
|
|
43
|
-
* const ws = new WebSocket('ws://example.com');
|
|
44
|
-
* ws.onmessage = (event) => set(event.data);
|
|
45
|
-
* return () => ws.close();
|
|
46
|
-
* });
|
|
47
|
-
*
|
|
48
|
-
* // Use with async/await
|
|
49
|
-
* effect(async (t) => {
|
|
50
|
-
* const message = await $messages.get(t);
|
|
51
|
-
* console.log('Received:', message);
|
|
52
|
-
* });
|
|
53
|
-
*
|
|
54
|
-
* // Wait for the first message
|
|
55
|
-
* const firstMessage = await $messages.pick();
|
|
56
|
-
* console.log('First message:', firstMessage);
|
|
57
|
-
*
|
|
58
|
-
* // Async timer stream
|
|
59
|
-
* const $asyncTick = streamAsync<number>((set) => {
|
|
60
|
-
* let count = 0;
|
|
61
|
-
* const id = setInterval(() => set(count++), 1000);
|
|
62
|
-
* return () => clearInterval(id);
|
|
63
|
-
* });
|
|
64
|
-
* ```
|
|
65
|
-
*
|
|
66
|
-
* @typeParam T - The type of the values emitted by the stream (not the Promise itself).
|
|
67
|
-
* @public
|
|
68
|
-
*/
|
|
69
|
-
export class FlowStreamAsync<T> extends FlowObservable<Promise<T>> {
|
|
70
|
-
/**
|
|
71
|
-
* Creates a new asynchronous FlowStream.
|
|
72
|
-
*
|
|
73
|
-
* @param updater - A function that receives a setter callback and returns a disposer.
|
|
74
|
-
* The setter should be called whenever new data is available (can be called asynchronously).
|
|
75
|
-
* The disposer will be invoked when the stream is disposed to clean up resources.
|
|
76
|
-
*
|
|
77
|
-
* @remarks
|
|
78
|
-
* The updater is invoked immediately during construction. An initial Promise is created
|
|
79
|
-
* that will resolve when the setter is first called. Make sure to return a proper cleanup
|
|
80
|
-
* function to avoid resource leaks.
|
|
81
|
-
*
|
|
82
|
-
* @public
|
|
83
|
-
*/
|
|
84
|
-
constructor(updater: FlowStreamUpdater<T>) {
|
|
85
|
-
super();
|
|
86
|
-
this._disposer = updater((value: T) => {
|
|
87
|
-
this._set(value);
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
this._value = new Promise((resolve) => {
|
|
91
|
-
this._resolve = resolve;
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Internal method to get the raw value.
|
|
97
|
-
* @internal
|
|
98
|
-
*/
|
|
99
|
-
protected _getRaw(): Promise<T> {
|
|
100
|
-
if (this._disposed) throw new Error("[PicoFlow] Primitive is disposed");
|
|
101
|
-
return this._value;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Disposes the stream, releasing all resources.
|
|
106
|
-
* @remarks In addition to disposing the underlying observable, this method calls the disposer
|
|
107
|
-
* returned by the updater.
|
|
108
|
-
* @public
|
|
109
|
-
*/
|
|
110
|
-
public override dispose(): void {
|
|
111
|
-
super.dispose();
|
|
112
|
-
this._disposer();
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/* INTERNAL ------------------------------------------------------ */
|
|
116
|
-
|
|
117
|
-
private _initialized = false;
|
|
118
|
-
private _awaitedValue?: T;
|
|
119
|
-
|
|
120
|
-
private _resolve!: (value: T) => void;
|
|
121
|
-
private _disposer: FlowStreamDisposer;
|
|
122
|
-
|
|
123
|
-
private _set(value: T): void {
|
|
124
|
-
/* v8 ignore next */
|
|
125
|
-
if (this._disposed) throw new Error("[PicoFlow] Primitive is disposed");
|
|
126
|
-
|
|
127
|
-
if (!this._initialized) {
|
|
128
|
-
this._resolve(value);
|
|
129
|
-
this._initialized = true;
|
|
130
|
-
this._awaitedValue = value;
|
|
131
|
-
this.trigger();
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (value === this._awaitedValue) return;
|
|
136
|
-
|
|
137
|
-
this._value = Promise.resolve(value);
|
|
138
|
-
this._awaitedValue = value;
|
|
139
|
-
this.trigger();
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Creates a new reactive asynchronous stream that always returns a Promise.
|
|
145
|
-
*
|
|
146
|
-
* @typeParam T - The type of the stream value.
|
|
147
|
-
* @param updater - A function that receives a setter to update the stream's value.
|
|
148
|
-
* It should return a disposer function to clean up resources.
|
|
149
|
-
* @returns A new instance of {@link FlowStreamAsync}.
|
|
150
|
-
*
|
|
151
|
-
* @remarks
|
|
152
|
-
* Async streams are ideal for push-based async data sources where you want to use async/await.
|
|
153
|
-
* Unlike {@link stream}, this always returns a Promise that resolves to the value. The initial
|
|
154
|
-
* Promise is created on construction and resolves when the setter is first called.
|
|
155
|
-
*
|
|
156
|
-
* @example
|
|
157
|
-
* ```typescript
|
|
158
|
-
* const $asyncMessages = streamAsync<string>((set) => {
|
|
159
|
-
* const ws = new WebSocket('ws://example.com');
|
|
160
|
-
* ws.onmessage = (e) => set(e.data);
|
|
161
|
-
* return () => ws.close();
|
|
162
|
-
* });
|
|
163
|
-
*
|
|
164
|
-
* effect(async (t) => {
|
|
165
|
-
* const message = await $asyncMessages.get(t);
|
|
166
|
-
* console.log('Received:', message);
|
|
167
|
-
* });
|
|
168
|
-
* ```
|
|
169
|
-
*
|
|
170
|
-
* @public
|
|
171
|
-
*/
|
|
172
|
-
export function streamAsync<T>(
|
|
173
|
-
updater: (set: (value: T) => void) => () => void,
|
|
174
|
-
): FlowStreamAsync<T> {
|
|
175
|
-
return new FlowStreamAsync(updater);
|
|
176
|
-
}
|