url-safe-bitpacking 0.3.0 → 0.3.1
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
|
|
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
|
|
@@ -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;
|
|
@@ -753,6 +940,47 @@ var FromState = (stateDescriptor, name, base64String) => {
|
|
|
753
940
|
const [parsedObject] = dataEntryBitstringParser(dataObject, bitstring);
|
|
754
941
|
return new ObjectNode(parsedObject, null);
|
|
755
942
|
};
|
|
943
|
+
// src/stateHandling/stateData.ts
|
|
944
|
+
var getObjectForDataEntries = (entries) => {
|
|
945
|
+
const object = {};
|
|
946
|
+
entries.forEach((item) => {
|
|
947
|
+
object[item.name] = getStateData(item);
|
|
948
|
+
});
|
|
949
|
+
return object;
|
|
950
|
+
};
|
|
951
|
+
var getStateData = (entry) => {
|
|
952
|
+
switch (entry.type) {
|
|
953
|
+
case "BOOLEAN":
|
|
954
|
+
case "INT":
|
|
955
|
+
case "FLOAT":
|
|
956
|
+
case "VERSION":
|
|
957
|
+
return entry.value;
|
|
958
|
+
case "ENUM":
|
|
959
|
+
return entry.mapping[entry.value];
|
|
960
|
+
case "ENUM_ARRAY":
|
|
961
|
+
return entry.value.map((v) => entry.mapping[v]);
|
|
962
|
+
case "OPTIONAL":
|
|
963
|
+
return entry.value === null ? null : getStateData(entry.value);
|
|
964
|
+
case "ENUM_OPTIONS":
|
|
965
|
+
const state = entry.mapping[entry.state];
|
|
966
|
+
if (entry.value) {
|
|
967
|
+
switch (entry.value.type) {
|
|
968
|
+
case "OBJECT":
|
|
969
|
+
return {
|
|
970
|
+
...getStateData(entry.value),
|
|
971
|
+
state
|
|
972
|
+
};
|
|
973
|
+
default:
|
|
974
|
+
return { state, value: getStateData(entry.value) };
|
|
975
|
+
}
|
|
976
|
+
} else
|
|
977
|
+
return { state };
|
|
978
|
+
case "OBJECT":
|
|
979
|
+
return getObjectForDataEntries(entry.value);
|
|
980
|
+
case "ARRAY":
|
|
981
|
+
return entry.value.map((v) => getStateData(v));
|
|
982
|
+
}
|
|
983
|
+
};
|
|
756
984
|
// src/utils/interpolateData.ts
|
|
757
985
|
var interpolateEntryAt = (dataEntry2, t) => {
|
|
758
986
|
const localT = Math.max(Math.min(1, t), 0);
|
|
@@ -788,6 +1016,7 @@ var getRelativeValue = (dataEntry2) => {
|
|
|
788
1016
|
export {
|
|
789
1017
|
parseBase64ToBits,
|
|
790
1018
|
interpolateEntryAt,
|
|
1019
|
+
getStateData,
|
|
791
1020
|
getRelativeValue,
|
|
792
1021
|
getOptionsFromMaxAndMapping,
|
|
793
1022
|
getEnumMaxAndMappingFromOptions,
|
|
@@ -810,6 +1039,7 @@ export {
|
|
|
810
1039
|
EnumOptionsNode,
|
|
811
1040
|
EnumNode,
|
|
812
1041
|
EnumArrayNode,
|
|
1042
|
+
DataEntryFactory,
|
|
813
1043
|
ConstantBitWidthDataTypes,
|
|
814
1044
|
BooleanNode,
|
|
815
1045
|
ArrayNode
|
|
@@ -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;
|
package/dist/types/index.d.ts
CHANGED