@typeonce/ritmo 0.6.0 → 0.8.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.
Files changed (148) hide show
  1. package/README.md +2 -0
  2. package/dist/Brand.d.ts +9 -4
  3. package/dist/Brand.d.ts.map +1 -1
  4. package/dist/Brand.js +9 -4
  5. package/dist/Brand.js.map +1 -1
  6. package/dist/Clock.d.ts +186 -0
  7. package/dist/Clock.d.ts.map +1 -0
  8. package/dist/Clock.js +111 -0
  9. package/dist/Clock.js.map +1 -0
  10. package/dist/Command.d.ts +250 -41
  11. package/dist/Command.d.ts.map +1 -1
  12. package/dist/Command.js +59 -23
  13. package/dist/Command.js.map +1 -1
  14. package/dist/Condition.d.ts +12 -1
  15. package/dist/Condition.d.ts.map +1 -1
  16. package/dist/Condition.js.map +1 -1
  17. package/dist/Debug.d.ts +163 -15
  18. package/dist/Debug.d.ts.map +1 -1
  19. package/dist/Debug.js.map +1 -1
  20. package/dist/Decode.d.ts +1 -1
  21. package/dist/Decode.js +1 -1
  22. package/dist/Descriptor.d.ts +67 -24
  23. package/dist/Descriptor.d.ts.map +1 -1
  24. package/dist/Descriptor.js +32 -15
  25. package/dist/Descriptor.js.map +1 -1
  26. package/dist/Entity.d.ts +22 -5
  27. package/dist/Entity.d.ts.map +1 -1
  28. package/dist/Entity.js +2 -2
  29. package/dist/Entity.js.map +1 -1
  30. package/dist/EntityScope.d.ts +26 -1
  31. package/dist/EntityScope.d.ts.map +1 -1
  32. package/dist/EntityScope.js +14 -2
  33. package/dist/EntityScope.js.map +1 -1
  34. package/dist/HostClock.d.ts +49 -0
  35. package/dist/HostClock.d.ts.map +1 -0
  36. package/dist/HostClock.js +46 -0
  37. package/dist/HostClock.js.map +1 -0
  38. package/dist/Inspector.d.ts +7 -1
  39. package/dist/Inspector.d.ts.map +1 -1
  40. package/dist/Inspector.js.map +1 -1
  41. package/dist/Machine.d.ts +67 -36
  42. package/dist/Machine.d.ts.map +1 -1
  43. package/dist/Machine.js +10 -3
  44. package/dist/Machine.js.map +1 -1
  45. package/dist/Query.d.ts +74 -26
  46. package/dist/Query.d.ts.map +1 -1
  47. package/dist/Query.js +32 -28
  48. package/dist/Query.js.map +1 -1
  49. package/dist/Runtime.d.ts +39 -16
  50. package/dist/Runtime.d.ts.map +1 -1
  51. package/dist/Runtime.js +556 -87
  52. package/dist/Runtime.js.map +1 -1
  53. package/dist/Schedule.d.ts +217 -10
  54. package/dist/Schedule.d.ts.map +1 -1
  55. package/dist/Schedule.js +5 -0
  56. package/dist/Schedule.js.map +1 -1
  57. package/dist/Schema.d.ts +196 -44
  58. package/dist/Schema.d.ts.map +1 -1
  59. package/dist/Schema.js +29 -11
  60. package/dist/Schema.js.map +1 -1
  61. package/dist/Snapshot.d.ts +14 -0
  62. package/dist/Snapshot.d.ts.map +1 -1
  63. package/dist/Snapshot.js.map +1 -1
  64. package/dist/System.d.ts +212 -58
  65. package/dist/System.d.ts.map +1 -1
  66. package/dist/System.js +84 -6
  67. package/dist/System.js.map +1 -1
  68. package/dist/index.d.ts +8 -7
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +8 -7
  71. package/dist/index.js.map +1 -1
  72. package/dist/internal/cells.d.ts +3 -3
  73. package/dist/internal/cells.d.ts.map +1 -1
  74. package/dist/internal/cells.js +9 -11
  75. package/dist/internal/cells.js.map +1 -1
  76. package/dist/internal/debug.d.ts +13 -0
  77. package/dist/internal/debug.d.ts.map +1 -1
  78. package/dist/internal/debug.js +192 -7
  79. package/dist/internal/debug.js.map +1 -1
  80. package/dist/internal/equal.d.ts +8 -0
  81. package/dist/internal/equal.d.ts.map +1 -0
  82. package/dist/internal/equal.js +38 -0
  83. package/dist/internal/equal.js.map +1 -0
  84. package/dist/internal/fragments.d.ts.map +1 -1
  85. package/dist/internal/fragments.js +11 -1
  86. package/dist/internal/fragments.js.map +1 -1
  87. package/dist/internal/game.d.ts.map +1 -1
  88. package/dist/internal/game.js +41 -6
  89. package/dist/internal/game.js.map +1 -1
  90. package/dist/internal/order.d.ts +10 -0
  91. package/dist/internal/order.d.ts.map +1 -0
  92. package/dist/internal/order.js +122 -0
  93. package/dist/internal/order.js.map +1 -0
  94. package/dist/internal/queries.d.ts.map +1 -1
  95. package/dist/internal/queries.js +32 -10
  96. package/dist/internal/queries.js.map +1 -1
  97. package/dist/internal/requirements.d.ts +26 -0
  98. package/dist/internal/requirements.d.ts.map +1 -0
  99. package/dist/internal/requirements.js +46 -0
  100. package/dist/internal/requirements.js.map +1 -0
  101. package/package.json +1 -1
  102. package/src/Brand.ts +9 -4
  103. package/src/Clock.ts +311 -0
  104. package/src/Command.ts +407 -89
  105. package/src/Condition.ts +17 -1
  106. package/src/Debug.ts +172 -14
  107. package/src/Decode.ts +1 -1
  108. package/src/Descriptor.ts +92 -37
  109. package/src/Entity.ts +24 -5
  110. package/src/EntityScope.ts +27 -2
  111. package/src/HostClock.ts +64 -0
  112. package/src/Inspector.ts +7 -2
  113. package/src/Machine.ts +81 -37
  114. package/src/Query.ts +110 -38
  115. package/src/Runtime.ts +607 -111
  116. package/src/Schedule.ts +380 -13
  117. package/src/Schema.ts +249 -63
  118. package/src/Snapshot.ts +4 -0
  119. package/src/System.ts +248 -93
  120. package/src/index.ts +8 -7
  121. package/src/internal/cells.ts +10 -12
  122. package/src/internal/debug.ts +208 -12
  123. package/src/internal/equal.ts +31 -0
  124. package/src/internal/fragments.ts +12 -2
  125. package/src/internal/game.ts +61 -7
  126. package/src/internal/order.ts +144 -0
  127. package/src/internal/queries.ts +37 -13
  128. package/src/internal/requirements.ts +71 -0
  129. package/dist/Definition.d.ts +0 -99
  130. package/dist/Definition.d.ts.map +0 -1
  131. package/dist/Definition.js +0 -68
  132. package/dist/Definition.js.map +0 -1
  133. package/dist/Feature.d.ts +0 -106
  134. package/dist/Feature.d.ts.map +0 -1
  135. package/dist/Feature.js +0 -87
  136. package/dist/Feature.js.map +0 -1
  137. package/dist/Fx.d.ts +0 -128
  138. package/dist/Fx.d.ts.map +0 -1
  139. package/dist/Fx.js +0 -112
  140. package/dist/Fx.js.map +0 -1
  141. package/dist/internal/definition.d.ts +0 -17
  142. package/dist/internal/definition.d.ts.map +0 -1
  143. package/dist/internal/definition.js +0 -25
  144. package/dist/internal/definition.js.map +0 -1
  145. package/src/Definition.ts +0 -106
  146. package/src/Feature.ts +0 -241
  147. package/src/Fx.ts +0 -176
  148. package/src/internal/definition.ts +0 -56
