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.
Files changed (47) hide show
  1. package/.agents/skills/mlclaw/SKILL.md +214 -0
  2. package/.agents/skills/mlclaw/agents/openai.yaml +4 -0
  3. package/.gitattributes +35 -0
  4. package/Dockerfile +45 -0
  5. package/LICENSE +21 -0
  6. package/README.md +206 -0
  7. package/assets/mlclaw.svg +143 -0
  8. package/dist/hf-state-sync.js +9532 -0
  9. package/dist/mlclaw-space-runtime.js +5010 -0
  10. package/dist/mlclaw.mjs +16502 -0
  11. package/entrypoint.sh +87 -0
  12. package/mlclaw.ps1 +108 -0
  13. package/mlclaw.sh +117 -0
  14. package/openclaw.default.json +67 -0
  15. package/package.json +66 -0
  16. package/scripts/configure-huggingface-model.mjs +86 -0
  17. package/scripts/configure-telegram.mjs +55 -0
  18. package/scripts/report-telegram-probe.mjs +18 -0
  19. package/space/README.md +42 -0
  20. package/src/hf-bucket-client/client.ts +217 -0
  21. package/src/hf-state-sync/archive.ts +137 -0
  22. package/src/hf-state-sync/cli.ts +92 -0
  23. package/src/hf-state-sync/hub.ts +81 -0
  24. package/src/hf-state-sync/manifest.ts +67 -0
  25. package/src/hf-state-sync/paths.ts +73 -0
  26. package/src/hf-state-sync/restore.ts +109 -0
  27. package/src/hf-state-sync/snapshot.ts +133 -0
  28. package/src/hf-state-sync/sqlite.ts +57 -0
  29. package/src/hf-state-sync/supervise.ts +256 -0
  30. package/src/vendor/hfjs-xet/error.ts +52 -0
  31. package/src/vendor/hfjs-xet/types/public.ts +207 -0
  32. package/src/vendor/hfjs-xet/utils/ChunkCache.ts +102 -0
  33. package/src/vendor/hfjs-xet/utils/RangeList.ts +182 -0
  34. package/src/vendor/hfjs-xet/utils/SplicedBlob.ts +249 -0
  35. package/src/vendor/hfjs-xet/utils/XetBlob.ts +732 -0
  36. package/src/vendor/hfjs-xet/utils/checkCredentials.ts +21 -0
  37. package/src/vendor/hfjs-xet/utils/combineUint8Arrays.ts +13 -0
  38. package/src/vendor/hfjs-xet/utils/createXorbs.ts +782 -0
  39. package/src/vendor/hfjs-xet/utils/shardParser.ts +152 -0
  40. package/src/vendor/hfjs-xet/utils/sum.ts +9 -0
  41. package/src/vendor/hfjs-xet/utils/uploadShards.ts +443 -0
  42. package/src/vendor/hfjs-xet/utils/xetWriteToken.ts +101 -0
  43. package/src/vendor/hfjs-xet/vendor/lz4js/index.ts +540 -0
  44. package/src/vendor/hfjs-xet/vendor/lz4js/util.ts +57 -0
  45. package/src/vendor/hfjs-xet/vendor/lz4js/xxh32.ts +99 -0
  46. package/src/vendor/hfjs-xet/vendor/type-fest/basic.ts +34 -0
  47. 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;