@owlmeans/queue 0.1.18-rc.23 → 0.1.18-rc.25

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
@@ -16,7 +16,7 @@ and on the driver only where the application wires itself up.
16
16
  ## Installation
17
17
 
18
18
  ```bash
19
- bun add @owlmeans/queue@^0.1.18-rc.23
19
+ bun add @owlmeans/queue@^0.1.18-rc.25
20
20
  ```
21
21
 
22
22
  ## Concepts
@@ -26,8 +26,8 @@ bun add @owlmeans/queue@^0.1.18-rc.23
26
26
  address, not a deployment.
27
27
  - **Listen**: `listenQueues(cfg, ...names)` in one process's own config says which queues *that
28
28
  process* consumes. A process that listens to nothing is a producer only.
29
- - **Queued protocol**: an immutable entrypoint protocol whose route uses `job()` instead of
30
- `backend()` (`RouteProtocols.QUEUE`). Callers use `ctx.entrypoint(protocol).call(...)` unchanged,
29
+ - **Queued protocol**: an immutable backend entrypoint protocol whose route uses `job()` from this
30
+ package (`QUEUE_PROTOCOL`). Callers use `ctx.entrypoint(protocol).call(...)` unchanged,
31
31
  and the QUEUE transport carries the call through the broker.
32
32
  - **Job record**: `ctx.jobs(queue)` returns a `QueueResource`, the ordinary `Resource<JobRecord>`
33
33
  contract plus `wait`, `flow`, `counts` and `close`. `create` enqueues, `list` inspects and `take`
@@ -80,7 +80,8 @@ appendRedisQueue(context, { hooks: billingQueueHooks(context) })
80
80
 
81
81
  ```ts
82
82
  import { contract, protocol, typed } from '@owlmeans/entrypoint'
83
- import { backend, job, route } from '@owlmeans/route'
83
+ import { job } from '@owlmeans/queue'
84
+ import { backend, route } from '@owlmeans/route'
84
85
 
85
86
  const aliases = { base: 'app:report', build: 'app:report:build' } as const
86
87
  const reportBase = protocol(route(aliases.base, '/reports', backend({ service: APP_WORKER })), contract())
@@ -286,7 +287,7 @@ not the job, so read the job back to learn what became of it.
286
287
  ## Related packages
287
288
 
288
289
  - [`@owlmeans/redis-queue`](../redis-queue): the BullMQ driver, and where queue integration tests live
289
- - [`@owlmeans/route`](../route): `RouteProtocols.QUEUE` and the `job()` builder
290
+ - [`@owlmeans/route`](../route): transport-neutral route declarations used by the queue-owned `job()` builder
290
291
  - [`@owlmeans/entrypoint`](../entrypoint): protocol declarations and the transport seam
291
292
  - [`@owlmeans/resource`](../resource): the `Resource` contract jobs are read through
292
293
  - [`@owlmeans/server-job`](../server-job) / [`@owlmeans/client-job`](../client-job): listing,
@@ -300,7 +301,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
300
301
  your project's skill store (`.agents/skills/`):
301
302
 
302
303
  ```sh
303
- npx @owlmeans/agent-skills@^0.1.18-rc.28
304
+ npx @owlmeans/agent-skills@^0.1.18-rc.31
304
305
  ```
305
306
 
306
307
  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.23",
5
- "generatedAt": "2026-09-17T08:16:11.196Z",
4
+ "version": "0.1.18-rc.25",
5
+ "generatedAt": "2026-09-21T21:54:22.945Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -8,19 +8,20 @@ user-invocable: false
8
8
  # @owlmeans/queue
9
9
 
10
10
  **Layer:** Infra
11
- **Install:** `"@owlmeans/queue": "^0.1.18-rc.23"` in `dependencies`
11
+ **Install:** `"@owlmeans/queue": "^0.1.18-rc.25"` in `dependencies`
12
12
 
13
- Contracts only. It carries no broker code — a driver package (`@owlmeans/redis-queue`) implements
14
- them. Depend on this one from a shared contract package; depend on the driver only where the
13
+ Backend transport contracts only. It carries no broker code — a driver package
14
+ (`@owlmeans/redis-queue`) implements them. Depend on this one from a shared backend package;
15
+ generic common and frontend packages must not import it. Depend on the driver only where the
15
16
  application wires itself up.
16
17
 
17
18
  ## The one idea
18
19
 
19
- A queued call is an immutable entrypoint protocol whose route names `RouteProtocols.QUEUE`.
20
+ A queued call is an immutable entrypoint protocol whose route names `QUEUE_PROTOCOL`.
20
21
  Ordinary calls use `ctx.entrypoint(protocol).call(request)`. Code that needs broker options or a
21
22
  job handle uses `enqueueProtocol(ctx, protocol, request, options)` and
22
23
  `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.
