url-safe-bitpacking 0.2.0 → 0.3.0

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.
Files changed (56) hide show
  1. package/README.md +20 -60
  2. package/dist/enums/dataTypes.d.ts +16 -4
  3. package/dist/factory/arrayFactory.d.ts +3 -2
  4. package/dist/factory/booleanFactory.d.ts +2 -1
  5. package/dist/factory/enumArrayFactory.d.ts +3 -2
  6. package/dist/factory/enumFactory.d.ts +3 -1
  7. package/dist/factory/enumOptionsFactory.d.ts +3 -2
  8. package/dist/factory/factory.d.ts +14 -12
  9. package/dist/factory/floatFactory.d.ts +2 -2
  10. package/dist/factory/intFactory.d.ts +2 -1
  11. package/dist/factory/objectFactory.d.ts +3 -0
  12. package/dist/factory/optionalFactory.d.ts +3 -2
  13. package/dist/factory/utils.d.ts +12 -2
  14. package/dist/factory/versionFactory.d.ts +2 -1
  15. package/dist/index.d.ts +5 -5
  16. package/dist/index.js +548 -519
  17. package/dist/parsers/arrayParser.d.ts +4 -3
  18. package/dist/parsers/enumArrayParser.d.ts +3 -1
  19. package/dist/parsers/enumOptionsParser.d.ts +5 -0
  20. package/dist/parsers/index.d.ts +1 -0
  21. package/dist/parsers/intParser.d.ts +2 -4
  22. package/dist/parsers/objectParser.d.ts +4 -0
  23. package/dist/parsers/optionalParser.d.ts +4 -3
  24. package/dist/parsers/parserNestedDataUtils.d.ts +14 -0
  25. package/dist/parsers/parserUtils.d.ts +56 -0
  26. package/dist/parsers/parsers.d.ts +14 -80
  27. package/dist/stateHandling/index.d.ts +1 -1
  28. package/dist/stateHandling/stateNode.d.ts +123 -0
  29. package/dist/typeFactory/dataEntryTyping.d.ts +2 -2
  30. package/dist/types/arrayData.d.ts +3 -3
  31. package/dist/types/dataEntry.d.ts +45 -15
  32. package/dist/types/enumArrayData.d.ts +4 -1
  33. package/dist/types/enumData.d.ts +3 -1
  34. package/dist/types/enumOptionsData.d.ts +5 -3
  35. package/dist/types/index.d.ts +2 -1
  36. package/dist/types/objectData.d.ts +8 -0
  37. package/dist/types/optionalData.d.ts +4 -3
  38. package/dist/types/stateDataEntry.d.ts +10 -6
  39. package/dist/types/updateType.d.ts +16 -0
  40. package/dist/update/arrayUpdate.d.ts +4 -2
  41. package/dist/update/booleanUpdate.d.ts +3 -2
  42. package/dist/update/enumArrayUpdate.d.ts +3 -2
  43. package/dist/update/enumOptionsUpdate.d.ts +3 -2
  44. package/dist/update/enumUpdate.d.ts +2 -1
  45. package/dist/update/floatUpdate.d.ts +2 -1
  46. package/dist/update/index.d.ts +1 -0
  47. package/dist/update/intUpdate.d.ts +2 -1
  48. package/dist/update/objectUpdate.d.ts +2 -0
  49. package/dist/update/optionalUpdate.d.ts +3 -2
  50. package/dist/update/updateUtils.d.ts +27 -0
  51. package/dist/update/updateValues.d.ts +5 -4
  52. package/dist/update/validateUtils.d.ts +2 -0
  53. package/dist/update/versionUpdate.d.ts +3 -2
  54. package/dist/utils/interpolateData.d.ts +4 -1
  55. package/dist/utils/relativeValue.d.ts +4 -1
  56. package/package.json +2 -2
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Package for creating definitions of parametric models that can be stored as compactly as possible in a URL by storing it in a web-safe base-64 string. This pacakge is till very much WIP. Feel free to suggest by making an issue or pull-request [GitHub](https://github.com/JonasWard/url-safe-bitpacking).
4
4
 
5
- ### goal for version 0.2
5
+ ### goal for 1.0
6
6
 
7
7
  | what | code | tests | docs |
8
8
  | ---------------------------------------------------- | -------- | -------- | -------- |
@@ -19,65 +19,25 @@ Package for creating definitions of parametric models that can be stored as comp
19
19
 
20
20
  The goal of this library is to offer a flexible, minimal and, variable object definition that can be stored in the browser URL. The main imagined use-case is parametric models that have nested and variable sub-object definitions. The library heavily relies on the bitpacking of custom bitwidth numeric values. Because of that, the biggest trade-off for this library is legibility. Without the related object definition, it would be impossible to reconstruct the state. The big advantage though is the ability to store rather many variables in a very condensed URL, allowing to store all information in rather short urls which then can be used for qr code generation.
21
21
 
22
- ## bit-level data types
23
-
24
- Currently, there are 4 data types implemented (+1 special case for safety). All data entries have a name that will behave as an attribute name in the object.
25
-
26
- ### bool
27
-
28
- Bool type values are simple yes or no, 1 or 0s, nothing special
29
-
30
- ```typescript
31
- DataEntryFactory.createBoolean(false, 'shapePreProcessingWarpabsolute');
32
- ```
33
-
34
- ### enum
35
-
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
-
38
- ```typescript
39
- DataEntryFactory.createEnum(0, 3, 'footprintType');
40
- ```
41
-
42
- ### int
43
-
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
-
46
- ```typescript
47
- DataEntryFactory.createInt(5, 3, 20, 'circleDivisions');
48
- ```
49
-
50
- ### float
51
-
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
-
54
- ```typescript
55
- DataEntryFactory.createFloat(20, 10, 200, -1, 'shapePreProcessingWarptotal');
56
- ```
57
-
58
- ### enum array
59
-
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
-
62
- ```typescript
63
- DataEntryFactory.createEnumArray([0, 1, 2], 0, 10, 3, 5, 'enumArrayA')
64
- ```
65
-
66
- ### version
67
-
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
-
70
- ```typescript
71
- DataEntryFactory.createVersion(0, 8, 'version');
72
- ```
73
-
74
- ## nested attribute definitions
75
-
76
- More often than not in parametric models, certain data belongs together. It can also happen that the specific state of some values will have an impact on other ones being present (or which ranges are allowed). To be able to deal with this there is the option to nest data. I tried to come with an as concise yet versatile way of defining the object definitions.
77
-
78
- ### single nes
79
-
80
- For the Double Nested arrays there are currently two variations: either an Optional type, which only accepts two values of which is an empty array and will be toggle on/off in relation to a certain boolean data entry.
22
+ # Types defined in `url-safe-bitpacking`
23
+ `url-safe-bitpacking` stores the state of an object according to its definition (`descriptor`) into memory (for now using a `bitstring`, a string consisting of `0` and `1`s, parsed into a `base64` string). Attributes of the object are packed according to their specific `bitwidths`, the amount of bits they take up in memory.
24
+
25
+ From a memory footprint perspective there are two types of attributes in an object defintion. Those that have a definition that gives them a `fixed` bitwidth and those that have a `variable` bitwidth. For the **variable** ones the state of its value will have an impact on the memory footprint of the object. For the **fixed** types, their definition defines their memory footprint. Some of the objects with a **variable** footprint have some state to them, which informs how the state should be parsed. The size of this state is defined by the **descriptor** of the object.
26
+
27
+ | | VERSION | BOOLEAN | ENUM | INT | FLOAT | ENUM_ARRAY | OPTIONAL | ENUM_OPTIONS | ARRAY | OBJECT |
28
+ | ------------------------ | ----------- | ----------- | ----------- | ----------- | ----------- | -------------- | ------------ | ---------------- | ----------- | ----------- |
29
+ | Predefined Bitwidth | **✓** | **✓** | **✓** | **✓** | **✓** | ✗ | ✗ | ✗ | ✗ | ✗ |
30
+ | Has State Bit | ✗ | ✗ | ✗ | ✗ | ✗ | **✓** | **✓** | **✓** | **✓** | ✗ |
31
+ | Min Bitwidth | `4` | `1` | `1` | `0` | `0` | `1` | – | – | – | – |
32
+ | Max Bitwidth | `10` | `1` | `10` | `21` | `21` | `10` | – | – | – | – |
33
+ | Min State Bitwidth | – | – | – | – | – | `0` | `1` | `1` | `0` | – |
34
+ | Max State Bitwidth | – | – | – | – | – | `10` | `1` | `10` | `10` | – |
35
+ | Max Available States | `1024` | `2` | `1024` | `2097152` | `2097152` | `1024 x 1024` | `2` | `1024` | `1024` | `0` |
36
+ | Has Mapping | ✗ | ✗ | **✓** | ✗ | ✗ | **✓** | ✗ | **✓** | ✗ | ✗ |
37
+ | Has Nested Objects | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | **✓** | **✓** | **✓** | **✓** |
38
+ | **UPDATING** | **VERSION** | **BOOLEAN** | **ENUM** | **INT** | **FLOAT** | **ENUM_ARRAY** | **OPTIONAL** | **ENUM_OPTIONS** | **ARRAY** | **OBJECT** |
39
+ | Requires Value on Update | **✓** | **✓** | **✓** | **✓** | **✓** | **✓** | **✗** | **✗** | **✗** | **✗** |
40
+ | Requires State on Update | – | – | – | – | – | **✗** | **✓** | **✓** | **✓** | – |
81
41
 
82
42
  # Install
83
43
 
@@ -1,4 +1,16 @@
1
- export declare const DataTypeValues: readonly ["VERSION", "BOOLEAN", "ENUM", "INT", "FLOAT", "ENUM_ARRAY"];
2
- export declare const ComplexDataValues: readonly ["OPTIONAL", "ENUM_OPTIONS", "ARRAY"];
3
- export type DataType = (typeof DataTypeValues)[number];
4
- export type ComplexDataType = (typeof ComplexDataValues)[number];
1
+ import { DataEntry } from '../types';
2
+ export declare const ConstantBitWidthDataTypes: readonly ["VERSION", "BOOLEAN", "ENUM", "INT", "FLOAT"];
3
+ export declare const VariableBitWidthDataTypes: readonly ["ENUM_ARRAY", "OPTIONAL", "ENUM_OPTIONS", "ARRAY", "OBJECT"];
4
+ export declare const HasMappingDataTypes: readonly ["ENUM", "ENUM_ARRAY", "ENUM_OPTIONS"];
5
+ export declare const HasStateBitsDataTypes: readonly ["ENUM_ARRAY", "OPTIONAL", "ENUM_OPTIONS", "ARRAY"];
6
+ export declare const HasChildDataTypes: readonly ["OPTIONAL", "ENUM_OPTIONS"];
7
+ export declare const HasChildrenDataTypes: readonly ["ARRAY", "OBJECT"];
8
+ export declare const HasNestedDataTypes: readonly ["OPTIONAL", "ENUM_OPTIONS", "ARRAY", "OBJECT"];
9
+ export declare const ValueUpdateDataTypes: readonly ["VERSION", "BOOLEAN", "ENUM", "INT", "FLOAT", "ENUM_ARRAY"];
10
+ export declare const StateUpdateDataTypes: readonly ["OPTIONAL", "ENUM_OPTIONS", "ARRAY"];
11
+ export type ValueUpdateType = (typeof ValueUpdateDataTypes)[number];
12
+ export type StateUpdateType = (typeof StateUpdateDataTypes)[number];
13
+ export type DataType = (typeof ConstantBitWidthDataTypes)[number] | (typeof VariableBitWidthDataTypes)[number];
14
+ export type SpecifiedDataEntry<T extends DataType> = DataEntry & {
15
+ type: T;
16
+ };
@@ -1,2 +1,3 @@
1
- import { ArrayDataEntry, NestedData } from '@/types';
2
- export declare const create: (descriptor: NestedData, defaultState?: number, minCount?: number, maxCount?: number, name?: string, index?: number) => ArrayDataEntry;
1
+ import { ArrayDataEntry } from '../types';
2
+ export type ArrayFactory = (descriptor: ArrayDataEntry['descriptor'], defaultState?: number, minCount?: number, maxCount?: number, name?: string) => ArrayDataEntry;
3
+ export declare const create: ArrayFactory;
@@ -1,2 +1,3 @@
1
1
  import { BooleanDataEntry } from '../types';
2
- export declare const create: (value: boolean, name?: string, index?: number) => BooleanDataEntry;
2
+ export type BooleanFactory = (value: boolean, name?: string) => BooleanDataEntry;
3
+ export declare const create: BooleanFactory;
@@ -1,2 +1,3 @@
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 type EnumArrayFactory = (value: number[], options: EnumOptionsType, minCount?: number, maxCount?: number, name?: string) => EnumArrayDataEntry;
3
+ export declare const create: EnumArrayFactory;
@@ -1,2 +1,4 @@
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 type EnumFactory = (value: number, options: EnumOptionsType, name?: string) => EnumDataEntry;
4
+ export declare const create: EnumFactory;
@@ -1,2 +1,3 @@
1
- import { EnumOptionsDataEntry, NestedData } from '@/types';
2
- export declare const create: (descriptor: NestedData[], defaultState?: number, name?: string, index?: number) => EnumOptionsDataEntry;
1
+ import { DataEntry, EnumOptionsDataEntry, EnumOptionsType } from '../types';
2
+ export type EnumOptionsFactory = (descriptor: (DataEntry | null)[], defaultState?: number, name?: string, options?: EnumOptionsType) => EnumOptionsDataEntry;
3
+ export declare const create: EnumOptionsFactory;
@@ -7,19 +7,21 @@ import { create as createEnumArray } from './enumArrayFactory';
7
7
  import { create as createOptional } from './optionalFactory';
8
8
  import { create as createEnumOptions } from './enumOptionsFactory';
9
9
  import { create as createArray } from './arrayFactory';
10
+ import { create as createObject } from './objectFactory';
11
+ import { DataEntry, ObjectDataEntry, VersionDataEntry } from '../types';
10
12
  /**
11
13
  * Record containing all the factory methods for the different data entry objects
12
14
  */
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;
15
+ export declare const DescriptorFactory: {
16
+ FLOAT: typeof createFloat;
17
+ INT: typeof createInt;
18
+ ENUM: typeof createEnum;
19
+ BOOLEAN: typeof createBoolean;
20
+ VERSION: typeof createVersion;
21
+ ENUM_ARRAY: typeof createEnumArray;
22
+ OPTIONAL: typeof createOptional;
23
+ ENUM_OPTIONS: typeof createEnumOptions;
24
+ ARRAY: typeof createArray;
25
+ OBJECT: typeof createObject;
25
26
  };
27
+ export declare const StateDescriptorFactoryMethod: (descriptor: [VersionDataEntry, ...DataEntry[]], name?: string) => ObjectDataEntry;
@@ -1,5 +1,6 @@
1
1
  import { FloatDataEntry } from '../types';
2
2
  import { PrecisionRangeType } from '../types/floatData';
3
+ export type FloatFactory = (value: number, min?: number, max?: number, precision?: PrecisionRangeType, name?: string) => FloatDataEntry;
3
4
  /**
4
5
  * Method to create a float data entry
5
6
  * @param value - `number` default value, should be between `min` and `max`
@@ -7,6 +8,5 @@ import { PrecisionRangeType } from '../types/floatData';
7
8
  * @param max - `number` (default: 1), should be larger than `min`
8
9
  * @param precision - `PrecisionRangeType` (default: 2 -> .01),
9
10
  * @param name - `string`
10
- * @param index - `number`
11
11
  */
12
- export declare const create: (value: number, min?: number, max?: number, precision?: PrecisionRangeType, name?: string, index?: number) => FloatDataEntry;
12
+ export declare const create: FloatFactory;
@@ -1,2 +1,3 @@
1
1
  import { IntDataEntry } from '../types';
2
- export declare const create: (value: number, min?: number, max?: number, name?: string, index?: number) => IntDataEntry;
2
+ export type IntFactory = (value: number, min?: number, max?: number, name?: string) => IntDataEntry;
3
+ export declare const create: IntFactory;
@@ -0,0 +1,3 @@
1
+ import { DataEntry, ObjectDataEntry } from '../types';
2
+ export type ObjectFactory = (descriptor: DataEntry[], name?: string) => ObjectDataEntry;
3
+ export declare const create: ObjectFactory;
@@ -1,2 +1,3 @@
1
- import { NestedData, OptionalDataEntry } from '@/types';
2
- export declare const create: (descriptor: [null, NestedData] | [NestedData, null], defaultState?: boolean, name?: string, index?: number) => OptionalDataEntry;
1
+ import { DataEntry, OptionalDataEntry } from '../types';
2
+ export type OptionalFactory = (descriptor: [DataEntry, null] | [null, DataEntry], defaultState?: boolean, name?: string) => OptionalDataEntry;
3
+ export declare const create: OptionalFactory;
@@ -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;
@@ -1,3 +1,4 @@
1
1
  import { VersionDataEntry } from '../types';
2
2
  import { VersionRangeType } from '../types/versionData';
3
- export declare const create: (value: number, bits?: VersionRangeType, name?: string, index?: number) => VersionDataEntry;
3
+ export type VersionFactory = (value: number, bits?: VersionRangeType, name?: string) => VersionDataEntry;
4
+ export declare const create: VersionFactory;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
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';
5
- export { createStateDataObject, getInitialStateFromBase64 } from './stateHandling';
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';
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';
6
5
  export { interpolateEntryAt, getRelativeValue } from './utils';
6
+ export { getEnumMaxAndMappingFromOptions, getOptionsFromMaxAndMapping } from './factory/utils';