@event-driven-io/emmett-esdb 0.43.0-beta.23 → 0.43.0-beta.26

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/dist/index.cjs CHANGED
@@ -281,11 +281,6 @@ const eventStoreDBSubscription = ({ client, from, batchSize, eachBatch, resilien
281
281
  }
282
282
  };
283
283
  };
284
- const zipEventStoreDBEventStoreMessageBatchPullerStartFrom = (options) => {
285
- if (options.length === 0 || options.some((o) => o === void 0 || o === "BEGINNING")) return "BEGINNING";
286
- if (options.every((o) => o === "END")) return "END";
287
- return options.filter((o) => o !== void 0 && o !== "BEGINNING" && o !== "END").sort((a, b) => a > b ? 1 : -1)[0];
288
- };
289
284
 
290
285
  //#endregion
291
286
  //#region src/eventStore/consumers/eventStoreDBEventStoreConsumer.ts
@@ -347,13 +342,13 @@ const eventStoreDBEventStoreConsumer = (options) => {
347
342
  },
348
343
  whenStarted: () => startedAwaiter.wait,
349
344
  processors,
350
- reactor: (options) => {
351
- const processor = (0, _event_driven_io_emmett.inMemoryReactor)(options);
345
+ reactor: (processorOptions) => {
346
+ const processor = (0, _event_driven_io_emmett.inMemoryReactor)((0, _event_driven_io_emmett.mergeObservabilityOptions)(processorOptions, options.observability));
352
347
  processors.push(processor);
353
348
  return processor;
354
349
  },
355
- projector: (options) => {
356
- const processor = (0, _event_driven_io_emmett.inMemoryProjector)(options);
350
+ projector: (processorOptions) => {
351
+ const processor = (0, _event_driven_io_emmett.inMemoryProjector)((0, _event_driven_io_emmett.mergeObservabilityOptions)(processorOptions, options.observability));
357
352
  processors.push(processor);
358
353
  return processor;
359
354
  },
@@ -371,7 +366,7 @@ const eventStoreDBEventStoreConsumer = (options) => {
371
366
  if (!isRunning) return;
372
367
  try {
373
368
  if (!isInitialized) await init();
374
- const startFrom = zipEventStoreDBEventStoreMessageBatchPullerStartFrom(await Promise.all(processors.map((o) => o.start(client))));
369
+ const startFrom = _event_driven_io_emmett.CurrentMessageProcessorPosition.zip(await Promise.all(processors.map((o) => o.start(client))));
375
370
  await subscription.start({
376
371
  startFrom,
377
372
  started: startedAwaiter
@@ -402,5 +397,4 @@ exports.eventStoreDBSubscription = eventStoreDBSubscription;
402
397
  exports.getEventStoreDBEventStore = getEventStoreDBEventStore;
403
398
  exports.isDatabaseUnavailableError = isDatabaseUnavailableError;
404
399
  exports.mapFromESDBEvent = mapFromESDBEvent;
405
- exports.zipEventStoreDBEventStoreMessageBatchPullerStartFrom = zipEventStoreDBEventStoreMessageBatchPullerStartFrom;
406
400
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["StreamNotFoundError","jsonEvent","WrongExpectedVersionError","ExpectedVersionConflictError","ANY","NO_CONCURRENCY_CHECK","STREAM_DOES_NOT_EXIST","NO_STREAM","STREAM_EXISTS","ESDB_STREAM_EXISTS","START","END","Transform","JSONSerializer","Writable","EventStoreDBClient","EmmettError"],"sources":["../src/eventStore/eventstoreDBEventStore.ts","../src/eventStore/consumers/subscriptions/index.ts","../src/eventStore/consumers/eventStoreDBEventStoreConsumer.ts"],"sourcesContent":["import {\n ExpectedVersionConflictError,\n NO_CONCURRENCY_CHECK,\n STREAM_DOES_NOT_EXIST,\n STREAM_EXISTS,\n assertExpectedVersionMatchesCurrent,\n bigIntProcessorCheckpoint,\n downcastRecordedMessages,\n upcastRecordedMessage,\n type AggregateStreamOptions,\n type AggregateStreamResultWithGlobalPosition,\n type AnyMessage,\n type AppendToStreamOptions,\n type AppendToStreamResultWithGlobalPosition,\n type Event,\n type EventStore,\n type ExpectedStreamVersion,\n type ReadEvent,\n type ReadEventMetadataWithGlobalPosition,\n type ReadStreamOptions,\n type ReadStreamResult,\n type RecordedMessage,\n type StreamExistsResult,\n} from '@event-driven-io/emmett';\nimport type { EventStoreDBClient } from '@eventstore/db-client';\nimport {\n ANY,\n STREAM_EXISTS as ESDB_STREAM_EXISTS,\n NO_STREAM,\n StreamNotFoundError,\n WrongExpectedVersionError,\n jsonEvent,\n type AppendExpectedRevision,\n type ReadStreamOptions as ESDBReadStreamOptions,\n type ResolvedEvent,\n} from '@eventstore/db-client';\nimport {\n $all,\n eventStoreDBEventStoreConsumer,\n type EventStoreDBEventStoreConsumer,\n type EventStoreDBEventStoreConsumerConfig,\n type EventStoreDBEventStoreConsumerType,\n} from './consumers';\n\nconst toEventStoreDBReadOptions = <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n>(\n options: ReadStreamOptions<EventType, EventPayloadType> | undefined,\n): ESDBReadStreamOptions | undefined => {\n return options\n ? {\n fromRevision: 'from' in options ? options.from : undefined,\n maxCount:\n 'maxCount' in options\n ? options.maxCount\n : 'to' in options\n ? options.to\n : undefined,\n }\n : undefined;\n};\n\nexport const EventStoreDBEventStoreDefaultStreamVersion = -1n;\n\nexport type EventStoreDBReadEventMetadata = ReadEventMetadataWithGlobalPosition;\n\nexport type EventStoreDBReadEvent<EventType extends Event = Event> = ReadEvent<\n EventType,\n EventStoreDBReadEventMetadata\n>;\n\nexport interface EventStoreDBEventStore extends EventStore<EventStoreDBReadEventMetadata> {\n appendToStream<\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n events: EventType[],\n options?: AppendToStreamOptions<EventType, EventPayloadType>,\n ): Promise<AppendToStreamResultWithGlobalPosition>;\n consumer<ConsumerEventType extends Event = Event>(\n options?: EventStoreDBEventStoreConsumerConfig<ConsumerEventType>,\n ): EventStoreDBEventStoreConsumer<ConsumerEventType>;\n}\n\nexport const getEventStoreDBEventStore = (\n eventStore: EventStoreDBClient,\n): EventStoreDBEventStore => {\n return {\n async aggregateStream<\n State,\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n options: AggregateStreamOptions<\n State,\n EventType,\n EventStoreDBReadEventMetadata,\n EventPayloadType\n >,\n ): Promise<AggregateStreamResultWithGlobalPosition<State>> {\n const { evolve, initialState, read } = options;\n\n const expectedStreamVersion = read?.expectedStreamVersion;\n\n let state = initialState();\n let currentStreamVersion: bigint =\n EventStoreDBEventStoreDefaultStreamVersion;\n let lastCheckpoint: bigint | undefined = undefined;\n\n try {\n for await (const resolvedEvent of eventStore.readStream<EventPayloadType>(\n streamName,\n toEventStoreDBReadOptions(options.read),\n )) {\n const { event } = resolvedEvent;\n if (!event) continue;\n\n state = evolve(\n state,\n upcastRecordedMessage(\n mapFromESDBEvent<EventPayloadType>(resolvedEvent),\n options?.read?.schema?.versioning,\n ),\n );\n currentStreamVersion = event.revision;\n lastCheckpoint = event.position?.commit;\n }\n\n assertExpectedVersionMatchesCurrent(\n currentStreamVersion,\n expectedStreamVersion,\n EventStoreDBEventStoreDefaultStreamVersion,\n );\n\n return lastCheckpoint\n ? {\n currentStreamVersion,\n lastEventGlobalPosition:\n bigIntProcessorCheckpoint(lastCheckpoint),\n state,\n streamExists: true,\n }\n : {\n currentStreamVersion,\n state,\n streamExists: false,\n };\n } catch (error) {\n if (error instanceof StreamNotFoundError) {\n return {\n currentStreamVersion,\n state,\n streamExists: false,\n };\n }\n\n throw error;\n }\n },\n\n readStream: async <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n options?: ReadStreamOptions<EventType, EventPayloadType>,\n ): Promise<ReadStreamResult<EventType, EventStoreDBReadEventMetadata>> => {\n const events: ReadEvent<EventType, EventStoreDBReadEventMetadata>[] = [];\n\n let currentStreamVersion: bigint =\n EventStoreDBEventStoreDefaultStreamVersion;\n\n try {\n for await (const resolvedEvent of eventStore.readStream<EventPayloadType>(\n streamName,\n toEventStoreDBReadOptions(options),\n )) {\n const { event } = resolvedEvent;\n if (!event) continue;\n events.push(\n upcastRecordedMessage(\n mapFromESDBEvent<EventPayloadType>(resolvedEvent),\n options?.schema?.versioning,\n ),\n );\n\n currentStreamVersion = event.revision;\n }\n return {\n currentStreamVersion,\n events,\n streamExists: true,\n };\n } catch (error) {\n if (error instanceof StreamNotFoundError) {\n return {\n currentStreamVersion,\n events: [],\n streamExists: false,\n };\n }\n\n throw error;\n }\n },\n\n appendToStream: async <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n events: EventType[],\n options?: AppendToStreamOptions<EventType, EventPayloadType>,\n ): Promise<AppendToStreamResultWithGlobalPosition> => {\n try {\n const eventsToStore = downcastRecordedMessages(\n events,\n options?.schema?.versioning,\n );\n const serializedEvents = eventsToStore.map(jsonEvent);\n\n const expectedRevision = toExpectedRevision(\n options?.expectedStreamVersion,\n );\n\n const appendResult = await eventStore.appendToStream(\n streamName,\n serializedEvents,\n {\n expectedRevision,\n },\n );\n\n return {\n nextExpectedStreamVersion: appendResult.nextExpectedRevision,\n lastEventGlobalPosition: bigIntProcessorCheckpoint(\n appendResult.position!.commit,\n ),\n createdNewStream:\n appendResult.nextExpectedRevision >=\n BigInt(serializedEvents.length),\n };\n } catch (error) {\n if (error instanceof WrongExpectedVersionError) {\n throw new ExpectedVersionConflictError(\n BigInt(error.actualVersion),\n toExpectedVersion(error.expectedVersion),\n );\n }\n\n throw error;\n }\n },\n\n consumer: <ConsumerEventType extends Event = Event>(\n options?: EventStoreDBEventStoreConsumerConfig<ConsumerEventType>,\n ): EventStoreDBEventStoreConsumer<ConsumerEventType> =>\n eventStoreDBEventStoreConsumer<ConsumerEventType>({\n ...(options ?? {}),\n client: eventStore,\n }),\n\n streamExists: async (streamName: string): Promise<StreamExistsResult> => {\n try {\n for await (const resolvedEvent of eventStore.readStream(streamName)) {\n const { event } = resolvedEvent;\n\n if (!event) continue;\n\n return true;\n }\n\n return false;\n } catch (error) {\n if (error instanceof StreamNotFoundError) {\n return false;\n }\n\n throw error;\n }\n },\n\n //streamEvents: streamEvents(eventStore),\n };\n};\n\nconst getESDBCheckpoint = <MessageType extends AnyMessage = AnyMessage>(\n resolvedEvent: ResolvedEvent<MessageType>,\n from?: EventStoreDBEventStoreConsumerType,\n): bigint => {\n return !from || from?.stream === $all\n ? (resolvedEvent.link?.position?.commit ??\n resolvedEvent.event?.position?.commit)!\n : (resolvedEvent.link?.revision ?? resolvedEvent.event!.revision);\n};\n\nexport const mapFromESDBEvent = <MessageType extends AnyMessage = AnyMessage>(\n resolvedEvent: ResolvedEvent<MessageType>,\n from?: EventStoreDBEventStoreConsumerType,\n): RecordedMessage<MessageType, EventStoreDBReadEventMetadata> => {\n const event = resolvedEvent.event!;\n return <RecordedMessage<MessageType, EventStoreDBReadEventMetadata>>{\n type: event.type,\n data: event.data,\n metadata: {\n ...((event.metadata as EventStoreDBReadEventMetadata) ??\n ({} as EventStoreDBReadEventMetadata)),\n eventId: event.id,\n streamName: event.streamId,\n streamPosition: event.revision,\n globalPosition: bigIntProcessorCheckpoint(event.position!.commit),\n checkpoint: bigIntProcessorCheckpoint(\n getESDBCheckpoint(resolvedEvent, from),\n ),\n },\n };\n};\n\nconst toExpectedRevision = (\n expected: ExpectedStreamVersion | undefined,\n): AppendExpectedRevision => {\n if (expected === undefined) return ANY;\n\n if (expected === NO_CONCURRENCY_CHECK) return ANY;\n\n if (expected == STREAM_DOES_NOT_EXIST) return NO_STREAM;\n\n if (expected == STREAM_EXISTS) return ESDB_STREAM_EXISTS;\n\n return expected as bigint;\n};\n\nconst toExpectedVersion = (\n expected: AppendExpectedRevision | undefined,\n): ExpectedStreamVersion => {\n if (expected === undefined) return NO_CONCURRENCY_CHECK;\n\n if (expected === ANY) return NO_CONCURRENCY_CHECK;\n\n if (expected == NO_STREAM) return STREAM_DOES_NOT_EXIST;\n\n if (expected == ESDB_STREAM_EXISTS) return STREAM_EXISTS;\n\n return expected;\n};\n\n// const { map } = streamTransformations;\n//\n// // eslint-disable-next-line @typescript-eslint/no-unused-vars\n// const convertToWebReadableStream = (\n// allStreamSubscription: AllStreamSubscription,\n// ): ReadableStream<AllStreamResolvedEvent | GlobalStreamCaughtUp> => {\n// // Validate the input type\n// if (!(allStreamSubscription instanceof Readable)) {\n// throw new Error('Provided stream is not a Node.js Readable stream.');\n// }\n\n// let globalPosition = 0n;\n\n// const stream = Readable.toWeb(\n// allStreamSubscription,\n// ) as ReadableStream<AllStreamResolvedEvent>;\n\n// const writable = new WritableStream<\n// AllStreamResolvedEvent | GlobalStreamCaughtUp\n// >();\n\n// allStreamSubscription.on('caughtUp', async () => {\n// console.log(globalPosition);\n// await writable.getWriter().write(globalStreamCaughtUp({ globalPosition }));\n// });\n\n// const transform = map<\n// AllStreamResolvedEvent,\n// AllStreamResolvedEvent | GlobalStreamCaughtUp\n// >((event) => {\n// if (event?.event?.position.commit)\n// globalPosition = event.event?.position.commit;\n\n// return event;\n// });\n\n// return stream.pipeThrough<AllStreamResolvedEvent | GlobalStreamCaughtUp>(\n// transform,\n// );\n// };\n\n// const streamEvents = (eventStore: EventStoreDBClient) => () => {\n// return restream<\n// AllStreamResolvedEvent | GlobalSubscriptionEvent,\n// | ReadEvent<Event, EventStoreDBReadEventMetadata>\n// | GlobalSubscriptionEvent\n// >(\n// (): ReadableStream<AllStreamResolvedEvent | GlobalSubscriptionEvent> =>\n// convertToWebReadableStream(\n// eventStore.subscribeToAll({\n// fromPosition: START,\n// filter: excludeSystemEvents(),\n// }),\n// ),\n// (\n// resolvedEvent: AllStreamResolvedEvent | GlobalSubscriptionEvent,\n// ): ReadEvent<Event, EventStoreDBReadEventMetadata> =>\n// mapFromESDBEvent(resolvedEvent.event as JSONRecordedEvent<Event>),\n// );\n// };\n","import {\n asyncRetry,\n getCheckpoint,\n isString,\n JSONSerializer,\n parseBigIntProcessorCheckpoint,\n type AnyMessage,\n type AsyncAwaiter,\n type AsyncRetryOptions,\n type BatchRecordedMessageHandlerWithoutContext,\n type EmmettError,\n type Message,\n type ProcessorCheckpoint,\n type SingleMessageHandlerResult,\n} from '@event-driven-io/emmett';\nimport type { EventStoreDBClient } from '@eventstore/db-client';\nimport {\n END,\n excludeSystemEvents,\n START,\n type ResolvedEvent,\n type StreamSubscription,\n} from '@eventstore/db-client';\nimport { pipeline, Transform, Writable, type WritableOptions } from 'stream';\nimport {\n mapFromESDBEvent,\n type EventStoreDBReadEventMetadata,\n} from '../../eventstoreDBEventStore';\nimport {\n $all,\n type EventStoreDBEventStoreConsumerType,\n} from '../eventStoreDBEventStoreConsumer';\n\nexport const DefaultEventStoreDBEventStoreProcessorBatchSize = 100;\nexport const DefaultEventStoreDBEventStoreProcessorPullingFrequencyInMs = 50;\n\nexport type EventStoreDBEventStoreMessagesBatchHandlerResult = void | {\n type: 'STOP';\n reason?: string;\n error?: EmmettError;\n};\n\nexport type EventStoreDBSubscriptionOptions<\n MessageType extends Message = Message,\n> = {\n from?: EventStoreDBEventStoreConsumerType;\n client: EventStoreDBClient;\n batchSize: number;\n eachBatch: BatchRecordedMessageHandlerWithoutContext<\n MessageType,\n EventStoreDBReadEventMetadata\n >;\n resilience?: {\n resubscribeOptions?: AsyncRetryOptions;\n };\n};\n\nexport type EventStoreDBSubscriptionStartFrom =\n { lastCheckpoint: ProcessorCheckpoint } | 'BEGINNING' | 'END';\n\nexport type EventStoreDBSubscriptionStartOptions = {\n startFrom: EventStoreDBSubscriptionStartFrom;\n started?: AsyncAwaiter<void>;\n};\n\nexport type EventStoreDBSubscription = {\n isRunning: boolean;\n start(options: EventStoreDBSubscriptionStartOptions): Promise<void>;\n stop(): Promise<void>;\n};\n\nconst toGlobalPosition = (startFrom: EventStoreDBSubscriptionStartFrom) =>\n startFrom === 'BEGINNING'\n ? START\n : startFrom === 'END'\n ? END\n : {\n prepare: parseBigIntProcessorCheckpoint(startFrom.lastCheckpoint),\n commit: parseBigIntProcessorCheckpoint(startFrom.lastCheckpoint),\n };\n\nconst toStreamPosition = (startFrom: EventStoreDBSubscriptionStartFrom) =>\n startFrom === 'BEGINNING'\n ? START\n : startFrom === 'END'\n ? END\n : parseBigIntProcessorCheckpoint(startFrom.lastCheckpoint);\n\nconst subscribe = (\n client: EventStoreDBClient,\n from: EventStoreDBEventStoreConsumerType | undefined,\n options: EventStoreDBSubscriptionStartOptions,\n) =>\n from == undefined || from.stream == $all\n ? client.subscribeToAll({\n ...(from?.options ?? {}),\n fromPosition: toGlobalPosition(options.startFrom),\n filter: excludeSystemEvents(),\n })\n : client.subscribeToStream(from.stream, {\n ...(from.options ?? {}),\n fromRevision: toStreamPosition(options.startFrom),\n });\n\nexport const isDatabaseUnavailableError = (error: unknown) =>\n error instanceof Error &&\n 'type' in error &&\n error.type === 'unavailable' &&\n 'code' in error &&\n error.code === 14;\n\nexport const EventStoreDBResubscribeDefaultOptions: AsyncRetryOptions = {\n forever: true,\n minTimeout: 100,\n factor: 1.5,\n shouldRetryError: (error) => !isDatabaseUnavailableError(error),\n};\n\ntype SubscriptionSequentialHandlerOptions<\n MessageType extends AnyMessage = AnyMessage,\n> = EventStoreDBSubscriptionOptions<MessageType> & WritableOptions;\n\nclass SubscriptionSequentialHandler<\n MessageType extends AnyMessage = AnyMessage,\n> extends Transform {\n private options: SubscriptionSequentialHandlerOptions<MessageType>;\n private from: EventStoreDBEventStoreConsumerType | undefined;\n public isRunning: boolean;\n\n constructor(options: SubscriptionSequentialHandlerOptions<MessageType>) {\n super({ objectMode: true, ...options });\n this.options = options;\n this.from = options.from;\n this.isRunning = true;\n }\n\n async _transform(\n resolvedEvent: ResolvedEvent<MessageType>,\n _encoding: BufferEncoding,\n callback: (error?: Error | null) => void,\n ): Promise<void> {\n try {\n if (!this.isRunning || !resolvedEvent.event) {\n callback();\n return;\n }\n\n const message = mapFromESDBEvent(resolvedEvent, this.from);\n const messageCheckpoint = getCheckpoint(message);\n\n const result = await this.options.eachBatch([message]);\n\n if (result && result.type === 'STOP') {\n this.isRunning = false;\n if (!result.error) this.push(messageCheckpoint);\n\n this.push(result);\n this.push(null);\n callback();\n return;\n }\n\n this.push(messageCheckpoint);\n callback();\n } catch (error) {\n callback(error as Error);\n }\n }\n}\n\nexport const eventStoreDBSubscription = <\n MessageType extends AnyMessage = AnyMessage,\n>({\n client,\n from,\n batchSize,\n eachBatch,\n resilience,\n}: EventStoreDBSubscriptionOptions<MessageType>): EventStoreDBSubscription => {\n let isRunning = false;\n\n let start: Promise<void>;\n let processor: SubscriptionSequentialHandler<MessageType>;\n\n let subscription: StreamSubscription<MessageType>;\n\n const resubscribeOptions: AsyncRetryOptions =\n resilience?.resubscribeOptions ?? {\n ...EventStoreDBResubscribeDefaultOptions,\n shouldRetryResult: () => isRunning,\n shouldRetryError: (error) =>\n isRunning &&\n EventStoreDBResubscribeDefaultOptions.shouldRetryError!(error),\n };\n\n const stopSubscription = (callback?: () => void): Promise<void> => {\n isRunning = false;\n if (processor) processor.isRunning = false;\n return subscription\n .unsubscribe()\n .then(() => {\n subscription.destroy();\n })\n .catch((err) => console.error('Error during unsubscribe.%s', err))\n .finally(callback ?? (() => {}));\n };\n\n const pipeMessages = (options: EventStoreDBSubscriptionStartOptions) => {\n let retry = 0;\n return asyncRetry(\n () =>\n new Promise<void>((resolve, reject) => {\n if (!isRunning) {\n resolve();\n return;\n }\n console.info(\n `Starting subscription. ${retry++} retries. From: ${JSONSerializer.serialize(from ?? '$all')}, Start from: ${JSONSerializer.serialize(\n options.startFrom,\n )}`,\n );\n subscription = subscribe(client, from, options);\n subscription.once('confirmation', () => options.started?.resolve());\n\n processor = new SubscriptionSequentialHandler({\n client,\n from,\n batchSize,\n eachBatch,\n resilience,\n });\n\n const handler = new (class extends Writable {\n async _write(\n result: ProcessorCheckpoint | SingleMessageHandlerResult,\n _encoding: string,\n done: () => void,\n ) {\n if (!isRunning) return;\n\n if (isString(result)) {\n options.startFrom = {\n lastCheckpoint: result,\n };\n done();\n return;\n }\n\n if (result && result.type === 'STOP' && result.error) {\n console.error(\n `Subscription stopped with error code: ${result.error.errorCode}, message: ${\n result.error.message\n }.`,\n );\n }\n\n await stopSubscription();\n done();\n }\n })({ objectMode: true });\n\n pipeline(\n subscription,\n processor,\n handler,\n async (error: Error | null) => {\n console.info(`Stopping subscription.`);\n await stopSubscription(() => {\n if (!error) {\n console.info('Subscription ended successfully.');\n resolve();\n return;\n }\n console.error(\n `Received error: ${JSONSerializer.serialize(error)}.`,\n );\n options.started?.reject(error);\n reject(error);\n });\n },\n );\n }),\n resubscribeOptions,\n );\n };\n\n return {\n get isRunning() {\n return isRunning;\n },\n start: (options) => {\n if (isRunning) return start;\n\n start = (async () => {\n isRunning = true;\n\n return pipeMessages(options);\n })();\n\n return start;\n },\n stop: async () => {\n if (!isRunning) return start ? await start : Promise.resolve();\n await stopSubscription();\n await start;\n },\n };\n};\n\nexport const zipEventStoreDBEventStoreMessageBatchPullerStartFrom = (\n options: (EventStoreDBSubscriptionStartFrom | undefined)[],\n): EventStoreDBSubscriptionStartFrom => {\n if (\n options.length === 0 ||\n options.some((o) => o === undefined || o === 'BEGINNING')\n )\n return 'BEGINNING';\n\n if (options.every((o) => o === 'END')) return 'END';\n\n return options\n .filter((o) => o !== undefined && o !== 'BEGINNING' && o !== 'END')\n .sort((a, b) => (a > b ? 1 : -1))[0]!;\n};\n","import type {\n AsyncAwaiter,\n MessageHandlerContext,\n MessageProcessor,\n} from '@event-driven-io/emmett';\nimport {\n asyncAwaiter,\n EmmettError,\n inMemoryProjector,\n inMemoryReactor,\n type AnyEvent,\n type AnyMessage,\n type AnyRecordedMessageMetadata,\n type AsyncRetryOptions,\n type BatchRecordedMessageHandlerWithoutContext,\n type InMemoryProcessor,\n type InMemoryProjectorOptions,\n type InMemoryReactorOptions,\n type Message,\n type MessageConsumer,\n type MessageConsumerOptions,\n} from '@event-driven-io/emmett';\nimport {\n EventStoreDBClient,\n type SubscribeToAllOptions,\n type SubscribeToStreamOptions,\n} from '@eventstore/db-client';\nimport { v7 as uuid } from 'uuid';\nimport type { EventStoreDBReadEventMetadata } from '../eventstoreDBEventStore';\nimport {\n DefaultEventStoreDBEventStoreProcessorBatchSize,\n eventStoreDBSubscription,\n zipEventStoreDBEventStoreMessageBatchPullerStartFrom,\n type EventStoreDBSubscription,\n} from './subscriptions';\n\nexport type EventStoreDBEventStoreConsumerConfig<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ConsumerMessageType extends Message = any,\n> = MessageConsumerOptions<ConsumerMessageType> & {\n from?: EventStoreDBEventStoreConsumerType;\n pulling?: {\n batchSize?: number;\n };\n resilience?: {\n resubscribeOptions?: AsyncRetryOptions;\n };\n};\n\nexport type EventStoreDBEventStoreConsumerOptions<\n ConsumerEventType extends Message = Message,\n> = EventStoreDBEventStoreConsumerConfig<ConsumerEventType> &\n (\n | {\n connectionString: string;\n client?: never;\n }\n | { client: EventStoreDBClient; connectionString?: never }\n );\n\nexport type $all = '$all';\nexport const $all = '$all';\n\nexport type EventStoreDBEventStoreConsumerType =\n | {\n stream: $all;\n options?: Exclude<SubscribeToAllOptions, 'fromPosition'>;\n }\n | {\n stream: string;\n options?: Exclude<SubscribeToStreamOptions, 'fromRevision'>;\n };\n\nexport type EventStoreDBEventStoreConsumer<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ConsumerMessageType extends AnyMessage = any,\n> = MessageConsumer<ConsumerMessageType> &\n Readonly<{\n reactor: <MessageType extends AnyMessage = ConsumerMessageType>(\n options: InMemoryReactorOptions<MessageType>,\n ) => InMemoryProcessor<MessageType>;\n }> &\n (AnyEvent extends ConsumerMessageType\n ? Readonly<{\n projector: <\n EventType extends AnyEvent = ConsumerMessageType & AnyEvent,\n >(\n options: InMemoryProjectorOptions<EventType>,\n ) => InMemoryProcessor<EventType>;\n }>\n : object);\n\nexport const eventStoreDBEventStoreConsumer = <\n ConsumerMessageType extends Message = AnyMessage,\n>(\n options: EventStoreDBEventStoreConsumerOptions<ConsumerMessageType>,\n): EventStoreDBEventStoreConsumer<ConsumerMessageType> => {\n let isRunning = false;\n let isInitialized = false;\n const { pulling } = options;\n const processors = options.processors ?? [];\n let abortController: AbortController | null = null;\n\n let start: Promise<void>;\n\n let currentSubscription: EventStoreDBSubscription | undefined;\n\n const startedAwaiter: AsyncAwaiter<void> = asyncAwaiter<void>();\n\n const client =\n 'client' in options && options.client\n ? options.client\n : EventStoreDBClient.connectionString(options.connectionString);\n\n const eachBatch: BatchRecordedMessageHandlerWithoutContext<\n ConsumerMessageType,\n EventStoreDBReadEventMetadata\n > = async (messagesBatch) => {\n const activeProcessors = processors.filter((s) => s.isActive);\n\n if (activeProcessors.length === 0)\n return {\n type: 'STOP',\n reason: 'No active processors',\n };\n\n const result = await Promise.allSettled(\n activeProcessors.map(async (s) => {\n // TODO: Add here filtering to only pass messages that can be handled by\n return await s.handle(messagesBatch, { client });\n }),\n );\n\n const error = result.find((r) => r.status === 'rejected')?.reason as\n Error | undefined;\n\n return result.some(\n (r) => r.status === 'fulfilled' && r.value?.type !== 'STOP',\n )\n ? undefined\n : {\n type: 'STOP',\n error: error ? EmmettError.mapFrom(error) : undefined,\n };\n };\n\n const subscription = (currentSubscription = eventStoreDBSubscription({\n client,\n from: options.from,\n eachBatch,\n batchSize:\n pulling?.batchSize ?? DefaultEventStoreDBEventStoreProcessorBatchSize,\n resilience: options.resilience,\n }));\n\n const init = async (): Promise<void> => {\n if (isInitialized) return;\n for (const processor of processors) {\n await processor.init({});\n }\n isInitialized = true;\n };\n\n const stopProcessors = () => Promise.all(processors.map((p) => p.close({})));\n\n const stop = async () => {\n if (!isRunning) return;\n isRunning = false;\n abortController?.abort();\n if (currentSubscription) {\n await currentSubscription.stop();\n currentSubscription = undefined;\n }\n await start;\n abortController = null;\n await stopProcessors();\n };\n\n return {\n consumerId: options.consumerId ?? uuid(),\n get isRunning() {\n return isRunning;\n },\n whenStarted: (): Promise<void> => startedAwaiter.wait,\n processors,\n reactor: <MessageType extends AnyMessage = ConsumerMessageType>(\n options: InMemoryReactorOptions<MessageType>,\n ): InMemoryProcessor<MessageType> => {\n const processor = inMemoryReactor(options);\n\n processors.push(\n // TODO: change that\n processor as unknown as MessageProcessor<\n ConsumerMessageType,\n AnyRecordedMessageMetadata,\n MessageHandlerContext\n >,\n );\n\n return processor;\n },\n projector: <EventType extends AnyEvent = ConsumerMessageType & AnyEvent>(\n options: InMemoryProjectorOptions<EventType>,\n ): InMemoryProcessor<EventType> => {\n const processor = inMemoryProjector(options);\n\n processors.push(\n // TODO: change that\n processor as unknown as MessageProcessor<\n ConsumerMessageType,\n AnyRecordedMessageMetadata,\n MessageHandlerContext\n >,\n );\n\n return processor;\n },\n start: () => {\n if (isRunning) return start;\n\n startedAwaiter.reset();\n\n if (processors.length === 0) {\n const error = new EmmettError(\n 'Cannot start consumer without at least a single processor',\n );\n startedAwaiter.reject(error);\n return Promise.reject(error);\n }\n isRunning = true;\n abortController = new AbortController();\n\n start = (async () => {\n if (!isRunning) return;\n\n try {\n if (!isInitialized) {\n await init();\n }\n\n const startFrom =\n zipEventStoreDBEventStoreMessageBatchPullerStartFrom(\n await Promise.all(processors.map((o) => o.start(client))),\n );\n\n await subscription.start({ startFrom, started: startedAwaiter });\n } catch (error) {\n isRunning = false;\n startedAwaiter.reject(error);\n throw error;\n } finally {\n await stopProcessors();\n }\n })();\n\n return start;\n },\n stop,\n close: stop,\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["StreamNotFoundError","jsonEvent","WrongExpectedVersionError","ExpectedVersionConflictError","ANY","NO_CONCURRENCY_CHECK","STREAM_DOES_NOT_EXIST","NO_STREAM","STREAM_EXISTS","ESDB_STREAM_EXISTS","START","END","Transform","JSONSerializer","Writable","EventStoreDBClient","EmmettError","CurrentMessageProcessorPosition"],"sources":["../src/eventStore/eventstoreDBEventStore.ts","../src/eventStore/consumers/subscriptions/index.ts","../src/eventStore/consumers/eventStoreDBEventStoreConsumer.ts"],"sourcesContent":["import {\n ExpectedVersionConflictError,\n NO_CONCURRENCY_CHECK,\n STREAM_DOES_NOT_EXIST,\n STREAM_EXISTS,\n assertExpectedVersionMatchesCurrent,\n bigIntProcessorCheckpoint,\n downcastRecordedMessages,\n upcastRecordedMessage,\n type AggregateStreamOptions,\n type AggregateStreamResultWithGlobalPosition,\n type AnyMessage,\n type AppendToStreamOptions,\n type AppendToStreamResultWithGlobalPosition,\n type Event,\n type EventStore,\n type ExpectedStreamVersion,\n type ReadEvent,\n type ReadEventMetadataWithGlobalPosition,\n type ReadStreamOptions,\n type ReadStreamResult,\n type RecordedMessage,\n type StreamExistsResult,\n} from '@event-driven-io/emmett';\nimport type { EventStoreDBClient } from '@eventstore/db-client';\nimport {\n ANY,\n STREAM_EXISTS as ESDB_STREAM_EXISTS,\n NO_STREAM,\n StreamNotFoundError,\n WrongExpectedVersionError,\n jsonEvent,\n type AppendExpectedRevision,\n type ReadStreamOptions as ESDBReadStreamOptions,\n type ResolvedEvent,\n} from '@eventstore/db-client';\nimport {\n $all,\n eventStoreDBEventStoreConsumer,\n type EventStoreDBEventStoreConsumer,\n type EventStoreDBEventStoreConsumerConfig,\n type EventStoreDBEventStoreConsumerType,\n} from './consumers';\n\nconst toEventStoreDBReadOptions = <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n>(\n options: ReadStreamOptions<EventType, EventPayloadType> | undefined,\n): ESDBReadStreamOptions | undefined => {\n return options\n ? {\n fromRevision: 'from' in options ? options.from : undefined,\n maxCount:\n 'maxCount' in options\n ? options.maxCount\n : 'to' in options\n ? options.to\n : undefined,\n }\n : undefined;\n};\n\nexport const EventStoreDBEventStoreDefaultStreamVersion = -1n;\n\nexport type EventStoreDBReadEventMetadata = ReadEventMetadataWithGlobalPosition;\n\nexport type EventStoreDBReadEvent<EventType extends Event = Event> = ReadEvent<\n EventType,\n EventStoreDBReadEventMetadata\n>;\n\nexport interface EventStoreDBEventStore extends EventStore<EventStoreDBReadEventMetadata> {\n appendToStream<\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n events: EventType[],\n options?: AppendToStreamOptions<EventType, EventPayloadType>,\n ): Promise<AppendToStreamResultWithGlobalPosition>;\n consumer<ConsumerEventType extends Event = Event>(\n options?: EventStoreDBEventStoreConsumerConfig<ConsumerEventType>,\n ): EventStoreDBEventStoreConsumer<ConsumerEventType>;\n}\n\nexport const getEventStoreDBEventStore = (\n eventStore: EventStoreDBClient,\n): EventStoreDBEventStore => {\n return {\n async aggregateStream<\n State,\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n options: AggregateStreamOptions<\n State,\n EventType,\n EventStoreDBReadEventMetadata,\n EventPayloadType\n >,\n ): Promise<AggregateStreamResultWithGlobalPosition<State>> {\n const { evolve, initialState, read } = options;\n\n const expectedStreamVersion = read?.expectedStreamVersion;\n\n let state = initialState();\n let currentStreamVersion: bigint =\n EventStoreDBEventStoreDefaultStreamVersion;\n let lastCheckpoint: bigint | undefined = undefined;\n\n try {\n for await (const resolvedEvent of eventStore.readStream<EventPayloadType>(\n streamName,\n toEventStoreDBReadOptions(options.read),\n )) {\n const { event } = resolvedEvent;\n if (!event) continue;\n\n state = evolve(\n state,\n upcastRecordedMessage(\n mapFromESDBEvent<EventPayloadType>(resolvedEvent),\n options?.read?.schema?.versioning,\n ),\n );\n currentStreamVersion = event.revision;\n lastCheckpoint = event.position?.commit;\n }\n\n assertExpectedVersionMatchesCurrent(\n currentStreamVersion,\n expectedStreamVersion,\n EventStoreDBEventStoreDefaultStreamVersion,\n );\n\n return lastCheckpoint\n ? {\n currentStreamVersion,\n lastEventGlobalPosition:\n bigIntProcessorCheckpoint(lastCheckpoint),\n state,\n streamExists: true,\n }\n : {\n currentStreamVersion,\n state,\n streamExists: false,\n };\n } catch (error) {\n if (error instanceof StreamNotFoundError) {\n return {\n currentStreamVersion,\n state,\n streamExists: false,\n };\n }\n\n throw error;\n }\n },\n\n readStream: async <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n options?: ReadStreamOptions<EventType, EventPayloadType>,\n ): Promise<ReadStreamResult<EventType, EventStoreDBReadEventMetadata>> => {\n const events: ReadEvent<EventType, EventStoreDBReadEventMetadata>[] = [];\n\n let currentStreamVersion: bigint =\n EventStoreDBEventStoreDefaultStreamVersion;\n\n try {\n for await (const resolvedEvent of eventStore.readStream<EventPayloadType>(\n streamName,\n toEventStoreDBReadOptions(options),\n )) {\n const { event } = resolvedEvent;\n if (!event) continue;\n events.push(\n upcastRecordedMessage(\n mapFromESDBEvent<EventPayloadType>(resolvedEvent),\n options?.schema?.versioning,\n ),\n );\n\n currentStreamVersion = event.revision;\n }\n return {\n currentStreamVersion,\n events,\n streamExists: true,\n };\n } catch (error) {\n if (error instanceof StreamNotFoundError) {\n return {\n currentStreamVersion,\n events: [],\n streamExists: false,\n };\n }\n\n throw error;\n }\n },\n\n appendToStream: async <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n events: EventType[],\n options?: AppendToStreamOptions<EventType, EventPayloadType>,\n ): Promise<AppendToStreamResultWithGlobalPosition> => {\n try {\n const eventsToStore = downcastRecordedMessages(\n events,\n options?.schema?.versioning,\n );\n const serializedEvents = eventsToStore.map(jsonEvent);\n\n const expectedRevision = toExpectedRevision(\n options?.expectedStreamVersion,\n );\n\n const appendResult = await eventStore.appendToStream(\n streamName,\n serializedEvents,\n {\n expectedRevision,\n },\n );\n\n return {\n nextExpectedStreamVersion: appendResult.nextExpectedRevision,\n lastEventGlobalPosition: bigIntProcessorCheckpoint(\n appendResult.position!.commit,\n ),\n createdNewStream:\n appendResult.nextExpectedRevision >=\n BigInt(serializedEvents.length),\n };\n } catch (error) {\n if (error instanceof WrongExpectedVersionError) {\n throw new ExpectedVersionConflictError(\n BigInt(error.actualVersion),\n toExpectedVersion(error.expectedVersion),\n );\n }\n\n throw error;\n }\n },\n\n consumer: <ConsumerEventType extends Event = Event>(\n options?: EventStoreDBEventStoreConsumerConfig<ConsumerEventType>,\n ): EventStoreDBEventStoreConsumer<ConsumerEventType> =>\n eventStoreDBEventStoreConsumer<ConsumerEventType>({\n ...(options ?? {}),\n client: eventStore,\n }),\n\n streamExists: async (streamName: string): Promise<StreamExistsResult> => {\n try {\n for await (const resolvedEvent of eventStore.readStream(streamName)) {\n const { event } = resolvedEvent;\n\n if (!event) continue;\n\n return true;\n }\n\n return false;\n } catch (error) {\n if (error instanceof StreamNotFoundError) {\n return false;\n }\n\n throw error;\n }\n },\n\n //streamEvents: streamEvents(eventStore),\n };\n};\n\nconst getESDBCheckpoint = <MessageType extends AnyMessage = AnyMessage>(\n resolvedEvent: ResolvedEvent<MessageType>,\n from?: EventStoreDBEventStoreConsumerType,\n): bigint => {\n return !from || from?.stream === $all\n ? (resolvedEvent.link?.position?.commit ??\n resolvedEvent.event?.position?.commit)!\n : (resolvedEvent.link?.revision ?? resolvedEvent.event!.revision);\n};\n\nexport const mapFromESDBEvent = <MessageType extends AnyMessage = AnyMessage>(\n resolvedEvent: ResolvedEvent<MessageType>,\n from?: EventStoreDBEventStoreConsumerType,\n): RecordedMessage<MessageType, EventStoreDBReadEventMetadata> => {\n const event = resolvedEvent.event!;\n return <RecordedMessage<MessageType, EventStoreDBReadEventMetadata>>{\n type: event.type,\n data: event.data,\n metadata: {\n ...((event.metadata as EventStoreDBReadEventMetadata) ??\n ({} as EventStoreDBReadEventMetadata)),\n eventId: event.id,\n streamName: event.streamId,\n streamPosition: event.revision,\n globalPosition: bigIntProcessorCheckpoint(event.position!.commit),\n checkpoint: bigIntProcessorCheckpoint(\n getESDBCheckpoint(resolvedEvent, from),\n ),\n },\n };\n};\n\nconst toExpectedRevision = (\n expected: ExpectedStreamVersion | undefined,\n): AppendExpectedRevision => {\n if (expected === undefined) return ANY;\n\n if (expected === NO_CONCURRENCY_CHECK) return ANY;\n\n if (expected == STREAM_DOES_NOT_EXIST) return NO_STREAM;\n\n if (expected == STREAM_EXISTS) return ESDB_STREAM_EXISTS;\n\n return expected as bigint;\n};\n\nconst toExpectedVersion = (\n expected: AppendExpectedRevision | undefined,\n): ExpectedStreamVersion => {\n if (expected === undefined) return NO_CONCURRENCY_CHECK;\n\n if (expected === ANY) return NO_CONCURRENCY_CHECK;\n\n if (expected == NO_STREAM) return STREAM_DOES_NOT_EXIST;\n\n if (expected == ESDB_STREAM_EXISTS) return STREAM_EXISTS;\n\n return expected;\n};\n\n// const { map } = streamTransformations;\n//\n// // eslint-disable-next-line @typescript-eslint/no-unused-vars\n// const convertToWebReadableStream = (\n// allStreamSubscription: AllStreamSubscription,\n// ): ReadableStream<AllStreamResolvedEvent | GlobalStreamCaughtUp> => {\n// // Validate the input type\n// if (!(allStreamSubscription instanceof Readable)) {\n// throw new Error('Provided stream is not a Node.js Readable stream.');\n// }\n\n// let globalPosition = 0n;\n\n// const stream = Readable.toWeb(\n// allStreamSubscription,\n// ) as ReadableStream<AllStreamResolvedEvent>;\n\n// const writable = new WritableStream<\n// AllStreamResolvedEvent | GlobalStreamCaughtUp\n// >();\n\n// allStreamSubscription.on('caughtUp', async () => {\n// console.log(globalPosition);\n// await writable.getWriter().write(globalStreamCaughtUp({ globalPosition }));\n// });\n\n// const transform = map<\n// AllStreamResolvedEvent,\n// AllStreamResolvedEvent | GlobalStreamCaughtUp\n// >((event) => {\n// if (event?.event?.position.commit)\n// globalPosition = event.event?.position.commit;\n\n// return event;\n// });\n\n// return stream.pipeThrough<AllStreamResolvedEvent | GlobalStreamCaughtUp>(\n// transform,\n// );\n// };\n\n// const streamEvents = (eventStore: EventStoreDBClient) => () => {\n// return restream<\n// AllStreamResolvedEvent | GlobalSubscriptionEvent,\n// | ReadEvent<Event, EventStoreDBReadEventMetadata>\n// | GlobalSubscriptionEvent\n// >(\n// (): ReadableStream<AllStreamResolvedEvent | GlobalSubscriptionEvent> =>\n// convertToWebReadableStream(\n// eventStore.subscribeToAll({\n// fromPosition: START,\n// filter: excludeSystemEvents(),\n// }),\n// ),\n// (\n// resolvedEvent: AllStreamResolvedEvent | GlobalSubscriptionEvent,\n// ): ReadEvent<Event, EventStoreDBReadEventMetadata> =>\n// mapFromESDBEvent(resolvedEvent.event as JSONRecordedEvent<Event>),\n// );\n// };\n","import type { CurrentMessageProcessorPosition } from '@event-driven-io/emmett';\nimport {\n asyncRetry,\n getCheckpoint,\n isString,\n JSONSerializer,\n parseBigIntProcessorCheckpoint,\n type AnyMessage,\n type AsyncAwaiter,\n type AsyncRetryOptions,\n type BatchRecordedMessageHandlerWithoutContext,\n type EmmettError,\n type Message,\n type ProcessorCheckpoint,\n type SingleMessageHandlerResult,\n} from '@event-driven-io/emmett';\nimport type { EventStoreDBClient } from '@eventstore/db-client';\nimport {\n END,\n excludeSystemEvents,\n START,\n type ResolvedEvent,\n type StreamSubscription,\n} from '@eventstore/db-client';\nimport { pipeline, Transform, Writable, type WritableOptions } from 'stream';\nimport {\n mapFromESDBEvent,\n type EventStoreDBReadEventMetadata,\n} from '../../eventstoreDBEventStore';\nimport {\n $all,\n type EventStoreDBEventStoreConsumerType,\n} from '../eventStoreDBEventStoreConsumer';\n\nexport const DefaultEventStoreDBEventStoreProcessorBatchSize = 100;\nexport const DefaultEventStoreDBEventStoreProcessorPullingFrequencyInMs = 50;\n\nexport type EventStoreDBEventStoreMessagesBatchHandlerResult = void | {\n type: 'STOP';\n reason?: string;\n error?: EmmettError;\n};\n\nexport type EventStoreDBSubscriptionOptions<\n MessageType extends Message = Message,\n> = {\n from?: EventStoreDBEventStoreConsumerType;\n client: EventStoreDBClient;\n batchSize: number;\n eachBatch: BatchRecordedMessageHandlerWithoutContext<\n MessageType,\n EventStoreDBReadEventMetadata\n >;\n resilience?: {\n resubscribeOptions?: AsyncRetryOptions;\n };\n};\n\nexport type EventStoreDBSubscriptionStartFrom = CurrentMessageProcessorPosition;\n\nexport type EventStoreDBSubscriptionStartOptions = {\n startFrom: EventStoreDBSubscriptionStartFrom;\n started?: AsyncAwaiter<void>;\n};\n\nexport type EventStoreDBSubscription = {\n isRunning: boolean;\n start(options: EventStoreDBSubscriptionStartOptions): Promise<void>;\n stop(): Promise<void>;\n};\n\nconst toGlobalPosition = (startFrom: EventStoreDBSubscriptionStartFrom) =>\n startFrom === 'BEGINNING'\n ? START\n : startFrom === 'END'\n ? END\n : {\n prepare: parseBigIntProcessorCheckpoint(startFrom.lastCheckpoint),\n commit: parseBigIntProcessorCheckpoint(startFrom.lastCheckpoint),\n };\n\nconst toStreamPosition = (startFrom: EventStoreDBSubscriptionStartFrom) =>\n startFrom === 'BEGINNING'\n ? START\n : startFrom === 'END'\n ? END\n : parseBigIntProcessorCheckpoint(startFrom.lastCheckpoint);\n\nconst subscribe = (\n client: EventStoreDBClient,\n from: EventStoreDBEventStoreConsumerType | undefined,\n options: EventStoreDBSubscriptionStartOptions,\n) =>\n from == undefined || from.stream == $all\n ? client.subscribeToAll({\n ...(from?.options ?? {}),\n fromPosition: toGlobalPosition(options.startFrom),\n filter: excludeSystemEvents(),\n })\n : client.subscribeToStream(from.stream, {\n ...(from.options ?? {}),\n fromRevision: toStreamPosition(options.startFrom),\n });\n\nexport const isDatabaseUnavailableError = (error: unknown) =>\n error instanceof Error &&\n 'type' in error &&\n error.type === 'unavailable' &&\n 'code' in error &&\n error.code === 14;\n\nexport const EventStoreDBResubscribeDefaultOptions: AsyncRetryOptions = {\n forever: true,\n minTimeout: 100,\n factor: 1.5,\n shouldRetryError: (error) => !isDatabaseUnavailableError(error),\n};\n\ntype SubscriptionSequentialHandlerOptions<\n MessageType extends AnyMessage = AnyMessage,\n> = EventStoreDBSubscriptionOptions<MessageType> & WritableOptions;\n\nclass SubscriptionSequentialHandler<\n MessageType extends AnyMessage = AnyMessage,\n> extends Transform {\n private options: SubscriptionSequentialHandlerOptions<MessageType>;\n private from: EventStoreDBEventStoreConsumerType | undefined;\n public isRunning: boolean;\n\n constructor(options: SubscriptionSequentialHandlerOptions<MessageType>) {\n super({ objectMode: true, ...options });\n this.options = options;\n this.from = options.from;\n this.isRunning = true;\n }\n\n async _transform(\n resolvedEvent: ResolvedEvent<MessageType>,\n _encoding: BufferEncoding,\n callback: (error?: Error | null) => void,\n ): Promise<void> {\n try {\n if (!this.isRunning || !resolvedEvent.event) {\n callback();\n return;\n }\n\n const message = mapFromESDBEvent(resolvedEvent, this.from);\n const messageCheckpoint = getCheckpoint(message);\n\n const result = await this.options.eachBatch([message]);\n\n if (result && result.type === 'STOP') {\n this.isRunning = false;\n if (!result.error) this.push(messageCheckpoint);\n\n this.push(result);\n this.push(null);\n callback();\n return;\n }\n\n this.push(messageCheckpoint);\n callback();\n } catch (error) {\n callback(error as Error);\n }\n }\n}\n\nexport const eventStoreDBSubscription = <\n MessageType extends AnyMessage = AnyMessage,\n>({\n client,\n from,\n batchSize,\n eachBatch,\n resilience,\n}: EventStoreDBSubscriptionOptions<MessageType>): EventStoreDBSubscription => {\n let isRunning = false;\n\n let start: Promise<void>;\n let processor: SubscriptionSequentialHandler<MessageType>;\n\n let subscription: StreamSubscription<MessageType>;\n\n const resubscribeOptions: AsyncRetryOptions =\n resilience?.resubscribeOptions ?? {\n ...EventStoreDBResubscribeDefaultOptions,\n shouldRetryResult: () => isRunning,\n shouldRetryError: (error) =>\n isRunning &&\n EventStoreDBResubscribeDefaultOptions.shouldRetryError!(error),\n };\n\n const stopSubscription = (callback?: () => void): Promise<void> => {\n isRunning = false;\n if (processor) processor.isRunning = false;\n return subscription\n .unsubscribe()\n .then(() => {\n subscription.destroy();\n })\n .catch((err) => console.error('Error during unsubscribe.%s', err))\n .finally(callback ?? (() => {}));\n };\n\n const pipeMessages = (options: EventStoreDBSubscriptionStartOptions) => {\n let retry = 0;\n return asyncRetry(\n () =>\n new Promise<void>((resolve, reject) => {\n if (!isRunning) {\n resolve();\n return;\n }\n console.info(\n `Starting subscription. ${retry++} retries. From: ${JSONSerializer.serialize(from ?? '$all')}, Start from: ${JSONSerializer.serialize(\n options.startFrom,\n )}`,\n );\n subscription = subscribe(client, from, options);\n subscription.once('confirmation', () => options.started?.resolve());\n\n processor = new SubscriptionSequentialHandler({\n client,\n from,\n batchSize,\n eachBatch,\n resilience,\n });\n\n const handler = new (class extends Writable {\n async _write(\n result: ProcessorCheckpoint | SingleMessageHandlerResult,\n _encoding: string,\n done: () => void,\n ) {\n if (!isRunning) return;\n\n if (isString(result)) {\n options.startFrom = {\n lastCheckpoint: result,\n };\n done();\n return;\n }\n\n if (result && result.type === 'STOP' && result.error) {\n console.error(\n `Subscription stopped with error code: ${result.error.errorCode}, message: ${\n result.error.message\n }.`,\n );\n }\n\n await stopSubscription();\n done();\n }\n })({ objectMode: true });\n\n pipeline(\n subscription,\n processor,\n handler,\n async (error: Error | null) => {\n console.info(`Stopping subscription.`);\n await stopSubscription(() => {\n if (!error) {\n console.info('Subscription ended successfully.');\n resolve();\n return;\n }\n console.error(\n `Received error: ${JSONSerializer.serialize(error)}.`,\n );\n options.started?.reject(error);\n reject(error);\n });\n },\n );\n }),\n resubscribeOptions,\n );\n };\n\n return {\n get isRunning() {\n return isRunning;\n },\n start: (options) => {\n if (isRunning) return start;\n\n start = (async () => {\n isRunning = true;\n\n return pipeMessages(options);\n })();\n\n return start;\n },\n stop: async () => {\n if (!isRunning) return start ? await start : Promise.resolve();\n await stopSubscription();\n await start;\n },\n };\n};\n","import type {\n AsyncAwaiter,\n MessageHandlerContext,\n MessageProcessor,\n} from '@event-driven-io/emmett';\nimport {\n asyncAwaiter,\n CurrentMessageProcessorPosition,\n EmmettError,\n inMemoryProjector,\n inMemoryReactor,\n mergeObservabilityOptions,\n type AnyEvent,\n type AnyMessage,\n type AnyRecordedMessageMetadata,\n type AsyncRetryOptions,\n type BatchRecordedMessageHandlerWithoutContext,\n type InMemoryProcessor,\n type InMemoryProjectorOptions,\n type InMemoryReactorOptions,\n type Message,\n type MessageConsumer,\n type MessageConsumerOptions,\n} from '@event-driven-io/emmett';\nimport {\n EventStoreDBClient,\n type SubscribeToAllOptions,\n type SubscribeToStreamOptions,\n} from '@eventstore/db-client';\nimport { v7 as uuid } from 'uuid';\nimport type { EventStoreDBReadEventMetadata } from '../eventstoreDBEventStore';\nimport {\n DefaultEventStoreDBEventStoreProcessorBatchSize,\n eventStoreDBSubscription,\n type EventStoreDBSubscription,\n} from './subscriptions';\n\nexport type EventStoreDBEventStoreConsumerConfig<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ConsumerMessageType extends Message = any,\n> = MessageConsumerOptions<ConsumerMessageType> & {\n from?: EventStoreDBEventStoreConsumerType;\n pulling?: {\n batchSize?: number;\n };\n resilience?: {\n resubscribeOptions?: AsyncRetryOptions;\n };\n};\n\nexport type EventStoreDBEventStoreConsumerOptions<\n ConsumerEventType extends Message = Message,\n> = EventStoreDBEventStoreConsumerConfig<ConsumerEventType> &\n (\n | {\n connectionString: string;\n client?: never;\n }\n | { client: EventStoreDBClient; connectionString?: never }\n );\n\nexport type $all = '$all';\nexport const $all = '$all';\n\nexport type EventStoreDBEventStoreConsumerType =\n | {\n stream: $all;\n options?: Exclude<SubscribeToAllOptions, 'fromPosition'>;\n }\n | {\n stream: string;\n options?: Exclude<SubscribeToStreamOptions, 'fromRevision'>;\n };\n\nexport type EventStoreDBEventStoreConsumer<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ConsumerMessageType extends AnyMessage = any,\n> = MessageConsumer<ConsumerMessageType> &\n Readonly<{\n reactor: <MessageType extends AnyMessage = ConsumerMessageType>(\n options: InMemoryReactorOptions<MessageType>,\n ) => InMemoryProcessor<MessageType>;\n }> &\n (AnyEvent extends ConsumerMessageType\n ? Readonly<{\n projector: <\n EventType extends AnyEvent = ConsumerMessageType & AnyEvent,\n >(\n options: InMemoryProjectorOptions<EventType>,\n ) => InMemoryProcessor<EventType>;\n }>\n : object);\n\nexport const eventStoreDBEventStoreConsumer = <\n ConsumerMessageType extends Message = AnyMessage,\n>(\n options: EventStoreDBEventStoreConsumerOptions<ConsumerMessageType>,\n): EventStoreDBEventStoreConsumer<ConsumerMessageType> => {\n let isRunning = false;\n let isInitialized = false;\n const { pulling } = options;\n const processors = options.processors ?? [];\n let abortController: AbortController | null = null;\n\n let start: Promise<void>;\n\n let currentSubscription: EventStoreDBSubscription | undefined;\n\n const startedAwaiter: AsyncAwaiter<void> = asyncAwaiter<void>();\n\n const client =\n 'client' in options && options.client\n ? options.client\n : EventStoreDBClient.connectionString(options.connectionString);\n\n const eachBatch: BatchRecordedMessageHandlerWithoutContext<\n ConsumerMessageType,\n EventStoreDBReadEventMetadata\n > = async (messagesBatch) => {\n const activeProcessors = processors.filter((s) => s.isActive);\n\n if (activeProcessors.length === 0)\n return {\n type: 'STOP',\n reason: 'No active processors',\n };\n\n const result = await Promise.allSettled(\n activeProcessors.map(async (s) => {\n // TODO: Add here filtering to only pass messages that can be handled by\n return await s.handle(messagesBatch, { client });\n }),\n );\n\n const error = result.find((r) => r.status === 'rejected')?.reason as\n Error | undefined;\n\n return result.some(\n (r) => r.status === 'fulfilled' && r.value?.type !== 'STOP',\n )\n ? undefined\n : {\n type: 'STOP',\n error: error ? EmmettError.mapFrom(error) : undefined,\n };\n };\n\n const subscription = (currentSubscription = eventStoreDBSubscription({\n client,\n from: options.from,\n eachBatch,\n batchSize:\n pulling?.batchSize ?? DefaultEventStoreDBEventStoreProcessorBatchSize,\n resilience: options.resilience,\n }));\n\n const init = async (): Promise<void> => {\n if (isInitialized) return;\n for (const processor of processors) {\n await processor.init({});\n }\n isInitialized = true;\n };\n\n const stopProcessors = () => Promise.all(processors.map((p) => p.close({})));\n\n const stop = async () => {\n if (!isRunning) return;\n isRunning = false;\n abortController?.abort();\n if (currentSubscription) {\n await currentSubscription.stop();\n currentSubscription = undefined;\n }\n await start;\n abortController = null;\n await stopProcessors();\n };\n\n return {\n consumerId: options.consumerId ?? uuid(),\n get isRunning() {\n return isRunning;\n },\n whenStarted: (): Promise<void> => startedAwaiter.wait,\n processors,\n reactor: <MessageType extends AnyMessage = ConsumerMessageType>(\n processorOptions: InMemoryReactorOptions<MessageType>,\n ): InMemoryProcessor<MessageType> => {\n const processor = inMemoryReactor(\n mergeObservabilityOptions(processorOptions, options.observability),\n );\n\n processors.push(\n // TODO: change that\n processor as unknown as MessageProcessor<\n ConsumerMessageType,\n AnyRecordedMessageMetadata,\n MessageHandlerContext\n >,\n );\n\n return processor;\n },\n projector: <EventType extends AnyEvent = ConsumerMessageType & AnyEvent>(\n processorOptions: InMemoryProjectorOptions<EventType>,\n ): InMemoryProcessor<EventType> => {\n const processor = inMemoryProjector(\n mergeObservabilityOptions(processorOptions, options.observability),\n );\n\n processors.push(\n // TODO: change that\n processor as unknown as MessageProcessor<\n ConsumerMessageType,\n AnyRecordedMessageMetadata,\n MessageHandlerContext\n >,\n );\n\n return processor;\n },\n start: () => {\n if (isRunning) return start;\n\n startedAwaiter.reset();\n\n if (processors.length === 0) {\n const error = new EmmettError(\n 'Cannot start consumer without at least a single processor',\n );\n startedAwaiter.reject(error);\n return Promise.reject(error);\n }\n isRunning = true;\n abortController = new AbortController();\n\n start = (async () => {\n if (!isRunning) return;\n\n try {\n if (!isInitialized) {\n await init();\n }\n\n const startFrom = CurrentMessageProcessorPosition.zip(\n await Promise.all(processors.map((o) => o.start(client))),\n );\n\n await subscription.start({ startFrom, started: startedAwaiter });\n } catch (error) {\n isRunning = false;\n startedAwaiter.reject(error);\n throw error;\n } finally {\n await stopProcessors();\n }\n })();\n\n return start;\n },\n stop,\n close: stop,\n };\n};\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { AnyEvent, AnyMessage, AppendToStreamOptions, AppendToStreamResultWithGlobalPosition, AsyncAwaiter, AsyncRetryOptions, BatchRecordedMessageHandlerWithoutContext, EmmettError, Event, EventStore, InMemoryProcessor, InMemoryProjectorOptions, InMemoryReactorOptions, Message, MessageConsumer, MessageConsumerOptions, ProcessorCheckpoint, ReadEvent, ReadEventMetadataWithGlobalPosition, RecordedMessage } from "@event-driven-io/emmett";
1
+ import { AnyEvent, AnyMessage, AppendToStreamOptions, AppendToStreamResultWithGlobalPosition, AsyncAwaiter, AsyncRetryOptions, BatchRecordedMessageHandlerWithoutContext, CurrentMessageProcessorPosition, EmmettError, Event, EventStore, InMemoryProcessor, InMemoryProjectorOptions, InMemoryReactorOptions, Message, MessageConsumer, MessageConsumerOptions, ReadEvent, ReadEventMetadataWithGlobalPosition, RecordedMessage } from "@event-driven-io/emmett";
2
2
  import { EventStoreDBClient, ResolvedEvent, SubscribeToAllOptions, SubscribeToStreamOptions } from "@eventstore/db-client";
3
3
 
4
4
  //#region src/eventStore/consumers/eventStoreDBEventStoreConsumer.d.ts
@@ -62,9 +62,7 @@ type EventStoreDBSubscriptionOptions<MessageType extends Message = Message> = {
62
62
  resubscribeOptions?: AsyncRetryOptions;
63
63
  };
64
64
  };
65
- type EventStoreDBSubscriptionStartFrom = {
66
- lastCheckpoint: ProcessorCheckpoint;
67
- } | 'BEGINNING' | 'END';
65
+ type EventStoreDBSubscriptionStartFrom = CurrentMessageProcessorPosition;
68
66
  type EventStoreDBSubscriptionStartOptions = {
69
67
  startFrom: EventStoreDBSubscriptionStartFrom;
70
68
  started?: AsyncAwaiter<void>;
@@ -83,7 +81,6 @@ declare const eventStoreDBSubscription: <MessageType extends AnyMessage = AnyMes
83
81
  eachBatch,
84
82
  resilience
85
83
  }: EventStoreDBSubscriptionOptions<MessageType>) => EventStoreDBSubscription;
86
- declare const zipEventStoreDBEventStoreMessageBatchPullerStartFrom: (options: (EventStoreDBSubscriptionStartFrom | undefined)[]) => EventStoreDBSubscriptionStartFrom;
87
84
  //#endregion
88
- export { $all, DefaultEventStoreDBEventStoreProcessorBatchSize, DefaultEventStoreDBEventStoreProcessorPullingFrequencyInMs, EventStoreDBEventStore, EventStoreDBEventStoreConsumer, EventStoreDBEventStoreConsumerConfig, EventStoreDBEventStoreConsumerOptions, EventStoreDBEventStoreConsumerType, EventStoreDBEventStoreDefaultStreamVersion, EventStoreDBEventStoreMessagesBatchHandlerResult, EventStoreDBReadEvent, EventStoreDBReadEventMetadata, EventStoreDBResubscribeDefaultOptions, EventStoreDBSubscription, EventStoreDBSubscriptionOptions, EventStoreDBSubscriptionStartFrom, EventStoreDBSubscriptionStartOptions, eventStoreDBEventStoreConsumer, eventStoreDBSubscription, getEventStoreDBEventStore, isDatabaseUnavailableError, mapFromESDBEvent, zipEventStoreDBEventStoreMessageBatchPullerStartFrom };
85
+ export { $all, DefaultEventStoreDBEventStoreProcessorBatchSize, DefaultEventStoreDBEventStoreProcessorPullingFrequencyInMs, EventStoreDBEventStore, EventStoreDBEventStoreConsumer, EventStoreDBEventStoreConsumerConfig, EventStoreDBEventStoreConsumerOptions, EventStoreDBEventStoreConsumerType, EventStoreDBEventStoreDefaultStreamVersion, EventStoreDBEventStoreMessagesBatchHandlerResult, EventStoreDBReadEvent, EventStoreDBReadEventMetadata, EventStoreDBResubscribeDefaultOptions, EventStoreDBSubscription, EventStoreDBSubscriptionOptions, EventStoreDBSubscriptionStartFrom, EventStoreDBSubscriptionStartOptions, eventStoreDBEventStoreConsumer, eventStoreDBSubscription, getEventStoreDBEventStore, isDatabaseUnavailableError, mapFromESDBEvent };
89
86
  //# sourceMappingURL=index.d.cts.map
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AnyEvent, AnyMessage, AppendToStreamOptions, AppendToStreamResultWithGlobalPosition, AsyncAwaiter, AsyncRetryOptions, BatchRecordedMessageHandlerWithoutContext, EmmettError, Event, EventStore, InMemoryProcessor, InMemoryProjectorOptions, InMemoryReactorOptions, Message, MessageConsumer, MessageConsumerOptions, ProcessorCheckpoint, ReadEvent, ReadEventMetadataWithGlobalPosition, RecordedMessage } from "@event-driven-io/emmett";
1
+ import { AnyEvent, AnyMessage, AppendToStreamOptions, AppendToStreamResultWithGlobalPosition, AsyncAwaiter, AsyncRetryOptions, BatchRecordedMessageHandlerWithoutContext, CurrentMessageProcessorPosition, EmmettError, Event, EventStore, InMemoryProcessor, InMemoryProjectorOptions, InMemoryReactorOptions, Message, MessageConsumer, MessageConsumerOptions, ReadEvent, ReadEventMetadataWithGlobalPosition, RecordedMessage } from "@event-driven-io/emmett";
2
2
  import { EventStoreDBClient, ResolvedEvent, SubscribeToAllOptions, SubscribeToStreamOptions } from "@eventstore/db-client";
3
3
 
4
4
  //#region src/eventStore/consumers/eventStoreDBEventStoreConsumer.d.ts
@@ -62,9 +62,7 @@ type EventStoreDBSubscriptionOptions<MessageType extends Message = Message> = {
62
62
  resubscribeOptions?: AsyncRetryOptions;
63
63
  };
64
64
  };
65
- type EventStoreDBSubscriptionStartFrom = {
66
- lastCheckpoint: ProcessorCheckpoint;
67
- } | 'BEGINNING' | 'END';
65
+ type EventStoreDBSubscriptionStartFrom = CurrentMessageProcessorPosition;
68
66
  type EventStoreDBSubscriptionStartOptions = {
69
67
  startFrom: EventStoreDBSubscriptionStartFrom;
70
68
  started?: AsyncAwaiter<void>;
@@ -83,7 +81,6 @@ declare const eventStoreDBSubscription: <MessageType extends AnyMessage = AnyMes
83
81
  eachBatch,
84
82
  resilience
85
83
  }: EventStoreDBSubscriptionOptions<MessageType>) => EventStoreDBSubscription;
