aiecsjs 0.5.5 → 0.5.7

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.
Files changed (64) hide show
  1. package/README.md +26 -17
  2. package/README_ZHTW.md +26 -17
  3. package/api.json +25 -2
  4. package/dist/chunk-22ICWJ5O.js +2 -0
  5. package/dist/chunk-22ICWJ5O.js.map +1 -0
  6. package/dist/chunk-2KCN5RVK.js +2 -0
  7. package/dist/chunk-2KCN5RVK.js.map +1 -0
  8. package/dist/chunk-5QWEV4VJ.cjs +2 -0
  9. package/dist/chunk-5QWEV4VJ.cjs.map +1 -0
  10. package/dist/chunk-AGWUE6JB.js +2 -0
  11. package/dist/chunk-AGWUE6JB.js.map +1 -0
  12. package/dist/chunk-P5GW7GKY.cjs +2 -0
  13. package/dist/chunk-P5GW7GKY.cjs.map +1 -0
  14. package/dist/chunk-SRX2MZPX.cjs +2 -0
  15. package/dist/chunk-SRX2MZPX.cjs.map +1 -0
  16. package/dist/commands.cjs +1 -1
  17. package/dist/commands.cjs.map +1 -1
  18. package/dist/commands.d.cts +1 -1
  19. package/dist/commands.d.ts +1 -1
  20. package/dist/commands.js +1 -1
  21. package/dist/commands.js.map +1 -1
  22. package/dist/index.cjs +1 -1
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +63 -4
  25. package/dist/index.d.ts +63 -4
  26. package/dist/index.js +1 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/observers.cjs +1 -1
  29. package/dist/observers.d.cts +1 -1
  30. package/dist/observers.d.ts +1 -1
  31. package/dist/observers.js +1 -1
  32. package/dist/observers.js.map +1 -1
  33. package/dist/relations.cjs +1 -1
  34. package/dist/relations.d.cts +1 -1
  35. package/dist/relations.d.ts +1 -1
  36. package/dist/relations.js +1 -1
  37. package/dist/relations.js.map +1 -1
  38. package/dist/serialize.cjs +1 -1
  39. package/dist/serialize.d.cts +1 -1
  40. package/dist/serialize.d.ts +1 -1
  41. package/dist/serialize.js +1 -1
  42. package/dist/{types-BGEeHad-.d.cts → types-BeVLA7xG.d.cts} +11 -1
  43. package/dist/{types-BGEeHad-.d.ts → types-BeVLA7xG.d.ts} +11 -1
  44. package/dist/worker.cjs +1 -1
  45. package/dist/worker.cjs.map +1 -1
  46. package/dist/worker.d.cts +2 -2
  47. package/dist/worker.d.ts +2 -2
  48. package/dist/worker.js +1 -1
  49. package/dist/worker.js.map +1 -1
  50. package/llms-full.txt +67 -22
  51. package/llms.txt +17 -17
  52. package/package.json +7 -2
  53. package/dist/chunk-ENULPSKV.js +0 -2
  54. package/dist/chunk-ENULPSKV.js.map +0 -1
  55. package/dist/chunk-EVPXWN4C.js +0 -2
  56. package/dist/chunk-EVPXWN4C.js.map +0 -1
  57. package/dist/chunk-F6VQ6V3Y.cjs +0 -2
  58. package/dist/chunk-F6VQ6V3Y.cjs.map +0 -1
  59. package/dist/chunk-M6L4SSE4.cjs +0 -2
  60. package/dist/chunk-M6L4SSE4.cjs.map +0 -1
  61. package/dist/chunk-O5OK5TLX.cjs +0 -2
  62. package/dist/chunk-O5OK5TLX.cjs.map +0 -1
  63. package/dist/chunk-ZWOAXX4R.js +0 -2
  64. package/dist/chunk-ZWOAXX4R.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/serialize.ts"],"names":["MAGIC","FORMAT_VERSION","serializeWorld","world","options","snapshot","toJSON","e","c","comp","packBinary","deserializeWorld","bytes","unpackBinary","fromJSON","state","getWorldState","entities","idx","archId","arch","gen","packedEid","packEid","w","base","components","wi","word","lsb","bit","info","storage","data","obj","f","col","arr","baseI","i","RESTORE_CAPACITY_FLOOR","clampRestoreCapacity","rawCapacity","entityCount","needed","initialCapacity","createWorld","eidMap","eid","createEntity","getComponentByInternalId","handle","getComponentHandle","addComponent","factory","json","jsonBytes","versionBytes","VERSION","total","out","view","off","formatVersion","onUnknown","MAX_FIELD_LEN","verLen","jsonLen","cause","createDeltaSerializer","listAllComponents","current","delta","computeDelta","targetWorld","deltaBytes","targetState","ensureEntityAtSlot","prev","curr","prevByEid","changed","prevE","prevSig","currSig"],"mappings":"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","file":"chunk-P5GW7GKY.cjs","sourcesContent":["// aiecsjs/serialize — binary, JSON, and delta serializers.\n\nimport { testBit } from './internal/bitmask.js'\nimport {\n addComponent,\n defineComponent,\n defineObjectComponent,\n defineTag,\n getComponentByInternalId,\n getComponentInfo,\n listAllComponents,\n} from './internal/component.js'\nimport { createEntity, destroyEntity, ensureEntityAtSlot, packEid } from './internal/entity.js'\nimport type {\n ComponentInfo,\n ComponentLike,\n DeltaSerializer,\n DeserializeOptions,\n EntityId,\n SerializeOptions,\n World,\n WorldSnapshot,\n} from './internal/types.js'\nimport { createWorld, getWorldState } from './internal/world.js'\nimport { VERSION } from './version.js'\n\nconst MAGIC = 'AIEC'\nconst FORMAT_VERSION = 1\n\nexport function serializeWorld(world: World, options?: SerializeOptions): Uint8Array {\n const snapshot = toJSON(world)\n if (options?.components) {\n snapshot.entities = snapshot.entities.map((e) => ({\n eid: e.eid,\n components: e.components.filter((c) =>\n options.components!.some((comp) => comp.__id === c.id),\n ),\n }))\n }\n return packBinary(snapshot)\n}\n\nexport function deserializeWorld(bytes: Uint8Array, options?: DeserializeOptions): World {\n const snapshot = unpackBinary(bytes, options)\n return fromJSON(snapshot)\n}\n\n/**\n * Serialize a world snapshot to a plain JSON-compatible object.\n *\n * Note: `EntityRef` is in-memory only — not preserved across serialize/deserialize.\n * Generation counters reset on world load. Stale refs from before serialization\n * will deref to null after loading the snapshot into a new world.\n */\nexport function toJSON(world: World): WorldSnapshot {\n const state = getWorldState(world)\n const entities: WorldSnapshot['entities'] = []\n // Iterate by raw slot index; snapshot stores raw idx in the `eid` field\n // (wire format unchanged — idx is used for load-side entity re-creation).\n for (let idx = 1; idx < state.capacity; idx++) {\n const archId = state.entityArchetype[idx] ?? 0\n if (archId === 0) continue // slot unused\n\n const arch = state.archetypes[archId]\n if (!arch) continue\n\n // Build the packed eid from idx + current generation to do alive check\n const gen = state.generations[idx] ?? 0\n const packedEid = packEid(idx, gen, state.options)\n if (!arch.entityRow.has(packedEid)) continue\n\n const w = state.options.maskWordCount\n const base = idx * w\n const components: WorldSnapshot['entities'][0]['components'] = []\n for (let wi = 0; wi < w; wi++) {\n let word = state.entityMask[base + wi] ?? 0\n while (word !== 0) {\n const lsb = word & -word\n const bit = (wi << 5) + (31 - Math.clz32(lsb))\n const info = state.componentInfoByBit[bit]\n if (info) {\n const storage = state.componentStorageByBit[bit]\n let data: unknown = null\n if (info.kind === 'soa' && storage?.soa) {\n const obj: Record<string, unknown> = {}\n for (const f of info.fields) {\n const col = storage.soa[f.name]\n if (!col) continue\n if (f.vectorLen === 1) {\n obj[f.name] = col[idx]\n } else {\n const arr: number[] = []\n const baseI = idx * f.vectorLen\n for (let i = 0; i < f.vectorLen; i++) arr.push(col[baseI + i] ?? 0)\n obj[f.name] = arr\n }\n }\n data = obj\n } else if (info.kind === 'aos' && storage?.aos) {\n data = storage.aos[idx] ?? null\n } else {\n data = true\n }\n components.push({ kind: info.kind, id: info.id, data })\n }\n word &= word - 1\n }\n }\n // Wire format stores raw idx (not packed) for cross-session portability\n entities.push({ eid: idx, components })\n }\n return {\n version: state.version,\n capacity: state.capacity,\n entities,\n }\n}\n\n// Default initial-capacity floor for a restored world (matches createWorld's\n// own default). Keeps the common round-trip from needlessly shrinking while\n// staying a trivial allocation (~36 KB of index arrays at 1024 slots).\nconst RESTORE_CAPACITY_FLOOR = 1024\n\n// SECURITY (ECS-S-01): the snapshot `capacity` field is attacker-controlled on\n// any untrusted-load path (localStorage, network — both documented flows for the\n// stable deserializeWorld). createWorld only clamps to 1<<indexBits (16,777,216),\n// so an inflated value forces a near-600 MB TypedArray allocation from a tiny\n// payload — a browser-tab OOM DoS. Clamp the *starting* capacity to the real\n// entity count (fromJSON re-creates entities via createEntity, which grows the\n// world on demand, so a tight initial hint never loses data). A garbage/missing\n// value falls back to the count too.\nfunction clampRestoreCapacity(rawCapacity: unknown, entityCount: number): number {\n const needed = Math.max(RESTORE_CAPACITY_FLOOR, entityCount + 1)\n if (typeof rawCapacity !== 'number' || !Number.isFinite(rawCapacity) || rawCapacity <= 0) {\n return needed\n }\n return Math.min(Math.floor(rawCapacity), needed)\n}\n\nexport function fromJSON(snapshot: WorldSnapshot): World {\n const initialCapacity = clampRestoreCapacity(snapshot.capacity, snapshot.entities.length)\n const world = createWorld({ initialCapacity })\n const eidMap = new Map<number, EntityId>()\n for (const e of snapshot.entities) {\n const eid = createEntity(world)\n eidMap.set(e.eid, eid)\n }\n for (const e of snapshot.entities) {\n const eid = eidMap.get(e.eid)!\n for (const comp of e.components) {\n const info = getComponentByInternalId(comp.id)\n if (!info) {\n // Component missing — silently skip; future version may throw based on options\n continue\n }\n const handle = getComponentHandle(info)\n if (handle) {\n addComponent(world, eid, handle, comp.data as any)\n }\n }\n }\n return world\n}\n\n// Reconstruct a component handle from its ComponentInfo. Since defineComponent\n// returns plain handles { __kind, __id, __schema }, we can synthesize them.\nfunction getComponentHandle(info: ComponentInfo): ComponentLike | null {\n if (info.kind === 'soa') {\n return { __kind: 'soa', __id: info.id, __schema: info.schema ?? {} } as ComponentLike\n }\n if (info.kind === 'aos') {\n const factory = info.factory ?? (() => ({}))\n return { __kind: 'aos', __id: info.id, __factory: factory } as ComponentLike\n }\n return { __kind: 'tag', __id: info.id } as ComponentLike\n}\n\n// --- Binary packing (wrapped JSON for 0.1) ---\n\nfunction packBinary(snapshot: WorldSnapshot): Uint8Array {\n const json = JSON.stringify(snapshot)\n const jsonBytes = new TextEncoder().encode(json)\n const versionBytes = new TextEncoder().encode(VERSION)\n const headerSize = 4 + 4 + 4 + versionBytes.length + 4\n const total = headerSize + jsonBytes.length\n const out = new Uint8Array(total)\n const view = new DataView(out.buffer)\n let off = 0\n out[off++] = MAGIC.charCodeAt(0)\n out[off++] = MAGIC.charCodeAt(1)\n out[off++] = MAGIC.charCodeAt(2)\n out[off++] = MAGIC.charCodeAt(3)\n view.setUint32(off, FORMAT_VERSION, true)\n off += 4\n view.setUint32(off, versionBytes.length, true)\n off += 4\n out.set(versionBytes, off)\n off += versionBytes.length\n view.setUint32(off, jsonBytes.length, true)\n off += 4\n out.set(jsonBytes, off)\n return out\n}\n\nfunction unpackBinary(bytes: Uint8Array, options?: DeserializeOptions): WorldSnapshot {\n if (bytes.length < 12) throw new Error('aiecsjs: bytes too short to be a valid snapshot')\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)\n if (\n bytes[0] !== MAGIC.charCodeAt(0) ||\n bytes[1] !== MAGIC.charCodeAt(1) ||\n bytes[2] !== MAGIC.charCodeAt(2) ||\n bytes[3] !== MAGIC.charCodeAt(3)\n ) {\n throw new Error('aiecsjs: invalid magic bytes')\n }\n let off = 4\n const formatVersion = view.getUint32(off, true)\n off += 4\n const onUnknown = options?.onUnknownVersion ?? 'throw'\n if (formatVersion !== FORMAT_VERSION && onUnknown === 'throw') {\n throw new Error(`aiecsjs: format version ${formatVersion} not supported`)\n }\n\n // SECURITY: explicit bounds checks on every length field. DataView itself\n // throws on out-of-range reads, but an attacker who controls the bytes can\n // still craft a `verLen` that skips past data of their choosing — we make\n // each step's invariant explicit and impose a sane cap to short-circuit\n // pathological payloads early.\n const MAX_FIELD_LEN = 64 * 1024 * 1024 // 64 MiB\n if (off + 4 > bytes.length) {\n throw new Error('aiecsjs: snapshot truncated before verLen')\n }\n const verLen = view.getUint32(off, true)\n off += 4\n if (verLen > MAX_FIELD_LEN || off + verLen > bytes.length) {\n throw new Error(`aiecsjs: snapshot verLen=${verLen} out of bounds`)\n }\n off += verLen // skip the aiecsjs version string\n\n if (off + 4 > bytes.length) {\n throw new Error('aiecsjs: snapshot truncated before jsonLen')\n }\n const jsonLen = view.getUint32(off, true)\n off += 4\n if (jsonLen > MAX_FIELD_LEN || off + jsonLen > bytes.length) {\n throw new Error(`aiecsjs: snapshot jsonLen=${jsonLen} out of bounds`)\n }\n const jsonBytes = bytes.subarray(off, off + jsonLen)\n const json = new TextDecoder().decode(jsonBytes)\n // Wrap the parse so a malformed body (e.g. a truncated/garbled payload reached\n // under onUnknownVersion:'best-effort') surfaces a namespaced `aiecsjs:` error\n // instead of leaking a raw SyntaxError — consistent with the rest of the module.\n // Bounds checks above already guarantee `json` covers exactly the declared body.\n try {\n return JSON.parse(json) as WorldSnapshot\n } catch (cause) {\n throw new Error('aiecsjs: snapshot body is not valid JSON', { cause })\n }\n}\n\n// --- Delta serializer ---\n\ninterface DeltaState {\n world: World\n components: ComponentLike[]\n lastSnapshot: WorldSnapshot | null\n}\n\nexport function createDeltaSerializer(world: World, options?: SerializeOptions): DeltaSerializer {\n const state: DeltaState = {\n world,\n components:\n options?.components ??\n listAllComponents()\n .map((i) => getComponentHandle(i)!)\n .filter(Boolean),\n lastSnapshot: null,\n }\n return {\n capture(): Uint8Array {\n const current = toJSON(state.world)\n let delta: WorldSnapshot\n if (!state.lastSnapshot) {\n delta = current\n } else {\n // Compute simple delta: entities with changed components\n delta = computeDelta(state.lastSnapshot, current)\n }\n state.lastSnapshot = current\n return packBinary(delta)\n },\n apply(targetWorld: World, deltaBytes: Uint8Array): void {\n const snapshot = unpackBinary(deltaBytes)\n // Materialise each snapshot entity at the SAME slot index the source used\n // (the wire stores raw slot indices in `eid`). ensureEntityAtSlot reuses a\n // live slot, reclaims a freed one, or advances the frontier — so apply() is\n // sound on a non-pristine / independently-churned replica (it uses the\n // slot's CURRENT generation, never gen=0) and never spawns phantom padding\n // entities for holes in the source's slot range.\n //\n // CAVEAT: deltas carry added/changed entities only (see computeDelta) —\n // entity REMOVALS are not represented, so a replica is not pruned when the\n // source destroys an entity, and a component removed on the source is not\n // removed on the replica. apply() is additive/updating.\n const targetState = getWorldState(targetWorld)\n for (const e of snapshot.entities) {\n if (e.eid <= 0 || e.eid >= targetState.options.maxEntities) continue\n const eid = ensureEntityAtSlot(targetState, e.eid)\n for (const comp of e.components) {\n const info = getComponentByInternalId(comp.id)\n if (!info) continue\n const handle = getComponentHandle(info)\n if (handle) addComponent(targetWorld, eid, handle, comp.data as any)\n }\n }\n },\n reset(): void {\n state.lastSnapshot = null\n },\n }\n}\n\nfunction computeDelta(prev: WorldSnapshot, curr: WorldSnapshot): WorldSnapshot {\n const prevByEid = new Map(prev.entities.map((e) => [e.eid, e]))\n const changed: WorldSnapshot['entities'] = []\n for (const e of curr.entities) {\n const prevE = prevByEid.get(e.eid)\n if (!prevE) {\n changed.push(e)\n continue\n }\n const prevSig = JSON.stringify(prevE.components)\n const currSig = JSON.stringify(e.components)\n if (prevSig !== currSig) changed.push(e)\n }\n return { version: curr.version, capacity: curr.capacity, entities: changed }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunk5QWEV4VJ_cjs=require('./chunk-5QWEV4VJ.cjs');var E=1,f=new Map;function A(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 T(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=A(e),r=f.get(t);if(r)return r;let o={id:E++,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 f.set(t,o),o}function $(n){let e=n,t=`enter:${e.id}`,r=f.get(t);if(r)return r;let o={id:E++,mask:[],all:e.all,any:e.any,none:e.none,columnViewCache:e.columnViewCache,reactiveKind:"enter",sourceQueryId:e.id,sourceQuery:e};return f.set(t,o),o}function D(n){let e=n,t=`exit:${e.id}`,r=f.get(t);if(r)return r;let o={id:E++,mask:[],all:e.all,any:e.any,none:e.none,columnViewCache:e.columnViewCache,reactiveKind:"exit",sourceQueryId:e.id,sourceQuery:e};return f.set(t,o),o}function p(n,e){if(n.queries[e.id]===e&&n.queryMasks.has(e.id))return;let t=n.options.maskWordCount,r=chunk5QWEV4VJ_cjs.b(t),o=chunk5QWEV4VJ_cjs.b(t),i=chunk5QWEV4VJ_cjs.b(t);for(let a of e.all){let u=C(a),d=chunk5QWEV4VJ_cjs.q(n,u);chunk5QWEV4VJ_cjs.c(r,d);}for(let a of e.any){let u=C(a),d=chunk5QWEV4VJ_cjs.q(n,u);chunk5QWEV4VJ_cjs.c(o,d);}for(let a of e.none){let u=C(a),d=chunk5QWEV4VJ_cjs.q(n,u);chunk5QWEV4VJ_cjs.c(i,d);}let c={withMask:r,anyMask:o,noneMask:i,anyHasBits:!chunk5QWEV4VJ_cjs.d(o)};n.queryMasks.set(e.id,c),n.queries[e.id]=e,n.queryArchetypeCache[e.id]=null,n.queryArchetypeStamp[e.id]=-1;let s=[...chunk5QWEV4VJ_cjs.f(r),...chunk5QWEV4VJ_cjs.f(o),...chunk5QWEV4VJ_cjs.f(i)];for(let a of s){let u=n.bitToQueries.get(a);u||(u=new Set,n.bitToQueries.set(a,u)),u.add(e.id);}e.reactiveKind!=="normal"&&(n.reactiveBuffers.has(e.id)||n.reactiveBuffers.set(e.id,{entered:[],exited:[]}),e.sourceQuery&&p(n,e.sourceQuery));}function m(n,e){if(p(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 c=n.archetypes[i];chunk5QWEV4VJ_cjs.e(c.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 H(n,e){let t=chunk5QWEV4VJ_cjs.j(n),o=m(t,e),i=[];for(let c of o){let s=t.archetypes[c];i.push({id:s.id,mask:Array.from(s.mask),size:s.size});}return i}function L(n,e){let t=chunk5QWEV4VJ_cjs.j(n),r=e,o=[];if(r.reactiveKind==="enter"){let c=t.reactiveBuffers.get(r.id);if(c){for(let s of c.entered)o.push(s);c.entered.length=0;}return o}if(r.reactiveKind==="exit"){let c=t.reactiveBuffers.get(r.id);if(c){for(let s of c.exited)o.push(s);c.exited.length=0;}return o}let i=m(t,r);for(let c of i){let s=t.archetypes[c];for(let a=0;a<s.size;a++)o.push(s.entities[a]);}return o}function*F(n,e){let t=chunk5QWEV4VJ_cjs.j(n),r=e;if(r.reactiveKind!=="normal"){let i=t.reactiveBuffers.get(r.id);if(!i)return;let c=r.reactiveKind==="enter"?i.entered:i.exited;for(let s of c)yield s;c.length=0;return}let o=m(t,r);for(let i of o){let c=t.archetypes[i];for(let s=0;s<c.size;s++)yield c.entities[s];}}function O(n,e,t){let r=chunk5QWEV4VJ_cjs.j(n),o=e;if(o.reactiveKind!=="normal"){let s=r.reactiveBuffers.get(o.id);if(!s)return;let a=o.reactiveKind==="enter"?s.entered:s.exited;if(a.length===0)return;let u=g(r,o);for(let d=0;d<a.length;d++){let y=a[d];w(t,y,u);}a.length=0;return}p(r,o);let i=m(r,o),c=g(r,o);for(let s of i){let a=r.archetypes[s],u=a.entities;for(let d=0;d<a.size;d++)w(t,u[d],c);}}function w(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 G(n,e,t){let r=chunk5QWEV4VJ_cjs.j(n),o=e,i=r.options.indexMask;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 d=g(r,o);for(let y=0;y<u.length;y++){let h=u[y];W(t,h,h&i,d);}u.length=0;return}p(r,o);let c=m(r,o),s=g(r,o);for(let a of c){let u=r.archetypes[a],d=u.entities;for(let y=0;y<u.size;y++){let h=d[y];W(t,h,h&i,s);}}}function W(n,e,t,r){switch(r.length){case 0:n(e,t);break;case 1:n(e,t,r[0]);break;case 2:n(e,t,r[0],r[1]);break;case 3:n(e,t,r[0],r[1],r[2]);break;case 4:n(e,t,r[0],r[1],r[2],r[3]);break;case 5:n(e,t,r[0],r[1],r[2],r[3],r[4]);break;default:n(e,t,...r);}}function g(n,e){let t=[];for(let r of e.columnViewCache){let o=chunk5QWEV4VJ_cjs.J(r),i=n.componentBitFor.get(o.id);if(i===void 0){t.push(void 0);continue}let c=n.componentStorageByBit[i];if(!c){t.push(void 0);continue}c.kind==="soa"?t.push(c.soa):c.kind==="aos"?t.push(c.aos):t.push(true);}return t}function N(n,e,t,r,o){for(let s of f.values())s.reactiveKind!=="normal"&&s.sourceQuery&&n.queries[s.sourceQuery.id]!==s.sourceQuery&&p(n,s.sourceQuery);let i=n.bitToQueries.get(t);if(!i)return;let c=n.options.maskWordCount;for(let s of i){let a=n.queries[s];if(!a||a.reactiveKind!=="normal")continue;let u=n.queryMasks.get(s);if(!u)continue;let d=chunk5QWEV4VJ_cjs.e(r,u.withMask,u.anyMask,u.noneMask,u.anyHasBits,c),y=chunk5QWEV4VJ_cjs.e(o,u.withMask,u.anyMask,u.noneMask,u.anyHasBits,c);!d&&y?_(n,s,"enter",e):d&&!y&&_(n,s,"exit",e);}}function _(n,e,t,r){for(let o of f.values()){if(o.sourceQueryId!==e||o.reactiveKind!==t)continue;p(n,o);let i=K(n,o.id);t==="enter"?i.entered.push(r):i.exited.push(r);}}function K(n,e){let t=n.reactiveBuffers.get(e);return t||(t={entered:[],exited:[]},n.reactiveBuffers.set(e,t)),t}function C(n){let e=S(n);if(!e)throw new Error(`aiecsjs: component id ${n} not registered`);return e}var x=null;function U(n){x=n;}function S(n){return x?x(n):void 0}exports.a=T;exports.b=$;exports.c=D;exports.d=H;exports.e=L;exports.f=F;exports.g=O;exports.h=G;exports.i=N;exports.j=U;//# sourceMappingURL=chunk-SRX2MZPX.cjs.map
