Skip to content

feat: Support ArrayBuffer and Buffer Views serialization#201

Merged
kentonv merged 5 commits into
cloudflare:mainfrom
ttmx:feat/bufferviews-serialization
Jul 16, 2026
Merged

feat: Support ArrayBuffer and Buffer Views serialization#201
kentonv merged 5 commits into
cloudflare:mainfrom
ttmx:feat/bufferviews-serialization

Conversation

@ttmx

@ttmx ttmx commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Added serialization support for ArrayBuffer and Buffer views, like Int8Array, Uint8ClampedArray, etc.

@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@ttmx
ttmx force-pushed the feat/bufferviews-serialization branch from 66c4db3 to 4231ea8 Compare June 25, 2026 11:29
@changeset-bot

changeset-bot Bot commented Jun 25, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f3ac57a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
capnweb Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@ttmx

ttmx commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

github-actions Bot added a commit that referenced this pull request Jun 25, 2026
@ttmx ttmx changed the title Support ArrayBuffer and Buffer Views serialization feat: Support ArrayBuffer and Buffer Views serialization Jun 25, 2026

@kentonv kentonv left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Design looks good to me. I'm overloaded and don't have time to review line-by-line, maybe @dimitropoulos or @teamchong can take it.

Comment thread protocol.md Outdated
@pkg-pr-new

pkg-pr-new Bot commented Jun 25, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/cloudflare/capnweb@201

commit: f3ac57a

Comment thread protocol.md
Comment thread src/serialize.ts Outdated
Comment thread src/serialize.ts Outdated
@ndisidore

Copy link
Copy Markdown
Collaborator

/bonk review this

@ask-bonk ask-bonk Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the ArrayBuffer / typed-array serialization support. The design is solid and I'm glad to see the earlier review feedback addressed: the misalignment validation, little-endian wire order, and the minor version bump are all in place, and the test coverage is thorough (offset views, endianness, misalignment, unknown markers).

A few things worth considering below. None are blocking, but the "Uint8Array" marker robustness gap and the swapByteOrder missing default are worth a look.

Notes / questions:

  1. Incoming "Uint8Array" marker throws. The serializer intentionally emits the 2-element legacy form for Uint8Array, but a different or future implementation could legitimately send ["bytes", b64, "Uint8Array"]. That currently falls through to the default case and throws Unknown bytes type marker: Uint8Array. Since the protocol doc lists the marker set explicitly, it may be worth either (a) accepting "Uint8Array" (and "Buffer"?) as valid inbound markers, or (b) documenting in protocol.md that Uint8Array must always use the 2-element form. Deciding this now avoids a compatibility footgun later.

  2. The 12-case prototype switch in Devaluator duplicates the marker names already listed in core.ts and the deserialize switch. A single prototype→name map (or reusing one shared constant) would reduce the chance of these three lists drifting apart over time. Stylistic, but this is exactly the kind of triplicated list that tends to rot.

Comment thread src/serialize.ts
Comment thread src/serialize.ts Outdated
Comment thread src/serialize.ts Outdated
Comment thread protocol.md
@ask-bonk

ask-bonk Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review submitted successfully. Here's a summary of what I found:

Review of PR #201: ArrayBuffer and Buffer Views serialization

The PR is well-executed. The prior reviewer feedback (from ndisidore and kentonv) has all been addressed:

  • Misalignment validation (byteLength % elementSize) — added
  • Little-endian wire order mandated and implemented
  • Version bump corrected to minor (not patch)
  • Explicit type list added to protocol.md

Non-blocking notes I posted:

  1. Inbound "Uint8Array" marker throws — the serializer only ever emits the 2-element legacy form for Uint8Array, so an incoming explicit "Uint8Array" marker (from another implementation) falls into the default case and throws. Worth either accepting it or explicitly documenting the rule in protocol.md.

  2. swapByteOrder has no default case — silently no-ops on an unexpected elementSize. Currently unreachable, but a default: throw would fail loudly on misuse. Posted a suggestion.

  3. Triplicated type lists — the prototype switch in Devaluator, TYPED_ARRAY_ELEMENT_SIZE, and the deserialize switch all enumerate overlapping subsets of the same type set; a shared table would prevent drift.

  4. Defensive .slice() copy — correct and necessary (guards against Node Buffer pooling); suggested a clarifying comment.

  5. protocol.md — spec is silent on unknown-marker behavior and the Uint8Array rule; documenting these would firm up the wire contract for other implementations.

