@owlmeans/queue 0.1.18-rc.11 → 0.1.18-rc.13

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
@@ -44,16 +44,17 @@ same binary run as a producer in one deployment and a worker in another.
44
44
  ## Declaring a queued entrypoint
45
45
 
46
46
  ```typescript
47
+ import { contract, protocol, typed } from '@owlmeans/entrypoint'
47
48
  import { job } from '@owlmeans/route'
48
49
 
49
- entrypoint(
50
+ protocol(
50
51
  route(agent.story.develop, '/:id/develop',
51
52
  job({ parent: agent.story.base, service: AGENT, queue: AGENT_WORK, timeout: 30_000 })),
52
- filter(params(StoryParamsSchema))
53
+ contract.request({ params: typed<StoryParams>(StoryParamsSchema) }, typed()),
53
54
  )
54
55
  ```
55
56
 
56
- It is served with `elevate(...)` and called with `call()` like any backend entrypoint. Add
57
+ It is served by binding its shared job protocol and called with `call()` like any backend entrypoint. Add
57
58
  `reply: false` to return as soon as the job is accepted — the call resolves `Accepted` with
58
59
  `{ id, queue }`, which is what a long pipeline wants.
59
60
 
@@ -132,7 +133,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
132
133
  your project's skill store (`.agents/skills/`):
133
134
 
134
135
  ```sh
135
- npx @owlmeans/agent-skills@^0.1.18-rc.14
136
+ npx @owlmeans/agent-skills@^0.1.18-rc.16
136
137
  ```
137
138
 
138
139
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/queue",
4
- "version": "0.1.18-rc.11",
5
- "generatedAt": "2026-09-10T23:12:07.519Z",
4
+ "version": "0.1.18-rc.13",
5
+ "generatedAt": "2026-09-12T12:32:46.383Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: queue
3
- description: How to use @owlmeans/queue — job queues as resources, the QUEUE route protocol that makes a queued call indistinguishable from an HTTP one, declaring queues and job names, the producer/consumer split, job graphs, envelope freshness, and the rules a processor must follow. Auto-invoked when importing queue types or declaring a job route.
3
+ description: How to use @owlmeans/queue — protocol-object enqueue/wait, job queues as resources, QUEUE declarations, producer/consumer split, single-flight job ids, lifecycle hooks, and processor rules. Auto-invoked when importing queue types or declaring a job protocol.
4
4
  user-invocable: false
5
5
  ---
6
6
  <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
@@ -8,7 +8,7 @@ user-invocable: false
8
8
  # @owlmeans/queue
9
9
 
10
10
  **Layer:** Infra
11
- **Install:** `"@owlmeans/queue": "^0.1.18-rc.11"` in `dependencies`
11
+ **Install:** `"@owlmeans/queue": "^0.1.18-rc.13"` in `dependencies`
12
12
 
13
13
  Contracts only. It carries no broker code — a driver package (`@owlmeans/redis-queue`) implements
14
14
  them. Depend on this one from a shared contract package; depend on the driver only where the
@@ -16,9 +16,11 @@ application wires itself up.
16
16
 
17
17
  ## The one idea
18
18
 
19
- A queued call is an ordinary entrypoint call. The route names `RouteProtocols.QUEUE`, the
20
- transport registered under that protocol takes it, and the caller writes `ep.call(...)` exactly as
21
- for HTTP. Nothing at a call site says "queue".
19
+ A queued call is an immutable entrypoint protocol whose route names `RouteProtocols.QUEUE`.
20
+ Ordinary calls use `ctx.entrypoint(protocol).call(request)`. Code that needs broker options or a
21
+ job handle uses `enqueueProtocol(ctx, protocol, request, options)` and
22
+ `waitForProtocol(ctx, protocol, job)`. Both derive queue and job name from the protocol object and
23
+ preserve its exact request/reply pair; raw strings and non-QUEUE declarations are rejected.
22
24
 
23
25
  That is what makes it worth having: moving a service-to-service call onto the broker is a change
24
26
  to a declaration, not to the places that call it, and the broker holds the work across a restart of
@@ -30,7 +32,7 @@ Queues and the jobs they accept live in the SHARED backend package, so producers
30
32
  read one list:
31
33
 
32
34
  ```typescript
33
- declareQueue(cfg, AGENT_WORK, ['agent:story:develop', 'agent:story:code'], {
35
+ declareQueue(cfg, AGENT_WORK, [story.develop.alias], {
34
36
  worker: { concurrency: 3, lockDuration: 60_000 }
35
37
  })
36
38
  ```
@@ -48,16 +50,32 @@ listenQueues(cfg, AGENT_WORK, AGENT_OPS) // absent ⇒ producer only
48
50
  Keep them apart. A declaration is an address; `listen` is a deployment fact. If a worker bound
