zstdify 1.0.1 → 1.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.
Files changed (92) hide show
  1. package/README.md +27 -2
  2. package/dist/compress.d.ts +5 -0
  3. package/dist/compress.js +13 -1
  4. package/dist/compress.js.map +1 -1
  5. package/dist/dictionary/generateDictionary.d.ts +59 -0
  6. package/dist/dictionary/generateDictionary.js +187 -0
  7. package/dist/dictionary/generateDictionary.js.map +1 -0
  8. package/dist/encode/frameWriter.d.ts +1 -1
  9. package/dist/encode/frameWriter.js +26 -1
  10. package/dist/encode/frameWriter.js.map +1 -1
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.js +1 -0
  13. package/dist/index.js.map +1 -1
  14. package/package.json +1 -1
  15. package/dist/barrelExports.test.d.ts +0 -1
  16. package/dist/barrelExports.test.js +0 -25
  17. package/dist/barrelExports.test.js.map +0 -1
  18. package/dist/bitstream/bitReader.test.d.ts +0 -1
  19. package/dist/bitstream/bitReader.test.js +0 -47
  20. package/dist/bitstream/bitReader.test.js.map +0 -1
  21. package/dist/bitstream/bitReaderReverse.test.d.ts +0 -1
  22. package/dist/bitstream/bitReaderReverse.test.js +0 -49
  23. package/dist/bitstream/bitReaderReverse.test.js.map +0 -1
  24. package/dist/bitstream/littleEndian.test.d.ts +0 -1
  25. package/dist/bitstream/littleEndian.test.js +0 -21
  26. package/dist/bitstream/littleEndian.test.js.map +0 -1
  27. package/dist/bitstream/varint.test.d.ts +0 -1
  28. package/dist/bitstream/varint.test.js +0 -25
  29. package/dist/bitstream/varint.test.js.map +0 -1
  30. package/dist/compress.test.d.ts +0 -1
  31. package/dist/compress.test.js +0 -39
  32. package/dist/compress.test.js.map +0 -1
  33. package/dist/decode/block.test.d.ts +0 -1
  34. package/dist/decode/block.test.js +0 -26
  35. package/dist/decode/block.test.js.map +0 -1
  36. package/dist/decode/decompressFrame.test.d.ts +0 -1
  37. package/dist/decode/decompressFrame.test.js +0 -95
  38. package/dist/decode/decompressFrame.test.js.map +0 -1
  39. package/dist/decode/literals.corruption.test.d.ts +0 -1
  40. package/dist/decode/literals.corruption.test.js +0 -68
  41. package/dist/decode/literals.corruption.test.js.map +0 -1
  42. package/dist/decode/literals.test.d.ts +0 -1
  43. package/dist/decode/literals.test.js +0 -68
  44. package/dist/decode/literals.test.js.map +0 -1
  45. package/dist/decode/reconstruct.test.d.ts +0 -1
  46. package/dist/decode/reconstruct.test.js +0 -42
  47. package/dist/decode/reconstruct.test.js.map +0 -1
  48. package/dist/decode/sequences.corruption.test.d.ts +0 -1
  49. package/dist/decode/sequences.corruption.test.js +0 -32
  50. package/dist/decode/sequences.corruption.test.js.map +0 -1
  51. package/dist/decode/sequences.level1.test.d.ts +0 -1
  52. package/dist/decode/sequences.level1.test.js +0 -35
  53. package/dist/decode/sequences.level1.test.js.map +0 -1
  54. package/dist/decode/sequences.modes.test.d.ts +0 -1
  55. package/dist/decode/sequences.modes.test.js +0 -56
  56. package/dist/decode/sequences.modes.test.js.map +0 -1
  57. package/dist/dictionary/decoderDictionary.test.d.ts +0 -1
  58. package/dist/dictionary/decoderDictionary.test.js +0 -87
  59. package/dist/dictionary/decoderDictionary.test.js.map +0 -1
  60. package/dist/encode/blockWriter.test.d.ts +0 -1
  61. package/dist/encode/blockWriter.test.js +0 -31
  62. package/dist/encode/blockWriter.test.js.map +0 -1
  63. package/dist/encode/compressedBlock.test.d.ts +0 -1
  64. package/dist/encode/compressedBlock.test.js +0 -63
  65. package/dist/encode/compressedBlock.test.js.map +0 -1
  66. package/dist/encode/frameWriter.test.d.ts +0 -1
  67. package/dist/encode/frameWriter.test.js +0 -38
  68. package/dist/encode/frameWriter.test.js.map +0 -1
  69. package/dist/encode/greedySequences.test.d.ts +0 -1
  70. package/dist/encode/greedySequences.test.js +0 -33
  71. package/dist/encode/greedySequences.test.js.map +0 -1
  72. package/dist/entropy/fse.test.d.ts +0 -1
  73. package/dist/entropy/fse.test.js +0 -41
  74. package/dist/entropy/fse.test.js.map +0 -1
  75. package/dist/entropy/huffman.test.d.ts +0 -1
  76. package/dist/entropy/huffman.test.js +0 -22
  77. package/dist/entropy/huffman.test.js.map +0 -1
  78. package/dist/entropy/weights.test.d.ts +0 -1
  79. package/dist/entropy/weights.test.js +0 -38
  80. package/dist/entropy/weights.test.js.map +0 -1
  81. package/dist/errors.test.d.ts +0 -1
  82. package/dist/errors.test.js +0 -16
  83. package/dist/errors.test.js.map +0 -1
  84. package/dist/frame/checksum.test.d.ts +0 -1
  85. package/dist/frame/checksum.test.js +0 -28
  86. package/dist/frame/checksum.test.js.map +0 -1
  87. package/dist/frame/frameHeader.test.d.ts +0 -1
  88. package/dist/frame/frameHeader.test.js +0 -83
  89. package/dist/frame/frameHeader.test.js.map +0 -1
  90. package/dist/frame/skippable.test.d.ts +0 -1
  91. package/dist/frame/skippable.test.js +0 -35
  92. package/dist/frame/skippable.test.js.map +0 -1
