@substrat-run/kernel 0.159.0 → 0.160.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/billing-retention.d.ts +46 -0
  2. package/dist/billing-retention.d.ts.map +1 -0
  3. package/dist/billing-retention.js +78 -0
  4. package/dist/billing-retention.js.map +1 -0
  5. package/dist/byte-stream.d.ts +102 -0
  6. package/dist/byte-stream.d.ts.map +1 -0
  7. package/dist/byte-stream.js +153 -0
  8. package/dist/byte-stream.js.map +1 -0
  9. package/dist/connection-landings.d.ts +15 -3
  10. package/dist/connection-landings.d.ts.map +1 -1
  11. package/dist/connection-landings.js +10 -2
  12. package/dist/connection-landings.js.map +1 -1
  13. package/dist/deadline-fetch.d.ts +34 -0
  14. package/dist/deadline-fetch.d.ts.map +1 -0
  15. package/dist/deadline-fetch.js +231 -0
  16. package/dist/deadline-fetch.js.map +1 -0
  17. package/dist/deployment-wire-auth.d.ts +82 -0
  18. package/dist/deployment-wire-auth.d.ts.map +1 -0
  19. package/dist/deployment-wire-auth.js +150 -0
  20. package/dist/deployment-wire-auth.js.map +1 -0
  21. package/dist/entity-trash.d.ts +65 -8
  22. package/dist/entity-trash.d.ts.map +1 -1
  23. package/dist/entity-trash.js +80 -12
  24. package/dist/entity-trash.js.map +1 -1
  25. package/dist/export-break.d.ts +6 -0
  26. package/dist/export-break.d.ts.map +1 -1
  27. package/dist/export-break.js +11 -0
  28. package/dist/export-break.js.map +1 -1
  29. package/dist/index.d.ts +18 -9
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +16 -7
  32. package/dist/index.js.map +1 -1
  33. package/dist/meter-days.d.ts +107 -0
  34. package/dist/meter-days.d.ts.map +1 -0
  35. package/dist/meter-days.js +230 -0
  36. package/dist/meter-days.js.map +1 -0
  37. package/dist/meters.d.ts +19 -1
  38. package/dist/meters.d.ts.map +1 -1
  39. package/dist/meters.js +0 -0
  40. package/dist/meters.js.map +1 -1
  41. package/dist/ops-failure-reference.d.ts +31 -0
  42. package/dist/ops-failure-reference.d.ts.map +1 -0
  43. package/dist/ops-failure-reference.js +32 -0
  44. package/dist/ops-failure-reference.js.map +1 -0
  45. package/dist/platform-request-cap.d.ts +9 -0
  46. package/dist/platform-request-cap.d.ts.map +1 -0
  47. package/dist/platform-request-cap.js +42 -0
  48. package/dist/platform-request-cap.js.map +1 -0
  49. package/dist/platform-sweep.d.ts +170 -7
  50. package/dist/platform-sweep.d.ts.map +1 -1
  51. package/dist/platform-sweep.js +375 -45
  52. package/dist/platform-sweep.js.map +1 -1
  53. package/dist/request-rollup.d.ts +161 -0
  54. package/dist/request-rollup.d.ts.map +1 -0
  55. package/dist/request-rollup.js +273 -0
  56. package/dist/request-rollup.js.map +1 -0
  57. package/dist/reserved-roles.d.ts +157 -4
  58. package/dist/reserved-roles.d.ts.map +1 -1
  59. package/dist/reserved-roles.js +216 -2
  60. package/dist/reserved-roles.js.map +1 -1
  61. package/dist/schedule-state.d.ts +5 -0
  62. package/dist/schedule-state.d.ts.map +1 -1
  63. package/dist/scope-host.d.ts +260 -15
  64. package/dist/scope-host.d.ts.map +1 -1
  65. package/dist/scope-host.js +53 -2
  66. package/dist/scope-host.js.map +1 -1
  67. package/dist/scope-lifecycle.d.ts +7 -0
  68. package/dist/scope-lifecycle.d.ts.map +1 -1
  69. package/dist/scope-lifecycle.js +7 -0
  70. package/dist/scope-lifecycle.js.map +1 -1
  71. package/dist/scope-record.d.ts +16 -5
  72. package/dist/scope-record.d.ts.map +1 -1
  73. package/dist/scope-record.js +72 -7
  74. package/dist/scope-record.js.map +1 -1
  75. package/dist/spine-restore.d.ts +7 -3
  76. package/dist/spine-restore.d.ts.map +1 -1
  77. package/dist/spine-restore.js +14 -3
  78. package/dist/spine-restore.js.map +1 -1
  79. package/dist/storage-gauge.d.ts +47 -13
  80. package/dist/storage-gauge.d.ts.map +1 -1
  81. package/dist/storage-gauge.js +84 -27
  82. package/dist/storage-gauge.js.map +1 -1
  83. package/dist/subject-redaction.d.ts +9 -3
  84. package/dist/subject-redaction.d.ts.map +1 -1
  85. package/dist/subject-redaction.js +24 -12
  86. package/dist/subject-redaction.js.map +1 -1
  87. package/dist/vertical-owners.d.ts +69 -0
  88. package/dist/vertical-owners.d.ts.map +1 -0
  89. package/dist/vertical-owners.js +108 -0
  90. package/dist/vertical-owners.js.map +1 -0
  91. package/package.json +2 -2