49
51
  whatever it could serve, every deployment of the same binary would consume everything it imports.
50
52
 
51
- A queued entrypoint is declared like any other, with `job()` in place of `backend()`:
53
+ A queued entrypoint is an immutable protocol with `job()` in place of `backend()`:
52
54
 
53
55
  ```typescript
54
- entrypoint(
56
+ protocol(
55
57
  route(agent.story.develop, '/:id/develop',
56
58
  job({ parent: agent.story.base, service: AGENT, queue: AGENT_WORK, timeout: 30_000 })),
57
- filter(params(StoryParamsSchema))
59
+ contract.request({ params: typed<StoryParams>(StoryParamsSchema) }, typed()),
58
60
  )
59
61
  ```
60
62
 
63
+ The alias appears in `declareQueue(...jobs)` only because the broker is a string-keyed adapter.
64
+ Application producers and handlers keep the protocol object.
65
+
66
+ When an admission record owns single flight, select the job id atomically first, then enqueue it:
67
+
68
+ ```typescript
69
+ const queued = await enqueueProtocol(context, tokenBalance.reconcile, {
70
+ body: { projectionId },
71
+ }, { id: claimId, delay: 250, attempts: 3, backoff: { type: 'exponential', delay: 250 } })
72
+ const result = await waitForProtocol(context, tokenBalance.reconcile, queued)
73
+ ```
74
+
75
+ Per-call `id`, delay, attempts, backoff and retention belong here; putting them into an alias-based
76
+ helper forfeits protocol inference. `queueJobOf(request)` exposes `{ id, name, queue, attempt }` to
77
+ the rare protocol handler that must compare a broker job with its persisted claim.
78
+
61
79
  `reply: false` makes it fire-and-forget: the call resolves `Accepted` with `{ id, queue }` as soon
62
80
  as the BROKER has accepted the enqueue — before any worker has picked the job up, so the resolution
63
81
  says the job exists and nothing about it having started. That is what a long pipeline wants; watch
@@ -162,6 +180,8 @@ listens to, grouped by queue, which is what a driver binds.
162
180
 
163
181
  | Export | Description |
164
182
  |--------|-------------|
183
+ | `enqueueProtocol` / `waitForProtocol` | Typed protocol-object enqueue and result wait; validates protocol kind and queue configuration. |
184
+ | `queueJobOf(request)` / `QueueJobMeta` | Explicit broker identity boundary for a protocol handler, including `touch()` for long work. |
165
185
  | `declareQueue` / `listenQueues` | Configuration — what exists, and what this process consumes |
166
186
  | `queueOf` / `queueOfJob` / `isListening` | Reading it back; `queueOf` throws `UnknownQueue` |
167
187
  | `QueueConfig` / `QueueDeclaration` / `QueueWorkerOptions` / `JobOptions` | The configuration shapes |
@@ -193,5 +213,5 @@ listens to, grouped by queue, which is what a driver binds.
193
213
  - `redis-queue` — the BullMQ driver; integration tests for queue behaviour live there
194
214
  - `server-job` / `client-job` — exposing a queue's jobs to an application's UI (list, cancel,
195
215
  progress over a socket), without touching the contracts here
196
- - `entrypoint` — declarations, elevation, and the transport lookup
216
+ - `entrypoint` — protocol declarations, bindings, and the transport lookup
197
217
  - `resource` — the criteria and paging semantics `list` follows
package/build/bridge.d.ts CHANGED
@@ -1,11 +1,13 @@
1
1
  import type { AbstractRequest } from '@owlmeans/entrypoint';
2
2
  import type { BasicContext } from '@owlmeans/context';
3
- import type { Config, Context, JobContext, JobEnvelope, JobReply } from './types.js';
3
+ import type { Config, Context, JobContext, JobEnvelope, JobReply, QueueJobMeta } from './types.js';
4
4
  /**
5
5
  * Rebuild the request the producer described. A queued call is still a call: the same guards, the
6
6
  * same filter, the same handler run against it — only the wire is different.
7
7
  */