2
+ //# sourceMappingURL=chunk-SRX2MZPX.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/query.ts"],"names":["nextQueryId","moduleQueryCache","descKey","d","all","c","a","b","any","none","defineQuery","arg","desc","key","cached","q","enterQuery","query","reactive","exitQuery","ensureQueryRegistered","state","ww","withMask","createMask","anyMask","noneMask","compId","info","getComponentInfoById","bit","getOrRegisterComponentBit","setBit","bundle","isMaskZero","involvedBits","listBits","s","getQueryArchetypes","words","list","arch","matches","queryArchetypes","world","getWorldState","ids","out","id","runQuery","buf","e","archIds","r","iterQuery","src","forEachEntity","fn","cols","buildColumnViews","i","callWithCols","ents","eid","forEachEntityIndexed","indexMask","callWithColsIndexed","comp","getComponentInfo","storage","recordEntityMaskChange","changedBit","prevMask","nextMask","involved","qid","wasMatch","isMatch","pushReactive","queryId","kind","ensureReactiveBuffer","componentId","lazyGetComponentInfo","_getComponentInfoFn","registerComponentLookup"],"mappings":"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","file":"chunk-SRX2MZPX.cjs","sourcesContent":["import { createMask, isMaskZero, listBits, matches, setBit } from './bitmask.js'\nimport { getComponentInfo } from './component.js'\nimport type {\n Archetype,\n ComponentInfo,\n ComponentLike,\n EntityId,\n Query,\n QueryDescriptor,\n QueryInternal,\n QueryMaskBundle,\n ReactiveBuffer,\n World,\n WorldState,\n} from './types.js'\nimport {\n getOrRegisterComponentBit,\n getWorldState,\n readEntityMask,\n tryGetComponentBit,\n} from './world.js'\n\nlet nextQueryId = 1\nconst moduleQueryCache = new Map<string, QueryInternal>()\n\nfunction descKey(d: QueryDescriptor): string {\n const all = (d.all ?? [])\n .map((c) => c.__id)\n .sort((a, b) => a - b)\n .join('-')\n const any = (d.any ?? [])\n .map((c) => c.__id)\n .sort((a, b) => a - b)\n .join('-')\n const none = (d.none ?? [])\n .map((c) => c.__id)\n .sort((a, b) => a - b)\n .join('-')\n return `A${all}|Y${any}|N${none}`\n}\n\nexport function defineQuery(arg: ComponentLike[] | QueryDescriptor): Query {\n const desc: QueryDescriptor = Array.isArray(arg) ? { all: arg } : arg\n\n // Validate all members are components\n for (const c of [...(desc.all ?? []), ...(desc.any ?? []), ...(desc.none ?? [])]) {\n if (!c || typeof c !== 'object' || typeof (c as any).__id !== 'number') {\n throw new TypeError('aiecsjs: defineQuery received a non-component value')\n }\n }\n\n const key = descKey(desc)\n const cached = moduleQueryCache.get(key)\n if (cached) return cached\n\n const q: QueryInternal = {\n id: nextQueryId++,\n mask: [],\n all: (desc.all ?? []).map((c) => c.__id),\n any: (desc.any ?? []).map((c) => c.__id),\n none: (desc.none ?? []).map((c) => c.__id),\n columnViewCache: [...(desc.all ?? []), ...(desc.any ?? [])],\n reactiveKind: 'normal',\n sourceQueryId: -1,\n sourceQuery: null,\n }\n moduleQueryCache.set(key, q)\n return q\n}\n\n/**\n * Reactive \"entered\" view of `query`: each read drains the entities that began\n * matching since the last read (via `runQuery` / `iterQuery` / `forEachEntity`).\n *\n * **MUST-DRAIN CONTRACT (unbounded buffer).** The enter buffer has **no cap**.\n * Every structural change that makes an entity newly match pushes one id; the\n * buffer only shrinks when you read the reactive view. A view that is created\n * but never read — e.g. a disabled system, or reading only the {@link exitQuery}\n * twin — accumulates one number per event **forever**, an unbounded memory leak\n * at churn rates (e.g. ~1k spawns/frame). Read every enter view you create, once\n * per frame. Dropping ids silently would corrupt enter/exit symmetry, so capping\n * is intentionally not done — draining is the caller's responsibility.\n */\nexport function enterQuery(query: Query): Query {\n const q = query as QueryInternal\n const key = `enter:${q.id}`\n const cached = moduleQueryCache.get(key)\n if (cached) return cached\n const reactive: QueryInternal = {\n id: nextQueryId++,\n mask: [],\n all: q.all,\n any: q.any,\n none: q.none,\n columnViewCache: q.columnViewCache,\n reactiveKind: 'enter',\n sourceQueryId: q.id,\n sourceQuery: q,\n }\n moduleQueryCache.set(key, reactive)\n return reactive\n}\n\n/**\n * Reactive \"exited\" view of `query`: each read drains the entities that stopped\n * matching since the last read (via `runQuery` / `iterQuery` / `forEachEntity`).\n *\n * **MUST-DRAIN CONTRACT (unbounded buffer).** The exit buffer has **no cap** —\n * same discipline as {@link enterQuery}. An unread exit view accumulates one id\n * per matching structural change (including every `destroyEntity` of a matching\n * entity) without bound. Read every exit view you create, once per frame. Capping\n * is intentionally not done because dropping ids would break enter/exit symmetry.\n */\nexport function exitQuery(query: Query): Query {\n const q = query as QueryInternal\n const key = `exit:${q.id}`\n const cached = moduleQueryCache.get(key)\n if (cached) return cached\n const reactive: QueryInternal = {\n id: nextQueryId++,\n mask: [],\n all: q.all,\n any: q.any,\n none: q.none,\n columnViewCache: q.columnViewCache,\n reactiveKind: 'exit',\n sourceQueryId: q.id,\n sourceQuery: q,\n }\n moduleQueryCache.set(key, reactive)\n return reactive\n}\n\n// --- Per-world query setup ---\n\nfunction ensureQueryRegistered(state: WorldState, q: QueryInternal): void {\n if (state.queries[q.id] === q && state.queryMasks.has(q.id)) return\n\n // Build per-world bitmasks (this may register new bits)\n const ww = state.options.maskWordCount\n const withMask = createMask(ww)\n const anyMask = createMask(ww)\n const noneMask = createMask(ww)\n for (const compId of q.all) {\n const info = getComponentInfoById(compId)\n const bit = getOrRegisterComponentBit(state, info)\n setBit(withMask, bit)\n }\n for (const compId of q.any) {\n const info = getComponentInfoById(compId)\n const bit = getOrRegisterComponentBit(state, info)\n setBit(anyMask, bit)\n }\n for (const compId of q.none) {\n const info = getComponentInfoById(compId)\n const bit = getOrRegisterComponentBit(state, info)\n setBit(noneMask, bit)\n }\n\n const bundle: QueryMaskBundle = {\n withMask,\n anyMask,\n noneMask,\n anyHasBits: !isMaskZero(anyMask),\n }\n state.queryMasks.set(q.id, bundle)\n\n state.queries[q.id] = q\n state.queryArchetypeCache[q.id] = null\n state.queryArchetypeStamp[q.id] = -1\n\n // Build bit → queries index for fast reactive lookup\n const involvedBits: number[] = [\n ...listBits(withMask),\n ...listBits(anyMask),\n ...listBits(noneMask),\n ]\n for (const b of involvedBits) {\n let s = state.bitToQueries.get(b)\n if (!s) {\n s = new Set<number>()\n state.bitToQueries.set(b, s)\n }\n s.add(q.id)\n }\n\n // Initialize reactive buffer for enter/exit queries\n if (q.reactiveKind !== 'normal') {\n if (!state.reactiveBuffers.has(q.id)) {\n state.reactiveBuffers.set(q.id, { entered: [], exited: [] })\n }\n // Also register the source query so recordEntityMaskChange will see it\n if (q.sourceQuery) ensureQueryRegistered(state, q.sourceQuery)\n }\n}\n\nfunction getQueryArchetypes(state: WorldState, q: QueryInternal): number[] {\n ensureQueryRegistered(state, q)\n if (state.queryArchetypeCache[q.id] && state.queryArchetypeStamp[q.id] === state.queryVersion) {\n return state.queryArchetypeCache[q.id]!\n }\n const bundle = state.queryMasks.get(q.id)!\n const words = state.options.maskWordCount\n const list: number[] = []\n for (let i = 0; i < state.archetypes.length; i++) {\n const arch = state.archetypes[i]!\n if (\n matches(arch.mask, bundle.withMask, bundle.anyMask, bundle.noneMask, bundle.anyHasBits, words)\n ) {\n list.push(i)\n }\n }\n state.queryArchetypeCache[q.id] = list\n state.queryArchetypeStamp[q.id] = state.queryVersion\n return list\n}\n\nexport function queryArchetypes(world: World, query: Query): readonly Archetype[] {\n const state = getWorldState(world)\n const q = query as QueryInternal\n const ids = getQueryArchetypes(state, q)\n const out: Archetype[] = []\n for (const id of ids) {\n const arch = state.archetypes[id]!\n out.push({ id: arch.id, mask: Array.from(arch.mask), size: arch.size })\n }\n return out\n}\n\nexport function runQuery(world: World, query: Query): readonly EntityId[] {\n const state = getWorldState(world)\n const q = query as QueryInternal\n const out: EntityId[] = []\n if (q.reactiveKind === 'enter') {\n const buf = state.reactiveBuffers.get(q.id)\n if (buf) {\n for (const e of buf.entered) out.push(e as EntityId)\n buf.entered.length = 0\n }\n return out\n }\n if (q.reactiveKind === 'exit') {\n const buf = state.reactiveBuffers.get(q.id)\n if (buf) {\n for (const e of buf.exited) out.push(e as EntityId)\n buf.exited.length = 0\n }\n return out\n }\n const archIds = getQueryArchetypes(state, q)\n for (const id of archIds) {\n const arch = state.archetypes[id]!\n for (let r = 0; r < arch.size; r++) {\n out.push(arch.entities[r] as EntityId)\n }\n }\n return out\n}\n\nexport function* iterQuery(world: World, query: Query): IterableIterator<EntityId> {\n const state = getWorldState(world)\n const q = query as QueryInternal\n if (q.reactiveKind !== 'normal') {\n const buf = state.reactiveBuffers.get(q.id)\n if (!buf) return\n const src = q.reactiveKind === 'enter' ? buf.entered : buf.exited\n for (const e of src) yield e as EntityId\n src.length = 0\n return\n }\n const archIds = getQueryArchetypes(state, q)\n for (const id of archIds) {\n const arch = state.archetypes[id]!\n for (let r = 0; r < arch.size; r++) {\n yield arch.entities[r] as EntityId\n }\n }\n}\n\n/**\n * Iterate every entity matching `query`, invoking `fn(e, ...cols)` once per row\n * with the packed {@link EntityId} and the query's SoA column views.\n *\n * **Caution — `e` is a packed EntityId, not a column subscript.** It carries the\n * generation in its high bits, so indexing a column view with it directly\n * (`pos.x[e]`) reads out of bounds once a slot has been recycled. Use `e` only\n * for identity operations (`destroyEntity` / `hasComponent` / `refOf`). To index\n * columns safely, prefer {@link forEachEntityIndexed} — which yields the masked\n * slot index `i` alongside `e` — or mask it yourself with {@link getEntityIndex}.\n *\n * @see {@link forEachEntityIndexed} — same iteration plus the safe column index `i`.\n * @see {@link getEntityIndex} — mask a packed EntityId to its raw slot index.\n */\nexport function forEachEntity(\n world: World,\n query: Query,\n fn: (eid: EntityId, ...cols: any[]) => void,\n): void {\n const state = getWorldState(world)\n const q = query as QueryInternal\n\n if (q.reactiveKind !== 'normal') {\n const buf = state.reactiveBuffers.get(q.id)\n if (!buf) return\n const src = q.reactiveKind === 'enter' ? buf.entered : buf.exited\n if (src.length === 0) return\n const cols = buildColumnViews(state, q)\n for (let i = 0; i < src.length; i++) {\n const e = src[i] as EntityId\n callWithCols(fn, e, cols)\n }\n src.length = 0\n return\n }\n\n ensureQueryRegistered(state, q)\n const archIds = getQueryArchetypes(state, q)\n const cols = buildColumnViews(state, q)\n for (const id of archIds) {\n const arch = state.archetypes[id]!\n const ents = arch.entities\n // Re-read `arch.size` each iteration (do NOT cache it as `n`): an in-loop\n // `destroyEntity` swap-pops the visited row, shrinks `arch.size`, and zeroes\n // the freed tail slot. A cached bound would keep walking into those zeroed\n // tail rows and hand the callback the reserved sentinel eid 0 (ECS-B-01).\n // The swapped-in survivor is intentionally skipped this pass (deferred to the\n // next). This is a scalar property read — no per-iteration allocation, so the\n // zero-allocation hot-path contract holds. Mirrors runQuery (:230) / iterQuery.\n for (let r = 0; r < arch.size; r++) {\n callWithCols(fn, ents[r] as EntityId, cols)\n }\n }\n}\n\nfunction callWithCols(\n fn: (eid: EntityId, ...cols: any[]) => void,\n eid: EntityId,\n cols: any[],\n): void {\n // Specialise for low arities to avoid spread allocation.\n switch (cols.length) {\n case 0:\n fn(eid)\n break\n case 1:\n fn(eid, cols[0])\n break\n case 2:\n fn(eid, cols[0], cols[1])\n break\n case 3:\n fn(eid, cols[0], cols[1], cols[2])\n break\n case 4:\n fn(eid, cols[0], cols[1], cols[2], cols[3])\n break\n case 5:\n fn(eid, cols[0], cols[1], cols[2], cols[3], cols[4])\n break\n default:\n fn(eid, ...cols)\n }\n}\n\n/**\n * Like {@link forEachEntity}, but yields the masked column index `i` alongside\n * the packed `EntityId`. The callback signature is `(e, i, ...cols)`:\n *\n * - `e` — the packed EntityId (carries the generation in its high bits). Use\n * it for in-loop `destroyEntity` / `hasComponent` / `refOf`, exactly as with\n * `forEachEntity`.\n * - `i` — `e & indexMask`, the raw slot index. This is the **correct subscript**\n * for SoA column views (`pos.x[i]`), and stays correct after a slot is\n * recycled — where indexing with the packed `e` would read out of bounds.\n * - `...cols` — the same column views `forEachEntity` passes.\n *\n * This closes the packed-EntityId footgun (A1): callers no longer need to call\n * `getEntityIndex(e)` (or hand-mask) themselves to index columns safely.\n */\nexport function forEachEntityIndexed(\n world: World,\n query: Query,\n fn: (e: EntityId, i: number, ...cols: any[]) => void,\n): void {\n const state = getWorldState(world)\n const q = query as QueryInternal\n const indexMask = state.options.indexMask\n\n if (q.reactiveKind !== 'normal') {\n const buf = state.reactiveBuffers.get(q.id)\n if (!buf) return\n const src = q.reactiveKind === 'enter' ? buf.entered : buf.exited\n if (src.length === 0) return\n const cols = buildColumnViews(state, q)\n for (let i = 0; i < src.length; i++) {\n const e = src[i] as EntityId\n callWithColsIndexed(fn, e, e & indexMask, cols)\n }\n src.length = 0\n return\n }\n\n ensureQueryRegistered(state, q)\n const archIds = getQueryArchetypes(state, q)\n const cols = buildColumnViews(state, q)\n for (const id of archIds) {\n const arch = state.archetypes[id]!\n const ents = arch.entities\n // Re-read `arch.size` each iteration — see forEachEntity for the rationale.\n // An in-loop `destroyEntity` swap-pops the row and zeroes the freed tail; a\n // cached bound would replay the sentinel eid 0 across the public boundary\n // (ECS-B-01). Scalar read only; the zero-allocation hot-path contract holds.\n for (let r = 0; r < arch.size; r++) {\n const e = ents[r] as EntityId\n callWithColsIndexed(fn, e, e & indexMask, cols)\n }\n }\n}\n\nfunction callWithColsIndexed(\n fn: (e: EntityId, i: number, ...cols: any[]) => void,\n e: EntityId,\n i: number,\n cols: any[],\n): void {\n // Specialise for low arities to avoid spread allocation.\n switch (cols.length) {\n case 0:\n fn(e, i)\n break\n case 1:\n fn(e, i, cols[0])\n break\n case 2:\n fn(e, i, cols[0], cols[1])\n break\n case 3:\n fn(e, i, cols[0], cols[1], cols[2])\n break\n case 4:\n fn(e, i, cols[0], cols[1], cols[2], cols[3])\n break\n case 5:\n fn(e, i, cols[0], cols[1], cols[2], cols[3], cols[4])\n break\n default:\n fn(e, i, ...cols)\n }\n}\n\nfunction buildColumnViews(state: WorldState, q: QueryInternal): any[] {\n const out: any[] = []\n for (const comp of q.columnViewCache) {\n const info = getComponentInfo(comp)\n const bit = state.componentBitFor.get(info.id)\n if (bit === undefined) {\n out.push(undefined)\n continue\n }\n const storage = state.componentStorageByBit[bit]\n if (!storage) {\n out.push(undefined)\n continue\n }\n if (storage.kind === 'soa') out.push(storage.soa)\n else if (storage.kind === 'aos') out.push(storage.aos)\n else out.push(true) // tag\n }\n return out\n}\n\n// --- Reactive query updates (called from migration code) ---\n\nexport function recordEntityMaskChange(\n state: WorldState,\n eid: EntityId,\n changedBit: number,\n prevMask: Uint32Array,\n nextMask: Uint32Array,\n): void {\n // Lazy-register any reactive queries (and their sources) so we can correctly\n // determine match transitions even if the user only ever called enterQuery/exitQuery.\n for (const q of moduleQueryCache.values()) {\n if (q.reactiveKind === 'normal') continue\n if (q.sourceQuery && state.queries[q.sourceQuery.id] !== q.sourceQuery) {\n ensureQueryRegistered(state, q.sourceQuery)\n }\n }\n\n const involved = state.bitToQueries.get(changedBit)\n if (!involved) return\n const words = state.options.maskWordCount\n for (const qid of involved) {\n const q = state.queries[qid]\n if (!q) continue\n if (q.reactiveKind !== 'normal') continue\n const bundle = state.queryMasks.get(qid)\n if (!bundle) continue\n const wasMatch = matches(\n prevMask,\n bundle.withMask,\n bundle.anyMask,\n bundle.noneMask,\n bundle.anyHasBits,\n words,\n )\n const isMatch = matches(\n nextMask,\n bundle.withMask,\n bundle.anyMask,\n bundle.noneMask,\n bundle.anyHasBits,\n words,\n )\n if (!wasMatch && isMatch) {\n pushReactive(state, qid, 'enter', eid)\n } else if (wasMatch && !isMatch) {\n pushReactive(state, qid, 'exit', eid)\n }\n }\n}\n\nfunction pushReactive(\n state: WorldState,\n queryId: number,\n kind: 'enter' | 'exit',\n eid: EntityId,\n): void {\n // Walk the module cache (not just state.queries) so reactive variants that\n // haven't been registered with this world yet still receive events.\n for (const r of moduleQueryCache.values()) {\n if (r.sourceQueryId !== queryId) continue\n if (r.reactiveKind !== kind) continue\n // Lazily register the reactive query in this world so subsequent reads can find it\n ensureQueryRegistered(state, r)\n const buf = ensureReactiveBuffer(state, r.id)\n if (kind === 'enter') buf.entered.push(eid as number)\n else buf.exited.push(eid as number)\n }\n}\n\nfunction ensureReactiveBuffer(state: WorldState, qid: number): ReactiveBuffer {\n let buf = state.reactiveBuffers.get(qid)\n if (!buf) {\n buf = { entered: [], exited: [] }\n state.reactiveBuffers.set(qid, buf)\n }\n return buf\n}\n\n// --- Helpers ---\n\nfunction getComponentInfoById(componentId: number): ComponentInfo {\n // We need access to the component registry's lookup by id. Re-import dynamically to avoid cycles.\n const info = lazyGetComponentInfo(componentId)\n if (!info) throw new Error(`aiecsjs: component id ${componentId} not registered`)\n return info\n}\n\nlet _getComponentInfoFn: ((id: number) => ComponentInfo | undefined) | null = null\nexport function registerComponentLookup(fn: (id: number) => ComponentInfo | undefined): void {\n _getComponentInfoFn = fn\n}\nfunction lazyGetComponentInfo(id: number): ComponentInfo | undefined {\n return _getComponentInfoFn ? _getComponentInfoFn(id) : undefined\n}\n\nexport function _resetQueryRegistry_FOR_TESTS_ONLY(): void {\n moduleQueryCache.clear()\n nextQueryId = 1\n}\n"]}
package/dist/commands.cjs CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var chunkM6L4SSE4_cjs=require('./chunk-M6L4SSE4.cjs');function l(n){let e={worldId:chunkM6L4SSE4_cjs.i(n).id,ops:[],nextPlaceholder:-1,flushing:false};return h(e)}function C(n){let o=y(n);if(!o.flushing){o.flushing=true;try{let e=B(o.worldId),r=new Map;for(let t of o.ops)t.kind==="create"&&r.set(t.placeholder,chunkM6L4SSE4_cjs.u(e));let d=t=>{let a=t;if(a<0){let f=r.get(a);if(f===void 0)throw new Error(`aiecsjs: unresolved placeholder ${a}`);return f}return t};for(let t of o.ops)t.kind==="add"?chunkM6L4SSE4_cjs.J(e,d(t.eid),t.component,t.initial):t.kind==="remove"&&chunkM6L4SSE4_cjs.K(e,d(t.eid),t.component);for(let t of o.ops)t.kind==="destroy"&&chunkM6L4SSE4_cjs.w(e,d(t.eid));o.ops.length=0,o.nextPlaceholder=-1;}finally{o.flushing=false;}}}function W(n,o){let e=l(n),r=o(e);return C(e),r}var p=new WeakMap;function h(n){let o={add(e,r,d){n.ops.push({kind:"add",eid:e,component:r,initial:d});},remove(e,r){n.ops.push({kind:"remove",eid:e,component:r});},destroy(e){n.ops.push({kind:"destroy",eid:e});},create(){let e=n.nextPlaceholder--;return n.ops.push({kind:"create",placeholder:e}),e}};return p.set(o,n),o}function y(n){let o=p.get(n);if(!o)throw new Error("aiecsjs: unknown CommandBuffer");return o}function B(n){let o=k(n);return {id:o.id,capacity:o.capacity,version:o.version}}function k(n){return chunkM6L4SSE4_cjs.i({id:n,capacity:0,version:"0.0.0"})}exports.createCommandBuffer=l;exports.flush=C;exports.withCommandBuffer=W;//# sourceMappingURL=commands.cjs.map
1
+ 'use strict';var chunk5QWEV4VJ_cjs=require('./chunk-5QWEV4VJ.cjs');function l(e){let n={worldId:chunk5QWEV4VJ_cjs.j(e).id,ops:[],nextPlaceholder:-1,flushing:false};return h(n)}function C(e){let o=y(e);if(!o.flushing){o.flushing=true;try{let n=k(o.worldId),r=new Map;for(let t of o.ops)t.kind==="create"&&r.set(t.placeholder,chunk5QWEV4VJ_cjs.v(n));let d=t=>{let i=t;if(i<0){let f=r.get(i);if(f===void 0)throw new Error(`aiecsjs: unresolved placeholder ${i}`);return f}return t};for(let t of o.ops)t.kind==="add"?chunk5QWEV4VJ_cjs.K(n,d(t.eid),t.component,t.initial):t.kind==="remove"&&chunk5QWEV4VJ_cjs.L(n,d(t.eid),t.component);for(let t of o.ops)t.kind==="destroy"&&chunk5QWEV4VJ_cjs.x(n,d(t.eid));o.ops.length=0,o.nextPlaceholder=-1;}finally{o.flushing=false;}}}function b(e,o){let n=l(e),r=o(n);return C(n),r}var p=new WeakMap;function h(e){let o={add(n,r,d){e.ops.push({kind:"add",eid:n,component:r,initial:d});},remove(n,r){e.ops.push({kind:"remove",eid:n,component:r});},destroy(n){e.ops.push({kind:"destroy",eid:n});},create(){let n=e.nextPlaceholder--;return e.ops.push({kind:"create",placeholder:n}),n}};return p.set(o,e),o}function y(e){let o=p.get(e);if(!o)throw new Error("aiecsjs: unknown CommandBuffer");return o}function k(e){let o=B(e);return {id:o.id,capacity:o.capacity,version:o.version}}function B(e){return chunk5QWEV4VJ_cjs.j({id:e,capacity:0,version:"0.0.0"})}exports.createCommandBuffer=l;exports.flush=C;exports.withCommandBuffer=b;//# sourceMappingURL=commands.cjs.map
2
2
  //# sourceMappingURL=commands.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands.ts"],"names":["createCommandBuffer","world","buf","getWorldState","makeApi","flush","cb","state","stateOf","lookupWorld","placeholders","op","createEntity","resolve","eid","num","real","addComponent","removeComponent","destroyEntity","withCommandBuffer","fn","result","cbStateMap","api","component","initial","ph","s","worldId","lookupState"],"mappings":"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","file":"commands.cjs","sourcesContent":["// aiecsjs/commands — deferred structural mutations during iteration.\n\nimport { addComponent, removeComponent } from './internal/component.js'\nimport { createEntity, destroyEntity } from './internal/entity.js'\nimport type {\n CommandBuffer,\n CommandBufferState,\n CommandOp,\n ComponentInit,\n ComponentLike,\n EntityId,\n World,\n} from './internal/types.js'\nimport { getWorldState } from './internal/world.js'\n\nexport function createCommandBuffer(world: World): CommandBuffer {\n const state = getWorldState(world)\n const buf: CommandBufferState = {\n worldId: state.id,\n ops: [],\n nextPlaceholder: -1,\n flushing: false,\n }\n attachState(buf)\n return makeApi(buf)\n}\n\nexport function flush(cb: CommandBuffer): void {\n const state = stateOf(cb)\n if (state.flushing) return\n state.flushing = true\n try {\n const world = lookupWorld(state.worldId)\n\n // Phase 1: resolve placeholders by creating real entities first\n const placeholders = new Map<number, EntityId>()\n for (const op of state.ops) {\n if (op.kind === 'create') {\n placeholders.set(op.placeholder, createEntity(world))\n }\n }\n\n const resolve = (eid: EntityId): EntityId => {\n const num = eid as number\n if (num < 0) {\n const real = placeholders.get(num)\n if (real === undefined) throw new Error(`aiecsjs: unresolved placeholder ${num}`)\n return real\n }\n return eid\n }\n\n // Phase 2: add/remove in queue order\n for (const op of state.ops) {\n if (op.kind === 'add') {\n addComponent(\n world,\n resolve(op.eid),\n op.component,\n op.initial as ComponentInit<ComponentLike>,\n )\n } else if (op.kind === 'remove') {\n removeComponent(world, resolve(op.eid), op.component)\n }\n }\n\n // Phase 3: destroy last\n for (const op of state.ops) {\n if (op.kind === 'destroy') {\n destroyEntity(world, resolve(op.eid))\n }\n }\n\n state.ops.length = 0\n state.nextPlaceholder = -1\n } finally {\n state.flushing = false\n }\n}\n\nexport function withCommandBuffer<R>(world: World, fn: (cb: CommandBuffer) => R): R {\n const cb = createCommandBuffer(world)\n const result = fn(cb)\n flush(cb)\n return result\n}\n\n// --- Internals ---\n\nconst cbStateMap = new WeakMap<object, CommandBufferState>()\n\nfunction attachState(state: CommandBufferState): void {\n // The CommandBuffer API object is created in makeApi; we link them via WeakMap there.\n void state\n}\n\nfunction makeApi(state: CommandBufferState): CommandBuffer {\n const api: CommandBuffer = {\n add(eid, component, initial) {\n state.ops.push({ kind: 'add', eid, component, initial })\n },\n remove(eid, component) {\n state.ops.push({ kind: 'remove', eid, component })\n },\n destroy(eid) {\n state.ops.push({ kind: 'destroy', eid })\n },\n create() {\n const ph = state.nextPlaceholder--\n state.ops.push({ kind: 'create', placeholder: ph })\n return ph as EntityId\n },\n }\n cbStateMap.set(api, state)\n return api\n}\n\nfunction stateOf(cb: CommandBuffer): CommandBufferState {\n const s = cbStateMap.get(cb)\n if (!s) throw new Error('aiecsjs: unknown CommandBuffer')\n return s\n}\n\n// Look up a public World from its state id. We need a registry — re-import lazily.\nfunction lookupWorld(worldId: number): World {\n // The world registry is in internal/world.ts. We need to construct a public reference.\n // Since destroy clears state, we look up afresh by id via the worldRegistry.\n const state = lookupState(worldId)\n return { id: state.id, capacity: state.capacity, version: state.version } as World\n}\n\nfunction lookupState(worldId: number): import('./internal/types.js').WorldState {\n // Access worldRegistry indirectly via getWorldState requires a World object.\n // Use a small workaround: construct a minimal World-like and call getWorldState.\n return getWorldState({ id: worldId, capacity: 0, version: '0.0.0' } as World)\n}\n"]}
