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.
- package/dist/factory/factory.d.ts +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +301 -68
- package/dist/parsers/enumParser.d.ts +3 -3
- package/dist/stateHandling/index.d.ts +1 -0
- package/dist/stateHandling/stateData.d.ts +2 -3
- package/dist/stateHandling/stateNode.d.ts +18 -16
- package/dist/types/index.d.ts +1 -0
- package/dist/types/stateData.d.ts +4 -0
- package/package.json +1 -1
|
@@ -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
|
|
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 = (
|
|
120
|
-
var rawParser3 = (rawString,
|
|
121
|
-
var rawStringifier3 = (value,
|
|
122
|
-
if (value >
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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.
|
|
608
|
-
|
|
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
|
-
|
|
616
|
-
if (this.state ===
|
|
809
|
+
const constrainedNewState = constrainState(newState);
|
|
810
|
+
if (this.state === constrainedNewState)
|
|
617
811
|
return;
|
|
618
|
-
this.
|
|
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
|
-
|
|
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
|
|
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.
|
|
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
|
-
|
|
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
|
|
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.
|
|
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
|
-
|
|
893
|
+
...this.descriptor,
|
|
705
894
|
name: this.name,
|
|
706
895
|
value: this.children.map((child) => child.toDataEntry()),
|
|
707
|
-
|
|
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
|
|
722
|
-
this.children =
|
|
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
|
-
|
|
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: (
|
|
3
|
-
export declare const rawParser: (rawString: string,
|
|
4
|
-
export declare const rawStringifier: (value: number,
|
|
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,3 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
|
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
|
|
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;
|
package/dist/types/index.d.ts
CHANGED