@ecsia/core 0.1.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/LICENSE +21 -0
- package/README.md +29 -0
- package/dist/bitmask/bitmask.d.ts +21 -0
- package/dist/bitmask/bitmask.d.ts.map +1 -0
- package/dist/bitmask/bitmask.js +103 -0
- package/dist/bitmask/bitmask.js.map +1 -0
- package/dist/bitmask/index.d.ts +3 -0
- package/dist/bitmask/index.d.ts.map +1 -0
- package/dist/bitmask/index.js +2 -0
- package/dist/bitmask/index.js.map +1 -0
- package/dist/component/accessor.d.ts +40 -0
- package/dist/component/accessor.d.ts.map +1 -0
- package/dist/component/accessor.js +220 -0
- package/dist/component/accessor.js.map +1 -0
- package/dist/component/column-set.d.ts +20 -0
- package/dist/component/column-set.d.ts.map +1 -0
- package/dist/component/column-set.js +60 -0
- package/dist/component/column-set.js.map +1 -0
- package/dist/component/define.d.ts +23 -0
- package/dist/component/define.d.ts.map +1 -0
- package/dist/component/define.js +155 -0
- package/dist/component/define.js.map +1 -0
- package/dist/component/descriptors.d.ts +3 -0
- package/dist/component/descriptors.d.ts.map +1 -0
- package/dist/component/descriptors.js +147 -0
- package/dist/component/descriptors.js.map +1 -0
- package/dist/component/index.d.ts +10 -0
- package/dist/component/index.d.ts.map +1 -0
- package/dist/component/index.js +6 -0
- package/dist/component/index.js.map +1 -0
- package/dist/component/sidecar.d.ts +58 -0
- package/dist/component/sidecar.d.ts.map +1 -0
- package/dist/component/sidecar.js +136 -0
- package/dist/component/sidecar.js.map +1 -0
- package/dist/config.d.ts +55 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +70 -0
- package/dist/config.js.map +1 -0
- package/dist/entity/codec.d.ts +45 -0
- package/dist/entity/codec.d.ts.map +1 -0
- package/dist/entity/codec.js +53 -0
- package/dist/entity/codec.js.map +1 -0
- package/dist/entity/index-allocator.d.ts +46 -0
- package/dist/entity/index-allocator.d.ts.map +1 -0
- package/dist/entity/index-allocator.js +121 -0
- package/dist/entity/index-allocator.js.map +1 -0
- package/dist/entity/index.d.ts +13 -0
- package/dist/entity/index.d.ts.map +1 -0
- package/dist/entity/index.js +7 -0
- package/dist/entity/index.js.map +1 -0
- package/dist/entity/record.d.ts +28 -0
- package/dist/entity/record.d.ts.map +1 -0
- package/dist/entity/record.js +42 -0
- package/dist/entity/record.js.map +1 -0
- package/dist/entity/ref.d.ts +70 -0
- package/dist/entity/ref.d.ts.map +1 -0
- package/dist/entity/ref.js +104 -0
- package/dist/entity/ref.js.map +1 -0
- package/dist/entity/reservation.d.ts +12 -0
- package/dist/entity/reservation.d.ts.map +1 -0
- package/dist/entity/reservation.js +28 -0
- package/dist/entity/reservation.js.map +1 -0
- package/dist/entity/store.d.ts +60 -0
- package/dist/entity/store.d.ts.map +1 -0
- package/dist/entity/store.js +193 -0
- package/dist/entity/store.js.map +1 -0
- package/dist/env.d.ts +2 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +12 -0
- package/dist/env.js.map +1 -0
- package/dist/ids.d.ts +9 -0
- package/dist/ids.d.ts.map +1 -0
- package/dist/ids.js +8 -0
- package/dist/ids.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/inspect-surface.d.ts +27 -0
- package/dist/inspect-surface.d.ts.map +1 -0
- package/dist/inspect-surface.js +14 -0
- package/dist/inspect-surface.js.map +1 -0
- package/dist/internal.d.ts +19 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +19 -0
- package/dist/internal.js.map +1 -0
- package/dist/memory/allocU32.d.ts +25 -0
- package/dist/memory/allocU32.d.ts.map +1 -0
- package/dist/memory/allocU32.js +95 -0
- package/dist/memory/allocU32.js.map +1 -0
- package/dist/memory/buffers.d.ts +94 -0
- package/dist/memory/buffers.d.ts.map +1 -0
- package/dist/memory/buffers.js +308 -0
- package/dist/memory/buffers.js.map +1 -0
- package/dist/memory/index.d.ts +7 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +4 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/layout.d.ts +37 -0
- package/dist/memory/layout.d.ts.map +1 -0
- package/dist/memory/layout.js +116 -0
- package/dist/memory/layout.js.map +1 -0
- package/dist/query/compile.d.ts +73 -0
- package/dist/query/compile.d.ts.map +1 -0
- package/dist/query/compile.js +158 -0
- package/dist/query/compile.js.map +1 -0
- package/dist/query/engine.d.ts +48 -0
- package/dist/query/engine.d.ts.map +1 -0
- package/dist/query/engine.js +230 -0
- package/dist/query/engine.js.map +1 -0
- package/dist/query/index.d.ts +8 -0
- package/dist/query/index.d.ts.map +1 -0
- package/dist/query/index.js +10 -0
- package/dist/query/index.js.map +1 -0
- package/dist/query/live-query.d.ts +122 -0
- package/dist/query/live-query.d.ts.map +1 -0
- package/dist/query/live-query.js +543 -0
- package/dist/query/live-query.js.map +1 -0
- package/dist/query/sparse-set.d.ts +18 -0
- package/dist/query/sparse-set.d.ts.map +1 -0
- package/dist/query/sparse-set.js +126 -0
- package/dist/query/sparse-set.js.map +1 -0
- package/dist/reactivity/change-version.d.ts +19 -0
- package/dist/reactivity/change-version.d.ts.map +1 -0
- package/dist/reactivity/change-version.js +76 -0
- package/dist/reactivity/change-version.js.map +1 -0
- package/dist/reactivity/index.d.ts +12 -0
- package/dist/reactivity/index.d.ts.map +1 -0
- package/dist/reactivity/index.js +12 -0
- package/dist/reactivity/index.js.map +1 -0
- package/dist/reactivity/log.d.ts +83 -0
- package/dist/reactivity/log.d.ts.map +1 -0
- package/dist/reactivity/log.js +260 -0
- package/dist/reactivity/log.js.map +1 -0
- package/dist/reactivity/observer-commands.d.ts +40 -0
- package/dist/reactivity/observer-commands.d.ts.map +1 -0
- package/dist/reactivity/observer-commands.js +111 -0
- package/dist/reactivity/observer-commands.js.map +1 -0
- package/dist/reactivity/observers.d.ts +50 -0
- package/dist/reactivity/observers.d.ts.map +1 -0
- package/dist/reactivity/observers.js +127 -0
- package/dist/reactivity/observers.js.map +1 -0
- package/dist/reactivity/reactivity.d.ts +141 -0
- package/dist/reactivity/reactivity.d.ts.map +1 -0
- package/dist/reactivity/reactivity.js +479 -0
- package/dist/reactivity/reactivity.js.map +1 -0
- package/dist/reactivity/structural-journal.d.ts +30 -0
- package/dist/reactivity/structural-journal.d.ts.map +1 -0
- package/dist/reactivity/structural-journal.js +77 -0
- package/dist/reactivity/structural-journal.js.map +1 -0
- package/dist/registry.d.ts +26 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +58 -0
- package/dist/registry.js.map +1 -0
- package/dist/serialize-surface.d.ts +170 -0
- package/dist/serialize-surface.d.ts.map +1 -0
- package/dist/serialize-surface.js +6 -0
- package/dist/serialize-surface.js.map +1 -0
- package/dist/storage/archetype.d.ts +38 -0
- package/dist/storage/archetype.d.ts.map +1 -0
- package/dist/storage/archetype.js +47 -0
- package/dist/storage/archetype.js.map +1 -0
- package/dist/storage/cold-store.d.ts +41 -0
- package/dist/storage/cold-store.d.ts.map +1 -0
- package/dist/storage/cold-store.js +100 -0
- package/dist/storage/cold-store.js.map +1 -0
- package/dist/storage/index.d.ts +10 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +5 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/signature.d.ts +27 -0
- package/dist/storage/signature.d.ts.map +1 -0
- package/dist/storage/signature.js +115 -0
- package/dist/storage/signature.js.map +1 -0
- package/dist/storage/storage.d.ts +72 -0
- package/dist/storage/storage.d.ts.map +1 -0
- package/dist/storage/storage.js +192 -0
- package/dist/storage/storage.js.map +1 -0
- package/dist/storage/store.d.ts +88 -0
- package/dist/storage/store.d.ts.map +1 -0
- package/dist/storage/store.js +473 -0
- package/dist/storage/store.js.map +1 -0
- package/dist/util/stable-index.d.ts +29 -0
- package/dist/util/stable-index.d.ts.map +1 -0
- package/dist/util/stable-index.js +51 -0
- package/dist/util/stable-index.js.map +1 -0
- package/dist/world.d.ts +262 -0
- package/dist/world.d.ts.map +1 -0
- package/dist/world.js +831 -0
- package/dist/world.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { EntityHandle, FieldDescriptor, FieldToken } from '@ecsia/schema';
|
|
2
|
+
export type ElementKind = 'u8' | 'u8c' | 'i8' | 'u16' | 'i16' | 'u32' | 'i32' | 'f32' | 'f64';
|
|
3
|
+
export type TypedArray = Uint8Array | Uint8ClampedArray | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array | Float64Array;
|
|
4
|
+
type AnyTypedArrayCtor = {
|
|
5
|
+
new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): TypedArray;
|
|
6
|
+
readonly BYTES_PER_ELEMENT: number;
|
|
7
|
+
};
|
|
8
|
+
export declare function elementCtor(element: ElementKind): AnyTypedArrayCtor;
|
|
9
|
+
export declare function elementBytes(element: ElementKind): number;
|
|
10
|
+
export interface ColumnLayout {
|
|
11
|
+
readonly element: ElementKind;
|
|
12
|
+
/** Elements per row: 1 scalar, N vec, 1 staticString index. */
|
|
13
|
+
readonly stride: number;
|
|
14
|
+
readonly elementBytes: number;
|
|
15
|
+
readonly rowBytes: number;
|
|
16
|
+
/**
|
|
17
|
+
* The non-zero fill applied to fresh AND grown rows. `-1` for eid columns (a fresh eid row
|
|
18
|
+
* is the null sentinel, never 0 which is a valid entity index). 0 for every other kind (the
|
|
19
|
+
* runtime zero-inits the buffer), unless a user default makes it non-zero-equivalent.
|
|
20
|
+
*/
|
|
21
|
+
readonly fillOnInit: number;
|
|
22
|
+
}
|
|
23
|
+
export declare function makeColumnLayout(element: ElementKind, stride: number, fillOnInit?: number): ColumnLayout;
|
|
24
|
+
export declare const EID_NULL = -1;
|
|
25
|
+
export declare function encodeEid(handle: EntityHandle | number): number;
|
|
26
|
+
export declare function decodeEid(stored: number): EntityHandle | null;
|
|
27
|
+
export declare function stringIndexElement(choicesLength: number): ElementKind;
|
|
28
|
+
/**
|
|
29
|
+
* Project a field token to its ColumnLayout, or `null` for object tokens (no
|
|
30
|
+
* buffer). `fillOnInit` is taken from the descriptor when the field needs an explicit init (eid,
|
|
31
|
+
* or a user-overridden non-zero default); otherwise 0.
|
|
32
|
+
*/
|
|
33
|
+
export declare function tokenToColumnLayout(token: FieldToken, fillOnInit?: number): ColumnLayout | null;
|
|
34
|
+
/** Project a resolved FieldDescriptor to its ColumnLayout, or `null` for non-column-backed fields. */
|
|
35
|
+
export declare function fieldToColumnLayout(field: FieldDescriptor): ColumnLayout | null;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/memory/layout.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,UAAU,EAA+B,MAAM,eAAe,CAAA;AAE3G,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAA;AAE7F,MAAM,MAAM,UAAU,GAClB,UAAU,GACV,iBAAiB,GACjB,SAAS,GACT,WAAW,GACX,UAAU,GACV,WAAW,GACX,UAAU,GACV,YAAY,GACZ,YAAY,CAAA;AAEhB,KAAK,iBAAiB,GAAG;IACvB,KAAK,MAAM,EAAE,eAAe,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,CAAA;IAC/E,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;CACnC,CAAA;AAcD,wBAAgB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,iBAAiB,CAEnE;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAEzD;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,SAAI,GAAG,YAAY,CASnG;AAKD,eAAO,MAAM,QAAQ,KAAK,CAAA;AAE1B,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAE7D;AAID,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,WAAW,CAIrE;AA4BD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,SAAI,GAAG,YAAY,GAAG,IAAI,CAmB1F;AAED,sGAAsG;AACtG,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,eAAe,GAAG,YAAY,GAAG,IAAI,CAI/E"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// Physical column layout per field type. Owns the ElementKind tag, the
|
|
2
|
+
// ColumnLayout shape, the field-token → ColumnLayout table (eid → i32 with -1 sentinel;
|
|
3
|
+
// staticString → smallest uint; vecN → stride n; object<T> → no column), and the normative eid
|
|
4
|
+
// encode/decode.
|
|
5
|
+
const ELEMENT_CTORS = {
|
|
6
|
+
u8: Uint8Array,
|
|
7
|
+
u8c: Uint8ClampedArray,
|
|
8
|
+
i8: Int8Array,
|
|
9
|
+
u16: Uint16Array,
|
|
10
|
+
i16: Int16Array,
|
|
11
|
+
u32: Uint32Array,
|
|
12
|
+
i32: Int32Array,
|
|
13
|
+
f32: Float32Array,
|
|
14
|
+
f64: Float64Array,
|
|
15
|
+
};
|
|
16
|
+
export function elementCtor(element) {
|
|
17
|
+
return ELEMENT_CTORS[element];
|
|
18
|
+
}
|
|
19
|
+
export function elementBytes(element) {
|
|
20
|
+
return ELEMENT_CTORS[element].BYTES_PER_ELEMENT;
|
|
21
|
+
}
|
|
22
|
+
export function makeColumnLayout(element, stride, fillOnInit = 0) {
|
|
23
|
+
const eb = elementBytes(element);
|
|
24
|
+
return {
|
|
25
|
+
element,
|
|
26
|
+
stride,
|
|
27
|
+
elementBytes: eb,
|
|
28
|
+
rowBytes: eb * stride,
|
|
29
|
+
fillOnInit,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
// --- /decode (NORMATIVE) ------------------------------------
|
|
33
|
+
// The full u32 handle bit-pattern is stored via Int32Array; -1 is the null sentinel.
|
|
34
|
+
export const EID_NULL = -1;
|
|
35
|
+
export function encodeEid(handle) {
|
|
36
|
+
return handle | 0;
|
|
37
|
+
}
|
|
38
|
+
export function decodeEid(stored) {
|
|
39
|
+
return stored === EID_NULL ? null : (stored >>> 0);
|
|
40
|
+
}
|
|
41
|
+
// ---
|
|
42
|
+
export function stringIndexElement(choicesLength) {
|
|
43
|
+
if (choicesLength <= 256)
|
|
44
|
+
return 'u8';
|
|
45
|
+
if (choicesLength <= 65_536)
|
|
46
|
+
return 'u16';
|
|
47
|
+
return 'u32';
|
|
48
|
+
}
|
|
49
|
+
// --- → ElementKind table ------------------------------
|
|
50
|
+
const SCALAR_ELEMENT = {
|
|
51
|
+
bool: 'u8',
|
|
52
|
+
i8: 'i8',
|
|
53
|
+
u8: 'u8',
|
|
54
|
+
u8c: 'u8c',
|
|
55
|
+
i16: 'i16',
|
|
56
|
+
u16: 'u16',
|
|
57
|
+
i32: 'i32',
|
|
58
|
+
u32: 'u32',
|
|
59
|
+
f32: 'f32',
|
|
60
|
+
f64: 'f64',
|
|
61
|
+
eid: 'i32',
|
|
62
|
+
};
|
|
63
|
+
function isVecToken(t) {
|
|
64
|
+
return typeof t === 'object' && t.kind === 'vec';
|
|
65
|
+
}
|
|
66
|
+
function isStaticStringToken(t) {
|
|
67
|
+
return typeof t === 'object' && t.kind === 'staticString';
|
|
68
|
+
}
|
|
69
|
+
function isObjectToken(t) {
|
|
70
|
+
return typeof t === 'object' && t.kind === 'object';
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Project a field token to its ColumnLayout, or `null` for object tokens (no
|
|
74
|
+
* buffer). `fillOnInit` is taken from the descriptor when the field needs an explicit init (eid,
|
|
75
|
+
* or a user-overridden non-zero default); otherwise 0.
|
|
76
|
+
*/
|
|
77
|
+
export function tokenToColumnLayout(token, fillOnInit = 0) {
|
|
78
|
+
if (typeof token === 'string') {
|
|
79
|
+
if (isObjectToken(token))
|
|
80
|
+
return null;
|
|
81
|
+
// The 'string' rich token projects to no column, like object<T>.
|
|
82
|
+
if (token === 'string')
|
|
83
|
+
return null;
|
|
84
|
+
const element = SCALAR_ELEMENT[token];
|
|
85
|
+
if (element === undefined)
|
|
86
|
+
throw new Error(`unknown scalar token: ${token}`);
|
|
87
|
+
return makeColumnLayout(element, 1, fillOnInit);
|
|
88
|
+
}
|
|
89
|
+
if (isVecToken(token)) {
|
|
90
|
+
const element = SCALAR_ELEMENT[token.elem];
|
|
91
|
+
if (element === undefined)
|
|
92
|
+
throw new Error(`unknown vec element token: ${String(token.elem)}`);
|
|
93
|
+
return makeColumnLayout(element, token.len, fillOnInit);
|
|
94
|
+
}
|
|
95
|
+
if (isStaticStringToken(token)) {
|
|
96
|
+
return makeColumnLayout(stringIndexElement(token.choices.length), 1, fillOnInit);
|
|
97
|
+
}
|
|
98
|
+
// object token (the only remaining branch): no column.
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
/** Project a resolved FieldDescriptor to its ColumnLayout, or `null` for non-column-backed fields. */
|
|
102
|
+
export function fieldToColumnLayout(field) {
|
|
103
|
+
if (field.ctor === null)
|
|
104
|
+
return null;
|
|
105
|
+
const fill = field.needsExplicitInit ? toFillValue(field) : 0;
|
|
106
|
+
return tokenToColumnLayout(field.token, fill);
|
|
107
|
+
}
|
|
108
|
+
function toFillValue(field) {
|
|
109
|
+
// The grown-tail/fresh-row fill is encoded into the column's slot space. For eid the default is
|
|
110
|
+
// the null sentinel (-1); for a user-overridden scalar it is the encoded default.
|
|
111
|
+
const d = field.default;
|
|
112
|
+
if (d === null || d === undefined)
|
|
113
|
+
return EID_NULL;
|
|
114
|
+
return field.encode(d);
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/memory/layout.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { ComponentDef, ComponentId, QueryTerm, Schema } from '@ecsia/schema';
|
|
2
|
+
/** One packed membership-bit reference within the fixed-stride signature words. */
|
|
3
|
+
export interface Word {
|
|
4
|
+
readonly wordIndex: number;
|
|
5
|
+
readonly mask: number;
|
|
6
|
+
}
|
|
7
|
+
/** A residual (large pair-ID) term tested by sigHas binary search, not a sigWords AND. */
|
|
8
|
+
export interface ResidualTerm {
|
|
9
|
+
readonly componentId: ComponentId;
|
|
10
|
+
readonly negate: boolean;
|
|
11
|
+
}
|
|
12
|
+
export type ValueRole = 'read' | 'write' | 'optional' | 'pairRead' | 'pairWrite';
|
|
13
|
+
/**
|
|
14
|
+
* An exclusive-relation specific-target term (relations ): the target is a
|
|
15
|
+
* COLUMN value, not a signature bit, so the archetype is matched by `presenceId(R)` and iteration
|
|
16
|
+
* filters rows by `targetColumn[row] === target`. Carried on the CompiledQuery; the engine applies it.
|
|
17
|
+
*/
|
|
18
|
+
export interface RowFilterTerm {
|
|
19
|
+
readonly presenceId: ComponentId;
|
|
20
|
+
/** The full target EntityHandle (encoded eid value stored in the column) to compare each row against. */
|
|
21
|
+
readonly targetEid: number;
|
|
22
|
+
/** Field index of the exclusive `eid` target column within the presence component's ColumnSet. */
|
|
23
|
+
readonly targetFieldIndex: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The relations-owned resolution of a Pair(...) term to a concrete ComponentId.
|
|
27
|
+
* Injected by relations into the world's CompileContext (core never imports relations).: a
|
|
28
|
+
* query must NOT mint — `mintedOnly` resolution returns `unsatisfiable` when the pair never existed.
|
|
29
|
+
*/
|
|
30
|
+
export interface ResolvedPair {
|
|
31
|
+
/** The signature bit to AND-match (presence id for wildcard/exclusive; pair id for tag/overflow). */
|
|
32
|
+
readonly componentId: ComponentId;
|
|
33
|
+
/** True iff the pair id was never minted → the query matches nothing without mutating the id space. */
|
|
34
|
+
readonly unsatisfiable: boolean;
|
|
35
|
+
/** Present for exclusive specific-target pairs: the post-presence row filter. */
|
|
36
|
+
readonly rowFilter?: RowFilterTerm;
|
|
37
|
+
}
|
|
38
|
+
/** Value terms in declaration order (drives the pooled element + cursor binding). */
|
|
39
|
+
export interface CompiledValueTerm {
|
|
40
|
+
readonly componentId: ComponentId;
|
|
41
|
+
readonly role: ValueRole;
|
|
42
|
+
readonly key: string;
|
|
43
|
+
}
|
|
44
|
+
export interface CompiledQuery {
|
|
45
|
+
readonly withWords: readonly Word[];
|
|
46
|
+
readonly notWords: readonly Word[];
|
|
47
|
+
readonly optionalIds: readonly ComponentId[];
|
|
48
|
+
readonly residualWith: readonly ResidualTerm[];
|
|
49
|
+
readonly valueTerms: readonly CompiledValueTerm[];
|
|
50
|
+
readonly referencedIds: readonly ComponentId[];
|
|
51
|
+
/** Exclusive specific-target pair filters: match by presence bit, then filter rows by target. */
|
|
52
|
+
readonly rowFilters: readonly RowFilterTerm[];
|
|
53
|
+
readonly hash: string;
|
|
54
|
+
/** True iff a specific-pair term resolved to a never-minted pair id → matches nothing. */
|
|
55
|
+
readonly unsatisfiable: boolean;
|
|
56
|
+
}
|
|
57
|
+
/** The seam the compiler uses to resolve component (and, later, pair) ids — owned by the world. */
|
|
58
|
+
export interface CompileContext {
|
|
59
|
+
/** ComponentId for a registered ComponentDef, or throws if the def is not in this world. */
|
|
60
|
+
idOf(def: ComponentDef<Schema>): ComponentId;
|
|
61
|
+
/** Fixed bitmask bit count: ids below this go in the packed words, larger pair ids are residual. */
|
|
62
|
+
readonly fixedBitCount: number;
|
|
63
|
+
/**
|
|
64
|
+
* Resolve a Pair(R, target | Wildcard) term to a ComponentId. Injected by the
|
|
65
|
+
* relations module via the world; absent in a relation-free world (every pair term is then
|
|
66
|
+
* unsatisfiable, the behavior).: this NEVER mints — it only looks up already-minted ids.
|
|
67
|
+
*/
|
|
68
|
+
resolvePair?(relationId: number, target: number | symbol): ResolvedPair;
|
|
69
|
+
}
|
|
70
|
+
declare const WILDCARD_TAG: unique symbol;
|
|
71
|
+
export declare function compileQuery(terms: readonly QueryTerm[], ctx: CompileContext): CompiledQuery;
|
|
72
|
+
export { WILDCARD_TAG };
|
|
73
|
+
//# sourceMappingURL=compile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/query/compile.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAEjF,mFAAmF;AACnF,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,0FAA0F;AAC1F,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACzB;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,CAAA;AAEhF;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAA;IAChC,yGAAyG;IACzG,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,kGAAkG;IAClG,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;CAClC;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,qGAAqG;IACrG,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,uGAAuG;IACvG,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B,iFAAiF;IACjF,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAA;CACnC;AAED,qFAAqF;AACrF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,SAAS,IAAI,EAAE,CAAA;IACnC,QAAQ,CAAC,QAAQ,EAAE,SAAS,IAAI,EAAE,CAAA;IAClC,QAAQ,CAAC,WAAW,EAAE,SAAS,WAAW,EAAE,CAAA;IAC5C,QAAQ,CAAC,YAAY,EAAE,SAAS,YAAY,EAAE,CAAA;IAC9C,QAAQ,CAAC,UAAU,EAAE,SAAS,iBAAiB,EAAE,CAAA;IACjD,QAAQ,CAAC,aAAa,EAAE,SAAS,WAAW,EAAE,CAAA;IAC9C,iGAAiG;IACjG,QAAQ,CAAC,UAAU,EAAE,SAAS,aAAa,EAAE,CAAA;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,0FAA0F;IAC1F,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;CAChC;AAED,mGAAmG;AACnG,MAAM,WAAW,cAAc;IAC7B,4FAA4F;IAC5F,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,MAAM,CAAC,GAAG,WAAW,CAAA;IAC5C,oGAAoG;IACpG,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B;;;;OAIG;IACH,WAAW,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,YAAY,CAAA;CACxE;AAiBD,QAAA,MAAM,YAAY,eAAqC,CAAA;AA+EvD,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,GAAG,EAAE,cAAc,GAAG,aAAa,CAuE5F;AAED,OAAO,EAAE,YAAY,EAAE,CAAA"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// Query compilation: turn a readonly QueryTerm[] into a CompiledQuery with
|
|
2
|
+
// packed withWords / notWords signature masks, the optional value terms, the residual large-pair-ID
|
|
3
|
+
// terms, and a canonical order-independent hash that encodes pair-target ids and role tags.
|
|
4
|
+
//
|
|
5
|
+
// classifyTerm reads the `__term` discriminant on the typed wrappers and the
|
|
6
|
+
// PairDef shape; a bare ComponentDef is treated as read. Pair-term resolution (presence id /
|
|
7
|
+
// pair id / exclusivity) is the relations module's contract; compiles the component/with/
|
|
8
|
+
// without/optional terms in full and the pair terms via the resolver hook the world supplies.
|
|
9
|
+
const WILDCARD_TAG = Symbol.for('ecsia.query.wildcard');
|
|
10
|
+
function isPairDef(t) {
|
|
11
|
+
return typeof t === 'object' && t !== null && 'relation' in t && 'target' in t;
|
|
12
|
+
}
|
|
13
|
+
function classifyTerm(t) {
|
|
14
|
+
if (isPairDef(t)) {
|
|
15
|
+
const pair = t;
|
|
16
|
+
const isWildcard = typeof pair.target === 'symbol';
|
|
17
|
+
return {
|
|
18
|
+
kind: isWildcard ? 'pairWildcard' : 'pairSpecific',
|
|
19
|
+
def: null,
|
|
20
|
+
pair,
|
|
21
|
+
role: 'none',
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const term = t;
|
|
25
|
+
switch (term.__term) {
|
|
26
|
+
case 'read':
|
|
27
|
+
return { kind: 'component', def: term.c ?? null, pair: null, role: 'read' };
|
|
28
|
+
case 'write':
|
|
29
|
+
return { kind: 'component', def: term.c ?? null, pair: null, role: 'write' };
|
|
30
|
+
case 'has':
|
|
31
|
+
return { kind: 'component', def: term.c ?? null, pair: null, role: 'none' };
|
|
32
|
+
case 'without':
|
|
33
|
+
return { kind: 'without', def: term.c ?? null, pair: null, role: 'none' };
|
|
34
|
+
case 'optional':
|
|
35
|
+
return { kind: 'optional', def: term.c ?? null, pair: null, role: 'read' };
|
|
36
|
+
default:
|
|
37
|
+
// bare ComponentDef == read.
|
|
38
|
+
return { kind: 'component', def: t, pair: null, role: 'bare' };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function addWithBit(withWords, residual, c, fixedBitCount) {
|
|
42
|
+
if (c < fixedBitCount)
|
|
43
|
+
withWords.push({ wordIndex: c >>> 5, mask: (1 << (c & 31)) >>> 0 });
|
|
44
|
+
else
|
|
45
|
+
residual.push({ componentId: c, negate: false });
|
|
46
|
+
}
|
|
47
|
+
function addNotBit(notWords, residual, c, fixedBitCount) {
|
|
48
|
+
if (c < fixedBitCount)
|
|
49
|
+
notWords.push({ wordIndex: c >>> 5, mask: (1 << (c & 31)) >>> 0 });
|
|
50
|
+
else
|
|
51
|
+
residual.push({ componentId: c, negate: true });
|
|
52
|
+
}
|
|
53
|
+
function keyOf(def) {
|
|
54
|
+
return def.name;
|
|
55
|
+
}
|
|
56
|
+
/** (R,p1) and Pair(R,p2) are distinct keys. */
|
|
57
|
+
function pairHashId(pair) {
|
|
58
|
+
if (typeof pair.target === 'symbol')
|
|
59
|
+
return 'W' + pair.relation.id;
|
|
60
|
+
// exclusivity (the X-tag) is the relations module's contract; uses the tag/overflow form.
|
|
61
|
+
return 'p' + pair.relation.id + '.' + pair.target;
|
|
62
|
+
}
|
|
63
|
+
function canonicalHash(terms, ctx) {
|
|
64
|
+
const parts = [];
|
|
65
|
+
for (const t of terms) {
|
|
66
|
+
const cl = classifyTerm(t);
|
|
67
|
+
let cid;
|
|
68
|
+
if (cl.pair !== null)
|
|
69
|
+
cid = pairHashId(cl.pair);
|
|
70
|
+
else
|
|
71
|
+
cid = ctx.idOf(cl.def);
|
|
72
|
+
// Role tags keep has (membership) distinct from read; read/write/bare collapse to one P tag
|
|
73
|
+
// (same matching constraint, same `current`); without → N; optional → O.
|
|
74
|
+
const roleTag = cl.kind === 'without'
|
|
75
|
+
? 'N'
|
|
76
|
+
: cl.kind === 'optional'
|
|
77
|
+
? 'O'
|
|
78
|
+
: cl.kind === 'component' && cl.role === 'none'
|
|
79
|
+
? 'M'
|
|
80
|
+
: 'P';
|
|
81
|
+
parts.push(roleTag + ':' + cid);
|
|
82
|
+
}
|
|
83
|
+
parts.sort();
|
|
84
|
+
return parts.join('|');
|
|
85
|
+
}
|
|
86
|
+
export function compileQuery(terms, ctx) {
|
|
87
|
+
const withWords = [];
|
|
88
|
+
const notWords = [];
|
|
89
|
+
const optionalIds = [];
|
|
90
|
+
const residualWith = [];
|
|
91
|
+
const valueTerms = [];
|
|
92
|
+
const rowFilters = [];
|
|
93
|
+
const referenced = new Set();
|
|
94
|
+
let unsatisfiable = false;
|
|
95
|
+
for (const t of terms) {
|
|
96
|
+
const cl = classifyTerm(t);
|
|
97
|
+
switch (cl.kind) {
|
|
98
|
+
case 'component': {
|
|
99
|
+
const def = cl.def;
|
|
100
|
+
const cid = ctx.idOf(def);
|
|
101
|
+
referenced.add(cid);
|
|
102
|
+
addWithBit(withWords, residualWith, cid, ctx.fixedBitCount);
|
|
103
|
+
if (cl.role === 'read' || cl.role === 'write' || cl.role === 'bare') {
|
|
104
|
+
valueTerms.push({
|
|
105
|
+
componentId: cid,
|
|
106
|
+
role: cl.role === 'bare' ? 'read' : cl.role,
|
|
107
|
+
key: keyOf(def),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
case 'without': {
|
|
113
|
+
const cid = ctx.idOf(cl.def);
|
|
114
|
+
referenced.add(cid);
|
|
115
|
+
addNotBit(notWords, residualWith, cid, ctx.fixedBitCount);
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
case 'optional': {
|
|
119
|
+
const def = cl.def;
|
|
120
|
+
const cid = ctx.idOf(def);
|
|
121
|
+
referenced.add(cid);
|
|
122
|
+
optionalIds.push(cid);
|
|
123
|
+
valueTerms.push({ componentId: cid, role: 'optional', key: keyOf(def) });
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
case 'pairWildcard':
|
|
127
|
+
case 'pairSpecific': {
|
|
128
|
+
// / relations: relations injects `resolvePair`; without it (relation-free
|
|
129
|
+
// world, the case) every pair term matches nothing.: resolvePair NEVER mints.
|
|
130
|
+
const pair = cl.pair;
|
|
131
|
+
const resolved = ctx.resolvePair?.(pair.relation.id, pair.target);
|
|
132
|
+
if (resolved === undefined || resolved.unsatisfiable) {
|
|
133
|
+
unsatisfiable = true;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
const cid = resolved.componentId;
|
|
137
|
+
referenced.add(cid);
|
|
138
|
+
addWithBit(withWords, residualWith, cid, ctx.fixedBitCount);
|
|
139
|
+
if (resolved.rowFilter !== undefined)
|
|
140
|
+
rowFilters.push(resolved.rowFilter);
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return Object.freeze({
|
|
146
|
+
withWords,
|
|
147
|
+
notWords,
|
|
148
|
+
optionalIds,
|
|
149
|
+
residualWith,
|
|
150
|
+
valueTerms,
|
|
151
|
+
referencedIds: [...referenced],
|
|
152
|
+
rowFilters,
|
|
153
|
+
hash: canonicalHash(terms, ctx),
|
|
154
|
+
unsatisfiable,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
export { WILDCARD_TAG };
|
|
158
|
+
//# sourceMappingURL=compile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/query/compile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ComponentId, QueryTerm } from '@ecsia/schema';
|
|
2
|
+
import type { Bitmask } from '../bitmask/index.js';
|
|
3
|
+
import type { Archetype, Signature } from '../storage/index.js';
|
|
4
|
+
import type { Buffers } from '../memory/index.js';
|
|
5
|
+
import type { CompileContext } from './compile.js';
|
|
6
|
+
import { LiveQuery } from './live-query.js';
|
|
7
|
+
import type { LiveQueryDeps, ReactivityQueryHooks } from './live-query.js';
|
|
8
|
+
export interface QueryEngineDeps extends LiveQueryDeps {
|
|
9
|
+
readonly buffers: Buffers;
|
|
10
|
+
readonly bitmask: Bitmask;
|
|
11
|
+
readonly maxEntities: number;
|
|
12
|
+
/** The dense archetype list (store.byId), walked once to seed a new query. */
|
|
13
|
+
readonly byId: Archetype[];
|
|
14
|
+
/** Subscribe to archetypeCreated so new archetypes join matching live queries. */
|
|
15
|
+
onArchetypeCreated(fn: (arch: Archetype) => void): void;
|
|
16
|
+
/** Resolve a registered component's id (and the fixed bitmask bit count) for compilation. */
|
|
17
|
+
readonly compileContext: CompileContext;
|
|
18
|
+
/** index → its CURRENT signature (resolveLocation → archetype.signature) for residual terms. */
|
|
19
|
+
signatureOf(index: number): Signature;
|
|
20
|
+
/** Full handle (from a dense rows[] slot) → its entity index (low handle bits). */
|
|
21
|
+
indexOfHandle(handle: number): number;
|
|
22
|
+
}
|
|
23
|
+
export declare class QueryEngine {
|
|
24
|
+
#private;
|
|
25
|
+
constructor(deps: QueryEngineDeps);
|
|
26
|
+
/** Late-bind the reactivity write-log hooks so the Changed flavor works (world wiring). */
|
|
27
|
+
setReactivity(hooks: ReactivityQueryHooks): void;
|
|
28
|
+
/**: compile, dedup by canonical hash, seed on a miss. */
|
|
29
|
+
query(terms: readonly QueryTerm[]): LiveQuery;
|
|
30
|
+
/** Exposed for the world facade / tests: iterate every live query (e.g. for frameReset). */
|
|
31
|
+
get liveQueries(): IterableIterator<LiveQuery>;
|
|
32
|
+
/**: re-test ONE migrated entity against only the queries referencing the changed component. */
|
|
33
|
+
maintainEntity(index: number, componentId: ComponentId): void;
|
|
34
|
+
/**
|
|
35
|
+
*: a freshly spawned entity lands in the EMPTY archetype. It carries no component, so
|
|
36
|
+
* the per-component `maintainEntity` path never fires for it — yet a constraint-less query (empty
|
|
37
|
+
* withWords/notWords/residualWith) DOES match the empty signature and the seed already
|
|
38
|
+
* includes such entities. To keep the incremental path symmetric with the seed (so a query created
|
|
39
|
+
* BEFORE a plain spawn agrees with one created after), re-test the new index against every query
|
|
40
|
+
* that matches the empty archetype and add it.
|
|
41
|
+
*/
|
|
42
|
+
onEntitySpawned(index: number, emptyArchetype: Archetype): void;
|
|
43
|
+
/**: evict a despawned entity from EVERY live query (constraint-less queries included). */
|
|
44
|
+
dropEntity(index: number): void;
|
|
45
|
+
/** Reset every live query's per-frame transient flavor lists (FRAME_RESET). */
|
|
46
|
+
frameReset(): void;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/query/engine.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAU,MAAM,eAAe,CAAA;AACnE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,oBAAoB,CAAA;AAE5D,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,cAAc,CAAA;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAG1E,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,CAAA;IAC1B,kFAAkF;IAClF,kBAAkB,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,GAAG,IAAI,CAAA;IACvD,6FAA6F;IAC7F,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAA;IACvC,gGAAgG;IAChG,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,mFAAmF;IACnF,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;CACtC;AAED,qBAAa,WAAW;;gBAQV,IAAI,EAAE,eAAe;IAKjC,2FAA2F;IAC3F,aAAa,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI;IAKhD,yDAAyD;IACzD,KAAK,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS;IAY7C,4FAA4F;IAC5F,IAAI,WAAW,IAAI,gBAAgB,CAAC,SAAS,CAAC,CAE7C;IA0HD,+FAA+F;IAC/F,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,IAAI;IAW7D;;;;;;;OAOG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,SAAS,GAAG,IAAI;IAM/D,0FAA0F;IAC1F,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAsB/B,+EAA+E;IAC/E,UAAU,IAAI,IAAI;CAGnB"}
|