diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2021-08-11 12:27:05 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-11 12:27:05 +0200 |
commit | a0285e2eb88f6254f6494b0ecd1878db3a3b2a58 (patch) | |
tree | 90671b004537e20f9493fd3277ffd21d30b39a0e /ext/web/02_structured_clone.js | |
parent | 3a6994115176781b3a93d70794b1b81bc95e42b4 (diff) |
Rename extensions/ directory to ext/ (#11643)
Diffstat (limited to 'ext/web/02_structured_clone.js')
-rw-r--r-- | ext/web/02_structured_clone.js | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/ext/web/02_structured_clone.js b/ext/web/02_structured_clone.js new file mode 100644 index 000000000..4845c6508 --- /dev/null +++ b/ext/web/02_structured_clone.js @@ -0,0 +1,85 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. + +// @ts-check +/// <reference path="../../core/lib.deno_core.d.ts" /> +/// <reference path="../../core/internal.d.ts" /> +/// <reference path="../web/internal.d.ts" /> +/// <reference path="../web/lib.deno_web.d.ts" /> + +"use strict"; + +((window) => { + const core = window.Deno.core; + const { DOMException } = window.__bootstrap.domException; + const { + ArrayBuffer, + ArrayBufferIsView, + DataView, + TypedArrayPrototypeSlice, + TypeError, + WeakMap, + WeakMapPrototypeSet, + } = window.__bootstrap.primordials; + + const objectCloneMemo = new WeakMap(); + + function cloneArrayBuffer( + srcBuffer, + srcByteOffset, + srcLength, + _cloneConstructor, + ) { + // this function fudges the return type but SharedArrayBuffer is disabled for a while anyway + return TypedArrayPrototypeSlice( + srcBuffer, + srcByteOffset, + srcByteOffset + srcLength, + ); + } + + /** Clone a value in a similar way to structured cloning. It is similar to a +* StructureDeserialize(StructuredSerialize(...)). */ + function structuredClone(value) { + // Performance optimization for buffers, otherwise + // `serialize/deserialize` will allocate new buffer. + if (value instanceof ArrayBuffer) { + const cloned = cloneArrayBuffer( + value, + 0, + value.byteLength, + ArrayBuffer, + ); + WeakMapPrototypeSet(objectCloneMemo, value, cloned); + return cloned; + } + if (ArrayBufferIsView(value)) { + const clonedBuffer = structuredClone(value.buffer); + // Use DataViewConstructor type purely for type-checking, can be a + // DataView or TypedArray. They use the same constructor signature, + // only DataView has a length in bytes and TypedArrays use a length in + // terms of elements, so we adjust for that. + let length; + if (value instanceof DataView) { + length = value.byteLength; + } else { + length = value.length; + } + return new (value.constructor)( + clonedBuffer, + value.byteOffset, + length, + ); + } + + try { + return core.deserialize(core.serialize(value)); + } catch (e) { + if (e instanceof TypeError) { + throw new DOMException("Uncloneable value", "DataCloneError"); + } + throw e; + } + } + + window.__bootstrap.structuredClone = structuredClone; +})(globalThis); |