import type { IEvent } from './IEvent.ts'; import { isObject } from './isObject.ts'; /** * Interface for tracking event processing state to prevent concurrent processing * by multiple processes. */ export interface IEventLocker { /** * Retrieves the last projected event, * allowing the projection state to be restored from subsequent events. */ getLastEvent(): Promise | IEvent | undefined; /** * Marks an event as projecting to prevent it from being processed * by another projection instance using the same storage. * * @returns `false` if the event is already being processed or has been processed. */ tryMarkAsProjecting(event: IEvent): Promise | boolean; /** * Marks an event as projected. */ markAsProjected(event: IEvent): Promise | void; /** * Records an event as the last projected event (restore checkpoint). */ markAsLastEvent(event: IEvent): Promise | void; } export const isEventLocker = (view: unknown): view is IEventLocker => ( isObject(view) && 'getLastEvent' in view && 'tryMarkAsProjecting' in view && 'markAsProjected' in view && 'markAsLastEvent' in view ) || ( typeof view === 'function' && typeof (view as any).getLastEvent === 'function' && typeof (view as any).tryMarkAsProjecting === 'function' && typeof (view as any).markAsProjected === 'function' && typeof (view as any).markAsLastEvent === 'function' );