8
- export declare const requestOf: (envelope: JobEnvelope, path: string, context?: BasicContext<any>) => AbstractRequest;
8
+ export declare const requestOf: (envelope: JobEnvelope, path: string, context?: BasicContext<any>, job?: QueueJobMeta) => AbstractRequest;
9
+ /** Read broker identity only where an entrypoint truly needs to bind work to an admission claim. */
10
+ export declare const queueJobOf: (request: unknown) => QueueJobMeta | null;
9
11
  /**
10
12
  * Freshness is judged from when the job was ENQUEUED, not from now.
11
13
  *
@@ -1 +1 @@
1
- {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAkC,MAAM,sBAAsB,CAAA;AAC3F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAMrD,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAGpF;;;GAGG;AACH,eAAO,MAAM,SAAS,aACV,WAAW,QAAQ,MAAM,YAAY,YAAY,CAAC,GAAG,CAAC,KAC/D,eAWD,CAAA;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,aAAc,WAAW,QAAQ,MAAM,KAAG,IAQjE,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,GAAU,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,WAC3D,CAAC,OAAO,UAAU,CAAC,WAAW,CAAC,KACvC,OAAO,CAAC,QAAQ,CAyDlB,CAAA"}
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAkC,MAAM,sBAAsB,CAAA;AAC3F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAMrD,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAGlG;;;GAGG;AACH,eAAO,MAAM,SAAS,aACV,WAAW,QAAQ,MAAM,YAAY,YAAY,CAAC,GAAG,CAAC,QAAQ,YAAY,KACnF,eAWD,CAAA;AAEF,oGAAoG;AACpG,eAAO,MAAM,UAAU,YAAa,OAAO,KAAG,YAAY,GAAG,IAK5D,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,aAAc,WAAW,QAAQ,MAAM,KAAG,IAQjE,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,GAAU,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,WAC3D,CAAC,OAAO,UAAU,CAAC,WAAW,CAAC,KACvC,OAAO,CAAC,QAAQ,CA2DlB,CAAA"}
package/build/bridge.js CHANGED
@@ -7,7 +7,7 @@ import { EnvelopeExpired, JobNotServed } from './errors.js';
7
7
  * Rebuild the request the producer described. A queued call is still a call: the same guards, the
8
8
  * same filter, the same handler run against it — only the wire is different.
9
9
  */
