aiecsjs 0.2.0 → 0.3.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/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { o as WorldOptions, W as World, E as EntityId, c as ComponentLike, b as ComponentInit, k as SoASchema, h as SoAComponent, A as AoSComponent, T as TagComponent, f as QueryDescriptor, Q as Query, a as Archetype, l as System } from './types-BGEeHad-.cjs';
2
2
  export { d as ComponentView, g as SoAColumns, i as SoAFieldDecl, j as SoAFieldType, n as Types } from './types-BGEeHad-.cjs';
3
3
 
4
- declare const VERSION = "0.2.0";
4
+ declare const VERSION = "0.3.0";
5
5
 
6
6
  declare function createWorld(options?: WorldOptions): World;
7
7
  declare function destroyWorld(world: World): void;
@@ -13,9 +13,28 @@ declare function isWorld(x: unknown): x is World;
13
13
  declare function createEntity(world: World): EntityId;
14
14
  declare function destroyEntity(world: World, eid: EntityId): void;
15
15
  declare function entityExists(world: World, eid: EntityId): boolean;
16
+ /**
17
+ * Extract the index portion of a packed entity ID.
18
+ *
19
+ * Uses the default 24-bit index layout. If you created the world with a
20
+ * non-default `indexBits`, use `EntityRef` + `deref` instead.
21
+ */
16
22
  declare function getEntityIndex(eid: EntityId): number;
17
- declare function getEntityGeneration(_eid: EntityId): number;
18
- declare function packEntity(index: number, _generation: number): EntityId;
23
+ /**
24
+ * Extract the generation portion of a packed entity ID.
25
+ *
26
+ * Uses the default 8-bit generation layout. If you created the world with a
27
+ * non-default `generationBits`, use `EntityRef` + `deref` instead.
28
+ */
29
+ declare function getEntityGeneration(eid: EntityId): number;
30
+ /**
31
+ * Pack an index and generation into an EntityId using the default 24/8 bit layout.
32
+ *
33
+ * Uses the default `indexBits=24, generationBits=8`. If you created the world
34
+ * with non-default bit sizes, this will produce values with incorrect layout.
35
+ * Use `EntityRef` and `deref` for portable cross-world identity matching.
36
+ */
37
+ declare function packEntity(index: number, generation: number): EntityId;
19
38
  declare function isEntity(world: World, x: unknown): x is EntityId;
20
39
 
21
40
  declare function defineComponent<S extends SoASchema>(schema: S): SoAComponent<S>;
