@relaybus/rabbitmq 0.4.1 → 0.5.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/dist/index.d.cts CHANGED
@@ -252,6 +252,12 @@ interface EncodedMessage {
252
252
  interface RabbitMqCodec {
253
253
  readonly encode: (envelope: EventEnvelope) => EncodedMessage;
254
254
  readonly decode: RabbitMqMessageDecoder;
255
+ /**
256
+ * Returns this codec with more wire names for event types, which a route or catalog declares
257
+ * (`wireTypes` of `route(...)` or `defineCatalog`). Only a codec that maps type names has it
258
+ * ({@link jsonEnvelope}); declaring wire names for a transport whose codec lacks it fails at boot.
259
+ */
260
+ readonly withWireTypes?: (wireTypes: Readonly<Record<string, string>>) => RabbitMqCodec;
255
261
  }
256
262
  /**
257
263
  * CloudEvents 1.0 binary content mode, the default: the body is the JSON
@@ -492,6 +498,15 @@ declare class RabbitMqTransport extends SubscribingTransport {
492
498
  * @throws {UnroutableMessageError} no queue is bound to `destination` (unless `allowUnroutable`)
493
499
  * @throws whatever the `codec`'s `encode` throws, such as {@link RabbitMqUnencodableEventError}
494
500
  */
501
+ /**
502
+ * Checks the wire names a route or catalog declares and returns the function that makes the codec
503
+ * write and read events under them. The bus calls it when it is created, before the transport
504
+ * connects.
505
+ *
506
+ * @throws WireTypesUnsupportedError when the codec does not map type names (use `jsonEnvelope`),
507
+ * WireTypeCollisionError when a name clashes with one of the codec's own `wireTypes`.
508
+ */
509
+ declareWireTypes(wireTypes: Readonly<Record<string, string>>): () => void;
495
510
  publish(envelope: EventEnvelope, destination: string): Promise<void>;
496
511
  /**
497
512
  * Binds one durable quorum queue to `destinations` and delivers its messages
package/dist/index.d.ts CHANGED
@@ -252,6 +252,12 @@ interface EncodedMessage {
252
252
  interface RabbitMqCodec {
253
253
  readonly encode: (envelope: EventEnvelope) => EncodedMessage;
254
254
  readonly decode: RabbitMqMessageDecoder;
255
+ /**
256
+ * Returns this codec with more wire names for event types, which a route or catalog declares
257
+ * (`wireTypes` of `route(...)` or `defineCatalog`). Only a codec that maps type names has it
258
+ * ({@link jsonEnvelope}); declaring wire names for a transport whose codec lacks it fails at boot.
259
+ */
260
+ readonly withWireTypes?: (wireTypes: Readonly<Record<string, string>>) => RabbitMqCodec;
255
261
  }
256
262
  /**
257
263
  * CloudEvents 1.0 binary content mode, the default: the body is the JSON
@@ -492,6 +498,15 @@ declare class RabbitMqTransport extends SubscribingTransport {
492
498
  * @throws {UnroutableMessageError} no queue is bound to `destination` (unless `allowUnroutable`)
493
499
  * @throws whatever the `codec`'s `encode` throws, such as {@link RabbitMqUnencodableEventError}
494
500
  */
501
+ /**
502
+ * Checks the wire names a route or catalog declares and returns the function that makes the codec
503
+ * write and read events under them. The bus calls it when it is created, before the transport
504
+ * connects.
505
+ *
506
+ * @throws WireTypesUnsupportedError when the codec does not map type names (use `jsonEnvelope`),
507
+ * WireTypeCollisionError when a name clashes with one of the codec's own `wireTypes`.
508
+ */
509
+ declareWireTypes(wireTypes: Readonly<Record<string, string>>): () => void;
495
510
  publish(envelope: EventEnvelope, destination: string): Promise<void>;
