@frockbot/applet-sdk 0.7.88 → 0.7.89
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/package.json +1 -1
- package/src/build/boot.ts +37 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frockbot/applet-sdk",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.89",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Authoring SDK for FrockBot Applets: schema-first Durable Object server, TanStack DB client, component kit, linter, and the build pipeline.",
|
package/src/build/boot.ts
CHANGED
|
@@ -1,20 +1,41 @@
|
|
|
1
1
|
// A workerd boot, bounded.
|
|
2
2
|
//
|
|
3
3
|
// Each build spawns its own workerd through Miniflare, and a spawn
|
|
4
|
-
// occasionally never
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
4
|
+
// occasionally never comes up (a bun+workerd spawn race, roughly one boot in
|
|
5
|
+
// fifty): it either never reports ready, or it fails outright and leaves the
|
|
6
|
+
// runtime's stdio socket with nothing to connect to. A build that awaited
|
|
7
|
+
// `ready` unbounded would hang to the test's timeout, or hang the build
|
|
8
|
+
// container's request. So a boot is given a deadline, a boot that misses it
|
|
9
|
+
// is let go of rather than waited on, both shapes are named
|
|
10
|
+
// `RuntimeDidNotStart`, and the caller tries once more before answering with
|
|
11
|
+
// that as its diagnostic.
|
|
10
12
|
|
|
11
13
|
/** How long a workerd boot is given before the build gives up on it. */
|
|
12
14
|
export const BOOT_DEADLINE_MS = 30_000;
|
|
13
15
|
|
|
14
|
-
/** A workerd that never
|
|
16
|
+
/** A workerd that never came up; the boot, not the code, failed. */
|
|
15
17
|
export class RuntimeDidNotStart extends Error {}
|
|
16
18
|
|
|
17
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* The same race seen from the other side: the spawn fails outright rather
|
|
21
|
+
* than hanging, and the runtime's stdio socket is never there to connect to.
|
|
22
|
+
* That is a boot that did not happen, not a fault in the code being built.
|
|
23
|
+
*/
|
|
24
|
+
function spawnFailed(error: unknown): boolean {
|
|
25
|
+
const { code, syscall } = (error ?? {}) as {
|
|
26
|
+
code?: unknown;
|
|
27
|
+
syscall?: unknown;
|
|
28
|
+
};
|
|
29
|
+
return (
|
|
30
|
+
(syscall === "connect" || syscall === "spawn") &&
|
|
31
|
+
(code === "ENOENT" || code === "ECONNREFUSED" || code === "EAGAIN")
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* `ready`, or a `RuntimeDidNotStart` when the runtime never came up — either
|
|
37
|
+
* because `ready` did not settle in time or because the spawn failed.
|
|
38
|
+
*/
|
|
18
39
|
export async function bootedWithin<T>(ready: Promise<T>): Promise<T> {
|
|
19
40
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
20
41
|
const deadline = new Promise<never>((_, reject) => {
|
|
@@ -30,6 +51,14 @@ export async function bootedWithin<T>(ready: Promise<T>): Promise<T> {
|
|
|
30
51
|
});
|
|
31
52
|
try {
|
|
32
53
|
return await Promise.race([ready, deadline]);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
if (!spawnFailed(error)) throw error;
|
|
56
|
+
throw new RuntimeDidNotStart(
|
|
57
|
+
`The Workers runtime could not be spawned: ${
|
|
58
|
+
error instanceof Error ? error.message : String(error)
|
|
59
|
+
}`,
|
|
60
|
+
{ cause: error },
|
|
61
|
+
);
|
|
33
62
|
} finally {
|
|
34
63
|
clearTimeout(timer);
|
|
35
64
|
}
|