@warlock.js/herald 5.29.0 → 5.31.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 (69) hide show
  1. package/CHANGELOG.md +15 -2
  2. package/README.md +17 -16
  3. package/cjs/index.cjs +10 -10
  4. package/cjs/index.cjs.map +1 -1
  5. package/esm/communicators/broker-registry.d.mts +1 -1
  6. package/esm/communicators/broker-registry.d.mts.map +1 -1
  7. package/esm/communicators/broker-registry.mjs +1 -1
  8. package/esm/communicators/broker-registry.mjs.map +1 -1
  9. package/esm/communicators/broker.d.mts +1 -1
  10. package/esm/communicators/broker.d.mts.map +1 -1
  11. package/esm/communicators/broker.mjs +1 -1
  12. package/esm/communicators/broker.mjs.map +1 -1
  13. package/esm/contracts/broker-driver.contract.d.mts +1 -1
  14. package/esm/contracts/broker-driver.contract.d.mts.map +1 -1
  15. package/esm/contracts/channel.contract.d.mts +1 -1
  16. package/esm/contracts/channel.contract.d.mts.map +1 -1
  17. package/esm/decorators/consumable.d.mts +1 -1
  18. package/esm/decorators/consumable.d.mts.map +1 -1
  19. package/esm/decorators/consumable.mjs +1 -1
  20. package/esm/decorators/consumable.mjs.map +1 -1
  21. package/esm/drivers/rabbitmq/rabbitmq-channel.d.mts +1 -1
  22. package/esm/drivers/rabbitmq/rabbitmq-channel.d.mts.map +1 -1
  23. package/esm/drivers/rabbitmq/rabbitmq-channel.mjs +1 -1
  24. package/esm/drivers/rabbitmq/rabbitmq-channel.mjs.map +1 -1
  25. package/esm/drivers/rabbitmq/rabbitmq-driver.d.mts +1 -1
  26. package/esm/drivers/rabbitmq/rabbitmq-driver.d.mts.map +1 -1
  27. package/esm/drivers/rabbitmq/rabbitmq-driver.mjs +1 -1
  28. package/esm/drivers/rabbitmq/rabbitmq-driver.mjs.map +1 -1
  29. package/esm/message-managers/event-consumer.d.mts +1 -1
  30. package/esm/message-managers/event-consumer.d.mts.map +1 -1
  31. package/esm/message-managers/event-consumer.mjs +1 -1
  32. package/esm/message-managers/event-consumer.mjs.map +1 -1
  33. package/esm/message-managers/event-message.d.mts +1 -1
  34. package/esm/message-managers/event-message.d.mts.map +1 -1
  35. package/esm/message-managers/event-message.mjs +1 -1
  36. package/esm/message-managers/event-message.mjs.map +1 -1
  37. package/esm/message-managers/prepare-consumer-subscription.mjs +1 -1
  38. package/esm/message-managers/prepare-consumer-subscription.mjs.map +1 -1
  39. package/esm/message-managers/types.d.mts +1 -1
  40. package/esm/message-managers/types.d.mts.map +1 -1
  41. package/esm/types/channel.types.d.mts +2 -2
  42. package/esm/types/channel.types.d.mts.map +1 -1
  43. package/esm/types/connection.types.d.mts +1 -1
  44. package/esm/types/connection.types.d.mts.map +1 -1
  45. package/esm/types/driver.types.d.mts +1 -1
  46. package/esm/types/driver.types.d.mts.map +1 -1
  47. package/esm/types/message.types.d.mts +1 -1
  48. package/esm/types/message.types.d.mts.map +1 -1
  49. package/esm/types/publish.types.d.mts +1 -1
  50. package/esm/types/publish.types.d.mts.map +1 -1
  51. package/esm/types/registry.types.d.mts +1 -1
  52. package/esm/types/registry.types.d.mts.map +1 -1
  53. package/esm/types/subscribe.types.d.mts +1 -1
  54. package/esm/types/subscribe.types.d.mts.map +1 -1
  55. package/esm/use-case-broadcast.d.mts +1 -1
  56. package/esm/use-case-broadcast.d.mts.map +1 -1
  57. package/esm/use-case-broadcast.mjs +1 -1
  58. package/esm/use-case-broadcast.mjs.map +1 -1
  59. package/esm/utils/connect-to-broker.d.mts +1 -1
  60. package/esm/utils/connect-to-broker.d.mts.map +1 -1
  61. package/esm/utils/connect-to-broker.mjs +1 -1
  62. package/esm/utils/connect-to-broker.mjs.map +1 -1
  63. package/llms-full.txt +62 -57
  64. package/package.json +5 -4
  65. package/skills/consume-message/SKILL.md +30 -28
  66. package/skills/herald-basics/SKILL.md +8 -8
  67. package/skills/index.md +4 -1
  68. package/skills/publish-message/SKILL.md +19 -16
  69. package/skills/request-and-respond/SKILL.md +5 -5
