-
Notifications
You must be signed in to change notification settings - Fork 5.4k
/
02_structured_clone.js
85 lines (77 loc) · 2.37 KB
/
02_structured_clone.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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);