seroval 0.9.0 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +4 -287
  2. package/dist/cjs/development/index.cjs +3529 -1140
  3. package/dist/cjs/development/index.cjs.map +4 -4
  4. package/dist/cjs/production/index.cjs +3 -3
  5. package/dist/esm/development/index.mjs +3533 -1142
  6. package/dist/esm/development/index.mjs.map +4 -4
  7. package/dist/esm/production/index.mjs +3 -3
  8. package/dist/types/core/Serializer.d.ts +15 -0
  9. package/dist/types/{tree → core}/UnsupportedTypeError.d.ts +4 -3
  10. package/dist/types/{assert.d.ts → core/assert.d.ts} +1 -1
  11. package/dist/types/core/assignments.d.ts +33 -0
  12. package/dist/types/core/base-primitives.d.ts +12 -0
  13. package/dist/types/{compat.d.ts → core/compat.d.ts} +22 -22
  14. package/dist/types/core/constants.d.ts +89 -0
  15. package/dist/types/core/context.d.ts +9 -0
  16. package/dist/types/core/cross/async.d.ts +3 -0
  17. package/dist/types/core/cross/context.d.ts +37 -0
  18. package/dist/types/core/cross/index.d.ts +8 -0
  19. package/dist/types/core/cross/primitives.d.ts +9 -0
  20. package/dist/types/core/cross/serialize.d.ts +5 -0
  21. package/dist/types/core/cross/stream.d.ts +3 -0
  22. package/dist/types/core/cross/sync.d.ts +3 -0
  23. package/dist/types/core/cross/web-api.d.ts +4 -0
  24. package/dist/types/{get-identifier.d.ts → core/get-identifier.d.ts} +1 -1
  25. package/dist/types/core/keys.d.ts +13 -0
  26. package/dist/types/{tree/constants.d.ts → core/literals.d.ts} +9 -11
  27. package/dist/types/core/promise-to-result.d.ts +1 -0
  28. package/dist/types/{tree → core}/reference.d.ts +5 -6
  29. package/dist/types/{tree → core}/shared.d.ts +13 -13
  30. package/dist/types/{string.d.ts → core/string.d.ts} +3 -3
  31. package/dist/types/core/tree/async.d.ts +3 -0
  32. package/dist/types/core/tree/context.d.ts +44 -0
  33. package/dist/types/core/tree/deserialize.d.ts +3 -0
  34. package/dist/types/core/tree/index.d.ts +14 -0
  35. package/dist/types/core/tree/primitives.d.ts +9 -0
  36. package/dist/types/core/tree/serialize.d.ts +4 -0
  37. package/dist/types/core/tree/sync.d.ts +3 -0
  38. package/dist/types/core/tree/web-api.d.ts +4 -0
  39. package/dist/types/{tree → core}/types.d.ts +228 -238
  40. package/dist/types/core/web-api.d.ts +4 -0
  41. package/dist/types/index.d.ts +9 -19
  42. package/dist/types/types.d.ts +20 -20
  43. package/package.json +5 -5
  44. package/src/core/Serializer.ts +48 -0
  45. package/src/{tree → core}/UnsupportedTypeError.ts +1 -1
  46. package/src/core/assignments.ts +159 -0
  47. package/src/{tree/primitives.ts → core/base-primitives.ts} +33 -136
  48. package/src/core/constants.ts +169 -0
  49. package/src/core/context.ts +15 -0
  50. package/src/core/cross/async.ts +614 -0
  51. package/src/core/cross/context.ts +102 -0
  52. package/src/core/cross/index.ts +169 -0
  53. package/src/core/cross/primitives.ts +137 -0
  54. package/src/core/cross/serialize.ts +847 -0
  55. package/src/core/cross/stream.ts +745 -0
  56. package/src/core/cross/sync.ts +561 -0
  57. package/src/core/cross/web-api.ts +55 -0
  58. package/src/core/header.js +61 -0
  59. package/src/core/keys.ts +41 -0
  60. package/src/core/literals.ts +28 -0
  61. package/src/core/promise-to-result.ts +9 -0
  62. package/src/{tree → core}/reference.ts +6 -7
  63. package/src/{tree → core}/shared.ts +4 -4
  64. package/src/{tree → core/tree}/async.ts +46 -34
  65. package/src/core/tree/context.ts +125 -0
  66. package/src/{tree → core/tree}/deserialize.ts +68 -55
  67. package/src/core/tree/index.ts +142 -0
  68. package/src/core/tree/primitives.ts +132 -0
  69. package/src/{tree → core/tree}/serialize.ts +87 -193
  70. package/src/{tree → core/tree}/sync.ts +50 -39
  71. package/src/{tree → core/tree}/web-api.ts +8 -52
  72. package/src/{tree → core}/types.ts +76 -60
  73. package/src/core/web-api.ts +51 -0
  74. package/src/index.ts +7 -141
  75. package/src/types.ts +1 -1
  76. package/dist/types/context.d.ts +0 -67
  77. package/dist/types/tree/async.d.ts +0 -3
  78. package/dist/types/tree/deserialize.d.ts +0 -3
  79. package/dist/types/tree/primitives.d.ts +0 -19
  80. package/dist/types/tree/serialize.d.ts +0 -4
  81. package/dist/types/tree/symbols.d.ts +0 -33
  82. package/dist/types/tree/sync.d.ts +0 -3
  83. package/dist/types/tree/web-api.d.ts +0 -6
  84. package/src/context.ts +0 -164
  85. package/src/tree/constants.ts +0 -73
  86. package/src/tree/symbols.ts +0 -65
  87. /package/src/{assert.ts → core/assert.ts} +0 -0
  88. /package/src/{compat.ts → core/compat.ts} +0 -0
  89. /package/src/{get-identifier.ts → core/get-identifier.ts} +0 -0
  90. /package/src/{string.ts → core/string.ts} +0 -0
