@substrate-ai/core 0.20.1 → 0.20.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/README.md +33 -33
  2. package/package.json +10 -2
  3. package/dist/__tests__/adapter.test.d.ts +0 -12
  4. package/dist/__tests__/adapter.test.d.ts.map +0 -1
  5. package/dist/__tests__/adapter.test.js +0 -259
  6. package/dist/__tests__/adapter.test.js.map +0 -1
  7. package/dist/__tests__/event-bus.test.d.ts +0 -14
  8. package/dist/__tests__/event-bus.test.d.ts.map +0 -1
  9. package/dist/__tests__/event-bus.test.js +0 -199
  10. package/dist/__tests__/event-bus.test.js.map +0 -1
  11. package/dist/__tests__/output-quality.test.d.ts +0 -8
  12. package/dist/__tests__/output-quality.test.d.ts.map +0 -1
  13. package/dist/__tests__/output-quality.test.js +0 -166
  14. package/dist/__tests__/output-quality.test.js.map +0 -1
  15. package/dist/__tests__/schema-suffix.test.d.ts +0 -9
  16. package/dist/__tests__/schema-suffix.test.d.ts.map +0 -1
  17. package/dist/__tests__/schema-suffix.test.js +0 -126
  18. package/dist/__tests__/schema-suffix.test.js.map +0 -1
  19. package/dist/__tests__/yaml-parser.test.d.ts +0 -18
  20. package/dist/__tests__/yaml-parser.test.d.ts.map +0 -1
  21. package/dist/__tests__/yaml-parser.test.js +0 -475
  22. package/dist/__tests__/yaml-parser.test.js.map +0 -1
  23. package/dist/adapters/__tests__/adapter-output-normalizer.test.d.ts +0 -12
  24. package/dist/adapters/__tests__/adapter-output-normalizer.test.d.ts.map +0 -1
  25. package/dist/adapters/__tests__/adapter-output-normalizer.test.js +0 -193
  26. package/dist/adapters/__tests__/adapter-output-normalizer.test.js.map +0 -1
  27. package/dist/persistence/dolt-adapter-transaction.test.d.ts +0 -10
  28. package/dist/persistence/dolt-adapter-transaction.test.d.ts.map +0 -1
  29. package/dist/persistence/dolt-adapter-transaction.test.js +0 -359
  30. package/dist/persistence/dolt-adapter-transaction.test.js.map +0 -1
package/README.md CHANGED
@@ -1,55 +1,55 @@
1
1
  # @substrate-ai/core
2
2
 
