zeck 1.0.7 → 2.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/README.md CHANGED
@@ -408,6 +408,28 @@ This avoids redundant Fibonacci numbers (F(0)=0 and F(1)=F(2)=1).
408
408
  - The library supports both big-endian and little-endian interpretations, but other byte orderings or word boundaries are not currently explored
409
409
  - **⚠️ Warning:** Compressing or decompressing files larger than 10KB (10,000 bytes) is unstable due to time and memory pressure. The library may experience performance issues, excessive memory usage, or failures when processing files exceeding this size.
410
410
 
411
+ ## NPM Versioning Quirk
412
+
413
+ For some reason, NPM was showing there were versions of zeck published between `1.0.0` and `1.0.6` from 2024, even though I never published them to npm. I don't know how this happened. So I bumped the version to `1.0.7` and was able to successfully publish it to npm. Maybe there was an old package with the same name that was deleted, and NPM is still showing the old versions.
414
+
415
+ Here is a snippet of the `time` object from the npm registry JSON (https://registry.npmjs.org/zeck):
416
+
417
+ ```json
418
+ "time": {
419
+ "created": "2026-01-02T20:19:14.018Z",
420
+ "modified": "2026-01-03T17:25:15.940Z",
421
+ "1.0.0": "2024-02-21T14:36:36.292Z",
422
+ "1.0.1": "2024-02-21T15:26:38.621Z",
423
+ "1.0.2": "2024-02-21T15:36:30.258Z",
424
+ "1.0.3": "2024-02-21T15:48:07.853Z",
425
+ "1.0.4": "2024-02-21T15:48:38.804Z",
426
+ "1.0.5": "2024-02-21T16:02:36.339Z",
427
+ "1.0.6": "2024-02-21T16:36:36.643Z",
428
+ "0.1.0": "2026-01-02T20:19:14.175Z",
429
+ "0.2.0": "2026-01-03T17:25:15.702Z"
430
+ },
431
+ ```
432
+
411
433
  ## License
412
434
 
413
435
  This project is licensed under the MIT License - see the [LICENSE.txt](LICENSE.txt) file for details.
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "Peter Ryszkiewicz"
6
6
  ],
7
7
  "description": "A Rust library for compressing and decompressing data using the Zeckendorf representation algorithm",
8
- "version": "1.0.7",
8
+ "version": "2.1.0",
9
9
  "license": "MIT",
