@codehz/ecs 0.10.1 → 0.10.2

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.
@@ -1114,44 +1114,43 @@ declare class World {
1114
1114
  */
1115
1115
  exists(entityId: EntityId): boolean;
1116
1116
  /**
1117
- * Adds or updates a component on an entity (or marks void component as present).
1117
+ * Marks a void component as present on an entity.
1118
1118
  * The change is buffered and takes effect after calling `world.sync()`.
1119
- * If the entity does not exist, throws an error.
1120
1119
  *
1121
- * @overload set(entityId: EntityId, componentType: EntityId<void>): void
1122
- * Marks a void component as present on the entity
1120
+ * @throws {Error} If the entity does not exist
1121
+ * @throws {Error} If the component type is invalid or is a wildcard relation
1123
1122
  *
1124
- * @overload set<T>(componentId: ComponentId<T>, component: Exclude<NoInfer<T>, number>): void
1123
+ * @example
1124
+ * world.set(entity, Marker);
1125
+ * world.sync();
1126
+ */
1127
+ set(entityId: EntityId, componentType: EntityId<void>): void;
1128
+ /**
1125
1129
  * @deprecated Use `world.singleton(componentId).set(value)` or `world.set(componentId, componentId, value)` instead.
1126
- * Compatibility shorthand for singleton component data when the second argument is not a number
1130
+ * Compatibility shorthand for singleton component data when the second argument is not a number.
1127
1131
  *
1128
- * @overload set<T>(entityId: EntityId, componentType: EntityId<T>, component: NoInfer<T>): void
1129
- * Adds or updates a component with data on the entity
1132
+ * @throws {Error} If the component entity does not exist
1133
+ *
1134
+ * @example
1135
+ * world.set(GlobalConfig, { debug: true });
1136
+ * world.sync();
1137
+ */
1138
+ set<T>(componentId: ComponentId<T>, component: Exclude<NoInfer<T>, number>): void;
1139
+ /**
1140
+ * Adds or updates component data on an entity.
1141
+ * The change is buffered and takes effect after calling `world.sync()`.
1130
1142
  *
1131
1143
  * @throws {Error} If the entity does not exist
1132
1144
  * @throws {Error} If the component type is invalid or is a wildcard relation
1133
1145
  *
1134
1146
  * @example
1135
1147
  * world.set(entity, Position, { x: 10, y: 20 });
1136
- * world.set(entity, Marker); // void component
1137
- * world.singleton(GlobalConfig).set({ debug: true }); // singleton component
1138
- * world.set(GlobalConfig, { debug: true }); // deprecated singleton compatibility shorthand
1139
- * world.sync(); // Apply changes
1148
+ * world.sync();
1140
1149
  */
1141
- set(entityId: EntityId, componentType: EntityId<void>): void;
1142
- /** @deprecated Use `world.singleton(componentId).set(value)` or `world.set(componentId, componentId, value)` instead. */
1143
- set<T>(componentId: ComponentId<T>, component: Exclude<NoInfer<T>, number>): void;
1144
1150
  set<T>(entityId: EntityId, componentType: EntityId<T>, component: NoInfer<T>): void;
1145
1151
  /**
1146
1152
  * Removes a component from an entity.
1147
1153
  * The change is buffered and takes effect after calling `world.sync()`.
1148
- * If the entity does not exist, throws an error.
1149
- *
1150
- * @overload remove<T>(entityId: EntityId, componentType: EntityId<T>): void
1151
- * Removes a component from an entity.
1152
- *
1153
- * @overload remove<T>(componentId: ComponentId<T>): void
1154
- * Removes a singleton component (shorthand for remove(componentId, componentId)).
1155
1154
  *
1156
1155
  * @template T - The component data type
1157
1156
  * @param entityId - The entity identifier
@@ -1162,11 +1161,22 @@ declare class World {
1162
1161
  *
1163
1162
  * @example
1164
1163
  * world.remove(entity, Position);
1164
+ * world.sync(); // Apply changes
1165
+ */
1166
+ remove<T>(entityId: EntityId, componentType: EntityId<T>): void;
1167
+ /**
1168
+ * Removes a singleton component (shorthand for remove(componentId, componentId)).
1169
+ * The change is buffered and takes effect after calling `world.sync()`.
1170
+ *
1171
+ * @template T - The component data type
1172
+ *
1173
+ * @throws {Error} If the component entity does not exist
1174
+ *
1175
+ * @example
1165
1176
  * world.remove(GlobalConfig); // Remove singleton component
1166
1177
  * world.sync(); // Apply changes
1167
1178
  */
1168
1179
  remove<T>(componentId: ComponentId<T>): void;
1169
- remove<T>(entityId: EntityId, componentType: EntityId<T>): void;
1170
1180
  /**
1171
1181
  * Deletes an entity and all its components from the world.
1172
1182
  * The change is buffered and takes effect after calling `world.sync()`.
@@ -1200,15 +1210,8 @@ declare class World {
1200
1210
  *
1201
1211
  * Immediately reflects the current state without waiting for `sync()`.
1202
1212
  *
1203
- * @overload has<T>(entityId: EntityId, componentType: EntityId<T>): boolean
1204
- * Checks if a specific component type is present on the entity.
1205
- *
1206
- * @overload has<T>(componentId: ComponentId<T>): boolean
1207
- * Shorthand for checking a **singleton component** — a component that is its own
1208
- * entity (component-as-entity pattern). Equivalent to `has(componentId, componentId)`.
1209
- *
1210
1213
  * @template T - The component data type
1211
- * @param entityId - The entity identifier, or a singleton component ID
1214
+ * @param entityId - The entity identifier
1212
1215
  * @param componentType - The component type to check
1213
1216
  * @returns `true` if the entity has the component, `false` otherwise
1214
1217
  *
@@ -1217,55 +1220,73 @@ declare class World {
1217
1220
  * if (world.has(entity, Position)) {
1218
1221
  * const pos = world.get(entity, Position);
1219
1222
  * }
1223
+ */
1224
+ has<T>(entityId: EntityId, componentType: EntityId<T>): boolean;
1225
+ /**
1226
+ * Checks if a **singleton component** (component-as-entity) is present.
1227
+ * Equivalent to `has(componentId, componentId)`.
1220
1228
  *
1221
- * // Check a singleton component (component-as-entity)
1229
+ * Immediately reflects the current state without waiting for `sync()`.
1230
+ *
1231
+ * @template T - The component data type
1232
+ * @param componentId - The singleton component ID
1233
+ * @returns `true` if the singleton component exists, `false` otherwise
1234
+ *
1235
+ * @example
1222
1236
  * if (world.has(GlobalConfig)) {
1223
1237
  * const config = world.get(GlobalConfig);
1224
1238
  * }
1225
- *
1226
- * // Use exists() for entity liveness checks
1227
- * if (world.exists(entity)) { ... }
1228
1239
  */
1229
1240
  has<T>(componentId: ComponentId<T>): boolean;
1230
- has<T>(entityId: EntityId, componentType: EntityId<T>): boolean;
1231
1241
  /**
1232
1242
  * Retrieves a component from an entity.
1233
- * For wildcard relations, returns all relations of that type.
1234
1243
  * Throws an error if the component does not exist; use `has()` to check first or use `getOptional()`.
1235
1244
  *
1236
- * @overload get<T>(entityId: EntityId<T>): T
1237
- * When called with only an entity ID, retrieves the entity's primary component.
1245
+ * @template T - The component data type
1246
+ * @param entityId - The entity identifier
1247
+ * @param componentType - The component type to retrieve
1238
1248
  *
1239
- * @overload get<T>(entityId: EntityId, componentType: WildcardRelationId<T>): [EntityId<unknown>, T][]
1240
- * For wildcard relations, returns an array of [target entity, component value] pairs.
1249
+ * @throws {Error} If the entity does not exist
1250
+ * @throws {Error} If the component does not exist on the entity
1241
1251
  *
1242
- * @overload get<T>(entityId: EntityId, componentType: EntityId<T>): T
1243
- * Retrieves a specific component from the entity.
1252
+ * @example
1253
+ * const position = world.get(entity, Position);
1254
+ */
1255
+ get<T>(entityId: EntityId, componentType: EntityId<T>): T;
1256
+ /**
1257
+ * Retrieves all relations of a given wildcard type for an entity.
1258
+ * Returns an array of [target entity, component value] pairs.
1259
+ *
1260
+ * @template T - The component data type
1261
+ * @param entityId - The entity identifier
1262
+ * @param componentType - The wildcard relation type
1263
+ * @returns Array of [target entity, component value] pairs
1244
1264
  *
1245
1265
  * @throws {Error} If the entity does not exist
1246
- * @throws {Error} If the component does not exist on the entity
1247
1266
  *
1248
1267
  * @example
1249
- * const position = world.get(entity, Position); // Throws if no Position
1250
- * const relations = world.get(entity, relation(Parent, "*")); // Wildcard relation
1268
+ * const relations = world.get(entity, relation(Parent, "*"));
1251
1269
  */
1252
- get<T>(entityId: EntityId<T>): T;
1253
1270
  get<T>(entityId: EntityId, componentType: WildcardRelationId<T>): [EntityId<unknown>, T][];
1254
- get<T>(entityId: EntityId, componentType: EntityId<T>): T;
1255
1271
  /**
1256
- * Safely retrieves a component from an entity without throwing an error.
1257
- * Returns `undefined` if the component does not exist.
1258
- * For wildcard relations, returns `undefined` if there are no relations.
1272
+ * Retrieves the entity's primary component when called with only an entity ID.
1259
1273
  *
1260
1274
  * @template T - The component data type
1261
- * @overload getOptional<T>(entityId: EntityId<T>): { value: T } | undefined
1262
- * Retrieves the entity's primary component safely.
1275
+ * @param entityId - The entity identifier
1276
+ * @returns The component value
1263
1277
  *
1264
- * @overload getOptional<T>(entityId: EntityId, componentType: WildcardRelationId<T>): { value: [EntityId<unknown>, T][] } | undefined
1265
- * Retrieves all matching relation values safely.
1278
+ * @throws {Error} If the entity does not exist
1279
+ * @throws {Error} If the component does not exist on the entity
1280
+ */
1281
+ get<T>(entityId: EntityId<T>): T;
1282
+ /**
1283
+ * Safely retrieves a component from an entity without throwing an error.
1284
+ * Returns `undefined` if the component does not exist.
1266
1285
  *
1267
- * @overload getOptional<T>(entityId: EntityId, componentType: EntityId<T>): { value: T } | undefined
1268
- * Retrieves a specific component safely.
1286
+ * @template T - The component data type
1287
+ * @param entityId - The entity identifier
1288
+ * @param componentType - The component type to retrieve
1289
+ * @returns The component value wrapped in `{ value }`, or `undefined` if absent
1269
1290
  *
1270
1291
  * @throws {Error} If the entity does not exist
1271
1292
  *
@@ -1275,13 +1296,34 @@ declare class World {
1275
1296
  * console.log(position.value.x);
1276
1297
  * }
1277
1298
  */
1278
- getOptional<T>(entityId: EntityId<T>): {
1299
+ getOptional<T>(entityId: EntityId, componentType: EntityId<T>): {
1279
1300
  value: T;
1280
1301
  } | undefined;
1302
+ /**
1303
+ * Safely retrieves all matching relation values for a wildcard relation type.
1304
+ * Returns `undefined` if there are no relations.
1305
+ *
1306
+ * @template T - The component data type
1307
+ * @param entityId - The entity identifier
1308
+ * @param componentType - The wildcard relation type
1309
+ * @returns Array of [target, value] pairs wrapped in `{ value }`, or `undefined` if none
1310
+ *
1311
+ * @throws {Error} If the entity does not exist
1312
+ */
1281
1313
  getOptional<T>(entityId: EntityId, componentType: WildcardRelationId<T>): {
1282
1314
  value: [EntityId<unknown>, T][];
1283
1315
  } | undefined;
1284
- getOptional<T>(entityId: EntityId, componentType: EntityId<T>): {
1316
+ /**
1317
+ * Safely retrieves the entity's primary component without throwing an error.
1318
+ * Returns `undefined` if the component does not exist.
1319
+ *
1320
+ * @template T - The component data type
1321
+ * @param entityId - The entity identifier
1322
+ * @returns The component value wrapped in `{ value }`, or `undefined` if absent
1323
+ *
1324
+ * @throws {Error} If the entity does not exist
1325
+ */
1326
+ getOptional<T>(entityId: EntityId<T>): {
1285
1327
  value: T;
1286
1328
  } | undefined;
1287
1329
  /**
@@ -1386,21 +1428,15 @@ declare class World {
1386
1428
  }): void;
1387
1429
  /**
1388
1430
  * Registers a lifecycle hook that responds to component changes.
1389
- * The hook callback is invoked when components matching the specified types are added, updated, or removed.
1390
- * @overload hook<const T extends readonly ComponentType<any>[]>(
1391
- * componentTypes: T,
1392
- * hook: LifecycleHook<T> | LifecycleCallback<T>,
1393
- * filter?: QueryFilter,
1394
- * ): () => void
1395
- * Registers a hook for multiple component types.
1396
- * The hook is triggered when entities enter/exit the matching set.
1431
+ * The hook callback is invoked when components matching the specified types
1432
+ * are added, updated, or removed.
1397
1433
  *
1398
1434
  * @param componentTypes - Component types that define the matching entity set
1399
1435
  * @param hook - Either a hook object with on_init/on_set/on_remove handlers, or a callback function
1400
1436
  * @param filter - Optional query-style filter applied to the hook match set
1401
1437
  * @returns A function that unsubscribes the hook when called
1402
1438
  *
1403
- * @throws {Error} If no required components are specified in array overload
1439
+ * @throws {Error} If no required components are specified
1404
1440
  *
1405
1441
  * @example
1406
1442
  * const unsubscribe = world.hook([Position, Velocity], {
@@ -1535,32 +1571,30 @@ declare class World {
1535
1571
  getMatchingArchetypes(componentTypes: EntityId<any>[]): Archetype[];
1536
1572
  /**
1537
1573
  * Queries entities with specific components.
1538
- * For simpler use cases, prefer using `createQuery()` with `forEach()` which is cached and more efficient.
1539
- *
1540
- * @overload query(componentTypes: EntityId<any>[]): EntityId[]
1541
1574
  * Returns an array of entity IDs that have all specified components.
1542
- *
1543
- * @overload query<const T extends readonly EntityId<any>[]>(
1544
- * componentTypes: T,
1545
- * includeComponents: true,
1546
- * ): Array<{ entity: EntityId; components: ComponentTuple<T> }>
1547
- * Returns entities along with their component data.
1575
+ * For simpler use cases, prefer using `createQuery()` with `forEach()` which is cached and more efficient.
1548
1576
  *
1549
1577
  * @param componentTypes - Array of component types to query
1550
- * @param includeComponents - If true, includes component data in results
1551
- * @returns Array of entity IDs or objects with entities and components
1578
+ * @returns Array of entity IDs matching the query
1552
1579
  *
1553
1580
  * @example
1554
- * // Just entity IDs
1555
1581
  * const entities = world.query([Position, Velocity]);
1582
+ */
1583
+ query(componentTypes: EntityId<any>[]): EntityId[];
1584
+ /**
1585
+ * Queries entities with specific components and returns their component data.
1586
+ *
1587
+ * @template T - The tuple of component types
1588
+ * @param componentTypes - Array of component types to query
1589
+ * @param includeComponents - Must be `true` to include component data
1590
+ * @returns Array of objects with entity and component data
1556
1591
  *
1557
- * // With components
1592
+ * @example
1558
1593
  * const results = world.query([Position, Velocity], true);
1559
1594
  * results.forEach(({ entity, components: [pos, vel] }) => {
1560
1595
  * pos.x += vel.x;
1561
1596
  * });
1562
1597
  */
1563
- query(componentTypes: EntityId<any>[]): EntityId[];
1564
1598
  query<const T extends readonly EntityId<any>[]>(componentTypes: T, includeComponents: true): Array<{
1565
1599
  entity: EntityId;
1566
1600
  components: ComponentTuple<T>;
package/dist/world.mjs CHANGED
@@ -3107,6 +3107,7 @@ var World = class World {
3107
3107
  if (this.componentEntities.exists(entityId)) return true;
3108
3108
  return this.entityToArchetype.has(entityId);
3109
3109
  }
3110
+ /** Internal implementation for `set()` overloads. */
3110
3111
  set(entityId, componentTypeOrComponent, maybeComponent) {
3111
3112
  const { entityId: targetEntityId, componentType, component, deprecatedSingletonShorthand } = resolveSetOperation(entityId, componentTypeOrComponent, maybeComponent, arguments.length, (id) => this.exists(id));
3112
3113
  if (deprecatedSingletonShorthand) console.warn(World.DEPRECATED_SINGLETON_SET_SHORTHAND_WARNING);