feat: optional lazy unpack wrappers (#40) - #25691
Merged
Merged
Conversation
8 tasks
- unpack(buf, { lazy: true }) wraps maps/arrays as accessors
- keep the msgpack zone and source Buffer alive with the wrapper
- toJSON fully materializes; util.inspect does not hang
- Copy the caller Buffer before msgpack_unpack_next when lazy is set - str/bin aliases session-owned bytes, not the transferable backing store - Add a transfer test for str and bin after structuredClone detach
enochgroot
force-pushed
the
feat/lazy-unpack
branch
from
September 19, 2026 13:41
81bf44f to
917be5a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
unpack(buf, { lazy: true })so MessagePack maps/arrays become accessor wrappers instead of fully converting nested values up front (issue Optinally wrap msgpack_object instead of converting to V8 object #40).unpack(buf)is still eager. Nested values convert on read;toJSON/inspect.customfully materialize soJSON.stringifyandutil.inspectdo not hang.__proto__/constructorstay own properties, same as eager unpack. Incomplete input still returnsnull; oversized headers still throw.This branch is stacked on unmerged
feat/pack-type-hints(#52 / PR #25690). Merge that first, or this PR will include those commits.Test plan
npm test— 208 tests, 0 failures (23 new intest/lazy.test.js)npm run coverage:js— 100% statements / branches / functions / lines onlib/+bin/npm run coverage:native— 95.7% lines (1002/1047), 95.5% branches (976/1022), 100% functions (66/66); gate is 95%unpack({a:1,b:2,c:[1,2,3]})one-arg still deep-equals the sourceunpack(buf, {lazy:true}).c[1] === 2without readinga/bJSON.stringifyof lazy unpack matches eager unpack__proto__/constructordo not pollute prototypesnull; oversized array/map headers still throwOptional microbench on a small nested object (100k iters, this sandbox): JSON.parse 0.72 µs/op, eager unpack 2.28 µs/op, lazy wrap 4.68 µs/op, lazy then
.c[1]7.05 µs/op. Wrapper overhead dominates small payloads; the point of lazy is skipping unread nested conversion on large maps, not beating eager on tiny objects.Closes #40