@oasys/oecs 0.3.1 → 0.5.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/CHANGELOG.md +553 -0
- package/README.md +207 -267
- package/dist/core/ecs/access_check.d.cts +77 -0
- package/dist/core/ecs/access_check.d.ts +77 -0
- package/dist/core/ecs/access_check.d.ts.map +1 -0
- package/dist/core/ecs/archetype.d.cts +486 -0
- package/dist/core/ecs/archetype.d.ts +486 -0
- package/dist/core/ecs/archetype.d.ts.map +1 -0
- package/dist/core/ecs/archetype_graph.d.cts +96 -0
- package/dist/core/ecs/archetype_graph.d.ts +96 -0
- package/dist/core/ecs/archetype_graph.d.ts.map +1 -0
- package/dist/core/ecs/builtin_relations.d.cts +43 -0
- package/dist/core/ecs/builtin_relations.d.ts +43 -0
- package/dist/core/ecs/builtin_relations.d.ts.map +1 -0
- package/dist/core/ecs/command_log.d.cts +116 -0
- package/dist/core/ecs/command_log.d.ts +116 -0
- package/dist/core/ecs/command_log.d.ts.map +1 -0
- package/dist/core/ecs/component.d.cts +176 -0
- package/dist/core/ecs/component.d.ts +176 -0
- package/dist/core/ecs/component.d.ts.map +1 -0
- package/dist/core/ecs/compute_backend.d.cts +37 -0
- package/dist/core/ecs/compute_backend.d.ts +37 -0
- package/dist/core/ecs/compute_backend.d.ts.map +1 -0
- package/dist/core/ecs/debug_names.d.cts +7 -0
- package/dist/core/ecs/debug_names.d.ts +7 -0
- package/dist/core/ecs/debug_names.d.ts.map +1 -0
- package/dist/core/ecs/deferred_commands.d.cts +55 -0
- package/dist/core/ecs/deferred_commands.d.ts +55 -0
- package/dist/core/ecs/deferred_commands.d.ts.map +1 -0
- package/dist/core/ecs/dispatch_trace.d.cts +93 -0
- package/dist/core/ecs/dispatch_trace.d.ts +93 -0
- package/dist/core/ecs/dispatch_trace.d.ts.map +1 -0
- package/dist/core/ecs/ecs.d.cts +562 -0
- package/dist/core/ecs/ecs.d.ts +562 -0
- package/dist/core/ecs/ecs.d.ts.map +1 -0
- package/dist/core/ecs/ecs_memory.d.cts +179 -0
- package/dist/core/ecs/ecs_memory.d.ts +179 -0
- package/dist/core/ecs/ecs_memory.d.ts.map +1 -0
- package/dist/core/ecs/entity.d.cts +34 -0
- package/dist/core/ecs/entity.d.ts +34 -0
- package/dist/core/ecs/entity.d.ts.map +1 -0
- package/dist/core/ecs/entity_allocator.d.cts +59 -0
- package/dist/core/ecs/entity_allocator.d.ts +59 -0
- package/dist/core/ecs/entity_allocator.d.ts.map +1 -0
- package/dist/core/ecs/event.d.cts +79 -0
- package/dist/core/ecs/event.d.ts +79 -0
- package/dist/core/ecs/event.d.ts.map +1 -0
- package/dist/core/ecs/event_registry.d.cts +22 -0
- package/dist/core/ecs/event_registry.d.ts +22 -0
- package/dist/core/ecs/event_registry.d.ts.map +1 -0
- package/dist/core/ecs/facades.d.cts +158 -0
- package/dist/core/ecs/facades.d.ts +158 -0
- package/dist/core/ecs/facades.d.ts.map +1 -0
- package/dist/core/ecs/frame_stepper.d.cts +58 -0
- package/dist/core/ecs/frame_stepper.d.ts +58 -0
- package/dist/core/ecs/frame_stepper.d.ts.map +1 -0
- package/dist/core/ecs/frame_trace.d.cts +133 -0
- package/dist/core/ecs/frame_trace.d.ts +133 -0
- package/dist/core/ecs/frame_trace.d.ts.map +1 -0
- package/dist/core/ecs/host_commands.d.cts +274 -0
- package/dist/core/ecs/host_commands.d.ts +274 -0
- package/dist/core/ecs/host_commands.d.ts.map +1 -0
- package/dist/core/ecs/index.d.cts +46 -0
- package/dist/core/ecs/index.d.ts +46 -0
- package/dist/core/ecs/index.d.ts.map +1 -0
- package/dist/core/ecs/observer.d.cts +173 -0
- package/dist/core/ecs/observer.d.ts +173 -0
- package/dist/core/ecs/observer.d.ts.map +1 -0
- package/dist/core/ecs/query.d.cts +718 -0
- package/dist/core/ecs/query.d.ts +718 -0
- package/dist/core/ecs/query.d.ts.map +1 -0
- package/dist/core/ecs/ref.d.cts +31 -0
- package/dist/core/ecs/ref.d.ts +31 -0
- package/dist/core/ecs/ref.d.ts.map +1 -0
- package/dist/core/ecs/relation.d.cts +243 -0
- package/dist/core/ecs/relation.d.ts +243 -0
- package/dist/core/ecs/relation.d.ts.map +1 -0
- package/dist/core/ecs/relation_service.d.cts +235 -0
- package/dist/core/ecs/relation_service.d.ts +235 -0
- package/dist/core/ecs/relation_service.d.ts.map +1 -0
- package/dist/core/ecs/resource.d.cts +53 -0
- package/dist/core/ecs/resource.d.ts +53 -0
- package/dist/core/ecs/resource.d.ts.map +1 -0
- package/dist/core/ecs/resource_registry.d.cts +20 -0
- package/dist/core/ecs/resource_registry.d.ts +20 -0
- package/dist/core/ecs/resource_registry.d.ts.map +1 -0
- package/dist/core/ecs/resume.d.cts +85 -0
- package/dist/core/ecs/resume.d.ts +85 -0
- package/dist/core/ecs/resume.d.ts.map +1 -0
- package/dist/core/ecs/run_condition.d.cts +81 -0
- package/dist/core/ecs/run_condition.d.ts +81 -0
- package/dist/core/ecs/run_condition.d.ts.map +1 -0
- package/dist/core/ecs/schedule.d.cts +142 -0
- package/dist/core/ecs/schedule.d.ts +142 -0
- package/dist/core/ecs/schedule.d.ts.map +1 -0
- package/dist/core/ecs/snapshot_service.d.cts +94 -0
- package/dist/core/ecs/snapshot_service.d.ts +94 -0
- package/dist/core/ecs/snapshot_service.d.ts.map +1 -0
- package/dist/core/ecs/sparse_store.d.cts +110 -0
- package/dist/core/ecs/sparse_store.d.ts +110 -0
- package/dist/core/ecs/sparse_store.d.ts.map +1 -0
- package/dist/core/ecs/store.d.cts +950 -0
- package/dist/core/ecs/store.d.ts +950 -0
- package/dist/core/ecs/store.d.ts.map +1 -0
- package/dist/core/ecs/store_layout_listener.d.cts +23 -0
- package/dist/core/ecs/store_layout_listener.d.ts +23 -0
- package/dist/core/ecs/store_layout_listener.d.ts.map +1 -0
- package/dist/core/ecs/system.d.cts +250 -0
- package/dist/core/ecs/system.d.ts +250 -0
- package/dist/core/ecs/system.d.ts.map +1 -0
- package/dist/core/ecs/utils/arrays.d.cts +7 -0
- package/dist/{utils → core/ecs/utils}/arrays.d.ts +2 -1
- package/dist/core/ecs/utils/arrays.d.ts.map +1 -0
- package/dist/core/ecs/utils/constants.d.ts +12 -0
- package/dist/core/ecs/utils/constants.d.ts.map +1 -0
- package/dist/core/ecs/utils/error.d.cts +61 -0
- package/dist/core/ecs/utils/error.d.ts +61 -0
- package/dist/core/ecs/utils/error.d.ts.map +1 -0
- package/dist/core/store/action_ring.d.cts +136 -0
- package/dist/core/store/action_ring.d.ts +136 -0
- package/dist/core/store/action_ring.d.ts.map +1 -0
- package/dist/core/store/allocator.d.cts +238 -0
- package/dist/core/store/allocator.d.ts +238 -0
- package/dist/core/store/allocator.d.ts.map +1 -0
- package/dist/core/store/buffer_backed_column.d.cts +69 -0
- package/dist/core/store/buffer_backed_column.d.ts +69 -0
- package/dist/core/store/buffer_backed_column.d.ts.map +1 -0
- package/dist/core/store/column_store.d.cts +273 -0
- package/dist/core/store/column_store.d.ts +273 -0
- package/dist/core/store/column_store.d.ts.map +1 -0
- package/dist/core/store/command_dispatch.d.cts +52 -0
- package/dist/core/store/command_dispatch.d.ts +52 -0
- package/dist/core/store/command_dispatch.d.ts.map +1 -0
- package/dist/core/store/command_ring.d.cts +107 -0
- package/dist/core/store/command_ring.d.ts +107 -0
- package/dist/core/store/command_ring.d.ts.map +1 -0
- package/dist/core/store/descriptor.d.cts +80 -0
- package/dist/core/store/descriptor.d.ts +80 -0
- package/dist/core/store/descriptor.d.ts.map +1 -0
- package/dist/core/store/entity_index.d.cts +108 -0
- package/dist/core/store/entity_index.d.ts +108 -0
- package/dist/core/store/entity_index.d.ts.map +1 -0
- package/dist/core/store/event_ring.d.cts +95 -0
- package/dist/core/store/event_ring.d.ts +95 -0
- package/dist/core/store/event_ring.d.ts.map +1 -0
- package/dist/core/store/extend.d.cts +39 -0
- package/dist/core/store/extend.d.ts +39 -0
- package/dist/core/store/extend.d.ts.map +1 -0
- package/dist/core/store/grow.d.cts +34 -0
- package/dist/core/store/grow.d.ts +34 -0
- package/dist/core/store/grow.d.ts.map +1 -0
- package/dist/core/store/header.d.cts +64 -0
- package/dist/core/store/header.d.ts +64 -0
- package/dist/core/store/header.d.ts.map +1 -0
- package/dist/core/store/index.d.cts +17 -0
- package/dist/core/store/index.d.ts +17 -0
- package/dist/core/store/index.d.ts.map +1 -0
- package/dist/core/store/layout_ops.d.cts +152 -0
- package/dist/core/store/layout_ops.d.ts +152 -0
- package/dist/core/store/layout_ops.d.ts.map +1 -0
- package/dist/core/store/region_table.d.cts +74 -0
- package/dist/core/store/region_table.d.ts +74 -0
- package/dist/core/store/region_table.d.ts.map +1 -0
- package/dist/core/store/snapshot.d.cts +43 -0
- package/dist/core/store/snapshot.d.ts +43 -0
- package/dist/core/store/snapshot.d.ts.map +1 -0
- package/dist/core/store/state_hash.d.cts +38 -0
- package/dist/core/store/state_hash.d.ts +38 -0
- package/dist/core/store/state_hash.d.ts.map +1 -0
- package/dist/core/store/store_regions.d.cts +38 -0
- package/dist/core/store/store_regions.d.ts +38 -0
- package/dist/core/store/store_regions.d.ts.map +1 -0
- package/dist/core/store/vendored_abi/abi.d.cts +43 -0
- package/dist/core/store/vendored_abi/abi.d.ts +43 -0
- package/dist/core/store/vendored_abi/abi.d.ts.map +1 -0
- package/dist/dev_flag.d.cts +17 -0
- package/dist/dev_flag.d.ts +17 -0
- package/dist/dev_flag.d.ts.map +1 -0
- package/dist/extensions/editor/editor.d.cts +170 -0
- package/dist/extensions/editor/editor.d.ts +170 -0
- package/dist/extensions/editor/editor.d.ts.map +1 -0
- package/dist/extensions/editor/field_handle.d.cts +40 -0
- package/dist/extensions/editor/field_handle.d.ts +40 -0
- package/dist/extensions/editor/field_handle.d.ts.map +1 -0
- package/dist/extensions/editor/index.cjs +1 -0
- package/dist/extensions/editor/index.d.cts +21 -0
- package/dist/extensions/editor/index.d.ts +21 -0
- package/dist/extensions/editor/index.d.ts.map +1 -0
- package/dist/extensions/editor/index.js +237 -0
- package/dist/extensions/reactive/ecs_sync.d.cts +214 -0
- package/dist/extensions/reactive/ecs_sync.d.ts +214 -0
- package/dist/extensions/reactive/ecs_sync.d.ts.map +1 -0
- package/dist/extensions/reactive/index.cjs +1 -0
- package/dist/extensions/reactive/index.d.cts +23 -0
- package/dist/extensions/reactive/index.d.ts +23 -0
- package/dist/extensions/reactive/index.d.ts.map +1 -0
- package/dist/extensions/reactive/index.js +215 -0
- package/dist/extensions/solid/index.cjs +1 -0
- package/dist/extensions/solid/index.d.cts +6 -0
- package/dist/extensions/solid/index.d.ts +6 -0
- package/dist/extensions/solid/index.d.ts.map +1 -0
- package/dist/extensions/solid/index.js +36 -0
- package/dist/extensions/solid/kernel_solid.d.cts +45 -0
- package/dist/extensions/solid/kernel_solid.d.ts +45 -0
- package/dist/extensions/solid/kernel_solid.d.ts.map +1 -0
- package/dist/host_commands-BF8QMi3c.cjs +1 -0
- package/dist/host_commands-i4cAeyL5.js +2318 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +66 -0
- package/dist/index.d.ts +65 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7080 -1289
- package/dist/internal.cjs +2 -0
- package/dist/internal.d.cts +20 -0
- package/dist/internal.d.ts +20 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +141 -0
- package/dist/interop-CT-REx0W.cjs +1 -0
- package/dist/interop-CcY6ASQc.js +18 -0
- package/dist/kernel-DgyrLFjW.js +227 -0
- package/dist/kernel-yWV3XnAb.cjs +1 -0
- package/dist/primitives.cjs +1 -0
- package/dist/primitives.d.cts +18 -0
- package/dist/primitives.d.ts +18 -0
- package/dist/primitives.d.ts.map +1 -0
- package/dist/primitives.js +45 -0
- package/dist/reactive/array.d.cts +24 -0
- package/dist/reactive/array.d.ts +24 -0
- package/dist/reactive/array.d.ts.map +1 -0
- package/dist/reactive/index.cjs +1 -0
- package/dist/reactive/index.d.cts +11 -0
- package/dist/reactive/index.d.ts +11 -0
- package/dist/reactive/index.d.ts.map +1 -0
- package/dist/reactive/index.js +18 -0
- package/dist/reactive/interop.d.cts +19 -0
- package/dist/reactive/interop.d.ts +19 -0
- package/dist/reactive/interop.d.ts.map +1 -0
- package/dist/reactive/kernel.d.cts +73 -0
- package/dist/reactive/kernel.d.ts +73 -0
- package/dist/reactive/kernel.d.ts.map +1 -0
- package/dist/reactive/map.d.cts +16 -0
- package/dist/reactive/map.d.ts +16 -0
- package/dist/reactive/map.d.ts.map +1 -0
- package/dist/reactive/shallow.d.cts +11 -0
- package/dist/reactive/shallow.d.ts +11 -0
- package/dist/reactive/shallow.d.ts.map +1 -0
- package/dist/reactive/struct.d.cts +10 -0
- package/dist/reactive/struct.d.ts +10 -0
- package/dist/reactive/struct.d.ts.map +1 -0
- package/dist/shallow-DQ8aG51_.cjs +1 -0
- package/dist/shallow-DfnAm9vG.js +150 -0
- package/dist/shared-BU1Cd40h.js +103 -0
- package/dist/shared-BymrGTyR.cjs +1 -0
- package/dist/shared.cjs +1 -0
- package/dist/shared.d.cts +22 -0
- package/dist/shared.d.ts +22 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +7 -0
- package/dist/topological_sort-BDvEyb9W.cjs +1 -0
- package/dist/topological_sort-DK6EjpWa.js +135 -0
- package/dist/type_primitives/assertions.d.cts +32 -0
- package/dist/type_primitives/assertions.d.ts +25 -9
- package/dist/type_primitives/assertions.d.ts.map +1 -1
- package/dist/type_primitives/binary_heap/binary_heap.d.cts +37 -0
- package/dist/type_primitives/binary_heap/binary_heap.d.ts +6 -2
- package/dist/type_primitives/binary_heap/binary_heap.d.ts.map +1 -1
- package/dist/type_primitives/bitset/bitset.d.cts +54 -0
- package/dist/type_primitives/bitset/bitset.d.ts +16 -4
- package/dist/type_primitives/bitset/bitset.d.ts.map +1 -1
- package/dist/type_primitives/brand.d.cts +23 -0
- package/dist/type_primitives/brand.d.ts +6 -1
- package/dist/type_primitives/brand.d.ts.map +1 -1
- package/dist/type_primitives/error.d.cts +16 -0
- package/dist/type_primitives/error.d.ts +8 -3
- package/dist/type_primitives/error.d.ts.map +1 -1
- package/dist/type_primitives/index.d.cts +13 -0
- package/dist/type_primitives/index.d.ts +12 -9
- package/dist/type_primitives/index.d.ts.map +1 -1
- package/dist/type_primitives/sparse_map/sparse_map.d.cts +30 -0
- package/dist/type_primitives/sparse_map/sparse_map.d.ts +7 -3
- package/dist/type_primitives/sparse_map/sparse_map.d.ts.map +1 -1
- package/dist/type_primitives/sparse_set/sparse_set.d.cts +28 -0
- package/dist/type_primitives/sparse_set/sparse_set.d.ts +4 -0
- package/dist/type_primitives/sparse_set/sparse_set.d.ts.map +1 -1
- package/dist/type_primitives/topological_sort/topological_sort.d.cts +29 -0
- package/dist/type_primitives/topological_sort/topological_sort.d.ts +7 -3
- package/dist/type_primitives/topological_sort/topological_sort.d.ts.map +1 -1
- package/dist/type_primitives/typed_arrays/typed_arrays.d.cts +127 -0
- package/dist/type_primitives/typed_arrays/typed_arrays.d.ts +53 -16
- package/dist/type_primitives/typed_arrays/typed_arrays.d.ts.map +1 -1
- package/dist/typed_arrays-BcXcnzB4.js +258 -0
- package/dist/typed_arrays-D3NmwtCG.cjs +1 -0
- package/dist/utils/error.d.cts +6 -0
- package/dist/utils/error.d.ts +2 -20
- package/dist/utils/error.d.ts.map +1 -1
- package/dist/version.d.cts +10 -0
- package/dist/version.d.ts +10 -0
- package/dist/version.d.ts.map +1 -0
- package/package.json +115 -5
- package/dist/archetype.d.ts +0 -108
- package/dist/archetype.d.ts.map +0 -1
- package/dist/component.d.ts +0 -45
- package/dist/component.d.ts.map +0 -1
- package/dist/ecs.d.ts +0 -104
- package/dist/ecs.d.ts.map +0 -1
- package/dist/entity.d.ts +0 -11
- package/dist/entity.d.ts.map +0 -1
- package/dist/event.d.ts +0 -30
- package/dist/event.d.ts.map +0 -1
- package/dist/query.d.ts +0 -94
- package/dist/query.d.ts.map +0 -1
- package/dist/ref.d.ts +0 -23
- package/dist/ref.d.ts.map +0 -1
- package/dist/resource.d.ts +0 -23
- package/dist/resource.d.ts.map +0 -1
- package/dist/schedule.d.ts +0 -45
- package/dist/schedule.d.ts.map +0 -1
- package/dist/store.d.ts +0 -118
- package/dist/store.d.ts.map +0 -1
- package/dist/system.d.ts +0 -16
- package/dist/system.d.ts.map +0 -1
- package/dist/utils/arrays.d.ts.map +0 -1
- package/dist/utils/constants.d.ts.map +0 -1
- /package/dist/{utils/constants.d.ts → core/ecs/utils/constants.d.cts} +0 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { BitSet } from '../../type_primitives/index.js';
|
|
2
|
+
import { Archetype, ArchetypeColumnLayout, ArchetypeID } from './archetype.js';
|
|
3
|
+
import { ComponentID } from './component.js';
|
|
4
|
+
import { ComponentMeta } from './store.js';
|
|
5
|
+
import { ArchetypeSpec } from '../store/index.js';
|
|
6
|
+
/** What the graph needs from `Store` — closure-injected. `extendStore` and
|
|
7
|
+
* `materialize` bind the storage lifecycle (SAB extend + column-store views
|
|
8
|
+
* + grow handler) on the Store side; `fanIntoQueries` binds query-registry
|
|
9
|
+
* state. All are creation-path only — never called on an edge-cache hit. */
|
|
10
|
+
export interface ArchetypeGraphHost {
|
|
11
|
+
/** Component field metadata, indexed by ComponentID — for building a new
|
|
12
|
+
* archetype's column layouts. */
|
|
13
|
+
readonly componentMetas: () => readonly ComponentMeta[];
|
|
14
|
+
/** Row capacity for a new archetype's column region. */
|
|
15
|
+
readonly initialCapacity: () => number;
|
|
16
|
+
/** Extend the SAB with the new archetypes' column regions (one call for
|
|
17
|
+
* the whole batch — the bulk path's O(N²)→O(N) win, #213). */
|
|
18
|
+
readonly extendStore: (specs: ArchetypeSpec[]) => void;
|
|
19
|
+
/** Materialise the `Archetype` over the live column store and attach the
|
|
20
|
+
* store's grow handler. */
|
|
21
|
+
readonly materialize: (id: ArchetypeID, ownedMask: BitSet, layouts: ArchetypeColumnLayout[]) => Archetype;
|
|
22
|
+
/** Push a newly-installed archetype into every registered query whose
|
|
23
|
+
* masks it satisfies. */
|
|
24
|
+
readonly fanIntoQueries: (archetype: Archetype) => void;
|
|
25
|
+
}
|
|
26
|
+
export declare class ArchetypeGraph {
|
|
27
|
+
/** All archetypes, indexed by `ArchetypeID` (ids are minted monotonically
|
|
28
|
+
* and never removed). Store's flush loops hoist this array to a local. */
|
|
29
|
+
readonly archetypes: Archetype[];
|
|
30
|
+
/** Inverted index: ComponentID → ascending list of ArchetypeIDs that contain
|
|
31
|
+
* that component. Indexed POSITIONALLY by component id (a small, dense id
|
|
32
|
+
* space, 0..STORE_DESCRIPTOR_COMPONENT_LIMIT-1), so a lookup is an array
|
|
33
|
+
* index, not a Map hash. Used by `getMatchingArchetypes` to start the
|
|
34
|
+
* superset scan from the smallest bucket. Each bucket is a plain push-only
|
|
35
|
+
* array — NOT a Set — and deliberately does NOT dedup: a (component,
|
|
36
|
+
* archetype) pair can be inserted here at most once (see the "no duplicate
|
|
37
|
+
* pair" invariant on `install` + ADR-0015), so there is nothing for a Set
|
|
38
|
+
* to collapse. Archetypes are never removed from a Store, so buckets only
|
|
39
|
+
* grow, in ascending archetype-id order — which is canonical order,
|
|
40
|
+
* exploited by `_forEachChangedArchetype` to skip a sort. */
|
|
41
|
+
readonly componentIndex: ArchetypeID[][];
|
|
42
|
+
private readonly archetypeMap;
|
|
43
|
+
private nextArchetypeId;
|
|
44
|
+
private readonly host;
|
|
45
|
+
constructor(host: ArchetypeGraphHost);
|
|
46
|
+
get(id: ArchetypeID): Archetype;
|
|
47
|
+
/**
|
|
48
|
+
* Find or create an archetype for the given component mask.
|
|
49
|
+
* Also updates the componentIndex and pushes into matching registered queries.
|
|
50
|
+
*
|
|
51
|
+
* Hot single-mask path. The bulk batched variant — used by Phase C
|
|
52
|
+
* pre-warming at `ecs.startup()` — is `createManyFromMasks`;
|
|
53
|
+
* see #213 / `ECS.startup()` for how it gets called and why.
|
|
54
|
+
*/
|
|
55
|
+
getOrCreateFromMask(mask: BitSet): ArchetypeID;
|
|
56
|
+
/**
|
|
57
|
+
* Bulk variant of `getOrCreateFromMask` — Phase C of issue #213.
|
|
58
|
+
*
|
|
59
|
+
* Given a set of masks, creates Archetypes for the ones not already
|
|
60
|
+
* planted, in a SINGLE `extendColumnStore` call (instead of one per
|
|
61
|
+
* archetype). Single-mask creation is O(N) in archetypes-so-far because
|
|
62
|
+
* the extend has to copy every existing archetype's live rows forward;
|
|
63
|
+
* N such calls compound to O(N²). Batching collapses the per-archetype
|
|
64
|
+
* setup-and-copy down to one pass — the per-startup cost the design doc
|
|
65
|
+
* §5.2 calls out as "O(N²) → O(N)" for in-tree systems whose archetype
|
|
66
|
+
* set is known at registration time via `spawns` + `transitions`.
|
|
67
|
+
*
|
|
68
|
+
* Masks already in the map are skipped. Returns the resolved
|
|
69
|
+
* `ArchetypeID` per input mask in input order — callers that don't need
|
|
70
|
+
* the ids can ignore the return value.
|
|
71
|
+
*/
|
|
72
|
+
createManyFromMasks(masks: readonly BitSet[]): ArchetypeID[];
|
|
73
|
+
/** Hash-bucketed mask → ArchetypeID lookup; null when the mask isn't planted. */
|
|
74
|
+
private lookup;
|
|
75
|
+
/** Walk the mask's set bits and resolve each non-tag component to its
|
|
76
|
+
* layout. Used by both single and bulk archetype-create paths. */
|
|
77
|
+
private buildLayouts;
|
|
78
|
+
/** Materialise the `Archetype` for `id` (via the host, which binds the
|
|
79
|
+
* live column store + grow handler), register in the archetype map +
|
|
80
|
+
* component index, and fan into any matching registered queries.
|
|
81
|
+
*
|
|
82
|
+
* Clones `mask` before storing — callers may pass scratch BitSets that
|
|
83
|
+
* they intend to reuse (e.g. `addComponents` / `removeComponents`'s
|
|
84
|
+
* `_scratchTargetMask`). The Archetype and the archetypeMap bucket
|
|
85
|
+
* both keep references long-term, so the clone is required for
|
|
86
|
+
* correctness — and is the previously-implicit guarantee made by the
|
|
87
|
+
* mask-allocating callers (`copyWithSet`, `copyWithClear`, etc.). */
|
|
88
|
+
private install;
|
|
89
|
+
/** Resolve "add component_id to archetype_id" → target ArchetypeID. Caches the edge. */
|
|
90
|
+
resolveAdd(archetypeId: ArchetypeID, componentId: ComponentID): ArchetypeID;
|
|
91
|
+
/** Resolve "remove component_id from archetype_id" → target ArchetypeID. Caches the edge. */
|
|
92
|
+
resolveRemove(archetypeId: ArchetypeID, componentId: ComponentID): ArchetypeID;
|
|
93
|
+
/** Cache a bidirectional add/remove edge between two archetypes. */
|
|
94
|
+
private cacheEdge;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=archetype_graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archetype_graph.d.ts","sourceRoot":"","sources":["../../../src/core/ecs/archetype_graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,MAAM,EAAsB,MAAM,uBAAuB,CAAC;AACnE,OAAO,EACN,SAAS,EAGT,KAAK,qBAAqB,EAE1B,KAAK,WAAW,EAChB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAG7C,OAAO,EAGN,KAAK,aAAa,EAElB,MAAM,UAAU,CAAC;AAGlB;;;4EAG4E;AAC5E,MAAM,WAAW,kBAAkB;IAClC;qCACiC;IACjC,QAAQ,CAAC,cAAc,EAAE,MAAM,SAAS,aAAa,EAAE,CAAC;IACxD,wDAAwD;IACxD,QAAQ,CAAC,eAAe,EAAE,MAAM,MAAM,CAAC;IACvC;kEAC8D;IAC9D,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;IACvD;+BAC2B;IAC3B,QAAQ,CAAC,WAAW,EAAE,CACrB,EAAE,EAAE,WAAW,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,qBAAqB,EAAE,KAC5B,SAAS,CAAC;IACf;6BACyB;IACzB,QAAQ,CAAC,cAAc,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAC;CACxD;AAED,qBAAa,cAAc;IAC1B;8EAC0E;IAC1E,SAAgB,UAAU,EAAE,SAAS,EAAE,CAAM;IAC7C;;;;;;;;;;iEAU6D;IAC7D,SAAgB,cAAc,EAAE,WAAW,EAAE,EAAE,CAAM;IAErD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyC;IACtE,OAAO,CAAC,eAAe,CAAK;IAE5B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;gBAE9B,IAAI,EAAE,kBAAkB;IAI7B,GAAG,CAAC,EAAE,EAAE,WAAW,GAAG,SAAS;IAStC;;;;;;;OAOG;IACI,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW;IAkBrD;;;;;;;;;;;;;;;OAeG;IACI,mBAAmB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,WAAW,EAAE;IA4DnE,iFAAiF;IACjF,OAAO,CAAC,MAAM;IASd;sEACkE;IAClE,OAAO,CAAC,YAAY;IAkBpB;;;;;;;;;yEASqE;IACrE,OAAO,CAAC,OAAO;IA0Df,wFAAwF;IACjF,UAAU,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,GAAG,WAAW;IAYlF,6FAA6F;IACtF,aAAa,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,GAAG,WAAW;IAYrF,oEAAoE;IACpE,OAAO,CAAC,SAAS;CAuBjB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ECS } from './ecs.cjs';
|
|
2
|
+
import { OnDeleteTarget, RelationDef } from './relation.cjs';
|
|
3
|
+
/** Options for a built-in relation. `exclusive` / `multi` are fixed (always
|
|
4
|
+
* exclusive — required for the chain/tree traversal helpers), so only the
|
|
5
|
+
* target-deletion cleanup policy is tunable. */
|
|
6
|
+
export interface BuiltinRelationOptions {
|
|
7
|
+
/** What happens to a relation's sources when a target is destroyed.
|
|
8
|
+
* Defaults per relation (see each registrar). */
|
|
9
|
+
readonly onDeleteTarget?: OnDeleteTarget;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Register an **`IsA(instance → exemplar)`** relation — a thin instance-of link.
|
|
13
|
+
*
|
|
14
|
+
* - "all instances of exemplar E" is `ecs.relations.sourcesOf(E, IsA)`.
|
|
15
|
+
* - the IsA chain (`instance → exemplar → …`) is walked with
|
|
16
|
+
* `ecs.relations.ancestorsOf(instance, IsA)` / `rootOf` / `cascadeOf(exemplar, IsA)`.
|
|
17
|
+
* - **No component inheritance** — IsA records the link only; materialization of
|
|
18
|
+
* an instance from its exemplar stays a spawn-time copy (the template path,
|
|
19
|
+
* #462), deliberately decoupled (#477 / #478). An exemplar is a real entity,
|
|
20
|
+
* not a `Template` (a non-entity template can't be a relation target).
|
|
21
|
+
*
|
|
22
|
+
* Default `onDeleteTarget: "clear"` — destroying an exemplar drops its
|
|
23
|
+
* instances' IsA link but leaves the instances alive (the thin analog of
|
|
24
|
+
* flecs's `IsA`-remove, since there is no inherited data to strip). Pass
|
|
25
|
+
* `"delete"` for strong instance-of (exemplar death cascade-destroys instances).
|
|
26
|
+
*/
|
|
27
|
+
export declare function registerIsA(ecs: ECS, opts?: BuiltinRelationOptions): RelationDef<"exclusive">;
|
|
28
|
+
/**
|
|
29
|
+
* Register a **`ChildOf(child → parent)`** relation — a thin hierarchy link.
|
|
30
|
+
*
|
|
31
|
+
* - a parent's children are `ecs.relations.sourcesOf(parent, ChildOf)`.
|
|
32
|
+
* - the hierarchy is walked with `ecs.relations.ancestorsOf(child, ChildOf)` (up to the
|
|
33
|
+
* root), `rootOf`, and `cascadeOf(root, ChildOf)` (down, breadth-first,
|
|
34
|
+
* parents before children).
|
|
35
|
+
* - unlike flecs's `ChildOf`, this does **not** scope names/lookup — the engine
|
|
36
|
+
* has no name registry; it is purely the structural parent link.
|
|
37
|
+
*
|
|
38
|
+
* Default `onDeleteTarget: "delete"` — destroying a parent cascade-destroys
|
|
39
|
+
* its whole subtree (flecs's default). Pass `"clear"` to let children survive as
|
|
40
|
+
* roots, or `"orphan"` to leave a dangling `targetOf`.
|
|
41
|
+
*/
|
|
42
|
+
export declare function registerChildOf(ecs: ECS, opts?: BuiltinRelationOptions): RelationDef<"exclusive">;
|
|
43
|
+
//# sourceMappingURL=builtin_relations.d.ts.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ECS } from './ecs.js';
|
|
2
|
+
import { OnDeleteTarget, RelationDef } from './relation.js';
|
|
3
|
+
/** Options for a built-in relation. `exclusive` / `multi` are fixed (always
|
|
4
|
+
* exclusive — required for the chain/tree traversal helpers), so only the
|
|
5
|
+
* target-deletion cleanup policy is tunable. */
|
|
6
|
+
export interface BuiltinRelationOptions {
|
|
7
|
+
/** What happens to a relation's sources when a target is destroyed.
|
|
8
|
+
* Defaults per relation (see each registrar). */
|
|
9
|
+
readonly onDeleteTarget?: OnDeleteTarget;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Register an **`IsA(instance → exemplar)`** relation — a thin instance-of link.
|
|
13
|
+
*
|
|
14
|
+
* - "all instances of exemplar E" is `ecs.relations.sourcesOf(E, IsA)`.
|
|
15
|
+
* - the IsA chain (`instance → exemplar → …`) is walked with
|
|
16
|
+
* `ecs.relations.ancestorsOf(instance, IsA)` / `rootOf` / `cascadeOf(exemplar, IsA)`.
|
|
17
|
+
* - **No component inheritance** — IsA records the link only; materialization of
|
|
18
|
+
* an instance from its exemplar stays a spawn-time copy (the template path,
|
|
19
|
+
* #462), deliberately decoupled (#477 / #478). An exemplar is a real entity,
|
|
20
|
+
* not a `Template` (a non-entity template can't be a relation target).
|
|
21
|
+
*
|
|
22
|
+
* Default `onDeleteTarget: "clear"` — destroying an exemplar drops its
|
|
23
|
+
* instances' IsA link but leaves the instances alive (the thin analog of
|
|
24
|
+
* flecs's `IsA`-remove, since there is no inherited data to strip). Pass
|
|
25
|
+
* `"delete"` for strong instance-of (exemplar death cascade-destroys instances).
|
|
26
|
+
*/
|
|
27
|
+
export declare function registerIsA(ecs: ECS, opts?: BuiltinRelationOptions): RelationDef<"exclusive">;
|
|
28
|
+
/**
|
|
29
|
+
* Register a **`ChildOf(child → parent)`** relation — a thin hierarchy link.
|
|
30
|
+
*
|
|
31
|
+
* - a parent's children are `ecs.relations.sourcesOf(parent, ChildOf)`.
|
|
32
|
+
* - the hierarchy is walked with `ecs.relations.ancestorsOf(child, ChildOf)` (up to the
|
|
33
|
+
* root), `rootOf`, and `cascadeOf(root, ChildOf)` (down, breadth-first,
|
|
34
|
+
* parents before children).
|
|
35
|
+
* - unlike flecs's `ChildOf`, this does **not** scope names/lookup — the engine
|
|
36
|
+
* has no name registry; it is purely the structural parent link.
|
|
37
|
+
*
|
|
38
|
+
* Default `onDeleteTarget: "delete"` — destroying a parent cascade-destroys
|
|
39
|
+
* its whole subtree (flecs's default). Pass `"clear"` to let children survive as
|
|
40
|
+
* roots, or `"orphan"` to leave a dangling `targetOf`.
|
|
41
|
+
*/
|
|
42
|
+
export declare function registerChildOf(ecs: ECS, opts?: BuiltinRelationOptions): RelationDef<"exclusive">;
|
|
43
|
+
//# sourceMappingURL=builtin_relations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtin_relations.d.ts","sourceRoot":"","sources":["../../../src/core/ecs/builtin_relations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;KAsBK;AAEL,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9D;;gDAEgD;AAChD,MAAM,WAAW,sBAAsB;IACtC;qDACiD;IACjD,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;CACzC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,sBAAsB,GAAG,WAAW,CAAC,WAAW,CAAC,CAK7F;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,sBAAsB,GAAG,WAAW,CAAC,WAAW,CAAC,CAKjG"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { ECS } from './ecs.cjs';
|
|
2
|
+
import { HostCommand, HostCommandQueue, HostCommandSink } from './host_commands.cjs';
|
|
3
|
+
/** One recorded update tick: the commands the apply system drained at this
|
|
4
|
+
* tick's update-phase head, plus the `dt` passed to `ecs.update(dt)`. Replay
|
|
5
|
+
* MUST re-issue `update(dt)` for every recorded tick — even an empty one — since
|
|
6
|
+
* `dt` itself drives the sim (movement, timers), not just the commands. */
|
|
7
|
+
export interface RecordedTick {
|
|
8
|
+
/** The ECS tick (`ctx.ecsTick`) this bucket belongs to. */
|
|
9
|
+
readonly tick: number;
|
|
10
|
+
/** The `dt` `ecs.update(dt)` was called with for this tick. */
|
|
11
|
+
readonly dt: number;
|
|
12
|
+
/** Commands applied this tick, in apply order (typed queue first, then ring),
|
|
13
|
+
* `onSpawned` stripped. */
|
|
14
|
+
readonly commands: readonly HostCommand[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A recorded session: the `seed` it ran under, the seed-time commands drained at
|
|
18
|
+
* startup, and the per-tick command stream. Plain, serializable data — the
|
|
19
|
+
* record-side mirror of the typed `HostCommand` vocabulary. Replay it with
|
|
20
|
+
* {@link replayCommandLog}; persist it with {@link serializeCommandLog}.
|
|
21
|
+
*/
|
|
22
|
+
export interface CommandLog {
|
|
23
|
+
/** Session seed — the implementer's deterministic input (e.g. an RNG seed).
|
|
24
|
+
* Opaque to the engine (the core tick takes only `dt`); carried so a replay
|
|
25
|
+
* rebuilds the world the same way the original was built. */
|
|
26
|
+
readonly seed: number;
|
|
27
|
+
/** Commands drained at the PRE_STARTUP head (seed-time edits), applied before
|
|
28
|
+
* the first update tick. Enqueued BEFORE `ecs.startup()` on replay. */
|
|
29
|
+
readonly startup: readonly HostCommand[];
|
|
30
|
+
/** One entry per update tick, in order. */
|
|
31
|
+
readonly ticks: readonly RecordedTick[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The record side of record/replay: a {@link HostCommandSink} the apply system
|
|
35
|
+
* feeds. Construct one with the session `seed`, hand it to
|
|
36
|
+
* `installHostCommandSeam(world, { recorder })`, and it accumulates the
|
|
37
|
+
* command stream as the ECS ticks. Read it back with {@link log} (a live view,
|
|
38
|
+
* ready to {@link serializeCommandLog serialize}).
|
|
39
|
+
*
|
|
40
|
+
* Bucketing: STARTUP-phase drains (which never call {@link openTick}) append to
|
|
41
|
+
* the {@link startup} bucket; each update-phase drain {@link openTick}s its tick
|
|
42
|
+
* — multiple update-phase drains in one tick reuse the same bucket (keyed by the
|
|
43
|
+
* ECS tick), so a frame's commands stay together. The apply system runs every
|
|
44
|
+
* tick, so every tick's `dt` is recorded even when no commands were applied.
|
|
45
|
+
*
|
|
46
|
+
* One recorder per session — don't share across worlds.
|
|
47
|
+
*/
|
|
48
|
+
export declare class HostCommandRecorder implements HostCommandSink {
|
|
49
|
+
/** Session seed, echoed into the produced {@link CommandLog}. */
|
|
50
|
+
readonly seed: number;
|
|
51
|
+
private readonly _startup;
|
|
52
|
+
private readonly _ticks;
|
|
53
|
+
/** Where {@link record} appends. Defaults to the startup bucket (seed-time
|
|
54
|
+
* drains happen before any `openTick`); each `openTick` repoints it. */
|
|
55
|
+
private sink;
|
|
56
|
+
constructor(seed?: number);
|
|
57
|
+
openTick(tick: number, dt: number): void;
|
|
58
|
+
readonly record: (cmd: HostCommand) => void;
|
|
59
|
+
/** A live {@link CommandLog} view over the accumulated stream — not a copy.
|
|
60
|
+
* Serialize it (which deep-copies through JSON) before mutating the world
|
|
61
|
+
* further if you need a stable snapshot, or use {@link snapshotLog}. */
|
|
62
|
+
log(): CommandLog;
|
|
63
|
+
/** A STABLE deep copy of the accumulated stream — safe to hold across
|
|
64
|
+
* further recording (the safe default; `log()` is the zero-copy live view). */
|
|
65
|
+
snapshotLog(): CommandLog;
|
|
66
|
+
}
|
|
67
|
+
/** Serialize a {@link CommandLog} to a JSON string. `EntityID` is a plain number
|
|
68
|
+
* and round-trips as-is; a `ComponentDef` is a callable, so the replacer writes
|
|
69
|
+
* it as `{ [DEF_TAG]: id }`. (The recorder already stripped `onSpawned`, the
|
|
70
|
+
* only other non-serializable member.)
|
|
71
|
+
*
|
|
72
|
+
* Throws {@link ECS_ERROR.COMMAND_LOG_TAG_COLLISION} if any non-def object in the
|
|
73
|
+
* log (i.e. a command's `values` map) owns a field named {@link DEF_TAG}: the
|
|
74
|
+
* reviver tags defs in-band, so such a value would be silently revived as a def,
|
|
75
|
+
* dropping the real field data. Field names are arbitrary, so this is reachable;
|
|
76
|
+
* failing here keeps the round-trip lossless instead of corrupting on parse. */
|
|
77
|
+
export declare function serializeCommandLog(log: CommandLog): string;
|
|
78
|
+
/** Parse a {@link CommandLog} from {@link serializeCommandLog} output. */
|
|
79
|
+
export declare function deserializeCommandLog(json: string): CommandLog;
|
|
80
|
+
/** Outcome of {@link replayCommandLog}. */
|
|
81
|
+
export interface ReplayResult {
|
|
82
|
+
/** Seed-time commands re-applied before the first tick. */
|
|
83
|
+
readonly startupCommands: number;
|
|
84
|
+
/** Update ticks replayed. */
|
|
85
|
+
readonly ticks: number;
|
|
86
|
+
/** Per-tick `stateHash` captured after each `update`, in tick order — empty
|
|
87
|
+
* unless the world is deterministic (or `hash` was forced). Compare against
|
|
88
|
+
* the original run's per-tick hashes to prove the replay matched (ADR-0020). */
|
|
89
|
+
readonly stateHashes: readonly number[];
|
|
90
|
+
}
|
|
91
|
+
/** Options for {@link replayCommandLog}. */
|
|
92
|
+
export interface ReplayOptions {
|
|
93
|
+
/** Capture `ecs.snapshots.stateHash()` after each tick. Defaults to the world's
|
|
94
|
+
* `deterministic` flag — a deterministic world is hashed, a non-deterministic
|
|
95
|
+
* one is not (its `stateHash` would throw, ADR-0020). Force `true` only on a
|
|
96
|
+
* deterministic world. */
|
|
97
|
+
readonly hash?: boolean;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Replay a recorded {@link CommandLog} against `world`, reproducing the original
|
|
101
|
+
* session tick-for-tick. `world` must be FRESH and NOT yet started, built
|
|
102
|
+
* identically to the recorded run (same components registered in the same order,
|
|
103
|
+
* same systems, same `seed` from `log.seed`) and seam-installed — pass the
|
|
104
|
+
* `HostCommandQueue` `installHostCommandSeam` returned as `queue`. The driver
|
|
105
|
+
* owns startup: it enqueues the seed-time commands, calls `ecs.startup()`
|
|
106
|
+
* (which drains them at PRE_STARTUP), then for each recorded tick enqueues that
|
|
107
|
+
* tick's commands and calls `ecs.update(dt)` with the recorded `dt`.
|
|
108
|
+
*
|
|
109
|
+
* Determinism (ADR-0020): with `{ deterministic: true }` the per-tick
|
|
110
|
+
* `stateHashes` this returns must equal the original run's — that equality is
|
|
111
|
+
* replay fidelity. Identity caveat (§85): a despawned-then-respawned entity gets
|
|
112
|
+
* a fresh id, but because spawn order is reproduced, every recorded id still
|
|
113
|
+
* resolves to the same entity on replay.
|
|
114
|
+
*/
|
|
115
|
+
export declare function replayCommandLog(ecs: ECS, queue: HostCommandQueue, log: CommandLog, opts?: ReplayOptions): ReplayResult;
|
|
116
|
+
//# sourceMappingURL=command_log.d.ts.map
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { ECS } from './ecs.js';
|
|
2
|
+
import { HostCommand, HostCommandQueue, HostCommandSink } from './host_commands.js';
|
|
3
|
+
/** One recorded update tick: the commands the apply system drained at this
|
|
4
|
+
* tick's update-phase head, plus the `dt` passed to `ecs.update(dt)`. Replay
|
|
5
|
+
* MUST re-issue `update(dt)` for every recorded tick — even an empty one — since
|
|
6
|
+
* `dt` itself drives the sim (movement, timers), not just the commands. */
|
|
7
|
+
export interface RecordedTick {
|
|
8
|
+
/** The ECS tick (`ctx.ecsTick`) this bucket belongs to. */
|
|
9
|
+
readonly tick: number;
|
|
10
|
+
/** The `dt` `ecs.update(dt)` was called with for this tick. */
|
|
11
|
+
readonly dt: number;
|
|
12
|
+
/** Commands applied this tick, in apply order (typed queue first, then ring),
|
|
13
|
+
* `onSpawned` stripped. */
|
|
14
|
+
readonly commands: readonly HostCommand[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A recorded session: the `seed` it ran under, the seed-time commands drained at
|
|
18
|
+
* startup, and the per-tick command stream. Plain, serializable data — the
|
|
19
|
+
* record-side mirror of the typed `HostCommand` vocabulary. Replay it with
|
|
20
|
+
* {@link replayCommandLog}; persist it with {@link serializeCommandLog}.
|
|
21
|
+
*/
|
|
22
|
+
export interface CommandLog {
|
|
23
|
+
/** Session seed — the implementer's deterministic input (e.g. an RNG seed).
|
|
24
|
+
* Opaque to the engine (the core tick takes only `dt`); carried so a replay
|
|
25
|
+
* rebuilds the world the same way the original was built. */
|
|
26
|
+
readonly seed: number;
|
|
27
|
+
/** Commands drained at the PRE_STARTUP head (seed-time edits), applied before
|
|
28
|
+
* the first update tick. Enqueued BEFORE `ecs.startup()` on replay. */
|
|
29
|
+
readonly startup: readonly HostCommand[];
|
|
30
|
+
/** One entry per update tick, in order. */
|
|
31
|
+
readonly ticks: readonly RecordedTick[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The record side of record/replay: a {@link HostCommandSink} the apply system
|
|
35
|
+
* feeds. Construct one with the session `seed`, hand it to
|
|
36
|
+
* `installHostCommandSeam(world, { recorder })`, and it accumulates the
|
|
37
|
+
* command stream as the ECS ticks. Read it back with {@link log} (a live view,
|
|
38
|
+
* ready to {@link serializeCommandLog serialize}).
|
|
39
|
+
*
|
|
40
|
+
* Bucketing: STARTUP-phase drains (which never call {@link openTick}) append to
|
|
41
|
+
* the {@link startup} bucket; each update-phase drain {@link openTick}s its tick
|
|
42
|
+
* — multiple update-phase drains in one tick reuse the same bucket (keyed by the
|
|
43
|
+
* ECS tick), so a frame's commands stay together. The apply system runs every
|
|
44
|
+
* tick, so every tick's `dt` is recorded even when no commands were applied.
|
|
45
|
+
*
|
|
46
|
+
* One recorder per session — don't share across worlds.
|
|
47
|
+
*/
|
|
48
|
+
export declare class HostCommandRecorder implements HostCommandSink {
|
|
49
|
+
/** Session seed, echoed into the produced {@link CommandLog}. */
|
|
50
|
+
readonly seed: number;
|
|
51
|
+
private readonly _startup;
|
|
52
|
+
private readonly _ticks;
|
|
53
|
+
/** Where {@link record} appends. Defaults to the startup bucket (seed-time
|
|
54
|
+
* drains happen before any `openTick`); each `openTick` repoints it. */
|
|
55
|
+
private sink;
|
|
56
|
+
constructor(seed?: number);
|
|
57
|
+
openTick(tick: number, dt: number): void;
|
|
58
|
+
readonly record: (cmd: HostCommand) => void;
|
|
59
|
+
/** A live {@link CommandLog} view over the accumulated stream — not a copy.
|
|
60
|
+
* Serialize it (which deep-copies through JSON) before mutating the world
|
|
61
|
+
* further if you need a stable snapshot, or use {@link snapshotLog}. */
|
|
62
|
+
log(): CommandLog;
|
|
63
|
+
/** A STABLE deep copy of the accumulated stream — safe to hold across
|
|
64
|
+
* further recording (the safe default; `log()` is the zero-copy live view). */
|
|
65
|
+
snapshotLog(): CommandLog;
|
|
66
|
+
}
|
|
67
|
+
/** Serialize a {@link CommandLog} to a JSON string. `EntityID` is a plain number
|
|
68
|
+
* and round-trips as-is; a `ComponentDef` is a callable, so the replacer writes
|
|
69
|
+
* it as `{ [DEF_TAG]: id }`. (The recorder already stripped `onSpawned`, the
|
|
70
|
+
* only other non-serializable member.)
|
|
71
|
+
*
|
|
72
|
+
* Throws {@link ECS_ERROR.COMMAND_LOG_TAG_COLLISION} if any non-def object in the
|
|
73
|
+
* log (i.e. a command's `values` map) owns a field named {@link DEF_TAG}: the
|
|
74
|
+
* reviver tags defs in-band, so such a value would be silently revived as a def,
|
|
75
|
+
* dropping the real field data. Field names are arbitrary, so this is reachable;
|
|
76
|
+
* failing here keeps the round-trip lossless instead of corrupting on parse. */
|
|
77
|
+
export declare function serializeCommandLog(log: CommandLog): string;
|
|
78
|
+
/** Parse a {@link CommandLog} from {@link serializeCommandLog} output. */
|
|
79
|
+
export declare function deserializeCommandLog(json: string): CommandLog;
|
|
80
|
+
/** Outcome of {@link replayCommandLog}. */
|
|
81
|
+
export interface ReplayResult {
|
|
82
|
+
/** Seed-time commands re-applied before the first tick. */
|
|
83
|
+
readonly startupCommands: number;
|
|
84
|
+
/** Update ticks replayed. */
|
|
85
|
+
readonly ticks: number;
|
|
86
|
+
/** Per-tick `stateHash` captured after each `update`, in tick order — empty
|
|
87
|
+
* unless the world is deterministic (or `hash` was forced). Compare against
|
|
88
|
+
* the original run's per-tick hashes to prove the replay matched (ADR-0020). */
|
|
89
|
+
readonly stateHashes: readonly number[];
|
|
90
|
+
}
|
|
91
|
+
/** Options for {@link replayCommandLog}. */
|
|
92
|
+
export interface ReplayOptions {
|
|
93
|
+
/** Capture `ecs.snapshots.stateHash()` after each tick. Defaults to the world's
|
|
94
|
+
* `deterministic` flag — a deterministic world is hashed, a non-deterministic
|
|
95
|
+
* one is not (its `stateHash` would throw, ADR-0020). Force `true` only on a
|
|
96
|
+
* deterministic world. */
|
|
97
|
+
readonly hash?: boolean;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Replay a recorded {@link CommandLog} against `world`, reproducing the original
|
|
101
|
+
* session tick-for-tick. `world` must be FRESH and NOT yet started, built
|
|
102
|
+
* identically to the recorded run (same components registered in the same order,
|
|
103
|
+
* same systems, same `seed` from `log.seed`) and seam-installed — pass the
|
|
104
|
+
* `HostCommandQueue` `installHostCommandSeam` returned as `queue`. The driver
|
|
105
|
+
* owns startup: it enqueues the seed-time commands, calls `ecs.startup()`
|
|
106
|
+
* (which drains them at PRE_STARTUP), then for each recorded tick enqueues that
|
|
107
|
+
* tick's commands and calls `ecs.update(dt)` with the recorded `dt`.
|
|
108
|
+
*
|
|
109
|
+
* Determinism (ADR-0020): with `{ deterministic: true }` the per-tick
|
|
110
|
+
* `stateHashes` this returns must equal the original run's — that equality is
|
|
111
|
+
* replay fidelity. Identity caveat (§85): a despawned-then-respawned entity gets
|
|
112
|
+
* a fresh id, but because spawn order is reproduced, every recorded id still
|
|
113
|
+
* resolves to the same entity on replay.
|
|
114
|
+
*/
|
|
115
|
+
export declare function replayCommandLog(ecs: ECS, queue: HostCommandQueue, log: CommandLog, opts?: ReplayOptions): ReplayResult;
|
|
116
|
+
//# sourceMappingURL=command_log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command_log.d.ts","sourceRoot":"","sources":["../../../src/core/ecs/command_log.ts"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEtF;;;2EAG2E;AAC3E,MAAM,WAAW,YAAY;IAC5B,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;+BAC2B;IAC3B,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;CAC1C;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IAC1B;;iEAE6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;2EACuE;IACvE,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;CACxC;AAiBD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,mBAAoB,YAAW,eAAe;IAC1D,iEAAiE;IACjE,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C;4EACwE;IACxE,OAAO,CAAC,IAAI,CAAgC;gBAEhC,IAAI,SAAI;IAIpB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAaxC,QAAQ,CAAC,MAAM,QAAS,WAAW,KAAG,IAAI,CAExC;IAEF;;4EAEwE;IACxE,GAAG,IAAI,UAAU;IAIjB;mFAC+E;IAC/E,WAAW,IAAI,UAAU;CAOzB;AAYD;;;;;;;;;gFASgF;AAChF,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAqB3D;AAED,0EAA0E;AAC1E,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAW9D;AAED,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IAC5B,2DAA2D;IAC3D,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,6BAA6B;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;oFAEgF;IAChF,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED,4CAA4C;AAC5C,MAAM,WAAW,aAAa;IAC7B;;;8BAG0B;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC/B,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,gBAAgB,EACvB,GAAG,EAAE,UAAU,EACf,IAAI,CAAC,EAAE,aAAa,GAClB,YAAY,CAcd"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { Brand, TypedArrayTag } from '../../type_primitives/index.cjs';
|
|
2
|
+
export type ComponentID = Brand<number, "component_id">;
|
|
3
|
+
export declare const asComponentId: (value: number) => ComponentID;
|
|
4
|
+
/** Core schema type: maps field names to typed array tags. */
|
|
5
|
+
export type ComponentSchema = Readonly<Record<string, TypedArrayTag>>;
|
|
6
|
+
/** Compile-time tag → TypedArray mapping. */
|
|
7
|
+
export type TagToTypedArray = {
|
|
8
|
+
f32: Float32Array;
|
|
9
|
+
f64: Float64Array;
|
|
10
|
+
i8: Int8Array;
|
|
11
|
+
i16: Int16Array;
|
|
12
|
+
i32: Int32Array;
|
|
13
|
+
u8: Uint8Array;
|
|
14
|
+
u16: Uint16Array;
|
|
15
|
+
u32: Uint32Array;
|
|
16
|
+
};
|
|
17
|
+
/** Maps schema fields to their value object: { x: number, y: number }. */
|
|
18
|
+
export type FieldValues<S extends ComponentSchema> = {
|
|
19
|
+
readonly [K in keyof S]: number;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Values argument tuple for attaching a component of schema `S` — empty for a
|
|
23
|
+
* tag, a single optional partial-values map otherwise. A tag schema
|
|
24
|
+
* (`Record<string, never>`) would otherwise degenerate: `keyof` an
|
|
25
|
+
* index-signature record is `string`, so `Partial<FieldValues<…>>` collapses to
|
|
26
|
+
* `Record<string, number>` and `Frozen({ anything: 1 })` compiles. The
|
|
27
|
+
* conditional forbids values on tags outright; a schema-erased `ComponentDef`
|
|
28
|
+
* falls into the valued branch, so untyped call sites keep the loose shape.
|
|
29
|
+
*/
|
|
30
|
+
export type ValuesArg<S extends ComponentSchema> = S extends Record<string, never> ? [] : [values?: Partial<FieldValues<S>>];
|
|
31
|
+
/**
|
|
32
|
+
* `FieldValues` for APIs where the values object is required and complete
|
|
33
|
+
* (`addComponent`'s valued overload, the host-seam `SpawnEntry`). Guards the
|
|
34
|
+
* same tag degeneracy as `ValuesArg`: a tag accepts only the empty object
|
|
35
|
+
* (`Record<string, never>` — every property typed `never`), so
|
|
36
|
+
* `addComponent(e, Frozen, { x: 1 })` is a compile error while the
|
|
37
|
+
* tag-overload-less call sites can still pass `{}`.
|
|
38
|
+
*/
|
|
39
|
+
export type CompleteFieldValues<S extends ComponentSchema> = S extends Record<string, never> ? Record<string, never> : FieldValues<S>;
|
|
40
|
+
/**
|
|
41
|
+
* Trailing-argument tuple for the attach surfaces (`ctx.commands.add`'s
|
|
42
|
+
* explicit-values form, `ctx.addSparse`): a tag takes NO values argument, a valued schema REQUIRES a
|
|
43
|
+
* complete one. Encodes the former tag/valued overload pair as one signature,
|
|
44
|
+
* which the typed system seam needs — its `def` parameter is a single
|
|
45
|
+
* declared-access-constrained type param, and per-schema overloads would
|
|
46
|
+
* re-introduce the tag-vs-valued split on top of it.
|
|
47
|
+
*/
|
|
48
|
+
export type AttachValuesArg<S extends ComponentSchema> = S extends Record<string, never> ? [] : [values: CompleteFieldValues<S>];
|
|
49
|
+
/** Maps schema fields to their specific typed array columns. */
|
|
50
|
+
export type ColumnsForSchema<S extends ComponentSchema> = {
|
|
51
|
+
readonly [K in keyof S]: TagToTypedArray[S[K]];
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Mutable sibling of `ColumnsForSchema` — the field-keyed column group handed
|
|
55
|
+
* back by `eachChunk`'s `cols.mut(def)` (no `readonly`, since the whole point
|
|
56
|
+
* is in-place writes). The change-tick is stamped once when the group is
|
|
57
|
+
* resolved, so the per-row loop is plain typed-array indexing (§eachChunk).
|
|
58
|
+
*/
|
|
59
|
+
export type MutableColumnsForSchema<S extends ComponentSchema> = {
|
|
60
|
+
[K in keyof S]: TagToTypedArray[S[K]];
|
|
61
|
+
};
|
|
62
|
+
declare const __schema: unique symbol;
|
|
63
|
+
/**
|
|
64
|
+
* A component handle. **Callable**: `Pos({ x, y })` produces a `Bundle` (omitted
|
|
65
|
+
* fields zero-fill at attach), so one varargs shape — `spawn(Pos({x,y}),
|
|
66
|
+
* Vel({vx:1}), IsEnemy)` — replaces the older incompatible attach shapes. A bare
|
|
67
|
+
* `Pos` (uncalled) still stands in for a tag / all-zero values wherever a
|
|
68
|
+
* `BundleOrDef` is accepted.
|
|
69
|
+
*
|
|
70
|
+
* The numeric component id lives on `.id` (registration order). Consumers treat
|
|
71
|
+
* the def as an opaque handle; internal code reads `def.id` where it needs the
|
|
72
|
+
* raw id. The call signature's `S` makes `ComponentDef<{x:"f64"}>` distinct from
|
|
73
|
+
* `ComponentDef<{vx:"f64"}>`.
|
|
74
|
+
*
|
|
75
|
+
* The optional `[__schema]` slot never exists at runtime; it re-states `S` in a
|
|
76
|
+
* covariant tuple position so that a TAG def type is not a universal assignment
|
|
77
|
+
* sink. Through the call signature alone every def is assignable to
|
|
78
|
+
* `ComponentDef<Record<string, never>>` (the tag callable takes no required
|
|
79
|
+
* args and any `Bundle` satisfies its return), which would let ONE tag in a
|
|
80
|
+
* system's declared-access union admit every component at compile time
|
|
81
|
+
* (§typestate — `DeclaredRead` and friends in system.ts). With the slot, a
|
|
82
|
+
* valued schema is not assignable to the tag schema (`"f64" ⊀ never`), while
|
|
83
|
+
* schema erasure (`ComponentDef<S>` → bare `ComponentDef`) still works because
|
|
84
|
+
* every schema is assignable to `ComponentSchema`.
|
|
85
|
+
*
|
|
86
|
+
* Build one with `makeComponentDef`; never construct by hand.
|
|
87
|
+
*/
|
|
88
|
+
export interface ComponentDef<S extends ComponentSchema = ComponentSchema> {
|
|
89
|
+
(...values: ValuesArg<S>): Bundle<S>;
|
|
90
|
+
readonly id: ComponentID;
|
|
91
|
+
readonly [__schema]?: [S];
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Recover a def's schema type: `SchemaOf<typeof Pos>` is `{x:"f64", y:"f64"}`.
|
|
95
|
+
* The typed `SystemContext` methods (§typestate) constrain their `def`
|
|
96
|
+
* parameter to the system's declared-access union and use this to type the
|
|
97
|
+
* field argument, in place of taking `ComponentDef<S>` directly.
|
|
98
|
+
*/
|
|
99
|
+
export type SchemaOf<D> = D extends ComponentDef<infer S extends ComponentSchema> ? S : never;
|
|
100
|
+
/**
|
|
101
|
+
* `unknown` if `D` is one of the query's declared terms, else an error tuple —
|
|
102
|
+
* the query-seam sibling of system.ts's `DeclaredRead` (§typestate,
|
|
103
|
+
* POLISH_AUDIT #6). `Query.eachChunk`'s cursor and `ArchetypeView`'s column
|
|
104
|
+
* accessors intersect this into their `def` parameter so fetching a component
|
|
105
|
+
* that is NOT a term of the iterating query fails to compile (previously
|
|
106
|
+
* caught only by the dev-mode access check, and only when the system's
|
|
107
|
+
* declaration was itself wrong). Same encoding rules as the system asserts:
|
|
108
|
+
* stable `D extends ComponentDef<any>` constraints keep instantiations
|
|
109
|
+
* mutually assignable, and the conditional keys on the signature's own `D`.
|
|
110
|
+
*/
|
|
111
|
+
export type DeclaredQueryTerm<Defs extends readonly ComponentDef<any>[], D> = [D] extends [
|
|
112
|
+
Defs[number]
|
|
113
|
+
] ? unknown : ["component is not a term of this query — add it with .and(...)", D];
|
|
114
|
+
/** Options bag accepted by `registerComponent` / `registerSparseComponent`. */
|
|
115
|
+
export interface ComponentRegisterOptions {
|
|
116
|
+
/** Debug label for diagnostics — errors then read `'Pos' (component 5)`
|
|
117
|
+
* instead of `component 5`. Never affects behaviour, layout, or hashing. */
|
|
118
|
+
readonly name?: string;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Schema-erased component handle — just the `.id`. Internal, schema-agnostic
|
|
122
|
+
* code (access checks, dirty-set notes, field-id lookup) takes this instead of
|
|
123
|
+
* `ComponentDef`: the callable signature makes `ComponentDef<S>` *invariant* in
|
|
124
|
+
* `S` (a generic `ComponentDef<S>` is not assignable to `ComponentDef`), but
|
|
125
|
+
* every `ComponentDef<S>` is assignable to `ComponentHandle` because it carries
|
|
126
|
+
* `.id`. Use it wherever only the id is read.
|
|
127
|
+
*/
|
|
128
|
+
export type ComponentHandle = {
|
|
129
|
+
readonly id: ComponentID;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Mint a callable `ComponentDef` for a freshly-registered component id. The
|
|
133
|
+
* returned function produces a `Bundle` when called (`Pos({x,y})`) and carries
|
|
134
|
+
* its numeric id on a non-enumerable `.id` (invisible to spreads / `JSON`).
|
|
135
|
+
* The single cast bridges the function value to the branded handle type — the
|
|
136
|
+
* `.id` is installed at runtime by `defineProperty` (§10c branded-ID boundary).
|
|
137
|
+
*/
|
|
138
|
+
export declare function makeComponentDef<S extends ComponentSchema>(id: ComponentID): ComponentDef<S>;
|
|
139
|
+
export interface Bundle<S extends ComponentSchema = ComponentSchema> {
|
|
140
|
+
readonly def: ComponentDef<S>;
|
|
141
|
+
readonly values: Partial<FieldValues<S>>;
|
|
142
|
+
}
|
|
143
|
+
/** Either a populated bundle or a bare def (tag / all-fields-zero). */
|
|
144
|
+
export type BundleOrDef<S extends ComponentSchema = ComponentSchema> = Bundle<S> | ComponentDef<S>;
|
|
145
|
+
/** Pair a component def with field values to attach. Omitted fields zero-fill;
|
|
146
|
+
* a tag def takes no values (see `ValuesArg`). */
|
|
147
|
+
export declare function bundle<S extends ComponentSchema>(def: ComponentDef<S>, ...values: ValuesArg<S>): Bundle<S>;
|
|
148
|
+
/** Extract the def from a `BundleOrDef`. A bare def is the callable; a bundle a plain object. */
|
|
149
|
+
export declare function bundleDef(item: BundleOrDef): ComponentDef;
|
|
150
|
+
/** Extract the values from a `BundleOrDef` (a bare def contributes no values). */
|
|
151
|
+
export declare function bundleValues(item: BundleOrDef): Readonly<Record<string, number>>;
|
|
152
|
+
/**
|
|
153
|
+
* Compile-time readonly view of a typed array column. Blocks index writes at
|
|
154
|
+
* the type layer.
|
|
155
|
+
*
|
|
156
|
+
* **Advisory, not a runtime barrier:** the value behind this type is the live
|
|
157
|
+
* mutable backing `TypedArray` (`Archetype.getColumnRead` returns
|
|
158
|
+
* `.buf as unknown as ReadonlyColumn`), so a §10c-policed cast can still write
|
|
159
|
+
* through. For mutation use the mutable `Archetype.getColumn` (tick-bumping).
|
|
160
|
+
* Enforced by the escape-hatch lint, not the runtime.
|
|
161
|
+
*/
|
|
162
|
+
export interface ReadonlyColumn {
|
|
163
|
+
readonly [index: number]: number;
|
|
164
|
+
readonly length: number;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Compile-time readonly view of a Uint32Array. Blocks index writes at the type
|
|
168
|
+
* layer. **Advisory, not a runtime barrier** — same caveat as `ReadonlyColumn`:
|
|
169
|
+
* the underlying value is the live mutable buffer.
|
|
170
|
+
*/
|
|
171
|
+
export interface ReadonlyUint32Array {
|
|
172
|
+
readonly [index: number]: number;
|
|
173
|
+
readonly length: number;
|
|
174
|
+
}
|
|
175
|
+
export {};
|
|
176
|
+
//# sourceMappingURL=component.d.ts.map
|