UNPKG

4.41 kBJavaScriptView Raw
1import { __assign } from "tslib";
2import "../../utilities/globals/index.js";
3import { Trie } from "@wry/trie";
4import { canUseWeakMap, canUseWeakSet, isNonNullObject as isObjectOrArray, } from "../../utilities/index.js";
5import { isArray } from "./helpers.js";
6function shallowCopy(value) {
7 if (isObjectOrArray(value)) {
8 return isArray(value)
9 ? value.slice(0)
10 : __assign({ __proto__: Object.getPrototypeOf(value) }, value);
11 }
12 return value;
13}
14var ObjectCanon = (function () {
15 function ObjectCanon() {
16 this.known = new (canUseWeakSet ? WeakSet : Set)();
17 this.pool = new Trie(canUseWeakMap);
18 this.passes = new WeakMap();
19 this.keysByJSON = new Map();
20 this.empty = this.admit({});
21 }
22 ObjectCanon.prototype.isKnown = function (value) {
23 return isObjectOrArray(value) && this.known.has(value);
24 };
25 ObjectCanon.prototype.pass = function (value) {
26 if (isObjectOrArray(value)) {
27 var copy = shallowCopy(value);
28 this.passes.set(copy, value);
29 return copy;
30 }
31 return value;
32 };
33 ObjectCanon.prototype.admit = function (value) {
34 var _this = this;
35 if (isObjectOrArray(value)) {
36 var original = this.passes.get(value);
37 if (original)
38 return original;
39 var proto = Object.getPrototypeOf(value);
40 switch (proto) {
41 case Array.prototype: {
42 if (this.known.has(value))
43 return value;
44 var array = value.map(this.admit, this);
45 var node = this.pool.lookupArray(array);
46 if (!node.array) {
47 this.known.add(node.array = array);
48 if (__DEV__) {
49 Object.freeze(array);
50 }
51 }
52 return node.array;
53 }
54 case null:
55 case Object.prototype: {
56 if (this.known.has(value))
57 return value;
58 var proto_1 = Object.getPrototypeOf(value);
59 var array_1 = [proto_1];
60 var keys = this.sortedKeys(value);
61 array_1.push(keys.json);
62 var firstValueIndex_1 = array_1.length;
63 keys.sorted.forEach(function (key) {
64 array_1.push(_this.admit(value[key]));
65 });
66 var node = this.pool.lookupArray(array_1);
67 if (!node.object) {
68 var obj_1 = node.object = Object.create(proto_1);
69 this.known.add(obj_1);
70 keys.sorted.forEach(function (key, i) {
71 obj_1[key] = array_1[firstValueIndex_1 + i];
72 });
73 if (__DEV__) {
74 Object.freeze(obj_1);
75 }
76 }
77 return node.object;
78 }
79 }
80 }
81 return value;
82 };
83 ObjectCanon.prototype.sortedKeys = function (obj) {
84 var keys = Object.keys(obj);
85 var node = this.pool.lookupArray(keys);
86 if (!node.keys) {
87 keys.sort();
88 var json = JSON.stringify(keys);
89 if (!(node.keys = this.keysByJSON.get(json))) {
90 this.keysByJSON.set(json, node.keys = { sorted: keys, json: json });
91 }
92 }
93 return node.keys;
94 };
95 return ObjectCanon;
96}());
97export { ObjectCanon };
98export var canonicalStringify = Object.assign(function (value) {
99 if (isObjectOrArray(value)) {
100 if (stringifyCanon === void 0) {
101 resetCanonicalStringify();
102 }
103 var canonical = stringifyCanon.admit(value);
104 var json = stringifyCache.get(canonical);
105 if (json === void 0) {
106 stringifyCache.set(canonical, json = JSON.stringify(canonical));
107 }
108 return json;
109 }
110 return JSON.stringify(value);
111}, {
112 reset: resetCanonicalStringify,
113});
114var stringifyCanon;
115var stringifyCache;
116function resetCanonicalStringify() {
117 stringifyCanon = new ObjectCanon;
118 stringifyCache = new (canUseWeakMap ? WeakMap : Map)();
119}
120//# sourceMappingURL=object-canon.js.map
\No newline at end of file