url-safe-bitpacking 0.3.0 → 0.3.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.
@@ -12,7 +12,7 @@ import { DataEntry, ObjectDataEntry, VersionDataEntry } from '../types';
12
12
  /**
13
13
  * Record containing all the factory methods for the different data entry objects
14
14
  */
15
- export declare const DescriptorFactory: {
15
+ export declare const DataEntryFactory: {
16
16
  FLOAT: typeof createFloat;
17
17
  INT: typeof createInt;
18
18
  ENUM: typeof createEnum;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { DataType, ConstantBitWidthDataTypes, VariableBitWidthDataTypes } from './enums';
2
- export { PrecisionRangeType, SignificandMaxBits, FloatDataEntry, IntegerMaxBits, IntDataEntry, EnumDataEntry, EnumArrayDataEntry, VersionRangeType, VersionDataEntry, BooleanDataEntry, DataEntry, ProtectedAttributeNames, EnumOptionsType, EnumMappingType, PROTECTED_ATTRIBUTE_NAMES } from './types';
2
+ export { PrecisionRangeType, SignificandMaxBits, FloatDataEntry, IntegerMaxBits, IntDataEntry, EnumDataEntry, EnumArrayDataEntry, VersionRangeType, VersionDataEntry, BooleanDataEntry, DataEntry, ProtectedAttributeNames, EnumOptionsType, EnumMappingType, PROTECTED_ATTRIBUTE_NAMES, StateDataObject, StateDataObjectValue } from './types';
3
3
  export { getBitsCount, dataEntryBitstringParser, dataEntryCorrecting, dataEntryBitsStringifier, parseBase64ToBits } from './parsers';
4
- export { SpecificTypeNode, NodeFactory, GetStateNodeTree, FromState, ArrayNode, BooleanNode, EnumNode, IntNode, FloatNode, EnumArrayNode, OptionalNode, EnumOptionsNode, ObjectNode, StateNode } from './stateHandling';
4
+ export { SpecificTypeNode, NodeFactory, GetStateNodeTree, FromState, ArrayNode, BooleanNode, EnumNode, IntNode, FloatNode, EnumArrayNode, OptionalNode, EnumOptionsNode, ObjectNode, StateNode, getStateData } from './stateHandling';
5
5
  export { interpolateEntryAt, getRelativeValue } from './utils';
6
+ export { DataEntryFactory } from './factory';
6
7
  export { getEnumMaxAndMappingFromOptions, getOptionsFromMaxAndMapping } from './factory/utils';
package/dist/index.js CHANGED
@@ -2,6 +2,8 @@
2
2
  var ConstantBitWidthDataTypes = ["VERSION", "BOOLEAN", "ENUM", "INT", "FLOAT"];
3
3
  var VariableBitWidthDataTypes = ["ENUM_ARRAY", "OPTIONAL", "ENUM_OPTIONS", "ARRAY", "OBJECT"];
4
4
  var HasStateBitsDataTypes = ["ENUM_ARRAY", "OPTIONAL", "ENUM_OPTIONS", "ARRAY"];
5
+ // src/types/enumData.ts
6
+ var EnumMaxBits = 8;
5
7
  // src/types/floatData.ts
6
8
  var SignificandMaxBits = 20;
7
9
  // src/types/intData.ts
@@ -116,12 +118,12 @@ var rawStringifier2 = (value, intData2) => {
116
118
  };
117
119
 
118
120
  // src/parsers/enumParser.ts
119
- var getBitsCount3 = (versionData2) => versionData2.bits;
120
- var rawParser3 = (rawString, versionData2) => rawValueParser(rawString, versionData2.bits);
121
- var rawStringifier3 = (value, versionData2) => {
122
- if (value > versionData2.max)
121
+ var getBitsCount3 = (enumData2) => enumData2.bits;
122
+ var rawParser3 = (rawString, enumData2) => rawValueParser(rawString, enumData2.bits);
123
+ var rawStringifier3 = (value, enumData2) => {
124
+ if (value > enumData2.max)
123
125
  throw new Error("Version exceeds max");
124
- return rawIntStringifier(value, versionData2.bits);
126
+ return rawIntStringifier(value, enumData2.bits);
125
127
  };
126
128
 
127
129
  // src/parsers/versionParser.ts
@@ -454,8 +456,59 @@ var updateStateEntry = (original, update) => {
454
456
  }
455
457
  };
456
458
  // src/factory/helperMethod.ts
459
+ var getBitsForIntegerNumber = (number, maxBits) => {
460
+ const bitCount = Math.ceil(Math.log2(number));
461
+ if (bitCount > maxBits)
462
+ throw new Error(`Cannot get ${maxBits} bits for a number with ${bitCount} bits`);
463
+ return bitCount;
464
+ };
457
465
  var getMinimumBitsForInteger = (v) => Math.ceil(Math.log2(v + 1));
458
466
 
467
+ // src/factory/floatFactory.ts
468
+ var create = (value, min = 0, max = 1, precision = 2, name = "a float") => {
469
+ const precisionMultiplier = 10 ** precision;
470
+ const roundedMin = Math.floor(min * precisionMultiplier);
471
+ const roundedMax = Math.ceil(max * precisionMultiplier);
472
+ const delta = roundedMax - roundedMin;
473
+ const significand = Math.max(1, getBitsForIntegerNumber(delta, SignificandMaxBits));
474
+ return {
475
+ value,
476
+ type: "FLOAT",
477
+ min: roundedMin / precisionMultiplier,
478
+ max: roundedMax / precisionMultiplier,
479
+ precision,
480
+ significand,
481
+ name
482
+ };
483
+ };
484
+
485
+ // src/factory/intFactory.ts
486
+ var create2 = (value, min = 0, max = 10, name = "an int") => {
487
+ if (!Number.isInteger(min) || !Number.isInteger(max))
488
+ throw new Error("min and max must be integers");
489
+ if (max - min < 1)
490
+ throw new Error("max must be at least one");
491
+ if (Math.abs(max - min) > 2 ** IntegerMaxBits - 1)
492
+ throw new Error("max - min must be less than 1024");
493
+ const bits = getBitsForIntegerNumber(max - min + 1, IntegerMaxBits);
494
+ return { value, type: "INT", min, max, bits, name };
495
+ };
496
+
497
+ // src/factory/booleanFactory.ts
498
+ var create3 = (value, name = "a boolean") => ({
499
+ value,
500
+ type: "BOOLEAN",
501
+ name
502
+ });
503
+
504
+ // src/factory/versionFactory.ts
505
+ var create4 = (value, bits = 8, name = "a version") => ({
506
+ value,
507
+ type: "VERSION",
508
+ bits,
509
+ name
510
+ });
511
+
459
512
  // src/factory/utils.ts
460
513
  var getEnumMaxAndMappingFromOptions = (options) => {
461
514
  if (typeof options === "string")
@@ -472,12 +525,134 @@ var getOptionsFromMaxAndMapping = (v) => {
472
525
  return v.mapping;
473
526
  };
474
527
 
528
+ // src/factory/enumFactory.ts
529
+ var create5 = (value, options, name = "an enum") => {
530
+ const { max, mapping } = getEnumMaxAndMappingFromOptions(options);
531
+ if (!Number.isInteger(max))
532
+ throw new Error(`max must be integers, you have given ${max}`);
533
+ if (max < 1)
534
+ throw new Error("max must be at least one");
535
+ if (max > 2 ** EnumMaxBits - 1)
536
+ throw new Error("max - min must be less than 256");
537
+ const bits = getBitsForIntegerNumber(max + 1, EnumMaxBits);
538
+ return { value, type: "ENUM", max, bits, name, mapping };
539
+ };
540
+
541
+ // src/factory/enumArrayFactory.ts
542
+ var minEnumArrayCount = 0;
543
+ var maxOptionsCount = 1024;
544
+ var create6 = (value, options, minCount = minEnumArrayCount, maxCount = 10, name = "enum array") => {
545
+ const { max, mapping } = getEnumMaxAndMappingFromOptions(options);
546
+ if (!Number.isInteger(max))
547
+ throw new Error(`max must be integers, you have given ${max}`);
548
+ if (!Number.isInteger(minCount) || !Number.isInteger(maxCount))
549
+ throw new Error("minCount and maxCount must be integers");
550
+ if (max < 1)
551
+ throw new Error("must have at least one option");
552
+ if (max > maxOptionsCount)
553
+ throw new Error(`maximum allowed options is 1024, you have given ${max + 1} options`);
554
+ minCount = Math.min(minCount, maxCount);
555
+ maxCount = Math.max(minCount, maxCount);
556
+ if (minCount < 0)
557
+ throw new Error("minCount can't be negative");
558
+ if (maxCount - minCount < 0)
559
+ throw new Error(`count range length must be positive, given count range length is ${Math.abs(maxCount - minCount)}`);
560
+ if (Math.abs(maxCount - minCount) > 2 ** IntegerMaxBits - 1)
561
+ throw new Error(`count range length must be less than 1024, given count range length is ${Math.abs(maxCount - minCount)}`);
562
+ value.forEach((v, i) => {
563
+ if (!Number.isInteger(v))
564
+ throw new Error(`all entries must be integers, index ${i} (${v}) is not`);
565
+ if (v > max)
566
+ throw new Error(`all entries must be within the range ${0} - ${max}, index ${i} (${v}) is not`);
567
+ });
568
+ if (value.length < minCount || value.length > maxCount)
569
+ throw new Error(`value length must be between minCount and maxCount, ${value.length} is not between ${minCount} and ${maxCount}`);
570
+ const stateBits = getBitsForIntegerNumber(maxCount - minCount + 1, IntegerMaxBits);
571
+ return {
572
+ type: "ENUM_ARRAY",
573
+ minCount,
574
+ maxCount,
575
+ value: JSON.parse(JSON.stringify(value)),
576
+ max,
577
+ name,
578
+ mapping,
579
+ stateBits
580
+ };
581
+ };
582
+
583
+ // src/factory/optionalFactory.ts
584
+ var create7 = (descriptor, defaultState = false, name = "an optional") => {
585
+ if (descriptor[0] === null && descriptor[1] === null)
586
+ throw new Error("descriptor must have at least one non-null value");
587
+ if (descriptor[0] !== null && descriptor[1] !== null)
588
+ throw new Error("descriptor must have only one non-null value");
589
+ return {
590
+ type: "OPTIONAL",
591
+ state: defaultState,
592
+ descriptor,
593
+ value: JSON.parse(JSON.stringify(defaultState ? descriptor[1] : descriptor[0])),
594
+ name,
595
+ stateBits: 1
596
+ };
597
+ };
598
+
475
599
  // src/factory/enumOptionsFactory.ts
476
600
  var maxEnumOptions = 64;
477
601
  var maxEnumOptionsBits = getMinimumBitsForInteger(maxEnumOptions);
602
+ var create8 = (descriptor, defaultState = 0, name = "enum options", options) => {
603
+ if (descriptor.length < 2)
604
+ throw new Error("descriptor must have at least two entries");
605
+ if (descriptor.length - 1 < defaultState)
606
+ throw new Error("defaultState must be less than the length of the descriptor");
607
+ const mapping = [];
608
+ if (options) {
609
+ const { max, mapping: mapping2 } = getEnumMaxAndMappingFromOptions(options);
610
+ if (max !== descriptor.length - 1)
611
+ throw new Error("max must be equal to the length of the descriptor - 1");
612
+ mapping2.push(...mapping2);
613
+ } else
614
+ mapping.push(...descriptor.map((_, i) => i));
615
+ return {
616
+ value: JSON.parse(JSON.stringify(descriptor[defaultState])),
617
+ descriptor,
618
+ name,
619
+ mapping,
620
+ type: "ENUM_OPTIONS",
621
+ stateBits: getBitsForIntegerNumber(descriptor.length, maxEnumOptionsBits),
622
+ state: defaultState
623
+ };
624
+ };
625
+
626
+ // src/factory/arrayFactory.ts
627
+ var maxArrayCount = 1024;
628
+ var create9 = (descriptor, defaultState = 0, minCount = 0, maxCount = 10, name = "an array") => {
629
+ if (!Number.isInteger(minCount) || !Number.isInteger(maxCount))
630
+ throw new Error("minCount and maxCount must be integers");
631
+ if (minCount < 0)
632
+ throw new Error("minCount must be at least 0");
633
+ if (maxCount < 0)
634
+ throw new Error("maxCount must be at least 0");
635
+ if (maxCount - minCount < 0)
636
+ throw new Error("maxCount must be greater than or equal to minCount");
637
+ if (maxCount - minCount > maxArrayCount)
638
+ throw new Error(`maxCount (${maxCount}) - minCount (${minCount}) = ${maxCount - minCount} must be less than or equal to maxArrayCount (${maxArrayCount})`);
639
+ if (defaultState < minCount || defaultState > maxCount)
640
+ throw new Error(`defaultState must be between minCount (${minCount}) and maxCount (${maxCount}), given defaultState is ${defaultState}`);
641
+ const stateBits = getMinimumBitsForInteger(maxCount - minCount);
642
+ return {
643
+ value: [...Array(defaultState)].map(() => JSON.parse(JSON.stringify(descriptor))),
644
+ descriptor,
645
+ type: "ARRAY",
646
+ minCount,
647
+ maxCount,
648
+ stateBits,
649
+ state: defaultState,
650
+ name
651
+ };
652
+ };
478
653
 
479
654
  // src/factory/objectFactory.ts
480
- var create = (descriptor, name = "an object") => {
655
+ var create10 = (descriptor, name = "an object") => {
481
656
  return {
482
657
  type: "OBJECT",
483
658
  descriptor,
@@ -488,7 +663,19 @@ var create = (descriptor, name = "an object") => {
488
663
  };
489
664
 
490
665
  // src/factory/factory.ts
491
- var StateDescriptorFactoryMethod = create;
666
+ var DataEntryFactory = {
667
+ FLOAT: create,
668
+ INT: create2,
669
+ ENUM: create5,
670
+ BOOLEAN: create3,
671
+ VERSION: create4,
672
+ ENUM_ARRAY: create6,
673
+ OPTIONAL: create7,
674
+ ENUM_OPTIONS: create8,
675
+ ARRAY: create9,
676
+ OBJECT: create10
677
+ };
678
+ var StateDescriptorFactoryMethod = create10;
492
679
  // src/stateHandling/stateNode.ts
493
680
  class StateNode {
494
681
  parent;
@@ -504,8 +691,11 @@ class StateNode {
504
691
  }
505
692
  updateUpstream = () => {
506
693
  const newBitstring = this.getBitString();
507
- if (newBitstring !== this.bitstring)
508
- this.bitstring = newBitstring, this.parent && this.parent.updateUpstream();
694
+ if (newBitstring !== this.bitstring) {
695
+ this.bitstring = newBitstring;
696
+ if (this.parent)
697
+ this.parent.updateUpstream();
698
+ }
509
699
  };
510
700
  getStateBits = () => {
511
701
  throw new Error("not implemented for " + this.type);
@@ -565,10 +755,8 @@ class SimpleStateNodes extends StateNode {
565
755
  }
566
756
  getChildren = () => [];
567
757
  getDescription = () => `${this.name}: ${this.value}`;
568
- updateValue = (value) => {
569
- this.value = constrainValue7(this.descriptor, value);
570
- this.updateUpstream();
571
- };
758
+ updateValue = (value) => (this.value = constrainValue7(this.descriptor, value), this.updateUpstream());
759
+ updateDescriptor = (entry) => (this.descriptor = entry, this.updateValue(this.value));
572
760
  toDataEntry = () => ({
573
761
  ...this.descriptor,
574
762
  name: this.name,
@@ -596,121 +784,118 @@ class EnumArrayNode extends SimpleStateNodes {
596
784
  getDescription = () => `${this.name}: [${this.value.map((v) => this.descriptor.mapping[v]).join(", ")}]`;
597
785
  }
598
786
 
599
- class OptionalNode extends StateNode {
787
+ class ComplexStateNodes extends StateNode {
600
788
  state;
601
- stateBits;
602
789
  descriptor;
603
- child = null;
604
790
  constructor(entry, parent) {
605
791
  super(entry, parent);
606
792
  this.state = entry.state;
607
- this.stateBits = entry.stateBits;
608
- this.descriptor = entry["descriptor"];
793
+ this.descriptor = entry;
794
+ }
795
+ }
796
+
797
+ class OptionalNode extends ComplexStateNodes {
798
+ child = null;
799
+ constructor(entry, parent) {
800
+ super(entry, parent);
801
+ this.child = this.initializedChild();
609
802
  this.bitstring = this.getBitString();
610
803
  }
611
804
  getChildren = () => [this.child];
612
805
  getStateBits = () => rawStateStringifier3(this.state);
613
806
  getValueBits = () => this.child ? this.child.bitstring : "";
807
+ initializedChild = () => this.descriptor.descriptor[this.state ? 1 : 0] ? NodeFactory(this.descriptor.descriptor[this.state ? 1 : 0], this) : null;
614
808
  updateState = (newState) => {
615
- this.state = constrainState(newState);
616
- if (this.state === this.state)
809
+ const constrainedNewState = constrainState(newState);
810
+ if (this.state === constrainedNewState)
617
811
  return;
618
- this.child = this.descriptor[this.state ? 1 : 0] ? NodeFactory(this.descriptor[this.state ? 1 : 0], this) : null;
812
+ this.state = constrainedNewState;
813
+ this.child = this.descriptor.descriptor[this.state ? 1 : 0] ? NodeFactory(this.descriptor.descriptor[this.state ? 1 : 0], this) : null;
814
+ this.updateUpstream();
815
+ };
816
+ updateDescriptor = (entry) => {
817
+ this.descriptor = entry;
818
+ this.child = this.initializedChild();
619
819
  this.updateUpstream();
620
820
  };
621
821
  toDataEntry = () => ({
622
- type: "OPTIONAL",
822
+ ...this.descriptor,
623
823
  name: this.name,
624
824
  state: this.state,
625
- stateBits: this.stateBits,
626
- descriptor: this.descriptor,
627
825
  value: this.child ? this.child.toDataEntry() : null
628
826
  });
629
827
  getDescription = () => `${this.name}: ${this.state}`;
630
828
  }
631
829
 
632
- class EnumOptionsNode extends StateNode {
633
- state;
634
- stateBits;
635
- descriptor;
636
- mapping;
830
+ class EnumOptionsNode extends ComplexStateNodes {
637
831
  child = null;
638
832
  constructor(entry, parent) {
639
833
  super(entry, parent);
640
- this.state = entry.state;
641
- this.stateBits = entry.stateBits;
642
- this.descriptor = entry["descriptor"];
643
- this.mapping = entry["mapping"];
644
- this.child = entry["value"] ? NodeFactory(entry["value"], this) : null;
834
+ this.child = this.initializedChild();
645
835
  this.bitstring = this.getBitString();
646
836
  }
647
837
  getChildren = () => [this.child];
648
- getStateBits = () => rawStateStringifier4(this.state, this.stateBits);
838
+ getStateBits = () => rawStateStringifier4(this.state, this.descriptor.stateBits);
649
839
  getValueBits = () => this.child ? this.child.bitstring : "";
840
+ initializedChild = () => this.descriptor.descriptor[this.state] ? NodeFactory(this.descriptor.descriptor[this.state], this) : null;
650
841
  updateState = (newState) => {
651
- const constrainedNewState = constrainState2(this.descriptor.length, newState);
842
+ const constrainedNewState = constrainState2(this.descriptor.descriptor.length, newState);
652
843
  if (constrainedNewState === this.state)
653
844
  return;
654
- const validationResult = validateDataEntry(this.descriptor[constrainedNewState], this.child ? this.child.toDataEntry() : null);
845
+ const validationResult = validateDataEntry(this.descriptor.descriptor[constrainedNewState], this.child ? this.child.toDataEntry() : null);
655
846
  this.child = validationResult ? NodeFactory(validationResult, this) : null;
656
847
  this.state = constrainedNewState;
657
848
  this.updateUpstream();
658
849
  };
850
+ updateDescriptor = (entry) => {
851
+ this.descriptor = entry;
852
+ this.child = this.initializedChild();
853
+ this.updateUpstream();
854
+ };
659
855
  toDataEntry = () => ({
660
- type: "ENUM_OPTIONS",
856
+ ...this.descriptor,
661
857
  name: this.name,
662
858
  state: this.state,
663
- stateBits: this.stateBits,
664
- descriptor: this.descriptor,
665
- mapping: this.mapping,
666
859
  value: this.child ? this.child.toDataEntry() : null
667
860
  });
668
- getDescription = () => `${this.name}: ${this.state} of ${this.mapping.length} options`;
861
+ getDescription = () => `${this.name}: ${this.state} of ${this.descriptor.mapping.length} options`;
669
862
  }
670
863
 
671
- class ArrayNode extends StateNode {
672
- descriptor;
864
+ class ArrayNode extends ComplexStateNodes {
673
865
  children;
674
- minCount;
675
- maxCount;
676
- stateBits;
677
- state;
678
866
  constructor(entry, parent) {
679
867
  super(entry, parent);
680
- this.descriptor = entry["descriptor"];
681
- this.children = entry["value"].map((child) => NodeFactory(child, this));
682
- this.minCount = entry["minCount"];
683
- this.maxCount = entry["maxCount"];
684
- this.stateBits = entry["stateBits"];
685
- this.state = entry["state"];
868
+ this.children = this.initializedChildren();
686
869
  this.bitstring = this.getBitString();
687
870
  }
871
+ initializedChildren = () => this.descriptor.value.map((child) => NodeFactory(child, this));
688
872
  getChildren = () => this.children;
689
- getStateBits = () => rawStateStringifier2(this.state, this.minCount, this.stateBits);
873
+ getStateBits = () => rawStateStringifier2(this.state, this.descriptor.minCount, this.descriptor.stateBits);
690
874
  getValueBits = () => this.children.map((child) => child.bitstring).join("");
875
+ updateDescriptor = (entry) => {
876
+ this.descriptor = entry;
877
+ this.children = this.initializedChildren();
878
+ this.updateUpstream();
879
+ };
691
880
  updateState = (newState) => {
692
- const constrainedNewState = constrainState3(newState, this.minCount, this.maxCount);
881
+ const constrainedNewState = constrainState3(newState, this.descriptor.minCount, this.descriptor.maxCount);
693
882
  if (constrainedNewState === this.state)
694
883
  return;
695
884
  if (constrainedNewState < this.state)
696
885
  this.children = this.children.slice(0, constrainedNewState);
697
886
  else
698
887
  for (let i = this.state;i < constrainedNewState; i++)
699
- this.children.push(NodeFactory(this.descriptor, this));
888
+ this.children.push(NodeFactory(this.descriptor.descriptor, this));
700
889
  this.state = constrainedNewState;
701
890
  this.updateUpstream();
702
891
  };
703
892
  toDataEntry = () => ({
704
- type: "ARRAY",
893
+ ...this.descriptor,
705
894
  name: this.name,
706
895
  value: this.children.map((child) => child.toDataEntry()),
707
- minCount: this.minCount,
708
- maxCount: this.maxCount,
709
- stateBits: this.stateBits,
710
- state: this.state,
711
- descriptor: this.descriptor
896
+ state: this.state
712
897
  });
713
- getDescription = () => `${this.name}: ${this.state} of (${this.minCount}, ${this.maxCount})`;
898
+ getDescription = () => `${this.name}: ${this.state} of (${this.descriptor.minCount}, ${this.descriptor.maxCount})`;
714
899
  }
715
900
 
716
901
  class ObjectNode extends StateNode {
@@ -718,18 +903,23 @@ class ObjectNode extends StateNode {
718
903
  children;
719
904
  constructor(entry, parent) {
720
905
  super(entry, parent);
721
- this.descriptor = entry["descriptor"];
722
- this.children = entry["value"].map((child) => NodeFactory(child, this));
906
+ this.descriptor = entry;
907
+ this.children = this.initializedChild();
723
908
  this.bitstring = this.getBitString();
724
909
  }
910
+ initializedChild = () => this.descriptor.value.map((child) => NodeFactory(child, this));
911
+ updateDescriptor = (entry) => {
912
+ this.descriptor = entry;
913
+ this.children = this.initializedChild();
914
+ this.updateUpstream();
915
+ };
725
916
  getChildren = () => this.children;
726
917
  getStateBits = () => "";
727
918
  getValueBits = () => this.children.map((child) => child.bitstring).join("");
728
919
  toDataEntry = () => ({
729
- type: "OBJECT",
920
+ ...this.descriptor,
730
921
  name: this.name,
731
922
  value: this.children.map((child) => child.toDataEntry()),
732
- descriptor: this.descriptor,
733
923
  stateBits: 0
734
924
  });
735
925
  }
@@ -753,6 +943,47 @@ var FromState = (stateDescriptor, name, base64String) => {
753
943
  const [parsedObject] = dataEntryBitstringParser(dataObject, bitstring);
754
944
  return new ObjectNode(parsedObject, null);
755
945
  };
946
+ // src/stateHandling/stateData.ts
947
+ var getObjectForDataEntries = (entries) => {
948
+ const object = {};
949
+ entries.forEach((item) => {
950
+ object[item.name] = getStateData(item);
951
+ });
952
+ return object;
953
+ };
954
+ var getStateData = (entry) => {
955
+ switch (entry.type) {
956
+ case "BOOLEAN":
957
+ case "INT":
958
+ case "FLOAT":
959
+ case "VERSION":
960
+ return entry.value;
961
+ case "ENUM":
962
+ return entry.mapping[entry.value];
963
+ case "ENUM_ARRAY":
964
+ return entry.value.map((v) => entry.mapping[v]);
965
+ case "OPTIONAL":
966
+ return entry.value === null ? null : getStateData(entry.value);
967
+ case "ENUM_OPTIONS":
968
+ const state = entry.mapping[entry.state];
969
+ if (entry.value) {
970
+ switch (entry.value.type) {
971
+ case "OBJECT":
972
+ return {
973
+ ...getStateData(entry.value),
974
+ state
975
+ };
976
+ default:
977
+ return { state, value: getStateData(entry.value) };
978
+ }
979
+ } else
980
+ return { state };
981
+ case "OBJECT":
982
+ return getObjectForDataEntries(entry.value);
983
+ case "ARRAY":
984
+ return entry.value.map((v) => getStateData(v));
985
+ }
986
+ };
756
987
  // src/utils/interpolateData.ts
757
988
  var interpolateEntryAt = (dataEntry2, t) => {
758
989
  const localT = Math.max(Math.min(1, t), 0);
@@ -788,6 +1019,7 @@ var getRelativeValue = (dataEntry2) => {
788
1019
  export {
789
1020
  parseBase64ToBits,
790
1021
  interpolateEntryAt,
1022
+ getStateData,
791
1023
  getRelativeValue,
792
1024
  getOptionsFromMaxAndMapping,
793
1025
  getEnumMaxAndMappingFromOptions,
@@ -810,6 +1042,7 @@ export {
810
1042
  EnumOptionsNode,
811
1043
  EnumNode,
812
1044
  EnumArrayNode,
1045
+ DataEntryFactory,
813
1046
  ConstantBitWidthDataTypes,
814
1047
  BooleanNode,
815
1048
  ArrayNode
@@ -1,4 +1,4 @@
1
1
  import { EnumData } from '../types/enumData';
2
- export declare const getBitsCount: (versionData: EnumData) => number;
3
- export declare const rawParser: (rawString: string, versionData: EnumData) => number;
4
- export declare const rawStringifier: (value: number, versionData: EnumData) => string;
2
+ export declare const getBitsCount: (enumData: EnumData) => number;
3
+ export declare const rawParser: (rawString: string, enumData: EnumData) => number;
4
+ export declare const rawStringifier: (value: number, enumData: EnumData) => string;
@@ -1 +1,2 @@
1
1
  export * from './stateNode';
2
+ export * from './stateData';
@@ -1,3 +1,2 @@
1
- import { NestedData } from '@/types';
2
- import { StateDataObject } from '@/types/stateDataEntry';
3
- export declare const getStateData: (state: NestedData) => StateDataObject;
1
+ import { DataEntry, StateDataObjectValue } from '../types';
2
+ export declare const getStateData: (entry: DataEntry) => StateDataObjectValue;
@@ -1,5 +1,5 @@
1
1
  import { DataType } from '../enums';
2
- import { ArrayDataEntry, BooleanDataEntry, DataEntry, EnumArrayDataEntry, EnumDataEntry, EnumOptionsDataEntry, FloatDataEntry, IntDataEntry, ObjectDataEntry, OptionalDataEntry, VersionDataEntry, UpdateWithValidationTypes } from '../types';
2
+ import { ArrayDataEntry, BooleanDataEntry, DataEntry, EnumArrayDataEntry, EnumDataEntry, EnumOptionsDataEntry, FloatDataEntry, IntDataEntry, ObjectDataEntry, OptionalDataEntry, VersionDataEntry, UpdateWithValidationTypes, UpdateWithStateEntries } from '../types';
3
3
  export declare class StateNode {
4
4
  protected parent: StateNode | null;
5
5
  protected root: StateNode;
@@ -35,6 +35,7 @@ declare class SimpleStateNodes<T extends UpdateWithValidationTypes> extends Stat
35
35
  getChildren: () => SpecificTypeNode[];
36
36
  getDescription: () => string;
37
37
  updateValue: (value: T["value"]) => void;
38
+ updateDescriptor: (entry: T) => void;
38
39
  toDataEntry: () => T;
39
40
  }
40
41
  export declare class VersionNode extends SimpleStateNodes<VersionDataEntry> {
@@ -51,44 +52,43 @@ export declare class EnumArrayNode extends SimpleStateNodes<EnumArrayDataEntry>
51
52
  getStateBits: () => string;
52
53
  getDescription: () => string;
53
54
  }
54
- export declare class OptionalNode extends StateNode {
55
- private state;
56
- private stateBits;
57
- private descriptor;
55
+ declare class ComplexStateNodes<T extends UpdateWithStateEntries> extends StateNode {
56
+ state: T['state'];
57
+ descriptor: T;
58
+ constructor(entry: T, parent: SpecificTypeNode | null);
59
+ }
60
+ export declare class OptionalNode extends ComplexStateNodes<OptionalDataEntry> {
58
61
  private child;
59
62
  constructor(entry: OptionalDataEntry, parent: SpecificTypeNode | null);
60
63
  getChildren: () => (SpecificTypeNode | null)[];
61
64
  getStateBits: () => string;
62
65
  getValueBits: () => string;
66
+ private initializedChild;
63
67
  updateState: (newState: OptionalDataEntry["state"]) => void;
68
+ updateDescriptor: (entry: OptionalDataEntry) => void;
64
69
  toDataEntry: () => OptionalDataEntry;
65
70
  getDescription: () => string;
66
71
  }
67
- export declare class EnumOptionsNode extends StateNode {
68
- private state;
69
- private stateBits;
70
- private descriptor;
71
- private mapping;
72
+ export declare class EnumOptionsNode extends ComplexStateNodes<EnumOptionsDataEntry> {
72
73
  private child;
73
74
  constructor(entry: EnumOptionsDataEntry, parent: SpecificTypeNode | null);
74
75
  getChildren: () => (SpecificTypeNode | null)[];
75
76
  getStateBits: () => string;
76
77
  getValueBits: () => string;
78
+ private initializedChild;
77
79
  updateState: (newState: EnumOptionsDataEntry["state"]) => void;
80
+ updateDescriptor: (entry: EnumOptionsDataEntry) => void;
78
81
  toDataEntry: () => EnumOptionsDataEntry;
79
82
  getDescription: () => string;
80
83
  }
81
- export declare class ArrayNode extends StateNode {
82
- private descriptor;
84
+ export declare class ArrayNode extends ComplexStateNodes<ArrayDataEntry> {
83
85
  private children;
84
- private minCount;
85
- private maxCount;
86
- private stateBits;
87
- private state;
88
86
  constructor(entry: ArrayDataEntry, parent: SpecificTypeNode | null);
87
+ private initializedChildren;
89
88
  getChildren: () => SpecificTypeNode[];
90
89
  getStateBits: () => string;
91
90
  getValueBits: () => string;
91
+ updateDescriptor: (entry: ArrayDataEntry) => void;
92
92
  updateState: (newState: ArrayDataEntry["state"]) => void;
93
93
  toDataEntry: () => ArrayDataEntry;
94
94
  getDescription: () => string;
@@ -97,6 +97,8 @@ export declare class ObjectNode extends StateNode {
97
97
  private descriptor;
98
98
  private children;
99
99
  constructor(entry: ObjectDataEntry, parent: SpecificTypeNode | null);
100
+ private initializedChild;
101
+ updateDescriptor: (entry: ObjectDataEntry) => void;
100
102
  getChildren: () => SpecificTypeNode[];
101
103
  getStateBits: () => string;
102
104
  getValueBits: () => string;
@@ -10,3 +10,4 @@ export * from './booleanData';
10
10
  export * from './dataEntry';
11
11
  export * from './objectData';
12
12
  export * from './updateType';
13
+ export * from './stateData';
@@ -0,0 +1,4 @@
1
+ export type StateDataObjectValue = object | string | number | number[] | boolean | null | StateDataObject;
2
+ export type StateDataObject = {
3
+ [key: string]: StateDataObjectValue;
4
+ };
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "dist/*"
7
7
  ],
8
8
  "type": "module",
9
- "version": "0.3.0",
9
+ "version": "0.3.2",
10
10
  "author": "Jonas Ward",
11
11
  "description": "Library for creating web safe base64 objects with custom bith widths and dynamic values.",
12
12
  "scripts": {