archetype-ecs 1.2.0 → 1.3.2
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 +126 -63
- package/bench/allocations-1m.js +1 -1
- package/bench/multi-ecs-bench.js +1 -1
- package/bench/typed-vs-bitecs-1m.js +1 -1
- package/bench/typed-vs-untyped.js +81 -81
- package/bench/vs-bitecs.js +31 -56
- package/dist/ComponentRegistry.d.ts +18 -0
- package/dist/ComponentRegistry.js +29 -0
- package/dist/EntityManager.d.ts +52 -0
- package/dist/EntityManager.js +891 -0
- package/dist/Profiler.d.ts +12 -0
- package/dist/Profiler.js +38 -0
- package/dist/System.d.ts +41 -0
- package/dist/System.js +159 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +29 -0
- package/dist/src/ComponentRegistry.d.ts +18 -0
- package/dist/src/ComponentRegistry.js +29 -0
- package/dist/src/EntityManager.d.ts +49 -0
- package/dist/src/EntityManager.js +853 -0
- package/dist/src/Profiler.d.ts +12 -0
- package/dist/src/Profiler.js +38 -0
- package/dist/src/System.d.ts +37 -0
- package/dist/src/System.js +139 -0
- package/dist/src/index.d.ts +14 -0
- package/dist/src/index.js +29 -0
- package/dist/tests/EntityManager.test.d.ts +1 -0
- package/dist/tests/EntityManager.test.js +651 -0
- package/dist/tests/System.test.d.ts +1 -0
- package/dist/tests/System.test.js +630 -0
- package/dist/tests/types.d.ts +1 -0
- package/dist/tests/types.js +129 -0
- package/package.json +9 -7
- package/src/ComponentRegistry.ts +49 -0
- package/src/EntityManager.ts +1018 -0
- package/src/{Profiler.js → Profiler.ts} +18 -5
- package/src/System.ts +226 -0
- package/src/index.ts +44 -0
- package/tests/{EntityManager.test.js → EntityManager.test.ts} +338 -70
- package/tests/System.test.ts +730 -0
- package/tests/types.ts +67 -66
- package/tsconfig.json +8 -5
- package/tsconfig.test.json +13 -0
- package/.claude/settings.local.json +0 -32
- package/src/ComponentRegistry.js +0 -21
- package/src/EntityManager.js +0 -462
- package/src/index.d.ts +0 -111
- package/src/index.js +0 -37
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface ProfilerEntry {
|
|
2
|
+
avg: number;
|
|
3
|
+
}
|
|
4
|
+
export interface Profiler {
|
|
5
|
+
readonly enabled: boolean;
|
|
6
|
+
setEnabled(value: boolean): void;
|
|
7
|
+
begin(): number;
|
|
8
|
+
end(name: string, t0: number): void;
|
|
9
|
+
record(name: string, ms: number): void;
|
|
10
|
+
getData(): Map<string, ProfilerEntry>;
|
|
11
|
+
}
|
|
12
|
+
export declare const profiler: Profiler;
|
package/dist/Profiler.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const EMA_ALPHA = 0.1;
|
|
2
|
+
const data = new Map();
|
|
3
|
+
let enabled = false;
|
|
4
|
+
export const profiler = {
|
|
5
|
+
get enabled() { return enabled; },
|
|
6
|
+
setEnabled(value) {
|
|
7
|
+
enabled = value;
|
|
8
|
+
if (!value)
|
|
9
|
+
data.clear();
|
|
10
|
+
},
|
|
11
|
+
begin() {
|
|
12
|
+
return enabled ? performance.now() : 0;
|
|
13
|
+
},
|
|
14
|
+
end(name, t0) {
|
|
15
|
+
if (!enabled)
|
|
16
|
+
return;
|
|
17
|
+
const ms = performance.now() - t0;
|
|
18
|
+
const entry = data.get(name);
|
|
19
|
+
if (entry) {
|
|
20
|
+
entry.avg += (ms - entry.avg) * EMA_ALPHA;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
data.set(name, { avg: ms });
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
record(name, ms) {
|
|
27
|
+
if (!enabled)
|
|
28
|
+
return;
|
|
29
|
+
const entry = data.get(name);
|
|
30
|
+
if (entry) {
|
|
31
|
+
entry.avg += (ms - entry.avg) * EMA_ALPHA;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
data.set(name, { avg: ms });
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
getData() { return data; }
|
|
38
|
+
};
|
package/dist/System.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ComponentDef } from './ComponentRegistry.js';
|
|
2
|
+
import type { EntityId, EntityManager, ArchetypeView } from './EntityManager.js';
|
|
3
|
+
export declare function OnAdded(...types: ComponentDef[]): (method: (id: EntityId) => void, _context: ClassMethodDecoratorContext) => void;
|
|
4
|
+
export declare function OnRemoved(...types: ComponentDef[]): (method: (id: EntityId) => void, _context: ClassMethodDecoratorContext) => void;
|
|
5
|
+
interface Hook {
|
|
6
|
+
buffer: Set<EntityId>;
|
|
7
|
+
handler: (id: EntityId) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare class System {
|
|
10
|
+
em: EntityManager;
|
|
11
|
+
_unsubs: (() => void)[];
|
|
12
|
+
_hooks: Hook[];
|
|
13
|
+
constructor(em: EntityManager);
|
|
14
|
+
_registerHook(kind: 'add' | 'remove', types: ComponentDef[], handler: (id: EntityId) => void): void;
|
|
15
|
+
forEach(types: ComponentDef[], callback: (view: ArchetypeView) => void, exclude?: ComponentDef[]): void;
|
|
16
|
+
tick?(): void;
|
|
17
|
+
/** Process hooks and tick without clearing removed-data snapshots. */
|
|
18
|
+
_runCore(): void;
|
|
19
|
+
run(): void;
|
|
20
|
+
dispose(): void;
|
|
21
|
+
}
|
|
22
|
+
type HookCallback = (entityId: EntityId) => void;
|
|
23
|
+
export interface SystemContext {
|
|
24
|
+
onAdded(...args: [...ComponentDef[], HookCallback]): void;
|
|
25
|
+
onRemoved(...args: [...ComponentDef[], HookCallback]): void;
|
|
26
|
+
forEach(types: ComponentDef[], callback: (view: ArchetypeView) => void, exclude?: ComponentDef[]): void;
|
|
27
|
+
}
|
|
28
|
+
export type FunctionalSystemConstructor = (sys: SystemContext) => (() => void) | void;
|
|
29
|
+
export interface FunctionalSystem {
|
|
30
|
+
(): void;
|
|
31
|
+
/** @internal Process hooks and tick without clearing removed-data snapshots. */
|
|
32
|
+
_runCore(): void;
|
|
33
|
+
dispose(): void;
|
|
34
|
+
}
|
|
35
|
+
export declare function createSystem(em: EntityManager, constructor: FunctionalSystemConstructor): FunctionalSystem;
|
|
36
|
+
export interface Pipeline {
|
|
37
|
+
(): void;
|
|
38
|
+
dispose(): void;
|
|
39
|
+
}
|
|
40
|
+
export declare function createSystems(em: EntityManager, entries: (FunctionalSystemConstructor | (new (em: EntityManager) => System))[]): Pipeline;
|
|
41
|
+
export {};
|
package/dist/System.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
// ── Decorators (TC39 Stage 3) ────────────────────────────
|
|
2
|
+
export function OnAdded(...types) {
|
|
3
|
+
return function (method, _context) {
|
|
4
|
+
_context.addInitializer(function () {
|
|
5
|
+
const self = this;
|
|
6
|
+
self._registerHook('add', types, method.bind(self));
|
|
7
|
+
});
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function OnRemoved(...types) {
|
|
11
|
+
return function (method, _context) {
|
|
12
|
+
_context.addInitializer(function () {
|
|
13
|
+
const self = this;
|
|
14
|
+
self._registerHook('remove', types, method.bind(self));
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export class System {
|
|
19
|
+
em;
|
|
20
|
+
_unsubs = [];
|
|
21
|
+
_hooks = [];
|
|
22
|
+
constructor(em) {
|
|
23
|
+
this.em = em;
|
|
24
|
+
}
|
|
25
|
+
_registerHook(kind, types, handler) {
|
|
26
|
+
const buffer = new Set();
|
|
27
|
+
if (kind === 'add') {
|
|
28
|
+
for (const comp of types) {
|
|
29
|
+
const unsub = this.em.onAdd(comp, (id) => {
|
|
30
|
+
for (let i = 0; i < types.length; i++) {
|
|
31
|
+
if (!this.em.hasComponent(id, types[i]))
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
buffer.add(id);
|
|
35
|
+
});
|
|
36
|
+
this._unsubs.push(unsub);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
for (const comp of types) {
|
|
41
|
+
const unsub = this.em.onRemove(comp, (id) => buffer.add(id));
|
|
42
|
+
this._unsubs.push(unsub);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
this._hooks.push({ buffer, handler });
|
|
46
|
+
}
|
|
47
|
+
forEach(types, callback, exclude) {
|
|
48
|
+
this.em.forEach(types, callback, exclude);
|
|
49
|
+
}
|
|
50
|
+
/** Process hooks and tick without clearing removed-data snapshots. */
|
|
51
|
+
_runCore() {
|
|
52
|
+
for (const hook of this._hooks) {
|
|
53
|
+
for (const id of hook.buffer)
|
|
54
|
+
hook.handler(id);
|
|
55
|
+
hook.buffer.clear();
|
|
56
|
+
}
|
|
57
|
+
if (this.tick)
|
|
58
|
+
this.tick();
|
|
59
|
+
}
|
|
60
|
+
run() {
|
|
61
|
+
this._runCore();
|
|
62
|
+
this.em.commitRemovals();
|
|
63
|
+
}
|
|
64
|
+
dispose() {
|
|
65
|
+
for (const unsub of this._unsubs)
|
|
66
|
+
unsub();
|
|
67
|
+
this._unsubs.length = 0;
|
|
68
|
+
this._hooks.length = 0;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export function createSystem(em, constructor) {
|
|
72
|
+
const hooks = [];
|
|
73
|
+
const sys = {
|
|
74
|
+
onAdded(...args) {
|
|
75
|
+
const callback = args[args.length - 1];
|
|
76
|
+
const types = args.slice(0, -1);
|
|
77
|
+
const buffer = new Set();
|
|
78
|
+
const unsubs = [];
|
|
79
|
+
for (const comp of types) {
|
|
80
|
+
const unsub = em.onAdd(comp, (id) => {
|
|
81
|
+
for (let i = 0; i < types.length; i++) {
|
|
82
|
+
if (!em.hasComponent(id, types[i]))
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
buffer.add(id);
|
|
86
|
+
});
|
|
87
|
+
unsubs.push(unsub);
|
|
88
|
+
}
|
|
89
|
+
hooks.push({ unsubs, buffer, callback });
|
|
90
|
+
},
|
|
91
|
+
onRemoved(...args) {
|
|
92
|
+
const callback = args[args.length - 1];
|
|
93
|
+
const types = args.slice(0, -1);
|
|
94
|
+
const buffer = new Set();
|
|
95
|
+
const unsubs = [];
|
|
96
|
+
for (const comp of types) {
|
|
97
|
+
const unsub = em.onRemove(comp, (id) => {
|
|
98
|
+
buffer.add(id);
|
|
99
|
+
});
|
|
100
|
+
unsubs.push(unsub);
|
|
101
|
+
}
|
|
102
|
+
hooks.push({ unsubs, buffer, callback });
|
|
103
|
+
},
|
|
104
|
+
forEach(types, callback, exclude) {
|
|
105
|
+
em.forEach(types, callback, exclude);
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
const tick = constructor(sys);
|
|
109
|
+
function runCore() {
|
|
110
|
+
for (const hook of hooks) {
|
|
111
|
+
for (const id of hook.buffer)
|
|
112
|
+
hook.callback(id);
|
|
113
|
+
hook.buffer.clear();
|
|
114
|
+
}
|
|
115
|
+
if (tick)
|
|
116
|
+
tick();
|
|
117
|
+
}
|
|
118
|
+
function system() {
|
|
119
|
+
runCore();
|
|
120
|
+
em.commitRemovals();
|
|
121
|
+
}
|
|
122
|
+
system._runCore = runCore;
|
|
123
|
+
system.dispose = function () {
|
|
124
|
+
for (const hook of hooks) {
|
|
125
|
+
for (const unsub of hook.unsubs)
|
|
126
|
+
unsub();
|
|
127
|
+
}
|
|
128
|
+
hooks.length = 0;
|
|
129
|
+
};
|
|
130
|
+
return system;
|
|
131
|
+
}
|
|
132
|
+
function isSystemClass(entry) {
|
|
133
|
+
let proto = entry.prototype;
|
|
134
|
+
while (proto) {
|
|
135
|
+
proto = Object.getPrototypeOf(proto);
|
|
136
|
+
if (proto === System.prototype)
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
export function createSystems(em, entries) {
|
|
142
|
+
const systems = entries.map(Entry => {
|
|
143
|
+
if (isSystemClass(Entry)) {
|
|
144
|
+
return new Entry(em);
|
|
145
|
+
}
|
|
146
|
+
const sys = createSystem(em, Entry);
|
|
147
|
+
return { _runCore: sys._runCore, dispose: sys.dispose };
|
|
148
|
+
});
|
|
149
|
+
function pipeline() {
|
|
150
|
+
for (let i = 0; i < systems.length; i++)
|
|
151
|
+
systems[i]._runCore();
|
|
152
|
+
em.commitRemovals();
|
|
153
|
+
}
|
|
154
|
+
pipeline.dispose = function () {
|
|
155
|
+
for (let i = 0; i < systems.length; i++)
|
|
156
|
+
systems[i].dispose();
|
|
157
|
+
};
|
|
158
|
+
return pipeline;
|
|
159
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { createEntityManager } from './EntityManager.js';
|
|
2
|
+
export type { EntityId, ArchetypeView, EntityManager, SerializedData } from './EntityManager.js';
|
|
3
|
+
export { createSystem, createSystems, System, OnAdded, OnRemoved } from './System.js';
|
|
4
|
+
export type { SystemContext, FunctionalSystemConstructor, FunctionalSystem, Pipeline } from './System.js';
|
|
5
|
+
export { profiler } from './Profiler.js';
|
|
6
|
+
export type { Profiler, ProfilerEntry } from './Profiler.js';
|
|
7
|
+
export { TYPED, componentSchemas, parseTypeSpec } from './ComponentRegistry.js';
|
|
8
|
+
export type { ComponentDef, FieldRef, TypeSpec } from './ComponentRegistry.js';
|
|
9
|
+
import { type ComponentDef } from './ComponentRegistry.js';
|
|
10
|
+
export declare function component(name: string): ComponentDef;
|
|
11
|
+
export declare function component<const F extends readonly string[]>(name: string, type: string, fields: F): ComponentDef<F[number]>;
|
|
12
|
+
export declare function component<S extends Record<string, string>>(name: string, schema: S): ComponentDef<Extract<keyof S, string>>;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export { createEntityManager } from './EntityManager.js';
|
|
2
|
+
export { createSystem, createSystems, System, OnAdded, OnRemoved } from './System.js';
|
|
3
|
+
export { profiler } from './Profiler.js';
|
|
4
|
+
export { TYPED, componentSchemas, parseTypeSpec } from './ComponentRegistry.js';
|
|
5
|
+
import { parseTypeSpec, componentSchemas } from './ComponentRegistry.js';
|
|
6
|
+
export function component(name, typeOrSchema, fields) {
|
|
7
|
+
const sym = Symbol(name);
|
|
8
|
+
const comp = { _sym: sym, _name: name };
|
|
9
|
+
let schema;
|
|
10
|
+
if (typeof typeOrSchema === 'string' && Array.isArray(fields)) {
|
|
11
|
+
const spec = parseTypeSpec(typeOrSchema);
|
|
12
|
+
schema = {};
|
|
13
|
+
for (const f of fields) {
|
|
14
|
+
schema[f] = spec;
|
|
15
|
+
comp[f] = { _sym: sym, _field: f };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
else if (typeOrSchema && typeof typeOrSchema === 'object') {
|
|
19
|
+
schema = {};
|
|
20
|
+
for (const [field, type] of Object.entries(typeOrSchema)) {
|
|
21
|
+
schema[field] = parseTypeSpec(type);
|
|
22
|
+
comp[field] = { _sym: sym, _field: field };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (schema) {
|
|
26
|
+
componentSchemas.set(sym, schema);
|
|
27
|
+
}
|
|
28
|
+
return comp;
|
|
29
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const TYPED: unique symbol;
|
|
2
|
+
type TypedArrayConstructor = typeof Float32Array | typeof Float64Array | typeof Int8Array | typeof Int16Array | typeof Int32Array | typeof Uint8Array | typeof Uint16Array | typeof Uint32Array | typeof Array;
|
|
3
|
+
export declare const TYPE_MAP: Record<string, TypedArrayConstructor>;
|
|
4
|
+
export type TypeSpec = TypedArrayConstructor | [TypedArrayConstructor, number];
|
|
5
|
+
export declare function parseTypeSpec(typeStr: string): TypeSpec;
|
|
6
|
+
export declare const componentSchemas: Map<symbol, Record<string, TypeSpec>>;
|
|
7
|
+
export interface FieldRef {
|
|
8
|
+
readonly _sym: symbol;
|
|
9
|
+
readonly _field: string;
|
|
10
|
+
}
|
|
11
|
+
export type ComponentDef<S extends Record<string, string> = {}> = {
|
|
12
|
+
readonly _sym: symbol;
|
|
13
|
+
readonly _name: string;
|
|
14
|
+
} & {
|
|
15
|
+
readonly [K in keyof S]: FieldRef;
|
|
16
|
+
};
|
|
17
|
+
export declare function toSym(type: ComponentDef | symbol): symbol;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const TYPED = Symbol('typed');
|
|
2
|
+
export const TYPE_MAP = {
|
|
3
|
+
'f32': Float32Array,
|
|
4
|
+
'f64': Float64Array,
|
|
5
|
+
'i8': Int8Array,
|
|
6
|
+
'i16': Int16Array,
|
|
7
|
+
'i32': Int32Array,
|
|
8
|
+
'u8': Uint8Array,
|
|
9
|
+
'u16': Uint16Array,
|
|
10
|
+
'u32': Uint32Array,
|
|
11
|
+
'string': Array,
|
|
12
|
+
};
|
|
13
|
+
export function parseTypeSpec(typeStr) {
|
|
14
|
+
const match = typeStr.match(/^(\w+)\[(\d+)\]$/);
|
|
15
|
+
if (match) {
|
|
16
|
+
const Ctor = TYPE_MAP[match[1]];
|
|
17
|
+
if (!Ctor)
|
|
18
|
+
throw new Error(`Unknown base type "${match[1]}"`);
|
|
19
|
+
return [Ctor, parseInt(match[2])];
|
|
20
|
+
}
|
|
21
|
+
const Ctor = TYPE_MAP[typeStr];
|
|
22
|
+
if (!Ctor)
|
|
23
|
+
throw new Error(`Unknown type "${typeStr}"`);
|
|
24
|
+
return Ctor;
|
|
25
|
+
}
|
|
26
|
+
export const componentSchemas = new Map();
|
|
27
|
+
export function toSym(type) {
|
|
28
|
+
return type._sym || type;
|
|
29
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type ComponentDef, type FieldRef } from './ComponentRegistry.js';
|
|
2
|
+
export type { FieldRef } from './ComponentRegistry.js';
|
|
3
|
+
export type EntityId = number;
|
|
4
|
+
export interface ArchetypeView {
|
|
5
|
+
readonly id: number;
|
|
6
|
+
readonly entityIds: EntityId[];
|
|
7
|
+
readonly count: number;
|
|
8
|
+
readonly snapshotEntityIds: EntityId[] | null;
|
|
9
|
+
readonly snapshotCount: number;
|
|
10
|
+
field(ref: FieldRef): any;
|
|
11
|
+
fieldStride(ref: FieldRef): number;
|
|
12
|
+
snapshot(ref: FieldRef): any;
|
|
13
|
+
}
|
|
14
|
+
export interface SerializedData {
|
|
15
|
+
nextId: number;
|
|
16
|
+
entities: EntityId[];
|
|
17
|
+
components: Record<string, Record<string, unknown>>;
|
|
18
|
+
}
|
|
19
|
+
export interface EntityManager {
|
|
20
|
+
createEntity(): EntityId;
|
|
21
|
+
destroyEntity(id: EntityId): void;
|
|
22
|
+
addComponent(entityId: EntityId, type: ComponentDef, data?: any): void;
|
|
23
|
+
removeComponent(entityId: EntityId, type: ComponentDef): void;
|
|
24
|
+
getComponent(entityId: EntityId, type: ComponentDef): any;
|
|
25
|
+
get(entityId: EntityId, fieldRef: FieldRef): any;
|
|
26
|
+
set(entityId: EntityId, fieldRef: FieldRef, value: any): void;
|
|
27
|
+
hasComponent(entityId: EntityId, type: ComponentDef): boolean;
|
|
28
|
+
query(include: ComponentDef[], exclude?: ComponentDef[]): EntityId[];
|
|
29
|
+
getAllEntities(): EntityId[];
|
|
30
|
+
createEntityWith(...args: unknown[]): EntityId;
|
|
31
|
+
count(include: ComponentDef[], exclude?: ComponentDef[]): number;
|
|
32
|
+
forEach(include: ComponentDef[], callback: (view: ArchetypeView) => void, exclude?: ComponentDef[]): void;
|
|
33
|
+
onAdd(type: ComponentDef, callback: (entityId: EntityId) => void): () => void;
|
|
34
|
+
onRemove(type: ComponentDef, callback: (entityId: EntityId) => void): () => void;
|
|
35
|
+
flushHooks(): void;
|
|
36
|
+
enableTracking(filterComponent: ComponentDef): void;
|
|
37
|
+
flushChanges(): {
|
|
38
|
+
created: Set<EntityId>;
|
|
39
|
+
destroyed: Set<EntityId>;
|
|
40
|
+
};
|
|
41
|
+
flushSnapshots(): void;
|
|
42
|
+
serialize(symbolToName: Map<symbol, string>, stripComponents?: ComponentDef[], skipEntitiesWith?: ComponentDef[], options?: {
|
|
43
|
+
serializers?: Map<string, (data: unknown) => unknown>;
|
|
44
|
+
}): SerializedData;
|
|
45
|
+
deserialize(data: SerializedData, nameToSymbol: Record<string, ComponentDef>, options?: {
|
|
46
|
+
deserializers?: Map<string, (data: unknown) => unknown>;
|
|
47
|
+
}): void;
|
|
48
|
+
}
|
|
49
|
+
export declare function createEntityManager(): EntityManager;
|