@event-driven-io/emmett-sqlite 0.43.0-beta.14 → 0.43.0-beta.15
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.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["AssertionError","SQL","DumboError","UniqueConstraintError","BatchCommandNoChangesError","NO_CONCURRENCY_CHECK","STREAM_DOES_NOT_EXIST","STREAM_EXISTS","ExpectedVersionConflictError","identifier","SQL","identifier","plain","SQL","identifier","SQL","identifier","SQL","identifier","JSONSerializer","EmmettError","defaultProcessorVersion","defaultProcessorPartition","EmmettError","JSONSerializer","ExpectedVersionConflictError","NO_CONCURRENCY_CHECK","SQL","identifier","SQL","identifier","DumboError","UniqueConstraintError","SQL","SQL"],"sources":["../src/eventStore/projections/pongo/pongoProjections.ts","../src/eventStore/projections/pongo/pongoProjectionSpec.ts","../src/eventStore/projections/sqliteProjection.ts","../src/eventStore/projections/sqliteProjectionSpec.ts","../src/eventStore/schema/typing.ts","../src/eventStore/schema/appendToStream.ts","../src/eventStore/schema/migrations/0_41_0/0_41_0.snapshot.ts","../src/eventStore/schema/migrations/0_42_0/0_42_0.migration.ts","../src/eventStore/schema/migrations/0_42_0/0_42_0.snapshot.ts","../src/eventStore/schema/readLastMessageGlobalPosition.ts","../src/eventStore/schema/readMessagesBatch.ts","../src/eventStore/schema/readProcessorCheckpoint.ts","../src/eventStore/consumers/messageBatchProcessing/index.ts","../src/eventStore/consumers/sqliteCheckpointer.ts","../src/eventStore/consumers/sqliteProcessor.ts","../src/eventStore/consumers/sqliteEventStoreConsumer.ts","../src/eventStore/SQLiteEventStore.ts","../src/eventStore/schema/readStream.ts","../src/eventStore/schema/storeProcessorCheckpoint.ts","../src/eventStore/schema/streamExists.ts","../src/eventStore/schema/tables.ts"],"sourcesContent":["import {\n reduceAsync,\n type CanHandle,\n type Event,\n type EventStoreReadSchemaOptions,\n type JSONSerializationOptions,\n type ReadEvent,\n type TruncateProjection,\n} from '@event-driven-io/emmett';\nimport {\n pongoClient,\n type PongoClient,\n type PongoDBCollectionOptions,\n type PongoDocument,\n} from '@event-driven-io/pongo';\nimport {\n sqliteProjection,\n type SQLiteProjectionDefinition,\n type SQLiteProjectionHandlerContext,\n} from '..';\nimport type { SQLiteReadEventMetadata } from '../../SQLiteEventStore';\n\nexport type PongoProjectionHandlerContext = SQLiteProjectionHandlerContext & {\n pongo: PongoClient;\n};\n\nexport type PongoWithNotNullDocumentEvolve<\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n> =\n | ((\n document: Document,\n event: ReadEvent<EventType, EventMetaDataType>,\n ) => Document | null)\n | ((\n document: Document,\n event: ReadEvent<EventType>,\n ) => Promise<Document | null>);\n\nexport type PongoWithNullableDocumentEvolve<\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n> =\n | ((\n document: Document | null,\n event: ReadEvent<EventType, EventMetaDataType>,\n ) => Document | null)\n | ((\n document: Document | null,\n event: ReadEvent<EventType>,\n ) => Promise<Document | null>);\n\nexport type PongoDocumentEvolve<\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n> =\n | PongoWithNotNullDocumentEvolve<Document, EventType, EventMetaDataType>\n | PongoWithNullableDocumentEvolve<Document, EventType, EventMetaDataType>;\n\nexport type PongoProjectionOptions<\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n> = {\n name: string;\n kind?: string;\n version?: number;\n handle: (\n events: ReadEvent<EventType, SQLiteReadEventMetadata>[],\n context: PongoProjectionHandlerContext,\n ) => Promise<void>;\n canHandle: CanHandle<EventType>;\n truncate?: TruncateProjection<PongoProjectionHandlerContext>;\n init?: (context: PongoProjectionHandlerContext) => void | Promise<void>;\n eventsOptions?: {\n schema?: EventStoreReadSchemaOptions<EventType, EventPayloadType>;\n };\n} & JSONSerializationOptions;\n\nexport const pongoProjection = <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n>({\n name,\n kind,\n version,\n truncate,\n handle,\n canHandle,\n eventsOptions,\n}: PongoProjectionOptions<\n EventType,\n EventPayloadType\n>): SQLiteProjectionDefinition<EventType, EventPayloadType> =>\n sqliteProjection<EventType, EventPayloadType>({\n name,\n version,\n kind: kind ?? 'emt:projections:postgresql:pongo:generic',\n canHandle,\n eventsOptions,\n handle: async (events, context) => {\n const { connection } = context;\n const driver = (await pongoDriverRegistry.tryResolve(\n context.driverType,\n ))!;\n const pongo = pongoClient({\n driver,\n connectionOptions: { connection },\n });\n try {\n await handle(events, {\n ...context,\n pongo,\n });\n } finally {\n await pongo.close();\n }\n },\n truncate: truncate\n ? async (context) => {\n const { connection } = context;\n const driver = (await pongoDriverRegistry.tryResolve(\n context.driverType,\n ))!;\n const pongo = pongoClient({\n driver,\n connectionOptions: { connection },\n });\n try {\n await truncate({\n ...context,\n pongo,\n });\n } finally {\n await pongo.close();\n }\n }\n : undefined,\n });\n\nexport type PongoMultiStreamProjectionOptions<\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n EventPayloadType extends Event = EventType,\n DocumentPayload extends PongoDocument = Document,\n> = {\n kind?: string;\n canHandle: CanHandle<EventType>;\n version?: number;\n collectionName: string;\n collectionOptions?: PongoDBCollectionOptions<Document, DocumentPayload>;\n eventsOptions?: {\n schema?: EventStoreReadSchemaOptions<EventType, EventPayloadType>;\n };\n getDocumentId: (event: ReadEvent<EventType>) => string;\n} & (\n | {\n evolve: PongoWithNullableDocumentEvolve<\n Document,\n EventType,\n EventMetaDataType\n >;\n }\n | {\n evolve: PongoWithNotNullDocumentEvolve<\n Document,\n EventType,\n EventMetaDataType\n >;\n initialState: () => Document;\n }\n) &\n JSONSerializationOptions;\n\nexport const pongoMultiStreamProjection = <\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n EventPayloadType extends Event = EventType,\n>(\n options: PongoMultiStreamProjectionOptions<\n Document,\n EventType,\n EventMetaDataType,\n EventPayloadType\n >,\n): SQLiteProjectionDefinition<EventType, EventPayloadType> => {\n const { collectionName, getDocumentId, canHandle } = options;\n const collectionNameWithVersion =\n options.version && options.version > 0\n ? `${collectionName}_v${options.version}`\n : collectionName;\n\n return pongoProjection({\n name: collectionNameWithVersion,\n version: options.version,\n kind: options.kind ?? 'emt:projections:postgresql:pongo:multi_stream',\n eventsOptions: options.eventsOptions,\n handle: async (events, { pongo }) => {\n const collection = pongo\n .db()\n .collection<Document>(\n collectionNameWithVersion,\n options.collectionOptions,\n );\n\n const eventsByDocumentId = events\n .map((event) => {\n const documentId = getDocumentId(event);\n\n return {\n documentId,\n event: event as ReadEvent<EventType, EventMetaDataType>,\n };\n })\n .reduce((acc, { documentId, event }) => {\n if (!acc.has(documentId)) {\n acc.set(documentId, []);\n }\n acc.get(documentId)!.push(event);\n return acc;\n }, new Map<string, ReadEvent<EventType, EventMetaDataType>[]>());\n\n await collection.handle(\n [...eventsByDocumentId.keys()],\n (document, id) => {\n const events = eventsByDocumentId.get(id)!;\n\n return reduceAsync(\n events,\n async (acc, event) => await options.evolve(acc!, event),\n document ??\n ('initialState' in options ? options.initialState() : null),\n );\n },\n );\n },\n canHandle,\n truncate: async (context) => {\n const { connection } = context;\n const driver = (await pongoDriverRegistry.tryResolve(\n context.driverType,\n ))!;\n const pongo = pongoClient({\n driver,\n connectionOptions: { connection },\n });\n\n try {\n await pongo\n .db()\n .collection<Document>(\n collectionNameWithVersion,\n options.collectionOptions,\n )\n .deleteMany();\n } finally {\n await pongo.close();\n }\n },\n init: async (context) => {\n const { connection } = context;\n const driver = (await pongoDriverRegistry.tryResolve(\n context.driverType,\n ))!;\n const pongo = pongoClient({\n connectionOptions: { connection },\n driver,\n });\n\n try {\n await pongo\n .db()\n .collection<Document>(\n collectionNameWithVersion,\n options.collectionOptions,\n )\n .schema.migrate(); // TODO: ADD migration optionscontext.migrationOptions);\n } finally {\n await pongo.close();\n }\n },\n });\n};\n\nexport type PongoSingleStreamProjectionOptions<\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n EventPayloadType extends Event = EventType,\n DocumentPayload extends PongoDocument = Document,\n> = {\n canHandle: CanHandle<EventType>;\n getDocumentId?: (event: ReadEvent<EventType>) => string;\n version?: number;\n collectionName: string;\n collectionOptions?: PongoDBCollectionOptions<Document, DocumentPayload>;\n eventsOptions?: {\n schema?: EventStoreReadSchemaOptions<EventType, EventPayloadType>;\n };\n} & (\n | {\n evolve: PongoWithNullableDocumentEvolve<\n Document,\n EventType,\n EventMetaDataType\n >;\n }\n | {\n evolve: PongoWithNotNullDocumentEvolve<\n Document,\n EventType,\n EventMetaDataType\n >;\n initialState: () => Document;\n }\n) &\n JSONSerializationOptions;\n\nexport const pongoSingleStreamProjection = <\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n EventPayloadType extends Event = EventType,\n>(\n options: PongoSingleStreamProjectionOptions<\n Document,\n EventType,\n EventMetaDataType,\n EventPayloadType\n >,\n): SQLiteProjectionDefinition<EventType, EventPayloadType> => {\n return pongoMultiStreamProjection<\n Document,\n EventType,\n EventMetaDataType,\n EventPayloadType\n >({\n ...options,\n kind: 'emt:projections:postgresql:pongo:single_stream',\n getDocumentId:\n options.getDocumentId ?? ((event) => event.metadata.streamName),\n });\n};\n","import type { DatabaseDriverType } from '@event-driven-io/dumbo';\nimport type { AnySQLiteConnection } from '@event-driven-io/dumbo/sqlite';\nimport {\n assertDeepEqual,\n assertEqual,\n assertIsNotNull,\n assertIsNull,\n assertThatArray,\n} from '@event-driven-io/emmett';\nimport {\n pongoClient,\n type PongoCollection,\n type PongoDocument,\n type PongoFilter,\n type WithId,\n} from '@event-driven-io/pongo';\nimport type { SQLiteProjectionAssert } from '..';\n\nexport type PongoAssertOptions = {\n inCollection: string;\n inDatabase?: string;\n};\n\nconst withCollection = async (\n handle: (collection: PongoCollection<PongoDocument>) => Promise<void>,\n options: {\n connection: AnySQLiteConnection;\n } & PongoAssertOptions,\n) => {\n const { connection, inDatabase, inCollection } = options;\n\n const driver = (await pongoDriverRegistry.tryResolve(\n connection.driverType as DatabaseDriverType,\n ))!;\n const pongo = pongoClient({\n connectionOptions: { connection },\n driver,\n });\n try {\n const collection = pongo.db(inDatabase).collection(inCollection);\n\n return handle(collection);\n } finally {\n await pongo.close();\n }\n};\n\nconst withoutIdAndVersion = <Doc extends PongoDocument | WithId<PongoDocument>>(\n doc: Doc,\n) => {\n const { _id, _version, ...without } = doc;\n\n return without;\n};\n\nconst assertDocumentsEqual = <\n Doc extends PongoDocument | WithId<PongoDocument>,\n>(\n actual: PongoDocument,\n expected: Doc,\n) => {\n if ('_id' in expected)\n assertEqual(\n expected._id,\n actual._id,\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n `Document ids are not matching! Expected: ${expected._id}, Actual: ${actual._id}`,\n );\n\n return assertDeepEqual(\n withoutIdAndVersion(actual),\n withoutIdAndVersion(expected),\n );\n};\n\ntype FilterOrId<Doc extends PongoDocument | WithId<PongoDocument>> =\n | { withId: string }\n | {\n matchingFilter: PongoFilter<Doc>;\n };\n\nexport const documentExists =\n <Doc extends PongoDocument | WithId<PongoDocument>>(\n document: Doc,\n options: PongoAssertOptions & FilterOrId<Doc>,\n ): SQLiteProjectionAssert =>\n (assertOptions) =>\n withCollection(\n async (collection) => {\n const result = await collection.findOne(\n 'withId' in options\n ? { _id: options.withId }\n : options.matchingFilter,\n );\n\n assertIsNotNull(result);\n\n assertDocumentsEqual(result, document);\n },\n { ...options, ...assertOptions },\n );\n\nexport const documentsAreTheSame =\n <Doc extends PongoDocument | WithId<PongoDocument>>(\n documents: Doc[],\n options: PongoAssertOptions & FilterOrId<Doc>,\n ): SQLiteProjectionAssert =>\n (assertOptions) =>\n withCollection(\n async (collection) => {\n const result = await collection.find(\n 'withId' in options\n ? { _id: options.withId }\n : options.matchingFilter,\n );\n\n assertEqual(\n documents.length,\n result.length,\n 'Different Documents Count than expected',\n );\n\n for (let i = 0; i < documents.length; i++) {\n assertThatArray(result as Doc[]).contains(documents[i]!);\n }\n },\n { ...options, ...assertOptions },\n );\n\nexport const documentsMatchingHaveCount =\n <Doc extends PongoDocument | WithId<PongoDocument>>(\n expectedCount: number,\n options: PongoAssertOptions & FilterOrId<Doc>,\n ): SQLiteProjectionAssert =>\n (assertOptions) =>\n withCollection(\n async (collection) => {\n const result = await collection.find(\n 'withId' in options\n ? { _id: options.withId }\n : options.matchingFilter,\n );\n\n assertEqual(\n expectedCount,\n result.length,\n 'Different Documents Count than expected',\n );\n },\n { ...options, ...assertOptions },\n );\n\nexport const documentMatchingExists =\n <Doc extends PongoDocument | WithId<PongoDocument>>(\n options: PongoAssertOptions & FilterOrId<Doc>,\n ): SQLiteProjectionAssert =>\n (assertOptions) =>\n withCollection(\n async (collection) => {\n const result = await collection.find(\n 'withId' in options\n ? { _id: options.withId }\n : options.matchingFilter,\n );\n\n assertThatArray(result).isNotEmpty();\n },\n { ...options, ...assertOptions },\n );\n\nexport const documentDoesNotExist =\n <Doc extends PongoDocument | WithId<PongoDocument>>(\n options: PongoAssertOptions & FilterOrId<Doc>,\n ): SQLiteProjectionAssert =>\n (assertOptions) =>\n withCollection(\n async (collection) => {\n const result = await collection.findOne(\n 'withId' in options\n ? { _id: options.withId }\n : options.matchingFilter,\n );\n\n assertIsNull(result);\n },\n { ...options, ...assertOptions },\n );\n\nexport const expectPongoDocuments = {\n fromCollection: <Doc extends PongoDocument | WithId<PongoDocument>>(\n collectionName: string,\n ) => {\n return {\n withId: (id: string) => {\n return {\n toBeEqual: (document: Doc) =>\n documentExists(document, {\n withId: id,\n inCollection: collectionName,\n }),\n toExist: () =>\n documentMatchingExists({\n withId: id,\n inCollection: collectionName,\n }),\n notToExist: () =>\n documentDoesNotExist({\n withId: id,\n inCollection: collectionName,\n }),\n };\n },\n matching: <Doc extends PongoDocument | WithId<PongoDocument>>(\n filter: PongoFilter<Doc>,\n ) => {\n return {\n toBeTheSame: (documents: Doc[]) =>\n documentsAreTheSame<Doc>(documents, {\n matchingFilter: filter,\n inCollection: collectionName,\n }),\n toHaveCount: (expectedCount: number) =>\n documentsMatchingHaveCount(expectedCount, {\n matchingFilter: filter,\n inCollection: collectionName,\n }),\n toExist: () =>\n documentMatchingExists({\n matchingFilter: filter,\n inCollection: collectionName,\n }),\n notToExist: () =>\n documentDoesNotExist({\n matchingFilter: filter,\n inCollection: collectionName,\n }),\n };\n },\n };\n },\n};\n","import type {\n DatabaseDriverType,\n SQL,\n SQLExecutor,\n} from '@event-driven-io/dumbo';\nimport type { AnySQLiteConnection } from '@event-driven-io/dumbo/sqlite';\nimport {\n projection,\n type CanHandle,\n type Event,\n type EventStoreReadSchemaOptions,\n type JSONSerializationOptions,\n type ProjectionDefinition,\n type ProjectionHandler,\n type ProjectionInitOptions,\n type ReadEvent,\n} from '@event-driven-io/emmett';\nimport type { SQLiteReadEventMetadata } from '../SQLiteEventStore';\n\nexport type SQLiteProjectionHandlerContext = {\n execute: SQLExecutor;\n connection: AnySQLiteConnection;\n driverType: DatabaseDriverType;\n};\n\nexport type SQLiteProjectionHandler<\n EventType extends Event = Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n> = ProjectionHandler<\n EventType,\n EventMetaDataType,\n SQLiteProjectionHandlerContext\n>;\n\nexport type SQLiteProjectionDefinition<\n EventType extends Event = Event,\n EventPayloadType extends Event = EventType,\n> = ProjectionDefinition<\n EventType,\n SQLiteReadEventMetadata,\n SQLiteProjectionHandlerContext,\n EventPayloadType\n>;\n\nexport type SQLiteProjectionHandlerOptions<EventType extends Event = Event> = {\n events: ReadEvent<EventType, SQLiteReadEventMetadata>[];\n projections: SQLiteProjectionDefinition<EventType>[];\n} & SQLiteProjectionHandlerContext;\n\nexport const handleProjections = async <EventType extends Event = Event>(\n options: SQLiteProjectionHandlerOptions<EventType>,\n): Promise<void> => {\n const {\n projections: allProjections,\n events,\n connection,\n execute,\n driverType,\n } = options;\n\n const eventTypes = events.map((e) => e.type);\n\n for (const projection of allProjections) {\n if (!projection.canHandle.some((type) => eventTypes.includes(type))) {\n continue;\n }\n await projection.handle(events, {\n connection,\n execute,\n driverType,\n });\n }\n};\n\nexport const sqliteProjection = <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n>(\n definition: SQLiteProjectionDefinition<EventType, EventPayloadType>,\n): SQLiteProjectionDefinition<EventType, EventPayloadType> =>\n projection<\n EventType,\n SQLiteReadEventMetadata,\n SQLiteProjectionHandlerContext,\n EventPayloadType\n >(definition);\n\nexport type SQLiteRawBatchSQLProjection<\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n> = {\n name: string;\n kind?: string;\n version?: number;\n evolve: (\n events: EventType[],\n context: SQLiteProjectionHandlerContext,\n ) => Promise<SQL[]> | SQL[];\n canHandle: CanHandle<EventType>;\n init?: (\n context: ProjectionInitOptions<SQLiteProjectionHandlerContext>,\n ) => void | Promise<void> | SQL | Promise<SQL> | Promise<SQL[]> | SQL[];\n eventsOptions?: {\n schema?: EventStoreReadSchemaOptions<EventType, EventPayloadType>;\n };\n} & JSONSerializationOptions;\n\nexport const sqliteRawBatchSQLProjection = <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n>(\n options: SQLiteRawBatchSQLProjection<EventType, EventPayloadType>,\n): SQLiteProjectionDefinition<EventType, EventPayloadType> =>\n sqliteProjection<EventType, EventPayloadType>({\n name: options.name,\n kind: options.kind ?? 'emt:projections:sqlite:raw_sql:batch',\n version: options.version,\n canHandle: options.canHandle,\n eventsOptions: options.eventsOptions,\n handle: async (events, context) => {\n const sqls: SQL[] = await options.evolve(events, context);\n\n await context.execute.batchCommand(sqls);\n },\n init: async (initOptions) => {\n const initSQL = options.init\n ? await options.init(initOptions)\n : undefined;\n\n if (initSQL) {\n if (Array.isArray(initSQL)) {\n await initOptions.context.execute.batchCommand(initSQL);\n } else {\n await initOptions.context.execute.command(initSQL);\n }\n }\n },\n });\n\nexport type SQLiteRawSQLProjection<\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n> = {\n name: string;\n kind?: string;\n version?: number;\n evolve: (\n events: EventType,\n context: SQLiteProjectionHandlerContext,\n ) => Promise<SQL[]> | SQL[] | Promise<SQL> | SQL;\n canHandle: CanHandle<EventType>;\n init?: (\n context: ProjectionInitOptions<SQLiteProjectionHandlerContext>,\n ) => void | Promise<void> | SQL | Promise<SQL> | Promise<SQL[]> | SQL[];\n eventsOptions?: {\n schema?: EventStoreReadSchemaOptions<EventType, EventPayloadType>;\n };\n} & JSONSerializationOptions;\n\nexport const sqliteRawSQLProjection = <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n>(\n options: SQLiteRawSQLProjection<EventType, EventPayloadType>,\n): SQLiteProjectionDefinition<EventType, EventPayloadType> => {\n const { evolve, kind, ...rest } = options;\n return sqliteRawBatchSQLProjection<EventType, EventPayloadType>({\n kind: kind ?? 'emt:projections:sqlite:raw:_sql:single',\n ...rest,\n evolve: async (events, context) => {\n const sqls: SQL[] = [];\n\n for (const event of events) {\n const pendingSqls = await evolve(event, context);\n if (Array.isArray(pendingSqls)) {\n sqls.push(...pendingSqls);\n } else {\n sqls.push(pendingSqls);\n }\n }\n return sqls;\n },\n });\n};\n","import type { SQL } from '@event-driven-io/dumbo';\nimport { dumbo, type Dumbo, type QueryResultRow } from '@event-driven-io/dumbo';\nimport type { AnySQLiteConnection } from '@event-driven-io/dumbo/sqlite';\nimport {\n assertFails,\n AssertionError,\n assertThatArray,\n assertTrue,\n bigIntProcessorCheckpoint,\n isErrorConstructor,\n type CombinedReadEventMetadata,\n type Event,\n type JSONSerializationOptions,\n type ReadEvent,\n type ThenThrows,\n} from '@event-driven-io/emmett';\nimport { v4 as uuid } from 'uuid';\nimport type {\n AnyEventStoreDriver,\n InferOptionsFromEventStoreDriver,\n} from '../eventStoreDriver';\nimport type { SQLiteReadEventMetadata } from '../SQLiteEventStore';\nimport {\n handleProjections,\n type SQLiteProjectionDefinition,\n} from './sqliteProjection';\n\nexport type SQLiteProjectionSpecEvent<\n EventType extends Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n> = EventType & {\n metadata?: Partial<EventMetaDataType>;\n};\n\nexport type SQLiteProjectionSpecWhenOptions = {\n numberOfTimes: number;\n};\n\nexport type SQLiteProjectionSpec<EventType extends Event> = (\n givenEvents: SQLiteProjectionSpecEvent<EventType>[],\n) => {\n when: (\n events: SQLiteProjectionSpecEvent<EventType>[],\n options?: SQLiteProjectionSpecWhenOptions,\n ) => {\n then: (assert: SQLiteProjectionAssert, message?: string) => Promise<void>;\n thenThrows: <ErrorType extends Error = Error>(\n ...args: Parameters<ThenThrows<ErrorType>>\n ) => Promise<void>;\n };\n};\n\nexport type SQLiteProjectionAssert = (options: {\n connection: AnySQLiteConnection;\n}) => Promise<void | boolean>;\n\nexport type SQLiteProjectionSpecOptions<\n EventType extends Event,\n Driver extends AnyEventStoreDriver = AnyEventStoreDriver,\n> = {\n projection: SQLiteProjectionDefinition<EventType>;\n\n driver: Driver;\n pool?: Dumbo;\n} & InferOptionsFromEventStoreDriver<Driver> &\n JSONSerializationOptions;\n\nexport const SQLiteProjectionSpec = {\n for: <\n EventType extends Event,\n Driver extends AnyEventStoreDriver = AnyEventStoreDriver,\n >(\n options: SQLiteProjectionSpecOptions<EventType, Driver>,\n ): SQLiteProjectionSpec<EventType> => {\n {\n const driverType = options.driver.driverType;\n const pool =\n options.pool ??\n dumbo({\n serialization: options.serialization,\n transactionOptions: {\n allowNestedTransactions: true,\n mode: 'session_based',\n },\n ...options.driver.mapToDumboOptions(options),\n });\n const projection = options.projection;\n let wasInitialized = false;\n\n return (givenEvents: SQLiteProjectionSpecEvent<EventType>[]) => {\n return {\n when: (\n events: SQLiteProjectionSpecEvent<EventType>[],\n options?: SQLiteProjectionSpecWhenOptions,\n ) => {\n const allEvents: ReadEvent<EventType, SQLiteReadEventMetadata>[] =\n [];\n\n const run = async (connection: AnySQLiteConnection) => {\n let globalPosition = 0n;\n const numberOfTimes = options?.numberOfTimes ?? 1;\n\n for (const event of [\n ...givenEvents,\n ...Array.from({ length: numberOfTimes }).flatMap(() => events),\n ]) {\n const metadata: SQLiteReadEventMetadata = {\n checkpoint: bigIntProcessorCheckpoint(++globalPosition),\n globalPosition,\n streamPosition: globalPosition,\n streamName: `test-${uuid()}`,\n messageId: uuid(),\n };\n\n allEvents.push({\n ...event,\n kind: 'Event',\n metadata: {\n ...metadata,\n ...('metadata' in event ? (event.metadata ?? {}) : {}),\n } as CombinedReadEventMetadata<\n EventType,\n SQLiteReadEventMetadata\n >,\n });\n }\n\n if (!wasInitialized && projection.init) {\n await projection.init({\n registrationType: 'async',\n status: 'active',\n context: {\n execute: connection.execute,\n connection,\n driverType,\n },\n version: projection.version ?? 1,\n });\n wasInitialized = true;\n }\n\n await connection.withTransaction(() =>\n handleProjections({\n events: allEvents,\n projections: [projection],\n execute: connection.execute,\n connection,\n driverType,\n }),\n );\n };\n\n return {\n then: (\n assert: SQLiteProjectionAssert,\n message?: string,\n ): Promise<void> =>\n pool.withConnection(async (connection) => {\n await run(connection);\n\n const succeeded = await assert({\n connection,\n });\n\n if (succeeded !== undefined && succeeded === false)\n assertFails(\n message ??\n \"Projection specification didn't match the criteria\",\n );\n }),\n thenThrows: <ErrorType extends Error>(\n ...args: Parameters<ThenThrows<ErrorType>>\n ): Promise<void> =>\n pool.withConnection(async (connection) => {\n try {\n await run(connection);\n throw new AssertionError(\n 'Handler did not fail as expected',\n );\n } catch (error) {\n if (error instanceof AssertionError) throw error;\n\n if (args.length === 0) return;\n\n if (!isErrorConstructor(args[0])) {\n assertTrue(\n args[0](error as ErrorType),\n `Error didn't match the error condition: ${error?.toString()}`,\n );\n return;\n }\n\n assertTrue(\n error instanceof args[0],\n `Caught error is not an instance of the expected type: ${error?.toString()}`,\n );\n\n if (args[1]) {\n assertTrue(\n args[1](error as ErrorType),\n `Error didn't match the error condition: ${error?.toString()}`,\n );\n }\n }\n }),\n };\n },\n };\n };\n }\n },\n};\n\nexport const eventInStream = <\n EventType extends Event = Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n>(\n streamName: string,\n event: SQLiteProjectionSpecEvent<EventType, EventMetaDataType>,\n): SQLiteProjectionSpecEvent<EventType, EventMetaDataType> => {\n return {\n ...event,\n metadata: {\n ...(event.metadata ?? {}),\n streamName: event.metadata?.streamName ?? streamName,\n } as Partial<EventMetaDataType>,\n };\n};\n\nexport const eventsInStream = <\n EventType extends Event = Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n>(\n streamName: string,\n events: SQLiteProjectionSpecEvent<EventType, EventMetaDataType>[],\n): SQLiteProjectionSpecEvent<EventType, EventMetaDataType>[] => {\n return events.map((e) => eventInStream(streamName, e));\n};\n\nexport const newEventsInStream = eventsInStream;\n\nexport const assertSQLQueryResultMatches =\n <T extends QueryResultRow>(sql: SQL, rows: T[]): SQLiteProjectionAssert =>\n async ({\n connection,\n }: {\n connection: AnySQLiteConnection;\n }): Promise<void> => {\n const result = await connection.execute.query<T>(sql);\n\n assertThatArray(rows).containsExactlyInAnyOrder(result.rows);\n };\n\nexport const expectSQL = {\n query: (sql: SQL) => ({\n resultRows: {\n toBeTheSame: <T extends QueryResultRow>(rows: T[]) =>\n assertSQLQueryResultMatches(sql, rows),\n },\n }),\n};\n","export const emmettPrefix = 'emt';\n\nexport const globalTag = 'global';\nexport const defaultTag = `${emmettPrefix}:default`;\nexport const unknownTag = `${emmettPrefix}:unknown`;\n\nexport const globalNames = {\n module: `${emmettPrefix}:module:${globalTag}`,\n};\n\nconst columns = {\n partition: {\n name: 'partition',\n },\n isArchived: { name: 'is_archived' },\n};\n\nexport const streamsTable = {\n name: `${emmettPrefix}_streams`,\n columns: {\n partition: columns.partition,\n isArchived: columns.isArchived,\n },\n};\n\nexport const messagesTable = {\n name: `${emmettPrefix}_messages`,\n columns: {\n partition: columns.partition,\n isArchived: columns.isArchived,\n },\n};\n\nexport const processorsTable = {\n name: `${emmettPrefix}_processors`,\n};\n\nexport const projectionsTable = {\n name: `${emmettPrefix}_projections`,\n};\n","import {\n BatchCommandNoChangesError,\n DumboError,\n singleOrNull,\n SQL,\n UniqueConstraintError,\n type AnyDatabaseTransaction,\n type SQLExecutor,\n} from '@event-driven-io/dumbo';\nimport type { AnySQLiteConnection } from '@event-driven-io/dumbo/sqlite';\nimport {\n downcastRecordedMessages,\n ExpectedVersionConflictError,\n isExpectedVersionConflictError,\n NO_CONCURRENCY_CHECK,\n STREAM_DOES_NOT_EXIST,\n STREAM_EXISTS,\n type AppendToStreamOptions,\n type BeforeEventStoreCommitHandler,\n type ExpectedStreamVersion,\n type Event as Message,\n type RecordedMessage,\n} from '@event-driven-io/emmett';\nimport { v4 as uuid } from 'uuid';\nimport type {\n SQLiteEventStore,\n SQLiteReadEventMetadata,\n} from '../SQLiteEventStore';\nimport { defaultTag, messagesTable, streamsTable } from './typing';\n\nconst { identifier, merge } = SQL;\n\nexport type AppendEventResult =\n | {\n success: true;\n nextStreamPosition: bigint;\n lastGlobalPosition: bigint;\n }\n | { success: false };\n\nexport const appendToStream = async <MessageType extends Message>(\n connection: AnySQLiteConnection,\n streamName: string,\n streamType: string,\n messages: MessageType[],\n options?: AppendToStreamOptions & {\n partition?: string;\n onBeforeCommit?: BeforeEventStoreCommitHandler<\n SQLiteEventStore,\n { connection: AnySQLiteConnection }\n >;\n },\n): Promise<AppendEventResult> => {\n if (messages.length === 0) return { success: false };\n\n const expectedStreamVersion = toExpectedVersion(\n options?.expectedStreamVersion,\n );\n\n const messagesToAppend: RecordedMessage<\n MessageType,\n SQLiteReadEventMetadata\n >[] = messages.map(\n (\n m: Message,\n i: number,\n ): RecordedMessage<MessageType, SQLiteReadEventMetadata> =>\n ({\n ...m,\n kind: m.kind ?? 'Event',\n metadata: {\n streamName,\n messageId: uuid(),\n streamPosition: BigInt(i + 1),\n ...('metadata' in m ? (m.metadata ?? {}) : {}),\n },\n }) as RecordedMessage<MessageType, SQLiteReadEventMetadata>,\n );\n\n try {\n return await connection.withTransaction(\n async (transaction: AnyDatabaseTransaction) => {\n const result = await appendToStreamRaw(\n transaction.execute,\n streamName,\n streamType,\n downcastRecordedMessages(\n messagesToAppend,\n options?.schema?.versioning,\n ),\n {\n expectedStreamVersion,\n },\n );\n\n if (options?.onBeforeCommit)\n await options.onBeforeCommit(messagesToAppend, { connection });\n\n // TODO: Refactor this to map or not success from appendToStreamRaw\n return { success: true, result };\n },\n );\n } catch (err: unknown) {\n if (\n isExpectedVersionConflictError(err) ||\n DumboError.isInstanceOf(err, {\n errorType: UniqueConstraintError.ErrorType,\n }) ||\n DumboError.isInstanceOf(err, {\n errorType: BatchCommandNoChangesError.ErrorType,\n })\n ) {\n return { success: false };\n }\n throw err;\n }\n};\n\nconst toExpectedVersion = (\n expected: ExpectedStreamVersion | undefined,\n): bigint | null => {\n if (expected === undefined) return null;\n\n if (expected === NO_CONCURRENCY_CHECK) return null;\n\n // TODO: this needs to be fixed\n if (expected == STREAM_DOES_NOT_EXIST) return null;\n\n // TODO: this needs to be fixed\n if (expected == STREAM_EXISTS) return null;\n\n return expected as bigint;\n};\n\nconst appendToStreamRaw = async (\n execute: SQLExecutor,\n streamId: string,\n streamType: string,\n messages: RecordedMessage[],\n options?: {\n expectedStreamVersion: bigint | null;\n partition?: string;\n },\n): Promise<AppendEventResult> => {\n let expectedStreamVersion = options?.expectedStreamVersion ?? null;\n\n // TODO: Add eventually strategy not to call that for sqlite,\n // Now it's a shortcut to make it right for D1 trading of a bit performance\n const currentStreamVersion: bigint | null = await getLastStreamPosition(\n execute,\n streamId,\n expectedStreamVersion,\n );\n\n expectedStreamVersion ??= currentStreamVersion ?? 0n;\n\n if (expectedStreamVersion !== currentStreamVersion) {\n throw new ExpectedVersionConflictError(\n currentStreamVersion,\n expectedStreamVersion,\n );\n }\n\n const streamSQL =\n expectedStreamVersion === 0n\n ? SQL`INSERT INTO ${identifier(streamsTable.name)}\n (stream_id, stream_position, partition, stream_type, stream_metadata, is_archived)\n VALUES (\n ${streamId},\n ${messages.length},\n ${options?.partition ?? streamsTable.columns.partition},\n ${streamType},\n '[]',\n false\n )\n RETURNING stream_position;\n `\n : SQL`UPDATE ${identifier(streamsTable.name)}\n SET stream_position = stream_position + ${messages.length}\n WHERE stream_id = ${streamId}\n AND stream_position = ${expectedStreamVersion}\n AND partition = ${options?.partition ?? streamsTable.columns.partition}\n AND is_archived = false\n RETURNING stream_position;\n `;\n\n const insertSQL = buildMessageInsertQuery(\n messages,\n expectedStreamVersion,\n streamId,\n options?.partition?.toString() ?? defaultTag,\n );\n\n const results = await execute.batchCommand<{\n stream_position?: string;\n global_position?: string;\n }>([streamSQL, insertSQL], { assertChanges: true });\n\n const [streamResult, messagesResult] = results;\n\n const streamPosition = streamResult?.rows[0]?.stream_position;\n const globalPosition = messagesResult?.rows.at(-1)?.global_position;\n\n if (!streamPosition)\n throw new ExpectedVersionConflictError(0n, expectedStreamVersion ?? 0n);\n if (!globalPosition) throw new Error('Could not find global position');\n\n return {\n success: true,\n nextStreamPosition: BigInt(streamPosition),\n lastGlobalPosition: BigInt(globalPosition),\n };\n};\n\nasync function getLastStreamPosition(\n execute: SQLExecutor,\n streamId: string,\n expectedStreamVersion: bigint | null,\n): Promise<bigint> {\n const result = await singleOrNull(\n execute.query<{\n stream_position: string;\n }>(\n SQL`SELECT CAST(stream_position AS VARCHAR) AS stream_position FROM ${identifier(streamsTable.name)} WHERE stream_id = ${streamId}`,\n ),\n );\n\n if (result?.stream_position == null) {\n expectedStreamVersion = 0n;\n } else {\n expectedStreamVersion = BigInt(result.stream_position);\n }\n return expectedStreamVersion;\n}\n\nconst buildMessageInsertQuery = (\n messages: RecordedMessage[],\n expectedStreamVersion: bigint,\n streamId: string,\n partition: string | null | undefined,\n): SQL => {\n const values = messages.map((message: RecordedMessage) => {\n if (\n message.metadata?.streamPosition == null ||\n typeof message.metadata.streamPosition !== 'bigint'\n ) {\n throw new Error('Stream position is required');\n }\n\n const streamPosition =\n BigInt(message.metadata.streamPosition) + BigInt(expectedStreamVersion);\n\n return SQL`(${streamId},${streamPosition ?? 0n},${partition ?? defaultTag},${message.kind === 'Event' ? 'E' : 'C'},${message.data},${message.metadata},${expectedStreamVersion ?? 0n},${message.type},${message.metadata.messageId},${false})`;\n });\n\n return SQL`\n INSERT INTO ${identifier(messagesTable.name)} (\n stream_id, \n stream_position, \n partition, \n message_kind,\n message_data, \n message_metadata, \n message_schema_version, \n message_type, \n message_id, \n is_archived\n ) \n VALUES ${merge(values, ',')} \n RETURNING \n CAST(global_position as VARCHAR) AS global_position\n `;\n};\n","import { SQL } from '@event-driven-io/dumbo';\n\nexport const schema_0_41_0: SQL[] = [\n SQL`CREATE TABLE IF NOT EXISTS emt_streams(\n stream_id TEXT NOT NULL,\n stream_position BIGINT NOT NULL DEFAULT 0,\n partition TEXT NOT NULL DEFAULT 'global',\n stream_type TEXT NOT NULL,\n stream_metadata JSONB NOT NULL,\n is_archived BOOLEAN NOT NULL DEFAULT FALSE,\n PRIMARY KEY (stream_id, partition, is_archived),\n UNIQUE (stream_id, partition, is_archived)\n)`,\n SQL`CREATE TABLE IF NOT EXISTS emt_messages(\n stream_id TEXT NOT NULL,\n stream_position BIGINT NOT NULL,\n partition TEXT NOT NULL DEFAULT 'global',\n message_kind CHAR(1) NOT NULL DEFAULT 'E',\n message_data JSONB NOT NULL,\n message_metadata JSONB NOT NULL,\n message_schema_version TEXT NOT NULL,\n message_type TEXT NOT NULL,\n message_id TEXT NOT NULL,\n is_archived BOOLEAN NOT NULL DEFAULT FALSE,\n global_position INTEGER PRIMARY KEY,\n created DATETIME DEFAULT CURRENT_TIMESTAMP,\n UNIQUE (stream_id, stream_position, partition, is_archived)\n)`,\n SQL`CREATE TABLE IF NOT EXISTS emt_subscriptions(\n subscription_id TEXT NOT NULL,\n version INTEGER NOT NULL DEFAULT 1,\n partition TEXT NOT NULL DEFAULT 'global',\n last_processed_position BIGINT NOT NULL,\n PRIMARY KEY (subscription_id, partition, version)\n)`,\n];\n","import { singleOrNull, SQL, type SQLExecutor } from '@event-driven-io/dumbo';\nimport { globalTag, processorsTable, projectionsTable } from '../../typing';\n\nconst { identifier, plain } = SQL;\n\nexport const migration_0_42_0_SQLs: SQL[] = [\n SQL`CREATE TABLE IF NOT EXISTS ${identifier(processorsTable.name)}(\n processor_id TEXT NOT NULL,\n version INTEGER NOT NULL DEFAULT 1,\n partition TEXT NOT NULL DEFAULT '${plain(globalTag)}',\n status TEXT NOT NULL DEFAULT 'stopped',\n last_processed_checkpoint TEXT NOT NULL,\n processor_instance_id TEXT DEFAULT 'emt:unknown',\n PRIMARY KEY (processor_id, partition, version)\n)`,\n SQL`CREATE TABLE IF NOT EXISTS ${identifier(projectionsTable.name)}(\n name TEXT NOT NULL,\n version INTEGER NOT NULL DEFAULT 1,\n partition TEXT NOT NULL DEFAULT '${plain(globalTag)}',\n type CHAR(1) NOT NULL,\n kind TEXT NOT NULL,\n status TEXT NOT NULL,\n definition JSONB NOT NULL DEFAULT '{}',\n PRIMARY KEY (name, partition, version)\n)`,\n SQL`INSERT INTO ${identifier(processorsTable.name)}\n (processor_id, version, partition, status, last_processed_checkpoint, processor_instance_id)\n SELECT\n subscription_id,\n version,\n partition,\n 'stopped',\n printf('%019d', last_processed_position),\n 'emt:unknown'\n FROM emt_subscriptions`,\n SQL`DROP TABLE emt_subscriptions`,\n];\n\nexport const migration_0_42_0_FromSubscriptionsToProcessors = async (\n execute: SQLExecutor,\n): Promise<void> => {\n const tableExists = await singleOrNull(\n execute.query<{ name: string }>(\n SQL`SELECT name FROM sqlite_master WHERE type='table' AND name='emt_subscriptions'`,\n ),\n );\n\n if (!tableExists) {\n return;\n }\n\n await execute.batchCommand(migration_0_42_0_SQLs);\n};\n","import { SQL } from '@event-driven-io/dumbo';\n\nexport const schema_0_42_0: SQL[] = [\n SQL`CREATE TABLE IF NOT EXISTS emt_streams(\n stream_id TEXT NOT NULL,\n stream_position BIGINT NOT NULL DEFAULT 0,\n partition TEXT NOT NULL DEFAULT 'global',\n stream_type TEXT NOT NULL,\n stream_metadata JSONB NOT NULL,\n is_archived BOOLEAN NOT NULL DEFAULT FALSE,\n PRIMARY KEY (stream_id, partition, is_archived),\n UNIQUE (stream_id, partition, is_archived)\n)`,\n SQL`CREATE TABLE IF NOT EXISTS emt_messages(\n stream_id TEXT NOT NULL,\n stream_position BIGINT NOT NULL,\n partition TEXT NOT NULL DEFAULT 'global',\n message_kind CHAR(1) NOT NULL DEFAULT 'E',\n message_data JSONB NOT NULL,\n message_metadata JSONB NOT NULL,\n message_schema_version TEXT NOT NULL,\n message_type TEXT NOT NULL,\n message_id TEXT NOT NULL,\n is_archived BOOLEAN NOT NULL DEFAULT FALSE,\n global_position INTEGER PRIMARY KEY,\n created DATETIME DEFAULT CURRENT_TIMESTAMP,\n UNIQUE (stream_id, stream_position, partition, is_archived)\n)`,\n SQL`CREATE TABLE IF NOT EXISTS emt_processors(\n processor_id TEXT NOT NULL,\n version INTEGER NOT NULL DEFAULT 1,\n partition TEXT NOT NULL DEFAULT 'global',\n status TEXT NOT NULL DEFAULT 'stopped',\n last_processed_checkpoint TEXT NOT NULL,\n processor_instance_id TEXT DEFAULT 'emt:unknown',\n PRIMARY KEY (processor_id, partition, version)\n)`,\n SQL`CREATE TABLE IF NOT EXISTS emt_projections(\n name TEXT NOT NULL,\n version INTEGER NOT NULL DEFAULT 1,\n partition TEXT NOT NULL DEFAULT 'global',\n type CHAR(1) NOT NULL,\n kind TEXT NOT NULL,\n status TEXT NOT NULL,\n definition JSONB NOT NULL DEFAULT '{}',\n PRIMARY KEY (name, partition, version)\n)`,\n];\n","import { SQL, type SQLExecutor, singleOrNull } from '@event-driven-io/dumbo';\nimport { defaultTag, messagesTable } from './typing';\nconst { identifier } = SQL;\n\ntype ReadLastMessageGlobalPositionSqlResult = {\n global_position: string;\n};\n\nexport type ReadLastMessageGlobalPositionResult = {\n currentGlobalPosition: bigint | null;\n};\n\nexport const readLastMessageGlobalPosition = async (\n execute: SQLExecutor,\n options?: { partition?: string },\n): Promise<ReadLastMessageGlobalPositionResult> => {\n const result = await singleOrNull(\n execute.query<ReadLastMessageGlobalPositionSqlResult>(\n SQL`\n SELECT global_position\n FROM ${identifier(messagesTable.name)}\n WHERE partition = ${options?.partition ?? defaultTag} AND is_archived = FALSE\n ORDER BY global_position DESC\n LIMIT 1`,\n ),\n );\n\n return {\n currentGlobalPosition:\n result !== null ? BigInt(result.global_position) : null,\n };\n};\n","import { mapRows, SQL, type SQLExecutor } from '@event-driven-io/dumbo';\nimport type { JSONSerializer } from '@event-driven-io/emmett';\nimport {\n bigIntProcessorCheckpoint,\n type CombinedMessageMetadata,\n type Message,\n type RecordedMessage,\n type RecordedMessageMetadata,\n type RecordedMessageMetadataWithGlobalPosition,\n} from '@event-driven-io/emmett';\nimport { defaultTag, messagesTable } from './typing';\nconst { identifier } = SQL;\n\ntype ReadMessagesBatchSqlResult = {\n stream_position: string;\n stream_id: string;\n message_data: string;\n message_metadata: string;\n message_schema_version: string;\n message_type: string;\n message_id: string;\n global_position: string;\n transaction_id: string;\n created: string;\n};\n\nexport type ReadMessagesBatchOptions = (\n | {\n after: bigint;\n batchSize: number;\n }\n | {\n from: bigint;\n batchSize: number;\n }\n | { to: bigint; batchSize: number }\n | { from: bigint; to: bigint }\n) & {\n partition?: string;\n serializer: JSONSerializer;\n};\n\nexport type ReadMessagesBatchResult<\n MessageType extends Message,\n MessageMetadataType extends RecordedMessageMetadata = RecordedMessageMetadata,\n> = {\n currentGlobalPosition: bigint;\n messages: RecordedMessage<MessageType, MessageMetadataType>[];\n areMessagesLeft: boolean;\n};\n\nexport const readMessagesBatch = async <\n MessageType extends Message,\n RecordedMessageMetadataType extends\n RecordedMessageMetadataWithGlobalPosition =\n RecordedMessageMetadataWithGlobalPosition,\n>(\n execute: SQLExecutor,\n options: ReadMessagesBatchOptions,\n): Promise<\n ReadMessagesBatchResult<MessageType, RecordedMessageMetadataType>\n> => {\n const { serializer } = options;\n const from = 'from' in options ? options.from : undefined;\n const after = 'after' in options ? options.after : undefined;\n const batchSize =\n 'batchSize' in options ? options.batchSize : options.to - options.from;\n\n const fromCondition: SQL =\n from !== undefined\n ? SQL`AND global_position >= ${from}`\n : after !== undefined\n ? SQL`AND global_position > ${after}`\n : SQL.EMPTY;\n\n const toCondition: SQL =\n 'to' in options ? SQL`AND global_position <= ${options.to}` : SQL.EMPTY;\n\n const limitCondition: SQL =\n 'batchSize' in options ? SQL`LIMIT ${options.batchSize}` : SQL.EMPTY;\n\n const messages: RecordedMessage<MessageType, RecordedMessageMetadataType>[] =\n await mapRows(\n execute.query<ReadMessagesBatchSqlResult>(\n SQL`SELECT stream_id, stream_position, global_position, message_data, message_metadata, message_schema_version, message_type, message_id\n FROM ${identifier(messagesTable.name)}\n WHERE partition = ${options?.partition ?? defaultTag} AND is_archived = FALSE ${fromCondition} ${toCondition}\n ORDER BY global_position\n ${limitCondition}`,\n ),\n (row) => {\n const rawEvent = {\n type: row.message_type,\n data: serializer.deserialize(row.message_data),\n metadata: serializer.deserialize(row.message_metadata),\n } as unknown as MessageType;\n\n const metadata: RecordedMessageMetadataWithGlobalPosition = {\n ...('metadata' in rawEvent ? (rawEvent.metadata ?? {}) : {}),\n messageId: row.message_id,\n streamName: row.stream_id,\n streamPosition: BigInt(row.stream_position),\n globalPosition: BigInt(row.global_position),\n checkpoint: bigIntProcessorCheckpoint(BigInt(row.global_position)),\n };\n\n return {\n ...rawEvent,\n kind: 'Event',\n metadata: metadata as CombinedMessageMetadata<\n MessageType,\n RecordedMessageMetadataType\n >,\n };\n },\n );\n\n return messages.length > 0\n ? {\n currentGlobalPosition:\n messages[messages.length - 1]!.metadata.globalPosition,\n messages: messages,\n areMessagesLeft: messages.length === batchSize,\n }\n : {\n currentGlobalPosition:\n 'from' in options\n ? options.from\n : 'after' in options\n ? options.after\n : 0n,\n messages: [],\n areMessagesLeft: false,\n };\n};\n","import { SQL, type SQLExecutor, singleOrNull } from '@event-driven-io/dumbo';\nimport type { ProcessorCheckpoint } from '@event-driven-io/emmett';\nimport { defaultTag, processorsTable } from './typing';\nconst { identifier } = SQL;\n\ntype ReadProcessorCheckpointSqlResult = {\n last_processed_checkpoint: string;\n};\n\nexport type ReadProcessorCheckpointResult = {\n lastProcessedCheckpoint: ProcessorCheckpoint | null;\n};\n\nexport const readProcessorCheckpoint = async (\n execute: SQLExecutor,\n options: { processorId: string; partition?: string },\n): Promise<ReadProcessorCheckpointResult> => {\n const result = await singleOrNull(\n execute.query<ReadProcessorCheckpointSqlResult>(\n SQL`SELECT last_processed_checkpoint\n FROM ${identifier(processorsTable.name)}\n WHERE partition = ${options?.partition ?? defaultTag} AND processor_id = ${options.processorId}\n LIMIT 1`,\n ),\n );\n\n return {\n lastProcessedCheckpoint:\n result !== null\n ? (result.last_processed_checkpoint as ProcessorCheckpoint)\n : null,\n };\n};\n","import type { SQLExecutor } from '@event-driven-io/dumbo';\nimport {\n JSONSerializer,\n parseBigIntProcessorCheckpoint,\n type AsyncAwaiter,\n type BatchRecordedMessageHandlerWithoutContext,\n type EmmettError,\n type Event,\n type JSONSerializationOptions,\n type Message,\n type ProcessorCheckpoint,\n type ReadEvent,\n type ReadEventMetadataWithGlobalPosition,\n} from '@event-driven-io/emmett';\nimport { readLastMessageGlobalPosition } from '../../schema/readLastMessageGlobalPosition';\nimport {\n readMessagesBatch,\n type ReadMessagesBatchOptions,\n} from '../../schema/readMessagesBatch';\n\nexport const DefaultSQLiteEventStoreProcessorBatchSize = 100;\nexport const DefaultSQLiteEventStoreProcessorPullingFrequencyInMs = 50;\n\nexport type SQLiteEventStoreMessagesBatch<EventType extends Event = Event> = {\n messages: ReadEvent<EventType, ReadEventMetadataWithGlobalPosition>[];\n};\n\nexport type SQLiteEventStoreMessagesBatchHandlerResult = void | {\n type: 'STOP';\n reason?: string;\n error?: EmmettError;\n};\n\nexport type SQLiteEventStoreMessageBatchPullerOptions<\n MessageType extends Message = Message,\n> = {\n executor: SQLExecutor;\n pullingFrequencyInMs: number;\n batchSize: number;\n eachBatch: BatchRecordedMessageHandlerWithoutContext<\n MessageType,\n ReadEventMetadataWithGlobalPosition\n >;\n stopWhen?: {\n noMessagesLeft?: boolean;\n };\n signal: AbortSignal;\n} & JSONSerializationOptions;\n\nexport type SQLiteEventStoreMessageBatchPullerStartFrom =\n | { lastCheckpoint: ProcessorCheckpoint }\n | 'BEGINNING'\n | 'END';\n\nexport type SQLiteEventStoreMessageBatchPullerStartOptions = {\n startFrom: SQLiteEventStoreMessageBatchPullerStartFrom;\n signal?: AbortSignal;\n started?: AsyncAwaiter<void>;\n};\n\nexport type SQLiteEventStoreMessageBatchPuller = {\n isRunning: boolean;\n start(options: SQLiteEventStoreMessageBatchPullerStartOptions): Promise<void>;\n stop(): Promise<void>;\n};\n\nexport const sqliteEventStoreMessageBatchPuller = <\n MessageType extends Message = Message,\n>({\n executor,\n batchSize,\n eachBatch,\n pullingFrequencyInMs,\n stopWhen,\n signal,\n serialization,\n}: SQLiteEventStoreMessageBatchPullerOptions<MessageType>): SQLiteEventStoreMessageBatchPuller => {\n let isRunning = false;\n\n let start: Promise<void>;\n const serializer = JSONSerializer.from({ serialization });\n\n const pullMessages = async (\n options: SQLiteEventStoreMessageBatchPullerStartOptions,\n ) => {\n let after: bigint;\n try {\n after =\n options.startFrom === 'BEGINNING'\n ? 0n\n : options.startFrom === 'END'\n ? ((await readLastMessageGlobalPosition(executor))\n .currentGlobalPosition ?? 0n)\n : parseBigIntProcessorCheckpoint(options.startFrom.lastCheckpoint);\n } catch (error) {\n options.started?.reject(error);\n throw error;\n }\n\n options.started?.resolve();\n\n const readMessagesOptions: ReadMessagesBatchOptions = {\n after,\n batchSize,\n serializer,\n };\n\n let waitTime = 100;\n\n while (isRunning && !signal?.aborted) {\n const { messages, currentGlobalPosition, areMessagesLeft } =\n await readMessagesBatch<MessageType>(executor, readMessagesOptions);\n\n if (messages.length > 0) {\n const result = await eachBatch(messages);\n\n if (result && result.type === 'STOP') {\n isRunning = false;\n break;\n }\n }\n\n readMessagesOptions.after = currentGlobalPosition;\n\n await new Promise((resolve) => setTimeout(resolve, waitTime));\n\n if (stopWhen?.noMessagesLeft === true && !areMessagesLeft) {\n isRunning = false;\n break;\n }\n\n if (!areMessagesLeft) {\n waitTime = Math.min(waitTime * 2, 1000);\n } else {\n waitTime = pullingFrequencyInMs;\n }\n }\n };\n\n return {\n get isRunning() {\n return isRunning;\n },\n start: (options) => {\n if (isRunning) return start;\n isRunning = true;\n\n start = (async () => {\n return pullMessages(options);\n })();\n\n return start;\n },\n stop: async () => {\n if (!isRunning) return;\n isRunning = false;\n await start;\n },\n };\n};\n\nexport const zipSQLiteEventStoreMessageBatchPullerStartFrom = (\n options: (SQLiteEventStoreMessageBatchPullerStartFrom | undefined)[],\n): SQLiteEventStoreMessageBatchPullerStartFrom => {\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 { AnyMessage, Message } from '@event-driven-io/emmett';\nimport {\n type Checkpointer,\n type ReadEventMetadataWithGlobalPosition,\n getCheckpoint,\n} from '@event-driven-io/emmett';\nimport { readProcessorCheckpoint, storeProcessorCheckpoint } from '../schema';\nimport type { SQLiteProcessorHandlerContext } from './sqliteProcessor';\n\nexport type SQLiteCheckpointer<MessageType extends AnyMessage = AnyMessage> =\n Checkpointer<\n MessageType,\n ReadEventMetadataWithGlobalPosition,\n SQLiteProcessorHandlerContext\n >;\n\nexport const sqliteCheckpointer = <\n MessageType extends Message = Message,\n>(): SQLiteCheckpointer<MessageType> => ({\n read: async (options, context) => {\n const result = await readProcessorCheckpoint(context.execute, options);\n\n return { lastCheckpoint: result?.lastProcessedCheckpoint };\n },\n store: async (options, context) => {\n const newCheckpoint = getCheckpoint(options.message);\n\n const result = await storeProcessorCheckpoint(context.execute, {\n lastProcessedCheckpoint: options.lastCheckpoint,\n newCheckpoint,\n processorId: options.processorId,\n partition: options.partition,\n version: options.version,\n });\n\n return result.success\n ? { success: true, newCheckpoint: result.newCheckpoint }\n : result;\n },\n});\n","import type { SQLExecutor } from '@event-driven-io/dumbo';\nimport type {\n AnySQLiteConnection,\n SQLiteTransaction,\n} from '@event-driven-io/dumbo/sqlite';\nimport type {\n AnyCommand,\n AnyEvent,\n AnyMessage,\n AnyRecordedMessageMetadata,\n BatchRecordedMessageHandlerWithContext,\n Checkpointer,\n Message,\n MessageProcessingScope,\n MessageProcessor,\n ProcessorHooks,\n ProjectorOptions,\n ReactorOptions,\n ReadEventMetadataWithGlobalPosition,\n SingleMessageHandlerResult,\n SingleRecordedMessageHandlerWithContext,\n WorkflowProcessorContext,\n WorkflowProcessorOptions,\n} from '@event-driven-io/emmett';\nimport {\n defaultProcessorPartition,\n defaultProcessorVersion,\n EmmettError,\n getProcessorInstanceId,\n getProjectorId,\n getWorkflowId,\n projector,\n reactor,\n workflowProcessor,\n type Event,\n type ReadEvent,\n} from '@event-driven-io/emmett';\nimport type { EventStoreSchemaMigrationOptions } from '../schema';\nimport type { SQLiteEventStoreMessageBatchPullerStartFrom } from './messageBatchProcessing';\nimport { sqliteCheckpointer } from './sqliteCheckpointer';\n\nexport type SQLiteProcessorEventsBatch<EventType extends Event = Event> = {\n messages: ReadEvent<EventType, ReadEventMetadataWithGlobalPosition>[];\n};\n\nexport type SQLiteProcessorHandlerContext = {\n execute: SQLExecutor;\n connection: AnySQLiteConnection;\n} &\n // TODO: Reconsider if it should be for all processors\n EventStoreSchemaMigrationOptions;\n\nexport type SQLiteProcessor<MessageType extends Message = AnyMessage> =\n MessageProcessor<\n MessageType,\n ReadEventMetadataWithGlobalPosition,\n SQLiteProcessorHandlerContext\n >;\n\nexport type SQLiteProcessorEachMessageHandler<\n MessageType extends Message = Message,\n> = SingleRecordedMessageHandlerWithContext<\n MessageType,\n ReadEventMetadataWithGlobalPosition,\n SQLiteProcessorHandlerContext\n>;\n\nexport type SQLiteProcessorEachBatchHandler<\n MessageType extends Message = Message,\n> = BatchRecordedMessageHandlerWithContext<\n MessageType,\n ReadEventMetadataWithGlobalPosition,\n SQLiteProcessorHandlerContext\n>;\n\nexport type SQLiteProcessorStartFrom =\n | SQLiteEventStoreMessageBatchPullerStartFrom\n | 'CURRENT';\n\nexport type SQLiteProcessorConnectionOptions = {\n connection?: AnySQLiteConnection;\n};\n\nexport type SQLiteReactorOptions<\n MessageType extends Message = Message,\n MessagePayloadType extends AnyMessage = MessageType,\n> = ReactorOptions<\n MessageType,\n ReadEventMetadataWithGlobalPosition,\n SQLiteProcessorHandlerContext,\n MessagePayloadType\n> &\n SQLiteProcessorConnectionOptions;\n\nexport type SQLiteProjectorOptions<\n EventType extends AnyEvent = AnyEvent,\n EventPayloadType extends Event = EventType,\n> = ProjectorOptions<\n EventType,\n ReadEventMetadataWithGlobalPosition,\n SQLiteProcessorHandlerContext,\n EventPayloadType\n> &\n SQLiteProcessorConnectionOptions &\n EventStoreSchemaMigrationOptions;\n\nexport type SQLiteWorkflowProcessorOptions<\n Input extends AnyEvent | AnyCommand,\n State,\n Output extends AnyEvent | AnyCommand,\n MetaDataType extends AnyRecordedMessageMetadata = AnyRecordedMessageMetadata,\n HandlerContext extends WorkflowProcessorContext = WorkflowProcessorContext,\n StoredMessage extends AnyEvent | AnyCommand = Output,\n> = WorkflowProcessorOptions<\n Input,\n State,\n Output,\n MetaDataType,\n HandlerContext,\n StoredMessage\n> &\n SQLiteProcessorConnectionOptions & {\n messageStore: WorkflowProcessorContext['connection']['messageStore'];\n };\n\nconst sqliteProcessingScope =\n (): MessageProcessingScope<SQLiteProcessorHandlerContext> => {\n const processingScope: MessageProcessingScope<\n SQLiteProcessorHandlerContext\n > = async <Result = SingleMessageHandlerResult>(\n handler: (\n context: SQLiteProcessorHandlerContext,\n ) => Result | Promise<Result>,\n partialContext: Partial<SQLiteProcessorHandlerContext>,\n ) => {\n const connection = partialContext?.connection;\n\n if (!connection)\n // TODO: Map it to dumbo connection correctly\n throw new EmmettError('Connection is required in context or options');\n\n return connection.withTransaction(\n async (transaction: SQLiteTransaction) => {\n return handler({\n ...partialContext,\n connection: connection,\n execute: transaction.execute,\n });\n },\n );\n };\n\n return processingScope;\n };\n\nconst sqliteWorkflowProcessingScope = (\n messageStore: WorkflowProcessorContext['connection']['messageStore'],\n): MessageProcessingScope<\n SQLiteProcessorHandlerContext & WorkflowProcessorContext\n> => {\n const processingScope: MessageProcessingScope<\n SQLiteProcessorHandlerContext & WorkflowProcessorContext\n > = async <Result = SingleMessageHandlerResult>(\n handler: (\n context: SQLiteProcessorHandlerContext & WorkflowProcessorContext,\n ) => Result | Promise<Result>,\n partialContext: Partial<\n SQLiteProcessorHandlerContext & WorkflowProcessorContext\n >,\n ) => {\n const connection = partialContext?.connection;\n\n if (!connection)\n throw new EmmettError('Connection is required in context or options');\n\n return connection.withTransaction(\n async (transaction: SQLiteTransaction) => {\n return handler({\n ...partialContext,\n connection: Object.assign(connection, { messageStore }),\n execute: transaction.execute,\n });\n },\n );\n };\n\n return processingScope;\n};\n\nexport const sqliteWorkflowProcessor = <\n Input extends AnyEvent | AnyCommand,\n State,\n Output extends AnyEvent | AnyCommand,\n MetaDataType extends AnyRecordedMessageMetadata = AnyRecordedMessageMetadata,\n HandlerContext extends SQLiteProcessorHandlerContext &\n WorkflowProcessorContext = SQLiteProcessorHandlerContext &\n WorkflowProcessorContext,\n StoredMessage extends AnyEvent | AnyCommand = Output,\n>(\n options: SQLiteWorkflowProcessorOptions<\n Input,\n State,\n Output,\n MetaDataType,\n HandlerContext,\n StoredMessage\n >,\n): SQLiteProcessor<Input | Output> => {\n const {\n processorId = options.processorId ??\n getWorkflowId({\n workflowName: options.workflow.name ?? 'unknown',\n }),\n processorInstanceId = getProcessorInstanceId(processorId),\n version = defaultProcessorVersion,\n partition = defaultProcessorPartition,\n } = options;\n\n const hooks: ProcessorHooks<HandlerContext> = {\n ...(options.hooks ?? {}),\n onClose: options.hooks?.onClose,\n };\n\n return workflowProcessor({\n ...options,\n processorId,\n processorInstanceId,\n version,\n partition,\n hooks,\n processingScope: sqliteWorkflowProcessingScope(\n options.messageStore,\n ) as unknown as MessageProcessingScope<HandlerContext>,\n checkpoints: sqliteCheckpointer<Input | Output>() as Checkpointer<\n Input | Output,\n MetaDataType,\n HandlerContext\n >,\n }) as SQLiteProcessor<Input | Output>;\n};\n\nexport const sqliteReactor = <\n MessageType extends Message = Message,\n MessagePayloadType extends AnyMessage = MessageType,\n>(\n options: SQLiteReactorOptions<MessageType, MessagePayloadType>,\n): SQLiteProcessor<MessageType> => {\n const {\n processorId = options.processorId,\n processorInstanceId = getProcessorInstanceId(processorId),\n version = defaultProcessorVersion,\n partition = defaultProcessorPartition,\n hooks,\n } = options;\n\n return reactor({\n ...options,\n processorId,\n processorInstanceId,\n version,\n partition,\n hooks,\n processingScope: sqliteProcessingScope(),\n\n checkpoints: sqliteCheckpointer<MessageType>(),\n });\n};\n\nexport const sqliteProjector = <\n EventType extends Event = Event,\n EventPayloadType extends Event = EventType,\n>(\n options: SQLiteProjectorOptions<EventType, EventPayloadType>,\n): SQLiteProcessor<EventType> => {\n const {\n processorId = getProjectorId({\n projectionName: options.projection.name ?? 'unknown',\n }),\n processorInstanceId = getProcessorInstanceId(processorId),\n version = defaultProcessorVersion,\n partition = defaultProcessorPartition,\n } = options;\n\n const hooks: ProcessorHooks<SQLiteProcessorHandlerContext> = {\n ...(options.hooks ?? {}),\n onInit:\n options.projection.init !== undefined || options.hooks?.onInit\n ? async (context: SQLiteProcessorHandlerContext) => {\n if (options.projection.init)\n await options.projection.init({\n version: options.projection.version ?? version,\n status: 'active',\n registrationType: 'async',\n context: {\n ...context,\n migrationOptions: options.migrationOptions,\n },\n });\n if (options.hooks?.onInit)\n await options.hooks.onInit({\n ...context,\n migrationOptions: options.migrationOptions,\n });\n }\n : options.hooks?.onInit,\n onClose: options.hooks?.onClose,\n };\n\n const processor = projector<\n EventType,\n ReadEventMetadataWithGlobalPosition,\n SQLiteProcessorHandlerContext,\n EventPayloadType\n >({\n ...options,\n processorId,\n processorInstanceId,\n version,\n partition,\n hooks,\n processingScope: sqliteProcessingScope(),\n checkpoints: sqliteCheckpointer<EventType>(),\n });\n\n return processor;\n};\n","import { dumbo, type Dumbo } from '@event-driven-io/dumbo';\nimport type {\n AnyCommand,\n JSONSerializationOptions,\n MessageProcessor,\n WorkflowProcessorContext,\n} from '@event-driven-io/emmett';\nimport {\n asyncAwaiter,\n EmmettError,\n type AnyEvent,\n type AnyMessage,\n type AnyRecordedMessageMetadata,\n type AsyncAwaiter,\n type BatchRecordedMessageHandlerWithoutContext,\n type DefaultRecord,\n type Message,\n type MessageConsumer,\n type MessageConsumerOptions,\n type ReadEventMetadataWithGlobalPosition,\n} from '@event-driven-io/emmett';\nimport { v7 as uuid } from 'uuid';\nimport type {\n AnyEventStoreDriver,\n InferOptionsFromEventStoreDriver,\n} from '../eventStoreDriver';\nimport { getSQLiteEventStore } from '../SQLiteEventStore';\nimport {\n DefaultSQLiteEventStoreProcessorBatchSize,\n DefaultSQLiteEventStoreProcessorPullingFrequencyInMs,\n sqliteEventStoreMessageBatchPuller,\n zipSQLiteEventStoreMessageBatchPullerStartFrom,\n type SQLiteEventStoreMessageBatchPuller,\n} from './messageBatchProcessing';\nimport {\n sqliteProjector,\n sqliteReactor,\n sqliteWorkflowProcessor,\n type SQLiteProcessor,\n type SQLiteProcessorHandlerContext,\n type SQLiteProjectorOptions,\n type SQLiteReactorOptions,\n type SQLiteWorkflowProcessorOptions,\n} from './sqliteProcessor';\n\nexport type SQLiteEventStoreConsumerConfig<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ConsumerMessageType extends Message = any,\n> = MessageConsumerOptions<ConsumerMessageType> & {\n stopWhen?: {\n noMessagesLeft?: boolean;\n };\n pulling?: {\n batchSize?: number;\n pullingFrequencyInMs?: number;\n };\n};\n\nexport type SQLiteEventStoreConsumerOptions<\n ConsumerMessageType extends Message = Message,\n Driver extends AnyEventStoreDriver = AnyEventStoreDriver,\n> = SQLiteEventStoreConsumerConfig<ConsumerMessageType> & {\n driver: Driver;\n pool?: Dumbo;\n} & InferOptionsFromEventStoreDriver<Driver> &\n JSONSerializationOptions;\n\nexport type SQLiteEventStoreConsumer<\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: SQLiteReactorOptions<MessageType>,\n ) => SQLiteProcessor<MessageType>;\n\n workflowProcessor: <\n Input extends AnyEvent | AnyCommand,\n State,\n Output extends AnyEvent | AnyCommand,\n MetaDataType extends AnyRecordedMessageMetadata =\n AnyRecordedMessageMetadata,\n HandlerContext extends SQLiteProcessorHandlerContext &\n WorkflowProcessorContext = SQLiteProcessorHandlerContext &\n WorkflowProcessorContext,\n StoredMessage extends AnyEvent | AnyCommand = Output,\n >(\n options: Omit<\n SQLiteWorkflowProcessorOptions<\n Input,\n State,\n Output,\n MetaDataType,\n HandlerContext,\n StoredMessage\n >,\n 'messageStore'\n >,\n ) => SQLiteProcessor<Input | Output>;\n }> &\n (AnyEvent extends ConsumerMessageType\n ? Readonly<{\n projector: <\n EventType extends AnyEvent = ConsumerMessageType & AnyEvent,\n >(\n options: SQLiteProjectorOptions<EventType>,\n ) => SQLiteProcessor<EventType>;\n }>\n : object);\n\nexport const sqliteEventStoreConsumer = <\n ConsumerMessageType extends Message = AnyMessage,\n Driver extends AnyEventStoreDriver = AnyEventStoreDriver,\n>(\n options: SQLiteEventStoreConsumerOptions<ConsumerMessageType, Driver>,\n): SQLiteEventStoreConsumer<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 messagePuller: SQLiteEventStoreMessageBatchPuller | undefined;\n\n const startedAwaiter: AsyncAwaiter<void> = asyncAwaiter<void>();\n\n const pool =\n options.pool ??\n dumbo({\n serialization: options.serialization,\n transactionOptions: {\n allowNestedTransactions: true,\n mode: 'session_based',\n },\n ...options.driver.mapToDumboOptions(options),\n });\n\n const eachBatch: BatchRecordedMessageHandlerWithoutContext<\n ConsumerMessageType,\n ReadEventMetadataWithGlobalPosition\n > = (messagesBatch) =>\n pool.withConnection(async (connection) => {\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 processor\n return await s.handle(messagesBatch, {\n connection,\n execute: connection.execute,\n });\n }),\n );\n\n return result.some(\n (r) => r.status === 'fulfilled' && r.value?.type !== 'STOP',\n )\n ? undefined\n : {\n type: 'STOP',\n };\n });\n\n const processorContext = {\n execute: undefined,\n connection: undefined,\n };\n\n const stopProcessors = () =>\n Promise.all(processors.map((p) => p.close(processorContext)));\n\n const stop = async () => {\n if (!isRunning) return;\n isRunning = false;\n if (messagePuller) {\n abortController?.abort();\n await messagePuller.stop();\n }\n await start;\n\n messagePuller = undefined;\n abortController = null;\n\n await stopProcessors();\n };\n\n const init = async (): Promise<void> => {\n if (isInitialized) return;\n\n const sqliteProcessors = processors as unknown as SQLiteProcessor[];\n\n await pool.withConnection(async (connection) => {\n for (const processor of sqliteProcessors) {\n if (processor.init) {\n await processor.init({\n ...processorContext,\n connection,\n execute: connection.execute,\n });\n }\n }\n });\n isInitialized = true;\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 init,\n reactor: <MessageType extends AnyMessage = ConsumerMessageType>(\n options: SQLiteReactorOptions<MessageType>,\n ): SQLiteProcessor<MessageType> => {\n const processor = sqliteReactor(options);\n\n processors.push(\n // TODO: change that\n processor as unknown as MessageProcessor<\n ConsumerMessageType,\n AnyRecordedMessageMetadata,\n DefaultRecord\n >,\n );\n\n return processor;\n },\n projector: <EventType extends AnyEvent = ConsumerMessageType & AnyEvent>(\n options: SQLiteProjectorOptions<EventType>,\n ): SQLiteProcessor<EventType> => {\n const processor = sqliteProjector(options);\n\n processors.push(\n // TODO: change that\n processor as unknown as MessageProcessor<\n ConsumerMessageType,\n AnyRecordedMessageMetadata,\n DefaultRecord\n >,\n );\n\n return processor;\n },\n workflowProcessor: <\n Input extends AnyEvent | AnyCommand,\n State,\n Output extends AnyEvent | AnyCommand,\n MetaDataType extends AnyRecordedMessageMetadata =\n AnyRecordedMessageMetadata,\n HandlerContext extends SQLiteProcessorHandlerContext &\n WorkflowProcessorContext = SQLiteProcessorHandlerContext &\n WorkflowProcessorContext,\n StoredMessage extends AnyEvent | AnyCommand = Output,\n >(\n processorOptions: Omit<\n SQLiteWorkflowProcessorOptions<\n Input,\n State,\n Output,\n MetaDataType,\n HandlerContext,\n StoredMessage\n >,\n 'messageStore'\n >,\n ): SQLiteProcessor<Input | Output> => {\n const messageStore = getSQLiteEventStore({\n ...options,\n pool,\n schema: { autoMigration: 'None' },\n });\n\n const processor = sqliteWorkflowProcessor({\n ...processorOptions,\n messageStore,\n });\n\n processors.push(\n // TODO: change that\n processor as unknown as MessageProcessor<\n ConsumerMessageType,\n AnyRecordedMessageMetadata,\n DefaultRecord\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\n isRunning = true;\n abortController = new AbortController();\n\n start = (async () => {\n if (!isRunning) return;\n\n try {\n messagePuller = sqliteEventStoreMessageBatchPuller({\n stopWhen: options.stopWhen,\n executor: pool.execute,\n eachBatch,\n batchSize:\n pulling?.batchSize ?? DefaultSQLiteEventStoreProcessorBatchSize,\n pullingFrequencyInMs:\n pulling?.pullingFrequencyInMs ??\n DefaultSQLiteEventStoreProcessorPullingFrequencyInMs,\n signal: abortController.signal,\n });\n\n if (!isInitialized) {\n await init();\n }\n\n const startFrom = await pool.withConnection(async (connection) =>\n zipSQLiteEventStoreMessageBatchPullerStartFrom(\n await Promise.all(\n processors.map(async (o) => {\n const result = await o.start({\n execute: connection.execute,\n connection,\n });\n\n return result;\n }),\n ),\n ),\n );\n\n await messagePuller.start({\n startFrom,\n started: startedAwaiter,\n });\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: async () => {\n await stop();\n await pool.close();\n },\n };\n};\n","import { dumbo, type Dumbo } from '@event-driven-io/dumbo';\nimport type { AnySQLiteConnection } from '@event-driven-io/dumbo/sqlite';\nimport {\n assertExpectedVersionMatchesCurrent,\n ExpectedVersionConflictError,\n JSONSerializer,\n NO_CONCURRENCY_CHECK,\n type AggregateStreamOptions,\n type AggregateStreamResult,\n type AppendToStreamOptions,\n type AppendToStreamResultWithGlobalPosition,\n type BeforeEventStoreCommitHandler,\n type Event,\n type EventStore,\n type EventStoreSession,\n type EventStoreSessionFactory,\n type JSONSerializationOptions,\n type ProjectionRegistration,\n type ReadEvent,\n type ReadEventMetadataWithGlobalPosition,\n type ReadStreamOptions,\n type ReadStreamResult,\n type StreamExistsResult,\n} from '@event-driven-io/emmett';\nimport {\n sqliteEventStoreConsumer,\n type SQLiteEventStoreConsumer,\n type SQLiteEventStoreConsumerConfig,\n} from './consumers';\nimport type {\n AnyEventStoreDriver,\n InferOptionsFromEventStoreDriver,\n} from './eventStoreDriver';\nimport {\n handleProjections,\n type SQLiteProjectionHandlerContext,\n} from './projections';\nimport {\n appendToStream,\n createEventStoreSchema,\n readStream,\n schemaSQL,\n streamExists,\n unknownTag,\n type SQLiteStreamExistsOptions,\n} from './schema';\n\nexport type EventHandler<E extends Event = Event> = (\n eventEnvelope: ReadEvent<E>,\n) => void;\n\nexport const SQLiteEventStoreDefaultStreamVersion = 0n;\n\nexport interface SQLiteEventStore\n extends\n EventStore<SQLiteReadEventMetadata>,\n EventStoreSessionFactory<SQLiteEventStore> {\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?: SQLiteEventStoreConsumerConfig<ConsumerEventType>,\n ): SQLiteEventStoreConsumer<ConsumerEventType>;\n streamExists(\n streamName: string,\n options?: SQLiteStreamExistsOptions,\n ): Promise<StreamExistsResult>;\n close(): Promise<void>;\n schema: {\n sql(): string;\n print(): void;\n migrate(): Promise<void>;\n };\n}\n\nexport type SQLiteReadEventMetadata = ReadEventMetadataWithGlobalPosition;\n\nexport type SQLiteReadEvent<EventType extends Event = Event> = ReadEvent<\n EventType,\n SQLiteReadEventMetadata\n>;\n\nexport type SQLiteEventStoreOptions<\n EventStoreDriver extends AnyEventStoreDriver = AnyEventStoreDriver,\n> = {\n driver: EventStoreDriver;\n projections?: ProjectionRegistration<\n 'inline',\n SQLiteReadEventMetadata,\n SQLiteProjectionHandlerContext\n >[];\n schema?: {\n autoMigration?: 'None' | 'CreateOrUpdate';\n };\n hooks?: {\n /**\n * This hook will be called **BEFORE** event store schema is created\n */\n onBeforeSchemaCreated?: (context: {\n connection: AnySQLiteConnection;\n }) => Promise<void> | void;\n /**\n * This hook will be called **BEFORE** events were stored in the event store.\n * @type {BeforeEventStoreCommitHandler<SQLiteEventStore, HandlerContext>}\n */\n onBeforeCommit?: BeforeEventStoreCommitHandler<\n SQLiteEventStore,\n { connection: AnySQLiteConnection }\n >;\n /**\n * This hook will be called **AFTER** event store schema was created\n */\n onAfterSchemaCreated?: () => Promise<void> | void;\n };\n} & { pool?: Dumbo } & InferOptionsFromEventStoreDriver<EventStoreDriver> &\n JSONSerializationOptions;\n\nexport const getSQLiteEventStore = <\n Driver extends AnyEventStoreDriver = AnyEventStoreDriver,\n>(\n options: SQLiteEventStoreOptions<Driver>,\n): SQLiteEventStore => {\n let autoGenerateSchema = false;\n\n const serializer = JSONSerializer.from(options);\n\n const pool =\n options.pool ??\n dumbo({\n serialization: options.serialization,\n transactionOptions: {\n allowNestedTransactions: true,\n mode: 'session_based',\n },\n ...options.driver.mapToDumboOptions(options),\n });\n let migrateSchema: Promise<void> | undefined = undefined;\n\n const inlineProjections = (options.projections ?? [])\n .filter(({ type }) => type === 'inline')\n .map(({ projection }) => projection);\n\n const onBeforeCommitHook = options.hooks?.onBeforeCommit;\n\n if (options) {\n autoGenerateSchema =\n options.schema?.autoMigration === undefined ||\n options.schema?.autoMigration !== 'None';\n }\n\n const migrate = (connection: AnySQLiteConnection): Promise<void> => {\n if (!migrateSchema) {\n migrateSchema = createEventStoreSchema(connection, {\n onBeforeSchemaCreated: async (context) => {\n for (const projection of inlineProjections) {\n if (projection.init) {\n await projection.init({\n version: projection.version ?? 1,\n registrationType: 'async',\n status: 'active',\n context: {\n execute: context.connection.execute,\n connection: context.connection,\n driverType: options.driver.driverType,\n },\n });\n }\n }\n if (options.hooks?.onBeforeSchemaCreated) {\n await options.hooks.onBeforeSchemaCreated(context);\n }\n },\n onAfterSchemaCreated: options.hooks?.onAfterSchemaCreated,\n });\n }\n\n return migrateSchema;\n };\n\n const ensureSchemaExists = (): Promise<void> => {\n if (!autoGenerateSchema) return Promise.resolve();\n\n return pool.withConnection((connection) => migrate(connection));\n };\n\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 ReadEventMetadataWithGlobalPosition,\n EventPayloadType\n >,\n ): Promise<AggregateStreamResult<State>> {\n await ensureSchemaExists();\n const { evolve, initialState, read } = options;\n\n const expectedStreamVersion = read?.expectedStreamVersion;\n\n let state = initialState();\n\n if (typeof streamName !== 'string') {\n throw new Error('Stream name is not string');\n }\n\n const result = await readStream<EventType, EventPayloadType>(\n pool.execute,\n streamName,\n { ...read, serializer: read?.serialization?.serializer ?? serializer },\n );\n\n const currentStreamVersion = result.currentStreamVersion;\n\n assertExpectedVersionMatchesCurrent(\n currentStreamVersion,\n expectedStreamVersion,\n SQLiteEventStoreDefaultStreamVersion,\n );\n\n for (const event of result.events) {\n if (!event) continue;\n state = evolve(state, event);\n }\n\n return {\n currentStreamVersion: currentStreamVersion,\n state,\n streamExists: result.streamExists,\n };\n },\n\n readStream: async <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n readOptions?: ReadStreamOptions<EventType, EventPayloadType>,\n ): Promise<\n ReadStreamResult<EventType, ReadEventMetadataWithGlobalPosition>\n > => {\n await ensureSchemaExists();\n\n return readStream<EventType, EventPayloadType>(pool.execute, streamName, {\n ...readOptions,\n serializer: options.serialization?.serializer ?? serializer,\n });\n },\n\n appendToStream: async <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n events: EventType[],\n appendOptions?: AppendToStreamOptions<EventType, EventPayloadType>,\n ): Promise<AppendToStreamResultWithGlobalPosition> => {\n await ensureSchemaExists();\n // TODO: This has to be smarter when we introduce urn-based resolution\n const [firstPart, ...rest] = streamName.split('-');\n\n const streamType = firstPart && rest.length > 0 ? firstPart : unknownTag;\n\n const appendResult = await pool.withConnection(\n (connection) =>\n appendToStream(connection, streamName, streamType, events, {\n ...(appendOptions as AppendToStreamOptions),\n onBeforeCommit: async (messages, context) => {\n if (inlineProjections.length > 0)\n await handleProjections({\n projections: inlineProjections,\n events: messages,\n execute: context.connection.execute,\n connection: context.connection,\n driverType: options.driver.driverType,\n });\n\n if (onBeforeCommitHook)\n await onBeforeCommitHook(messages, context);\n },\n }),\n { readonly: false },\n );\n\n if (!appendResult.success)\n throw new ExpectedVersionConflictError(\n -1n, //TODO: Return actual version in case of error\n appendOptions?.expectedStreamVersion ?? NO_CONCURRENCY_CHECK,\n );\n\n return {\n nextExpectedStreamVersion: appendResult.nextStreamPosition,\n lastEventGlobalPosition: appendResult.lastGlobalPosition,\n createdNewStream:\n appendResult.nextStreamPosition >= BigInt(events.length),\n };\n },\n\n async streamExists(\n streamName: string,\n options?: SQLiteStreamExistsOptions,\n ): Promise<StreamExistsResult> {\n await ensureSchemaExists();\n return streamExists(pool.execute, streamName, options);\n },\n\n consumer: <ConsumerEventType extends Event = Event>(\n consumerOptions?: SQLiteEventStoreConsumerConfig<ConsumerEventType>,\n ): SQLiteEventStoreConsumer<ConsumerEventType> =>\n sqliteEventStoreConsumer<ConsumerEventType, Driver>({\n ...(options ?? {}),\n ...(consumerOptions ?? {}),\n pool,\n }),\n\n async withSession<T = unknown>(\n callback: (session: EventStoreSession<SQLiteEventStore>) => Promise<T>,\n ): Promise<T> {\n return await pool.withConnection(async (connection) => {\n const sessionStore = getSQLiteEventStore({\n ...options,\n pool: dumbo({\n ...options.driver.mapToDumboOptions(options),\n connection,\n serialization: options.serialization,\n }),\n transactionOptions: {\n allowNestedTransactions: true,\n mode: 'session_based',\n },\n schema: {\n ...options.schema,\n autoMigration: 'None',\n },\n serialization: options.serialization,\n });\n\n await ensureSchemaExists();\n\n return callback({\n eventStore: sessionStore,\n close: () => Promise.resolve(),\n });\n });\n },\n\n close: () => pool.close(),\n schema: {\n sql: () => schemaSQL.join(''),\n print: () => console.log(schemaSQL.join('')),\n migrate: () => pool.withConnection(migrate),\n },\n };\n};\n","import { SQL, type SQLExecutor } from '@event-driven-io/dumbo';\nimport type { JSONSerializer } from '@event-driven-io/emmett';\nimport {\n bigIntProcessorCheckpoint,\n upcastRecordedMessage,\n type CombinedReadEventMetadata,\n type Event,\n type ReadEvent,\n type ReadEventMetadataWithGlobalPosition,\n type ReadStreamOptions,\n type ReadStreamResult,\n} from '@event-driven-io/emmett';\nimport { SQLiteEventStoreDefaultStreamVersion } from '../SQLiteEventStore';\nimport { defaultTag, messagesTable } from './typing';\nconst { identifier } = SQL;\n\ntype ReadStreamSqlResult = {\n stream_position: string;\n message_data: string;\n message_metadata: string;\n message_schema_version: string;\n message_type: string;\n message_id: string;\n global_position: string;\n created: string;\n};\n\nexport const readStream = async <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n>(\n execute: SQLExecutor,\n streamId: string,\n options: ReadStreamOptions<EventType, EventPayloadType> & {\n partition?: string;\n serializer: JSONSerializer;\n },\n): Promise<\n ReadStreamResult<EventType, ReadEventMetadataWithGlobalPosition>\n> => {\n const { serializer } = options;\n const fromCondition: SQL = options.from\n ? SQL`AND stream_position >= ${options.from}`\n : SQL.EMPTY;\n\n const to = Number(\n options?.to ??\n (options?.maxCount ? (options.from ?? 0n) + options.maxCount : NaN),\n );\n\n const toCondition: SQL = !isNaN(to)\n ? SQL`AND stream_position <= ${to}`\n : SQL.EMPTY;\n\n const { rows: results } = await execute.query<ReadStreamSqlResult>(\n SQL`SELECT stream_id, stream_position, global_position, message_data, message_metadata, message_schema_version, message_type, message_id\n FROM ${identifier(messagesTable.name)}\n WHERE stream_id = ${streamId} AND partition = ${options?.partition ?? defaultTag} AND is_archived = FALSE ${fromCondition} ${toCondition}\n ORDER BY stream_position ASC`,\n );\n\n const messages: ReadEvent<EventType, ReadEventMetadataWithGlobalPosition>[] =\n results.map((row) => {\n const rawEvent = {\n type: row.message_type,\n data: serializer.deserialize(row.message_data),\n metadata: serializer.deserialize(row.message_metadata),\n } as unknown as EventPayloadType;\n\n const metadata: ReadEventMetadataWithGlobalPosition = {\n ...('metadata' in rawEvent ? (rawEvent.metadata ?? {}) : {}),\n messageId: row.message_id,\n streamName: streamId,\n streamPosition: BigInt(row.stream_position),\n globalPosition: BigInt(row.global_position),\n checkpoint: bigIntProcessorCheckpoint(BigInt(row.global_position)),\n };\n\n const event = {\n ...rawEvent,\n kind: 'Event',\n metadata: metadata as CombinedReadEventMetadata<\n EventPayloadType,\n ReadEventMetadataWithGlobalPosition\n >,\n };\n\n return upcastRecordedMessage(event, options?.schema?.versioning);\n });\n\n return messages.length > 0\n ? {\n currentStreamVersion:\n messages[messages.length - 1]!.metadata.streamPosition,\n events: messages,\n streamExists: true,\n }\n : {\n currentStreamVersion: SQLiteEventStoreDefaultStreamVersion,\n events: [],\n streamExists: false,\n };\n};\n","import {\n DumboError,\n singleOrNull,\n SQL,\n UniqueConstraintError,\n type SQLExecutor,\n} from '@event-driven-io/dumbo';\nimport type { ProcessorCheckpoint } from '@event-driven-io/emmett';\nimport { defaultTag, processorsTable, unknownTag } from './typing';\n\nconst { identifier } = SQL;\n\n// for more infos see the postgresql stored procedure version\nasync function storeSubscriptionCheckpointSQLite(\n execute: SQLExecutor,\n processorId: string,\n version: number,\n position: ProcessorCheckpoint | null,\n checkPosition: ProcessorCheckpoint | null,\n partition: string,\n processorInstanceId?: string,\n): Promise<0 | 1 | 2> {\n processorInstanceId ??= unknownTag;\n if (checkPosition !== null) {\n const updateResult = await execute.command(\n SQL`\n UPDATE ${identifier(processorsTable.name)}\n SET \n last_processed_checkpoint = ${position},\n processor_instance_id = ${processorInstanceId}\n WHERE processor_id = ${processorId} \n AND last_processed_checkpoint = ${checkPosition} \n AND partition = ${partition}\n `,\n );\n if (updateResult.rowCount && updateResult.rowCount > 0) {\n return 1;\n }\n const current_position = await singleOrNull(\n execute.query<{ last_processed_checkpoint: string }>(\n SQL`\n SELECT last_processed_checkpoint FROM ${identifier(processorsTable.name)} \n WHERE processor_id = ${processorId} AND partition = ${partition}`,\n ),\n );\n\n const currentPosition =\n current_position && current_position?.last_processed_checkpoint !== null\n ? current_position.last_processed_checkpoint\n : null;\n\n if (currentPosition === position) {\n return 0;\n } else if (\n position !== null &&\n currentPosition !== null &&\n currentPosition > position\n ) {\n return 2;\n } else {\n return 2;\n }\n } else {\n try {\n await execute.command(\n SQL`INSERT INTO ${identifier(processorsTable.name)} (processor_id, version, last_processed_checkpoint, partition, processor_instance_id) \n VALUES (${processorId}, ${version}, ${position}, ${partition}, ${processorInstanceId})`,\n );\n return 1;\n } catch (err) {\n if (\n !DumboError.isInstanceOf(err, {\n errorType: UniqueConstraintError.ErrorType,\n })\n ) {\n throw err;\n }\n\n const current = await singleOrNull(\n execute.query<{ last_processed_checkpoint: string }>(\n SQL`\n SELECT last_processed_checkpoint FROM ${identifier(processorsTable.name)} \n WHERE processor_id = ${processorId} AND partition = ${partition}`,\n ),\n );\n const currentPosition =\n current && current?.last_processed_checkpoint !== null\n ? BigInt(current.last_processed_checkpoint)\n : null;\n\n if (currentPosition === position) {\n return 0;\n } else {\n return 2;\n }\n }\n }\n}\n\nexport type StoreProcessorCheckpointResult =\n | {\n success: true;\n newCheckpoint: ProcessorCheckpoint | null;\n }\n | { success: false; reason: 'IGNORED' | 'MISMATCH' };\n\nexport async function storeProcessorCheckpoint(\n execute: SQLExecutor,\n options: {\n processorId: string;\n version: number | undefined;\n newCheckpoint: ProcessorCheckpoint | null;\n lastProcessedCheckpoint: ProcessorCheckpoint | null;\n partition?: string;\n processorInstanceId?: string;\n },\n): Promise<StoreProcessorCheckpointResult> {\n try {\n const result = await storeSubscriptionCheckpointSQLite(\n execute,\n options.processorId,\n options.version ?? 1,\n options.newCheckpoint,\n options.lastProcessedCheckpoint,\n options.partition ?? defaultTag,\n );\n\n return result === 1\n ? { success: true, newCheckpoint: options.newCheckpoint }\n : { success: false, reason: result === 0 ? 'IGNORED' : 'MISMATCH' };\n } catch (error) {\n console.log(error);\n throw error;\n }\n}\n","import { exists, SQL, type SQLExecutor } from '@event-driven-io/dumbo';\nimport type { StreamExistsResult } from '@event-driven-io/emmett';\nimport { defaultTag, streamsTable } from './typing';\n\nexport type SQLiteStreamExistsOptions = { partition: string };\n\ntype StreamExistsSqlResult = { exists: boolean };\n\nexport const streamExists = (\n execute: SQLExecutor,\n streamId: string,\n options?: SQLiteStreamExistsOptions,\n): Promise<StreamExistsResult> =>\n exists(\n execute.query<StreamExistsSqlResult>(\n SQL`SELECT EXISTS (\n SELECT 1\n from ${SQL.identifier(streamsTable.name)}\n WHERE stream_id = ${streamId} AND partition = ${options?.partition ?? defaultTag} AND is_archived = FALSE) as exists\n `,\n ),\n );\n","import { SQL, type AnyDatabaseTransaction } from '@event-driven-io/dumbo';\nimport type { AnySQLiteConnection } from '@event-driven-io/dumbo/sqlite';\nimport type { SQLiteEventStoreOptions } from '../SQLiteEventStore';\nimport { migration_0_42_0_FromSubscriptionsToProcessors } from './migrations';\nimport {\n globalTag,\n messagesTable,\n processorsTable,\n projectionsTable,\n streamsTable,\n unknownTag,\n} from './typing';\n\nconst { identifier, plain } = SQL;\n\nexport const streamsTableSQL = SQL`CREATE TABLE IF NOT EXISTS ${identifier(streamsTable.name)}(\n stream_id TEXT NOT NULL,\n stream_position BIGINT NOT NULL DEFAULT 0,\n partition TEXT NOT NULL DEFAULT '${plain(globalTag)}',\n stream_type TEXT NOT NULL,\n stream_metadata JSONB NOT NULL,\n is_archived BOOLEAN NOT NULL DEFAULT FALSE,\n PRIMARY KEY (stream_id, partition, is_archived),\n UNIQUE (stream_id, partition, is_archived)\n );`;\n\nexport const messagesTableSQL = SQL`CREATE TABLE IF NOT EXISTS ${identifier(messagesTable.name)}(\n stream_id TEXT NOT NULL,\n stream_position BIGINT NOT NULL,\n partition TEXT NOT NULL DEFAULT '${plain(globalTag)}',\n message_kind CHAR(1) NOT NULL DEFAULT 'E',\n message_data JSONB NOT NULL,\n message_metadata JSONB NOT NULL,\n message_schema_version TEXT NOT NULL,\n message_type TEXT NOT NULL,\n message_id TEXT NOT NULL,\n is_archived BOOLEAN NOT NULL DEFAULT FALSE,\n global_position INTEGER PRIMARY KEY,\n created DATETIME DEFAULT CURRENT_TIMESTAMP,\n UNIQUE (stream_id, stream_position, partition, is_archived)\n ); \n`;\n\nexport const processorsTableSQL = SQL`\n CREATE TABLE IF NOT EXISTS ${SQL.identifier(processorsTable.name)}(\n processor_id TEXT NOT NULL,\n version INTEGER NOT NULL DEFAULT 1,\n partition TEXT NOT NULL DEFAULT '${plain(globalTag)}',\n status TEXT NOT NULL DEFAULT 'stopped',\n last_processed_checkpoint TEXT NOT NULL,\n processor_instance_id TEXT DEFAULT '${plain(unknownTag)}',\n PRIMARY KEY (processor_id, partition, version)\n );\n`;\n\nexport const projectionsTableSQL = SQL`\n CREATE TABLE IF NOT EXISTS ${SQL.identifier(projectionsTable.name)}(\n name TEXT NOT NULL,\n version INTEGER NOT NULL DEFAULT 1,\n partition TEXT NOT NULL DEFAULT '${plain(globalTag)}',\n type CHAR(1) NOT NULL,\n kind TEXT NOT NULL,\n status TEXT NOT NULL,\n definition JSONB NOT NULL DEFAULT '{}',\n PRIMARY KEY (name, partition, version)\n );\n`;\n\nexport const schemaSQL: SQL[] = [\n streamsTableSQL,\n messagesTableSQL,\n processorsTableSQL,\n projectionsTableSQL,\n];\n\nexport type CreateEventStoreSchemaOptions = {\n dryRun?: boolean | undefined;\n ignoreMigrationHashMismatch?: boolean | undefined;\n migrationTimeoutMs?: number | undefined;\n};\n\nexport type EventStoreSchemaMigrationOptions = {\n migrationOptions?: CreateEventStoreSchemaOptions;\n};\n\nexport const createEventStoreSchema = async (\n pool: AnySQLiteConnection,\n hooks?: SQLiteEventStoreOptions['hooks'],\n): Promise<void> => {\n await pool.withTransaction(async (tx: AnyDatabaseTransaction) => {\n await migration_0_42_0_FromSubscriptionsToProcessors(tx.execute);\n\n if (hooks?.onBeforeSchemaCreated) {\n await hooks.onBeforeSchemaCreated({\n connection: tx.connection as AnySQLiteConnection,\n });\n }\n await tx.execute.batchCommand(schemaSQL);\n\n if (hooks?.onAfterSchemaCreated) {\n await hooks.onAfterSchemaCreated();\n }\n });\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["AssertionError","SQL","DumboError","UniqueConstraintError","BatchCommandNoChangesError","NO_CONCURRENCY_CHECK","STREAM_DOES_NOT_EXIST","STREAM_EXISTS","ExpectedVersionConflictError","identifier","SQL","identifier","plain","SQL","identifier","SQL","identifier","SQL","identifier","JSONSerializer","EmmettError","defaultProcessorVersion","defaultProcessorPartition","EmmettError","JSONSerializer","ExpectedVersionConflictError","NO_CONCURRENCY_CHECK","SQL","identifier","SQL","identifier","DumboError","UniqueConstraintError","SQL","SQL"],"sources":["../src/eventStore/projections/pongo/pongoProjections.ts","../src/eventStore/projections/pongo/pongoProjectionSpec.ts","../src/eventStore/projections/sqliteProjection.ts","../src/eventStore/projections/sqliteProjectionSpec.ts","../src/eventStore/schema/typing.ts","../src/eventStore/schema/appendToStream.ts","../src/eventStore/schema/migrations/0_41_0/0_41_0.snapshot.ts","../src/eventStore/schema/migrations/0_42_0/0_42_0.migration.ts","../src/eventStore/schema/migrations/0_42_0/0_42_0.snapshot.ts","../src/eventStore/schema/readLastMessageGlobalPosition.ts","../src/eventStore/schema/readMessagesBatch.ts","../src/eventStore/schema/readProcessorCheckpoint.ts","../src/eventStore/consumers/messageBatchProcessing/index.ts","../src/eventStore/consumers/sqliteCheckpointer.ts","../src/eventStore/consumers/sqliteProcessor.ts","../src/eventStore/consumers/sqliteEventStoreConsumer.ts","../src/eventStore/SQLiteEventStore.ts","../src/eventStore/schema/readStream.ts","../src/eventStore/schema/storeProcessorCheckpoint.ts","../src/eventStore/schema/streamExists.ts","../src/eventStore/schema/tables.ts"],"sourcesContent":["import {\n reduceAsync,\n type CanHandle,\n type Event,\n type EventStoreReadSchemaOptions,\n type JSONSerializationOptions,\n type ReadEvent,\n type TruncateProjection,\n} from '@event-driven-io/emmett';\nimport {\n pongoClient,\n type PongoClient,\n type PongoDBCollectionOptions,\n type PongoDocument,\n} from '@event-driven-io/pongo';\nimport {\n sqliteProjection,\n type SQLiteProjectionDefinition,\n type SQLiteProjectionHandlerContext,\n} from '..';\nimport type { SQLiteReadEventMetadata } from '../../SQLiteEventStore';\n\nexport type PongoProjectionHandlerContext = SQLiteProjectionHandlerContext & {\n pongo: PongoClient;\n};\n\nexport type PongoWithNotNullDocumentEvolve<\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n> =\n | ((\n document: Document,\n event: ReadEvent<EventType, EventMetaDataType>,\n ) => Document | null)\n | ((\n document: Document,\n event: ReadEvent<EventType>,\n ) => Promise<Document | null>);\n\nexport type PongoWithNullableDocumentEvolve<\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n> =\n | ((\n document: Document | null,\n event: ReadEvent<EventType, EventMetaDataType>,\n ) => Document | null)\n | ((\n document: Document | null,\n event: ReadEvent<EventType>,\n ) => Promise<Document | null>);\n\nexport type PongoDocumentEvolve<\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n> =\n | PongoWithNotNullDocumentEvolve<Document, EventType, EventMetaDataType>\n | PongoWithNullableDocumentEvolve<Document, EventType, EventMetaDataType>;\n\nexport type PongoProjectionOptions<\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n> = {\n name: string;\n kind?: string;\n version?: number;\n handle: (\n events: ReadEvent<EventType, SQLiteReadEventMetadata>[],\n context: PongoProjectionHandlerContext,\n ) => Promise<void>;\n canHandle: CanHandle<EventType>;\n truncate?: TruncateProjection<PongoProjectionHandlerContext>;\n init?: (context: PongoProjectionHandlerContext) => void | Promise<void>;\n eventsOptions?: {\n schema?: EventStoreReadSchemaOptions<EventType, EventPayloadType>;\n };\n} & JSONSerializationOptions;\n\nexport const pongoProjection = <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n>({\n name,\n kind,\n version,\n truncate,\n handle,\n canHandle,\n eventsOptions,\n}: PongoProjectionOptions<\n EventType,\n EventPayloadType\n>): SQLiteProjectionDefinition<EventType, EventPayloadType> =>\n sqliteProjection<EventType, EventPayloadType>({\n name,\n version,\n kind: kind ?? 'emt:projections:postgresql:pongo:generic',\n canHandle,\n eventsOptions,\n handle: async (events, context) => {\n const { connection } = context;\n const driver = (await pongoDriverRegistry.tryResolve(\n context.driverType,\n ))!;\n const pongo = pongoClient({\n driver,\n connectionOptions: { connection },\n });\n try {\n await handle(events, {\n ...context,\n pongo,\n });\n } finally {\n await pongo.close();\n }\n },\n truncate: truncate\n ? async (context) => {\n const { connection } = context;\n const driver = (await pongoDriverRegistry.tryResolve(\n context.driverType,\n ))!;\n const pongo = pongoClient({\n driver,\n connectionOptions: { connection },\n });\n try {\n await truncate({\n ...context,\n pongo,\n });\n } finally {\n await pongo.close();\n }\n }\n : undefined,\n });\n\nexport type PongoMultiStreamProjectionOptions<\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n EventPayloadType extends Event = EventType,\n DocumentPayload extends PongoDocument = Document,\n> = {\n kind?: string;\n canHandle: CanHandle<EventType>;\n version?: number;\n collectionName: string;\n collectionOptions?: PongoDBCollectionOptions<Document, DocumentPayload>;\n eventsOptions?: {\n schema?: EventStoreReadSchemaOptions<EventType, EventPayloadType>;\n };\n getDocumentId: (event: ReadEvent<EventType>) => string;\n} & (\n | {\n evolve: PongoWithNullableDocumentEvolve<\n Document,\n EventType,\n EventMetaDataType\n >;\n }\n | {\n evolve: PongoWithNotNullDocumentEvolve<\n Document,\n EventType,\n EventMetaDataType\n >;\n initialState: () => Document;\n }\n) &\n JSONSerializationOptions;\n\nexport const pongoMultiStreamProjection = <\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n EventPayloadType extends Event = EventType,\n>(\n options: PongoMultiStreamProjectionOptions<\n Document,\n EventType,\n EventMetaDataType,\n EventPayloadType\n >,\n): SQLiteProjectionDefinition<EventType, EventPayloadType> => {\n const { collectionName, getDocumentId, canHandle } = options;\n const collectionNameWithVersion =\n options.version && options.version > 0\n ? `${collectionName}_v${options.version}`\n : collectionName;\n\n return pongoProjection({\n name: collectionNameWithVersion,\n version: options.version,\n kind: options.kind ?? 'emt:projections:postgresql:pongo:multi_stream',\n eventsOptions: options.eventsOptions,\n handle: async (events, { pongo }) => {\n const collection = pongo\n .db()\n .collection<Document>(\n collectionNameWithVersion,\n options.collectionOptions,\n );\n\n const eventsByDocumentId = events\n .map((event) => {\n const documentId = getDocumentId(event);\n\n return {\n documentId,\n event: event as ReadEvent<EventType, EventMetaDataType>,\n };\n })\n .reduce((acc, { documentId, event }) => {\n if (!acc.has(documentId)) {\n acc.set(documentId, []);\n }\n acc.get(documentId)!.push(event);\n return acc;\n }, new Map<string, ReadEvent<EventType, EventMetaDataType>[]>());\n\n await collection.handle(\n [...eventsByDocumentId.keys()],\n (document, id) => {\n const events = eventsByDocumentId.get(id)!;\n\n return reduceAsync(\n events,\n async (acc, event) => await options.evolve(acc!, event),\n document ??\n ('initialState' in options ? options.initialState() : null),\n );\n },\n );\n },\n canHandle,\n truncate: async (context) => {\n const { connection } = context;\n const driver = (await pongoDriverRegistry.tryResolve(\n context.driverType,\n ))!;\n const pongo = pongoClient({\n driver,\n connectionOptions: { connection },\n });\n\n try {\n await pongo\n .db()\n .collection<Document>(\n collectionNameWithVersion,\n options.collectionOptions,\n )\n .deleteMany();\n } finally {\n await pongo.close();\n }\n },\n init: async (context) => {\n const { connection } = context;\n const driver = (await pongoDriverRegistry.tryResolve(\n context.driverType,\n ))!;\n const pongo = pongoClient({\n connectionOptions: { connection },\n driver,\n });\n\n try {\n await pongo\n .db()\n .collection<Document>(\n collectionNameWithVersion,\n options.collectionOptions,\n )\n .schema.migrate(); // TODO: ADD migration optionscontext.migrationOptions);\n } finally {\n await pongo.close();\n }\n },\n });\n};\n\nexport type PongoSingleStreamProjectionOptions<\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n EventPayloadType extends Event = EventType,\n DocumentPayload extends PongoDocument = Document,\n> = {\n canHandle: CanHandle<EventType>;\n getDocumentId?: (event: ReadEvent<EventType>) => string;\n version?: number;\n collectionName: string;\n collectionOptions?: PongoDBCollectionOptions<Document, DocumentPayload>;\n eventsOptions?: {\n schema?: EventStoreReadSchemaOptions<EventType, EventPayloadType>;\n };\n} & (\n | {\n evolve: PongoWithNullableDocumentEvolve<\n Document,\n EventType,\n EventMetaDataType\n >;\n }\n | {\n evolve: PongoWithNotNullDocumentEvolve<\n Document,\n EventType,\n EventMetaDataType\n >;\n initialState: () => Document;\n }\n) &\n JSONSerializationOptions;\n\nexport const pongoSingleStreamProjection = <\n Document extends PongoDocument,\n EventType extends Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n EventPayloadType extends Event = EventType,\n>(\n options: PongoSingleStreamProjectionOptions<\n Document,\n EventType,\n EventMetaDataType,\n EventPayloadType\n >,\n): SQLiteProjectionDefinition<EventType, EventPayloadType> => {\n return pongoMultiStreamProjection<\n Document,\n EventType,\n EventMetaDataType,\n EventPayloadType\n >({\n ...options,\n kind: 'emt:projections:postgresql:pongo:single_stream',\n getDocumentId:\n options.getDocumentId ?? ((event) => event.metadata.streamName),\n });\n};\n","import type { DatabaseDriverType } from '@event-driven-io/dumbo';\nimport type { AnySQLiteConnection } from '@event-driven-io/dumbo/sqlite';\nimport {\n assertDeepEqual,\n assertEqual,\n assertIsNotNull,\n assertIsNull,\n assertThatArray,\n} from '@event-driven-io/emmett';\nimport {\n pongoClient,\n type PongoCollection,\n type PongoDocument,\n type PongoFilter,\n type WithId,\n} from '@event-driven-io/pongo';\nimport type { SQLiteProjectionAssert } from '..';\n\nexport type PongoAssertOptions = {\n inCollection: string;\n inDatabase?: string;\n};\n\nconst withCollection = async (\n handle: (collection: PongoCollection<PongoDocument>) => Promise<void>,\n options: {\n connection: AnySQLiteConnection;\n } & PongoAssertOptions,\n) => {\n const { connection, inDatabase, inCollection } = options;\n\n const driver = (await pongoDriverRegistry.tryResolve(\n connection.driverType as DatabaseDriverType,\n ))!;\n const pongo = pongoClient({\n connectionOptions: { connection },\n driver,\n });\n try {\n const collection = pongo.db(inDatabase).collection(inCollection);\n\n return handle(collection);\n } finally {\n await pongo.close();\n }\n};\n\nconst withoutIdAndVersion = <Doc extends PongoDocument | WithId<PongoDocument>>(\n doc: Doc,\n) => {\n const { _id, _version, ...without } = doc;\n\n return without;\n};\n\nconst assertDocumentsEqual = <\n Doc extends PongoDocument | WithId<PongoDocument>,\n>(\n actual: PongoDocument,\n expected: Doc,\n) => {\n if ('_id' in expected)\n assertEqual(\n expected._id,\n actual._id,\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n `Document ids are not matching! Expected: ${expected._id}, Actual: ${actual._id}`,\n );\n\n return assertDeepEqual(\n withoutIdAndVersion(actual),\n withoutIdAndVersion(expected),\n );\n};\n\ntype FilterOrId<Doc extends PongoDocument | WithId<PongoDocument>> =\n | { withId: string }\n | {\n matchingFilter: PongoFilter<Doc>;\n };\n\nexport const documentExists =\n <Doc extends PongoDocument | WithId<PongoDocument>>(\n document: Doc,\n options: PongoAssertOptions & FilterOrId<Doc>,\n ): SQLiteProjectionAssert =>\n (assertOptions) =>\n withCollection(\n async (collection) => {\n const result = await collection.findOne(\n 'withId' in options\n ? { _id: options.withId }\n : options.matchingFilter,\n );\n\n assertIsNotNull(result);\n\n assertDocumentsEqual(result, document);\n },\n { ...options, ...assertOptions },\n );\n\nexport const documentsAreTheSame =\n <Doc extends PongoDocument | WithId<PongoDocument>>(\n documents: Doc[],\n options: PongoAssertOptions & FilterOrId<Doc>,\n ): SQLiteProjectionAssert =>\n (assertOptions) =>\n withCollection(\n async (collection) => {\n const result = await collection.find(\n 'withId' in options\n ? { _id: options.withId }\n : options.matchingFilter,\n );\n\n assertEqual(\n documents.length,\n result.length,\n 'Different Documents Count than expected',\n );\n\n for (let i = 0; i < documents.length; i++) {\n assertThatArray(result as Doc[]).contains(documents[i]!);\n }\n },\n { ...options, ...assertOptions },\n );\n\nexport const documentsMatchingHaveCount =\n <Doc extends PongoDocument | WithId<PongoDocument>>(\n expectedCount: number,\n options: PongoAssertOptions & FilterOrId<Doc>,\n ): SQLiteProjectionAssert =>\n (assertOptions) =>\n withCollection(\n async (collection) => {\n const result = await collection.find(\n 'withId' in options\n ? { _id: options.withId }\n : options.matchingFilter,\n );\n\n assertEqual(\n expectedCount,\n result.length,\n 'Different Documents Count than expected',\n );\n },\n { ...options, ...assertOptions },\n );\n\nexport const documentMatchingExists =\n <Doc extends PongoDocument | WithId<PongoDocument>>(\n options: PongoAssertOptions & FilterOrId<Doc>,\n ): SQLiteProjectionAssert =>\n (assertOptions) =>\n withCollection(\n async (collection) => {\n const result = await collection.find(\n 'withId' in options\n ? { _id: options.withId }\n : options.matchingFilter,\n );\n\n assertThatArray(result).isNotEmpty();\n },\n { ...options, ...assertOptions },\n );\n\nexport const documentDoesNotExist =\n <Doc extends PongoDocument | WithId<PongoDocument>>(\n options: PongoAssertOptions & FilterOrId<Doc>,\n ): SQLiteProjectionAssert =>\n (assertOptions) =>\n withCollection(\n async (collection) => {\n const result = await collection.findOne(\n 'withId' in options\n ? { _id: options.withId }\n : options.matchingFilter,\n );\n\n assertIsNull(result);\n },\n { ...options, ...assertOptions },\n );\n\nexport const expectPongoDocuments = {\n fromCollection: <Doc extends PongoDocument | WithId<PongoDocument>>(\n collectionName: string,\n ) => {\n return {\n withId: (id: string) => {\n return {\n toBeEqual: (document: Doc) =>\n documentExists(document, {\n withId: id,\n inCollection: collectionName,\n }),\n toExist: () =>\n documentMatchingExists({\n withId: id,\n inCollection: collectionName,\n }),\n notToExist: () =>\n documentDoesNotExist({\n withId: id,\n inCollection: collectionName,\n }),\n };\n },\n matching: <Doc extends PongoDocument | WithId<PongoDocument>>(\n filter: PongoFilter<Doc>,\n ) => {\n return {\n toBeTheSame: (documents: Doc[]) =>\n documentsAreTheSame<Doc>(documents, {\n matchingFilter: filter,\n inCollection: collectionName,\n }),\n toHaveCount: (expectedCount: number) =>\n documentsMatchingHaveCount(expectedCount, {\n matchingFilter: filter,\n inCollection: collectionName,\n }),\n toExist: () =>\n documentMatchingExists({\n matchingFilter: filter,\n inCollection: collectionName,\n }),\n notToExist: () =>\n documentDoesNotExist({\n matchingFilter: filter,\n inCollection: collectionName,\n }),\n };\n },\n };\n },\n};\n","import type {\n DatabaseDriverType,\n SQL,\n SQLExecutor,\n} from '@event-driven-io/dumbo';\nimport type { AnySQLiteConnection } from '@event-driven-io/dumbo/sqlite';\nimport {\n projection,\n type CanHandle,\n type Event,\n type EventStoreReadSchemaOptions,\n type JSONSerializationOptions,\n type ProjectionDefinition,\n type ProjectionHandler,\n type ProjectionInitOptions,\n type ReadEvent,\n} from '@event-driven-io/emmett';\nimport type { SQLiteReadEventMetadata } from '../SQLiteEventStore';\n\nexport type SQLiteProjectionHandlerContext = {\n execute: SQLExecutor;\n connection: AnySQLiteConnection;\n driverType: DatabaseDriverType;\n};\n\nexport type SQLiteProjectionHandler<\n EventType extends Event = Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n> = ProjectionHandler<\n EventType,\n EventMetaDataType,\n SQLiteProjectionHandlerContext\n>;\n\nexport type SQLiteProjectionDefinition<\n EventType extends Event = Event,\n EventPayloadType extends Event = EventType,\n> = ProjectionDefinition<\n EventType,\n SQLiteReadEventMetadata,\n SQLiteProjectionHandlerContext,\n EventPayloadType\n>;\n\nexport type SQLiteProjectionHandlerOptions<EventType extends Event = Event> = {\n events: ReadEvent<EventType, SQLiteReadEventMetadata>[];\n projections: SQLiteProjectionDefinition<EventType>[];\n} & SQLiteProjectionHandlerContext;\n\nexport const handleProjections = async <EventType extends Event = Event>(\n options: SQLiteProjectionHandlerOptions<EventType>,\n): Promise<void> => {\n const {\n projections: allProjections,\n events,\n connection,\n execute,\n driverType,\n } = options;\n\n const eventTypes = events.map((e) => e.type);\n\n for (const projection of allProjections) {\n if (!projection.canHandle.some((type) => eventTypes.includes(type))) {\n continue;\n }\n await projection.handle(events, {\n connection,\n execute,\n driverType,\n });\n }\n};\n\nexport const sqliteProjection = <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n>(\n definition: SQLiteProjectionDefinition<EventType, EventPayloadType>,\n): SQLiteProjectionDefinition<EventType, EventPayloadType> =>\n projection<\n EventType,\n SQLiteReadEventMetadata,\n SQLiteProjectionHandlerContext,\n EventPayloadType\n >(definition);\n\nexport type SQLiteRawBatchSQLProjection<\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n> = {\n name: string;\n kind?: string;\n version?: number;\n evolve: (\n events: EventType[],\n context: SQLiteProjectionHandlerContext,\n ) => Promise<SQL[]> | SQL[];\n canHandle: CanHandle<EventType>;\n init?: (\n context: ProjectionInitOptions<SQLiteProjectionHandlerContext>,\n ) => void | Promise<void> | SQL | Promise<SQL> | Promise<SQL[]> | SQL[];\n eventsOptions?: {\n schema?: EventStoreReadSchemaOptions<EventType, EventPayloadType>;\n };\n} & JSONSerializationOptions;\n\nexport const sqliteRawBatchSQLProjection = <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n>(\n options: SQLiteRawBatchSQLProjection<EventType, EventPayloadType>,\n): SQLiteProjectionDefinition<EventType, EventPayloadType> =>\n sqliteProjection<EventType, EventPayloadType>({\n name: options.name,\n kind: options.kind ?? 'emt:projections:sqlite:raw_sql:batch',\n version: options.version,\n canHandle: options.canHandle,\n eventsOptions: options.eventsOptions,\n handle: async (events, context) => {\n const sqls: SQL[] = await options.evolve(events, context);\n\n await context.execute.batchCommand(sqls);\n },\n init: async (initOptions) => {\n const initSQL = options.init\n ? await options.init(initOptions)\n : undefined;\n\n if (initSQL) {\n if (Array.isArray(initSQL)) {\n await initOptions.context.execute.batchCommand(initSQL);\n } else {\n await initOptions.context.execute.command(initSQL);\n }\n }\n },\n });\n\nexport type SQLiteRawSQLProjection<\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n> = {\n name: string;\n kind?: string;\n version?: number;\n evolve: (\n events: EventType,\n context: SQLiteProjectionHandlerContext,\n ) => Promise<SQL[]> | SQL[] | Promise<SQL> | SQL;\n canHandle: CanHandle<EventType>;\n init?: (\n context: ProjectionInitOptions<SQLiteProjectionHandlerContext>,\n ) => void | Promise<void> | SQL | Promise<SQL> | Promise<SQL[]> | SQL[];\n eventsOptions?: {\n schema?: EventStoreReadSchemaOptions<EventType, EventPayloadType>;\n };\n} & JSONSerializationOptions;\n\nexport const sqliteRawSQLProjection = <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n>(\n options: SQLiteRawSQLProjection<EventType, EventPayloadType>,\n): SQLiteProjectionDefinition<EventType, EventPayloadType> => {\n const { evolve, kind, ...rest } = options;\n return sqliteRawBatchSQLProjection<EventType, EventPayloadType>({\n kind: kind ?? 'emt:projections:sqlite:raw:_sql:single',\n ...rest,\n evolve: async (events, context) => {\n const sqls: SQL[] = [];\n\n for (const event of events) {\n const pendingSqls = await evolve(event, context);\n if (Array.isArray(pendingSqls)) {\n sqls.push(...pendingSqls);\n } else {\n sqls.push(pendingSqls);\n }\n }\n return sqls;\n },\n });\n};\n","import type { SQL } from '@event-driven-io/dumbo';\nimport { dumbo, type Dumbo, type QueryResultRow } from '@event-driven-io/dumbo';\nimport type { AnySQLiteConnection } from '@event-driven-io/dumbo/sqlite';\nimport {\n assertFails,\n AssertionError,\n assertThatArray,\n assertTrue,\n bigIntProcessorCheckpoint,\n isErrorConstructor,\n type CombinedReadEventMetadata,\n type Event,\n type JSONSerializationOptions,\n type ReadEvent,\n type ThenThrows,\n} from '@event-driven-io/emmett';\nimport { v4 as uuid } from 'uuid';\nimport type {\n AnyEventStoreDriver,\n InferOptionsFromEventStoreDriver,\n} from '../eventStoreDriver';\nimport type { SQLiteReadEventMetadata } from '../SQLiteEventStore';\nimport {\n handleProjections,\n type SQLiteProjectionDefinition,\n} from './sqliteProjection';\n\nexport type SQLiteProjectionSpecEvent<\n EventType extends Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n> = EventType & {\n metadata?: Partial<EventMetaDataType>;\n};\n\nexport type SQLiteProjectionSpecWhenOptions = {\n numberOfTimes: number;\n};\n\nexport type SQLiteProjectionSpec<EventType extends Event> = (\n givenEvents: SQLiteProjectionSpecEvent<EventType>[],\n) => {\n when: (\n events: SQLiteProjectionSpecEvent<EventType>[],\n options?: SQLiteProjectionSpecWhenOptions,\n ) => {\n then: (assert: SQLiteProjectionAssert, message?: string) => Promise<void>;\n thenThrows: <ErrorType extends Error = Error>(\n ...args: Parameters<ThenThrows<ErrorType>>\n ) => Promise<void>;\n };\n};\n\nexport type SQLiteProjectionAssert = (options: {\n connection: AnySQLiteConnection;\n}) => Promise<void | boolean>;\n\nexport type SQLiteProjectionSpecOptions<\n EventType extends Event,\n Driver extends AnyEventStoreDriver = AnyEventStoreDriver,\n> = {\n projection: SQLiteProjectionDefinition<EventType>;\n\n driver: Driver;\n pool?: Dumbo;\n} & InferOptionsFromEventStoreDriver<Driver> &\n JSONSerializationOptions;\n\nexport const SQLiteProjectionSpec = {\n for: <\n EventType extends Event,\n Driver extends AnyEventStoreDriver = AnyEventStoreDriver,\n >(\n options: SQLiteProjectionSpecOptions<EventType, Driver>,\n ): SQLiteProjectionSpec<EventType> => {\n {\n const driverType = options.driver.driverType;\n const pool =\n options.pool ??\n dumbo({\n serialization: options.serialization,\n transactionOptions: {\n allowNestedTransactions: true,\n mode: 'session_based',\n },\n ...options.driver.mapToDumboOptions(options),\n });\n const projection = options.projection;\n let wasInitialized = false;\n\n return (givenEvents: SQLiteProjectionSpecEvent<EventType>[]) => {\n return {\n when: (\n events: SQLiteProjectionSpecEvent<EventType>[],\n options?: SQLiteProjectionSpecWhenOptions,\n ) => {\n const allEvents: ReadEvent<EventType, SQLiteReadEventMetadata>[] =\n [];\n\n const run = async (connection: AnySQLiteConnection) => {\n let globalPosition = 0n;\n const numberOfTimes = options?.numberOfTimes ?? 1;\n\n for (const event of [\n ...givenEvents,\n ...Array.from({ length: numberOfTimes }).flatMap(() => events),\n ]) {\n const metadata: SQLiteReadEventMetadata = {\n checkpoint: bigIntProcessorCheckpoint(++globalPosition),\n globalPosition,\n streamPosition: globalPosition,\n streamName: `test-${uuid()}`,\n messageId: uuid(),\n };\n\n allEvents.push({\n ...event,\n kind: 'Event',\n metadata: {\n ...metadata,\n ...('metadata' in event ? (event.metadata ?? {}) : {}),\n } as CombinedReadEventMetadata<\n EventType,\n SQLiteReadEventMetadata\n >,\n });\n }\n\n if (!wasInitialized && projection.init) {\n await projection.init({\n registrationType: 'async',\n status: 'active',\n context: {\n execute: connection.execute,\n connection,\n driverType,\n },\n version: projection.version ?? 1,\n });\n wasInitialized = true;\n }\n\n await connection.withTransaction(() =>\n handleProjections({\n events: allEvents,\n projections: [projection],\n execute: connection.execute,\n connection,\n driverType,\n }),\n );\n };\n\n return {\n then: (\n assert: SQLiteProjectionAssert,\n message?: string,\n ): Promise<void> =>\n pool.withConnection(async (connection) => {\n await run(connection);\n\n const succeeded = await assert({\n connection,\n });\n\n if (succeeded !== undefined && succeeded === false)\n assertFails(\n message ??\n \"Projection specification didn't match the criteria\",\n );\n }),\n thenThrows: <ErrorType extends Error>(\n ...args: Parameters<ThenThrows<ErrorType>>\n ): Promise<void> =>\n pool.withConnection(async (connection) => {\n try {\n await run(connection);\n throw new AssertionError(\n 'Handler did not fail as expected',\n );\n } catch (error) {\n if (error instanceof AssertionError) throw error;\n\n if (args.length === 0) return;\n\n if (!isErrorConstructor(args[0])) {\n assertTrue(\n args[0](error as ErrorType),\n `Error didn't match the error condition: ${error?.toString()}`,\n );\n return;\n }\n\n assertTrue(\n error instanceof args[0],\n `Caught error is not an instance of the expected type: ${error?.toString()}`,\n );\n\n if (args[1]) {\n assertTrue(\n args[1](error as ErrorType),\n `Error didn't match the error condition: ${error?.toString()}`,\n );\n }\n }\n }),\n };\n },\n };\n };\n }\n },\n};\n\nexport const eventInStream = <\n EventType extends Event = Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n>(\n streamName: string,\n event: SQLiteProjectionSpecEvent<EventType, EventMetaDataType>,\n): SQLiteProjectionSpecEvent<EventType, EventMetaDataType> => {\n return {\n ...event,\n metadata: {\n ...(event.metadata ?? {}),\n streamName: event.metadata?.streamName ?? streamName,\n } as Partial<EventMetaDataType>,\n };\n};\n\nexport const eventsInStream = <\n EventType extends Event = Event,\n EventMetaDataType extends SQLiteReadEventMetadata = SQLiteReadEventMetadata,\n>(\n streamName: string,\n events: SQLiteProjectionSpecEvent<EventType, EventMetaDataType>[],\n): SQLiteProjectionSpecEvent<EventType, EventMetaDataType>[] => {\n return events.map((e) => eventInStream(streamName, e));\n};\n\nexport const newEventsInStream = eventsInStream;\n\nexport const assertSQLQueryResultMatches =\n <T extends QueryResultRow>(sql: SQL, rows: T[]): SQLiteProjectionAssert =>\n async ({\n connection,\n }: {\n connection: AnySQLiteConnection;\n }): Promise<void> => {\n const result = await connection.execute.query<T>(sql);\n\n assertThatArray(rows).containsExactlyInAnyOrder(result.rows);\n };\n\nexport const expectSQL = {\n query: (sql: SQL) => ({\n resultRows: {\n toBeTheSame: <T extends QueryResultRow>(rows: T[]) =>\n assertSQLQueryResultMatches(sql, rows),\n },\n }),\n};\n","export const emmettPrefix = 'emt';\n\nexport const globalTag = 'global';\nexport const defaultTag = `${emmettPrefix}:default`;\nexport const unknownTag = `${emmettPrefix}:unknown`;\n\nexport const globalNames = {\n module: `${emmettPrefix}:module:${globalTag}`,\n};\n\nconst columns = {\n partition: {\n name: 'partition',\n },\n isArchived: { name: 'is_archived' },\n};\n\nexport const streamsTable = {\n name: `${emmettPrefix}_streams`,\n columns: {\n partition: columns.partition,\n isArchived: columns.isArchived,\n },\n};\n\nexport const messagesTable = {\n name: `${emmettPrefix}_messages`,\n columns: {\n partition: columns.partition,\n isArchived: columns.isArchived,\n },\n};\n\nexport const processorsTable = {\n name: `${emmettPrefix}_processors`,\n};\n\nexport const projectionsTable = {\n name: `${emmettPrefix}_projections`,\n};\n","import {\n BatchCommandNoChangesError,\n DumboError,\n singleOrNull,\n SQL,\n UniqueConstraintError,\n type AnyDatabaseTransaction,\n type SQLExecutor,\n} from '@event-driven-io/dumbo';\nimport type { AnySQLiteConnection } from '@event-driven-io/dumbo/sqlite';\nimport {\n downcastRecordedMessages,\n ExpectedVersionConflictError,\n isExpectedVersionConflictError,\n NO_CONCURRENCY_CHECK,\n STREAM_DOES_NOT_EXIST,\n STREAM_EXISTS,\n type AppendToStreamOptions,\n type BeforeEventStoreCommitHandler,\n type ExpectedStreamVersion,\n type Event as Message,\n type RecordedMessage,\n} from '@event-driven-io/emmett';\nimport { v4 as uuid } from 'uuid';\nimport type {\n SQLiteEventStore,\n SQLiteReadEventMetadata,\n} from '../SQLiteEventStore';\nimport { defaultTag, messagesTable, streamsTable } from './typing';\n\nconst { identifier, merge } = SQL;\n\nexport type AppendEventResult =\n | {\n success: true;\n nextStreamPosition: bigint;\n lastGlobalPosition: bigint;\n }\n | { success: false };\n\nexport const appendToStream = async <MessageType extends Message>(\n connection: AnySQLiteConnection,\n streamName: string,\n streamType: string,\n messages: MessageType[],\n options?: AppendToStreamOptions & {\n partition?: string;\n onBeforeCommit?: BeforeEventStoreCommitHandler<\n SQLiteEventStore,\n { connection: AnySQLiteConnection }\n >;\n },\n): Promise<AppendEventResult> => {\n if (messages.length === 0) return { success: false };\n\n const expectedStreamVersion = toExpectedVersion(\n options?.expectedStreamVersion,\n );\n\n const messagesToAppend: RecordedMessage<\n MessageType,\n SQLiteReadEventMetadata\n >[] = messages.map(\n (\n m: Message,\n i: number,\n ): RecordedMessage<MessageType, SQLiteReadEventMetadata> =>\n ({\n ...m,\n kind: m.kind ?? 'Event',\n metadata: {\n streamName,\n messageId: uuid(),\n streamPosition: BigInt(i + 1),\n ...('metadata' in m ? (m.metadata ?? {}) : {}),\n },\n }) as RecordedMessage<MessageType, SQLiteReadEventMetadata>,\n );\n\n try {\n return await connection.withTransaction(\n async (transaction: AnyDatabaseTransaction) => {\n const result = await appendToStreamRaw(\n transaction.execute,\n streamName,\n streamType,\n downcastRecordedMessages(\n messagesToAppend,\n options?.schema?.versioning,\n ),\n {\n expectedStreamVersion,\n },\n );\n\n if (options?.onBeforeCommit)\n await options.onBeforeCommit(messagesToAppend, { connection });\n\n // TODO: Refactor this to map or not success from appendToStreamRaw\n return { success: true, result };\n },\n );\n } catch (err: unknown) {\n if (\n isExpectedVersionConflictError(err) ||\n DumboError.isInstanceOf(err, {\n errorType: UniqueConstraintError.ErrorType,\n }) ||\n DumboError.isInstanceOf(err, {\n errorType: BatchCommandNoChangesError.ErrorType,\n })\n ) {\n return { success: false };\n }\n throw err;\n }\n};\n\nconst toExpectedVersion = (\n expected: ExpectedStreamVersion | undefined,\n): bigint | null => {\n if (expected === undefined) return null;\n\n if (expected === NO_CONCURRENCY_CHECK) return null;\n\n // TODO: this needs to be fixed\n if (expected == STREAM_DOES_NOT_EXIST) return null;\n\n // TODO: this needs to be fixed\n if (expected == STREAM_EXISTS) return null;\n\n return expected as bigint;\n};\n\nconst appendToStreamRaw = async (\n execute: SQLExecutor,\n streamId: string,\n streamType: string,\n messages: RecordedMessage[],\n options?: {\n expectedStreamVersion: bigint | null;\n partition?: string;\n },\n): Promise<AppendEventResult> => {\n let expectedStreamVersion = options?.expectedStreamVersion ?? null;\n\n // TODO: Add eventually strategy not to call that for sqlite,\n // Now it's a shortcut to make it right for D1 trading of a bit performance\n const currentStreamVersion: bigint | null = await getLastStreamPosition(\n execute,\n streamId,\n expectedStreamVersion,\n );\n\n expectedStreamVersion ??= currentStreamVersion ?? 0n;\n\n if (expectedStreamVersion !== currentStreamVersion) {\n throw new ExpectedVersionConflictError(\n currentStreamVersion,\n expectedStreamVersion,\n );\n }\n\n const streamSQL =\n expectedStreamVersion === 0n\n ? SQL`INSERT INTO ${identifier(streamsTable.name)}\n (stream_id, stream_position, partition, stream_type, stream_metadata, is_archived)\n VALUES (\n ${streamId},\n ${messages.length},\n ${options?.partition ?? streamsTable.columns.partition},\n ${streamType},\n '[]',\n false\n )\n RETURNING stream_position;\n `\n : SQL`UPDATE ${identifier(streamsTable.name)}\n SET stream_position = stream_position + ${messages.length}\n WHERE stream_id = ${streamId}\n AND stream_position = ${expectedStreamVersion}\n AND partition = ${options?.partition ?? streamsTable.columns.partition}\n AND is_archived = false\n RETURNING stream_position;\n `;\n\n const insertSQL = buildMessageInsertQuery(\n messages,\n expectedStreamVersion,\n streamId,\n options?.partition?.toString() ?? defaultTag,\n );\n\n const results = await execute.batchCommand<{\n stream_position?: string;\n global_position?: string;\n }>([streamSQL, insertSQL], { assertChanges: true });\n\n const [streamResult, messagesResult] = results;\n\n const streamPosition = streamResult?.rows[0]?.stream_position;\n const globalPosition = messagesResult?.rows.at(-1)?.global_position;\n\n if (!streamPosition)\n throw new ExpectedVersionConflictError(0n, expectedStreamVersion ?? 0n);\n if (!globalPosition) throw new Error('Could not find global position');\n\n return {\n success: true,\n nextStreamPosition: BigInt(streamPosition),\n lastGlobalPosition: BigInt(globalPosition),\n };\n};\n\nasync function getLastStreamPosition(\n execute: SQLExecutor,\n streamId: string,\n expectedStreamVersion: bigint | null,\n): Promise<bigint> {\n const result = await singleOrNull(\n execute.query<{\n stream_position: string;\n }>(\n SQL`SELECT CAST(stream_position AS VARCHAR) AS stream_position FROM ${identifier(streamsTable.name)} WHERE stream_id = ${streamId}`,\n ),\n );\n\n if (result?.stream_position == null) {\n expectedStreamVersion = 0n;\n } else {\n expectedStreamVersion = BigInt(result.stream_position);\n }\n return expectedStreamVersion;\n}\n\nconst buildMessageInsertQuery = (\n messages: RecordedMessage[],\n expectedStreamVersion: bigint,\n streamId: string,\n partition: string | null | undefined,\n): SQL => {\n const values = messages.map((message: RecordedMessage) => {\n if (\n message.metadata?.streamPosition == null ||\n typeof message.metadata.streamPosition !== 'bigint'\n ) {\n throw new Error('Stream position is required');\n }\n\n const streamPosition =\n BigInt(message.metadata.streamPosition) + BigInt(expectedStreamVersion);\n\n return SQL`(${streamId},${streamPosition ?? 0n},${partition ?? defaultTag},${message.kind === 'Event' ? 'E' : 'C'},${message.data},${message.metadata},${expectedStreamVersion ?? 0n},${message.type},${message.metadata.messageId},${false})`;\n });\n\n return SQL`\n INSERT INTO ${identifier(messagesTable.name)} (\n stream_id, \n stream_position, \n partition, \n message_kind,\n message_data, \n message_metadata, \n message_schema_version, \n message_type, \n message_id, \n is_archived\n ) \n VALUES ${merge(values, ',')} \n RETURNING \n CAST(global_position as VARCHAR) AS global_position\n `;\n};\n","import { SQL } from '@event-driven-io/dumbo';\n\nexport const schema_0_41_0: SQL[] = [\n SQL`CREATE TABLE IF NOT EXISTS emt_streams(\n stream_id TEXT NOT NULL,\n stream_position BIGINT NOT NULL DEFAULT 0,\n partition TEXT NOT NULL DEFAULT 'global',\n stream_type TEXT NOT NULL,\n stream_metadata JSONB NOT NULL,\n is_archived BOOLEAN NOT NULL DEFAULT FALSE,\n PRIMARY KEY (stream_id, partition, is_archived),\n UNIQUE (stream_id, partition, is_archived)\n)`,\n SQL`CREATE TABLE IF NOT EXISTS emt_messages(\n stream_id TEXT NOT NULL,\n stream_position BIGINT NOT NULL,\n partition TEXT NOT NULL DEFAULT 'global',\n message_kind CHAR(1) NOT NULL DEFAULT 'E',\n message_data JSONB NOT NULL,\n message_metadata JSONB NOT NULL,\n message_schema_version TEXT NOT NULL,\n message_type TEXT NOT NULL,\n message_id TEXT NOT NULL,\n is_archived BOOLEAN NOT NULL DEFAULT FALSE,\n global_position INTEGER PRIMARY KEY,\n created DATETIME DEFAULT CURRENT_TIMESTAMP,\n UNIQUE (stream_id, stream_position, partition, is_archived)\n)`,\n SQL`CREATE TABLE IF NOT EXISTS emt_subscriptions(\n subscription_id TEXT NOT NULL,\n version INTEGER NOT NULL DEFAULT 1,\n partition TEXT NOT NULL DEFAULT 'global',\n last_processed_position BIGINT NOT NULL,\n PRIMARY KEY (subscription_id, partition, version)\n)`,\n];\n","import { singleOrNull, SQL, type SQLExecutor } from '@event-driven-io/dumbo';\nimport { globalTag, processorsTable, projectionsTable } from '../../typing';\n\nconst { identifier, plain } = SQL;\n\nexport const migration_0_42_0_SQLs: SQL[] = [\n SQL`CREATE TABLE IF NOT EXISTS ${identifier(processorsTable.name)}(\n processor_id TEXT NOT NULL,\n version INTEGER NOT NULL DEFAULT 1,\n partition TEXT NOT NULL DEFAULT '${plain(globalTag)}',\n status TEXT NOT NULL DEFAULT 'stopped',\n last_processed_checkpoint TEXT NOT NULL,\n processor_instance_id TEXT DEFAULT 'emt:unknown',\n PRIMARY KEY (processor_id, partition, version)\n)`,\n SQL`CREATE TABLE IF NOT EXISTS ${identifier(projectionsTable.name)}(\n name TEXT NOT NULL,\n version INTEGER NOT NULL DEFAULT 1,\n partition TEXT NOT NULL DEFAULT '${plain(globalTag)}',\n type CHAR(1) NOT NULL,\n kind TEXT NOT NULL,\n status TEXT NOT NULL,\n definition JSONB NOT NULL DEFAULT '{}',\n PRIMARY KEY (name, partition, version)\n)`,\n SQL`INSERT INTO ${identifier(processorsTable.name)}\n (processor_id, version, partition, status, last_processed_checkpoint, processor_instance_id)\n SELECT\n subscription_id,\n version,\n partition,\n 'stopped',\n printf('%019d', last_processed_position),\n 'emt:unknown'\n FROM emt_subscriptions`,\n SQL`DROP TABLE emt_subscriptions`,\n];\n\nexport const migration_0_42_0_FromSubscriptionsToProcessors = async (\n execute: SQLExecutor,\n): Promise<void> => {\n const tableExists = await singleOrNull(\n execute.query<{ name: string }>(\n SQL`SELECT name FROM sqlite_master WHERE type='table' AND name='emt_subscriptions'`,\n ),\n );\n\n if (!tableExists) {\n return;\n }\n\n await execute.batchCommand(migration_0_42_0_SQLs);\n};\n","import { SQL } from '@event-driven-io/dumbo';\n\nexport const schema_0_42_0: SQL[] = [\n SQL`CREATE TABLE IF NOT EXISTS emt_streams(\n stream_id TEXT NOT NULL,\n stream_position BIGINT NOT NULL DEFAULT 0,\n partition TEXT NOT NULL DEFAULT 'global',\n stream_type TEXT NOT NULL,\n stream_metadata JSONB NOT NULL,\n is_archived BOOLEAN NOT NULL DEFAULT FALSE,\n PRIMARY KEY (stream_id, partition, is_archived),\n UNIQUE (stream_id, partition, is_archived)\n)`,\n SQL`CREATE TABLE IF NOT EXISTS emt_messages(\n stream_id TEXT NOT NULL,\n stream_position BIGINT NOT NULL,\n partition TEXT NOT NULL DEFAULT 'global',\n message_kind CHAR(1) NOT NULL DEFAULT 'E',\n message_data JSONB NOT NULL,\n message_metadata JSONB NOT NULL,\n message_schema_version TEXT NOT NULL,\n message_type TEXT NOT NULL,\n message_id TEXT NOT NULL,\n is_archived BOOLEAN NOT NULL DEFAULT FALSE,\n global_position INTEGER PRIMARY KEY,\n created DATETIME DEFAULT CURRENT_TIMESTAMP,\n UNIQUE (stream_id, stream_position, partition, is_archived)\n)`,\n SQL`CREATE TABLE IF NOT EXISTS emt_processors(\n processor_id TEXT NOT NULL,\n version INTEGER NOT NULL DEFAULT 1,\n partition TEXT NOT NULL DEFAULT 'global',\n status TEXT NOT NULL DEFAULT 'stopped',\n last_processed_checkpoint TEXT NOT NULL,\n processor_instance_id TEXT DEFAULT 'emt:unknown',\n PRIMARY KEY (processor_id, partition, version)\n)`,\n SQL`CREATE TABLE IF NOT EXISTS emt_projections(\n name TEXT NOT NULL,\n version INTEGER NOT NULL DEFAULT 1,\n partition TEXT NOT NULL DEFAULT 'global',\n type CHAR(1) NOT NULL,\n kind TEXT NOT NULL,\n status TEXT NOT NULL,\n definition JSONB NOT NULL DEFAULT '{}',\n PRIMARY KEY (name, partition, version)\n)`,\n];\n","import { SQL, type SQLExecutor, singleOrNull } from '@event-driven-io/dumbo';\nimport { defaultTag, messagesTable } from './typing';\nconst { identifier } = SQL;\n\ntype ReadLastMessageGlobalPositionSqlResult = {\n global_position: string;\n};\n\nexport type ReadLastMessageGlobalPositionResult = {\n currentGlobalPosition: bigint | null;\n};\n\nexport const readLastMessageGlobalPosition = async (\n execute: SQLExecutor,\n options?: { partition?: string },\n): Promise<ReadLastMessageGlobalPositionResult> => {\n const result = await singleOrNull(\n execute.query<ReadLastMessageGlobalPositionSqlResult>(\n SQL`\n SELECT global_position\n FROM ${identifier(messagesTable.name)}\n WHERE partition = ${options?.partition ?? defaultTag} AND is_archived = FALSE\n ORDER BY global_position DESC\n LIMIT 1`,\n ),\n );\n\n return {\n currentGlobalPosition:\n result !== null ? BigInt(result.global_position) : null,\n };\n};\n","import { mapRows, SQL, type SQLExecutor } from '@event-driven-io/dumbo';\nimport type { JSONSerializer } from '@event-driven-io/emmett';\nimport {\n bigIntProcessorCheckpoint,\n type CombinedMessageMetadata,\n type Message,\n type RecordedMessage,\n type RecordedMessageMetadata,\n type RecordedMessageMetadataWithGlobalPosition,\n} from '@event-driven-io/emmett';\nimport { defaultTag, messagesTable } from './typing';\nconst { identifier } = SQL;\n\ntype ReadMessagesBatchSqlResult = {\n stream_position: string;\n stream_id: string;\n message_data: string;\n message_metadata: string;\n message_schema_version: string;\n message_type: string;\n message_id: string;\n global_position: string;\n transaction_id: string;\n created: string;\n};\n\nexport type ReadMessagesBatchOptions = (\n | {\n after: bigint;\n batchSize: number;\n }\n | {\n from: bigint;\n batchSize: number;\n }\n | { to: bigint; batchSize: number }\n | { from: bigint; to: bigint }\n) & {\n partition?: string;\n serializer: JSONSerializer;\n};\n\nexport type ReadMessagesBatchResult<\n MessageType extends Message,\n MessageMetadataType extends RecordedMessageMetadata = RecordedMessageMetadata,\n> = {\n currentGlobalPosition: bigint;\n messages: RecordedMessage<MessageType, MessageMetadataType>[];\n areMessagesLeft: boolean;\n};\n\nexport const readMessagesBatch = async <\n MessageType extends Message,\n RecordedMessageMetadataType extends\n RecordedMessageMetadataWithGlobalPosition =\n RecordedMessageMetadataWithGlobalPosition,\n>(\n execute: SQLExecutor,\n options: ReadMessagesBatchOptions,\n): Promise<\n ReadMessagesBatchResult<MessageType, RecordedMessageMetadataType>\n> => {\n const { serializer } = options;\n const from = 'from' in options ? options.from : undefined;\n const after = 'after' in options ? options.after : undefined;\n const batchSize =\n 'batchSize' in options ? options.batchSize : options.to - options.from;\n\n const fromCondition: SQL =\n from !== undefined\n ? SQL`AND global_position >= ${from}`\n : after !== undefined\n ? SQL`AND global_position > ${after}`\n : SQL.EMPTY;\n\n const toCondition: SQL =\n 'to' in options ? SQL`AND global_position <= ${options.to}` : SQL.EMPTY;\n\n const limitCondition: SQL =\n 'batchSize' in options ? SQL`LIMIT ${options.batchSize}` : SQL.EMPTY;\n\n const messages: RecordedMessage<MessageType, RecordedMessageMetadataType>[] =\n await mapRows(\n execute.query<ReadMessagesBatchSqlResult>(\n SQL`SELECT stream_id, stream_position, global_position, message_data, message_metadata, message_schema_version, message_type, message_id\n FROM ${identifier(messagesTable.name)}\n WHERE partition = ${options?.partition ?? defaultTag} AND is_archived = FALSE ${fromCondition} ${toCondition}\n ORDER BY global_position\n ${limitCondition}`,\n ),\n (row) => {\n const rawEvent = {\n type: row.message_type,\n data: serializer.deserialize(row.message_data),\n metadata: serializer.deserialize(row.message_metadata),\n } as unknown as MessageType;\n\n const metadata: RecordedMessageMetadataWithGlobalPosition = {\n ...('metadata' in rawEvent ? (rawEvent.metadata ?? {}) : {}),\n messageId: row.message_id,\n streamName: row.stream_id,\n streamPosition: BigInt(row.stream_position),\n globalPosition: BigInt(row.global_position),\n checkpoint: bigIntProcessorCheckpoint(BigInt(row.global_position)),\n };\n\n return {\n ...rawEvent,\n kind: 'Event',\n metadata: metadata as CombinedMessageMetadata<\n MessageType,\n RecordedMessageMetadataType\n >,\n };\n },\n );\n\n return messages.length > 0\n ? {\n currentGlobalPosition:\n messages[messages.length - 1]!.metadata.globalPosition,\n messages: messages,\n areMessagesLeft: messages.length === batchSize,\n }\n : {\n currentGlobalPosition:\n 'from' in options\n ? options.from\n : 'after' in options\n ? options.after\n : 0n,\n messages: [],\n areMessagesLeft: false,\n };\n};\n","import { SQL, type SQLExecutor, singleOrNull } from '@event-driven-io/dumbo';\nimport type { ProcessorCheckpoint } from '@event-driven-io/emmett';\nimport { defaultTag, processorsTable } from './typing';\nconst { identifier } = SQL;\n\ntype ReadProcessorCheckpointSqlResult = {\n last_processed_checkpoint: string;\n};\n\nexport type ReadProcessorCheckpointResult = {\n lastProcessedCheckpoint: ProcessorCheckpoint | null;\n};\n\nexport const readProcessorCheckpoint = async (\n execute: SQLExecutor,\n options: { processorId: string; partition?: string },\n): Promise<ReadProcessorCheckpointResult> => {\n const result = await singleOrNull(\n execute.query<ReadProcessorCheckpointSqlResult>(\n SQL`SELECT last_processed_checkpoint\n FROM ${identifier(processorsTable.name)}\n WHERE partition = ${options?.partition ?? defaultTag} AND processor_id = ${options.processorId}\n LIMIT 1`,\n ),\n );\n\n return {\n lastProcessedCheckpoint:\n result !== null\n ? (result.last_processed_checkpoint as ProcessorCheckpoint)\n : null,\n };\n};\n","import type { SQLExecutor } from '@event-driven-io/dumbo';\nimport {\n JSONSerializer,\n parseBigIntProcessorCheckpoint,\n type AsyncAwaiter,\n type BatchRecordedMessageHandlerWithoutContext,\n type EmmettError,\n type Event,\n type JSONSerializationOptions,\n type Message,\n type ProcessorCheckpoint,\n type ReadEvent,\n type ReadEventMetadataWithGlobalPosition,\n} from '@event-driven-io/emmett';\nimport { readLastMessageGlobalPosition } from '../../schema/readLastMessageGlobalPosition';\nimport {\n readMessagesBatch,\n type ReadMessagesBatchOptions,\n} from '../../schema/readMessagesBatch';\n\nexport const DefaultSQLiteEventStoreProcessorBatchSize = 100;\nexport const DefaultSQLiteEventStoreProcessorPullingFrequencyInMs = 50;\n\nexport type SQLiteEventStoreMessagesBatch<EventType extends Event = Event> = {\n messages: ReadEvent<EventType, ReadEventMetadataWithGlobalPosition>[];\n};\n\nexport type SQLiteEventStoreMessagesBatchHandlerResult = void | {\n type: 'STOP';\n reason?: string;\n error?: EmmettError;\n};\n\nexport type SQLiteEventStoreMessageBatchPullerOptions<\n MessageType extends Message = Message,\n> = {\n executor: SQLExecutor;\n pullingFrequencyInMs: number;\n batchSize: number;\n eachBatch: BatchRecordedMessageHandlerWithoutContext<\n MessageType,\n ReadEventMetadataWithGlobalPosition\n >;\n stopWhen?: {\n noMessagesLeft?: boolean;\n };\n signal: AbortSignal;\n} & JSONSerializationOptions;\n\nexport type SQLiteEventStoreMessageBatchPullerStartFrom =\n | { lastCheckpoint: ProcessorCheckpoint }\n | 'BEGINNING'\n | 'END';\n\nexport type SQLiteEventStoreMessageBatchPullerStartOptions = {\n startFrom: SQLiteEventStoreMessageBatchPullerStartFrom;\n signal?: AbortSignal;\n started?: AsyncAwaiter<void>;\n};\n\nexport type SQLiteEventStoreMessageBatchPuller = {\n isRunning: boolean;\n start(options: SQLiteEventStoreMessageBatchPullerStartOptions): Promise<void>;\n stop(): Promise<void>;\n};\n\nexport const sqliteEventStoreMessageBatchPuller = <\n MessageType extends Message = Message,\n>({\n executor,\n batchSize,\n eachBatch,\n pullingFrequencyInMs,\n stopWhen,\n signal,\n serialization,\n}: SQLiteEventStoreMessageBatchPullerOptions<MessageType>): SQLiteEventStoreMessageBatchPuller => {\n let isRunning = false;\n\n let start: Promise<void>;\n const serializer = JSONSerializer.from({ serialization });\n\n const pullMessages = async (\n options: SQLiteEventStoreMessageBatchPullerStartOptions,\n ) => {\n let after: bigint;\n try {\n after =\n options.startFrom === 'BEGINNING'\n ? 0n\n : options.startFrom === 'END'\n ? ((await readLastMessageGlobalPosition(executor))\n .currentGlobalPosition ?? 0n)\n : parseBigIntProcessorCheckpoint(options.startFrom.lastCheckpoint);\n } catch (error) {\n options.started?.reject(error);\n throw error;\n }\n\n options.started?.resolve();\n\n const readMessagesOptions: ReadMessagesBatchOptions = {\n after,\n batchSize,\n serializer,\n };\n\n let waitTime = 100;\n\n while (isRunning && !signal?.aborted) {\n const { messages, currentGlobalPosition, areMessagesLeft } =\n await readMessagesBatch<MessageType>(executor, readMessagesOptions);\n\n if (messages.length > 0) {\n const result = await eachBatch(messages);\n\n if (result && result.type === 'STOP') {\n isRunning = false;\n break;\n }\n }\n\n readMessagesOptions.after = currentGlobalPosition;\n\n await new Promise((resolve) => setTimeout(resolve, waitTime));\n\n if (stopWhen?.noMessagesLeft === true && !areMessagesLeft) {\n isRunning = false;\n break;\n }\n\n if (!areMessagesLeft) {\n waitTime = Math.min(waitTime * 2, 1000);\n } else {\n waitTime = pullingFrequencyInMs;\n }\n }\n };\n\n return {\n get isRunning() {\n return isRunning;\n },\n start: (options) => {\n if (isRunning) return start;\n isRunning = true;\n\n start = (async () => {\n return pullMessages(options);\n })();\n\n return start;\n },\n stop: async () => {\n if (!isRunning) return;\n isRunning = false;\n await start;\n },\n };\n};\n\nexport const zipSQLiteEventStoreMessageBatchPullerStartFrom = (\n options: (SQLiteEventStoreMessageBatchPullerStartFrom | undefined)[],\n): SQLiteEventStoreMessageBatchPullerStartFrom => {\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 { AnyMessage, Message } from '@event-driven-io/emmett';\nimport {\n type Checkpointer,\n type ReadEventMetadataWithGlobalPosition,\n getCheckpoint,\n} from '@event-driven-io/emmett';\nimport { readProcessorCheckpoint, storeProcessorCheckpoint } from '../schema';\nimport type { SQLiteProcessorHandlerContext } from './sqliteProcessor';\n\nexport type SQLiteCheckpointer<MessageType extends AnyMessage = AnyMessage> =\n Checkpointer<\n MessageType,\n ReadEventMetadataWithGlobalPosition,\n SQLiteProcessorHandlerContext\n >;\n\nexport const sqliteCheckpointer = <\n MessageType extends Message = Message,\n>(): SQLiteCheckpointer<MessageType> => ({\n read: async (options, context) => {\n const result = await readProcessorCheckpoint(context.execute, options);\n\n return { lastCheckpoint: result?.lastProcessedCheckpoint };\n },\n store: async (options, context) => {\n const newCheckpoint = getCheckpoint(options.message);\n\n const result = await storeProcessorCheckpoint(context.execute, {\n lastProcessedCheckpoint: options.lastCheckpoint,\n newCheckpoint,\n processorId: options.processorId,\n partition: options.partition,\n version: options.version,\n });\n\n return result.success\n ? { success: true, newCheckpoint: result.newCheckpoint }\n : result;\n },\n});\n","import type { SQLExecutor } from '@event-driven-io/dumbo';\nimport type {\n AnySQLiteConnection,\n SQLiteTransaction,\n} from '@event-driven-io/dumbo/sqlite';\nimport type {\n AnyCommand,\n AnyEvent,\n AnyMessage,\n AnyRecordedMessageMetadata,\n BatchRecordedMessageHandlerWithContext,\n Checkpointer,\n Message,\n MessageProcessingScope,\n MessageProcessor,\n ProcessorHooks,\n ProjectorOptions,\n ReactorOptions,\n ReadEventMetadataWithGlobalPosition,\n SingleMessageHandlerResult,\n SingleRecordedMessageHandlerWithContext,\n WorkflowProcessorContext,\n WorkflowProcessorOptions,\n} from '@event-driven-io/emmett';\nimport {\n defaultProcessorPartition,\n defaultProcessorVersion,\n EmmettError,\n getProcessorInstanceId,\n getProjectorId,\n getWorkflowId,\n projector,\n reactor,\n workflowProcessor,\n type Event,\n type ReadEvent,\n} from '@event-driven-io/emmett';\nimport type { EventStoreSchemaMigrationOptions } from '../schema';\nimport type { SQLiteEventStoreMessageBatchPullerStartFrom } from './messageBatchProcessing';\nimport { sqliteCheckpointer } from './sqliteCheckpointer';\n\nexport type SQLiteProcessorEventsBatch<EventType extends Event = Event> = {\n messages: ReadEvent<EventType, ReadEventMetadataWithGlobalPosition>[];\n};\n\nexport type SQLiteProcessorHandlerContext = {\n execute: SQLExecutor;\n connection: AnySQLiteConnection;\n} &\n // TODO: Reconsider if it should be for all processors\n EventStoreSchemaMigrationOptions;\n\nexport type SQLiteProcessor<MessageType extends Message = AnyMessage> =\n MessageProcessor<\n MessageType,\n ReadEventMetadataWithGlobalPosition,\n SQLiteProcessorHandlerContext\n >;\n\nexport type SQLiteProcessorEachMessageHandler<\n MessageType extends Message = Message,\n> = SingleRecordedMessageHandlerWithContext<\n MessageType,\n ReadEventMetadataWithGlobalPosition,\n SQLiteProcessorHandlerContext\n>;\n\nexport type SQLiteProcessorEachBatchHandler<\n MessageType extends Message = Message,\n> = BatchRecordedMessageHandlerWithContext<\n MessageType,\n ReadEventMetadataWithGlobalPosition,\n SQLiteProcessorHandlerContext\n>;\n\nexport type SQLiteProcessorStartFrom =\n | SQLiteEventStoreMessageBatchPullerStartFrom\n | 'CURRENT';\n\nexport type SQLiteProcessorConnectionOptions = {\n connection?: AnySQLiteConnection;\n};\n\nexport type SQLiteReactorOptions<\n MessageType extends Message = Message,\n MessagePayloadType extends AnyMessage = MessageType,\n> = ReactorOptions<\n MessageType,\n ReadEventMetadataWithGlobalPosition,\n SQLiteProcessorHandlerContext,\n MessagePayloadType\n> &\n SQLiteProcessorConnectionOptions;\n\nexport type SQLiteProjectorOptions<\n EventType extends AnyEvent = AnyEvent,\n EventPayloadType extends Event = EventType,\n> = ProjectorOptions<\n EventType,\n ReadEventMetadataWithGlobalPosition,\n SQLiteProcessorHandlerContext,\n EventPayloadType\n> &\n SQLiteProcessorConnectionOptions &\n EventStoreSchemaMigrationOptions;\n\nexport type SQLiteWorkflowProcessorOptions<\n Input extends AnyEvent | AnyCommand,\n State,\n Output extends AnyEvent | AnyCommand,\n MetaDataType extends AnyRecordedMessageMetadata = AnyRecordedMessageMetadata,\n HandlerContext extends WorkflowProcessorContext = WorkflowProcessorContext,\n StoredMessage extends AnyEvent | AnyCommand = Output,\n> = WorkflowProcessorOptions<\n Input,\n State,\n Output,\n MetaDataType,\n HandlerContext,\n StoredMessage\n> &\n SQLiteProcessorConnectionOptions & {\n messageStore: WorkflowProcessorContext['connection']['messageStore'];\n };\n\nconst sqliteProcessingScope =\n (): MessageProcessingScope<SQLiteProcessorHandlerContext> => {\n const processingScope: MessageProcessingScope<\n SQLiteProcessorHandlerContext\n > = async <Result = SingleMessageHandlerResult>(\n handler: (\n context: SQLiteProcessorHandlerContext,\n ) => Result | Promise<Result>,\n partialContext: Partial<SQLiteProcessorHandlerContext>,\n ) => {\n const connection = partialContext?.connection;\n\n if (!connection)\n // TODO: Map it to dumbo connection correctly\n throw new EmmettError('Connection is required in context or options');\n\n return connection.withTransaction(\n async (transaction: SQLiteTransaction) => {\n return handler({\n ...partialContext,\n connection: connection,\n execute: transaction.execute,\n });\n },\n );\n };\n\n return processingScope;\n };\n\nconst sqliteWorkflowProcessingScope = (\n messageStore: WorkflowProcessorContext['connection']['messageStore'],\n): MessageProcessingScope<\n SQLiteProcessorHandlerContext & WorkflowProcessorContext\n> => {\n const processingScope: MessageProcessingScope<\n SQLiteProcessorHandlerContext & WorkflowProcessorContext\n > = async <Result = SingleMessageHandlerResult>(\n handler: (\n context: SQLiteProcessorHandlerContext & WorkflowProcessorContext,\n ) => Result | Promise<Result>,\n partialContext: Partial<\n SQLiteProcessorHandlerContext & WorkflowProcessorContext\n >,\n ) => {\n const connection = partialContext?.connection;\n\n if (!connection)\n throw new EmmettError('Connection is required in context or options');\n\n return connection.withTransaction(\n async (transaction: SQLiteTransaction) => {\n return handler({\n ...partialContext,\n connection: Object.assign(connection, { messageStore }),\n execute: transaction.execute,\n });\n },\n );\n };\n\n return processingScope;\n};\n\nexport const sqliteWorkflowProcessor = <\n Input extends AnyEvent | AnyCommand,\n State,\n Output extends AnyEvent | AnyCommand,\n MetaDataType extends AnyRecordedMessageMetadata = AnyRecordedMessageMetadata,\n HandlerContext extends SQLiteProcessorHandlerContext &\n WorkflowProcessorContext = SQLiteProcessorHandlerContext &\n WorkflowProcessorContext,\n StoredMessage extends AnyEvent | AnyCommand = Output,\n>(\n options: SQLiteWorkflowProcessorOptions<\n Input,\n State,\n Output,\n MetaDataType,\n HandlerContext,\n StoredMessage\n >,\n): SQLiteProcessor<Input | Output> => {\n const {\n processorId = options.processorId ??\n getWorkflowId({\n workflowName: options.workflow.name ?? 'unknown',\n }),\n processorInstanceId = getProcessorInstanceId(processorId),\n version = defaultProcessorVersion,\n partition = defaultProcessorPartition,\n } = options;\n\n const hooks: ProcessorHooks<HandlerContext> = {\n ...(options.hooks ?? {}),\n onClose: options.hooks?.onClose,\n };\n\n return workflowProcessor({\n ...options,\n processorId,\n processorInstanceId,\n version,\n partition,\n hooks,\n processingScope: sqliteWorkflowProcessingScope(\n options.messageStore,\n ) as unknown as MessageProcessingScope<HandlerContext>,\n checkpoints: sqliteCheckpointer<Input | Output>() as Checkpointer<\n Input | Output,\n MetaDataType,\n HandlerContext\n >,\n }) as SQLiteProcessor<Input | Output>;\n};\n\nexport const sqliteReactor = <\n MessageType extends Message = Message,\n MessagePayloadType extends AnyMessage = MessageType,\n>(\n options: SQLiteReactorOptions<MessageType, MessagePayloadType>,\n): SQLiteProcessor<MessageType> => {\n const {\n processorId = options.processorId,\n processorInstanceId = getProcessorInstanceId(processorId),\n version = defaultProcessorVersion,\n partition = defaultProcessorPartition,\n hooks,\n } = options;\n\n return reactor({\n ...options,\n processorId,\n processorInstanceId,\n version,\n partition,\n hooks,\n processingScope: sqliteProcessingScope(),\n\n checkpoints: sqliteCheckpointer<MessageType>(),\n });\n};\n\nexport const sqliteProjector = <\n EventType extends Event = Event,\n EventPayloadType extends Event = EventType,\n>(\n options: SQLiteProjectorOptions<EventType, EventPayloadType>,\n): SQLiteProcessor<EventType> => {\n const {\n processorId = getProjectorId({\n projectionName: options.projection.name ?? 'unknown',\n }),\n processorInstanceId = getProcessorInstanceId(processorId),\n version = defaultProcessorVersion,\n partition = defaultProcessorPartition,\n } = options;\n\n const hooks: ProcessorHooks<SQLiteProcessorHandlerContext> = {\n ...(options.hooks ?? {}),\n onInit:\n options.projection.init !== undefined || options.hooks?.onInit\n ? async (context: SQLiteProcessorHandlerContext) => {\n if (options.projection.init)\n await options.projection.init({\n version: options.projection.version ?? version,\n status: 'active',\n registrationType: 'async',\n context: {\n ...context,\n migrationOptions: options.migrationOptions,\n },\n });\n if (options.hooks?.onInit)\n await options.hooks.onInit({\n ...context,\n migrationOptions: options.migrationOptions,\n });\n }\n : options.hooks?.onInit,\n onClose: options.hooks?.onClose,\n };\n\n const processor = projector<\n EventType,\n ReadEventMetadataWithGlobalPosition,\n SQLiteProcessorHandlerContext,\n EventPayloadType\n >({\n ...options,\n processorId,\n processorInstanceId,\n version,\n partition,\n hooks,\n processingScope: sqliteProcessingScope(),\n checkpoints: sqliteCheckpointer<EventType>(),\n });\n\n return processor;\n};\n","import { dumbo, type Dumbo } from '@event-driven-io/dumbo';\nimport type {\n AnyCommand,\n JSONSerializationOptions,\n MessageProcessor,\n WorkflowProcessorContext,\n} from '@event-driven-io/emmett';\nimport {\n asyncAwaiter,\n EmmettError,\n type AnyEvent,\n type AnyMessage,\n type AnyRecordedMessageMetadata,\n type AsyncAwaiter,\n type BatchRecordedMessageHandlerWithoutContext,\n type DefaultRecord,\n type Message,\n type MessageConsumer,\n type MessageConsumerOptions,\n type ReadEventMetadataWithGlobalPosition,\n} from '@event-driven-io/emmett';\nimport { v7 as uuid } from 'uuid';\nimport type {\n AnyEventStoreDriver,\n InferOptionsFromEventStoreDriver,\n} from '../eventStoreDriver';\nimport { getSQLiteEventStore } from '../SQLiteEventStore';\nimport {\n DefaultSQLiteEventStoreProcessorBatchSize,\n DefaultSQLiteEventStoreProcessorPullingFrequencyInMs,\n sqliteEventStoreMessageBatchPuller,\n zipSQLiteEventStoreMessageBatchPullerStartFrom,\n type SQLiteEventStoreMessageBatchPuller,\n} from './messageBatchProcessing';\nimport {\n sqliteProjector,\n sqliteReactor,\n sqliteWorkflowProcessor,\n type SQLiteProcessor,\n type SQLiteProcessorHandlerContext,\n type SQLiteProjectorOptions,\n type SQLiteReactorOptions,\n type SQLiteWorkflowProcessorOptions,\n} from './sqliteProcessor';\n\nexport type SQLiteEventStoreConsumerConfig<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ConsumerMessageType extends Message = any,\n> = MessageConsumerOptions<ConsumerMessageType> & {\n stopWhen?: {\n noMessagesLeft?: boolean;\n };\n pulling?: {\n batchSize?: number;\n pullingFrequencyInMs?: number;\n };\n};\n\nexport type SQLiteEventStoreConsumerOptions<\n ConsumerMessageType extends Message = Message,\n Driver extends AnyEventStoreDriver = AnyEventStoreDriver,\n> = SQLiteEventStoreConsumerConfig<ConsumerMessageType> & {\n driver: Driver;\n pool?: Dumbo;\n} & InferOptionsFromEventStoreDriver<Driver> &\n JSONSerializationOptions;\n\nexport type SQLiteEventStoreConsumer<\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: SQLiteReactorOptions<MessageType>,\n ) => SQLiteProcessor<MessageType>;\n\n workflowProcessor: <\n Input extends AnyEvent | AnyCommand,\n State,\n Output extends AnyEvent | AnyCommand,\n MetaDataType extends AnyRecordedMessageMetadata =\n AnyRecordedMessageMetadata,\n HandlerContext extends SQLiteProcessorHandlerContext &\n WorkflowProcessorContext = SQLiteProcessorHandlerContext &\n WorkflowProcessorContext,\n StoredMessage extends AnyEvent | AnyCommand = Output,\n >(\n options: Omit<\n SQLiteWorkflowProcessorOptions<\n Input,\n State,\n Output,\n MetaDataType,\n HandlerContext,\n StoredMessage\n >,\n 'messageStore'\n >,\n ) => SQLiteProcessor<Input | Output>;\n }> &\n (AnyEvent extends ConsumerMessageType\n ? Readonly<{\n projector: <\n EventType extends AnyEvent = ConsumerMessageType & AnyEvent,\n >(\n options: SQLiteProjectorOptions<EventType>,\n ) => SQLiteProcessor<EventType>;\n }>\n : object);\n\nexport const sqliteEventStoreConsumer = <\n ConsumerMessageType extends Message = AnyMessage,\n Driver extends AnyEventStoreDriver = AnyEventStoreDriver,\n>(\n options: SQLiteEventStoreConsumerOptions<ConsumerMessageType, Driver>,\n): SQLiteEventStoreConsumer<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 messagePuller: SQLiteEventStoreMessageBatchPuller | undefined;\n\n const startedAwaiter: AsyncAwaiter<void> = asyncAwaiter<void>();\n\n const pool =\n options.pool ??\n dumbo({\n serialization: options.serialization,\n transactionOptions: {\n allowNestedTransactions: true,\n mode: 'session_based',\n },\n ...options.driver.mapToDumboOptions(options),\n });\n\n const eachBatch: BatchRecordedMessageHandlerWithoutContext<\n ConsumerMessageType,\n ReadEventMetadataWithGlobalPosition\n > = (messagesBatch) =>\n pool.withConnection(async (connection) => {\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 processor\n return await s.handle(messagesBatch, {\n connection,\n execute: connection.execute,\n });\n }),\n );\n\n return result.some(\n (r) => r.status === 'fulfilled' && r.value?.type !== 'STOP',\n )\n ? undefined\n : {\n type: 'STOP',\n };\n });\n\n const processorContext = {\n execute: undefined,\n connection: undefined,\n };\n\n const stopProcessors = () =>\n Promise.all(processors.map((p) => p.close(processorContext)));\n\n const stop = async () => {\n if (!isRunning) return;\n isRunning = false;\n if (messagePuller) {\n abortController?.abort();\n await messagePuller.stop();\n }\n await start;\n\n messagePuller = undefined;\n abortController = null;\n\n await stopProcessors();\n };\n\n const init = async (): Promise<void> => {\n if (isInitialized) return;\n\n const sqliteProcessors = processors as unknown as SQLiteProcessor[];\n\n await pool.withConnection(async (connection) => {\n for (const processor of sqliteProcessors) {\n if (processor.init) {\n await processor.init({\n ...processorContext,\n connection,\n execute: connection.execute,\n });\n }\n }\n });\n isInitialized = true;\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 init,\n reactor: <MessageType extends AnyMessage = ConsumerMessageType>(\n options: SQLiteReactorOptions<MessageType>,\n ): SQLiteProcessor<MessageType> => {\n const processor = sqliteReactor(options);\n\n processors.push(\n // TODO: change that\n processor as unknown as MessageProcessor<\n ConsumerMessageType,\n AnyRecordedMessageMetadata,\n DefaultRecord\n >,\n );\n\n return processor;\n },\n projector: <EventType extends AnyEvent = ConsumerMessageType & AnyEvent>(\n options: SQLiteProjectorOptions<EventType>,\n ): SQLiteProcessor<EventType> => {\n const processor = sqliteProjector(options);\n\n processors.push(\n // TODO: change that\n processor as unknown as MessageProcessor<\n ConsumerMessageType,\n AnyRecordedMessageMetadata,\n DefaultRecord\n >,\n );\n\n return processor;\n },\n workflowProcessor: <\n Input extends AnyEvent | AnyCommand,\n State,\n Output extends AnyEvent | AnyCommand,\n MetaDataType extends AnyRecordedMessageMetadata =\n AnyRecordedMessageMetadata,\n HandlerContext extends SQLiteProcessorHandlerContext &\n WorkflowProcessorContext = SQLiteProcessorHandlerContext &\n WorkflowProcessorContext,\n StoredMessage extends AnyEvent | AnyCommand = Output,\n >(\n processorOptions: Omit<\n SQLiteWorkflowProcessorOptions<\n Input,\n State,\n Output,\n MetaDataType,\n HandlerContext,\n StoredMessage\n >,\n 'messageStore'\n >,\n ): SQLiteProcessor<Input | Output> => {\n const messageStore = getSQLiteEventStore({\n ...options,\n pool,\n schema: { autoMigration: 'None' },\n });\n\n const processor = sqliteWorkflowProcessor({\n ...processorOptions,\n messageStore,\n });\n\n processors.push(\n // TODO: change that\n processor as unknown as MessageProcessor<\n ConsumerMessageType,\n AnyRecordedMessageMetadata,\n DefaultRecord\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\n isRunning = true;\n abortController = new AbortController();\n\n start = (async () => {\n if (!isRunning) return;\n\n try {\n messagePuller = sqliteEventStoreMessageBatchPuller({\n stopWhen: options.stopWhen,\n executor: pool.execute,\n eachBatch,\n batchSize:\n pulling?.batchSize ?? DefaultSQLiteEventStoreProcessorBatchSize,\n pullingFrequencyInMs:\n pulling?.pullingFrequencyInMs ??\n DefaultSQLiteEventStoreProcessorPullingFrequencyInMs,\n signal: abortController.signal,\n });\n\n if (!isInitialized) {\n await init();\n }\n\n const startFrom = await pool.withConnection(async (connection) =>\n zipSQLiteEventStoreMessageBatchPullerStartFrom(\n await Promise.all(\n processors.map(async (o) => {\n const result = await o.start({\n execute: connection.execute,\n connection,\n });\n\n return result;\n }),\n ),\n ),\n );\n\n await messagePuller.start({\n startFrom,\n started: startedAwaiter,\n });\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: async () => {\n await stop();\n await pool.close();\n },\n };\n};\n","import { dumbo, type Dumbo } from '@event-driven-io/dumbo';\nimport type { AnySQLiteConnection } from '@event-driven-io/dumbo/sqlite';\nimport {\n assertExpectedVersionMatchesCurrent,\n ExpectedVersionConflictError,\n JSONSerializer,\n NO_CONCURRENCY_CHECK,\n type AggregateStreamOptions,\n type AggregateStreamResult,\n type AppendToStreamOptions,\n type AppendToStreamResultWithGlobalPosition,\n type BeforeEventStoreCommitHandler,\n type Event,\n type EventStore,\n type EventStoreSession,\n type EventStoreSessionFactory,\n type JSONSerializationOptions,\n type ProjectionRegistration,\n type ReadEvent,\n type ReadEventMetadataWithGlobalPosition,\n type ReadStreamOptions,\n type ReadStreamResult,\n type StreamExistsResult,\n} from '@event-driven-io/emmett';\nimport {\n sqliteEventStoreConsumer,\n type SQLiteEventStoreConsumer,\n type SQLiteEventStoreConsumerConfig,\n} from './consumers';\nimport type {\n AnyEventStoreDriver,\n InferOptionsFromEventStoreDriver,\n} from './eventStoreDriver';\nimport {\n handleProjections,\n type SQLiteProjectionHandlerContext,\n} from './projections';\nimport {\n appendToStream,\n createEventStoreSchema,\n readStream,\n schemaSQL,\n streamExists,\n unknownTag,\n type SQLiteStreamExistsOptions,\n} from './schema';\n\nexport type EventHandler<E extends Event = Event> = (\n eventEnvelope: ReadEvent<E>,\n) => void;\n\nexport const SQLiteEventStoreDefaultStreamVersion = 0n;\n\nexport interface SQLiteEventStore\n extends\n EventStore<SQLiteReadEventMetadata>,\n EventStoreSessionFactory<SQLiteEventStore> {\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?: SQLiteEventStoreConsumerConfig<ConsumerEventType>,\n ): SQLiteEventStoreConsumer<ConsumerEventType>;\n streamExists(\n streamName: string,\n options?: SQLiteStreamExistsOptions,\n ): Promise<StreamExistsResult>;\n close(): Promise<void>;\n schema: {\n sql(): string;\n print(): void;\n migrate(): Promise<void>;\n };\n}\n\nexport type SQLiteReadEventMetadata = ReadEventMetadataWithGlobalPosition;\n\nexport type SQLiteReadEvent<EventType extends Event = Event> = ReadEvent<\n EventType,\n SQLiteReadEventMetadata\n>;\n\nexport type SQLiteEventStoreOptions<\n EventStoreDriver extends AnyEventStoreDriver = AnyEventStoreDriver,\n> = {\n driver: EventStoreDriver;\n projections?: ProjectionRegistration<\n 'inline',\n SQLiteReadEventMetadata,\n SQLiteProjectionHandlerContext\n >[];\n schema?: {\n autoMigration?: 'None' | 'CreateOrUpdate';\n };\n hooks?: {\n /**\n * This hook will be called **BEFORE** event store schema is created\n */\n onBeforeSchemaCreated?: (context: {\n connection: AnySQLiteConnection;\n }) => Promise<void> | void;\n /**\n * This hook will be called **BEFORE** events were stored in the event store.\n * @type {BeforeEventStoreCommitHandler<SQLiteEventStore, HandlerContext>}\n */\n onBeforeCommit?: BeforeEventStoreCommitHandler<\n SQLiteEventStore,\n { connection: AnySQLiteConnection }\n >;\n /**\n * This hook will be called **AFTER** event store schema was created\n */\n onAfterSchemaCreated?: () => Promise<void> | void;\n };\n} & { pool?: Dumbo } & InferOptionsFromEventStoreDriver<EventStoreDriver> &\n JSONSerializationOptions;\n\nexport const getSQLiteEventStore = <\n Driver extends AnyEventStoreDriver = AnyEventStoreDriver,\n>(\n options: SQLiteEventStoreOptions<Driver>,\n): SQLiteEventStore => {\n let autoGenerateSchema = false;\n\n const serializer = JSONSerializer.from(options);\n\n const pool =\n options.pool ??\n dumbo({\n serialization: options.serialization,\n transactionOptions: {\n allowNestedTransactions: true,\n mode: 'session_based',\n },\n ...options.driver.mapToDumboOptions(options),\n });\n let migrateSchema: Promise<void> | undefined = undefined;\n\n const inlineProjections = (options.projections ?? [])\n .filter(({ type }) => type === 'inline')\n .map(({ projection }) => projection);\n\n const onBeforeCommitHook = options.hooks?.onBeforeCommit;\n\n if (options) {\n autoGenerateSchema =\n options.schema?.autoMigration === undefined ||\n options.schema?.autoMigration !== 'None';\n }\n\n const migrate = (connection: AnySQLiteConnection): Promise<void> => {\n if (!migrateSchema) {\n migrateSchema = createEventStoreSchema(connection, {\n onBeforeSchemaCreated: async (context) => {\n for (const projection of inlineProjections) {\n if (projection.init) {\n await projection.init({\n version: projection.version ?? 1,\n registrationType: 'async',\n status: 'active',\n context: {\n execute: context.connection.execute,\n connection: context.connection,\n driverType: options.driver.driverType,\n },\n });\n }\n }\n if (options.hooks?.onBeforeSchemaCreated) {\n await options.hooks.onBeforeSchemaCreated(context);\n }\n },\n onAfterSchemaCreated: options.hooks?.onAfterSchemaCreated,\n });\n }\n\n return migrateSchema;\n };\n\n const ensureSchemaExists = (): Promise<void> => {\n if (!autoGenerateSchema) return Promise.resolve();\n\n return pool.withConnection((connection) => migrate(connection));\n };\n\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 ReadEventMetadataWithGlobalPosition,\n EventPayloadType\n >,\n ): Promise<AggregateStreamResult<State>> {\n await ensureSchemaExists();\n const { evolve, initialState, read } = options;\n\n const expectedStreamVersion = read?.expectedStreamVersion;\n\n let state = initialState();\n\n if (typeof streamName !== 'string') {\n throw new Error('Stream name is not string');\n }\n\n const result = await readStream<EventType, EventPayloadType>(\n pool.execute,\n streamName,\n { ...read, serializer: read?.serialization?.serializer ?? serializer },\n );\n\n const currentStreamVersion = result.currentStreamVersion;\n\n assertExpectedVersionMatchesCurrent(\n currentStreamVersion,\n expectedStreamVersion,\n SQLiteEventStoreDefaultStreamVersion,\n );\n\n for (const event of result.events) {\n if (!event) continue;\n state = evolve(state, event);\n }\n\n return {\n currentStreamVersion: currentStreamVersion,\n state,\n streamExists: result.streamExists,\n };\n },\n\n readStream: async <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n readOptions?: ReadStreamOptions<EventType, EventPayloadType>,\n ): Promise<\n ReadStreamResult<EventType, ReadEventMetadataWithGlobalPosition>\n > => {\n await ensureSchemaExists();\n\n return readStream<EventType, EventPayloadType>(pool.execute, streamName, {\n ...readOptions,\n serializer: options.serialization?.serializer ?? serializer,\n });\n },\n\n appendToStream: async <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n >(\n streamName: string,\n events: EventType[],\n appendOptions?: AppendToStreamOptions<EventType, EventPayloadType>,\n ): Promise<AppendToStreamResultWithGlobalPosition> => {\n await ensureSchemaExists();\n // TODO: This has to be smarter when we introduce urn-based resolution\n const [firstPart, ...rest] = streamName.split('-');\n\n const streamType = firstPart && rest.length > 0 ? firstPart : unknownTag;\n\n const appendResult = await pool.withConnection(\n (connection) =>\n appendToStream(connection, streamName, streamType, events, {\n ...(appendOptions as AppendToStreamOptions),\n onBeforeCommit: async (messages, context) => {\n if (inlineProjections.length > 0)\n await handleProjections({\n projections: inlineProjections,\n events: messages,\n execute: context.connection.execute,\n connection: context.connection,\n driverType: options.driver.driverType,\n });\n\n if (onBeforeCommitHook)\n await onBeforeCommitHook(messages, context);\n },\n }),\n { readonly: false },\n );\n\n if (!appendResult.success)\n throw new ExpectedVersionConflictError(\n -1n, //TODO: Return actual version in case of error\n appendOptions?.expectedStreamVersion ?? NO_CONCURRENCY_CHECK,\n );\n\n return {\n nextExpectedStreamVersion: appendResult.nextStreamPosition,\n lastEventGlobalPosition: appendResult.lastGlobalPosition,\n createdNewStream:\n appendResult.nextStreamPosition >= BigInt(events.length),\n };\n },\n\n async streamExists(\n streamName: string,\n options?: SQLiteStreamExistsOptions,\n ): Promise<StreamExistsResult> {\n await ensureSchemaExists();\n return streamExists(pool.execute, streamName, options);\n },\n\n consumer: <ConsumerEventType extends Event = Event>(\n consumerOptions?: SQLiteEventStoreConsumerConfig<ConsumerEventType>,\n ): SQLiteEventStoreConsumer<ConsumerEventType> =>\n sqliteEventStoreConsumer<ConsumerEventType, Driver>({\n ...(options ?? {}),\n ...(consumerOptions ?? {}),\n pool,\n }),\n\n async withSession<T = unknown>(\n callback: (session: EventStoreSession<SQLiteEventStore>) => Promise<T>,\n ): Promise<T> {\n return await pool.withConnection(async (connection) => {\n const sessionStore = getSQLiteEventStore({\n ...options,\n pool: dumbo({\n ...options.driver.mapToDumboOptions(options),\n connection,\n serialization: options.serialization,\n }),\n transactionOptions: {\n allowNestedTransactions: true,\n mode: 'session_based',\n },\n schema: {\n ...options.schema,\n autoMigration: 'None',\n },\n serialization: options.serialization,\n });\n\n await ensureSchemaExists();\n\n return callback({\n eventStore: sessionStore,\n close: () => Promise.resolve(),\n });\n });\n },\n\n close: () => pool.close(),\n schema: {\n sql: () => schemaSQL.join(''),\n print: () => console.log(schemaSQL.join('')),\n migrate: () => pool.withConnection(migrate),\n },\n };\n};\n","import { SQL, type SQLExecutor } from '@event-driven-io/dumbo';\nimport type { JSONSerializer } from '@event-driven-io/emmett';\nimport {\n bigIntProcessorCheckpoint,\n upcastRecordedMessage,\n type CombinedReadEventMetadata,\n type Event,\n type ReadEvent,\n type ReadEventMetadataWithGlobalPosition,\n type ReadStreamOptions,\n type ReadStreamResult,\n} from '@event-driven-io/emmett';\nimport { SQLiteEventStoreDefaultStreamVersion } from '../SQLiteEventStore';\nimport { defaultTag, messagesTable } from './typing';\nconst { identifier } = SQL;\n\ntype ReadStreamSqlResult = {\n stream_position: string;\n message_data: string;\n message_metadata: string;\n message_schema_version: string;\n message_type: string;\n message_id: string;\n global_position: string;\n created: string;\n};\n\nexport const readStream = async <\n EventType extends Event,\n EventPayloadType extends Event = EventType,\n>(\n execute: SQLExecutor,\n streamId: string,\n options: ReadStreamOptions<EventType, EventPayloadType> & {\n partition?: string;\n serializer: JSONSerializer;\n },\n): Promise<\n ReadStreamResult<EventType, ReadEventMetadataWithGlobalPosition>\n> => {\n const { serializer } = options;\n const fromCondition: SQL = options.from\n ? SQL`AND stream_position >= ${options.from}`\n : SQL.EMPTY;\n\n const to = Number(\n options?.to ??\n (options?.maxCount ? (options.from ?? 0n) + options.maxCount : NaN),\n );\n\n const toCondition: SQL = !isNaN(to)\n ? SQL`AND stream_position <= ${to}`\n : SQL.EMPTY;\n\n const { rows: results } = await execute.query<ReadStreamSqlResult>(\n SQL`SELECT stream_id, stream_position, global_position, message_data, message_metadata, message_schema_version, message_type, message_id\n FROM ${identifier(messagesTable.name)}\n WHERE stream_id = ${streamId} AND partition = ${options?.partition ?? defaultTag} AND is_archived = FALSE ${fromCondition} ${toCondition}\n ORDER BY stream_position ASC`,\n );\n\n const messages: ReadEvent<EventType, ReadEventMetadataWithGlobalPosition>[] =\n results.map((row) => {\n const rawEvent = {\n type: row.message_type,\n data: serializer.deserialize(row.message_data),\n metadata: serializer.deserialize(row.message_metadata),\n } as unknown as EventPayloadType;\n\n const metadata: ReadEventMetadataWithGlobalPosition = {\n ...('metadata' in rawEvent ? (rawEvent.metadata ?? {}) : {}),\n messageId: row.message_id,\n streamName: streamId,\n streamPosition: BigInt(row.stream_position),\n globalPosition: BigInt(row.global_position),\n checkpoint: bigIntProcessorCheckpoint(BigInt(row.global_position)),\n };\n\n const event = {\n ...rawEvent,\n kind: 'Event',\n metadata: metadata as CombinedReadEventMetadata<\n EventPayloadType,\n ReadEventMetadataWithGlobalPosition\n >,\n };\n\n return upcastRecordedMessage(event, options?.schema?.versioning);\n });\n\n return messages.length > 0\n ? {\n currentStreamVersion:\n messages[messages.length - 1]!.metadata.streamPosition,\n events: messages,\n streamExists: true,\n }\n : {\n currentStreamVersion: SQLiteEventStoreDefaultStreamVersion,\n events: [],\n streamExists: false,\n };\n};\n","import {\n DumboError,\n singleOrNull,\n SQL,\n UniqueConstraintError,\n type SQLExecutor,\n} from '@event-driven-io/dumbo';\nimport type { ProcessorCheckpoint } from '@event-driven-io/emmett';\nimport { defaultTag, processorsTable, unknownTag } from './typing';\n\nconst { identifier } = SQL;\n\n// for more infos see the postgresql stored procedure version\nasync function storeSubscriptionCheckpointSQLite(\n execute: SQLExecutor,\n processorId: string,\n version: number,\n position: ProcessorCheckpoint | null,\n checkPosition: ProcessorCheckpoint | null,\n partition: string,\n processorInstanceId?: string,\n): Promise<0 | 1 | 2> {\n processorInstanceId ??= unknownTag;\n if (checkPosition !== null) {\n const updateResult = await execute.command(\n SQL`\n UPDATE ${identifier(processorsTable.name)}\n SET \n last_processed_checkpoint = ${position},\n processor_instance_id = ${processorInstanceId}\n WHERE processor_id = ${processorId} \n AND last_processed_checkpoint = ${checkPosition} \n AND partition = ${partition}\n `,\n );\n if (updateResult.rowCount && updateResult.rowCount > 0) {\n return 1;\n }\n const current_position = await singleOrNull(\n execute.query<{ last_processed_checkpoint: string }>(\n SQL`\n SELECT last_processed_checkpoint FROM ${identifier(processorsTable.name)} \n WHERE processor_id = ${processorId} AND partition = ${partition}`,\n ),\n );\n\n const currentPosition =\n current_position && current_position?.last_processed_checkpoint !== null\n ? current_position.last_processed_checkpoint\n : null;\n\n if (currentPosition === position) {\n return 0;\n } else if (\n position !== null &&\n currentPosition !== null &&\n currentPosition > position\n ) {\n return 2;\n } else {\n return 2;\n }\n } else {\n try {\n await execute.command(\n SQL`INSERT INTO ${identifier(processorsTable.name)} (processor_id, version, last_processed_checkpoint, partition, processor_instance_id) \n VALUES (${processorId}, ${version}, ${position}, ${partition}, ${processorInstanceId})`,\n );\n return 1;\n } catch (err) {\n if (\n !DumboError.isInstanceOf(err, {\n errorType: UniqueConstraintError.ErrorType,\n })\n ) {\n throw err;\n }\n\n const current = await singleOrNull(\n execute.query<{ last_processed_checkpoint: string }>(\n SQL`\n SELECT last_processed_checkpoint FROM ${identifier(processorsTable.name)} \n WHERE processor_id = ${processorId} AND partition = ${partition}`,\n ),\n );\n const currentPosition =\n current && current?.last_processed_checkpoint !== null\n ? BigInt(current.last_processed_checkpoint)\n : null;\n\n if (currentPosition === position) {\n return 0;\n } else {\n return 2;\n }\n }\n }\n}\n\nexport type StoreProcessorCheckpointResult =\n | {\n success: true;\n newCheckpoint: ProcessorCheckpoint | null;\n }\n | { success: false; reason: 'IGNORED' | 'MISMATCH' };\n\nexport async function storeProcessorCheckpoint(\n execute: SQLExecutor,\n options: {\n processorId: string;\n version: number | undefined;\n newCheckpoint: ProcessorCheckpoint | null;\n lastProcessedCheckpoint: ProcessorCheckpoint | null;\n partition?: string;\n processorInstanceId?: string;\n },\n): Promise<StoreProcessorCheckpointResult> {\n try {\n const result = await storeSubscriptionCheckpointSQLite(\n execute,\n options.processorId,\n options.version ?? 1,\n options.newCheckpoint,\n options.lastProcessedCheckpoint,\n options.partition ?? defaultTag,\n );\n\n return result === 1\n ? { success: true, newCheckpoint: options.newCheckpoint }\n : { success: false, reason: result === 0 ? 'IGNORED' : 'MISMATCH' };\n } catch (error) {\n console.log(error);\n throw error;\n }\n}\n","import { exists, SQL, type SQLExecutor } from '@event-driven-io/dumbo';\nimport type { StreamExistsResult } from '@event-driven-io/emmett';\nimport { defaultTag, streamsTable } from './typing';\n\nexport type SQLiteStreamExistsOptions = { partition: string };\n\ntype StreamExistsSqlResult = { exists: boolean };\n\nexport const streamExists = (\n execute: SQLExecutor,\n streamId: string,\n options?: SQLiteStreamExistsOptions,\n): Promise<StreamExistsResult> =>\n exists(\n execute.query<StreamExistsSqlResult>(\n SQL`SELECT EXISTS (\n SELECT 1\n from ${SQL.identifier(streamsTable.name)}\n WHERE stream_id = ${streamId} AND partition = ${options?.partition ?? defaultTag} AND is_archived = FALSE) as exists\n `,\n ),\n );\n","import { SQL, type AnyDatabaseTransaction } from '@event-driven-io/dumbo';\nimport type { AnySQLiteConnection } from '@event-driven-io/dumbo/sqlite';\nimport type { SQLiteEventStoreOptions } from '../SQLiteEventStore';\nimport { migration_0_42_0_FromSubscriptionsToProcessors } from './migrations';\nimport {\n globalTag,\n messagesTable,\n processorsTable,\n projectionsTable,\n streamsTable,\n unknownTag,\n} from './typing';\n\nconst { identifier, plain } = SQL;\n\nexport const streamsTableSQL = SQL`CREATE TABLE IF NOT EXISTS ${identifier(streamsTable.name)}(\n stream_id TEXT NOT NULL,\n stream_position BIGINT NOT NULL DEFAULT 0,\n partition TEXT NOT NULL DEFAULT '${plain(globalTag)}',\n stream_type TEXT NOT NULL,\n stream_metadata JSONB NOT NULL,\n is_archived BOOLEAN NOT NULL DEFAULT FALSE,\n PRIMARY KEY (stream_id, partition, is_archived),\n UNIQUE (stream_id, partition, is_archived)\n );`;\n\nexport const messagesTableSQL = SQL`CREATE TABLE IF NOT EXISTS ${identifier(messagesTable.name)}(\n stream_id TEXT NOT NULL,\n stream_position BIGINT NOT NULL,\n partition TEXT NOT NULL DEFAULT '${plain(globalTag)}',\n message_kind CHAR(1) NOT NULL DEFAULT 'E',\n message_data JSONB NOT NULL,\n message_metadata JSONB NOT NULL,\n message_schema_version TEXT NOT NULL,\n message_type TEXT NOT NULL,\n message_id TEXT NOT NULL,\n is_archived BOOLEAN NOT NULL DEFAULT FALSE,\n global_position INTEGER PRIMARY KEY,\n created DATETIME DEFAULT CURRENT_TIMESTAMP,\n UNIQUE (stream_id, stream_position, partition, is_archived)\n ); \n`;\n\nexport const processorsTableSQL = SQL`\n CREATE TABLE IF NOT EXISTS ${SQL.identifier(processorsTable.name)}(\n processor_id TEXT NOT NULL,\n version INTEGER NOT NULL DEFAULT 1,\n partition TEXT NOT NULL DEFAULT '${plain(globalTag)}',\n status TEXT NOT NULL DEFAULT 'stopped',\n last_processed_checkpoint TEXT NOT NULL,\n processor_instance_id TEXT DEFAULT '${plain(unknownTag)}',\n PRIMARY KEY (processor_id, partition, version)\n );\n`;\n\nexport const projectionsTableSQL = SQL`\n CREATE TABLE IF NOT EXISTS ${SQL.identifier(projectionsTable.name)}(\n name TEXT NOT NULL,\n version INTEGER NOT NULL DEFAULT 1,\n partition TEXT NOT NULL DEFAULT '${plain(globalTag)}',\n type CHAR(1) NOT NULL,\n kind TEXT NOT NULL,\n status TEXT NOT NULL,\n definition JSONB NOT NULL DEFAULT '{}',\n PRIMARY KEY (name, partition, version)\n );\n`;\n\nexport const schemaSQL: SQL[] = [\n streamsTableSQL,\n messagesTableSQL,\n processorsTableSQL,\n projectionsTableSQL,\n];\n\nexport type CreateEventStoreSchemaOptions = {\n dryRun?: boolean | undefined;\n ignoreMigrationHashMismatch?: boolean | undefined;\n migrationTimeoutMs?: number | undefined;\n};\n\nexport type EventStoreSchemaMigrationOptions = {\n migrationOptions?: CreateEventStoreSchemaOptions;\n};\n\nexport const createEventStoreSchema = async (\n pool: AnySQLiteConnection,\n hooks?: SQLiteEventStoreOptions['hooks'],\n): Promise<void> => {\n await pool.withTransaction(async (tx: AnyDatabaseTransaction) => {\n await migration_0_42_0_FromSubscriptionsToProcessors(tx.execute);\n\n if (hooks?.onBeforeSchemaCreated) {\n await hooks.onBeforeSchemaCreated({\n connection: tx.connection as AnySQLiteConnection,\n });\n }\n await tx.execute.batchCommand(schemaSQL);\n\n if (hooks?.onAfterSchemaCreated) {\n await hooks.onAfterSchemaCreated();\n }\n });\n};\n"],"mappings":"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"}
|