@amqp-contract/worker-nestjs 0.9.0 → 0.11.0

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/README.md CHANGED
@@ -21,6 +21,7 @@ pnpm add @amqp-contract/worker-nestjs @amqp-contract/worker @amqp-contract/contr
21
21
  ```typescript
22
22
  import { Module } from "@nestjs/common";
23
23
  import { AmqpWorkerModule } from "@amqp-contract/worker-nestjs";
24
+ import { Future, Result } from "@swan-io/boxed";
24
25
  import { contract } from "./contract";
25
26
 
26
27
  @Module({
@@ -28,8 +29,9 @@ import { contract } from "./contract";
28
29
  AmqpWorkerModule.forRoot({
29
30
  contract,
30
31
  handlers: {
31
- processOrder: async (message) => {
32
- console.log("Processing order:", message.orderId);
32
+ processOrder: ({ payload }) => {
33
+ console.log("Processing order:", payload.orderId);
34
+ return Future.value(Result.Ok(undefined));
33
35
  },
34
36
  },
35
37
  urls: ["amqp://localhost"],
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { AmqpConnectionManagerOptions, ConnectionUrl } from "amqp-connection-manager";
2
2
  import { DynamicModule, ModuleMetadata, OnModuleDestroy, OnModuleInit, Type } from "@nestjs/common";
3
- import { WorkerInferConsumerHandlers, WorkerInferSafeConsumerHandlers, defineHandler, defineHandlers } from "@amqp-contract/worker";
3
+ import { WorkerInferSafeConsumerHandlers, WorkerInferSafeConsumerHandlers as WorkerInferSafeConsumerHandlers$1, defineHandler, defineHandlers } from "@amqp-contract/worker";
4
4
  import { ContractDefinition } from "@amqp-contract/contract";
5
5
 
6
6
  //#region src/worker.service.d.ts
@@ -12,39 +12,26 @@ import { ContractDefinition } from "@amqp-contract/contract";
12
12
  *
13
13
  * @example
14
14
  * ```typescript
15
- * import { defineHandlers, defineUnsafeHandlers } from '@amqp-contract/worker';
16
- * import { Future, Result } from '@swan-io/boxed';
17
- * import { RetryableError } from '@amqp-contract/worker';
15
+ * import { defineHandlers, RetryableError } from '@amqp-contract/worker';
16
+ * import { Future } from '@swan-io/boxed';
18
17
  *
19
- * // Using safe handlers (recommended)
20
18
  * const options: AmqpWorkerModuleOptions<typeof contract> = {
21
19
  * contract: myContract,
22
20
  * handlers: defineHandlers(myContract, {
23
- * processOrder: (message) =>
24
- * Future.fromPromise(processPayment(message))
21
+ * processOrder: ({ payload }) =>
22
+ * Future.fromPromise(processPayment(payload))
25
23
  * .mapOk(() => undefined)
26
24
  * .mapError((error) => new RetryableError('Payment failed', error))
27
25
  * }),
28
26
  * urls: ['amqp://localhost'],
29
27
  * };
30
- *
31
- * // Using unsafe handlers (legacy)
32
- * const options: AmqpWorkerModuleOptions<typeof contract> = {
33
- * contract: myContract,
34
- * handlers: defineUnsafeHandlers(myContract, {
35
- * processOrder: async (message) => {
36
- * console.log('Processing order:', message.orderId);
37
- * }
38
- * }),
39
- * urls: ['amqp://localhost'],
40
- * };
41
28
  * ```
42
29
  */
43
30
  type AmqpWorkerModuleOptions<TContract extends ContractDefinition> = {
44
31
  /** The AMQP contract definition specifying consumers and their message schemas */
45
32
  contract: TContract;
46
- /** Message handlers for each consumer defined in the contract. Use defineHandlers or defineUnsafeHandlers to create type-safe handlers. */
47
- handlers: WorkerInferSafeConsumerHandlers<TContract>;
33
+ /** Message handlers for each consumer defined in the contract. Use defineHandlers to create type-safe handlers. */
34
+ handlers: WorkerInferSafeConsumerHandlers$1<TContract>;
48
35
  /** AMQP broker URL(s). Multiple URLs provide failover support */
49
36
  urls: ConnectionUrl[];
50
37
  /** Optional connection configuration (heartbeat, reconnect settings, etc.) */
@@ -204,5 +191,5 @@ declare class AmqpWorkerModule {
204
191
  */
205
192
  declare const MODULE_OPTIONS_TOKEN: unique symbol;
206
193
  //#endregion
207
- export { AmqpWorkerModule, type AmqpWorkerModuleAsyncOptions, type AmqpWorkerModuleOptions, AmqpWorkerService, MODULE_OPTIONS_TOKEN, type WorkerInferConsumerHandlers, defineHandler, defineHandlers };
194
+ export { AmqpWorkerModule, type AmqpWorkerModuleAsyncOptions, type AmqpWorkerModuleOptions, AmqpWorkerService, MODULE_OPTIONS_TOKEN, type WorkerInferSafeConsumerHandlers, defineHandler, defineHandlers };
208
195
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/worker.service.ts","../src/worker.module.ts","../src/worker.module-definition.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAyCA;;;;;;;;AA6CA;;;;;;;;;;;;AC9EkE;;;;;;;;AAalE;;;;;AAeY,KDKA,uBCLA,CAAA,kBDK0C,kBCL1C,CAAA,GAAA;EAAc;EAmDb,QAAA,ED5CD,SC4CiB;EAOM;EACE,QAAA,EDlDzB,+BCkDyB,CDlDO,SCkDP,CAAA;EAAxB;EACR,IAAA,EDjDG,aCiDH,EAAA;EAoBmC;EACE,iBAAA,CAAA,EDpEpB,4BCoEoB,GAAA,SAAA;CAA7B;;;;;;ACjHb;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cFmFa,oCAAoC,+BACpC,cAAc;;;uBAMG,wBAAwB;;;;;;;;;;;kBAa9B;;;;;;;;qBAWG;;;;;;;AA7E3B,KC3BK,8BD2B8B,CAAA,kBC3BmB,kBD2BnB,CAAA,GC1B/B,uBD0B+B,CC1BP,SD0BO,CAAA,GCzB/B,ODyB+B,CCzBvB,uBDyBuB,CCzBC,SDyBD,CAAA,CAAA;;;;AAIvB,KCxBA,4BDwBA,CAAA,kBCxB+C,kBDwB/C,CAAA,GAAA;EAEJ;;;AAuCR;EACiD,UAAA,EAAA,CAAA,GAAA,IAAA,EAAA,GAAA,EAAA,EAAA,GC5Df,8BD4De,CC5DgB,SD4DhB,CAAA;EAOK;;;;EANzC,MAAA,CAAA,EAAA,CAAA,MAAA,GAAA,MAAA,GCxDiB,IDwDjB,CAAA,OAAA,CAAA,CAAA,EAAA;EAAc;;;YCpDf;;AA5BsD;;;;;;;;AAalE;;;;;;;AAiEA;;;;;;;;;;;;;AClFA;;;;;;;;;;;;;;;;;;;cDmFa,gBAAA;;;;;;;mCAOsB,6BACtB,wBAAwB,aAChC;;;;;;;wCAoBmC,6BAC3B,6BAA6B,aACrC;;;;;;;;cClHQ"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/worker.service.ts","../src/worker.module.ts","../src/worker.module-definition.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AA4BA;;;;;;;;AA6CA;;;;;;;;;;;;AC3DK,KDcO,uBCdP,CAAA,kBDciD,kBCdnB,CAAA,GAAA;EAAmB;EAC1B,QAAA,EDehB,SCfgB;EAAxB;EACgC,QAAA,EDgBxB,iCChBwB,CDgBQ,SChBR,CAAA;EAAxB;EAAR,IAAA,EDkBI,aClBJ,EAAA;EAAO;EAKC,iBAAA,CAAA,EDeU,4BCfkB,GAAA,SAAA;CAAmB;;;;;;AAiE3D;;;;;;;;;;;;;AClFA;;;;;;;;;;;;;;;;cFsEa,oCAAoC,+BACpC,cAAc;;;uBAMG,wBAAwB;;;;;;;;;;;kBAa9B;;;;;;;;qBAWG;;;;;;;AA7E3B,KCdK,8BDc8B,CAAA,kBCdmB,kBDcnB,CAAA,GCb/B,uBDa+B,CCbP,SDaO,CAAA,GCZ/B,ODY+B,CCZvB,uBDYuB,CCZC,SDYD,CAAA,CAAA;;;;AAIvB,KCXA,4BDWA,CAAA,kBCX+C,kBDW/C,CAAA,GAAA;EAEJ;;;AAuCR;EACiD,UAAA,EAAA,CAAA,GAAA,IAAA,EAAA,GAAA,EAAA,EAAA,GC/Cf,8BD+Ce,CC/CgB,SD+ChB,CAAA;EAOK;;;;EANzC,MAAA,CAAA,EAAA,CAAA,MAAA,GAAA,MAAA,GC3CiB,ID2CjB,CAAA,OAAA,CAAA,CAAA,EAAA;EAAc;;;YCvCf;;AA5BsD;;;;;;;;AAalE;;;;;;;AAiEA;;;;;;;;;;;;;AClFA;;;;;;;;;;;;;;;;;;;cDmFa,gBAAA;;;;;;;mCAOsB,6BACtB,wBAAwB,aAChC;;;;;;;wCAoBmC,6BAC3B,6BAA6B,aACrC;;;;;;;;cClHQ"}
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { DynamicModule, ModuleMetadata, OnModuleDestroy, OnModuleInit, Type } from "@nestjs/common";
2
- import { WorkerInferConsumerHandlers, WorkerInferSafeConsumerHandlers, defineHandler, defineHandlers } from "@amqp-contract/worker";
2
+ import { WorkerInferSafeConsumerHandlers, WorkerInferSafeConsumerHandlers as WorkerInferSafeConsumerHandlers$1, defineHandler, defineHandlers } from "@amqp-contract/worker";
3
3
  import { AmqpConnectionManagerOptions, ConnectionUrl } from "amqp-connection-manager";
4
4
  import { ContractDefinition } from "@amqp-contract/contract";
5
5
 
@@ -12,39 +12,26 @@ import { ContractDefinition } from "@amqp-contract/contract";
12
12
  *
13
13
  * @example
14
14
  * ```typescript
