@substrat-run/kernel 0.158.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.
- package/dist/billing-retention.d.ts +46 -0
- package/dist/billing-retention.d.ts.map +1 -0
- package/dist/billing-retention.js +78 -0
- package/dist/billing-retention.js.map +1 -0
- package/dist/byte-stream.d.ts +102 -0
- package/dist/byte-stream.d.ts.map +1 -0
- package/dist/byte-stream.js +153 -0
- package/dist/byte-stream.js.map +1 -0
- package/dist/connection-landings.d.ts +15 -3
- package/dist/connection-landings.d.ts.map +1 -1
- package/dist/connection-landings.js +10 -2
- package/dist/connection-landings.js.map +1 -1
- package/dist/deadline-fetch.d.ts +34 -0
- package/dist/deadline-fetch.d.ts.map +1 -0
- package/dist/deadline-fetch.js +231 -0
- package/dist/deadline-fetch.js.map +1 -0
- package/dist/deployment-wire-auth.d.ts +82 -0
- package/dist/deployment-wire-auth.d.ts.map +1 -0
- package/dist/deployment-wire-auth.js +150 -0
- package/dist/deployment-wire-auth.js.map +1 -0
- package/dist/entity-trash.d.ts +65 -8
- package/dist/entity-trash.d.ts.map +1 -1
- package/dist/entity-trash.js +80 -12
- package/dist/entity-trash.js.map +1 -1
- package/dist/export-break.d.ts +6 -0
- package/dist/export-break.d.ts.map +1 -1
- package/dist/export-break.js +11 -0
- package/dist/export-break.js.map +1 -1
- package/dist/index.d.ts +18 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -7
- package/dist/index.js.map +1 -1
- package/dist/invocation-line.d.ts +3 -2
- package/dist/invocation-line.d.ts.map +1 -1
- package/dist/invocation-line.js +2 -0
- package/dist/invocation-line.js.map +1 -1
- package/dist/meter-days.d.ts +107 -0
- package/dist/meter-days.d.ts.map +1 -0
- package/dist/meter-days.js +230 -0
- package/dist/meter-days.js.map +1 -0
- package/dist/meters.d.ts +19 -1
- package/dist/meters.d.ts.map +1 -1
- package/dist/meters.js +0 -0
- package/dist/meters.js.map +1 -1
- package/dist/ops-failure-reference.d.ts +31 -0
- package/dist/ops-failure-reference.d.ts.map +1 -0
- package/dist/ops-failure-reference.js +32 -0
- package/dist/ops-failure-reference.js.map +1 -0
- package/dist/platform-request-cap.d.ts +9 -0
- package/dist/platform-request-cap.d.ts.map +1 -0
- package/dist/platform-request-cap.js +42 -0
- package/dist/platform-request-cap.js.map +1 -0
- package/dist/platform-sweep.d.ts +170 -7
- package/dist/platform-sweep.d.ts.map +1 -1
- package/dist/platform-sweep.js +375 -45
- package/dist/platform-sweep.js.map +1 -1
- package/dist/request-rollup.d.ts +161 -0
- package/dist/request-rollup.d.ts.map +1 -0
- package/dist/request-rollup.js +273 -0
- package/dist/request-rollup.js.map +1 -0
- package/dist/reserved-roles.d.ts +157 -4
- package/dist/reserved-roles.d.ts.map +1 -1
- package/dist/reserved-roles.js +216 -2
- package/dist/reserved-roles.js.map +1 -1
- package/dist/schedule-state.d.ts +5 -0
- package/dist/schedule-state.d.ts.map +1 -1
- package/dist/scope-host.d.ts +260 -15
- package/dist/scope-host.d.ts.map +1 -1
- package/dist/scope-host.js +53 -2
- package/dist/scope-host.js.map +1 -1
- package/dist/scope-lifecycle.d.ts +7 -0
- package/dist/scope-lifecycle.d.ts.map +1 -1
- package/dist/scope-lifecycle.js +7 -0
- package/dist/scope-lifecycle.js.map +1 -1
- package/dist/scope-record.d.ts +16 -5
- package/dist/scope-record.d.ts.map +1 -1
- package/dist/scope-record.js +72 -7
- package/dist/scope-record.js.map +1 -1
- package/dist/spine-restore.d.ts +7 -3
- package/dist/spine-restore.d.ts.map +1 -1
- package/dist/spine-restore.js +14 -3
- package/dist/spine-restore.js.map +1 -1
- package/dist/storage-gauge.d.ts +47 -13
- package/dist/storage-gauge.d.ts.map +1 -1
- package/dist/storage-gauge.js +84 -27
- package/dist/storage-gauge.js.map +1 -1
- package/dist/subject-redaction.d.ts +9 -3
- package/dist/subject-redaction.d.ts.map +1 -1
- package/dist/subject-redaction.js +24 -12
- package/dist/subject-redaction.js.map +1 -1
- package/dist/vertical-owners.d.ts +69 -0
- package/dist/vertical-owners.d.ts.map +1 -0
- package/dist/vertical-owners.js +108 -0
- package/dist/vertical-owners.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { RedactionSql } from './subject-redaction.js';
|
|
2
|
+
/**
|
|
3
|
+
* How long the platform keeps its billing rollups (#2501): the compact per-(tenant, vertical)
|
|
4
|
+
* daily counts a later invoice, or a dispute about one, is answered from. Today that is the daily
|
|
5
|
+
* request rollup (`request-rollup.ts`) and the daily meter snapshot (`meter-days.ts`). The raw
|
|
6
|
+
* captures behind a rollup keep their own, shorter windows, and no existing retention follows
|
|
7
|
+
* this constant: the storage gauge's day rows stay `STORAGE_GAUGE_RETENTION_MONTHS` and model
|
|
8
|
+
* usage stays `MODEL_USAGE_RETENTION_DAYS`.
|
|
9
|
+
*
|
|
10
|
+
* `null` means the rollups are never pruned. That is a placeholder, not a decision: the horizon
|
|
11
|
+
* waits on the maintainer's bookkeeping, and no legal period is written here. Keeping
|
|
12
|
+
* everything is the reversible default, since a pruned row cannot be brought back while a
|
|
13
|
+
* horizon can be set later. The rollups hold counts and bytes only, never personal content.
|
|
14
|
+
*/
|
|
15
|
+
export declare const BILLING_ROLLUP_RETENTION_MONTHS: number | null;
|
|
16
|
+
/**
|
|
17
|
+
* The first day a billing retention of `months` keeps, or null when `months` is null (kept for
|
|
18
|
+
* good). A horizon is a whole number of months, at least one. Every billing rollup prunes by it.
|
|
19
|
+
*/
|
|
20
|
+
export declare function billingRollupHorizon(nowMs: number, months: number | null): string | null;
|
|
21
|
+
/**
|
|
22
|
+
* The UTC day `months` calendar months before `nowMs`. The day of the month is clamped to the
|
|
23
|
+
* target month's last day, so the 31st counts back to the 28th, 29th or 30th rather than rolling
|
|
24
|
+
* forward into the month after.
|
|
25
|
+
*/
|
|
26
|
+
export declare function utcDayMonthsBefore(nowMs: number, months: number): string;
|
|
27
|
+
/** The UTC day an instant falls on. */
|
|
28
|
+
export declare function utcDayOf(ms: number): string;
|
|
29
|
+
/** `day`, refused unless it is a UTC day that exists (`YYYY-MM-DD`). */
|
|
30
|
+
export declare function assertUtcDay(name: string, day: string): string;
|
|
31
|
+
/** Push an inclusive window of UTC days onto a `WHERE` list and its parameters, each day checked first. */
|
|
32
|
+
export declare function pushDayWindow(filter: {
|
|
33
|
+
since?: string;
|
|
34
|
+
until?: string;
|
|
35
|
+
}, where: string[], params: (string | number)[]): void;
|
|
36
|
+
/**
|
|
37
|
+
* Delete at most `limit` rows of a billing rollup's `rows` table older than a retention of
|
|
38
|
+
* `months`, oldest first, then the `records` of the days that are gone. `months` null deletes
|
|
39
|
+
* nothing. A record goes only once its day holds no row, so a day still being pruned stays marked
|
|
40
|
+
* done and is not rolled up again in between. Returns how many rows went.
|
|
41
|
+
*/
|
|
42
|
+
export declare function pruneBillingDays(sql: RedactionSql, tables: {
|
|
43
|
+
rows: string;
|
|
44
|
+
records: string;
|
|
45
|
+
}, nowMs: number, limit: number, months: number | null): number;
|
|
46
|
+
//# sourceMappingURL=billing-retention.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"billing-retention.d.ts","sourceRoot":"","sources":["../src/billing-retention.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAG3D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,+BAA+B,EAAE,MAAM,GAAG,IAAW,CAAC;AAEnE;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAMxF;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAMxE;AAED,uCAAuC;AACvC,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wEAAwE;AACxE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED,2GAA2G;AAC3G,wBAAgB,aAAa,CAAC,MAAM,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,IAAI,CAS5H;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,YAAY,EACjB,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EACzC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GAAG,IAAI,GACpB,MAAM,CAWR"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { utcDay } from '@substrat-run/contracts';
|
|
2
|
+
import { assertRowLimit, boundedRetentionDelete } from './scope-host.js';
|
|
3
|
+
/**
|
|
4
|
+
* How long the platform keeps its billing rollups (#2501): the compact per-(tenant, vertical)
|
|
5
|
+
* daily counts a later invoice, or a dispute about one, is answered from. Today that is the daily
|
|
6
|
+
* request rollup (`request-rollup.ts`) and the daily meter snapshot (`meter-days.ts`). The raw
|
|
7
|
+
* captures behind a rollup keep their own, shorter windows, and no existing retention follows
|
|
8
|
+
* this constant: the storage gauge's day rows stay `STORAGE_GAUGE_RETENTION_MONTHS` and model
|
|
9
|
+
* usage stays `MODEL_USAGE_RETENTION_DAYS`.
|
|
10
|
+
*
|
|
11
|
+
* `null` means the rollups are never pruned. That is a placeholder, not a decision: the horizon
|
|
12
|
+
* waits on the maintainer's bookkeeping, and no legal period is written here. Keeping
|
|
13
|
+
* everything is the reversible default, since a pruned row cannot be brought back while a
|
|
14
|
+
* horizon can be set later. The rollups hold counts and bytes only, never personal content.
|
|
15
|
+
*/
|
|
16
|
+
export const BILLING_ROLLUP_RETENTION_MONTHS = null;
|
|
17
|
+
/**
|
|
18
|
+
* The first day a billing retention of `months` keeps, or null when `months` is null (kept for
|
|
19
|
+
* good). A horizon is a whole number of months, at least one. Every billing rollup prunes by it.
|
|
20
|
+
*/
|
|
21
|
+
export function billingRollupHorizon(nowMs, months) {
|
|
22
|
+
if (months === null)
|
|
23
|
+
return null;
|
|
24
|
+
if (!Number.isInteger(months) || months < 1) {
|
|
25
|
+
throw new Error(`a billing retention must be a whole number of months, at least one, or null, got ${String(months)}`);
|
|
26
|
+
}
|
|
27
|
+
return utcDayMonthsBefore(nowMs, months);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The UTC day `months` calendar months before `nowMs`. The day of the month is clamped to the
|
|
31
|
+
* target month's last day, so the 31st counts back to the 28th, 29th or 30th rather than rolling
|
|
32
|
+
* forward into the month after.
|
|
33
|
+
*/
|
|
34
|
+
export function utcDayMonthsBefore(nowMs, months) {
|
|
35
|
+
const now = new Date(nowMs);
|
|
36
|
+
const month = now.getUTCMonth() - months;
|
|
37
|
+
// Day 0 of the following month is the last day of the target month.
|
|
38
|
+
const lastDay = new Date(Date.UTC(now.getUTCFullYear(), month + 1, 0)).getUTCDate();
|
|
39
|
+
return new Date(Date.UTC(now.getUTCFullYear(), month, Math.min(now.getUTCDate(), lastDay))).toISOString().slice(0, 10);
|
|
40
|
+
}
|
|
41
|
+
/** The UTC day an instant falls on. */
|
|
42
|
+
export function utcDayOf(ms) {
|
|
43
|
+
return new Date(ms).toISOString().slice(0, 10);
|
|
44
|
+
}
|
|
45
|
+
/** `day`, refused unless it is a UTC day that exists (`YYYY-MM-DD`). */
|
|
46
|
+
export function assertUtcDay(name, day) {
|
|
47
|
+
if (!utcDay.safeParse(day).success)
|
|
48
|
+
throw new Error(`${name} must be a UTC day (YYYY-MM-DD), got ${JSON.stringify(day)}`);
|
|
49
|
+
return day;
|
|
50
|
+
}
|
|
51
|
+
/** Push an inclusive window of UTC days onto a `WHERE` list and its parameters, each day checked first. */
|
|
52
|
+
export function pushDayWindow(filter, where, params) {
|
|
53
|
+
if (filter.since !== undefined) {
|
|
54
|
+
where.push('day >= ?');
|
|
55
|
+
params.push(assertUtcDay('since', filter.since));
|
|
56
|
+
}
|
|
57
|
+
if (filter.until !== undefined) {
|
|
58
|
+
where.push('day <= ?');
|
|
59
|
+
params.push(assertUtcDay('until', filter.until));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Delete at most `limit` rows of a billing rollup's `rows` table older than a retention of
|
|
64
|
+
* `months`, oldest first, then the `records` of the days that are gone. `months` null deletes
|
|
65
|
+
* nothing. A record goes only once its day holds no row, so a day still being pruned stays marked
|
|
66
|
+
* done and is not rolled up again in between. Returns how many rows went.
|
|
67
|
+
*/
|
|
68
|
+
export function pruneBillingDays(sql, tables, nowMs, limit, months) {
|
|
69
|
+
const capped = assertRowLimit('limit', limit);
|
|
70
|
+
const horizon = billingRollupHorizon(nowMs, months);
|
|
71
|
+
if (horizon === null)
|
|
72
|
+
return 0;
|
|
73
|
+
const pruned = sql(boundedRetentionDelete(tables.rows, 'day'), [horizon, capped]).length;
|
|
74
|
+
sql(`DELETE FROM ${tables.records}
|
|
75
|
+
WHERE day < ? AND NOT EXISTS (SELECT 1 FROM ${tables.rows} d WHERE d.day = ${tables.records}.day)`, [horizon]);
|
|
76
|
+
return pruned;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=billing-retention.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"billing-retention.js","sourceRoot":"","sources":["../src/billing-retention.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bytes as a stream (#2498, `docs/rfc/file-bearing-sources.md` §6).
|
|
3
|
+
*
|
|
4
|
+
* The byte seams between a provider, a connector and the attachment store each took the whole
|
|
5
|
+
* body as one buffer, so the largest file a connector could land was whatever the worker had
|
|
6
|
+
* memory for. Each seam now also takes a {@link SizedByteStream}: a stream, plus the length its
|
|
7
|
+
* producer declares. The length is declared rather than counted because the stores need it
|
|
8
|
+
* before the first byte (R2 refuses a stream of unknown length), and it is enforced on the way
|
|
9
|
+
* through: a stream that carries more or fewer bytes than it declared errors instead of landing.
|
|
10
|
+
*
|
|
11
|
+
* Structural, for the reason `FetchLike` is: the kernel depends on no platform typings, and a
|
|
12
|
+
* web `ReadableStream<Uint8Array>` from Node, workerd or a browser satisfies {@link ByteStream}
|
|
13
|
+
* without either being required.
|
|
14
|
+
*/
|
|
15
|
+
/** One read from a {@link ByteStreamReader}: a chunk, or the end. */
|
|
16
|
+
export interface ByteStreamRead {
|
|
17
|
+
readonly done: boolean;
|
|
18
|
+
readonly value?: Uint8Array;
|
|
19
|
+
}
|
|
20
|
+
/** The reader a {@link ByteStream} hands out — the slice of `ReadableStreamDefaultReader` used here. */
|
|
21
|
+
export interface ByteStreamReader {
|
|
22
|
+
read(): Promise<ByteStreamRead>;
|
|
23
|
+
cancel(reason?: unknown): Promise<void>;
|
|
24
|
+
releaseLock(): void;
|
|
25
|
+
}
|
|
26
|
+
/** A web `ReadableStream<Uint8Array>`, structurally. */
|
|
27
|
+
export interface ByteStream {
|
|
28
|
+
getReader(): ByteStreamReader;
|
|
29
|
+
}
|
|
30
|
+
/** A byte stream with the length its producer declares. */
|
|
31
|
+
export interface SizedByteStream {
|
|
32
|
+
readonly stream: ByteStream;
|
|
33
|
+
readonly length: number;
|
|
34
|
+
}
|
|
35
|
+
/** A body a byte seam takes: the whole buffer, as before, or a sized stream. */
|
|
36
|
+
export type ByteBody = Uint8Array | SizedByteStream;
|
|
37
|
+
/**
|
|
38
|
+
* Bytes a connector already holds, in the shape a connector upload takes (#2538): the buffer itself
|
|
39
|
+
* up to {@link CONNECTOR_ATTACHMENT_BUFFERED_MAX_BYTES}, and above it a {@link SizedByteStream} of the
|
|
40
|
+
* same bytes, which the platform sends by the streamed route instead of refusing. It does not shrink
|
|
41
|
+
* what the connector holds; it keeps a file the connector could fetch landing end to end. The stream
|
|
42
|
+
* is one-shot: read it once, and call this again for another upload of the same bytes.
|
|
43
|
+
*/
|
|
44
|
+
export declare function connectorUploadBody(bytes: Uint8Array): ByteBody;
|
|
45
|
+
/** Is `body` a sized stream rather than a buffer? */
|
|
46
|
+
export declare function isSizedByteStream(body: unknown): body is SizedByteStream;
|
|
47
|
+
/**
|
|
48
|
+
* A running SHA-256, fed one chunk at a time. The kernel holds no implementation: Web Crypto has
|
|
49
|
+
* no incremental digest and a hand-rolled one is not an option, so each adapter passes its
|
|
50
|
+
* runtime's own (workerd's `crypto.DigestStream`, Node's `createHash`).
|
|
51
|
+
*/
|
|
52
|
+
export interface IncrementalSha256 {
|
|
53
|
+
update(chunk: Uint8Array): void | Promise<void>;
|
|
54
|
+
/** The lowercase hex digest of everything fed so far. Called once, after the last chunk. */
|
|
55
|
+
hex(): Promise<string>;
|
|
56
|
+
}
|
|
57
|
+
/** What a witnessed stream's bytes were, once they have all passed. */
|
|
58
|
+
export interface StreamWitness {
|
|
59
|
+
readonly sha256: string;
|
|
60
|
+
readonly size: number;
|
|
61
|
+
}
|
|
62
|
+
/** A sized stream that hashes and counts its bytes as its reader takes them. */
|
|
63
|
+
export interface WitnessedStream {
|
|
64
|
+
readonly body: SizedByteStream;
|
|
65
|
+
/**
|
|
66
|
+
* The bytes' sha256 and size. Throws until the stream has been read to its end, so a store
|
|
67
|
+
* that answered without consuming the body cannot have a record written for bytes it never saw.
|
|
68
|
+
*/
|
|
69
|
+
witness(): StreamWitness;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Hash and count `body` while it flows to wherever it is going. The digest is fed each chunk
|
|
73
|
+
* before the chunk moves on, and the final digest is taken before the stream reports its end, so
|
|
74
|
+
* once the consumer has read to the end — a store's `put` has resolved — {@link
|
|
75
|
+
* WitnessedStream.witness} answers.
|
|
76
|
+
*/
|
|
77
|
+
export declare function witnessedStream(body: SizedByteStream, digest: IncrementalSha256): WitnessedStream;
|
|
78
|
+
/**
|
|
79
|
+
* `body` as a stream of known length that the runtime takes, held to its declared length: a
|
|
80
|
+
* stream that carries more or fewer bytes errors whatever reads it. On workerd that is a
|
|
81
|
+
* `FixedLengthStream`, which a `fetch` sends with a `Content-Length` rather than chunked and
|
|
82
|
+
* which R2's `put` accepts (it refuses a stream of unknown length); the runtime enforces the
|
|
83
|
+
* length there, so a web stream is piped straight in. Elsewhere it is the stream passed through
|
|
84
|
+
* a relay that enforces the length.
|
|
85
|
+
*/
|
|
86
|
+
export declare function knownLengthStream(body: SizedByteStream): ByteStream;
|
|
87
|
+
/**
|
|
88
|
+
* A request init whose body is a sized stream, as the runtime's `fetch` takes it: the body
|
|
89
|
+
* as {@link knownLengthStream}, and off workerd the `Content-Length` header and `duplex: 'half'`
|
|
90
|
+
* a streamed request body needs there. `fetchLikeOf` sends through it, so a `FetchLike` does not
|
|
91
|
+
* call this itself: a runtime `fetch` becomes one by `fetchLikeOf`. A caller that holds a
|
|
92
|
+
* runtime `fetch` it does not make a `FetchLike` (the platform's vertical client) does.
|
|
93
|
+
*/
|
|
94
|
+
export declare function knownLengthInit<Init extends {
|
|
95
|
+
headers?: Record<string, string>;
|
|
96
|
+
body: SizedByteStream;
|
|
97
|
+
}>(init: Init): Omit<Init, 'body'> & {
|
|
98
|
+
body: ByteStream;
|
|
99
|
+
headers: Record<string, string>;
|
|
100
|
+
duplex?: 'half';
|
|
101
|
+
};
|
|
102
|
+
//# sourceMappingURL=byte-stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"byte-stream.d.ts","sourceRoot":"","sources":["../src/byte-stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,qEAAqE;AACrE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;CAC7B;AAED,wGAAwG;AACxG,MAAM,WAAW,gBAAgB;IAC/B,IAAI,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IAChC,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,WAAW,IAAI,IAAI,CAAC;CACrB;AAED,wDAAwD;AACxD,MAAM,WAAW,UAAU;IACzB,SAAS,IAAI,gBAAgB,CAAC;CAC/B;AAED,2DAA2D;AAC3D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,gFAAgF;AAChF,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,eAAe,CAAC;AAEpD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,QAAQ,CAmB/D;AAED,qDAAqD;AACrD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,eAAe,CAQxE;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,4FAA4F;IAC5F,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CACxB;AAED,uEAAuE;AACvE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,gFAAgF;AAChF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B;;;OAGG;IACH,OAAO,IAAI,aAAa,CAAC;CAC1B;AAmED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,iBAAiB,GAAG,eAAe,CAiBjG;AAUD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,UAAU,CAOnE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,SAAS;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,EAAE,eAAe,CAAA;CAAE,EACtG,IAAI,EAAE,IAAI,GACT,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAS7F"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bytes as a stream (#2498, `docs/rfc/file-bearing-sources.md` §6).
|
|
3
|
+
*
|
|
4
|
+
* The byte seams between a provider, a connector and the attachment store each took the whole
|
|
5
|
+
* body as one buffer, so the largest file a connector could land was whatever the worker had
|
|
6
|
+
* memory for. Each seam now also takes a {@link SizedByteStream}: a stream, plus the length its
|
|
7
|
+
* producer declares. The length is declared rather than counted because the stores need it
|
|
8
|
+
* before the first byte (R2 refuses a stream of unknown length), and it is enforced on the way
|
|
9
|
+
* through: a stream that carries more or fewer bytes than it declared errors instead of landing.
|
|
10
|
+
*
|
|
11
|
+
* Structural, for the reason `FetchLike` is: the kernel depends on no platform typings, and a
|
|
12
|
+
* web `ReadableStream<Uint8Array>` from Node, workerd or a browser satisfies {@link ByteStream}
|
|
13
|
+
* without either being required.
|
|
14
|
+
*/
|
|
15
|
+
import { CONNECTOR_ATTACHMENT_BUFFERED_MAX_BYTES } from '@substrat-run/contracts';
|
|
16
|
+
/**
|
|
17
|
+
* Bytes a connector already holds, in the shape a connector upload takes (#2538): the buffer itself
|
|
18
|
+
* up to {@link CONNECTOR_ATTACHMENT_BUFFERED_MAX_BYTES}, and above it a {@link SizedByteStream} of the
|
|
19
|
+
* same bytes, which the platform sends by the streamed route instead of refusing. It does not shrink
|
|
20
|
+
* what the connector holds; it keeps a file the connector could fetch landing end to end. The stream
|
|
21
|
+
* is one-shot: read it once, and call this again for another upload of the same bytes.
|
|
22
|
+
*/
|
|
23
|
+
export function connectorUploadBody(bytes) {
|
|
24
|
+
if (bytes.byteLength <= CONNECTOR_ATTACHMENT_BUFFERED_MAX_BYTES)
|
|
25
|
+
return bytes;
|
|
26
|
+
const CHUNK = 1024 * 1024;
|
|
27
|
+
let at = 0;
|
|
28
|
+
const stream = new ReadableStream({
|
|
29
|
+
async pull(controller) {
|
|
30
|
+
if (at >= bytes.byteLength) {
|
|
31
|
+
controller.close();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
controller.enqueue(bytes.subarray(at, Math.min(at + CHUNK, bytes.byteLength)));
|
|
35
|
+
at += CHUNK;
|
|
36
|
+
},
|
|
37
|
+
async cancel() { },
|
|
38
|
+
}, { highWaterMark: 0 });
|
|
39
|
+
return { stream, length: bytes.byteLength };
|
|
40
|
+
}
|
|
41
|
+
/** Is `body` a sized stream rather than a buffer? */
|
|
42
|
+
export function isSizedByteStream(body) {
|
|
43
|
+
return (typeof body === 'object' &&
|
|
44
|
+
body !== null &&
|
|
45
|
+
!ArrayBuffer.isView(body) &&
|
|
46
|
+
typeof body.stream?.getReader === 'function' &&
|
|
47
|
+
typeof body.length === 'number');
|
|
48
|
+
}
|
|
49
|
+
/** Refuse a declared length no stream can have. */
|
|
50
|
+
function assertDeclaredLength(length) {
|
|
51
|
+
if (!Number.isSafeInteger(length) || length < 0) {
|
|
52
|
+
throw new Error(`a byte stream's declared length must be a non-negative integer, not ${length}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* A new stream that passes `source` through chunk by chunk, holding it to `length`. Pull-driven
|
|
57
|
+
* with no queue of its own (`highWaterMark: 0`), so a chunk is read from the source only when the
|
|
58
|
+
* consumer asks for one: at most one chunk is in flight, whatever the body's size.
|
|
59
|
+
*/
|
|
60
|
+
function relay(source, length, onChunk, onEnd) {
|
|
61
|
+
assertDeclaredLength(length);
|
|
62
|
+
const reader = source.getReader();
|
|
63
|
+
let size = 0;
|
|
64
|
+
return new ReadableStream({
|
|
65
|
+
async pull(controller) {
|
|
66
|
+
try {
|
|
67
|
+
const { done, value } = await reader.read();
|
|
68
|
+
if (done) {
|
|
69
|
+
if (size !== length) {
|
|
70
|
+
throw new Error(`the byte stream ended after ${size} bytes; it declared ${length}`);
|
|
71
|
+
}
|
|
72
|
+
await onEnd?.();
|
|
73
|
+
controller.close();
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
// A read that neither ends nor carries a chunk is a broken source: answering it by
|
|
77
|
+
// returning would leave the consumer's read waiting for a pull that never comes.
|
|
78
|
+
if (!value)
|
|
79
|
+
throw new Error('the byte stream yielded a read with neither a chunk nor its end');
|
|
80
|
+
size += value.byteLength;
|
|
81
|
+
if (size > length) {
|
|
82
|
+
throw new Error(`the byte stream carried more than the ${length} bytes it declared`);
|
|
83
|
+
}
|
|
84
|
+
await onChunk?.(value);
|
|
85
|
+
controller.enqueue(value);
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
controller.error(err);
|
|
89
|
+
await reader.cancel(err).catch(() => { });
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
cancel: (reason) => reader.cancel(reason),
|
|
93
|
+
}, { highWaterMark: 0 });
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Hash and count `body` while it flows to wherever it is going. The digest is fed each chunk
|
|
97
|
+
* before the chunk moves on, and the final digest is taken before the stream reports its end, so
|
|
98
|
+
* once the consumer has read to the end — a store's `put` has resolved — {@link
|
|
99
|
+
* WitnessedStream.witness} answers.
|
|
100
|
+
*/
|
|
101
|
+
export function witnessedStream(body, digest) {
|
|
102
|
+
let witnessed;
|
|
103
|
+
const stream = relay(body.stream, body.length, (chunk) => digest.update(chunk), async () => {
|
|
104
|
+
witnessed = { sha256: await digest.hex(), size: body.length };
|
|
105
|
+
});
|
|
106
|
+
return {
|
|
107
|
+
body: { stream, length: body.length },
|
|
108
|
+
witness: () => {
|
|
109
|
+
if (!witnessed)
|
|
110
|
+
throw new Error('the byte stream was not read to its end, so its bytes are unwitnessed');
|
|
111
|
+
return witnessed;
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/** The runtime's own `FixedLengthStream`, where it has one (workerd). */
|
|
116
|
+
function fixedLengthStream() {
|
|
117
|
+
return globalThis.FixedLengthStream;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* `body` as a stream of known length that the runtime takes, held to its declared length: a
|
|
121
|
+
* stream that carries more or fewer bytes errors whatever reads it. On workerd that is a
|
|
122
|
+
* `FixedLengthStream`, which a `fetch` sends with a `Content-Length` rather than chunked and
|
|
123
|
+
* which R2's `put` accepts (it refuses a stream of unknown length); the runtime enforces the
|
|
124
|
+
* length there, so a web stream is piped straight in. Elsewhere it is the stream passed through
|
|
125
|
+
* a relay that enforces the length.
|
|
126
|
+
*/
|
|
127
|
+
export function knownLengthStream(body) {
|
|
128
|
+
const Fixed = fixedLengthStream();
|
|
129
|
+
if (!Fixed)
|
|
130
|
+
return relay(body.stream, body.length);
|
|
131
|
+
assertDeclaredLength(body.length);
|
|
132
|
+
const piped = body.stream;
|
|
133
|
+
const source = typeof piped.pipeThrough === 'function' ? piped : relay(body.stream, body.length);
|
|
134
|
+
return source.pipeThrough(new Fixed(body.length));
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* A request init whose body is a sized stream, as the runtime's `fetch` takes it: the body
|
|
138
|
+
* as {@link knownLengthStream}, and off workerd the `Content-Length` header and `duplex: 'half'`
|
|
139
|
+
* a streamed request body needs there. `fetchLikeOf` sends through it, so a `FetchLike` does not
|
|
140
|
+
* call this itself: a runtime `fetch` becomes one by `fetchLikeOf`. A caller that holds a
|
|
141
|
+
* runtime `fetch` it does not make a `FetchLike` (the platform's vertical client) does.
|
|
142
|
+
*/
|
|
143
|
+
export function knownLengthInit(init) {
|
|
144
|
+
const length = init.body.length;
|
|
145
|
+
const onWorkerd = fixedLengthStream() !== undefined;
|
|
146
|
+
return {
|
|
147
|
+
...init,
|
|
148
|
+
body: knownLengthStream(init.body),
|
|
149
|
+
headers: { ...init.headers, ...(onWorkerd ? {} : { 'content-length': String(length) }) },
|
|
150
|
+
...(onWorkerd ? {} : { duplex: 'half' }),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=byte-stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"byte-stream.js","sourceRoot":"","sources":["../src/byte-stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,uCAAuC,EAAE,MAAM,yBAAyB,CAAC;AA6BlF;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAiB;IACnD,IAAI,KAAK,CAAC,UAAU,IAAI,uCAAuC;QAAE,OAAO,KAAK,CAAC;IAC9E,MAAM,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,MAAM,MAAM,GAAG,IAAI,cAAc,CAC/B;QACE,KAAK,CAAC,IAAI,CAAC,UAAU;YACnB,IAAI,EAAE,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;gBAC3B,UAAU,CAAC,KAAK,EAAE,CAAC;gBACnB,OAAO;YACT,CAAC;YACD,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAC/E,EAAE,IAAI,KAAK,CAAC;QACd,CAAC;QACD,KAAK,CAAC,MAAM,KAAI,CAAC;KAClB,EACD,EAAE,aAAa,EAAE,CAAC,EAAE,CACrB,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC;AAC9C,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,iBAAiB,CAAC,IAAa;IAC7C,OAAO,CACL,OAAO,IAAI,KAAK,QAAQ;QACxB,IAAI,KAAK,IAAI;QACb,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC;QACzB,OAAQ,IAA6C,CAAC,MAAM,EAAE,SAAS,KAAK,UAAU;QACtF,OAAQ,IAA6B,CAAC,MAAM,KAAK,QAAQ,CAC1D,CAAC;AACJ,CAAC;AAwCD,mDAAmD;AACnD,SAAS,oBAAoB,CAAC,MAAc;IAC1C,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,uEAAuE,MAAM,EAAE,CAAC,CAAC;IACnG,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,KAAK,CACZ,MAAkB,EAClB,MAAc,EACd,OAAqD,EACrD,KAAkC;IAElC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;IAClC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,OAAO,IAAI,cAAc,CACvB;QACE,KAAK,CAAC,IAAI,CAAC,UAAU;YACnB,IAAI,CAAC;gBACH,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;gBAC5C,IAAI,IAAI,EAAE,CAAC;oBACT,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;wBACpB,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,uBAAuB,MAAM,EAAE,CAAC,CAAC;oBACtF,CAAC;oBACD,MAAM,KAAK,EAAE,EAAE,CAAC;oBAChB,UAAU,CAAC,KAAK,EAAE,CAAC;oBACnB,OAAO;gBACT,CAAC;gBACD,mFAAmF;gBACnF,iFAAiF;gBACjF,IAAI,CAAC,KAAK;oBAAE,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;gBAC/F,IAAI,IAAI,KAAK,CAAC,UAAU,CAAC;gBACzB,IAAI,IAAI,GAAG,MAAM,EAAE,CAAC;oBAClB,MAAM,IAAI,KAAK,CAAC,yCAAyC,MAAM,oBAAoB,CAAC,CAAC;gBACvF,CAAC;gBACD,MAAM,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;gBACvB,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACtB,MAAM,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QACD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;KAC1C,EACD,EAAE,aAAa,EAAE,CAAC,EAAE,CACrB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,IAAqB,EAAE,MAAyB;IAC9E,IAAI,SAAoC,CAAC;IACzC,MAAM,MAAM,GAAG,KAAK,CAClB,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,MAAM,EACX,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAC/B,KAAK,IAAI,EAAE;QACT,SAAS,GAAG,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IAChE,CAAC,CACF,CAAC;IACF,OAAO;QACL,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE;QACrC,OAAO,EAAE,GAAG,EAAE;YACZ,IAAI,CAAC,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;YACzG,OAAO,SAAS,CAAC;QACnB,CAAC;KACF,CAAC;AACJ,CAAC;AAKD,yEAAyE;AACzE,SAAS,iBAAiB;IACxB,OAAQ,UAA4D,CAAC,iBAAiB,CAAC;AACzF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAqB;IACrD,MAAM,KAAK,GAAG,iBAAiB,EAAE,CAAC;IAClC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACnD,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAoE,CAAC;IACxF,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAA6B,CAAC;IAC9H,OAAO,MAAM,CAAC,WAAY,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AACrD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAU;IAEV,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IAChC,MAAM,SAAS,GAAG,iBAAiB,EAAE,KAAK,SAAS,CAAC;IACpD,OAAO;QACL,GAAG,IAAI;QACP,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;QAClC,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;QACxF,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAe,EAAE,CAAC;KAClD,CAAC;AACJ,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Connection, ConnectionLandingOptions, ManifestConnectionLandings, PlatformActorId, ScopeId, TenantId } from '@substrat-run/contracts';
|
|
2
|
-
import type { ScopeHost } from './scope-host.js';
|
|
1
|
+
import type { Connection, ConnectionLandingOptions, ManifestConnectionLandings, PlatformActorId, Scope, ScopeId, TenantId } from '@substrat-run/contracts';
|
|
2
|
+
import type { ScopeFilter, ScopeHost } from './scope-host.js';
|
|
3
3
|
/**
|
|
4
4
|
* Connection landings, applied (#2316): the connector pass's step that turns a vertical's declared
|
|
5
5
|
* `connections` into a held key and a binding for every live connection of that provider.
|
|
@@ -94,9 +94,21 @@ export declare class LandingPass {
|
|
|
94
94
|
private readonly actor;
|
|
95
95
|
private readonly input;
|
|
96
96
|
private readonly concurrency;
|
|
97
|
+
/**
|
|
98
|
+
* How the pass reads a tenant's scopes: the sweep's own reader, so a directory row that does
|
|
99
|
+
* not read as a scope is stepped over here too and named once with the pass's others, rather
|
|
100
|
+
* than failing every landing in its tenant.
|
|
101
|
+
*/
|
|
102
|
+
private readonly listScopes;
|
|
97
103
|
private readonly targets;
|
|
98
104
|
private readonly held;
|
|
99
|
-
constructor(host: ScopeHost, actor: PlatformActorId, input: ConnectionLandingOptionsInput, concurrency: number
|
|
105
|
+
constructor(host: ScopeHost, actor: PlatformActorId, input: ConnectionLandingOptionsInput, concurrency: number,
|
|
106
|
+
/**
|
|
107
|
+
* How the pass reads a tenant's scopes: the sweep's own reader, so a directory row that does
|
|
108
|
+
* not read as a scope is stepped over here too and named once with the pass's others, rather
|
|
109
|
+
* than failing every landing in its tenant.
|
|
110
|
+
*/
|
|
111
|
+
listScopes: (filter: ScopeFilter) => Promise<Scope[]>);
|
|
100
112
|
/** Grant and bind what `connection`'s installs declare for its provider, and say what happened. */
|
|
101
113
|
apply(connection: Connection): Promise<LandingOutcome>;
|
|
102
114
|
/** Every primary, active install of `vertical` in `tenantId`, with what its running version declares. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-landings.d.ts","sourceRoot":"","sources":["../src/connection-landings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,eAAe,
|
|
1
|
+
{"version":3,"file":"connection-landings.d.ts","sourceRoot":"","sources":["../src/connection-landings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,eAAe,EAEf,KAAK,EACL,OAAO,EACP,QAAQ,EACT,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAM9D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iGAAiG;IACjG,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC,CAAC;IAC9H,kGAAkG;IAClG,IAAI,CACF,IAAI,EAAE,SAAS,EACf,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClI,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB;;;;;OAKG;IACH,OAAO,CAAC,CACN,GAAG,EAAE,wBAAwB,GAAG,SAAS,EACzC,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GACnE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3B;;;;OAIG;IACH,KAAK,CAAC,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC;CAC9G;AAED,MAAM,WAAW,6BAA6B;IAC5C,0GAA0G;IAC1G,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;IACnF,wFAAwF;IACxF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC3C;AAED,6FAA6F;AAC7F,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,oEAAoE;IACpE,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,2FAA2F;IAC3F,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC9C;AASD;;;;GAIG;AACH,qBAAa,WAAW;IAKpB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,UAAU;IAb7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwC;IAChE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA0D;IAE/E,YACmB,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,6BAA6B,EACpC,WAAW,EAAE,MAAM;IACpC;;;;OAIG;IACc,UAAU,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC,EACpE;IAEJ,mGAAmG;IAC7F,KAAK,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC,CA2D3D;IAED,yGAAyG;IACzG,OAAO,CAAC,SAAS;IAwBjB,0EAA0E;IAC1E,OAAO,CAAC,QAAQ;CASjB"}
|
|
@@ -12,13 +12,21 @@ export class LandingPass {
|
|
|
12
12
|
actor;
|
|
13
13
|
input;
|
|
14
14
|
concurrency;
|
|
15
|
+
listScopes;
|
|
15
16
|
targets = new Map();
|
|
16
17
|
held = new Map();
|
|
17
|
-
constructor(host, actor, input, concurrency
|
|
18
|
+
constructor(host, actor, input, concurrency,
|
|
19
|
+
/**
|
|
20
|
+
* How the pass reads a tenant's scopes: the sweep's own reader, so a directory row that does
|
|
21
|
+
* not read as a scope is stepped over here too and named once with the pass's others, rather
|
|
22
|
+
* than failing every landing in its tenant.
|
|
23
|
+
*/
|
|
24
|
+
listScopes) {
|
|
18
25
|
this.host = host;
|
|
19
26
|
this.actor = actor;
|
|
20
27
|
this.input = input;
|
|
21
28
|
this.concurrency = concurrency;
|
|
29
|
+
this.listScopes = listScopes;
|
|
22
30
|
}
|
|
23
31
|
/** Grant and bind what `connection`'s installs declare for its provider, and say what happened. */
|
|
24
32
|
async apply(connection) {
|
|
@@ -92,7 +100,7 @@ export class LandingPass {
|
|
|
92
100
|
let found = this.targets.get(key);
|
|
93
101
|
if (!found) {
|
|
94
102
|
found = (async () => {
|
|
95
|
-
const scopes = (await this.
|
|
103
|
+
const scopes = (await this.listScopes({ tenantId })).filter((s) => s.vertical === vertical && s.status === 'active' && isPrimaryScope(s));
|
|
96
104
|
if (scopes.length === 0)
|
|
97
105
|
return [];
|
|
98
106
|
const running = await runningFactsOf(this.host.admin, this.actor, scopes, (slug, versionId) => this.input.read(slug, versionId), (reason) => ({ kind: 'unreadable', reason }), this.concurrency);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-landings.js","sourceRoot":"","sources":["../src/connection-landings.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAmFjC;;;;GAIG;AACH,MAAM,OAAO,WAAW;IAKH,IAAI;IACJ,KAAK;IACL,KAAK;IACL,WAAW;
|
|
1
|
+
{"version":3,"file":"connection-landings.js","sourceRoot":"","sources":["../src/connection-landings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ExtractionTimers } from './attachment-extractor.js';
|
|
2
|
+
import type { FetchLike } from './scope-host.js';
|
|
3
|
+
/**
|
|
4
|
+
* How long a streamed response body may go without a byte before it errors. 30 s, the default
|
|
5
|
+
* `timeoutMs` of a connector call: a provider that has been silent for as long as a whole call
|
|
6
|
+
* may take has stalled, and a slower link than that is still delivering within it. The window
|
|
7
|
+
* runs only while the stream waits on the provider: a consumer that is slow to take the next
|
|
8
|
+
* chunk (a store writing the last one) does not spend it.
|
|
9
|
+
*/
|
|
10
|
+
export declare const STREAM_IDLE_TIMEOUT_MS = 30000;
|
|
11
|
+
/**
|
|
12
|
+
* The most a streamed body may take from its first read to its end, however steadily it flows:
|
|
13
|
+
* 10 minutes. Finite because a hosted run lives under the platform's wall limits and a trickle
|
|
14
|
+
* that never stops would otherwise hold a connection (and a run) for ever; generous because the
|
|
15
|
+
* idle window, not this, is what cuts a stalled transfer. At the 10 minutes a steady 1 MB/s
|
|
16
|
+
* link still moves about 600 MB.
|
|
17
|
+
*/
|
|
18
|
+
export declare const STREAM_MAX_DURATION_MS: number;
|
|
19
|
+
export interface DeadlineOptions {
|
|
20
|
+
/** The idle window of a streamed body. Default {@link STREAM_IDLE_TIMEOUT_MS}. */
|
|
21
|
+
idleMs?: number;
|
|
22
|
+
/** The absolute cap on a streamed body's duration. Default {@link STREAM_MAX_DURATION_MS}. */
|
|
23
|
+
maxStreamMs?: number;
|
|
24
|
+
/** The timers every bound runs on: the runtime's by default, a test's on a clock it moves itself. */
|
|
25
|
+
timers?: ExtractionTimers;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* `fetchImpl`, with `timeoutMs` on the call and an idle window plus an absolute cap on a streamed
|
|
29
|
+
* body (see the module header). The signal it hands the runtime is its own; a `signal` in `init`
|
|
30
|
+
* aborts it, so wrapping a `fetch` that is itself wrapped (a connector's timeout around a host's)
|
|
31
|
+
* lets the outer bound reach the runtime.
|
|
32
|
+
*/
|
|
33
|
+
export declare function deadlineFetch(fetchImpl: FetchLike, timeoutMs: number, options?: DeadlineOptions): FetchLike;
|
|
34
|
+
//# sourceMappingURL=deadline-fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deadline-fetch.d.ts","sourceRoot":"","sources":["../src/deadline-fetch.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAqB,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEpE;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAE7C;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,QAAc,CAAC;AA4BlD,MAAM,WAAW,eAAe;IAC9B,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8FAA8F;IAC9F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qGAAqG;IACrG,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B;AAgBD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,SAAS,CAmF/G"}
|