@oasys/oecs 0.4.0 → 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 +42 -31
- package/dist/core/ecs/access_check.d.cts +77 -0
- package/dist/core/ecs/access_check.d.ts +8 -8
- package/dist/core/ecs/access_check.d.ts.map +1 -1
- package/dist/core/ecs/archetype.d.cts +486 -0
- package/dist/core/ecs/archetype.d.ts +23 -11
- package/dist/core/ecs/archetype.d.ts.map +1 -1
- 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 +8 -8
- package/dist/core/ecs/builtin_relations.d.ts.map +1 -1
- package/dist/core/ecs/command_log.d.cts +116 -0
- package/dist/core/ecs/command_log.d.ts +13 -10
- package/dist/core/ecs/command_log.d.ts.map +1 -1
- package/dist/core/ecs/component.d.cts +176 -0
- package/dist/core/ecs/component.d.ts +75 -5
- package/dist/core/ecs/component.d.ts.map +1 -1
- package/dist/core/ecs/compute_backend.d.cts +37 -0
- package/dist/core/ecs/compute_backend.d.ts +2 -2
- 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 +3 -3
- package/dist/core/ecs/ecs.d.cts +562 -0
- package/dist/core/ecs/ecs.d.ts +314 -285
- package/dist/core/ecs/ecs.d.ts.map +1 -1
- package/dist/core/ecs/ecs_memory.d.cts +179 -0
- package/dist/core/ecs/ecs_memory.d.ts +1 -1
- package/dist/core/ecs/entity.d.cts +34 -0
- package/dist/core/ecs/entity.d.ts +7 -1
- package/dist/core/ecs/entity.d.ts.map +1 -1
- 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 +36 -11
- package/dist/core/ecs/event.d.ts.map +1 -1
- 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 +5 -5
- package/dist/core/ecs/frame_trace.d.ts.map +1 -1
- package/dist/core/ecs/host_commands.d.cts +274 -0
- package/dist/core/ecs/host_commands.d.ts +53 -31
- package/dist/core/ecs/host_commands.d.ts.map +1 -1
- package/dist/core/ecs/index.d.cts +46 -0
- package/dist/core/ecs/index.d.ts +45 -40
- package/dist/core/ecs/index.d.ts.map +1 -1
- package/dist/core/ecs/observer.d.cts +173 -0
- package/dist/core/ecs/observer.d.ts +43 -12
- package/dist/core/ecs/observer.d.ts.map +1 -1
- package/dist/core/ecs/query.d.cts +718 -0
- package/dist/core/ecs/query.d.ts +251 -90
- package/dist/core/ecs/query.d.ts.map +1 -1
- package/dist/core/ecs/ref.d.cts +31 -0
- package/dist/core/ecs/ref.d.ts +3 -3
- package/dist/core/ecs/relation.d.cts +243 -0
- package/dist/core/ecs/relation.d.ts +26 -14
- package/dist/core/ecs/relation.d.ts.map +1 -1
- 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 +25 -5
- package/dist/core/ecs/resource.d.ts.map +1 -1
- 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 +6 -6
- package/dist/core/ecs/resume.d.ts.map +1 -1
- package/dist/core/ecs/run_condition.d.cts +81 -0
- package/dist/core/ecs/run_condition.d.ts +15 -9
- package/dist/core/ecs/run_condition.d.ts.map +1 -1
- package/dist/core/ecs/schedule.d.cts +142 -0
- package/dist/core/ecs/schedule.d.ts +15 -6
- package/dist/core/ecs/schedule.d.ts.map +1 -1
- 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 +5 -2
- package/dist/core/ecs/sparse_store.d.ts.map +1 -1
- package/dist/core/ecs/store.d.cts +950 -0
- package/dist/core/ecs/store.d.ts +143 -342
- package/dist/core/ecs/store.d.ts.map +1 -1
- package/dist/core/ecs/store_layout_listener.d.cts +23 -0
- package/dist/core/ecs/system.d.cts +250 -0
- package/dist/core/ecs/system.d.ts +138 -22
- package/dist/core/ecs/system.d.ts.map +1 -1
- package/dist/{utils/arrays.d.ts → core/ecs/utils/arrays.d.cts} +1 -0
- package/dist/core/ecs/utils/error.d.cts +61 -0
- package/dist/core/ecs/utils/error.d.ts +12 -2
- package/dist/core/ecs/utils/error.d.ts.map +1 -1
- package/dist/core/store/action_ring.d.cts +136 -0
- package/dist/core/store/allocator.d.cts +238 -0
- package/dist/core/store/allocator.d.ts.map +1 -1
- package/dist/core/store/buffer_backed_column.d.cts +69 -0
- package/dist/core/store/buffer_backed_column.d.ts +2 -2
- package/dist/core/store/column_store.d.cts +273 -0
- package/dist/core/store/column_store.d.ts +18 -10
- package/dist/core/store/column_store.d.ts.map +1 -1
- package/dist/core/store/command_dispatch.d.cts +52 -0
- package/dist/core/store/command_ring.d.cts +107 -0
- package/dist/core/store/descriptor.d.cts +80 -0
- package/dist/core/store/descriptor.d.ts +1 -1
- package/dist/core/store/descriptor.d.ts.map +1 -1
- package/dist/core/store/entity_index.d.cts +108 -0
- package/dist/core/store/event_ring.d.cts +95 -0
- package/dist/core/store/extend.d.cts +39 -0
- package/dist/core/store/extend.d.ts +3 -73
- package/dist/core/store/extend.d.ts.map +1 -1
- package/dist/core/store/grow.d.cts +34 -0
- package/dist/core/store/grow.d.ts +4 -9
- package/dist/core/store/grow.d.ts.map +1 -1
- package/dist/core/store/header.d.cts +64 -0
- package/dist/core/store/header.d.ts +1 -1
- package/dist/core/store/header.d.ts.map +1 -1
- package/dist/core/store/index.d.cts +17 -0
- package/dist/core/store/index.d.ts +16 -15
- package/dist/core/store/index.d.ts.map +1 -1
- 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 +1 -1
- package/dist/core/store/region_table.d.ts.map +1 -1
- package/dist/core/store/snapshot.d.cts +43 -0
- package/dist/core/store/snapshot.d.ts +2 -2
- package/dist/core/store/state_hash.d.cts +38 -0
- package/dist/core/store/state_hash.d.ts +1 -1
- package/dist/core/store/store_regions.d.cts +38 -0
- package/dist/core/store/store_regions.d.ts +1 -1
- package/dist/core/store/vendored_abi/abi.d.ts +43 -0
- package/dist/core/store/{__generated__ → vendored_abi}/abi.d.ts.map +1 -1
- 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 +43 -22
- package/dist/extensions/editor/editor.d.ts.map +1 -1
- package/dist/extensions/editor/field_handle.d.cts +40 -0
- package/dist/extensions/editor/field_handle.d.ts +8 -3
- package/dist/extensions/editor/field_handle.d.ts.map +1 -1
- package/dist/extensions/editor/index.cjs +1 -1
- package/dist/extensions/editor/index.d.cts +21 -0
- package/dist/extensions/editor/index.d.ts +2 -2
- package/dist/extensions/editor/index.js +116 -88
- package/dist/extensions/reactive/ecs_sync.d.cts +214 -0
- package/dist/extensions/reactive/ecs_sync.d.ts +26 -22
- package/dist/extensions/reactive/ecs_sync.d.ts.map +1 -1
- package/dist/extensions/reactive/index.cjs +1 -1
- package/dist/extensions/reactive/index.d.cts +23 -0
- package/dist/extensions/reactive/index.d.ts +1 -1
- package/dist/extensions/reactive/index.js +106 -116
- package/dist/extensions/solid/index.cjs +1 -1
- package/dist/extensions/solid/index.d.cts +6 -0
- package/dist/extensions/solid/index.d.ts +2 -2
- package/dist/extensions/solid/index.js +8 -4
- package/dist/extensions/solid/kernel_solid.d.cts +45 -0
- package/dist/extensions/solid/kernel_solid.d.ts +6 -3
- package/dist/extensions/solid/kernel_solid.d.ts.map +1 -1
- package/dist/host_commands-BF8QMi3c.cjs +1 -0
- package/dist/host_commands-i4cAeyL5.js +2318 -0
- package/dist/index.cjs +1 -2
- package/dist/index.d.cts +66 -0
- package/dist/index.d.ts +50 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4469 -5933
- 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/primitives.cjs +1 -1
- package/dist/primitives.d.cts +18 -0
- package/dist/primitives.d.ts +6 -6
- package/dist/primitives.js +24 -23
- 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/{core/reactive → reactive}/interop.d.ts +1 -1
- package/dist/reactive/interop.d.ts.map +1 -0
- package/dist/reactive/kernel.d.cts +73 -0
- package/dist/{core/reactive → reactive}/kernel.d.ts +5 -3
- package/dist/reactive/kernel.d.ts.map +1 -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/{core/reactive → reactive}/struct.d.ts +1 -1
- 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 -1
- package/dist/shared.d.cts +22 -0
- package/dist/shared.d.ts +2 -2
- package/dist/shared.js +1 -1
- 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 +13 -1
- 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/bitset/bitset.d.cts +54 -0
- package/dist/type_primitives/brand.d.cts +23 -0
- package/dist/type_primitives/error.d.cts +16 -0
- package/dist/type_primitives/error.d.ts +4 -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 +9 -9
- package/dist/type_primitives/sparse_map/sparse_map.d.cts +30 -0
- package/dist/type_primitives/sparse_set/sparse_set.d.cts +28 -0
- package/dist/type_primitives/topological_sort/topological_sort.d.cts +29 -0
- package/dist/type_primitives/typed_arrays/typed_arrays.d.cts +127 -0
- 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/version.d.cts +10 -0
- package/dist/version.d.ts +10 -0
- package/dist/version.d.ts.map +1 -0
- package/package.json +102 -19
- package/dist/array-CxbPyiHO.cjs +0 -1
- package/dist/array-uFR7Q8fU.js +0 -132
- package/dist/core/reactive/array.d.ts.map +0 -1
- package/dist/core/reactive/index.cjs +0 -1
- package/dist/core/reactive/index.d.ts +0 -10
- package/dist/core/reactive/index.d.ts.map +0 -1
- package/dist/core/reactive/index.js +0 -17
- package/dist/core/reactive/interop.d.ts.map +0 -1
- package/dist/core/reactive/kernel.d.ts.map +0 -1
- package/dist/core/reactive/map.d.ts.map +0 -1
- package/dist/core/reactive/struct.d.ts.map +0 -1
- package/dist/log/console_sink.d.ts +0 -4
- package/dist/log/console_sink.d.ts.map +0 -1
- package/dist/log/index.d.ts +0 -3
- package/dist/log/index.d.ts.map +0 -1
- package/dist/log/logger.d.ts +0 -27
- package/dist/log/logger.d.ts.map +0 -1
- package/dist/shared-BXSZnxx4.cjs +0 -1
- package/dist/shared-C678TAPY.js +0 -99
- package/dist/topological_sort-DlRpSrxu.js +0 -391
- package/dist/topological_sort-WAT-VHb-.cjs +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
- /package/dist/core/store/{__generated__/abi.d.ts → vendored_abi/abi.d.cts} +0 -0
- /package/dist/{core/reactive/array.d.ts → reactive/array.d.cts} +0 -0
- /package/dist/{core/reactive/map.d.ts → reactive/map.d.cts} +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { AppError } from '../../../utils/error.cjs';
|
|
2
|
+
export declare enum ECS_ERROR {
|
|
3
|
+
EID_MAX_INDEX_OVERFLOW = "EID_MAX_INDEX_OVERFLOW",
|
|
4
|
+
EID_MAX_GEN_OVERFLOW = "EID_MAX_GEN_OVERFLOW",
|
|
5
|
+
COMPONENT_NOT_REGISTERED = "COMPONENT_NOT_REGISTERED",
|
|
6
|
+
COMPONENT_LIMIT_EXCEEDED = "COMPONENT_LIMIT_EXCEEDED",
|
|
7
|
+
ENTITY_NOT_ALIVE = "ENTITY_NOT_ALIVE",
|
|
8
|
+
CIRCULAR_SYSTEM_DEPENDENCY = "CIRCULAR_SYSTEM_DEPENDENCY",
|
|
9
|
+
DUPLICATE_SYSTEM = "DUPLICATE_SYSTEM",
|
|
10
|
+
ARCHETYPE_NOT_FOUND = "ARCHETYPE_NOT_FOUND",
|
|
11
|
+
RESOURCE_NOT_REGISTERED = "RESOURCE_NOT_REGISTERED",
|
|
12
|
+
RESOURCE_ALREADY_REGISTERED = "RESOURCE_ALREADY_REGISTERED",
|
|
13
|
+
EVENT_ALREADY_REGISTERED = "EVENT_ALREADY_REGISTERED",
|
|
14
|
+
EVENT_NOT_REGISTERED = "EVENT_NOT_REGISTERED",
|
|
15
|
+
FIELD_NOT_REGISTERED = "FIELD_NOT_REGISTERED",
|
|
16
|
+
RELATION_NOT_REGISTERED = "RELATION_NOT_REGISTERED",
|
|
17
|
+
RELATION_MODE_INVALID = "RELATION_MODE_INVALID",
|
|
18
|
+
RELATION_MODE_MISMATCH = "RELATION_MODE_MISMATCH",
|
|
19
|
+
RELATION_CYCLE = "RELATION_CYCLE",
|
|
20
|
+
SPARSE_CACHE_KEY_OVERFLOW = "SPARSE_CACHE_KEY_OVERFLOW",
|
|
21
|
+
SPARSE_QUERY_DENSE_PATH = "SPARSE_QUERY_DENSE_PATH",
|
|
22
|
+
HIERARCHY_ALREADY_SET = "HIERARCHY_ALREADY_SET",
|
|
23
|
+
HIERARCHY_INVALID_MAX_DEPTH = "HIERARCHY_INVALID_MAX_DEPTH",
|
|
24
|
+
OBSERVER_NON_CONVERGENT = "OBSERVER_NON_CONVERGENT",
|
|
25
|
+
OBSERVER_INVALID_CONFIG = "OBSERVER_INVALID_CONFIG",
|
|
26
|
+
OBSERVER_ONSET_EMIT = "OBSERVER_ONSET_EMIT",
|
|
27
|
+
INVALID_FIXED_TIMESTEP = "INVALID_FIXED_TIMESTEP",
|
|
28
|
+
INVALID_MAX_FIXED_STEPS = "INVALID_MAX_FIXED_STEPS",
|
|
29
|
+
INVALID_RECORDER_SCHEDULE = "INVALID_RECORDER_SCHEDULE",
|
|
30
|
+
EMPTY_ARCHETYPE_MATERIALIZE = "EMPTY_ARCHETYPE_MATERIALIZE",
|
|
31
|
+
COMPONENT_INDEX_INVARIANT = "COMPONENT_INDEX_INVARIANT",
|
|
32
|
+
OPTIONAL_TERM_NOT_DECLARED = "OPTIONAL_TERM_NOT_DECLARED",
|
|
33
|
+
QUERY_ACCESS_UNDECLARED = "QUERY_ACCESS_UNDECLARED",
|
|
34
|
+
/** A system touched a component/sparse/relation/resource it didn't declare
|
|
35
|
+
* in its access surface — distinct from *_NOT_REGISTERED (which means the
|
|
36
|
+
* thing was never registered with the world at all). */
|
|
37
|
+
ACCESS_UNDECLARED = "ACCESS_UNDECLARED",
|
|
38
|
+
/** `Query.singleEntity` found 0 or >1 matches (dev-only assertion). */
|
|
39
|
+
QUERY_NOT_SINGLETON = "QUERY_NOT_SINGLETON",
|
|
40
|
+
/** A run-condition factory was given invalid arguments (dev-only). */
|
|
41
|
+
INVALID_RUN_CONDITION = "INVALID_RUN_CONDITION",
|
|
42
|
+
SYSTEM_FN_ARITY = "SYSTEM_FN_ARITY",
|
|
43
|
+
PARTITION_APPEND_NEEDS_ENTITY_ROW = "PARTITION_APPEND_NEEDS_ENTITY_ROW",
|
|
44
|
+
PARTITION_BULK_INTO_DISABLED = "PARTITION_BULK_INTO_DISABLED",
|
|
45
|
+
ENTITY_NOT_DISABLED = "ENTITY_NOT_DISABLED",
|
|
46
|
+
STRUCTURAL_DURING_ITERATION = "STRUCTURAL_DURING_ITERATION",
|
|
47
|
+
BACKEND_ALREADY_ATTACHED = "BACKEND_ALREADY_ATTACHED",
|
|
48
|
+
DETERMINISM_DISABLED = "DETERMINISM_DISABLED",
|
|
49
|
+
NON_DETERMINISTIC_COLUMN_TYPE = "NON_DETERMINISTIC_COLUMN_TYPE",
|
|
50
|
+
INVALID_MEMORY_OPTIONS = "INVALID_MEMORY_OPTIONS",
|
|
51
|
+
STORE_CAP_EXCEEDED = "STORE_CAP_EXCEEDED",
|
|
52
|
+
REGION_NOT_DECLARED = "REGION_NOT_DECLARED",
|
|
53
|
+
COMMAND_LOG_TAG_COLLISION = "COMMAND_LOG_TAG_COLLISION",
|
|
54
|
+
INVALID_FRAME_STEP = "INVALID_FRAME_STEP"
|
|
55
|
+
}
|
|
56
|
+
export declare class ECSError extends AppError {
|
|
57
|
+
readonly category: ECS_ERROR;
|
|
58
|
+
constructor(category: ECS_ERROR, message?: string, context?: Record<string, unknown>);
|
|
59
|
+
}
|
|
60
|
+
export declare function isEcsError(error: unknown): error is ECSError;
|
|
61
|
+
//# sourceMappingURL=error.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AppError } from '../../../utils/error';
|
|
1
|
+
import { AppError } from '../../../utils/error.js';
|
|
2
2
|
export declare enum ECS_ERROR {
|
|
3
3
|
EID_MAX_INDEX_OVERFLOW = "EID_MAX_INDEX_OVERFLOW",
|
|
4
4
|
EID_MAX_GEN_OVERFLOW = "EID_MAX_GEN_OVERFLOW",
|
|
@@ -31,17 +31,27 @@ export declare enum ECS_ERROR {
|
|
|
31
31
|
COMPONENT_INDEX_INVARIANT = "COMPONENT_INDEX_INVARIANT",
|
|
32
32
|
OPTIONAL_TERM_NOT_DECLARED = "OPTIONAL_TERM_NOT_DECLARED",
|
|
33
33
|
QUERY_ACCESS_UNDECLARED = "QUERY_ACCESS_UNDECLARED",
|
|
34
|
+
/** A system touched a component/sparse/relation/resource it didn't declare
|
|
35
|
+
* in its access surface — distinct from *_NOT_REGISTERED (which means the
|
|
36
|
+
* thing was never registered with the world at all). */
|
|
37
|
+
ACCESS_UNDECLARED = "ACCESS_UNDECLARED",
|
|
38
|
+
/** `Query.singleEntity` found 0 or >1 matches (dev-only assertion). */
|
|
39
|
+
QUERY_NOT_SINGLETON = "QUERY_NOT_SINGLETON",
|
|
40
|
+
/** A run-condition factory was given invalid arguments (dev-only). */
|
|
41
|
+
INVALID_RUN_CONDITION = "INVALID_RUN_CONDITION",
|
|
34
42
|
SYSTEM_FN_ARITY = "SYSTEM_FN_ARITY",
|
|
35
43
|
PARTITION_APPEND_NEEDS_ENTITY_ROW = "PARTITION_APPEND_NEEDS_ENTITY_ROW",
|
|
36
44
|
PARTITION_BULK_INTO_DISABLED = "PARTITION_BULK_INTO_DISABLED",
|
|
37
45
|
ENTITY_NOT_DISABLED = "ENTITY_NOT_DISABLED",
|
|
46
|
+
STRUCTURAL_DURING_ITERATION = "STRUCTURAL_DURING_ITERATION",
|
|
38
47
|
BACKEND_ALREADY_ATTACHED = "BACKEND_ALREADY_ATTACHED",
|
|
39
48
|
DETERMINISM_DISABLED = "DETERMINISM_DISABLED",
|
|
40
49
|
NON_DETERMINISTIC_COLUMN_TYPE = "NON_DETERMINISTIC_COLUMN_TYPE",
|
|
41
50
|
INVALID_MEMORY_OPTIONS = "INVALID_MEMORY_OPTIONS",
|
|
42
51
|
STORE_CAP_EXCEEDED = "STORE_CAP_EXCEEDED",
|
|
43
52
|
REGION_NOT_DECLARED = "REGION_NOT_DECLARED",
|
|
44
|
-
COMMAND_LOG_TAG_COLLISION = "COMMAND_LOG_TAG_COLLISION"
|
|
53
|
+
COMMAND_LOG_TAG_COLLISION = "COMMAND_LOG_TAG_COLLISION",
|
|
54
|
+
INVALID_FRAME_STEP = "INVALID_FRAME_STEP"
|
|
45
55
|
}
|
|
46
56
|
export declare class ECSError extends AppError {
|
|
47
57
|
readonly category: ECS_ERROR;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../../src/core/ecs/utils/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,oBAAY,SAAS;IACpB,sBAAsB,2BAA2B;IACjD,oBAAoB,yBAAyB;IAC7C,wBAAwB,6BAA6B;IACrD,wBAAwB,6BAA6B;IACrD,gBAAgB,qBAAqB;IACrC,0BAA0B,+BAA+B;IACzD,gBAAgB,qBAAqB;IACrC,mBAAmB,wBAAwB;IAC3C,uBAAuB,4BAA4B;IACnD,2BAA2B,gCAAgC;IAC3D,wBAAwB,6BAA6B;IACrD,oBAAoB,yBAAyB;IAC7C,oBAAoB,yBAAyB;IAC7C,uBAAuB,4BAA4B;IACnD,qBAAqB,0BAA0B;IAC/C,sBAAsB,2BAA2B;IACjD,cAAc,mBAAmB;IACjC,yBAAyB,8BAA8B;IACvD,uBAAuB,4BAA4B;IACnD,qBAAqB,0BAA0B;IAC/C,2BAA2B,gCAAgC;IAC3D,uBAAuB,4BAA4B;IACnD,uBAAuB,4BAA4B;IACnD,mBAAmB,wBAAwB;IAC3C,sBAAsB,2BAA2B;IACjD,uBAAuB,4BAA4B;IACnD,yBAAyB,8BAA8B;IACvD,2BAA2B,gCAAgC;IAC3D,yBAAyB,8BAA8B;IACvD,0BAA0B,+BAA+B;IACzD,uBAAuB,4BAA4B;IACnD,eAAe,oBAAoB;IACnC,iCAAiC,sCAAsC;IACvE,4BAA4B,iCAAiC;IAC7D,mBAAmB,wBAAwB;IAC3C,wBAAwB,6BAA6B;IACrD,oBAAoB,yBAAyB;IAC7C,6BAA6B,kCAAkC;IAC/D,sBAAsB,2BAA2B;IACjD,kBAAkB,uBAAuB;IACzC,mBAAmB,wBAAwB;IAC3C,yBAAyB,8BAA8B;
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../../src/core/ecs/utils/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,oBAAY,SAAS;IACpB,sBAAsB,2BAA2B;IACjD,oBAAoB,yBAAyB;IAC7C,wBAAwB,6BAA6B;IACrD,wBAAwB,6BAA6B;IACrD,gBAAgB,qBAAqB;IACrC,0BAA0B,+BAA+B;IACzD,gBAAgB,qBAAqB;IACrC,mBAAmB,wBAAwB;IAC3C,uBAAuB,4BAA4B;IACnD,2BAA2B,gCAAgC;IAC3D,wBAAwB,6BAA6B;IACrD,oBAAoB,yBAAyB;IAC7C,oBAAoB,yBAAyB;IAC7C,uBAAuB,4BAA4B;IACnD,qBAAqB,0BAA0B;IAC/C,sBAAsB,2BAA2B;IACjD,cAAc,mBAAmB;IACjC,yBAAyB,8BAA8B;IACvD,uBAAuB,4BAA4B;IACnD,qBAAqB,0BAA0B;IAC/C,2BAA2B,gCAAgC;IAC3D,uBAAuB,4BAA4B;IACnD,uBAAuB,4BAA4B;IACnD,mBAAmB,wBAAwB;IAC3C,sBAAsB,2BAA2B;IACjD,uBAAuB,4BAA4B;IACnD,yBAAyB,8BAA8B;IACvD,2BAA2B,gCAAgC;IAC3D,yBAAyB,8BAA8B;IACvD,0BAA0B,+BAA+B;IACzD,uBAAuB,4BAA4B;IACnD;;4DAEwD;IACxD,iBAAiB,sBAAsB;IACvC,uEAAuE;IACvE,mBAAmB,wBAAwB;IAC3C,sEAAsE;IACtE,qBAAqB,0BAA0B;IAC/C,eAAe,oBAAoB;IACnC,iCAAiC,sCAAsC;IACvE,4BAA4B,iCAAiC;IAC7D,mBAAmB,wBAAwB;IAC3C,2BAA2B,gCAAgC;IAC3D,wBAAwB,6BAA6B;IACrD,oBAAoB,yBAAyB;IAC7C,6BAA6B,kCAAkC;IAC/D,sBAAsB,2BAA2B;IACjD,kBAAkB,uBAAuB;IACzC,mBAAmB,wBAAwB;IAC3C,yBAAyB,8BAA8B;IACvD,kBAAkB,uBAAuB;CACzC;AAED,qBAAa,QAAS,SAAQ,QAAQ;aAEpB,QAAQ,EAAE,SAAS;gBAAnB,QAAQ,EAAE,SAAS,EACnC,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAIlC;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Action ring — main-thread producer / worker-thread consumer SPSC ring
|
|
3
|
+
* for client input intents (`send_action`-shaped bytes). Plan §6.5 task
|
|
4
|
+
* 3 / `docs/ideas/buffer-wasm-sim-plan-2026-05-14T1600.md`.
|
|
5
|
+
*
|
|
6
|
+
* Same on-the-wire shape as `command_ring.ts`, but with two practical
|
|
7
|
+
* differences:
|
|
8
|
+
*
|
|
9
|
+
* 1. Producer/consumer roles flip — the action ring is main → worker,
|
|
10
|
+
* whereas the command ring is sim → host.
|
|
11
|
+
* 2. Slot payload carries a `length` prefix because client actions are
|
|
12
|
+
* variable-width (the encoded bytes that would normally go straight
|
|
13
|
+
* to the WebSocket). `payload[0]` is the length in bytes; bytes
|
|
14
|
+
* `[1..1+length)` are the action payload itself.
|
|
15
|
+
*
|
|
16
|
+
* Layout (identical to command ring header):
|
|
17
|
+
*
|
|
18
|
+
* [ write_head: u32 ] monotonic; modulo `capacity_slots` for slot
|
|
19
|
+
* [ read_head: u32 ] monotonic
|
|
20
|
+
* [ capacity: u32 ] slot count, power-of-two
|
|
21
|
+
* [ overflow: u32 ] 0 = OK; 1 = ring exhausted (producer side)
|
|
22
|
+
* [ slot 0: 16 B ] length: u8, payload: [15]u8
|
|
23
|
+
* [ slot 1: 16 B ] ...
|
|
24
|
+
*
|
|
25
|
+
* SPSC contract:
|
|
26
|
+
* - Producer: main thread, from `GameNetworkClient.send_action`. Pushes
|
|
27
|
+
* one entry per user action; `Atomics.store`s `write_head` after each.
|
|
28
|
+
* - Consumer: sim worker, drained on each `apply_diff` / `apply_snapshot`
|
|
29
|
+
* boundary. `Atomics.store`s `read_head` after each pop.
|
|
30
|
+
* - Today's consumer is a no-op observer (logs / counts in DEV) — the
|
|
31
|
+
* wire path still goes main → WebSocket → server. PR 5N migrates the
|
|
32
|
+
* `PredictionReconciler` into the worker so the action ring becomes
|
|
33
|
+
* load-bearing for client-side prediction.
|
|
34
|
+
*
|
|
35
|
+
* Overflow:
|
|
36
|
+
* - If main writes a slot when `(write_head - read_head) === capacity`,
|
|
37
|
+
* it sets `overflow = 1` and the push returns `false`. The server
|
|
38
|
+
* send path is independent (`_transport.send(...)` ran first), so an
|
|
39
|
+
* overflow doesn't drop the action — it only drops worker
|
|
40
|
+
* observability for that one entry.
|
|
41
|
+
*
|
|
42
|
+
* Atomics: the head fields (`write_head` / `read_head`) are the
|
|
43
|
+
* cross-thread synchronization edge — the producer runs on the main
|
|
44
|
+
* thread, the consumer in the sim worker, and both alias the same
|
|
45
|
+
* `SharedArrayBuffer`. The producer writes the slot bytes, then
|
|
46
|
+
* `Atomics.store`s `write_head`; the consumer `Atomics.load`s
|
|
47
|
+
* `write_head` before touching the slot, reads it, then `Atomics.store`s
|
|
48
|
+
* `read_head`. These SeqCst ops establish the happens-before that a
|
|
49
|
+
* plain `DataView` write does not under the JS memory model (#374):
|
|
50
|
+
* without them the worker could observe a bumped `write_head` before the
|
|
51
|
+
* producer's `setUint8(len)` + payload `set()` are visible and read a
|
|
52
|
+
* torn/stale slot, and the producer could read a stale `read_head`
|
|
53
|
+
* (false overflow, or overwrite a slot mid-read). Slot payload bytes
|
|
54
|
+
* stay on plain `DataView` / `Uint8Array` ops — the head Atomics fence
|
|
55
|
+
* them, so no per-byte atomic is needed. A future PR may still add an
|
|
56
|
+
* `Atomics.wait/notify` pair so the worker can block between actions
|
|
57
|
+
* instead of polling — additive change, no layout shift.
|
|
58
|
+
*/
|
|
59
|
+
/** Total bytes for the ring header. Identical to `command_ring`. */
|
|
60
|
+
export declare const ACTION_RING_HEADER_BYTES = 16;
|
|
61
|
+
/** Fixed slot size — 1-byte length + 15-byte payload. */
|
|
62
|
+
export declare const ACTION_RING_SLOT_BYTES = 16;
|
|
63
|
+
/** Default ring capacity in slots. Sized for ~250 ms of click-spam at 60
|
|
64
|
+
* Hz on the high end of human input rates; 256 × 16 B = 4 KiB + 16 B
|
|
65
|
+
* header. */
|
|
66
|
+
export declare const ACTION_RING_DEFAULT_CAPACITY_SLOTS = 256;
|
|
67
|
+
/** Max payload bytes per slot (slot size minus the length prefix). All
|
|
68
|
+
* actions defined in `packages/protocol/src/actions.ts` encode to under
|
|
69
|
+
* 8 bytes, so this is comfortably above today's max. */
|
|
70
|
+
export declare const ACTION_RING_MAX_PAYLOAD_BYTES: number;
|
|
71
|
+
/** Byte offsets within the ring header. Matches `command_ring` so a
|
|
72
|
+
* future shared helper can normalise across both rings without per-ring
|
|
73
|
+
* arithmetic. */
|
|
74
|
+
export declare const ACTION_RING_HEADER_OFFSETS: {
|
|
75
|
+
readonly write_head: 0;
|
|
76
|
+
readonly read_head: 4;
|
|
77
|
+
readonly capacity_slots: 8;
|
|
78
|
+
readonly overflow_flag: 12;
|
|
79
|
+
};
|
|
80
|
+
/** Total bytes the ring occupies for `capacity_slots` slots. */
|
|
81
|
+
export declare function actionRingBytes(capacitySlots: number): number;
|
|
82
|
+
export declare class ActionRingError extends Error {
|
|
83
|
+
constructor(message: string);
|
|
84
|
+
}
|
|
85
|
+
/** Initialise the ring header at `ringOff` in the SAB. Zeroes heads
|
|
86
|
+
* and the overflow flag; sets `capacity_slots`. Slot bytes are left
|
|
87
|
+
* as-is (callers normally allocate the ring on a zero-initialised SAB). */
|
|
88
|
+
export declare function initActionRing(view: DataView, ringOff: number, capacitySlots: number): void;
|
|
89
|
+
/** Read live ring-header fields. Heads are stored signed but returned
|
|
90
|
+
* unsigned (`>>> 0`) so the monotonic-counter arithmetic below is
|
|
91
|
+
* identical to the prior `getUint32` behaviour. */
|
|
92
|
+
export declare function actionRingWriteHead(view: DataView, ringOff: number): number;
|
|
93
|
+
export declare function actionRingReadHead(view: DataView, ringOff: number): number;
|
|
94
|
+
export declare function actionRingCapacitySlots(view: DataView, ringOff: number): number;
|
|
95
|
+
export declare function actionRingOverflow(view: DataView, ringOff: number): boolean;
|
|
96
|
+
/** Pending entry count = `(write_head - read_head) mod 2^32`. */
|
|
97
|
+
export declare function pendingActionCount(view: DataView, ringOff: number): number;
|
|
98
|
+
/** Push an action into the ring. `payload` must be in
|
|
99
|
+
* `[1, ACTION_RING_MAX_PAYLOAD_BYTES]`; longer payloads — and **empty**
|
|
100
|
+
* ones — are an `ActionRingError` (the producer is the only caller and it
|
|
101
|
+
* can size its inputs ahead of time). The zero-length rejection closes the
|
|
102
|
+
* lower-bound footgun: a 0-byte slot is indistinguishable from
|
|
103
|
+
* `popAction`'s empty-ring sentinel (`0`), so admitting one would let it
|
|
104
|
+
* masquerade as "ring empty". No encoder produces a 0-byte payload, so this
|
|
105
|
+
* only ever rejects the ABI-skew bug case (#430). Returns `false` on
|
|
106
|
+
* overflow and sets the overflow flag. */
|
|
107
|
+
export declare function pushAction(view: DataView, ringOff: number, payload: Uint8Array): boolean;
|
|
108
|
+
/** Pop one action from the ring. Returns the byte length written into
|
|
109
|
+
* `outPayload`, or `0` if the ring was empty. `outPayload` must be at
|
|
110
|
+
* least `ACTION_RING_MAX_PAYLOAD_BYTES`; only the first `length` bytes
|
|
111
|
+
* are meaningful after a non-zero return.
|
|
112
|
+
*
|
|
113
|
+
* NOTE: a `0` return is ambiguous — it means "ring empty" OR "a 0-byte
|
|
114
|
+
* slot" (the latter only reachable via ABI-skew, since `pushAction`
|
|
115
|
+
* rejects empty payloads). Callers that loop must decide emptiness from
|
|
116
|
+
* the heads (`pendingActionCount` / `write_head === read_head`), not
|
|
117
|
+
* from this return value; see `drainActionRing` and #430. */
|
|
118
|
+
export declare function popAction(view: DataView, ringOff: number, outPayload: Uint8Array): number;
|
|
119
|
+
/** Drain every pending action, invoking `handler(payload)` per entry.
|
|
120
|
+
* The `payload` passed to the handler is a freshly-copied
|
|
121
|
+
* `Uint8Array(length)` so handlers can hold it past the next pop without
|
|
122
|
+
* aliasing the scratch buffer. Returns the number of actions drained.
|
|
123
|
+
*
|
|
124
|
+
* Termination is decided from the heads (`pendingActionCount`), NOT from
|
|
125
|
+
* `popAction`'s return value. A genuine 0-byte slot returns `0` — the same
|
|
126
|
+
* value `popAction` yields on an empty ring — so terminating on `len === 0`
|
|
127
|
+
* would silently consume the zero-length entry and strand everything queued
|
|
128
|
+
* behind it for a tick (#430). The heads check is SPSC-safe: this consumer
|
|
129
|
+
* is the sole reader, so a non-zero pending count cannot race to empty before
|
|
130
|
+
* the `popAction` below. */
|
|
131
|
+
export declare function drainActionRing(view: DataView, ringOff: number, handler: (payload: Uint8Array) => void): number;
|
|
132
|
+
/** Clear the overflow flag. The producer sets it on a failed push; the
|
|
133
|
+
* consumer can reset it once it has observed and logged the condition,
|
|
134
|
+
* so a single overflow doesn't keep firing dev assertions. */
|
|
135
|
+
export declare function clearActionRingOverflow(view: DataView, ringOff: number): void;
|
|
136
|
+
//# sourceMappingURL=action_ring.d.ts.map
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BufferAllocator — pluggable buffer source for the SAB layer (#234 / PR 3D).
|
|
3
|
+
*
|
|
4
|
+
* The engine has historically allocated its SAB as a fresh
|
|
5
|
+
* `new SharedArrayBuffer(totalBytes)` inside `createColumnStore`.
|
|
6
|
+
* Phase 3D requires the SAB to optionally be backed by a
|
|
7
|
+
* `WebAssembly.Memory.buffer` so the WASM sim can read/write the live
|
|
8
|
+
* ECS columns through its own memory handle. This module abstracts the
|
|
9
|
+
* "where does the buffer come from" decision behind a single function
|
|
10
|
+
* type.
|
|
11
|
+
*
|
|
12
|
+
* Contract for every `BufferAllocator`:
|
|
13
|
+
* - Returns a `SharedArrayBuffer` of byteLength >= `bytes`.
|
|
14
|
+
* - MAY detach any prior buffer the implementation has handed out
|
|
15
|
+
* (e.g., `WebAssembly.Memory.grow` detaches existing typed-array
|
|
16
|
+
* views into the previous buffer). Callers MUST snapshot any data
|
|
17
|
+
* they need to preserve BEFORE invoking the allocator.
|
|
18
|
+
* - Returned buffers MAY be larger than `bytes` (e.g., wasm-memory
|
|
19
|
+
* rounds up to 64 KiB page boundaries). Callers must rely on the
|
|
20
|
+
* SAB header / descriptor for the canonical layout, not on
|
|
21
|
+
* `buffer.byteLength`.
|
|
22
|
+
*
|
|
23
|
+
* The default `DEFAULT_SAB_ALLOCATOR` does `new SharedArrayBuffer(bytes)`
|
|
24
|
+
* — fast, allocation-per-call, prior buffers untouched. Production code
|
|
25
|
+
* paths that don't care about wasm interop stay on this.
|
|
26
|
+
*
|
|
27
|
+
* `wasmMemoryAllocator(memory)` returns an allocator that grows the
|
|
28
|
+
* given `WebAssembly.Memory` (in 64 KiB page increments) as needed and
|
|
29
|
+
* returns its current buffer. Used by a host so the
|
|
30
|
+
* engine's SAB IS the sim's memory.
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* Source of `SharedArrayBuffer`s for the SAB layer. See the file header
|
|
34
|
+
* for the contract — in particular, the detachment caveat for in-place
|
|
35
|
+
* implementations.
|
|
36
|
+
*
|
|
37
|
+
* The optional `isInPlace` marker tells the SAB layer that
|
|
38
|
+
* **TypedArray and DataView views built over a returned buffer remain
|
|
39
|
+
* valid after a subsequent allocator call** — reads and writes through
|
|
40
|
+
* the old views land on the same underlying memory the new buffer
|
|
41
|
+
* exposes. The `extendColumnStore` fast path uses this hint to skip the
|
|
42
|
+
* snapshot+restore + view-rebuild work that's only necessary when the
|
|
43
|
+
* memory actually moves.
|
|
44
|
+
*
|
|
45
|
+
* Note: `isInPlace` does NOT promise the SAB *reference* stays
|
|
46
|
+
* identical. `growableSabAllocator` happens to return the same SAB
|
|
47
|
+
* instance every time (`SharedArrayBuffer.prototype.grow` resizes in
|
|
48
|
+
* place); `wasmMemoryAllocator` on shared `WebAssembly.Memory`
|
|
49
|
+
* returns a *new* SAB ref after `memory.grow()`, but old views built
|
|
50
|
+
* over the previous ref keep working — V8 keeps the underlying linear
|
|
51
|
+
* memory mapped at the same address. Verified empirically (this branch,
|
|
52
|
+
* Bun + V8): writes via an old `Int32Array(old_ref, off, len)` after
|
|
53
|
+
* `memory.grow()` are visible through a fresh view over the new ref,
|
|
54
|
+
* and vice versa. Default allocator omits the marker;
|
|
55
|
+
* `growableSabAllocator` and `wasmMemoryAllocator` set it.
|
|
56
|
+
*/
|
|
57
|
+
export interface BufferAllocator {
|
|
58
|
+
/** Returns a buffer of byteLength >= `bytes`. The historical name is
|
|
59
|
+
* "SAB", but the return is `ArrayBufferLike`: `growableSabAllocator` /
|
|
60
|
+
* `wasmMemoryAllocator` produce a `SharedArrayBuffer` (the SAB profile),
|
|
61
|
+
* while `heapArraybufferAllocator` produces a plain resizable
|
|
62
|
+
* `ArrayBuffer` (the pure-TS heap profile — no cross-origin isolation
|
|
63
|
+
* required). The store layer treats the backing uniformly; only the
|
|
64
|
+
* WASM/worker boundary narrows back to `SharedArrayBuffer`. */
|
|
65
|
+
(bytes: number): ArrayBufferLike;
|
|
66
|
+
readonly isInPlace?: boolean;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The only allocator shape a **live `Store`** accepts (#682). ADR-0008 makes
|
|
70
|
+
* "a live Store is backed by an in-place allocator" a correctness invariant —
|
|
71
|
+
* the flush loops hoist entity-index views across grows. This brand moves
|
|
72
|
+
* that invariant from runtime convention to the type/construction boundary:
|
|
73
|
+
* `growableSabAllocator` / `wasmMemoryAllocator` / `heapArraybufferAllocator`
|
|
74
|
+
* return it; `DEFAULT_SAB_ALLOCATOR` keeps the wide `BufferAllocator` type and
|
|
75
|
+
* therefore cannot typecheck where a live-Store backing is required. Non-in-place
|
|
76
|
+
* allocators remain valid for snapshot/test sizing only. The brand says nothing
|
|
77
|
+
* about *shared* vs *heap* backing — `heapArraybufferAllocator`'s resizable
|
|
78
|
+
* `ArrayBuffer` is just as in-place as a growable SAB (`.resize()` preserves
|
|
79
|
+
* existing views exactly like `SharedArrayBuffer.prototype.grow`).
|
|
80
|
+
*/
|
|
81
|
+
export type InPlaceBufferAllocator = BufferAllocator & {
|
|
82
|
+
readonly isInPlace: true;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Thrown when an allocator cannot satisfy a request because its by-design
|
|
86
|
+
* byte ceiling is reached (#380: the cap is a runaway-growth signal, not a
|
|
87
|
+
* limit to paper over — there is deliberately no grow-beyond-cap fallback).
|
|
88
|
+
* Typed so `Store`'s grow handler can recognise the cap case and re-throw
|
|
89
|
+
* with the caller's declared sizing intent attached (#682) without ever
|
|
90
|
+
* catching-to-recover.
|
|
91
|
+
*/
|
|
92
|
+
export declare class StoreCapExceededError extends Error {
|
|
93
|
+
readonly requestedBytes: number;
|
|
94
|
+
/** `null` when the ceiling isn't knowable from JS (a shared
|
|
95
|
+
* `WebAssembly.Memory` doesn't expose its `maximum`). */
|
|
96
|
+
readonly capBytes: number | null;
|
|
97
|
+
constructor(message: string, requestedBytes: number,
|
|
98
|
+
/** `null` when the ceiling isn't knowable from JS (a shared
|
|
99
|
+
* `WebAssembly.Memory` doesn't expose its `maximum`). */
|
|
100
|
+
capBytes: number | null, options?: ErrorOptions);
|
|
101
|
+
}
|
|
102
|
+
/** Thrown when a **SAB-producing** allocator runs in an environment that
|
|
103
|
+
* doesn't expose `SharedArrayBuffer`. The fix is environment-level (the host
|
|
104
|
+
* must serve the page cross-origin isolated, or be a runtime like Bun that
|
|
105
|
+
* exposes SAB unconditionally) — OR choose the pure-TS heap profile
|
|
106
|
+
* (`memory: { heap: {} }` / `heapArraybufferAllocator`), which needs no SAB
|
|
107
|
+
* and no cross-origin isolation. Lives on the allocator (not the store)
|
|
108
|
+
* because the allocator is the only thing that constructs a SAB. */
|
|
109
|
+
export declare class SabUnavailableError extends Error {
|
|
110
|
+
constructor();
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Allocate a fresh `SharedArrayBuffer` per call. Prior buffers are
|
|
114
|
+
* untouched and remain valid for as long as the caller holds references.
|
|
115
|
+
* This is the default used by `createColumnStore` when no allocator is
|
|
116
|
+
* provided. Throws `SabUnavailableError` in a runtime without SAB — the
|
|
117
|
+
* availability check lives here (the SAB-producing seam), not in
|
|
118
|
+
* `createColumnStore`, so a heap allocator never trips it.
|
|
119
|
+
*/
|
|
120
|
+
export declare const DEFAULT_SAB_ALLOCATOR: BufferAllocator;
|
|
121
|
+
/**
|
|
122
|
+
* Allocator that backs the SAB by a single growable `SharedArrayBuffer`
|
|
123
|
+
* (created with `{ maxByteLength: maxBytes }`). First call allocates;
|
|
124
|
+
* subsequent calls `.grow(bytes)` the existing buffer and return it.
|
|
125
|
+
*
|
|
126
|
+
* The `isInPlace` marker is set so `extendColumnStore` knows it can
|
|
127
|
+
* reuse the buffer rather than allocating fresh and copying data —
|
|
128
|
+
* existing typed-array views built with explicit `(byteOffset, length)`
|
|
129
|
+
* stay valid after `.grow()` in Bun + V8 (the underlying mapping extends
|
|
130
|
+
* in place rather than relocating).
|
|
131
|
+
*
|
|
132
|
+
* Sizing: `maxBytes` is committed *virtual* memory, not resident RAM —
|
|
133
|
+
* physical pages fault in lazily as the SAB actually grows. Larger caps
|
|
134
|
+
* cost more per allocation than smaller ones — Bun benchmark
|
|
135
|
+
* `alloc(64,max=1GB)+grow(65568)` measures ~32 µs vs ~21 µs at 256 MB
|
|
136
|
+
* and ~12 µs at 1 MB (V8 per-byte bookkeeping at construction).
|
|
137
|
+
* Production callers with bigger worlds can pass a larger cap; the bench
|
|
138
|
+
* gains are ~10 µs/Store-construction by staying under 256 MB.
|
|
139
|
+
*
|
|
140
|
+
* THE 256 MiB DEFAULT IS A HARD DESIGN CEILING, NOT A SOFT TARGET — and
|
|
141
|
+
* exceeding it is INTENDED to be fatal. There is deliberately no
|
|
142
|
+
* grow-beyond-cap fallback or compaction pass (see #380, and the loud
|
|
143
|
+
* note at the `bytes > maxBytes` throw below). If you are here because
|
|
144
|
+
* a workload died at the cap and you are tempted to add a fresh-allocator
|
|
145
|
+
* realloc fallback: don't, unless the numbers below have changed. They
|
|
146
|
+
* say the cap is structurally unreachable for a real workload.
|
|
147
|
+
*
|
|
148
|
+
* Measured footprint of a real 2-party workload (instrumented, 2026-05;
|
|
149
|
+
* do NOT trust the old "~500 archetypes × 64-capacity ≈ 2 MiB" figure
|
|
150
|
+
* that used to live here — it was wrong on every term):
|
|
151
|
+
* - Total SAB capacity ≈ 16.2 MiB — ~6% of the cap.
|
|
152
|
+
* - ~12 MiB of that is the entity-index region's *virtual* reservation
|
|
153
|
+
* (`ENTITY_INDEX_DEFAULT_CAPACITY = 1<<20` slots × 12 B); only ~12 KiB
|
|
154
|
+
* of it is physically resident for a 1000-entity workload.
|
|
155
|
+
* - Only ~5 archetypes are prewarmed (no lazy archetypes), each at
|
|
156
|
+
* `DEFAULT_COLUMN_CAPACITY = 1024` rows — NOT 64. Live column data is
|
|
157
|
+
* ~0.1 MiB; a fully-populated entity row is ~49 B.
|
|
158
|
+
* - Columns never trigger a grow: 1024 initial capacity already covers the
|
|
159
|
+
* ~1000-row budget, so the doubling + in-place hole tax never fires on
|
|
160
|
+
* the hot path.
|
|
161
|
+
* The entity-ID space itself caps total live entities at `1<<20` ≈ 1M
|
|
162
|
+
* (20-bit index in `EntityID`). Even at that absolute ceiling — ~1M rows
|
|
163
|
+
* × 49 B × ~3 (post-double capacity + abandoned holes) ≈ ~150 MiB columns
|
|
164
|
+
* + 12 MiB index — the workload still lands under 256 MiB. You cannot reach
|
|
165
|
+
* the cap without first exhausting the entity-ID space. Hitting it
|
|
166
|
+
* therefore signals a real defect upstream (runaway entity creation), not
|
|
167
|
+
* a sizing shortfall to paper over.
|
|
168
|
+
*
|
|
169
|
+
* Cited verification (#237 audit, this branch): Bun runtime check
|
|
170
|
+
* confirms `new Int32Array(buffer, off, len)` retains identical byteOffset,
|
|
171
|
+
* length, and stored values after `.grow()`; DataView byteLength
|
|
172
|
+
* auto-tracks the grown buffer.
|
|
173
|
+
*
|
|
174
|
+
* Used by the `extendColumnStore` fast path during lazy archetype
|
|
175
|
+
* registration (#237 Option A) — keeps existing column views valid so
|
|
176
|
+
* `refreshViews` is a no-op for old archetypes.
|
|
177
|
+
*/
|
|
178
|
+
export declare function growableSabAllocator(maxBytes?: number): InPlaceBufferAllocator;
|
|
179
|
+
/**
|
|
180
|
+
* Allocator that backs the store by a single growable **plain `ArrayBuffer`**
|
|
181
|
+
* (created with `{ maxByteLength: maxBytes }`, grown via `.resize()`). This is
|
|
182
|
+
* the pure-TS **heap profile** — the oecs default and the answer to ADR-0018's
|
|
183
|
+
* deferred §1B: no `SharedArrayBuffer`, hence no cross-origin isolation
|
|
184
|
+
* (COOP/COEP) requirement, and no worker/WASM transfer (single-process worlds
|
|
185
|
+
* only). Otherwise identical to `growableSabAllocator`:
|
|
186
|
+
*
|
|
187
|
+
* - `isInPlace: true`. A resizable `ArrayBuffer`'s `.resize()` keeps the
|
|
188
|
+
* same buffer object and preserves existing TypedArray/DataView views, so
|
|
189
|
+
* the store's `extend`/`grow` fast path carries column views forward
|
|
190
|
+
* unchanged — exactly as `SharedArrayBuffer.prototype.grow` does. ADR-0008's
|
|
191
|
+
* entity-index-hoist-across-grow invariant holds identically.
|
|
192
|
+
* - same 256 MiB default cap with hard-ceiling semantics (#380): reaching it
|
|
193
|
+
* signals runaway growth upstream, not a limit to route around.
|
|
194
|
+
*
|
|
195
|
+
* Why a non-shared buffer suffices: `Atomics` live only on the cross-thread
|
|
196
|
+
* command/event/action rings, never on the core store path, so a single-process
|
|
197
|
+
* world needs no sharing. `stateHash` determinism works here too — FNV1a over
|
|
198
|
+
* column bytes is backing-agnostic.
|
|
199
|
+
*/
|
|
200
|
+
export declare function heapArraybufferAllocator(maxBytes?: number): InPlaceBufferAllocator;
|
|
201
|
+
/**
|
|
202
|
+
* Allocator that backs the SAB by `memory.buffer` — i.e. makes the engine's
|
|
203
|
+
* live SAB *be* a WASM module's `WebAssembly.Memory`. Grows the memory in
|
|
204
|
+
* 64 KiB page increments when `bytes` exceeds the current buffer.
|
|
205
|
+
*
|
|
206
|
+
* This is the **opt-in storage backing for the WASM path** (#625). A consumer
|
|
207
|
+
* that attaches a WASM `ComputeBackend` passes
|
|
208
|
+
* `bufferAllocator: wasmMemoryAllocator(memory)` so the Zig systems read/write
|
|
209
|
+
* the same bytes the host's columns live in — zero-copy across the FFI boundary.
|
|
210
|
+
* It is NOT a match-context assumption: a pure-TS game omits `bufferAllocator` and
|
|
211
|
+
* gets the default (`DEFAULT_SAB_ALLOCATOR` — a fresh `SharedArrayBuffer` per
|
|
212
|
+
* alloc) or opts into `growableSabAllocator` for the in-place fast path
|
|
213
|
+
* without any WASM module. "The SAB is the WebAssembly.Memory" is thus a
|
|
214
|
+
* property the WASM backend opts into, paid for only when WASM is in use.
|
|
215
|
+
*
|
|
216
|
+
* After `memory.grow()` on a *shared* memory, `memory.buffer` returns a
|
|
217
|
+
* new `SharedArrayBuffer` reference, but **TypedArrays and DataViews
|
|
218
|
+
* built over the previous reference remain valid** — V8 keeps the
|
|
219
|
+
* underlying linear memory mapped at the same address, so reads and
|
|
220
|
+
* writes through old views land on the same bytes the new buffer
|
|
221
|
+
* exposes. This is why `isInPlace: true` is safe here (verified
|
|
222
|
+
* empirically against Bun + V8): the SAB layer's fast path can carry
|
|
223
|
+
* forward existing column views across an `extend` without paying for
|
|
224
|
+
* snapshot+restore. Old DataViews' `byteLength` is frozen at the
|
|
225
|
+
* pre-grow size, so callers needing to write past that boundary must
|
|
226
|
+
* construct a fresh DataView over the post-grow buffer (the SAB-layer
|
|
227
|
+
* extend path does this).
|
|
228
|
+
*
|
|
229
|
+
* Throws if `memory` was not constructed with `shared: true` — the SAB
|
|
230
|
+
* contract requires `SharedArrayBuffer`-backed memory. Throws a contextual
|
|
231
|
+
* error if a needed grow fails (cap reached or host refusal): the JS API's
|
|
232
|
+
* `memory.grow` throws a RangeError on cap overrun rather than returning the
|
|
233
|
+
* core wasm instruction's `-1`, and both are normalised into that error. The
|
|
234
|
+
* caller should construct memory with a `maximum` large enough for the
|
|
235
|
+
* workload's worst-case capacity.
|
|
236
|
+
*/
|
|
237
|
+
export declare function wasmMemoryAllocator(memory: WebAssembly.Memory): InPlaceBufferAllocator;
|
|
238
|
+
//# sourceMappingURL=allocator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"allocator.d.ts","sourceRoot":"","sources":["../../../src/core/store/allocator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,WAAW,eAAe;IAC/B;;;;;;mEAM+D;IAC/D,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAAC;IACjC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,sBAAsB,GAAG,eAAe,GAAG;IAAE,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAA;CAAE,CAAC;AAEpF;;;;;;;GAOG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;aAG9B,cAAc,EAAE,MAAM;IACtC;6DACyD;aACzC,QAAQ,EAAE,MAAM,GAAG,IAAI;gBAJvC,OAAO,EAAE,MAAM,EACC,cAAc,EAAE,MAAM;IACtC;6DACyD;IACzC,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvC,OAAO,CAAC,EAAE,YAAY;CAKvB;AAED;;;;;;oEAMoE;AACpE,qBAAa,mBAAoB,SAAQ,KAAK;;CAe7C;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,EAAE,eAGnC,CAAC;
|
|
1
|
+
{"version":3,"file":"allocator.d.ts","sourceRoot":"","sources":["../../../src/core/store/allocator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,WAAW,eAAe;IAC/B;;;;;;mEAM+D;IAC/D,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAAC;IACjC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,sBAAsB,GAAG,eAAe,GAAG;IAAE,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAA;CAAE,CAAC;AAEpF;;;;;;;GAOG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;aAG9B,cAAc,EAAE,MAAM;IACtC;6DACyD;aACzC,QAAQ,EAAE,MAAM,GAAG,IAAI;gBAJvC,OAAO,EAAE,MAAM,EACC,cAAc,EAAE,MAAM;IACtC;6DACyD;IACzC,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvC,OAAO,CAAC,EAAE,YAAY;CAKvB;AAED;;;;;;oEAMoE;AACpE,qBAAa,mBAAoB,SAAQ,KAAK;;CAe7C;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,EAAE,eAGnC,CAAC;AA+DF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,GAAE,MAA0B,GAAG,sBAAsB,CA6BjG;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,wBAAwB,CACvC,QAAQ,GAAE,MAA0B,GAClC,sBAAsB,CAuBxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,GAAG,sBAAsB,CA6DtF"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { ColumnBacking } from '../../type_primitives/index.cjs';
|
|
2
|
+
import { AnyTypedArray } from './column_store.cjs';
|
|
3
|
+
/** Thrown when an operation would grow a fixed-capacity SAB column. The
|
|
4
|
+
* grow path (re-allocate the SAB, bump `view_stamp`, rebuild views) is a
|
|
5
|
+
* separate sub-task; until it lands, hitting capacity is a hard error so
|
|
6
|
+
* the symptom surfaces immediately rather than silently corrupting state. */
|
|
7
|
+
export declare class StoreColumnOverflowError extends Error {
|
|
8
|
+
readonly capacity: number;
|
|
9
|
+
readonly requested: number;
|
|
10
|
+
constructor(capacity: number, requested: number);
|
|
11
|
+
}
|
|
12
|
+
export declare class BufferBackedColumn<T extends AnyTypedArray> implements ColumnBacking<T> {
|
|
13
|
+
private _buf;
|
|
14
|
+
private _capacity;
|
|
15
|
+
private _len;
|
|
16
|
+
/** `view` MUST be a TypedArray constructed over a SAB at the correct
|
|
17
|
+
* stride alignment (see `createColumnStore`). The column treats
|
|
18
|
+
* `view.length` as the immutable capacity for the lifetime of this view —
|
|
19
|
+
* call `refreshView` after a SAB realloc to point at the new view. */
|
|
20
|
+
constructor(view: T);
|
|
21
|
+
/** Swap the backing view to one over a freshly-grown SAB. The caller is
|
|
22
|
+
* responsible for having copied the first `length` elements into
|
|
23
|
+
* `newView` already (`growColumnStore` does this). The logical length is
|
|
24
|
+
* preserved across the swap; capacity becomes `newView.length`.
|
|
25
|
+
*
|
|
26
|
+
* Used to honour the `view_stamp` invariant after a host-side SAB realloc
|
|
27
|
+
* (#171 §6.1.4 / §8.1): every cached column view must be rebuilt before
|
|
28
|
+
* the next read/write. */
|
|
29
|
+
refreshView(newView: T): void;
|
|
30
|
+
get length(): number;
|
|
31
|
+
get capacity(): number;
|
|
32
|
+
push(value: number): void;
|
|
33
|
+
pop(): number;
|
|
34
|
+
get(i: number): number;
|
|
35
|
+
setAt(i: number, value: number): void;
|
|
36
|
+
/** Move the last element into slot `i`, decrement length. Returns the
|
|
37
|
+
* value previously at slot `i`. Matches `GrowableTypedArray.swapRemove`. */
|
|
38
|
+
swapRemove(i: number): number;
|
|
39
|
+
clear(): void;
|
|
40
|
+
/** Set the logical length directly, declaring that `[0, len)` of the backing
|
|
41
|
+
* SAB view already holds valid data. The snapshot-mount path
|
|
42
|
+
* (`Archetype.restoreHostRows`, #789) uses this to re-sync the column's
|
|
43
|
+
* logical length with the restored `Archetype.length` — the bytes come from
|
|
44
|
+
* the restored SAB, but `_len` is host state. Throws on overrun (cannot grow
|
|
45
|
+
* a fixed SAB view here — the mount already adopted the restored capacity). */
|
|
46
|
+
setLength(len: number): void;
|
|
47
|
+
/** Raw backing view. Stable for the lifetime of the SAB; views over a
|
|
48
|
+
* SAB do not invalidate the way a `GrowableTypedArray`'s `buf` does
|
|
49
|
+
* after a grow. (`view_stamp` will signal "underlying SAB swapped"
|
|
50
|
+
* once #171 §6.1.4 lands.) */
|
|
51
|
+
get buf(): T;
|
|
52
|
+
/** Zero-copy subarray of valid data (`0..length-1`). */
|
|
53
|
+
view(): T;
|
|
54
|
+
[Symbol.iterator](): Iterator<number>;
|
|
55
|
+
/** Throw if the backing view cannot hold `capacity` elements. Mirrors
|
|
56
|
+
* `GrowableTypedArray.ensureCapacity` but cannot allocate — a SAB
|
|
57
|
+
* grow requires republishing the underlying buffer and rebuilding views
|
|
58
|
+
* across every archetype, which is the §6.1.4 invariant. */
|
|
59
|
+
ensureCapacity(capacity: number): void;
|
|
60
|
+
/** Append `count` elements from `src[srcOffset..srcOffset+count]`.
|
|
61
|
+
* Throws on overrun. */
|
|
62
|
+
bulkAppend(src: T, srcOffset: number, count: number): void;
|
|
63
|
+
/** Append `count` zeroes. Throws on overrun. */
|
|
64
|
+
bulkAppendZeroes(count: number): void;
|
|
65
|
+
/** Append `count` copies of `value`. Throws on overrun. Single-pass
|
|
66
|
+
* analogue of `bulkAppendZeroes` for a non-zero default. */
|
|
67
|
+
bulkAppendValue(value: number, count: number): void;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=buffer_backed_column.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ColumnBacking } from '../../type_primitives';
|
|
2
|
-
import { AnyTypedArray } from './column_store';
|
|
1
|
+
import { ColumnBacking } from '../../type_primitives/index.js';
|
|
2
|
+
import { AnyTypedArray } from './column_store.js';
|
|
3
3
|
/** Thrown when an operation would grow a fixed-capacity SAB column. The
|
|
4
4
|
* grow path (re-allocate the SAB, bump `view_stamp`, rebuild views) is a
|
|
5
5
|
* separate sub-task; until it lands, hitting capacity is a hard error so
|