@nimbus-sh/core 0.2.0 → 0.4.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 +112 -0
- package/dist/_shared/tarball-stream.d.ts +93 -0
- package/dist/_shared/tarball-stream.d.ts.map +1 -0
- package/dist/_shared/tarball-stream.js +235 -0
- package/dist/_shared/tarball.d.ts +17 -0
- package/dist/_shared/tarball.d.ts.map +1 -0
- package/dist/_shared/tarball.js +39 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/runtime/clang-runner.d.ts +38 -0
- package/dist/runtime/clang-runner.d.ts.map +1 -0
- package/dist/runtime/clang-runner.js +866 -0
- package/dist/runtime/facet-host.d.ts +12 -0
- package/dist/runtime/facet-host.d.ts.map +1 -1
- package/dist/runtime/local-facet-host.d.ts.map +1 -1
- package/dist/runtime/local-facet-host.js +29 -9
- package/dist/runtime/ruby-gems.d.ts +30 -0
- package/dist/runtime/ruby-gems.d.ts.map +1 -0
- package/dist/runtime/ruby-gems.js +636 -0
- package/dist/runtime/ruby-runner.d.ts +127 -0
- package/dist/runtime/ruby-runner.d.ts.map +1 -0
- package/dist/runtime/ruby-runner.js +1357 -0
- package/dist/runtime/runtime-package.d.ts +63 -0
- package/dist/runtime/runtime-package.d.ts.map +1 -0
- package/dist/runtime/runtime-package.js +66 -0
- package/dist/runtime/runtime-registry.d.ts +3 -2
- package/dist/runtime/runtime-registry.d.ts.map +1 -1
- package/dist/runtime/runtime-registry.js +1 -1
- package/dist/runtime/session-process-supervisor.d.ts +15 -0
- package/dist/runtime/session-process-supervisor.d.ts.map +1 -1
- package/dist/runtime/session-process-supervisor.js +30 -0
- package/dist/workspace/nimbus-workspace.d.ts +102 -22
- package/dist/workspace/nimbus-workspace.d.ts.map +1 -1
- package/dist/workspace/nimbus-workspace.js +197 -52
- package/package.json +4 -2
- package/src/_shared/tarball-stream.ts +263 -0
- package/src/_shared/tarball.ts +46 -0
- package/src/index.ts +7 -0
- package/src/runtime/clang-runner.ts +924 -0
- package/src/runtime/facet-host.ts +12 -0
- package/src/runtime/local-facet-host.ts +28 -8
- package/src/runtime/ruby-gems.ts +682 -0
- package/src/runtime/ruby-runner.ts +1484 -0
- package/src/runtime/runtime-package.ts +114 -0
- package/src/runtime/runtime-registry.ts +4 -3
- package/src/runtime/session-process-supervisor.ts +27 -0
- package/src/workspace/nimbus-workspace.ts +268 -63
|
@@ -79,6 +79,18 @@ export interface FacetSpec {
|
|
|
79
79
|
syscalls?: FacetSyscalls;
|
|
80
80
|
/** Facets the host may keep warm for this spec. Default 1. */
|
|
81
81
|
concurrency?: number;
|
|
82
|
+
/**
|
|
83
|
+
* Who a warm facet may be reused FOR. Default `session`.
|
|
84
|
+
*
|
|
85
|
+
* A scope keeps whatever the last call left in it, so by default it may only
|
|
86
|
+
* ever answer for the session that opened it. `global` is a claim the
|
|
87
|
+
* RUNTIME makes about itself and one only a pure function can make: no
|
|
88
|
+
* syscalls binding, nothing retained between calls, output decided entirely
|
|
89
|
+
* by the arguments. The clang toolchain is that — a compile is the same
|
|
90
|
+
* compile for every tenant — and one warm isolate holding its 31 MiB of
|
|
91
|
+
* compiled compiler serves all of them.
|
|
92
|
+
*/
|
|
93
|
+
reuse?: 'session' | 'global';
|
|
82
94
|
}
|
|
83
95
|
|
|
84
96
|
/** The session a facet's syscalls reach, and who they reach it as. */
|
|
@@ -113,12 +113,21 @@ export function localFacetHost(): FacetHost {
|
|
|
113
113
|
root: string,
|
|
114
114
|
options?: FacetFilesystemOptions,
|
|
115
115
|
): FacetFilesystemSeed | { error: string } {
|
|
116
|
-
|
|
116
|
+
const seeded = snapshotVfs(vfs, root, {
|
|
117
117
|
extraRoots: options?.extraRoots,
|
|
118
118
|
skipSubdirs: [],
|
|
119
119
|
maxBytes: LOCAL_SEED_MAX_BYTES,
|
|
120
120
|
maxFiles: LOCAL_SEED_MAX_FILES,
|
|
121
121
|
});
|
|
122
|
+
if ('error' in seeded) return seeded;
|
|
123
|
+
// The seed is also the WHOLE of what this guest has, which is a stronger
|
|
124
|
+
// claim than the walk's: `snapshotVfs` reports the roots it listed
|
|
125
|
+
// exhaustively, and this says every path outside them is absent too. It
|
|
126
|
+
// is — a miss out there could only be answered by suspending the guest
|
|
127
|
+
// mid-syscall, which this host cannot do, so the alternative to "absent"
|
|
128
|
+
// is not "fetched" but a read the guest can never receive. Ruby's VM
|
|
129
|
+
// startup stats dozens of prefixes it was never given.
|
|
130
|
+
return { ...seeded, snapshot: { ...seeded.snapshot, enumeratedRoots: [''] } };
|
|
122
131
|
},
|
|
123
132
|
open: (spec) => new LocalFacet(spec),
|
|
124
133
|
};
|
|
@@ -152,8 +161,7 @@ class LocalFacet implements Facet {
|
|
|
152
161
|
|
|
153
162
|
private async call<A, R>(fn: FacetFn<A, R>, args: A, options?: FacetSubmitOptions): Promise<R> {
|
|
154
163
|
if (this.disposed) throw new Error(`Nimbus: facet '${this.spec.tag}' is disposed`);
|
|
155
|
-
const scope = await this.scope();
|
|
156
|
-
await this.addModules(options?.wasmModules);
|
|
164
|
+
const scope = await this.scope(options?.wasmModules);
|
|
157
165
|
let scoped = this.scoped.get(fn as FacetFn<never, unknown>);
|
|
158
166
|
if (!scoped) {
|
|
159
167
|
const value = scope(`(${fn.toString()})`);
|
|
@@ -172,17 +180,29 @@ class LocalFacet implements Facet {
|
|
|
172
180
|
* The returned closure's `eval` is a DIRECT eval inside the body the preamble
|
|
173
181
|
* was evaluated in, which is what puts the preamble's top-level declarations
|
|
174
182
|
* in scope for every function submitted afterwards.
|
|
183
|
+
*
|
|
184
|
+
* Both wasm tables are filled BEFORE that body runs, per-call images merged
|
|
185
|
+
* over the spec's. A preamble may boot its runtime as it is evaluated — Ruby
|
|
186
|
+
* instantiates the interpreter right there — so it reads the table at that
|
|
187
|
+
* moment and an image added afterwards would arrive to a facet that had
|
|
188
|
+
* already given up on it. workerd has the same ordering for the same reason:
|
|
189
|
+
* per-call images ride in the module map the inner worker is built from.
|
|
175
190
|
*/
|
|
176
|
-
private async scope(
|
|
177
|
-
|
|
178
|
-
|
|
191
|
+
private async scope(
|
|
192
|
+
callModules: Record<string, ArrayBuffer> | undefined,
|
|
193
|
+
): Promise<(source: string) => unknown> {
|
|
194
|
+
const built = this.evaluate;
|
|
195
|
+
if (!built) await this.addModules(this.spec.wasmModules);
|
|
196
|
+
await this.addModules(callModules);
|
|
197
|
+
if (built) return built;
|
|
179
198
|
const globals = { __NIMBUS_WASM: this.wasmTable };
|
|
180
199
|
const build = new AsyncFunction(
|
|
181
200
|
'globalThis',
|
|
182
201
|
`${this.spec.preamble ?? ''}\nreturn (source) => eval(source);`,
|
|
183
202
|
);
|
|
184
|
-
|
|
185
|
-
|
|
203
|
+
const evaluate = await build.call(globals, globals) as (source: string) => unknown;
|
|
204
|
+
this.evaluate = evaluate;
|
|
205
|
+
return evaluate;
|
|
186
206
|
}
|
|
187
207
|
|
|
188
208
|
private async addModules(modules: Record<string, ArrayBuffer> | undefined): Promise<void> {
|