It may be worth it to pipe Duper into your WASM/native code, and get back plain JSON out, which you then hand off to the runtime's `JSON.parse` with a post-processing step to support any special features needed. Something like this:
// idea of implementing public duper.parse function to lean on
// runtime's JSON.parse
//
// downlevel to json, eg binary strings become base64 normal json strings
const { jsonString, enhancements } = duper.duperToJSON(data)
// let the runtime go fast when decoding
const rawObject = JSON.parse(jsonString)
// `enhance` knows the paths to all the binary base64 strings
// and replaces them with Uint8Arrays
const decoded = duper.enhance(rawObject, enhancements)
Here enhancements is something very easy / low cost to construct over the FFI bridge, like type Path = Array<string | number>
type TransformFn = (value: unknown) => unknown
type Transform = TransformFn | Enhancements
type Enhancements = Array<[path: Path, transform: Transform]>
Not sure if this would end up faster, it may allocate more, but it's probably better than unoptimized object/array construction from WASM/native -> runtime. You could also try with a `reviver` argument to JSON.parse but i always find the lack of full path to key somewhat clunky.