@znight/messaging 0.0.0-stage → 0.1.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.
Files changed (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +622 -2
  3. package/dist/async-CFh_bvex.mjs +216 -0
  4. package/dist/async-CFh_bvex.mjs.map +1 -0
  5. package/dist/codec-Dku-NXXU.mjs +83 -0
  6. package/dist/codec-Dku-NXXU.mjs.map +1 -0
  7. package/dist/compiler.d.mts +75 -0
  8. package/dist/compiler.mjs +1023 -0
  9. package/dist/compiler.mjs.map +1 -0
  10. package/dist/driver-ZxLqy_Ap.d.mts +216 -0
  11. package/dist/index.d.mts +459 -0
  12. package/dist/index.mjs +870 -0
  13. package/dist/index.mjs.map +1 -0
  14. package/dist/kafka.d.mts +51 -0
  15. package/dist/kafka.mjs +517 -0
  16. package/dist/kafka.mjs.map +1 -0
  17. package/dist/memory.d.mts +124 -0
  18. package/dist/memory.mjs +429 -0
  19. package/dist/memory.mjs.map +1 -0
  20. package/dist/rabbitmq.d.mts +65 -0
  21. package/dist/rabbitmq.mjs +686 -0
  22. package/dist/rabbitmq.mjs.map +1 -0
  23. package/dist/shared-BJBpLS8V.mjs +52 -0
  24. package/dist/shared-BJBpLS8V.mjs.map +1 -0
  25. package/dist/sqs.d.mts +38 -0
  26. package/dist/sqs.mjs +421 -0
  27. package/dist/sqs.mjs.map +1 -0
  28. package/package.json +123 -4
  29. package/src/broker.ts +156 -0
  30. package/src/codec.ts +98 -0
  31. package/src/compiler/analyze.ts +800 -0
  32. package/src/compiler/constants.ts +73 -0
  33. package/src/compiler/data.ts +75 -0
  34. package/src/compiler/generate.ts +131 -0
  35. package/src/compiler/index.ts +52 -0
  36. package/src/compiler/patterns.ts +54 -0
  37. package/src/compiler/retry.ts +136 -0
  38. package/src/compiler/validate.ts +57 -0
  39. package/src/compiler/values.ts +76 -0
  40. package/src/consumers.ts +260 -0
  41. package/src/decorators.ts +131 -0
  42. package/src/driver.ts +142 -0
  43. package/src/drivers/kafka.ts +765 -0
  44. package/src/drivers/memory.ts +609 -0
  45. package/src/drivers/rabbitmq.ts +944 -0
  46. package/src/drivers/shared.ts +81 -0
  47. package/src/drivers/sqs.ts +583 -0
  48. package/src/errors.ts +95 -0
  49. package/src/headers.ts +70 -0
  50. package/src/hooks.ts +2 -0
  51. package/src/index.ts +89 -0
  52. package/src/internal/async.ts +115 -0
  53. package/src/message.ts +96 -0
  54. package/src/metadata.ts +65 -0
  55. package/src/plugin.ts +236 -0
  56. package/src/retry.ts +129 -0
  57. package/src/runtime.ts +424 -0
  58. package/src/standard-schema.ts +68 -0
  59. package/src/tokens.ts +14 -0
  60. package/src/validation.ts +61 -0
@@ -0,0 +1,459 @@
1
+ import { a as DriverDelivery, c as SubscribeOptions, d as InboundMessage, f as OutboundMessage, i as DriverContext, l as Subscription, m as PublishResult, n as DeliveryHandler, o as MessagingDriver, p as PublishOptions, r as DriverCapabilities, s as RetryRequest, t as DeadLetterRequest, u as DeadLetterReason } from "./driver-ZxLqy_Ap.mjs";
2
+ import { ClassMarker, CoreLogger, MessagePublishEvent, MethodMarker, ParameterMarker, Plugin, PluginOptions, Scope, Token, TypedToken, ZnightError } from "@znight/core";
3
+ /** Backoff strategy between attempts. */
4
+ type BackoffStrategy = "fixed" | "exponential";
5
+ /** Options of `@Retry()` and of the plugin's `defaults.retry`. */
6
+ interface RetryOptions {
7
+ /** Total number of attempts, including the first delivery (`1`: no retry). */
8
+ readonly attempts: number;
9
+ /** `fixed`: always `delay`; `exponential`: `delay * 2^(attempt - 1)`, capped by `maxDelay`. Default: `exponential`. */
10
+ readonly backoff?: BackoffStrategy;
11
+ /** Base delay between attempts, in milliseconds. Default: 1000. */
12
+ readonly delay?: number;
13
+ /** Upper bound of exponential delays, in milliseconds. */
14
+ readonly maxDelay?: number;
15
+ }
16
+ /** A normalized retry policy, as stored in the metadata (`MessageHandlerDefinition.retry`). */
17
+ interface RetryPolicy {
18
+ readonly attempts: number;
19
+ readonly backoff: BackoffStrategy;
20
+ readonly delay: number;
21
+ readonly maxDelay?: number;
22
+ }
23
+ /** Default base delay of a retry policy, in milliseconds. */
24
+ export declare const DEFAULT_RETRY_DELAY_MS = 1e3;
25
+ /** Default backoff strategy. */
26
+ export declare const DEFAULT_BACKOFF: BackoffStrategy;
27
+ /** Policy applied to handlers without `@Retry` when the plugin sets no `defaults.retry`. */
28
+ export declare const DEFAULT_RETRY_POLICY: RetryPolicy;
29
+ /**
30
+ * Validates retry options and fills defaults.
31
+ *
32
+ * @throws ZnightError ZNIGHT011 for invalid values (`where` names the handler in the message).
33
+ */
34
+ export declare function normalizeRetry(options: RetryOptions | RetryPolicy, where?: string): RetryPolicy;
35
+ /**
36
+ * Delay before the next attempt once `attempt` (1-based) failed: `delay` for `fixed`,
37
+ * `delay * 2^(attempt - 1)` capped by `maxDelay` for `exponential`.
38
+ */
39
+ export declare function computeRetryDelay(policy: RetryPolicy, attempt: number): number;
40
+ /** Messaging metadata of the application. */
41
+ interface MessagingMetadata {
42
+ readonly consumers: readonly ConsumerDefinition[];
43
+ }
44
+ /**
45
+ * Options of a consumer: `concurrency` and `deadLetter` are read by the runtime, every other key is a
46
+ * driver option (e.g. Kafka `groupId`) forwarded to `MessagingDriver.subscribe`.
47
+ */
48
+ interface ConsumerRuntimeOptions {
49
+ /** Maximum number of messages handled concurrently by this consumer. Default: plugin `defaults.concurrency`. */
50
+ readonly concurrency?: number;
51
+ /** Dead-letter destination, or `false` to disable dead-lettering. Default: the plugin/driver naming. */
52
+ readonly deadLetter?: string | false;
53
+ readonly [driverOption: string]: unknown;
54
+ }
55
+ /** One `@Consumer` class. */
56
+ interface ConsumerDefinition {
57
+ /** Provider token of the consumer class. */
58
+ readonly token: Token;
59
+ /** Queue (RabbitMQ, SQS) or topic (Kafka) consumed. */
60
+ readonly queue: string;
61
+ /** `@Consumer({ queue, ...options })` without `queue` and `scope`. */
62
+ readonly options?: ConsumerRuntimeOptions;
63
+ /** `@OnMessage` methods, in declaration order. */
64
+ readonly handlers: readonly MessageHandlerDefinition[];
65
+ /** Name of the `@OnError` method, if any: `(error, message) => void | 'ack'`. */
66
+ readonly errorHandler?: string;
67
+ }
68
+ /** One `@OnMessage` method. */
69
+ interface MessageHandlerDefinition {
70
+ /** Method name (logs, hook events). */
71
+ readonly method: string;
72
+ /**
73
+ * `@OnMessage(type)`: the message type handled (exact match, or a pattern where `*` matches any
74
+ * sequence of characters). Without type, the handler is the consumer's default handler.
75
+ */
76
+ readonly type?: string;
77
+ /** `@Retry` policy, normalized. Default: the plugin's `defaults.retry`. */
78
+ readonly retry?: RetryPolicy;
79
+ /**
80
+ * Calls the handler: extracts and validates the parameters from the message
81
+ * (`@Message(schema)` → `validateMessage(schema, m.payload)`, `@Headers(name)` →
82
+ * `messageHeader(m, name)`, `@Ctx()` → `m`).
83
+ */
84
+ readonly invoke: (consumer: any, message: InboundMessage) => unknown;
85
+ }
86
+ declare module "@znight/core" {
87
+ interface ZnightExtensionsMetadata {
88
+ readonly messaging?: MessagingMetadata;
89
+ }
90
+ }
91
+ /** An encoded body and its content type. */
92
+ interface EncodedBody {
93
+ readonly body: Uint8Array | string;
94
+ readonly contentType: string;
95
+ }
96
+ /**
97
+ * Converts payloads to bodies and back. The default {@link jsonCodec} handles JSON, text and binary
98
+ * payloads; provide your own (MessagePack, Avro...) with `MessagingPlugin.configure({ codec })`.
99
+ */
100
+ interface MessageCodec {
101
+ /**
102
+ * Encodes a payload for publication. `contentType` is the one requested by the publisher, if any
103
+ * (`publish(queue, payload, { contentType })`).
104
+ */
105
+ encode(payload: unknown, contentType: string | undefined): EncodedBody;
106
+ /**
107
+ * Decodes a received body. Throw a {@link MessageDecodeError} (a `NonRetryableError`) for malformed
108
+ * bodies: the message is dead-lettered with reason `decode`.
109
+ */
110
+ decode(body: Uint8Array | string, contentType: string | undefined): unknown;
111
+ }
112
+ export declare const JSON_CONTENT_TYPE = "application/json";
113
+ export declare const TEXT_CONTENT_TYPE = "text/plain; charset=utf-8";
114
+ export declare const BINARY_CONTENT_TYPE = "application/octet-stream";
115
+ /** Body as text (UTF-8). */
116
+ export declare function bodyToText(body: Uint8Array | string): string;
117
+ /** Body as bytes (UTF-8 for strings). */
118
+ export declare function bodyToBytes(body: Uint8Array | string): Uint8Array;
119
+ /** Lower-cased media type without parameters (`application/json; charset=utf-8` → `application/json`). */
120
+ export declare function mediaType(contentType: string | undefined): string | undefined;
121
+ /**
122
+ * The default codec.
123
+ *
124
+ * - encode: `Uint8Array` → `application/octet-stream`; a `string` with an explicit text/binary
125
+ * `contentType` is sent as is; everything else is JSON (`application/json`), including strings.
126
+ * `undefined` is an empty JSON body.
127
+ * - decode: JSON (`application/json`, `*+json`) is parsed (empty body → `undefined`; malformed →
128
+ * `MessageDecodeError`); `text/*` → string; other declared types → `Uint8Array`. Without content
129
+ * type, JSON is attempted and the text is returned when it is not valid JSON.
130
+ */
131
+ export declare const jsonCodec: MessageCodec;
132
+ /** State of a {@link ConsumerRuntime}. */
133
+ type ConsumerState = "created" | "starting" | "running" | "stopping" | "stopped";
134
+ /**
135
+ * Publishes messages. Inject it in any provider (it is a singleton external provided by
136
+ * `MessagingPlugin`):
137
+ *
138
+ * ```ts
139
+ * @Injectable()
140
+ * export class OrderService {
141
+ * constructor(private readonly broker: MessageBroker) {}
142
+ *
143
+ * async place(order: Order) {
144
+ * await this.broker.publish('orders', order, { type: 'order.placed', key: order.customerId })
145
+ * }
146
+ * }
147
+ * ```
148
+ *
149
+ * `publish()` resolves once the broker confirmed the message (publisher confirms, SQS response,
150
+ * Kafka acknowledgement). It is usable from `onBootstrap` of the messaging plugin until the
151
+ * application is disposed (including providers' `onStart` / `onStop`).
152
+ */
153
+ export declare abstract class MessageBroker {
154
+ /**
155
+ * Publishes `payload` to `queue` (a queue for RabbitMQ/SQS, a topic for Kafka). The payload is
156
+ * encoded by the plugin codec (JSON by default; `Uint8Array` is sent as binary).
157
+ */
158
+ abstract publish(queue: string, payload: unknown, options?: PublishOptions): Promise<PublishResult>;
159
+ }
160
+ /**
161
+ * Copy of the [Standard Schema v1](https://standardschema.dev) interface (MIT). Zod, Valibot, ArkType,
162
+ * Effect Schema... implement it: `@Message(schema)` accepts any of them without depending on one.
163
+ *
164
+ * The upstream declaration uses a namespace; the types are flattened here (`erasableSyntaxOnly`) but
165
+ * remain structurally identical, so any Standard Schema implementation is assignable.
166
+ */
167
+ /** A schema implementing the Standard Schema v1 interface. */
168
+ interface StandardSchemaV1<Input = unknown, Output = Input> {
169
+ readonly "~standard": StandardSchemaV1Props<Input, Output>;
170
+ }
171
+ /** The `~standard` property of a {@link StandardSchemaV1}. */
172
+ interface StandardSchemaV1Props<Input = unknown, Output = Input> {
173
+ /** Version of the Standard Schema specification. */
174
+ readonly version: 1;
175
+ /** Library implementing the schema (`zod`, `valibot`...). */
176
+ readonly vendor: string;
177
+ /** Validates an unknown value, synchronously or asynchronously. */
178
+ readonly validate: (value: unknown) => StandardSchemaV1Result<Output> | Promise<StandardSchemaV1Result<Output>>;
179
+ /** Inferred types (type-level only). */
180
+ readonly types?: StandardSchemaV1Types<Input, Output> | undefined;
181
+ }
182
+ /** Result of {@link StandardSchemaV1Props.validate}. */
183
+ type StandardSchemaV1Result<Output> = StandardSchemaV1SuccessResult<Output> | StandardSchemaV1FailureResult;
184
+ /** Successful validation: `value` is the schema output (defaults, transforms applied). */
185
+ interface StandardSchemaV1SuccessResult<Output> {
186
+ readonly value: Output;
187
+ readonly issues?: undefined;
188
+ }
189
+ /** Failed validation. */
190
+ interface StandardSchemaV1FailureResult {
191
+ readonly issues: readonly StandardSchemaV1Issue[];
192
+ }
193
+ /** One validation issue. */
194
+ interface StandardSchemaV1Issue {
195
+ readonly message: string;
196
+ readonly path?: readonly (PropertyKey | StandardSchemaV1PathSegment)[] | undefined;
197
+ }
198
+ /** A segment of an issue path. */
199
+ interface StandardSchemaV1PathSegment {
200
+ readonly key: PropertyKey;
201
+ }
202
+ /** Input and output types of a schema (type-level only). */
203
+ interface StandardSchemaV1Types<Input = unknown, Output = Input> {
204
+ readonly input: Input;
205
+ readonly output: Output;
206
+ }
207
+ /** Input type of a Standard Schema. */
208
+ type InferSchemaInput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["input"];
209
+ /** Output type of a Standard Schema (what handlers receive). */
210
+ type InferSchemaOutput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["output"];
211
+ /** Whether `value` looks like a Standard Schema v1 (has a `~standard.validate` function). */
212
+ export declare function isStandardSchema(value: unknown): value is StandardSchemaV1;
213
+ /** Options of {@link Consumer} (static). */
214
+ interface ConsumerOptions {
215
+ /** Queue (RabbitMQ, SQS) or topic (Kafka) to consume. */
216
+ readonly queue: string;
217
+ /** Scope of the consumer provider. Default: `singleton`; `request` creates one instance per message. */
218
+ readonly scope?: Scope;
219
+ /** Maximum number of messages handled concurrently. Default: plugin `defaults.concurrency` (1). */
220
+ readonly concurrency?: number;
221
+ /** Dead-letter queue/topic, or `false` to disable dead-lettering. Default: driver naming (`<queue>.dlq`). */
222
+ readonly deadLetter?: string | false;
223
+ /** Driver-specific options (e.g. Kafka `groupId`). */
224
+ readonly [driverOption: string]: unknown;
225
+ }
226
+ /** Result of an `@OnError` method: `'ack'` acknowledges (swallows) the message, anything else dead-letters it. */
227
+ type ErrorHandlerResult = "ack" | undefined | void;
228
+ /**
229
+ * Signature of an `@OnError` method. Declared as a method signature so that parameters may be
230
+ * narrowed (`onError(error: Error, message: InboundMessage<Order>)`).
231
+ */
232
+ type ErrorHandlerMethod = ErrorHandlerSignature["onError"];
233
+ interface ErrorHandlerSignature {
234
+ onError(error: unknown, message: InboundMessage): ErrorHandlerResult | Promise<ErrorHandlerResult>;
235
+ }
236
+ /** Marker usable on an `@OnError` method: checks its signature. */
237
+ type ErrorHandlerMarker = <F extends ErrorHandlerMethod>(target: object, propertyKeyOrContext: string | symbol | ClassMethodDecoratorContext<unknown, F>, descriptor?: TypedPropertyDescriptor<F>) => void;
238
+ /**
239
+ * Declares a message consumer: a provider (singleton by default) whose `@OnMessage` methods handle
240
+ * the messages of `queue`. Arguments are static.
241
+ *
242
+ * ```ts
243
+ * @Consumer('orders')
244
+ * export class OrderConsumer {
245
+ * constructor(private readonly orders: OrderService) {}
246
+ *
247
+ * @OnMessage('order.created')
248
+ * @Retry({ attempts: 5, backoff: 'exponential', delay: 500 })
249
+ * async created(@Message(OrderCreated) event: OrderCreated) {
250
+ * await this.orders.process(event)
251
+ * }
252
+ * }
253
+ * ```
254
+ */
255
+ export declare function Consumer(queue: string): ClassMarker;
256
+ export declare function Consumer(options: ConsumerOptions): ClassMarker;
257
+ /**
258
+ * Declares a message handler. With `type` (static), it handles the messages of that type (exact
259
+ * match, or a pattern where `*` matches any sequence: `'order.*'`); without type it is the consumer's
260
+ * default handler (messages without type, or whose type no other handler matches). A message no
261
+ * handler matches is dead-lettered (reason `no-handler`).
262
+ */
263
+ export declare function OnMessage(_type?: string): MethodMarker;
264
+ /**
265
+ * Retry policy of a handler (static options). `attempts` counts the first delivery:
266
+ * `{ attempts: 3 }` means one delivery plus two retries. Without `@Retry`, the plugin's
267
+ * `defaults.retry` applies (3 attempts, exponential from 1 s).
268
+ */
269
+ export declare function Retry(_options: RetryOptions): MethodMarker;
270
+ /**
271
+ * Declares the consumer's error handler, called once a message will not be retried anymore (last
272
+ * attempt failed, `NonRetryableError`, invalid payload, no matching handler). Returning `'ack'`
273
+ * acknowledges the message; returning anything else (or throwing) dead-letters it.
274
+ *
275
+ * ```ts
276
+ * @OnError()
277
+ * onError(error: unknown, message: InboundMessage) {
278
+ * if (message.type?.startsWith('legacy.')) return 'ack'
279
+ * }
280
+ * ```
281
+ */
282
+ export declare function OnError(): ErrorHandlerMarker;
283
+ /**
284
+ * Injects the message payload. With a Standard Schema (Zod, Valibot...), the payload is validated and
285
+ * the parameter receives the schema output; an invalid payload is dead-lettered without retry
286
+ * (reason `validation`). The schema is a _value_ argument (inline, or an exported binding).
287
+ */
288
+ export declare function Message(_schema?: StandardSchemaV1): ParameterMarker;
289
+ /** Injects all the message headers, or the value of one header (`string | undefined`). `name` is static. */
290
+ export declare function Headers(_name?: string): ParameterMarker;
291
+ /** Injects the {@link InboundMessage} (id, type, attempt, headers, raw message, abort signal...). */
292
+ export declare function Ctx(): ParameterMarker;
293
+ /**
294
+ * Thrown by a handler to dead-letter the message immediately, without further attempts (invalid
295
+ * business data, permanent failure...). Subclass it for domain errors.
296
+ *
297
+ * ```ts
298
+ * if (order.total < 0) throw new NonRetryableError('Negative order total')
299
+ * ```
300
+ */
301
+ export declare class NonRetryableError extends Error {
302
+ constructor(message: string, options?: ErrorOptions);
303
+ }
304
+ /**
305
+ * Whether retrying `error` is pointless: a {@link NonRetryableError} (also recognised across copies of
306
+ * this package, through a global symbol brand).
307
+ */
308
+ export declare function isNonRetryable(error: unknown): boolean;
309
+ /** One failed check of a `@Message(schema)` validation. */
310
+ interface MessageValidationIssue {
311
+ /** Dotted path of the invalid value (`items.0.quantity`), empty for the root. */
312
+ readonly path: string;
313
+ readonly message: string;
314
+ }
315
+ /** The payload does not match the `@Message(schema)` of the handler. Never retried. */
316
+ export declare class MessageValidationError extends NonRetryableError {
317
+ readonly issues: readonly MessageValidationIssue[];
318
+ constructor(label: string, issues: readonly MessageValidationIssue[]);
319
+ }
320
+ /** The body cannot be decoded (malformed JSON...). Never retried. */
321
+ export declare class MessageDecodeError extends NonRetryableError {
322
+ constructor(message: string, options?: ErrorOptions);
323
+ }
324
+ /** No `@OnMessage` handler of the consumer matches the message type. Never retried. */
325
+ export declare class NoHandlerError extends NonRetryableError {
326
+ readonly messageType: string | undefined;
327
+ constructor(consumer: string, type: string | undefined);
328
+ }
329
+ /** A delivery arrived after its last allowed attempt (e.g. redelivered after a dead-letter failure). */
330
+ export declare class AttemptsExhaustedError extends NonRetryableError {
331
+ constructor(attempt: number, maxAttempts: number);
332
+ }
333
+ /**
334
+ * Header names used by Znight on the wire. They are plain message headers (AMQP headers, SQS message
335
+ * attributes, Kafka record headers), so non-Znight producers and consumers can read and write them.
336
+ */
337
+ export declare const MessagingHeaders: {
338
+ /** Znight message id (Kafka and SQS; AMQP uses the `message-id` property). */
339
+ readonly Id: "x-znight-id";
340
+ /** Message type used to select the handler (Kafka and SQS; AMQP uses the `type` property). */
341
+ readonly Type: "x-znight-type";
342
+ /** Content type of the body (Kafka and SQS; AMQP uses the `content-type` property). */
343
+ readonly ContentType: "content-type";
344
+ /** 1-based attempt number carried by republished retries (RabbitMQ, Kafka). */
345
+ readonly Attempt: "x-znight-attempt";
346
+ /** Epoch milliseconds before which a Kafka retry record must not be processed. */
347
+ readonly NotBefore: "x-znight-not-before";
348
+ /** Body encoding when the transport only carries text (SQS: `base64` for binary payloads). */
349
+ readonly Encoding: "x-znight-encoding";
350
+ /** Why the message was dead-lettered (`DeadLetterReason`). */
351
+ readonly DeadLetterReason: "x-znight-dead-letter-reason";
352
+ /** Message of the error that dead-lettered the message (truncated). */
353
+ readonly Error: "x-znight-error";
354
+ /** Queue the dead-lettered message was consumed from. */
355
+ readonly OriginalQueue: "x-znight-original-queue";
356
+ /** Number of attempts made before the message was dead-lettered. */
357
+ readonly Attempts: "x-znight-attempts";
358
+ /** Kafka consumer group that dead-lettered the record. */
359
+ readonly ConsumerGroup: "x-znight-consumer-group";
360
+ };
361
+ /**
362
+ * Reads a header: exact name first, then a case-insensitive match. Used by the code generated for
363
+ * `@Headers('name')` parameters.
364
+ */
365
+ export declare function messageHeader(message: {
366
+ readonly headers: Readonly<Record<string, string>>;
367
+ }, name: string): string | undefined;
368
+ /** Parses the {@link MessagingHeaders.Attempt} header: a positive integer, `1` when absent or invalid. */
369
+ export declare function attemptFromHeaders(headers: Readonly<Record<string, string>>): number;
370
+ /** Defaults applied to every consumer (each `@Consumer` / `@Retry` may override them). */
371
+ interface MessagingDefaults {
372
+ /** Retry policy of handlers without `@Retry`. Default: 3 attempts, exponential from 1 s up to 30 s. `false`: no retry. */
373
+ readonly retry?: RetryOptions | false;
374
+ /** Concurrency of consumers without `concurrency` option. Default: 1. */
375
+ readonly concurrency?: number;
376
+ /**
377
+ * Dead-letter destination of a queue, or `false` to disable dead-lettering (messages are then
378
+ * rejected natively or discarded). Default: the driver naming (`orders.dlq`, SQS `orders-dlq`).
379
+ */
380
+ readonly deadLetter?: ((queue: string) => string) | false;
381
+ /**
382
+ * Pause, in milliseconds, before releasing a message whose settlement failed (dead-letter queue
383
+ * unavailable...), to avoid hot redelivery loops. Default: 1000.
384
+ */
385
+ readonly requeueDelay?: number;
386
+ }
387
+ /** Options of {@link MessagingPlugin.configure}. */
388
+ interface MessagingPluginOptions {
389
+ /** The broker driver: `rabbitmq()`, `sqs()`, `kafka()` or `memory()` (from the matching subpath). */
390
+ readonly driver: MessagingDriver;
391
+ readonly defaults?: MessagingDefaults;
392
+ /** Payload encoding. Default: {@link jsonCodec}. */
393
+ readonly codec?: MessageCodec;
394
+ /** Subscribe the consumers on start. `false` for publish-only processes. Default: `true`. */
395
+ readonly consume?: boolean;
396
+ }
397
+ /** Runtime status of a consumer. */
398
+ interface ConsumerStatus {
399
+ /** Display name of the consumer class. */
400
+ readonly consumer: string;
401
+ readonly queue: string;
402
+ readonly state: ConsumerState;
403
+ readonly concurrency: number;
404
+ readonly inFlight: number;
405
+ readonly deadLetterQueue: string | undefined;
406
+ }
407
+ /** The plugin returned by {@link MessagingPlugin.configure}. */
408
+ interface MessagingPluginInstance extends Plugin {
409
+ readonly name: "messaging";
410
+ /** The broker (also injectable as `MessageBroker`). */
411
+ readonly broker: MessageBroker;
412
+ /** The driver, once the plugin is bootstrapped. */
413
+ readonly driver: MessagingDriver | undefined;
414
+ /** Status of every consumer, once the plugin is bootstrapped. */
415
+ consumers(): ConsumerStatus[];
416
+ }
417
+ /**
418
+ * Message consumers and publishing.
419
+ *
420
+ * ```ts
421
+ * import { MessagingPlugin } from '@znight/messaging'
422
+ * import { rabbitmq } from '@znight/messaging/rabbitmq'
423
+ *
424
+ * const app = await Application.create({
425
+ * metadata: __ZNIGHT_METADATA__,
426
+ * plugins: [MessagingPlugin.configure({ driver: rabbitmq({ url: 'amqp://localhost' }) })],
427
+ * })
428
+ * ```
429
+ *
430
+ * Options may be computed from the container (evaluated in `onBootstrap`):
431
+ * `MessagingPlugin.configure(c => ({ driver: rabbitmq({ url: c.get(AmqpConfig).url }) }))`.
432
+ */
433
+ export declare const MessagingPlugin: {
434
+ configure(options: PluginOptions<MessagingPluginOptions>): MessagingPluginInstance;
435
+ };
436
+ /** Tokens of the externals provided by `MessagingPlugin` (declared in the package manifest). */
437
+ export declare const MessagingTokens: {
438
+ /** The {@link MessageBroker} singleton. */
439
+ readonly MessageBroker: TypedToken<MessageBroker>;
440
+ /** The {@link InboundMessage} of the current delivery (request-scoped). */
441
+ readonly InboundMessage: TypedToken<InboundMessage>;
442
+ };
443
+ /**
444
+ * Validates `value` with a Standard Schema (Zod, Valibot, ArkType...) and returns the schema
445
+ * **output** (defaults and transforms applied). On failure it throws a {@link MessageValidationError},
446
+ * a `NonRetryableError`: the message is dead-lettered without further attempts.
447
+ *
448
+ * Returns synchronously when the schema validates synchronously, a promise otherwise. Called by the
449
+ * code generated for `@Message(schema)` parameters:
450
+ *
451
+ * ```ts
452
+ * invoke: async (c, m) => c.handle(await validateMessage(OrderCreated, m.payload))
453
+ * ```
454
+ *
455
+ * @param label Describes the value in the error message. Default: `'message payload'`.
456
+ */
457
+ export declare function validateMessage<S extends StandardSchemaV1>(schema: S, value: unknown, label?: string): InferSchemaOutput<S> | Promise<InferSchemaOutput<S>>;
458
+ export type { BackoffStrategy, ConsumerDefinition, ConsumerOptions, ConsumerRuntimeOptions, ConsumerState, ConsumerStatus, DeadLetterReason, DeadLetterRequest, DeliveryHandler, DriverCapabilities, DriverContext, DriverDelivery, EncodedBody, ErrorHandlerMarker, ErrorHandlerMethod, ErrorHandlerResult, InboundMessage, InferSchemaInput, InferSchemaOutput, MessageCodec, MessageHandlerDefinition, MessagePublishEvent, MessageValidationIssue, MessagingDefaults, MessagingDriver, MessagingMetadata, MessagingPluginInstance, MessagingPluginOptions, OutboundMessage, PublishOptions, PublishResult, RetryOptions, RetryPolicy, RetryRequest, StandardSchemaV1, StandardSchemaV1FailureResult, StandardSchemaV1Issue, StandardSchemaV1PathSegment, StandardSchemaV1Props, StandardSchemaV1Result, StandardSchemaV1SuccessResult, StandardSchemaV1Types, SubscribeOptions, Subscription };
459
+ //# sourceMappingURL=index.d.mts.map