@sadhaka/loom-engine 0.13.0 → 0.15.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 (89) hide show
  1. package/dist/audio/audio-asset-cache.d.ts +12 -0
  2. package/dist/audio/audio-asset-cache.d.ts.map +1 -0
  3. package/dist/audio/audio-asset-cache.js +53 -0
  4. package/dist/audio/audio-asset-cache.js.map +1 -0
  5. package/dist/audio/audio-asset-loader.d.ts +16 -0
  6. package/dist/audio/audio-asset-loader.d.ts.map +1 -0
  7. package/dist/audio/audio-asset-loader.js +100 -0
  8. package/dist/audio/audio-asset-loader.js.map +1 -0
  9. package/dist/audio/audio-listener-resource.d.ts +19 -0
  10. package/dist/audio/audio-listener-resource.d.ts.map +1 -0
  11. package/dist/audio/audio-listener-resource.js +57 -0
  12. package/dist/audio/audio-listener-resource.js.map +1 -0
  13. package/dist/audio/cue-catalog.d.ts +39 -0
  14. package/dist/audio/cue-catalog.d.ts.map +1 -0
  15. package/dist/audio/cue-catalog.js +186 -0
  16. package/dist/audio/cue-catalog.js.map +1 -0
  17. package/dist/audio/music-director.d.ts +18 -0
  18. package/dist/audio/music-director.d.ts.map +1 -0
  19. package/dist/audio/music-director.js +177 -0
  20. package/dist/audio/music-director.js.map +1 -0
  21. package/dist/audio/spatial-audio-bus.d.ts +66 -0
  22. package/dist/audio/spatial-audio-bus.d.ts.map +1 -0
  23. package/dist/audio/spatial-audio-bus.js +341 -0
  24. package/dist/audio/spatial-audio-bus.js.map +1 -0
  25. package/dist/audio/spatial-audio-system.d.ts +17 -0
  26. package/dist/audio/spatial-audio-system.d.ts.map +1 -0
  27. package/dist/audio/spatial-audio-system.js +98 -0
  28. package/dist/audio/spatial-audio-system.js.map +1 -0
  29. package/dist/audio/zone-audio-system.d.ts +78 -0
  30. package/dist/audio/zone-audio-system.d.ts.map +1 -0
  31. package/dist/audio/zone-audio-system.js +206 -0
  32. package/dist/audio/zone-audio-system.js.map +1 -0
  33. package/dist/director/ai/ai-plugin-registry.d.ts +20 -0
  34. package/dist/director/ai/ai-plugin-registry.d.ts.map +1 -0
  35. package/dist/director/ai/ai-plugin-registry.js +232 -0
  36. package/dist/director/ai/ai-plugin-registry.js.map +1 -0
  37. package/dist/director/ai/mock-ai-plugin.d.ts +24 -0
  38. package/dist/director/ai/mock-ai-plugin.d.ts.map +1 -0
  39. package/dist/director/ai/mock-ai-plugin.js +83 -0
  40. package/dist/director/ai/mock-ai-plugin.js.map +1 -0
  41. package/dist/director/ai/plugin-context.d.ts +27 -0
  42. package/dist/director/ai/plugin-context.d.ts.map +1 -0
  43. package/dist/director/ai/plugin-context.js +152 -0
  44. package/dist/director/ai/plugin-context.js.map +1 -0
  45. package/dist/director/ai/plugin.d.ts +57 -0
  46. package/dist/director/ai/plugin.d.ts.map +1 -0
  47. package/dist/director/ai/plugin.js +32 -0
  48. package/dist/director/ai/plugin.js.map +1 -0
  49. package/dist/director/index.d.ts +27 -0
  50. package/dist/director/index.d.ts.map +1 -0
  51. package/dist/director/index.js +26 -0
  52. package/dist/director/index.js.map +1 -0
  53. package/dist/director/zone/mock-zone-bridge.d.ts +22 -0
  54. package/dist/director/zone/mock-zone-bridge.d.ts.map +1 -0
  55. package/dist/director/zone/mock-zone-bridge.js +107 -0
  56. package/dist/director/zone/mock-zone-bridge.js.map +1 -0
  57. package/dist/director/zone/sse-zone-bridge.d.ts +40 -0
  58. package/dist/director/zone/sse-zone-bridge.d.ts.map +1 -0
  59. package/dist/director/zone/sse-zone-bridge.js +164 -0
  60. package/dist/director/zone/sse-zone-bridge.js.map +1 -0
  61. package/dist/director/zone/zone-event-bridge.d.ts +21 -0
  62. package/dist/director/zone/zone-event-bridge.d.ts.map +1 -0
  63. package/dist/director/zone/zone-event-bridge.js +24 -0
  64. package/dist/director/zone/zone-event-bridge.js.map +1 -0
  65. package/dist/director/zone/zone-event-envelope.d.ts +90 -0
  66. package/dist/director/zone/zone-event-envelope.d.ts.map +1 -0
  67. package/dist/director/zone/zone-event-envelope.js +104 -0
  68. package/dist/director/zone/zone-event-envelope.js.map +1 -0
  69. package/dist/director/zone/zone-event-log.d.ts +17 -0
  70. package/dist/director/zone/zone-event-log.d.ts.map +1 -0
  71. package/dist/director/zone/zone-event-log.js +46 -0
  72. package/dist/director/zone/zone-event-log.js.map +1 -0
  73. package/dist/director/zone/zone-event-system.d.ts +14 -0
  74. package/dist/director/zone/zone-event-system.d.ts.map +1 -0
  75. package/dist/director/zone/zone-event-system.js +179 -0
  76. package/dist/director/zone/zone-event-system.js.map +1 -0
  77. package/dist/director/zone/zone-state-resource.d.ts +15 -0
  78. package/dist/director/zone/zone-state-resource.d.ts.map +1 -0
  79. package/dist/director/zone/zone-state-resource.js +60 -0
  80. package/dist/director/zone/zone-state-resource.js.map +1 -0
  81. package/dist/index.d.ts +27 -1
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +23 -1
  84. package/dist/index.js.map +1 -1
  85. package/dist/server/index.d.ts +7 -0
  86. package/dist/server/index.d.ts.map +1 -0
  87. package/dist/server/index.js +33 -0
  88. package/dist/server/index.js.map +1 -0
  89. package/package.json +6 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-plugin-registry.js","sourceRoot":"","sources":["../../../src/director/ai/ai-plugin-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { DirectorEvent } from '../event-envelope.js';
