@vworlds/vecs 1.0.10 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +218 -229
  2. package/dist/command.d.ts +1 -46
  3. package/dist/component.d.ts +51 -59
  4. package/dist/component.js +31 -25
  5. package/dist/component.js.map +1 -1
  6. package/dist/dsl.d.ts +34 -26
  7. package/dist/dsl.js +46 -20
  8. package/dist/dsl.js.map +1 -1
  9. package/dist/entity.d.ts +96 -106
  10. package/dist/entity.js +261 -190
  11. package/dist/entity.js.map +1 -1
  12. package/dist/filter.d.ts +31 -23
  13. package/dist/filter.js +24 -17
  14. package/dist/filter.js.map +1 -1
  15. package/dist/index.d.ts +1 -1
  16. package/dist/package.json +3 -1
  17. package/dist/phase.d.ts +5 -28
  18. package/dist/phase.js +11 -10
  19. package/dist/phase.js.map +1 -1
  20. package/dist/query.d.ts +107 -144
  21. package/dist/query.js +200 -169
  22. package/dist/query.js.map +1 -1
  23. package/dist/system.d.ts +59 -87
  24. package/dist/system.js +114 -114
  25. package/dist/system.js.map +1 -1
  26. package/dist/util/array_map.d.ts +4 -55
  27. package/dist/util/array_map.js +35 -37
  28. package/dist/util/array_map.js.map +1 -1
  29. package/dist/util/bitset.d.ts +40 -50
  30. package/dist/util/bitset.js +76 -62
  31. package/dist/util/bitset.js.map +1 -1
  32. package/dist/util/events.d.ts +14 -18
  33. package/dist/util/events.js +24 -3
  34. package/dist/util/events.js.map +1 -1
  35. package/dist/util/ordered_set.d.ts +1 -17
  36. package/dist/util/ordered_set.js +74 -25
  37. package/dist/util/ordered_set.js.map +1 -1
  38. package/dist/world.d.ts +212 -224
  39. package/dist/world.js +368 -330
  40. package/dist/world.js.map +1 -1
  41. package/eslint-rules/internal-underscore.js +60 -0
  42. package/eslint.config.js +5 -0
  43. package/package.json +3 -1
package/dist/entity.d.ts CHANGED
@@ -1,202 +1,192 @@
1
1
  import { Component } from "./component.js";
2
2
  import type { World } from "./world.js";
3
- import { type Query } from "./query.js";
3
+ import { ReadonlyArrayMap } from "./util/array_map.js";
4
4
  import { Events } from "./util/events.js";
5
5
  import { Bitset } from "./util/bitset.js";
6
6
  type EntityEvents = Events<{
7
7
  destroy(): void;
8
8
  }>;
9
9
  /**
10
- * A game object a unique identifier with an arbitrary set of
11
- * {@link Component | components} attached to it.
10
+ * A game object: a unique numeric id with an arbitrary set of
11
+ * {@link Component | components} attached.
12
12
  *
13
- * You never construct an `Entity` directly. Use {@link World.entity} to create
14
- * one, or {@link World.getOrCreateEntity} when the id is assigned by an
15
- * external authority (e.g. the server):
13
+ * Never instantiate `Entity` directly. Use {@link World.entity} for an
14
+ * auto-assigned id, or {@link World.getOrCreateEntity} when the id comes from
15
+ * an external authority such as a game server:
16
16
  *
17
17
  * ```ts
18
18
  * const e = world.entity();
19
19
  * e.set(Position, { x: 100 });
20
20
  * ```
21
21
  *
22
- * Entities support a parent–child hierarchy. When a parent is destroyed its
23
- * children are destroyed recursively. The `children` set is created lazily.
22
+ * Entities support a parent–child hierarchy. `parent` and `children` form a
23
+ * bidirectional link maintained by {@link setParent}; the children set is
24
+ * created lazily. Destroying a parent recursively destroys its children.
24
25
  *
25
26
  * ## Deferred semantics
26
27
  *
27
28
  * Inside a system body or `forEach` iteration the world is in **deferred
28
- * mode**: `add` / `set` / `remove` / `destroy` only enqueue commands; the
29
- * data layer (`components` map, `componentBitmask`) is not mutated until the
30
- * world processes the queue. Concretely, inside deferred mode:
29
+ * mode**: `add` / `set` / `modified` / `remove` / `destroy` / `setParent` only
30
+ * enqueue commands. The data layer (the components map and `componentBitmask`)
31
+ * is mutated when the world drains its queue. Concretely, while deferred:
31
32
  *
32
33
  * - `entity.get(C)` returns `undefined` after `entity.add(C)` (no instance yet).
33
34
  * - `entity.get(C)` returns the previous value after `entity.set(C, props)`.
34
35
  * - `entity.get(C)` still returns the component after `entity.remove(C)`.
35
36
  *
36
- * Outside deferred mode (top-level user code) the same calls execute inline
37
- * mutations are visible immediately.
37
+ * Outside deferred mode the same calls execute inline and mutations are
38
+ * visible immediately.
38
39
  */
