@codehz/ecs 0.3.9 → 0.3.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.mts +8 -1
- package/index.mjs +95 -19
- package/index.mjs.map +1 -1
- package/package.json +1 -1
package/index.d.mts
CHANGED
|
@@ -330,6 +330,13 @@ declare class Archetype {
|
|
|
330
330
|
* @param callback Function called for each entity with its component data
|
|
331
331
|
*/
|
|
332
332
|
forEach(callback: (entityId: EntityId, components: Map<EntityId<any>, any>) => void): void;
|
|
333
|
+
/**
|
|
334
|
+
* Check if any entity in this archetype has a relation matching the given component ID
|
|
335
|
+
* This includes both regular relations in componentTypes and dontFragment relations
|
|
336
|
+
* @param componentId The component ID to match
|
|
337
|
+
* @returns true if any entity has a matching relation
|
|
338
|
+
*/
|
|
339
|
+
hasRelationWithComponentId(componentId: EntityId<any>): boolean;
|
|
333
340
|
}
|
|
334
341
|
//#endregion
|
|
335
342
|
//#region src/changeset.d.ts
|
|
@@ -698,7 +705,7 @@ declare class World<UpdateParams extends any[] = []> {
|
|
|
698
705
|
*/
|
|
699
706
|
private ensureArchetype;
|
|
700
707
|
/**
|
|
701
|
-
* Filter out dontFragment relations from component types
|
|
708
|
+
* Filter out dontFragment relations from component types, but keep wildcard markers
|
|
702
709
|
*/
|
|
703
710
|
private filterRegularComponentTypes;
|
|
704
711
|
/**
|
package/index.mjs
CHANGED
|
@@ -619,35 +619,45 @@ var Archetype = class {
|
|
|
619
619
|
/**
|
|
620
620
|
* Helper: build component tuples for a specific entity index using precomputed data sources
|
|
621
621
|
*/
|
|
622
|
-
buildComponentsForIndex(componentTypes, componentDataSources, entityIndex) {
|
|
622
|
+
buildComponentsForIndex(componentTypes, componentDataSources, entityIndex, entityId) {
|
|
623
623
|
return componentDataSources.map((dataSource, i) => {
|
|
624
624
|
const compType = componentTypes[i];
|
|
625
|
-
return this.buildSingleComponent(compType, dataSource, entityIndex);
|
|
625
|
+
return this.buildSingleComponent(compType, dataSource, entityIndex, entityId);
|
|
626
626
|
});
|
|
627
627
|
}
|
|
628
628
|
/**
|
|
629
629
|
* Build a single component value from its data source
|
|
630
630
|
*/
|
|
631
|
-
buildSingleComponent(compType, dataSource, entityIndex) {
|
|
631
|
+
buildSingleComponent(compType, dataSource, entityIndex, entityId) {
|
|
632
632
|
const optional = isOptionalEntityId(compType);
|
|
633
|
-
|
|
633
|
+
const actualType = optional ? compType.optional : compType;
|
|
634
|
+
if (getIdType(actualType) === "wildcard-relation") return this.buildWildcardRelationValue(actualType, dataSource, entityIndex, entityId, optional);
|
|
634
635
|
else return this.buildRegularComponentValue(dataSource, entityIndex, optional);
|
|
635
636
|
}
|
|
636
637
|
/**
|
|
637
638
|
* Build wildcard relation value from matching relations
|
|
638
639
|
*/
|
|
639
|
-
buildWildcardRelationValue(dataSource, entityIndex, optional) {
|
|
640
|
-
|
|
641
|
-
if (optional) return;
|
|
642
|
-
throw new Error(`No matching relations found for mandatory wildcard relation component type`);
|
|
643
|
-
}
|
|
644
|
-
const matchingRelations = dataSource;
|
|
640
|
+
buildWildcardRelationValue(wildcardRelationType, dataSource, entityIndex, entityId, optional) {
|
|
641
|
+
const matchingRelations = dataSource || [];
|
|
645
642
|
const relations = [];
|
|
646
643
|
for (const relType of matchingRelations) {
|
|
647
644
|
const data = this.getComponentData(relType)[entityIndex];
|
|
648
645
|
const decodedRel = decodeRelationId(relType);
|
|
649
646
|
relations.push([decodedRel.targetId, data === MISSING_COMPONENT ? void 0 : data]);
|
|
650
647
|
}
|
|
648
|
+
const targetComponentId = decodeRelationId(wildcardRelationType).componentId;
|
|
649
|
+
const dontFragmentData = this.dontFragmentRelations.get(entityId);
|
|
650
|
+
if (dontFragmentData) for (const [relType, data] of dontFragmentData) {
|
|
651
|
+
const relDetailed = getDetailedIdType(relType);
|
|
652
|
+
if ((relDetailed.type === "entity-relation" || relDetailed.type === "component-relation") && relDetailed.componentId === targetComponentId) relations.push([relDetailed.targetId, data]);
|
|
653
|
+
}
|
|
654
|
+
if (relations.length === 0) {
|
|
655
|
+
if (!optional) {
|
|
656
|
+
const wildcardDecoded = decodeRelationId(wildcardRelationType);
|
|
657
|
+
throw new Error(`No matching relations found for mandatory wildcard relation component ${wildcardDecoded.componentId} on entity ${entityId}`);
|
|
658
|
+
}
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
651
661
|
return optional ? { value: relations } : relations;
|
|
652
662
|
}
|
|
653
663
|
/**
|
|
@@ -685,7 +695,10 @@ var Archetype = class {
|
|
|
685
695
|
*/
|
|
686
696
|
*iterateWithComponents(componentTypes) {
|
|
687
697
|
const componentDataSources = this.getCachedComponentDataSources(componentTypes);
|
|
688
|
-
for (let entityIndex = 0; entityIndex < this.entities.length; entityIndex++)
|
|
698
|
+
for (let entityIndex = 0; entityIndex < this.entities.length; entityIndex++) {
|
|
699
|
+
const entity = this.entities[entityIndex];
|
|
700
|
+
yield [entity, ...this.buildComponentsForIndex(componentTypes, componentDataSources, entityIndex, entity)];
|
|
701
|
+
}
|
|
689
702
|
}
|
|
690
703
|
/**
|
|
691
704
|
* Iterate over entities with their component data for specified component types
|
|
@@ -697,7 +710,7 @@ var Archetype = class {
|
|
|
697
710
|
const componentDataSources = this.getCachedComponentDataSources(componentTypes);
|
|
698
711
|
for (let entityIndex = 0; entityIndex < this.entities.length; entityIndex++) {
|
|
699
712
|
const entity = this.entities[entityIndex];
|
|
700
|
-
callback(entity, ...this.buildComponentsForIndex(componentTypes, componentDataSources, entityIndex));
|
|
713
|
+
callback(entity, ...this.buildComponentsForIndex(componentTypes, componentDataSources, entityIndex, entity));
|
|
701
714
|
}
|
|
702
715
|
}
|
|
703
716
|
/**
|
|
@@ -714,6 +727,26 @@ var Archetype = class {
|
|
|
714
727
|
callback(this.entities[i], components);
|
|
715
728
|
}
|
|
716
729
|
}
|
|
730
|
+
/**
|
|
731
|
+
* Check if any entity in this archetype has a relation matching the given component ID
|
|
732
|
+
* This includes both regular relations in componentTypes and dontFragment relations
|
|
733
|
+
* @param componentId The component ID to match
|
|
734
|
+
* @returns true if any entity has a matching relation
|
|
735
|
+
*/
|
|
736
|
+
hasRelationWithComponentId(componentId) {
|
|
737
|
+
for (const componentType of this.componentTypes) {
|
|
738
|
+
const detailedType = getDetailedIdType(componentType);
|
|
739
|
+
if ((detailedType.type === "entity-relation" || detailedType.type === "component-relation") && detailedType.componentId === componentId) return true;
|
|
740
|
+
}
|
|
741
|
+
for (const entityId of this.entities) {
|
|
742
|
+
const entityDontFragmentRelations = this.dontFragmentRelations.get(entityId);
|
|
743
|
+
if (entityDontFragmentRelations) for (const relationType of entityDontFragmentRelations.keys()) {
|
|
744
|
+
const detailedType = getDetailedIdType(relationType);
|
|
745
|
+
if ((detailedType.type === "entity-relation" || detailedType.type === "component-relation") && detailedType.componentId === componentId) return true;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
return false;
|
|
749
|
+
}
|
|
717
750
|
};
|
|
718
751
|
|
|
719
752
|
//#endregion
|
|
@@ -1008,7 +1041,20 @@ var Query = class {
|
|
|
1008
1041
|
getEntities() {
|
|
1009
1042
|
this.ensureNotDisposed();
|
|
1010
1043
|
const result = [];
|
|
1011
|
-
|
|
1044
|
+
if (this.componentTypes.some((ct) => {
|
|
1045
|
+
return getDetailedIdType(ct).type === "wildcard-relation";
|
|
1046
|
+
})) for (const archetype of this.cachedArchetypes) for (const entity of archetype.getEntities()) {
|
|
1047
|
+
let hasAllRelations = true;
|
|
1048
|
+
for (const componentType of this.componentTypes) if (getDetailedIdType(componentType).type === "wildcard-relation") {
|
|
1049
|
+
const relations = archetype.get(entity, componentType);
|
|
1050
|
+
if (!relations || relations.length === 0) {
|
|
1051
|
+
hasAllRelations = false;
|
|
1052
|
+
break;
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
if (hasAllRelations) result.push(entity);
|
|
1056
|
+
}
|
|
1057
|
+
else for (const archetype of this.cachedArchetypes) result.push(...archetype.getEntities());
|
|
1012
1058
|
return result;
|
|
1013
1059
|
}
|
|
1014
1060
|
/**
|
|
@@ -1511,10 +1557,11 @@ var World = class {
|
|
|
1511
1557
|
matchingArchetypes = Array.from(intersection);
|
|
1512
1558
|
}
|
|
1513
1559
|
} else matchingArchetypes = [...this.archetypes];
|
|
1514
|
-
for (const wildcard of wildcardRelations)
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1560
|
+
for (const wildcard of wildcardRelations) if (isDontFragmentComponent(wildcard.componentId)) {
|
|
1561
|
+
const archetypesWithMarker = this.archetypesByComponent.get(wildcard.relationId) || [];
|
|
1562
|
+
if (matchingArchetypes.length === 0) matchingArchetypes = archetypesWithMarker;
|
|
1563
|
+
else matchingArchetypes = matchingArchetypes.filter((archetype) => archetypesWithMarker.includes(archetype));
|
|
1564
|
+
} else matchingArchetypes = matchingArchetypes.filter((archetype) => archetype.hasRelationWithComponentId(wildcard.componentId));
|
|
1518
1565
|
return matchingArchetypes;
|
|
1519
1566
|
}
|
|
1520
1567
|
query(componentTypes, includeComponents) {
|
|
@@ -1563,6 +1610,10 @@ var World = class {
|
|
|
1563
1610
|
processSetCommand(entityId, currentArchetype, componentType, component$1, changeset) {
|
|
1564
1611
|
const detailedType = getDetailedIdType(componentType);
|
|
1565
1612
|
if ((detailedType.type === "entity-relation" || detailedType.type === "component-relation") && isExclusiveComponent(detailedType.componentId)) this.removeExclusiveRelations(entityId, currentArchetype, detailedType.componentId, changeset);
|
|
1613
|
+
if ((detailedType.type === "entity-relation" || detailedType.type === "component-relation") && isDontFragmentComponent(detailedType.componentId)) {
|
|
1614
|
+
const wildcardMarker = relation(detailedType.componentId, "*");
|
|
1615
|
+
if (!currentArchetype.componentTypes.includes(wildcardMarker)) changeset.set(wildcardMarker, void 0);
|
|
1616
|
+
}
|
|
1566
1617
|
changeset.set(componentType, component$1);
|
|
1567
1618
|
}
|
|
1568
1619
|
/**
|
|
@@ -1589,7 +1640,24 @@ var World = class {
|
|
|
1589
1640
|
processDeleteCommand(entityId, currentArchetype, componentType, changeset) {
|
|
1590
1641
|
const detailedType = getDetailedIdType(componentType);
|
|
1591
1642
|
if (detailedType.type === "wildcard-relation") this.removeWildcardRelations(entityId, currentArchetype, detailedType.componentId, changeset);
|
|
1592
|
-
else
|
|
1643
|
+
else {
|
|
1644
|
+
changeset.delete(componentType);
|
|
1645
|
+
if ((detailedType.type === "entity-relation" || detailedType.type === "component-relation") && isDontFragmentComponent(detailedType.componentId)) {
|
|
1646
|
+
const wildcardMarker = relation(detailedType.componentId, "*");
|
|
1647
|
+
const entityData = currentArchetype.getEntity(entityId);
|
|
1648
|
+
let hasOtherRelations = false;
|
|
1649
|
+
if (entityData) for (const [otherComponentType] of entityData) {
|
|
1650
|
+
if (otherComponentType === componentType) continue;
|
|
1651
|
+
if (changeset.removes.has(otherComponentType)) continue;
|
|
1652
|
+
const otherDetailedType = getDetailedIdType(otherComponentType);
|
|
1653
|
+
if ((otherDetailedType.type === "entity-relation" || otherDetailedType.type === "component-relation") && otherDetailedType.componentId === detailedType.componentId) {
|
|
1654
|
+
hasOtherRelations = true;
|
|
1655
|
+
break;
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
if (!hasOtherRelations) changeset.delete(wildcardMarker);
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1593
1661
|
}
|
|
1594
1662
|
/**
|
|
1595
1663
|
* Remove all relations matching a wildcard component ID
|
|
@@ -1601,6 +1669,10 @@ var World = class {
|
|
|
1601
1669
|
if (currentArchetype.componentTypes.includes(componentType)) continue;
|
|
1602
1670
|
if (this.isRelationWithComponent(componentType, baseComponentId)) changeset.delete(componentType);
|
|
1603
1671
|
}
|
|
1672
|
+
if (isDontFragmentComponent(baseComponentId)) {
|
|
1673
|
+
const wildcardMarker = relation(baseComponentId, "*");
|
|
1674
|
+
changeset.delete(wildcardMarker);
|
|
1675
|
+
}
|
|
1604
1676
|
}
|
|
1605
1677
|
/**
|
|
1606
1678
|
* Apply changeset to entity, moving to new archetype if needed
|
|
@@ -1689,12 +1761,16 @@ var World = class {
|
|
|
1689
1761
|
return getOrCreateWithSideEffect(this.archetypeBySignature, hashKey, () => this.createNewArchetype(sortedTypes));
|
|
1690
1762
|
}
|
|
1691
1763
|
/**
|
|
1692
|
-
* Filter out dontFragment relations from component types
|
|
1764
|
+
* Filter out dontFragment relations from component types, but keep wildcard markers
|
|
1693
1765
|
*/
|
|
1694
1766
|
filterRegularComponentTypes(componentTypes) {
|
|
1695
1767
|
const regularTypes = [];
|
|
1696
1768
|
for (const componentType of componentTypes) {
|
|
1697
1769
|
const detailedType = getDetailedIdType(componentType);
|
|
1770
|
+
if (detailedType.type === "wildcard-relation" && isDontFragmentComponent(detailedType.componentId)) {
|
|
1771
|
+
regularTypes.push(componentType);
|
|
1772
|
+
continue;
|
|
1773
|
+
}
|
|
1698
1774
|
if ((detailedType.type === "entity-relation" || detailedType.type === "component-relation") && isDontFragmentComponent(detailedType.componentId)) continue;
|
|
1699
1775
|
regularTypes.push(componentType);
|
|
1700
1776
|
}
|
package/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["actualTargetId: number","type: \"entity-relation\" | \"component-relation\" | \"wildcard-relation\"","ComponentNames: Map<ComponentId<any>, string>","ComponentIdForNames: Map<string, ComponentId<any>>","ComponentOptions: Map<ComponentId<any>, ComponentOptions>","name: string | undefined","options: ComponentOptions | undefined","result: Array<{\n entity: EntityId;\n components: Map<EntityId<any>, any>;\n }>","relations: [EntityId<unknown>, any][]","result: Array<{\n entity: EntityId;\n components: ComponentTuple<T>;\n }>","component","result: EntityId[]","result: Array<{\n entity: EntityId;\n components: ComponentTuple<T>;\n }>","result: T[]","result: System<UpdateParams>[]","componentsArray: SerializedComponent[]","componentTypes: EntityId<any>[]","componentType: EntityId<any>","queue: EntityId[]","component","regularComponents: EntityId<any>[]","wildcardRelations: { componentId: EntityId<any>; relationId: EntityId<any> }[]","matchingArchetypes: Archetype[]","result: Array<{\n entity: EntityId;\n components: any;\n }>","result: EntityId[]","regularTypes: EntityId<any>[]","entities: SerializedEntity[]","type: SerializedComponent[\"type\"]"],"sources":["../src/entity.ts","../src/types.ts","../src/utils.ts","../src/archetype.ts","../src/changeset.ts","../src/command-buffer.ts","../src/multi-map.ts","../src/query-filter.ts","../src/query.ts","../src/system-scheduler.ts","../src/world.ts"],"sourcesContent":["/**\n * Unique symbol brand for associating component type information with EntityId\n */\ndeclare const __componentTypeMarker: unique symbol;\n\n/**\n * Unique symbol brand for tagging the kind of EntityId (e.g., 'component', 'entity-relation')\n */\ndeclare const __entityIdTypeTag: unique symbol;\n\n/**\n * Entity ID type for ECS architecture\n * Based on 52-bit integers within safe integer range\n * - Component IDs: 1-1023\n * - Entity IDs: 1024+\n * - Relation IDs: negative numbers encoding component and entity associations\n */\nexport type EntityId<T = void, U = unknown> = number & {\n readonly [__componentTypeMarker]: T;\n readonly [__entityIdTypeTag]: U;\n};\n\nexport type ComponentId<T = void> = EntityId<T, \"component\">;\nexport type EntityRelationId<T = void> = EntityId<T, \"entity-relation\">;\nexport type ComponentRelationId<T = void> = EntityId<T, \"component-relation\">;\nexport type WildcardRelationId<T = void> = EntityId<T, \"wildcard-relation\">;\nexport type RelationId<T = void> = EntityRelationId<T> | ComponentRelationId<T> | WildcardRelationId<T>;\n\n/**\n * Constants for ID ranges\n */\nexport const INVALID_COMPONENT_ID = 0;\nexport const COMPONENT_ID_MAX = 1023;\nexport const ENTITY_ID_START = 1024;\n\n/**\n * Constants for relation ID encoding\n */\nexport const RELATION_SHIFT = 2 ** 42;\nexport const WILDCARD_TARGET_ID = 0;\n\n/**\n * Create a component ID\n * @param id Component identifier (1-1023)\n * @internal This function is for internal use and testing only. Use `component()` to create components.\n * @see component\n */\nexport function createComponentId<T = void>(id: number): ComponentId<T> {\n if (id < 1 || id > COMPONENT_ID_MAX) {\n throw new Error(`Component ID must be between 1 and ${COMPONENT_ID_MAX}`);\n }\n return id as ComponentId<T>;\n}\n\n/**\n * Create an entity ID\n * @param id Entity identifier (starting from 1024)\n */\nexport function createEntityId(id: number): EntityId {\n if (id < ENTITY_ID_START) {\n throw new Error(`Entity ID must be ${ENTITY_ID_START} or greater`);\n }\n return id as EntityId;\n}\n\n/**\n * Type for relation ID based on component and target types\n */\ntype RelationIdType<T, R> =\n R extends ComponentId<infer U>\n ? U extends void\n ? ComponentRelationId<T>\n : ComponentRelationId<T extends void ? U : T>\n : R extends EntityId<any>\n ? EntityRelationId<T>\n : never;\n\n/**\n * Create a relation ID by associating a component with another ID (entity or component)\n * @param componentId The component ID (0-1023)\n * @param targetId The target ID (entity, component, or '*' for wildcard)\n */\nexport function relation<T>(componentId: ComponentId<T>, targetId: \"*\"): WildcardRelationId<T>;\nexport function relation<T, R extends EntityId<any>>(componentId: ComponentId<T>, targetId: R): RelationIdType<T, R>;\nexport function relation<T>(componentId: ComponentId<T>, targetId: EntityId<any> | \"*\"): EntityId<any> {\n if (!isComponentId(componentId)) {\n throw new Error(\"First argument must be a valid component ID\");\n }\n\n let actualTargetId: number;\n if (targetId === \"*\") {\n actualTargetId = WILDCARD_TARGET_ID;\n } else {\n if (!isEntityId(targetId) && !isComponentId(targetId)) {\n throw new Error(\"Second argument must be a valid entity ID, component ID, or '*'\");\n }\n actualTargetId = targetId;\n }\n\n // Encode: negative number with component_id * 2^42 + target_id\n return -(componentId * RELATION_SHIFT + actualTargetId) as EntityId<any>;\n}\n\n/**\n * Check if an ID is a component ID\n */\nexport function isComponentId<T>(id: EntityId<T>): id is ComponentId<T> {\n return id >= 1 && id <= COMPONENT_ID_MAX;\n}\n\n/**\n * Check if an ID is an entity ID\n */\nexport function isEntityId<T>(id: EntityId<T>): id is EntityId<T> {\n return id >= ENTITY_ID_START;\n}\n\n/**\n * Check if an ID is a relation ID\n */\nexport function isRelationId<T>(id: EntityId<T>): id is RelationId<T> {\n return id < 0;\n}\n\n/**\n * Check if an ID is a wildcard relation id\n */\nexport function isWildcardRelationId<T>(id: EntityId<T>): id is WildcardRelationId<T> {\n if (!isRelationId(id)) {\n return false;\n }\n const absId = -id;\n const targetId = absId % RELATION_SHIFT;\n return targetId === WILDCARD_TARGET_ID;\n}\n\n/**\n * Decode a relation ID into component and target IDs\n * @param relationId The relation ID (must be negative)\n * @returns Object with componentId, targetId, and relation type\n */\nexport function decodeRelationId(relationId: RelationId<any>): {\n componentId: ComponentId<any>;\n targetId: EntityId<any>;\n type: \"entity\" | \"component\" | \"wildcard\";\n} {\n if (!isRelationId(relationId)) {\n throw new Error(\"ID is not a relation ID\");\n }\n const absId = -relationId;\n\n const componentId = Math.floor(absId / RELATION_SHIFT) as ComponentId<any>;\n const targetId = (absId % RELATION_SHIFT) as EntityId<any>;\n\n // Determine type based on targetId range\n if (targetId === WILDCARD_TARGET_ID) {\n return { componentId, targetId, type: \"wildcard\" };\n } else if (isEntityId(targetId)) {\n return { componentId, targetId, type: \"entity\" };\n } else if (isComponentId(targetId)) {\n return { componentId, targetId, type: \"component\" };\n } else {\n throw new Error(\"Invalid target ID in relation\");\n }\n}\n\n/**\n * Get the string representation of an ID type\n */\nexport function getIdType(\n id: EntityId<any>,\n): \"component\" | \"entity\" | \"entity-relation\" | \"component-relation\" | \"wildcard-relation\" | \"invalid\" {\n if (isComponentId(id)) return \"component\";\n if (isEntityId(id)) return \"entity\";\n\n if (isRelationId(id)) {\n try {\n const decoded = decodeRelationId(id);\n // Validate that componentId and targetId are valid\n if (\n !isComponentId(decoded.componentId) ||\n (decoded.type !== \"wildcard\" && !isEntityId(decoded.targetId) && !isComponentId(decoded.targetId))\n ) {\n return \"invalid\";\n }\n switch (decoded.type) {\n case \"entity\":\n return \"entity-relation\";\n case \"component\":\n return \"component-relation\";\n case \"wildcard\":\n return \"wildcard-relation\";\n }\n } catch (error) {\n return \"invalid\"; // fallback for invalid relation IDs\n }\n }\n\n return \"invalid\"; // fallback for unknown/invalid IDs\n}\n\n/**\n * Get detailed type information for an EntityId\n * @param id The EntityId to analyze\n * @returns Detailed type information including relation subtypes\n */\nexport function getDetailedIdType(id: EntityId<any>):\n | {\n type: \"component\" | \"entity\" | \"invalid\";\n componentId?: never;\n targetId?: never;\n }\n | {\n type: \"entity-relation\" | \"wildcard-relation\";\n componentId: ComponentId<any>;\n targetId: EntityId<any>;\n }\n | {\n type: \"component-relation\";\n componentId: ComponentId<any>;\n targetId: ComponentId<any>;\n } {\n if (isComponentId(id)) {\n return { type: \"component\" };\n }\n\n if (isEntityId(id)) {\n return { type: \"entity\" };\n }\n\n if (isRelationId(id)) {\n try {\n const decoded = decodeRelationId(id);\n // Validate that componentId and targetId are valid\n if (\n !isComponentId(decoded.componentId) ||\n (decoded.type !== \"wildcard\" && !isEntityId(decoded.targetId) && !isComponentId(decoded.targetId))\n ) {\n return { type: \"invalid\" };\n }\n let type: \"entity-relation\" | \"component-relation\" | \"wildcard-relation\";\n\n switch (decoded.type) {\n case \"entity\":\n type = \"entity-relation\";\n break;\n case \"component\":\n type = \"component-relation\";\n break;\n case \"wildcard\":\n type = \"wildcard-relation\";\n break;\n }\n\n return {\n type,\n componentId: decoded.componentId,\n targetId: decoded.targetId as any,\n };\n } catch (error) {\n // Invalid relation ID\n return { type: \"invalid\" };\n }\n }\n\n // Unknown/invalid ID\n return { type: \"invalid\" };\n}\n\n/**\n * Inspect an EntityId and return a human-readable string representation\n * @param id The EntityId to inspect\n * @returns A friendly string representation of the ID\n */\nexport function inspectEntityId(id: EntityId<any>): string {\n if (id === INVALID_COMPONENT_ID) {\n return \"Invalid Component ID (0)\";\n }\n\n if (isComponentId(id)) {\n return `Component ID (${id})`;\n }\n\n if (isEntityId(id)) {\n return `Entity ID (${id})`;\n }\n\n if (isRelationId(id)) {\n try {\n const decoded = decodeRelationId(id);\n // Validate that both component and target IDs are valid\n if (\n !isComponentId(decoded.componentId) ||\n (decoded.type !== \"wildcard\" && !isEntityId(decoded.targetId) && !isComponentId(decoded.targetId))\n ) {\n return `Invalid Relation ID (${id})`;\n }\n const componentStr = `Component ID (${decoded.componentId})`;\n const targetStr =\n decoded.type === \"entity\"\n ? `Entity ID (${decoded.targetId})`\n : decoded.type === \"component\"\n ? `Component ID (${decoded.targetId})`\n : \"Wildcard (*)\";\n return `Relation ID: ${componentStr} -> ${targetStr}`;\n } catch (error) {\n return `Invalid Relation ID (${id})`;\n }\n }\n\n return `Unknown ID (${id})`;\n}\n\n/**\n * Entity ID Manager for automatic allocation and freelist recycling\n */\nexport class EntityIdManager {\n private nextId: number = ENTITY_ID_START;\n private freelist: Set<EntityId> = new Set();\n\n /**\n * Allocate a new entity ID\n * Uses freelist if available, otherwise increments counter\n */\n allocate(): EntityId {\n if (this.freelist.size > 0) {\n const id = this.freelist.values().next().value!;\n this.freelist.delete(id);\n return id;\n } else {\n const id = this.nextId;\n this.nextId++;\n // Check for overflow (though unlikely in practice)\n if (this.nextId >= Number.MAX_SAFE_INTEGER) {\n throw new Error(\"Entity ID overflow: reached maximum safe integer\");\n }\n return id as EntityId;\n }\n }\n\n /**\n * Deallocate an entity ID, adding it to the freelist for reuse\n * @param id The entity ID to deallocate\n */\n deallocate(id: EntityId<any>): void {\n if (!isEntityId(id)) {\n throw new Error(\"Can only deallocate valid entity IDs\");\n }\n if (id >= this.nextId) {\n throw new Error(\"Cannot deallocate an ID that was never allocated\");\n }\n this.freelist.add(id);\n }\n\n /**\n * Get the current freelist size (for debugging/monitoring)\n */\n getFreelistSize(): number {\n return this.freelist.size;\n }\n\n /**\n * Get the next ID that would be allocated (for debugging)\n */\n getNextId(): number {\n return this.nextId;\n }\n\n /**\n * Serialize internal state for persistence.\n * Returns a plain object representing allocator state. Values may be non-JSON-serializable.\n */\n serializeState(): { nextId: number; freelist: number[] } {\n return { nextId: this.nextId, freelist: Array.from(this.freelist) };\n }\n\n /**\n * Restore internal state from a previously-serialized object.\n * Overwrites the current nextId and freelist.\n */\n deserializeState(state: { nextId: number; freelist?: number[] }): void {\n if (typeof state.nextId !== \"number\") {\n throw new Error(\"Invalid state for EntityIdManager.deserializeState\");\n }\n this.nextId = state.nextId;\n this.freelist = new Set((state.freelist || []) as EntityId[]);\n }\n}\n\n/**\n * Component ID Manager for automatic allocation\n * Components are typically registered once and not recycled\n */\nexport class ComponentIdAllocator {\n private nextId: number = 1;\n\n /**\n * Allocate a new component ID\n * Increments counter sequentially from 1\n */\n allocate<T = void>(): ComponentId<T> {\n if (this.nextId > COMPONENT_ID_MAX) {\n throw new Error(`Component ID overflow: maximum ${COMPONENT_ID_MAX} components allowed`);\n }\n const id = this.nextId;\n this.nextId++;\n return id as ComponentId<T>;\n }\n\n /**\n * Get the next ID that would be allocated (for debugging)\n */\n getNextId(): number {\n return this.nextId;\n }\n\n /**\n * Check if more component IDs are available\n */\n hasAvailableIds(): boolean {\n return this.nextId <= COMPONENT_ID_MAX;\n }\n}\n\nconst globalComponentIdAllocator = new ComponentIdAllocator();\n\nconst ComponentNames: Map<ComponentId<any>, string> = new Map();\nconst ComponentIdForNames: Map<string, ComponentId<any>> = new Map();\n\n/**\n * Component options that define intrinsic properties\n */\nexport interface ComponentOptions {\n /**\n * Optional name for the component (for serialization/debugging)\n */\n name?: string;\n /**\n * If true, an entity can have at most one relation per base component.\n * When adding a new relation with the same base component, any existing relations\n * with that base component are automatically removed.\n * Only applicable to relation components.\n */\n exclusive?: boolean;\n /**\n * If true, when a relation target entity is deleted, all entities that reference\n * it through this component will also be deleted (cascade delete).\n * Only applicable to entity-relation components.\n */\n cascadeDelete?: boolean;\n /**\n * If true, relations with this component will not cause archetype fragmentation.\n * Entities with different target entities for this relation component will be stored\n * in the same archetype, preventing fragmentation when there are many different targets.\n * Only applicable to relation components.\n * Inspired by Flecs' DontFragment trait.\n */\n dontFragment?: boolean;\n}\n\nconst ComponentOptions: Map<ComponentId<any>, ComponentOptions> = new Map();\n\n/**\n * Allocate a new component ID from the global allocator.\n * @param nameOrOptions Optional name for the component (for serialization/debugging) or options object\n * @returns The allocated component ID\n * @example\n * // Just a name\n * const Position = component<Position>(\"Position\");\n *\n * // With options\n * const ChildOf = component({ exclusive: true, cascadeDelete: true });\n *\n * // With name and options\n * const ChildOf = component({ name: \"ChildOf\", exclusive: true });\n */\nexport function component<T = void>(nameOrOptions?: string | ComponentOptions): ComponentId<T> {\n const id = globalComponentIdAllocator.allocate<T>();\n\n let name: string | undefined;\n let options: ComponentOptions | undefined;\n\n // Parse the parameter\n if (typeof nameOrOptions === \"string\") {\n name = nameOrOptions;\n } else if (typeof nameOrOptions === \"object\" && nameOrOptions !== null) {\n options = nameOrOptions;\n name = options.name;\n }\n\n // Register name if provided\n if (name) {\n if (ComponentIdForNames.has(name)) {\n throw new Error(`Component name \"${name}\" is already registered`);\n }\n\n ComponentNames.set(id, name);\n ComponentIdForNames.set(name, id);\n }\n\n // Register options if provided\n if (options) {\n ComponentOptions.set(id, options);\n }\n\n return id;\n}\n\n/**\n * Get a component ID by its registered name\n * @param name The component name\n * @returns The component ID if found, undefined otherwise\n */\nexport function getComponentIdByName(name: string): ComponentId<any> | undefined {\n return ComponentIdForNames.get(name);\n}\n\n/** Get a component name by its ID\n * @param id The component ID\n * @returns The component name if found, undefined otherwise\n */\nexport function getComponentNameById(id: ComponentId<any>): string | undefined {\n return ComponentNames.get(id);\n}\n\n/**\n * Get component options by its ID\n * @param id The component ID\n * @returns The component options if found, undefined otherwise\n */\nexport function getComponentOptions(id: ComponentId<any>): ComponentOptions | undefined {\n return ComponentOptions.get(id);\n}\n\n/**\n * Check if a component is marked as exclusive\n * @param id The component ID\n * @returns true if the component is exclusive, false otherwise\n */\nexport function isExclusiveComponent(id: ComponentId<any>): boolean {\n return ComponentOptions.get(id)?.exclusive ?? false;\n}\n\n/**\n * Check if a component is marked as cascade delete\n * @param id The component ID\n * @returns true if the component is cascade delete, false otherwise\n */\nexport function isCascadeDeleteComponent(id: ComponentId<any>): boolean {\n return ComponentOptions.get(id)?.cascadeDelete ?? false;\n}\n\n/**\n * Check if a component is marked as dontFragment\n * @param id The component ID\n * @returns true if the component is dontFragment, false otherwise\n */\nexport function isDontFragmentComponent(id: ComponentId<any>): boolean {\n return ComponentOptions.get(id)?.dontFragment ?? false;\n}\n","import type { EntityId, WildcardRelationId } from \"./entity\";\n\n/**\n * Hook types for component lifecycle events\n */\nexport interface LifecycleHook<T = unknown> {\n /**\n * Called when a component is added to an entity\n */\n on_init?: (entityId: EntityId, componentType: EntityId<T>, component: T) => void;\n /**\n * Called when a component is added to an entity\n */\n on_set?: (entityId: EntityId, componentType: EntityId<T>, component: T) => void;\n /**\n * Called when a component is deleted from an entity\n */\n on_remove?: (entityId: EntityId, componentType: EntityId<T>, component: T) => void;\n}\n\nexport type ComponentType<T> = EntityId<T> | OptionalEntityId<T>;\n\nexport type OptionalEntityId<T> = { optional: EntityId<T> };\n\nexport function isOptionalEntityId<T>(type: ComponentType<T>): type is OptionalEntityId<T> {\n return typeof type === \"object\" && type !== null && \"optional\" in type;\n}\n\nexport type ComponentTypeToData<T> = T extends { optional: infer U }\n ? { value: ComponentTypeToData<U> } | undefined\n : T extends WildcardRelationId<infer U>\n ? [EntityId<unknown>, U][]\n : T extends EntityId<infer U>\n ? U\n : never;\n\n/**\n * Type helper for component tuples extracted from EntityId array\n */\nexport type ComponentTuple<T extends readonly ComponentType<any>[]> = {\n readonly [K in keyof T]: ComponentTypeToData<T[K]>;\n};\n","/**\n * Utility functions for ECS library\n */\n\n/**\n * Get a value from cache or compute and cache it if not present\n * @param cache The cache map\n * @param key The cache key\n * @param compute Function to compute the value if not cached\n * @returns The cached or computed value\n */\nexport function getOrComputeCache<K, V>(cache: Map<K, V>, key: K, compute: () => V): V {\n let value = cache.get(key);\n if (value === undefined) {\n value = compute();\n cache.set(key, value);\n }\n return value;\n}\n\n/**\n * Get a value from cache or create and cache it if not present, allowing side effects during creation\n * @param cache The cache map\n * @param key The cache key\n * @param create Function to create the value if not cached (can have side effects)\n * @returns The cached or created value\n */\nexport function getOrCreateWithSideEffect<K, V>(cache: Map<K, V>, key: K, create: () => V): V {\n let value = cache.get(key);\n if (value === undefined) {\n value = create();\n cache.set(key, value);\n }\n return value;\n}\n","import type { EntityId, RelationId, WildcardRelationId } from \"./entity\";\nimport {\n decodeRelationId,\n getDetailedIdType,\n getIdType,\n isDontFragmentComponent,\n isWildcardRelationId,\n} from \"./entity\";\nimport { isOptionalEntityId, type ComponentTuple, type ComponentType } from \"./types\";\nimport { getOrComputeCache } from \"./utils\";\n\n/**\n * Special value to represent missing component data\n */\nexport const MISSING_COMPONENT = Symbol(\"missing component\");\n\n/**\n * Archetype class for ECS architecture\n * Represents a group of entities that share the same set of components\n * Optimized for fast iteration and component access\n */\nexport class Archetype {\n /**\n * The component types that define this archetype\n */\n public readonly componentTypes: EntityId<any>[];\n\n /**\n * List of entities in this archetype\n */\n private entities: EntityId[] = [];\n\n /**\n * Component data storage - maps component type to array of component data\n * Each array index corresponds to the entity index in the entities array\n */\n private componentData: Map<EntityId<any>, any[]> = new Map();\n\n /**\n * Reverse mapping from entity to its index in this archetype\n */\n private entityToIndex: Map<EntityId, number> = new Map();\n\n /**\n * Reference to dontFragment relations storage from World\n * This allows entities with different relation targets to share the same archetype\n * Stored in World to avoid migration overhead when entities change archetypes\n */\n private dontFragmentRelations: Map<EntityId, Map<EntityId<any>, any>>;\n\n /**\n * Cache for pre-computed component data sources to avoid repeated calculations\n * For regular components: data array\n * For wildcards: matching relation types array\n */\n private componentDataSourcesCache: Map<string, (any[] | EntityId<any>[] | undefined)[]> = new Map();\n\n /**\n * Create a new archetype with the specified component types\n * @param componentTypes The component types that define this archetype\n * @param dontFragmentRelations Reference to the World's dontFragmentRelations storage\n */\n constructor(componentTypes: EntityId<any>[], dontFragmentRelations: Map<EntityId, Map<EntityId<any>, any>>) {\n this.componentTypes = [...componentTypes].sort((a, b) => a - b); // Sort for consistent ordering\n this.dontFragmentRelations = dontFragmentRelations;\n\n // Initialize component data arrays\n for (const componentType of this.componentTypes) {\n this.componentData.set(componentType, []);\n }\n }\n\n /**\n * Get the number of entities in this archetype\n */\n get size(): number {\n return this.entities.length;\n }\n\n /**\n * Check if this archetype matches the given component types\n * @param componentTypes The component types to check\n */\n matches(componentTypes: EntityId<any>[]): boolean {\n if (this.componentTypes.length !== componentTypes.length) {\n return false;\n }\n const sortedTypes = [...componentTypes].sort((a, b) => a - b);\n return this.componentTypes.every((type, index) => type === sortedTypes[index]);\n }\n\n /**\n * Add an entity to this archetype with initial component data\n * @param entityId The entity to add\n * @param componentData Map of component type to component data (includes both regular and dontFragment components)\n */\n addEntity(entityId: EntityId, componentData: Map<EntityId<any>, any>): void {\n if (this.entityToIndex.has(entityId)) {\n throw new Error(`Entity ${entityId} is already in this archetype`);\n }\n\n const index = this.entities.length;\n this.entities.push(entityId);\n this.entityToIndex.set(entityId, index);\n\n // Add component data for regular components (those in the archetype signature)\n for (const componentType of this.componentTypes) {\n const data = componentData.get(componentType);\n this.getComponentData(componentType).push(data === undefined ? MISSING_COMPONENT : data);\n }\n\n // Add dontFragment relations separately\n const dontFragmentData = new Map<EntityId<any>, any>();\n for (const [componentType, data] of componentData) {\n // Skip if already added as regular component\n if (this.componentTypes.includes(componentType)) {\n continue;\n }\n\n // Check if this is a dontFragment relation\n const detailedType = getDetailedIdType(componentType);\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isDontFragmentComponent(detailedType.componentId!)\n ) {\n dontFragmentData.set(componentType, data);\n }\n }\n\n if (dontFragmentData.size > 0) {\n this.dontFragmentRelations.set(entityId, dontFragmentData);\n }\n }\n\n /**\n * Get all component data for a specific entity\n * @param entityId The entity to get data for\n * @returns Map of component type to component data (includes both regular and dontFragment components)\n */\n getEntity(entityId: EntityId): Map<EntityId<any>, any> | undefined {\n const index = this.entityToIndex.get(entityId);\n if (index === undefined) {\n return undefined;\n }\n\n const entityData = new Map<EntityId<any>, any>();\n for (const componentType of this.componentTypes) {\n const dataArray = this.getComponentData(componentType);\n const data = dataArray[index];\n entityData.set(componentType, data === MISSING_COMPONENT ? undefined : data);\n }\n\n // Add dontFragment relations\n const dontFragmentData = this.dontFragmentRelations.get(entityId);\n if (dontFragmentData) {\n for (const [componentType, data] of dontFragmentData) {\n entityData.set(componentType, data);\n }\n }\n\n return entityData;\n }\n\n /**\n * Dump all entities and their component data in this archetype\n * @returns Array of objects with entity and component data (includes both regular and dontFragment components)\n */\n dump(): Array<{\n entity: EntityId;\n components: Map<EntityId<any>, any>;\n }> {\n const result: Array<{\n entity: EntityId;\n components: Map<EntityId<any>, any>;\n }> = [];\n\n for (let i = 0; i < this.entities.length; i++) {\n const entity = this.entities[i]!;\n const components = new Map<EntityId<any>, any>();\n for (const componentType of this.componentTypes) {\n const dataArray = this.getComponentData(componentType);\n const data = dataArray[i];\n components.set(componentType, data === MISSING_COMPONENT ? undefined : data);\n }\n\n // Add dontFragment relations\n const dontFragmentData = this.dontFragmentRelations.get(entity);\n if (dontFragmentData) {\n for (const [componentType, data] of dontFragmentData) {\n components.set(componentType, data);\n }\n }\n\n result.push({ entity, components });\n }\n\n return result;\n }\n\n /**\n * Remove an entity from this archetype\n * @param entityId The entity to remove\n * @returns The component data of the removed entity (includes both regular and dontFragment components)\n */\n removeEntity(entityId: EntityId): Map<EntityId<any>, any> | undefined {\n const index = this.entityToIndex.get(entityId);\n if (index === undefined) {\n return undefined;\n }\n\n // Extract component data before removal\n const removedData = new Map<EntityId<any>, any>();\n for (const componentType of this.componentTypes) {\n const dataArray = this.getComponentData(componentType);\n removedData.set(componentType, dataArray[index]);\n }\n\n // Include dontFragment relations in removed data\n const dontFragmentData = this.dontFragmentRelations.get(entityId);\n if (dontFragmentData) {\n for (const [componentType, data] of dontFragmentData) {\n removedData.set(componentType, data);\n }\n this.dontFragmentRelations.delete(entityId);\n }\n\n this.entityToIndex.delete(entityId);\n\n // Use swap-and-pop strategy for O(1) removal instead of O(n) splice\n const lastIndex = this.entities.length - 1;\n if (index !== lastIndex) {\n // Swap with last entity\n const lastEntity = this.entities[lastIndex]!;\n this.entities[index] = lastEntity;\n this.entityToIndex.set(lastEntity, index);\n\n // Swap component data for all components\n for (const componentType of this.componentTypes) {\n const dataArray = this.getComponentData(componentType);\n dataArray[index] = dataArray[lastIndex];\n }\n }\n\n // Remove the last element (now O(1))\n this.entities.pop();\n for (const componentType of this.componentTypes) {\n this.getComponentData(componentType).pop();\n }\n\n return removedData;\n }\n\n /**\n * Check if an entity is in this archetype\n * @param entityId The entity to check\n */\n exists(entityId: EntityId): boolean {\n return this.entityToIndex.has(entityId);\n }\n\n /**\n * Get component data for a specific entity and wildcard relation type\n * Returns an array of all matching relation instances\n * @param entityId The entity\n * @param componentType The wildcard relation type\n */\n get<T>(entityId: EntityId, componentType: WildcardRelationId<T>): [EntityId<unknown>, any][];\n /**\n * Get component data for a specific entity and component type\n * @param entityId The entity\n * @param componentType The component type\n */\n get<T>(entityId: EntityId, componentType: EntityId<T>): T;\n get<T>(entityId: EntityId, componentType: EntityId<T> | WildcardRelationId<T>): T | [EntityId<unknown>, any][] {\n const index = this.entityToIndex.get(entityId);\n if (index === undefined) {\n throw new Error(`Entity ${entityId} is not in this archetype`);\n }\n\n if (isWildcardRelationId(componentType)) {\n const decoded = decodeRelationId(componentType);\n const componentId = decoded.componentId;\n const relations: [EntityId<unknown>, any][] = [];\n\n // Check regular archetype components\n for (const relType of this.componentTypes) {\n const relDetailed = getDetailedIdType(relType);\n if (\n (relDetailed.type === \"entity-relation\" || relDetailed.type === \"component-relation\") &&\n relDetailed.componentId === componentId\n ) {\n const dataArray = this.getComponentData(relType);\n if (dataArray && dataArray[index] !== undefined) {\n const data = dataArray[index];\n relations.push([relDetailed.targetId, data === MISSING_COMPONENT ? undefined : data]);\n }\n }\n }\n\n // Check dontFragment relations\n const dontFragmentData = this.dontFragmentRelations.get(entityId);\n if (dontFragmentData) {\n for (const [relType, data] of dontFragmentData) {\n const relDetailed = getDetailedIdType(relType);\n if (\n (relDetailed.type === \"entity-relation\" || relDetailed.type === \"component-relation\") &&\n relDetailed.componentId === componentId\n ) {\n relations.push([relDetailed.targetId, data]);\n }\n }\n }\n\n return relations;\n } else {\n // First check if it's in the archetype signature\n if (this.componentTypes.includes(componentType)) {\n const data = this.getComponentData(componentType)[index]!;\n return data === MISSING_COMPONENT ? (undefined as T) : data;\n }\n\n // Check dontFragment relations\n const dontFragmentData = this.dontFragmentRelations.get(entityId);\n if (dontFragmentData && dontFragmentData.has(componentType)) {\n return dontFragmentData.get(componentType);\n }\n\n throw new Error(`Component type ${componentType} not found for entity ${entityId}`);\n }\n }\n\n /**\n * Set component data for a specific entity and component type\n * @param entityId The entity\n * @param componentType The component type\n * @param data The component data\n */\n set<T>(entityId: EntityId, componentType: EntityId<T>, data: T): void {\n const index = this.entityToIndex.get(entityId);\n if (index === undefined) {\n throw new Error(`Entity ${entityId} is not in this archetype`);\n }\n\n // Check if it's in the archetype signature\n if (this.componentData.has(componentType)) {\n const dataArray = this.getComponentData(componentType);\n dataArray[index] = data;\n return;\n }\n\n // Check if it's a dontFragment relation\n const detailedType = getDetailedIdType(componentType);\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isDontFragmentComponent(detailedType.componentId!)\n ) {\n let dontFragmentData = this.dontFragmentRelations.get(entityId);\n if (!dontFragmentData) {\n dontFragmentData = new Map();\n this.dontFragmentRelations.set(entityId, dontFragmentData);\n }\n dontFragmentData.set(componentType, data);\n return;\n }\n\n throw new Error(`Component type ${componentType} is not in this archetype`);\n }\n\n /**\n * Get all entities in this archetype\n */\n getEntities(): EntityId[] {\n return this.entities;\n }\n\n /**\n * Get the mapping of entities to their indices in this archetype\n */\n getEntityToIndexMap(): Map<EntityId, number> {\n return this.entityToIndex;\n }\n\n /**\n * Get component data for all entities of a specific component type\n * @param componentType The component type\n */\n getComponentData<T>(componentType: EntityId<T>): T[] {\n const data = this.componentData.get(componentType);\n if (!data) {\n throw new Error(`Component type ${componentType} is not in this archetype`);\n }\n return data;\n }\n\n /**\n * Get optional component data for all entities of a specific component type\n * @param componentType The component type\n * @returns An array of component data or undefined if not present\n */\n getOptionalComponentData<T>(componentType: EntityId<T>): T[] | undefined {\n return this.componentData.get(componentType);\n }\n\n /**\n * Helper: compute or return cached data sources for provided componentTypes\n */\n private getCachedComponentDataSources<const T extends readonly ComponentType<any>[]>(\n componentTypes: T,\n ): (any[] | EntityId<any>[] | undefined)[] {\n const cacheKey = this.buildCacheKey(componentTypes);\n return getOrComputeCache(this.componentDataSourcesCache, cacheKey, () =>\n componentTypes.map((compType) => this.getComponentDataSource(compType)),\n );\n }\n\n /**\n * Build cache key for component types\n */\n private buildCacheKey(componentTypes: readonly ComponentType<any>[]): string {\n return componentTypes.map((id) => (isOptionalEntityId(id) ? `opt(${id.optional})` : `${id}`)).join(\",\");\n }\n\n /**\n * Get data source for a single component type\n */\n private getComponentDataSource(compType: ComponentType<any>): any[] | EntityId<any>[] | undefined {\n const optional = isOptionalEntityId(compType);\n const actualType = optional ? compType.optional : compType;\n const detailedType = getDetailedIdType(actualType);\n\n if (detailedType.type === \"wildcard-relation\") {\n return this.getWildcardRelationDataSource(detailedType.componentId, optional);\n } else {\n return optional ? this.getOptionalComponentData(actualType) : this.getComponentData(actualType);\n }\n }\n\n /**\n * Get data source for wildcard relations\n */\n private getWildcardRelationDataSource(componentId: EntityId<any>, optional: boolean): EntityId<any>[] | undefined {\n const matchingRelations = this.componentTypes.filter((ct) => {\n const detailedCt = getDetailedIdType(ct);\n return (\n (detailedCt.type === \"entity-relation\" || detailedCt.type === \"component-relation\") &&\n detailedCt.componentId === componentId\n );\n });\n\n return optional ? (matchingRelations.length > 0 ? matchingRelations : undefined) : matchingRelations;\n }\n\n /**\n * Helper: build component tuples for a specific entity index using precomputed data sources\n */\n private buildComponentsForIndex<const T extends readonly ComponentType<any>[]>(\n componentTypes: T,\n componentDataSources: (any[] | EntityId<any>[] | undefined)[],\n entityIndex: number,\n ): ComponentTuple<T> {\n return componentDataSources.map((dataSource, i) => {\n const compType = componentTypes[i]!;\n return this.buildSingleComponent(compType, dataSource, entityIndex);\n }) as ComponentTuple<T>;\n }\n\n /**\n * Build a single component value from its data source\n */\n private buildSingleComponent(\n compType: ComponentType<any>,\n dataSource: any[] | EntityId<any>[] | undefined,\n entityIndex: number,\n ): any {\n const optional = isOptionalEntityId(compType);\n const actualType = optional ? compType.optional : compType;\n\n if (getIdType(actualType) === \"wildcard-relation\") {\n return this.buildWildcardRelationValue(dataSource, entityIndex, optional);\n } else {\n return this.buildRegularComponentValue(dataSource, entityIndex, optional);\n }\n }\n\n /**\n * Build wildcard relation value from matching relations\n */\n private buildWildcardRelationValue(\n dataSource: any[] | EntityId<any>[] | undefined,\n entityIndex: number,\n optional: boolean,\n ): any {\n if (dataSource === undefined) {\n if (optional) {\n return undefined;\n }\n throw new Error(`No matching relations found for mandatory wildcard relation component type`);\n }\n\n const matchingRelations = dataSource as EntityId<any>[];\n const relations: [EntityId<unknown>, any][] = [];\n\n for (const relType of matchingRelations) {\n const dataArray = this.getComponentData(relType);\n const data = dataArray[entityIndex];\n const decodedRel = decodeRelationId(relType as RelationId<any>);\n relations.push([decodedRel.targetId, data === MISSING_COMPONENT ? undefined : data]);\n }\n\n return optional ? { value: relations } : relations;\n }\n\n /**\n * Build regular component value from data source\n */\n private buildRegularComponentValue(\n dataSource: any[] | EntityId<any>[] | undefined,\n entityIndex: number,\n optional: boolean,\n ): any {\n if (dataSource === undefined) {\n if (optional) {\n return undefined;\n }\n throw new Error(`Component data not found for mandatory component type`);\n }\n\n const dataArray = dataSource as any[];\n const data = dataArray[entityIndex];\n const result = data === MISSING_COMPONENT ? undefined : data;\n\n return optional ? { value: result } : result;\n }\n\n /**\n * Get entities with their component data for specified component types\n * Optimized for bulk component access with pre-computed indices\n * @param componentTypes Array of component types to retrieve\n * @returns Array of objects with entity and component data\n */\n getEntitiesWithComponents<const T extends readonly ComponentType<any>[]>(\n componentTypes: T,\n ): Array<{\n entity: EntityId;\n components: ComponentTuple<T>;\n }> {\n const result: Array<{\n entity: EntityId;\n components: ComponentTuple<T>;\n }> = [];\n\n this.forEachWithComponents(componentTypes, (entity, ...components) => {\n result.push({ entity, components });\n });\n\n return result;\n }\n\n /**\n * Iterate over entities with their component data for specified component types\n * implemented as a generator returning each entity/components pair lazily\n * @param componentTypes Array of component types to retrieve\n */\n *iterateWithComponents<const T extends readonly ComponentType<any>[]>(\n componentTypes: T,\n ): IterableIterator<[EntityId, ...ComponentTuple<T>]> {\n // Reuse the same pre-caching and data access logic as forEachWithComponents\n const componentDataSources = this.getCachedComponentDataSources(componentTypes);\n\n for (let entityIndex = 0; entityIndex < this.entities.length; entityIndex++) {\n const entity = this.entities[entityIndex]!;\n\n const components = this.buildComponentsForIndex(componentTypes, componentDataSources, entityIndex);\n\n yield [entity, ...components];\n }\n }\n\n /**\n * Iterate over entities with their component data for specified component types\n * Optimized for bulk component access\n * @param componentTypes Array of component types to retrieve\n * @param callback Function called for each entity with its components\n */\n forEachWithComponents<const T extends readonly ComponentType<any>[]>(\n componentTypes: T,\n callback: (entity: EntityId, ...components: ComponentTuple<T>) => void,\n ): void {\n // Create a cache key from component types\n const componentDataSources = this.getCachedComponentDataSources(componentTypes);\n\n for (let entityIndex = 0; entityIndex < this.entities.length; entityIndex++) {\n const entity = this.entities[entityIndex]!;\n\n // Direct array access for each component type using pre-cached sources\n const components = this.buildComponentsForIndex(componentTypes, componentDataSources, entityIndex);\n\n callback(entity, ...components);\n }\n }\n\n /**\n * Iterate over all entities with their component data\n * @param callback Function called for each entity with its component data\n */\n forEach(callback: (entityId: EntityId, components: Map<EntityId<any>, any>) => void): void {\n for (let i = 0; i < this.entities.length; i++) {\n const components = new Map<EntityId<any>, any>();\n for (const componentType of this.componentTypes) {\n const data = this.getComponentData(componentType)[i];\n components.set(componentType, data === MISSING_COMPONENT ? undefined : data);\n }\n callback(this.entities[i]!, components);\n }\n }\n}\n","import type { EntityId } from \"./entity\";\n\n/**\n * @internal Represents a set of component changes to be applied to an entity\n */\nexport class ComponentChangeset {\n readonly adds = new Map<EntityId<any>, any>();\n readonly removes = new Set<EntityId<any>>();\n\n /**\n * Add a component to the changeset\n */\n set<T>(componentType: EntityId<T>, component: T): void {\n this.adds.set(componentType, component);\n this.removes.delete(componentType); // Remove from removes if it was going to be removed\n }\n\n /**\n * Remove a component from the changeset\n */\n delete<T>(componentType: EntityId<T>): void {\n this.removes.add(componentType);\n this.adds.delete(componentType); // Remove from adds if it was going to be added\n }\n\n /**\n * Check if the changeset has any changes\n */\n hasChanges(): boolean {\n return this.adds.size > 0 || this.removes.size > 0;\n }\n\n /**\n * Clear all changes\n */\n clear(): void {\n this.adds.clear();\n this.removes.clear();\n }\n\n /**\n * Merge another changeset into this one\n */\n merge(other: ComponentChangeset): void {\n // Merge additions\n for (const [componentType, component] of other.adds) {\n this.adds.set(componentType, component);\n this.removes.delete(componentType);\n }\n // Merge removals\n for (const componentType of other.removes) {\n this.removes.add(componentType);\n this.adds.delete(componentType);\n }\n }\n\n /**\n * Apply the changeset to existing components and return the final state\n */\n applyTo(existingComponents: Map<EntityId<any>, any>): Map<EntityId<any>, any> {\n // Apply removals\n for (const componentType of this.removes) {\n existingComponents.delete(componentType);\n }\n\n // Apply additions/updates\n for (const [componentType, component] of this.adds) {\n existingComponents.set(componentType, component);\n }\n\n return existingComponents;\n }\n\n /**\n * Get the final component types after applying the changeset\n * @param existingComponentTypes - The current component types on the entity\n * @returns The final component types or undefined if no changes\n */\n getFinalComponentTypes(existingComponentTypes: EntityId<any>[]): EntityId<any>[] | undefined {\n const finalComponentTypes = new Set<EntityId<any>>(existingComponentTypes);\n let changed = false;\n\n // Apply removals\n for (const componentType of this.removes) {\n if (!finalComponentTypes.has(componentType)) {\n this.removes.delete(componentType);\n continue; // Component not present, skip\n }\n changed = true;\n finalComponentTypes.delete(componentType);\n }\n\n // Apply additions\n for (const componentType of this.adds.keys()) {\n if (finalComponentTypes.has(componentType)) {\n continue; // Component already present, skip\n }\n changed = true;\n finalComponentTypes.add(componentType);\n }\n\n return changed ? Array.from(finalComponentTypes) : undefined;\n }\n}\n","import type { EntityId } from \"./entity\";\n\n/**\n * Command for deferred execution\n */\nexport interface Command {\n type: \"set\" | \"delete\" | \"destroy\";\n entityId: EntityId;\n componentType?: EntityId<any>;\n component?: any;\n}\n\n/**\n * Command buffer for deferred structural changes\n */\nexport class CommandBuffer {\n private commands: Command[] = [];\n private executeEntityCommands: (entityId: EntityId, commands: Command[]) => void;\n\n /**\n * Create a command buffer with an executor function\n */\n constructor(executeEntityCommands: (entityId: EntityId, commands: Command[]) => void) {\n this.executeEntityCommands = executeEntityCommands;\n }\n\n /**\n * Add a component to an entity (deferred)\n */\n set(entityId: EntityId, componentType: EntityId<void>): void;\n set<T>(entityId: EntityId, componentType: EntityId<T>, component: NoInfer<T>): void;\n set(entityId: EntityId, componentType: EntityId, component?: any): void {\n this.commands.push({ type: \"set\", entityId, componentType, component });\n }\n\n /**\n * Remove a component from an entity (deferred)\n */\n remove<T>(entityId: EntityId, componentType: EntityId<T>): void {\n this.commands.push({ type: \"delete\", entityId, componentType });\n }\n\n /**\n * Destroy an entity (deferred)\n */\n delete(entityId: EntityId): void {\n this.commands.push({ type: \"destroy\", entityId });\n }\n\n /**\n * Execute all commands and clear the buffer\n */\n execute(): void {\n const MAX_ITERATIONS = 100;\n let iterations = 0;\n\n while (this.commands.length > 0) {\n if (iterations >= MAX_ITERATIONS) {\n throw new Error(\"Command execution exceeded maximum iterations, possible infinite loop\");\n }\n iterations++;\n\n const currentCommands = [...this.commands];\n this.commands = [];\n\n // Group commands by entity\n const entityCommands = new Map<EntityId, Command[]>();\n for (const cmd of currentCommands) {\n if (!entityCommands.has(cmd.entityId)) {\n entityCommands.set(cmd.entityId, []);\n }\n entityCommands.get(cmd.entityId)!.push(cmd);\n }\n\n // Process each entity's commands with optimization\n for (const [entityId, commands] of entityCommands) {\n this.executeEntityCommands(entityId, commands);\n }\n }\n }\n\n /**\n * Get current commands (for testing)\n */\n getCommands(): Command[] {\n return [...this.commands];\n }\n\n /**\n * Clear all commands\n */\n clear(): void {\n this.commands = [];\n }\n}\n","// A lightweight generic MultiMap implementation backed by Map<K, Set<V>>.\n// Provides usual operations: add, remove, get, has, keys, values, entries,\n// clear, deleteKey and size accessors.\n\nclass MultiMap<K, V> {\n private map: Map<K, Set<V>> = new Map();\n\n // Number of value entries across all keys (not number of keys).\n private _valueCount = 0;\n\n get valueCount(): number {\n return this._valueCount;\n }\n\n get keyCount(): number {\n return this.map.size;\n }\n\n hasKey(key: K): boolean {\n return this.map.has(key);\n }\n\n has(key: K, value?: V): boolean {\n const set = this.map.get(key);\n if (!set) return false;\n if (arguments.length === 1) return true;\n return set.has(value as V);\n }\n\n add(key: K, value: V): void {\n let set = this.map.get(key);\n if (!set) {\n set = new Set();\n this.map.set(key, set);\n }\n if (!set.has(value)) {\n set.add(value);\n this._valueCount++;\n }\n }\n\n // Remove a specific value for a key. Returns true if removed.\n remove(key: K, value: V): boolean {\n const set = this.map.get(key);\n if (!set) return false;\n if (!set.has(value)) return false;\n set.delete(value);\n this._valueCount--;\n if (set.size === 0) this.map.delete(key);\n return true;\n }\n\n // Delete entire key and all its values. Returns true if key existed.\n deleteKey(key: K): boolean {\n const set = this.map.get(key);\n if (!set) return false;\n this._valueCount -= set.size;\n this.map.delete(key);\n return true;\n }\n\n get(key: K): Set<V> {\n const set = this.map.get(key);\n return set ? new Set(set) : new Set();\n }\n\n // iterate keys, values and entries (key -> Set copy)\n *keys(): IterableIterator<K> {\n yield* this.map.keys();\n }\n\n *values(): IterableIterator<V> {\n for (const set of this.map.values()) {\n for (const v of set) yield v;\n }\n }\n\n [Symbol.iterator](): IterableIterator<[K, V]> {\n return this.entries();\n }\n\n *entries(): IterableIterator<[K, V]> {\n for (const [k, set] of this.map.entries()) {\n for (const v of set) yield [k, v];\n }\n }\n\n clear(): void {\n this.map.clear();\n this._valueCount = 0;\n }\n}\n\nexport { MultiMap };\nexport type { MultiMap as MultiMapType };\n","import { Archetype } from \"./archetype\";\nimport type { EntityId } from \"./entity\";\nimport { decodeRelationId, getDetailedIdType, isRelationId } from \"./entity\";\n\n/**\n * Filter options for queries\n */\nexport interface QueryFilter {\n negativeComponentTypes?: EntityId<any>[];\n}\n\n/**\n * Serialize a QueryFilter into a deterministic string suitable for cache keys.\n * Currently only serializes `negativeComponentTypes`.\n */\nexport function serializeQueryFilter(filter: QueryFilter = {}): string {\n const negative = (filter.negativeComponentTypes || []).slice().sort((a, b) => a - b);\n if (negative.length === 0) return \"\";\n return `neg:${negative.join(\",\")}`;\n}\n\n/**\n * Check if an archetype matches the given component types\n */\nexport function matchesComponentTypes(archetype: Archetype, componentTypes: EntityId<any>[]): boolean {\n return componentTypes.every((type) => {\n const detailedType = getDetailedIdType(type);\n if (detailedType.type === \"wildcard-relation\") {\n // For wildcard relations, check if archetype contains the component relation\n return archetype.componentTypes.some((archetypeType) => {\n if (!isRelationId(archetypeType)) return false;\n const decoded = decodeRelationId(archetypeType);\n return decoded.componentId === detailedType.componentId;\n });\n } else {\n // For regular components, check direct inclusion\n return archetype.componentTypes.includes(type);\n }\n });\n}\n\n/**\n * Check if an archetype matches the filter conditions (only filtering logic)\n */\nexport function matchesFilter(archetype: Archetype, filter: QueryFilter): boolean {\n const negativeTypes = filter.negativeComponentTypes || [];\n return negativeTypes.every((type) => {\n const detailedType = getDetailedIdType(type);\n if (detailedType.type === \"wildcard-relation\") {\n // For wildcard relations in negative filter, exclude archetypes that contain ANY relation with the same component\n return !archetype.componentTypes.some((archetypeType) => {\n if (!isRelationId(archetypeType)) return false;\n const decoded = decodeRelationId(archetypeType);\n return decoded.componentId === detailedType.componentId;\n });\n } else {\n // For regular components, check direct exclusion\n return !archetype.componentTypes.includes(type);\n }\n });\n}\n","import { Archetype } from \"./archetype\";\nimport type { EntityId } from \"./entity\";\nimport { matchesComponentTypes, matchesFilter, type QueryFilter } from \"./query-filter\";\nimport type { ComponentTuple, ComponentType } from \"./types\";\nimport type { World } from \"./world\";\n\n/**\n * Query class for efficient entity queries with cached archetypes\n */\nexport class Query {\n private world: World<any[]>;\n private componentTypes: EntityId<any>[];\n private filter: QueryFilter;\n private cachedArchetypes: Archetype[] = [];\n private isDisposed = false;\n\n constructor(world: World<any[]>, componentTypes: EntityId<any>[], filter: QueryFilter = {}) {\n this.world = world;\n this.componentTypes = [...componentTypes].sort((a, b) => a - b);\n this.filter = filter;\n this.updateCache();\n // Register with world for archetype updates\n world._registerQuery(this);\n }\n\n /**\n * Check if query is disposed and throw error if so\n */\n private ensureNotDisposed(): void {\n if (this.isDisposed) {\n throw new Error(\"Query has been disposed\");\n }\n }\n\n /**\n * Get all entities matching the query\n */\n getEntities(): EntityId[] {\n this.ensureNotDisposed();\n const result: EntityId[] = [];\n for (const archetype of this.cachedArchetypes) {\n result.push(...archetype.getEntities());\n }\n return result;\n }\n\n /**\n * Get entities with their component data\n * @param componentTypes Array of component types to retrieve\n * @returns Array of objects with entity and component data\n */\n getEntitiesWithComponents<const T extends readonly ComponentType<any>[]>(\n componentTypes: T,\n ): Array<{\n entity: EntityId;\n components: ComponentTuple<T>;\n }> {\n this.ensureNotDisposed();\n\n const result: Array<{\n entity: EntityId;\n components: ComponentTuple<T>;\n }> = [];\n\n for (const archetype of this.cachedArchetypes) {\n const entitiesWithData = archetype.getEntitiesWithComponents(componentTypes);\n result.push(...entitiesWithData);\n }\n\n return result;\n }\n\n /**\n * Iterate over entities with their component data\n * @param componentTypes Array of component types to retrieve\n * @param callback Function called for each entity with its components\n */\n forEach<const T extends readonly ComponentType<any>[]>(\n componentTypes: T,\n callback: (entity: EntityId, ...components: ComponentTuple<T>) => void,\n ): void {\n this.ensureNotDisposed();\n\n for (const archetype of this.cachedArchetypes) {\n archetype.forEachWithComponents(componentTypes, callback);\n }\n }\n\n /**\n * Iterate over entities with their component data (generator)\n * @param componentTypes Array of component types to retrieve\n */\n *iterate<const T extends readonly ComponentType<any>[]>(\n componentTypes: T,\n ): IterableIterator<[EntityId, ...ComponentTuple<T>]> {\n this.ensureNotDisposed();\n\n for (const archetype of this.cachedArchetypes) {\n yield* archetype.iterateWithComponents(componentTypes);\n }\n }\n\n /**\n * Get component data arrays for all matching entities\n * @param componentType The component type to retrieve\n * @returns Array of component data for all matching entities\n */\n getComponentData<T>(componentType: EntityId<T>): T[] {\n this.ensureNotDisposed();\n\n const result: T[] = [];\n for (const archetype of this.cachedArchetypes) {\n result.push(...archetype.getComponentData(componentType));\n }\n return result;\n }\n\n /**\n * Update the cached archetypes\n * Called when new archetypes are created\n */\n updateCache(): void {\n if (this.isDisposed) return;\n\n this.cachedArchetypes = this.world\n .getMatchingArchetypes(this.componentTypes)\n .filter((archetype: Archetype) => matchesFilter(archetype, this.filter));\n }\n\n /**\n * Check if a new archetype matches this query and add to cache if it does\n */\n checkNewArchetype(archetype: Archetype): void {\n if (this.isDisposed) return;\n if (\n matchesComponentTypes(archetype, this.componentTypes) &&\n matchesFilter(archetype, this.filter) &&\n !this.cachedArchetypes.includes(archetype)\n ) {\n this.cachedArchetypes.push(archetype);\n }\n }\n\n /**\n * Remove an archetype from the cached archetypes\n */\n removeArchetype(archetype: Archetype): void {\n if (this.isDisposed) return;\n const index = this.cachedArchetypes.indexOf(archetype);\n if (index !== -1) {\n this.cachedArchetypes.splice(index, 1);\n }\n }\n\n /**\n * Dispose the query and disconnect from world\n */\n /**\n * Request disposal of this query.\n * This will decrement the world's reference count for the query.\n * The query will only be fully disposed when the ref count reaches zero.\n */\n dispose(): void {\n // Ask the world to release this query (decrement refcount and fully dispose when zero)\n this.world.releaseQuery(this);\n }\n\n /**\n * Internal full dispose called by World when refCount reaches zero.\n */\n _disposeInternal(): void {\n if (!this.isDisposed) {\n // Unregister from world (remove from notification list)\n this.world._unregisterQuery(this);\n this.cachedArchetypes = [];\n this.isDisposed = true;\n }\n }\n\n /**\n * Symbol.dispose implementation for automatic resource management\n */\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n /**\n * Check if the query has been disposed\n */\n get disposed(): boolean {\n return this.isDisposed;\n }\n}\n","import type { System } from \"./system\";\n\n/**\n * System Scheduler for managing system dependencies and execution order\n */\nexport class SystemScheduler<UpdateParams extends any[] = []> {\n private systems = new Set<System<UpdateParams>>();\n private systemDependencies = new Map<System<UpdateParams>, Set<System<UpdateParams>>>();\n private cachedExecutionOrder: System<UpdateParams>[] | null = null;\n\n /**\n * Add a system with optional dependencies\n * @param system The system to add\n * @param additionalDeps Additional dependencies for the system\n */\n addSystem(system: System<UpdateParams>, additionalDeps: System<UpdateParams>[] = []): void {\n this.systems.add(system);\n // Also add dependencies to the set\n for (const dep of system.dependencies || []) {\n this.systems.add(dep);\n }\n this.systemDependencies.set(system, new Set([...additionalDeps, ...(system.dependencies || [])]));\n this.cachedExecutionOrder = null;\n }\n\n /**\n * Get the execution order of systems based on dependencies\n * Uses topological sort\n */\n getExecutionOrder(): System<UpdateParams>[] {\n if (this.cachedExecutionOrder !== null) {\n return this.cachedExecutionOrder;\n }\n\n const result: System<UpdateParams>[] = [];\n const visited = new Set<System<UpdateParams>>();\n const visiting = new Set<System<UpdateParams>>();\n\n const visit = (system: System<UpdateParams>): void => {\n if (visited.has(system)) return;\n if (visiting.has(system)) {\n throw new Error(\"Circular dependency detected in system scheduling\");\n }\n\n visiting.add(system);\n\n for (const dep of this.systemDependencies.get(system) || []) {\n visit(dep);\n }\n\n visiting.delete(system);\n visited.add(system);\n result.push(system);\n };\n\n for (const system of this.systems) {\n if (!visited.has(system)) {\n visit(system);\n }\n }\n\n this.cachedExecutionOrder = result;\n return result;\n }\n\n update(...params: UpdateParams): Promise<void[]> | void {\n const executionOrder = this.getExecutionOrder();\n const systemPromises = new Map<System<UpdateParams>, Promise<void>>();\n\n for (const system of executionOrder) {\n const deps = Array.from(this.systemDependencies.get(system) || []);\n const depPromises = deps.map((dep) => systemPromises.get(dep)!).filter(Boolean);\n\n if (depPromises.length > 0) {\n const promise = Promise.all(depPromises).then(() => system.update(...params));\n systemPromises.set(system, promise);\n } else {\n const result = system.update(...params);\n if (result instanceof Promise) {\n systemPromises.set(system, result);\n }\n }\n }\n\n return Promise.all(systemPromises.values());\n }\n\n /**\n * Clear all systems and dependencies\n */\n clear(): void {\n this.systems.clear();\n this.cachedExecutionOrder = null;\n }\n}\n","import { Archetype, MISSING_COMPONENT } from \"./archetype\";\nimport { ComponentChangeset } from \"./changeset\";\nimport { CommandBuffer, type Command } from \"./command-buffer\";\nimport type { ComponentId, EntityId, WildcardRelationId } from \"./entity\";\nimport {\n decodeRelationId,\n EntityIdManager,\n getComponentIdByName,\n getComponentNameById,\n getDetailedIdType,\n isCascadeDeleteComponent,\n isDontFragmentComponent,\n isExclusiveComponent,\n isRelationId,\n relation,\n} from \"./entity\";\nimport { MultiMap } from \"./multi-map\";\nimport { Query } from \"./query\";\nimport { serializeQueryFilter, type QueryFilter } from \"./query-filter\";\nimport type { System } from \"./system\";\nimport { SystemScheduler } from \"./system-scheduler\";\nimport type { ComponentTuple, LifecycleHook } from \"./types\";\nimport { getOrCreateWithSideEffect } from \"./utils\";\n\n/**\n * World class for ECS architecture\n * Manages entities, components, and systems\n */\nexport class World<UpdateParams extends any[] = []> {\n // Core data structures for entity and archetype management\n /** Manages allocation and deallocation of entity IDs */\n private entityIdManager = new EntityIdManager();\n\n /** Array of all archetypes in the world */\n private archetypes: Archetype[] = [];\n\n /** Maps archetype signatures (component type signatures) to archetype instances */\n private archetypeBySignature = new Map<string, Archetype>();\n\n /** Maps entity IDs to their current archetype */\n private entityToArchetype = new Map<EntityId, Archetype>();\n\n /** Maps component types to arrays of archetypes that contain them */\n private archetypesByComponent = new Map<EntityId<any>, Archetype[]>();\n\n /** Tracks which entities reference each entity as a component type */\n private entityReferences = new Map<EntityId, MultiMap<EntityId, EntityId>>();\n\n /** Storage for dontFragment relations - maps entity ID to a map of relation type to component data */\n private dontFragmentRelations: Map<EntityId, Map<EntityId<any>, any>> = new Map();\n\n // Query management\n /** Array of all active queries for archetype change notifications */\n private queries: Query[] = [];\n\n /** Cache for queries keyed by component types and filter signatures */\n private queryCache = new Map<string, { query: Query; refCount: number }>();\n\n // System management\n /** Schedules and executes systems in dependency order */\n private systemScheduler = new SystemScheduler<UpdateParams>();\n\n // Command execution\n /** Buffers structural changes for deferred execution */\n private commandBuffer = new CommandBuffer((entityId, commands) => this.executeEntityCommands(entityId, commands));\n\n // Lifecycle and configuration\n /** Stores lifecycle hooks for component and relation events */\n private hooks = new Map<EntityId<any>, Set<LifecycleHook<any>>>();\n\n /**\n * Create a new World.\n * If an optional snapshot object is provided (previously produced by `world.serialize()`),\n * the world will be restored from that snapshot. The snapshot may contain non-JSON values.\n */\n constructor(snapshot?: SerializedWorld) {\n // If snapshot provided, restore world state\n if (snapshot && typeof snapshot === \"object\") {\n if (snapshot.entityManager) {\n this.entityIdManager.deserializeState(snapshot.entityManager);\n }\n\n // Restore entities and their components\n if (Array.isArray(snapshot.entities)) {\n for (const entry of snapshot.entities) {\n const entityId = entry.id as EntityId;\n const componentsArray: SerializedComponent[] = entry.components || [];\n\n const componentMap = new Map<EntityId<any>, any>();\n const componentTypes: EntityId<any>[] = [];\n\n for (const componentEntry of componentsArray) {\n const componentTypeRaw = componentEntry.type;\n let componentType: EntityId<any>;\n\n if (typeof componentTypeRaw === \"number\") {\n componentType = componentTypeRaw as EntityId<any>;\n } else if (typeof componentTypeRaw === \"string\") {\n // Component name lookup\n const compId = getComponentIdByName(componentTypeRaw);\n if (compId === undefined) {\n throw new Error(`Unknown component name in snapshot: ${componentTypeRaw}`);\n }\n componentType = compId;\n } else if (\n typeof componentTypeRaw === \"object\" &&\n componentTypeRaw !== null &&\n typeof componentTypeRaw.component === \"string\"\n ) {\n // Component name lookup\n const compId = getComponentIdByName(componentTypeRaw.component);\n if (compId === undefined) {\n throw new Error(`Unknown component name in snapshot: ${componentTypeRaw.component}`);\n }\n if (typeof componentTypeRaw.target === \"string\") {\n const targetCompId = getComponentIdByName(componentTypeRaw.target);\n if (targetCompId === undefined) {\n throw new Error(`Unknown target component name in snapshot: ${componentTypeRaw.target}`);\n }\n componentType = relation(compId, targetCompId);\n } else {\n componentType = relation(compId, componentTypeRaw.target as EntityId);\n }\n } else {\n throw new Error(`Invalid component type in snapshot: ${JSON.stringify(componentTypeRaw)}`);\n }\n componentMap.set(componentType, componentEntry.value);\n componentTypes.push(componentType);\n }\n\n const archetype = this.ensureArchetype(componentTypes);\n archetype.addEntity(entityId, componentMap);\n this.entityToArchetype.set(entityId, archetype);\n\n // Update reverse index based on component types\n for (const compType of componentTypes) {\n const detailedType = getDetailedIdType(compType);\n if (detailedType.type === \"entity-relation\") {\n const targetEntityId = detailedType.targetId!;\n this.trackEntityReference(entityId, compType, targetEntityId);\n } else if (detailedType.type === \"entity\") {\n this.trackEntityReference(entityId, compType, compType);\n }\n }\n }\n }\n }\n }\n\n /**\n * Generate a signature string for component types array\n * @returns A string signature for the component types\n */\n private createArchetypeSignature(componentTypes: EntityId<any>[]): string {\n return componentTypes.join(\",\");\n }\n\n /**\n * Create a new entity\n * @returns The ID of the newly created entity\n */\n new(): EntityId {\n const entityId = this.entityIdManager.allocate();\n // Create empty archetype for entities with no components\n let emptyArchetype = this.ensureArchetype([]);\n emptyArchetype.addEntity(entityId, new Map());\n this.entityToArchetype.set(entityId, emptyArchetype);\n return entityId;\n }\n\n /**\n * Destroy an entity and remove all its components (immediate execution)\n */\n private destroyEntityImmediate(entityId: EntityId): void {\n // Implement BFS-style cascade deletion for entity relations where cascade is enabled\n const queue: EntityId[] = [entityId];\n const visited = new Set<EntityId>();\n\n while (queue.length > 0) {\n const cur = queue.shift()!;\n if (visited.has(cur)) continue;\n visited.add(cur);\n\n const archetype = this.entityToArchetype.get(cur);\n if (!archetype) {\n continue; // Entity doesn't exist\n }\n\n // Collect references to this entity and iterate\n const componentReferences = Array.from(this.getEntityReferences(cur));\n for (const [sourceEntityId, componentType] of componentReferences) {\n // For each referencing entity, decide whether to cascade delete or simply remove the component\n const sourceArchetype = this.entityToArchetype.get(sourceEntityId);\n if (!sourceArchetype) continue;\n\n const detailedType = getDetailedIdType(componentType);\n // Cascade only applies to entity relations (not component-relation)\n if (detailedType.type === \"entity-relation\" && isCascadeDeleteComponent(detailedType.componentId!)) {\n // Enqueue the referencing entity for deletion (cascade)\n if (!visited.has(sourceEntityId)) {\n queue.push(sourceEntityId);\n }\n continue;\n }\n\n // Non-cascade behavior: remove the relation component from the source entity\n const currentComponents = new Map<EntityId<any>, any>();\n let removedComponent = sourceArchetype.get(sourceEntityId, componentType);\n for (const archetypeComponentType of sourceArchetype.componentTypes) {\n if (archetypeComponentType !== componentType) {\n const componentData = sourceArchetype.get(sourceEntityId, archetypeComponentType);\n currentComponents.set(archetypeComponentType, componentData);\n }\n }\n\n const newArchetype = this.ensureArchetype(currentComponents.keys());\n\n // Remove from current archetype\n sourceArchetype.removeEntity(sourceEntityId);\n if (sourceArchetype.getEntities().length === 0) {\n this.cleanupEmptyArchetype(sourceArchetype);\n }\n\n // Add to new archetype\n newArchetype.addEntity(sourceEntityId, currentComponents);\n this.entityToArchetype.set(sourceEntityId, newArchetype);\n\n // Remove from component reverse index\n this.untrackEntityReference(sourceEntityId, componentType, cur);\n\n // Trigger component removed hooks\n this.triggerLifecycleHooks(sourceEntityId, new Map(), new Map([[componentType, removedComponent]]));\n }\n\n // Clean up the reverse index for this entity\n this.entityReferences.delete(cur);\n\n // Remove the entity itself\n archetype.removeEntity(cur);\n if (archetype.getEntities().length === 0) {\n this.cleanupEmptyArchetype(archetype);\n }\n this.entityToArchetype.delete(cur);\n this.entityIdManager.deallocate(cur);\n }\n }\n\n /**\n * Check if an entity exists\n */\n exists(entityId: EntityId): boolean {\n return this.entityToArchetype.has(entityId);\n }\n\n /**\n * Add a component to an entity (deferred)\n */\n set(entityId: EntityId, componentType: EntityId<void>): void;\n set<T>(entityId: EntityId, componentType: EntityId<T>, component: NoInfer<T>): void;\n set(entityId: EntityId, componentType: EntityId, component?: any): void {\n if (!this.exists(entityId)) {\n throw new Error(`Entity ${entityId} does not exist`);\n }\n\n // Validate component type\n const detailedType = getDetailedIdType(componentType);\n if (detailedType.type === \"invalid\") {\n throw new Error(`Invalid component type: ${componentType}`);\n }\n if (detailedType.type === \"wildcard-relation\") {\n throw new Error(`Cannot directly add wildcard relation components: ${componentType}`);\n }\n\n this.commandBuffer.set(entityId, componentType, component);\n }\n\n /**\n * Remove a component from an entity (deferred)\n */\n remove<T>(entityId: EntityId, componentType: EntityId<T>): void {\n if (!this.exists(entityId)) {\n throw new Error(`Entity ${entityId} does not exist`);\n }\n\n // Validate component type\n const detailedType = getDetailedIdType(componentType);\n if (detailedType.type === \"invalid\") {\n throw new Error(`Invalid component type: ${componentType}`);\n }\n\n this.commandBuffer.remove(entityId, componentType);\n }\n\n /**\n * Destroy an entity and remove all its components (deferred)\n */\n delete(entityId: EntityId): void {\n this.commandBuffer.delete(entityId);\n }\n\n /**\n * Check if an entity has a specific component\n */\n has<T>(entityId: EntityId, componentType: EntityId<T>): boolean {\n const archetype = this.entityToArchetype.get(entityId);\n if (!archetype) {\n return false;\n }\n\n // Check regular archetype components\n if (archetype.componentTypes.includes(componentType)) {\n return true;\n }\n\n // Check dontFragment relations\n const detailedType = getDetailedIdType(componentType);\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isDontFragmentComponent(detailedType.componentId!)\n ) {\n // Check if entity has this dontFragment relation in the shared storage\n return this.dontFragmentRelations.get(entityId)?.has(componentType) ?? false;\n }\n\n return false;\n }\n\n /**\n * Get component data for a specific entity and wildcard relation type\n * Returns an array of all matching relation instances\n * @param entityId The entity\n * @param componentType The wildcard relation type\n * @returns Array of [targetEntityId, componentData] pairs for all matching relations\n */\n get<T>(entityId: EntityId, componentType: WildcardRelationId<T>): [EntityId<unknown>, T][];\n /**\n * Get component data for a specific entity and component type\n * @param entityId The entity\n * @param componentType The component type\n * @returns The component data\n */\n get<T>(entityId: EntityId, componentType: EntityId<T>): T;\n get<T>(entityId: EntityId, componentType: EntityId<T> | WildcardRelationId<T>): T | [EntityId<unknown>, any][] {\n const archetype = this.entityToArchetype.get(entityId);\n if (!archetype) {\n throw new Error(`Entity ${entityId} does not exist`);\n }\n\n // Check if entity has the component before attempting to get it\n // Note: undefined is a valid component value, so we cannot use undefined to check existence\n const detailedType = getDetailedIdType(componentType);\n if (detailedType.type !== \"wildcard-relation\") {\n // For regular components, check if the component type exists in the archetype or dontFragmentRelations\n const inArchetype = archetype.componentTypes.includes(componentType);\n const isDontFragment =\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isDontFragmentComponent(detailedType.componentId!);\n\n // For dontFragment relations, check if it exists in the dontFragmentRelations storage\n const hasComponent =\n inArchetype || (isDontFragment && this.dontFragmentRelations.get(entityId)?.has(componentType));\n\n if (!hasComponent) {\n throw new Error(\n `Entity ${entityId} does not have component ${componentType}. Use has() to check component existence before calling get().`,\n );\n }\n }\n\n return archetype.get(entityId, componentType);\n }\n\n /**\n * Register a system with optional dependencies\n */\n registerSystem(system: System<UpdateParams>, additionalDeps: System<UpdateParams>[] = []): void {\n this.systemScheduler.addSystem(system, additionalDeps);\n }\n\n /**\n * Register a lifecycle hook for component or wildcard relation events\n */\n hook<T>(componentType: EntityId<T>, hook: LifecycleHook<T>): void {\n if (!this.hooks.has(componentType)) {\n this.hooks.set(componentType, new Set());\n }\n this.hooks.get(componentType)!.add(hook);\n\n if (hook.on_init !== undefined) {\n this.archetypesByComponent.get(componentType)?.forEach((archetype) => {\n const entities = archetype.getEntityToIndexMap();\n const componentData = archetype.getComponentData<T>(componentType);\n for (const [entity, index] of entities) {\n const data = componentData[index];\n const value = (data === MISSING_COMPONENT ? undefined : data) as T;\n hook.on_init?.(entity, componentType, value);\n }\n });\n }\n }\n\n /**\n * Unregister a lifecycle hook for component or wildcard relation events\n */\n unhook<T>(componentType: EntityId<T>, hook: LifecycleHook<T>): void {\n const hooks = this.hooks.get(componentType);\n if (hooks) {\n hooks.delete(hook);\n if (hooks.size === 0) {\n this.hooks.delete(componentType);\n }\n }\n }\n\n /**\n * Mark a component as exclusive relation\n * @deprecated This method has been removed. Use component options instead: component({ exclusive: true })\n * @throws Always throws an error directing to the new API\n */\n setExclusive(componentId: EntityId): void {\n throw new Error(\"setExclusive has been removed. Use component options instead: component({ exclusive: true })\");\n }\n\n /**\n * Mark a component as cascade-delete relation\n * @deprecated This method has been removed. Use component options instead: component({ cascadeDelete: true })\n * @throws Always throws an error directing to the new API\n */\n setCascadeDelete(componentId: EntityId): void {\n throw new Error(\n \"setCascadeDelete has been removed. Use component options instead: component({ cascadeDelete: true })\",\n );\n }\n\n /**\n * Update the world (run all systems in dependency order)\n * This function is synchronous when all systems are synchronous,\n * and asynchronous (returns a Promise) when any system is asynchronous.\n */\n update(...params: UpdateParams): Promise<void> | void {\n const result = this.systemScheduler.update(...params);\n if (result instanceof Promise) {\n return result.then(() => this.commandBuffer.execute());\n } else {\n this.commandBuffer.execute();\n }\n }\n\n /**\n * Execute all deferred commands immediately without running systems\n */\n sync(): void {\n this.commandBuffer.execute();\n }\n\n /**\n * Create a cached query for efficient entity lookups\n * @returns A Query object for the specified component types and filter\n */\n createQuery(componentTypes: EntityId<any>[], filter: QueryFilter = {}): Query {\n // Build a deterministic key for the query (component types sorted + filter negative components sorted)\n const sortedTypes = [...componentTypes].sort((a, b) => a - b);\n const filterKey = serializeQueryFilter(filter);\n const key = `${this.createArchetypeSignature(sortedTypes)}${filterKey ? `|${filterKey}` : \"\"}`;\n\n const cached = this.queryCache.get(key);\n if (cached) {\n cached.refCount++;\n return cached.query;\n }\n\n const query = new Query(this, sortedTypes, filter);\n this.queryCache.set(key, { query, refCount: 1 });\n return query;\n }\n\n /**\n * @internal Register a query for archetype update notifications\n */\n _registerQuery(query: Query): void {\n this.queries.push(query);\n }\n\n /**\n * @internal Unregister a query\n */\n _unregisterQuery(query: Query): void {\n const index = this.queries.indexOf(query);\n if (index !== -1) {\n this.queries.splice(index, 1);\n }\n }\n\n /**\n * Release a query reference obtained from createQuery.\n * Decrements the refCount and fully disposes the query when it reaches zero.\n */\n releaseQuery(query: Query): void {\n for (const [k, v] of this.queryCache.entries()) {\n if (v.query === query) {\n v.refCount--;\n if (v.refCount <= 0) {\n this.queryCache.delete(k);\n this._unregisterQuery(query);\n // Fully dispose the query (will unregister it from notification list)\n v.query._disposeInternal();\n }\n return;\n }\n }\n }\n\n /**\n * @internal Get archetypes that match specific component types (for internal use by queries)\n */\n getMatchingArchetypes(componentTypes: EntityId<any>[]): Archetype[] {\n if (componentTypes.length === 0) {\n return [...this.archetypes];\n }\n\n // Separate regular components from wildcard relations\n const regularComponents: EntityId<any>[] = [];\n const wildcardRelations: { componentId: EntityId<any>; relationId: EntityId<any> }[] = [];\n\n for (const componentType of componentTypes) {\n const detailedType = getDetailedIdType(componentType);\n if (detailedType.type === \"wildcard-relation\") {\n wildcardRelations.push({\n componentId: detailedType.componentId!,\n relationId: componentType,\n });\n } else {\n regularComponents.push(componentType);\n }\n }\n\n // Get archetypes for regular components\n let matchingArchetypes: Archetype[] = [];\n\n if (regularComponents.length > 0) {\n const sortedRegularTypes = [...regularComponents].sort((a, b) => a - b);\n\n if (sortedRegularTypes.length === 1) {\n const componentType = sortedRegularTypes[0]!;\n matchingArchetypes = this.archetypesByComponent.get(componentType) || [];\n } else {\n // Multi-component query - find intersection of archetypes\n const archetypeLists = sortedRegularTypes.map((type) => this.archetypesByComponent.get(type) || []);\n const firstList = archetypeLists[0] || [];\n const intersection = new Set<Archetype>();\n\n // Find archetypes that contain all required components\n for (const archetype of firstList) {\n let hasAllComponents = true;\n for (let listIndex = 1; listIndex < archetypeLists.length; listIndex++) {\n const otherList = archetypeLists[listIndex]!;\n if (!otherList.includes(archetype)) {\n hasAllComponents = false;\n break;\n }\n }\n if (hasAllComponents) {\n intersection.add(archetype);\n }\n }\n\n matchingArchetypes = Array.from(intersection);\n }\n } else {\n // No regular components, start with all archetypes\n matchingArchetypes = [...this.archetypes];\n }\n\n // Filter by wildcard relations\n for (const wildcard of wildcardRelations) {\n // Keep only archetypes that have the component\n matchingArchetypes = matchingArchetypes.filter((archetype) =>\n archetype.componentTypes.some((archetypeType) => {\n if (!isRelationId(archetypeType)) return false;\n const decoded = decodeRelationId(archetypeType);\n return decoded.componentId === wildcard.componentId;\n }),\n );\n }\n\n return matchingArchetypes;\n }\n\n /**\n * Query entities with specific components\n * @returns Array of entity IDs that have all the specified components\n */\n query(componentTypes: EntityId<any>[]): EntityId[];\n query<const T extends readonly EntityId<any>[]>(\n componentTypes: T,\n includeComponents: true,\n ): Array<{\n entity: EntityId;\n components: ComponentTuple<T>;\n }>;\n query(\n componentTypes: EntityId<any>[],\n includeComponents?: boolean,\n ):\n | EntityId[]\n | Array<{\n entity: EntityId;\n components: any;\n }> {\n const matchingArchetypes = this.getMatchingArchetypes(componentTypes);\n\n if (includeComponents) {\n const result: Array<{\n entity: EntityId;\n components: any;\n }> = [];\n\n for (const archetype of matchingArchetypes) {\n const entitiesWithData = archetype.getEntitiesWithComponents(componentTypes as EntityId<any>[]);\n result.push(...entitiesWithData);\n }\n\n return result;\n } else {\n const result: EntityId[] = [];\n for (const archetype of matchingArchetypes) {\n result.push(...archetype.getEntities());\n }\n return result;\n }\n }\n\n /**\n * @internal Execute commands for a single entity (for internal use by CommandBuffer)\n * @returns ComponentChangeset describing the changes made\n */\n executeEntityCommands(entityId: EntityId, commands: Command[]): ComponentChangeset {\n const changeset = new ComponentChangeset();\n\n // Handle entity destruction\n if (commands.some((cmd) => cmd.type === \"destroy\")) {\n this.destroyEntityImmediate(entityId);\n return changeset;\n }\n\n const currentArchetype = this.entityToArchetype.get(entityId);\n if (!currentArchetype) {\n return changeset;\n }\n\n // Process commands to build changeset\n this.processCommands(entityId, currentArchetype, commands, changeset);\n\n // Apply changes to entity\n const removedComponents = this.applyChangeset(entityId, currentArchetype, changeset);\n\n // Update entity reference tracking\n this.updateEntityReferences(entityId, changeset);\n\n // Trigger lifecycle hooks\n this.triggerLifecycleHooks(entityId, changeset.adds, removedComponents);\n\n return changeset;\n }\n\n /**\n * Process commands and populate the changeset\n */\n private processCommands(\n entityId: EntityId,\n currentArchetype: Archetype,\n commands: Command[],\n changeset: ComponentChangeset,\n ): void {\n for (const command of commands) {\n if (command.type === \"set\" && command.componentType) {\n this.processSetCommand(entityId, currentArchetype, command.componentType, command.component, changeset);\n } else if (command.type === \"delete\" && command.componentType) {\n this.processDeleteCommand(entityId, currentArchetype, command.componentType, changeset);\n }\n }\n }\n\n /**\n * Process a set command, handling exclusive relations\n */\n private processSetCommand(\n entityId: EntityId,\n currentArchetype: Archetype,\n componentType: EntityId<any>,\n component: any,\n changeset: ComponentChangeset,\n ): void {\n const detailedType = getDetailedIdType(componentType);\n\n // Handle exclusive relations by removing existing relations with the same base component\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isExclusiveComponent(detailedType.componentId!)\n ) {\n this.removeExclusiveRelations(entityId, currentArchetype, detailedType.componentId!, changeset);\n }\n\n changeset.set(componentType, component);\n }\n\n /**\n * Remove all relations with the same base component (for exclusive relations)\n */\n private removeExclusiveRelations(\n entityId: EntityId,\n currentArchetype: Archetype,\n baseComponentId: EntityId<any>,\n changeset: ComponentChangeset,\n ): void {\n // Check archetype components\n for (const componentType of currentArchetype.componentTypes) {\n if (this.isRelationWithComponent(componentType, baseComponentId)) {\n changeset.delete(componentType);\n }\n }\n\n // Check dontFragment relations\n const entityData = currentArchetype.getEntity(entityId);\n if (entityData) {\n for (const [componentType] of entityData) {\n if (currentArchetype.componentTypes.includes(componentType)) continue;\n if (this.isRelationWithComponent(componentType, baseComponentId)) {\n changeset.delete(componentType);\n }\n }\n }\n }\n\n /**\n * Check if a component type is a relation with the given base component\n */\n private isRelationWithComponent(componentType: EntityId<any>, baseComponentId: EntityId<any>): boolean {\n const detailedType = getDetailedIdType(componentType);\n return (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n detailedType.componentId === baseComponentId\n );\n }\n\n /**\n * Process a delete command, handling wildcard relations\n */\n private processDeleteCommand(\n entityId: EntityId,\n currentArchetype: Archetype,\n componentType: EntityId<any>,\n changeset: ComponentChangeset,\n ): void {\n const detailedType = getDetailedIdType(componentType);\n\n if (detailedType.type === \"wildcard-relation\") {\n this.removeWildcardRelations(entityId, currentArchetype, detailedType.componentId!, changeset);\n } else {\n changeset.delete(componentType);\n }\n }\n\n /**\n * Remove all relations matching a wildcard component ID\n */\n private removeWildcardRelations(\n entityId: EntityId,\n currentArchetype: Archetype,\n baseComponentId: EntityId<any>,\n changeset: ComponentChangeset,\n ): void {\n // Check archetype components\n for (const componentType of currentArchetype.componentTypes) {\n if (this.isRelationWithComponent(componentType, baseComponentId)) {\n changeset.delete(componentType);\n }\n }\n\n // Check dontFragment relations\n const entityData = currentArchetype.getEntity(entityId);\n if (entityData) {\n for (const [componentType] of entityData) {\n if (currentArchetype.componentTypes.includes(componentType)) continue;\n if (this.isRelationWithComponent(componentType, baseComponentId)) {\n changeset.delete(componentType);\n }\n }\n }\n }\n\n /**\n * Apply changeset to entity, moving to new archetype if needed\n * @returns Map of removed components with their data\n */\n private applyChangeset(\n entityId: EntityId,\n currentArchetype: Archetype,\n changeset: ComponentChangeset,\n ): Map<EntityId<any>, any> {\n const currentEntityData = currentArchetype.getEntity(entityId);\n const allCurrentComponentTypes = currentEntityData\n ? Array.from(currentEntityData.keys())\n : currentArchetype.componentTypes;\n\n const finalComponentTypes = changeset.getFinalComponentTypes(allCurrentComponentTypes);\n const removedComponents = new Map<EntityId<any>, any>();\n\n if (finalComponentTypes) {\n // Move to new archetype\n this.moveEntityToNewArchetype(entityId, currentArchetype, finalComponentTypes, changeset, removedComponents);\n } else {\n // Update in same archetype\n this.updateEntityInSameArchetype(entityId, currentArchetype, changeset, removedComponents);\n }\n\n return removedComponents;\n }\n\n /**\n * Move entity to a new archetype with updated components\n */\n private moveEntityToNewArchetype(\n entityId: EntityId,\n currentArchetype: Archetype,\n finalComponentTypes: EntityId<any>[],\n changeset: ComponentChangeset,\n removedComponents: Map<EntityId<any>, any>,\n ): void {\n const newArchetype = this.ensureArchetype(finalComponentTypes);\n const currentComponents = currentArchetype.removeEntity(entityId)!;\n\n // Track removed components\n for (const componentType of changeset.removes) {\n removedComponents.set(componentType, currentComponents.get(componentType));\n }\n\n // Add to new archetype with updated components\n newArchetype.addEntity(entityId, changeset.applyTo(currentComponents));\n this.entityToArchetype.set(entityId, newArchetype);\n\n // Cleanup empty archetype\n if (currentArchetype.getEntities().length === 0) {\n this.cleanupEmptyArchetype(currentArchetype);\n }\n }\n\n /**\n * Update entity in same archetype (no archetype change needed)\n */\n private updateEntityInSameArchetype(\n entityId: EntityId,\n currentArchetype: Archetype,\n changeset: ComponentChangeset,\n removedComponents: Map<EntityId<any>, any>,\n ): void {\n const currentComponents = currentArchetype.getEntity(entityId)!;\n const hasDontFragmentChanges = this.hasDontFragmentChanges(changeset);\n\n // Track removed dontFragment components\n if (hasDontFragmentChanges) {\n for (const componentType of changeset.removes) {\n const detailedType = getDetailedIdType(componentType);\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isDontFragmentComponent(detailedType.componentId!)\n ) {\n removedComponents.set(componentType, currentComponents.get(componentType));\n }\n }\n }\n\n if (hasDontFragmentChanges) {\n // Re-add entity with updated components\n this.readdEntityWithUpdatedComponents(entityId, currentArchetype, currentComponents, changeset);\n } else {\n // Direct update for non-dontFragment components\n for (const [componentType, component] of changeset.adds) {\n currentArchetype.set(entityId, componentType, component);\n }\n }\n }\n\n /**\n * Check if changeset contains dontFragment relation changes\n */\n private hasDontFragmentChanges(changeset: ComponentChangeset): boolean {\n for (const componentType of changeset.removes) {\n const detailedType = getDetailedIdType(componentType);\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isDontFragmentComponent(detailedType.componentId!)\n ) {\n return true;\n }\n }\n\n for (const [componentType] of changeset.adds) {\n const detailedType = getDetailedIdType(componentType);\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isDontFragmentComponent(detailedType.componentId!)\n ) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Remove and re-add entity with updated components (for dontFragment changes)\n */\n private readdEntityWithUpdatedComponents(\n entityId: EntityId,\n archetype: Archetype,\n currentComponents: Map<EntityId<any>, any>,\n changeset: ComponentChangeset,\n ): void {\n const newComponents = new Map<EntityId<any>, any>();\n\n // Copy current components except those marked for removal\n for (const [ct, value] of currentComponents) {\n if (!changeset.removes.has(ct)) {\n newComponents.set(ct, value);\n }\n }\n\n // Add new components from changeset\n for (const [ct, value] of changeset.adds) {\n newComponents.set(ct, value);\n }\n\n archetype.removeEntity(entityId);\n archetype.addEntity(entityId, newComponents);\n }\n\n /**\n * Update entity reference tracking based on changeset\n */\n private updateEntityReferences(entityId: EntityId, changeset: ComponentChangeset): void {\n // Remove references for removed components\n for (const componentType of changeset.removes) {\n const detailedType = getDetailedIdType(componentType);\n if (detailedType.type === \"entity-relation\") {\n this.untrackEntityReference(entityId, componentType, detailedType.targetId!);\n } else if (detailedType.type === \"entity\") {\n this.untrackEntityReference(entityId, componentType, componentType);\n }\n }\n\n // Add references for added components\n for (const [componentType] of changeset.adds) {\n const detailedType = getDetailedIdType(componentType);\n if (detailedType.type === \"entity-relation\") {\n this.trackEntityReference(entityId, componentType, detailedType.targetId!);\n } else if (detailedType.type === \"entity\") {\n this.trackEntityReference(entityId, componentType, componentType);\n }\n }\n }\n\n /**\n * Get or create an archetype for the given component types\n * Filters out dontFragment relations from the archetype signature\n * @returns The archetype for the given component types (excluding dontFragment relations)\n */\n private ensureArchetype(componentTypes: Iterable<EntityId<any>>): Archetype {\n const regularTypes = this.filterRegularComponentTypes(componentTypes);\n const sortedTypes = regularTypes.sort((a, b) => a - b);\n const hashKey = this.createArchetypeSignature(sortedTypes);\n\n return getOrCreateWithSideEffect(this.archetypeBySignature, hashKey, () => this.createNewArchetype(sortedTypes));\n }\n\n /**\n * Filter out dontFragment relations from component types\n */\n private filterRegularComponentTypes(componentTypes: Iterable<EntityId<any>>): EntityId<any>[] {\n const regularTypes: EntityId<any>[] = [];\n\n for (const componentType of componentTypes) {\n const detailedType = getDetailedIdType(componentType);\n\n // Skip dontFragment relations from archetype signature\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isDontFragmentComponent(detailedType.componentId!)\n ) {\n continue;\n }\n\n regularTypes.push(componentType);\n }\n\n return regularTypes;\n }\n\n /**\n * Create a new archetype and register it with all tracking structures\n */\n private createNewArchetype(componentTypes: EntityId<any>[]): Archetype {\n const newArchetype = new Archetype(componentTypes, this.dontFragmentRelations);\n this.archetypes.push(newArchetype);\n\n // Register archetype in component index\n this.registerArchetypeInComponentIndex(newArchetype, componentTypes);\n\n // Notify queries about new archetype\n this.notifyQueriesOfNewArchetype(newArchetype);\n\n return newArchetype;\n }\n\n /**\n * Register archetype in the component-to-archetype index\n */\n private registerArchetypeInComponentIndex(archetype: Archetype, componentTypes: EntityId<any>[]): void {\n for (const componentType of componentTypes) {\n const archetypes = this.archetypesByComponent.get(componentType) || [];\n archetypes.push(archetype);\n this.archetypesByComponent.set(componentType, archetypes);\n }\n }\n\n /**\n * Notify all queries to check the new archetype\n */\n private notifyQueriesOfNewArchetype(archetype: Archetype): void {\n for (const query of this.queries) {\n query.checkNewArchetype(archetype);\n }\n }\n\n /**\n * Add a component reference to the reverse index when an entity is used as a component type\n * @param sourceEntityId The entity that has the component\n * @param componentType The component type (which may be an entity ID used as component type)\n * @param targetEntityId The entity being used as component type\n */\n private trackEntityReference(sourceEntityId: EntityId, componentType: EntityId, targetEntityId: EntityId): void {\n if (!this.entityReferences.has(targetEntityId)) {\n this.entityReferences.set(targetEntityId, new MultiMap());\n }\n this.entityReferences.get(targetEntityId)!.add(sourceEntityId, componentType);\n }\n\n /**\n * Remove a component reference from the reverse index\n * @param sourceEntityId The entity that has the component\n * @param componentType The component type\n * @param targetEntityId The entity being used as component type\n */\n private untrackEntityReference(sourceEntityId: EntityId, componentType: EntityId, targetEntityId: EntityId): void {\n const references = this.entityReferences.get(targetEntityId);\n if (references) {\n references.remove(sourceEntityId, componentType);\n if (references.keyCount === 0) {\n this.entityReferences.delete(targetEntityId);\n }\n }\n }\n\n /**\n * Get all component references where a target entity is used as a component type\n * @param targetEntityId The target entity\n * @returns A MultiMap of sourceEntityId to componentTypes that reference the target entity\n */\n private getEntityReferences(targetEntityId: EntityId): Iterable<[EntityId, EntityId]> {\n return this.entityReferences.get(targetEntityId) ?? new MultiMap();\n }\n\n /**\n * Remove an empty archetype from all internal data structures\n */\n private cleanupEmptyArchetype(archetype: Archetype): void {\n if (archetype.getEntities().length > 0) {\n return;\n }\n\n this.removeArchetypeFromList(archetype);\n this.removeArchetypeFromSignatureMap(archetype);\n this.removeArchetypeFromComponentIndex(archetype);\n this.removeArchetypeFromQueries(archetype);\n }\n\n /**\n * Remove archetype from the main archetypes list\n */\n private removeArchetypeFromList(archetype: Archetype): void {\n const index = this.archetypes.indexOf(archetype);\n if (index !== -1) {\n this.archetypes.splice(index, 1);\n }\n }\n\n /**\n * Remove archetype from the signature-to-archetype map\n */\n private removeArchetypeFromSignatureMap(archetype: Archetype): void {\n const hashKey = this.createArchetypeSignature(archetype.componentTypes);\n this.archetypeBySignature.delete(hashKey);\n }\n\n /**\n * Remove archetype from the component-to-archetypes index\n */\n private removeArchetypeFromComponentIndex(archetype: Archetype): void {\n for (const componentType of archetype.componentTypes) {\n const archetypes = this.archetypesByComponent.get(componentType);\n if (archetypes) {\n const compIndex = archetypes.indexOf(archetype);\n if (compIndex !== -1) {\n archetypes.splice(compIndex, 1);\n if (archetypes.length === 0) {\n this.archetypesByComponent.delete(componentType);\n }\n }\n }\n }\n }\n\n /**\n * Remove archetype from all queries\n */\n private removeArchetypeFromQueries(archetype: Archetype): void {\n for (const query of this.queries) {\n query.removeArchetype(archetype);\n }\n }\n\n /**\n * Execute component lifecycle hooks for added and removed components\n */\n private triggerLifecycleHooks(\n entityId: EntityId,\n addedComponents: Map<EntityId<any>, any>,\n removedComponents: Map<EntityId<any>, any>,\n ): void {\n // Trigger component added hooks\n for (const [componentType, component] of addedComponents) {\n // Trigger direct component hooks\n const directHooks = this.hooks.get(componentType);\n if (directHooks) {\n for (const lifecycleHook of directHooks) {\n lifecycleHook.on_set?.(entityId, componentType, component);\n }\n }\n\n // Trigger wildcard relation hooks for added components\n const detailedType = getDetailedIdType(componentType);\n if (\n detailedType.type === \"entity-relation\" ||\n detailedType.type === \"component-relation\" ||\n detailedType.type === \"wildcard-relation\"\n ) {\n const wildcardRelationId = relation(detailedType.componentId!, \"*\");\n const wildcardHooks = this.hooks.get(wildcardRelationId);\n if (wildcardHooks) {\n for (const lifecycleHook of wildcardHooks) {\n lifecycleHook.on_set?.(entityId, componentType, component);\n }\n }\n }\n }\n\n // Trigger component removed hooks\n for (const [componentType, component] of removedComponents) {\n // Trigger direct component hooks\n const directHooks = this.hooks.get(componentType);\n if (directHooks) {\n for (const lifecycleHook of directHooks) {\n lifecycleHook.on_remove?.(entityId, componentType, component);\n }\n }\n\n // Trigger wildcard relation hooks for removed components\n const detailedType = getDetailedIdType(componentType);\n if (\n detailedType.type === \"entity-relation\" ||\n detailedType.type === \"component-relation\" ||\n detailedType.type === \"wildcard-relation\"\n ) {\n const wildcardRelationId = relation(detailedType.componentId!, \"*\");\n const wildcardHooks = this.hooks.get(wildcardRelationId);\n if (wildcardHooks) {\n for (const hook of wildcardHooks) {\n hook.on_remove?.(entityId, componentType, component);\n }\n }\n }\n }\n }\n\n /**\n * Convert the world into a plain snapshot object.\n * This returns an in-memory structure and does not perform JSON stringification.\n * Component values are stored as-is (they may be non-JSON-serializable).\n */\n serialize(): SerializedWorld {\n const entities: SerializedEntity[] = [];\n\n for (const archetype of this.archetypes) {\n const dumpedEntities = archetype.dump();\n for (const { entity, components } of dumpedEntities) {\n entities.push({\n id: entity,\n components: Array.from(components.entries()).map(([rawType, value]) => {\n const detailedType = getDetailedIdType(rawType);\n let type: SerializedComponent[\"type\"] = rawType;\n let componentName;\n switch (detailedType.type) {\n case \"component\":\n type = getComponentNameById(rawType as ComponentId) || rawType;\n break;\n case \"entity-relation\":\n componentName = getComponentNameById(detailedType.componentId);\n if (componentName) {\n type = { component: componentName, target: detailedType.targetId! };\n }\n break;\n case \"component-relation\":\n componentName = getComponentNameById(detailedType.componentId);\n if (componentName) {\n type = {\n component: componentName,\n target: getComponentNameById(detailedType.targetId!) || detailedType.targetId!,\n };\n }\n break;\n }\n return { type, value: value === MISSING_COMPONENT ? undefined : value };\n }),\n });\n }\n }\n\n return {\n version: 1,\n entityManager: this.entityIdManager.serializeState(),\n entities,\n };\n }\n}\n\nexport type SerializedWorld = {\n version: number;\n entityManager: any;\n entities: SerializedEntity[];\n};\n\nexport type SerializedEntity = {\n id: number;\n components: SerializedComponent[];\n};\n\nexport type SerializedComponent = {\n type: number | string | { component: string; target: number | string };\n value: any;\n};\n"],"mappings":";AAgCA,MAAa,mBAAmB;AAChC,MAAa,kBAAkB;;;;AAK/B,MAAa,iBAAiB,KAAK;AACnC,MAAa,qBAAqB;AA6ClC,SAAgB,SAAY,aAA6B,UAA8C;AACrG,KAAI,CAAC,cAAc,YAAY,CAC7B,OAAM,IAAI,MAAM,8CAA8C;CAGhE,IAAIA;AACJ,KAAI,aAAa,IACf,kBAAiB;MACZ;AACL,MAAI,CAAC,WAAW,SAAS,IAAI,CAAC,cAAc,SAAS,CACnD,OAAM,IAAI,MAAM,kEAAkE;AAEpF,mBAAiB;;AAInB,QAAO,EAAE,cAAc,iBAAiB;;;;;AAM1C,SAAgB,cAAiB,IAAuC;AACtE,QAAO,MAAM,KAAK,MAAM;;;;;AAM1B,SAAgB,WAAc,IAAoC;AAChE,QAAO,MAAM;;;;;AAMf,SAAgB,aAAgB,IAAsC;AACpE,QAAO,KAAK;;;;;AAMd,SAAgB,qBAAwB,IAA8C;AACpF,KAAI,CAAC,aAAa,GAAG,CACnB,QAAO;AAIT,QAFc,CAAC,KACU,mBACL;;;;;;;AAQtB,SAAgB,iBAAiB,YAI/B;AACA,KAAI,CAAC,aAAa,WAAW,CAC3B,OAAM,IAAI,MAAM,0BAA0B;CAE5C,MAAM,QAAQ,CAAC;CAEf,MAAM,cAAc,KAAK,MAAM,QAAQ,eAAe;CACtD,MAAM,WAAY,QAAQ;AAG1B,KAAI,aAAa,mBACf,QAAO;EAAE;EAAa;EAAU,MAAM;EAAY;UACzC,WAAW,SAAS,CAC7B,QAAO;EAAE;EAAa;EAAU,MAAM;EAAU;UACvC,cAAc,SAAS,CAChC,QAAO;EAAE;EAAa;EAAU,MAAM;EAAa;KAEnD,OAAM,IAAI,MAAM,gCAAgC;;;;;AAOpD,SAAgB,UACd,IACqG;AACrG,KAAI,cAAc,GAAG,CAAE,QAAO;AAC9B,KAAI,WAAW,GAAG,CAAE,QAAO;AAE3B,KAAI,aAAa,GAAG,CAClB,KAAI;EACF,MAAM,UAAU,iBAAiB,GAAG;AAEpC,MACE,CAAC,cAAc,QAAQ,YAAY,IAClC,QAAQ,SAAS,cAAc,CAAC,WAAW,QAAQ,SAAS,IAAI,CAAC,cAAc,QAAQ,SAAS,CAEjG,QAAO;AAET,UAAQ,QAAQ,MAAhB;GACE,KAAK,SACH,QAAO;GACT,KAAK,YACH,QAAO;GACT,KAAK,WACH,QAAO;;UAEJ,OAAO;AACd,SAAO;;AAIX,QAAO;;;;;;;AAQT,SAAgB,kBAAkB,IAe5B;AACJ,KAAI,cAAc,GAAG,CACnB,QAAO,EAAE,MAAM,aAAa;AAG9B,KAAI,WAAW,GAAG,CAChB,QAAO,EAAE,MAAM,UAAU;AAG3B,KAAI,aAAa,GAAG,CAClB,KAAI;EACF,MAAM,UAAU,iBAAiB,GAAG;AAEpC,MACE,CAAC,cAAc,QAAQ,YAAY,IAClC,QAAQ,SAAS,cAAc,CAAC,WAAW,QAAQ,SAAS,IAAI,CAAC,cAAc,QAAQ,SAAS,CAEjG,QAAO,EAAE,MAAM,WAAW;EAE5B,IAAIC;AAEJ,UAAQ,QAAQ,MAAhB;GACE,KAAK;AACH,WAAO;AACP;GACF,KAAK;AACH,WAAO;AACP;GACF,KAAK;AACH,WAAO;AACP;;AAGJ,SAAO;GACL;GACA,aAAa,QAAQ;GACrB,UAAU,QAAQ;GACnB;UACM,OAAO;AAEd,SAAO,EAAE,MAAM,WAAW;;AAK9B,QAAO,EAAE,MAAM,WAAW;;;;;AAkD5B,IAAa,kBAAb,MAA6B;CAC3B,AAAQ,SAAiB;CACzB,AAAQ,2BAA0B,IAAI,KAAK;;;;;CAM3C,WAAqB;AACnB,MAAI,KAAK,SAAS,OAAO,GAAG;GAC1B,MAAM,KAAK,KAAK,SAAS,QAAQ,CAAC,MAAM,CAAC;AACzC,QAAK,SAAS,OAAO,GAAG;AACxB,UAAO;SACF;GACL,MAAM,KAAK,KAAK;AAChB,QAAK;AAEL,OAAI,KAAK,UAAU,OAAO,iBACxB,OAAM,IAAI,MAAM,mDAAmD;AAErE,UAAO;;;;;;;CAQX,WAAW,IAAyB;AAClC,MAAI,CAAC,WAAW,GAAG,CACjB,OAAM,IAAI,MAAM,uCAAuC;AAEzD,MAAI,MAAM,KAAK,OACb,OAAM,IAAI,MAAM,mDAAmD;AAErE,OAAK,SAAS,IAAI,GAAG;;;;;CAMvB,kBAA0B;AACxB,SAAO,KAAK,SAAS;;;;;CAMvB,YAAoB;AAClB,SAAO,KAAK;;;;;;CAOd,iBAAyD;AACvD,SAAO;GAAE,QAAQ,KAAK;GAAQ,UAAU,MAAM,KAAK,KAAK,SAAS;GAAE;;;;;;CAOrE,iBAAiB,OAAsD;AACrE,MAAI,OAAO,MAAM,WAAW,SAC1B,OAAM,IAAI,MAAM,qDAAqD;AAEvE,OAAK,SAAS,MAAM;AACpB,OAAK,WAAW,IAAI,IAAK,MAAM,YAAY,EAAE,CAAgB;;;;;;;AAQjE,IAAa,uBAAb,MAAkC;CAChC,AAAQ,SAAiB;;;;;CAMzB,WAAqC;AACnC,MAAI,KAAK,SAAS,iBAChB,OAAM,IAAI,MAAM,kCAAkC,iBAAiB,qBAAqB;EAE1F,MAAM,KAAK,KAAK;AAChB,OAAK;AACL,SAAO;;;;;CAMT,YAAoB;AAClB,SAAO,KAAK;;;;;CAMd,kBAA2B;AACzB,SAAO,KAAK,UAAU;;;AAI1B,MAAM,6BAA6B,IAAI,sBAAsB;AAE7D,MAAMC,iCAAgD,IAAI,KAAK;AAC/D,MAAMC,sCAAqD,IAAI,KAAK;AAiCpE,MAAMC,mCAA4D,IAAI,KAAK;;;;;;;;;;;;;;;AAgB3E,SAAgB,UAAoB,eAA2D;CAC7F,MAAM,KAAK,2BAA2B,UAAa;CAEnD,IAAIC;CACJ,IAAIC;AAGJ,KAAI,OAAO,kBAAkB,SAC3B,QAAO;UACE,OAAO,kBAAkB,YAAY,kBAAkB,MAAM;AACtE,YAAU;AACV,SAAO,QAAQ;;AAIjB,KAAI,MAAM;AACR,MAAI,oBAAoB,IAAI,KAAK,CAC/B,OAAM,IAAI,MAAM,mBAAmB,KAAK,yBAAyB;AAGnE,iBAAe,IAAI,IAAI,KAAK;AAC5B,sBAAoB,IAAI,MAAM,GAAG;;AAInC,KAAI,QACF,kBAAiB,IAAI,IAAI,QAAQ;AAGnC,QAAO;;;;;;;AAQT,SAAgB,qBAAqB,MAA4C;AAC/E,QAAO,oBAAoB,IAAI,KAAK;;;;;;AAOtC,SAAgB,qBAAqB,IAA0C;AAC7E,QAAO,eAAe,IAAI,GAAG;;;;;;;AAiB/B,SAAgB,qBAAqB,IAA+B;AAClE,QAAO,iBAAiB,IAAI,GAAG,EAAE,aAAa;;;;;;;AAQhD,SAAgB,yBAAyB,IAA+B;AACtE,QAAO,iBAAiB,IAAI,GAAG,EAAE,iBAAiB;;;;;;;AAQpD,SAAgB,wBAAwB,IAA+B;AACrE,QAAO,iBAAiB,IAAI,GAAG,EAAE,gBAAgB;;;;;ACthBnD,SAAgB,mBAAsB,MAAqD;AACzF,QAAO,OAAO,SAAS,YAAY,SAAS,QAAQ,cAAc;;;;;;;;;;;;;;;ACdpE,SAAgB,kBAAwB,OAAkB,KAAQ,SAAqB;CACrF,IAAI,QAAQ,MAAM,IAAI,IAAI;AAC1B,KAAI,UAAU,QAAW;AACvB,UAAQ,SAAS;AACjB,QAAM,IAAI,KAAK,MAAM;;AAEvB,QAAO;;;;;;;;;AAUT,SAAgB,0BAAgC,OAAkB,KAAQ,QAAoB;CAC5F,IAAI,QAAQ,MAAM,IAAI,IAAI;AAC1B,KAAI,UAAU,QAAW;AACvB,UAAQ,QAAQ;AAChB,QAAM,IAAI,KAAK,MAAM;;AAEvB,QAAO;;;;;;;;ACnBT,MAAa,oBAAoB,OAAO,oBAAoB;;;;;;AAO5D,IAAa,YAAb,MAAuB;;;;CAIrB,AAAgB;;;;CAKhB,AAAQ,WAAuB,EAAE;;;;;CAMjC,AAAQ,gCAA2C,IAAI,KAAK;;;;CAK5D,AAAQ,gCAAuC,IAAI,KAAK;;;;;;CAOxD,AAAQ;;;;;;CAOR,AAAQ,4CAAkF,IAAI,KAAK;;;;;;CAOnG,YAAY,gBAAiC,uBAA+D;AAC1G,OAAK,iBAAiB,CAAC,GAAG,eAAe,CAAC,MAAM,GAAG,MAAM,IAAI,EAAE;AAC/D,OAAK,wBAAwB;AAG7B,OAAK,MAAM,iBAAiB,KAAK,eAC/B,MAAK,cAAc,IAAI,eAAe,EAAE,CAAC;;;;;CAO7C,IAAI,OAAe;AACjB,SAAO,KAAK,SAAS;;;;;;CAOvB,QAAQ,gBAA0C;AAChD,MAAI,KAAK,eAAe,WAAW,eAAe,OAChD,QAAO;EAET,MAAM,cAAc,CAAC,GAAG,eAAe,CAAC,MAAM,GAAG,MAAM,IAAI,EAAE;AAC7D,SAAO,KAAK,eAAe,OAAO,MAAM,UAAU,SAAS,YAAY,OAAO;;;;;;;CAQhF,UAAU,UAAoB,eAA8C;AAC1E,MAAI,KAAK,cAAc,IAAI,SAAS,CAClC,OAAM,IAAI,MAAM,UAAU,SAAS,+BAA+B;EAGpE,MAAM,QAAQ,KAAK,SAAS;AAC5B,OAAK,SAAS,KAAK,SAAS;AAC5B,OAAK,cAAc,IAAI,UAAU,MAAM;AAGvC,OAAK,MAAM,iBAAiB,KAAK,gBAAgB;GAC/C,MAAM,OAAO,cAAc,IAAI,cAAc;AAC7C,QAAK,iBAAiB,cAAc,CAAC,KAAK,SAAS,SAAY,oBAAoB,KAAK;;EAI1F,MAAM,mCAAmB,IAAI,KAAyB;AACtD,OAAK,MAAM,CAAC,eAAe,SAAS,eAAe;AAEjD,OAAI,KAAK,eAAe,SAAS,cAAc,CAC7C;GAIF,MAAM,eAAe,kBAAkB,cAAc;AACrD,QACG,aAAa,SAAS,qBAAqB,aAAa,SAAS,yBAClE,wBAAwB,aAAa,YAAa,CAElD,kBAAiB,IAAI,eAAe,KAAK;;AAI7C,MAAI,iBAAiB,OAAO,EAC1B,MAAK,sBAAsB,IAAI,UAAU,iBAAiB;;;;;;;CAS9D,UAAU,UAAyD;EACjE,MAAM,QAAQ,KAAK,cAAc,IAAI,SAAS;AAC9C,MAAI,UAAU,OACZ;EAGF,MAAM,6BAAa,IAAI,KAAyB;AAChD,OAAK,MAAM,iBAAiB,KAAK,gBAAgB;GAE/C,MAAM,OADY,KAAK,iBAAiB,cAAc,CAC/B;AACvB,cAAW,IAAI,eAAe,SAAS,oBAAoB,SAAY,KAAK;;EAI9E,MAAM,mBAAmB,KAAK,sBAAsB,IAAI,SAAS;AACjE,MAAI,iBACF,MAAK,MAAM,CAAC,eAAe,SAAS,iBAClC,YAAW,IAAI,eAAe,KAAK;AAIvC,SAAO;;;;;;CAOT,OAGG;EACD,MAAMC,SAGD,EAAE;AAEP,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,KAAK;GAC7C,MAAM,SAAS,KAAK,SAAS;GAC7B,MAAM,6BAAa,IAAI,KAAyB;AAChD,QAAK,MAAM,iBAAiB,KAAK,gBAAgB;IAE/C,MAAM,OADY,KAAK,iBAAiB,cAAc,CAC/B;AACvB,eAAW,IAAI,eAAe,SAAS,oBAAoB,SAAY,KAAK;;GAI9E,MAAM,mBAAmB,KAAK,sBAAsB,IAAI,OAAO;AAC/D,OAAI,iBACF,MAAK,MAAM,CAAC,eAAe,SAAS,iBAClC,YAAW,IAAI,eAAe,KAAK;AAIvC,UAAO,KAAK;IAAE;IAAQ;IAAY,CAAC;;AAGrC,SAAO;;;;;;;CAQT,aAAa,UAAyD;EACpE,MAAM,QAAQ,KAAK,cAAc,IAAI,SAAS;AAC9C,MAAI,UAAU,OACZ;EAIF,MAAM,8BAAc,IAAI,KAAyB;AACjD,OAAK,MAAM,iBAAiB,KAAK,gBAAgB;GAC/C,MAAM,YAAY,KAAK,iBAAiB,cAAc;AACtD,eAAY,IAAI,eAAe,UAAU,OAAO;;EAIlD,MAAM,mBAAmB,KAAK,sBAAsB,IAAI,SAAS;AACjE,MAAI,kBAAkB;AACpB,QAAK,MAAM,CAAC,eAAe,SAAS,iBAClC,aAAY,IAAI,eAAe,KAAK;AAEtC,QAAK,sBAAsB,OAAO,SAAS;;AAG7C,OAAK,cAAc,OAAO,SAAS;EAGnC,MAAM,YAAY,KAAK,SAAS,SAAS;AACzC,MAAI,UAAU,WAAW;GAEvB,MAAM,aAAa,KAAK,SAAS;AACjC,QAAK,SAAS,SAAS;AACvB,QAAK,cAAc,IAAI,YAAY,MAAM;AAGzC,QAAK,MAAM,iBAAiB,KAAK,gBAAgB;IAC/C,MAAM,YAAY,KAAK,iBAAiB,cAAc;AACtD,cAAU,SAAS,UAAU;;;AAKjC,OAAK,SAAS,KAAK;AACnB,OAAK,MAAM,iBAAiB,KAAK,eAC/B,MAAK,iBAAiB,cAAc,CAAC,KAAK;AAG5C,SAAO;;;;;;CAOT,OAAO,UAA6B;AAClC,SAAO,KAAK,cAAc,IAAI,SAAS;;CAgBzC,IAAO,UAAoB,eAAoF;EAC7G,MAAM,QAAQ,KAAK,cAAc,IAAI,SAAS;AAC9C,MAAI,UAAU,OACZ,OAAM,IAAI,MAAM,UAAU,SAAS,2BAA2B;AAGhE,MAAI,qBAAqB,cAAc,EAAE;GAEvC,MAAM,cADU,iBAAiB,cAAc,CACnB;GAC5B,MAAMC,YAAwC,EAAE;AAGhD,QAAK,MAAM,WAAW,KAAK,gBAAgB;IACzC,MAAM,cAAc,kBAAkB,QAAQ;AAC9C,SACG,YAAY,SAAS,qBAAqB,YAAY,SAAS,yBAChE,YAAY,gBAAgB,aAC5B;KACA,MAAM,YAAY,KAAK,iBAAiB,QAAQ;AAChD,SAAI,aAAa,UAAU,WAAW,QAAW;MAC/C,MAAM,OAAO,UAAU;AACvB,gBAAU,KAAK,CAAC,YAAY,UAAU,SAAS,oBAAoB,SAAY,KAAK,CAAC;;;;GAM3F,MAAM,mBAAmB,KAAK,sBAAsB,IAAI,SAAS;AACjE,OAAI,iBACF,MAAK,MAAM,CAAC,SAAS,SAAS,kBAAkB;IAC9C,MAAM,cAAc,kBAAkB,QAAQ;AAC9C,SACG,YAAY,SAAS,qBAAqB,YAAY,SAAS,yBAChE,YAAY,gBAAgB,YAE5B,WAAU,KAAK,CAAC,YAAY,UAAU,KAAK,CAAC;;AAKlD,UAAO;SACF;AAEL,OAAI,KAAK,eAAe,SAAS,cAAc,EAAE;IAC/C,MAAM,OAAO,KAAK,iBAAiB,cAAc,CAAC;AAClD,WAAO,SAAS,oBAAqB,SAAkB;;GAIzD,MAAM,mBAAmB,KAAK,sBAAsB,IAAI,SAAS;AACjE,OAAI,oBAAoB,iBAAiB,IAAI,cAAc,CACzD,QAAO,iBAAiB,IAAI,cAAc;AAG5C,SAAM,IAAI,MAAM,kBAAkB,cAAc,wBAAwB,WAAW;;;;;;;;;CAUvF,IAAO,UAAoB,eAA4B,MAAe;EACpE,MAAM,QAAQ,KAAK,cAAc,IAAI,SAAS;AAC9C,MAAI,UAAU,OACZ,OAAM,IAAI,MAAM,UAAU,SAAS,2BAA2B;AAIhE,MAAI,KAAK,cAAc,IAAI,cAAc,EAAE;GACzC,MAAM,YAAY,KAAK,iBAAiB,cAAc;AACtD,aAAU,SAAS;AACnB;;EAIF,MAAM,eAAe,kBAAkB,cAAc;AACrD,OACG,aAAa,SAAS,qBAAqB,aAAa,SAAS,yBAClE,wBAAwB,aAAa,YAAa,EAClD;GACA,IAAI,mBAAmB,KAAK,sBAAsB,IAAI,SAAS;AAC/D,OAAI,CAAC,kBAAkB;AACrB,uCAAmB,IAAI,KAAK;AAC5B,SAAK,sBAAsB,IAAI,UAAU,iBAAiB;;AAE5D,oBAAiB,IAAI,eAAe,KAAK;AACzC;;AAGF,QAAM,IAAI,MAAM,kBAAkB,cAAc,2BAA2B;;;;;CAM7E,cAA0B;AACxB,SAAO,KAAK;;;;;CAMd,sBAA6C;AAC3C,SAAO,KAAK;;;;;;CAOd,iBAAoB,eAAiC;EACnD,MAAM,OAAO,KAAK,cAAc,IAAI,cAAc;AAClD,MAAI,CAAC,KACH,OAAM,IAAI,MAAM,kBAAkB,cAAc,2BAA2B;AAE7E,SAAO;;;;;;;CAQT,yBAA4B,eAA6C;AACvE,SAAO,KAAK,cAAc,IAAI,cAAc;;;;;CAM9C,AAAQ,8BACN,gBACyC;EACzC,MAAM,WAAW,KAAK,cAAc,eAAe;AACnD,SAAO,kBAAkB,KAAK,2BAA2B,gBACvD,eAAe,KAAK,aAAa,KAAK,uBAAuB,SAAS,CAAC,CACxE;;;;;CAMH,AAAQ,cAAc,gBAAuD;AAC3E,SAAO,eAAe,KAAK,OAAQ,mBAAmB,GAAG,GAAG,OAAO,GAAG,SAAS,KAAK,GAAG,KAAM,CAAC,KAAK,IAAI;;;;;CAMzG,AAAQ,uBAAuB,UAAmE;EAChG,MAAM,WAAW,mBAAmB,SAAS;EAC7C,MAAM,aAAa,WAAW,SAAS,WAAW;EAClD,MAAM,eAAe,kBAAkB,WAAW;AAElD,MAAI,aAAa,SAAS,oBACxB,QAAO,KAAK,8BAA8B,aAAa,aAAa,SAAS;MAE7E,QAAO,WAAW,KAAK,yBAAyB,WAAW,GAAG,KAAK,iBAAiB,WAAW;;;;;CAOnG,AAAQ,8BAA8B,aAA4B,UAAgD;EAChH,MAAM,oBAAoB,KAAK,eAAe,QAAQ,OAAO;GAC3D,MAAM,aAAa,kBAAkB,GAAG;AACxC,WACG,WAAW,SAAS,qBAAqB,WAAW,SAAS,yBAC9D,WAAW,gBAAgB;IAE7B;AAEF,SAAO,WAAY,kBAAkB,SAAS,IAAI,oBAAoB,SAAa;;;;;CAMrF,AAAQ,wBACN,gBACA,sBACA,aACmB;AACnB,SAAO,qBAAqB,KAAK,YAAY,MAAM;GACjD,MAAM,WAAW,eAAe;AAChC,UAAO,KAAK,qBAAqB,UAAU,YAAY,YAAY;IACnE;;;;;CAMJ,AAAQ,qBACN,UACA,YACA,aACK;EACL,MAAM,WAAW,mBAAmB,SAAS;AAG7C,MAAI,UAFe,WAAW,SAAS,WAAW,SAEzB,KAAK,oBAC5B,QAAO,KAAK,2BAA2B,YAAY,aAAa,SAAS;MAEzE,QAAO,KAAK,2BAA2B,YAAY,aAAa,SAAS;;;;;CAO7E,AAAQ,2BACN,YACA,aACA,UACK;AACL,MAAI,eAAe,QAAW;AAC5B,OAAI,SACF;AAEF,SAAM,IAAI,MAAM,6EAA6E;;EAG/F,MAAM,oBAAoB;EAC1B,MAAMA,YAAwC,EAAE;AAEhD,OAAK,MAAM,WAAW,mBAAmB;GAEvC,MAAM,OADY,KAAK,iBAAiB,QAAQ,CACzB;GACvB,MAAM,aAAa,iBAAiB,QAA2B;AAC/D,aAAU,KAAK,CAAC,WAAW,UAAU,SAAS,oBAAoB,SAAY,KAAK,CAAC;;AAGtF,SAAO,WAAW,EAAE,OAAO,WAAW,GAAG;;;;;CAM3C,AAAQ,2BACN,YACA,aACA,UACK;AACL,MAAI,eAAe,QAAW;AAC5B,OAAI,SACF;AAEF,SAAM,IAAI,MAAM,wDAAwD;;EAI1E,MAAM,OADY,WACK;EACvB,MAAM,SAAS,SAAS,oBAAoB,SAAY;AAExD,SAAO,WAAW,EAAE,OAAO,QAAQ,GAAG;;;;;;;;CASxC,0BACE,gBAIC;EACD,MAAMC,SAGD,EAAE;AAEP,OAAK,sBAAsB,iBAAiB,QAAQ,GAAG,eAAe;AACpE,UAAO,KAAK;IAAE;IAAQ;IAAY,CAAC;IACnC;AAEF,SAAO;;;;;;;CAQT,CAAC,sBACC,gBACoD;EAEpD,MAAM,uBAAuB,KAAK,8BAA8B,eAAe;AAE/E,OAAK,IAAI,cAAc,GAAG,cAAc,KAAK,SAAS,QAAQ,cAK5D,OAAM,CAJS,KAAK,SAAS,cAId,GAFI,KAAK,wBAAwB,gBAAgB,sBAAsB,YAAY,CAErE;;;;;;;;CAUjC,sBACE,gBACA,UACM;EAEN,MAAM,uBAAuB,KAAK,8BAA8B,eAAe;AAE/E,OAAK,IAAI,cAAc,GAAG,cAAc,KAAK,SAAS,QAAQ,eAAe;GAC3E,MAAM,SAAS,KAAK,SAAS;AAK7B,YAAS,QAAQ,GAFE,KAAK,wBAAwB,gBAAgB,sBAAsB,YAAY,CAEnE;;;;;;;CAQnC,QAAQ,UAAmF;AACzF,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,KAAK;GAC7C,MAAM,6BAAa,IAAI,KAAyB;AAChD,QAAK,MAAM,iBAAiB,KAAK,gBAAgB;IAC/C,MAAM,OAAO,KAAK,iBAAiB,cAAc,CAAC;AAClD,eAAW,IAAI,eAAe,SAAS,oBAAoB,SAAY,KAAK;;AAE9E,YAAS,KAAK,SAAS,IAAK,WAAW;;;;;;;;;;AC/lB7C,IAAa,qBAAb,MAAgC;CAC9B,AAAS,uBAAO,IAAI,KAAyB;CAC7C,AAAS,0BAAU,IAAI,KAAoB;;;;CAK3C,IAAO,eAA4B,aAAoB;AACrD,OAAK,KAAK,IAAI,eAAeC,YAAU;AACvC,OAAK,QAAQ,OAAO,cAAc;;;;;CAMpC,OAAU,eAAkC;AAC1C,OAAK,QAAQ,IAAI,cAAc;AAC/B,OAAK,KAAK,OAAO,cAAc;;;;;CAMjC,aAAsB;AACpB,SAAO,KAAK,KAAK,OAAO,KAAK,KAAK,QAAQ,OAAO;;;;;CAMnD,QAAc;AACZ,OAAK,KAAK,OAAO;AACjB,OAAK,QAAQ,OAAO;;;;;CAMtB,MAAM,OAAiC;AAErC,OAAK,MAAM,CAAC,eAAeA,gBAAc,MAAM,MAAM;AACnD,QAAK,KAAK,IAAI,eAAeA,YAAU;AACvC,QAAK,QAAQ,OAAO,cAAc;;AAGpC,OAAK,MAAM,iBAAiB,MAAM,SAAS;AACzC,QAAK,QAAQ,IAAI,cAAc;AAC/B,QAAK,KAAK,OAAO,cAAc;;;;;;CAOnC,QAAQ,oBAAsE;AAE5E,OAAK,MAAM,iBAAiB,KAAK,QAC/B,oBAAmB,OAAO,cAAc;AAI1C,OAAK,MAAM,CAAC,eAAeA,gBAAc,KAAK,KAC5C,oBAAmB,IAAI,eAAeA,YAAU;AAGlD,SAAO;;;;;;;CAQT,uBAAuB,wBAAsE;EAC3F,MAAM,sBAAsB,IAAI,IAAmB,uBAAuB;EAC1E,IAAI,UAAU;AAGd,OAAK,MAAM,iBAAiB,KAAK,SAAS;AACxC,OAAI,CAAC,oBAAoB,IAAI,cAAc,EAAE;AAC3C,SAAK,QAAQ,OAAO,cAAc;AAClC;;AAEF,aAAU;AACV,uBAAoB,OAAO,cAAc;;AAI3C,OAAK,MAAM,iBAAiB,KAAK,KAAK,MAAM,EAAE;AAC5C,OAAI,oBAAoB,IAAI,cAAc,CACxC;AAEF,aAAU;AACV,uBAAoB,IAAI,cAAc;;AAGxC,SAAO,UAAU,MAAM,KAAK,oBAAoB,GAAG;;;;;;;;;ACtFvD,IAAa,gBAAb,MAA2B;CACzB,AAAQ,WAAsB,EAAE;CAChC,AAAQ;;;;CAKR,YAAY,uBAA0E;AACpF,OAAK,wBAAwB;;CAQ/B,IAAI,UAAoB,eAAyB,aAAuB;AACtE,OAAK,SAAS,KAAK;GAAE,MAAM;GAAO;GAAU;GAAe;GAAW,CAAC;;;;;CAMzE,OAAU,UAAoB,eAAkC;AAC9D,OAAK,SAAS,KAAK;GAAE,MAAM;GAAU;GAAU;GAAe,CAAC;;;;;CAMjE,OAAO,UAA0B;AAC/B,OAAK,SAAS,KAAK;GAAE,MAAM;GAAW;GAAU,CAAC;;;;;CAMnD,UAAgB;EACd,MAAM,iBAAiB;EACvB,IAAI,aAAa;AAEjB,SAAO,KAAK,SAAS,SAAS,GAAG;AAC/B,OAAI,cAAc,eAChB,OAAM,IAAI,MAAM,wEAAwE;AAE1F;GAEA,MAAM,kBAAkB,CAAC,GAAG,KAAK,SAAS;AAC1C,QAAK,WAAW,EAAE;GAGlB,MAAM,iCAAiB,IAAI,KAA0B;AACrD,QAAK,MAAM,OAAO,iBAAiB;AACjC,QAAI,CAAC,eAAe,IAAI,IAAI,SAAS,CACnC,gBAAe,IAAI,IAAI,UAAU,EAAE,CAAC;AAEtC,mBAAe,IAAI,IAAI,SAAS,CAAE,KAAK,IAAI;;AAI7C,QAAK,MAAM,CAAC,UAAU,aAAa,eACjC,MAAK,sBAAsB,UAAU,SAAS;;;;;;CAQpD,cAAyB;AACvB,SAAO,CAAC,GAAG,KAAK,SAAS;;;;;CAM3B,QAAc;AACZ,OAAK,WAAW,EAAE;;;;;;ACxFtB,IAAM,WAAN,MAAqB;CACnB,AAAQ,sBAAsB,IAAI,KAAK;CAGvC,AAAQ,cAAc;CAEtB,IAAI,aAAqB;AACvB,SAAO,KAAK;;CAGd,IAAI,WAAmB;AACrB,SAAO,KAAK,IAAI;;CAGlB,OAAO,KAAiB;AACtB,SAAO,KAAK,IAAI,IAAI,IAAI;;CAG1B,IAAI,KAAQ,OAAoB;EAC9B,MAAM,MAAM,KAAK,IAAI,IAAI,IAAI;AAC7B,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI,UAAU,WAAW,EAAG,QAAO;AACnC,SAAO,IAAI,IAAI,MAAW;;CAG5B,IAAI,KAAQ,OAAgB;EAC1B,IAAI,MAAM,KAAK,IAAI,IAAI,IAAI;AAC3B,MAAI,CAAC,KAAK;AACR,yBAAM,IAAI,KAAK;AACf,QAAK,IAAI,IAAI,KAAK,IAAI;;AAExB,MAAI,CAAC,IAAI,IAAI,MAAM,EAAE;AACnB,OAAI,IAAI,MAAM;AACd,QAAK;;;CAKT,OAAO,KAAQ,OAAmB;EAChC,MAAM,MAAM,KAAK,IAAI,IAAI,IAAI;AAC7B,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI,CAAC,IAAI,IAAI,MAAM,CAAE,QAAO;AAC5B,MAAI,OAAO,MAAM;AACjB,OAAK;AACL,MAAI,IAAI,SAAS,EAAG,MAAK,IAAI,OAAO,IAAI;AACxC,SAAO;;CAIT,UAAU,KAAiB;EACzB,MAAM,MAAM,KAAK,IAAI,IAAI,IAAI;AAC7B,MAAI,CAAC,IAAK,QAAO;AACjB,OAAK,eAAe,IAAI;AACxB,OAAK,IAAI,OAAO,IAAI;AACpB,SAAO;;CAGT,IAAI,KAAgB;EAClB,MAAM,MAAM,KAAK,IAAI,IAAI,IAAI;AAC7B,SAAO,MAAM,IAAI,IAAI,IAAI,mBAAG,IAAI,KAAK;;CAIvC,CAAC,OAA4B;AAC3B,SAAO,KAAK,IAAI,MAAM;;CAGxB,CAAC,SAA8B;AAC7B,OAAK,MAAM,OAAO,KAAK,IAAI,QAAQ,CACjC,MAAK,MAAM,KAAK,IAAK,OAAM;;CAI/B,CAAC,OAAO,YAAsC;AAC5C,SAAO,KAAK,SAAS;;CAGvB,CAAC,UAAoC;AACnC,OAAK,MAAM,CAAC,GAAG,QAAQ,KAAK,IAAI,SAAS,CACvC,MAAK,MAAM,KAAK,IAAK,OAAM,CAAC,GAAG,EAAE;;CAIrC,QAAc;AACZ,OAAK,IAAI,OAAO;AAChB,OAAK,cAAc;;;;;;;;;;AC1EvB,SAAgB,qBAAqB,SAAsB,EAAE,EAAU;CACrE,MAAM,YAAY,OAAO,0BAA0B,EAAE,EAAE,OAAO,CAAC,MAAM,GAAG,MAAM,IAAI,EAAE;AACpF,KAAI,SAAS,WAAW,EAAG,QAAO;AAClC,QAAO,OAAO,SAAS,KAAK,IAAI;;;;;AAMlC,SAAgB,sBAAsB,WAAsB,gBAA0C;AACpG,QAAO,eAAe,OAAO,SAAS;EACpC,MAAM,eAAe,kBAAkB,KAAK;AAC5C,MAAI,aAAa,SAAS,oBAExB,QAAO,UAAU,eAAe,MAAM,kBAAkB;AACtD,OAAI,CAAC,aAAa,cAAc,CAAE,QAAO;AAEzC,UADgB,iBAAiB,cAAc,CAChC,gBAAgB,aAAa;IAC5C;MAGF,QAAO,UAAU,eAAe,SAAS,KAAK;GAEhD;;;;;AAMJ,SAAgB,cAAc,WAAsB,QAA8B;AAEhF,SADsB,OAAO,0BAA0B,EAAE,EACpC,OAAO,SAAS;EACnC,MAAM,eAAe,kBAAkB,KAAK;AAC5C,MAAI,aAAa,SAAS,oBAExB,QAAO,CAAC,UAAU,eAAe,MAAM,kBAAkB;AACvD,OAAI,CAAC,aAAa,cAAc,CAAE,QAAO;AAEzC,UADgB,iBAAiB,cAAc,CAChC,gBAAgB,aAAa;IAC5C;MAGF,QAAO,CAAC,UAAU,eAAe,SAAS,KAAK;GAEjD;;;;;;;;AClDJ,IAAa,QAAb,MAAmB;CACjB,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAQ,mBAAgC,EAAE;CAC1C,AAAQ,aAAa;CAErB,YAAY,OAAqB,gBAAiC,SAAsB,EAAE,EAAE;AAC1F,OAAK,QAAQ;AACb,OAAK,iBAAiB,CAAC,GAAG,eAAe,CAAC,MAAM,GAAG,MAAM,IAAI,EAAE;AAC/D,OAAK,SAAS;AACd,OAAK,aAAa;AAElB,QAAM,eAAe,KAAK;;;;;CAM5B,AAAQ,oBAA0B;AAChC,MAAI,KAAK,WACP,OAAM,IAAI,MAAM,0BAA0B;;;;;CAO9C,cAA0B;AACxB,OAAK,mBAAmB;EACxB,MAAMC,SAAqB,EAAE;AAC7B,OAAK,MAAM,aAAa,KAAK,iBAC3B,QAAO,KAAK,GAAG,UAAU,aAAa,CAAC;AAEzC,SAAO;;;;;;;CAQT,0BACE,gBAIC;AACD,OAAK,mBAAmB;EAExB,MAAMC,SAGD,EAAE;AAEP,OAAK,MAAM,aAAa,KAAK,kBAAkB;GAC7C,MAAM,mBAAmB,UAAU,0BAA0B,eAAe;AAC5E,UAAO,KAAK,GAAG,iBAAiB;;AAGlC,SAAO;;;;;;;CAQT,QACE,gBACA,UACM;AACN,OAAK,mBAAmB;AAExB,OAAK,MAAM,aAAa,KAAK,iBAC3B,WAAU,sBAAsB,gBAAgB,SAAS;;;;;;CAQ7D,CAAC,QACC,gBACoD;AACpD,OAAK,mBAAmB;AAExB,OAAK,MAAM,aAAa,KAAK,iBAC3B,QAAO,UAAU,sBAAsB,eAAe;;;;;;;CAS1D,iBAAoB,eAAiC;AACnD,OAAK,mBAAmB;EAExB,MAAMC,SAAc,EAAE;AACtB,OAAK,MAAM,aAAa,KAAK,iBAC3B,QAAO,KAAK,GAAG,UAAU,iBAAiB,cAAc,CAAC;AAE3D,SAAO;;;;;;CAOT,cAAoB;AAClB,MAAI,KAAK,WAAY;AAErB,OAAK,mBAAmB,KAAK,MAC1B,sBAAsB,KAAK,eAAe,CAC1C,QAAQ,cAAyB,cAAc,WAAW,KAAK,OAAO,CAAC;;;;;CAM5E,kBAAkB,WAA4B;AAC5C,MAAI,KAAK,WAAY;AACrB,MACE,sBAAsB,WAAW,KAAK,eAAe,IACrD,cAAc,WAAW,KAAK,OAAO,IACrC,CAAC,KAAK,iBAAiB,SAAS,UAAU,CAE1C,MAAK,iBAAiB,KAAK,UAAU;;;;;CAOzC,gBAAgB,WAA4B;AAC1C,MAAI,KAAK,WAAY;EACrB,MAAM,QAAQ,KAAK,iBAAiB,QAAQ,UAAU;AACtD,MAAI,UAAU,GACZ,MAAK,iBAAiB,OAAO,OAAO,EAAE;;;;;;;;;;CAY1C,UAAgB;AAEd,OAAK,MAAM,aAAa,KAAK;;;;;CAM/B,mBAAyB;AACvB,MAAI,CAAC,KAAK,YAAY;AAEpB,QAAK,MAAM,iBAAiB,KAAK;AACjC,QAAK,mBAAmB,EAAE;AAC1B,QAAK,aAAa;;;;;;CAOtB,CAAC,OAAO,WAAiB;AACvB,OAAK,SAAS;;;;;CAMhB,IAAI,WAAoB;AACtB,SAAO,KAAK;;;;;;;;;ACzLhB,IAAa,kBAAb,MAA8D;CAC5D,AAAQ,0BAAU,IAAI,KAA2B;CACjD,AAAQ,qCAAqB,IAAI,KAAsD;CACvF,AAAQ,uBAAsD;;;;;;CAO9D,UAAU,QAA8B,iBAAyC,EAAE,EAAQ;AACzF,OAAK,QAAQ,IAAI,OAAO;AAExB,OAAK,MAAM,OAAO,OAAO,gBAAgB,EAAE,CACzC,MAAK,QAAQ,IAAI,IAAI;AAEvB,OAAK,mBAAmB,IAAI,QAAQ,IAAI,IAAI,CAAC,GAAG,gBAAgB,GAAI,OAAO,gBAAgB,EAAE,CAAE,CAAC,CAAC;AACjG,OAAK,uBAAuB;;;;;;CAO9B,oBAA4C;AAC1C,MAAI,KAAK,yBAAyB,KAChC,QAAO,KAAK;EAGd,MAAMC,SAAiC,EAAE;EACzC,MAAM,0BAAU,IAAI,KAA2B;EAC/C,MAAM,2BAAW,IAAI,KAA2B;EAEhD,MAAM,SAAS,WAAuC;AACpD,OAAI,QAAQ,IAAI,OAAO,CAAE;AACzB,OAAI,SAAS,IAAI,OAAO,CACtB,OAAM,IAAI,MAAM,oDAAoD;AAGtE,YAAS,IAAI,OAAO;AAEpB,QAAK,MAAM,OAAO,KAAK,mBAAmB,IAAI,OAAO,IAAI,EAAE,CACzD,OAAM,IAAI;AAGZ,YAAS,OAAO,OAAO;AACvB,WAAQ,IAAI,OAAO;AACnB,UAAO,KAAK,OAAO;;AAGrB,OAAK,MAAM,UAAU,KAAK,QACxB,KAAI,CAAC,QAAQ,IAAI,OAAO,CACtB,OAAM,OAAO;AAIjB,OAAK,uBAAuB;AAC5B,SAAO;;CAGT,OAAO,GAAG,QAA8C;EACtD,MAAM,iBAAiB,KAAK,mBAAmB;EAC/C,MAAM,iCAAiB,IAAI,KAA0C;AAErE,OAAK,MAAM,UAAU,gBAAgB;GAEnC,MAAM,cADO,MAAM,KAAK,KAAK,mBAAmB,IAAI,OAAO,IAAI,EAAE,CAAC,CACzC,KAAK,QAAQ,eAAe,IAAI,IAAI,CAAE,CAAC,OAAO,QAAQ;AAE/E,OAAI,YAAY,SAAS,GAAG;IAC1B,MAAM,UAAU,QAAQ,IAAI,YAAY,CAAC,WAAW,OAAO,OAAO,GAAG,OAAO,CAAC;AAC7E,mBAAe,IAAI,QAAQ,QAAQ;UAC9B;IACL,MAAM,SAAS,OAAO,OAAO,GAAG,OAAO;AACvC,QAAI,kBAAkB,QACpB,gBAAe,IAAI,QAAQ,OAAO;;;AAKxC,SAAO,QAAQ,IAAI,eAAe,QAAQ,CAAC;;;;;CAM7C,QAAc;AACZ,OAAK,QAAQ,OAAO;AACpB,OAAK,uBAAuB;;;;;;;;;;AChEhC,IAAa,QAAb,MAAoD;;CAGlD,AAAQ,kBAAkB,IAAI,iBAAiB;;CAG/C,AAAQ,aAA0B,EAAE;;CAGpC,AAAQ,uCAAuB,IAAI,KAAwB;;CAG3D,AAAQ,oCAAoB,IAAI,KAA0B;;CAG1D,AAAQ,wCAAwB,IAAI,KAAiC;;CAGrE,AAAQ,mCAAmB,IAAI,KAA6C;;CAG5E,AAAQ,wCAAgE,IAAI,KAAK;;CAIjF,AAAQ,UAAmB,EAAE;;CAG7B,AAAQ,6BAAa,IAAI,KAAiD;;CAI1E,AAAQ,kBAAkB,IAAI,iBAA+B;;CAI7D,AAAQ,gBAAgB,IAAI,eAAe,UAAU,aAAa,KAAK,sBAAsB,UAAU,SAAS,CAAC;;CAIjH,AAAQ,wBAAQ,IAAI,KAA6C;;;;;;CAOjE,YAAY,UAA4B;AAEtC,MAAI,YAAY,OAAO,aAAa,UAAU;AAC5C,OAAI,SAAS,cACX,MAAK,gBAAgB,iBAAiB,SAAS,cAAc;AAI/D,OAAI,MAAM,QAAQ,SAAS,SAAS,CAClC,MAAK,MAAM,SAAS,SAAS,UAAU;IACrC,MAAM,WAAW,MAAM;IACvB,MAAMC,kBAAyC,MAAM,cAAc,EAAE;IAErE,MAAM,+BAAe,IAAI,KAAyB;IAClD,MAAMC,iBAAkC,EAAE;AAE1C,SAAK,MAAM,kBAAkB,iBAAiB;KAC5C,MAAM,mBAAmB,eAAe;KACxC,IAAIC;AAEJ,SAAI,OAAO,qBAAqB,SAC9B,iBAAgB;cACP,OAAO,qBAAqB,UAAU;MAE/C,MAAM,SAAS,qBAAqB,iBAAiB;AACrD,UAAI,WAAW,OACb,OAAM,IAAI,MAAM,uCAAuC,mBAAmB;AAE5E,sBAAgB;gBAEhB,OAAO,qBAAqB,YAC5B,qBAAqB,QACrB,OAAO,iBAAiB,cAAc,UACtC;MAEA,MAAM,SAAS,qBAAqB,iBAAiB,UAAU;AAC/D,UAAI,WAAW,OACb,OAAM,IAAI,MAAM,uCAAuC,iBAAiB,YAAY;AAEtF,UAAI,OAAO,iBAAiB,WAAW,UAAU;OAC/C,MAAM,eAAe,qBAAqB,iBAAiB,OAAO;AAClE,WAAI,iBAAiB,OACnB,OAAM,IAAI,MAAM,8CAA8C,iBAAiB,SAAS;AAE1F,uBAAgB,SAAS,QAAQ,aAAa;YAE9C,iBAAgB,SAAS,QAAQ,iBAAiB,OAAmB;WAGvE,OAAM,IAAI,MAAM,uCAAuC,KAAK,UAAU,iBAAiB,GAAG;AAE5F,kBAAa,IAAI,eAAe,eAAe,MAAM;AACrD,oBAAe,KAAK,cAAc;;IAGpC,MAAM,YAAY,KAAK,gBAAgB,eAAe;AACtD,cAAU,UAAU,UAAU,aAAa;AAC3C,SAAK,kBAAkB,IAAI,UAAU,UAAU;AAG/C,SAAK,MAAM,YAAY,gBAAgB;KACrC,MAAM,eAAe,kBAAkB,SAAS;AAChD,SAAI,aAAa,SAAS,mBAAmB;MAC3C,MAAM,iBAAiB,aAAa;AACpC,WAAK,qBAAqB,UAAU,UAAU,eAAe;gBACpD,aAAa,SAAS,SAC/B,MAAK,qBAAqB,UAAU,UAAU,SAAS;;;;;;;;;CAYnE,AAAQ,yBAAyB,gBAAyC;AACxE,SAAO,eAAe,KAAK,IAAI;;;;;;CAOjC,MAAgB;EACd,MAAM,WAAW,KAAK,gBAAgB,UAAU;EAEhD,IAAI,iBAAiB,KAAK,gBAAgB,EAAE,CAAC;AAC7C,iBAAe,UAAU,0BAAU,IAAI,KAAK,CAAC;AAC7C,OAAK,kBAAkB,IAAI,UAAU,eAAe;AACpD,SAAO;;;;;CAMT,AAAQ,uBAAuB,UAA0B;EAEvD,MAAMC,QAAoB,CAAC,SAAS;EACpC,MAAM,0BAAU,IAAI,KAAe;AAEnC,SAAO,MAAM,SAAS,GAAG;GACvB,MAAM,MAAM,MAAM,OAAO;AACzB,OAAI,QAAQ,IAAI,IAAI,CAAE;AACtB,WAAQ,IAAI,IAAI;GAEhB,MAAM,YAAY,KAAK,kBAAkB,IAAI,IAAI;AACjD,OAAI,CAAC,UACH;GAIF,MAAM,sBAAsB,MAAM,KAAK,KAAK,oBAAoB,IAAI,CAAC;AACrE,QAAK,MAAM,CAAC,gBAAgB,kBAAkB,qBAAqB;IAEjE,MAAM,kBAAkB,KAAK,kBAAkB,IAAI,eAAe;AAClE,QAAI,CAAC,gBAAiB;IAEtB,MAAM,eAAe,kBAAkB,cAAc;AAErD,QAAI,aAAa,SAAS,qBAAqB,yBAAyB,aAAa,YAAa,EAAE;AAElG,SAAI,CAAC,QAAQ,IAAI,eAAe,CAC9B,OAAM,KAAK,eAAe;AAE5B;;IAIF,MAAM,oCAAoB,IAAI,KAAyB;IACvD,IAAI,mBAAmB,gBAAgB,IAAI,gBAAgB,cAAc;AACzE,SAAK,MAAM,0BAA0B,gBAAgB,eACnD,KAAI,2BAA2B,eAAe;KAC5C,MAAM,gBAAgB,gBAAgB,IAAI,gBAAgB,uBAAuB;AACjF,uBAAkB,IAAI,wBAAwB,cAAc;;IAIhE,MAAM,eAAe,KAAK,gBAAgB,kBAAkB,MAAM,CAAC;AAGnE,oBAAgB,aAAa,eAAe;AAC5C,QAAI,gBAAgB,aAAa,CAAC,WAAW,EAC3C,MAAK,sBAAsB,gBAAgB;AAI7C,iBAAa,UAAU,gBAAgB,kBAAkB;AACzD,SAAK,kBAAkB,IAAI,gBAAgB,aAAa;AAGxD,SAAK,uBAAuB,gBAAgB,eAAe,IAAI;AAG/D,SAAK,sBAAsB,gCAAgB,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC,CAAC,eAAe,iBAAiB,CAAC,CAAC,CAAC;;AAIrG,QAAK,iBAAiB,OAAO,IAAI;AAGjC,aAAU,aAAa,IAAI;AAC3B,OAAI,UAAU,aAAa,CAAC,WAAW,EACrC,MAAK,sBAAsB,UAAU;AAEvC,QAAK,kBAAkB,OAAO,IAAI;AAClC,QAAK,gBAAgB,WAAW,IAAI;;;;;;CAOxC,OAAO,UAA6B;AAClC,SAAO,KAAK,kBAAkB,IAAI,SAAS;;CAQ7C,IAAI,UAAoB,eAAyB,aAAuB;AACtE,MAAI,CAAC,KAAK,OAAO,SAAS,CACxB,OAAM,IAAI,MAAM,UAAU,SAAS,iBAAiB;EAItD,MAAM,eAAe,kBAAkB,cAAc;AACrD,MAAI,aAAa,SAAS,UACxB,OAAM,IAAI,MAAM,2BAA2B,gBAAgB;AAE7D,MAAI,aAAa,SAAS,oBACxB,OAAM,IAAI,MAAM,qDAAqD,gBAAgB;AAGvF,OAAK,cAAc,IAAI,UAAU,eAAeC,YAAU;;;;;CAM5D,OAAU,UAAoB,eAAkC;AAC9D,MAAI,CAAC,KAAK,OAAO,SAAS,CACxB,OAAM,IAAI,MAAM,UAAU,SAAS,iBAAiB;AAKtD,MADqB,kBAAkB,cAAc,CACpC,SAAS,UACxB,OAAM,IAAI,MAAM,2BAA2B,gBAAgB;AAG7D,OAAK,cAAc,OAAO,UAAU,cAAc;;;;;CAMpD,OAAO,UAA0B;AAC/B,OAAK,cAAc,OAAO,SAAS;;;;;CAMrC,IAAO,UAAoB,eAAqC;EAC9D,MAAM,YAAY,KAAK,kBAAkB,IAAI,SAAS;AACtD,MAAI,CAAC,UACH,QAAO;AAIT,MAAI,UAAU,eAAe,SAAS,cAAc,CAClD,QAAO;EAIT,MAAM,eAAe,kBAAkB,cAAc;AACrD,OACG,aAAa,SAAS,qBAAqB,aAAa,SAAS,yBAClE,wBAAwB,aAAa,YAAa,CAGlD,QAAO,KAAK,sBAAsB,IAAI,SAAS,EAAE,IAAI,cAAc,IAAI;AAGzE,SAAO;;CAkBT,IAAO,UAAoB,eAAoF;EAC7G,MAAM,YAAY,KAAK,kBAAkB,IAAI,SAAS;AACtD,MAAI,CAAC,UACH,OAAM,IAAI,MAAM,UAAU,SAAS,iBAAiB;EAKtD,MAAM,eAAe,kBAAkB,cAAc;AACrD,MAAI,aAAa,SAAS,qBAAqB;GAE7C,MAAM,cAAc,UAAU,eAAe,SAAS,cAAc;GACpE,MAAM,kBACH,aAAa,SAAS,qBAAqB,aAAa,SAAS,yBAClE,wBAAwB,aAAa,YAAa;AAMpD,OAAI,EAFF,eAAgB,kBAAkB,KAAK,sBAAsB,IAAI,SAAS,EAAE,IAAI,cAAc,EAG9F,OAAM,IAAI,MACR,UAAU,SAAS,2BAA2B,cAAc,gEAC7D;;AAIL,SAAO,UAAU,IAAI,UAAU,cAAc;;;;;CAM/C,eAAe,QAA8B,iBAAyC,EAAE,EAAQ;AAC9F,OAAK,gBAAgB,UAAU,QAAQ,eAAe;;;;;CAMxD,KAAQ,eAA4B,MAA8B;AAChE,MAAI,CAAC,KAAK,MAAM,IAAI,cAAc,CAChC,MAAK,MAAM,IAAI,+BAAe,IAAI,KAAK,CAAC;AAE1C,OAAK,MAAM,IAAI,cAAc,CAAE,IAAI,KAAK;AAExC,MAAI,KAAK,YAAY,OACnB,MAAK,sBAAsB,IAAI,cAAc,EAAE,SAAS,cAAc;GACpE,MAAM,WAAW,UAAU,qBAAqB;GAChD,MAAM,gBAAgB,UAAU,iBAAoB,cAAc;AAClE,QAAK,MAAM,CAAC,QAAQ,UAAU,UAAU;IACtC,MAAM,OAAO,cAAc;IAC3B,MAAM,QAAS,SAAS,oBAAoB,SAAY;AACxD,SAAK,UAAU,QAAQ,eAAe,MAAM;;IAE9C;;;;;CAON,OAAU,eAA4B,MAA8B;EAClE,MAAM,QAAQ,KAAK,MAAM,IAAI,cAAc;AAC3C,MAAI,OAAO;AACT,SAAM,OAAO,KAAK;AAClB,OAAI,MAAM,SAAS,EACjB,MAAK,MAAM,OAAO,cAAc;;;;;;;;CAUtC,aAAa,aAA6B;AACxC,QAAM,IAAI,MAAM,+FAA+F;;;;;;;CAQjH,iBAAiB,aAA6B;AAC5C,QAAM,IAAI,MACR,uGACD;;;;;;;CAQH,OAAO,GAAG,QAA4C;EACpD,MAAM,SAAS,KAAK,gBAAgB,OAAO,GAAG,OAAO;AACrD,MAAI,kBAAkB,QACpB,QAAO,OAAO,WAAW,KAAK,cAAc,SAAS,CAAC;MAEtD,MAAK,cAAc,SAAS;;;;;CAOhC,OAAa;AACX,OAAK,cAAc,SAAS;;;;;;CAO9B,YAAY,gBAAiC,SAAsB,EAAE,EAAS;EAE5E,MAAM,cAAc,CAAC,GAAG,eAAe,CAAC,MAAM,GAAG,MAAM,IAAI,EAAE;EAC7D,MAAM,YAAY,qBAAqB,OAAO;EAC9C,MAAM,MAAM,GAAG,KAAK,yBAAyB,YAAY,GAAG,YAAY,IAAI,cAAc;EAE1F,MAAM,SAAS,KAAK,WAAW,IAAI,IAAI;AACvC,MAAI,QAAQ;AACV,UAAO;AACP,UAAO,OAAO;;EAGhB,MAAM,QAAQ,IAAI,MAAM,MAAM,aAAa,OAAO;AAClD,OAAK,WAAW,IAAI,KAAK;GAAE;GAAO,UAAU;GAAG,CAAC;AAChD,SAAO;;;;;CAMT,eAAe,OAAoB;AACjC,OAAK,QAAQ,KAAK,MAAM;;;;;CAM1B,iBAAiB,OAAoB;EACnC,MAAM,QAAQ,KAAK,QAAQ,QAAQ,MAAM;AACzC,MAAI,UAAU,GACZ,MAAK,QAAQ,OAAO,OAAO,EAAE;;;;;;CAQjC,aAAa,OAAoB;AAC/B,OAAK,MAAM,CAAC,GAAG,MAAM,KAAK,WAAW,SAAS,CAC5C,KAAI,EAAE,UAAU,OAAO;AACrB,KAAE;AACF,OAAI,EAAE,YAAY,GAAG;AACnB,SAAK,WAAW,OAAO,EAAE;AACzB,SAAK,iBAAiB,MAAM;AAE5B,MAAE,MAAM,kBAAkB;;AAE5B;;;;;;CAQN,sBAAsB,gBAA8C;AAClE,MAAI,eAAe,WAAW,EAC5B,QAAO,CAAC,GAAG,KAAK,WAAW;EAI7B,MAAMC,oBAAqC,EAAE;EAC7C,MAAMC,oBAAiF,EAAE;AAEzF,OAAK,MAAM,iBAAiB,gBAAgB;GAC1C,MAAM,eAAe,kBAAkB,cAAc;AACrD,OAAI,aAAa,SAAS,oBACxB,mBAAkB,KAAK;IACrB,aAAa,aAAa;IAC1B,YAAY;IACb,CAAC;OAEF,mBAAkB,KAAK,cAAc;;EAKzC,IAAIC,qBAAkC,EAAE;AAExC,MAAI,kBAAkB,SAAS,GAAG;GAChC,MAAM,qBAAqB,CAAC,GAAG,kBAAkB,CAAC,MAAM,GAAG,MAAM,IAAI,EAAE;AAEvE,OAAI,mBAAmB,WAAW,GAAG;IACnC,MAAM,gBAAgB,mBAAmB;AACzC,yBAAqB,KAAK,sBAAsB,IAAI,cAAc,IAAI,EAAE;UACnE;IAEL,MAAM,iBAAiB,mBAAmB,KAAK,SAAS,KAAK,sBAAsB,IAAI,KAAK,IAAI,EAAE,CAAC;IACnG,MAAM,YAAY,eAAe,MAAM,EAAE;IACzC,MAAM,+BAAe,IAAI,KAAgB;AAGzC,SAAK,MAAM,aAAa,WAAW;KACjC,IAAI,mBAAmB;AACvB,UAAK,IAAI,YAAY,GAAG,YAAY,eAAe,QAAQ,YAEzD,KAAI,CADc,eAAe,WAClB,SAAS,UAAU,EAAE;AAClC,yBAAmB;AACnB;;AAGJ,SAAI,iBACF,cAAa,IAAI,UAAU;;AAI/B,yBAAqB,MAAM,KAAK,aAAa;;QAI/C,sBAAqB,CAAC,GAAG,KAAK,WAAW;AAI3C,OAAK,MAAM,YAAY,kBAErB,sBAAqB,mBAAmB,QAAQ,cAC9C,UAAU,eAAe,MAAM,kBAAkB;AAC/C,OAAI,CAAC,aAAa,cAAc,CAAE,QAAO;AAEzC,UADgB,iBAAiB,cAAc,CAChC,gBAAgB,SAAS;IACxC,CACH;AAGH,SAAO;;CAeT,MACE,gBACA,mBAMK;EACL,MAAM,qBAAqB,KAAK,sBAAsB,eAAe;AAErE,MAAI,mBAAmB;GACrB,MAAMC,SAGD,EAAE;AAEP,QAAK,MAAM,aAAa,oBAAoB;IAC1C,MAAM,mBAAmB,UAAU,0BAA0B,eAAkC;AAC/F,WAAO,KAAK,GAAG,iBAAiB;;AAGlC,UAAO;SACF;GACL,MAAMC,SAAqB,EAAE;AAC7B,QAAK,MAAM,aAAa,mBACtB,QAAO,KAAK,GAAG,UAAU,aAAa,CAAC;AAEzC,UAAO;;;;;;;CAQX,sBAAsB,UAAoB,UAAyC;EACjF,MAAM,YAAY,IAAI,oBAAoB;AAG1C,MAAI,SAAS,MAAM,QAAQ,IAAI,SAAS,UAAU,EAAE;AAClD,QAAK,uBAAuB,SAAS;AACrC,UAAO;;EAGT,MAAM,mBAAmB,KAAK,kBAAkB,IAAI,SAAS;AAC7D,MAAI,CAAC,iBACH,QAAO;AAIT,OAAK,gBAAgB,UAAU,kBAAkB,UAAU,UAAU;EAGrE,MAAM,oBAAoB,KAAK,eAAe,UAAU,kBAAkB,UAAU;AAGpF,OAAK,uBAAuB,UAAU,UAAU;AAGhD,OAAK,sBAAsB,UAAU,UAAU,MAAM,kBAAkB;AAEvE,SAAO;;;;;CAMT,AAAQ,gBACN,UACA,kBACA,UACA,WACM;AACN,OAAK,MAAM,WAAW,SACpB,KAAI,QAAQ,SAAS,SAAS,QAAQ,cACpC,MAAK,kBAAkB,UAAU,kBAAkB,QAAQ,eAAe,QAAQ,WAAW,UAAU;WAC9F,QAAQ,SAAS,YAAY,QAAQ,cAC9C,MAAK,qBAAqB,UAAU,kBAAkB,QAAQ,eAAe,UAAU;;;;;CAQ7F,AAAQ,kBACN,UACA,kBACA,eACA,aACA,WACM;EACN,MAAM,eAAe,kBAAkB,cAAc;AAGrD,OACG,aAAa,SAAS,qBAAqB,aAAa,SAAS,yBAClE,qBAAqB,aAAa,YAAa,CAE/C,MAAK,yBAAyB,UAAU,kBAAkB,aAAa,aAAc,UAAU;AAGjG,YAAU,IAAI,eAAeL,YAAU;;;;;CAMzC,AAAQ,yBACN,UACA,kBACA,iBACA,WACM;AAEN,OAAK,MAAM,iBAAiB,iBAAiB,eAC3C,KAAI,KAAK,wBAAwB,eAAe,gBAAgB,CAC9D,WAAU,OAAO,cAAc;EAKnC,MAAM,aAAa,iBAAiB,UAAU,SAAS;AACvD,MAAI,WACF,MAAK,MAAM,CAAC,kBAAkB,YAAY;AACxC,OAAI,iBAAiB,eAAe,SAAS,cAAc,CAAE;AAC7D,OAAI,KAAK,wBAAwB,eAAe,gBAAgB,CAC9D,WAAU,OAAO,cAAc;;;;;;CASvC,AAAQ,wBAAwB,eAA8B,iBAAyC;EACrG,MAAM,eAAe,kBAAkB,cAAc;AACrD,UACG,aAAa,SAAS,qBAAqB,aAAa,SAAS,yBAClE,aAAa,gBAAgB;;;;;CAOjC,AAAQ,qBACN,UACA,kBACA,eACA,WACM;EACN,MAAM,eAAe,kBAAkB,cAAc;AAErD,MAAI,aAAa,SAAS,oBACxB,MAAK,wBAAwB,UAAU,kBAAkB,aAAa,aAAc,UAAU;MAE9F,WAAU,OAAO,cAAc;;;;;CAOnC,AAAQ,wBACN,UACA,kBACA,iBACA,WACM;AAEN,OAAK,MAAM,iBAAiB,iBAAiB,eAC3C,KAAI,KAAK,wBAAwB,eAAe,gBAAgB,CAC9D,WAAU,OAAO,cAAc;EAKnC,MAAM,aAAa,iBAAiB,UAAU,SAAS;AACvD,MAAI,WACF,MAAK,MAAM,CAAC,kBAAkB,YAAY;AACxC,OAAI,iBAAiB,eAAe,SAAS,cAAc,CAAE;AAC7D,OAAI,KAAK,wBAAwB,eAAe,gBAAgB,CAC9D,WAAU,OAAO,cAAc;;;;;;;CAUvC,AAAQ,eACN,UACA,kBACA,WACyB;EACzB,MAAM,oBAAoB,iBAAiB,UAAU,SAAS;EAC9D,MAAM,2BAA2B,oBAC7B,MAAM,KAAK,kBAAkB,MAAM,CAAC,GACpC,iBAAiB;EAErB,MAAM,sBAAsB,UAAU,uBAAuB,yBAAyB;EACtF,MAAM,oCAAoB,IAAI,KAAyB;AAEvD,MAAI,oBAEF,MAAK,yBAAyB,UAAU,kBAAkB,qBAAqB,WAAW,kBAAkB;MAG5G,MAAK,4BAA4B,UAAU,kBAAkB,WAAW,kBAAkB;AAG5F,SAAO;;;;;CAMT,AAAQ,yBACN,UACA,kBACA,qBACA,WACA,mBACM;EACN,MAAM,eAAe,KAAK,gBAAgB,oBAAoB;EAC9D,MAAM,oBAAoB,iBAAiB,aAAa,SAAS;AAGjE,OAAK,MAAM,iBAAiB,UAAU,QACpC,mBAAkB,IAAI,eAAe,kBAAkB,IAAI,cAAc,CAAC;AAI5E,eAAa,UAAU,UAAU,UAAU,QAAQ,kBAAkB,CAAC;AACtE,OAAK,kBAAkB,IAAI,UAAU,aAAa;AAGlD,MAAI,iBAAiB,aAAa,CAAC,WAAW,EAC5C,MAAK,sBAAsB,iBAAiB;;;;;CAOhD,AAAQ,4BACN,UACA,kBACA,WACA,mBACM;EACN,MAAM,oBAAoB,iBAAiB,UAAU,SAAS;EAC9D,MAAM,yBAAyB,KAAK,uBAAuB,UAAU;AAGrE,MAAI,uBACF,MAAK,MAAM,iBAAiB,UAAU,SAAS;GAC7C,MAAM,eAAe,kBAAkB,cAAc;AACrD,QACG,aAAa,SAAS,qBAAqB,aAAa,SAAS,yBAClE,wBAAwB,aAAa,YAAa,CAElD,mBAAkB,IAAI,eAAe,kBAAkB,IAAI,cAAc,CAAC;;AAKhF,MAAI,uBAEF,MAAK,iCAAiC,UAAU,kBAAkB,mBAAmB,UAAU;MAG/F,MAAK,MAAM,CAAC,eAAeA,gBAAc,UAAU,KACjD,kBAAiB,IAAI,UAAU,eAAeA,YAAU;;;;;CAQ9D,AAAQ,uBAAuB,WAAwC;AACrE,OAAK,MAAM,iBAAiB,UAAU,SAAS;GAC7C,MAAM,eAAe,kBAAkB,cAAc;AACrD,QACG,aAAa,SAAS,qBAAqB,aAAa,SAAS,yBAClE,wBAAwB,aAAa,YAAa,CAElD,QAAO;;AAIX,OAAK,MAAM,CAAC,kBAAkB,UAAU,MAAM;GAC5C,MAAM,eAAe,kBAAkB,cAAc;AACrD,QACG,aAAa,SAAS,qBAAqB,aAAa,SAAS,yBAClE,wBAAwB,aAAa,YAAa,CAElD,QAAO;;AAIX,SAAO;;;;;CAMT,AAAQ,iCACN,UACA,WACA,mBACA,WACM;EACN,MAAM,gCAAgB,IAAI,KAAyB;AAGnD,OAAK,MAAM,CAAC,IAAI,UAAU,kBACxB,KAAI,CAAC,UAAU,QAAQ,IAAI,GAAG,CAC5B,eAAc,IAAI,IAAI,MAAM;AAKhC,OAAK,MAAM,CAAC,IAAI,UAAU,UAAU,KAClC,eAAc,IAAI,IAAI,MAAM;AAG9B,YAAU,aAAa,SAAS;AAChC,YAAU,UAAU,UAAU,cAAc;;;;;CAM9C,AAAQ,uBAAuB,UAAoB,WAAqC;AAEtF,OAAK,MAAM,iBAAiB,UAAU,SAAS;GAC7C,MAAM,eAAe,kBAAkB,cAAc;AACrD,OAAI,aAAa,SAAS,kBACxB,MAAK,uBAAuB,UAAU,eAAe,aAAa,SAAU;YACnE,aAAa,SAAS,SAC/B,MAAK,uBAAuB,UAAU,eAAe,cAAc;;AAKvE,OAAK,MAAM,CAAC,kBAAkB,UAAU,MAAM;GAC5C,MAAM,eAAe,kBAAkB,cAAc;AACrD,OAAI,aAAa,SAAS,kBACxB,MAAK,qBAAqB,UAAU,eAAe,aAAa,SAAU;YACjE,aAAa,SAAS,SAC/B,MAAK,qBAAqB,UAAU,eAAe,cAAc;;;;;;;;CAUvE,AAAQ,gBAAgB,gBAAoD;EAE1E,MAAM,cADe,KAAK,4BAA4B,eAAe,CACpC,MAAM,GAAG,MAAM,IAAI,EAAE;EACtD,MAAM,UAAU,KAAK,yBAAyB,YAAY;AAE1D,SAAO,0BAA0B,KAAK,sBAAsB,eAAe,KAAK,mBAAmB,YAAY,CAAC;;;;;CAMlH,AAAQ,4BAA4B,gBAA0D;EAC5F,MAAMM,eAAgC,EAAE;AAExC,OAAK,MAAM,iBAAiB,gBAAgB;GAC1C,MAAM,eAAe,kBAAkB,cAAc;AAGrD,QACG,aAAa,SAAS,qBAAqB,aAAa,SAAS,yBAClE,wBAAwB,aAAa,YAAa,CAElD;AAGF,gBAAa,KAAK,cAAc;;AAGlC,SAAO;;;;;CAMT,AAAQ,mBAAmB,gBAA4C;EACrE,MAAM,eAAe,IAAI,UAAU,gBAAgB,KAAK,sBAAsB;AAC9E,OAAK,WAAW,KAAK,aAAa;AAGlC,OAAK,kCAAkC,cAAc,eAAe;AAGpE,OAAK,4BAA4B,aAAa;AAE9C,SAAO;;;;;CAMT,AAAQ,kCAAkC,WAAsB,gBAAuC;AACrG,OAAK,MAAM,iBAAiB,gBAAgB;GAC1C,MAAM,aAAa,KAAK,sBAAsB,IAAI,cAAc,IAAI,EAAE;AACtE,cAAW,KAAK,UAAU;AAC1B,QAAK,sBAAsB,IAAI,eAAe,WAAW;;;;;;CAO7D,AAAQ,4BAA4B,WAA4B;AAC9D,OAAK,MAAM,SAAS,KAAK,QACvB,OAAM,kBAAkB,UAAU;;;;;;;;CAUtC,AAAQ,qBAAqB,gBAA0B,eAAyB,gBAAgC;AAC9G,MAAI,CAAC,KAAK,iBAAiB,IAAI,eAAe,CAC5C,MAAK,iBAAiB,IAAI,gBAAgB,IAAI,UAAU,CAAC;AAE3D,OAAK,iBAAiB,IAAI,eAAe,CAAE,IAAI,gBAAgB,cAAc;;;;;;;;CAS/E,AAAQ,uBAAuB,gBAA0B,eAAyB,gBAAgC;EAChH,MAAM,aAAa,KAAK,iBAAiB,IAAI,eAAe;AAC5D,MAAI,YAAY;AACd,cAAW,OAAO,gBAAgB,cAAc;AAChD,OAAI,WAAW,aAAa,EAC1B,MAAK,iBAAiB,OAAO,eAAe;;;;;;;;CAUlD,AAAQ,oBAAoB,gBAA0D;AACpF,SAAO,KAAK,iBAAiB,IAAI,eAAe,IAAI,IAAI,UAAU;;;;;CAMpE,AAAQ,sBAAsB,WAA4B;AACxD,MAAI,UAAU,aAAa,CAAC,SAAS,EACnC;AAGF,OAAK,wBAAwB,UAAU;AACvC,OAAK,gCAAgC,UAAU;AAC/C,OAAK,kCAAkC,UAAU;AACjD,OAAK,2BAA2B,UAAU;;;;;CAM5C,AAAQ,wBAAwB,WAA4B;EAC1D,MAAM,QAAQ,KAAK,WAAW,QAAQ,UAAU;AAChD,MAAI,UAAU,GACZ,MAAK,WAAW,OAAO,OAAO,EAAE;;;;;CAOpC,AAAQ,gCAAgC,WAA4B;EAClE,MAAM,UAAU,KAAK,yBAAyB,UAAU,eAAe;AACvE,OAAK,qBAAqB,OAAO,QAAQ;;;;;CAM3C,AAAQ,kCAAkC,WAA4B;AACpE,OAAK,MAAM,iBAAiB,UAAU,gBAAgB;GACpD,MAAM,aAAa,KAAK,sBAAsB,IAAI,cAAc;AAChE,OAAI,YAAY;IACd,MAAM,YAAY,WAAW,QAAQ,UAAU;AAC/C,QAAI,cAAc,IAAI;AACpB,gBAAW,OAAO,WAAW,EAAE;AAC/B,SAAI,WAAW,WAAW,EACxB,MAAK,sBAAsB,OAAO,cAAc;;;;;;;;CAU1D,AAAQ,2BAA2B,WAA4B;AAC7D,OAAK,MAAM,SAAS,KAAK,QACvB,OAAM,gBAAgB,UAAU;;;;;CAOpC,AAAQ,sBACN,UACA,iBACA,mBACM;AAEN,OAAK,MAAM,CAAC,eAAeN,gBAAc,iBAAiB;GAExD,MAAM,cAAc,KAAK,MAAM,IAAI,cAAc;AACjD,OAAI,YACF,MAAK,MAAM,iBAAiB,YAC1B,eAAc,SAAS,UAAU,eAAeA,YAAU;GAK9D,MAAM,eAAe,kBAAkB,cAAc;AACrD,OACE,aAAa,SAAS,qBACtB,aAAa,SAAS,wBACtB,aAAa,SAAS,qBACtB;IACA,MAAM,qBAAqB,SAAS,aAAa,aAAc,IAAI;IACnE,MAAM,gBAAgB,KAAK,MAAM,IAAI,mBAAmB;AACxD,QAAI,cACF,MAAK,MAAM,iBAAiB,cAC1B,eAAc,SAAS,UAAU,eAAeA,YAAU;;;AAOlE,OAAK,MAAM,CAAC,eAAeA,gBAAc,mBAAmB;GAE1D,MAAM,cAAc,KAAK,MAAM,IAAI,cAAc;AACjD,OAAI,YACF,MAAK,MAAM,iBAAiB,YAC1B,eAAc,YAAY,UAAU,eAAeA,YAAU;GAKjE,MAAM,eAAe,kBAAkB,cAAc;AACrD,OACE,aAAa,SAAS,qBACtB,aAAa,SAAS,wBACtB,aAAa,SAAS,qBACtB;IACA,MAAM,qBAAqB,SAAS,aAAa,aAAc,IAAI;IACnE,MAAM,gBAAgB,KAAK,MAAM,IAAI,mBAAmB;AACxD,QAAI,cACF,MAAK,MAAM,QAAQ,cACjB,MAAK,YAAY,UAAU,eAAeA,YAAU;;;;;;;;;CAY9D,YAA6B;EAC3B,MAAMO,WAA+B,EAAE;AAEvC,OAAK,MAAM,aAAa,KAAK,YAAY;GACvC,MAAM,iBAAiB,UAAU,MAAM;AACvC,QAAK,MAAM,EAAE,QAAQ,gBAAgB,eACnC,UAAS,KAAK;IACZ,IAAI;IACJ,YAAY,MAAM,KAAK,WAAW,SAAS,CAAC,CAAC,KAAK,CAAC,SAAS,WAAW;KACrE,MAAM,eAAe,kBAAkB,QAAQ;KAC/C,IAAIC,OAAoC;KACxC,IAAI;AACJ,aAAQ,aAAa,MAArB;MACE,KAAK;AACH,cAAO,qBAAqB,QAAuB,IAAI;AACvD;MACF,KAAK;AACH,uBAAgB,qBAAqB,aAAa,YAAY;AAC9D,WAAI,cACF,QAAO;QAAE,WAAW;QAAe,QAAQ,aAAa;QAAW;AAErE;MACF,KAAK;AACH,uBAAgB,qBAAqB,aAAa,YAAY;AAC9D,WAAI,cACF,QAAO;QACL,WAAW;QACX,QAAQ,qBAAqB,aAAa,SAAU,IAAI,aAAa;QACtE;AAEH;;AAEJ,YAAO;MAAE;MAAM,OAAO,UAAU,oBAAoB,SAAY;MAAO;MACvE;IACH,CAAC;;AAIN,SAAO;GACL,SAAS;GACT,eAAe,KAAK,gBAAgB,gBAAgB;GACpD;GACD"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["actualTargetId: number","type: \"entity-relation\" | \"component-relation\" | \"wildcard-relation\"","ComponentNames: Map<ComponentId<any>, string>","ComponentIdForNames: Map<string, ComponentId<any>>","ComponentOptions: Map<ComponentId<any>, ComponentOptions>","name: string | undefined","options: ComponentOptions | undefined","result: Array<{\n entity: EntityId;\n components: Map<EntityId<any>, any>;\n }>","relations: [EntityId<unknown>, any][]","result: Array<{\n entity: EntityId;\n components: ComponentTuple<T>;\n }>","component","result: EntityId[]","result: Array<{\n entity: EntityId;\n components: ComponentTuple<T>;\n }>","result: T[]","result: System<UpdateParams>[]","componentsArray: SerializedComponent[]","componentTypes: EntityId<any>[]","componentType: EntityId<any>","queue: EntityId[]","component","regularComponents: EntityId<any>[]","wildcardRelations: { componentId: ComponentId<any>; relationId: EntityId<any> }[]","matchingArchetypes: Archetype[]","result: Array<{\n entity: EntityId;\n components: any;\n }>","result: EntityId[]","regularTypes: EntityId<any>[]","entities: SerializedEntity[]","type: SerializedComponent[\"type\"]"],"sources":["../src/entity.ts","../src/types.ts","../src/utils.ts","../src/archetype.ts","../src/changeset.ts","../src/command-buffer.ts","../src/multi-map.ts","../src/query-filter.ts","../src/query.ts","../src/system-scheduler.ts","../src/world.ts"],"sourcesContent":["/**\n * Unique symbol brand for associating component type information with EntityId\n */\ndeclare const __componentTypeMarker: unique symbol;\n\n/**\n * Unique symbol brand for tagging the kind of EntityId (e.g., 'component', 'entity-relation')\n */\ndeclare const __entityIdTypeTag: unique symbol;\n\n/**\n * Entity ID type for ECS architecture\n * Based on 52-bit integers within safe integer range\n * - Component IDs: 1-1023\n * - Entity IDs: 1024+\n * - Relation IDs: negative numbers encoding component and entity associations\n */\nexport type EntityId<T = void, U = unknown> = number & {\n readonly [__componentTypeMarker]: T;\n readonly [__entityIdTypeTag]: U;\n};\n\nexport type ComponentId<T = void> = EntityId<T, \"component\">;\nexport type EntityRelationId<T = void> = EntityId<T, \"entity-relation\">;\nexport type ComponentRelationId<T = void> = EntityId<T, \"component-relation\">;\nexport type WildcardRelationId<T = void> = EntityId<T, \"wildcard-relation\">;\nexport type RelationId<T = void> = EntityRelationId<T> | ComponentRelationId<T> | WildcardRelationId<T>;\n\n/**\n * Constants for ID ranges\n */\nexport const INVALID_COMPONENT_ID = 0;\nexport const COMPONENT_ID_MAX = 1023;\nexport const ENTITY_ID_START = 1024;\n\n/**\n * Constants for relation ID encoding\n */\nexport const RELATION_SHIFT = 2 ** 42;\nexport const WILDCARD_TARGET_ID = 0;\n\n/**\n * Create a component ID\n * @param id Component identifier (1-1023)\n * @internal This function is for internal use and testing only. Use `component()` to create components.\n * @see component\n */\nexport function createComponentId<T = void>(id: number): ComponentId<T> {\n if (id < 1 || id > COMPONENT_ID_MAX) {\n throw new Error(`Component ID must be between 1 and ${COMPONENT_ID_MAX}`);\n }\n return id as ComponentId<T>;\n}\n\n/**\n * Create an entity ID\n * @param id Entity identifier (starting from 1024)\n */\nexport function createEntityId(id: number): EntityId {\n if (id < ENTITY_ID_START) {\n throw new Error(`Entity ID must be ${ENTITY_ID_START} or greater`);\n }\n return id as EntityId;\n}\n\n/**\n * Type for relation ID based on component and target types\n */\ntype RelationIdType<T, R> =\n R extends ComponentId<infer U>\n ? U extends void\n ? ComponentRelationId<T>\n : ComponentRelationId<T extends void ? U : T>\n : R extends EntityId<any>\n ? EntityRelationId<T>\n : never;\n\n/**\n * Create a relation ID by associating a component with another ID (entity or component)\n * @param componentId The component ID (0-1023)\n * @param targetId The target ID (entity, component, or '*' for wildcard)\n */\nexport function relation<T>(componentId: ComponentId<T>, targetId: \"*\"): WildcardRelationId<T>;\nexport function relation<T, R extends EntityId<any>>(componentId: ComponentId<T>, targetId: R): RelationIdType<T, R>;\nexport function relation<T>(componentId: ComponentId<T>, targetId: EntityId<any> | \"*\"): EntityId<any> {\n if (!isComponentId(componentId)) {\n throw new Error(\"First argument must be a valid component ID\");\n }\n\n let actualTargetId: number;\n if (targetId === \"*\") {\n actualTargetId = WILDCARD_TARGET_ID;\n } else {\n if (!isEntityId(targetId) && !isComponentId(targetId)) {\n throw new Error(\"Second argument must be a valid entity ID, component ID, or '*'\");\n }\n actualTargetId = targetId;\n }\n\n // Encode: negative number with component_id * 2^42 + target_id\n return -(componentId * RELATION_SHIFT + actualTargetId) as EntityId<any>;\n}\n\n/**\n * Check if an ID is a component ID\n */\nexport function isComponentId<T>(id: EntityId<T>): id is ComponentId<T> {\n return id >= 1 && id <= COMPONENT_ID_MAX;\n}\n\n/**\n * Check if an ID is an entity ID\n */\nexport function isEntityId<T>(id: EntityId<T>): id is EntityId<T> {\n return id >= ENTITY_ID_START;\n}\n\n/**\n * Check if an ID is a relation ID\n */\nexport function isRelationId<T>(id: EntityId<T>): id is RelationId<T> {\n return id < 0;\n}\n\n/**\n * Check if an ID is a wildcard relation id\n */\nexport function isWildcardRelationId<T>(id: EntityId<T>): id is WildcardRelationId<T> {\n if (!isRelationId(id)) {\n return false;\n }\n const absId = -id;\n const targetId = absId % RELATION_SHIFT;\n return targetId === WILDCARD_TARGET_ID;\n}\n\n/**\n * Decode a relation ID into component and target IDs\n * @param relationId The relation ID (must be negative)\n * @returns Object with componentId, targetId, and relation type\n */\nexport function decodeRelationId(relationId: RelationId<any>): {\n componentId: ComponentId<any>;\n targetId: EntityId<any>;\n type: \"entity\" | \"component\" | \"wildcard\";\n} {\n if (!isRelationId(relationId)) {\n throw new Error(\"ID is not a relation ID\");\n }\n const absId = -relationId;\n\n const componentId = Math.floor(absId / RELATION_SHIFT) as ComponentId<any>;\n const targetId = (absId % RELATION_SHIFT) as EntityId<any>;\n\n // Determine type based on targetId range\n if (targetId === WILDCARD_TARGET_ID) {\n return { componentId, targetId, type: \"wildcard\" };\n } else if (isEntityId(targetId)) {\n return { componentId, targetId, type: \"entity\" };\n } else if (isComponentId(targetId)) {\n return { componentId, targetId, type: \"component\" };\n } else {\n throw new Error(\"Invalid target ID in relation\");\n }\n}\n\n/**\n * Get the string representation of an ID type\n */\nexport function getIdType(\n id: EntityId<any>,\n): \"component\" | \"entity\" | \"entity-relation\" | \"component-relation\" | \"wildcard-relation\" | \"invalid\" {\n if (isComponentId(id)) return \"component\";\n if (isEntityId(id)) return \"entity\";\n\n if (isRelationId(id)) {\n try {\n const decoded = decodeRelationId(id);\n // Validate that componentId and targetId are valid\n if (\n !isComponentId(decoded.componentId) ||\n (decoded.type !== \"wildcard\" && !isEntityId(decoded.targetId) && !isComponentId(decoded.targetId))\n ) {\n return \"invalid\";\n }\n switch (decoded.type) {\n case \"entity\":\n return \"entity-relation\";\n case \"component\":\n return \"component-relation\";\n case \"wildcard\":\n return \"wildcard-relation\";\n }\n } catch (error) {\n return \"invalid\"; // fallback for invalid relation IDs\n }\n }\n\n return \"invalid\"; // fallback for unknown/invalid IDs\n}\n\n/**\n * Get detailed type information for an EntityId\n * @param id The EntityId to analyze\n * @returns Detailed type information including relation subtypes\n */\nexport function getDetailedIdType(id: EntityId<any>):\n | {\n type: \"component\" | \"entity\" | \"invalid\";\n componentId?: never;\n targetId?: never;\n }\n | {\n type: \"entity-relation\" | \"wildcard-relation\";\n componentId: ComponentId<any>;\n targetId: EntityId<any>;\n }\n | {\n type: \"component-relation\";\n componentId: ComponentId<any>;\n targetId: ComponentId<any>;\n } {\n if (isComponentId(id)) {\n return { type: \"component\" };\n }\n\n if (isEntityId(id)) {\n return { type: \"entity\" };\n }\n\n if (isRelationId(id)) {\n try {\n const decoded = decodeRelationId(id);\n // Validate that componentId and targetId are valid\n if (\n !isComponentId(decoded.componentId) ||\n (decoded.type !== \"wildcard\" && !isEntityId(decoded.targetId) && !isComponentId(decoded.targetId))\n ) {\n return { type: \"invalid\" };\n }\n let type: \"entity-relation\" | \"component-relation\" | \"wildcard-relation\";\n\n switch (decoded.type) {\n case \"entity\":\n type = \"entity-relation\";\n break;\n case \"component\":\n type = \"component-relation\";\n break;\n case \"wildcard\":\n type = \"wildcard-relation\";\n break;\n }\n\n return {\n type,\n componentId: decoded.componentId,\n targetId: decoded.targetId as any,\n };\n } catch (error) {\n // Invalid relation ID\n return { type: \"invalid\" };\n }\n }\n\n // Unknown/invalid ID\n return { type: \"invalid\" };\n}\n\n/**\n * Inspect an EntityId and return a human-readable string representation\n * @param id The EntityId to inspect\n * @returns A friendly string representation of the ID\n */\nexport function inspectEntityId(id: EntityId<any>): string {\n if (id === INVALID_COMPONENT_ID) {\n return \"Invalid Component ID (0)\";\n }\n\n if (isComponentId(id)) {\n return `Component ID (${id})`;\n }\n\n if (isEntityId(id)) {\n return `Entity ID (${id})`;\n }\n\n if (isRelationId(id)) {\n try {\n const decoded = decodeRelationId(id);\n // Validate that both component and target IDs are valid\n if (\n !isComponentId(decoded.componentId) ||\n (decoded.type !== \"wildcard\" && !isEntityId(decoded.targetId) && !isComponentId(decoded.targetId))\n ) {\n return `Invalid Relation ID (${id})`;\n }\n const componentStr = `Component ID (${decoded.componentId})`;\n const targetStr =\n decoded.type === \"entity\"\n ? `Entity ID (${decoded.targetId})`\n : decoded.type === \"component\"\n ? `Component ID (${decoded.targetId})`\n : \"Wildcard (*)\";\n return `Relation ID: ${componentStr} -> ${targetStr}`;\n } catch (error) {\n return `Invalid Relation ID (${id})`;\n }\n }\n\n return `Unknown ID (${id})`;\n}\n\n/**\n * Entity ID Manager for automatic allocation and freelist recycling\n */\nexport class EntityIdManager {\n private nextId: number = ENTITY_ID_START;\n private freelist: Set<EntityId> = new Set();\n\n /**\n * Allocate a new entity ID\n * Uses freelist if available, otherwise increments counter\n */\n allocate(): EntityId {\n if (this.freelist.size > 0) {\n const id = this.freelist.values().next().value!;\n this.freelist.delete(id);\n return id;\n } else {\n const id = this.nextId;\n this.nextId++;\n // Check for overflow (though unlikely in practice)\n if (this.nextId >= Number.MAX_SAFE_INTEGER) {\n throw new Error(\"Entity ID overflow: reached maximum safe integer\");\n }\n return id as EntityId;\n }\n }\n\n /**\n * Deallocate an entity ID, adding it to the freelist for reuse\n * @param id The entity ID to deallocate\n */\n deallocate(id: EntityId<any>): void {\n if (!isEntityId(id)) {\n throw new Error(\"Can only deallocate valid entity IDs\");\n }\n if (id >= this.nextId) {\n throw new Error(\"Cannot deallocate an ID that was never allocated\");\n }\n this.freelist.add(id);\n }\n\n /**\n * Get the current freelist size (for debugging/monitoring)\n */\n getFreelistSize(): number {\n return this.freelist.size;\n }\n\n /**\n * Get the next ID that would be allocated (for debugging)\n */\n getNextId(): number {\n return this.nextId;\n }\n\n /**\n * Serialize internal state for persistence.\n * Returns a plain object representing allocator state. Values may be non-JSON-serializable.\n */\n serializeState(): { nextId: number; freelist: number[] } {\n return { nextId: this.nextId, freelist: Array.from(this.freelist) };\n }\n\n /**\n * Restore internal state from a previously-serialized object.\n * Overwrites the current nextId and freelist.\n */\n deserializeState(state: { nextId: number; freelist?: number[] }): void {\n if (typeof state.nextId !== \"number\") {\n throw new Error(\"Invalid state for EntityIdManager.deserializeState\");\n }\n this.nextId = state.nextId;\n this.freelist = new Set((state.freelist || []) as EntityId[]);\n }\n}\n\n/**\n * Component ID Manager for automatic allocation\n * Components are typically registered once and not recycled\n */\nexport class ComponentIdAllocator {\n private nextId: number = 1;\n\n /**\n * Allocate a new component ID\n * Increments counter sequentially from 1\n */\n allocate<T = void>(): ComponentId<T> {\n if (this.nextId > COMPONENT_ID_MAX) {\n throw new Error(`Component ID overflow: maximum ${COMPONENT_ID_MAX} components allowed`);\n }\n const id = this.nextId;\n this.nextId++;\n return id as ComponentId<T>;\n }\n\n /**\n * Get the next ID that would be allocated (for debugging)\n */\n getNextId(): number {\n return this.nextId;\n }\n\n /**\n * Check if more component IDs are available\n */\n hasAvailableIds(): boolean {\n return this.nextId <= COMPONENT_ID_MAX;\n }\n}\n\nconst globalComponentIdAllocator = new ComponentIdAllocator();\n\nconst ComponentNames: Map<ComponentId<any>, string> = new Map();\nconst ComponentIdForNames: Map<string, ComponentId<any>> = new Map();\n\n/**\n * Component options that define intrinsic properties\n */\nexport interface ComponentOptions {\n /**\n * Optional name for the component (for serialization/debugging)\n */\n name?: string;\n /**\n * If true, an entity can have at most one relation per base component.\n * When adding a new relation with the same base component, any existing relations\n * with that base component are automatically removed.\n * Only applicable to relation components.\n */\n exclusive?: boolean;\n /**\n * If true, when a relation target entity is deleted, all entities that reference\n * it through this component will also be deleted (cascade delete).\n * Only applicable to entity-relation components.\n */\n cascadeDelete?: boolean;\n /**\n * If true, relations with this component will not cause archetype fragmentation.\n * Entities with different target entities for this relation component will be stored\n * in the same archetype, preventing fragmentation when there are many different targets.\n * Only applicable to relation components.\n * Inspired by Flecs' DontFragment trait.\n */\n dontFragment?: boolean;\n}\n\nconst ComponentOptions: Map<ComponentId<any>, ComponentOptions> = new Map();\n\n/**\n * Allocate a new component ID from the global allocator.\n * @param nameOrOptions Optional name for the component (for serialization/debugging) or options object\n * @returns The allocated component ID\n * @example\n * // Just a name\n * const Position = component<Position>(\"Position\");\n *\n * // With options\n * const ChildOf = component({ exclusive: true, cascadeDelete: true });\n *\n * // With name and options\n * const ChildOf = component({ name: \"ChildOf\", exclusive: true });\n */\nexport function component<T = void>(nameOrOptions?: string | ComponentOptions): ComponentId<T> {\n const id = globalComponentIdAllocator.allocate<T>();\n\n let name: string | undefined;\n let options: ComponentOptions | undefined;\n\n // Parse the parameter\n if (typeof nameOrOptions === \"string\") {\n name = nameOrOptions;\n } else if (typeof nameOrOptions === \"object\" && nameOrOptions !== null) {\n options = nameOrOptions;\n name = options.name;\n }\n\n // Register name if provided\n if (name) {\n if (ComponentIdForNames.has(name)) {\n throw new Error(`Component name \"${name}\" is already registered`);\n }\n\n ComponentNames.set(id, name);\n ComponentIdForNames.set(name, id);\n }\n\n // Register options if provided\n if (options) {\n ComponentOptions.set(id, options);\n }\n\n return id;\n}\n\n/**\n * Get a component ID by its registered name\n * @param name The component name\n * @returns The component ID if found, undefined otherwise\n */\nexport function getComponentIdByName(name: string): ComponentId<any> | undefined {\n return ComponentIdForNames.get(name);\n}\n\n/** Get a component name by its ID\n * @param id The component ID\n * @returns The component name if found, undefined otherwise\n */\nexport function getComponentNameById(id: ComponentId<any>): string | undefined {\n return ComponentNames.get(id);\n}\n\n/**\n * Get component options by its ID\n * @param id The component ID\n * @returns The component options if found, undefined otherwise\n */\nexport function getComponentOptions(id: ComponentId<any>): ComponentOptions | undefined {\n return ComponentOptions.get(id);\n}\n\n/**\n * Check if a component is marked as exclusive\n * @param id The component ID\n * @returns true if the component is exclusive, false otherwise\n */\nexport function isExclusiveComponent(id: ComponentId<any>): boolean {\n return ComponentOptions.get(id)?.exclusive ?? false;\n}\n\n/**\n * Check if a component is marked as cascade delete\n * @param id The component ID\n * @returns true if the component is cascade delete, false otherwise\n */\nexport function isCascadeDeleteComponent(id: ComponentId<any>): boolean {\n return ComponentOptions.get(id)?.cascadeDelete ?? false;\n}\n\n/**\n * Check if a component is marked as dontFragment\n * @param id The component ID\n * @returns true if the component is dontFragment, false otherwise\n */\nexport function isDontFragmentComponent(id: ComponentId<any>): boolean {\n return ComponentOptions.get(id)?.dontFragment ?? false;\n}\n","import type { EntityId, WildcardRelationId } from \"./entity\";\n\n/**\n * Hook types for component lifecycle events\n */\nexport interface LifecycleHook<T = unknown> {\n /**\n * Called when a component is added to an entity\n */\n on_init?: (entityId: EntityId, componentType: EntityId<T>, component: T) => void;\n /**\n * Called when a component is added to an entity\n */\n on_set?: (entityId: EntityId, componentType: EntityId<T>, component: T) => void;\n /**\n * Called when a component is deleted from an entity\n */\n on_remove?: (entityId: EntityId, componentType: EntityId<T>, component: T) => void;\n}\n\nexport type ComponentType<T> = EntityId<T> | OptionalEntityId<T>;\n\nexport type OptionalEntityId<T> = { optional: EntityId<T> };\n\nexport function isOptionalEntityId<T>(type: ComponentType<T>): type is OptionalEntityId<T> {\n return typeof type === \"object\" && type !== null && \"optional\" in type;\n}\n\nexport type ComponentTypeToData<T> = T extends { optional: infer U }\n ? { value: ComponentTypeToData<U> } | undefined\n : T extends WildcardRelationId<infer U>\n ? [EntityId<unknown>, U][]\n : T extends EntityId<infer U>\n ? U\n : never;\n\n/**\n * Type helper for component tuples extracted from EntityId array\n */\nexport type ComponentTuple<T extends readonly ComponentType<any>[]> = {\n readonly [K in keyof T]: ComponentTypeToData<T[K]>;\n};\n","/**\n * Utility functions for ECS library\n */\n\n/**\n * Get a value from cache or compute and cache it if not present\n * @param cache The cache map\n * @param key The cache key\n * @param compute Function to compute the value if not cached\n * @returns The cached or computed value\n */\nexport function getOrComputeCache<K, V>(cache: Map<K, V>, key: K, compute: () => V): V {\n let value = cache.get(key);\n if (value === undefined) {\n value = compute();\n cache.set(key, value);\n }\n return value;\n}\n\n/**\n * Get a value from cache or create and cache it if not present, allowing side effects during creation\n * @param cache The cache map\n * @param key The cache key\n * @param create Function to create the value if not cached (can have side effects)\n * @returns The cached or created value\n */\nexport function getOrCreateWithSideEffect<K, V>(cache: Map<K, V>, key: K, create: () => V): V {\n let value = cache.get(key);\n if (value === undefined) {\n value = create();\n cache.set(key, value);\n }\n return value;\n}\n","import type { EntityId, RelationId, WildcardRelationId } from \"./entity\";\nimport {\n decodeRelationId,\n getDetailedIdType,\n getIdType,\n isDontFragmentComponent,\n isWildcardRelationId,\n} from \"./entity\";\nimport { isOptionalEntityId, type ComponentTuple, type ComponentType } from \"./types\";\nimport { getOrComputeCache } from \"./utils\";\n\n/**\n * Special value to represent missing component data\n */\nexport const MISSING_COMPONENT = Symbol(\"missing component\");\n\n/**\n * Archetype class for ECS architecture\n * Represents a group of entities that share the same set of components\n * Optimized for fast iteration and component access\n */\nexport class Archetype {\n /**\n * The component types that define this archetype\n */\n public readonly componentTypes: EntityId<any>[];\n\n /**\n * List of entities in this archetype\n */\n private entities: EntityId[] = [];\n\n /**\n * Component data storage - maps component type to array of component data\n * Each array index corresponds to the entity index in the entities array\n */\n private componentData: Map<EntityId<any>, any[]> = new Map();\n\n /**\n * Reverse mapping from entity to its index in this archetype\n */\n private entityToIndex: Map<EntityId, number> = new Map();\n\n /**\n * Reference to dontFragment relations storage from World\n * This allows entities with different relation targets to share the same archetype\n * Stored in World to avoid migration overhead when entities change archetypes\n */\n private dontFragmentRelations: Map<EntityId, Map<EntityId<any>, any>>;\n\n /**\n * Cache for pre-computed component data sources to avoid repeated calculations\n * For regular components: data array\n * For wildcards: matching relation types array\n */\n private componentDataSourcesCache: Map<string, (any[] | EntityId<any>[] | undefined)[]> = new Map();\n\n /**\n * Create a new archetype with the specified component types\n * @param componentTypes The component types that define this archetype\n * @param dontFragmentRelations Reference to the World's dontFragmentRelations storage\n */\n constructor(componentTypes: EntityId<any>[], dontFragmentRelations: Map<EntityId, Map<EntityId<any>, any>>) {\n this.componentTypes = [...componentTypes].sort((a, b) => a - b); // Sort for consistent ordering\n this.dontFragmentRelations = dontFragmentRelations;\n\n // Initialize component data arrays\n for (const componentType of this.componentTypes) {\n this.componentData.set(componentType, []);\n }\n }\n\n /**\n * Get the number of entities in this archetype\n */\n get size(): number {\n return this.entities.length;\n }\n\n /**\n * Check if this archetype matches the given component types\n * @param componentTypes The component types to check\n */\n matches(componentTypes: EntityId<any>[]): boolean {\n if (this.componentTypes.length !== componentTypes.length) {\n return false;\n }\n const sortedTypes = [...componentTypes].sort((a, b) => a - b);\n return this.componentTypes.every((type, index) => type === sortedTypes[index]);\n }\n\n /**\n * Add an entity to this archetype with initial component data\n * @param entityId The entity to add\n * @param componentData Map of component type to component data (includes both regular and dontFragment components)\n */\n addEntity(entityId: EntityId, componentData: Map<EntityId<any>, any>): void {\n if (this.entityToIndex.has(entityId)) {\n throw new Error(`Entity ${entityId} is already in this archetype`);\n }\n\n const index = this.entities.length;\n this.entities.push(entityId);\n this.entityToIndex.set(entityId, index);\n\n // Add component data for regular components (those in the archetype signature)\n for (const componentType of this.componentTypes) {\n const data = componentData.get(componentType);\n this.getComponentData(componentType).push(data === undefined ? MISSING_COMPONENT : data);\n }\n\n // Add dontFragment relations separately\n const dontFragmentData = new Map<EntityId<any>, any>();\n for (const [componentType, data] of componentData) {\n // Skip if already added as regular component\n if (this.componentTypes.includes(componentType)) {\n continue;\n }\n\n // Check if this is a dontFragment relation\n const detailedType = getDetailedIdType(componentType);\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isDontFragmentComponent(detailedType.componentId!)\n ) {\n dontFragmentData.set(componentType, data);\n }\n }\n\n if (dontFragmentData.size > 0) {\n this.dontFragmentRelations.set(entityId, dontFragmentData);\n }\n }\n\n /**\n * Get all component data for a specific entity\n * @param entityId The entity to get data for\n * @returns Map of component type to component data (includes both regular and dontFragment components)\n */\n getEntity(entityId: EntityId): Map<EntityId<any>, any> | undefined {\n const index = this.entityToIndex.get(entityId);\n if (index === undefined) {\n return undefined;\n }\n\n const entityData = new Map<EntityId<any>, any>();\n for (const componentType of this.componentTypes) {\n const dataArray = this.getComponentData(componentType);\n const data = dataArray[index];\n entityData.set(componentType, data === MISSING_COMPONENT ? undefined : data);\n }\n\n // Add dontFragment relations\n const dontFragmentData = this.dontFragmentRelations.get(entityId);\n if (dontFragmentData) {\n for (const [componentType, data] of dontFragmentData) {\n entityData.set(componentType, data);\n }\n }\n\n return entityData;\n }\n\n /**\n * Dump all entities and their component data in this archetype\n * @returns Array of objects with entity and component data (includes both regular and dontFragment components)\n */\n dump(): Array<{\n entity: EntityId;\n components: Map<EntityId<any>, any>;\n }> {\n const result: Array<{\n entity: EntityId;\n components: Map<EntityId<any>, any>;\n }> = [];\n\n for (let i = 0; i < this.entities.length; i++) {\n const entity = this.entities[i]!;\n const components = new Map<EntityId<any>, any>();\n for (const componentType of this.componentTypes) {\n const dataArray = this.getComponentData(componentType);\n const data = dataArray[i];\n components.set(componentType, data === MISSING_COMPONENT ? undefined : data);\n }\n\n // Add dontFragment relations\n const dontFragmentData = this.dontFragmentRelations.get(entity);\n if (dontFragmentData) {\n for (const [componentType, data] of dontFragmentData) {\n components.set(componentType, data);\n }\n }\n\n result.push({ entity, components });\n }\n\n return result;\n }\n\n /**\n * Remove an entity from this archetype\n * @param entityId The entity to remove\n * @returns The component data of the removed entity (includes both regular and dontFragment components)\n */\n removeEntity(entityId: EntityId): Map<EntityId<any>, any> | undefined {\n const index = this.entityToIndex.get(entityId);\n if (index === undefined) {\n return undefined;\n }\n\n // Extract component data before removal\n const removedData = new Map<EntityId<any>, any>();\n for (const componentType of this.componentTypes) {\n const dataArray = this.getComponentData(componentType);\n removedData.set(componentType, dataArray[index]);\n }\n\n // Include dontFragment relations in removed data\n const dontFragmentData = this.dontFragmentRelations.get(entityId);\n if (dontFragmentData) {\n for (const [componentType, data] of dontFragmentData) {\n removedData.set(componentType, data);\n }\n this.dontFragmentRelations.delete(entityId);\n }\n\n this.entityToIndex.delete(entityId);\n\n // Use swap-and-pop strategy for O(1) removal instead of O(n) splice\n const lastIndex = this.entities.length - 1;\n if (index !== lastIndex) {\n // Swap with last entity\n const lastEntity = this.entities[lastIndex]!;\n this.entities[index] = lastEntity;\n this.entityToIndex.set(lastEntity, index);\n\n // Swap component data for all components\n for (const componentType of this.componentTypes) {\n const dataArray = this.getComponentData(componentType);\n dataArray[index] = dataArray[lastIndex];\n }\n }\n\n // Remove the last element (now O(1))\n this.entities.pop();\n for (const componentType of this.componentTypes) {\n this.getComponentData(componentType).pop();\n }\n\n return removedData;\n }\n\n /**\n * Check if an entity is in this archetype\n * @param entityId The entity to check\n */\n exists(entityId: EntityId): boolean {\n return this.entityToIndex.has(entityId);\n }\n\n /**\n * Get component data for a specific entity and wildcard relation type\n * Returns an array of all matching relation instances\n * @param entityId The entity\n * @param componentType The wildcard relation type\n */\n get<T>(entityId: EntityId, componentType: WildcardRelationId<T>): [EntityId<unknown>, any][];\n /**\n * Get component data for a specific entity and component type\n * @param entityId The entity\n * @param componentType The component type\n */\n get<T>(entityId: EntityId, componentType: EntityId<T>): T;\n get<T>(entityId: EntityId, componentType: EntityId<T> | WildcardRelationId<T>): T | [EntityId<unknown>, any][] {\n const index = this.entityToIndex.get(entityId);\n if (index === undefined) {\n throw new Error(`Entity ${entityId} is not in this archetype`);\n }\n\n if (isWildcardRelationId(componentType)) {\n const decoded = decodeRelationId(componentType);\n const componentId = decoded.componentId;\n const relations: [EntityId<unknown>, any][] = [];\n\n // Check regular archetype components\n for (const relType of this.componentTypes) {\n const relDetailed = getDetailedIdType(relType);\n if (\n (relDetailed.type === \"entity-relation\" || relDetailed.type === \"component-relation\") &&\n relDetailed.componentId === componentId\n ) {\n const dataArray = this.getComponentData(relType);\n if (dataArray && dataArray[index] !== undefined) {\n const data = dataArray[index];\n relations.push([relDetailed.targetId, data === MISSING_COMPONENT ? undefined : data]);\n }\n }\n }\n\n // Check dontFragment relations\n const dontFragmentData = this.dontFragmentRelations.get(entityId);\n if (dontFragmentData) {\n for (const [relType, data] of dontFragmentData) {\n const relDetailed = getDetailedIdType(relType);\n if (\n (relDetailed.type === \"entity-relation\" || relDetailed.type === \"component-relation\") &&\n relDetailed.componentId === componentId\n ) {\n relations.push([relDetailed.targetId, data]);\n }\n }\n }\n\n return relations;\n } else {\n // First check if it's in the archetype signature\n if (this.componentTypes.includes(componentType)) {\n const data = this.getComponentData(componentType)[index]!;\n return data === MISSING_COMPONENT ? (undefined as T) : data;\n }\n\n // Check dontFragment relations\n const dontFragmentData = this.dontFragmentRelations.get(entityId);\n if (dontFragmentData && dontFragmentData.has(componentType)) {\n return dontFragmentData.get(componentType);\n }\n\n throw new Error(`Component type ${componentType} not found for entity ${entityId}`);\n }\n }\n\n /**\n * Set component data for a specific entity and component type\n * @param entityId The entity\n * @param componentType The component type\n * @param data The component data\n */\n set<T>(entityId: EntityId, componentType: EntityId<T>, data: T): void {\n const index = this.entityToIndex.get(entityId);\n if (index === undefined) {\n throw new Error(`Entity ${entityId} is not in this archetype`);\n }\n\n // Check if it's in the archetype signature\n if (this.componentData.has(componentType)) {\n const dataArray = this.getComponentData(componentType);\n dataArray[index] = data;\n return;\n }\n\n // Check if it's a dontFragment relation\n const detailedType = getDetailedIdType(componentType);\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isDontFragmentComponent(detailedType.componentId!)\n ) {\n let dontFragmentData = this.dontFragmentRelations.get(entityId);\n if (!dontFragmentData) {\n dontFragmentData = new Map();\n this.dontFragmentRelations.set(entityId, dontFragmentData);\n }\n dontFragmentData.set(componentType, data);\n return;\n }\n\n throw new Error(`Component type ${componentType} is not in this archetype`);\n }\n\n /**\n * Get all entities in this archetype\n */\n getEntities(): EntityId[] {\n return this.entities;\n }\n\n /**\n * Get the mapping of entities to their indices in this archetype\n */\n getEntityToIndexMap(): Map<EntityId, number> {\n return this.entityToIndex;\n }\n\n /**\n * Get component data for all entities of a specific component type\n * @param componentType The component type\n */\n getComponentData<T>(componentType: EntityId<T>): T[] {\n const data = this.componentData.get(componentType);\n if (!data) {\n throw new Error(`Component type ${componentType} is not in this archetype`);\n }\n return data;\n }\n\n /**\n * Get optional component data for all entities of a specific component type\n * @param componentType The component type\n * @returns An array of component data or undefined if not present\n */\n getOptionalComponentData<T>(componentType: EntityId<T>): T[] | undefined {\n return this.componentData.get(componentType);\n }\n\n /**\n * Helper: compute or return cached data sources for provided componentTypes\n */\n private getCachedComponentDataSources<const T extends readonly ComponentType<any>[]>(\n componentTypes: T,\n ): (any[] | EntityId<any>[] | undefined)[] {\n const cacheKey = this.buildCacheKey(componentTypes);\n return getOrComputeCache(this.componentDataSourcesCache, cacheKey, () =>\n componentTypes.map((compType) => this.getComponentDataSource(compType)),\n );\n }\n\n /**\n * Build cache key for component types\n */\n private buildCacheKey(componentTypes: readonly ComponentType<any>[]): string {\n return componentTypes.map((id) => (isOptionalEntityId(id) ? `opt(${id.optional})` : `${id}`)).join(\",\");\n }\n\n /**\n * Get data source for a single component type\n */\n private getComponentDataSource(compType: ComponentType<any>): any[] | EntityId<any>[] | undefined {\n const optional = isOptionalEntityId(compType);\n const actualType = optional ? compType.optional : compType;\n const detailedType = getDetailedIdType(actualType);\n\n if (detailedType.type === \"wildcard-relation\") {\n return this.getWildcardRelationDataSource(detailedType.componentId, optional);\n } else {\n return optional ? this.getOptionalComponentData(actualType) : this.getComponentData(actualType);\n }\n }\n\n /**\n * Get data source for wildcard relations\n */\n private getWildcardRelationDataSource(componentId: EntityId<any>, optional: boolean): EntityId<any>[] | undefined {\n const matchingRelations = this.componentTypes.filter((ct) => {\n const detailedCt = getDetailedIdType(ct);\n return (\n (detailedCt.type === \"entity-relation\" || detailedCt.type === \"component-relation\") &&\n detailedCt.componentId === componentId\n );\n });\n\n return optional ? (matchingRelations.length > 0 ? matchingRelations : undefined) : matchingRelations;\n }\n\n /**\n * Helper: build component tuples for a specific entity index using precomputed data sources\n */\n private buildComponentsForIndex<const T extends readonly ComponentType<any>[]>(\n componentTypes: T,\n componentDataSources: (any[] | EntityId<any>[] | undefined)[],\n entityIndex: number,\n entityId: EntityId,\n ): ComponentTuple<T> {\n return componentDataSources.map((dataSource, i) => {\n const compType = componentTypes[i]!;\n return this.buildSingleComponent(compType, dataSource, entityIndex, entityId);\n }) as ComponentTuple<T>;\n }\n\n /**\n * Build a single component value from its data source\n */\n private buildSingleComponent(\n compType: ComponentType<any>,\n dataSource: any[] | EntityId<any>[] | undefined,\n entityIndex: number,\n entityId: EntityId,\n ): any {\n const optional = isOptionalEntityId(compType);\n const actualType = optional ? compType.optional : compType;\n\n if (getIdType(actualType) === \"wildcard-relation\") {\n return this.buildWildcardRelationValue(\n actualType as WildcardRelationId<any>,\n dataSource,\n entityIndex,\n entityId,\n optional,\n );\n } else {\n return this.buildRegularComponentValue(dataSource, entityIndex, optional);\n }\n }\n\n /**\n * Build wildcard relation value from matching relations\n */\n private buildWildcardRelationValue(\n wildcardRelationType: WildcardRelationId<any>,\n dataSource: any[] | EntityId<any>[] | undefined,\n entityIndex: number,\n entityId: EntityId,\n optional: boolean,\n ): any {\n const matchingRelations = (dataSource as EntityId<any>[]) || [];\n const relations: [EntityId<unknown>, any][] = [];\n\n // Add regular archetype relations\n for (const relType of matchingRelations) {\n const dataArray = this.getComponentData(relType);\n const data = dataArray[entityIndex];\n const decodedRel = decodeRelationId(relType as RelationId<any>);\n relations.push([decodedRel.targetId, data === MISSING_COMPONENT ? undefined : data]);\n }\n\n // Add dontFragment relations for this entity\n // Get the component ID from the wildcard relation type\n const wildcardDecoded = decodeRelationId(wildcardRelationType);\n const targetComponentId = wildcardDecoded.componentId;\n\n const dontFragmentData = this.dontFragmentRelations.get(entityId);\n if (dontFragmentData) {\n // Check dontFragment relations for matching component ID\n for (const [relType, data] of dontFragmentData) {\n const relDetailed = getDetailedIdType(relType);\n if (\n (relDetailed.type === \"entity-relation\" || relDetailed.type === \"component-relation\") &&\n relDetailed.componentId === targetComponentId\n ) {\n relations.push([relDetailed.targetId, data]);\n }\n }\n }\n\n // If no relations found and not optional, this entity doesn't match\n if (relations.length === 0) {\n if (!optional) {\n const wildcardDecoded = decodeRelationId(wildcardRelationType);\n throw new Error(\n `No matching relations found for mandatory wildcard relation component ${wildcardDecoded.componentId} on entity ${entityId}`,\n );\n }\n // For optional, return undefined when there are no relations\n return undefined;\n }\n\n return optional ? { value: relations } : relations;\n }\n\n /**\n * Build regular component value from data source\n */\n private buildRegularComponentValue(\n dataSource: any[] | EntityId<any>[] | undefined,\n entityIndex: number,\n optional: boolean,\n ): any {\n if (dataSource === undefined) {\n if (optional) {\n return undefined;\n }\n throw new Error(`Component data not found for mandatory component type`);\n }\n\n const dataArray = dataSource as any[];\n const data = dataArray[entityIndex];\n const result = data === MISSING_COMPONENT ? undefined : data;\n\n return optional ? { value: result } : result;\n }\n\n /**\n * Get entities with their component data for specified component types\n * Optimized for bulk component access with pre-computed indices\n * @param componentTypes Array of component types to retrieve\n * @returns Array of objects with entity and component data\n */\n getEntitiesWithComponents<const T extends readonly ComponentType<any>[]>(\n componentTypes: T,\n ): Array<{\n entity: EntityId;\n components: ComponentTuple<T>;\n }> {\n const result: Array<{\n entity: EntityId;\n components: ComponentTuple<T>;\n }> = [];\n\n this.forEachWithComponents(componentTypes, (entity, ...components) => {\n result.push({ entity, components });\n });\n\n return result;\n }\n\n /**\n * Iterate over entities with their component data for specified component types\n * implemented as a generator returning each entity/components pair lazily\n * @param componentTypes Array of component types to retrieve\n */\n *iterateWithComponents<const T extends readonly ComponentType<any>[]>(\n componentTypes: T,\n ): IterableIterator<[EntityId, ...ComponentTuple<T>]> {\n // Reuse the same pre-caching and data access logic as forEachWithComponents\n const componentDataSources = this.getCachedComponentDataSources(componentTypes);\n\n for (let entityIndex = 0; entityIndex < this.entities.length; entityIndex++) {\n const entity = this.entities[entityIndex]!;\n\n const components = this.buildComponentsForIndex(componentTypes, componentDataSources, entityIndex, entity);\n\n yield [entity, ...components];\n }\n }\n\n /**\n * Iterate over entities with their component data for specified component types\n * Optimized for bulk component access\n * @param componentTypes Array of component types to retrieve\n * @param callback Function called for each entity with its components\n */\n forEachWithComponents<const T extends readonly ComponentType<any>[]>(\n componentTypes: T,\n callback: (entity: EntityId, ...components: ComponentTuple<T>) => void,\n ): void {\n // Create a cache key from component types\n const componentDataSources = this.getCachedComponentDataSources(componentTypes);\n\n for (let entityIndex = 0; entityIndex < this.entities.length; entityIndex++) {\n const entity = this.entities[entityIndex]!;\n\n // Direct array access for each component type using pre-cached sources\n const components = this.buildComponentsForIndex(componentTypes, componentDataSources, entityIndex, entity);\n\n callback(entity, ...components);\n }\n }\n\n /**\n * Iterate over all entities with their component data\n * @param callback Function called for each entity with its component data\n */\n forEach(callback: (entityId: EntityId, components: Map<EntityId<any>, any>) => void): void {\n for (let i = 0; i < this.entities.length; i++) {\n const components = new Map<EntityId<any>, any>();\n for (const componentType of this.componentTypes) {\n const data = this.getComponentData(componentType)[i];\n components.set(componentType, data === MISSING_COMPONENT ? undefined : data);\n }\n callback(this.entities[i]!, components);\n }\n }\n\n /**\n * Check if any entity in this archetype has a relation matching the given component ID\n * This includes both regular relations in componentTypes and dontFragment relations\n * @param componentId The component ID to match\n * @returns true if any entity has a matching relation\n */\n hasRelationWithComponentId(componentId: EntityId<any>): boolean {\n // Check regular archetype components\n for (const componentType of this.componentTypes) {\n const detailedType = getDetailedIdType(componentType);\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n detailedType.componentId === componentId\n ) {\n return true;\n }\n }\n\n // Check dontFragment relations for any entity in this archetype\n for (const entityId of this.entities) {\n const entityDontFragmentRelations = this.dontFragmentRelations.get(entityId);\n if (entityDontFragmentRelations) {\n for (const relationType of entityDontFragmentRelations.keys()) {\n const detailedType = getDetailedIdType(relationType);\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n detailedType.componentId === componentId\n ) {\n return true;\n }\n }\n }\n }\n\n return false;\n }\n}\n","import type { EntityId } from \"./entity\";\n\n/**\n * @internal Represents a set of component changes to be applied to an entity\n */\nexport class ComponentChangeset {\n readonly adds = new Map<EntityId<any>, any>();\n readonly removes = new Set<EntityId<any>>();\n\n /**\n * Add a component to the changeset\n */\n set<T>(componentType: EntityId<T>, component: T): void {\n this.adds.set(componentType, component);\n this.removes.delete(componentType); // Remove from removes if it was going to be removed\n }\n\n /**\n * Remove a component from the changeset\n */\n delete<T>(componentType: EntityId<T>): void {\n this.removes.add(componentType);\n this.adds.delete(componentType); // Remove from adds if it was going to be added\n }\n\n /**\n * Check if the changeset has any changes\n */\n hasChanges(): boolean {\n return this.adds.size > 0 || this.removes.size > 0;\n }\n\n /**\n * Clear all changes\n */\n clear(): void {\n this.adds.clear();\n this.removes.clear();\n }\n\n /**\n * Merge another changeset into this one\n */\n merge(other: ComponentChangeset): void {\n // Merge additions\n for (const [componentType, component] of other.adds) {\n this.adds.set(componentType, component);\n this.removes.delete(componentType);\n }\n // Merge removals\n for (const componentType of other.removes) {\n this.removes.add(componentType);\n this.adds.delete(componentType);\n }\n }\n\n /**\n * Apply the changeset to existing components and return the final state\n */\n applyTo(existingComponents: Map<EntityId<any>, any>): Map<EntityId<any>, any> {\n // Apply removals\n for (const componentType of this.removes) {\n existingComponents.delete(componentType);\n }\n\n // Apply additions/updates\n for (const [componentType, component] of this.adds) {\n existingComponents.set(componentType, component);\n }\n\n return existingComponents;\n }\n\n /**\n * Get the final component types after applying the changeset\n * @param existingComponentTypes - The current component types on the entity\n * @returns The final component types or undefined if no changes\n */\n getFinalComponentTypes(existingComponentTypes: EntityId<any>[]): EntityId<any>[] | undefined {\n const finalComponentTypes = new Set<EntityId<any>>(existingComponentTypes);\n let changed = false;\n\n // Apply removals\n for (const componentType of this.removes) {\n if (!finalComponentTypes.has(componentType)) {\n this.removes.delete(componentType);\n continue; // Component not present, skip\n }\n changed = true;\n finalComponentTypes.delete(componentType);\n }\n\n // Apply additions\n for (const componentType of this.adds.keys()) {\n if (finalComponentTypes.has(componentType)) {\n continue; // Component already present, skip\n }\n changed = true;\n finalComponentTypes.add(componentType);\n }\n\n return changed ? Array.from(finalComponentTypes) : undefined;\n }\n}\n","import type { EntityId } from \"./entity\";\n\n/**\n * Command for deferred execution\n */\nexport interface Command {\n type: \"set\" | \"delete\" | \"destroy\";\n entityId: EntityId;\n componentType?: EntityId<any>;\n component?: any;\n}\n\n/**\n * Command buffer for deferred structural changes\n */\nexport class CommandBuffer {\n private commands: Command[] = [];\n private executeEntityCommands: (entityId: EntityId, commands: Command[]) => void;\n\n /**\n * Create a command buffer with an executor function\n */\n constructor(executeEntityCommands: (entityId: EntityId, commands: Command[]) => void) {\n this.executeEntityCommands = executeEntityCommands;\n }\n\n /**\n * Add a component to an entity (deferred)\n */\n set(entityId: EntityId, componentType: EntityId<void>): void;\n set<T>(entityId: EntityId, componentType: EntityId<T>, component: NoInfer<T>): void;\n set(entityId: EntityId, componentType: EntityId, component?: any): void {\n this.commands.push({ type: \"set\", entityId, componentType, component });\n }\n\n /**\n * Remove a component from an entity (deferred)\n */\n remove<T>(entityId: EntityId, componentType: EntityId<T>): void {\n this.commands.push({ type: \"delete\", entityId, componentType });\n }\n\n /**\n * Destroy an entity (deferred)\n */\n delete(entityId: EntityId): void {\n this.commands.push({ type: \"destroy\", entityId });\n }\n\n /**\n * Execute all commands and clear the buffer\n */\n execute(): void {\n const MAX_ITERATIONS = 100;\n let iterations = 0;\n\n while (this.commands.length > 0) {\n if (iterations >= MAX_ITERATIONS) {\n throw new Error(\"Command execution exceeded maximum iterations, possible infinite loop\");\n }\n iterations++;\n\n const currentCommands = [...this.commands];\n this.commands = [];\n\n // Group commands by entity\n const entityCommands = new Map<EntityId, Command[]>();\n for (const cmd of currentCommands) {\n if (!entityCommands.has(cmd.entityId)) {\n entityCommands.set(cmd.entityId, []);\n }\n entityCommands.get(cmd.entityId)!.push(cmd);\n }\n\n // Process each entity's commands with optimization\n for (const [entityId, commands] of entityCommands) {\n this.executeEntityCommands(entityId, commands);\n }\n }\n }\n\n /**\n * Get current commands (for testing)\n */\n getCommands(): Command[] {\n return [...this.commands];\n }\n\n /**\n * Clear all commands\n */\n clear(): void {\n this.commands = [];\n }\n}\n","// A lightweight generic MultiMap implementation backed by Map<K, Set<V>>.\n// Provides usual operations: add, remove, get, has, keys, values, entries,\n// clear, deleteKey and size accessors.\n\nclass MultiMap<K, V> {\n private map: Map<K, Set<V>> = new Map();\n\n // Number of value entries across all keys (not number of keys).\n private _valueCount = 0;\n\n get valueCount(): number {\n return this._valueCount;\n }\n\n get keyCount(): number {\n return this.map.size;\n }\n\n hasKey(key: K): boolean {\n return this.map.has(key);\n }\n\n has(key: K, value?: V): boolean {\n const set = this.map.get(key);\n if (!set) return false;\n if (arguments.length === 1) return true;\n return set.has(value as V);\n }\n\n add(key: K, value: V): void {\n let set = this.map.get(key);\n if (!set) {\n set = new Set();\n this.map.set(key, set);\n }\n if (!set.has(value)) {\n set.add(value);\n this._valueCount++;\n }\n }\n\n // Remove a specific value for a key. Returns true if removed.\n remove(key: K, value: V): boolean {\n const set = this.map.get(key);\n if (!set) return false;\n if (!set.has(value)) return false;\n set.delete(value);\n this._valueCount--;\n if (set.size === 0) this.map.delete(key);\n return true;\n }\n\n // Delete entire key and all its values. Returns true if key existed.\n deleteKey(key: K): boolean {\n const set = this.map.get(key);\n if (!set) return false;\n this._valueCount -= set.size;\n this.map.delete(key);\n return true;\n }\n\n get(key: K): Set<V> {\n const set = this.map.get(key);\n return set ? new Set(set) : new Set();\n }\n\n // iterate keys, values and entries (key -> Set copy)\n *keys(): IterableIterator<K> {\n yield* this.map.keys();\n }\n\n *values(): IterableIterator<V> {\n for (const set of this.map.values()) {\n for (const v of set) yield v;\n }\n }\n\n [Symbol.iterator](): IterableIterator<[K, V]> {\n return this.entries();\n }\n\n *entries(): IterableIterator<[K, V]> {\n for (const [k, set] of this.map.entries()) {\n for (const v of set) yield [k, v];\n }\n }\n\n clear(): void {\n this.map.clear();\n this._valueCount = 0;\n }\n}\n\nexport { MultiMap };\nexport type { MultiMap as MultiMapType };\n","import { Archetype } from \"./archetype\";\nimport type { EntityId } from \"./entity\";\nimport { decodeRelationId, getDetailedIdType, isRelationId } from \"./entity\";\n\n/**\n * Filter options for queries\n */\nexport interface QueryFilter {\n negativeComponentTypes?: EntityId<any>[];\n}\n\n/**\n * Serialize a QueryFilter into a deterministic string suitable for cache keys.\n * Currently only serializes `negativeComponentTypes`.\n */\nexport function serializeQueryFilter(filter: QueryFilter = {}): string {\n const negative = (filter.negativeComponentTypes || []).slice().sort((a, b) => a - b);\n if (negative.length === 0) return \"\";\n return `neg:${negative.join(\",\")}`;\n}\n\n/**\n * Check if an archetype matches the given component types\n */\nexport function matchesComponentTypes(archetype: Archetype, componentTypes: EntityId<any>[]): boolean {\n return componentTypes.every((type) => {\n const detailedType = getDetailedIdType(type);\n if (detailedType.type === \"wildcard-relation\") {\n // For wildcard relations, check if archetype contains the component relation\n return archetype.componentTypes.some((archetypeType) => {\n if (!isRelationId(archetypeType)) return false;\n const decoded = decodeRelationId(archetypeType);\n return decoded.componentId === detailedType.componentId;\n });\n } else {\n // For regular components, check direct inclusion\n return archetype.componentTypes.includes(type);\n }\n });\n}\n\n/**\n * Check if an archetype matches the filter conditions (only filtering logic)\n */\nexport function matchesFilter(archetype: Archetype, filter: QueryFilter): boolean {\n const negativeTypes = filter.negativeComponentTypes || [];\n return negativeTypes.every((type) => {\n const detailedType = getDetailedIdType(type);\n if (detailedType.type === \"wildcard-relation\") {\n // For wildcard relations in negative filter, exclude archetypes that contain ANY relation with the same component\n return !archetype.componentTypes.some((archetypeType) => {\n if (!isRelationId(archetypeType)) return false;\n const decoded = decodeRelationId(archetypeType);\n return decoded.componentId === detailedType.componentId;\n });\n } else {\n // For regular components, check direct exclusion\n return !archetype.componentTypes.includes(type);\n }\n });\n}\n","import { Archetype } from \"./archetype\";\nimport type { EntityId, WildcardRelationId } from \"./entity\";\nimport { getDetailedIdType } from \"./entity\";\nimport { matchesComponentTypes, matchesFilter, type QueryFilter } from \"./query-filter\";\nimport type { ComponentTuple, ComponentType } from \"./types\";\nimport type { World } from \"./world\";\n\n/**\n * Query class for efficient entity queries with cached archetypes\n */\nexport class Query {\n private world: World<any[]>;\n private componentTypes: EntityId<any>[];\n private filter: QueryFilter;\n private cachedArchetypes: Archetype[] = [];\n private isDisposed = false;\n\n constructor(world: World<any[]>, componentTypes: EntityId<any>[], filter: QueryFilter = {}) {\n this.world = world;\n this.componentTypes = [...componentTypes].sort((a, b) => a - b);\n this.filter = filter;\n this.updateCache();\n // Register with world for archetype updates\n world._registerQuery(this);\n }\n\n /**\n * Check if query is disposed and throw error if so\n */\n private ensureNotDisposed(): void {\n if (this.isDisposed) {\n throw new Error(\"Query has been disposed\");\n }\n }\n\n /**\n * Get all entities matching the query\n */\n getEntities(): EntityId[] {\n this.ensureNotDisposed();\n const result: EntityId[] = [];\n\n // Check if any component types are wildcard relations\n const hasWildcardRelations = this.componentTypes.some((ct) => {\n const detailed = getDetailedIdType(ct);\n return detailed.type === \"wildcard-relation\";\n });\n\n // If there are wildcard relations, we need to filter entities that actually have them\n // This is necessary for dontFragment components where an archetype can contain entities\n // with and without the relation\n if (hasWildcardRelations) {\n for (const archetype of this.cachedArchetypes) {\n for (const entity of archetype.getEntities()) {\n // Check if entity has all required wildcard relations\n let hasAllRelations = true;\n for (const componentType of this.componentTypes) {\n const detailed = getDetailedIdType(componentType);\n if (detailed.type === \"wildcard-relation\") {\n // Check if entity has at least one relation matching this wildcard\n const relations = archetype.get(entity, componentType as WildcardRelationId<any>);\n if (!relations || relations.length === 0) {\n hasAllRelations = false;\n break;\n }\n }\n }\n if (hasAllRelations) {\n result.push(entity);\n }\n }\n }\n } else {\n // No wildcard relations, can just return all entities from matching archetypes\n for (const archetype of this.cachedArchetypes) {\n result.push(...archetype.getEntities());\n }\n }\n\n return result;\n }\n\n /**\n * Get entities with their component data\n * @param componentTypes Array of component types to retrieve\n * @returns Array of objects with entity and component data\n */\n getEntitiesWithComponents<const T extends readonly ComponentType<any>[]>(\n componentTypes: T,\n ): Array<{\n entity: EntityId;\n components: ComponentTuple<T>;\n }> {\n this.ensureNotDisposed();\n\n const result: Array<{\n entity: EntityId;\n components: ComponentTuple<T>;\n }> = [];\n\n for (const archetype of this.cachedArchetypes) {\n const entitiesWithData = archetype.getEntitiesWithComponents(componentTypes);\n result.push(...entitiesWithData);\n }\n\n return result;\n }\n\n /**\n * Iterate over entities with their component data\n * @param componentTypes Array of component types to retrieve\n * @param callback Function called for each entity with its components\n */\n forEach<const T extends readonly ComponentType<any>[]>(\n componentTypes: T,\n callback: (entity: EntityId, ...components: ComponentTuple<T>) => void,\n ): void {\n this.ensureNotDisposed();\n\n for (const archetype of this.cachedArchetypes) {\n archetype.forEachWithComponents(componentTypes, callback);\n }\n }\n\n /**\n * Iterate over entities with their component data (generator)\n * @param componentTypes Array of component types to retrieve\n */\n *iterate<const T extends readonly ComponentType<any>[]>(\n componentTypes: T,\n ): IterableIterator<[EntityId, ...ComponentTuple<T>]> {\n this.ensureNotDisposed();\n\n for (const archetype of this.cachedArchetypes) {\n yield* archetype.iterateWithComponents(componentTypes);\n }\n }\n\n /**\n * Get component data arrays for all matching entities\n * @param componentType The component type to retrieve\n * @returns Array of component data for all matching entities\n */\n getComponentData<T>(componentType: EntityId<T>): T[] {\n this.ensureNotDisposed();\n\n const result: T[] = [];\n for (const archetype of this.cachedArchetypes) {\n result.push(...archetype.getComponentData(componentType));\n }\n return result;\n }\n\n /**\n * Update the cached archetypes\n * Called when new archetypes are created\n */\n updateCache(): void {\n if (this.isDisposed) return;\n\n this.cachedArchetypes = this.world\n .getMatchingArchetypes(this.componentTypes)\n .filter((archetype: Archetype) => matchesFilter(archetype, this.filter));\n }\n\n /**\n * Check if a new archetype matches this query and add to cache if it does\n */\n checkNewArchetype(archetype: Archetype): void {\n if (this.isDisposed) return;\n if (\n matchesComponentTypes(archetype, this.componentTypes) &&\n matchesFilter(archetype, this.filter) &&\n !this.cachedArchetypes.includes(archetype)\n ) {\n this.cachedArchetypes.push(archetype);\n }\n }\n\n /**\n * Remove an archetype from the cached archetypes\n */\n removeArchetype(archetype: Archetype): void {\n if (this.isDisposed) return;\n const index = this.cachedArchetypes.indexOf(archetype);\n if (index !== -1) {\n this.cachedArchetypes.splice(index, 1);\n }\n }\n\n /**\n * Dispose the query and disconnect from world\n */\n /**\n * Request disposal of this query.\n * This will decrement the world's reference count for the query.\n * The query will only be fully disposed when the ref count reaches zero.\n */\n dispose(): void {\n // Ask the world to release this query (decrement refcount and fully dispose when zero)\n this.world.releaseQuery(this);\n }\n\n /**\n * Internal full dispose called by World when refCount reaches zero.\n */\n _disposeInternal(): void {\n if (!this.isDisposed) {\n // Unregister from world (remove from notification list)\n this.world._unregisterQuery(this);\n this.cachedArchetypes = [];\n this.isDisposed = true;\n }\n }\n\n /**\n * Symbol.dispose implementation for automatic resource management\n */\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n /**\n * Check if the query has been disposed\n */\n get disposed(): boolean {\n return this.isDisposed;\n }\n}\n","import type { System } from \"./system\";\n\n/**\n * System Scheduler for managing system dependencies and execution order\n */\nexport class SystemScheduler<UpdateParams extends any[] = []> {\n private systems = new Set<System<UpdateParams>>();\n private systemDependencies = new Map<System<UpdateParams>, Set<System<UpdateParams>>>();\n private cachedExecutionOrder: System<UpdateParams>[] | null = null;\n\n /**\n * Add a system with optional dependencies\n * @param system The system to add\n * @param additionalDeps Additional dependencies for the system\n */\n addSystem(system: System<UpdateParams>, additionalDeps: System<UpdateParams>[] = []): void {\n this.systems.add(system);\n // Also add dependencies to the set\n for (const dep of system.dependencies || []) {\n this.systems.add(dep);\n }\n this.systemDependencies.set(system, new Set([...additionalDeps, ...(system.dependencies || [])]));\n this.cachedExecutionOrder = null;\n }\n\n /**\n * Get the execution order of systems based on dependencies\n * Uses topological sort\n */\n getExecutionOrder(): System<UpdateParams>[] {\n if (this.cachedExecutionOrder !== null) {\n return this.cachedExecutionOrder;\n }\n\n const result: System<UpdateParams>[] = [];\n const visited = new Set<System<UpdateParams>>();\n const visiting = new Set<System<UpdateParams>>();\n\n const visit = (system: System<UpdateParams>): void => {\n if (visited.has(system)) return;\n if (visiting.has(system)) {\n throw new Error(\"Circular dependency detected in system scheduling\");\n }\n\n visiting.add(system);\n\n for (const dep of this.systemDependencies.get(system) || []) {\n visit(dep);\n }\n\n visiting.delete(system);\n visited.add(system);\n result.push(system);\n };\n\n for (const system of this.systems) {\n if (!visited.has(system)) {\n visit(system);\n }\n }\n\n this.cachedExecutionOrder = result;\n return result;\n }\n\n update(...params: UpdateParams): Promise<void[]> | void {\n const executionOrder = this.getExecutionOrder();\n const systemPromises = new Map<System<UpdateParams>, Promise<void>>();\n\n for (const system of executionOrder) {\n const deps = Array.from(this.systemDependencies.get(system) || []);\n const depPromises = deps.map((dep) => systemPromises.get(dep)!).filter(Boolean);\n\n if (depPromises.length > 0) {\n const promise = Promise.all(depPromises).then(() => system.update(...params));\n systemPromises.set(system, promise);\n } else {\n const result = system.update(...params);\n if (result instanceof Promise) {\n systemPromises.set(system, result);\n }\n }\n }\n\n return Promise.all(systemPromises.values());\n }\n\n /**\n * Clear all systems and dependencies\n */\n clear(): void {\n this.systems.clear();\n this.cachedExecutionOrder = null;\n }\n}\n","import { Archetype, MISSING_COMPONENT } from \"./archetype\";\nimport { ComponentChangeset } from \"./changeset\";\nimport { CommandBuffer, type Command } from \"./command-buffer\";\nimport type { ComponentId, EntityId, WildcardRelationId } from \"./entity\";\nimport {\n EntityIdManager,\n getComponentIdByName,\n getComponentNameById,\n getDetailedIdType,\n isCascadeDeleteComponent,\n isDontFragmentComponent,\n isExclusiveComponent,\n relation,\n} from \"./entity\";\nimport { MultiMap } from \"./multi-map\";\nimport { Query } from \"./query\";\nimport { serializeQueryFilter, type QueryFilter } from \"./query-filter\";\nimport type { System } from \"./system\";\nimport { SystemScheduler } from \"./system-scheduler\";\nimport type { ComponentTuple, LifecycleHook } from \"./types\";\nimport { getOrCreateWithSideEffect } from \"./utils\";\n\n/**\n * World class for ECS architecture\n * Manages entities, components, and systems\n */\nexport class World<UpdateParams extends any[] = []> {\n // Core data structures for entity and archetype management\n /** Manages allocation and deallocation of entity IDs */\n private entityIdManager = new EntityIdManager();\n\n /** Array of all archetypes in the world */\n private archetypes: Archetype[] = [];\n\n /** Maps archetype signatures (component type signatures) to archetype instances */\n private archetypeBySignature = new Map<string, Archetype>();\n\n /** Maps entity IDs to their current archetype */\n private entityToArchetype = new Map<EntityId, Archetype>();\n\n /** Maps component types to arrays of archetypes that contain them */\n private archetypesByComponent = new Map<EntityId<any>, Archetype[]>();\n\n /** Tracks which entities reference each entity as a component type */\n private entityReferences = new Map<EntityId, MultiMap<EntityId, EntityId>>();\n\n /** Storage for dontFragment relations - maps entity ID to a map of relation type to component data */\n private dontFragmentRelations: Map<EntityId, Map<EntityId<any>, any>> = new Map();\n\n // Query management\n /** Array of all active queries for archetype change notifications */\n private queries: Query[] = [];\n\n /** Cache for queries keyed by component types and filter signatures */\n private queryCache = new Map<string, { query: Query; refCount: number }>();\n\n // System management\n /** Schedules and executes systems in dependency order */\n private systemScheduler = new SystemScheduler<UpdateParams>();\n\n // Command execution\n /** Buffers structural changes for deferred execution */\n private commandBuffer = new CommandBuffer((entityId, commands) => this.executeEntityCommands(entityId, commands));\n\n // Lifecycle and configuration\n /** Stores lifecycle hooks for component and relation events */\n private hooks = new Map<EntityId<any>, Set<LifecycleHook<any>>>();\n\n /**\n * Create a new World.\n * If an optional snapshot object is provided (previously produced by `world.serialize()`),\n * the world will be restored from that snapshot. The snapshot may contain non-JSON values.\n */\n constructor(snapshot?: SerializedWorld) {\n // If snapshot provided, restore world state\n if (snapshot && typeof snapshot === \"object\") {\n if (snapshot.entityManager) {\n this.entityIdManager.deserializeState(snapshot.entityManager);\n }\n\n // Restore entities and their components\n if (Array.isArray(snapshot.entities)) {\n for (const entry of snapshot.entities) {\n const entityId = entry.id as EntityId;\n const componentsArray: SerializedComponent[] = entry.components || [];\n\n const componentMap = new Map<EntityId<any>, any>();\n const componentTypes: EntityId<any>[] = [];\n\n for (const componentEntry of componentsArray) {\n const componentTypeRaw = componentEntry.type;\n let componentType: EntityId<any>;\n\n if (typeof componentTypeRaw === \"number\") {\n componentType = componentTypeRaw as EntityId<any>;\n } else if (typeof componentTypeRaw === \"string\") {\n // Component name lookup\n const compId = getComponentIdByName(componentTypeRaw);\n if (compId === undefined) {\n throw new Error(`Unknown component name in snapshot: ${componentTypeRaw}`);\n }\n componentType = compId;\n } else if (\n typeof componentTypeRaw === \"object\" &&\n componentTypeRaw !== null &&\n typeof componentTypeRaw.component === \"string\"\n ) {\n // Component name lookup\n const compId = getComponentIdByName(componentTypeRaw.component);\n if (compId === undefined) {\n throw new Error(`Unknown component name in snapshot: ${componentTypeRaw.component}`);\n }\n if (typeof componentTypeRaw.target === \"string\") {\n const targetCompId = getComponentIdByName(componentTypeRaw.target);\n if (targetCompId === undefined) {\n throw new Error(`Unknown target component name in snapshot: ${componentTypeRaw.target}`);\n }\n componentType = relation(compId, targetCompId);\n } else {\n componentType = relation(compId, componentTypeRaw.target as EntityId);\n }\n } else {\n throw new Error(`Invalid component type in snapshot: ${JSON.stringify(componentTypeRaw)}`);\n }\n componentMap.set(componentType, componentEntry.value);\n componentTypes.push(componentType);\n }\n\n const archetype = this.ensureArchetype(componentTypes);\n archetype.addEntity(entityId, componentMap);\n this.entityToArchetype.set(entityId, archetype);\n\n // Update reverse index based on component types\n for (const compType of componentTypes) {\n const detailedType = getDetailedIdType(compType);\n if (detailedType.type === \"entity-relation\") {\n const targetEntityId = detailedType.targetId!;\n this.trackEntityReference(entityId, compType, targetEntityId);\n } else if (detailedType.type === \"entity\") {\n this.trackEntityReference(entityId, compType, compType);\n }\n }\n }\n }\n }\n }\n\n /**\n * Generate a signature string for component types array\n * @returns A string signature for the component types\n */\n private createArchetypeSignature(componentTypes: EntityId<any>[]): string {\n return componentTypes.join(\",\");\n }\n\n /**\n * Create a new entity\n * @returns The ID of the newly created entity\n */\n new(): EntityId {\n const entityId = this.entityIdManager.allocate();\n // Create empty archetype for entities with no components\n let emptyArchetype = this.ensureArchetype([]);\n emptyArchetype.addEntity(entityId, new Map());\n this.entityToArchetype.set(entityId, emptyArchetype);\n return entityId;\n }\n\n /**\n * Destroy an entity and remove all its components (immediate execution)\n */\n private destroyEntityImmediate(entityId: EntityId): void {\n // Implement BFS-style cascade deletion for entity relations where cascade is enabled\n const queue: EntityId[] = [entityId];\n const visited = new Set<EntityId>();\n\n while (queue.length > 0) {\n const cur = queue.shift()!;\n if (visited.has(cur)) continue;\n visited.add(cur);\n\n const archetype = this.entityToArchetype.get(cur);\n if (!archetype) {\n continue; // Entity doesn't exist\n }\n\n // Collect references to this entity and iterate\n const componentReferences = Array.from(this.getEntityReferences(cur));\n for (const [sourceEntityId, componentType] of componentReferences) {\n // For each referencing entity, decide whether to cascade delete or simply remove the component\n const sourceArchetype = this.entityToArchetype.get(sourceEntityId);\n if (!sourceArchetype) continue;\n\n const detailedType = getDetailedIdType(componentType);\n // Cascade only applies to entity relations (not component-relation)\n if (detailedType.type === \"entity-relation\" && isCascadeDeleteComponent(detailedType.componentId!)) {\n // Enqueue the referencing entity for deletion (cascade)\n if (!visited.has(sourceEntityId)) {\n queue.push(sourceEntityId);\n }\n continue;\n }\n\n // Non-cascade behavior: remove the relation component from the source entity\n const currentComponents = new Map<EntityId<any>, any>();\n let removedComponent = sourceArchetype.get(sourceEntityId, componentType);\n for (const archetypeComponentType of sourceArchetype.componentTypes) {\n if (archetypeComponentType !== componentType) {\n const componentData = sourceArchetype.get(sourceEntityId, archetypeComponentType);\n currentComponents.set(archetypeComponentType, componentData);\n }\n }\n\n const newArchetype = this.ensureArchetype(currentComponents.keys());\n\n // Remove from current archetype\n sourceArchetype.removeEntity(sourceEntityId);\n if (sourceArchetype.getEntities().length === 0) {\n this.cleanupEmptyArchetype(sourceArchetype);\n }\n\n // Add to new archetype\n newArchetype.addEntity(sourceEntityId, currentComponents);\n this.entityToArchetype.set(sourceEntityId, newArchetype);\n\n // Remove from component reverse index\n this.untrackEntityReference(sourceEntityId, componentType, cur);\n\n // Trigger component removed hooks\n this.triggerLifecycleHooks(sourceEntityId, new Map(), new Map([[componentType, removedComponent]]));\n }\n\n // Clean up the reverse index for this entity\n this.entityReferences.delete(cur);\n\n // Remove the entity itself\n archetype.removeEntity(cur);\n if (archetype.getEntities().length === 0) {\n this.cleanupEmptyArchetype(archetype);\n }\n this.entityToArchetype.delete(cur);\n this.entityIdManager.deallocate(cur);\n }\n }\n\n /**\n * Check if an entity exists\n */\n exists(entityId: EntityId): boolean {\n return this.entityToArchetype.has(entityId);\n }\n\n /**\n * Add a component to an entity (deferred)\n */\n set(entityId: EntityId, componentType: EntityId<void>): void;\n set<T>(entityId: EntityId, componentType: EntityId<T>, component: NoInfer<T>): void;\n set(entityId: EntityId, componentType: EntityId, component?: any): void {\n if (!this.exists(entityId)) {\n throw new Error(`Entity ${entityId} does not exist`);\n }\n\n // Validate component type\n const detailedType = getDetailedIdType(componentType);\n if (detailedType.type === \"invalid\") {\n throw new Error(`Invalid component type: ${componentType}`);\n }\n if (detailedType.type === \"wildcard-relation\") {\n throw new Error(`Cannot directly add wildcard relation components: ${componentType}`);\n }\n\n this.commandBuffer.set(entityId, componentType, component);\n }\n\n /**\n * Remove a component from an entity (deferred)\n */\n remove<T>(entityId: EntityId, componentType: EntityId<T>): void {\n if (!this.exists(entityId)) {\n throw new Error(`Entity ${entityId} does not exist`);\n }\n\n // Validate component type\n const detailedType = getDetailedIdType(componentType);\n if (detailedType.type === \"invalid\") {\n throw new Error(`Invalid component type: ${componentType}`);\n }\n\n this.commandBuffer.remove(entityId, componentType);\n }\n\n /**\n * Destroy an entity and remove all its components (deferred)\n */\n delete(entityId: EntityId): void {\n this.commandBuffer.delete(entityId);\n }\n\n /**\n * Check if an entity has a specific component\n */\n has<T>(entityId: EntityId, componentType: EntityId<T>): boolean {\n const archetype = this.entityToArchetype.get(entityId);\n if (!archetype) {\n return false;\n }\n\n // Check regular archetype components\n if (archetype.componentTypes.includes(componentType)) {\n return true;\n }\n\n // Check dontFragment relations\n const detailedType = getDetailedIdType(componentType);\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isDontFragmentComponent(detailedType.componentId!)\n ) {\n // Check if entity has this dontFragment relation in the shared storage\n return this.dontFragmentRelations.get(entityId)?.has(componentType) ?? false;\n }\n\n return false;\n }\n\n /**\n * Get component data for a specific entity and wildcard relation type\n * Returns an array of all matching relation instances\n * @param entityId The entity\n * @param componentType The wildcard relation type\n * @returns Array of [targetEntityId, componentData] pairs for all matching relations\n */\n get<T>(entityId: EntityId, componentType: WildcardRelationId<T>): [EntityId<unknown>, T][];\n /**\n * Get component data for a specific entity and component type\n * @param entityId The entity\n * @param componentType The component type\n * @returns The component data\n */\n get<T>(entityId: EntityId, componentType: EntityId<T>): T;\n get<T>(entityId: EntityId, componentType: EntityId<T> | WildcardRelationId<T>): T | [EntityId<unknown>, any][] {\n const archetype = this.entityToArchetype.get(entityId);\n if (!archetype) {\n throw new Error(`Entity ${entityId} does not exist`);\n }\n\n // Check if entity has the component before attempting to get it\n // Note: undefined is a valid component value, so we cannot use undefined to check existence\n const detailedType = getDetailedIdType(componentType);\n if (detailedType.type !== \"wildcard-relation\") {\n // For regular components, check if the component type exists in the archetype or dontFragmentRelations\n const inArchetype = archetype.componentTypes.includes(componentType);\n const isDontFragment =\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isDontFragmentComponent(detailedType.componentId!);\n\n // For dontFragment relations, check if it exists in the dontFragmentRelations storage\n const hasComponent =\n inArchetype || (isDontFragment && this.dontFragmentRelations.get(entityId)?.has(componentType));\n\n if (!hasComponent) {\n throw new Error(\n `Entity ${entityId} does not have component ${componentType}. Use has() to check component existence before calling get().`,\n );\n }\n }\n\n return archetype.get(entityId, componentType);\n }\n\n /**\n * Register a system with optional dependencies\n */\n registerSystem(system: System<UpdateParams>, additionalDeps: System<UpdateParams>[] = []): void {\n this.systemScheduler.addSystem(system, additionalDeps);\n }\n\n /**\n * Register a lifecycle hook for component or wildcard relation events\n */\n hook<T>(componentType: EntityId<T>, hook: LifecycleHook<T>): void {\n if (!this.hooks.has(componentType)) {\n this.hooks.set(componentType, new Set());\n }\n this.hooks.get(componentType)!.add(hook);\n\n if (hook.on_init !== undefined) {\n this.archetypesByComponent.get(componentType)?.forEach((archetype) => {\n const entities = archetype.getEntityToIndexMap();\n const componentData = archetype.getComponentData<T>(componentType);\n for (const [entity, index] of entities) {\n const data = componentData[index];\n const value = (data === MISSING_COMPONENT ? undefined : data) as T;\n hook.on_init?.(entity, componentType, value);\n }\n });\n }\n }\n\n /**\n * Unregister a lifecycle hook for component or wildcard relation events\n */\n unhook<T>(componentType: EntityId<T>, hook: LifecycleHook<T>): void {\n const hooks = this.hooks.get(componentType);\n if (hooks) {\n hooks.delete(hook);\n if (hooks.size === 0) {\n this.hooks.delete(componentType);\n }\n }\n }\n\n /**\n * Mark a component as exclusive relation\n * @deprecated This method has been removed. Use component options instead: component({ exclusive: true })\n * @throws Always throws an error directing to the new API\n */\n setExclusive(componentId: EntityId): void {\n throw new Error(\"setExclusive has been removed. Use component options instead: component({ exclusive: true })\");\n }\n\n /**\n * Mark a component as cascade-delete relation\n * @deprecated This method has been removed. Use component options instead: component({ cascadeDelete: true })\n * @throws Always throws an error directing to the new API\n */\n setCascadeDelete(componentId: EntityId): void {\n throw new Error(\n \"setCascadeDelete has been removed. Use component options instead: component({ cascadeDelete: true })\",\n );\n }\n\n /**\n * Update the world (run all systems in dependency order)\n * This function is synchronous when all systems are synchronous,\n * and asynchronous (returns a Promise) when any system is asynchronous.\n */\n update(...params: UpdateParams): Promise<void> | void {\n const result = this.systemScheduler.update(...params);\n if (result instanceof Promise) {\n return result.then(() => this.commandBuffer.execute());\n } else {\n this.commandBuffer.execute();\n }\n }\n\n /**\n * Execute all deferred commands immediately without running systems\n */\n sync(): void {\n this.commandBuffer.execute();\n }\n\n /**\n * Create a cached query for efficient entity lookups\n * @returns A Query object for the specified component types and filter\n */\n createQuery(componentTypes: EntityId<any>[], filter: QueryFilter = {}): Query {\n // Build a deterministic key for the query (component types sorted + filter negative components sorted)\n const sortedTypes = [...componentTypes].sort((a, b) => a - b);\n const filterKey = serializeQueryFilter(filter);\n const key = `${this.createArchetypeSignature(sortedTypes)}${filterKey ? `|${filterKey}` : \"\"}`;\n\n const cached = this.queryCache.get(key);\n if (cached) {\n cached.refCount++;\n return cached.query;\n }\n\n const query = new Query(this, sortedTypes, filter);\n this.queryCache.set(key, { query, refCount: 1 });\n return query;\n }\n\n /**\n * @internal Register a query for archetype update notifications\n */\n _registerQuery(query: Query): void {\n this.queries.push(query);\n }\n\n /**\n * @internal Unregister a query\n */\n _unregisterQuery(query: Query): void {\n const index = this.queries.indexOf(query);\n if (index !== -1) {\n this.queries.splice(index, 1);\n }\n }\n\n /**\n * Release a query reference obtained from createQuery.\n * Decrements the refCount and fully disposes the query when it reaches zero.\n */\n releaseQuery(query: Query): void {\n for (const [k, v] of this.queryCache.entries()) {\n if (v.query === query) {\n v.refCount--;\n if (v.refCount <= 0) {\n this.queryCache.delete(k);\n this._unregisterQuery(query);\n // Fully dispose the query (will unregister it from notification list)\n v.query._disposeInternal();\n }\n return;\n }\n }\n }\n\n /**\n * @internal Get archetypes that match specific component types (for internal use by queries)\n */\n getMatchingArchetypes(componentTypes: EntityId<any>[]): Archetype[] {\n if (componentTypes.length === 0) {\n return [...this.archetypes];\n }\n\n // Separate regular components from wildcard relations\n const regularComponents: EntityId<any>[] = [];\n const wildcardRelations: { componentId: ComponentId<any>; relationId: EntityId<any> }[] = [];\n\n for (const componentType of componentTypes) {\n const detailedType = getDetailedIdType(componentType);\n if (detailedType.type === \"wildcard-relation\") {\n wildcardRelations.push({\n componentId: detailedType.componentId!,\n relationId: componentType,\n });\n } else {\n regularComponents.push(componentType);\n }\n }\n\n // Get archetypes for regular components\n let matchingArchetypes: Archetype[] = [];\n\n if (regularComponents.length > 0) {\n const sortedRegularTypes = [...regularComponents].sort((a, b) => a - b);\n\n if (sortedRegularTypes.length === 1) {\n const componentType = sortedRegularTypes[0]!;\n matchingArchetypes = this.archetypesByComponent.get(componentType) || [];\n } else {\n // Multi-component query - find intersection of archetypes\n const archetypeLists = sortedRegularTypes.map((type) => this.archetypesByComponent.get(type) || []);\n const firstList = archetypeLists[0] || [];\n const intersection = new Set<Archetype>();\n\n // Find archetypes that contain all required components\n for (const archetype of firstList) {\n let hasAllComponents = true;\n for (let listIndex = 1; listIndex < archetypeLists.length; listIndex++) {\n const otherList = archetypeLists[listIndex]!;\n if (!otherList.includes(archetype)) {\n hasAllComponents = false;\n break;\n }\n }\n if (hasAllComponents) {\n intersection.add(archetype);\n }\n }\n\n matchingArchetypes = Array.from(intersection);\n }\n } else {\n // No regular components, start with all archetypes\n matchingArchetypes = [...this.archetypes];\n }\n\n // Filter by wildcard relations\n for (const wildcard of wildcardRelations) {\n // For dontFragment components, check if wildcard marker is in archetypesByComponent\n if (isDontFragmentComponent(wildcard.componentId)) {\n // Use the wildcard marker for efficient lookup\n const archetypesWithMarker = this.archetypesByComponent.get(wildcard.relationId) || [];\n\n if (matchingArchetypes.length === 0) {\n // No regular components, use all archetypes with the wildcard marker\n matchingArchetypes = archetypesWithMarker;\n } else {\n // Filter to only include archetypes that have the wildcard marker\n matchingArchetypes = matchingArchetypes.filter((archetype) => archetypesWithMarker.includes(archetype));\n }\n } else {\n // For regular (non-dontFragment) relations, fall back to entity-level checking\n // This is necessary because non-dontFragment relations are in the archetype signature\n matchingArchetypes = matchingArchetypes.filter((archetype) =>\n archetype.hasRelationWithComponentId(wildcard.componentId),\n );\n }\n }\n\n return matchingArchetypes;\n }\n\n /**\n * Query entities with specific components\n * @returns Array of entity IDs that have all the specified components\n */\n query(componentTypes: EntityId<any>[]): EntityId[];\n query<const T extends readonly EntityId<any>[]>(\n componentTypes: T,\n includeComponents: true,\n ): Array<{\n entity: EntityId;\n components: ComponentTuple<T>;\n }>;\n query(\n componentTypes: EntityId<any>[],\n includeComponents?: boolean,\n ):\n | EntityId[]\n | Array<{\n entity: EntityId;\n components: any;\n }> {\n const matchingArchetypes = this.getMatchingArchetypes(componentTypes);\n\n if (includeComponents) {\n const result: Array<{\n entity: EntityId;\n components: any;\n }> = [];\n\n for (const archetype of matchingArchetypes) {\n const entitiesWithData = archetype.getEntitiesWithComponents(componentTypes as EntityId<any>[]);\n result.push(...entitiesWithData);\n }\n\n return result;\n } else {\n const result: EntityId[] = [];\n for (const archetype of matchingArchetypes) {\n result.push(...archetype.getEntities());\n }\n return result;\n }\n }\n\n /**\n * @internal Execute commands for a single entity (for internal use by CommandBuffer)\n * @returns ComponentChangeset describing the changes made\n */\n executeEntityCommands(entityId: EntityId, commands: Command[]): ComponentChangeset {\n const changeset = new ComponentChangeset();\n\n // Handle entity destruction\n if (commands.some((cmd) => cmd.type === \"destroy\")) {\n this.destroyEntityImmediate(entityId);\n return changeset;\n }\n\n const currentArchetype = this.entityToArchetype.get(entityId);\n if (!currentArchetype) {\n return changeset;\n }\n\n // Process commands to build changeset\n this.processCommands(entityId, currentArchetype, commands, changeset);\n\n // Apply changes to entity\n const removedComponents = this.applyChangeset(entityId, currentArchetype, changeset);\n\n // Update entity reference tracking\n this.updateEntityReferences(entityId, changeset);\n\n // Trigger lifecycle hooks\n this.triggerLifecycleHooks(entityId, changeset.adds, removedComponents);\n\n return changeset;\n }\n\n /**\n * Process commands and populate the changeset\n */\n private processCommands(\n entityId: EntityId,\n currentArchetype: Archetype,\n commands: Command[],\n changeset: ComponentChangeset,\n ): void {\n for (const command of commands) {\n if (command.type === \"set\" && command.componentType) {\n this.processSetCommand(entityId, currentArchetype, command.componentType, command.component, changeset);\n } else if (command.type === \"delete\" && command.componentType) {\n this.processDeleteCommand(entityId, currentArchetype, command.componentType, changeset);\n }\n }\n }\n\n /**\n * Process a set command, handling exclusive relations\n */\n private processSetCommand(\n entityId: EntityId,\n currentArchetype: Archetype,\n componentType: EntityId<any>,\n component: any,\n changeset: ComponentChangeset,\n ): void {\n const detailedType = getDetailedIdType(componentType);\n\n // Handle exclusive relations by removing existing relations with the same base component\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isExclusiveComponent(detailedType.componentId!)\n ) {\n this.removeExclusiveRelations(entityId, currentArchetype, detailedType.componentId!, changeset);\n }\n\n // For dontFragment relations, ensure wildcard marker is in archetype signature\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isDontFragmentComponent(detailedType.componentId!)\n ) {\n const wildcardMarker = relation(detailedType.componentId!, \"*\");\n // Add wildcard marker to changeset if not already in archetype\n if (!currentArchetype.componentTypes.includes(wildcardMarker)) {\n changeset.set(wildcardMarker, undefined);\n }\n }\n\n changeset.set(componentType, component);\n }\n\n /**\n * Remove all relations with the same base component (for exclusive relations)\n */\n private removeExclusiveRelations(\n entityId: EntityId,\n currentArchetype: Archetype,\n baseComponentId: ComponentId<any>,\n changeset: ComponentChangeset,\n ): void {\n // Check archetype components\n for (const componentType of currentArchetype.componentTypes) {\n if (this.isRelationWithComponent(componentType, baseComponentId)) {\n changeset.delete(componentType);\n }\n }\n\n // Check dontFragment relations\n const entityData = currentArchetype.getEntity(entityId);\n if (entityData) {\n for (const [componentType] of entityData) {\n if (currentArchetype.componentTypes.includes(componentType)) continue;\n if (this.isRelationWithComponent(componentType, baseComponentId)) {\n changeset.delete(componentType);\n }\n }\n }\n }\n\n /**\n * Check if a component type is a relation with the given base component\n */\n private isRelationWithComponent(componentType: EntityId<any>, baseComponentId: ComponentId<any>): boolean {\n const detailedType = getDetailedIdType(componentType);\n return (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n detailedType.componentId === baseComponentId\n );\n }\n\n /**\n * Process a delete command, handling wildcard relations\n */\n private processDeleteCommand(\n entityId: EntityId,\n currentArchetype: Archetype,\n componentType: EntityId<any>,\n changeset: ComponentChangeset,\n ): void {\n const detailedType = getDetailedIdType(componentType);\n\n if (detailedType.type === \"wildcard-relation\") {\n this.removeWildcardRelations(entityId, currentArchetype, detailedType.componentId!, changeset);\n } else {\n changeset.delete(componentType);\n\n // If removing a dontFragment relation, check if we should remove the wildcard marker\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isDontFragmentComponent(detailedType.componentId!)\n ) {\n // Check if there are any other dontFragment relations with the same component ID\n const wildcardMarker = relation(detailedType.componentId!, \"*\");\n const entityData = currentArchetype.getEntity(entityId);\n let hasOtherRelations = false;\n\n if (entityData) {\n for (const [otherComponentType] of entityData) {\n if (otherComponentType === componentType) continue; // Skip the one being removed\n if (changeset.removes.has(otherComponentType)) continue; // Skip if also being removed\n\n const otherDetailedType = getDetailedIdType(otherComponentType);\n if (\n (otherDetailedType.type === \"entity-relation\" || otherDetailedType.type === \"component-relation\") &&\n otherDetailedType.componentId === detailedType.componentId\n ) {\n hasOtherRelations = true;\n break;\n }\n }\n }\n\n // If no other relations exist, remove the wildcard marker\n if (!hasOtherRelations) {\n changeset.delete(wildcardMarker);\n }\n }\n }\n }\n\n /**\n * Remove all relations matching a wildcard component ID\n */\n private removeWildcardRelations(\n entityId: EntityId,\n currentArchetype: Archetype,\n baseComponentId: ComponentId<any>,\n changeset: ComponentChangeset,\n ): void {\n // Check archetype components\n for (const componentType of currentArchetype.componentTypes) {\n if (this.isRelationWithComponent(componentType, baseComponentId)) {\n changeset.delete(componentType);\n }\n }\n\n // Check dontFragment relations\n const entityData = currentArchetype.getEntity(entityId);\n if (entityData) {\n for (const [componentType] of entityData) {\n if (currentArchetype.componentTypes.includes(componentType)) continue;\n if (this.isRelationWithComponent(componentType, baseComponentId)) {\n changeset.delete(componentType);\n }\n }\n }\n\n // If removing dontFragment relations, also remove the wildcard marker\n if (isDontFragmentComponent(baseComponentId)) {\n const wildcardMarker = relation(baseComponentId, \"*\");\n changeset.delete(wildcardMarker);\n }\n }\n\n /**\n * Apply changeset to entity, moving to new archetype if needed\n * @returns Map of removed components with their data\n */\n private applyChangeset(\n entityId: EntityId,\n currentArchetype: Archetype,\n changeset: ComponentChangeset,\n ): Map<EntityId<any>, any> {\n const currentEntityData = currentArchetype.getEntity(entityId);\n const allCurrentComponentTypes = currentEntityData\n ? Array.from(currentEntityData.keys())\n : currentArchetype.componentTypes;\n\n const finalComponentTypes = changeset.getFinalComponentTypes(allCurrentComponentTypes);\n const removedComponents = new Map<EntityId<any>, any>();\n\n if (finalComponentTypes) {\n // Move to new archetype\n this.moveEntityToNewArchetype(entityId, currentArchetype, finalComponentTypes, changeset, removedComponents);\n } else {\n // Update in same archetype\n this.updateEntityInSameArchetype(entityId, currentArchetype, changeset, removedComponents);\n }\n\n return removedComponents;\n }\n\n /**\n * Move entity to a new archetype with updated components\n */\n private moveEntityToNewArchetype(\n entityId: EntityId,\n currentArchetype: Archetype,\n finalComponentTypes: EntityId<any>[],\n changeset: ComponentChangeset,\n removedComponents: Map<EntityId<any>, any>,\n ): void {\n const newArchetype = this.ensureArchetype(finalComponentTypes);\n const currentComponents = currentArchetype.removeEntity(entityId)!;\n\n // Track removed components\n for (const componentType of changeset.removes) {\n removedComponents.set(componentType, currentComponents.get(componentType));\n }\n\n // Add to new archetype with updated components\n newArchetype.addEntity(entityId, changeset.applyTo(currentComponents));\n this.entityToArchetype.set(entityId, newArchetype);\n\n // Cleanup empty archetype\n if (currentArchetype.getEntities().length === 0) {\n this.cleanupEmptyArchetype(currentArchetype);\n }\n }\n\n /**\n * Update entity in same archetype (no archetype change needed)\n */\n private updateEntityInSameArchetype(\n entityId: EntityId,\n currentArchetype: Archetype,\n changeset: ComponentChangeset,\n removedComponents: Map<EntityId<any>, any>,\n ): void {\n const currentComponents = currentArchetype.getEntity(entityId)!;\n const hasDontFragmentChanges = this.hasDontFragmentChanges(changeset);\n\n // Track removed dontFragment components\n if (hasDontFragmentChanges) {\n for (const componentType of changeset.removes) {\n const detailedType = getDetailedIdType(componentType);\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isDontFragmentComponent(detailedType.componentId!)\n ) {\n removedComponents.set(componentType, currentComponents.get(componentType));\n }\n }\n }\n\n if (hasDontFragmentChanges) {\n // Re-add entity with updated components\n this.readdEntityWithUpdatedComponents(entityId, currentArchetype, currentComponents, changeset);\n } else {\n // Direct update for non-dontFragment components\n for (const [componentType, component] of changeset.adds) {\n currentArchetype.set(entityId, componentType, component);\n }\n }\n }\n\n /**\n * Check if changeset contains dontFragment relation changes\n */\n private hasDontFragmentChanges(changeset: ComponentChangeset): boolean {\n for (const componentType of changeset.removes) {\n const detailedType = getDetailedIdType(componentType);\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isDontFragmentComponent(detailedType.componentId!)\n ) {\n return true;\n }\n }\n\n for (const [componentType] of changeset.adds) {\n const detailedType = getDetailedIdType(componentType);\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isDontFragmentComponent(detailedType.componentId!)\n ) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Remove and re-add entity with updated components (for dontFragment changes)\n */\n private readdEntityWithUpdatedComponents(\n entityId: EntityId,\n archetype: Archetype,\n currentComponents: Map<EntityId<any>, any>,\n changeset: ComponentChangeset,\n ): void {\n const newComponents = new Map<EntityId<any>, any>();\n\n // Copy current components except those marked for removal\n for (const [ct, value] of currentComponents) {\n if (!changeset.removes.has(ct)) {\n newComponents.set(ct, value);\n }\n }\n\n // Add new components from changeset\n for (const [ct, value] of changeset.adds) {\n newComponents.set(ct, value);\n }\n\n archetype.removeEntity(entityId);\n archetype.addEntity(entityId, newComponents);\n }\n\n /**\n * Update entity reference tracking based on changeset\n */\n private updateEntityReferences(entityId: EntityId, changeset: ComponentChangeset): void {\n // Remove references for removed components\n for (const componentType of changeset.removes) {\n const detailedType = getDetailedIdType(componentType);\n if (detailedType.type === \"entity-relation\") {\n this.untrackEntityReference(entityId, componentType, detailedType.targetId!);\n } else if (detailedType.type === \"entity\") {\n this.untrackEntityReference(entityId, componentType, componentType);\n }\n }\n\n // Add references for added components\n for (const [componentType] of changeset.adds) {\n const detailedType = getDetailedIdType(componentType);\n if (detailedType.type === \"entity-relation\") {\n this.trackEntityReference(entityId, componentType, detailedType.targetId!);\n } else if (detailedType.type === \"entity\") {\n this.trackEntityReference(entityId, componentType, componentType);\n }\n }\n }\n\n /**\n * Get or create an archetype for the given component types\n * Filters out dontFragment relations from the archetype signature\n * @returns The archetype for the given component types (excluding dontFragment relations)\n */\n private ensureArchetype(componentTypes: Iterable<EntityId<any>>): Archetype {\n const regularTypes = this.filterRegularComponentTypes(componentTypes);\n const sortedTypes = regularTypes.sort((a, b) => a - b);\n const hashKey = this.createArchetypeSignature(sortedTypes);\n\n return getOrCreateWithSideEffect(this.archetypeBySignature, hashKey, () => this.createNewArchetype(sortedTypes));\n }\n\n /**\n * Filter out dontFragment relations from component types, but keep wildcard markers\n */\n private filterRegularComponentTypes(componentTypes: Iterable<EntityId<any>>): EntityId<any>[] {\n const regularTypes: EntityId<any>[] = [];\n\n for (const componentType of componentTypes) {\n const detailedType = getDetailedIdType(componentType);\n\n // Keep wildcard markers for dontFragment components (they mark the archetype)\n if (detailedType.type === \"wildcard-relation\" && isDontFragmentComponent(detailedType.componentId!)) {\n regularTypes.push(componentType);\n continue;\n }\n\n // Skip specific dontFragment relations from archetype signature\n if (\n (detailedType.type === \"entity-relation\" || detailedType.type === \"component-relation\") &&\n isDontFragmentComponent(detailedType.componentId!)\n ) {\n continue;\n }\n\n regularTypes.push(componentType);\n }\n\n return regularTypes;\n }\n\n /**\n * Create a new archetype and register it with all tracking structures\n */\n private createNewArchetype(componentTypes: EntityId<any>[]): Archetype {\n const newArchetype = new Archetype(componentTypes, this.dontFragmentRelations);\n this.archetypes.push(newArchetype);\n\n // Register archetype in component index\n this.registerArchetypeInComponentIndex(newArchetype, componentTypes);\n\n // Notify queries about new archetype\n this.notifyQueriesOfNewArchetype(newArchetype);\n\n return newArchetype;\n }\n\n /**\n * Register archetype in the component-to-archetype index\n */\n private registerArchetypeInComponentIndex(archetype: Archetype, componentTypes: EntityId<any>[]): void {\n for (const componentType of componentTypes) {\n const archetypes = this.archetypesByComponent.get(componentType) || [];\n archetypes.push(archetype);\n this.archetypesByComponent.set(componentType, archetypes);\n }\n }\n\n /**\n * Notify all queries to check the new archetype\n */\n private notifyQueriesOfNewArchetype(archetype: Archetype): void {\n for (const query of this.queries) {\n query.checkNewArchetype(archetype);\n }\n }\n\n /**\n * Add a component reference to the reverse index when an entity is used as a component type\n * @param sourceEntityId The entity that has the component\n * @param componentType The component type (which may be an entity ID used as component type)\n * @param targetEntityId The entity being used as component type\n */\n private trackEntityReference(sourceEntityId: EntityId, componentType: EntityId, targetEntityId: EntityId): void {\n if (!this.entityReferences.has(targetEntityId)) {\n this.entityReferences.set(targetEntityId, new MultiMap());\n }\n this.entityReferences.get(targetEntityId)!.add(sourceEntityId, componentType);\n }\n\n /**\n * Remove a component reference from the reverse index\n * @param sourceEntityId The entity that has the component\n * @param componentType The component type\n * @param targetEntityId The entity being used as component type\n */\n private untrackEntityReference(sourceEntityId: EntityId, componentType: EntityId, targetEntityId: EntityId): void {\n const references = this.entityReferences.get(targetEntityId);\n if (references) {\n references.remove(sourceEntityId, componentType);\n if (references.keyCount === 0) {\n this.entityReferences.delete(targetEntityId);\n }\n }\n }\n\n /**\n * Get all component references where a target entity is used as a component type\n * @param targetEntityId The target entity\n * @returns A MultiMap of sourceEntityId to componentTypes that reference the target entity\n */\n private getEntityReferences(targetEntityId: EntityId): Iterable<[EntityId, EntityId]> {\n return this.entityReferences.get(targetEntityId) ?? new MultiMap();\n }\n\n /**\n * Remove an empty archetype from all internal data structures\n */\n private cleanupEmptyArchetype(archetype: Archetype): void {\n if (archetype.getEntities().length > 0) {\n return;\n }\n\n this.removeArchetypeFromList(archetype);\n this.removeArchetypeFromSignatureMap(archetype);\n this.removeArchetypeFromComponentIndex(archetype);\n this.removeArchetypeFromQueries(archetype);\n }\n\n /**\n * Remove archetype from the main archetypes list\n */\n private removeArchetypeFromList(archetype: Archetype): void {\n const index = this.archetypes.indexOf(archetype);\n if (index !== -1) {\n this.archetypes.splice(index, 1);\n }\n }\n\n /**\n * Remove archetype from the signature-to-archetype map\n */\n private removeArchetypeFromSignatureMap(archetype: Archetype): void {\n const hashKey = this.createArchetypeSignature(archetype.componentTypes);\n this.archetypeBySignature.delete(hashKey);\n }\n\n /**\n * Remove archetype from the component-to-archetypes index\n */\n private removeArchetypeFromComponentIndex(archetype: Archetype): void {\n for (const componentType of archetype.componentTypes) {\n const archetypes = this.archetypesByComponent.get(componentType);\n if (archetypes) {\n const compIndex = archetypes.indexOf(archetype);\n if (compIndex !== -1) {\n archetypes.splice(compIndex, 1);\n if (archetypes.length === 0) {\n this.archetypesByComponent.delete(componentType);\n }\n }\n }\n }\n }\n\n /**\n * Remove archetype from all queries\n */\n private removeArchetypeFromQueries(archetype: Archetype): void {\n for (const query of this.queries) {\n query.removeArchetype(archetype);\n }\n }\n\n /**\n * Execute component lifecycle hooks for added and removed components\n */\n private triggerLifecycleHooks(\n entityId: EntityId,\n addedComponents: Map<EntityId<any>, any>,\n removedComponents: Map<EntityId<any>, any>,\n ): void {\n // Trigger component added hooks\n for (const [componentType, component] of addedComponents) {\n // Trigger direct component hooks\n const directHooks = this.hooks.get(componentType);\n if (directHooks) {\n for (const lifecycleHook of directHooks) {\n lifecycleHook.on_set?.(entityId, componentType, component);\n }\n }\n\n // Trigger wildcard relation hooks for added components\n const detailedType = getDetailedIdType(componentType);\n if (\n detailedType.type === \"entity-relation\" ||\n detailedType.type === \"component-relation\" ||\n detailedType.type === \"wildcard-relation\"\n ) {\n const wildcardRelationId = relation(detailedType.componentId!, \"*\");\n const wildcardHooks = this.hooks.get(wildcardRelationId);\n if (wildcardHooks) {\n for (const lifecycleHook of wildcardHooks) {\n lifecycleHook.on_set?.(entityId, componentType, component);\n }\n }\n }\n }\n\n // Trigger component removed hooks\n for (const [componentType, component] of removedComponents) {\n // Trigger direct component hooks\n const directHooks = this.hooks.get(componentType);\n if (directHooks) {\n for (const lifecycleHook of directHooks) {\n lifecycleHook.on_remove?.(entityId, componentType, component);\n }\n }\n\n // Trigger wildcard relation hooks for removed components\n const detailedType = getDetailedIdType(componentType);\n if (\n detailedType.type === \"entity-relation\" ||\n detailedType.type === \"component-relation\" ||\n detailedType.type === \"wildcard-relation\"\n ) {\n const wildcardRelationId = relation(detailedType.componentId!, \"*\");\n const wildcardHooks = this.hooks.get(wildcardRelationId);\n if (wildcardHooks) {\n for (const hook of wildcardHooks) {\n hook.on_remove?.(entityId, componentType, component);\n }\n }\n }\n }\n }\n\n /**\n * Convert the world into a plain snapshot object.\n * This returns an in-memory structure and does not perform JSON stringification.\n * Component values are stored as-is (they may be non-JSON-serializable).\n */\n serialize(): SerializedWorld {\n const entities: SerializedEntity[] = [];\n\n for (const archetype of this.archetypes) {\n const dumpedEntities = archetype.dump();\n for (const { entity, components } of dumpedEntities) {\n entities.push({\n id: entity,\n components: Array.from(components.entries()).map(([rawType, value]) => {\n const detailedType = getDetailedIdType(rawType);\n let type: SerializedComponent[\"type\"] = rawType;\n let componentName;\n switch (detailedType.type) {\n case \"component\":\n type = getComponentNameById(rawType as ComponentId) || rawType;\n break;\n case \"entity-relation\":\n componentName = getComponentNameById(detailedType.componentId);\n if (componentName) {\n type = { component: componentName, target: detailedType.targetId! };\n }\n break;\n case \"component-relation\":\n componentName = getComponentNameById(detailedType.componentId);\n if (componentName) {\n type = {\n component: componentName,\n target: getComponentNameById(detailedType.targetId!) || detailedType.targetId!,\n };\n }\n break;\n }\n return { type, value: value === MISSING_COMPONENT ? undefined : value };\n }),\n });\n }\n }\n\n return {\n version: 1,\n entityManager: this.entityIdManager.serializeState(),\n entities,\n };\n }\n}\n\nexport type SerializedWorld = {\n version: number;\n entityManager: any;\n entities: SerializedEntity[];\n};\n\nexport type SerializedEntity = {\n id: number;\n components: SerializedComponent[];\n};\n\nexport type SerializedComponent = {\n type: number | string | { component: string; target: number | string };\n value: any;\n};\n"],"mappings":"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"}
|