zeck 2.1.0 → 2.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 CHANGED
@@ -13,17 +13,20 @@ The Zeckendorf algorithm represents numbers as a sum of non-consecutive Fibonacc
13
13
  ## Features
14
14
 
15
15
  - **Compression & Decompression**: Convert data to/from Zeckendorf representation
16
+ - **File Format with Headers**: `.zeck` file format that automatically preserves original file size and endianness information
16
17
  - **Multiple Endian Interpretations**: Support for both big-endian and little-endian input interpretations
17
18
  - **Automatic Best Compression**: Try both endian interpretations and automatically select the best result
18
19
  - **Multiple Fibonacci Algorithms**:
19
20
  - Slow recursive (memoized, for small numbers)
20
21
  - Slow iterative (memoized, for large numbers)
21
22
  - Fast Doubling (optimized, ~160x faster for large indices)
23
+ - Memoized Fast Doubling (with sparse HashMap caching for large, non-contiguous indices)
22
24
  - **BigInt Support**: Handle arbitrarily large numbers using `num-bigint`
23
25
  - **Memoization**: Thread-safe caching for improved performance
24
26
  - **Statistics & Visualization**: Generate compression statistics and plots
25
27
  - **Benchmarking**: Comprehensive performance benchmarks
26
28
  - **WebAssembly Support**: Available as a WebAssembly module for use in web browsers
29
+ - **Error Handling**: Comprehensive error types for file format operations
27
30
 
28
31
  ## WebAssembly
29
32
 
@@ -44,14 +47,14 @@ Or add this to your `Cargo.toml`:
44
47
 
45
48
  ```toml
46
49
  [dependencies]
47
- zeck = "0.1.0"
50
+ zeck = "2.1.0"
48
51
  ```
49
52
 
50
53
  For plotting features:
51
54
 
52
55
  ```toml
53
56
  [dependencies]
54
- zeck = { version = "0.1.0", features = ["plotting"] }
57
+ zeck = { version = "2.1.0", features = ["plotting"] }
55
58
  ```
56
59
 
57
60
  ### Install from GitHub (development version)
@@ -87,70 +90,130 @@ Or add this to your `package.json`:
87
90
  ```json
88
91
  {
89
92
  "dependencies": {
90
- "zeck": "^0.1.0"
93
+ "zeck": "^2.1.0"
91
94
  }
92
95
  }
93
96
  ```
94
97
 
95
98
  ## Usage
96
99
 
97
- ### Basic Compression/Decompression
100
+ ### File Format Compression (Recommended)
98
101
 
99
- #### Big-Endian Interpretation
102
+ The `.zeck` file format automatically handles size preservation and endianness information. This is the recommended approach for most use cases.
103
+
104
+ #### Big-Endian File Format
100
105
 
101
106
  ```rust
102
- use zeck::{zeckendorf_compress_be, zeckendorf_decompress_be};
107
+ use zeck::zeck_file_format::{compress::compress_zeck_be, decompress::decompress_zeck_file};
103
108
 
104
109
  // Compress data (interpreted as big-endian integer)
105
110
  let data = vec![12u8];
106
- let compressed = zeckendorf_compress_be(&data);
111
+ let zeck_file = compress_zeck_be(&data)?;
107
112
 
108
- // Decompress data
109
- let decompressed = zeckendorf_decompress_be(&compressed);
113
+ // Serialize to bytes for storage
114
+ let bytes = zeck_file.to_bytes();
115
+
116
+ // Later, deserialize and decompress
117
+ use zeck::zeck_file_format::file::deserialize_zeck_file;
118
+ let zeck_file = deserialize_zeck_file(&bytes)?;
119
+ let decompressed = decompress_zeck_file(&zeck_file)?;
110
120
  assert_eq!(data, decompressed);
111
121
  ```
112
122
 
113
- #### Little-Endian Interpretation
123
+ #### Little-Endian File Format
114
124
 