15
- * import { defineHandlers, defineUnsafeHandlers } from '@amqp-contract/worker';
16
- * import { Future, Result } from '@swan-io/boxed';
17
- * import { RetryableError } from '@amqp-contract/worker';
15
+ * import { defineHandlers, RetryableError } from '@amqp-contract/worker';
16
+ * import { Future } from '@swan-io/boxed';
18
17
  *
19
- * // Using safe handlers (recommended)
20
18
  * const options: AmqpWorkerModuleOptions<typeof contract> = {
21
19
  * contract: myContract,
22
20
  * handlers: defineHandlers(myContract, {
23
- * processOrder: (message) =>
24
- * Future.fromPromise(processPayment(message))
21
+ * processOrder: ({ payload }) =>
22
+ * Future.fromPromise(processPayment(payload))
25
23
  * .mapOk(() => undefined)
26
24
  * .mapError((error) => new RetryableError('Payment failed', error))
27
25
  * }),
28
26
  * urls: ['amqp://localhost'],
29
27
  * };
30
- *
31
- * // Using unsafe handlers (legacy)
32
- * const options: AmqpWorkerModuleOptions<typeof contract> = {
33
- * contract: myContract,
34
- * handlers: defineUnsafeHandlers(myContract, {
35
- * processOrder: async (message) => {
36
- * console.log('Processing order:', message.orderId);
37
- * }
38
- * }),
39
- * urls: ['amqp://localhost'],
40
- * };
41
28
  * ```
42
29
  */
43
30
  type AmqpWorkerModuleOptions<TContract extends ContractDefinition> = {
44
31
  /** The AMQP contract definition specifying consumers and their message schemas */
45
32
  contract: TContract;
46
- /** Message handlers for each consumer defined in the contract. Use defineHandlers or defineUnsafeHandlers to create type-safe handlers. */
47
- handlers: WorkerInferSafeConsumerHandlers<TContract>;
33
+ /** Message handlers for each consumer defined in the contract. Use defineHandlers to create type-safe handlers. */
34
+ handlers: WorkerInferSafeConsumerHandlers$1<TContract>;
48
35
  /** AMQP broker URL(s). Multiple URLs provide failover support */
49
36
  urls: ConnectionUrl[];
50
37
  /** Optional connection configuration (heartbeat, reconnect settings, etc.) */
@@ -204,5 +191,5 @@ declare class AmqpWorkerModule {
204
191
  */
205
192
  declare const MODULE_OPTIONS_TOKEN: unique symbol;
206
193
  //#endregion
207
- export { AmqpWorkerModule, type AmqpWorkerModuleAsyncOptions, type AmqpWorkerModuleOptions, AmqpWorkerService, MODULE_OPTIONS_TOKEN, type WorkerInferConsumerHandlers, defineHandler, defineHandlers };
194
+ export { AmqpWorkerModule, type AmqpWorkerModuleAsyncOptions, type AmqpWorkerModuleOptions, AmqpWorkerService, MODULE_OPTIONS_TOKEN, type WorkerInferSafeConsumerHandlers, defineHandler, defineHandlers };
208
195
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/worker.service.ts","../src/worker.module.ts","../src/worker.module-definition.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAyCA;;;;;;;;AA6CA;;;;;;;;;;;;AC9EkE;;;;;;;;AAalE;;;;;AAeY,KDKA,uBCLA,CAAA,kBDK0C,kBCL1C,CAAA,GAAA;EAAc;EAmDb,QAAA,ED5CD,SC4CiB;EAOM;EACE,QAAA,EDlDzB,+BCkDyB,CDlDO,SCkDP,CAAA;EAAxB;EACR,IAAA,EDjDG,aCiDH,EAAA;EAoBmC;EACE,iBAAA,CAAA,EDpEpB,4BCoEoB,GAAA,SAAA;CAA7B;;;;;;ACjHb;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cFmFa,oCAAoC,+BACpC,cAAc;;;uBAMG,wBAAwB;;;;;;;;;;;kBAa9B;;;;;;;;qBAWG;;;;;;;AA7E3B,KC3BK,8BD2B8B,CAAA,kBC3BmB,kBD2BnB,CAAA,GC1B/B,uBD0B+B,CC1BP,SD0BO,CAAA,GCzB/B,ODyB+B,CCzBvB,uBDyBuB,CCzBC,SDyBD,CAAA,CAAA;;;;AAIvB,KCxBA,4BDwBA,CAAA,kBCxB+C,kBDwB/C,CAAA,GAAA;EAEJ;;;AAuCR;EACiD,UAAA,EAAA,CAAA,GAAA,IAAA,EAAA,GAAA,EAAA,EAAA,GC5Df,8BD4De,CC5DgB,SD4DhB,CAAA;EAOK;;;;EANzC,MAAA,CAAA,EAAA,CAAA,MAAA,GAAA,MAAA,GCxDiB,IDwDjB,CAAA,OAAA,CAAA,CAAA,EAAA;EAAc;;;YCpDf;;AA5BsD;;;;;;;;AAalE;;;;;;;AAiEA;;;;;;;;;;;;;AClFA;;;;;;;;;;;;;;;;;;;cDmFa,gBAAA;;;;;;;mCAOsB,6BACtB,wBAAwB,aAChC;;;;;;;wCAoBmC,6BAC3B,6BAA6B,aACrC;;;;;;;;cClHQ"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/worker.service.ts","../src/worker.module.ts","../src/worker.module-definition.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AA4BA;;;;;;;;AA6CA;;;;;;;;;;;;AC3DK,KDcO,uBCdP,CAAA,kBDciD,kBCdnB,CAAA,GAAA;EAAmB;EAC1B,QAAA,EDehB,SCfgB;EAAxB;EACgC,QAAA,EDgBxB,iCChBwB,CDgBQ,SChBR,CAAA;EAAxB;EAAR,IAAA,EDkBI,aClBJ,EAAA;EAAO;EAKC,iBAAA,CAAA,EDeU,4BCfkB,GAAA,SAAA;CAAmB;;;;;;AAiE3D;;;;;;;;;;;;;AClFA;;;;;;;;;;;;;;;;cFsEa,oCAAoC,+BACpC,cAAc;;;uBAMG,wBAAwB;;;;;;;;;;;kBAa9B;;;;;;;;qBAWG;;;;;;;AA7E3B,KCdK,8BDc8B,CAAA,kBCdmB,kBDcnB,CAAA,GCb/B,uBDa+B,CCbP,SDaO,CAAA,GCZ/B,ODY+B,CCZvB,uBDYuB,CCZC,SDYD,CAAA,CAAA;;;;AAIvB,KCXA,4BDWA,CAAA,kBCX+C,kBDW/C,CAAA,GAAA;EAEJ;;;AAuCR;EACiD,UAAA,EAAA,CAAA,GAAA,IAAA,EAAA,GAAA,EAAA,EAAA,GC/Cf,8BD+Ce,CC/CgB,SD+ChB,CAAA;EAOK;;;;EANzC,MAAA,CAAA,EAAA,CAAA,MAAA,GAAA,MAAA,GC3CiB,ID2CjB,CAAA,OAAA,CAAA,CAAA,EAAA;EAAc;;;YCvCf;;AA5BsD;;;;;;;;AAalE;;;;;;;AAiEA;;;;;;;;;;;;;AClFA;;;;;;;;;;;;;;;;;;;cDmFa,gBAAA;;;;;;;mCAOsB,6BACtB,wBAAwB,aAChC;;;;;;;wCAoBmC,6BAC3B,6BAA6B,aACrC;;;;;;;;cClHQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["AmqpWorkerService","AmqpWorkerModule"],"sources":["../src/worker.module-definition.ts","../src/worker.service.ts","../src/worker.module.ts"],"sourcesContent":["/**\n * Injection token for AMQP worker module options\n * Used by NestJS DI system to inject configuration into AmqpWorkerService\n */\nexport const MODULE_OPTIONS_TOKEN = Symbol(\"AMQP_WORKER_MODULE_OPTIONS\");\n","import type { AmqpConnectionManagerOptions, ConnectionUrl } from \"amqp-connection-manager\";\nimport { Inject, Injectable, type OnModuleDestroy, type OnModuleInit } from \"@nestjs/common\";\nimport { TypedAmqpWorker, type WorkerInferSafeConsumerHandlers } from \"@amqp-contract/worker\";\nimport type { ContractDefinition } from \"@amqp-contract/contract\";\nimport { MODULE_OPTIONS_TOKEN } from \"./worker.module-definition.js\";\n\n/**\n * Configuration options for the AMQP worker NestJS module.\n *\n * @typeParam TContract - The contract definition type\n *\n * @example\n * ```typescript\n * import { defineHandlers, defineUnsafeHandlers } from '@amqp-contract/worker';\n * import { Future, Result } from '@swan-io/boxed';\n * import { RetryableError } from '@amqp-contract/worker';\n *\n * // Using safe handlers (recommended)\n * const options: AmqpWorkerModuleOptions<typeof contract> = {\n * contract: myContract,\n * handlers: defineHandlers(myContract, {\n * processOrder: (message) =>\n * Future.fromPromise(processPayment(message))\n * .mapOk(() => undefined)\n * .mapError((error) => new RetryableError('Payment failed', error))\n * }),\n * urls: ['amqp://localhost'],\n * };\n *\n * // Using unsafe handlers (legacy)\n * const options: AmqpWorkerModuleOptions<typeof contract> = {\n * contract: myContract,\n * handlers: defineUnsafeHandlers(myContract, {\n * processOrder: async (message) => {\n * console.log('Processing order:', message.orderId);\n * }\n * }),\n * urls: ['amqp://localhost'],\n * };\n * ```\n */\nexport type AmqpWorkerModuleOptions<TContract extends ContractDefinition> = {\n /** The AMQP contract definition specifying consumers and their message schemas */\n contract: TContract;\n /** Message handlers for each consumer defined in the contract. Use defineHandlers or defineUnsafeHandlers to create type-safe handlers. */\n handlers: WorkerInferSafeConsumerHandlers<TContract>;\n /** AMQP broker URL(s). Multiple URLs provide failover support */\n urls: ConnectionUrl[];\n /** Optional connection configuration (heartbeat, reconnect settings, etc.) */\n connectionOptions?: AmqpConnectionManagerOptions | undefined;\n};\n\n/**\n * Type-safe AMQP worker service for NestJS applications.\n *\n * This service wraps {@link TypedAmqpWorker} and integrates it with the NestJS\n * lifecycle, automatically starting message consumption on module init and\n * cleaning up resources on module destroy.\n *\n * @typeParam TContract - The contract definition type\n *\n * @example\n * ```typescript\n * // In your module\n * import { AmqpWorkerModule } from '@amqp-contract/worker-nestjs';\n *\n * @Module({\n * imports: [\n * AmqpWorkerModule.forRoot({\n * contract: myContract,\n * handlers: {\n * processOrder: async (message) => {\n * console.log('Received order:', message.orderId);\n * // Process the order...\n * }\n * },\n * urls: ['amqp://localhost']\n * })\n * ]\n * })\n * export class AppModule {}\n *\n * // The worker automatically starts consuming messages when the module initializes\n * // and stops gracefully when the application shuts down\n * ```\n */\n@Injectable()\nexport class AmqpWorkerService<TContract extends ContractDefinition>\n implements OnModuleInit, OnModuleDestroy\n{\n private worker: TypedAmqpWorker<TContract> | null = null;\n\n constructor(\n @Inject(MODULE_OPTIONS_TOKEN)\n private readonly options: AmqpWorkerModuleOptions<TContract>,\n ) {}\n\n /**\n * Initialize the AMQP worker when the NestJS module starts.\n *\n * This lifecycle hook automatically creates and starts the worker,\n * beginning message consumption from all configured consumers.\n * The connection will be established in the background with\n * automatic reconnection handling.\n *\n * @throws Error if the worker fails to start\n */\n async onModuleInit(): Promise<void> {\n this.worker = await TypedAmqpWorker.create(this.options).resultToPromise();\n }\n\n /**\n * Close the AMQP worker when the NestJS module is destroyed.\n *\n * This lifecycle hook ensures proper cleanup of resources when the\n * NestJS application shuts down, gracefully stopping message consumption\n * and closing the connection.\n */\n async onModuleDestroy(): Promise<void> {\n if (this.worker) {\n await this.worker.close().resultToPromise();\n this.worker = null;\n }\n }\n}\n","import { type AmqpWorkerModuleOptions, AmqpWorkerService } from \"./worker.service.js\";\nimport {\n type DynamicModule,\n Module,\n type ModuleMetadata,\n type Provider,\n type Type,\n} from \"@nestjs/common\";\nimport type { ContractDefinition } from \"@amqp-contract/contract\";\nimport { MODULE_OPTIONS_TOKEN } from \"./worker.module-definition.js\";\n\n/**\n * Factory function return type for async module configuration\n */\ntype AmqpWorkerModuleOptionsFactory<TContract extends ContractDefinition> =\n | AmqpWorkerModuleOptions<TContract>\n | Promise<AmqpWorkerModuleOptions<TContract>>;\n\n/**\n * Options for async module configuration using factory pattern\n */\nexport type AmqpWorkerModuleAsyncOptions<TContract extends ContractDefinition> = {\n /**\n * Factory function that returns the module options.\n * Can use injected dependencies to create configuration.\n */\n // oxlint-disable-next-line no-explicit-any\n useFactory: (...args: any[]) => AmqpWorkerModuleOptionsFactory<TContract>;\n /**\n * Optional dependencies to inject into the factory function.\n * Can be a token (string/symbol) a class or a reference to a provider.\n */\n inject?: (string | symbol | Type<unknown>)[];\n /**\n * Optional list of imported modules that export providers needed by the factory\n */\n imports?: ModuleMetadata[\"imports\"];\n};\n\n/**\n * NestJS module for AMQP worker integration\n * This module provides type-safe AMQP worker functionality using @amqp-contract/worker\n * without relying on NestJS decorators (except for dependency injection)\n *\n * @typeParam TContract - The contract definition type for type-safe handlers\n *\n * @example\n * ```typescript\n * // Synchronous configuration\n * @Module({\n * imports: [\n * AmqpWorkerModule.forRoot({\n * contract: myContract,\n * handlers: {\n * processOrder: async (message) => {\n * // message is fully typed based on the contract\n * console.log('Order:', message.orderId);\n * }\n * },\n * urls: ['amqp://localhost']\n * })\n * ]\n * })\n * export class AppModule {}\n *\n * // Asynchronous configuration\n * @Module({\n * imports: [\n * AmqpWorkerModule.forRootAsync({\n * imports: [ConfigModule],\n * useFactory: (configService: ConfigService) => ({\n * contract: myContract,\n * handlers: {\n * processOrder: async (message) => {\n * console.log('Order:', message.orderId);\n * }\n * },\n * urls: configService.get('AMQP_URLS')\n * }),\n * inject: [ConfigService]\n * })\n * ]\n * })\n * export class AppModule {}\n * ```\n */\n@Module({})\nexport class AmqpWorkerModule {\n /**\n * Register the AMQP worker module with synchronous configuration\n *\n * @param options - The worker configuration options with contract and handlers\n * @returns A dynamic module for NestJS\n */\n static forRoot<TContract extends ContractDefinition>(\n options: AmqpWorkerModuleOptions<TContract>,\n ): DynamicModule {\n return {\n module: AmqpWorkerModule,\n providers: [\n {\n provide: MODULE_OPTIONS_TOKEN,\n useValue: options,\n },\n AmqpWorkerService,\n ],\n exports: [AmqpWorkerService],\n };\n }\n\n /**\n * Register the AMQP worker module with asynchronous configuration\n *\n * @param options - Async configuration options with factory function\n * @returns A dynamic module for NestJS\n */\n static forRootAsync<TContract extends ContractDefinition>(\n options: AmqpWorkerModuleAsyncOptions<TContract>,\n ): DynamicModule {\n const providers: Provider[] = [\n {\n provide: MODULE_OPTIONS_TOKEN,\n useFactory: options.useFactory,\n inject: options.inject ?? [],\n },\n AmqpWorkerService,\n ];\n\n return {\n module: AmqpWorkerModule,\n imports: options.imports ?? [],\n providers,\n exports: [AmqpWorkerService],\n };\n }\n}\n"],"mappings":";;;;;;;;AAIA,MAAa,uBAAuB,OAAO,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;ACmFjE,8BAAMA,oBAEb;CACE,AAAQ,SAA4C;CAEpD,YACE,AACiB,SACjB;EADiB;;;;;;;;;;;;CAanB,MAAM,eAA8B;AAClC,OAAK,SAAS,MAAM,gBAAgB,OAAO,KAAK,QAAQ,CAAC,iBAAiB;;;;;;;;;CAU5E,MAAM,kBAAiC;AACrC,MAAI,KAAK,QAAQ;AACf,SAAM,KAAK,OAAO,OAAO,CAAC,iBAAiB;AAC3C,QAAK,SAAS;;;;;CAnCnB,YAAY;oBAOR,OAAO,qBAAqB;;;;;;;ACN1B,iDAAMC,mBAAiB;;;;;;;CAO5B,OAAO,QACL,SACe;AACf,SAAO;GACL;GACA,WAAW,CACT;IACE,SAAS;IACT,UAAU;IACX,EACD,kBACD;GACD,SAAS,CAAC,kBAAkB;GAC7B;;;;;;;;CASH,OAAO,aACL,SACe;EACf,MAAM,YAAwB,CAC5B;GACE,SAAS;GACT,YAAY,QAAQ;GACpB,QAAQ,QAAQ,UAAU,EAAE;GAC7B,EACD,kBACD;AAED,SAAO;GACL;GACA,SAAS,QAAQ,WAAW,EAAE;GAC9B;GACA,SAAS,CAAC,kBAAkB;GAC7B;;;mDA/CJ,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"index.mjs","names":["AmqpWorkerService","AmqpWorkerModule"],"sources":["../src/worker.module-definition.ts","../src/worker.service.ts","../src/worker.module.ts"],"sourcesContent":["/**\n * Injection token for AMQP worker module options\n * Used by NestJS DI system to inject configuration into AmqpWorkerService\n */\nexport const MODULE_OPTIONS_TOKEN = Symbol(\"AMQP_WORKER_MODULE_OPTIONS\");\n","import type { AmqpConnectionManagerOptions, ConnectionUrl } from \"amqp-connection-manager\";\nimport { Inject, Injectable, type OnModuleDestroy, type OnModuleInit } from \"@nestjs/common\";\nimport { TypedAmqpWorker, type WorkerInferSafeConsumerHandlers } from \"@amqp-contract/worker\";\nimport type { ContractDefinition } from \"@amqp-contract/contract\";\nimport { MODULE_OPTIONS_TOKEN } from \"./worker.module-definition.js\";\n\n/**\n * Configuration options for the AMQP worker NestJS module.\n *\n * @typeParam TContract - The contract definition type\n *\n * @example\n * ```typescript\n * import { defineHandlers, RetryableError } from '@amqp-contract/worker';\n * import { Future } from '@swan-io/boxed';\n *\n * const options: AmqpWorkerModuleOptions<typeof contract> = {\n * contract: myContract,\n * handlers: defineHandlers(myContract, {\n * processOrder: ({ payload }) =>\n * Future.fromPromise(processPayment(payload))\n * .mapOk(() => undefined)\n * .mapError((error) => new RetryableError('Payment failed', error))\n * }),\n * urls: ['amqp://localhost'],\n * };\n * ```\n */\nexport type AmqpWorkerModuleOptions<TContract extends ContractDefinition> = {\n /** The AMQP contract definition specifying consumers and their message schemas */\n contract: TContract;\n /** Message handlers for each consumer defined in the contract. Use defineHandlers to create type-safe handlers. */\n handlers: WorkerInferSafeConsumerHandlers<TContract>;\n /** AMQP broker URL(s). Multiple URLs provide failover support */\n urls: ConnectionUrl[];\n /** Optional connection configuration (heartbeat, reconnect settings, etc.) */\n connectionOptions?: AmqpConnectionManagerOptions | undefined;\n};\n\n/**\n * Type-safe AMQP worker service for NestJS applications.\n *\n * This service wraps {@link TypedAmqpWorker} and integrates it with the NestJS\n * lifecycle, automatically starting message consumption on module init and\n * cleaning up resources on module destroy.\n *\n * @typeParam TContract - The contract definition type\n *\n * @example\n * ```typescript\n * // In your module\n * import { AmqpWorkerModule } from '@amqp-contract/worker-nestjs';\n *\n * @Module({\n * imports: [\n * AmqpWorkerModule.forRoot({\n * contract: myContract,\n * handlers: {\n * processOrder: async (message) => {\n * console.log('Received order:', message.orderId);\n * // Process the order...\n * }\n * },\n * urls: ['amqp://localhost']\n * })\n * ]\n * })\n * export class AppModule {}\n *\n * // The worker automatically starts consuming messages when the module initializes\n * // and stops gracefully when the application shuts down\n * ```\n */\n@Injectable()\nexport class AmqpWorkerService<TContract extends ContractDefinition>\n implements OnModuleInit, OnModuleDestroy\n{\n private worker: TypedAmqpWorker<TContract> | null = null;\n\n constructor(\n @Inject(MODULE_OPTIONS_TOKEN)\n private readonly options: AmqpWorkerModuleOptions<TContract>,\n ) {}\n\n /**\n * Initialize the AMQP worker when the NestJS module starts.\n *\n * This lifecycle hook automatically creates and starts the worker,\n * beginning message consumption from all configured consumers.\n * The connection will be established in the background with\n * automatic reconnection handling.\n *\n * @throws Error if the worker fails to start\n */\n async onModuleInit(): Promise<void> {\n this.worker = await TypedAmqpWorker.create(this.options).resultToPromise();\n }\n\n /**\n * Close the AMQP worker when the NestJS module is destroyed.\n *\n * This lifecycle hook ensures proper cleanup of resources when the\n * NestJS application shuts down, gracefully stopping message consumption\n * and closing the connection.\n */\n async onModuleDestroy(): Promise<void> {\n if (this.worker) {\n await this.worker.close().resultToPromise();\n this.worker = null;\n }\n }\n}\n","import { type AmqpWorkerModuleOptions, AmqpWorkerService } from \"./worker.service.js\";\nimport {\n type DynamicModule,\n Module,\n type ModuleMetadata,\n type Provider,\n type Type,\n} from \"@nestjs/common\";\nimport type { ContractDefinition } from \"@amqp-contract/contract\";\nimport { MODULE_OPTIONS_TOKEN } from \"./worker.module-definition.js\";\n\n/**\n * Factory function return type for async module configuration\n */\ntype AmqpWorkerModuleOptionsFactory<TContract extends ContractDefinition> =\n | AmqpWorkerModuleOptions<TContract>\n | Promise<AmqpWorkerModuleOptions<TContract>>;\n\n/**\n * Options for async module configuration using factory pattern\n */\nexport type AmqpWorkerModuleAsyncOptions<TContract extends ContractDefinition> = {\n /**\n * Factory function that returns the module options.\n * Can use injected dependencies to create configuration.\n */\n // oxlint-disable-next-line no-explicit-any\n useFactory: (...args: any[]) => AmqpWorkerModuleOptionsFactory<TContract>;\n /**\n * Optional dependencies to inject into the factory function.\n * Can be a token (string/symbol) a class or a reference to a provider.\n */\n inject?: (string | symbol | Type<unknown>)[];\n /**\n * Optional list of imported modules that export providers needed by the factory\n */\n imports?: ModuleMetadata[\"imports\"];\n};\n\n/**\n * NestJS module for AMQP worker integration\n * This module provides type-safe AMQP worker functionality using @amqp-contract/worker\n * without relying on NestJS decorators (except for dependency injection)\n *\n * @typeParam TContract - The contract definition type for type-safe handlers\n *\n * @example\n * ```typescript\n * // Synchronous configuration\n * @Module({\n * imports: [\n * AmqpWorkerModule.forRoot({\n * contract: myContract,\n * handlers: {\n * processOrder: async (message) => {\n * // message is fully typed based on the contract\n * console.log('Order:', message.orderId);\n * }\n * },\n * urls: ['amqp://localhost']\n * })\n * ]\n * })\n * export class AppModule {}\n *\n * // Asynchronous configuration\n * @Module({\n * imports: [\n * AmqpWorkerModule.forRootAsync({\n * imports: [ConfigModule],\n * useFactory: (configService: ConfigService) => ({\n * contract: myContract,\n * handlers: {\n * processOrder: async (message) => {\n * console.log('Order:', message.orderId);\n * }\n * },\n * urls: configService.get('AMQP_URLS')\n * }),\n * inject: [ConfigService]\n * })\n * ]\n * })\n * export class AppModule {}\n * ```\n */\n@Module({})\nexport class AmqpWorkerModule {\n /**\n * Register the AMQP worker module with synchronous configuration\n *\n * @param options - The worker configuration options with contract and handlers\n * @returns A dynamic module for NestJS\n */\n static forRoot<TContract extends ContractDefinition>(\n options: AmqpWorkerModuleOptions<TContract>,\n ): DynamicModule {\n return {\n module: AmqpWorkerModule,\n providers: [\n {\n provide: MODULE_OPTIONS_TOKEN,\n useValue: options,\n },\n AmqpWorkerService,\n ],\n exports: [AmqpWorkerService],\n };\n }\n\n /**\n * Register the AMQP worker module with asynchronous configuration\n *\n * @param options - Async configuration options with factory function\n * @returns A dynamic module for NestJS\n */\n static forRootAsync<TContract extends ContractDefinition>(\n options: AmqpWorkerModuleAsyncOptions<TContract>,\n ): DynamicModule {\n const providers: Provider[] = [\n {\n provide: MODULE_OPTIONS_TOKEN,\n useFactory: options.useFactory,\n inject: options.inject ?? [],\n },\n AmqpWorkerService,\n ];\n\n return {\n module: AmqpWorkerModule,\n imports: options.imports ?? [],\n providers,\n exports: [AmqpWorkerService],\n };\n }\n}\n"],"mappings":";;;;;;;;AAIA,MAAa,uBAAuB,OAAO,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;ACsEjE,8BAAMA,oBAEb;CACE,AAAQ,SAA4C;CAEpD,YACE,AACiB,SACjB;EADiB;;;;;;;;;;;;CAanB,MAAM,eAA8B;AAClC,OAAK,SAAS,MAAM,gBAAgB,OAAO,KAAK,QAAQ,CAAC,iBAAiB;;;;;;;;;CAU5E,MAAM,kBAAiC;AACrC,MAAI,KAAK,QAAQ;AACf,SAAM,KAAK,OAAO,OAAO,CAAC,iBAAiB;AAC3C,QAAK,SAAS;;;;;CAnCnB,YAAY;oBAOR,OAAO,qBAAqB;;;;;;;ACO1B,iDAAMC,mBAAiB;;;;;;;CAO5B,OAAO,QACL,SACe;AACf,SAAO;GACL;GACA,WAAW,CACT;IACE,SAAS;IACT,UAAU;IACX,EACD,kBACD;GACD,SAAS,CAAC,kBAAkB;GAC7B;;;;;;;;CASH,OAAO,aACL,SACe;EACf,MAAM,YAAwB,CAC5B;GACE,SAAS;GACT,YAAY,QAAQ;GACpB,QAAQ,QAAQ,UAAU,EAAE;GAC7B,EACD,kBACD;AAED,SAAO;GACL;GACA,SAAS,QAAQ,WAAW,EAAE;GAC9B;GACA,SAAS,CAAC,kBAAkB;GAC7B;;;mDA/CJ,OAAO,EAAE,CAAC"}
package/docs/index.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  ### AmqpWorkerModule
10
10
 