package/skills/index.md CHANGED
@@ -1,17 +1,20 @@
1
1
  ---
2
- description: "Message bus over RabbitMQ (Kafka planned): publish, subscribe, and request-response between services. Exports `connectToBroker`, `herald`, `heraldChannel`, `Broker`, `defineEvent`, `defineConsumer`, `EventMessage`, `EventConsumer`, `Consumable`, `brokerRegistry`. Use for: \"publish an event to RabbitMQ\", \"subscribe to a channel\", \"ack or nack a message\", \"request and reply over the bus\", \"cross-service messaging\". Not this package: durable retried background jobs on Redis → @warlock.js/queue; cron/recurring work → @warlock.js/scheduler."
2
+ description: 'Message bus over RabbitMQ (Kafka planned): publish, subscribe, and request-response between services. Exports `connectToBroker`, `herald`, `heraldChannel`, `Broker`, `defineEvent`, `defineConsumer`, `EventMessage`, `EventConsumer`, `Consumable`, `brokerRegistry`. Use for: "publish an event to RabbitMQ", "subscribe to a channel", "ack or nack a message", "request and reply over the bus", "cross-service messaging". Not this package: durable retried background jobs on Redis → @warlock.js/queue; cron/recurring work → @warlock.js/scheduler.'
3
3
  ---
4
+
4
5
  # @warlock.js/herald
5
6
 
6
7
  Herald is the broker-agnostic message bus. `connectToBroker(config)` boots a broker once; `herald()` returns it (`herald("name")` for a named one); `.channel(name)` is the queue/topic you publish into and subscribe from. Channels are typed with generics and can validate with a seal schema. Server-only.
7
8
 
8
9
  ## The 80% path
10
+
9
11
  1. Orient with `herald-basics.md` (the map and foundations).
10
12
  2. Connect at startup, then publish: `publish-message.md`.
11
13
  3. Consume with `subscribe` handlers or consumer classes: `consume-message.md`.
12
14
  4. Need a reply? `request-and-respond.md`.
13
15
 
14
16
  ## Conventions and pitfalls
17
+
15
18
  - Call `connectToBroker` once before any publish or subscribe.
16
19
  - Smart auto-ack is the default: a clean return acks, a throw nacks with requeue. `autoAck: true` loses messages on a crash; avoid it.
17
20
  - Use `ctx.reject()` / `ctx.retry(ms)` only for a non-default outcome.
@@ -27,8 +27,8 @@ type UserPayload = { userId: number; email: string };
27
27
 
28
28
  const channel = herald().channel<UserPayload>("user.created");
29
29
 
30
- await channel.publish({ userId: 1, email: "test@example.com" }); // ✅ typed
31
- await channel.publish({ userId: "1" } as never); // ❌ compile error
30
+ await channel.publish({ userId: 1, email: "test@example.com" }); // ✅ typed
31
+ await channel.publish({ userId: "1" } as never); // ❌ compile error
32
32
  ```
33
33
 
34
34
  Share the payload type between producer and consumer via a common `types/` file.
@@ -45,7 +45,7 @@ const userSchema = v.object({
45
45
 
46
46
  const channel = herald().channel("user.created", { schema: userSchema });
47
47
 
48
- await channel.publish({ userId: 1, email: "invalid" }); // Throws — fails .email()
48
+ await channel.publish({ userId: 1, email: "invalid" }); // Throws — fails .email()
49
49
  ```
