@alife-sdk/core 0.1.1 → 0.4.0

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 +20 -2
  2. package/dist/ai/BehaviorTree.d.ts +174 -0
  3. package/dist/ai/BehaviorTree.d.ts.map +1 -0
  4. package/dist/ai/BehaviorTree.js +280 -0
  5. package/dist/ai/BehaviorTree.js.map +1 -0
  6. package/dist/ai/GOAPAction.d.ts +21 -1
  7. package/dist/ai/GOAPAction.d.ts.map +1 -1
  8. package/dist/ai/GOAPPlanner.d.ts +4 -3
  9. package/dist/ai/GOAPPlanner.d.ts.map +1 -1
  10. package/dist/ai/GOAPPlanner.js +31 -3
  11. package/dist/ai/GOAPPlanner.js.map +1 -1
  12. package/dist/ai/StateMachine.d.ts +38 -0
  13. package/dist/ai/StateMachine.d.ts.map +1 -1
  14. package/dist/ai/StateMachine.js +80 -0
  15. package/dist/ai/StateMachine.js.map +1 -1
  16. package/dist/ai/WorldState.d.ts +8 -0
  17. package/dist/ai/WorldState.d.ts.map +1 -1
  18. package/dist/ai/WorldState.js +14 -0
  19. package/dist/ai/WorldState.js.map +1 -1
  20. package/dist/ai/index.d.ts +5 -1
  21. package/dist/ai/index.d.ts.map +1 -1
  22. package/dist/ai/index.js +1 -0
  23. package/dist/ai/index.js.map +1 -1
  24. package/dist/core/ReactiveQuery.d.ts +85 -0
  25. package/dist/core/ReactiveQuery.d.ts.map +1 -0
  26. package/dist/core/ReactiveQuery.js +154 -0
  27. package/dist/core/ReactiveQuery.js.map +1 -0
  28. package/dist/entity/EntityHandle.d.ts +76 -0
  29. package/dist/entity/EntityHandle.d.ts.map +1 -0
  30. package/dist/entity/EntityHandle.js +133 -0
  31. package/dist/entity/EntityHandle.js.map +1 -0
  32. package/dist/entity/index.d.ts +2 -0
  33. package/dist/entity/index.d.ts.map +1 -1
  34. package/dist/entity/index.js +1 -1
  35. package/dist/entity/index.js.map +1 -1
  36. package/dist/index.d.ts +2 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +1 -0
  39. package/dist/index.js.map +1 -1
  40. package/dist/registry/AIStateRegistry.d.ts +4 -0
  41. package/dist/registry/AIStateRegistry.d.ts.map +1 -1
  42. package/dist/registry/AIStateRegistry.js.map +1 -1
  43. package/package.json +1 -1
@@ -18,13 +18,51 @@ export type TransitionResult = {
18
18
  readonly success: false;
19
19
  readonly reason: 'not_allowed' | 'exit_guard' | 'enter_guard';
20
20
  };
