@sproutboat/toolchain 0.4.1 → 0.4.2

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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @sproutboat/toolchain
2
2
 
3
+ ## 0.4.2
4
+
5
+ ### Patch Changes
6
+
7
+ - fa09d90: Update the pinned Porffor compiler to alpha 6 and remove the superseded local promise-resolution workaround.
8
+
3
9
  ## 0.4.1
4
10
 
5
11
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sproutboat/toolchain",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {
package/src/acquire.ts CHANGED
@@ -5,7 +5,7 @@ import { homedir } from "node:os";
5
5
  import { resolve } from "node:path";
6
6
  // @ts-expect-error Bun's file loader supplies a path; see the pinned-commit
7
7
  // check below for why this is safe to trust unconditionally.
8
- import vendoredPorfforArchive from "../vendor/porffor-1f4ae4a.tar.gz" with { type: "file" };
8
+ import vendoredPorfforArchive from "../vendor/porffor-038f415.tar.gz" with { type: "file" };
9
9
  import { ensurePorfforPatched } from "./patch";
10
10
  import { PORFFOR_ARCHIVE_SHA256, PORFFOR_ARCHIVE_URL, PORFFOR_COMMIT_FULL } from "./pin";
11
11
 
@@ -26,7 +26,12 @@ type AcquireOptions = {
26
26
  timeoutMs?: number;
27
27
  };
28
28
 
29
- const required = ["runtime/index.js", "compiler/render.js", "compiler/index.js", "compiler/uwebsockets.js"];
29
+ const required = [
30
+ "runtime/index.js",
31
+ "compiler/render.js",
32
+ "compiler/index.js",
33
+ "compiler/uwebsockets.js",
34
+ ];
30
35
  async function digest(path: string): Promise<string> {
31
36
  return createHash("sha256")
32
37
  .update(await readFile(path))
@@ -42,9 +47,11 @@ async function complete(dir: string, expectedArchive = PORFFOR_ARCHIVE_SHA256):
42
47
  archiveSha256?: string;
43
48
  files?: Record<string, string>;
44
49
  };
45
- if (manifest.commit !== PORFFOR_COMMIT_FULL || manifest.archiveSha256 !== expectedArchive) return false;
50
+ if (manifest.commit !== PORFFOR_COMMIT_FULL || manifest.archiveSha256 !== expectedArchive)
51
+ return false;
46
52
  for (const file of required)
47
- if (!manifest.files?.[file] || (await digest(resolve(dir, file))) !== manifest.files[file]) return false;
53
+ if (!manifest.files?.[file] || (await digest(resolve(dir, file))) !== manifest.files[file])
54
+ return false;
48
55
  return true;
49
56
  } catch {
50
57
  return false;
@@ -81,10 +88,16 @@ async function extract(archive: string, stage: string): Promise<void> {
81
88
  });
82
89
  const [code, stderr] = await Promise.all([child.exited, new Response(child.stderr).text()]);
83
90
  if (code !== 0)
84
- throw new PorfforToolchainError("archive", `could not extract pinned Porffor archive: ${stderr.trim()}`);
91
+ throw new PorfforToolchainError(
92
+ "archive",
93
+ `could not extract pinned Porffor archive: ${stderr.trim()}`,
94
+ );
85
95
  for (const file of required)
86
96
  if (!existsSync(resolve(stage, file)))
87
- throw new PorfforToolchainError("archive", `Porffor archive is missing required file ${file}`);
97
+ throw new PorfforToolchainError(
98
+ "archive",
99
+ `Porffor archive is missing required file ${file}`,
100
+ );
88
101
  }
89
102
 
90
103
  async function waitForPublisher(dir: string, lock: string): Promise<string | null> {
@@ -113,7 +126,9 @@ export async function ensurePorffor(options: AcquireOptions = {}): Promise<strin
113
126
  return dir;
114
127
  }
