moflo 4.8.19 → 4.8.20
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.
- package/.claude/guidance/shipped/moflo.md +45 -0
- package/.claude/helpers/statusline.cjs +1 -1
- package/.claude/workflow-state.json +9 -0
- package/package.json +2 -2
- package/src/@claude-flow/cli/dist/src/init/statusline-generator.js +1 -1
- package/src/@claude-flow/cli/dist/src/services/agentic-flow-bridge.js +5 -3
- package/src/@claude-flow/cli/package.json +1 -1
- package/src/@claude-flow/memory/dist/agent-memory-scope.d.ts +131 -0
- package/src/@claude-flow/memory/dist/agent-memory-scope.js +223 -0
- package/src/@claude-flow/memory/dist/agent-memory-scope.test.d.ts +8 -0
- package/src/@claude-flow/memory/dist/agent-memory-scope.test.js +466 -0
- package/src/@claude-flow/memory/dist/agentdb-adapter.d.ts +165 -0
- package/src/@claude-flow/memory/dist/agentdb-adapter.js +806 -0
- package/src/@claude-flow/memory/dist/agentdb-backend.d.ts +212 -0
- package/src/@claude-flow/memory/dist/agentdb-backend.js +842 -0
- package/src/@claude-flow/memory/dist/agentdb-backend.test.d.ts +7 -0
- package/src/@claude-flow/memory/dist/agentdb-backend.test.js +258 -0
- package/src/@claude-flow/memory/dist/application/commands/delete-memory.command.d.ts +65 -0
- package/src/@claude-flow/memory/dist/application/commands/delete-memory.command.js +129 -0
- package/src/@claude-flow/memory/dist/application/commands/store-memory.command.d.ts +48 -0
- package/src/@claude-flow/memory/dist/application/commands/store-memory.command.js +72 -0
- package/src/@claude-flow/memory/dist/application/index.d.ts +12 -0
- package/src/@claude-flow/memory/dist/application/index.js +15 -0
- package/src/@claude-flow/memory/dist/application/queries/search-memory.query.d.ts +72 -0
- package/src/@claude-flow/memory/dist/application/queries/search-memory.query.js +143 -0
- package/src/@claude-flow/memory/dist/application/services/memory-application-service.d.ts +121 -0
- package/src/@claude-flow/memory/dist/application/services/memory-application-service.js +190 -0
- package/src/@claude-flow/memory/dist/auto-memory-bridge.d.ts +226 -0
- package/src/@claude-flow/memory/dist/auto-memory-bridge.js +709 -0
- package/src/@claude-flow/memory/dist/auto-memory-bridge.test.d.ts +8 -0
- package/src/@claude-flow/memory/dist/auto-memory-bridge.test.js +757 -0
- package/src/@claude-flow/memory/dist/benchmark.test.d.ts +2 -0
- package/src/@claude-flow/memory/dist/benchmark.test.js +277 -0
- package/src/@claude-flow/memory/dist/cache-manager.d.ts +134 -0
- package/src/@claude-flow/memory/dist/cache-manager.js +407 -0
- package/src/@claude-flow/memory/dist/controller-registry.d.ts +216 -0
- package/src/@claude-flow/memory/dist/controller-registry.js +893 -0
- package/src/@claude-flow/memory/dist/controller-registry.test.d.ts +14 -0
- package/src/@claude-flow/memory/dist/controller-registry.test.js +593 -0
- package/src/@claude-flow/memory/dist/database-provider.d.ts +87 -0
- package/src/@claude-flow/memory/dist/database-provider.js +372 -0
- package/src/@claude-flow/memory/dist/database-provider.test.d.ts +7 -0
- package/src/@claude-flow/memory/dist/database-provider.test.js +287 -0
- package/src/@claude-flow/memory/dist/domain/entities/memory-entry.d.ts +143 -0
- package/src/@claude-flow/memory/dist/domain/entities/memory-entry.js +226 -0
- package/src/@claude-flow/memory/dist/domain/index.d.ts +11 -0
- package/src/@claude-flow/memory/dist/domain/index.js +12 -0
- package/src/@claude-flow/memory/dist/domain/repositories/memory-repository.interface.d.ts +102 -0
- package/src/@claude-flow/memory/dist/domain/repositories/memory-repository.interface.js +11 -0
- package/src/@claude-flow/memory/dist/domain/services/memory-domain-service.d.ts +105 -0
- package/src/@claude-flow/memory/dist/domain/services/memory-domain-service.js +297 -0
- package/src/@claude-flow/memory/dist/hnsw-index.d.ts +111 -0
- package/src/@claude-flow/memory/dist/hnsw-index.js +781 -0
- package/src/@claude-flow/memory/dist/hnsw-lite.d.ts +23 -0
- package/src/@claude-flow/memory/dist/hnsw-lite.js +168 -0
- package/src/@claude-flow/memory/dist/index.d.ts +204 -0
- package/src/@claude-flow/memory/dist/index.js +358 -0
- package/src/@claude-flow/memory/dist/infrastructure/index.d.ts +17 -0
- package/src/@claude-flow/memory/dist/infrastructure/index.js +16 -0
- package/src/@claude-flow/memory/dist/infrastructure/repositories/hybrid-memory-repository.d.ts +66 -0
- package/src/@claude-flow/memory/dist/infrastructure/repositories/hybrid-memory-repository.js +409 -0
- package/src/@claude-flow/memory/dist/learning-bridge.d.ts +137 -0
- package/src/@claude-flow/memory/dist/learning-bridge.js +335 -0
- package/src/@claude-flow/memory/dist/learning-bridge.test.d.ts +8 -0
- package/src/@claude-flow/memory/dist/learning-bridge.test.js +578 -0
- package/src/@claude-flow/memory/dist/memory-graph.d.ts +100 -0
- package/src/@claude-flow/memory/dist/memory-graph.js +333 -0
- package/src/@claude-flow/memory/dist/memory-graph.test.d.ts +8 -0
- package/src/@claude-flow/memory/dist/memory-graph.test.js +609 -0
- package/src/@claude-flow/memory/dist/migration.d.ts +68 -0
- package/src/@claude-flow/memory/dist/migration.js +513 -0
- package/src/@claude-flow/memory/dist/persistent-sona.d.ts +144 -0
- package/src/@claude-flow/memory/dist/persistent-sona.js +332 -0
- package/src/@claude-flow/memory/dist/query-builder.d.ts +211 -0
- package/src/@claude-flow/memory/dist/query-builder.js +438 -0
- package/src/@claude-flow/memory/dist/rvf-backend.d.ts +51 -0
- package/src/@claude-flow/memory/dist/rvf-backend.js +481 -0
- package/src/@claude-flow/memory/dist/rvf-learning-store.d.ts +139 -0
- package/src/@claude-flow/memory/dist/rvf-learning-store.js +295 -0
- package/src/@claude-flow/memory/dist/rvf-migration.d.ts +45 -0
- package/src/@claude-flow/memory/dist/rvf-migration.js +234 -0
- package/src/@claude-flow/memory/dist/sqljs-backend.d.ts +127 -0
- package/src/@claude-flow/memory/dist/sqljs-backend.js +600 -0
- package/src/@claude-flow/memory/dist/types.d.ts +484 -0
- package/src/@claude-flow/memory/dist/types.js +58 -0
- package/src/@claude-flow/shared/dist/core/config/defaults.d.ts +41 -0
- package/src/@claude-flow/shared/dist/core/config/defaults.js +186 -0
- package/src/@claude-flow/shared/dist/core/config/index.d.ts +8 -0
- package/src/@claude-flow/shared/dist/core/config/index.js +12 -0
- package/src/@claude-flow/shared/dist/core/config/loader.d.ts +45 -0
- package/src/@claude-flow/shared/dist/core/config/loader.js +222 -0
- package/src/@claude-flow/shared/dist/core/config/schema.d.ts +1134 -0
- package/src/@claude-flow/shared/dist/core/config/schema.js +158 -0
- package/src/@claude-flow/shared/dist/core/config/validator.d.ts +92 -0
- package/src/@claude-flow/shared/dist/core/config/validator.js +147 -0
- package/src/@claude-flow/shared/dist/core/event-bus.d.ts +31 -0
- package/src/@claude-flow/shared/dist/core/event-bus.js +197 -0
- package/src/@claude-flow/shared/dist/core/index.d.ts +15 -0
- package/src/@claude-flow/shared/dist/core/index.js +19 -0
- package/src/@claude-flow/shared/dist/core/interfaces/agent.interface.d.ts +200 -0
- package/src/@claude-flow/shared/dist/core/interfaces/agent.interface.js +6 -0
- package/src/@claude-flow/shared/dist/core/interfaces/coordinator.interface.d.ts +310 -0
- package/src/@claude-flow/shared/dist/core/interfaces/coordinator.interface.js +7 -0
- package/src/@claude-flow/shared/dist/core/interfaces/event.interface.d.ts +224 -0
- package/src/@claude-flow/shared/dist/core/interfaces/event.interface.js +46 -0
- package/src/@claude-flow/shared/dist/core/interfaces/index.d.ts +10 -0
- package/src/@claude-flow/shared/dist/core/interfaces/index.js +15 -0
- package/src/@claude-flow/shared/dist/core/interfaces/memory.interface.d.ts +298 -0
- package/src/@claude-flow/shared/dist/core/interfaces/memory.interface.js +7 -0
- package/src/@claude-flow/shared/dist/core/interfaces/task.interface.d.ts +185 -0
- package/src/@claude-flow/shared/dist/core/interfaces/task.interface.js +6 -0
- package/src/@claude-flow/shared/dist/core/orchestrator/event-coordinator.d.ts +35 -0
- package/src/@claude-flow/shared/dist/core/orchestrator/event-coordinator.js +101 -0
- package/src/@claude-flow/shared/dist/core/orchestrator/health-monitor.d.ts +60 -0
- package/src/@claude-flow/shared/dist/core/orchestrator/health-monitor.js +166 -0
- package/src/@claude-flow/shared/dist/core/orchestrator/index.d.ts +46 -0
- package/src/@claude-flow/shared/dist/core/orchestrator/index.js +64 -0
- package/src/@claude-flow/shared/dist/core/orchestrator/lifecycle-manager.d.ts +56 -0
- package/src/@claude-flow/shared/dist/core/orchestrator/lifecycle-manager.js +195 -0
- package/src/@claude-flow/shared/dist/core/orchestrator/session-manager.d.ts +83 -0
- package/src/@claude-flow/shared/dist/core/orchestrator/session-manager.js +193 -0
- package/src/@claude-flow/shared/dist/core/orchestrator/task-manager.d.ts +49 -0
- package/src/@claude-flow/shared/dist/core/orchestrator/task-manager.js +253 -0
- package/src/@claude-flow/shared/dist/events/domain-events.d.ts +282 -0
- package/src/@claude-flow/shared/dist/events/domain-events.js +165 -0
- package/src/@claude-flow/shared/dist/events/event-store.d.ts +126 -0
- package/src/@claude-flow/shared/dist/events/event-store.js +432 -0
- package/src/@claude-flow/shared/dist/events/event-store.test.d.ts +8 -0
- package/src/@claude-flow/shared/dist/events/event-store.test.js +297 -0
- package/src/@claude-flow/shared/dist/events/example-usage.d.ts +10 -0
- package/src/@claude-flow/shared/dist/events/example-usage.js +193 -0
- package/src/@claude-flow/shared/dist/events/index.d.ts +21 -0
- package/src/@claude-flow/shared/dist/events/index.js +22 -0
- package/src/@claude-flow/shared/dist/events/projections.d.ts +177 -0
- package/src/@claude-flow/shared/dist/events/projections.js +421 -0
- package/src/@claude-flow/shared/dist/events/rvf-event-log.d.ts +82 -0
- package/src/@claude-flow/shared/dist/events/rvf-event-log.js +340 -0
- package/src/@claude-flow/shared/dist/events/state-reconstructor.d.ts +101 -0
- package/src/@claude-flow/shared/dist/events/state-reconstructor.js +263 -0
- package/src/@claude-flow/shared/dist/events.d.ts +80 -0
- package/src/@claude-flow/shared/dist/events.js +249 -0
- package/src/@claude-flow/shared/dist/hooks/example-usage.d.ts +42 -0
- package/src/@claude-flow/shared/dist/hooks/example-usage.js +351 -0
- package/src/@claude-flow/shared/dist/hooks/executor.d.ts +100 -0
- package/src/@claude-flow/shared/dist/hooks/executor.js +267 -0
- package/src/@claude-flow/shared/dist/hooks/hooks.test.d.ts +9 -0
- package/src/@claude-flow/shared/dist/hooks/hooks.test.js +322 -0
- package/src/@claude-flow/shared/dist/hooks/index.d.ts +52 -0
- package/src/@claude-flow/shared/dist/hooks/index.js +51 -0
- package/src/@claude-flow/shared/dist/hooks/registry.d.ts +133 -0
- package/src/@claude-flow/shared/dist/hooks/registry.js +277 -0
- package/src/@claude-flow/shared/dist/hooks/safety/bash-safety.d.ts +105 -0
- package/src/@claude-flow/shared/dist/hooks/safety/bash-safety.js +481 -0
- package/src/@claude-flow/shared/dist/hooks/safety/file-organization.d.ts +144 -0
- package/src/@claude-flow/shared/dist/hooks/safety/file-organization.js +328 -0
- package/src/@claude-flow/shared/dist/hooks/safety/git-commit.d.ts +158 -0
- package/src/@claude-flow/shared/dist/hooks/safety/git-commit.js +450 -0
- package/src/@claude-flow/shared/dist/hooks/safety/index.d.ts +17 -0
- package/src/@claude-flow/shared/dist/hooks/safety/index.js +17 -0
- package/src/@claude-flow/shared/dist/hooks/session-hooks.d.ts +234 -0
- package/src/@claude-flow/shared/dist/hooks/session-hooks.js +334 -0
- package/src/@claude-flow/shared/dist/hooks/task-hooks.d.ts +163 -0
- package/src/@claude-flow/shared/dist/hooks/task-hooks.js +326 -0
- package/src/@claude-flow/shared/dist/hooks/types.d.ts +267 -0
- package/src/@claude-flow/shared/dist/hooks/types.js +62 -0
- package/src/@claude-flow/shared/dist/hooks/verify-exports.test.d.ts +9 -0
- package/src/@claude-flow/shared/dist/hooks/verify-exports.test.js +93 -0
- package/src/@claude-flow/shared/dist/index.d.ts +20 -0
- package/src/@claude-flow/shared/dist/index.js +50 -0
- package/src/@claude-flow/shared/dist/mcp/connection-pool.d.ts +98 -0
- package/src/@claude-flow/shared/dist/mcp/connection-pool.js +364 -0
- package/src/@claude-flow/shared/dist/mcp/index.d.ts +69 -0
- package/src/@claude-flow/shared/dist/mcp/index.js +84 -0
- package/src/@claude-flow/shared/dist/mcp/server.d.ts +166 -0
- package/src/@claude-flow/shared/dist/mcp/server.js +593 -0
- package/src/@claude-flow/shared/dist/mcp/session-manager.d.ts +136 -0
- package/src/@claude-flow/shared/dist/mcp/session-manager.js +335 -0
- package/src/@claude-flow/shared/dist/mcp/tool-registry.d.ts +178 -0
- package/src/@claude-flow/shared/dist/mcp/tool-registry.js +439 -0
- package/src/@claude-flow/shared/dist/mcp/transport/http.d.ts +104 -0
- package/src/@claude-flow/shared/dist/mcp/transport/http.js +476 -0
- package/src/@claude-flow/shared/dist/mcp/transport/index.d.ts +102 -0
- package/src/@claude-flow/shared/dist/mcp/transport/index.js +238 -0
- package/src/@claude-flow/shared/dist/mcp/transport/stdio.d.ts +104 -0
- package/src/@claude-flow/shared/dist/mcp/transport/stdio.js +263 -0
- package/src/@claude-flow/shared/dist/mcp/transport/websocket.d.ts +133 -0
- package/src/@claude-flow/shared/dist/mcp/transport/websocket.js +396 -0
- package/src/@claude-flow/shared/dist/mcp/types.d.ts +438 -0
- package/src/@claude-flow/shared/dist/mcp/types.js +54 -0
- package/src/@claude-flow/shared/dist/plugin-interface.d.ts +544 -0
- package/src/@claude-flow/shared/dist/plugin-interface.js +23 -0
- package/src/@claude-flow/shared/dist/plugin-loader.d.ts +139 -0
- package/src/@claude-flow/shared/dist/plugin-loader.js +434 -0
- package/src/@claude-flow/shared/dist/plugin-registry.d.ts +183 -0
- package/src/@claude-flow/shared/dist/plugin-registry.js +457 -0
- package/src/@claude-flow/shared/dist/plugins/index.d.ts +10 -0
- package/src/@claude-flow/shared/dist/plugins/index.js +10 -0
- package/src/@claude-flow/shared/dist/plugins/official/hive-mind-plugin.d.ts +106 -0
- package/src/@claude-flow/shared/dist/plugins/official/hive-mind-plugin.js +241 -0
- package/src/@claude-flow/shared/dist/plugins/official/index.d.ts +10 -0
- package/src/@claude-flow/shared/dist/plugins/official/index.js +10 -0
- package/src/@claude-flow/shared/dist/plugins/official/maestro-plugin.d.ts +121 -0
- package/src/@claude-flow/shared/dist/plugins/official/maestro-plugin.js +355 -0
- package/src/@claude-flow/shared/dist/plugins/types.d.ts +93 -0
- package/src/@claude-flow/shared/dist/plugins/types.js +9 -0
- package/src/@claude-flow/shared/dist/resilience/bulkhead.d.ts +105 -0
- package/src/@claude-flow/shared/dist/resilience/bulkhead.js +206 -0
- package/src/@claude-flow/shared/dist/resilience/circuit-breaker.d.ts +132 -0
- package/src/@claude-flow/shared/dist/resilience/circuit-breaker.js +233 -0
- package/src/@claude-flow/shared/dist/resilience/index.d.ts +19 -0
- package/src/@claude-flow/shared/dist/resilience/index.js +19 -0
- package/src/@claude-flow/shared/dist/resilience/rate-limiter.d.ts +168 -0
- package/src/@claude-flow/shared/dist/resilience/rate-limiter.js +314 -0
- package/src/@claude-flow/shared/dist/resilience/retry.d.ts +91 -0
- package/src/@claude-flow/shared/dist/resilience/retry.js +159 -0
- package/src/@claude-flow/shared/dist/security/index.d.ts +10 -0
- package/src/@claude-flow/shared/dist/security/index.js +12 -0
- package/src/@claude-flow/shared/dist/security/input-validation.d.ts +73 -0
- package/src/@claude-flow/shared/dist/security/input-validation.js +201 -0
- package/src/@claude-flow/shared/dist/security/secure-random.d.ts +92 -0
- package/src/@claude-flow/shared/dist/security/secure-random.js +142 -0
- package/src/@claude-flow/shared/dist/services/index.d.ts +7 -0
- package/src/@claude-flow/shared/dist/services/index.js +7 -0
- package/src/@claude-flow/shared/dist/services/v3-progress.service.d.ts +124 -0
- package/src/@claude-flow/shared/dist/services/v3-progress.service.js +402 -0
- package/src/@claude-flow/shared/dist/types/agent.types.d.ts +137 -0
- package/src/@claude-flow/shared/dist/types/agent.types.js +6 -0
- package/src/@claude-flow/shared/dist/types/index.d.ts +11 -0
- package/src/@claude-flow/shared/dist/types/index.js +17 -0
- package/src/@claude-flow/shared/dist/types/mcp.types.d.ts +266 -0
- package/src/@claude-flow/shared/dist/types/mcp.types.js +7 -0
- package/src/@claude-flow/shared/dist/types/memory.types.d.ts +236 -0
- package/src/@claude-flow/shared/dist/types/memory.types.js +7 -0
- package/src/@claude-flow/shared/dist/types/swarm.types.d.ts +186 -0
- package/src/@claude-flow/shared/dist/types/swarm.types.js +65 -0
- package/src/@claude-flow/shared/dist/types/task.types.d.ts +178 -0
- package/src/@claude-flow/shared/dist/types/task.types.js +32 -0
- package/src/@claude-flow/shared/dist/types.d.ts +197 -0
- package/src/@claude-flow/shared/dist/types.js +21 -0
- package/src/@claude-flow/shared/dist/utils/secure-logger.d.ts +69 -0
- package/src/@claude-flow/shared/dist/utils/secure-logger.js +208 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event Projections for Read Models (ADR-007)
|
|
3
|
+
*
|
|
4
|
+
* Build read models from domain events using projections.
|
|
5
|
+
* Projections listen to events and maintain queryable state.
|
|
6
|
+
*
|
|
7
|
+
* Implemented Projections:
|
|
8
|
+
* - AgentStateProjection - Current state of all agents
|
|
9
|
+
* - TaskHistoryProjection - Complete task execution history
|
|
10
|
+
* - MemoryIndexProjection - Memory access patterns and index
|
|
11
|
+
*
|
|
12
|
+
* @module v3/shared/events/projections
|
|
13
|
+
*/
|
|
14
|
+
import { EventEmitter } from 'node:events';
|
|
15
|
+
import { DomainEvent } from './domain-events.js';
|
|
16
|
+
import { EventStore } from './event-store.js';
|
|
17
|
+
import { AgentId, TaskId, AgentStatus, TaskStatus } from '../types.js';
|
|
18
|
+
export declare abstract class Projection extends EventEmitter {
|
|
19
|
+
protected eventStore: EventStore;
|
|
20
|
+
protected initialized: boolean;
|
|
21
|
+
constructor(eventStore: EventStore);
|
|
22
|
+
/**
|
|
23
|
+
* Initialize the projection by replaying events
|
|
24
|
+
*/
|
|
25
|
+
initialize(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Handle a domain event
|
|
28
|
+
*/
|
|
29
|
+
abstract handle(event: DomainEvent): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Reset the projection state
|
|
32
|
+
*/
|
|
33
|
+
abstract reset(): void;
|
|
34
|
+
}
|
|
35
|
+
export interface AgentProjectionState {
|
|
36
|
+
id: AgentId;
|
|
37
|
+
role: string;
|
|
38
|
+
domain: string;
|
|
39
|
+
status: AgentStatus;
|
|
40
|
+
currentTask: TaskId | null;
|
|
41
|
+
completedTasks: TaskId[];
|
|
42
|
+
failedTasks: TaskId[];
|
|
43
|
+
totalTaskDuration: number;
|
|
44
|
+
taskCount: number;
|
|
45
|
+
errorCount: number;
|
|
46
|
+
spawnedAt: number;
|
|
47
|
+
startedAt: number | null;
|
|
48
|
+
stoppedAt: number | null;
|
|
49
|
+
lastActivityAt: number;
|
|
50
|
+
}
|
|
51
|
+
export declare class AgentStateProjection extends Projection {
|
|
52
|
+
private agents;
|
|
53
|
+
/**
|
|
54
|
+
* Get state for a specific agent
|
|
55
|
+
*/
|
|
56
|
+
getAgent(agentId: AgentId): AgentProjectionState | null;
|
|
57
|
+
/**
|
|
58
|
+
* Get all agents
|
|
59
|
+
*/
|
|
60
|
+
getAllAgents(): AgentProjectionState[];
|
|
61
|
+
/**
|
|
62
|
+
* Get agents by status
|
|
63
|
+
*/
|
|
64
|
+
getAgentsByStatus(status: AgentStatus): AgentProjectionState[];
|
|
65
|
+
/**
|
|
66
|
+
* Get agents by domain
|
|
67
|
+
*/
|
|
68
|
+
getAgentsByDomain(domain: string): AgentProjectionState[];
|
|
69
|
+
/**
|
|
70
|
+
* Get active agent count
|
|
71
|
+
*/
|
|
72
|
+
getActiveAgentCount(): number;
|
|
73
|
+
handle(event: DomainEvent): Promise<void>;
|
|
74
|
+
reset(): void;
|
|
75
|
+
private handleAgentSpawned;
|
|
76
|
+
private handleAgentStarted;
|
|
77
|
+
private handleAgentStopped;
|
|
78
|
+
private handleAgentFailed;
|
|
79
|
+
private handleAgentStatusChanged;
|
|
80
|
+
private handleAgentTaskAssigned;
|
|
81
|
+
private handleAgentTaskCompleted;
|
|
82
|
+
}
|
|
83
|
+
export interface TaskProjectionState {
|
|
84
|
+
id: TaskId;
|
|
85
|
+
type: string;
|
|
86
|
+
title: string;
|
|
87
|
+
status: TaskStatus;
|
|
88
|
+
priority: string;
|
|
89
|
+
assignedAgent: AgentId | null;
|
|
90
|
+
dependencies: TaskId[];
|
|
91
|
+
blockedBy: TaskId[];
|
|
92
|
+
createdAt: number;
|
|
93
|
+
startedAt: number | null;
|
|
94
|
+
completedAt: number | null;
|
|
95
|
+
failedAt: number | null;
|
|
96
|
+
duration: number | null;
|
|
97
|
+
result: unknown;
|
|
98
|
+
error: string | null;
|
|
99
|
+
retryCount: number;
|
|
100
|
+
}
|
|
101
|
+
export declare class TaskHistoryProjection extends Projection {
|
|
102
|
+
private tasks;
|
|
103
|
+
/**
|
|
104
|
+
* Get task by ID
|
|
105
|
+
*/
|
|
106
|
+
getTask(taskId: TaskId): TaskProjectionState | null;
|
|
107
|
+
/**
|
|
108
|
+
* Get all tasks
|
|
109
|
+
*/
|
|
110
|
+
getAllTasks(): TaskProjectionState[];
|
|
111
|
+
/**
|
|
112
|
+
* Get tasks by status
|
|
113
|
+
*/
|
|
114
|
+
getTasksByStatus(status: TaskStatus): TaskProjectionState[];
|
|
115
|
+
/**
|
|
116
|
+
* Get tasks by agent
|
|
117
|
+
*/
|
|
118
|
+
getTasksByAgent(agentId: AgentId): TaskProjectionState[];
|
|
119
|
+
/**
|
|
120
|
+
* Get completed task count
|
|
121
|
+
*/
|
|
122
|
+
getCompletedTaskCount(): number;
|
|
123
|
+
/**
|
|
124
|
+
* Get average task duration
|
|
125
|
+
*/
|
|
126
|
+
getAverageTaskDuration(): number;
|
|
127
|
+
handle(event: DomainEvent): Promise<void>;
|
|
128
|
+
reset(): void;
|
|
129
|
+
private handleTaskCreated;
|
|
130
|
+
private handleTaskQueued;
|
|
131
|
+
private handleTaskStarted;
|
|
132
|
+
private handleTaskCompleted;
|
|
133
|
+
private handleTaskFailed;
|
|
134
|
+
private handleTaskBlocked;
|
|
135
|
+
}
|
|
136
|
+
export interface MemoryProjectionState {
|
|
137
|
+
id: string;
|
|
138
|
+
namespace: string;
|
|
139
|
+
key: string;
|
|
140
|
+
type: string;
|
|
141
|
+
size: number;
|
|
142
|
+
accessCount: number;
|
|
143
|
+
storedAt: number;
|
|
144
|
+
lastAccessedAt: number;
|
|
145
|
+
deletedAt: number | null;
|
|
146
|
+
isDeleted: boolean;
|
|
147
|
+
}
|
|
148
|
+
export declare class MemoryIndexProjection extends Projection {
|
|
149
|
+
private memories;
|
|
150
|
+
/**
|
|
151
|
+
* Get memory by ID
|
|
152
|
+
*/
|
|
153
|
+
getMemory(memoryId: string): MemoryProjectionState | null;
|
|
154
|
+
/**
|
|
155
|
+
* Get all active memories (not deleted)
|
|
156
|
+
*/
|
|
157
|
+
getActiveMemories(): MemoryProjectionState[];
|
|
158
|
+
/**
|
|
159
|
+
* Get memories by namespace
|
|
160
|
+
*/
|
|
161
|
+
getMemoriesByNamespace(namespace: string): MemoryProjectionState[];
|
|
162
|
+
/**
|
|
163
|
+
* Get most accessed memories
|
|
164
|
+
*/
|
|
165
|
+
getMostAccessedMemories(limit?: number): MemoryProjectionState[];
|
|
166
|
+
/**
|
|
167
|
+
* Get total memory size by namespace
|
|
168
|
+
*/
|
|
169
|
+
getTotalSizeByNamespace(namespace: string): number;
|
|
170
|
+
handle(event: DomainEvent): Promise<void>;
|
|
171
|
+
reset(): void;
|
|
172
|
+
private handleMemoryStored;
|
|
173
|
+
private handleMemoryRetrieved;
|
|
174
|
+
private handleMemoryDeleted;
|
|
175
|
+
private handleMemoryExpired;
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=projections.d.ts.map
|
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event Projections for Read Models (ADR-007)
|
|
3
|
+
*
|
|
4
|
+
* Build read models from domain events using projections.
|
|
5
|
+
* Projections listen to events and maintain queryable state.
|
|
6
|
+
*
|
|
7
|
+
* Implemented Projections:
|
|
8
|
+
* - AgentStateProjection - Current state of all agents
|
|
9
|
+
* - TaskHistoryProjection - Complete task execution history
|
|
10
|
+
* - MemoryIndexProjection - Memory access patterns and index
|
|
11
|
+
*
|
|
12
|
+
* @module v3/shared/events/projections
|
|
13
|
+
*/
|
|
14
|
+
import { EventEmitter } from 'node:events';
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// Projection Base Class
|
|
17
|
+
// =============================================================================
|
|
18
|
+
export class Projection extends EventEmitter {
|
|
19
|
+
eventStore;
|
|
20
|
+
initialized = false;
|
|
21
|
+
constructor(eventStore) {
|
|
22
|
+
super();
|
|
23
|
+
this.eventStore = eventStore;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Initialize the projection by replaying events
|
|
27
|
+
*/
|
|
28
|
+
async initialize() {
|
|
29
|
+
if (this.initialized)
|
|
30
|
+
return;
|
|
31
|
+
// Replay all events to build current state
|
|
32
|
+
for await (const event of this.eventStore.replay()) {
|
|
33
|
+
await this.handle(event);
|
|
34
|
+
}
|
|
35
|
+
this.initialized = true;
|
|
36
|
+
this.emit('initialized');
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export class AgentStateProjection extends Projection {
|
|
40
|
+
agents = new Map();
|
|
41
|
+
/**
|
|
42
|
+
* Get state for a specific agent
|
|
43
|
+
*/
|
|
44
|
+
getAgent(agentId) {
|
|
45
|
+
return this.agents.get(agentId) || null;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get all agents
|
|
49
|
+
*/
|
|
50
|
+
getAllAgents() {
|
|
51
|
+
return Array.from(this.agents.values());
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get agents by status
|
|
55
|
+
*/
|
|
56
|
+
getAgentsByStatus(status) {
|
|
57
|
+
return this.getAllAgents().filter((agent) => agent.status === status);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get agents by domain
|
|
61
|
+
*/
|
|
62
|
+
getAgentsByDomain(domain) {
|
|
63
|
+
return this.getAllAgents().filter((agent) => agent.domain === domain);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get active agent count
|
|
67
|
+
*/
|
|
68
|
+
getActiveAgentCount() {
|
|
69
|
+
return this.getAgentsByStatus('active').length;
|
|
70
|
+
}
|
|
71
|
+
async handle(event) {
|
|
72
|
+
switch (event.type) {
|
|
73
|
+
case 'agent:spawned':
|
|
74
|
+
this.handleAgentSpawned(event);
|
|
75
|
+
break;
|
|
76
|
+
case 'agent:started':
|
|
77
|
+
this.handleAgentStarted(event);
|
|
78
|
+
break;
|
|
79
|
+
case 'agent:stopped':
|
|
80
|
+
this.handleAgentStopped(event);
|
|
81
|
+
break;
|
|
82
|
+
case 'agent:failed':
|
|
83
|
+
this.handleAgentFailed(event);
|
|
84
|
+
break;
|
|
85
|
+
case 'agent:status-changed':
|
|
86
|
+
this.handleAgentStatusChanged(event);
|
|
87
|
+
break;
|
|
88
|
+
case 'agent:task-assigned':
|
|
89
|
+
this.handleAgentTaskAssigned(event);
|
|
90
|
+
break;
|
|
91
|
+
case 'agent:task-completed':
|
|
92
|
+
this.handleAgentTaskCompleted(event);
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
reset() {
|
|
97
|
+
this.agents.clear();
|
|
98
|
+
this.emit('reset');
|
|
99
|
+
}
|
|
100
|
+
handleAgentSpawned(event) {
|
|
101
|
+
const { agentId, role, domain } = event.payload;
|
|
102
|
+
this.agents.set(agentId, {
|
|
103
|
+
id: agentId,
|
|
104
|
+
role: role,
|
|
105
|
+
domain: domain,
|
|
106
|
+
status: 'idle',
|
|
107
|
+
currentTask: null,
|
|
108
|
+
completedTasks: [],
|
|
109
|
+
failedTasks: [],
|
|
110
|
+
totalTaskDuration: 0,
|
|
111
|
+
taskCount: 0,
|
|
112
|
+
errorCount: 0,
|
|
113
|
+
spawnedAt: event.timestamp,
|
|
114
|
+
startedAt: null,
|
|
115
|
+
stoppedAt: null,
|
|
116
|
+
lastActivityAt: event.timestamp,
|
|
117
|
+
});
|
|
118
|
+
this.emit('agent:spawned', { agentId });
|
|
119
|
+
}
|
|
120
|
+
handleAgentStarted(event) {
|
|
121
|
+
const { agentId } = event.payload;
|
|
122
|
+
const agent = this.agents.get(agentId);
|
|
123
|
+
if (agent) {
|
|
124
|
+
agent.status = 'active';
|
|
125
|
+
agent.startedAt = event.timestamp;
|
|
126
|
+
agent.lastActivityAt = event.timestamp;
|
|
127
|
+
this.emit('agent:started', { agentId });
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
handleAgentStopped(event) {
|
|
131
|
+
const { agentId } = event.payload;
|
|
132
|
+
const agent = this.agents.get(agentId);
|
|
133
|
+
if (agent) {
|
|
134
|
+
agent.status = 'completed';
|
|
135
|
+
agent.stoppedAt = event.timestamp;
|
|
136
|
+
agent.lastActivityAt = event.timestamp;
|
|
137
|
+
this.emit('agent:stopped', { agentId });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
handleAgentFailed(event) {
|
|
141
|
+
const { agentId } = event.payload;
|
|
142
|
+
const agent = this.agents.get(agentId);
|
|
143
|
+
if (agent) {
|
|
144
|
+
agent.status = 'error';
|
|
145
|
+
agent.errorCount++;
|
|
146
|
+
agent.lastActivityAt = event.timestamp;
|
|
147
|
+
this.emit('agent:failed', { agentId });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
handleAgentStatusChanged(event) {
|
|
151
|
+
const { agentId, newStatus } = event.payload;
|
|
152
|
+
const agent = this.agents.get(agentId);
|
|
153
|
+
if (agent) {
|
|
154
|
+
agent.status = newStatus;
|
|
155
|
+
agent.lastActivityAt = event.timestamp;
|
|
156
|
+
this.emit('agent:status-changed', { agentId, status: newStatus });
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
handleAgentTaskAssigned(event) {
|
|
160
|
+
const { agentId, taskId } = event.payload;
|
|
161
|
+
const agent = this.agents.get(agentId);
|
|
162
|
+
if (agent) {
|
|
163
|
+
agent.currentTask = taskId;
|
|
164
|
+
agent.status = 'active';
|
|
165
|
+
agent.lastActivityAt = event.timestamp;
|
|
166
|
+
this.emit('agent:task-assigned', { agentId, taskId });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
handleAgentTaskCompleted(event) {
|
|
170
|
+
const { agentId, taskId, duration } = event.payload;
|
|
171
|
+
const agent = this.agents.get(agentId);
|
|
172
|
+
if (agent) {
|
|
173
|
+
agent.completedTasks.push(taskId);
|
|
174
|
+
agent.currentTask = null;
|
|
175
|
+
agent.taskCount++;
|
|
176
|
+
agent.totalTaskDuration += duration || 0;
|
|
177
|
+
agent.status = 'idle';
|
|
178
|
+
agent.lastActivityAt = event.timestamp;
|
|
179
|
+
this.emit('agent:task-completed', { agentId, taskId });
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
export class TaskHistoryProjection extends Projection {
|
|
184
|
+
tasks = new Map();
|
|
185
|
+
/**
|
|
186
|
+
* Get task by ID
|
|
187
|
+
*/
|
|
188
|
+
getTask(taskId) {
|
|
189
|
+
return this.tasks.get(taskId) || null;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Get all tasks
|
|
193
|
+
*/
|
|
194
|
+
getAllTasks() {
|
|
195
|
+
return Array.from(this.tasks.values());
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Get tasks by status
|
|
199
|
+
*/
|
|
200
|
+
getTasksByStatus(status) {
|
|
201
|
+
return this.getAllTasks().filter((task) => task.status === status);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Get tasks by agent
|
|
205
|
+
*/
|
|
206
|
+
getTasksByAgent(agentId) {
|
|
207
|
+
return this.getAllTasks().filter((task) => task.assignedAgent === agentId);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Get completed task count
|
|
211
|
+
*/
|
|
212
|
+
getCompletedTaskCount() {
|
|
213
|
+
return this.getTasksByStatus('completed').length;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Get average task duration
|
|
217
|
+
*/
|
|
218
|
+
getAverageTaskDuration() {
|
|
219
|
+
const completed = this.getTasksByStatus('completed').filter((t) => t.duration !== null);
|
|
220
|
+
if (completed.length === 0)
|
|
221
|
+
return 0;
|
|
222
|
+
const total = completed.reduce((sum, task) => sum + (task.duration || 0), 0);
|
|
223
|
+
return total / completed.length;
|
|
224
|
+
}
|
|
225
|
+
async handle(event) {
|
|
226
|
+
switch (event.type) {
|
|
227
|
+
case 'task:created':
|
|
228
|
+
this.handleTaskCreated(event);
|
|
229
|
+
break;
|
|
230
|
+
case 'task:queued':
|
|
231
|
+
this.handleTaskQueued(event);
|
|
232
|
+
break;
|
|
233
|
+
case 'task:started':
|
|
234
|
+
this.handleTaskStarted(event);
|
|
235
|
+
break;
|
|
236
|
+
case 'task:completed':
|
|
237
|
+
this.handleTaskCompleted(event);
|
|
238
|
+
break;
|
|
239
|
+
case 'task:failed':
|
|
240
|
+
this.handleTaskFailed(event);
|
|
241
|
+
break;
|
|
242
|
+
case 'task:blocked':
|
|
243
|
+
this.handleTaskBlocked(event);
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
reset() {
|
|
248
|
+
this.tasks.clear();
|
|
249
|
+
this.emit('reset');
|
|
250
|
+
}
|
|
251
|
+
handleTaskCreated(event) {
|
|
252
|
+
const { taskId, taskType, title, priority, dependencies } = event.payload;
|
|
253
|
+
this.tasks.set(taskId, {
|
|
254
|
+
id: taskId,
|
|
255
|
+
type: taskType,
|
|
256
|
+
title: title,
|
|
257
|
+
status: 'pending',
|
|
258
|
+
priority: priority,
|
|
259
|
+
assignedAgent: null,
|
|
260
|
+
dependencies: dependencies || [],
|
|
261
|
+
blockedBy: [],
|
|
262
|
+
createdAt: event.timestamp,
|
|
263
|
+
startedAt: null,
|
|
264
|
+
completedAt: null,
|
|
265
|
+
failedAt: null,
|
|
266
|
+
duration: null,
|
|
267
|
+
result: null,
|
|
268
|
+
error: null,
|
|
269
|
+
retryCount: 0,
|
|
270
|
+
});
|
|
271
|
+
this.emit('task:created', { taskId });
|
|
272
|
+
}
|
|
273
|
+
handleTaskQueued(event) {
|
|
274
|
+
const { taskId } = event.payload;
|
|
275
|
+
const task = this.tasks.get(taskId);
|
|
276
|
+
if (task) {
|
|
277
|
+
task.status = 'queued';
|
|
278
|
+
this.emit('task:queued', { taskId });
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
handleTaskStarted(event) {
|
|
282
|
+
const { taskId, agentId } = event.payload;
|
|
283
|
+
const task = this.tasks.get(taskId);
|
|
284
|
+
if (task) {
|
|
285
|
+
task.status = 'in-progress';
|
|
286
|
+
task.assignedAgent = agentId;
|
|
287
|
+
task.startedAt = event.timestamp;
|
|
288
|
+
this.emit('task:started', { taskId, agentId });
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
handleTaskCompleted(event) {
|
|
292
|
+
const { taskId, result, duration } = event.payload;
|
|
293
|
+
const task = this.tasks.get(taskId);
|
|
294
|
+
if (task) {
|
|
295
|
+
task.status = 'completed';
|
|
296
|
+
task.completedAt = event.timestamp;
|
|
297
|
+
task.duration = duration || (task.startedAt ? event.timestamp - task.startedAt : null);
|
|
298
|
+
task.result = result;
|
|
299
|
+
this.emit('task:completed', { taskId });
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
handleTaskFailed(event) {
|
|
303
|
+
const { taskId, error, retryCount } = event.payload;
|
|
304
|
+
const task = this.tasks.get(taskId);
|
|
305
|
+
if (task) {
|
|
306
|
+
task.status = 'failed';
|
|
307
|
+
task.failedAt = event.timestamp;
|
|
308
|
+
task.error = error;
|
|
309
|
+
task.retryCount = retryCount;
|
|
310
|
+
this.emit('task:failed', { taskId });
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
handleTaskBlocked(event) {
|
|
314
|
+
const { taskId, blockedBy } = event.payload;
|
|
315
|
+
const task = this.tasks.get(taskId);
|
|
316
|
+
if (task) {
|
|
317
|
+
task.status = 'blocked';
|
|
318
|
+
task.blockedBy = blockedBy;
|
|
319
|
+
this.emit('task:blocked', { taskId, blockedBy });
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
export class MemoryIndexProjection extends Projection {
|
|
324
|
+
memories = new Map();
|
|
325
|
+
/**
|
|
326
|
+
* Get memory by ID
|
|
327
|
+
*/
|
|
328
|
+
getMemory(memoryId) {
|
|
329
|
+
return this.memories.get(memoryId) || null;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Get all active memories (not deleted)
|
|
333
|
+
*/
|
|
334
|
+
getActiveMemories() {
|
|
335
|
+
return Array.from(this.memories.values()).filter((m) => !m.isDeleted);
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Get memories by namespace
|
|
339
|
+
*/
|
|
340
|
+
getMemoriesByNamespace(namespace) {
|
|
341
|
+
return this.getActiveMemories().filter((m) => m.namespace === namespace);
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Get most accessed memories
|
|
345
|
+
*/
|
|
346
|
+
getMostAccessedMemories(limit = 10) {
|
|
347
|
+
return this.getActiveMemories()
|
|
348
|
+
.sort((a, b) => b.accessCount - a.accessCount)
|
|
349
|
+
.slice(0, limit);
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Get total memory size by namespace
|
|
353
|
+
*/
|
|
354
|
+
getTotalSizeByNamespace(namespace) {
|
|
355
|
+
return this.getMemoriesByNamespace(namespace).reduce((sum, m) => sum + m.size, 0);
|
|
356
|
+
}
|
|
357
|
+
async handle(event) {
|
|
358
|
+
switch (event.type) {
|
|
359
|
+
case 'memory:stored':
|
|
360
|
+
this.handleMemoryStored(event);
|
|
361
|
+
break;
|
|
362
|
+
case 'memory:retrieved':
|
|
363
|
+
this.handleMemoryRetrieved(event);
|
|
364
|
+
break;
|
|
365
|
+
case 'memory:deleted':
|
|
366
|
+
this.handleMemoryDeleted(event);
|
|
367
|
+
break;
|
|
368
|
+
case 'memory:expired':
|
|
369
|
+
this.handleMemoryExpired(event);
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
reset() {
|
|
374
|
+
this.memories.clear();
|
|
375
|
+
this.emit('reset');
|
|
376
|
+
}
|
|
377
|
+
handleMemoryStored(event) {
|
|
378
|
+
const { memoryId, namespace, key, memoryType, size } = event.payload;
|
|
379
|
+
this.memories.set(memoryId, {
|
|
380
|
+
id: memoryId,
|
|
381
|
+
namespace: namespace,
|
|
382
|
+
key: key,
|
|
383
|
+
type: memoryType,
|
|
384
|
+
size: size || 0,
|
|
385
|
+
accessCount: 0,
|
|
386
|
+
storedAt: event.timestamp,
|
|
387
|
+
lastAccessedAt: event.timestamp,
|
|
388
|
+
deletedAt: null,
|
|
389
|
+
isDeleted: false,
|
|
390
|
+
});
|
|
391
|
+
this.emit('memory:stored', { memoryId });
|
|
392
|
+
}
|
|
393
|
+
handleMemoryRetrieved(event) {
|
|
394
|
+
const { memoryId, accessCount } = event.payload;
|
|
395
|
+
const memory = this.memories.get(memoryId);
|
|
396
|
+
if (memory && !memory.isDeleted) {
|
|
397
|
+
memory.accessCount = accessCount;
|
|
398
|
+
memory.lastAccessedAt = event.timestamp;
|
|
399
|
+
this.emit('memory:retrieved', { memoryId });
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
handleMemoryDeleted(event) {
|
|
403
|
+
const { memoryId } = event.payload;
|
|
404
|
+
const memory = this.memories.get(memoryId);
|
|
405
|
+
if (memory) {
|
|
406
|
+
memory.isDeleted = true;
|
|
407
|
+
memory.deletedAt = event.timestamp;
|
|
408
|
+
this.emit('memory:deleted', { memoryId });
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
handleMemoryExpired(event) {
|
|
412
|
+
const { memoryId } = event.payload;
|
|
413
|
+
const memory = this.memories.get(memoryId);
|
|
414
|
+
if (memory) {
|
|
415
|
+
memory.isDeleted = true;
|
|
416
|
+
memory.deletedAt = event.timestamp;
|
|
417
|
+
this.emit('memory:expired', { memoryId });
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
//# sourceMappingURL=projections.js.map
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RVF Event Log (ADR-057 Phase 2)
|
|
3
|
+
*
|
|
4
|
+
* Pure-TypeScript append-only event log that stores events in a binary
|
|
5
|
+
* file format. Replaces the sql.js-dependent EventStore with a zero-
|
|
6
|
+
* dependency alternative.
|
|
7
|
+
*
|
|
8
|
+
* Binary format:
|
|
9
|
+
* File header: 4 bytes — magic "RVFL"
|
|
10
|
+
* Record: 4 bytes (uint32 BE payload length) + N bytes (JSON payload)
|
|
11
|
+
*
|
|
12
|
+
* In-memory indexes are rebuilt on initialize() by replaying the file.
|
|
13
|
+
* Snapshots are stored in a separate `.snap.rvf` file using the same format.
|
|
14
|
+
*
|
|
15
|
+
* @module v3/shared/events/rvf-event-log
|
|
16
|
+
*/
|
|
17
|
+
import { EventEmitter } from 'node:events';
|
|
18
|
+
import type { DomainEvent } from './domain-events.js';
|
|
19
|
+
import type { EventFilter, EventSnapshot, EventStoreStats } from './event-store.js';
|
|
20
|
+
export interface RvfEventLogConfig {
|
|
21
|
+
/** Path to event log file */
|
|
22
|
+
logPath: string;
|
|
23
|
+
/** Enable verbose logging */
|
|
24
|
+
verbose?: boolean;
|
|
25
|
+
/** Maximum events before snapshot recommendation */
|
|
26
|
+
snapshotThreshold?: number;
|
|
27
|
+
}
|
|
28
|
+
export declare class RvfEventLog extends EventEmitter {
|
|
29
|
+
private config;
|
|
30
|
+
private initialized;
|
|
31
|
+
/**
|
|
32
|
+
* All events kept in insertion order.
|
|
33
|
+
* Rebuilt from the file on initialize().
|
|
34
|
+
*/
|
|
35
|
+
private events;
|
|
36
|
+
/** Fast lookup: aggregateId -> indices into this.events */
|
|
37
|
+
private aggregateIndex;
|
|
38
|
+
/** Version tracking per aggregate */
|
|
39
|
+
private aggregateVersions;
|
|
40
|
+
/** Snapshots keyed by aggregateId (latest wins) */
|
|
41
|
+
private snapshots;
|
|
42
|
+
/** Path to the companion snapshot file */
|
|
43
|
+
private snapshotPath;
|
|
44
|
+
constructor(config?: Partial<RvfEventLogConfig>);
|
|
45
|
+
/** Create / open the log file and rebuild in-memory indexes. */
|
|
46
|
+
initialize(): Promise<void>;
|
|
47
|
+
/** Flush to disk and release resources. */
|
|
48
|
+
close(): Promise<void>;
|
|
49
|
+
/** Append a domain event to the log. */
|
|
50
|
+
append(event: DomainEvent): Promise<void>;
|
|
51
|
+
/** Save a snapshot for an aggregate. */
|
|
52
|
+
saveSnapshot(snapshot: EventSnapshot): Promise<void>;
|
|
53
|
+
/** Get events for a specific aggregate, optionally from a version. */
|
|
54
|
+
getEvents(aggregateId: string, fromVersion?: number): Promise<DomainEvent[]>;
|
|
55
|
+
/** Query events with an optional filter (matches EventStore.query API). */
|
|
56
|
+
getAllEvents(filter?: EventFilter): Promise<DomainEvent[]>;
|
|
57
|
+
/** Get latest snapshot for an aggregate. */
|
|
58
|
+
getSnapshot(aggregateId: string): Promise<EventSnapshot | null>;
|
|
59
|
+
/** Return event store statistics. */
|
|
60
|
+
getStats(): Promise<EventStoreStats>;
|
|
61
|
+
/**
|
|
62
|
+
* Flush to disk.
|
|
63
|
+
* For the append-only log this is a no-op because every append() call
|
|
64
|
+
* writes to disk synchronously. Provided for API compatibility with
|
|
65
|
+
* EventStore.
|
|
66
|
+
*/
|
|
67
|
+
persist(): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Replay an RVF file and invoke `handler` for every decoded record.
|
|
70
|
+
* Used both for events and snapshots.
|
|
71
|
+
*/
|
|
72
|
+
private replayFile;
|
|
73
|
+
/** Append a single record to an RVF file. */
|
|
74
|
+
private appendRecord;
|
|
75
|
+
/** Add an event to the in-memory indexes. */
|
|
76
|
+
private indexEvent;
|
|
77
|
+
/** Ensure parent directory exists for a file path. */
|
|
78
|
+
private ensureDirectory;
|
|
79
|
+
/** Guard that throws if initialize() has not been called. */
|
|
80
|
+
private ensureInitialized;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=rvf-event-log.d.ts.map
|