21
+ export interface StateTransitionEvent {
22
+ readonly from: string;
23
+ readonly to: string;
24
+ readonly timestamp: number;
25
+ }
21
26
  export declare class StateMachine {
22
27
  private currentStateId;
28
+ private previousStateId;
29
+ private stateEnterTime;
23
30
  private readonly registry;
24
31
  private readonly entity;
32
+ private readonly enterListeners;
33
+ private readonly exitListeners;
34
+ private readonly changeListeners;
35
+ private readonly historyLog;
25
36
  constructor(entity: IEntity, registry: AIStateRegistry, initialState: string);
26
37
  /** Current active state identifier. */
27
38
  get state(): string;
39
+ /** Previous state identifier, or `null` if no transition has occurred yet. */
40
+ get previous(): string | null;
41
+ /** Milliseconds elapsed since entering the current state. */
42
+ get currentStateDuration(): number;
43
+ /** Returns `true` if the current state has the given tag. */
44
+ hasTag(tag: string): boolean;
45
+ /** Returns the metadata object of the current state, or `undefined`. */
46
+ get metadata(): Readonly<Record<string, unknown>> | undefined;
47
+ /**
48
+ * Subscribe to the moment the FSM enters `state`.
49
+ * @returns Unsubscribe function.
50
+ */
51
+ onEnter(state: string, callback: (from: string | null) => void): () => void;
52
+ /**
53
+ * Subscribe to the moment the FSM exits `state`.
54
+ * @returns Unsubscribe function.
55
+ */
56
+ onExit(state: string, callback: (to: string) => void): () => void;
57
+ /**
58
+ * Subscribe to any state change.
59
+ * @returns Unsubscribe function.
60
+ */
61
+ onChange(callback: (from: string, to: string) => void): () => void;
62
+ /** Returns a snapshot of the transition history (oldest first). */
63
+ getHistory(): readonly StateTransitionEvent[];
64
+ /** Clears the transition history. */
65
+ clearHistory(): void;
28
66
  /**
29
67
  * Force transition to a new state.
30
68
  *
@@ -1 +1 @@
1
- {"version":3,"file":"StateMachine.d.ts","sourceRoot":"","sources":["../../src/ai/StateMachine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,YAAY,GAAG,aAAa,CAAA;CAAE,CAAC;AAE/F,qBAAa,YAAY;IACvB,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;gBAErB,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM;IAa5E,uCAAuC;IACvC,IAAI,KAAK,IAAI,MAAM,CAElB;IAMD;;;;;;OAMG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB;IAsB9C;;;;;;;;OAQG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAkB3B,iEAAiE;IACjE,OAAO,IAAI,IAAI;CAIhB"}
1
+ {"version":3,"file":"StateMachine.d.ts","sourceRoot":"","sources":["../../src/ai/StateMachine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,YAAY,GAAG,aAAa,CAAA;CAAE,CAAC;AAE/F,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IAEjC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyD;IACxF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgD;IAC9E,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiD;IACjF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA8B;gBAE7C,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM;IAc5E,uCAAuC;IACvC,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,8EAA8E;IAC9E,IAAI,QAAQ,IAAI,MAAM,GAAG,IAAI,CAE5B;IAED,6DAA6D;IAC7D,IAAI,oBAAoB,IAAI,MAAM,CAEjC;IAMD,6DAA6D;IAC7D,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAK5B,wEAAwE;IACxE,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAE5D;IAMD;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,MAAM,IAAI;IAM3E;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI;IAMjE;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI;IASlE,mEAAmE;IACnE,UAAU,IAAI,SAAS,oBAAoB,EAAE;IAI7C,qCAAqC;IACrC,YAAY,IAAI,IAAI;IAQpB;;;;;;OAMG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB;IAwC9C;;;;;;;;OAQG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAkB3B,iEAAiE;IACjE,OAAO,IAAI,IAAI;CAIhB"}
@@ -12,9 +12,15 @@
12
12
  */
13
13
  export class StateMachine {
14
14
  constructor(entity, registry, initialState) {
15
+ this.previousStateId = null;
16
+ this.enterListeners = new Map();
17
+ this.exitListeners = new Map();
18
+ this.changeListeners = new Set();
19
+ this.historyLog = [];
15
20
  this.entity = entity;
16
21
  this.registry = registry;
17
22
  this.currentStateId = initialState;
23
+ this.stateEnterTime = Date.now();
18
24
  const definition = this.registry.get(this.currentStateId);
19
25
  definition.handler.enter(this.entity);
20
26
  }
@@ -25,6 +31,68 @@ export class StateMachine {
25
31
  get state() {
26
32
  return this.currentStateId;
27
33
  }
34
+ /** Previous state identifier, or `null` if no transition has occurred yet. */
35
+ get previous() {
36
+ return this.previousStateId;
37
+ }
38
+ /** Milliseconds elapsed since entering the current state. */
39
+ get currentStateDuration() {
40
+ return Date.now() - this.stateEnterTime;
41
+ }
42
+ // -----------------------------------------------------------------------
43
+ // Tag queries
44
+ // -----------------------------------------------------------------------
45
+ /** Returns `true` if the current state has the given tag. */
46
+ hasTag(tag) {
47
+ const def = this.registry.tryGet(this.currentStateId);
48
+ return def?.tags?.includes(tag) ?? false;
49
+ }
50
+ /** Returns the metadata object of the current state, or `undefined`. */
51
+ get metadata() {
52
+ return this.registry.tryGet(this.currentStateId)?.metadata;
53
+ }
54
+ // -----------------------------------------------------------------------
55
+ // Event subscriptions
56
+ // -----------------------------------------------------------------------
57
+ /**
58
+ * Subscribe to the moment the FSM enters `state`.
59
+ * @returns Unsubscribe function.
60
+ */
61
+ onEnter(state, callback) {
62
+ if (!this.enterListeners.has(state))
63
+ this.enterListeners.set(state, new Set());
64
+ this.enterListeners.get(state).add(callback);
65
+ return () => this.enterListeners.get(state)?.delete(callback);
66
+ }
67
+ /**
68
+ * Subscribe to the moment the FSM exits `state`.
69
+ * @returns Unsubscribe function.
70
+ */
71
+ onExit(state, callback) {
72
+ if (!this.exitListeners.has(state))
73
+ this.exitListeners.set(state, new Set());
74
+ this.exitListeners.get(state).add(callback);
75
+ return () => this.exitListeners.get(state)?.delete(callback);
76
+ }
77
+ /**
78
+ * Subscribe to any state change.
79
+ * @returns Unsubscribe function.
80
+ */
81
+ onChange(callback) {
82
+ this.changeListeners.add(callback);
83
+ return () => this.changeListeners.delete(callback);
84
+ }
85
+ // -----------------------------------------------------------------------
86
+ // History
87
+ // -----------------------------------------------------------------------
88
+ /** Returns a snapshot of the transition history (oldest first). */
89
+ getHistory() {
90
+ return [...this.historyLog];
91
+ }
92
+ /** Clears the transition history. */
93
+ clearHistory() {
94
+ this.historyLog.length = 0;
95
+ }
28
96
  // -----------------------------------------------------------------------
29
97
  // Transitions
30
98
  // -----------------------------------------------------------------------
@@ -46,9 +114,21 @@ export class StateMachine {
46
114
  return { success: false, reason: 'exit_guard' };
47
115
  if (newDefinition.canEnter?.(this.entity, this.currentStateId) === false)
48
116
  return { success: false, reason: 'enter_guard' };
117
+ const from = this.currentStateId;
118
+ // Exit
49
119
  oldDefinition.handler.exit(this.entity);
120
+ this.exitListeners.get(from)?.forEach(cb => cb(newState));
121
+ // Advance state
122
+ this.previousStateId = from;
50
123
  this.currentStateId = newState;
124
+ this.stateEnterTime = Date.now();
125
+ // Record history
126
+ this.historyLog.push({ from, to: newState, timestamp: this.stateEnterTime });
127
+ // Notify change listeners
128
+ this.changeListeners.forEach(cb => cb(from, newState));
129
+ // Enter
51
130
  newDefinition.handler.enter(this.entity);
131
+ this.enterListeners.get(newState)?.forEach(cb => cb(from));
52
132
  return { success: true };
53
133
  }
54
134
  // -----------------------------------------------------------------------
@@ -1 +1 @@
1
- {"version":3,"file":"StateMachine.js","sourceRoot":"","sources":["../../src/ai/StateMachine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AASH,MAAM,OAAO,YAAY;IAKvB,YAAY,MAAe,EAAE,QAAyB,EAAE,YAAoB;QAC1E,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,cAAc,GAAG,YAAY,CAAC;QAEnC,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC1D,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,0EAA0E;IAC1E,YAAY;IACZ,0EAA0E;IAE1E,uCAAuC;IACvC,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED,0EAA0E;IAC1E,cAAc;IACd,0EAA0E;IAE1E;;;;;;OAMG;IACH,UAAU,CAAC,QAAgB;QACzB,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC7D,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAElD,oFAAoF;QACpF,IAAI,aAAa,CAAC,kBAAkB,IAAI,CAAC,aAAa,CAAC,kBAAkB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7F,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;QACnD,CAAC;QAED,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,KAAK;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;QAC9G,IAAI,aAAa,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,CAAC,KAAK,KAAK;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;QAE3H,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC;QAC/B,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,0EAA0E;IAC1E,SAAS;IACT,0EAA0E;IAE1E;;;;;;;;OAQG;IACH,MAAM,CAAC,KAAa;QAClB,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC1D,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAE9C,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CACjD,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,MAAM,CACZ,CAAC;QAEF,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,UAAU;IACV,0EAA0E;IAE1E,iEAAiE;IACjE,OAAO;QACL,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC1D,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;CACF"}
1
+ {"version":3,"file":"StateMachine.js","sourceRoot":"","sources":["../../src/ai/StateMachine.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,14 @@ export type WorldStateValue = boolean | number | string;
17
17
  export declare class WorldState {
18
18
  private readonly properties;
19
19
  set(key: string, value: WorldStateValue): void;
20
+ /**
21
+ * Create a WorldState from a plain object.
22
+ * Equivalent to calling set() for each key-value pair.
23
+ *
24
+ * @example
25
+ * const ws = WorldState.from({ hasAmmo: true, underFire: false, ammoCount: 3 });
26
+ */
27
+ static from(props: Record<string, WorldStateValue>): WorldState;
20
28
  get(key: string): WorldStateValue | undefined;
21
29
  has(key: string): boolean;
22
30
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"WorldState.d.ts","sourceRoot":"","sources":["../../src/ai/WorldState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAExD,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsC;IAMjE,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI;IAQ9C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI7C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAQzB;;;;;;OAMG;IACH,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO;IAQpC,0BAA0B;IAC1B,KAAK,IAAI,UAAU;IAQnB;;;;;;OAMG;IACH,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM;IAUrC;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU;IAQ7C,8EAA8E;IAC9E,IAAI,IAAI,gBAAgB,CAAC,MAAM,CAAC;CAGjC"}
1
+ {"version":3,"file":"WorldState.d.ts","sourceRoot":"","sources":["../../src/ai/WorldState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAExD,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsC;IAMjE,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI;IAI9C;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,UAAU;IAY/D,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI7C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAQzB;;;;;;OAMG;IACH,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO;IAQpC,0BAA0B;IAC1B,KAAK,IAAI,UAAU;IAQnB;;;;;;OAMG;IACH,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM;IAUrC;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU;IAQ7C,8EAA8E;IAC9E,IAAI,IAAI,gBAAgB,CAAC,MAAM,CAAC;CAGjC"}
@@ -23,6 +23,20 @@ export class WorldState {
23
23
  set(key, value) {
24
24
  this.properties.set(key, value);
25
25
  }
26
+ /**
27
+ * Create a WorldState from a plain object.
28
+ * Equivalent to calling set() for each key-value pair.
29
+ *
30
+ * @example
31
+ * const ws = WorldState.from({ hasAmmo: true, underFire: false, ammoCount: 3 });
32
+ */
33
+ static from(props) {
34
+ const state = new WorldState();
35
+ for (const [key, value] of Object.entries(props)) {
36
+ state.set(key, value);
37
+ }
38
+ return state;
39
+ }
26
40
  // -----------------------------------------------------------------------
27
41
  // Accessors
28
42
  // -----------------------------------------------------------------------
@@ -1 +1 @@
1
- {"version":3,"file":"WorldState.js","sourceRoot":"","sources":["../../src/ai/WorldState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,MAAM,OAAO,UAAU;IAAvB;QACmB,eAAU,GAAG,IAAI,GAAG,EAA2B,CAAC;IAmFnE,CAAC;IAjFC,0EAA0E;IAC1E,WAAW;IACX,0EAA0E;IAE1E,GAAG,CAAC,GAAW,EAAE,KAAsB;QACrC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,0EAA0E;IAC1E,YAAY;IACZ,0EAA0E;IAE1E,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,0EAA0E;IAC1E,qBAAqB;IACrB,0EAA0E;IAE1E;;;;;;OAMG;IACH,SAAS,CAAC,IAAgB;QACxB,KAAK,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC/C,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC9C,IAAI,YAAY,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;QAC/C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,0BAA0B;IAC1B,KAAK;QACH,MAAM,IAAI,GAAG,IAAI,UAAU,EAAE,CAAC;QAC9B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC3C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACH,UAAU,CAAC,KAAiB;QAC1B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YAC5C,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC;gBACvC,KAAK,EAAE,CAAC;YACV,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,OAAmB;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC1B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YAC9C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8EAA8E;IAC9E,IAAI;QACF,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IAChC,CAAC;CACF"}
1
+ {"version":3,"file":"WorldState.js","sourceRoot":"","sources":["../../src/ai/WorldState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,MAAM,OAAO,UAAU;IAAvB;QACmB,eAAU,GAAG,IAAI,GAAG,EAA2B,CAAC;IAkGnE,CAAC;IAhGC,0EAA0E;IAC1E,WAAW;IACX,0EAA0E;IAE1E,GAAG,CAAC,GAAW,EAAE,KAAsB;QACrC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAClC,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,CAAC,KAAsC;QAChD,MAAM,KAAK,GAAG,IAAI,UAAU,EAAE,CAAC;QAC/B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACjD,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACxB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,0EAA0E;IAC1E,YAAY;IACZ,0EAA0E;IAE1E,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,0EAA0E;IAC1E,qBAAqB;IACrB,0EAA0E;IAE1E;;;;;;OAMG;IACH,SAAS,CAAC,IAAgB;QACxB,KAAK,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC/C,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC9C,IAAI,YAAY,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;QAC/C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,0BAA0B;IAC1B,KAAK;QACH,MAAM,IAAI,GAAG,IAAI,UAAU,EAAE,CAAC;QAC9B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC3C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACH,UAAU,CAAC,KAAiB;QAC1B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YAC5C,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC;gBACvC,KAAK,EAAE,CAAC;YACV,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,OAAmB;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC1B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YAC9C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8EAA8E;IAC9E,IAAI;QACF,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IAChC,CAAC;CACF"}
@@ -1,10 +1,14 @@
1
1
  export { StateMachine } from './StateMachine';
2
- export type { TransitionResult } from './StateMachine';
2
+ export type { TransitionResult, StateTransitionEvent } from './StateMachine';
3
3
  export { MemoryBank, MemoryChannel } from './MemorySystem';
4
4
  export type { MemoryRecord, IMemoryBankConfig, IMemoryInput } from './MemorySystem';
5
5
  export { DangerManager, DangerType } from './DangerManager';
6
6
  export type { IDangerEntry } from './DangerManager';
7
7
  export { WorldState } from './WorldState';
8
+ export type { WorldStateValue } from './WorldState';
8
9
  export { GOAPPlanner } from './GOAPPlanner';
9
10
  export { GOAPAction, ActionStatus } from './GOAPAction';
11
+ export type { GOAPActionDef } from './GOAPAction';
12
+ export { Blackboard, Task, Condition, Sequence, Selector, Parallel, Inverter, AlwaysSucceed, AlwaysFail, Repeater, Cooldown } from './BehaviorTree';
13
+ export type { TaskStatus, ITreeNode, ParallelPolicy } from './BehaviorTree';
10
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ai/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC3D,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC5D,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ai/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC3D,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC5D,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACxD,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACpJ,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/ai/index.js CHANGED
@@ -5,4 +5,5 @@ export { DangerManager, DangerType } from './DangerManager';
5
5
  export { WorldState } from './WorldState';
6
6
  export { GOAPPlanner } from './GOAPPlanner';
7
7
  export { GOAPAction, ActionStatus } from './GOAPAction';
8
+ export { Blackboard, Task, Condition, Sequence, Selector, Parallel, Inverter, AlwaysSucceed, AlwaysFail, Repeater, Cooldown } from './BehaviorTree';
8
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ai/index.ts"],"names":[],"mappings":"AAAA,qBAAqB;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE3D,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE5D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ai/index.ts"],"names":[],"mappings":"AAAA,qBAAqB;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE3D,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE5D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAExD,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * ReactiveQuery — observe when entities enter and exit a filtered set.
3
+ *
4
+ * Instead of polling the entire entity set every frame, a ReactiveQuery
5
+ * maintains a stable "matched" set and fires change notifications only when
6
+ * entities enter or leave the query (i.e. when the predicate result changes).
7
+ *
8
+ * Usage pattern:
9
+ * 1. Create a query with a predicate.
10
+ * 2. Subscribe to `onChange` to react to structural changes.
11
+ * 3. Call `update(allEntities)` each tick to re-evaluate.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const hostileQuery = new ReactiveQuery<IEntity>(
16
+ * (e) => e.isAlive && e.hasComponent('hostile')
17
+ * );
18
+ *
19
+ * hostileQuery.onChange(({ added, removed }) => {
20
+ * added.forEach(e => combatSystem.track(e));
21
+ * removed.forEach(e => combatSystem.untrack(e));
22
+ * });
23
+ *
24
+ * // Each tick:
25
+ * hostileQuery.update(world.entities());
26
+ * ```
27
+ */
28
+ /** Changes detected since the last `update()` call. */
29
+ export interface QueryChanges<T> {
30
+ /** Entities that newly matched the predicate this update. */
31
+ readonly added: readonly T[];
32
+ /** Entities that no longer match the predicate this update. */
33
+ readonly removed: readonly T[];
34
+ /** All entities currently matching the predicate after this update. */
35
+ readonly current: readonly T[];
36
+ }
37
+ /** Callback invoked when any entities are added or removed from the query. */
38
+ export type QueryChangeListener<T> = (changes: QueryChanges<T>) => void;
39
+ /**
40
+ * Tracks which entities satisfy a predicate and fires change events when
41
+ * the matched set changes.
42
+ */
43
+ export declare class ReactiveQuery<T> {
44
+ private readonly predicate;
45
+ private readonly matched;
46
+ private readonly listeners;
47
+ constructor(predicate: (entity: T) => boolean);
48
+ /**
49
+ * Re-evaluate the predicate against `allEntities`.
50
+ *
51
+ * Fires `onChange` listeners if the matched set changed.
52
+ * Call this once per tick from the owning system.
53
+ */
54
+ update(allEntities: Iterable<T>): void;
55
+ /**
56
+ * Subscribe to change events. Called whenever entities enter or exit the
57
+ * matched set.
58
+ *
59
+ * @returns Unsubscribe function.
60
+ */
61
+ onChange(listener: QueryChangeListener<T>): () => void;
62
+ /** All entities currently matching the predicate (stable snapshot). */
63
+ get current(): readonly T[];
64
+ /** Number of currently matched entities. */
65
+ get size(): number;
66
+ /** Return `true` if the entity is currently in the matched set. */
67
+ has(entity: T): boolean;
68
+ /**
69
+ * Manually add an entity to the matched set without re-evaluating the
70
+ * predicate. Fires `onChange` with the single addition.
71
+ *
72
+ * Useful when external code creates entities and knows they should match.
73
+ */
74
+ track(entity: T): void;
75
+ /**
76
+ * Manually remove an entity from the matched set.
77
+ * Fires `onChange` with the single removal.
78
+ *
79
+ * Useful when entities are destroyed mid-tick.
80
+ */
81
+ untrack(entity: T): void;
82
+ /** Remove all entities and clear all listeners. */
83
+ dispose(): void;
84
+ }
85
+ //# sourceMappingURL=ReactiveQuery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReactiveQuery.d.ts","sourceRoot":"","sources":["../../src/core/ReactiveQuery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAMH,uDAAuD;AACvD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;IAC7B,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;IAC/B,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;CAChC;AAED,8EAA8E;AAC9E,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AAMxE;;;GAGG;AACH,qBAAa,aAAa,CAAC,CAAC;IAId,OAAO,CAAC,QAAQ,CAAC,SAAS;IAHtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqC;gBAElC,SAAS,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO;IAM9D;;;;;OAKG;IACH,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI;IAwCtC;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAStD,uEAAuE;IACvE,IAAI,OAAO,IAAI,SAAS,CAAC,EAAE,CAE1B;IAED,4CAA4C;IAC5C,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,mEAAmE;IACnE,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO;IAIvB;;;;;OAKG;IACH,KAAK,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI;IAatB;;;;;OAKG;IACH,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI;IAaxB,mDAAmD;IACnD,OAAO,IAAI,IAAI;CAIhB"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * ReactiveQuery — observe when entities enter and exit a filtered set.
3
+ *
4
+ * Instead of polling the entire entity set every frame, a ReactiveQuery
5
+ * maintains a stable "matched" set and fires change notifications only when
6
+ * entities enter or leave the query (i.e. when the predicate result changes).
7
+ *
8
+ * Usage pattern:
9
+ * 1. Create a query with a predicate.
10
+ * 2. Subscribe to `onChange` to react to structural changes.
11
+ * 3. Call `update(allEntities)` each tick to re-evaluate.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const hostileQuery = new ReactiveQuery<IEntity>(
16
+ * (e) => e.isAlive && e.hasComponent('hostile')
17
+ * );
18
+ *
19
+ * hostileQuery.onChange(({ added, removed }) => {
20
+ * added.forEach(e => combatSystem.track(e));
21
+ * removed.forEach(e => combatSystem.untrack(e));
22
+ * });
23
+ *
24
+ * // Each tick:
25
+ * hostileQuery.update(world.entities());
26
+ * ```
27
+ */
28
+ // ---------------------------------------------------------------------------
29
+ // ReactiveQuery
30
+ // ---------------------------------------------------------------------------
31
+ /**
32
+ * Tracks which entities satisfy a predicate and fires change events when
33
+ * the matched set changes.
34
+ */
35
+ export class ReactiveQuery {
36
+ constructor(predicate) {
37
+ this.predicate = predicate;
38
+ this.matched = new Set();
39
+ this.listeners = new Set();
40
+ }
41
+ // -------------------------------------------------------------------------
42
+ // Update
43
+ // -------------------------------------------------------------------------
44
+ /**
45
+ * Re-evaluate the predicate against `allEntities`.
46
+ *
47
+ * Fires `onChange` listeners if the matched set changed.
48
+ * Call this once per tick from the owning system.
49
+ */
50
+ update(allEntities) {
51
+ const added = [];
52
+ const removed = [];
53
+ const nextMatched = new Set();
54
+ for (const entity of allEntities) {
55
+ if (this.predicate(entity)) {
56
+ nextMatched.add(entity);
57
+ if (!this.matched.has(entity)) {
58
+ added.push(entity);
59
+ }
60
+ }
61
+ }
62
+ for (const entity of this.matched) {
63
+ if (!nextMatched.has(entity)) {
64
+ removed.push(entity);
65
+ }
66
+ }
67
+ // Commit new matched set
68
+ this.matched.clear();
69
+ for (const e of nextMatched)
70
+ this.matched.add(e);
71
+ if (added.length > 0 || removed.length > 0) {
72
+ const changes = {
73
+ added,
74
+ removed,
75
+ current: [...this.matched],
76
+ };
77
+ for (const listener of this.listeners) {
78
+ listener(changes);
79
+ }
80
+ }
81
+ }
82
+ // -------------------------------------------------------------------------
83
+ // Subscriptions
84
+ // -------------------------------------------------------------------------
85
+ /**
86
+ * Subscribe to change events. Called whenever entities enter or exit the
87
+ * matched set.
88
+ *
89
+ * @returns Unsubscribe function.
90
+ */
91
+ onChange(listener) {
92
+ this.listeners.add(listener);
93
+ return () => this.listeners.delete(listener);
94
+ }
95
+ // -------------------------------------------------------------------------
96
+ // Accessors
97
+ // -------------------------------------------------------------------------
98
+ /** All entities currently matching the predicate (stable snapshot). */
99
+ get current() {
100
+ return [...this.matched];
101
+ }
102
+ /** Number of currently matched entities. */
103
+ get size() {
104
+ return this.matched.size;
105
+ }
106
+ /** Return `true` if the entity is currently in the matched set. */
107
+ has(entity) {
108
+ return this.matched.has(entity);
109
+ }
110
+ /**
111
+ * Manually add an entity to the matched set without re-evaluating the
112
+ * predicate. Fires `onChange` with the single addition.
113
+ *
114
+ * Useful when external code creates entities and knows they should match.
115
+ */
116
+ track(entity) {
117
+ if (this.matched.has(entity))
118
+ return;
119
+ this.matched.add(entity);
120
+ const changes = {
121
+ added: [entity],
122
+ removed: [],
123
+ current: [...this.matched],
124
+ };
125
+ for (const listener of this.listeners) {
126
+ listener(changes);
127
+ }
128
+ }
129
+ /**
130
+ * Manually remove an entity from the matched set.
131
+ * Fires `onChange` with the single removal.
132
+ *
133
+ * Useful when entities are destroyed mid-tick.
134
+ */
135
+ untrack(entity) {
136
+ if (!this.matched.has(entity))
137
+ return;
138
+ this.matched.delete(entity);
139
+ const changes = {
140
+ added: [],
141
+ removed: [entity],
142
+ current: [...this.matched],
143
+ };
144
+ for (const listener of this.listeners) {
145
+ listener(changes);
146
+ }
147
+ }
148
+ /** Remove all entities and clear all listeners. */
149
+ dispose() {
150
+ this.matched.clear();
151
+ this.listeners.clear();
152
+ }
153
+ }
154
+ //# sourceMappingURL=ReactiveQuery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReactiveQuery.js","sourceRoot":"","sources":["../../src/core/ReactiveQuery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * EntityHandle — versioned entity references with use-after-free protection.
3
+ *
4
+ * Instead of holding raw entity references that can become dangling after an
5
+ * entity is destroyed, systems hold an EntityHandle. The handle encodes both
6
+ * the entity's slot index and a generation counter. When a slot is reused for
7
+ * a new entity the generation is bumped, making all old handles stale.
8
+ *
9
+ * Bit layout (fits in a JavaScript safe integer):
10
+ * [47..20] generation (28 bits, up to ~268 M versions per slot)
11
+ * [19.. 0] index (20 bits, up to ~1 M concurrent slots)
12
+ *
13
+ * Usage:
14
+ * const manager = new EntityHandleManager();
15
+ * const handle = manager.alloc('wolf-1');
16
+ * manager.resolve(handle); // → 'wolf-1'
17
+ * manager.free(handle);
18
+ * manager.resolve(handle); // → null (stale)
19
+ */
20
+ /** Opaque numeric type that encodes (generation, index). */
21
+ export type EntityHandle = number & {
22
+ readonly __brand: 'EntityHandle';
23
+ };
24
+ /** Sentinel value for an absent or invalid handle. */
25
+ export declare const NULL_HANDLE: EntityHandle;
26
+ /** Pack (index, generation) into a single handle. */
27
+ export declare function makeHandle(index: number, generation: number): EntityHandle;
28
+ /** Extract the slot index from a handle. */
29
+ export declare function indexOf(handle: EntityHandle): number;
30
+ /** Extract the generation counter from a handle. */
31
+ export declare function genOf(handle: EntityHandle): number;
32
+ /** Return `true` if the handle is not the null sentinel. */
33
+ export declare function isValidHandle(handle: EntityHandle): boolean;
34
+ /** Human-readable description for logging / debugging. */
35
+ export declare function handleToString(handle: EntityHandle): string;
36
+ /**
37
+ * Central registry that owns the slot → entity-id mapping.
38
+ *
39
+ * Recycles freed slots so slot count stays bounded. Old handles pointing at
40
+ * recycled slots resolve to `null` because their stored generation no longer
41
+ * matches the slot's current generation.
42
+ */
43
+ export declare class EntityHandleManager<TId = string> {
44
+ /** Generation counter per slot (index = slot index). */
45
+ private readonly generations;
46
+ /** Entity ID stored in each live slot. `null` = free. */
47
+ private readonly ids;
48
+ /** Slot indices available for reuse. */
49
+ private readonly freeList;
50
+ /** Next slot to allocate when freeList is empty. */
51
+ private nextSlot;
52
+ /**
53
+ * Allocate a new handle for the given entity id.
54
+ * @throws if the slot limit is exhausted.
55
+ */
56
+ alloc(id: TId): EntityHandle;
57
+ /**
58
+ * Release a handle, incrementing the slot's generation.
59
+ * All existing handles pointing at this slot become stale.
60
+ *
61
+ * Does nothing (and does not throw) if the handle is already stale.
62
+ */
63
+ free(handle: EntityHandle): void;
64
+ /**
65
+ * Resolve a handle to its entity id.
66
+ * Returns `null` if the handle is stale (entity was freed) or null.
67
+ */
68
+ resolve(handle: EntityHandle): TId | null;
69
+ /**
70
+ * Return `true` if the handle points to a currently-live slot.
71
+ */
72
+ isAlive(handle: EntityHandle): boolean;
73
+ /** Number of currently-live slots. */
74
+ get size(): number;
75
+ }
76
+ //# sourceMappingURL=EntityHandle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityHandle.d.ts","sourceRoot":"","sources":["../../src/entity/EntityHandle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAgBH,4DAA4D;AAC5D,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAA;CAAE,CAAC;AAEzE,sDAAsD;AACtD,eAAO,MAAM,WAAW,EAAQ,YAAY,CAAC;AAE7C,qDAAqD;AACrD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,YAAY,CAG1E;AAED,4CAA4C;AAC5C,wBAAgB,OAAO,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAEpD;AAED,oDAAoD;AACpD,wBAAgB,KAAK,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAElD;AAED,4DAA4D;AAC5D,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAE3D;AAED,0DAA0D;AAC1D,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAG3D;AAMD;;;;;;GAMG;AACH,qBAAa,mBAAmB,CAAC,GAAG,GAAG,MAAM;IAC3C,wDAAwD;IACxD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgB;IAC5C,yDAAyD;IACzD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAsB;IAC1C,wCAAwC;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,oDAAoD;IACpD,OAAO,CAAC,QAAQ,CAAK;IAErB;;;OAGG;IACH,KAAK,CAAC,EAAE,EAAE,GAAG,GAAG,YAAY;IAiB5B;;;;;OAKG;IACH,IAAI,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAQhC;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,YAAY,GAAG,GAAG,GAAG,IAAI;IAOzC;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO;IAMtC,sCAAsC;IACtC,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}