24
+ preserve its exact request/reply pair; raw strings and non-queue declarations are rejected.
24
25
 
25
26
  That is what makes it worth having: moving a service-to-service call onto the broker is a change
26
27
  to a declaration, not to the places that call it, and the broker holds the work across a restart of
@@ -60,6 +61,9 @@ protocol(
60
61
  )
61
62
  ```
62
63
 
64
+ Import `job`, `QUEUE_PROTOCOL`, `isQueueRoute` and `queueRouteOptions` from `@owlmeans/queue`.
65
+ The generic route package deliberately knows none of the queue option shape.
66
+
63
67
  The alias appears in `declareQueue(...jobs)` only because the broker is a string-keyed adapter.
64
68
  Application producers and handlers keep the protocol object.
65
69
 
@@ -241,7 +245,7 @@ listens to, grouped by queue, which is what a driver binds.
241
245
 
242
246
  - `@owlmeans/context` — service registration and the middleware stage
243
247
  - `@owlmeans/entrypoint` — the transport seam and the served-entrypoint dispatch
244
- - `@owlmeans/route` — `RouteProtocols.QUEUE` and the `job()` builder
248
+ - `@owlmeans/route` — the generic declaration model that `QUEUE_PROTOCOL` and `job()` extend
245
249
  - `@owlmeans/resource` — the `Resource` contract jobs are read through
246
250
  - `@owlmeans/auth` / `@owlmeans/auth-common` — guarding a queued call and attaching its entity
247
251
  - `@owlmeans/error` — marshalling a refusal across the hop
package/build/index.d.ts CHANGED
@@ -6,4 +6,5 @@ export * from './transport.js';
6
6
  export * from './bridge.js';
7
7
  export * from './worker.js';
8
8
  export * from './protocol.js';
9
+ export * from './route.js';
9
10
  //# 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;AAC3B,cAAc,eAAe,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;AAC7B,cAAc,YAAY,CAAA"}
package/build/index.js CHANGED
@@ -6,4 +6,5 @@ export * from './transport.js';
6
6
  export * from './bridge.js';
7
7
  export * from './worker.js';
8
8
  export * from './protocol.js';
9
+ export * from './route.js';
9
10
  //# 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;AAC3B,cAAc,eAAe,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;AAC7B,cAAc,YAAY,CAAA"}
@@ -1 +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"}
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;AAoBjD,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"}
package/build/protocol.js CHANGED
@@ -1,19 +1,16 @@
1
1
  import { isEntrypointProtocol } from '@owlmeans/entrypoint';
2
2
  import { ResilientError } from '@owlmeans/error';
3
- import { RouteProtocols } from '@owlmeans/route';
4
3
  import { queueOf } from './config.js';
5
4
  import { UnknownQueue } from './errors.js';
5
+ import { isQueueRoute, queueRouteOptions } from './route.js';
6
6
  const queueFor = (context, declaration) => {
7
7
  if (declaration == null || typeof declaration !== 'object' || !isEntrypointProtocol(declaration)) {
8
8
  throw new UnknownQueue('protocol declaration required');
9
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`);
10
+ if (!isQueueRoute(declaration.route)) {
11
+ throw new UnknownQueue(`${declaration.alias}: not a queue protocol`);
16
12
  }
13
+ const { queue } = queueRouteOptions(declaration.route);
17
14
  const configured = queueOf(context.cfg, queue);