@@ -0,0 +1,144 @@
1
+ /**
2
+ * The runtime form of the `Game.System.thisTick` check, for erased schedules
3
+ * (`tryTick`) and the `this-tick-order` lint. The compile-time form lives in
4
+ * `Schedule.ts` (`TickOrderErrors`) and produces the same messages.
5
+ */
6
+ import type { Descriptor } from "../Descriptor.ts"
7
+ import type * as Query from "../Query.ts"
8
+ import * as Schedule from "../Schedule.ts"
9
+ import type { SystemDefinition } from "../System.ts"
10
+
11
+ type AnySystem = SystemDefinition<any, any, any, any, any>
12
+ type OrderIssue = Schedule.OrderIssue
13
+ type Access = { readonly mode: "read" | "changed" | "write"; readonly descriptor: Descriptor.Any; readonly thisTick?: true }
14
+ type QueryAccess = {
15
+ readonly thisTick?: true
16
+ readonly selection: Record<string, { readonly mode?: string; readonly descriptor?: Descriptor.Any }>
17
+ readonly with: ReadonlyArray<Descriptor.Any>
18
+ readonly without: ReadonlyArray<Descriptor.Any>
19
+ readonly filters: ReadonlyArray<Query.Filter<any>>
20
+ }
21
+ /** Every component a filter names: the one of `added` / `changed`, or each member of `anyOf`. */
22
+ const filterNames = (filter: Query.Filter<any>): ReadonlyArray<string> =>
23
+ filter.kind === "anyOf" ? filter.filters.map((member) => member.descriptor.name) : [filter.descriptor.name]
24
+ type Permission = { readonly permission: string; readonly values: ReadonlyArray<{ readonly name: string }> }
25
+
26
+ /** One position of a tick: a system, or a point where queued commands are applied. */
27
+ type Item = { readonly kind: "system"; readonly system: AnySystem } | { readonly kind: "flush" }
28
+
29
+ const accesses = (system: AnySystem): ReadonlyArray<Access> => [
30
+ ...Object.values(system.spec.events as Record<string, Access>),
31
+ ...Object.values(system.spec.resources as Record<string, Access>)
32
+ ]
33
+
34
+ const sameData = (left: Descriptor.Any, right: Descriptor.Any): boolean =>
35
+ left.kind === right.kind && left.name === right.name
36
+
37
+ const sameSystem = (left: AnySystem, right: AnySystem): boolean => (left.base ?? left) === (right.base ?? right)
38
+
39
+ /**
40
+ * The positions of a tick, flattened: an `applyStateTransitions(...)` step
41
+ * applies queued commands, then runs every schedule of its bundle (as if
42
+ * each may run), markers inside them included.
43
+ */
44
+ const flatten = (steps: ReadonlyArray<Schedule.ScheduleStep>): Array<Item> =>
45
+ steps.flatMap((step): Array<Item> => {
46
+ if (Schedule.isSystemStep(step)) return [{ kind: "system", system: step as AnySystem }]
47
+ if (step.kind === "applyDeferred") return [{ kind: "flush" }]
48
+ const bundle = step.bundle as { readonly entries: ReadonlyArray<{ readonly steps: ReadonlyArray<Schedule.ScheduleStep> }> } | undefined
49
+ return [{ kind: "flush" }, ...(bundle?.entries ?? []).flatMap((entry) => flatten(entry.steps))]
50
+ })
51
+
52
+ const permissionNames = (system: AnySystem, kind: string): Set<string> => {
53
+ const commands = system.spec.commands as { readonly permissions: ReadonlyArray<Permission> } | undefined
54
+ return new Set((commands?.permissions ?? []).filter((p) => p.permission === kind).flatMap((p) => p.values.map((value) => value.name)))
55
+ }
56
+
57
+ /**
58
+ * Whether a system's declared commands can change what a query sees: spawns
59
+ * covering every component it requires, or inserts / removes of any
60
+ * component it names. Despawns never count.
61
+ */
62
+ const changesQuery = (system: AnySystem, query: QueryAccess): boolean => {
63
+ const slots = Object.values(query.selection)
64
+ const required = [
65
+ ...slots.filter((slot) => slot.mode === "read" || slot.mode === "write").flatMap((slot) => slot.descriptor ? [slot.descriptor.name] : []),
66
+ ...query.with.map((d) => d.name)
67
+ ]
68
+ const named = new Set([
69
+ ...slots.flatMap((slot) => slot.descriptor ? [slot.descriptor.name] : []),
70
+ ...query.with.map((d) => d.name),
71
+ ...query.without.map((d) => d.name),
72
+ ...query.filters.flatMap((filter) => filterNames(filter))
73
+ ])
74
+ const changes = [...permissionNames(system, "inserts"), ...permissionNames(system, "removes")]
75
+ if (changes.some((name) => named.has(name))) return true
76
+ const spawns = permissionNames(system, "spawns")
77
+ return spawns.size > 0 && required.every((name) => spawns.has(name))
78
+ }
79
+
80
+ /**
81
+ * Checks the systems of one tick, in the order they run. A read with no
82
+ * writer in the tick is fine (a reused reader); `event-never-written` covers
83
+ * a writer missing everywhere.
84
+ */
85
+ export const tickOrderIssues = (steps: ReadonlyArray<Schedule.ScheduleStep>): ReadonlyArray<OrderIssue> => {
86
+ // A schedule's steps never change, so `tryTick` checks each schedule once.
87
+ const cached = checked.get(steps)
88
+ if (cached !== undefined) return cached
89
+ const issues = computeIssues(steps)
90
+ checked.set(steps, issues)
91
+ return issues
92
+ }
93
+
94
+ const checked = new WeakMap<ReadonlyArray<Schedule.ScheduleStep>, ReadonlyArray<OrderIssue>>()
95
+
96
+ const computeIssues = (steps: ReadonlyArray<Schedule.ScheduleStep>): ReadonlyArray<OrderIssue> => {
97
+ const items = flatten(steps)
98
+ const issues: Array<OrderIssue> = []
99
+ const systemsAt = items.flatMap((item, at) => item.kind === "system" ? [{ system: item.system, at }] : [])
100
+ for (const { system: reader, at: index } of systemsAt) {
101
+ for (const read of accesses(reader)) {
102
+ if ((read.mode !== "read" && read.mode !== "changed") || read.thisTick !== true) continue
103
+ const data = read.descriptor.name
104
+ for (const { system, at } of systemsAt) {
105
+ if (at <= index || sameSystem(system, reader)) continue
106
+ if (!accesses(system).some((access) => access.mode === "write" && sameData(access.descriptor, read.descriptor))) continue
107
+ issues.push({
108
+ kind: "lateWriter",
109
+ reader: reader.name,
110
+ data,
111
+ writer: system.name,
112
+ message: `${reader.name} needs ${data} from this tick, but its writer ${system.name} runs after it: move ${system.name} before ${reader.name}, or read ${data} without thisTick`
113
+ })
114
+ }
115
+ }
116
+ for (const [slot, query] of Object.entries(reader.spec.queries as Record<string, QueryAccess>)) {
117
+ if (query.thisTick !== true) continue
118
+ const data = `queries.${slot}`
119
+ let lastFlush = -1
120
+ for (let at = 0; at < index; at++) if (items[at]!.kind === "flush") lastFlush = at
121
+ for (const { system, at } of systemsAt) {
122
+ if (sameSystem(system, reader) || !changesQuery(system, query)) continue
123
+ if (at > index) {
124
+ issues.push({
125
+ kind: "lateWriter",
126
+ reader: reader.name,
127
+ data,
128
+ writer: system.name,
129
+ message: `${system.name} queues commands that ${reader.name} needs this tick (${data}), but it runs after ${reader.name}: move ${system.name} before the applyDeferred() that precedes ${reader.name}, or read ${data} without thisTick`
130
+ })
131
+ } else if (at > lastFlush && at < index) {
132
+ issues.push({
133
+ kind: "unflushedWriter",
134
+ reader: reader.name,
135
+ data,
136
+ writer: system.name,
137
+ message: `${reader.name} needs this tick's commands for ${data}, but ${system.name} queues them with no applyDeferred() in between: add Game.Schedule.applyDeferred() after ${system.name}`
138
+ })
139
+ }
140
+ }
141
+ }
142
+ }
143
+ return issues
144
+ }
@@ -33,7 +33,7 @@ type SlotPlan =
33
33
  readonly mode: "write"
