@amqp-contract/worker 0.23.0 → 0.24.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 +41 -36
- package/dist/index.cjs +125 -120
- package/dist/index.d.cts +69 -64
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +69 -64
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +125 -120
- package/dist/index.mjs.map +1 -1
- package/docs/index.md +109 -102
- package/package.json +7 -7
package/docs/index.md
CHANGED
|
@@ -170,7 +170,7 @@ Error.prepareStackTrace
|
|
|
170
170
|
|
|
171
171
|
### NonRetryableError
|
|
172
172
|
|
|
173
|
-
Defined in: [packages/worker/src/errors.ts:34](https://github.com/btravers/amqp-contract/blob/
|
|
173
|
+
Defined in: [packages/worker/src/errors.ts:34](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/errors.ts#L34)
|
|
174
174
|
|
|
175
175
|
Non-retryable errors - permanent failures that should not be retried
|
|
176
176
|
Examples: invalid data, business rule violations, permanent external failures
|
|
@@ -190,7 +190,7 @@ immediately sent to the dead letter queue (DLQ) if configured.
|
|
|
190
190
|
new NonRetryableError(message, cause?): NonRetryableError;
|
|
191
191
|
```
|
|
192
192
|
|
|
193
|
-
Defined in: [packages/worker/src/errors.ts:35](https://github.com/btravers/amqp-contract/blob/
|
|
193
|
+
Defined in: [packages/worker/src/errors.ts:35](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/errors.ts#L35)
|
|
194
194
|
|
|
195
195
|
###### Parameters
|
|
196
196
|
|
|
@@ -213,7 +213,7 @@ Error.constructor
|
|
|
213
213
|
|
|
214
214
|
| Property | Modifier | Type | Description | Inherited from | Defined in |
|
|
215
215
|
| ------ | ------ | ------ | ------ | ------ | ------ |
|
|
216
|
-
| <a id="cause-1"></a> `cause?` | `readonly` | `unknown` | - | `Error.cause` | [packages/worker/src/errors.ts:37](https://github.com/btravers/amqp-contract/blob/
|
|
216
|
+
| <a id="cause-1"></a> `cause?` | `readonly` | `unknown` | - | `Error.cause` | [packages/worker/src/errors.ts:37](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/errors.ts#L37) |
|
|
217
217
|
| <a id="message-1"></a> `message` | `public` | `string` | - | `Error.message` | node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1075 |
|
|
218
218
|
| <a id="name-1"></a> `name` | `public` | `string` | - | `Error.name` | node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1074 |
|
|
219
219
|
| <a id="stack-1"></a> `stack?` | `public` | `string` | - | `Error.stack` | node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1076 |
|
|
@@ -323,7 +323,7 @@ Error.prepareStackTrace
|
|
|
323
323
|
|
|
324
324
|
### RetryableError
|
|
325
325
|
|
|
326
|
-
Defined in: [packages/worker/src/errors.ts:10](https://github.com/btravers/amqp-contract/blob/
|
|
326
|
+
Defined in: [packages/worker/src/errors.ts:10](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/errors.ts#L10)
|
|
327
327
|
|
|
328
328
|
Retryable errors - transient failures that may succeed on retry
|
|
329
329
|
Examples: network timeouts, rate limiting, temporary service unavailability
|
|
@@ -343,7 +343,7 @@ The worker will apply exponential backoff and retry the message.
|
|
|
343
343
|
new RetryableError(message, cause?): RetryableError;
|
|
344
344
|
```
|
|
345
345
|
|
|
346
|
-
Defined in: [packages/worker/src/errors.ts:11](https://github.com/btravers/amqp-contract/blob/
|
|
346
|
+
Defined in: [packages/worker/src/errors.ts:11](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/errors.ts#L11)
|
|
347
347
|
|
|
348
348
|
###### Parameters
|
|
349
349
|
|
|
@@ -366,7 +366,7 @@ Error.constructor
|
|
|
366
366
|
|
|
367
367
|
| Property | Modifier | Type | Description | Inherited from | Defined in |
|
|
368
368
|
| ------ | ------ | ------ | ------ | ------ | ------ |
|
|
369
|
-
| <a id="cause-2"></a> `cause?` | `readonly` | `unknown` | - | `Error.cause` | [packages/worker/src/errors.ts:13](https://github.com/btravers/amqp-contract/blob/
|
|
369
|
+
| <a id="cause-2"></a> `cause?` | `readonly` | `unknown` | - | `Error.cause` | [packages/worker/src/errors.ts:13](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/errors.ts#L13) |
|
|
370
370
|
| <a id="message-2"></a> `message` | `public` | `string` | - | `Error.message` | node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1075 |
|
|
371
371
|
| <a id="name-2"></a> `name` | `public` | `string` | - | `Error.name` | node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1074 |
|
|
372
372
|
| <a id="stack-2"></a> `stack?` | `public` | `string` | - | `Error.stack` | node\_modules/.pnpm/typescript@6.0.3/node\_modules/typescript/lib/lib.es5.d.ts:1076 |
|
|
@@ -476,7 +476,7 @@ Error.prepareStackTrace
|
|
|
476
476
|
|
|
477
477
|
### TypedAmqpWorker
|
|
478
478
|
|
|
479
|
-
Defined in: [packages/worker/src/worker.ts:
|
|
479
|
+
Defined in: [packages/worker/src/worker.ts:181](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/worker.ts#L181)
|
|
480
480
|
|
|
481
481
|
Type-safe AMQP worker for consuming messages from RabbitMQ.
|
|
482
482
|
|
|
@@ -488,6 +488,7 @@ and error handling for consuming messages based on a contract definition.
|
|
|
488
488
|
```typescript
|
|
489
489
|
import { TypedAmqpWorker } from '@amqp-contract/worker';
|
|
490
490
|
import { defineQueue, defineMessage, defineContract, defineConsumer } from '@amqp-contract/contract';
|
|
491
|
+
import { okAsync } from 'neverthrow';
|
|
491
492
|
import { z } from 'zod';
|
|
492
493
|
|
|
493
494
|
const orderQueue = defineQueue('order-processing');
|
|
@@ -502,19 +503,22 @@ const contract = defineContract({
|
|
|
502
503
|
}
|
|
503
504
|
});
|
|
504
505
|
|
|
505
|
-
const
|
|
506
|
+
const result = await TypedAmqpWorker.create({
|
|
506
507
|
contract,
|
|
507
508
|
handlers: {
|
|
508
|
-
processOrder:
|
|
509
|
-
console.log('Processing order',
|
|
510
|
-
|
|
511
|
-
}
|
|
509
|
+
processOrder: ({ payload }) => {
|
|
510
|
+
console.log('Processing order', payload.orderId);
|
|
511
|
+
return okAsync(undefined);
|
|
512
|
+
},
|
|
512
513
|
},
|
|
513
|
-
urls: ['amqp://localhost']
|
|
514
|
-
})
|
|
514
|
+
urls: ['amqp://localhost'],
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
if (result.isErr()) throw result.error;
|
|
518
|
+
const worker = result.value;
|
|
515
519
|
|
|
516
520
|
// Close when done
|
|
517
|
-
await worker.close()
|
|
521
|
+
await worker.close();
|
|
518
522
|
```
|
|
519
523
|
|
|
520
524
|
#### Type Parameters
|
|
@@ -528,10 +532,10 @@ await worker.close().resultToPromise();
|
|
|
528
532
|
##### close()
|
|
529
533
|
|
|
530
534
|
```ts
|
|
531
|
-
close():
|
|
535
|
+
close(): ResultAsync<void, TechnicalError>;
|
|
532
536
|
```
|
|
533
537
|
|
|
534
|
-
Defined in: [packages/worker/src/worker.ts:
|
|
538
|
+
Defined in: [packages/worker/src/worker.ts:341](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/worker.ts#L341)
|
|
535
539
|
|
|
536
540
|
Close the AMQP channel and connection.
|
|
537
541
|
|
|
@@ -540,14 +544,12 @@ stopping all message consumption and cleaning up resources.
|
|
|
540
544
|
|
|
541
545
|
###### Returns
|
|
542
546
|
|
|
543
|
-
`
|
|
544
|
-
|
|
545
|
-
A Future that resolves to a Result indicating success or failure
|
|
547
|
+
`ResultAsync`<`void`, `TechnicalError`>
|
|
546
548
|
|
|
547
549
|
###### Example
|
|
548
550
|
|
|
549
551
|
```typescript
|
|
550
|
-
const closeResult = await worker.close()
|
|
552
|
+
const closeResult = await worker.close();
|
|
551
553
|
if (closeResult.isOk()) {
|
|
552
554
|
console.log('Worker closed successfully');
|
|
553
555
|
}
|
|
@@ -556,10 +558,10 @@ if (closeResult.isOk()) {
|
|
|
556
558
|
##### create()
|
|
557
559
|
|
|
558
560
|
```ts
|
|
559
|
-
static create<TContract>(
|
|
561
|
+
static create<TContract>(__namedParameters): ResultAsync<TypedAmqpWorker<TContract>, TechnicalError>;
|
|
560
562
|
```
|
|
561
563
|
|
|
562
|
-
Defined in: [packages/worker/src/worker.ts:
|
|
564
|
+
Defined in: [packages/worker/src/worker.ts:280](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/worker.ts#L280)
|
|
563
565
|
|
|
564
566
|
Create a type-safe AMQP worker from a contract.
|
|
565
567
|
|
|
@@ -579,26 +581,26 @@ URLs and connection options, following RabbitMQ best practices.
|
|
|
579
581
|
|
|
580
582
|
###### Parameters
|
|
581
583
|
|
|
582
|
-
| Parameter | Type |
|
|
583
|
-
| ------ | ------ |
|
|
584
|
-
| `
|
|
584
|
+
| Parameter | Type |
|
|
585
|
+
| ------ | ------ |
|
|
586
|
+
| `__namedParameters` | [`CreateWorkerOptions`](#createworkeroptions)<`TContract`> |
|
|
585
587
|
|
|
586
588
|
###### Returns
|
|
587
589
|
|
|
588
|
-
`
|
|
590
|
+
`ResultAsync`<[`TypedAmqpWorker`](#typedamqpworker)<`TContract`>, `TechnicalError`>
|
|
589
591
|
|
|
590
|
-
A
|
|
592
|
+
A ResultAsync that resolves to the worker or a TechnicalError.
|
|
591
593
|
|
|
592
594
|
###### Example
|
|
593
595
|
|
|
594
596
|
```typescript
|
|
595
|
-
const
|
|
597
|
+
const result = await TypedAmqpWorker.create({
|
|
596
598
|
contract: myContract,
|
|
597
599
|
handlers: {
|
|
598
|
-
processOrder:
|
|
600
|
+
processOrder: ({ payload }) => okAsync(undefined),
|
|
599
601
|
},
|
|
600
|
-
urls: ['amqp://localhost']
|
|
601
|
-
})
|
|
602
|
+
urls: ['amqp://localhost'],
|
|
603
|
+
});
|
|
602
604
|
```
|
|
603
605
|
|
|
604
606
|
## Type Aliases
|
|
@@ -609,7 +611,7 @@ const worker = await TypedAmqpWorker.create({
|
|
|
609
611
|
type ConsumerOptions = AmqpClientConsumerOptions;
|
|
610
612
|
```
|
|
611
613
|
|
|
612
|
-
Defined in: [packages/worker/src/worker.ts:49](https://github.com/btravers/amqp-contract/blob/
|
|
614
|
+
Defined in: [packages/worker/src/worker.ts:49](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/worker.ts#L49)
|
|
613
615
|
|
|
614
616
|
***
|
|
615
617
|
|
|
@@ -619,7 +621,7 @@ Defined in: [packages/worker/src/worker.ts:49](https://github.com/btravers/amqp-
|
|
|
619
621
|
type CreateWorkerOptions<TContract> = object;
|
|
620
622
|
```
|
|
621
623
|
|
|
622
|
-
Defined in: [packages/worker/src/worker.ts:96](https://github.com/btravers/amqp-contract/blob/
|
|
624
|
+
Defined in: [packages/worker/src/worker.ts:96](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/worker.ts#L96)
|
|
623
625
|
|
|
624
626
|
Options for creating a type-safe AMQP worker.
|
|
625
627
|
|
|
@@ -632,13 +634,13 @@ const options: CreateWorkerOptions<typeof contract> = {
|
|
|
632
634
|
// Simple handler
|
|
633
635
|
processOrder: ({ payload }) => {
|
|
634
636
|
console.log('Processing order:', payload.orderId);
|
|
635
|
-
return
|
|
637
|
+
return okAsync(undefined);
|
|
636
638
|
},
|
|
637
639
|
// Handler with prefetch configuration
|
|
638
640
|
processPayment: [
|
|
639
641
|
({ payload }) => {
|
|
640
642
|
console.log('Processing payment:', payload.paymentId);
|
|
641
|
-
return
|
|
643
|
+
return okAsync(undefined);
|
|
642
644
|
},
|
|
643
645
|
{ prefetch: 10 }
|
|
644
646
|
]
|
|
@@ -667,14 +669,14 @@ not at the handler level. See `QueueDefinition.retry` for configuration options.
|
|
|
667
669
|
|
|
668
670
|
| Property | Type | Description | Defined in |
|
|
669
671
|
| ------ | ------ | ------ | ------ |
|
|
670
|
-
| <a id="connectionoptions"></a> `connectionOptions?` | `AmqpConnectionManagerOptions` | Optional connection configuration (heartbeat, reconnect settings, etc.) | [packages/worker/src/worker.ts:113](https://github.com/btravers/amqp-contract/blob/
|
|
671
|
-
| <a id="connecttimeoutms"></a> `connectTimeoutMs?` | `number` \| `null` | Maximum time in ms to wait for the AMQP connection to become ready before `create()` resolves to `
|
|
672
|
-
| <a id="contract"></a> `contract` | `TContract` | The AMQP contract definition specifying consumers and their message schemas | [packages/worker/src/worker.ts:98](https://github.com/btravers/amqp-contract/blob/
|
|
673
|
-
| <a id="defaultconsumeroptions"></a> `defaultConsumerOptions?` | [`ConsumerOptions`](#consumeroptions) | Optional default consumer options applied to all consumer handlers. Handler-specific options provided in tuple form override these defaults. | [packages/worker/src/worker.ts:126](https://github.com/btravers/amqp-contract/blob/
|
|
674
|
-
| <a id="handlers"></a> `handlers` | `WorkerInferHandlers`<`TContract`> | Handlers for each `consumers` and `rpcs` entry in the contract. - Regular consumers return `
|
|
675
|
-
| <a id="logger"></a> `logger?` | `Logger` | Optional logger for logging message consumption and errors | [packages/worker/src/worker.ts:115](https://github.com/btravers/amqp-contract/blob/
|
|
676
|
-
| <a id="telemetry"></a> `telemetry?` | `TelemetryProvider` | Optional telemetry provider for tracing and metrics. If not provided, uses the default provider which attempts to load OpenTelemetry. OpenTelemetry instrumentation is automatically enabled if @opentelemetry/api is installed. | [packages/worker/src/worker.ts:121](https://github.com/btravers/amqp-contract/blob/
|
|
677
|
-
| <a id="urls"></a> `urls` | `ConnectionUrl`[] | AMQP broker URL(s). Multiple URLs provide failover support | [packages/worker/src/worker.ts:111](https://github.com/btravers/amqp-contract/blob/
|
|
672
|
+
| <a id="connectionoptions"></a> `connectionOptions?` | `AmqpConnectionManagerOptions` | Optional connection configuration (heartbeat, reconnect settings, etc.) | [packages/worker/src/worker.ts:113](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/worker.ts#L113) |
|
|
673
|
+
| <a id="connecttimeoutms"></a> `connectTimeoutMs?` | `number` \| `null` | Maximum time in ms to wait for the AMQP connection to become ready before `create()` resolves to an `err(TechnicalError)`. Defaults to 30s (the [AmqpClient](https://btravers.github.io/amqp-contract/api/core#amqpclient)'s `DEFAULT_CONNECT_TIMEOUT_MS`). Pass `null` to disable the timeout and let amqp-connection-manager retry indefinitely. | [packages/worker/src/worker.ts:133](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/worker.ts#L133) |
|
|
674
|
+
| <a id="contract"></a> `contract` | `TContract` | The AMQP contract definition specifying consumers and their message schemas | [packages/worker/src/worker.ts:98](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/worker.ts#L98) |
|
|
675
|
+
| <a id="defaultconsumeroptions"></a> `defaultConsumerOptions?` | [`ConsumerOptions`](#consumeroptions) | Optional default consumer options applied to all consumer handlers. Handler-specific options provided in tuple form override these defaults. | [packages/worker/src/worker.ts:126](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/worker.ts#L126) |
|
|
676
|
+
| <a id="handlers"></a> `handlers` | `WorkerInferHandlers`<`TContract`> | Handlers for each `consumers` and `rpcs` entry in the contract. - Regular consumers return `ResultAsync<void, HandlerError>`. - RPC handlers return `ResultAsync<TResponse, HandlerError>` where `TResponse` is inferred from the RPC's response message schema. Use `defineHandler` / `defineHandlers` to create handlers with full type inference. | [packages/worker/src/worker.ts:109](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/worker.ts#L109) |
|
|
677
|
+
| <a id="logger"></a> `logger?` | `Logger` | Optional logger for logging message consumption and errors | [packages/worker/src/worker.ts:115](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/worker.ts#L115) |
|
|
678
|
+
| <a id="telemetry"></a> `telemetry?` | `TelemetryProvider` | Optional telemetry provider for tracing and metrics. If not provided, uses the default provider which attempts to load OpenTelemetry. OpenTelemetry instrumentation is automatically enabled if @opentelemetry/api is installed. | [packages/worker/src/worker.ts:121](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/worker.ts#L121) |
|
|
679
|
+
| <a id="urls"></a> `urls` | `ConnectionUrl`[] | AMQP broker URL(s). Multiple URLs provide failover support | [packages/worker/src/worker.ts:111](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/worker.ts#L111) |
|
|
678
680
|
|
|
679
681
|
***
|
|
680
682
|
|
|
@@ -686,7 +688,7 @@ type HandlerError =
|
|
|
686
688
|
| NonRetryableError;
|
|
687
689
|
```
|
|
688
690
|
|
|
689
|
-
Defined in: [packages/worker/src/errors.ts:55](https://github.com/btravers/amqp-contract/blob/
|
|
691
|
+
Defined in: [packages/worker/src/errors.ts:55](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/errors.ts#L55)
|
|
690
692
|
|
|
691
693
|
Union type representing all handler errors.
|
|
692
694
|
Use this type when defining handlers that explicitly signal error outcomes.
|
|
@@ -699,7 +701,7 @@ Use this type when defining handlers that explicitly signal error outcomes.
|
|
|
699
701
|
type WorkerConsumedMessage<TPayload, THeaders> = object;
|
|
700
702
|
```
|
|
701
703
|
|
|
702
|
-
Defined in: [packages/worker/src/types.ts:156](https://github.com/btravers/amqp-contract/blob/
|
|
704
|
+
Defined in: [packages/worker/src/types.ts:156](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/types.ts#L156)
|
|
703
705
|
|
|
704
706
|
A consumed message containing parsed payload and headers.
|
|
705
707
|
|
|
@@ -713,7 +715,7 @@ const handler = defineHandler(contract, 'processOrder', (message, rawMessage) =>
|
|
|
713
715
|
console.log(message.payload.orderId); // Typed payload
|
|
714
716
|
console.log(message.headers?.priority); // Typed headers (if defined)
|
|
715
717
|
console.log(rawMessage.fields.deliveryTag); // Raw AMQP message
|
|
716
|
-
return
|
|
718
|
+
return okAsync(undefined);
|
|
717
719
|
});
|
|
718
720
|
```
|
|
719
721
|
|
|
@@ -728,8 +730,8 @@ const handler = defineHandler(contract, 'processOrder', (message, rawMessage) =>
|
|
|
728
730
|
|
|
729
731
|
| Property | Type | Description | Defined in |
|
|
730
732
|
| ------ | ------ | ------ | ------ |
|
|
731
|
-
| <a id="headers"></a> `headers` | `THeaders` *extends* `undefined` ? `undefined` : `THeaders` | The validated message headers (present only when headers schema is defined) | [packages/worker/src/types.ts:160](https://github.com/btravers/amqp-contract/blob/
|
|
732
|
-
| <a id="payload"></a> `payload` | `TPayload` | The validated message payload | [packages/worker/src/types.ts:158](https://github.com/btravers/amqp-contract/blob/
|
|
733
|
+
| <a id="headers"></a> `headers` | `THeaders` *extends* `undefined` ? `undefined` : `THeaders` | The validated message headers (present only when headers schema is defined) | [packages/worker/src/types.ts:160](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/types.ts#L160) |
|
|
734
|
+
| <a id="payload"></a> `payload` | `TPayload` | The validated message payload | [packages/worker/src/types.ts:158](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/types.ts#L158) |
|
|
733
735
|
|
|
734
736
|
***
|
|
735
737
|
|
|
@@ -739,7 +741,7 @@ const handler = defineHandler(contract, 'processOrder', (message, rawMessage) =>
|
|
|
739
741
|
type WorkerInferConsumedMessage<TContract, TName> = WorkerConsumedMessage<WorkerInferConsumerPayload<TContract, TName>, WorkerInferConsumerHeaders<TContract, TName>>;
|
|
740
742
|
```
|
|
741
743
|
|
|
742
|
-
Defined in: [packages/worker/src/types.ts:166](https://github.com/btravers/amqp-contract/blob/
|
|
744
|
+
Defined in: [packages/worker/src/types.ts:166](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/types.ts#L166)
|
|
743
745
|
|
|
744
746
|
Infer the full consumed message type for a regular consumer.
|
|
745
747
|
|
|
@@ -755,13 +757,13 @@ Infer the full consumed message type for a regular consumer.
|
|
|
755
757
|
### WorkerInferConsumerHandler
|
|
756
758
|
|
|
757
759
|
```ts
|
|
758
|
-
type WorkerInferConsumerHandler<TContract, TName> = (message, rawMessage) =>
|
|
760
|
+
type WorkerInferConsumerHandler<TContract, TName> = (message, rawMessage) => ResultAsync<void, HandlerError>;
|
|
759
761
|
```
|
|
760
762
|
|
|
761
|
-
Defined in: [packages/worker/src/types.ts:197](https://github.com/btravers/amqp-contract/blob/
|
|
763
|
+
Defined in: [packages/worker/src/types.ts:197](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/types.ts#L197)
|
|
762
764
|
|
|
763
765
|
Handler signature for a regular consumer (event/command). Returns
|
|
764
|
-
`
|
|
766
|
+
`ResultAsync<void, HandlerError>` — there is no response message.
|
|
765
767
|
|
|
766
768
|
#### Type Parameters
|
|
767
769
|
|
|
@@ -779,7 +781,7 @@ Handler signature for a regular consumer (event/command). Returns
|
|
|
779
781
|
|
|
780
782
|
#### Returns
|
|
781
783
|
|
|
782
|
-
`
|
|
784
|
+
`ResultAsync`<`void`, [`HandlerError`](#handlererror)>
|
|
783
785
|
|
|
784
786
|
***
|
|
785
787
|
|
|
@@ -791,7 +793,7 @@ type WorkerInferConsumerHandlerEntry<TContract, TName> =
|
|
|
791
793
|
| readonly [WorkerInferConsumerHandler<TContract, TName>, ConsumerOptions];
|
|
792
794
|
```
|
|
793
795
|
|
|
794
|
-
Defined in: [packages/worker/src/types.ts:223](https://github.com/btravers/amqp-contract/blob/
|
|
796
|
+
Defined in: [packages/worker/src/types.ts:223](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/types.ts#L223)
|
|
795
797
|
|
|
796
798
|
Handler entry for a regular consumer — function or `[handler, options]`.
|
|
797
799
|
|
|
@@ -810,7 +812,7 @@ Handler entry for a regular consumer — function or `[handler, options]`.
|
|
|
810
812
|
type WorkerInferConsumerHandlers<TContract> = WorkerInferHandlers<TContract>;
|
|
811
813
|
```
|
|
812
814
|
|
|
813
|
-
Defined in: [packages/worker/src/types.ts:269](https://github.com/btravers/amqp-contract/blob/
|
|
815
|
+
Defined in: [packages/worker/src/types.ts:269](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/types.ts#L269)
|
|
814
816
|
|
|
815
817
|
#### Type Parameters
|
|
816
818
|
|
|
@@ -830,7 +832,7 @@ Use `WorkerInferHandlers` — handlers now span consumers ∪ rpcs.
|
|
|
830
832
|
type WorkerInferConsumerHeaders<TContract, TName> = ConsumerInferHeadersOutput<InferConsumer<TContract, TName>>;
|
|
831
833
|
```
|
|
832
834
|
|
|
833
|
-
Defined in: [packages/worker/src/types.ts:85](https://github.com/btravers/amqp-contract/blob/
|
|
835
|
+
Defined in: [packages/worker/src/types.ts:85](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/types.ts#L85)
|
|
834
836
|
|
|
835
837
|
Infer the headers type for a regular consumer.
|
|
836
838
|
Returns undefined if no headers schema is defined.
|
|
@@ -855,11 +857,11 @@ function defineHandler<TContract, TName>(
|
|
|
855
857
|
handler): WorkerInferConsumerHandlerEntry<TContract, TName>;
|
|
856
858
|
```
|
|
857
859
|
|
|
858
|
-
Defined in: [packages/worker/src/handlers.ts:
|
|
860
|
+
Defined in: [packages/worker/src/handlers.ts:105](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/handlers.ts#L105)
|
|
859
861
|
|
|
860
862
|
Define a type-safe handler for a specific consumer in a contract.
|
|
861
863
|
|
|
862
|
-
**Recommended:** This function creates handlers that return `
|
|
864
|
+
**Recommended:** This function creates handlers that return `ResultAsync<void, HandlerError>`,
|
|
863
865
|
providing explicit error handling and better control over retry behavior.
|
|
864
866
|
|
|
865
867
|
Supports two patterns:
|
|
@@ -879,7 +881,7 @@ Supports two patterns:
|
|
|
879
881
|
| ------ | ------ | ------ |
|
|
880
882
|
| `contract` | `TContract` | The contract definition containing the consumer |
|
|
881
883
|
| `consumerName` | `TName` | The name of the consumer from the contract |
|
|
882
|
-
| `handler` | [`WorkerInferConsumerHandler`](#workerinferconsumerhandler)<`TContract`, `TName`> | The handler function that returns `
|
|
884
|
+
| `handler` | [`WorkerInferConsumerHandler`](#workerinferconsumerhandler)<`TContract`, `TName`> | The handler function that returns `ResultAsync<void, HandlerError>` |
|
|
883
885
|
|
|
884
886
|
##### Returns
|
|
885
887
|
|
|
@@ -891,17 +893,18 @@ A type-safe handler that can be used with TypedAmqpWorker
|
|
|
891
893
|
|
|
892
894
|
```typescript
|
|
893
895
|
import { defineHandler, RetryableError, NonRetryableError } from '@amqp-contract/worker';
|
|
894
|
-
import {
|
|
896
|
+
import { errAsync, okAsync, ResultAsync } from 'neverthrow';
|
|
895
897
|
import { orderContract } from './contract';
|
|
896
898
|
|
|
897
|
-
// Simple handler with explicit error handling
|
|
899
|
+
// Simple handler with explicit error handling
|
|
898
900
|
const processOrderHandler = defineHandler(
|
|
899
901
|
orderContract,
|
|
900
902
|
'processOrder',
|
|
901
903
|
({ payload }) =>
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
904
|
+
ResultAsync.fromPromise(
|
|
905
|
+
processPayment(payload),
|
|
906
|
+
(error) => new RetryableError('Payment failed', error),
|
|
907
|
+
).map(() => undefined),
|
|
905
908
|
);
|
|
906
909
|
|
|
907
910
|
// Handler with validation (non-retryable error)
|
|
@@ -911,10 +914,10 @@ const validateOrderHandler = defineHandler(
|
|
|
911
914
|
({ payload }) => {
|
|
912
915
|
if (payload.amount < 1) {
|
|
913
916
|
// Won't be retried - goes directly to DLQ
|
|
914
|
-
return
|
|
917
|
+
return errAsync(new NonRetryableError('Invalid order amount'));
|
|
915
918
|
}
|
|
916
|
-
return
|
|
917
|
-
}
|
|
919
|
+
return okAsync(undefined);
|
|
920
|
+
},
|
|
918
921
|
);
|
|
919
922
|
```
|
|
920
923
|
|
|
@@ -928,11 +931,11 @@ function defineHandler<TContract, TName>(
|
|
|
928
931
|
options): WorkerInferConsumerHandlerEntry<TContract, TName>;
|
|
929
932
|
```
|
|
930
933
|
|
|
931
|
-
Defined in: [packages/worker/src/handlers.ts:
|
|
934
|
+
Defined in: [packages/worker/src/handlers.ts:113](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/handlers.ts#L113)
|
|
932
935
|
|
|
933
936
|
Define a type-safe handler for a specific consumer in a contract.
|
|
934
937
|
|
|
935
|
-
**Recommended:** This function creates handlers that return `
|
|
938
|
+
**Recommended:** This function creates handlers that return `ResultAsync<void, HandlerError>`,
|
|
936
939
|
providing explicit error handling and better control over retry behavior.
|
|
937
940
|
|
|
938
941
|
Supports two patterns:
|
|
@@ -952,7 +955,7 @@ Supports two patterns:
|
|
|
952
955
|
| ------ | ------ | ------ |
|
|
953
956
|
| `contract` | `TContract` | The contract definition containing the consumer |
|
|
954
957
|
| `consumerName` | `TName` | The name of the consumer from the contract |
|
|
955
|
-
| `handler` | [`WorkerInferConsumerHandler`](#workerinferconsumerhandler)<`TContract`, `TName`> | The handler function that returns `
|
|
958
|
+
| `handler` | [`WorkerInferConsumerHandler`](#workerinferconsumerhandler)<`TContract`, `TName`> | The handler function that returns `ResultAsync<void, HandlerError>` |
|
|
956
959
|
| `options` | `ConsumerOptions` | Optional consumer options (prefetch) |
|
|
957
960
|
|
|
958
961
|
##### Returns
|
|
@@ -965,17 +968,18 @@ A type-safe handler that can be used with TypedAmqpWorker
|
|
|
965
968
|
|
|
966
969
|
```typescript
|
|
967
970
|
import { defineHandler, RetryableError, NonRetryableError } from '@amqp-contract/worker';
|
|
968
|
-
import {
|
|
971
|
+
import { errAsync, okAsync, ResultAsync } from 'neverthrow';
|
|
969
972
|
import { orderContract } from './contract';
|
|
970
973
|
|
|
971
|
-
// Simple handler with explicit error handling
|
|
974
|
+
// Simple handler with explicit error handling
|
|
972
975
|
const processOrderHandler = defineHandler(
|
|
973
976
|
orderContract,
|
|
974
977
|
'processOrder',
|
|
975
978
|
({ payload }) =>
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
+
ResultAsync.fromPromise(
|
|
980
|
+
processPayment(payload),
|
|
981
|
+
(error) => new RetryableError('Payment failed', error),
|
|
982
|
+
).map(() => undefined),
|
|
979
983
|
);
|
|
980
984
|
|
|
981
985
|
// Handler with validation (non-retryable error)
|
|
@@ -985,10 +989,10 @@ const validateOrderHandler = defineHandler(
|
|
|
985
989
|
({ payload }) => {
|
|
986
990
|
if (payload.amount < 1) {
|
|
987
991
|
// Won't be retried - goes directly to DLQ
|
|
988
|
-
return
|
|
992
|
+
return errAsync(new NonRetryableError('Invalid order amount'));
|
|
989
993
|
}
|
|
990
|
-
return
|
|
991
|
-
}
|
|
994
|
+
return okAsync(undefined);
|
|
995
|
+
},
|
|
992
996
|
);
|
|
993
997
|
```
|
|
994
998
|
|
|
@@ -1000,11 +1004,11 @@ const validateOrderHandler = defineHandler(
|
|
|
1000
1004
|
function defineHandlers<TContract>(contract, handlers): WorkerInferConsumerHandlers<TContract>;
|
|
1001
1005
|
```
|
|
1002
1006
|
|
|
1003
|
-
Defined in: [packages/worker/src/handlers.ts:
|
|
1007
|
+
Defined in: [packages/worker/src/handlers.ts:170](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/handlers.ts#L170)
|
|
1004
1008
|
|
|
1005
1009
|
Define multiple type-safe handlers for consumers in a contract.
|
|
1006
1010
|
|
|
1007
|
-
**Recommended:** This function creates handlers that return `
|
|
1011
|
+
**Recommended:** This function creates handlers that return `ResultAsync<void, HandlerError>`,
|
|
1008
1012
|
providing explicit error handling and better control over retry behavior.
|
|
1009
1013
|
|
|
1010
1014
|
#### Type Parameters
|
|
@@ -1030,18 +1034,20 @@ A type-safe handlers object that can be used with TypedAmqpWorker
|
|
|
1030
1034
|
|
|
1031
1035
|
```typescript
|
|
1032
1036
|
import { defineHandlers, RetryableError } from '@amqp-contract/worker';
|
|
1033
|
-
import {
|
|
1037
|
+
import { ResultAsync } from 'neverthrow';
|
|
1034
1038
|
import { orderContract } from './contract';
|
|
1035
1039
|
|
|
1036
1040
|
const handlers = defineHandlers(orderContract, {
|
|
1037
1041
|
processOrder: ({ payload }) =>
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1042
|
+
ResultAsync.fromPromise(
|
|
1043
|
+
processPayment(payload),
|
|
1044
|
+
(error) => new RetryableError('Payment failed', error),
|
|
1045
|
+
).map(() => undefined),
|
|
1041
1046
|
notifyOrder: ({ payload }) =>
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1047
|
+
ResultAsync.fromPromise(
|
|
1048
|
+
sendNotification(payload),
|
|
1049
|
+
(error) => new RetryableError('Notification failed', error),
|
|
1050
|
+
).map(() => undefined),
|
|
1045
1051
|
});
|
|
1046
1052
|
```
|
|
1047
1053
|
|
|
@@ -1053,7 +1059,7 @@ const handlers = defineHandlers(orderContract, {
|
|
|
1053
1059
|
function isHandlerError(error): error is HandlerError;
|
|
1054
1060
|
```
|
|
1055
1061
|
|
|
1056
|
-
Defined in: [packages/worker/src/errors.ts:131](https://github.com/btravers/amqp-contract/blob/
|
|
1062
|
+
Defined in: [packages/worker/src/errors.ts:131](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/errors.ts#L131)
|
|
1057
1063
|
|
|
1058
1064
|
Type guard to check if an error is any HandlerError (RetryableError or NonRetryableError).
|
|
1059
1065
|
|
|
@@ -1090,7 +1096,7 @@ function handleError(error: unknown) {
|
|
|
1090
1096
|
function isNonRetryableError(error): error is NonRetryableError;
|
|
1091
1097
|
```
|
|
1092
1098
|
|
|
1093
|
-
Defined in: [packages/worker/src/errors.ts:109](https://github.com/btravers/amqp-contract/blob/
|
|
1099
|
+
Defined in: [packages/worker/src/errors.ts:109](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/errors.ts#L109)
|
|
1094
1100
|
|
|
1095
1101
|
Type guard to check if an error is a NonRetryableError.
|
|
1096
1102
|
|
|
@@ -1130,7 +1136,7 @@ try {
|
|
|
1130
1136
|
function isRetryableError(error): error is RetryableError;
|
|
1131
1137
|
```
|
|
1132
1138
|
|
|
1133
|
-
Defined in: [packages/worker/src/errors.ts:84](https://github.com/btravers/amqp-contract/blob/
|
|
1139
|
+
Defined in: [packages/worker/src/errors.ts:84](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/errors.ts#L84)
|
|
1134
1140
|
|
|
1135
1141
|
Type guard to check if an error is a RetryableError.
|
|
1136
1142
|
|
|
@@ -1172,7 +1178,7 @@ try {
|
|
|
1172
1178
|
function nonRetryable(message, cause?): NonRetryableError;
|
|
1173
1179
|
```
|
|
1174
1180
|
|
|
1175
|
-
Defined in: [packages/worker/src/errors.ts:
|
|
1181
|
+
Defined in: [packages/worker/src/errors.ts:194](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/errors.ts#L194)
|
|
1176
1182
|
|
|
1177
1183
|
Create a NonRetryableError with less verbosity.
|
|
1178
1184
|
|
|
@@ -1196,17 +1202,17 @@ A new NonRetryableError instance
|
|
|
1196
1202
|
|
|
1197
1203
|
```typescript
|
|
1198
1204
|
import { nonRetryable } from '@amqp-contract/worker';
|
|
1199
|
-
import {
|
|
1205
|
+
import { errAsync, okAsync } from 'neverthrow';
|
|
1200
1206
|
|
|
1201
1207
|
const handler = ({ payload }) => {
|
|
1202
1208
|
if (!isValidPayload(payload)) {
|
|
1203
|
-
return
|
|
1209
|
+
return errAsync(nonRetryable('Invalid payload format'));
|
|
1204
1210
|
}
|
|
1205
|
-
return
|
|
1211
|
+
return okAsync(undefined);
|
|
1206
1212
|
};
|
|
1207
1213
|
|
|
1208
1214
|
// Equivalent to:
|
|
1209
|
-
// return
|
|
1215
|
+
// return errAsync(new NonRetryableError('Invalid payload format'));
|
|
1210
1216
|
```
|
|
1211
1217
|
|
|
1212
1218
|
***
|
|
@@ -1217,7 +1223,7 @@ const handler = ({ payload }) => {
|
|
|
1217
1223
|
function retryable(message, cause?): RetryableError;
|
|
1218
1224
|
```
|
|
1219
1225
|
|
|
1220
|
-
Defined in: [packages/worker/src/errors.ts:
|
|
1226
|
+
Defined in: [packages/worker/src/errors.ts:164](https://github.com/btravers/amqp-contract/blob/1ba3d51bb1d4a09c356afad101dc9e6e6d605185/packages/worker/src/errors.ts#L164)
|
|
1221
1227
|
|
|
1222
1228
|
Create a RetryableError with less verbosity.
|
|
1223
1229
|
|
|
@@ -1241,13 +1247,14 @@ A new RetryableError instance
|
|
|
1241
1247
|
|
|
1242
1248
|
```typescript
|
|
1243
1249
|
import { retryable } from '@amqp-contract/worker';
|
|
1244
|
-
import {
|
|
1250
|
+
import { ResultAsync } from 'neverthrow';
|
|
1245
1251
|
|
|
1246
1252
|
const handler = ({ payload }) =>
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1253
|
+
ResultAsync.fromPromise(
|
|
1254
|
+
processPayment(payload),
|
|
1255
|
+
(e) => retryable('Payment service unavailable', e),
|
|
1256
|
+
).map(() => undefined);
|
|
1250
1257
|
|
|
1251
1258
|
// Equivalent to:
|
|
1252
|
-
// .
|
|
1259
|
+
// ResultAsync.fromPromise(processPayment(payload), (e) => new RetryableError('...', e))
|
|
1253
1260
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amqp-contract/worker",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"description": "Worker utilities for consuming messages using amqp-contract",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"amqp",
|
|
@@ -51,23 +51,23 @@
|
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@standard-schema/spec": "1.1.0",
|
|
54
|
-
"
|
|
55
|
-
"@amqp-contract/contract": "0.
|
|
56
|
-
"@amqp-contract/core": "0.
|
|
54
|
+
"neverthrow": "8.2.0",
|
|
55
|
+
"@amqp-contract/contract": "0.24.0",
|
|
56
|
+
"@amqp-contract/core": "0.24.0"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@types/amqplib": "0.10.8",
|
|
60
60
|
"@types/node": "24.12.2",
|
|
61
61
|
"@vitest/coverage-v8": "4.1.5",
|
|
62
62
|
"amqp-connection-manager": "5.0.0",
|
|
63
|
-
"amqplib": "
|
|
63
|
+
"amqplib": "0.10.9",
|
|
64
64
|
"tsdown": "0.21.10",
|
|
65
65
|
"typedoc": "0.28.19",
|
|
66
66
|
"typedoc-plugin-markdown": "4.11.0",
|
|
67
67
|
"typescript": "6.0.3",
|
|
68
68
|
"vitest": "4.1.5",
|
|
69
|
-
"zod": "4.3
|
|
70
|
-
"@amqp-contract/testing": "0.
|
|
69
|
+
"zod": "4.4.3",
|
|
70
|
+
"@amqp-contract/testing": "0.24.0",
|
|
71
71
|
"@amqp-contract/tsconfig": "0.1.0",
|
|
72
72
|
"@amqp-contract/typedoc": "0.1.0"
|
|
73
73
|
},
|