@amqp-contract/worker-nestjs 0.7.0 → 0.9.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
@@ -32,7 +32,7 @@ import { contract } from "./contract";
32
32
  console.log("Processing order:", message.orderId);
33
33
  },
34
34
  },
35
- connection: "amqp://localhost",
35
+ urls: ["amqp://localhost"],
36
36
  }),
37
37
  ],
38
38
  })
package/dist/index.cjs CHANGED
@@ -9,13 +9,13 @@ let _amqp_contract_worker = require("@amqp-contract/worker");
9
9
  const MODULE_OPTIONS_TOKEN = Symbol("AMQP_WORKER_MODULE_OPTIONS");
10
10
 
11
11
  //#endregion
12
- //#region \0@oxc-project+runtime@0.103.0/helpers/decorateMetadata.js
12
+ //#region \0@oxc-project+runtime@0.107.0/helpers/decorateMetadata.js
13
13
  function __decorateMetadata(k, v) {
14
14
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
15
15
  }
16
16
 
17
17
  //#endregion
18
- //#region \0@oxc-project+runtime@0.103.0/helpers/decorateParam.js
18
+ //#region \0@oxc-project+runtime@0.107.0/helpers/decorateParam.js
19
19
  function __decorateParam(paramIndex, decorator) {
20
20
  return function(target, key) {
21
21
  decorator(target, key, paramIndex);
@@ -23,7 +23,7 @@ function __decorateParam(paramIndex, decorator) {
23
23
  }
24
24
 
25
25
  //#endregion
26
- //#region \0@oxc-project+runtime@0.103.0/helpers/decorate.js
26
+ //#region \0@oxc-project+runtime@0.107.0/helpers/decorate.js
27
27
  function __decorate(decorators, target, key, desc) {
28
28
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
29
29
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -101,11 +101,11 @@ let AmqpWorkerModule = _AmqpWorkerModule = class AmqpWorkerModule$1 {
101
101
  const providers = [{
102
102
  provide: MODULE_OPTIONS_TOKEN,
103
103
  useFactory: options.useFactory,
104
- inject: options.inject || []
104
+ inject: options.inject ?? []
105
105
  }, AmqpWorkerService];
106
106
  return {
107
107
  module: _AmqpWorkerModule,
108
- imports: options.imports || [],
108
+ imports: options.imports ?? [],
109
109
  providers,
110
110
  exports: [AmqpWorkerService]
111
111
  };
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, WorkerInferConsumerHandlers as WorkerInferConsumerHandlers$1, defineHandler, defineHandlers } from "@amqp-contract/worker";
3
+ import { WorkerInferConsumerHandlers, WorkerInferSafeConsumerHandlers, 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,25 +12,39 @@ 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';
18
+ *
19
+ * // Using safe handlers (recommended)
20
+ * const options: AmqpWorkerModuleOptions<typeof contract> = {
21
+ * contract: myContract,
22
+ * handlers: defineHandlers(myContract, {
23
+ * processOrder: (message) =>
24
+ * Future.fromPromise(processPayment(message))
25
+ * .mapOk(() => undefined)
26
+ * .mapError((error) => new RetryableError('Payment failed', error))
27
+ * }),
28
+ * urls: ['amqp://localhost'],
29
+ * };
30
+ *
31
+ * // Using unsafe handlers (legacy)
15
32
  * const options: AmqpWorkerModuleOptions<typeof contract> = {
16
33
  * contract: myContract,
17
- * handlers: {
34
+ * handlers: defineUnsafeHandlers(myContract, {
18
35
  * processOrder: async (message) => {
19
36
  * console.log('Processing order:', message.orderId);
20
37
  * }
21
- * },
38
+ * }),
22
39
  * urls: ['amqp://localhost'],
23
- * connectionOptions: {
24
- * heartbeatIntervalInSeconds: 30
25
- * }
26
40
  * };
27
41
  * ```
28
42
  */
29
43
  type AmqpWorkerModuleOptions<TContract extends ContractDefinition> = {
30
44
  /** The AMQP contract definition specifying consumers and their message schemas */
31
45
  contract: TContract;
32
- /** Message handlers for each consumer defined in the contract */
33
- handlers: WorkerInferConsumerHandlers$1<TContract>;
46
+ /** Message handlers for each consumer defined in the contract. Use defineHandlers or defineUnsafeHandlers to create type-safe handlers. */
47
+ handlers: WorkerInferSafeConsumerHandlers<TContract>;
34
48
  /** AMQP broker URL(s). Multiple URLs provide failover support */
35
49
  urls: ConnectionUrl[];
36
50
  /** Optional connection configuration (heartbeat, reconnect settings, etc.) */
@@ -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":";;;;;;;;;AA2BA;;;;;;;;AA6CA;;;;;;;;;;;KA7CY,0CAA0C;ECbjD;EAAiD,QAAA,EDe1C,SCf0C;EAC1B;EAAxB,QAAA,EDgBQ,6BChBR,CDgBoC,SChBpC,CAAA;EACgC;EAAxB,IAAA,EDiBJ,aCjBI,EAAA;EAAR;EAAO,iBAAA,CAAA,EDmBW,4BCnBX,GAAA,SAAA;AAKX,CAAA;;;;;;;AAiEA;;;;;;;;;;;;;AClFA;;;;;;;;;;;;;;;cFqEa,oCAAoC,+BACpC,cAAc;;;uBAMG,wBAAwB;;;;;;;;;;;kBAa9B;;;;;;;;qBAWG;;;;;;;AA7E3B,KCbK,8BDa8B,CAAA,kBCbmB,kBDanB,CAAA,GCZ/B,uBDY+B,CCZP,SDYO,CAAA,GCX/B,ODW+B,CCXvB,uBDWuB,CCXC,SDWD,CAAA,CAAA;;;;AAIvB,KCVA,4BDUA,CAAA,kBCV+C,kBDU/C,CAAA,GAAA;EAEJ;;;AAuCR;EACiD,UAAA,EAAA,CAAA,GAAA,IAAA,EAAA,GAAA,EAAA,EAAA,GC9Cf,8BD8Ce,CC9CgB,SD8ChB,CAAA;EAOK;;;;EANzC,MAAA,CAAA,EAAA,CAAA,MAAA,GAAA,MAAA,GC1CiB,ID0CjB,CAAA,OAAA,CAAA,CAAA,EAAA;EAAc;;;YCtCf;;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":";;;;;;;;;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"}
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { DynamicModule, ModuleMetadata, OnModuleDestroy, OnModuleInit, Type } from "@nestjs/common";
2
- import { WorkerInferConsumerHandlers, WorkerInferConsumerHandlers as WorkerInferConsumerHandlers$1, defineHandler, defineHandlers } from "@amqp-contract/worker";
2
+ import { WorkerInferConsumerHandlers, WorkerInferSafeConsumerHandlers, 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,25 +12,39 @@ 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';
18
+ *
19
+ * // Using safe handlers (recommended)
20
+ * const options: AmqpWorkerModuleOptions<typeof contract> = {
21
+ * contract: myContract,
22
+ * handlers: defineHandlers(myContract, {
23
+ * processOrder: (message) =>
24
+ * Future.fromPromise(processPayment(message))
25
+ * .mapOk(() => undefined)
26
+ * .mapError((error) => new RetryableError('Payment failed', error))
27
+ * }),
28
+ * urls: ['amqp://localhost'],
29
+ * };
30
+ *
31
+ * // Using unsafe handlers (legacy)
15
32
  * const options: AmqpWorkerModuleOptions<typeof contract> = {
16
33
  * contract: myContract,
17
- * handlers: {
34
+ * handlers: defineUnsafeHandlers(myContract, {
18
35
  * processOrder: async (message) => {
19
36
  * console.log('Processing order:', message.orderId);
20
37
  * }
21
- * },
38
+ * }),
22
39
  * urls: ['amqp://localhost'],
23
- * connectionOptions: {
24
- * heartbeatIntervalInSeconds: 30
25
- * }
26
40
  * };
27
41
  * ```
28
42
  */
29
43
  type AmqpWorkerModuleOptions<TContract extends ContractDefinition> = {
30
44
  /** The AMQP contract definition specifying consumers and their message schemas */
31
45
  contract: TContract;
32
- /** Message handlers for each consumer defined in the contract */
33
- handlers: WorkerInferConsumerHandlers$1<TContract>;
46
+ /** Message handlers for each consumer defined in the contract. Use defineHandlers or defineUnsafeHandlers to create type-safe handlers. */
47
+ handlers: WorkerInferSafeConsumerHandlers<TContract>;
34
48
  /** AMQP broker URL(s). Multiple URLs provide failover support */
35
49
  urls: ConnectionUrl[];
36
50
  /** Optional connection configuration (heartbeat, reconnect settings, etc.) */
@@ -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":";;;;;;;;;AA2BA;;;;;;;;AA6CA;;;;;;;;;;;KA7CY,0CAA0C;ECbjD;EAAiD,QAAA,EDe1C,SCf0C;EAC1B;EAAxB,QAAA,EDgBQ,6BChBR,CDgBoC,SChBpC,CAAA;EACgC;EAAxB,IAAA,EDiBJ,aCjBI,EAAA;EAAR;EAAO,iBAAA,CAAA,EDmBW,4BCnBX,GAAA,SAAA;AAKX,CAAA;;;;;;;AAiEA;;;;;;;;;;;;;AClFA;;;;;;;;;;;;;;;cFqEa,oCAAoC,+BACpC,cAAc;;;uBAMG,wBAAwB;;;;;;;;;;;kBAa9B;;;;;;;;qBAWG;;;;;;;AA7E3B,KCbK,8BDa8B,CAAA,kBCbmB,kBDanB,CAAA,GCZ/B,uBDY+B,CCZP,SDYO,CAAA,GCX/B,ODW+B,CCXvB,uBDWuB,CCXC,SDWD,CAAA,CAAA;;;;AAIvB,KCVA,4BDUA,CAAA,kBCV+C,kBDU/C,CAAA,GAAA;EAEJ;;;AAuCR;EACiD,UAAA,EAAA,CAAA,GAAA,IAAA,EAAA,GAAA,EAAA,EAAA,GC9Cf,8BD8Ce,CC9CgB,SD8ChB,CAAA;EAOK;;;;EANzC,MAAA,CAAA,EAAA,CAAA,MAAA,GAAA,MAAA,GC1CiB,ID0CjB,CAAA,OAAA,CAAA,CAAA,EAAA;EAAc;;;YCtCf;;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":";;;;;;;;;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"}
package/dist/index.mjs CHANGED
@@ -9,13 +9,13 @@ import { TypedAmqpWorker, defineHandler, defineHandlers } from "@amqp-contract/w
9
9
  const MODULE_OPTIONS_TOKEN = Symbol("AMQP_WORKER_MODULE_OPTIONS");
10
10
 
11
11
  //#endregion
12
- //#region \0@oxc-project+runtime@0.103.0/helpers/decorateMetadata.js
12
+ //#region \0@oxc-project+runtime@0.107.0/helpers/decorateMetadata.js
13
13
  function __decorateMetadata(k, v) {
14
14
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
15
15
  }
16
16
 
17
17
  //#endregion
18
- //#region \0@oxc-project+runtime@0.103.0/helpers/decorateParam.js
18
+ //#region \0@oxc-project+runtime@0.107.0/helpers/decorateParam.js
19
19
  function __decorateParam(paramIndex, decorator) {
20
20
  return function(target, key) {
21
21
  decorator(target, key, paramIndex);
@@ -23,7 +23,7 @@ function __decorateParam(paramIndex, decorator) {
23
23
  }
24
24
 
25
25
  //#endregion
26
- //#region \0@oxc-project+runtime@0.103.0/helpers/decorate.js
26
+ //#region \0@oxc-project+runtime@0.107.0/helpers/decorate.js
27
27
  function __decorate(decorators, target, key, desc) {
28
28
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
29
29
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -101,11 +101,11 @@ let AmqpWorkerModule = _AmqpWorkerModule = class AmqpWorkerModule$1 {
101
101
  const providers = [{
102
102
  provide: MODULE_OPTIONS_TOKEN,
103
103
  useFactory: options.useFactory,
104
- inject: options.inject || []
104
+ inject: options.inject ?? []
105
105
  }, AmqpWorkerService];
106
106
  return {
107
107
  module: _AmqpWorkerModule,
108
- imports: options.imports || [],
108
+ imports: options.imports ?? [],
109
109
  providers,
110
110
  exports: [AmqpWorkerService]
111
111
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["AmqpWorkerService","options: AmqpWorkerModuleOptions<TContract>","AmqpWorkerModule","providers: Provider[]"],"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 WorkerInferConsumerHandlers } 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 * const options: AmqpWorkerModuleOptions<typeof contract> = {\n * contract: myContract,\n * handlers: {\n * processOrder: async (message) => {\n * console.log('Processing order:', message.orderId);\n * }\n * },\n * urls: ['amqp://localhost'],\n * connectionOptions: {\n * heartbeatIntervalInSeconds: 30\n * }\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 */\n handlers: WorkerInferConsumerHandlers<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;;;;;;;;;;;;;;;;;;;;;;;;;;;ACqEjE,8BAAMA,oBAEb;CACE,AAAQ,SAA4C;CAEpD,YACE,AACiBC,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;;;;;;;ACQ1B,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,MAAMC,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, 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"}
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/382c6d2fbfc563c9f6f16cb71cb33fd4a3d41d77/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/f058a24938d9644a82812e57d7995cb683cfd6b5/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/382c6d2fbfc563c9f6f16cb71cb33fd4a3d41d77/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/f058a24938d9644a82812e57d7995cb683cfd6b5/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/382c6d2fbfc563c9f6f16cb71cb33fd4a3d41d77/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/f058a24938d9644a82812e57d7995cb683cfd6b5/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:74](https://github.com/btravers/amqp-contract/blob/382c6d2fbfc563c9f6f16cb71cb33fd4a3d41d77/packages/worker-nestjs/src/worker.service.ts#L74)
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)
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:79](https://github.com/btravers/amqp-contract/blob/382c6d2fbfc563c9f6f16cb71cb33fd4a3d41d77/packages/worker-nestjs/src/worker.service.ts#L79)
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)
190
190
 
191
191
  ###### Parameters
192
192
 
@@ -206,7 +206,7 @@ Defined in: [worker-nestjs/src/worker.service.ts:79](https://github.com/btravers
206
206
  onModuleDestroy(): Promise<void>;
207
207
  ```
208
208
 
209
- Defined in: [worker-nestjs/src/worker.service.ts:105](https://github.com/btravers/amqp-contract/blob/382c6d2fbfc563c9f6f16cb71cb33fd4a3d41d77/packages/worker-nestjs/src/worker.service.ts#L105)
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)
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:94](https://github.com/btravers/amqp-contract/blob/382c6d2fbfc563c9f6f16cb71cb33fd4a3d41d77/packages/worker-nestjs/src/worker.service.ts#L94)
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)
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/382c6d2fbfc563c9f6f16cb71cb33fd4a3d41d77/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/f058a24938d9644a82812e57d7995cb683cfd6b5/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/382c6d2fbfc563c9f6f16cb71cb33fd4a3d41d77/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/382c6d2fbfc563c9f6f16cb71cb33fd4a3d41d77/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/382c6d2fbfc563c9f6f16cb71cb33fd4a3d41d77/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/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) |
281
281
 
282
282
  ***
283
283
 
@@ -287,24 +287,38 @@ 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:28](https://github.com/btravers/amqp-contract/blob/382c6d2fbfc563c9f6f16cb71cb33fd4a3d41d77/packages/worker-nestjs/src/worker.service.ts#L28)
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)
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';
300
+
301
+ // Using safe handlers (recommended)
302
+ const options: AmqpWorkerModuleOptions<typeof contract> = {
303
+ contract: myContract,
304
+ handlers: defineHandlers(myContract, {
305
+ processOrder: (message) =>
306
+ Future.fromPromise(processPayment(message))
307
+ .mapOk(() => undefined)
308
+ .mapError((error) => new RetryableError('Payment failed', error))
309
+ }),
310
+ urls: ['amqp://localhost'],
311
+ };
312
+
313
+ // Using unsafe handlers (legacy)
297
314
  const options: AmqpWorkerModuleOptions<typeof contract> = {
298
315
  contract: myContract,
299
- handlers: {
316
+ handlers: defineUnsafeHandlers(myContract, {
300
317
  processOrder: async (message) => {
301
318
  console.log('Processing order:', message.orderId);
302
319
  }
303
- },
320
+ }),
304
321
  urls: ['amqp://localhost'],
305
- connectionOptions: {
306
- heartbeatIntervalInSeconds: 30
307
- }
308
322
  };
309
323
  ```
310
324
 
@@ -318,23 +332,20 @@ const options: AmqpWorkerModuleOptions<typeof contract> = {
318
332
 
319
333
  | Property | Type | Description | Defined in |
320
334
  | ------ | ------ | ------ | ------ |
321
- | <a id="connectionoptions"></a> `connectionOptions?` | `AmqpConnectionManagerOptions` | Optional connection configuration (heartbeat, reconnect settings, etc.) | [worker-nestjs/src/worker.service.ts:36](https://github.com/btravers/amqp-contract/blob/382c6d2fbfc563c9f6f16cb71cb33fd4a3d41d77/packages/worker-nestjs/src/worker.service.ts#L36) |
322
- | <a id="contract"></a> `contract` | `TContract` | The AMQP contract definition specifying consumers and their message schemas | [worker-nestjs/src/worker.service.ts:30](https://github.com/btravers/amqp-contract/blob/382c6d2fbfc563c9f6f16cb71cb33fd4a3d41d77/packages/worker-nestjs/src/worker.service.ts#L30) |
323
- | <a id="handlers"></a> `handlers` | [`WorkerInferConsumerHandlers`](#workerinferconsumerhandlers)\<`TContract`\> | Message handlers for each consumer defined in the contract | [worker-nestjs/src/worker.service.ts:32](https://github.com/btravers/amqp-contract/blob/382c6d2fbfc563c9f6f16cb71cb33fd4a3d41d77/packages/worker-nestjs/src/worker.service.ts#L32) |
324
- | <a id="urls"></a> `urls` | `ConnectionUrl`[] | AMQP broker URL(s). Multiple URLs provide failover support | [worker-nestjs/src/worker.service.ts:34](https://github.com/btravers/amqp-contract/blob/382c6d2fbfc563c9f6f16cb71cb33fd4a3d41d77/packages/worker-nestjs/src/worker.service.ts#L34) |
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) |
325
339
 
326
340
  ***
327
341
 
328
- ### WorkerInferConsumerHandlers
342
+ ### ~~WorkerInferConsumerHandlers~~
329
343
 
330
344
  ```ts
331
- type WorkerInferConsumerHandlers<TContract> = { [K in InferConsumerNames<TContract>]: WorkerInferConsumerHandlerEntry<TContract, K> };
345
+ type WorkerInferConsumerHandlers<TContract> = WorkerInferUnsafeConsumerHandlers<TContract>;
332
346
  ```
333
347
 
334
- Defined in: worker/dist/index.d.mts:84
335
-
336
- Infer all consumer handlers for a contract.
337
- Handlers can be either single-message handlers, batch handlers, or a tuple of [handler, options].
348
+ Defined in: worker/dist/index.d.mts:182
338
349
 
339
350
  #### Type Parameters
340
351
 
@@ -342,6 +353,10 @@ Handlers can be either single-message handlers, batch handlers, or a tuple of [h
342
353
  | ------ |
343
354
  | `TContract` *extends* `ContractDefinition` |
344
355
 
356
+ #### Deprecated
357
+
358
+ Use WorkerInferUnsafeConsumerHandlers instead
359
+
345
360
  ## Variables
346
361
 
347
362
  ### MODULE\_OPTIONS\_TOKEN
@@ -350,7 +365,7 @@ Handlers can be either single-message handlers, batch handlers, or a tuple of [h
350
365
  const MODULE_OPTIONS_TOKEN: typeof MODULE_OPTIONS_TOKEN;
351
366
  ```
352
367
 
353
- Defined in: [worker-nestjs/src/worker.module-definition.ts:5](https://github.com/btravers/amqp-contract/blob/382c6d2fbfc563c9f6f16cb71cb33fd4a3d41d77/packages/worker-nestjs/src/worker.module-definition.ts#L5)
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
369
 
355
370
  Injection token for AMQP worker module options
356
371
  Used by NestJS DI system to inject configuration into AmqpWorkerService
@@ -365,24 +380,21 @@ Used by NestJS DI system to inject configuration into AmqpWorkerService
365
380
  function defineHandler<TContract, TName>(
366
381
  contract,
367
382
  consumerName,
368
- handler): WorkerInferConsumerHandlerEntry<TContract, TName>;
383
+ handler): WorkerInferSafeConsumerHandlerEntry<TContract, TName>;
369
384
  ```
370
385
 
371
- Defined in: worker/dist/index.d.mts:324
386
+ Defined in: worker/dist/index.d.mts:511
372
387
 
373
388
  Define a type-safe handler for a specific consumer in a contract.
374
389
 
375
- This utility allows you to define handlers outside of the worker creation,
376
- providing better code organization and reusability.
390
+ **Recommended:** This function creates handlers that return `Future<Result<void, HandlerError>>`,
391
+ providing explicit error handling and better control over retry behavior.
377
392
 
378
393
  Supports three patterns:
379
394
  1. Simple handler: just the function (single message handler)
380
395
  2. Handler with prefetch: [handler, { prefetch: 10 }] (single message handler with config)
381
396
  3. Batch handler: [batchHandler, { batchSize: 5, batchTimeout: 1000 }] (REQUIRES batchSize config)
382
397
 
383
- **Important**: Batch handlers (handlers that accept an array of messages) MUST include
384
- batchSize configuration. You cannot create a batch handler without specifying batchSize.
385
-
386
398
  ##### Type Parameters
387
399
 
388
400
  | Type Parameter | Description |
@@ -396,49 +408,42 @@ batchSize configuration. You cannot create a batch handler without specifying ba
396
408
  | ------ | ------ | ------ |
397
409
  | `contract` | `TContract` | The contract definition containing the consumer |
398
410
  | `consumerName` | `TName` | The name of the consumer from the contract |
399
- | `handler` | `WorkerInferConsumerHandler`\<`TContract`, `TName`\> | The async handler function that processes messages (single or batch) |
411
+ | `handler` | `WorkerInferSafeConsumerHandler`\<`TContract`, `TName`\> | The handler function that returns `Future<Result<void, HandlerError>>` |
400
412
 
401
413
  ##### Returns
402
414
 
403
- `WorkerInferConsumerHandlerEntry`\<`TContract`, `TName`\>
415
+ `WorkerInferSafeConsumerHandlerEntry`\<`TContract`, `TName`\>
404
416
 
405
417
  A type-safe handler that can be used with TypedAmqpWorker
406
418
 
407
419
  ##### Example
408
420
 
409
421
  ```typescript
410
- import { defineHandler } from '@amqp-contract/worker';
422
+ import { defineHandler, RetryableError, NonRetryableError } from '@amqp-contract/worker';
423
+ import { Future, Result } from '@swan-io/boxed';
411
424
  import { orderContract } from './contract';
412
425
 
413
- // Simple single-message handler without options
426
+ // Simple handler with explicit error handling using mapError
414
427
  const processOrderHandler = defineHandler(
415
428
  orderContract,
416
429
  'processOrder',
417
- async (message) => {
418
- console.log('Processing order:', message.orderId);
419
- await processPayment(message);
420
- }
421
- );
422
-
423
- // Single-message handler with prefetch
424
- const processOrderWithPrefetch = defineHandler(
425
- orderContract,
426
- 'processOrder',
427
- async (message) => {
428
- await processOrder(message);
429
- },
430
- { prefetch: 10 }
430
+ (message) =>
431
+ Future.fromPromise(processPayment(message))
432
+ .mapOk(() => undefined)
433
+ .mapError((error) => new RetryableError('Payment failed', error))
431
434
  );
432
435
 
433
- // Batch handler - MUST include batchSize
434
- const processBatchOrders = defineHandler(
436
+ // Handler with validation (non-retryable error)
437
+ const validateOrderHandler = defineHandler(
435
438
  orderContract,
436
- 'processOrders',
437
- async (messages) => {
438
- // messages is an array - batchSize configuration is REQUIRED
439
- await db.insertMany(messages);
440
- },
441
- { batchSize: 5, batchTimeout: 1000 }
439
+ 'validateOrder',
440
+ (message) => {
441
+ if (message.amount < 1) {
442
+ // Won't be retried - goes directly to DLQ
443
+ return Future.value(Result.Error(new NonRetryableError('Invalid order amount')));
444
+ }
445
+ return Future.value(Result.Ok(undefined));
446
+ }
442
447
  );
443
448
  ```
444
449
 
@@ -449,24 +454,21 @@ function defineHandler<TContract, TName>(
449
454
  contract,
450
455
  consumerName,
451
456
  handler,
452
- options): WorkerInferConsumerHandlerEntry<TContract, TName>;
457
+ options): WorkerInferSafeConsumerHandlerEntry<TContract, TName>;
453
458
  ```
454
459
 
455
- Defined in: worker/dist/index.d.mts:325
460
+ Defined in: worker/dist/index.d.mts:512
456
461
 
457
462
  Define a type-safe handler for a specific consumer in a contract.
458
463
 
459
- This utility allows you to define handlers outside of the worker creation,
460
- providing better code organization and reusability.
464
+ **Recommended:** This function creates handlers that return `Future<Result<void, HandlerError>>`,
465
+ providing explicit error handling and better control over retry behavior.
461
466
 
462
467
  Supports three patterns:
463
468
  1. Simple handler: just the function (single message handler)
464
469
  2. Handler with prefetch: [handler, { prefetch: 10 }] (single message handler with config)
465
470
  3. Batch handler: [batchHandler, { batchSize: 5, batchTimeout: 1000 }] (REQUIRES batchSize config)
466
471
 
467
- **Important**: Batch handlers (handlers that accept an array of messages) MUST include
468
- batchSize configuration. You cannot create a batch handler without specifying batchSize.
469
-
470
472
  ##### Type Parameters
471
473
 
472
474
  | Type Parameter | Description |
@@ -480,53 +482,46 @@ batchSize configuration. You cannot create a batch handler without specifying ba
480
482
  | ------ | ------ | ------ |
481
483
  | `contract` | `TContract` | The contract definition containing the consumer |
482
484
  | `consumerName` | `TName` | The name of the consumer from the contract |
483
- | `handler` | `WorkerInferConsumerHandler`\<`TContract`, `TName`\> | The async handler function that processes messages (single or batch) |
484
- | `options` | \{ `batchSize?`: `undefined`; `batchTimeout?`: `undefined`; `prefetch?`: `number`; \} | Optional consumer options (prefetch, batchSize, batchTimeout) - For single-message handlers: { prefetch?: number } is optional - For batch handlers: { batchSize: number, batchTimeout?: number } is REQUIRED |
485
+ | `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) |
485
487
  | `options.batchSize?` | `undefined` | - |
486
488
  | `options.batchTimeout?` | `undefined` | - |
487
489
  | `options.prefetch?` | `number` | - |
488
490
 
489
491
  ##### Returns
490
492
 
491
- `WorkerInferConsumerHandlerEntry`\<`TContract`, `TName`\>
493
+ `WorkerInferSafeConsumerHandlerEntry`\<`TContract`, `TName`\>
492
494
 
493
495
  A type-safe handler that can be used with TypedAmqpWorker
494
496
 
495
497
  ##### Example
496
498
 
497
499
  ```typescript
498
- import { defineHandler } from '@amqp-contract/worker';
500
+ import { defineHandler, RetryableError, NonRetryableError } from '@amqp-contract/worker';
501
+ import { Future, Result } from '@swan-io/boxed';
499
502
  import { orderContract } from './contract';
500
503
 
501
- // Simple single-message handler without options
504
+ // Simple handler with explicit error handling using mapError
502
505
  const processOrderHandler = defineHandler(
503
506
  orderContract,
504
507
  'processOrder',
505
- async (message) => {
506
- console.log('Processing order:', message.orderId);
507
- await processPayment(message);
508
- }
509
- );
510
-
511
- // Single-message handler with prefetch
512
- const processOrderWithPrefetch = defineHandler(
513
- orderContract,
514
- 'processOrder',
515
- async (message) => {
516
- await processOrder(message);
517
- },
518
- { prefetch: 10 }
508
+ (message) =>
509
+ Future.fromPromise(processPayment(message))
510
+ .mapOk(() => undefined)
511
+ .mapError((error) => new RetryableError('Payment failed', error))
519
512
  );
520
513
 
521
- // Batch handler - MUST include batchSize
522
- const processBatchOrders = defineHandler(
514
+ // Handler with validation (non-retryable error)
515
+ const validateOrderHandler = defineHandler(
523
516
  orderContract,
524
- 'processOrders',
525
- async (messages) => {
526
- // messages is an array - batchSize configuration is REQUIRED
527
- await db.insertMany(messages);
528
- },
529
- { batchSize: 5, batchTimeout: 1000 }
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
+ }
530
525
  );
531
526
  ```
532
527
 
@@ -537,24 +532,21 @@ function defineHandler<TContract, TName>(
537
532
  contract,
538
533
  consumerName,
539
534
  handler,
540
- options): WorkerInferConsumerHandlerEntry<TContract, TName>;
535
+ options): WorkerInferSafeConsumerHandlerEntry<TContract, TName>;
541
536
  ```
542
537
 
543
- Defined in: worker/dist/index.d.mts:330
538
+ Defined in: worker/dist/index.d.mts:517
544
539
 
545
540
  Define a type-safe handler for a specific consumer in a contract.
546
541
 
547
- This utility allows you to define handlers outside of the worker creation,
548
- providing better code organization and reusability.
542
+ **Recommended:** This function creates handlers that return `Future<Result<void, HandlerError>>`,
543
+ providing explicit error handling and better control over retry behavior.
549
544
 
550
545
  Supports three patterns:
551
546
  1. Simple handler: just the function (single message handler)
552
547
  2. Handler with prefetch: [handler, { prefetch: 10 }] (single message handler with config)
553
548
  3. Batch handler: [batchHandler, { batchSize: 5, batchTimeout: 1000 }] (REQUIRES batchSize config)
554
549
 
555
- **Important**: Batch handlers (handlers that accept an array of messages) MUST include
556
- batchSize configuration. You cannot create a batch handler without specifying batchSize.
557
-
558
550
  ##### Type Parameters
559
551
 
560
552
  | Type Parameter | Description |
@@ -568,53 +560,46 @@ batchSize configuration. You cannot create a batch handler without specifying ba
568
560
  | ------ | ------ | ------ |
569
561
  | `contract` | `TContract` | The contract definition containing the consumer |
570
562
  | `consumerName` | `TName` | The name of the consumer from the contract |
571
- | `handler` | `WorkerInferConsumerBatchHandler`\<`TContract`, `TName`\> | The async handler function that processes messages (single or batch) |
572
- | `options` | \{ `batchSize`: `number`; `batchTimeout?`: `number`; `prefetch?`: `number`; \} | Optional consumer options (prefetch, batchSize, batchTimeout) - For single-message handlers: { prefetch?: number } is optional - For batch handlers: { batchSize: number, batchTimeout?: number } is REQUIRED |
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) |
573
565
  | `options.batchSize` | `number` | - |
574
566
  | `options.batchTimeout?` | `number` | - |
575
567
  | `options.prefetch?` | `number` | - |
576
568
 
577
569
  ##### Returns
578
570
 
579
- `WorkerInferConsumerHandlerEntry`\<`TContract`, `TName`\>
571
+ `WorkerInferSafeConsumerHandlerEntry`\<`TContract`, `TName`\>
580
572
 
581
573
  A type-safe handler that can be used with TypedAmqpWorker
582
574
 
583
575
  ##### Example
584
576
 
585
577
  ```typescript
586
- import { defineHandler } from '@amqp-contract/worker';
578
+ import { defineHandler, RetryableError, NonRetryableError } from '@amqp-contract/worker';
579
+ import { Future, Result } from '@swan-io/boxed';
587
580
  import { orderContract } from './contract';
588
581
 
589
- // Simple single-message handler without options
582
+ // Simple handler with explicit error handling using mapError
590
583
  const processOrderHandler = defineHandler(
591
584
  orderContract,
592
585
  'processOrder',
593
- async (message) => {
594
- console.log('Processing order:', message.orderId);
595
- await processPayment(message);
596
- }
586
+ (message) =>
587
+ Future.fromPromise(processPayment(message))
588
+ .mapOk(() => undefined)
589
+ .mapError((error) => new RetryableError('Payment failed', error))
597
590
  );
598
591
 
599
- // Single-message handler with prefetch
600
- const processOrderWithPrefetch = defineHandler(
592
+ // Handler with validation (non-retryable error)
593
+ const validateOrderHandler = defineHandler(
601
594
  orderContract,
602
- 'processOrder',
603
- async (message) => {
604
- await processOrder(message);
605
- },
606
- { prefetch: 10 }
607
- );
608
-
609
- // Batch handler - MUST include batchSize
610
- const processBatchOrders = defineHandler(
611
- orderContract,
612
- 'processOrders',
613
- async (messages) => {
614
- // messages is an array - batchSize configuration is REQUIRED
615
- await db.insertMany(messages);
616
- },
617
- { batchSize: 5, batchTimeout: 1000 }
595
+ 'validateOrder',
596
+ (message) => {
597
+ if (message.amount < 1) {
598
+ // Won't be retried - goes directly to DLQ
599
+ return Future.value(Result.Error(new NonRetryableError('Invalid order amount')));
600
+ }
601
+ return Future.value(Result.Ok(undefined));
602
+ }
618
603
  );
619
604
  ```
620
605
 
@@ -623,15 +608,15 @@ const processBatchOrders = defineHandler(
623
608
  ### defineHandlers()
624
609
 
625
610
  ```ts
626
- function defineHandlers<TContract>(contract, handlers): WorkerInferConsumerHandlers<TContract>;
611
+ function defineHandlers<TContract>(contract, handlers): WorkerInferSafeConsumerHandlers<TContract>;
627
612
  ```
628
613
 
629
- Defined in: worker/dist/index.d.mts:391
614
+ Defined in: worker/dist/index.d.mts:551
630
615
 
631
616
  Define multiple type-safe handlers for consumers in a contract.
632
617
 
633
- This utility allows you to define all handlers at once outside of the worker creation,
634
- ensuring type safety and providing better code organization.
618
+ **Recommended:** This function creates handlers that return `Future<Result<void, HandlerError>>`,
619
+ providing explicit error handling and better control over retry behavior.
635
620
 
636
621
  #### Type Parameters
637
622
 
@@ -644,55 +629,29 @@ ensuring type safety and providing better code organization.
644
629
  | Parameter | Type | Description |
645
630
  | ------ | ------ | ------ |
646
631
  | `contract` | `TContract` | The contract definition containing the consumers |
647
- | `handlers` | [`WorkerInferConsumerHandlers`](#workerinferconsumerhandlers)\<`TContract`\> | An object with async handler functions for each consumer |
632
+ | `handlers` | `WorkerInferSafeConsumerHandlers`\<`TContract`\> | An object with handler functions for each consumer |
648
633
 
649
634
  #### Returns
650
635
 
651
- [`WorkerInferConsumerHandlers`](#workerinferconsumerhandlers)\<`TContract`\>
636
+ `WorkerInferSafeConsumerHandlers`\<`TContract`\>
652
637
 
653
638
  A type-safe handlers object that can be used with TypedAmqpWorker
654
639
 
655
- #### Examples
640
+ #### Example
656
641
 
657
642
  ```typescript
658
- import { defineHandlers } from '@amqp-contract/worker';
643
+ import { defineHandlers, RetryableError } from '@amqp-contract/worker';
644
+ import { Future } from '@swan-io/boxed';
659
645
  import { orderContract } from './contract';
660
646
 
661
- // Define all handlers at once
662
- const handlers = defineHandlers(orderContract, {
663
- processOrder: async (message) => {
664
- // message is fully typed based on the contract
665
- console.log('Processing order:', message.orderId);
666
- await processPayment(message);
667
- },
668
- notifyOrder: async (message) => {
669
- await sendNotification(message);
670
- },
671
- shipOrder: async (message) => {
672
- await prepareShipment(message);
673
- },
674
- });
675
-
676
- // Use the handlers in worker
677
- const worker = await TypedAmqpWorker.create({
678
- contract: orderContract,
679
- handlers,
680
- connection: 'amqp://localhost',
681
- });
682
- ```
683
-
684
- ```typescript
685
- // Separate handler definitions for better organization
686
- async function handleProcessOrder(message: WorkerInferConsumerInput<typeof orderContract, 'processOrder'>) {
687
- await processOrder(message);
688
- }
689
-
690
- async function handleNotifyOrder(message: WorkerInferConsumerInput<typeof orderContract, 'notifyOrder'>) {
691
- await sendNotification(message);
692
- }
693
-
694
647
  const handlers = defineHandlers(orderContract, {
695
- processOrder: handleProcessOrder,
696
- notifyOrder: handleNotifyOrder,
648
+ processOrder: (message) =>
649
+ Future.fromPromise(processPayment(message))
650
+ .mapOk(() => undefined)
651
+ .mapError((error) => new RetryableError('Payment failed', error)),
652
+ notifyOrder: (message) =>
653
+ Future.fromPromise(sendNotification(message))
654
+ .mapOk(() => undefined)
655
+ .mapError((error) => new RetryableError('Notification failed', error)),
697
656
  });
698
657
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amqp-contract/worker-nestjs",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "NestJS integration for @amqp-contract/worker",
5
5
  "keywords": [
6
6
  "amqp",
@@ -52,29 +52,29 @@
52
52
  "docs"
53
53
  ],
54
54
  "dependencies": {
55
- "@amqp-contract/contract": "0.7.0",
56
- "@amqp-contract/worker": "0.7.0"
55
+ "@amqp-contract/contract": "0.9.0",
56
+ "@amqp-contract/worker": "0.9.0"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@nestjs/common": "11.1.11",
60
60
  "@nestjs/core": "11.1.11",
61
61
  "@nestjs/testing": "11.1.11",
62
62
  "@swan-io/boxed": "3.2.1",
63
- "@types/node": "25.0.3",
63
+ "@types/node": "25.0.5",
64
64
  "@vitest/coverage-v8": "4.0.16",
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
- "tsdown": "0.18.4",
69
+ "tsdown": "0.19.0",
70
70
  "typedoc": "0.28.15",
71
71
  "typedoc-plugin-markdown": "4.9.0",
72
72
  "typescript": "5.9.3",
73
73
  "vitest": "4.0.16",
74
74
  "zod": "4.3.5",
75
- "@amqp-contract/testing": "0.7.0",
76
- "@amqp-contract/tsconfig": "0.0.0",
77
- "@amqp-contract/typedoc": "0.0.1"
75
+ "@amqp-contract/testing": "0.9.0",
76
+ "@amqp-contract/tsconfig": "0.1.0",
77
+ "@amqp-contract/typedoc": "0.1.0"
78
78
  },
79
79
  "peerDependencies": {
80
80
  "@nestjs/common": "^11.0.0",