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 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
@@ -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;
@@ -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 +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;
@@ -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.1",
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": {