seroval 0.7.0 → 0.9.0

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 (42) hide show
  1. package/dist/cjs/development/index.cjs +1247 -1069
  2. package/dist/cjs/development/index.cjs.map +4 -4
  3. package/dist/cjs/production/index.cjs +3 -3
  4. package/dist/esm/development/index.mjs +1247 -1069
  5. package/dist/esm/development/index.mjs.map +4 -4
  6. package/dist/esm/production/index.mjs +3 -3
  7. package/dist/types/assert.d.ts +1 -1
  8. package/dist/types/context.d.ts +8 -2
  9. package/dist/types/index.d.ts +3 -4
  10. package/dist/types/string.d.ts +1 -1
  11. package/dist/types/tree/UnsupportedTypeError.d.ts +3 -0
  12. package/dist/types/tree/async.d.ts +3 -3
  13. package/dist/types/tree/constants.d.ts +11 -0
  14. package/dist/types/tree/deserialize.d.ts +2 -2
  15. package/dist/types/tree/primitives.d.ts +9 -15
  16. package/dist/types/tree/serialize.d.ts +2 -2
  17. package/dist/types/tree/shared.d.ts +12 -8
  18. package/dist/types/tree/sync.d.ts +3 -3
  19. package/dist/types/tree/types.d.ts +74 -71
  20. package/dist/types/tree/web-api.d.ts +2 -2
  21. package/dist/types/types.d.ts +4 -4
  22. package/package.json +11 -9
  23. package/src/assert.ts +2 -2
  24. package/src/compat.ts +0 -1
  25. package/src/context.ts +20 -7
  26. package/src/get-identifier.ts +1 -1
  27. package/src/index.ts +35 -26
  28. package/src/string.ts +2 -2
  29. package/src/tree/UnsupportedTypeError.ts +8 -0
  30. package/src/tree/async.ts +256 -233
  31. package/src/tree/constants.ts +73 -0
  32. package/src/tree/deserialize.ts +112 -93
  33. package/src/tree/primitives.ts +93 -134
  34. package/src/tree/reference.ts +3 -3
  35. package/src/tree/serialize.ts +307 -201
  36. package/src/tree/shared.ts +45 -22
  37. package/src/tree/symbols.ts +13 -13
  38. package/src/tree/sync.ts +236 -198
  39. package/src/tree/types.ts +87 -94
  40. package/src/tree/web-api.ts +14 -7
  41. package/src/types.ts +7 -3
  42. package/src/tree/iterator.ts +0 -14
package/src/context.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { ALL_ENABLED } from './compat';
2
2
  import getIdentifier from './get-identifier';
3
+ import type { SerovalObjectFlags } from './tree/types';
3
4
 
