1 | /*
|
---|
2 | MIT License http://www.opensource.org/licenses/mit-license.php
|
---|
3 | */
|
---|
4 |
|
---|
5 | "use strict";
|
---|
6 |
|
---|
7 | const cache = new WeakMap();
|
---|
8 |
|
---|
9 | class ObjectStructure {
|
---|
10 | constructor() {
|
---|
11 | this.keys = undefined;
|
---|
12 | this.children = undefined;
|
---|
13 | }
|
---|
14 |
|
---|
15 | getKeys(keys) {
|
---|
16 | if (this.keys === undefined) this.keys = keys;
|
---|
17 | return this.keys;
|
---|
18 | }
|
---|
19 |
|
---|
20 | key(key) {
|
---|
21 | if (this.children === undefined) this.children = new Map();
|
---|
22 | const child = this.children.get(key);
|
---|
23 | if (child !== undefined) return child;
|
---|
24 | const newChild = new ObjectStructure();
|
---|
25 | this.children.set(key, newChild);
|
---|
26 | return newChild;
|
---|
27 | }
|
---|
28 | }
|
---|
29 |
|
---|
30 | const getCachedKeys = (keys, cacheAssoc) => {
|
---|
31 | let root = cache.get(cacheAssoc);
|
---|
32 | if (root === undefined) {
|
---|
33 | root = new ObjectStructure();
|
---|
34 | cache.set(cacheAssoc, root);
|
---|
35 | }
|
---|
36 | let current = root;
|
---|
37 | for (const key of keys) {
|
---|
38 | current = current.key(key);
|
---|
39 | }
|
---|
40 | return current.getKeys(keys);
|
---|
41 | };
|
---|
42 |
|
---|
43 | class PlainObjectSerializer {
|
---|
44 | serialize(obj, { write }) {
|
---|
45 | const keys = Object.keys(obj);
|
---|
46 | if (keys.length > 128) {
|
---|
47 | // Objects with so many keys are unlikely to share structure
|
---|
48 | // with other objects
|
---|
49 | write(keys);
|
---|
50 | for (const key of keys) {
|
---|
51 | write(obj[key]);
|
---|
52 | }
|
---|
53 | } else if (keys.length > 1) {
|
---|
54 | write(getCachedKeys(keys, write));
|
---|
55 | for (const key of keys) {
|
---|
56 | write(obj[key]);
|
---|
57 | }
|
---|
58 | } else if (keys.length === 1) {
|
---|
59 | const key = keys[0];
|
---|
60 | write(key);
|
---|
61 | write(obj[key]);
|
---|
62 | } else {
|
---|
63 | write(null);
|
---|
64 | }
|
---|
65 | }
|
---|
66 | deserialize({ read }) {
|
---|
67 | const keys = read();
|
---|
68 | const obj = {};
|
---|
69 | if (Array.isArray(keys)) {
|
---|
70 | for (const key of keys) {
|
---|
71 | obj[key] = read();
|
---|
72 | }
|
---|
73 | } else if (keys !== null) {
|
---|
74 | obj[keys] = read();
|
---|
75 | }
|
---|
76 | return obj;
|
---|
77 | }
|
---|
78 | }
|
---|
79 |
|
---|
80 | module.exports = PlainObjectSerializer;
|
---|