86
- declare const zipEventStoreDBEventStoreMessageBatchPullerStartFrom: (options: (EventStoreDBSubscriptionStartFrom | undefined)[]) => EventStoreDBSubscriptionStartFrom;
87
84
  //#endregion
88
- export { $all, DefaultEventStoreDBEventStoreProcessorBatchSize, DefaultEventStoreDBEventStoreProcessorPullingFrequencyInMs, EventStoreDBEventStore, EventStoreDBEventStoreConsumer, EventStoreDBEventStoreConsumerConfig, EventStoreDBEventStoreConsumerOptions, EventStoreDBEventStoreConsumerType, EventStoreDBEventStoreDefaultStreamVersion, EventStoreDBEventStoreMessagesBatchHandlerResult, EventStoreDBReadEvent, EventStoreDBReadEventMetadata, EventStoreDBResubscribeDefaultOptions, EventStoreDBSubscription, EventStoreDBSubscriptionOptions, EventStoreDBSubscriptionStartFrom, EventStoreDBSubscriptionStartOptions, eventStoreDBEventStoreConsumer, eventStoreDBSubscription, getEventStoreDBEventStore, isDatabaseUnavailableError, mapFromESDBEvent, zipEventStoreDBEventStoreMessageBatchPullerStartFrom };
85
+ export { $all, DefaultEventStoreDBEventStoreProcessorBatchSize, DefaultEventStoreDBEventStoreProcessorPullingFrequencyInMs, EventStoreDBEventStore, EventStoreDBEventStoreConsumer, EventStoreDBEventStoreConsumerConfig, EventStoreDBEventStoreConsumerOptions, EventStoreDBEventStoreConsumerType, EventStoreDBEventStoreDefaultStreamVersion, EventStoreDBEventStoreMessagesBatchHandlerResult, EventStoreDBReadEvent, EventStoreDBReadEventMetadata, EventStoreDBResubscribeDefaultOptions, EventStoreDBSubscription, EventStoreDBSubscriptionOptions, EventStoreDBSubscriptionStartFrom, EventStoreDBSubscriptionStartOptions, eventStoreDBEventStoreConsumer, eventStoreDBSubscription, getEventStoreDBEventStore, isDatabaseUnavailableError, mapFromESDBEvent };
89
86
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { EmmettError, ExpectedVersionConflictError, JSONSerializer, NO_CONCURRENCY_CHECK, STREAM_DOES_NOT_EXIST, STREAM_EXISTS, assertExpectedVersionMatchesCurrent, asyncAwaiter, asyncRetry, bigIntProcessorCheckpoint, downcastRecordedMessages, getCheckpoint, inMemoryProjector, inMemoryReactor, isString, parseBigIntProcessorCheckpoint, upcastRecordedMessage } from "@event-driven-io/emmett";
1
+ import { CurrentMessageProcessorPosition, EmmettError, ExpectedVersionConflictError, JSONSerializer, NO_CONCURRENCY_CHECK, STREAM_DOES_NOT_EXIST, STREAM_EXISTS, assertExpectedVersionMatchesCurrent, asyncAwaiter, asyncRetry, bigIntProcessorCheckpoint, downcastRecordedMessages, getCheckpoint, inMemoryProjector, inMemoryReactor, isString, mergeObservabilityOptions, parseBigIntProcessorCheckpoint, upcastRecordedMessage } from "@event-driven-io/emmett";
2
2
  import { ANY, END, EventStoreDBClient, NO_STREAM, START, STREAM_EXISTS as STREAM_EXISTS$1, StreamNotFoundError, WrongExpectedVersionError, excludeSystemEvents, jsonEvent } from "@eventstore/db-client";