39
40
  export declare class Entity {
40
- /** The {@link World} that owns this entity. */
41
+ /** World that owns this entity. */
41
42
  readonly world: World;
42
- /** Unique numeric entity id assigned at creation time. */
43
+ /** Unique numeric entity id assigned at creation. */
43
44
  readonly eid: number;
44
- private components;
45
45
  /**
46
- * Bitmask representing the set of component types currently attached to this
47
- * entity. Used by the world to efficiently match entities against query
48
- * predicates.
46
+ * Bitmask of component type ids currently attached to this entity. Used by
47
+ * the world for fast archetype matching against query predicates.
49
48
  */
50
49
  readonly componentBitmask: Bitset;
51
- private readonly queries;
52
50
  /**
53
- * A free-form property bag that modules can use to associate arbitrary data
54
- * with an entity without registering a component.
51
+ * Free-form property bag. Modules can use it to associate arbitrary data with
52
+ * an entity without registering a dedicated component.
55
53
  */
56
54
  properties: Map<string, any>;
57
- _events: EntityEvents;
58
- private _parent;
59
- private _children;
60
- /** @internal True once the world has fully processed this entity's destruction. */
61
- _destroyed: boolean;
62
- private static readonly _emptyChildren;
63
55
  constructor(
64
- /** The {@link World} that owns this entity. */
56
+ /** World that owns this entity. */
65
57
  world: World,
66
- /** Unique numeric entity id assigned at creation time. */
58
+ /** Unique numeric entity id assigned at creation. */
67
59
  eid: number);
68
- /** Parent entity in the scene hierarchy, or `undefined` if this is a root entity. */
60
+ /**
61
+ * Re-evaluate every world query for this entity, firing `_enter` / `_exit`
62
+ * routing whenever membership flipped.
63
+ */
64
+ private _updateQueries;
65
+ /**
66
+ * Construct a fresh component of `type`, apply `props`, store it on this
67
+ * entity, fire the `onAdd` hook, and route query updates.
68
+ *
69
+ * If the component type belongs to an exclusivity group, any conflicting
70
+ * component already on this entity is removed first.
71
+ */
72
+ private _new;
73
+ /** Parent entity in the scene hierarchy, or `undefined` for a root entity. */
69
74
  get parent(): Entity | undefined;
70
- /** Read-only view of direct child entities. */
75
+ /**
76
+ * Read-only view of direct child entities. The backing set is created lazily
77
+ * on the first child link; before that this getter returns a shared empty set.
78
+ */
71
79
  get children(): ReadonlySet<Entity>;
72
80
  /**
73
- * Immediately reparent this entity. Maintains the bidirectional link,
74
- * removes it from the old parent's children, and adds it to the new
75
- * parent's children. Throws if the operation would create a cycle.
81
+ * Typed event emitter for entity-level lifecycle events. Currently only the
82
+ * `"destroy"` event is emitted, just before the entity is fully torn down.
83
+ *
84
+ * The emitter is created lazily on first access.
85
+ */
86
+ get events(): EntityEvents;
87
+ /** `true` when no components are currently attached to this entity. */
88
+ get empty(): boolean;
89
+ /**
90
+ * Read-only view of all components currently attached to this entity, keyed
91
+ * by numeric component type id.
92
+ *
93
+ * The mutating methods (`set`, `delete`, `clear`) are not exposed. Use
94
+ * `entity.add`, `entity.set`, and `entity.remove` to change the component
95
+ * set.
96
+ *
97
+ * ```ts
98
+ * entity.components.forEach((c) => console.log(c.constructor.name));
99
+ * ```
76
100
  */
77
- _setParent(newParent: Entity | undefined): void;
101
+ get components(): ReadonlyArrayMap<Component>;
78
102
  /**
79
103
  * Reparent this entity. In deferred mode the change is queued; outside
80
- * deferred mode it executes immediately.
104
+ * deferred mode it executes inline.
105
+ *
106
+ * @param newParent - New parent, or `undefined` to make this a root entity.
81
107
  */
82
108
  setParent(newParent: Entity | undefined): void;
83
109
  /**
84
- * Queue an `onSet` / `update` notification for the given component and
85
- * return the entity for chaining.
110
+ * Mark `c` as having changed, queueing the corresponding `onSet` / `update`
111
+ * notifications.
86
112
  *
87
- * Equivalent to `component.modified()`, but usable inside an entity method
88
- * chain (e.g. after `add` or `set`).
113
+ * Equivalent to `c.modified()` but returns the entity for chaining. Repeated
114
+ * calls before the world routes the modified command are coalesced via the
115
+ * component's dirty flag.
89
116
  *
90
- * @param c - The component instance whose data changed.
117
+ * @param c - Component instance whose data changed.
91
118
  * @returns This entity, for chaining.
92
119
  */
93
120
  modified<C extends typeof Component>(c: InstanceType<C>): Entity;
94
121
  /**
95
- * Add a component of type `Class` to this entity if it isn't already
96
- * present, and return the entity for chaining.
122
+ * Attach a component to this entity if it is not already present.
97
123
  *
98
- * Does nothing if the component is already attached. `add` does not fire
99
- * `onSet` — use {@link set} when you want to apply data and notify.
124
+ * Idempotent. Does not fire `onSet` use {@link set} when you want to apply
125
+ * data and notify watchers.
100
126
  *
101
- * @param Class - The component class to instantiate.
127
+ * @param Class - Component class to instantiate.
102
128
  * @returns This entity, for chaining.
103
129
  */
104
130
  add<C extends typeof Component>(Class: C): Entity;
105
131
  /**
106
- * Add a component by its numeric type id.
132
+ * Attach a component by numeric type id.
107
133
  *
108
- * @param type - Numeric component type id (as returned by
109
- * {@link World.getComponentType}).
134
+ * @param type - Numeric component type id.
135
+ * @returns This entity, for chaining.
110
136
  */
111
137
  add(type: number): Entity;
112
138
  /**
113
- * Add a component of type `Class` (if not already present), assign the
114
- * provided properties onto the instance, and return the entity for chaining.
139
+ * Attach a component (creating it if necessary), copy `props` onto the
140
+ * instance, and fire the `onSet` hook plus any `update` callbacks for the
141
+ * component type.
115
142
  *
116
- * In deferred mode the props are not applied until the world processes the
117
- * resulting `Set` command.
143
+ * In deferred mode `props` are not applied until the queued `Set` command is
144
+ * routed.
118
145
  *
119
- * @param Class - The component class to instantiate.
146
+ * @param Class - Component class to instantiate.
120
147
  * @param props - Properties to assign onto the component instance.
121
148
  * @returns This entity, for chaining.
122
149
  */
123
150
  set<C extends typeof Component>(Class: C, props: Partial<InstanceType<C>>): Entity;
124
151
  /**
125
- * Add a component by its numeric type id, assign the provided properties,
126
- * and return the entity for chaining.
152
+ * Attach a component by numeric type id and copy `props` onto it.
127
153
  *
128
154
  * @param type - Numeric component type id.
129
155
  * @param props - Properties to assign onto the component instance.
156
+ * @returns This entity, for chaining.
130
157
  */
131
158
  set(type: number, props: Partial<Component>): Entity;
132
159
  /**
133
- * Remove the component of the given class from this entity.
160
+ * Detach a component from this entity.
134
161
  *
135
- * In deferred mode the removal is queued `get(Class)` continues to return
136
- * the component until the queue is processed. Once processed, queries fire
137
- * exit callbacks first, then the `onRemove` hook fires.
162
+ * In deferred mode the removal is queued; `get(C)` continues to return the
163
+ * component until the queue drains. When applied, queries fire `exit`
164
+ * callbacks first and the `onRemove` hook fires last.
138
165
  *
139
- * @param Class - The component class to remove.
166
+ * @param Class - Component class to detach.
140
167
  */
141
168
  remove<C extends typeof Component>(Class: C): void;
142
169
  /**
143
- * Remove a component by its numeric type id.
170
+ * Detach a component by numeric type id.
144
171
  *
145
172
  * @param type - Numeric component type id.
146
173
  */
147
174
  remove(type: number): void;
148
- /** @internal Look up a component instance by type id. */
149
- _get(type: number): Component | undefined;
150
175
  /**
151
- * Retrieve the component of type `Class`, or `undefined` if not present.
176
+ * Look up a component on this entity.
152
177
  *
153
178
  * @param typeOrClass - Component class or numeric type id.
154
- * @returns The component instance or `undefined`.
179
+ * @returns The component instance, or `undefined` when it is not attached.
155
180
  */
156
181
  get<C extends typeof Component>(typeOrClass: number | C): InstanceType<C> | undefined;
157
182
  /**
158
- * Typed event emitter for entity-level lifecycle events.
159
- *
160
- * Currently emits one event:
161
- * - `"destroy"` — fired just before the entity is fully torn down.
162
- *
163
- * The emitter is created lazily on first access.
164
- */
165
- get events(): EntityEvents;
166
- isInQuery(q: Query): boolean;
167
- /** @internal Removes a query from this entity's tracking sets without firing any callbacks. */
168
- _purgeQuery(q: Query): void;
169
- /** @internal Add a query to the entity's tracked-query set. Called by Query._enter. */
170
- _addQueryMembership(q: Query): void;
171
- /** @internal Remove a query from the entity's tracked-query set. Called by Query._exit. */
172
- _removeQueryMembership(q: Query): void;
173
- private _updateQueries;
174
- private _new;
175
- /** @internal Execute a Set command — create if absent, apply props, fire hooks, route events. */
176
- _set(type: number, props: Partial<Component> | undefined): void;
177
- /** @internal Execute a Modified command — fire onSet and route update events. */
178
- _modified(type: number): void;
179
- /** @internal Execute a Remove command — clear bitmask, route exits, remove component, fire onRemove. */
180
- _remove(type: number): void;
181
- /** @internal Execute a Destroy command — exit queries, fire onRemove, emit event, unregister. */
182
- _destroy(): void;
183
- /** `true` when the entity has no components attached. */
184
- get empty(): boolean;
185
- /**
186
- * Destroy this entity and recursively destroy all of its children.
183
+ * Destroy this entity and recursively destroy its children.
187
184
  *
188
- * All components have their `onRemove` hooks fired, the entity is
189
- * unregistered from the world, and the `"destroy"` event is emitted. The
190
- * entity must not be used after the destroy completes.
185
+ * Each component fires its `onRemove` hook, the `"destroy"` event is emitted
186
+ * just before teardown, and the entity is unregistered from the world.
187
+ * After destruction the entity must not be used.
191
188
  */
192
189
  destroy(): void;
193
- /**
194
- * Iterate over every component currently attached to this entity.
195
- *
196
- * @param callback - Called with each component instance. Iteration order is
197
- * not guaranteed.
198
- */
199
- forEachComponent(callback: (c: Component) => void): void;
200
190
  /** Returns `"EntityN"` where N is the entity id. */
201
191
  toString(): string;
202
192
  }