seroval 0.4.0-alpha.8 → 0.4.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.
package/src/context.ts CHANGED
@@ -1,23 +1,25 @@
1
- import { parseTargets } from './compat';
1
+ import { ALL_ENABLED } from './compat';
2
2
  import getIdentifier from './get-identifier';
3
3
 
4
4
  interface IndexAssignment {
5
- type: 'index';
6
- source: string;
7
- value: string;
5
+ t: 'index';
6
+ s: string;
7
+ k: undefined;
8
+ v: string;
8
9
  }
9
10
 
10
11
  interface MapAssignment {
11
- type: 'map';
12
- source: string;
13
- key: string;
14
- value: string;
12
+ t: 'map';
13
+ s: string;
14
+ k: string;
15
+ v: string;
15
16
  }
16
17
 
17
18
  interface SetAssignment {
18
- type: 'set';
19
- source: string;
20
- value: string;
19
+ t: 'set';
20
+ s: string;
21
+ k: undefined;
22
+ v: string;
21
23
  }
22
24
 
23
25
  // Array of assignments to be done (used for recursion)
@@ -28,7 +30,7 @@ export type Assignment =
28
30
 
29
31
  export interface ParserContext {
30
32
  refs: Map<unknown, number>;
31
- markedRefs: Record<number, number>;
33
+ markedRefs: Set<number>;
32
34
  features: number;
33
35
  }
34
36
 
@@ -38,7 +40,7 @@ export interface SerializationContext {
38
40
  validRefs: number[];
39
41
  refSize: number;
40
42
  // Refs that are...referenced
41
- markedRefs: Record<number, number>;
43
+ markedRefs: Set<number>;
42
44
  // Variables
43
45
  vars: string[];
44
46
  // Array of assignments to be done (used for recursion)
@@ -48,25 +50,25 @@ export interface SerializationContext {
48
50
  }
49
51
 
50
52
  export interface Options {
51
- target: string | string[];
53
+ disabledFeatures: number;
52
54
  }
53
55
 
54
56
  const DEFAULT_OPTIONS: Options = {
55
- target: 'es2023',
57
+ disabledFeatures: 0,
56
58
  };
57
59
 
58
60
  export function createParserContext(options: Partial<Options> = {}): ParserContext {
59
61
  // eslint-disable-next-line prefer-object-spread
60
62
  const result = Object.assign({}, DEFAULT_OPTIONS, options || {});
61
63
  return {
62
- markedRefs: {},
64
+ markedRefs: new Set(),
63
65
  refs: new Map(),
64
- features: parseTargets(result.target),
66
+ features: ALL_ENABLED ^ result.disabledFeatures,
65
67
  };
66
68
  }
67
69
 
68
70
  export interface SerializationOptions {
69
- markedRefs: Record<number, number>;
71
+ markedRefs: number[] | Set<number>;
70
72
  features: number;
71
73
  }
72
74
 
@@ -78,7 +80,7 @@ export function createSerializationContext(options: SerializationOptions): Seria
78
80
  validRefs: [],
79
81
  refSize: 0,
80
82
  features: options.features,
81
- markedRefs: options.markedRefs,
83
+ markedRefs: new Set(options.markedRefs),
82
84
  };
83
85
  }
84
86
 
@@ -86,7 +88,7 @@ export function createSerializationContext(options: SerializationOptions): Seria
86
88
  * Increments the number of references the referenced value has
87
89
  */
88
90
  export function markRef(ctx: ParserContext | SerializationContext, current: number) {
89
- ctx.markedRefs[current] = 1;
91
+ ctx.markedRefs.add(current);
90
92
  }
91
93
 
92
94
  /**
@@ -127,13 +129,22 @@ export function getRefParam(ctx: SerializationContext, index: number) {
127
129
  */
