seroval 0.4.0-alpha.2 → 0.4.0-alpha.3

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/tree.ts CHANGED
@@ -540,27 +540,30 @@ function serializePropertiesSync(
540
540
  ctx: SerializationContext,
541
541
  properties: Record<string, unknown>,
542
542
  ): SerovalDictionaryNode {
543
- const keyNodes: string[] = [];
544
- const valueNodes: SerovalNode[] = [];
545
- const deferredKeys: string[] = [];
546
- const deferredValues: ServerValue[] = [];
547
543
  const keys = Object.keys(properties);
544
+ const size = keys.length;
545
+ const keyNodes = new Array<string>(size);
546
+ const valueNodes = new Array<SerovalNode>(size);
547
+ const deferredKeys = new Array<string>(size);
548
+ const deferredValues = new Array<ServerValue>(size);
548
549
  let deferredSize = 0;
550
+ let nodesSize = 0;
549
551
  for (const key of keys) {
550
552
  if (isIterable(properties[key])) {
551
- deferredKeys.push(key);
552
- deferredValues.push(properties[key] as ServerValue);
553
+ deferredKeys[deferredSize] = key;
554
+ deferredValues[deferredSize] = properties[key] as ServerValue;
553
555
  deferredSize++;
554
556
  } else {
555
- keyNodes.push(key);
556
- valueNodes.push(generateTreeSync(ctx, properties[key] as ServerValue));
557
+ keyNodes[nodesSize] = key;
558
+ valueNodes[nodesSize] = generateTreeSync(ctx, properties[key] as ServerValue);
559
+ nodesSize++;
557
560
  }
558
561
  }
559
562
  for (let i = 0; i < deferredSize; i++) {
560
- keyNodes.push(deferredKeys[i]);
561
- valueNodes.push(generateTreeSync(ctx, deferredValues[i]));
563
+ keyNodes[nodesSize + i] = deferredKeys[i];
564
+ valueNodes[nodesSize + i] = generateTreeSync(ctx, deferredValues[i]);
562
565
  }
563
- return [keyNodes, valueNodes, keys.length];
566
+ return [keyNodes, valueNodes, size];
564
567
  }
565
568
 