10
10
  "repository": {
11
11
  "type": "git",
package/zeck.d.ts CHANGED
@@ -1,5 +1,41 @@
1
1
  /* tslint:disable */
2
2
  /* eslint-disable */
3
+ /**
4
+ * Represents a .zeck file with its header information and compressed data.
5
+ *
6
+ * This struct holds all the information needed to reconstruct a .zeck file,
7
+ * including the format version, original file size, endianness flags, and
8
+ * the compressed data itself.
9
+ */
10
+ export interface ZeckFile {
11
+ /**
12
+ * File format version
13
+ */
14
+ version: number;
15
+ /**
16
+ * Original uncompressed file size in bytes
17
+ */
18
+ original_size: number;
19
+ /**
20
+ * Flags byte (bit 0 = big endian, bits 1-7 reserved)
21
+ */
22
+ flags: number;
23
+ /**
24
+ * Compressed data (without header)
25
+ */
26
+ compressed_data: number[];
27
+ }
28
+
29
+ /**
30
+ * Result of best compression attempt, containing the best compressed zeck file and the size for the other endianness attempt, or if neither produced compression (both were larger than the original).
31
+ */
32
+ export type BestCompressionResult = { BigEndianBest: { zeck_file: ZeckFile; le_size: number } } | { LittleEndianBest: { zeck_file: ZeckFile; be_size: number } } | { Neither: { be_size: number; le_size: number } };
33
+
34
+ /**
35
+ * Errors that can occur when parsing or processing .zeck files.
36
+ */
37
+ export type ZeckFormatError = { HeaderTooShort: { actual_length: number; required_length: number } } | { UnsupportedVersion: { found_version: number; supported_version: number } } | { ReservedFlagsSet: { flags: number } } | { CompressionFailed: { original_size: number; be_size: number; le_size: number } } | { DecompressedTooLarge: { expected_size: number; actual_size: number } } | { DataSizeTooLarge: { size: number } };
38
+
3
39
 
4
40
  /**
5
41
  * Returns the number of bits required to represent the given number. Returns 0 if the number is less than or equal to 0.
@@ -17,6 +53,129 @@
17
53
  */
18
54
  export function bit_count_for_number(n: number): number;
19
55
 
56
+ /**
57
+ * Compresses data using the Zeckendorf algorithm with big endian interpretation,
58
+ * and stores the result in a [`ZeckFile`] struct.
59
+ *
60
+ * # ⚠️ Warning
61
+ *
62
+ * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
63
+ * The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
64
+ *
65
+ * # Examples
66
+ *
67
+ * ```
68
+ * # use zeck::zeck_file_format::compress::compress_zeck_be;
69
+ * let data = vec![1, 0];
70
+ * match compress_zeck_be(&data) {
71
+ * Ok(zeck_file) => {
72
+ * // Access file information
73
+ * println!("Original size: {} bytes", zeck_file.original_size);
74
+ * println!("Is big endian: {}", zeck_file.is_big_endian());
75
+ * // Serialize to bytes for writing to file
76
+ * let bytes = zeck_file.to_bytes();
77
+ * }
78
+ * Err(e) => {
79
+ * // Handle error (e.g., data size too large)
80
+ * }
81
+ * }
82
+ * ```
83
+ */
84
+ export function compress_zeck_be(data: Uint8Array): ZeckFile;
85
+
86
+ /**
87
+ * Compresses data using the Zeckendorf algorithm with automatic endianness selection,
88
+ * and stores the result in a [`BestCompressionResult`] struct.
89
+ *
90
+ * This function attempts compression with both big endian and little endian interpretations,
91
+ * and returns the best result, or if neither produced compression (both were larger than the original).
92
+ *
93
+ * # ⚠️ Warning
94
+ *
95
+ * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
96
+ * The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
97
+ *
98
+ * # Examples
99
+ *
100
+ * ```
101
+ * # use zeck::zeck_file_format::compress::compress_zeck_best;
102
+ * # use zeck::zeck_file_format::compress::BestCompressionResult;
103
+ * # use zeck::zeck_file_format::decompress::decompress_zeck_file;
104
+ * let data = vec![0, 1]; // Compresses best interpreted as a big endian integer
105
+ * match compress_zeck_best(&data) {
106
+ * Ok(best_compression_result) => {
107
+ * match best_compression_result {
108
+ * BestCompressionResult::BigEndianBest { zeck_file, le_size } => {
109
+ * let decompressed = decompress_zeck_file(&zeck_file).unwrap();
110
+ * assert_eq!(decompressed, data);
111
+ * }
112
+ * BestCompressionResult::LittleEndianBest { zeck_file, be_size } => {
113
+ * assert!(false);
114
+ * }
115
+ * BestCompressionResult::Neither { be_size, le_size } => {
116
+ * assert!(false);
117
+ * }
118
+ * }
119
+ * }
120
+ * Err(e) => {
121
+ * assert!(false);
122
+ * }
123
+ * }
124
+ *
125
+ * let data = vec![1, 0]; // Compresses best interpreted as a little endian integer
126
+ * match compress_zeck_best(&data) {
127
+ * Ok(best_compression_result) => {
128
+ * match best_compression_result {
129
+ * BestCompressionResult::BigEndianBest { zeck_file, le_size } => {
130
+ * assert!(false);
131
+ * }
132
+ * BestCompressionResult::LittleEndianBest { zeck_file, be_size } => {
133
+ * let decompressed = decompress_zeck_file(&zeck_file).unwrap();
134
+ * assert_eq!(decompressed, data);
135
+ * }
136
+ * BestCompressionResult::Neither { be_size, le_size } => {
137
+ * assert!(false);
138
+ * }
139
+ * }
140
+ * }
141
+ * Err(e) => {
142
+ * assert!(false);
143
+ * }
144
+ * }
145
+ * ```
146
+ */
147
+ export function compress_zeck_best(data: Uint8Array): BestCompressionResult;
148
+
149
+ /**
150
+ * Compresses data using the Zeckendorf algorithm with little endian interpretation,
151
+ * and stores the result in a [`ZeckFile`] struct.
152
+ *
153
+ * # ⚠️ Warning
154
+ *
155
+ * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
156
+ * The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
157
+ *
158
+ * # Examples
159
+ *
160
+ * ```
161
+ * # use zeck::zeck_file_format::compress::compress_zeck_le;
162
+ * let data = vec![1, 0];
163
+ * match compress_zeck_le(&data) {
164
+ * Ok(zeck_file) => {
165
+ * // Access file information
166
+ * println!("Original size: {} bytes", zeck_file.original_size);
167
+ * println!("Compressed size: {} bytes", zeck_file.compressed_data.len());
168
+ * // Serialize to bytes for writing to file
169
+ * let bytes = zeck_file.to_bytes();
170
+ * }
171
+ * Err(e) => {
172
+ * // Handle error (e.g., data size too large)
173
+ * }
174
+ * }
175
+ * ```
176
+ */
177
+ export function compress_zeck_le(data: Uint8Array): ZeckFile;
178
+
20
179
  /**
21
180
  * Effective Fibonacci Index to Fibonacci Index: FI(efi) === efi + 2, where efi is the Effective Fibonacci Index
22
181
  *
@@ -64,9 +223,9 @@ export function ezba_from_ezld(effective_zeckendorf_list_descending: BigUint64Ar
64
223
  *
65
224
  * ```
66
225
  * # use zeck::ezba_to_ezla;
67
- * assert_eq!(ezba_to_ezla(&[0, 0, 0, 0, 0, 0, 0, 0]), vec![]);
68
- * assert_eq!(ezba_to_ezla(&[1, 0, 0, 0, 0, 0, 0, 0]), vec![0]);
69
- * assert_eq!(ezba_to_ezla(&[1, 1, 1, 0, 0, 0, 0, 0]), vec![0, 2, 4]);
226
+ * assert_eq!(ezba_to_ezla(&[0, 0, 0, 0, 0, 0, 0, 0]), vec![] as Vec<u64>);
227
+ * assert_eq!(ezba_to_ezla(&[1, 0, 0, 0, 0, 0, 0, 0]), vec![0u64]);
228
+ * assert_eq!(ezba_to_ezla(&[1, 1, 1, 0, 0, 0, 0, 0]), vec![0u64, 2u64, 4u64]);
70
229
  * ```
71
230
  */
72
231
  export function ezba_to_ezla(ezba_bits: Uint8Array): BigUint64Array;
@@ -194,21 +353,21 @@ export function memoized_slow_fibonacci_recursive(fi: bigint): bigint;
194
353
  * ```
195
354
  * # use zeck::memoized_zeckendorf_list_descending_for_integer;
196
355
  * // Base cases
197
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(0), vec![]);
198
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(1), vec![2]);
199
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(2), vec![3]);
356
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(0), vec![] as Vec<u64>);
357
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(1), vec![2u64]);
358
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(2), vec![3u64]);
200
359
  *
201
360
  * // Small Zeckendorf numbers
202
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(3), vec![4]);
203
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(4), vec![4, 2]);
204
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(5), vec![5]);
205
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(6), vec![5, 2]);
206
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(7), vec![5, 3]);
207
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(8), vec![6]);
208
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(9), vec![6, 2]);
209
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(10), vec![6, 3]);
210
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(11), vec![6, 4]);
211
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(12), vec![6, 4, 2]);
361
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(3), vec![4u64]);
362
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(4), vec![4u64, 2u64]);
363
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(5), vec![5u64]);
364
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(6), vec![5u64, 2u64]);
365
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(7), vec![5u64, 3u64]);
366
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(8), vec![6u64]);
367
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(9), vec![6u64, 2u64]);
368
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(10), vec![6u64, 3u64]);
369
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(11), vec![6u64, 4u64]);
370
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(12), vec![6u64, 4u64, 2u64]);
212
371
  * ```
213
372
  */
214
373
  export function memoized_zeckendorf_list_descending_for_integer(n: bigint): BigUint64Array;
@@ -236,24 +395,20 @@ export function memoized_zeckendorf_list_descending_for_integer(n: bigint): BigU
236
395
  export function pack_ezba_bits_to_bytes(ezba: Uint8Array): Uint8Array;
237
396
 
238
397
  /**
239
- * Unpacks a vector of bytes into a vector of bits (0s and 1s) from an ezba (Effective Zeckendorf Bits Ascending).
398
+ * Compresses a slice of bytes using the Padless Zeckendorf Compression algorithm.
240
399
  *
241
- * # Examples
400
+ * Assumes the input data is interpreted as a big endian integer. The output data is in little endian order, so the first bit and byte is the least significant bit and byte and the last bit and byte is the most significant bit and byte.
242
401
  *
243
- * ```
244
- * # use zeck::unpack_bytes_to_ezba_bits;
245
- * assert_eq!(unpack_bytes_to_ezba_bits(&[0]), vec![0, 0, 0, 0, 0, 0, 0, 0]);
246
- * assert_eq!(unpack_bytes_to_ezba_bits(&[1]), vec![1, 0, 0, 0, 0, 0, 0, 0]);
247
- * assert_eq!(unpack_bytes_to_ezba_bits(&[0b111]), vec![1, 1, 1, 0, 0, 0, 0, 0]);
248
- * assert_eq!(unpack_bytes_to_ezba_bits(&[1, 1]), vec![1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]);
249
- * ```
250
- */
251
- export function unpack_bytes_to_ezba_bits(bytes: Uint8Array): Uint8Array;
252
-
253
- /**
254
- * Compresses a slice of bytes using the Zeckendorf algorithm.
402
+ * # ⚠️ Important: Original Size Preservation
255
403
  *
256
- * Assumes the input data is interpreted as a big endian integer. The output data is in little endian order, so the first bit and byte is the least significant bit and byte and the last bit and byte is the most significant bit and byte.
404
+ * **This function strips leading zero bytes from the input data during compression.**
405
+ * It is the caller's responsibility to retain the original size information (e.g., `data.len()`)
406
+ * before calling this function. When decompressing, the original size must be used to pad the
407
+ * decompressed data with leading zeros to restore the exact original data. Without the original
408
+ * size, information will be lost during decompression.
409
+ *
410
+ * For a format that automatically handles size preservation, use [`crate::zeck_file_format::compress::compress_zeck_be`]
411
+ * instead, which includes a header with the original size information.
257
412
  *
258
413
  * # ⚠️ Warning
259
414
  *
@@ -265,23 +420,34 @@ export function unpack_bytes_to_ezba_bits(bytes: Uint8Array): Uint8Array;
265
420
  * # Examples
266
421
  *
267
422
  * ```
268
- * # use zeck::zeckendorf_compress_be_broken_do_not_use;
269
- * assert_eq!(zeckendorf_compress_be_broken_do_not_use(&[0]), vec![0]);
270
- * assert_eq!(zeckendorf_compress_be_broken_do_not_use(&[1]), vec![1]);
271
- * assert_eq!(zeckendorf_compress_be_broken_do_not_use(&[12]), vec![0b111]);
272
- * assert_eq!(zeckendorf_compress_be_broken_do_not_use(&[54]), vec![30]);
273
- * assert_eq!(zeckendorf_compress_be_broken_do_not_use(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
274
- * assert_eq!(zeckendorf_compress_be_broken_do_not_use(&[255]), vec![33, 2]);
275
- * assert_eq!(zeckendorf_compress_be_broken_do_not_use(&[1, 0]), vec![34, 2]);
423
+ * # use zeck::padless_zeckendorf_compress_be_dangerous;
424
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[0]), vec![0]);
425
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[1]), vec![1]);
426
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[12]), vec![0b111]);
427
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[54]), vec![30]);
428
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
429
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[255]), vec![33, 2]);
430
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[1, 0]), vec![34, 2]);
276
431
  * ```
277
432
  */
278
- export function zeckendorf_compress_be_broken_do_not_use(data: Uint8Array): Uint8Array;
433
+ export function padless_zeckendorf_compress_be_dangerous(data: Uint8Array): Uint8Array;
279
434
 
280
435
  /**
281
- * Compresses a slice of bytes using the Zeckendorf algorithm.
436
+ * Compresses a slice of bytes using the Padless Zeckendorf Compression algorithm.
282
437
  *
283
438
  * Assumes the input data is interpreted as a little endian integer. The output data is in little endian order, so the first bit and byte is the least significant bit and byte and the last bit and byte is the most significant bit and byte.
284
439
  *
440
+ * # ⚠️ Important: Original Size Preservation
441
+ *
442
+ * **This function strips leading zero bytes from the input data during compression.**
443
+ * It is the caller's responsibility to retain the original size information (e.g., `data.len()`)
444
+ * before calling this function. When decompressing, the original size must be used to pad the
445
+ * decompressed data with leading zeros to restore the exact original data. Without the original
446
+ * size, information will be lost during decompression.
447
+ *
448
+ * For a format that automatically handles size preservation, use [`crate::zeck_file_format::compress::compress_zeck_le`]
449
+ * instead, which includes a header with the original size information.
450
+ *
285
451
  * # ⚠️ Warning
286
452
  *
287
453
  * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
@@ -290,22 +456,30 @@ export function zeckendorf_compress_be_broken_do_not_use(data: Uint8Array): Uint
290
456
  * # Examples
291
457
  *
292
458
  * ```
293
- * # use zeck::zeckendorf_compress_le_broken_do_not_use;
294
- * assert_eq!(zeckendorf_compress_le_broken_do_not_use(&[0]), vec![0]);
295
- * assert_eq!(zeckendorf_compress_le_broken_do_not_use(&[1]), vec![1]);
296
- * assert_eq!(zeckendorf_compress_le_broken_do_not_use(&[12]), vec![0b111]);
297
- * assert_eq!(zeckendorf_compress_le_broken_do_not_use(&[54]), vec![30]);
298
- * assert_eq!(zeckendorf_compress_le_broken_do_not_use(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
299
- * assert_eq!(zeckendorf_compress_le_broken_do_not_use(&[255]), vec![33, 2]);
300
- * assert_eq!(zeckendorf_compress_le_broken_do_not_use(&[0, 1]), vec![34, 2]);
459
+ * # use zeck::padless_zeckendorf_compress_le_dangerous;
460
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[0]), vec![0]);
461
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[1]), vec![1]);
462
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[12]), vec![0b111]);
463
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[54]), vec![30]);
464
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
465
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[255]), vec![33, 2]);
466
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[0, 1]), vec![34, 2]);
301
467
  * ```
302
468
  */
303
- export function zeckendorf_compress_le_broken_do_not_use(data: Uint8Array): Uint8Array;
469
+ export function padless_zeckendorf_compress_le_dangerous(data: Uint8Array): Uint8Array;
304
470
 
305
471
  /**
306
472
  * Decompresses a slice of bytes compressed using the Zeckendorf algorithm, assuming the original data was compressed using the big endian bytes interpretation.
307
473
  *
308
- * Assume the original input data was interpreted as a big endian integer, for now. See the TODO in the [`zeckendorf_compress_be`] function for more information.
474
+ * Assume the original input data was interpreted as a big endian integer, for now. See the TODO in the [`padless_zeckendorf_compress_be_dangerous`] function for more information.
475
+ *
476
+ * # ⚠️ Important: Leading Zero Padding
477
+ *
478
+ * **This function does not pad leading zero bytes.** If the original data had leading zeros, they will not be restored.
479
+ * The decompressed output will be the minimal representation of the number (without leading zeros).
480
+ *
481
+ * For a format that automatically handles size preservation and padding, use [`crate::zeck_file_format::file::deserialize_zeck_file`]
482
+ * and [`crate::zeck_file_format::decompress::decompress_zeck_file`] instead, which includes a header with the original size information and restores leading zeros.
309
483
  *
310
484
  * # ⚠️ Warning
311
485
  *
@@ -315,19 +489,27 @@ export function zeckendorf_compress_le_broken_do_not_use(data: Uint8Array): Uint
315
489
  * # Examples
316
490
  *
317
491
  * ```
318
- * # use zeck::zeckendorf_decompress_be_broken_do_not_use;
319
- * assert_eq!(zeckendorf_decompress_be_broken_do_not_use(&[0]), vec![0]);
320
- * assert_eq!(zeckendorf_decompress_be_broken_do_not_use(&[1]), vec![1]);
321
- * assert_eq!(zeckendorf_decompress_be_broken_do_not_use(&[0b111]), vec![12]);
322
- * assert_eq!(zeckendorf_decompress_be_broken_do_not_use(&[33, 2]), vec![255]);
323
- * assert_eq!(zeckendorf_decompress_be_broken_do_not_use(&[34, 2]), vec![1, 0]);
492
+ * # use zeck::padless_zeckendorf_decompress_be_dangerous;
493
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[0]), vec![0]);
494
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[1]), vec![1]);
495
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[0b111]), vec![12]);
496
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[33, 2]), vec![255]);
497
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[34, 2]), vec![1, 0]);
324
498
  * ```
325
499
  */
326
- export function zeckendorf_decompress_be_broken_do_not_use(compressed_data: Uint8Array): Uint8Array;
500
+ export function padless_zeckendorf_decompress_be_dangerous(compressed_data: Uint8Array): Uint8Array;
327
501
 
328
502
  /**
329
503
  * Decompresses a slice of bytes compressed using the Zeckendorf algorithm, assuming the original data was compressed using the little endian bytes interpretation.
330
504
  *
505
+ * # ⚠️ Important: Leading Zero Padding
506
+ *
507
+ * **This function does not pad leading zero bytes.** If the original data had leading zeros, they will not be restored.
508
+ * The decompressed output will be the minimal representation of the number (without leading zeros).
509
+ *
510
+ * For a format that automatically handles size preservation and padding, use [`crate::zeck_file_format::file::deserialize_zeck_file`]
511
+ * and [`crate::zeck_file_format::decompress::decompress_zeck_file`] instead, which includes a header with the original size information and restores leading zeros.
512
+ *
331
513
  * # ⚠️ Warning
332
514
  *
333
515
  * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
@@ -336,15 +518,30 @@ export function zeckendorf_decompress_be_broken_do_not_use(compressed_data: Uint
336
518
  * # Examples
337
519
  *
338
520
  * ```
339
- * # use zeck::zeckendorf_decompress_le_broken_do_not_use;
340
- * assert_eq!(zeckendorf_decompress_le_broken_do_not_use(&[0]), vec![0]);
341
- * assert_eq!(zeckendorf_decompress_le_broken_do_not_use(&[1]), vec![1]);
342
- * assert_eq!(zeckendorf_decompress_le_broken_do_not_use(&[0b111]), vec![12]);
343
- * assert_eq!(zeckendorf_decompress_le_broken_do_not_use(&[33, 2]), vec![255]);
344
- * assert_eq!(zeckendorf_decompress_le_broken_do_not_use(&[34, 2]), vec![0, 1]);
521
+ * # use zeck::padless_zeckendorf_decompress_le_dangerous;
522
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[0]), vec![0]);
523
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[1]), vec![1]);
524
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[0b111]), vec![12]);
525
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[33, 2]), vec![255]);
526
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[34, 2]), vec![0, 1]);
527
+ * ```
528
+ */
529
+ export function padless_zeckendorf_decompress_le_dangerous(compressed_data: Uint8Array): Uint8Array;
530
+
531
+ /**
532
+ * Unpacks a vector of bytes into a vector of bits (0s and 1s) from an ezba (Effective Zeckendorf Bits Ascending).
533
+ *
534
+ * # Examples
535
+ *
536
+ * ```
537
+ * # use zeck::unpack_bytes_to_ezba_bits;
538
+ * assert_eq!(unpack_bytes_to_ezba_bits(&[0]), vec![0, 0, 0, 0, 0, 0, 0, 0]);
539
+ * assert_eq!(unpack_bytes_to_ezba_bits(&[1]), vec![1, 0, 0, 0, 0, 0, 0, 0]);
540
+ * assert_eq!(unpack_bytes_to_ezba_bits(&[0b111]), vec![1, 1, 1, 0, 0, 0, 0, 0]);
541
+ * assert_eq!(unpack_bytes_to_ezba_bits(&[1, 1]), vec![1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]);
345
542
  * ```
346
543
  */
347
- export function zeckendorf_decompress_le_broken_do_not_use(compressed_data: Uint8Array): Uint8Array;
544
+ export function unpack_bytes_to_ezba_bits(bytes: Uint8Array): Uint8Array;
348
545
 
349
546
  /**
350
547
  * An Effective Zeckendorf List (EZL) has a lowest EFI of 0, which is an FI of 2.
package/zeck_bg.js CHANGED
@@ -3,6 +3,12 @@ export function __wbg_set_wasm(val) {
3
3
  wasm = val;
4
4
  }
5
5
 
6
+ function addToExternrefTable0(obj) {
7
+ const idx = wasm.__externref_table_alloc();
8
+ wasm.__wbindgen_externrefs.set(idx, obj);
9
+ return idx;
10
+ }
11
+
6
12
  function getArrayU64FromWasm0(ptr, len) {
7
13
  ptr = ptr >>> 0;
8
14
  return getBigUint64ArrayMemory0().subarray(ptr / 8, ptr / 8 + len);
@@ -21,6 +27,11 @@ function getBigUint64ArrayMemory0() {
21
27
  return cachedBigUint64ArrayMemory0;
22
28
  }
23
29
 
30
+ function getStringFromWasm0(ptr, len) {
31
+ ptr = ptr >>> 0;
32
+ return decodeText(ptr, len);
33
+ }
34
+
24
35
  let cachedUint8ArrayMemory0 = null;
25
36
  function getUint8ArrayMemory0() {
26
37
  if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
@@ -29,6 +40,15 @@ function getUint8ArrayMemory0() {
29
40
  return cachedUint8ArrayMemory0;
30
41
  }
31
42
 
43
+ function handleError(f, args) {
44
+ try {
45
+ return f.apply(this, args);
46
+ } catch (e) {
47
+ const idx = addToExternrefTable0(e);
48
+ wasm.__wbindgen_exn_store(idx);
49
+ }
50
+ }
51
+
32
52
  function passArray64ToWasm0(arg, malloc) {
33
53
  const ptr = malloc(arg.length * 8, 8) >>> 0;
34
54
  getBigUint64ArrayMemory0().set(arg, ptr / 8);
@@ -43,6 +63,26 @@ function passArray8ToWasm0(arg, malloc) {
43
63
  return ptr;
44
64
  }
45
65
 
66
+ function takeFromExternrefTable0(idx) {
67
+ const value = wasm.__wbindgen_externrefs.get(idx);
68
+ wasm.__externref_table_dealloc(idx);
69
+ return value;
70
+ }
71
+
72
+ let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
73
+ cachedTextDecoder.decode();
74
+ const MAX_SAFARI_DECODE_BYTES = 2146435072;
75
+ let numBytesDecoded = 0;
76
+ function decodeText(ptr, len) {
77
+ numBytesDecoded += len;
78
+ if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
79
+ cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
80
+ cachedTextDecoder.decode();
81
+ numBytesDecoded = len;
82
+ }
83
+ return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
84
+ }
85
+
46
86
  let WASM_VECTOR_LEN = 0;
47
87
 
48
88
  /**
@@ -66,6 +106,159 @@ export function bit_count_for_number(n) {
66
106
  return ret >>> 0;
67
107
  }
68
108
 
109
+ /**
110
+ * Compresses data using the Zeckendorf algorithm with big endian interpretation,
111
+ * and stores the result in a [`ZeckFile`] struct.
112
+ *
113
+ * # ⚠️ Warning
114
+ *
115
+ * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
116
+ * The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
117
+ *
118
+ * # Examples
119
+ *
120
+ * ```
121
+ * # use zeck::zeck_file_format::compress::compress_zeck_be;
122
+ * let data = vec![1, 0];
123
+ * match compress_zeck_be(&data) {
124
+ * Ok(zeck_file) => {
125
+ * // Access file information
126
+ * println!("Original size: {} bytes", zeck_file.original_size);
127
+ * println!("Is big endian: {}", zeck_file.is_big_endian());
128
+ * // Serialize to bytes for writing to file
129
+ * let bytes = zeck_file.to_bytes();
130
+ * }
131
+ * Err(e) => {
132
+ * // Handle error (e.g., data size too large)
133
+ * }
134
+ * }
135
+ * ```
136
+ * @param {Uint8Array} data
137
+ * @returns {ZeckFile}
138
+ */
139
+ export function compress_zeck_be(data) {
140
+ const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
141
+ const len0 = WASM_VECTOR_LEN;
142
+ const ret = wasm.compress_zeck_be(ptr0, len0);
143
+ if (ret[2]) {
144
+ throw takeFromExternrefTable0(ret[1]);
145
+ }
146
+ return takeFromExternrefTable0(ret[0]);
147
+ }
148
+
149
+ /**
150
+ * Compresses data using the Zeckendorf algorithm with automatic endianness selection,
151
+ * and stores the result in a [`BestCompressionResult`] struct.
152
+ *
153
+ * This function attempts compression with both big endian and little endian interpretations,
154
+ * and returns the best result, or if neither produced compression (both were larger than the original).
155
+ *
156
+ * # ⚠️ Warning
157
+ *
158
+ * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
159
+ * The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
160
+ *
161
+ * # Examples
162
+ *
163
+ * ```
164
+ * # use zeck::zeck_file_format::compress::compress_zeck_best;
165
+ * # use zeck::zeck_file_format::compress::BestCompressionResult;
166
+ * # use zeck::zeck_file_format::decompress::decompress_zeck_file;
167
+ * let data = vec![0, 1]; // Compresses best interpreted as a big endian integer
168
+ * match compress_zeck_best(&data) {
169
+ * Ok(best_compression_result) => {
170
+ * match best_compression_result {
171
+ * BestCompressionResult::BigEndianBest { zeck_file, le_size } => {
172
+ * let decompressed = decompress_zeck_file(&zeck_file).unwrap();
173
+ * assert_eq!(decompressed, data);
174
+ * }
175
+ * BestCompressionResult::LittleEndianBest { zeck_file, be_size } => {
176
+ * assert!(false);
177
+ * }
178
+ * BestCompressionResult::Neither { be_size, le_size } => {
179
+ * assert!(false);
180
+ * }
181
+ * }
182
+ * }
183
+ * Err(e) => {
184
+ * assert!(false);
185
+ * }
186
+ * }
187
+ *
188
+ * let data = vec![1, 0]; // Compresses best interpreted as a little endian integer
189
+ * match compress_zeck_best(&data) {
190
+ * Ok(best_compression_result) => {
191
+ * match best_compression_result {
192
+ * BestCompressionResult::BigEndianBest { zeck_file, le_size } => {
193
+ * assert!(false);
194
+ * }
195
+ * BestCompressionResult::LittleEndianBest { zeck_file, be_size } => {
196
+ * let decompressed = decompress_zeck_file(&zeck_file).unwrap();
197
+ * assert_eq!(decompressed, data);
198
+ * }
199
+ * BestCompressionResult::Neither { be_size, le_size } => {
200
+ * assert!(false);
201
+ * }
202
+ * }
203
+ * }
204
+ * Err(e) => {
205
+ * assert!(false);
206
+ * }
207
+ * }
208
+ * ```
209
+ * @param {Uint8Array} data
210
+ * @returns {BestCompressionResult}
211
+ */
212
+ export function compress_zeck_best(data) {
213
+ const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
214
+ const len0 = WASM_VECTOR_LEN;
215
+ const ret = wasm.compress_zeck_best(ptr0, len0);
216
+ if (ret[2]) {
217
+ throw takeFromExternrefTable0(ret[1]);
218
+ }
219
+ return takeFromExternrefTable0(ret[0]);
220
+ }
221
+
222
+ /**
223
+ * Compresses data using the Zeckendorf algorithm with little endian interpretation,
224
+ * and stores the result in a [`ZeckFile`] struct.
225
+ *
226
+ * # ⚠️ Warning
227
+ *
228
+ * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
229
+ * The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
230
+ *
231
+ * # Examples
232
+ *
233
+ * ```
234
+ * # use zeck::zeck_file_format::compress::compress_zeck_le;
235
+ * let data = vec![1, 0];
236
+ * match compress_zeck_le(&data) {
237
+ * Ok(zeck_file) => {
238
+ * // Access file information
239
+ * println!("Original size: {} bytes", zeck_file.original_size);
240
+ * println!("Compressed size: {} bytes", zeck_file.compressed_data.len());
241
+ * // Serialize to bytes for writing to file
242
+ * let bytes = zeck_file.to_bytes();
243
+ * }
244
+ * Err(e) => {
245
+ * // Handle error (e.g., data size too large)
246
+ * }
247
+ * }
248
+ * ```
249
+ * @param {Uint8Array} data
250
+ * @returns {ZeckFile}
251
+ */
252
+ export function compress_zeck_le(data) {
253
+ const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
254
+ const len0 = WASM_VECTOR_LEN;
255
+ const ret = wasm.compress_zeck_le(ptr0, len0);
256
+ if (ret[2]) {
257
+ throw takeFromExternrefTable0(ret[1]);
258
+ }
259
+ return takeFromExternrefTable0(ret[0]);
260
+ }
261
+
69
262
  /**
70
263
  * Effective Fibonacci Index to Fibonacci Index: FI(efi) === efi + 2, where efi is the Effective Fibonacci Index
71
264
  *
@@ -127,9 +320,9 @@ export function ezba_from_ezld(effective_zeckendorf_list_descending) {
127
320
  *
128
321
  * ```
129
322
  * # use zeck::ezba_to_ezla;
130
- * assert_eq!(ezba_to_ezla(&[0, 0, 0, 0, 0, 0, 0, 0]), vec![]);
131
- * assert_eq!(ezba_to_ezla(&[1, 0, 0, 0, 0, 0, 0, 0]), vec![0]);
132
- * assert_eq!(ezba_to_ezla(&[1, 1, 1, 0, 0, 0, 0, 0]), vec![0, 2, 4]);
323
+ * assert_eq!(ezba_to_ezla(&[0, 0, 0, 0, 0, 0, 0, 0]), vec![] as Vec<u64>);
324
+ * assert_eq!(ezba_to_ezla(&[1, 0, 0, 0, 0, 0, 0, 0]), vec![0u64]);
325
+ * assert_eq!(ezba_to_ezla(&[1, 1, 1, 0, 0, 0, 0, 0]), vec![0u64, 2u64, 4u64]);
133
326
  * ```
134
327
  * @param {Uint8Array} ezba_bits
135
328
  * @returns {BigUint64Array}
@@ -295,21 +488,21 @@ export function memoized_slow_fibonacci_recursive(fi) {
295
488
  * ```
296
489
  * # use zeck::memoized_zeckendorf_list_descending_for_integer;
297
490
  * // Base cases
298
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(0), vec![]);
299
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(1), vec![2]);
300
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(2), vec![3]);
491
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(0), vec![] as Vec<u64>);
492
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(1), vec![2u64]);
493
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(2), vec![3u64]);
301
494
  *
302
495
  * // Small Zeckendorf numbers
303
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(3), vec![4]);
304
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(4), vec![4, 2]);
305
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(5), vec![5]);
306
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(6), vec![5, 2]);
307
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(7), vec![5, 3]);
308
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(8), vec![6]);
309
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(9), vec![6, 2]);
310
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(10), vec![6, 3]);
311
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(11), vec![6, 4]);
312
- * assert_eq!(memoized_zeckendorf_list_descending_for_integer(12), vec![6, 4, 2]);
496
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(3), vec![4u64]);
497
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(4), vec![4u64, 2u64]);
498
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(5), vec![5u64]);
499
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(6), vec![5u64, 2u64]);
500
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(7), vec![5u64, 3u64]);
501
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(8), vec![6u64]);
502
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(9), vec![6u64, 2u64]);
503
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(10), vec![6u64, 3u64]);
504
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(11), vec![6u64, 4u64]);
505
+ * assert_eq!(memoized_zeckendorf_list_descending_for_integer(12), vec![6u64, 4u64, 2u64]);
313
506
  * ```
314
507
  * @param {bigint} n
315
508
  * @returns {BigUint64Array}
@@ -353,33 +546,20 @@ export function pack_ezba_bits_to_bytes(ezba) {
353
546
  }
354
547
 
355
548
  /**
356
- * Unpacks a vector of bytes into a vector of bits (0s and 1s) from an ezba (Effective Zeckendorf Bits Ascending).
549
+ * Compresses a slice of bytes using the Padless Zeckendorf Compression algorithm.
357
550
  *
358
- * # Examples
551
+ * Assumes the input data is interpreted as a big endian integer. The output data is in little endian order, so the first bit and byte is the least significant bit and byte and the last bit and byte is the most significant bit and byte.
359
552
  *
360
- * ```
361
- * # use zeck::unpack_bytes_to_ezba_bits;
362
- * assert_eq!(unpack_bytes_to_ezba_bits(&[0]), vec![0, 0, 0, 0, 0, 0, 0, 0]);
363
- * assert_eq!(unpack_bytes_to_ezba_bits(&[1]), vec![1, 0, 0, 0, 0, 0, 0, 0]);
364
- * assert_eq!(unpack_bytes_to_ezba_bits(&[0b111]), vec![1, 1, 1, 0, 0, 0, 0, 0]);
365
- * assert_eq!(unpack_bytes_to_ezba_bits(&[1, 1]), vec![1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]);
366
- * ```
367
- * @param {Uint8Array} bytes
368
- * @returns {Uint8Array}
369
- */
370
- export function unpack_bytes_to_ezba_bits(bytes) {
371
- const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);
372
- const len0 = WASM_VECTOR_LEN;
373
- const ret = wasm.unpack_bytes_to_ezba_bits(ptr0, len0);
374
- var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
375
- wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
376
- return v2;
377
- }
378
-
379
- /**
380
- * Compresses a slice of bytes using the Zeckendorf algorithm.
553
+ * # ⚠️ Important: Original Size Preservation
381
554
  *
382
- * Assumes the input data is interpreted as a big endian integer. The output data is in little endian order, so the first bit and byte is the least significant bit and byte and the last bit and byte is the most significant bit and byte.
555
+ * **This function strips leading zero bytes from the input data during compression.**
556
+ * It is the caller's responsibility to retain the original size information (e.g., `data.len()`)
557
+ * before calling this function. When decompressing, the original size must be used to pad the
558
+ * decompressed data with leading zeros to restore the exact original data. Without the original
559
+ * size, information will be lost during decompression.
560
+ *
561
+ * For a format that automatically handles size preservation, use [`crate::zeck_file_format::compress::compress_zeck_be`]
562
+ * instead, which includes a header with the original size information.
383
563
  *
384
564
  * # ⚠️ Warning
385
565
  *
@@ -391,32 +571,43 @@ export function unpack_bytes_to_ezba_bits(bytes) {
391
571
  * # Examples
392
572
  *
393
573
  * ```
394
- * # use zeck::zeckendorf_compress_be_broken_do_not_use;
395
- * assert_eq!(zeckendorf_compress_be_broken_do_not_use(&[0]), vec![0]);
396
- * assert_eq!(zeckendorf_compress_be_broken_do_not_use(&[1]), vec![1]);
397
- * assert_eq!(zeckendorf_compress_be_broken_do_not_use(&[12]), vec![0b111]);
398
- * assert_eq!(zeckendorf_compress_be_broken_do_not_use(&[54]), vec![30]);
399
- * assert_eq!(zeckendorf_compress_be_broken_do_not_use(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
400
- * assert_eq!(zeckendorf_compress_be_broken_do_not_use(&[255]), vec![33, 2]);
401
- * assert_eq!(zeckendorf_compress_be_broken_do_not_use(&[1, 0]), vec![34, 2]);
574
+ * # use zeck::padless_zeckendorf_compress_be_dangerous;
575
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[0]), vec![0]);
576
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[1]), vec![1]);
577
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[12]), vec![0b111]);
578
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[54]), vec![30]);
579
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
580
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[255]), vec![33, 2]);
581
+ * assert_eq!(padless_zeckendorf_compress_be_dangerous(&[1, 0]), vec![34, 2]);
402
582
  * ```
403
583
  * @param {Uint8Array} data
404
584
  * @returns {Uint8Array}
405
585
  */