@@ -0,0 +1,231 @@
1
+ /**
2
+ * How long a streamed response body may go without a byte before it errors. 30 s, the default
3
+ * `timeoutMs` of a connector call: a provider that has been silent for as long as a whole call
4
+ * may take has stalled, and a slower link than that is still delivering within it. The window
5
+ * runs only while the stream waits on the provider: a consumer that is slow to take the next
6
+ * chunk (a store writing the last one) does not spend it.
7
+ */
8
+ export const STREAM_IDLE_TIMEOUT_MS = 30_000;
9
+ /**
10
+ * The most a streamed body may take from its first read to its end, however steadily it flows:
11
+ * 10 minutes. Finite because a hosted run lives under the platform's wall limits and a trickle
12
+ * that never stops would otherwise hold a connection (and a run) for ever; generous because the
13
+ * idle window, not this, is what cuts a stalled transfer. At the 10 minutes a steady 1 MB/s
14
+ * link still moves about 600 MB.
15
+ */
16
+ export const STREAM_MAX_DURATION_MS = 10 * 60_000;
17
+ /**
18
+ * How many empty chunks in a row a stream may deliver before it is treated as making no progress.
19
+ * Generous: a real source sends a few at most. It is a count, not a time, because a source that
20
+ * answers only with empty chunks answers in microtasks and no timer would ever get to run.
21
+ */
22
+ const MAX_CONSECUTIVE_EMPTY_READS = 1_000;
23
+ /** The runtime's timers, called bare — workerd throws `Illegal invocation` on `obj.setTimeout(…)`. */
24
+ const RUNTIME_TIMERS = {
25
+ setTimeout: (fn, ms) => setTimeout(fn, ms),
26
+ clearTimeout: (handle) => clearTimeout(handle),
27
+ };
28
+ /** The error every bound ends in. Neutral: it names neither the provider nor the URL. */
29
+ const timeoutError = (message) => new DOMException(message, 'TimeoutError');
30
+ /** The three reads that buffer the whole body; the call's total deadline covers them. */
31
+ const BUFFERED_READS = new Set(['text', 'json', 'arrayBuffer']);
32
+ /**
33
+ * `fetchImpl`, with `timeoutMs` on the call and an idle window plus an absolute cap on a streamed
34
+ * body (see the module header). The signal it hands the runtime is its own; a `signal` in `init`
35
+ * aborts it, so wrapping a `fetch` that is itself wrapped (a connector's timeout around a host's)
36
+ * lets the outer bound reach the runtime.
37
+ */
38
+ export function deadlineFetch(fetchImpl, timeoutMs, options = {}) {
39
+ const idleMs = options.idleMs ?? STREAM_IDLE_TIMEOUT_MS;
40
+ const maxStreamMs = options.maxStreamMs ?? STREAM_MAX_DURATION_MS;
41
+ const timers = options.timers ?? RUNTIME_TIMERS;
42
+ return async (input, init) => {
43
+ const controller = new AbortController();
44
+ let timedOut;
45
+ const upstream = init?.signal;
46
+ // The caller's own abort ends the call: its deadline is released, so it cannot fire later and
47
+ // pass a cancel off as a timeout.
48
+ const onUpstreamAbort = () => {
49
+ releaseTotal();
50
+ controller.abort(upstream?.reason);
51
+ };
52
+ if (upstream?.aborted)
53
+ controller.abort(upstream.reason);
54
+ else
55
+ upstream?.addEventListener?.('abort', onUpstreamAbort, { once: true });
56
+ const total = timers.setTimeout(() => {
57
+ timedOut ??= timeoutError('The operation was aborted due to timeout');
58
+ controller.abort(timedOut);
59
+ finish();
60
+ }, timeoutMs);
61
+ // Not held against the process: `AbortSignal.timeout`'s timer was not either.
62
+ unref(total);
63
+ const releaseTotal = () => timers.clearTimeout(total);
64
+ /** The call is over: its deadline and its hold on the caller's signal go. Idempotent. */
65
+ function finish() {
66
+ releaseTotal();
67
+ upstream?.removeEventListener?.('abort', onUpstreamAbort);
68
+ }
69
+ /**
70
+ * What a failed read reports. A runtime may fail a read the call's deadline aborted with a
71
+ * generic abort rather than the reason; that one is the deadline's `TimeoutError`. Any other
72
+ * failure (a caller's cancel, a network error) keeps its own class.
73
+ */
74
+ const reported = (err) => timedOut && err?.name === 'AbortError' ? timedOut : err;
75
+ let res;
76
+ try {
77
+ res = await fetchImpl(input, { ...init, signal: controller.signal });
78
+ }
79
+ catch (err) {
80
+ finish();
81
+ throw reported(err);
82
+ }
83
+ // A response that has no body at all (`null`, as on a web `Response`) has nothing to bound.
84
+ // A stand-in with no `body` field (`undefined`) may still be read buffered, so it keeps the deadline.
85
+ if (res.body === null)
86
+ finish();
87
+ let guarded;
88
+ return new Proxy(res, {
89
+ get(target, prop) {
90
+ const value = Reflect.get(target, prop, target);
91
+ if (prop === 'body') {
92
+ if (!value)
93
+ return value;
94
+ // Looking at the body takes nothing: the native stream stays unlocked and the call's
95
+ // deadline stays armed until the first read of the stream handed out here.
96
+ guarded ??= guardedBody(value, {
97
+ idleMs,
98
+ maxStreamMs,
99
+ timers,
100
+ releaseTotal,
101
+ finish,
102
+ abortCall: (reason) => controller.abort(reason),
103
+ reported,
104
+ });
105
+ return guarded;
106
+ }
107
+ if (typeof value !== 'function')
108
+ return value;
109
+ // Called on the response itself, never the proxy: a native method refuses any other receiver.
110
+ if (BUFFERED_READS.has(prop)) {
111
+ return async (...args) => {
112
+ try {
113
+ return await value.apply(target, args);
114
+ }
115
+ catch (err) {
116
+ // A runtime may fail a read the call's deadline aborted with a generic abort.
117
+ throw reported(err);
118
+ }
119
+ finally {
120
+ finish();
121
+ }
122
+ };
123
+ }
124
+ return value.bind(target);
125
+ },
126
+ });
127
+ };
128
+ }
129
+ /** A timer that does not hold a Node process open, where the runtime lets it say so. */
130
+ function unref(handle) {
131
+ handle?.unref?.();
132
+ }
133
+ /**
134
+ * `body`, passed through chunk by chunk. The native reader is taken on the FIRST pull, not here,
135
+ * so a stream that is only looked at, or taken and never read, leaves the native body unlocked
136
+ * and the call's deadline in force. From the first read: the stream errors when the provider is
137
+ * silent for `idleMs` (empty chunks are not bytes and do not reset the window) or when `maxStreamMs`
138
+ * has passed in all. Pull-driven with no queue of its own, so the idle window runs only while a
139
+ * read waits on the provider. Whichever bound ends it cancels the source reader, aborts the call
140
+ * (which releases the connection) and errors the stream: nothing is left reading, nothing buffered.
141
+ *
142
+ * The bounds are TIMERS that end the stream, never promises raced against each read: a promise
143
+ * that outlives a read keeps a reaction for every race it was in, and through it the chunk the
144
+ * race resolved with. Nothing long-lived here holds a chunk once it has been delivered.
145
+ */
146
+ function guardedBody(body, o) {
147
+ let reader;
148
+ let ctl;
149
+ let capHandle;
150
+ let over = false;
151
+ /** End the stream with `err`, once: error it, let go of the call, cancel the source. */
152
+ const stop = async (err) => {
153
+ if (over)
154
+ return;
155
+ over = true;
156
+ o.timers.clearTimeout(capHandle);
157
+ try {
158
+ ctl?.error(err);
159
+ }
160
+ catch {
161
+ // already closed or errored
162
+ }
163
+ o.abortCall(err);
164
+ o.finish();
165
+ await reader?.cancel(err).catch(() => { });
166
+ try {
167
+ reader?.releaseLock();
168
+ }
169
+ catch {
170
+ // a read the cancel has not yet settled: the lock goes with the stream
171
+ }
172
+ };
173
+ /** The first read: the call's deadline hands over to the idle window and the absolute cap. */
174
+ const begin = () => {
175
+ o.releaseTotal();
176
+ capHandle = o.timers.setTimeout(() => void stop(timeoutError('The transfer exceeded its maximum duration')), o.maxStreamMs);
177
+ unref(capHandle);
178
+ return body.getReader();
179
+ };
180
+ return new ReadableStream({
181
+ start(controller) {
182
+ ctl = controller;
183
+ },
184
+ async pull(controller) {
185
+ if (over)
186
+ return;
187
+ let idle;
188
+ let empties = 0;
189
+ try {
190
+ reader ??= begin();
191
+ idle = o.timers.setTimeout(() => void stop(timeoutError(`The response body stalled: no bytes for ${o.idleMs} ms`)), o.idleMs);
192
+ unref(idle);
193
+ for (;;) {
194
+ const { done, value } = await reader.read();
195
+ // A bound (or the consumer) ended the stream while this read waited: it has answered.
196
+ if (over)
197
+ return;
198
+ if (done) {
199
+ over = true;
200
+ o.timers.clearTimeout(capHandle);
201
+ o.finish();
202
+ controller.close();
203
+ return;
204
+ }
205
+ if (!value)
206
+ throw new Error('the byte stream yielded a read with neither a chunk nor its end');
207
+ // An empty chunk carries nothing: it is read past under the same window, not counted as progress.
208
+ // A source that answers only with empty chunks, all in microtasks, would never let a timer
209
+ // run, so the run of them is itself bounded.
210
+ if (value.byteLength === 0) {
211
+ if (++empties > MAX_CONSECUTIVE_EMPTY_READS) {
212
+ throw timeoutError('The response body made no progress');
213
+ }
214
+ continue;
215
+ }
216
+ controller.enqueue(value);
217
+ return;
218
+ }
219
+ }
220
+ catch (err) {
221
+ // A runtime may end a read the call's deadline aborted with a generic abort.
222
+ await stop(o.reported(err));
223
+ }
224
+ finally {
225
+ o.timers.clearTimeout(idle);
226
+ }
227
+ },
228
+ cancel: (reason) => stop(reason),
229
+ }, { highWaterMark: 0 });
230
+ }
231
+ //# sourceMappingURL=deadline-fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deadline-fetch.js","sourceRoot":"","sources":["../src/deadline-fetch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * The capability record (RFC wire-signing §7, Q8), as statements both adapters run against their
3
+ * directory: one row per deployment, the script an upload went to (a version's archive script or a
4
+ * vertical's serving script), holding what that upload gave it. Every upload of the script replaces
5
+ * its row, so the row is the last upload's: the one the running script was built from. Written once
6
+ * so the two adapters cannot keep different records of the same fleet.
7
+ *
8
+ * The uploader writes it from what it built and injected; a vertical never declares it, since a
9
+ * claim a version makes about itself proves nothing. The readiness report (follow-on 4) reads it.
10
+ * A vertical's rows go with the vertical (`forgetVerticalWireAuth`), so none outlives what it
11
+ * describes.
12
+ */
13
+ import { type DeploymentWireAuth, type TenantId } from '@substrat-run/contracts';
14
+ import type { SwitchSql } from './system-switch.js';
15
+ export type { DeploymentWireAuthInput } from '@substrat-run/contracts';
16
+ /** Interpolated into both adapters' directory DDL, so the two spell one table. */
17
+ export declare const DEPLOYMENT_WIRE_AUTH_DDL = "\n CREATE TABLE IF NOT EXISTS vertical_wire_auth (\n deployment_ref TEXT PRIMARY KEY,\n vertical_slug TEXT NOT NULL,\n version_id TEXT,\n record TEXT NOT NULL,\n recorded_at TEXT NOT NULL\n );\n CREATE INDEX IF NOT EXISTS vertical_wire_auth_slug ON vertical_wire_auth (vertical_slug);\n";
18
+ /**
19
+ * Whose records a read may return: the verticals one tenant owns now (`verticals.owner_tenant`), or
20
+ * the whole fleet, said in so many words. There is no default, so a reader that forgets to confine
21
+ * itself is refused rather than handed every tenant's deployments: a record names scripts, versions
22
+ * and key ids, and a tenant reads only its own. A record whose vertical no tenant owns, or that the
23
+ * registry does not know, is reached only by the fleet.
24
+ *
25
+ * A tenant reach follows the vertical's current owner: it is resolved at read time, so whoever owns
26
+ * the slug then reads every record the table holds for it, and a tenant that no longer owns it reads
27
+ * none. Apart from a whole-directory restore (`restoreDirectory`), which replaces the owners and the
28
+ * records together from one dump, no host path moves the owner of a registered vertical today: an
29
+ * owner changes by deleting the vertical, which removes its records, and registering the slug again.
30
+ * A record written while no tenant owned the slug is read by the tenant that owns it at read time. Key
31
+ * ids are not secrets.
32
+ */
33
+ export type DeploymentWireAuthReach = {
34
+ readonly tenantId: TenantId;
35
+ } | {
36
+ readonly fleet: true;
37
+ };
38
+ /**
39
+ * Which records a read returns, one page of them: the keyset convention by script name, `cursor` the
40
+ * last name of the page before. A version's script keeps its record for as long as its vertical
41
+ * exists, so a read is always a page: `limit` is required, at most `LIST_PAGE_MAX`.
42
+ */
43
+ export interface DeploymentWireAuthFilter {
44
+ readonly reach: DeploymentWireAuthReach;
45
+ readonly verticalSlug?: string;
46
+ readonly limit: number;
47
+ readonly cursor?: string;
48
+ readonly order?: 'asc' | 'desc';
49
+ }
50
+ /** The longest `verticalSlug` or `cursor` a read takes. A script name is far shorter. */
51
+ export declare const WIRE_AUTH_FILTER_TEXT_MAX = 256;
52
+ /**
53
+ * The filter a read is allowed to run, or a `validation_failed` refusal: only the filter's own keys;
54
+ * a reach that is exactly one tenant (a tenant id) or exactly the fleet; a limit from 1 to
55
+ * `LIST_PAGE_MAX`; a vertical and a cursor of 1 to `WIRE_AUTH_FILTER_TEXT_MAX` characters; an order
56
+ * of `asc` or `desc`. Both adapters judge it before the read, and the Cloudflare host before the call
57
+ * into the directory's object, so the refusal keeps its code across the RPC.
58
+ *
59
+ * Answers a NEW object built from the judged fields alone, never the caller's, so nothing else crosses
60
+ * the RPC or reaches the access log. `reach` is its first key: the log keeps a read's params cut to a
61
+ * bounded length, and nothing after the reach can push it out of what is kept.
62
+ */
63
+ export declare function assertWireAuthFilter(filter: unknown): DeploymentWireAuthFilter;
64
+ /** The access-log target of a read: the tenant a tenant reach names, none for the fleet. */
65
+ export declare function wireAuthAccessTarget(filter: DeploymentWireAuthFilter): {
66
+ tenantId: TenantId | null;
67
+ };
68
+ /**
69
+ * Record an upload's capability for its script, replacing the script's earlier record. Takes the row
70
+ * the adapter parsed (`deploymentWireAuth`) before it reached here: on Cloudflare that parse runs
71
+ * before the call into the directory's object, so a refusal keeps its code across the RPC.
72
+ */
73
+ export declare function writeDeploymentWireAuth(db: SwitchSql, row: DeploymentWireAuth): void;
74
+ /**
75
+ * One page of the stored records the filter reaches, by script name. The filter is judged here too
76
+ * (`assertWireAuthFilter`), so no caller reaches the table unconfined or unbounded. A row that does
77
+ * not parse throws: it is a corrupt directory, not a fact.
78
+ */
79
+ export declare function deploymentWireAuthOf(db: SwitchSql, input: DeploymentWireAuthFilter): DeploymentWireAuth[];
80
+ /** Forget a vertical's records, with the vertical. */
81
+ export declare function forgetVerticalWireAuth(db: SwitchSql, verticalSlug: string): void;
82
+ //# sourceMappingURL=deployment-wire-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployment-wire-auth.d.ts","sourceRoot":"","sources":["../src/deployment-wire-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAA8D,KAAK,kBAAkB,EAAE,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAC7I,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAEvE,kFAAkF;AAClF,eAAO,MAAM,wBAAwB,qUASpC,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,uBAAuB,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAA;CAAE,CAAC;AAEjG;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,KAAK,EAAE,uBAAuB,CAAC;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CACjC;AAID,yFAAyF;AACzF,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAS7C;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,GAAG,wBAAwB,CA0C9E;AAED,4FAA4F;AAC5F,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,wBAAwB,GAAG;IAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;CAAE,CAEpG;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,kBAAkB,GAAG,IAAI,CAepF;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,wBAAwB,GAAG,kBAAkB,EAAE,CAiCzG;AAED,sDAAsD;AACtD,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAEhF"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * The capability record (RFC wire-signing §7, Q8), as statements both adapters run against their
3
+ * directory: one row per deployment, the script an upload went to (a version's archive script or a
4
+ * vertical's serving script), holding what that upload gave it. Every upload of the script replaces
5
+ * its row, so the row is the last upload's: the one the running script was built from. Written once
6
+ * so the two adapters cannot keep different records of the same fleet.
7
+ *
8
+ * The uploader writes it from what it built and injected; a vertical never declares it, since a
9
+ * claim a version makes about itself proves nothing. The readiness report (follow-on 4) reads it.
10
+ * A vertical's rows go with the vertical (`forgetVerticalWireAuth`), so none outlives what it
11
+ * describes.
12
+ */
13
+ import { deploymentWireAuth, LIST_PAGE_MAX, substratError, tenantId } from '@substrat-run/contracts';
14
+ /** Interpolated into both adapters' directory DDL, so the two spell one table. */
15
+ export const DEPLOYMENT_WIRE_AUTH_DDL = `
16
+ CREATE TABLE IF NOT EXISTS vertical_wire_auth (
17
+ deployment_ref TEXT PRIMARY KEY,
18
+ vertical_slug TEXT NOT NULL,
19
+ version_id TEXT,
20
+ record TEXT NOT NULL,
21
+ recorded_at TEXT NOT NULL
22
+ );
23
+ CREATE INDEX IF NOT EXISTS vertical_wire_auth_slug ON vertical_wire_auth (vertical_slug);
24
+ `;
25
+ const refused = (message) => substratError('validation_failed', message);
26
+ /** The longest `verticalSlug` or `cursor` a read takes. A script name is far shorter. */
27
+ export const WIRE_AUTH_FILTER_TEXT_MAX = 256;
28
+ const FILTER_KEYS = new Set(['reach', 'verticalSlug', 'limit', 'cursor', 'order']);
29
+ /** The longest caller-supplied key name a refusal echoes, so its text stays bounded. */
30
+ const ECHOED_KEY_MAX = 64;
31
+ const echoedKey = (key) => (key.length > ECHOED_KEY_MAX ? `${key.slice(0, ECHOED_KEY_MAX)}…` : key);
32
+ const REACH_REFUSAL = 'a capability-record read names its reach: one tenant ({ tenantId }) or the fleet ({ fleet: true }), exactly one';
33
+ /**
34
+ * The filter a read is allowed to run, or a `validation_failed` refusal: only the filter's own keys;
35
+ * a reach that is exactly one tenant (a tenant id) or exactly the fleet; a limit from 1 to
36
+ * `LIST_PAGE_MAX`; a vertical and a cursor of 1 to `WIRE_AUTH_FILTER_TEXT_MAX` characters; an order
37
+ * of `asc` or `desc`. Both adapters judge it before the read, and the Cloudflare host before the call
38
+ * into the directory's object, so the refusal keeps its code across the RPC.
39
+ *
40
+ * Answers a NEW object built from the judged fields alone, never the caller's, so nothing else crosses
41
+ * the RPC or reaches the access log. `reach` is its first key: the log keeps a read's params cut to a
42
+ * bounded length, and nothing after the reach can push it out of what is kept.
43
+ */
44
+ export function assertWireAuthFilter(filter) {
45
+ if (typeof filter !== 'object' || filter === null || Array.isArray(filter)) {
46
+ throw refused('a capability-record read needs a filter naming its reach and its limit');
47
+ }
48
+ // Own properties only: a field inherited from a prototype, a polluted one included, is not the caller's.
49
+ const own = (o, key) => (Object.hasOwn(o, key) ? o[key] : undefined);
50
+ const extra = Object.keys(filter).filter((key) => !FILTER_KEYS.has(key));
51
+ if (extra.length > 0) {
52
+ throw refused(`a capability-record read takes reach, verticalSlug, limit, cursor and order; not ${extra.slice(0, 3).map(echoedKey).join(', ')}`);
53
+ }
54
+ const r = own(filter, 'reach');
55
+ if (typeof r !== 'object' || r === null || Array.isArray(r))
56
+ throw refused(REACH_REFUSAL);
57
+ const keys = Object.keys(r);
58
+ if (keys.length !== 1)
59
+ throw refused(REACH_REFUSAL);
60
+ const value = own(r, keys[0]);
61
+ let reach;
62
+ if (keys[0] === 'fleet' && value === true)
63
+ reach = { fleet: true };
64
+ else if (keys[0] === 'tenantId' && tenantId.safeParse(value).success)
65
+ reach = { tenantId: tenantId.parse(value) };
66
+ else
67
+ throw refused(REACH_REFUSAL);
68
+ const limit = own(filter, 'limit');
69
+ if (typeof limit !== 'number' || !Number.isInteger(limit) || limit < 1 || limit > LIST_PAGE_MAX) {
70
+ throw refused(`limit must be an integer from 1 to ${LIST_PAGE_MAX}, got ${typeof limit === 'number' ? String(limit) : typeof limit}`);
71
+ }
72
+ const text = (name) => {
73
+ const v = own(filter, name);
74
+ if (v === undefined)
75
+ return undefined;
76
+ if (typeof v !== 'string' || v.length === 0 || v.length > WIRE_AUTH_FILTER_TEXT_MAX) {
77
+ throw refused(`${name} must be a string of 1 to ${WIRE_AUTH_FILTER_TEXT_MAX} characters`);
78
+ }
79
+ return v;
80
+ };
81
+ const verticalSlug = text('verticalSlug');
82
+ const cursor = text('cursor');
83
+ const order = own(filter, 'order');
84
+ if (order !== undefined && order !== 'asc' && order !== 'desc')
85
+ throw refused('order must be asc or desc');
86
+ return {
87
+ reach,
88
+ ...(verticalSlug !== undefined ? { verticalSlug } : {}),
89
+ limit,
90
+ ...(cursor !== undefined ? { cursor } : {}),
91
+ ...(order !== undefined ? { order } : {}),
92
+ };
93
+ }
94
+ /** The access-log target of a read: the tenant a tenant reach names, none for the fleet. */
95
+ export function wireAuthAccessTarget(filter) {
96
+ return { tenantId: 'tenantId' in filter.reach ? filter.reach.tenantId : null };
97
+ }
98
+ /**
99
+ * Record an upload's capability for its script, replacing the script's earlier record. Takes the row
100
+ * the adapter parsed (`deploymentWireAuth`) before it reached here: on Cloudflare that parse runs
101
+ * before the call into the directory's object, so a refusal keeps its code across the RPC.
102
+ */
103
+ export function writeDeploymentWireAuth(db, row) {
104
+ db.run(`INSERT INTO vertical_wire_auth (deployment_ref, vertical_slug, version_id, record, recorded_at)
105
+ VALUES (?, ?, ?, ?, ?)
106
+ ON CONFLICT (deployment_ref) DO UPDATE SET
107
+ vertical_slug = excluded.vertical_slug,
108
+ version_id = excluded.version_id,
109
+ record = excluded.record,
110
+ recorded_at = excluded.recorded_at`, row.deploymentRef, row.verticalSlug, row.versionId, JSON.stringify(row.record), row.recordedAt);
111
+ }
112
+ /**
113
+ * One page of the stored records the filter reaches, by script name. The filter is judged here too
114
+ * (`assertWireAuthFilter`), so no caller reaches the table unconfined or unbounded. A row that does
115
+ * not parse throws: it is a corrupt directory, not a fact.
116
+ */
117
+ export function deploymentWireAuthOf(db, input) {
118
+ const filter = assertWireAuthFilter(input);
119
+ const desc = filter.order === 'desc';
120
+ const where = [];
121
+ const params = [];
122
+ if ('tenantId' in filter.reach) {
123
+ where.push('vertical_slug IN (SELECT slug FROM verticals WHERE owner_tenant = ?)');
124
+ params.push(filter.reach.tenantId);
125
+ }
126
+ if (filter.verticalSlug !== undefined) {
127
+ where.push('vertical_slug = ?');
128
+ params.push(filter.verticalSlug);
129
+ }
130
+ if (filter.cursor) {
131
+ where.push(desc ? 'deployment_ref < ?' : 'deployment_ref > ?');
132
+ params.push(filter.cursor);
133
+ }
134
+ params.push(filter.limit);
135
+ const rows = db.all('SELECT deployment_ref, vertical_slug, version_id, record, recorded_at FROM vertical_wire_auth' +
136
+ (where.length ? ` WHERE ${where.join(' AND ')}` : '') +
137
+ ` ORDER BY deployment_ref ${desc ? 'DESC' : 'ASC'} LIMIT ?`, ...params);
138
+ return rows.map((r) => deploymentWireAuth.parse({
139
+ deploymentRef: r['deployment_ref'],
140
+ verticalSlug: r['vertical_slug'],
141
+ versionId: r['version_id'],
142
+ record: JSON.parse(String(r['record'])),
143
+ recordedAt: r['recorded_at'],
144
+ }));
145
+ }
146
+ /** Forget a vertical's records, with the vertical. */
147
+ export function forgetVerticalWireAuth(db, verticalSlug) {
148
+ db.run('DELETE FROM vertical_wire_auth WHERE vertical_slug = ?', verticalSlug);
149
+ }
150
+ //# sourceMappingURL=deployment-wire-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployment-wire-auth.js","sourceRoot":"","sources":["../src/deployment-wire-auth.ts"],"names":[],"mappings":"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"}
@@ -24,7 +24,15 @@ import { type EntityRef, type EntityStateDeclaration, type OperationTarget, type
24
24
  import { type EntityStatePlan, type StateCheck } from './entity-state.js';
25
25
  import type { ScopedSql } from './scope-host.js';
26
26
  import type { SystemScheduleState } from './system-switch.js';
27
- /** How many entities one purge pass deletes per entity type. A full batch leaves the schedule due. */
27
+ /**
28
+ * How many entities one purge pass deletes per entity type. A full batch leaves the schedule due.
29
+ *
30
+ * A CEILING, not a promise: a purge that enqueues a platform request is held to the scope's
31
+ * `MAX_PENDING_PLATFORM_REQUESTS` as well, which is smaller. The two are not reconciled by a
32
+ * second number — the cap is the one authority and decides how many such purges a pass commits.
33
+ * Past the head of its pass, a pass that meets the cap's refusal stops there; at the head the
34
+ * refusal is a failure like any other (`runPurgePass`, #2506).
35
+ */
28
36
  export declare const PURGE_BATCH = 50;
29
37
  /**
30
38
  * Is `entity` out of reach as a parent (#119): its type declares trash, and it is in the trash or
@@ -104,9 +112,11 @@ export declare function purgeCandidates(sql: ScopedSql, plan: EntityStatePlan, c
104
112
  /**
105
113
  * A purge LAP in progress (#2096) — what a schedule's cadence row holds in `purge_cursor` between
106
114
  * passes. A lap walks the whole due bin, oldest first, `PURGE_BATCH` at a time; each pass resumes
107
- * after the last entity the one before it tried, whatever became of that entity. So entities that
115
+ * after the last entity the one before it tried, whatever became of that entity — except one the
116
+ * scope's platform-request cap turned away past the head of its pass (#2506), which was not tried
117
+ * in any sense that matters: it rolled back whole, and the next pass starts at it. So entities that
108
118
  * keep failing cannot hold the head of the walk: the walk moves past them, reaches everything due
109
- * behind them in the same lap, and tries them again in the next.
119
+ * behind them in the same lap, and tries them again in the next. A refused head is one of them.
110
120
  *
111
121
  * `failed` counts the purges that failed in the lap's earlier passes, so the pass that closes the
112
122
  * lap — the one that writes the cadence row — records the lap `failed` even when its own batch
@@ -132,6 +142,12 @@ export interface PurgeDue {
132
142
  readonly idFrom: string;
133
143
  /** The ids this pass tries, in the walk's order. */
134
144
  readonly ids: string[];
145
+ /**
146
+ * #2506: the walk position of each of `ids`, in the same order — what lets a pass that stops
147
+ * part-way resume after the last entity it actually tried. Absent from a hand-built `PurgeDue`,
148
+ * which a pass then cannot cut short (see `runPurgePass`).
149
+ */
150
+ readonly keys?: readonly PurgeKey[];
135
151
  /** The lap as this pass found it. */
136
152
  readonly lap: PurgeLap;
137
153
  /** Where the next pass resumes when more is due after these ids — or null: this pass closes the lap. */
@@ -190,8 +206,21 @@ export interface PurgePass {
190
206
  * Absent, like `more`, from a scope running code older than the lap, which ran no lap.
191
207
  */
192
208
  lapFailed?: number;
209
+ /**
210
+ * #2517: the cap refused the head because the purge passes before this one in the same tick filled
211
+ * the queue (`runPurgePass`), so the pass tried nothing and waits for the next tick. A host reports
212
+ * the run `skipped` and counts it in `ScheduleRunReport.deferred`, never `fired`. Absent otherwise,
213
+ * and from a scope running code older than the field, which fails such a head instead.
214
+ */
215
+ deferred?: true;
193
216
  /** Why the scope ran no purge at all this pass (`purgeHeldBy`), when its gate held it. */
194
217
  held?: string;
218
+ /**
219
+ * #2440: platform requests the purges that committed enqueued, when a scope that runs the purges
220
+ * out of the caller's sight reports them (the Durable Object does; the SQLite host counts through
221
+ * the stub it invokes with). Absent means none, or a scope running code older than this field.
222
+ */
223
+ platformRequests?: number;
195
224
  }
196
225
  /** A pass the scope's gate held: nothing selected, nothing tried, the lap where it was. */
197
226
  export declare function heldPurgePass(held: string): PurgePass;
@@ -206,15 +235,43 @@ export declare function heldPurgePass(held: string): PurgePass;
206
235
  * batch with its failures added while more is due, or close the lap. After the pass, so a pass cut
207
236
  * short repeats its batch rather than skipping it. `inScope` runs the write against the scope's
208
237
  * spine, in the turn the adapter's storage needs.
238
+ *
239
+ * The one exception to "whatever its purges did" is the scope's platform-request cap (#2506): a
240
+ * purge the cap refuses (`isPlatformRequestRefusal`) AFTER the pass has got past its head is
241
+ * deferred rather than failed, and the lap resumes at it. A pass always moves the lap strictly
242
+ * forward, so neither a deferral nor a refused head can hold the head of the walk.
243
+ *
244
+ * One more case (#2517): a head the cap refuses is deferred, not failed, when
245
+ * `earlierPurgeRequests` says that the PURGE passes run before this one in the same scheduled tick
246
+ * (this module's or an earlier module's) enqueued requests. Nothing drains the scope between the
247
+ * schedules of a tick, so that head met a queue the tick's own purges filled, and failing it would
248
+ * make the run wait its whole cadence for nothing. The pass then ends having tried nothing
249
+ * (`deferred`): the lap is left exactly as it was, `more` is true so the schedule stays due, and
250
+ * the next tick tries the same head again.
251
+ *
252
+ * Only purge passes count, never an ordinary schedule's requests or any other traffic, because
253
+ * that is what bounds the deferral. Each tick that defers this head needs a purge ahead of it to
254
+ * have COMMITTED a purge that enqueued a request, and that entity has left its bin for good; an
255
+ * ordinary schedule can enqueue every tick forever, which would hold the head, and everything
256
+ * behind it, for ever (#2096). So the head is deferred only while the purges ahead of it keep
257
+ * committing requests, and on the first tick none does (their laps closed, their cadence not due,
258
+ * or the queue still full so they could enqueue nothing) it runs like any head: it purges if it
259
+ * fits, and a head that cannot fit, or a queue other traffic holds full, fails it as before. It
260
+ * cannot spin: the scheduled tick runs each schedule once.
209
261
  */
210
- export declare function runPurgePass(operation: string, due: PurgeDue, purgeOne: (entityId: string) => Promise<void>, inScope: (write: (sql: ScopedSql) => void) => unknown): Promise<PurgePass>;
262
+ export declare function runPurgePass(operation: string, due: PurgeDue, purgeOne: (entityId: string) => Promise<void>, inScope: (write: (sql: ScopedSql) => void) => unknown, earlierPurgeRequests?: number): Promise<PurgePass>;
211
263
  /**
212
264
  * Whether a purge pass leaves its schedule due, so the next sweep pass continues its lap rather
213
265
  * than waiting the cadence: more is due after its batch (#2096). It cannot spin (#2087): every pass
214
- * moves the lap strictly forward, whatever its purges did, and the pass that runs out of due
215
- * entities closes the lap and records the run — so a cadence window holds one lap, and an entity
216
- * that keeps failing is tried once per window, not once per sweep tick. A scope running code older
217
- * than the lap answers no `more`, and its pass waits its cadence.
266
+ * moves the lap strictly forward, whatever its purges did, bar one — the pass that defers its head
267
+ * to the next tick because the tick's earlier purge passes filled the queue (#2517), which needs a
268
+ * purge ahead of it to have committed a request (so the tick made progress) and which nothing
269
+ * re-runs within the tick. A pass that defers an entity the platform-request cap turned away (#2506) has
270
+ * already got past its head, and the entity is the head of the next pass, where a refusal is a
271
+ * failure like any other — and the pass that runs out
272
+ * of due entities closes the lap and records the run. So a cadence window holds one lap, and an
273
+ * entity that keeps failing is tried once per window, not once per sweep tick. A scope running
274
+ * code older than the lap answers no `more`, and its pass waits its cadence.
218
275
  */
219
276
  export declare function purgeStillDue(pass: PurgePass): boolean;
220
277
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"entity-trash.d.ts","sourceRoot":"","sources":["../src/entity-trash.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"entity-trash.d.ts","sourceRoot":"","sources":["../src/entity-trash.ts"],"names":[],"mappings":"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"}