3
- General-purpose agent infrastructure for the Substrate platform. This package contains all transport-agnostic modules extracted from the Substrate monolith during Epic 41 (Core Extraction Phase 1). Downstream packages `substrate-ai` (SDLC), factory, and any custom orchestrators — import from `@substrate-ai/core` without coupling to SDLC-specific types.
3
+ Transport-agnostic primitives for the [Substrate](https://github.com/johnplanow/substrate) platform. This is the foundation package adapters, dispatch, routing, persistence, telemetry, cost tracking, event bus, and supervisor analysis kept free of SDLC-specific concerns so downstream packages (`@substrate-ai/sdlc`, `@substrate-ai/factory`, or custom orchestrators) can compose the pieces they need.
4
4
 
5
- ## Exported Modules
5
+ ## Install
6
6
 
7
- | Namespace | Key exports |
7
+ ```bash
8
+ npm install @substrate-ai/core
9
+ ```
10
+
11
+ Node 22 or later is required. If you plan to use the Dolt persistence adapter in socket mode, also install `mysql2` — it is declared as an optional peer dependency so consumers who only use the CLI or file-backed adapters skip the transitive binary.
12
+
13
+ ## Modules
14
+
15
+ | Namespace | Representative exports |
8
16
  |---|---|
9
17
  | **adapters** | `WorkerAdapter`, `AdapterRegistry`, `SpawnCommand`, `AdapterOptions` |
18
+ | **budget** | `BudgetTracker` |
10
19
  | **config** | `SubstrateConfig`, config loader, validation helpers |
11
- | **dispatch** | `Dispatcher`, `DispatchRequest`, `DispatchHandle`, `DispatchResult`, `DispatchConfig` |
12
- | **events** | `TypedEventBus`, `TypedEventBusImpl`, `createEventBus`, `CoreEvents`, `EventMap`, `EventHandler` |
13
- | **git** | Git utilities, worktree management, `GitManager` |
14
- | **persistence** | `DatabaseAdapter`, `DatabaseAdapterConfig`, `SyncAdapter`, `isSyncAdapter`, `InitSchemaFn` |
15
- | **routing** | `RoutingDecision`, `RoutingPolicy`, `IRoutingResolver`, `ModelResolution` |
16
- | **telemetry** | Telemetry pipeline, scoring modules, `ITelemetryPersistence`, `estimateCost` |
17
- | **supervisor** | Analysis engine, experimenter framework |
18
- | **budget** | `BudgetTracker` interface and implementation |
19
- | **cost-tracker** | Token rates, cost tracking, `CostEntry`, `TaskCostSummary`, `SessionCostSummary` |
20
- | **monitor** | `MonitorAgent`, `RecommendationEngine`, `ReportGenerator`, `TaskTypeClassifier` |
21
- | **version-manager** | `VersionManager`, `VersionManagerImpl`, `UpdateChecker`, `VersionCache` |
22
20
  | **context** | `ContextCompiler`, `TaskDescriptor`, `CompileResult` |
21
+ | **cost-tracker** | `CostTracker`, `CostEntry`, `TaskCostSummary`, `TOKEN_RATES` |
22
+ | **dispatch** | `Dispatcher`, `DispatchRequest`, `DispatchHandle`, `DispatchResult` |
23
+ | **events** | `TypedEventBus`, `createEventBus`, `CoreEvents`, `EventMap`, `EventHandler` |
24
+ | **git** | Git utilities, worktree management, `GitManager` |
25
+ | **llm** | `callLLM`, `LLMCallParams`, `LLMCallResult` (default stub — provide your own implementation) |
26
+ | **monitor** | `MonitorAgent`, `RecommendationEngine`, `ReportGenerator` |
27
+ | **persistence** | `DatabaseAdapter`, `SyncAdapter`, `createDatabaseAdapter` |
23
28
  | **quality-gates** | `QualityGate`, `GatePipeline`, `GateResult` |
29
+ | **routing** | `RoutingDecision`, `RoutingPolicy`, `IRoutingResolver` |
30
+ | **supervisor** | Analysis engine, experimenter framework |
31
+ | **telemetry** | Telemetry pipeline, scoring modules, `estimateCost` |
32
+ | **version-manager** | `VersionManager`, `UpdateChecker`, `VersionCache` |
24
33
 
25
34
  ## Usage
26
35
 
27
36
  ```typescript
28
- // Event bus subscribe and publish typed pipeline events
29
- import { createEventBus, TypedEventBus } from '@substrate-ai/core';
37
+ import { createEventBus, type TypedEventBus } from '@substrate-ai/core'
30
38
 
31
- const bus: TypedEventBus = createEventBus();
32
- bus.on('story:complete', (event) => console.log('Story done:', event.storyKey));
39
+ const bus: TypedEventBus = createEventBus()
40
+ bus.on('story:complete', (event) => console.log('Story done:', event.storyKey))
33
41
  ```
34
42
 
35
43
  ```typescript
36
- // Adapter registry register and retrieve worker adapters
37
- import { AdapterRegistry, WorkerAdapter } from '@substrate-ai/core';
44
+ import { AdapterRegistry } from '@substrate-ai/core'
38
45
 
39
- const registry = new AdapterRegistry();
40
- registry.register('claude', myClaudeAdapter);
41
- const adapter: WorkerAdapter = registry.get('claude');
46
+ const registry = new AdapterRegistry()
47
+ registry.register('claude', myClaudeAdapter)
48
+ const adapter = registry.get('claude')
42
49
  ```
43
50
 
44
- ```typescript
45
- // Persistence — create a database adapter for pipeline state
46
- import { DatabaseAdapterConfig, createDatabaseAdapter } from '@substrate-ai/core';
47
-
48
- const config: DatabaseAdapterConfig = { backend: 'dolt', basePath: '.substrate' };
49
- const db = await createDatabaseAdapter(config);
50
- await db.initSchema(mySchema);
51
- ```
51
+ ## Versioning
52
52
 
53
- ## Version
53
+ This package releases in lockstep with `substrate-ai` on every `v*` tag push. Pick any version ≥ `0.20.1` — all four `@substrate-ai/*` packages publish together with verified npm provenance.
54
54
 
55
- `@substrate-ai/core` follows the root `substrate-ai` version. Current version: **0.9.0** (Epic 41 — Core Extraction Phase 1 complete).
55
+ See the [main repository](https://github.com/johnplanow/substrate) for the full platform documentation.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@substrate-ai/core",
3
- "version": "0.20.1",
3
+ "version": "0.20.2",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -22,12 +22,20 @@
22
22
  "scripts": {
23
23
  "build": "tsc -b"
24
24
  },
25
+ "engines": {
26
+ "node": ">=22.0.0"
27
+ },
25
28
  "dependencies": {
26
29
  "js-yaml": "^4.1.1",
27
30
  "semver": "^7.6.3",
28
31
  "zod": "^4.3.6"
29
32
  },
30
- "optionalDependencies": {
33
+ "peerDependencies": {
31
34
  "mysql2": "^3.20.0"
35
+ },
36
+ "peerDependenciesMeta": {
37
+ "mysql2": {
38
+ "optional": true
39
+ }
32
40
  }
33
41
  }
@@ -1,12 +0,0 @@
1
- /**
2
- * Unit tests for packages/core/src/persistence/adapter.ts
3
- *
4
- * Tests the createDatabaseAdapter() factory function with all three backend
5
- * modes (auto, memory, dolt), Dolt availability detection, fallback logic,
6
- * and warning messages.
7
- *
8
- * All filesystem and child_process interactions are mocked — no real Dolt
9
- * installation is required.
10
- */
11
- export {};
12
- //# sourceMappingURL=adapter.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"adapter.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/adapter.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
@@ -1,259 +0,0 @@
1
- /**
2
- * Unit tests for packages/core/src/persistence/adapter.ts
3
- *
4
- * Tests the createDatabaseAdapter() factory function with all three backend
5
- * modes (auto, memory, dolt), Dolt availability detection, fallback logic,
6
- * and warning messages.
7
- *
8
- * All filesystem and child_process interactions are mocked — no real Dolt
9
- * installation is required.
10
- */
11
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
12
- import { createDatabaseAdapter } from '../persistence/adapter.js';
13
- import { DoltDatabaseAdapter } from '../persistence/dolt-adapter.js';
14
- import { InMemoryDatabaseAdapter } from '../persistence/memory-adapter.js';
15
- // ---------------------------------------------------------------------------
16
- // Mock node:child_process and node:fs
17
- // ---------------------------------------------------------------------------
18
- vi.mock('node:child_process', () => ({
19
- spawnSync: vi.fn(),
20
- }));
21
- vi.mock('node:fs', () => ({
22
- existsSync: vi.fn(),
23
- }));
24
- import { spawnSync } from 'node:child_process';
25
- import { existsSync } from 'node:fs';
26
- const mockedSpawnSync = vi.mocked(spawnSync);
27
- const mockedExistsSync = vi.mocked(existsSync);
28
- // ---------------------------------------------------------------------------
29
- // Helper: create a mock DoltClientLike factory
30
- // ---------------------------------------------------------------------------
31
- function makeMockDoltClientFactory() {
32
- const mockClient = {
33
- query: vi.fn().mockResolvedValue([]),
34
- close: vi.fn().mockResolvedValue(undefined),
35
- };
36
- const factory = vi.fn().mockReturnValue(mockClient);
37
- return { factory, mockClient };
38
- }
39
- // ---------------------------------------------------------------------------
40
- // Helper: configure mocks so isDoltAvailable returns true
41
- // ---------------------------------------------------------------------------
42
- function configureDoltAvailable() {
43
- mockedExistsSync.mockReturnValue(true);
44
- mockedSpawnSync.mockReturnValue({
45
- status: 0,
46
- pid: 1,
47
- output: [],
48
- stdout: Buffer.from(''),
49
- stderr: Buffer.from(''),
50
- signal: null,
51
- });
52
- }
53
- // ---------------------------------------------------------------------------
54
- // Helper: configure mocks so isDoltAvailable returns false (no .dolt dir)
55
- // ---------------------------------------------------------------------------
56
- function configureDoltUnavailable() {
57
- mockedExistsSync.mockReturnValue(false);
58
- mockedSpawnSync.mockReturnValue({
59
- error: new Error('ENOENT'),
60
- status: null,
61
- pid: 0,
62
- output: [],
63
- stdout: Buffer.from(''),
64
- stderr: Buffer.from(''),
65
- signal: null,
66
- });
67
- }
68
- // ---------------------------------------------------------------------------
69
- // Helper: configure mocks so .dolt dir exists but binary fails
70
- // ---------------------------------------------------------------------------
71
- function configureDoltDirExistsBinaryFails() {
72
- mockedExistsSync.mockReturnValue(true);
73
- mockedSpawnSync.mockReturnValue({
74
- error: new Error('ENOENT'),
75
- status: null,
76
- pid: 0,
77
- output: [],
78
- stdout: Buffer.from(''),
79
- stderr: Buffer.from(''),
80
- signal: null,
81
- });
82
- }
83
- // ---------------------------------------------------------------------------
84
- // Tests
85
- // ---------------------------------------------------------------------------
86
- describe('createDatabaseAdapter', () => {
87
- beforeEach(() => {
88
- vi.clearAllMocks();
89
- });
90
- afterEach(() => {
91
- vi.restoreAllMocks();
92
- });
93
- // -------------------------------------------------------------------------
94
- // backend = 'memory'
95
- // -------------------------------------------------------------------------
96
- describe('backend = "memory"', () => {
97
- it('returns an InMemoryDatabaseAdapter regardless of Dolt availability', () => {
98
- configureDoltAvailable();
99
- const adapter = createDatabaseAdapter({ backend: 'memory' });
100
- expect(adapter).toBeInstanceOf(InMemoryDatabaseAdapter);
101
- // Should not probe Dolt at all
102
- expect(mockedExistsSync).not.toHaveBeenCalled();
103
- expect(mockedSpawnSync).not.toHaveBeenCalled();
104
- });
105
- it('does not call the doltClientFactory when backend is memory', () => {
106
- const { factory } = makeMockDoltClientFactory();
107
- const adapter = createDatabaseAdapter({ backend: 'memory' }, factory);
108
- expect(adapter).toBeInstanceOf(InMemoryDatabaseAdapter);
109
- expect(factory).not.toHaveBeenCalled();
110
- });
111
- });
112
- // -------------------------------------------------------------------------
113
- // backend = 'dolt'
114
- // -------------------------------------------------------------------------
115
- describe('backend = "dolt"', () => {
116
- it('returns a DoltDatabaseAdapter when factory is provided', () => {
117
- const { factory, mockClient } = makeMockDoltClientFactory();
118
- const adapter = createDatabaseAdapter({ backend: 'dolt', basePath: '/tmp/test-project' }, factory);
119
- expect(adapter).toBeInstanceOf(DoltDatabaseAdapter);
120
- expect(factory).toHaveBeenCalledWith('/tmp/test-project/.substrate/state');
121
- });
122
- it('falls back to InMemoryDatabaseAdapter when no factory is provided', () => {
123
- const warnSpy = vi.spyOn(console, 'debug').mockImplementation(() => { });
124
- const adapter = createDatabaseAdapter({ backend: 'dolt' });
125
- expect(adapter).toBeInstanceOf(InMemoryDatabaseAdapter);
126
- expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('no doltClientFactory provided'));
127
- });
128
- });
129
- // -------------------------------------------------------------------------
130
- // backend = 'auto'
131
- // -------------------------------------------------------------------------
132
- describe('backend = "auto"', () => {
133
- it('returns DoltDatabaseAdapter when Dolt is available and factory provided', () => {
134
- configureDoltAvailable();
135
- const { factory } = makeMockDoltClientFactory();
136
- const adapter = createDatabaseAdapter({ backend: 'auto', basePath: '/tmp/test-project' }, factory);
137
- expect(adapter).toBeInstanceOf(DoltDatabaseAdapter);
138
- expect(factory).toHaveBeenCalledWith('/tmp/test-project/.substrate/state');
139
- });
140
- it('returns InMemoryDatabaseAdapter when Dolt dir does not exist', () => {
141
- configureDoltUnavailable();
142
- const { factory } = makeMockDoltClientFactory();
143
- const adapter = createDatabaseAdapter({ backend: 'auto', basePath: '/tmp/test-project' }, factory);
144
- expect(adapter).toBeInstanceOf(InMemoryDatabaseAdapter);
145
- // Factory should NOT be called since Dolt is unavailable
146
- expect(factory).not.toHaveBeenCalled();
147
- });
148
- it('returns InMemoryDatabaseAdapter when no factory is provided even if Dolt is available', () => {
149
- configureDoltAvailable();
150
- const adapter = createDatabaseAdapter({
151
- backend: 'auto',
152
- basePath: '/tmp/test-project',
153
- });
154
- expect(adapter).toBeInstanceOf(InMemoryDatabaseAdapter);
155
- });
156
- it('defaults backend to "auto" when config is undefined', () => {
157
- configureDoltUnavailable();
158
- const adapter = createDatabaseAdapter();
159
- expect(adapter).toBeInstanceOf(InMemoryDatabaseAdapter);
160
- });
161
- it('defaults basePath to process.cwd() when not specified', () => {
162
- configureDoltAvailable();
163
- const { factory } = makeMockDoltClientFactory();
164
- const cwd = process.cwd();
165
- const adapter = createDatabaseAdapter({ backend: 'auto' }, factory);
166
- expect(adapter).toBeInstanceOf(DoltDatabaseAdapter);
167
- expect(factory).toHaveBeenCalledWith(`${cwd}/.substrate/state`);
168
- });
169
- });
170
- // -------------------------------------------------------------------------
171
- // isDoltAvailable — retry logic
172
- // -------------------------------------------------------------------------
173
- describe('isDoltAvailable retry logic (via auto backend)', () => {
174
- it('retries once when .dolt dir exists but binary fails, then succeeds', () => {
175
- const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
176
- // .dolt directory exists
177
- mockedExistsSync.mockReturnValue(true);
178
- // First call to `dolt version` fails, retry succeeds
179
- let callCount = 0;
180
- mockedSpawnSync.mockImplementation((cmd) => {
181
- if (cmd === 'dolt') {
182
- callCount++;
183
- if (callCount <= 1) {
184
- // First attempt: binary unavailable
185
- return {
186
- error: new Error('ENOENT'),
187
- status: null,
188
- pid: 0,
189
- output: [],
190
- stdout: Buffer.from(''),
191
- stderr: Buffer.from(''),
192
- signal: null,
193
- };
194
- }
195
- // Retry: binary available
196
- return {
197
- status: 0,
198
- pid: 1,
199
- output: [],
200
- stdout: Buffer.from(''),
201
- stderr: Buffer.from(''),
202
- signal: null,
203
- };
204
- }
205
- // sleep call
206
- return {
207
- status: 0,
208
- pid: 1,
209
- output: [],
210
- stdout: Buffer.from(''),
211
- stderr: Buffer.from(''),
212
- signal: null,
213
- };
214
- });
215
- const { factory } = makeMockDoltClientFactory();
216
- const adapter = createDatabaseAdapter({ backend: 'auto', basePath: '/tmp/test-project' }, factory);
217
- expect(adapter).toBeInstanceOf(DoltDatabaseAdapter);
218
- // Should have warned about the retry
219
- expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('retrying once'));
220
- });
221
- it('falls back to InMemory with warning when .dolt dir exists but binary fails on both attempts', () => {
222
- const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
223
- configureDoltDirExistsBinaryFails();
224
- const { factory } = makeMockDoltClientFactory();
225
- const adapter = createDatabaseAdapter({ backend: 'auto', basePath: '/tmp/test-project' }, factory);
226
- expect(adapter).toBeInstanceOf(InMemoryDatabaseAdapter);
227
- // Should warn about retry and about final fallback
228
- expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('retrying once'));
229
- expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('still unavailable after retry'));
230
- });
231
- });
232
- // -------------------------------------------------------------------------
233
- // backendType property
234
- // -------------------------------------------------------------------------
235
- describe('backendType property', () => {
236
- it('InMemoryDatabaseAdapter has backendType "memory"', () => {
237
- configureDoltUnavailable();
238
- const adapter = createDatabaseAdapter({ backend: 'memory' });
239
- expect(adapter.backendType).toBe('memory');
240
- });
241
- it('DoltDatabaseAdapter has backendType "dolt"', () => {
242
- configureDoltAvailable();
243
- const { factory } = makeMockDoltClientFactory();
244
- const adapter = createDatabaseAdapter({ backend: 'auto', basePath: '/tmp/test-project' }, factory);
245
- expect(adapter.backendType).toBe('dolt');
246
- });
247
- });
248
- // -------------------------------------------------------------------------
249
- // Edge cases
250
- // -------------------------------------------------------------------------
251
- describe('edge cases', () => {
252
- it('handles backend=undefined in config (defaults to auto)', () => {
253
- configureDoltUnavailable();
254
- const adapter = createDatabaseAdapter({ backend: 'auto' });
255
- expect(adapter).toBeInstanceOf(InMemoryDatabaseAdapter);
256
- });
257
- });
258
- });
259
- //# sourceMappingURL=adapter.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"adapter.test.js","sourceRoot":"","sources":["../../src/__tests__/adapter.test.ts"],"names":[],"mappings":"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"}
@@ -1,14 +0,0 @@
1
- /**
2
- * Unit tests for packages/core/src/events/event-bus.ts
3
- *
4
- * Tests the TypedEventBusImpl class and createEventBus factory:
5
- * - Basic emit/on/off lifecycle
6
- * - Typed event emission with correct payload delivery
7
- * - Multiple handlers for same event
8
- * - Handler removal (off)
9
- * - Synchronous dispatch guarantee
10
- * - Multiple event types coexisting
11
- * - createEventBus factory returns working instance
12
- */
13
- export {};
14
- //# sourceMappingURL=event-bus.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"event-bus.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/event-bus.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
@@ -1,199 +0,0 @@
1
- /**
2
- * Unit tests for packages/core/src/events/event-bus.ts
3
- *
4
- * Tests the TypedEventBusImpl class and createEventBus factory:
5
- * - Basic emit/on/off lifecycle
6
- * - Typed event emission with correct payload delivery
7
- * - Multiple handlers for same event
8
- * - Handler removal (off)
9
- * - Synchronous dispatch guarantee
10
- * - Multiple event types coexisting
11
- * - createEventBus factory returns working instance
12
- */
13
- import { describe, it, expect, vi } from 'vitest';
14
- import { TypedEventBusImpl, createEventBus } from '../events/event-bus.js';
15
- // ---------------------------------------------------------------------------
16
- // TypedEventBusImpl
17
- // ---------------------------------------------------------------------------
18
- describe('TypedEventBusImpl', () => {
19
- // -----------------------------------------------------------------------
20
- // emit / on basics
21
- // -----------------------------------------------------------------------
22
- describe('emit and on', () => {
23
- it('delivers a payload to a registered handler', () => {
24
- const bus = new TypedEventBusImpl();
25
- const handler = vi.fn();
26
- bus.on('test:simple', handler);
27
- bus.emit('test:simple', { message: 'hello' });
28
- expect(handler).toHaveBeenCalledOnce();
29
- expect(handler).toHaveBeenCalledWith({ message: 'hello' });
30
- });
31
- it('delivers correct payload for numeric events', () => {
32
- const bus = new TypedEventBusImpl();
33
- const handler = vi.fn();
34
- bus.on('test:numeric', handler);
35
- bus.emit('test:numeric', { value: 42 });
36
- expect(handler).toHaveBeenCalledWith({ value: 42 });
37
- });
38
- it('delivers complex nested payloads', () => {
39
- const bus = new TypedEventBusImpl();
40
- const handler = vi.fn();
41
- const payload = {
42
- items: ['a', 'b', 'c'],
43
- count: 3,
44
- nested: { ok: true },
45
- };
46
- bus.on('test:complex', handler);
47
- bus.emit('test:complex', payload);
48
- expect(handler).toHaveBeenCalledWith(payload);
49
- });
50
- it('does not deliver to handlers of different events', () => {
51
- const bus = new TypedEventBusImpl();
52
- const simpleHandler = vi.fn();
53
- const numericHandler = vi.fn();
54
- bus.on('test:simple', simpleHandler);
55
- bus.on('test:numeric', numericHandler);
56
- bus.emit('test:simple', { message: 'only simple' });
57
- expect(simpleHandler).toHaveBeenCalledOnce();
58
- expect(numericHandler).not.toHaveBeenCalled();
59
- });
60
- it('emitting with no registered handlers does not throw', () => {
61
- const bus = new TypedEventBusImpl();
62
- expect(() => {
63
- bus.emit('test:simple', { message: 'nobody listening' });
64
- }).not.toThrow();
65
- });
66
- });
67
- // -----------------------------------------------------------------------
68
- // Multiple handlers
69
- // -----------------------------------------------------------------------
70
- describe('multiple handlers', () => {
71
- it('delivers to all registered handlers for the same event', () => {
72
- const bus = new TypedEventBusImpl();
73
- const handler1 = vi.fn();
74
- const handler2 = vi.fn();
75
- const handler3 = vi.fn();
76
- bus.on('test:simple', handler1);
77
- bus.on('test:simple', handler2);
78
- bus.on('test:simple', handler3);
79
- bus.emit('test:simple', { message: 'broadcast' });
80
- expect(handler1).toHaveBeenCalledOnce();
81
- expect(handler2).toHaveBeenCalledOnce();
82
- expect(handler3).toHaveBeenCalledOnce();
83
- // All received the same payload
84
- for (const h of [handler1, handler2, handler3]) {
85
- expect(h).toHaveBeenCalledWith({ message: 'broadcast' });
86
- }
87
- });
88
- it('delivers multiple emissions to the same handler', () => {
89
- const bus = new TypedEventBusImpl();
90
- const handler = vi.fn();
91
- bus.on('test:numeric', handler);
92
- bus.emit('test:numeric', { value: 1 });
93
- bus.emit('test:numeric', { value: 2 });
94
- bus.emit('test:numeric', { value: 3 });
95
- expect(handler).toHaveBeenCalledTimes(3);
96
- expect(handler).toHaveBeenNthCalledWith(1, { value: 1 });
97
- expect(handler).toHaveBeenNthCalledWith(2, { value: 2 });
98
- expect(handler).toHaveBeenNthCalledWith(3, { value: 3 });
99
- });
100
- });
101
- // -----------------------------------------------------------------------
102
- // off (handler removal)
103
- // -----------------------------------------------------------------------
104
- describe('off', () => {
105
- it('stops delivering to a removed handler', () => {
106
- const bus = new TypedEventBusImpl();
107
- const handler = vi.fn();
108
- bus.on('test:simple', handler);
109
- bus.emit('test:simple', { message: 'before off' });
110
- expect(handler).toHaveBeenCalledOnce();
111
- bus.off('test:simple', handler);
112
- bus.emit('test:simple', { message: 'after off' });
113
- expect(handler).toHaveBeenCalledOnce(); // still 1, not 2
114
- });
115
- it('only removes the specific handler, not others', () => {
116
- const bus = new TypedEventBusImpl();
117
- const handlerA = vi.fn();
118
- const handlerB = vi.fn();
119
- bus.on('test:simple', handlerA);
120
- bus.on('test:simple', handlerB);
121
- bus.off('test:simple', handlerA);
122
- bus.emit('test:simple', { message: 'after removing A' });
123
- expect(handlerA).not.toHaveBeenCalled();
124
- expect(handlerB).toHaveBeenCalledOnce();
125
- });
126
- it('removing a handler that was never registered does not throw', () => {
127
- const bus = new TypedEventBusImpl();
128
- const handler = vi.fn();
129
- expect(() => {
130
- bus.off('test:simple', handler);
131
- }).not.toThrow();
132
- });
133
- });
134
- // -----------------------------------------------------------------------
135
- // Synchronous dispatch
136
- // -----------------------------------------------------------------------
137
- describe('synchronous dispatch', () => {
138
- it('all handlers complete before emit returns', () => {
139
- const bus = new TypedEventBusImpl();
140
- const order = [];
141
- bus.on('test:simple', () => order.push(1));
142
- bus.on('test:simple', () => order.push(2));
143
- bus.emit('test:simple', { message: 'sync test' });
144
- order.push(3); // This runs after emit returns
145
- // If dispatch were async, order might be [3, 1, 2]
146
- expect(order).toEqual([1, 2, 3]);
147
- });
148
- });
149
- // -----------------------------------------------------------------------
150
- // Multiple event types
151
- // -----------------------------------------------------------------------
152
- describe('event type isolation', () => {
153
- it('maintains separate handler lists per event type', () => {
154
- const bus = new TypedEventBusImpl();
155
- const simpleHandler = vi.fn();
156
- const numericHandler = vi.fn();
157
- bus.on('test:simple', simpleHandler);
158
- bus.on('test:numeric', numericHandler);
159
- bus.emit('test:simple', { message: 'hello' });
160
- bus.emit('test:numeric', { value: 99 });
161
- expect(simpleHandler).toHaveBeenCalledOnce();
162
- expect(simpleHandler).toHaveBeenCalledWith({ message: 'hello' });
163
- expect(numericHandler).toHaveBeenCalledOnce();
164
- expect(numericHandler).toHaveBeenCalledWith({ value: 99 });
165
- });
166
- it('removing handler for one event does not affect others', () => {
167
- const bus = new TypedEventBusImpl();
168
- const simpleHandler = vi.fn();
169
- const numericHandler = vi.fn();
170
- bus.on('test:simple', simpleHandler);
171
- bus.on('test:numeric', numericHandler);
172
- bus.off('test:simple', simpleHandler);
173
- bus.emit('test:simple', { message: 'removed' });
174
- bus.emit('test:numeric', { value: 1 });
175
- expect(simpleHandler).not.toHaveBeenCalled();
176
- expect(numericHandler).toHaveBeenCalledOnce();
177
- });
178
- });
179
- });
180
- // ---------------------------------------------------------------------------
181
- // createEventBus factory
182
- // ---------------------------------------------------------------------------
183
- describe('createEventBus', () => {
184
- it('returns a TypedEventBusImpl instance', () => {
185
- const bus = createEventBus();
186
- expect(bus).toBeInstanceOf(TypedEventBusImpl);
187
- });
188
- it('returned bus supports full emit/on/off lifecycle', () => {
189
- const bus = createEventBus();
190
- const handler = vi.fn();
191
- bus.on('test:simple', handler);
192
- bus.emit('test:simple', { message: 'factory test' });
193
- expect(handler).toHaveBeenCalledWith({ message: 'factory test' });
194
- bus.off('test:simple', handler);
195
- bus.emit('test:simple', { message: 'after off' });
196
- expect(handler).toHaveBeenCalledOnce();
197
- });
198
- });
199
- //# sourceMappingURL=event-bus.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"event-bus.test.js","sourceRoot":"","sources":["../../src/__tests__/event-bus.test.ts"],"names":[],"mappings":"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"}