@0xobelisk/ecs 1.2.0-pre.24

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/query.ts","../src/subscription.ts","../src/world.ts"],"sourcesContent":["// ECS type definitions\nexport type {\n EntityId,\n ComponentType,\n Unsubscribe,\n ComponentCallback,\n ComponentChangeCallback,\n EntityCallback,\n QueryChange,\n QueryChangeCallback,\n QueryWatcher,\n PagedResult,\n BatchQueryResult,\n ComponentChangeEvent,\n EntityChangeEvent,\n QueryOptions,\n SubscriptionOptions,\n ComponentMetadata,\n ComponentField,\n ComponentDiscoveryResult,\n ResourceMetadata,\n ResourceDiscoveryResult,\n ECSWorldConfig,\n DubheMetadata,\n} from './types';\n\n// Main class exports\nexport { DubheECSWorld } from './world';\nexport { ComponentDiscoverer, ResourceDiscoverer } from './world';\nexport { ECSQuery } from './query';\nexport { ECSSubscription } from './subscription';\n\n// Factory function exports\nexport { createECSWorld } from './world';\n\n// Utility function exports\nexport {\n extractEntityIds,\n calculateDelta,\n findEntityIntersection,\n findEntityUnion,\n extractIntersectionFromBatchResult,\n extractUnionFromBatchResult,\n debounce,\n normalizeComponentType,\n createCacheKey,\n isValidEntityId,\n isValidComponentType,\n deepEqual,\n safeJsonParse,\n formatError,\n createTimestamp,\n limitArray,\n paginateArray,\n} from './utils';\n\n// Default export main class\nexport { DubheECSWorld as default } from './world';\n","// ECS utility functions\n\nimport { EntityId, ComponentType, QueryChange } from './types';\nimport { Connection, StoreTableRow } from '@0xobelisk/graphql-client';\n\n/**\n * Extract entity IDs from GraphQL query results\n * @param connection GraphQL query result\n * @param options Extraction options\n * @param options.idFields Field names to use as entity ID, defaults to ['nodeId', 'entityId']\n * @param options.composite Whether to compose multiple fields as ID, defaults to false\n */\nexport function extractEntityIds<T extends StoreTableRow>(\n connection: Connection<T>,\n options?: {\n idFields?: string[];\n composite?: boolean;\n }\n): EntityId[] {\n const { idFields = ['nodeId', 'entityId'], composite = false } =\n options || {};\n\n return connection.edges\n .map((edge) => {\n const node = edge.node as any;\n\n if (composite) {\n // Compose multiple fields as ID\n const idParts = idFields\n .map((field) => node[field] || '')\n .filter(Boolean);\n return idParts.join('|'); // Use | separator to compose\n } else {\n // Try to find the first existing field as ID\n for (const field of idFields) {\n if (node[field] !== undefined && node[field] !== null) {\n return node[field] as EntityId;\n }\n }\n\n // If none found, return the first available value or empty string\n return (Object.values(node)[0] as EntityId) || '';\n }\n })\n .filter(Boolean); // Filter out empty values\n}\n\n/**\n * Calculate differences between two entity ID arrays\n */\nexport function calculateDelta(\n oldResults: EntityId[],\n newResults: EntityId[]\n): QueryChange {\n const oldSet = new Set(oldResults);\n const newSet = new Set(newResults);\n\n const added = newResults.filter((id) => !oldSet.has(id));\n const removed = oldResults.filter((id) => !newSet.has(id));\n\n return {\n added,\n removed,\n current: newResults,\n };\n}\n\n/**\n * Find intersection of multiple entity ID arrays\n */\nexport function findEntityIntersection(entitySets: EntityId[][]): EntityId[] {\n if (entitySets.length === 0) return [];\n if (entitySets.length === 1) return entitySets[0];\n\n return entitySets.reduce((intersection, currentSet) => {\n const currentSetLookup = new Set(currentSet);\n return intersection.filter((id) => currentSetLookup.has(id));\n });\n}\n\n/**\n * Find union of multiple entity ID arrays\n */\nexport function findEntityUnion(entitySets: EntityId[][]): EntityId[] {\n const unionSet = new Set<EntityId>();\n\n entitySets.forEach((set) => {\n set.forEach((id) => unionSet.add(id));\n });\n\n return Array.from(unionSet);\n}\n\n/**\n * Extract entity intersection from batch query results\n */\nexport function extractIntersectionFromBatchResult(\n batchResult: Record<string, Connection<StoreTableRow>>,\n componentTypes: ComponentType[],\n options?: {\n idFields?: string[];\n composite?: boolean;\n }\n): EntityId[] {\n const entitySets = componentTypes.map((type) => {\n const connection = batchResult[type];\n return connection ? extractEntityIds(connection, options) : [];\n });\n\n return findEntityIntersection(entitySets);\n}\n\n/**\n * Extract entity union from batch query results\n */\nexport function extractUnionFromBatchResult(\n batchResult: Record<string, Connection<StoreTableRow>>,\n componentTypes: ComponentType[],\n options?: {\n idFields?: string[];\n composite?: boolean;\n }\n): EntityId[] {\n const entitySets = componentTypes.map((type) => {\n const connection = batchResult[type];\n return connection ? extractEntityIds(connection, options) : [];\n });\n\n return findEntityUnion(entitySets);\n}\n\n/**\n * Debounce function\n */\nexport function debounce<T extends (...args: any[]) => any>(\n func: T,\n waitMs: number\n): (...args: Parameters<T>) => void {\n let timeoutId: NodeJS.Timeout | null = null;\n\n return (...args: Parameters<T>) => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n\n timeoutId = setTimeout(() => {\n func(...args);\n timeoutId = null;\n }, waitMs);\n };\n}\n\n/**\n * Normalize component type name (handle singular/plural)\n */\nexport function normalizeComponentType(componentType: ComponentType): {\n singular: string;\n plural: string;\n} {\n // Simple singular/plural conversion logic\n const singular = componentType.endsWith('s')\n ? componentType.slice(0, -1)\n : componentType;\n\n const plural = componentType.endsWith('s')\n ? componentType\n : componentType + 's';\n\n return { singular, plural };\n}\n\n/**\n * Create cache key\n */\nexport function createCacheKey(\n operation: string,\n componentTypes: ComponentType[],\n options?: Record<string, any>\n): string {\n const sortedTypes = [...componentTypes].sort();\n const optionsStr = options ? JSON.stringify(options) : '';\n return `${operation}:${sortedTypes.join(',')}:${optionsStr}`;\n}\n\n/**\n * Validate entity ID format\n */\nexport function isValidEntityId(entityId: any): entityId is EntityId {\n return typeof entityId === 'string' && entityId.length > 0;\n}\n\n/**\n * Validate component type format\n */\nexport function isValidComponentType(\n componentType: any\n): componentType is ComponentType {\n return typeof componentType === 'string' && componentType.length > 0;\n}\n\n/**\n * Deep compare two objects for equality\n */\nexport function deepEqual(obj1: any, obj2: any): boolean {\n if (obj1 === obj2) return true;\n\n if (obj1 == null || obj2 == null) return false;\n\n if (typeof obj1 !== typeof obj2) return false;\n\n if (typeof obj1 !== 'object') return false;\n\n const keys1 = Object.keys(obj1);\n const keys2 = Object.keys(obj2);\n\n if (keys1.length !== keys2.length) return false;\n\n for (const key of keys1) {\n if (!keys2.includes(key)) return false;\n if (!deepEqual(obj1[key], obj2[key])) return false;\n }\n\n return true;\n}\n\n/**\n * Safely parse JSON\n */\nexport function safeJsonParse<T = any>(json: string, defaultValue: T): T {\n try {\n return JSON.parse(json);\n } catch {\n return defaultValue;\n }\n}\n\n/**\n * Format error message\n */\nexport function formatError(error: any): string {\n if (error instanceof Error) {\n return error.message;\n }\n\n if (typeof error === 'string') {\n return error;\n }\n\n return JSON.stringify(error);\n}\n\n/**\n * Create timestamp\n */\nexport function createTimestamp(): number {\n return Date.now();\n}\n\n/**\n * Limit array size\n */\nexport function limitArray<T>(array: T[], limit: number): T[] {\n return limit > 0 ? array.slice(0, limit) : array;\n}\n\n/**\n * Paginate array\n */\nexport function paginateArray<T>(\n array: T[],\n page: number,\n pageSize: number\n): {\n items: T[];\n totalCount: number;\n hasMore: boolean;\n page: number;\n pageSize: number;\n} {\n const startIndex = (page - 1) * pageSize;\n const endIndex = startIndex + pageSize;\n const items = array.slice(startIndex, endIndex);\n\n return {\n items,\n totalCount: array.length,\n hasMore: endIndex < array.length,\n page,\n pageSize,\n };\n}\n","// ECS query system implementation\n\nimport { DubheGraphqlClient } from '@0xobelisk/graphql-client';\nimport { EntityId, ComponentType, QueryOptions, PagedResult } from './types';\nimport {\n extractEntityIds,\n extractIntersectionFromBatchResult,\n extractUnionFromBatchResult,\n isValidEntityId,\n isValidComponentType,\n createCacheKey,\n limitArray,\n paginateArray,\n formatError,\n} from './utils';\nimport { ComponentDiscoverer } from './world';\n\n/**\n * ECS query system core implementation\n */\nexport class ECSQuery {\n private graphqlClient: DubheGraphqlClient;\n private queryCache = new Map<\n string,\n { result: EntityId[]; timestamp: number }\n >();\n private cacheTimeout = 5000; // 5 second cache timeout\n private availableComponents: ComponentType[] = [];\n private componentDiscoverer: ComponentDiscoverer | null = null;\n // Component primary key cache - pre-parsed during initialization\n private componentPrimaryKeys = new Map<ComponentType, string>();\n\n constructor(\n graphqlClient: DubheGraphqlClient,\n componentDiscoverer?: ComponentDiscoverer\n ) {\n this.graphqlClient = graphqlClient;\n this.componentDiscoverer = componentDiscoverer || null;\n }\n\n /**\n * Set available component list\n */\n setAvailableComponents(componentTypes: ComponentType[]): void {\n this.availableComponents = componentTypes;\n }\n\n /**\n * Pre-parse and cache all component primary key information\n */\n initializeComponentMetadata(\n componentMetadataList: Array<{ name: ComponentType; primaryKeys: string[] }>\n ) {\n this.componentPrimaryKeys.clear();\n\n for (const metadata of componentMetadataList) {\n if (metadata.primaryKeys.length === 1) {\n this.componentPrimaryKeys.set(metadata.name, metadata.primaryKeys[0]);\n }\n }\n }\n\n /**\n * Get component's primary key field name (quickly retrieve from cache)\n */\n getComponentPrimaryKeyField(componentType: ComponentType): string {\n return this.componentPrimaryKeys.get(componentType) || 'entityId';\n }\n\n /**\n * Set component discoverer\n */\n setComponentDiscoverer(discoverer: ComponentDiscoverer): void {\n this.componentDiscoverer = discoverer;\n }\n\n /**\n * Get component field information\n */\n private async getComponentFields(\n componentType: ComponentType\n ): Promise<string[]> {\n if (this.componentDiscoverer) {\n try {\n const metadata =\n this.componentDiscoverer.getComponentMetadata(componentType);\n if (metadata) {\n return metadata.fields.map((field) => field.name);\n }\n } catch (error) {\n // Ignore error for now\n }\n }\n\n // Throw error when unable to auto-parse, requiring user to explicitly specify\n throw new Error(\n `Unable to get field information for component ${componentType}. Please explicitly specify fields in QueryOptions or ensure component discoverer is properly configured.`\n );\n }\n\n /**\n * Get component's primary key fields\n */\n private async getComponentPrimaryKeys(\n componentType: ComponentType\n ): Promise<string[]> {\n if (this.componentDiscoverer) {\n try {\n const metadata =\n this.componentDiscoverer.getComponentMetadata(componentType);\n if (metadata && metadata.primaryKeys.length > 0) {\n return metadata.primaryKeys;\n }\n } catch (error) {\n // Ignore error for now\n }\n }\n\n // Throw error when unable to auto-parse, requiring user to explicitly specify\n throw new Error(\n `Unable to get primary key information for component ${componentType}. Please explicitly specify idFields in QueryOptions or ensure component discoverer is properly configured.`\n );\n }\n\n /**\n * Get fields to use for queries (priority: user specified > dubhe config auto-parsed)\n */\n private async getQueryFields(\n componentType: ComponentType,\n userFields?: string[]\n ): Promise<string[]> {\n if (userFields && userFields.length > 0) {\n return userFields;\n }\n\n // Use dubhe config auto-parsed fields, will throw error if failed requiring explicit specification\n return this.getComponentFields(componentType);\n }\n\n /**\n * Check if entity exists\n */\n async hasEntity(entityId: EntityId): Promise<boolean> {\n if (!isValidEntityId(entityId)) return false;\n\n try {\n // Check entity existence by querying any possible component tables\n // This can be optimized to query a dedicated entity table\n const tables = await this.getAvailableComponents();\n for (const table of tables) {\n // for (const table of tables.slice(0, 3)) {\n // Only check first 3 tables to avoid too many queries\n try {\n const condition = this.buildEntityCondition(table, entityId);\n const component = await this.graphqlClient.getTableByCondition(\n table,\n condition\n );\n if (component) return true;\n } catch (error) {\n // If query fails for a table, continue checking next table\n }\n }\n\n return false;\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Get all entity IDs (collected from all component tables)\n */\n async getAllEntities(): Promise<EntityId[]> {\n try {\n const tables = await this.getAvailableComponents();\n\n // Query all tables in parallel using cached field information\n const queries = await Promise.all(\n tables.map(async (table) => {\n const fields = await this.getQueryFields(table);\n const primaryKey = this.componentPrimaryKeys.get(table) || 'entityId';\n\n return {\n key: table,\n tableName: table,\n params: {\n fields: fields,\n filter: {},\n },\n primaryKey, // Use cached primary key information\n };\n })\n );\n\n const batchResult = await this.graphqlClient.batchQuery(\n queries.map((q) => ({\n key: q.key,\n tableName: q.tableName,\n params: q.params,\n }))\n );\n\n // Extract entity IDs using cached primary key fields\n return extractUnionFromBatchResult(batchResult, tables, {\n idFields: undefined, // Let extractEntityIds auto-infer\n composite: false,\n });\n } catch (error) {\n return [];\n }\n }\n\n /**\n * Get entity count\n */\n async getEntityCount(): Promise<number> {\n const entities = await this.getAllEntities();\n return entities.length;\n }\n\n /**\n * Check if entity has specific component\n */\n async hasComponent(\n entityId: EntityId,\n componentType: ComponentType\n ): Promise<boolean> {\n if (!isValidEntityId(entityId) || !isValidComponentType(componentType)) {\n return false;\n }\n\n // Validate if it's an ECS-compliant component\n if (!this.isECSComponent(componentType)) {\n return false;\n }\n\n try {\n const condition = this.buildEntityCondition(componentType, entityId);\n const component = await this.graphqlClient.getTableByCondition(\n componentType,\n condition\n );\n return component !== null;\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Get specific component data of entity\n */\n async getComponent<T>(\n entityId: EntityId,\n componentType: ComponentType\n ): Promise<T | null> {\n if (!isValidEntityId(entityId) || !isValidComponentType(componentType)) {\n return null;\n }\n\n // Validate if it's an ECS-compliant component\n if (!this.isECSComponent(componentType)) {\n return null;\n }\n\n try {\n const condition = this.buildEntityCondition(componentType, entityId);\n const component = await this.graphqlClient.getTableByCondition(\n componentType,\n condition\n );\n return component as T;\n } catch (error) {\n return null;\n }\n }\n\n /**\n * Get all component types that entity has\n */\n async getComponents(entityId: EntityId): Promise<ComponentType[]> {\n if (!isValidEntityId(entityId)) return [];\n\n try {\n const tables = await this.getAvailableComponents();\n const componentTypes: ComponentType[] = [];\n\n // Check if entity exists in each table\n await Promise.all(\n tables.map(async (table) => {\n const hasComp = await this.hasComponent(entityId, table);\n if (hasComp) {\n componentTypes.push(table);\n }\n })\n );\n\n return componentTypes;\n } catch (error) {\n return [];\n }\n }\n\n /**\n * Validate if component type is ECS-compliant\n */\n private isECSComponent(componentType: ComponentType): boolean {\n return this.availableComponents.includes(componentType);\n }\n\n /**\n * Build entity query condition (using cached primary key field name)\n */\n private buildEntityCondition(\n componentType: ComponentType,\n entityId: EntityId\n ): Record<string, any> {\n // Get primary key field name from cache\n const primaryKeyField = this.componentPrimaryKeys.get(componentType);\n if (primaryKeyField) {\n return { [primaryKeyField]: entityId };\n } else {\n // If not in cache, fallback to default 'entityId' field\n return { entityId: entityId };\n }\n }\n\n /**\n * Filter and validate component type list, keeping only ECS-compliant components\n */\n private filterValidECSComponents(\n componentTypes: ComponentType[]\n ): ComponentType[] {\n const validComponents = componentTypes.filter((componentType) => {\n if (!isValidComponentType(componentType)) {\n return false;\n }\n\n if (!this.isECSComponent(componentType)) {\n return false;\n }\n\n return true;\n });\n\n return validComponents;\n }\n\n /**\n * Query all entities that have a specific component\n */\n async queryWith(\n componentType: ComponentType,\n options?: QueryOptions\n ): Promise<EntityId[]> {\n if (!isValidComponentType(componentType)) return [];\n\n // Validate if it's an ECS-compliant component\n if (!this.isECSComponent(componentType)) {\n return [];\n }\n\n const cacheKey = createCacheKey('queryWith', [componentType], options);\n const cached = this.getCachedResult(cacheKey);\n if (cached && options?.cache !== false) return cached;\n\n try {\n // Intelligently get query fields and primary key information\n const queryFields = await this.getQueryFields(\n componentType,\n options?.fields\n );\n const primaryKeys = await this.getComponentPrimaryKeys(componentType);\n\n const connection = await this.graphqlClient.getAllTables(componentType, {\n first: options?.limit,\n fields: queryFields,\n orderBy: options?.orderBy,\n });\n\n const result = extractEntityIds(connection, {\n idFields: options?.idFields || primaryKeys,\n composite: options?.compositeId,\n });\n this.setCachedResult(cacheKey, result);\n return result;\n } catch (error) {\n return [];\n }\n }\n\n /**\n * Query entities that have all specified components (intersection)\n */\n async queryWithAll(\n componentTypes: ComponentType[],\n options?: QueryOptions\n ): Promise<EntityId[]> {\n if (componentTypes.length === 0) return [];\n if (componentTypes.length === 1)\n return this.queryWith(componentTypes[0], options);\n\n const validTypes = this.filterValidECSComponents(componentTypes);\n if (validTypes.length === 0) return [];\n\n const cacheKey = createCacheKey('queryWithAll', validTypes, options);\n const cached = this.getCachedResult(cacheKey);\n if (cached && options?.cache !== false) return cached;\n\n try {\n // Batch query all component tables using intelligent field resolution\n const queries = await Promise.all(\n validTypes.map(async (type) => {\n const queryFields = await this.getQueryFields(type, options?.fields);\n return {\n key: type,\n tableName: type,\n params: {\n fields: queryFields,\n first: options?.limit,\n orderBy: options?.orderBy,\n },\n };\n })\n );\n\n const batchResult = await this.graphqlClient.batchQuery(queries);\n\n // If user didn't specify idFields, try using first component's primary key\n let idFields = options?.idFields;\n if (!idFields && validTypes.length > 0) {\n try {\n idFields = await this.getComponentPrimaryKeys(validTypes[0]);\n } catch (error) {\n // If unable to get primary key, keep idFields undefined, let extractEntityIds auto-infer\n }\n }\n\n const result = extractIntersectionFromBatchResult(\n batchResult,\n validTypes,\n {\n idFields,\n composite: options?.compositeId,\n }\n );\n\n this.setCachedResult(cacheKey, result);\n return result;\n } catch (error) {\n return [];\n }\n }\n\n /**\n * Query entities that have any of the specified components (union)\n */\n async queryWithAny(\n componentTypes: ComponentType[],\n options?: QueryOptions\n ): Promise<EntityId[]> {\n if (componentTypes.length === 0) return [];\n if (componentTypes.length === 1)\n return this.queryWith(componentTypes[0], options);\n\n const validTypes = this.filterValidECSComponents(componentTypes);\n if (validTypes.length === 0) return [];\n\n const cacheKey = createCacheKey('queryWithAny', validTypes, options);\n const cached = this.getCachedResult(cacheKey);\n if (cached && options?.cache !== false) return cached;\n\n try {\n // Batch query all component tables using intelligent field resolution\n const queries = await Promise.all(\n validTypes.map(async (type) => {\n const queryFields = await this.getQueryFields(type, options?.fields);\n return {\n key: type,\n tableName: type,\n params: {\n fields: queryFields,\n first: options?.limit,\n orderBy: options?.orderBy,\n },\n };\n })\n );\n\n const batchResult = await this.graphqlClient.batchQuery(queries);\n\n // If user didn't specify idFields, try using first component's primary key\n let idFields = options?.idFields;\n if (!idFields && validTypes.length > 0) {\n try {\n idFields = await this.getComponentPrimaryKeys(validTypes[0]);\n } catch (error) {\n // If unable to get primary key, keep idFields undefined, let extractEntityIds auto-infer\n }\n }\n\n const result = extractUnionFromBatchResult(batchResult, validTypes, {\n idFields,\n composite: options?.compositeId,\n });\n\n this.setCachedResult(cacheKey, result);\n return result;\n } catch (error) {\n return [];\n }\n }\n\n /**\n * Query entities that have include components but not exclude components\n */\n async queryWithout(\n includeTypes: ComponentType[],\n excludeTypes: ComponentType[],\n options?: QueryOptions\n ): Promise<EntityId[]> {\n if (includeTypes.length === 0) return [];\n\n // Validate include types are all ECS-compliant components\n const validIncludeTypes = this.filterValidECSComponents(includeTypes);\n if (validIncludeTypes.length === 0) return [];\n\n // Validate exclude types are all ECS-compliant components\n const validExcludeTypes = this.filterValidECSComponents(excludeTypes);\n\n try {\n // First get entities that have all include components\n const includedEntities = await this.queryWithAll(\n validIncludeTypes,\n options\n );\n\n if (validExcludeTypes.length === 0) return includedEntities;\n\n // Get entities that have any exclude components\n const excludedEntities = await this.queryWithAny(validExcludeTypes);\n const excludedSet = new Set(excludedEntities);\n\n // Remove excluded entities from included entities\n return includedEntities.filter((entityId) => !excludedSet.has(entityId));\n } catch (error) {\n return [];\n }\n }\n\n /**\n * Query components based on conditions\n */\n async queryWhere<T>(\n componentType: ComponentType,\n predicate: Record<string, any>,\n options?: QueryOptions\n ): Promise<EntityId[]> {\n if (!isValidComponentType(componentType)) return [];\n\n // Validate if it's an ECS-compliant component\n if (!this.isECSComponent(componentType)) {\n return [];\n }\n\n try {\n // Intelligently get query fields and primary key information\n const queryFields = await this.getQueryFields(\n componentType,\n options?.fields\n );\n const primaryKeys = await this.getComponentPrimaryKeys(componentType);\n\n const connection = await this.graphqlClient.getAllTables(componentType, {\n filter: predicate,\n first: options?.limit,\n fields: queryFields,\n orderBy: options?.orderBy,\n });\n\n return extractEntityIds(connection, {\n idFields: options?.idFields || primaryKeys,\n composite: options?.compositeId,\n });\n } catch (error) {\n return [];\n }\n }\n\n /**\n * Range query\n */\n async queryRange(\n componentType: ComponentType,\n field: string,\n min: any,\n max: any,\n options?: QueryOptions\n ): Promise<EntityId[]> {\n if (!isValidComponentType(componentType)) return [];\n\n // Validate if it's an ECS-compliant component\n if (!this.isECSComponent(componentType)) {\n return [];\n }\n\n const predicate = {\n [field]: {\n greaterThanOrEqualTo: min,\n lessThanOrEqualTo: max,\n },\n };\n\n return this.queryWhere(componentType, predicate, options);\n }\n\n /**\n * Paginated query\n */\n async queryPaged(\n componentTypes: ComponentType[],\n page: number,\n pageSize: number\n ): Promise<PagedResult<EntityId>> {\n try {\n const allResults =\n componentTypes.length === 1\n ? await this.queryWith(componentTypes[0])\n : await this.queryWithAll(componentTypes);\n\n return paginateArray(allResults, page, pageSize);\n } catch (error) {\n return {\n items: [],\n totalCount: 0,\n hasMore: false,\n page,\n pageSize,\n };\n }\n }\n\n /**\n * Create query builder\n */\n query(): ECSQueryBuilder {\n return new ECSQueryBuilder(this);\n }\n\n /**\n * Get cached result\n */\n private getCachedResult(cacheKey: string): EntityId[] | null {\n const cached = this.queryCache.get(cacheKey);\n if (cached && Date.now() - cached.timestamp < this.cacheTimeout) {\n return cached.result;\n }\n return null;\n }\n\n /**\n * Set cached result\n */\n private setCachedResult(cacheKey: string, result: EntityId[]): void {\n this.queryCache.set(cacheKey, {\n result,\n timestamp: Date.now(),\n });\n }\n\n /**\n * Clean expired cache\n */\n private cleanExpiredCache(): void {\n const now = Date.now();\n for (const [key, cached] of this.queryCache.entries()) {\n if (now - cached.timestamp >= this.cacheTimeout) {\n this.queryCache.delete(key);\n }\n }\n }\n\n /**\n * Get available component list\n */\n private async getAvailableComponents(): Promise<string[]> {\n if (this.availableComponents.length > 0) {\n return this.availableComponents;\n }\n\n // Return empty array by default, set by component discovery system\n return [];\n }\n\n /**\n * Dispose resources\n */\n dispose(): void {\n this.queryCache.clear();\n }\n}\n\n/**\n * Query builder implementation\n */\nexport class ECSQueryBuilder {\n private ecsQuery: ECSQuery;\n private includeTypes: ComponentType[] = [];\n private excludeTypes: ComponentType[] = [];\n private whereConditions: Array<{\n componentType: ComponentType;\n predicate: Record<string, any>;\n }> = [];\n private orderByOptions: Array<{\n componentType: ComponentType;\n field: string;\n direction: 'ASC' | 'DESC';\n }> = [];\n private limitValue?: number;\n private offsetValue?: number;\n\n constructor(ecsQuery: ECSQuery) {\n this.ecsQuery = ecsQuery;\n }\n\n with(...componentTypes: ComponentType[]): ECSQueryBuilder {\n this.includeTypes.push(...componentTypes);\n return this;\n }\n\n without(...componentTypes: ComponentType[]): ECSQueryBuilder {\n this.excludeTypes.push(...componentTypes);\n return this;\n }\n\n where<T>(\n componentType: ComponentType,\n predicate: Record<string, any>\n ): ECSQueryBuilder {\n this.whereConditions.push({ componentType, predicate });\n return this;\n }\n\n orderBy(\n componentType: ComponentType,\n field: string,\n direction: 'ASC' | 'DESC' = 'ASC'\n ): ECSQueryBuilder {\n this.orderByOptions.push({ componentType, field, direction });\n return this;\n }\n\n limit(count: number): ECSQueryBuilder {\n this.limitValue = count;\n return this;\n }\n\n offset(count: number): ECSQueryBuilder {\n this.offsetValue = count;\n return this;\n }\n\n async execute(): Promise<EntityId[]> {\n try {\n const options: QueryOptions = {\n limit: this.limitValue,\n offset: this.offsetValue,\n orderBy: this.orderByOptions.map((order) => ({\n field: order.field,\n direction: order.direction,\n })),\n };\n\n // 如果有where条件,先处理过滤\n if (this.whereConditions.length > 0) {\n const filteredResults: EntityId[][] = [];\n\n for (const condition of this.whereConditions) {\n const result = await this.ecsQuery.queryWhere(\n condition.componentType,\n condition.predicate,\n options\n );\n filteredResults.push(result);\n }\n\n // 找到交集\n const intersection = filteredResults.reduce((acc, current) => {\n const currentSet = new Set(current);\n return acc.filter((id) => currentSet.has(id));\n });\n\n return intersection;\n }\n\n // 处理基本的包含/排除查询\n if (this.excludeTypes.length > 0) {\n return this.ecsQuery.queryWithout(\n this.includeTypes,\n this.excludeTypes,\n options\n );\n } else {\n return this.ecsQuery.queryWithAll(this.includeTypes, options);\n }\n } catch (error) {\n return [];\n }\n }\n}\n","// ECS subscription system implementation\n\nimport { Observable, Observer } from '@apollo/client';\nimport { DubheGraphqlClient } from '@0xobelisk/graphql-client';\nimport {\n EntityId,\n ComponentType,\n ComponentCallback,\n QueryChangeCallback,\n QueryWatcher,\n QueryChange,\n SubscriptionOptions,\n Unsubscribe,\n ComponentChangeEvent,\n} from './types';\nimport {\n calculateDelta,\n debounce,\n isValidEntityId,\n isValidComponentType,\n formatError,\n createTimestamp,\n} from './utils';\nimport { ComponentDiscoverer } from './world';\nimport pluralize from 'pluralize';\n\n/**\n * ECS subscription result\n */\nexport interface ECSSubscriptionResult<T = any> {\n entityId: EntityId;\n data: T | null;\n changeType: 'added' | 'updated' | 'removed';\n timestamp: number;\n error?: Error;\n}\n\n/**\n * ECS query change result\n */\nexport interface QueryChangeResult {\n changes: QueryChange;\n error?: Error;\n}\n\n/**\n * ECS subscription system core implementation\n */\nexport class ECSSubscription {\n private graphqlClient: DubheGraphqlClient;\n private subscriptions = new Map<string, any>();\n private queryWatchers = new Map<string, QueryWatcherImpl>();\n private componentDiscoverer: ComponentDiscoverer | null = null;\n private availableComponents: ComponentType[] = [];\n // Component primary key cache - consistent with implementation in query.ts\n private componentPrimaryKeys = new Map<ComponentType, string>();\n\n constructor(\n graphqlClient: DubheGraphqlClient,\n componentDiscoverer?: ComponentDiscoverer\n ) {\n this.graphqlClient = graphqlClient;\n this.componentDiscoverer = componentDiscoverer || null;\n }\n\n /**\n * Set available component list\n */\n setAvailableComponents(componentTypes: ComponentType[]): void {\n this.availableComponents = componentTypes;\n }\n\n /**\n * Pre-parse and cache all component primary key information (consistent with query.ts)\n */\n initializeComponentMetadata(\n componentMetadataList: Array<{ name: ComponentType; primaryKeys: string[] }>\n ) {\n this.componentPrimaryKeys.clear();\n\n for (const metadata of componentMetadataList) {\n if (metadata.primaryKeys.length === 1) {\n this.componentPrimaryKeys.set(metadata.name, metadata.primaryKeys[0]);\n }\n }\n }\n\n /**\n * Get component's primary key field name (quickly retrieve from cache, consistent with query.ts)\n */\n getComponentPrimaryKeyField(componentType: ComponentType): string {\n return this.componentPrimaryKeys.get(componentType) || 'entityId';\n }\n\n /**\n * Set component discoverer\n */\n setComponentDiscoverer(discoverer: ComponentDiscoverer): void {\n this.componentDiscoverer = discoverer;\n }\n\n /**\n * Validate if component type is ECS-compliant\n */\n private isECSComponent(componentType: ComponentType): boolean {\n return this.availableComponents.includes(componentType);\n }\n\n /**\n * Get component field information (intelligent parsing)\n */\n private async getComponentFields(\n componentType: ComponentType\n ): Promise<string[]> {\n if (this.componentDiscoverer) {\n try {\n const metadata =\n this.componentDiscoverer.getComponentMetadata(componentType);\n if (metadata) {\n return metadata.fields.map((field: any) => field.name);\n }\n } catch (error) {\n // Ignore error for now\n }\n }\n\n // Return basic fields when unable to auto-parse\n return ['createdAt', 'updatedAt'];\n }\n\n /**\n * Get fields to use for queries (priority: user specified > dubhe config auto-parsed > default fields)\n */\n private async getQueryFields(\n componentType: ComponentType,\n userFields?: string[]\n ): Promise<string[]> {\n if (userFields && userFields.length > 0) {\n return userFields;\n }\n\n // Use dubhe config auto-parsed fields, return default fields if failed\n return this.getComponentFields(componentType);\n }\n\n /**\n * Listen to component added events\n */\n onComponentAdded<T>(\n componentType: ComponentType,\n options?: SubscriptionOptions & { fields?: string[] }\n ): Observable<ECSSubscriptionResult<T>> {\n if (!isValidComponentType(componentType)) {\n return new Observable((observer: Observer<ECSSubscriptionResult<T>>) => {\n observer.error(new Error(`Invalid component type: ${componentType}`));\n });\n }\n\n // Validate if it's an ECS-compliant component\n if (!this.isECSComponent(componentType)) {\n return new Observable((observer: Observer<ECSSubscriptionResult<T>>) => {\n observer.error(\n new Error(\n `Component type ${componentType} is not ECS-compliant or not available`\n )\n );\n });\n }\n\n return new Observable((observer: Observer<ECSSubscriptionResult<T>>) => {\n let subscription: any = null;\n\n // Asynchronously get fields and create subscription\n this.getQueryFields(componentType, options?.fields)\n .then((subscriptionFields) => {\n const debouncedEmit = options?.debounceMs\n ? debounce(\n (result: ECSSubscriptionResult<T>) => observer.next(result),\n options.debounceMs\n )\n : (result: ECSSubscriptionResult<T>) => observer.next(result);\n\n const observable = this.graphqlClient.subscribeToTableChanges(\n componentType,\n {\n initialEvent: options?.initialEvent ?? false,\n fields: subscriptionFields,\n onData: (data) => {\n try {\n // Process batch data\n const pluralTableName =\n this.getPluralTableName(componentType);\n const nodes = data?.listen?.query?.[pluralTableName]?.nodes;\n if (nodes && Array.isArray(nodes)) {\n nodes.forEach((node: any) => {\n if (node) {\n const entityId =\n node.entityId ||\n this.extractEntityId(node, componentType);\n if (entityId) {\n const result: ECSSubscriptionResult<T> = {\n entityId,\n data: node as T,\n changeType: 'added',\n timestamp: Date.now(),\n };\n debouncedEmit(result);\n }\n }\n });\n }\n } catch (error) {\n observer.error(error);\n }\n },\n onError: (error) => {\n observer.error(error);\n },\n onComplete: () => {\n observer.complete();\n },\n }\n );\n\n // Start subscription\n subscription = observable.subscribe({});\n })\n .catch((error) => {\n observer.error(error);\n });\n\n // Return cleanup function\n return () => {\n if (subscription) {\n subscription.unsubscribe();\n }\n };\n });\n }\n\n /**\n * Listen to component removed events\n */\n onComponentRemoved<T>(\n componentType: ComponentType,\n options?: SubscriptionOptions & { fields?: string[] }\n ): Observable<ECSSubscriptionResult<T>> {\n if (!isValidComponentType(componentType)) {\n return new Observable((observer: Observer<ECSSubscriptionResult<T>>) => {\n observer.error(new Error(`Invalid component type: ${componentType}`));\n });\n }\n\n // Validate if it's an ECS-compliant component\n if (!this.isECSComponent(componentType)) {\n return new Observable((observer: Observer<ECSSubscriptionResult<T>>) => {\n observer.error(\n new Error(\n `Component type ${componentType} is not ECS-compliant or not available`\n )\n );\n });\n }\n\n return new Observable((observer: Observer<ECSSubscriptionResult<T>>) => {\n let subscription: any = null;\n let lastKnownEntities = new Set<EntityId>();\n\n try {\n const debouncedEmit = options?.debounceMs\n ? debounce(\n (result: ECSSubscriptionResult<T>) => observer.next(result),\n options.debounceMs\n )\n : (result: ECSSubscriptionResult<T>) => observer.next(result);\n\n // First get current entity list\n this.initializeLastKnownEntities(componentType, lastKnownEntities);\n\n const observable = this.graphqlClient.subscribeToTableChanges(\n componentType,\n {\n initialEvent: false,\n fields: ['updatedAt'], // Removal detection only needs basic fields\n onData: (data) => {\n try {\n // Get current entity list\n const pluralTableName = this.getPluralTableName(componentType);\n const nodes =\n data?.listen?.query?.[pluralTableName]?.nodes || [];\n const currentEntities = new Set<EntityId>(\n nodes\n .map((node: any) => {\n const entityId =\n node.entityId ||\n this.extractEntityId(node, componentType);\n return entityId;\n })\n .filter(Boolean)\n );\n\n // Find removed entities\n const removedEntities = Array.from(lastKnownEntities).filter(\n (entityId) => !currentEntities.has(entityId)\n );\n\n removedEntities.forEach((entityId) => {\n const result: ECSSubscriptionResult<T> = {\n entityId,\n data: null,\n changeType: 'removed',\n timestamp: Date.now(),\n };\n debouncedEmit(result);\n });\n\n lastKnownEntities = currentEntities;\n } catch (error) {\n observer.error(error);\n }\n },\n onError: (error) => {\n observer.error(error);\n },\n onComplete: () => {\n observer.complete();\n },\n }\n );\n\n // Start subscription\n subscription = observable.subscribe({});\n } catch (error) {\n observer.error(error);\n }\n\n // Return cleanup function\n return () => {\n if (subscription) {\n subscription.unsubscribe();\n }\n };\n });\n }\n\n /**\n * Listen to component changed events (added, removed, modified)\n */\n onComponentChanged<T>(\n componentType: ComponentType,\n options?: SubscriptionOptions & { fields?: string[] }\n ): Observable<ECSSubscriptionResult<T>> {\n if (!isValidComponentType(componentType)) {\n return new Observable((observer: Observer<ECSSubscriptionResult<T>>) => {\n observer.error(new Error(`Invalid component type: ${componentType}`));\n });\n }\n\n // Validate if it's an ECS-compliant component\n if (!this.isECSComponent(componentType)) {\n return new Observable((observer: Observer<ECSSubscriptionResult<T>>) => {\n observer.error(\n new Error(\n `Component type ${componentType} is not ECS-compliant or not available`\n )\n );\n });\n }\n\n return new Observable((observer: Observer<ECSSubscriptionResult<T>>) => {\n let subscription: any = null;\n\n // Asynchronously get fields and create subscription\n this.getQueryFields(componentType, options?.fields)\n .then((subscriptionFields) => {\n const debouncedEmit = options?.debounceMs\n ? debounce(\n (result: ECSSubscriptionResult<T>) => observer.next(result),\n options.debounceMs\n )\n : (result: ECSSubscriptionResult<T>) => observer.next(result);\n\n const observable = this.graphqlClient.subscribeToTableChanges(\n componentType,\n {\n initialEvent: options?.initialEvent ?? false,\n fields: subscriptionFields,\n onData: (data) => {\n try {\n // Get plural table name correctly\n const pluralTableName =\n this.getPluralTableName(componentType);\n\n const nodes = data?.listen?.query?.[pluralTableName]?.nodes;\n\n if (nodes && Array.isArray(nodes)) {\n nodes.forEach((node: any) => {\n if (node) {\n // Entity ID may be in different fields\n const entityId =\n node.entityId ||\n this.extractEntityId(node, componentType);\n\n if (entityId) {\n const result: ECSSubscriptionResult<T> = {\n entityId,\n data: node as T,\n changeType: 'updated',\n timestamp: Date.now(),\n };\n debouncedEmit(result);\n }\n }\n });\n }\n } catch (error) {\n observer.error(error);\n }\n },\n onError: (error) => {\n observer.error(error);\n },\n onComplete: () => {\n observer.complete();\n },\n }\n );\n\n // Start subscription\n subscription = observable.subscribe({});\n })\n .catch((error) => {\n observer.error(error);\n });\n\n // Return cleanup function\n return () => {\n if (subscription) {\n subscription.unsubscribe();\n }\n };\n });\n }\n\n /**\n * Listen to component changes with specific conditions\n */\n onComponentCondition<T>(\n componentType: ComponentType,\n filter: Record<string, any>,\n options?: SubscriptionOptions & { fields?: string[] }\n ): Observable<ECSSubscriptionResult<T>> {\n if (!isValidComponentType(componentType)) {\n return new Observable((observer: Observer<ECSSubscriptionResult<T>>) => {\n observer.error(new Error(`Invalid component type: ${componentType}`));\n });\n }\n\n // Validate if it's an ECS-compliant component\n if (!this.isECSComponent(componentType)) {\n return new Observable((observer: Observer<ECSSubscriptionResult<T>>) => {\n observer.error(\n new Error(\n `Component type ${componentType} is not ECS-compliant or not available`\n )\n );\n });\n }\n\n return new Observable((observer: Observer<ECSSubscriptionResult<T>>) => {\n let subscription: any = null;\n\n // Asynchronously get fields and create subscription\n this.getQueryFields(componentType, options?.fields)\n .then((subscriptionFields) => {\n const debouncedEmit = options?.debounceMs\n ? debounce(\n (result: ECSSubscriptionResult<T>) => observer.next(result),\n options.debounceMs\n )\n : (result: ECSSubscriptionResult<T>) => observer.next(result);\n\n const observable = this.graphqlClient.subscribeToFilteredTableChanges(\n componentType,\n filter,\n {\n initialEvent: options?.initialEvent ?? false,\n fields: subscriptionFields,\n onData: (data) => {\n try {\n const pluralTableName =\n this.getPluralTableName(componentType);\n const nodes =\n data?.listen?.query?.[pluralTableName]?.nodes || [];\n\n nodes.forEach((node: any) => {\n if (node) {\n const entityId =\n node.entityId ||\n this.extractEntityId(node, componentType);\n if (entityId) {\n const result: ECSSubscriptionResult<T> = {\n entityId,\n data: node as T,\n changeType: 'updated',\n timestamp: Date.now(),\n };\n debouncedEmit(result);\n }\n }\n });\n } catch (error) {\n observer.error(error);\n }\n },\n onError: (error) => {\n observer.error(error);\n },\n onComplete: () => {\n observer.complete();\n },\n }\n );\n\n // Start subscription\n subscription = observable.subscribe({});\n })\n .catch((error) => {\n observer.error(error);\n });\n\n // Return cleanup function\n return () => {\n if (subscription) {\n subscription.unsubscribe();\n }\n };\n });\n }\n\n /**\n * Listen to query result changes\n */\n watchQuery(\n componentTypes: ComponentType[],\n options?: SubscriptionOptions\n ): Observable<QueryChangeResult> {\n const validTypes = componentTypes.filter(isValidComponentType);\n if (validTypes.length === 0) {\n return new Observable((observer: Observer<QueryChangeResult>) => {\n observer.error(\n new Error('No valid component types for query watching')\n );\n });\n }\n\n return new Observable((observer: Observer<QueryChangeResult>) => {\n const watcher = new QueryWatcherImpl(\n this.graphqlClient,\n validTypes,\n (changes: QueryChange) => {\n const result: QueryChangeResult = {\n changes,\n };\n\n if (options?.debounceMs) {\n const debouncedEmit = debounce(\n () => observer.next(result),\n options.debounceMs\n );\n debouncedEmit();\n } else {\n observer.next(result);\n }\n },\n options\n );\n\n // Return cleanup function\n return () => {\n watcher.dispose();\n };\n });\n }\n\n /**\n * Create real-time data stream\n */\n createRealTimeStream<T>(\n componentType: ComponentType,\n initialFilter?: Record<string, any>\n ): Observable<Array<{ entityId: EntityId; data: T }>> {\n if (!isValidComponentType(componentType)) {\n return new Observable(\n (observer: Observer<Array<{ entityId: EntityId; data: T }>>) => {\n observer.error(new Error(`Invalid component type: ${componentType}`));\n }\n );\n }\n\n return new Observable(\n (observer: Observer<Array<{ entityId: EntityId; data: T }>>) => {\n try {\n const subscription = this.graphqlClient.createRealTimeDataStream(\n componentType,\n { filter: initialFilter }\n );\n\n const streamSubscription = subscription.subscribe({\n next: (connection: any) => {\n const results = connection.edges\n .map((edge: any) => {\n const node = edge.node as any;\n const entityId =\n node.nodeId ||\n node.entityId ||\n Object.values(node)[0] ||\n '';\n return {\n entityId,\n data: node as T,\n };\n })\n .filter((result: any) => result.entityId);\n observer.next(results);\n },\n error: (error: any) => {\n observer.error(error);\n },\n complete: () => {\n observer.complete();\n },\n });\n\n // Return cleanup function\n return () => {\n streamSubscription.unsubscribe();\n };\n } catch (error) {\n observer.error(error);\n }\n }\n );\n }\n\n /**\n * Initialize known entity list (for deletion detection)\n */\n private async initializeLastKnownEntities(\n componentType: ComponentType,\n lastKnownEntities: Set<EntityId>\n ): Promise<void> {\n try {\n const connection = await this.graphqlClient.getAllTables(componentType, {\n fields: ['updatedAt'],\n });\n\n connection.edges.forEach((edge) => {\n const node = edge.node as any;\n const entityId = node.nodeId || node.entityId || Object.values(node)[0];\n if (entityId) {\n lastKnownEntities.add(entityId);\n }\n });\n } catch (error) {\n // Ignore error for now\n }\n }\n\n /**\n * Convert singular table name to plural form (using pluralize library for correctness)\n */\n private getPluralTableName(tableName: string): string {\n // First convert to camelCase\n const camelCaseName = this.toCamelCase(tableName);\n\n // Use pluralize library for pluralization\n return pluralize.plural(camelCaseName);\n }\n\n /**\n * Convert snake_case to camelCase\n */\n private toCamelCase(str: string): string {\n return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n }\n\n /**\n * Extract entity ID from node (using component's primary key field information)\n */\n private extractEntityId(node: any, componentType: ComponentType): string {\n if (!node || typeof node !== 'object') {\n return '';\n }\n\n // Use component's primary key field (consistent with query.ts)\n const primaryKeyField = this.getComponentPrimaryKeyField(componentType);\n\n // First try using primary key field\n if (node[primaryKeyField] && typeof node[primaryKeyField] === 'string') {\n return node[primaryKeyField];\n }\n\n // If primary key field doesn't exist, fallback to default entityId field\n if (\n primaryKeyField !== 'entityId' &&\n node.entityId &&\n typeof node.entityId === 'string'\n ) {\n return node.entityId;\n }\n\n // Finally try getting first string value as fallback\n const values = Object.values(node);\n for (const value of values) {\n if (typeof value === 'string' && value.length > 0) {\n return value;\n }\n }\n\n return '';\n }\n\n /**\n * Unsubscribe all subscriptions\n */\n unsubscribeAll(): void {\n // Unsubscribe regular subscriptions\n this.subscriptions.forEach((subscription) => {\n try {\n subscription?.unsubscribe();\n } catch (error) {\n // Ignore error for now\n }\n });\n this.subscriptions.clear();\n\n // Unsubscribe query watchers\n this.queryWatchers.forEach((watcher) => {\n try {\n watcher.dispose();\n } catch (error) {\n // Ignore error for now\n }\n });\n this.queryWatchers.clear();\n }\n\n /**\n * Dispose resources\n */\n dispose(): void {\n this.unsubscribeAll();\n }\n}\n\n/**\n * Query watcher implementation\n */\nclass QueryWatcherImpl {\n private graphqlClient: DubheGraphqlClient;\n private componentTypes: ComponentType[];\n private callback: QueryChangeCallback;\n private options?: SubscriptionOptions;\n private subscriptions: any[] = [];\n private currentResults: EntityId[] = [];\n private isInitialized = false;\n\n constructor(\n graphqlClient: DubheGraphqlClient,\n componentTypes: ComponentType[],\n callback: QueryChangeCallback,\n options?: SubscriptionOptions\n ) {\n this.graphqlClient = graphqlClient;\n this.componentTypes = componentTypes;\n this.callback = callback;\n this.options = options;\n this.initialize();\n }\n\n private async initialize(): Promise<void> {\n try {\n // Get initial results\n await this.updateCurrentResults();\n\n // Create subscription for each component type\n this.componentTypes.forEach((componentType) => {\n const observable = this.graphqlClient.subscribeToTableChanges(\n componentType,\n {\n initialEvent: false,\n onData: () => {\n // When data changes, recalculate results\n this.handleDataChange();\n },\n onError: (error) => {\n // Ignore error for now\n },\n }\n );\n\n // Start subscription\n const actualSubscription = observable.subscribe({});\n this.subscriptions.push(actualSubscription);\n });\n\n this.isInitialized = true;\n\n // Trigger initial event (if needed)\n if (this.options?.initialEvent && this.currentResults.length > 0) {\n this.callback({\n added: this.currentResults,\n removed: [],\n current: this.currentResults,\n });\n }\n } catch (error) {\n // Ignore error for now\n }\n }\n\n private async handleDataChange(): Promise<void> {\n if (!this.isInitialized) return;\n\n try {\n const oldResults = [...this.currentResults];\n await this.updateCurrentResults();\n\n const changes = calculateDelta(oldResults, this.currentResults);\n\n if (changes.added.length > 0 || changes.removed.length > 0) {\n const debouncedCallback = this.options?.debounceMs\n ? debounce(this.callback, this.options.debounceMs)\n : this.callback;\n\n debouncedCallback(changes);\n }\n } catch (error) {\n // Ignore error for now\n }\n }\n\n private async updateCurrentResults(): Promise<void> {\n try {\n if (this.componentTypes.length === 1) {\n // Single component query\n const connection = await this.graphqlClient.getAllTables(\n this.componentTypes[0],\n { fields: ['updatedAt'] }\n );\n this.currentResults = connection.edges\n .map((edge) => {\n const node = edge.node as any;\n return node.nodeId || node.entityId || Object.values(node)[0] || '';\n })\n .filter(Boolean);\n } else {\n // Multi-component query (intersection)\n const queries = this.componentTypes.map((type) => ({\n key: type,\n tableName: type,\n params: {\n fields: ['updatedAt'],\n filter: {},\n },\n }));\n\n const batchResult = await this.graphqlClient.batchQuery(queries);\n\n // Calculate intersection\n const entitySets = this.componentTypes.map((type) => {\n const connection = batchResult[type];\n return connection\n ? connection.edges\n .map((edge) => {\n const node = edge.node as any;\n return (\n node.nodeId || node.entityId || Object.values(node)[0] || ''\n );\n })\n .filter(Boolean)\n : [];\n });\n\n this.currentResults = entitySets.reduce((intersection, currentSet) => {\n const currentSetLookup = new Set(currentSet);\n return intersection.filter((id) => currentSetLookup.has(id));\n });\n }\n } catch (error) {\n this.currentResults = [];\n }\n }\n\n getCurrentResults(): EntityId[] {\n return [...this.currentResults];\n }\n\n dispose(): void {\n this.subscriptions.forEach((subscription) => {\n try {\n subscription?.unsubscribe();\n } catch (error) {\n // Ignore error for now\n }\n });\n this.subscriptions = [];\n }\n}\n","// ECS World main class implementation\n\nimport { DubheGraphqlClient } from '@0xobelisk/graphql-client';\nimport { ECSQuery } from './query';\nimport { ECSSubscription } from './subscription';\nimport {\n EntityId,\n ComponentType,\n QueryOptions,\n SubscriptionOptions,\n ComponentCallback,\n QueryChangeCallback,\n QueryWatcher,\n Unsubscribe,\n PagedResult,\n ECSWorldConfig,\n ComponentMetadata,\n ComponentDiscoveryResult,\n ComponentField,\n ResourceMetadata,\n ResourceDiscoveryResult,\n DubheMetadata,\n} from './types';\nimport { formatError } from './utils';\n\n/**\n * Component Discoverer - Supports DubheMetadata JSON format\n */\nexport class ComponentDiscoverer {\n private graphqlClient: DubheGraphqlClient;\n public dubheMetadata: DubheMetadata;\n public discoveryResult: ComponentDiscoveryResult;\n public componentMetadataMap = new Map<ComponentType, ComponentMetadata>();\n public componentTypes: ComponentType[] = [];\n\n constructor(graphqlClient: DubheGraphqlClient, dubheMetadata: DubheMetadata) {\n this.graphqlClient = graphqlClient;\n this.dubheMetadata = dubheMetadata;\n\n const components: ComponentMetadata[] = [];\n const errors: string[] = [];\n\n this.parseFromDubheMetadata(components, errors);\n\n const result: ComponentDiscoveryResult = {\n components,\n discoveredAt: Date.now(),\n errors: errors.length > 0 ? errors : undefined,\n totalDiscovered: components.length,\n fromDubheMetadata: true,\n };\n\n this.discoveryResult = result;\n this.componentTypes = components.map((comp) => comp.name);\n\n components.forEach((comp) => {\n this.componentMetadataMap.set(comp.name, comp);\n });\n }\n\n /**\n * Parse components from DubheMetadata JSON format\n */\n private parseFromDubheMetadata(\n components: ComponentMetadata[],\n errors: string[]\n ): void {\n if (!this.dubheMetadata?.components) {\n return;\n }\n\n for (const componentRecord of this.dubheMetadata.components) {\n for (const [componentName, componentConfig] of Object.entries(\n componentRecord\n )) {\n const componentType = this.tableNameToComponentName(componentName);\n\n try {\n const fields: ComponentField[] = [];\n const primaryKeys: string[] = [];\n const enumFields: string[] = [];\n\n if (componentConfig.fields && Array.isArray(componentConfig.fields)) {\n for (const fieldRecord of componentConfig.fields) {\n for (const [fieldName, fieldType] of Object.entries(\n fieldRecord\n )) {\n const camelFieldName = this.snakeToCamel(fieldName);\n const typeStr = String(fieldType);\n\n const isCustomKey =\n componentConfig.keys &&\n componentConfig.keys.includes(fieldName);\n\n fields.push({\n name: camelFieldName,\n type: this.dubheTypeToGraphQLType(typeStr),\n nullable: !isCustomKey,\n isPrimaryKey: isCustomKey,\n isEnum: this.isEnumType(typeStr),\n });\n\n if (isCustomKey) {\n primaryKeys.push(camelFieldName);\n }\n\n if (this.isEnumType(typeStr)) {\n enumFields.push(camelFieldName);\n }\n }\n }\n }\n\n // Add default entityId if no custom primary key\n if (primaryKeys.length === 0) {\n fields.unshift({\n name: 'entityId',\n type: 'String',\n nullable: false,\n isPrimaryKey: true,\n isEnum: false,\n });\n primaryKeys.push('entityId');\n }\n\n // Add system fields\n fields.push(\n {\n name: 'createdAt',\n type: 'String',\n nullable: false,\n isPrimaryKey: false,\n isEnum: false,\n },\n {\n name: 'updatedAt',\n type: 'String',\n nullable: false,\n isPrimaryKey: false,\n isEnum: false,\n }\n );\n\n // Only register as ECS component if it has a single primary key\n if (primaryKeys.length !== 1) {\n continue;\n }\n\n const metadata: ComponentMetadata = {\n name: componentType,\n tableName: componentName,\n fields,\n primaryKeys,\n hasDefaultId: primaryKeys.includes('entityId'),\n enumFields,\n lastUpdated: Date.now(),\n description: `Auto-discovered component: ${componentName}`,\n };\n\n components.push(metadata);\n } catch (error) {\n const errorMsg = `Component ${componentType} validation failed: ${formatError(error)}`;\n errors.push(errorMsg);\n }\n }\n }\n }\n\n getComponentTypes(): ComponentType[] {\n return this.componentTypes;\n }\n\n getComponentMetadata(componentType: ComponentType): ComponentMetadata | null {\n return this.componentMetadataMap.get(componentType) || null;\n }\n\n private snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n }\n\n private dubheTypeToGraphQLType(dubheType: string): string {\n if (dubheType.startsWith('vector<') && dubheType.endsWith('>')) {\n return 'String';\n }\n\n switch (dubheType) {\n case 'u8':\n case 'u16':\n case 'u32':\n case 'u64':\n case 'u128':\n case 'i8':\n case 'i16':\n case 'i32':\n case 'i64':\n case 'i128':\n return 'Int';\n case 'address':\n case 'string':\n return 'String';\n case 'bool':\n return 'Boolean';\n case 'enum':\n return 'String';\n default:\n return 'String';\n }\n }\n\n private componentNameToTableName(componentName: string): string {\n if (!componentName.endsWith('s')) {\n return componentName + 's';\n }\n return componentName;\n }\n\n private tableNameToComponentName(tableName: string): string {\n if (tableName.endsWith('s') && tableName.length > 1) {\n return tableName.slice(0, -1);\n }\n return tableName;\n }\n\n private isEnumType(typeStr: string): boolean {\n return this.dubheMetadata.enums.some(\n (enumDef: any) => typeof enumDef === 'object' && enumDef[typeStr]\n );\n }\n}\n\n/**\n * Resource Discoverer - Supports DubheMetadata JSON format\n */\nexport class ResourceDiscoverer {\n private graphqlClient: DubheGraphqlClient;\n public dubheMetadata: DubheMetadata;\n public discoveryResult: ResourceDiscoveryResult;\n public resourceMetadataMap = new Map<string, ResourceMetadata>();\n public resourceTypes: string[] = [];\n\n constructor(graphqlClient: DubheGraphqlClient, dubheMetadata: DubheMetadata) {\n this.graphqlClient = graphqlClient;\n this.dubheMetadata = dubheMetadata;\n\n const resources: ResourceMetadata[] = [];\n const errors: string[] = [];\n\n this.parseFromDubheMetadata(resources, errors);\n\n const result: ResourceDiscoveryResult = {\n resources,\n discoveredAt: Date.now(),\n errors: errors.length > 0 ? errors : undefined,\n totalDiscovered: resources.length,\n fromDubheMetadata: true,\n };\n\n this.discoveryResult = result;\n this.resourceTypes = resources.map((res) => res.name);\n\n resources.forEach((res) => {\n this.resourceMetadataMap.set(res.name, res);\n });\n }\n\n /**\n * Parse resources from DubheMetadata JSON format\n */\n private parseFromDubheMetadata(\n resources: ResourceMetadata[],\n errors: string[]\n ): void {\n if (!this.dubheMetadata?.resources) {\n return;\n }\n\n for (const resourceRecord of this.dubheMetadata.resources) {\n for (const [resourceName, resourceConfig] of Object.entries(\n resourceRecord\n )) {\n try {\n const fields: ComponentField[] = [];\n const primaryKeys: string[] = [];\n const enumFields: string[] = [];\n\n if (resourceConfig.fields && Array.isArray(resourceConfig.fields)) {\n for (const fieldRecord of resourceConfig.fields) {\n for (const [fieldName, fieldType] of Object.entries(\n fieldRecord\n )) {\n const camelFieldName = this.snakeToCamel(fieldName);\n const typeStr = String(fieldType);\n\n const isCustomKey =\n resourceConfig.keys &&\n resourceConfig.keys.includes(fieldName);\n\n fields.push({\n name: camelFieldName,\n type: this.dubheTypeToGraphQLType(typeStr),\n nullable: !isCustomKey,\n isPrimaryKey: isCustomKey,\n isEnum: this.isEnumType(typeStr),\n });\n\n if (isCustomKey) {\n primaryKeys.push(camelFieldName);\n }\n\n if (this.isEnumType(typeStr)) {\n enumFields.push(camelFieldName);\n }\n }\n }\n }\n\n // Add system fields\n fields.push(\n {\n name: 'createdAt',\n type: 'String',\n nullable: false,\n isPrimaryKey: false,\n isEnum: false,\n },\n {\n name: 'updatedAt',\n type: 'String',\n nullable: false,\n isPrimaryKey: false,\n isEnum: false,\n }\n );\n\n const resourceType = resourceName;\n const metadata: ResourceMetadata = {\n name: resourceType,\n tableName: resourceName,\n fields,\n primaryKeys,\n hasCompositeKeys: primaryKeys.length > 1,\n hasNoKeys: primaryKeys.length === 0,\n enumFields,\n lastUpdated: Date.now(),\n description: `Auto-discovered resource: ${resourceName}`,\n };\n\n resources.push(metadata);\n } catch (error) {\n const errorMsg = `Resource ${resourceName} validation failed: ${formatError(error)}`;\n errors.push(errorMsg);\n }\n }\n }\n }\n\n getResourceTypes(): string[] {\n return this.resourceTypes;\n }\n\n getResourceMetadata(resourceType: string): ResourceMetadata | null {\n return this.resourceMetadataMap.get(resourceType) || null;\n }\n\n private snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n }\n\n private dubheTypeToGraphQLType(dubheType: string): string {\n if (dubheType.startsWith('vector<') && dubheType.endsWith('>')) {\n return 'String';\n }\n\n switch (dubheType) {\n case 'u8':\n case 'u16':\n case 'u32':\n case 'u64':\n case 'u128':\n case 'i8':\n case 'i16':\n case 'i32':\n case 'i64':\n case 'i128':\n return 'Int';\n case 'address':\n case 'string':\n return 'String';\n case 'bool':\n return 'Boolean';\n case 'enum':\n return 'String';\n default:\n return 'String';\n }\n }\n\n private isEnumType(typeStr: string): boolean {\n return this.dubheMetadata.enums.some(\n (enumDef: any) => typeof enumDef === 'object' && enumDef[typeStr]\n );\n }\n}\n\n/**\n * ECS World - Main ECS world class\n */\nexport class DubheECSWorld {\n private graphqlClient: DubheGraphqlClient;\n private querySystem: ECSQuery;\n private subscriptionSystem: ECSSubscription;\n private componentDiscoverer: ComponentDiscoverer;\n private resourceDiscoverer: ResourceDiscoverer;\n private config: ECSWorldConfig;\n private dubheMetadata: DubheMetadata;\n\n constructor(\n graphqlClient: DubheGraphqlClient,\n config?: Partial<ECSWorldConfig>\n ) {\n this.graphqlClient = graphqlClient;\n\n this.config = {\n queryConfig: {\n defaultCacheTimeout: 5 * 60 * 1000,\n maxConcurrentQueries: 10,\n enableBatchOptimization: true,\n },\n subscriptionConfig: {\n defaultDebounceMs: 100,\n maxSubscriptions: 50,\n reconnectOnError: true,\n },\n ...config,\n };\n\n // Get dubheMetadata from config or GraphQL client\n let dubheMetadata = this.config.dubheMetadata;\n if (!dubheMetadata) {\n dubheMetadata = this.graphqlClient.getDubheMetadata();\n if (!dubheMetadata) {\n throw new Error(\n 'DubheMetadata is required for ECS World initialization. ' +\n 'Please provide it either in ECSWorldConfig or in GraphQL client configuration.'\n );\n }\n }\n\n this.dubheMetadata = dubheMetadata;\n\n // Initialize discoverers\n this.componentDiscoverer = new ComponentDiscoverer(\n graphqlClient,\n this.dubheMetadata\n );\n this.resourceDiscoverer = new ResourceDiscoverer(\n graphqlClient,\n this.dubheMetadata\n );\n\n // Initialize systems\n this.querySystem = new ECSQuery(graphqlClient, this.componentDiscoverer);\n this.subscriptionSystem = new ECSSubscription(\n graphqlClient,\n this.componentDiscoverer\n );\n\n this.initializeWithConfig();\n }\n\n private initializeWithConfig(): void {\n try {\n // Get ECS-compliant components (single primary key only)\n const ecsComponents =\n this.componentDiscoverer.discoveryResult.components.filter((comp) => {\n // Must have exactly one primary key to be ECS-compliant\n return comp.primaryKeys.length === 1;\n });\n\n // Get all resources\n const resources = this.resourceDiscoverer.discoveryResult.resources;\n\n // Initialize query system with ECS components and their metadata\n this.querySystem.setAvailableComponents(\n ecsComponents.map((comp) => comp.name)\n );\n\n // Initialize component primary key cache\n this.querySystem.initializeComponentMetadata(\n ecsComponents.map((comp) => ({\n name: comp.name,\n primaryKeys: comp.primaryKeys,\n }))\n );\n\n // Initialize subscription system with ECS components and metadata\n this.subscriptionSystem.setAvailableComponents(\n ecsComponents.map((comp) => comp.name)\n );\n\n // Initialize subscription system component metadata cache\n this.subscriptionSystem.initializeComponentMetadata(\n ecsComponents.map((comp) => ({\n name: comp.name,\n primaryKeys: comp.primaryKeys,\n }))\n );\n\n // Configure systems with settings\n if (this.config.queryConfig) {\n // Configure query system\n }\n\n if (this.config.subscriptionConfig) {\n // Configure subscription system\n }\n } catch (error) {\n throw new Error(`Failed to initialize ECS World: ${formatError(error)}`);\n }\n }\n\n // ============ Configuration and Initialization ============\n\n /**\n * Configure ECS world\n */\n configure(config: Partial<ECSWorldConfig>): void {\n this.config = { ...this.config, ...config };\n\n // Recreate component and resource discoverers if metadata changed\n if (config.dubheMetadata) {\n this.dubheMetadata = config.dubheMetadata;\n this.componentDiscoverer = new ComponentDiscoverer(\n this.graphqlClient,\n this.dubheMetadata\n );\n this.resourceDiscoverer = new ResourceDiscoverer(\n this.graphqlClient,\n this.dubheMetadata\n );\n\n // Update query and subscription systems\n this.querySystem.setComponentDiscoverer(this.componentDiscoverer);\n this.subscriptionSystem.setComponentDiscoverer(this.componentDiscoverer);\n\n this.initializeWithConfig();\n }\n }\n\n // ============ Component Discovery and Information ============\n\n /**\n * Discover and return all available ECS component types\n */\n discoverComponents(): ComponentType[] {\n return this.componentDiscoverer.getComponentTypes();\n }\n\n /**\n * Get all available ECS component types (cached)\n */\n getAvailableComponents(): ComponentType[] {\n return this.componentDiscoverer.getComponentTypes();\n }\n\n /**\n * Get metadata for a specific ECS component\n */\n getComponentMetadata(componentType: ComponentType): ComponentMetadata | null {\n return this.componentDiscoverer.getComponentMetadata(componentType);\n }\n\n // ============ Resource Discovery and Information ============\n\n /**\n * Get all available resource types\n */\n getAvailableResources(): string[] {\n return this.resourceDiscoverer.getResourceTypes();\n }\n\n /**\n * Get metadata for a specific resource\n */\n getResourceMetadata(resourceType: string): ResourceMetadata | null {\n return this.resourceDiscoverer.getResourceMetadata(resourceType);\n }\n\n // ============ Entity Queries ============\n\n /**\n * Check if entity exists\n */\n async hasEntity(entityId: EntityId): Promise<boolean> {\n return this.querySystem.hasEntity(entityId);\n }\n\n /**\n * Get all entity IDs\n */\n async getAllEntities(): Promise<EntityId[]> {\n return this.querySystem.getAllEntities();\n }\n\n /**\n * Get entity count\n */\n async getEntityCount(): Promise<number> {\n return this.querySystem.getEntityCount();\n }\n\n // ============ Standard ECS Interface (camelCase naming) ============\n\n /**\n * Get complete data of a single entity\n * @param entityId Entity ID\n * @returns Complete component data of the entity, or null if entity doesn't exist\n */\n async getEntity(entityId: EntityId): Promise<any | null> {\n try {\n // First check if entity exists\n const exists = await this.hasEntity(entityId);\n if (!exists) {\n return null;\n }\n\n // Get all components of the entity\n const componentTypes = await this.getComponents(entityId);\n if (componentTypes.length === 0) {\n return null;\n }\n\n // Get data for all components\n const entityData: Record<string, any> = {\n entityId,\n components: {},\n };\n\n for (const componentType of componentTypes) {\n const componentData = await this.getComponent(entityId, componentType);\n if (componentData) {\n entityData.components[componentType] = componentData;\n }\n }\n\n return entityData;\n } catch (error) {\n console.error(`Failed to get entity ${entityId}:`, formatError(error));\n return null;\n }\n }\n\n /**\n * Get all entity ID list\n * @returns Array of all entity IDs\n */\n async getEntities(): Promise<EntityId[]> {\n return this.getAllEntities();\n }\n\n /**\n * Get all entities that have a specific component\n * @param componentType Component type\n * @returns Array of entity IDs that have this component\n */\n async getEntitiesByComponent(\n componentType: ComponentType\n ): Promise<EntityId[]> {\n return this.queryWith(componentType);\n }\n\n // Note: getComponent, getComponents, hasComponent methods are defined below\n\n // ============ Component Queries ============\n\n /**\n * Check if entity has specific component\n */\n async hasComponent(\n entityId: EntityId,\n componentType: ComponentType\n ): Promise<boolean> {\n return this.querySystem.hasComponent(entityId, componentType);\n }\n\n /**\n * Get specific component data of entity\n */\n async getComponent<T>(\n entityId: EntityId,\n componentType: ComponentType\n ): Promise<T | null> {\n return this.querySystem.getComponent<T>(entityId, componentType);\n }\n\n /**\n * Get all component types that entity has\n */\n async getComponents(entityId: EntityId): Promise<ComponentType[]> {\n return this.querySystem.getComponents(entityId);\n }\n\n // ============ World Queries ============\n\n /**\n * Query all entities that have a specific component\n */\n async queryWith(\n componentType: ComponentType,\n options?: QueryOptions\n ): Promise<EntityId[]> {\n return this.querySystem.queryWith(componentType, options);\n }\n\n /**\n * Query entities that have all specified components (intersection)\n */\n async queryWithAll(\n componentTypes: ComponentType[],\n options?: QueryOptions\n ): Promise<EntityId[]> {\n return this.querySystem.queryWithAll(componentTypes, options);\n }\n\n /**\n * Query entities that have any of the specified components (union)\n */\n async queryWithAny(\n componentTypes: ComponentType[],\n options?: QueryOptions\n ): Promise<EntityId[]> {\n return this.querySystem.queryWithAny(componentTypes, options);\n }\n\n /**\n * Query entities that have include components but not exclude components\n */\n async queryWithout(\n includeTypes: ComponentType[],\n excludeTypes: ComponentType[],\n options?: QueryOptions\n ): Promise<EntityId[]> {\n return this.querySystem.queryWithout(includeTypes, excludeTypes, options);\n }\n\n // ============ Conditional Queries ============\n\n /**\n * Query components based on conditions\n */\n async queryWhere<T>(\n componentType: ComponentType,\n predicate: Record<string, any>,\n options?: QueryOptions\n ): Promise<EntityId[]> {\n return this.querySystem.queryWhere<T>(componentType, predicate, options);\n }\n\n /**\n * Range query\n */\n async queryRange(\n componentType: ComponentType,\n field: string,\n min: any,\n max: any,\n options?: QueryOptions\n ): Promise<EntityId[]> {\n return this.querySystem.queryRange(componentType, field, min, max, options);\n }\n\n /**\n * Paginated query\n */\n async queryPaged(\n componentTypes: ComponentType[],\n page: number,\n pageSize: number\n ): Promise<PagedResult<EntityId>> {\n return this.querySystem.queryPaged(componentTypes, page, pageSize);\n }\n\n // ============ Query Builder ============\n\n /**\n * Create query builder\n */\n query() {\n return this.querySystem.query();\n }\n\n // ============ Subscription System ============\n\n /**\n * Listen to component added events\n */\n onComponentAdded<T>(\n componentType: ComponentType,\n options?: SubscriptionOptions & { fields?: string[] }\n ) {\n return this.subscriptionSystem.onComponentAdded<T>(componentType, options);\n }\n\n /**\n * Listen to component removed events\n */\n onComponentRemoved<T>(\n componentType: ComponentType,\n options?: SubscriptionOptions & { fields?: string[] }\n ) {\n return this.subscriptionSystem.onComponentRemoved<T>(\n componentType,\n options\n );\n }\n\n /**\n * Listen to component changed events\n */\n onComponentChanged<T>(\n componentType: ComponentType,\n options?: SubscriptionOptions & { fields?: string[] }\n ) {\n return this.subscriptionSystem.onComponentChanged<T>(\n componentType,\n options\n );\n }\n\n /**\n * Listen to component changes with specific conditions\n */\n onComponentCondition<T>(\n componentType: ComponentType,\n filter: Record<string, any>,\n options?: SubscriptionOptions & { fields?: string[] }\n ) {\n return this.subscriptionSystem.onComponentCondition<T>(\n componentType,\n filter,\n options\n );\n }\n\n /**\n * Listen to query result changes\n */\n watchQuery(componentTypes: ComponentType[], options?: SubscriptionOptions) {\n return this.subscriptionSystem.watchQuery(componentTypes, options);\n }\n\n /**\n * Create real-time data stream\n */\n createRealTimeStream<T>(\n componentType: ComponentType,\n initialFilter?: Record<string, any>\n ) {\n return this.subscriptionSystem.createRealTimeStream<T>(\n componentType,\n initialFilter\n );\n }\n\n // ============ Convenience Methods ============\n\n /**\n * Query entity data with specific component (includes component data)\n */\n async queryWithComponentData<T>(\n componentType: ComponentType,\n options?: QueryOptions\n ): Promise<Array<{ entityId: EntityId; data: T }>> {\n try {\n const entityIds = await this.queryWith(componentType, options);\n const results: Array<{ entityId: EntityId; data: T }> = [];\n\n for (const entityId of entityIds) {\n const componentData = await this.getComponent<T>(\n entityId,\n componentType\n );\n if (componentData) {\n results.push({ entityId, data: componentData });\n }\n }\n\n return results;\n } catch (error) {\n return [];\n }\n }\n\n /**\n * Query multi-component entity data\n */\n async queryMultiComponentData<T1, T2>(\n component1Type: ComponentType,\n component2Type: ComponentType,\n options?: QueryOptions\n ): Promise<Array<{ entityId: EntityId; data1: T1; data2: T2 }>> {\n try {\n const entityIds = await this.queryWithAll(\n [component1Type, component2Type],\n options\n );\n const results: Array<{ entityId: EntityId; data1: T1; data2: T2 }> = [];\n\n for (const entityId of entityIds) {\n const [data1, data2] = await Promise.all([\n this.getComponent<T1>(entityId, component1Type),\n this.getComponent<T2>(entityId, component2Type),\n ]);\n\n if (data1 && data2) {\n results.push({ entityId, data1, data2 });\n }\n }\n\n return results;\n } catch (error) {\n return [];\n }\n }\n\n /**\n * Get complete entity state (all component data)\n */\n async getEntityState(entityId: EntityId): Promise<{\n entityId: EntityId;\n components: Record<ComponentType, any>;\n } | null> {\n try {\n const componentTypes = await this.getComponents(entityId);\n if (componentTypes.length === 0) return null;\n\n const components: Record<ComponentType, any> = {};\n\n for (const componentType of componentTypes) {\n const componentData = await this.getComponent(entityId, componentType);\n if (componentData) {\n components[componentType] = componentData;\n }\n }\n\n return { entityId, components };\n } catch (error) {\n return null;\n }\n }\n\n // ============ Statistics and Analysis ============\n\n /**\n * Get component statistics\n */\n async getComponentStats(): Promise<Record<ComponentType, number>> {\n try {\n const stats: Record<ComponentType, number> = {};\n\n // Get all available component types\n const componentTypes = await this.getAvailableComponents();\n\n await Promise.all(\n componentTypes.map(async (componentType) => {\n try {\n const entities = await this.queryWith(componentType);\n stats[componentType] = entities.length;\n } catch (error) {\n stats[componentType] = 0;\n }\n })\n );\n\n return stats;\n } catch (error) {\n return {};\n }\n }\n\n /**\n * Find orphan entities (entities with only one component)\n */\n async findOrphanEntities(): Promise<EntityId[]> {\n try {\n const allEntities = await this.getAllEntities();\n const orphanEntities: EntityId[] = [];\n\n for (const entityId of allEntities) {\n const components = await this.getComponents(entityId);\n if (components.length === 1) {\n orphanEntities.push(entityId);\n }\n }\n\n return orphanEntities;\n } catch (error) {\n return [];\n }\n }\n\n // ============ Resource Management ============\n\n /**\n * Unsubscribe all subscriptions\n */\n unsubscribeAll(): void {\n this.subscriptionSystem.unsubscribeAll();\n }\n\n /**\n * Clear all caches\n */\n clearCache(): void {\n this.querySystem.dispose();\n }\n\n /**\n * Dispose resources\n */\n dispose(): void {\n this.querySystem.dispose();\n this.subscriptionSystem.dispose();\n }\n\n // ============ Get Underlying Clients ============\n\n /**\n * Get GraphQL client (for advanced operations)\n */\n getGraphQLClient(): DubheGraphqlClient {\n return this.graphqlClient;\n }\n\n /**\n * Get query system (for advanced query operations)\n */\n getQuerySystem(): ECSQuery {\n return this.querySystem;\n }\n\n /**\n * Get subscription system (for advanced subscription operations)\n */\n getSubscriptionSystem(): ECSSubscription {\n return this.subscriptionSystem;\n }\n\n /**\n * Get ECS world configuration\n */\n getConfig(): ECSWorldConfig {\n return { ...this.config };\n }\n\n /**\n * Get dubhe metadata info (JSON format)\n */\n getDubheMetadata(): DubheMetadata {\n return this.dubheMetadata;\n }\n\n // ============ Resource Queries ============\n\n /**\n * Query resource by primary keys\n */\n async getResource<T>(\n resourceType: string,\n keyValues?: Record<string, any>,\n options?: QueryOptions\n ): Promise<T | null> {\n try {\n // Verify if it's a known resource type\n const resourceMetadata =\n this.resourceDiscoverer.getResourceMetadata(resourceType);\n if (!resourceMetadata) {\n return null;\n }\n keyValues = keyValues || {};\n\n // Build where condition for keys\n const whereConditions: Record<string, any> = {};\n for (const [key, value] of Object.entries(keyValues)) {\n whereConditions[key] = { equalTo: value };\n }\n\n const result = await this.graphqlClient.getAllTables(resourceType, {\n first: 1,\n filter: whereConditions,\n fields: options?.fields || resourceMetadata.fields.map((f) => f.name),\n ...options,\n });\n\n const record = result.edges[0]?.node;\n return record ? (record as T) : null;\n } catch (error) {\n return null;\n }\n }\n\n /**\n * Query multiple resources\n */\n async getResources<T>(\n resourceType: string,\n filters?: Record<string, any>,\n options?: QueryOptions\n ): Promise<T[]> {\n try {\n // Verify if it's a known resource type\n const resourceMetadata =\n this.resourceDiscoverer.getResourceMetadata(resourceType);\n if (!resourceMetadata) {\n return [];\n }\n\n // Build where condition\n const whereConditions: Record<string, any> = {};\n if (filters) {\n for (const [key, value] of Object.entries(filters)) {\n if (typeof value === 'object' && value !== null) {\n // If value is already a filter object, use it directly\n whereConditions[key] = value;\n } else {\n // Otherwise, wrap in equalTo\n whereConditions[key] = { equalTo: value };\n }\n }\n }\n\n const result = await this.graphqlClient.getAllTables(resourceType, {\n filter:\n Object.keys(whereConditions).length > 0 ? whereConditions : undefined,\n fields: options?.fields || resourceMetadata.fields.map((f) => f.name),\n ...options,\n });\n\n const records = result.edges.map((edge) => edge.node as T);\n return records;\n } catch (error) {\n return [];\n }\n }\n\n /**\n * Get all resources of a specific type\n */\n async getAllResources<T>(\n resourceType: string,\n options?: QueryOptions\n ): Promise<T[]> {\n return this.getResources<T>(resourceType, undefined, options);\n }\n\n /**\n * Check if a resource exists\n */\n async hasResource(\n resourceType: string,\n keyValues: Record<string, any>\n ): Promise<boolean> {\n const resource = await this.getResource(resourceType, keyValues);\n return resource !== null;\n }\n\n /**\n * Get resource count\n */\n async getResourceCount(resourceType: string): Promise<number> {\n try {\n const result = await this.graphqlClient.getAllTables(resourceType, {\n first: 1, // Only need count, not actual data\n });\n return result.totalCount || 0;\n } catch (error) {\n return 0;\n }\n }\n\n /**\n * Subscribe to resource changes\n */\n subscribeToResourceChanges<T>(\n resourceType: string,\n options?: SubscriptionOptions & {\n fields?: string[];\n initialEvent?: boolean;\n filter?: Record<string, any>;\n }\n ) {\n // Verify if it's a known resource type\n const resourceMetadata =\n this.resourceDiscoverer.getResourceMetadata(resourceType);\n if (!resourceMetadata) {\n throw new Error(\n `Unknown resource type: ${resourceType}. Available resources: [${this.getAvailableResources().join(', ')}]`\n );\n }\n\n const subscriptionFields =\n options?.fields || resourceMetadata.fields.map((f) => f.name);\n\n return this.graphqlClient.subscribeToFilteredTableChanges(\n resourceType,\n options?.filter,\n {\n ...options,\n fields: subscriptionFields,\n }\n );\n }\n}\n\n/**\n * Factory function to create ECS world instance\n */\nexport function createECSWorld(\n graphqlClient: DubheGraphqlClient,\n config?: Partial<ECSWorldConfig>\n): DubheECSWorld {\n return new DubheECSWorld(graphqlClient, config);\n}\n"],"mappings":"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","names":["pluralize"]}