82 lines
3.1 KiB
TypeScript
82 lines
3.1 KiB
TypeScript
/**
|
|
* RVF Event Log (ADR-057 Phase 2)
|
|
*
|
|
* Pure-TypeScript append-only event log that stores events in a binary
|
|
* file format. Replaces the sql.js-dependent EventStore with a zero-
|
|
* dependency alternative.
|
|
*
|
|
* Binary format:
|
|
* File header: 4 bytes — magic "RVFL"
|
|
* Record: 4 bytes (uint32 BE payload length) + N bytes (JSON payload)
|
|
*
|
|
* In-memory indexes are rebuilt on initialize() by replaying the file.
|
|
* Snapshots are stored in a separate `.snap.rvf` file using the same format.
|
|
*
|
|
* @module v3/shared/events/rvf-event-log
|
|
*/
|
|
import { EventEmitter } from 'node:events';
|
|
import type { DomainEvent } from './domain-events.js';
|
|
import type { EventFilter, EventSnapshot, EventStoreStats } from './event-store.js';
|
|
export interface RvfEventLogConfig {
|
|
/** Path to event log file */
|
|
logPath: string;
|
|
/** Enable verbose logging */
|
|
verbose?: boolean;
|
|
/** Maximum events before snapshot recommendation */
|
|
snapshotThreshold?: number;
|
|
}
|
|
export declare class RvfEventLog extends EventEmitter {
|
|
private config;
|
|
private initialized;
|
|
/**
|
|
* All events kept in insertion order.
|
|
* Rebuilt from the file on initialize().
|
|
*/
|
|
private events;
|
|
/** Fast lookup: aggregateId -> indices into this.events */
|
|
private aggregateIndex;
|
|
/** Version tracking per aggregate */
|
|
private aggregateVersions;
|
|
/** Snapshots keyed by aggregateId (latest wins) */
|
|
private snapshots;
|
|
/** Path to the companion snapshot file */
|
|
private snapshotPath;
|
|
constructor(config?: Partial<RvfEventLogConfig>);
|
|
/** Create / open the log file and rebuild in-memory indexes. */
|
|
initialize(): Promise<void>;
|
|
/** Flush to disk and release resources. */
|
|
close(): Promise<void>;
|
|
/** Append a domain event to the log. */
|
|
append(event: DomainEvent): Promise<void>;
|
|
/** Save a snapshot for an aggregate. */
|
|
saveSnapshot(snapshot: EventSnapshot): Promise<void>;
|
|
/** Get events for a specific aggregate, optionally from a version. */
|
|
getEvents(aggregateId: string, fromVersion?: number): Promise<DomainEvent[]>;
|
|
/** Query events with an optional filter (matches EventStore.query API). */
|
|
getAllEvents(filter?: EventFilter): Promise<DomainEvent[]>;
|
|
/** Get latest snapshot for an aggregate. */
|
|
getSnapshot(aggregateId: string): Promise<EventSnapshot | null>;
|
|
/** Return event store statistics. */
|
|
getStats(): Promise<EventStoreStats>;
|
|
/**
|
|
* Flush to disk.
|
|
* For the append-only log this is a no-op because every append() call
|
|
* writes to disk synchronously. Provided for API compatibility with
|
|
* EventStore.
|
|
*/
|
|
persist(): Promise<void>;
|
|
/**
|
|
* Replay an RVF file and invoke `handler` for every decoded record.
|
|
* Used both for events and snapshots.
|
|
*/
|
|
private replayFile;
|
|
/** Append a single record to an RVF file. */
|
|
private appendRecord;
|
|
/** Add an event to the in-memory indexes. */
|
|
private indexEvent;
|
|
/** Ensure parent directory exists for a file path. */
|
|
private ensureDirectory;
|
|
/** Guard that throws if initialize() has not been called. */
|
|
private ensureInitialized;
|
|
}
|
|
//# sourceMappingURL=rvf-event-log.d.ts.map
|