package/README.md CHANGED
@@ -19,6 +19,10 @@ Pure JavaScript/TypeScript zstd compression/decompression library. No native dep
19
19
  - Raw blocks, RLE blocks, and compressed blocks.
20
20
  - Compression-level driven behavior with automatic raw fallback when compressed output is not smaller.
21
21
  - Optional frame content checksums.
22
+ - Optional dictionary-aware frame headers (`dictID`) for dictionary workflows.
23
+ - **Dictionary generation**:
24
+ - Pure TypeScript dictionary training from sample payloads.
25
+ - Zstd-inspired training options (`fastcover`/`cover`/`legacy` style knobs).
22
26
  - **Interop-focused**: `zstdify` output is decoded by the official `zstd` CLI, and `zstd` CLI output is decoded by `zstdify`.
23
27
  - **Extensively tested**:
24
28
  - Round-trip and property-based tests.
@@ -39,8 +43,29 @@ const restored = decompress(compressed);
39
43
 
40
44
  ## API
41
45
 
42
- - `compress(input: Uint8Array, options?: { level?: number; checksum?: boolean }): Uint8Array`
46
+ - `compress(input: Uint8Array, options?: { level?: number; checksum?: boolean; dictionary?: Uint8Array | { bytes: Uint8Array; id?: number }; noDictId?: boolean }): Uint8Array`
43
47
  - `decompress(input: Uint8Array, options?: { maxSize?: number; dictionary?: Uint8Array | { bytes: Uint8Array; id?: number } }): Uint8Array`
48
+ - `generateDictionary(samples: Uint8Array[], options?: { maxDictSize?: number; dictId?: number; algorithm?: "fastcover" | "cover" | "legacy"; k?: number; d?: number; steps?: number; split?: number; f?: number; accel?: number; selectivity?: number; shrink?: boolean | number }): Uint8Array`
49
+
50
+ Dictionary generation outputs a raw-content dictionary. If you want a specific `dictID` written into compressed frames, pass it to `compress()` via `dictionary: { bytes, id }`.
51
+
52
+ ### Dictionary workflow example
53
+
54
+ ```ts
55
+ import { compress, decompress, generateDictionary } from 'zstdify';
56
+
57
+ const encoder = new TextEncoder();
58
+ const samples = [
59
+ encoder.encode('alpha beta gamma delta'),
60
+ encoder.encode('header vertex texture normal index'),
61
+ encoder.encode('offset match literal sequence table'),
62
+ ];
63
+ const dictionary = generateDictionary(samples, { maxDictSize: 2048, algorithm: 'fastcover' });
64
+
65
+ const payload = encoder.encode('header vertex texture offset match literal');
66
+ const compressed = compress(payload, { dictionary: { bytes: dictionary, id: 42 } });
67
+ const restored = decompress(compressed, { dictionary: { bytes: dictionary, id: 42 } });
68
+ ```
44
69
 
45
70
  ## CLI Tool
46
71
 
@@ -72,7 +97,7 @@ All of the following run as part of the test suite (`pnpm test` / `pnpm vitest`)
72
97
 
