@nimbus-sh/fabric 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 +21 -0
- package/README.md +487 -0
- package/dist/alarms.d.ts +134 -0
- package/dist/alarms.d.ts.map +1 -0
- package/dist/alarms.js +214 -0
- package/dist/bindings.d.ts +316 -0
- package/dist/bindings.d.ts.map +1 -0
- package/dist/bindings.js +678 -0
- package/dist/ctx-exports.d.ts +47 -0
- package/dist/ctx-exports.d.ts.map +1 -0
- package/dist/ctx-exports.js +54 -0
- package/dist/facet-image-store.d.ts +112 -0
- package/dist/facet-image-store.d.ts.map +1 -0
- package/dist/facet-image-store.js +181 -0
- package/dist/fanout-pool.d.ts +223 -0
- package/dist/fanout-pool.d.ts.map +1 -0
- package/dist/fanout-pool.js +368 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/inner-do-registry.d.ts +41 -0
- package/dist/inner-do-registry.d.ts.map +1 -0
- package/dist/inner-do-registry.js +51 -0
- package/dist/launch-journal.d.ts +170 -0
- package/dist/launch-journal.d.ts.map +1 -0
- package/dist/launch-journal.js +154 -0
- package/dist/launch-pacer.d.ts +173 -0
- package/dist/launch-pacer.d.ts.map +1 -0
- package/dist/launch-pacer.js +193 -0
- package/dist/loader-ledger.d.ts +57 -0
- package/dist/loader-ledger.d.ts.map +1 -0
- package/dist/loader-ledger.js +91 -0
- package/dist/loader-pool.d.ts +315 -0
- package/dist/loader-pool.d.ts.map +1 -0
- package/dist/loader-pool.js +666 -0
- package/dist/process-fabric.d.ts +524 -0
- package/dist/process-fabric.d.ts.map +1 -0
- package/dist/process-fabric.js +388 -0
- package/dist/process-host.d.ts +132 -0
- package/dist/process-host.d.ts.map +1 -0
- package/dist/process-host.js +444 -0
- package/dist/vendor/errors.d.ts +24 -0
- package/dist/vendor/errors.d.ts.map +1 -0
- package/dist/vendor/errors.js +46 -0
- package/dist/vendor/serialize.d.ts +3 -0
- package/dist/vendor/serialize.d.ts.map +1 -0
- package/dist/vendor/serialize.js +25 -0
- package/dist/vendor/types.d.ts +69 -0
- package/dist/vendor/types.d.ts.map +1 -0
- package/dist/vendor/types.js +4 -0
- package/dist/workerd-facet-host.d.ts +207 -0
- package/dist/workerd-facet-host.d.ts.map +1 -0
- package/dist/workerd-facet-host.js +508 -0
- package/dist/ws-hibernation-config.d.ts +73 -0
- package/dist/ws-hibernation-config.d.ts.map +1 -0
- package/dist/ws-hibernation-config.js +93 -0
- package/package.json +62 -0
- package/src/alarms.ts +275 -0
- package/src/bindings.ts +871 -0
- package/src/ctx-exports.ts +77 -0
- package/src/facet-image-store.ts +196 -0
- package/src/fanout-pool.ts +503 -0
- package/src/index.ts +26 -0
- package/src/inner-do-registry.ts +58 -0
- package/src/launch-journal.ts +229 -0
- package/src/launch-pacer.ts +231 -0
- package/src/loader-ledger.ts +112 -0
- package/src/loader-pool.ts +984 -0
- package/src/process-fabric.ts +729 -0
- package/src/process-host.ts +566 -0
- package/src/vendor/errors.ts +56 -0
- package/src/vendor/serialize.ts +37 -0
- package/src/vendor/types.ts +75 -0
- package/src/workerd-facet-host.ts +694 -0
- package/src/ws-hibernation-config.ts +123 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* workerd-facet-host.ts — how a resident process is actually made, on workerd.
|
|
3
|
+
*
|
|
4
|
+
* `process-fabric.ts` says what a resident process IS, in terms no
|
|
5
|
+
* runtime owns: a boot spec, a start contract, a handle that can be routed to
|
|
6
|
+
* and released. This module is the one implementation of that on Cloudflare,
|
|
7
|
+
* and everything here is a workerd mechanism rather than a Nimbus concept —
|
|
8
|
+
* `ctx.facets`, the Worker Loader, `ctx.exports`, and the facet-index
|
|
9
|
+
* arithmetic the slot book exists to satisfy.
|
|
10
|
+
*
|
|
11
|
+
* The split is what lets the contract be read without the platform: a host
|
|
12
|
+
* that is not a Durable Object implements `ProcessHost` against the same
|
|
13
|
+
* `HostedProcess` and never imports this file.
|
|
14
|
+
*/
|
|
15
|
+
import { type HostedProcess, type OneShotParams, type ProcessHostParams, type ResidentDiskReader, type ResidentSupervisorProps } from './process-fabric.js';
|
|
16
|
+
/** Structural surface of a NimbusLoadedEntrypoint RPC stub. */
|
|
17
|
+
export interface LoadedWorkerEntrypointStub {
|
|
18
|
+
handleHttpRequest?: (request: Request) => Promise<Response>;
|
|
19
|
+
fetch?(request: Request): Promise<Response>;
|
|
20
|
+
}
|
|
21
|
+
export interface NimbusCtxExports {
|
|
22
|
+
NimbusLoadedEntrypoint?: (options: {
|
|
23
|
+
props: {
|
|
24
|
+
key: string;
|
|
25
|
+
name: string | null;
|
|
26
|
+
depth: number;
|
|
27
|
+
supervisor: {
|
|
28
|
+
doId: string;
|
|
29
|
+
pid: number;
|
|
30
|
+
writerId: string;
|
|
31
|
+
};
|
|
32
|
+
stage?: unknown;
|
|
33
|
+
};
|
|
34
|
+
}) => LoadedWorkerEntrypointStub;
|
|
35
|
+
}
|
|
36
|
+
export declare function getNimbusCtxExports(): NimbusCtxExports;
|
|
37
|
+
/**
|
|
38
|
+
* Mint a NimbusLoadedEntrypoint stub for a keyed dynamic worker. Used by the
|
|
39
|
+
* one-shot runtime paths, which run a program to completion inside a single
|
|
40
|
+
* request rather than leaving it resident: their module map is assembled in
|
|
41
|
+
* that stateless entrypoint's own isolate, never in a session DO.
|
|
42
|
+
*/
|
|
43
|
+
export declare function createLoadedWorkerEntrypoint(ctxExports: NimbusCtxExports, supervisor: {
|
|
44
|
+
doId: string;
|
|
45
|
+
pid: number;
|
|
46
|
+
writerId: string;
|
|
47
|
+
}, stage: unknown, name?: string | null): Promise<LoadedWorkerEntrypointStub>;
|
|
48
|
+
/**
|
|
49
|
+
* Total bytes a dynamic Worker's module map may carry, across every member of
|
|
50
|
+
* it. A hard platform limit, not a policy knob: 62 MiB lands and 64 MiB is
|
|
51
|
+
* refused with "Dynamic Worker code size (N bytes) exceeds the maximum allowed
|
|
52
|
+
* size of 67108864 bytes", confirmed at five sizes with two trials each. The
|
|
53
|
+
* budget is shared, so a ruby process is already 34.3 MiB down before its disk
|
|
54
|
+
* is counted.
|
|
55
|
+
*/
|
|
56
|
+
export declare const DYNAMIC_WORKER_CODE_LIMIT_BYTES = 67108864;
|
|
57
|
+
/**
|
|
58
|
+
* Refuse a module map over {@link DYNAMIC_WORKER_CODE_LIMIT_BYTES}, naming
|
|
59
|
+
* the largest members. The platform's own refusal reports one number for a
|
|
60
|
+
* budget shared across every member of the map, which tells the operator
|
|
61
|
+
* nothing about WHAT to shrink — so every fabric seam that assembles a map
|
|
62
|
+
* runs this before the loader sees it.
|
|
63
|
+
*
|
|
64
|
+
* Costed to its two paths. Under the ceiling: one length read per member —
|
|
65
|
+
* UTF-16 code units for text, which equal UTF-8 bytes for the ASCII module
|
|
66
|
+
* text the generators emit and undercount otherwise; the platform's own
|
|
67
|
+
* refusal still backstops the exotic case, because this check exists to name
|
|
68
|
+
* members, not to be the ceiling. Over it: exact UTF-8 sizes, computed only
|
|
69
|
+
* then, sorted so the biggest lever is first.
|
|
70
|
+
*/
|
|
71
|
+
export declare function assertModuleMapWithinCodeLimit(modules: Record<string, unknown>): void;
|
|
72
|
+
/** What an unkeyed `LOADER.load` hands back. */
|
|
73
|
+
interface LoadedWorkerStub {
|
|
74
|
+
getEntrypoint(): LoadedWorkerEntrypointStub;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* `env.LOADER` — the Worker Loader binding, as used from inside a DO.
|
|
78
|
+
*
|
|
79
|
+
* Both arms are here because both are the same platform affordance seen from
|
|
80
|
+
* the two lifetimes Nimbus runs programs under: `get` is keyed and yields a
|
|
81
|
+
* Durable Object class, so a resident process can be re-entered; `load` is
|
|
82
|
+
* unkeyed and yields a stateless entrypoint, which is all a program that ends
|
|
83
|
+
* with its call can ever need.
|
|
84
|
+
*/
|
|
85
|
+
interface WorkerLoaderBinding {
|
|
86
|
+
get(id: string, code: () => Promise<unknown>): {
|
|
87
|
+
getDurableObjectClass(name: string): unknown;
|
|
88
|
+
};
|
|
89
|
+
load(code: unknown): LoadedWorkerStub;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* The bindings `openResidentFacet` needs off whichever DO is hosting. A
|
|
93
|
+
* staged boot's assembler may read more off the same env (Nimbus's reads
|
|
94
|
+
* ASSETS); the env travels to it whole, so nothing further is named here.
|
|
95
|
+
*/
|
|
96
|
+
export interface ResidentFacetEnv {
|
|
97
|
+
LOADER?: WorkerLoaderBinding;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Fork one facet's entire SQLite into another by copy-on-write — the one way
|
|
101
|
+
* the fabric calls `ctx.facets.clone`, because the raw call carries a hazard
|
|
102
|
+
* measured on production workerd: ANY `src` that does not resolve to a
|
|
103
|
+
* populated facet — a typo, a name not created yet, not merely the obvious
|
|
104
|
+
* `''`/`'.'`/`'/'` — silently EMPTIES the destination and reports success. A
|
|
105
|
+
* blocklist of bad names would pass a typo straight through and wipe a
|
|
106
|
+
* process's filesystem while returning ok, so validation is positive on both
|
|
107
|
+
* ends: the source must answer as populated before the clone runs, the
|
|
108
|
+
* destination must answer as populated after it, and anything else fails
|
|
109
|
+
* loud.
|
|
110
|
+
*
|
|
111
|
+
* `populated` is the caller's probe because populated-ness is the caller's
|
|
112
|
+
* schema. The hosting actor cannot read a facet's SQLite from outside it, and
|
|
113
|
+
* an EMPTIED facet still reports a 4,096-byte database — one page, the empty
|
|
114
|
+
* file — so only a check that positively finds the caller's own data means
|
|
115
|
+
* anything. The post-clone probe is not redundant with the pre-clone one: the
|
|
116
|
+
* probe answers off the caller's accounting, and the capture races un-awaited
|
|
117
|
+
* writes to the source, so the destination is verified rather than inferred.
|
|
118
|
+
*
|
|
119
|
+
* The primitive itself, measured: a reflink, 18–31 ms for a 45.73 MB corpus
|
|
120
|
+
* and 34–54 ms for 1 GB — flat, because nothing is copied — with the data
|
|
121
|
+
* visible from the destination's constructor. Same-Durable-Object only.
|
|
122
|
+
* Quiesce and await writes to the source first; the destination name consumes
|
|
123
|
+
* a facet ID on first use like any other facet name; and the shared ~10 GiB
|
|
124
|
+
* storage budget grants no copy-on-write credit — crossing it resets the
|
|
125
|
+
* object rather than raising an error.
|
|
126
|
+
*/
|
|
127
|
+
export declare function cloneFacetStorage(ctx: DurableObjectState, clone: {
|
|
128
|
+
src: string;
|
|
129
|
+
dst: string;
|
|
130
|
+
populated(name: string): boolean | Promise<boolean>;
|
|
131
|
+
}): Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* The facet name for a slot. Reused, and that is the entire point.
|
|
134
|
+
*
|
|
135
|
+
* A Durable Object admits 65,536 facets over its LIFETIME: the IDs are
|
|
136
|
+
* append-only and are never reclaimed, so the bound is on facets ever CREATED,
|
|
137
|
+
* not facets alive at once. Naming a facet after its pid, when pids never
|
|
138
|
+
* repeat, therefore burned one of those IDs on every spawn — a long-lived
|
|
139
|
+
* session would eventually exhaust its facet index with no way back, and the
|
|
140
|
+
* failure is unrecoverable rather than merely slow.
|
|
141
|
+
*
|
|
142
|
+
* Reusing a NAME costs no new ID. So the name comes from a free list and the
|
|
143
|
+
* pid stays what it always was: the process identity in the ProcessTable. The
|
|
144
|
+
* two were only ever conflated because one of them happened to be handy.
|
|
145
|
+
*/
|
|
146
|
+
export declare function residentFacetName(slot: number): string;
|
|
147
|
+
/**
|
|
148
|
+
* Facet IDs a Durable Object is granted over its LIFETIME. Append-only and
|
|
149
|
+
* never reclaimed, so crossing it is unrecoverable for the object — which is
|
|
150
|
+
* why the ledger below counts consumption durably instead of leaving the
|
|
151
|
+
* bound as prose the slot book merely respects.
|
|
152
|
+
*/
|
|
153
|
+
export declare const FACET_ID_LIFETIME_BUDGET = 65536;
|
|
154
|
+
/** Where the ledger persists the count of facet names ever minted. */
|
|
155
|
+
export declare const FACET_NAME_HIGH_WATER_KEY = "fabric_facet_name_high_water";
|
|
156
|
+
/**
|
|
157
|
+
* The lifetime facet-ID ledger: how many facet names this fabric has ever
|
|
158
|
+
* minted on the Durable Object, against the 65,536 the platform will ever
|
|
159
|
+
* grant it. `consumed` only ever counts FIRST uses — a reused name, in this
|
|
160
|
+
* incarnation or any earlier one, cost no new ID, which is the slot book's
|
|
161
|
+
* whole reason to exist. Surfaced so an operator can see proximity to a wall
|
|
162
|
+
* whose crossing is unrecoverable, instead of discovering it from the
|
|
163
|
+
* platform's opaque failure.
|
|
164
|
+
*/
|
|
165
|
+
export declare function facetIdBudget(ctx: DurableObjectState): Promise<{
|
|
166
|
+
consumed: number;
|
|
167
|
+
budget: number;
|
|
168
|
+
}>;
|
|
169
|
+
/**
|
|
170
|
+
* What `openResidentFacet` hands back: a running process, minus its placement.
|
|
171
|
+
*
|
|
172
|
+
* `slot` rides along because the caller's `describe` needs the facet's real
|
|
173
|
+
* name and the slot is not derivable from the pid — that indirection is the
|
|
174
|
+
* whole point of the free list. Reading it back out of the book later would
|
|
175
|
+
* also race the release that empties it.
|
|
176
|
+
*/
|
|
177
|
+
export type ResidentFacet = Omit<HostedProcess, 'describe'> & {
|
|
178
|
+
slot: number;
|
|
179
|
+
};
|
|
180
|
+
/**
|
|
181
|
+
* Open a resident process as a facet of the actor whose `ctx` and `env` are
|
|
182
|
+
* given, and start its runner.
|
|
183
|
+
*
|
|
184
|
+
* This is the ONE way a resident process comes into existence, and every
|
|
185
|
+
* substrate goes through it: the facet host calls it with the coordinator's
|
|
186
|
+
* own `ctx`, the peer host calls it — over one RPC — with a sibling session
|
|
187
|
+
* DO's. Everything a substrate could plausibly want to special-case is a
|
|
188
|
+
* PARAMETER here rather than a branch: which actor hosts the child, and how
|
|
189
|
+
* the boot spec's by-path members are read.
|
|
190
|
+
*/
|
|
191
|
+
export declare function openResidentFacet(ctx: DurableObjectState, env: ResidentFacetEnv, disk: () => ResidentDiskReader, supervisor: ResidentSupervisorProps, params: ProcessHostParams): ResidentFacet;
|
|
192
|
+
/**
|
|
193
|
+
* Run one program to completion as an UNKEYED dynamic worker.
|
|
194
|
+
*
|
|
195
|
+
* Unkeyed is the whole difference from `openResidentFacet`: nothing can
|
|
196
|
+
* re-resolve this worker into a later request's context, so it can never be a
|
|
197
|
+
* routeable target and never has to be released by name. It exists for the
|
|
198
|
+
* duration of one call and its stubs are dropped as that call unwinds.
|
|
199
|
+
*
|
|
200
|
+
* Shared by both substrates on purpose. `peer` places processes that have a
|
|
201
|
+
* residency to place; a one-shot has none, and shipping its fully-inline map
|
|
202
|
+
* across a sibling hop would meet the 32 MiB RPC ceiling that by-path boot
|
|
203
|
+
* specs exist to avoid — for a run that gains nothing by moving.
|
|
204
|
+
*/
|
|
205
|
+
export declare function runOneShotWorker<T>(ctx: DurableObjectState, env: ResidentFacetEnv, supervisor: ResidentSupervisorProps, params: OneShotParams, consume: (response: Response) => Promise<T>): Promise<T>;
|
|
206
|
+
export {};
|
|
207
|
+
//# sourceMappingURL=workerd-facet-host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workerd-facet-host.d.ts","sourceRoot":"","sources":["../src/workerd-facet-host.ts"],"names":[],"mappings":"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"}
|