seroval 0.4.0-alpha.6 → 0.4.0-alpha.7

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.
@@ -145,7 +145,7 @@ function createMapSet(
145
145
  function createArrayAssign(
146
146
  ctx: SerializationContext,
147
147
  ref: number,
148
- index: number,
148
+ index: number | string,
149
149
  value: string,
150
150
  ) {
151
151
  markRef(ctx, ref);
@@ -157,11 +157,9 @@ function createObjectAssign(
157
157
  ref: number,
158
158
  key: string,
159
159
  value: string,
160
- computed: boolean,
161
160
  ) {
162
161
  markRef(ctx, ref);
163
- const member = computed ? `[${key}]` : `.${key}`;
164
- createAssignment(ctx, `${getRefParam(ctx, ref)}${member}`, value);
162
+ createAssignment(ctx, `${getRefParam(ctx, ref)}.${key}`, value);
165
163
  }
166
164
 
167
165
  const IDENTIFIER_CHECK = /^([$A-Z_][0-9A-Z_$]*)$/i;
@@ -169,59 +167,59 @@ const IDENTIFIER_CHECK = /^([$A-Z_][0-9A-Z_$]*)$/i;
169
167
  function serializeAssignments(
170
168
  ctx: SerializationContext,
171
169
  targetRef: number,
172
- record: SerovalDictionaryNode,
170
+ [keys, values, size]: SerovalDictionaryNode,
173
171
  ) {
174
172
  ctx.stack.push(targetRef);
175
173
  const mainAssignments: Assignment[] = [];
176
- for (const key of Object.keys(record)) {
174
+ for (let i = 0; i < size; i++) {
177
175
  const parentStack = ctx.stack;
178
176
  ctx.stack = [];
179
- const refParam = serializeTree(ctx, record[key]);
177
+ const refParam = serializeTree(ctx, values[i]);
180
178
  ctx.stack = parentStack;
179
+ const key = keys[i];
181
180
  const check = Number(key);
182
181
  const parentAssignment = ctx.assignments;
183
182
  ctx.assignments = mainAssignments;
184
183
  // Test if key is a valid number or JS identifier
185
184
  // so that we don't have to serialize the key and wrap with brackets
186
185
  const isIdentifier = check >= 0 || IDENTIFIER_CHECK.test(key);
187
- createObjectAssign(
188
- ctx,
189
- targetRef,
190
- isIdentifier ? key : quote(key),
191
- refParam,
192
- !(isIdentifier && Number.isNaN(check)),
193
- );
186
+ if (isIdentifier && Number.isNaN(check)) {
187
+ createObjectAssign(ctx, targetRef, key, refParam);
188
+ } else {
189
+ createArrayAssign(ctx, targetRef, isIdentifier ? key : quote(key), refParam);
190
+ }
194
191
  ctx.assignments = parentAssignment;
195
192
  }
196
193
  ctx.stack.pop();
197
194
  return resolveAssignments(mainAssignments);
198
195
  }
199
196
 
200
- function serializeDictionary(
197
+ function serializeObject(
201
198
  ctx: SerializationContext,
202
199
  sourceID: number,
203
- record: SerovalDictionaryNode,
200
+ [keys, values, size]: SerovalDictionaryNode,
204
201
  ) {
202
+ if (size === 0) {
203
+ return '{}';
204
+ }
205
205
  let result = '';
206
206
  ctx.stack.push(sourceID);
207
- for (const key of Object.keys(record)) {
208
- const val = record[key];
207
+ for (let i = 0; i < size; i++) {
208
+ const key = keys[i];
209
+ const val = values[i];
209
210
  const check = Number(key);
210
211
  // Test if key is a valid number or JS identifier
211
212
  // so that we don't have to serialize the key and wrap with brackets
212
213
  const isIdentifier = check >= 0 || IDENTIFIER_CHECK.test(key);
213
- const validKey = isIdentifier ? key : quote(key);
214
214
  if (isReferenceInStack(ctx, val)) {
215
215
  const refParam = getRefParam(ctx, val[1]);
216
- createObjectAssign(
217
- ctx,
218
- sourceID,
219
- validKey,
220
- refParam,
221
- !(isIdentifier && Number.isNaN(check)),
222
- );
216
+ if (isIdentifier && Number.isNaN(check)) {
217
+ createObjectAssign(ctx, sourceID, key, refParam);
218
+ } else {
219
+ createArrayAssign(ctx, sourceID, isIdentifier ? key : quote(key), refParam);
220
+ }
223
221
  } else {
224
- result += `${validKey}:${serializeTree(ctx, val)},`;
222
+ result += `${isIdentifier ? key : quote(key)}:${serializeTree(ctx, val)},`;
225
223
  }
226
224
  }
227
225
  ctx.stack.pop();
@@ -400,7 +398,7 @@ function serializeWithObjectAssign(
400
398
  id: number,
401
399
  serialized: string,
402
400
  ) {
403
- const fields = serializeDictionary(ctx, id, value);
401
+ const fields = serializeObject(ctx, id, value);
404
402
  if (fields !== '{}') {
405
403
  return `Object.assign(${serialized},${fields})`;
406
404
  }
@@ -551,7 +549,7 @@ export default function serializeTree(
551
549
  case SerovalNodeType.NullConstructor:
552
550
  return serializeNullConstructor(ctx, value, id);
553
551
  case SerovalNodeType.Object:
554
- return assignRef(ctx, id, serializeDictionary(ctx, id, value));
552
+ return assignRef(ctx, id, serializeObject(ctx, id, value));
555
553
  default:
556
554
  throw new Error('Unsupported type');
557
555
  }
package/src/tree/sync.ts CHANGED
@@ -24,24 +24,34 @@ import {
24
24
  SerovalSetNode,
25
25
  } from './types';
26
26
 
27
- function generateDictionary(
27
+ function serializePropertiesSync(
28
28
  ctx: ParserContext,
29
- properties: Record<string, ServerValue>,
29
+ properties: Record<string, unknown>,
30
30
  ): SerovalDictionaryNode {
31
31
  const keys = Object.keys(properties);
32
- const nodes: SerovalDictionaryNode = {};
33
- const deferred: Record<string, ServerValue> = {};
32
+ const size = keys.length;
33
+ const keyNodes = new Array<string>(size);
34
+ const valueNodes = new Array<SerovalNode>(size);
35
+ const deferredKeys = new Array<string>(size);
36
+ const deferredValues = new Array<ServerValue>(size);
37
+ let deferredSize = 0;
38
+ let nodesSize = 0;
34
39
  for (const key of keys) {
35
40
  if (isIterable(properties[key])) {
36
- deferred[key] = properties[key];
41
+ deferredKeys[deferredSize] = key;
42
+ deferredValues[deferredSize] = properties[key] as ServerValue;
43
+ deferredSize++;
37
44
  } else {
38
- nodes[key] = generateTreeSync(ctx, properties[key]);
45
+ keyNodes[nodesSize] = key;
46
+ valueNodes[nodesSize] = generateTreeSync(ctx, properties[key] as ServerValue);
47
+ nodesSize++;
39
48
  }
40
49
  }
41
- for (const key of Object.keys(deferred)) {
42
- nodes[key] = generateTreeSync(ctx, deferred[key]);
50
+ for (let i = 0; i < deferredSize; i++) {
51
+ keyNodes[nodesSize + i] = deferredKeys[i];
52
+ valueNodes[nodesSize + i] = generateTreeSync(ctx, deferredValues[i]);
43
53
  }
44
- return nodes;
54
+ return [keyNodes, valueNodes, size];
45
55
  }
46
56
 
47
57
  function generateSetNode(
@@ -141,7 +151,7 @@ function generateAggregateErrorNode(
141
151
  ): SerovalAggregateErrorNode {
142
152
  const options = getErrorOptions(current);
143
153
  const optionsNode = options
144
- ? generateDictionary(ctx, options)
154
+ ? serializePropertiesSync(ctx, options)
145
155
  : undefined;
146
156
  const errorsNode = generateTreeSync(ctx, current.errors as ServerValue);
147
157
  return [SerovalNodeType.AggregateError, [current.message, optionsNode, errorsNode], id];
@@ -154,7 +164,7 @@ function generateErrorNode(
154
164
  ): SerovalErrorNode {
155
165
  const options = getErrorOptions(current);
156
166
  const optionsNode = options
157
- ? generateDictionary(ctx, options)
167
+ ? serializePropertiesSync(ctx, options)
158
168
  : undefined;
159
169
  return [
160
170
  SerovalNodeType.Error,
@@ -172,9 +182,7 @@ function generateIterableNode(
172
182
  const options = getIterableOptions(current);
173
183
  return [SerovalNodeType.Iterable, [
174
184
  // Parse options first before the items
175
- options
176
- ? generateDictionary(ctx, options as Record<string, ServerValue>)
177
- : undefined,
185
+ options ? serializePropertiesSync(ctx, options) : undefined,
178
186
  generateNodeList(ctx, Array.from(current)),
179
187
  ], id];
180
188
  }
@@ -218,7 +226,7 @@ function generateTreeSync(
218
226
  if (current.constructor === Object || empty) {
219
227
  return [
220
228
  empty ? SerovalNodeType.NullConstructor : SerovalNodeType.Object,
221
- generateDictionary(ctx, current as Record<string, ServerValue>),
229
+ serializePropertiesSync(ctx, current as Record<string, unknown>),
222
230
  id,
223
231
  ];
224
232
  }
package/src/tree/types.ts CHANGED
@@ -39,7 +39,7 @@ export type SerovalSemiPrimitiveNode =
39
39
  id: number
40
40
  ];
41
41
 
42
- export type SerovalDictionaryNode = Record<string, SerovalNode>;
42
+ export type SerovalDictionaryNode = [key: string[], value: SerovalNode[], size: number];
43
43
  export type SerovalSetNode = [type: SerovalNodeType.Set, value: SerovalNode[], id: number];
44
44
  export type SerovalMapNode = [
45
45
  type: SerovalNodeType.Map,