package/README.md CHANGED
@@ -80,294 +80,11 @@ Output (as a string):
80
80
  }, h[3] = h, j.set("self", j), k.add(k).add(h), m.self = m, m))()
81
81
  ```
82
82
 
83
- ### Mutual cyclic example
83
+ ## Docs
84
84
 
85
- ```js
86
- import { serialize } from 'seroval';
87
-
88
- const a = new Map([['name', 'a']]);
89
- const b = new Map([['name', 'b']]);
90
- const c = new Map([['name', 'c']]);
91
- const d = new Map([['name', 'd']]);
92
-
93
- c.set('left', a);
94
- d.set('left', a);
95
- c.set('right', b);
96
- d.set('right', b);
97
- a.set('children', [c, d]);
98
- b.set('children', [c, d]);
99
-
100
- const result = serialize({ a, b, c, d });
101
- console.log(result);
102
- ```
103
-
104
- Output (as a string):
105
-
106
- ```js
107
- ((h,j,k,m,o,q)=>(q={a:h=new Map([["name","a"],["children",[j=new Map([["name","c"],["right",o=new Map([["name","b"],["children",k=[,m=new Map([["name","d"]])]]])]]),m]]]),b:o,c:j,d:m},j.set("left",h),k[0]=j,m.set("left",h).set("right",o),q))()
108
-
109
- // Formatted
110
- ((h, j, k, m, o, q) => (q = {
111
- a: h = new Map([
112
- ["name", "a"],
113
- ["children", [j = new Map([
114
- ["name", "c"],
115
- ["right", o = new Map([
116
- ["name", "b"],
117
- ["children", k = [, m = new Map([
118
- ["name", "d"]
119
- ])]]
120
- ])]
121
- ]), m]]
122
- ]),
123
- b: o,
124
- c: j,
125
- d: m
126
- }, j.set("left", h), k[0] = j, m.set("left", h).set("right", o), q))()
127
- ```
128
-
129
- ## Deserialization
130
-
131
- ```js
132
- import { serialize, deserialize } from 'seroval';
133
-
134
- const value = undefined;
135
- console.log(deserialize(serialize(value)) === value);
136
- ```
137
-
138
- ## JSON
139
-
140
- `serialize` and `deserialize` is great for server-to-client communication, but what about the other way? `serialize` may cause an [RCE if used as a payload for requests](https://huntr.dev/bounties/63f1ff91-48f3-4886-a179-103f1ddd8ff8). `seroval` includes `toJSON` and `fromJSON` as an alternative form of serialization.
141
-
142
- First example above outputs the following JSON
143
-
144
- ```js
145
- import { toJSON } from 'seroval';
146
- // ...
147
- const result = toJSON(object);
148
- console.log(JSON.stringify(result));
149
- ```
150
-
151
- ```json
152
- {"t":{"t":16,"i":0,"d":{"k":["number","string","boolean","null","undefined","bigint","array","regexp","date","map","set","self"],"v":[{"t":15,"i":1,"l":5,"a":[{"t":0,"s":0.4350045546286634},{"t":5},{"t":8},{"t":6},{"t":7}]},{"t":15,"i":2,"l":2,"a":[{"t":1,"s":"hello world"},{"t":1,"s":"\\x3Cscript>Hello World\\x3C/script>"}]},{"t":15,"i":3,"l":2,"a":[{"t":2,"s":true},{"t":2,"s":false}]},{"t":3},{"t":4},{"t":9,"s":"9007199254740991"},{"t":15,"i":4,"l":5,"a":[null,null,null,{"t":10,"i":4},{"t":14,"i":5,"d":{"k":[{"t":1,"s":"hello"},{"t":1,"s":"self"},{"t":1,"s":"mutual"}],"v":[{"t":1,"s":"world"},{"t":10,"i":5},{"t":13,"i":6,"l":4,"a":[{"t":1,"s":"hello"},{"t":1,"s":"world"},{"t":10,"i":6},{"t":10,"i":4}]}],"s":3}}]},{"t":12,"i":7,"c":"[a-z0-9]+","m":"i"},{"t":11,"i":8,"s":"2023-03-22T02:55:33.504Z"},{"t":10,"i":5},{"t":10,"i":6},{"t":10,"i":0}],"s":12}},"r":0,"i":true,"f":8191,"m":[4,5,6,0]}
153
- ```
154
-
155
- Then you can feed it to `fromJSON`:
156
-
157
- ```js
158
- import { fromJSON } from 'seroval';
159
-
160
- const revived = fromJSON(result);
161
- ```
162
-
163
- Alternatively, if you want to compile the JSON output to JS (like `deserialize`), you can use `compileJSON`
164
-
165
- ```js
166
- import { compileJSON, deserialize } from 'seroval';
167
-
168
- const code = compileJSON(result);
169
- const revived = deserialize(code);
170
- ```
171
-
172
- ## Promise serialization
173
-
174
- `seroval` allows Promise serialization through `serializeAsync` and `toJSONAsync`.
175
-
176
- ```js
177
- import { serializeAsync } from 'seroval';
178
-
179
- const value = Promise.resolve(100);
180
-
181
- const result = await serializeAsync(value); // "Promise.resolve(100)"
182
-
183
- console.log(await deserialize(result)); // 100
184
- ```
185
-
186
- > **Note**
187
- > `seroval` can only serialize the resolved value and so the output will always be using `Promise.resolve`. If the Promise fulfills with rejection, the rejected value is thrown before serialization happens.
188
-
189
- ## Serializable references
190
-
191
- There are values that has no way to be serializable at all, i.e. functions, but usually in an isomorphic code, functions can exist on both client and server-side. What if we can serialize these functions in such a way we can refer to their counterparts?
192
-
193
- `seroval` has `createReference` that you can use to map user-defined strings to their references.
194
-
195
- ```js
196
- import { createReference } from 'seroval';
197
-
198
- const thisIsAnIsomorphicFunction = createReference(
199
- // This is (ideally) a unique identifier
200
- // that is used to map the serialized value
201
- // to its actual reference (and vice versa)
202
- 'my-function',
203
- () => {
204
- // Ideally this function should exist on both
205
- // server and client, but we want to add the ability
206
- // to serialize and deserialize this reference on
207
- // both sides
208
- }
209
- );
210
-
211
- // we can now serialize this
212
- const serialized = toJSON(thisIsAnIsomorphicFunction); // or any of the serializer
213
- thisIsAnIsomorphicFunction === fromJSON(serialized); // true
214
- ```
215
-
216
- > **Note**
217
- > It can only accept objects, functions and symbols and it doesn't actually
218
- > serialize their values but only the string you used to identify the reference
219
-
220
- ## Supports
221
-
222
- The following values are the only values accepted by `seroval`:
223
-
224
- - Exact values
225
- - `NaN`
226
- - `Infinity`
227
- - `-Infinity`
228
- - `-0`
229
- - Primitives
230
- - `number`
231
- - `string`
232
- - `boolean`
233
- - `null`
234
- - `undefined`
235
- - `bigint`
236
- - `Array` + holes
237
- - `Object`
238
- - `RegExp`
239
- - `Date`
240
- - `Map`
241
- - `Set`
242
- - `Object.create(null)`
243
- - `ArrayBuffer`
244
- - `DataView`
245
- - `TypedArray`
246
- - `Int8Array`
247
- - `Int16Array`
248
- - `Int32Array`
249
- - `Uint8Array`
250
- - `Uint16Array`
251
- - `Uint32Array`
252
- - `Uint8ClampedArray`
253
- - `Float32Array`
254
- - `Float64Array`
255
- - `BigInt64Array`
256
- - `BigUint64Array`
257
- - `Error`
258
- - `AggregateError`
259
- - `EvalError`
260
- - `RangeError`
261
- - `ReferenceError`
262
- - `SyntaxError`
263
- - `TypeError`
264
- - `URIError`
265
- - `Promise` (with `serializeAsync` and `toJSONAsync`)
266
- - [`Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol)
267
- - [Well-known symbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#static_properties)
268
- - Web API
269
- - [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL)
270
- - [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)
271
- - [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) (with `serializeAsync` and `toJSONAsync`)
272
- - [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) (with `serializeAsync` and `toJSONAsync`)
273
- - [`Headers`](https://developer.mozilla.org/en-US/docs/Web/API/Headers)
274
- - [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData)
275
- - If `FormData` has a `Blob`/`File` entry, it can only be serialized with `serializeAsync` and `toJSONAsync`
276
- - Cyclic references (both self and mutual)
277
- - Isomorphic references (a reference that exist on both the serializer and deserializer side)
278
-
279
- ## Compat
280
-
281
- `serialize`, `serializeAsync`, `toJSON` and `toJSONAsync` can accept a `{ disabledFeatures: number }` option. The `disabledFeatures` defines how the output code would look like when serialized by `serialize`, `serializeAsync` and `compileJSON`.
282
-
283
- ```js
284
- import { serialize, Feature } from 'seroval';
285
-
286
- const y = Object.create(null);
287
- y.self = y;
288
- y.example = 'Hello World';
289
-
290
- function serializeWithTarget(value, disabledFeatures) {
291
- const result = serialize(value, {
292
- disabledFeatures,
293
- });
294
- console.log(result);
295
- }
296
-
297
- serializeWithTarget(y, Feature.ArrowFunction | Feature.ObjectAssign);
298
- serializeWithTarget(y, 0);
299
- ```
300
-
301
- ```js
302
- (function(h){return (h=Object.create(null),h.self=h,h.example="Hello World",h)})()
303
- (h=>(h=Object.assign(Object.create(null),{example:"Hello World"}),h.self=h,h))()
304
- ```
305
-
306
- `disabledFeatures` uses bit flags for faster checking, so if you need to disable multiple features, you can use the logical OR symbol (`|`).
307
-
308
- Here's an `ES2017` flag:
309
-
310
- ```js
311
- import { serialize, Feature } from 'seroval';
312
-
313
- const ES2017FLAG =
314
- Feature.AggregateError // ES2021
315
- | Feature.BigInt // ES2020
316
- | Feature.BigIntTypedArray // ES2020;
317
-
318
- serialize(myValue, {
319
- disabledFeatures: ES2017FLAG,
320
- })
321
- ```
322
-
323
- By default, all feature flags are enabled. The following are the feature flags and their behavior when disabled:
324
-
325
- - [`AggregateError`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError)
326
- - Compiles down to `Error` instead.
327
- - [`ArrayPrototypeValues`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values)
328
- - Used for `Iterable`, uses `Symbol.iterator` instead.
329
- - [`ArrowFunction`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
330
- - Uses function expressions for top-level and for deferred `Promise` values
331
- - method shorthands (if `MethodShortand` is not set) or function expressions for `Iterable`.
332
- - [`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt)
333
- - Throws when attempted to use, includes `BigIntTypedArray`
334
- - Disables use of `BigInt`, `BigInt64Array` and `BigUint64Array`
335
- - [`ErrorPrototypeStack`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/stack)
336
- - Skipped when detected.
337
- - Affects both `Error` and `AggregateError`
338
- - [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)
339
- - Throws when attempted to use.
340
- - Disables serialization of `Map`
341
- - [`MethodShorthand`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions)
342
- - Uses function expressions instead.
343
- - Only affects `Iterable`
344
- - [`ObjectAssign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
345
- - Uses manual object assignments instead.
346
- - Affects `Iterable`, `Error`, `AggregateError` and `Object.create(null)`
347
- - [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
348
- - Throws when attempted to use in `serializeAsync` and `toJSONAsync`.
349
- - Disables serialization of `Promise`
350
- - [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set)
351
- - Throws when attempted to use.
352
- - Disables serialization of `Set`
353
- - [`Symbol`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol)
354
- - Throws when attempted to use.
355
- - This disables serialization of well-known symbols and `Iterable`.
356
- - [`TypedArray`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray)
357
- - Throws when attempted to use.
358
- - Disables serialization of `TypedArray`
359
- - [`BigIntTypedArray`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt64Array)
360
- - Throws when attempted to use
361
- - Also throws if `BigInt` is disabled.
362
- - Disables serialization of `BigInt64Array` and `BigUint64Array`
363
- - `WebAPI`
364
- - Throws and disables the following usage:
365
- - [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL)
366
- - [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)
367
- - [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)
368
- - [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File)
369
- - [`Headers`](https://developer.mozilla.org/en-US/docs/Web/API/Headers)
370
- - [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData)
85
+ - [Serialization](https://github.com/lxsmnsyc/seroval/blob/main/docs/serialization.md)
86
+ - [Compatibility](https://github.com/lxsmnsyc/seroval/blob/main/docs/compatibility.md)
87
+ - [Isomorphic References](https://github.com/lxsmnsyc/seroval/blob/main/docs/isomorphic-refs.md)
371
88
 
372
89
  ## Sponsors
373
90