source: imaps-frontend/node_modules/@ungap/structured-clone/cjs/serialize.js

main
Last change on this file was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 4.1 KB
Line 
1'use strict';
2const {
3 VOID, PRIMITIVE, ARRAY, OBJECT, DATE, REGEXP, MAP, SET, ERROR, BIGINT
4} = require('./types.js');
5
6const EMPTY = '';
7
8const {toString} = {};
9const {keys} = Object;
10
11const typeOf = value => {
12 const type = typeof value;
13 if (type !== 'object' || !value)
14 return [PRIMITIVE, type];
15
16 const asString = toString.call(value).slice(8, -1);
17 switch (asString) {
18 case 'Array':
19 return [ARRAY, EMPTY];
20 case 'Object':
21 return [OBJECT, EMPTY];
22 case 'Date':
23 return [DATE, EMPTY];
24 case 'RegExp':
25 return [REGEXP, EMPTY];
26 case 'Map':
27 return [MAP, EMPTY];
28 case 'Set':
29 return [SET, EMPTY];
30 }
31
32 if (asString.includes('Array'))
33 return [ARRAY, asString];
34
35 if (asString.includes('Error'))
36 return [ERROR, asString];
37
38 return [OBJECT, asString];
39};
40
41const shouldSkip = ([TYPE, type]) => (
42 TYPE === PRIMITIVE &&
43 (type === 'function' || type === 'symbol')
44);
45
46const serializer = (strict, json, $, _) => {
47
48 const as = (out, value) => {
49 const index = _.push(out) - 1;
50 $.set(value, index);
51 return index;
52 };
53
54 const pair = value => {
55 if ($.has(value))
56 return $.get(value);
57
58 let [TYPE, type] = typeOf(value);
59 switch (TYPE) {
60 case PRIMITIVE: {
61 let entry = value;
62 switch (type) {
63 case 'bigint':
64 TYPE = BIGINT;
65 entry = value.toString();
66 break;
67 case 'function':
68 case 'symbol':
69 if (strict)
70 throw new TypeError('unable to serialize ' + type);
71 entry = null;
72 break;
73 case 'undefined':
74 return as([VOID], value);
75 }
76 return as([TYPE, entry], value);
77 }
78 case ARRAY: {
79 if (type)
80 return as([type, [...value]], value);
81
82 const arr = [];
83 const index = as([TYPE, arr], value);
84 for (const entry of value)
85 arr.push(pair(entry));
86 return index;
87 }
88 case OBJECT: {
89 if (type) {
90 switch (type) {
91 case 'BigInt':
92 return as([type, value.toString()], value);
93 case 'Boolean':
94 case 'Number':
95 case 'String':
96 return as([type, value.valueOf()], value);
97 }
98 }
99
100 if (json && ('toJSON' in value))
101 return pair(value.toJSON());
102
103 const entries = [];
104 const index = as([TYPE, entries], value);
105 for (const key of keys(value)) {
106 if (strict || !shouldSkip(typeOf(value[key])))
107 entries.push([pair(key), pair(value[key])]);
108 }
109 return index;
110 }
111 case DATE:
112 return as([TYPE, value.toISOString()], value);
113 case REGEXP: {
114 const {source, flags} = value;
115 return as([TYPE, {source, flags}], value);
116 }
117 case MAP: {
118 const entries = [];
119 const index = as([TYPE, entries], value);
120 for (const [key, entry] of value) {
121 if (strict || !(shouldSkip(typeOf(key)) || shouldSkip(typeOf(entry))))
122 entries.push([pair(key), pair(entry)]);
123 }
124 return index;
125 }
126 case SET: {
127 const entries = [];
128 const index = as([TYPE, entries], value);
129 for (const entry of value) {
130 if (strict || !shouldSkip(typeOf(entry)))
131 entries.push(pair(entry));
132 }
133 return index;
134 }
135 }
136
137 const {message} = value;
138 return as([TYPE, {name: type, message}], value);
139 };
140
141 return pair;
142};
143
144/**
145 * @typedef {Array<string,any>} Record a type representation
146 */
147
148/**
149 * Returns an array of serialized Records.
150 * @param {any} value a serializable value.
151 * @param {{json?: boolean, lossy?: boolean}?} options an object with a `lossy` or `json` property that,
152 * if `true`, will not throw errors on incompatible types, and behave more
153 * like JSON stringify would behave. Symbol and Function will be discarded.
154 * @returns {Record[]}
155 */
156 const serialize = (value, {json, lossy} = {}) => {
157 const _ = [];
158 return serializer(!(json || lossy), !!json, new Map, _)(value), _;
159};
160exports.serialize = serialize;
Note: See TracBrowser for help on using the repository browser.