densing 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jonas Ward
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,438 @@
1
+ **Densing** is a TypeScript library for ultra-compact data serialization. It uses bit-level packing to encode structured data into the smallest possible representation, then converts it to character based encodings like urlSafeBase64, or QRBase45-safe strings.
2
+
3
+ Perfect for embedding complex data in URLs, QR codes, or any scenario where every character counts!
4
+
5
+ ## 🎯 Why Densing?
6
+
7
+ ```typescript
8
+ // Traditional JSON: 87 bytes
9
+ const json = '{"deviceId":42,"enabled":true,"temperature":23.5,"mode":"performance"}';
10
+
11
+ // Densing: base64 -> 4 characters (4 bytes) - **94% smaller!**
12
+ const densed = 'Cqnu';
13
+
14
+ // note with:
15
+ // deviceId: value form 0 to 1000 -> 1001 states -> 10 bits
16
+ // enabled: boolean value -> 2 states -> 1 bit
17
+ // temperature: value from -40.0 to 125.0 (one decimal precision) -> 1650 states -> 11 bits
18
+ // mode: 'eco' | 'normal' | 'performance' -> 3 states -> 2 bits
19
+ // --> 24 bits (3 bytes)
20
+ ```
21
+
22
+ ### Key Features
23
+
24
+ - 🔬 **Bit-level precision** - Only uses the exact bits needed for your data
25
+ - 📦 **Type-safe schemas** - Define your data structure with full TypeScript support
26
+ - 🔐 **URL-safe encoding** - Base64url by default, custom bases supported
27
+ - ✅ **Built-in validation method** - Ensure data integrity before encoding
28
+ - 📊 **Size analysis** - See exactly how many bits each field uses
29
+ - 🔄 **Lossless compression** - Perfect round-trip encoding/decoding
30
+ - 🚀 **Zero dependencies** - Lightweight and fast, only uses base javascript types
31
+
32
+ ## 📦 Installation
33
+
34
+ ```bash
35
+ npm install densing
36
+ # or
37
+ bun add densing
38
+ ```
39
+
40
+ ## 🚀 Quick Start
41
+
42
+ ```typescript
43
+ import { schema, int, bool, fixed, enumeration, densing, undensing } from 'densing';
44
+
45
+ // 1. Define your schema
46
+ const DeviceSchema = schema(
47
+ int('deviceId', 0, 1000), // 10 bits (0-1000)
48
+ bool('enabled'), // 1 bit
49
+ fixed('temperature', -40, 125, 0.1), // 11 bits (-40 to 125, precision 0.1)
50
+ enumeration('mode', ['eco', 'normal', 'performance']) // 2 bits (3 options)
51
+ );
52
+ // total of 24 bits
53
+
54
+ // 2. Encode your data
55
+ const data = {
56
+ deviceId: 42,
57
+ enabled: true,
58
+ temperature: 23.5,
59
+ mode: 'performance'
60
+ };
61
+
62
+ const encoded = densing(DeviceSchema, data);
63
+ console.log(encoded); // "Cqnu" (24 bits, 4 base64 chars vs JSON 70 chars, -94%)
64
+
65
+ // 3. Decode it back
66
+ const decoded = undensing(DeviceSchema, encoded);
67
+ console.log(decoded); // { deviceId: 42, enabled: true, temperature: 23.5, mode: 'performance' }
68
+ ```
69
+
70
+ ## 📚 Core Concepts
71
+
72
+ ### Schema Definition
73
+
74
+ Schemas define the structure and constraints of your data. Densing uses this to calculate the minimum bits needed.
75
+
76
+ ```typescript
77
+ import { schema, int, fixed, bool, enumeration } from 'densing';
78
+
79
+ const MySchema = schema(
80
+ // Integers: specify min and max range
81
+ int('id', 0, 1000), // 10 bits for 1001 possible values
82
+
83
+ // Fixed-point numbers: specify range and precision
84
+ fixed('price', 0, 100, 0.01), // 14 bits for $0.00 to $100.00
85
+
86
+ // Booleans: just 1 bit
87
+ bool('active'),
88
+
89
+ // Enums: bits based on number of options
90
+ enumeration('status', ['pending', 'active', 'done']) // 2 bits for 3 options
91
+ );
92
+ ```
93
+
94
+ ### Field Types
95
+
96
+ | Type | Description | Bits Used | Example |
97
+ | ----------- | ------------------- | --------------------------------- | ----------------------------------------------------------- |
98
+ | `int` | Integer range | `log2(max - min + 1)` | `int('age', 0, 120)` → 7 bits |
99
+ | `fixed` | Fixed-point decimal | `log2((max-min) / precision + 1)` | `fixed('temp', 0, 50, 0.1)` → 9 bits |
100
+ | `bool` | Boolean | 1 bit | `bool('enabled')` |
101
+ | `enum` | Enumeration | `log2(options.length)` | `enumeration('color', ['R', 'G', 'B'])` → 2 bits |
102
+ | `optional` | Optional field | 1 + field bits | `optional('metadata', int('version', 0, 10))` |
103
+ | `array` | Array of fields | length bits + content | `array('items', 0, 10, int('value', 0, 100))` |
104
+ | `enumArray` | Packed enum array | length + packed content | `enumArray('tags', enum, 0, 5)` |
105
+ | `object` | Nested object | sum of field bits | `object('config', bool('debug'), int('port', 1024, 65535))` |
106
+ | `union` | Discriminated union | discriminator + variant | `union('action', discriminator, variants)` |
107
+
108
+ ## 🎨 Examples
109
+
110
+ ### Optional Fields
111
+
112
+ Optional fields add a single presence bit:
113
+
114
+ ```typescript
115
+ import { schema, int, optional } from 'densing';
116
+
117
+ const UserSchema = schema(
118
+ int('id', 0, 10000), // 10001 states -> 14 bits
119
+ optional('age', int('ageValue', 0, 120)) // 2 + 121 states -> 1 bit presence + 7 bits if present
120
+ ); // 14 + 1 (+ 7 bits) -> 15 or 22 bits
121
+
122
+ // With age
123
+ densing(UserSchema, { id: 100, age: 25 }); // "AZJk" (22 bits, 4 base64 chars vs JSON 19 chars, -79%)
124
+
125
+ // Without age
126
+ densing(UserSchema, { id: 100, age: null }); // "AZA" (15 bits, 3 base64 chars vs JSON 21 chars, -86%)
127
+ ```
128
+
129
+ ### Nested Objects
130
+
131
+ ```typescript
132
+ import { schema, int, object, bool } from 'densing';
133
+
134
+ const ConfigSchema = schema(int('version', 1, 10), object('settings', bool('darkMode'), int('fontSize', 8, 24)));
135
+
136
+ const data = {
137
+ version: 2,
138
+ settings: {
139
+ darkMode: true,
140
+ fontSize: 14
141
+ }
142
+ };
143
+
144
+ densing(ConfigSchema, data); // "GY" (10 bits, 2 base64 chars vs JSON 56 chars, -96%)
145
+ ```
146
+
147
+ ### Arrays
148
+
149
+ ```typescript
150
+ import { schema, array, int } from 'densing';
151
+
152
+ const ListSchema = schema(
153
+ array('scores', 0, 10, int('score', 0, 100)) // 0-10 scores, each 0-100 -> 4 bits + 0-10 x 7 bits
154
+ );
155
+
156
+ // In readme-examples.test.ts, you can add:
157
+ const data1 = { scores: [95] }; // 4 + 7 bits -> 11 bits -> 2 characters vs 13 (-85%) => "G-"
158
+ const data2 = { scores: [95, 87, 92, 88] }; // 4 + 4 * 7 bits -> 32 bits -> 6 characters vs 22 (-73%) => "S_XuWA"
159
+ const data3 = { scores: [95, 87, 92, 88, 10, 12, 13, 15, 16, 99] }; // 4 + 10 * 7 bits -> 74 bits -> 13 characters vs 40 (-68%) => "q_XuWBQwaPIYw"
160
+
161
+ densing(ListSchema, data1); // "G-" (11 bits, 2 base64 chars vs JSON 15 chars, -87%)
162
+ densing(ListSchema, data2); // "S_XuWA" (32 bits, 6 base64 chars vs JSON 24 chars, -75%)
163
+ densing(ListSchema, data3); // "q_XuWBQwaPIYw" (74 bits, 13 base64 chars vs JSON 42 chars, -69%)
164
+ ```
165
+
166
+ ### Unions (Polymorphic Types)
167
+
168
+ ```typescript
169
+ import { schema, union, enumeration, int, bool } from 'densing';
170
+
171
+ const ActionSchema = schema(
172
+ union('action', enumeration('type', ['start', 'stop', 'pause']), {
173
+ start: [int('delay', 0, 60)],
174
+ stop: [bool('force')],
175
+ pause: [int('duration', 0, 3600)]
176
+ })
177
+ );
178
+
179
+ // Start action
180
+ densing(ActionSchema, { action: { type: 'start', delay: 5 } }); // "BQ" (8 bits, 2 base64 chars vs JSON 37 chars, -95%)
181
+
182
+ // Stop action
183
+ densing(ActionSchema, { action: { type: 'stop', force: true } }); // "Y" (3 bits, 1 base64 char vs JSON 39 chars, -97%)
184
+
185
+ // Pause action
186
+ densing(ActionSchema, { action: { type: 'pause', duration: 1234 } }); // "k0g" (14 bits, 3 base64 chars vs JSON 43 chars, -93%)
187
+ ```
188
+
189
+ ### Enum Arrays (Packed)
190
+
191
+ Enum arrays are packed into minimal bits using base-N encoding:
192
+
193
+ ```typescript
194
+ import { schema, enumArray, enumeration } from 'densing';
195
+
196
+ const ColorSchema = schema(enumArray('palette', enumeration('color', ['R', 'G', 'B']), 0, 10));
197
+
198
+ const data = { palette: ['R', 'G', 'B', 'R', 'R'] };
199
+ const encoded = densing(ColorSchema, data);
200
+ // "Ut" (12 bits, 2 base64 chars vs JSON 33 chars, -94%)
201
+ ```
202
+
203
+ ## 🔧 Advanced Features
204
+
205
+ ### Validation
206
+
207
+ Validate data before encoding:
208
+
209
+ ```typescript
210
+ import { validate } from 'densing';
211
+
212
+ const result = validate(MySchema, data);
213
+
214
+ if (!result.valid) {
215
+ console.error('Validation errors:', result.errors);
216
+ // [{ path: 'age', message: 'value 150 out of range [0, 120]' }]
217
+ }
218
+ ```
219
+
220
+ ### Size Analysis
221
+
222
+ See exactly how your data will be encoded:
223
+
224
+ ```typescript
225
+ import { analyzeDenseSchemaSize, calculateDenseDataSize } from 'densing';
226
+
227
+ // Static analysis (without data)
228
+ const schemaSize = analyzeDenseSchemaSize(MySchema);
229
+ console.log(schemaSize.staticRange);
230
+ // { minBits: 18, maxBits: 45, minBase64Chars: 3, maxBase64Chars: 8 }
231
+
232
+ // Actual size for specific data
233
+ const dataSize = calculateDenseDataSize(MySchema, myData);
234
+ console.log(dataSize);
235
+ // {
236
+ // totalBits: 32,
237
+ // base64Length: 6,
238
+ // fieldSizes: { deviceId: 10, enabled: 1, temperature: 11, mode: 2 },
239
+ // efficiency: { utilizationPercent: 51.8 }
240
+ // }
241
+ ```
242
+
243
+ ### Default Values
244
+
245
+ Generate default data for your schema:
246
+
247
+ ```typescript
248
+ import { getDefaultData } from 'densing';
249
+
250
+ const defaultData = getDefaultData(MySchema);
251
+ // { deviceId: 0, enabled: false, temperature: -40, mode: 'eco' }
252
+ ```
253
+
254
+ ### Type Generation
255
+
256
+ Generate TypeScript types from your schema:
257
+
258
+ ```typescript
259
+ import { generateTypes } from 'densing';
260
+
261
+ const types = generateTypes(MySchema, 'MyData');
262
+ console.log(types);
263
+ // export interface MyData {
264
+ // deviceId: number;
265
+ // enabled: boolean;
266
+ // temperature: number;
267
+ // mode: 'eco' | 'normal' | 'performance';
268
+ // }
269
+ ```
270
+
271
+ ### Custom Bases
272
+
273
+ Use any character set for encoding:
274
+
275
+ ```typescript
276
+ // Default: base64url (URL-safe)
277
+ densing(schema, data); // "VA" (example)
278
+
279
+ // Binary string
280
+ densing(schema, data, 'binary'); // "0101010"
281
+
282
+ // Custom base (hexadecimal)
283
+ densing(schema, data, '0123456789ABCDEF'); // "54"
284
+
285
+ // Decode with same base
286
+ undensing(schema, encoded, 'binary');
287
+ ```
288
+
289
+ ### Recursive Structures
290
+
291
+ Define recursive data structures with `createRecursiveUnion`:
292
+
293
+ ```typescript
294
+ import { schema, createRecursiveUnion, int, enumeration } from 'densing';
295
+
296
+ const ExpressionSchema = schema(
297
+ createRecursiveUnion(
298
+ 'expr',
299
+ ['number', 'add', 'multiply'],
300
+ (recurse) => ({
301
+ number: [int('value', 0, 1000)],
302
+ add: [recurse('left'), recurse('right')],
303
+ multiply: [recurse('left'), recurse('right')]
304
+ }),
305
+ 5 // max depth
306
+ )
307
+ );
308
+
309
+ // Encode: (5 + 3) * 2
310
+ const data = {
311
+ expr: {
312
+ type: 'multiply',
313
+ left: {
314
+ type: 'add',
315
+ left: { type: 'number', value: 5 },
316
+ right: { type: 'number', value: 3 }
317
+ },
318
+ right: { type: 'number', value: 2 }
319
+ }
320
+ };
321
+
322
+ densing(ExpressionSchema, data); // "kAUAMAI" (190 bits, 7 base64 chars vs JSON 157 chars, -96%)
323
+ ```
324
+
325
+ ## 📊 Use Cases
326
+
327
+ ### URL Parameters
328
+
329
+ ```typescript
330
+ // Embed complex state in URLs
331
+ const state = { page: 5, sortBy: 'date', filters: [1, 3] };
332
+ const url = `https://app.com/search?state=${densing(StateSchema, state)}`;
333
+ // https://app.com/search?state=CCEw (4 base64 chars, 20 bits vs JSON 42 chars, -90%)
334
+ ```
335
+
336
+ ### QR Codes
337
+
338
+ ```typescript
339
+ // Fit more data in QR codes
340
+ const deviceConfig = { id: 123, settings: {...} };
341
+ const qrData = densing(ConfigSchema, deviceConfig);
342
+ // Compact encoding means lower error correction level or more data capacity
343
+ ```
344
+
345
+ ### IoT & Embedded Systems
346
+
347
+ ```typescript
348
+ // Minimize bandwidth for sensor data
349
+ const sensorData = { temp: 23.5, humidity: 65.2, battery: 87 };
350
+ const payload = densing(SensorSchema, sensorData);
351
+ // "T3Rlc" (28 bits, 5 base64 chars vs JSON 42 chars, -88%)
352
+ ```
353
+
354
+ ### Local Storage
355
+
356
+ ```typescript
357
+ // Reduce storage footprint
358
+ localStorage.setItem('userPrefs', densing(PrefsSchema, preferences));
359
+ // Store 10 preferences in compact form instead of verbose JSON
360
+ ```
361
+
362
+ ## 🧪 Testing
363
+
364
+ The library includes comprehensive tests:
365
+
366
+ ```bash
367
+ bun test
368
+ # 348 tests pass
369
+ ```
370
+
371
+ ## 📖 API Reference
372
+
373
+ For detailed API documentation, see [API.md](./API.md).
374
+
375
+ ### Core Functions
376
+
377
+ - `schema(...fields)` - Define a schema
378
+ - `densing(schema, data, base?)` - Encode data
379
+ - `undensing(schema, encoded, base?)` - Decode data
380
+ - `validate(schema, data)` - Validate data
381
+ - `getDefaultData(schema)` - Generate default values
382
+
383
+ ### Field Builders
384
+
385
+ - `int(name, min, max, default?)` - Integer field
386
+ - `fixed(name, min, max, precision, default?)` - Fixed-point number
387
+ - `bool(name, default?)` - Boolean field
388
+ - `enumeration(name, options, default?)` - Enum field
389
+ - `optional(name, field, default?)` - Optional field
390
+ - `array(name, minLength, maxLength, itemField)` - Array field
391
+ - `enumArray(name, enumField, minLength, maxLength)` - Packed enum array
392
+ - `object(name, ...fields)` - Nested object
393
+ - `union(name, discriminator, variants)` - Discriminated union
394
+
395
+ ### Utility Functions
396
+
397
+ - `analyzeDenseSchemaSize(schema)` - Static size analysis
398
+ - `calculateDenseDataSize(schema, data)` - Actual size calculation
399
+ - `getDenseFieldBitWidthRange(field)` - Min/max bits for field
400
+ - `calculateDenseFieldBitWidth(field, value)` - Actual bits used
401
+ - `getFieldByPath(schema, path)` - Get field by path
402
+ - `walkDenseSchema(schema, callback)` - Visit all fields
403
+ - `getAllDenseSchemaPaths(schema)` - Get all field paths
404
+ - `generateTypes(schema, typeName?)` - Generate TypeScript types
405
+
406
+ ## 🎯 Performance
407
+
408
+ Densing is designed for efficiency (benchmarked on Bun runtime on m4 macbookAir):
409
+
410
+ **Simple Schema (4 fields: int, bool, fixed, enum):**
411
+ - Encoding: **~1,330,000 ops/sec** (0.75µs per operation)
412
+ - Decoding: **~1,516,000 ops/sec** (0.66µs per operation)
413
+ - Round-trip: **~753,000 ops/sec** (1.33µs per operation)
414
+
415
+ **Complex Schema (nested objects, arrays, optionals):**
416
+ - Encoding: **~484,000 ops/sec** (2.06µs per operation)
417
+ - Decoding: **~394,000 ops/sec** (2.54µs per operation)
418
+
419
+ **Large Arrays (50 integer elements):**
420
+ - Encoding: **~98,000 ops/sec** (10.23µs per operation)
421
+ - Decoding: **~91,000 ops/sec** (11.02µs per operation)
422
+
423
+ Run your own benchmarks:
424
+ ```bash
425
+ bun run benchmark.ts
426
+ ```
427
+
428
+ ## 🤝 Contributing
429
+
430
+ Contributions are welcome! Please feel free to submit issues or pull requests.
431
+
432
+ ## 🙏 Acknowledgments
433
+
434
+ Built with TypeScript and tested with Bun.
435
+
436
+ ---
437
+
438
+ **Made with ❤️ for applications where every character matters**
package/dist/api.d.ts ADDED
@@ -0,0 +1,69 @@
1
+ import { DenseSchema, DenseField } from './schema-type';
2
+ /**
3
+ * Calculate the bit width RANGE for a field (min and max possible bits)
4
+ * Returns the minimum and maximum number of bits that can be used to encode this field
5
+ */
6
+ export declare const getDenseFieldBitWidthRange: (field: DenseField) => {
7
+ min: number;
8
+ max: number;
9
+ };
10
+ /**
11
+ * Calculate the ACTUAL bit width for a field with a specific value
12
+ * Returns the exact number of bits that will be used when encoding this value
13
+ */
14
+ export declare const calculateDenseFieldBitWidth: (field: DenseField, value: any) => number;
15
+ /**
16
+ * Schema-level size information (static analysis without data)
17
+ */
18
+ export interface SchemaSizeInfo {
19
+ staticRange: {
20
+ minBits: number;
21
+ maxBits: number;
22
+ minBytes: number;
23
+ maxBytes: number;
24
+ minBase64Chars: number;
25
+ maxBase64Chars: number;
26
+ };
27
+ fieldRanges: Record<string, {
28
+ min: number;
29
+ max: number;
30
+ }>;
31
+ }
32
+ /**
33
+ * Analyze a schema to get static size information (min/max possible encoding sizes)
34
+ */
35
+ export declare const analyzeDenseSchemaSize: (schema: DenseSchema) => SchemaSizeInfo;
36
+ /**
37
+ * Data-specific size information (actual encoding size for given data)
38
+ */
39
+ export interface DataSizeInfo {
40
+ totalBits: number;
41
+ totalBytes: number;
42
+ base64Length: number;
43
+ fieldSizes: Record<string, number>;
44
+ efficiency: {
45
+ usedBits: number;
46
+ minPossibleBits: number;
47
+ maxPossibleBits: number;
48
+ utilizationPercent: number;
49
+ };
50
+ }
51
+ /**
52
+ * Calculate the actual encoding size for specific data
53
+ */
54
+ export declare const calculateDenseDataSize: (schema: DenseSchema, data: any) => DataSizeInfo;
55
+ /**
56
+ * Get a field definition by path
57
+ * @example getFieldByPath(schema, 'network.port') -> IntField
58
+ */
59
+ export declare const getFieldByPath: (schema: DenseSchema, path: string) => DenseField | null;
60
+ /**
61
+ * Walk all fields in schema (including nested)
62
+ * @example walkDenseSchema(schema, (field, path) => console.log(path, field))
63
+ */
64
+ export declare const walkDenseSchema: (schema: DenseSchema, callback: (field: DenseField, path: string, parent?: DenseField) => void, prefix?: string) => void;
65
+ /**
66
+ * Get all paths in schema
67
+ * @example getAllPaths(schema) -> ['deviceId', 'deviceType', 'network.ssid', 'network.port', ...]
68
+ */
69
+ export declare const getAllDenseSchemaPaths: (schema: DenseSchema) => string[];
@@ -0,0 +1,39 @@
1
+ import { BitWriter, BitReader, BaseType } from './helpers';
2
+ import { DenseSchema, DenseField, ConstantBitWidthField } from './schema-type';
3
+ export declare const bitsForRange: (range: number) => number;
4
+ export declare const bitsForMinMaxLength: (minLength: number, maxLength: number) => number;
5
+ export declare const lengthForUIntMinMaxLength: (uInt: number, minLength: number) => number;
6
+ export declare const bitsForOptions: (options: readonly string[]) => number;
7
+ /**
8
+ * Densing method - key method to dense (pack into encoded string) the data for a given schema into a string of a specific base
9
+ * @param denseSchema - The schema to dense the data for
10
+ * @param data - The data to dense
11
+ * @param base - The base as string of characters, where every symbol is interpreted as a specific value
12
+ * @returns The dense string in the given base
13
+ */
14
+ export declare const densing: (denseSchema: DenseSchema, data: any, base?: BaseType | string) => string;
15
+ export declare const getUIntForConstantBitWidthField: (field: ConstantBitWidthField, value: any) => number;
16
+ export declare const getBitWidthForContantBitWidthFields: (field: ConstantBitWidthField) => number;
17
+ /**
18
+ * Helper method to dense a single field of the schema into the given bit writer
19
+ * @param w - The bit writer to write the dense data to
20
+ * @param field - The field used as the template to dense the value with
21
+ * @param value - The value to dense, should match the type of the field! This method doesn't do any validation of data!
22
+ */
23
+ export declare const densingField: (w: BitWriter, field: DenseField, value: any) => void;
24
+ /**
25
+ * Undensing method - key method to undense (unpack from encoded string) the data for a given schema from a string of a specific base
26
+ * @param denseSchema - The schema to undense the data for
27
+ * @param baseString - The dense string to undense
28
+ * @param base - The base as string of characters, where every symbol is interpreted as a specific value
29
+ * @returns The undense data
30
+ */
31
+ export declare const undensing: (denseSchema: DenseSchema, baseString: string, base?: BaseType | string) => any;
32
+ export declare const undensingDataForConstantBitWidthField: (field: ConstantBitWidthField, unsignedInt: number) => any;
33
+ /**
34
+ * Internal Helper method to undense a single field of the schema from the given bit reader
35
+ * @param r - The bit reader to read the dense data from
36
+ * @param denseField - The field used as the template to undense the value with
37
+ * @returns The undense value, should match the type of the field! This method doesn't do any validation of data!
38
+ */
39
+ export declare const undensingField: (r: BitReader, denseField: DenseField) => any;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * In Densing defined base types
3
+ * You can provide your own as well
4
+ */
5
+ export declare const BaseTypes: readonly ["base64url", "baseQRCode45UrlSafe", "binary"];
6
+ /**
7
+ * Predefined base types
8
+ */
9
+ export type BaseType = (typeof BaseTypes)[number];
10
+ export declare const base64url = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
11
+ export declare const baseQRCode45UrlSafe = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-.";
12
+ export declare const binary = "01";
13
+ export declare const getBigIntFromBase64: (base64: string) => bigint;
14
+ export declare const getBase64FromBigInt: (bigInt: bigint, bitWidth?: number) => string;
15
+ export declare const getbaseQRCode45UrlSafeFromBigInt: (bigInt: bigint, bitWidth?: number) => string;
16
+ export declare const getBigIntFrombaseQRCode45UrlSafe: (baseQRCode45UrlSafe: string) => bigint;
17
+ /**
18
+ * Helper class for writing the uInt numeric value of a field in the schema into the bigint representing the densed data
19
+ */
20
+ export declare class BitWriter {
21
+ private buffer;
22
+ private bitsWritten;
23
+ constructor();
24
+ writeUInt: (value: number | bigint, bitWidth: number) => void;
25
+ getBigInt: () => bigint;
26
+ getBitLength: () => number;
27
+ getFromBase: (base?: BaseType | string) => string;
28
+ }
29
+ /**
30
+ * Helper class for reading the uInt numeric value of a field in the schema from the bigint representing the densed data
31
+ */
32
+ export declare class BitReader {
33
+ private buffer;
34
+ private bitsLeft;
35
+ private constructor();
36
+ readUInt: (bitWidth: number) => number;
37
+ readUBigInt: (bitWidth: number) => bigint;
38
+ static getFromBase: (baseString: string, base: BaseType | string) => BitReader;
39
+ }
@@ -0,0 +1,5 @@
1
+ export * from './schema';
2
+ export * from './densing';
3
+ export * from './helpers';
4
+ export * from './schema-type';
5
+ export * from './api';