50
50
 
51
51
  The schema runs `validate()` before the message hits the broker. Invalid payloads never leave the producer. See the `seal-basics` topic of the `warlock-js-seal` skill.
@@ -54,10 +54,10 @@ The schema runs `validate()` before the message hits the broker. Invalid payload
54
54
 
55
55
  ```ts
56
56
  await channel.publish(payload, {
57
- priority: 5, // 0-9, higher = served first
58
- expiration: 60_000, // ms — message expires if not consumed (RabbitMQ uses `expiration`, not `ttl`)
59
- delay: 5_000, // ms — delayed delivery (requires RabbitMQ delay plugin)
60
- persistent: true, // survive broker restart (default true)
57
+ priority: 5, // 0-9, higher = served first
58
+ expiration: 60_000, // ms — message expires if not consumed (RabbitMQ uses `expiration`, not `ttl`)
59
+ delay: 5_000, // ms — delayed delivery (requires RabbitMQ delay plugin)
60
+ persistent: true, // survive broker restart (default true)
61
61
  correlationId: "uuid", // for tracking across services
62
62
  headers: {
63
63
  tenantId: "42",
@@ -71,14 +71,17 @@ The headers field is free-form — consumers read `message.metadata.headers?.ten
71
71
  ## Batch publishing
72
72
 
73
73
  ```ts
74
- await channel.publishBatch([
75
- { userId: 1, email: "a@example.com" },
76
- { userId: 2, email: "b@example.com" },
77
- { userId: 3, email: "c@example.com" },
78
- ], {
79
- // Options apply to every message in the batch
80
- persistent: true,
81
- });
74
+ await channel.publishBatch(
75
+ [
76
+ { userId: 1, email: "a@example.com" },
77
+ { userId: 2, email: "b@example.com" },
78
+ { userId: 3, email: "c@example.com" },
79
+ ],
80
+ {
81
+ // Options apply to every message in the batch
82
+ persistent: true,
83
+ },
84
+ );
82
85
  ```
83
86
 
84
87
  Under the hood `publishBatch` iterates and calls `.publish()` per message — there's no AMQP-level batching today. It's an ergonomic shape for "emit these N items" (bulk import, fanout to many recipients), not a throughput optimization. The same `options` apply to every message.
@@ -128,7 +131,7 @@ export default {
128
131
  ```ts
129
132
  // The use case opts in — channel name defaults to the use case name.
130
133
  export const createUserUseCase = useCase({
131
- name: "users.create", // → publishes to channel "users.create"
134
+ name: "users.create", // → publishes to channel "users.create"
132
135
  schema: createUserSchema,
133
136
  handler: async (data) => User.create(data),
134
137
  broadcast: true,
@@ -36,12 +36,12 @@ The promise rejects if no reply arrives within `timeout` ms. Pick a sane number
36
36
 
37
37
  ## When to use it vs HTTP
38
38
 
39
- | Use HTTP | Use request/respond |
40
- | --- | --- |
39
+ | Use HTTP | Use request/respond |
40
+ | ------------------------------- | ------------------------------------------- |
41
41
  | Stateless, fast, idempotent ops | Slow / queued ops where the caller can wait |
42
- | Public API surface | Internal service-to-service |
43
- | Frontend consumption | Backend orchestration |
44
- | Synchronous user-facing flow | Async-but-needs-result patterns |
42
+ | Public API surface | Internal service-to-service |
43
+ | Frontend consumption | Backend orchestration |
44
+ | Synchronous user-facing flow | Async-but-needs-result patterns |
45
45
 
46
46
  The bus adds queue persistence and retry. HTTP is faster for sub-100ms ops; the bus shines when the operation has variable duration or needs a queue's backpressure.
47
47