Skip to content

refactor(sse): declare the ArrayBuffer backing on media byte producers - #8665

Merged
diegosouzapw merged 1 commit into
diegosouzapw:release/v3.8.49from
backryun:chore/ts7-types-buffer-arraybuffer
Jul 27, 2026
Merged

diegosouzapw merged 1 commit into
diegosouzapw:release/v3.8.49from
backryun:chore/ts7-types-buffer-arraybuffer

Conversation

@backryun

Copy link
Copy Markdown
Contributor

Part of the TS7 readiness campaign (#8484). One root cause, 5 diagnostics, zero new.

Root cause

Six declarations spell a byte buffer as bare Buffer / Uint8Array. Without its type argument that widens to ArrayBufferLike, which also admits SharedArrayBuffer — so the value is rejected at every Web API boundary it is actually passed to: BodyInit for new Response(...), BlobPart for new Blob([...]).

Every one of them is already ArrayBuffer-backed at runtime:

producer allocation consumed by
hexToBytes() (audioSpeech.ts) new Uint8Array(len) new Response(bytes) — MiniMax T2A v2
synthesizeGtts() (gtts.ts) Buffer.concat(...) new Response(audio) — gTTS
pcmToWav() → vertexGenerateSpeech() (vertexMedia.ts) Buffer.concat([header, pcm]) new Response(audio) — Vertex Gemini TTS
fetchRemoteImage() (remoteImageFetch.ts) Buffer.from(await response.arrayBuffer()) new Blob([...]) — Topaz upload
readPageResponseBody() (browserPool.ts) Buffer.from(body) (copies) browserBackedChat.ts response body

The declarations were simply less specific than the values, so this states what the code already guarantees. It is the same fix #8533 applied to the multipart and gRPC-web bodies.

Diagnostics fixed

file count code
open-sse/handlers/audioSpeech.ts 3 TS2345 → BodyInit
open-sse/handlers/imageGeneration.ts 1 TS2322 → BlobPart
open-sse/services/browserBackedChat.ts 1 TS2322 → Buffer<ArrayBuffer>

Measured as a line-number-agnostic diff of the complete tsc -p open-sse/tsconfig.json error set against a freshly re-measured base: 208 → 203, 5 fixed, 0 new.

Note that three of the five fixed diagnostics are in files this PR does not touch — the fix is at each producer, not at the call site.

Behaviour

Type annotations only; no runtime change. The narrowing is safe in both directions: Buffer<ArrayBuffer> is assignable to Buffer, so no existing consumer is affected, and every producer's allocation is ArrayBuffer-backed (Node buffers are never SharedArrayBuffer-backed, pooled or not).

Test plan

New tests/unit/media-body-arraybuffer-backing.test.ts — 4 tests, one per reachable producer. Each asserts both the backing and that the value really is accepted by the Web API it is passed to in production:

assert.ok(wav.buffer instanceof ArrayBuffer);
assert.doesNotThrow(() => new Response(wav));

The existing tests for these functions assert their contents — the RIFF header (vertex-media.test.ts), the concatenated chunks (gtts-provider.test.ts), the decoded base64 (remote-image-fetch.test.ts). None asserted the backing, which is the one property the narrowed return types exist to guarantee and the one a refactor to a shared allocation would break.

The sixth producer, hexToBytes(), is module-private; its new Response(bytes) path is already exercised end-to-end by minimax-tts-1043.test.ts, which builds the response and reads its body.

node --import tsx/esm --test tests/unit/media-body-arraybuffer-backing.test.ts   # 4/4

Regression run over every touched producer's existing suite — gtts-provider, vertex-media, vertex-tts, remote-image-fetch, remote-image-fetch-dns-rebinding, remote-image-fetch-pin-dns-connection, browser-pool-optional-import, minimax-tts-1043, audio-speech-handler, audio-speech-fishaudio, image-generation-handler: 108 pass, 0 fail.

Gates: typecheck:core clean, check:file-size OK, ESLint clean on all touched files.

The one red check, Merge integrity (changelog + generated skills), is base-red on release/v3.8.49 and unrelated to this diff — it reproduces on the bare tip and is being fixed by #8657 / tracked in #8658.

@backryun
backryun requested a review from diegosouzapw as a code owner July 26, 2026 11:44
@backryun
backryun force-pushed the chore/ts7-types-buffer-arraybuffer branch 2 times, most recently from dcbc2cc to 801a02b Compare July 27, 2026 15:18
Six declarations spell a byte buffer as bare `Buffer` / `Uint8Array`. Without
its type argument that widens to `ArrayBufferLike`, which also admits
`SharedArrayBuffer` — so the value is rejected at every Web API boundary it is
actually passed to: `BodyInit` for `new Response(...)` and `BlobPart` for
`new Blob([...])`.

Every one of them is already ArrayBuffer-backed at runtime. `hexToBytes()`
allocates with `new Uint8Array(len)`; `synthesizeGtts()` and `pcmToWav()` return
`Buffer.concat(...)`; `fetchRemoteImage()` returns
`Buffer.from(await response.arrayBuffer())`; `readPageResponseBody()` returns
`Buffer.from(body)`, which copies. The declarations were simply less specific
than the values, so this states what the code already guarantees.

Same fix diegosouzapw#8533 applied to the multipart and gRPC-web bodies.

Fixes 5 of the 208 `tsc -p open-sse/tsconfig.json` diagnostics with no new ones:
3 in audioSpeech.ts (MiniMax hex, gTTS, Vertex Gemini TTS), 1 in
imageGeneration.ts (Topaz Blob upload) and 1 in browserBackedChat.ts.

Refs diegosouzapw#8484
@backryun
backryun force-pushed the chore/ts7-types-buffer-arraybuffer branch from 801a02b to 24adb2d Compare July 27, 2026 15:35
@diegosouzapw
diegosouzapw merged commit 116d583 into diegosouzapw:release/v3.8.49 Jul 27, 2026
15 checks passed
@backryun
backryun deleted the chore/ts7-types-buffer-arraybuffer branch July 27, 2026 22:21
@diegosouzapw diegosouzapw mentioned this pull request Jul 28, 2026
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
diegosouzapw#8665)

Six declarations spell a byte buffer as bare `Buffer` / `Uint8Array`. Without
its type argument that widens to `ArrayBufferLike`, which also admits
`SharedArrayBuffer` — so the value is rejected at every Web API boundary it is
actually passed to: `BodyInit` for `new Response(...)` and `BlobPart` for
`new Blob([...])`.

Every one of them is already ArrayBuffer-backed at runtime. `hexToBytes()`
allocates with `new Uint8Array(len)`; `synthesizeGtts()` and `pcmToWav()` return
`Buffer.concat(...)`; `fetchRemoteImage()` returns
`Buffer.from(await response.arrayBuffer())`; `readPageResponseBody()` returns
`Buffer.from(body)`, which copies. The declarations were simply less specific
than the values, so this states what the code already guarantees.

Same fix diegosouzapw#8533 applied to the multipart and gRPC-web bodies.

Fixes 5 of the 208 `tsc -p open-sse/tsconfig.json` diagnostics with no new ones:
3 in audioSpeech.ts (MiniMax hex, gTTS, Vertex Gemini TTS), 1 in
imageGeneration.ts (Topaz Blob upload) and 1 in browserBackedChat.ts.

Refs diegosouzapw#8484
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
diegosouzapw#8665)

Six declarations spell a byte buffer as bare `Buffer` / `Uint8Array`. Without
its type argument that widens to `ArrayBufferLike`, which also admits
`SharedArrayBuffer` — so the value is rejected at every Web API boundary it is
actually passed to: `BodyInit` for `new Response(...)` and `BlobPart` for
`new Blob([...])`.

Every one of them is already ArrayBuffer-backed at runtime. `hexToBytes()`
allocates with `new Uint8Array(len)`; `synthesizeGtts()` and `pcmToWav()` return
`Buffer.concat(...)`; `fetchRemoteImage()` returns
`Buffer.from(await response.arrayBuffer())`; `readPageResponseBody()` returns
`Buffer.from(body)`, which copies. The declarations were simply less specific
than the values, so this states what the code already guarantees.

Same fix diegosouzapw#8533 applied to the multipart and gRPC-web bodies.

Fixes 5 of the 208 `tsc -p open-sse/tsconfig.json` diagnostics with no new ones:
3 in audioSpeech.ts (MiniMax hex, gTTS, Vertex Gemini TTS), 1 in
imageGeneration.ts (Topaz Blob upload) and 1 in browserBackedChat.ts.

Refs diegosouzapw#8484
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants