@owlmeans/server-job 0.1.18-rc.2 → 0.1.18-rc.4

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
@@ -1,101 +1,10 @@
1
1
  # @owlmeans/server-job
2
2
 
3
- The read side of a queue, as entrypoints an application elevates: list, get, cancel and a socket
4
- that pushes lifecycle events. Jobs themselves are enqueued and processed through
5
- [`@owlmeans/queue`](../queue) and its driver — nothing here produces or consumes work.
3
+ Server entrypoints for a queue job protocol group: list, get, cancel and lifecycle watch.
6
4
 
7
- ## Overview
8
-
9
- - `declareJobEntrypoints(root, opts?)` — the four declarations, for the app's SHARED package
10
- - `serveJobEntrypoints(entrypoints, root, opts?)` — elevate them with this package's handlers
11
- - `listJobs` / `getJob` / `cancelJob` / `watchJobs` — the handlers, when an app elevates by hand
12
- - A caller sees only the jobs it owns; the escape hatch is an option, not a hardcoded permission
13
-
14
- ## Installation
15
-
16
- ```bash
17
- bun add @owlmeans/server-job@^0.1.18-rc.0
18
- ```
19
-
20
- ## Usage
21
-
22
- Declare the group once, in the package both halves import:
23
-
24
- ```typescript
25
- import { declareJobEntrypoints } from '@owlmeans/server-job'
26
-
27
- export const REPORTS = 'reports'
28
- export const entrypoints = [
29
- ...declareJobEntrypoints(REPORTS, { path: '/reports/jobs', parent: app.api.base }),
30
- ]
31
- ```
32
-
33
- Serve it in the API process, alongside the queue driver it already wires:
34
-
35
- ```typescript
36
- import { serveJobEntrypoints } from '@owlmeans/server-job'
37
- import { appendRedisQueue } from '@owlmeans/redis-queue'
38
-
39
- appendRedisQueue(context)
40
- serveJobEntrypoints(entrypoints, REPORTS, { queue: REPORT_QUEUE })
41
- context.registerEntrypoints(entrypoints)
42
- ```
43
-
44
- Enqueue with the owner in the payload — that is what every read here filters on:
45
-
46
- ```typescript
47
- await context.jobs<ReportJob, ReportResult>(REPORT_QUEUE).create({
48
- name: 'report:build',
49
- data: { owner: req.auth!.profileId ?? req.auth!.userId, target: id },
50
- })
51
- ```
52
-
53
- And report progress from the processor, so there is something to watch:
54
-
55
- ```typescript
56
- worker.process(REPORT_QUEUE, 'report:build', async job => {
57
- for (const [done, page] of pages.entries()) {
58
- await job.touch()
59
- await job.progress({ done, total: pages.length })
60
- await render(page)
61
- }
62
- return { url }
63
- })
64
- ```
65
-
66
- ## Ownership
67
-
68
- `data.owner` (rename it with `ownerField`) is compared against `auth.profileId ?? auth.userId`.
69
- A job that exists but belongs to someone else answers exactly as an absent one: `UnknownJob`.
70
-
71
- An operator console passes a predicate instead of a permission name:
72
-
73
- ```typescript
74
- serveJobEntrypoints(entrypoints, REPORTS, {
75
- queue: REPORT_QUEUE,
76
- admin: req => req.auth?.scopes?.includes('ops') === true,
77
- })
78
- ```
79
-
80
- ## The one gotcha
81
-
82
- A `JobEvent` carries no owner, so `watchJobs` attributes each frame by reading its job back. A
83
- queue configured with `removeOnComplete` has nothing left to read when the completion arrives, and
84
- an unattributable frame is dropped rather than fanned out. Leave completed jobs in place on any
85
- queue that is watched.
86
-
87
- ## Depends On
88
-
89
- - [`@owlmeans/queue`](../queue) — `ctx.jobs(queue)`, `JobRecord`, `JobEvent`, `UnknownJob`
90
- - [`@owlmeans/server-api`](../server-api) — `handleRequest` / `handleParams`
91
- - [`@owlmeans/server-socket`](../server-socket) — `handleConnection`
92
- - [`@owlmeans/server-entrypoint`](../server-entrypoint) — `elevate`
93
- - [`@owlmeans/auth-common`](../auth-common) — `DEFAULT_GUARD`
94
-
95
- ## Related
96
-
97
- - [`@owlmeans/client-job`](../client-job) — the browser half that addresses these entrypoints
98
- - [`@owlmeans/web-panel`](../web-panel) `./jobs` — `JobProgress`, `JobStatus`, `useJobToasts`
5
+ Declare a group in shared code with `declareJobEntrypoints(root, options)`, then register
6
+ `...serveJobEntrypoints(jobProtocols)` in the API runtime. The package returns local bindings and
7
+ keeps the shared job declarations immutable.
99
8
 
100
9
  <!-- owlmeans:agent-guidance:start -->
101
10
  ## Agent guidance
@@ -105,7 +14,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
105
14
  your project's skill store (`.agents/skills/`):
106
15
 
107
16
  ```sh
108
- npx @owlmeans/agent-skills@^0.1.18-rc.14
17
+ npx @owlmeans/agent-skills@^0.1.18-rc.16
109
18
  ```
110
19
 
111
20
  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/server-job",
4
- "version": "0.1.18-rc.2",
5
- "generatedAt": "2026-09-10T23:12:07.514Z",
4
+ "version": "0.1.18-rc.4",
5
+ "generatedAt": "2026-09-12T12:32:46.377Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: server-job
3
- description: How to use @owlmeans/server-job — declaring and elevating the list/get/cancel/watch entrypoints over a queue, the ownership rule that scopes them to the authenticated subject, the admin escape hatch, and the socket that pushes JobEvent frames. Auto-invoked when exposing queue jobs to an application's UI or importing job entrypoint helpers.
3
+ description: How to use @owlmeans/server-job — declaring and binding the list/get/cancel/watch entrypoints over a queue, the ownership rule that scopes them to the authenticated subject, the admin escape hatch, and the socket that pushes JobEvent frames. Auto-invoked when exposing queue jobs to an application's UI or importing job entrypoint helpers.
4
4
  user-invocable: false
5
5
  ---
6
6
  <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
@@ -8,10 +8,10 @@ user-invocable: false
8
8
  # @owlmeans/server-job
9
9
 
10
10
  **Layer:** Server
11
- **Install:** `"@owlmeans/server-job": "^0.1.18-rc.2"` in `dependencies`
11
+ **Install:** `"@owlmeans/server-job": "^0.1.18-rc.4"` in `dependencies`
12
12
 
13
13
  The READ side of a queue. `@owlmeans/queue` and its driver enqueue and process; this package turns
14
- what they leave behind into four entrypoints an application elevates, so that "a long job reports
14
+ what they leave behind into four entrypoints an application binds, so that "a long job reports
15
15
  progress to the user's screen" is wiring rather than code.
16
16
 
17
17
  ## Key Exports
@@ -20,8 +20,8 @@ progress to the user's screen" is wiring rather than code.
20
20
  |--------|-------------|
21
21
  | `declareJobEntrypoints(root, opts?)` | The four declarations of one job group, for the SHARED package |