18
15
  if (!configured.jobs.includes(declaration.alias)) {
19
16
  throw new UnknownQueue(`${queue}:${declaration.alias}`);
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { RouteDeclaration, RouteModel, RouteOptions } from '@owlmeans/route';
2
+ /** The transport identifier owned by the queue package. */
3
+ export declare const QUEUE_PROTOCOL: 'queue';
4
+ /** Queue-owned options stored in a generic route declaration. */
5
+ export interface QueueRouteOptions extends Omit<RouteOptions, 'protocol' | 'protocolOptions'> {
6
+ queue: string;
7
+ reply?: boolean;
8
+ }
9
+ /** Declare a backend route carried by a queue. */
10
+ export declare const job: (opts: QueueRouteOptions, secondary?: Omit<QueueRouteOptions, 'queue'>) => Partial<RouteOptions>;
11
+ /** Whether a declaration belongs to the queue transport. */
12
+ export declare const isQueueRoute: (route: RouteDeclaration | RouteModel) => boolean;
13
+ /** Read and validate queue-owned route options. */
14
+ export declare const queueRouteOptions: (route: RouteDeclaration | RouteModel) => Pick<QueueRouteOptions, 'queue' | 'reply'>;
15
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../src/route.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAGjF,2DAA2D;AAC3D,eAAO,MAAM,cAAc,EAAG,OAAgB,CAAA;AAE9C,iEAAiE;AACjE,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,YAAY,EAAE,UAAU,GAAG,iBAAiB,CAAC;IAC3F,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,kDAAkD;AAClD,eAAO,MAAM,GAAG,SACR,iBAAiB,cACX,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,KAC3C,OAAO,CAAC,YAAY,CAMtB,CAAA;AAED,4DAA4D;AAC5D,eAAO,MAAM,YAAY,UAAW,gBAAgB,GAAG,UAAU,KAAG,OACE,CAAA;AAEtE,mDAAmD;AACnD,eAAO,MAAM,iBAAiB,UACrB,gBAAgB,GAAG,UAAU,KACnC,IAAI,CAAC,iBAAiB,EAAE,OAAO,GAAG,OAAO,CAe3C,CAAA"}
package/build/route.js ADDED
@@ -0,0 +1,32 @@
1
+ import { backend } from '@owlmeans/route';
2
+ import { UnknownQueue } from './errors.js';
3
+ /** The transport identifier owned by the queue package. */
4
+ export const QUEUE_PROTOCOL = 'queue';
5
+ /** Declare a backend route carried by a queue. */
6
+ export const job = (opts, secondary) => {
7
+ const { queue, reply, ...routeOptions } = { ...opts, ...secondary };
8
+ const declaration = backend(routeOptions);
9
+ declaration.protocol = QUEUE_PROTOCOL;
10
+ declaration.protocolOptions = { queue, ...(reply == null ? {} : { reply }) };
11
+ return declaration;
12
+ };
13
+ /** Whether a declaration belongs to the queue transport. */
14
+ export const isQueueRoute = (route) => ('route' in route ? route.route : route).protocol === QUEUE_PROTOCOL;
15
+ /** Read and validate queue-owned route options. */
16
+ export const queueRouteOptions = (route) => {
17
+ const declaration = 'route' in route ? route.route : route;
18
+ if (declaration.protocol !== QUEUE_PROTOCOL
19
+ || declaration.protocolOptions == null
20
+ || typeof declaration.protocolOptions !== 'object') {
21
+ throw new UnknownQueue(`${declaration.alias}: not a queue protocol`);
22
+ }
23
+ const options = declaration.protocolOptions;
24
+ if (typeof options.queue !== 'string' || options.queue.trim() === '') {
25
+ throw new UnknownQueue(`${declaration.alias}: route declares no queue`);
26
+ }
27
+ if (options.reply != null && typeof options.reply !== 'boolean') {
28
+ throw new UnknownQueue(`${declaration.alias}: invalid queue reply option`);
29
+ }
30
+ return { queue: options.queue, reply: options.reply };
31
+ };
32
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../src/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,2DAA2D;AAC3D,MAAM,CAAC,MAAM,cAAc,GAAG,OAAgB,CAAA;AAQ9C,kDAAkD;AAClD,MAAM,CAAC,MAAM,GAAG,GAAG,CACjB,IAAuB,EACvB,SAA4C,EACrB,EAAE;IACzB,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,YAAY,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,SAAS,EAAE,CAAA;IACnE,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IACzC,WAAW,CAAC,QAAQ,GAAG,cAAc,CAAA;IACrC,WAAW,CAAC,eAAe,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;IAC5E,OAAO,WAAW,CAAA;AACpB,CAAC,CAAA;AAED,4DAA4D;AAC5D,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAoC,EAAW,EAAE,CAC5E,CAAC,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,KAAK,cAAc,CAAA;AAEtE,mDAAmD;AACnD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,KAAoC,EACQ,EAAE;IAC9C,MAAM,WAAW,GAAG,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAA;IAC1D,IAAI,WAAW,CAAC,QAAQ,KAAK,cAAc;WACtC,WAAW,CAAC,eAAe,IAAI,IAAI;WACnC,OAAO,WAAW,CAAC,eAAe,KAAK,QAAQ,EAAE,CAAC;QACrD,MAAM,IAAI,YAAY,CAAC,GAAG,WAAW,CAAC,KAAK,wBAAwB,CAAC,CAAA;IACtE,CAAC;IACD,MAAM,OAAO,GAAG,WAAW,CAAC,eAA0C,CAAA;IACtE,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrE,MAAM,IAAI,YAAY,CAAC,GAAG,WAAW,CAAC,KAAK,2BAA2B,CAAC,CAAA;IACzE,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,IAAI,IAAI,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAChE,MAAM,IAAI,YAAY,CAAC,GAAG,WAAW,CAAC,KAAK,8BAA8B,CAAC,CAAA;IAC5E,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,KAA4B,EAAE,CAAA;AAC9E,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAqC,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAKlG,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAsC,MAAM,YAAY,CAAA;AAIrF;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,WAAW,MAAM,wBAmD/C,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,WAC7E,CAAC,UAAU,MAAM,KACzB,CAMF,CAAA"}
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAqC,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAIlG,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAsC,MAAM,YAAY,CAAA;AAIrF;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,WAAW,MAAM,wBAiD/C,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,WAC7E,CAAC,UAAU,MAAM,KACzB,CAMF,CAAA"}
@@ -1,9 +1,8 @@
1
1
  import { assertContext, createService } from '@owlmeans/context';
2
2
  import { EntrypointOutcome, transportAlias } from '@owlmeans/entrypoint';
3
- import { RouteProtocols } from '@owlmeans/route';
4
3
  import { ResilientError } from '@owlmeans/error';
5
4
  import { DEFAULT_JOB_TIMEOUT } from './consts.js';
6
- import { UnknownQueue } from './errors.js';
5
+ import { QUEUE_PROTOCOL, queueRouteOptions } from './route.js';
7
6
  /**
8
7
  * The producing half of the bridge: it turns a call on a QUEUE entrypoint into a job, and the
9
8
  * job's outcome back into a reply.
@@ -14,18 +13,16 @@ import { UnknownQueue } from './errors.js';
14
13
  * the request rather than from the entrypoint: the far side rebuilds a request, and anything only
15
14
  * HTTP understands would not survive the trip anyway.
16
15
  */
17
- export const makeQueueTransport = (alias = transportAlias(RouteProtocols.QUEUE)) => {
16
+ export const makeQueueTransport = (alias = transportAlias(QUEUE_PROTOCOL)) => {
18
17
  const location = `queue-transport:${alias}`;
19
18
  const service = createService(alias, {
20
- protocol: RouteProtocols.QUEUE,
19
+ protocol: QUEUE_PROTOCOL,
21
20
  handle: (async (req, res) => {
22
21
  const context = assertContext(service.ctx, location);
23
22
  const entrypoint = context.entrypoint(req.alias);
24
23
  const route = entrypoint.route.route;
25
- if (route.queue == null) {
26
- throw new UnknownQueue(`${req.alias}: route declares no queue`);
27
- }
28
- const jobs = context.jobs(route.queue);
24
+ const { queue, reply: waitsForReply } = queueRouteOptions(route);
25
+ const jobs = context.jobs(queue);
29
26
  const envelope = {
30
27
  alias: req.alias,
31
28
  params: req.params,
@@ -34,11 +31,11 @@ export const makeQueueTransport = (alias = transportAlias(RouteProtocols.QUEUE))
34
31
  headers: req.headers,
35
32
  enqueuedAt: new Date().toISOString(),
36
33
  };
37
- const job = await jobs.create({ queue: route.queue, name: req.alias, data: envelope });
34
+ const job = await jobs.create({ queue, name: req.alias, data: envelope });
38
35
  // `reply: false` says the caller is not waiting for the work, only for the promise that it
39
36
  // was taken. `Accepted` plus the job's identity is the whole answer — enough to watch it.
40
- if (route.reply === false) {
41
- res.resolve({ id: job.id, queue: route.queue }, EntrypointOutcome.Accepted);
37
+ if (waitsForReply === false) {
38
+ res.resolve({ id: job.id, queue }, EntrypointOutcome.Accepted);
42
39
  return;
43
40
  }
44
41
  const reply = await jobs.wait(job.id, {
@@ -1 +1 @@
1
- {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAEnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAE5D,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAc,WAAW,EAAE,YAAY,EAAsB,MAAM,YAAY,CAAA;AAI5G;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,WACtD,CAAC,KACT,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAoBhC,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,WAC/D,CAAC,KACT,YAAY,CAAC,WAAW,EAAE,OAAO,CACmC,CAAA;AAEvE;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,WAAW,MAAM,KAAmB,UAcpE,CAAA"}
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAEnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAc,WAAW,EAAE,YAAY,EAAsB,MAAM,YAAY,CAAA;AAK5G;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,WACtD,CAAC,KACT,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAqBhC,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,WAC/D,CAAC,KACT,YAAY,CAAC,WAAW,EAAE,OAAO,CACmC,CAAA;AAEvE;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,WAAW,MAAM,KAAmB,UAcpE,CAAA"}
package/build/worker.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { MiddlewareStage, MiddlewareType, AppType } from '@owlmeans/context';
2
- import { RouteProtocols } from '@owlmeans/route';
3
2
  import { handleJob } from './bridge.js';
4
3
  import { DEFAULT_ALIAS } from './consts.js';
4
+ import { isQueueRoute, queueRouteOptions } from './route.js';
5
5
  /**
6
6
  * Every queued entrypoint this process both SERVES and LISTENS to, grouped by queue.
7
7
  *
@@ -15,16 +15,17 @@ export const servedJobs = (context) => {
15
15
  const served = new Map();
16
16
  context.entrypoints().forEach(entrypoint => {
17
17
  const route = entrypoint.route.route;
18
- if (route.type !== AppType.Backend || route.protocol !== RouteProtocols.QUEUE) {
18
+ if (route.type !== AppType.Backend || !isQueueRoute(route)) {
19
19
  return;
20
20
  }
21
21
  if (route.service != null && route.service !== context.cfg.service) {
22
22
  return;
23
23
  }
24
- if (entrypoint.handle == null || route.queue == null || !listen.includes(route.queue)) {
24
+ const { queue } = queueRouteOptions(route);
25
+ if (entrypoint.handle == null || !listen.includes(queue)) {
25
26
  return;
26
27
  }
27
- served.set(route.queue, [...(served.get(route.queue) ?? []), entrypoint]);
28
+ served.set(queue, [...(served.get(queue) ?? []), entrypoint]);
28
29
  });
29
30
  return served;
30
31
  };
@@ -1 +1 @@
1
- {"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAE5E,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,OAAU,EACuB,EAAE;IACnC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,IAAI,EAAE,CAAA;IAC9C,MAAM,MAAM,GAAG,IAAI,GAAG,EAA8B,CAAA;IAEpD,OAAO,CAAC,WAAW,EAAoB,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE;QAC3D,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAA;QACpC,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC,QAAQ,KAAK,cAAc,CAAC,KAAK,EAAE,CAAC;YAC9E,OAAM;QACR,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,IAAI,KAAK,CAAC,OAAO,KAAK,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACnE,OAAM;QACR,CAAC;QACD,IAAI,UAAU,CAAC,MAAM,IAAI,IAAI,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACtF,OAAM;QACR,CAAC;QAED,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,CAAA;IAC3E,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,OAAU,EAC0B,EAAE,CACtC,KAAK,EAAE,GAA4B,EAAE,EAAE,CAAC,MAAM,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;AAEvE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,KAAK,GAAW,aAAa,EAAc,EAAE,CAAC,CAAC;IACnF,IAAI,EAAE,cAAc,CAAC,OAAO;IAC5B,KAAK,EAAE,eAAe,CAAC,KAAK;IAC5B,KAAK,EAAE,KAAK,EAAC,OAAO,EAAC,EAAE;QACrB,MAAM,GAAG,GAAG,OAAqC,CAAA;QACjD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/C,OAAM;QACR,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAM;QACR,CAAC;QAED,MAAM,GAAG,CAAC,OAAO,CAAqB,KAAK,CAAC,CAAC,KAAK,EAAE,CAAA;IACtD,CAAC;CACF,CAAC,CAAA"}
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAG5E,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAE5D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,OAAU,EACuB,EAAE;IACnC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,IAAI,EAAE,CAAA;IAC9C,MAAM,MAAM,GAAG,IAAI,GAAG,EAA8B,CAAA;IAEpD,OAAO,CAAC,WAAW,EAAoB,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE;QAC3D,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAA;QACpC,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3D,OAAM;QACR,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,IAAI,KAAK,CAAC,OAAO,KAAK,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACnE,OAAM;QACR,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAA;QAC1C,IAAI,UAAU,CAAC,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACzD,OAAM;QACR,CAAC;QAED,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,CAAA;IAC/D,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,OAAU,EAC0B,EAAE,CACtC,KAAK,EAAE,GAA4B,EAAE,EAAE,CAAC,MAAM,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;AAEvE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,KAAK,GAAW,aAAa,EAAc,EAAE,CAAC,CAAC;IACnF,IAAI,EAAE,cAAc,CAAC,OAAO;IAC5B,KAAK,EAAE,eAAe,CAAC,KAAK;IAC5B,KAAK,EAAE,KAAK,EAAC,OAAO,EAAC,EAAE;QACrB,MAAM,GAAG,GAAG,OAAqC,CAAA;QACjD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/C,OAAM;QACR,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAM;QACR,CAAC;QAED,MAAM,GAAG,CAAC,OAAO,CAAqB,KAAK,CAAC,CAAC,KAAK,EAAE,CAAA;IACtD,CAAC;CACF,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/queue",
3
- "version": "0.1.18-rc.23",
3
+ "version": "0.1.18-rc.25",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -31,12 +31,12 @@
31
31
  "access": "public"
32
32
  },
33
33
  "dependencies": {
34
- "@owlmeans/auth": "^0.1.18-rc.27",
35
- "@owlmeans/auth-common": "^0.1.18-rc.29",
36
- "@owlmeans/context": "^0.1.18-rc.25",
37
- "@owlmeans/entrypoint": "^0.1.18-rc.28",
38
- "@owlmeans/error": "^0.1.18-rc.27",
39
- "@owlmeans/resource": "^0.1.18-rc.27",
40
- "@owlmeans/route": "^0.1.18-rc.26"
34
+ "@owlmeans/auth": "^0.1.18-rc.29",
35
+ "@owlmeans/auth-common": "^0.1.18-rc.31",
36
+ "@owlmeans/context": "^0.1.18-rc.27",
37
+ "@owlmeans/entrypoint": "^0.1.18-rc.30",
38
+ "@owlmeans/error": "^0.1.18-rc.29",
39
+ "@owlmeans/resource": "^0.1.18-rc.29",
40
+ "@owlmeans/route": "^0.1.18-rc.28"
41
41
  }
42
42
  }
package/src/index.ts CHANGED
@@ -6,3 +6,4 @@ export * from './transport.js'
6
6
  export * from './bridge.js'
7
7
  export * from './worker.js'
8
8
  export * from './protocol.js'
9
+ export * from './route.js'
package/src/protocol.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import type { EntrypointProtocolDeclaration, RequestOf, ResponseOf } from '@owlmeans/entrypoint'
2
2
  import { isEntrypointProtocol } from '@owlmeans/entrypoint'
3
3
  import { ResilientError } from '@owlmeans/error'
4
- import { RouteProtocols } from '@owlmeans/route'
5
4
  import { queueOf } from './config.js'
6
5
  import { UnknownQueue } from './errors.js'
6
+ import { isQueueRoute, queueRouteOptions } from './route.js'
7
7
  import type {
8
8
  Config, Context, JobEnvelope, JobOptions, JobRecord, JobReply, QueueAppend,
9
9
  } from './types.js'
@@ -17,13 +17,10 @@ const queueFor = (context: QueueContext, declaration: unknown): {
17
17
  if (declaration == null || typeof declaration !== 'object' || !isEntrypointProtocol(declaration)) {
18
18
  throw new UnknownQueue('protocol declaration required')
19
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`)
20
+ if (!isQueueRoute(declaration.route)) {
21
+ throw new UnknownQueue(`${declaration.alias}: not a queue protocol`)
26
22
  }
23
+ const { queue } = queueRouteOptions(declaration.route)
27
24
  const configured = queueOf(context.cfg, queue)
28
25
  if (!configured.jobs.includes(declaration.alias)) {
29
26
  throw new UnknownQueue(`${queue}:${declaration.alias}`)
package/src/route.ts ADDED
@@ -0,0 +1,48 @@
1
+ import { backend } from '@owlmeans/route'
2
+ import type { RouteDeclaration, RouteModel, RouteOptions } from '@owlmeans/route'
3
+ import { UnknownQueue } from './errors.js'
4
+
5
+ /** The transport identifier owned by the queue package. */
6
+ export const QUEUE_PROTOCOL = 'queue' as const
7
+
8
+ /** Queue-owned options stored in a generic route declaration. */
9
+ export interface QueueRouteOptions extends Omit<RouteOptions, 'protocol' | 'protocolOptions'> {
10
+ queue: string
11
+ reply?: boolean
12
+ }
13
+
14
+ /** Declare a backend route carried by a queue. */
15
+ export const job = (
16
+ opts: QueueRouteOptions,
17
+ secondary?: Omit<QueueRouteOptions, 'queue'>,
18
+ ): Partial<RouteOptions> => {
19
+ const { queue, reply, ...routeOptions } = { ...opts, ...secondary }
20
+ const declaration = backend(routeOptions)
21
+ declaration.protocol = QUEUE_PROTOCOL
22
+ declaration.protocolOptions = { queue, ...(reply == null ? {} : { reply }) }
23
+ return declaration
24
+ }
25
+
26
+ /** Whether a declaration belongs to the queue transport. */
27
+ export const isQueueRoute = (route: RouteDeclaration | RouteModel): boolean =>
28
+ ('route' in route ? route.route : route).protocol === QUEUE_PROTOCOL
29
+
30
+ /** Read and validate queue-owned route options. */
31
+ export const queueRouteOptions = (
32
+ route: RouteDeclaration | RouteModel,
33
+ ): Pick<QueueRouteOptions, 'queue' | 'reply'> => {
34
+ const declaration = 'route' in route ? route.route : route
35
+ if (declaration.protocol !== QUEUE_PROTOCOL
36
+ || declaration.protocolOptions == null
37
+ || typeof declaration.protocolOptions !== 'object') {
38
+ throw new UnknownQueue(`${declaration.alias}: not a queue protocol`)
39
+ }
40
+ const options = declaration.protocolOptions as Record<string, unknown>
41
+ if (typeof options.queue !== 'string' || options.queue.trim() === '') {
42
+ throw new UnknownQueue(`${declaration.alias}: route declares no queue`)
43
+ }
44
+ if (options.reply != null && typeof options.reply !== 'boolean') {
45
+ throw new UnknownQueue(`${declaration.alias}: invalid queue reply option`)
46
+ }
47
+ return { queue: options.queue, reply: options.reply as boolean | undefined }
48
+ }
package/src/transport.ts CHANGED
@@ -1,12 +1,11 @@
1
1
  import { assertContext, createService } from '@owlmeans/context'
2
2
  import type { AbstractRequest, AbstractResponse, EntrypointTransport } from '@owlmeans/entrypoint'
3
3
  import { EntrypointOutcome, transportAlias } from '@owlmeans/entrypoint'
4
- import { RouteProtocols } from '@owlmeans/route'
5
4
  import { ResilientError } from '@owlmeans/error'
6
5
  import type { CommonEntrypoint } from '@owlmeans/entrypoint'
7
6
  import type { Config, Context, JobEnvelope, JobReply, QueueAppend } from './types.js'
8
7
  import { DEFAULT_JOB_TIMEOUT } from './consts.js'
9
- import { UnknownQueue } from './errors.js'
8
+ import { QUEUE_PROTOCOL, queueRouteOptions } from './route.js'
10
9
 
11
10
  /**
12
11
  * The producing half of the bridge: it turns a call on a QUEUE entrypoint into a job, and the
@@ -18,22 +17,20 @@ import { UnknownQueue } from './errors.js'
18
17
  * the request rather than from the entrypoint: the far side rebuilds a request, and anything only
19
18
  * HTTP understands would not survive the trip anyway.
20
19
  */
21
- export const makeQueueTransport = (alias: string = transportAlias(RouteProtocols.QUEUE)) => {
20
+ export const makeQueueTransport = (alias: string = transportAlias(QUEUE_PROTOCOL)) => {
22
21
  const location = `queue-transport:${alias}`
23
22
 
24
23
  const service = createService<EntrypointTransport>(alias, {
25
- protocol: RouteProtocols.QUEUE,
24
+ protocol: QUEUE_PROTOCOL,
26
25
 
27
26
  handle: (async <T>(req: AbstractRequest, res: AbstractResponse<T>) => {
28
27
  const context = assertContext<Config, Context<Config>>(service.ctx as Context<Config>, location)
29
28
  const entrypoint = context.entrypoint<CommonEntrypoint>(req.alias)
30
29
  const route = entrypoint.route.route
31
30
 
32
- if (route.queue == null) {
33
- throw new UnknownQueue(`${req.alias}: route declares no queue`)
34
- }
31
+ const { queue, reply: waitsForReply } = queueRouteOptions(route)
35
32
 
36
- const jobs = (context as unknown as QueueAppend).jobs<JobEnvelope, JobReply<T>>(route.queue)
33
+ const jobs = (context as unknown as QueueAppend).jobs<JobEnvelope, JobReply<T>>(queue)
37
34
 
38
35
  const envelope: JobEnvelope = {
39
36
  alias: req.alias,
@@ -44,12 +41,12 @@ export const makeQueueTransport = (alias: string = transportAlias(RouteProtocols
44
41
  enqueuedAt: new Date().toISOString(),
45
42
  }
46
43
 
47
- const job = await jobs.create({ queue: route.queue, name: req.alias, data: envelope })
44
+ const job = await jobs.create({ queue, name: req.alias, data: envelope })
48
45
 
49
46
  // `reply: false` says the caller is not waiting for the work, only for the promise that it
50
47
  // was taken. `Accepted` plus the job's identity is the whole answer — enough to watch it.
51
- if (route.reply === false) {
52
- res.resolve({ id: job.id, queue: route.queue } as T, EntrypointOutcome.Accepted)
48
+ if (waitsForReply === false) {
49
+ res.resolve({ id: job.id, queue } as T, EntrypointOutcome.Accepted)
53
50
 
54
51
  return
55
52
  }
package/src/worker.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import type { Middleware } from '@owlmeans/context'
2
2
  import { MiddlewareStage, MiddlewareType, AppType } from '@owlmeans/context'
3
3
  import type { CommonEntrypoint } from '@owlmeans/entrypoint'
4
- import { RouteProtocols } from '@owlmeans/route'
5
4
  import type { Config, Context, JobContext, JobEnvelope, JobProcessor, QueueWorkerService } from './types.js'
6
5
  import { handleJob } from './bridge.js'
7
6
  import { DEFAULT_ALIAS } from './consts.js'
7
+ import { isQueueRoute, queueRouteOptions } from './route.js'
8
8
 
9
9
  /**
10
10
  * Every queued entrypoint this process both SERVES and LISTENS to, grouped by queue.
@@ -22,17 +22,18 @@ export const servedJobs = <C extends Config, T extends Context<C>>(
22
22
 
23
23
  context.entrypoints<CommonEntrypoint>().forEach(entrypoint => {
24
24
  const route = entrypoint.route.route
25
- if (route.type !== AppType.Backend || route.protocol !== RouteProtocols.QUEUE) {
25
+ if (route.type !== AppType.Backend || !isQueueRoute(route)) {
26
26
  return
27
27
  }
28
28
  if (route.service != null && route.service !== context.cfg.service) {
29
29
  return
30
30
  }
31
- if (entrypoint.handle == null || route.queue == null || !listen.includes(route.queue)) {
31
+ const { queue } = queueRouteOptions(route)
32
+ if (entrypoint.handle == null || !listen.includes(queue)) {
32
33
  return
33
34
  }
34
35
 
35
- served.set(route.queue, [...(served.get(route.queue) ?? []), entrypoint])
36
+ served.set(queue, [...(served.get(queue) ?? []), entrypoint])
36
37
  })
37
38
 
38
39
  return served
@@ -1,8 +1,8 @@
1
1
  import { describe, expect, test } from 'bun:test'
2
2
  import { contract, protocol, schema } from '@owlmeans/entrypoint'
3
- import { job, route } from '@owlmeans/route'
3
+ import { route } from '@owlmeans/route'
4
4
  import type { JSONSchemaType } from 'ajv'
5
- import { enqueueProtocol, waitForProtocol, type JobRecord } from '../src/index.js'
5
+ import { enqueueProtocol, job, waitForProtocol, type JobRecord } from '../src/index.js'
6
6
 
7
7
  interface Input { value: number }
8
8
  interface Output { doubled: number }