@sproutboat/runtime 0.17.0 → 0.17.1
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/CHANGELOG.md +6 -0
- package/package.json +1 -1
- package/src/native-fetch-prelude.js +5 -5
- package/test/native-waituntil.ts +17 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @sproutboat/runtime
|
|
2
2
|
|
|
3
|
+
## 0.17.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 3dabc97: Scheduled, queue and Durable Object alarm triggers answer `204` with no body again. The prelude built that reply as `new Response("", { status: 204 })`, which the Fetch-spec `Response` of 0.17.0 rejects (an empty string is still a body), so the first cron or alarm failed, and on the alarm path the error took the server down.
|
|
8
|
+
|
|
3
9
|
## 0.17.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/package.json
CHANGED
|
@@ -5080,7 +5080,7 @@ async function __sb204WithDrain(res, tasks) {
|
|
|
5080
5080
|
__sbLogUncaught("scheduled/alarm", error);
|
|
5081
5081
|
}
|
|
5082
5082
|
await __sbDrainWaitUntil(tasks);
|
|
5083
|
-
return new Response(
|
|
5083
|
+
return new Response(null, { status: 204 });
|
|
5084
5084
|
}
|
|
5085
5085
|
|
|
5086
5086
|
async function __sbQueueWithDrain(result, tasks) {
|
|
@@ -5179,10 +5179,10 @@ globalThis.__sbEntry = function (handlers, request) {
|
|
|
5179
5179
|
} catch (error) {
|
|
5180
5180
|
// #179 — same rule as fetch: don't let a throw here crash the process.
|
|
5181
5181
|
__sbLogUncaught("scheduled", error);
|
|
5182
|
-
return new Response(
|
|
5182
|
+
return new Response(null, { status: 204 });
|
|
5183
5183
|
}
|
|
5184
5184
|
if (__sbTasks.length || (__sres && __sbIsFn(__sres.then))) return __sb204WithDrain(__sres, __sbTasks);
|
|
5185
|
-
return new Response(
|
|
5185
|
+
return new Response(null, { status: 204 });
|
|
5186
5186
|
}
|
|
5187
5187
|
|
|
5188
5188
|
if (trigger === "queue") {
|
|
@@ -5214,12 +5214,12 @@ globalThis.__sbEntry = function (handlers, request) {
|
|
|
5214
5214
|
} catch (error) {
|
|
5215
5215
|
// #179 — same rule as fetch: don't let a throw here crash the process.
|
|
5216
5216
|
__sbLogUncaught("alarm", error);
|
|
5217
|
-
return new Response(
|
|
5217
|
+
return new Response(null, { status: 204 });
|
|
5218
5218
|
}
|
|
5219
5219
|
// Was fire-and-forget before: an async `alarm()` and any `state.waitUntil()`
|
|
5220
5220
|
// it queued were both dropped the moment 204 went out. Await both.
|
|
5221
5221
|
if (inst.__sbTasks.length || (__ares && __sbIsFn(__ares.then))) return __sb204WithDrain(__ares, inst.__sbTasks);
|
|
5222
|
-
return new Response(
|
|
5222
|
+
return new Response(null, { status: 204 });
|
|
5223
5223
|
}
|
|
5224
5224
|
|
|
5225
5225
|
return new Response("unknown trigger", { status: 400 });
|
package/test/native-waituntil.ts
CHANGED
|
@@ -15,7 +15,11 @@ const handler = `export default {async fetch(request, env, ctx) {
|
|
|
15
15
|
return new Response("scheduled");
|
|
16
16
|
}
|
|
17
17
|
if (path === "/state") return new Response(String(globalThis.__done));
|
|
18
|
+
if (path === "/cron") return new Response(String(globalThis.__cron));
|
|
18
19
|
return new Response("ok");
|
|
20
|
+
},
|
|
21
|
+
async scheduled(event, env, ctx) {
|
|
22
|
+
ctx.waitUntil(new Promise((resolve) => setTimeout(() => { globalThis.__cron = event.cron; resolve(); }, 50)));
|
|
19
23
|
}};`;
|
|
20
24
|
|
|
21
25
|
function freePort(): number {
|
|
@@ -59,7 +63,7 @@ try {
|
|
|
59
63
|
const port = freePort();
|
|
60
64
|
server = Bun.spawn([binary], {
|
|
61
65
|
cwd: workdir,
|
|
62
|
-
env: { ...process.env, PORT: String(port) },
|
|
66
|
+
env: { ...process.env, PORT: String(port), SB_BROKER_TOKEN: "native-test-token" },
|
|
63
67
|
stdout: "ignore",
|
|
64
68
|
stderr: "inherit",
|
|
65
69
|
});
|
|
@@ -82,7 +86,18 @@ try {
|
|
|
82
86
|
assert.equal(await (await fetch(`http://127.0.0.1:${port}/state`)).text(), "pending");
|
|
83
87
|
await Bun.sleep(700);
|
|
84
88
|
assert.equal(await (await fetch(`http://127.0.0.1:${port}/state`)).text(), "done");
|
|
85
|
-
|
|
89
|
+
// A trigger answers 204 with no body. new Response("", { status: 204 }) throws under the
|
|
90
|
+
// Fetch-spec Response, and the prelude used it: the first cron or alarm took the server down.
|
|
91
|
+
const cron = await fetch(`http://127.0.0.1:${port}/`, {
|
|
92
|
+
method: "POST",
|
|
93
|
+
headers: { "x-sb-trigger": "scheduled", "x-sb-token": "native-test-token", "content-type": "application/json" },
|
|
94
|
+
body: JSON.stringify({ cron: "*/5 * * * *", scheduledTime: Date.now() }),
|
|
95
|
+
});
|
|
96
|
+
assert.equal(cron.status, 204);
|
|
97
|
+
assert.equal(await cron.text(), "");
|
|
98
|
+
assert.equal(await (await fetch(`http://127.0.0.1:${port}/cron`)).text(), "*/5 * * * *");
|
|
99
|
+
assert.equal(server.exitCode, null, "the server exited after a scheduled trigger");
|
|
100
|
+
console.log(`Native waitUntil runs after the response (${Math.round(elapsed)} ms) and completes; scheduled() answers 204`);
|
|
86
101
|
} finally {
|
|
87
102
|
if (server) {
|
|
88
103
|
server.kill(9);
|