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 +158 -28
- package/package.json +1 -1
- package/zeck.d.ts +82 -10
- package/zeck_bg.js +190 -0
- package/zeck_bg.wasm +0 -0
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 = "
|
|
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 = "
|
|
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": "^
|
|
93
|
+
"zeck": "^2.1.0"
|
|
91
94
|
}
|
|
92
95
|
}
|
|
93
96
|
```
|
|
94
97
|
|
|
95
98
|
## Usage
|
|
96
99
|
|
|
97
|
-
###
|
|
100
|
+
### File Format Compression (Recommended)
|
|
98
101
|
|
|
99
|
-
|
|
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::{
|
|
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
|
|
111
|
+
let zeck_file = compress_zeck_be(&data)?;
|
|
107
112
|
|
|
108
|
-
//
|
|
109
|
-
let
|
|
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
|
|
123
|
+
#### Little-Endian File Format
|
|
114
124
|
|
|
115
125
|
```rust
|
|
116
|
-
use zeck::{
|
|
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
|
|
130
|
+
let zeck_file = compress_zeck_le(&data)?;
|
|
121
131
|
|
|
122
132
|
// Decompress data
|
|
123
|
-
let decompressed =
|
|
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::{
|
|
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
|
-
|
|
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 =
|
|
150
|
+
let decompressed = decompress_zeck_file(&zeck_file)?;
|
|
140
151
|
assert_eq!(data, decompressed);
|
|
141
152
|
}
|
|
142
|
-
|
|
153
|
+
BestCompressionResult::LittleEndianBest { zeck_file, be_size } => {
|
|
143
154
|
// Little-endian produced the best compression
|
|
144
|
-
let decompressed =
|
|
155
|
+
let decompressed = decompress_zeck_file(&zeck_file)?;
|
|
145
156
|
assert_eq!(data, decompressed);
|
|
146
157
|
}
|
|
147
|
-
|
|
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::
|
|
164
|
-
let fib_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 `
|
|
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 `
|
|
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
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
|