aiecsjs 0.2.1 → 0.3.1

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 (50) hide show
  1. package/CHANGELOG.md +90 -2
  2. package/README.md +8 -3
  3. package/README_ZHTW.md +8 -3
  4. package/STABILITY.md +10 -4
  5. package/STABILITY_ZHTW.md +10 -3
  6. package/api.json +568 -100
  7. package/dist/chunk-37HMYMJG.cjs +2 -0
  8. package/dist/chunk-37HMYMJG.cjs.map +1 -0
  9. package/dist/chunk-4RPFOVQC.cjs +2 -0
  10. package/dist/chunk-4RPFOVQC.cjs.map +1 -0
  11. package/dist/chunk-AGHSWLNQ.cjs +2 -0
  12. package/dist/chunk-AGHSWLNQ.cjs.map +1 -0
  13. package/dist/chunk-FDXCXNZK.js +2 -0
  14. package/dist/chunk-FDXCXNZK.js.map +1 -0
  15. package/dist/chunk-L5CMKMIP.js +2 -0
  16. package/dist/chunk-L5CMKMIP.js.map +1 -0
  17. package/dist/chunk-QOKIEF7C.js +2 -0
  18. package/dist/chunk-QOKIEF7C.js.map +1 -0
  19. package/dist/commands.cjs +1 -1
  20. package/dist/commands.cjs.map +1 -1
  21. package/dist/commands.js +1 -1
  22. package/dist/commands.js.map +1 -1
  23. package/dist/index.cjs +1 -1
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +87 -4
  26. package/dist/index.d.ts +87 -4
  27. package/dist/index.js +1 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/observers.cjs +1 -1
  30. package/dist/observers.cjs.map +1 -1
  31. package/dist/observers.d.cts +16 -3
  32. package/dist/observers.d.ts +16 -3
  33. package/dist/observers.js +1 -1
  34. package/dist/observers.js.map +1 -1
  35. package/dist/relations.cjs +1 -1
  36. package/dist/relations.cjs.map +1 -1
  37. package/dist/relations.js +1 -1
  38. package/dist/relations.js.map +1 -1
  39. package/dist/serialize.cjs +1 -1
  40. package/dist/serialize.cjs.map +1 -1
  41. package/dist/serialize.d.cts +7 -0
  42. package/dist/serialize.d.ts +7 -0
  43. package/dist/serialize.js +1 -1
  44. package/dist/serialize.js.map +1 -1
  45. package/dist/worker.cjs +1 -1
  46. package/dist/worker.cjs.map +1 -1
  47. package/dist/worker.js +1 -1
  48. package/dist/worker.js.map +1 -1
  49. package/llms-full.txt +108 -9
  50. package/package.json +6 -2
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/internal/bitmask.ts","../src/version.ts","../src/internal/world.ts","../src/internal/entity.ts","../src/internal/component.ts","../src/serialize.ts"],"names":["createMask","wordCount","setBit","mask","bit","w","testBit","cloneMask","src","out","i","maskHash","m","parts","VERSION","DEFAULT_OPTIONS","DEFAULT_MAX_COMPONENTS","nextWorldId","worldRegistry","getWorldState","world","state","registerWorld","resolveOptions","opts","o","indexBits","generationBits","maxComponents","maxByIndex","initialCapacity","maxEntities","createEmptyArchetype","maskWordCount","createWorld","options","resolved","id","generationCtor","generations","empty","makePublicWorld","ensureCapacity","needed","newCap","growEntityArrays","genCtor","newGen","newArch","newMask","storage","info","growSoAColumns","soa","fields","f","old","newLen","next","findOrCreateArchetype","key","existing","arch","collectBits","ensureArchetypeCapacity","bits","word","lsb","getOrRegisterComponentBit","readEntityMask","eid","base","writeEntityMask","createEntity","row","entityExists","isAliveInternal","archId","componentInfoById","getComponentInfo","component","addComponent","initial","prevMask","writeInitial","migrateEntity","obj","col","val","arr","factory","inst","target","srcArchId","srcArch","destArchId","destArch","lastRow","moved","newRow","getComponentByInternalId","listAllComponents","MAGIC","FORMAT_VERSION","serializeWorld","snapshot","toJSON","c","comp","packBinary","deserializeWorld","bytes","unpackBinary","fromJSON","entities","components","wi","data","baseI","eidMap","handle","getComponentHandle","json","jsonBytes","versionBytes","total","view","off","formatVersion","onUnknown","MAX_FIELD_LEN","verLen","jsonLen","createDeltaSerializer","current","delta","computeDelta","targetWorld","deltaBytes","targetState","e","prev","curr","prevByEid","changed","prevE","prevSig","currSig"],"mappings":"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","file":"serialize.js","sourcesContent":["// Multi-word Uint32 bitmask helpers.\n\nexport function createMask(wordCount: number): Uint32Array {\n return new Uint32Array(wordCount)\n}\n\nexport function setBit(mask: Uint32Array, bit: number): void {\n const w = bit >>> 5\n mask[w] = (mask[w] ?? 0) | (1 << (bit & 31))\n}\n\nexport function clearBit(mask: Uint32Array, bit: number): void {\n const w = bit >>> 5\n mask[w] = (mask[w] ?? 0) & ~(1 << (bit & 31))\n}\n\nexport function testBit(mask: Uint32Array, bit: number): boolean {\n const w = bit >>> 5\n return ((mask[w] ?? 0) & (1 << (bit & 31))) !== 0\n}\n\nexport function copyMask(dst: Uint32Array, src: Uint32Array): void {\n const n = src.length\n for (let i = 0; i < n; i++) dst[i] = src[i] ?? 0\n}\n\nexport function cloneMask(src: Uint32Array): Uint32Array {\n const out = new Uint32Array(src.length)\n for (let i = 0; i < src.length; i++) out[i] = src[i] ?? 0\n return out\n}\n\nexport function maskEquals(a: Uint32Array, b: Uint32Array): boolean {\n const n = a.length\n if (b.length !== n) return false\n for (let i = 0; i < n; i++) if ((a[i] ?? 0) !== (b[i] ?? 0)) return false\n return true\n}\n\nexport function maskHash(m: Uint32Array): string {\n // Stable string key for Map lookups. Hex-joined.\n const parts: string[] = []\n for (let i = 0; i < m.length; i++) {\n parts.push((m[i] ?? 0).toString(16))\n }\n return parts.join(',')\n}\n\nexport function isMaskZero(m: Uint32Array): boolean {\n for (let i = 0; i < m.length; i++) if ((m[i] ?? 0) !== 0) return false\n return true\n}\n\nexport function unionMask(a: Uint32Array, b: Uint32Array): Uint32Array {\n const out = new Uint32Array(a.length)\n for (let i = 0; i < a.length; i++) out[i] = (a[i] ?? 0) | (b[i] ?? 0)\n return out\n}\n\n/**\n * Test whether an archetype's mask matches a query.\n * - withMask: all of these bits must be present\n * - anyMask: if anyHasBits, at least one of these bits must be present\n * - noneMask: none of these bits may be present\n */\nexport function matches(\n mask: Uint32Array,\n withMask: Uint32Array,\n anyMask: Uint32Array,\n noneMask: Uint32Array,\n anyHasBits: boolean,\n words: number,\n): boolean {\n let anyHit = !anyHasBits\n for (let w = 0; w < words; w++) {\n const m = mask[w] ?? 0\n const wm = withMask[w] ?? 0\n const am = anyMask[w] ?? 0\n const nm = noneMask[w] ?? 0\n if ((m & wm) !== wm) return false\n if ((m & nm) !== 0) return false\n if (!anyHit && (m & am) !== 0) anyHit = true\n }\n return anyHit\n}\n\nexport function listBits(mask: Uint32Array): number[] {\n const out: number[] = []\n for (let w = 0; w < mask.length; w++) {\n let word = mask[w] ?? 0\n while (word !== 0) {\n const bit = (w << 5) + ctz32(word)\n out.push(bit)\n word &= word - 1\n }\n }\n return out\n}\n\n// Iterate set bits in a slice of a larger Uint32Array starting at `base`.\n// Shared by destroy paths and storage cleanup so the bit-extraction maths\n// lives in exactly one place.\nexport function forEachSetBit(\n mask: Uint32Array,\n base: number,\n words: number,\n fn: (bit: number) => void,\n): void {\n for (let wi = 0; wi < words; wi++) {\n let word = mask[base + wi] ?? 0\n while (word !== 0) {\n const bit = (wi << 5) + ctz32(word)\n fn(bit)\n word &= word - 1\n }\n }\n}\n\n// Match a query against an entity's mask stored as a slice inside a larger\n// Uint32Array. Reading directly from the parent array avoids the temporary\n// Uint32Array allocation on every observer dispatch.\nexport function matchesEntityMask(\n entityMask: Uint32Array,\n base: number,\n words: number,\n withMask: Uint32Array,\n anyMask: Uint32Array,\n noneMask: Uint32Array,\n anyHasBits: boolean,\n): boolean {\n let anyHit = !anyHasBits\n for (let i = 0; i < words; i++) {\n const m = entityMask[base + i] ?? 0\n const wm = withMask[i] ?? 0\n const am = anyMask[i] ?? 0\n const nm = noneMask[i] ?? 0\n if ((m & wm) !== wm) return false\n if ((m & nm) !== 0) return false\n if (!anyHit && (m & am) !== 0) anyHit = true\n }\n return anyHit\n}\n\nfunction ctz32(v: number): number {\n // Count trailing zeros in a 32-bit integer (assumes v !== 0)\n return 31 - Math.clz32(v & -v)\n}\n","export const VERSION = '0.2.1'\n","import { VERSION } from '../version.js'\nimport { cloneMask, copyMask, createMask, maskHash } from './bitmask.js'\nimport type {\n ArchetypeState,\n ComponentInfo,\n FieldInfo,\n ResolvedWorldOptions,\n World,\n WorldComponentStorage,\n WorldOptions,\n WorldState,\n} from './types.js'\n\nexport const WORLD_BRAND = Symbol.for('aiecsjs.world')\n\nconst DEFAULT_OPTIONS: Required<Omit<WorldOptions, 'buffer' | 'bufferByteOffset'>> = {\n initialCapacity: 1024,\n maxEntities: 1_000_000,\n indexBits: 24,\n generationBits: 8,\n}\n\nconst DEFAULT_MAX_COMPONENTS = 256\n\nlet nextWorldId = 1\nconst worldRegistry = new Map<number, WorldState>()\n\nexport function getWorldState(world: World): WorldState {\n const state = worldRegistry.get(world.id)\n if (!state) throw new Error(`aiecsjs: world ${world.id} is destroyed or unknown`)\n if (state.destroyed) throw new Error(`aiecsjs: world ${world.id} is destroyed`)\n return state\n}\n\nexport function registerWorld(state: WorldState): void {\n worldRegistry.set(state.id, state)\n}\n\nexport function unregisterWorld(id: number): void {\n worldRegistry.delete(id)\n}\n\nexport function isWorldRegistered(id: number): boolean {\n return worldRegistry.has(id)\n}\n\nfunction resolveOptions(opts: WorldOptions | undefined): ResolvedWorldOptions {\n const o = opts ?? {}\n const indexBits = o.indexBits ?? DEFAULT_OPTIONS.indexBits\n const generationBits = o.generationBits ?? DEFAULT_OPTIONS.generationBits\n const maxComponents = DEFAULT_MAX_COMPONENTS\n if (indexBits < 1 || indexBits > 24) {\n throw new Error('aiecsjs: indexBits must be in [1, 24]')\n }\n if (generationBits < 0 || generationBits > 16) {\n throw new Error('aiecsjs: generationBits must be in [0, 16]')\n }\n const maxByIndex = 1 << indexBits\n const initialCapacity = Math.max(\n 1,\n Math.min(o.initialCapacity ?? DEFAULT_OPTIONS.initialCapacity, maxByIndex),\n )\n const maxEntities = Math.max(\n initialCapacity,\n Math.min(o.maxEntities ?? DEFAULT_OPTIONS.maxEntities, maxByIndex),\n )\n return {\n initialCapacity,\n maxEntities,\n indexBits,\n generationBits,\n maxComponents,\n maskWordCount: Math.ceil(maxComponents / 32),\n buffer: o.buffer ?? null,\n bufferByteOffset: o.bufferByteOffset ?? 0,\n }\n}\n\nexport function createEmptyArchetype(maskWordCount: number, maxComponents: number): ArchetypeState {\n return {\n id: 0,\n mask: createMask(maskWordCount),\n size: 0,\n capacity: 16,\n entities: new Uint32Array(16),\n entityRow: new Map<number, number>(),\n componentBits: [],\n edgeAdd: new Int32Array(maxComponents).fill(-1),\n edgeRemove: new Int32Array(maxComponents).fill(-1),\n }\n}\n\nexport function createWorld(options?: WorldOptions): World {\n const resolved = resolveOptions(options)\n const id = nextWorldId++\n\n const generationCtor = resolved.generationBits > 8 ? Uint16Array : Uint8Array\n const generations = new generationCtor(resolved.initialCapacity)\n\n const state: WorldState = {\n id,\n capacity: resolved.initialCapacity,\n version: VERSION,\n options: resolved,\n size: 0,\n nextFreshIndex: 1, // 0 reserved\n freeList: [],\n generations,\n destroyed: false,\n componentBitFor: new Map<number, number>(),\n componentInfoByBit: new Array(resolved.maxComponents).fill(null),\n componentStorageByBit: new Array(resolved.maxComponents).fill(null),\n nextComponentBit: 0,\n entityArchetype: new Uint32Array(resolved.initialCapacity),\n entityMask: new Uint32Array(resolved.initialCapacity * resolved.maskWordCount),\n archetypes: [],\n archetypeByMaskHash: new Map<string, number>(),\n queryVersion: 0,\n queries: [],\n queryMasks: new Map(),\n queryArchetypeCache: [],\n queryArchetypeStamp: [],\n bitToQueries: new Map<number, Set<number>>(),\n reactiveBuffers: new Map(),\n observers: [],\n relationStorage: new Map(),\n sab: resolved.buffer,\n readOnly: false,\n }\n\n // Seed archetype 0 (the empty mask)\n const empty = createEmptyArchetype(resolved.maskWordCount, resolved.maxComponents)\n empty.id = 0\n state.archetypes.push(empty)\n state.archetypeByMaskHash.set(maskHash(empty.mask), 0)\n\n registerWorld(state)\n return makePublicWorld(state)\n}\n\nexport function makePublicWorld(state: WorldState): World {\n return {\n id: state.id,\n get capacity() {\n return state.capacity\n },\n version: state.version,\n } as World\n}\n\nexport function destroyWorld(world: World): void {\n const state = worldRegistry.get(world.id)\n if (!state || state.destroyed) return\n state.destroyed = true\n // Clear large buffers to help GC\n state.archetypes = []\n state.archetypeByMaskHash.clear()\n state.componentInfoByBit = []\n state.componentStorageByBit = []\n state.queries = []\n state.queryMasks.clear()\n state.queryArchetypeCache = []\n state.observers = []\n state.relationStorage.clear()\n state.reactiveBuffers.clear()\n unregisterWorld(world.id)\n}\n\nexport function resetWorld(world: World): void {\n const state = getWorldState(world)\n // Keep capacity and registered components; clear entities and per-entity state.\n state.size = 0\n state.nextFreshIndex = 1\n state.freeList = []\n state.generations.fill(0)\n state.entityArchetype.fill(0)\n state.entityMask.fill(0)\n // Wipe archetype memberships but keep archetype graph for stability.\n for (const arch of state.archetypes) {\n arch.size = 0\n arch.entityRow.clear()\n }\n // Clear SoA columns and AoS instances; storage allocation is preserved.\n for (const storage of state.componentStorageByBit) {\n if (!storage) continue\n if (storage.kind === 'soa' && storage.soa) {\n for (const k of Object.keys(storage.soa)) {\n storage.soa[k]?.fill(0)\n }\n } else if (storage.kind === 'aos' && storage.aos) {\n storage.aos.fill(undefined as unknown as never)\n }\n }\n state.queryVersion++\n for (const buf of state.reactiveBuffers.values()) {\n buf.entered.length = 0\n buf.exited.length = 0\n }\n}\n\nexport function getWorldSize(world: World): number {\n return getWorldState(world).size\n}\n\nexport function getWorldCapacity(world: World): number {\n return getWorldState(world).capacity\n}\n\n// --- Capacity growth ---\n\nexport function ensureCapacity(state: WorldState, needed: number): void {\n if (needed <= state.capacity) return\n if (needed > state.options.maxEntities) {\n throw new Error(\n `aiecsjs: requested capacity ${needed} exceeds maxEntities ${state.options.maxEntities}`,\n )\n }\n let newCap = state.capacity\n while (newCap < needed) newCap = Math.min(newCap * 2, state.options.maxEntities)\n growEntityArrays(state, newCap)\n}\n\nfunction growEntityArrays(state: WorldState, newCap: number): void {\n // generations\n const genCtor: any = state.generations.constructor\n const newGen = new genCtor(newCap) as Uint8Array | Uint16Array\n ;(newGen as Uint8Array).set(state.generations as Uint8Array)\n state.generations = newGen\n\n // entityArchetype\n const newArch = new Uint32Array(newCap)\n newArch.set(state.entityArchetype)\n state.entityArchetype = newArch\n\n // entityMask\n const wordCount = state.options.maskWordCount\n const newMask = new Uint32Array(newCap * wordCount)\n newMask.set(state.entityMask)\n state.entityMask = newMask\n\n // Component storages (SoA columns + AoS arrays)\n for (const storage of state.componentStorageByBit) {\n if (!storage) continue\n if (storage.kind === 'soa' && storage.soa) {\n const info = state.componentInfoByBit[storage.bit]\n if (info) growSoAColumns(storage.soa, info.fields, newCap)\n } else if (storage.kind === 'aos' && storage.aos) {\n storage.aos.length = newCap\n }\n }\n\n state.capacity = newCap\n}\n\nfunction growSoAColumns(soa: Record<string, any>, fields: FieldInfo[], newCap: number): void {\n for (const f of fields) {\n const old = soa[f.name]\n if (!old) continue\n const newLen = newCap * f.vectorLen\n if (old.length >= newLen) continue\n const next = new f.ctor(newLen)\n next.set(old)\n soa[f.name] = next\n }\n}\n\n// --- Archetype management ---\n\nexport function findOrCreateArchetype(\n state: WorldState,\n mask: Uint32Array,\n): { archId: number; created: boolean } {\n const key = maskHash(mask)\n const existing = state.archetypeByMaskHash.get(key)\n if (existing !== undefined) return { archId: existing, created: false }\n\n const id = state.archetypes.length\n const arch: ArchetypeState = {\n id,\n mask: cloneMask(mask),\n size: 0,\n capacity: 16,\n entities: new Uint32Array(16),\n entityRow: new Map<number, number>(),\n componentBits: collectBits(mask),\n edgeAdd: new Int32Array(state.options.maxComponents).fill(-1),\n edgeRemove: new Int32Array(state.options.maxComponents).fill(-1),\n }\n state.archetypes.push(arch)\n state.archetypeByMaskHash.set(key, id)\n state.queryVersion++\n return { archId: id, created: true }\n}\n\nexport function ensureArchetypeCapacity(arch: ArchetypeState, needed: number): void {\n if (needed <= arch.capacity) return\n let newCap = arch.capacity\n while (newCap < needed) newCap *= 2\n const next = new Uint32Array(newCap)\n next.set(arch.entities)\n arch.entities = next\n arch.capacity = newCap\n}\n\nfunction collectBits(mask: Uint32Array): number[] {\n const bits: number[] = []\n for (let w = 0; w < mask.length; w++) {\n let word = mask[w] ?? 0\n while (word !== 0) {\n const lsb = word & -word\n const bit = (w << 5) + (31 - Math.clz32(lsb))\n bits.push(bit)\n word &= word - 1\n }\n }\n return bits\n}\n\n// --- Component registration in a world ---\n\nexport function getOrRegisterComponentBit(state: WorldState, info: ComponentInfo): number {\n const existing = state.componentBitFor.get(info.id)\n if (existing !== undefined) return existing\n\n if (state.nextComponentBit >= state.options.maxComponents) {\n throw new Error(`aiecsjs: world reached maxComponents=${state.options.maxComponents}`)\n }\n const bit = state.nextComponentBit++\n state.componentBitFor.set(info.id, bit)\n state.componentInfoByBit[bit] = info\n\n // Create storage\n let storage: WorldComponentStorage\n if (info.kind === 'soa') {\n const soa: Record<string, any> = {}\n for (const f of info.fields) {\n soa[f.name] = new f.ctor(state.capacity * f.vectorLen)\n }\n storage = { kind: 'soa', componentId: info.id, bit, soa }\n } else if (info.kind === 'aos') {\n storage = { kind: 'aos', componentId: info.id, bit, aos: new Array(state.capacity) }\n } else {\n storage = { kind: 'tag', componentId: info.id, bit }\n }\n state.componentStorageByBit[bit] = storage\n return bit\n}\n\n// Read a bitmask out of state.entityMask[] into a fresh Uint32Array.\nexport function readEntityMask(state: WorldState, eid: number): Uint32Array {\n const w = state.options.maskWordCount\n const out = new Uint32Array(w)\n const base = eid * w\n for (let i = 0; i < w; i++) out[i] = state.entityMask[base + i] ?? 0\n return out\n}\n\nexport function writeEntityMask(state: WorldState, eid: number, mask: Uint32Array): void {\n const w = state.options.maskWordCount\n const base = eid * w\n for (let i = 0; i < w; i++) state.entityMask[base + i] = mask[i] ?? 0\n}\n\n// Get the bit of a component within a world without registering.\nexport function tryGetComponentBit(state: WorldState, info: ComponentInfo): number | undefined {\n return state.componentBitFor.get(info.id)\n}\n\nexport function isWorld(x: unknown): x is World {\n if (!x || typeof x !== 'object') return false\n const obj = x as { id?: unknown; version?: unknown }\n if (typeof obj.id !== 'number') return false\n if (typeof obj.version !== 'string') return false\n return worldRegistry.has(obj.id)\n}\n","import { clearAllEntityStorages } from './component.js'\nimport type { EntityId, World, WorldState } from './types.js'\nimport { ensureArchetypeCapacity, ensureCapacity, getWorldState } from './world.js'\n\nexport function createEntity(world: World): EntityId {\n const state = getWorldState(world)\n if (state.readOnly) {\n throw new Error('aiecsjs: cannot createEntity on a read-only world (worker-attached)')\n }\n\n let eid: number\n if (state.freeList.length > 0) {\n eid = state.freeList.pop()!\n } else {\n if (state.nextFreshIndex >= state.options.maxEntities) {\n throw new Error(`aiecsjs: reached maxEntities ${state.options.maxEntities}`)\n }\n if (state.nextFreshIndex >= state.capacity) {\n ensureCapacity(state, state.nextFreshIndex + 1)\n }\n eid = state.nextFreshIndex++\n }\n\n // Move into the empty archetype (0)\n const arch = state.archetypes[0]\n if (!arch) throw new Error('aiecsjs: missing empty archetype')\n ensureArchetypeCapacity(arch, arch.size + 1)\n const row = arch.size\n arch.entities[row] = eid\n arch.entityRow.set(eid, row)\n arch.size++\n\n state.entityArchetype[eid] = 0\n // Reset entityMask row for this eid\n const w = state.options.maskWordCount\n const base = eid * w\n for (let i = 0; i < w; i++) state.entityMask[base + i] = 0\n\n state.size++\n return eid as EntityId\n}\n\nexport function destroyEntity(world: World, eid: EntityId): void {\n const state = getWorldState(world)\n if (state.readOnly) {\n throw new Error('aiecsjs: cannot destroyEntity on a read-only world')\n }\n if (!isAliveInternal(state, eid)) return\n\n // Fire onRemove for every component the entity has, plus reactive exit\n // (Late-bound to avoid circular imports — done via observers module.)\n const { dispatchDestroyObservers } = lazyObservers()\n dispatchDestroyObservers(state, eid)\n\n // Clean up relations referring to this entity\n cleanupRelationsOnDestroy(state, eid)\n\n // Zero the SoA columns / undefine the AoS slots the entity owned, before\n // the mask is cleared. Without this, destroyed entities leave stale data\n // visible to snapshots and serialisation.\n clearAllEntityStorages(state, eid)\n\n // Swap-pop from its archetype\n const archId = state.entityArchetype[eid] ?? 0\n const arch = state.archetypes[archId]\n if (arch) {\n const row = arch.entityRow.get(eid)\n if (row !== undefined) {\n const lastRow = arch.size - 1\n if (row !== lastRow) {\n const moved = arch.entities[lastRow] ?? 0\n arch.entities[row] = moved\n arch.entityRow.set(moved, row)\n }\n arch.entities[lastRow] = 0\n arch.entityRow.delete(eid)\n arch.size--\n }\n }\n\n // Wipe state\n state.entityArchetype[eid] = 0\n const w = state.options.maskWordCount\n const base = eid * w\n for (let i = 0; i < w; i++) state.entityMask[base + i] = 0\n // bump generation (Uint8Array wraps to 8 bits naturally; Uint16Array to 16)\n const idx = eid as number\n state.generations[idx] = ((state.generations[idx] ?? 0) + 1) & 0xffff\n\n state.freeList.push(eid)\n state.size--\n}\n\nexport function entityExists(world: World, eid: EntityId): boolean {\n const state = getWorldState(world)\n return isAliveInternal(state, eid)\n}\n\nexport function isAliveInternal(state: WorldState, eid: number): boolean {\n if (eid <= 0) return false\n if (eid >= state.capacity) return false\n // An entity is alive iff it is in some archetype (its row map points somewhere).\n const archId = state.entityArchetype[eid] ?? 0\n const arch = state.archetypes[archId]\n if (!arch) return false\n return arch.entityRow.has(eid)\n}\n\nexport function getEntityIndex(eid: EntityId): number {\n return eid as number\n}\n\nexport function getEntityGeneration(_eid: EntityId): number {\n // Unversioned in 0.1: generation not encoded in EntityId.\n return 0\n}\n\nexport function packEntity(index: number, _generation: number): EntityId {\n // Identity in 0.1.\n return index as EntityId\n}\n\nexport function isEntity(world: World, x: unknown): x is EntityId {\n if (typeof x !== 'number') return false\n return entityExists(world, x as EntityId)\n}\n\n// --- Lazy loaders to break import cycles ---\n\ninterface ObserversAPI {\n dispatchDestroyObservers(state: WorldState, eid: EntityId): void\n}\nlet _observersAPI: ObserversAPI | null = null\nexport function registerObserversAPI(api: ObserversAPI): void {\n _observersAPI = api\n}\nfunction lazyObservers(): ObserversAPI {\n if (!_observersAPI) {\n return { dispatchDestroyObservers: () => {} }\n }\n return _observersAPI\n}\n\nlet _relationsCleanup: ((state: WorldState, eid: EntityId) => void) | null = null\nexport function registerRelationsCleanup(fn: (state: WorldState, eid: EntityId) => void): void {\n _relationsCleanup = fn\n}\nfunction cleanupRelationsOnDestroy(state: WorldState, eid: EntityId): void {\n if (_relationsCleanup) _relationsCleanup(state, eid)\n}\n","import { clearBit, cloneMask, forEachSetBit, setBit, testBit } from './bitmask.js'\nimport { isAliveInternal } from './entity.js'\nimport type {\n AoSComponent,\n ComponentInfo,\n ComponentInit,\n ComponentLike,\n EntityId,\n FieldInfo,\n SoAColumns,\n SoAComponent,\n SoASchema,\n TagComponent,\n TypedArrayConstructor,\n World,\n WorldComponentStorage,\n WorldState,\n} from './types.js'\nimport {\n ensureArchetypeCapacity,\n findOrCreateArchetype,\n getOrRegisterComponentBit,\n getWorldState,\n readEntityMask,\n tryGetComponentBit,\n writeEntityMask,\n} from './world.js'\n\n// --- Component factories ---\n\nlet nextComponentId = 1\n\nconst TYPE_CTOR: Record<string, TypedArrayConstructor> = {\n i8: Int8Array,\n u8: Uint8Array,\n i16: Int16Array,\n u16: Uint16Array,\n i32: Int32Array,\n u32: Uint32Array,\n f32: Float32Array,\n f64: Float64Array,\n eid: Uint32Array,\n bool: Uint8Array,\n}\n\nconst componentInfoById = new Map<number, ComponentInfo>()\n\nexport function defineComponent<S extends SoASchema>(schema: S): SoAComponent<S> {\n const fields: FieldInfo[] = []\n for (const [name, decl] of Object.entries(schema)) {\n let type: keyof typeof TYPE_CTOR\n let vectorLen = 1\n if (typeof decl === 'string') {\n type = decl\n } else if (Array.isArray(decl)) {\n const [t, len] = decl\n type = t\n vectorLen = len\n } else {\n throw new TypeError(`aiecsjs: invalid field declaration for \"${name}\"`)\n }\n const ctor = TYPE_CTOR[type]\n if (!ctor) throw new TypeError(`aiecsjs: unknown field type \"${type}\" for field \"${name}\"`)\n fields.push({\n name,\n type: type as any,\n vectorLen,\n ctor,\n bytesPerElement: (ctor as any).BYTES_PER_ELEMENT,\n })\n }\n const id = nextComponentId++\n const info: ComponentInfo = { id, kind: 'soa', schema, fields, factory: null }\n componentInfoById.set(id, info)\n const handle: SoAComponent<S> = {\n __kind: 'soa',\n __id: id,\n __schema: schema,\n }\n return handle\n}\n\nexport function defineTag(): TagComponent {\n const id = nextComponentId++\n const info: ComponentInfo = { id, kind: 'tag', schema: null, fields: [], factory: null }\n componentInfoById.set(id, info)\n return { __kind: 'tag', __id: id }\n}\n\nexport function defineObjectComponent<T>(factory?: () => T): AoSComponent<T> {\n const id = nextComponentId++\n const fac = factory ?? (() => ({}) as T)\n const info: ComponentInfo = { id, kind: 'aos', schema: null, fields: [], factory: fac as any }\n componentInfoById.set(id, info)\n return { __kind: 'aos', __id: id, __factory: fac }\n}\n\nexport function getComponentInfo(component: ComponentLike): ComponentInfo {\n const info = componentInfoById.get(component.__id)\n if (!info)\n throw new Error(\n 'aiecsjs: component is not registered (call defineComponent/defineTag/defineObjectComponent)',\n )\n return info\n}\n\n// --- Component ops on entities ---\n\nexport function addComponent<C extends ComponentLike>(\n world: World,\n eid: EntityId,\n component: C,\n initial?: ComponentInit<C>,\n): void {\n const state = getWorldState(world)\n if (state.readOnly) throw new Error('aiecsjs: cannot mutate a read-only world')\n if (!isAliveInternal(state, eid)) {\n throw new Error(`aiecsjs: addComponent on dead entity ${eid}`)\n }\n const info = getComponentInfo(component)\n const bit = getOrRegisterComponentBit(state, info)\n\n const prevMask = readEntityMask(state, eid)\n if (testBit(prevMask, bit)) {\n if (initial !== undefined) writeInitial(state, eid, component, initial)\n return\n }\n const newMask = cloneMask(prevMask)\n setBit(newMask, bit)\n migrateEntity(state, eid, newMask)\n\n writeInitial(state, eid, component, initial)\n\n fireAddObservers(state, eid, bit)\n notifyMaskChange(state, eid, bit, prevMask, newMask)\n}\n\nexport function removeComponent<C extends ComponentLike>(\n world: World,\n eid: EntityId,\n component: C,\n): void {\n const state = getWorldState(world)\n if (state.readOnly) throw new Error('aiecsjs: cannot mutate a read-only world')\n if (!isAliveInternal(state, eid)) return\n const info = getComponentInfo(component)\n const bit = tryGetComponentBit(state, info)\n if (bit === undefined) return\n const prevMask = readEntityMask(state, eid)\n if (!testBit(prevMask, bit)) return\n\n // Write the new mask BEFORE firing observers so query-targeted observers\n // reading `state.entityMask` see the post-removal state (and thus correctly\n // detect \"entity left this query\"). Without this reorder, a query that\n // requires the removed component would still match during dispatch and the\n // remove observer would never fire. Component-targeted observers receive the\n // bit directly and don't depend on mask timing. addComponent already follows\n // this \"mutate then fire\" order; keeping removeComponent consistent.\n const newMask = cloneMask(prevMask)\n clearBit(newMask, bit)\n migrateEntity(state, eid, newMask)\n\n fireRemoveObservers(state, eid, bit)\n\n const storage = state.componentStorageByBit[bit]\n if (storage?.kind === 'soa' && storage.soa) {\n clearSoAEntity(storage.soa, info.fields, eid)\n } else if (storage?.kind === 'aos' && storage.aos) {\n storage.aos[eid] = undefined\n }\n\n notifyMaskChange(state, eid, bit, prevMask, newMask)\n}\n\nexport function hasComponent<C extends ComponentLike>(\n world: World,\n eid: EntityId,\n component: C,\n): boolean {\n const state = getWorldState(world)\n if (!isAliveInternal(state, eid)) return false\n const info = getComponentInfo(component)\n const bit = tryGetComponentBit(state, info)\n if (bit === undefined) return false\n const mask = readEntityMask(state, eid)\n return testBit(mask, bit)\n}\n\nexport function getComponent<C extends ComponentLike>(\n world: World,\n eid: EntityId,\n component: C,\n): unknown {\n const state = getWorldState(world)\n if (!isAliveInternal(state, eid)) return undefined\n const info = getComponentInfo(component)\n const bit = tryGetComponentBit(state, info)\n if (bit === undefined) return undefined\n const mask = readEntityMask(state, eid)\n if (!testBit(mask, bit)) return undefined\n const storage = state.componentStorageByBit[bit]\n if (!storage) return undefined\n if (storage.kind === 'soa') return storage.soa\n if (storage.kind === 'aos') return storage.aos?.[eid]\n return true // tag\n}\n\nexport function setComponent<C extends ComponentLike, V>(\n world: World,\n eid: EntityId,\n component: C,\n value: V,\n): void {\n const state = getWorldState(world)\n if (state.readOnly) throw new Error('aiecsjs: cannot mutate a read-only world')\n if (!isAliveInternal(state, eid)) throw new Error(`aiecsjs: setComponent on dead entity ${eid}`)\n const info = getComponentInfo(component)\n const bit = tryGetComponentBit(state, info)\n if (bit === undefined) {\n // Adding via set\n addComponent(world, eid, component, value as any)\n return\n }\n const mask = readEntityMask(state, eid)\n if (!testBit(mask, bit)) {\n addComponent(world, eid, component, value as any)\n return\n }\n writeInitial(state, eid, component, value as any)\n fireSetObservers(state, eid, bit, value)\n}\n\n// --- Internals ---\n\nfunction writeInitial(\n state: WorldState,\n eid: number,\n component: ComponentLike,\n initial: unknown,\n): void {\n const info = getComponentInfo(component)\n const bit = state.componentBitFor.get(info.id)\n if (bit === undefined) return\n const storage = state.componentStorageByBit[bit]\n if (!storage) return\n if (info.kind === 'soa' && storage.soa) {\n if (initial == null) return\n const obj = initial as Record<string, unknown>\n for (const f of info.fields) {\n if (!(f.name in obj)) continue\n const col = storage.soa[f.name]\n if (!col) continue\n const val = obj[f.name]\n if (f.vectorLen === 1) {\n col[eid] = typeof val === 'boolean' ? (val ? 1 : 0) : Number(val)\n } else if (Array.isArray(val) || ArrayBuffer.isView(val)) {\n const base = eid * f.vectorLen\n const arr = val as ArrayLike<number>\n for (let i = 0; i < f.vectorLen; i++) col[base + i] = Number(arr[i] ?? 0)\n }\n }\n } else if (info.kind === 'aos' && storage.aos) {\n const factory = info.factory ?? (() => ({}))\n let inst = storage.aos[eid]\n if (inst === undefined) {\n inst = factory()\n storage.aos[eid] = inst\n }\n if (initial && typeof initial === 'object') {\n // SECURITY: do NOT use `Object.assign(inst, initial)` here. When `initial`\n // comes from `JSON.parse(untrustedBytes)` — e.g. via `fromJSON`,\n // `deserializeWorld`, or app code piping a bridge payload — the parsed\n // object can carry an OWN `__proto__` property, and `Object.assign` uses\n // [[Set]] semantics which would trigger the proto setter and clobber the\n // instance's prototype chain. Explicit own-key copy with a deny-list\n // closes the prototype-pollution path.\n const src = initial as Record<string, unknown>\n const target = inst as Record<string, unknown>\n for (const key of Object.keys(src)) {\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue\n target[key] = src[key]\n }\n }\n }\n // tag: nothing\n}\n\nfunction clearSoAEntity(soa: SoAColumns, fields: FieldInfo[], eid: number): void {\n for (const f of fields) {\n const col = soa[f.name]\n if (!col) continue\n if (f.vectorLen === 1) {\n col[eid] = 0\n } else {\n const base = eid * f.vectorLen\n for (let i = 0; i < f.vectorLen; i++) col[base + i] = 0\n }\n }\n}\n\n// Clear every component-storage slot that the entity currently owns.\n// Walks the entity's mask; for each set bit, zeroes the SoA columns or\n// undefines the AoS slot at the entity index. Tag storages are bit-only.\n// Caller (e.g. destroyEntity) is expected to clear the mask separately.\nexport function clearAllEntityStorages(state: WorldState, eid: EntityId): void {\n const wordCount = state.options.maskWordCount\n const idx = eid as number\n const base = idx * wordCount\n forEachSetBit(state.entityMask, base, wordCount, (bit) => {\n const storage = state.componentStorageByBit[bit]\n const info = state.componentInfoByBit[bit]\n if (storage?.kind === 'soa' && storage.soa && info) {\n clearSoAEntity(storage.soa, info.fields, idx)\n } else if (storage?.kind === 'aos' && storage.aos) {\n storage.aos[idx] = undefined\n }\n })\n}\n\nfunction migrateEntity(state: WorldState, eid: number, newMask: Uint32Array): void {\n const srcArchId = state.entityArchetype[eid] ?? 0\n const srcArch = state.archetypes[srcArchId]\n if (!srcArch) return\n\n const found = findOrCreateArchetype(state, newMask)\n const destArchId = found.archId\n const destArch = state.archetypes[destArchId]\n if (!destArch) return\n\n if (destArchId !== srcArchId) {\n // Swap-pop from src\n const row = srcArch.entityRow.get(eid)\n if (row !== undefined) {\n const lastRow = srcArch.size - 1\n if (row !== lastRow) {\n const moved = srcArch.entities[lastRow] ?? 0\n srcArch.entities[row] = moved\n srcArch.entityRow.set(moved, row)\n }\n srcArch.entities[lastRow] = 0\n srcArch.entityRow.delete(eid)\n srcArch.size--\n }\n\n // Append to dest\n ensureArchetypeCapacity(destArch, destArch.size + 1)\n const newRow = destArch.size\n destArch.entities[newRow] = eid\n destArch.entityRow.set(eid, newRow)\n destArch.size++\n\n state.entityArchetype[eid] = destArchId\n }\n\n writeEntityMask(state, eid, newMask)\n}\n\n// --- Observer dispatch (lazy-bound) ---\n\ninterface ObserversDispatchAPI {\n fireAdd(state: WorldState, eid: EntityId, bit: number): void\n fireRemove(state: WorldState, eid: EntityId, bit: number): void\n fireSet(state: WorldState, eid: EntityId, bit: number, value: unknown): void\n}\nlet _dispatch: ObserversDispatchAPI = {\n fireAdd: () => {},\n fireRemove: () => {},\n fireSet: () => {},\n}\n\ntype MaskChangeFn = (\n state: WorldState,\n eid: EntityId,\n bit: number,\n prev: Uint32Array,\n next: Uint32Array,\n) => void\nlet _maskChange: MaskChangeFn = () => {}\nexport function registerMaskChangeDispatch(fn: MaskChangeFn): void {\n _maskChange = fn\n}\nfunction notifyMaskChange(\n state: WorldState,\n eid: number,\n bit: number,\n prev: Uint32Array,\n next: Uint32Array,\n): void {\n _maskChange(state, eid as EntityId, bit, prev, next)\n}\nexport function registerObserverDispatch(api: ObserversDispatchAPI): void {\n _dispatch = api\n}\nfunction fireAddObservers(state: WorldState, eid: number, bit: number): void {\n _dispatch.fireAdd(state, eid as EntityId, bit)\n}\nfunction fireRemoveObservers(state: WorldState, eid: number, bit: number): void {\n _dispatch.fireRemove(state, eid as EntityId, bit)\n}\nfunction fireSetObservers(state: WorldState, eid: number, bit: number, value: unknown): void {\n _dispatch.fireSet(state, eid as EntityId, bit, value)\n}\n\n// --- Helper for serialize/worker ---\n\nexport function getComponentByInternalId(id: number): ComponentInfo | undefined {\n return componentInfoById.get(id)\n}\n\nexport function listAllComponents(): ComponentInfo[] {\n return Array.from(componentInfoById.values())\n}\n\nexport function _resetComponentRegistry_FOR_TESTS_ONLY(): void {\n componentInfoById.clear()\n nextComponentId = 1\n}\n","// 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, entityExists } 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\nexport function toJSON(world: World): WorldSnapshot {\n const state = getWorldState(world)\n const entities: WorldSnapshot['entities'] = []\n for (let eid = 1; eid < state.capacity; eid++) {\n if (!entityExists(world, eid as EntityId)) continue\n const archId = state.entityArchetype[eid] ?? 0\n if (archId === 0) continue // unattached (shouldn't happen for alive)\n\n const w = state.options.maskWordCount\n const base = eid * 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[eid]\n } else {\n const arr: number[] = []\n const baseI = eid * 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[eid] ?? 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 entities.push({ eid, components })\n }\n return {\n version: state.version,\n capacity: state.capacity,\n entities,\n }\n}\n\nexport function fromJSON(snapshot: WorldSnapshot): World {\n const world = createWorld({ initialCapacity: snapshot.capacity })\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 return JSON.parse(json) as WorldSnapshot\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 // Apply: ensure entities exist, then add/update their components\n const targetState = getWorldState(targetWorld)\n for (const e of snapshot.entities) {\n if (e.eid >= targetState.capacity) continue\n if (!entityExists(targetWorld, e.eid as EntityId)) {\n // Create the entity. For simplicity, we just spawn until we have enough.\n while (targetState.size < e.eid) {\n createEntity(targetWorld)\n }\n }\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, e.eid as EntityId, 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"]}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"serialize.js"}
package/dist/worker.cjs CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var w="0.2.1";function U(t){return new Uint32Array(t)}function M(t,n){let e=n>>>5;t[e]=(t[e]??0)|1<<(n&31);}function O(t,n){let e=n>>>5;return ((t[e]??0)&1<<(n&31))!==0}function g(t){let n=new Uint32Array(t.length);for(let e=0;e<t.length;e++)n[e]=t[e]??0;return n}function E(t){let n=[];for(let e=0;e<t.length;e++)n.push((t[e]??0).toString(16));return n.join(",")}var C={initialCapacity:1024,maxEntities:1e6,indexBits:24,generationBits:8},K=256,tt=1,b=new Map;function u(t){let n=b.get(t.id);if(!n)throw new Error(`aiecsjs: world ${t.id} is destroyed or unknown`);if(n.destroyed)throw new Error(`aiecsjs: world ${t.id} is destroyed`);return n}function nt(t){b.set(t.id,t);}function et(t){b.delete(t);}function _(t){return b.has(t)}function ot(t){let n=t??{},e=n.indexBits??C.indexBits,o=n.generationBits??C.generationBits,r=K;if(e<1||e>24)throw new Error("aiecsjs: indexBits must be in [1, 24]");if(o<0||o>16)throw new Error("aiecsjs: generationBits must be in [0, 16]");let s=1<<e,i=Math.max(1,Math.min(n.initialCapacity??C.initialCapacity,s)),c=Math.max(i,Math.min(n.maxEntities??C.maxEntities,s));return {initialCapacity:i,maxEntities:c,indexBits:e,generationBits:o,maxComponents:r,maskWordCount:Math.ceil(r/32),buffer:n.buffer??null,bufferByteOffset:n.bufferByteOffset??0}}function rt(t,n){return {id:0,mask:U(t),size:0,capacity:16,entities:new Uint32Array(16),entityRow:new Map,componentBits:[],edgeAdd:new Int32Array(n).fill(-1),edgeRemove:new Int32Array(n).fill(-1)}}function j(t){let n=ot(t),e=tt++,o=n.generationBits>8?Uint16Array:Uint8Array,r=new o(n.initialCapacity),s={id:e,capacity:n.initialCapacity,version:w,options:n,size:0,nextFreshIndex:1,freeList:[],generations:r,destroyed:false,componentBitFor:new Map,componentInfoByBit:new Array(n.maxComponents).fill(null),componentStorageByBit:new Array(n.maxComponents).fill(null),nextComponentBit:0,entityArchetype:new Uint32Array(n.initialCapacity),entityMask:new Uint32Array(n.initialCapacity*n.maskWordCount),archetypes:[],archetypeByMaskHash:new Map,queryVersion:0,queries:[],queryMasks:new Map,queryArchetypeCache:[],queryArchetypeStamp:[],bitToQueries:new Map,reactiveBuffers:new Map,observers:[],relationStorage:new Map,sab:n.buffer,readOnly:false},i=rt(n.maskWordCount,n.maxComponents);return i.id=0,s.archetypes.push(i),s.archetypeByMaskHash.set(E(i.mask),0),nt(s),it(s)}function it(t){return {id:t.id,get capacity(){return t.capacity},version:t.version}}function R(t){let n=b.get(t.id);!n||n.destroyed||(n.destroyed=true,n.archetypes=[],n.archetypeByMaskHash.clear(),n.componentInfoByBit=[],n.componentStorageByBit=[],n.queries=[],n.queryMasks.clear(),n.queryArchetypeCache=[],n.observers=[],n.relationStorage.clear(),n.reactiveBuffers.clear(),et(t.id));}function L(t,n){if(n<=t.capacity)return;if(n>t.options.maxEntities)throw new Error(`aiecsjs: requested capacity ${n} exceeds maxEntities ${t.options.maxEntities}`);let e=t.capacity;for(;e<n;)e=Math.min(e*2,t.options.maxEntities);st(t,e);}function st(t,n){let e=t.generations.constructor,o=new e(n);o.set(t.generations),t.generations=o;let r=new Uint32Array(n);r.set(t.entityArchetype),t.entityArchetype=r;let s=t.options.maskWordCount,i=new Uint32Array(n*s);i.set(t.entityMask),t.entityMask=i;for(let c of t.componentStorageByBit)if(c)if(c.kind==="soa"&&c.soa){let a=t.componentInfoByBit[c.bit];a&&at(c.soa,a.fields,n);}else c.kind==="aos"&&c.aos&&(c.aos.length=n);t.capacity=n;}function at(t,n,e){for(let o of n){let r=t[o.name];if(!r)continue;let s=e*o.vectorLen;if(r.length>=s)continue;let i=new o.ctor(s);i.set(r),t[o.name]=i;}}function z(t,n){let e=E(n),o=t.archetypeByMaskHash.get(e);if(o!==void 0)return {archId:o,created:false};let r=t.archetypes.length,s={id:r,mask:g(n),size:0,capacity:16,entities:new Uint32Array(16),entityRow:new Map,componentBits:ct(n),edgeAdd:new Int32Array(t.options.maxComponents).fill(-1),edgeRemove:new Int32Array(t.options.maxComponents).fill(-1)};return t.archetypes.push(s),t.archetypeByMaskHash.set(e,r),t.queryVersion++,{archId:r,created:true}}function S(t,n){if(n<=t.capacity)return;let e=t.capacity;for(;e<n;)e*=2;let o=new Uint32Array(e);o.set(t.entities),t.entities=o,t.capacity=e;}function ct(t){let n=[];for(let e=0;e<t.length;e++){let o=t[e]??0;for(;o!==0;){let r=o&-o,s=(e<<5)+(31-Math.clz32(r));n.push(s),o&=o-1;}}return n}function T(t,n){let e=t.componentBitFor.get(n.id);if(e!==void 0)return e;if(t.nextComponentBit>=t.options.maxComponents)throw new Error(`aiecsjs: world reached maxComponents=${t.options.maxComponents}`);let o=t.nextComponentBit++;t.componentBitFor.set(n.id,o),t.componentInfoByBit[o]=n;let r;if(n.kind==="soa"){let s={};for(let i of n.fields)s[i.name]=new i.ctor(t.capacity*i.vectorLen);r={kind:"soa",componentId:n.id,bit:o,soa:s};}else n.kind==="aos"?r={kind:"aos",componentId:n.id,bit:o,aos:new Array(t.capacity)}:r={kind:"tag",componentId:n.id,bit:o};return t.componentStorageByBit[o]=r,o}function D(t,n){let e=t.options.maskWordCount,o=new Uint32Array(e),r=n*e;for(let s=0;s<e;s++)o[s]=t.entityMask[r+s]??0;return o}function F(t,n,e){let o=t.options.maskWordCount,r=n*o;for(let s=0;s<o;s++)t.entityMask[r+s]=e[s]??0;}function N(t){let n=u(t);if(n.readOnly)throw new Error("aiecsjs: cannot createEntity on a read-only world (worker-attached)");let e;if(n.freeList.length>0)e=n.freeList.pop();else {if(n.nextFreshIndex>=n.options.maxEntities)throw new Error(`aiecsjs: reached maxEntities ${n.options.maxEntities}`);n.nextFreshIndex>=n.capacity&&L(n,n.nextFreshIndex+1),e=n.nextFreshIndex++;}let o=n.archetypes[0];if(!o)throw new Error("aiecsjs: missing empty archetype");S(o,o.size+1);let r=o.size;o.entities[r]=e,o.entityRow.set(e,r),o.size++,n.entityArchetype[e]=0;let s=n.options.maskWordCount,i=e*s;for(let c=0;c<s;c++)n.entityMask[i+c]=0;return n.size++,e}function V(t,n){let e=u(t);return I(e,n)}function I(t,n){if(n<=0||n>=t.capacity)return false;let e=t.entityArchetype[n]??0,o=t.archetypes[e];return o?o.entityRow.has(n):false}var $=new Map;function q(t){let n=$.get(t.__id);if(!n)throw new Error("aiecsjs: component is not registered (call defineComponent/defineTag/defineObjectComponent)");return n}function H(t,n,e,o){let r=u(t);if(r.readOnly)throw new Error("aiecsjs: cannot mutate a read-only world");if(!I(r,n))throw new Error(`aiecsjs: addComponent on dead entity ${n}`);let s=q(e),i=T(r,s),c=D(r,n);if(O(c,i)){o!==void 0&&P(r,n,e,o);return}let a=g(c);M(a,i),ft(r,n,a),P(r,n,e,o);}function P(t,n,e,o){let r=q(e),s=t.componentBitFor.get(r.id);if(s===void 0)return;let i=t.componentStorageByBit[s];if(i){if(r.kind==="soa"&&i.soa){if(o==null)return;let c=o;for(let a of r.fields){if(!(a.name in c))continue;let f=i.soa[a.name];if(!f)continue;let d=c[a.name];if(a.vectorLen===1)f[n]=typeof d=="boolean"?d?1:0:Number(d);else if(Array.isArray(d)||ArrayBuffer.isView(d)){let l=n*a.vectorLen,y=d;for(let p=0;p<a.vectorLen;p++)f[l+p]=Number(y[p]??0);}}}else if(r.kind==="aos"&&i.aos){let c=r.factory??(()=>({})),a=i.aos[n];if(a===void 0&&(a=c(),i.aos[n]=a),o&&typeof o=="object"){let f=o,d=a;for(let l of Object.keys(f))l==="__proto__"||l==="constructor"||l==="prototype"||(d[l]=f[l]);}}}}function ft(t,n,e){let o=t.entityArchetype[n]??0,r=t.archetypes[o];if(!r)return;let i=z(t,e).archId,c=t.archetypes[i];if(c){if(i!==o){let a=r.entityRow.get(n);if(a!==void 0){let d=r.size-1;if(a!==d){let l=r.entities[d]??0;r.entities[a]=l,r.entityRow.set(l,a);}r.entities[d]=0,r.entityRow.delete(n),r.size--;}S(c,c.size+1);let f=c.size;c.entities[f]=n,c.entityRow.set(n,f),c.size++,t.entityArchetype[n]=i;}F(t,n,e);}}function G(t){return $.get(t)}var m="AIEC",J=1;function Y(t,n){let e=yt(t);return wt(e)}function v(t,n){let e=bt(t);return mt(e)}function yt(t){let n=u(t),e=[];for(let o=1;o<n.capacity;o++){if(!V(t,o)||(n.entityArchetype[o]??0)===0)continue;let s=n.options.maskWordCount,i=o*s,c=[];for(let a=0;a<s;a++){let f=n.entityMask[i+a]??0;for(;f!==0;){let d=f&-f,l=(a<<5)+(31-Math.clz32(d)),y=n.componentInfoByBit[l];if(y){let p=n.componentStorageByBit[l],A=null;if(y.kind==="soa"&&p?.soa){let x={};for(let h of y.fields){let k=p.soa[h.name];if(k)if(h.vectorLen===1)x[h.name]=k[o];else {let B=[],Z=o*h.vectorLen;for(let W=0;W<h.vectorLen;W++)B.push(k[Z+W]??0);x[h.name]=B;}}A=x;}else y.kind==="aos"&&p?.aos?A=p.aos[o]??null:A=true;c.push({kind:y.kind,id:y.id,data:A});}f&=f-1;}}e.push({eid:o,components:c});}return {version:n.version,capacity:n.capacity,entities:e}}function mt(t){let n=j({initialCapacity:t.capacity}),e=new Map;for(let o of t.entities){let r=N(n);e.set(o.eid,r);}for(let o of t.entities){let r=e.get(o.eid);for(let s of o.components){let i=G(s.id);if(!i)continue;let c=ht(i);c&&H(n,r,c,s.data);}}return n}function ht(t){if(t.kind==="soa")return {__kind:"soa",__id:t.id,__schema:t.schema??{}};if(t.kind==="aos"){let n=t.factory??(()=>({}));return {__kind:"aos",__id:t.id,__factory:n}}return {__kind:"tag",__id:t.id}}function wt(t){let n=JSON.stringify(t),e=new TextEncoder().encode(n),o=new TextEncoder().encode(w),s=12+o.length+4+e.length,i=new Uint8Array(s),c=new DataView(i.buffer),a=0;return i[a++]=m.charCodeAt(0),i[a++]=m.charCodeAt(1),i[a++]=m.charCodeAt(2),i[a++]=m.charCodeAt(3),c.setUint32(a,J,true),a+=4,c.setUint32(a,o.length,true),a+=4,i.set(o,a),a+=o.length,c.setUint32(a,e.length,true),a+=4,i.set(e,a),i}function bt(t,n){if(t.length<12)throw new Error("aiecsjs: bytes too short to be a valid snapshot");let e=new DataView(t.buffer,t.byteOffset,t.byteLength);if(t[0]!==m.charCodeAt(0)||t[1]!==m.charCodeAt(1)||t[2]!==m.charCodeAt(2)||t[3]!==m.charCodeAt(3))throw new Error("aiecsjs: invalid magic bytes");let o=4,r=e.getUint32(o,true);o+=4;let s="throw";if(r!==J&&s==="throw")throw new Error(`aiecsjs: format version ${r} not supported`);let i=64*1024*1024;if(o+4>t.length)throw new Error("aiecsjs: snapshot truncated before verLen");let c=e.getUint32(o,true);if(o+=4,c>i||o+c>t.length)throw new Error(`aiecsjs: snapshot verLen=${c} out of bounds`);if(o+=c,o+4>t.length)throw new Error("aiecsjs: snapshot truncated before jsonLen");let a=e.getUint32(o,true);if(o+=4,a>i||o+a>t.length)throw new Error(`aiecsjs: snapshot jsonLen=${a} out of bounds`);let f=t.subarray(o,o+a),d=new TextDecoder().decode(f);return JSON.parse(d)}var Q=1095320899;function Yt(t){let n=u(t),e=Y(t);if(typeof SharedArrayBuffer>"u"){let r=new ArrayBuffer(e.byteLength);return new Uint8Array(r).set(e),{buffer:r,meta:X(n)}}let o=new SharedArrayBuffer(e.byteLength);return new Uint8Array(o).set(e),{buffer:o,meta:X(n)}}function Xt(t){At(t.meta);let n=new Uint8Array(t.buffer);return v(n)}function Qt(t,n){let e=new Uint8Array(t),o=v(e);if(n?.readOnly){let r=u(o);r.readOnly=true;}return o}function Zt(t){_(t.id)&&R(t);}function X(t){let n=[];for(let e of t.componentInfoByBit)e&&n.push({id:e.id,kind:e.kind,schema:e.schema});return {magic:Q,formatVersion:1,aiecsjsVersion:w,indexBits:t.options.indexBits,generationBits:t.options.generationBits,maxComponents:t.options.maxComponents,maskWordCount:t.options.maskWordCount,capacity:t.capacity,componentSchemas:n}}function At(t){if(t.magic!==Q)throw new Error("aiecsjs: invalid snapshot meta (wrong magic)");if(t.formatVersion!==1)throw new Error(`aiecsjs: unsupported snapshot format version ${t.formatVersion}`)}exports.adoptSnapshot=Xt;exports.attachWorld=Qt;exports.detachWorld=Zt;exports.transferableSnapshot=Yt;//# sourceMappingURL=worker.cjs.map
1
+ 'use strict';var chunkAGHSWLNQ_cjs=require('./chunk-AGHSWLNQ.cjs'),chunk4RPFOVQC_cjs=require('./chunk-4RPFOVQC.cjs');var l=1095320899;function W(r){let e=chunk4RPFOVQC_cjs.i(r),o=chunkAGHSWLNQ_cjs.a(r);if(typeof SharedArrayBuffer>"u"){let n=new ArrayBuffer(o.byteLength);return new Uint8Array(n).set(o),{buffer:n,meta:p(e)}}let t=new SharedArrayBuffer(o.byteLength);return new Uint8Array(t).set(o),{buffer:t,meta:p(e)}}function b(r){m(r.meta);let e=new Uint8Array(r.buffer);return chunkAGHSWLNQ_cjs.b(e)}function S(r,e){let o=new Uint8Array(r),t=chunkAGHSWLNQ_cjs.b(o);if(e?.readOnly){let n=chunk4RPFOVQC_cjs.i(t);n.readOnly=true;}return t}function w(r){chunk4RPFOVQC_cjs.j(r.id)&&chunk4RPFOVQC_cjs.l(r);}function p(r){let e=[];for(let o of r.componentInfoByBit)o&&e.push({id:o.id,kind:o.kind,schema:o.schema});return {magic:l,formatVersion:1,aiecsjsVersion:chunk4RPFOVQC_cjs.a,indexBits:r.options.indexBits,generationBits:r.options.generationBits,maxComponents:r.options.maxComponents,maskWordCount:r.options.maskWordCount,capacity:r.capacity,componentSchemas:e}}function m(r){if(r.magic!==l)throw new Error("aiecsjs: invalid snapshot meta (wrong magic)");if(r.formatVersion!==1)throw new Error(`aiecsjs: unsupported snapshot format version ${r.formatVersion}`)}exports.adoptSnapshot=b;exports.attachWorld=S;exports.detachWorld=w;exports.transferableSnapshot=W;//# sourceMappingURL=worker.cjs.map
2
2
  //# sourceMappingURL=worker.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/version.ts","../src/internal/bitmask.ts","../src/internal/world.ts","../src/internal/entity.ts","../src/internal/component.ts","../src/serialize.ts","../src/worker.ts"],"names":["VERSION","createMask","wordCount","setBit","mask","bit","w","testBit","cloneMask","src","out","i","maskHash","m","parts","DEFAULT_OPTIONS","DEFAULT_MAX_COMPONENTS","nextWorldId","worldRegistry","getWorldState","world","state","registerWorld","unregisterWorld","id","isWorldRegistered","resolveOptions","opts","o","indexBits","generationBits","maxComponents","maxByIndex","initialCapacity","maxEntities","createEmptyArchetype","maskWordCount","createWorld","options","resolved","generationCtor","generations","empty","makePublicWorld","destroyWorld","ensureCapacity","needed","newCap","growEntityArrays","genCtor","newGen","newArch","newMask","storage","info","growSoAColumns","soa","fields","f","old","newLen","next","findOrCreateArchetype","key","existing","arch","collectBits","ensureArchetypeCapacity","bits","word","lsb","getOrRegisterComponentBit","readEntityMask","eid","base","writeEntityMask","createEntity","row","entityExists","isAliveInternal","archId","componentInfoById","getComponentInfo","component","addComponent","initial","prevMask","writeInitial","migrateEntity","obj","col","val","arr","factory","inst","target","srcArchId","srcArch","destArchId","destArch","lastRow","moved","newRow","getComponentByInternalId","MAGIC","FORMAT_VERSION","serializeWorld","snapshot","toJSON","packBinary","deserializeWorld","bytes","unpackBinary","fromJSON","entities","components","wi","data","baseI","eidMap","e","comp","handle","getComponentHandle","json","jsonBytes","versionBytes","total","view","off","formatVersion","onUnknown","MAX_FIELD_LEN","verLen","jsonLen","transferableSnapshot","ab","buildMeta","sab","adoptSnapshot","snap","validateMeta","attachWorld","buffer","detachWorld","componentSchemas","meta"],"mappings":"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","file":"worker.cjs","sourcesContent":["export const VERSION = '0.2.1'\n","// Multi-word Uint32 bitmask helpers.\n\nexport function createMask(wordCount: number): Uint32Array {\n return new Uint32Array(wordCount)\n}\n\nexport function setBit(mask: Uint32Array, bit: number): void {\n const w = bit >>> 5\n mask[w] = (mask[w] ?? 0) | (1 << (bit & 31))\n}\n\nexport function clearBit(mask: Uint32Array, bit: number): void {\n const w = bit >>> 5\n mask[w] = (mask[w] ?? 0) & ~(1 << (bit & 31))\n}\n\nexport function testBit(mask: Uint32Array, bit: number): boolean {\n const w = bit >>> 5\n return ((mask[w] ?? 0) & (1 << (bit & 31))) !== 0\n}\n\nexport function copyMask(dst: Uint32Array, src: Uint32Array): void {\n const n = src.length\n for (let i = 0; i < n; i++) dst[i] = src[i] ?? 0\n}\n\nexport function cloneMask(src: Uint32Array): Uint32Array {\n const out = new Uint32Array(src.length)\n for (let i = 0; i < src.length; i++) out[i] = src[i] ?? 0\n return out\n}\n\nexport function maskEquals(a: Uint32Array, b: Uint32Array): boolean {\n const n = a.length\n if (b.length !== n) return false\n for (let i = 0; i < n; i++) if ((a[i] ?? 0) !== (b[i] ?? 0)) return false\n return true\n}\n\nexport function maskHash(m: Uint32Array): string {\n // Stable string key for Map lookups. Hex-joined.\n const parts: string[] = []\n for (let i = 0; i < m.length; i++) {\n parts.push((m[i] ?? 0).toString(16))\n }\n return parts.join(',')\n}\n\nexport function isMaskZero(m: Uint32Array): boolean {\n for (let i = 0; i < m.length; i++) if ((m[i] ?? 0) !== 0) return false\n return true\n}\n\nexport function unionMask(a: Uint32Array, b: Uint32Array): Uint32Array {\n const out = new Uint32Array(a.length)\n for (let i = 0; i < a.length; i++) out[i] = (a[i] ?? 0) | (b[i] ?? 0)\n return out\n}\n\n/**\n * Test whether an archetype's mask matches a query.\n * - withMask: all of these bits must be present\n * - anyMask: if anyHasBits, at least one of these bits must be present\n * - noneMask: none of these bits may be present\n */\nexport function matches(\n mask: Uint32Array,\n withMask: Uint32Array,\n anyMask: Uint32Array,\n noneMask: Uint32Array,\n anyHasBits: boolean,\n words: number,\n): boolean {\n let anyHit = !anyHasBits\n for (let w = 0; w < words; w++) {\n const m = mask[w] ?? 0\n const wm = withMask[w] ?? 0\n const am = anyMask[w] ?? 0\n const nm = noneMask[w] ?? 0\n if ((m & wm) !== wm) return false\n if ((m & nm) !== 0) return false\n if (!anyHit && (m & am) !== 0) anyHit = true\n }\n return anyHit\n}\n\nexport function listBits(mask: Uint32Array): number[] {\n const out: number[] = []\n for (let w = 0; w < mask.length; w++) {\n let word = mask[w] ?? 0\n while (word !== 0) {\n const bit = (w << 5) + ctz32(word)\n out.push(bit)\n word &= word - 1\n }\n }\n return out\n}\n\n// Iterate set bits in a slice of a larger Uint32Array starting at `base`.\n// Shared by destroy paths and storage cleanup so the bit-extraction maths\n// lives in exactly one place.\nexport function forEachSetBit(\n mask: Uint32Array,\n base: number,\n words: number,\n fn: (bit: number) => void,\n): void {\n for (let wi = 0; wi < words; wi++) {\n let word = mask[base + wi] ?? 0\n while (word !== 0) {\n const bit = (wi << 5) + ctz32(word)\n fn(bit)\n word &= word - 1\n }\n }\n}\n\n// Match a query against an entity's mask stored as a slice inside a larger\n// Uint32Array. Reading directly from the parent array avoids the temporary\n// Uint32Array allocation on every observer dispatch.\nexport function matchesEntityMask(\n entityMask: Uint32Array,\n base: number,\n words: number,\n withMask: Uint32Array,\n anyMask: Uint32Array,\n noneMask: Uint32Array,\n anyHasBits: boolean,\n): boolean {\n let anyHit = !anyHasBits\n for (let i = 0; i < words; i++) {\n const m = entityMask[base + i] ?? 0\n const wm = withMask[i] ?? 0\n const am = anyMask[i] ?? 0\n const nm = noneMask[i] ?? 0\n if ((m & wm) !== wm) return false\n if ((m & nm) !== 0) return false\n if (!anyHit && (m & am) !== 0) anyHit = true\n }\n return anyHit\n}\n\nfunction ctz32(v: number): number {\n // Count trailing zeros in a 32-bit integer (assumes v !== 0)\n return 31 - Math.clz32(v & -v)\n}\n","import { VERSION } from '../version.js'\nimport { cloneMask, copyMask, createMask, maskHash } from './bitmask.js'\nimport type {\n ArchetypeState,\n ComponentInfo,\n FieldInfo,\n ResolvedWorldOptions,\n World,\n WorldComponentStorage,\n WorldOptions,\n WorldState,\n} from './types.js'\n\nexport const WORLD_BRAND = Symbol.for('aiecsjs.world')\n\nconst DEFAULT_OPTIONS: Required<Omit<WorldOptions, 'buffer' | 'bufferByteOffset'>> = {\n initialCapacity: 1024,\n maxEntities: 1_000_000,\n indexBits: 24,\n generationBits: 8,\n}\n\nconst DEFAULT_MAX_COMPONENTS = 256\n\nlet nextWorldId = 1\nconst worldRegistry = new Map<number, WorldState>()\n\nexport function getWorldState(world: World): WorldState {\n const state = worldRegistry.get(world.id)\n if (!state) throw new Error(`aiecsjs: world ${world.id} is destroyed or unknown`)\n if (state.destroyed) throw new Error(`aiecsjs: world ${world.id} is destroyed`)\n return state\n}\n\nexport function registerWorld(state: WorldState): void {\n worldRegistry.set(state.id, state)\n}\n\nexport function unregisterWorld(id: number): void {\n worldRegistry.delete(id)\n}\n\nexport function isWorldRegistered(id: number): boolean {\n return worldRegistry.has(id)\n}\n\nfunction resolveOptions(opts: WorldOptions | undefined): ResolvedWorldOptions {\n const o = opts ?? {}\n const indexBits = o.indexBits ?? DEFAULT_OPTIONS.indexBits\n const generationBits = o.generationBits ?? DEFAULT_OPTIONS.generationBits\n const maxComponents = DEFAULT_MAX_COMPONENTS\n if (indexBits < 1 || indexBits > 24) {\n throw new Error('aiecsjs: indexBits must be in [1, 24]')\n }\n if (generationBits < 0 || generationBits > 16) {\n throw new Error('aiecsjs: generationBits must be in [0, 16]')\n }\n const maxByIndex = 1 << indexBits\n const initialCapacity = Math.max(\n 1,\n Math.min(o.initialCapacity ?? DEFAULT_OPTIONS.initialCapacity, maxByIndex),\n )\n const maxEntities = Math.max(\n initialCapacity,\n Math.min(o.maxEntities ?? DEFAULT_OPTIONS.maxEntities, maxByIndex),\n )\n return {\n initialCapacity,\n maxEntities,\n indexBits,\n generationBits,\n maxComponents,\n maskWordCount: Math.ceil(maxComponents / 32),\n buffer: o.buffer ?? null,\n bufferByteOffset: o.bufferByteOffset ?? 0,\n }\n}\n\nexport function createEmptyArchetype(maskWordCount: number, maxComponents: number): ArchetypeState {\n return {\n id: 0,\n mask: createMask(maskWordCount),\n size: 0,\n capacity: 16,\n entities: new Uint32Array(16),\n entityRow: new Map<number, number>(),\n componentBits: [],\n edgeAdd: new Int32Array(maxComponents).fill(-1),\n edgeRemove: new Int32Array(maxComponents).fill(-1),\n }\n}\n\nexport function createWorld(options?: WorldOptions): World {\n const resolved = resolveOptions(options)\n const id = nextWorldId++\n\n const generationCtor = resolved.generationBits > 8 ? Uint16Array : Uint8Array\n const generations = new generationCtor(resolved.initialCapacity)\n\n const state: WorldState = {\n id,\n capacity: resolved.initialCapacity,\n version: VERSION,\n options: resolved,\n size: 0,\n nextFreshIndex: 1, // 0 reserved\n freeList: [],\n generations,\n destroyed: false,\n componentBitFor: new Map<number, number>(),\n componentInfoByBit: new Array(resolved.maxComponents).fill(null),\n componentStorageByBit: new Array(resolved.maxComponents).fill(null),\n nextComponentBit: 0,\n entityArchetype: new Uint32Array(resolved.initialCapacity),\n entityMask: new Uint32Array(resolved.initialCapacity * resolved.maskWordCount),\n archetypes: [],\n archetypeByMaskHash: new Map<string, number>(),\n queryVersion: 0,\n queries: [],\n queryMasks: new Map(),\n queryArchetypeCache: [],\n queryArchetypeStamp: [],\n bitToQueries: new Map<number, Set<number>>(),\n reactiveBuffers: new Map(),\n observers: [],\n relationStorage: new Map(),\n sab: resolved.buffer,\n readOnly: false,\n }\n\n // Seed archetype 0 (the empty mask)\n const empty = createEmptyArchetype(resolved.maskWordCount, resolved.maxComponents)\n empty.id = 0\n state.archetypes.push(empty)\n state.archetypeByMaskHash.set(maskHash(empty.mask), 0)\n\n registerWorld(state)\n return makePublicWorld(state)\n}\n\nexport function makePublicWorld(state: WorldState): World {\n return {\n id: state.id,\n get capacity() {\n return state.capacity\n },\n version: state.version,\n } as World\n}\n\nexport function destroyWorld(world: World): void {\n const state = worldRegistry.get(world.id)\n if (!state || state.destroyed) return\n state.destroyed = true\n // Clear large buffers to help GC\n state.archetypes = []\n state.archetypeByMaskHash.clear()\n state.componentInfoByBit = []\n state.componentStorageByBit = []\n state.queries = []\n state.queryMasks.clear()\n state.queryArchetypeCache = []\n state.observers = []\n state.relationStorage.clear()\n state.reactiveBuffers.clear()\n unregisterWorld(world.id)\n}\n\nexport function resetWorld(world: World): void {\n const state = getWorldState(world)\n // Keep capacity and registered components; clear entities and per-entity state.\n state.size = 0\n state.nextFreshIndex = 1\n state.freeList = []\n state.generations.fill(0)\n state.entityArchetype.fill(0)\n state.entityMask.fill(0)\n // Wipe archetype memberships but keep archetype graph for stability.\n for (const arch of state.archetypes) {\n arch.size = 0\n arch.entityRow.clear()\n }\n // Clear SoA columns and AoS instances; storage allocation is preserved.\n for (const storage of state.componentStorageByBit) {\n if (!storage) continue\n if (storage.kind === 'soa' && storage.soa) {\n for (const k of Object.keys(storage.soa)) {\n storage.soa[k]?.fill(0)\n }\n } else if (storage.kind === 'aos' && storage.aos) {\n storage.aos.fill(undefined as unknown as never)\n }\n }\n state.queryVersion++\n for (const buf of state.reactiveBuffers.values()) {\n buf.entered.length = 0\n buf.exited.length = 0\n }\n}\n\nexport function getWorldSize(world: World): number {\n return getWorldState(world).size\n}\n\nexport function getWorldCapacity(world: World): number {\n return getWorldState(world).capacity\n}\n\n// --- Capacity growth ---\n\nexport function ensureCapacity(state: WorldState, needed: number): void {\n if (needed <= state.capacity) return\n if (needed > state.options.maxEntities) {\n throw new Error(\n `aiecsjs: requested capacity ${needed} exceeds maxEntities ${state.options.maxEntities}`,\n )\n }\n let newCap = state.capacity\n while (newCap < needed) newCap = Math.min(newCap * 2, state.options.maxEntities)\n growEntityArrays(state, newCap)\n}\n\nfunction growEntityArrays(state: WorldState, newCap: number): void {\n // generations\n const genCtor: any = state.generations.constructor\n const newGen = new genCtor(newCap) as Uint8Array | Uint16Array\n ;(newGen as Uint8Array).set(state.generations as Uint8Array)\n state.generations = newGen\n\n // entityArchetype\n const newArch = new Uint32Array(newCap)\n newArch.set(state.entityArchetype)\n state.entityArchetype = newArch\n\n // entityMask\n const wordCount = state.options.maskWordCount\n const newMask = new Uint32Array(newCap * wordCount)\n newMask.set(state.entityMask)\n state.entityMask = newMask\n\n // Component storages (SoA columns + AoS arrays)\n for (const storage of state.componentStorageByBit) {\n if (!storage) continue\n if (storage.kind === 'soa' && storage.soa) {\n const info = state.componentInfoByBit[storage.bit]\n if (info) growSoAColumns(storage.soa, info.fields, newCap)\n } else if (storage.kind === 'aos' && storage.aos) {\n storage.aos.length = newCap\n }\n }\n\n state.capacity = newCap\n}\n\nfunction growSoAColumns(soa: Record<string, any>, fields: FieldInfo[], newCap: number): void {\n for (const f of fields) {\n const old = soa[f.name]\n if (!old) continue\n const newLen = newCap * f.vectorLen\n if (old.length >= newLen) continue\n const next = new f.ctor(newLen)\n next.set(old)\n soa[f.name] = next\n }\n}\n\n// --- Archetype management ---\n\nexport function findOrCreateArchetype(\n state: WorldState,\n mask: Uint32Array,\n): { archId: number; created: boolean } {\n const key = maskHash(mask)\n const existing = state.archetypeByMaskHash.get(key)\n if (existing !== undefined) return { archId: existing, created: false }\n\n const id = state.archetypes.length\n const arch: ArchetypeState = {\n id,\n mask: cloneMask(mask),\n size: 0,\n capacity: 16,\n entities: new Uint32Array(16),\n entityRow: new Map<number, number>(),\n componentBits: collectBits(mask),\n edgeAdd: new Int32Array(state.options.maxComponents).fill(-1),\n edgeRemove: new Int32Array(state.options.maxComponents).fill(-1),\n }\n state.archetypes.push(arch)\n state.archetypeByMaskHash.set(key, id)\n state.queryVersion++\n return { archId: id, created: true }\n}\n\nexport function ensureArchetypeCapacity(arch: ArchetypeState, needed: number): void {\n if (needed <= arch.capacity) return\n let newCap = arch.capacity\n while (newCap < needed) newCap *= 2\n const next = new Uint32Array(newCap)\n next.set(arch.entities)\n arch.entities = next\n arch.capacity = newCap\n}\n\nfunction collectBits(mask: Uint32Array): number[] {\n const bits: number[] = []\n for (let w = 0; w < mask.length; w++) {\n let word = mask[w] ?? 0\n while (word !== 0) {\n const lsb = word & -word\n const bit = (w << 5) + (31 - Math.clz32(lsb))\n bits.push(bit)\n word &= word - 1\n }\n }\n return bits\n}\n\n// --- Component registration in a world ---\n\nexport function getOrRegisterComponentBit(state: WorldState, info: ComponentInfo): number {\n const existing = state.componentBitFor.get(info.id)\n if (existing !== undefined) return existing\n\n if (state.nextComponentBit >= state.options.maxComponents) {\n throw new Error(`aiecsjs: world reached maxComponents=${state.options.maxComponents}`)\n }\n const bit = state.nextComponentBit++\n state.componentBitFor.set(info.id, bit)\n state.componentInfoByBit[bit] = info\n\n // Create storage\n let storage: WorldComponentStorage\n if (info.kind === 'soa') {\n const soa: Record<string, any> = {}\n for (const f of info.fields) {\n soa[f.name] = new f.ctor(state.capacity * f.vectorLen)\n }\n storage = { kind: 'soa', componentId: info.id, bit, soa }\n } else if (info.kind === 'aos') {\n storage = { kind: 'aos', componentId: info.id, bit, aos: new Array(state.capacity) }\n } else {\n storage = { kind: 'tag', componentId: info.id, bit }\n }\n state.componentStorageByBit[bit] = storage\n return bit\n}\n\n// Read a bitmask out of state.entityMask[] into a fresh Uint32Array.\nexport function readEntityMask(state: WorldState, eid: number): Uint32Array {\n const w = state.options.maskWordCount\n const out = new Uint32Array(w)\n const base = eid * w\n for (let i = 0; i < w; i++) out[i] = state.entityMask[base + i] ?? 0\n return out\n}\n\nexport function writeEntityMask(state: WorldState, eid: number, mask: Uint32Array): void {\n const w = state.options.maskWordCount\n const base = eid * w\n for (let i = 0; i < w; i++) state.entityMask[base + i] = mask[i] ?? 0\n}\n\n// Get the bit of a component within a world without registering.\nexport function tryGetComponentBit(state: WorldState, info: ComponentInfo): number | undefined {\n return state.componentBitFor.get(info.id)\n}\n\nexport function isWorld(x: unknown): x is World {\n if (!x || typeof x !== 'object') return false\n const obj = x as { id?: unknown; version?: unknown }\n if (typeof obj.id !== 'number') return false\n if (typeof obj.version !== 'string') return false\n return worldRegistry.has(obj.id)\n}\n","import { clearAllEntityStorages } from './component.js'\nimport type { EntityId, World, WorldState } from './types.js'\nimport { ensureArchetypeCapacity, ensureCapacity, getWorldState } from './world.js'\n\nexport function createEntity(world: World): EntityId {\n const state = getWorldState(world)\n if (state.readOnly) {\n throw new Error('aiecsjs: cannot createEntity on a read-only world (worker-attached)')\n }\n\n let eid: number\n if (state.freeList.length > 0) {\n eid = state.freeList.pop()!\n } else {\n if (state.nextFreshIndex >= state.options.maxEntities) {\n throw new Error(`aiecsjs: reached maxEntities ${state.options.maxEntities}`)\n }\n if (state.nextFreshIndex >= state.capacity) {\n ensureCapacity(state, state.nextFreshIndex + 1)\n }\n eid = state.nextFreshIndex++\n }\n\n // Move into the empty archetype (0)\n const arch = state.archetypes[0]\n if (!arch) throw new Error('aiecsjs: missing empty archetype')\n ensureArchetypeCapacity(arch, arch.size + 1)\n const row = arch.size\n arch.entities[row] = eid\n arch.entityRow.set(eid, row)\n arch.size++\n\n state.entityArchetype[eid] = 0\n // Reset entityMask row for this eid\n const w = state.options.maskWordCount\n const base = eid * w\n for (let i = 0; i < w; i++) state.entityMask[base + i] = 0\n\n state.size++\n return eid as EntityId\n}\n\nexport function destroyEntity(world: World, eid: EntityId): void {\n const state = getWorldState(world)\n if (state.readOnly) {\n throw new Error('aiecsjs: cannot destroyEntity on a read-only world')\n }\n if (!isAliveInternal(state, eid)) return\n\n // Fire onRemove for every component the entity has, plus reactive exit\n // (Late-bound to avoid circular imports — done via observers module.)\n const { dispatchDestroyObservers } = lazyObservers()\n dispatchDestroyObservers(state, eid)\n\n // Clean up relations referring to this entity\n cleanupRelationsOnDestroy(state, eid)\n\n // Zero the SoA columns / undefine the AoS slots the entity owned, before\n // the mask is cleared. Without this, destroyed entities leave stale data\n // visible to snapshots and serialisation.\n clearAllEntityStorages(state, eid)\n\n // Swap-pop from its archetype\n const archId = state.entityArchetype[eid] ?? 0\n const arch = state.archetypes[archId]\n if (arch) {\n const row = arch.entityRow.get(eid)\n if (row !== undefined) {\n const lastRow = arch.size - 1\n if (row !== lastRow) {\n const moved = arch.entities[lastRow] ?? 0\n arch.entities[row] = moved\n arch.entityRow.set(moved, row)\n }\n arch.entities[lastRow] = 0\n arch.entityRow.delete(eid)\n arch.size--\n }\n }\n\n // Wipe state\n state.entityArchetype[eid] = 0\n const w = state.options.maskWordCount\n const base = eid * w\n for (let i = 0; i < w; i++) state.entityMask[base + i] = 0\n // bump generation (Uint8Array wraps to 8 bits naturally; Uint16Array to 16)\n const idx = eid as number\n state.generations[idx] = ((state.generations[idx] ?? 0) + 1) & 0xffff\n\n state.freeList.push(eid)\n state.size--\n}\n\nexport function entityExists(world: World, eid: EntityId): boolean {\n const state = getWorldState(world)\n return isAliveInternal(state, eid)\n}\n\nexport function isAliveInternal(state: WorldState, eid: number): boolean {\n if (eid <= 0) return false\n if (eid >= state.capacity) return false\n // An entity is alive iff it is in some archetype (its row map points somewhere).\n const archId = state.entityArchetype[eid] ?? 0\n const arch = state.archetypes[archId]\n if (!arch) return false\n return arch.entityRow.has(eid)\n}\n\nexport function getEntityIndex(eid: EntityId): number {\n return eid as number\n}\n\nexport function getEntityGeneration(_eid: EntityId): number {\n // Unversioned in 0.1: generation not encoded in EntityId.\n return 0\n}\n\nexport function packEntity(index: number, _generation: number): EntityId {\n // Identity in 0.1.\n return index as EntityId\n}\n\nexport function isEntity(world: World, x: unknown): x is EntityId {\n if (typeof x !== 'number') return false\n return entityExists(world, x as EntityId)\n}\n\n// --- Lazy loaders to break import cycles ---\n\ninterface ObserversAPI {\n dispatchDestroyObservers(state: WorldState, eid: EntityId): void\n}\nlet _observersAPI: ObserversAPI | null = null\nexport function registerObserversAPI(api: ObserversAPI): void {\n _observersAPI = api\n}\nfunction lazyObservers(): ObserversAPI {\n if (!_observersAPI) {\n return { dispatchDestroyObservers: () => {} }\n }\n return _observersAPI\n}\n\nlet _relationsCleanup: ((state: WorldState, eid: EntityId) => void) | null = null\nexport function registerRelationsCleanup(fn: (state: WorldState, eid: EntityId) => void): void {\n _relationsCleanup = fn\n}\nfunction cleanupRelationsOnDestroy(state: WorldState, eid: EntityId): void {\n if (_relationsCleanup) _relationsCleanup(state, eid)\n}\n","import { clearBit, cloneMask, forEachSetBit, setBit, testBit } from './bitmask.js'\nimport { isAliveInternal } from './entity.js'\nimport type {\n AoSComponent,\n ComponentInfo,\n ComponentInit,\n ComponentLike,\n EntityId,\n FieldInfo,\n SoAColumns,\n SoAComponent,\n SoASchema,\n TagComponent,\n TypedArrayConstructor,\n World,\n WorldComponentStorage,\n WorldState,\n} from './types.js'\nimport {\n ensureArchetypeCapacity,\n findOrCreateArchetype,\n getOrRegisterComponentBit,\n getWorldState,\n readEntityMask,\n tryGetComponentBit,\n writeEntityMask,\n} from './world.js'\n\n// --- Component factories ---\n\nlet nextComponentId = 1\n\nconst TYPE_CTOR: Record<string, TypedArrayConstructor> = {\n i8: Int8Array,\n u8: Uint8Array,\n i16: Int16Array,\n u16: Uint16Array,\n i32: Int32Array,\n u32: Uint32Array,\n f32: Float32Array,\n f64: Float64Array,\n eid: Uint32Array,\n bool: Uint8Array,\n}\n\nconst componentInfoById = new Map<number, ComponentInfo>()\n\nexport function defineComponent<S extends SoASchema>(schema: S): SoAComponent<S> {\n const fields: FieldInfo[] = []\n for (const [name, decl] of Object.entries(schema)) {\n let type: keyof typeof TYPE_CTOR\n let vectorLen = 1\n if (typeof decl === 'string') {\n type = decl\n } else if (Array.isArray(decl)) {\n const [t, len] = decl\n type = t\n vectorLen = len\n } else {\n throw new TypeError(`aiecsjs: invalid field declaration for \"${name}\"`)\n }\n const ctor = TYPE_CTOR[type]\n if (!ctor) throw new TypeError(`aiecsjs: unknown field type \"${type}\" for field \"${name}\"`)\n fields.push({\n name,\n type: type as any,\n vectorLen,\n ctor,\n bytesPerElement: (ctor as any).BYTES_PER_ELEMENT,\n })\n }\n const id = nextComponentId++\n const info: ComponentInfo = { id, kind: 'soa', schema, fields, factory: null }\n componentInfoById.set(id, info)\n const handle: SoAComponent<S> = {\n __kind: 'soa',\n __id: id,\n __schema: schema,\n }\n return handle\n}\n\nexport function defineTag(): TagComponent {\n const id = nextComponentId++\n const info: ComponentInfo = { id, kind: 'tag', schema: null, fields: [], factory: null }\n componentInfoById.set(id, info)\n return { __kind: 'tag', __id: id }\n}\n\nexport function defineObjectComponent<T>(factory?: () => T): AoSComponent<T> {\n const id = nextComponentId++\n const fac = factory ?? (() => ({}) as T)\n const info: ComponentInfo = { id, kind: 'aos', schema: null, fields: [], factory: fac as any }\n componentInfoById.set(id, info)\n return { __kind: 'aos', __id: id, __factory: fac }\n}\n\nexport function getComponentInfo(component: ComponentLike): ComponentInfo {\n const info = componentInfoById.get(component.__id)\n if (!info)\n throw new Error(\n 'aiecsjs: component is not registered (call defineComponent/defineTag/defineObjectComponent)',\n )\n return info\n}\n\n// --- Component ops on entities ---\n\nexport function addComponent<C extends ComponentLike>(\n world: World,\n eid: EntityId,\n component: C,\n initial?: ComponentInit<C>,\n): void {\n const state = getWorldState(world)\n if (state.readOnly) throw new Error('aiecsjs: cannot mutate a read-only world')\n if (!isAliveInternal(state, eid)) {\n throw new Error(`aiecsjs: addComponent on dead entity ${eid}`)\n }\n const info = getComponentInfo(component)\n const bit = getOrRegisterComponentBit(state, info)\n\n const prevMask = readEntityMask(state, eid)\n if (testBit(prevMask, bit)) {\n if (initial !== undefined) writeInitial(state, eid, component, initial)\n return\n }\n const newMask = cloneMask(prevMask)\n setBit(newMask, bit)\n migrateEntity(state, eid, newMask)\n\n writeInitial(state, eid, component, initial)\n\n fireAddObservers(state, eid, bit)\n notifyMaskChange(state, eid, bit, prevMask, newMask)\n}\n\nexport function removeComponent<C extends ComponentLike>(\n world: World,\n eid: EntityId,\n component: C,\n): void {\n const state = getWorldState(world)\n if (state.readOnly) throw new Error('aiecsjs: cannot mutate a read-only world')\n if (!isAliveInternal(state, eid)) return\n const info = getComponentInfo(component)\n const bit = tryGetComponentBit(state, info)\n if (bit === undefined) return\n const prevMask = readEntityMask(state, eid)\n if (!testBit(prevMask, bit)) return\n\n // Write the new mask BEFORE firing observers so query-targeted observers\n // reading `state.entityMask` see the post-removal state (and thus correctly\n // detect \"entity left this query\"). Without this reorder, a query that\n // requires the removed component would still match during dispatch and the\n // remove observer would never fire. Component-targeted observers receive the\n // bit directly and don't depend on mask timing. addComponent already follows\n // this \"mutate then fire\" order; keeping removeComponent consistent.\n const newMask = cloneMask(prevMask)\n clearBit(newMask, bit)\n migrateEntity(state, eid, newMask)\n\n fireRemoveObservers(state, eid, bit)\n\n const storage = state.componentStorageByBit[bit]\n if (storage?.kind === 'soa' && storage.soa) {\n clearSoAEntity(storage.soa, info.fields, eid)\n } else if (storage?.kind === 'aos' && storage.aos) {\n storage.aos[eid] = undefined\n }\n\n notifyMaskChange(state, eid, bit, prevMask, newMask)\n}\n\nexport function hasComponent<C extends ComponentLike>(\n world: World,\n eid: EntityId,\n component: C,\n): boolean {\n const state = getWorldState(world)\n if (!isAliveInternal(state, eid)) return false\n const info = getComponentInfo(component)\n const bit = tryGetComponentBit(state, info)\n if (bit === undefined) return false\n const mask = readEntityMask(state, eid)\n return testBit(mask, bit)\n}\n\nexport function getComponent<C extends ComponentLike>(\n world: World,\n eid: EntityId,\n component: C,\n): unknown {\n const state = getWorldState(world)\n if (!isAliveInternal(state, eid)) return undefined\n const info = getComponentInfo(component)\n const bit = tryGetComponentBit(state, info)\n if (bit === undefined) return undefined\n const mask = readEntityMask(state, eid)\n if (!testBit(mask, bit)) return undefined\n const storage = state.componentStorageByBit[bit]\n if (!storage) return undefined\n if (storage.kind === 'soa') return storage.soa\n if (storage.kind === 'aos') return storage.aos?.[eid]\n return true // tag\n}\n\nexport function setComponent<C extends ComponentLike, V>(\n world: World,\n eid: EntityId,\n component: C,\n value: V,\n): void {\n const state = getWorldState(world)\n if (state.readOnly) throw new Error('aiecsjs: cannot mutate a read-only world')\n if (!isAliveInternal(state, eid)) throw new Error(`aiecsjs: setComponent on dead entity ${eid}`)\n const info = getComponentInfo(component)\n const bit = tryGetComponentBit(state, info)\n if (bit === undefined) {\n // Adding via set\n addComponent(world, eid, component, value as any)\n return\n }\n const mask = readEntityMask(state, eid)\n if (!testBit(mask, bit)) {\n addComponent(world, eid, component, value as any)\n return\n }\n writeInitial(state, eid, component, value as any)\n fireSetObservers(state, eid, bit, value)\n}\n\n// --- Internals ---\n\nfunction writeInitial(\n state: WorldState,\n eid: number,\n component: ComponentLike,\n initial: unknown,\n): void {\n const info = getComponentInfo(component)\n const bit = state.componentBitFor.get(info.id)\n if (bit === undefined) return\n const storage = state.componentStorageByBit[bit]\n if (!storage) return\n if (info.kind === 'soa' && storage.soa) {\n if (initial == null) return\n const obj = initial as Record<string, unknown>\n for (const f of info.fields) {\n if (!(f.name in obj)) continue\n const col = storage.soa[f.name]\n if (!col) continue\n const val = obj[f.name]\n if (f.vectorLen === 1) {\n col[eid] = typeof val === 'boolean' ? (val ? 1 : 0) : Number(val)\n } else if (Array.isArray(val) || ArrayBuffer.isView(val)) {\n const base = eid * f.vectorLen\n const arr = val as ArrayLike<number>\n for (let i = 0; i < f.vectorLen; i++) col[base + i] = Number(arr[i] ?? 0)\n }\n }\n } else if (info.kind === 'aos' && storage.aos) {\n const factory = info.factory ?? (() => ({}))\n let inst = storage.aos[eid]\n if (inst === undefined) {\n inst = factory()\n storage.aos[eid] = inst\n }\n if (initial && typeof initial === 'object') {\n // SECURITY: do NOT use `Object.assign(inst, initial)` here. When `initial`\n // comes from `JSON.parse(untrustedBytes)` — e.g. via `fromJSON`,\n // `deserializeWorld`, or app code piping a bridge payload — the parsed\n // object can carry an OWN `__proto__` property, and `Object.assign` uses\n // [[Set]] semantics which would trigger the proto setter and clobber the\n // instance's prototype chain. Explicit own-key copy with a deny-list\n // closes the prototype-pollution path.\n const src = initial as Record<string, unknown>\n const target = inst as Record<string, unknown>\n for (const key of Object.keys(src)) {\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue\n target[key] = src[key]\n }\n }\n }\n // tag: nothing\n}\n\nfunction clearSoAEntity(soa: SoAColumns, fields: FieldInfo[], eid: number): void {\n for (const f of fields) {\n const col = soa[f.name]\n if (!col) continue\n if (f.vectorLen === 1) {\n col[eid] = 0\n } else {\n const base = eid * f.vectorLen\n for (let i = 0; i < f.vectorLen; i++) col[base + i] = 0\n }\n }\n}\n\n// Clear every component-storage slot that the entity currently owns.\n// Walks the entity's mask; for each set bit, zeroes the SoA columns or\n// undefines the AoS slot at the entity index. Tag storages are bit-only.\n// Caller (e.g. destroyEntity) is expected to clear the mask separately.\nexport function clearAllEntityStorages(state: WorldState, eid: EntityId): void {\n const wordCount = state.options.maskWordCount\n const idx = eid as number\n const base = idx * wordCount\n forEachSetBit(state.entityMask, base, wordCount, (bit) => {\n const storage = state.componentStorageByBit[bit]\n const info = state.componentInfoByBit[bit]\n if (storage?.kind === 'soa' && storage.soa && info) {\n clearSoAEntity(storage.soa, info.fields, idx)\n } else if (storage?.kind === 'aos' && storage.aos) {\n storage.aos[idx] = undefined\n }\n })\n}\n\nfunction migrateEntity(state: WorldState, eid: number, newMask: Uint32Array): void {\n const srcArchId = state.entityArchetype[eid] ?? 0\n const srcArch = state.archetypes[srcArchId]\n if (!srcArch) return\n\n const found = findOrCreateArchetype(state, newMask)\n const destArchId = found.archId\n const destArch = state.archetypes[destArchId]\n if (!destArch) return\n\n if (destArchId !== srcArchId) {\n // Swap-pop from src\n const row = srcArch.entityRow.get(eid)\n if (row !== undefined) {\n const lastRow = srcArch.size - 1\n if (row !== lastRow) {\n const moved = srcArch.entities[lastRow] ?? 0\n srcArch.entities[row] = moved\n srcArch.entityRow.set(moved, row)\n }\n srcArch.entities[lastRow] = 0\n srcArch.entityRow.delete(eid)\n srcArch.size--\n }\n\n // Append to dest\n ensureArchetypeCapacity(destArch, destArch.size + 1)\n const newRow = destArch.size\n destArch.entities[newRow] = eid\n destArch.entityRow.set(eid, newRow)\n destArch.size++\n\n state.entityArchetype[eid] = destArchId\n }\n\n writeEntityMask(state, eid, newMask)\n}\n\n// --- Observer dispatch (lazy-bound) ---\n\ninterface ObserversDispatchAPI {\n fireAdd(state: WorldState, eid: EntityId, bit: number): void\n fireRemove(state: WorldState, eid: EntityId, bit: number): void\n fireSet(state: WorldState, eid: EntityId, bit: number, value: unknown): void\n}\nlet _dispatch: ObserversDispatchAPI = {\n fireAdd: () => {},\n fireRemove: () => {},\n fireSet: () => {},\n}\n\ntype MaskChangeFn = (\n state: WorldState,\n eid: EntityId,\n bit: number,\n prev: Uint32Array,\n next: Uint32Array,\n) => void\nlet _maskChange: MaskChangeFn = () => {}\nexport function registerMaskChangeDispatch(fn: MaskChangeFn): void {\n _maskChange = fn\n}\nfunction notifyMaskChange(\n state: WorldState,\n eid: number,\n bit: number,\n prev: Uint32Array,\n next: Uint32Array,\n): void {\n _maskChange(state, eid as EntityId, bit, prev, next)\n}\nexport function registerObserverDispatch(api: ObserversDispatchAPI): void {\n _dispatch = api\n}\nfunction fireAddObservers(state: WorldState, eid: number, bit: number): void {\n _dispatch.fireAdd(state, eid as EntityId, bit)\n}\nfunction fireRemoveObservers(state: WorldState, eid: number, bit: number): void {\n _dispatch.fireRemove(state, eid as EntityId, bit)\n}\nfunction fireSetObservers(state: WorldState, eid: number, bit: number, value: unknown): void {\n _dispatch.fireSet(state, eid as EntityId, bit, value)\n}\n\n// --- Helper for serialize/worker ---\n\nexport function getComponentByInternalId(id: number): ComponentInfo | undefined {\n return componentInfoById.get(id)\n}\n\nexport function listAllComponents(): ComponentInfo[] {\n return Array.from(componentInfoById.values())\n}\n\nexport function _resetComponentRegistry_FOR_TESTS_ONLY(): void {\n componentInfoById.clear()\n nextComponentId = 1\n}\n","// 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, entityExists } 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\nexport function toJSON(world: World): WorldSnapshot {\n const state = getWorldState(world)\n const entities: WorldSnapshot['entities'] = []\n for (let eid = 1; eid < state.capacity; eid++) {\n if (!entityExists(world, eid as EntityId)) continue\n const archId = state.entityArchetype[eid] ?? 0\n if (archId === 0) continue // unattached (shouldn't happen for alive)\n\n const w = state.options.maskWordCount\n const base = eid * 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[eid]\n } else {\n const arr: number[] = []\n const baseI = eid * 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[eid] ?? 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 entities.push({ eid, components })\n }\n return {\n version: state.version,\n capacity: state.capacity,\n entities,\n }\n}\n\nexport function fromJSON(snapshot: WorldSnapshot): World {\n const world = createWorld({ initialCapacity: snapshot.capacity })\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 return JSON.parse(json) as WorldSnapshot\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 // Apply: ensure entities exist, then add/update their components\n const targetState = getWorldState(targetWorld)\n for (const e of snapshot.entities) {\n if (e.eid >= targetState.capacity) continue\n if (!entityExists(targetWorld, e.eid as EntityId)) {\n // Create the entity. For simplicity, we just spawn until we have enough.\n while (targetState.size < e.eid) {\n createEntity(targetWorld)\n }\n }\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, e.eid as EntityId, 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","// aiecsjs/worker — SharedArrayBuffer helpers (experimental, snapshot-copy in 0.1).\n//\n// Note: 0.1 implements SAB as a transferable snapshot pattern rather than true\n// shared-memory aliasing. The world is serialized into the SAB, and the worker\n// reconstructs a fresh world from those bytes via adoptSnapshot/attachWorld.\n// True shared-column memory is on the 0.2 roadmap. The API matches the\n// documented contract and survives postMessage cleanly.\n\nimport type { TransferableSnapshot, World, WorldMeta, WorldState } from './internal/types.js'\nimport { destroyWorld, getWorldState, isWorldRegistered } from './internal/world.js'\nimport { deserializeWorld, serializeWorld } from './serialize.js'\nimport { VERSION } from './version.js'\n\nconst MAGIC = 0x41494543 // 'AIEC' little-endian as uint32\n\nexport function transferableSnapshot(world: World): TransferableSnapshot {\n const state = getWorldState(world)\n const bytes = serializeWorld(world)\n\n if (typeof SharedArrayBuffer === 'undefined') {\n // Fallback: ArrayBuffer wrapped to look like a SAB at runtime\n const ab = new ArrayBuffer(bytes.byteLength)\n new Uint8Array(ab).set(bytes)\n return {\n buffer: ab as unknown as SharedArrayBuffer,\n meta: buildMeta(state),\n }\n }\n\n const sab = new SharedArrayBuffer(bytes.byteLength)\n new Uint8Array(sab).set(bytes)\n return { buffer: sab, meta: buildMeta(state) }\n}\n\n/**\n * Adopt a snapshot previously produced by `transferableSnapshot`.\n *\n * SECURITY: same trust expectation as `attachWorld` — the sender of the\n * `TransferableSnapshot` (typically a Web Worker) must be trusted. The\n * function runs `validateMeta` and `deserializeWorld`, which enforce magic\n * + format version + length bounds on the binary header; but the inner\n * JSON payload, once decoded, is fed to `addComponent` and reaches AoS\n * components. For untrusted senders, use `aibridgejs` + `toJSON(world)` at\n * the application boundary instead.\n */\nexport function adoptSnapshot(snap: TransferableSnapshot): World {\n validateMeta(snap.meta)\n const bytes = new Uint8Array(snap.buffer)\n return deserializeWorld(bytes)\n}\n\n/**\n * Adopt a SharedArrayBuffer-backed snapshot produced by `transferableSnapshot`.\n *\n * SECURITY: the SAB sender must be trusted. `attachWorld` performs the same\n * magic + version + length-bounds checks as `deserializeWorld`, but the JSON\n * payload itself is deserialised into AoS components via `addComponent`. If\n * the sender is untrusted (e.g. a third-party Web Worker that you do not\n * audit), prefer the higher-level `aibridgejs` channel + `toJSON(world)`\n * pattern, which lets you validate the shape at the application boundary\n * before constructing entities.\n */\nexport function attachWorld(buffer: SharedArrayBuffer, options?: { readOnly?: boolean }): World {\n const bytes = new Uint8Array(buffer)\n const world = deserializeWorld(bytes)\n if (options?.readOnly) {\n const state = getWorldState(world)\n state.readOnly = true\n }\n return world\n}\n\nexport function detachWorld(world: World): void {\n if (isWorldRegistered(world.id)) {\n destroyWorld(world)\n }\n}\n\nfunction buildMeta(state: WorldState): WorldMeta {\n const componentSchemas: WorldMeta['componentSchemas'] = []\n for (const info of state.componentInfoByBit) {\n if (!info) continue\n componentSchemas.push({ id: info.id, kind: info.kind, schema: info.schema })\n }\n return {\n magic: MAGIC,\n formatVersion: 1,\n aiecsjsVersion: VERSION,\n indexBits: state.options.indexBits,\n generationBits: state.options.generationBits,\n maxComponents: state.options.maxComponents,\n maskWordCount: state.options.maskWordCount,\n capacity: state.capacity,\n componentSchemas,\n }\n}\n\nfunction validateMeta(meta: WorldMeta): void {\n if (meta.magic !== MAGIC) {\n throw new Error('aiecsjs: invalid snapshot meta (wrong magic)')\n }\n if (meta.formatVersion !== 1) {\n throw new Error(`aiecsjs: unsupported snapshot format version ${meta.formatVersion}`)\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/worker.ts"],"names":["MAGIC","transferableSnapshot","world","state","getWorldState","bytes","serializeWorld","ab","buildMeta","sab","adoptSnapshot","snap","validateMeta","deserializeWorld","attachWorld","buffer","options","detachWorld","isWorldRegistered","destroyWorld","componentSchemas","info","VERSION","meta"],"mappings":"qHAkBA,IAAMA,CAAAA,CAAQ,WAEP,SAASC,CAAAA,CAAqBC,EAAoC,CACvE,IAAMC,CAAAA,CAAQC,mBAAAA,CAAcF,CAAK,CAAA,CAC3BG,EAAQC,mBAAAA,CAAeJ,CAAK,EAElC,GAAI,OAAO,kBAAsB,GAAA,CAAa,CAE5C,IAAMK,CAAAA,CAAK,IAAI,WAAA,CAAYF,EAAM,UAAU,CAAA,CAC3C,WAAI,UAAA,CAAWE,CAAE,EAAE,GAAA,CAAIF,CAAK,CAAA,CACrB,CACL,MAAA,CAAQE,CAAAA,CACR,KAAMC,CAAAA,CAAUL,CAAK,CACvB,CACF,CAEA,IAAMM,EAAM,IAAI,iBAAA,CAAkBJ,CAAAA,CAAM,UAAU,CAAA,CAClD,OAAA,IAAI,WAAWI,CAAG,CAAA,CAAE,IAAIJ,CAAK,CAAA,CACtB,CAAE,MAAA,CAAQI,CAAAA,CAAK,IAAA,CAAMD,CAAAA,CAAUL,CAAK,CAAE,CAC/C,CAaO,SAASO,CAAAA,CAAcC,CAAAA,CAAmC,CAC/DC,CAAAA,CAAaD,EAAK,IAAI,CAAA,CACtB,IAAMN,CAAAA,CAAQ,IAAI,UAAA,CAAWM,EAAK,MAAM,CAAA,CACxC,OAAOE,mBAAAA,CAAiBR,CAAK,CAC/B,CAaO,SAASS,CAAAA,CAAYC,CAAAA,CAA2BC,CAAAA,CAAyC,CAC9F,IAAMX,CAAAA,CAAQ,IAAI,UAAA,CAAWU,CAAM,CAAA,CAC7Bb,CAAAA,CAAQW,oBAAiBR,CAAK,CAAA,CACpC,GAAIW,CAAAA,EAAS,QAAA,CAAU,CACrB,IAAMb,CAAAA,CAAQC,mBAAAA,CAAcF,CAAK,CAAA,CACjCC,CAAAA,CAAM,SAAW,KACnB,CACA,OAAOD,CACT,CAEO,SAASe,EAAYf,CAAAA,CAAoB,CAC1CgB,mBAAAA,CAAkBhB,CAAAA,CAAM,EAAE,CAAA,EAC5BiB,oBAAajB,CAAK,EAEtB,CAEA,SAASM,CAAAA,CAAUL,CAAAA,CAA8B,CAC/C,IAAMiB,CAAAA,CAAkD,EAAC,CACzD,IAAA,IAAWC,KAAQlB,CAAAA,CAAM,kBAAA,CAClBkB,CAAAA,EACLD,CAAAA,CAAiB,IAAA,CAAK,CAAE,GAAIC,CAAAA,CAAK,EAAA,CAAI,IAAA,CAAMA,CAAAA,CAAK,IAAA,CAAM,MAAA,CAAQA,EAAK,MAAO,CAAC,CAAA,CAE7E,OAAO,CACL,KAAA,CAAOrB,EACP,aAAA,CAAe,CAAA,CACf,eAAgBsB,mBAAAA,CAChB,SAAA,CAAWnB,EAAM,OAAA,CAAQ,SAAA,CACzB,cAAA,CAAgBA,CAAAA,CAAM,OAAA,CAAQ,cAAA,CAC9B,cAAeA,CAAAA,CAAM,OAAA,CAAQ,aAAA,CAC7B,aAAA,CAAeA,CAAAA,CAAM,OAAA,CAAQ,cAC7B,QAAA,CAAUA,CAAAA,CAAM,QAAA,CAChB,gBAAA,CAAAiB,CACF,CACF,CAEA,SAASR,CAAAA,CAAaW,EAAuB,CAC3C,GAAIA,EAAK,KAAA,GAAUvB,CAAAA,CACjB,MAAM,IAAI,KAAA,CAAM,8CAA8C,EAEhE,GAAIuB,CAAAA,CAAK,aAAA,GAAkB,CAAA,CACzB,MAAM,IAAI,MAAM,CAAA,6CAAA,EAAgDA,CAAAA,CAAK,aAAa,CAAA,CAAE,CAExF","file":"worker.cjs","sourcesContent":["// aiecsjs/worker — SharedArrayBuffer helpers (experimental, snapshot-copy).\n//\n// Note: 0.x implements SAB as a transferable snapshot pattern rather than true\n// shared-memory aliasing. The world is serialized into the SAB, and the worker\n// reconstructs a fresh world from those bytes via adoptSnapshot/attachWorld.\n// True shared-column memory is targeted for a future stable release.\n// The API matches the documented contract and survives postMessage cleanly.\n//\n// EntityRef is in-memory only — not preserved across worker boundaries.\n// Generation counters reset on adoptSnapshot/attachWorld. Pass `EntityRef.id`\n// (the packed EntityId) across the worker boundary only if you understand that\n// the generation portion will be stale after a round-trip snapshot.\n\nimport type { TransferableSnapshot, World, WorldMeta, WorldState } from './internal/types.js'\nimport { destroyWorld, getWorldState, isWorldRegistered } from './internal/world.js'\nimport { deserializeWorld, serializeWorld } from './serialize.js'\nimport { VERSION } from './version.js'\n\nconst MAGIC = 0x41494543 // 'AIEC' little-endian as uint32\n\nexport function transferableSnapshot(world: World): TransferableSnapshot {\n const state = getWorldState(world)\n const bytes = serializeWorld(world)\n\n if (typeof SharedArrayBuffer === 'undefined') {\n // Fallback: ArrayBuffer wrapped to look like a SAB at runtime\n const ab = new ArrayBuffer(bytes.byteLength)\n new Uint8Array(ab).set(bytes)\n return {\n buffer: ab as unknown as SharedArrayBuffer,\n meta: buildMeta(state),\n }\n }\n\n const sab = new SharedArrayBuffer(bytes.byteLength)\n new Uint8Array(sab).set(bytes)\n return { buffer: sab, meta: buildMeta(state) }\n}\n\n/**\n * Adopt a snapshot previously produced by `transferableSnapshot`.\n *\n * SECURITY: same trust expectation as `attachWorld` — the sender of the\n * `TransferableSnapshot` (typically a Web Worker) must be trusted. The\n * function runs `validateMeta` and `deserializeWorld`, which enforce magic\n * + format version + length bounds on the binary header; but the inner\n * JSON payload, once decoded, is fed to `addComponent` and reaches AoS\n * components. For untrusted senders, use `aibridgejs` + `toJSON(world)` at\n * the application boundary instead.\n */\nexport function adoptSnapshot(snap: TransferableSnapshot): World {\n validateMeta(snap.meta)\n const bytes = new Uint8Array(snap.buffer)\n return deserializeWorld(bytes)\n}\n\n/**\n * Adopt a SharedArrayBuffer-backed snapshot produced by `transferableSnapshot`.\n *\n * SECURITY: the SAB sender must be trusted. `attachWorld` performs the same\n * magic + version + length-bounds checks as `deserializeWorld`, but the JSON\n * payload itself is deserialised into AoS components via `addComponent`. If\n * the sender is untrusted (e.g. a third-party Web Worker that you do not\n * audit), prefer the higher-level `aibridgejs` channel + `toJSON(world)`\n * pattern, which lets you validate the shape at the application boundary\n * before constructing entities.\n */\nexport function attachWorld(buffer: SharedArrayBuffer, options?: { readOnly?: boolean }): World {\n const bytes = new Uint8Array(buffer)\n const world = deserializeWorld(bytes)\n if (options?.readOnly) {\n const state = getWorldState(world)\n state.readOnly = true\n }\n return world\n}\n\nexport function detachWorld(world: World): void {\n if (isWorldRegistered(world.id)) {\n destroyWorld(world)\n }\n}\n\nfunction buildMeta(state: WorldState): WorldMeta {\n const componentSchemas: WorldMeta['componentSchemas'] = []\n for (const info of state.componentInfoByBit) {\n if (!info) continue\n componentSchemas.push({ id: info.id, kind: info.kind, schema: info.schema })\n }\n return {\n magic: MAGIC,\n formatVersion: 1,\n aiecsjsVersion: VERSION,\n indexBits: state.options.indexBits,\n generationBits: state.options.generationBits,\n maxComponents: state.options.maxComponents,\n maskWordCount: state.options.maskWordCount,\n capacity: state.capacity,\n componentSchemas,\n }\n}\n\nfunction validateMeta(meta: WorldMeta): void {\n if (meta.magic !== MAGIC) {\n throw new Error('aiecsjs: invalid snapshot meta (wrong magic)')\n }\n if (meta.formatVersion !== 1) {\n throw new Error(`aiecsjs: unsupported snapshot format version ${meta.formatVersion}`)\n }\n}\n"]}