1
+ {"version":3,"sources":["../src/commands.ts"],"names":["createCommandBuffer","world","buf","getWorldState","makeApi","flush","cb","state","stateOf","lookupWorld","placeholders","op","createEntity","resolve","eid","num","real","addComponent","removeComponent","destroyEntity","withCommandBuffer","fn","result","cbStateMap","api","component","initial","ph","s","worldId","lookupState"],"mappings":"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","file":"commands.cjs","sourcesContent":["// aiecsjs/commands — deferred structural mutations during iteration.\n\nimport { addComponent, removeComponent } from './internal/component.js'\nimport { createEntity, destroyEntity } from './internal/entity.js'\nimport type {\n CommandBuffer,\n CommandBufferState,\n CommandOp,\n ComponentInit,\n ComponentLike,\n EntityId,\n World,\n} from './internal/types.js'\nimport { getWorldState } from './internal/world.js'\n\nexport function createCommandBuffer(world: World): CommandBuffer {\n const state = getWorldState(world)\n const buf: CommandBufferState = {\n worldId: state.id,\n ops: [],\n nextPlaceholder: -1,\n flushing: false,\n }\n return makeApi(buf)\n}\n\nexport function flush(cb: CommandBuffer): void {\n const state = stateOf(cb)\n if (state.flushing) return\n state.flushing = true\n try {\n const world = lookupWorld(state.worldId)\n\n // Phase 1: resolve placeholders by creating real entities first\n const placeholders = new Map<number, EntityId>()\n for (const op of state.ops) {\n if (op.kind === 'create') {\n placeholders.set(op.placeholder, createEntity(world))\n }\n }\n\n const resolve = (eid: EntityId): EntityId => {\n const num = eid as number\n if (num < 0) {\n const real = placeholders.get(num)\n if (real === undefined) throw new Error(`aiecsjs: unresolved placeholder ${num}`)\n return real\n }\n return eid\n }\n\n // Phase 2: add/remove in queue order\n for (const op of state.ops) {\n if (op.kind === 'add') {\n addComponent(\n world,\n resolve(op.eid),\n op.component,\n op.initial as ComponentInit<ComponentLike>,\n )\n } else if (op.kind === 'remove') {\n removeComponent(world, resolve(op.eid), op.component)\n }\n }\n\n // Phase 3: destroy last\n for (const op of state.ops) {\n if (op.kind === 'destroy') {\n destroyEntity(world, resolve(op.eid))\n }\n }\n\n state.ops.length = 0\n state.nextPlaceholder = -1\n } finally {\n state.flushing = false\n }\n}\n\nexport function withCommandBuffer<R>(world: World, fn: (cb: CommandBuffer) => R): R {\n const cb = createCommandBuffer(world)\n const result = fn(cb)\n flush(cb)\n return result\n}\n\n// --- Internals ---\n\nconst cbStateMap = new WeakMap<object, CommandBufferState>()\n\nfunction makeApi(state: CommandBufferState): CommandBuffer {\n const api: CommandBuffer = {\n add(eid, component, initial) {\n state.ops.push({ kind: 'add', eid, component, initial })\n },\n remove(eid, component) {\n state.ops.push({ kind: 'remove', eid, component })\n },\n destroy(eid) {\n state.ops.push({ kind: 'destroy', eid })\n },\n create() {\n const ph = state.nextPlaceholder--\n state.ops.push({ kind: 'create', placeholder: ph })\n return ph as EntityId\n },\n }\n cbStateMap.set(api, state)\n return api\n}\n\nfunction stateOf(cb: CommandBuffer): CommandBufferState {\n const s = cbStateMap.get(cb)\n if (!s) throw new Error('aiecsjs: unknown CommandBuffer')\n return s\n}\n\n// Look up a public World from its state id. We need a registry — re-import lazily.\nfunction lookupWorld(worldId: number): World {\n // The world registry is in internal/world.ts. We need to construct a public reference.\n // Since destroy clears state, we look up afresh by id via the worldRegistry.\n const state = lookupState(worldId)\n return { id: state.id, capacity: state.capacity, version: state.version } as World\n}\n\nfunction lookupState(worldId: number): import('./internal/types.js').WorldState {\n // Access worldRegistry indirectly via getWorldState requires a World object.\n // Use a small workaround: construct a minimal World-like and call getWorldState.\n return getWorldState({ id: worldId, capacity: 0, version: '0.0.0' } as World)\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { W as World, C as CommandBuffer } from './types-BGEeHad-.cjs';
1
+ import { W as World, C as CommandBuffer } from './types-BeVLA7xG.cjs';
2
2
 
3
3
  declare function createCommandBuffer(world: World): CommandBuffer;
4
4
  declare function flush(cb: CommandBuffer): void;
@@ -1,4 +1,4 @@
1
- import { W as World, C as CommandBuffer } from './types-BGEeHad-.js';
1
+ import { W as World, C as CommandBuffer } from './types-BeVLA7xG.js';
2
2
 
3
3
  declare function createCommandBuffer(world: World): CommandBuffer;
4
4
  declare function flush(cb: CommandBuffer): void;
package/dist/commands.js CHANGED
@@ -1,2 +1,2 @@
1
- import {i,u,J,K,w}from'./chunk-ENULPSKV.js';function l(n){let e={worldId:i(n).id,ops:[],nextPlaceholder:-1,flushing:false};return h(e)}function C(n){let o=y(n);if(!o.flushing){o.flushing=true;try{let e=B(o.worldId),r=new Map;for(let t of o.ops)t.kind==="create"&&r.set(t.placeholder,u(e));let d=t=>{let a=t;if(a<0){let f=r.get(a);if(f===void 0)throw new Error(`aiecsjs: unresolved placeholder ${a}`);return f}return t};for(let t of o.ops)t.kind==="add"?J(e,d(t.eid),t.component,t.initial):t.kind==="remove"&&K(e,d(t.eid),t.component);for(let t of o.ops)t.kind==="destroy"&&w(e,d(t.eid));o.ops.length=0,o.nextPlaceholder=-1;}finally{o.flushing=false;}}}function W(n,o){let e=l(n),r=o(e);return C(e),r}var p=new WeakMap;function h(n){let o={add(e,r,d){n.ops.push({kind:"add",eid:e,component:r,initial:d});},remove(e,r){n.ops.push({kind:"remove",eid:e,component:r});},destroy(e){n.ops.push({kind:"destroy",eid:e});},create(){let e=n.nextPlaceholder--;return n.ops.push({kind:"create",placeholder:e}),e}};return p.set(o,n),o}function y(n){let o=p.get(n);if(!o)throw new Error("aiecsjs: unknown CommandBuffer");return o}function B(n){let o=k(n);return {id:o.id,capacity:o.capacity,version:o.version}}function k(n){return i({id:n,capacity:0,version:"0.0.0"})}export{l as createCommandBuffer,C as flush,W as withCommandBuffer};//# sourceMappingURL=commands.js.map
1
+ import {j,v,K,L,x}from'./chunk-2KCN5RVK.js';function l(e){let n={worldId:j(e).id,ops:[],nextPlaceholder:-1,flushing:false};return h(n)}function C(e){let o=y(e);if(!o.flushing){o.flushing=true;try{let n=k(o.worldId),r=new Map;for(let t of o.ops)t.kind==="create"&&r.set(t.placeholder,v(n));let d=t=>{let i=t;if(i<0){let f=r.get(i);if(f===void 0)throw new Error(`aiecsjs: unresolved placeholder ${i}`);return f}return t};for(let t of o.ops)t.kind==="add"?K(n,d(t.eid),t.component,t.initial):t.kind==="remove"&&L(n,d(t.eid),t.component);for(let t of o.ops)t.kind==="destroy"&&x(n,d(t.eid));o.ops.length=0,o.nextPlaceholder=-1;}finally{o.flushing=false;}}}function b(e,o){let n=l(e),r=o(n);return C(n),r}var p=new WeakMap;function h(e){let o={add(n,r,d){e.ops.push({kind:"add",eid:n,component:r,initial:d});},remove(n,r){e.ops.push({kind:"remove",eid:n,component:r});},destroy(n){e.ops.push({kind:"destroy",eid:n});},create(){let n=e.nextPlaceholder--;return e.ops.push({kind:"create",placeholder:n}),n}};return p.set(o,e),o}function y(e){let o=p.get(e);if(!o)throw new Error("aiecsjs: unknown CommandBuffer");return o}function k(e){let o=B(e);return {id:o.id,capacity:o.capacity,version:o.version}}function B(e){return j({id:e,capacity:0,version:"0.0.0"})}export{l as createCommandBuffer,C as flush,b as withCommandBuffer};//# sourceMappingURL=commands.js.map
2
2
  //# sourceMappingURL=commands.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands.ts"],"names":["createCommandBuffer","world","buf","getWorldState","makeApi","flush","cb","state","stateOf","lookupWorld","placeholders","op","createEntity","resolve","eid","num","real","addComponent","removeComponent","destroyEntity","withCommandBuffer","fn","result","cbStateMap","api","component","initial","ph","s","worldId","lookupState"],"mappings":"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","file":"commands.js","sourcesContent":["// aiecsjs/commands — deferred structural mutations during iteration.\n\nimport { addComponent, removeComponent } from './internal/component.js'\nimport { createEntity, destroyEntity } from './internal/entity.js'\nimport type {\n CommandBuffer,\n CommandBufferState,\n CommandOp,\n ComponentInit,\n ComponentLike,\n EntityId,\n World,\n} from './internal/types.js'\nimport { getWorldState } from './internal/world.js'\n\nexport function createCommandBuffer(world: World): CommandBuffer {\n const state = getWorldState(world)\n const buf: CommandBufferState = {\n worldId: state.id,\n ops: [],\n nextPlaceholder: -1,\n flushing: false,\n }\n attachState(buf)\n return makeApi(buf)\n}\n\nexport function flush(cb: CommandBuffer): void {\n const state = stateOf(cb)\n if (state.flushing) return\n state.flushing = true\n try {\n const world = lookupWorld(state.worldId)\n\n // Phase 1: resolve placeholders by creating real entities first\n const placeholders = new Map<number, EntityId>()\n for (const op of state.ops) {\n if (op.kind === 'create') {\n placeholders.set(op.placeholder, createEntity(world))\n }\n }\n\n const resolve = (eid: EntityId): EntityId => {\n const num = eid as number\n if (num < 0) {\n const real = placeholders.get(num)\n if (real === undefined) throw new Error(`aiecsjs: unresolved placeholder ${num}`)\n return real\n }\n return eid\n }\n\n // Phase 2: add/remove in queue order\n for (const op of state.ops) {\n if (op.kind === 'add') {\n addComponent(\n world,\n resolve(op.eid),\n op.component,\n op.initial as ComponentInit<ComponentLike>,\n )\n } else if (op.kind === 'remove') {\n removeComponent(world, resolve(op.eid), op.component)\n }\n }\n\n // Phase 3: destroy last\n for (const op of state.ops) {\n if (op.kind === 'destroy') {\n destroyEntity(world, resolve(op.eid))\n }\n }\n\n state.ops.length = 0\n state.nextPlaceholder = -1\n } finally {\n state.flushing = false\n }\n}\n\nexport function withCommandBuffer<R>(world: World, fn: (cb: CommandBuffer) => R): R {\n const cb = createCommandBuffer(world)\n const result = fn(cb)\n flush(cb)\n return result\n}\n\n// --- Internals ---\n\nconst cbStateMap = new WeakMap<object, CommandBufferState>()\n\nfunction attachState(state: CommandBufferState): void {\n // The CommandBuffer API object is created in makeApi; we link them via WeakMap there.\n void state\n}\n\nfunction makeApi(state: CommandBufferState): CommandBuffer {\n const api: CommandBuffer = {\n add(eid, component, initial) {\n state.ops.push({ kind: 'add', eid, component, initial })\n },\n remove(eid, component) {\n state.ops.push({ kind: 'remove', eid, component })\n },\n destroy(eid) {\n state.ops.push({ kind: 'destroy', eid })\n },\n create() {\n const ph = state.nextPlaceholder--\n state.ops.push({ kind: 'create', placeholder: ph })\n return ph as EntityId\n },\n }\n cbStateMap.set(api, state)\n return api\n}\n\nfunction stateOf(cb: CommandBuffer): CommandBufferState {\n const s = cbStateMap.get(cb)\n if (!s) throw new Error('aiecsjs: unknown CommandBuffer')\n return s\n}\n\n// Look up a public World from its state id. We need a registry — re-import lazily.\nfunction lookupWorld(worldId: number): World {\n // The world registry is in internal/world.ts. We need to construct a public reference.\n // Since destroy clears state, we look up afresh by id via the worldRegistry.\n const state = lookupState(worldId)\n return { id: state.id, capacity: state.capacity, version: state.version } as World\n}\n\nfunction lookupState(worldId: number): import('./internal/types.js').WorldState {\n // Access worldRegistry indirectly via getWorldState requires a World object.\n // Use a small workaround: construct a minimal World-like and call getWorldState.\n return getWorldState({ id: worldId, capacity: 0, version: '0.0.0' } as World)\n}\n"]}
1
+ {"version":3,"sources":["../src/commands.ts"],"names":["createCommandBuffer","world","buf","getWorldState","makeApi","flush","cb","state","stateOf","lookupWorld","placeholders","op","createEntity","resolve","eid","num","real","addComponent","removeComponent","destroyEntity","withCommandBuffer","fn","result","cbStateMap","api","component","initial","ph","s","worldId","lookupState"],"mappings":"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","file":"commands.js","sourcesContent":["// aiecsjs/commands — deferred structural mutations during iteration.\n\nimport { addComponent, removeComponent } from './internal/component.js'\nimport { createEntity, destroyEntity } from './internal/entity.js'\nimport type {\n CommandBuffer,\n CommandBufferState,\n CommandOp,\n ComponentInit,\n ComponentLike,\n EntityId,\n World,\n} from './internal/types.js'\nimport { getWorldState } from './internal/world.js'\n\nexport function createCommandBuffer(world: World): CommandBuffer {\n const state = getWorldState(world)\n const buf: CommandBufferState = {\n worldId: state.id,\n ops: [],\n nextPlaceholder: -1,\n flushing: false,\n }\n return makeApi(buf)\n}\n\nexport function flush(cb: CommandBuffer): void {\n const state = stateOf(cb)\n if (state.flushing) return\n state.flushing = true\n try {\n const world = lookupWorld(state.worldId)\n\n // Phase 1: resolve placeholders by creating real entities first\n const placeholders = new Map<number, EntityId>()\n for (const op of state.ops) {\n if (op.kind === 'create') {\n placeholders.set(op.placeholder, createEntity(world))\n }\n }\n\n const resolve = (eid: EntityId): EntityId => {\n const num = eid as number\n if (num < 0) {\n const real = placeholders.get(num)\n if (real === undefined) throw new Error(`aiecsjs: unresolved placeholder ${num}`)\n return real\n }\n return eid\n }\n\n // Phase 2: add/remove in queue order\n for (const op of state.ops) {\n if (op.kind === 'add') {\n addComponent(\n world,\n resolve(op.eid),\n op.component,\n op.initial as ComponentInit<ComponentLike>,\n )\n } else if (op.kind === 'remove') {\n removeComponent(world, resolve(op.eid), op.component)\n }\n }\n\n // Phase 3: destroy last\n for (const op of state.ops) {\n if (op.kind === 'destroy') {\n destroyEntity(world, resolve(op.eid))\n }\n }\n\n state.ops.length = 0\n state.nextPlaceholder = -1\n } finally {\n state.flushing = false\n }\n}\n\nexport function withCommandBuffer<R>(world: World, fn: (cb: CommandBuffer) => R): R {\n const cb = createCommandBuffer(world)\n const result = fn(cb)\n flush(cb)\n return result\n}\n\n// --- Internals ---\n\nconst cbStateMap = new WeakMap<object, CommandBufferState>()\n\nfunction makeApi(state: CommandBufferState): CommandBuffer {\n const api: CommandBuffer = {\n add(eid, component, initial) {\n state.ops.push({ kind: 'add', eid, component, initial })\n },\n remove(eid, component) {\n state.ops.push({ kind: 'remove', eid, component })\n },\n destroy(eid) {\n state.ops.push({ kind: 'destroy', eid })\n },\n create() {\n const ph = state.nextPlaceholder--\n state.ops.push({ kind: 'create', placeholder: ph })\n return ph as EntityId\n },\n }\n cbStateMap.set(api, state)\n return api\n}\n\nfunction stateOf(cb: CommandBuffer): CommandBufferState {\n const s = cbStateMap.get(cb)\n if (!s) throw new Error('aiecsjs: unknown CommandBuffer')\n return s\n}\n\n// Look up a public World from its state id. We need a registry — re-import lazily.\nfunction lookupWorld(worldId: number): World {\n // The world registry is in internal/world.ts. We need to construct a public reference.\n // Since destroy clears state, we look up afresh by id via the worldRegistry.\n const state = lookupState(worldId)\n return { id: state.id, capacity: state.capacity, version: state.version } as World\n}\n\nfunction lookupState(worldId: number): import('./internal/types.js').WorldState {\n // Access worldRegistry indirectly via getWorldState requires a World object.\n // Use a small workaround: construct a minimal World-like and call getWorldState.\n return getWorldState({ id: worldId, capacity: 0, version: '0.0.0' } as World)\n}\n"]}
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var chunkO5OK5TLX_cjs=require('./chunk-O5OK5TLX.cjs'),chunkM6L4SSE4_cjs=require('./chunk-M6L4SSE4.cjs');var $={i8:"i8",u8:"u8",i16:"i16",u16:"u16",i32:"i32",u32:"u32",f32:"f32",f64:"f64",eid:"eid",bool:"bool"};function J(...n){return n.length===0?e=>e:n.length===1?n[0]:(e,r)=>{let t=e;for(let o of n)t=o(t,r);return t}}var i=class extends Error{eid;constructor(e){super(`aiecsjs: entity ${e} is not alive`),this.name="EntityNotAliveError",this.eid=e;}};function X(n,e){let r=chunkM6L4SSE4_cjs.i(n);if(!chunkM6L4SSE4_cjs.y(r,e))throw new i(e);return Object.freeze({id:e,worldId:r.id})}function b(n,e){let r=chunkM6L4SSE4_cjs.i(n);if(e.worldId!==r.id)return null;let t=e.id,o=chunkM6L4SSE4_cjs.s(t,r.options);if(o<=0||o>=r.capacity)return null;let x=r.entityArchetype[o]??0,d=r.archetypes[x];if(!d||!d.entityRow.has(e.id))return null;let C=r.generations[o]??0,A=chunkM6L4SSE4_cjs.t(t,r.options);return C!==A?null:e.id}function Y(n,e){return b(n,e)!==null}chunkO5OK5TLX_cjs.j(n=>chunkM6L4SSE4_cjs.Q(n));chunkM6L4SSE4_cjs.O((n,e,r,t,o)=>{chunkO5OK5TLX_cjs.i(n,e,r,t,o);});var de=typeof SharedArrayBuffer<"u";Object.defineProperty(exports,"defineQuery",{enumerable:true,get:function(){return chunkO5OK5TLX_cjs.a}});Object.defineProperty(exports,"enterQuery",{enumerable:true,get:function(){return chunkO5OK5TLX_cjs.b}});Object.defineProperty(exports,"exitQuery",{enumerable:true,get:function(){return chunkO5OK5TLX_cjs.c}});Object.defineProperty(exports,"forEachEntity",{enumerable:true,get:function(){return chunkO5OK5TLX_cjs.g}});Object.defineProperty(exports,"forEachEntityIndexed",{enumerable:true,get:function(){return chunkO5OK5TLX_cjs.h}});Object.defineProperty(exports,"iterQuery",{enumerable:true,get:function(){return chunkO5OK5TLX_cjs.f}});Object.defineProperty(exports,"queryArchetypes",{enumerable:true,get:function(){return chunkO5OK5TLX_cjs.d}});Object.defineProperty(exports,"runQuery",{enumerable:true,get:function(){return chunkO5OK5TLX_cjs.e}});Object.defineProperty(exports,"VERSION",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.a}});Object.defineProperty(exports,"addComponent",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.J}});Object.defineProperty(exports,"createEntity",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.u}});Object.defineProperty(exports,"createWorld",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.k}});Object.defineProperty(exports,"defineComponent",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.F}});Object.defineProperty(exports,"defineObjectComponent",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.H}});Object.defineProperty(exports,"defineTag",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.G}});Object.defineProperty(exports,"destroyEntity",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.w}});Object.defineProperty(exports,"destroyWorld",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.l}});Object.defineProperty(exports,"disposeWorld",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.l}});Object.defineProperty(exports,"entityExists",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.x}});Object.defineProperty(exports,"getComponent",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.M}});Object.defineProperty(exports,"getEntityGeneration",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.A}});Object.defineProperty(exports,"getEntityIndex",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.z}});Object.defineProperty(exports,"getWorldCapacity",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.o}});Object.defineProperty(exports,"getWorldSize",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.n}});Object.defineProperty(exports,"hasComponent",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.L}});Object.defineProperty(exports,"isEntity",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.C}});Object.defineProperty(exports,"isWorld",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.q}});Object.defineProperty(exports,"packEntity",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.B}});Object.defineProperty(exports,"removeComponent",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.K}});Object.defineProperty(exports,"resetWorld",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.m}});Object.defineProperty(exports,"setComponent",{enumerable:true,get:function(){return chunkM6L4SSE4_cjs.N}});exports.EntityNotAliveError=i;exports.IS_SAB_SUPPORTED=de;exports.Types=$;exports.aliveRef=Y;exports.deref=b;exports.pipe=J;exports.refOf=X;//# sourceMappingURL=index.cjs.map
1
+ 'use strict';var chunkSRX2MZPX_cjs=require('./chunk-SRX2MZPX.cjs'),chunk5QWEV4VJ_cjs=require('./chunk-5QWEV4VJ.cjs');var J={i8:"i8",u8:"u8",i16:"i16",u16:"u16",i32:"i32",u32:"u32",f32:"f32",f64:"f64",eid:"eid",bool:"bool"};function X(...n){return n.length===0?e=>e:n.length===1?n[0]:(e,r)=>{let t=e;for(let o of n)t=o(t,r);return t}}var i=class extends Error{eid;constructor(e){super(`aiecsjs: entity ${e} is not alive`),this.name="EntityNotAliveError",this.eid=e;}};function Y(n,e){let r=chunk5QWEV4VJ_cjs.j(n);if(!chunk5QWEV4VJ_cjs.z(r,e))throw new i(e);return Object.freeze({id:e,worldId:r.id})}function b(n,e){let r=chunk5QWEV4VJ_cjs.j(n);if(e.worldId!==r.id)return null;let t=e.id,o=chunk5QWEV4VJ_cjs.t(t,r.options);if(o<=0||o>=r.capacity)return null;let x=r.entityArchetype[o]??0,d=r.archetypes[x];if(!d||!d.entityRow.has(e.id))return null;let C=r.generations[o]??0,A=chunk5QWEV4VJ_cjs.u(t,r.options);return C!==A?null:e.id}function Z(n,e){return b(n,e)!==null}chunkSRX2MZPX_cjs.j(n=>chunk5QWEV4VJ_cjs.R(n));chunk5QWEV4VJ_cjs.P((n,e,r,t,o)=>{chunkSRX2MZPX_cjs.i(n,e,r,t,o);});var pe=typeof SharedArrayBuffer<"u";Object.defineProperty(exports,"defineQuery",{enumerable:true,get:function(){return chunkSRX2MZPX_cjs.a}});Object.defineProperty(exports,"enterQuery",{enumerable:true,get:function(){return chunkSRX2MZPX_cjs.b}});Object.defineProperty(exports,"exitQuery",{enumerable:true,get:function(){return chunkSRX2MZPX_cjs.c}});Object.defineProperty(exports,"forEachEntity",{enumerable:true,get:function(){return chunkSRX2MZPX_cjs.g}});Object.defineProperty(exports,"forEachEntityIndexed",{enumerable:true,get:function(){return chunkSRX2MZPX_cjs.h}});Object.defineProperty(exports,"iterQuery",{enumerable:true,get:function(){return chunkSRX2MZPX_cjs.f}});Object.defineProperty(exports,"queryArchetypes",{enumerable:true,get:function(){return chunkSRX2MZPX_cjs.d}});Object.defineProperty(exports,"runQuery",{enumerable:true,get:function(){return chunkSRX2MZPX_cjs.e}});Object.defineProperty(exports,"EcsError",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.i}});Object.defineProperty(exports,"VERSION",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.a}});Object.defineProperty(exports,"addComponent",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.K}});Object.defineProperty(exports,"createEntity",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.v}});Object.defineProperty(exports,"createWorld",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.l}});Object.defineProperty(exports,"defineComponent",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.G}});Object.defineProperty(exports,"defineObjectComponent",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.I}});Object.defineProperty(exports,"defineTag",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.H}});Object.defineProperty(exports,"destroyEntity",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.x}});Object.defineProperty(exports,"destroyWorld",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.m}});Object.defineProperty(exports,"disposeWorld",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.m}});Object.defineProperty(exports,"entityExists",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.y}});Object.defineProperty(exports,"getComponent",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.N}});Object.defineProperty(exports,"getEntityGeneration",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.B}});Object.defineProperty(exports,"getEntityIndex",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.A}});Object.defineProperty(exports,"getWorldCapacity",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.p}});Object.defineProperty(exports,"getWorldSize",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.o}});Object.defineProperty(exports,"hasComponent",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.M}});Object.defineProperty(exports,"isEntity",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.D}});Object.defineProperty(exports,"isWorld",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.r}});Object.defineProperty(exports,"packEntity",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.C}});Object.defineProperty(exports,"removeComponent",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.L}});Object.defineProperty(exports,"resetWorld",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.n}});Object.defineProperty(exports,"setComponent",{enumerable:true,get:function(){return chunk5QWEV4VJ_cjs.O}});exports.EntityNotAliveError=i;exports.IS_SAB_SUPPORTED=pe;exports.Types=J;exports.aliveRef=Z;exports.deref=b;exports.pipe=X;exports.refOf=Y;//# sourceMappingURL=index.cjs.map
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/internal/types.ts","../src/internal/pipe.ts","../src/ref.ts","../src/index.ts"],"names":["Types","pipe","systems","w","world","ctx","s","EntityNotAliveError","eid","refOf","entity","state","getWorldState","isAliveInternal","deref","ref","idx","unpackIdx","archId","arch","storedGen","refGen","unpackGen","aliveRef","registerComponentLookup","id","getComponentByInternalId","registerMaskChangeDispatch","bit","prev","next","recordEntityMaskChange","IS_SAB_SUPPORTED"],"mappings":"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","file":"index.cjs","sourcesContent":["// Shared type definitions for aiecsjs internals.\n// Public-facing types are re-exported from src/index.ts.\n\nexport type EntityId = number & { readonly __brand: 'EntityId' }\n\nexport const Types = {\n i8: 'i8',\n u8: 'u8',\n i16: 'i16',\n u16: 'u16',\n i32: 'i32',\n u32: 'u32',\n f32: 'f32',\n f64: 'f64',\n eid: 'eid',\n bool: 'bool',\n} as const\n\nexport type SoAFieldType =\n | 'i8'\n | 'u8'\n | 'i16'\n | 'u16'\n | 'i32'\n | 'u32'\n | 'f32'\n | 'f64'\n | 'eid'\n | 'bool'\n\nexport type SoAFieldDecl = SoAFieldType | readonly [SoAFieldType, number]\nexport type SoASchema = Readonly<Record<string, SoAFieldDecl>>\n\nexport interface SoAComponent<S extends SoASchema = SoASchema> {\n readonly __kind: 'soa'\n readonly __id: number\n readonly __schema: S\n}\n\nexport interface AoSComponent<T = unknown> {\n readonly __kind: 'aos'\n readonly __id: number\n readonly __factory: () => T\n}\n\nexport interface TagComponent {\n readonly __kind: 'tag'\n readonly __id: number\n}\n\nexport type ComponentLike = SoAComponent<any> | AoSComponent<any> | TagComponent\n\nexport type ColumnArray =\n | Int8Array\n | Uint8Array\n | Int16Array\n | Uint16Array\n | Int32Array\n | Uint32Array\n | Float32Array\n | Float64Array\n\nexport interface SoAColumns {\n [field: string]: ColumnArray\n}\n\nexport type ComponentView<C extends ComponentLike> = C extends SoAComponent<infer _S>\n ? SoAColumns\n : C extends AoSComponent<infer T>\n ? T | undefined\n : C extends TagComponent\n ? boolean\n : never\n\nexport type ComponentInit<C extends ComponentLike> = C extends SoAComponent<infer _S>\n ? Record<string, unknown>\n : C extends AoSComponent<infer T>\n ? Partial<T>\n : undefined\n\nexport interface QueryDescriptor {\n all?: ComponentLike[]\n any?: ComponentLike[]\n none?: ComponentLike[]\n}\n\nexport interface Query {\n readonly id: number\n readonly mask: ReadonlyArray<number>\n}\n\nexport interface Archetype {\n readonly id: number\n readonly mask: ReadonlyArray<number>\n readonly size: number\n}\n\nexport interface WorldOptions {\n initialCapacity?: number\n maxEntities?: number\n indexBits?: number\n generationBits?: number\n buffer?: SharedArrayBuffer\n bufferByteOffset?: number\n}\n\nexport interface World {\n readonly id: number\n readonly capacity: number\n readonly version: string\n}\n\nexport type System<W extends World = World, Ctx = unknown> = (world: W, ctx: Ctx) => W\n\n// --- Internal-only types ---\n\nexport interface ResolvedWorldOptions {\n initialCapacity: number\n maxEntities: number\n indexBits: number\n generationBits: number\n indexMask: number\n generationMask: number\n maxComponents: number\n maskWordCount: number\n buffer: SharedArrayBuffer | null\n bufferByteOffset: number\n}\n\nexport interface FieldInfo {\n name: string\n type: SoAFieldType\n vectorLen: number // 1 for scalar\n ctor: TypedArrayConstructor\n bytesPerElement: number\n}\n\nexport type TypedArrayConstructor =\n | Int8ArrayConstructor\n | Uint8ArrayConstructor\n | Int16ArrayConstructor\n | Uint16ArrayConstructor\n | Int32ArrayConstructor\n | Uint32ArrayConstructor\n | Float32ArrayConstructor\n | Float64ArrayConstructor\n\nexport interface ComponentInfo {\n id: number\n kind: 'soa' | 'aos' | 'tag'\n schema: SoASchema | null\n fields: FieldInfo[]\n factory: (() => unknown) | null\n}\n\nexport interface WorldComponentStorage {\n // For each component bit in this world: storage backed by a column map (SoA), object array (AoS), or null (tag)\n kind: 'soa' | 'aos' | 'tag'\n componentId: number\n bit: number\n // SoA: field name → TypedArray of size `worldCapacity`\n soa?: SoAColumns\n // AoS: per-entity object array, sparse, indexed by eid; undefined for unowned\n aos?: (unknown | undefined)[]\n}\n\nexport interface ArchetypeState {\n id: number\n mask: Uint32Array\n size: number\n capacity: number\n entities: Uint32Array // packed eids in row order\n entityRow: Map<number, number> // eid → row (small archetype-local lookup)\n componentBits: number[] // sorted\n edgeAdd: Int32Array // [bit] → archetype id; -1 unknown\n edgeRemove: Int32Array // [bit] → archetype id; -1 unknown\n}\n\nexport interface QueryInternal extends Query {\n id: number\n all: number[]\n any: number[]\n none: number[]\n // Cache of column references per matched archetype (per query-call)\n columnViewCache: ComponentLike[] // the requested components in their declared order\n reactiveKind: 'normal' | 'enter' | 'exit'\n sourceQueryId: number // -1 for normal\n sourceQuery: QueryInternal | null // back-ref for reactive registration\n}\n\n// Per-world resolved bitmasks for a query. Component bits are assigned per\n// world, so the masks must live in WorldState — keeping them on the shared\n// QueryInternal would silently cross-contaminate worlds whose component\n// registration order differs.\nexport interface QueryMaskBundle {\n withMask: Uint32Array\n anyMask: Uint32Array\n noneMask: Uint32Array\n anyHasBits: boolean\n}\n\nexport interface ReactiveBuffer {\n entered: number[]\n exited: number[]\n}\n\nexport type ObserverEvent = 'add' | 'remove' | 'set'\n\nexport interface ObserverEntry {\n event: ObserverEvent\n componentBit: number // -1 means \"any component\" (used by query observe)\n queryId: number // -1 means component-only\n handler: (eid: EntityId, value?: unknown) => void\n}\n\nexport interface CommandBufferState {\n worldId: number\n ops: CommandOp[]\n nextPlaceholder: number\n flushing: boolean\n}\n\nexport type CommandOp =\n | { kind: 'create'; placeholder: number }\n | { kind: 'add'; eid: EntityId; component: ComponentLike; initial?: unknown }\n | { kind: 'remove'; eid: EntityId; component: ComponentLike }\n | { kind: 'destroy'; eid: EntityId }\n\nexport interface CommandBuffer {\n add<C extends ComponentLike>(eid: EntityId, component: C, initial?: ComponentInit<C>): void\n remove<C extends ComponentLike>(eid: EntityId, component: C): void\n destroy(eid: EntityId): void\n create(): EntityId\n}\n\nexport interface WorldMeta {\n magic: number\n formatVersion: number\n aiecsjsVersion: string\n indexBits: number\n generationBits: number\n maxComponents: number\n maskWordCount: number\n capacity: number\n componentSchemas: Array<{ id: number; kind: 'soa' | 'aos' | 'tag'; schema: SoASchema | null }>\n}\n\nexport interface TransferableSnapshot {\n buffer: SharedArrayBuffer\n meta: WorldMeta\n}\n\nexport interface SerializeOptions {\n components?: ComponentLike[]\n}\n\nexport interface DeserializeOptions {\n components?: ComponentLike[]\n onUnknownVersion?: 'throw' | 'best-effort'\n}\n\nexport interface WorldSnapshot {\n version: string\n capacity: number\n entities: Array<{\n eid: number\n components: Array<{\n kind: 'soa' | 'aos' | 'tag'\n id: number\n data: unknown\n }>\n }>\n}\n\nexport interface DeltaSerializer {\n capture(): Uint8Array\n apply(world: World, delta: Uint8Array): void\n reset(): void\n}\n\nexport interface Relation<T = void> {\n readonly __kind: 'relation'\n readonly __id: number\n readonly __exclusive: boolean\n readonly __hasData: boolean\n}\n\nexport interface RelationStorage {\n rel: Relation<any>\n exclusive: Int32Array | null // [srcEid] → tgtEid; -1 means none\n outgoing: Map<number, number[]> // srcEid → tgtEid[]\n data: Map<number, Map<number, unknown>> // srcEid → (tgtEid → data); nested to stay correct across capacity growth\n}\n\nexport interface WorldState {\n // --- public view ---\n readonly id: number\n capacity: number\n readonly version: string\n\n // --- options ---\n options: ResolvedWorldOptions\n\n // --- entity allocation ---\n size: number // alive count\n nextFreshIndex: number // never-used index\n freeList: number[] // recycled indices\n generations: Uint8Array | Uint16Array // [eid] → version\n destroyed: boolean\n\n // --- component registry (per-world) ---\n componentBitFor: Map<number, number> // global component id → bit pos in this world\n componentInfoByBit: (ComponentInfo | null)[] // bit pos → ComponentInfo\n componentStorageByBit: (WorldComponentStorage | null)[]\n nextComponentBit: number\n\n // --- sparse entity state ---\n entityArchetype: Uint32Array // [eid] → archetype id (0 = unattached)\n // entityMask flattened: word w of mask of eid is at entityMask[eid * maskWordCount + w]\n entityMask: Uint32Array\n\n // --- archetype registry ---\n archetypes: ArchetypeState[]\n archetypeByMaskHash: Map<string, number>\n queryVersion: number\n\n // --- query cache ---\n queries: QueryInternal[] // by id\n queryMasks: Map<number, QueryMaskBundle> // queryId → per-world resolved bitmasks\n queryArchetypeCache: (number[] | null)[]\n queryArchetypeStamp: number[]\n bitToQueries: Map<number, Set<number>> // bit → queryIds that mention this bit\n\n // --- reactive query state ---\n reactiveBuffers: Map<number, ReactiveBuffer> // queryId → { entered, exited }\n\n // --- observers ---\n observers: ObserverEntry[]\n\n // --- relations ---\n relationStorage: Map<number, RelationStorage> // relation id → storage\n\n // --- worker / SAB ---\n sab: SharedArrayBuffer | null\n readOnly: boolean\n}\n","import type { System, World } from './types.js'\n\nexport function pipe<W extends World = World, Ctx = unknown>(\n ...systems: System<W, Ctx>[]\n): System<W, Ctx> {\n if (systems.length === 0) return (w: W) => w\n if (systems.length === 1) return systems[0]!\n return (world: W, ctx: Ctx) => {\n let w = world\n for (const s of systems) w = s(w, ctx)\n return w\n }\n}\n","// aiecsjs/ref — ABA-safe entity references.\n//\n// EntityRef<T> wraps a packed EntityId with a world identity check so that\n// stale references (pointing at a recycled slot with a different generation)\n// safely return null rather than silently accessing the wrong entity.\n//\n// EntityRef is in-memory only. Do not pass across worker boundaries or persist\n// to disk. The packed id field has meaning only within the world that issued it.\n// Generation counters reset on resetWorld / deserializeWorld / adoptSnapshot.\n\nimport { isAliveInternal, unpackGen, unpackIdx } from './internal/entity.js'\nimport type { EntityId, World } from './internal/types.js'\nimport { getWorldState } from './internal/world.js'\n\n/**\n * ABA-safe entity reference.\n *\n * Holds the packed EntityId and the id of the world that issued it.\n * Use `deref(world, ref)` to validate and retrieve the live entity id.\n *\n * The phantom type `T` allows callers to distinguish reference kinds at the\n * type system level — e.g. `EntityRef<'bullet'>` vs `EntityRef<'player'>` —\n * without any runtime overhead.\n *\n * @example\n * const ref = refOf<'bullet'>(world, e)\n * // later, in a system:\n * const live = deref(world, ref)\n * if (live !== null) {\n * // entity is still alive with the same generation\n * }\n */\nexport interface EntityRef<T = unknown> {\n readonly id: EntityId // packed value (index + generation)\n readonly worldId: number // world.id — guards against cross-world deref\n readonly __phantom?: T // phantom type tag; zero runtime size\n}\n\n/**\n * Thrown by `refOf` when the entity is not alive.\n * `deref` and `aliveRef` never throw — they return null/false.\n */\nexport class EntityNotAliveError extends Error {\n readonly eid: number\n constructor(eid: number) {\n super(`aiecsjs: entity ${eid} is not alive`)\n this.name = 'EntityNotAliveError'\n this.eid = eid\n }\n}\n\n/**\n * Create an ABA-safe reference to a live entity.\n *\n * @throws {EntityNotAliveError} if the entity is not alive (dead, never created, or eid === 0).\n *\n * The returned object is frozen. `id` is the packed EntityId; `worldId` is\n * the world's numeric id used by `deref` to reject cross-world lookups.\n *\n * The function may be called on the hot path — each call returns a new object\n * but performs no allocation beyond that.\n */\nexport function refOf<T = unknown>(world: World, entity: EntityId): EntityRef<T> {\n const state = getWorldState(world)\n if (!isAliveInternal(state, entity as number)) {\n throw new EntityNotAliveError(entity as number)\n }\n return Object.freeze({ id: entity, worldId: state.id }) as EntityRef<T>\n}\n\n/**\n * Resolve a ref to its live EntityId, or return null if stale.\n *\n * Returns null when any of the following hold:\n * 1. `ref.worldId !== state.id` — cross-world ref\n * 2. `getEntityIndex(ref.id) >= state.capacity` — index out-of-bounds\n * 3. `getEntityIndex(ref.id) === 0` — sentinel slot\n * 4. entity is not in any archetype's entityRow (slot released)\n * 5. generation mismatch → ABA: old ref points at recycled slot\n *\n * Never throws.\n */\nexport function deref<T = unknown>(world: World, ref: EntityRef<T>): EntityId | null {\n const state = getWorldState(world)\n\n // Cross-world guard\n if (ref.worldId !== state.id) return null\n\n const eid = ref.id as number\n const idx = unpackIdx(eid, state.options)\n\n // Sentinel and OOB guards\n if (idx <= 0) return null\n if (idx >= state.capacity) return null\n\n // Archetype membership check\n const archId = state.entityArchetype[idx] ?? 0\n const arch = state.archetypes[archId]\n if (!arch) return null\n if (!arch.entityRow.has(ref.id)) return null\n\n // Generation match — the core ABA protection\n const storedGen = state.generations[idx] ?? 0\n const refGen = unpackGen(eid, state.options)\n if (storedGen !== refGen) return null\n\n return ref.id\n}\n\n/**\n * Boolean guard form of `deref`. Equivalent to `deref(world, ref) !== null`.\n * Use in guard clauses when you do not need the resolved EntityId.\n *\n * Never throws.\n */\nexport function aliveRef<T = unknown>(world: World, ref: EntityRef<T>): boolean {\n return deref(world, ref) !== null\n}\n","// aiecsjs — public root entry.\n// Re-exports the core API and wires up the lazy cross-module references.\n\nexport { VERSION } from './version.js'\n\nimport {\n getComponentByInternalId,\n registerMaskChangeDispatch,\n registerObserverDispatch,\n} from './internal/component.js'\nimport { registerObserversAPI, registerRelationsCleanup } from './internal/entity.js'\nimport { recordEntityMaskChange, registerComponentLookup } from './internal/query.js'\nimport type { EntityId, WorldState } from './internal/types.js'\n\n// Wire query → component lookup\nregisterComponentLookup((id) => getComponentByInternalId(id))\n\n// Wire component mask-change → query reactive update\nregisterMaskChangeDispatch((state, eid, bit, prev, next) => {\n recordEntityMaskChange(state, eid, bit, prev, next)\n})\n\n// Observer dispatch is registered lazily by observers.ts on first import.\n// Relations cleanup is registered lazily by relations.ts on first import.\n\n// --- Type re-exports ---\nexport type {\n EntityId,\n World,\n WorldOptions,\n System,\n SoAComponent,\n AoSComponent,\n TagComponent,\n ComponentLike,\n ComponentInit,\n ComponentView,\n SoAColumns,\n SoASchema,\n SoAFieldType,\n SoAFieldDecl,\n Query,\n QueryDescriptor,\n Archetype,\n} from './internal/types.js'\n\n// --- World ---\nexport {\n createWorld,\n destroyWorld,\n resetWorld,\n getWorldSize,\n getWorldCapacity,\n isWorld,\n} from './internal/world.js'\n\n// `disposeWorld` is the new preferred name (added 0.2.0). It is the same\n// function as `destroyWorld`, exported under a name that aligns with the ai*js\n// ecosystem `dispose()` convention (aifsmjs Runtime, aibridgejs Bridge).\n//\n// `destroyWorld` is the original 0.1.x export. It is now deprecated as of 0.2.0\n// and is scheduled for removal in 1.0. New code should import `disposeWorld`.\nexport { destroyWorld as disposeWorld } from './internal/world.js'\n\n// --- Entity ---\nexport {\n createEntity,\n destroyEntity,\n entityExists,\n getEntityIndex,\n getEntityGeneration,\n packEntity,\n isEntity,\n} from './internal/entity.js'\n\n// --- Component ---\nexport {\n defineComponent,\n defineTag,\n defineObjectComponent,\n addComponent,\n removeComponent,\n hasComponent,\n getComponent,\n setComponent,\n} from './internal/component.js'\n\nexport { Types } from './internal/types.js'\n\n// --- Query ---\nexport {\n defineQuery,\n runQuery,\n iterQuery,\n forEachEntity,\n forEachEntityIndexed,\n enterQuery,\n exitQuery,\n queryArchetypes,\n} from './internal/query.js'\n\n// --- System ---\nexport { pipe } from './internal/pipe.js'\n\n// --- Utility ---\nexport const IS_SAB_SUPPORTED: boolean = typeof SharedArrayBuffer !== 'undefined'\n\n// --- EntityRef (ABA-safe references) ---\nexport type { EntityRef } from './ref.js'\nexport { refOf, deref, aliveRef, EntityNotAliveError } from './ref.js'\n"]}
1
+ {"version":3,"sources":["../src/internal/types.ts","../src/internal/pipe.ts","../src/ref.ts","../src/index.ts"],"names":["Types","pipe","systems","w","world","ctx","s","EntityNotAliveError","eid","refOf","entity","state","getWorldState","isAliveInternal","deref","ref","idx","unpackIdx","archId","arch","storedGen","refGen","unpackGen","aliveRef","registerComponentLookup","id","getComponentByInternalId","registerMaskChangeDispatch","bit","prev","next","recordEntityMaskChange","IS_SAB_SUPPORTED"],"mappings":"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","file":"index.cjs","sourcesContent":["// Shared type definitions for aiecsjs internals.\n// Public-facing types are re-exported from src/index.ts.\n\nexport type EntityId = number & { readonly __brand: 'EntityId' }\n\nexport const Types = {\n i8: 'i8',\n u8: 'u8',\n i16: 'i16',\n u16: 'u16',\n i32: 'i32',\n u32: 'u32',\n f32: 'f32',\n f64: 'f64',\n eid: 'eid',\n bool: 'bool',\n} as const\n\nexport type SoAFieldType =\n | 'i8'\n | 'u8'\n | 'i16'\n | 'u16'\n | 'i32'\n | 'u32'\n | 'f32'\n | 'f64'\n | 'eid'\n | 'bool'\n\nexport type SoAFieldDecl = SoAFieldType | readonly [SoAFieldType, number]\nexport type SoASchema = Readonly<Record<string, SoAFieldDecl>>\n\nexport interface SoAComponent<S extends SoASchema = SoASchema> {\n readonly __kind: 'soa'\n readonly __id: number\n readonly __schema: S\n}\n\nexport interface AoSComponent<T = unknown> {\n readonly __kind: 'aos'\n readonly __id: number\n readonly __factory: () => T\n}\n\nexport interface TagComponent {\n readonly __kind: 'tag'\n readonly __id: number\n}\n\nexport type ComponentLike = SoAComponent<any> | AoSComponent<any> | TagComponent\n\nexport type ColumnArray =\n | Int8Array\n | Uint8Array\n | Int16Array\n | Uint16Array\n | Int32Array\n | Uint32Array\n | Float32Array\n | Float64Array\n\nexport interface SoAColumns {\n [field: string]: ColumnArray\n}\n\nexport type ComponentView<C extends ComponentLike> = C extends SoAComponent<infer _S>\n ? SoAColumns\n : C extends AoSComponent<infer T>\n ? T | undefined\n : C extends TagComponent\n ? boolean\n : never\n\nexport type ComponentInit<C extends ComponentLike> = C extends SoAComponent<infer _S>\n ? Record<string, unknown>\n : C extends AoSComponent<infer T>\n ? Partial<T>\n : undefined\n\nexport interface QueryDescriptor {\n all?: ComponentLike[]\n any?: ComponentLike[]\n none?: ComponentLike[]\n}\n\nexport interface Query {\n readonly id: number\n readonly mask: ReadonlyArray<number>\n}\n\nexport interface Archetype {\n readonly id: number\n readonly mask: ReadonlyArray<number>\n readonly size: number\n}\n\nexport interface WorldOptions {\n initialCapacity?: number\n maxEntities?: number\n indexBits?: number\n generationBits?: number\n /**\n * RESERVED / UNIMPLEMENTED (0.x). Setting this has **no effect** today: the\n * world always allocates its own column storage and never reads or writes a\n * caller-supplied SAB. The 0.x Worker handoff is a snapshot-copy transport —\n * post `transferableSnapshot(world)` and rebuild via `adoptSnapshot` from\n * `aiecsjs/worker`; do not pre-allocate a SAB here. The field is kept so the\n * shape is forward-compatible with the true shared-column backing targeted\n * for 0.3+ (see STABILITY.md, `aiecsjs/worker`).\n */\n buffer?: SharedArrayBuffer\n /** RESERVED / UNIMPLEMENTED (0.x). Paired with {@link WorldOptions.buffer}; no effect today. */\n bufferByteOffset?: number\n}\n\nexport interface World {\n readonly id: number\n readonly capacity: number\n readonly version: string\n}\n\nexport type System<W extends World = World, Ctx = unknown> = (world: W, ctx: Ctx) => W\n\n// --- Internal-only types ---\n\nexport interface ResolvedWorldOptions {\n initialCapacity: number\n maxEntities: number\n indexBits: number\n generationBits: number\n indexMask: number\n generationMask: number\n maxComponents: number\n maskWordCount: number\n buffer: SharedArrayBuffer | null\n bufferByteOffset: number\n}\n\nexport interface FieldInfo {\n name: string\n type: SoAFieldType\n vectorLen: number // 1 for scalar\n ctor: TypedArrayConstructor\n bytesPerElement: number\n}\n\nexport type TypedArrayConstructor =\n | Int8ArrayConstructor\n | Uint8ArrayConstructor\n | Int16ArrayConstructor\n | Uint16ArrayConstructor\n | Int32ArrayConstructor\n | Uint32ArrayConstructor\n | Float32ArrayConstructor\n | Float64ArrayConstructor\n\nexport interface ComponentInfo {\n id: number\n kind: 'soa' | 'aos' | 'tag'\n schema: SoASchema | null\n fields: FieldInfo[]\n factory: (() => unknown) | null\n}\n\nexport interface WorldComponentStorage {\n // For each component bit in this world: storage backed by a column map (SoA), object array (AoS), or null (tag)\n kind: 'soa' | 'aos' | 'tag'\n componentId: number\n bit: number\n // SoA: field name → TypedArray of size `worldCapacity`\n soa?: SoAColumns\n // AoS: per-entity object array, sparse, indexed by eid; undefined for unowned\n aos?: (unknown | undefined)[]\n}\n\nexport interface ArchetypeState {\n id: number\n mask: Uint32Array\n size: number\n capacity: number\n entities: Uint32Array // packed eids in row order\n entityRow: Map<number, number> // eid → row (small archetype-local lookup)\n componentBits: number[] // sorted\n edgeAdd: Int32Array // [bit] → archetype id; -1 unknown\n edgeRemove: Int32Array // [bit] → archetype id; -1 unknown\n}\n\nexport interface QueryInternal extends Query {\n id: number\n all: number[]\n any: number[]\n none: number[]\n // Cache of column references per matched archetype (per query-call)\n columnViewCache: ComponentLike[] // the requested components in their declared order\n reactiveKind: 'normal' | 'enter' | 'exit'\n sourceQueryId: number // -1 for normal\n sourceQuery: QueryInternal | null // back-ref for reactive registration\n}\n\n// Per-world resolved bitmasks for a query. Component bits are assigned per\n// world, so the masks must live in WorldState — keeping them on the shared\n// QueryInternal would silently cross-contaminate worlds whose component\n// registration order differs.\nexport interface QueryMaskBundle {\n withMask: Uint32Array\n anyMask: Uint32Array\n noneMask: Uint32Array\n anyHasBits: boolean\n}\n\nexport interface ReactiveBuffer {\n entered: number[]\n exited: number[]\n}\n\nexport type ObserverEvent = 'add' | 'remove' | 'set'\n\nexport interface ObserverEntry {\n event: ObserverEvent\n componentBit: number // -1 means \"any component\" (used by query observe)\n queryId: number // -1 means component-only\n handler: (eid: EntityId, value?: unknown) => void\n}\n\nexport interface CommandBufferState {\n worldId: number\n ops: CommandOp[]\n nextPlaceholder: number\n flushing: boolean\n}\n\nexport type CommandOp =\n | { kind: 'create'; placeholder: number }\n | { kind: 'add'; eid: EntityId; component: ComponentLike; initial?: unknown }\n | { kind: 'remove'; eid: EntityId; component: ComponentLike }\n | { kind: 'destroy'; eid: EntityId }\n\nexport interface CommandBuffer {\n add<C extends ComponentLike>(eid: EntityId, component: C, initial?: ComponentInit<C>): void\n remove<C extends ComponentLike>(eid: EntityId, component: C): void\n destroy(eid: EntityId): void\n create(): EntityId\n}\n\nexport interface WorldMeta {\n magic: number\n formatVersion: number\n aiecsjsVersion: string\n indexBits: number\n generationBits: number\n maxComponents: number\n maskWordCount: number\n capacity: number\n componentSchemas: Array<{ id: number; kind: 'soa' | 'aos' | 'tag'; schema: SoASchema | null }>\n}\n\nexport interface TransferableSnapshot {\n // Union, not bare SharedArrayBuffer: in a non-cross-origin-isolated environment\n // `SharedArrayBuffer` is undefined, so transferableSnapshot falls back to a\n // plain ArrayBuffer (worker.ts). Declaring the honest union lets consumers\n // branch on `instanceof SharedArrayBuffer` instead of trusting a type that\n // would otherwise lie. Experimental subpath — the union is allowed to land in 0.x.\n buffer: SharedArrayBuffer | ArrayBuffer\n meta: WorldMeta\n}\n\nexport interface SerializeOptions {\n components?: ComponentLike[]\n}\n\nexport interface DeserializeOptions {\n components?: ComponentLike[]\n onUnknownVersion?: 'throw' | 'best-effort'\n}\n\nexport interface WorldSnapshot {\n version: string\n capacity: number\n entities: Array<{\n eid: number\n components: Array<{\n kind: 'soa' | 'aos' | 'tag'\n id: number\n data: unknown\n }>\n }>\n}\n\nexport interface DeltaSerializer {\n capture(): Uint8Array\n apply(world: World, delta: Uint8Array): void\n reset(): void\n}\n\nexport interface Relation<T = void> {\n readonly __kind: 'relation'\n readonly __id: number\n readonly __exclusive: boolean\n readonly __hasData: boolean\n}\n\nexport interface RelationStorage {\n rel: Relation<any>\n exclusive: Int32Array | null // [srcEid] → tgtEid; -1 means none\n outgoing: Map<number, number[]> // srcEid → tgtEid[]\n data: Map<number, Map<number, unknown>> // srcEid → (tgtEid → data); nested to stay correct across capacity growth\n}\n\nexport interface WorldState {\n // --- public view ---\n readonly id: number\n capacity: number\n readonly version: string\n\n // --- options ---\n options: ResolvedWorldOptions\n\n // --- entity allocation ---\n size: number // alive count\n nextFreshIndex: number // never-used index\n freeList: number[] // recycled indices\n generations: Uint8Array | Uint16Array // [eid] → version\n destroyed: boolean\n\n // --- component registry (per-world) ---\n componentBitFor: Map<number, number> // global component id → bit pos in this world\n componentInfoByBit: (ComponentInfo | null)[] // bit pos → ComponentInfo\n componentStorageByBit: (WorldComponentStorage | null)[]\n nextComponentBit: number\n\n // --- sparse entity state ---\n entityArchetype: Uint32Array // [eid] → archetype id (0 = unattached)\n // entityMask flattened: word w of mask of eid is at entityMask[eid * maskWordCount + w]\n entityMask: Uint32Array\n\n // --- archetype registry ---\n archetypes: ArchetypeState[]\n archetypeByMaskHash: Map<string, number>\n queryVersion: number\n\n // --- query cache ---\n queries: QueryInternal[] // by id\n queryMasks: Map<number, QueryMaskBundle> // queryId → per-world resolved bitmasks\n queryArchetypeCache: (number[] | null)[]\n queryArchetypeStamp: number[]\n bitToQueries: Map<number, Set<number>> // bit → queryIds that mention this bit\n\n // --- reactive query state ---\n reactiveBuffers: Map<number, ReactiveBuffer> // queryId → { entered, exited }\n\n // --- observers ---\n observers: ObserverEntry[]\n\n // --- relations ---\n relationStorage: Map<number, RelationStorage> // relation id → storage\n\n // --- worker / SAB ---\n sab: SharedArrayBuffer | null\n readOnly: boolean\n}\n","import type { System, World } from './types.js'\n\nexport function pipe<W extends World = World, Ctx = unknown>(\n ...systems: System<W, Ctx>[]\n): System<W, Ctx> {\n if (systems.length === 0) return (w: W) => w\n if (systems.length === 1) return systems[0]!\n return (world: W, ctx: Ctx) => {\n let w = world\n for (const s of systems) w = s(w, ctx)\n return w\n }\n}\n","// aiecsjs/ref — ABA-safe entity references.\n//\n// EntityRef<T> wraps a packed EntityId with a world identity check so that\n// stale references (pointing at a recycled slot with a different generation)\n// safely return null rather than silently accessing the wrong entity.\n//\n// EntityRef is in-memory only. Do not pass across worker boundaries or persist\n// to disk. The packed id field has meaning only within the world that issued it.\n// Generation counters reset on resetWorld / deserializeWorld / adoptSnapshot.\n\nimport { isAliveInternal, unpackGen, unpackIdx } from './internal/entity.js'\nimport type { EntityId, World } from './internal/types.js'\nimport { getWorldState } from './internal/world.js'\n\n/**\n * ABA-safe entity reference.\n *\n * Holds the packed EntityId and the id of the world that issued it.\n * Use `deref(world, ref)` to validate and retrieve the live entity id.\n *\n * The phantom type `T` allows callers to distinguish reference kinds at the\n * type system level — e.g. `EntityRef<'bullet'>` vs `EntityRef<'player'>` —\n * without any runtime overhead.\n *\n * @example\n * const ref = refOf<'bullet'>(world, e)\n * // later, in a system:\n * const live = deref(world, ref)\n * if (live !== null) {\n * // entity is still alive with the same generation\n * }\n */\nexport interface EntityRef<T = unknown> {\n readonly id: EntityId // packed value (index + generation)\n readonly worldId: number // world.id — guards against cross-world deref\n readonly __phantom?: T // phantom type tag; zero runtime size\n}\n\n/**\n * Thrown by `refOf` when the entity is not alive.\n * `deref` and `aliveRef` never throw — they return null/false.\n */\nexport class EntityNotAliveError extends Error {\n readonly eid: number\n constructor(eid: number) {\n super(`aiecsjs: entity ${eid} is not alive`)\n this.name = 'EntityNotAliveError'\n this.eid = eid\n }\n}\n\n/**\n * Create an ABA-safe reference to a live entity.\n *\n * @throws {EntityNotAliveError} if the entity is not alive (dead, never created, or eid === 0).\n *\n * The returned object is frozen. `id` is the packed EntityId; `worldId` is\n * the world's numeric id used by `deref` to reject cross-world lookups.\n *\n * The function may be called on the hot path — each call returns a new object\n * but performs no allocation beyond that.\n */\nexport function refOf<T = unknown>(world: World, entity: EntityId): EntityRef<T> {\n const state = getWorldState(world)\n if (!isAliveInternal(state, entity as number)) {\n throw new EntityNotAliveError(entity as number)\n }\n return Object.freeze({ id: entity, worldId: state.id }) as EntityRef<T>\n}\n\n/**\n * Resolve a ref to its live EntityId, or return null if stale.\n *\n * Returns null when any of the following hold:\n * 1. `ref.worldId !== state.id` — cross-world ref\n * 2. `getEntityIndex(ref.id) >= state.capacity` — index out-of-bounds\n * 3. `getEntityIndex(ref.id) === 0` — sentinel slot\n * 4. entity is not in any archetype's entityRow (slot released)\n * 5. generation mismatch → ABA: old ref points at recycled slot\n *\n * Never throws.\n */\nexport function deref<T = unknown>(world: World, ref: EntityRef<T>): EntityId | null {\n const state = getWorldState(world)\n\n // Cross-world guard\n if (ref.worldId !== state.id) return null\n\n const eid = ref.id as number\n const idx = unpackIdx(eid, state.options)\n\n // Sentinel and OOB guards\n if (idx <= 0) return null\n if (idx >= state.capacity) return null\n\n // Archetype membership check\n const archId = state.entityArchetype[idx] ?? 0\n const arch = state.archetypes[archId]\n if (!arch) return null\n if (!arch.entityRow.has(ref.id)) return null\n\n // Generation match — the core ABA protection\n const storedGen = state.generations[idx] ?? 0\n const refGen = unpackGen(eid, state.options)\n if (storedGen !== refGen) return null\n\n return ref.id\n}\n\n/**\n * Boolean guard form of `deref`. Equivalent to `deref(world, ref) !== null`.\n * Use in guard clauses when you do not need the resolved EntityId.\n *\n * Never throws.\n */\nexport function aliveRef<T = unknown>(world: World, ref: EntityRef<T>): boolean {\n return deref(world, ref) !== null\n}\n","// aiecsjs — public root entry.\n// Re-exports the core API and wires up the lazy cross-module references.\n\nexport { VERSION } from './version.js'\n\nimport {\n getComponentByInternalId,\n registerMaskChangeDispatch,\n registerObserverDispatch,\n} from './internal/component.js'\nimport { registerObserversAPI, registerRelationsCleanup } from './internal/entity.js'\nimport { recordEntityMaskChange, registerComponentLookup } from './internal/query.js'\nimport type { EntityId, WorldState } from './internal/types.js'\n\n// Wire query → component lookup\nregisterComponentLookup((id) => getComponentByInternalId(id))\n\n// Wire component mask-change → query reactive update\nregisterMaskChangeDispatch((state, eid, bit, prev, next) => {\n recordEntityMaskChange(state, eid, bit, prev, next)\n})\n\n// Observer dispatch is registered lazily by observers.ts on first import.\n// Relations cleanup is registered lazily by relations.ts on first import.\n\n// --- Type re-exports ---\nexport type {\n EntityId,\n World,\n WorldOptions,\n System,\n SoAComponent,\n AoSComponent,\n TagComponent,\n ComponentLike,\n ComponentInit,\n ComponentView,\n SoAColumns,\n SoASchema,\n SoAFieldType,\n SoAFieldDecl,\n Query,\n QueryDescriptor,\n Archetype,\n} from './internal/types.js'\n\n// --- World ---\nexport {\n createWorld,\n destroyWorld,\n resetWorld,\n getWorldSize,\n getWorldCapacity,\n isWorld,\n} from './internal/world.js'\n\n// `disposeWorld` is the new preferred name (added 0.2.0). It is the same\n// function as `destroyWorld`, exported under a name that aligns with the ai*js\n// ecosystem `dispose()` convention (aifsmjs Runtime, aibridgejs Bridge).\n//\n// `destroyWorld` is the original 0.1.x export. It is now deprecated as of 0.2.0\n// and is scheduled for removal in 1.0. New code should import `disposeWorld`.\nexport { destroyWorld as disposeWorld } from './internal/world.js'\n\n// --- Entity ---\nexport {\n createEntity,\n destroyEntity,\n entityExists,\n getEntityIndex,\n getEntityGeneration,\n packEntity,\n isEntity,\n} from './internal/entity.js'\n\n// --- Component ---\nexport {\n defineComponent,\n defineTag,\n defineObjectComponent,\n addComponent,\n removeComponent,\n hasComponent,\n getComponent,\n setComponent,\n} from './internal/component.js'\n\nexport { Types } from './internal/types.js'\n\n// --- Query ---\nexport {\n defineQuery,\n runQuery,\n iterQuery,\n forEachEntity,\n forEachEntityIndexed,\n enterQuery,\n exitQuery,\n queryArchetypes,\n} from './internal/query.js'\n\n// --- System ---\nexport { pipe } from './internal/pipe.js'\n\n// --- Utility ---\nexport const IS_SAB_SUPPORTED: boolean = typeof SharedArrayBuffer !== 'undefined'\n\n// --- Errors ---\nexport { EcsError } from './internal/errors.js'\n\n// --- EntityRef (ABA-safe references) ---\nexport type { EntityRef } from './ref.js'\nexport { refOf, deref, aliveRef, EntityNotAliveError } from './ref.js'\n"]}
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
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
- export { d as ComponentView, g as SoAColumns, i as SoAFieldDecl, j as SoAFieldType, n as Types } from './types-BGEeHad-.cjs';
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-BeVLA7xG.cjs';
2
+ export { d as ComponentView, g as SoAColumns, i as SoAFieldDecl, j as SoAFieldType, n as Types } from './types-BeVLA7xG.cjs';
3
3
 