22
22
  | `jobEntrypointAliases(root)` | `{ base, list, get, cancel, watch }` — the alias shape both halves use |
23
- | `serveJobEntrypoints(entrypoints, root, opts?)` | Elevate the group with this package's handlers |
24
- | `listJobs(opts?)` / `getJob(opts?)` / `cancelJob(opts?)` | The HTTP handlers, for elevating by hand |
23
+ | `serveJobEntrypoints(jobProtocols, opts?)` | Return the local bindings for one declared job protocol group |
24
+ | `listJobs(opts?)` / `getJob(opts?)` / `cancelJob(opts?)` | The HTTP handlers, for binding by hand |
25
25
  | `watchJobs(opts?)` | The socket handler — pushes `JobEvent` frames under `JOB_EVENT` |
26
26
  | `jobOwnerOf(req)` / `requireJobOwner(req)` / `jobViewer(req, ctx, opts?)` | Who a request reads as |
27
27
  | `jobScope(viewer, opts?)` / `owns(record, viewer, opts?)` / `readOwnedJob(...)` | Applying that to records |
@@ -40,9 +40,9 @@ the package its API and its browser both import, and neither side ever writes a
40
40
  import { declareJobEntrypoints } from '@owlmeans/server-job'
41
41
 
42
42
  export const REPORTS = 'reports'
43
- export const entrypoints = [
44
- ...declareJobEntrypoints(REPORTS, { path: '/reports/jobs', parent: app.api.base }),
45
- ]
43
+ export const protocols = {
44
+ jobs: declareJobEntrypoints(REPORTS, { path: '/reports/jobs', parent: app.api.base }),
45
+ }
46
46
  ```
47
47
 
48
48
  Aliases are `<root>`, `<root>:list`, `<root>:get`, `<root>:cancel`, `<root>:watch`. **That shape,
@@ -65,15 +65,16 @@ import { serveJobEntrypoints } from '@owlmeans/server-job'
65
65
  import { appendRedisQueue } from '@owlmeans/redis-queue'
66
66
 
67
67
  appendRedisQueue(context)
68
- serveJobEntrypoints(entrypoints, REPORTS, { queue: REPORT_QUEUE })
69
- context.registerEntrypoints(entrypoints)
68
+ export const appEntrypoints = [
69
+ ...serveJobEntrypoints(protocols.jobs, { queue: REPORT_QUEUE }),
70
+ ]
71
+ context.registerEntrypoints(appEntrypoints)
70
72
  ```
71
73
 
72
- `elevate` replaces in place, so an app wanting one handler of its own elevates that alias again
73
- afterwards. `queue` names which declared queue the group reads; omitted, `ctx.jobs()` answers with
74
- the sole declared queue and refuses to guess once there are two. Passing an array that carries no
75
- group under that root is a `SyntaxError` — the declarations and the serving call must name the same
76
- root, and they usually do because both read it from one exported constant.
74
+ Pass the declared protocol group, never a flattened or materialized entrypoint list. `serveJobEntrypoints()`
75
+ returns only local bindings; an app wanting a custom handler binds the same protocol afterwards.
76
+ `queue` names which declared queue the group reads; omitted, `ctx.jobs()` answers with the sole
77
+ declared queue and refuses to guess once there are two.
77
78
 
78
79
  ## The ownership rule
79
80
 
@@ -98,7 +99,7 @@ The escape hatch is a predicate, never a permission name — which permission, g
98
99
  "operator" is the application's decision:
99
100
 
