@worker-protocol/hono 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/NOTICE +9 -0
- package/dist/actions.d.ts +200 -0
- package/dist/actions.js +203 -0
- package/dist/buckets.d.ts +36 -0
- package/dist/buckets.js +133 -0
- package/dist/codes.d.ts +201 -0
- package/dist/codes.js +129 -0
- package/dist/collection.d.ts +44 -0
- package/dist/collection.js +62 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.js +22 -0
- package/dist/metrics.d.ts +56 -0
- package/dist/metrics.js +122 -0
- package/dist/mount.d.ts +92 -0
- package/dist/mount.js +432 -0
- package/dist/surfaces.d.ts +483 -0
- package/dist/surfaces.js +424 -0
- package/dist/tasks.d.ts +78 -0
- package/dist/tasks.js +45 -0
- package/dist/worker.d.ts +169 -0
- package/dist/worker.js +1 -0
- package/package.json +51 -0
package/dist/worker.d.ts
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import type { activityState, alertSeverity, eventsEntry, eventTypeDeclaration, health } from "@worker-protocol/schemas";
|
|
2
|
+
import type * as z from "zod";
|
|
3
|
+
import type { ActionFacts } from "./actions.ts";
|
|
4
|
+
import type { ErrorCode } from "./codes.ts";
|
|
5
|
+
import type { MetricFacts } from "./metrics.ts";
|
|
6
|
+
import type { TaskFacts, TaskTypes } from "./tasks.ts";
|
|
7
|
+
/**
|
|
8
|
+
* What a Worker author implements, and the whole of it.
|
|
9
|
+
*
|
|
10
|
+
* **Everything this protocol fixes is `mount()`'s.** The addresses, the verbs, the two headers on
|
|
11
|
+
* every response, the error envelope, the page envelope and its cursor, the refusal for a version
|
|
12
|
+
* this Worker cannot speak or a filter it does not know, the bucket boundaries cut in a declared
|
|
13
|
+
* zone, the idempotency window. None of it is a decision a Worker gets to make, so none of it is
|
|
14
|
+
* asked for here.
|
|
15
|
+
*
|
|
16
|
+
* What is left is what only the Worker knows, and it is a short list: who it is, whether a
|
|
17
|
+
* credential is good, how it is doing, which Tasks' conditions hold, how much of something
|
|
18
|
+
* happened, what an Action does. That division is the measure this package is held to —
|
|
19
|
+
* `examples/minimal-worker` is a conformant Worker in under 150 lines, and anything above that
|
|
20
|
+
* line is a rule `mount()` should have carried.
|
|
21
|
+
*
|
|
22
|
+
* A Capability left `undefined` is one the Descriptor does not declare (DESC-2), and its address is
|
|
23
|
+
* not served: a Descriptor naming a Capability that answers nothing is DESC-18's fault, and a
|
|
24
|
+
* Worker built through this interface cannot produce one.
|
|
25
|
+
*/
|
|
26
|
+
export type Worker = {
|
|
27
|
+
/**
|
|
28
|
+
* The Worker's own id. DESC-6 and DESC-27: not the URL, and not derived from it — so it is a
|
|
29
|
+
* constant a Worker is deployed with, never anything read from the address at boot.
|
|
30
|
+
*/
|
|
31
|
+
id: string;
|
|
32
|
+
/** The edition this Worker speaks (DESC-23). Defaults to the one `@worker-protocol/schemas` encodes. */
|
|
33
|
+
edition?: string;
|
|
34
|
+
/**
|
|
35
|
+
* TASK-31. The Task types this Worker answers, which IS its Skill, keyed by type.
|
|
36
|
+
*
|
|
37
|
+
* Beside the id rather than inside `tasks`, because a Skill is served at no address: it is what
|
|
38
|
+
* this Worker is, and a Capability is what it serves. A Worker that only ANSWERS Tasks declares
|
|
39
|
+
* this and no `tasks` Capability at all.
|
|
40
|
+
*
|
|
41
|
+
* Each entry says what this Worker NEEDS to receive to answer a Task of that type — which is the
|
|
42
|
+
* other half of what the owner's `raises` says it sends, and what a Tower compares to answer
|
|
43
|
+
* "can this Worker take that one's Tasks?" before any work changes hands.
|
|
44
|
+
*/
|
|
45
|
+
skills?: Record<string, SkillDeclaration>;
|
|
46
|
+
/**
|
|
47
|
+
* Whether a presented credential is good, on every address this protocol defines (REG-21).
|
|
48
|
+
*
|
|
49
|
+
* `token` is what followed `Bearer ` (REG-3), or `undefined` where nothing readable was
|
|
50
|
+
* presented. `unauthenticated` is `401`, `forbidden` is `403` (ENDP-29), and how the Worker
|
|
51
|
+
* decides is its own. Left out, the Worker reads openly, which `spec/registration.md` permits.
|
|
52
|
+
*
|
|
53
|
+
* It may answer a promise, and it has to: `spec/registration.md` names *a Worker that validates
|
|
54
|
+
* an API key against an identity provider* as the first example of what REG-3 admits, and that
|
|
55
|
+
* is a network call. A signature that could not await it forbade the case the rule was written
|
|
56
|
+
* around, and left a Worker comparing against a secret it was deployed with as the only kind
|
|
57
|
+
* this package could serve.
|
|
58
|
+
*/
|
|
59
|
+
authenticate?: (token: string | undefined) => "accepted" | "unauthenticated" | "forbidden" | Promise<"accepted" | "unauthenticated" | "forbidden">;
|
|
60
|
+
/** `health`: the answer to a poll (HLTH-2). HLTH-5 makes it `200` whatever it reports. */
|
|
61
|
+
health?: () => z.infer<typeof health> | Promise<z.infer<typeof health>>;
|
|
62
|
+
/** `metrics`: what the entry declares (MET-1 to MET-6), and the Worker's own values. */
|
|
63
|
+
metrics?: MetricFacts;
|
|
64
|
+
/** `actions`: the Actions this Worker accepts, each with its input and what it does. */
|
|
65
|
+
actions?: ActionFacts;
|
|
66
|
+
/** `alerts`: the Alerts whose conditions hold (ALRT-2). `mount()` orders, serializes and pages. */
|
|
67
|
+
alerts?: () => Alert[] | Promise<Alert[]>;
|
|
68
|
+
/**
|
|
69
|
+
* `activity`: what this Worker is doing and has undertaken to do (ACTV-2).
|
|
70
|
+
*
|
|
71
|
+
* The Worker answers its own domain — an id, a state, when it entered it, a line for a person —
|
|
72
|
+
* and `mount()` carries the rest: the instant's format, the order ENDP-23 requires, the page
|
|
73
|
+
* envelope. It is the consumer's own Fact about its work and not a Claim; `spec/activity.md`
|
|
74
|
+
* holds the argument.
|
|
75
|
+
*/
|
|
76
|
+
activity?: () => Activity[] | Promise<Activity[]>;
|
|
77
|
+
/**
|
|
78
|
+
* `nudges`: told that there is work of a Task type this Worker answers (NDG-2).
|
|
79
|
+
*
|
|
80
|
+
* Everything about the call is `mount()`'s, and more of it than usual: the body's shape is NDG-2's
|
|
81
|
+
* rather than this Worker's, a type it declares no Skill for is refused `404` before this is
|
|
82
|
+
* reached (NDG-3), and the answer is `204` because there is nothing to say. What is left is the
|
|
83
|
+
* one thing only the Worker knows — that it should go and read that work sooner than its next
|
|
84
|
+
* sweep would have.
|
|
85
|
+
*
|
|
86
|
+
* It is handed the type and nothing else, and TASK-15 is why: the owner is authoritative over
|
|
87
|
+
* whether the condition still holds, so a Task that travelled here would be a claim that may
|
|
88
|
+
* already be false. The Worker reads, and what it reads is true when it reads it.
|
|
89
|
+
*
|
|
90
|
+
* Declaring it is optional and what it buys is latency. Without it this Worker is told nothing and
|
|
91
|
+
* works from its own schedule, which is slower and never wrong (TASK-19).
|
|
92
|
+
*/
|
|
93
|
+
nudges?: (type: string) => void | Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* `events`: the entry and nothing else, because there is no address to serve (EVT-11).
|
|
96
|
+
*
|
|
97
|
+
* Each event type's `data` is a Zod object, as an Action's input and a Task's payload are.
|
|
98
|
+
* `mount()` writes the JSON Schema the Descriptor carries, so a Worker declares one shape.
|
|
99
|
+
*/
|
|
100
|
+
events?: Omit<z.infer<typeof eventsEntry>, "version" | "address" | "publishes"> & {
|
|
101
|
+
publishes: Record<string, Omit<z.infer<typeof eventTypeDeclaration>, "data"> & {
|
|
102
|
+
data: z.ZodType;
|
|
103
|
+
}>;
|
|
104
|
+
};
|
|
105
|
+
/** `tasks`: what the entry declares (TASK-27, TASK-2 to TASK-4), and which conditions hold. */
|
|
106
|
+
tasks?: {
|
|
107
|
+
/** TASK-2. Every Task type this Worker raises, with its payload schema and answering Actions. */
|
|
108
|
+
raises: TaskTypes;
|
|
109
|
+
} & TaskFacts;
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* TASK-31. What a Worker declares about one Skill: the payload it needs to receive to answer one.
|
|
113
|
+
*
|
|
114
|
+
* A Zod object, as an Action's input and a Task's payload are, and `mount()` writes the JSON Schema
|
|
115
|
+
* the Descriptor carries. It is this Worker's own requirement — NAME-6 judges it against what an
|
|
116
|
+
* owner sends, and a Tower holding both knows at enrollment whether the work can be read.
|
|
117
|
+
*
|
|
118
|
+
* Optional: `{}` claims the type and says nothing about what it needs, which is what a Worker that
|
|
119
|
+
* takes whatever arrives should say. It costs the check, and nothing else.
|
|
120
|
+
*/
|
|
121
|
+
export type SkillDeclaration = {
|
|
122
|
+
/** What this Worker needs to RECEIVE in order to answer one. */
|
|
123
|
+
payload?: z.ZodType;
|
|
124
|
+
/** What this Worker PRODUCES in answer, judged against the owner's answering Action. */
|
|
125
|
+
produces?: z.ZodType;
|
|
126
|
+
};
|
|
127
|
+
/** What a Worker says about a condition an operator should see: the domain, and no more (ALRT-3). */
|
|
128
|
+
export type Alert = {
|
|
129
|
+
/** ALRT-3. The Worker's own id for this Alert. Opaque to everyone else. */
|
|
130
|
+
id: string;
|
|
131
|
+
/** ALRT-4. `warning` or `critical`, and this edition defines no third value. */
|
|
132
|
+
severity: z.infer<typeof alertSeverity>;
|
|
133
|
+
/**
|
|
134
|
+
* ALRT-3. When the condition began — a `Date`, which `mount()` writes as the instant the rule
|
|
135
|
+
* fixes. It is what lets a console tell `this is new` from `this is the same as yesterday`.
|
|
136
|
+
*/
|
|
137
|
+
since: Date;
|
|
138
|
+
/** ALRT-3. Human-readable, and parsed by nothing. */
|
|
139
|
+
summary: string;
|
|
140
|
+
/** ALRT-3, ALRT-7. The Actions this Alert offers, by the names the `actions` entry holds. */
|
|
141
|
+
actions: string[];
|
|
142
|
+
};
|
|
143
|
+
/** What a Worker says about one thing it holds: the domain, and the whole of it (ACTV-3). */
|
|
144
|
+
export type Activity = {
|
|
145
|
+
/** ACTV-3. The Worker's own id, opaque to everyone else. */
|
|
146
|
+
id: string;
|
|
147
|
+
/** ACTV-4. `scheduled`, `pending` or `running`. */
|
|
148
|
+
state: z.infer<typeof activityState>;
|
|
149
|
+
/**
|
|
150
|
+
* ACTV-3. When it entered its current state — began running, joined the queue, was undertaken.
|
|
151
|
+
* A Worker that answers `new Date()` here is answering *now* and telling an operator nothing.
|
|
152
|
+
*/
|
|
153
|
+
since: Date;
|
|
154
|
+
/** ACTV-3. For a person. Nothing parses it. */
|
|
155
|
+
summary: string;
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* A refusal. The code fixes the status and the class (ENDP-26), so only the code is chosen and a
|
|
159
|
+
* Worker cannot answer a code under a status the vocabulary does not give it.
|
|
160
|
+
*/
|
|
161
|
+
export type Refusal = {
|
|
162
|
+
code: ErrorCode;
|
|
163
|
+
message: string;
|
|
164
|
+
};
|
|
165
|
+
/** A success. `body: null` is no body at all — not the four bytes `null` (ACT-10, ACT-11). */
|
|
166
|
+
export type Answer = {
|
|
167
|
+
status: number;
|
|
168
|
+
body: unknown;
|
|
169
|
+
};
|
package/dist/worker.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@worker-protocol/hono",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"workerProtocolEdition": "0.1",
|
|
5
|
+
"description": "The protocol's surface as Hono routes, and mount(): a Worker author implements an interface and gets every address, header and refusal this protocol fixes",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/rowing-tech/worker-protocol.git",
|
|
10
|
+
"directory": "packages/hono"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/rowing-tech/worker-protocol#readme",
|
|
13
|
+
"bugs": "https://github.com/rowing-tech/worker-protocol/issues",
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"type": "module",
|
|
18
|
+
"main": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"default": "./dist/index.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"LICENSE",
|
|
29
|
+
"NOTICE"
|
|
30
|
+
],
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@hono/zod-openapi": "1.6.3",
|
|
33
|
+
"@worker-protocol/schemas": "0.1.0"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"hono": "^4.13.7",
|
|
37
|
+
"zod": "^4.5.4"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "26.5.1",
|
|
41
|
+
"hono": "4.13.7",
|
|
42
|
+
"typescript": "7.0.2",
|
|
43
|
+
"vitest": "5.0.0",
|
|
44
|
+
"zod": "4.5.4"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
48
|
+
"build": "tsc -p tsconfig.build.json",
|
|
49
|
+
"test": "vitest run"
|
|
50
|
+
}
|
|
51
|
+
}
|