@forgeax/engine-ecs 0.1.26 → 0.1.28
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/README.md +94 -35
- package/dist/__tests__/world-read.unit.test.d.ts +2 -0
- package/dist/__tests__/world-read.unit.test.d.ts.map +1 -0
- package/dist/commands.d.ts +2 -0
- package/dist/commands.d.ts.map +1 -1
- package/dist/index.mjs +3471 -4263
- package/dist/index.mjs.map +1 -1
- package/dist/internal.d.ts +2 -3
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.mjs +3 -333
- package/dist/internal.mjs.map +1 -1
- package/dist/projection/index.mjs.map +1 -1
- package/dist/shared.mjs.map +1 -1
- package/dist/world-entity-lifecycle.d.ts +3 -14
- package/dist/world-entity-lifecycle.d.ts.map +1 -1
- package/dist/world-internal.d.ts +65 -5
- package/dist/world-internal.d.ts.map +1 -1
- package/dist/world-read.d.ts +16 -0
- package/dist/world-read.d.ts.map +1 -0
- package/dist/world-read.mjs +8 -0
- package/dist/world-read.mjs.map +1 -0
- package/dist/world-scheduling.d.ts +0 -4
- package/dist/world-scheduling.d.ts.map +1 -1
- package/dist/world-storage-primitives.d.ts +26 -0
- package/dist/world-storage-primitives.d.ts.map +1 -0
- package/dist/world.d.ts +352 -157
- package/dist/world.d.ts.map +1 -1
- package/package.json +8 -4
- package/src/__tests__/command-buffer.test.ts +29 -3
- package/src/__tests__/hierarchy.unit.test.ts +3 -3
- package/src/__tests__/world-health.contract.test.ts +195 -2
- package/src/__tests__/world-read.unit.test.ts +30 -0
- package/src/commands.ts +22 -9
- package/src/internal.ts +5 -3
- package/src/world-entity-lifecycle.ts +23 -252
- package/src/world-internal-augmentation.d.ts +11 -0
- package/src/world-internal.ts +114 -63
- package/src/world-read.ts +38 -0
- package/src/world-scheduling.ts +0 -26
- package/src/world-storage-primitives.ts +179 -0
- package/src/world.ts +2590 -509
- package/dist/world-component-access.d.ts +0 -311
- package/dist/world-component-access.d.ts.map +0 -1
- package/dist/world-component-storage.d.ts +0 -298
- package/dist/world-component-storage.d.ts.map +0 -1
- package/dist/world-core.d.ts +0 -39
- package/dist/world-core.d.ts.map +0 -1
- package/src/world-component-access.ts +0 -1769
- package/src/world-component-storage.ts +0 -1264
- package/src/world-core.ts +0 -74
package/dist/internal.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export { worldInternal } from './world-internal';
|
|
1
|
+
export { componentId, componentSchema } from './component';
|
|
2
|
+
export { componentDefinition } from './component-schema';
|
|
4
3
|
import type { Result } from '@forgeax/engine-types';
|
|
5
4
|
import type { Component } from './component';
|
|
6
5
|
import type { QuerySpanUnavailableError } from './errors';
|
package/dist/internal.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,yEAAyE;AACzE,eAAO,MAAM,cAAc,EAAE,OAAO,MAEC,CAAC;AAYtC;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,CAAC,SAAS,SAAS,SAAS,EAAE,EAC9B,CAAC,SAAS,SAAS,SAAS,EAAE,EAC9B,CAAC,SAAS,SAAS,SAAS,EAAE,EAC9B,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAEnB,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EACrB,SAAS,EAAE,CAAC,GACX,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,yBAAyB,CAAC,CAGrE;AAED,YAAY,EACV,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,8BAA8B,CAAC"}
|
package/dist/internal.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import '@forgeax/engine-types';
|
|
2
2
|
|
|
3
3
|
// src/component.ts
|
|
4
4
|
|
|
@@ -10,9 +10,6 @@ var definitions = globalSymbols[COMPONENT_REGISTRY] ?? (() => {
|
|
|
10
10
|
globalSymbols[COMPONENT_REGISTRY] = registry;
|
|
11
11
|
return registry;
|
|
12
12
|
})();
|
|
13
|
-
function registerComponentDefinition(component, definition) {
|
|
14
|
-
definitions.definitions.set(component, definition);
|
|
15
|
-
}
|
|
16
13
|
function componentDefinition(component) {
|
|
17
14
|
const definition = definitions.definitions.get(component);
|
|
18
15
|
if (definition === void 0) {
|
|
@@ -20,93 +17,6 @@ function componentDefinition(component) {
|
|
|
20
17
|
}
|
|
21
18
|
return definition;
|
|
22
19
|
}
|
|
23
|
-
function deepFreeze(value) {
|
|
24
|
-
if (value === null || typeof value !== "object" && typeof value !== "function") {
|
|
25
|
-
return value;
|
|
26
|
-
}
|
|
27
|
-
if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
|
|
28
|
-
return value;
|
|
29
|
-
}
|
|
30
|
-
const object = value;
|
|
31
|
-
for (const key of Reflect.ownKeys(object)) {
|
|
32
|
-
const child = object[key];
|
|
33
|
-
if (child !== null && (typeof child === "object" || typeof child === "function")) {
|
|
34
|
-
deepFreeze(child);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return Object.freeze(value);
|
|
38
|
-
}
|
|
39
|
-
function assertComponentStorage(value) {
|
|
40
|
-
if (value !== "table" && value !== "sparse") {
|
|
41
|
-
throw new Error(`Unsupported component storage '${value}'. Expected 'table' or 'sparse'.`);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// src/world-internal.ts
|
|
46
|
-
var worldInternal = /* @__PURE__ */ Symbol.for(
|
|
47
|
-
"forgeax.ecs.worldInternal"
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
// src/errors.ts
|
|
51
|
-
var SchemaUnsupportedFieldError = class extends Error {
|
|
52
|
-
name = "SchemaUnsupportedFieldError";
|
|
53
|
-
code = "schema-unsupported-field";
|
|
54
|
-
hint;
|
|
55
|
-
constructor(fieldName, fieldType) {
|
|
56
|
-
let hint = "Supported types: f32 / f64 / i32 / u32 / i16 / u16 / i8 / u8 / bool / enum / ref.";
|
|
57
|
-
if (fieldType.startsWith("handle<") && fieldType.endsWith(">")) {
|
|
58
|
-
const tag = fieldType.slice(7, -1);
|
|
59
|
-
hint = `'handle<${tag}>' was removed in feat-20260614 M5; use 'shared<${tag}>' instead. The brand and storage layout are unchanged; only the keyword + write-barrier dispatch (SharedRefStore retain/release) is new.`;
|
|
60
|
-
} else if (fieldType.startsWith("ref<") && fieldType.endsWith(">")) {
|
|
61
|
-
const tag = fieldType.slice(4, -1);
|
|
62
|
-
hint = `'ref<${tag}>' was renamed in feat-20260614 M1; use 'unique<${tag}>' instead. The brand and storage layout are unchanged; the dispatch still routes through UniqueRefStore (single-holder direct release).`;
|
|
63
|
-
}
|
|
64
|
-
super(
|
|
65
|
-
`Schema field "${fieldName}" has unsupported type "${fieldType}".
|
|
66
|
-
field: ${fieldName}
|
|
67
|
-
type: ${fieldType}
|
|
68
|
-
hint: ${hint}`
|
|
69
|
-
);
|
|
70
|
-
this.hint = hint;
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
var SparseStorageRequiresTagError = class extends Error {
|
|
74
|
-
name = "SparseStorageRequiresTagError";
|
|
75
|
-
code = "sparse-storage-requires-tag";
|
|
76
|
-
expected = "sparse components have an empty schema and no relationship metadata";
|
|
77
|
-
hint = "remove all fields and relationship metadata, or use storage: table";
|
|
78
|
-
detail;
|
|
79
|
-
constructor(componentName) {
|
|
80
|
-
super(
|
|
81
|
-
`Sparse component "${componentName}" must be a zero-field, non-relationship tag.
|
|
82
|
-
component: ${componentName}
|
|
83
|
-
hint: remove all fields and relationship metadata, or use storage: table`
|
|
84
|
-
);
|
|
85
|
-
this.detail = { componentName };
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
var ManagedArrayElementTypeNotAllowedError = class extends Error {
|
|
89
|
-
name = "ManagedArrayElementTypeNotAllowedError";
|
|
90
|
-
code = "managed-array-element-type-not-allowed";
|
|
91
|
-
hint;
|
|
92
|
-
expected;
|
|
93
|
-
detail;
|
|
94
|
-
constructor(fieldName, elementType) {
|
|
95
|
-
const hint = `array<T> element type must be a scalar (f32/f64/i32/u32/i16/u16/i8/u8/bool/enum/ref) or entity. ref<X> / handle<X> / buffer:N / nested array<...> are forbidden on field "${fieldName}".`;
|
|
96
|
-
const expected = "element type in {scalar | entity}";
|
|
97
|
-
super(
|
|
98
|
-
`managed-array: element type not allowed.
|
|
99
|
-
code: managed-array-element-type-not-allowed
|
|
100
|
-
field: ${fieldName}
|
|
101
|
-
elementType: ${elementType}
|
|
102
|
-
expected: ${expected}
|
|
103
|
-
hint: ${hint}`
|
|
104
|
-
);
|
|
105
|
-
this.hint = hint;
|
|
106
|
-
this.expected = expected;
|
|
107
|
-
this.detail = { fieldName, elementType, hint };
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
20
|
|
|
111
21
|
// src/component.ts
|
|
112
22
|
var FIELD_SIZE_BYTES = {
|
|
@@ -122,88 +32,6 @@ var FIELD_SIZE_BYTES = {
|
|
|
122
32
|
enum: 4,
|
|
123
33
|
ref: 4
|
|
124
34
|
};
|
|
125
|
-
function fieldTypeToMetaKey(fieldType) {
|
|
126
|
-
if (fieldType === "entity" || fieldType === "string" || fieldType === "buffer") {
|
|
127
|
-
return fieldType;
|
|
128
|
-
}
|
|
129
|
-
if (fieldType.startsWith("unique<") && fieldType.endsWith(">")) return "ref";
|
|
130
|
-
if (fieldType.startsWith("shared<") && fieldType.endsWith(">")) return "shared";
|
|
131
|
-
if (fieldType.startsWith("buffer<") && fieldType.endsWith(">")) return "buffer";
|
|
132
|
-
if (fieldType.startsWith("array<") && fieldType.endsWith(">")) return "array";
|
|
133
|
-
if (TYPE_METADATA[fieldType] !== void 0) return fieldType;
|
|
134
|
-
return null;
|
|
135
|
-
}
|
|
136
|
-
function isManagedField(fieldType) {
|
|
137
|
-
return TYPE_METADATA[fieldTypeToMetaKey(fieldType) ?? ""]?.isManaged ?? false;
|
|
138
|
-
}
|
|
139
|
-
function isManagedBufferField(fieldType) {
|
|
140
|
-
return TYPE_METADATA[fieldTypeToMetaKey(fieldType) ?? ""]?.isBuffer ?? false;
|
|
141
|
-
}
|
|
142
|
-
function isEntityField(fieldType) {
|
|
143
|
-
return TYPE_METADATA[fieldTypeToMetaKey(fieldType) ?? ""]?.isEntityRef ?? false;
|
|
144
|
-
}
|
|
145
|
-
function isManagedArrayField(fieldType) {
|
|
146
|
-
return TYPE_METADATA[fieldTypeToMetaKey(fieldType) ?? ""]?.isArray ?? false;
|
|
147
|
-
}
|
|
148
|
-
var MANAGED_ARRAY_ELEMENT_TYPES = /* @__PURE__ */ new Set([
|
|
149
|
-
"f32",
|
|
150
|
-
"f64",
|
|
151
|
-
"i32",
|
|
152
|
-
"u32",
|
|
153
|
-
"i16",
|
|
154
|
-
"u16",
|
|
155
|
-
"i8",
|
|
156
|
-
"u8",
|
|
157
|
-
"bool",
|
|
158
|
-
"enum",
|
|
159
|
-
"ref",
|
|
160
|
-
"entity"
|
|
161
|
-
]);
|
|
162
|
-
function isValidArrayElementType(elementType) {
|
|
163
|
-
if (MANAGED_ARRAY_ELEMENT_TYPES.has(elementType)) return true;
|
|
164
|
-
if (elementType.startsWith("shared<") && elementType.endsWith(">") && elementType.length > 9)
|
|
165
|
-
return true;
|
|
166
|
-
return false;
|
|
167
|
-
}
|
|
168
|
-
function parseManagedArraySchema(fieldType) {
|
|
169
|
-
if (!fieldType.startsWith("array<") || !fieldType.endsWith(">")) return null;
|
|
170
|
-
const inner = fieldType.slice(6, -1);
|
|
171
|
-
const commaIdx = inner.indexOf(",");
|
|
172
|
-
if (commaIdx === -1) {
|
|
173
|
-
if (!isValidArrayElementType(inner)) return null;
|
|
174
|
-
return { elementType: inner, length: void 0 };
|
|
175
|
-
}
|
|
176
|
-
const head = inner.slice(0, commaIdx).trim();
|
|
177
|
-
const tail = inner.slice(commaIdx + 1).trim();
|
|
178
|
-
if (!isValidArrayElementType(head)) return null;
|
|
179
|
-
if (!/^[1-9]\d*$/.test(tail)) return null;
|
|
180
|
-
return { elementType: head, length: Number.parseInt(tail, 10) };
|
|
181
|
-
}
|
|
182
|
-
function bufferFieldByteLength(fieldType) {
|
|
183
|
-
if (!fieldType.startsWith("buffer<") || !fieldType.endsWith(">")) return Number.NaN;
|
|
184
|
-
const tail = fieldType.slice(7, -1);
|
|
185
|
-
if (!/^[1-9]\d*$/.test(tail)) return Number.NaN;
|
|
186
|
-
return Number.parseInt(tail, 10);
|
|
187
|
-
}
|
|
188
|
-
function isSchemaVocabKeyword(s) {
|
|
189
|
-
if (s === "string") return true;
|
|
190
|
-
if (s === "entity") return true;
|
|
191
|
-
if (s === "buffer") return true;
|
|
192
|
-
if (s.startsWith("buffer<") && s.endsWith(">")) {
|
|
193
|
-
const tail = s.slice(7, -1);
|
|
194
|
-
return /^[1-9]\d*$/.test(tail);
|
|
195
|
-
}
|
|
196
|
-
if (s.startsWith("unique<") && s.endsWith(">")) {
|
|
197
|
-
return /^\w+$/.test(s.slice(7, -1));
|
|
198
|
-
}
|
|
199
|
-
if (s.startsWith("shared<") && s.endsWith(">")) {
|
|
200
|
-
return /^\w+$/.test(s.slice(7, -1));
|
|
201
|
-
}
|
|
202
|
-
if (s.startsWith("array<") && s.endsWith(">")) {
|
|
203
|
-
return parseManagedArraySchema(s) !== null;
|
|
204
|
-
}
|
|
205
|
-
return false;
|
|
206
|
-
}
|
|
207
35
|
var COMPONENT_OWNER_REGISTRY = /* @__PURE__ */ Symbol.for("forgeax.ecs.componentOwnerRegistry");
|
|
208
36
|
var ownerSymbols = globalThis;
|
|
209
37
|
var ownerRegistry = ownerSymbols[COMPONENT_OWNER_REGISTRY] ?? (() => {
|
|
@@ -215,11 +43,6 @@ var ownerRegistry = ownerSymbols[COMPONENT_OWNER_REGISTRY] ?? (() => {
|
|
|
215
43
|
ownerSymbols[COMPONENT_OWNER_REGISTRY] = registry;
|
|
216
44
|
return registry;
|
|
217
45
|
})();
|
|
218
|
-
var entityDefinitionSeen = false;
|
|
219
|
-
var componentDefinedBeforeEntity = false;
|
|
220
|
-
function isComponentDefinitionOrderValid() {
|
|
221
|
-
return !componentDefinedBeforeEntity;
|
|
222
|
-
}
|
|
223
46
|
function componentId(component) {
|
|
224
47
|
const id = ownerRegistry.ids.get(component);
|
|
225
48
|
if (id === void 0) throw new Error(`Component identity missing for '${component.name}'.`);
|
|
@@ -257,7 +80,7 @@ function scalarRow(t) {
|
|
|
257
80
|
isArray: false
|
|
258
81
|
};
|
|
259
82
|
}
|
|
260
|
-
|
|
83
|
+
Object.freeze({
|
|
261
84
|
f32: scalarRow("f32"),
|
|
262
85
|
f64: scalarRow("f64"),
|
|
263
86
|
i32: scalarRow("i32"),
|
|
@@ -329,159 +152,6 @@ var TYPE_METADATA = Object.freeze({
|
|
|
329
152
|
isArray: true
|
|
330
153
|
}
|
|
331
154
|
});
|
|
332
|
-
function fieldSpecType(fieldName, spec) {
|
|
333
|
-
if (typeof spec === "string") return spec;
|
|
334
|
-
const t = spec.type;
|
|
335
|
-
if (typeof t !== "string") {
|
|
336
|
-
throw new SchemaUnsupportedFieldError(
|
|
337
|
-
fieldName,
|
|
338
|
-
`<field-descriptor missing 'type'> (expected { type, default?, meta? })`
|
|
339
|
-
);
|
|
340
|
-
}
|
|
341
|
-
return t;
|
|
342
|
-
}
|
|
343
|
-
function defineComponent(name, fields, options) {
|
|
344
|
-
const storage = options?.storage ?? "table";
|
|
345
|
-
assertComponentStorage(storage);
|
|
346
|
-
if (storage === "sparse" && Object.keys(fields).length !== 0) {
|
|
347
|
-
throw new SparseStorageRequiresTagError(name);
|
|
348
|
-
}
|
|
349
|
-
const schema = {};
|
|
350
|
-
const reflectedFields = {};
|
|
351
|
-
const collectedMeta = {};
|
|
352
|
-
const collectedDefaults = {};
|
|
353
|
-
for (const fieldName of Object.keys(fields)) {
|
|
354
|
-
const spec = fields[fieldName];
|
|
355
|
-
const fieldType = fieldSpecType(fieldName, spec);
|
|
356
|
-
let arrayMeta;
|
|
357
|
-
if (TYPE_METADATA[fieldType]?.isScalar === true) ; else if (fieldType === "string") ; else if (fieldType.startsWith("array<") && fieldType.endsWith(">")) {
|
|
358
|
-
const parsed = parseManagedArraySchema(fieldType);
|
|
359
|
-
if (parsed === null) {
|
|
360
|
-
const elementType = fieldType.slice(6, -1);
|
|
361
|
-
throw new ManagedArrayElementTypeNotAllowedError(fieldName, elementType);
|
|
362
|
-
}
|
|
363
|
-
arrayMeta = deepFreeze(
|
|
364
|
-
parsed.length === void 0 ? { elementType: parsed.elementType } : { elementType: parsed.elementType, length: parsed.length }
|
|
365
|
-
);
|
|
366
|
-
} else if (!isSchemaVocabKeyword(fieldType)) {
|
|
367
|
-
throw new SchemaUnsupportedFieldError(fieldName, fieldType);
|
|
368
|
-
}
|
|
369
|
-
schema[fieldName] = fieldType;
|
|
370
|
-
const row = {
|
|
371
|
-
type: fieldType
|
|
372
|
-
};
|
|
373
|
-
if (typeof spec !== "string") {
|
|
374
|
-
const desc = spec;
|
|
375
|
-
if ("default" in desc) {
|
|
376
|
-
row.default = desc.default;
|
|
377
|
-
collectedDefaults[fieldName] = desc.default;
|
|
378
|
-
}
|
|
379
|
-
if (desc.shape !== void 0) row.shape = desc.shape;
|
|
380
|
-
if (desc.meta !== void 0) {
|
|
381
|
-
Object.assign(collectedMeta, desc.meta);
|
|
382
|
-
}
|
|
383
|
-
if (desc.transient !== void 0) row.transient = desc.transient;
|
|
384
|
-
if (desc.labels !== void 0) row.labels = deepFreeze({ ...desc.labels });
|
|
385
|
-
}
|
|
386
|
-
if (arrayMeta !== void 0) row.arrayMeta = arrayMeta;
|
|
387
|
-
reflectedFields[fieldName] = Object.freeze(row);
|
|
388
|
-
}
|
|
389
|
-
if (name === "Entity") {
|
|
390
|
-
entityDefinitionSeen = true;
|
|
391
|
-
} else if (!entityDefinitionSeen) {
|
|
392
|
-
componentDefinedBeforeEntity = true;
|
|
393
|
-
}
|
|
394
|
-
const id = name === "Entity" ? 0 : ownerRegistry.nextId++;
|
|
395
|
-
const frozenDefaults = Object.keys(collectedDefaults).length === 0 ? void 0 : deepFreeze(collectedDefaults);
|
|
396
|
-
if (options?.meta !== void 0) {
|
|
397
|
-
Object.assign(collectedMeta, options.meta);
|
|
398
|
-
}
|
|
399
|
-
const frozenSchema = deepFreeze(schema);
|
|
400
|
-
const frozenFields = deepFreeze(reflectedFields);
|
|
401
|
-
const meta = collectedMeta;
|
|
402
|
-
const token = Object.freeze({ name, fields: frozenFields, storage });
|
|
403
|
-
ownerRegistry.ids.set(token, id);
|
|
404
|
-
ownerRegistry.schemas.set(token, frozenSchema);
|
|
405
|
-
registerComponentDefinition(token, {
|
|
406
|
-
fields: frozenFields,
|
|
407
|
-
defaults: frozenDefaults,
|
|
408
|
-
policy: {
|
|
409
|
-
transient: options?.transient ?? false,
|
|
410
|
-
meta,
|
|
411
|
-
requires: Object.freeze([...options?.requires ?? []])
|
|
412
|
-
}
|
|
413
|
-
});
|
|
414
|
-
return Object.freeze(token);
|
|
415
|
-
}
|
|
416
|
-
var ComponentInUseError = class extends Error {
|
|
417
|
-
name = "ComponentInUseError";
|
|
418
|
-
code = "component-in-use";
|
|
419
|
-
expected = "the component to have no live entity or scheduled-system references";
|
|
420
|
-
hint = "Remove owning systems and component values before disposing the registration lease.";
|
|
421
|
-
detail;
|
|
422
|
-
constructor(componentName) {
|
|
423
|
-
super(`Component ${componentName} is still in use.`);
|
|
424
|
-
this.detail = { componentName };
|
|
425
|
-
}
|
|
426
|
-
};
|
|
427
|
-
var ComponentNameConflictError = class extends Error {
|
|
428
|
-
name = "ComponentNameConflictError";
|
|
429
|
-
code = "component-name-conflict";
|
|
430
|
-
expected = "one component token per name in a World";
|
|
431
|
-
hint = "Use the token already registered in this World or choose a distinct component name.";
|
|
432
|
-
detail;
|
|
433
|
-
constructor(componentName) {
|
|
434
|
-
super(`Component ${componentName} is already registered with a different token.`);
|
|
435
|
-
this.detail = { componentName };
|
|
436
|
-
}
|
|
437
|
-
};
|
|
438
|
-
var ComponentCatalog = class {
|
|
439
|
-
constructor(inUse) {
|
|
440
|
-
this.inUse = inUse;
|
|
441
|
-
}
|
|
442
|
-
inUse;
|
|
443
|
-
registrations = /* @__PURE__ */ new Map();
|
|
444
|
-
register(component) {
|
|
445
|
-
const current = this.registrations.get(component.name);
|
|
446
|
-
if (current !== void 0 && current.component !== component) {
|
|
447
|
-
return err(new ComponentNameConflictError(component.name));
|
|
448
|
-
}
|
|
449
|
-
if (current === void 0) {
|
|
450
|
-
this.registrations.set(component.name, { component, owners: 1 });
|
|
451
|
-
} else {
|
|
452
|
-
current.owners += 1;
|
|
453
|
-
}
|
|
454
|
-
let active = true;
|
|
455
|
-
return ok({
|
|
456
|
-
component,
|
|
457
|
-
dispose: () => {
|
|
458
|
-
if (!active) return ok(void 0);
|
|
459
|
-
const registration = this.registrations.get(component.name);
|
|
460
|
-
if (registration === void 0 || registration.component !== component) {
|
|
461
|
-
active = false;
|
|
462
|
-
return ok(void 0);
|
|
463
|
-
}
|
|
464
|
-
if (registration.owners > 1) {
|
|
465
|
-
registration.owners -= 1;
|
|
466
|
-
active = false;
|
|
467
|
-
return ok(void 0);
|
|
468
|
-
}
|
|
469
|
-
if (this.inUse(component)) return err(new ComponentInUseError(component.name));
|
|
470
|
-
this.registrations.delete(component.name);
|
|
471
|
-
active = false;
|
|
472
|
-
return ok(void 0);
|
|
473
|
-
}
|
|
474
|
-
});
|
|
475
|
-
}
|
|
476
|
-
resolve(name) {
|
|
477
|
-
return this.registrations.get(name)?.component;
|
|
478
|
-
}
|
|
479
|
-
entries() {
|
|
480
|
-
return new Map(
|
|
481
|
-
[...this.registrations].map(([name, registration]) => [name, registration.component])
|
|
482
|
-
);
|
|
483
|
-
}
|
|
484
|
-
};
|
|
485
155
|
|
|
486
156
|
// src/internal.ts
|
|
487
157
|
var DERIVED_WRITER = /* @__PURE__ */ Symbol.for(
|
|
@@ -492,6 +162,6 @@ function getDerivedWriter(query, component) {
|
|
|
492
162
|
return internalQuery[DERIVED_WRITER](component);
|
|
493
163
|
}
|
|
494
164
|
|
|
495
|
-
export {
|
|
165
|
+
export { DERIVED_WRITER, componentDefinition, componentId, componentSchema, getDerivedWriter };
|
|
496
166
|
//# sourceMappingURL=internal.mjs.map
|
|
497
167
|
//# sourceMappingURL=internal.mjs.map
|