3
3
  import { v7 } from "uuid";
4
4
  import { Transform, Writable, pipeline } from "stream";
@@ -280,11 +280,6 @@ const eventStoreDBSubscription = ({ client, from, batchSize, eachBatch, resilien
280
280
  }
281
281
  };
282
282
  };
283
- const zipEventStoreDBEventStoreMessageBatchPullerStartFrom = (options) => {
284
- if (options.length === 0 || options.some((o) => o === void 0 || o === "BEGINNING")) return "BEGINNING";
285
- if (options.every((o) => o === "END")) return "END";
286
- return options.filter((o) => o !== void 0 && o !== "BEGINNING" && o !== "END").sort((a, b) => a > b ? 1 : -1)[0];
287
- };
288
283
 
289
284
  //#endregion
290
285
  //#region src/eventStore/consumers/eventStoreDBEventStoreConsumer.ts
@@ -346,13 +341,13 @@ const eventStoreDBEventStoreConsumer = (options) => {
346
341
  },
347
342
  whenStarted: () => startedAwaiter.wait,
348
343
  processors,
349
- reactor: (options) => {
350
- const processor = inMemoryReactor(options);
344
+ reactor: (processorOptions) => {
345
+ const processor = inMemoryReactor(mergeObservabilityOptions(processorOptions, options.observability));
351
346
  processors.push(processor);
352
347
  return processor;
353
348
  },
354
- projector: (options) => {
355
- const processor = inMemoryProjector(options);
349
+ projector: (processorOptions) => {
350
+ const processor = inMemoryProjector(mergeObservabilityOptions(processorOptions, options.observability));
356
351
  processors.push(processor);
357
352
  return processor;
358
353
  },
@@ -370,7 +365,7 @@ const eventStoreDBEventStoreConsumer = (options) => {
370
365
  if (!isRunning) return;
371
366
  try {
372
367
  if (!isInitialized) await init();
373
- const startFrom = zipEventStoreDBEventStoreMessageBatchPullerStartFrom(await Promise.all(processors.map((o) => o.start(client))));
368
+ const startFrom = CurrentMessageProcessorPosition.zip(await Promise.all(processors.map((o) => o.start(client))));
374
369
  await subscription.start({
375
370
  startFrom,
376
371
  started: startedAwaiter
@@ -391,5 +386,5 @@ const eventStoreDBEventStoreConsumer = (options) => {
391
386
  };
392
387
 
393
388
  //#endregion
394
- export { $all, DefaultEventStoreDBEventStoreProcessorBatchSize, DefaultEventStoreDBEventStoreProcessorPullingFrequencyInMs, EventStoreDBEventStoreDefaultStreamVersion, EventStoreDBResubscribeDefaultOptions, eventStoreDBEventStoreConsumer, eventStoreDBSubscription, getEventStoreDBEventStore, isDatabaseUnavailableError, mapFromESDBEvent, zipEventStoreDBEventStoreMessageBatchPullerStartFrom };
389
+ export { $all, DefaultEventStoreDBEventStoreProcessorBatchSize, DefaultEventStoreDBEventStoreProcessorPullingFrequencyInMs, EventStoreDBEventStoreDefaultStreamVersion, EventStoreDBResubscribeDefaultOptions, eventStoreDBEventStoreConsumer, eventStoreDBSubscription, getEventStoreDBEventStore, isDatabaseUnavailableError, mapFromESDBEvent };
395
390
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["ESDB_STREAM_EXISTS","uuid"],"sources":["../src/eventStore/eventstoreDBEventStore.ts","../src/eventStore/consumers/subscriptions/index.ts","../src/eventStore/consumers/eventStoreDBEventStoreConsumer.ts"],"sourcesContent":["import {\n ExpectedVersionConflictError,\n NO_CONCURRENCY_CHECK,\n STREAM_DOES_NOT_EXIST,\n STREAM_EXISTS,\n assertExpectedVersionMatchesCurrent,\n bigIntProcessorCheckpoint,\n downcastRecordedMessages,\n upcastRecordedMessage,\n type AggregateStreamOptions,\n type AggregateStreamResultWithGlobalPosition,\n type AnyMessage,\n type AppendToStreamOptions,\n type AppendToStreamResultWithGlobalPosition,\n type Event,\n type EventStore,\n type ExpectedStreamVersion,\n type ReadEvent,\n type ReadEventMetadataWithGlobalPosition,\n type ReadStreamOptions,\n type ReadStreamResult,\n type RecordedMessage,\n type StreamExistsResult,\n} from '@event-driven-io/emmett';\nimport type { EventStoreDBClient } from '@eventstore/db-client';\nimport {\n ANY,\n STREAM_EXISTS as ESDB_STREAM_EXISTS,\n NO_STREAM,\n StreamNotFoundError,\n WrongExpectedVersionError,\n jsonEvent,\n type AppendExpectedRevision,\n type ReadStreamOptions as ESDBReadStreamOptions,\n type ResolvedEvent,\n} from '@eventstore/db-client';\nimport {\n $all,\n eventStoreDBEventStoreConsumer,\n type EventStoreDBEventStoreConsumer,\n type EventStoreDBEventStoreConsumerConfig,\n type EventStoreDBEventStoreConsumerType,\n} from './consumers';\n\nconst toEventStoreDBReadOptions = <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n>(\n options: ReadStreamOptions<EventType, EventPayloadType> | undefined,\n): ESDBReadStreamOptions | undefined => {\n return options\n ? {\n fromRevision: 'from' in options ? options.from : undefined,\n maxCount:\n 'maxCount' in options\n ? options.maxCount\n : 'to' in options\n ? options.to\n : undefined,\n }\n : undefined;\n};\n\nexport const EventStoreDBEventStoreDefaultStreamVersion = -1n;\n\nexport type EventStoreDBReadEventMetadata = ReadEventMetadataWithGlobalPosition;\n\nexport type EventStoreDBReadEvent<EventType extends Event = Event> = ReadEvent<\n EventType,\n EventStoreDBReadEventMetadata\n>;\n\nexport interface EventStoreDBEventStore extends EventStore<EventStoreDBReadEventMetadata> {\n appendToStream<\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n events: EventType[],\n options?: AppendToStreamOptions<EventType, EventPayloadType>,\n ): Promise<AppendToStreamResultWithGlobalPosition>;\n consumer<ConsumerEventType extends Event = Event>(\n options?: EventStoreDBEventStoreConsumerConfig<ConsumerEventType>,\n ): EventStoreDBEventStoreConsumer<ConsumerEventType>;\n}\n\nexport const getEventStoreDBEventStore = (\n eventStore: EventStoreDBClient,\n): EventStoreDBEventStore => {\n return {\n async aggregateStream<\n State,\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n options: AggregateStreamOptions<\n State,\n EventType,\n EventStoreDBReadEventMetadata,\n EventPayloadType\n >,\n ): Promise<AggregateStreamResultWithGlobalPosition<State>> {\n const { evolve, initialState, read } = options;\n\n const expectedStreamVersion = read?.expectedStreamVersion;\n\n let state = initialState();\n let currentStreamVersion: bigint =\n EventStoreDBEventStoreDefaultStreamVersion;\n let lastCheckpoint: bigint | undefined = undefined;\n\n try {\n for await (const resolvedEvent of eventStore.readStream<EventPayloadType>(\n streamName,\n toEventStoreDBReadOptions(options.read),\n )) {\n const { event } = resolvedEvent;\n if (!event) continue;\n\n state = evolve(\n state,\n upcastRecordedMessage(\n mapFromESDBEvent<EventPayloadType>(resolvedEvent),\n options?.read?.schema?.versioning,\n ),\n );\n currentStreamVersion = event.revision;\n lastCheckpoint = event.position?.commit;\n }\n\n assertExpectedVersionMatchesCurrent(\n currentStreamVersion,\n expectedStreamVersion,\n EventStoreDBEventStoreDefaultStreamVersion,\n );\n\n return lastCheckpoint\n ? {\n currentStreamVersion,\n lastEventGlobalPosition:\n bigIntProcessorCheckpoint(lastCheckpoint),\n state,\n streamExists: true,\n }\n : {\n currentStreamVersion,\n state,\n streamExists: false,\n };\n } catch (error) {\n if (error instanceof StreamNotFoundError) {\n return {\n currentStreamVersion,\n state,\n streamExists: false,\n };\n }\n\n throw error;\n }\n },\n\n readStream: async <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n options?: ReadStreamOptions<EventType, EventPayloadType>,\n ): Promise<ReadStreamResult<EventType, EventStoreDBReadEventMetadata>> => {\n const events: ReadEvent<EventType, EventStoreDBReadEventMetadata>[] = [];\n\n let currentStreamVersion: bigint =\n EventStoreDBEventStoreDefaultStreamVersion;\n\n try {\n for await (const resolvedEvent of eventStore.readStream<EventPayloadType>(\n streamName,\n toEventStoreDBReadOptions(options),\n )) {\n const { event } = resolvedEvent;\n if (!event) continue;\n events.push(\n upcastRecordedMessage(\n mapFromESDBEvent<EventPayloadType>(resolvedEvent),\n options?.schema?.versioning,\n ),\n );\n\n currentStreamVersion = event.revision;\n }\n return {\n currentStreamVersion,\n events,\n streamExists: true,\n };\n } catch (error) {\n if (error instanceof StreamNotFoundError) {\n return {\n currentStreamVersion,\n events: [],\n streamExists: false,\n };\n }\n\n throw error;\n }\n },\n\n appendToStream: async <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n events: EventType[],\n options?: AppendToStreamOptions<EventType, EventPayloadType>,\n ): Promise<AppendToStreamResultWithGlobalPosition> => {\n try {\n const eventsToStore = downcastRecordedMessages(\n events,\n options?.schema?.versioning,\n );\n const serializedEvents = eventsToStore.map(jsonEvent);\n\n const expectedRevision = toExpectedRevision(\n options?.expectedStreamVersion,\n );\n\n const appendResult = await eventStore.appendToStream(\n streamName,\n serializedEvents,\n {\n expectedRevision,\n },\n );\n\n return {\n nextExpectedStreamVersion: appendResult.nextExpectedRevision,\n lastEventGlobalPosition: bigIntProcessorCheckpoint(\n appendResult.position!.commit,\n ),\n createdNewStream:\n appendResult.nextExpectedRevision >=\n BigInt(serializedEvents.length),\n };\n } catch (error) {\n if (error instanceof WrongExpectedVersionError) {\n throw new ExpectedVersionConflictError(\n BigInt(error.actualVersion),\n toExpectedVersion(error.expectedVersion),\n );\n }\n\n throw error;\n }\n },\n\n consumer: <ConsumerEventType extends Event = Event>(\n options?: EventStoreDBEventStoreConsumerConfig<ConsumerEventType>,\n ): EventStoreDBEventStoreConsumer<ConsumerEventType> =>\n eventStoreDBEventStoreConsumer<ConsumerEventType>({\n ...(options ?? {}),\n client: eventStore,\n }),\n\n streamExists: async (streamName: string): Promise<StreamExistsResult> => {\n try {\n for await (const resolvedEvent of eventStore.readStream(streamName)) {\n const { event } = resolvedEvent;\n\n if (!event) continue;\n\n return true;\n }\n\n return false;\n } catch (error) {\n if (error instanceof StreamNotFoundError) {\n return false;\n }\n\n throw error;\n }\n },\n\n //streamEvents: streamEvents(eventStore),\n };\n};\n\nconst getESDBCheckpoint = <MessageType extends AnyMessage = AnyMessage>(\n resolvedEvent: ResolvedEvent<MessageType>,\n from?: EventStoreDBEventStoreConsumerType,\n): bigint => {\n return !from || from?.stream === $all\n ? (resolvedEvent.link?.position?.commit ??\n resolvedEvent.event?.position?.commit)!\n : (resolvedEvent.link?.revision ?? resolvedEvent.event!.revision);\n};\n\nexport const mapFromESDBEvent = <MessageType extends AnyMessage = AnyMessage>(\n resolvedEvent: ResolvedEvent<MessageType>,\n from?: EventStoreDBEventStoreConsumerType,\n): RecordedMessage<MessageType, EventStoreDBReadEventMetadata> => {\n const event = resolvedEvent.event!;\n return <RecordedMessage<MessageType, EventStoreDBReadEventMetadata>>{\n type: event.type,\n data: event.data,\n metadata: {\n ...((event.metadata as EventStoreDBReadEventMetadata) ??\n ({} as EventStoreDBReadEventMetadata)),\n eventId: event.id,\n streamName: event.streamId,\n streamPosition: event.revision,\n globalPosition: bigIntProcessorCheckpoint(event.position!.commit),\n checkpoint: bigIntProcessorCheckpoint(\n getESDBCheckpoint(resolvedEvent, from),\n ),\n },\n };\n};\n\nconst toExpectedRevision = (\n expected: ExpectedStreamVersion | undefined,\n): AppendExpectedRevision => {\n if (expected === undefined) return ANY;\n\n if (expected === NO_CONCURRENCY_CHECK) return ANY;\n\n if (expected == STREAM_DOES_NOT_EXIST) return NO_STREAM;\n\n if (expected == STREAM_EXISTS) return ESDB_STREAM_EXISTS;\n\n return expected as bigint;\n};\n\nconst toExpectedVersion = (\n expected: AppendExpectedRevision | undefined,\n): ExpectedStreamVersion => {\n if (expected === undefined) return NO_CONCURRENCY_CHECK;\n\n if (expected === ANY) return NO_CONCURRENCY_CHECK;\n\n if (expected == NO_STREAM) return STREAM_DOES_NOT_EXIST;\n\n if (expected == ESDB_STREAM_EXISTS) return STREAM_EXISTS;\n\n return expected;\n};\n\n// const { map } = streamTransformations;\n//\n// // eslint-disable-next-line @typescript-eslint/no-unused-vars\n// const convertToWebReadableStream = (\n// allStreamSubscription: AllStreamSubscription,\n// ): ReadableStream<AllStreamResolvedEvent | GlobalStreamCaughtUp> => {\n// // Validate the input type\n// if (!(allStreamSubscription instanceof Readable)) {\n// throw new Error('Provided stream is not a Node.js Readable stream.');\n// }\n\n// let globalPosition = 0n;\n\n// const stream = Readable.toWeb(\n// allStreamSubscription,\n// ) as ReadableStream<AllStreamResolvedEvent>;\n\n// const writable = new WritableStream<\n// AllStreamResolvedEvent | GlobalStreamCaughtUp\n// >();\n\n// allStreamSubscription.on('caughtUp', async () => {\n// console.log(globalPosition);\n// await writable.getWriter().write(globalStreamCaughtUp({ globalPosition }));\n// });\n\n// const transform = map<\n// AllStreamResolvedEvent,\n// AllStreamResolvedEvent | GlobalStreamCaughtUp\n// >((event) => {\n// if (event?.event?.position.commit)\n// globalPosition = event.event?.position.commit;\n\n// return event;\n// });\n\n// return stream.pipeThrough<AllStreamResolvedEvent | GlobalStreamCaughtUp>(\n// transform,\n// );\n// };\n\n// const streamEvents = (eventStore: EventStoreDBClient) => () => {\n// return restream<\n// AllStreamResolvedEvent | GlobalSubscriptionEvent,\n// | ReadEvent<Event, EventStoreDBReadEventMetadata>\n// | GlobalSubscriptionEvent\n// >(\n// (): ReadableStream<AllStreamResolvedEvent | GlobalSubscriptionEvent> =>\n// convertToWebReadableStream(\n// eventStore.subscribeToAll({\n// fromPosition: START,\n// filter: excludeSystemEvents(),\n// }),\n// ),\n// (\n// resolvedEvent: AllStreamResolvedEvent | GlobalSubscriptionEvent,\n// ): ReadEvent<Event, EventStoreDBReadEventMetadata> =>\n// mapFromESDBEvent(resolvedEvent.event as JSONRecordedEvent<Event>),\n// );\n// };\n","import {\n asyncRetry,\n getCheckpoint,\n isString,\n JSONSerializer,\n parseBigIntProcessorCheckpoint,\n type AnyMessage,\n type AsyncAwaiter,\n type AsyncRetryOptions,\n type BatchRecordedMessageHandlerWithoutContext,\n type EmmettError,\n type Message,\n type ProcessorCheckpoint,\n type SingleMessageHandlerResult,\n} from '@event-driven-io/emmett';\nimport type { EventStoreDBClient } from '@eventstore/db-client';\nimport {\n END,\n excludeSystemEvents,\n START,\n type ResolvedEvent,\n type StreamSubscription,\n} from '@eventstore/db-client';\nimport { pipeline, Transform, Writable, type WritableOptions } from 'stream';\nimport {\n mapFromESDBEvent,\n type EventStoreDBReadEventMetadata,\n} from '../../eventstoreDBEventStore';\nimport {\n $all,\n type EventStoreDBEventStoreConsumerType,\n} from '../eventStoreDBEventStoreConsumer';\n\nexport const DefaultEventStoreDBEventStoreProcessorBatchSize = 100;\nexport const DefaultEventStoreDBEventStoreProcessorPullingFrequencyInMs = 50;\n\nexport type EventStoreDBEventStoreMessagesBatchHandlerResult = void | {\n type: 'STOP';\n reason?: string;\n error?: EmmettError;\n};\n\nexport type EventStoreDBSubscriptionOptions<\n MessageType extends Message = Message,\n> = {\n from?: EventStoreDBEventStoreConsumerType;\n client: EventStoreDBClient;\n batchSize: number;\n eachBatch: BatchRecordedMessageHandlerWithoutContext<\n MessageType,\n EventStoreDBReadEventMetadata\n >;\n resilience?: {\n resubscribeOptions?: AsyncRetryOptions;\n };\n};\n\nexport type EventStoreDBSubscriptionStartFrom =\n { lastCheckpoint: ProcessorCheckpoint } | 'BEGINNING' | 'END';\n\nexport type EventStoreDBSubscriptionStartOptions = {\n startFrom: EventStoreDBSubscriptionStartFrom;\n started?: AsyncAwaiter<void>;\n};\n\nexport type EventStoreDBSubscription = {\n isRunning: boolean;\n start(options: EventStoreDBSubscriptionStartOptions): Promise<void>;\n stop(): Promise<void>;\n};\n\nconst toGlobalPosition = (startFrom: EventStoreDBSubscriptionStartFrom) =>\n startFrom === 'BEGINNING'\n ? START\n : startFrom === 'END'\n ? END\n : {\n prepare: parseBigIntProcessorCheckpoint(startFrom.lastCheckpoint),\n commit: parseBigIntProcessorCheckpoint(startFrom.lastCheckpoint),\n };\n\nconst toStreamPosition = (startFrom: EventStoreDBSubscriptionStartFrom) =>\n startFrom === 'BEGINNING'\n ? START\n : startFrom === 'END'\n ? END\n : parseBigIntProcessorCheckpoint(startFrom.lastCheckpoint);\n\nconst subscribe = (\n client: EventStoreDBClient,\n from: EventStoreDBEventStoreConsumerType | undefined,\n options: EventStoreDBSubscriptionStartOptions,\n) =>\n from == undefined || from.stream == $all\n ? client.subscribeToAll({\n ...(from?.options ?? {}),\n fromPosition: toGlobalPosition(options.startFrom),\n filter: excludeSystemEvents(),\n })\n : client.subscribeToStream(from.stream, {\n ...(from.options ?? {}),\n fromRevision: toStreamPosition(options.startFrom),\n });\n\nexport const isDatabaseUnavailableError = (error: unknown) =>\n error instanceof Error &&\n 'type' in error &&\n error.type === 'unavailable' &&\n 'code' in error &&\n error.code === 14;\n\nexport const EventStoreDBResubscribeDefaultOptions: AsyncRetryOptions = {\n forever: true,\n minTimeout: 100,\n factor: 1.5,\n shouldRetryError: (error) => !isDatabaseUnavailableError(error),\n};\n\ntype SubscriptionSequentialHandlerOptions<\n MessageType extends AnyMessage = AnyMessage,\n> = EventStoreDBSubscriptionOptions<MessageType> & WritableOptions;\n\nclass SubscriptionSequentialHandler<\n MessageType extends AnyMessage = AnyMessage,\n> extends Transform {\n private options: SubscriptionSequentialHandlerOptions<MessageType>;\n private from: EventStoreDBEventStoreConsumerType | undefined;\n public isRunning: boolean;\n\n constructor(options: SubscriptionSequentialHandlerOptions<MessageType>) {\n super({ objectMode: true, ...options });\n this.options = options;\n this.from = options.from;\n this.isRunning = true;\n }\n\n async _transform(\n resolvedEvent: ResolvedEvent<MessageType>,\n _encoding: BufferEncoding,\n callback: (error?: Error | null) => void,\n ): Promise<void> {\n try {\n if (!this.isRunning || !resolvedEvent.event) {\n callback();\n return;\n }\n\n const message = mapFromESDBEvent(resolvedEvent, this.from);\n const messageCheckpoint = getCheckpoint(message);\n\n const result = await this.options.eachBatch([message]);\n\n if (result && result.type === 'STOP') {\n this.isRunning = false;\n if (!result.error) this.push(messageCheckpoint);\n\n this.push(result);\n this.push(null);\n callback();\n return;\n }\n\n this.push(messageCheckpoint);\n callback();\n } catch (error) {\n callback(error as Error);\n }\n }\n}\n\nexport const eventStoreDBSubscription = <\n MessageType extends AnyMessage = AnyMessage,\n>({\n client,\n from,\n batchSize,\n eachBatch,\n resilience,\n}: EventStoreDBSubscriptionOptions<MessageType>): EventStoreDBSubscription => {\n let isRunning = false;\n\n let start: Promise<void>;\n let processor: SubscriptionSequentialHandler<MessageType>;\n\n let subscription: StreamSubscription<MessageType>;\n\n const resubscribeOptions: AsyncRetryOptions =\n resilience?.resubscribeOptions ?? {\n ...EventStoreDBResubscribeDefaultOptions,\n shouldRetryResult: () => isRunning,\n shouldRetryError: (error) =>\n isRunning &&\n EventStoreDBResubscribeDefaultOptions.shouldRetryError!(error),\n };\n\n const stopSubscription = (callback?: () => void): Promise<void> => {\n isRunning = false;\n if (processor) processor.isRunning = false;\n return subscription\n .unsubscribe()\n .then(() => {\n subscription.destroy();\n })\n .catch((err) => console.error('Error during unsubscribe.%s', err))\n .finally(callback ?? (() => {}));\n };\n\n const pipeMessages = (options: EventStoreDBSubscriptionStartOptions) => {\n let retry = 0;\n return asyncRetry(\n () =>\n new Promise<void>((resolve, reject) => {\n if (!isRunning) {\n resolve();\n return;\n }\n console.info(\n `Starting subscription. ${retry++} retries. From: ${JSONSerializer.serialize(from ?? '$all')}, Start from: ${JSONSerializer.serialize(\n options.startFrom,\n )}`,\n );\n subscription = subscribe(client, from, options);\n subscription.once('confirmation', () => options.started?.resolve());\n\n processor = new SubscriptionSequentialHandler({\n client,\n from,\n batchSize,\n eachBatch,\n resilience,\n });\n\n const handler = new (class extends Writable {\n async _write(\n result: ProcessorCheckpoint | SingleMessageHandlerResult,\n _encoding: string,\n done: () => void,\n ) {\n if (!isRunning) return;\n\n if (isString(result)) {\n options.startFrom = {\n lastCheckpoint: result,\n };\n done();\n return;\n }\n\n if (result && result.type === 'STOP' && result.error) {\n console.error(\n `Subscription stopped with error code: ${result.error.errorCode}, message: ${\n result.error.message\n }.`,\n );\n }\n\n await stopSubscription();\n done();\n }\n })({ objectMode: true });\n\n pipeline(\n subscription,\n processor,\n handler,\n async (error: Error | null) => {\n console.info(`Stopping subscription.`);\n await stopSubscription(() => {\n if (!error) {\n console.info('Subscription ended successfully.');\n resolve();\n return;\n }\n console.error(\n `Received error: ${JSONSerializer.serialize(error)}.`,\n );\n options.started?.reject(error);\n reject(error);\n });\n },\n );\n }),\n resubscribeOptions,\n );\n };\n\n return {\n get isRunning() {\n return isRunning;\n },\n start: (options) => {\n if (isRunning) return start;\n\n start = (async () => {\n isRunning = true;\n\n return pipeMessages(options);\n })();\n\n return start;\n },\n stop: async () => {\n if (!isRunning) return start ? await start : Promise.resolve();\n await stopSubscription();\n await start;\n },\n };\n};\n\nexport const zipEventStoreDBEventStoreMessageBatchPullerStartFrom = (\n options: (EventStoreDBSubscriptionStartFrom | undefined)[],\n): EventStoreDBSubscriptionStartFrom => {\n if (\n options.length === 0 ||\n options.some((o) => o === undefined || o === 'BEGINNING')\n )\n return 'BEGINNING';\n\n if (options.every((o) => o === 'END')) return 'END';\n\n return options\n .filter((o) => o !== undefined && o !== 'BEGINNING' && o !== 'END')\n .sort((a, b) => (a > b ? 1 : -1))[0]!;\n};\n","import type {\n AsyncAwaiter,\n MessageHandlerContext,\n MessageProcessor,\n} from '@event-driven-io/emmett';\nimport {\n asyncAwaiter,\n EmmettError,\n inMemoryProjector,\n inMemoryReactor,\n type AnyEvent,\n type AnyMessage,\n type AnyRecordedMessageMetadata,\n type AsyncRetryOptions,\n type BatchRecordedMessageHandlerWithoutContext,\n type InMemoryProcessor,\n type InMemoryProjectorOptions,\n type InMemoryReactorOptions,\n type Message,\n type MessageConsumer,\n type MessageConsumerOptions,\n} from '@event-driven-io/emmett';\nimport {\n EventStoreDBClient,\n type SubscribeToAllOptions,\n type SubscribeToStreamOptions,\n} from '@eventstore/db-client';\nimport { v7 as uuid } from 'uuid';\nimport type { EventStoreDBReadEventMetadata } from '../eventstoreDBEventStore';\nimport {\n DefaultEventStoreDBEventStoreProcessorBatchSize,\n eventStoreDBSubscription,\n zipEventStoreDBEventStoreMessageBatchPullerStartFrom,\n type EventStoreDBSubscription,\n} from './subscriptions';\n\nexport type EventStoreDBEventStoreConsumerConfig<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ConsumerMessageType extends Message = any,\n> = MessageConsumerOptions<ConsumerMessageType> & {\n from?: EventStoreDBEventStoreConsumerType;\n pulling?: {\n batchSize?: number;\n };\n resilience?: {\n resubscribeOptions?: AsyncRetryOptions;\n };\n};\n\nexport type EventStoreDBEventStoreConsumerOptions<\n ConsumerEventType extends Message = Message,\n> = EventStoreDBEventStoreConsumerConfig<ConsumerEventType> &\n (\n | {\n connectionString: string;\n client?: never;\n }\n | { client: EventStoreDBClient; connectionString?: never }\n );\n\nexport type $all = '$all';\nexport const $all = '$all';\n\nexport type EventStoreDBEventStoreConsumerType =\n | {\n stream: $all;\n options?: Exclude<SubscribeToAllOptions, 'fromPosition'>;\n }\n | {\n stream: string;\n options?: Exclude<SubscribeToStreamOptions, 'fromRevision'>;\n };\n\nexport type EventStoreDBEventStoreConsumer<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ConsumerMessageType extends AnyMessage = any,\n> = MessageConsumer<ConsumerMessageType> &\n Readonly<{\n reactor: <MessageType extends AnyMessage = ConsumerMessageType>(\n options: InMemoryReactorOptions<MessageType>,\n ) => InMemoryProcessor<MessageType>;\n }> &\n (AnyEvent extends ConsumerMessageType\n ? Readonly<{\n projector: <\n EventType extends AnyEvent = ConsumerMessageType & AnyEvent,\n >(\n options: InMemoryProjectorOptions<EventType>,\n ) => InMemoryProcessor<EventType>;\n }>\n : object);\n\nexport const eventStoreDBEventStoreConsumer = <\n ConsumerMessageType extends Message = AnyMessage,\n>(\n options: EventStoreDBEventStoreConsumerOptions<ConsumerMessageType>,\n): EventStoreDBEventStoreConsumer<ConsumerMessageType> => {\n let isRunning = false;\n let isInitialized = false;\n const { pulling } = options;\n const processors = options.processors ?? [];\n let abortController: AbortController | null = null;\n\n let start: Promise<void>;\n\n let currentSubscription: EventStoreDBSubscription | undefined;\n\n const startedAwaiter: AsyncAwaiter<void> = asyncAwaiter<void>();\n\n const client =\n 'client' in options && options.client\n ? options.client\n : EventStoreDBClient.connectionString(options.connectionString);\n\n const eachBatch: BatchRecordedMessageHandlerWithoutContext<\n ConsumerMessageType,\n EventStoreDBReadEventMetadata\n > = async (messagesBatch) => {\n const activeProcessors = processors.filter((s) => s.isActive);\n\n if (activeProcessors.length === 0)\n return {\n type: 'STOP',\n reason: 'No active processors',\n };\n\n const result = await Promise.allSettled(\n activeProcessors.map(async (s) => {\n // TODO: Add here filtering to only pass messages that can be handled by\n return await s.handle(messagesBatch, { client });\n }),\n );\n\n const error = result.find((r) => r.status === 'rejected')?.reason as\n Error | undefined;\n\n return result.some(\n (r) => r.status === 'fulfilled' && r.value?.type !== 'STOP',\n )\n ? undefined\n : {\n type: 'STOP',\n error: error ? EmmettError.mapFrom(error) : undefined,\n };\n };\n\n const subscription = (currentSubscription = eventStoreDBSubscription({\n client,\n from: options.from,\n eachBatch,\n batchSize:\n pulling?.batchSize ?? DefaultEventStoreDBEventStoreProcessorBatchSize,\n resilience: options.resilience,\n }));\n\n const init = async (): Promise<void> => {\n if (isInitialized) return;\n for (const processor of processors) {\n await processor.init({});\n }\n isInitialized = true;\n };\n\n const stopProcessors = () => Promise.all(processors.map((p) => p.close({})));\n\n const stop = async () => {\n if (!isRunning) return;\n isRunning = false;\n abortController?.abort();\n if (currentSubscription) {\n await currentSubscription.stop();\n currentSubscription = undefined;\n }\n await start;\n abortController = null;\n await stopProcessors();\n };\n\n return {\n consumerId: options.consumerId ?? uuid(),\n get isRunning() {\n return isRunning;\n },\n whenStarted: (): Promise<void> => startedAwaiter.wait,\n processors,\n reactor: <MessageType extends AnyMessage = ConsumerMessageType>(\n options: InMemoryReactorOptions<MessageType>,\n ): InMemoryProcessor<MessageType> => {\n const processor = inMemoryReactor(options);\n\n processors.push(\n // TODO: change that\n processor as unknown as MessageProcessor<\n ConsumerMessageType,\n AnyRecordedMessageMetadata,\n MessageHandlerContext\n >,\n );\n\n return processor;\n },\n projector: <EventType extends AnyEvent = ConsumerMessageType & AnyEvent>(\n options: InMemoryProjectorOptions<EventType>,\n ): InMemoryProcessor<EventType> => {\n const processor = inMemoryProjector(options);\n\n processors.push(\n // TODO: change that\n processor as unknown as MessageProcessor<\n ConsumerMessageType,\n AnyRecordedMessageMetadata,\n MessageHandlerContext\n >,\n );\n\n return processor;\n },\n start: () => {\n if (isRunning) return start;\n\n startedAwaiter.reset();\n\n if (processors.length === 0) {\n const error = new EmmettError(\n 'Cannot start consumer without at least a single processor',\n );\n startedAwaiter.reject(error);\n return Promise.reject(error);\n }\n isRunning = true;\n abortController = new AbortController();\n\n start = (async () => {\n if (!isRunning) return;\n\n try {\n if (!isInitialized) {\n await init();\n }\n\n const startFrom =\n zipEventStoreDBEventStoreMessageBatchPullerStartFrom(\n await Promise.all(processors.map((o) => o.start(client))),\n );\n\n await subscription.start({ startFrom, started: startedAwaiter });\n } catch (error) {\n isRunning = false;\n startedAwaiter.reject(error);\n throw error;\n } finally {\n await stopProcessors();\n }\n })();\n\n return start;\n },\n stop,\n close: stop,\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["ESDB_STREAM_EXISTS","uuid"],"sources":["../src/eventStore/eventstoreDBEventStore.ts","../src/eventStore/consumers/subscriptions/index.ts","../src/eventStore/consumers/eventStoreDBEventStoreConsumer.ts"],"sourcesContent":["import {\n ExpectedVersionConflictError,\n NO_CONCURRENCY_CHECK,\n STREAM_DOES_NOT_EXIST,\n STREAM_EXISTS,\n assertExpectedVersionMatchesCurrent,\n bigIntProcessorCheckpoint,\n downcastRecordedMessages,\n upcastRecordedMessage,\n type AggregateStreamOptions,\n type AggregateStreamResultWithGlobalPosition,\n type AnyMessage,\n type AppendToStreamOptions,\n type AppendToStreamResultWithGlobalPosition,\n type Event,\n type EventStore,\n type ExpectedStreamVersion,\n type ReadEvent,\n type ReadEventMetadataWithGlobalPosition,\n type ReadStreamOptions,\n type ReadStreamResult,\n type RecordedMessage,\n type StreamExistsResult,\n} from '@event-driven-io/emmett';\nimport type { EventStoreDBClient } from '@eventstore/db-client';\nimport {\n ANY,\n STREAM_EXISTS as ESDB_STREAM_EXISTS,\n NO_STREAM,\n StreamNotFoundError,\n WrongExpectedVersionError,\n jsonEvent,\n type AppendExpectedRevision,\n type ReadStreamOptions as ESDBReadStreamOptions,\n type ResolvedEvent,\n} from '@eventstore/db-client';\nimport {\n $all,\n eventStoreDBEventStoreConsumer,\n type EventStoreDBEventStoreConsumer,\n type EventStoreDBEventStoreConsumerConfig,\n type EventStoreDBEventStoreConsumerType,\n} from './consumers';\n\nconst toEventStoreDBReadOptions = <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n>(\n options: ReadStreamOptions<EventType, EventPayloadType> | undefined,\n): ESDBReadStreamOptions | undefined => {\n return options\n ? {\n fromRevision: 'from' in options ? options.from : undefined,\n maxCount:\n 'maxCount' in options\n ? options.maxCount\n : 'to' in options\n ? options.to\n : undefined,\n }\n : undefined;\n};\n\nexport const EventStoreDBEventStoreDefaultStreamVersion = -1n;\n\nexport type EventStoreDBReadEventMetadata = ReadEventMetadataWithGlobalPosition;\n\nexport type EventStoreDBReadEvent<EventType extends Event = Event> = ReadEvent<\n EventType,\n EventStoreDBReadEventMetadata\n>;\n\nexport interface EventStoreDBEventStore extends EventStore<EventStoreDBReadEventMetadata> {\n appendToStream<\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n events: EventType[],\n options?: AppendToStreamOptions<EventType, EventPayloadType>,\n ): Promise<AppendToStreamResultWithGlobalPosition>;\n consumer<ConsumerEventType extends Event = Event>(\n options?: EventStoreDBEventStoreConsumerConfig<ConsumerEventType>,\n ): EventStoreDBEventStoreConsumer<ConsumerEventType>;\n}\n\nexport const getEventStoreDBEventStore = (\n eventStore: EventStoreDBClient,\n): EventStoreDBEventStore => {\n return {\n async aggregateStream<\n State,\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n options: AggregateStreamOptions<\n State,\n EventType,\n EventStoreDBReadEventMetadata,\n EventPayloadType\n >,\n ): Promise<AggregateStreamResultWithGlobalPosition<State>> {\n const { evolve, initialState, read } = options;\n\n const expectedStreamVersion = read?.expectedStreamVersion;\n\n let state = initialState();\n let currentStreamVersion: bigint =\n EventStoreDBEventStoreDefaultStreamVersion;\n let lastCheckpoint: bigint | undefined = undefined;\n\n try {\n for await (const resolvedEvent of eventStore.readStream<EventPayloadType>(\n streamName,\n toEventStoreDBReadOptions(options.read),\n )) {\n const { event } = resolvedEvent;\n if (!event) continue;\n\n state = evolve(\n state,\n upcastRecordedMessage(\n mapFromESDBEvent<EventPayloadType>(resolvedEvent),\n options?.read?.schema?.versioning,\n ),\n );\n currentStreamVersion = event.revision;\n lastCheckpoint = event.position?.commit;\n }\n\n assertExpectedVersionMatchesCurrent(\n currentStreamVersion,\n expectedStreamVersion,\n EventStoreDBEventStoreDefaultStreamVersion,\n );\n\n return lastCheckpoint\n ? {\n currentStreamVersion,\n lastEventGlobalPosition:\n bigIntProcessorCheckpoint(lastCheckpoint),\n state,\n streamExists: true,\n }\n : {\n currentStreamVersion,\n state,\n streamExists: false,\n };\n } catch (error) {\n if (error instanceof StreamNotFoundError) {\n return {\n currentStreamVersion,\n state,\n streamExists: false,\n };\n }\n\n throw error;\n }\n },\n\n readStream: async <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n options?: ReadStreamOptions<EventType, EventPayloadType>,\n ): Promise<ReadStreamResult<EventType, EventStoreDBReadEventMetadata>> => {\n const events: ReadEvent<EventType, EventStoreDBReadEventMetadata>[] = [];\n\n let currentStreamVersion: bigint =\n EventStoreDBEventStoreDefaultStreamVersion;\n\n try {\n for await (const resolvedEvent of eventStore.readStream<EventPayloadType>(\n streamName,\n toEventStoreDBReadOptions(options),\n )) {\n const { event } = resolvedEvent;\n if (!event) continue;\n events.push(\n upcastRecordedMessage(\n mapFromESDBEvent<EventPayloadType>(resolvedEvent),\n options?.schema?.versioning,\n ),\n );\n\n currentStreamVersion = event.revision;\n }\n return {\n currentStreamVersion,\n events,\n streamExists: true,\n };\n } catch (error) {\n if (error instanceof StreamNotFoundError) {\n return {\n currentStreamVersion,\n events: [],\n streamExists: false,\n };\n }\n\n throw error;\n }\n },\n\n appendToStream: async <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n events: EventType[],\n options?: AppendToStreamOptions<EventType, EventPayloadType>,\n ): Promise<AppendToStreamResultWithGlobalPosition> => {\n try {\n const eventsToStore = downcastRecordedMessages(\n events,\n options?.schema?.versioning,\n );\n const serializedEvents = eventsToStore.map(jsonEvent);\n\n const expectedRevision = toExpectedRevision(\n options?.expectedStreamVersion,\n );\n\n const appendResult = await eventStore.appendToStream(\n streamName,\n serializedEvents,\n {\n expectedRevision,\n },\n );\n\n return {\n nextExpectedStreamVersion: appendResult.nextExpectedRevision,\n lastEventGlobalPosition: bigIntProcessorCheckpoint(\n appendResult.position!.commit,\n ),\n createdNewStream:\n appendResult.nextExpectedRevision >=\n BigInt(serializedEvents.length),\n };\n } catch (error) {\n if (error instanceof WrongExpectedVersionError) {\n throw new ExpectedVersionConflictError(\n BigInt(error.actualVersion),\n toExpectedVersion(error.expectedVersion),\n );\n }\n\n throw error;\n }\n },\n\n consumer: <ConsumerEventType extends Event = Event>(\n options?: EventStoreDBEventStoreConsumerConfig<ConsumerEventType>,\n ): EventStoreDBEventStoreConsumer<ConsumerEventType> =>\n eventStoreDBEventStoreConsumer<ConsumerEventType>({\n ...(options ?? {}),\n client: eventStore,\n }),\n\n streamExists: async (streamName: string): Promise<StreamExistsResult> => {\n try {\n for await (const resolvedEvent of eventStore.readStream(streamName)) {\n const { event } = resolvedEvent;\n\n if (!event) continue;\n\n return true;\n }\n\n return false;\n } catch (error) {\n if (error instanceof StreamNotFoundError) {\n return false;\n }\n\n throw error;\n }\n },\n\n //streamEvents: streamEvents(eventStore),\n };\n};\n\nconst getESDBCheckpoint = <MessageType extends AnyMessage = AnyMessage>(\n resolvedEvent: ResolvedEvent<MessageType>,\n from?: EventStoreDBEventStoreConsumerType,\n): bigint => {\n return !from || from?.stream === $all\n ? (resolvedEvent.link?.position?.commit ??\n resolvedEvent.event?.position?.commit)!\n : (resolvedEvent.link?.revision ?? resolvedEvent.event!.revision);\n};\n\nexport const mapFromESDBEvent = <MessageType extends AnyMessage = AnyMessage>(\n resolvedEvent: ResolvedEvent<MessageType>,\n from?: EventStoreDBEventStoreConsumerType,\n): RecordedMessage<MessageType, EventStoreDBReadEventMetadata> => {\n const event = resolvedEvent.event!;\n return <RecordedMessage<MessageType, EventStoreDBReadEventMetadata>>{\n type: event.type,\n data: event.data,\n metadata: {\n ...((event.metadata as EventStoreDBReadEventMetadata) ??\n ({} as EventStoreDBReadEventMetadata)),\n eventId: event.id,\n streamName: event.streamId,\n streamPosition: event.revision,\n globalPosition: bigIntProcessorCheckpoint(event.position!.commit),\n checkpoint: bigIntProcessorCheckpoint(\n getESDBCheckpoint(resolvedEvent, from),\n ),\n },\n };\n};\n\nconst toExpectedRevision = (\n expected: ExpectedStreamVersion | undefined,\n): AppendExpectedRevision => {\n if (expected === undefined) return ANY;\n\n if (expected === NO_CONCURRENCY_CHECK) return ANY;\n\n if (expected == STREAM_DOES_NOT_EXIST) return NO_STREAM;\n\n if (expected == STREAM_EXISTS) return ESDB_STREAM_EXISTS;\n\n return expected as bigint;\n};\n\nconst toExpectedVersion = (\n expected: AppendExpectedRevision | undefined,\n): ExpectedStreamVersion => {\n if (expected === undefined) return NO_CONCURRENCY_CHECK;\n\n if (expected === ANY) return NO_CONCURRENCY_CHECK;\n\n if (expected == NO_STREAM) return STREAM_DOES_NOT_EXIST;\n\n if (expected == ESDB_STREAM_EXISTS) return STREAM_EXISTS;\n\n return expected;\n};\n\n// const { map } = streamTransformations;\n//\n// // eslint-disable-next-line @typescript-eslint/no-unused-vars\n// const convertToWebReadableStream = (\n// allStreamSubscription: AllStreamSubscription,\n// ): ReadableStream<AllStreamResolvedEvent | GlobalStreamCaughtUp> => {\n// // Validate the input type\n// if (!(allStreamSubscription instanceof Readable)) {\n// throw new Error('Provided stream is not a Node.js Readable stream.');\n// }\n\n// let globalPosition = 0n;\n\n// const stream = Readable.toWeb(\n// allStreamSubscription,\n// ) as ReadableStream<AllStreamResolvedEvent>;\n\n// const writable = new WritableStream<\n// AllStreamResolvedEvent | GlobalStreamCaughtUp\n// >();\n\n// allStreamSubscription.on('caughtUp', async () => {\n// console.log(globalPosition);\n// await writable.getWriter().write(globalStreamCaughtUp({ globalPosition }));\n// });\n\n// const transform = map<\n// AllStreamResolvedEvent,\n// AllStreamResolvedEvent | GlobalStreamCaughtUp\n// >((event) => {\n// if (event?.event?.position.commit)\n// globalPosition = event.event?.position.commit;\n\n// return event;\n// });\n\n// return stream.pipeThrough<AllStreamResolvedEvent | GlobalStreamCaughtUp>(\n// transform,\n// );\n// };\n\n// const streamEvents = (eventStore: EventStoreDBClient) => () => {\n// return restream<\n// AllStreamResolvedEvent | GlobalSubscriptionEvent,\n// | ReadEvent<Event, EventStoreDBReadEventMetadata>\n// | GlobalSubscriptionEvent\n// >(\n// (): ReadableStream<AllStreamResolvedEvent | GlobalSubscriptionEvent> =>\n// convertToWebReadableStream(\n// eventStore.subscribeToAll({\n// fromPosition: START,\n// filter: excludeSystemEvents(),\n// }),\n// ),\n// (\n// resolvedEvent: AllStreamResolvedEvent | GlobalSubscriptionEvent,\n// ): ReadEvent<Event, EventStoreDBReadEventMetadata> =>\n// mapFromESDBEvent(resolvedEvent.event as JSONRecordedEvent<Event>),\n// );\n// };\n","import type { CurrentMessageProcessorPosition } from '@event-driven-io/emmett';\nimport {\n asyncRetry,\n getCheckpoint,\n isString,\n JSONSerializer,\n parseBigIntProcessorCheckpoint,\n type AnyMessage,\n type AsyncAwaiter,\n type AsyncRetryOptions,\n type BatchRecordedMessageHandlerWithoutContext,\n type EmmettError,\n type Message,\n type ProcessorCheckpoint,\n type SingleMessageHandlerResult,\n} from '@event-driven-io/emmett';\nimport type { EventStoreDBClient } from '@eventstore/db-client';\nimport {\n END,\n excludeSystemEvents,\n START,\n type ResolvedEvent,\n type StreamSubscription,\n} from '@eventstore/db-client';\nimport { pipeline, Transform, Writable, type WritableOptions } from 'stream';\nimport {\n mapFromESDBEvent,\n type EventStoreDBReadEventMetadata,\n} from '../../eventstoreDBEventStore';\nimport {\n $all,\n type EventStoreDBEventStoreConsumerType,\n} from '../eventStoreDBEventStoreConsumer';\n\nexport const DefaultEventStoreDBEventStoreProcessorBatchSize = 100;\nexport const DefaultEventStoreDBEventStoreProcessorPullingFrequencyInMs = 50;\n\nexport type EventStoreDBEventStoreMessagesBatchHandlerResult = void | {\n type: 'STOP';\n reason?: string;\n error?: EmmettError;\n};\n\nexport type EventStoreDBSubscriptionOptions<\n MessageType extends Message = Message,\n> = {\n from?: EventStoreDBEventStoreConsumerType;\n client: EventStoreDBClient;\n batchSize: number;\n eachBatch: BatchRecordedMessageHandlerWithoutContext<\n MessageType,\n EventStoreDBReadEventMetadata\n >;\n resilience?: {\n resubscribeOptions?: AsyncRetryOptions;\n };\n};\n\nexport type EventStoreDBSubscriptionStartFrom = CurrentMessageProcessorPosition;\n\nexport type EventStoreDBSubscriptionStartOptions = {\n startFrom: EventStoreDBSubscriptionStartFrom;\n started?: AsyncAwaiter<void>;\n};\n\nexport type EventStoreDBSubscription = {\n isRunning: boolean;\n start(options: EventStoreDBSubscriptionStartOptions): Promise<void>;\n stop(): Promise<void>;\n};\n\nconst toGlobalPosition = (startFrom: EventStoreDBSubscriptionStartFrom) =>\n startFrom === 'BEGINNING'\n ? START\n : startFrom === 'END'\n ? END\n : {\n prepare: parseBigIntProcessorCheckpoint(startFrom.lastCheckpoint),\n commit: parseBigIntProcessorCheckpoint(startFrom.lastCheckpoint),\n };\n\nconst toStreamPosition = (startFrom: EventStoreDBSubscriptionStartFrom) =>\n startFrom === 'BEGINNING'\n ? START\n : startFrom === 'END'\n ? END\n : parseBigIntProcessorCheckpoint(startFrom.lastCheckpoint);\n\nconst subscribe = (\n client: EventStoreDBClient,\n from: EventStoreDBEventStoreConsumerType | undefined,\n options: EventStoreDBSubscriptionStartOptions,\n) =>\n from == undefined || from.stream == $all\n ? client.subscribeToAll({\n ...(from?.options ?? {}),\n fromPosition: toGlobalPosition(options.startFrom),\n filter: excludeSystemEvents(),\n })\n : client.subscribeToStream(from.stream, {\n ...(from.options ?? {}),\n fromRevision: toStreamPosition(options.startFrom),\n });\n\nexport const isDatabaseUnavailableError = (error: unknown) =>\n error instanceof Error &&\n 'type' in error &&\n error.type === 'unavailable' &&\n 'code' in error &&\n error.code === 14;\n\nexport const EventStoreDBResubscribeDefaultOptions: AsyncRetryOptions = {\n forever: true,\n minTimeout: 100,\n factor: 1.5,\n shouldRetryError: (error) => !isDatabaseUnavailableError(error),\n};\n\ntype SubscriptionSequentialHandlerOptions<\n MessageType extends AnyMessage = AnyMessage,\n> = EventStoreDBSubscriptionOptions<MessageType> & WritableOptions;\n\nclass SubscriptionSequentialHandler<\n MessageType extends AnyMessage = AnyMessage,\n> extends Transform {\n private options: SubscriptionSequentialHandlerOptions<MessageType>;\n private from: EventStoreDBEventStoreConsumerType | undefined;\n public isRunning: boolean;\n\n constructor(options: SubscriptionSequentialHandlerOptions<MessageType>) {\n super({ objectMode: true, ...options });\n this.options = options;\n this.from = options.from;\n this.isRunning = true;\n }\n\n async _transform(\n resolvedEvent: ResolvedEvent<MessageType>,\n _encoding: BufferEncoding,\n callback: (error?: Error | null) => void,\n ): Promise<void> {\n try {\n if (!this.isRunning || !resolvedEvent.event) {\n callback();\n return;\n }\n\n const message = mapFromESDBEvent(resolvedEvent, this.from);\n const messageCheckpoint = getCheckpoint(message);\n\n const result = await this.options.eachBatch([message]);\n\n if (result && result.type === 'STOP') {\n this.isRunning = false;\n if (!result.error) this.push(messageCheckpoint);\n\n this.push(result);\n this.push(null);\n callback();\n return;\n }\n\n this.push(messageCheckpoint);\n callback();\n } catch (error) {\n callback(error as Error);\n }\n }\n}\n\nexport const eventStoreDBSubscription = <\n MessageType extends AnyMessage = AnyMessage,\n>({\n client,\n from,\n batchSize,\n eachBatch,\n resilience,\n}: EventStoreDBSubscriptionOptions<MessageType>): EventStoreDBSubscription => {\n let isRunning = false;\n\n let start: Promise<void>;\n let processor: SubscriptionSequentialHandler<MessageType>;\n\n let subscription: StreamSubscription<MessageType>;\n\n const resubscribeOptions: AsyncRetryOptions =\n resilience?.resubscribeOptions ?? {\n ...EventStoreDBResubscribeDefaultOptions,\n shouldRetryResult: () => isRunning,\n shouldRetryError: (error) =>\n isRunning &&\n EventStoreDBResubscribeDefaultOptions.shouldRetryError!(error),\n };\n\n const stopSubscription = (callback?: () => void): Promise<void> => {\n isRunning = false;\n if (processor) processor.isRunning = false;\n return subscription\n .unsubscribe()\n .then(() => {\n subscription.destroy();\n })\n .catch((err) => console.error('Error during unsubscribe.%s', err))\n .finally(callback ?? (() => {}));\n };\n\n const pipeMessages = (options: EventStoreDBSubscriptionStartOptions) => {\n let retry = 0;\n return asyncRetry(\n () =>\n new Promise<void>((resolve, reject) => {\n if (!isRunning) {\n resolve();\n return;\n }\n console.info(\n `Starting subscription. ${retry++} retries. From: ${JSONSerializer.serialize(from ?? '$all')}, Start from: ${JSONSerializer.serialize(\n options.startFrom,\n )}`,\n );\n subscription = subscribe(client, from, options);\n subscription.once('confirmation', () => options.started?.resolve());\n\n processor = new SubscriptionSequentialHandler({\n client,\n from,\n batchSize,\n eachBatch,\n resilience,\n });\n\n const handler = new (class extends Writable {\n async _write(\n result: ProcessorCheckpoint | SingleMessageHandlerResult,\n _encoding: string,\n done: () => void,\n ) {\n if (!isRunning) return;\n\n if (isString(result)) {\n options.startFrom = {\n lastCheckpoint: result,\n };\n done();\n return;\n }\n\n if (result && result.type === 'STOP' && result.error) {\n console.error(\n `Subscription stopped with error code: ${result.error.errorCode}, message: ${\n result.error.message\n }.`,\n );\n }\n\n await stopSubscription();\n done();\n }\n })({ objectMode: true });\n\n pipeline(\n subscription,\n processor,\n handler,\n async (error: Error | null) => {\n console.info(`Stopping subscription.`);\n await stopSubscription(() => {\n if (!error) {\n console.info('Subscription ended successfully.');\n resolve();\n return;\n }\n console.error(\n `Received error: ${JSONSerializer.serialize(error)}.`,\n );\n options.started?.reject(error);\n reject(error);\n });\n },\n );\n }),\n resubscribeOptions,\n );\n };\n\n return {\n get isRunning() {\n return isRunning;\n },\n start: (options) => {\n if (isRunning) return start;\n\n start = (async () => {\n isRunning = true;\n\n return pipeMessages(options);\n })();\n\n return start;\n },\n stop: async () => {\n if (!isRunning) return start ? await start : Promise.resolve();\n await stopSubscription();\n await start;\n },\n };\n};\n","import type {\n AsyncAwaiter,\n MessageHandlerContext,\n MessageProcessor,\n} from '@event-driven-io/emmett';\nimport {\n asyncAwaiter,\n CurrentMessageProcessorPosition,\n EmmettError,\n inMemoryProjector,\n inMemoryReactor,\n mergeObservabilityOptions,\n type AnyEvent,\n type AnyMessage,\n type AnyRecordedMessageMetadata,\n type AsyncRetryOptions,\n type BatchRecordedMessageHandlerWithoutContext,\n type InMemoryProcessor,\n type InMemoryProjectorOptions,\n type InMemoryReactorOptions,\n type Message,\n type MessageConsumer,\n type MessageConsumerOptions,\n} from '@event-driven-io/emmett';\nimport {\n EventStoreDBClient,\n type SubscribeToAllOptions,\n type SubscribeToStreamOptions,\n} from '@eventstore/db-client';\nimport { v7 as uuid } from 'uuid';\nimport type { EventStoreDBReadEventMetadata } from '../eventstoreDBEventStore';\nimport {\n DefaultEventStoreDBEventStoreProcessorBatchSize,\n eventStoreDBSubscription,\n type EventStoreDBSubscription,\n} from './subscriptions';\n\nexport type EventStoreDBEventStoreConsumerConfig<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ConsumerMessageType extends Message = any,\n> = MessageConsumerOptions<ConsumerMessageType> & {\n from?: EventStoreDBEventStoreConsumerType;\n pulling?: {\n batchSize?: number;\n };\n resilience?: {\n resubscribeOptions?: AsyncRetryOptions;\n };\n};\n\nexport type EventStoreDBEventStoreConsumerOptions<\n ConsumerEventType extends Message = Message,\n> = EventStoreDBEventStoreConsumerConfig<ConsumerEventType> &\n (\n | {\n connectionString: string;\n client?: never;\n }\n | { client: EventStoreDBClient; connectionString?: never }\n );\n\nexport type $all = '$all';\nexport const $all = '$all';\n\nexport type EventStoreDBEventStoreConsumerType =\n | {\n stream: $all;\n options?: Exclude<SubscribeToAllOptions, 'fromPosition'>;\n }\n | {\n stream: string;\n options?: Exclude<SubscribeToStreamOptions, 'fromRevision'>;\n };\n\nexport type EventStoreDBEventStoreConsumer<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ConsumerMessageType extends AnyMessage = any,\n> = MessageConsumer<ConsumerMessageType> &\n Readonly<{\n reactor: <MessageType extends AnyMessage = ConsumerMessageType>(\n options: InMemoryReactorOptions<MessageType>,\n ) => InMemoryProcessor<MessageType>;\n }> &\n (AnyEvent extends ConsumerMessageType\n ? Readonly<{\n projector: <\n EventType extends AnyEvent = ConsumerMessageType & AnyEvent,\n >(\n options: InMemoryProjectorOptions<EventType>,\n ) => InMemoryProcessor<EventType>;\n }>\n : object);\n\nexport const eventStoreDBEventStoreConsumer = <\n ConsumerMessageType extends Message = AnyMessage,\n>(\n options: EventStoreDBEventStoreConsumerOptions<ConsumerMessageType>,\n): EventStoreDBEventStoreConsumer<ConsumerMessageType> => {\n let isRunning = false;\n let isInitialized = false;\n const { pulling } = options;\n const processors = options.processors ?? [];\n let abortController: AbortController | null = null;\n\n let start: Promise<void>;\n\n let currentSubscription: EventStoreDBSubscription | undefined;\n\n const startedAwaiter: AsyncAwaiter<void> = asyncAwaiter<void>();\n\n const client =\n 'client' in options && options.client\n ? options.client\n : EventStoreDBClient.connectionString(options.connectionString);\n\n const eachBatch: BatchRecordedMessageHandlerWithoutContext<\n ConsumerMessageType,\n EventStoreDBReadEventMetadata\n > = async (messagesBatch) => {\n const activeProcessors = processors.filter((s) => s.isActive);\n\n if (activeProcessors.length === 0)\n return {\n type: 'STOP',\n reason: 'No active processors',\n };\n\n const result = await Promise.allSettled(\n activeProcessors.map(async (s) => {\n // TODO: Add here filtering to only pass messages that can be handled by\n return await s.handle(messagesBatch, { client });\n }),\n );\n\n const error = result.find((r) => r.status === 'rejected')?.reason as\n Error | undefined;\n\n return result.some(\n (r) => r.status === 'fulfilled' && r.value?.type !== 'STOP',\n )\n ? undefined\n : {\n type: 'STOP',\n error: error ? EmmettError.mapFrom(error) : undefined,\n };\n };\n\n const subscription = (currentSubscription = eventStoreDBSubscription({\n client,\n from: options.from,\n eachBatch,\n batchSize:\n pulling?.batchSize ?? DefaultEventStoreDBEventStoreProcessorBatchSize,\n resilience: options.resilience,\n }));\n\n const init = async (): Promise<void> => {\n if (isInitialized) return;\n for (const processor of processors) {\n await processor.init({});\n }\n isInitialized = true;\n };\n\n const stopProcessors = () => Promise.all(processors.map((p) => p.close({})));\n\n const stop = async () => {\n if (!isRunning) return;\n isRunning = false;\n abortController?.abort();\n if (currentSubscription) {\n await currentSubscription.stop();\n currentSubscription = undefined;\n }\n await start;\n abortController = null;\n await stopProcessors();\n };\n\n return {\n consumerId: options.consumerId ?? uuid(),\n get isRunning() {\n return isRunning;\n },\n whenStarted: (): Promise<void> => startedAwaiter.wait,\n processors,\n reactor: <MessageType extends AnyMessage = ConsumerMessageType>(\n processorOptions: InMemoryReactorOptions<MessageType>,\n ): InMemoryProcessor<MessageType> => {\n const processor = inMemoryReactor(\n mergeObservabilityOptions(processorOptions, options.observability),\n );\n\n processors.push(\n // TODO: change that\n processor as unknown as MessageProcessor<\n ConsumerMessageType,\n AnyRecordedMessageMetadata,\n MessageHandlerContext\n >,\n );\n\n return processor;\n },\n projector: <EventType extends AnyEvent = ConsumerMessageType & AnyEvent>(\n processorOptions: InMemoryProjectorOptions<EventType>,\n ): InMemoryProcessor<EventType> => {\n const processor = inMemoryProjector(\n mergeObservabilityOptions(processorOptions, options.observability),\n );\n\n processors.push(\n // TODO: change that\n processor as unknown as MessageProcessor<\n ConsumerMessageType,\n AnyRecordedMessageMetadata,\n MessageHandlerContext\n >,\n );\n\n return processor;\n },\n start: () => {\n if (isRunning) return start;\n\n startedAwaiter.reset();\n\n if (processors.length === 0) {\n const error = new EmmettError(\n 'Cannot start consumer without at least a single processor',\n );\n startedAwaiter.reject(error);\n return Promise.reject(error);\n }\n isRunning = true;\n abortController = new AbortController();\n\n start = (async () => {\n if (!isRunning) return;\n\n try {\n if (!isInitialized) {\n await init();\n }\n\n const startFrom = CurrentMessageProcessorPosition.zip(\n await Promise.all(processors.map((o) => o.start(client))),\n );\n\n await subscription.start({ startFrom, started: startedAwaiter });\n } catch (error) {\n isRunning = false;\n startedAwaiter.reject(error);\n throw error;\n } finally {\n await stopProcessors();\n }\n })();\n\n return start;\n },\n stop,\n close: stop,\n };\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@event-driven-io/emmett-esdb",
3
3
  "type": "module",
4
- "version": "0.43.0-beta.23",
4
+ "version": "0.43.0-beta.26",
5
5
  "description": "Emmett - EventStoreDB - Event Sourcing development made simple",
6
6
  "scripts": {
7
7
  "build": "tsdown",
@@ -48,10 +48,10 @@
48
48
  ],
49
49
  "dependencies": {},
50
50
  "devDependencies": {
51
- "@event-driven-io/emmett-testcontainers": "0.43.0-beta.23"
51
+ "@event-driven-io/emmett-testcontainers": "0.43.0-beta.26"
52
52
  },
53
53
  "peerDependencies": {
54
- "@event-driven-io/emmett": "0.43.0-beta.23",
54
+ "@event-driven-io/emmett": "0.43.0-beta.26",
55
55
  "@eventstore/db-client": "^6.2.1"
56
56
  }
57
57
  }