@playfast/reform 1.2.0 → 1.3.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/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 +21 -0
- package/dist/calc/asyncCalc.d.ts.map +1 -0
- package/dist/calc/asyncCalc.js +90 -0
- package/dist/calc/asyncCalc.js.map +1 -0
- package/dist/calc/asyncCalcTypes.d.ts +78 -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 +113 -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 +12 -0
- package/dist/calc/queryState.d.ts.map +1 -0
- package/dist/calc/queryState.js +17 -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 +86 -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 +56 -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 +92 -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 +47 -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 +67 -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/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/queryDriver.d.ts +7 -0
- package/dist/internal/queryDriver.d.ts.map +1 -0
- package/dist/internal/queryDriver.js +198 -0
- package/dist/internal/queryDriver.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 +19 -0
- package/dist/internal/queryDriverHydrate.js.map +1 -0
- package/dist/internal/queryDriverStore.d.ts +54 -0
- package/dist/internal/queryDriverStore.d.ts.map +1 -0
- package/dist/internal/queryDriverStore.js +77 -0
- package/dist/internal/queryDriverStore.js.map +1 -0
- package/dist/internal/queryDriverTypes.d.ts +41 -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 +13 -0
- package/dist/internal/scheduler.d.ts.map +1 -0
- package/dist/internal/scheduler.js +38 -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 +42 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +58 -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 +20 -0
- package/dist/remote/pendingQueue.d.ts.map +1 -0
- package/dist/remote/pendingQueue.js +113 -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 +176 -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 +41 -0
- package/dist/remote/remoteStateSend.d.ts.map +1 -0
- package/dist/remote/remoteStateSend.js +67 -0
- package/dist/remote/remoteStateSend.js.map +1 -0
- package/dist/remote/remoteStateTypes.d.ts +103 -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 +17 -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 +151 -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 +67 -0
- package/dist/runtime/eventBudget.js.map +1 -0
- package/dist/runtime/featureMount.d.ts +16 -0
- package/dist/runtime/featureMount.d.ts.map +1 -0
- package/dist/runtime/featureMount.js +54 -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 +32 -0
- package/dist/runtime/loop.d.ts.map +1 -0
- package/dist/runtime/loop.js +128 -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 +91 -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 +45 -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 +59 -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/boundary/boundary.test.ts +26 -23
- package/src/calc/asyncCalc.invalidate.test.ts +258 -55
- package/src/calc/asyncCalc.test.ts +225 -85
- package/src/calc/asyncCalc.ts +27 -141
- package/src/calc/asyncCalcTypes.test.ts +64 -0
- package/src/calc/asyncCalcTypes.ts +139 -0
- package/src/calc/calc.test.ts +10 -11
- package/src/calc/calcFamily.test.ts +12 -12
- package/src/channel/channel.ts +8 -106
- package/src/channel/procedures.ts +108 -0
- package/src/compose/composition.ts +49 -246
- package/src/compose/compositionTypes.ts +249 -0
- package/src/event/event.fromSource.test.ts +12 -12
- package/src/feature/feature.ts +50 -1210
- package/src/feature/feature.typecheck.ts +2 -61
- package/src/feature/featureBinding.ts +158 -0
- package/src/feature/featureClass.ts +162 -0
- package/src/feature/featureConfig.ts +192 -0
- package/src/feature/featureFactory.ts +163 -0
- package/src/feature/featureModule.ts +136 -0
- package/src/feature/featureModule.typecheck.ts +63 -0
- package/src/feature/featureNativeTree.ts +152 -0
- package/src/feature/featureRequirement.ts +82 -0
- package/src/feature/featureVariants.ts +234 -0
- package/src/feature/mountFeature.ts +54 -0
- package/src/graph/closure.ts +45 -226
- package/src/graph/services.ts +95 -0
- package/src/graph/summary.ts +134 -0
- package/src/internal/queryDriver.ts +20 -89
- package/src/internal/queryDriverHydrate.ts +45 -0
- package/src/internal/queryDriverTypes.ts +8 -10
- package/src/internal/store.test.ts +27 -6
- package/src/remote/pendingQueue.ts +145 -0
- package/src/remote/remoteState.test.ts +28 -22
- package/src/remote/remoteState.ts +63 -489
- package/src/remote/remoteStateMake.ts +97 -0
- package/src/remote/remoteStateSend.ts +122 -0
- package/src/remote/remoteStateTypes.ts +155 -0
- package/src/runtime/appRuntime.activation.test.ts +9 -5
- package/src/runtime/appRuntime.test.ts +40 -16
- package/src/runtime/appRuntime.ts +17 -472
- package/src/runtime/capturedAppRuntime.ts +274 -0
- package/src/runtime/eventBudget.test.ts +38 -8
- package/src/runtime/featureMount.ts +94 -0
- package/src/runtime/hardening.test.ts +18 -4
- package/src/runtime/instrumentation.test.ts +49 -12
- package/src/runtime/loop.test.ts +51 -10
- package/src/runtime/runtimeHandle.ts +124 -0
- package/src/state/stateFamily.test.ts +25 -8
- package/src/testkit/flight.testkit.ts +9 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { type Effect, Option, Schema } from 'effect'
|
|
2
|
+
import type { AnyComposition, CompositionClass } from '../compose/composition'
|
|
3
|
+
import type { UiContract } from '../compose/ui'
|
|
4
|
+
import {
|
|
5
|
+
type AnyFeatureGraphSummary,
|
|
6
|
+
FeatureChildSummaryTypeId,
|
|
7
|
+
FeatureGraphSummaryTypeId,
|
|
8
|
+
FeatureGraphValidTypeId,
|
|
9
|
+
FeatureModuleGraphValidTypeId,
|
|
10
|
+
type FeatureSummaryCompositionIdentity,
|
|
11
|
+
type FeatureSummaryCompositionProps,
|
|
12
|
+
type FeatureSummaryContract,
|
|
13
|
+
type FeatureSummaryInput,
|
|
14
|
+
type FeatureSummaryName,
|
|
15
|
+
type FeatureSummaryOpenServices,
|
|
16
|
+
type FeatureSummaryStates,
|
|
17
|
+
type FeatureSummaryUsesInput,
|
|
18
|
+
SlotBindingSummaryTypeId,
|
|
19
|
+
} from '../graph/closure'
|
|
20
|
+
import type { FeatureLoadFailed } from '../internal/errors'
|
|
21
|
+
import type { Tagged } from '../runtime/bus'
|
|
22
|
+
import {
|
|
23
|
+
type FeatureBinding,
|
|
24
|
+
type FeatureBindingCapture,
|
|
25
|
+
FeatureBindingTypeId,
|
|
26
|
+
type FeatureManifest,
|
|
27
|
+
} from './featureBinding'
|
|
28
|
+
import type { RuntimePlaceholders } from './featureConfig'
|
|
29
|
+
import type { LoadedModule } from './featureModule'
|
|
30
|
+
import type { FeatureSummaryOf } from './featureNativeTree'
|
|
31
|
+
import type { FeatureRequirement } from './featureRequirement'
|
|
32
|
+
|
|
33
|
+
export const makeFeatureManifest = (
|
|
34
|
+
name: string,
|
|
35
|
+
strategy: 'lazy' | 'default',
|
|
36
|
+
composition: AnyComposition,
|
|
37
|
+
placeholder: Option.Option<RuntimePlaceholders>,
|
|
38
|
+
): FeatureManifest => ({
|
|
39
|
+
kind: 'Feature',
|
|
40
|
+
name,
|
|
41
|
+
strategy,
|
|
42
|
+
composition: composition.manifest,
|
|
43
|
+
placeholder: Option.map(placeholder, (placeholders) => ({
|
|
44
|
+
loading: placeholders.loading.manifest,
|
|
45
|
+
failed: placeholders.failed.manifest,
|
|
46
|
+
})),
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const makeFeatureInputParser =
|
|
50
|
+
(
|
|
51
|
+
composition: AnyComposition,
|
|
52
|
+
inputSchema: Schema.Schema.AnyNoContext | undefined,
|
|
53
|
+
placeholder: Option.Option<RuntimePlaceholders>,
|
|
54
|
+
): ((input: unknown) => Option.Option<unknown>) =>
|
|
55
|
+
(input) =>
|
|
56
|
+
Option.flatMap(
|
|
57
|
+
Option.match(Option.fromNullable(inputSchema), {
|
|
58
|
+
onNone: () => Option.some(input),
|
|
59
|
+
onSome: (schema) => Schema.validateOption(schema)(input),
|
|
60
|
+
}),
|
|
61
|
+
(decoded) =>
|
|
62
|
+
Option.flatMap(composition.parseProps(decoded), () =>
|
|
63
|
+
Option.match(placeholder, {
|
|
64
|
+
onNone: () => Option.some(decoded),
|
|
65
|
+
onSome: (placeholders) =>
|
|
66
|
+
Option.map(placeholders.loading.parseProps(decoded), () => decoded),
|
|
67
|
+
}),
|
|
68
|
+
),
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
export const makeFeatureSummary = <
|
|
72
|
+
FeatureIdentity,
|
|
73
|
+
MountProps,
|
|
74
|
+
CompositionProps,
|
|
75
|
+
C extends UiContract,
|
|
76
|
+
S extends ReadonlyArray<unknown>,
|
|
77
|
+
N extends string,
|
|
78
|
+
Identity,
|
|
79
|
+
OpenServices,
|
|
80
|
+
SupportOpenServices,
|
|
81
|
+
UsesInput extends boolean,
|
|
82
|
+
Input,
|
|
83
|
+
>(
|
|
84
|
+
composition: CompositionClass<CompositionProps, C, S, N, Identity>,
|
|
85
|
+
): FeatureSummaryOf<
|
|
86
|
+
FeatureIdentity,
|
|
87
|
+
MountProps,
|
|
88
|
+
CompositionProps,
|
|
89
|
+
C,
|
|
90
|
+
S,
|
|
91
|
+
N,
|
|
92
|
+
Identity,
|
|
93
|
+
OpenServices,
|
|
94
|
+
SupportOpenServices,
|
|
95
|
+
UsesInput,
|
|
96
|
+
Input
|
|
97
|
+
> => ({
|
|
98
|
+
[SlotBindingSummaryTypeId]: SlotBindingSummaryTypeId,
|
|
99
|
+
[FeatureChildSummaryTypeId]: {
|
|
100
|
+
featureIdentity: [],
|
|
101
|
+
compositionIdentity: [],
|
|
102
|
+
},
|
|
103
|
+
[FeatureGraphSummaryTypeId]: {
|
|
104
|
+
featureIdentity: [],
|
|
105
|
+
mountProps: [],
|
|
106
|
+
compositionProps: [],
|
|
107
|
+
contract: [],
|
|
108
|
+
states: [],
|
|
109
|
+
name: composition.manifest.name,
|
|
110
|
+
compositionIdentity: [],
|
|
111
|
+
openServices: [],
|
|
112
|
+
supportOpenServices: [],
|
|
113
|
+
usesInput: [],
|
|
114
|
+
input: [],
|
|
115
|
+
validated: FeatureModuleGraphValidTypeId,
|
|
116
|
+
},
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
export const makeFeatureBinding = <
|
|
120
|
+
Summary extends AnyFeatureGraphSummary,
|
|
121
|
+
ROut,
|
|
122
|
+
DirectRequires extends ReadonlyArray<FeatureRequirement>,
|
|
123
|
+
>(
|
|
124
|
+
identity: symbol,
|
|
125
|
+
manifest: FeatureManifest,
|
|
126
|
+
summary: Summary,
|
|
127
|
+
composition: CompositionClass<
|
|
128
|
+
FeatureSummaryCompositionProps<Summary>,
|
|
129
|
+
FeatureSummaryContract<Summary>,
|
|
130
|
+
FeatureSummaryStates<Summary>,
|
|
131
|
+
FeatureSummaryName<Summary>,
|
|
132
|
+
FeatureSummaryCompositionIdentity<Summary>
|
|
133
|
+
>,
|
|
134
|
+
load: Effect.Effect<
|
|
135
|
+
LoadedModule<
|
|
136
|
+
ROut,
|
|
137
|
+
DirectRequires,
|
|
138
|
+
FeatureSummaryOpenServices<Summary>,
|
|
139
|
+
FeatureSummaryUsesInput<Summary>,
|
|
140
|
+
FeatureSummaryInput<Summary>
|
|
141
|
+
>,
|
|
142
|
+
FeatureLoadFailed
|
|
143
|
+
>,
|
|
144
|
+
placeholder: Option.Option<RuntimePlaceholders>,
|
|
145
|
+
inputSchema: Schema.Schema.AnyNoContext | undefined,
|
|
146
|
+
boot: ReadonlyArray<Tagged>,
|
|
147
|
+
): FeatureBinding<Summary, ROut, DirectRequires> => {
|
|
148
|
+
const binding: FeatureBinding<Summary, ROut, DirectRequires> = {
|
|
149
|
+
[FeatureBindingTypeId]: FeatureBindingTypeId,
|
|
150
|
+
[FeatureGraphValidTypeId]: FeatureGraphValidTypeId,
|
|
151
|
+
manifest,
|
|
152
|
+
identity,
|
|
153
|
+
summary,
|
|
154
|
+
composition,
|
|
155
|
+
strategy: manifest.strategy,
|
|
156
|
+
load,
|
|
157
|
+
placeholder,
|
|
158
|
+
parseInput: makeFeatureInputParser(composition, inputSchema, placeholder),
|
|
159
|
+
boot,
|
|
160
|
+
capture: <Result>(visit: FeatureBindingCapture<Result>): Result => visit(binding),
|
|
161
|
+
}
|
|
162
|
+
return binding
|
|
163
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { Effect, type Layer, type Schema } from 'effect'
|
|
2
|
+
import {
|
|
3
|
+
FeatureModuleGraphValidTypeId,
|
|
4
|
+
type ModuleOpenServices,
|
|
5
|
+
type ValidateFeatureGraphLayer,
|
|
6
|
+
} from '../graph/closure'
|
|
7
|
+
import { FeatureLoadFailed } from '../internal/errors'
|
|
8
|
+
import type {
|
|
9
|
+
DefaultFeatureOpenServices,
|
|
10
|
+
FeatureModuleInput,
|
|
11
|
+
FeatureRequirement,
|
|
12
|
+
} from './featureRequirement'
|
|
13
|
+
|
|
14
|
+
export interface FeatureModule<
|
|
15
|
+
ROut,
|
|
16
|
+
DirectRequires extends ReadonlyArray<FeatureRequirement>,
|
|
17
|
+
OpenServices = DefaultFeatureOpenServices<ROut, DirectRequires>,
|
|
18
|
+
UsesInput extends boolean = false,
|
|
19
|
+
Input = never,
|
|
20
|
+
> extends AnyLoadedModule {
|
|
21
|
+
readonly [FeatureModuleGraphValidTypeId]: FeatureModuleGraphValidTypeId
|
|
22
|
+
readonly requires: DirectRequires
|
|
23
|
+
readonly usesInput: UsesInput
|
|
24
|
+
readonly layer: Layer.Layer<ROut, never, FeatureModuleInput<OpenServices, UsesInput>>
|
|
25
|
+
readonly inputSchema: UsesInput extends true ? Schema.Schema.AnyNoContext : undefined
|
|
26
|
+
readonly Input: (input: Input) => void
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type LoadedModuleCapture<Result> = <
|
|
30
|
+
ROut,
|
|
31
|
+
DirectRequires extends ReadonlyArray<FeatureRequirement>,
|
|
32
|
+
OpenServices,
|
|
33
|
+
UsesInput extends boolean,
|
|
34
|
+
Input,
|
|
35
|
+
>(
|
|
36
|
+
module: LoadedModule<ROut, DirectRequires, OpenServices, UsesInput, Input>,
|
|
37
|
+
) => Result
|
|
38
|
+
|
|
39
|
+
export interface AnyLoadedModule {
|
|
40
|
+
readonly capture: <Result>(visit: LoadedModuleCapture<Result>) => Result
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type FeatureLayerOutput<L extends Layer.Layer.Any> = Layer.Layer.Success<L>
|
|
44
|
+
|
|
45
|
+
// Reject erased contexts before graph validation can mistake them for permissive inputs.
|
|
46
|
+
export type ExactFeatureLayer<L extends Layer.Layer.Any, UsesInput extends boolean> = Layer.Layer<
|
|
47
|
+
FeatureLayerOutput<L>,
|
|
48
|
+
never,
|
|
49
|
+
FeatureModuleInput<ModuleOpenServices<L, UsesInput>, UsesInput>
|
|
50
|
+
> &
|
|
51
|
+
(unknown extends Layer.Layer.Context<L>
|
|
52
|
+
? {
|
|
53
|
+
readonly featureLayerContextMustBeExact: 'A feature layer context cannot be erased'
|
|
54
|
+
}
|
|
55
|
+
: object)
|
|
56
|
+
|
|
57
|
+
export const featureModule = <
|
|
58
|
+
const DirectRequires extends ReadonlyArray<FeatureRequirement>,
|
|
59
|
+
L extends Layer.Layer.Any,
|
|
60
|
+
>(
|
|
61
|
+
requires: DirectRequires,
|
|
62
|
+
layer: L & ExactFeatureLayer<L, false> & ValidateFeatureGraphLayer<L, DirectRequires, false>,
|
|
63
|
+
): FeatureModule<
|
|
64
|
+
FeatureLayerOutput<L>,
|
|
65
|
+
DirectRequires,
|
|
66
|
+
ModuleOpenServices<L, false>,
|
|
67
|
+
false,
|
|
68
|
+
never
|
|
69
|
+
> => {
|
|
70
|
+
const module: FeatureModule<
|
|
71
|
+
FeatureLayerOutput<L>,
|
|
72
|
+
DirectRequires,
|
|
73
|
+
ModuleOpenServices<L, false>,
|
|
74
|
+
false,
|
|
75
|
+
never
|
|
76
|
+
> = {
|
|
77
|
+
[FeatureModuleGraphValidTypeId]: FeatureModuleGraphValidTypeId,
|
|
78
|
+
requires,
|
|
79
|
+
usesInput: false,
|
|
80
|
+
layer,
|
|
81
|
+
inputSchema: undefined,
|
|
82
|
+
Input: () => undefined,
|
|
83
|
+
capture: <Result>(visit: LoadedModuleCapture<Result>): Result => visit(module),
|
|
84
|
+
}
|
|
85
|
+
return module
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export const featureModuleFromInput = <
|
|
89
|
+
const InputSchema extends Schema.Schema.AnyNoContext,
|
|
90
|
+
const DirectRequires extends ReadonlyArray<FeatureRequirement>,
|
|
91
|
+
L extends Layer.Layer.Any,
|
|
92
|
+
>(
|
|
93
|
+
input: InputSchema,
|
|
94
|
+
requires: DirectRequires,
|
|
95
|
+
layer: L & ExactFeatureLayer<L, true> & ValidateFeatureGraphLayer<L, DirectRequires, true>,
|
|
96
|
+
): FeatureModule<
|
|
97
|
+
FeatureLayerOutput<L>,
|
|
98
|
+
DirectRequires,
|
|
99
|
+
ModuleOpenServices<L, true>,
|
|
100
|
+
true,
|
|
101
|
+
Schema.Schema.Type<InputSchema>
|
|
102
|
+
> => {
|
|
103
|
+
const module: FeatureModule<
|
|
104
|
+
FeatureLayerOutput<L>,
|
|
105
|
+
DirectRequires,
|
|
106
|
+
ModuleOpenServices<L, true>,
|
|
107
|
+
true,
|
|
108
|
+
Schema.Schema.Type<InputSchema>
|
|
109
|
+
> = {
|
|
110
|
+
[FeatureModuleGraphValidTypeId]: FeatureModuleGraphValidTypeId,
|
|
111
|
+
requires,
|
|
112
|
+
usesInput: true,
|
|
113
|
+
layer,
|
|
114
|
+
inputSchema: input,
|
|
115
|
+
Input: () => undefined,
|
|
116
|
+
capture: <Result>(visit: LoadedModuleCapture<Result>): Result => visit(module),
|
|
117
|
+
}
|
|
118
|
+
return module
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Seal dynamic imports as typed Effects so chunk failures become FeatureLoadFailed.
|
|
122
|
+
export const lazyImport = <M>(
|
|
123
|
+
thunk: () => Promise<{ readonly default: M }>,
|
|
124
|
+
): Effect.Effect<M, FeatureLoadFailed> =>
|
|
125
|
+
Effect.tryPromise({
|
|
126
|
+
try: thunk,
|
|
127
|
+
catch: (cause) => new FeatureLoadFailed({ cause }),
|
|
128
|
+
}).pipe(Effect.map((module) => module.default))
|
|
129
|
+
|
|
130
|
+
export interface LoadedModule<
|
|
131
|
+
ROut,
|
|
132
|
+
DirectRequires extends ReadonlyArray<FeatureRequirement>,
|
|
133
|
+
OpenServices = DefaultFeatureOpenServices<ROut, DirectRequires>,
|
|
134
|
+
UsesInput extends boolean = false,
|
|
135
|
+
Input = never,
|
|
136
|
+
> extends FeatureModule<ROut, DirectRequires, OpenServices, UsesInput, Input> {}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Context, Layer, Schema as S } from 'effect'
|
|
2
|
+
import * as State from '../state/state'
|
|
3
|
+
import * as StateGroup from '../state/stateGroup'
|
|
4
|
+
import { type EngineServices, type FeatureModule, featureModule } from './feature'
|
|
5
|
+
|
|
6
|
+
const FeedStateBase: State.StateClass<'feed', string> = State.make('feed', S.String)
|
|
7
|
+
class FeedState extends FeedStateBase {}
|
|
8
|
+
const FilterStateBase: State.StateClass<'filter', string> = State.make('filter', S.String)
|
|
9
|
+
class FilterState extends FilterStateBase {}
|
|
10
|
+
const TodosStatesBase: StateGroup.StateGroupClass<readonly [typeof FeedState, typeof FilterState]> =
|
|
11
|
+
StateGroup.make(FeedState, FilterState)
|
|
12
|
+
class TodosStates extends TodosStatesBase {}
|
|
13
|
+
|
|
14
|
+
interface ClockService {
|
|
15
|
+
readonly now: () => number
|
|
16
|
+
}
|
|
17
|
+
const ClockBase: Context.TagClass<Clock, 'feature.typecheck.Clock', ClockService> = Context.Tag(
|
|
18
|
+
'feature.typecheck.Clock',
|
|
19
|
+
)<Clock, ClockService>()
|
|
20
|
+
export class Clock extends ClockBase {}
|
|
21
|
+
|
|
22
|
+
declare const readsFeed: Layer.Layer<
|
|
23
|
+
{ readonly _out: true },
|
|
24
|
+
never,
|
|
25
|
+
State.StateStore<'feed', string> | EngineServices
|
|
26
|
+
>
|
|
27
|
+
|
|
28
|
+
declare const readsTodos: Layer.Layer<
|
|
29
|
+
{ readonly _out: true },
|
|
30
|
+
never,
|
|
31
|
+
State.StateStore<'feed', string> | State.StateStore<'filter', string> | EngineServices
|
|
32
|
+
>
|
|
33
|
+
|
|
34
|
+
const okState: FeatureModule<{ readonly _out: true }, readonly [typeof FeedState]> = featureModule(
|
|
35
|
+
[FeedState],
|
|
36
|
+
readsFeed,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
const okGroup: FeatureModule<{ readonly _out: true }, readonly [typeof TodosStates]> =
|
|
40
|
+
featureModule([TodosStates], readsTodos)
|
|
41
|
+
|
|
42
|
+
const badEmpty =
|
|
43
|
+
// @ts-expect-error feature layer reads a store it does not declare in `requires`
|
|
44
|
+
featureModule([], readsFeed)
|
|
45
|
+
|
|
46
|
+
declare const readsClock: Layer.Layer<{ readonly _clock: true }, never, Clock | EngineServices>
|
|
47
|
+
|
|
48
|
+
export const okService: FeatureModule<{ readonly _clock: true }, readonly [typeof Clock]> =
|
|
49
|
+
featureModule([Clock], readsClock)
|
|
50
|
+
|
|
51
|
+
const badService =
|
|
52
|
+
// @ts-expect-error feature layer reads an ordinary Context service it did not declare
|
|
53
|
+
featureModule([], readsClock)
|
|
54
|
+
|
|
55
|
+
declare const privateEngine: Layer.Layer<EngineServices, never, EngineServices>
|
|
56
|
+
// @ts-expect-error a Feature module cannot provide its own Engine services
|
|
57
|
+
const invalidPrivateEngine = featureModule([], privateEngine)
|
|
58
|
+
|
|
59
|
+
void okState
|
|
60
|
+
void okGroup
|
|
61
|
+
void badEmpty
|
|
62
|
+
void badService
|
|
63
|
+
void invalidPrivateEngine
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import type { Effect } from 'effect'
|
|
2
|
+
import type { CompositionClass } from '../compose/composition'
|
|
3
|
+
import type { UiContract } from '../compose/ui'
|
|
4
|
+
import type {
|
|
5
|
+
AnyFeatureGraphSummary,
|
|
6
|
+
FeatureGraphSummary,
|
|
7
|
+
FeatureSummaryCompositionIdentity,
|
|
8
|
+
FeatureSummaryCompositionProps,
|
|
9
|
+
FeatureSummaryContract,
|
|
10
|
+
FeatureSummaryInput,
|
|
11
|
+
FeatureSummaryName,
|
|
12
|
+
FeatureSummaryOpenServices,
|
|
13
|
+
FeatureSummaryStates,
|
|
14
|
+
FeatureSummarySupportOpenServices,
|
|
15
|
+
FeatureSummaryUsesInput,
|
|
16
|
+
} from '../graph/closure'
|
|
17
|
+
import type { FeatureLoadFailed } from '../internal/errors'
|
|
18
|
+
import type { CapturedFeatureBinding } from './featureBinding'
|
|
19
|
+
import type { FeatureModule } from './featureModule'
|
|
20
|
+
import type { FeatureRequirement } from './featureRequirement'
|
|
21
|
+
|
|
22
|
+
export interface FeatureNativeTree<
|
|
23
|
+
Summary extends AnyFeatureGraphSummary,
|
|
24
|
+
ROut,
|
|
25
|
+
DirectRequires extends ReadonlyArray<FeatureRequirement>,
|
|
26
|
+
SupportOut,
|
|
27
|
+
SupportDirectRequires extends ReadonlyArray<FeatureRequirement>,
|
|
28
|
+
Composition extends CompositionClass<
|
|
29
|
+
FeatureSummaryCompositionProps<Summary>,
|
|
30
|
+
FeatureSummaryContract<Summary>,
|
|
31
|
+
FeatureSummaryStates<Summary>,
|
|
32
|
+
FeatureSummaryName<Summary>,
|
|
33
|
+
FeatureSummaryCompositionIdentity<Summary>
|
|
34
|
+
> = CompositionClass<
|
|
35
|
+
FeatureSummaryCompositionProps<Summary>,
|
|
36
|
+
FeatureSummaryContract<Summary>,
|
|
37
|
+
FeatureSummaryStates<Summary>,
|
|
38
|
+
FeatureSummaryName<Summary>,
|
|
39
|
+
FeatureSummaryCompositionIdentity<Summary>
|
|
40
|
+
>,
|
|
41
|
+
> {
|
|
42
|
+
readonly identity: symbol
|
|
43
|
+
readonly summary: Summary
|
|
44
|
+
readonly composition: Composition
|
|
45
|
+
readonly load: Effect.Effect<
|
|
46
|
+
FeatureModule<
|
|
47
|
+
ROut,
|
|
48
|
+
DirectRequires,
|
|
49
|
+
FeatureSummaryOpenServices<Summary>,
|
|
50
|
+
FeatureSummaryUsesInput<Summary>,
|
|
51
|
+
FeatureSummaryInput<Summary>
|
|
52
|
+
>,
|
|
53
|
+
FeatureLoadFailed
|
|
54
|
+
>
|
|
55
|
+
readonly binding: CapturedFeatureBinding<Summary, ROut, DirectRequires>
|
|
56
|
+
readonly eagerModule:
|
|
57
|
+
| FeatureModule<ROut, DirectRequires, FeatureSummaryOpenServices<Summary>, false, never>
|
|
58
|
+
| undefined
|
|
59
|
+
readonly supportModule:
|
|
60
|
+
| FeatureModule<
|
|
61
|
+
SupportOut,
|
|
62
|
+
SupportDirectRequires,
|
|
63
|
+
FeatureSummarySupportOpenServices<Summary>,
|
|
64
|
+
false,
|
|
65
|
+
never
|
|
66
|
+
>
|
|
67
|
+
| undefined
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface EagerFeatureNativeTree<
|
|
71
|
+
Summary extends AnyFeatureGraphSummary,
|
|
72
|
+
ROut,
|
|
73
|
+
DirectRequires extends ReadonlyArray<FeatureRequirement>,
|
|
74
|
+
Composition extends CompositionClass<
|
|
75
|
+
FeatureSummaryCompositionProps<Summary>,
|
|
76
|
+
FeatureSummaryContract<Summary>,
|
|
77
|
+
FeatureSummaryStates<Summary>,
|
|
78
|
+
FeatureSummaryName<Summary>,
|
|
79
|
+
FeatureSummaryCompositionIdentity<Summary>
|
|
80
|
+
> = CompositionClass<
|
|
81
|
+
FeatureSummaryCompositionProps<Summary>,
|
|
82
|
+
FeatureSummaryContract<Summary>,
|
|
83
|
+
FeatureSummaryStates<Summary>,
|
|
84
|
+
FeatureSummaryName<Summary>,
|
|
85
|
+
FeatureSummaryCompositionIdentity<Summary>
|
|
86
|
+
>,
|
|
87
|
+
> extends FeatureNativeTree<Summary, ROut, DirectRequires, never, readonly [], Composition> {
|
|
88
|
+
readonly eagerModule: FeatureModule<
|
|
89
|
+
ROut,
|
|
90
|
+
DirectRequires,
|
|
91
|
+
FeatureSummaryOpenServices<Summary>,
|
|
92
|
+
false,
|
|
93
|
+
never
|
|
94
|
+
>
|
|
95
|
+
readonly supportModule: undefined
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface LazyFeatureNativeTree<
|
|
99
|
+
Summary extends AnyFeatureGraphSummary,
|
|
100
|
+
ROut,
|
|
101
|
+
DirectRequires extends ReadonlyArray<FeatureRequirement>,
|
|
102
|
+
SupportOut,
|
|
103
|
+
SupportDirectRequires extends ReadonlyArray<FeatureRequirement>,
|
|
104
|
+
Composition extends CompositionClass<
|
|
105
|
+
FeatureSummaryCompositionProps<Summary>,
|
|
106
|
+
FeatureSummaryContract<Summary>,
|
|
107
|
+
FeatureSummaryStates<Summary>,
|
|
108
|
+
FeatureSummaryName<Summary>,
|
|
109
|
+
FeatureSummaryCompositionIdentity<Summary>
|
|
110
|
+
> = CompositionClass<
|
|
111
|
+
FeatureSummaryCompositionProps<Summary>,
|
|
112
|
+
FeatureSummaryContract<Summary>,
|
|
113
|
+
FeatureSummaryStates<Summary>,
|
|
114
|
+
FeatureSummaryName<Summary>,
|
|
115
|
+
FeatureSummaryCompositionIdentity<Summary>
|
|
116
|
+
>,
|
|
117
|
+
> extends FeatureNativeTree<
|
|
118
|
+
Summary,
|
|
119
|
+
ROut,
|
|
120
|
+
DirectRequires,
|
|
121
|
+
SupportOut,
|
|
122
|
+
SupportDirectRequires,
|
|
123
|
+
Composition
|
|
124
|
+
> {
|
|
125
|
+
readonly eagerModule: undefined
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export type FeatureSummaryOf<
|
|
129
|
+
FeatureIdentity,
|
|
130
|
+
MountProps,
|
|
131
|
+
CompositionProps,
|
|
132
|
+
C extends UiContract,
|
|
133
|
+
S extends ReadonlyArray<unknown>,
|
|
134
|
+
N extends string,
|
|
135
|
+
Identity,
|
|
136
|
+
OpenServices,
|
|
137
|
+
SupportOpenServices,
|
|
138
|
+
UsesInput extends boolean,
|
|
139
|
+
Input,
|
|
140
|
+
> = FeatureGraphSummary<
|
|
141
|
+
FeatureIdentity,
|
|
142
|
+
MountProps,
|
|
143
|
+
CompositionProps,
|
|
144
|
+
C,
|
|
145
|
+
S,
|
|
146
|
+
N,
|
|
147
|
+
Identity,
|
|
148
|
+
OpenServices,
|
|
149
|
+
SupportOpenServices,
|
|
150
|
+
UsesInput,
|
|
151
|
+
Input
|
|
152
|
+
>
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Context } from 'effect'
|
|
2
|
+
import { CompositionIdTypeId } from '../compose/composition'
|
|
3
|
+
import type { OpenServicesFromFeatureSlotWitnesses } from '../graph/closure'
|
|
4
|
+
import type { EngineServices } from '../runtime/loop'
|
|
5
|
+
|
|
6
|
+
const FeatureInputBase: Context.TagClass<FeatureInput, 'reform/FeatureInput', unknown> =
|
|
7
|
+
Context.Tag('reform/FeatureInput')<FeatureInput, unknown>()
|
|
8
|
+
export class FeatureInput extends FeatureInputBase {}
|
|
9
|
+
|
|
10
|
+
// Context.Tag is invariant, so erased requirements use its structural identity carrier.
|
|
11
|
+
export interface FeatureServiceTag<out Identifier = unknown, out Service = unknown> {
|
|
12
|
+
readonly [Context.TagTypeId]: object
|
|
13
|
+
readonly Identifier: Identifier
|
|
14
|
+
readonly Service: Service
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface StoredFeatureRequirement<out Identifier = unknown, out Service = unknown> {
|
|
18
|
+
readonly store: FeatureServiceTag<Identifier, Service>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type RequireCarrier =
|
|
22
|
+
| StoredFeatureRequirement
|
|
23
|
+
| {
|
|
24
|
+
readonly members: ReadonlyArray<StoredFeatureRequirement>
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type FeatureRequirement = RequireCarrier | FeatureServiceTag
|
|
28
|
+
|
|
29
|
+
export type TagRequirement<Tag> =
|
|
30
|
+
Tag extends FeatureServiceTag<infer Identifier, infer _Service> ? Identifier : never
|
|
31
|
+
|
|
32
|
+
export type StoredRequirementIdentifier<Carrier> = Carrier extends {
|
|
33
|
+
readonly store: infer Tag
|
|
34
|
+
}
|
|
35
|
+
? TagRequirement<Tag>
|
|
36
|
+
: never
|
|
37
|
+
|
|
38
|
+
export type RequirementIdentifier<Requirement> = Requirement extends FeatureServiceTag
|
|
39
|
+
? TagRequirement<Requirement>
|
|
40
|
+
: Requirement extends {
|
|
41
|
+
readonly members: infer Members extends ReadonlyArray<StoredFeatureRequirement>
|
|
42
|
+
}
|
|
43
|
+
? StoredRequirementIdentifier<Members[number]>
|
|
44
|
+
: StoredRequirementIdentifier<Requirement>
|
|
45
|
+
|
|
46
|
+
export type ProvidedBy<Requires extends ReadonlyArray<FeatureRequirement>> = RequirementIdentifier<
|
|
47
|
+
Requires[number]
|
|
48
|
+
>
|
|
49
|
+
|
|
50
|
+
export type DefaultFeatureOpenServices<ROut, DirectRequires extends ReadonlyArray<FeatureRequirement>> =
|
|
51
|
+
| ProvidedBy<DirectRequires>
|
|
52
|
+
| OpenServicesFromFeatureSlotWitnesses<ROut>
|
|
53
|
+
|
|
54
|
+
export type CompositionNames<ROut> = ROut extends {
|
|
55
|
+
readonly [CompositionIdTypeId]: {
|
|
56
|
+
readonly name: infer Name extends string
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
? Name
|
|
60
|
+
: never
|
|
61
|
+
|
|
62
|
+
export type CompositionIdentities<ROut> = ROut extends {
|
|
63
|
+
readonly [CompositionIdTypeId]: {
|
|
64
|
+
readonly identity: infer Identity
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
? Identity
|
|
68
|
+
: never
|
|
69
|
+
|
|
70
|
+
export type RootCompositionName<ROut> = [CompositionNames<ROut>] extends [never]
|
|
71
|
+
? string
|
|
72
|
+
: CompositionNames<ROut>
|
|
73
|
+
|
|
74
|
+
export type RootCompositionIdentity<ROut> = [CompositionIdentities<ROut>] extends [never]
|
|
75
|
+
? unknown
|
|
76
|
+
: CompositionIdentities<ROut>
|
|
77
|
+
|
|
78
|
+
// Feature layers may require the shared engine but must never provide it.
|
|
79
|
+
export type FeatureModuleInput<OpenServices, UsesInput extends boolean> =
|
|
80
|
+
| EngineServices
|
|
81
|
+
| OpenServices
|
|
82
|
+
| (UsesInput extends true ? FeatureInput : never)
|