url-safe-bitpacking 0.2.0 → 0.2.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.
package/README.md CHANGED
@@ -28,7 +28,7 @@ Currently, there are 4 data types implemented (+1 special case for safety). All
28
28
  Bool type values are simple yes or no, 1 or 0s, nothing special
29
29
 
30
30
  ```typescript
31
- DataEntryFactory.createBoolean(false, 'shapePreProcessingWarpabsolute');
31
+ DescriptorFactory.BOOLEAN(false, 'shapePreProcessingWarpabsolute');
32
32
  ```
33
33
 
34
34
  ### enum
@@ -36,7 +36,7 @@ DataEntryFactory.createBoolean(false, 'shapePreProcessingWarpabsolute');
36
36
  An enum in this context is a continuous array of integers. The Bitwidth of this data type is defined by the maximum entry. eg. in case you you would need 21 states, the larges value would be 20. The value 20 would require at least five bits (log2(20) ~ 4.32). The maximum bitwidth for enums is right now hardcoded to 8-bit (which would be the range [0, 255] ).
37
37
 
38
38
  ```typescript
39
- DataEntryFactory.createEnum(0, 3, 'footprintType');
39
+ DescriptorFactory.ENUM(0, 3, 'footprintType');
40
40
  ```
41
41
 
42
42
  ### int
@@ -44,7 +44,7 @@ DataEntryFactory.createEnum(0, 3, 'footprintType');
44
44
  An int type is rather similar to the enum, except that it starts at a specific minimum value. The range that then needs to be able to be stored is: max - min. In case you would need values from -30 to 10, you would have to be able to store 10 - 30 + 1 = 51 states. This would require a bitwidth of 6 (log2(51) ~ 5.67). The max bitwidth is now hardcoded to be 12 (which would be the range [minimum, 4095 - minimum])
45
45
 
46
46
  ```typescript
47
- DataEntryFactory.createInt(5, 3, 20, 'circleDivisions');
47
+ DescriptorFactory.INT(5, 3, 20, 'circleDivisions');
48
48
  ```
49
49
 
50
50
  ### float
@@ -52,7 +52,7 @@ DataEntryFactory.createInt(5, 3, 20, 'circleDivisions');
52
52
  Floating points work very much like the integer type, with the main difference that one can also define a precision to define at what order of magnitude (from -3 to +3) the variable should be considered. The significand can be up to 20 bits, which eg. at precision -3 would allow a range of .001 to 1048.576.
53
53
 
54
54
  ```typescript
55
- DataEntryFactory.createFloat(20, 10, 200, -1, 'shapePreProcessingWarptotal');
55
+ DescriptorFactory.FLOAT(20, 10, 200, -1, 'shapePreProcessingWarptotal');
56
56
  ```
57
57
 
58
58
  ### enum array
@@ -60,7 +60,7 @@ DataEntryFactory.createFloat(20, 10, 200, -1, 'shapePreProcessingWarptotal');
60
60
  Enum arrays are a special type of arrays where integer values are intepreted as being values of a **specific base** to then be transformed to base 2. The base is derived from the delta of the max `and` the `min` value of the enums. Besides that, there is also a `minCount` and `maxCount` value (which can be the same value, but `minCount` is at least 1). This only offers a compression rate of upto 22% vis-a-vis an array of `IntDataEntry` (worst case its 0% percent, it never takes up more space), so sometimes questionable whether it makese sense to use ^^.
61
61
 
62
62
  ```typescript
63
- DataEntryFactory.createEnumArray([0, 1, 2], 0, 10, 3, 5, 'enumArrayA')
63
+ DescriptorFactory.ENUM_ARRAY([0, 1, 2], 0, 10, 3, 5, 'enumArrayA')
64
64
  ```
65
65
 
66
66
  ### version
@@ -68,7 +68,7 @@ DataEntryFactory.createEnumArray([0, 1, 2], 0, 10, 3, 5, 'enumArrayA')
68
68
  There is also a Version object which is a special case of the enum data type and has a bitwidth of 4, 6, 8 or, 10 and always occupies the first bits of the bitarray.
69
69
 
70
70
  ```typescript
71
- DataEntryFactory.createVersion(0, 8, 'version');
71
+ DescriptorFactory.VERSION(0, 8, 'version');
72
72
  ```
73
73
 
74
74
  ## nested attribute definitions
@@ -1,2 +1,2 @@
1
- import { EnumArrayDataEntry } from '@/types';
2
- export declare const create: (value: number[], options: (string | number | object)[] | string | number, minCount?: number, maxCount?: number, name?: string, index?: number) => EnumArrayDataEntry;
1
+ import { EnumArrayDataEntry, EnumOptionsType } from '@/types';
2
+ export declare const create: (value: number[], options: EnumOptionsType, minCount?: number, maxCount?: number, name?: string, index?: number) => EnumArrayDataEntry;
@@ -1,2 +1,3 @@
1
1
  import { EnumDataEntry } from '../types';
