@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,94 @@
|
|
|
1
|
+
import { Archetype } from './archetype.cjs';
|
|
2
|
+
import { EntityAllocator } from './entity_allocator.cjs';
|
|
3
|
+
import { SparseComponentStore } from './sparse_store.cjs';
|
|
4
|
+
import { RelationStore } from './relation.cjs';
|
|
5
|
+
import { ColumnStore, InPlaceBufferAllocator } from '../store/index.cjs';
|
|
6
|
+
import { HostState } from './resume.cjs';
|
|
7
|
+
/** What the snapshot/resume orchestration needs from `Store` — closure-
|
|
8
|
+
* injected (the `RelationServiceHost` style). Accessors re-read live fields
|
|
9
|
+
* per call (the column store and the entity-index views are replaced on
|
|
10
|
+
* restore); the three mutation members keep Store-owned state transitions on
|
|
11
|
+
* the Store side. All cold-path. */
|
|
12
|
+
export interface SnapshotHost {
|
|
13
|
+
readonly sparseStores: () => readonly SparseComponentStore[];
|
|
14
|
+
readonly relationStores: () => readonly RelationStore[];
|
|
15
|
+
/** Live SAB generations view (replanted on restore) — for rebuilding
|
|
16
|
+
* relation ids from entity indices. */
|
|
17
|
+
readonly generations: () => Int32Array;
|
|
18
|
+
readonly archetypes: () => readonly Archetype[];
|
|
19
|
+
readonly columnStore: () => ColumnStore;
|
|
20
|
+
readonly bufferAllocator: () => InPlaceBufferAllocator;
|
|
21
|
+
readonly entityIndexCapacity: () => number;
|
|
22
|
+
readonly tick: () => number;
|
|
23
|
+
readonly setTick: (tick: number) => void;
|
|
24
|
+
/** Stamp live row counts into the dense descriptors so a bare dense
|
|
25
|
+
* reader of the snapshot sees self-consistent counts. */
|
|
26
|
+
readonly publishRowCounts: () => void;
|
|
27
|
+
/** Adopt a restored dense store: swap the live backing, refresh archetype
|
|
28
|
+
* views, recover the allocator high-water from the restored region, and
|
|
29
|
+
* republish (the grow tail). Owned by Store — see `_mountRestoredDense`. */
|
|
30
|
+
readonly mountRestoredDense: (restored: ColumnStore) => void;
|
|
31
|
+
/** Rebuild each archetype's host-side `length`/`enabledCount`/entity-id
|
|
32
|
+
* back-references from the restored entity-index region + captured host
|
|
33
|
+
* state. Owned by Store — see `_reconstructHostRows`. */
|
|
34
|
+
readonly reconstructHostRows: (host: HostState) => void;
|
|
35
|
+
/** Every archetype's membership just changed — bump the query epoch and
|
|
36
|
+
* force the next descriptor publish. */
|
|
37
|
+
readonly invalidateQueryCaches: () => void;
|
|
38
|
+
}
|
|
39
|
+
export declare class SnapshotService {
|
|
40
|
+
private readonly host;
|
|
41
|
+
/** The allocator IS its own snapshot seam (H1 step 3): free-list copy on
|
|
42
|
+
* capture; `setHighWater` + `restoreHostState` on mount. */
|
|
43
|
+
private readonly allocator;
|
|
44
|
+
constructor(host: SnapshotHost, allocator: EntityAllocator);
|
|
45
|
+
/** Serialize the sparse stores **and** relation side data to a self-contained
|
|
46
|
+
* byte buffer — the sparse half of a world snapshot (the dense half is the
|
|
47
|
+
* SAB snapshot). Two framed sections: the sparse stores (`snapshotSparseStores`
|
|
48
|
+
* — exclusive relation targets + multi membership ride here) followed
|
|
49
|
+
* by the relation side data (`snapshotRelations` — multi forward target
|
|
50
|
+
* sets, which live outside the sparse store). Both are written in canonical
|
|
51
|
+
* entity-index order, so two worlds with identical contents inserted in
|
|
52
|
+
* different orders snapshot byte-for-byte the same (#470). The reverse index
|
|
53
|
+
* is derived and never serialized — `restoreSparse` rebuilds it. */
|
|
54
|
+
snapshotSparse(): Uint8Array;
|
|
55
|
+
/** Repopulate the sparse stores from `snapshotSparse` bytes, replacing all
|
|
56
|
+
* current sparse data (full-equality round-trip of membership + data), then
|
|
57
|
+
* rebuild every relation's derived side indices: multi forward sets from the
|
|
58
|
+
* relation section, and the reverse index for both cardinalities (exclusive
|
|
59
|
+
* from the just-restored sparse target field, multi from the rebuilt forward
|
|
60
|
+
* sets). The sparse components and relations must already be registered in
|
|
61
|
+
* the same order — restore carries data, not the registration (which is
|
|
62
|
+
* code). Throws `SparseRestoreError` if the snapshot's shape, field identity,
|
|
63
|
+
* entity-index bounds, or frame length don't validate. */
|
|
64
|
+
restoreSparse(bytes: Uint8Array): void;
|
|
65
|
+
/** Rebuild every relation's derived side indices after the sparse stores have
|
|
66
|
+
* been restored. `restoreRelations` resets all relations, rebuilds the multi
|
|
67
|
+
* forward sets + their reverse edges from `relBytes`, and validates shape.
|
|
68
|
+
* The exclusive reverse index can't be carried in the bytes (it's derivable),
|
|
69
|
+
* so it's rebuilt here from the backing sparse store: every member row holds
|
|
70
|
+
* `(source index → target EntityID)`, which is exactly one reverse edge. */
|
|
71
|
+
private rebuildRelationIndices;
|
|
72
|
+
/** Capture the full live world to one self-contained byte buffer that
|
|
73
|
+
* `restoreInto` can mount back onto a live, ticking world (#789). Three
|
|
74
|
+
* sections (see `resume.ts`): the dense SAB column bytes, the sparse +
|
|
75
|
+
* relation bytes, and the host-side bookkeeping the SAB omits. */
|
|
76
|
+
snapshot(): Uint8Array;
|
|
77
|
+
/** Gather the host-side state a snapshot carries alongside the dense + sparse
|
|
78
|
+
* bytes — see `snapshot()`. The free-list is copied (it's a live mutable). */
|
|
79
|
+
private collectHostState;
|
|
80
|
+
/** Mount a `snapshot()` buffer onto the live world and leave it ready to keep
|
|
81
|
+
* ticking. Fails closed on a malformed frame or a registration mismatch
|
|
82
|
+
* BEFORE any live state is touched. */
|
|
83
|
+
restoreInto(bytes: Uint8Array): void;
|
|
84
|
+
/** Read-only validation of a `snapshotSparse` SECTION (the framed
|
|
85
|
+
* `[sparseLen][relLen][sparse][rel]` buffer) against the live registry, used
|
|
86
|
+
* by `restoreInto` to fail closed on a sparse-registration mismatch BEFORE the
|
|
87
|
+
* dense mount commits. Mirrors `restoreSparse`'s frame check, then validates the
|
|
88
|
+
* sparse-stores sub-section without mutating. A relation-registration difference
|
|
89
|
+
* surfaces here too: every `registerRelation` adds a backing sparse store, so a
|
|
90
|
+
* differing relation set changes the sparse store count / schema. Throws
|
|
91
|
+
* `SparseRestoreError` on a mismatch. */
|
|
92
|
+
private assertSparseSectionMatches;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=snapshot_service.d.ts.map
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Archetype } from './archetype.js';
|
|
2
|
+
import { EntityAllocator } from './entity_allocator.js';
|
|
3
|
+
import { SparseComponentStore } from './sparse_store.js';
|
|
4
|
+
import { RelationStore } from './relation.js';
|
|
5
|
+
import { ColumnStore, InPlaceBufferAllocator } from '../store/index.js';
|
|
6
|
+
import { HostState } from './resume.js';
|
|
7
|
+
/** What the snapshot/resume orchestration needs from `Store` — closure-
|
|
8
|
+
* injected (the `RelationServiceHost` style). Accessors re-read live fields
|
|
9
|
+
* per call (the column store and the entity-index views are replaced on
|
|
10
|
+
* restore); the three mutation members keep Store-owned state transitions on
|
|
11
|
+
* the Store side. All cold-path. */
|
|
12
|
+
export interface SnapshotHost {
|
|
13
|
+
readonly sparseStores: () => readonly SparseComponentStore[];
|
|
14
|
+
readonly relationStores: () => readonly RelationStore[];
|
|
15
|
+
/** Live SAB generations view (replanted on restore) — for rebuilding
|
|
16
|
+
* relation ids from entity indices. */
|
|
17
|
+
readonly generations: () => Int32Array;
|
|
18
|
+
readonly archetypes: () => readonly Archetype[];
|
|
19
|
+
readonly columnStore: () => ColumnStore;
|
|
20
|
+
readonly bufferAllocator: () => InPlaceBufferAllocator;
|
|
21
|
+
readonly entityIndexCapacity: () => number;
|
|
22
|
+
readonly tick: () => number;
|
|
23
|
+
readonly setTick: (tick: number) => void;
|
|
24
|
+
/** Stamp live row counts into the dense descriptors so a bare dense
|
|
25
|
+
* reader of the snapshot sees self-consistent counts. */
|
|
26
|
+
readonly publishRowCounts: () => void;
|
|
27
|
+
/** Adopt a restored dense store: swap the live backing, refresh archetype
|
|
28
|
+
* views, recover the allocator high-water from the restored region, and
|
|
29
|
+
* republish (the grow tail). Owned by Store — see `_mountRestoredDense`. */
|
|
30
|
+
readonly mountRestoredDense: (restored: ColumnStore) => void;
|
|
31
|
+
/** Rebuild each archetype's host-side `length`/`enabledCount`/entity-id
|
|
32
|
+
* back-references from the restored entity-index region + captured host
|
|
33
|
+
* state. Owned by Store — see `_reconstructHostRows`. */
|
|
34
|
+
readonly reconstructHostRows: (host: HostState) => void;
|
|
35
|
+
/** Every archetype's membership just changed — bump the query epoch and
|
|
36
|
+
* force the next descriptor publish. */
|
|
37
|
+
readonly invalidateQueryCaches: () => void;
|
|
38
|
+
}
|
|
39
|
+
export declare class SnapshotService {
|
|
40
|
+
private readonly host;
|
|
41
|
+
/** The allocator IS its own snapshot seam (H1 step 3): free-list copy on
|
|
42
|
+
* capture; `setHighWater` + `restoreHostState` on mount. */
|
|
43
|
+
private readonly allocator;
|
|
44
|
+
constructor(host: SnapshotHost, allocator: EntityAllocator);
|
|
45
|
+
/** Serialize the sparse stores **and** relation side data to a self-contained
|
|
46
|
+
* byte buffer — the sparse half of a world snapshot (the dense half is the
|
|
47
|
+
* SAB snapshot). Two framed sections: the sparse stores (`snapshotSparseStores`
|
|
48
|
+
* — exclusive relation targets + multi membership ride here) followed
|
|
49
|
+
* by the relation side data (`snapshotRelations` — multi forward target
|
|
50
|
+
* sets, which live outside the sparse store). Both are written in canonical
|
|
51
|
+
* entity-index order, so two worlds with identical contents inserted in
|
|
52
|
+
* different orders snapshot byte-for-byte the same (#470). The reverse index
|
|
53
|
+
* is derived and never serialized — `restoreSparse` rebuilds it. */
|
|
54
|
+
snapshotSparse(): Uint8Array;
|
|
55
|
+
/** Repopulate the sparse stores from `snapshotSparse` bytes, replacing all
|
|
56
|
+
* current sparse data (full-equality round-trip of membership + data), then
|
|
57
|
+
* rebuild every relation's derived side indices: multi forward sets from the
|
|
58
|
+
* relation section, and the reverse index for both cardinalities (exclusive
|
|
59
|
+
* from the just-restored sparse target field, multi from the rebuilt forward
|
|
60
|
+
* sets). The sparse components and relations must already be registered in
|
|
61
|
+
* the same order — restore carries data, not the registration (which is
|
|
62
|
+
* code). Throws `SparseRestoreError` if the snapshot's shape, field identity,
|
|
63
|
+
* entity-index bounds, or frame length don't validate. */
|
|
64
|
+
restoreSparse(bytes: Uint8Array): void;
|
|
65
|
+
/** Rebuild every relation's derived side indices after the sparse stores have
|
|
66
|
+
* been restored. `restoreRelations` resets all relations, rebuilds the multi
|
|
67
|
+
* forward sets + their reverse edges from `relBytes`, and validates shape.
|
|
68
|
+
* The exclusive reverse index can't be carried in the bytes (it's derivable),
|
|
69
|
+
* so it's rebuilt here from the backing sparse store: every member row holds
|
|
70
|
+
* `(source index → target EntityID)`, which is exactly one reverse edge. */
|
|
71
|
+
private rebuildRelationIndices;
|
|
72
|
+
/** Capture the full live world to one self-contained byte buffer that
|
|
73
|
+
* `restoreInto` can mount back onto a live, ticking world (#789). Three
|
|
74
|
+
* sections (see `resume.ts`): the dense SAB column bytes, the sparse +
|
|
75
|
+
* relation bytes, and the host-side bookkeeping the SAB omits. */
|
|
76
|
+
snapshot(): Uint8Array;
|
|
77
|
+
/** Gather the host-side state a snapshot carries alongside the dense + sparse
|
|
78
|
+
* bytes — see `snapshot()`. The free-list is copied (it's a live mutable). */
|
|
79
|
+
private collectHostState;
|
|
80
|
+
/** Mount a `snapshot()` buffer onto the live world and leave it ready to keep
|
|
81
|
+
* ticking. Fails closed on a malformed frame or a registration mismatch
|
|
82
|
+
* BEFORE any live state is touched. */
|
|
83
|
+
restoreInto(bytes: Uint8Array): void;
|
|
84
|
+
/** Read-only validation of a `snapshotSparse` SECTION (the framed
|
|
85
|
+
* `[sparseLen][relLen][sparse][rel]` buffer) against the live registry, used
|
|
86
|
+
* by `restoreInto` to fail closed on a sparse-registration mismatch BEFORE the
|
|
87
|
+
* dense mount commits. Mirrors `restoreSparse`'s frame check, then validates the
|
|
88
|
+
* sparse-stores sub-section without mutating. A relation-registration difference
|
|
89
|
+
* surfaces here too: every `registerRelation` adds a backing sparse store, so a
|
|
90
|
+
* differing relation set changes the sparse store count / schema. Throws
|
|
91
|
+
* `SparseRestoreError` on a mismatch. */
|
|
92
|
+
private assertSparseSectionMatches;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=snapshot_service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot_service.d.ts","sourceRoot":"","sources":["../../../src/core/ecs/snapshot_service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EACN,oBAAoB,EAKpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAuC,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAGN,KAAK,WAAW,EAChB,KAAK,sBAAsB,EAC3B,MAAM,UAAU,CAAC;AAClB,OAAO,EAON,KAAK,SAAS,EACd,MAAM,UAAU,CAAC;AAElB;;;;oCAIoC;AACpC,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,SAAS,oBAAoB,EAAE,CAAC;IAC7D,QAAQ,CAAC,cAAc,EAAE,MAAM,SAAS,aAAa,EAAE,CAAC;IACxD;2CACuC;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,UAAU,CAAC;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,SAAS,SAAS,EAAE,CAAC;IAChD,QAAQ,CAAC,WAAW,EAAE,MAAM,WAAW,CAAC;IACxC,QAAQ,CAAC,eAAe,EAAE,MAAM,sBAAsB,CAAC;IACvD,QAAQ,CAAC,mBAAmB,EAAE,MAAM,MAAM,CAAC;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC;6DACyD;IACzD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,IAAI,CAAC;IACtC;;gFAE4E;IAC5E,QAAQ,CAAC,kBAAkB,EAAE,CAAC,QAAQ,EAAE,WAAW,KAAK,IAAI,CAAC;IAC7D;;6DAEyD;IACzD,QAAQ,CAAC,mBAAmB,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACxD;4CACwC;IACxC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,IAAI,CAAC;CAC3C;AAED,qBAAa,eAAe;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAe;IACpC;gEAC4D;IAC5D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;gBAEhC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe;IAK1D;;;;;;;;wEAQoE;IAC7D,cAAc,IAAI,UAAU;IAanC;;;;;;;;8DAQ0D;IACnD,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAuB7C;;;;;gFAK4E;IAC5E,OAAO,CAAC,sBAAsB;IAW9B;;;sEAGkE;IAC3D,QAAQ,IAAI,UAAU;IAa7B;kFAC8E;IAC9E,OAAO,CAAC,gBAAgB;IAqBxB;;2CAEuC;IAChC,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IA2C3C;;;;;;;6CAOyC;IACzC,OAAO,CAAC,0BAA0B;CAgBlC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Brand, TypedArrayTag } from '../../type_primitives/index.cjs';
|
|
2
|
+
import { ComponentSchema } from './component.cjs';
|
|
3
|
+
/** Sparse-component handle id. A separate id space from `ComponentID` — it
|
|
4
|
+
* indexes `Store`'s `sparseStores`, never the archetype mask, which is the
|
|
5
|
+
* mechanism by which sparse components escape the 128-bit identity cap. */
|
|
6
|
+
export type SparseComponentID = Brand<number, "sparse_component_id">;
|
|
7
|
+
declare const __sparseSchema: unique symbol;
|
|
8
|
+
export type SparseComponentDef<S extends ComponentSchema = ComponentSchema> = SparseComponentID & {
|
|
9
|
+
readonly [__sparseSchema]: S;
|
|
10
|
+
};
|
|
11
|
+
/** Recover a sparse def's schema type — the sparse sibling of `SchemaOf`
|
|
12
|
+
* (component.ts), used by the typed `SystemContext` sparse surface. */
|
|
13
|
+
export type SparseSchemaOf<D> = D extends SparseComponentDef<infer S extends ComponentSchema> ? S : never;
|
|
14
|
+
/** One sparse component's membership + data. Pure data structure — the `Store`
|
|
15
|
+
* owns liveness checks and dev-mode error throwing; this class only knows
|
|
16
|
+
* entity indices and field rows. */
|
|
17
|
+
export declare class SparseComponentStore {
|
|
18
|
+
/** entity index → field-value row (length = field count; `[]` for a tag). */
|
|
19
|
+
private readonly _data;
|
|
20
|
+
readonly fieldNames: string[];
|
|
21
|
+
readonly fieldTypes: TypedArrayTag[];
|
|
22
|
+
readonly fieldIndex: Record<string, number>;
|
|
23
|
+
constructor(fieldNames: string[], fieldTypes: TypedArrayTag[]);
|
|
24
|
+
/** Number of entities holding this sparse component. */
|
|
25
|
+
get size(): number;
|
|
26
|
+
/** Live entity indices that hold this component (dense, iteration order is
|
|
27
|
+
* SparseMap insertion/swap order — NOT canonical). Used by the hot query
|
|
28
|
+
* integration path (#469); for the determinism surface use
|
|
29
|
+
* `canonicalIndices` instead. */
|
|
30
|
+
get indices(): readonly number[];
|
|
31
|
+
/** Live entity indices in **canonical** (ascending) order — the determinism
|
|
32
|
+
* ordering for `stateHash` + snapshot/restore (ADR-0011, #470). The native
|
|
33
|
+
* `indices` getter is insertion/swap order and would make two worlds with
|
|
34
|
+
* identical contents reached by different add/remove histories diverge, so
|
|
35
|
+
* the cold determinism paths sort here. Allocates a sorted copy each call;
|
|
36
|
+
* never call it on the hot query path. Indices are 20-bit entity indices,
|
|
37
|
+
* so the subtraction comparator can't overflow. */
|
|
38
|
+
canonicalIndices(): number[];
|
|
39
|
+
/** The field-value row for `index` (length = field count; `[]` for a tag),
|
|
40
|
+
* or `undefined` if `index` isn't a member. Read-only view for the
|
|
41
|
+
* determinism paths (`stateHash`, snapshot); mutate via `setField`. */
|
|
42
|
+
getRow(index: number): readonly number[] | undefined;
|
|
43
|
+
/** Drop all membership + data. Restore path only — `restoreSparseStores`
|
|
44
|
+
* repopulates a cleared store from snapshot bytes. */
|
|
45
|
+
clear(): void;
|
|
46
|
+
/** Insert the positional field-value `row` for `index`, taking ownership of
|
|
47
|
+
* the array. Restore path only; bypasses the name→index mapping `setRow`
|
|
48
|
+
* does, because snapshot bytes are already positional. */
|
|
49
|
+
setRawRow(index: number, row: number[]): void;
|
|
50
|
+
has(index: number): boolean;
|
|
51
|
+
/** Insert or overwrite the row for `index`, building it from `values`.
|
|
52
|
+
* Fields absent from `values` default to 0; a tag stores `[]`. */
|
|
53
|
+
setRow(index: number, values: Record<string, number>): void;
|
|
54
|
+
/** Drop `index`'s membership + data. Returns whether it was present. */
|
|
55
|
+
remove(index: number): boolean;
|
|
56
|
+
/** Read one field, or `undefined` if `index` doesn't hold this component. */
|
|
57
|
+
getField(index: number, fieldIdx: number): number | undefined;
|
|
58
|
+
/** Write one field. Returns `false` (no-op) if `index` isn't a member. */
|
|
59
|
+
setField(index: number, fieldIdx: number, value: number): boolean;
|
|
60
|
+
}
|
|
61
|
+
export declare class SparseRestoreError extends Error {
|
|
62
|
+
constructor(message: string);
|
|
63
|
+
}
|
|
64
|
+
/** Serialize a registry of sparse stores into a self-contained byte buffer —
|
|
65
|
+
* the **sparse half** of a world snapshot (the dense half is the SAB snapshot,
|
|
66
|
+
* `snapshotColumnStore`). Members are emitted in canonical (ascending
|
|
67
|
+
* entity-index) order so the bytes are independent of insertion / removal
|
|
68
|
+
* history: two worlds with identical sparse contents reached by different
|
|
69
|
+
* mutation orders serialize byte-for-byte the same (#470).
|
|
70
|
+
*
|
|
71
|
+
* Layout (all integers little-endian, to match the dense SAB snapshot and stay
|
|
72
|
+
* architecture-independent):
|
|
73
|
+
*
|
|
74
|
+
* u32 storeCount
|
|
75
|
+
* repeat storeCount times:
|
|
76
|
+
* u32 fieldCount
|
|
77
|
+
* u32 schemaHash
|
|
78
|
+
* u32 memberCount
|
|
79
|
+
* repeat memberCount times (canonical entity-index order):
|
|
80
|
+
* u32 entityIndex
|
|
81
|
+
* f64 × fieldCount (the positional field row; none for a tag)
|
|
82
|
+
*
|
|
83
|
+
* `fieldCount` is redundant with the registered schema but is written so
|
|
84
|
+
* `restoreSparseStores` can reject a snapshot whose shape doesn't match the
|
|
85
|
+
* stores it's restoring into; `schemaHash` (a `schemaFingerprint` over the
|
|
86
|
+
* field names + types) goes further and rejects a buffer whose shape matches
|
|
87
|
+
* field-for-field but whose field **identity** doesn't (#494). */
|
|
88
|
+
export declare function snapshotSparseStores(stores: readonly SparseComponentStore[]): Uint8Array;
|
|
89
|
+
/** Repopulate already-registered sparse stores from `snapshotSparseStores`
|
|
90
|
+
* bytes, giving full-equality round-trip (membership + data). The `stores`
|
|
91
|
+
* registry must already exist with the same shape the snapshot was taken from
|
|
92
|
+
* — restore replays data into a world whose sparse components are registered
|
|
93
|
+
* in the same order (the registration is code, not snapshot state). Each store
|
|
94
|
+
* is cleared first, so restoring is idempotent and drops any pre-existing rows.
|
|
95
|
+
*
|
|
96
|
+
* Throws `SparseRestoreError` on any shape or identity mismatch (store count,
|
|
97
|
+
* field count, schema-hash field identity, an entity index past `MAX_INDEX`,
|
|
98
|
+
* or a truncated / over-long buffer) rather than silently corrupting state.
|
|
99
|
+
* The index bound matters because the index keys a `SparseMap` whose backing
|
|
100
|
+
* array grows to `index` length — an unvalidated crafted u32 (up to ~4.29e9)
|
|
101
|
+
* would allocate multi-GB (#494). */
|
|
102
|
+
export declare function restoreSparseStores(stores: readonly SparseComponentStore[], bytes: Uint8Array): void;
|
|
103
|
+
/** Read-only validation of a `snapshotSparseStores` buffer against the live
|
|
104
|
+
* registry, WITHOUT mutating any store (#789). Mirrors `restoreSparseStores`'s
|
|
105
|
+
* shape/field-identity/index-bounds/frame checks so `Store.restoreInto` can fail
|
|
106
|
+
* closed on a sparse-registration mismatch BEFORE the dense mount overwrites live
|
|
107
|
+
* column data. Throws `SparseRestoreError` on any mismatch / malformed buffer. */
|
|
108
|
+
export declare function validateSparseStores(stores: readonly SparseComponentStore[], bytes: Uint8Array): void;
|
|
109
|
+
export {};
|
|
110
|
+
//# sourceMappingURL=sparse_store.d.ts.map
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Brand, TypedArrayTag } from '../../type_primitives/index.js';
|
|
2
|
+
import { ComponentSchema } from './component.js';
|
|
3
|
+
/** Sparse-component handle id. A separate id space from `ComponentID` — it
|
|
4
|
+
* indexes `Store`'s `sparseStores`, never the archetype mask, which is the
|
|
5
|
+
* mechanism by which sparse components escape the 128-bit identity cap. */
|
|
6
|
+
export type SparseComponentID = Brand<number, "sparse_component_id">;
|
|
7
|
+
declare const __sparseSchema: unique symbol;
|
|
8
|
+
export type SparseComponentDef<S extends ComponentSchema = ComponentSchema> = SparseComponentID & {
|
|
9
|
+
readonly [__sparseSchema]: S;
|
|
10
|
+
};
|
|
11
|
+
/** Recover a sparse def's schema type — the sparse sibling of `SchemaOf`
|
|
12
|
+
* (component.ts), used by the typed `SystemContext` sparse surface. */
|
|
13
|
+
export type SparseSchemaOf<D> = D extends SparseComponentDef<infer S extends ComponentSchema> ? S : never;
|
|
14
|
+
/** One sparse component's membership + data. Pure data structure — the `Store`
|
|
15
|
+
* owns liveness checks and dev-mode error throwing; this class only knows
|
|
16
|
+
* entity indices and field rows. */
|
|
17
|
+
export declare class SparseComponentStore {
|
|
18
|
+
/** entity index → field-value row (length = field count; `[]` for a tag). */
|
|
19
|
+
private readonly _data;
|
|
20
|
+
readonly fieldNames: string[];
|
|
21
|
+
readonly fieldTypes: TypedArrayTag[];
|
|
22
|
+
readonly fieldIndex: Record<string, number>;
|
|
23
|
+
constructor(fieldNames: string[], fieldTypes: TypedArrayTag[]);
|
|
24
|
+
/** Number of entities holding this sparse component. */
|
|
25
|
+
get size(): number;
|
|
26
|
+
/** Live entity indices that hold this component (dense, iteration order is
|
|
27
|
+
* SparseMap insertion/swap order — NOT canonical). Used by the hot query
|
|
28
|
+
* integration path (#469); for the determinism surface use
|
|
29
|
+
* `canonicalIndices` instead. */
|
|
30
|
+
get indices(): readonly number[];
|
|
31
|
+
/** Live entity indices in **canonical** (ascending) order — the determinism
|
|
32
|
+
* ordering for `stateHash` + snapshot/restore (ADR-0011, #470). The native
|
|
33
|
+
* `indices` getter is insertion/swap order and would make two worlds with
|
|
34
|
+
* identical contents reached by different add/remove histories diverge, so
|
|
35
|
+
* the cold determinism paths sort here. Allocates a sorted copy each call;
|
|
36
|
+
* never call it on the hot query path. Indices are 20-bit entity indices,
|
|
37
|
+
* so the subtraction comparator can't overflow. */
|
|
38
|
+
canonicalIndices(): number[];
|
|
39
|
+
/** The field-value row for `index` (length = field count; `[]` for a tag),
|
|
40
|
+
* or `undefined` if `index` isn't a member. Read-only view for the
|
|
41
|
+
* determinism paths (`stateHash`, snapshot); mutate via `setField`. */
|
|
42
|
+
getRow(index: number): readonly number[] | undefined;
|
|
43
|
+
/** Drop all membership + data. Restore path only — `restoreSparseStores`
|
|
44
|
+
* repopulates a cleared store from snapshot bytes. */
|
|
45
|
+
clear(): void;
|
|
46
|
+
/** Insert the positional field-value `row` for `index`, taking ownership of
|
|
47
|
+
* the array. Restore path only; bypasses the name→index mapping `setRow`
|
|
48
|
+
* does, because snapshot bytes are already positional. */
|
|
49
|
+
setRawRow(index: number, row: number[]): void;
|
|
50
|
+
has(index: number): boolean;
|
|
51
|
+
/** Insert or overwrite the row for `index`, building it from `values`.
|
|
52
|
+
* Fields absent from `values` default to 0; a tag stores `[]`. */
|
|
53
|
+
setRow(index: number, values: Record<string, number>): void;
|
|
54
|
+
/** Drop `index`'s membership + data. Returns whether it was present. */
|
|
55
|
+
remove(index: number): boolean;
|
|
56
|
+
/** Read one field, or `undefined` if `index` doesn't hold this component. */
|
|
57
|
+
getField(index: number, fieldIdx: number): number | undefined;
|
|
58
|
+
/** Write one field. Returns `false` (no-op) if `index` isn't a member. */
|
|
59
|
+
setField(index: number, fieldIdx: number, value: number): boolean;
|
|
60
|
+
}
|
|
61
|
+
export declare class SparseRestoreError extends Error {
|
|
62
|
+
constructor(message: string);
|
|
63
|
+
}
|
|
64
|
+
/** Serialize a registry of sparse stores into a self-contained byte buffer —
|
|
65
|
+
* the **sparse half** of a world snapshot (the dense half is the SAB snapshot,
|
|
66
|
+
* `snapshotColumnStore`). Members are emitted in canonical (ascending
|
|
67
|
+
* entity-index) order so the bytes are independent of insertion / removal
|
|
68
|
+
* history: two worlds with identical sparse contents reached by different
|
|
69
|
+
* mutation orders serialize byte-for-byte the same (#470).
|
|
70
|
+
*
|
|
71
|
+
* Layout (all integers little-endian, to match the dense SAB snapshot and stay
|
|
72
|
+
* architecture-independent):
|
|
73
|
+
*
|
|
74
|
+
* u32 storeCount
|
|
75
|
+
* repeat storeCount times:
|
|
76
|
+
* u32 fieldCount
|
|
77
|
+
* u32 schemaHash
|
|
78
|
+
* u32 memberCount
|
|
79
|
+
* repeat memberCount times (canonical entity-index order):
|
|
80
|
+
* u32 entityIndex
|
|
81
|
+
* f64 × fieldCount (the positional field row; none for a tag)
|
|
82
|
+
*
|
|
83
|
+
* `fieldCount` is redundant with the registered schema but is written so
|
|
84
|
+
* `restoreSparseStores` can reject a snapshot whose shape doesn't match the
|
|
85
|
+
* stores it's restoring into; `schemaHash` (a `schemaFingerprint` over the
|
|
86
|
+
* field names + types) goes further and rejects a buffer whose shape matches
|
|
87
|
+
* field-for-field but whose field **identity** doesn't (#494). */
|
|
88
|
+
export declare function snapshotSparseStores(stores: readonly SparseComponentStore[]): Uint8Array;
|
|
89
|
+
/** Repopulate already-registered sparse stores from `snapshotSparseStores`
|
|
90
|
+
* bytes, giving full-equality round-trip (membership + data). The `stores`
|
|
91
|
+
* registry must already exist with the same shape the snapshot was taken from
|
|
92
|
+
* — restore replays data into a world whose sparse components are registered
|
|
93
|
+
* in the same order (the registration is code, not snapshot state). Each store
|
|
94
|
+
* is cleared first, so restoring is idempotent and drops any pre-existing rows.
|
|
95
|
+
*
|
|
96
|
+
* Throws `SparseRestoreError` on any shape or identity mismatch (store count,
|
|
97
|
+
* field count, schema-hash field identity, an entity index past `MAX_INDEX`,
|
|
98
|
+
* or a truncated / over-long buffer) rather than silently corrupting state.
|
|
99
|
+
* The index bound matters because the index keys a `SparseMap` whose backing
|
|
100
|
+
* array grows to `index` length — an unvalidated crafted u32 (up to ~4.29e9)
|
|
101
|
+
* would allocate multi-GB (#494). */
|
|
102
|
+
export declare function restoreSparseStores(stores: readonly SparseComponentStore[], bytes: Uint8Array): void;
|
|
103
|
+
/** Read-only validation of a `snapshotSparseStores` buffer against the live
|
|
104
|
+
* registry, WITHOUT mutating any store (#789). Mirrors `restoreSparseStores`'s
|
|
105
|
+
* shape/field-identity/index-bounds/frame checks so `Store.restoreInto` can fail
|
|
106
|
+
* closed on a sparse-registration mismatch BEFORE the dense mount overwrites live
|
|
107
|
+
* column data. Throws `SparseRestoreError` on any mismatch / malformed buffer. */
|
|
108
|
+
export declare function validateSparseStores(stores: readonly SparseComponentStore[], bytes: Uint8Array): void;
|
|
109
|
+
export {};
|
|
110
|
+
//# sourceMappingURL=sparse_store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sparse_store.d.ts","sourceRoot":"","sources":["../../../src/core/ecs/sparse_store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;KA0BK;AAEL,OAAO,EAAE,KAAK,EAAa,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD;;2EAE2E;AAC3E,MAAM,MAAM,iBAAiB,GAAG,KAAK,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;AAOrE,OAAO,CAAC,MAAM,cAAc,EAAE,OAAO,MAAM,CAAC;AAE5C,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,eAAe,GAAG,eAAe,IAAI,iBAAiB,GAAG;IACjG,QAAQ,CAAC,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;CAC7B,CAAC;AAEF;uEACuE;AACvE,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,CAAC,SAAS,kBAAkB,CAAC,MAAM,CAAC,SAAS,eAAe,CAAC,GAC1F,CAAC,GACD,KAAK,CAAC;AAET;;oCAEoC;AACpC,qBAAa,oBAAoB;IAChC,6EAA6E;IAC7E,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IACnD,SAAgB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrC,SAAgB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5C,SAAgB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAEvC,UAAU,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,aAAa,EAAE;IAQ7D,wDAAwD;IACxD,IAAW,IAAI,IAAI,MAAM,CAExB;IAED;;;qCAGiC;IACjC,IAAW,OAAO,IAAI,SAAS,MAAM,EAAE,CAEtC;IAED;;;;;;uDAMmD;IAC5C,gBAAgB,IAAI,MAAM,EAAE;IAInC;;2EAEuE;IAChE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS;IAI3D;0DACsD;IAC/C,KAAK,IAAI,IAAI;IAIpB;;8DAE0D;IACnD,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI;IAI7C,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIlC;sEACkE;IAC3D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAUlE,wEAAwE;IACjE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIrC,6EAA6E;IACtE,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAKpE,0EAA0E;IACnE,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;CAMxE;AAED,qBAAa,kBAAmB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI3B;AAuCD;;;;;;;;;;;;;;;;;;;;;;;kEAuBkE;AAClE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,oBAAoB,EAAE,GAAG,UAAU,CAuCxF;AAED;;;;;;;;;;;;qCAYqC;AACrC,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,SAAS,oBAAoB,EAAE,EACvC,KAAK,EAAE,UAAU,GACf,IAAI,CAkEN;AAED;;;;kFAIkF;AAClF,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,SAAS,oBAAoB,EAAE,EACvC,KAAK,EAAE,UAAU,GACf,IAAI,CA4DN"}
|