115
125
  ```rust
116
- use zeck::{zeckendorf_compress_le, zeckendorf_decompress_le};
126
+ use zeck::zeck_file_format::{compress::compress_zeck_le, decompress::decompress_zeck_file};
117
127
 
118
128
  // Compress data (interpreted as little-endian integer)
119
129
  let data = vec![12u8];
120
- let compressed = zeckendorf_compress_le(&data);
130
+ let zeck_file = compress_zeck_le(&data)?;
121
131
 
122
132
  // Decompress data
123
- let decompressed = zeckendorf_decompress_le(&compressed);
133
+ let decompressed = decompress_zeck_file(&zeck_file)?;
124
134
  assert_eq!(data, decompressed);
125
135
  ```
126
136
 
127
- #### Automatic Best Compression
137
+ #### Automatic Best Compression (File Format)
128
138
 
129
139
  ```rust
130
- use zeck::{zeckendorf_compress_best, zeckendorf_decompress_be, zeckendorf_decompress_le, CompressionResult};
140
+ use zeck::zeck_file_format::{
141
+ compress::{compress_zeck_best, BestCompressionResult},
142
+ decompress::decompress_zeck_file,
143
+ };
131
144
 
132
145
  // Try both endian interpretations and get the best result
133
146
  let data = vec![1, 0];
134
- let result = zeckendorf_compress_best(&data);
135
-
136
- match result {
137
- CompressionResult::BigEndianBest { compressed_data, le_size } => {
147
+ match compress_zeck_best(&data)? {
148
+ BestCompressionResult::BigEndianBest { zeck_file, le_size } => {
138
149
  // Big-endian produced the best compression
139
- let decompressed = zeckendorf_decompress_be(&compressed_data);
150
+ let decompressed = decompress_zeck_file(&zeck_file)?;
140
151
  assert_eq!(data, decompressed);
141
152
  }
142
- CompressionResult::LittleEndianBest { compressed_data, be_size } => {
153
+ BestCompressionResult::LittleEndianBest { zeck_file, be_size } => {
143
154
  // Little-endian produced the best compression
144
- let decompressed = zeckendorf_decompress_le(&compressed_data);
155
+ let decompressed = decompress_zeck_file(&zeck_file)?;
145
156
  assert_eq!(data, decompressed);
146
157
  }
147
- CompressionResult::Neither { be_size, le_size } => {
158
+ BestCompressionResult::Neither { be_size, le_size } => {
148
159
  // Neither method compressed the data (both were larger than original)
149
160
  println!("Neither method compressed: BE size = {}, LE size = {}", be_size, le_size);
150
161
  }
151
162
  }
152
163
  ```
153
164
 
165
+ ### Padless Compression (Advanced)
166
+
167
+ The padless compression functions strip leading zero bytes and do not preserve original size information. **You must manually track the original size** if you need to restore leading zeros. These functions are marked as `_dangerous` to indicate they require careful handling.
168
+
169
+ **⚠️ Important:** The padless functions are lower-level and do not preserve leading zero bytes. Use the file format functions above for most use cases.
170
+
171
+ #### Big-Endian Padless
172
+
173
+ ```rust
174
+ use zeck::{padless_zeckendorf_compress_be_dangerous, padless_zeckendorf_decompress_be_dangerous};
175
+
176
+ // Compress data (interpreted as big-endian integer)
177
+ let data = vec![12u8];
178
+ let compressed = padless_zeckendorf_compress_be_dangerous(&data);
179
+
180
+ // Decompress data (leading zeros may be lost)
181
+ let decompressed = padless_zeckendorf_decompress_be_dangerous(&compressed);
182
+ // Note: decompressed may not equal data if data had leading zeros
183
+ ```
184
+
185
+ #### Little-Endian Padless
186
+
187
+ ```rust
188
+ use zeck::{padless_zeckendorf_compress_le_dangerous, padless_zeckendorf_decompress_le_dangerous};
189
+
190
+ // Compress data (interpreted as little-endian integer)
191
+ let data = vec![12u8];
192
+ let compressed = padless_zeckendorf_compress_le_dangerous(&data);
193
+
194
+ // Decompress data (trailing zeros may be lost)
195
+ let decompressed = padless_zeckendorf_decompress_le_dangerous(&compressed);
196
+ ```
197
+
198
+ #### Automatic Best Padless Compression
199
+
200
+ ```rust
201
+ use zeck::{padless_zeckendorf_compress_best_dangerous, PadlessCompressionResult};
202
+
203
+ let data = vec![1, 0];
204
+ match padless_zeckendorf_compress_best_dangerous(&data) {
205
+ PadlessCompressionResult::BigEndianBest { compressed_data, le_size } => {
206
+ // Use padless_zeckendorf_decompress_be_dangerous for decompression
207
+ }
208
+ PadlessCompressionResult::LittleEndianBest { compressed_data, be_size } => {
209
+ // Use padless_zeckendorf_decompress_le_dangerous for decompression
210
+ }
211
+ PadlessCompressionResult::Neither { be_size, le_size } => {
212
+ // Neither method compressed the data
213
+ }
214
+ }
215
+ ```
216
+
154
217
  ### Fibonacci Numbers