128
130
  export function createRef(
129
131
  ctx: ParserContext,
130
- index: unknown,
131
- ) {
132
- const current = ctx.refs.get(index);
133
- if (current != null) {
134
- return current;
132
+ current: unknown,
133
+ mark: boolean,
134
+ ): number {
135
+ // Check if reference number already exists
136
+ const ref = ctx.refs.get(current);
137
+ if (ref != null) {
138
+ // Exists, means this value is currently
139
+ // being referenced
140
+ // Mark reference
141
+ if (mark) {
142
+ markRef(ctx, ref);
143
+ }
144
+ return ref;
135
145
  }
146
+ // Create a new reference ID
136
147
  const id = ctx.refs.size;
137
- ctx.refs.set(index, id);
148
+ ctx.refs.set(current, id);
138
149
  return id;
139
150
  }
package/src/index.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  /* eslint-disable no-await-in-loop */
2
- import { isPrimitive } from './checks';
3
2
  import { Feature } from './compat';
4
3
  import {
5
4
  SerializationContext,
@@ -10,7 +9,6 @@ import {
10
9
  } from './context';
11
10
  import parseAsync from './tree/async';
12
11
  import serializeTree, { resolvePatches } from './tree/serialize';
13
- import { serializePrimitive } from './tree/shared';
14
12
  import parseSync from './tree/sync';
15
13
  import { SerovalNode } from './tree/types';
16
14
  import {
@@ -29,6 +27,7 @@ export {
29
27
  CommonServerValue,
30
28
  SemiPrimitiveValue,
31
29
  ErrorValue,
30
+ Feature,
32
31
  };
33
32
 
34
33
  function finalize(
@@ -44,10 +43,9 @@ function finalize(
44
43
  if (patches) {
45
44
  // Get (or create) a ref from the source
46
45
  const index = getRefParam(ctx, rootID);
47
- if (result.startsWith(`${index}=`)) {
48
- body = `${result},${patches}${index}`;
49
- } else {
50
- body = `${index}=${result},${patches}${index}`;
46
+ body = result + ',' + patches + index;
47
+ if (!result.startsWith(index + '=')) {
48
+ body = index + '=' + body;
51
49
  }
52
50
  }
53
51
  let params = ctx.vars.length > 1
@@ -56,14 +54,14 @@ function finalize(
56
54
  // Source is probably already assigned
57
55
  if (ctx.features & Feature.ArrowFunction) {
58
56
  params = ctx.vars.length > 1 || ctx.vars.length === 0
59
- ? `(${params})`
57
+ ? '(' + params + ')'
60
58
  : params;
61
- return `(${params}=>(${body}))()`;
59
+ return '(' + params + '=>(' + body + '))()';
62
60
  }
63
- return `(function(${params}){return ${body}})()`;
61
+ return '(function(' + params + '){return ' + body + '})()';
64
62
  }
65
63
  if (isObject) {
66
- return `(${result})`;
64
+ return '(' + result + ')';
67
65
  }
68
66
  return result;
69
67
  }
@@ -73,9 +71,6 @@ export function serialize<T extends ServerValue>(
73
71
  options?: Partial<Options>,
74
72
  ) {
75
73
  const ctx = createParserContext(options);
76
- if (isPrimitive(source)) {
77
- return String(serializePrimitive(source));
78
- }
79
74
  const [tree, rootID, isObject] = parseSync(ctx, source);
80
75
  const serial = createSerializationContext(ctx);
81
76
  const result = serializeTree(serial, tree);
@@ -87,9 +82,6 @@ export async function serializeAsync<T extends AsyncServerValue>(
87
82
  options?: Partial<Options>,
88
83
  ) {
89
84
  const ctx = createParserContext(options);
90
- if (isPrimitive(source)) {
91
- return String(serializePrimitive(source));
92
- }
93
85
  const [tree, rootID, isObject] = await parseAsync(ctx, source);
94
86
  const serial = createSerializationContext(ctx);
95
87
  const result = serializeTree(serial, tree);
@@ -101,13 +93,13 @@ export function deserialize<T extends AsyncServerValue>(source: string): T {
101
93
  return (0, eval)(source) as T;
102
94
  }
103
95
 
104
- type SerovalJSON = [
105
- tree: SerovalNode,
106
- root: number,
107
- isObject: boolean,
108
- feature: number,
109
- markedRefs: Record<number, number>,
110
- ];
96
+ interface SerovalJSON {
97
+ t: SerovalNode,
98
+ r: number,
99
+ i: boolean,
100
+ f: number,
101
+ m: number[],
102
+ }
111
103
 
112
104
  export function toJSON<T extends ServerValue>(
113
105
  source: T,
@@ -115,13 +107,13 @@ export function toJSON<T extends ServerValue>(
115
107
  ) {
116
108
  const ctx = createParserContext(options);
117
109
  const [tree, root, isObject] = parseSync(ctx, source);
118
- return JSON.stringify([
119
- tree,
120
- root,
121
- isObject,
122
- ctx.features,
123
- ctx.markedRefs,
124
- ]);
110
+ return JSON.stringify({
111
+ t: tree,
112
+ r: root,
113
+ i: isObject,
114
+ f: ctx.features,
115
+ m: Array.from(ctx.markedRefs),
116
+ });
125
117
  }
126
118
 
127
119
  export async function toJSONAsync<T extends AsyncServerValue>(
@@ -130,23 +122,23 @@ export async function toJSONAsync<T extends AsyncServerValue>(
130
122
  ) {
131
123
  const ctx = createParserContext(options);
132
124
  const [tree, root, isObject] = await parseAsync(ctx, source);
133
- return JSON.stringify([
134
- tree,
135
- root,
136
- isObject,
137
- ctx.features,
138
- ctx.markedRefs,
139
- ]);
125
+ return JSON.stringify({
126
+ t: tree,
127
+ r: root,
128
+ i: isObject,
129
+ f: ctx.features,
130
+ m: Array.from(ctx.markedRefs),
131
+ });
140
132
  }
141
133
 
142
134
  export function compileJSON(source: string): string {
143
135
  const parsed = JSON.parse(source) as SerovalJSON;
144
136
  const serial = createSerializationContext({
145
- features: parsed[3],
146
- markedRefs: parsed[4],
137
+ features: parsed.f,
138
+ markedRefs: parsed.m,
147
139
  });
148
- const result = serializeTree(serial, parsed[0]);
149
- return finalize(serial, parsed[1], parsed[2], result);
140
+ const result = serializeTree(serial, parsed.t);
141
+ return finalize(serial, parsed.r, parsed.i, result);
150
142
  }
151
143
 
152
144
  export function fromJSON<T extends AsyncServerValue>(source: string): T {
package/src/quote.ts CHANGED
@@ -41,5 +41,5 @@ export default function quote(str: string) {
41
41
  } else {
42
42
  result += str.slice(lastPos);
43
43
  }
44
- return `"${result}"`;
44
+ return '"' + result + '"';
45
45
  }