@@ -37,6 +56,70 @@ declare function forEachEntity(world: World, query: Query, fn: (eid: EntityId, .
37
56
 
38
57
  declare function pipe<W extends World = World, Ctx = unknown>(...systems: System<W, Ctx>[]): System<W, Ctx>;
39
58
 
59
+ /**
60
+ * ABA-safe entity reference.
61
+ *
62
+ * Holds the packed EntityId and the id of the world that issued it.
63
+ * Use `deref(world, ref)` to validate and retrieve the live entity id.
64
+ *
65
+ * The phantom type `T` allows callers to distinguish reference kinds at the
66
+ * type system level — e.g. `EntityRef<'bullet'>` vs `EntityRef<'player'>` —
67
+ * without any runtime overhead.
68
+ *
69
+ * @example
70
+ * const ref = refOf<'bullet'>(world, e)
71
+ * // later, in a system:
72
+ * const live = deref(world, ref)
73
+ * if (live !== null) {
74
+ * // entity is still alive with the same generation
75
+ * }
76
+ */
77
+ interface EntityRef<T = unknown> {
78
+ readonly id: EntityId;
79
+ readonly worldId: number;
80
+ readonly __phantom?: T;
81
+ }
82
+ /**
83
+ * Thrown by `refOf` when the entity is not alive.
84
+ * `deref` and `aliveRef` never throw — they return null/false.
85
+ */
86
+ declare class EntityNotAliveError extends Error {
87
+ readonly eid: number;
88
+ constructor(eid: number);
89
+ }
90
+ /**
91
+ * Create an ABA-safe reference to a live entity.
92
+ *
93
+ * @throws {EntityNotAliveError} if the entity is not alive (dead, never created, or eid === 0).
94
+ *
95
+ * The returned object is frozen. `id` is the packed EntityId; `worldId` is
96
+ * the world's numeric id used by `deref` to reject cross-world lookups.
97
+ *
98
+ * The function may be called on the hot path — each call returns a new object
99
+ * but performs no allocation beyond that.
100
+ */
101
+ declare function refOf<T = unknown>(world: World, entity: EntityId): EntityRef<T>;
102
+ /**
103
+ * Resolve a ref to its live EntityId, or return null if stale.
104
+ *
105
+ * Returns null when any of the following hold:
106
+ * 1. `ref.worldId !== state.id` — cross-world ref
107
+ * 2. `getEntityIndex(ref.id) >= state.capacity` — index out-of-bounds
108
+ * 3. `getEntityIndex(ref.id) === 0` — sentinel slot
109
+ * 4. entity is not in any archetype's entityRow (slot released)
110
+ * 5. generation mismatch → ABA: old ref points at recycled slot
111
+ *
112
+ * Never throws.
113
+ */
114
+ declare function deref<T = unknown>(world: World, ref: EntityRef<T>): EntityId | null;
115
+ /**
116
+ * Boolean guard form of `deref`. Equivalent to `deref(world, ref) !== null`.
117
+ * Use in guard clauses when you do not need the resolved EntityId.
118
+ *
119
+ * Never throws.
120
+ */
121
+ declare function aliveRef<T = unknown>(world: World, ref: EntityRef<T>): boolean;
122
+
40
123
  declare const IS_SAB_SUPPORTED: boolean;
41
124
 
42
- export { AoSComponent, Archetype, ComponentInit, ComponentLike, EntityId, IS_SAB_SUPPORTED, Query, QueryDescriptor, SoAComponent, SoASchema, System, TagComponent, VERSION, World, WorldOptions, addComponent, createEntity, createWorld, defineComponent, defineObjectComponent, defineQuery, defineTag, destroyEntity, destroyWorld, destroyWorld as disposeWorld, enterQuery, entityExists, exitQuery, forEachEntity, getComponent, getEntityGeneration, getEntityIndex, getWorldCapacity, getWorldSize, hasComponent, isEntity, isWorld, iterQuery, packEntity, pipe, queryArchetypes, removeComponent, resetWorld, runQuery, setComponent };
125
+ export { AoSComponent, Archetype, ComponentInit, ComponentLike, EntityId, EntityNotAliveError, type EntityRef, IS_SAB_SUPPORTED, Query, QueryDescriptor, SoAComponent, SoASchema, System, TagComponent, VERSION, World, WorldOptions, addComponent, aliveRef, createEntity, createWorld, defineComponent, defineObjectComponent, defineQuery, defineTag, deref, destroyEntity, destroyWorld, destroyWorld as disposeWorld, enterQuery, entityExists, exitQuery, forEachEntity, getComponent, getEntityGeneration, getEntityIndex, getWorldCapacity, getWorldSize, hasComponent, isEntity, isWorld, iterQuery, packEntity, pipe, queryArchetypes, refOf, removeComponent, resetWorld, runQuery, setComponent };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { o as WorldOptions, W as World, E as EntityId, c as ComponentLike, b as ComponentInit, k as SoASchema, h as SoAComponent, A as AoSComponent, T as TagComponent, f as QueryDescriptor, Q as Query, a as Archetype, l as System } from './types-BGEeHad-.js';
2
2
  export { d as ComponentView, g as SoAColumns, i as SoAFieldDecl, j as SoAFieldType, n as Types } from './types-BGEeHad-.js';
3
3
 
4
- declare const VERSION = "0.2.0";
4
+ declare const VERSION = "0.3.0";
5
5
 
6
6
  declare function createWorld(options?: WorldOptions): World;
7
7
  declare function destroyWorld(world: World): void;
@@ -13,9 +13,28 @@ declare function isWorld(x: unknown): x is World;
13
13
  declare function createEntity(world: World): EntityId;
14
14
  declare function destroyEntity(world: World, eid: EntityId): void;
15
15
  declare function entityExists(world: World, eid: EntityId): boolean;
16
+ /**
17
+ * Extract the index portion of a packed entity ID.
18
+ *
19
+ * Uses the default 24-bit index layout. If you created the world with a
20
+ * non-default `indexBits`, use `EntityRef` + `deref` instead.
21
+ */
16
22
  declare function getEntityIndex(eid: EntityId): number;
17
- declare function getEntityGeneration(_eid: EntityId): number;
18
- declare function packEntity(index: number, _generation: number): EntityId;
23
+ /**
24
+ * Extract the generation portion of a packed entity ID.
25
+ *
26
+ * Uses the default 8-bit generation layout. If you created the world with a
27
+ * non-default `generationBits`, use `EntityRef` + `deref` instead.
28
+ */
29
+ declare function getEntityGeneration(eid: EntityId): number;
30
+ /**
31
+ * Pack an index and generation into an EntityId using the default 24/8 bit layout.
32
+ *
33
+ * Uses the default `indexBits=24, generationBits=8`. If you created the world
34
+ * with non-default bit sizes, this will produce values with incorrect layout.
35
+ * Use `EntityRef` and `deref` for portable cross-world identity matching.
36
+ */
37
+ declare function packEntity(index: number, generation: number): EntityId;
19
38
  declare function isEntity(world: World, x: unknown): x is EntityId;
20
39
 
21
40
  declare function defineComponent<S extends SoASchema>(schema: S): SoAComponent<S>;
@@ -37,6 +56,70 @@ declare function forEachEntity(world: World, query: Query, fn: (eid: EntityId, .
37
56
 
38
57
  declare function pipe<W extends World = World, Ctx = unknown>(...systems: System<W, Ctx>[]): System<W, Ctx>;
39
58
 
59
+ /**
60
+ * ABA-safe entity reference.
61
+ *
62
+ * Holds the packed EntityId and the id of the world that issued it.
63
+ * Use `deref(world, ref)` to validate and retrieve the live entity id.
64
+ *
65
+ * The phantom type `T` allows callers to distinguish reference kinds at the
66
+ * type system level — e.g. `EntityRef<'bullet'>` vs `EntityRef<'player'>` —
67
+ * without any runtime overhead.
68
+ *
69
+ * @example
70
+ * const ref = refOf<'bullet'>(world, e)
71
+ * // later, in a system:
72
+ * const live = deref(world, ref)
73
+ * if (live !== null) {
74
+ * // entity is still alive with the same generation
75
+ * }
76
+ */
77
+ interface EntityRef<T = unknown> {
78
+ readonly id: EntityId;
79
+ readonly worldId: number;
80
+ readonly __phantom?: T;
81
+ }
82
+ /**
83
+ * Thrown by `refOf` when the entity is not alive.
84
+ * `deref` and `aliveRef` never throw — they return null/false.
85
+ */
86
+ declare class EntityNotAliveError extends Error {
87
+ readonly eid: number;
88
+ constructor(eid: number);
89
+ }
90
+ /**
91
+ * Create an ABA-safe reference to a live entity.
92
+ *
93
+ * @throws {EntityNotAliveError} if the entity is not alive (dead, never created, or eid === 0).
94
+ *
95
+ * The returned object is frozen. `id` is the packed EntityId; `worldId` is
96
+ * the world's numeric id used by `deref` to reject cross-world lookups.
97
+ *
98
+ * The function may be called on the hot path — each call returns a new object
99
+ * but performs no allocation beyond that.
100
+ */
101
+ declare function refOf<T = unknown>(world: World, entity: EntityId): EntityRef<T>;
102
+ /**
103
+ * Resolve a ref to its live EntityId, or return null if stale.
104
+ *
105
+ * Returns null when any of the following hold:
106
+ * 1. `ref.worldId !== state.id` — cross-world ref
107
+ * 2. `getEntityIndex(ref.id) >= state.capacity` — index out-of-bounds
108
+ * 3. `getEntityIndex(ref.id) === 0` — sentinel slot
109
+ * 4. entity is not in any archetype's entityRow (slot released)
110
+ * 5. generation mismatch → ABA: old ref points at recycled slot
111
+ *
112
+ * Never throws.
113
+ */
114
+ declare function deref<T = unknown>(world: World, ref: EntityRef<T>): EntityId | null;
115
+ /**
116
+ * Boolean guard form of `deref`. Equivalent to `deref(world, ref) !== null`.
117
+ * Use in guard clauses when you do not need the resolved EntityId.
118
+ *
119
+ * Never throws.
120
+ */
121
+ declare function aliveRef<T = unknown>(world: World, ref: EntityRef<T>): boolean;
122
+
40
123
  declare const IS_SAB_SUPPORTED: boolean;
41
124
 
42
- export { AoSComponent, Archetype, ComponentInit, ComponentLike, EntityId, IS_SAB_SUPPORTED, Query, QueryDescriptor, SoAComponent, SoASchema, System, TagComponent, VERSION, World, WorldOptions, addComponent, createEntity, createWorld, defineComponent, defineObjectComponent, defineQuery, defineTag, destroyEntity, destroyWorld, destroyWorld as disposeWorld, enterQuery, entityExists, exitQuery, forEachEntity, getComponent, getEntityGeneration, getEntityIndex, getWorldCapacity, getWorldSize, hasComponent, isEntity, isWorld, iterQuery, packEntity, pipe, queryArchetypes, removeComponent, resetWorld, runQuery, setComponent };
125
+ export { AoSComponent, Archetype, ComponentInit, ComponentLike, EntityId, EntityNotAliveError, type EntityRef, IS_SAB_SUPPORTED, Query, QueryDescriptor, SoAComponent, SoASchema, System, TagComponent, VERSION, World, WorldOptions, addComponent, aliveRef, createEntity, createWorld, defineComponent, defineObjectComponent, defineQuery, defineTag, deref, destroyEntity, destroyWorld, destroyWorld as disposeWorld, enterQuery, entityExists, exitQuery, forEachEntity, getComponent, getEntityGeneration, getEntityIndex, getWorldCapacity, getWorldSize, hasComponent, isEntity, isWorld, iterQuery, packEntity, pipe, queryArchetypes, refOf, removeComponent, resetWorld, runQuery, setComponent };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- var U="0.2.0";function b(n){return new Uint32Array(n)}function h(n,e){let t=e>>>5;n[t]=(n[t]??0)|1<<(e&31);}function D(n,e){let t=e>>>5;n[t]=(n[t]??0)&~(1<<(e&31));}function C(n,e){let t=e>>>5;return ((n[t]??0)&1<<(e&31))!==0}function g(n){let e=new Uint32Array(n.length);for(let t=0;t<n.length;t++)e[t]=n[t]??0;return e}function O(n){let e=[];for(let t=0;t<n.length;t++)e.push((n[t]??0).toString(16));return e.join(",")}function q(n){for(let e=0;e<n.length;e++)if((n[e]??0)!==0)return false;return true}function E(n,e,t,r,o,i){let s=!o;for(let a=0;a<i;a++){let c=n[a]??0,u=e[a]??0,d=t[a]??0,y=r[a]??0;if((c&u)!==u||(c&y)!==0)return false;!s&&(c&d)!==0&&(s=true);}return s}function W(n){let e=[];for(let t=0;t<n.length;t++){let r=n[t]??0;for(;r!==0;){let o=(t<<5)+P(r);e.push(o),r&=r-1;}}return e}function V(n,e,t,r){for(let o=0;o<t;o++){let i=n[e+o]??0;for(;i!==0;){let s=(o<<5)+P(i);r(s),i&=i-1;}}}function P(n){return 31-Math.clz32(n&-n)}var B={initialCapacity:1024,maxEntities:1e6,indexBits:24,generationBits:8},ye=256,fe=1,k=new Map;function f(n){let e=k.get(n.id);if(!e)throw new Error(`aiecsjs: world ${n.id} is destroyed or unknown`);if(e.destroyed)throw new Error(`aiecsjs: world ${n.id} is destroyed`);return e}function pe(n){k.set(n.id,n);}function le(n){k.delete(n);}function me(n){let e=n??{},t=e.indexBits??B.indexBits,r=e.generationBits??B.generationBits,o=ye;if(t<1||t>24)throw new Error("aiecsjs: indexBits must be in [1, 24]");if(r<0||r>16)throw new Error("aiecsjs: generationBits must be in [0, 16]");let i=1<<t,s=Math.max(1,Math.min(e.initialCapacity??B.initialCapacity,i)),a=Math.max(s,Math.min(e.maxEntities??B.maxEntities,i));return {initialCapacity:s,maxEntities:a,indexBits:t,generationBits:r,maxComponents:o,maskWordCount:Math.ceil(o/32),buffer:e.buffer??null,bufferByteOffset:e.bufferByteOffset??0}}function be(n,e){return {id:0,mask:b(n),size:0,capacity:16,entities:new Uint32Array(16),entityRow:new Map,componentBits:[],edgeAdd:new Int32Array(e).fill(-1),edgeRemove:new Int32Array(e).fill(-1)}}function he(n){let e=me(n),t=fe++,r=e.generationBits>8?Uint16Array:Uint8Array,o=new r(e.initialCapacity),i={id:t,capacity:e.initialCapacity,version:U,options:e,size:0,nextFreshIndex:1,freeList:[],generations:o,destroyed:false,componentBitFor:new Map,componentInfoByBit:new Array(e.maxComponents).fill(null),componentStorageByBit:new Array(e.maxComponents).fill(null),nextComponentBit:0,entityArchetype:new Uint32Array(e.initialCapacity),entityMask:new Uint32Array(e.initialCapacity*e.maskWordCount),archetypes:[],archetypeByMaskHash:new Map,queryVersion:0,queries:[],queryMasks:new Map,queryArchetypeCache:[],queryArchetypeStamp:[],bitToQueries:new Map,reactiveBuffers:new Map,observers:[],relationStorage:new Map,sab:e.buffer,readOnly:false},s=be(e.maskWordCount,e.maxComponents);return s.id=0,i.archetypes.push(s),i.archetypeByMaskHash.set(O(s.mask),0),pe(i),Ce(i)}function Ce(n){return {id:n.id,get capacity(){return n.capacity},version:n.version}}function $(n){let e=k.get(n.id);!e||e.destroyed||(e.destroyed=true,e.archetypes=[],e.archetypeByMaskHash.clear(),e.componentInfoByBit=[],e.componentStorageByBit=[],e.queries=[],e.queryMasks.clear(),e.queryArchetypeCache=[],e.observers=[],e.relationStorage.clear(),e.reactiveBuffers.clear(),le(n.id));}function Ae(n){let e=f(n);e.size=0,e.nextFreshIndex=1,e.freeList=[],e.generations.fill(0),e.entityArchetype.fill(0),e.entityMask.fill(0);for(let t of e.archetypes)t.size=0,t.entityRow.clear();for(let t of e.componentStorageByBit)if(t)if(t.kind==="soa"&&t.soa)for(let r of Object.keys(t.soa))t.soa[r]?.fill(0);else t.kind==="aos"&&t.aos&&t.aos.fill(void 0);e.queryVersion++;for(let t of e.reactiveBuffers.values())t.entered.length=0,t.exited.length=0;}function xe(n){return f(n).size}function ge(n){return f(n).capacity}function H(n,e){if(e<=n.capacity)return;if(e>n.options.maxEntities)throw new Error(`aiecsjs: requested capacity ${e} exceeds maxEntities ${n.options.maxEntities}`);let t=n.capacity;for(;t<e;)t=Math.min(t*2,n.options.maxEntities);ke(n,t);}function ke(n,e){let t=n.generations.constructor,r=new t(e);r.set(n.generations),n.generations=r;let o=new Uint32Array(e);o.set(n.entityArchetype),n.entityArchetype=o;let i=n.options.maskWordCount,s=new Uint32Array(e*i);s.set(n.entityMask),n.entityMask=s;for(let a of n.componentStorageByBit)if(a)if(a.kind==="soa"&&a.soa){let c=n.componentInfoByBit[a.bit];c&&Ie(a.soa,c.fields,e);}else a.kind==="aos"&&a.aos&&(a.aos.length=e);n.capacity=e;}function Ie(n,e,t){for(let r of e){let o=n[r.name];if(!o)continue;let i=t*r.vectorLen;if(o.length>=i)continue;let s=new r.ctor(i);s.set(o),n[r.name]=s;}}function K(n,e){let t=O(e),r=n.archetypeByMaskHash.get(t);if(r!==void 0)return {archId:r,created:false};let o=n.archetypes.length,i={id:o,mask:g(e),size:0,capacity:16,entities:new Uint32Array(16),entityRow:new Map,componentBits:we(e),edgeAdd:new Int32Array(n.options.maxComponents).fill(-1),edgeRemove:new Int32Array(n.options.maxComponents).fill(-1)};return n.archetypes.push(i),n.archetypeByMaskHash.set(t,o),n.queryVersion++,{archId:o,created:true}}function M(n,e){if(e<=n.capacity)return;let t=n.capacity;for(;t<e;)t*=2;let r=new Uint32Array(t);r.set(n.entities),n.entities=r,n.capacity=t;}function we(n){let e=[];for(let t=0;t<n.length;t++){let r=n[t]??0;for(;r!==0;){let o=r&-r,i=(t<<5)+(31-Math.clz32(o));e.push(i),r&=r-1;}}return e}function A(n,e){let t=n.componentBitFor.get(e.id);if(t!==void 0)return t;if(n.nextComponentBit>=n.options.maxComponents)throw new Error(`aiecsjs: world reached maxComponents=${n.options.maxComponents}`);let r=n.nextComponentBit++;n.componentBitFor.set(e.id,r),n.componentInfoByBit[r]=e;let o;if(e.kind==="soa"){let i={};for(let s of e.fields)i[s.name]=new s.ctor(n.capacity*s.vectorLen);o={kind:"soa",componentId:e.id,bit:r,soa:i};}else e.kind==="aos"?o={kind:"aos",componentId:e.id,bit:r,aos:new Array(n.capacity)}:o={kind:"tag",componentId:e.id,bit:r};return n.componentStorageByBit[r]=o,r}function x(n,e){let t=n.options.maskWordCount,r=new Uint32Array(t),o=e*t;for(let i=0;i<t;i++)r[i]=n.entityMask[o+i]??0;return r}function N(n,e,t){let r=n.options.maskWordCount,o=e*r;for(let i=0;i<r;i++)n.entityMask[o+i]=t[i]??0;}function I(n,e){return n.componentBitFor.get(e.id)}function ve(n){if(!n||typeof n!="object")return false;let e=n;return typeof e.id!="number"||typeof e.version!="string"?false:k.has(e.id)}function Se(n){let e=f(n);if(e.readOnly)throw new Error("aiecsjs: cannot createEntity on a read-only world (worker-attached)");let t;if(e.freeList.length>0)t=e.freeList.pop();else {if(e.nextFreshIndex>=e.options.maxEntities)throw new Error(`aiecsjs: reached maxEntities ${e.options.maxEntities}`);e.nextFreshIndex>=e.capacity&&H(e,e.nextFreshIndex+1),t=e.nextFreshIndex++;}let r=e.archetypes[0];if(!r)throw new Error("aiecsjs: missing empty archetype");M(r,r.size+1);let o=r.size;r.entities[o]=t,r.entityRow.set(t,o),r.size++,e.entityArchetype[t]=0;let i=e.options.maskWordCount,s=t*i;for(let a=0;a<i;a++)e.entityMask[s+a]=0;return e.size++,t}function Ee(n,e){let t=f(n);if(t.readOnly)throw new Error("aiecsjs: cannot destroyEntity on a read-only world");if(!p(t,e))return;X(t,e);let o=t.entityArchetype[e]??0,i=t.archetypes[o];if(i){let u=i.entityRow.get(e);if(u!==void 0){let d=i.size-1;if(u!==d){let y=i.entities[d]??0;i.entities[u]=y,i.entityRow.set(y,u);}i.entities[d]=0,i.entityRow.delete(e),i.size--;}}t.entityArchetype[e]=0;let s=t.options.maskWordCount,a=e*s;for(let u=0;u<s;u++)t.entityMask[a+u]=0;let c=e;t.generations[c]=(t.generations[c]??0)+1&65535,t.freeList.push(e),t.size--;}function Z(n,e){let t=f(n);return p(t,e)}function p(n,e){if(e<=0||e>=n.capacity)return false;let t=n.entityArchetype[e]??0,r=n.archetypes[t];return r?r.entityRow.has(e):false}function We(n){return n}function Be(n){return 0}function Me(n,e){return n}function _e(n,e){return typeof e!="number"?false:Z(n,e)}var T=1,Qe={i8:Int8Array,u8:Uint8Array,i16:Int16Array,u16:Uint16Array,i32:Int32Array,u32:Uint32Array,f32:Float32Array,f64:Float64Array,eid:Uint32Array,bool:Uint8Array},w=new Map;function Re(n){let e=[];for(let[i,s]of Object.entries(n)){let a,c=1;if(typeof s=="string")a=s;else if(Array.isArray(s)){let[d,y]=s;a=d,c=y;}else throw new TypeError(`aiecsjs: invalid field declaration for "${i}"`);let u=Qe[a];if(!u)throw new TypeError(`aiecsjs: unknown field type "${a}" for field "${i}"`);e.push({name:i,type:a,vectorLen:c,ctor:u,bytesPerElement:u.BYTES_PER_ELEMENT});}let t=T++,r={id:t,kind:"soa",schema:n,fields:e,factory:null};return w.set(t,r),{__kind:"soa",__id:t,__schema:n}}function Te(){let n=T++,e={id:n,kind:"tag",schema:null,fields:[],factory:null};return w.set(n,e),{__kind:"tag",__id:n}}function Le(n){let e=T++,t=n??(()=>({})),r={id:e,kind:"aos",schema:null,fields:[],factory:t};return w.set(e,r),{__kind:"aos",__id:e,__factory:t}}function l(n){let e=w.get(n.__id);if(!e)throw new Error("aiecsjs: component is not registered (call defineComponent/defineTag/defineObjectComponent)");return e}function Q(n,e,t,r){let o=f(n);if(o.readOnly)throw new Error("aiecsjs: cannot mutate a read-only world");if(!p(o,e))throw new Error(`aiecsjs: addComponent on dead entity ${e}`);let i=l(t),s=A(o,i),a=x(o,e);if(C(a,s)){r!==void 0&&R(o,e,t,r);return}let c=g(a);h(c,s),ee(o,e,c),R(o,e,t,r),re(o,e,s,a,c);}function je(n,e,t){let r=f(n);if(r.readOnly)throw new Error("aiecsjs: cannot mutate a read-only world");if(!p(r,e))return;let o=l(t),i=I(r,o);if(i===void 0)return;let s=x(r,e);if(!C(s,i))return;let a=g(s);D(a,i),ee(r,e,a);let c=r.componentStorageByBit[i];c?.kind==="soa"&&c.soa?J(c.soa,o.fields,e):c?.kind==="aos"&&c.aos&&(c.aos[e]=void 0),re(r,e,i,s,a);}function Fe(n,e,t){let r=f(n);if(!p(r,e))return false;let o=l(t),i=I(r,o);if(i===void 0)return false;let s=x(r,e);return C(s,i)}function ze(n,e,t){let r=f(n);if(!p(r,e))return;let o=l(t),i=I(r,o);if(i===void 0)return;let s=x(r,e);if(!C(s,i))return;let a=r.componentStorageByBit[i];if(a)return a.kind==="soa"?a.soa:a.kind==="aos"?a.aos?.[e]:true}function De(n,e,t,r){let o=f(n);if(o.readOnly)throw new Error("aiecsjs: cannot mutate a read-only world");if(!p(o,e))throw new Error(`aiecsjs: setComponent on dead entity ${e}`);let i=l(t),s=I(o,i);if(s===void 0){Q(n,e,t,r);return}let a=x(o,e);if(!C(a,s)){Q(n,e,t,r);return}R(o,e,t,r);}function R(n,e,t,r){let o=l(t),i=n.componentBitFor.get(o.id);if(i===void 0)return;let s=n.componentStorageByBit[i];if(s){if(o.kind==="soa"&&s.soa){if(r==null)return;let a=r;for(let c of o.fields){if(!(c.name in a))continue;let u=s.soa[c.name];if(!u)continue;let d=a[c.name];if(c.vectorLen===1)u[e]=typeof d=="boolean"?d?1:0:Number(d);else if(Array.isArray(d)||ArrayBuffer.isView(d)){let y=e*c.vectorLen,de=d;for(let S=0;S<c.vectorLen;S++)u[y+S]=Number(de[S]??0);}}}else if(o.kind==="aos"&&s.aos){let a=o.factory??(()=>({})),c=s.aos[e];if(c===void 0&&(c=a(),s.aos[e]=c),r&&typeof r=="object"){let u=r,d=c;for(let y of Object.keys(u))y==="__proto__"||y==="constructor"||y==="prototype"||(d[y]=u[y]);}}}}function J(n,e,t){for(let r of e){let o=n[r.name];if(o)if(r.vectorLen===1)o[t]=0;else {let i=t*r.vectorLen;for(let s=0;s<r.vectorLen;s++)o[i+s]=0;}}}function X(n,e){let t=n.options.maskWordCount,r=e,o=r*t;V(n.entityMask,o,t,i=>{let s=n.componentStorageByBit[i],a=n.componentInfoByBit[i];s?.kind==="soa"&&s.soa&&a?J(s.soa,a.fields,r):s?.kind==="aos"&&s.aos&&(s.aos[r]=void 0);});}function ee(n,e,t){let r=n.entityArchetype[e]??0,o=n.archetypes[r];if(!o)return;let s=K(n,t).archId,a=n.archetypes[s];if(a){if(s!==r){let c=o.entityRow.get(e);if(c!==void 0){let d=o.size-1;if(c!==d){let y=o.entities[d]??0;o.entities[c]=y,o.entityRow.set(y,c);}o.entities[d]=0,o.entityRow.delete(e),o.size--;}M(a,a.size+1);let u=a.size;a.entities[u]=e,a.entityRow.set(e,u),a.size++,n.entityArchetype[e]=s;}N(n,e,t);}}var ne=()=>{};function te(n){ne=n;}function re(n,e,t,r,o){ne(n,e,t,r,o);}function oe(n){return w.get(n)}var z=1,m=new Map;function $e(n){let e=(n.all??[]).map(o=>o.__id).sort((o,i)=>o-i).join("-"),t=(n.any??[]).map(o=>o.__id).sort((o,i)=>o-i).join("-"),r=(n.none??[]).map(o=>o.__id).sort((o,i)=>o-i).join("-");return `A${e}|Y${t}|N${r}`}function He(n){let e=Array.isArray(n)?{all:n}:n;for(let i of [...e.all??[],...e.any??[],...e.none??[]])if(!i||typeof i!="object"||typeof i.__id!="number")throw new TypeError("aiecsjs: defineQuery received a non-component value");let t=$e(e),r=m.get(t);if(r)return r;let o={id:z++,mask:[],all:(e.all??[]).map(i=>i.__id),any:(e.any??[]).map(i=>i.__id),none:(e.none??[]).map(i=>i.__id),columnViewCache:[...e.all??[],...e.any??[]],reactiveKind:"normal",sourceQueryId:-1,sourceQuery:null};return m.set(t,o),o}function Ke(n){let e=n,t=`enter:${e.id}`,r=m.get(t);if(r)return r;let o={id:z++,mask:[],all:e.all,any:e.any,none:e.none,columnViewCache:e.columnViewCache,reactiveKind:"enter",sourceQueryId:e.id,sourceQuery:e};return m.set(t,o),o}function Ne(n){let e=n,t=`exit:${e.id}`,r=m.get(t);if(r)return r;let o={id:z++,mask:[],all:e.all,any:e.any,none:e.none,columnViewCache:e.columnViewCache,reactiveKind:"exit",sourceQueryId:e.id,sourceQuery:e};return m.set(t,o),o}function v(n,e){if(n.queries[e.id]===e&&n.queryMasks.has(e.id))return;let t=n.options.maskWordCount,r=b(t),o=b(t),i=b(t);for(let c of e.all){let u=j(c),d=A(n,u);h(r,d);}for(let c of e.any){let u=j(c),d=A(n,u);h(o,d);}for(let c of e.none){let u=j(c),d=A(n,u);h(i,d);}let s={withMask:r,anyMask:o,noneMask:i,anyHasBits:!q(o)};n.queryMasks.set(e.id,s),n.queries[e.id]=e,n.queryArchetypeCache[e.id]=null,n.queryArchetypeStamp[e.id]=-1;let a=[...W(r),...W(o),...W(i)];for(let c of a){let u=n.bitToQueries.get(c);u||(u=new Set,n.bitToQueries.set(c,u)),u.add(e.id);}e.reactiveKind!=="normal"&&(n.reactiveBuffers.has(e.id)||n.reactiveBuffers.set(e.id,{entered:[],exited:[]}),e.sourceQuery&&v(n,e.sourceQuery));}function _(n,e){if(v(n,e),n.queryArchetypeCache[e.id]&&n.queryArchetypeStamp[e.id]===n.queryVersion)return n.queryArchetypeCache[e.id];let t=n.queryMasks.get(e.id),r=n.options.maskWordCount,o=[];for(let i=0;i<n.archetypes.length;i++){let s=n.archetypes[i];E(s.mask,t.withMask,t.anyMask,t.noneMask,t.anyHasBits,r)&&o.push(i);}return n.queryArchetypeCache[e.id]=o,n.queryArchetypeStamp[e.id]=n.queryVersion,o}function Ge(n,e){let t=f(n),o=_(t,e),i=[];for(let s of o){let a=t.archetypes[s];i.push({id:a.id,mask:Array.from(a.mask),size:a.size});}return i}function Ye(n,e){let t=f(n),r=e,o=[];if(r.reactiveKind==="enter"){let s=t.reactiveBuffers.get(r.id);if(s){for(let a of s.entered)o.push(a);s.entered.length=0;}return o}if(r.reactiveKind==="exit"){let s=t.reactiveBuffers.get(r.id);if(s){for(let a of s.exited)o.push(a);s.exited.length=0;}return o}let i=_(t,r);for(let s of i){let a=t.archetypes[s];for(let c=0;c<a.size;c++)o.push(a.entities[c]);}return o}function*Ze(n,e){let t=f(n),r=e;if(r.reactiveKind!=="normal"){let i=t.reactiveBuffers.get(r.id);if(!i)return;let s=r.reactiveKind==="enter"?i.entered:i.exited;for(let a of s)yield a;s.length=0;return}let o=_(t,r);for(let i of o){let s=t.archetypes[i];for(let a=0;a<s.size;a++)yield s.entities[a];}}function Xe(n,e,t){let r=f(n),o=e;if(o.reactiveKind!=="normal"){let a=r.reactiveBuffers.get(o.id);if(!a)return;let c=o.reactiveKind==="enter"?a.entered:a.exited;if(c.length===0)return;let u=se(r,o);for(let d=0;d<c.length;d++){let y=c[d];ie(t,y,u);}c.length=0;return}v(r,o);let i=_(r,o),s=se(r,o);for(let a of i){let c=r.archetypes[a],u=c.entities,d=c.size;for(let y=0;y<d;y++)ie(t,u[y],s);}}function ie(n,e,t){switch(t.length){case 0:n(e);break;case 1:n(e,t[0]);break;case 2:n(e,t[0],t[1]);break;case 3:n(e,t[0],t[1],t[2]);break;case 4:n(e,t[0],t[1],t[2],t[3]);break;case 5:n(e,t[0],t[1],t[2],t[3],t[4]);break;default:n(e,...t);}}function se(n,e){let t=[];for(let r of e.columnViewCache){let o=l(r),i=n.componentBitFor.get(o.id);if(i===void 0){t.push(void 0);continue}let s=n.componentStorageByBit[i];if(!s){t.push(void 0);continue}s.kind==="soa"?t.push(s.soa):s.kind==="aos"?t.push(s.aos):t.push(true);}return t}function ce(n,e,t,r,o){for(let a of m.values())a.reactiveKind!=="normal"&&a.sourceQuery&&n.queries[a.sourceQuery.id]!==a.sourceQuery&&v(n,a.sourceQuery);let i=n.bitToQueries.get(t);if(!i)return;let s=n.options.maskWordCount;for(let a of i){let c=n.queries[a];if(!c||c.reactiveKind!=="normal")continue;let u=n.queryMasks.get(a);if(!u)continue;let d=E(r,u.withMask,u.anyMask,u.noneMask,u.anyHasBits,s),y=E(o,u.withMask,u.anyMask,u.noneMask,u.anyHasBits,s);!d&&y?ae(n,a,"enter",e):d&&!y&&ae(n,a,"exit",e);}}function ae(n,e,t,r){for(let o of m.values()){if(o.sourceQueryId!==e||o.reactiveKind!==t)continue;v(n,o);let i=Je(n,o.id);t==="enter"?i.entered.push(r):i.exited.push(r);}}function Je(n,e){let t=n.reactiveBuffers.get(e);return t||(t={entered:[],exited:[]},n.reactiveBuffers.set(e,t)),t}function j(n){let e=en(n);if(!e)throw new Error(`aiecsjs: component id ${n} not registered`);return e}var F=null;function ue(n){F=n;}function en(n){return F?F(n):void 0}var nn={i8:"i8",u8:"u8",i16:"i16",u16:"u16",i32:"i32",u32:"u32",f32:"f32",f64:"f64",eid:"eid",bool:"bool"};function tn(...n){return n.length===0?e=>e:n.length===1?n[0]:(e,t)=>{let r=e;for(let o of n)r=o(r,t);return r}}ue(n=>oe(n));te((n,e,t,r,o)=>{ce(n,e,t,r,o);});var Wn=typeof SharedArrayBuffer<"u";export{Wn as IS_SAB_SUPPORTED,nn as Types,U as VERSION,Q as addComponent,Se as createEntity,he as createWorld,Re as defineComponent,Le as defineObjectComponent,He as defineQuery,Te as defineTag,Ee as destroyEntity,$ as destroyWorld,$ as disposeWorld,Ke as enterQuery,Z as entityExists,Ne as exitQuery,Xe as forEachEntity,ze as getComponent,Be as getEntityGeneration,We as getEntityIndex,ge as getWorldCapacity,xe as getWorldSize,Fe as hasComponent,_e as isEntity,ve as isWorld,Ze as iterQuery,Me as packEntity,tn as pipe,Ge as queryArchetypes,je as removeComponent,Ae as resetWorld,Ye as runQuery,De as setComponent};//# sourceMappingURL=index.js.map
1
+ var U="0.3.0";function h(n){return new Uint32Array(n)}function x(n,e){let t=e>>>5;n[t]=(n[t]??0)|1<<(e&31);}function P(n,e){let t=e>>>5;n[t]=(n[t]??0)&~(1<<(e&31));}function A(n,e){let t=e>>>5;return ((n[t]??0)&1<<(e&31))!==0}function g(n){let e=new Uint32Array(n.length);for(let t=0;t<n.length;t++)e[t]=n[t]??0;return e}function Q(n){let e=[];for(let t=0;t<n.length;t++)e.push((n[t]??0).toString(16));return e.join(",")}function N(n){for(let e=0;e<n.length;e++)if((n[e]??0)!==0)return false;return true}function W(n,e,t,r,o,i){let s=!o;for(let a=0;a<i;a++){let u=n[a]??0,c=e[a]??0,d=t[a]??0,y=r[a]??0;if((u&c)!==c||(u&y)!==0)return false;!s&&(u&d)!==0&&(s=true);}return s}function B(n){let e=[];for(let t=0;t<n.length;t++){let r=n[t]??0;for(;r!==0;){let o=(t<<5)+K(r);e.push(o),r&=r-1;}}return e}function $(n,e,t,r){for(let o=0;o<t;o++){let i=n[e+o]??0;for(;i!==0;){let s=(o<<5)+K(i);r(s),i&=i-1;}}}function K(n){return 31-Math.clz32(n&-n)}var M={initialCapacity:1024,maxEntities:1e6,indexBits:24,generationBits:8},Ae=256,Ce=1,I=new Map;function f(n){let e=I.get(n.id);if(!e)throw new Error(`aiecsjs: world ${n.id} is destroyed or unknown`);if(e.destroyed)throw new Error(`aiecsjs: world ${n.id} is destroyed`);return e}function ke(n){I.set(n.id,n);}function ge(n){I.delete(n);}function Ie(n){let e=n??{},t=e.indexBits??M.indexBits,r=e.generationBits??M.generationBits,o=Ae;if(t<1||t>24)throw new Error("aiecsjs: indexBits must be in [1, 24]");if(r<0||r>16)throw new Error("aiecsjs: generationBits must be in [0, 16]");let i=1<<t,s=Math.max(1,Math.min(e.initialCapacity??M.initialCapacity,i)),a=Math.max(s,Math.min(e.maxEntities??M.maxEntities,i));return {initialCapacity:s,maxEntities:a,indexBits:t,generationBits:r,indexMask:(1<<t)-1,generationMask:r===0?0:(1<<r)-1,maxComponents:o,maskWordCount:Math.ceil(o/32),buffer:e.buffer??null,bufferByteOffset:e.bufferByteOffset??0}}function we(n,e){return {id:0,mask:h(n),size:0,capacity:16,entities:new Uint32Array(16),entityRow:new Map,componentBits:[],edgeAdd:new Int32Array(e).fill(-1),edgeRemove:new Int32Array(e).fill(-1)}}function ve(n){let e=Ie(n),t=Ce++,r=e.generationBits>8?Uint16Array:Uint8Array,o=new r(e.initialCapacity),i={id:t,capacity:e.initialCapacity,version:U,options:e,size:0,nextFreshIndex:1,freeList:[],generations:o,destroyed:false,componentBitFor:new Map,componentInfoByBit:new Array(e.maxComponents).fill(null),componentStorageByBit:new Array(e.maxComponents).fill(null),nextComponentBit:0,entityArchetype:new Uint32Array(e.initialCapacity),entityMask:new Uint32Array(e.initialCapacity*e.maskWordCount),archetypes:[],archetypeByMaskHash:new Map,queryVersion:0,queries:[],queryMasks:new Map,queryArchetypeCache:[],queryArchetypeStamp:[],bitToQueries:new Map,reactiveBuffers:new Map,observers:[],relationStorage:new Map,sab:e.buffer,readOnly:false},s=we(e.maskWordCount,e.maxComponents);return s.id=0,i.archetypes.push(s),i.archetypeByMaskHash.set(Q(s.mask),0),ke(i),Se(i)}function Se(n){return {id:n.id,get capacity(){return n.capacity},version:n.version}}function G(n){let e=I.get(n.id);!e||e.destroyed||(e.destroyed=true,e.archetypes=[],e.archetypeByMaskHash.clear(),e.componentInfoByBit=[],e.componentStorageByBit=[],e.queries=[],e.queryMasks.clear(),e.queryArchetypeCache=[],e.observers=[],e.relationStorage.clear(),e.reactiveBuffers.clear(),ge(n.id));}function Ee(n){let e=f(n);e.size=0,e.nextFreshIndex=1,e.freeList=[],e.generations.fill(0),e.entityArchetype.fill(0),e.entityMask.fill(0);for(let t of e.archetypes)t.size=0,t.entityRow.clear();for(let t of e.componentStorageByBit)if(t)if(t.kind==="soa"&&t.soa)for(let r of Object.keys(t.soa))t.soa[r]?.fill(0);else t.kind==="aos"&&t.aos&&t.aos.fill(void 0);e.queryVersion++;for(let t of e.reactiveBuffers.values())t.entered.length=0,t.exited.length=0;}function We(n){return f(n).size}function Be(n){return f(n).capacity}function H(n,e){if(e<=n.capacity)return;if(e>n.options.maxEntities)throw new Error(`aiecsjs: requested capacity ${e} exceeds maxEntities ${n.options.maxEntities}`);let t=n.capacity;for(;t<e;)t=Math.min(t*2,n.options.maxEntities);Me(n,t);}function Me(n,e){let t=n.generations.constructor,r=new t(e);r.set(n.generations),n.generations=r;let o=new Uint32Array(e);o.set(n.entityArchetype),n.entityArchetype=o;let i=n.options.maskWordCount,s=new Uint32Array(e*i);s.set(n.entityMask),n.entityMask=s;for(let a of n.componentStorageByBit)if(a)if(a.kind==="soa"&&a.soa){let u=n.componentInfoByBit[a.bit];u&&_e(a.soa,u.fields,e);}else a.kind==="aos"&&a.aos&&(a.aos.length=e);n.capacity=e;}function _e(n,e,t){for(let r of e){let o=n[r.name];if(!o)continue;let i=t*r.vectorLen;if(o.length>=i)continue;let s=new r.ctor(i);s.set(o),n[r.name]=s;}}function Y(n,e){let t=Q(e),r=n.archetypeByMaskHash.get(t);if(r!==void 0)return {archId:r,created:false};let o=n.archetypes.length,i={id:o,mask:g(e),size:0,capacity:16,entities:new Uint32Array(16),entityRow:new Map,componentBits:Oe(e),edgeAdd:new Int32Array(n.options.maxComponents).fill(-1),edgeRemove:new Int32Array(n.options.maxComponents).fill(-1)};return n.archetypes.push(i),n.archetypeByMaskHash.set(t,o),n.queryVersion++,{archId:o,created:true}}function _(n,e){if(e<=n.capacity)return;let t=n.capacity;for(;t<e;)t*=2;let r=new Uint32Array(t);r.set(n.entities),n.entities=r,n.capacity=t;}function Oe(n){let e=[];for(let t=0;t<n.length;t++){let r=n[t]??0;for(;r!==0;){let o=r&-r,i=(t<<5)+(31-Math.clz32(o));e.push(i),r&=r-1;}}return e}function C(n,e){let t=n.componentBitFor.get(e.id);if(t!==void 0)return t;if(n.nextComponentBit>=n.options.maxComponents)throw new Error(`aiecsjs: world reached maxComponents=${n.options.maxComponents}`);let r=n.nextComponentBit++;n.componentBitFor.set(e.id,r),n.componentInfoByBit[r]=e;let o;if(e.kind==="soa"){let i={};for(let s of e.fields)i[s.name]=new s.ctor(n.capacity*s.vectorLen);o={kind:"soa",componentId:e.id,bit:r,soa:i};}else e.kind==="aos"?o={kind:"aos",componentId:e.id,bit:r,aos:new Array(n.capacity)}:o={kind:"tag",componentId:e.id,bit:r};return n.componentStorageByBit[r]=o,r}function k(n,e){let t=n.options.maskWordCount,r=new Uint32Array(t),i=(e&n.options.indexMask)*t;for(let s=0;s<t;s++)r[s]=n.entityMask[i+s]??0;return r}function X(n,e,t){let r=n.options.maskWordCount,i=(e&n.options.indexMask)*r;for(let s=0;s<r;s++)n.entityMask[i+s]=t[s]??0;}function w(n,e){return n.componentBitFor.get(e.id)}function Re(n){if(!n||typeof n!="object")return false;let e=n;return typeof e.id!="number"||typeof e.version!="string"?false:I.has(e.id)}var T=24,Ue=8,ee=(1<<T)-1,ne=(1<<Ue)-1;function Qe(n,e,t){return (e&t.generationMask)<<t.indexBits|n&t.indexMask}function te(n,e){return n&e.indexMask}function re(n,e){return n>>>e.indexBits&e.generationMask}function Te(n){let e=f(n);if(e.readOnly)throw new Error("aiecsjs: cannot createEntity on a read-only world (worker-attached)");let t;if(e.freeList.length>0)t=e.freeList.pop();else {if(e.nextFreshIndex>=e.options.maxEntities)throw new Error(`aiecsjs: reached maxEntities ${e.options.maxEntities}`);e.nextFreshIndex>=e.capacity&&H(e,e.nextFreshIndex+1),t=e.nextFreshIndex++;}let r=e.generations[t]??0,o=Qe(t,r,e.options),i=e.archetypes[0];if(!i)throw new Error("aiecsjs: missing empty archetype");_(i,i.size+1);let s=i.size;i.entities[s]=o,i.entityRow.set(o,s),i.size++,e.entityArchetype[t]=0;let a=e.options.maskWordCount,u=t*a;for(let c=0;c<a;c++)e.entityMask[u+c]=0;return e.size++,o}function Le(n,e){let t=f(n);if(t.readOnly)throw new Error("aiecsjs: cannot destroyEntity on a read-only world");if(!l(t,e))return;let r=e&t.options.indexMask;ie(t,e);let i=t.entityArchetype[r]??0,s=t.archetypes[i];if(s){let c=s.entityRow.get(e);if(c!==void 0){let d=s.size-1;if(c!==d){let y=s.entities[d]??0;s.entities[c]=y,s.entityRow.set(y,c);}s.entities[d]=0,s.entityRow.delete(e),s.size--;}}t.entityArchetype[r]=0;let a=t.options.maskWordCount,u=r*a;for(let c=0;c<a;c++)t.entityMask[u+c]=0;t.generations[r]=(t.generations[r]??0)+1&t.options.generationMask,t.freeList.push(r),t.size--;}function oe(n,e){let t=f(n);return l(t,e)}function l(n,e){let t=e&n.options.indexMask;if(t<=0||t>=n.capacity)return false;let r=n.entityArchetype[t]??0,o=n.archetypes[r];if(!o||!o.entityRow.has(e))return false;let i=n.generations[t]??0,s=e>>>n.options.indexBits&n.options.generationMask;return i===s}function je(n){return n&ee}function Fe(n){return n>>>T&ne}function ze(n,e){return (e&ne)<<T|n&ee}function De(n,e){return typeof e!="number"?false:oe(n,e)}var F=1,Pe={i8:Int8Array,u8:Uint8Array,i16:Int16Array,u16:Uint16Array,i32:Int32Array,u32:Uint32Array,f32:Float32Array,f64:Float64Array,eid:Uint32Array,bool:Uint8Array},v=new Map;function Ne(n){let e=[];for(let[i,s]of Object.entries(n)){let a,u=1;if(typeof s=="string")a=s;else if(Array.isArray(s)){let[d,y]=s;a=d,u=y;}else throw new TypeError(`aiecsjs: invalid field declaration for "${i}"`);let c=Pe[a];if(!c)throw new TypeError(`aiecsjs: unknown field type "${a}" for field "${i}"`);e.push({name:i,type:a,vectorLen:u,ctor:c,bytesPerElement:c.BYTES_PER_ELEMENT});}let t=F++,r={id:t,kind:"soa",schema:n,fields:e,factory:null};return v.set(t,r),{__kind:"soa",__id:t,__schema:n}}function $e(){let n=F++,e={id:n,kind:"tag",schema:null,fields:[],factory:null};return v.set(n,e),{__kind:"tag",__id:n}}function Ke(n){let e=F++,t=n??(()=>({})),r={id:e,kind:"aos",schema:null,fields:[],factory:t};return v.set(e,r),{__kind:"aos",__id:e,__factory:t}}function m(n){let e=v.get(n.__id);if(!e)throw new Error("aiecsjs: component is not registered (call defineComponent/defineTag/defineObjectComponent)");return e}function L(n,e,t,r){let o=f(n);if(o.readOnly)throw new Error("aiecsjs: cannot mutate a read-only world");if(!l(o,e))throw new Error(`aiecsjs: addComponent on dead entity ${e}`);let i=m(t),s=C(o,i),a=k(o,e);if(A(a,s)){r!==void 0&&j(o,e,t,r);return}let u=g(a);x(u,s),ae(o,e,u),j(o,e,t,r),de(o,e,s,a,u);}function Ge(n,e,t){let r=f(n);if(r.readOnly)throw new Error("aiecsjs: cannot mutate a read-only world");if(!l(r,e))return;let o=m(t),i=w(r,o);if(i===void 0)return;let s=k(r,e);if(!A(s,i))return;let a=g(s);P(a,i),ae(r,e,a);let u=e&r.options.indexMask,c=r.componentStorageByBit[i];c?.kind==="soa"&&c.soa?se(c.soa,o.fields,u):c?.kind==="aos"&&c.aos&&(c.aos[u]=void 0),de(r,e,i,s,a);}function He(n,e,t){let r=f(n);if(!l(r,e))return false;let o=m(t),i=w(r,o);if(i===void 0)return false;let s=k(r,e);return A(s,i)}function Ye(n,e,t){let r=f(n);if(!l(r,e))return;let o=m(t),i=w(r,o);if(i===void 0)return;let s=k(r,e);if(!A(s,i))return;let a=r.componentStorageByBit[i];if(a){if(a.kind==="soa")return a.soa;if(a.kind==="aos"){let u=e&r.options.indexMask;return a.aos?.[u]}return true}}function Xe(n,e,t,r){let o=f(n);if(o.readOnly)throw new Error("aiecsjs: cannot mutate a read-only world");if(!l(o,e))throw new Error(`aiecsjs: setComponent on dead entity ${e}`);let i=m(t),s=w(o,i);if(s===void 0){L(n,e,t,r);return}let a=k(o,e);if(!A(a,s)){L(n,e,t,r);return}j(o,e,t,r);}function j(n,e,t,r){let o=m(t),i=n.componentBitFor.get(o.id);if(i===void 0)return;let s=n.componentStorageByBit[i];if(!s)return;let a=e&n.options.indexMask;if(o.kind==="soa"&&s.soa){if(r==null)return;let u=r;for(let c of o.fields){if(!(c.name in u))continue;let d=s.soa[c.name];if(!d)continue;let y=u[c.name];if(c.vectorLen===1)d[a]=typeof y=="boolean"?y?1:0:Number(y);else if(Array.isArray(y)||ArrayBuffer.isView(y)){let p=a*c.vectorLen,xe=y;for(let E=0;E<c.vectorLen;E++)d[p+E]=Number(xe[E]??0);}}}else if(o.kind==="aos"&&s.aos){let u=o.factory??(()=>({})),c=s.aos[a];if(c===void 0&&(c=u(),s.aos[a]=c),r&&typeof r=="object"){let d=r,y=c;for(let p of Object.keys(d))p==="__proto__"||p==="constructor"||p==="prototype"||(y[p]=d[p]);}}}function se(n,e,t){for(let r of e){let o=n[r.name];if(o)if(r.vectorLen===1)o[t]=0;else {let i=t*r.vectorLen;for(let s=0;s<r.vectorLen;s++)o[i+s]=0;}}}function ie(n,e){let t=n.options.maskWordCount,r=e&n.options.indexMask,o=r*t;$(n.entityMask,o,t,i=>{let s=n.componentStorageByBit[i],a=n.componentInfoByBit[i];s?.kind==="soa"&&s.soa&&a?se(s.soa,a.fields,r):s?.kind==="aos"&&s.aos&&(s.aos[r]=void 0);});}function ae(n,e,t){let r=e&n.options.indexMask,o=n.entityArchetype[r]??0,i=n.archetypes[o];if(!i)return;let a=Y(n,t).archId,u=n.archetypes[a];if(u){if(a!==o){let c=i.entityRow.get(e);if(c!==void 0){let y=i.size-1;if(c!==y){let p=i.entities[y]??0;i.entities[c]=p,i.entityRow.set(p,c);}i.entities[y]=0,i.entityRow.delete(e),i.size--;}_(u,u.size+1);let d=u.size;u.entities[d]=e,u.entityRow.set(e,d),u.size++,n.entityArchetype[r]=a;}X(n,e,t);}}var ce=()=>{};function ue(n){ce=n;}function de(n,e,t,r,o){ce(n,e,t,r,o);}function ye(n){return v.get(n)}var V=1,b=new Map;function nn(n){let e=(n.all??[]).map(o=>o.__id).sort((o,i)=>o-i).join("-"),t=(n.any??[]).map(o=>o.__id).sort((o,i)=>o-i).join("-"),r=(n.none??[]).map(o=>o.__id).sort((o,i)=>o-i).join("-");return `A${e}|Y${t}|N${r}`}function tn(n){let e=Array.isArray(n)?{all:n}:n;for(let i of [...e.all??[],...e.any??[],...e.none??[]])if(!i||typeof i!="object"||typeof i.__id!="number")throw new TypeError("aiecsjs: defineQuery received a non-component value");let t=nn(e),r=b.get(t);if(r)return r;let o={id:V++,mask:[],all:(e.all??[]).map(i=>i.__id),any:(e.any??[]).map(i=>i.__id),none:(e.none??[]).map(i=>i.__id),columnViewCache:[...e.all??[],...e.any??[]],reactiveKind:"normal",sourceQueryId:-1,sourceQuery:null};return b.set(t,o),o}function rn(n){let e=n,t=`enter:${e.id}`,r=b.get(t);if(r)return r;let o={id:V++,mask:[],all:e.all,any:e.any,none:e.none,columnViewCache:e.columnViewCache,reactiveKind:"enter",sourceQueryId:e.id,sourceQuery:e};return b.set(t,o),o}function on(n){let e=n,t=`exit:${e.id}`,r=b.get(t);if(r)return r;let o={id:V++,mask:[],all:e.all,any:e.any,none:e.none,columnViewCache:e.columnViewCache,reactiveKind:"exit",sourceQueryId:e.id,sourceQuery:e};return b.set(t,o),o}function S(n,e){if(n.queries[e.id]===e&&n.queryMasks.has(e.id))return;let t=n.options.maskWordCount,r=h(t),o=h(t),i=h(t);for(let u of e.all){let c=D(u),d=C(n,c);x(r,d);}for(let u of e.any){let c=D(u),d=C(n,c);x(o,d);}for(let u of e.none){let c=D(u),d=C(n,c);x(i,d);}let s={withMask:r,anyMask:o,noneMask:i,anyHasBits:!N(o)};n.queryMasks.set(e.id,s),n.queries[e.id]=e,n.queryArchetypeCache[e.id]=null,n.queryArchetypeStamp[e.id]=-1;let a=[...B(r),...B(o),...B(i)];for(let u of a){let c=n.bitToQueries.get(u);c||(c=new Set,n.bitToQueries.set(u,c)),c.add(e.id);}e.reactiveKind!=="normal"&&(n.reactiveBuffers.has(e.id)||n.reactiveBuffers.set(e.id,{entered:[],exited:[]}),e.sourceQuery&&S(n,e.sourceQuery));}function O(n,e){if(S(n,e),n.queryArchetypeCache[e.id]&&n.queryArchetypeStamp[e.id]===n.queryVersion)return n.queryArchetypeCache[e.id];let t=n.queryMasks.get(e.id),r=n.options.maskWordCount,o=[];for(let i=0;i<n.archetypes.length;i++){let s=n.archetypes[i];W(s.mask,t.withMask,t.anyMask,t.noneMask,t.anyHasBits,r)&&o.push(i);}return n.queryArchetypeCache[e.id]=o,n.queryArchetypeStamp[e.id]=n.queryVersion,o}function sn(n,e){let t=f(n),o=O(t,e),i=[];for(let s of o){let a=t.archetypes[s];i.push({id:a.id,mask:Array.from(a.mask),size:a.size});}return i}function an(n,e){let t=f(n),r=e,o=[];if(r.reactiveKind==="enter"){let s=t.reactiveBuffers.get(r.id);if(s){for(let a of s.entered)o.push(a);s.entered.length=0;}return o}if(r.reactiveKind==="exit"){let s=t.reactiveBuffers.get(r.id);if(s){for(let a of s.exited)o.push(a);s.exited.length=0;}return o}let i=O(t,r);for(let s of i){let a=t.archetypes[s];for(let u=0;u<a.size;u++)o.push(a.entities[u]);}return o}function*cn(n,e){let t=f(n),r=e;if(r.reactiveKind!=="normal"){let i=t.reactiveBuffers.get(r.id);if(!i)return;let s=r.reactiveKind==="enter"?i.entered:i.exited;for(let a of s)yield a;s.length=0;return}let o=O(t,r);for(let i of o){let s=t.archetypes[i];for(let a=0;a<s.size;a++)yield s.entities[a];}}function un(n,e,t){let r=f(n),o=e;if(o.reactiveKind!=="normal"){let a=r.reactiveBuffers.get(o.id);if(!a)return;let u=o.reactiveKind==="enter"?a.entered:a.exited;if(u.length===0)return;let c=pe(r,o);for(let d=0;d<u.length;d++){let y=u[d];fe(t,y,c);}u.length=0;return}S(r,o);let i=O(r,o),s=pe(r,o);for(let a of i){let u=r.archetypes[a],c=u.entities,d=u.size;for(let y=0;y<d;y++)fe(t,c[y],s);}}function fe(n,e,t){switch(t.length){case 0:n(e);break;case 1:n(e,t[0]);break;case 2:n(e,t[0],t[1]);break;case 3:n(e,t[0],t[1],t[2]);break;case 4:n(e,t[0],t[1],t[2],t[3]);break;case 5:n(e,t[0],t[1],t[2],t[3],t[4]);break;default:n(e,...t);}}function pe(n,e){let t=[];for(let r of e.columnViewCache){let o=m(r),i=n.componentBitFor.get(o.id);if(i===void 0){t.push(void 0);continue}let s=n.componentStorageByBit[i];if(!s){t.push(void 0);continue}s.kind==="soa"?t.push(s.soa):s.kind==="aos"?t.push(s.aos):t.push(true);}return t}function me(n,e,t,r,o){for(let a of b.values())a.reactiveKind!=="normal"&&a.sourceQuery&&n.queries[a.sourceQuery.id]!==a.sourceQuery&&S(n,a.sourceQuery);let i=n.bitToQueries.get(t);if(!i)return;let s=n.options.maskWordCount;for(let a of i){let u=n.queries[a];if(!u||u.reactiveKind!=="normal")continue;let c=n.queryMasks.get(a);if(!c)continue;let d=W(r,c.withMask,c.anyMask,c.noneMask,c.anyHasBits,s),y=W(o,c.withMask,c.anyMask,c.noneMask,c.anyHasBits,s);!d&&y?le(n,a,"enter",e):d&&!y&&le(n,a,"exit",e);}}function le(n,e,t,r){for(let o of b.values()){if(o.sourceQueryId!==e||o.reactiveKind!==t)continue;S(n,o);let i=dn(n,o.id);t==="enter"?i.entered.push(r):i.exited.push(r);}}function dn(n,e){let t=n.reactiveBuffers.get(e);return t||(t={entered:[],exited:[]},n.reactiveBuffers.set(e,t)),t}function D(n){let e=yn(n);if(!e)throw new Error(`aiecsjs: component id ${n} not registered`);return e}var q=null;function be(n){q=n;}function yn(n){return q?q(n):void 0}var fn={i8:"i8",u8:"u8",i16:"i16",u16:"u16",i32:"i32",u32:"u32",f32:"f32",f64:"f64",eid:"eid",bool:"bool"};function pn(...n){return n.length===0?e=>e:n.length===1?n[0]:(e,t)=>{let r=e;for(let o of n)r=o(r,t);return r}}var R=class extends Error{eid;constructor(e){super(`aiecsjs: entity ${e} is not alive`),this.name="EntityNotAliveError",this.eid=e;}};function ln(n,e){let t=f(n);if(!l(t,e))throw new R(e);return Object.freeze({id:e,worldId:t.id})}function he(n,e){let t=f(n);if(e.worldId!==t.id)return null;let r=e.id,o=te(r,t.options);if(o<=0||o>=t.capacity)return null;let i=t.entityArchetype[o]??0,s=t.archetypes[i];if(!s||!s.entityRow.has(e.id))return null;let a=t.generations[o]??0,u=re(r,t.options);return a!==u?null:e.id}function mn(n,e){return he(n,e)!==null}be(n=>ye(n));ue((n,e,t,r,o)=>{me(n,e,t,r,o);});var Vn=typeof SharedArrayBuffer<"u";export{R as EntityNotAliveError,Vn as IS_SAB_SUPPORTED,fn as Types,U as VERSION,L as addComponent,mn as aliveRef,Te as createEntity,ve as createWorld,Ne as defineComponent,Ke as defineObjectComponent,tn as defineQuery,$e as defineTag,he as deref,Le as destroyEntity,G as destroyWorld,G as disposeWorld,rn as enterQuery,oe as entityExists,on as exitQuery,un as forEachEntity,Ye as getComponent,Fe as getEntityGeneration,je as getEntityIndex,Be as getWorldCapacity,We as getWorldSize,He as hasComponent,De as isEntity,Re as isWorld,cn as iterQuery,ze as packEntity,pn as pipe,sn as queryArchetypes,ln as refOf,Ge as removeComponent,Ee as resetWorld,an as runQuery,Xe as setComponent};//# sourceMappingURL=index.js.map
2
2
  //# sourceMappingURL=index.js.map