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/dist/index.js CHANGED
@@ -1,10 +1,9 @@
1
1
  // src/enums/dataTypes.ts
2
- var DataTypeValues = ["VERSION", "BOOLEAN", "ENUM", "INT", "FLOAT", "ENUM_ARRAY"];
3
- var ComplexDataValues = ["OPTIONAL", "ENUM_OPTIONS", "ARRAY"];
2
+ var ConstantBitWidthDataTypes = ["VERSION", "BOOLEAN", "ENUM", "INT", "FLOAT"];
3
+ var VariableBitWidthDataTypes = ["ENUM_ARRAY", "OPTIONAL", "ENUM_OPTIONS", "ARRAY", "OBJECT"];
4
+ var HasStateBitsDataTypes = ["ENUM_ARRAY", "OPTIONAL", "ENUM_OPTIONS", "ARRAY"];
4
5
  // src/types/floatData.ts
5
6
  var SignificandMaxBits = 20;
6
- // src/types/enumData.ts
7
- var EnumMaxBits = 8;
8
7
  // src/types/intData.ts
9
8
  var IntegerMaxBits = 12;
10
9
  // src/types/dataEntry.ts
@@ -26,235 +25,64 @@ var PROTECTED_ATTRIBUTE_NAMES = [
26
25
  "descriptor",
27
26
  "mapping"
28
27
  ];
