@globalart/nestjs-typeorm-outbox 1.7.0 → 1.7.1
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 +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -187,7 +187,7 @@ let TypeormOutboxCronService = class TypeormOutboxCronService {
|
|
|
187
187
|
await queryRunner.connect();
|
|
188
188
|
try {
|
|
189
189
|
await queryRunner.startTransaction();
|
|
190
|
-
const entities = await queryRunner.manager.createQueryBuilder(TypeormOutboxEntity, "e").where("e.status = :status", { status: "pending" }).orderBy("e.createdAt", "ASC").setLock("
|
|
190
|
+
const entities = await queryRunner.manager.createQueryBuilder(TypeormOutboxEntity, "e").where("e.status = :status", { status: "pending" }).orderBy("e.createdAt", "ASC").setLock("pessimistic_write", void 0, ["SKIP LOCKED"]).getMany();
|
|
191
191
|
if (entities.length) await queryRunner.manager.update(TypeormOutboxEntity, entities.map((e) => e.id), { status: "processing" });
|
|
192
192
|
await queryRunner.commitTransaction();
|
|
193
193
|
return entities;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["CronJob","Transport","TypeOrmModule","ClientProxyFactory"],"sources":["../src/core/typeorm-outbox.di-tokens.ts","../src/core/typeorm-outbox.entity.ts","../src/core/typeorm-outbox.enums.ts","../src/core/typeorm-outbox.interfaces.ts","../src/core/typeorm-outbox-cron.service.ts","../src/core/typeorm-outbox.service.ts","../src/core/typeorm-outbox.module.ts"],"sourcesContent":["import { Inject } from \"@nestjs/common\";\n\nexport const TYPEORM_OUTBOX_CRON_CONFIG_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_CRON_CONFIG_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_SERVICE_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_SERVICE_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_BROKER_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_BROKER_TOKEN\",\n);\n\nexport const InjectTypeormOutboxCronConfig = () =>\n Inject(TYPEORM_OUTBOX_CRON_CONFIG_TOKEN);\nexport const InjectTypeormOutboxModuleConfig = () =>\n Inject(TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN);\nexport const InjectTypeormOutboxService = () =>\n Inject(TYPEORM_OUTBOX_SERVICE_TOKEN);\nexport const InjectTypeormOutboxBroker = () =>\n Inject(TYPEORM_OUTBOX_BROKER_TOKEN);\n","import {\n Column,\n CreateDateColumn,\n Entity,\n PrimaryColumn,\n PrimaryGeneratedColumn,\n UpdateDateColumn,\n} from \"typeorm\";\n\n@Entity(\"outbox_messages\")\nexport class TypeormOutboxEntity {\n @PrimaryColumn()\n id!: string;\n\n @Column({ name: 'status', default: 'pending' })\n status!: string;\n\n @CreateDateColumn({ name: \"created_at\" })\n createdAt!: Date;\n\n @UpdateDateColumn({ name: \"updated_at\" })\n updatedAt!: Date;\n\n @Column(\"character varying\", { name: \"destination_topic\" })\n destinationTopic!: string;\n\n @Column(\"jsonb\", { nullable: true })\n headers!: Record<string, string>;\n\n @Column(\"jsonb\", { nullable: true })\n keys!: Record<string, unknown>;\n\n @Column(\"jsonb\")\n value!: Record<string, any>;\n}\n","export enum CronExpression {\n EVERY_SECOND = \"* * * * * *\",\n EVERY_2_SECONDS = \"*/2 * * * * *\",\n EVERY_3_SECONDS = \"*/3 * * * * *\",\n EVERY_4_SECONDS = \"*/4 * * * * *\",\n EVERY_5_SECONDS = \"*/5 * * * * *\",\n EVERY_6_SECONDS = \"*/6 * * * * *\",\n EVERY_7_SECONDS = \"*/7 * * * * *\",\n EVERY_8_SECONDS = \"*/8 * * * * *\",\n EVERY_9_SECONDS = \"*/9 * * * * *\",\n EVERY_10_SECONDS = \"*/10 * * * * *\",\n EVERY_11_SECONDS = \"*/11 * * * * *\",\n EVERY_12_SECONDS = \"*/12 * * * * *\",\n EVERY_13_SECONDS = \"*/13 * * * * *\",\n EVERY_14_SECONDS = \"*/14 * * * * *\",\n EVERY_15_SECONDS = \"*/15 * * * * *\",\n EVERY_16_SECONDS = \"*/16 * * * * *\",\n EVERY_17_SECONDS = \"*/17 * * * * *\",\n EVERY_18_SECONDS = \"*/18 * * * * *\",\n EVERY_19_SECONDS = \"*/19 * * * * *\",\n EVERY_20_SECONDS = \"*/20 * * * * *\",\n EVERY_21_SECONDS = \"*/21 * * * * *\",\n EVERY_22_SECONDS = \"*/22 * * * * *\",\n EVERY_23_SECONDS = \"*/23 * * * * *\",\n EVERY_24_SECONDS = \"*/24 * * * * *\",\n EVERY_25_SECONDS = \"*/25 * * * * *\",\n EVERY_26_SECONDS = \"*/26 * * * * *\",\n EVERY_27_SECONDS = \"*/27 * * * * *\",\n EVERY_28_SECONDS = \"*/28 * * * * *\",\n EVERY_29_SECONDS = \"*/29 * * * * *\",\n EVERY_30_SECONDS = \"*/30 * * * * *\",\n EVERY_31_SECONDS = \"*/31 * * * * *\",\n EVERY_32_SECONDS = \"*/32 * * * * *\",\n EVERY_33_SECONDS = \"*/33 * * * * *\",\n EVERY_34_SECONDS = \"*/34 * * * * *\",\n EVERY_35_SECONDS = \"*/35 * * * * *\",\n EVERY_36_SECONDS = \"*/36 * * * * *\",\n EVERY_37_SECONDS = \"*/37 * * * * *\",\n EVERY_38_SECONDS = \"*/38 * * * * *\",\n EVERY_39_SECONDS = \"*/39 * * * * *\",\n EVERY_40_SECONDS = \"*/40 * * * * *\",\n EVERY_41_SECONDS = \"*/41 * * * * *\",\n EVERY_42_SECONDS = \"*/42 * * * * *\",\n EVERY_43_SECONDS = \"*/43 * * * * *\",\n EVERY_44_SECONDS = \"*/44 * * * * *\",\n EVERY_45_SECONDS = \"*/45 * * * * *\",\n EVERY_46_SECONDS = \"*/46 * * * * *\",\n EVERY_47_SECONDS = \"*/47 * * * * *\",\n EVERY_48_SECONDS = \"*/48 * * * * *\",\n EVERY_49_SECONDS = \"*/49 * * * * *\",\n EVERY_50_SECONDS = \"*/50 * * * * *\",\n EVERY_51_SECONDS = \"*/51 * * * * *\",\n EVERY_52_SECONDS = \"*/52 * * * * *\",\n EVERY_53_SECONDS = \"*/53 * * * * *\",\n EVERY_54_SECONDS = \"*/54 * * * * *\",\n EVERY_55_SECONDS = \"*/55 * * * * *\",\n EVERY_56_SECONDS = \"*/56 * * * * *\",\n EVERY_57_SECONDS = \"*/57 * * * * *\",\n EVERY_58_SECONDS = \"*/58 * * * * *\",\n EVERY_59_SECONDS = \"*/59 * * * * *\",\n EVERY_MINUTE = \"0 * * * * *\",\n}","import { KafkaOptions, MqttOptions, NatsOptions } from \"@nestjs/microservices\";\nimport { InjectionToken, ModuleMetadata, Type } from \"@nestjs/common\";\nimport { CronExpression } from \"./typeorm-outbox.enums\";\n\ntype BrokerConfig = MqttOptions | NatsOptions | KafkaOptions;\n\nexport class TypeormOutboxRegisterCronModuleOptions {\n brokerConfig: BrokerConfig = {};\n deleteItem?: boolean = true;\n typeOrmConnectionName?: string = \"default\";\n cronExpression?: string = CronExpression.EVERY_SECOND;\n}\n\nexport interface TypeormOutboxRegisterCronAsyncOptions extends Pick<\n ModuleMetadata,\n \"imports\"\n> {\n inject?: InjectionToken[];\n useExisting?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useClass?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useFactory?: (\n ...args: any[]\n ) =>\n | Promise<TypeormOutboxRegisterCronModuleOptions>\n | TypeormOutboxRegisterCronModuleOptions;\n}\n\nexport class TypeormOutboxModuleOptions {\n typeOrmConnectionName?: string = \"default\";\n}\n\nexport interface TypeormOutboxModuleAsyncOptions extends Pick<\n ModuleMetadata,\n \"imports\"\n> {\n inject?: InjectionToken[];\n useFactory?: (\n ...args: any[]\n ) => Promise<TypeormOutboxModuleOptions> | TypeormOutboxModuleOptions;\n}\n","import {\n Injectable,\n OnApplicationBootstrap,\n OnApplicationShutdown,\n} from \"@nestjs/common\";\nimport {\n InjectTypeormOutboxBroker,\n InjectTypeormOutboxCronConfig,\n} from \"./typeorm-outbox.di-tokens\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { firstValueFrom } from \"rxjs\";\nimport { ClientProxy, Transport } from \"@nestjs/microservices\";\nimport { CronJob } from \"cron\";\nimport { TypeormOutboxRegisterCronModuleOptions } from \"./typeorm-outbox.interfaces\";\nimport { DataSource } from \"typeorm\";\nimport { CronExpression } from \"./typeorm-outbox.enums\";\n\n@Injectable()\nexport class TypeormOutboxCronService\n implements OnApplicationBootstrap, OnApplicationShutdown\n{\n constructor(\n @InjectTypeormOutboxBroker()\n private readonly brokerClient: ClientProxy,\n @InjectTypeormOutboxCronConfig()\n private readonly moduleConfig: TypeormOutboxRegisterCronModuleOptions,\n private readonly dataSource: DataSource,\n ) {}\n\n private cronJob!: CronJob;\n private isRunning = false;\n\n onApplicationBootstrap() {\n this.validateBrokerClient();\n this.cronJob = new CronJob(\n this.moduleConfig.cronExpression ?? CronExpression.EVERY_SECOND,\n () => {\n if (this.isRunning) return;\n this.isRunning = true;\n this.executeCronJob().finally(() => {\n this.isRunning = false;\n });\n },\n );\n this.cronJob.start();\n }\n\n onApplicationShutdown() {\n if (!this.cronJob) {\n return;\n }\n this.cronJob.stop();\n }\n\n private validateBrokerClient() {\n const brokerConfig = this.moduleConfig.brokerConfig;\n if (\n ![Transport.KAFKA, Transport.NATS, Transport.MQTT].includes(\n brokerConfig?.transport as Transport,\n )\n ) {\n throw new Error(\n `[TypeormOutboxCronService] Broker config must be an instance of KafkaOptions, NatsOptions, or MqttOptions`,\n );\n }\n }\n\n private async executeCronJob() {\n const entities = await this.claimPendingEntities();\n if (!entities.length) return;\n\n for (const entity of entities) {\n await firstValueFrom(\n this.brokerClient.emit(entity.destinationTopic, {\n key: entity.keys,\n value: entity.value,\n headers: entity.headers,\n }),\n );\n\n await this.finalizeEntity(entity.id);\n }\n }\n\n private async claimPendingEntities(): Promise<TypeormOutboxEntity[]> {\n const queryRunner = this.dataSource.createQueryRunner();\n await queryRunner.connect();\n\n try {\n await queryRunner.startTransaction();\n\n const entities = await queryRunner.manager\n .createQueryBuilder(TypeormOutboxEntity, \"e\")\n .where(\"e.status = :status\", { status: \"pending\" })\n .orderBy(\"e.createdAt\", \"ASC\")\n .setLock(\"pessimistic_write_or_fail\")\n .getMany();\n\n if (entities.length) {\n await queryRunner.manager.update(\n TypeormOutboxEntity,\n entities.map((e) => e.id),\n { status: \"processing\" },\n );\n }\n\n await queryRunner.commitTransaction();\n return entities;\n } catch (error) {\n await queryRunner.rollbackTransaction();\n throw error;\n } finally {\n await queryRunner.release();\n }\n }\n\n private async finalizeEntity(id: string): Promise<void> {\n if (this.moduleConfig.deleteItem) {\n await this.dataSource.manager.delete(TypeormOutboxEntity, id);\n } else {\n await this.dataSource.manager.update(\n TypeormOutboxEntity,\n { id },\n { status: \"sent\" },\n );\n }\n }\n}","import { Injectable } from \"@nestjs/common\";\nimport { InjectRepository } from \"@nestjs/typeorm\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { Repository } from \"typeorm\";\nimport { randomUUID } from \"crypto\";\n\nexport interface CreateOutboxOptions {\n destinationTopic: string;\n value: any;\n headers?: any;\n keys?: any;\n}\n\n@Injectable()\nexport class TypeormOutboxService {\n constructor(\n @InjectRepository(TypeormOutboxEntity)\n private readonly outboxRepository: Repository<TypeormOutboxEntity>,\n ) {}\n\n async create(options: CreateOutboxOptions): Promise<TypeormOutboxEntity> {\n return this.outboxRepository.save({\n id: randomUUID(),\n destinationTopic: options.destinationTopic,\n headers: options.headers,\n keys: options.keys,\n value: options.value,\n });\n }\n}\n","import { TypeOrmModule } from \"@nestjs/typeorm\";\nimport { DynamicModule, Module, Provider } from \"@nestjs/common\";\nimport {\n TypeormOutboxRegisterCronAsyncOptions,\n TypeormOutboxRegisterCronModuleOptions,\n TypeormOutboxModuleOptions,\n TypeormOutboxModuleAsyncOptions,\n} from \"./typeorm-outbox.interfaces\";\nimport {\n TYPEORM_OUTBOX_BROKER_TOKEN,\n TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n TYPEORM_OUTBOX_SERVICE_TOKEN,\n} from \"./typeorm-outbox.di-tokens\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { TypeormOutboxService } from \"./typeorm-outbox.service\";\nimport { ClientProxyFactory } from \"@nestjs/microservices\";\nimport { TypeormOutboxCronService } from \"./typeorm-outbox-cron.service\";\n\nconst serviceProvider = (): Provider => ({\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n});\n\nconst brokerProvider = (useValue: any = {}): Provider => ({\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useValue,\n});\n\nconst typeOrmFeature = (connectionName = \"default\") =>\n TypeOrmModule.forFeature([TypeormOutboxEntity], connectionName);\n\nconst mergeModuleOptions = <T extends object>(\n defaults: new () => T,\n overrides?: Partial<T>,\n): T => ({ ...new defaults(), ...overrides });\n\nconst moduleConfigProvider = (\n options: TypeormOutboxModuleOptions,\n): Provider => ({\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useValue: mergeModuleOptions(TypeormOutboxModuleOptions, options),\n});\n\nconst asyncModuleConfigProvider = (\n options: TypeormOutboxModuleAsyncOptions,\n): Provider => ({\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useFactory: async (...args: any[]) =>\n mergeModuleOptions(\n TypeormOutboxModuleOptions,\n await options.useFactory?.(...args),\n ),\n inject: options.inject || [],\n});\n\nconst cronConfigProvider = (\n options: TypeormOutboxRegisterCronAsyncOptions,\n): Provider => ({\n provide: TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n useFactory: async (...args: any[]) =>\n mergeModuleOptions(\n TypeormOutboxRegisterCronModuleOptions,\n await options.useFactory?.(...args),\n ),\n inject: options.inject || [],\n});\n\nconst cronBrokerProvider = (\n options: TypeormOutboxRegisterCronAsyncOptions,\n): Provider => ({\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useFactory: async (...args: any[]) => {\n const config = mergeModuleOptions(\n TypeormOutboxRegisterCronModuleOptions,\n await options.useFactory?.(...args),\n );\n return ClientProxyFactory.create(config?.brokerConfig ?? {});\n },\n inject: options.inject || [],\n});\n\n@Module({})\nexport class TypeormOutboxModule {\n static forRoot(options: TypeormOutboxModuleOptions = {}): DynamicModule {\n const providers = [\n moduleConfigProvider(options),\n serviceProvider(),\n brokerProvider(),\n ];\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [typeOrmFeature(options.typeOrmConnectionName)],\n providers,\n exports: providers,\n };\n }\n\n static forRootAsync(options: TypeormOutboxModuleAsyncOptions): DynamicModule {\n const providers = [\n asyncModuleConfigProvider(options),\n serviceProvider(),\n brokerProvider(),\n ];\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [typeOrmFeature()],\n providers,\n exports: providers,\n };\n }\n\n static registerCronAsync(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): DynamicModule {\n const providers = [\n cronConfigProvider(options),\n cronBrokerProvider(options),\n serviceProvider(),\n ];\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [typeOrmFeature()],\n providers: [TypeormOutboxCronService, ...providers],\n exports: providers,\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["CronJob","Transport","TypeOrmModule","ClientProxyFactory"],"sources":["../src/core/typeorm-outbox.di-tokens.ts","../src/core/typeorm-outbox.entity.ts","../src/core/typeorm-outbox.enums.ts","../src/core/typeorm-outbox.interfaces.ts","../src/core/typeorm-outbox-cron.service.ts","../src/core/typeorm-outbox.service.ts","../src/core/typeorm-outbox.module.ts"],"sourcesContent":["import { Inject } from \"@nestjs/common\";\n\nexport const TYPEORM_OUTBOX_CRON_CONFIG_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_CRON_CONFIG_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_SERVICE_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_SERVICE_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_BROKER_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_BROKER_TOKEN\",\n);\n\nexport const InjectTypeormOutboxCronConfig = () =>\n Inject(TYPEORM_OUTBOX_CRON_CONFIG_TOKEN);\nexport const InjectTypeormOutboxModuleConfig = () =>\n Inject(TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN);\nexport const InjectTypeormOutboxService = () =>\n Inject(TYPEORM_OUTBOX_SERVICE_TOKEN);\nexport const InjectTypeormOutboxBroker = () =>\n Inject(TYPEORM_OUTBOX_BROKER_TOKEN);\n","import {\n Column,\n CreateDateColumn,\n Entity,\n PrimaryColumn,\n PrimaryGeneratedColumn,\n UpdateDateColumn,\n} from \"typeorm\";\n\n@Entity(\"outbox_messages\")\nexport class TypeormOutboxEntity {\n @PrimaryColumn()\n id!: string;\n\n @Column({ name: 'status', default: 'pending' })\n status!: string;\n\n @CreateDateColumn({ name: \"created_at\" })\n createdAt!: Date;\n\n @UpdateDateColumn({ name: \"updated_at\" })\n updatedAt!: Date;\n\n @Column(\"character varying\", { name: \"destination_topic\" })\n destinationTopic!: string;\n\n @Column(\"jsonb\", { nullable: true })\n headers!: Record<string, string>;\n\n @Column(\"jsonb\", { nullable: true })\n keys!: Record<string, unknown>;\n\n @Column(\"jsonb\")\n value!: Record<string, any>;\n}\n","export enum CronExpression {\n EVERY_SECOND = \"* * * * * *\",\n EVERY_2_SECONDS = \"*/2 * * * * *\",\n EVERY_3_SECONDS = \"*/3 * * * * *\",\n EVERY_4_SECONDS = \"*/4 * * * * *\",\n EVERY_5_SECONDS = \"*/5 * * * * *\",\n EVERY_6_SECONDS = \"*/6 * * * * *\",\n EVERY_7_SECONDS = \"*/7 * * * * *\",\n EVERY_8_SECONDS = \"*/8 * * * * *\",\n EVERY_9_SECONDS = \"*/9 * * * * *\",\n EVERY_10_SECONDS = \"*/10 * * * * *\",\n EVERY_11_SECONDS = \"*/11 * * * * *\",\n EVERY_12_SECONDS = \"*/12 * * * * *\",\n EVERY_13_SECONDS = \"*/13 * * * * *\",\n EVERY_14_SECONDS = \"*/14 * * * * *\",\n EVERY_15_SECONDS = \"*/15 * * * * *\",\n EVERY_16_SECONDS = \"*/16 * * * * *\",\n EVERY_17_SECONDS = \"*/17 * * * * *\",\n EVERY_18_SECONDS = \"*/18 * * * * *\",\n EVERY_19_SECONDS = \"*/19 * * * * *\",\n EVERY_20_SECONDS = \"*/20 * * * * *\",\n EVERY_21_SECONDS = \"*/21 * * * * *\",\n EVERY_22_SECONDS = \"*/22 * * * * *\",\n EVERY_23_SECONDS = \"*/23 * * * * *\",\n EVERY_24_SECONDS = \"*/24 * * * * *\",\n EVERY_25_SECONDS = \"*/25 * * * * *\",\n EVERY_26_SECONDS = \"*/26 * * * * *\",\n EVERY_27_SECONDS = \"*/27 * * * * *\",\n EVERY_28_SECONDS = \"*/28 * * * * *\",\n EVERY_29_SECONDS = \"*/29 * * * * *\",\n EVERY_30_SECONDS = \"*/30 * * * * *\",\n EVERY_31_SECONDS = \"*/31 * * * * *\",\n EVERY_32_SECONDS = \"*/32 * * * * *\",\n EVERY_33_SECONDS = \"*/33 * * * * *\",\n EVERY_34_SECONDS = \"*/34 * * * * *\",\n EVERY_35_SECONDS = \"*/35 * * * * *\",\n EVERY_36_SECONDS = \"*/36 * * * * *\",\n EVERY_37_SECONDS = \"*/37 * * * * *\",\n EVERY_38_SECONDS = \"*/38 * * * * *\",\n EVERY_39_SECONDS = \"*/39 * * * * *\",\n EVERY_40_SECONDS = \"*/40 * * * * *\",\n EVERY_41_SECONDS = \"*/41 * * * * *\",\n EVERY_42_SECONDS = \"*/42 * * * * *\",\n EVERY_43_SECONDS = \"*/43 * * * * *\",\n EVERY_44_SECONDS = \"*/44 * * * * *\",\n EVERY_45_SECONDS = \"*/45 * * * * *\",\n EVERY_46_SECONDS = \"*/46 * * * * *\",\n EVERY_47_SECONDS = \"*/47 * * * * *\",\n EVERY_48_SECONDS = \"*/48 * * * * *\",\n EVERY_49_SECONDS = \"*/49 * * * * *\",\n EVERY_50_SECONDS = \"*/50 * * * * *\",\n EVERY_51_SECONDS = \"*/51 * * * * *\",\n EVERY_52_SECONDS = \"*/52 * * * * *\",\n EVERY_53_SECONDS = \"*/53 * * * * *\",\n EVERY_54_SECONDS = \"*/54 * * * * *\",\n EVERY_55_SECONDS = \"*/55 * * * * *\",\n EVERY_56_SECONDS = \"*/56 * * * * *\",\n EVERY_57_SECONDS = \"*/57 * * * * *\",\n EVERY_58_SECONDS = \"*/58 * * * * *\",\n EVERY_59_SECONDS = \"*/59 * * * * *\",\n EVERY_MINUTE = \"0 * * * * *\",\n}","import { KafkaOptions, MqttOptions, NatsOptions } from \"@nestjs/microservices\";\nimport { InjectionToken, ModuleMetadata, Type } from \"@nestjs/common\";\nimport { CronExpression } from \"./typeorm-outbox.enums\";\n\ntype BrokerConfig = MqttOptions | NatsOptions | KafkaOptions;\n\nexport class TypeormOutboxRegisterCronModuleOptions {\n brokerConfig: BrokerConfig = {};\n deleteItem?: boolean = true;\n typeOrmConnectionName?: string = \"default\";\n cronExpression?: string = CronExpression.EVERY_SECOND;\n}\n\nexport interface TypeormOutboxRegisterCronAsyncOptions extends Pick<\n ModuleMetadata,\n \"imports\"\n> {\n inject?: InjectionToken[];\n useExisting?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useClass?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useFactory?: (\n ...args: any[]\n ) =>\n | Promise<TypeormOutboxRegisterCronModuleOptions>\n | TypeormOutboxRegisterCronModuleOptions;\n}\n\nexport class TypeormOutboxModuleOptions {\n typeOrmConnectionName?: string = \"default\";\n}\n\nexport interface TypeormOutboxModuleAsyncOptions extends Pick<\n ModuleMetadata,\n \"imports\"\n> {\n inject?: InjectionToken[];\n useFactory?: (\n ...args: any[]\n ) => Promise<TypeormOutboxModuleOptions> | TypeormOutboxModuleOptions;\n}\n","import {\n Injectable,\n OnApplicationBootstrap,\n OnApplicationShutdown,\n} from \"@nestjs/common\";\nimport {\n InjectTypeormOutboxBroker,\n InjectTypeormOutboxCronConfig,\n} from \"./typeorm-outbox.di-tokens\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { firstValueFrom } from \"rxjs\";\nimport { ClientProxy, Transport } from \"@nestjs/microservices\";\nimport { CronJob } from \"cron\";\nimport { TypeormOutboxRegisterCronModuleOptions } from \"./typeorm-outbox.interfaces\";\nimport { DataSource } from \"typeorm\";\nimport { CronExpression } from \"./typeorm-outbox.enums\";\n\n@Injectable()\nexport class TypeormOutboxCronService\n implements OnApplicationBootstrap, OnApplicationShutdown\n{\n constructor(\n @InjectTypeormOutboxBroker()\n private readonly brokerClient: ClientProxy,\n @InjectTypeormOutboxCronConfig()\n private readonly moduleConfig: TypeormOutboxRegisterCronModuleOptions,\n private readonly dataSource: DataSource,\n ) {}\n\n private cronJob!: CronJob;\n private isRunning = false;\n\n onApplicationBootstrap() {\n this.validateBrokerClient();\n this.cronJob = new CronJob(\n this.moduleConfig.cronExpression ?? CronExpression.EVERY_SECOND,\n () => {\n if (this.isRunning) return;\n this.isRunning = true;\n this.executeCronJob().finally(() => {\n this.isRunning = false;\n });\n },\n );\n this.cronJob.start();\n }\n\n onApplicationShutdown() {\n if (!this.cronJob) {\n return;\n }\n this.cronJob.stop();\n }\n\n private validateBrokerClient() {\n const brokerConfig = this.moduleConfig.brokerConfig;\n if (\n ![Transport.KAFKA, Transport.NATS, Transport.MQTT].includes(\n brokerConfig?.transport as Transport,\n )\n ) {\n throw new Error(\n `[TypeormOutboxCronService] Broker config must be an instance of KafkaOptions, NatsOptions, or MqttOptions`,\n );\n }\n }\n\n private async executeCronJob() {\n const entities = await this.claimPendingEntities();\n if (!entities.length) return;\n\n for (const entity of entities) {\n await firstValueFrom(\n this.brokerClient.emit(entity.destinationTopic, {\n key: entity.keys,\n value: entity.value,\n headers: entity.headers,\n }),\n );\n\n await this.finalizeEntity(entity.id);\n }\n }\n\n private async claimPendingEntities(): Promise<TypeormOutboxEntity[]> {\n const queryRunner = this.dataSource.createQueryRunner();\n await queryRunner.connect();\n\n try {\n await queryRunner.startTransaction();\n\n const entities = await queryRunner.manager\n .createQueryBuilder(TypeormOutboxEntity, \"e\")\n .where(\"e.status = :status\", { status: \"pending\" })\n .orderBy(\"e.createdAt\", \"ASC\")\n .setLock(\"pessimistic_write\", undefined, [\"SKIP LOCKED\"])\n .getMany();\n\n if (entities.length) {\n await queryRunner.manager.update(\n TypeormOutboxEntity,\n entities.map((e) => e.id),\n { status: \"processing\" },\n );\n }\n\n await queryRunner.commitTransaction();\n return entities;\n } catch (error) {\n await queryRunner.rollbackTransaction();\n throw error;\n } finally {\n await queryRunner.release();\n }\n }\n\n private async finalizeEntity(id: string): Promise<void> {\n if (this.moduleConfig.deleteItem) {\n await this.dataSource.manager.delete(TypeormOutboxEntity, id);\n } else {\n await this.dataSource.manager.update(\n TypeormOutboxEntity,\n { id },\n { status: \"sent\" },\n );\n }\n }\n}","import { Injectable } from \"@nestjs/common\";\nimport { InjectRepository } from \"@nestjs/typeorm\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { Repository } from \"typeorm\";\nimport { randomUUID } from \"crypto\";\n\nexport interface CreateOutboxOptions {\n destinationTopic: string;\n value: any;\n headers?: any;\n keys?: any;\n}\n\n@Injectable()\nexport class TypeormOutboxService {\n constructor(\n @InjectRepository(TypeormOutboxEntity)\n private readonly outboxRepository: Repository<TypeormOutboxEntity>,\n ) {}\n\n async create(options: CreateOutboxOptions): Promise<TypeormOutboxEntity> {\n return this.outboxRepository.save({\n id: randomUUID(),\n destinationTopic: options.destinationTopic,\n headers: options.headers,\n keys: options.keys,\n value: options.value,\n });\n }\n}\n","import { TypeOrmModule } from \"@nestjs/typeorm\";\nimport { DynamicModule, Module, Provider } from \"@nestjs/common\";\nimport {\n TypeormOutboxRegisterCronAsyncOptions,\n TypeormOutboxRegisterCronModuleOptions,\n TypeormOutboxModuleOptions,\n TypeormOutboxModuleAsyncOptions,\n} from \"./typeorm-outbox.interfaces\";\nimport {\n TYPEORM_OUTBOX_BROKER_TOKEN,\n TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n TYPEORM_OUTBOX_SERVICE_TOKEN,\n} from \"./typeorm-outbox.di-tokens\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { TypeormOutboxService } from \"./typeorm-outbox.service\";\nimport { ClientProxyFactory } from \"@nestjs/microservices\";\nimport { TypeormOutboxCronService } from \"./typeorm-outbox-cron.service\";\n\nconst serviceProvider = (): Provider => ({\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n});\n\nconst brokerProvider = (useValue: any = {}): Provider => ({\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useValue,\n});\n\nconst typeOrmFeature = (connectionName = \"default\") =>\n TypeOrmModule.forFeature([TypeormOutboxEntity], connectionName);\n\nconst mergeModuleOptions = <T extends object>(\n defaults: new () => T,\n overrides?: Partial<T>,\n): T => ({ ...new defaults(), ...overrides });\n\nconst moduleConfigProvider = (\n options: TypeormOutboxModuleOptions,\n): Provider => ({\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useValue: mergeModuleOptions(TypeormOutboxModuleOptions, options),\n});\n\nconst asyncModuleConfigProvider = (\n options: TypeormOutboxModuleAsyncOptions,\n): Provider => ({\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useFactory: async (...args: any[]) =>\n mergeModuleOptions(\n TypeormOutboxModuleOptions,\n await options.useFactory?.(...args),\n ),\n inject: options.inject || [],\n});\n\nconst cronConfigProvider = (\n options: TypeormOutboxRegisterCronAsyncOptions,\n): Provider => ({\n provide: TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n useFactory: async (...args: any[]) =>\n mergeModuleOptions(\n TypeormOutboxRegisterCronModuleOptions,\n await options.useFactory?.(...args),\n ),\n inject: options.inject || [],\n});\n\nconst cronBrokerProvider = (\n options: TypeormOutboxRegisterCronAsyncOptions,\n): Provider => ({\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useFactory: async (...args: any[]) => {\n const config = mergeModuleOptions(\n TypeormOutboxRegisterCronModuleOptions,\n await options.useFactory?.(...args),\n );\n return ClientProxyFactory.create(config?.brokerConfig ?? {});\n },\n inject: options.inject || [],\n});\n\n@Module({})\nexport class TypeormOutboxModule {\n static forRoot(options: TypeormOutboxModuleOptions = {}): DynamicModule {\n const providers = [\n moduleConfigProvider(options),\n serviceProvider(),\n brokerProvider(),\n ];\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [typeOrmFeature(options.typeOrmConnectionName)],\n providers,\n exports: providers,\n };\n }\n\n static forRootAsync(options: TypeormOutboxModuleAsyncOptions): DynamicModule {\n const providers = [\n asyncModuleConfigProvider(options),\n serviceProvider(),\n brokerProvider(),\n ];\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [typeOrmFeature()],\n providers,\n exports: providers,\n };\n }\n\n static registerCronAsync(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): DynamicModule {\n const providers = [\n cronConfigProvider(options),\n cronBrokerProvider(options),\n serviceProvider(),\n ];\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [typeOrmFeature()],\n providers: [TypeormOutboxCronService, ...providers],\n exports: providers,\n };\n }\n}\n"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -186,7 +186,7 @@ let TypeormOutboxCronService = class TypeormOutboxCronService {
|
|
|
186
186
|
await queryRunner.connect();
|
|
187
187
|
try {
|
|
188
188
|
await queryRunner.startTransaction();
|
|
189
|
-
const entities = await queryRunner.manager.createQueryBuilder(TypeormOutboxEntity, "e").where("e.status = :status", { status: "pending" }).orderBy("e.createdAt", "ASC").setLock("
|
|
189
|
+
const entities = await queryRunner.manager.createQueryBuilder(TypeormOutboxEntity, "e").where("e.status = :status", { status: "pending" }).orderBy("e.createdAt", "ASC").setLock("pessimistic_write", void 0, ["SKIP LOCKED"]).getMany();
|
|
190
190
|
if (entities.length) await queryRunner.manager.update(TypeormOutboxEntity, entities.map((e) => e.id), { status: "processing" });
|
|
191
191
|
await queryRunner.commitTransaction();
|
|
192
192
|
return entities;
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/core/typeorm-outbox.di-tokens.ts","../src/core/typeorm-outbox.entity.ts","../src/core/typeorm-outbox.enums.ts","../src/core/typeorm-outbox.interfaces.ts","../src/core/typeorm-outbox-cron.service.ts","../src/core/typeorm-outbox.service.ts","../src/core/typeorm-outbox.module.ts"],"sourcesContent":["import { Inject } from \"@nestjs/common\";\n\nexport const TYPEORM_OUTBOX_CRON_CONFIG_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_CRON_CONFIG_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_SERVICE_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_SERVICE_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_BROKER_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_BROKER_TOKEN\",\n);\n\nexport const InjectTypeormOutboxCronConfig = () =>\n Inject(TYPEORM_OUTBOX_CRON_CONFIG_TOKEN);\nexport const InjectTypeormOutboxModuleConfig = () =>\n Inject(TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN);\nexport const InjectTypeormOutboxService = () =>\n Inject(TYPEORM_OUTBOX_SERVICE_TOKEN);\nexport const InjectTypeormOutboxBroker = () =>\n Inject(TYPEORM_OUTBOX_BROKER_TOKEN);\n","import {\n Column,\n CreateDateColumn,\n Entity,\n PrimaryColumn,\n PrimaryGeneratedColumn,\n UpdateDateColumn,\n} from \"typeorm\";\n\n@Entity(\"outbox_messages\")\nexport class TypeormOutboxEntity {\n @PrimaryColumn()\n id!: string;\n\n @Column({ name: 'status', default: 'pending' })\n status!: string;\n\n @CreateDateColumn({ name: \"created_at\" })\n createdAt!: Date;\n\n @UpdateDateColumn({ name: \"updated_at\" })\n updatedAt!: Date;\n\n @Column(\"character varying\", { name: \"destination_topic\" })\n destinationTopic!: string;\n\n @Column(\"jsonb\", { nullable: true })\n headers!: Record<string, string>;\n\n @Column(\"jsonb\", { nullable: true })\n keys!: Record<string, unknown>;\n\n @Column(\"jsonb\")\n value!: Record<string, any>;\n}\n","export enum CronExpression {\n EVERY_SECOND = \"* * * * * *\",\n EVERY_2_SECONDS = \"*/2 * * * * *\",\n EVERY_3_SECONDS = \"*/3 * * * * *\",\n EVERY_4_SECONDS = \"*/4 * * * * *\",\n EVERY_5_SECONDS = \"*/5 * * * * *\",\n EVERY_6_SECONDS = \"*/6 * * * * *\",\n EVERY_7_SECONDS = \"*/7 * * * * *\",\n EVERY_8_SECONDS = \"*/8 * * * * *\",\n EVERY_9_SECONDS = \"*/9 * * * * *\",\n EVERY_10_SECONDS = \"*/10 * * * * *\",\n EVERY_11_SECONDS = \"*/11 * * * * *\",\n EVERY_12_SECONDS = \"*/12 * * * * *\",\n EVERY_13_SECONDS = \"*/13 * * * * *\",\n EVERY_14_SECONDS = \"*/14 * * * * *\",\n EVERY_15_SECONDS = \"*/15 * * * * *\",\n EVERY_16_SECONDS = \"*/16 * * * * *\",\n EVERY_17_SECONDS = \"*/17 * * * * *\",\n EVERY_18_SECONDS = \"*/18 * * * * *\",\n EVERY_19_SECONDS = \"*/19 * * * * *\",\n EVERY_20_SECONDS = \"*/20 * * * * *\",\n EVERY_21_SECONDS = \"*/21 * * * * *\",\n EVERY_22_SECONDS = \"*/22 * * * * *\",\n EVERY_23_SECONDS = \"*/23 * * * * *\",\n EVERY_24_SECONDS = \"*/24 * * * * *\",\n EVERY_25_SECONDS = \"*/25 * * * * *\",\n EVERY_26_SECONDS = \"*/26 * * * * *\",\n EVERY_27_SECONDS = \"*/27 * * * * *\",\n EVERY_28_SECONDS = \"*/28 * * * * *\",\n EVERY_29_SECONDS = \"*/29 * * * * *\",\n EVERY_30_SECONDS = \"*/30 * * * * *\",\n EVERY_31_SECONDS = \"*/31 * * * * *\",\n EVERY_32_SECONDS = \"*/32 * * * * *\",\n EVERY_33_SECONDS = \"*/33 * * * * *\",\n EVERY_34_SECONDS = \"*/34 * * * * *\",\n EVERY_35_SECONDS = \"*/35 * * * * *\",\n EVERY_36_SECONDS = \"*/36 * * * * *\",\n EVERY_37_SECONDS = \"*/37 * * * * *\",\n EVERY_38_SECONDS = \"*/38 * * * * *\",\n EVERY_39_SECONDS = \"*/39 * * * * *\",\n EVERY_40_SECONDS = \"*/40 * * * * *\",\n EVERY_41_SECONDS = \"*/41 * * * * *\",\n EVERY_42_SECONDS = \"*/42 * * * * *\",\n EVERY_43_SECONDS = \"*/43 * * * * *\",\n EVERY_44_SECONDS = \"*/44 * * * * *\",\n EVERY_45_SECONDS = \"*/45 * * * * *\",\n EVERY_46_SECONDS = \"*/46 * * * * *\",\n EVERY_47_SECONDS = \"*/47 * * * * *\",\n EVERY_48_SECONDS = \"*/48 * * * * *\",\n EVERY_49_SECONDS = \"*/49 * * * * *\",\n EVERY_50_SECONDS = \"*/50 * * * * *\",\n EVERY_51_SECONDS = \"*/51 * * * * *\",\n EVERY_52_SECONDS = \"*/52 * * * * *\",\n EVERY_53_SECONDS = \"*/53 * * * * *\",\n EVERY_54_SECONDS = \"*/54 * * * * *\",\n EVERY_55_SECONDS = \"*/55 * * * * *\",\n EVERY_56_SECONDS = \"*/56 * * * * *\",\n EVERY_57_SECONDS = \"*/57 * * * * *\",\n EVERY_58_SECONDS = \"*/58 * * * * *\",\n EVERY_59_SECONDS = \"*/59 * * * * *\",\n EVERY_MINUTE = \"0 * * * * *\",\n}","import { KafkaOptions, MqttOptions, NatsOptions } from \"@nestjs/microservices\";\nimport { InjectionToken, ModuleMetadata, Type } from \"@nestjs/common\";\nimport { CronExpression } from \"./typeorm-outbox.enums\";\n\ntype BrokerConfig = MqttOptions | NatsOptions | KafkaOptions;\n\nexport class TypeormOutboxRegisterCronModuleOptions {\n brokerConfig: BrokerConfig = {};\n deleteItem?: boolean = true;\n typeOrmConnectionName?: string = \"default\";\n cronExpression?: string = CronExpression.EVERY_SECOND;\n}\n\nexport interface TypeormOutboxRegisterCronAsyncOptions extends Pick<\n ModuleMetadata,\n \"imports\"\n> {\n inject?: InjectionToken[];\n useExisting?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useClass?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useFactory?: (\n ...args: any[]\n ) =>\n | Promise<TypeormOutboxRegisterCronModuleOptions>\n | TypeormOutboxRegisterCronModuleOptions;\n}\n\nexport class TypeormOutboxModuleOptions {\n typeOrmConnectionName?: string = \"default\";\n}\n\nexport interface TypeormOutboxModuleAsyncOptions extends Pick<\n ModuleMetadata,\n \"imports\"\n> {\n inject?: InjectionToken[];\n useFactory?: (\n ...args: any[]\n ) => Promise<TypeormOutboxModuleOptions> | TypeormOutboxModuleOptions;\n}\n","import {\n Injectable,\n OnApplicationBootstrap,\n OnApplicationShutdown,\n} from \"@nestjs/common\";\nimport {\n InjectTypeormOutboxBroker,\n InjectTypeormOutboxCronConfig,\n} from \"./typeorm-outbox.di-tokens\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { firstValueFrom } from \"rxjs\";\nimport { ClientProxy, Transport } from \"@nestjs/microservices\";\nimport { CronJob } from \"cron\";\nimport { TypeormOutboxRegisterCronModuleOptions } from \"./typeorm-outbox.interfaces\";\nimport { DataSource } from \"typeorm\";\nimport { CronExpression } from \"./typeorm-outbox.enums\";\n\n@Injectable()\nexport class TypeormOutboxCronService\n implements OnApplicationBootstrap, OnApplicationShutdown\n{\n constructor(\n @InjectTypeormOutboxBroker()\n private readonly brokerClient: ClientProxy,\n @InjectTypeormOutboxCronConfig()\n private readonly moduleConfig: TypeormOutboxRegisterCronModuleOptions,\n private readonly dataSource: DataSource,\n ) {}\n\n private cronJob!: CronJob;\n private isRunning = false;\n\n onApplicationBootstrap() {\n this.validateBrokerClient();\n this.cronJob = new CronJob(\n this.moduleConfig.cronExpression ?? CronExpression.EVERY_SECOND,\n () => {\n if (this.isRunning) return;\n this.isRunning = true;\n this.executeCronJob().finally(() => {\n this.isRunning = false;\n });\n },\n );\n this.cronJob.start();\n }\n\n onApplicationShutdown() {\n if (!this.cronJob) {\n return;\n }\n this.cronJob.stop();\n }\n\n private validateBrokerClient() {\n const brokerConfig = this.moduleConfig.brokerConfig;\n if (\n ![Transport.KAFKA, Transport.NATS, Transport.MQTT].includes(\n brokerConfig?.transport as Transport,\n )\n ) {\n throw new Error(\n `[TypeormOutboxCronService] Broker config must be an instance of KafkaOptions, NatsOptions, or MqttOptions`,\n );\n }\n }\n\n private async executeCronJob() {\n const entities = await this.claimPendingEntities();\n if (!entities.length) return;\n\n for (const entity of entities) {\n await firstValueFrom(\n this.brokerClient.emit(entity.destinationTopic, {\n key: entity.keys,\n value: entity.value,\n headers: entity.headers,\n }),\n );\n\n await this.finalizeEntity(entity.id);\n }\n }\n\n private async claimPendingEntities(): Promise<TypeormOutboxEntity[]> {\n const queryRunner = this.dataSource.createQueryRunner();\n await queryRunner.connect();\n\n try {\n await queryRunner.startTransaction();\n\n const entities = await queryRunner.manager\n .createQueryBuilder(TypeormOutboxEntity, \"e\")\n .where(\"e.status = :status\", { status: \"pending\" })\n .orderBy(\"e.createdAt\", \"ASC\")\n .setLock(\"pessimistic_write_or_fail\")\n .getMany();\n\n if (entities.length) {\n await queryRunner.manager.update(\n TypeormOutboxEntity,\n entities.map((e) => e.id),\n { status: \"processing\" },\n );\n }\n\n await queryRunner.commitTransaction();\n return entities;\n } catch (error) {\n await queryRunner.rollbackTransaction();\n throw error;\n } finally {\n await queryRunner.release();\n }\n }\n\n private async finalizeEntity(id: string): Promise<void> {\n if (this.moduleConfig.deleteItem) {\n await this.dataSource.manager.delete(TypeormOutboxEntity, id);\n } else {\n await this.dataSource.manager.update(\n TypeormOutboxEntity,\n { id },\n { status: \"sent\" },\n );\n }\n }\n}","import { Injectable } from \"@nestjs/common\";\nimport { InjectRepository } from \"@nestjs/typeorm\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { Repository } from \"typeorm\";\nimport { randomUUID } from \"crypto\";\n\nexport interface CreateOutboxOptions {\n destinationTopic: string;\n value: any;\n headers?: any;\n keys?: any;\n}\n\n@Injectable()\nexport class TypeormOutboxService {\n constructor(\n @InjectRepository(TypeormOutboxEntity)\n private readonly outboxRepository: Repository<TypeormOutboxEntity>,\n ) {}\n\n async create(options: CreateOutboxOptions): Promise<TypeormOutboxEntity> {\n return this.outboxRepository.save({\n id: randomUUID(),\n destinationTopic: options.destinationTopic,\n headers: options.headers,\n keys: options.keys,\n value: options.value,\n });\n }\n}\n","import { TypeOrmModule } from \"@nestjs/typeorm\";\nimport { DynamicModule, Module, Provider } from \"@nestjs/common\";\nimport {\n TypeormOutboxRegisterCronAsyncOptions,\n TypeormOutboxRegisterCronModuleOptions,\n TypeormOutboxModuleOptions,\n TypeormOutboxModuleAsyncOptions,\n} from \"./typeorm-outbox.interfaces\";\nimport {\n TYPEORM_OUTBOX_BROKER_TOKEN,\n TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n TYPEORM_OUTBOX_SERVICE_TOKEN,\n} from \"./typeorm-outbox.di-tokens\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { TypeormOutboxService } from \"./typeorm-outbox.service\";\nimport { ClientProxyFactory } from \"@nestjs/microservices\";\nimport { TypeormOutboxCronService } from \"./typeorm-outbox-cron.service\";\n\nconst serviceProvider = (): Provider => ({\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n});\n\nconst brokerProvider = (useValue: any = {}): Provider => ({\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useValue,\n});\n\nconst typeOrmFeature = (connectionName = \"default\") =>\n TypeOrmModule.forFeature([TypeormOutboxEntity], connectionName);\n\nconst mergeModuleOptions = <T extends object>(\n defaults: new () => T,\n overrides?: Partial<T>,\n): T => ({ ...new defaults(), ...overrides });\n\nconst moduleConfigProvider = (\n options: TypeormOutboxModuleOptions,\n): Provider => ({\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useValue: mergeModuleOptions(TypeormOutboxModuleOptions, options),\n});\n\nconst asyncModuleConfigProvider = (\n options: TypeormOutboxModuleAsyncOptions,\n): Provider => ({\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useFactory: async (...args: any[]) =>\n mergeModuleOptions(\n TypeormOutboxModuleOptions,\n await options.useFactory?.(...args),\n ),\n inject: options.inject || [],\n});\n\nconst cronConfigProvider = (\n options: TypeormOutboxRegisterCronAsyncOptions,\n): Provider => ({\n provide: TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n useFactory: async (...args: any[]) =>\n mergeModuleOptions(\n TypeormOutboxRegisterCronModuleOptions,\n await options.useFactory?.(...args),\n ),\n inject: options.inject || [],\n});\n\nconst cronBrokerProvider = (\n options: TypeormOutboxRegisterCronAsyncOptions,\n): Provider => ({\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useFactory: async (...args: any[]) => {\n const config = mergeModuleOptions(\n TypeormOutboxRegisterCronModuleOptions,\n await options.useFactory?.(...args),\n );\n return ClientProxyFactory.create(config?.brokerConfig ?? {});\n },\n inject: options.inject || [],\n});\n\n@Module({})\nexport class TypeormOutboxModule {\n static forRoot(options: TypeormOutboxModuleOptions = {}): DynamicModule {\n const providers = [\n moduleConfigProvider(options),\n serviceProvider(),\n brokerProvider(),\n ];\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [typeOrmFeature(options.typeOrmConnectionName)],\n providers,\n exports: providers,\n };\n }\n\n static forRootAsync(options: TypeormOutboxModuleAsyncOptions): DynamicModule {\n const providers = [\n asyncModuleConfigProvider(options),\n serviceProvider(),\n brokerProvider(),\n ];\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [typeOrmFeature()],\n providers,\n exports: providers,\n };\n }\n\n static registerCronAsync(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): DynamicModule {\n const providers = [\n cronConfigProvider(options),\n cronBrokerProvider(options),\n serviceProvider(),\n ];\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [typeOrmFeature()],\n providers: [TypeormOutboxCronService, ...providers],\n exports: providers,\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/core/typeorm-outbox.di-tokens.ts","../src/core/typeorm-outbox.entity.ts","../src/core/typeorm-outbox.enums.ts","../src/core/typeorm-outbox.interfaces.ts","../src/core/typeorm-outbox-cron.service.ts","../src/core/typeorm-outbox.service.ts","../src/core/typeorm-outbox.module.ts"],"sourcesContent":["import { Inject } from \"@nestjs/common\";\n\nexport const TYPEORM_OUTBOX_CRON_CONFIG_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_CRON_CONFIG_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_SERVICE_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_SERVICE_TOKEN\",\n);\nexport const TYPEORM_OUTBOX_BROKER_TOKEN = Symbol(\n \"TYPEORM_OUTBOX_BROKER_TOKEN\",\n);\n\nexport const InjectTypeormOutboxCronConfig = () =>\n Inject(TYPEORM_OUTBOX_CRON_CONFIG_TOKEN);\nexport const InjectTypeormOutboxModuleConfig = () =>\n Inject(TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN);\nexport const InjectTypeormOutboxService = () =>\n Inject(TYPEORM_OUTBOX_SERVICE_TOKEN);\nexport const InjectTypeormOutboxBroker = () =>\n Inject(TYPEORM_OUTBOX_BROKER_TOKEN);\n","import {\n Column,\n CreateDateColumn,\n Entity,\n PrimaryColumn,\n PrimaryGeneratedColumn,\n UpdateDateColumn,\n} from \"typeorm\";\n\n@Entity(\"outbox_messages\")\nexport class TypeormOutboxEntity {\n @PrimaryColumn()\n id!: string;\n\n @Column({ name: 'status', default: 'pending' })\n status!: string;\n\n @CreateDateColumn({ name: \"created_at\" })\n createdAt!: Date;\n\n @UpdateDateColumn({ name: \"updated_at\" })\n updatedAt!: Date;\n\n @Column(\"character varying\", { name: \"destination_topic\" })\n destinationTopic!: string;\n\n @Column(\"jsonb\", { nullable: true })\n headers!: Record<string, string>;\n\n @Column(\"jsonb\", { nullable: true })\n keys!: Record<string, unknown>;\n\n @Column(\"jsonb\")\n value!: Record<string, any>;\n}\n","export enum CronExpression {\n EVERY_SECOND = \"* * * * * *\",\n EVERY_2_SECONDS = \"*/2 * * * * *\",\n EVERY_3_SECONDS = \"*/3 * * * * *\",\n EVERY_4_SECONDS = \"*/4 * * * * *\",\n EVERY_5_SECONDS = \"*/5 * * * * *\",\n EVERY_6_SECONDS = \"*/6 * * * * *\",\n EVERY_7_SECONDS = \"*/7 * * * * *\",\n EVERY_8_SECONDS = \"*/8 * * * * *\",\n EVERY_9_SECONDS = \"*/9 * * * * *\",\n EVERY_10_SECONDS = \"*/10 * * * * *\",\n EVERY_11_SECONDS = \"*/11 * * * * *\",\n EVERY_12_SECONDS = \"*/12 * * * * *\",\n EVERY_13_SECONDS = \"*/13 * * * * *\",\n EVERY_14_SECONDS = \"*/14 * * * * *\",\n EVERY_15_SECONDS = \"*/15 * * * * *\",\n EVERY_16_SECONDS = \"*/16 * * * * *\",\n EVERY_17_SECONDS = \"*/17 * * * * *\",\n EVERY_18_SECONDS = \"*/18 * * * * *\",\n EVERY_19_SECONDS = \"*/19 * * * * *\",\n EVERY_20_SECONDS = \"*/20 * * * * *\",\n EVERY_21_SECONDS = \"*/21 * * * * *\",\n EVERY_22_SECONDS = \"*/22 * * * * *\",\n EVERY_23_SECONDS = \"*/23 * * * * *\",\n EVERY_24_SECONDS = \"*/24 * * * * *\",\n EVERY_25_SECONDS = \"*/25 * * * * *\",\n EVERY_26_SECONDS = \"*/26 * * * * *\",\n EVERY_27_SECONDS = \"*/27 * * * * *\",\n EVERY_28_SECONDS = \"*/28 * * * * *\",\n EVERY_29_SECONDS = \"*/29 * * * * *\",\n EVERY_30_SECONDS = \"*/30 * * * * *\",\n EVERY_31_SECONDS = \"*/31 * * * * *\",\n EVERY_32_SECONDS = \"*/32 * * * * *\",\n EVERY_33_SECONDS = \"*/33 * * * * *\",\n EVERY_34_SECONDS = \"*/34 * * * * *\",\n EVERY_35_SECONDS = \"*/35 * * * * *\",\n EVERY_36_SECONDS = \"*/36 * * * * *\",\n EVERY_37_SECONDS = \"*/37 * * * * *\",\n EVERY_38_SECONDS = \"*/38 * * * * *\",\n EVERY_39_SECONDS = \"*/39 * * * * *\",\n EVERY_40_SECONDS = \"*/40 * * * * *\",\n EVERY_41_SECONDS = \"*/41 * * * * *\",\n EVERY_42_SECONDS = \"*/42 * * * * *\",\n EVERY_43_SECONDS = \"*/43 * * * * *\",\n EVERY_44_SECONDS = \"*/44 * * * * *\",\n EVERY_45_SECONDS = \"*/45 * * * * *\",\n EVERY_46_SECONDS = \"*/46 * * * * *\",\n EVERY_47_SECONDS = \"*/47 * * * * *\",\n EVERY_48_SECONDS = \"*/48 * * * * *\",\n EVERY_49_SECONDS = \"*/49 * * * * *\",\n EVERY_50_SECONDS = \"*/50 * * * * *\",\n EVERY_51_SECONDS = \"*/51 * * * * *\",\n EVERY_52_SECONDS = \"*/52 * * * * *\",\n EVERY_53_SECONDS = \"*/53 * * * * *\",\n EVERY_54_SECONDS = \"*/54 * * * * *\",\n EVERY_55_SECONDS = \"*/55 * * * * *\",\n EVERY_56_SECONDS = \"*/56 * * * * *\",\n EVERY_57_SECONDS = \"*/57 * * * * *\",\n EVERY_58_SECONDS = \"*/58 * * * * *\",\n EVERY_59_SECONDS = \"*/59 * * * * *\",\n EVERY_MINUTE = \"0 * * * * *\",\n}","import { KafkaOptions, MqttOptions, NatsOptions } from \"@nestjs/microservices\";\nimport { InjectionToken, ModuleMetadata, Type } from \"@nestjs/common\";\nimport { CronExpression } from \"./typeorm-outbox.enums\";\n\ntype BrokerConfig = MqttOptions | NatsOptions | KafkaOptions;\n\nexport class TypeormOutboxRegisterCronModuleOptions {\n brokerConfig: BrokerConfig = {};\n deleteItem?: boolean = true;\n typeOrmConnectionName?: string = \"default\";\n cronExpression?: string = CronExpression.EVERY_SECOND;\n}\n\nexport interface TypeormOutboxRegisterCronAsyncOptions extends Pick<\n ModuleMetadata,\n \"imports\"\n> {\n inject?: InjectionToken[];\n useExisting?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useClass?: Type<TypeormOutboxRegisterCronModuleOptions>;\n useFactory?: (\n ...args: any[]\n ) =>\n | Promise<TypeormOutboxRegisterCronModuleOptions>\n | TypeormOutboxRegisterCronModuleOptions;\n}\n\nexport class TypeormOutboxModuleOptions {\n typeOrmConnectionName?: string = \"default\";\n}\n\nexport interface TypeormOutboxModuleAsyncOptions extends Pick<\n ModuleMetadata,\n \"imports\"\n> {\n inject?: InjectionToken[];\n useFactory?: (\n ...args: any[]\n ) => Promise<TypeormOutboxModuleOptions> | TypeormOutboxModuleOptions;\n}\n","import {\n Injectable,\n OnApplicationBootstrap,\n OnApplicationShutdown,\n} from \"@nestjs/common\";\nimport {\n InjectTypeormOutboxBroker,\n InjectTypeormOutboxCronConfig,\n} from \"./typeorm-outbox.di-tokens\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { firstValueFrom } from \"rxjs\";\nimport { ClientProxy, Transport } from \"@nestjs/microservices\";\nimport { CronJob } from \"cron\";\nimport { TypeormOutboxRegisterCronModuleOptions } from \"./typeorm-outbox.interfaces\";\nimport { DataSource } from \"typeorm\";\nimport { CronExpression } from \"./typeorm-outbox.enums\";\n\n@Injectable()\nexport class TypeormOutboxCronService\n implements OnApplicationBootstrap, OnApplicationShutdown\n{\n constructor(\n @InjectTypeormOutboxBroker()\n private readonly brokerClient: ClientProxy,\n @InjectTypeormOutboxCronConfig()\n private readonly moduleConfig: TypeormOutboxRegisterCronModuleOptions,\n private readonly dataSource: DataSource,\n ) {}\n\n private cronJob!: CronJob;\n private isRunning = false;\n\n onApplicationBootstrap() {\n this.validateBrokerClient();\n this.cronJob = new CronJob(\n this.moduleConfig.cronExpression ?? CronExpression.EVERY_SECOND,\n () => {\n if (this.isRunning) return;\n this.isRunning = true;\n this.executeCronJob().finally(() => {\n this.isRunning = false;\n });\n },\n );\n this.cronJob.start();\n }\n\n onApplicationShutdown() {\n if (!this.cronJob) {\n return;\n }\n this.cronJob.stop();\n }\n\n private validateBrokerClient() {\n const brokerConfig = this.moduleConfig.brokerConfig;\n if (\n ![Transport.KAFKA, Transport.NATS, Transport.MQTT].includes(\n brokerConfig?.transport as Transport,\n )\n ) {\n throw new Error(\n `[TypeormOutboxCronService] Broker config must be an instance of KafkaOptions, NatsOptions, or MqttOptions`,\n );\n }\n }\n\n private async executeCronJob() {\n const entities = await this.claimPendingEntities();\n if (!entities.length) return;\n\n for (const entity of entities) {\n await firstValueFrom(\n this.brokerClient.emit(entity.destinationTopic, {\n key: entity.keys,\n value: entity.value,\n headers: entity.headers,\n }),\n );\n\n await this.finalizeEntity(entity.id);\n }\n }\n\n private async claimPendingEntities(): Promise<TypeormOutboxEntity[]> {\n const queryRunner = this.dataSource.createQueryRunner();\n await queryRunner.connect();\n\n try {\n await queryRunner.startTransaction();\n\n const entities = await queryRunner.manager\n .createQueryBuilder(TypeormOutboxEntity, \"e\")\n .where(\"e.status = :status\", { status: \"pending\" })\n .orderBy(\"e.createdAt\", \"ASC\")\n .setLock(\"pessimistic_write\", undefined, [\"SKIP LOCKED\"])\n .getMany();\n\n if (entities.length) {\n await queryRunner.manager.update(\n TypeormOutboxEntity,\n entities.map((e) => e.id),\n { status: \"processing\" },\n );\n }\n\n await queryRunner.commitTransaction();\n return entities;\n } catch (error) {\n await queryRunner.rollbackTransaction();\n throw error;\n } finally {\n await queryRunner.release();\n }\n }\n\n private async finalizeEntity(id: string): Promise<void> {\n if (this.moduleConfig.deleteItem) {\n await this.dataSource.manager.delete(TypeormOutboxEntity, id);\n } else {\n await this.dataSource.manager.update(\n TypeormOutboxEntity,\n { id },\n { status: \"sent\" },\n );\n }\n }\n}","import { Injectable } from \"@nestjs/common\";\nimport { InjectRepository } from \"@nestjs/typeorm\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { Repository } from \"typeorm\";\nimport { randomUUID } from \"crypto\";\n\nexport interface CreateOutboxOptions {\n destinationTopic: string;\n value: any;\n headers?: any;\n keys?: any;\n}\n\n@Injectable()\nexport class TypeormOutboxService {\n constructor(\n @InjectRepository(TypeormOutboxEntity)\n private readonly outboxRepository: Repository<TypeormOutboxEntity>,\n ) {}\n\n async create(options: CreateOutboxOptions): Promise<TypeormOutboxEntity> {\n return this.outboxRepository.save({\n id: randomUUID(),\n destinationTopic: options.destinationTopic,\n headers: options.headers,\n keys: options.keys,\n value: options.value,\n });\n }\n}\n","import { TypeOrmModule } from \"@nestjs/typeorm\";\nimport { DynamicModule, Module, Provider } from \"@nestjs/common\";\nimport {\n TypeormOutboxRegisterCronAsyncOptions,\n TypeormOutboxRegisterCronModuleOptions,\n TypeormOutboxModuleOptions,\n TypeormOutboxModuleAsyncOptions,\n} from \"./typeorm-outbox.interfaces\";\nimport {\n TYPEORM_OUTBOX_BROKER_TOKEN,\n TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n TYPEORM_OUTBOX_SERVICE_TOKEN,\n} from \"./typeorm-outbox.di-tokens\";\nimport { TypeormOutboxEntity } from \"./typeorm-outbox.entity\";\nimport { TypeormOutboxService } from \"./typeorm-outbox.service\";\nimport { ClientProxyFactory } from \"@nestjs/microservices\";\nimport { TypeormOutboxCronService } from \"./typeorm-outbox-cron.service\";\n\nconst serviceProvider = (): Provider => ({\n provide: TYPEORM_OUTBOX_SERVICE_TOKEN,\n useClass: TypeormOutboxService,\n});\n\nconst brokerProvider = (useValue: any = {}): Provider => ({\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useValue,\n});\n\nconst typeOrmFeature = (connectionName = \"default\") =>\n TypeOrmModule.forFeature([TypeormOutboxEntity], connectionName);\n\nconst mergeModuleOptions = <T extends object>(\n defaults: new () => T,\n overrides?: Partial<T>,\n): T => ({ ...new defaults(), ...overrides });\n\nconst moduleConfigProvider = (\n options: TypeormOutboxModuleOptions,\n): Provider => ({\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useValue: mergeModuleOptions(TypeormOutboxModuleOptions, options),\n});\n\nconst asyncModuleConfigProvider = (\n options: TypeormOutboxModuleAsyncOptions,\n): Provider => ({\n provide: TYPEORM_OUTBOX_MODULE_CONFIG_TOKEN,\n useFactory: async (...args: any[]) =>\n mergeModuleOptions(\n TypeormOutboxModuleOptions,\n await options.useFactory?.(...args),\n ),\n inject: options.inject || [],\n});\n\nconst cronConfigProvider = (\n options: TypeormOutboxRegisterCronAsyncOptions,\n): Provider => ({\n provide: TYPEORM_OUTBOX_CRON_CONFIG_TOKEN,\n useFactory: async (...args: any[]) =>\n mergeModuleOptions(\n TypeormOutboxRegisterCronModuleOptions,\n await options.useFactory?.(...args),\n ),\n inject: options.inject || [],\n});\n\nconst cronBrokerProvider = (\n options: TypeormOutboxRegisterCronAsyncOptions,\n): Provider => ({\n provide: TYPEORM_OUTBOX_BROKER_TOKEN,\n useFactory: async (...args: any[]) => {\n const config = mergeModuleOptions(\n TypeormOutboxRegisterCronModuleOptions,\n await options.useFactory?.(...args),\n );\n return ClientProxyFactory.create(config?.brokerConfig ?? {});\n },\n inject: options.inject || [],\n});\n\n@Module({})\nexport class TypeormOutboxModule {\n static forRoot(options: TypeormOutboxModuleOptions = {}): DynamicModule {\n const providers = [\n moduleConfigProvider(options),\n serviceProvider(),\n brokerProvider(),\n ];\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [typeOrmFeature(options.typeOrmConnectionName)],\n providers,\n exports: providers,\n };\n }\n\n static forRootAsync(options: TypeormOutboxModuleAsyncOptions): DynamicModule {\n const providers = [\n asyncModuleConfigProvider(options),\n serviceProvider(),\n brokerProvider(),\n ];\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [typeOrmFeature()],\n providers,\n exports: providers,\n };\n }\n\n static registerCronAsync(\n options: TypeormOutboxRegisterCronAsyncOptions,\n ): DynamicModule {\n const providers = [\n cronConfigProvider(options),\n cronBrokerProvider(options),\n serviceProvider(),\n ];\n return {\n module: TypeormOutboxModule,\n global: true,\n imports: [typeOrmFeature()],\n providers: [TypeormOutboxCronService, ...providers],\n exports: providers,\n };\n }\n}\n"],"mappings":"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"}
|