url-safe-bitpacking 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # url-safe-bitpacking
2
+
3
+ To install dependencies:
4
+
5
+ ```bash
6
+ bun install
7
+ ```
8
+
9
+ To run:
10
+
11
+ ```bash
12
+ bun run index.ts
13
+ ```
14
+
15
+ This project was created using `bun init` in bun v1.0.7. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
package/dist/bundle.js ADDED
@@ -0,0 +1,577 @@
1
+ // src/enums/dataTypes.ts
2
+ var DataType;
3
+ (function(DataType2) {
4
+ DataType2[DataType2["VERSION"] = 0] = "VERSION";
5
+ DataType2[DataType2["BOOLEAN"] = 1] = "BOOLEAN";
6
+ DataType2[DataType2["ENUM"] = 2] = "ENUM";
7
+ DataType2[DataType2["INT"] = 3] = "INT";
8
+ DataType2[DataType2["FLOAT"] = 4] = "FLOAT";
9
+ })(DataType || (DataType = {}));
10
+ // src/enums/objectGenerationTypes.ts
11
+ var ObjectGenerationOutputStatus;
12
+ (function(ObjectGenerationOutputStatus2) {
13
+ ObjectGenerationOutputStatus2[ObjectGenerationOutputStatus2["DEFAULT"] = 0] = "DEFAULT";
14
+ ObjectGenerationOutputStatus2[ObjectGenerationOutputStatus2["FROM_TYPE"] = 1] = "FROM_TYPE";
15
+ ObjectGenerationOutputStatus2[ObjectGenerationOutputStatus2["PARSED"] = 2] = "PARSED";
16
+ ObjectGenerationOutputStatus2[ObjectGenerationOutputStatus2["ERROR_PARSING"] = 3] = "ERROR_PARSING";
17
+ })(ObjectGenerationOutputStatus || (ObjectGenerationOutputStatus = {}));
18
+ // src/factory/intFactory.ts
19
+ var getBitsForIntegerNumber = (number) => Math.ceil(Math.log2(number));
20
+ var create = (min, max) => {
21
+ if (!Number.isInteger(min) || !Number.isInteger(max))
22
+ throw new Error("min and max must be integers");
23
+ if (max - min < 1)
24
+ throw new Error("max must be at least one");
25
+ if (Math.abs(max - min) > 1023)
26
+ throw new Error("max - min must be less than 1024");
27
+ const bits = getBitsForIntegerNumber(max - min + 1);
28
+ return { type: DataType.INT, min, max, bits };
29
+ };
30
+
31
+ // src/factory/floatFactory.ts
32
+ var create2 = (min, max, precision) => {
33
+ const precisionMultiplier = 10 ** precision;
34
+ const roundedMin = Math.floor(min * precisionMultiplier);
35
+ const roundedMax = Math.ceil(max * precisionMultiplier);
36
+ const delta = roundedMax - roundedMin;
37
+ const significand = Math.max(1, getBitsForIntegerNumber(delta));
38
+ return {
39
+ type: DataType.FLOAT,
40
+ min: roundedMin / precisionMultiplier,
41
+ max: roundedMax / precisionMultiplier,
42
+ precision,
43
+ significand
44
+ };
45
+ };
46
+
47
+ // src/factory/booleanFactory.ts
48
+ var create3 = () => ({ type: DataType.BOOLEAN });
49
+
50
+ // src/factory/versionFactory.ts
51
+ var create4 = (bits) => ({
52
+ type: DataType.VERSION,
53
+ bits
54
+ });
55
+
56
+ // src/factory/enumFactory.ts
57
+ var create5 = (max) => {
58
+ if (!Number.isInteger(max))
59
+ throw new Error("min and max must be integers");
60
+ if (max < 1)
61
+ throw new Error("max must be at least one");
62
+ if (max > 1023)
63
+ throw new Error("max - min must be less than 1024");
64
+ const bits = getBitsForIntegerNumber(max + 1);
65
+ return { type: DataType.ENUM, max, bits };
66
+ };
67
+
68
+ // src/factory/factory.ts
69
+ class DataRangeDescriptionFactory {
70
+ static createFloat = create2;
71
+ static createInt = create;
72
+ static createEnum = create5;
73
+ static createBoolean = create3;
74
+ static createVersion = create4;
75
+ }
76
+
77
+ class DataDescriptionFactory {
78
+ static createFloat = (min = 0, max = 1, precision = 2, name = "", index = 0) => ({
79
+ ...create2(min, max, precision),
80
+ name,
81
+ index
82
+ });
83
+ static createInt = (min = 0, max = 10, name = "", index = 0) => ({
84
+ ...create(min, max),
85
+ name,
86
+ index
87
+ });
88
+ static createEnum = (max = 10, name = "", index = 0) => ({
89
+ ...create5(max),
90
+ name,
91
+ index
92
+ });
93
+ static createBoolean = (name = "", index = 0) => ({
94
+ ...create3(),
95
+ name,
96
+ index
97
+ });
98
+ static createVersion = (bits = 8, name = "", index = 0) => ({
99
+ ...create4(bits),
100
+ name,
101
+ index
102
+ });
103
+ }
104
+
105
+ class DataEntryFactory {
106
+ static createFloat = (value, min = 0, max = 1, precision = 2, name = "", index = 0) => ({
107
+ ...create2(min, max, precision),
108
+ value,
109
+ name,
110
+ index
111
+ });
112
+ static createInt = (value, min = 0, max = 10, name = "", index = 0) => ({
113
+ ...create(min, max),
114
+ value,
115
+ name,
116
+ index
117
+ });
118
+ static createEnum = (value, max = 10, name = "", index = 0) => ({
119
+ ...create5(max),
120
+ value,
121
+ name,
122
+ index
123
+ });
124
+ static createBoolean = (value, name = "", index = 0) => ({
125
+ ...create3(),
126
+ value,
127
+ name,
128
+ index
129
+ });
130
+ static createVersion = (value, bits = 8, name = "", index = 0) => ({
131
+ ...create4(bits),
132
+ value,
133
+ name,
134
+ index
135
+ });
136
+ }
137
+ // src/parsers/intParser.ts
138
+ var getBitsCount = (intData) => intData.bits;
139
+ var rawValueParser = (stateString, bitCount) => {
140
+ if (stateString.length < bitCount)
141
+ throw new Error(`To few bits for this int bit string (${stateString.length} instead of ${bitCount})`);
142
+ if (stateString.length > bitCount)
143
+ throw new Error(`To many bits for this int bit string (${stateString.length} instead of ${bitCount})`);
144
+ const parsed = parseInt(stateString, 2);
145
+ if (isNaN(parsed))
146
+ throw new Error("Invalid int state string");
147
+ return parsed;
148
+ };
149
+ var rawParser = (stateString, intData) => {
150
+ const v = rawValueParser(stateString, intData.bits) + intData.min;
151
+ if (v > intData.max)
152
+ throw new Error("Value exceeds max");
153
+ return v;
154
+ };
155
+ var rawIntStringifier = (value, bitCount) => {
156
+ if (Number.isInteger(value) === false)
157
+ throw new Error("Value is not an integer");
158
+ return value.toString(2).padStart(bitCount, "0");
159
+ };
160
+ var rawStringifier = (value, intData) => {
161
+ if (value < intData.min)
162
+ throw new Error("Value is below min");
163
+ if (value > intData.max)
164
+ throw new Error("Value exceeds max");
165
+ return rawIntStringifier(value - intData.min, intData.bits);
166
+ };
167
+
168
+ // src/parsers/floatParser.ts
169
+ var getBitsCount2 = (floatData) => floatData.significand;
170
+ var rawValueParser2 = (stateString, significandBits, precision) => {
171
+ if (stateString.length < significandBits)
172
+ throw new Error(`To few bits for this float bit string (${stateString.length} instead of ${significandBits})`);
173
+ if (stateString.length > significandBits)
174
+ throw new Error(`To many bits for this float bit string (${stateString.length} instead of ${significandBits})`);
175
+ const significand = rawValueParser(stateString, significandBits);
176
+ return significand * 10 ** -precision;
177
+ };
178
+ var rawParser2 = (stateString, floatData) => {
179
+ const v = floatData.min + rawValueParser2(stateString, floatData.significand, floatData.precision);
180
+ if (v > floatData.max)
181
+ throw new Error("Float value exceeds max");
182
+ return v;
183
+ };
184
+ var rawStringifier2 = (value, floatData) => rawIntStringifier(Math.round((value - floatData.min) * 10 ** floatData.precision), floatData.significand);
185
+
186
+ // src/parsers/enumParser.ts
187
+ var getBitsCount3 = (versionData) => versionData.bits;
188
+ var rawParser3 = (rawString, versionData) => rawValueParser(rawString, versionData.bits);
189
+ var rawStringifier3 = (value, versionData) => {
190
+ if (value > versionData.max)
191
+ throw new Error("Version exceeds max");
192
+ return rawIntStringifier(value, versionData.bits);
193
+ };
194
+
195
+ // src/parsers/versionParser.ts
196
+ var getBitsCount4 = (versionData) => versionData.bits;
197
+ var rawParser4 = (rawString, versionData) => rawValueParser(rawString, versionData.bits);
198
+ var rawStringifier4 = (value, versionData) => {
199
+ if (value > 2 ** versionData.bits - 1)
200
+ throw new Error("Version exceeds max");
201
+ return rawIntStringifier(value, versionData.bits);
202
+ };
203
+
204
+ // src/parsers/booleanParser.ts
205
+ var getBitsCount5 = () => 1;
206
+ var rawValueParser3 = (stateString) => {
207
+ if (stateString === "1")
208
+ return true;
209
+ if (stateString === "0")
210
+ return false;
211
+ throw new Error("Invalid boolean bit string");
212
+ };
213
+ var rawParser5 = (stateString) => rawValueParser3(stateString);
214
+ var rawStringifier5 = (value) => value ? "1" : "0";
215
+
216
+ // src/parsers/parsers.ts
217
+ var valueBitsParser = (bitString, mapData) => {
218
+ switch (mapData.type) {
219
+ case DataType.BOOLEAN:
220
+ return rawParser5(bitString);
221
+ case DataType.INT:
222
+ return rawParser(bitString, mapData);
223
+ case DataType.ENUM:
224
+ return rawParser3(bitString, mapData);
225
+ case DataType.FLOAT:
226
+ return rawParser2(bitString, mapData);
227
+ case DataType.VERSION:
228
+ return rawParser4(bitString, mapData);
229
+ }
230
+ };
231
+ var dataBitsParser = (rawString, mapData) => {
232
+ switch (mapData.type) {
233
+ case DataType.BOOLEAN:
234
+ return { ...mapData, value: valueBitsParser(rawString, mapData) };
235
+ case DataType.ENUM:
236
+ case DataType.INT:
237
+ case DataType.FLOAT:
238
+ case DataType.VERSION:
239
+ return { ...mapData, value: valueBitsParser(rawString, mapData) };
240
+ }
241
+ };
242
+ var getBitsCount6 = (mapData) => {
243
+ switch (mapData.type) {
244
+ case DataType.BOOLEAN:
245
+ return getBitsCount5();
246
+ case DataType.INT:
247
+ return getBitsCount(mapData);
248
+ case DataType.FLOAT:
249
+ return getBitsCount2(mapData);
250
+ case DataType.VERSION:
251
+ return getBitsCount4(mapData);
252
+ case DataType.ENUM:
253
+ return getBitsCount3(mapData);
254
+ }
255
+ };
256
+ var dataBitsArrayParser = (bitString, mapDataArray) => {
257
+ const bitCounts = mapDataArray.map((mapData) => getBitsCount6(mapData));
258
+ const bitStartEndMap = [];
259
+ bitCounts.forEach((bitCount, index) => {
260
+ const start = index === 0 ? 0 : bitStartEndMap[index - 1][1];
261
+ bitStartEndMap.push([start, start + bitCount]);
262
+ });
263
+ return mapDataArray.map((mapData, i) => dataBitsParser(bitString.slice(bitStartEndMap[i][0], bitStartEndMap[i][1]), mapData));
264
+ };
265
+ var dataBitsStringifier = (data) => {
266
+ switch (data.type) {
267
+ case DataType.BOOLEAN:
268
+ return rawStringifier5(data.value);
269
+ case DataType.INT:
270
+ return rawStringifier(data.value, data);
271
+ case DataType.FLOAT:
272
+ return rawStringifier2(data.value, data);
273
+ case DataType.VERSION:
274
+ return rawStringifier4(data.value, data);
275
+ case DataType.ENUM:
276
+ return rawStringifier3(data.value, data);
277
+ }
278
+ };
279
+ var dataEntryCorrecting = (dataEntry) => dataBitsParser(dataBitsStringifier(dataEntry), dataEntry);
280
+ var base64url = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
281
+ var parseBitsToBase64 = (bits) => {
282
+ const chunks = bits.match(/.{1,6}/g);
283
+ const numbers = chunks?.map((c) => Number.parseInt(c.padEnd(6, "0"), 2)) ?? [];
284
+ return numbers.map((n) => base64url.charAt(n)).join("");
285
+ };
286
+ var parseBase64ToBits = (base64) => {
287
+ const numbers = base64.split("").map((c) => base64url.indexOf(c));
288
+ const chunks = numbers.map((n) => n.toString(2).padStart(6, "0"));
289
+ return chunks.join("");
290
+ };
291
+ var dataArrayStringifier = (dataEntryArray) => {
292
+ return dataEntryArray.map(dataBitsStringifier).join("");
293
+ };
294
+
295
+ // src/objectmap/versionReading.ts
296
+ var parameterOffset = 100;
297
+ var getVariableStrings = (definitionArrayObject) => {
298
+ const keys = [];
299
+ definitionArrayObject.forEach((value) => {
300
+ if (Array.isArray(value)) {
301
+ if (value.length === 2)
302
+ keys.push(...getVariableStrings(value[1]));
303
+ if (value.length === 3)
304
+ keys.push(value[1].name);
305
+ }
306
+ });
307
+ return keys;
308
+ };
309
+ var nestedDataEntryArrayToObject = (definitionArrayObject, startIndex) => {
310
+ const baseIndex = startIndex * parameterOffset;
311
+ return Object.fromEntries(definitionArrayObject.map((value, i) => {
312
+ if (Array.isArray(value)) {
313
+ if (value.length === 2)
314
+ return [value[0], nestedDataEntryArrayToObject(value[1], baseIndex + i)];
315
+ else
316
+ return [value[0], nestedDataEntryArrayToObject(value[2](value[1]), baseIndex + i)];
317
+ }
318
+ return [value.name, { ...value, index: baseIndex + i }];
319
+ }));
320
+ };
321
+ var definitionArrayObjectParser = (bitString, v, orderIndex) => {
322
+ const [key, values] = v;
323
+ const [nestedSemanticObject, objectGenerationStatus, localEndIndex] = parsingDefinitionArrayObject(bitString, values, orderIndex);
324
+ return [[key, nestedSemanticObject], objectGenerationStatus, localEndIndex];
325
+ };
326
+ var methodParser = (bitString, v, orderIndex) => {
327
+ const [key, keyDataDescription, methodGenerator] = v;
328
+ const [keyDataEntry, status, bitWidth] = dataEntryParser(bitString, keyDataDescription, orderIndex);
329
+ const [result, localStatus, localEndIndex] = definitionArrayObjectParser(bitString, [key, methodGenerator(keyDataEntry)], orderIndex);
330
+ return [result, localStatus !== ObjectGenerationOutputStatus.PARSED ? localStatus : status, localEndIndex];
331
+ };
332
+ var dataEntryParser = (bitString, v, baseOrderIndex) => {
333
+ const bitWidth = getBitsCount6(v);
334
+ const value = dataBitsParser(bitString.slice(0, bitWidth), v);
335
+ return [{ ...value, index: baseOrderIndex }, ObjectGenerationOutputStatus.PARSED, bitWidth];
336
+ };
337
+ var parsingDefinitionArrayObject = (bitString, definitionArrayObject, orderIndex) => {
338
+ const baseOrderIndex = orderIndex * parameterOffset;
339
+ let startIndex = 0;
340
+ let objectGenerationStatus = ObjectGenerationOutputStatus.PARSED;
341
+ return [
342
+ Object.fromEntries(definitionArrayObject.map((value, i) => {
343
+ if (Array.isArray(value)) {
344
+ if (value.length === 2) {
345
+ const [[key, nestedSemanticObject], status, localEndIndex] = definitionArrayObjectParser(bitString.slice(startIndex), value, baseOrderIndex + i);
346
+ startIndex += localEndIndex;
347
+ ObjectGenerationOutputStatus.PARSED;
348
+ return [key, nestedSemanticObject];
349
+ } else {
350
+ const [[key, nestedSemanticObject], status, localEndIndex] = methodParser(bitString.slice(startIndex), value, baseOrderIndex + i);
351
+ startIndex += localEndIndex;
352
+ ObjectGenerationOutputStatus.PARSED;
353
+ return [key, nestedSemanticObject];
354
+ }
355
+ } else {
356
+ const [dataEntry, status, localEndIndex] = dataEntryParser(bitString.slice(startIndex), value, baseOrderIndex + i);
357
+ startIndex += localEndIndex;
358
+ ObjectGenerationOutputStatus.PARSED;
359
+ return [dataEntry.name, dataEntry];
360
+ }
361
+ })),
362
+ objectGenerationStatus,
363
+ startIndex
364
+ ];
365
+ };
366
+ var readingVersion = (bitstring) => dataBitsArrayParser(bitstring, [DataDescriptionFactory.createVersion(8)])[0];
367
+ var parseUrlMethod = (url, parserVersions) => {
368
+ const bitString = parseBase64ToBits(url);
369
+ const version = readingVersion(bitString);
370
+ const versionParser = parserVersions[version.value];
371
+ if (!versionParser)
372
+ throw new Error(`No parser for version ${version.value}`);
373
+ return parsingDefinitionArrayObject(bitString, versionParser.objectGeneratorParameters, 0)[0];
374
+ };
375
+ var parseDownNestedDataDescription = (nestedDataDescription) => {
376
+ const dataDescriptions = [];
377
+ Object.values(nestedDataDescription).forEach((value) => {
378
+ if (value.hasOwnProperty("type"))
379
+ dataDescriptions.push(value);
380
+ else
381
+ dataDescriptions.push(...parseDownNestedDataDescription(value));
382
+ });
383
+ return dataDescriptions.sort();
384
+ };
385
+ var getURLForData = (data) => {
386
+ const dataEntryArray = parseDownNestedDataDescription(data);
387
+ const bitstring = dataArrayStringifier(dataEntryArray);
388
+ return parseBitsToBase64(bitstring);
389
+ };
390
+ var getTestStringValues = (data) => {
391
+ const dataEntryArray = parseDownNestedDataDescription(data);
392
+ const bitstring = dataArrayStringifier(dataEntryArray);
393
+ const url = parseBitsToBase64(bitstring);
394
+ const dataValueStrings = dataEntryArray.map((dataEntry) => dataBitsStringifier(dataEntry));
395
+ const singleString = dataValueStrings.join("");
396
+ const base64bitStringArray = singleString.match(/.{1,6}/g)?.map((c) => c.padEnd(6, "0")) ?? [];
397
+ const base64valueArray = url.split("").map((c) => c.padStart(6, "_"));
398
+ const raw = JSON.stringify(parseDownNestedDataDescription(data), undefined, 1);
399
+ return {
400
+ bitsString: dataValueStrings.join("-"),
401
+ base64BitString: base64bitStringArray.join("-"),
402
+ base64SplitString: base64valueArray.join("-"),
403
+ base64String: url,
404
+ raw
405
+ };
406
+ };
407
+ // src/update/floatUpdate.ts
408
+ var updateValue = (original, update) => {
409
+ const value = Math.max(Math.min(update.value, original.max), original.min);
410
+ return {
411
+ ...original,
412
+ value
413
+ };
414
+ };
415
+
416
+ // src/update/intUpdate.ts
417
+ var updateValue2 = (original, update) => {
418
+ const value = Math.max(Math.min(update.value, original.max), original.min);
419
+ return {
420
+ ...original,
421
+ value
422
+ };
423
+ };
424
+
425
+ // src/update/enumUpdate.ts
426
+ var updateValue3 = (original, update) => {
427
+ const value = Math.min(original.max, update.value);
428
+ return {
429
+ ...original,
430
+ value
431
+ };
432
+ };
433
+
434
+ // src/update/versionUpdate.ts
435
+ var updateValue4 = (original, update) => {
436
+ const value = Math.min(original.bits ** 2 - 1, update.value);
437
+ return {
438
+ ...original,
439
+ value
440
+ };
441
+ };
442
+
443
+ // src/update/booleanUpdate.ts
444
+ var updateValue5 = (original, update) => ({
445
+ ...original,
446
+ value: update.value
447
+ });
448
+
449
+ // src/update/updateValues.ts
450
+ var updateValue6 = (original, update) => {
451
+ if (original.type !== update.type)
452
+ throw new Error("Types do not match");
453
+ switch (original.type) {
454
+ case DataType.FLOAT:
455
+ return updateValue(original, update);
456
+ case DataType.INT:
457
+ return updateValue2(original, update);
458
+ case DataType.ENUM:
459
+ return updateValue3(original, update);
460
+ case DataType.VERSION:
461
+ return updateValue4(original, update);
462
+ case DataType.BOOLEAN:
463
+ return updateValue5(original, update);
464
+ }
465
+ };
466
+
467
+ // src/objectmap/versionUpdate.ts
468
+ var dataEntryUpdating = (dataEntry, dataEntryArray) => {
469
+ const existingDataEntry = dataEntryArray.find((d) => d.name === dataEntry.name);
470
+ if (!existingDataEntry)
471
+ return [dataEntry.name, dataEntry];
472
+ return [dataEntry.name, updateValue6(dataEntry, existingDataEntry)];
473
+ };
474
+ var nestedDataEntryArrayUpdating = (definitionNestedArrray, dataEntryArray) => {
475
+ const [keyString, nestedDefinitionArray] = definitionNestedArrray;
476
+ return [keyString, updateDataEntryObject(nestedDefinitionArray, dataEntryArray)];
477
+ };
478
+ var generationObjectUpdating = (definitionArrayObject, dataEntryArray) => {
479
+ const [keyString, keyDataEntry, methodGenerator] = definitionArrayObject;
480
+ const foundKeyDataEntry = dataEntryArray.find((d) => d.name === keyDataEntry.name);
481
+ const newKeyData = foundKeyDataEntry ? updateValue6(keyDataEntry, foundKeyDataEntry) : keyDataEntry;
482
+ return [keyString, updateDataEntryObject(methodGenerator(newKeyData), dataEntryArray)];
483
+ };
484
+ var updateDataEntryObject = (definitionArrayObject, dataArray) => {
485
+ const newNestedObject = {};
486
+ definitionArrayObject.forEach((value) => {
487
+ if (Array.isArray(value)) {
488
+ if (value.length === 2) {
489
+ const [keyString, nestedDataEntry] = nestedDataEntryArrayUpdating(value, dataArray);
490
+ newNestedObject[keyString] = nestedDataEntry;
491
+ } else {
492
+ const [keyString, nestedDataEntry] = generationObjectUpdating(value, dataArray);
493
+ newNestedObject[keyString] = nestedDataEntry;
494
+ }
495
+ } else {
496
+ const [key, dataEntry] = dataEntryUpdating(value, dataArray);
497
+ newNestedObject[key] = dataEntry;
498
+ }
499
+ });
500
+ return newNestedObject;
501
+ };
502
+ var getDefaultObject = (versionObjects, versionindex) => {
503
+ const versionParser = versionObjects[versionindex];
504
+ if (!versionParser)
505
+ throw new Error(`No parser for version ${versionindex} index`);
506
+ return nestedDataEntryArrayToObject(versionParser.objectGeneratorParameters, 0);
507
+ };
508
+ var updateDataEntry = (data, newDataEntry, versionObjects) => {
509
+ const version = data.version;
510
+ const versionParser = versionObjects[version.value];
511
+ if (!versionParser)
512
+ throw new Error(`No parser for version ${version.value}`);
513
+ const correctedDataEntry = dataEntryCorrecting(newDataEntry);
514
+ const dataEntryArray = parseDownNestedDataDescription(data);
515
+ const virginDataEntryArray = [correctedDataEntry, ...dataEntryArray];
516
+ return updateDataEntryObject(versionParser.objectGeneratorParameters, virginDataEntryArray);
517
+ };
518
+ // src/utils/interpolateData.ts
519
+ var interpolateEntryAt = (dataEntry2, t) => {
520
+ const localT = Math.max(Math.min(1, t), 0);
521
+ const cosT = Math.cos(localT * 2 * Math.PI) * 0.5 + 0.5;
522
+ switch (dataEntry2.type) {
523
+ case DataType.BOOLEAN:
524
+ return { ...dataEntry2, value: Boolean(Math.round(localT)) };
525
+ case DataType.VERSION:
526
+ return { ...dataEntry2, value: Math.floor(localT * (dataEntry2.bits ** 2 - 0.001)) };
527
+ case DataType.ENUM:
528
+ return { ...dataEntry2, value: Math.floor(localT * (dataEntry2.max + 0.999)) };
529
+ case DataType.INT:
530
+ return { ...dataEntry2, value: dataEntry2.min + Math.floor(cosT * (dataEntry2.max - dataEntry2.min + 0.999)) };
531
+ case DataType.FLOAT:
532
+ const v = dataEntry2.min + cosT * (dataEntry2.max - dataEntry2.min);
533
+ return dataEntryCorrecting({ ...dataEntry2, value: Math.min(dataEntry2.max, Math.max(v, dataEntry2.min)) });
534
+ }
535
+ };
536
+ // src/utils/relativeValue.ts
537
+ var getRelativeValue = (dataEntry2) => {
538
+ switch (dataEntry2.type) {
539
+ case DataType.BOOLEAN:
540
+ return Number(dataEntry2.value);
541
+ case DataType.INT:
542
+ case DataType.FLOAT:
543
+ return (dataEntry2.value - dataEntry2.min) / (dataEntry2.max - dataEntry2.min);
544
+ case DataType.VERSION:
545
+ return dataEntry2.value / (2 ** dataEntry2.bits - 1);
546
+ case DataType.ENUM:
547
+ return dataEntry2.value / dataEntry2.max;
548
+ }
549
+ };
550
+ export {
551
+ valueBitsParser,
552
+ updateValue6 as updateValue,
553
+ updateDataEntryObject,
554
+ updateDataEntry,
555
+ parseUrlMethod,
556
+ parseDownNestedDataDescription,
557
+ parseBitsToBase64,
558
+ parseBase64ToBits,
559
+ nestedDataEntryArrayToObject,
560
+ interpolateEntryAt,
561
+ getVariableStrings,
562
+ getURLForData,
563
+ getTestStringValues,
564
+ getRelativeValue,
565
+ getDefaultObject,
566
+ getBitsCount6 as getBitsCount,
567
+ dataEntryCorrecting,
568
+ dataBitsStringifier,
569
+ dataBitsParser,
570
+ dataBitsArrayParser,
571
+ dataArrayStringifier,
572
+ ObjectGenerationOutputStatus,
573
+ DataType,
574
+ DataRangeDescriptionFactory,
575
+ DataEntryFactory,
576
+ DataDescriptionFactory
577
+ };
@@ -0,0 +1,7 @@
1
+ export * from './enums';
2
+ export * from './factory';
3
+ export * from './objectmap';
4
+ export * from './parsers';
5
+ export * from './types';
6
+ export * from './update';
7
+ export * from './utils';
package/dist/index.js ADDED
@@ -0,0 +1,596 @@
1
+ // src/enums/dataTypes.ts
2
+ var DataType;
3
+ (function(DataType2) {
4
+ DataType2[DataType2["VERSION"] = 0] = "VERSION";
5
+ DataType2[DataType2["BOOLEAN"] = 1] = "BOOLEAN";
6
+ DataType2[DataType2["ENUM"] = 2] = "ENUM";
7
+ DataType2[DataType2["INT"] = 3] = "INT";
8
+ DataType2[DataType2["FLOAT"] = 4] = "FLOAT";
9
+ })(DataType || (DataType = {}));
10
+ // src/enums/objectGenerationTypes.ts
11
+ var ObjectGenerationOutputStatus;
12
+ (function(ObjectGenerationOutputStatus2) {
13
+ ObjectGenerationOutputStatus2[ObjectGenerationOutputStatus2["DEFAULT"] = 0] = "DEFAULT";
14
+ ObjectGenerationOutputStatus2[ObjectGenerationOutputStatus2["FROM_TYPE"] = 1] = "FROM_TYPE";
15
+ ObjectGenerationOutputStatus2[ObjectGenerationOutputStatus2["PARSED"] = 2] = "PARSED";
16
+ ObjectGenerationOutputStatus2[ObjectGenerationOutputStatus2["ERROR_PARSING"] = 3] = "ERROR_PARSING";
17
+ })(ObjectGenerationOutputStatus || (ObjectGenerationOutputStatus = {}));
18
+ // src/types/floatData.ts
19
+ var SignificandMaxBits = 20;
20
+
21
+ // src/factory/helperMethod.ts
22
+ var getBitsForIntegerNumber = (number, maxBits) => {
23
+ const bitCount = Math.ceil(Math.log2(number));
24
+ if (bitCount > maxBits)
25
+ throw new Error(`Cannot get ${maxBits} bits for a number with ${bitCount} bits`);
26
+ return bitCount;
27
+ };
28
+
29
+ // src/factory/floatFactory.ts
30
+ var create = (min, max, precision) => {
31
+ const precisionMultiplier = 10 ** precision;
32
+ const roundedMin = Math.floor(min * precisionMultiplier);
33
+ const roundedMax = Math.ceil(max * precisionMultiplier);
34
+ const delta = roundedMax - roundedMin;
35
+ const significand = Math.max(1, getBitsForIntegerNumber(delta, SignificandMaxBits));
36
+ return {
37
+ type: DataType.FLOAT,
38
+ min: roundedMin / precisionMultiplier,
39
+ max: roundedMax / precisionMultiplier,
40
+ precision,
41
+ significand
42
+ };
43
+ };
44
+
45
+ // src/types/intData.ts
46
+ var IntegerMaxBits = 12;
47
+
48
+ // src/factory/intFactory.ts
49
+ var create2 = (min, max) => {
50
+ if (!Number.isInteger(min) || !Number.isInteger(max))
51
+ throw new Error("min and max must be integers");
52
+ if (max - min < 1)
53
+ throw new Error("max must be at least one");
54
+ if (Math.abs(max - min) > 2 ** IntegerMaxBits - 1)
55
+ throw new Error("max - min must be less than 1024");
56
+ const bits = getBitsForIntegerNumber(max - min + 1, IntegerMaxBits);
57
+ return { type: DataType.INT, min, max, bits };
58
+ };
59
+
60
+ // src/factory/booleanFactory.ts
61
+ var create3 = () => ({ type: DataType.BOOLEAN });
62
+
63
+ // src/factory/versionFactory.ts
64
+ var create4 = (bits) => ({
65
+ type: DataType.VERSION,
66
+ bits
67
+ });
68
+
69
+ // src/types/enumData.ts
70
+ var EnumMaxBits = 8;
71
+
72
+ // src/factory/enumFactory.ts
73
+ var create5 = (max) => {
74
+ if (!Number.isInteger(max))
75
+ throw new Error("min and max must be integers");
76
+ if (max < 1)
77
+ throw new Error("max must be at least one");
78
+ if (max > 2 ** EnumMaxBits - 1)
79
+ throw new Error("max - min must be less than 256");
80
+ const bits = getBitsForIntegerNumber(max + 1, EnumMaxBits);
81
+ return { type: DataType.ENUM, max, bits };
82
+ };
83
+
84
+ // src/factory/factory.ts
85
+ class DataRangeDescriptionFactory {
86
+ static createFloat = create;
87
+ static createInt = create2;
88
+ static createEnum = create5;
89
+ static createBoolean = create3;
90
+ static createVersion = create4;
91
+ }
92
+
93
+ class DataDescriptionFactory {
94
+ static createFloat = (min = 0, max = 1, precision = 2, name = "", index = 0) => ({
95
+ ...create(min, max, precision),
96
+ name,
97
+ index
98
+ });
99
+ static createInt = (min = 0, max = 10, name = "", index = 0) => ({
100
+ ...create2(min, max),
101
+ name,
102
+ index
103
+ });
104
+ static createEnum = (max = 10, name = "", index = 0) => ({
105
+ ...create5(max),
106
+ name,
107
+ index
108
+ });
109
+ static createBoolean = (name = "", index = 0) => ({
110
+ ...create3(),
111
+ name,
112
+ index
113
+ });
114
+ static createVersion = (bits = 8, name = "", index = 0) => ({
115
+ ...create4(bits),
116
+ name,
117
+ index
118
+ });
119
+ }
120
+
121
+ class DataEntryFactory {
122
+ static createFloat = (value, min = 0, max = 1, precision = 2, name = "", index = 0) => ({
123
+ ...create(min, max, precision),
124
+ value,
125
+ name,
126
+ index
127
+ });
128
+ static createInt = (value, min = 0, max = 10, name = "", index = 0) => ({
129
+ ...create2(min, max),
130
+ value,
131
+ name,
132
+ index
133
+ });
134
+ static createEnum = (value, max = 10, name = "", index = 0) => ({
135
+ ...create5(max),
136
+ value,
137
+ name,
138
+ index
139
+ });
140
+ static createBoolean = (value, name = "", index = 0) => ({
141
+ ...create3(),
142
+ value,
143
+ name,
144
+ index
145
+ });
146
+ static createVersion = (value, bits = 8, name = "", index = 0) => ({
147
+ ...create4(bits),
148
+ value,
149
+ name,
150
+ index
151
+ });
152
+ }
153
+ // src/parsers/intParser.ts
154
+ var getBitsCount = (intData2) => intData2.bits;
155
+ var rawValueParser = (stateString, bitCount) => {
156
+ if (stateString.length < bitCount)
157
+ throw new Error(`To few bits for this int bit string (${stateString.length} instead of ${bitCount})`);
158
+ if (stateString.length > bitCount)
159
+ throw new Error(`To many bits for this int bit string (${stateString.length} instead of ${bitCount})`);
160
+ const parsed = parseInt(stateString, 2);
161
+ if (isNaN(parsed))
162
+ throw new Error("Invalid int state string");
163
+ return parsed;
164
+ };
165
+ var rawParser = (stateString, intData2) => {
166
+ const v = rawValueParser(stateString, intData2.bits) + intData2.min;
167
+ if (v > intData2.max)
168
+ throw new Error("Value exceeds max");
169
+ return v;
170
+ };
171
+ var rawIntStringifier = (value, bitCount) => {
172
+ if (Number.isInteger(value) === false)
173
+ throw new Error("Value is not an integer");
174
+ return value.toString(2).padStart(bitCount, "0");
175
+ };
176
+ var rawStringifier = (value, intData2) => {
177
+ if (value < intData2.min)
178
+ throw new Error("Value is below min");
179
+ if (value > intData2.max)
180
+ throw new Error("Value exceeds max");
181
+ return rawIntStringifier(value - intData2.min, intData2.bits);
182
+ };
183
+
184
+ // src/parsers/floatParser.ts
185
+ var getBitsCount2 = (floatData2) => floatData2.significand;
186
+ var rawValueParser2 = (stateString, significandBits, precision) => {
187
+ if (stateString.length < significandBits)
188
+ throw new Error(`To few bits for this float bit string (${stateString.length} instead of ${significandBits})`);
189
+ if (stateString.length > significandBits)
190
+ throw new Error(`To many bits for this float bit string (${stateString.length} instead of ${significandBits})`);
191
+ const significand = rawValueParser(stateString, significandBits);
192
+ return significand * 10 ** -precision;
193
+ };
194
+ var rawParser2 = (stateString, floatData2) => {
195
+ const v = floatData2.min + rawValueParser2(stateString, floatData2.significand, floatData2.precision);
196
+ if (v > floatData2.max)
197
+ throw new Error("Float value exceeds max");
198
+ return v;
199
+ };
200
+ var rawStringifier2 = (value, floatData2) => rawIntStringifier(Math.round((value - floatData2.min) * 10 ** floatData2.precision), floatData2.significand);
201
+
202
+ // src/parsers/enumParser.ts
203
+ var getBitsCount3 = (versionData) => versionData.bits;
204
+ var rawParser3 = (rawString, versionData) => rawValueParser(rawString, versionData.bits);
205
+ var rawStringifier3 = (value, versionData) => {
206
+ if (value > versionData.max)
207
+ throw new Error("Version exceeds max");
208
+ return rawIntStringifier(value, versionData.bits);
209
+ };
210
+
211
+ // src/parsers/versionParser.ts
212
+ var getBitsCount4 = (versionData) => versionData.bits;
213
+ var rawParser4 = (rawString, versionData) => rawValueParser(rawString, versionData.bits);
214
+ var rawStringifier4 = (value, versionData) => {
215
+ if (value > 2 ** versionData.bits - 1)
216
+ throw new Error("Version exceeds max");
217
+ return rawIntStringifier(value, versionData.bits);
218
+ };
219
+
220
+ // src/parsers/booleanParser.ts
221
+ var getBitsCount5 = () => 1;
222
+ var rawValueParser3 = (stateString) => {
223
+ if (stateString === "1")
224
+ return true;
225
+ if (stateString === "0")
226
+ return false;
227
+ throw new Error("Invalid boolean bit string");
228
+ };
229
+ var rawParser5 = (stateString) => rawValueParser3(stateString);
230
+ var rawStringifier5 = (value) => value ? "1" : "0";
231
+
232
+ // src/parsers/parsers.ts
233
+ var valueBitsParser = (bitString, mapData) => {
234
+ switch (mapData.type) {
235
+ case DataType.BOOLEAN:
236
+ return rawParser5(bitString);
237
+ case DataType.INT:
238
+ return rawParser(bitString, mapData);
239
+ case DataType.ENUM:
240
+ return rawParser3(bitString, mapData);
241
+ case DataType.FLOAT:
242
+ return rawParser2(bitString, mapData);
243
+ case DataType.VERSION:
244
+ return rawParser4(bitString, mapData);
245
+ }
246
+ };
247
+ var dataBitsParser = (rawString, mapData) => {
248
+ switch (mapData.type) {
249
+ case DataType.BOOLEAN:
250
+ return { ...mapData, value: valueBitsParser(rawString, mapData) };
251
+ case DataType.ENUM:
252
+ case DataType.INT:
253
+ case DataType.FLOAT:
254
+ case DataType.VERSION:
255
+ return { ...mapData, value: valueBitsParser(rawString, mapData) };
256
+ }
257
+ };
258
+ var getBitsCount6 = (mapData) => {
259
+ switch (mapData.type) {
260
+ case DataType.BOOLEAN:
261
+ return getBitsCount5();
262
+ case DataType.INT:
263
+ return getBitsCount(mapData);
264
+ case DataType.FLOAT:
265
+ return getBitsCount2(mapData);
266
+ case DataType.VERSION:
267
+ return getBitsCount4(mapData);
268
+ case DataType.ENUM:
269
+ return getBitsCount3(mapData);
270
+ }
271
+ };
272
+ var dataBitsArrayParser = (bitString, mapDataArray) => {
273
+ const bitCounts = mapDataArray.map((mapData) => getBitsCount6(mapData));
274
+ const bitStartEndMap = [];
275
+ bitCounts.forEach((bitCount, index) => {
276
+ const start = index === 0 ? 0 : bitStartEndMap[index - 1][1];
277
+ bitStartEndMap.push([start, start + bitCount]);
278
+ });
279
+ return mapDataArray.map((mapData, i) => dataBitsParser(bitString.slice(bitStartEndMap[i][0], bitStartEndMap[i][1]), mapData));
280
+ };
281
+ var dataBitsStringifier = (data) => {
282
+ switch (data.type) {
283
+ case DataType.BOOLEAN:
284
+ return rawStringifier5(data.value);
285
+ case DataType.INT:
286
+ return rawStringifier(data.value, data);
287
+ case DataType.FLOAT:
288
+ return rawStringifier2(data.value, data);
289
+ case DataType.VERSION:
290
+ return rawStringifier4(data.value, data);
291
+ case DataType.ENUM:
292
+ return rawStringifier3(data.value, data);
293
+ }
294
+ };
295
+ var dataEntryCorrecting = (dataEntry) => dataBitsParser(dataBitsStringifier(dataEntry), dataEntry);
296
+ var base64url = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
297
+ var parseBitsToBase64 = (bits) => {
298
+ const chunks = bits.match(/.{1,6}/g);
299
+ const numbers = chunks?.map((c) => Number.parseInt(c.padEnd(6, "0"), 2)) ?? [];
300
+ return numbers.map((n) => base64url.charAt(n)).join("");
301
+ };
302
+ var parseBase64ToBits = (base64) => {
303
+ const numbers = base64.split("").map((c) => base64url.indexOf(c));
304
+ const chunks = numbers.map((n) => n.toString(2).padStart(6, "0"));
305
+ return chunks.join("");
306
+ };
307
+ var dataArrayStringifier = (dataEntryArray) => {
308
+ return dataEntryArray.map(dataBitsStringifier).join("");
309
+ };
310
+
311
+ // src/objectmap/versionReading.ts
312
+ var parameterOffset = 100;
313
+ var getVariableStrings = (definitionArrayObject) => {
314
+ const keys = [];
315
+ definitionArrayObject.forEach((value) => {
316
+ if (Array.isArray(value)) {
317
+ if (value.length === 2)
318
+ keys.push(...getVariableStrings(value[1]));
319
+ if (value.length === 3)
320
+ keys.push(value[1].name);
321
+ }
322
+ });
323
+ return keys;
324
+ };
325
+ var nestedDataEntryArrayToObject = (definitionArrayObject, startIndex) => {
326
+ const baseIndex = startIndex * parameterOffset;
327
+ return Object.fromEntries(definitionArrayObject.map((value, i) => {
328
+ if (Array.isArray(value)) {
329
+ if (value.length === 2)
330
+ return [value[0], nestedDataEntryArrayToObject(value[1], baseIndex + i)];
331
+ else
332
+ return [value[0], nestedDataEntryArrayToObject(value[2](value[1]), baseIndex + i)];
333
+ }
334
+ return [value.name, { ...value, index: baseIndex + i }];
335
+ }));
336
+ };
337
+ var definitionArrayObjectParser = (bitString, v, orderIndex) => {
338
+ const [key, values] = v;
339
+ const [nestedSemanticObject, objectGenerationStatus, localEndIndex] = parsingDefinitionArrayObject(bitString, values, orderIndex);
340
+ return [[key, nestedSemanticObject], objectGenerationStatus, localEndIndex];
341
+ };
342
+ var methodParser = (bitString, v, orderIndex) => {
343
+ const [key, keyDataDescription, methodGenerator] = v;
344
+ const [keyDataEntry, status, bitWidth] = dataEntryParser(bitString, keyDataDescription, orderIndex);
345
+ const [result, localStatus, localEndIndex] = definitionArrayObjectParser(bitString, [key, methodGenerator(keyDataEntry)], orderIndex);
346
+ return [result, localStatus !== ObjectGenerationOutputStatus.PARSED ? localStatus : status, localEndIndex];
347
+ };
348
+ var dataEntryParser = (bitString, v, baseOrderIndex) => {
349
+ const bitWidth = getBitsCount6(v);
350
+ const value = dataBitsParser(bitString.slice(0, bitWidth), v);
351
+ return [{ ...value, index: baseOrderIndex }, ObjectGenerationOutputStatus.PARSED, bitWidth];
352
+ };
353
+ var parsingDefinitionArrayObject = (bitString, definitionArrayObject, orderIndex) => {
354
+ const baseOrderIndex = orderIndex * parameterOffset;
355
+ let startIndex = 0;
356
+ let objectGenerationStatus = ObjectGenerationOutputStatus.PARSED;
357
+ return [
358
+ Object.fromEntries(definitionArrayObject.map((value, i) => {
359
+ if (Array.isArray(value)) {
360
+ if (value.length === 2) {
361
+ const [[key, nestedSemanticObject], status, localEndIndex] = definitionArrayObjectParser(bitString.slice(startIndex), value, baseOrderIndex + i);
362
+ startIndex += localEndIndex;
363
+ ObjectGenerationOutputStatus.PARSED;
364
+ return [key, nestedSemanticObject];
365
+ } else {
366
+ const [[key, nestedSemanticObject], status, localEndIndex] = methodParser(bitString.slice(startIndex), value, baseOrderIndex + i);
367
+ startIndex += localEndIndex;
368
+ ObjectGenerationOutputStatus.PARSED;
369
+ return [key, nestedSemanticObject];
370
+ }
371
+ } else {
372
+ const [dataEntry, status, localEndIndex] = dataEntryParser(bitString.slice(startIndex), value, baseOrderIndex + i);
373
+ startIndex += localEndIndex;
374
+ ObjectGenerationOutputStatus.PARSED;
375
+ return [dataEntry.name, dataEntry];
376
+ }
377
+ })),
378
+ objectGenerationStatus,
379
+ startIndex
380
+ ];
381
+ };
382
+ var readingVersion = (bitstring) => dataBitsArrayParser(bitstring, [DataDescriptionFactory.createVersion(8)])[0];
383
+ var parseUrlMethod = (url, parserVersions) => {
384
+ const bitString = parseBase64ToBits(url);
385
+ const version = readingVersion(bitString);
386
+ const versionParser = parserVersions[version.value];
387
+ if (!versionParser)
388
+ throw new Error(`No parser for version ${version.value}`);
389
+ return parsingDefinitionArrayObject(bitString, versionParser.objectGeneratorParameters, 0)[0];
390
+ };
391
+ var parseDownNestedDataDescription = (nestedDataDescription) => {
392
+ const dataDescriptions = [];
393
+ Object.values(nestedDataDescription).forEach((value) => {
394
+ if (value.hasOwnProperty("type"))
395
+ dataDescriptions.push(value);
396
+ else
397
+ dataDescriptions.push(...parseDownNestedDataDescription(value));
398
+ });
399
+ return dataDescriptions.sort();
400
+ };
401
+ var getURLForData = (data) => {
402
+ const dataEntryArray = parseDownNestedDataDescription(data);
403
+ const bitstring = dataArrayStringifier(dataEntryArray);
404
+ return parseBitsToBase64(bitstring);
405
+ };
406
+ var getTestStringValues = (data) => {
407
+ const dataEntryArray = parseDownNestedDataDescription(data);
408
+ const bitstring = dataArrayStringifier(dataEntryArray);
409
+ const url = parseBitsToBase64(bitstring);
410
+ const dataValueStrings = dataEntryArray.map((dataEntry) => dataBitsStringifier(dataEntry));
411
+ const singleString = dataValueStrings.join("");
412
+ const base64bitStringArray = singleString.match(/.{1,6}/g)?.map((c) => c.padEnd(6, "0")) ?? [];
413
+ const base64valueArray = url.split("").map((c) => c.padStart(6, "_"));
414
+ const raw = JSON.stringify(parseDownNestedDataDescription(data), undefined, 1);
415
+ return {
416
+ bitsString: dataValueStrings.join("-"),
417
+ base64BitString: base64bitStringArray.join("-"),
418
+ base64SplitString: base64valueArray.join("-"),
419
+ base64String: url,
420
+ raw
421
+ };
422
+ };
423
+ // src/update/floatUpdate.ts
424
+ var updateValue = (original, update) => {
425
+ const value = Math.max(Math.min(update.value, original.max), original.min);
426
+ return {
427
+ ...original,
428
+ value
429
+ };
430
+ };
431
+
432
+ // src/update/intUpdate.ts
433
+ var updateValue2 = (original, update) => {
434
+ const value = Math.max(Math.min(update.value, original.max), original.min);
435
+ return {
436
+ ...original,
437
+ value
438
+ };
439
+ };
440
+
441
+ // src/update/enumUpdate.ts
442
+ var updateValue3 = (original, update) => {
443
+ const value = Math.min(original.max, update.value);
444
+ return {
445
+ ...original,
446
+ value
447
+ };
448
+ };
449
+
450
+ // src/update/versionUpdate.ts
451
+ var updateValue4 = (original, update) => {
452
+ const value = Math.min(original.bits ** 2 - 1, update.value);
453
+ return {
454
+ ...original,
455
+ value
456
+ };
457
+ };
458
+
459
+ // src/update/booleanUpdate.ts
460
+ var updateValue5 = (original, update) => ({
461
+ ...original,
462
+ value: update.value
463
+ });
464
+
465
+ // src/update/updateValues.ts
466
+ var updateValue6 = (original, update) => {
467
+ if (original.type !== update.type)
468
+ throw new Error("Types do not match");
469
+ switch (original.type) {
470
+ case DataType.FLOAT:
471
+ return updateValue(original, update);
472
+ case DataType.INT:
473
+ return updateValue2(original, update);
474
+ case DataType.ENUM:
475
+ return updateValue3(original, update);
476
+ case DataType.VERSION:
477
+ return updateValue4(original, update);
478
+ case DataType.BOOLEAN:
479
+ return updateValue5(original, update);
480
+ }
481
+ };
482
+
483
+ // src/objectmap/versionUpdate.ts
484
+ var dataEntryUpdating = (dataEntry, dataEntryArray) => {
485
+ const existingDataEntry = dataEntryArray.find((d) => d.name === dataEntry.name);
486
+ if (!existingDataEntry)
487
+ return [dataEntry.name, dataEntry];
488
+ return [dataEntry.name, updateValue6(dataEntry, existingDataEntry)];
489
+ };
490
+ var nestedDataEntryArrayUpdating = (definitionNestedArrray, dataEntryArray) => {
491
+ const [keyString, nestedDefinitionArray] = definitionNestedArrray;
492
+ return [keyString, updateDataEntryObject(nestedDefinitionArray, dataEntryArray)];
493
+ };
494
+ var generationObjectUpdating = (definitionArrayObject, dataEntryArray) => {
495
+ const [keyString, keyDataEntry, methodGenerator] = definitionArrayObject;
496
+ const foundKeyDataEntry = dataEntryArray.find((d) => d.name === keyDataEntry.name);
497
+ const newKeyData = foundKeyDataEntry ? updateValue6(keyDataEntry, foundKeyDataEntry) : keyDataEntry;
498
+ return [keyString, updateDataEntryObject(methodGenerator(newKeyData), dataEntryArray)];
499
+ };
500
+ var updateDataEntryObject = (definitionArrayObject, dataArray) => {
501
+ const newNestedObject = {};
502
+ definitionArrayObject.forEach((value) => {
503
+ if (Array.isArray(value)) {
504
+ if (value.length === 2) {
505
+ const [keyString, nestedDataEntry] = nestedDataEntryArrayUpdating(value, dataArray);
506
+ newNestedObject[keyString] = nestedDataEntry;
507
+ } else {
508
+ const [keyString, nestedDataEntry] = generationObjectUpdating(value, dataArray);
509
+ newNestedObject[keyString] = nestedDataEntry;
510
+ }
511
+ } else {
512
+ const [key, dataEntry] = dataEntryUpdating(value, dataArray);
513
+ newNestedObject[key] = dataEntry;
514
+ }
515
+ });
516
+ return newNestedObject;
517
+ };
518
+ var getDefaultObject = (versionObjects, versionindex) => {
519
+ const versionParser = versionObjects[versionindex];
520
+ if (!versionParser)
521
+ throw new Error(`No parser for version ${versionindex} index`);
522
+ return nestedDataEntryArrayToObject(versionParser.objectGeneratorParameters, 0);
523
+ };
524
+ var updateDataEntry = (data, newDataEntry, versionObjects) => {
525
+ const version = data.version;
526
+ const versionParser = versionObjects[version.value];
527
+ if (!versionParser)
528
+ throw new Error(`No parser for version ${version.value}`);
529
+ const correctedDataEntry = dataEntryCorrecting(newDataEntry);
530
+ const dataEntryArray = parseDownNestedDataDescription(data);
531
+ const virginDataEntryArray = [correctedDataEntry, ...dataEntryArray];
532
+ return updateDataEntryObject(versionParser.objectGeneratorParameters, virginDataEntryArray);
533
+ };
534
+ // src/utils/interpolateData.ts
535
+ var interpolateEntryAt = (dataEntry2, t) => {
536
+ const localT = Math.max(Math.min(1, t), 0);
537
+ const cosT = Math.cos(localT * 2 * Math.PI) * 0.5 + 0.5;
538
+ switch (dataEntry2.type) {
539
+ case DataType.BOOLEAN:
540
+ return { ...dataEntry2, value: Boolean(Math.round(localT)) };
541
+ case DataType.VERSION:
542
+ return { ...dataEntry2, value: Math.floor(localT * (dataEntry2.bits ** 2 - 0.001)) };
543
+ case DataType.ENUM:
544
+ return { ...dataEntry2, value: Math.floor(localT * (dataEntry2.max + 0.999)) };
545
+ case DataType.INT:
546
+ return { ...dataEntry2, value: dataEntry2.min + Math.floor(cosT * (dataEntry2.max - dataEntry2.min + 0.999)) };
547
+ case DataType.FLOAT:
548
+ const v = dataEntry2.min + cosT * (dataEntry2.max - dataEntry2.min);
549
+ return dataEntryCorrecting({ ...dataEntry2, value: Math.min(dataEntry2.max, Math.max(v, dataEntry2.min)) });
550
+ }
551
+ };
552
+ // src/utils/relativeValue.ts
553
+ var getRelativeValue = (dataEntry2) => {
554
+ switch (dataEntry2.type) {
555
+ case DataType.BOOLEAN:
556
+ return Number(dataEntry2.value);
557
+ case DataType.INT:
558
+ case DataType.FLOAT:
559
+ return (dataEntry2.value - dataEntry2.min) / (dataEntry2.max - dataEntry2.min);
560
+ case DataType.VERSION:
561
+ return dataEntry2.value / (2 ** dataEntry2.bits - 1);
562
+ case DataType.ENUM:
563
+ return dataEntry2.value / dataEntry2.max;
564
+ }
565
+ };
566
+ export {
567
+ valueBitsParser,
568
+ updateValue6 as updateValue,
569
+ updateDataEntryObject,
570
+ updateDataEntry,
571
+ parseUrlMethod,
572
+ parseDownNestedDataDescription,
573
+ parseBitsToBase64,
574
+ parseBase64ToBits,
575
+ nestedDataEntryArrayToObject,
576
+ interpolateEntryAt,
577
+ getVariableStrings,
578
+ getURLForData,
579
+ getTestStringValues,
580
+ getRelativeValue,
581
+ getDefaultObject,
582
+ getBitsCount6 as getBitsCount,
583
+ dataEntryCorrecting,
584
+ dataBitsStringifier,
585
+ dataBitsParser,
586
+ dataBitsArrayParser,
587
+ dataArrayStringifier,
588
+ SignificandMaxBits,
589
+ ObjectGenerationOutputStatus,
590
+ IntegerMaxBits,
591
+ EnumMaxBits,
592
+ DataType,
593
+ DataRangeDescriptionFactory,
594
+ DataEntryFactory,
595
+ DataDescriptionFactory
596
+ };
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "url-safe-bitpacking",
3
+ "module": "src/index.ts",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "files": [
7
+ "dist/*.js",
8
+ "dist/*.d.ts"
9
+ ],
10
+ "type": "module",
11
+ "version": "0.1.1",
12
+ "author": "Jonas Ward",
13
+ "description": "Library for creating web safe base64 objects with custom bith widths and dynamic values.",
14
+ "scripts": {
15
+ "build": "bun build --target=node ./src/index.ts --outfile=dist/index.js && bun run build:declaration",
16
+ "build:declaration": "tsc --emitDeclarationOnly --project tsconfig.types.json",
17
+ "postbuild": "rimraf tsconfig.types.tsbuildinfo"
18
+ },
19
+ "devDependencies": {
20
+ "bun-types": "latest",
21
+ "rimraf": "^6.0.1"
22
+ },
23
+ "peerDependencies": {
24
+ "typescript": "^5.0.0"
25
+ },
26
+ "dependencies": {
27
+ "typescript": "^5.6.2"
28
+ }
29
+ }