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