4
5
  interface IndexAssignment {
5
6
  t: 'index';
@@ -42,21 +43,29 @@ export interface ParserContext {
42
43
  features: number;
43
44
  }
44
45
 
46
+ export interface FlaggedObject {
47
+ type: SerovalObjectFlags;
48
+ value: string;
49
+ }
50
+
45
51
  export interface SerializationContext {
46
52
  stack: number[];
47
53
  // Map tree refs to actual refs
48
- validRefs: number[];
54
+ validRefs: (number | undefined)[];
49
55
  refSize: number;
50
56
  // Refs that are...referenced
51
57
  markedRefs: Set<number>;
52
58
  // Variables
53
- vars: string[];
59
+ vars: (string | undefined)[];
54
60
  // Array of assignments to be done (used for recursion)
55
61
  assignments: Assignment[];
56
62
  // Supported features
57
63
  features: number;
58
64
 
59
65
  valueMap: Map<number, unknown>;
66
+
67
+ // Object flags
68
+ flags: FlaggedObject[];
60
69
  }
61
70
 
62
71
  export interface Options {
@@ -69,7 +78,7 @@ const DEFAULT_OPTIONS: Options = {
69
78
 
70
79
  export function createParserContext(options: Partial<Options> = {}): ParserContext {
71
80
  // eslint-disable-next-line prefer-object-spread
72
- const result = Object.assign({}, DEFAULT_OPTIONS, options || {});
81
+ const result = Object.assign({}, DEFAULT_OPTIONS, options);
73
82
  return {
74
83
  markedRefs: new Set(),
75
84
  refs: new Map(),
@@ -92,20 +101,24 @@ export function createSerializationContext(options: SerializationOptions): Seria
92
101
  features: options.features,
93
102
  markedRefs: new Set(options.markedRefs),
94
103
  valueMap: new Map(),
104
+ flags: [],
95
105
  };
96
106
  }
97
107
 
98
108
  /**
99
109
  * Increments the number of references the referenced value has
100
110
  */
101
- export function markRef(ctx: ParserContext | SerializationContext, current: number) {
111
+ export function markRef(
112
+ ctx: ParserContext | SerializationContext,
113
+ current: number,
114
+ ): void {
102
115
  ctx.markedRefs.add(current);
103
116
  }
104
117
  /**
105
118
  * Creates the reference param (identifier) from the given reference ID
106
119
  * Calling this function means the value has been referenced somewhere
107
120
  */
108
- export function getRefParam(ctx: SerializationContext, index: number) {
121
+ export function getRefParam(ctx: SerializationContext, index: number): string {
109
122
  /**
110
123
  * Creates a new reference ID from a given reference ID
111
124
  * This new reference ID means that the reference itself
@@ -128,7 +141,7 @@ export function getRefParam(ctx: SerializationContext, index: number) {
128
141
  export function getRootID<T>(
129
142
  ctx: ParserContext,
130
143
  current: T,
131
- ) {
144
+ ): number {
132
145
  const ref = ctx.refs.get(current);
133
146
  if (ref == null) {
134
147
  return ctx.refs.size;
@@ -139,7 +152,7 @@ export function getRootID<T>(
139
152
  export function createIndexedValue<T>(
140
153
  ctx: ParserContext,
141
154
  current: T,
142
- ) {
155
+ ): number {
143
156
  const ref = ctx.refs.get(current);
144
157
  if (ref == null) {
145
158
  const id = ctx.refs.size;
@@ -4,7 +4,7 @@ const REF_START_CHARS_LEN = REF_START_CHARS.length;
4
4
  const REF_CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$_';
5
5
  const REF_CHARS_LEN = REF_CHARS.length;
6
6
 
7
- export default function getIdentifier(index: number) {
7
+ export default function getIdentifier(index: number): string {
8
8
  let mod = index % REF_START_CHARS_LEN;
9
9
  let ref = REF_START_CHARS[mod];
10
10
  index = (index - mod) / REF_START_CHARS_LEN;
package/src/index.ts CHANGED
@@ -1,19 +1,23 @@
1
1
  /* eslint-disable no-await-in-loop */
2
2
  import { Feature } from './compat';
3
- import {
3
+ import type {
4
4
  SerializationContext,
5
- getRefParam,
6
5
  Options,
6
+ } from './context';
7
+ import {
8
+ getRefParam,
7
9
  createParserContext,
8
10
  createSerializationContext,
11
+ getRootID,
9
12
  } from './context';
13
+ import parseSync from './tree/sync';
10
14
  import parseAsync from './tree/async';
11
15
  import deserializeTree from './tree/deserialize';
12
16
  import serializeTree, { resolvePatches } from './tree/serialize';
13
- import parseSync from './tree/sync';
14
- import { SerovalNode } from './tree/types';
17
+ import type { SerovalNode } from './tree/types';
18
+ import { SerovalNodeType } from './tree/types';
15
19
 
16
- export {
20
+ export type {
17
21
  AsyncServerValue,
18
22
  ServerValue,
19
23
  PrimitiveValue,
@@ -28,7 +32,7 @@ function finalize(
28
32
  rootID: number,
29
33
  isObject: boolean,
30
34
  result: string,
31
- ) {
35
+ ): string {
32
36
  // Shared references detected
33
37
  if (ctx.vars.length) {
34
38
  const patches = resolvePatches(ctx);
@@ -62,23 +66,33 @@ function finalize(
62
66
  export function serialize<T>(
63
67
  source: T,
64
68
  options?: Partial<Options>,
65
- ) {
69
+ ): string {
66
70
  const ctx = createParserContext(options);
67
- const [tree, rootID, isObject] = parseSync(ctx, source);
71
+ const tree = parseSync(ctx, source);
68
72
  const serial = createSerializationContext(ctx);
69
73
  const result = serializeTree(serial, tree);
70
- return finalize(serial, rootID, isObject, result);
74
+ return finalize(
75
+ serial,
76
+ getRootID(ctx, source),
77
+ tree.t === SerovalNodeType.Object,
78
+ result,
79
+ );
71
80
  }
72
81
 
73
82
  export async function serializeAsync<T>(
74
83
  source: T,
75
84
  options?: Partial<Options>,
76
- ) {
85
+ ): Promise<string> {
77
86
  const ctx = createParserContext(options);
78
- const [tree, rootID, isObject] = await parseAsync(ctx, source);
87
+ const tree = await parseAsync(ctx, source);
79
88
  const serial = createSerializationContext(ctx);
80
89
  const result = serializeTree(serial, tree);
81
- return finalize(serial, rootID, isObject, result);
90
+ return finalize(
91
+ serial,
92
+ getRootID(ctx, source),
93
+ tree.t === SerovalNodeType.Object,
94
+ result,
95
+ );
82
96
  }
83
97
 
84
98
  export function deserialize<T>(source: string): T {
@@ -87,11 +101,10 @@ export function deserialize<T>(source: string): T {
87
101
  }
88
102
 
89
103
  export interface SerovalJSON {
90
- t: SerovalNode,
91
- r: number,
92
- i: boolean,
93
- f: number,
94
- m: number[],
104
+ t: SerovalNode;
105
+ r: number;
106
+ f: number;
107
+ m: number[];
95
108
  }
96
109
 
97
110
  export function toJSON<T>(
@@ -99,11 +112,9 @@ export function toJSON<T>(
99
112
  options?: Partial<Options>,
100
113
  ): SerovalJSON {
101
114
  const ctx = createParserContext(options);
102
- const [tree, root, isObject] = parseSync(ctx, source);
103
115
  return {
104
- t: tree,
105
- r: root,
106
- i: isObject,
116
+ t: parseSync(ctx, source),
117
+ r: getRootID(ctx, source),
107
118
  f: ctx.features,
108
119
  m: Array.from(ctx.markedRefs),
109
120
  };
@@ -114,11 +125,9 @@ export async function toJSONAsync<T>(
114
125
  options?: Partial<Options>,
115
126
  ): Promise<SerovalJSON> {
116
127
  const ctx = createParserContext(options);
117
- const [tree, root, isObject] = await parseAsync(ctx, source);
118
128
  return {
119
- t: tree,
120
- r: root,
121
- i: isObject,
129
+ t: await parseAsync(ctx, source),
130
+ r: getRootID(ctx, source),
122
131
  f: ctx.features,
123
132
  m: Array.from(ctx.markedRefs),
124
133
  };
@@ -130,7 +139,7 @@ export function compileJSON(source: SerovalJSON): string {
130
139
  markedRefs: source.m,
131
140
  });
132
141
  const result = serializeTree(serial, source.t);
133
- return finalize(serial, source.r, source.i, result);
142
+ return finalize(serial, source.r, source.t.i === SerovalNodeType.Object, result);
134
143
  }
135
144
 
136
145
  export function fromJSON<T>(source: SerovalJSON): T {
package/src/string.ts CHANGED
@@ -1,4 +1,4 @@
1
- export function serializeChar(str: string) {
1
+ export function serializeChar(str: string): string | undefined {
2
2
  switch (str) {
3
3
  case '"': return '\\"';
4
4
  case '\\': return '\\\\';
@@ -19,7 +19,7 @@ export function serializeChar(str: string) {
19
19
  // not listed as DoubleStringCharacters on
20
20
  // Also includes "<" to escape "</script>" and "\" to avoid invalid escapes in the output.
21
21
  // http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.4
22
- export function serializeString(str: string) {
22
+ export function serializeString(str: string): string {
23
23
  let result = '';
24
24
  let lastPos = 0;
25
25
  let replacement: string | undefined;
@@ -0,0 +1,8 @@
1
+ // eslint-disable-next-line @typescript-eslint/unbound-method
2
+ const { toString } = Object.prototype;
3
+
4
+ export default class UnsupportedTypeError extends Error {
5
+ constructor(value: unknown) {
6
+ super('Unsupported type "' + toString.call(value) + '"');
7
+ }
8
+ }