4
- declare const VERSION = "0.5.5";
4
+ declare const VERSION = "0.5.7";
5
5
 
6
6
  declare function createWorld(options?: WorldOptions): World;
7
7
  declare function destroyWorld(world: World): void;
@@ -47,11 +47,48 @@ declare function getComponent<C extends ComponentLike>(world: World, eid: Entity
47
47
  declare function setComponent<C extends ComponentLike, V>(world: World, eid: EntityId, component: C, value: V): void;
48
48
 
49
49
  declare function defineQuery(arg: ComponentLike[] | QueryDescriptor): Query;
50
+ /**
51
+ * Reactive "entered" view of `query`: each read drains the entities that began
52
+ * matching since the last read (via `runQuery` / `iterQuery` / `forEachEntity`).
53
+ *
54
+ * **MUST-DRAIN CONTRACT (unbounded buffer).** The enter buffer has **no cap**.
55
+ * Every structural change that makes an entity newly match pushes one id; the
56
+ * buffer only shrinks when you read the reactive view. A view that is created
57
+ * but never read — e.g. a disabled system, or reading only the {@link exitQuery}
58
+ * twin — accumulates one number per event **forever**, an unbounded memory leak
59
+ * at churn rates (e.g. ~1k spawns/frame). Read every enter view you create, once
60
+ * per frame. Dropping ids silently would corrupt enter/exit symmetry, so capping
61
+ * is intentionally not done — draining is the caller's responsibility.
62
+ */
50
63
  declare function enterQuery(query: Query): Query;
64
+ /**
65
+ * Reactive "exited" view of `query`: each read drains the entities that stopped
66
+ * matching since the last read (via `runQuery` / `iterQuery` / `forEachEntity`).
67
+ *
68
+ * **MUST-DRAIN CONTRACT (unbounded buffer).** The exit buffer has **no cap** —
69
+ * same discipline as {@link enterQuery}. An unread exit view accumulates one id
70
+ * per matching structural change (including every `destroyEntity` of a matching
71
+ * entity) without bound. Read every exit view you create, once per frame. Capping
72
+ * is intentionally not done because dropping ids would break enter/exit symmetry.
73
+ */
51
74
  declare function exitQuery(query: Query): Query;
52
75
  declare function queryArchetypes(world: World, query: Query): readonly Archetype[];
53
76
  declare function runQuery(world: World, query: Query): readonly EntityId[];
54
77
  declare function iterQuery(world: World, query: Query): IterableIterator<EntityId>;
78
+ /**
79
+ * Iterate every entity matching `query`, invoking `fn(e, ...cols)` once per row
80
+ * with the packed {@link EntityId} and the query's SoA column views.
81
+ *
82
+ * **Caution — `e` is a packed EntityId, not a column subscript.** It carries the
83
+ * generation in its high bits, so indexing a column view with it directly
84
+ * (`pos.x[e]`) reads out of bounds once a slot has been recycled. Use `e` only
85
+ * for identity operations (`destroyEntity` / `hasComponent` / `refOf`). To index
86
+ * columns safely, prefer {@link forEachEntityIndexed} — which yields the masked
87
+ * slot index `i` alongside `e` — or mask it yourself with {@link getEntityIndex}.
88
+ *
89
+ * @see {@link forEachEntityIndexed} — same iteration plus the safe column index `i`.
90
+ * @see {@link getEntityIndex} — mask a packed EntityId to its raw slot index.
91
+ */
55
92
  declare function forEachEntity(world: World, query: Query, fn: (eid: EntityId, ...cols: any[]) => void): void;
56
93
  /**
57
94
  * Like {@link forEachEntity}, but yields the masked column index `i` alongside
@@ -72,6 +109,28 @@ declare function forEachEntityIndexed(world: World, query: Query, fn: (e: Entity
72
109
 
73
110
  declare function pipe<W extends World = World, Ctx = unknown>(...systems: System<W, Ctx>[]): System<W, Ctx>;
74
111
 
112
+ /**
113
+ * Thrown by core world/entity/component operations for invariant violations and
114
+ * misuse (bad world options, a destroyed/unknown world, exhausted component
115
+ * slots, capacity overflow). Carries the existing `aiecsjs: `-prefixed message.
116
+ *
117
+ * Catch this to distinguish an aiecsjs-originated failure from an unrelated
118
+ * runtime error, instead of string-matching on the message. Mirrors the
119
+ * {@link EntityNotAliveError} class style.
120
+ *
121
+ * @example
122
+ * try {
123
+ * createWorld({ indexBits: 99 })
124
+ * } catch (err) {
125
+ * if (err instanceof EcsError) {
126
+ * // an aiecsjs invariant was violated
127
+ * }
128
+ * }
129
+ */
130
+ declare class EcsError extends Error {
131
+ constructor(message: string);
132
+ }
133
+
75
134
  /**
76
135
  * ABA-safe entity reference.
77
136
  *
@@ -138,4 +197,4 @@ declare function aliveRef<T = unknown>(world: World, ref: EntityRef<T>): boolean
138
197
 
139
198
  declare const IS_SAB_SUPPORTED: boolean;
140
199
 
141
- 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, forEachEntityIndexed, getComponent, getEntityGeneration, getEntityIndex, getWorldCapacity, getWorldSize, hasComponent, isEntity, isWorld, iterQuery, packEntity, pipe, queryArchetypes, refOf, removeComponent, resetWorld, runQuery, setComponent };
200
+ export { AoSComponent, Archetype, ComponentInit, ComponentLike, EcsError, 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, forEachEntityIndexed, getComponent, getEntityGeneration, getEntityIndex, getWorldCapacity, getWorldSize, hasComponent, isEntity, isWorld, iterQuery, packEntity, pipe, queryArchetypes, refOf, removeComponent, resetWorld, runQuery, setComponent };