11
- Defined in: [worker-nestjs/src/worker.module.ts:88](https://github.com/btravers/amqp-contract/blob/f058a24938d9644a82812e57d7995cb683cfd6b5/packages/worker-nestjs/src/worker.module.ts#L88)
11
+ Defined in: [worker-nestjs/src/worker.module.ts:88](https://github.com/btravers/amqp-contract/blob/ed05e43c04fa526b751d45622ccc1ac53b2e96f9/packages/worker-nestjs/src/worker.module.ts#L88)
12
12
 
13
13
  NestJS module for AMQP worker integration
14
14
  This module provides type-safe AMQP worker functionality using @amqp-contract/worker
@@ -79,7 +79,7 @@ new AmqpWorkerModule(): AmqpWorkerModule;
79
79
  static forRoot<TContract>(options): DynamicModule;
80
80
  ```
81
81
 
82
- Defined in: [worker-nestjs/src/worker.module.ts:95](https://github.com/btravers/amqp-contract/blob/f058a24938d9644a82812e57d7995cb683cfd6b5/packages/worker-nestjs/src/worker.module.ts#L95)
82
+ Defined in: [worker-nestjs/src/worker.module.ts:95](https://github.com/btravers/amqp-contract/blob/ed05e43c04fa526b751d45622ccc1ac53b2e96f9/packages/worker-nestjs/src/worker.module.ts#L95)
83
83
 
84
84
  Register the AMQP worker module with synchronous configuration
85
85
 
@@ -107,7 +107,7 @@ A dynamic module for NestJS
107
107
  static forRootAsync<TContract>(options): DynamicModule;
108
108
  ```
109
109
 
110
- Defined in: [worker-nestjs/src/worker.module.ts:117](https://github.com/btravers/amqp-contract/blob/f058a24938d9644a82812e57d7995cb683cfd6b5/packages/worker-nestjs/src/worker.module.ts#L117)
110
+ Defined in: [worker-nestjs/src/worker.module.ts:117](https://github.com/btravers/amqp-contract/blob/ed05e43c04fa526b751d45622ccc1ac53b2e96f9/packages/worker-nestjs/src/worker.module.ts#L117)
111
111
 
112
112
  Register the AMQP worker module with asynchronous configuration
113
113
 
@@ -133,7 +133,7 @@ A dynamic module for NestJS
133
133
 
134
134
  ### AmqpWorkerService
135
135
 
136
- Defined in: [worker-nestjs/src/worker.service.ts:88](https://github.com/btravers/amqp-contract/blob/f058a24938d9644a82812e57d7995cb683cfd6b5/packages/worker-nestjs/src/worker.service.ts#L88)
136
+ Defined in: [worker-nestjs/src/worker.service.ts:75](https://github.com/btravers/amqp-contract/blob/ed05e43c04fa526b751d45622ccc1ac53b2e96f9/packages/worker-nestjs/src/worker.service.ts#L75)
137
137
 
138
138
  Type-safe AMQP worker service for NestJS applications.
139
139
 
@@ -186,7 +186,7 @@ export class AppModule {}
186
186
  new AmqpWorkerService<TContract>(options): AmqpWorkerService<TContract>;
187
187
  ```
188
188
 
189
- Defined in: [worker-nestjs/src/worker.service.ts:93](https://github.com/btravers/amqp-contract/blob/f058a24938d9644a82812e57d7995cb683cfd6b5/packages/worker-nestjs/src/worker.service.ts#L93)
189
+ Defined in: [worker-nestjs/src/worker.service.ts:80](https://github.com/btravers/amqp-contract/blob/ed05e43c04fa526b751d45622ccc1ac53b2e96f9/packages/worker-nestjs/src/worker.service.ts#L80)
190
190
 
191
191
  ###### Parameters
192
192
 
@@ -206,7 +206,7 @@ Defined in: [worker-nestjs/src/worker.service.ts:93](https://github.com/btravers
206
206
  onModuleDestroy(): Promise<void>;
207
207
  ```
208
208
 
209
- Defined in: [worker-nestjs/src/worker.service.ts:119](https://github.com/btravers/amqp-contract/blob/f058a24938d9644a82812e57d7995cb683cfd6b5/packages/worker-nestjs/src/worker.service.ts#L119)
209
+ Defined in: [worker-nestjs/src/worker.service.ts:106](https://github.com/btravers/amqp-contract/blob/ed05e43c04fa526b751d45622ccc1ac53b2e96f9/packages/worker-nestjs/src/worker.service.ts#L106)
210
210
 
211
211
  Close the AMQP worker when the NestJS module is destroyed.
212
212
 
@@ -230,7 +230,7 @@ OnModuleDestroy.onModuleDestroy
230
230
  onModuleInit(): Promise<void>;
231
231
  ```
232
232
 
233
- Defined in: [worker-nestjs/src/worker.service.ts:108](https://github.com/btravers/amqp-contract/blob/f058a24938d9644a82812e57d7995cb683cfd6b5/packages/worker-nestjs/src/worker.service.ts#L108)
233
+ Defined in: [worker-nestjs/src/worker.service.ts:95](https://github.com/btravers/amqp-contract/blob/ed05e43c04fa526b751d45622ccc1ac53b2e96f9/packages/worker-nestjs/src/worker.service.ts#L95)
234
234
 
235
235
  Initialize the AMQP worker when the NestJS module starts.
236
236
 
@@ -261,7 +261,7 @@ OnModuleInit.onModuleInit
261
261
  type AmqpWorkerModuleAsyncOptions<TContract> = object;
262
262
  ```
263
263
 
264
- Defined in: [worker-nestjs/src/worker.module.ts:22](https://github.com/btravers/amqp-contract/blob/f058a24938d9644a82812e57d7995cb683cfd6b5/packages/worker-nestjs/src/worker.module.ts#L22)
264
+ Defined in: [worker-nestjs/src/worker.module.ts:22](https://github.com/btravers/amqp-contract/blob/ed05e43c04fa526b751d45622ccc1ac53b2e96f9/packages/worker-nestjs/src/worker.module.ts#L22)
265
265
 
266
266
  Options for async module configuration using factory pattern
267
267
 
@@ -275,9 +275,9 @@ Options for async module configuration using factory pattern
275
275
 
276
276
  | Property | Type | Description | Defined in |
277
277
  | ------ | ------ | ------ | ------ |
278
- | <a id="imports"></a> `imports?` | `ModuleMetadata`\[`"imports"`\] | Optional list of imported modules that export providers needed by the factory | [worker-nestjs/src/worker.module.ts:37](https://github.com/btravers/amqp-contract/blob/f058a24938d9644a82812e57d7995cb683cfd6b5/packages/worker-nestjs/src/worker.module.ts#L37) |
279
- | <a id="inject"></a> `inject?` | (`string` \| `symbol` \| `Type`\<`unknown`\>)[] | Optional dependencies to inject into the factory function. Can be a token (string/symbol) a class or a reference to a provider. | [worker-nestjs/src/worker.module.ts:33](https://github.com/btravers/amqp-contract/blob/f058a24938d9644a82812e57d7995cb683cfd6b5/packages/worker-nestjs/src/worker.module.ts#L33) |
280
- | <a id="usefactory"></a> `useFactory` | (...`args`) => `AmqpWorkerModuleOptionsFactory`\<`TContract`\> | Factory function that returns the module options. Can use injected dependencies to create configuration. | [worker-nestjs/src/worker.module.ts:28](https://github.com/btravers/amqp-contract/blob/f058a24938d9644a82812e57d7995cb683cfd6b5/packages/worker-nestjs/src/worker.module.ts#L28) |
278
+ | <a id="imports"></a> `imports?` | `ModuleMetadata`\[`"imports"`\] | Optional list of imported modules that export providers needed by the factory | [worker-nestjs/src/worker.module.ts:37](https://github.com/btravers/amqp-contract/blob/ed05e43c04fa526b751d45622ccc1ac53b2e96f9/packages/worker-nestjs/src/worker.module.ts#L37) |
279
+ | <a id="inject"></a> `inject?` | (`string` \| `symbol` \| `Type`\<`unknown`\>)[] | Optional dependencies to inject into the factory function. Can be a token (string/symbol) a class or a reference to a provider. | [worker-nestjs/src/worker.module.ts:33](https://github.com/btravers/amqp-contract/blob/ed05e43c04fa526b751d45622ccc1ac53b2e96f9/packages/worker-nestjs/src/worker.module.ts#L33) |
280
+ | <a id="usefactory"></a> `useFactory` | (...`args`) => `AmqpWorkerModuleOptionsFactory`\<`TContract`\> | Factory function that returns the module options. Can use injected dependencies to create configuration. | [worker-nestjs/src/worker.module.ts:28](https://github.com/btravers/amqp-contract/blob/ed05e43c04fa526b751d45622ccc1ac53b2e96f9/packages/worker-nestjs/src/worker.module.ts#L28) |
281
281
 
282
282
  ***
283
283
 
@@ -287,39 +287,26 @@ Options for async module configuration using factory pattern
287
287
  type AmqpWorkerModuleOptions<TContract> = object;
288
288
  ```
289
289
 
290
- Defined in: [worker-nestjs/src/worker.service.ts:42](https://github.com/btravers/amqp-contract/blob/f058a24938d9644a82812e57d7995cb683cfd6b5/packages/worker-nestjs/src/worker.service.ts#L42)
290
+ Defined in: [worker-nestjs/src/worker.service.ts:29](https://github.com/btravers/amqp-contract/blob/ed05e43c04fa526b751d45622ccc1ac53b2e96f9/packages/worker-nestjs/src/worker.service.ts#L29)
291
291
 
292
292
  Configuration options for the AMQP worker NestJS module.
293
293
 
294
294
  #### Example
295
295
 
296
296
  ```typescript
297
- import { defineHandlers, defineUnsafeHandlers } from '@amqp-contract/worker';
298
- import { Future, Result } from '@swan-io/boxed';
299
- import { RetryableError } from '@amqp-contract/worker';
297
+ import { defineHandlers, RetryableError } from '@amqp-contract/worker';
298
+ import { Future } from '@swan-io/boxed';
300
299
 
301
- // Using safe handlers (recommended)
302
300
  const options: AmqpWorkerModuleOptions<typeof contract> = {
303
301
  contract: myContract,
304
302
  handlers: defineHandlers(myContract, {
305
- processOrder: (message) =>
306
- Future.fromPromise(processPayment(message))
303
+ processOrder: ({ payload }) =>
304
+ Future.fromPromise(processPayment(payload))
307
305
  .mapOk(() => undefined)
308
306
  .mapError((error) => new RetryableError('Payment failed', error))
309
307
  }),
310
308
  urls: ['amqp://localhost'],
311
309
  };
312
-
313
- // Using unsafe handlers (legacy)
314
- const options: AmqpWorkerModuleOptions<typeof contract> = {
315
- contract: myContract,
316
- handlers: defineUnsafeHandlers(myContract, {
317
- processOrder: async (message) => {
318
- console.log('Processing order:', message.orderId);
319
- }
320
- }),
321
- urls: ['amqp://localhost'],
322
- };
323
310
  ```
324
311
 
325
312
  #### Type Parameters
@@ -332,20 +319,23 @@ const options: AmqpWorkerModuleOptions<typeof contract> = {
332
319
 
333
320
  | Property | Type | Description | Defined in |
334
321
  | ------ | ------ | ------ | ------ |
335
- | <a id="connectionoptions"></a> `connectionOptions?` | `AmqpConnectionManagerOptions` | Optional connection configuration (heartbeat, reconnect settings, etc.) | [worker-nestjs/src/worker.service.ts:50](https://github.com/btravers/amqp-contract/blob/f058a24938d9644a82812e57d7995cb683cfd6b5/packages/worker-nestjs/src/worker.service.ts#L50) |
336
- | <a id="contract"></a> `contract` | `TContract` | The AMQP contract definition specifying consumers and their message schemas | [worker-nestjs/src/worker.service.ts:44](https://github.com/btravers/amqp-contract/blob/f058a24938d9644a82812e57d7995cb683cfd6b5/packages/worker-nestjs/src/worker.service.ts#L44) |
337
- | <a id="handlers"></a> `handlers` | `WorkerInferSafeConsumerHandlers`\<`TContract`\> | Message handlers for each consumer defined in the contract. Use defineHandlers or defineUnsafeHandlers to create type-safe handlers. | [worker-nestjs/src/worker.service.ts:46](https://github.com/btravers/amqp-contract/blob/f058a24938d9644a82812e57d7995cb683cfd6b5/packages/worker-nestjs/src/worker.service.ts#L46) |
338
- | <a id="urls"></a> `urls` | `ConnectionUrl`[] | AMQP broker URL(s). Multiple URLs provide failover support | [worker-nestjs/src/worker.service.ts:48](https://github.com/btravers/amqp-contract/blob/f058a24938d9644a82812e57d7995cb683cfd6b5/packages/worker-nestjs/src/worker.service.ts#L48) |
322
+ | <a id="connectionoptions"></a> `connectionOptions?` | `AmqpConnectionManagerOptions` | Optional connection configuration (heartbeat, reconnect settings, etc.) | [worker-nestjs/src/worker.service.ts:37](https://github.com/btravers/amqp-contract/blob/ed05e43c04fa526b751d45622ccc1ac53b2e96f9/packages/worker-nestjs/src/worker.service.ts#L37) |
323
+ | <a id="contract"></a> `contract` | `TContract` | The AMQP contract definition specifying consumers and their message schemas | [worker-nestjs/src/worker.service.ts:31](https://github.com/btravers/amqp-contract/blob/ed05e43c04fa526b751d45622ccc1ac53b2e96f9/packages/worker-nestjs/src/worker.service.ts#L31) |
324
+ | <a id="handlers"></a> `handlers` | [`WorkerInferSafeConsumerHandlers`](#workerinfersafeconsumerhandlers)\<`TContract`\> | Message handlers for each consumer defined in the contract. Use defineHandlers to create type-safe handlers. | [worker-nestjs/src/worker.service.ts:33](https://github.com/btravers/amqp-contract/blob/ed05e43c04fa526b751d45622ccc1ac53b2e96f9/packages/worker-nestjs/src/worker.service.ts#L33) |
325
+ | <a id="urls"></a> `urls` | `ConnectionUrl`[] | AMQP broker URL(s). Multiple URLs provide failover support | [worker-nestjs/src/worker.service.ts:35](https://github.com/btravers/amqp-contract/blob/ed05e43c04fa526b751d45622ccc1ac53b2e96f9/packages/worker-nestjs/src/worker.service.ts#L35) |
339
326
 
340
327
  ***
341
328
 
342
- ### ~~WorkerInferConsumerHandlers~~
329
+ ### WorkerInferSafeConsumerHandlers
343
330
 
344
331
  ```ts
345
- type WorkerInferConsumerHandlers<TContract> = WorkerInferUnsafeConsumerHandlers<TContract>;
332
+ type WorkerInferSafeConsumerHandlers<TContract> = { [K in InferConsumerNames<TContract>]: WorkerInferSafeConsumerHandlerEntry<TContract, K> };
346
333
  ```
347
334
 
348
- Defined in: worker/dist/index.d.mts:182
335
+ Defined in: worker/dist/index.d.mts:160
336
+
337
+ Safe consumer handlers for a contract.
338
+ All handlers return `Future<Result<void, HandlerError>>` for explicit error control.
349
339
 
350
340
  #### Type Parameters
351
341
 
@@ -353,10 +343,6 @@ Defined in: worker/dist/index.d.mts:182
353
343
  | ------ |
354
344
  | `TContract` *extends* `ContractDefinition` |
355
345
 
356
- #### Deprecated
357
-
358
- Use WorkerInferUnsafeConsumerHandlers instead
359
-
360
346
  ## Variables
361
347
 
362
348
  ### MODULE\_OPTIONS\_TOKEN
@@ -365,7 +351,7 @@ Use WorkerInferUnsafeConsumerHandlers instead
365
351
  const MODULE_OPTIONS_TOKEN: typeof MODULE_OPTIONS_TOKEN;
366
352
  ```
367
353
 
368
- Defined in: [worker-nestjs/src/worker.module-definition.ts:5](https://github.com/btravers/amqp-contract/blob/f058a24938d9644a82812e57d7995cb683cfd6b5/packages/worker-nestjs/src/worker.module-definition.ts#L5)
354
+ Defined in: [worker-nestjs/src/worker.module-definition.ts:5](https://github.com/btravers/amqp-contract/blob/ed05e43c04fa526b751d45622ccc1ac53b2e96f9/packages/worker-nestjs/src/worker.module-definition.ts#L5)
369
355
 
370
356
  Injection token for AMQP worker module options
371
357
  Used by NestJS DI system to inject configuration into AmqpWorkerService
@@ -383,17 +369,16 @@ function defineHandler<TContract, TName>(
383
369
  handler): WorkerInferSafeConsumerHandlerEntry<TContract, TName>;
384
370
  ```
385
371
 
386
- Defined in: worker/dist/index.d.mts:511
372
+ Defined in: worker/dist/index.d.mts:486
387
373
 
388
374
  Define a type-safe handler for a specific consumer in a contract.
389
375
 
390
376
  **Recommended:** This function creates handlers that return `Future<Result<void, HandlerError>>`,
391
377
  providing explicit error handling and better control over retry behavior.
392
378
 
393
- Supports three patterns:
394
- 1. Simple handler: just the function (single message handler)
395
- 2. Handler with prefetch: [handler, { prefetch: 10 }] (single message handler with config)
396
- 3. Batch handler: [batchHandler, { batchSize: 5, batchTimeout: 1000 }] (REQUIRES batchSize config)
379
+ Supports two patterns:
380
+ 1. Simple handler: just the function
381
+ 2. Handler with options: [handler, { prefetch: 10 }]
397
382
 
398
383
  ##### Type Parameters
399
384
 
@@ -427,8 +412,8 @@ import { orderContract } from './contract';
427
412
  const processOrderHandler = defineHandler(
428
413
  orderContract,
429
414
  'processOrder',
430
- (message) =>
431
- Future.fromPromise(processPayment(message))
415
+ ({ payload }) =>
416
+ Future.fromPromise(processPayment(payload))
432
417
  .mapOk(() => undefined)
433
418
  .mapError((error) => new RetryableError('Payment failed', error))
434
419
  );
@@ -437,8 +422,8 @@ const processOrderHandler = defineHandler(
437
422
  const validateOrderHandler = defineHandler(
438
423
  orderContract,
439
424
  'validateOrder',
440
- (message) => {
441
- if (message.amount < 1) {
425
+ ({ payload }) => {
426
+ if (payload.amount < 1) {
442
427
  // Won't be retried - goes directly to DLQ
443
428
  return Future.value(Result.Error(new NonRetryableError('Invalid order amount')));
444
429
  }
@@ -457,17 +442,16 @@ function defineHandler<TContract, TName>(
457
442
  options): WorkerInferSafeConsumerHandlerEntry<TContract, TName>;
458
443
  ```
459
444
 
460
- Defined in: worker/dist/index.d.mts:512
445
+ Defined in: worker/dist/index.d.mts:487
461
446
 
462
447
  Define a type-safe handler for a specific consumer in a contract.
463
448
 
464
449
  **Recommended:** This function creates handlers that return `Future<Result<void, HandlerError>>`,
465
450
  providing explicit error handling and better control over retry behavior.
466
451
 
467
- Supports three patterns:
468
- 1. Simple handler: just the function (single message handler)
469
- 2. Handler with prefetch: [handler, { prefetch: 10 }] (single message handler with config)
470
- 3. Batch handler: [batchHandler, { batchSize: 5, batchTimeout: 1000 }] (REQUIRES batchSize config)
452
+ Supports two patterns:
453
+ 1. Simple handler: just the function
454
+ 2. Handler with options: [handler, { prefetch: 10 }]
471
455
 
472
456
  ##### Type Parameters
473
457
 
@@ -483,87 +467,7 @@ Supports three patterns:
483
467
  | `contract` | `TContract` | The contract definition containing the consumer |
484
468
  | `consumerName` | `TName` | The name of the consumer from the contract |
485
469
  | `handler` | `WorkerInferSafeConsumerHandler`\<`TContract`, `TName`\> | The handler function that returns `Future<Result<void, HandlerError>>` |
486
- | `options` | \{ `batchSize?`: `undefined`; `batchTimeout?`: `undefined`; `prefetch?`: `number`; \} | Optional consumer options (prefetch, batchSize, batchTimeout) |
487
- | `options.batchSize?` | `undefined` | - |
488
- | `options.batchTimeout?` | `undefined` | - |
489
- | `options.prefetch?` | `number` | - |
490
-
491
- ##### Returns
492
-
493
- `WorkerInferSafeConsumerHandlerEntry`\<`TContract`, `TName`\>
494
-
495
- A type-safe handler that can be used with TypedAmqpWorker
496
-
497
- ##### Example
498
-
499
- ```typescript
500
- import { defineHandler, RetryableError, NonRetryableError } from '@amqp-contract/worker';
501
- import { Future, Result } from '@swan-io/boxed';
502
- import { orderContract } from './contract';
503
-
504
- // Simple handler with explicit error handling using mapError
505
- const processOrderHandler = defineHandler(
506
- orderContract,
507
- 'processOrder',
508
- (message) =>
509
- Future.fromPromise(processPayment(message))
510
- .mapOk(() => undefined)
511
- .mapError((error) => new RetryableError('Payment failed', error))
512
- );
513
-
514
- // Handler with validation (non-retryable error)
515
- const validateOrderHandler = defineHandler(
516
- orderContract,
517
- 'validateOrder',
518
- (message) => {
519
- if (message.amount < 1) {
520
- // Won't be retried - goes directly to DLQ
521
- return Future.value(Result.Error(new NonRetryableError('Invalid order amount')));
522
- }
523
- return Future.value(Result.Ok(undefined));
524
- }
525
- );
526
- ```
527
-
528
- #### Call Signature
529
-
530
- ```ts
531
- function defineHandler<TContract, TName>(
532
- contract,
533
- consumerName,
534
- handler,
535
- options): WorkerInferSafeConsumerHandlerEntry<TContract, TName>;
536
- ```
537
-
538
- Defined in: worker/dist/index.d.mts:517
539
-
540
- Define a type-safe handler for a specific consumer in a contract.
541
-
542
- **Recommended:** This function creates handlers that return `Future<Result<void, HandlerError>>`,
543
- providing explicit error handling and better control over retry behavior.
544
-
545
- Supports three patterns:
546
- 1. Simple handler: just the function (single message handler)
547
- 2. Handler with prefetch: [handler, { prefetch: 10 }] (single message handler with config)
548
- 3. Batch handler: [batchHandler, { batchSize: 5, batchTimeout: 1000 }] (REQUIRES batchSize config)
549
-
550
- ##### Type Parameters
551
-
552
- | Type Parameter | Description |
553
- | ------ | ------ |
554
- | `TContract` *extends* `ContractDefinition` | The contract definition type |
555
- | `TName` *extends* `string` \| `number` \| `symbol` | The consumer name from the contract |
556
-
557
- ##### Parameters
558
-
559
- | Parameter | Type | Description |
560
- | ------ | ------ | ------ |
561
- | `contract` | `TContract` | The contract definition containing the consumer |
562
- | `consumerName` | `TName` | The name of the consumer from the contract |
563
- | `handler` | `WorkerInferSafeConsumerBatchHandler`\<`TContract`, `TName`\> | The handler function that returns `Future<Result<void, HandlerError>>` |
564
- | `options` | \{ `batchSize`: `number`; `batchTimeout?`: `number`; `prefetch?`: `number`; \} | Optional consumer options (prefetch, batchSize, batchTimeout) |
565
- | `options.batchSize` | `number` | - |
566
- | `options.batchTimeout?` | `number` | - |
470
+ | `options` | \{ `prefetch?`: `number`; \} | Optional consumer options (prefetch) |
567
471
  | `options.prefetch?` | `number` | - |
568
472
 
569
473
  ##### Returns
@@ -583,8 +487,8 @@ import { orderContract } from './contract';
583
487
  const processOrderHandler = defineHandler(
584
488
  orderContract,
585
489
  'processOrder',
586
- (message) =>
587
- Future.fromPromise(processPayment(message))
490
+ ({ payload }) =>
491
+ Future.fromPromise(processPayment(payload))
588
492
  .mapOk(() => undefined)
589
493
  .mapError((error) => new RetryableError('Payment failed', error))
590
494
  );
@@ -593,8 +497,8 @@ const processOrderHandler = defineHandler(
593
497
  const validateOrderHandler = defineHandler(
594
498
  orderContract,
595
499
  'validateOrder',
596
- (message) => {
597
- if (message.amount < 1) {
500
+ ({ payload }) => {
501
+ if (payload.amount < 1) {
598
502
  // Won't be retried - goes directly to DLQ
599
503
  return Future.value(Result.Error(new NonRetryableError('Invalid order amount')));
600
504
  }
@@ -611,7 +515,7 @@ const validateOrderHandler = defineHandler(
611
515
  function defineHandlers<TContract>(contract, handlers): WorkerInferSafeConsumerHandlers<TContract>;
612
516
  ```
613
517
 
614
- Defined in: worker/dist/index.d.mts:551
518
+ Defined in: worker/dist/index.d.mts:519
615
519
 
616
520
  Define multiple type-safe handlers for consumers in a contract.
617
521
 
@@ -629,11 +533,11 @@ providing explicit error handling and better control over retry behavior.
629
533
  | Parameter | Type | Description |
630
534
  | ------ | ------ | ------ |
631
535
  | `contract` | `TContract` | The contract definition containing the consumers |
632
- | `handlers` | `WorkerInferSafeConsumerHandlers`\<`TContract`\> | An object with handler functions for each consumer |
536
+ | `handlers` | [`WorkerInferSafeConsumerHandlers`](#workerinfersafeconsumerhandlers)\<`TContract`\> | An object with handler functions for each consumer |
633
537
 
634
538
  #### Returns
635
539
 
636
- `WorkerInferSafeConsumerHandlers`\<`TContract`\>
540
+ [`WorkerInferSafeConsumerHandlers`](#workerinfersafeconsumerhandlers)\<`TContract`\>
637
541
 
638
542
  A type-safe handlers object that can be used with TypedAmqpWorker
639
543
 
@@ -645,12 +549,12 @@ import { Future } from '@swan-io/boxed';
645
549
  import { orderContract } from './contract';
646
550
 
647
551
  const handlers = defineHandlers(orderContract, {
648
- processOrder: (message) =>
649
- Future.fromPromise(processPayment(message))
552
+ processOrder: ({ payload }) =>
553
+ Future.fromPromise(processPayment(payload))
650
554
  .mapOk(() => undefined)
651
555
  .mapError((error) => new RetryableError('Payment failed', error)),
652
- notifyOrder: (message) =>
653
- Future.fromPromise(sendNotification(message))
556
+ notifyOrder: ({ payload }) =>
557
+ Future.fromPromise(sendNotification(payload))
654
558
  .mapOk(() => undefined)
655
559
  .mapError((error) => new RetryableError('Notification failed', error)),
656
560
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amqp-contract/worker-nestjs",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "NestJS integration for @amqp-contract/worker",
5
5
  "keywords": [
6
6
  "amqp",
@@ -52,27 +52,27 @@
52
52
  "docs"
53
53
  ],
54
54
  "dependencies": {
55
- "@amqp-contract/contract": "0.9.0",
56
- "@amqp-contract/worker": "0.9.0"
55
+ "@amqp-contract/contract": "0.11.0",
56
+ "@amqp-contract/worker": "0.11.0"
57
57
  },
58
58
  "devDependencies": {
59
- "@nestjs/common": "11.1.11",
60
- "@nestjs/core": "11.1.11",
61
- "@nestjs/testing": "11.1.11",
59
+ "@nestjs/common": "11.1.12",
60
+ "@nestjs/core": "11.1.12",
61
+ "@nestjs/testing": "11.1.12",
62
62
  "@swan-io/boxed": "3.2.1",
63
- "@types/node": "25.0.5",
64
- "@vitest/coverage-v8": "4.0.16",
63
+ "@types/node": "25.0.9",
64
+ "@vitest/coverage-v8": "4.0.17",
65
65
  "amqp-connection-manager": "5.0.0",
66
66
  "amqplib": "0.10.9",
67
67
  "reflect-metadata": "0.2.2",
68
68
  "rxjs": "7.8.2",
69
69
  "tsdown": "0.19.0",
70
- "typedoc": "0.28.15",
70
+ "typedoc": "0.28.16",
71
71
  "typedoc-plugin-markdown": "4.9.0",
72
72
  "typescript": "5.9.3",
73
- "vitest": "4.0.16",
73
+ "vitest": "4.0.17",
74
74
  "zod": "4.3.5",
75
- "@amqp-contract/testing": "0.9.0",
75
+ "@amqp-contract/testing": "0.11.0",
76
76
  "@amqp-contract/tsconfig": "0.1.0",
77
77
  "@amqp-contract/typedoc": "0.1.0"
78
78
  },