34
34
  readonly ordinal: number
35
35
  readonly constructor: DescriptorModule.ResultConstructor<unknown, unknown, unknown> | undefined
36
- readonly state: string | undefined
36
+ readonly entityState: string | undefined
37
37
  }
38
38
  | {
39
39
  readonly slot: string
@@ -46,6 +46,9 @@ interface LifecycleFilterPlan {
46
46
  readonly ordinal: number
47
47
  }
48
48
 
49
+ /** A query filter: one lifecycle filter, or `anyOf` several (passes when one does). */
50
+ type FilterPlan = ReadonlyArray<LifecycleFilterPlan>
51
+
49
52
  interface QueryState {
50
53
  readonly ordinal: number
51
54
  readonly required: ReadonlyArray<number>
@@ -54,7 +57,7 @@ interface QueryState {
54
57
  readonly withoutRelations: ReadonlyArray<Relation.Relation.Any>
55
58
  readonly withRelated: ReadonlyArray<Relation.Relation.Any>
56
59
  readonly withoutRelated: ReadonlyArray<Relation.Relation.Any>
57
- readonly filters: ReadonlyArray<LifecycleFilterPlan>
60
+ readonly filters: ReadonlyArray<FilterPlan>
58
61
  readonly slots: ReadonlyArray<SlotPlan>
59
62
  readonly proofSlots: ReadonlyArray<readonly [string, number]>
60
63
  readonly writeSlots: ReadonlyArray<readonly [string, number]>
@@ -143,7 +146,7 @@ export const makeQueryEngine = (world: World) => {
143
146
  mode: "write",
144
147
  ordinal,
145
148
  constructor: DescriptorModule.constructorOf(access.descriptor),
146
- state: DescriptorModule.isState(access.descriptor) ? access.descriptor.name : undefined
149
+ entityState: DescriptorModule.isEntityState(access.descriptor) ? access.descriptor.name : undefined
147
150
  })
148
151
  } else {
149
152
  slots.push({ slot, mode: "read", ordinal })
@@ -185,11 +188,13 @@ export const makeQueryEngine = (world: World) => {
185
188
  withoutRelations: query.withoutRelations,
186
189
  withRelated: unique(withRelated),
187
190
  withoutRelated: query.withoutRelated,
188
- filters: query.filters.map((filter) => {
189
- const ordinal = world.ordinalOf(filter.descriptor)
190
- world.trackChanges(ordinal)
191
- return { kind: filter.kind, ordinal }
192
- }),
191
+ filters: query.filters.map((filter) =>
192
+ (filter.kind === "anyOf" ? filter.filters : [filter]).map((member) => {
193
+ const ordinal = world.ordinalOf(member.descriptor)
194
+ world.trackChanges(ordinal)
195
+ return { kind: member.kind, ordinal }
196
+ })
197
+ ),
193
198
  slots,
194
199
  proofSlots,
195
200
  writeSlots,
@@ -239,14 +244,33 @@ export const makeQueryEngine = (world: World) => {
239
244
 
240
245
  const matchesFilters = (state: QueryState, record: EntityRecord, since: number): boolean => {
241
246
  for (const filter of state.filters) {
242
- const matched = filter.kind === "added"
243
- ? world.addedSince(record, filter.ordinal, since)
244
- : world.changedSince(record, filter.ordinal, since)
247
+ let matched = false
248
+ for (const member of filter) {
249
+ matched = member.kind === "added"
250
+ ? world.addedSince(record, member.ordinal, since)
251
+ : world.changedSince(record, member.ordinal, since)
252
+ if (matched) break
253
+ }
245
254
  if (!matched) return false
246
255
  }
247
256
  return true
248
257
  }
249
258
 
259
+ /**
260
+ * Ids that may pass one filter (may repeat), or `undefined` when a change
261
+ * log no longer covers `since`. An `anyOf` is the union of its members' logs.
262
+ */
263
+ const filterCandidates = (filter: FilterPlan, since: number): ReadonlyArray<number> | undefined => {
264
+ if (filter.length === 1) return world.changedCandidates(filter[0]!.ordinal, since)
265
+ const union: Array<number> = []
266
+ for (const member of filter) {
267
+ const logged = world.changedCandidates(member.ordinal, since)
268
+ if (logged === undefined) return undefined
269
+ for (const id of logged) union.push(id)
270
+ }
271
+ return union
272
+ }
273
+
250
274
  const relatedIds = (relation: Relation.Relation.Any, id: number): ReadonlyArray<Entity.EntityId<any, any>> =>
251
275
  world.relatedSourceIds(relation, id).map(world.entityIdOf)
252
276
 
@@ -255,7 +279,7 @@ export const makeQueryEngine = (world: World) => {
255
279
  case "read":
256
280
  return Cells.componentRead(record, plan.ordinal)
257
281
  case "write":
258
- return Cells.componentWrite(record, plan.ordinal, world, plan.constructor, plan.state)
282
+ return Cells.componentWrite(record, plan.ordinal, world, plan.constructor, plan.entityState)
259
283
  case "optional":
260
284
  return Cells.componentOptional(record, plan.ordinal)
261
285
  case "readRelation":
@@ -426,7 +450,7 @@ export const makeQueryEngine = (world: World) => {
426
450
  // bounds the candidates for either filter.
427
451
  let candidates: ReadonlyArray<number> | undefined
428
452
  for (const filter of state.filters) {
429
- const logged = world.changedCandidates(filter.ordinal, since)
453
+ const logged = filterCandidates(filter, since)
430
454
  if (logged === undefined) continue
431
455
  if (logged.length === 0) return []
432
456
  if (candidates === undefined || logged.length < candidates.length) candidates = logged
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Runtime side of `Schema.requires`: the requirement index built once per
3
+ * bound schema, used to expand `Game.System.spawns(...)`, to check commands
4
+ * when they are applied, and to check restored entities.
5
+ *
6
+ * The compile-time counterpart lives in `Command.ts` (spawn, insert, remove)
7
+ * and `Schema.ts` (`ValidateRequires`).
8
+ */
9
+ import type { Descriptor } from "../Descriptor.ts"
10
+ import type { Schema } from "../Schema.ts"
11
+
12
+ type ComponentDescriptor = Descriptor<"component", string, any>
13
+
14
+ export interface RequirementIndex {
15
+ /** Whether the schema declares any requirement. */
16
+ readonly empty: boolean
17
+ /** Component name to the components it directly requires. */
18
+ readonly requires: ReadonlyMap<string, ReadonlyArray<ComponentDescriptor>>
19
+ /** Component name to the components that directly require it. */
20
+ readonly requiredBy: ReadonlyMap<string, ReadonlyArray<ComponentDescriptor>>
21
+ }
22
+
23
+ const push = (map: Map<string, Array<ComponentDescriptor>>, key: string, value: ComponentDescriptor): void => {
24
+ const list = map.get(key)
25
+ if (list === undefined) map.set(key, [value])
26
+ else if (!list.some((entry) => entry.name === value.name)) list.push(value)
27
+ }
28
+
29
+ export const requirementIndex = (schema: Schema.Any): RequirementIndex => {
30
+ const requires = new Map<string, Array<ComponentDescriptor>>()
31
+ const requiredBy = new Map<string, Array<ComponentDescriptor>>()
32
+ for (const requirement of schema.requires) {
33
+ for (const required of requirement.required) {
34
+ push(requires, requirement.component.name, required)
35
+ push(requiredBy, required.name, requirement.component)
36
+ }
37
+ }
38
+ return { empty: requires.size === 0, requires, requiredBy }
39
+ }
40
+
41
+ /** `components` and everything they require, transitively, without duplicates. */
42
+ export const withRequired = (
43
+ index: RequirementIndex,
44
+ components: ReadonlyArray<ComponentDescriptor>
45
+ ): ReadonlyArray<ComponentDescriptor> => {
46
+ if (index.empty) return components
47
+ const result: Array<ComponentDescriptor> = []
48
+ const seen = new Set<string>()
49
+ const visit = (descriptor: ComponentDescriptor): void => {
50
+ if (seen.has(descriptor.name)) return
51
+ seen.add(descriptor.name)
52
+ result.push(descriptor)
53
+ for (const required of index.requires.get(descriptor.name) ?? []) visit(required)
54
+ }
55
+ components.forEach(visit)
56
+ return result
57
+ }
58
+
59
+ /** The first requirement `held` breaks, as `[requirer, missing]`, or `undefined`. */
60
+ export const firstMissing = (
61
+ index: RequirementIndex,
62
+ held: (name: string) => boolean,
63
+ names: Iterable<string>
64
+ ): readonly [string, string] | undefined => {
65
+ for (const name of names) {
66
+ for (const required of index.requires.get(name) ?? []) {
67
+ if (!held(required.name)) return [name, required.name]
68
+ }
69
+ }
70
+ return undefined
71
+ }
@@ -1,99 +0,0 @@
1
- /**
2
- * Helpers for validating reusable authored values once and reusing them later.
3
- *
4
- * `Definition` is intended for static or rarely changing authored data such as
5
- * spawn points, collider sizes, arena bounds, or other constants that should
6
- * cross the validation boundary once and then remain branded afterward.
7
- *
8
- * In game code this is the "content setup" companion to runtime/world setup:
9
- * validate authored constants early, keep them in carried form, and then reuse
10
- * them from setup systems, reset systems, or content modules without
11
- * revalidating on every frame.
12
- *
13
- * @example
14
- * ```ts
15
- * // Validate authored constants once when defining the content bundle.
16
- * const player = Definition.all({
17
- * spawn: Definition.entry(Vector2, { x: 32, y: 48 }),
18
- * size: Definition.entry(Size2, { width: 16, height: 16 })
19
- * })
20
- * ```
21
- *
22
- * @module Definition
23
- * @docGroup core
24
- *
25
- * @categoryDescription Definition Types
26
- * Named reusable shapes used to validate and retain authored values.
27
- *
28
- * @categoryDescription Definition Builders
29
- * Helpers that validate one or several authored values through existing constructors.
30
- */
31
- import * as internal from "./internal/definition.ts";
32
- import type * as Result from "./Result.ts";
33
- /**
34
- * One reusable validated definition entry.
35
- *
36
- * @category Definition Types
37
- */
38
- export type Entry<Value, Error> = internal.Entry<Value, Error>;
39
- /**
40
- * Record of named definition entries accepted by {@link all}.
41
- *
42
- * @category Definition Types
43
- */
44
- export type Entries = internal.Entries;
45
- /**
46
- * Minimal constructor contract accepted by {@link entry}.
47
- *
48
- * @category Definition Types
49
- */
50
- export type ResultConstructor<Value, Raw, Error> = internal.ResultConstructor<Value, Raw, Error>;
51
- /**
52
- * Success shape produced by {@link all}.
53
- *
54
- * @category Definition Types
55
- */
56
- export type SuccessOf<Input extends Entries> = internal.SuccessOf<Input>;
57
- /**
58
- * Error shape produced by {@link all}.
59
- *
60
- * @category Definition Types
61
- */
62
- export type ErrorOf<Input extends Entries> = internal.ErrorOf<Input>;
63
- /**
64
- * Validates one reusable authored value through an existing constructor.
65
- *
66
- * Use this for one named authored constant that should cross a constructor
67
- * boundary now and remain in carried form afterward.
68
- *
69
- * @example
70
- * ```ts
71
- * // Validate a single authored position once during content setup.
72
- * const playerSpawn = Definition.entry(Vector2, { x: 32, y: 48 })
73
- * ```
74
- *
75
- * @category Definition Builders
76
- */
77
- export declare const entry: <Value, Raw, Error>(constructor: ResultConstructor<Value, Raw, Error>, raw: Raw) => Entry<Value, Error>;
78
- /**
79
- * Validates a named record of reusable authored values at once.
80
- *
81
- * Successful entries are returned under the same keys. Failed entries remain
82
- * keyed so authored-data setup can report exactly which constant was invalid.
83
- *
84
- * Use this when one content bundle or level definition should either validate
85
- * as a whole or report a structured set of authoring failures.
86
- *
87
- * @example
88
- * ```ts
89
- * // Validate one authored content bundle and keep failures keyed by field.
90
- * const definitions = Definition.all({
91
- * spawn: Definition.entry(Vector2, { x: 32, y: 48 }),
92
- * collider: Definition.entry(Size2, { width: 16, height: 16 })
93
- * })
94
- * ```
95
- *
96
- * @category Definition Builders
97
- */
98
- export declare const all: <Input extends Entries>(input: Input) => Result.Result<SuccessOf<Input>, ErrorOf<Input>>;
99
- //# sourceMappingURL=Definition.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Definition.d.ts","sourceRoot":"","sources":["../src/Definition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,KAAK,QAAQ,MAAM,0BAA0B,CAAA;AACpD,OAAO,KAAK,KAAK,MAAM,MAAM,aAAa,CAAA;AAE1C;;;;GAIG;AACH,MAAM,MAAM,KAAK,CAAC,KAAK,EAAE,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AAC9D;;;;GAIG;AACH,MAAM,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAA;AACtC;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,QAAQ,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,CAAA;AAChG;;;;GAIG;AACH,MAAM,MAAM,SAAS,CAAC,KAAK,SAAS,OAAO,IAAI,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;AACxE;;;;GAIG;AACH,MAAM,MAAM,OAAO,CAAC,KAAK,SAAS,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAEpE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,KAAK,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EACpC,WAAW,EAAE,iBAAiB,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,EACjD,GAAG,EAAE,GAAG,KACL,KAAK,CAAC,KAAK,EAAE,KAAK,CAAkB,CAAA;AAEzC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,GAAG,EAAE,CAAC,KAAK,SAAS,OAAO,EACtC,KAAK,EAAE,KAAK,KACT,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAgB,CAAA"}
@@ -1,68 +0,0 @@
1
- /**
2
- * Helpers for validating reusable authored values once and reusing them later.
3
- *
4
- * `Definition` is intended for static or rarely changing authored data such as
5
- * spawn points, collider sizes, arena bounds, or other constants that should
6
- * cross the validation boundary once and then remain branded afterward.
7
- *
8
- * In game code this is the "content setup" companion to runtime/world setup:
9
- * validate authored constants early, keep them in carried form, and then reuse
10
- * them from setup systems, reset systems, or content modules without
11
- * revalidating on every frame.
12
- *
13
- * @example
14
- * ```ts
15
- * // Validate authored constants once when defining the content bundle.
16
- * const player = Definition.all({
17
- * spawn: Definition.entry(Vector2, { x: 32, y: 48 }),
18
- * size: Definition.entry(Size2, { width: 16, height: 16 })
19
- * })
20
- * ```
21
- *
22
- * @module Definition
23
- * @docGroup core
24
- *
25
- * @categoryDescription Definition Types
26
- * Named reusable shapes used to validate and retain authored values.
27
- *
28
- * @categoryDescription Definition Builders
29
- * Helpers that validate one or several authored values through existing constructors.
30
- */
31
- import * as internal from "./internal/definition.js";
32
- /**
33
- * Validates one reusable authored value through an existing constructor.
34
- *
35
- * Use this for one named authored constant that should cross a constructor
36
- * boundary now and remain in carried form afterward.
37
- *
38
- * @example
39
- * ```ts
40
- * // Validate a single authored position once during content setup.
41
- * const playerSpawn = Definition.entry(Vector2, { x: 32, y: 48 })
42
- * ```
43
- *
44
- * @category Definition Builders
45
- */
46
- export const entry = internal.entry;
47
- /**
48
- * Validates a named record of reusable authored values at once.
49
- *
50
- * Successful entries are returned under the same keys. Failed entries remain
51
- * keyed so authored-data setup can report exactly which constant was invalid.
52
- *
53
- * Use this when one content bundle or level definition should either validate
54
- * as a whole or report a structured set of authoring failures.
55
- *
56
- * @example
57
- * ```ts
58
- * // Validate one authored content bundle and keep failures keyed by field.
59
- * const definitions = Definition.all({
60
- * spawn: Definition.entry(Vector2, { x: 32, y: 48 }),
61
- * collider: Definition.entry(Size2, { width: 16, height: 16 })
62
- * })
63
- * ```
64
- *
65
- * @category Definition Builders
66
- */
67
- export const all = internal.all;
68
- //# sourceMappingURL=Definition.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Definition.js","sourceRoot":"","sources":["../src/Definition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,KAAK,QAAQ,MAAM,0BAA0B,CAAA;AAkCpD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,KAAK,GAGS,QAAQ,CAAC,KAAK,CAAA;AAEzC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,GAAG,GAEuC,QAAQ,CAAC,GAAG,CAAA"}
package/dist/Feature.d.ts DELETED
@@ -1,106 +0,0 @@
1
- import type * as Schedule from "./Schedule.ts";
2
- import type { MergeSchemaDefinitions, Schema, SchemaDefinition, ValidateFragments } from "./Schema.ts";
3
- type EmptySchema = SchemaDefinition<{}, {}, {}, {}>;
4
- type AnyFeature = {
5
- readonly kind: "feature";
6
- readonly name: string;
7
- readonly schema: Schema.Any;
8
- readonly requires: ReadonlyArray<AnyFeature>;
9
- readonly build: unknown;
10
- readonly output: FeatureBuildOutput;
11
- };
12
- type AnySchedule = Schedule.ScheduleDefinition<any, any, any, any, any>;
13
- /**
14
- * What a feature builder returns: bootstrap and update schedules, plus any
15
- * other values the feature wants to expose on the composed project.
16
- */
17
- export type FeatureBuildOutput = {
18
- readonly bootstrap?: ReadonlyArray<AnySchedule>;
19
- readonly update?: ReadonlyArray<AnySchedule>;
20
- };
21
- /**
22
- * The bound authoring surface a feature builder receives. It is the normal
23
- * `Game` API restricted to the descriptors the feature can see; runtimes are
24
- * built from the composed project instead.
25
- */
26
- export type FeatureBuildGame<Accessible extends Schema.Any, Root = unknown> = Omit<Schema.Game<Accessible, Root>, "Runtime">;
27
- type FeatureBuildFunction<Accessible extends Schema.Any, Output extends FeatureBuildOutput = FeatureBuildOutput> = (Game: FeatureBuildGame<Accessible>) => Output;
28
- export interface FeatureDefinition<Name extends string = string, FeatureSchema extends Schema.Any = Schema.Any, Requires extends ReadonlyArray<AnyFeature> = ReadonlyArray<AnyFeature>, Output extends FeatureBuildOutput = FeatureBuildOutput> {
29
- readonly kind: "feature";
30
- readonly name: Name;
31
- readonly schema: FeatureSchema;
32
- readonly requires: Requires;
33
- readonly build: FeatureBuildFunction<MergeSchemaDefinitions<FeatureSchema, MergeFeatureSchemas<Requires>>, Output>;
34
- readonly output: Output;
35
- }
36
- type MergeFeatureSchemas<Features extends ReadonlyArray<AnyFeature>> = Features extends readonly [infer Head extends AnyFeature, ...infer Tail extends Array<AnyFeature>] ? MergeSchemaDefinitions<FeatureClosureSchema<Head>, MergeFeatureSchemas<Tail>> : EmptySchema;
37
- type FeatureClosureSchema<F extends AnyFeature> = F extends FeatureDefinition<any, infer FeatureSchema extends Schema.Any, infer Requires extends ReadonlyArray<AnyFeature>, any> ? MergeSchemaDefinitions<FeatureSchema, MergeFeatureSchemas<Requires>> : EmptySchema;
38
- type FeatureNames<Features extends ReadonlyArray<AnyFeature>> = Features[number]["name"];
39
- type DuplicateFeatureNames<Features extends ReadonlyArray<AnyFeature>, Seen extends string = never> = Features extends readonly [infer Head extends AnyFeature, ...infer Tail extends Array<AnyFeature>] ? Head["name"] extends Seen ? Head["name"] | DuplicateFeatureNames<Tail, Seen> : DuplicateFeatureNames<Tail, Seen | Head["name"]> : never;
40
- type MissingFeatureDependencies<Features extends ReadonlyArray<AnyFeature>> = Exclude<Features[number]["requires"][number]["name"], FeatureNames<Features>>;
41
- type FeatureSchemas<Features extends ReadonlyArray<AnyFeature>> = {
42
- readonly [K in keyof Features]: Features[K]["schema"];
43
- };
44
- /**
45
- * Rejects duplicate feature names, missing required features, and schema
46
- * fragments whose keys or descriptor names collide.
47
- */
48
- type ValidateFeatureSelection<Features extends ReadonlyArray<AnyFeature>> = [
49
- DuplicateFeatureNames<Features>
50
- ] extends [never] ? [MissingFeatureDependencies<Features>] extends [never] ? ValidateFragments<FeatureSchemas<Features>> : {
51
- readonly __fixFeatureDependencies__: MissingFeatureDependencies<Features>;
52
- } : {
53
- readonly __fixFeatureSelection__: DuplicateFeatureNames<Features>;
54
- };
55
- type RebindFeatureSchedule<ScheduleValue, S extends Schema.Any, Root> = ScheduleValue extends Schedule.ScheduleDefinition<any, infer Requirements, any, infer Carried, infer Failure> ? Schedule.ScheduleDefinition<S, Requirements, Root, Carried, Failure> : never;
56
- type FeatureScheduleArray<Output, Key extends "bootstrap" | "update"> = Key extends keyof Output ? Extract<Output[Key], ReadonlyArray<AnySchedule>> : readonly [];
57
- type NormalizeFeatureOutput<Output extends object, S extends Schema.Any, Root> = {
58
- readonly [K in Exclude<keyof Output, "bootstrap" | "update">]: Output[K];
59
- } & {
60
- readonly bootstrap: ReadonlyArray<RebindFeatureSchedule<FeatureScheduleArray<Output, "bootstrap">[number], S, Root>>;
61
- readonly update: ReadonlyArray<RebindFeatureSchedule<FeatureScheduleArray<Output, "update">[number], S, Root>>;
62
- };
63
- type FeatureOutputRecord<Features extends ReadonlyArray<AnyFeature>, S extends Schema.Any, Root> = {
64
- readonly [K in FeatureNames<Features>]: NormalizeFeatureOutput<Extract<Features[number], {
65
- readonly name: K;
66
- }>["output"], S, Root>;
67
- };
68
- /**
69
- * The result of composing features: the merged schema, the bound `Game`,
70
- * each feature's normalized output, and the aggregated schedules in feature
71
- * order.
72
- */
73
- export interface ComposedFeatureProject<Features extends ReadonlyArray<AnyFeature>, Root = unknown, S extends Schema.Any = MergeFeatureSchemas<Features>> {
74
- readonly schema: S;
75
- readonly Game: Schema.Game<S, Root>;
76
- readonly features: FeatureOutputRecord<Features, S, Root>;
77
- readonly schedules: {
78
- readonly bootstrap: ReadonlyArray<FeatureOutputRecord<Features, S, Root>[FeatureNames<Features>]["bootstrap"][number]>;
79
- readonly update: ReadonlyArray<FeatureOutputRecord<Features, S, Root>[FeatureNames<Features>]["update"][number]>;
80
- };
81
- }
82
- /**
83
- * Defines one pre-bind feature.
84
- */
85
- export declare const define: <const Name extends string, FeatureSchema extends Schema.Any, const Requires extends ReadonlyArray<AnyFeature> = [], Output extends FeatureBuildOutput = FeatureBuildOutput>(name: Name, options: {
86
- readonly schema: FeatureSchema;
87
- readonly requires?: Requires;
88
- readonly build: FeatureBuildFunction<MergeSchemaDefinitions<FeatureSchema, MergeFeatureSchemas<Requires>>, Output>;
89
- }) => FeatureDefinition<Name, FeatureSchema, Requires, Output>;
90
- /**
91
- * Composes features into one merged schema and one bound `Game`, then builds
92
- * every feature against it.
93
- *
94
- * Aggregated schedule order is the selected feature order, not dependency
95
- * order. Run them with `runtime.tick(...project.schedules.update)`.
96
- */
97
- export declare const compose: <Root, const Features extends readonly [AnyFeature, ...Array<AnyFeature>]>(options: {
98
- readonly root: Root;
99
- readonly features: Features;
100
- } & ValidateFeatureSelection<Features>) => ComposedFeatureProject<Features, Root>;
101
- export declare const Feature: {
102
- define: typeof define;
103
- compose: typeof compose;
104
- };
105
- export {};
106
- //# sourceMappingURL=Feature.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Feature.d.ts","sourceRoot":"","sources":["../src/Feature.ts"],"names":[],"mappings":"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"}