@playfast/reform 1.0.1 → 1.2.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 +103 -56
- package/package.json +17 -17
- package/src/boundary/boundary.test.ts +63 -49
- package/src/boundary/boundary.ts +144 -113
- package/src/calc/asyncCalc.invalidate.test.ts +518 -32
- package/src/calc/asyncCalc.test.ts +207 -213
- package/src/calc/asyncCalc.ts +131 -154
- package/src/calc/asyncData.ts +0 -37
- package/src/calc/calc.test.ts +7 -33
- package/src/calc/calc.ts +44 -58
- package/src/calc/calcFamily.test.ts +80 -34
- package/src/calc/calcFamily.ts +54 -65
- package/src/calc/compose.test.ts +1 -12
- package/src/calc/compose.ts +1 -36
- package/src/calc/queryState.ts +0 -23
- package/src/channel/channel.ts +126 -111
- package/src/compose/composition.test.ts +19 -0
- package/src/compose/composition.ts +351 -127
- package/src/compose/host.ts +0 -6
- package/src/compose/props.ts +13 -12
- package/src/compose/provide.ts +189 -62
- package/src/compose/slot.ts +158 -49
- package/src/compose/structure.test.ts +6 -9
- package/src/compose/structure.ts +108 -79
- package/src/compose/ui.test.ts +19 -7
- package/src/compose/ui.ts +155 -156
- package/src/compose/ui.typecheck.ts +40 -18
- package/src/definition/definition.ts +22 -41
- package/src/event/event.fromSource.test.ts +172 -0
- package/src/event/event.test.ts +10 -3
- package/src/event/event.ts +102 -27
- package/src/event/eventGroup.ts +0 -1
- package/src/feature/feature.mount.test.ts +122 -43
- package/src/feature/feature.test.ts +46 -21
- package/src/feature/feature.ts +1347 -256
- package/src/feature/feature.typecheck.ts +273 -68
- package/src/graph/closure.ts +403 -0
- package/src/index.ts +68 -126
- package/src/internal/bucketCache.ts +39 -0
- package/src/internal/capture.ts +9 -24
- package/src/internal/env.ts +7 -0
- package/src/internal/errors.test.ts +0 -6
- package/src/internal/errors.ts +37 -60
- package/src/internal/inspect.test.ts +0 -6
- package/src/internal/inspect.ts +0 -12
- package/src/internal/queryDriver.ts +105 -201
- package/src/internal/queryDriverStore.ts +156 -0
- package/src/internal/queryDriverTypes.ts +59 -0
- package/src/internal/queryEvents.ts +0 -12
- package/src/internal/queryStore.ts +0 -14
- package/src/internal/reuse.test.ts +10 -14
- package/src/internal/reuse.ts +5 -30
- package/src/internal/scheduler.ts +4 -44
- package/src/internal/seeds.ts +0 -14
- package/src/internal/sources.ts +26 -49
- package/src/internal/stateRegistry.ts +0 -14
- package/src/internal/store.test.ts +1 -3
- package/src/internal/store.ts +0 -37
- package/src/internal/track.ts +3 -20
- package/src/internal/variance.ts +5 -0
- package/src/internal.ts +222 -0
- package/src/namespace/namespace.test.ts +46 -0
- package/src/namespace/namespace.ts +106 -0
- package/src/procedure/procedure.ts +40 -35
- package/src/reducer/reducer.ts +78 -52
- package/src/remote/remoteState.test.ts +590 -397
- package/src/remote/remoteState.ts +425 -347
- package/src/remote/remoteState.typecheck.ts +47 -56
- package/src/runtime/appRuntime.activation.test.ts +100 -0
- package/src/runtime/appRuntime.test.ts +249 -0
- package/src/runtime/appRuntime.ts +415 -97
- package/src/runtime/bus.ts +2 -15
- package/src/runtime/eventBudget.test.ts +152 -0
- package/src/runtime/eventBudget.ts +120 -0
- package/src/runtime/hardening.test.ts +73 -13
- package/src/runtime/instrumentation.test.ts +55 -52
- package/src/runtime/instrumentation.ts +6 -60
- package/src/runtime/loop.test.ts +36 -17
- package/src/runtime/loop.ts +87 -88
- package/src/runtime/queries.ts +0 -17
- package/src/scene/featureScene.test.ts +61 -0
- package/src/scene/scene.ts +247 -104
- package/src/scene/seedScene.test.ts +42 -79
- package/src/state/state.nominal.typecheck.ts +68 -0
- package/src/state/state.test.ts +17 -0
- package/src/state/state.ts +80 -46
- package/src/state/stateFamily.test.ts +16 -11
- package/src/state/stateFamily.ts +55 -65
- package/src/state/stateGroup.ts +53 -64
- package/src/state/token.ts +40 -23
- package/src/synced/syncedStore.ts +46 -58
- package/src/testkit/flight.testkit.ts +75 -0
- package/src/ui/node.ts +0 -6
- package/src/ui/trigger.ts +0 -5
- package/src/wire/tree.test.ts +8 -7
- package/src/wire/tree.ts +0 -39
- package/src/wire/triggers.test.ts +6 -6
- package/src/wire/triggers.ts +14 -32
- package/src/internal/ctx.ts +0 -16
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import { Layer } from 'effect'
|
|
2
|
+
import { CompositionIdTypeId } from '../compose/composition'
|
|
3
|
+
import type { UiContract } from '../compose/ui'
|
|
4
|
+
import { SlotServiceTypeId } from '../compose/slot'
|
|
5
|
+
import type { FeatureInput, FeatureRequirement, ProvidedBy } from '../feature/feature'
|
|
6
|
+
import type { EngineServices } from '../runtime/loop'
|
|
7
|
+
import type { StateStore } from '../state/state'
|
|
8
|
+
import type { StateFamilyStore } from '../state/stateFamily'
|
|
9
|
+
|
|
10
|
+
export const FeatureGraphValidTypeId: unique symbol = Symbol.for('reform/FeatureGraphValid')
|
|
11
|
+
export type FeatureGraphValidTypeId = typeof FeatureGraphValidTypeId
|
|
12
|
+
|
|
13
|
+
export const FeatureModuleGraphValidTypeId: unique symbol = Symbol.for(
|
|
14
|
+
'reform/FeatureModuleGraphValid',
|
|
15
|
+
)
|
|
16
|
+
export type FeatureModuleGraphValidTypeId = typeof FeatureModuleGraphValidTypeId
|
|
17
|
+
|
|
18
|
+
export const FeatureChildSummaryTypeId: unique symbol = Symbol.for('reform/FeatureChildSummary')
|
|
19
|
+
export type FeatureChildSummaryTypeId = typeof FeatureChildSummaryTypeId
|
|
20
|
+
|
|
21
|
+
export const FeatureGraphSummaryTypeId: unique symbol = Symbol.for('reform/FeatureGraphSummary')
|
|
22
|
+
export type FeatureGraphSummaryTypeId = typeof FeatureGraphSummaryTypeId
|
|
23
|
+
|
|
24
|
+
export const SlotBindingSummaryTypeId: unique symbol = Symbol.for('reform/SlotBindingSummary')
|
|
25
|
+
export type SlotBindingSummaryTypeId = typeof SlotBindingSummaryTypeId
|
|
26
|
+
|
|
27
|
+
export interface SlotBindingSummary {
|
|
28
|
+
readonly [SlotBindingSummaryTypeId]: SlotBindingSummaryTypeId
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The constant-size proof published after a Feature's current module has passed
|
|
33
|
+
* graph validation. Type-only facts use empty-or-singleton tuples so the runtime
|
|
34
|
+
* summary stays compact while direct indexed access recovers their exact types.
|
|
35
|
+
*/
|
|
36
|
+
export interface FeatureGraphSummary<
|
|
37
|
+
out FeatureIdentity,
|
|
38
|
+
out MountProps,
|
|
39
|
+
out CompositionProps,
|
|
40
|
+
out C extends UiContract,
|
|
41
|
+
out S extends ReadonlyArray<unknown>,
|
|
42
|
+
out N extends string,
|
|
43
|
+
out CompositionIdentity,
|
|
44
|
+
out OpenServices,
|
|
45
|
+
out SupportOpenServices,
|
|
46
|
+
out UsesInput extends boolean,
|
|
47
|
+
out Input,
|
|
48
|
+
> extends SlotBindingSummary {
|
|
49
|
+
readonly [FeatureGraphSummaryTypeId]: {
|
|
50
|
+
readonly featureIdentity: readonly [] | readonly [FeatureIdentity]
|
|
51
|
+
readonly mountProps: readonly [] | readonly [MountProps]
|
|
52
|
+
readonly compositionProps: readonly [] | readonly [CompositionProps]
|
|
53
|
+
readonly contract: readonly [] | readonly [C]
|
|
54
|
+
readonly states: readonly [] | readonly [S]
|
|
55
|
+
readonly name: N
|
|
56
|
+
readonly compositionIdentity: readonly [] | readonly [CompositionIdentity]
|
|
57
|
+
readonly openServices: readonly [] | readonly [OpenServices]
|
|
58
|
+
readonly supportOpenServices: readonly [] | readonly [SupportOpenServices]
|
|
59
|
+
readonly usesInput: readonly [] | readonly [UsesInput]
|
|
60
|
+
readonly input: readonly [] | readonly [Input]
|
|
61
|
+
readonly validated: FeatureModuleGraphValidTypeId
|
|
62
|
+
}
|
|
63
|
+
readonly [FeatureChildSummaryTypeId]: {
|
|
64
|
+
readonly featureIdentity: readonly [] | readonly [FeatureIdentity]
|
|
65
|
+
readonly compositionIdentity: readonly [] | readonly [CompositionIdentity]
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export type FeatureChildSummary<
|
|
70
|
+
FeatureIdentity,
|
|
71
|
+
MountProps,
|
|
72
|
+
CompositionProps,
|
|
73
|
+
C extends UiContract,
|
|
74
|
+
S extends ReadonlyArray<unknown>,
|
|
75
|
+
N extends string,
|
|
76
|
+
CompositionIdentity,
|
|
77
|
+
OpenServices,
|
|
78
|
+
SupportOpenServices,
|
|
79
|
+
UsesInput extends boolean,
|
|
80
|
+
Input,
|
|
81
|
+
> = FeatureGraphSummary<
|
|
82
|
+
FeatureIdentity,
|
|
83
|
+
MountProps,
|
|
84
|
+
CompositionProps,
|
|
85
|
+
C,
|
|
86
|
+
S,
|
|
87
|
+
N,
|
|
88
|
+
CompositionIdentity,
|
|
89
|
+
OpenServices,
|
|
90
|
+
SupportOpenServices,
|
|
91
|
+
UsesInput,
|
|
92
|
+
Input
|
|
93
|
+
>
|
|
94
|
+
|
|
95
|
+
export type AnyFeatureGraphSummary = FeatureGraphSummary<
|
|
96
|
+
unknown,
|
|
97
|
+
unknown,
|
|
98
|
+
unknown,
|
|
99
|
+
UiContract,
|
|
100
|
+
ReadonlyArray<unknown>,
|
|
101
|
+
string,
|
|
102
|
+
unknown,
|
|
103
|
+
unknown,
|
|
104
|
+
unknown,
|
|
105
|
+
boolean,
|
|
106
|
+
unknown
|
|
107
|
+
>
|
|
108
|
+
|
|
109
|
+
export type FeatureSummaryIdentity<Summary extends AnyFeatureGraphSummary> =
|
|
110
|
+
Summary[FeatureGraphSummaryTypeId]['featureIdentity'][number]
|
|
111
|
+
export type FeatureSummaryMountProps<Summary extends AnyFeatureGraphSummary> =
|
|
112
|
+
Summary[FeatureGraphSummaryTypeId]['mountProps'][number]
|
|
113
|
+
export type FeatureSummaryCompositionProps<Summary extends AnyFeatureGraphSummary> =
|
|
114
|
+
Summary[FeatureGraphSummaryTypeId]['compositionProps'][number]
|
|
115
|
+
export type FeatureSummaryContract<Summary extends AnyFeatureGraphSummary> =
|
|
116
|
+
Summary[FeatureGraphSummaryTypeId]['contract'][number]
|
|
117
|
+
export type FeatureSummaryStates<Summary extends AnyFeatureGraphSummary> =
|
|
118
|
+
Summary[FeatureGraphSummaryTypeId]['states'][number]
|
|
119
|
+
export type FeatureSummaryName<Summary extends AnyFeatureGraphSummary> =
|
|
120
|
+
Summary[FeatureGraphSummaryTypeId]['name']
|
|
121
|
+
export type FeatureSummaryCompositionIdentity<Summary extends AnyFeatureGraphSummary> =
|
|
122
|
+
Summary[FeatureGraphSummaryTypeId]['compositionIdentity'][number]
|
|
123
|
+
export type FeatureSummaryOpenServices<Summary extends AnyFeatureGraphSummary> =
|
|
124
|
+
Summary[FeatureGraphSummaryTypeId]['openServices'][number]
|
|
125
|
+
export type FeatureSummarySupportOpenServices<Summary extends AnyFeatureGraphSummary> =
|
|
126
|
+
Summary[FeatureGraphSummaryTypeId]['supportOpenServices'][number]
|
|
127
|
+
export type FeatureSummaryUsesInput<Summary extends AnyFeatureGraphSummary> =
|
|
128
|
+
Summary[FeatureGraphSummaryTypeId]['usesInput'][number]
|
|
129
|
+
export type FeatureSummaryInput<Summary extends AnyFeatureGraphSummary> =
|
|
130
|
+
Summary[FeatureGraphSummaryTypeId]['input'][number]
|
|
131
|
+
|
|
132
|
+
export const CompositionChildSummaryTypeId: unique symbol = Symbol.for(
|
|
133
|
+
'reform/CompositionChildSummary',
|
|
134
|
+
)
|
|
135
|
+
export type CompositionChildSummaryTypeId = typeof CompositionChildSummaryTypeId
|
|
136
|
+
|
|
137
|
+
export interface CompositionChildSummary<out CompositionIdentity> extends SlotBindingSummary {
|
|
138
|
+
readonly [CompositionChildSummaryTypeId]: {
|
|
139
|
+
readonly compositionIdentity: CompositionIdentity
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
type IsAny<Value> = 0 extends 1 & Value ? true : false
|
|
144
|
+
|
|
145
|
+
type IsErased<Value> = IsAny<Value> extends true ? true : unknown extends Value ? true : false
|
|
146
|
+
|
|
147
|
+
type ExactStateStoreName<Service> =
|
|
148
|
+
IsAny<Service> extends true
|
|
149
|
+
? never
|
|
150
|
+
: Service extends StateStore<infer Name, infer _Value>
|
|
151
|
+
? string extends Name
|
|
152
|
+
? never
|
|
153
|
+
: Name
|
|
154
|
+
: never
|
|
155
|
+
|
|
156
|
+
type ExactStateFamilyStoreName<Service> =
|
|
157
|
+
IsAny<Service> extends true
|
|
158
|
+
? never
|
|
159
|
+
: Service extends StateFamilyStore<infer Name, infer _Key, infer _Value>
|
|
160
|
+
? string extends Name
|
|
161
|
+
? never
|
|
162
|
+
: Name
|
|
163
|
+
: never
|
|
164
|
+
|
|
165
|
+
type ServiceIsProvided<Required, Provided> =
|
|
166
|
+
IsErased<Provided> extends true
|
|
167
|
+
? false
|
|
168
|
+
: Required extends StateStore<infer Name, infer _Value>
|
|
169
|
+
? Name extends ExactStateStoreName<Provided>
|
|
170
|
+
? true
|
|
171
|
+
: false
|
|
172
|
+
: Required extends StateFamilyStore<infer Name, infer _Key, infer _Value>
|
|
173
|
+
? Name extends ExactStateFamilyStoreName<Provided>
|
|
174
|
+
? true
|
|
175
|
+
: false
|
|
176
|
+
: [Required] extends [Provided]
|
|
177
|
+
? true
|
|
178
|
+
: false
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Remove only services the provider can satisfy by their runtime Context tag.
|
|
182
|
+
* Named State/StateFamily identifiers intentionally do not collapse into their
|
|
183
|
+
* structurally broader Store/FamilyStore service APIs.
|
|
184
|
+
*/
|
|
185
|
+
export type ExactServiceExclude<Required, Provided> = Required extends unknown
|
|
186
|
+
? ServiceIsProvided<Required, Provided> extends true
|
|
187
|
+
? never
|
|
188
|
+
: Required
|
|
189
|
+
: never
|
|
190
|
+
|
|
191
|
+
type ExactServiceExtract<Required, Provided> = Required extends unknown
|
|
192
|
+
? ServiceIsProvided<Required, Provided> extends true
|
|
193
|
+
? Required
|
|
194
|
+
: never
|
|
195
|
+
: never
|
|
196
|
+
|
|
197
|
+
type GraphValidationPassed = object
|
|
198
|
+
|
|
199
|
+
type ExactIdentity<Identity> = IsErased<Identity> extends true ? never : Identity
|
|
200
|
+
|
|
201
|
+
type InputService<UsesInput extends boolean> = UsesInput extends true ? FeatureInput : never
|
|
202
|
+
|
|
203
|
+
export type OpenServicesFromFeatureSlotWitnesses<Services> = Services extends {
|
|
204
|
+
readonly [SlotServiceTypeId]: {
|
|
205
|
+
readonly binding: FeatureChildSummary<
|
|
206
|
+
infer _FeatureIdentity,
|
|
207
|
+
infer _MountProps,
|
|
208
|
+
infer _CompositionProps,
|
|
209
|
+
infer _Contract,
|
|
210
|
+
infer _States,
|
|
211
|
+
infer _Name,
|
|
212
|
+
infer _CompositionIdentity,
|
|
213
|
+
infer OpenServices,
|
|
214
|
+
infer SupportOpenServices,
|
|
215
|
+
infer _UsesInput,
|
|
216
|
+
infer _Input
|
|
217
|
+
>
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
? OpenServices | SupportOpenServices
|
|
221
|
+
: never
|
|
222
|
+
|
|
223
|
+
export type DescendantOpenServices<L extends Layer.Layer.Any> =
|
|
224
|
+
OpenServicesFromFeatureSlotWitnesses<Layer.Layer.Success<L>>
|
|
225
|
+
|
|
226
|
+
export type ModuleOpenServices<L extends Layer.Layer.Any, UsesInput extends boolean> = Exclude<
|
|
227
|
+
Layer.Layer.Context<L>,
|
|
228
|
+
EngineServices | InputService<UsesInput>
|
|
229
|
+
>
|
|
230
|
+
|
|
231
|
+
type LayerErrorIsNever<L extends Layer.Layer.Any> =
|
|
232
|
+
IsErased<Layer.Layer.Error<L>> extends true
|
|
233
|
+
? {
|
|
234
|
+
readonly featureLayerErrorMustBeNever: 'A feature layer error channel cannot be erased'
|
|
235
|
+
}
|
|
236
|
+
: [Layer.Layer.Error<L>] extends [never]
|
|
237
|
+
? GraphValidationPassed
|
|
238
|
+
: {
|
|
239
|
+
readonly featureLayerErrorMustBeNever: 'A feature layer must have an error channel of exactly never'
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
type LayerOutputsAreExact<L extends Layer.Layer.Any> =
|
|
243
|
+
IsErased<Layer.Layer.Success<L>> extends true
|
|
244
|
+
? {
|
|
245
|
+
readonly featureLayerOutputsMustBeExact: 'A feature layer output cannot be erased'
|
|
246
|
+
}
|
|
247
|
+
: GraphValidationPassed
|
|
248
|
+
|
|
249
|
+
type DescendantOpenServicesAreExact<L extends Layer.Layer.Any> =
|
|
250
|
+
IsErased<DescendantOpenServices<L>> extends true
|
|
251
|
+
? {
|
|
252
|
+
readonly featureDescendantOpenServicesMustBeExact: "A child feature's open services cannot be erased"
|
|
253
|
+
}
|
|
254
|
+
: GraphValidationPassed
|
|
255
|
+
|
|
256
|
+
type UnexpectedOpenServices<
|
|
257
|
+
L extends Layer.Layer.Any,
|
|
258
|
+
DirectRequires extends ReadonlyArray<FeatureRequirement>,
|
|
259
|
+
UsesInput extends boolean,
|
|
260
|
+
> = ExactServiceExclude<
|
|
261
|
+
Layer.Layer.Context<L>,
|
|
262
|
+
EngineServices | InputService<UsesInput> | ProvidedBy<DirectRequires> | DescendantOpenServices<L>
|
|
263
|
+
>
|
|
264
|
+
|
|
265
|
+
type OpenServicesAreDeclared<
|
|
266
|
+
L extends Layer.Layer.Any,
|
|
267
|
+
DirectRequires extends ReadonlyArray<FeatureRequirement>,
|
|
268
|
+
UsesInput extends boolean,
|
|
269
|
+
> =
|
|
270
|
+
IsErased<Layer.Layer.Context<L>> extends true
|
|
271
|
+
? {
|
|
272
|
+
readonly featureLayerContextMustBeExact: 'A feature layer context cannot be erased'
|
|
273
|
+
}
|
|
274
|
+
: [UnexpectedOpenServices<L, DirectRequires, UsesInput>] extends [never]
|
|
275
|
+
? GraphValidationPassed
|
|
276
|
+
: {
|
|
277
|
+
readonly undeclaredFeatureOpenServices: UnexpectedOpenServices<
|
|
278
|
+
L,
|
|
279
|
+
DirectRequires,
|
|
280
|
+
UsesInput
|
|
281
|
+
>
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
type MissingDirectRequirements<
|
|
285
|
+
L extends Layer.Layer.Any,
|
|
286
|
+
DirectRequires extends ReadonlyArray<FeatureRequirement>,
|
|
287
|
+
> = ExactServiceExclude<ProvidedBy<DirectRequires>, Layer.Layer.Context<L>>
|
|
288
|
+
|
|
289
|
+
type DirectRequirementsAreOpen<
|
|
290
|
+
L extends Layer.Layer.Any,
|
|
291
|
+
DirectRequires extends ReadonlyArray<FeatureRequirement>,
|
|
292
|
+
> = [MissingDirectRequirements<L, DirectRequires>] extends [never]
|
|
293
|
+
? GraphValidationPassed
|
|
294
|
+
: {
|
|
295
|
+
readonly unusedDirectFeatureRequirements: MissingDirectRequirements<L, DirectRequires>
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
type PrivateEngineOutputs<L extends Layer.Layer.Any> = Extract<
|
|
299
|
+
Layer.Layer.Success<L>,
|
|
300
|
+
EngineServices
|
|
301
|
+
>
|
|
302
|
+
|
|
303
|
+
type EngineOutputsAreShared<L extends Layer.Layer.Any> = [PrivateEngineOutputs<L>] extends [never]
|
|
304
|
+
? GraphValidationPassed
|
|
305
|
+
: {
|
|
306
|
+
readonly featureCannotProvideEngineServices: PrivateEngineOutputs<L>
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
type SelfRequiredOutputs<L extends Layer.Layer.Any> = ExactServiceExtract<
|
|
310
|
+
Layer.Layer.Context<L>,
|
|
311
|
+
Layer.Layer.Success<L>
|
|
312
|
+
>
|
|
313
|
+
|
|
314
|
+
type OutputsAreNotSelfRequired<L extends Layer.Layer.Any> = [SelfRequiredOutputs<L>] extends [never]
|
|
315
|
+
? GraphValidationPassed
|
|
316
|
+
: {
|
|
317
|
+
readonly featureCannotRequireItsOwnOutputs: SelfRequiredOutputs<L>
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
type SlotIdentity<Descriptor> =
|
|
321
|
+
// Erased descriptors must FAIL validation: `unknown` never matches a bound
|
|
322
|
+
// identity, so it surfaces in `unboundFeatureSlotIdentities`.
|
|
323
|
+
IsErased<Descriptor> extends true
|
|
324
|
+
? unknown
|
|
325
|
+
: Descriptor extends ReadonlyArray<infer Entry>
|
|
326
|
+
? SlotIdentity<Entry>
|
|
327
|
+
: Descriptor extends {
|
|
328
|
+
readonly [SlotServiceTypeId]: {
|
|
329
|
+
readonly identity: infer Identity
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
? Identity
|
|
333
|
+
: Descriptor
|
|
334
|
+
|
|
335
|
+
type RequiredSlotIdentities<Services> = Services extends {
|
|
336
|
+
readonly [CompositionIdTypeId]: {
|
|
337
|
+
readonly requiredSlots: infer RequiredSlots
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
? SlotIdentity<RequiredSlots>
|
|
341
|
+
: never
|
|
342
|
+
|
|
343
|
+
type BoundSlotIdentities<Services> = Services extends {
|
|
344
|
+
readonly [SlotServiceTypeId]: {
|
|
345
|
+
readonly identity: infer Identity
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
? ExactIdentity<Identity>
|
|
349
|
+
: never
|
|
350
|
+
|
|
351
|
+
type MissingSlotBindings<L extends Layer.Layer.Any> = Exclude<
|
|
352
|
+
RequiredSlotIdentities<Layer.Layer.Success<L>>,
|
|
353
|
+
BoundSlotIdentities<Layer.Layer.Success<L>>
|
|
354
|
+
>
|
|
355
|
+
|
|
356
|
+
type RequiredSlotsAreBound<L extends Layer.Layer.Any> = [MissingSlotBindings<L>] extends [never]
|
|
357
|
+
? GraphValidationPassed
|
|
358
|
+
: {
|
|
359
|
+
readonly unboundFeatureSlotIdentities: MissingSlotBindings<L>
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
type PlainChildCompositionIdentities<Services> = Services extends {
|
|
363
|
+
readonly [SlotServiceTypeId]: {
|
|
364
|
+
readonly binding: CompositionChildSummary<infer CompositionIdentity>
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
? CompositionIdentity
|
|
368
|
+
: never
|
|
369
|
+
|
|
370
|
+
type LiveCompositionIdentities<Services> = Services extends {
|
|
371
|
+
readonly [CompositionIdTypeId]: {
|
|
372
|
+
readonly identity: infer Identity
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
? ExactIdentity<Identity>
|
|
376
|
+
: never
|
|
377
|
+
|
|
378
|
+
type MissingPlainChildCompositions<L extends Layer.Layer.Any> = Exclude<
|
|
379
|
+
PlainChildCompositionIdentities<Layer.Layer.Success<L>>,
|
|
380
|
+
LiveCompositionIdentities<Layer.Layer.Success<L> | Layer.Layer.Context<L>>
|
|
381
|
+
>
|
|
382
|
+
|
|
383
|
+
type PlainChildrenAreLive<L extends Layer.Layer.Any> = [MissingPlainChildCompositions<L>] extends [
|
|
384
|
+
never,
|
|
385
|
+
]
|
|
386
|
+
? GraphValidationPassed
|
|
387
|
+
: {
|
|
388
|
+
readonly missingPlainChildCompositions: MissingPlainChildCompositions<L>
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
export type ValidateFeatureGraphLayer<
|
|
392
|
+
L extends Layer.Layer.Any,
|
|
393
|
+
DirectRequires extends ReadonlyArray<FeatureRequirement>,
|
|
394
|
+
UsesInput extends boolean,
|
|
395
|
+
> = LayerErrorIsNever<L> &
|
|
396
|
+
LayerOutputsAreExact<L> &
|
|
397
|
+
DescendantOpenServicesAreExact<L> &
|
|
398
|
+
OpenServicesAreDeclared<L, DirectRequires, UsesInput> &
|
|
399
|
+
DirectRequirementsAreOpen<L, DirectRequires> &
|
|
400
|
+
EngineOutputsAreShared<L> &
|
|
401
|
+
OutputsAreNotSelfRequired<L> &
|
|
402
|
+
RequiredSlotsAreBound<L> &
|
|
403
|
+
PlainChildrenAreLive<L>
|