@oasys/oecs 0.4.0 → 0.5.1
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 +636 -0
- package/README.md +47 -32
- 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 +25 -13
- 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 +201 -0
- package/dist/core/ecs/component.d.ts +100 -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 +580 -0
- package/dist/core/ecs/ecs.d.ts +340 -293
- 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 +8 -2
- 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 +284 -0
- package/dist/core/ecs/host_commands.d.ts +77 -45
- 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 +44 -13
- package/dist/core/ecs/observer.d.ts.map +1 -1
- package/dist/core/ecs/query.d.cts +734 -0
- package/dist/core/ecs/query.d.ts +267 -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/ref.d.ts.map +1 -1
- 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 +16 -10
- 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 +937 -0
- package/dist/core/ecs/store.d.ts +144 -356
- 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 +2 -0
- package/dist/dev_flag.d.ts +2 -0
- package/dist/dev_flag.d.ts.map +1 -0
- package/dist/extensions/editor/editor.d.cts +172 -0
- package/dist/extensions/editor/editor.d.ts +65 -42
- 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 +10 -5
- 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 +130 -100
- 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-BI8pEmjH.js +2326 -0
- package/dist/host_commands-CxhpzMx9.cjs +1 -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 +4489 -5898
- 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
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ or a WASM compute backend; both profiles share one core and agree, byte-for-byte
|
|
|
12
12
|
|
|
13
13
|
- **Fast** — struct-of-arrays column storage grouped by archetype; iteration is a tight loop over typed
|
|
14
14
|
arrays with no per-entity object allocation.
|
|
15
|
-
- **Type-safe** —
|
|
15
|
+
- **Type-safe** — component handles are callable defs with stable numeric ids at runtime and fully-typed schemas at compile time;
|
|
16
16
|
misspelled fields are compile errors.
|
|
17
17
|
- **Deterministic** — an opt-in mode gives a backing-agnostic `stateHash` plus snapshot/restore and
|
|
18
18
|
command-log replay.
|
|
@@ -28,22 +28,25 @@ deno add jsr:@oasys/oecs # JSR (Deno)
|
|
|
28
28
|
npx jsr add @oasys/oecs # JSR (npm-compatible)
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
Requires a runtime with resizable `ArrayBuffer` (the default heap profile grows in place):
|
|
32
|
+
Node ≥ 20, Deno ≥ 1.38, Chrome 111+, Firefox 128+, Safari 16.4+.
|
|
33
|
+
|
|
31
34
|
## Quick start
|
|
32
35
|
|
|
33
36
|
```ts
|
|
34
37
|
import { ECS, SCHEDULE } from "@oasys/oecs";
|
|
35
38
|
|
|
36
|
-
const
|
|
39
|
+
const ecs = new ECS(); // pure-TS heap profile — no SharedArrayBuffer needed
|
|
37
40
|
|
|
38
41
|
// Components — record syntax (per-field type) or array shorthand (defaults to "f64")
|
|
39
|
-
const Pos =
|
|
40
|
-
const Vel =
|
|
42
|
+
const Pos = ecs.registerComponent({ x: "f64", y: "f64" });
|
|
43
|
+
const Vel = ecs.registerComponent(["vx", "vy"] as const);
|
|
41
44
|
|
|
42
45
|
// A query is a live, cached view over matching archetypes — build it once, reuse it.
|
|
43
|
-
const movers =
|
|
46
|
+
const movers = ecs.query(Pos, Vel);
|
|
44
47
|
|
|
45
48
|
// Systems declare the components they read/write (checked in dev builds).
|
|
46
|
-
const move =
|
|
49
|
+
const move = ecs.registerSystem({
|
|
47
50
|
reads: [Vel],
|
|
48
51
|
writes: [Pos], // a declared write implies read of the same component
|
|
49
52
|
fn: (ctx, dt) => {
|
|
@@ -58,15 +61,15 @@ const move = world.registerSystem({
|
|
|
58
61
|
},
|
|
59
62
|
});
|
|
60
63
|
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
ecs.addSystems(SCHEDULE.UPDATE, move);
|
|
65
|
+
ecs.startup();
|
|
63
66
|
|
|
64
|
-
const e =
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
const e = ecs.spawn();
|
|
68
|
+
ecs.addComponent(e, Pos, { x: 0, y: 0 });
|
|
69
|
+
ecs.addComponent(e, Vel, { vx: 100, vy: 50 });
|
|
67
70
|
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
ecs.update(1 / 60);
|
|
72
|
+
ecs.getField(e, Pos, "x"); // ≈ 1.667
|
|
70
73
|
```
|
|
71
74
|
|
|
72
75
|
## Features
|
|
@@ -75,16 +78,17 @@ world.getField(e, Pos, "x"); // ≈ 1.667
|
|
|
75
78
|
|
|
76
79
|
- **Archetype SoA storage** over a backing-neutral `ColumnStore` — entities with the same component set
|
|
77
80
|
share contiguous typed-array columns; cache-friendly loops, no per-entity object allocation.
|
|
78
|
-
- **Phantom-typed components** — `registerComponent({ x: "f64", y: "f64" })`
|
|
79
|
-
runtime and a fully-typed schema at compile time.
|
|
80
|
-
for uniform `f64`, and `registerTag()` for
|
|
81
|
+
- **Phantom-typed components** — `registerComponent({ x: "f64", y: "f64" })` returns a callable
|
|
82
|
+
`ComponentDef` with a stable numeric `.id` at runtime and a fully-typed schema at compile time.
|
|
83
|
+
Record syntax for per-field types, array shorthand for uniform `f64`, and `registerTag()` for
|
|
84
|
+
data-free markers. Field types: `f32 f64 i8 i16 i32 u8 u16 u32`.
|
|
81
85
|
- **Two storage profiles, one core** — pure-TS heap (`ArrayBuffer`) by default; opt-in
|
|
82
86
|
`SharedArrayBuffer` for workers / WASM. Same code path, same `stateHash`, sized through a single
|
|
83
87
|
`memory` surface (entity budget, byte cap, or pinned capacity).
|
|
84
88
|
|
|
85
89
|
**Queries**
|
|
86
90
|
|
|
87
|
-
- **Live, cached queries** — `
|
|
91
|
+
- **Live, cached queries** — `ecs.query(Pos, Vel)` refined with `.and()` / `.without()` / `.anyOf()`;
|
|
88
92
|
new matching archetypes are pushed in automatically.
|
|
89
93
|
- **Two iteration verbs** — `forEach(arch => …)` for read-only archetype iteration, `eachChunk((cols, count) => …)`
|
|
90
94
|
for the mutable hot path (`cols.mut` / `cols.read` resolve a whole component's columns at once).
|
|
@@ -98,7 +102,7 @@ world.getField(e, Pos, "x"); // ≈ 1.667
|
|
|
98
102
|
|
|
99
103
|
- **Declarative systems** — plain functions in a `SystemConfig` declaring `reads` / `writes`, enforced by
|
|
100
104
|
a dev-mode access checker (tree-shaken in production). Bare `(ctx, dt)` and `(q, ctx, dt)` +
|
|
101
|
-
query-builder overloads exist for access
|
|
105
|
+
query-builder overloads exist for no-access glue; lifecycle hooks `onAdded` / `onRemoved` / `dispose`;
|
|
102
106
|
`exclusive: true` for full-world setup/teardown.
|
|
103
107
|
- **Topological scheduler** — seven phases (`PRE_STARTUP` → `STARTUP` → `POST_STARTUP`, `FIXED_UPDATE`,
|
|
104
108
|
`PRE_UPDATE` → `UPDATE` → `POST_UPDATE`); per-phase Kahn sort by `before` / `after`, with insertion
|
|
@@ -109,17 +113,19 @@ world.getField(e, Pos, "x"); // ≈ 1.667
|
|
|
109
113
|
|
|
110
114
|
**Structural changes**
|
|
111
115
|
|
|
112
|
-
- **Deferred
|
|
113
|
-
|
|
114
|
-
`
|
|
116
|
+
- **Deferred inside systems, immediate on the host** — `ctx.commands` (a Bevy-`Commands`-style
|
|
117
|
+
facade) buffers add / remove / despawn / enable / disable until the phase flush, so iterators
|
|
118
|
+
stay valid (`commands.spawn` returns the id immediately; its component attaches are deferred). Every host-side mutation (`ecs.addComponent` / `removeComponent` /
|
|
119
|
+
`despawn` / `disable` / `enable`) applies immediately.
|
|
115
120
|
- **Entity enable/disable** — `disable` / `enable` / `isDisabled`; disabled rows sit in a partitioned
|
|
116
121
|
tail and are skipped by default queries.
|
|
117
|
-
- **Templates & bundles** — `
|
|
118
|
-
`
|
|
122
|
+
- **Templates & bundles** — `ecs.template(Pos({ x, y }), …)` blueprints consumed by `spawn` /
|
|
123
|
+
`spawnMany` for zero-transition spawns; the same callable-bundle varargs drive `spawnBundle(...)`
|
|
124
|
+
and `addComponents(...)`.
|
|
119
125
|
|
|
120
126
|
**Reactivity & relationships**
|
|
121
127
|
|
|
122
|
-
- **Observers** — `
|
|
128
|
+
- **Observers** — `ecs.observe(...)` for `onAdd` / `onRemove` / `onSet` / `onEnable` / `onDisable`,
|
|
123
129
|
structural or per-entity.
|
|
124
130
|
- **Relations** — `(relation, target)` pairs with `ChildOf` / `IsA` presets, exclusive / multi arities,
|
|
125
131
|
bidirectional queries (`targetOf` / `sourcesOf` / `ancestorsOf` / `rootOf` / `cascadeOf`), and
|
|
@@ -134,19 +140,20 @@ world.getField(e, Pos, "x"); // ≈ 1.667
|
|
|
134
140
|
|
|
135
141
|
**Determinism, persistence & integration**
|
|
136
142
|
|
|
137
|
-
- **Determinism** (opt-in) — `new ECS({ deterministic: true })`, then `
|
|
138
|
-
live
|
|
139
|
-
world and a shared world with identical history produce
|
|
140
|
-
|
|
143
|
+
- **Determinism** (opt-in) — `new ECS({ deterministic: true })`, then `ecs.snapshots.stateHash()` (an FNV-1a-style
|
|
144
|
+
32-bit digest over live dense bytes, sparse stores, and multi-relation target sets), `ecs.snapshots.capture()` /
|
|
145
|
+
`ecs.snapshots.restore(...)`, plus sparse variants. Backing-agnostic: a heap world and a shared world with identical history produce
|
|
146
|
+
identical hashes.
|
|
147
|
+
- **Host → ECS write seam** — `installHostCommandSeam(ecs)` applies typed `HostCommand`s off-schedule
|
|
141
148
|
via a blessed `exclusive` system, with record/replay (`HostCommandRecorder`, `replayCommandLog`) and a
|
|
142
149
|
cross-thread ring transport.
|
|
143
150
|
- **Reactive UI seam** (optional) — a zero-dep signals kernel (`@oasys/oecs/reactive`), an ECS→reactive
|
|
144
151
|
bridge that publishes only dirty entities/columns (`@oasys/oecs/reactive-sync`), and a SolidJS adapter
|
|
145
152
|
(`@oasys/oecs/solid`).
|
|
146
153
|
- **Editor layer** — undo/redo + field handles over the write seam (`@oasys/oecs/editor`).
|
|
147
|
-
- **Frame tracing** — `
|
|
154
|
+
- **Frame tracing** — `ecs.setTrace(sink)` + `FrameTraceRecorder` for a structured per-frame event
|
|
148
155
|
stream (dev-gated).
|
|
149
|
-
- **Compute backend seam** — `
|
|
156
|
+
- **Compute backend seam** — `ecs.attachBackend(...)` to run a system body on a compiled backend (WASM,
|
|
150
157
|
…) instead of its TS closure.
|
|
151
158
|
|
|
152
159
|
**Reference**
|
|
@@ -168,20 +175,26 @@ The core is `@oasys/oecs`; everything else is opt-in and costs nothing until imp
|
|
|
168
175
|
| `@oasys/oecs/editor` | undo/redo + field-handle layer over the host-write seam |
|
|
169
176
|
| `@oasys/oecs/solid` | SolidJS adapter (`solid-js` is an **optional** peer dependency) |
|
|
170
177
|
| `@oasys/oecs/primitives` | the standalone data structures oecs is built on |
|
|
178
|
+
| `@oasys/oecs/internal` | unstable internals (codecs, ABI constants, access checker) — **no semver guarantees** |
|
|
171
179
|
|
|
172
180
|
## Dev vs prod
|
|
173
181
|
|
|
174
182
|
A compile-time `__DEV__` flag gates every runtime check — bounds and liveness checks, duplicate-system
|
|
175
183
|
detection, registration validation, and the system access checker (`reads`/`writes`). These are
|
|
176
184
|
**tree-shaken out of production builds**, so treat "throws in dev" as a development tripwire, not a
|
|
177
|
-
production guarantee.
|
|
185
|
+
production guarantee. (Raw-source consumers — JSR/Deno — get `__DEV__ = true` by default; set
|
|
186
|
+
`globalThis.__DEV__ = false` to opt out.) The scheduler's cycle detection and constructor-option
|
|
187
|
+
validation (timestep, memory options, relation cardinality) are always active.
|
|
178
188
|
|
|
179
189
|
## Documentation
|
|
180
190
|
|
|
181
191
|
- **New to oecs?** Start with the [Getting Started](docs/GETTING_STARTED.md) tutorial, then
|
|
182
192
|
[Best Practices](docs/BEST_PRACTICES.md) and the [Architecture](docs/ARCHITECTURE.md) overview.
|
|
183
|
-
- **
|
|
193
|
+
- **Using optional extensions?** See the [Extensions guide](docs/EXTENSIONS.md) for reactive UI,
|
|
194
|
+
editor, Solid, shared-memory, and primitives usage.
|
|
195
|
+
- **Upgrading from 0.4?** See the [Migration guide (0.4 → 0.5)](docs/MIGRATION-0.4-to-0.5.md) and the
|
|
184
196
|
[CHANGELOG](CHANGELOG.md).
|
|
197
|
+
- **Upgrading from 0.3?** See the [Migration guide (0.3 → 0.4)](docs/MIGRATION-0.3-to-0.4.md).
|
|
185
198
|
- **Full API reference** — start at the [reference index](docs/api/index.md):
|
|
186
199
|
[components](docs/api/components.md) ·
|
|
187
200
|
[entities](docs/api/entities.md) ·
|
|
@@ -197,6 +210,8 @@ production guarantee. The scheduler's cycle detection is the one check that is a
|
|
|
197
210
|
[sparse storage](docs/api/sparse-storage.md) ·
|
|
198
211
|
[determinism](docs/api/determinism.md) ·
|
|
199
212
|
[memory](docs/api/memory.md) ·
|
|
213
|
+
[WASM backends](docs/api/wasm.md) ·
|
|
214
|
+
[parallelism](docs/api/parallel.md) ·
|
|
200
215
|
[host-write seam](docs/api/host-write-seam.md) ·
|
|
201
216
|
[reactive](docs/api/reactive.md) ·
|
|
202
217
|
[editor](docs/api/editor.md) ·
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { ComponentDef, ComponentHandle } from './component.cjs';
|
|
2
|
+
import { SparseComponentDef } from './sparse_store.cjs';
|
|
3
|
+
import { RelationDef } from './relation.cjs';
|
|
4
|
+
import { ResourceKey } from './resource.cjs';
|
|
5
|
+
import { SystemDescriptor } from './system.cjs';
|
|
6
|
+
interface AccessSets {
|
|
7
|
+
reads: Set<number>;
|
|
8
|
+
writes: Set<number>;
|
|
9
|
+
addAllowed: Set<number>;
|
|
10
|
+
removeAllowed: Set<number>;
|
|
11
|
+
hasDespawns: boolean;
|
|
12
|
+
resourceReads: Set<symbol>;
|
|
13
|
+
resourceWrites: Set<symbol>;
|
|
14
|
+
sparseReads: Set<number>;
|
|
15
|
+
sparseWrites: Set<number>;
|
|
16
|
+
relationReads: Set<number>;
|
|
17
|
+
relationWrites: Set<number>;
|
|
18
|
+
}
|
|
19
|
+
declare function setsFor(desc: SystemDescriptor): AccessSets;
|
|
20
|
+
/** The reads-only access surface a run condition declares (#576). A condition
|
|
21
|
+
* can only `reads` components (via a captured query) and `resourceReads`; every
|
|
22
|
+
* mutation set is empty by construction, so the same `check_*` machinery rejects
|
|
23
|
+
* any write/structural/resource-write a misbehaving predicate attempts. */
|
|
24
|
+
interface ConditionAccess {
|
|
25
|
+
readonly name: string;
|
|
26
|
+
readonly reads?: readonly ComponentDef[];
|
|
27
|
+
readonly resourceReads?: readonly ResourceKey<any>[];
|
|
28
|
+
}
|
|
29
|
+
declare class AccessCheck {
|
|
30
|
+
private active;
|
|
31
|
+
private sets;
|
|
32
|
+
private activeName;
|
|
33
|
+
private exclusive;
|
|
34
|
+
enter(desc: SystemDescriptor): void;
|
|
35
|
+
/** Open a reads-only span for a run condition (#576). No descriptor — a
|
|
36
|
+
* condition can gate a whole SystemSet, so it isn't attributable to one
|
|
37
|
+
* system — just its declared reads/resource_reads and a name for diagnostics.
|
|
38
|
+
* Paired with `leave()`. */
|
|
39
|
+
enterCondition(cond: ConditionAccess): void;
|
|
40
|
+
leave(): void;
|
|
41
|
+
isActive(): boolean;
|
|
42
|
+
/** Current system descriptor, if any. Null during a run-condition span. */
|
|
43
|
+
current(): SystemDescriptor | null;
|
|
44
|
+
checkRead(def: ComponentHandle): void;
|
|
45
|
+
checkWrite(def: ComponentHandle): void;
|
|
46
|
+
checkAdd(def: ComponentHandle): void;
|
|
47
|
+
checkRemove(def: ComponentHandle): void;
|
|
48
|
+
checkDestroy(): void;
|
|
49
|
+
checkResourceRead(key: ResourceKey<any>): void;
|
|
50
|
+
checkResourceWrite(key: ResourceKey<any>): void;
|
|
51
|
+
checkSparseRead(def: SparseComponentDef): void;
|
|
52
|
+
checkSparseWrite(def: SparseComponentDef): void;
|
|
53
|
+
checkRelationRead(def: RelationDef): void;
|
|
54
|
+
checkRelationWrite(def: RelationDef): void;
|
|
55
|
+
/** A `(*, T)` wildcard (`Query.forEachRelatedTo`, #579) reads every
|
|
56
|
+
* relation's reverse index, so it can't name a specific relation — it is
|
|
57
|
+
* authorised by the `ANY_RELATION` sentinel in `relationReads`. Honoured here
|
|
58
|
+
* exactly like a per-relation read, just keyed on the reserved sentinel id
|
|
59
|
+
* (which computeSets folds into `relationReads` like any other entry). */
|
|
60
|
+
checkRelationReadAny(): void;
|
|
61
|
+
private optionalScopes;
|
|
62
|
+
enterOptionalScope(optional: readonly number[]): void;
|
|
63
|
+
leaveOptionalScope(): void;
|
|
64
|
+
checkOptionalFetch(def: ComponentHandle): void;
|
|
65
|
+
private failComponent;
|
|
66
|
+
private failSparse;
|
|
67
|
+
private failRelation;
|
|
68
|
+
private failResource;
|
|
69
|
+
}
|
|
70
|
+
export declare const accessCheck: AccessCheck;
|
|
71
|
+
/** @internal — test seam for unit tests that need a fresh tracker. */
|
|
72
|
+
export declare const _accessCheckInternals: {
|
|
73
|
+
create: () => AccessCheck;
|
|
74
|
+
setsFor: typeof setsFor;
|
|
75
|
+
};
|
|
76
|
+
export {};
|
|
77
|
+
//# sourceMappingURL=access_check.d.ts.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ComponentDef, ComponentHandle } from './component';
|
|
2
|
-
import { SparseComponentDef } from './sparse_store';
|
|
3
|
-
import { RelationDef } from './relation';
|
|
4
|
-
import { ResourceKey } from './resource';
|
|
5
|
-
import { SystemDescriptor } from './system';
|
|
1
|
+
import { ComponentDef, ComponentHandle } from './component.js';
|
|
2
|
+
import { SparseComponentDef } from './sparse_store.js';
|
|
3
|
+
import { RelationDef } from './relation.js';
|
|
4
|
+
import { ResourceKey } from './resource.js';
|
|
5
|
+
import { SystemDescriptor } from './system.js';
|
|
6
6
|
interface AccessSets {
|
|
7
7
|
reads: Set<number>;
|
|
8
8
|
writes: Set<number>;
|
|
@@ -24,7 +24,7 @@ declare function setsFor(desc: SystemDescriptor): AccessSets;
|
|
|
24
24
|
interface ConditionAccess {
|
|
25
25
|
readonly name: string;
|
|
26
26
|
readonly reads?: readonly ComponentDef[];
|
|
27
|
-
readonly resourceReads?: readonly ResourceKey<
|
|
27
|
+
readonly resourceReads?: readonly ResourceKey<any>[];
|
|
28
28
|
}
|
|
29
29
|
declare class AccessCheck {
|
|
30
30
|
private active;
|
|
@@ -46,8 +46,8 @@ declare class AccessCheck {
|
|
|
46
46
|
checkAdd(def: ComponentHandle): void;
|
|
47
47
|
checkRemove(def: ComponentHandle): void;
|
|
48
48
|
checkDestroy(): void;
|
|
49
|
-
checkResourceRead(key: ResourceKey<
|
|
50
|
-
checkResourceWrite(key: ResourceKey<
|
|
49
|
+
checkResourceRead(key: ResourceKey<any>): void;
|
|
50
|
+
checkResourceWrite(key: ResourceKey<any>): void;
|
|
51
51
|
checkSparseRead(def: SparseComponentDef): void;
|
|
52
52
|
checkSparseWrite(def: SparseComponentDef): void;
|
|
53
53
|
checkRelationRead(def: RelationDef): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"access_check.d.ts","sourceRoot":"","sources":["../../../src/core/ecs/access_check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4BK;AAEL,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"access_check.d.ts","sourceRoot":"","sources":["../../../src/core/ecs/access_check.ts"],"names":[],"mappings":"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"}
|