@ersbeth/picoflow 1.1.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +857 -1528
- 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 -53
- 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 -139
- 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
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Migration Guide: v1.x.x → v2.0.0
|
|
2
|
+
|
|
3
|
+
PicoFlow v2 introduces several breaking changes that improve consistency, performance, and API clarity. This guide will help you migrate your codebase from v1.x.x to v2.0.0.
|
|
4
|
+
|
|
5
|
+
## Quick Summary
|
|
6
|
+
|
|
7
|
+
- **Effect API removed** - replaced with `subscribe()` and `.subscribe()`
|
|
8
|
+
- **FlowMap tracking simplified** - single `$lastAction` signal instead of three separate signals
|
|
9
|
+
- **FlowArray method renamed** - `setItem()` → `update()`
|
|
10
|
+
- **Constant always lazy** - must use function initializer
|
|
11
|
+
- **Improved terminology** - "effects" → "subscriptions", clearer naming
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## Breaking Changes
|
|
15
|
+
|
|
16
|
+
### 1. Effect API Removed
|
|
17
|
+
|
|
18
|
+
The global `effect()` function has been removed in favor of `subscribe()` and `.subscribe()` methods.
|
|
19
|
+
|
|
20
|
+
**v1.x.x:**
|
|
21
|
+
```typescript
|
|
22
|
+
import { effect } from '@ersbeth/picoflow'
|
|
23
|
+
|
|
24
|
+
effect((t) => {
|
|
25
|
+
const value = $state.get(t)
|
|
26
|
+
console.log(value)
|
|
27
|
+
})
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**v2.0.0:**
|
|
31
|
+
```typescript
|
|
32
|
+
// Option A: Single primitive - use .subscribe()
|
|
33
|
+
$state.subscribe((value) => {
|
|
34
|
+
console.log(value)
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
// Option B: Multiple primitives - use subscribe()
|
|
38
|
+
import { subscribe } from '@ersbeth/picoflow'
|
|
39
|
+
|
|
40
|
+
subscribe(
|
|
41
|
+
(t) => ({ a: $state1.get(t), b: $state2.get(t) }),
|
|
42
|
+
(data) => {
|
|
43
|
+
console.log(data.a, data.b)
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 2. FlowMap Fine-Grained Tracking Changed
|
|
49
|
+
|
|
50
|
+
FlowMap now uses a single `$lastAction` signal instead of three separate signals.
|
|
51
|
+
|
|
52
|
+
**v1.x.x:**
|
|
53
|
+
```typescript
|
|
54
|
+
const $users = map<number, User>()
|
|
55
|
+
|
|
56
|
+
// Three separate signals
|
|
57
|
+
$users.$lastAdded.subscribe((added) => {
|
|
58
|
+
console.log(added.key, added.value)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
$users.$lastUpdated.subscribe((updated) => {
|
|
62
|
+
console.log(updated.key, updated.value)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
$users.$lastDeleted.subscribe((deleted) => {
|
|
66
|
+
console.log(deleted.key, deleted.value)
|
|
67
|
+
})
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**v2.0.0:**
|
|
71
|
+
```typescript
|
|
72
|
+
const $users = map<number, User>()
|
|
73
|
+
|
|
74
|
+
// Single $lastAction signal
|
|
75
|
+
$users.$lastAction.subscribe((action) => {
|
|
76
|
+
if (!action) return
|
|
77
|
+
|
|
78
|
+
switch (action.type) {
|
|
79
|
+
case 'add':
|
|
80
|
+
console.log(action.key, action.addedValue)
|
|
81
|
+
break
|
|
82
|
+
case 'update':
|
|
83
|
+
console.log(action.key, action.setValue, action.clearedValue)
|
|
84
|
+
break
|
|
85
|
+
case 'delete':
|
|
86
|
+
console.log(action.key, action.removedValue)
|
|
87
|
+
break
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 3. FlowArray: `setItem()` → `update()`
|
|
93
|
+
|
|
94
|
+
The `setItem()` method has been renamed to `update()` for consistency.
|
|
95
|
+
|
|
96
|
+
**v1.x.x:**
|
|
97
|
+
```typescript
|
|
98
|
+
const $items = array([1, 2, 3])
|
|
99
|
+
$items.setItem(0, 10)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**v2.0.0:**
|
|
103
|
+
```typescript
|
|
104
|
+
const $items = array([1, 2, 3])
|
|
105
|
+
$items.update(0, 10)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 4. Constant Always Requires Function Initializer
|
|
109
|
+
|
|
110
|
+
Constants now always require a function initializer, enforcing lazy evaluation.
|
|
111
|
+
|
|
112
|
+
**v1.x.x (if direct values were allowed):**
|
|
113
|
+
```typescript
|
|
114
|
+
const $config = constant({ api: 'https://api.com' })
|
|
115
|
+
const $version = constant('1.0.0')
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**v2.0.0:**
|
|
119
|
+
```typescript
|
|
120
|
+
const $config = constant(() => ({ api: 'https://api.com' }))
|
|
121
|
+
const $version = constant(() => '1.0.0')
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 5. Terminology Updates
|
|
125
|
+
|
|
126
|
+
Some terminology has been clarified for better understanding.
|
|
127
|
+
|
|
128
|
+
#### Changes
|
|
129
|
+
|
|
130
|
+
| v1 Term | v2 Term | Notes |
|
|
131
|
+
|---------|---------|-------|
|
|
132
|
+
| "Effects" | "Side Effects" or "Subscriptions" | More precise |
|
|
133
|
+
| "TrackingContext" | "FlowTracker" | Official type name |
|
|
134
|
+
| `effect()` | `subscribe()` / `.subscribe()` | API change |
|
|
135
|
+
|
|
136
|
+
#### Migration
|
|
137
|
+
|
|
138
|
+
No code changes required - these are documentation updates. However, updating your comments and variable names to match the new terminology is recommended.
|
|
139
|
+
|
|
140
|
+
**Example:**
|
|
141
|
+
```typescript
|
|
142
|
+
// Before
|
|
143
|
+
const fx = effect((t) => { ... }) // Create effect
|
|
144
|
+
|
|
145
|
+
// After
|
|
146
|
+
const effect = $state.subscribe((value) => { ... }) // Create subscription
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Step-by-Step Migration Guide
|
|
150
|
+
|
|
151
|
+
Follow these steps for a smooth migration:
|
|
152
|
+
|
|
153
|
+
### 1. Update Dependencies
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
npm install @ersbeth/picoflow@^2.0.0
|
|
157
|
+
# or
|
|
158
|
+
pnpm add @ersbeth/picoflow@^2.0.0
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 2. Migrate Effects (Highest Priority)
|
|
162
|
+
|
|
163
|
+
Search for all `effect(` usages and migrate them:
|
|
164
|
+
- Single primitive → `.subscribe()`
|
|
165
|
+
- Multiple primitives → `subscribe()`
|
|
166
|
+
- Signals → `$signal.subscribe()`
|
|
167
|
+
|
|
168
|
+
**Tip**: Use your editor's "Find All" to locate all occurrences.
|
|
169
|
+
|
|
170
|
+
### 3. Update FlowMap Tracking
|
|
171
|
+
|
|
172
|
+
Search for:
|
|
173
|
+
- `$lastAdded` → migrate to `$lastAction` with type check
|
|
174
|
+
- `$lastUpdated` → migrate to `$lastAction` with type check
|
|
175
|
+
- `$lastDeleted` → migrate to `$lastAction` with type check
|
|
176
|
+
|
|
177
|
+
Update property names in action handlers.
|
|
178
|
+
|
|
179
|
+
### 4. Rename FlowArray Methods
|
|
180
|
+
|
|
181
|
+
Search and replace: `.setItem(` → `.update(`
|
|
182
|
+
|
|
183
|
+
### 5. Fix Constant Initialization
|
|
184
|
+
|
|
185
|
+
Search for `constant(` and ensure all have function initializers.
|
|
186
|
+
|
|
187
|
+
### 6. Test Thoroughly
|
|
188
|
+
|
|
189
|
+
Run your test suite and manually test reactive behaviors.
|
|
190
|
+
|
|
191
|
+
### 7. Update Documentation
|
|
192
|
+
|
|
193
|
+
Update internal docs, comments, and variable names to use v2 terminology.
|
|
194
|
+
|
|
195
|
+
## Getting Help
|
|
196
|
+
|
|
197
|
+
If you encounter issues during migration:
|
|
198
|
+
|
|
199
|
+
1. Check the [API documentation](/api/)
|
|
200
|
+
2. Review the [primitives guide](/guide/primitives/overview)
|
|
201
|
+
3. See the [side effects guide](/guide/primitives/effects)
|
|
202
|
+
4. Open an issue on GitHub with a minimal reproduction
|
|
203
|
+
|
|
204
|
+
Happy migrating! 🚀
|
|
@@ -73,7 +73,7 @@ const $count = state(0)
|
|
|
73
73
|
function Counter() {
|
|
74
74
|
// Convert to Solid primitive
|
|
75
75
|
const count = from($count)
|
|
76
|
-
return <div>Count: {count
|
|
76
|
+
return <div>Count: {count()}</div>
|
|
77
77
|
}
|
|
78
78
|
```
|
|
79
79
|
|
|
@@ -90,92 +90,6 @@ The `from()` function automatically determines the right Solid primitive based o
|
|
|
90
90
|
| `(t) => T` (getter function) | `SolidDerivation<T>` | Synchronous computation |
|
|
91
91
|
| `(t) => Promise<T>` (getter function) | `SolidResource<T>` | Asynchronous computation |
|
|
92
92
|
|
|
93
|
-
## SolidJS Primitives
|
|
94
|
-
|
|
95
|
-
PicoFlow also provides Solid-style primitives that you can use directly in Solid components. These are thin wrappers around SolidJS's built-in primitives with a class-based API consistent with PicoFlow's style.
|
|
96
|
-
|
|
97
|
-
### SolidState
|
|
98
|
-
|
|
99
|
-
`SolidState` wraps SolidJS's `createSignal`:
|
|
100
|
-
|
|
101
|
-
```typescript
|
|
102
|
-
import { SolidState } from '@ersbeth/picoflow/solid'
|
|
103
|
-
|
|
104
|
-
// Use in component
|
|
105
|
-
function Counter() {
|
|
106
|
-
|
|
107
|
-
// Create Solid state
|
|
108
|
-
const count = new SolidState(0)
|
|
109
|
-
|
|
110
|
-
return (
|
|
111
|
-
<div>
|
|
112
|
-
<p>Count: {count.get()}</p>
|
|
113
|
-
<button onClick={() => count.set(count.get() + 1)}>Increment</button>
|
|
114
|
-
<button onClick={() => count.set(prev => prev + 1)}>Increment (updater)</button>
|
|
115
|
-
</div>
|
|
116
|
-
)
|
|
117
|
-
}
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
**When to use:** When you want a simple reactive state that's only used in Solid components.
|
|
121
|
-
|
|
122
|
-
### SolidDerivation
|
|
123
|
-
|
|
124
|
-
`SolidDerivation` wraps SolidJS's `createMemo`:
|
|
125
|
-
|
|
126
|
-
```typescript
|
|
127
|
-
import { SolidState, SolidDerivation } from '@ersbeth/picoflow/solid'
|
|
128
|
-
|
|
129
|
-
// Use in component
|
|
130
|
-
function NameDisplay() {
|
|
131
|
-
const firstName = new SolidState('John')
|
|
132
|
-
const lastName = new SolidState('Doe')
|
|
133
|
-
|
|
134
|
-
// Create derived value
|
|
135
|
-
const fullName = new SolidDerivation(() => {
|
|
136
|
-
return `${firstName.get()} ${lastName.get()}`
|
|
137
|
-
})
|
|
138
|
-
return <div>{fullName.get()}</div> // Automatically updates
|
|
139
|
-
}
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
**When to use:** When you need computed values that are only used in Solid components.
|
|
143
|
-
|
|
144
|
-
### SolidResource
|
|
145
|
-
|
|
146
|
-
`SolidResource` wraps SolidJS's `createResource`:
|
|
147
|
-
|
|
148
|
-
```typescript
|
|
149
|
-
import { SolidResource } from '@ersbeth/picoflow/solid'
|
|
150
|
-
|
|
151
|
-
// Use in component
|
|
152
|
-
function UserProfile() {
|
|
153
|
-
|
|
154
|
-
// Create resource
|
|
155
|
-
const user = new SolidResource(async () => {
|
|
156
|
-
const res = await fetch('/api/user')
|
|
157
|
-
return res.json()
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
const userData = user.get()
|
|
161
|
-
|
|
162
|
-
return (
|
|
163
|
-
<div>
|
|
164
|
-
{user.state() === 'pending' && <p>Loading...</p>}
|
|
165
|
-
{state.state() === 'ready' && user.latest() && (
|
|
166
|
-
<>
|
|
167
|
-
<h1>{user.latest().name}</h1>
|
|
168
|
-
<p>{user.latest().email}</p>
|
|
169
|
-
</>
|
|
170
|
-
)}
|
|
171
|
-
{user.state() === 'errored' && <p>Error loading user</p>}
|
|
172
|
-
<button onClick={() => user.refetch()}>Refresh</button>
|
|
173
|
-
</div>
|
|
174
|
-
)
|
|
175
|
-
}
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
**When to use:** When you need async data loading that integrates with SolidJS's Suspense and ErrorBoundary.
|
|
179
93
|
|
|
180
94
|
## Complete Examples
|
|
181
95
|
|
|
@@ -196,7 +110,7 @@ function Counter() {
|
|
|
196
110
|
|
|
197
111
|
return (
|
|
198
112
|
<div>
|
|
199
|
-
<p>Count: {count
|
|
113
|
+
<p>Count: {count()}</p>
|
|
200
114
|
<p>{isEven.get() ? 'Even' : 'Odd'}</p>
|
|
201
115
|
<button onClick={() => $count.set(prev => prev + 1)}>Increment</button>
|
|
202
116
|
<button onClick={() => $count.set(prev => prev - 1)}>Decrement</button>
|
|
@@ -38,9 +38,10 @@ With reactive programming, dependencies update automatically:
|
|
|
38
38
|
const $count = state(0)
|
|
39
39
|
const $doubled = derivation((t) => $count.get(t) * 2)
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
subscribe(
|
|
42
|
+
(t) => ({ count: $count.get(t), doubled: $doubled.get(t) }),
|
|
43
|
+
(data) => updateUI(data.count, data.doubled) // Runs automatically!
|
|
44
|
+
)
|
|
44
45
|
|
|
45
46
|
function increment() {
|
|
46
47
|
$count.set(n => n + 1) // Everything else updates automatically!
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
PicoFlow follows simple, consistent conventions that make your reactive code easier to read and maintain. These conventions help you quickly identify reactive values and understand data flow at a glance.
|
|
4
|
-
|
|
5
|
-
## The $ Prefix
|
|
1
|
+
# Naming Convention
|
|
6
2
|
|
|
7
3
|
You'll see variables prefixed with `$` throughout PicoFlow examples:
|
|
8
4
|
|
|
@@ -27,35 +23,8 @@ const $userAge = state(25)
|
|
|
27
23
|
const $isAdult = derivation((t) => $userAge.get(t) >= 18)
|
|
28
24
|
|
|
29
25
|
// Plain values - no $ prefix
|
|
30
|
-
const currentName = $userName.pick() // Snapshot of current value
|
|
26
|
+
const currentName = await $userName.pick() // Snapshot of current value
|
|
31
27
|
const maxAge = 100 // Constant
|
|
32
28
|
```
|
|
33
29
|
|
|
34
|
-
## Benefits
|
|
35
|
-
|
|
36
|
-
**1. Visual Clarity**
|
|
37
|
-
|
|
38
|
-
```typescript
|
|
39
|
-
// Clear distinction between reactive and non-reactive
|
|
40
|
-
function updateProfile(newName: string) {
|
|
41
|
-
$userName.set(newName) // $ = reactive, will trigger effects
|
|
42
|
-
const timestamp = Date.now() // no $ = plain value
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
**2. Prevents Confusion**
|
|
47
|
-
|
|
48
|
-
```typescript
|
|
49
|
-
// Easy to see what's reactive
|
|
50
|
-
effect((t) => {
|
|
51
|
-
const user = $currentUser.get(t) // $ = will re-run on change
|
|
52
|
-
const config = appConfig // no $ = static value
|
|
53
|
-
|
|
54
|
-
fetchUserData(user.id, config)
|
|
55
|
-
})
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
**3. Code Review**
|
|
59
|
-
|
|
60
|
-
When reviewing code, the `$` prefix makes it immediately obvious which variables should be part of the reactive system and which should be regular JavaScript values.
|
|
61
30
|
|
|
@@ -54,13 +54,13 @@ yarn add solid-js
|
|
|
54
54
|
Import the primitives you need:
|
|
55
55
|
|
|
56
56
|
```typescript
|
|
57
|
-
import { state,
|
|
57
|
+
import { state, derivation, subscribe } from '@ersbeth/picoflow'
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
For SolidJS integration:
|
|
61
61
|
|
|
62
62
|
```typescript
|
|
63
|
-
import { from } from '@ersbeth/picoflow
|
|
63
|
+
import { from } from '@ersbeth/picoflow'
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
## Your First PicoFlow App
|
|
@@ -68,7 +68,7 @@ import { from } from '@ersbeth/picoflow/solid'
|
|
|
68
68
|
Let's build a simple counter with PicoFlow:
|
|
69
69
|
|
|
70
70
|
```typescript
|
|
71
|
-
import { state, derivation,
|
|
71
|
+
import { state, derivation, subscribe } from '@ersbeth/picoflow'
|
|
72
72
|
|
|
73
73
|
// Create reactive state (prefix with $ by convention)
|
|
74
74
|
const $count = state(0)
|
|
@@ -79,12 +79,13 @@ const $isEven = derivation((t) => {
|
|
|
79
79
|
})
|
|
80
80
|
|
|
81
81
|
// React to changes
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
82
|
+
subscribe(
|
|
83
|
+
(t) => ({ count:$count.get(t), even:$isEven.get(t)}),
|
|
84
|
+
(data) => {
|
|
85
|
+
console.log(`Count is ${data.count}, which is ${data.even ? 'even' : 'odd'}`)
|
|
86
|
+
}
|
|
87
|
+
)
|
|
88
|
+
// Logs "Count is 0, which is even"
|
|
88
89
|
|
|
89
90
|
// Update the state
|
|
90
91
|
$count.set(1) // Logs: "Count is 1, which is odd"
|
|
@@ -96,9 +97,11 @@ $count.set(3) // Logs: "Count is 3, which is odd"
|
|
|
96
97
|
|
|
97
98
|
1. **State** (`$count`) - Holds a mutable value
|
|
98
99
|
2. **Derivation** (`$isEven`) - Computes a value based on state
|
|
99
|
-
3. **
|
|
100
|
-
4.
|
|
101
|
-
5.
|
|
100
|
+
3. **Subscribe** - Creates an effect that runs automatically when dependencies change
|
|
101
|
+
4. **Data function** `(t) => ...` - Tracks dependencies and returns data
|
|
102
|
+
5. **Callback** `(data) => ...` - Performs side effects with the data
|
|
103
|
+
6. **`.get(t)`** - Reads a value AND creates a dependency
|
|
104
|
+
7. **`.set()`** - Updates state, triggering subscribers
|
|
102
105
|
|
|
103
106
|
### Data Flow
|
|
104
107
|
|
|
@@ -109,26 +112,28 @@ sequenceDiagram
|
|
|
109
112
|
participant User
|
|
110
113
|
participant $count
|
|
111
114
|
participant $isEven
|
|
112
|
-
participant
|
|
115
|
+
participant Subscribe
|
|
113
116
|
|
|
114
117
|
User->>$count: set(1)
|
|
115
118
|
activate $count
|
|
116
|
-
Note over $count: Updates value
|
|
119
|
+
Note over $count: Updates value 0 → 1
|
|
117
120
|
$count->>$isEven: notify()
|
|
118
|
-
Note over $isEven: Marks as dirty
|
|
119
|
-
$count->>
|
|
121
|
+
Note over $isEven: Marks as dirty (lazy recompute)
|
|
122
|
+
$count->>Subscribe: notify()
|
|
120
123
|
deactivate $count
|
|
121
124
|
|
|
122
|
-
activate
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
125
|
+
activate Subscribe
|
|
126
|
+
Note over Subscribe: Execute data function
|
|
127
|
+
Subscribe->>$count: get(t)
|
|
128
|
+
$count-->>Subscribe: 1
|
|
129
|
+
Subscribe->>$isEven: get(t)
|
|
126
130
|
activate $isEven
|
|
127
131
|
Note over $isEven: Recomputes because dirty
|
|
128
132
|
$isEven->>$count: get(t)
|
|
129
133
|
$count-->>$isEven: 1
|
|
130
|
-
$isEven-->>
|
|
134
|
+
$isEven-->>Subscribe: false
|
|
131
135
|
deactivate $isEven
|
|
132
|
-
Note over
|
|
133
|
-
|
|
136
|
+
Note over Subscribe: Call callback with {count: 1, even: false}
|
|
137
|
+
Note over Subscribe: Logs: "Count is 1, which is odd"
|
|
138
|
+
deactivate Subscribe
|
|
134
139
|
```
|
|
@@ -10,7 +10,7 @@ Throughout this guide, we'll use this simple but complete example:
|
|
|
10
10
|
const $a = state(1)
|
|
11
11
|
const $b = state(2)
|
|
12
12
|
const $c = derivation((t) => $a.get(t) + $b.get(t))
|
|
13
|
-
|
|
13
|
+
$c.subscribe((c) => console.log('C =', c))
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
This example demonstrates:
|
|
@@ -39,22 +39,21 @@ When you run the example code, here's the exact sequence of events:
|
|
|
39
39
|
3. **`derivation(...)` creates `$c`**
|
|
40
40
|
- A new `FlowDerivation` instance is created
|
|
41
41
|
- The compute function is stored but **NOT executed** (lazy evaluation)
|
|
42
|
-
- A `
|
|
42
|
+
- A `FlowTracker` will be created when the derivation is first accessed
|
|
43
43
|
- Still no computed value yet
|
|
44
44
|
|
|
45
|
-
4.
|
|
45
|
+
4. **`$c.subscribe(...)` creates the effect**
|
|
46
46
|
- A new `FlowEffect` instance is created
|
|
47
|
-
- A `TrackingContext` is created for the effect
|
|
48
47
|
- **The effect executes immediately** (not lazy!)
|
|
49
48
|
- During execution:
|
|
50
|
-
-
|
|
49
|
+
- The subscribe method internally calls `$c.get(t)` with a `FlowTracker`
|
|
51
50
|
- This triggers `$c` to initialize (first access)
|
|
52
|
-
- `$c`
|
|
51
|
+
- `$c` creates its own `FlowTracker` and runs its compute function
|
|
53
52
|
- Compute calls `$a.get(t)` → returns `1`, registers `$a` as dependency of `$c`
|
|
54
53
|
- Compute calls `$b.get(t)` → returns `2`, registers `$b` as dependency of `$c`
|
|
55
54
|
- Compute returns `3`
|
|
56
|
-
-
|
|
57
|
-
-
|
|
55
|
+
- The value `3` is registered as a dependency of the effect
|
|
56
|
+
- Callback is called with `3` and logs: `"C = 3"`
|
|
58
57
|
|
|
59
58
|
### Creation Sequence Diagram
|
|
60
59
|
|
|
@@ -82,7 +81,7 @@ sequenceDiagram
|
|
|
82
81
|
Note over $c: Store compute fn<br/>NOT executed yet<br/>(lazy)
|
|
83
82
|
deactivate $c
|
|
84
83
|
|
|
85
|
-
User->>Effect:
|
|
84
|
+
User->>Effect: $c.subscribe(...)
|
|
86
85
|
activate Effect
|
|
87
86
|
Note over Effect: Create & execute<br/>immediately
|
|
88
87
|
|
|
@@ -333,14 +332,12 @@ const $expensive = derivation((t) => {
|
|
|
333
332
|
return expensiveCalculation($data.get(t))
|
|
334
333
|
})
|
|
335
334
|
|
|
336
|
-
const
|
|
337
|
-
if (shouldDisplay)
|
|
338
|
-
display($expensive.get(t)) // Only computes when accessed
|
|
339
|
-
}
|
|
335
|
+
const effect = $expensive.subscribe((value) => {
|
|
336
|
+
if (shouldDisplay) display(value)
|
|
340
337
|
})
|
|
341
338
|
|
|
342
339
|
// When not needed, just dispose the effect
|
|
343
|
-
|
|
340
|
+
effect.dispose() // $expensive stops computing
|
|
344
341
|
```
|
|
345
342
|
|
|
346
343
|
### 2. Debug Dependency Issues
|
|
@@ -348,12 +345,12 @@ fx.dispose() // $expensive stops computing
|
|
|
348
345
|
```typescript
|
|
349
346
|
// If logs don't appear, check:
|
|
350
347
|
// 1. Is the effect created? (runs immediately)
|
|
351
|
-
// 2. Are you using .
|
|
348
|
+
// 2. Are you using .subscribe()? (not .pick())
|
|
352
349
|
// 3. Is anything disposed?
|
|
353
350
|
|
|
354
|
-
|
|
351
|
+
$state.subscribe((value) => {
|
|
355
352
|
console.log('Effect created') // Should log immediately
|
|
356
|
-
console.log('Value:',
|
|
353
|
+
console.log('Value:', value)
|
|
357
354
|
})
|
|
358
355
|
```
|
|
359
356
|
|
|
@@ -363,8 +360,8 @@ effect((t) => {
|
|
|
363
360
|
// Always dispose effects when done
|
|
364
361
|
const disposables: FlowDisposable[] = []
|
|
365
362
|
|
|
366
|
-
disposables.push(
|
|
367
|
-
disposables.push(
|
|
363
|
+
disposables.push(subscribe((t) => { /* ... */ }, () => { /* ... */ }))
|
|
364
|
+
disposables.push(subscribe((t) => { /* ... */ }, () => { /* ... */ }))
|
|
368
365
|
|
|
369
366
|
// Clean up
|
|
370
367
|
disposables.forEach(d => d.dispose())
|