Context
PR #51 makes Body extend the platform Blob surface as the follow-up for #50. During review, Codex flagged that stream-backed Body instances currently expose an empty inherited Blob backing, so Blob([body]) can silently drop the payload.
Before continuing that refactor, we should audit and align Blob itself against platform behavior from Chrome, Bun, Node, and the File API / MDN model.
Refs #50
Refs #51
Observed platform behavior
Checked locally against:
- Chrome 149.0.7827.116
- Node v26.0.0
- Bun 1.3.14
Shared behavior:
BlobPart accepts BufferSource, Blob, and string-like values.
ReadableStream is not read as a blob part; it is converted to the string [object ReadableStream].
TypedArray / ArrayBuffer sources are copied when the Blob is constructed. Mutating the original bytes after construction does not change Blob content.
- TypedArray views only contribute their view range.
Blob parts append the Blob internal byte sequence, and the part type is ignored.
Blob subclasses used as parts are read through their internal Blob backing, not through overridden text(), stream(), or arrayBuffer() methods.
arrayBuffer() returns a copy; mutating the returned buffer does not mutate the Blob.
- Blob reads are repeatable.
Suspected ht.Blob gaps
The current implementation likely needs explicit tests and fixes around snapshot/copy semantics:
Blob([Uint8List]) should copy bytes at construction.
Blob([ByteBuffer]) and Blob([ByteData]) should copy the relevant byte range at construction.
Blob.arrayBuffer() should return a fresh copy rather than exposing mutable internal storage.
Blob.slice() should continue to provide stable, repeatable Blob reads.
- IO/web-specific Blob wrappers should preserve the same semantics where practical.
This is separate from, but directly blocks, the Body extends Blob refactor. The review comment on PR #51 is consistent with platform behavior: Blob([body]) should not call Body.stream(). Therefore a stream-backed Body cannot be a valid Blob unless it has a real Blob byte backing or the refactor is narrowed.
Acceptance criteria
Context
PR #51 makes
Bodyextend the platformBlobsurface as the follow-up for #50. During review, Codex flagged that stream-backedBodyinstances currently expose an empty inherited Blob backing, soBlob([body])can silently drop the payload.Before continuing that refactor, we should audit and align
Blobitself against platform behavior from Chrome, Bun, Node, and the File API / MDN model.Refs #50
Refs #51
Observed platform behavior
Checked locally against:
Shared behavior:
BlobPartacceptsBufferSource,Blob, and string-like values.ReadableStreamis not read as a blob part; it is converted to the string[object ReadableStream].TypedArray/ArrayBuffersources are copied when the Blob is constructed. Mutating the original bytes after construction does not change Blob content.Blobparts append the Blob internal byte sequence, and the part type is ignored.Blobsubclasses used as parts are read through their internal Blob backing, not through overriddentext(),stream(), orarrayBuffer()methods.arrayBuffer()returns a copy; mutating the returned buffer does not mutate the Blob.Suspected ht.Blob gaps
The current implementation likely needs explicit tests and fixes around snapshot/copy semantics:
Blob([Uint8List])should copy bytes at construction.Blob([ByteBuffer])andBlob([ByteData])should copy the relevant byte range at construction.Blob.arrayBuffer()should return a fresh copy rather than exposing mutable internal storage.Blob.slice()should continue to provide stable, repeatable Blob reads.This is separate from, but directly blocks, the
Body extends Blobrefactor. The review comment on PR #51 is consistent with platform behavior:Blob([body])should not callBody.stream(). Therefore a stream-backedBodycannot be a valid Blob unless it has a real Blob byte backing or the refactor is narrowed.Acceptance criteria
arrayBuffer()returns a copy.