mlclaw 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/mlclaw/SKILL.md +214 -0
- package/.agents/skills/mlclaw/agents/openai.yaml +4 -0
- package/.gitattributes +35 -0
- package/Dockerfile +45 -0
- package/LICENSE +21 -0
- package/README.md +206 -0
- package/assets/mlclaw.svg +143 -0
- package/dist/hf-state-sync.js +9532 -0
- package/dist/mlclaw-space-runtime.js +5010 -0
- package/dist/mlclaw.mjs +16502 -0
- package/entrypoint.sh +87 -0
- package/mlclaw.ps1 +108 -0
- package/mlclaw.sh +117 -0
- package/openclaw.default.json +67 -0
- package/package.json +66 -0
- package/scripts/configure-huggingface-model.mjs +86 -0
- package/scripts/configure-telegram.mjs +55 -0
- package/scripts/report-telegram-probe.mjs +18 -0
- package/space/README.md +42 -0
- package/src/hf-bucket-client/client.ts +217 -0
- package/src/hf-state-sync/archive.ts +137 -0
- package/src/hf-state-sync/cli.ts +92 -0
- package/src/hf-state-sync/hub.ts +81 -0
- package/src/hf-state-sync/manifest.ts +67 -0
- package/src/hf-state-sync/paths.ts +73 -0
- package/src/hf-state-sync/restore.ts +109 -0
- package/src/hf-state-sync/snapshot.ts +133 -0
- package/src/hf-state-sync/sqlite.ts +57 -0
- package/src/hf-state-sync/supervise.ts +256 -0
- package/src/vendor/hfjs-xet/error.ts +52 -0
- package/src/vendor/hfjs-xet/types/public.ts +207 -0
- package/src/vendor/hfjs-xet/utils/ChunkCache.ts +102 -0
- package/src/vendor/hfjs-xet/utils/RangeList.ts +182 -0
- package/src/vendor/hfjs-xet/utils/SplicedBlob.ts +249 -0
- package/src/vendor/hfjs-xet/utils/XetBlob.ts +732 -0
- package/src/vendor/hfjs-xet/utils/checkCredentials.ts +21 -0
- package/src/vendor/hfjs-xet/utils/combineUint8Arrays.ts +13 -0
- package/src/vendor/hfjs-xet/utils/createXorbs.ts +782 -0
- package/src/vendor/hfjs-xet/utils/shardParser.ts +152 -0
- package/src/vendor/hfjs-xet/utils/sum.ts +9 -0
- package/src/vendor/hfjs-xet/utils/uploadShards.ts +443 -0
- package/src/vendor/hfjs-xet/utils/xetWriteToken.ts +101 -0
- package/src/vendor/hfjs-xet/vendor/lz4js/index.ts +540 -0
- package/src/vendor/hfjs-xet/vendor/lz4js/util.ts +57 -0
- package/src/vendor/hfjs-xet/vendor/lz4js/xxh32.ts +99 -0
- package/src/vendor/hfjs-xet/vendor/type-fest/basic.ts +34 -0
- package/tsconfig.json +16 -0
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
// @ts-nocheck -- vendored upstream code, kept verbatim; our strict tsconfig does not apply.
|
|
2
|
+
// Vendored from huggingface/huggingface.js@f8fdf6be (packages/hub/src/vendor/lz4js/index.ts), MIT License.
|
|
3
|
+
// Delete this directory when bucket support is upstreamed to @huggingface/hub.
|
|
4
|
+
// lz4.js - An implementation of Lz4 in plain JavaScript.
|
|
5
|
+
//
|
|
6
|
+
// TODO:
|
|
7
|
+
// - Unify header parsing/writing.
|
|
8
|
+
// - Support options (block size, checksums)
|
|
9
|
+
// - Support streams
|
|
10
|
+
// - Better error handling (handle bad offset, etc.)
|
|
11
|
+
// - HC support (better search algorithm)
|
|
12
|
+
// - Tests/benchmarking
|
|
13
|
+
|
|
14
|
+
import * as xxhash from "./xxh32.js";
|
|
15
|
+
import * as util from "./util.js";
|
|
16
|
+
|
|
17
|
+
// Constants
|
|
18
|
+
// --
|
|
19
|
+
|
|
20
|
+
// Compression format parameters/constants.
|
|
21
|
+
const minMatch = 4;
|
|
22
|
+
const matchSearchLimit = 12;
|
|
23
|
+
const minTrailingLitterals = 5;
|
|
24
|
+
const skipTrigger = 6;
|
|
25
|
+
const hashSize = 1 << 16;
|
|
26
|
+
|
|
27
|
+
// Token constants.
|
|
28
|
+
const mlBits = 4;
|
|
29
|
+
const mlMask = (1 << mlBits) - 1;
|
|
30
|
+
const runBits = 4;
|
|
31
|
+
const runMask = (1 << runBits) - 1;
|
|
32
|
+
|
|
33
|
+
// Shared buffers
|
|
34
|
+
const blockBuf = makeBuffer(5 << 20);
|
|
35
|
+
const hashTable = makeHashTable();
|
|
36
|
+
|
|
37
|
+
// Frame constants.
|
|
38
|
+
const magicNum = 0x184d2204;
|
|
39
|
+
|
|
40
|
+
// Frame descriptor flags.
|
|
41
|
+
const fdContentChksum = 0x4;
|
|
42
|
+
const fdContentSize = 0x8;
|
|
43
|
+
const fdBlockChksum = 0x10;
|
|
44
|
+
// var fdBlockIndep = 0x20;
|
|
45
|
+
const fdVersion = 0x40;
|
|
46
|
+
const fdVersionMask = 0xc0;
|
|
47
|
+
|
|
48
|
+
// Block sizes.
|
|
49
|
+
const bsUncompressed = 0x80000000;
|
|
50
|
+
const bsDefault = 7;
|
|
51
|
+
const bsShift = 4;
|
|
52
|
+
const bsMask = 7;
|
|
53
|
+
const bsMap: Record<number, number> = {
|
|
54
|
+
4: 0x10000,
|
|
55
|
+
5: 0x40000,
|
|
56
|
+
6: 0x100000,
|
|
57
|
+
7: 0x400000,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Utility functions/primitives
|
|
61
|
+
// --
|
|
62
|
+
|
|
63
|
+
// Makes our hashtable. On older browsers, may return a plain array.
|
|
64
|
+
function makeHashTable() {
|
|
65
|
+
try {
|
|
66
|
+
return new Uint32Array(hashSize);
|
|
67
|
+
} catch (error) {
|
|
68
|
+
const hashTable = new Array(hashSize);
|
|
69
|
+
|
|
70
|
+
for (let i = 0; i < hashSize; i++) {
|
|
71
|
+
hashTable[i] = 0;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return hashTable;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Clear hashtable.
|
|
79
|
+
function clearHashTable(table: Uint32Array | number[]) {
|
|
80
|
+
for (let i = 0; i < hashSize; i++) {
|
|
81
|
+
table[i] = 0;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Makes a byte buffer. On older browsers, may return a plain array.
|
|
86
|
+
function makeBuffer(size: number) {
|
|
87
|
+
return new Uint8Array(size);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function sliceArray(array: Uint8Array, start: number, end: number) {
|
|
91
|
+
return array.slice(start, end);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Implementation
|
|
95
|
+
// --
|
|
96
|
+
|
|
97
|
+
// Calculates an upper bound for lz4 compression.
|
|
98
|
+
export function compressBound(n: number) {
|
|
99
|
+
return (n + n / 255 + 16) | 0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Calculates an upper bound for lz4 decompression, by reading the data.
|
|
103
|
+
export function decompressBound(src: Uint8Array) {
|
|
104
|
+
let sIndex = 0;
|
|
105
|
+
|
|
106
|
+
// Read magic number
|
|
107
|
+
if (util.readU32(src, sIndex) !== magicNum) {
|
|
108
|
+
throw new Error("invalid magic number");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
sIndex += 4;
|
|
112
|
+
|
|
113
|
+
// Read descriptor
|
|
114
|
+
const descriptor = src[sIndex++];
|
|
115
|
+
|
|
116
|
+
// Check version
|
|
117
|
+
if ((descriptor & fdVersionMask) !== fdVersion) {
|
|
118
|
+
throw new Error("incompatible descriptor version " + (descriptor & fdVersionMask));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Read flags
|
|
122
|
+
const useBlockSum = (descriptor & fdBlockChksum) !== 0;
|
|
123
|
+
const useContentSize = (descriptor & fdContentSize) !== 0;
|
|
124
|
+
|
|
125
|
+
// Read block size
|
|
126
|
+
const bsIdx = (src[sIndex++] >> bsShift) & bsMask;
|
|
127
|
+
|
|
128
|
+
if (bsMap[bsIdx] === undefined) {
|
|
129
|
+
throw new Error("invalid block size " + bsIdx);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const maxBlockSize = bsMap[bsIdx];
|
|
133
|
+
|
|
134
|
+
// Get content size
|
|
135
|
+
if (useContentSize) {
|
|
136
|
+
return util.readU64(src, sIndex);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Checksum
|
|
140
|
+
sIndex++;
|
|
141
|
+
|
|
142
|
+
// Read blocks.
|
|
143
|
+
let maxSize = 0;
|
|
144
|
+
while (true) {
|
|
145
|
+
let blockSize = util.readU32(src, sIndex);
|
|
146
|
+
sIndex += 4;
|
|
147
|
+
|
|
148
|
+
if (blockSize & bsUncompressed) {
|
|
149
|
+
blockSize &= ~bsUncompressed;
|
|
150
|
+
maxSize += blockSize;
|
|
151
|
+
} else if (blockSize > 0) {
|
|
152
|
+
maxSize += maxBlockSize;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (blockSize === 0) {
|
|
156
|
+
return maxSize;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (useBlockSum) {
|
|
160
|
+
sIndex += 4;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
sIndex += blockSize;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Decompresses a block of Lz4.
|
|
168
|
+
export function decompressBlock(src: Uint8Array, dst: Uint8Array, sIndex: number, sLength: number, dIndex: number) {
|
|
169
|
+
let mLength, mOffset, sEnd, n, i;
|
|
170
|
+
const hasCopyWithin = dst.copyWithin !== undefined && dst.fill !== undefined;
|
|
171
|
+
|
|
172
|
+
// Setup initial state.
|
|
173
|
+
sEnd = sIndex + sLength;
|
|
174
|
+
|
|
175
|
+
// Consume entire input block.
|
|
176
|
+
while (sIndex < sEnd) {
|
|
177
|
+
const token = src[sIndex++];
|
|
178
|
+
|
|
179
|
+
// Copy literals.
|
|
180
|
+
let literalCount = token >> 4;
|
|
181
|
+
if (literalCount > 0) {
|
|
182
|
+
// Parse length.
|
|
183
|
+
if (literalCount === 0xf) {
|
|
184
|
+
while (true) {
|
|
185
|
+
literalCount += src[sIndex];
|
|
186
|
+
if (src[sIndex++] !== 0xff) {
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Copy literals
|
|
193
|
+
for (n = sIndex + literalCount; sIndex < n; ) {
|
|
194
|
+
dst[dIndex++] = src[sIndex++];
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (sIndex >= sEnd) {
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Copy match.
|
|
203
|
+
mLength = token & 0xf;
|
|
204
|
+
|
|
205
|
+
// Parse offset.
|
|
206
|
+
mOffset = src[sIndex++] | (src[sIndex++] << 8);
|
|
207
|
+
|
|
208
|
+
// Parse length.
|
|
209
|
+
if (mLength === 0xf) {
|
|
210
|
+
while (true) {
|
|
211
|
+
mLength += src[sIndex];
|
|
212
|
+
if (src[sIndex++] !== 0xff) {
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
mLength += minMatch;
|
|
219
|
+
|
|
220
|
+
// Copy match
|
|
221
|
+
// prefer to use typedarray.copyWithin for larger matches
|
|
222
|
+
// NOTE: copyWithin doesn't work as required by LZ4 for overlapping sequences
|
|
223
|
+
// e.g. mOffset=1, mLength=30 (repeach char 30 times)
|
|
224
|
+
// we special case the repeat char w/ array.fill
|
|
225
|
+
if (hasCopyWithin && mOffset === 1) {
|
|
226
|
+
dst.fill(dst[dIndex - 1] | 0, dIndex, dIndex + mLength);
|
|
227
|
+
dIndex += mLength;
|
|
228
|
+
} else if (hasCopyWithin && mOffset > mLength && mLength > 31) {
|
|
229
|
+
dst.copyWithin(dIndex, dIndex - mOffset, dIndex - mOffset + mLength);
|
|
230
|
+
dIndex += mLength;
|
|
231
|
+
} else {
|
|
232
|
+
for (i = dIndex - mOffset, n = i + mLength; i < n; ) {
|
|
233
|
+
dst[dIndex++] = dst[i++] | 0;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return dIndex;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Compresses a block with Lz4.
|
|
242
|
+
export function compressBlock(
|
|
243
|
+
src: Uint8Array,
|
|
244
|
+
dst: Uint8Array,
|
|
245
|
+
sIndex: number,
|
|
246
|
+
sLength: number,
|
|
247
|
+
hashTable: Uint32Array | number[],
|
|
248
|
+
) {
|
|
249
|
+
let mIndex, mAnchor, mLength, mOffset, mStep;
|
|
250
|
+
let literalCount, dIndex, sEnd, n;
|
|
251
|
+
|
|
252
|
+
// Setup initial state.
|
|
253
|
+
dIndex = 0;
|
|
254
|
+
sEnd = sLength + sIndex;
|
|
255
|
+
mAnchor = sIndex;
|
|
256
|
+
|
|
257
|
+
let searchMatchCount = (1 << skipTrigger) + 3;
|
|
258
|
+
|
|
259
|
+
// Search for matches with a limit of matchSearchLimit bytes
|
|
260
|
+
// before the end of block (Lz4 spec limitation.)
|
|
261
|
+
while (sIndex <= sEnd - matchSearchLimit) {
|
|
262
|
+
const seq = util.readU32(src, sIndex);
|
|
263
|
+
let hash = util.hashU32(seq) >>> 0;
|
|
264
|
+
|
|
265
|
+
// Crush hash to 16 bits.
|
|
266
|
+
hash = (((hash >> 16) ^ hash) >>> 0) & 0xffff;
|
|
267
|
+
|
|
268
|
+
// Look for a match in the hashtable. NOTE: remove one; see below.
|
|
269
|
+
mIndex = hashTable[hash] - 1;
|
|
270
|
+
|
|
271
|
+
// Put pos in hash table. NOTE: add one so that zero = invalid.
|
|
272
|
+
hashTable[hash] = sIndex + 1;
|
|
273
|
+
|
|
274
|
+
// Determine if there is a match (within range.)
|
|
275
|
+
if (mIndex < 0 || (sIndex - mIndex) >>> 16 > 0 || util.readU32(src, mIndex) !== seq) {
|
|
276
|
+
mStep = searchMatchCount++ >> skipTrigger;
|
|
277
|
+
sIndex += mStep;
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
searchMatchCount = (1 << skipTrigger) + 3;
|
|
282
|
+
|
|
283
|
+
// Calculate literal count and offset.
|
|
284
|
+
literalCount = sIndex - mAnchor;
|
|
285
|
+
mOffset = sIndex - mIndex;
|
|
286
|
+
|
|
287
|
+
// We've already matched one word, so get that out of the way.
|
|
288
|
+
sIndex += minMatch;
|
|
289
|
+
mIndex += minMatch;
|
|
290
|
+
|
|
291
|
+
// Determine match length.
|
|
292
|
+
// N.B.: mLength does not include minMatch, Lz4 adds it back
|
|
293
|
+
// in decoding.
|
|
294
|
+
mLength = sIndex;
|
|
295
|
+
while (sIndex < sEnd - minTrailingLitterals && src[sIndex] === src[mIndex]) {
|
|
296
|
+
sIndex++;
|
|
297
|
+
mIndex++;
|
|
298
|
+
}
|
|
299
|
+
mLength = sIndex - mLength;
|
|
300
|
+
|
|
301
|
+
// Write token + literal count.
|
|
302
|
+
const token = mLength < mlMask ? mLength : mlMask;
|
|
303
|
+
if (literalCount >= runMask) {
|
|
304
|
+
dst[dIndex++] = (runMask << mlBits) + token;
|
|
305
|
+
for (n = literalCount - runMask; n >= 0xff; n -= 0xff) {
|
|
306
|
+
dst[dIndex++] = 0xff;
|
|
307
|
+
}
|
|
308
|
+
dst[dIndex++] = n;
|
|
309
|
+
} else {
|
|
310
|
+
dst[dIndex++] = (literalCount << mlBits) + token;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Write literals.
|
|
314
|
+
for (let i = 0; i < literalCount; i++) {
|
|
315
|
+
dst[dIndex++] = src[mAnchor + i];
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Write offset.
|
|
319
|
+
dst[dIndex++] = mOffset;
|
|
320
|
+
dst[dIndex++] = mOffset >> 8;
|
|
321
|
+
|
|
322
|
+
// Write match length.
|
|
323
|
+
if (mLength >= mlMask) {
|
|
324
|
+
for (n = mLength - mlMask; n >= 0xff; n -= 0xff) {
|
|
325
|
+
dst[dIndex++] = 0xff;
|
|
326
|
+
}
|
|
327
|
+
dst[dIndex++] = n;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Move the anchor.
|
|
331
|
+
mAnchor = sIndex;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Nothing was encoded.
|
|
335
|
+
if (mAnchor === 0) {
|
|
336
|
+
return 0;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Write remaining literals.
|
|
340
|
+
// Write literal token+count.
|
|
341
|
+
literalCount = sEnd - mAnchor;
|
|
342
|
+
if (literalCount >= runMask) {
|
|
343
|
+
dst[dIndex++] = runMask << mlBits;
|
|
344
|
+
for (n = literalCount - runMask; n >= 0xff; n -= 0xff) {
|
|
345
|
+
dst[dIndex++] = 0xff;
|
|
346
|
+
}
|
|
347
|
+
dst[dIndex++] = n;
|
|
348
|
+
} else {
|
|
349
|
+
dst[dIndex++] = literalCount << mlBits;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Write literals.
|
|
353
|
+
sIndex = mAnchor;
|
|
354
|
+
while (sIndex < sEnd) {
|
|
355
|
+
dst[dIndex++] = src[sIndex++];
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
return dIndex;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Decompresses a frame of Lz4 data.
|
|
362
|
+
export function decompressFrame(src: Uint8Array, dst: Uint8Array) {
|
|
363
|
+
let useBlockSum, useContentSum, useContentSize, descriptor;
|
|
364
|
+
let sIndex = 0;
|
|
365
|
+
let dIndex = 0;
|
|
366
|
+
|
|
367
|
+
// Read magic number
|
|
368
|
+
if (util.readU32(src, sIndex) !== magicNum) {
|
|
369
|
+
throw new Error("invalid magic number");
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
sIndex += 4;
|
|
373
|
+
|
|
374
|
+
// Read descriptor
|
|
375
|
+
descriptor = src[sIndex++];
|
|
376
|
+
|
|
377
|
+
// Check version
|
|
378
|
+
if ((descriptor & fdVersionMask) !== fdVersion) {
|
|
379
|
+
throw new Error("incompatible descriptor version");
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Read flags
|
|
383
|
+
useBlockSum = (descriptor & fdBlockChksum) !== 0;
|
|
384
|
+
useContentSum = (descriptor & fdContentChksum) !== 0;
|
|
385
|
+
useContentSize = (descriptor & fdContentSize) !== 0;
|
|
386
|
+
|
|
387
|
+
// Read block size
|
|
388
|
+
const bsIdx = (src[sIndex++] >> bsShift) & bsMask;
|
|
389
|
+
|
|
390
|
+
if (bsMap[bsIdx] === undefined) {
|
|
391
|
+
throw new Error("invalid block size");
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (useContentSize) {
|
|
395
|
+
// TODO: read content size
|
|
396
|
+
sIndex += 8;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
sIndex++;
|
|
400
|
+
|
|
401
|
+
// Read blocks.
|
|
402
|
+
while (true) {
|
|
403
|
+
var compSize;
|
|
404
|
+
|
|
405
|
+
compSize = util.readU32(src, sIndex);
|
|
406
|
+
sIndex += 4;
|
|
407
|
+
|
|
408
|
+
if (compSize === 0) {
|
|
409
|
+
break;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (useBlockSum) {
|
|
413
|
+
// TODO: read block checksum
|
|
414
|
+
sIndex += 4;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Check if block is compressed
|
|
418
|
+
if ((compSize & bsUncompressed) !== 0) {
|
|
419
|
+
// Mask off the 'uncompressed' bit
|
|
420
|
+
compSize &= ~bsUncompressed;
|
|
421
|
+
|
|
422
|
+
// Copy uncompressed data into destination buffer.
|
|
423
|
+
for (let j = 0; j < compSize; j++) {
|
|
424
|
+
dst[dIndex++] = src[sIndex++];
|
|
425
|
+
}
|
|
426
|
+
} else {
|
|
427
|
+
// Decompress into blockBuf
|
|
428
|
+
dIndex = decompressBlock(src, dst, sIndex, compSize, dIndex);
|
|
429
|
+
sIndex += compSize;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (useContentSum) {
|
|
434
|
+
// TODO: read content checksum
|
|
435
|
+
sIndex += 4;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
return dIndex;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// Compresses data to an Lz4 frame.
|
|
442
|
+
export function compressFrame(src: Uint8Array, dst: Uint8Array) {
|
|
443
|
+
let dIndex = 0;
|
|
444
|
+
|
|
445
|
+
// Write magic number.
|
|
446
|
+
util.writeU32(dst, dIndex, magicNum);
|
|
447
|
+
dIndex += 4;
|
|
448
|
+
|
|
449
|
+
// Descriptor flags.
|
|
450
|
+
dst[dIndex++] = fdVersion;
|
|
451
|
+
dst[dIndex++] = bsDefault << bsShift;
|
|
452
|
+
|
|
453
|
+
// Descriptor checksum.
|
|
454
|
+
dst[dIndex] = xxhash.hash(0, dst, 4, dIndex - 4) >> 8;
|
|
455
|
+
dIndex++;
|
|
456
|
+
|
|
457
|
+
// Write blocks.
|
|
458
|
+
const maxBlockSize = bsMap[bsDefault];
|
|
459
|
+
let remaining = src.length;
|
|
460
|
+
let sIndex = 0;
|
|
461
|
+
|
|
462
|
+
// Clear the hashtable.
|
|
463
|
+
clearHashTable(hashTable);
|
|
464
|
+
|
|
465
|
+
// Split input into blocks and write.
|
|
466
|
+
while (remaining > 0) {
|
|
467
|
+
let compSize = 0;
|
|
468
|
+
const blockSize = remaining > maxBlockSize ? maxBlockSize : remaining;
|
|
469
|
+
|
|
470
|
+
compSize = compressBlock(src, blockBuf, sIndex, blockSize, hashTable);
|
|
471
|
+
|
|
472
|
+
if (compSize > blockSize || compSize === 0) {
|
|
473
|
+
// Output uncompressed.
|
|
474
|
+
util.writeU32(dst, dIndex, 0x80000000 | blockSize);
|
|
475
|
+
dIndex += 4;
|
|
476
|
+
|
|
477
|
+
for (let z = sIndex + blockSize; sIndex < z; ) {
|
|
478
|
+
dst[dIndex++] = src[sIndex++];
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
remaining -= blockSize;
|
|
482
|
+
} else {
|
|
483
|
+
// Output compressed.
|
|
484
|
+
util.writeU32(dst, dIndex, compSize);
|
|
485
|
+
dIndex += 4;
|
|
486
|
+
|
|
487
|
+
for (let j = 0; j < compSize; ) {
|
|
488
|
+
dst[dIndex++] = blockBuf[j++];
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
sIndex += blockSize;
|
|
492
|
+
remaining -= blockSize;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// Write blank end block.
|
|
497
|
+
util.writeU32(dst, dIndex, 0);
|
|
498
|
+
dIndex += 4;
|
|
499
|
+
|
|
500
|
+
return dIndex;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// Decompresses a buffer containing an Lz4 frame. maxSize is optional; if not
|
|
504
|
+
// provided, a maximum size will be determined by examining the data. The
|
|
505
|
+
// buffer returned will always be perfectly-sized.
|
|
506
|
+
export function decompress(src: Uint8Array, maxSize: number) {
|
|
507
|
+
let dst, size;
|
|
508
|
+
|
|
509
|
+
if (maxSize === undefined) {
|
|
510
|
+
maxSize = decompressBound(src);
|
|
511
|
+
}
|
|
512
|
+
dst = makeBuffer(maxSize);
|
|
513
|
+
size = decompressFrame(src, dst);
|
|
514
|
+
|
|
515
|
+
if (size !== maxSize) {
|
|
516
|
+
dst = sliceArray(dst, 0, size);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
return dst;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// Compresses a buffer to an Lz4 frame. maxSize is optional; if not provided,
|
|
523
|
+
// a buffer will be created based on the theoretical worst output size for a
|
|
524
|
+
// given input size. The buffer returned will always be perfectly-sized.
|
|
525
|
+
export function compress(src: Uint8Array, maxSize?: number) {
|
|
526
|
+
let dst, size;
|
|
527
|
+
|
|
528
|
+
if (maxSize === undefined) {
|
|
529
|
+
maxSize = compressBound(src.length);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
dst = makeBuffer(maxSize);
|
|
533
|
+
size = compressFrame(src, dst);
|
|
534
|
+
|
|
535
|
+
if (size !== maxSize) {
|
|
536
|
+
dst = sliceArray(dst, 0, size);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
return dst;
|
|
540
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// @ts-nocheck -- vendored upstream code, kept verbatim; our strict tsconfig does not apply.
|
|
2
|
+
// Vendored from huggingface/huggingface.js@f8fdf6be (packages/hub/src/vendor/lz4js/util.ts), MIT License.
|
|
3
|
+
// Delete this directory when bucket support is upstreamed to @huggingface/hub.
|
|
4
|
+
// Simple hash function, from: http://burtleburtle.net/bob/hash/integer.html.
|
|
5
|
+
// Chosen because it doesn't use multiply and achieves full avalanche.
|
|
6
|
+
export function hashU32(a: number): number {
|
|
7
|
+
a = a | 0;
|
|
8
|
+
a = (a + 2127912214 + (a << 12)) | 0;
|
|
9
|
+
a = a ^ -949894596 ^ (a >>> 19);
|
|
10
|
+
a = (a + 374761393 + (a << 5)) | 0;
|
|
11
|
+
a = (a + -744332180) ^ (a << 9);
|
|
12
|
+
a = (a + -42973499 + (a << 3)) | 0;
|
|
13
|
+
return (a ^ -1252372727 ^ (a >>> 16)) | 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Reads a 64-bit little-endian integer from an array.
|
|
17
|
+
export function readU64(b: Uint8Array, n: number): number {
|
|
18
|
+
let x = 0;
|
|
19
|
+
x |= b[n++] << 0;
|
|
20
|
+
x |= b[n++] << 8;
|
|
21
|
+
x |= b[n++] << 16;
|
|
22
|
+
x |= b[n++] << 24;
|
|
23
|
+
x |= b[n++] << 32;
|
|
24
|
+
x |= b[n++] << 40;
|
|
25
|
+
x |= b[n++] << 48;
|
|
26
|
+
x |= b[n++] << 56;
|
|
27
|
+
return x;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Reads a 32-bit little-endian integer from an array.
|
|
31
|
+
export function readU32(b: Uint8Array, n: number): number {
|
|
32
|
+
let x = 0;
|
|
33
|
+
x |= b[n++] << 0;
|
|
34
|
+
x |= b[n++] << 8;
|
|
35
|
+
x |= b[n++] << 16;
|
|
36
|
+
x |= b[n++] << 24;
|
|
37
|
+
return x;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Writes a 32-bit little-endian integer from an array.
|
|
41
|
+
export function writeU32(b: Uint8Array, n: number, x: number): void {
|
|
42
|
+
b[n++] = (x >> 0) & 0xff;
|
|
43
|
+
b[n++] = (x >> 8) & 0xff;
|
|
44
|
+
b[n++] = (x >> 16) & 0xff;
|
|
45
|
+
b[n++] = (x >> 24) & 0xff;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Multiplies two numbers using 32-bit integer multiplication.
|
|
49
|
+
// Algorithm from Emscripten.
|
|
50
|
+
export function imul(a: number, b: number): number {
|
|
51
|
+
const ah = a >>> 16;
|
|
52
|
+
const al = a & 65535;
|
|
53
|
+
const bh = b >>> 16;
|
|
54
|
+
const bl = b & 65535;
|
|
55
|
+
|
|
56
|
+
return (al * bl + ((ah * bl + al * bh) << 16)) | 0;
|
|
57
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// @ts-nocheck -- vendored upstream code, kept verbatim; our strict tsconfig does not apply.
|
|
2
|
+
// Vendored from huggingface/huggingface.js@f8fdf6be (packages/hub/src/vendor/lz4js/xxh32.ts), MIT License.
|
|
3
|
+
// Delete this directory when bucket support is upstreamed to @huggingface/hub.
|
|
4
|
+
// xxh32.js - implementation of xxhash32 in plain JavaScript
|
|
5
|
+
import * as util from "./util.js";
|
|
6
|
+
|
|
7
|
+
// xxhash32 primes
|
|
8
|
+
const prime1 = 0x9e3779b1;
|
|
9
|
+
const prime2 = 0x85ebca77;
|
|
10
|
+
const prime3 = 0xc2b2ae3d;
|
|
11
|
+
const prime4 = 0x27d4eb2f;
|
|
12
|
+
const prime5 = 0x165667b1;
|
|
13
|
+
|
|
14
|
+
// Utility functions/primitives
|
|
15
|
+
// --
|
|
16
|
+
function rotl32(x: number, r: number): number {
|
|
17
|
+
x = x | 0;
|
|
18
|
+
r = r | 0;
|
|
19
|
+
|
|
20
|
+
return (x >>> ((32 - r) | 0)) | (x << r) | 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function rotmul32(h: number, r: number, m: number): number {
|
|
24
|
+
h = h | 0;
|
|
25
|
+
r = r | 0;
|
|
26
|
+
m = m | 0;
|
|
27
|
+
|
|
28
|
+
return util.imul((h >>> ((32 - r) | 0)) | (h << r), m) | 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function shiftxor32(h: number, s: number): number {
|
|
32
|
+
h = h | 0;
|
|
33
|
+
s = s | 0;
|
|
34
|
+
|
|
35
|
+
return ((h >>> s) ^ h) | 0;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Implementation
|
|
39
|
+
// --
|
|
40
|
+
|
|
41
|
+
function xxhapply(h: number, src: number, m0: number, s: number, m1: number): number {
|
|
42
|
+
return rotmul32(util.imul(src, m0) + h, s, m1);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function xxh1(h: number, src: Uint8Array, index: number): number {
|
|
46
|
+
return rotmul32(h + util.imul(src[index], prime5), 11, prime1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function xxh4(h: number, src: Uint8Array, index: number): number {
|
|
50
|
+
return xxhapply(h, util.readU32(src, index), prime3, 17, prime4);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function xxh16(h: number[], src: Uint8Array, index: number): number[] {
|
|
54
|
+
return [
|
|
55
|
+
xxhapply(h[0], util.readU32(src, index + 0), prime2, 13, prime1),
|
|
56
|
+
xxhapply(h[1], util.readU32(src, index + 4), prime2, 13, prime1),
|
|
57
|
+
xxhapply(h[2], util.readU32(src, index + 8), prime2, 13, prime1),
|
|
58
|
+
xxhapply(h[3], util.readU32(src, index + 12), prime2, 13, prime1),
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function xxh32(seed: number, src: Uint8Array, index: number, len: number): number {
|
|
63
|
+
let h;
|
|
64
|
+
const l = len;
|
|
65
|
+
if (len >= 16) {
|
|
66
|
+
h = [seed + prime1 + prime2, seed + prime2, seed, seed - prime1];
|
|
67
|
+
|
|
68
|
+
while (len >= 16) {
|
|
69
|
+
h = xxh16(h, src, index);
|
|
70
|
+
|
|
71
|
+
index += 16;
|
|
72
|
+
len -= 16;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
h = rotl32(h[0], 1) + rotl32(h[1], 7) + rotl32(h[2], 12) + rotl32(h[3], 18) + l;
|
|
76
|
+
} else {
|
|
77
|
+
h = (seed + prime5 + len) >>> 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
while (len >= 4) {
|
|
81
|
+
h = xxh4(h, src, index);
|
|
82
|
+
|
|
83
|
+
index += 4;
|
|
84
|
+
len -= 4;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
while (len > 0) {
|
|
88
|
+
h = xxh1(h, src, index);
|
|
89
|
+
|
|
90
|
+
index++;
|
|
91
|
+
len--;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
h = shiftxor32(util.imul(shiftxor32(util.imul(shiftxor32(h, 15), prime2), 13), prime3), 16);
|
|
95
|
+
|
|
96
|
+
return h >>> 0;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const hash = xxh32;
|