115
128
  const root = resolve(
116
- options.cacheRoot ?? process.env.SPROUTBOAT_TOOLCHAIN_CACHE ?? resolve(homedir(), ".cache/sproutboat"),
129
+ options.cacheRoot ??
130
+ process.env.SPROUTBOAT_TOOLCHAIN_CACHE ??
131
+ resolve(homedir(), ".cache/sproutboat"),
117
132
  );
118
133
  const dir = resolve(root, `porffor-${PORFFOR_COMMIT_FULL}`);
119
134
  const expected = options.expectedSha256 ?? PORFFOR_ARCHIVE_SHA256;
@@ -127,7 +142,10 @@ export async function ensurePorffor(options: AcquireOptions = {}): Promise<strin
127
142
  if (published) return published;
128
143
  return ensurePorffor(options);
129
144
  }
130
- const stage = resolve(root, `.porffor-${PORFFOR_COMMIT_FULL}-${process.pid}-${crypto.randomUUID()}`);
145
+ const stage = resolve(
146
+ root,
147
+ `.porffor-${PORFFOR_COMMIT_FULL}-${process.pid}-${crypto.randomUUID()}`,
148
+ );
131
149
  try {
132
150
  if (await complete(dir, expected)) return dir;
133
151
  await rm(dir, { recursive: true, force: true });
@@ -139,9 +157,18 @@ export async function ensurePorffor(options: AcquireOptions = {}): Promise<strin
139
157
  // left stale by a pin bump (checksum below still catches a wrong file
140
158
  // rather than silently accepting it).
141
159
  const noOverride = options.url === undefined && options.expectedSha256 === undefined;
142
- const vendored = noOverride && existsSync(vendoredPorfforArchive) && (await digest(vendoredPorfforArchive)) === expected;
160
+ const vendored =
161
+ noOverride &&
162
+ existsSync(vendoredPorfforArchive) &&
163
+ (await digest(vendoredPorfforArchive)) === expected;
143
164
  if (vendored) await writeFile(archive, await readFile(vendoredPorfforArchive));
144
- else await download(options.url ?? PORFFOR_ARCHIVE_URL, archive, options.fetcher ?? fetch, options.timeoutMs ?? 30_000);
165
+ else
166
+ await download(
167
+ options.url ?? PORFFOR_ARCHIVE_URL,
168
+ archive,
169
+ options.fetcher ?? fetch,
170
+ options.timeoutMs ?? 30_000,
171
+ );
145
172
  const actual = await digest(archive);
146
173
  if (actual !== expected)
147
174
  throw new PorfforToolchainError(
@@ -152,7 +179,9 @@ export async function ensurePorffor(options: AcquireOptions = {}): Promise<strin
152
179
  await rm(archive, { force: true });
153
180
  await ensurePorfforPatched(stage);
154
181
  const files = Object.fromEntries(
155
- await Promise.all(required.map(async (file) => [file, await digest(resolve(stage, file))] as const)),
182
+ await Promise.all(
183
+ required.map(async (file) => [file, await digest(resolve(stage, file))] as const),
184
+ ),
156
185
  );
157
186
  await writeFile(
158
187
  resolve(stage, ".sproutboat-complete"),
package/src/patch.test.ts CHANGED
@@ -2,7 +2,7 @@ import { expect, test } from "bun:test";
2
2
  import { mkdtemp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
3
3
  import { tmpdir } from "node:os";
4
4
  import { join } from "node:path";
5
- import { patchPromiseTs, patchRenderJs, patchUwebsockets } from "./patch";
5
+ import { patchRenderJs, patchUwebsockets } from "./patch";
6
6
 
7
7
  // The parts of Porffor's compiler/render.js the patch anchors to.
8
8
  const RENDER = `void porf_native_fetch_runtime_init(void) {
@@ -162,7 +162,9 @@ test("#156: status-line fallback synthesizes a line for unlisted codes, idempote
162
162
 
163
163
  // #163: collect_headers takes res, drops a client-sent x-sb-remote-addr, and
164
164
  // appends the real peer; the call site passes res through.
165
- expect(once).toContain("static i32 collect_headers(uWS::HttpRequest* req, uWS::HttpResponse<false>* res) {");
165
+ expect(once).toContain(
166
+ "static i32 collect_headers(uWS::HttpRequest* req, uWS::HttpResponse<false>* res) {",
167
+ );
166
168
  expect(once).toContain("const i32 headers_ptr = collect_headers(req, res);");
167
169
  expect(once).toContain('if (key == "x-sb-remote-addr") continue;');
168
170
  expect(once).toContain("res->getRemoteAddressAsText()");
@@ -179,12 +181,22 @@ test("#156: status-line fallback synthesizes a line for unlisted codes, idempote
179
181
  );
180
182
  expect(once).toContain('key == "x-sb-raw-body"');
181
183
  expect(once).toContain("bool raw_body = false;");
182
- expect(once).toContain('if (std::string_view(scan_buf, scan_bytes) == "x-sb-raw-body") raw_body = true;');
183
- expect(once).toContain("if (raw_body) porf_native_fetch_read_raw_bytes(body_value, &body_buf, &body_len);");
184
- expect(once).toContain("else porf_native_fetch_read_value(body_value, &body_buf, &body_len, &body_owned);");
184
+ expect(once).toContain(
185
+ 'if (std::string_view(scan_buf, scan_bytes) == "x-sb-raw-body") raw_body = true;',
186
+ );
187
+ expect(once).toContain(
188
+ "if (raw_body) porf_native_fetch_read_raw_bytes(body_value, &body_buf, &body_len);",
189
+ );
190
+ expect(once).toContain(
191
+ "else porf_native_fetch_read_value(body_value, &body_buf, &body_len, &body_owned);",
192
+ );
185
193
  // Header reads are the original 4-arg call, unchanged.
186
- expect(once).toContain("porf_native_fetch_read_value(name_value, &name_buf, &name_len, &name_owned);");
187
- expect(once).toContain("porf_native_fetch_read_value(value_value, &value_buf, &value_len, &value_owned);");
194
+ expect(once).toContain(
195
+ "porf_native_fetch_read_value(name_value, &name_buf, &name_len, &name_owned);",
196
+ );
197
+ expect(once).toContain(
198
+ "porf_native_fetch_read_value(value_value, &value_buf, &value_len, &value_owned);",
199
+ );
188
200
 
189
201
  await patchUwebsockets(root);
190
202
  expect(await readFile(join(root, "compiler/uwebsockets.js"), "utf8")).toBe(once);
@@ -240,60 +252,3 @@ test("#165: render.js routes console output to stderr, unbuffered, idempotently"
240
252
  await rm(root, { recursive: true, force: true });
241
253
  }
242
254
  });
243
-
244
- // The part of Porffor's compiler/builtins/promise.ts the #168 patch anchors to.
245
- const PROMISE_TS = `export const __Porffor_promise_resolve = (value: any, promise: any): void => {
246
- if (Porffor.type(value) == Porffor.TYPES.object) {
247
- // cheap prototype-chain probe for 'then' before the expensive Get below, does not invoke getters
248
- const thenHash: i32 = __Porffor_object_hash('then');
249
- let probe: any = value;
250
- while (Porffor.type(probe) == Porffor.TYPES.object) {
251
- if (Porffor.object.lookup(probe, 'then', thenHash) != 0) break;
252
- probe = __Porffor_object_getPrototype(probe);
253
- }
254
- if (Porffor.type(probe) != Porffor.TYPES.object) {
255
- __ecma262_FulfillPromise(promise, value);
256
- return;
257
- }
258
- }
259
- };
260
- `;
261
-
262
- test("#168: promise-resolve's then-probe gets a fixed-point guard, idempotently", async () => {
263
- const root = await mkdtemp(join(tmpdir(), "sb-patch-promise-"));
264
- try {
265
- await mkdir(join(root, "compiler/builtins"), { recursive: true });
266
- await writeFile(join(root, "compiler/builtins/promise.ts"), PROMISE_TS);
267
- await patchPromiseTs(root);
268
- const once = await readFile(join(root, "compiler/builtins/promise.ts"), "utf8");
269
-
270
- expect(once).toContain("sproutboat #168");
271
- expect(once).toContain("let probeFound: boolean = false;");
272
- expect(once).toContain("if (Porffor.object.lookup(probe, 'then', thenHash) != 0) { probeFound = true; break; }");
273
- // The fixed-point guard mirrors _internal_object.ts's lastProto idiom.
274
- expect(once).toContain("Porffor.fastOr(probe == null, Porffor.IR.ptr(probe) == Porffor.IR.ptr(lastProto))");
275
- expect(once).toContain("if (!probeFound) {");
276
- // Belt-and-suspenders: a hard iteration cap terminates the loop even if
277
- // some other corruption shape (a drifting pointer, a longer cycle) defeats
278
- // the fixed-point check above.
279
- expect(once).toContain("if (probeSteps > 64) break;");
280
- // The old type-check-only exit condition is gone.
281
- expect(once).not.toContain("if (Porffor.type(probe) != Porffor.TYPES.object) {");
282
-
283
- await patchPromiseTs(root);
284
- expect(await readFile(join(root, "compiler/builtins/promise.ts"), "utf8")).toBe(once);
285
- } finally {
286
- await rm(root, { recursive: true, force: true });
287
- }
288
- });
289
-
290
- test("#168: a drifted promise builtin fails loudly instead of silently no-op'ing", async () => {
291
- const root = await mkdtemp(join(tmpdir(), "sb-patch-promise-drift-"));
292
- try {
293
- await mkdir(join(root, "compiler/builtins"), { recursive: true });
294
- await writeFile(join(root, "compiler/builtins/promise.ts"), "// nothing the patch recognizes\n");
295
- await expect(patchPromiseTs(root)).rejects.toThrow(/anchor not found/);
296
- } finally {
297
- await rm(root, { recursive: true, force: true });
298
- }
299
- });
package/src/patch.ts CHANGED
@@ -108,7 +108,8 @@ const BYTESTRING_MARKER = "sproutboat #172";
108
108
  * below) calls it, gated on the reserved `x-sb-raw-body` response header the
109
109
  * assets binding sets. Every existing call site is untouched.
110
110
  */
111
- const READ_RAW_ANCHOR = "int porf_native_fetch_read_value(jsval value, const char** out_buf, size_t* out_len, char** out_owned) {";
111
+ const READ_RAW_ANCHOR =
112
+ "int porf_native_fetch_read_value(jsval value, const char** out_buf, size_t* out_len, char** out_owned) {";
112
113
  const READ_RAW_INJECT =
113
114
  "// sproutboat #176: zero-copy passthrough for a bytestring that is already-\n" +
114
115
  "// finished bytes (an asset read off disk), never a string to UTF-8 encode.\n" +
@@ -208,7 +209,8 @@ const STATUS_SIG_MARKER = "static std::string lookup_status_line(i32 status) {";
208
209
  // 303 is the one this was reported for (POST-redirect-GET); give it the real
209
210
  // reason phrase. Everything else unlisted rides the synthesized fallback below.
210
211
  const STATUS_303_ANCHOR = ' case 302: return "302 Found";\n';
211
- const STATUS_303_INJECT = ' case 302: return "302 Found";\n case 303: return "303 See Other";\n';
212
+ const STATUS_303_INJECT =
213
+ ' case 302: return "302 Found";\n case 303: return "303 See Other";\n';
212
214
  const STATUS_303_MARKER = 'case 303: return "303 See Other";';
213
215
  const STATUS_DEFAULT_ANCHOR = " default: return {};";
214
216
  const STATUS_DEFAULT_INJECT = ' default: return std::to_string(status) + " Status";';
@@ -225,7 +227,8 @@ const STATUS_DEFAULT_MARKER = 'std::to_string(status) + " Status"';
225
227
  * `request.cf.clientIp` and resolves it against `SB_TRUSTED_PROXIES` if set.
226
228
  */
227
229
  const HDR_SIG_ANCHOR = "static i32 collect_headers(uWS::HttpRequest* req) {\n";
228
- const HDR_SIG_INJECT = "static i32 collect_headers(uWS::HttpRequest* req, uWS::HttpResponse<false>* res) {\n";
230
+ const HDR_SIG_INJECT =
231
+ "static i32 collect_headers(uWS::HttpRequest* req, uWS::HttpResponse<false>* res) {\n";
229
232
  const HDR_SIG_MARKER = "collect_headers(uWS::HttpRequest* req, uWS::HttpResponse";
230
233
 
231
234
  const HDR_CALL_ANCHOR = "const i32 headers_ptr = collect_headers(req);";
@@ -361,7 +364,7 @@ const WRITE_RESPONSE_INJECT =
361
364
  " size_t scan_bytes = 0;\n" +
362
365
  " char* scan_owned = nullptr;\n" +
363
366
  " porf_native_fetch_read_value(scan_name, &scan_buf, &scan_bytes, &scan_owned);\n" +
364
- " if (std::string_view(scan_buf, scan_bytes) == \"x-sb-raw-body\") raw_body = true;\n" +
367
+ ' if (std::string_view(scan_buf, scan_bytes) == "x-sb-raw-body") raw_body = true;\n' +
365
368
  " if (scan_owned) free(scan_owned);\n" +
366
369
  " }\n" +
367
370
  " }\n" +
@@ -410,75 +413,6 @@ const WRITE_RESPONSE_INJECT =
410
413
  "}";
411
414
  const WRITE_RESPONSE_MARKER = "porf_native_fetch_read_raw_bytes(body_value";
412
415
 
413
- /**
414
- * baronunread/sproutboat#168 — `__Porffor_promise_resolve`'s duck-typing probe
415
- * for `.then` walks a value's prototype chain with no termination guard. Under
416
- * certain allocator conditions `__Porffor_object_getPrototype` returns a stale
417
- * "object" jsval instead of the `null`/`undefined` that should end the chain,
418
- * so the walk never bottoms out — a true infinite spin (100% CPU, no error, no
419
- * log line) that wedges the whole process, since native-fetch serves one
420
- * request at a time on a single event loop. Hits any handler whose `fetch`
421
- * resolves a promise with a plain object — the common shape for a JSON
422
- * response — so this is not a rare pattern; onset is nondeterministic
423
- * (allocator/pool reuse), typically after a handful of requests.
424
- *
425
- * `_internal_object.ts`'s own prototype-chain walks already guard against
426
- * exactly this failure mode: track the previous prototype and stop once the
427
- * "next" pointer stops advancing (a fixed point reads the same as reaching the
428
- * end). This probe has no such guard. Mirror the same idiom here: an explicit
429
- * `probeFound` flag (so a fixed-point break reads as "no `.then` found",
430
- * matching how a legitimate null-terminated chain is read) plus the
431
- * `lastProto` pointer comparison used everywhere else in the runtime.
432
- *
433
- * A hard iteration cap rides alongside the fixed-point check, not instead of
434
- * it: the lldb trace showed the *same* stale pointer on every sample, which
435
- * the fixed-point check alone catches on its very next iteration, but that's
436
- * one observed corruption shape, not a guarantee about every allocator state
437
- * that can produce this bug. A cap makes termination unconditional regardless
438
- * of whether some other corrupted state instead drifts (a different bad
439
- * pointer each time) or cycles across more than one node — real prototype
440
- * chains are a handful of links deep, so 64 iterations is generous headroom
441
- * with no risk of cutting off a legitimate lookup.
442
- */
443
- const THEN_PROBE_ANCHOR =
444
- " const thenHash: i32 = __Porffor_object_hash('then');\n" +
445
- " let probe: any = value;\n" +
446
- " while (Porffor.type(probe) == Porffor.TYPES.object) {\n" +
447
- " if (Porffor.object.lookup(probe, 'then', thenHash) != 0) break;\n" +
448
- " probe = __Porffor_object_getPrototype(probe);\n" +
449
- " }\n" +
450
- " if (Porffor.type(probe) != Porffor.TYPES.object) {\n";
451
- const THEN_PROBE_INJECT =
452
- " const thenHash: i32 = __Porffor_object_hash('then');\n" +
453
- " let probe: any = value;\n" +
454
- " let lastProto: any = probe;\n" +
455
- " let probeFound: boolean = false; // sproutboat #168: fixed-point chain reads as \"not found\", not a spin\n" +
456
- " let probeSteps: i32 = 0; // sproutboat #168: hard cap, belt-and-suspenders alongside the fixed-point check\n" +
457
- " while (Porffor.type(probe) == Porffor.TYPES.object) {\n" +
458
- " if (Porffor.object.lookup(probe, 'then', thenHash) != 0) { probeFound = true; break; }\n" +
459
- " probe = __Porffor_object_getPrototype(probe);\n" +
460
- " if (Porffor.fastOr(probe == null, Porffor.IR.ptr(probe) == Porffor.IR.ptr(lastProto))) break;\n" +
461
- " lastProto = probe;\n" +
462
- " probeSteps++;\n" +
463
- " if (probeSteps > 64) break;\n" +
464
- " }\n" +
465
- " if (!probeFound) {\n";
466
- const THEN_PROBE_MARKER = "sproutboat #168";
467
-
468
- /** The promise builtin: the #168 `.then`-probe livelock fix. Exported for tests. */
469
- export async function patchPromiseTs(root: string): Promise<void> {
470
- const file = resolve(root, "compiler/builtins/promise.ts");
471
- let src = await readFile(file, "utf8");
472
- if (src.includes(THEN_PROBE_MARKER)) return;
473
- if (!src.includes(THEN_PROBE_ANCHOR)) {
474
- throw new Error(
475
- "could not patch Porffor's promise-resolve then-probe (#168): anchor not found in " +
476
- `${file}. Porffor's promise builtin changed — check patches/UPSTREAM.md.`,
477
- );
478
- }
479
- await writeFile(file, src.replace(THEN_PROBE_ANCHOR, THEN_PROBE_INJECT));
480
- }
481
-
482
416
  const done = new Set<string>();
483
417
 
484
418
  /** Edits to Porffor's uWebSockets shim: `[marker, anchor, inject, what]`. */
@@ -486,15 +420,30 @@ const UWS_EDITS = [
486
420
  [BODY_MARKER, BODY_ANCHOR, BODY_INJECT, "request body limit"],
487
421
  [STATUS_SIG_MARKER, STATUS_SIG_ANCHOR, STATUS_SIG_INJECT, "status-line return type (#156)"],
488
422
  [STATUS_303_MARKER, STATUS_303_ANCHOR, STATUS_303_INJECT, "status-line 303 case (#156)"],
489
- [STATUS_DEFAULT_MARKER, STATUS_DEFAULT_ANCHOR, STATUS_DEFAULT_INJECT, "status-line fallback (#156)"],
423
+ [
424
+ STATUS_DEFAULT_MARKER,
425
+ STATUS_DEFAULT_ANCHOR,
426
+ STATUS_DEFAULT_INJECT,
427
+ "status-line fallback (#156)",
428
+ ],
490
429
  [HDR_SIG_MARKER, HDR_SIG_ANCHOR, HDR_SIG_INJECT, "collect_headers res arg (#163)"],
491
430
  [HDR_CALL_MARKER, HDR_CALL_ANCHOR, HDR_CALL_INJECT, "collect_headers call site (#163)"],
492
431
  [HDR_CAP_MARKER, HDR_CAP_ANCHOR, HDR_CAP_INJECT, "remote-addr header capacity (#163)"],
493
432
  [HDR_SKIP_MARKER, HDR_SKIP_ANCHOR, HDR_SKIP_INJECT, "drop client-sent x-sb-remote-addr (#163)"],
494
433
  [HDR_APPEND_MARKER, HDR_APPEND_ANCHOR, HDR_APPEND_INJECT, "append x-sb-remote-addr (#163)"],
495
434
  [READ_RAW_DECL_MARKER, READ_RAW_DECL_ANCHOR, READ_RAW_DECL_INJECT, "read_raw_bytes decl (#176)"],
496
- [FORBIDDEN_HDR_MARKER, FORBIDDEN_HDR_ANCHOR, FORBIDDEN_HDR_INJECT, "drop x-sb-raw-body from the wire (#176)"],
497
- [WRITE_RESPONSE_MARKER, WRITE_RESPONSE_ANCHOR, WRITE_RESPONSE_INJECT, "detect x-sb-raw-body, steer the body read (#176)"],
435
+ [
436
+ FORBIDDEN_HDR_MARKER,
437
+ FORBIDDEN_HDR_ANCHOR,
438
+ FORBIDDEN_HDR_INJECT,
439
+ "drop x-sb-raw-body from the wire (#176)",
440
+ ],
441
+ [
442
+ WRITE_RESPONSE_MARKER,
443
+ WRITE_RESPONSE_ANCHOR,
444
+ WRITE_RESPONSE_INJECT,
445
+ "detect x-sb-raw-body, steer the body read (#176)",
446
+ ],
498
447
  ] as const;
499
448
 
500
449
  /** The uWebSockets shim source: body limit + the #156 status-line fix. Exported for tests. */
@@ -589,6 +538,5 @@ export async function ensurePorfforPatched(root: string): Promise<void> {
589
538
  await patchCompilerArgs(root);
590
539
  await patchUwebsockets(root);
591
540
  await patchRenderJs(root);
592
- await patchPromiseTs(root);
593
541
  done.add(root);
594
542
  }
package/src/pin.ts CHANGED
@@ -10,13 +10,14 @@
10
10
  * uWebSockets archive in `sproutboat-cli/vendor/` — then run both repos'
11
11
  * test + conformance suites. See sproutboat-cli/MIGRATION.md.
12
12
  */
13
- export const PORFFOR_CHANNEL = "alpha-5";
14
- export const PORFFOR_COMMIT_FULL = "1f4ae4ae3e0a5f0a93b3bc084359e1a3a23391fd";
13
+ export const PORFFOR_CHANNEL = "alpha-6";
14
+ export const PORFFOR_COMMIT_FULL = "038f415e08efc5f87a6bfcb05a18824caa3a14f6";
15
15
  export const PORFFOR_COMMIT = PORFFOR_COMMIT_FULL.slice(0, 7);
16
- export const PORFFOR_ARCHIVE_SHA256 = "a49a0e857574e93cb09c574dcf53b7cc049d3cb65c5b944b169755cad2a51d5d";
16
+ export const PORFFOR_ARCHIVE_SHA256 =
17
+ "61f65d8fac5f94a7910f0a3f046e8929a852addb0033a032b9f7e08d0b07df5c";
17
18
  export const PORFFOR_ARCHIVE_URL = `https://codeload.github.com/CanadaHonk/porffor/tar.gz/${PORFFOR_COMMIT_FULL}`;
18
19
 
19
- /** A compact identity string for a manifest / report (`alpha-5 (1f4ae4a)`). */
20
+ /** A compact identity string for a manifest / report (`alpha-6 (038f415)`). */
20
21
  export function porfforVersion(): string {
21
22
  return process.env.PORFFOR_VERSION || `${PORFFOR_CHANNEL} (${PORFFOR_COMMIT})`;
22
23
  }
Binary file
Binary file