No correctness bugs found in the happy path or the endianness handling; the tests are host-independent and cover the important edge cases.

github run

Comment thread src/serialize.ts
@kentonv

kentonv commented Jul 15, 2026

Copy link
Copy Markdown
Member

/bonk re-review please

@ask-bonk ask-bonk Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review. All the feedback from the previous rounds has been addressed cleanly:

  • Misalignment validation (byteLength % elementSize) — done, with a clear error message and test coverage.
  • Little-endian wire order — mandated in protocol.md and implemented via swapByteOrder; the endianness handling is host-independent and tested.
  • minor version bump — correct.
  • Explicit type list in protocol.md — added, including the unknown-marker throw behavior and the Uint8Array markerless rule that were called out last time.
  • swapByteOrder default — now throws RangeError on unsupported element sizes (the earlier suggestion).
  • Inbound explicit "Uint8Array" marker — now accepted (and tested), closing the compatibility footgun.
  • .slice() copy — documented as deliberate.

I ran tsc (no new errors in src/serialize.ts / src/core.ts) and a manual roundtrip of all 13 type markers, offset views, and the legacy/explicit Uint8Array forms — all correct.

Two small, non-blocking notes below. Nice work.

Comment thread src/serialize.ts
Comment thread src/core.ts
@ask-bonk

ask-bonk Bot commented Jul 15, 2026

Copy link
Copy Markdown

Re-review submitted. Summary of my findings:

PR #201 re-review — ArrayBuffer / typed-array serialization

All prior feedback resolved. The author addressed every point from the earlier rounds (ndisidore, kenton, and the previous bonk review):

  • Misalignment validation (byteLength % elementSize) with clear errors + tests
  • Little-endian wire order mandated in protocol.md and implemented host-independently
  • minor version bump
  • Explicit supported-type list, unknown-marker behavior, and Uint8Array markerless rule documented in protocol.md
  • swapByteOrder now throws RangeError on unsupported element sizes
  • Inbound explicit "Uint8Array" marker now accepted (closes the compatibility footgun)
  • .slice() copy documented as deliberate

Verification I ran: tsc (no new errors in the changed source files — the only errors are pre-existing bun-types issues in bun.test.ts, unrelated), plus a manual roundtrip of all 13 markers, offset views, and both legacy/explicit Uint8Array forms — all correct.

Two non-blocking notes posted:

  1. The deserialize inner switch's default: marker satisfies never is compile-time-only; if hit at runtime it would fall through into case "error". Suggested adding a runtime throw.
  2. core.ts's typeForRpc case list is a fourth hand-maintained enumeration of the byte-container type set — a shared prototype constant would eliminate drift risk.

No correctness bugs found. The PR looks ready to merge modulo the maintainer's call on the two minor notes.

github run

github-actions Bot pushed a commit to ttmx/capnweb that referenced this pull request Jul 15, 2026
Co-authored-by: kentonv <kentonv@users.noreply.github.com>
@kentonv

kentonv commented Jul 15, 2026

Copy link
Copy Markdown
Member

ughh Bonk accidentally pushed a commit. It does that sometimes and we don't know why. @ttmx can you force-push remove bonk's commit? Then I think we can merge this, no other changes needed.

@ttmx
ttmx force-pushed the feat/bufferviews-serialization branch from cce656c to f3ac57a Compare July 16, 2026 00:00
@kentonv
kentonv merged commit 7325f9d into cloudflare:main Jul 16, 2026
9 checks passed
@github-actions github-actions Bot mentioned this pull request Jul 16, 2026
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.

3 participants