566
569
  export function generateTreeSync(
@@ -582,45 +585,51 @@ export function generateTreeSync(
582
585
  }
583
586
  if (constructorCheck<Set<ServerValue>>(current, Set)) {
584
587
  assert(ctx.features.has(Feature.Set), 'Unsupported type "Set"');
585
- const nodes: SerovalNode[] = [];
586
- const deferred: ServerValue[] = [];
588
+ const len = current.size;
589
+ const nodes = new Array<SerovalNode>(len);
590
+ const deferred = new Array<ServerValue>(len);
591
+ let deferredSize = 0;
592
+ let nodeSize = 0;
587
593
  for (const item of current.keys()) {
588
594
  // Iterables are lazy, so the evaluation must be deferred
589
595
  if (isIterable(item)) {
590
- deferred.push(item);
596
+ deferred[deferredSize++] = item;
591
597
  } else {
592
- nodes.push(generateTreeSync(ctx, item));
598
+ nodes[nodeSize++] = generateTreeSync(ctx, item);
593
599
  }
594
600
  }
595
601
  // Parse deferred items
596
- for (let i = 0, len = deferred.length; i < len; i++) {
597
- nodes.push(generateTreeSync(ctx, deferred[i]));
602
+ for (let i = 0; i < deferredSize; i++) {
603
+ nodes[nodeSize + i] = generateTreeSync(ctx, deferred[i]);
598
604
  }
599
605
  return [SerovalNodeType.Set, nodes, id];
600
606
  }
601
607
  if (constructorCheck<Map<ServerValue, ServerValue>>(current, Map)) {
602
608
  assert(ctx.features.has(Feature.Map), 'Unsupported type "Map"');
603
- const keyNodes: SerovalNode[] = [];
604
- const valueNodes: SerovalNode[] = [];
605
- const deferredKey: ServerValue[] = [];
606
- const deferredValue: ServerValue[] = [];
609
+ const len = current.size;
610
+ const keyNodes = new Array<SerovalNode>(len);
611
+ const valueNodes = new Array<SerovalNode>(len);
612
+ const deferredKey = new Array<ServerValue>(len);
613
+ const deferredValue = new Array<ServerValue>(len);
607
614
  let deferredSize = 0;
615
+ let nodeSize = 0;
608
616
  for (const [key, value] of current.entries()) {
609
617
  // Either key or value might be an iterable
610
618
  if (isIterable(key) || isIterable(value)) {
611
- deferredKey.push(key);
612
- deferredValue.push(value);
619
+ deferredKey[deferredSize] = key;
620
+ deferredValue[deferredSize] = value;
613
621
  deferredSize++;
614
622
  } else {
615
- keyNodes.push(generateTreeSync(ctx, key));
616
- valueNodes.push(generateTreeSync(ctx, value));
623
+ keyNodes[nodeSize] = generateTreeSync(ctx, key);
624
+ valueNodes[nodeSize] = generateTreeSync(ctx, value);
625
+ nodeSize++;
617
626
  }
618
627
  }
619
628
  for (let i = 0; i < deferredSize; i++) {
620
- keyNodes.push(generateTreeSync(ctx, deferredKey[i]));
621
- valueNodes.push(generateTreeSync(ctx, deferredValue[i]));
629
+ keyNodes[nodeSize + i] = generateTreeSync(ctx, deferredKey[i]);
630
+ valueNodes[nodeSize + i] = generateTreeSync(ctx, deferredValue[i]);
622
631
  }
623
- return [SerovalNodeType.Map, [keyNodes, valueNodes, current.size], id];
632
+ return [SerovalNodeType.Map, [keyNodes, valueNodes, len], id];
624
633
  }
625
634
  if (Array.isArray(current)) {
626
635
  const size = current.length;
@@ -685,27 +694,30 @@ async function serializePropertiesAsync(
685
694
  ctx: SerializationContext,
686
695
  properties: Record<string, unknown>,
687
696
  ): Promise<SerovalDictionaryNode> {
688
- const keyNodes: string[] = [];
689
- const valueNodes: SerovalNode[] = [];
690
- const deferredKeys: string[] = [];
691
- const deferredValues: ServerValue[] = [];
692
697
  const keys = Object.keys(properties);
698
+ const size = keys.length;
699
+ const keyNodes = new Array<string>(size);
700
+ const valueNodes = new Array<SerovalNode>(size);
701
+ const deferredKeys = new Array<string>(size);
702
+ const deferredValues = new Array<ServerValue>(size);
693
703
  let deferredSize = 0;
704
+ let nodesSize = 0;
694
705
  for (const key of keys) {
695
706
  if (isIterable(properties[key])) {
696
- deferredKeys.push(key);
697
- deferredValues.push(properties[key] as ServerValue);
707
+ deferredKeys[deferredSize] = key;
708
+ deferredValues[deferredSize] = properties[key] as ServerValue;
698
709
  deferredSize++;
699
710
  } else {
700
- keyNodes.push(key);
701
- valueNodes.push(await generateTreeAsync(ctx, properties[key] as ServerValue));
711
+ keyNodes[nodesSize] = key;
712
+ valueNodes[nodesSize] = await generateTreeAsync(ctx, properties[key] as ServerValue);
713
+ nodesSize++;
702
714
  }
703
715
  }
704
716
  for (let i = 0; i < deferredSize; i++) {
705
- keyNodes.push(deferredKeys[i]);
706
- valueNodes.push(await generateTreeAsync(ctx, deferredValues[i]));
717
+ keyNodes[nodesSize + i] = deferredKeys[i];
718
+ valueNodes[nodesSize + i] = await generateTreeAsync(ctx, deferredValues[i]);
707
719
  }
708
- return [keyNodes, valueNodes, keys.length];
720
+ return [keyNodes, valueNodes, size];
709
721
  }
710
722
 
711
723
  export async function generateTreeAsync(
@@ -733,42 +745,51 @@ export async function generateTreeAsync(
733
745
  }
734
746
  if (constructorCheck<Set<AsyncServerValue>>(current, Set)) {
735
747
  assert(ctx.features.has(Feature.Set), 'Unsupported type "Set"');
736
- const nodes: SerovalNode[] = [];
737
- const deferred: AsyncServerValue[] = [];
748
+ const len = current.size;
749
+ const nodes = new Array<SerovalNode>(len);
750
+ const deferred = new Array<AsyncServerValue>(len);
751
+ let deferredSize = 0;
752
+ let nodeSize = 0;
738
753
  for (const item of current.keys()) {
754
+ // Iterables are lazy, so the evaluation must be deferred
739
755
  if (isIterable(item)) {
740
- deferred.push(item);
756
+ deferred[deferredSize++] = item;
741
757
  } else {
742
- nodes.push(await generateTreeAsync(ctx, item));
758
+ nodes[nodeSize++] = await generateTreeAsync(ctx, item);
743
759
  }
744
760
  }
745
- for (let i = 0, len = deferred.length; i < len; i++) {
746
- nodes.push(await generateTreeAsync(ctx, deferred[i]));
761
+ // Parse deferred items
762
+ for (let i = 0; i < deferredSize; i++) {
763
+ nodes[nodeSize + i] = await generateTreeAsync(ctx, deferred[i]);
747
764
  }
748
765
  return [SerovalNodeType.Set, nodes, id];
749
766
  }
750
767
  if (constructorCheck<Map<AsyncServerValue, AsyncServerValue>>(current, Map)) {
751
768
  assert(ctx.features.has(Feature.Map), 'Unsupported type "Map"');
752
- const keyNodes: SerovalNode[] = [];
753
- const valueNodes: SerovalNode[] = [];
754
- const deferredKey: AsyncServerValue[] = [];
755
- const deferredValue: AsyncServerValue[] = [];
769
+ const len = current.size;
770
+ const keyNodes = new Array<SerovalNode>(len);
771
+ const valueNodes = new Array<SerovalNode>(len);
772
+ const deferredKey = new Array<AsyncServerValue>(len);
773
+ const deferredValue = new Array<AsyncServerValue>(len);
756
774
  let deferredSize = 0;
775
+ let nodeSize = 0;
757
776
  for (const [key, value] of current.entries()) {
777
+ // Either key or value might be an iterable
758
778
  if (isIterable(key) || isIterable(value)) {
759
- deferredKey.push(key);
760
- deferredValue.push(value);
779
+ deferredKey[deferredSize] = key;
780
+ deferredValue[deferredSize] = value;
761
781
  deferredSize++;
762
782
  } else {
763
- keyNodes.push(await generateTreeAsync(ctx, key));
764
- valueNodes.push(await generateTreeAsync(ctx, value));
783
+ keyNodes[nodeSize] = await generateTreeAsync(ctx, key);
784
+ valueNodes[nodeSize] = await generateTreeAsync(ctx, value);
785
+ nodeSize++;
765
786
  }
766
787
  }
767
788
  for (let i = 0; i < deferredSize; i++) {
768
- keyNodes.push(await generateTreeAsync(ctx, deferredKey[i]));
769
- valueNodes.push(await generateTreeAsync(ctx, deferredValue[i]));
789
+ keyNodes[nodeSize + i] = await generateTreeAsync(ctx, deferredKey[i]);
790
+ valueNodes[nodeSize + i] = await generateTreeAsync(ctx, deferredValue[i]);
770
791
  }
771
- return [SerovalNodeType.Map, [keyNodes, valueNodes, current.size], id];
792
+ return [SerovalNodeType.Map, [keyNodes, valueNodes, len], id];
772
793
  }
773
794
  if (Array.isArray(current)) {
774
795
  const size = current.length;
@@ -884,14 +905,11 @@ function serializeAssignments(
884
905
  ctx.stack = parentStack;
885
906
  const key = keys[i];
886
907
  const check = Number(key);
887
- // Test if key is a valid number or JS identifier
888
- // so that we don't have to serialize the key and wrap with brackets
889
908
  const parentAssignment = ctx.assignments;
890
909
  ctx.assignments = mainAssignments;
891
- if (
892
- check >= 0
893
- || (Number.isNaN(check) && IDENTIFIER_CHECK.test(key))
894
- ) {
910
+ // Test if key is a valid number or JS identifier
911
+ // so that we don't have to serialize the key and wrap with brackets
912
+ if (IDENTIFIER_CHECK.test(key) || check >= 0) {
895
913
  if (!Number.isNaN(check)) {
896
914
  createObjectComputedAssign(ctx, targetRef, key, refParam);
897
915
  } else {
@@ -919,23 +937,20 @@ function serializeObject(
919
937
  const check = Number(key);
920
938
  // Test if key is a valid number or JS identifier
921
939
  // so that we don't have to serialize the key and wrap with brackets
922
- if (
923
- check >= 0
924
- || (Number.isNaN(check) && IDENTIFIER_CHECK.test(key))
925
- ) {
926
- if (isReferenceInStack(ctx, val)) {
927
- const refParam = getRefParam(ctx, val[1]);
940
+ const isIdentifier = IDENTIFIER_CHECK.test(key) || check >= 0;
941
+ if (isReferenceInStack(ctx, val)) {
942
+ const refParam = getRefParam(ctx, val[1]);
943
+ if (isIdentifier) {
928
944
  if (!Number.isNaN(check)) {
929
945
  createObjectComputedAssign(ctx, sourceID, key, refParam);
930
946
  } else {
931
947
  createObjectIdentifierAssign(ctx, sourceID, key, refParam);
932
948
  }
933
949
  } else {
934
- result += `${key}:${serializeTree(ctx, val)},`;
950
+ createObjectComputedAssign(ctx, sourceID, quote(key), refParam);
935
951
  }
936
- } else if (isReferenceInStack(ctx, val)) {
937
- const refParam = getRefParam(ctx, val[1]);
938
- createObjectComputedAssign(ctx, sourceID, quote(key), refParam);
952
+ } else if (isIdentifier) {
953
+ result += `${key}:${serializeTree(ctx, val)},`;
939
954
  } else {
940
955
  result += `${quote(key)}:${serializeTree(ctx, val)},`;
941
956
  }