2
- export declare const create: (value: number, options: (string | number | object)[] | string | number, name?: string, index?: number) => EnumDataEntry;
2
+ import { EnumOptionsType } from '../types/enumData';
3
+ export declare const create: (value: number, options: EnumOptionsType, name?: string, index?: number) => EnumDataEntry;
@@ -10,16 +10,14 @@ import { create as createArray } from './arrayFactory';
10
10
  /**
11
11
  * Record containing all the factory methods for the different data entry objects
12
12
  */
13
- export declare const DataEntryFactory: {
14
- createFloat: typeof createFloat;
15
- createInt: typeof createInt;
16
- createEnum: typeof createEnum;
17
- createBoolean: typeof createBoolean;
18
- createVersion: typeof createVersion;
19
- createEnumArray: typeof createEnumArray;
20
- };
21
- export declare const ComplexDataEntryFactory: {
22
- createOptional: typeof createOptional;
23
- createEnumOptions: typeof createEnumOptions;
24
- createArray: typeof createArray;
13
+ export declare const DescriptorFactory: {
14
+ readonly FLOAT: typeof createFloat;
15
+ readonly INT: typeof createInt;
16
+ readonly ENUM: typeof createEnum;
17
+ readonly BOOLEAN: typeof createBoolean;
18
+ readonly VERSION: typeof createVersion;
19
+ readonly ENUM_ARRAY: typeof createEnumArray;
20
+ readonly OPTIONAL: typeof createOptional;
21
+ readonly ENUM_OPTIONS: typeof createEnumOptions;
22
+ readonly ARRAY: typeof createArray;
25
23
  };
@@ -1,9 +1,19 @@
1
+ import { EnumMappingType, EnumOptionsType } from '@/types';
1
2
  /**
2
3
  * Method to get the max and mapping from the options
3
4
  * @param options - `any[] | string | number` the options to get the max and mapping from
4
5
  * @returns `{ max: number; mapping: any[] }` the max and mapping
5
6
  */
6
- export declare const getOptionsFromEnumOptions: (options: (string | number | object)[] | string | number) => {
7
+ export declare const getEnumMaxAndMappingFromOptions: (options: EnumOptionsType) => {
7
8
  max: number;
8
- mapping: (string | number | object)[];
9
+ mapping: EnumMappingType;
9
10
  };
11
+ /**
12
+ * Method to get the options from the max and mapping of an ENUM & ENUM_ARRAY type
13
+ * @param v - `{ max: number; mapping: EnumMappingType }` the max and mapping to get the options from
14
+ * @returns `EnumOptionsType` the options
15
+ */
16
+ export declare const getOptionsFromMaxAndMapping: (v: {
17
+ max: number;
18
+ mapping: EnumMappingType;
19
+ }) => EnumOptionsType;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { DataType, DataTypeValues, ComplexDataType, ComplexDataValues } from './enums';
2
- export { DataEntryFactory, ComplexDataEntryFactory } from './factory';
3
- export { PrecisionRangeType, SignificandMaxBits, FloatDataEntry, IntegerMaxBits, IntDataEntry, EnumDataEntry, EnumArrayDataEntry, VersionRangeType, VersionDataEntry, BooleanDataEntry, DataEntry, ComplexDataEntry, NestedData, ProtectedAttributeNames, StateDescriptor, StateObject, StateDataObject, StateDataEntry, State, PROTECTED_ATTRIBUTE_NAMES } from './types';
4
- export { parseBase64ToBits, getBitsCount, valueBitsParser, dataBitsParser, dataEntryBitstringParser, dataBitsStringifier, dataEntryCorrecting } from './parsers';
2
+ export { DescriptorFactory } from './factory';
3
+ export { PrecisionRangeType, SignificandMaxBits, FloatDataEntry, IntegerMaxBits, IntDataEntry, EnumDataEntry, EnumArrayDataEntry, VersionRangeType, VersionDataEntry, BooleanDataEntry, DataEntry, ComplexDataEntry, NestedData, ProtectedAttributeNames, StateDescriptor, StateObject, StateDataObject, StateDataEntry, State, EnumOptionsType, EnumMappingType, PROTECTED_ATTRIBUTE_NAMES } from './types';
4
+ export { parseBase64ToBits, getBitsCount, valueBitsParser, dataBitsParser, dataEntryBitstringParser, dataEntryCorrecting, dataBitsStringifier, complexDataStringifier, complexDataStateStringifier } from './parsers';
5
5
  export { createStateDataObject, getInitialStateFromBase64 } from './stateHandling';
6
6
  export { interpolateEntryAt, getRelativeValue } from './utils';
7
+ export { getEnumMaxAndMappingFromOptions, getOptionsFromMaxAndMapping } from './factory/utils';
package/dist/index.js CHANGED
@@ -84,17 +84,24 @@ var create4 = (value, bits = 8, name = "", index = -1) => ({
84
84
  });
85
85
 
86
86
  // src/factory/utils.ts
87
- var getOptionsFromEnumOptions = (options) => {
87
+ var getEnumMaxAndMappingFromOptions = (options) => {
88
88
  if (typeof options === "string")
89
- return { max: options.length - 1, mapping: options.split(",").map(Number) };
89
+ return { max: options.length - 1, mapping: options.split("") };
90
90
  if (typeof options === "number")
91
91
  return { max: options, mapping: Array.from({ length: options + 1 }, (_, i) => i) };
92
92
  return { max: options.length - 1, mapping: options };
93
93
  };
94
+ var getOptionsFromMaxAndMapping = (v) => {
95
+ if (v.mapping.every((option) => typeof option === "string" && option.length === 1))
96
+ return v.mapping.join("");
97
+ if (Array.from({ length: v.max + 1 }, (_, i) => i).every((option, i) => option === v.mapping[i]))
98
+ return v.max;
99
+ return v.mapping;
100
+ };
94
101
 
95
102
  // src/factory/enumFactory.ts
96
103
  var create5 = (value, options, name = "", index = -1) => {
97
- const { max, mapping } = getOptionsFromEnumOptions(options);
104
+ const { max, mapping } = getEnumMaxAndMappingFromOptions(options);
98
105
  if (!Number.isInteger(max))
99
106
  throw new Error(`max must be integers, you have given ${max}`);
100
107
  if (max < 1)
@@ -107,7 +114,7 @@ var create5 = (value, options, name = "", index = -1) => {
107
114
 
108
115
  // src/factory/enumArrayFactory.ts
109
116
  var create6 = (value, options, minCount = 1, maxCount = 10, name = "", index = -1) => {
110
- const { max, mapping } = getOptionsFromEnumOptions(options);
117
+ const { max, mapping } = getEnumMaxAndMappingFromOptions(options);
111
118
  if (!Number.isInteger(max))
112
119
  throw new Error(`max must be integers, you have given ${max}`);
113
120
  if (!Number.isInteger(minCount) || !Number.isInteger(maxCount))
@@ -209,18 +216,16 @@ var create9 = (descriptor, defaultState = 0, minCount = 0, maxCount = 10, name =
209
216
  };
210
217
 
211
218
  // src/factory/factory.ts
212
- var DataEntryFactory = {
213
- createFloat: create,
214
- createInt: create2,
215
- createEnum: create5,
216
- createBoolean: create3,
217
- createVersion: create4,
218
- createEnumArray: create6
219
- };
220
- var ComplexDataEntryFactory = {
221
- createOptional: create7,
222
- createEnumOptions: create8,
223
- createArray: create9
219
+ var DescriptorFactory = {
220
+ FLOAT: create,
221
+ INT: create2,
222
+ ENUM: create5,
223
+ BOOLEAN: create3,
224
+ VERSION: create4,
225
+ ENUM_ARRAY: create6,
226
+ OPTIONAL: create7,
227
+ ENUM_OPTIONS: create8,
228
+ ARRAY: create9
224
229
  };
225
230
  // src/parsers/intParser.ts
226
231
  var getBitsCount = (intData2) => intData2.bits;
@@ -351,6 +356,9 @@ var rawParser7 = (bitString, arrayData2) => {
351
356
  return [{ ...arrayData2, value, state }, bitString];
352
357
  };
353
358
  var rawStateStringifier = (arrayData2) => arrayData2.stateBits ? rawIntStringifier(arrayData2.value.length - arrayData2.minCount, arrayData2.stateBits) : "";
359
+ var rawStringifier7 = (arrayData2) => {
360
+ return rawStateStringifier(arrayData2) + arrayData2.value.map(nestedDataStringifier).join("");
361
+ };
354
362
 
355
363
  // src/parsers/optionalParser.ts
356
364
  var getState = (bitString) => Number(bitString.slice(0, 1));
@@ -362,6 +370,7 @@ var rawParser8 = (bitString, optionalData2) => {
362
370
  return [{ ...optionalData2, value, state }, remainingBitstring];
363
371
  };
364
372
  var rawStateStringifier2 = (optionalData2) => optionalData2.state ? "1" : "0";
373
+ var rawStringifier8 = (optionalData2) => optionalData2.value === null ? rawStateStringifier2(optionalData2) : rawStateStringifier2(optionalData2) + nestedDataStringifier(optionalData2.value);
365
374
 
366
375
  // src/parsers/enumOptionsFactory.ts
367
376
  var getStateIndex = (enumOptionsData2, bitString) => {
@@ -376,6 +385,7 @@ var rawParser9 = (bitString, enumOptionsData2) => {
376
385
  return [{ ...enumOptionsData2, value, state }, remainingBitstring];
377
386
  };
378
387
  var rawStateStringifier3 = (enumOptionsData2) => rawIntStringifier(enumOptionsData2.state, enumOptionsData2.stateBits);
388
+ var rawStringifier9 = (enumOptionsData2) => rawStateStringifier3(enumOptionsData2) + nestedDataStringifier(enumOptionsData2.value);
379
389
 
380
390
  // src/parsers/parsers.ts
381
391
  var valueBitsParser = (bitString, mapData) => {
@@ -461,6 +471,16 @@ var dataBitsStringifier = (data) => {
461
471
  return rawStringifier6(data.value, data);
462
472
  }
463
473
  };
474
+ var complexDataStringifier = (complexDataEntry) => {
475
+ switch (complexDataEntry.type) {
476
+ case "ARRAY":
477
+ return rawStringifier7(complexDataEntry);
478
+ case "OPTIONAL":
479
+ return rawStringifier8(complexDataEntry);
480
+ case "ENUM_OPTIONS":
481
+ return rawStringifier9(complexDataEntry);
482
+ }
483
+ };
464
484
  var complexDataStateStringifier = (complexDataEntry) => {
465
485
  switch (complexDataEntry.type) {
466
486
  case "ARRAY":
@@ -471,6 +491,7 @@ var complexDataStateStringifier = (complexDataEntry) => {
471
491
  return rawStateStringifier3(complexDataEntry);
472
492
  }
473
493
  };
494
+ var nestedDataStringifier = (nestedData) => nestedData.map((d) => ComplexDataValues.includes(d.type) ? complexDataStringifier(d) : dataBitsStringifier(d)).join("");
474
495
  var dataEntryCorrecting = (dataEntry2) => dataBitsParser(dataBitsStringifier(dataEntry2), dataEntry2);
475
496
  var base64url = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
476
497
  var getBitsForEnumArrayCountOfBase = (count, base) => Math.ceil(Math.log2(base) * count);
@@ -770,18 +791,21 @@ export {
770
791
  parseBase64ToBits,
771
792
  interpolateEntryAt,
772
793
  getRelativeValue,
794
+ getOptionsFromMaxAndMapping,
773
795
  getInitialStateFromBase64,
796
+ getEnumMaxAndMappingFromOptions,
774
797
  getBitsCount7 as getBitsCount,
775
798
  dataEntryCorrecting,
776
799
  dataEntryBitstringParser,
777
800
  dataBitsStringifier,
778
801
  dataBitsParser,
779
802
  createStateDataObject,
803
+ complexDataStringifier,
804
+ complexDataStateStringifier,
780
805
  SignificandMaxBits,
781
806
  PROTECTED_ATTRIBUTE_NAMES,
782
807
  IntegerMaxBits,
808
+ DescriptorFactory,
783
809
  DataTypeValues,
784
- DataEntryFactory,
785
- ComplexDataValues,
786
- ComplexDataEntryFactory
810
+ ComplexDataValues
787
811
  };
@@ -1,3 +1,4 @@
1
+ import { EnumMappingType } from './enumData';
1
2
  /**
2
3
  * Enum Array object
3
4
  *
@@ -16,5 +17,5 @@ export type EnumArrayData = {
16
17
  maxCount: number;
17
18
  value: number[];
18
19
  max: number;
19
- mapping: any[];
20
+ mapping: EnumMappingType;
20
21
  };
@@ -1,4 +1,6 @@
1
1
  export declare const EnumMaxBits = 8;
2
+ export type EnumMappingType = (string | number | object)[];
3
+ export type EnumOptionsType = string | number | EnumMappingType;
2
4
  /**
3
5
  * Enum object
4
6
  *
@@ -10,5 +12,5 @@ export type EnumData = {
10
12
  value: number;
11
13
  max: number;
12
14
  bits: number;
13
- mapping: (string | number | object)[];
15
+ mapping: EnumMappingType;
14
16
  };
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "dist/*"
7
7
  ],
8
8
  "type": "module",
9
- "version": "0.2.0",
9
+ "version": "0.2.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": {