155
218
 
156
219
  ```rust
@@ -160,8 +223,12 @@ use zeck::memoized_slow_fibonacci_recursive;
160
223
  let fib_10 = memoized_slow_fibonacci_recursive(10); // Returns 55
161
224
 
162
225
  // For larger numbers, use BigInt versions
163
- use zeck::fast_doubling_fibonacci_bigint;
164
- let fib_100 = fast_doubling_fibonacci_bigint(100);
226
+ use zeck::fast_doubling_fibonacci_biguint;
227
+ let fib_100 = fast_doubling_fibonacci_biguint(100);
228
+
229
+ // For even better performance with caching, use memoized fast doubling
230
+ use zeck::memoized_fast_doubling_fibonacci_biguint;
231
+ let fib_1000 = memoized_fast_doubling_fibonacci_biguint(1000);
165
232
  ```
166
233
 
167
234
  ### Zeckendorf Representation
@@ -172,8 +239,58 @@ use zeck::memoized_zeckendorf_list_descending_for_integer;
172
239
  // Get Zeckendorf representation as a list of Fibonacci indices
173
240
  let zld = memoized_zeckendorf_list_descending_for_integer(12);
174
241
  // Returns [6, 4, 2] meaning F(6) + F(4) + F(2) = 8 + 3 + 1 = 12
242
+
243
+ // For BigInt numbers
244
+ use zeck::memoized_zeckendorf_list_descending_for_biguint;
245
+ use num_bigint::BigUint;
246
+ let zld = memoized_zeckendorf_list_descending_for_biguint(&BigUint::from(12u64));
175
247
  ```
176
248
 
249
+ ### Utility Functions
250
+
251
+ The library provides various utility functions for working with Fibonacci numbers and Zeckendorf representations:
252
+
253
+ ```rust
254
+ use zeck::{
255
+ bit_count_for_number, // Count bits needed to represent a number
256
+ highest_one_bit, // Get the highest set bit
257
+ efi_to_fi, fi_to_efi, // Convert between Effective Fibonacci Index and Fibonacci Index
258
+ memoized_effective_fibonacci, // Get Fibonacci number from Effective Fibonacci Index
259
+ zl_to_ezl, ezl_to_zl, // Convert between Zeckendorf List and Effective Zeckendorf List
260
+ all_ones_zeckendorf_to_biguint, // Create "all ones" Zeckendorf numbers
261
+ PHI, PHI_SQUARED, // Golden ratio constants
262
+ };
263
+ ```
264
+
265
+ ### Error Handling
266
+
267
+ The file format functions return `Result` types with comprehensive error handling:
268
+
269
+ ```rust
270
+ use zeck::zeck_file_format::{compress::compress_zeck_be, error::ZeckFormatError};
271
+
272
+ match compress_zeck_be(&data) {
273
+ Ok(zeck_file) => {
274
+ // Compression succeeded
275
+ }
276
+ Err(ZeckFormatError::DataSizeTooLarge { size }) => {
277
+ // Data size exceeds u64::MAX
278
+ }
279
+ Err(e) => {
280
+ // Handle other errors
281
+ eprintln!("Compression error: {}", e);
282
+ }
283
+ }
284
+ ```
285
+
286
+ Common error types include:
287
+ - `HeaderTooShort`: Input data is too short to contain a valid header
288
+ - `UnsupportedVersion`: File format version is not supported
289
+ - `ReservedFlagsSet`: Reserved flags are set (indicating a newer format)
290
+ - `CompressionFailed`: Compression did not reduce the data size
291
+ - `DecompressedTooLarge`: Decompressed data is larger than expected
292
+ - `DataSizeTooLarge`: Data size exceeds the maximum representable size
293
+
177
294
  ## Binaries
178
295
 
179
296
  The project includes several utility binaries. The command-line compression tools (`zeck-compress` and `zeck-decompress`) can be installed globally via:
@@ -297,7 +414,7 @@ cat input.zbe | zeck-decompress --endian big
297
414
  ### Main Playground
298
415
 
299
416
  ```bash
