1 | import { __assign } from "tslib";
|
2 | import "../../utilities/globals/index.js";
|
3 | import { Trie } from "@wry/trie";
|
4 | import { canUseWeakMap, canUseWeakSet, isNonNullObject as isObjectOrArray, } from "../../utilities/index.js";
|
5 | import { isArray } from "./helpers.js";
|
6 | function 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 | }
|
14 | var 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 | }());
|
97 | export { ObjectCanon };
|
98 | export 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 | });
|
114 | var stringifyCanon;
|
115 | var stringifyCache;
|
116 | function resetCanonicalStringify() {
|
117 | stringifyCanon = new ObjectCanon;
|
118 | stringifyCache = new (canUseWeakMap ? WeakMap : Map)();
|
119 | }
|
120 |
|
\ | No newline at end of file |