dfahlander / typeson-registry

The type registry for typeson

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Structured cloning preset does not handle ArrayBuffers like structured cloning in browser

dumbmatter opened this issue · comments

I wrote https://github.com/dumbmatter/realistic-structured-clone a while back, and was recently linked to dexie/Dexie.js#647 (comment) which suggests that typeson could do a better job at achieving the same goal.

So I made a new branch https://github.com/dumbmatter/realistic-structured-clone/tree/typeson which basically just wraps typeson.

My hope was that this would pass all my unit tests, and then some. My tests only cover a subset of structured cloning, but that's all most people use (except this guy dumbmatter/realistic-structured-clone#5 :) ).

Mostly it worked, but one test failed, related to ArrayBuffers. This is the code:

var shared = new ArrayBuffer(7);
var obj = {
    wrapper1: new Uint8Array(shared),
    wrapper2: new Uint16Array(shared, 2, 2)
};
obj.wrapper1[0] = 1;
obj.wrapper2[1] = 0xffff;

var obj2 = structuredClone(obj);

console.log(obj2.wrapper1.buffer === obj2.wrapper2.buffer);

That should output "true", but with a Typeson-backed structuredClone function it says "false".

Here is a self-contained example of the error, including a comparison to structured cloning in the browser which does indeed output "true": https://github.com/dumbmatter/realistic-structured-clone/blob/typeson-bug/bug.js

I've got a fix coming for this... Need some time to finish off tests, push, etc., but it is working...

Essentially, our buffer-related code (including typed arrays and DataView) did not preserve the underlying buffer, which is a problem both for reestablishing circular references as well as for merely restoring a single typed array or data view with its full underlying buffer.

We do have code already for catching circular references, but the cyclic detection does not recurse on Typeson-replacements. Rather than trying a recursive solution which leverages that code (which I think may not even be possible given that such as a typed array's buffer property, for example, is not even iterable), I've gotten some code working in DataView, ArrayBuffer, and typed arrays which checks a buffer cache during replacement and revivification. (It requires an addition to Typeson I also intend to add shortly which passes a state object between revivers).

And thanks very much for the very helpful report...

This should now be fixed in v1.0.0-alpha.19 (commit 8da1f2c ). Note that it is important to update your dependencies, including Typeson.

Note that I added tests for typeson and typeson-registry but I haven't yet tested the changes here within IndexedDBShim.

If you would kindly confirm if it is working for you now--otherwise, my plan is to close this issue shortly, as I think it should be fixed.

Yep, it's fixed! Thanks!