73
98
  - **Round-trip**: `decompress(compress(x)) === x` for a variety of payloads and levels, plus property-based tests with [fast-check](https://fast-check.dev/).
74
99
  - **Conformance fixtures**: Pre-generated `.zst` files from the official zstd CLI (legacy fixtures and a committed decodecorpus-style **corpus** with manifest); we decompress and compare. See [packages/zstdify-tests/fixtures/README.md](packages/zstdify-tests/fixtures/README.md).
75
- - **Differential (zstd ↔ zstdify)**: When the zstd CLI is installed, we test zstd compress → zstdify decompress and zstdify compress → zstd decompress across payloads and levels.
100
+ - **Differential (zstd ↔ zstdify)**: We test zstd compress → zstdify decompress and zstdify compress → zstd decompress across payloads and levels.
76
101
  - **Corruption**: Truncation, checksum mismatch, invalid header bits, and related error paths.
77
102
  - **Compression regression**: Compressed sizes for fixed payloads are checked against golden values (ratio stability).
78
103
  - **Decompress robustness**: Each corpus fixture is decompressed in its own test (one test per file), so the suite tracks decompress behavior per input. See [upstream zstd TESTING.md](https://github.com/facebook/zstd/blob/dev/TESTING.md) for comparison.
@@ -5,5 +5,10 @@
5
5
  export type CompressOptions = {
6
6
  level?: number;
7
7
  checksum?: boolean;
8
+ dictionary?: Uint8Array | {
9
+ bytes: Uint8Array;
10
+ id?: number;
11
+ };
12
+ noDictId?: boolean;
8
13
  };
9
14
  export declare function compress(input: Uint8Array, options?: CompressOptions): Uint8Array;
package/dist/compress.js CHANGED
@@ -2,17 +2,29 @@
2
2
  * Compress input data using zstd.
3
3
  * Level 0: raw blocks only (no compression, fast).
4
4
  */
5
+ import { normalizeDecoderDictionary } from './dictionary/decoderDictionary.js';
5
6
  import { writeRawBlock, writeRLEBlock } from './encode/blockWriter.js';
6
7
  import { buildCompressedBlockPayload, writeCompressedBlock } from './encode/compressedBlock.js';
7
8
  import { writeFrameHeader } from './encode/frameWriter.js';
8
9
  import { buildGreedySequences } from './encode/greedySequences.js';
10
+ import { ZstdError } from './errors.js';
9
11
  import { computeContentChecksum32 } from './frame/checksum.js';
10
12
  const BLOCK_MAX = 128 * 1024;
11
13
  export function compress(input, options) {
12
14
  const level = options?.level ?? 0;
13
15
  const hasChecksum = options?.checksum ?? false;
16
+ const dictionary = options?.dictionary;
17
+ const dictionaryBytes = dictionary instanceof Uint8Array ? dictionary : dictionary?.bytes;
18
+ const providedDictionaryId = dictionary instanceof Uint8Array ? null : (dictionary?.id ?? null);
19
+ const normalizedDictionary = dictionaryBytes && dictionaryBytes.length > 0
20
+ ? normalizeDecoderDictionary(dictionaryBytes, providedDictionaryId)
21
+ : null;
22
+ const dictionaryId = options?.noDictId ? null : (normalizedDictionary?.dictionaryId ?? providedDictionaryId);
23
+ if (dictionaryId !== null && (!Number.isInteger(dictionaryId) || dictionaryId <= 0 || dictionaryId > 0xffff_ffff)) {
24
+ throw new ZstdError('dictionary.id must be a 32-bit positive integer', 'parameter_unsupported');
25
+ }
14
26
  const chunks = [];
15
- chunks.push(writeFrameHeader(input.length, hasChecksum));
27
+ chunks.push(writeFrameHeader(input.length, hasChecksum, dictionaryId));
16
28
  let offset = 0;
17
29
  const blockCount = input.length === 0 ? 1 : Math.ceil(input.length / BLOCK_MAX);
18
30
  let blockIndex = 0;
@@ -1 +1 @@
1
- {"version":3,"file":"compress.js","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compress.js","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ export type DictionaryTrainingAlgorithm = 'fastcover' | 'cover' | 'legacy';
2
+ export interface GenerateDictionaryOptions {
3
+ /**
4
+ * Target maximum output size for dictionary bytes.
5
+ * Similar to zstd CLI --maxdict.
6
+ */
7
+ maxDictSize?: number;
8
+ /**
9
+ * Included for API parity with zstd terminology.
10
+ * Raw-content dictionaries don't embed an ID in bytes; pass this value
11
+ * separately to compress/decompress options when needed.
12
+ */
13
+ dictId?: number;
14
+ /**
15
+ * Training mode selector inspired by zstd dictionary builders.
16
+ * This implementation is deterministic and uses algorithm-specific scoring.
17
+ */
18
+ algorithm?: DictionaryTrainingAlgorithm;
19
+ /**
20
+ * Candidate segment size (bytes) used while harvesting patterns.
21
+ */
22
+ k?: number;
23
+ /**
24
+ * Distance step (bytes) between candidate probes.
25
+ */
26
+ d?: number;
27
+ /**
28
+ * Number of score-curve refinement passes.
29
+ */
30
+ steps?: number;
31
+ /**
32
+ * Percent of each sample used for candidate harvesting (1-100).
33
+ */
34
+ split?: number;
35
+ /**
36
+ * Additional fastcover-style score multiplier.
37
+ */
38
+ f?: number;
39
+ /**
40
+ * Probe stride accelerator (1-10).
41
+ */
42
+ accel?: number;
43
+ /**
44
+ * Legacy-style density control (1-10), where lower means denser.
45
+ */
46
+ selectivity?: number;
47
+ /**
48
+ * Optional shrink pass. If true, applies default shrink factor.
49
+ * If number, interpreted as target shrink factor >= 1.
50
+ */
51
+ shrink?: boolean | number;
52
+ }
53
+ /**
54
+ * Generate a deterministic raw-content dictionary from training samples.
55
+ *
56
+ * The output is intentionally a raw-content dictionary byte sequence, which is
57
+ * compatible with zstd's -D usage and zstdify dictionary decode paths.
58
+ */
59
+ export declare function generateDictionary(samples: Uint8Array[], options?: GenerateDictionaryOptions): Uint8Array;
@@ -0,0 +1,187 @@
1
+ import { ZstdError } from '../errors.js';
2
+ const DEFAULT_MAX_DICT_SIZE = 112_640;
3
+ function clamp(value, min, max) {
4
+ return Math.min(max, Math.max(min, value));
5
+ }
6
+ function hashBytes(bytes) {
7
+ // FNV-1a 32-bit
8
+ let hash = 0x811c9dc5;
9
+ for (let i = 0; i < bytes.length; i++) {
10
+ hash ^= bytes[i] ?? 0;
11
+ hash = Math.imul(hash, 0x01000193) >>> 0;
12
+ }
13
+ return hash >>> 0;
14
+ }
15
+ function normalizeOptions(sampleCount, options) {
16
+ const algorithm = options?.algorithm ?? 'fastcover';
17
+ const maxDictSize = options?.maxDictSize ?? DEFAULT_MAX_DICT_SIZE;
18
+ const kDefault = algorithm === 'cover' ? 64 : algorithm === 'legacy' ? 32 : 48;
19
+ const dDefault = algorithm === 'cover' ? 8 : algorithm === 'legacy' ? 4 : 8;
20
+ const stepsDefault = algorithm === 'cover' ? 6 : algorithm === 'legacy' ? 3 : 4;
21
+ const splitDefault = algorithm === 'legacy' ? 100 : 75;
22
+ const accelDefault = 1;
23
+ const fDefault = 20;
24
+ const selectivityDefault = 9;
25
+ const shrinkDefault = false;
26
+ if (!Number.isInteger(maxDictSize) || maxDictSize <= 0) {
27
+ throw new ZstdError('maxDictSize must be a positive integer', 'parameter_unsupported');
28
+ }
29
+ if (options?.dictId !== undefined) {
30
+ if (!Number.isInteger(options.dictId) || options.dictId <= 0 || options.dictId > 0xffff_ffff) {
31
+ throw new ZstdError('dictId must be a 32-bit positive integer', 'parameter_unsupported');
32
+ }
33
+ }
34
+ const k = clamp(Math.trunc(options?.k ?? kDefault), 8, 1024);
35
+ const d = clamp(Math.trunc(options?.d ?? dDefault), 1, 64);
36
+ const steps = clamp(Math.trunc(options?.steps ?? stepsDefault), 1, 1000);
37
+ const split = clamp(Math.trunc(options?.split ?? splitDefault), 1, 100);
38
+ const f = clamp(Math.trunc(options?.f ?? fDefault), 1, 1000);
39
+ const accel = clamp(Math.trunc(options?.accel ?? accelDefault), 1, 10);
40
+ const selectivity = clamp(Math.trunc(options?.selectivity ?? selectivityDefault), 1, 10);
41
+ const shrink = options?.shrink ?? shrinkDefault;
42
+ if (sampleCount === 0) {
43
+ throw new ZstdError('Training requires at least one sample', 'parameter_unsupported');
44
+ }
45
+ return {
46
+ algorithm,
47
+ maxDictSize,
48
+ k,
49
+ d,
50
+ steps,
51
+ split,
52
+ f,
53
+ accel,
54
+ selectivity,
55
+ shrink,
56
+ };
57
+ }
58
+ function toHex(bytes) {
59
+ let out = '';
60
+ for (let i = 0; i < bytes.length; i++) {
61
+ out += (bytes[i] ?? 0).toString(16).padStart(2, '0');
62
+ }
63
+ return out;
64
+ }
65
+ function preprocessSamples(samples, splitPercent) {
66
+ const preprocessed = [];
67
+ for (const sample of samples) {
68
+ if (!(sample instanceof Uint8Array)) {
69
+ throw new ZstdError('All samples must be Uint8Array', 'parameter_unsupported');
70
+ }
71
+ if (sample.length === 0)
72
+ continue;
73
+ const usable = Math.max(1, Math.floor((sample.length * splitPercent) / 100));
74
+ preprocessed.push(sample.subarray(0, usable));
75
+ }
76
+ if (preprocessed.length === 0) {
77
+ throw new ZstdError('Training requires at least one non-empty sample', 'parameter_unsupported');
78
+ }
79
+ return preprocessed;
80
+ }
81
+ function scoreWeight(algorithm, bytes, hits, step, f, selectivity) {
82
+ const entropyBias = 1 + (hashBytes(bytes) % 13) / 32;
83
+ const length = bytes.length;
84
+ if (algorithm === 'legacy') {
85
+ const density = 11 - selectivity;
86
+ return hits * (1 + density / 4) + length * 0.5 + entropyBias;
87
+ }
88
+ if (algorithm === 'cover') {
89
+ return hits * (1 + step / 10) + length * 1.1 + entropyBias;
90
+ }
91
+ // fastcover
92
+ return hits * (1 + f / 40) + length * 0.9 + entropyBias;
93
+ }
94
+ function harvestCandidates(samples, k, d, accel, algorithm, steps, f, selectivity) {
95
+ const map = new Map();
96
+ for (let step = 0; step < steps; step++) {
97
+ const size = clamp(k + step * d, 8, 2048);
98
+ const stride = Math.max(1, Math.floor((d * accel) / Math.max(1, step + 1)));
99
+ for (const sample of samples) {
100
+ if (sample.length < size)
101
+ continue;
102
+ for (let i = 0; i + size <= sample.length; i += stride) {
103
+ const bytes = sample.subarray(i, i + size);
104
+ const key = toHex(bytes);
105
+ const existing = map.get(key);
106
+ if (existing) {
107
+ existing.hits += 1;
108
+ existing.score = scoreWeight(algorithm, existing.bytes, existing.hits, step + 1, f, selectivity);
109
+ continue;
110
+ }
111
+ const cloned = bytes.slice();
112
+ map.set(key, {
113
+ key,
114
+ bytes: cloned,
115
+ hits: 1,
116
+ score: scoreWeight(algorithm, cloned, 1, step + 1, f, selectivity),
117
+ });
118
+ }
119
+ }
120
+ }
121
+ return [...map.values()];
122
+ }
123
+ function maybeShrink(target, shrink) {
124
+ if (shrink === false)
125
+ return target;
126
+ if (shrink === true)
127
+ return Math.max(256, Math.floor(target * 0.75));
128
+ if (Number.isFinite(shrink) && shrink >= 1) {
129
+ return Math.max(256, Math.floor(target / shrink));
130
+ }
131
+ throw new ZstdError('shrink must be boolean or number >= 1', 'parameter_unsupported');
132
+ }
133
+ function buildDictionaryBytes(candidates, maxDictSize) {
134
+ const sorted = [...candidates].sort((a, b) => {
135
+ if (b.score !== a.score)
136
+ return b.score - a.score;
137
+ if (b.hits !== a.hits)
138
+ return b.hits - a.hits;
139
+ if (b.bytes.length !== a.bytes.length)
140
+ return b.bytes.length - a.bytes.length;
141
+ return a.key.localeCompare(b.key);
142
+ });
143
+ const chunks = [];
144
+ let total = 0;
145
+ for (const candidate of sorted) {
146
+ if (total >= maxDictSize)
147
+ break;
148
+ if (candidate.hits <= 1 && candidate.bytes.length < 24)
149
+ continue;
150
+ const remaining = maxDictSize - total;
151
+ if (remaining < 8)
152
+ break;
153
+ const piece = candidate.bytes.length <= remaining ? candidate.bytes : candidate.bytes.subarray(0, remaining);
154
+ if (piece.length < 8)
155
+ break;
156
+ chunks.push(piece.slice());
157
+ total += piece.length;
158
+ }
159
+ if (chunks.length === 0) {
160
+ // Fallback: ensure at least one deterministic dictionary segment exists.
161
+ const fallback = new Uint8Array(Math.min(256, maxDictSize));
162
+ for (let i = 0; i < fallback.length; i++)
163
+ fallback[i] = i & 0xff;
164
+ return fallback;
165
+ }
166
+ const out = new Uint8Array(total);
167
+ let offset = 0;
168
+ for (const chunk of chunks) {
169
+ out.set(chunk, offset);
170
+ offset += chunk.length;
171
+ }
172
+ return out;
173
+ }
174
+ /**
175
+ * Generate a deterministic raw-content dictionary from training samples.
176
+ *
177
+ * The output is intentionally a raw-content dictionary byte sequence, which is
178
+ * compatible with zstd's -D usage and zstdify dictionary decode paths.
179
+ */
180
+ export function generateDictionary(samples, options) {
181
+ const normalized = normalizeOptions(samples.length, options);
182
+ const preprocessed = preprocessSamples(samples, normalized.split);
183
+ const candidates = harvestCandidates(preprocessed, normalized.k, normalized.d, normalized.accel, normalized.algorithm, normalized.steps, normalized.f, normalized.selectivity);
184
+ const targetSize = maybeShrink(normalized.maxDictSize, normalized.shrink);
185
+ return buildDictionaryBytes(candidates, targetSize);
186
+ }
187
+ //# sourceMappingURL=generateDictionary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateDictionary.js","sourceRoot":"","sources":["../../src/dictionary/generateDictionary.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  /**
2
2
  * Write zstd frame header.
3
3
  */
4
- export declare function writeFrameHeader(contentSize: number, hasChecksum: boolean): Uint8Array;
4
+ export declare function writeFrameHeader(contentSize: number, hasChecksum: boolean, dictionaryId?: number | null): Uint8Array;
@@ -2,7 +2,18 @@
2
2
  * Write zstd frame header.
3
3
  */
4
4
  const ZSTD_MAGIC = 0xfd2fb528;
5
- export function writeFrameHeader(contentSize, hasChecksum) {
5
+ function writeDictionaryId(chunks, dictionaryId) {
6
+ if (dictionaryId <= 0xff) {
7
+ chunks.push(dictionaryId & 0xff);
8
+ return;
9
+ }
10
+ if (dictionaryId <= 0xffff) {
11
+ chunks.push(dictionaryId & 0xff, (dictionaryId >>> 8) & 0xff);
12
+ return;
13
+ }
14
+ chunks.push(dictionaryId & 0xff, (dictionaryId >>> 8) & 0xff, (dictionaryId >>> 16) & 0xff, (dictionaryId >>> 24) & 0xff);
15
+ }
16
+ export function writeFrameHeader(contentSize, hasChecksum, dictionaryId = null) {
6
17
  const chunks = [];
7
18
  chunks.push(ZSTD_MAGIC & 0xff, (ZSTD_MAGIC >> 8) & 0xff, (ZSTD_MAGIC >> 16) & 0xff, (ZSTD_MAGIC >> 24) & 0xff);
8
19
  let fhd = 0;
@@ -18,8 +29,22 @@ export function writeFrameHeader(contentSize, hasChecksum) {
18
29
  fhd |= 2 << 6;
19
30
  fhd |= 1 << 5;
20
31
  }
32
+ if (dictionaryId !== null) {
33
+ if (!Number.isInteger(dictionaryId) || dictionaryId <= 0 || dictionaryId > 0xffff_ffff) {
34
+ throw new Error('Invalid dictionaryId in frame header');
35
+ }
36
+ if (dictionaryId <= 0xff)
37
+ fhd |= 1;
38
+ else if (dictionaryId <= 0xffff)
39
+ fhd |= 2;
40
+ else
41
+ fhd |= 3;
42
+ }
21
43
  fhd |= (hasChecksum ? 1 : 0) << 2;
22
44
  chunks.push(fhd);
45
+ if (dictionaryId !== null) {
46
+ writeDictionaryId(chunks, dictionaryId >>> 0);
47
+ }
23
48
  if (contentSize <= 255) {
24
49
  chunks.push(contentSize & 0xff);
25
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"frameWriter.js","sourceRoot":"","sources":["../../src/encode/frameWriter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,UAAU,GAAG,UAAU,CAAC;AAE9B,MAAM,UAAU,gBAAgB,CAAC,WAAmB,EAAE,WAAoB,EAAc;IACtF,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,EAAE,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAE/G,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,WAAW,IAAI,GAAG,EAAE,CAAC;QACvB,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;SAAM,IAAI,WAAW,IAAI,GAAG,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC;QAC1C,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;SAAM,CAAC;QACN,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;IACD,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEjB,IAAI,WAAW,IAAI,GAAG,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAClC,CAAC;SAAM,IAAI,WAAW,IAAI,GAAG,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,GAAG,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,WAAW,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7E,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,EAAE,CAAC,WAAW,IAAI,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IACrH,CAAC;IAED,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;AAAA,CAC/B"}
1
+ {"version":3,"file":"frameWriter.js","sourceRoot":"","sources":["../../src/encode/frameWriter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,UAAU,GAAG,UAAU,CAAC;AAE9B,SAAS,iBAAiB,CAAC,MAAgB,EAAE,YAAoB,EAAQ;IACvE,IAAI,YAAY,IAAI,IAAI,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;QACjC,OAAO;IACT,CAAC;IACD,IAAI,YAAY,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,YAAY,GAAG,IAAI,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC9D,OAAO;IACT,CAAC;IACD,MAAM,CAAC,IAAI,CACT,YAAY,GAAG,IAAI,EACnB,CAAC,YAAY,KAAK,CAAC,CAAC,GAAG,IAAI,EAC3B,CAAC,YAAY,KAAK,EAAE,CAAC,GAAG,IAAI,EAC5B,CAAC,YAAY,KAAK,EAAE,CAAC,GAAG,IAAI,CAC7B,CAAC;AAAA,CACH;AAED,MAAM,UAAU,gBAAgB,CAC9B,WAAmB,EACnB,WAAoB,EACpB,YAAY,GAAkB,IAAI,EACtB;IACZ,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,EAAE,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAE/G,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,WAAW,IAAI,GAAG,EAAE,CAAC;QACvB,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;SAAM,IAAI,WAAW,IAAI,GAAG,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC;QAC1C,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;SAAM,CAAC;QACN,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;IACD,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,YAAY,IAAI,CAAC,IAAI,YAAY,GAAG,WAAW,EAAE,CAAC;YACvF,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,YAAY,IAAI,IAAI;YAAE,GAAG,IAAI,CAAC,CAAC;aAC9B,IAAI,YAAY,IAAI,MAAM;YAAE,GAAG,IAAI,CAAC,CAAC;;YACrC,GAAG,IAAI,CAAC,CAAC;IAChB,CAAC;IACD,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEjB,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,iBAAiB,CAAC,MAAM,EAAE,YAAY,KAAK,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,WAAW,IAAI,GAAG,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAClC,CAAC;SAAM,IAAI,WAAW,IAAI,GAAG,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,GAAG,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,WAAW,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7E,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,EAAE,CAAC,WAAW,IAAI,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IACrH,CAAC;IAED,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;AAAA,CAC/B"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { type CompressOptions, compress } from './compress.js';
2
2
  export { type DecompressOptions, decompress } from './decompress.js';
3
+ export { type DictionaryTrainingAlgorithm, type GenerateDictionaryOptions, generateDictionary, } from './dictionary/generateDictionary.js';
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export { compress } from './compress.js';
2
2
  export { decompress } from './decompress.js';
3
+ export { generateDictionary, } from './dictionary/generateDictionary.js';
3
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAA0B,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAA0B,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAGL,kBAAkB,GACnB,MAAM,oCAAoC,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "zstdify",
3
3
  "description": "Pure TypeScript zstd compression library",
4
- "version": "1.0.1",
4
+ "version": "1.1.0",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -1 +0,0 @@
1
- export {};
@@ -1,25 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import * as bitstream from './bitstream/index.js';
3
- import * as entropy from './entropy/index.js';
4
- import * as frame from './frame/index.js';
5
- import * as root from './index.js';
6
- describe('public barrel exports smoke', () => {
7
- it('exposes root API functions', () => {
8
- expect(typeof root.compress).toBe('function');
9
- expect(typeof root.decompress).toBe('function');
10
- });
11
- it('exposes bitstream helpers', () => {
12
- expect(typeof bitstream.BitReader).toBe('function');
13
- expect(typeof bitstream.BitWriter).toBe('function');
14
- expect(typeof bitstream.readU32LE).toBe('function');
15
- expect(typeof bitstream.encodeVarint).toBe('function');
16
- });
17
- it('exposes entropy and frame helpers', () => {
18
- expect(typeof entropy.buildFSEDecodeTable).toBe('function');
19
- expect(typeof entropy.buildHuffmanDecodeTable).toBe('function');
20
- expect(typeof frame.parseZstdFrame).toBe('function');
21
- expect(typeof frame.validateContentChecksum).toBe('function');
22
- expect(typeof frame.isSkippableFrame).toBe('function');
23
- });
24
- });
25
- //# sourceMappingURL=barrelExports.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"barrelExports.test.js","sourceRoot":"","sources":["../src/barrelExports.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AAEnC,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE,CAAC;IAC5C,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE,CAAC;QACrC,MAAM,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9C,MAAM,CAAC,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAAA,CACjD,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE,CAAC;QACpC,MAAM,CAAC,OAAO,SAAS,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACpD,MAAM,CAAC,OAAO,SAAS,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACpD,MAAM,CAAC,OAAO,SAAS,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACpD,MAAM,CAAC,OAAO,SAAS,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAAA,CACxD,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE,CAAC;QAC5C,MAAM,CAAC,OAAO,OAAO,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5D,MAAM,CAAC,OAAO,OAAO,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChE,MAAM,CAAC,OAAO,KAAK,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,CAAC,OAAO,KAAK,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9D,MAAM,CAAC,OAAO,KAAK,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAAA,CACxD,CAAC,CAAC;AAAA,CACJ,CAAC,CAAC"}
@@ -1 +0,0 @@
1
- export {};
@@ -1,47 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { BitReader } from './bitReader.js';
3
- describe('BitReader', () => {
4
- it('reads single bits', () => {
5
- // 0b10110100 = 0xB4
6
- const data = new Uint8Array([0xb4]);
7
- const r = new BitReader(data);
8
- expect(r.readBits(1)).toBe(0);
9
- expect(r.readBits(1)).toBe(0);
10
- expect(r.readBits(1)).toBe(1);
11
- expect(r.readBits(1)).toBe(0);
12
- expect(r.readBits(1)).toBe(1);
13
- expect(r.readBits(1)).toBe(1);
14
- expect(r.readBits(1)).toBe(0);
15
- expect(r.readBits(1)).toBe(1);
16
- expect(r.atEnd).toBe(true);
17
- });
18
- it('reads multi-bit values', () => {
19
- const data = new Uint8Array([0xff, 0x00]); // 11111111 00000000
20
- const r = new BitReader(data);
21
- expect(r.readBits(8)).toBe(0xff);
22
- expect(r.readBits(8)).toBe(0x00);
23
- });
24
- it('reads across byte boundaries', () => {
25
- // byte0: 1111 (low) 0000 (high), byte1: 1111 (low) 0000 (high)
26
- const data = new Uint8Array([0b00001111, 0b00001111]);
27
- const r = new BitReader(data);
28
- expect(r.readBits(4)).toBe(0b1111); // low 4 of byte0
29
- expect(r.readBits(8)).toBe(0b11110000); // high 4 of byte0 + low 4 of byte1
30
- expect(r.readBits(4)).toBe(0); // high 4 of byte1
31
- });
32
- it('align works', () => {
33
- const data = new Uint8Array([0xff, 0xab, 0xcd]);
34
- const r = new BitReader(data);
35
- r.readBits(3);
36
- r.align();
37
- expect(r.position).toBe(1);
38
- expect(r.readByte()).toBe(0xab);
39
- });
40
- it('throws on out of bounds', () => {
41
- const data = new Uint8Array([0xff]);
42
- const r = new BitReader(data);
43
- r.readBits(8);
44
- expect(() => r.readBits(1)).toThrow();
45
- });
46
- });
47
- //# sourceMappingURL=bitReader.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bitReader.test.js","sourceRoot":"","sources":["../../src/bitstream/bitReader.test.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- export {};
@@ -1,49 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { BitReaderReverse } from './bitReaderReverse.js';
3
- describe('BitReaderReverse', () => {
4
- it('supports unreadBits to rollback over-read', () => {
5
- const reader = new BitReaderReverse(new Uint8Array([0xa0, 0x01]), 0, 2);
6
- reader.skipPadding();
7
- const first = reader.readBits(2);
8
- expect(first).toBe(2);
9
- reader.unreadBits(1);
10
- expect(reader.readBits(1)).toBe(0);
11
- });
12
- it('zero-fills when reading past stream start', () => {
13
- const reader = new BitReaderReverse(new Uint8Array([0x80]), 0, 1);
14
- reader.skipPadding();
15
- // No payload bits remain after padding; reading still succeeds with zeros.
16
- expect(reader.readBits(4)).toBe(0);
17
- });
18
- it('position returns start byte when bitOffset <= startBit', () => {
19
- const reader = new BitReaderReverse(new Uint8Array([0x80]), 0, 1);
20
- reader.skipPadding();
21
- reader.readBits(4); // consume remaining (zeros)
22
- expect(reader.position).toBe(0);
23
- });
24
- it('position returns correct byte after reading bits', () => {
25
- const reader = new BitReaderReverse(new Uint8Array([0xa0, 0x01]), 0, 2);
26
- reader.skipPadding();
27
- reader.readBits(2);
28
- expect(reader.position).toBeGreaterThanOrEqual(0);
29
- expect(reader.position).toBeLessThanOrEqual(2);
30
- });
31
- it('skipBitsAtEnd advances logical position', () => {
32
- const reader = new BitReaderReverse(new Uint8Array([0x80]), 0, 1);
33
- reader.skipPadding();
34
- reader.skipBitsAtEnd(1);
35
- expect(reader.readBits(1)).toBe(0);
36
- });
37
- it('skipBitsAtEnd throws on buffer underflow', () => {
38
- const reader = new BitReaderReverse(new Uint8Array([0x80]), 0, 1);
39
- reader.skipPadding();
40
- expect(() => reader.skipBitsAtEnd(100)).toThrow(/underflow|RangeError/i);
41
- });
42
- it('unreadBits throws on overflow', () => {
43
- const reader = new BitReaderReverse(new Uint8Array([0xa0, 0x01]), 0, 2);
44
- reader.skipPadding();
45
- reader.readBits(2);
46
- expect(() => reader.unreadBits(20)).toThrow(/overflow|RangeError/i);
47
- });
48
- });
49
- //# sourceMappingURL=bitReaderReverse.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bitReaderReverse.test.js","sourceRoot":"","sources":["../../src/bitstream/bitReaderReverse.test.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- export {};