10
- export const requestOf = (envelope, path, context) => ({
10
+ export const requestOf = (envelope, path, context, job) => ({
11
11
  alias: envelope.alias,
12
12
  params: (envelope.params ?? {}),
13
13
  body: envelope.body,
@@ -17,8 +17,17 @@ export const requestOf = (envelope, path, context) => ({
17
17
  // Handlers reach their context through `original._ctx`, which the HTTP boundary sets on the raw
18
18
  // Fastify request. There is no raw request here, so the shape is supplied deliberately — a
19
19
  // handler must not have to know which transport delivered it.
20
- original: context != null ? { _ctx: context } : undefined,
20
+ original: context != null || job != null ? { _ctx: context, _job: job } : undefined,
21
21
  });
22
+ /** Read broker identity only where an entrypoint truly needs to bind work to an admission claim. */
23
+ export const queueJobOf = (request) => {
24
+ if (request == null || typeof request !== 'object' || !('original' in request))
25
+ return null;
26
+ const original = request.original;
27
+ if (original == null || typeof original !== 'object' || !('_job' in original))
28
+ return null;
29
+ return original._job ?? null;
30
+ };
22
31
  /**
23
32
  * Freshness is judged from when the job was ENQUEUED, not from now.
24
33
  *
@@ -53,7 +62,9 @@ export const handleJob = async (context, job) => {
53
62
  if (entrypoint.handle == null) {
54
63
  throw new JobNotServed(envelope.alias);
55
64
  }
56
- const request = requestOf(envelope, entrypoint.path(), context);
65
+ const request = requestOf(envelope, entrypoint.path(), context, {
66
+ id: job.id, name: job.name, queue: job.queue, attempt: job.attempt, touch: job.touch,
67
+ });
57
68
  const response = provideResponse();
58
69
  const guards = entrypoint.getGuards();
59
70
  if (guards.length > 0) {
@@ -1 +1 @@
1
- {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
package/build/errors.d.ts CHANGED
@@ -40,7 +40,7 @@ export declare class QueueNotListening extends QueueError {
40
40
  }
41
41
  /**
42
42
  * The job named an entrypoint this process does not serve. Unlike a missing queue this is not a
43
- * declaration problem: the alias exists, but nothing here elevated it, so the job was taken by a
43
+ * declaration problem: the alias exists, but nothing here bound it, so the job was taken by a
44
44
  * worker that cannot run it.
45
45
  */
46
46
  export declare class JobNotServed extends QueueError {
package/build/errors.js CHANGED
@@ -57,7 +57,7 @@ export class QueueNotListening extends QueueError {
57
57
  }
58
58
  /**
59
59
  * The job named an entrypoint this process does not serve. Unlike a missing queue this is not a
60
- * declaration problem: the alias exists, but nothing here elevated it, so the job was taken by a
60
+ * declaration problem: the alias exists, but nothing here bound it, so the job was taken by a
61
61
  * worker that cannot run it.
62
62
  */
63
63
  export class JobNotServed extends QueueError {
package/build/index.d.ts CHANGED
@@ -5,4 +5,5 @@ export * from './config.js';
5
5
  export * from './transport.js';
6
6
  export * from './bridge.js';
7
7
  export * from './worker.js';
8
+ export * from './protocol.js';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA"}
package/build/index.js CHANGED
@@ -5,4 +5,5 @@ export * from './config.js';
5
5
  export * from './transport.js';
6
6
  export * from './bridge.js';
7
7
  export * from './worker.js';
8
+ export * from './protocol.js';
8
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA"}
@@ -0,0 +1,11 @@
1
+ import type { EntrypointProtocolDeclaration, RequestOf, ResponseOf } from '@owlmeans/entrypoint';
2
+ import type { Config, Context, JobEnvelope, JobOptions, JobRecord, JobReply, QueueAppend } from './types.js';
3
+ type QueueContext = Context<Config> & QueueAppend;
4
+ /** Enqueue an immutable QUEUE protocol while preserving its exact request and response types. */
5
+ export declare const enqueueProtocol: <Protocol extends EntrypointProtocolDeclaration>(context: QueueContext, declaration: Protocol, request: RequestOf<Protocol>, options?: JobOptions) => Promise<JobRecord<JobEnvelope, JobReply<ResponseOf<Protocol>>>>;
6
+ /** Wait for a protocol job and unwrap the typed entrypoint reply. */
7
+ export declare const waitForProtocol: <Protocol extends EntrypointProtocolDeclaration>(context: QueueContext, declaration: Protocol, job: string | JobRecord<JobEnvelope, JobReply<ResponseOf<Protocol>>>, options?: {
8
+ timeout?: number;
9
+ }) => Promise<ResponseOf<Protocol>>;
10
+ export {};
11
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAMhG,OAAO,KAAK,EACV,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAC3E,MAAM,YAAY,CAAA;AAEnB,KAAK,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,WAAW,CAAA;AAuBjD,iGAAiG;AACjG,eAAO,MAAM,eAAe,GAAU,QAAQ,SAAS,6BAA6B,WACzE,YAAY,eACR,QAAQ,WACZ,SAAS,CAAC,QAAQ,CAAC,YAClB,UAAU,KACnB,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAkBhE,CAAA;AAED,qEAAqE;AACrE,eAAO,MAAM,eAAe,GAAU,QAAQ,SAAS,6BAA6B,WACzE,YAAY,eACR,QAAQ,OAChB,MAAM,GAAG,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,YAC1D;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,KAC7B,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAe9B,CAAA"}
@@ -0,0 +1,59 @@
1
+ import { isEntrypointProtocol } from '@owlmeans/entrypoint';
2
+ import { ResilientError } from '@owlmeans/error';
3
+ import { RouteProtocols } from '@owlmeans/route';
4
+ import { queueOf } from './config.js';
5
+ import { UnknownQueue } from './errors.js';
6
+ const queueFor = (context, declaration) => {
7
+ if (declaration == null || typeof declaration !== 'object' || !isEntrypointProtocol(declaration)) {
8
+ throw new UnknownQueue('protocol declaration required');
9
+ }
10
+ if (declaration.route.route.protocol !== RouteProtocols.QUEUE) {
11
+ throw new UnknownQueue(`${declaration.alias}: not a QUEUE protocol`);
12
+ }
13
+ const queue = declaration.route.route.queue;
14
+ if (queue == null) {
15
+ throw new UnknownQueue(`${declaration.alias}: route declares no queue`);
16
+ }
17
+ const configured = queueOf(context.cfg, queue);
18
+ if (!configured.jobs.includes(declaration.alias)) {
19
+ throw new UnknownQueue(`${queue}:${declaration.alias}`);
20
+ }
21
+ return { protocol: declaration, queue };
22
+ };
23
+ /** Enqueue an immutable QUEUE protocol while preserving its exact request and response types. */
24
+ export const enqueueProtocol = async (context, declaration, request, options) => {
25
+ const { protocol, queue } = queueFor(context, declaration);
26
+ const shaped = (request ?? {});
27
+ const envelope = {
28
+ alias: protocol.alias,
29
+ params: shaped.params,
30
+ body: shaped.body,
31
+ query: shaped.query,
32
+ headers: shaped.headers,
33
+ enqueuedAt: new Date().toISOString(),
34
+ };
35
+ return await context.jobs(queue).create({
36
+ queue,
37
+ name: protocol.alias,
38
+ data: envelope,
39
+ opts: options,
40
+ });
41
+ };
42
+ /** Wait for a protocol job and unwrap the typed entrypoint reply. */
43
+ export const waitForProtocol = async (context, declaration, job, options) => {
44
+ const { protocol, queue } = queueFor(context, declaration);
45
+ if (typeof job !== 'string' && (job.queue !== queue || job.name !== protocol.alias)) {
46
+ throw new UnknownQueue(`${job.queue}:${job.name}`);
47
+ }
48
+ const id = typeof job === 'string' ? job : job.id;
49
+ if (id == null) {
50
+ throw new UnknownQueue(`${queue}:${protocol.alias}: missing job id`);
51
+ }
52
+ const reply = await context.jobs(queue)
53
+ .wait(id, options);
54
+ if (reply.error != null) {
55
+ throw ResilientError.ensure(reply.error);
56
+ }
57
+ return reply.value;
58
+ };
59
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
package/build/types.d.ts CHANGED
@@ -201,6 +201,14 @@ export interface JobEnvelope {
201
201
  /** When the producer enqueued it — freshness is judged here, not at processing time. */
202
202
  enqueuedAt?: string;
203
203
  }
204
+ export interface QueueJobMeta {
205
+ id: string;
206
+ name: string;
207
+ queue: string;
208
+ attempt: number;
209
+ /** Renew the broker lock for protocol handlers whose work can outlive one lock duration. */
210
+ touch: () => Promise<void>;
211
+ }
204
212
  /** What a processor returns for an entrypoint job, so the caller can rebuild the reply. */
205
213
  export interface JobReply<T = unknown> {
206
214
  value?: T;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AACtF,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAClF,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEzD;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC3B,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,sFAAsF;IACtF,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,QAAQ,CAAC,EAAE,UAAU,CAAA;IACrB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,MAAM,CAAC,EAAE,kBAAkB,CAAA;IAC3B,QAAQ,CAAC,EAAE,UAAU,CAAA;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,OAAO,GAAG,aAAa,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,gBAAgB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IACnC,YAAY,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAChC;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,CAAE,SAAQ,cAAc;IACzE,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,CAAC,CAAA;IACP,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,MAAM,CAAC,EAAE,CAAC,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,UAAU,CAAA;CAClB;AAED,MAAM,WAAW,QAAQ,CAAC,CAAC,GAAG,OAAO;IACnC,IAAI,EAAE,YAAY,CAAA;IAClB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,CAAC,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,wEAAwE;AACxE,MAAM,WAAW,QAAQ,CAAC,CAAC,GAAG,OAAO;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,CAAC,CAAA;IACP,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAA;CACtB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,CACrD,SAAQ,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC9D,KAAK,EAAE,MAAM,CAAA;IACb;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B;;;;OAIG;IACH,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;IAC7D,0FAA0F;IAC1F,IAAI,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IACrD,MAAM,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAA;CAChD;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC,GAAG,OAAO;IACrC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,CAAC,CAAA;IACP,MAAM,EAAE,WAAW,CAAA;IACnB;;;;OAIG;IACH,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3C;;;;;;OAMG;IACH,QAAQ,EAAE,CAAC,CAAC,GAAG,OAAO,OAAO,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAA;IACvD,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CACtD;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO;IACpD,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CACjC;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAmB,SAAQ,kBAAkB;IAC5D,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAA;IACnF,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB,sEAAsE;IACtE,SAAS,EAAE,MAAM,MAAM,EAAE,CAAA;IACzB;;;;;;;OAOG;IACH,KAAK,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;CACnC;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;IAC5C,wFAAwF;IACxF,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,4FAA4F;IAC5F,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3B;AAED,2FAA2F;AAC3F,MAAM,WAAW,QAAQ,CAAC,CAAC,GAAG,OAAO;IACnC,KAAK,CAAC,EAAE,CAAC,CAAA;IACT,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACjF,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,KAAK,EAAE,SAAS,GAAG,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvH;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACrE;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACtD,MAAM,EAAE,MAAM,kBAAkB,CAAA;CACjC;AAED,MAAM,WAAW,MAAO,SAAQ,WAAW;IACzC,KAAK,CAAC,EAAE,WAAW,CAAA;CACpB;AAED,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,YAAY,CAAC,CAAC,CAAC;CAC1E;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;CACxE;AAED,MAAM,WAAW,qBAAsB,SAAQ,eAAe;CAC7D;AAED,MAAM,WAAW,sBAAuB,SAAQ,gBAAgB,CAAC,OAAO,CAAC;CACxE"}
package/build/worker.d.ts CHANGED
@@ -5,7 +5,7 @@ import type { Config, Context, JobEnvelope, JobProcessor } from './types.js';
5
5
  * Every queued entrypoint this process both SERVES and LISTENS to, grouped by queue.
6
6
  *
7
7
  * Both halves are required and they answer different questions. Serving is about code — the alias
8
- * was elevated here, so a handler exists. Listening is about deployment — this process was
8
+ * was bound here, so a handler exists. Listening is about deployment — this process was
9
9
  * configured to consume that queue. A worker that bound queues by what it can serve would make
10
10
  * every deployment of the same binary a worker for everything it happens to import.
11
11
  */
package/build/worker.js CHANGED
@@ -6,7 +6,7 @@ import { DEFAULT_ALIAS } from './consts.js';
6
6
  * Every queued entrypoint this process both SERVES and LISTENS to, grouped by queue.
7
7
  *
8
8
  * Both halves are required and they answer different questions. Serving is about code — the alias
9
- * was elevated here, so a handler exists. Listening is about deployment — this process was
9
+ * was bound here, so a handler exists. Listening is about deployment — this process was
10
10
  * configured to consume that queue. A worker that bound queues by what it can serve would make
11
11
  * every deployment of the same binary a worker for everything it happens to import.
12
12
  */
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@owlmeans/queue",
3
- "version": "0.1.18-rc.11",
3
+ "version": "0.1.18-rc.13",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "build": "tsc -b",
8
8
  "dev": "sleep 234 && nodemon -e ts,tsx,json --watch src --exec \"tsc -p ./tsconfig.json\"",
9
- "watch": "tsc -b -w --preserveWatchOutput --pretty"
9
+ "watch": "tsc -b -w --preserveWatchOutput --pretty",
10
+ "test": "bun test ./tests"
10
11
  },
11
12
  "main": "build/index.js",
12
13
  "module": "build/index.js",
@@ -30,12 +31,12 @@
30
31
  "access": "public"
31
32
  },
32
33
  "dependencies": {
33
- "@owlmeans/auth": "^0.1.18-rc.11",
34
- "@owlmeans/auth-common": "^0.1.18-rc.15",
35
- "@owlmeans/context": "^0.1.18-rc.10",
36
- "@owlmeans/entrypoint": "^0.1.18-rc.13",
37
- "@owlmeans/error": "^0.1.18-rc.10",
38
- "@owlmeans/resource": "^0.1.18-rc.11",
39
- "@owlmeans/route": "^0.1.18-rc.11"
34
+ "@owlmeans/auth": "^0.1.18-rc.13",
35
+ "@owlmeans/auth-common": "^0.1.18-rc.17",
36
+ "@owlmeans/context": "^0.1.18-rc.12",
37
+ "@owlmeans/entrypoint": "^0.1.18-rc.15",
38
+ "@owlmeans/error": "^0.1.18-rc.12",
39
+ "@owlmeans/resource": "^0.1.18-rc.13",
40
+ "@owlmeans/route": "^0.1.18-rc.13"
40
41
  }
41
42
  }
package/src/bridge.ts CHANGED
@@ -5,7 +5,7 @@ import type { Auth } from '@owlmeans/auth'
5
5
  import { AuthorizationError } from '@owlmeans/auth'
6
6
  import { attachEntity } from '@owlmeans/auth-common'
7
7
  import { ResilientError } from '@owlmeans/error'
8
- import type { Config, Context, JobContext, JobEnvelope, JobReply } from './types.js'
8
+ import type { Config, Context, JobContext, JobEnvelope, JobReply, QueueJobMeta } from './types.js'
9
9
  import { EnvelopeExpired, JobNotServed } from './errors.js'
10
10
 
11
11
  /**
@@ -13,7 +13,7 @@ import { EnvelopeExpired, JobNotServed } from './errors.js'
13
13
  * same filter, the same handler run against it — only the wire is different.
14
14
  */
15
15
  export const requestOf = (
16
- envelope: JobEnvelope, path: string, context?: BasicContext<any>
16
+ envelope: JobEnvelope, path: string, context?: BasicContext<any>, job?: QueueJobMeta,
17
17
  ): AbstractRequest => ({
18
18
  alias: envelope.alias,
19
19
  params: (envelope.params ?? {}) as AbstractRequest['params'],
@@ -24,9 +24,17 @@ export const requestOf = (
24
24
  // Handlers reach their context through `original._ctx`, which the HTTP boundary sets on the raw
25
25
  // Fastify request. There is no raw request here, so the shape is supplied deliberately — a
26
26
  // handler must not have to know which transport delivered it.
27
- original: context != null ? { _ctx: context } : undefined,
27
+ original: context != null || job != null ? { _ctx: context, _job: job } : undefined,
28
28
  })
29
29
 
30
+ /** Read broker identity only where an entrypoint truly needs to bind work to an admission claim. */
31
+ export const queueJobOf = (request: unknown): QueueJobMeta | null => {
32
+ if (request == null || typeof request !== 'object' || !('original' in request)) return null
33
+ const original = (request as { original?: unknown }).original
34
+ if (original == null || typeof original !== 'object' || !('_job' in original)) return null
35
+ return (original as { _job?: QueueJobMeta })._job ?? null
36
+ }
37
+
30
38
  /**
31
39
  * Freshness is judged from when the job was ENQUEUED, not from now.
32
40
  *
@@ -67,7 +75,9 @@ export const handleJob = async <C extends Config, T extends Context<C>>(
67
75
  throw new JobNotServed(envelope.alias)
68
76
  }
69
77
 
70
- const request = requestOf(envelope, entrypoint.path(), context)
78
+ const request = requestOf(envelope, entrypoint.path(), context, {
79
+ id: job.id, name: job.name, queue: job.queue, attempt: job.attempt, touch: job.touch,
80
+ })
71
81
  const response = provideResponse<unknown>()
72
82
 
73
83
  const guards = entrypoint.getGuards()
package/src/errors.ts CHANGED
@@ -70,7 +70,7 @@ export class QueueNotListening extends QueueError {
70
70
 
71
71
  /**
72
72
  * The job named an entrypoint this process does not serve. Unlike a missing queue this is not a
73
- * declaration problem: the alias exists, but nothing here elevated it, so the job was taken by a
73
+ * declaration problem: the alias exists, but nothing here bound it, so the job was taken by a
74
74
  * worker that cannot run it.
75
75
  */
76
76
  export class JobNotServed extends QueueError {
package/src/index.ts CHANGED
@@ -5,3 +5,4 @@ export * from './config.js'
5
5
  export * from './transport.js'
6
6
  export * from './bridge.js'
7
7
  export * from './worker.js'
8
+ export * from './protocol.js'
@@ -0,0 +1,81 @@
1
+ import type { EntrypointProtocolDeclaration, RequestOf, ResponseOf } from '@owlmeans/entrypoint'
2
+ import { isEntrypointProtocol } from '@owlmeans/entrypoint'
3
+ import { ResilientError } from '@owlmeans/error'
4
+ import { RouteProtocols } from '@owlmeans/route'
5
+ import { queueOf } from './config.js'
6
+ import { UnknownQueue } from './errors.js'
7
+ import type {
8
+ Config, Context, JobEnvelope, JobOptions, JobRecord, JobReply, QueueAppend,
9
+ } from './types.js'
10
+
11
+ type QueueContext = Context<Config> & QueueAppend
12
+
13
+ const queueFor = (context: QueueContext, declaration: unknown): {
14
+ protocol: EntrypointProtocolDeclaration
15
+ queue: string
16
+ } => {
17
+ if (declaration == null || typeof declaration !== 'object' || !isEntrypointProtocol(declaration)) {
18
+ throw new UnknownQueue('protocol declaration required')
19
+ }
20
+ if (declaration.route.route.protocol !== RouteProtocols.QUEUE) {
21
+ throw new UnknownQueue(`${declaration.alias}: not a QUEUE protocol`)
22
+ }
23
+ const queue = declaration.route.route.queue
24
+ if (queue == null) {
25
+ throw new UnknownQueue(`${declaration.alias}: route declares no queue`)
26
+ }
27
+ const configured = queueOf(context.cfg, queue)
28
+ if (!configured.jobs.includes(declaration.alias)) {
29
+ throw new UnknownQueue(`${queue}:${declaration.alias}`)
30
+ }
31
+ return { protocol: declaration, queue }
32
+ }
33
+
34
+ /** Enqueue an immutable QUEUE protocol while preserving its exact request and response types. */
35
+ export const enqueueProtocol = async <Protocol extends EntrypointProtocolDeclaration>(
36
+ context: QueueContext,
37
+ declaration: Protocol,
38
+ request: RequestOf<Protocol>,
39
+ options?: JobOptions,
40
+ ): Promise<JobRecord<JobEnvelope, JobReply<ResponseOf<Protocol>>>> => {
41
+ const { protocol, queue } = queueFor(context, declaration)
42
+ const shaped = (request ?? {}) as unknown as Record<string, unknown>
43
+ const envelope: JobEnvelope = {
44
+ alias: protocol.alias,
45
+ params: shaped.params as Record<string, unknown> | undefined,
46
+ body: shaped.body,
47
+ query: shaped.query as Record<string, unknown> | undefined,
48
+ headers: shaped.headers as Record<string, string | undefined> | undefined,
49
+ enqueuedAt: new Date().toISOString(),
50
+ }
51
+
52
+ return await context.jobs<JobEnvelope, JobReply<ResponseOf<Protocol>>>(queue).create({
53
+ queue,
54
+ name: protocol.alias,
55
+ data: envelope,
56
+ opts: options,
57
+ })
58
+ }
59
+
60
+ /** Wait for a protocol job and unwrap the typed entrypoint reply. */
61
+ export const waitForProtocol = async <Protocol extends EntrypointProtocolDeclaration>(
62
+ context: QueueContext,
63
+ declaration: Protocol,
64
+ job: string | JobRecord<JobEnvelope, JobReply<ResponseOf<Protocol>>>,
65
+ options?: { timeout?: number },
66
+ ): Promise<ResponseOf<Protocol>> => {
67
+ const { protocol, queue } = queueFor(context, declaration)
68
+ if (typeof job !== 'string' && (job.queue !== queue || job.name !== protocol.alias)) {
69
+ throw new UnknownQueue(`${job.queue}:${job.name}`)
70
+ }
71
+ const id = typeof job === 'string' ? job : job.id
72
+ if (id == null) {
73
+ throw new UnknownQueue(`${queue}:${protocol.alias}: missing job id`)
74
+ }
75
+ const reply = await context.jobs<JobEnvelope, JobReply<ResponseOf<Protocol>>>(queue)
76
+ .wait(id, options)
77
+ if (reply.error != null) {
78
+ throw ResilientError.ensure(reply.error as Error | string)
79
+ }
80
+ return reply.value as ResponseOf<Protocol>
81
+ }
package/src/types.ts CHANGED
@@ -210,6 +210,15 @@ export interface JobEnvelope {
210
210
  enqueuedAt?: string
211
211
  }
212
212
 
213
+ export interface QueueJobMeta {
214
+ id: string
215
+ name: string
216
+ queue: string
217
+ attempt: number
218
+ /** Renew the broker lock for protocol handlers whose work can outlive one lock duration. */
219
+ touch: () => Promise<void>
220
+ }
221
+
213
222
  /** What a processor returns for an entrypoint job, so the caller can rebuild the reply. */
214
223
  export interface JobReply<T = unknown> {
215
224
  value?: T
package/src/worker.ts CHANGED
@@ -10,7 +10,7 @@ import { DEFAULT_ALIAS } from './consts.js'
10
10
  * Every queued entrypoint this process both SERVES and LISTENS to, grouped by queue.
11
11
  *
12
12
  * Both halves are required and they answer different questions. Serving is about code — the alias
13
- * was elevated here, so a handler exists. Listening is about deployment — this process was
13
+ * was bound here, so a handler exists. Listening is about deployment — this process was
14
14
  * configured to consume that queue. A worker that bound queues by what it can serve would make
15
15
  * every deployment of the same binary a worker for everything it happens to import.
16
16
  */
@@ -0,0 +1,58 @@
1
+ import { describe, expect, test } from 'bun:test'
2
+ import { contract, protocol, schema } from '@owlmeans/entrypoint'
3
+ import { job, route } from '@owlmeans/route'
4
+ import type { JSONSchemaType } from 'ajv'
5
+ import { enqueueProtocol, waitForProtocol, type JobRecord } from '../src/index.js'
6
+
7
+ interface Input { value: number }
8
+ interface Output { doubled: number }
9
+ const InputSchema = schema<Input>({
10
+ type: 'object', properties: { value: { type: 'number' } }, required: ['value'], additionalProperties: false,
11
+ } as JSONSchemaType<Input>)
12
+ const OutputSchema = schema<Output>({
13
+ type: 'object', properties: { doubled: { type: 'number' } }, required: ['doubled'], additionalProperties: false,
14
+ } as JSONSchemaType<Output>)
15
+ const declaration = protocol(
16
+ route('test:double', '/double', job({ queue: 'test' })),
17
+ contract(InputSchema, OutputSchema),
18
+ )
19
+
20
+ const context = (reply: unknown = { value: { doubled: 6 } }) => {
21
+ const created: Partial<JobRecord>[] = []
22
+ return {
23
+ cfg: { queue: { queues: [{ name: 'test', jobs: [declaration.alias] }] } },
24
+ jobs: () => ({
25
+ create: async (record: Partial<JobRecord>) => {
26
+ created.push(record)
27
+ return { ...record, id: 'job-1' } as JobRecord
28
+ },
29
+ wait: async () => reply,
30
+ }),
31
+ created,
32
+ }
33
+ }
34
+
35
+ describe('protocol-aware queue calls', () => {
36
+ test('derives the broker address and keeps per-call options', async () => {
37
+ const ctx = context()
38
+ const queued = await enqueueProtocol(ctx as never, declaration, { body: { value: 3 } }, {
39
+ delay: 250, attempts: 3, id: 'projection-1',
40
+ })
41
+ expect(queued.queue).toBe('test')
42
+ expect(ctx.created[0]?.name).toBe(declaration.alias)
43
+ expect(ctx.created[0]?.opts).toEqual({ delay: 250, attempts: 3, id: 'projection-1' })
44
+ expect(await waitForProtocol(ctx as never, declaration, queued as never)).toEqual({ doubled: 6 })
45
+ })
46
+
47
+ test('rejects raw aliases and non-queue declarations at runtime', async () => {
48
+ await expect(enqueueProtocol(context() as never, declaration.alias as never, {} as never)).rejects.toThrow()
49
+ const http = protocol(route('test:http', '/http'), contract())
50
+ await expect(enqueueProtocol(context() as never, http, {})).rejects.toThrow()
51
+ })
52
+
53
+ test('rejects a job from another queue or protocol', async () => {
54
+ await expect(waitForProtocol(context() as never, declaration, {
55
+ id: 'x', queue: 'other', name: declaration.alias, data: {},
56
+ } as never)).rejects.toThrow()
57
+ })
58
+ })