300
- cargo run --release --bin zeck
417
+ cargo run --release --bin zeck-playground --features development_tools
301
418
  ```
302
419
 
303
420
  A playground/scratchpad for testing library functions.
@@ -373,6 +490,7 @@ cargo bench --bench zeckendorf_bench -- --baseline <name>
373
490
  ## Performance Characteristics
374
491
 
375
492
  - **Fast Doubling Fibonacci**: ~160x faster than iterative method for the 100,000th Fibonacci number
493
+ - **Memoized Fast Doubling**: Uses sparse HashMap caching for efficient memory usage with large, non-contiguous Fibonacci indices
376
494
  - **Memoization**: Thread-safe caching significantly improves repeated calculations. The trade-off is that the cache takes up memory.
377
495
  - **Compression Effectiveness**: Varies by input; compression ratios oscillate and become less favorable as input size increases
378
496
 
@@ -385,12 +503,23 @@ Every positive integer can be uniquely represented as a sum of non-consecutive F
385
503
 
386
504
  ### Compression Process
387
505
 
388
- 1. Input data is interpreted as either a big-endian or little-endian integer (you can choose, or use `zeckendorf_compress_best` to try both)
506
+ 1. Input data is interpreted as either a big-endian or little-endian integer (you can choose, or use `compress_zeck_best` to try both)
389
507
  2. The integer is converted to its Zeckendorf representation (list of Fibonacci indices)
390
508
  3. The representation is encoded as bits (use/skip bits)
391
509
  4. Bits are packed into bytes (little-endian output)
392
510
 
393
- The library provides functions to compress with either interpretation, or you can use `zeckendorf_compress_best` to automatically try both and select the one that produces the smallest output.
511
+ The library provides functions to compress with either interpretation, or you can use `compress_zeck_best` to automatically try both and select the one that produces the smallest output.
512
+
513
+ ### File Format
514
+
515
+ The `.zeck` file format includes a 10-byte header:
516
+ - **Version** (1 byte): File format version (currently 1)
517
+ - **Original Size** (8 bytes): Original uncompressed file size in bytes (little-endian)
518
+ - **Flags** (1 byte): Endianness and reserved flags
519
+ - Bit 0: Big endian flag (1 = big endian, 0 = little endian)
520
+ - Bits 1-7: Reserved for future use
521
+
522
+ The header is followed by the compressed data. This format automatically preserves the original file size, allowing proper restoration of leading or trailing zero bytes during decompression.
394
523
 
395
524
  ### Effective Fibonacci Indices
396
525
 
@@ -407,6 +536,7 @@ This avoids redundant Fibonacci numbers (F(0)=0 and F(1)=F(2)=1).
407
536
  - Compression effectiveness decreases as input size increases
408
537
  - The library supports both big-endian and little-endian interpretations, but other byte orderings or word boundaries are not currently explored
409
538
  - **⚠️ 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.
539
+ - Padless compression functions (`*_dangerous`) do not preserve leading/trailing zero bytes—use the file format functions for automatic size preservation
410
540
 
411
541
  ## NPM Versioning Quirk
412
542
 
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": "2.1.0",
8
+ "version": "2.1.1",
9
9
  "license": "MIT",
10
10
  "repository": {
11
11
  "type": "git",
package/zeck.d.ts CHANGED
@@ -1,11 +1,25 @@
1
1
  /* tslint:disable */
2
2
  /* eslint-disable */
3
+ /**
4
+ * 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).
5
+ */
6
+ export type BestCompressionResult = { BigEndianBest: { zeck_file: ZeckFile; le_size: number } } | { LittleEndianBest: { zeck_file: ZeckFile; be_size: number } } | { Neither: { be_size: number; le_size: number } };
7
+
8
+ /**
9
+ * Errors that can occur when parsing or processing .zeck files.
10
+ */
11
+ 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 } };
12
+
3
13
  /**
4
14
  * Represents a .zeck file with its header information and compressed data.
5
15
  *
6
16
  * This struct holds all the information needed to reconstruct a .zeck file,
7
17
  * including the format version, original file size, endianness flags, and
8
18
  * the compressed data itself.
19
+ *
20
+ * Using `derive(Serialize, Deserialize, Tsify)` and `tsify(into_wasm_abi, from_wasm_abi)` on the struct is necessary
21
+ * to allow the struct to be used in the WebAssembly module, namely because the `compressed_data` field is
22
+ * a [`Vec<u8>`], which needed [`Copy`], and the [`wasm_bindgen`] attribute was insufficient to achieve this.
9
23
  */
10
24
  export interface ZeckFile {
11
25
  /**
@@ -26,16 +40,6 @@ export interface ZeckFile {
26
40
  compressed_data: number[];
27
41
  }
28
42
 
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
-
39
43
 
40
44
  /**
41
45
  * Returns the number of bits required to represent the given number. Returns 0 if the number is less than or equal to 0.
@@ -176,6 +180,64 @@ export function compress_zeck_best(data: Uint8Array): BestCompressionResult;
176
180
  */
177
181
  export function compress_zeck_le(data: Uint8Array): ZeckFile;
178
182
 
183
+ /**
184
+ * Decompresses data from a [`ZeckFile`] struct.
185
+ *
186
+ * This function takes a [`ZeckFile`] directly and uses its header information to decompress
187
+ * the data. This is a convenience function that avoids the need to serialize and parse the
188
+ * file format when you already have a [`ZeckFile`] struct.
189
+ *
190
+ * # ⚠️ Warning
191
+ *
192
+ * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
193
+ * The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
194
+ *
195
+ * # Examples
196
+ *
197
+ * ```
198
+ * # use zeck::zeck_file_format::{compress::compress_zeck_le, decompress::decompress_zeck_file};
199
+ * let original = vec![0, 1];
200
+ * let zeck_file = compress_zeck_le(&original).unwrap();
201
+ * match decompress_zeck_file(&zeck_file) {
202
+ * Ok(decompressed) => {
203
+ * assert_eq!(decompressed, original);
204
+ * }
205
+ * Err(e) => {
206
+ * // Handle error
207
+ * assert!(false);
208
+ * }
209
+ * }
210
+ * ```
211
+ */
212
+ export function decompress_zeck_file(zeck_file: ZeckFile): Uint8Array;
213
+
214
+ /**
215
+ * Deserializes a .zeck file from raw bytes into a [`ZeckFile`] struct.
216
+ *
217
+ * This function reads the header to determine the file format version, original size, and endianness,
218
+ * and constructs a [`ZeckFile`] struct. To decompress the data, call [`crate::zeck_file_format::decompress::decompress_zeck_file`] on the result.
219
+ *
220
+ * # Examples
221
+ *
222
+ * ```
223
+ * # use zeck::zeck_file_format::{compress::compress_zeck_le, file::deserialize_zeck_file, decompress::decompress_zeck_file};
224
+ * let original = vec![0, 1];
225
+ * let zeck_file = compress_zeck_le(&original).unwrap();
226
+ * let zeck_file_bytes = zeck_file.to_bytes();
227
+ * match deserialize_zeck_file(&zeck_file_bytes) {
228
+ * Ok(zeck_file) => {
229
+ * let decompressed = decompress_zeck_file(&zeck_file).unwrap();
230
+ * assert_eq!(decompressed, original);
231
+ * }
232
+ * Err(e) => {
233
+ * // Handle error
234
+ * assert!(false);
235
+ * }
236
+ * }
237
+ * ```
238
+ */
239
+ export function deserialize_zeck_file(zeck_file_data: Uint8Array): ZeckFile;
240
+
179
241
  /**
180
242
  * Effective Fibonacci Index to Fibonacci Index: FI(efi) === efi + 2, where efi is the Effective Fibonacci Index
181
243
  *
@@ -543,6 +605,16 @@ export function padless_zeckendorf_decompress_le_dangerous(compressed_data: Uint
543
605
  */
544
606
  export function unpack_bytes_to_ezba_bits(bytes: Uint8Array): Uint8Array;
545
607
 
608
+ /**
609
+ * We need to make public standalone functions on ZeckFile because for some reason, the #[wasm_bindgen] attribute doesn't seem to work on the struct methods. Maybe using Tsify on ZeckFile is causing the issue.
610
+ * This is a workaround to allow the functions to be used in the WebAssembly module.
611
+ */
612
+ export function zeck_file_is_big_endian(zeck_file: ZeckFile): boolean;
613
+
614
+ export function zeck_file_to_bytes(zeck_file: ZeckFile): Uint8Array;
615
+
616
+ export function zeck_file_total_size(zeck_file: ZeckFile): number;
617
+
546
618
  /**
547
619
  * An Effective Zeckendorf List (EZL) has a lowest EFI of 0, which is an FI of 2.
548
620
  * This is because it doesn't make sense for the lists to contain FIs 0 or 1 because
package/zeck_bg.js CHANGED
@@ -27,6 +27,14 @@ function getBigUint64ArrayMemory0() {
27
27
  return cachedBigUint64ArrayMemory0;
28
28
  }
29
29
 
30
+ let cachedDataViewMemory0 = null;
31
+ function getDataViewMemory0() {
32
+ if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
33
+ cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
34
+ }
35
+ return cachedDataViewMemory0;
36
+ }
37
+
30
38
  function getStringFromWasm0(ptr, len) {
31
39
  ptr = ptr >>> 0;
32
40
  return decodeText(ptr, len);
@@ -49,6 +57,10 @@ function handleError(f, args) {
49
57
  }
50
58
  }
51
59
 
60
+ function isLikeNone(x) {
61
+ return x === undefined || x === null;
62
+ }
63
+
52
64
  function passArray64ToWasm0(arg, malloc) {
53
65
  const ptr = malloc(arg.length * 8, 8) >>> 0;
54
66
  getBigUint64ArrayMemory0().set(arg, ptr / 8);
@@ -63,6 +75,43 @@ function passArray8ToWasm0(arg, malloc) {
63
75
  return ptr;
64
76
  }
65
77
 
78
+ function passStringToWasm0(arg, malloc, realloc) {
79
+ if (realloc === undefined) {
80
+ const buf = cachedTextEncoder.encode(arg);
81
+ const ptr = malloc(buf.length, 1) >>> 0;
82
+ getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
83
+ WASM_VECTOR_LEN = buf.length;
84
+ return ptr;
85
+ }
86
+
87
+ let len = arg.length;
88
+ let ptr = malloc(len, 1) >>> 0;
89
+
90
+ const mem = getUint8ArrayMemory0();
91
+
92
+ let offset = 0;
93
+
94
+ for (; offset < len; offset++) {
95
+ const code = arg.charCodeAt(offset);
96
+ if (code > 0x7F) break;
97
+ mem[ptr + offset] = code;
98
+ }
99
+ if (offset !== len) {
100
+ if (offset !== 0) {
101
+ arg = arg.slice(offset);
102
+ }
103
+ ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
104
+ const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
105
+ const ret = cachedTextEncoder.encodeInto(arg, view);
106
+
107
+ offset += ret.written;
108
+ ptr = realloc(ptr, len, offset, 1) >>> 0;
109
+ }
110
+
111
+ WASM_VECTOR_LEN = offset;
112
+ return ptr;
113
+ }
114
+
66
115
  function takeFromExternrefTable0(idx) {
67
116
  const value = wasm.__wbindgen_externrefs.get(idx);
68
117
  wasm.__externref_table_dealloc(idx);
@@ -83,6 +132,19 @@ function decodeText(ptr, len) {
83
132
  return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
84
133
  }
85
134
 
135
+ const cachedTextEncoder = new TextEncoder();
136
+
137
+ if (!('encodeInto' in cachedTextEncoder)) {
138
+ cachedTextEncoder.encodeInto = function (arg, view) {
139
+ const buf = cachedTextEncoder.encode(arg);
140
+ view.set(buf);
141
+ return {
142
+ read: arg.length,
143
+ written: buf.length
144
+ };
145
+ }
146
+ }
147
+
86
148
  let WASM_VECTOR_LEN = 0;
87
149
 
88
150
  /**
@@ -259,6 +321,84 @@ export function compress_zeck_le(data) {
259
321
  return takeFromExternrefTable0(ret[0]);
260
322
  }
261
323
 
324
+ /**
325
+ * Decompresses data from a [`ZeckFile`] struct.
326
+ *
327
+ * This function takes a [`ZeckFile`] directly and uses its header information to decompress
328
+ * the data. This is a convenience function that avoids the need to serialize and parse the
329
+ * file format when you already have a [`ZeckFile`] struct.
330
+ *
331
+ * # ⚠️ Warning
332
+ *
333
+ * **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
334
+ * The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
335
+ *
336
+ * # Examples
337
+ *
338
+ * ```
339
+ * # use zeck::zeck_file_format::{compress::compress_zeck_le, decompress::decompress_zeck_file};
340
+ * let original = vec![0, 1];
341
+ * let zeck_file = compress_zeck_le(&original).unwrap();
342
+ * match decompress_zeck_file(&zeck_file) {
343
+ * Ok(decompressed) => {
344
+ * assert_eq!(decompressed, original);
345
+ * }
346
+ * Err(e) => {
347
+ * // Handle error
348
+ * assert!(false);
349
+ * }
350
+ * }
351
+ * ```
352
+ * @param {ZeckFile} zeck_file
353
+ * @returns {Uint8Array}
354
+ */
355
+ export function decompress_zeck_file(zeck_file) {
356
+ const ret = wasm.decompress_zeck_file(zeck_file);
357
+ if (ret[3]) {
358
+ throw takeFromExternrefTable0(ret[2]);
359
+ }
360
+ var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
361
+ wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
362
+ return v1;
363
+ }
364
+
365
+ /**
366
+ * Deserializes a .zeck file from raw bytes into a [`ZeckFile`] struct.
367
+ *
368
+ * This function reads the header to determine the file format version, original size, and endianness,
369
+ * and constructs a [`ZeckFile`] struct. To decompress the data, call [`crate::zeck_file_format::decompress::decompress_zeck_file`] on the result.
370
+ *
371
+ * # Examples
372
+ *
373
+ * ```
374
+ * # use zeck::zeck_file_format::{compress::compress_zeck_le, file::deserialize_zeck_file, decompress::decompress_zeck_file};
375
+ * let original = vec![0, 1];
376
+ * let zeck_file = compress_zeck_le(&original).unwrap();
377
+ * let zeck_file_bytes = zeck_file.to_bytes();
378
+ * match deserialize_zeck_file(&zeck_file_bytes) {
379
+ * Ok(zeck_file) => {
380
+ * let decompressed = decompress_zeck_file(&zeck_file).unwrap();
381
+ * assert_eq!(decompressed, original);
382
+ * }
383
+ * Err(e) => {
384
+ * // Handle error
385
+ * assert!(false);
386
+ * }
387
+ * }
388
+ * ```
389
+ * @param {Uint8Array} zeck_file_data
390
+ * @returns {ZeckFile}
391
+ */
392
+ export function deserialize_zeck_file(zeck_file_data) {
393
+ const ptr0 = passArray8ToWasm0(zeck_file_data, wasm.__wbindgen_malloc);
394
+ const len0 = WASM_VECTOR_LEN;
395
+ const ret = wasm.deserialize_zeck_file(ptr0, len0);
396
+ if (ret[2]) {
397
+ throw takeFromExternrefTable0(ret[1]);
398
+ }
399
+ return takeFromExternrefTable0(ret[0]);
400
+ }
401
+
262
402
  /**
263
403
  * Effective Fibonacci Index to Fibonacci Index: FI(efi) === efi + 2, where efi is the Effective Fibonacci Index
264
404
  *
@@ -739,6 +879,37 @@ export function unpack_bytes_to_ezba_bits(bytes) {
739
879
  return v2;
740
880
  }
741
881
 
882
+ /**
883
+ * We need to make public standalone functions on ZeckFile because for some reason, the #[wasm_bindgen] attribute doesn't seem to work on the struct methods. Maybe using Tsify on ZeckFile is causing the issue.
884
+ * This is a workaround to allow the functions to be used in the WebAssembly module.
885
+ * @param {ZeckFile} zeck_file
886
+ * @returns {boolean}
887
+ */
888
+ export function zeck_file_is_big_endian(zeck_file) {
889
+ const ret = wasm.zeck_file_is_big_endian(zeck_file);
890
+ return ret !== 0;
891
+ }
892
+
893
+ /**
894
+ * @param {ZeckFile} zeck_file
895
+ * @returns {Uint8Array}
896
+ */
897
+ export function zeck_file_to_bytes(zeck_file) {
898
+ const ret = wasm.zeck_file_to_bytes(zeck_file);
899
+ var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
900
+ wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
901
+ return v1;
902
+ }
903
+
904
+ /**
905
+ * @param {ZeckFile} zeck_file
906
+ * @returns {number}
907
+ */
908
+ export function zeck_file_total_size(zeck_file) {
909
+ const ret = wasm.zeck_file_total_size(zeck_file);
910
+ return ret >>> 0;
911
+ }
912
+
742
913
  /**
743
914
  * An Effective Zeckendorf List (EZL) has a lowest EFI of 0, which is an FI of 2.
744
915
  * This is because it doesn't make sense for the lists to contain FIs 0 or 1 because
@@ -767,6 +938,20 @@ export function zl_to_ezl(zl) {
767
938
  return v2;
768
939
  }
769
940
 
941
+ export function __wbg___wbindgen_is_undefined_f6b95eab589e0269(arg0) {
942
+ const ret = arg0 === undefined;
943
+ return ret;
944
+ };
945
+
946
+ export function __wbg___wbindgen_string_get_a2a31e16edf96e42(arg0, arg1) {
947
+ const obj = arg1;
948
+ const ret = typeof(obj) === 'string' ? obj : undefined;
949
+ var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
950
+ var len1 = WASM_VECTOR_LEN;
951
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
952
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
953
+ };
954
+
770
955
  export function __wbg___wbindgen_throw_dd24417ed36fc46e(arg0, arg1) {
771
956
  throw new Error(getStringFromWasm0(arg0, arg1));
772
957
  };
@@ -776,6 +961,11 @@ export function __wbg_parse_a09a54cf72639456() { return handleError(function (ar
776
961
  return ret;
777
962
  }, arguments) };
778
963
 
964
+ export function __wbg_stringify_655a6390e1f5eb6b() { return handleError(function (arg0) {
965
+ const ret = JSON.stringify(arg0);
966
+ return ret;
967
+ }, arguments) };
968
+
779
969
  export function __wbindgen_init_externref_table() {
780
970
  const table = wasm.__wbindgen_externrefs;
781
971
  const offset = table.grow(4);
package/zeck_bg.wasm CHANGED
Binary file