100
101
  ```typescript
101
- serveJobEntrypoints(entrypoints, REPORTS, {
102
+ serveJobEntrypoints(protocols.jobs, {
102
103
  queue: REPORT_QUEUE,
103
104
  admin: req => req.auth?.scopes?.includes('ops') === true,
104
105
  })
@@ -127,9 +128,9 @@ than fanned out to everyone. **Leave completed jobs in place on any queue that i
127
128
  ## Depends On
128
129
 
129
130
  - `@owlmeans/queue` — `ctx.jobs(queue)`, `JobRecord`, `JobEvent`, `JobState`, `UnknownJob`
130
- - `@owlmeans/server-api` — `handleRequest`, `handleParams`
131
- - `@owlmeans/server-socket` — `handleConnection`, and the guard enforcement that fills `req.auth`
132
- - `@owlmeans/server-entrypoint` — `elevate`
131
+ - `@owlmeans/server-api` — `handlers`
132
+ - `@owlmeans/server-socket` — `connection(protocol, callback)` and guard enforcement that fills `req.auth`
133
+ - `@owlmeans/server-entrypoint` — `bind`
133
134
  - `@owlmeans/auth-common` — `DEFAULT_GUARD`
134
135
 
135
136
  ## Related
@@ -1,6 +1,5 @@
1
- import type { AbstractResponse } from '@owlmeans/entrypoint';
2
- import type { RefedEntrypointHandler } from '@owlmeans/server-entrypoint';
3
- import type { JobHandlerOptions } from '../types.js';
1
+ import { handlers } from '@owlmeans/server-api';
2
+ import type { Context, JobEntrypoints, JobHandlerOptions } from '../types.js';
4
3
  /**
5
4
  * Cancel a job and answer with what was cancelled.
6
5
  *
@@ -11,5 +10,5 @@ import type { JobHandlerOptions } from '../types.js';
11
10
  *
12
11
  * @throws {UnknownJob}
13
12
  */
14
- export declare const cancelJob: (opts?: JobHandlerOptions) => RefedEntrypointHandler<AbstractResponse<any>>;
13
+ export declare const cancelJob: (protocol: JobEntrypoints['cancel'], opts?: JobHandlerOptions) => ReturnType<ReturnType<typeof handlers<Context>>['params']>;
15
14
  //# sourceMappingURL=cancel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cancel.d.ts","sourceRoot":"","sources":["../../src/actions/cancel.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAGpD;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS,UACb,iBAAiB,KACvB,sBAAsB,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAO3C,CAAA"}
1
+ {"version":3,"file":"cancel.d.ts","sourceRoot":"","sources":["../../src/actions/cancel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAG7E;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS,aACV,cAAc,CAAC,QAAQ,CAAC,SAC3B,iBAAiB,KACvB,UAAU,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAOxD,CAAA"}
@@ -1,4 +1,4 @@
1
- import { handleParams } from '@owlmeans/server-api';
1
+ import { handlers } from '@owlmeans/server-api';
2
2
  import { jobViewer, jobsOf, readOwnedJob } from '../utils/index.js';
3
3
  /**
4
4
  * Cancel a job and answer with what was cancelled.
@@ -10,7 +10,7 @@ import { jobViewer, jobsOf, readOwnedJob } from '../utils/index.js';
10
10
  *
11
11
  * @throws {UnknownJob}
12
12
  */
13
- export const cancelJob = (opts) => handleParams(async ({ id }, ctx, req) => {
13
+ export const cancelJob = (protocol, opts) => handlers().params(protocol, async ({ id }, ctx, req) => {
14
14
  const resource = jobsOf(ctx, opts);
15
15
  // Read first: `take` cannot tell whose job it removed, so ownership is settled before it.
16
16
  await readOwnedJob(resource, id, await jobViewer(req, ctx, opts), opts);
@@ -1 +1 @@
1
- {"version":3,"file":"cancel.js","sourceRoot":"","sources":["../../src/actions/cancel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAInD,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEnE;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,IAAwB,EACuB,EAAE,CACjD,YAAY,CAAiB,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACtD,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAClC,0FAA0F;IAC1F,MAAM,YAAY,CAAC,QAAQ,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAA;IAEvE,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AAChC,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"cancel.js","sourceRoot":"","sources":["../../src/actions/cancel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAE/C,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEnE;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,QAAkC,EAClC,IAAwB,EACoC,EAAE,CAC9D,QAAQ,EAAW,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IAC9D,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAClC,0FAA0F;IAC1F,MAAM,YAAY,CAAC,QAAQ,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAA;IAEvE,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AAChC,CAAC,CAAC,CAAA"}
@@ -1,10 +1,9 @@
1
- import type { AbstractResponse } from '@owlmeans/entrypoint';
2
- import type { RefedEntrypointHandler } from '@owlmeans/server-entrypoint';
3
- import type { JobHandlerOptions } from '../types.js';
1
+ import { handlers } from '@owlmeans/server-api';
2
+ import type { Context, JobEntrypoints, JobHandlerOptions } from '../types.js';
4
3
  /**
5
4
  * One job.
6
5
  *
7
6
  * @throws {UnknownJob} for an id that is absent AND for one that belongs to someone else.
8
7
  */
9
- export declare const getJob: (opts?: JobHandlerOptions) => RefedEntrypointHandler<AbstractResponse<any>>;
8
+ export declare const getJob: (protocol: JobEntrypoints['get'], opts?: JobHandlerOptions) => ReturnType<ReturnType<typeof handlers<Context>>['params']>;
10
9
  //# sourceMappingURL=get.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../src/actions/get.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAGpD;;;;GAIG;AACH,eAAO,MAAM,MAAM,UACV,iBAAiB,KACvB,sBAAsB,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAK3C,CAAA"}
1
+ {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../src/actions/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAG7E;;;;GAIG;AACH,eAAO,MAAM,MAAM,aACP,cAAc,CAAC,KAAK,CAAC,SACxB,iBAAiB,KACvB,UAAU,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAKxD,CAAA"}
@@ -1,11 +1,11 @@
1
- import { handleParams } from '@owlmeans/server-api';
1
+ import { handlers } from '@owlmeans/server-api';
2
2
  import { jobViewer, jobsOf, readOwnedJob } from '../utils/index.js';
3
3
  /**
4
4
  * One job.
5
5
  *
6
6
  * @throws {UnknownJob} for an id that is absent AND for one that belongs to someone else.
7
7
  */
8
- export const getJob = (opts) => handleParams(async ({ id }, ctx, req) => {
8
+ export const getJob = (protocol, opts) => handlers().params(protocol, async ({ id }, ctx, req) => {
9
9
  const resource = jobsOf(ctx, opts);
10
10
  return await readOwnedJob(resource, id, await jobViewer(req, ctx, opts), opts);
11
11
  });
@@ -1 +1 @@
1
- {"version":3,"file":"get.js","sourceRoot":"","sources":["../../src/actions/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAInD,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEnE;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CACpB,IAAwB,EACuB,EAAE,CACjD,YAAY,CAAiB,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACtD,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAElC,OAAO,MAAM,YAAY,CAAC,QAAQ,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAA;AAChF,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"get.js","sourceRoot":"","sources":["../../src/actions/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAE/C,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEnE;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CACpB,QAA+B,EAC/B,IAAwB,EACoC,EAAE,CAC9D,QAAQ,EAAW,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IAC9D,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAElC,OAAO,MAAM,YAAY,CAAC,QAAQ,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAA;AAChF,CAAC,CAAC,CAAA"}
@@ -1,6 +1,5 @@
1
- import type { AbstractResponse } from '@owlmeans/entrypoint';
2
- import type { RefedEntrypointHandler } from '@owlmeans/server-entrypoint';
3
- import type { JobHandlerOptions } from '../types.js';
1
+ import { handlers } from '@owlmeans/server-api';
2
+ import type { Context, JobEntrypoints, JobHandlerOptions } from '../types.js';
4
3
  /**
5
4
  * The caller's jobs, newest first.
6
5
  *
@@ -9,5 +8,5 @@ import type { JobHandlerOptions } from '../types.js';
9
8
  * name filters go through the same criteria language as every other resource, so a filter written
10
9
  * for this list means the same thing applied to the store the browser holds.
11
10
  */
12
- export declare const listJobs: (opts?: JobHandlerOptions) => RefedEntrypointHandler<AbstractResponse<any>>;
11
+ export declare const listJobs: (protocol: JobEntrypoints['list'], opts?: JobHandlerOptions) => ReturnType<ReturnType<typeof handlers<Context>>['request']>;
13
12
  //# sourceMappingURL=list.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/actions/list.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAKzE,OAAO,KAAK,EAAE,iBAAiB,EAAgB,MAAM,aAAa,CAAA;AAGlE;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,UACZ,iBAAiB,KACvB,sBAAsB,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAe7C,CAAA"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/actions/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAK/C,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAgB,MAAM,aAAa,CAAA;AAG3F;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,aACT,cAAc,CAAC,MAAM,CAAC,SACzB,iBAAiB,KACvB,UAAU,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAe3D,CAAA"}
@@ -1,4 +1,4 @@
1
- import { handleRequest } from '@owlmeans/server-api';
1
+ import { handlers } from '@owlmeans/server-api';
2
2
  import { DEFAULT_JOB_SORT } from '../consts.js';
3
3
  import { jobScope, jobViewer, jobsOf } from '../utils/index.js';
4
4
  /**
@@ -9,7 +9,7 @@ import { jobScope, jobViewer, jobsOf } from '../utils/index.js';
9
9
  * name filters go through the same criteria language as every other resource, so a filter written
10
10
  * for this list means the same thing applied to the store the browser holds.
11
11
  */
12
- export const listJobs = (opts) => handleRequest(async (req, ctx) => {
12
+ export const listJobs = (protocol, opts) => handlers().request(protocol, async (req, ctx) => {
13
13
  const resource = jobsOf(ctx, opts);
14
14
  const viewer = await jobViewer(req, ctx, opts);
15
15
  const query = (req.query ?? {});
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/actions/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAMpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAE/D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,IAAwB,EACuB,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACnF,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAClC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC9C,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAiB,CAAA;IAE/C,MAAM,KAAK,GAAwB;QACjC,GAAG,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;QACzB,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClE,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpD,CAAA;IAED,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE;QAChC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAClD,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3E,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/actions/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAI/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAE/D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,QAAgC,EAChC,IAAwB,EACqC,EAAE,CAAC,QAAQ,EAAW,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACzH,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAClC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC9C,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAiB,CAAA;IAE/C,MAAM,KAAK,GAAwB;QACjC,GAAG,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;QACzB,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClE,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpD,CAAA;IAED,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE;QAChC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAClD,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3E,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -1,6 +1,5 @@
1
- import type { AbstractResponse } from '@owlmeans/entrypoint';
2
- import type { RefedEntrypointHandler } from '@owlmeans/server-entrypoint';
3
- import type { JobHandlerOptions } from '../types.js';
1
+ import { connection } from '@owlmeans/server-socket';
2
+ import type { JobEntrypoints, JobHandlerOptions } from '../types.js';
4
3
  /**
5
4
  * Push this caller's job lifecycle events down a socket.
6
5
  *
@@ -13,5 +12,5 @@ import type { JobHandlerOptions } from '../types.js';
13
12
  * attributed by is gone by the time the event arrives, and an unattributable event is dropped
14
13
  * rather than fanned out to everyone. Leave completed jobs in place on any queue that is watched.
15
14
  */
16
- export declare const watchJobs: (opts?: JobHandlerOptions) => RefedEntrypointHandler<AbstractResponse<any>>;
15
+ export declare const watchJobs: (protocol: JobEntrypoints['watch'], opts?: JobHandlerOptions) => ReturnType<typeof connection>;
17
16
  //# sourceMappingURL=watch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/actions/watch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAKzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAGpD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,SAAS,UACb,iBAAiB,KACvB,sBAAsB,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAyC7C,CAAA"}
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/actions/watch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAKpD,OAAO,KAAK,EAAW,cAAc,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAG7E;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,SAAS,aACV,cAAc,CAAC,OAAO,CAAC,SAC1B,iBAAiB,KACvB,UAAU,CAAC,OAAO,UAAU,CAyC7B,CAAA"}
@@ -1,4 +1,4 @@
1
- import { handleConnection } from '@owlmeans/server-socket';
1
+ import { connection } from '@owlmeans/server-socket';
2
2
  import { MessageType } from '@owlmeans/socket';
3
3
  import { JOB_EVENT } from '../consts.js';
4
4
  import { jobViewer, jobsOf, owns } from '../utils/index.js';
@@ -14,7 +14,7 @@ import { jobViewer, jobsOf, owns } from '../utils/index.js';
14
14
  * attributed by is gone by the time the event arrives, and an unattributable event is dropped
15
15
  * rather than fanned out to everyone. Leave completed jobs in place on any queue that is watched.
16
16
  */
17
- export const watchJobs = (opts) => handleConnection(async (conn, ctx, req) => {
17
+ export const watchJobs = (protocol, opts) => connection(protocol, async (conn, ctx, req) => {
18
18
  const resource = jobsOf(ctx, opts);
19
19
  const viewer = await jobViewer(req, ctx, opts);
20
20
  const mine = new Set();
@@ -1 +1 @@
1
- {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/actions/watch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAI1D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAExC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAA;AAE3D;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,IAAwB,EACuB,EAAE,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IAC5F,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAClC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC9C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;IAE9B,MAAM,YAAY,GAAG,KAAK,EAAE,KAAe,EAAoB,EAAE;QAC/D,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YACzC,OAAO,IAAI,CAAA;QACb,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC5C,IAAI,MAAM,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;YAClD,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAElB,OAAO,IAAI,CAAA;IACb,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,KAAK,EAAC,KAAK,EAAC,EAAE;QACzD,IAAI,CAAC;YACH,IAAI,MAAM,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9B,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;YACrC,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,CAAC,CAAC,CAAA;QAC7C,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,MAAM,CAAC,KAAK,EAAC,OAAO,EAAC,EAAE;QAC1B,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAM;QACR,CAAC;QACD,MAAM,GAAG,GAAG,OAA6B,CAAA;QACzC,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,MAAM,IAAI,GAAG,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;YAC7D,IAAI,CAAC;gBACH,MAAM,WAAW,EAAE,CAAA;YACrB,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAA;YAClD,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/actions/watch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAExC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAA;AAE3D;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,QAAiC,EACjC,IAAwB,EACO,EAAE,CAAC,UAAU,CAA2B,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IAC1G,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAClC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC9C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;IAE9B,MAAM,YAAY,GAAG,KAAK,EAAE,KAAe,EAAoB,EAAE;QAC/D,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YACzC,OAAO,IAAI,CAAA;QACb,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC5C,IAAI,MAAM,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;YAClD,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAElB,OAAO,IAAI,CAAA;IACb,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,KAAK,EAAC,KAAK,EAAC,EAAE;QACzD,IAAI,CAAC;YACH,IAAI,MAAM,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9B,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;YACrC,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,CAAC,CAAC,CAAA;QAC7C,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,MAAM,CAAC,KAAK,EAAC,OAAO,EAAC,EAAE;QAC1B,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAM;QACR,CAAC;QACD,MAAM,GAAG,GAAG,OAA6B,CAAA;QACzC,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,MAAM,IAAI,GAAG,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;YAC7D,IAAI,CAAC;gBACH,MAAM,WAAW,EAAE,CAAA;YACrB,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAA;YAClD,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -1,5 +1,4 @@
1
- import type { CommonEntrypoint } from '@owlmeans/entrypoint';
2
- import type { JobEntrypointAliases, JobEntrypointOptions } from './types.js';
1
+ import type { JobEntrypointAliases, JobEntrypoints, JobEntrypointOptions } from './types.js';
3
2
  /**
4
3
  * The aliases one job group answers under.
5
4
  *
@@ -11,11 +10,11 @@ export declare const jobEntrypointAliases: (root: string) => JobEntrypointAliase
11
10
  * Declare the list/get/cancel/watch entrypoints of one job group.
12
11
  *
13
12
  * It belongs in the SHARED package of a target app — the one both the API and the browser import —
14
- * so that the server elevates and the client calls the very declarations, and neither side ever
13
+ * so that the server binds and the client calls the very declarations, and neither side ever
15
14
  * writes a path. Declaring a second group is the same call with another root.
16
15
  *
17
16
  * The guard rides on the base alone: guards are inherited, so stating it once is what keeps the
18
17
  * four from drifting apart.
19
18
  */
20
- export declare const declareJobEntrypoints: (root: string, opts?: JobEntrypointOptions) => CommonEntrypoint[];
19
+ export declare const declareJobEntrypoints: (root: string, opts?: JobEntrypointOptions) => JobEntrypoints;
21
20
  //# sourceMappingURL=entrypoints.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"entrypoints.d.ts","sourceRoot":"","sources":["../src/entrypoints.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAM5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAE5E;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,SAAU,MAAM,KAAG,oBAMlD,CAAA;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,SAC1B,MAAM,SAAS,oBAAoB,KACxC,gBAAgB,EAoBlB,CAAA"}
1
+ {"version":3,"file":"entrypoints.d.ts","sourceRoot":"","sources":["../src/entrypoints.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,oBAAoB,EAAgB,MAAM,YAAY,CAAA;AAE1G;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,SAAU,MAAM,KAAG,oBAMlD,CAAA;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,SAC1B,MAAM,SAAS,oBAAoB,KACxC,cA0BF,CAAA"}
@@ -1,4 +1,4 @@
1
- import { entrypoint, filter, guard, query } from '@owlmeans/entrypoint';
1
+ import { contract, openProtocol, protocol, typed } from '@owlmeans/entrypoint';
2
2
  import { backend, route, RouteMethod, socket } from '@owlmeans/route';
3
3
  import { DEFAULT_GUARD } from '@owlmeans/auth-common';
4
4
  import { DEFAULT_JOB_PATH } from './consts.js';
@@ -20,7 +20,7 @@ export const jobEntrypointAliases = (root) => ({
20
20
  * Declare the list/get/cancel/watch entrypoints of one job group.
21
21
  *
22
22
  * It belongs in the SHARED package of a target app — the one both the API and the browser import —
23
- * so that the server elevates and the client calls the very declarations, and neither side ever
23
+ * so that the server binds and the client calls the very declarations, and neither side ever
24
24
  * writes a path. Declaring a second group is the same call with another root.
25
25
  *
26
26
  * The guard rides on the base alone: guards are inherited, so stating it once is what keeps the
@@ -32,15 +32,15 @@ export const declareJobEntrypoints = (root, opts) => {
32
32
  ...(opts?.parent != null ? { parent: opts.parent } : {}),
33
33
  ...(opts?.service != null ? { service: opts.service } : {}),
34
34
  };
35
- const guarded = opts?.guard === null ? undefined : guard(opts?.guard ?? DEFAULT_GUARD);
36
- return [
37
- entrypoint(route(aliases.base, opts?.path ?? DEFAULT_JOB_PATH, backend(base)), guarded),
38
- entrypoint(route(aliases.list, '/', backend(aliases.base)), filter(query(JobListQuerySchema))),
35
+ const guarded = opts?.guard === null ? undefined : { guards: opts?.guard ?? DEFAULT_GUARD };
36
+ return {
37
+ base: openProtocol(route(aliases.base, opts?.path ?? DEFAULT_JOB_PATH, backend(base)), guarded),
38
+ list: protocol(route(aliases.list, '/', backend(aliases.base)), contract.request({ query: typed(JobListQuerySchema) }, typed())),
39
39
  // Static before parametric, so `/watch` is not swallowed by `/:id`. The router picks the
40
40
  // static branch on its own; the order here is for whoever reads the declaration.
41
- entrypoint(route(aliases.watch, '/watch', socket(aliases.base))),
42
- entrypoint(route(aliases.get, '/:id', backend(aliases.base))),
43
- entrypoint(route(aliases.cancel, '/:id', backend(aliases.base, RouteMethod.DELETE))),
44
- ];
41
+ watch: protocol(route(aliases.watch, '/watch', socket(aliases.base)), contract(typed())),
42
+ get: protocol(route(aliases.get, '/:id', backend(aliases.base)), contract.request({ params: typed() }, typed())),
43
+ cancel: protocol(route(aliases.cancel, '/:id', backend(aliases.base, RouteMethod.DELETE)), contract.request({ params: typed() }, typed())),
44
+ };
45
45
  };
46
46
  //# sourceMappingURL=entrypoints.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"entrypoints.js","sourceRoot":"","sources":["../src/entrypoints.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAEvE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAErE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAGjD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,IAAY,EAAwB,EAAE,CAAC,CAAC;IAC3E,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,GAAG,IAAI,OAAO;IACpB,GAAG,EAAE,GAAG,IAAI,MAAM;IAClB,MAAM,EAAE,GAAG,IAAI,SAAS;IACxB,KAAK,EAAE,GAAG,IAAI,QAAQ;CACvB,CAAC,CAAA;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,IAAY,EAAE,IAA2B,EACrB,EAAE;IACtB,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAA;IAC1C,MAAM,IAAI,GAA0B;QAClC,GAAG,CAAC,IAAI,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,GAAG,CAAC,IAAI,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5D,CAAA;IACD,MAAM,OAAO,GAAG,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,aAAa,CAAC,CAAA;IAEtF,OAAO;QACL,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,gBAAgB,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC;QACvF,UAAU,CACR,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAC/C,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAClC;QACD,yFAAyF;QACzF,iFAAiF;QACjF,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAChE,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7D,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;KACrF,CAAA;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"entrypoints.js","sourceRoot":"","sources":["../src/entrypoints.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC9E,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAErE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAGjD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,IAAY,EAAwB,EAAE,CAAC,CAAC;IAC3E,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,GAAG,IAAI,OAAO;IACpB,GAAG,EAAE,GAAG,IAAI,MAAM;IAClB,MAAM,EAAE,GAAG,IAAI,SAAS;IACxB,KAAK,EAAE,GAAG,IAAI,QAAQ;CACvB,CAAC,CAAA;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,IAAY,EAAE,IAA2B,EACzB,EAAE;IAClB,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAA;IAC1C,MAAM,IAAI,GAA0B;QAClC,GAAG,CAAC,IAAI,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,GAAG,CAAC,IAAI,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5D,CAAA;IACD,MAAM,OAAO,GAAG,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,aAAa,EAAE,CAAA;IAE3F,OAAO;QACL,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,gBAAgB,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC;QAC/F,IAAI,EAAE,QAAQ,CACZ,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAC/C,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,CAAe,kBAAkB,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAC9E;QACD,yFAAyF;QACzF,iFAAiF;QACjF,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,KAAK,EAAQ,CAAC,CAAC;QAC9F,GAAG,EAAE,QAAQ,CACX,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EACjD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAkB,EAAE,EAAE,KAAK,EAAE,CAAC,CAC/D;QACD,MAAM,EAAE,QAAQ,CACd,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,EACxE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAkB,EAAE,EAAE,KAAK,EAAE,CAAC,CAC/D;KACF,CAAA;AACH,CAAC,CAAA"}
package/build/helper.d.ts CHANGED
@@ -1,14 +1,12 @@
1
- import type { ServerEntrypoint } from '@owlmeans/server-entrypoint';
2
- import type { CommonEntrypoint } from '@owlmeans/entrypoint';
3
- import type { JobHandlerOptions } from './types.js';
1
+ import type { JobEntrypoints, JobHandlerOptions } from './types.js';
4
2
  /**
5
3
  * Attach this package's handlers to a group declared by {@link declareJobEntrypoints}.
6
4
  *
7
5
  * The whole server half of "a long job reports progress to the user's screen" is this call plus
8
6
  * the queue driver an app already wires — nothing is subclassed, and an app that wants one
9
- * handler of its own elevates that alias itself afterwards, since `elevate` replaces in place.
7
+ * handler of its own binds that alias itself afterwards.
10
8
  *
11
9
  * @throws {SyntaxError} when the array carries no group under that root.
12
10
  */
13
- export declare const serveJobEntrypoints: <R>(entrypoints: (CommonEntrypoint | ServerEntrypoint<R>)[], root: string, opts?: JobHandlerOptions) => ServerEntrypoint<R>[];
11
+ export declare const serveJobEntrypoints: (entrypoints: JobEntrypoints, opts?: JobHandlerOptions) => import("@owlmeans/server-entrypoint").ServerProtocolEntrypoint<import("@owlmeans/entrypoint").EntrypointProtocolDeclaration>[];
14
12
  //# sourceMappingURL=helper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAG5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,eACtB,CAAC,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,MAAM,SAAS,iBAAiB,KAC9F,gBAAgB,CAAC,CAAC,CAAC,EASrB,CAAA"}
1
+ {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnE;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,gBAAiB,cAAc,SAAS,iBAAiB,mIAMxF,CAAA"}
package/build/helper.js CHANGED
@@ -1,21 +1,19 @@
1
- import { elevate } from '@owlmeans/server-entrypoint';
2
- import { jobEntrypointAliases } from './entrypoints.js';
1
+ import { bind } from '@owlmeans/server-entrypoint';
3
2
  import { cancelJob, getJob, listJobs, watchJobs } from './actions/index.js';
4
3
  /**
5
4
  * Attach this package's handlers to a group declared by {@link declareJobEntrypoints}.
6
5
  *
7
6
  * The whole server half of "a long job reports progress to the user's screen" is this call plus
8
7
  * the queue driver an app already wires — nothing is subclassed, and an app that wants one
9
- * handler of its own elevates that alias itself afterwards, since `elevate` replaces in place.
8
+ * handler of its own binds that alias itself afterwards.
10
9
  *
11
10
  * @throws {SyntaxError} when the array carries no group under that root.
12
11
  */
13
- export const serveJobEntrypoints = (entrypoints, root, opts) => {
14
- const aliases = jobEntrypointAliases(root);
15
- elevate(entrypoints, aliases.base);
16
- elevate(entrypoints, aliases.list, listJobs(opts));
17
- elevate(entrypoints, aliases.watch, watchJobs(opts));
18
- elevate(entrypoints, aliases.get, getJob(opts));
19
- return elevate(entrypoints, aliases.cancel, cancelJob(opts));
20
- };
12
+ export const serveJobEntrypoints = (entrypoints, opts) => [
13
+ bind(entrypoints.base),
14
+ bind(entrypoints.list, listJobs(entrypoints.list, opts)),
15
+ bind(entrypoints.watch, watchJobs(entrypoints.watch, opts)),
16
+ bind(entrypoints.get, getJob(entrypoints.get, opts)),
17
+ bind(entrypoints.cancel, cancelJob(entrypoints.cancel, opts)),
18
+ ];
21
19
  //# sourceMappingURL=helper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AAGrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAG3E;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,WAAuD,EAAE,IAAY,EAAE,IAAwB,EACxE,EAAE;IACzB,MAAM,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAA;IAE1C,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IAClC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;IAClD,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAA;IACpD,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;IAE/C,OAAO,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAA;AAC9D,CAAC,CAAA"}
1
+ {"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAG3E;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,WAA2B,EAAE,IAAwB,EAAE,EAAE,CAAC;IAC5F,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IACtB,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACxD,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC3D,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACpD,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;CAC9D,CAAA"}
package/build/types.d.ts CHANGED
@@ -3,6 +3,7 @@ import type { AbstractRequest } from '@owlmeans/entrypoint';
3
3
  import type { QueueAppend, QueueConfig } from '@owlmeans/queue';
4
4
  import type { ApiServerAppend } from '@owlmeans/server-api';
5
5
  import type { ServerConfig, ServerContext } from '@owlmeans/server-context';
6
+ import type { EntrypointProtocol, OpenRequest, OpenValue } from '@owlmeans/entrypoint';
6
7
  export interface Config extends ServerConfig {
7
8
  queue?: QueueConfig;
8
9
  }
@@ -16,6 +17,24 @@ export interface JobEntrypointAliases {
16
17
  cancel: string;
17
18
  watch: string;
18
19
  }
20
+ /** The immutable declarations for one job group, addressed by property rather than alias lookup. */
21
+ export interface JobEntrypoints {
22
+ base: EntrypointProtocol<OpenRequest, OpenValue>;
23
+ list: EntrypointProtocol<{
24
+ query: JobListQuery;
25
+ }, unknown>;
26
+ get: EntrypointProtocol<{
27
+ params: {
28
+ id: string;
29
+ };
30
+ }, unknown>;
31
+ cancel: EntrypointProtocol<{
32
+ params: {
33
+ id: string;
34
+ };
35
+ }, unknown>;
36
+ watch: EntrypointProtocol<OpenRequest, void>;
37
+ }
19
38
  export interface JobEntrypointOptions {
20
39
  /** The path segment the group answers under. Defaults to `/jobs`. */
21
40
  path?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAE3E,MAAM,WAAW,MAAO,SAAQ,YAAY;IAC1C,KAAK,CAAC,EAAE,WAAW,CAAA;CACpB;AAED,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC,EAC1E,eAAe,EAAE,WAAW;CAAI;AAElC,gGAAgG;AAChG,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,wFAAwF;IACxF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,8DAA8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,CAAC,WAAW,CAAC,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACnF;AAED,MAAM,WAAW,iBAAiB;IAChC,uFAAuF;IACvF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mFAAmF;IACnF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,qFAAqF;IACrF,KAAK,CAAC,EAAE,aAAa,CAAA;CACtB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAEtF,MAAM,WAAW,MAAO,SAAQ,YAAY;IAC1C,KAAK,CAAC,EAAE,WAAW,CAAA;CACpB;AAED,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC,EAC1E,eAAe,EAAE,WAAW;CAAI;AAElC,gGAAgG;AAChG,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACd;AAED,oGAAoG;AACpG,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,kBAAkB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;IAChD,IAAI,EAAE,kBAAkB,CAAC;QAAE,KAAK,EAAE,YAAY,CAAA;KAAE,EAAE,OAAO,CAAC,CAAA;IAC1D,GAAG,EAAE,kBAAkB,CAAC;QAAE,MAAM,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,EAAE,OAAO,CAAC,CAAA;IAC5D,MAAM,EAAE,kBAAkB,CAAC;QAAE,MAAM,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,EAAE,OAAO,CAAC,CAAA;IAC/D,KAAK,EAAE,kBAAkB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;CAC7C;AAED,MAAM,WAAW,oBAAoB;IACnC,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,wFAAwF;IACxF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,8DAA8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,CAAC,WAAW,CAAC,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACnF;AAED,MAAM,WAAW,iBAAiB;IAChC,uFAAuF;IACvF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mFAAmF;IACnF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,qFAAqF;IACrF,KAAK,CAAC,EAAE,aAAa,CAAA;CACtB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/server-job",
3
- "version": "0.1.18-rc.2",
3
+ "version": "0.1.18-rc.4",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -30,17 +30,17 @@
30
30
  "access": "public"
31
31
  },
32
32
  "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/queue": "^0.1.18-rc.11",
38
- "@owlmeans/resource": "^0.1.18-rc.11",
39
- "@owlmeans/route": "^0.1.18-rc.11",
40
- "@owlmeans/server-api": "^0.1.18-rc.19",
41
- "@owlmeans/server-context": "^0.1.18-rc.14",
42
- "@owlmeans/server-entrypoint": "^0.1.18-rc.13",
43
- "@owlmeans/server-socket": "^0.1.18-rc.20",
44
- "@owlmeans/socket": "^0.1.18-rc.11"
33
+ "@owlmeans/auth": "^0.1.18-rc.13",
34
+ "@owlmeans/auth-common": "^0.1.18-rc.17",
35
+ "@owlmeans/context": "^0.1.18-rc.12",
36
+ "@owlmeans/entrypoint": "^0.1.18-rc.15",
37
+ "@owlmeans/queue": "^0.1.18-rc.13",
38
+ "@owlmeans/resource": "^0.1.18-rc.13",
39
+ "@owlmeans/route": "^0.1.18-rc.13",
40
+ "@owlmeans/server-api": "^0.1.18-rc.21",
41
+ "@owlmeans/server-context": "^0.1.18-rc.16",
42
+ "@owlmeans/server-entrypoint": "^0.1.18-rc.15",
43
+ "@owlmeans/server-socket": "^0.1.18-rc.22",
44
+ "@owlmeans/socket": "^0.1.18-rc.13"
45
45
  }
46
46
  }
@@ -1,7 +1,5 @@
1
- import { handleParams } from '@owlmeans/server-api'
2
- import type { AbstractResponse } from '@owlmeans/entrypoint'
3
- import type { RefedEntrypointHandler } from '@owlmeans/server-entrypoint'
4
- import type { JobHandlerOptions } from '../types.js'
1
+ import { handlers } from '@owlmeans/server-api'
2
+ import type { Context, JobEntrypoints, JobHandlerOptions } from '../types.js'
5
3
  import { jobViewer, jobsOf, readOwnedJob } from '../utils/index.js'
6
4
 
7
5
  /**
@@ -15,9 +13,10 @@ import { jobViewer, jobsOf, readOwnedJob } from '../utils/index.js'
15
13
  * @throws {UnknownJob}
16
14
  */
17
15
  export const cancelJob = (
16
+ protocol: JobEntrypoints['cancel'],
18
17
  opts?: JobHandlerOptions
19
- ): RefedEntrypointHandler<AbstractResponse<any>> =>
20
- handleParams<{ id: string }>(async ({ id }, ctx, req) => {
18
+ ): ReturnType<ReturnType<typeof handlers<Context>>['params']> =>
19
+ handlers<Context>().params(protocol, async ({ id }, ctx, req) => {
21
20
  const resource = jobsOf(ctx, opts)
22
21
  // Read first: `take` cannot tell whose job it removed, so ownership is settled before it.
23
22
  await readOwnedJob(resource, id, await jobViewer(req, ctx, opts), opts)
@@ -1,7 +1,5 @@
1
- import { handleParams } from '@owlmeans/server-api'
2
- import type { AbstractResponse } from '@owlmeans/entrypoint'
3
- import type { RefedEntrypointHandler } from '@owlmeans/server-entrypoint'
4
- import type { JobHandlerOptions } from '../types.js'
1
+ import { handlers } from '@owlmeans/server-api'
2
+ import type { Context, JobEntrypoints, JobHandlerOptions } from '../types.js'
5
3
  import { jobViewer, jobsOf, readOwnedJob } from '../utils/index.js'
6
4
 
7
5
  /**
@@ -10,9 +8,10 @@ import { jobViewer, jobsOf, readOwnedJob } from '../utils/index.js'
10
8
  * @throws {UnknownJob} for an id that is absent AND for one that belongs to someone else.
11
9
  */
12
10
  export const getJob = (
11
+ protocol: JobEntrypoints['get'],
13
12
  opts?: JobHandlerOptions
14
- ): RefedEntrypointHandler<AbstractResponse<any>> =>
15
- handleParams<{ id: string }>(async ({ id }, ctx, req) => {
13
+ ): ReturnType<ReturnType<typeof handlers<Context>>['params']> =>
14
+ handlers<Context>().params(protocol, async ({ id }, ctx, req) => {
16
15
  const resource = jobsOf(ctx, opts)
17
16
 
18
17
  return await readOwnedJob(resource, id, await jobViewer(req, ctx, opts), opts)
@@ -1,11 +1,9 @@
1
- import { handleRequest } from '@owlmeans/server-api'
2
- import type { AbstractResponse } from '@owlmeans/entrypoint'
3
- import type { RefedEntrypointHandler } from '@owlmeans/server-entrypoint'
1
+ import { handlers } from '@owlmeans/server-api'
4
2
  import type { Criteria } from '@owlmeans/resource'
5
3
  import type { JobRecord } from '@owlmeans/queue'
6
4
  import type { JobState } from '@owlmeans/queue'
7
5
  import { DEFAULT_JOB_SORT } from '../consts.js'
8
- import type { JobHandlerOptions, JobListQuery } from '../types.js'
6
+ import type { Context, JobEntrypoints, JobHandlerOptions, JobListQuery } from '../types.js'
9
7
  import { jobScope, jobViewer, jobsOf } from '../utils/index.js'
10
8
 
11
9
  /**
@@ -17,8 +15,9 @@ import { jobScope, jobViewer, jobsOf } from '../utils/index.js'
17
15
  * for this list means the same thing applied to the store the browser holds.
18
16
  */
19
17
  export const listJobs = (
18
+ protocol: JobEntrypoints['list'],
20
19
  opts?: JobHandlerOptions
21
- ): RefedEntrypointHandler<AbstractResponse<any>> => handleRequest(async (req, ctx) => {
20
+ ): ReturnType<ReturnType<typeof handlers<Context>>['request']> => handlers<Context>().request(protocol, async (req, ctx) => {
22
21
  const resource = jobsOf(ctx, opts)
23
22
  const viewer = await jobViewer(req, ctx, opts)
24
23
  const query = (req.query ?? {}) as JobListQuery
@@ -1,11 +1,9 @@
1
- import { handleConnection } from '@owlmeans/server-socket'
2
- import type { AbstractResponse } from '@owlmeans/entrypoint'
3
- import type { RefedEntrypointHandler } from '@owlmeans/server-entrypoint'
1
+ import { connection } from '@owlmeans/server-socket'
4
2
  import type { EventMessage } from '@owlmeans/socket'
5
3
  import { MessageType } from '@owlmeans/socket'
6
4
  import type { JobEvent } from '@owlmeans/queue'
7
5
  import { JOB_EVENT } from '../consts.js'
8
- import type { JobHandlerOptions } from '../types.js'
6
+ import type { Context, JobEntrypoints, JobHandlerOptions } from '../types.js'
9
7
  import { jobViewer, jobsOf, owns } from '../utils/index.js'
10
8
 
11
9
  /**
@@ -21,8 +19,9 @@ import { jobViewer, jobsOf, owns } from '../utils/index.js'
21
19
  * rather than fanned out to everyone. Leave completed jobs in place on any queue that is watched.
22
20
  */
23
21
  export const watchJobs = (
22
+ protocol: JobEntrypoints['watch'],
24
23
  opts?: JobHandlerOptions
25
- ): RefedEntrypointHandler<AbstractResponse<any>> => handleConnection(async (conn, ctx, req) => {
24
+ ): ReturnType<typeof connection> => connection<typeof protocol, Context>(protocol, async (conn, ctx, req) => {
26
25
  const resource = jobsOf(ctx, opts)
27
26
  const viewer = await jobViewer(req, ctx, opts)
28
27
  const mine = new Set<string>()
@@ -1,11 +1,10 @@
1
- import { entrypoint, filter, guard, query } from '@owlmeans/entrypoint'
2
- import type { CommonEntrypoint } from '@owlmeans/entrypoint'
1
+ import { contract, openProtocol, protocol, typed } from '@owlmeans/entrypoint'
3
2
  import { backend, route, RouteMethod, socket } from '@owlmeans/route'
4
3
  import type { RouteOptions } from '@owlmeans/route'
5
4
  import { DEFAULT_GUARD } from '@owlmeans/auth-common'
6
5
  import { DEFAULT_JOB_PATH } from './consts.js'
7
6
  import { JobListQuerySchema } from './schemas.js'
8
- import type { JobEntrypointAliases, JobEntrypointOptions } from './types.js'
7
+ import type { JobEntrypointAliases, JobEntrypoints, JobEntrypointOptions, JobListQuery } from './types.js'
9
8
 
10
9
  /**
11
10
  * The aliases one job group answers under.
@@ -25,7 +24,7 @@ export const jobEntrypointAliases = (root: string): JobEntrypointAliases => ({
25
24
  * Declare the list/get/cancel/watch entrypoints of one job group.
26
25
  *
27
26
  * It belongs in the SHARED package of a target app — the one both the API and the browser import —
28
- * so that the server elevates and the client calls the very declarations, and neither side ever
27
+ * so that the server binds and the client calls the very declarations, and neither side ever
29
28
  * writes a path. Declaring a second group is the same call with another root.
30
29
  *
31
30
  * The guard rides on the base alone: guards are inherited, so stating it once is what keeps the
@@ -33,24 +32,30 @@ export const jobEntrypointAliases = (root: string): JobEntrypointAliases => ({
33
32
  */
34
33
  export const declareJobEntrypoints = (
35
34
  root: string, opts?: JobEntrypointOptions
36
- ): CommonEntrypoint[] => {
35
+ ): JobEntrypoints => {
37
36
  const aliases = jobEntrypointAliases(root)
38
37
  const base: Partial<RouteOptions> = {
39
38
  ...(opts?.parent != null ? { parent: opts.parent } : {}),
40
39
  ...(opts?.service != null ? { service: opts.service } : {}),
41
40
  }
42
- const guarded = opts?.guard === null ? undefined : guard(opts?.guard ?? DEFAULT_GUARD)
41
+ const guarded = opts?.guard === null ? undefined : { guards: opts?.guard ?? DEFAULT_GUARD }
43
42
 
44
- return [
45
- entrypoint(route(aliases.base, opts?.path ?? DEFAULT_JOB_PATH, backend(base)), guarded),
46
- entrypoint(
43
+ return {
44
+ base: openProtocol(route(aliases.base, opts?.path ?? DEFAULT_JOB_PATH, backend(base)), guarded),
45
+ list: protocol(
47
46
  route(aliases.list, '/', backend(aliases.base)),
48
- filter(query(JobListQuerySchema))
47
+ contract.request({ query: typed<JobListQuery>(JobListQuerySchema) }, typed())
49
48
  ),
50
49
  // Static before parametric, so `/watch` is not swallowed by `/:id`. The router picks the
51
50
  // static branch on its own; the order here is for whoever reads the declaration.
52
- entrypoint(route(aliases.watch, '/watch', socket(aliases.base))),
53
- entrypoint(route(aliases.get, '/:id', backend(aliases.base))),
54
- entrypoint(route(aliases.cancel, '/:id', backend(aliases.base, RouteMethod.DELETE))),
55
- ]
51
+ watch: protocol(route(aliases.watch, '/watch', socket(aliases.base)), contract(typed<void>())),
52
+ get: protocol(
53
+ route(aliases.get, '/:id', backend(aliases.base)),
54
+ contract.request({ params: typed<{ id: string }>() }, typed())
55
+ ),
56
+ cancel: protocol(
57
+ route(aliases.cancel, '/:id', backend(aliases.base, RouteMethod.DELETE)),
58
+ contract.request({ params: typed<{ id: string }>() }, typed())
59
+ ),
60
+ }
56
61
  }
package/src/helper.ts CHANGED
@@ -1,28 +1,20 @@
1
- import { elevate } from '@owlmeans/server-entrypoint'
2
- import type { ServerEntrypoint } from '@owlmeans/server-entrypoint'
3
- import type { CommonEntrypoint } from '@owlmeans/entrypoint'
4
- import { jobEntrypointAliases } from './entrypoints.js'
1
+ import { bind } from '@owlmeans/server-entrypoint'
5
2
  import { cancelJob, getJob, listJobs, watchJobs } from './actions/index.js'
6
- import type { JobHandlerOptions } from './types.js'
3
+ import type { JobEntrypoints, JobHandlerOptions } from './types.js'
7
4
 
8
5
  /**
9
6
  * Attach this package's handlers to a group declared by {@link declareJobEntrypoints}.
10
7
  *
11
8
  * The whole server half of "a long job reports progress to the user's screen" is this call plus
12
9
  * the queue driver an app already wires — nothing is subclassed, and an app that wants one
13
- * handler of its own elevates that alias itself afterwards, since `elevate` replaces in place.
10
+ * handler of its own binds that alias itself afterwards.
14
11
  *
15
12
  * @throws {SyntaxError} when the array carries no group under that root.
16
13
  */
17
- export const serveJobEntrypoints = <R>(
18
- entrypoints: (CommonEntrypoint | ServerEntrypoint<R>)[], root: string, opts?: JobHandlerOptions
19
- ): ServerEntrypoint<R>[] => {
20
- const aliases = jobEntrypointAliases(root)
21
-
22
- elevate(entrypoints, aliases.base)
23
- elevate(entrypoints, aliases.list, listJobs(opts))
24
- elevate(entrypoints, aliases.watch, watchJobs(opts))
25
- elevate(entrypoints, aliases.get, getJob(opts))
26
-
27
- return elevate(entrypoints, aliases.cancel, cancelJob(opts))
28
- }
14
+ export const serveJobEntrypoints = (entrypoints: JobEntrypoints, opts?: JobHandlerOptions) => [
15
+ bind(entrypoints.base),
16
+ bind(entrypoints.list, listJobs(entrypoints.list, opts)),
17
+ bind(entrypoints.watch, watchJobs(entrypoints.watch, opts)),
18
+ bind(entrypoints.get, getJob(entrypoints.get, opts)),
19
+ bind(entrypoints.cancel, cancelJob(entrypoints.cancel, opts)),
20
+ ]
package/src/types.ts CHANGED
@@ -3,6 +3,7 @@ import type { AbstractRequest } from '@owlmeans/entrypoint'
3
3
  import type { QueueAppend, QueueConfig } from '@owlmeans/queue'
4
4
  import type { ApiServerAppend } from '@owlmeans/server-api'
5
5
  import type { ServerConfig, ServerContext } from '@owlmeans/server-context'
6
+ import type { EntrypointProtocol, OpenRequest, OpenValue } from '@owlmeans/entrypoint'
6
7
 
7
8
  export interface Config extends ServerConfig {
8
9
  queue?: QueueConfig
@@ -20,6 +21,15 @@ export interface JobEntrypointAliases {
20
21
  watch: string
21
22
  }
22
23
 
24
+ /** The immutable declarations for one job group, addressed by property rather than alias lookup. */
25
+ export interface JobEntrypoints {
26
+ base: EntrypointProtocol<OpenRequest, OpenValue>
27
+ list: EntrypointProtocol<{ query: JobListQuery }, unknown>
28
+ get: EntrypointProtocol<{ params: { id: string } }, unknown>
29
+ cancel: EntrypointProtocol<{ params: { id: string } }, unknown>
30
+ watch: EntrypointProtocol<OpenRequest, void>
31
+ }
32
+
23
33
  export interface JobEntrypointOptions {
24
34
  /** The path segment the group answers under. Defaults to `/jobs`. */
25
35
  path?: string