UNPKG

@arturwojnar/hermes-mongodb

Version:

Production-Ready TypeScript Outbox Pattern for MongoDB

1,213 lines (916 loc) 32.4 kB
import { parseSemVer, assert as assert$1, NotSupportedMongoVersionError, isNil, CancellationPromise, swallow, addDisposeOnSigterm, assertDate } from '@arturwojnar/hermes'; import { ObjectId, ClientSession } from 'mongodb'; import { setTimeout } from 'node:timers/promises'; var dist = {}; var primitive = {}; var hasRequiredPrimitive; function requirePrimitive () { if (hasRequiredPrimitive) return primitive; hasRequiredPrimitive = 1; Object.defineProperty(primitive, "__esModule", { value: true }); return primitive; } var builtIn = {}; var hasRequiredBuiltIn; function requireBuiltIn () { if (hasRequiredBuiltIn) return builtIn; hasRequiredBuiltIn = 1; Object.defineProperty(builtIn, "__esModule", { value: true }); return builtIn; } var keyOfBase = {}; var hasRequiredKeyOfBase; function requireKeyOfBase () { if (hasRequiredKeyOfBase) return keyOfBase; hasRequiredKeyOfBase = 1; Object.defineProperty(keyOfBase, "__esModule", { value: true }); return keyOfBase; } var strictExclude = {}; var hasRequiredStrictExclude; function requireStrictExclude () { if (hasRequiredStrictExclude) return strictExclude; hasRequiredStrictExclude = 1; Object.defineProperty(strictExclude, "__esModule", { value: true }); return strictExclude; } var strictExtract = {}; var hasRequiredStrictExtract; function requireStrictExtract () { if (hasRequiredStrictExtract) return strictExtract; hasRequiredStrictExtract = 1; Object.defineProperty(strictExtract, "__esModule", { value: true }); return strictExtract; } var strictOmit = {}; var hasRequiredStrictOmit; function requireStrictOmit () { if (hasRequiredStrictOmit) return strictOmit; hasRequiredStrictOmit = 1; Object.defineProperty(strictOmit, "__esModule", { value: true }); return strictOmit; } var writable = {}; var hasRequiredWritable; function requireWritable () { if (hasRequiredWritable) return writable; hasRequiredWritable = 1; Object.defineProperty(writable, "__esModule", { value: true }); return writable; } var asyncOrSync = {}; var hasRequiredAsyncOrSync; function requireAsyncOrSync () { if (hasRequiredAsyncOrSync) return asyncOrSync; hasRequiredAsyncOrSync = 1; Object.defineProperty(asyncOrSync, "__esModule", { value: true }); return asyncOrSync; } var asyncOrSyncType = {}; var hasRequiredAsyncOrSyncType; function requireAsyncOrSyncType () { if (hasRequiredAsyncOrSyncType) return asyncOrSyncType; hasRequiredAsyncOrSyncType = 1; Object.defineProperty(asyncOrSyncType, "__esModule", { value: true }); return asyncOrSyncType; } var dictionary = {}; var hasRequiredDictionary; function requireDictionary () { if (hasRequiredDictionary) return dictionary; hasRequiredDictionary = 1; Object.defineProperty(dictionary, "__esModule", { value: true }); return dictionary; } var dictionaryValues = {}; var hasRequiredDictionaryValues; function requireDictionaryValues () { if (hasRequiredDictionaryValues) return dictionaryValues; hasRequiredDictionaryValues = 1; Object.defineProperty(dictionaryValues, "__esModule", { value: true }); return dictionaryValues; } var merge = {}; var hasRequiredMerge; function requireMerge () { if (hasRequiredMerge) return merge; hasRequiredMerge = 1; Object.defineProperty(merge, "__esModule", { value: true }); return merge; } var mergeN = {}; var hasRequiredMergeN; function requireMergeN () { if (hasRequiredMergeN) return mergeN; hasRequiredMergeN = 1; Object.defineProperty(mergeN, "__esModule", { value: true }); return mergeN; } var newable = {}; var hasRequiredNewable; function requireNewable () { if (hasRequiredNewable) return newable; hasRequiredNewable = 1; Object.defineProperty(newable, "__esModule", { value: true }); return newable; } var nonNever = {}; var hasRequiredNonNever; function requireNonNever () { if (hasRequiredNonNever) return nonNever; hasRequiredNonNever = 1; Object.defineProperty(nonNever, "__esModule", { value: true }); return nonNever; } var omitProperties = {}; var hasRequiredOmitProperties; function requireOmitProperties () { if (hasRequiredOmitProperties) return omitProperties; hasRequiredOmitProperties = 1; Object.defineProperty(omitProperties, "__esModule", { value: true }); return omitProperties; } var opaque = {}; var hasRequiredOpaque; function requireOpaque () { if (hasRequiredOpaque) return opaque; hasRequiredOpaque = 1; Object.defineProperty(opaque, "__esModule", { value: true }); return opaque; } var pathValue = {}; var hasRequiredPathValue; function requirePathValue () { if (hasRequiredPathValue) return pathValue; hasRequiredPathValue = 1; Object.defineProperty(pathValue, "__esModule", { value: true }); return pathValue; } var paths = {}; var hasRequiredPaths; function requirePaths () { if (hasRequiredPaths) return paths; hasRequiredPaths = 1; Object.defineProperty(paths, "__esModule", { value: true }); return paths; } var pickProperties = {}; var hasRequiredPickProperties; function requirePickProperties () { if (hasRequiredPickProperties) return pickProperties; hasRequiredPickProperties = 1; Object.defineProperty(pickProperties, "__esModule", { value: true }); return pickProperties; } var prettify = {}; var hasRequiredPrettify; function requirePrettify () { if (hasRequiredPrettify) return prettify; hasRequiredPrettify = 1; Object.defineProperty(prettify, "__esModule", { value: true }); return prettify; } var safeDictionary = {}; var hasRequiredSafeDictionary; function requireSafeDictionary () { if (hasRequiredSafeDictionary) return safeDictionary; hasRequiredSafeDictionary = 1; Object.defineProperty(safeDictionary, "__esModule", { value: true }); return safeDictionary; } var unionToIntersection = {}; var hasRequiredUnionToIntersection; function requireUnionToIntersection () { if (hasRequiredUnionToIntersection) return unionToIntersection; hasRequiredUnionToIntersection = 1; Object.defineProperty(unionToIntersection, "__esModule", { value: true }); return unionToIntersection; } var valueOf = {}; var hasRequiredValueOf; function requireValueOf () { if (hasRequiredValueOf) return valueOf; hasRequiredValueOf = 1; Object.defineProperty(valueOf, "__esModule", { value: true }); return valueOf; } var xor = {}; var hasRequiredXor; function requireXor () { if (hasRequiredXor) return xor; hasRequiredXor = 1; Object.defineProperty(xor, "__esModule", { value: true }); return xor; } var markOptional = {}; var hasRequiredMarkOptional; function requireMarkOptional () { if (hasRequiredMarkOptional) return markOptional; hasRequiredMarkOptional = 1; Object.defineProperty(markOptional, "__esModule", { value: true }); return markOptional; } var markReadonly = {}; var hasRequiredMarkReadonly; function requireMarkReadonly () { if (hasRequiredMarkReadonly) return markReadonly; hasRequiredMarkReadonly = 1; Object.defineProperty(markReadonly, "__esModule", { value: true }); return markReadonly; } var markRequired = {}; var hasRequiredMarkRequired; function requireMarkRequired () { if (hasRequiredMarkRequired) return markRequired; hasRequiredMarkRequired = 1; Object.defineProperty(markRequired, "__esModule", { value: true }); return markRequired; } var markWritable = {}; var hasRequiredMarkWritable; function requireMarkWritable () { if (hasRequiredMarkWritable) return markWritable; hasRequiredMarkWritable = 1; Object.defineProperty(markWritable, "__esModule", { value: true }); return markWritable; } var buildable = {}; var hasRequiredBuildable; function requireBuildable () { if (hasRequiredBuildable) return buildable; hasRequiredBuildable = 1; Object.defineProperty(buildable, "__esModule", { value: true }); return buildable; } var deepNonNullable = {}; var hasRequiredDeepNonNullable; function requireDeepNonNullable () { if (hasRequiredDeepNonNullable) return deepNonNullable; hasRequiredDeepNonNullable = 1; Object.defineProperty(deepNonNullable, "__esModule", { value: true }); return deepNonNullable; } var deepNullable = {}; var hasRequiredDeepNullable; function requireDeepNullable () { if (hasRequiredDeepNullable) return deepNullable; hasRequiredDeepNullable = 1; Object.defineProperty(deepNullable, "__esModule", { value: true }); return deepNullable; } var strictDeepOmit = {}; var hasRequiredStrictDeepOmit; function requireStrictDeepOmit () { if (hasRequiredStrictDeepOmit) return strictDeepOmit; hasRequiredStrictDeepOmit = 1; Object.defineProperty(strictDeepOmit, "__esModule", { value: true }); return strictDeepOmit; } var deepOmit = {}; var hasRequiredDeepOmit; function requireDeepOmit () { if (hasRequiredDeepOmit) return deepOmit; hasRequiredDeepOmit = 1; Object.defineProperty(deepOmit, "__esModule", { value: true }); return deepOmit; } var deepPartial = {}; var hasRequiredDeepPartial; function requireDeepPartial () { if (hasRequiredDeepPartial) return deepPartial; hasRequiredDeepPartial = 1; Object.defineProperty(deepPartial, "__esModule", { value: true }); return deepPartial; } var strictDeepPick = {}; var hasRequiredStrictDeepPick; function requireStrictDeepPick () { if (hasRequiredStrictDeepPick) return strictDeepPick; hasRequiredStrictDeepPick = 1; Object.defineProperty(strictDeepPick, "__esModule", { value: true }); return strictDeepPick; } var deepPick = {}; var hasRequiredDeepPick; function requireDeepPick () { if (hasRequiredDeepPick) return deepPick; hasRequiredDeepPick = 1; Object.defineProperty(deepPick, "__esModule", { value: true }); return deepPick; } var deepReadonly = {}; var hasRequiredDeepReadonly; function requireDeepReadonly () { if (hasRequiredDeepReadonly) return deepReadonly; hasRequiredDeepReadonly = 1; Object.defineProperty(deepReadonly, "__esModule", { value: true }); return deepReadonly; } var deepRequired = {}; var hasRequiredDeepRequired; function requireDeepRequired () { if (hasRequiredDeepRequired) return deepRequired; hasRequiredDeepRequired = 1; Object.defineProperty(deepRequired, "__esModule", { value: true }); return deepRequired; } var deepUndefinable = {}; var hasRequiredDeepUndefinable; function requireDeepUndefinable () { if (hasRequiredDeepUndefinable) return deepUndefinable; hasRequiredDeepUndefinable = 1; Object.defineProperty(deepUndefinable, "__esModule", { value: true }); return deepUndefinable; } var deepWritable = {}; var hasRequiredDeepWritable; function requireDeepWritable () { if (hasRequiredDeepWritable) return deepWritable; hasRequiredDeepWritable = 1; Object.defineProperty(deepWritable, "__esModule", { value: true }); return deepWritable; } var optionalKeys = {}; var hasRequiredOptionalKeys; function requireOptionalKeys () { if (hasRequiredOptionalKeys) return optionalKeys; hasRequiredOptionalKeys = 1; Object.defineProperty(optionalKeys, "__esModule", { value: true }); return optionalKeys; } var pickKeys = {}; var hasRequiredPickKeys; function requirePickKeys () { if (hasRequiredPickKeys) return pickKeys; hasRequiredPickKeys = 1; Object.defineProperty(pickKeys, "__esModule", { value: true }); return pickKeys; } var readonlyKeys = {}; var hasRequiredReadonlyKeys; function requireReadonlyKeys () { if (hasRequiredReadonlyKeys) return readonlyKeys; hasRequiredReadonlyKeys = 1; Object.defineProperty(readonlyKeys, "__esModule", { value: true }); return readonlyKeys; } var requiredKeys = {}; var hasRequiredRequiredKeys; function requireRequiredKeys () { if (hasRequiredRequiredKeys) return requiredKeys; hasRequiredRequiredKeys = 1; Object.defineProperty(requiredKeys, "__esModule", { value: true }); return requiredKeys; } var writableKeys = {}; var hasRequiredWritableKeys; function requireWritableKeys () { if (hasRequiredWritableKeys) return writableKeys; hasRequiredWritableKeys = 1; Object.defineProperty(writableKeys, "__esModule", { value: true }); return writableKeys; } var exact = {}; var hasRequiredExact; function requireExact () { if (hasRequiredExact) return exact; hasRequiredExact = 1; Object.defineProperty(exact, "__esModule", { value: true }); return exact; } var isAny = {}; var hasRequiredIsAny; function requireIsAny () { if (hasRequiredIsAny) return isAny; hasRequiredIsAny = 1; Object.defineProperty(isAny, "__esModule", { value: true }); return isAny; } var isNever = {}; var hasRequiredIsNever; function requireIsNever () { if (hasRequiredIsNever) return isNever; hasRequiredIsNever = 1; Object.defineProperty(isNever, "__esModule", { value: true }); return isNever; } var isUnknown = {}; var hasRequiredIsUnknown; function requireIsUnknown () { if (hasRequiredIsUnknown) return isUnknown; hasRequiredIsUnknown = 1; Object.defineProperty(isUnknown, "__esModule", { value: true }); return isUnknown; } var isTuple = {}; var hasRequiredIsTuple; function requireIsTuple () { if (hasRequiredIsTuple) return isTuple; hasRequiredIsTuple = 1; Object.defineProperty(isTuple, "__esModule", { value: true }); return isTuple; } var nonEmptyObject = {}; var hasRequiredNonEmptyObject; function requireNonEmptyObject () { if (hasRequiredNonEmptyObject) return nonEmptyObject; hasRequiredNonEmptyObject = 1; Object.defineProperty(nonEmptyObject, "__esModule", { value: true }); return nonEmptyObject; } var anyArray = {}; var hasRequiredAnyArray; function requireAnyArray () { if (hasRequiredAnyArray) return anyArray; hasRequiredAnyArray = 1; Object.defineProperty(anyArray, "__esModule", { value: true }); return anyArray; } var arrayOrSingle = {}; var hasRequiredArrayOrSingle; function requireArrayOrSingle () { if (hasRequiredArrayOrSingle) return arrayOrSingle; hasRequiredArrayOrSingle = 1; Object.defineProperty(arrayOrSingle, "__esModule", { value: true }); return arrayOrSingle; } var elementOf = {}; var hasRequiredElementOf; function requireElementOf () { if (hasRequiredElementOf) return elementOf; hasRequiredElementOf = 1; Object.defineProperty(elementOf, "__esModule", { value: true }); return elementOf; } var head = {}; var hasRequiredHead; function requireHead () { if (hasRequiredHead) return head; hasRequiredHead = 1; Object.defineProperty(head, "__esModule", { value: true }); return head; } var nonEmptyArray = {}; var hasRequiredNonEmptyArray; function requireNonEmptyArray () { if (hasRequiredNonEmptyArray) return nonEmptyArray; hasRequiredNonEmptyArray = 1; Object.defineProperty(nonEmptyArray, "__esModule", { value: true }); return nonEmptyArray; } var readonlyArrayOrSingle = {}; var hasRequiredReadonlyArrayOrSingle; function requireReadonlyArrayOrSingle () { if (hasRequiredReadonlyArrayOrSingle) return readonlyArrayOrSingle; hasRequiredReadonlyArrayOrSingle = 1; Object.defineProperty(readonlyArrayOrSingle, "__esModule", { value: true }); return readonlyArrayOrSingle; } var tail = {}; var hasRequiredTail; function requireTail () { if (hasRequiredTail) return tail; hasRequiredTail = 1; Object.defineProperty(tail, "__esModule", { value: true }); return tail; } var tuple = {}; var hasRequiredTuple; function requireTuple () { if (hasRequiredTuple) return tuple; hasRequiredTuple = 1; Object.defineProperty(tuple, "__esModule", { value: true }); return tuple; } var camelCase = {}; var hasRequiredCamelCase; function requireCamelCase () { if (hasRequiredCamelCase) return camelCase; hasRequiredCamelCase = 1; Object.defineProperty(camelCase, "__esModule", { value: true }); return camelCase; } var deepCamelCaseProperties = {}; var hasRequiredDeepCamelCaseProperties; function requireDeepCamelCaseProperties () { if (hasRequiredDeepCamelCaseProperties) return deepCamelCaseProperties; hasRequiredDeepCamelCaseProperties = 1; Object.defineProperty(deepCamelCaseProperties, "__esModule", { value: true }); return deepCamelCaseProperties; } var anyFunction = {}; var hasRequiredAnyFunction; function requireAnyFunction () { if (hasRequiredAnyFunction) return anyFunction; hasRequiredAnyFunction = 1; Object.defineProperty(anyFunction, "__esModule", { value: true }); return anyFunction; } var predicateFunction = {}; var hasRequiredPredicateFunction; function requirePredicateFunction () { if (hasRequiredPredicateFunction) return predicateFunction; hasRequiredPredicateFunction = 1; Object.defineProperty(predicateFunction, "__esModule", { value: true }); return predicateFunction; } var predicateType = {}; var hasRequiredPredicateType; function requirePredicateType () { if (hasRequiredPredicateType) return predicateType; hasRequiredPredicateType = 1; Object.defineProperty(predicateType, "__esModule", { value: true }); return predicateType; } var unreachableCaseError = {}; var hasRequiredUnreachableCaseError; function requireUnreachableCaseError () { if (hasRequiredUnreachableCaseError) return unreachableCaseError; hasRequiredUnreachableCaseError = 1; Object.defineProperty(unreachableCaseError, "__esModule", { value: true }); unreachableCaseError.UnreachableCaseError = void 0; class UnreachableCaseError extends Error { constructor(value) { super(`Unreachable case: ${value}`); } } unreachableCaseError.UnreachableCaseError = UnreachableCaseError; return unreachableCaseError; } var assert = {}; var hasRequiredAssert; function requireAssert () { if (hasRequiredAssert) return assert; hasRequiredAssert = 1; Object.defineProperty(assert, "__esModule", { value: true }); assert.assert = void 0; function assert$1(condition, message = "no additional info provided") { if (!condition) { throw new Error("Assertion Error: " + message); } } assert.assert = assert$1; return assert; } var createFactoryWithConstraint = {}; var hasRequiredCreateFactoryWithConstraint; function requireCreateFactoryWithConstraint () { if (hasRequiredCreateFactoryWithConstraint) return createFactoryWithConstraint; hasRequiredCreateFactoryWithConstraint = 1; Object.defineProperty(createFactoryWithConstraint, "__esModule", { value: true }); createFactoryWithConstraint.createFactoryWithConstraint = void 0; const createFactoryWithConstraint$1 = () => (value) => value; createFactoryWithConstraint.createFactoryWithConstraint = createFactoryWithConstraint$1; return createFactoryWithConstraint; } var isExact = {}; var hasRequiredIsExact; function requireIsExact () { if (hasRequiredIsExact) return isExact; hasRequiredIsExact = 1; Object.defineProperty(isExact, "__esModule", { value: true }); isExact.isExact = void 0; const isExact$1 = () => (x) => x; isExact.isExact = isExact$1; return isExact; } var noop = {}; var hasRequiredNoop; function requireNoop () { if (hasRequiredNoop) return noop; hasRequiredNoop = 1; Object.defineProperty(noop, "__esModule", { value: true }); noop.noop = void 0; function noop$1(..._args) { } noop.noop = noop$1; return noop; } var awaited = {}; var hasRequiredAwaited; function requireAwaited () { if (hasRequiredAwaited) return awaited; hasRequiredAwaited = 1; Object.defineProperty(awaited, "__esModule", { value: true }); return awaited; } var hasRequiredDist; function requireDist () { if (hasRequiredDist) return dist; hasRequiredDist = 1; (function (exports) { // Basic var __createBinding = (dist && dist.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __exportStar = (dist && dist.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; Object.defineProperty(exports, "__esModule", { value: true }); __exportStar(requirePrimitive(), exports); __exportStar(requireBuiltIn(), exports); __exportStar(requireKeyOfBase(), exports); __exportStar(requireStrictExclude(), exports); __exportStar(requireStrictExtract(), exports); __exportStar(requireStrictOmit(), exports); __exportStar(requireWritable(), exports); // Utility types __exportStar(requireAsyncOrSync(), exports); __exportStar(requireAsyncOrSyncType(), exports); __exportStar(requireDictionary(), exports); __exportStar(requireDictionaryValues(), exports); __exportStar(requireMerge(), exports); __exportStar(requireMergeN(), exports); __exportStar(requireNewable(), exports); __exportStar(requireNonNever(), exports); __exportStar(requireOmitProperties(), exports); __exportStar(requireOpaque(), exports); __exportStar(requirePathValue(), exports); __exportStar(requirePaths(), exports); __exportStar(requirePickProperties(), exports); __exportStar(requirePrettify(), exports); __exportStar(requireSafeDictionary(), exports); __exportStar(requireUnionToIntersection(), exports); __exportStar(requireValueOf(), exports); __exportStar(requireXor(), exports); // Mark wrapper types __exportStar(requireMarkOptional(), exports); __exportStar(requireMarkReadonly(), exports); __exportStar(requireMarkRequired(), exports); __exportStar(requireMarkWritable(), exports); // Deep wrapper types __exportStar(requireBuildable(), exports); __exportStar(requireDeepNonNullable(), exports); __exportStar(requireDeepNullable(), exports); __exportStar(requireStrictDeepOmit(), exports); __exportStar(requireDeepOmit(), exports); __exportStar(requireDeepPartial(), exports); __exportStar(requireStrictDeepPick(), exports); __exportStar(requireDeepPick(), exports); __exportStar(requireDeepReadonly(), exports); __exportStar(requireDeepRequired(), exports); __exportStar(requireDeepUndefinable(), exports); __exportStar(requireDeepWritable(), exports); // Key types __exportStar(requireOptionalKeys(), exports); __exportStar(requirePickKeys(), exports); __exportStar(requireReadonlyKeys(), exports); __exportStar(requireRequiredKeys(), exports); __exportStar(requireWritableKeys(), exports); // Type checkers __exportStar(requireExact(), exports); __exportStar(requireIsAny(), exports); __exportStar(requireIsNever(), exports); __exportStar(requireIsUnknown(), exports); __exportStar(requireIsTuple(), exports); __exportStar(requireNonEmptyObject(), exports); // Arrays and Tuples __exportStar(requireAnyArray(), exports); __exportStar(requireArrayOrSingle(), exports); __exportStar(requireElementOf(), exports); __exportStar(requireHead(), exports); __exportStar(requireNonEmptyArray(), exports); __exportStar(requireReadonlyArrayOrSingle(), exports); __exportStar(requireTail(), exports); __exportStar(requireTuple(), exports); // Change case __exportStar(requireCamelCase(), exports); __exportStar(requireDeepCamelCaseProperties(), exports); // Function types __exportStar(requireAnyFunction(), exports); __exportStar(requirePredicateFunction(), exports); __exportStar(requirePredicateType(), exports); // Utility functions __exportStar(requireUnreachableCaseError(), exports); __exportStar(requireAssert(), exports); __exportStar(requireCreateFactoryWithConstraint(), exports); __exportStar(requireIsExact(), exports); __exportStar(requireNoop(), exports); // Build-in types __exportStar(requireAwaited(), exports); } (dist)); return dist; } var distExports = requireDist(); const OutboxMessagesCollectionName = '__outboxMessages'; const OutboxConsumersCollectionName = '__outboxConsumers'; const SupportedMongoVersions = ['5.0.0', '6.0.0', '7.0.0', '8.0.0-rc.18']; const SupportedMajorMongoVersions = SupportedMongoVersions.map((semver) => { const { major } = parseSemVer(semver); assert$1(major); return major; }); const createChangeStream = (getFullDocumentValue, messages, partitionKey, resumeToken) => { const pipeline = [ { $match: { operationType: 'insert', 'fullDocument.partitionKey': partitionKey, }, }, ]; return messages.watch(pipeline, { fullDocument: getFullDocumentValue(), startAfter: resumeToken, }); }; const ensureIndexes = async (db) => { const consumers = db.collection(OutboxConsumersCollectionName); await consumers.createIndex({ partitionKey: 1 }, { unique: true, name: 'idx_partitionKey_asc' }); }; const getConsumer = async (db, partitionKey) => { const consumers = db.collection(OutboxConsumersCollectionName); let consumer = await consumers.findOne({ partitionKey }); if (!consumer) { consumer = { _id: new ObjectId(), lastProcessedId: null, resumeToken: undefined, partitionKey, lastUpdatedAt: null, createdAt: new Date(), }; await consumers.insertOne(consumer); } const that = { async update(lastProcessedId, resumeToken) { assert$1(consumer); const { modifiedCount } = await consumers.updateOne({ _id: that._id }, { $set: { lastProcessedId, resumeToken, lastUpdatedAt: new Date() } }); if (!modifiedCount) { throw new Error(`Cant update the consumer ${that._id.toString()}.`); } consumer.lastProcessedId = lastProcessedId; consumer.resumeToken = resumeToken; }, async delete() { await consumers.deleteOne({ _id: that._id }); }, ...consumer, }; return that; }; const generateVersionPolicies = async (db) => { const buildInfo = (await db.admin().buildInfo()); const semver = parseSemVer(buildInfo.version); const major = semver.major || 0; const throwNotSupportedError = () => { throw new NotSupportedMongoVersionError({ currentVersion: buildInfo.version, supportedVersions: SupportedMajorMongoVersions, }); }; const supportedVersionCheckPolicy = () => { if (major < 5) { throwNotSupportedError(); } }; const changeStreamFullDocumentValuePolicy = (() => { if (major >= 6) { return 'whenAvailable'; } else if (major === 5) { return 'updateLookup'; } else { throwNotSupportedError(); } }); return { supportedVersionCheckPolicy, changeStreamFullDocumentValuePolicy, }; }; const createOutboxConsumer = (params) => { const { client, db, publish: _publish } = params; const partitionKey = params.partitionKey || 'default'; const saveTimestamps = params.saveTimestamps || false; const _now = params.now; const now = typeof _now === 'function' ? () => { const value = _now(); assertDate(value); return value; } : () => new Date(); const waitAfterFailedPublishMs = params.waitAfterFailedPublishMs || 1000; const shouldDisposeOnSigterm = isNil(params.shouldDisposeOnSigterm) ? true : !!params.shouldDisposeOnSigterm; const onDbError = params.onDbError || distExports.noop; const onFailedPublish = params.onFailedPublish || distExports.noop; const messages = db.collection(OutboxMessagesCollectionName); const addMessage = async (event, partitionKey, session) => Array.isArray(event) ? await messages.insertMany(event.map((data) => ({ _id: new ObjectId(), partitionKey, occurredAt: new Date(), data, })), { session }) : await messages.insertOne({ _id: new ObjectId(), partitionKey, occurredAt: new Date(), data: event, }, { session }); let shouldStopPromise = CancellationPromise.resolved(undefined); return { async start() { const { supportedVersionCheckPolicy, changeStreamFullDocumentValuePolicy } = await generateVersionPolicies(db); supportedVersionCheckPolicy(); await ensureIndexes(db); await shouldStopPromise; shouldStopPromise = new CancellationPromise(); const consumer = await getConsumer(db, partitionKey); const watchCursor = createChangeStream(changeStreamFullDocumentValuePolicy, messages, partitionKey, consumer.resumeToken); const _waitUntilEventIsSent = async (event) => { let published = false; while (!watchCursor.closed) { try { await _publish(event); published = true; break; } catch (error) { onFailedPublish(error); await setTimeout(waitAfterFailedPublishMs); continue; } } return published; }; const watch = async () => { while (!watchCursor.closed) { try { const result = await Promise.race([shouldStopPromise, watchCursor.hasNext()]); if (result === null) { await watchCursor.close(); break; } if (result) { const { _id: resumeToken, operationType, fullDocument: message, documentKey } = await watchCursor.next(); if (operationType !== 'insert') { continue; } if (await _waitUntilEventIsSent(message.data)) { if (saveTimestamps) { await db .collection(OutboxMessagesCollectionName) .updateOne({ _id: message._id }, { $set: { sentAt: now() } }); await consumer.update(documentKey._id, resumeToken); } else { await consumer.update(documentKey._id, resumeToken); } } } } catch (error) { onDbError(error); await setTimeout(waitAfterFailedPublishMs); } } }; watch() .catch(console.error) .finally(() => swallow(() => watchCursor.close())); const stop = async function stop() { if (!watchCursor.closed) { shouldStopPromise.resolve(null); await watchCursor.close(); } }; if (shouldDisposeOnSigterm) { addDisposeOnSigterm(stop); } return stop; }, async publish(event, sessionOrCallback) { if (sessionOrCallback instanceof ClientSession || !sessionOrCallback) { await addMessage(event, partitionKey, sessionOrCallback); } else { await client.withSession(async (session) => { await session.withTransaction(async (session) => { await sessionOrCallback(session, db, client); await addMessage(event, partitionKey, session); }); }); } }, async withScope(scopeFn) { return await client.withSession((session) => session.withTransaction(async (session) => { const publish = async (event) => { await addMessage(event, partitionKey, session); }; return await scopeFn({ publish, session, client }); })); }, }; }; export { createOutboxConsumer }; //# sourceMappingURL=index.mjs.map