@playfast/reform 1.2.1 → 1.4.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/README.md +15 -6
- package/dist/boundary/boundary.d.ts +64 -0
- package/dist/boundary/boundary.d.ts.map +1 -0
- package/dist/boundary/boundary.js +102 -0
- package/dist/boundary/boundary.js.map +1 -0
- package/dist/calc/asyncCalc.d.ts +23 -0
- package/dist/calc/asyncCalc.d.ts.map +1 -0
- package/dist/calc/asyncCalc.js +100 -0
- package/dist/calc/asyncCalc.js.map +1 -0
- package/dist/calc/asyncCalcTypes.d.ts +80 -0
- package/dist/calc/asyncCalcTypes.d.ts.map +1 -0
- package/dist/calc/asyncCalcTypes.js +2 -0
- package/dist/calc/asyncCalcTypes.js.map +1 -0
- package/dist/calc/asyncData.d.ts +29 -0
- package/dist/calc/asyncData.d.ts.map +1 -0
- package/dist/calc/asyncData.js +21 -0
- package/dist/calc/asyncData.js.map +1 -0
- package/dist/calc/calc.d.ts +39 -0
- package/dist/calc/calc.d.ts.map +1 -0
- package/dist/calc/calc.js +48 -0
- package/dist/calc/calc.js.map +1 -0
- package/dist/calc/calcFamily.d.ts +40 -0
- package/dist/calc/calcFamily.d.ts.map +1 -0
- package/dist/calc/calcFamily.js +156 -0
- package/dist/calc/calcFamily.js.map +1 -0
- package/dist/calc/compose.d.ts +5 -0
- package/dist/calc/compose.d.ts.map +1 -0
- package/dist/calc/compose.js +5 -0
- package/dist/calc/compose.js.map +1 -0
- package/dist/calc/queryState.d.ts +14 -0
- package/dist/calc/queryState.d.ts.map +1 -0
- package/dist/calc/queryState.js +39 -0
- package/dist/calc/queryState.js.map +1 -0
- package/dist/channel/channel.d.ts +51 -0
- package/dist/channel/channel.d.ts.map +1 -0
- package/dist/channel/channel.js +91 -0
- package/dist/channel/channel.js.map +1 -0
- package/dist/channel/procedures.d.ts +24 -0
- package/dist/channel/procedures.d.ts.map +1 -0
- package/dist/channel/procedures.js +82 -0
- package/dist/channel/procedures.js.map +1 -0
- package/dist/compose/composition.d.ts +12 -0
- package/dist/compose/composition.d.ts.map +1 -0
- package/dist/compose/composition.js +62 -0
- package/dist/compose/composition.js.map +1 -0
- package/dist/compose/compositionTypes.d.ts +127 -0
- package/dist/compose/compositionTypes.d.ts.map +1 -0
- package/dist/compose/compositionTypes.js +2 -0
- package/dist/compose/compositionTypes.js.map +1 -0
- package/dist/compose/host.d.ts +6 -0
- package/dist/compose/host.d.ts.map +1 -0
- package/dist/compose/host.js +2 -0
- package/dist/compose/host.js.map +1 -0
- package/dist/compose/props.d.ts +10 -0
- package/dist/compose/props.d.ts.map +1 -0
- package/dist/compose/props.js +6 -0
- package/dist/compose/props.js.map +1 -0
- package/dist/compose/provide.d.ts +18 -0
- package/dist/compose/provide.d.ts.map +1 -0
- package/dist/compose/provide.js +49 -0
- package/dist/compose/provide.js.map +1 -0
- package/dist/compose/slot.d.ts +70 -0
- package/dist/compose/slot.d.ts.map +1 -0
- package/dist/compose/slot.js +26 -0
- package/dist/compose/slot.js.map +1 -0
- package/dist/compose/structure.d.ts +51 -0
- package/dist/compose/structure.d.ts.map +1 -0
- package/dist/compose/structure.js +117 -0
- package/dist/compose/structure.js.map +1 -0
- package/dist/compose/ui.d.ts +112 -0
- package/dist/compose/ui.d.ts.map +1 -0
- package/dist/compose/ui.js +58 -0
- package/dist/compose/ui.js.map +1 -0
- package/dist/definition/definition.d.ts +11 -0
- package/dist/definition/definition.d.ts.map +1 -0
- package/dist/definition/definition.js +35 -0
- package/dist/definition/definition.js.map +1 -0
- package/dist/event/event.d.ts +52 -0
- package/dist/event/event.d.ts.map +1 -0
- package/dist/event/event.js +88 -0
- package/dist/event/event.js.map +1 -0
- package/dist/event/eventGroup.d.ts +8 -0
- package/dist/event/eventGroup.d.ts.map +1 -0
- package/dist/event/eventGroup.js +3 -0
- package/dist/event/eventGroup.js.map +1 -0
- package/dist/feature/feature.d.ts +27 -0
- package/dist/feature/feature.d.ts.map +1 -0
- package/dist/feature/feature.js +20 -0
- package/dist/feature/feature.js.map +1 -0
- package/dist/feature/featureBinding.d.ts +85 -0
- package/dist/feature/featureBinding.d.ts.map +1 -0
- package/dist/feature/featureBinding.js +10 -0
- package/dist/feature/featureBinding.js.map +1 -0
- package/dist/feature/featureClass.d.ts +10 -0
- package/dist/feature/featureClass.d.ts.map +1 -0
- package/dist/feature/featureClass.js +2 -0
- package/dist/feature/featureClass.js.map +1 -0
- package/dist/feature/featureConfig.d.ts +86 -0
- package/dist/feature/featureConfig.d.ts.map +1 -0
- package/dist/feature/featureConfig.js +13 -0
- package/dist/feature/featureConfig.js.map +1 -0
- package/dist/feature/featureFactory.d.ts +15 -0
- package/dist/feature/featureFactory.d.ts.map +1 -0
- package/dist/feature/featureFactory.js +59 -0
- package/dist/feature/featureFactory.js.map +1 -0
- package/dist/feature/featureModule.d.ts +28 -0
- package/dist/feature/featureModule.d.ts.map +1 -0
- package/dist/feature/featureModule.js +33 -0
- package/dist/feature/featureModule.js.map +1 -0
- package/dist/feature/featureNativeTree.d.ts +26 -0
- package/dist/feature/featureNativeTree.d.ts.map +1 -0
- package/dist/feature/featureNativeTree.js +2 -0
- package/dist/feature/featureNativeTree.js.map +1 -0
- package/dist/feature/featureRequirement.d.ts +43 -0
- package/dist/feature/featureRequirement.d.ts.map +1 -0
- package/dist/feature/featureRequirement.js +6 -0
- package/dist/feature/featureRequirement.js.map +1 -0
- package/dist/feature/featureVariants.d.ts +9 -0
- package/dist/feature/featureVariants.d.ts.map +1 -0
- package/dist/feature/featureVariants.js +59 -0
- package/dist/feature/featureVariants.js.map +1 -0
- package/dist/feature/mountFeature.d.ts +10 -0
- package/dist/feature/mountFeature.d.ts.map +1 -0
- package/dist/feature/mountFeature.js +14 -0
- package/dist/feature/mountFeature.js.map +1 -0
- package/dist/graph/closure.d.ts +77 -0
- package/dist/graph/closure.d.ts.map +1 -0
- package/dist/graph/closure.js +4 -0
- package/dist/graph/closure.js.map +1 -0
- package/dist/graph/services.d.ts +30 -0
- package/dist/graph/services.d.ts.map +1 -0
- package/dist/graph/services.js +2 -0
- package/dist/graph/services.js.map +1 -0
- package/dist/graph/summary.d.ts +60 -0
- package/dist/graph/summary.d.ts.map +1 -0
- package/dist/graph/summary.js +7 -0
- package/dist/graph/summary.js.map +1 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/bucketCache.d.ts +19 -0
- package/dist/internal/bucketCache.d.ts.map +1 -0
- package/dist/internal/bucketCache.js +20 -0
- package/dist/internal/bucketCache.js.map +1 -0
- package/dist/internal/capture.d.ts +17 -0
- package/dist/internal/capture.d.ts.map +1 -0
- package/dist/internal/capture.js +5 -0
- package/dist/internal/capture.js.map +1 -0
- package/dist/internal/env.d.ts +2 -0
- package/dist/internal/env.d.ts.map +1 -0
- package/dist/internal/env.js +5 -0
- package/dist/internal/env.js.map +1 -0
- package/dist/internal/errors.d.ts +48 -0
- package/dist/internal/errors.d.ts.map +1 -0
- package/dist/internal/errors.js +69 -0
- package/dist/internal/errors.js.map +1 -0
- package/dist/internal/familyKeys.d.ts +16 -0
- package/dist/internal/familyKeys.d.ts.map +1 -0
- package/dist/internal/familyKeys.js +35 -0
- package/dist/internal/familyKeys.js.map +1 -0
- package/dist/internal/inspect.d.ts +5 -0
- package/dist/internal/inspect.d.ts.map +1 -0
- package/dist/internal/inspect.js +20 -0
- package/dist/internal/inspect.js.map +1 -0
- package/dist/internal/platform.d.ts +43 -0
- package/dist/internal/platform.d.ts.map +1 -0
- package/dist/internal/platform.js +68 -0
- package/dist/internal/platform.js.map +1 -0
- package/dist/internal/queryDriver.d.ts +7 -0
- package/dist/internal/queryDriver.d.ts.map +1 -0
- package/dist/internal/queryDriver.js +222 -0
- package/dist/internal/queryDriver.js.map +1 -0
- package/dist/internal/queryDriverConsume.d.ts +9 -0
- package/dist/internal/queryDriverConsume.d.ts.map +1 -0
- package/dist/internal/queryDriverConsume.js +16 -0
- package/dist/internal/queryDriverConsume.js.map +1 -0
- package/dist/internal/queryDriverHydrate.d.ts +17 -0
- package/dist/internal/queryDriverHydrate.d.ts.map +1 -0
- package/dist/internal/queryDriverHydrate.js +25 -0
- package/dist/internal/queryDriverHydrate.js.map +1 -0
- package/dist/internal/queryDriverPersist.d.ts +16 -0
- package/dist/internal/queryDriverPersist.d.ts.map +1 -0
- package/dist/internal/queryDriverPersist.js +15 -0
- package/dist/internal/queryDriverPersist.js.map +1 -0
- package/dist/internal/queryDriverPersistWarn.d.ts +12 -0
- package/dist/internal/queryDriverPersistWarn.d.ts.map +1 -0
- package/dist/internal/queryDriverPersistWarn.js +31 -0
- package/dist/internal/queryDriverPersistWarn.js.map +1 -0
- package/dist/internal/queryDriverSettle.d.ts +23 -0
- package/dist/internal/queryDriverSettle.d.ts.map +1 -0
- package/dist/internal/queryDriverSettle.js +52 -0
- package/dist/internal/queryDriverSettle.js.map +1 -0
- package/dist/internal/queryDriverStore.d.ts +28 -0
- package/dist/internal/queryDriverStore.d.ts.map +1 -0
- package/dist/internal/queryDriverStore.js +53 -0
- package/dist/internal/queryDriverStore.js.map +1 -0
- package/dist/internal/queryDriverTypes.d.ts +44 -0
- package/dist/internal/queryDriverTypes.d.ts.map +1 -0
- package/dist/internal/queryDriverTypes.js +9 -0
- package/dist/internal/queryDriverTypes.js.map +1 -0
- package/dist/internal/queryEvents.d.ts +12 -0
- package/dist/internal/queryEvents.d.ts.map +1 -0
- package/dist/internal/queryEvents.js +11 -0
- package/dist/internal/queryEvents.js.map +1 -0
- package/dist/internal/queryStore.d.ts +13 -0
- package/dist/internal/queryStore.d.ts.map +1 -0
- package/dist/internal/queryStore.js +11 -0
- package/dist/internal/queryStore.js.map +1 -0
- package/dist/internal/reuse.d.ts +2 -0
- package/dist/internal/reuse.d.ts.map +1 -0
- package/dist/internal/reuse.js +55 -0
- package/dist/internal/reuse.js.map +1 -0
- package/dist/internal/scheduler.d.ts +14 -0
- package/dist/internal/scheduler.d.ts.map +1 -0
- package/dist/internal/scheduler.js +101 -0
- package/dist/internal/scheduler.js.map +1 -0
- package/dist/internal/seeds.d.ts +3 -0
- package/dist/internal/seeds.d.ts.map +1 -0
- package/dist/internal/seeds.js +3 -0
- package/dist/internal/seeds.js.map +1 -0
- package/dist/internal/sources.d.ts +20 -0
- package/dist/internal/sources.d.ts.map +1 -0
- package/dist/internal/sources.js +39 -0
- package/dist/internal/sources.js.map +1 -0
- package/dist/internal/stateRegistry.d.ts +2 -0
- package/dist/internal/stateRegistry.d.ts.map +1 -0
- package/dist/internal/stateRegistry.js +15 -0
- package/dist/internal/stateRegistry.js.map +1 -0
- package/dist/internal/store.d.ts +15 -0
- package/dist/internal/store.d.ts.map +1 -0
- package/dist/internal/store.js +61 -0
- package/dist/internal/store.js.map +1 -0
- package/dist/internal/track.d.ts +15 -0
- package/dist/internal/track.d.ts.map +1 -0
- package/dist/internal/track.js +11 -0
- package/dist/internal/track.js.map +1 -0
- package/dist/internal/variance.d.ts +4 -0
- package/dist/internal/variance.d.ts.map +1 -0
- package/dist/internal/variance.js +2 -0
- package/dist/internal/variance.js.map +1 -0
- package/dist/internal.d.ts +43 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +59 -0
- package/dist/internal.js.map +1 -0
- package/dist/namespace/namespace.d.ts +24 -0
- package/dist/namespace/namespace.d.ts.map +1 -0
- package/dist/namespace/namespace.js +20 -0
- package/dist/namespace/namespace.js.map +1 -0
- package/dist/procedure/procedure.d.ts +32 -0
- package/dist/procedure/procedure.d.ts.map +1 -0
- package/dist/procedure/procedure.js +34 -0
- package/dist/procedure/procedure.js.map +1 -0
- package/dist/reducer/reducer.d.ts +35 -0
- package/dist/reducer/reducer.d.ts.map +1 -0
- package/dist/reducer/reducer.js +73 -0
- package/dist/reducer/reducer.js.map +1 -0
- package/dist/remote/pendingQueue.d.ts +22 -0
- package/dist/remote/pendingQueue.d.ts.map +1 -0
- package/dist/remote/pendingQueue.js +129 -0
- package/dist/remote/pendingQueue.js.map +1 -0
- package/dist/remote/remoteState.d.ts +13 -0
- package/dist/remote/remoteState.d.ts.map +1 -0
- package/dist/remote/remoteState.js +189 -0
- package/dist/remote/remoteState.js.map +1 -0
- package/dist/remote/remoteStateMake.d.ts +8 -0
- package/dist/remote/remoteStateMake.d.ts.map +1 -0
- package/dist/remote/remoteStateMake.js +46 -0
- package/dist/remote/remoteStateMake.js.map +1 -0
- package/dist/remote/remoteStateSend.d.ts +43 -0
- package/dist/remote/remoteStateSend.d.ts.map +1 -0
- package/dist/remote/remoteStateSend.js +83 -0
- package/dist/remote/remoteStateSend.js.map +1 -0
- package/dist/remote/remoteStateTypes.d.ts +106 -0
- package/dist/remote/remoteStateTypes.d.ts.map +1 -0
- package/dist/remote/remoteStateTypes.js +4 -0
- package/dist/remote/remoteStateTypes.js.map +1 -0
- package/dist/runtime/appRuntime.d.ts +10 -0
- package/dist/runtime/appRuntime.d.ts.map +1 -0
- package/dist/runtime/appRuntime.js +6 -0
- package/dist/runtime/appRuntime.js.map +1 -0
- package/dist/runtime/bus.d.ts +22 -0
- package/dist/runtime/bus.d.ts.map +1 -0
- package/dist/runtime/bus.js +12 -0
- package/dist/runtime/bus.js.map +1 -0
- package/dist/runtime/capturedAppRuntime.d.ts +7 -0
- package/dist/runtime/capturedAppRuntime.d.ts.map +1 -0
- package/dist/runtime/capturedAppRuntime.js +137 -0
- package/dist/runtime/capturedAppRuntime.js.map +1 -0
- package/dist/runtime/eventBudget.d.ts +32 -0
- package/dist/runtime/eventBudget.d.ts.map +1 -0
- package/dist/runtime/eventBudget.js +68 -0
- package/dist/runtime/eventBudget.js.map +1 -0
- package/dist/runtime/featureMount.d.ts +48 -0
- package/dist/runtime/featureMount.d.ts.map +1 -0
- package/dist/runtime/featureMount.js +118 -0
- package/dist/runtime/featureMount.js.map +1 -0
- package/dist/runtime/instrumentation.d.ts +18 -0
- package/dist/runtime/instrumentation.d.ts.map +1 -0
- package/dist/runtime/instrumentation.js +16 -0
- package/dist/runtime/instrumentation.js.map +1 -0
- package/dist/runtime/loop.d.ts +44 -0
- package/dist/runtime/loop.d.ts.map +1 -0
- package/dist/runtime/loop.js +131 -0
- package/dist/runtime/loop.js.map +1 -0
- package/dist/runtime/queries.d.ts +20 -0
- package/dist/runtime/queries.d.ts.map +1 -0
- package/dist/runtime/queries.js +21 -0
- package/dist/runtime/queries.js.map +1 -0
- package/dist/runtime/runtimeHandle.d.ts +56 -0
- package/dist/runtime/runtimeHandle.d.ts.map +1 -0
- package/dist/runtime/runtimeHandle.js +2 -0
- package/dist/runtime/runtimeHandle.js.map +1 -0
- package/dist/scene/scene.d.ts +55 -0
- package/dist/scene/scene.d.ts.map +1 -0
- package/dist/scene/scene.js +74 -0
- package/dist/scene/scene.js.map +1 -0
- package/dist/state/state.d.ts +54 -0
- package/dist/state/state.d.ts.map +1 -0
- package/dist/state/state.js +41 -0
- package/dist/state/state.js.map +1 -0
- package/dist/state/stateFamily.d.ts +59 -0
- package/dist/state/stateFamily.d.ts.map +1 -0
- package/dist/state/stateFamily.js +139 -0
- package/dist/state/stateFamily.js.map +1 -0
- package/dist/state/stateGroup.d.ts +36 -0
- package/dist/state/stateGroup.d.ts.map +1 -0
- package/dist/state/stateGroup.js +33 -0
- package/dist/state/stateGroup.js.map +1 -0
- package/dist/state/token.d.ts +35 -0
- package/dist/state/token.d.ts.map +1 -0
- package/dist/state/token.js +18 -0
- package/dist/state/token.js.map +1 -0
- package/dist/synced/syncedStore.d.ts +44 -0
- package/dist/synced/syncedStore.d.ts.map +1 -0
- package/dist/synced/syncedStore.js +32 -0
- package/dist/synced/syncedStore.js.map +1 -0
- package/dist/testkit/flight.testkit.d.ts +18 -0
- package/dist/testkit/flight.testkit.d.ts.map +1 -0
- package/dist/testkit/flight.testkit.js +46 -0
- package/dist/testkit/flight.testkit.js.map +1 -0
- package/dist/ui/node.d.ts +3 -0
- package/dist/ui/node.d.ts.map +1 -0
- package/dist/ui/node.js +2 -0
- package/dist/ui/node.js.map +1 -0
- package/dist/ui/trigger.d.ts +2 -0
- package/dist/ui/trigger.d.ts.map +1 -0
- package/dist/ui/trigger.js +2 -0
- package/dist/ui/trigger.js.map +1 -0
- package/dist/wire/tree.d.ts +32 -0
- package/dist/wire/tree.d.ts.map +1 -0
- package/dist/wire/tree.js +64 -0
- package/dist/wire/tree.js.map +1 -0
- package/dist/wire/triggers.d.ts +25 -0
- package/dist/wire/triggers.d.ts.map +1 -0
- package/dist/wire/triggers.js +31 -0
- package/dist/wire/triggers.js.map +1 -0
- package/package.json +17 -5
- package/src/calc/asyncCalc-key-attribution.test.ts +182 -0
- package/src/calc/asyncCalc-registry-name.test.ts +82 -0
- package/src/calc/asyncCalc.superseded-commit.test.ts +162 -0
- package/src/calc/asyncCalc.test.ts +35 -7
- package/src/calc/asyncCalc.ts +33 -10
- package/src/calc/asyncCalcTypes.test.ts +64 -0
- package/src/calc/asyncCalcTypes.ts +8 -10
- package/src/calc/calcFamily.ts +81 -34
- package/src/calc/family-identity.test.ts +231 -0
- package/src/calc/queryState.ts +36 -5
- package/src/channel/channel-throttle-frames.test.ts +163 -0
- package/src/channel/channel.ts +5 -0
- package/src/compose/compose-identity.test.ts +175 -0
- package/src/compose/composition.ts +8 -4
- package/src/compose/structure.ts +45 -13
- package/src/compose/ui.ts +22 -5
- package/src/event/event.ts +31 -2
- package/src/event/syncTrigger.test.ts +66 -0
- package/src/internal/familyKeys.ts +41 -0
- package/src/internal/platform.test.ts +55 -0
- package/src/internal/platform.ts +72 -0
- package/src/internal/queryDriver-defect-attribution.test.ts +107 -0
- package/src/internal/queryDriver-persist-key.test.ts +118 -0
- package/src/internal/queryDriver.persistence-staleness.test.ts +209 -0
- package/src/internal/queryDriver.ts +92 -80
- package/src/internal/queryDriverConsume.ts +42 -0
- package/src/internal/queryDriverHydrate.ts +9 -3
- package/src/internal/queryDriverPersist.ts +42 -0
- package/src/internal/queryDriverPersistWarn.ts +61 -0
- package/src/internal/queryDriverSettle.ts +85 -0
- package/src/internal/queryDriverStore.ts +9 -74
- package/src/internal/queryDriverTypes.ts +10 -0
- package/src/internal/queryState-and-scheduler-audit.test.ts +170 -0
- package/src/internal/scheduler-multi-source-wake.test.ts +111 -0
- package/src/internal/scheduler.ts +80 -6
- package/src/internal.ts +1 -0
- package/src/reducer/reducer.ts +3 -3
- package/src/remote/pendingQueue.ts +35 -5
- package/src/remote/remoteState.intent-key-stamp.test.ts +207 -0
- package/src/remote/remoteState.key-attribution.test.ts +174 -0
- package/src/remote/remoteState.ts +27 -15
- package/src/remote/remoteStateSend.ts +29 -8
- package/src/remote/remoteStateTypes.ts +7 -0
- package/src/runtime/bus.ts +6 -1
- package/src/runtime/capturedAppRuntime.ts +134 -110
- package/src/runtime/eventBudget.ts +2 -1
- package/src/runtime/feature-mount-ownership.test.ts +539 -0
- package/src/runtime/featureMount.ts +110 -3
- package/src/runtime/loop.ts +29 -6
- package/src/runtime/mount-inflight-ownership.test.ts +361 -0
- package/src/runtime/mount-scope-hardening.test.ts +440 -0
- package/src/runtime/runtime.schema-identity.test.ts +188 -0
- package/src/state/state.ts +8 -4
- package/src/state/stateFamily.ts +86 -36
- package/src/state/stateGroup.ts +24 -6
- package/src/testkit/flight.testkit.ts +2 -1
- package/src/wire/tree-key-presence.test.ts +46 -0
- package/src/wire/tree.ts +9 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Context, Effect, Effectable } from 'effect';
|
|
2
|
+
import { readTracked } from '../internal/track.js';
|
|
3
|
+
export class StateToken extends Effectable.Class {
|
|
4
|
+
name;
|
|
5
|
+
store;
|
|
6
|
+
constructor(name, store) {
|
|
7
|
+
super();
|
|
8
|
+
this.name = name;
|
|
9
|
+
this.store = store;
|
|
10
|
+
}
|
|
11
|
+
commit() {
|
|
12
|
+
return Effect.flatMap(this.store, readTracked);
|
|
13
|
+
}
|
|
14
|
+
capture(visit) {
|
|
15
|
+
return visit(this);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/state/token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAG/C,MAAM,OAAO,UAIX,SAAQ,UAAU,CAAC,KAA2B;IACrC,IAAI,CAAG;IACP,KAAK,CAAmC;IACjD,YAAY,IAAO,EAAE,KAAwC;QAC3D,KAAK,EAAE,CAAA;QACP,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;IACD,MAAM;QACJ,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;IAChD,CAAC;IACD,OAAO,CAAS,KAA4B;QAC1C,OAAO,KAAK,CAAC,IAAI,CAAC,CAAA;IACpB,CAAC;CACF"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Context, Effect, Layer, Option, type Schema, type Scope } from 'effect';
|
|
2
|
+
import type { Effect as EffectType } from 'effect/Effect';
|
|
3
|
+
import { type Manifest } from '../definition/definition.js';
|
|
4
|
+
import { type Store } from '../internal/store.js';
|
|
5
|
+
import type { AnySource, Source, SourceCapture } from '../state/token.js';
|
|
6
|
+
import type { StateOptions } from '../state/state.js';
|
|
7
|
+
export interface SyncedSource<A> {
|
|
8
|
+
readonly snapshot: () => A;
|
|
9
|
+
readonly subscribe: (onChange: () => void) => () => void;
|
|
10
|
+
}
|
|
11
|
+
export interface SyncedStoreSchemaReflection {
|
|
12
|
+
readonly ast: Schema.Schema<unknown, unknown, unknown>['ast'];
|
|
13
|
+
}
|
|
14
|
+
export interface SyncedStoreManifest<N extends string> extends Manifest {
|
|
15
|
+
readonly kind: 'SyncedStore';
|
|
16
|
+
readonly name: N;
|
|
17
|
+
readonly schema: SyncedStoreSchemaReflection;
|
|
18
|
+
readonly title: Option.Option<string>;
|
|
19
|
+
readonly description: Option.Option<string>;
|
|
20
|
+
}
|
|
21
|
+
export declare const SyncedStoreIdentifierTypeId: unique symbol;
|
|
22
|
+
export type SyncedStoreIdentifierTypeId = typeof SyncedStoreIdentifierTypeId;
|
|
23
|
+
export interface SyncedStoreIdentifier<N extends string, in out A> extends Store<A> {
|
|
24
|
+
readonly [SyncedStoreIdentifierTypeId]: N;
|
|
25
|
+
}
|
|
26
|
+
export interface SyncedStoreClass<N extends string, in out A> extends EffectType<A, never, SyncedStoreIdentifier<N, A>>, Source<N, A, SyncedStoreIdentifier<N, A>> {
|
|
27
|
+
new (): {};
|
|
28
|
+
readonly manifest: SyncedStoreManifest<N>;
|
|
29
|
+
readonly store: Context.Tag<SyncedStoreIdentifier<N, A>, Store<A>>;
|
|
30
|
+
readonly name: N;
|
|
31
|
+
readonly capture: <Result>(visit: SourceCapture<Result>) => Result;
|
|
32
|
+
}
|
|
33
|
+
export interface StoreCarrier<Identifier, A> {
|
|
34
|
+
readonly store: Context.Tag<Identifier, Store<A>>;
|
|
35
|
+
}
|
|
36
|
+
export type AnySyncedStore = AnySource & {
|
|
37
|
+
readonly manifest: Manifest & {
|
|
38
|
+
readonly kind: 'SyncedStore';
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
export type SyncedValue<S> = S extends SyncedStoreClass<infer _N, infer A> ? A : never;
|
|
42
|
+
export declare const make: <const N extends string, ValueSchema extends Schema.Schema.AnyNoContext>(name: N, schema: ValueSchema, options?: StateOptions) => SyncedStoreClass<N, Schema.Schema.Type<ValueSchema>>;
|
|
43
|
+
export declare const live: <Identifier, A, R>(def: StoreCarrier<Identifier, A>, acquire: Effect.Effect<SyncedSource<A>, never, R>) => Layer.Layer<Identifier, never, Exclude<R, Scope.Scope>>;
|
|
44
|
+
//# sourceMappingURL=syncedStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syncedStore.d.ts","sourceRoot":"","sources":["../../src/synced/syncedStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Context, Effect, Layer, Option } from 'effect';
|
|
2
|
+
import { yieldableClass } from '../definition/definition.js';
|
|
3
|
+
import { resolveScheduler } from '../internal/scheduler.js';
|
|
4
|
+
import { makeDerivedStore } from '../internal/store.js';
|
|
5
|
+
import { readTracked } from '../internal/track.js';
|
|
6
|
+
export const SyncedStoreIdentifierTypeId = Symbol.for('reform/SyncedStoreIdentifier');
|
|
7
|
+
export const make = (name, schema, options = {}) => {
|
|
8
|
+
const store = Context.GenericTag(`reform/syncedStore/${name}`);
|
|
9
|
+
const manifest = {
|
|
10
|
+
kind: 'SyncedStore',
|
|
11
|
+
name,
|
|
12
|
+
schema,
|
|
13
|
+
title: Option.fromNullable(options.title),
|
|
14
|
+
description: Option.fromNullable(options.description),
|
|
15
|
+
};
|
|
16
|
+
const read = Effect.flatMap(store, readTracked);
|
|
17
|
+
const synced = yieldableClass(read, {
|
|
18
|
+
manifest,
|
|
19
|
+
store,
|
|
20
|
+
name,
|
|
21
|
+
capture: (visit) => visit(synced),
|
|
22
|
+
});
|
|
23
|
+
return synced;
|
|
24
|
+
};
|
|
25
|
+
export const live = (def, acquire) => Layer.scoped(def.store, Effect.gen(function* () {
|
|
26
|
+
const scheduler = yield* resolveScheduler;
|
|
27
|
+
const source = yield* acquire;
|
|
28
|
+
const { store, unsubscribe } = makeDerivedStore(source.snapshot, source.subscribe, scheduler);
|
|
29
|
+
yield* Effect.addFinalizer(() => Effect.sync(unsubscribe));
|
|
30
|
+
return store;
|
|
31
|
+
}));
|
|
32
|
+
//# sourceMappingURL=syncedStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syncedStore.js","sourceRoot":"","sources":["../../src/synced/syncedStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAA2B,MAAM,QAAQ,CAAA;AAEhF,OAAO,EAAiB,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAc,MAAM,mBAAmB,CAAA;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAqB/C,MAAM,CAAC,MAAM,2BAA2B,GAAkB,MAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAA;AA2BpG,MAAM,CAAC,MAAM,IAAI,GAAG,CAClB,IAAO,EACP,MAAmB,EACnB,UAAwB,EAAE,EAC4B,EAAE;IAExD,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAC9B,sBAAsB,IAAI,EAAE,CAC7B,CAAA;IACD,MAAM,QAAQ,GAA2B;QACvC,IAAI,EAAE,aAAa;QACnB,IAAI;QACJ,MAAM;QACN,KAAK,EAAE,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC;QACzC,WAAW,EAAE,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC;KACtD,CAAA;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;IAC/C,MAAM,MAAM,GAA2B,cAAc,CAAC,IAAI,EAAE;QAC1D,QAAQ;QACR,KAAK;QACL,IAAI;QACJ,OAAO,EAAE,CAAS,KAA4B,EAAU,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC;KACzE,CAAC,CAAA;IACF,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,IAAI,GAAG,CAClB,GAAgC,EAChC,OAAiD,EACQ,EAAE,CAC3D,KAAK,CAAC,MAAM,CACV,GAAG,CAAC,KAAK,EACT,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,gBAAgB,CAAA;IACzC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,OAAO,CAAA;IAC7B,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;IAC7F,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAA;IAC1D,OAAO,KAAK,CAAA;AACd,CAAC,CAAC,CACH,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Effect } from 'effect';
|
|
2
|
+
export declare const tick: (ms?: number) => Effect.Effect<void>;
|
|
3
|
+
export declare const flush: (turns?: number) => Effect.Effect<void>;
|
|
4
|
+
export declare const until: <A>(read: () => A, predicate: (value: A) => boolean, rounds?: number) => Effect.Effect<A>;
|
|
5
|
+
export interface FlightGate {
|
|
6
|
+
/** Wrap a query body: it records its entry, then parks while the gate holds. */
|
|
7
|
+
readonly through: <A, E, R>(body: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
|
|
8
|
+
/** Park every flight that reaches the gate from now on. */
|
|
9
|
+
readonly hold: Effect.Effect<void>;
|
|
10
|
+
/** Let the parked flights settle; later flights pass straight through. */
|
|
11
|
+
readonly release: Effect.Effect<void>;
|
|
12
|
+
/** Resolve once `count` flights have reached the gate. */
|
|
13
|
+
readonly awaitEntry: (count: number) => Effect.Effect<void>;
|
|
14
|
+
/** How many flights have reached the gate. */
|
|
15
|
+
readonly entered: () => number;
|
|
16
|
+
}
|
|
17
|
+
export declare const makeFlightGate: () => FlightGate;
|
|
18
|
+
//# sourceMappingURL=flight.testkit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flight.testkit.d.ts","sourceRoot":"","sources":["../../src/testkit/flight.testkit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,MAAM,EAAsB,MAAM,QAAQ,CAAA;AAWvE,eAAO,MAAM,IAAI,GAAI,WAAO,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAsC,CAAA;AAMvF,eAAO,MAAM,KAAK,GAAI,cAAS,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAGjD,CAAA;AAEH,eAAO,MAAM,KAAK,GAAI,CAAC,EACrB,MAAM,MAAM,CAAC,EACb,WAAW,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,EAChC,eAAY,KACX,MAAM,CAAC,MAAM,CAAC,CAAC,CAMd,CAAA;AAEJ,MAAM,WAAW,UAAU;IACzB,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IACnF,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAClC,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACrC,0DAA0D;IAC1D,QAAQ,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC3D,8CAA8C;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,MAAM,CAAA;CAC/B;AAED,eAAO,MAAM,cAAc,QAAO,UAqCjC,CAAA"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Deferred, Duration, Effect, MutableRef, Option } from 'effect';
|
|
2
|
+
import { microtask } from '../internal/platform.js';
|
|
3
|
+
// Coalescing/cancellation semantics are only meaningful while a query is still
|
|
4
|
+
// in flight. Tests used to build that overlap by racing wall-clock — a 25ms
|
|
5
|
+
// query delay against 5ms gaps between input writes — which silently stops
|
|
6
|
+
// overlapping on a loaded machine: the runs serialize, every key gets its own
|
|
7
|
+
// flight, and the assertion fails reporting a coalescing bug that isn't there.
|
|
8
|
+
// A gate makes the overlap explicit: hold the flight open, land the burst,
|
|
9
|
+
// release.
|
|
10
|
+
export const tick = (ms = 10) => Effect.sleep(Duration.millis(ms));
|
|
11
|
+
// The runtime notifies on the microtask queue (scheduler, stateFamily, calcFamily),
|
|
12
|
+
// so draining turns is exact where a duration is a guess: a microtask cannot be
|
|
13
|
+
// starved by host load the way a 10ms budget can. Use this to let the graph
|
|
14
|
+
// quiesce before asserting that something did NOT happen.
|
|
15
|
+
export const flush = (turns = 3) => Effect.promise(() => new Promise((resolve) => microtask(resolve))).pipe(Effect.repeatN(Math.max(turns - 1, 0)));
|
|
16
|
+
export const until = (read, predicate, rounds = 200) => Effect.suspend(() => {
|
|
17
|
+
const value = read();
|
|
18
|
+
return predicate(value) || rounds <= 0
|
|
19
|
+
? Effect.succeed(value)
|
|
20
|
+
: Effect.flatMap(tick(10), () => until(read, predicate, rounds - 1));
|
|
21
|
+
});
|
|
22
|
+
export const makeFlightGate = () => {
|
|
23
|
+
const latch = MutableRef.make(Option.none());
|
|
24
|
+
const entered = MutableRef.make(0);
|
|
25
|
+
return {
|
|
26
|
+
through: (body) => body.pipe(Effect.tap(() => Effect.suspend(() => {
|
|
27
|
+
MutableRef.update(entered, (count) => count + 1);
|
|
28
|
+
return Option.match(MutableRef.get(latch), {
|
|
29
|
+
onNone: () => Effect.void,
|
|
30
|
+
onSome: (parked) => Deferred.await(parked),
|
|
31
|
+
});
|
|
32
|
+
}))),
|
|
33
|
+
hold: Effect.flatMap(Deferred.make(), (parked) => Effect.sync(() => MutableRef.set(latch, Option.some(parked)))),
|
|
34
|
+
release: Effect.suspend(() => {
|
|
35
|
+
const parked = MutableRef.get(latch);
|
|
36
|
+
MutableRef.set(latch, Option.none());
|
|
37
|
+
return Option.match(parked, {
|
|
38
|
+
onNone: () => Effect.void,
|
|
39
|
+
onSome: (deferred) => Effect.asVoid(Deferred.succeed(deferred, undefined)),
|
|
40
|
+
});
|
|
41
|
+
}),
|
|
42
|
+
awaitEntry: (count) => Effect.asVoid(until(() => MutableRef.get(entered), (reached) => reached >= count)),
|
|
43
|
+
entered: () => MutableRef.get(entered),
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=flight.testkit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flight.testkit.js","sourceRoot":"","sources":["../../src/testkit/flight.testkit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/ui/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,MAAM,MAAM,IAAI,GAAG,SAAS,CAAA"}
|
package/dist/ui/node.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/ui/node.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trigger.d.ts","sourceRoot":"","sources":["../../src/ui/trigger.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trigger.js","sourceRoot":"","sources":["../../src/ui/trigger.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type WireProp = {
|
|
2
|
+
readonly _tag: 'Data';
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly value: unknown;
|
|
5
|
+
} | {
|
|
6
|
+
readonly _tag: 'Event';
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly handle: string;
|
|
9
|
+
};
|
|
10
|
+
export interface WireNodeExternalApi {
|
|
11
|
+
readonly id: string;
|
|
12
|
+
readonly name: string;
|
|
13
|
+
readonly parentId: string | null;
|
|
14
|
+
readonly childIndex: number;
|
|
15
|
+
readonly slot: string | null;
|
|
16
|
+
readonly key: string | null;
|
|
17
|
+
readonly props: ReadonlyArray<WireProp>;
|
|
18
|
+
}
|
|
19
|
+
export type WireNode = WireNodeExternalApi;
|
|
20
|
+
export type WireTree = ReadonlyArray<WireNode>;
|
|
21
|
+
export type WirePatch = {
|
|
22
|
+
readonly _tag: 'Upsert';
|
|
23
|
+
readonly node: WireNode;
|
|
24
|
+
} | {
|
|
25
|
+
readonly _tag: 'Delete';
|
|
26
|
+
readonly id: string;
|
|
27
|
+
};
|
|
28
|
+
export declare const diff: (previous: WireTree, next: WireTree) => ReadonlyArray<WirePatch>;
|
|
29
|
+
export declare const apply: (state: WireTree, patches: ReadonlyArray<WirePatch>) => WireTree;
|
|
30
|
+
export declare const roots: (tree: WireTree) => WireTree;
|
|
31
|
+
export declare const childrenOf: (tree: WireTree, parentId: string) => WireTree;
|
|
32
|
+
//# sourceMappingURL=tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../src/wire/tree.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,QAAQ,GAChB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACzE;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAE9E,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAA;CACxC;AAED,MAAM,MAAM,QAAQ,GAAG,mBAAmB,CAAA;AAE1C,MAAM,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAA;AAE9C,MAAM,MAAM,SAAS,GACjB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GACpD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAA;AA+DpD,eAAO,MAAM,IAAI,GAAI,UAAU,QAAQ,EAAE,MAAM,QAAQ,KAAG,aAAa,CAAC,SAAS,CAahF,CAAA;AAWD,eAAO,MAAM,KAAK,GAAI,OAAO,QAAQ,EAAE,SAAS,aAAa,CAAC,SAAS,CAAC,KAAG,QASxE,CAAA;AAIH,eAAO,MAAM,KAAK,GAAI,MAAM,QAAQ,KAAG,QAIpC,CAAA;AAEH,eAAO,MAAM,UAAU,GAAI,MAAM,QAAQ,EAAE,UAAU,MAAM,KAAG,QAI3D,CAAA"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Array, Match, Option, Order, Record as Rec } from 'effect';
|
|
2
|
+
import { sort as sortArray } from 'effect/Array';
|
|
3
|
+
const isRecord = (candidate) => typeof candidate === 'object' && candidate !== null;
|
|
4
|
+
const arraysEqual = (left, right) => left.length === right.length &&
|
|
5
|
+
left.every((element, index) => deepEqual({ left: element, right: right[index] }));
|
|
6
|
+
const recordsEqual = (left, right) => {
|
|
7
|
+
const leftKeys = Rec.keys(left);
|
|
8
|
+
const rightKeys = Rec.keys(right);
|
|
9
|
+
return (leftKeys.length === rightKeys.length &&
|
|
10
|
+
// Presence, not just value: two records of the same size whose keys differ both
|
|
11
|
+
// read `undefined` for the other's key and would compare equal. An encoded
|
|
12
|
+
// `S.optional` field keeps its key when its value is undefined, so a frame can
|
|
13
|
+
// really swap one such key for another and diff to no patches at all.
|
|
14
|
+
leftKeys.every((key) => Object.prototype.hasOwnProperty.call(right, key) &&
|
|
15
|
+
deepEqual({ left: left[key], right: right[key] })));
|
|
16
|
+
};
|
|
17
|
+
const deepEqual = ({ left, right }) => {
|
|
18
|
+
if (left === right) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
if (left === null || right === null) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
if (Array.isArray(left)) {
|
|
25
|
+
return Array.isArray(right) && arraysEqual(left, right);
|
|
26
|
+
}
|
|
27
|
+
if (Array.isArray(right)) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
if (isRecord(left) && isRecord(right)) {
|
|
31
|
+
return recordsEqual(left, right);
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
};
|
|
35
|
+
const nodesEqual = (leftNode, rightNode) => leftNode.name === rightNode.name &&
|
|
36
|
+
leftNode.parentId === rightNode.parentId &&
|
|
37
|
+
leftNode.childIndex === rightNode.childIndex &&
|
|
38
|
+
leftNode.slot === rightNode.slot &&
|
|
39
|
+
leftNode.key === rightNode.key &&
|
|
40
|
+
deepEqual({ left: leftNode.props, right: rightNode.props });
|
|
41
|
+
const isUnchanged = (node, previousById) => {
|
|
42
|
+
const previous = previousById.get(node.id);
|
|
43
|
+
return previous !== undefined && nodesEqual(previous, node);
|
|
44
|
+
};
|
|
45
|
+
export const diff = (previous, next) => {
|
|
46
|
+
const previousById = new Map(previous.map((node) => [node.id, node]));
|
|
47
|
+
const nextById = new Map(next.map((node) => [node.id, node]));
|
|
48
|
+
const deletes = previous
|
|
49
|
+
.filter((node) => !nextById.has(node.id))
|
|
50
|
+
.map((node) => ({ _tag: 'Delete', id: node.id }));
|
|
51
|
+
const upserts = next
|
|
52
|
+
.filter((node) => !isUnchanged(node, previousById))
|
|
53
|
+
.map((node) => ({ _tag: 'Upsert', node }));
|
|
54
|
+
return [...deletes, ...upserts];
|
|
55
|
+
};
|
|
56
|
+
const upsertNode = (state, node) => Option.match(Array.findFirstIndex(state, (existing) => existing.id === node.id), {
|
|
57
|
+
onNone: () => [...state, node],
|
|
58
|
+
onSome: (index) => [...state.slice(0, index), node, ...state.slice(index + 1)],
|
|
59
|
+
});
|
|
60
|
+
export const apply = (state, patches) => patches.reduce((current, patch) => Match.value(patch).pipe(Match.tag('Delete', ({ id }) => current.filter((node) => node.id !== id)), Match.tag('Upsert', ({ node }) => upsertNode(current, node)), Match.exhaustive), state);
|
|
61
|
+
const bySiblingOrder = Order.mapInput(Order.number, (node) => node.childIndex);
|
|
62
|
+
export const roots = (tree) => sortArray(tree.filter((node) => node.parentId === null), bySiblingOrder);
|
|
63
|
+
export const childrenOf = (tree, parentId) => sortArray(tree.filter((node) => node.parentId === parentId), bySiblingOrder);
|
|
64
|
+
//# sourceMappingURL=tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree.js","sourceRoot":"","sources":["../../src/wire/tree.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type Cause, Context, Effect, Layer, type ParseResult, Schema } from 'effect';
|
|
2
|
+
import type { Trigger } from '../ui/trigger.js';
|
|
3
|
+
export type TriggerHandle = string;
|
|
4
|
+
declare const UnknownTriggerBase: new (args: {
|
|
5
|
+
readonly handle: TriggerHandle;
|
|
6
|
+
}) => Cause.YieldableError & {
|
|
7
|
+
readonly _tag: 'reform/UnknownTrigger';
|
|
8
|
+
} & Readonly<{
|
|
9
|
+
readonly handle: TriggerHandle;
|
|
10
|
+
}>;
|
|
11
|
+
export declare class UnknownTrigger extends UnknownTriggerBase {
|
|
12
|
+
get message(): string;
|
|
13
|
+
}
|
|
14
|
+
export interface TriggerRegistryApi {
|
|
15
|
+
readonly register: <P, Encoded>(handle: TriggerHandle, trigger: Trigger<P>, schema: Schema.Schema<P, Encoded, never>) => Effect.Effect<void>;
|
|
16
|
+
readonly invoke: (handle: TriggerHandle, encodedPayload: unknown) => Effect.Effect<void, UnknownTrigger | ParseResult.ParseError>;
|
|
17
|
+
readonly revoke: (handle: TriggerHandle) => Effect.Effect<void>;
|
|
18
|
+
}
|
|
19
|
+
declare const TriggerRegistryBase: Context.TagClass<TriggerRegistry, 'reform/wire/TriggerRegistry', TriggerRegistryApi>;
|
|
20
|
+
export declare class TriggerRegistry extends TriggerRegistryBase {
|
|
21
|
+
}
|
|
22
|
+
export declare const make: Effect.Effect<TriggerRegistryApi>;
|
|
23
|
+
export declare const layer: Layer.Layer<TriggerRegistry>;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=triggers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triggers.d.ts","sourceRoot":"","sources":["../../src/wire/triggers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAE,OAAO,EAAQ,MAAM,EAAE,KAAK,EAAE,KAAK,WAAW,EAAO,MAAM,EAAE,MAAM,QAAQ,CAAA;AAChG,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAE5C,MAAM,MAAM,aAAa,GAAG,MAAM,CAAA;AAMlC,QAAA,MAAM,kBAAkB,EAAE,KAAK,IAAI,EAAE;IAAE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;CAAE,KAAK,KAAK,CAAC,cAAc,GAAG;IACjG,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAA;CACvC,GAAG,QAAQ,CAAC;IAAE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;CAAE,CAE7C,CAAA;AAEF,qBAAa,cAAe,SAAQ,kBAAkB;IACpD,IAAa,OAAO,IAAI,MAAM,CAE7B;CACF;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,OAAO,EAC5B,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,KACrC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,CACf,MAAM,EAAE,aAAa,EACrB,cAAc,EAAE,OAAO,KACpB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,GAAG,WAAW,CAAC,UAAU,CAAC,CAAA;IACjE,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;CAChE;AAED,QAAA,MAAM,mBAAmB,EAAE,OAAO,CAAC,QAAQ,CACzC,eAAe,EACf,6BAA6B,EAC7B,kBAAkB,CACiE,CAAA;AAErF,qBAAa,eAAgB,SAAQ,mBAAmB;CAAG;AAE3D,eAAO,MAAM,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAoCjD,CAAA;AAEF,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,eAAe,CAAuC,CAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Context, Data, Effect, Layer, Ref, Schema } from 'effect';
|
|
2
|
+
const UnknownTriggerBase = (Data.TaggedError('reform/UnknownTrigger'));
|
|
3
|
+
export class UnknownTrigger extends UnknownTriggerBase {
|
|
4
|
+
get message() {
|
|
5
|
+
return `reform: no trigger registered under handle '${this.handle}'`;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
const TriggerRegistryBase = Context.Tag('reform/wire/TriggerRegistry')();
|
|
9
|
+
export class TriggerRegistry extends TriggerRegistryBase {
|
|
10
|
+
}
|
|
11
|
+
export const make = Effect.gen(function* () {
|
|
12
|
+
const entries = yield* Ref.make(new Map());
|
|
13
|
+
const register = (handle, trigger, schema) => Ref.update(entries, (map) => new Map(map).set(handle, {
|
|
14
|
+
invoke: (encodedPayload) => Schema.decodeUnknown(schema)(encodedPayload).pipe(Effect.map((payload) => trigger(payload))),
|
|
15
|
+
}));
|
|
16
|
+
const invoke = Effect.fn('invoke')(function* (handle, encodedPayload) {
|
|
17
|
+
const entry = (yield* Ref.get(entries)).get(handle);
|
|
18
|
+
if (entry === undefined) {
|
|
19
|
+
return yield* Effect.fail(new UnknownTrigger({ handle }));
|
|
20
|
+
}
|
|
21
|
+
yield* entry.invoke(encodedPayload);
|
|
22
|
+
});
|
|
23
|
+
const revoke = (handle) => Ref.update(entries, (map) => {
|
|
24
|
+
const next = new Map(map);
|
|
25
|
+
next.delete(handle);
|
|
26
|
+
return next;
|
|
27
|
+
});
|
|
28
|
+
return { register, invoke, revoke };
|
|
29
|
+
});
|
|
30
|
+
export const layer = Layer.effect(TriggerRegistry, make);
|
|
31
|
+
//# sourceMappingURL=triggers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triggers.js","sourceRoot":"","sources":["../../src/wire/triggers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAoB,GAAG,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAShG,MAAM,kBAAkB,GAE2B,CAAA,IAAI,CAAC,WAAW,CAAC,uBAAuB,CAEzF,CAAA,CAAA;AAEF,MAAM,OAAO,cAAe,SAAQ,kBAAkB;IACpD,IAAa,OAAO;QAClB,OAAO,+CAA+C,IAAI,CAAC,MAAM,GAAG,CAAA;IACtE,CAAC;CACF;AAeD,MAAM,mBAAmB,GAIrB,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,EAAuC,CAAA;AAErF,MAAM,OAAO,eAAgB,SAAQ,mBAAmB;CAAG;AAE3D,MAAM,CAAC,MAAM,IAAI,GAAsC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IACzE,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,EAA+B,CAAC,CAAA;IAEvE,MAAM,QAAQ,GAAG,CACf,MAAqB,EACrB,OAAmB,EACnB,MAAwC,EACnB,EAAE,CACvB,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAC1B,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE;QACvB,MAAM,EAAE,CAAC,cAAc,EAAE,EAAE,CACzB,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC,IAAI,CAC/C,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAC1C;KACJ,CAAC,CACH,CAAA;IAEH,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,EAC1C,MAAqB,EACrB,cAAuB;QAEvB,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACnD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;QAC3D,CAAC;QACD,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;IACrC,CAAC,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,CAAC,MAAqB,EAAuB,EAAE,CAC5D,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QAC1B,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QACzB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QACnB,OAAO,IAAI,CAAA;IACb,CAAC,CAAC,CAAA;IAEJ,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,CAAA;AACrC,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,KAAK,GAAiC,KAAK,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playfast/reform",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "The renderer-neutral core of the reform framework — typed, headless state, events, reducers, derived values, async/remote data, and compositions built on Effect.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"effect",
|
|
@@ -20,15 +20,26 @@
|
|
|
20
20
|
"directory": "packages/reform"
|
|
21
21
|
},
|
|
22
22
|
"files": [
|
|
23
|
+
"dist",
|
|
23
24
|
"src",
|
|
24
25
|
"README.md"
|
|
25
26
|
],
|
|
26
27
|
"type": "module",
|
|
27
28
|
"sideEffects": false,
|
|
29
|
+
"main": "./dist/index.js",
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
28
31
|
"exports": {
|
|
29
32
|
"./package.json": "./package.json",
|
|
30
|
-
".":
|
|
31
|
-
|
|
33
|
+
".": {
|
|
34
|
+
"playfast-src": "./src/index.ts",
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"default": "./dist/index.js"
|
|
37
|
+
},
|
|
38
|
+
"./*": {
|
|
39
|
+
"playfast-src": "./src/*.ts",
|
|
40
|
+
"types": "./dist/*.d.ts",
|
|
41
|
+
"default": "./dist/*.js"
|
|
42
|
+
}
|
|
32
43
|
},
|
|
33
44
|
"publishConfig": {
|
|
34
45
|
"access": "public"
|
|
@@ -36,12 +47,13 @@
|
|
|
36
47
|
"scripts": {
|
|
37
48
|
"clean": "rm -rf dist .tsbuildinfo",
|
|
38
49
|
"check": "tsc --noEmit",
|
|
39
|
-
"build": "tsc -p tsconfig.build.json",
|
|
50
|
+
"build": "rm -rf dist .tsbuildinfo && tsc -p tsconfig.build.json && bun ../../scripts/fix-esm-extensions.ts dist",
|
|
40
51
|
"test": "vitest run",
|
|
41
52
|
"test:watch": "vitest",
|
|
42
53
|
"coverage": "vitest run --coverage",
|
|
43
54
|
"lint": "oxlint src",
|
|
44
|
-
"lint:fix": "oxlint --fix src"
|
|
55
|
+
"lint:fix": "oxlint --fix src",
|
|
56
|
+
"prepack": "bun run build"
|
|
45
57
|
},
|
|
46
58
|
"peerDependencies": {
|
|
47
59
|
"effect": "*",
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { expect, it } from '@effect/vitest'
|
|
2
|
+
import { Data, Effect, Layer, Option, Schema as S } from 'effect'
|
|
3
|
+
import { AsyncCalc, Engine, State, StateGroup } from '../index'
|
|
4
|
+
import { makeFlightGate, until } from '../testkit/flight.testkit'
|
|
5
|
+
import { toAsyncData } from './queryState'
|
|
6
|
+
|
|
7
|
+
// github.com/springdotnew/reform/issues/22 — a retained payload must name the
|
|
8
|
+
// input key it answers, so a consumer can never read the previous key's fields
|
|
9
|
+
// as an answer to the key it asked with.
|
|
10
|
+
|
|
11
|
+
class Boom extends Data.TaggedError('Boom')<{ readonly chatId: string }> {}
|
|
12
|
+
|
|
13
|
+
// The portal's chat-history shape in miniature: readers take a write grant off
|
|
14
|
+
// this object, so mis-attributing it hands out an affordance, not a flicker.
|
|
15
|
+
const Chat = S.Struct({ chatId: S.String, canWrite: S.Boolean })
|
|
16
|
+
|
|
17
|
+
class ChatId extends State.make('chatId', S.String) {}
|
|
18
|
+
class Inputs extends StateGroup.make(ChatId) {}
|
|
19
|
+
const chatId = StateGroup.select(Inputs, 'chatId')
|
|
20
|
+
const seededAtA = StateGroup.live(Inputs, { chatId: 'A' })
|
|
21
|
+
|
|
22
|
+
it.live('a key change does not surface the previous key as Success', () => {
|
|
23
|
+
class History extends AsyncCalc.make('HistorySuccess', {
|
|
24
|
+
inputs: [chatId],
|
|
25
|
+
output: Chat,
|
|
26
|
+
alwaysOn: true,
|
|
27
|
+
}) {}
|
|
28
|
+
const gate = makeFlightGate()
|
|
29
|
+
const HistoryLive = AsyncCalc.live(History, {
|
|
30
|
+
query: ({ chatId: id }) => gate.through(Effect.succeed({ chatId: id, canWrite: id === 'A' })),
|
|
31
|
+
})
|
|
32
|
+
const TestLayer = HistoryLive.pipe(Layer.provideMerge(seededAtA))
|
|
33
|
+
|
|
34
|
+
return Effect.gen(function* () {
|
|
35
|
+
const source = yield* chatId.store
|
|
36
|
+
const store = yield* History.store
|
|
37
|
+
yield* until(
|
|
38
|
+
() => store.get(),
|
|
39
|
+
(v) => v._tag === 'Success',
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
// Park B's flight so the window where A's payload is retained stays open.
|
|
43
|
+
yield* gate.hold
|
|
44
|
+
source.set('B')
|
|
45
|
+
yield* gate.awaitEntry(2)
|
|
46
|
+
|
|
47
|
+
expect(store.get()._tag).toBe('Loading')
|
|
48
|
+
|
|
49
|
+
yield* gate.release
|
|
50
|
+
const settled = yield* until(
|
|
51
|
+
() => store.get(),
|
|
52
|
+
(v) => v._tag === 'Success' && v.refetching === false,
|
|
53
|
+
)
|
|
54
|
+
expect(settled).toMatchObject({ _tag: 'Success', value: { chatId: 'B', canWrite: false } })
|
|
55
|
+
}).pipe(Effect.provide(TestLayer))
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it.live('a key change does not surface the previous key as Error', () => {
|
|
59
|
+
class History extends AsyncCalc.make('HistoryFailure', {
|
|
60
|
+
inputs: [chatId],
|
|
61
|
+
output: Chat,
|
|
62
|
+
error: S.instanceOf(Boom),
|
|
63
|
+
alwaysOn: true,
|
|
64
|
+
}) {}
|
|
65
|
+
const gate = makeFlightGate()
|
|
66
|
+
const HistoryLive = AsyncCalc.live(History, {
|
|
67
|
+
query: ({ chatId: id }) =>
|
|
68
|
+
id === 'A'
|
|
69
|
+
? Effect.fail(new Boom({ chatId: id }))
|
|
70
|
+
: gate.through(Effect.succeed({ chatId: id, canWrite: false })),
|
|
71
|
+
})
|
|
72
|
+
const TestLayer = HistoryLive.pipe(Layer.provideMerge(seededAtA))
|
|
73
|
+
|
|
74
|
+
return Effect.gen(function* () {
|
|
75
|
+
const source = yield* chatId.store
|
|
76
|
+
const store = yield* History.store
|
|
77
|
+
yield* until(
|
|
78
|
+
() => store.get(),
|
|
79
|
+
(v) => v._tag === 'Error',
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
// A's failure is not an answer about B.
|
|
83
|
+
yield* gate.hold
|
|
84
|
+
source.set('B')
|
|
85
|
+
yield* gate.awaitEntry(1)
|
|
86
|
+
|
|
87
|
+
expect(store.get()._tag).toBe('Loading')
|
|
88
|
+
}).pipe(Effect.provide(TestLayer))
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it.live('keepPreviousData opts back into showing the previous key while refetching', () => {
|
|
92
|
+
class History extends AsyncCalc.make('HistoryKept', {
|
|
93
|
+
inputs: [chatId],
|
|
94
|
+
output: Chat,
|
|
95
|
+
alwaysOn: true,
|
|
96
|
+
}) {}
|
|
97
|
+
const gate = makeFlightGate()
|
|
98
|
+
const HistoryLive = AsyncCalc.live(History, {
|
|
99
|
+
query: ({ chatId: id }) => gate.through(Effect.succeed({ chatId: id, canWrite: id === 'A' })),
|
|
100
|
+
keepPreviousData: true,
|
|
101
|
+
})
|
|
102
|
+
const TestLayer = HistoryLive.pipe(Layer.provideMerge(seededAtA))
|
|
103
|
+
|
|
104
|
+
return Effect.gen(function* () {
|
|
105
|
+
const source = yield* chatId.store
|
|
106
|
+
const store = yield* History.store
|
|
107
|
+
yield* until(
|
|
108
|
+
() => store.get(),
|
|
109
|
+
(v) => v._tag === 'Success',
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
yield* gate.hold
|
|
113
|
+
source.set('B')
|
|
114
|
+
yield* gate.awaitEntry(2)
|
|
115
|
+
|
|
116
|
+
expect(store.get()).toMatchObject({
|
|
117
|
+
_tag: 'Success',
|
|
118
|
+
value: { chatId: 'A' },
|
|
119
|
+
refetching: true,
|
|
120
|
+
})
|
|
121
|
+
}).pipe(Effect.provide(TestLayer))
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
it.live('a same-key refetch still keeps the settled value under refetching', () => {
|
|
125
|
+
class HistorySameKey extends AsyncCalc.make('HistorySameKey', {
|
|
126
|
+
inputs: [chatId],
|
|
127
|
+
output: Chat,
|
|
128
|
+
alwaysOn: true,
|
|
129
|
+
}) {}
|
|
130
|
+
const gate = makeFlightGate()
|
|
131
|
+
const HistoryLive = AsyncCalc.live(HistorySameKey, {
|
|
132
|
+
query: ({ chatId: id }) => gate.through(Effect.succeed({ chatId: id, canWrite: true })),
|
|
133
|
+
})
|
|
134
|
+
const TestLayer = HistoryLive.pipe(Layer.provideMerge(seededAtA), Layer.provideMerge(Engine))
|
|
135
|
+
|
|
136
|
+
return Effect.gen(function* () {
|
|
137
|
+
const store = yield* HistorySameKey.store
|
|
138
|
+
yield* until(
|
|
139
|
+
() => store.get(),
|
|
140
|
+
(v) => v._tag === 'Success',
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
// Same key: the payload still answers the question being asked.
|
|
144
|
+
yield* gate.hold
|
|
145
|
+
yield* AsyncCalc.refetch(HistorySameKey)
|
|
146
|
+
yield* gate.awaitEntry(2)
|
|
147
|
+
|
|
148
|
+
expect(store.get()).toMatchObject({
|
|
149
|
+
_tag: 'Success',
|
|
150
|
+
value: { chatId: 'A' },
|
|
151
|
+
refetching: true,
|
|
152
|
+
})
|
|
153
|
+
}).pipe(Effect.provide(TestLayer))
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
it('toAsyncData reports data from a superseded key as loading', () => {
|
|
157
|
+
const retained = {
|
|
158
|
+
data: Option.some({ chatId: 'A', canWrite: true }),
|
|
159
|
+
error: Option.none(),
|
|
160
|
+
isFetching: true,
|
|
161
|
+
isStale: false,
|
|
162
|
+
isPreviousKey: true,
|
|
163
|
+
keepPreviousData: false,
|
|
164
|
+
}
|
|
165
|
+
expect(toAsyncData(retained, false)._tag).toBe('Loading')
|
|
166
|
+
// The opt-in travels on the state, so every reading of one query agrees.
|
|
167
|
+
expect(toAsyncData({ ...retained, keepPreviousData: true }, false)).toMatchObject({
|
|
168
|
+
_tag: 'Success',
|
|
169
|
+
refetching: true,
|
|
170
|
+
})
|
|
171
|
+
// …and it keeps a payload, not a verdict: with nothing retained there is nothing
|
|
172
|
+
// to opt into, so a previous key's error stays withheld.
|
|
173
|
+
const failedOnly = {
|
|
174
|
+
data: Option.none<{ readonly chatId: string }>(),
|
|
175
|
+
error: Option.some('boom'),
|
|
176
|
+
isFetching: true,
|
|
177
|
+
isStale: false,
|
|
178
|
+
isPreviousKey: true,
|
|
179
|
+
keepPreviousData: true,
|
|
180
|
+
}
|
|
181
|
+
expect(toAsyncData(failedOnly, false)._tag).toBe('Loading')
|
|
182
|
+
})
|