496
511
  /**
497
512
  * Binds one durable quorum queue to `destinations` and delivers its messages
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { RelayBusError, NonRetryableError, assertEventType, ConfigurationError, systemClock, toErrorInfo, computeRetryDelay, isRetryableError, createRetryPolicy } from '@relaybus/core';
2
- import { createCloudEventReaders, DecodedEventReader, mediaTypeOf, isJsonObject, observeRejection, createJsonEnvelopeFormat, SubscribingTransport, writeStructuredCloudEvent, schedule, NonEmptyText, PositiveInteger, Milliseconds } from '@relaybus/core/internal';
1
+ import { RelayBusError, NonRetryableError, assertEventType, WireTypesUnsupportedError, ConfigurationError, systemClock, toErrorInfo, computeRetryDelay, isRetryableError, createRetryPolicy } from '@relaybus/core';
2
+ import { createCloudEventReaders, DecodedEventReader, mediaTypeOf, isJsonObject, observeRejection, createJsonEnvelopeFormat, mergeWireTypes, SubscribingTransport, withDeclaredWireTypes, writeStructuredCloudEvent, schedule, NonEmptyText, PositiveInteger, Milliseconds } from '@relaybus/core/internal';
3
3
  export { fromHeader, fromPayloadField } from '@relaybus/core/internal';
4
4
 
5
5
  // src/errors.ts
@@ -780,6 +780,7 @@ function jsonEnvelope(mapping) {
780
780
  });
781
781
  const contentType = mapping.contentType ?? DEFAULT_CONTENT_TYPE;
782
782
  return {
783
+ withWireTypes: (declared) => jsonEnvelope({ ...mapping, wireTypes: mergeWireTypes(mapping, declared) }),
783
784
  encode: (envelope) => {
784
785
  assertJsonPayload(envelope.payload, envelope.id);
785
786
  assertShortString("Event id", envelope.id);
@@ -1014,11 +1015,16 @@ function resolveCodec({
1014
1015
  if (decode !== void 0 && codec !== void 0) {
1015
1016
  throw new ConfigurationError("Give 'codec' or the deprecated 'decode', not both");
1016
1017
  }
1017
- const chosen = decode === void 0 ? codec ?? cloudEventsBinary : { encode: encodeEnvelope, decode };
1018
+ return codecSettings(
1019
+ decode === void 0 ? codec ?? cloudEventsBinary : { encode: encodeEnvelope, decode }
1020
+ );
1021
+ }
1022
+ function codecSettings(chosen) {
1018
1023
  if (chosen === cloudEventsBinary) {
1019
- return { encode: encodeEnvelope, decode: decodeEnvelope };
1024
+ return { codec: chosen, encode: encodeEnvelope, decode: decodeEnvelope };
1020
1025
  }
1021
1026
  return {
1027
+ codec: chosen,
1022
1028
  encode: chosen.encode,
1023
1029
  decode: (message) => decodeRabbitMqMessage(chosen, message)
1024
1030
  };
@@ -1396,6 +1402,8 @@ var RabbitMqTransport = class extends SubscribingTransport {
1396
1402
  #live;
1397
1403
  #subscription;
1398
1404
  #closing;
1405
+ /** Set when the transport first connects, publishes or subscribes: its wire format is fixed from then on. */
1406
+ #used = false;
1399
1407
  constructor(options) {
1400
1408
  super();
1401
1409
  this.#settings = resolveSettings(options);
@@ -1426,6 +1434,7 @@ var RabbitMqTransport = class extends SubscribingTransport {
1426
1434
  }
1427
1435
  /** Connects to the broker. Rejects when it is unreachable unless `failOnConnectError` is false. */
1428
1436
  async connect() {
1437
+ this.#used = true;
1429
1438
  await this.#supervisor.start(this.#settings.failOnConnectError);
1430
1439
  }
1431
1440
  /**
@@ -1439,7 +1448,27 @@ var RabbitMqTransport = class extends SubscribingTransport {
1439
1448
  * @throws {UnroutableMessageError} no queue is bound to `destination` (unless `allowUnroutable`)
1440
1449
  * @throws whatever the `codec`'s `encode` throws, such as {@link RabbitMqUnencodableEventError}
1441
1450
  */
1451
+ /**
1452
+ * Checks the wire names a route or catalog declares and returns the function that makes the codec
1453
+ * write and read events under them. The bus calls it when it is created, before the transport
1454
+ * connects.
1455
+ *
1456
+ * @throws WireTypesUnsupportedError when the codec does not map type names (use `jsonEnvelope`),
1457
+ * WireTypeCollisionError when a name clashes with one of the codec's own `wireTypes`.
1458
+ */
1459
+ declareWireTypes(wireTypes) {
1460
+ if (this.#used) {
1461
+ throw new WireTypesUnsupportedError(
1462
+ `Transport '${this.name}' already started; declare wire names before it connects or subscribes`
1463
+ );
1464
+ }
1465
+ const codec = withDeclaredWireTypes(this.#settings.codec, { wireTypes, transport: this.name });
1466
+ return () => {
1467
+ this.#settings = { ...this.#settings, ...codecSettings(codec) };
1468
+ };
1469
+ }
1442
1470
  async publish(envelope, destination) {
1471
+ this.#used = true;
1443
1472
  assertShortString("Destination (routing key)", destination);
1444
1473
  const { content, options } = this.#settings.encode(envelope);
1445
1474
  await this.#publishing.publish(this.#live?.publisher, {
@@ -1460,6 +1489,7 @@ var RabbitMqTransport = class extends SubscribingTransport {
1460
1489
  onMessage,
1461
1490
  hooks
1462
1491
  }) {
1492
+ this.#used = true;
1463
1493
  if (this.#subscription !== void 0) {
1464
1494
  throw new ConfigurationError(
1465
1495
  `Transport '${this.name}' already has a subscription; create another transport for another consumer group`
@@ -1525,6 +1555,7 @@ var RabbitMqTransport = class extends SubscribingTransport {
1525
1555
  * the connection's socket is destroyed instead of waiting for the broker.
1526
1556
  */
1527
1557
  async close(options = {}) {
1558
+ this.#used = true;
1528
1559
  const { signal } = options;
1529
1560
  const force = () => this.#supervisor.forceClose();
1530
1561
  if (signal?.aborted === true) {