2
+ import type { IAIPlugin, EmittedEvents, PluginContext, ZoneEvent } from './plugin.js';
3
+ export interface MockAIPluginScriptEntry {
4
+ atTick: number;
5
+ characterEvents?: DirectorEvent[];
6
+ zoneEvents?: ZoneEvent[];
7
+ }
8
+ export interface MockAIPluginOptions {
9
+ name?: string;
10
+ script: ReadonlyArray<MockAIPluginScriptEntry>;
11
+ priority?: number;
12
+ }
13
+ export declare class MockAIPlugin implements IAIPlugin {
14
+ readonly name: string;
15
+ readonly version = "0.0.1";
16
+ readonly priority: number;
17
+ private readonly script;
18
+ private tick;
19
+ constructor(opts: MockAIPluginOptions);
20
+ onTick(_ctx: PluginContext): Promise<EmittedEvents>;
21
+ currentTick(): number;
22
+ resetTick(): void;
23
+ }
24
+ //# sourceMappingURL=mock-ai-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-ai-plugin.d.ts","sourceRoot":"","sources":["../../../src/director/ai/mock-ai-plugin.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EACb,aAAa,EACb,SAAS,EACV,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,uBAAuB;IAGtC,MAAM,EAAE,MAAM,CAAC;IAEf,eAAe,CAAC,EAAE,aAAa,EAAE,CAAC;IAElC,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAIlC,IAAI,CAAC,EAAE,MAAM,CAAC;IAId,MAAM,EAAE,aAAa,CAAC,uBAAuB,CAAC,CAAC;IAE/C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,YAAa,YAAW,SAAS;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,WAAW;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyC;IAIhE,OAAO,CAAC,IAAI,CAAK;gBAEL,IAAI,EAAE,mBAAmB;IAM/B,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IA+BzD,WAAW,IAAI,MAAM;IAOrB,SAAS,IAAI,IAAI;CAGlB"}
@@ -0,0 +1,83 @@
1
+ // MockAIPlugin - deterministic synthetic events for tests + offline demo.
2
+ //
3
+ // Per LOOM-DIRECTOR-PROTOCOL-V2 Section 5.4: replaces real LLM
4
+ // dispatch with a scripted sequence of events keyed by tick number.
5
+ // Engine tests can wire this in place of an Anthropic-backed plugin
6
+ // to verify registry behavior, dispatch order, and downstream emit
7
+ // paths without burning API budget. The offline demo can use it to
8
+ // drive a showcase loop with predictable events.
9
+ //
10
+ // Determinism: the script is consulted on each onTick() call. The
11
+ // plugin keeps an internal tick counter that increments every call;
12
+ // the constructor's `tickKey` option lets the caller provide a
13
+ // counter source instead (e.g. tying it to the engine's frame index
14
+ // for cross-process consistency).
15
+ //
16
+ // Multiple instances: the constructor accepts an optional `name`
17
+ // override so a test can register two MockAIPlugins with different
18
+ // scripts. Without override, the name is 'mock' and registering two
19
+ // instances throws AIPluginDuplicateError (intentional - the spec
20
+ // keys plugins by name).
21
+ export class MockAIPlugin {
22
+ name;
23
+ version = '0.0.1';
24
+ priority;
25
+ script;
26
+ // Current tick count; increments every onTick() call. The first
27
+ // tick observed is 1 (matches the typical engine convention where
28
+ // tick 0 is "before-first-update").
29
+ tick = 0;
30
+ constructor(opts) {
31
+ this.name = opts.name ?? 'mock';
32
+ this.priority = opts.priority ?? 999;
33
+ this.script = opts.script;
34
+ }
35
+ async onTick(_ctx) {
36
+ this.tick++;
37
+ var characterEvents;
38
+ var zoneEvents;
39
+ for (var i = 0; i < this.script.length; i++) {
40
+ var entry = this.script[i];
41
+ if (!entry)
42
+ continue;
43
+ if (entry.atTick !== this.tick)
44
+ continue;
45
+ if (entry.characterEvents && entry.characterEvents.length > 0) {
46
+ if (!characterEvents)
47
+ characterEvents = [];
48
+ for (var ci = 0; ci < entry.characterEvents.length; ci++) {
49
+ var ce = entry.characterEvents[ci];
50
+ if (ce)
51
+ characterEvents.push(ce);
52
+ }
53
+ }
54
+ if (entry.zoneEvents && entry.zoneEvents.length > 0) {
55
+ if (!zoneEvents)
56
+ zoneEvents = [];
57
+ for (var zi = 0; zi < entry.zoneEvents.length; zi++) {
58
+ var ze = entry.zoneEvents[zi];
59
+ if (ze)
60
+ zoneEvents.push(ze);
61
+ }
62
+ }
63
+ }
64
+ var emitted = {};
65
+ if (characterEvents)
66
+ emitted.characterEvents = characterEvents;
67
+ if (zoneEvents)
68
+ emitted.zoneEvents = zoneEvents;
69
+ return emitted;
70
+ }
71
+ // Inspect-only: current tick count. Useful in tests to assert the
72
+ // plugin saw the expected number of dispatches.
73
+ currentTick() {
74
+ return this.tick;
75
+ }
76
+ // Reset the tick counter to 0 so the script can replay from the
77
+ // start. Tests that re-use a single plugin across multiple cases
78
+ // call this between cases.
79
+ resetTick() {
80
+ this.tick = 0;
81
+ }
82
+ }
83
+ //# sourceMappingURL=mock-ai-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-ai-plugin.js","sourceRoot":"","sources":["../../../src/director/ai/mock-ai-plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { PluginContext, PluginLogger, PluginStorage, PeerInfo, CharacterState } from './plugin.js';
2
+ export declare class MapPluginStorage {
3
+ private readonly store;
4
+ forPlugin(pluginName: string): PluginStorage;
5
+ clearPlugin(pluginName: string): void;
6
+ size(): number;
7
+ private composeKey;
8
+ }
9
+ export declare class ConsolePluginLogger implements PluginLogger {
10
+ private readonly pluginName;
11
+ constructor(pluginName: string);
12
+ info(msg: string, meta?: Record<string, unknown>): void;
13
+ warn(msg: string, meta?: Record<string, unknown>): void;
14
+ error(msg: string, meta?: Record<string, unknown>): void;
15
+ private write;
16
+ }
17
+ export interface BuildPluginContextOptions {
18
+ pluginName: string;
19
+ storage: MapPluginStorage;
20
+ logger?: PluginLogger;
21
+ getZonePeers?: (zoneId: string) => ReadonlyArray<PeerInfo>;
22
+ getCharacterState?: (characterId: string) => Readonly<CharacterState>;
23
+ getZoneState?: (zoneId: string) => ReadonlyMap<string, unknown>;
24
+ now?: () => number;
25
+ }
26
+ export declare function buildPluginContext(opts: BuildPluginContextOptions): PluginContext;
27
+ //# sourceMappingURL=plugin-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-context.d.ts","sourceRoot":"","sources":["../../../src/director/ai/plugin-context.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,cAAc,EACf,MAAM,aAAa,CAAC;AAQrB,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8B;IAKpD,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa;IAkB5C,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAsBrC,IAAI,IAAI,MAAM;IAId,OAAO,CAAC,UAAU;CAGnB;AAQD,qBAAa,mBAAoB,YAAW,YAAY;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,MAAM;IAE/C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIvD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIvD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIxD,OAAO,CAAC,KAAK;CAwBd;AAYD,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,gBAAgB,CAAC;IAE1B,MAAM,CAAC,EAAE,YAAY,CAAC;IAGtB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC3D,iBAAiB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,QAAQ,CAAC,cAAc,CAAC,CAAC;IACtE,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEhE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,yBAAyB,GAAG,aAAa,CAmCjF"}
@@ -0,0 +1,152 @@
1
+ // PluginContext concrete implementations.
2
+ //
3
+ // MapPluginStorage - in-memory KV backed by a single Map, namespaced
4
+ // per (pluginName, key). Survives across ticks;
5
+ // cleared when the registry calls clearPlugin().
6
+ // ConsolePluginLogger - tags every line with the plugin name and
7
+ // writes to console.{info,warn,error}. Suitable
8
+ // for tests + dev; production consumers can
9
+ // drop in a structured-log impl.
10
+ //
11
+ // These are reference implementations. Consumers wiring against
12
+ // `@sadhaka/loom-engine/server` may substitute their own
13
+ // PluginStorage / PluginLogger impls (e.g. Redis-backed storage,
14
+ // pino-backed logger) without changing the SPI surface.
15
+ //
16
+ // The registry does not assume MapPluginStorage; the SPI is
17
+ // the only contract. These exist so a consumer can stand a plugin
18
+ // up in five lines without writing a storage adapter first.
19
+ // ----- MapPluginStorage -----
20
+ //
21
+ // In-memory storage shared across all plugins; per-plugin namespace
22
+ // is enforced by composing the storage key as `${pluginName}::${key}`.
23
+ // `clearPlugin(name)` wipes every entry tagged with that plugin so
24
+ // unregister + re-register starts clean.
25
+ export class MapPluginStorage {
26
+ store = new Map();
27
+ // Build a per-plugin facade that satisfies the PluginStorage
28
+ // interface; the facade scopes get/set/delete to the plugin's
29
+ // namespace so plugin authors never see the composite key.
30
+ forPlugin(pluginName) {
31
+ var self = this;
32
+ return {
33
+ async get(key) {
34
+ return self.store.get(self.composeKey(pluginName, key));
35
+ },
36
+ async set(key, value) {
37
+ self.store.set(self.composeKey(pluginName, key), value);
38
+ },
39
+ async delete(key) {
40
+ self.store.delete(self.composeKey(pluginName, key));
41
+ },
42
+ };
43
+ }
44
+ // Wipe all entries belonging to a plugin. Called by the registry
45
+ // on unregister(). Iterates once; cost is O(total entries) but
46
+ // unregister is rare.
47
+ clearPlugin(pluginName) {
48
+ var prefix = pluginName + '::';
49
+ var keysToDelete = [];
50
+ var iter = this.store.keys();
51
+ var next = iter.next();
52
+ while (!next.done) {
53
+ var k = next.value;
54
+ if (k.startsWith(prefix)) {
55
+ keysToDelete.push(k);
56
+ }
57
+ next = iter.next();
58
+ }
59
+ for (var i = 0; i < keysToDelete.length; i++) {
60
+ var key = keysToDelete[i];
61
+ if (key !== undefined) {
62
+ this.store.delete(key);
63
+ }
64
+ }
65
+ }
66
+ // Inspect-only: total number of entries across all plugins. Useful
67
+ // in tests when asserting clearPlugin shrinks the store.
68
+ size() {
69
+ return this.store.size;
70
+ }
71
+ composeKey(pluginName, key) {
72
+ return pluginName + '::' + key;
73
+ }
74
+ }
75
+ // ----- ConsolePluginLogger -----
76
+ //
77
+ // Tags every line with `[plugin: <name>]` and forwards to the
78
+ // matching console method. Meta is JSON-stringified and appended;
79
+ // circular refs fall back to a short description so logging never
80
+ // throws at the boundary.
81
+ export class ConsolePluginLogger {
82
+ pluginName;
83
+ constructor(pluginName) {
84
+ this.pluginName = pluginName;
85
+ }
86
+ info(msg, meta) {
87
+ this.write('info', msg, meta);
88
+ }
89
+ warn(msg, meta) {
90
+ this.write('warn', msg, meta);
91
+ }
92
+ error(msg, meta) {
93
+ this.write('error', msg, meta);
94
+ }
95
+ write(level, msg, meta) {
96
+ var tag = '[plugin: ' + this.pluginName + ']';
97
+ var line = tag + ' ' + msg;
98
+ var metaStr = '';
99
+ if (meta) {
100
+ try {
101
+ metaStr = ' ' + JSON.stringify(meta);
102
+ }
103
+ catch {
104
+ metaStr = ' [meta-not-serializable]';
105
+ }
106
+ }
107
+ var out = line + metaStr;
108
+ if (level === 'info') {
109
+ console.info(out);
110
+ }
111
+ else if (level === 'warn') {
112
+ console.warn(out);
113
+ }
114
+ else {
115
+ console.error(out);
116
+ }
117
+ }
118
+ }
119
+ export function buildPluginContext(opts) {
120
+ var pluginName = opts.pluginName;
121
+ var logger = opts.logger ?? new ConsolePluginLogger(pluginName);
122
+ var storage = opts.storage.forPlugin(pluginName);
123
+ var getZonePeers = opts.getZonePeers ??
124
+ function () {
125
+ return [];
126
+ };
127
+ var getCharacterState = opts.getCharacterState ??
128
+ function (characterId) {
129
+ return {
130
+ characterId,
131
+ zone: '',
132
+ x: 0,
133
+ y: 0,
134
+ hp_current: 0,
135
+ hp_max: 0,
136
+ };
137
+ };
138
+ var getZoneState = opts.getZoneState ??
139
+ function () {
140
+ return new Map();
141
+ };
142
+ var now = opts.now ?? Date.now;
143
+ return {
144
+ getZonePeers,
145
+ getCharacterState,
146
+ getZoneState,
147
+ storage,
148
+ logger,
149
+ now,
150
+ };
151
+ }
152
+ //# sourceMappingURL=plugin-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-context.js","sourceRoot":"","sources":["../../../src/director/ai/plugin-context.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,qEAAqE;AACrE,iEAAiE;AACjE,sEAAsE;AACtE,kEAAkE;AAClE,uDAAuD;AACvD,EAAE;AACF,gEAAgE;AAChE,yDAAyD;AACzD,iEAAiE;AACjE,wDAAwD;AACxD,EAAE;AACF,4DAA4D;AAC5D,kEAAkE;AAClE,4DAA4D;AAU5D,+BAA+B;AAC/B,EAAE;AACF,oEAAoE;AACpE,uEAAuE;AACvE,mEAAmE;AACnE,yCAAyC;AACzC,MAAM,OAAO,gBAAgB;IACV,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;IAEpD,6DAA6D;IAC7D,8DAA8D;IAC9D,2DAA2D;IAC3D,SAAS,CAAC,UAAkB;QAC1B,IAAI,IAAI,GAAG,IAAI,CAAC;QAChB,OAAO;YACL,KAAK,CAAC,GAAG,CAAC,GAAW;gBACnB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC;YAC1D,CAAC;YACD,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAc;gBACnC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;YAC1D,CAAC;YACD,KAAK,CAAC,MAAM,CAAC,GAAW;gBACtB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC;YACtD,CAAC;SACF,CAAC;IACJ,CAAC;IAED,iEAAiE;IACjE,+DAA+D;IAC/D,sBAAsB;IACtB,WAAW,CAAC,UAAkB;QAC5B,IAAI,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC;QAC/B,IAAI,YAAY,GAAa,EAAE,CAAC;QAChC,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;YACnB,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzB,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACvB,CAAC;YACD,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACrB,CAAC;QACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,IAAI,GAAG,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;YAC1B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACtB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC;IAED,mEAAmE;IACnE,yDAAyD;IACzD,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAEO,UAAU,CAAC,UAAkB,EAAE,GAAW;QAChD,OAAO,UAAU,GAAG,IAAI,GAAG,GAAG,CAAC;IACjC,CAAC;CACF;AAED,kCAAkC;AAClC,EAAE;AACF,8DAA8D;AAC9D,kEAAkE;AAClE,kEAAkE;AAClE,0BAA0B;AAC1B,MAAM,OAAO,mBAAmB;IACD;IAA7B,YAA6B,UAAkB;QAAlB,eAAU,GAAV,UAAU,CAAQ;IAAG,CAAC;IAEnD,IAAI,CAAC,GAAW,EAAE,IAA8B;QAC9C,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,IAAI,CAAC,GAAW,EAAE,IAA8B;QAC9C,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,GAAW,EAAE,IAA8B;QAC/C,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACjC,CAAC;IAEO,KAAK,CACX,KAAgC,EAChC,GAAW,EACX,IAA8B;QAE9B,IAAI,GAAG,GAAG,WAAW,GAAG,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QAC9C,IAAI,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;QAC3B,IAAI,OAAO,GAAG,EAAE,CAAC;QACjB,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC;gBACH,OAAO,GAAG,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACvC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,GAAG,0BAA0B,CAAC;YACvC,CAAC;QACH,CAAC;QACD,IAAI,GAAG,GAAG,IAAI,GAAG,OAAO,CAAC;QACzB,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;aAAM,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;CACF;AA0BD,MAAM,UAAU,kBAAkB,CAAC,IAA+B;IAChE,IAAI,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;IACjC,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAChE,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IACjD,IAAI,YAAY,GACd,IAAI,CAAC,YAAY;QACjB;YACE,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;IACJ,IAAI,iBAAiB,GACnB,IAAI,CAAC,iBAAiB;QACtB,UAAU,WAAmB;YAC3B,OAAO;gBACL,WAAW;gBACX,IAAI,EAAE,EAAE;gBACR,CAAC,EAAE,CAAC;gBACJ,CAAC,EAAE,CAAC;gBACJ,UAAU,EAAE,CAAC;gBACb,MAAM,EAAE,CAAC;aACV,CAAC;QACJ,CAAC,CAAC;IACJ,IAAI,YAAY,GACd,IAAI,CAAC,YAAY;QACjB;YACE,OAAO,IAAI,GAAG,EAAmB,CAAC;QACpC,CAAC,CAAC;IACJ,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IAC/B,OAAO;QACL,YAAY;QACZ,iBAAiB;QACjB,YAAY;QACZ,OAAO;QACP,MAAM;QACN,GAAG;KACJ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,57 @@
1
+ import type { DirectorEvent } from '../event-envelope.js';
2
+ import type { ZoneEvent } from '../zone/zone-event-envelope.js';
3
+ export type { ZoneEvent };
4
+ export interface EmittedEvents {
5
+ characterEvents?: DirectorEvent[];
6
+ zoneEvents?: ZoneEvent[];
7
+ }
8
+ export interface PeerInfo {
9
+ characterId: string;
10
+ userId: string;
11
+ zone: string;
12
+ x: number;
13
+ y: number;
14
+ name: string | null;
15
+ }
16
+ export interface PlayerAction {
17
+ kind: 'damage' | 'interact' | 'speak' | 'use_item' | (string & {});
18
+ payload: Record<string, unknown>;
19
+ }
20
+ export interface CharacterState {
21
+ characterId: string;
22
+ zone: string;
23
+ x: number;
24
+ y: number;
25
+ hp_current: number;
26
+ hp_max: number;
27
+ }
28
+ export interface PluginStorage {
29
+ get(key: string): Promise<unknown | undefined>;
30
+ set(key: string, value: unknown): Promise<void>;
31
+ delete(key: string): Promise<void>;
32
+ }
33
+ export interface PluginLogger {
34
+ info(msg: string, meta?: Record<string, unknown>): void;
35
+ warn(msg: string, meta?: Record<string, unknown>): void;
36
+ error(msg: string, meta?: Record<string, unknown>): void;
37
+ }
38
+ export interface PluginContext {
39
+ getZonePeers(zoneId: string): ReadonlyArray<PeerInfo>;
40
+ getCharacterState(characterId: string): Readonly<CharacterState>;
41
+ getZoneState(zoneId: string): ReadonlyMap<string, unknown>;
42
+ storage: PluginStorage;
43
+ logger: PluginLogger;
44
+ now: () => number;
45
+ }
46
+ export interface IAIPlugin {
47
+ readonly name: string;
48
+ readonly version: string;
49
+ readonly priority: number;
50
+ onTick?(ctx: PluginContext): Promise<EmittedEvents>;
51
+ onPeerJoin?(ctx: PluginContext, peer: PeerInfo): Promise<EmittedEvents>;
52
+ onPeerLeave?(ctx: PluginContext, peer: PeerInfo): Promise<EmittedEvents>;
53
+ onZoneEnter?(ctx: PluginContext, peer: PeerInfo, fromZone: string | null): Promise<EmittedEvents>;
54
+ onPlayerAction?(ctx: PluginContext, peer: PeerInfo, action: PlayerAction): Promise<EmittedEvents>;
55
+ dispose?(): Promise<void>;
56
+ }
57
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/director/ai/plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ // IAIPlugin - server-side plugin SPI for the Director.
2
+ //
3
+ // Per LOOM-DIRECTOR-PROTOCOL-V2 Section 5: the engine no longer
4
+ // hardcodes a single Anthropic flow. Consumers register any number of
5
+ // IAIPlugin implementations against the AIPluginRegistry, and the
6
+ // runtime dispatches lifecycle hooks (tick, peer join/leave, zone
7
+ // enter, player action). Each hook returns EmittedEvents - either
8
+ // per-character v1 envelopes, v2 zone events, or both.
9
+ //
10
+ // This module is server-only. The browser bundle never imports it.
11
+ // It is exposed only via the `@sadhaka/loom-engine/server` entry
12
+ // point so consumers can wire LLM-backed plugins (Anthropic, OpenAI,
13
+ // local models, deterministic state machines, ...) on the Node side
14
+ // while the browser engine stays small.
15
+ //
16
+ // `ZoneEvent` (LOOM-DIRECTOR-PROTOCOL-V2 §3) is defined in
17
+ // `src/director/zone/zone-event-envelope.ts` (Track A, merged into
18
+ // 0.14.0 alongside this module). The registry carries zone events
19
+ // opaquely - it never dereferences fields beyond the discriminated
20
+ // union - so the only consumer of the strict type is plugin authors
21
+ // constructing ZoneEvent values in their hook returns.
22
+ //
23
+ // Spec invariants preserved:
24
+ // - All hooks are async; they return EmittedEvents.
25
+ // - Hooks not implemented by a plugin are simply omitted; the
26
+ // registry checks `typeof plugin.onX === 'function'` before call.
27
+ // - Plugins are pure-ish: given a context, they return events.
28
+ // State mutation is the engine's job (open question 8.2 resolved).
29
+ // - Plugin-direct event emission outside its returned EmittedEvents
30
+ // is not supported; the registry is the single funnel.
31
+ export {};
32
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../src/director/ai/plugin.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,EAAE;AACF,gEAAgE;AAChE,sEAAsE;AACtE,kEAAkE;AAClE,kEAAkE;AAClE,kEAAkE;AAClE,uDAAuD;AACvD,EAAE;AACF,mEAAmE;AACnE,iEAAiE;AACjE,qEAAqE;AACrE,oEAAoE;AACpE,wCAAwC;AACxC,EAAE;AACF,2DAA2D;AAC3D,mEAAmE;AACnE,kEAAkE;AAClE,mEAAmE;AACnE,oEAAoE;AACpE,uDAAuD;AACvD,EAAE;AACF,6BAA6B;AAC7B,sDAAsD;AACtD,gEAAgE;AAChE,sEAAsE;AACtE,iEAAiE;AACjE,uEAAuE;AACvE,sEAAsE;AACtE,2DAA2D"}
@@ -0,0 +1,27 @@
1
+ export type { EventEnvelope, DirectorEvent, DirectorEventType, DirectorEventDataMap, EventPriority, EncounterSpawnData, EncounterTickData, EncounterEndData, EncounterLootData, KnotContextData, KnotPaletteHex, KnotMood, VeBudgetUpdateData, VeilTier, SceneTransitionData, SceneTransitionKind, NarratorLineData, NarratorVoice, SystemHeartbeatData, SystemReplayCompleteData, SystemSnapshotRequiredData, MobSpec, BossSpec, DropSpec, } from './event-envelope.js';
2
+ export { parseEnvelope, parseEnvelopeJson, priorityFor, EventEnvelopeParseError, } from './event-envelope.js';
3
+ export type { IDirectorBridge, DirectorBridgeStatus, DirectorBridgeStats, } from './director-bridge.js';
4
+ export { RESOURCE_DIRECTOR_BRIDGE, RESOURCE_KNOT_CONTEXT, } from './director-bridge.js';
5
+ export { MockDirectorBridge } from './mock-director-bridge.js';
6
+ export type { SSEDirectorBridgeOptions } from './sse-director-bridge.js';
7
+ export { SSEDirectorBridge } from './sse-director-bridge.js';
8
+ export type { KnotPaletteRgba } from './knot-context-resource.js';
9
+ export { KnotContextResource } from './knot-context-resource.js';
10
+ export type { DirectorEventLog } from './director-system.js';
11
+ export { DirectorSystem, RESOURCE_DIRECTOR_LOG, createDirectorEventLog, } from './director-system.js';
12
+ export type { DirectorEncounterSystemOptions } from './director-encounter-system.js';
13
+ export { DirectorEncounterSystem } from './director-encounter-system.js';
14
+ export type { ZoneEventEnvelope, ZoneEvent, ZoneEventType, ZoneEventDataMap, ZoneBossSpec, ZoneBossSpawnData, ZoneBossTickData, ZoneBossEndData, ZoneBossOutcome, ZoneBossHit, ZoneNarratorData, ZoneKnotData, ZoneStateData, ZoneSnapshotData, ZoneStateChange, } from './zone/zone-event-envelope.js';
15
+ export { parseZoneEnvelope, parseZoneEnvelopeJson, priorityFor as zonePriorityFor, ZoneEventEnvelopeParseError, } from './zone/zone-event-envelope.js';
16
+ export type { IZoneEventBridge, ZoneEventBridgeStatus, ZoneEventBridgeStats, } from './zone/zone-event-bridge.js';
17
+ export { RESOURCE_ZONE_EVENT_BRIDGE } from './zone/zone-event-bridge.js';
18
+ export { MockZoneBridge } from './zone/mock-zone-bridge.js';
19
+ export type { SSEZoneBridgeOptions, SSEZoneBridgeEventSource, } from './zone/sse-zone-bridge.js';
20
+ export { SSEZoneBridge } from './zone/sse-zone-bridge.js';
21
+ export type { ZoneEventLog, ZoneEventLogEntry, } from './zone/zone-event-log.js';
22
+ export { RESOURCE_ZONE_EVENT_LOG, ZONE_RING_SIZE, createZoneEventLog, getOrCreateZoneEntry, pushZoneEvent, } from './zone/zone-event-log.js';
23
+ export type { DirectorZoneStateResource } from './zone/zone-state-resource.js';
24
+ export { RESOURCE_DIRECTOR_ZONE_STATE, createDirectorZoneStateResource, getOrCreateZoneStateMap, applyZoneStateChanges, replaceZoneStateFromSnapshot, } from './zone/zone-state-resource.js';
25
+ export type { ZoneEventSystemOptions } from './zone/zone-event-system.js';
26
+ export { ZoneEventSystem } from './zone/zone-event-system.js';
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/director/index.ts"],"names":[],"mappings":"AAaA,YAAY,EACV,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,QAAQ,EACR,kBAAkB,EAClB,QAAQ,EACR,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,EAC1B,OAAO,EACP,QAAQ,EACR,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,eAAe,EACf,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,YAAY,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,YAAY,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAGzE,YAAY,EACV,iBAAiB,EACjB,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,eAAe,GAChB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,WAAW,IAAI,eAAe,EAC9B,2BAA2B,GAC5B,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,YAAY,EACV,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,YAAY,EACV,YAAY,EACZ,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,GACd,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC/E,OAAO,EACL,4BAA4B,EAC5B,+BAA+B,EAC/B,uBAAuB,EACvB,qBAAqB,EACrB,4BAA4B,GAC7B,MAAM,+BAA+B,CAAC;AACvC,YAAY,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,26 @@
1
+ // Director module barrel - re-exports the v1 (Phase 6) surface plus
2
+ // the v2 (Phase 16) zone-event surface.
3
+ //
4
+ // v1 lives at the top level of src/director/. v2 lives under
5
+ // src/director/zone/. Track B's AI Plugin SPI lives under
6
+ // src/director/ai/ and is re-exported via @sadhaka/loom-engine/server,
7
+ // not from here. We do not pull AI plugin types into this barrel so
8
+ // the browser bundle stays small.
9
+ //
10
+ // Engine-level public re-exports happen in ../index.ts. Internal
11
+ // callers can import from this barrel for convenience.
12
+ export { parseEnvelope, parseEnvelopeJson, priorityFor, EventEnvelopeParseError, } from './event-envelope.js';
13
+ export { RESOURCE_DIRECTOR_BRIDGE, RESOURCE_KNOT_CONTEXT, } from './director-bridge.js';
14
+ export { MockDirectorBridge } from './mock-director-bridge.js';
15
+ export { SSEDirectorBridge } from './sse-director-bridge.js';
16
+ export { KnotContextResource } from './knot-context-resource.js';
17
+ export { DirectorSystem, RESOURCE_DIRECTOR_LOG, createDirectorEventLog, } from './director-system.js';
18
+ export { DirectorEncounterSystem } from './director-encounter-system.js';
19
+ export { parseZoneEnvelope, parseZoneEnvelopeJson, priorityFor as zonePriorityFor, ZoneEventEnvelopeParseError, } from './zone/zone-event-envelope.js';
20
+ export { RESOURCE_ZONE_EVENT_BRIDGE } from './zone/zone-event-bridge.js';
21
+ export { MockZoneBridge } from './zone/mock-zone-bridge.js';
22
+ export { SSEZoneBridge } from './zone/sse-zone-bridge.js';
23
+ export { RESOURCE_ZONE_EVENT_LOG, ZONE_RING_SIZE, createZoneEventLog, getOrCreateZoneEntry, pushZoneEvent, } from './zone/zone-event-log.js';
24
+ export { RESOURCE_DIRECTOR_ZONE_STATE, createDirectorZoneStateResource, getOrCreateZoneStateMap, applyZoneStateChanges, replaceZoneStateFromSnapshot, } from './zone/zone-state-resource.js';
25
+ export { ZoneEventSystem } from './zone/zone-event-system.js';
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/director/index.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,wCAAwC;AACxC,EAAE;AACF,6DAA6D;AAC7D,0DAA0D;AAC1D,uEAAuE;AACvE,oEAAoE;AACpE,kCAAkC;AAClC,EAAE;AACF,iEAAiE;AACjE,uDAAuD;AA6BvD,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAoBzE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,WAAW,IAAI,eAAe,EAC9B,2BAA2B,GAC5B,MAAM,+BAA+B,CAAC;AAMvC,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAK5D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAK1D,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,GACd,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,4BAA4B,EAC5B,+BAA+B,EAC/B,uBAAuB,EACvB,qBAAqB,EACrB,4BAA4B,GAC7B,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { ZoneEvent } from './zone-event-envelope.js';
2
+ import { type IZoneEventBridge, type ZoneEventBridgeStatus, type ZoneEventBridgeStats } from './zone-event-bridge.js';
3
+ export declare class MockZoneBridge implements IZoneEventBridge {
4
+ private queue;
5
+ private statusValue;
6
+ private readonly lastEventIdByZone;
7
+ private readonly statsValue;
8
+ start(): void;
9
+ stop(): void;
10
+ status(): ZoneEventBridgeStatus;
11
+ isConnected(): boolean;
12
+ getLastEventId(zone: string): number;
13
+ pollEvents(): ZoneEvent[];
14
+ stats(): Readonly<ZoneEventBridgeStats>;
15
+ enqueueIncoming(event: ZoneEvent): void;
16
+ enqueueIncomingJson(json: string): boolean;
17
+ enqueueAll(events: ReadonlyArray<ZoneEvent>): void;
18
+ bumpReconnect(): void;
19
+ setServerDrops(p1: number, p2: number): void;
20
+ pending(): number;
21
+ }
22
+ //# sourceMappingURL=mock-zone-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-zone-bridge.d.ts","sourceRoot":"","sources":["../../../src/director/zone/mock-zone-bridge.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAC1B,MAAM,wBAAwB,CAAC;AAEhC,qBAAa,cAAe,YAAW,gBAAgB;IACrD,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAkC;IACpE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAYzB;IAEF,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,IAAI;IAIZ,MAAM,IAAI,qBAAqB;IAI/B,WAAW,IAAI,OAAO;IAItB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIpC,UAAU,IAAI,SAAS,EAAE;IAOzB,KAAK,IAAI,QAAQ,CAAC,oBAAoB,CAAC;IAmBvC,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAavC,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAQ1C,UAAU,CAAC,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,GAAG,IAAI;IAQlD,aAAa,IAAI,IAAI;IAKrB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAM5C,OAAO,IAAI,MAAM;CAGlB"}
@@ -0,0 +1,107 @@
1
+ // MockZoneBridge - in-memory v2 zone-event source for tests + offline
2
+ // demos.
3
+ //
4
+ // Tests inject envelopes via enqueueIncoming() and let ZoneEventSystem
5
+ // drain them. The demo path can also use this when running without a
6
+ // backend connection. pollEvents() drains the queue in FIFO order.
7
+ //
8
+ // Tracks per-zone lastEventId so the IZoneEventBridge contract is
9
+ // satisfied. Does not reconnect, does not validate envelopes when fed
10
+ // objects directly - that's parseZoneEnvelope's job upstream of
11
+ // enqueueIncoming(). enqueueIncomingJson() is a convenience that runs
12
+ // the parser first and silently drops malformed payloads (mirrors how
13
+ // SSEZoneBridge would handle a bad frame).
14
+ import { parseZoneEnvelopeJson } from './zone-event-envelope.js';
15
+ export class MockZoneBridge {
16
+ queue = [];
17
+ statusValue = 'idle';
18
+ lastEventIdByZone = new Map();
19
+ statsValue = {
20
+ eventsReceived: 0,
21
+ reconnects: 0,
22
+ outOfOrderEvents: 0,
23
+ serverDropsP1: 0,
24
+ serverDropsP2: 0,
25
+ };
26
+ start() {
27
+ this.statusValue = 'connected';
28
+ }
29
+ stop() {
30
+ this.statusValue = 'closed';
31
+ }
32
+ status() {
33
+ return this.statusValue;
34
+ }
35
+ isConnected() {
36
+ return this.statusValue === 'connected';
37
+ }
38
+ getLastEventId(zone) {
39
+ return this.lastEventIdByZone.get(zone) ?? 0;
40
+ }
41
+ pollEvents() {
42
+ if (this.queue.length === 0)
43
+ return [];
44
+ const out = this.queue;
45
+ this.queue = [];
46
+ return out;
47
+ }
48
+ stats() {
49
+ // Allocate the read-only view fresh each call so mutations after
50
+ // the call don't leak through. lastEventIdByZone is wrapped in a
51
+ // shallow clone; spec calls this rare so cost is fine.
52
+ return {
53
+ eventsReceived: this.statsValue.eventsReceived,
54
+ reconnects: this.statsValue.reconnects,
55
+ outOfOrderEvents: this.statsValue.outOfOrderEvents,
56
+ serverDropsP1: this.statsValue.serverDropsP1,
57
+ serverDropsP2: this.statsValue.serverDropsP2,
58
+ lastEventIdByZone: new Map(this.lastEventIdByZone),
59
+ };
60
+ }
61
+ // ----- Mock-only injection helpers -----
62
+ // Enqueue a parsed envelope as if the server pushed it. Out-of-order
63
+ // injection is allowed; the consumer's per-zone gap detection should
64
+ // handle it.
65
+ enqueueIncoming(event) {
66
+ this.queue.push(event);
67
+ this.statsValue.eventsReceived++;
68
+ const prev = this.lastEventIdByZone.get(event.zone_id) ?? 0;
69
+ if (event.id > prev) {
70
+ this.lastEventIdByZone.set(event.zone_id, event.id);
71
+ }
72
+ else {
73
+ this.statsValue.outOfOrderEvents++;
74
+ }
75
+ }
76
+ // Convenience: enqueue from a JSON string. Silently drops malformed
77
+ // payloads, matching the SSE bridge's parse-error behaviour.
78
+ enqueueIncomingJson(json) {
79
+ const ev = parseZoneEnvelopeJson(json);
80
+ if (!ev)
81
+ return false;
82
+ this.enqueueIncoming(ev);
83
+ return true;
84
+ }
85
+ // Convenience: bulk enqueue.
86
+ enqueueAll(events) {
87
+ for (let i = 0; i < events.length; i++) {
88
+ const e = events[i];
89
+ if (e)
90
+ this.enqueueIncoming(e);
91
+ }
92
+ }
93
+ // Mock-only: simulate the server crediting a reconnect.
94
+ bumpReconnect() {
95
+ this.statsValue.reconnects++;
96
+ }
97
+ // Mock-only: simulate server-side drop counters from a heartbeat.
98
+ setServerDrops(p1, p2) {
99
+ this.statsValue.serverDropsP1 = p1;
100
+ this.statsValue.serverDropsP2 = p2;
101
+ }
102
+ // Inspect-only: how many events are buffered waiting for a poll.
103
+ pending() {
104
+ return this.queue.length;
105
+ }
106
+ }
107
+ //# sourceMappingURL=mock-zone-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-zone-bridge.js","sourceRoot":"","sources":["../../../src/director/zone/mock-zone-bridge.ts"],"names":[],"mappings":"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"}