package/dist/worker.js CHANGED
@@ -1,2 +1,2 @@
1
- var w="0.2.1";function U(t){return new Uint32Array(t)}function M(t,n){let e=n>>>5;t[e]=(t[e]??0)|1<<(n&31);}function O(t,n){let e=n>>>5;return ((t[e]??0)&1<<(n&31))!==0}function g(t){let n=new Uint32Array(t.length);for(let e=0;e<t.length;e++)n[e]=t[e]??0;return n}function E(t){let n=[];for(let e=0;e<t.length;e++)n.push((t[e]??0).toString(16));return n.join(",")}var C={initialCapacity:1024,maxEntities:1e6,indexBits:24,generationBits:8},K=256,tt=1,b=new Map;function u(t){let n=b.get(t.id);if(!n)throw new Error(`aiecsjs: world ${t.id} is destroyed or unknown`);if(n.destroyed)throw new Error(`aiecsjs: world ${t.id} is destroyed`);return n}function nt(t){b.set(t.id,t);}function et(t){b.delete(t);}function _(t){return b.has(t)}function ot(t){let n=t??{},e=n.indexBits??C.indexBits,o=n.generationBits??C.generationBits,r=K;if(e<1||e>24)throw new Error("aiecsjs: indexBits must be in [1, 24]");if(o<0||o>16)throw new Error("aiecsjs: generationBits must be in [0, 16]");let s=1<<e,i=Math.max(1,Math.min(n.initialCapacity??C.initialCapacity,s)),c=Math.max(i,Math.min(n.maxEntities??C.maxEntities,s));return {initialCapacity:i,maxEntities:c,indexBits:e,generationBits:o,maxComponents:r,maskWordCount:Math.ceil(r/32),buffer:n.buffer??null,bufferByteOffset:n.bufferByteOffset??0}}function rt(t,n){return {id:0,mask:U(t),size:0,capacity:16,entities:new Uint32Array(16),entityRow:new Map,componentBits:[],edgeAdd:new Int32Array(n).fill(-1),edgeRemove:new Int32Array(n).fill(-1)}}function j(t){let n=ot(t),e=tt++,o=n.generationBits>8?Uint16Array:Uint8Array,r=new o(n.initialCapacity),s={id:e,capacity:n.initialCapacity,version:w,options:n,size:0,nextFreshIndex:1,freeList:[],generations:r,destroyed:false,componentBitFor:new Map,componentInfoByBit:new Array(n.maxComponents).fill(null),componentStorageByBit:new Array(n.maxComponents).fill(null),nextComponentBit:0,entityArchetype:new Uint32Array(n.initialCapacity),entityMask:new Uint32Array(n.initialCapacity*n.maskWordCount),archetypes:[],archetypeByMaskHash:new Map,queryVersion:0,queries:[],queryMasks:new Map,queryArchetypeCache:[],queryArchetypeStamp:[],bitToQueries:new Map,reactiveBuffers:new Map,observers:[],relationStorage:new Map,sab:n.buffer,readOnly:false},i=rt(n.maskWordCount,n.maxComponents);return i.id=0,s.archetypes.push(i),s.archetypeByMaskHash.set(E(i.mask),0),nt(s),it(s)}function it(t){return {id:t.id,get capacity(){return t.capacity},version:t.version}}function R(t){let n=b.get(t.id);!n||n.destroyed||(n.destroyed=true,n.archetypes=[],n.archetypeByMaskHash.clear(),n.componentInfoByBit=[],n.componentStorageByBit=[],n.queries=[],n.queryMasks.clear(),n.queryArchetypeCache=[],n.observers=[],n.relationStorage.clear(),n.reactiveBuffers.clear(),et(t.id));}function L(t,n){if(n<=t.capacity)return;if(n>t.options.maxEntities)throw new Error(`aiecsjs: requested capacity ${n} exceeds maxEntities ${t.options.maxEntities}`);let e=t.capacity;for(;e<n;)e=Math.min(e*2,t.options.maxEntities);st(t,e);}function st(t,n){let e=t.generations.constructor,o=new e(n);o.set(t.generations),t.generations=o;let r=new Uint32Array(n);r.set(t.entityArchetype),t.entityArchetype=r;let s=t.options.maskWordCount,i=new Uint32Array(n*s);i.set(t.entityMask),t.entityMask=i;for(let c of t.componentStorageByBit)if(c)if(c.kind==="soa"&&c.soa){let a=t.componentInfoByBit[c.bit];a&&at(c.soa,a.fields,n);}else c.kind==="aos"&&c.aos&&(c.aos.length=n);t.capacity=n;}function at(t,n,e){for(let o of n){let r=t[o.name];if(!r)continue;let s=e*o.vectorLen;if(r.length>=s)continue;let i=new o.ctor(s);i.set(r),t[o.name]=i;}}function z(t,n){let e=E(n),o=t.archetypeByMaskHash.get(e);if(o!==void 0)return {archId:o,created:false};let r=t.archetypes.length,s={id:r,mask:g(n),size:0,capacity:16,entities:new Uint32Array(16),entityRow:new Map,componentBits:ct(n),edgeAdd:new Int32Array(t.options.maxComponents).fill(-1),edgeRemove:new Int32Array(t.options.maxComponents).fill(-1)};return t.archetypes.push(s),t.archetypeByMaskHash.set(e,r),t.queryVersion++,{archId:r,created:true}}function S(t,n){if(n<=t.capacity)return;let e=t.capacity;for(;e<n;)e*=2;let o=new Uint32Array(e);o.set(t.entities),t.entities=o,t.capacity=e;}function ct(t){let n=[];for(let e=0;e<t.length;e++){let o=t[e]??0;for(;o!==0;){let r=o&-o,s=(e<<5)+(31-Math.clz32(r));n.push(s),o&=o-1;}}return n}function T(t,n){let e=t.componentBitFor.get(n.id);if(e!==void 0)return e;if(t.nextComponentBit>=t.options.maxComponents)throw new Error(`aiecsjs: world reached maxComponents=${t.options.maxComponents}`);let o=t.nextComponentBit++;t.componentBitFor.set(n.id,o),t.componentInfoByBit[o]=n;let r;if(n.kind==="soa"){let s={};for(let i of n.fields)s[i.name]=new i.ctor(t.capacity*i.vectorLen);r={kind:"soa",componentId:n.id,bit:o,soa:s};}else n.kind==="aos"?r={kind:"aos",componentId:n.id,bit:o,aos:new Array(t.capacity)}:r={kind:"tag",componentId:n.id,bit:o};return t.componentStorageByBit[o]=r,o}function D(t,n){let e=t.options.maskWordCount,o=new Uint32Array(e),r=n*e;for(let s=0;s<e;s++)o[s]=t.entityMask[r+s]??0;return o}function F(t,n,e){let o=t.options.maskWordCount,r=n*o;for(let s=0;s<o;s++)t.entityMask[r+s]=e[s]??0;}function N(t){let n=u(t);if(n.readOnly)throw new Error("aiecsjs: cannot createEntity on a read-only world (worker-attached)");let e;if(n.freeList.length>0)e=n.freeList.pop();else {if(n.nextFreshIndex>=n.options.maxEntities)throw new Error(`aiecsjs: reached maxEntities ${n.options.maxEntities}`);n.nextFreshIndex>=n.capacity&&L(n,n.nextFreshIndex+1),e=n.nextFreshIndex++;}let o=n.archetypes[0];if(!o)throw new Error("aiecsjs: missing empty archetype");S(o,o.size+1);let r=o.size;o.entities[r]=e,o.entityRow.set(e,r),o.size++,n.entityArchetype[e]=0;let s=n.options.maskWordCount,i=e*s;for(let c=0;c<s;c++)n.entityMask[i+c]=0;return n.size++,e}function V(t,n){let e=u(t);return I(e,n)}function I(t,n){if(n<=0||n>=t.capacity)return false;let e=t.entityArchetype[n]??0,o=t.archetypes[e];return o?o.entityRow.has(n):false}var $=new Map;function q(t){let n=$.get(t.__id);if(!n)throw new Error("aiecsjs: component is not registered (call defineComponent/defineTag/defineObjectComponent)");return n}function H(t,n,e,o){let r=u(t);if(r.readOnly)throw new Error("aiecsjs: cannot mutate a read-only world");if(!I(r,n))throw new Error(`aiecsjs: addComponent on dead entity ${n}`);let s=q(e),i=T(r,s),c=D(r,n);if(O(c,i)){o!==void 0&&P(r,n,e,o);return}let a=g(c);M(a,i),ft(r,n,a),P(r,n,e,o);}function P(t,n,e,o){let r=q(e),s=t.componentBitFor.get(r.id);if(s===void 0)return;let i=t.componentStorageByBit[s];if(i){if(r.kind==="soa"&&i.soa){if(o==null)return;let c=o;for(let a of r.fields){if(!(a.name in c))continue;let f=i.soa[a.name];if(!f)continue;let d=c[a.name];if(a.vectorLen===1)f[n]=typeof d=="boolean"?d?1:0:Number(d);else if(Array.isArray(d)||ArrayBuffer.isView(d)){let l=n*a.vectorLen,y=d;for(let p=0;p<a.vectorLen;p++)f[l+p]=Number(y[p]??0);}}}else if(r.kind==="aos"&&i.aos){let c=r.factory??(()=>({})),a=i.aos[n];if(a===void 0&&(a=c(),i.aos[n]=a),o&&typeof o=="object"){let f=o,d=a;for(let l of Object.keys(f))l==="__proto__"||l==="constructor"||l==="prototype"||(d[l]=f[l]);}}}}function ft(t,n,e){let o=t.entityArchetype[n]??0,r=t.archetypes[o];if(!r)return;let i=z(t,e).archId,c=t.archetypes[i];if(c){if(i!==o){let a=r.entityRow.get(n);if(a!==void 0){let d=r.size-1;if(a!==d){let l=r.entities[d]??0;r.entities[a]=l,r.entityRow.set(l,a);}r.entities[d]=0,r.entityRow.delete(n),r.size--;}S(c,c.size+1);let f=c.size;c.entities[f]=n,c.entityRow.set(n,f),c.size++,t.entityArchetype[n]=i;}F(t,n,e);}}function G(t){return $.get(t)}var m="AIEC",J=1;function Y(t,n){let e=yt(t);return wt(e)}function v(t,n){let e=bt(t);return mt(e)}function yt(t){let n=u(t),e=[];for(let o=1;o<n.capacity;o++){if(!V(t,o)||(n.entityArchetype[o]??0)===0)continue;let s=n.options.maskWordCount,i=o*s,c=[];for(let a=0;a<s;a++){let f=n.entityMask[i+a]??0;for(;f!==0;){let d=f&-f,l=(a<<5)+(31-Math.clz32(d)),y=n.componentInfoByBit[l];if(y){let p=n.componentStorageByBit[l],A=null;if(y.kind==="soa"&&p?.soa){let x={};for(let h of y.fields){let k=p.soa[h.name];if(k)if(h.vectorLen===1)x[h.name]=k[o];else {let B=[],Z=o*h.vectorLen;for(let W=0;W<h.vectorLen;W++)B.push(k[Z+W]??0);x[h.name]=B;}}A=x;}else y.kind==="aos"&&p?.aos?A=p.aos[o]??null:A=true;c.push({kind:y.kind,id:y.id,data:A});}f&=f-1;}}e.push({eid:o,components:c});}return {version:n.version,capacity:n.capacity,entities:e}}function mt(t){let n=j({initialCapacity:t.capacity}),e=new Map;for(let o of t.entities){let r=N(n);e.set(o.eid,r);}for(let o of t.entities){let r=e.get(o.eid);for(let s of o.components){let i=G(s.id);if(!i)continue;let c=ht(i);c&&H(n,r,c,s.data);}}return n}function ht(t){if(t.kind==="soa")return {__kind:"soa",__id:t.id,__schema:t.schema??{}};if(t.kind==="aos"){let n=t.factory??(()=>({}));return {__kind:"aos",__id:t.id,__factory:n}}return {__kind:"tag",__id:t.id}}function wt(t){let n=JSON.stringify(t),e=new TextEncoder().encode(n),o=new TextEncoder().encode(w),s=12+o.length+4+e.length,i=new Uint8Array(s),c=new DataView(i.buffer),a=0;return i[a++]=m.charCodeAt(0),i[a++]=m.charCodeAt(1),i[a++]=m.charCodeAt(2),i[a++]=m.charCodeAt(3),c.setUint32(a,J,true),a+=4,c.setUint32(a,o.length,true),a+=4,i.set(o,a),a+=o.length,c.setUint32(a,e.length,true),a+=4,i.set(e,a),i}function bt(t,n){if(t.length<12)throw new Error("aiecsjs: bytes too short to be a valid snapshot");let e=new DataView(t.buffer,t.byteOffset,t.byteLength);if(t[0]!==m.charCodeAt(0)||t[1]!==m.charCodeAt(1)||t[2]!==m.charCodeAt(2)||t[3]!==m.charCodeAt(3))throw new Error("aiecsjs: invalid magic bytes");let o=4,r=e.getUint32(o,true);o+=4;let s="throw";if(r!==J&&s==="throw")throw new Error(`aiecsjs: format version ${r} not supported`);let i=64*1024*1024;if(o+4>t.length)throw new Error("aiecsjs: snapshot truncated before verLen");let c=e.getUint32(o,true);if(o+=4,c>i||o+c>t.length)throw new Error(`aiecsjs: snapshot verLen=${c} out of bounds`);if(o+=c,o+4>t.length)throw new Error("aiecsjs: snapshot truncated before jsonLen");let a=e.getUint32(o,true);if(o+=4,a>i||o+a>t.length)throw new Error(`aiecsjs: snapshot jsonLen=${a} out of bounds`);let f=t.subarray(o,o+a),d=new TextDecoder().decode(f);return JSON.parse(d)}var Q=1095320899;function Yt(t){let n=u(t),e=Y(t);if(typeof SharedArrayBuffer>"u"){let r=new ArrayBuffer(e.byteLength);return new Uint8Array(r).set(e),{buffer:r,meta:X(n)}}let o=new SharedArrayBuffer(e.byteLength);return new Uint8Array(o).set(e),{buffer:o,meta:X(n)}}function Xt(t){At(t.meta);let n=new Uint8Array(t.buffer);return v(n)}function Qt(t,n){let e=new Uint8Array(t),o=v(e);if(n?.readOnly){let r=u(o);r.readOnly=true;}return o}function Zt(t){_(t.id)&&R(t);}function X(t){let n=[];for(let e of t.componentInfoByBit)e&&n.push({id:e.id,kind:e.kind,schema:e.schema});return {magic:Q,formatVersion:1,aiecsjsVersion:w,indexBits:t.options.indexBits,generationBits:t.options.generationBits,maxComponents:t.options.maxComponents,maskWordCount:t.options.maskWordCount,capacity:t.capacity,componentSchemas:n}}function At(t){if(t.magic!==Q)throw new Error("aiecsjs: invalid snapshot meta (wrong magic)");if(t.formatVersion!==1)throw new Error(`aiecsjs: unsupported snapshot format version ${t.formatVersion}`)}export{Xt as adoptSnapshot,Qt as attachWorld,Zt as detachWorld,Yt as transferableSnapshot};//# sourceMappingURL=worker.js.map
1
+ import {a,b as b$1}from'./chunk-QOKIEF7C.js';import {i,j,l as l$1,a as a$1}from'./chunk-L5CMKMIP.js';var l=1095320899;function W(r){let e=i(r),o=a(r);if(typeof SharedArrayBuffer>"u"){let n=new ArrayBuffer(o.byteLength);return new Uint8Array(n).set(o),{buffer:n,meta:p(e)}}let t=new SharedArrayBuffer(o.byteLength);return new Uint8Array(t).set(o),{buffer:t,meta:p(e)}}function b(r){m(r.meta);let e=new Uint8Array(r.buffer);return b$1(e)}function S(r,e){let o=new Uint8Array(r),t=b$1(o);if(e?.readOnly){let n=i(t);n.readOnly=true;}return t}function w(r){j(r.id)&&l$1(r);}function p(r){let e=[];for(let o of r.componentInfoByBit)o&&e.push({id:o.id,kind:o.kind,schema:o.schema});return {magic:l,formatVersion:1,aiecsjsVersion:a$1,indexBits:r.options.indexBits,generationBits:r.options.generationBits,maxComponents:r.options.maxComponents,maskWordCount:r.options.maskWordCount,capacity:r.capacity,componentSchemas:e}}function m(r){if(r.magic!==l)throw new Error("aiecsjs: invalid snapshot meta (wrong magic)");if(r.formatVersion!==1)throw new Error(`aiecsjs: unsupported snapshot format version ${r.formatVersion}`)}export{b as adoptSnapshot,S as attachWorld,w as detachWorld,W as transferableSnapshot};//# sourceMappingURL=worker.js.map
2
2
  //# sourceMappingURL=worker.js.map