summaryrefslogtreecommitdiff
path: root/ext/web/02_structured_clone.js
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2021-08-11 12:27:05 +0200
committerGitHub <noreply@github.com>2021-08-11 12:27:05 +0200
commita0285e2eb88f6254f6494b0ecd1878db3a3b2a58 (patch)
tree90671b004537e20f9493fd3277ffd21d30b39a0e /ext/web/02_structured_clone.js
parent3a6994115176781b3a93d70794b1b81bc95e42b4 (diff)
Rename extensions/ directory to ext/ (#11643)
Diffstat (limited to 'ext/web/02_structured_clone.js')
-rw-r--r--ext/web/02_structured_clone.js85
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);