406
- export function zeckendorf_compress_be_broken_do_not_use(data) {
586
+ export function padless_zeckendorf_compress_be_dangerous(data) {
407
587
  const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
408
588
  const len0 = WASM_VECTOR_LEN;
409
- const ret = wasm.zeckendorf_compress_be_broken_do_not_use(ptr0, len0);
589
+ const ret = wasm.padless_zeckendorf_compress_be_dangerous(ptr0, len0);
410
590
  var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
411
591
  wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
412
592
  return v2;
413
593
  }
414
594
 
415
595
  /**
416
- * Compresses a slice of bytes using the Zeckendorf algorithm.
596
+ * Compresses a slice of bytes using the Padless Zeckendorf Compression algorithm.
417
597
  *
418
598
  * Assumes the input data is interpreted as a little endian integer. The output data is in little endian order, so the first bit and byte is the least significant bit and byte and the last bit and byte is the most significant bit and byte.
419
599
  *
600
+ * # ⚠️ Important: Original Size Preservation
601
+ *
602
+ * **This function strips leading zero bytes from the input data during compression.**
603
+ * It is the caller's responsibility to retain the original size information (e.g., `data.len()`)
604
+ * before calling this function. When decompressing, the original size must be used to pad the
605
+ * decompressed data with leading zeros to restore the exact original data. Without the original
606
+ * size, information will be lost during decompression.
607
+ *
608
+ * For a format that automatically handles size preservation, use [`crate::zeck_file_format::compress::compress_zeck_le`]
609
+ * instead, which includes a header with the original size information.
610
+ *
420
611
  * # ⚠️ Warning
421
612
  *
422
613
  * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
@@ -425,22 +616,22 @@ export function zeckendorf_compress_be_broken_do_not_use(data) {
425
616
  * # Examples
426
617
  *
427
618
  * ```
428
- * # use zeck::zeckendorf_compress_le_broken_do_not_use;
429
- * assert_eq!(zeckendorf_compress_le_broken_do_not_use(&[0]), vec![0]);
430
- * assert_eq!(zeckendorf_compress_le_broken_do_not_use(&[1]), vec![1]);
431
- * assert_eq!(zeckendorf_compress_le_broken_do_not_use(&[12]), vec![0b111]);
432
- * assert_eq!(zeckendorf_compress_le_broken_do_not_use(&[54]), vec![30]);
433
- * assert_eq!(zeckendorf_compress_le_broken_do_not_use(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
434
- * assert_eq!(zeckendorf_compress_le_broken_do_not_use(&[255]), vec![33, 2]);
435
- * assert_eq!(zeckendorf_compress_le_broken_do_not_use(&[0, 1]), vec![34, 2]);
619
+ * # use zeck::padless_zeckendorf_compress_le_dangerous;
620
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[0]), vec![0]);
621
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[1]), vec![1]);
622
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[12]), vec![0b111]);
623
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[54]), vec![30]);
624
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
625
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[255]), vec![33, 2]);
626
+ * assert_eq!(padless_zeckendorf_compress_le_dangerous(&[0, 1]), vec![34, 2]);
436
627
  * ```
437
628
  * @param {Uint8Array} data
438
629
  * @returns {Uint8Array}
439
630
  */
440
- export function zeckendorf_compress_le_broken_do_not_use(data) {
631
+ export function padless_zeckendorf_compress_le_dangerous(data) {
441
632
  const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
442
633
  const len0 = WASM_VECTOR_LEN;
443
- const ret = wasm.zeckendorf_compress_le_broken_do_not_use(ptr0, len0);
634
+ const ret = wasm.padless_zeckendorf_compress_le_dangerous(ptr0, len0);
444
635
  var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
445
636
  wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
446
637
  return v2;
@@ -449,7 +640,15 @@ export function zeckendorf_compress_le_broken_do_not_use(data) {
449
640
  /**
450
641
  * Decompresses a slice of bytes compressed using the Zeckendorf algorithm, assuming the original data was compressed using the big endian bytes interpretation.
451
642
  *
452
- * Assume the original input data was interpreted as a big endian integer, for now. See the TODO in the [`zeckendorf_compress_be`] function for more information.
643
+ * Assume the original input data was interpreted as a big endian integer, for now. See the TODO in the [`padless_zeckendorf_compress_be_dangerous`] function for more information.
644
+ *
645
+ * # ⚠️ Important: Leading Zero Padding
646
+ *
647
+ * **This function does not pad leading zero bytes.** If the original data had leading zeros, they will not be restored.
648
+ * The decompressed output will be the minimal representation of the number (without leading zeros).
649
+ *
650
+ * For a format that automatically handles size preservation and padding, use [`crate::zeck_file_format::file::deserialize_zeck_file`]
651
+ * and [`crate::zeck_file_format::decompress::decompress_zeck_file`] instead, which includes a header with the original size information and restores leading zeros.
453
652
  *
454
653
  * # ⚠️ Warning
455
654
  *
@@ -459,20 +658,20 @@ export function zeckendorf_compress_le_broken_do_not_use(data) {
459
658
  * # Examples
460
659
  *
461
660
  * ```
462
- * # use zeck::zeckendorf_decompress_be_broken_do_not_use;
463
- * assert_eq!(zeckendorf_decompress_be_broken_do_not_use(&[0]), vec![0]);
464
- * assert_eq!(zeckendorf_decompress_be_broken_do_not_use(&[1]), vec![1]);
465
- * assert_eq!(zeckendorf_decompress_be_broken_do_not_use(&[0b111]), vec![12]);
466
- * assert_eq!(zeckendorf_decompress_be_broken_do_not_use(&[33, 2]), vec![255]);
467
- * assert_eq!(zeckendorf_decompress_be_broken_do_not_use(&[34, 2]), vec![1, 0]);
661
+ * # use zeck::padless_zeckendorf_decompress_be_dangerous;
662
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[0]), vec![0]);
663
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[1]), vec![1]);
664
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[0b111]), vec![12]);
665
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[33, 2]), vec![255]);
666
+ * assert_eq!(padless_zeckendorf_decompress_be_dangerous(&[34, 2]), vec![1, 0]);
468
667
  * ```
469
668
  * @param {Uint8Array} compressed_data
470
669
  * @returns {Uint8Array}
471
670
  */
472
- export function zeckendorf_decompress_be_broken_do_not_use(compressed_data) {
671
+ export function padless_zeckendorf_decompress_be_dangerous(compressed_data) {
473
672
  const ptr0 = passArray8ToWasm0(compressed_data, wasm.__wbindgen_malloc);
474
673
  const len0 = WASM_VECTOR_LEN;
475
- const ret = wasm.zeckendorf_decompress_be_broken_do_not_use(ptr0, len0);
674
+ const ret = wasm.padless_zeckendorf_decompress_be_dangerous(ptr0, len0);
476
675
  var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
477
676
  wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
478
677
  return v2;
@@ -481,6 +680,14 @@ export function zeckendorf_decompress_be_broken_do_not_use(compressed_data) {
481
680
  /**
482
681
  * Decompresses a slice of bytes compressed using the Zeckendorf algorithm, assuming the original data was compressed using the little endian bytes interpretation.
483
682
  *
683
+ * # ⚠️ Important: Leading Zero Padding
684
+ *
685
+ * **This function does not pad leading zero bytes.** If the original data had leading zeros, they will not be restored.
686
+ * The decompressed output will be the minimal representation of the number (without leading zeros).
687
+ *
688
+ * For a format that automatically handles size preservation and padding, use [`crate::zeck_file_format::file::deserialize_zeck_file`]
689
+ * and [`crate::zeck_file_format::decompress::decompress_zeck_file`] instead, which includes a header with the original size information and restores leading zeros.
690
+ *
484
691
  * # ⚠️ Warning
485
692
  *
486
693
  * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
@@ -489,20 +696,44 @@ export function zeckendorf_decompress_be_broken_do_not_use(compressed_data) {
489
696
  * # Examples
490
697
  *
491
698
  * ```
492
- * # use zeck::zeckendorf_decompress_le_broken_do_not_use;
493
- * assert_eq!(zeckendorf_decompress_le_broken_do_not_use(&[0]), vec![0]);
494
- * assert_eq!(zeckendorf_decompress_le_broken_do_not_use(&[1]), vec![1]);
495
- * assert_eq!(zeckendorf_decompress_le_broken_do_not_use(&[0b111]), vec![12]);
496
- * assert_eq!(zeckendorf_decompress_le_broken_do_not_use(&[33, 2]), vec![255]);
497
- * assert_eq!(zeckendorf_decompress_le_broken_do_not_use(&[34, 2]), vec![0, 1]);
699
+ * # use zeck::padless_zeckendorf_decompress_le_dangerous;
700
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[0]), vec![0]);
701
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[1]), vec![1]);
702
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[0b111]), vec![12]);
703
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[33, 2]), vec![255]);
704
+ * assert_eq!(padless_zeckendorf_decompress_le_dangerous(&[34, 2]), vec![0, 1]);
498
705
  * ```
499
706
  * @param {Uint8Array} compressed_data
500
707
  * @returns {Uint8Array}
501
708
  */
502
- export function zeckendorf_decompress_le_broken_do_not_use(compressed_data) {
709
+ export function padless_zeckendorf_decompress_le_dangerous(compressed_data) {
503
710
  const ptr0 = passArray8ToWasm0(compressed_data, wasm.__wbindgen_malloc);
504
711
  const len0 = WASM_VECTOR_LEN;
505
- const ret = wasm.zeckendorf_decompress_le_broken_do_not_use(ptr0, len0);
712
+ const ret = wasm.padless_zeckendorf_decompress_le_dangerous(ptr0, len0);
713
+ var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
714
+ wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
715
+ return v2;
716
+ }
717
+
718
+ /**
719
+ * Unpacks a vector of bytes into a vector of bits (0s and 1s) from an ezba (Effective Zeckendorf Bits Ascending).
720
+ *
721
+ * # Examples
722
+ *
723
+ * ```
724
+ * # use zeck::unpack_bytes_to_ezba_bits;
725
+ * assert_eq!(unpack_bytes_to_ezba_bits(&[0]), vec![0, 0, 0, 0, 0, 0, 0, 0]);
726
+ * assert_eq!(unpack_bytes_to_ezba_bits(&[1]), vec![1, 0, 0, 0, 0, 0, 0, 0]);
727
+ * assert_eq!(unpack_bytes_to_ezba_bits(&[0b111]), vec![1, 1, 1, 0, 0, 0, 0, 0]);
728
+ * assert_eq!(unpack_bytes_to_ezba_bits(&[1, 1]), vec![1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]);
729
+ * ```
730
+ * @param {Uint8Array} bytes
731
+ * @returns {Uint8Array}
732
+ */
733
+ export function unpack_bytes_to_ezba_bits(bytes) {
734
+ const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);
735
+ const len0 = WASM_VECTOR_LEN;
736
+ const ret = wasm.unpack_bytes_to_ezba_bits(ptr0, len0);
506
737
  var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
507
738
  wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
508
739
  return v2;
@@ -536,6 +767,15 @@ export function zl_to_ezl(zl) {
536
767
  return v2;
537
768
  }
538
769
 
770
+ export function __wbg___wbindgen_throw_dd24417ed36fc46e(arg0, arg1) {
771
+ throw new Error(getStringFromWasm0(arg0, arg1));
772
+ };
773
+
774
+ export function __wbg_parse_a09a54cf72639456() { return handleError(function (arg0, arg1) {
775
+ const ret = JSON.parse(getStringFromWasm0(arg0, arg1));
776
+ return ret;
777
+ }, arguments) };
778
+
539
779
  export function __wbindgen_init_externref_table() {
540
780
  const table = wasm.__wbindgen_externrefs;
541
781
  const offset = table.grow(4);
package/zeck_bg.wasm CHANGED
Binary file