29
- // src/factory/helperMethod.ts
30
- var getBitsForIntegerNumber = (number, maxBits) => {
31
- const bitCount = Math.ceil(Math.log2(number));
32
- if (bitCount > maxBits)
33
- throw new Error(`Cannot get ${maxBits} bits for a number with ${bitCount} bits`);
34
- return bitCount;
35
- };
36
- var getMinimumBitsForInteger = (v) => Math.ceil(Math.log2(v + 1));
37
-
38
- // src/factory/floatFactory.ts
39
- var create = (value, min = 0, max = 1, precision = 2, name = "", index = -1) => {
40
- const precisionMultiplier = 10 ** precision;
41
- const roundedMin = Math.floor(min * precisionMultiplier);
42
- const roundedMax = Math.ceil(max * precisionMultiplier);
43
- const delta = roundedMax - roundedMin;
44
- const significand = Math.max(1, getBitsForIntegerNumber(delta, SignificandMaxBits));
45
- return {
46
- value,
47
- type: "FLOAT",
48
- min: roundedMin / precisionMultiplier,
49
- max: roundedMax / precisionMultiplier,
50
- precision,
51
- significand,
52
- name,
53
- index
54
- };
55
- };
56
-
57
- // src/factory/intFactory.ts
58
- var create2 = (value, min = 0, max = 10, name = "", index = -1) => {
59
- if (!Number.isInteger(min) || !Number.isInteger(max))
60
- throw new Error("min and max must be integers");
61
- if (max - min < 1)
62
- throw new Error("max must be at least one");
63
- if (Math.abs(max - min) > 2 ** IntegerMaxBits - 1)
64
- throw new Error("max - min must be less than 1024");
65
- const bits = getBitsForIntegerNumber(max - min + 1, IntegerMaxBits);
66
- return { value, type: "INT", min, max, bits, name, index };
67
- };
68
-
69
- // src/factory/booleanFactory.ts
70
- var create3 = (value, name = "", index = -1) => ({
71
- value,
72
- type: "BOOLEAN",
73
- name,
74
- index
75
- });
76
-
77
- // src/factory/versionFactory.ts
78
- var create4 = (value, bits = 8, name = "", index = -1) => ({
79
- value,
80
- type: "VERSION",
81
- bits,
82
- name,
83
- index
84
- });
85
-
86
- // src/factory/utils.ts
87
- var getOptionsFromEnumOptions = (options) => {
88
- if (typeof options === "string")
89
- return { max: options.length - 1, mapping: options.split(",").map(Number) };
90
- if (typeof options === "number")
91
- return { max: options, mapping: Array.from({ length: options + 1 }, (_, i) => i) };
92
- return { max: options.length - 1, mapping: options };
93
- };
94
-
95
- // src/factory/enumFactory.ts
96
- var create5 = (value, options, name = "", index = -1) => {
97
- const { max, mapping } = getOptionsFromEnumOptions(options);
98
- if (!Number.isInteger(max))
99
- throw new Error(`max must be integers, you have given ${max}`);
100
- if (max < 1)
101
- throw new Error("max must be at least one");
102
- if (max > 2 ** EnumMaxBits - 1)
103
- throw new Error("max - min must be less than 256");
104
- const bits = getBitsForIntegerNumber(max + 1, EnumMaxBits);
105
- return { value, type: "ENUM", max, bits, name, index, mapping };
106
- };
107
-
108
- // src/factory/enumArrayFactory.ts
109
- var create6 = (value, options, minCount = 1, maxCount = 10, name = "", index = -1) => {
110
- const { max, mapping } = getOptionsFromEnumOptions(options);
111
- if (!Number.isInteger(max))
112
- throw new Error(`max must be integers, you have given ${max}`);
113
- if (!Number.isInteger(minCount) || !Number.isInteger(maxCount))
114
- throw new Error("minCount and maxCount must be integers");
115
- if (max < 1)
116
- throw new Error("must have at least two options");
117
- if (max > 2 ** IntegerMaxBits - 1)
118
- throw new Error(`maximum allowed options is 1024, you have given ${max + 1} options`);
119
- minCount = Math.min(minCount, maxCount);
120
- maxCount = Math.max(minCount, maxCount);
121
- if (minCount < 1)
122
- throw new Error("minCount must be at least one");
123
- if (maxCount - minCount < 0)
124
- throw new Error(`count range length must be positive, given count range length is ${Math.abs(maxCount - minCount)}`);
125
- if (Math.abs(maxCount - minCount) > 2 ** IntegerMaxBits - 1)
126
- throw new Error(`count range length must be less than 1024, given count range length is ${Math.abs(maxCount - minCount)}`);
127
- value.forEach((v, i) => {
128
- if (!Number.isInteger(v))
129
- throw new Error(`all entries must be integers, index ${i} (${v}) is not`);
130
- if (v > max)
131
- throw new Error(`all entries must be within the range ${0} - ${max}, index ${i} (${v}) is not`);
132
- });
133
- if (value.length < minCount || value.length > maxCount)
134
- throw new Error(`value length must be between minCount and maxCount, ${value.length} is not between ${minCount} and ${maxCount}`);
135
- return {
136
- type: "ENUM_ARRAY",
137
- minCount,
138
- maxCount,
139
- value: JSON.parse(JSON.stringify(value)),
140
- max,
141
- name,
142
- index,
143
- mapping
144
- };
28
+ // src/types/updateType.ts
29
+ var ComplexDataTypes = ["ENUM_OPTIONS", "OPTIONAL", "ARRAY"];
30
+ // src/parsers/parserUtils.ts
31
+ var base64url = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
32
+ var getBitsForEnumArrayCountOfBase = (count, base) => Math.ceil(Math.log2(base) * count);
33
+ var convertArbitraryBaseToBitString = (input, fromBase) => {
34
+ const expectedOutputLength = getBitsForEnumArrayCountOfBase(input.length, fromBase);
35
+ const fromBaseBigInt = BigInt(fromBase);
36
+ let decimalValue = BigInt(0);
37
+ for (let i = input.length - 1;i >= 0; i--)
38
+ decimalValue = decimalValue * fromBaseBigInt + BigInt(input[i]);
39
+ const s = decimalValue.toString(2).padStart(expectedOutputLength, "0");
40
+ return s;
145
41
  };
146
-
147
- // src/factory/optionalFactory.ts
148
- var create7 = (descriptor, defaultState = false, name = "", index = -1) => {
149
- if (descriptor[0] === null && descriptor[1] === null)
150
- throw new Error("descriptor must have at least one non-null value");
151
- if (descriptor[0] !== null && descriptor[1] !== null)
152
- throw new Error("descriptor must have only one non-null value");
153
- return {
154
- type: "OPTIONAL",
155
- state: defaultState,
156
- descriptor,
157
- value: JSON.parse(JSON.stringify(defaultState ? descriptor[1] : descriptor[0])),
158
- name,
159
- index
160
- };
42
+ var convertBitStringToArbitraryBase = (input, toBase, expectedOutputLength) => {
43
+ let decimalValue = BigInt(`0b${input}`);
44
+ const toBaseBigInt = BigInt(toBase);
45
+ const result = [];
46
+ while (decimalValue > 0) {
47
+ const remainder = decimalValue % toBaseBigInt;
48
+ result.push(Number(remainder));
49
+ decimalValue = decimalValue / toBaseBigInt;
50
+ }
51
+ if (expectedOutputLength !== undefined && result.length !== expectedOutputLength)
52
+ for (let i = result.length;i < expectedOutputLength; i++)
53
+ result.push(0);
54
+ return result;
161
55
  };
162
-
163
- // src/factory/enumOptionsFactory.ts
164
- var maxEnumOptions = 64;
165
- var maxEnumOptionsBits = getMinimumBitsForInteger(maxEnumOptions);
166
- var create8 = (descriptor, defaultState = 0, name = "", index = -1) => {
167
- if (descriptor.length < 2)
168
- throw new Error("descriptor must have at least two entries");
169
- if (descriptor.length - 1 < defaultState)
170
- throw new Error("defaultState must be less than the length of the descriptor");
171
- return {
172
- value: JSON.parse(JSON.stringify(descriptor[defaultState])),
173
- descriptor,
174
- name,
175
- index,
176
- type: "ENUM_OPTIONS",
177
- stateBits: getBitsForIntegerNumber(descriptor.length, maxEnumOptionsBits),
178
- state: defaultState
179
- };
56
+ var parseBitsToBase64 = (bits) => {
57
+ const chunks = bits.match(/.{1,6}/g);
58
+ const numbers = chunks?.map((c) => Number.parseInt(c.padEnd(6, "0"), 2)) ?? [];
59
+ return numbers.map((n) => base64url.charAt(n)).join("");
180
60
  };
181
-
182
- // src/factory/arrayFactory.ts
183
- var maxArrayCount = 64;
184
- var create9 = (descriptor, defaultState = 0, minCount = 0, maxCount = 10, name = "", index = -1) => {
185
- if (!Number.isInteger(minCount) || !Number.isInteger(maxCount))
186
- throw new Error("minCount and maxCount must be integers");
187
- if (minCount < 0)
188
- throw new Error("minCount must be at least 0");
189
- if (maxCount < 0)
190
- throw new Error("maxCount must be at least 0");
191
- if (maxCount - minCount < 0)
192
- throw new Error("maxCount must be greater than or equal to minCount");
193
- if (maxCount - minCount > maxArrayCount)
194
- throw new Error(`maxCount (${maxCount}) - minCount (${minCount}) = ${maxCount - minCount} must be less than or equal to maxArrayCount (${maxArrayCount})`);
195
- if (defaultState < minCount || defaultState > maxCount)
196
- throw new Error(`defaultState must be between minCount (${minCount}) and maxCount (${maxCount}), given defaultState is ${defaultState}`);
197
- const stateBits = getMinimumBitsForInteger(maxCount - minCount);
198
- return {
199
- value: [...Array(defaultState)].map(() => JSON.parse(JSON.stringify(descriptor))),
200
- descriptor,
201
- type: "ARRAY",
202
- minCount,
203
- maxCount,
204
- stateBits,
205
- state: defaultState,
206
- name,
207
- index
208
- };
61
+ var parseBase64ToBits = (base64) => {
62
+ const numbers = base64.split("").map((c) => base64url.indexOf(c));
63
+ const chunks = numbers.map((n) => n.toString(2).padStart(6, "0"));
64
+ return chunks.join("");
209
65
  };
210
-
211
- // 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
66
+ var rawIntStringifier = (value, bitCount) => {
67
+ if (Number.isInteger(value) === false)
68
+ throw new Error("Value is not an integer");
69
+ return value.toString(2).padStart(bitCount, "0");
224
70
  };
225
- // src/parsers/intParser.ts
226
- var getBitsCount = (intData2) => intData2.bits;
227
71
  var rawValueParser = (stateString, bitCount) => {
228
72
  if (stateString.length < bitCount)
229
73
  throw new Error(`To few bits for this int bit string (${stateString.length} instead of ${bitCount})`);
230
74
  if (stateString.length > bitCount)
231
75
  throw new Error(`To many bits for this int bit string (${stateString.length} instead of ${bitCount})`);
76
+ if (bitCount === 0)
77
+ return 0;
232
78
  const parsed = parseInt(stateString, 2);
233
79
  if (isNaN(parsed))
234
80
  throw new Error("Invalid int state string");
235
81
  return parsed;
236
82
  };
237
- var rawParser = (stateString, intData2) => {
238
- const v = rawValueParser(stateString, intData2.bits) + intData2.min;
239
- if (v > intData2.max)
240
- throw new Error("Value exceeds max");
241
- return v;
242
- };
243
- var rawIntStringifier = (value, bitCount) => {
244
- if (Number.isInteger(value) === false)
245
- throw new Error("Value is not an integer");
246
- return value.toString(2).padStart(bitCount, "0");
247
- };
248
- var rawStringifier = (value, intData2) => {
249
- if (value < intData2.min)
250
- throw new Error("Value is below min");
251
- if (value > intData2.max)
252
- throw new Error("Value exceeds max");
253
- return rawIntStringifier(value - intData2.min, intData2.bits);
254
- };
255
83
 
256
84
  // src/parsers/floatParser.ts
257
- var getBitsCount2 = (floatData2) => floatData2.significand;
85
+ var getBitsCount = (floatData2) => floatData2.significand;
258
86
  var rawValueParser2 = (stateString, significandBits, precision) => {
259
87
  if (stateString.length < significandBits)
260
88
  throw new Error(`To few bits for this float bit string (${stateString.length} instead of ${significandBits})`);
@@ -263,13 +91,29 @@ var rawValueParser2 = (stateString, significandBits, precision) => {
263
91
  const significand = rawValueParser(stateString, significandBits);
264
92
  return significand * 10 ** -precision;
265
93
  };
266
- var rawParser2 = (stateString, floatData2) => {
94
+ var rawParser = (stateString, floatData2) => {
267
95
  const v = floatData2.min + rawValueParser2(stateString, floatData2.significand, floatData2.precision);
268
96
  if (v > floatData2.max)
269
97
  throw new Error("Float value exceeds max");
270
98
  return v;
271
99
  };
272
- var rawStringifier2 = (value, floatData2) => rawIntStringifier(Math.round((value - floatData2.min) * 10 ** floatData2.precision), floatData2.significand);
100
+ var rawStringifier = (value, floatData2) => rawIntStringifier(Math.round((value - floatData2.min) * 10 ** floatData2.precision), floatData2.significand);
101
+
102
+ // src/parsers/intParser.ts
103
+ var getBitsCount2 = (intData2) => intData2.bits;
104
+ var rawParser2 = (stateString, intData2) => {
105
+ const v = rawValueParser(stateString, intData2.bits) + intData2.min;
106
+ if (v > intData2.max)
107
+ throw new Error("Value exceeds max");
108
+ return v;
109
+ };
110
+ var rawStringifier2 = (value, intData2) => {
111
+ if (value < intData2.min)
112
+ throw new Error("Value is below min");
113
+ if (value > intData2.max)
114
+ throw new Error("Value exceeds max");
115
+ return rawIntStringifier(value - intData2.min, intData2.bits);
116
+ };
273
117
 
274
118
  // src/parsers/enumParser.ts
275
119
  var getBitsCount3 = (versionData2) => versionData2.bits;
@@ -302,294 +146,270 @@ var rawParser5 = (stateString) => rawValueParser3(stateString);
302
146
  var rawStringifier5 = (value) => value ? "1" : "0";
303
147
 
304
148
  // src/parsers/enumArrayParser.ts
305
- var getCountBitsCount = (enumArrayData2) => getBitsForIntegerNumber(enumArrayData2.maxCount - enumArrayData2.minCount + 1, IntegerMaxBits);
306
149
  var getNumberBitsCountForBase = (count, base) => getBitsForEnumArrayCountOfBase(count, base);
307
150
  var getEnumArrayBase = (enumArrayData2) => enumArrayData2.max + 1;
308
- var getCount = (enumArrayData2, bitString) => {
309
- const countBits = getCountBitsCount(enumArrayData2);
310
- if (countBits === 0)
311
- return enumArrayData2.minCount;
312
- return rawValueParser(bitString.slice(0, countBits), countBits) + enumArrayData2.minCount;
313
- };
314
- var getBitsCount6 = (enumArrayData2, bitString) => {
315
- const countBits = getCountBitsCount(enumArrayData2);
316
- const count = getCount(enumArrayData2, bitString);
317
- const valuesBitCount = getNumberBitsCountForBase(count, getEnumArrayBase(enumArrayData2));
318
- return countBits + valuesBitCount;
319
- };
320
- var rawParser6 = (bitString, enumArrayData2) => {
321
- const countBits = getCountBitsCount(enumArrayData2);
151
+ var getCount = (enumArrayData2, bitString) => rawValueParser(bitString.slice(0, enumArrayData2.stateBits), enumArrayData2.stateBits) + enumArrayData2.minCount;
152
+ var rawParser6 = (enumArrayData2, bitString) => {
322
153
  const count = getCount(enumArrayData2, bitString);
323
154
  const base = getEnumArrayBase(enumArrayData2);
324
155
  const valuesBitCount = getNumberBitsCountForBase(count, base);
325
- return convertBitStringToArbitraryBase(bitString.slice(countBits, countBits + valuesBitCount), base, count);
156
+ const value = convertBitStringToArbitraryBase(bitString.slice(enumArrayData2.stateBits, enumArrayData2.stateBits + valuesBitCount), base, count);
157
+ return [{ ...enumArrayData2, value }, bitString.slice(enumArrayData2.stateBits + valuesBitCount)];
326
158
  };
159
+ var rawStateStringifier = (value, minCount, stateBits) => stateBits ? rawIntStringifier(value.length - minCount, stateBits) : "";
327
160
  var rawStringifier6 = (value, enumArrayData2) => {
328
- const countBits = getCountBitsCount(enumArrayData2);
329
- const count = value.length;
161
+ const countBitstring = rawStateStringifier(value, enumArrayData2.minCount, enumArrayData2.stateBits);
330
162
  const base = getEnumArrayBase(enumArrayData2);
331
- const countBitstring = countBits ? rawIntStringifier(count - enumArrayData2.minCount, countBits) : "";
332
163
  const enumArrayBitstring = convertArbitraryBaseToBitString(value, base);
333
164
  return countBitstring + enumArrayBitstring;
334
165
  };
335
166
 
167
+ // src/parsers/parserNestedDataUtils.ts
168
+ var nestedDataStringifier = (nestedData) => nestedData.map(dataEntryBitsStringifier).join("");
169
+ var nestedDataBitstringParser = (bitstring, descriptor) => {
170
+ const resultingNestedData = descriptor.map((data) => {
171
+ const [resultingData, remainingBitstring] = dataEntryBitstringParser(data, bitstring);
172
+ bitstring = remainingBitstring;
173
+ return resultingData;
174
+ });
175
+ return [resultingNestedData, bitstring];
176
+ };
177
+
336
178
  // src/parsers/arrayParser.ts
337
179
  var getCount2 = (arrayData2, bitString) => {
338
180
  if (arrayData2.stateBits === 0)
339
181
  return arrayData2.minCount;
340
182
  return rawValueParser(bitString.slice(0, arrayData2.stateBits), arrayData2.stateBits) + arrayData2.minCount;
341
183
  };
342
- var rawParser7 = (bitString, arrayData2) => {
184
+ var rawParser7 = (arrayData2, bitString) => {
343
185
  const state = getCount2(arrayData2, bitString);
344
186
  bitString = bitString.slice(arrayData2.stateBits);
345
187
  const value = [];
346
188
  for (let i = 0;i < state; i++) {
347
- const [nestedData, remainingBitstring] = nestedDataBitstringParser(bitString, arrayData2.descriptor);
348
- value.push(nestedData);
189
+ const [entry, remainingBitstring] = dataEntryBitstringParser(arrayData2.descriptor, bitString);
190
+ value.push(entry);
349
191
  bitString = remainingBitstring;
350
192
  }
351
193
  return [{ ...arrayData2, value, state }, bitString];
352
194
  };
353
- var rawStateStringifier = (arrayData2) => arrayData2.stateBits ? rawIntStringifier(arrayData2.value.length - arrayData2.minCount, arrayData2.stateBits) : "";
195
+ var rawStateStringifier2 = (state, minCount, stateBits) => stateBits ? rawIntStringifier(state - minCount, stateBits) : "";
196
+ var rawStringifier7 = (arrayData2) => {
197
+ return rawStateStringifier2(arrayData2.state, arrayData2.minCount, arrayData2.stateBits) + nestedDataStringifier(arrayData2.value);
198
+ };
354
199
 
355
200
  // src/parsers/optionalParser.ts
356
201
  var getState = (bitString) => Number(bitString.slice(0, 1));
357
- var rawParser8 = (bitString, optionalData2) => {
202
+ var rawParser8 = (optionalData2, bitString) => {
358
203
  const descriptorIndex = getState(bitString);
359
- bitString = bitString.slice(1);
360
- const [value, remainingBitstring] = optionalData2.descriptor[descriptorIndex] ? nestedDataBitstringParser(bitString, optionalData2.descriptor[descriptorIndex]) : [null, bitString];
204
+ bitString = bitString.slice(optionalData2.stateBits);
205
+ const [value, remainingBitstring] = optionalData2.descriptor[descriptorIndex] ? dataEntryBitstringParser(optionalData2.descriptor[descriptorIndex], bitString) : [null, bitString];
361
206
  const state = Boolean(descriptorIndex);
362
207
  return [{ ...optionalData2, value, state }, remainingBitstring];
363
208
  };
364
- var rawStateStringifier2 = (optionalData2) => optionalData2.state ? "1" : "0";
209
+ var rawStateStringifier3 = (state) => state ? "1" : "0";
210
+ var rawStringifier8 = (optionalData2) => optionalData2.value === null ? rawStateStringifier3(optionalData2.state) : rawStateStringifier3(optionalData2.state) + dataEntryBitsStringifier(optionalData2.value);
365
211
 
366
- // src/parsers/enumOptionsFactory.ts
212
+ // src/parsers/enumOptionsParser.ts
367
213
  var getStateIndex = (enumOptionsData2, bitString) => {
368
214
  if (enumOptionsData2.stateBits === 0)
369
215
  return 0;
370
216
  return rawValueParser(bitString.slice(0, enumOptionsData2.stateBits), enumOptionsData2.stateBits);
371
217
  };
372
- var rawParser9 = (bitString, enumOptionsData2) => {
218
+ var rawParser9 = (enumOptionsData2, bitString) => {
373
219
  const state = getStateIndex(enumOptionsData2, bitString);
374
220
  bitString = bitString.slice(enumOptionsData2.stateBits);
375
- const [value, remainingBitstring] = nestedDataBitstringParser(bitString, enumOptionsData2.descriptor[state]);
221
+ const [value, remainingBitstring] = enumOptionsData2.descriptor[state] ? dataEntryBitstringParser(enumOptionsData2.descriptor[state], bitString) : [null, bitString];
376
222
  return [{ ...enumOptionsData2, value, state }, remainingBitstring];
377
223
  };
378
- var rawStateStringifier3 = (enumOptionsData2) => rawIntStringifier(enumOptionsData2.state, enumOptionsData2.stateBits);
224
+ var rawStateStringifier4 = (state, stateBits) => rawIntStringifier(state, stateBits);
225
+ var rawStringifier9 = (enumOptionsData2) => rawStateStringifier4(enumOptionsData2.state, enumOptionsData2.stateBits) + (enumOptionsData2.value ? dataEntryBitsStringifier(enumOptionsData2.value) : "");
226
+
227
+ // src/parsers/objectParser.ts
228
+ var rawParser10 = (objectData2, bitString) => {
229
+ const [value, remainingBitstring] = nestedDataBitstringParser(bitString, objectData2.descriptor);
230
+ return [{ ...objectData2, value }, remainingBitstring];
231
+ };
232
+ var rawStringifier10 = (objectData2) => nestedDataStringifier(objectData2.value);
379
233
 
380
234
  // src/parsers/parsers.ts
381
- var valueBitsParser = (bitString, mapData) => {
382
- switch (mapData.type) {
235
+ var simpleContentBitsCountForDataEntry = (entry) => {
236
+ switch (entry.type) {
383
237
  case "BOOLEAN":
384
- return rawParser5(bitString);
238
+ return getBitsCount5();
385
239
  case "INT":
386
- return rawParser(bitString, mapData);
240
+ return getBitsCount2(entry);
387
241
  case "ENUM":
388
- return rawParser3(bitString, mapData);
242
+ return getBitsCount3(entry);
389
243
  case "FLOAT":
390
- return rawParser2(bitString, mapData);
244
+ return getBitsCount(entry);
391
245
  case "VERSION":
392
- return rawParser4(bitString, mapData);
393
- case "ENUM_ARRAY":
394
- return rawParser6(bitString, mapData);
246
+ return getBitsCount4(entry);
395
247
  }
396
248
  };
397
- var dataBitsParser = (rawString, mapData) => {
398
- switch (mapData.type) {
249
+ var helperSimpleParserWrapper = (entry, bitstring) => [
250
+ { ...entry, value: simpleFromValueParser(bitstring.slice(0, simpleContentBitsCountForDataEntry(entry)), entry) },
251
+ bitstring.slice(simpleContentBitsCountForDataEntry(entry))
252
+ ];
253
+ var simpleFromValueParser = (bitString, entry) => {
254
+ switch (entry.type) {
399
255
  case "BOOLEAN":
400
- return { ...mapData, value: valueBitsParser(rawString, mapData) };
256
+ return rawParser5(bitString);
257
+ case "INT":
258
+ return rawParser2(bitString, entry);
401
259
  case "ENUM":
260
+ return rawParser3(bitString, entry);
261
+ case "FLOAT":
262
+ return rawParser(bitString, entry);
263
+ case "VERSION":
264
+ return rawParser4(bitString, entry);
265
+ }
266
+ };
267
+ var dataEntryBitstringParser = (entry, bitString) => {
268
+ const result = _dataEntryBitstringParser(entry, bitString);
269
+ return result;
270
+ };
271
+ var _dataEntryBitstringParser = (entry, bitString) => {
272
+ switch (entry.type) {
273
+ case "BOOLEAN":
402
274
  case "INT":
275
+ case "ENUM":
403
276
  case "FLOAT":
404
277
  case "VERSION":
405
- return { ...mapData, value: valueBitsParser(rawString, mapData) };
278
+ return helperSimpleParserWrapper(entry, bitString);
406
279
  case "ENUM_ARRAY":
407
- return { ...mapData, value: valueBitsParser(rawString, mapData) };
280
+ return rawParser6(entry, bitString);
281
+ case "ARRAY":
282
+ return rawParser7(entry, bitString);
283
+ case "OPTIONAL":
284
+ return rawParser8(entry, bitString);
285
+ case "ENUM_OPTIONS":
286
+ return rawParser9(entry, bitString);
287
+ case "OBJECT":
288
+ return rawParser10(entry, bitString);
408
289
  }
409
290
  };
410
- var getBitsCount7 = (mapData, bitString) => {
291
+ var getBitsCount6 = (mapData) => {
411
292
  switch (mapData.type) {
412
293
  case "BOOLEAN":
413
294
  return getBitsCount5();
414
295
  case "INT":
415
- return getBitsCount(mapData);
416
- case "FLOAT":
417
296
  return getBitsCount2(mapData);
297
+ case "FLOAT":
298
+ return getBitsCount(mapData);
418
299
  case "VERSION":
419
300
  return getBitsCount4(mapData);
420
301
  case "ENUM":
421
302
  return getBitsCount3(mapData);
422
- case "ENUM_ARRAY":
423
- return getBitsCount6(mapData, bitString);
424
303
  }
425
304
  };
426
- var dataEntryBitstringParser = (bitstring, dataEntry2) => [
427
- dataBitsParser(bitstring.slice(0, getBitsCount7(dataEntry2, bitstring)), dataEntry2),
428
- bitstring.slice(getBitsCount7(dataEntry2, bitstring))
429
- ];
430
- var nestedDataBitstringParser = (bitstring, descriptor) => {
431
- const resultingNestedData = descriptor.map((data) => {
432
- const [resultingData, remainingBitstring] = ComplexDataValues.includes(data.type) ? complexDataEntryBitstringParser(bitstring, data) : dataEntryBitstringParser(bitstring, data);
433
- bitstring = remainingBitstring;
434
- return resultingData;
435
- });
436
- return [resultingNestedData, bitstring];
437
- };
438
- var complexDataEntryBitstringParser = (bitstring, complexDataEntry) => {
439
- switch (complexDataEntry.type) {
440
- case "ARRAY":
441
- return rawParser7(bitstring, complexDataEntry);
442
- case "OPTIONAL":
443
- return rawParser8(bitstring, complexDataEntry);
444
- case "ENUM_OPTIONS":
445
- return rawParser9(bitstring, complexDataEntry);
446
- }
447
- };
448
- var dataBitsStringifier = (data) => {
449
- switch (data.type) {
305
+ var dataEntryBitsStringifier = (entry) => {
306
+ switch (entry.type) {
450
307
  case "BOOLEAN":
451
- return rawStringifier5(data.value);
308
+ return rawStringifier5(entry.value);
452
309
  case "INT":
453
- return rawStringifier(data.value, data);
310
+ return rawStringifier2(entry.value, entry);
454
311
  case "FLOAT":
455
- return rawStringifier2(data.value, data);
312
+ return rawStringifier(entry.value, entry);
456
313
  case "VERSION":
457
- return rawStringifier4(data.value, data);
314
+ return rawStringifier4(entry.value, entry);
458
315
  case "ENUM":
459
- return rawStringifier3(data.value, data);
316
+ return rawStringifier3(entry.value, entry);
460
317
  case "ENUM_ARRAY":
461
- return rawStringifier6(data.value, data);
462
- }
463
- };
464
- var complexDataStateStringifier = (complexDataEntry) => {
465
- switch (complexDataEntry.type) {
318
+ return rawStringifier6(entry.value, entry);
466
319
  case "ARRAY":
467
- return rawStateStringifier(complexDataEntry);
320
+ return rawStringifier7(entry);
468
321
  case "OPTIONAL":
469
- return rawStateStringifier2(complexDataEntry);
322
+ return rawStringifier8(entry);
470
323
  case "ENUM_OPTIONS":
471
- return rawStateStringifier3(complexDataEntry);
324
+ return rawStringifier9(entry);
325
+ case "OBJECT":
326
+ return rawStringifier10(entry);
472
327
  }
473
328
  };
474
- var dataEntryCorrecting = (dataEntry2) => dataBitsParser(dataBitsStringifier(dataEntry2), dataEntry2);
475
- var base64url = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
476
- var getBitsForEnumArrayCountOfBase = (count, base) => Math.ceil(Math.log2(base) * count);
477
- var convertArbitraryBaseToBitString = (input, fromBase) => {
478
- const expectedOutputLength = getBitsForEnumArrayCountOfBase(input.length, fromBase);
479
- const fromBaseBigInt = BigInt(fromBase);
480
- let decimalValue = BigInt(0);
481
- for (let i = input.length - 1;i >= 0; i--)
482
- decimalValue = decimalValue * fromBaseBigInt + BigInt(input[i]);
483
- const s = decimalValue.toString(2).padStart(expectedOutputLength, "0");
484
- return s;
485
- };
486
- var convertBitStringToArbitraryBase = (input, toBase, expectedOutputLength) => {
487
- let decimalValue = BigInt(`0b${input}`);
488
- const toBaseBigInt = BigInt(toBase);
489
- const result = [];
490
- while (decimalValue > 0) {
491
- const remainder = decimalValue % toBaseBigInt;
492
- result.push(Number(remainder));
493
- decimalValue = decimalValue / toBaseBigInt;
494
- }
495
- if (expectedOutputLength !== undefined && result.length !== expectedOutputLength)
496
- for (let i = result.length;i < expectedOutputLength; i++)
497
- result.push(0);
498
- return result;
499
- };
500
- var parseBitsToBase64 = (bits) => {
501
- const chunks = bits.match(/.{1,6}/g);
502
- const numbers = chunks?.map((c) => Number.parseInt(c.padEnd(6, "0"), 2)) ?? [];
503
- return numbers.map((n) => base64url.charAt(n)).join("");
504
- };
505
- var parseBase64ToBits = (base64) => {
506
- const numbers = base64.split("").map((c) => base64url.indexOf(c));
507
- const chunks = numbers.map((n) => n.toString(2).padStart(6, "0"));
508
- return chunks.join("");
329
+ var dataEntryCorrecting = (dataEntry2) => dataEntryBitstringParser(dataEntry2, dataEntryBitsStringifier(dataEntry2))[0];
330
+ // src/update/updateUtils.ts
331
+ var getStepForPrecision = (precision) => 10 ** -precision;
332
+ var constrainUnsignedInt = (value, maxValue) => Math.max(0, Math.min(Math.round(value), maxValue));
333
+ var constrainSignedInt = (value, minValue, maxValue) => constrainUnsignedInt(Math.round(value - minValue), Math.floor(maxValue - minValue)) + minValue;
334
+ var constrainFloat = (value, minValue, maxValue, precision) => {
335
+ const step = getStepForPrecision(precision);
336
+ const multi = 1 / step;
337
+ return constrainSignedInt(value * multi, minValue * multi, maxValue * multi) * step;
509
338
  };
339
+
510
340
  // src/update/floatUpdate.ts
511
- var updateValue = (original, update) => {
512
- original.value = Math.max(Math.min(update.value, original.max), original.min);
513
- return original;
514
- };
341
+ var constrainValue = (original, update) => constrainFloat(update, original.min, original.max, original.precision);
342
+ var updateValue = (original, update) => (original.value = constrainValue(original, update), original);
515
343
 
516
344
  // src/update/intUpdate.ts
517
- var updateValue2 = (original, update) => {
518
- original.value = Math.max(Math.min(update.value, original.max), original.min);
519
- return original;
520
- };
345
+ var constrainValue2 = (original, update) => constrainSignedInt(update, original.min, original.max);
346
+ var updateValue2 = (original, update) => (original.value = constrainValue2(original, update), original);
521
347
 
522
348
  // src/update/enumUpdate.ts
523
- var updateValue3 = (original, update) => {
524
- original.value = Math.min(original.max, update.value);
525
- return original;
526
- };
349
+ var constrainValue3 = (original, update) => constrainUnsignedInt(update, original.max);
350
+ var updateValue3 = (original, update) => (original.value = constrainValue3(original, update), original);
527
351
 
528
352
  // src/update/versionUpdate.ts
529
- var updateValue4 = (original, update) => {
530
- const value = Math.min(original.bits ** 2 - 1, update.value);
531
- return {
532
- ...original,
533
- value
534
- };
535
- };
353
+ var constrainValue4 = (original, update) => constrainUnsignedInt(update, original.bits ** 2 - 1);
354
+ var updateValue4 = (original, update) => (original.value = constrainValue4(original, update), original);
536
355
 
537
356
  // src/update/booleanUpdate.ts
538
- var updateValue5 = (original, update) => {
539
- original.value = update.value;
540
- return original;
541
- };
357
+ var constrainValue5 = (original, update) => update === true ? true : false;
358
+ var updateValue5 = (original, update) => (original.value = constrainValue5(original, update), original);
542
359
 
543
360
  // src/update/enumArrayUpdate.ts
544
- var updateValue6 = (original, update) => {
545
- const count = Math.max(Math.min(update.value.length, original.maxCount), original.minCount);
546
- original.value = [...new Array(count)].map((_, i) => Math.min(update.value[i] ?? 0, original.max));
547
- return original;
361
+ var constrainValue6 = (original, update) => {
362
+ const count = constrainUnsignedInt(update.length, original.maxCount);
363
+ return [...new Array(count)].map((_, i) => constrainUnsignedInt(update[i] ?? 0, original.max));
548
364
  };
365
+ var updateValue6 = (original, update) => (original.value = constrainValue6(original, update), original);
549
366
 
550
- // src/update/nestedDataMatching.ts
551
- var updateNestedData = (original, descriptor) => {
552
- const descriptorClone = JSON.parse(JSON.stringify(descriptor));
553
- if (!original)
554
- return descriptorClone;
555
- return descriptorClone.map((d, i) => original[i]?.type === d.type && original[i]?.name === d.name ? DataTypeValues.includes(original[i].type) ? updateValue7(d, original[i]) : updateComplexValue(d, original[i]) : d);
367
+ // src/update/validateUtils.ts
368
+ var validateDataEntry = (descriptorValue, differentValue) => {
369
+ if (descriptorValue === null)
370
+ return null;
371
+ if (differentValue === null)
372
+ return descriptorValue;
373
+ if (descriptorValue.type === differentValue.type)
374
+ if (ComplexDataTypes.includes(descriptorValue.type))
375
+ return updateStateEntry(descriptorValue, differentValue.state);
376
+ else
377
+ return updateValueEntry(descriptorValue, differentValue.value);
378
+ return descriptorValue;
556
379
  };
557
380
 
558
381
  // src/update/optionalUpdate.ts
559
- var updateComplexValue2 = (original, update) => {
560
- if (update.descriptor[Number(original.state)] !== null && original.value !== null) {
561
- original.state = update.state;
562
- original.value.length = 0;
563
- original.value.push(...updateNestedData(update.value, original.descriptor[Number(update.state)]));
564
- }
382
+ var constrainState = (state) => state === true ? true : false;
383
+ var updateState = (original, state) => {
384
+ original.state = constrainState(state);
385
+ original.value = validateDataEntry(original.descriptor[Number(state)], original.value);
565
386
  return original;
566
387
  };
567
388
 
568
389
  // src/update/enumOptionsUpdate.ts
569
- var updateComplexValue3 = (original, update) => {
570
- if (update.state <= original.descriptor.length - 1) {
571
- original.value.length = 0;
572
- original.value.push(...updateNestedData(update.value, original.descriptor[update.state]));
573
- original.state = update.state;
574
- }
390
+ var constrainState2 = (descriptorLength, state) => constrainUnsignedInt(state, descriptorLength - 1);
391
+ var updateState2 = (original, state) => {
392
+ original.state = constrainState2(original.descriptor.length, state);
393
+ original.value = validateDataEntry(original.descriptor[original.state], original.value);
575
394
  return original;
576
395
  };
577
396
 
578
397
  // src/update/arrayUpdate.ts
579
- var updateComplexValue4 = (original, update) => {
580
- if (update.state >= original.minCount && update.state <= original.maxCount) {
581
- original.state = update.state;
582
- original.value.length = 0;
583
- for (let i = 0;i < original.state; i++)
584
- original.value.push(updateNestedData(update.value[i], original.descriptor));
585
- }
398
+ var constrainState3 = (state, minCount, maxCount) => constrainSignedInt(state, minCount, maxCount);
399
+ var updateState3 = (original, state) => {
400
+ original.state = constrainState3(state, original.minCount, original.maxCount);
401
+ original.value = [...new Array(original.state)].map((_, i) => original.value[i] ? validateDataEntry(original.descriptor, original.value[i] ?? null) : original.descriptor);
402
+ return original;
403
+ };
404
+
405
+ // src/update/objectUpdate.ts
406
+ var updateValue7 = (original, value) => {
407
+ original.value = original.descriptor.map((v, i) => validateDataEntry(v, value[i] ?? null));
586
408
  return original;
587
409
  };
588
410
 
589
411
  // src/update/updateValues.ts
590
- var updateValue7 = (original, update) => {
591
- if (original.type !== update.type)
592
- throw new Error("Types do not match");
412
+ var updateValueEntry = (original, update) => {
593
413
  switch (original.type) {
594
414
  case "FLOAT":
595
415
  return updateValue(original, update);
@@ -603,132 +423,336 @@ var updateValue7 = (original, update) => {
603
423
  return updateValue4(original, update);
604
424
  case "ENUM_ARRAY":
605
425
  return updateValue6(original, update);
426
+ case "OBJECT":
427
+ return updateValue7(original, update);
606
428
  }
607
429
  };
608
- var updateComplexValue = (original, update) => {
609
- if (original.type !== update.type)
610
- throw new Error("Types do not match");
430
+ var constrainValue7 = (original, update) => {
611
431
  switch (original.type) {
612
- case "OPTIONAL":
613
- return updateComplexValue2(original, update);
614
- case "ENUM_OPTIONS":
615
- return updateComplexValue3(original, update);
616
- case "ARRAY":
617
- return updateComplexValue4(original, update);
618
- }
619
- };
620
- // src/stateHandling/stateData.ts
621
- var getStateData = (state) => {
622
- const object = {};
623
- state.forEach((item) => {
624
- switch (item.type) {
625
- case "BOOLEAN":
626
- object[item.name] = item.value;
627
- break;
628
- case "INT":
629
- object[item.name] = item.value;
630
- break;
631
- case "ENUM":
632
- object[item.name] = item.mapping[item.value];
633
- break;
634
- case "FLOAT":
635
- object[item.name] = item.value;
636
- break;
637
- case "VERSION":
638
- object[item.name] = item.value;
639
- break;
640
- case "ENUM_ARRAY":
641
- object[item.name] = item.value.map((v) => item.mapping[v]);
642
- break;
643
- case "OPTIONAL":
644
- object[item.name] = item.value === null ? null : getStateData(item.value);
645
- break;
646
- case "ENUM_OPTIONS":
647
- object[item.name] = {
648
- ...getStateData(item.value),
649
- state: item.state
650
- };
651
- break;
652
- case "ARRAY":
653
- object[item.name] = item.value.map(getStateData);
654
- break;
655
- }
656
- });
657
- return object;
658
- };
659
-
660
- // src/stateHandling/stateDataObject.ts
661
- var getBitstringForStateDataEntry = (stateDataEntry2) => {
662
- switch (stateDataEntry2.type) {
663
- case "BOOLEAN":
432
+ case "FLOAT":
433
+ return constrainValue(original, update);
664
434
  case "INT":
435
+ return constrainValue2(original, update);
665
436
  case "ENUM":
666
- case "FLOAT":
437
+ return constrainValue3(original, update);
438
+ case "BOOLEAN":
439
+ return constrainValue5(original, update);
667
440
  case "VERSION":
441
+ return constrainValue4(original, update);
668
442
  case "ENUM_ARRAY":
669
- return stateDataEntry2.bitstring = stateDataEntry2.bitstring ?? dataBitsStringifier(stateDataEntry2);
443
+ return constrainValue6(original, update);
444
+ }
445
+ };
446
+ var updateStateEntry = (original, update) => {
447
+ switch (original.type) {
670
448
  case "OPTIONAL":
671
- return stateDataEntry2.value === null ? complexDataStateStringifier(stateDataEntry2) : complexDataStateStringifier(stateDataEntry2) + getBitstringForStateNestedData(stateDataEntry2.value);
449
+ return updateState(original, update);
672
450
  case "ENUM_OPTIONS":
673
- return complexDataStateStringifier(stateDataEntry2) + getBitstringForStateNestedData(stateDataEntry2.value);
451
+ return updateState2(original, update);
674
452
  case "ARRAY":
675
- return complexDataStateStringifier(stateDataEntry2) + stateDataEntry2.value.map((vs) => getBitstringForStateNestedData(vs)).join("");
453
+ return updateState3(original, update);
676
454
  }
677
455
  };
678
- var getBitstringForStateNestedData = (nestedData) => nestedData.map(getBitstringForStateDataEntry).join("");
679
- var setComplexDataEntryValuesAsStateDataEntry = (currenEntry, updateCallback) => {
680
- switch (currenEntry.type) {
681
- case "OPTIONAL":
682
- currenEntry.value = currenEntry.value === null ? null : currenEntry.value.map((v) => getStateDataEntry(v, updateCallback));
683
- break;
684
- case "ARRAY":
685
- currenEntry.value = currenEntry.value.map((vs) => vs.map((v) => getStateDataEntry(v, updateCallback)));
686
- break;
687
- case "ENUM_OPTIONS":
688
- currenEntry.value = currenEntry.value.map((v) => getStateDataEntry(v, updateCallback));
689
- break;
456
+ // src/factory/helperMethod.ts
457
+ var getMinimumBitsForInteger = (v) => Math.ceil(Math.log2(v + 1));
458
+
459
+ // src/factory/utils.ts
460
+ var getEnumMaxAndMappingFromOptions = (options) => {
461
+ if (typeof options === "string")
462
+ return { max: options.length - 1, mapping: options.split("") };
463
+ if (typeof options === "number")
464
+ return { max: options, mapping: Array.from({ length: options + 1 }, (_, i) => i) };
465
+ return { max: options.length - 1, mapping: options };
466
+ };
467
+ var getOptionsFromMaxAndMapping = (v) => {
468
+ if (v.mapping.every((option) => typeof option === "string" && option.length === 1))
469
+ return v.mapping.join("");
470
+ if (Array.from({ length: v.max + 1 }, (_, i) => i).every((option, i) => option === v.mapping[i]))
471
+ return v.max;
472
+ return v.mapping;
473
+ };
474
+
475
+ // src/factory/enumOptionsFactory.ts
476
+ var maxEnumOptions = 64;
477
+ var maxEnumOptionsBits = getMinimumBitsForInteger(maxEnumOptions);
478
+
479
+ // src/factory/objectFactory.ts
480
+ var create = (descriptor, name = "an object") => {
481
+ return {
482
+ type: "OBJECT",
483
+ descriptor,
484
+ value: descriptor,
485
+ name,
486
+ stateBits: 0
487
+ };
488
+ };
489
+
490
+ // src/factory/factory.ts
491
+ var StateDescriptorFactoryMethod = create;
492
+ // src/stateHandling/stateNode.ts
493
+ class StateNode {
494
+ parent;
495
+ root;
496
+ type;
497
+ name;
498
+ bitstring = "";
499
+ constructor(entry, parent) {
500
+ this.parent = parent;
501
+ this.root = parent ? parent.root : this;
502
+ this.type = entry.type;
503
+ this.name = entry.name;
690
504
  }
691
- const newBitString = getBitstringForStateDataEntry(currenEntry);
692
- currenEntry.bitstring = newBitString;
693
- };
694
- var updateStateDataEntry = (currenEntry, newEntry, updateCallback) => {
695
- if (currenEntry.type !== newEntry.type || currenEntry.name !== newEntry.name)
696
- throw new Error(`Types (${currenEntry.type} & ${newEntry.type}) or names (${currenEntry.name} & ${newEntry.name}) do not match`);
697
- if (ComplexDataValues.includes(currenEntry.type)) {
698
- if (currenEntry.state !== newEntry.state) {
699
- const currentBitString = currenEntry.bitstring;
700
- const updatedCurrentEntry = updateComplexValue(currenEntry, newEntry);
701
- setComplexDataEntryValuesAsStateDataEntry(updatedCurrentEntry, updateCallback);
702
- if (currentBitString !== updatedCurrentEntry.bitstring)
703
- updateCallback();
704
- }
705
- } else {
706
- const currentBitString = currenEntry.bitstring;
707
- const updatedCurrentEntry = updateValue7(currenEntry, newEntry);
708
- updatedCurrentEntry.bitstring = dataBitsStringifier(updatedCurrentEntry);
709
- if (currentBitString !== updatedCurrentEntry.bitstring)
710
- updateCallback();
505
+ updateUpstream = () => {
506
+ const newBitstring = this.getBitString();
507
+ if (newBitstring !== this.bitstring)
508
+ this.bitstring = newBitstring, this.parent && this.parent.updateUpstream();
509
+ };
510
+ getStateBits = () => {
511
+ throw new Error("not implemented for " + this.type);
512
+ };
513
+ getValueBits = () => dataEntryBitsStringifier(this.toDataEntry());
514
+ getBitString = () => {
515
+ if (HasStateBitsDataTypes.includes(this.type))
516
+ return this.getStateBits() + this.getValueBits();
517
+ return this.getValueBits();
518
+ };
519
+ getBase64String = () => parseBitsToBase64(this.bitstring);
520
+ getParentString = () => {
521
+ if (this.parent)
522
+ return `${this.parent.name}
523
+ ↳${this.name}`;
524
+ else
525
+ return `root:"${this.getDescription()} - ${this.getBase64String()}"`;
526
+ };
527
+ getChildren = () => {
528
+ throw new Error("not implemented for " + this.type);
529
+ };
530
+ getDescription = () => this.name;
531
+ getChildrenStrings = () => {
532
+ const children = this.getChildren();
533
+ if (children.length === 0)
534
+ return [];
535
+ const strings = [];
536
+ children.forEach((child, level) => {
537
+ const indent = level < children.length - 1 ? "| " : " ";
538
+ if (child) {
539
+ strings.push(`|→"${child.getDescription()}"`);
540
+ for (const grandchild of child.getChildrenStrings())
541
+ strings.push(indent + grandchild);
542
+ } else
543
+ strings.push(`|→null`);
544
+ });
545
+ return strings;
546
+ };
547
+ toDataEntry = () => {
548
+ throw new Error("not implemented for " + this.type);
549
+ };
550
+ toString() {
551
+ return `${this.getParentString()}
552
+ ${this.getChildrenStrings().join(`
553
+ `)}`;
554
+ }
555
+ }
556
+
557
+ class SimpleStateNodes extends StateNode {
558
+ value;
559
+ descriptor;
560
+ constructor(entry, parent) {
561
+ super(entry, parent);
562
+ this.value = entry.value;
563
+ this.descriptor = entry;
564
+ this.bitstring = this.getBitString();
565
+ }
566
+ getChildren = () => [];
567
+ getDescription = () => `${this.name}: ${this.value}`;
568
+ updateValue = (value) => {
569
+ this.value = constrainValue7(this.descriptor, value);
570
+ this.updateUpstream();
571
+ };
572
+ toDataEntry = () => ({
573
+ ...this.descriptor,
574
+ name: this.name,
575
+ value: this.value
576
+ });
577
+ }
578
+
579
+ class VersionNode extends SimpleStateNodes {
580
+ }
581
+
582
+ class BooleanNode extends SimpleStateNodes {
583
+ }
584
+
585
+ class EnumNode extends SimpleStateNodes {
586
+ }
587
+
588
+ class IntNode extends SimpleStateNodes {
589
+ }
590
+
591
+ class FloatNode extends SimpleStateNodes {
592
+ }
593
+
594
+ class EnumArrayNode extends SimpleStateNodes {
595
+ getStateBits = () => rawStateStringifier(this.value, this.descriptor.minCount, this.descriptor.stateBits);
596
+ getDescription = () => `${this.name}: [${this.value.map((v) => this.descriptor.mapping[v]).join(", ")}]`;
597
+ }
598
+
599
+ class OptionalNode extends StateNode {
600
+ state;
601
+ stateBits;
602
+ descriptor;
603
+ child = null;
604
+ constructor(entry, parent) {
605
+ super(entry, parent);
606
+ this.state = entry.state;
607
+ this.stateBits = entry.stateBits;
608
+ this.descriptor = entry["descriptor"];
609
+ this.bitstring = this.getBitString();
610
+ }
611
+ getChildren = () => [this.child];
612
+ getStateBits = () => rawStateStringifier3(this.state);
613
+ getValueBits = () => this.child ? this.child.bitstring : "";
614
+ updateState = (newState) => {
615
+ this.state = constrainState(newState);
616
+ if (this.state === this.state)
617
+ return;
618
+ this.child = this.descriptor[this.state ? 1 : 0] ? NodeFactory(this.descriptor[this.state ? 1 : 0], this) : null;
619
+ this.updateUpstream();
620
+ };
621
+ toDataEntry = () => ({
622
+ type: "OPTIONAL",
623
+ name: this.name,
624
+ state: this.state,
625
+ stateBits: this.stateBits,
626
+ descriptor: this.descriptor,
627
+ value: this.child ? this.child.toDataEntry() : null
628
+ });
629
+ getDescription = () => `${this.name}: ${this.state}`;
630
+ }
631
+
632
+ class EnumOptionsNode extends StateNode {
633
+ state;
634
+ stateBits;
635
+ descriptor;
636
+ mapping;
637
+ child = null;
638
+ constructor(entry, parent) {
639
+ super(entry, parent);
640
+ this.state = entry.state;
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;
645
+ this.bitstring = this.getBitString();
646
+ }
647
+ getChildren = () => [this.child];
648
+ getStateBits = () => rawStateStringifier4(this.state, this.stateBits);
649
+ getValueBits = () => this.child ? this.child.bitstring : "";
650
+ updateState = (newState) => {
651
+ const constrainedNewState = constrainState2(this.descriptor.length, newState);
652
+ if (constrainedNewState === this.state)
653
+ return;
654
+ const validationResult = validateDataEntry(this.descriptor[constrainedNewState], this.child ? this.child.toDataEntry() : null);
655
+ this.child = validationResult ? NodeFactory(validationResult, this) : null;
656
+ this.state = constrainedNewState;
657
+ this.updateUpstream();
658
+ };
659
+ toDataEntry = () => ({
660
+ type: "ENUM_OPTIONS",
661
+ name: this.name,
662
+ state: this.state,
663
+ stateBits: this.stateBits,
664
+ descriptor: this.descriptor,
665
+ mapping: this.mapping,
666
+ value: this.child ? this.child.toDataEntry() : null
667
+ });
668
+ getDescription = () => `${this.name}: ${this.state} of ${this.mapping.length} options`;
669
+ }
670
+
671
+ class ArrayNode extends StateNode {
672
+ descriptor;
673
+ children;
674
+ minCount;
675
+ maxCount;
676
+ stateBits;
677
+ state;
678
+ constructor(entry, parent) {
679
+ super(entry, parent);
680
+ this.descriptor = entry["descriptor"];
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"];
686
+ this.bitstring = this.getBitString();
711
687
  }
712
- return currenEntry;
713
- };
714
- var getStateDataEntry = (entry, updateCallback) => {
715
- entry.bitstring = getBitstringForStateDataEntry(entry);
716
- entry.updateValue = (newEntry) => updateStateDataEntry(entry, newEntry, updateCallback);
717
- return entry;
718
- };
719
- var createStateDataObject = (initialState, updateCallback) => {
720
- const stateObject = {};
721
- const wrappedUpdateCallback = () => {
722
- stateObject.bitstring = getBitstringForStateNestedData(stateObject.state);
723
- stateObject.base64 = parseBitsToBase64(stateObject.bitstring);
724
- stateObject.data = getStateData(stateObject.state);
725
- updateCallback(stateObject);
688
+ getChildren = () => this.children;
689
+ getStateBits = () => rawStateStringifier2(this.state, this.minCount, this.stateBits);
690
+ getValueBits = () => this.children.map((child) => child.bitstring).join("");
691
+ updateState = (newState) => {
692
+ const constrainedNewState = constrainState3(newState, this.minCount, this.maxCount);
693
+ if (constrainedNewState === this.state)
694
+ return;
695
+ if (constrainedNewState < this.state)
696
+ this.children = this.children.slice(0, constrainedNewState);
697
+ else
698
+ for (let i = this.state;i < constrainedNewState; i++)
699
+ this.children.push(NodeFactory(this.descriptor, this));
700
+ this.state = constrainedNewState;
701
+ this.updateUpstream();
726
702
  };
727
- stateObject.state = initialState.map((item) => getStateDataEntry(item, wrappedUpdateCallback));
728
- wrappedUpdateCallback();
729
- return stateObject;
703
+ toDataEntry = () => ({
704
+ type: "ARRAY",
705
+ name: this.name,
706
+ value: this.children.map((child) => child.toDataEntry()),
707
+ minCount: this.minCount,
708
+ maxCount: this.maxCount,
709
+ stateBits: this.stateBits,
710
+ state: this.state,
711
+ descriptor: this.descriptor
712
+ });
713
+ getDescription = () => `${this.name}: ${this.state} of (${this.minCount}, ${this.maxCount})`;
714
+ }
715
+
716
+ class ObjectNode extends StateNode {
717
+ descriptor;
718
+ children;
719
+ constructor(entry, parent) {
720
+ super(entry, parent);
721
+ this.descriptor = entry["descriptor"];
722
+ this.children = entry["value"].map((child) => NodeFactory(child, this));
723
+ this.bitstring = this.getBitString();
724
+ }
725
+ getChildren = () => this.children;
726
+ getStateBits = () => "";
727
+ getValueBits = () => this.children.map((child) => child.bitstring).join("");
728
+ toDataEntry = () => ({
729
+ type: "OBJECT",
730
+ name: this.name,
731
+ value: this.children.map((child) => child.toDataEntry()),
732
+ descriptor: this.descriptor,
733
+ stateBits: 0
734
+ });
735
+ }
736
+ var StateNodeMap = {
737
+ VERSION: VersionNode,
738
+ BOOLEAN: BooleanNode,
739
+ ENUM: EnumNode,
740
+ INT: IntNode,
741
+ FLOAT: FloatNode,
742
+ ENUM_ARRAY: EnumArrayNode,
743
+ OPTIONAL: OptionalNode,
744
+ ENUM_OPTIONS: EnumOptionsNode,
745
+ ARRAY: ArrayNode,
746
+ OBJECT: ObjectNode
747
+ };
748
+ var NodeFactory = (entry, parent) => new StateNodeMap[entry.type](entry, parent);
749
+ var GetStateNodeTree = (entries, name) => new ObjectNode(StateDescriptorFactoryMethod(entries, name), null);
750
+ var FromState = (stateDescriptor, name, base64String) => {
751
+ const bitstring = parseBase64ToBits(base64String);
752
+ const dataObject = StateDescriptorFactoryMethod(stateDescriptor, name);
753
+ const [parsedObject] = dataEntryBitstringParser(dataObject, bitstring);
754
+ return new ObjectNode(parsedObject, null);
730
755
  };
731
- var getInitialStateFromBase64 = (base64, descriptor) => nestedDataBitstringParser(parseBase64ToBits(base64), descriptor)[0];
732
756
  // src/utils/interpolateData.ts
733
757
  var interpolateEntryAt = (dataEntry2, t) => {
734
758
  const localT = Math.max(Math.min(1, t), 0);
@@ -745,8 +769,6 @@ var interpolateEntryAt = (dataEntry2, t) => {
745
769
  case "FLOAT":
746
770
  const v = dataEntry2.min + cosT * (dataEntry2.max - dataEntry2.min);
747
771
  return dataEntryCorrecting({ ...dataEntry2, value: Math.min(dataEntry2.max, Math.max(v, dataEntry2.min)) });
748
- case "ENUM_ARRAY":
749
- return { ...dataEntry2, value: dataEntry2.value.map((v2) => Math.floor(localT * (v2 + 0.999))) };
750
772
  }
751
773
  };
752
774
  // src/utils/relativeValue.ts
@@ -761,27 +783,34 @@ var getRelativeValue = (dataEntry2) => {
761
783
  return dataEntry2.value / (2 ** dataEntry2.bits - 1);
762
784
  case "ENUM":
763
785
  return dataEntry2.value / dataEntry2.max;
764
- case "ENUM_ARRAY":
765
- return dataEntry2.value.reduce((acc, v) => acc + v, 0) / dataEntry2.value.length;
766
786
  }
767
787
  };
768
788
  export {
769
- valueBitsParser,
770
789
  parseBase64ToBits,
771
790
  interpolateEntryAt,
772
791
  getRelativeValue,
773
- getInitialStateFromBase64,
774
- getBitsCount7 as getBitsCount,
792
+ getOptionsFromMaxAndMapping,
793
+ getEnumMaxAndMappingFromOptions,
794
+ getBitsCount6 as getBitsCount,
775
795
  dataEntryCorrecting,
776
796
  dataEntryBitstringParser,
777
- dataBitsStringifier,
778
- dataBitsParser,
779
- createStateDataObject,
797
+ dataEntryBitsStringifier,
798
+ VariableBitWidthDataTypes,
799
+ StateNode,
780
800
  SignificandMaxBits,
781
801
  PROTECTED_ATTRIBUTE_NAMES,
802
+ OptionalNode,
803
+ ObjectNode,
804
+ NodeFactory,
782
805
  IntegerMaxBits,
783
- DataTypeValues,
784
- DataEntryFactory,
785
- ComplexDataValues,
786
- ComplexDataEntryFactory
806
+ IntNode,
807
+ GetStateNodeTree,
808
+ FromState,
809
+ FloatNode,
810
+ EnumOptionsNode,
811
+ EnumNode,
812
+ EnumArrayNode,
813
+ ConstantBitWidthDataTypes,
814
+ BooleanNode,
815
+ ArrayNode
787
816
  };