sproutboat 0.11.4 → 0.11.6
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 +40 -2
- package/SURFACE.md +1 -1
- package/package.json +8 -8
- package/src/types-gen.ts +1 -1
- package/types/sproutboat.d.ts +40 -7
package/CHANGELOG.md
CHANGED
|
@@ -8,7 +8,44 @@ a breaking change.
|
|
|
8
8
|
Reconstructed from git history on 2026-09-03 for everything through v0.4.11;
|
|
9
9
|
maintained going forward by the `release` skill.
|
|
10
10
|
|
|
11
|
-
## [
|
|
11
|
+
## [0.11.6] - 2026-09-15
|
|
12
|
+
### Fixed
|
|
13
|
+
- The 100% CPU livelock on a `fetch` handler that resolves a promise with a
|
|
14
|
+
plain object (baronunread/sproutboat#168). Root cause was
|
|
15
|
+
`__Porffor_promise_resolve`'s `.then` duck-type probe spinning forever on a
|
|
16
|
+
prototype-chain fixed point instead of terminating; patched in
|
|
17
|
+
`@sproutboat/toolchain` alongside the other local Porffor patches. Bumped
|
|
18
|
+
`@sproutboat/toolchain` to `^0.4.1` to pick it up.
|
|
19
|
+
- `new Response(r2Object.body)` corrupted any binary R2 object (each byte
|
|
20
|
+
0x80-0xFF doubled on the wire): the runtime couldn't tell opaque bytes
|
|
21
|
+
apart from a Latin-1-range string, so it UTF-8-encoded them a second time
|
|
22
|
+
(baronunread/sproutboat#177). Added `R2Object.toResponse(init?)`, which
|
|
23
|
+
serves the bytes unmodified. Bumped `@sproutboat/runtime` to `^0.7.1` and
|
|
24
|
+
`@sproutboat/wire` to `^0.6.0` to pick this up, along with the R2
|
|
25
|
+
file-backed storage rework (baronunread/sproutboat#56) both depend on.
|
|
26
|
+
- `sproutboat-env.d.ts`'s generated secret comment named the wrong command
|
|
27
|
+
(`secrets set`; the real one is `secrets put`), `SproutboatHandler` claimed
|
|
28
|
+
there is no `ctx`/`ctx.waitUntil` (shipped since #57/#171), and
|
|
29
|
+
`docs/standalone.md` still said a missing secret refuses the boot (0.11.1
|
|
30
|
+
changed that to throwing on first use instead).
|
|
31
|
+
|
|
32
|
+
## [0.11.5] - 2026-09-14
|
|
33
|
+
### Fixed
|
|
34
|
+
- Bumped `@sproutboat/runtime` to `^0.6.6`. `__sbEntry` called `handlers.fetch()`
|
|
35
|
+
(and the `scheduled`/`queue`/`alarm` trigger paths) with no try/catch at all:
|
|
36
|
+
any synchronous throw, or a rejected async handler promise, propagated all
|
|
37
|
+
the way up and crashed the whole process: not just the request that hit
|
|
38
|
+
it, but every other in-flight and future request on that sprout, until
|
|
39
|
+
whatever supervises it restarted the binary (baronunread/sproutboat#179). A
|
|
40
|
+
throwing/rejecting `fetch()` now returns a 500 instead. `scheduled()`/
|
|
41
|
+
`alarm()` still reply `204` either way (no failure signal existed before
|
|
42
|
+
this either); a throwing `queue()` falls through to the existing
|
|
43
|
+
default-ack pass, same as a handler that never calls `ack()`/`retry()` on
|
|
44
|
+
every message.
|
|
45
|
+
- Upgrading the CLI is the only way to pick this up. The runtime prelude is
|
|
46
|
+
embedded in the CLI binary when that binary is built, so a project's own
|
|
47
|
+
`@sproutboat/runtime` dependency has no effect on `--standalone` or
|
|
48
|
+
`--target host` builds.
|
|
12
49
|
|
|
13
50
|
## [0.11.4] - 2026-09-14
|
|
14
51
|
### Fixed
|
|
@@ -507,7 +544,8 @@ its own package.
|
|
|
507
544
|
- Renamed the package to `sproutboat` (was `@sproutboat/cli`); dropped the
|
|
508
545
|
`sprout` bin alias in favour of a user-defined shell alias.
|
|
509
546
|
|
|
510
|
-
[Unreleased]: https://github.com/baronunread/sproutboat-cli/compare/v0.11.
|
|
547
|
+
[Unreleased]: https://github.com/baronunread/sproutboat-cli/compare/v0.11.5...HEAD
|
|
548
|
+
[0.11.5]: https://github.com/baronunread/sproutboat-cli/compare/v0.11.4...v0.11.5
|
|
511
549
|
[0.11.4]: https://github.com/baronunread/sproutboat-cli/compare/v0.11.3...v0.11.4
|
|
512
550
|
[0.11.3]: https://github.com/baronunread/sproutboat-cli/compare/v0.11.2...v0.11.3
|
|
513
551
|
[0.11.2]: https://github.com/baronunread/sproutboat-cli/compare/v0.11.1...v0.11.2
|
package/SURFACE.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> Generated by `src/surface.test.ts` from `src/surface.ts` + the pinned
|
|
4
4
|
> toolchain constants. Do not edit by hand — run `UPDATE_SURFACE=1 bun test`.
|
|
5
5
|
|
|
6
|
-
**Package:** `sproutboat` 0.11.
|
|
6
|
+
**Package:** `sproutboat` 0.11.6 · runs on Bun (use `bunx`, not `npx`)
|
|
7
7
|
|
|
8
8
|
## Commands
|
|
9
9
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sproutboat",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.6",
|
|
4
4
|
"description": "Wrangler-shaped CLI for Sproutboat. Deploys workers to any control plane via --api-url / SPROUTBOAT_API_URL.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -64,9 +64,9 @@
|
|
|
64
64
|
"@sproutboat/artifact": "^0.2.0",
|
|
65
65
|
"@sproutboat/assets": "^0.2.0",
|
|
66
66
|
"@sproutboat/config": "^0.3.0",
|
|
67
|
-
"@sproutboat/runtime": "^0.
|
|
68
|
-
"@sproutboat/toolchain": "^0.4.
|
|
69
|
-
"@sproutboat/wire": "^0.
|
|
67
|
+
"@sproutboat/runtime": "^0.7.1",
|
|
68
|
+
"@sproutboat/toolchain": "^0.4.1",
|
|
69
|
+
"@sproutboat/wire": "^0.6.0",
|
|
70
70
|
"esbuild": "^0.28.2"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
@@ -78,10 +78,10 @@
|
|
|
78
78
|
"typescript": "7.0.2"
|
|
79
79
|
},
|
|
80
80
|
"optionalDependencies": {
|
|
81
|
-
"@sproutboat/cli-darwin-arm64": "0.11.
|
|
82
|
-
"@sproutboat/cli-darwin-x64": "0.11.
|
|
83
|
-
"@sproutboat/cli-linux-arm64": "0.11.
|
|
84
|
-
"@sproutboat/cli-linux-x64": "0.11.
|
|
81
|
+
"@sproutboat/cli-darwin-arm64": "0.11.6",
|
|
82
|
+
"@sproutboat/cli-darwin-x64": "0.11.6",
|
|
83
|
+
"@sproutboat/cli-linux-arm64": "0.11.6",
|
|
84
|
+
"@sproutboat/cli-linux-x64": "0.11.6"
|
|
85
85
|
},
|
|
86
86
|
"engines": {
|
|
87
87
|
"node": ">=18"
|
package/src/types-gen.ts
CHANGED
|
@@ -34,7 +34,7 @@ function entries(config: SproutboatConfig): Entry[] {
|
|
|
34
34
|
out.push({ name, type: "string", note: `vars: ${JSON.stringify(value)}` });
|
|
35
35
|
}
|
|
36
36
|
for (const name of config.secrets ?? []) {
|
|
37
|
-
out.push({ name, type: "string", note: "secret, set with `sproutboat secrets
|
|
37
|
+
out.push({ name, type: "string", note: "secret, set with `sproutboat secrets put`" });
|
|
38
38
|
}
|
|
39
39
|
for (const { binding } of resourceRefs(config.kv_namespaces)) out.push({ name: binding, type: "KVNamespace" });
|
|
40
40
|
for (const { binding } of resourceRefs(config.d1_databases)) out.push({ name: binding, type: "D1Database" });
|
package/types/sproutboat.d.ts
CHANGED
|
@@ -56,20 +56,46 @@ declare global {
|
|
|
56
56
|
|
|
57
57
|
// ---------------------------------------------------------------- R2
|
|
58
58
|
|
|
59
|
+
interface R2HttpMetadata {
|
|
60
|
+
contentType?: string;
|
|
61
|
+
contentDisposition?: string;
|
|
62
|
+
contentEncoding?: string;
|
|
63
|
+
contentLanguage?: string;
|
|
64
|
+
cacheControl?: string;
|
|
65
|
+
}
|
|
66
|
+
|
|
59
67
|
interface R2Object {
|
|
60
68
|
key: string;
|
|
61
69
|
size: number;
|
|
62
70
|
etag: string;
|
|
71
|
+
/** `etag`, quoted, ready for an `ETag` response header. */
|
|
72
|
+
httpEtag: string;
|
|
63
73
|
uploaded: string;
|
|
74
|
+
httpMetadata: R2HttpMetadata;
|
|
64
75
|
customMetadata?: Record<string, string>;
|
|
65
76
|
/**
|
|
66
77
|
* The object as a string. An object is held whole in memory on the way in
|
|
67
78
|
* and on the way out, so keep them small.
|
|
79
|
+
*
|
|
80
|
+
* `new Response(obj.body, ...)` corrupts any non-ASCII/binary content: the
|
|
81
|
+
* runtime cannot tell these bytes apart from a string a handler built, so
|
|
82
|
+
* it UTF-8-encodes them a second time (baronunread/sproutboat#177). Use
|
|
83
|
+
* `obj.toResponse()` instead for binary content — it serves the bytes
|
|
84
|
+
* unmodified.
|
|
68
85
|
*/
|
|
69
86
|
body: string;
|
|
87
|
+
text(): string;
|
|
88
|
+
json(): unknown;
|
|
89
|
+
/**
|
|
90
|
+
* A `Response` that serves `body` byte-for-byte, unlike `new
|
|
91
|
+
* Response(obj.body, ...)` (see `body` above). `init.headers`/`.status`
|
|
92
|
+
* merge in as usual; `content-type` defaults from `httpMetadata` and
|
|
93
|
+
* `etag` from `httpEtag` when not set.
|
|
94
|
+
*/
|
|
95
|
+
toResponse(init?: { status?: number; headers?: HeadersInit }): Response;
|
|
70
96
|
}
|
|
71
97
|
|
|
72
|
-
type R2ObjectHead = Omit<R2Object, "body">;
|
|
98
|
+
type R2ObjectHead = Omit<R2Object, "body" | "text" | "json" | "toResponse">;
|
|
73
99
|
|
|
74
100
|
interface R2Objects {
|
|
75
101
|
objects: R2ObjectHead[];
|
|
@@ -78,6 +104,7 @@ declare global {
|
|
|
78
104
|
}
|
|
79
105
|
|
|
80
106
|
interface R2PutOptions {
|
|
107
|
+
httpMetadata?: R2HttpMetadata;
|
|
81
108
|
customMetadata?: Record<string, string>;
|
|
82
109
|
}
|
|
83
110
|
|
|
@@ -226,16 +253,22 @@ declare global {
|
|
|
226
253
|
scheduledTime: number;
|
|
227
254
|
}
|
|
228
255
|
|
|
256
|
+
/**
|
|
257
|
+
* `env` is a global, not a parameter. `ctx` is the second argument, and its
|
|
258
|
+
* only member is `waitUntil`: work that outlives the response, drained
|
|
259
|
+
* in-process and capped at 25s.
|
|
260
|
+
*/
|
|
261
|
+
interface ExecutionContext {
|
|
262
|
+
waitUntil(promise: Promise<unknown>): void;
|
|
263
|
+
}
|
|
264
|
+
|
|
229
265
|
/**
|
|
230
266
|
* The default export.
|
|
231
|
-
*
|
|
232
|
-
* `fetch` takes only a request: `env` is a global, and there is no `ctx`, so
|
|
233
|
-
* there is no `ctx.waitUntil`. Use a queue for work that outlives a response.
|
|
234
267
|
*/
|
|
235
268
|
interface SproutboatHandler<QueueBody = unknown> {
|
|
236
|
-
fetch(request: Request): Response | Promise<Response>;
|
|
237
|
-
scheduled?(event: ScheduledEvent): void | Promise<void>;
|
|
238
|
-
queue?(batch: MessageBatch<QueueBody
|
|
269
|
+
fetch(request: Request, ctx: ExecutionContext): Response | Promise<Response>;
|
|
270
|
+
scheduled?(event: ScheduledEvent, ctx: ExecutionContext): void | Promise<void>;
|
|
271
|
+
queue?(batch: MessageBatch<QueueBody>, ctx: ExecutionContext): void | Promise<void>;
|
|
239
272
|
}
|
|
240
273
|
|
|
241
274
|
/**
|