@loaders.gl/zip 4.1.0-alpha.3 → 4.1.0-alpha.5

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 (34) hide show
  1. package/dist/dist.dev.js +198 -38
  2. package/dist/hash-file-utility.d.ts +6 -0
  3. package/dist/hash-file-utility.d.ts.map +1 -1
  4. package/dist/hash-file-utility.js +22 -0
  5. package/dist/hash-file-utility.js.map +1 -1
  6. package/dist/index.cjs +165 -48
  7. package/dist/index.d.ts +2 -1
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +2 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/parse-zip/cd-file-header.d.ts +1 -1
  12. package/dist/parse-zip/cd-file-header.js +2 -2
  13. package/dist/parse-zip/cd-file-header.js.map +1 -1
  14. package/dist/parse-zip/end-of-central-directory.d.ts +19 -0
  15. package/dist/parse-zip/end-of-central-directory.d.ts.map +1 -1
  16. package/dist/parse-zip/end-of-central-directory.js +41 -8
  17. package/dist/parse-zip/end-of-central-directory.js.map +1 -1
  18. package/dist/parse-zip/zip-compozition.d.ts +8 -0
  19. package/dist/parse-zip/zip-compozition.d.ts.map +1 -0
  20. package/dist/parse-zip/zip-compozition.js +43 -0
  21. package/dist/parse-zip/zip-compozition.js.map +1 -0
  22. package/dist/parse-zip/zip64-info-generation.d.ts +1 -1
  23. package/dist/parse-zip/zip64-info-generation.d.ts.map +1 -1
  24. package/dist/parse-zip/zip64-info-generation.js +1 -1
  25. package/dist/parse-zip/zip64-info-generation.js.map +1 -1
  26. package/dist/zip-loader.js +1 -1
  27. package/dist/zip-writer.js +1 -1
  28. package/package.json +5 -5
  29. package/src/hash-file-utility.ts +46 -1
  30. package/src/index.ts +2 -1
  31. package/src/parse-zip/cd-file-header.ts +3 -3
  32. package/src/parse-zip/end-of-central-directory.ts +97 -8
  33. package/src/parse-zip/zip-compozition.ts +113 -0
  34. package/src/parse-zip/zip64-info-generation.ts +2 -2
package/dist/dist.dev.js CHANGED
@@ -6956,6 +6956,8 @@ var __exports__ = (() => {
6956
6956
  ZipFileSystem: () => ZipFileSystem,
6957
6957
  ZipLoader: () => ZipLoader,
6958
6958
  ZipWriter: () => ZipWriter,
6959
+ addOneFile: () => addOneFile,
6960
+ composeHashFile: () => composeHashFile,
6959
6961
  generateCDHeader: () => generateCDHeader,
6960
6962
  generateLocalHeader: () => generateLocalHeader,
6961
6963
  localHeaderSignature: () => signature3,
@@ -6970,7 +6972,7 @@ var __exports__ = (() => {
6970
6972
 
6971
6973
  // src/zip-loader.ts
6972
6974
  var import_jszip = __toESM(require_jszip_min(), 1);
6973
- var VERSION = true ? "4.1.0-alpha.3" : "latest";
6975
+ var VERSION = true ? "4.1.0-alpha.5" : "latest";
6974
6976
  var ZipLoader = {
6975
6977
  id: "zip",
6976
6978
  module: "zip",
@@ -7015,7 +7017,7 @@ var __exports__ = (() => {
7015
7017
 
7016
7018
  // src/zip-writer.ts
7017
7019
  var import_jszip2 = __toESM(require_jszip_min(), 1);
7018
- var VERSION2 = true ? "4.1.0-alpha.3" : "latest";
7020
+ var VERSION2 = true ? "4.1.0-alpha.5" : "latest";
7019
7021
  var ZipWriter = {
7020
7022
  name: "Zip Archive",
7021
7023
  id: "zip",
@@ -7467,39 +7469,6 @@ var __exports__ = (() => {
7467
7469
  return targetOffset;
7468
7470
  };
7469
7471
 
7470
- // src/parse-zip/end-of-central-directory.ts
7471
- var eoCDSignature = new Uint8Array([80, 75, 5, 6]);
7472
- var zip64EoCDLocatorSignature = new Uint8Array([80, 75, 6, 7]);
7473
- var zip64EoCDSignature = new Uint8Array([80, 75, 6, 6]);
7474
- var CD_RECORDS_NUMBER_OFFSET = 8n;
7475
- var CD_START_OFFSET_OFFSET = 16n;
7476
- var ZIP64_EOCD_START_OFFSET_OFFSET = 8n;
7477
- var ZIP64_CD_RECORDS_NUMBER_OFFSET = 24n;
7478
- var ZIP64_CD_START_OFFSET_OFFSET = 48n;
7479
- var parseEoCDRecord = async (file) => {
7480
- const zipEoCDOffset = await searchFromTheEnd(file, eoCDSignature);
7481
- let cdRecordsNumber = BigInt(await file.getUint16(zipEoCDOffset + CD_RECORDS_NUMBER_OFFSET));
7482
- let cdStartOffset = BigInt(await file.getUint32(zipEoCDOffset + CD_START_OFFSET_OFFSET));
7483
- if (cdStartOffset === BigInt(4294967295) || cdRecordsNumber === BigInt(4294967295)) {
7484
- const zip64EoCDLocatorOffset = zipEoCDOffset - 20n;
7485
- const magicBytes = await file.slice(zip64EoCDLocatorOffset, zip64EoCDLocatorOffset + 4n);
7486
- if (!compareArrayBuffers(magicBytes, zip64EoCDLocatorSignature)) {
7487
- throw new Error("zip64 EoCD locator not found");
7488
- }
7489
- const zip64EoCDOffset = await file.getBigUint64(zip64EoCDLocatorOffset + ZIP64_EOCD_START_OFFSET_OFFSET);
7490
- const endOfCDMagicBytes = await file.slice(zip64EoCDOffset, zip64EoCDOffset + 4n);
7491
- if (!compareArrayBuffers(endOfCDMagicBytes, zip64EoCDSignature.buffer)) {
7492
- throw new Error("zip64 EoCD not found");
7493
- }
7494
- cdRecordsNumber = await file.getBigUint64(zip64EoCDOffset + ZIP64_CD_RECORDS_NUMBER_OFFSET);
7495
- cdStartOffset = await file.getBigUint64(zip64EoCDOffset + ZIP64_CD_START_OFFSET_OFFSET);
7496
- }
7497
- return {
7498
- cdRecordsNumber,
7499
- cdStartOffset
7500
- };
7501
- };
7502
-
7503
7472
  // src/parse-zip/zip64-info-generation.ts
7504
7473
  var signature = new Uint8Array([1, 0]);
7505
7474
  function createZip64Info(options) {
@@ -7519,7 +7488,7 @@ var __exports__ = (() => {
7519
7488
  return concatenateArrayBuffers(...arraysToConcat);
7520
7489
  }
7521
7490
  function setFieldToNumber(header, fieldSize, fieldOffset, value) {
7522
- NUMBER_SETTERS[fieldSize](header, fieldOffset, value);
7491
+ NUMBER_SETTERS[fieldSize](header, Number(fieldOffset), value);
7523
7492
  }
7524
7493
  var NUMBER_SETTERS = {
7525
7494
  2: (header, offset, value) => {
@@ -7549,6 +7518,71 @@ var __exports__ = (() => {
7549
7518
  name: "offset"
7550
7519
  }];
7551
7520
 
7521
+ // src/parse-zip/end-of-central-directory.ts
7522
+ var eoCDSignature = new Uint8Array([80, 75, 5, 6]);
7523
+ var zip64EoCDLocatorSignature = new Uint8Array([80, 75, 6, 7]);
7524
+ var zip64EoCDSignature = new Uint8Array([80, 75, 6, 6]);
7525
+ var CD_RECORDS_NUMBER_OFFSET = 8n;
7526
+ var CD_RECORDS_NUMBER_ON_DISC_OFFSET = 10n;
7527
+ var CD_CD_BYTE_SIZE_OFFSET = 12n;
7528
+ var CD_START_OFFSET_OFFSET = 16n;
7529
+ var ZIP64_EOCD_START_OFFSET_OFFSET = 8n;
7530
+ var ZIP64_CD_RECORDS_NUMBER_OFFSET = 24n;
7531
+ var ZIP64_CD_RECORDS_NUMBER_ON_DISC_OFFSET = 32n;
7532
+ var ZIP64_CD_CD_BYTE_SIZE_OFFSET = 40n;
7533
+ var ZIP64_CD_START_OFFSET_OFFSET = 48n;
7534
+ var parseEoCDRecord = async (file) => {
7535
+ const zipEoCDOffset = await searchFromTheEnd(file, eoCDSignature);
7536
+ let cdRecordsNumber = BigInt(await file.getUint16(zipEoCDOffset + CD_RECORDS_NUMBER_OFFSET));
7537
+ let cdStartOffset = BigInt(await file.getUint32(zipEoCDOffset + CD_START_OFFSET_OFFSET));
7538
+ let zip64EoCDLocatorOffset = zipEoCDOffset - 20n;
7539
+ let zip64EoCDOffset = 0n;
7540
+ const magicBytes = await file.slice(zip64EoCDLocatorOffset, zip64EoCDLocatorOffset + 4n);
7541
+ if (compareArrayBuffers(magicBytes, zip64EoCDLocatorSignature)) {
7542
+ zip64EoCDOffset = await file.getBigUint64(zip64EoCDLocatorOffset + ZIP64_EOCD_START_OFFSET_OFFSET);
7543
+ const endOfCDMagicBytes = await file.slice(zip64EoCDOffset, zip64EoCDOffset + 4n);
7544
+ if (!compareArrayBuffers(endOfCDMagicBytes, zip64EoCDSignature.buffer)) {
7545
+ throw new Error("zip64 EoCD not found");
7546
+ }
7547
+ cdRecordsNumber = await file.getBigUint64(zip64EoCDOffset + ZIP64_CD_RECORDS_NUMBER_OFFSET);
7548
+ cdStartOffset = await file.getBigUint64(zip64EoCDOffset + ZIP64_CD_START_OFFSET_OFFSET);
7549
+ } else {
7550
+ zip64EoCDLocatorOffset = 0n;
7551
+ }
7552
+ return {
7553
+ cdRecordsNumber,
7554
+ cdStartOffset,
7555
+ offsets: {
7556
+ zip64EoCDOffset,
7557
+ zip64EoCDLocatorOffset,
7558
+ zipEoCDOffset
7559
+ }
7560
+ };
7561
+ };
7562
+ async function updateEoCD(eocdBody, oldEoCDOffsets, newCDStartOffset, eocdStartOffset, newCDRecordsNumber) {
7563
+ const eocd = new DataView(eocdBody);
7564
+ const classicEoCDOffset = oldEoCDOffsets.zip64EoCDOffset ? oldEoCDOffsets.zipEoCDOffset - oldEoCDOffsets.zip64EoCDOffset : 0n;
7565
+ if (Number(newCDRecordsNumber) <= 65535) {
7566
+ setFieldToNumber(eocd, 2, classicEoCDOffset + CD_RECORDS_NUMBER_OFFSET, newCDRecordsNumber);
7567
+ setFieldToNumber(eocd, 2, classicEoCDOffset + CD_RECORDS_NUMBER_ON_DISC_OFFSET, newCDRecordsNumber);
7568
+ }
7569
+ if (eocdStartOffset - newCDStartOffset <= 4294967295) {
7570
+ setFieldToNumber(eocd, 4, classicEoCDOffset + CD_CD_BYTE_SIZE_OFFSET, eocdStartOffset - newCDStartOffset);
7571
+ }
7572
+ if (newCDStartOffset < 4294967295) {
7573
+ setFieldToNumber(eocd, 4, classicEoCDOffset + CD_START_OFFSET_OFFSET, newCDStartOffset);
7574
+ }
7575
+ if (oldEoCDOffsets.zip64EoCDLocatorOffset && oldEoCDOffsets.zip64EoCDOffset) {
7576
+ const locatorOffset = oldEoCDOffsets.zip64EoCDLocatorOffset - oldEoCDOffsets.zip64EoCDOffset;
7577
+ setFieldToNumber(eocd, 8, locatorOffset + ZIP64_EOCD_START_OFFSET_OFFSET, eocdStartOffset);
7578
+ setFieldToNumber(eocd, 8, ZIP64_CD_START_OFFSET_OFFSET, newCDStartOffset);
7579
+ setFieldToNumber(eocd, 8, ZIP64_CD_RECORDS_NUMBER_OFFSET, newCDRecordsNumber);
7580
+ setFieldToNumber(eocd, 8, ZIP64_CD_RECORDS_NUMBER_ON_DISC_OFFSET, newCDRecordsNumber);
7581
+ setFieldToNumber(eocd, 8, ZIP64_CD_CD_BYTE_SIZE_OFFSET, eocdStartOffset - newCDStartOffset);
7582
+ }
7583
+ return new Uint8Array(eocd.buffer);
7584
+ }
7585
+
7552
7586
  // src/parse-zip/cd-file-header.ts
7553
7587
  var CD_COMPRESSED_SIZE_OFFSET = 20n;
7554
7588
  var CD_UNCOMPRESSED_SIZE_OFFSET = 24n;
@@ -7656,7 +7690,7 @@ var __exports__ = (() => {
7656
7690
  const optionsToZip64 = {};
7657
7691
  if (optionsToUse.offset >= 4294967295) {
7658
7692
  optionsToZip64.offset = optionsToUse.offset;
7659
- optionsToUse.offset = 4294967295;
7693
+ optionsToUse.offset = BigInt(4294967295);
7660
7694
  }
7661
7695
  if (optionsToUse.length >= 4294967295) {
7662
7696
  optionsToZip64.size = optionsToUse.length;
@@ -7666,7 +7700,7 @@ var __exports__ = (() => {
7666
7700
  zip64header = createZip64Info(optionsToZip64);
7667
7701
  optionsToUse.extraLength = zip64header.byteLength;
7668
7702
  }
7669
- const header = new DataView(new ArrayBuffer(46));
7703
+ const header = new DataView(new ArrayBuffer(Number(CD_FILE_NAME_OFFSET)));
7670
7704
  for (const field of ZIP_HEADER_FIELDS) {
7671
7705
  setFieldToNumber(header, field.size, field.offset, optionsToUse[field.name ?? ""] ?? field.default ?? 0);
7672
7706
  }
@@ -7883,6 +7917,29 @@ var __exports__ = (() => {
7883
7917
  }
7884
7918
  };
7885
7919
 
7920
+ // ../crypto/src/lib/algorithms/crc32.ts
7921
+ var CRC32 = class {
7922
+ constructor() {
7923
+ this.crc = ~0;
7924
+ }
7925
+ update(arrayBuffer) {
7926
+ const CRC32_TABLE = getCRC32Table();
7927
+ const byteArray = new Uint8Array(arrayBuffer);
7928
+ for (let i = 0; i < byteArray.byteLength; i++) {
7929
+ this.crc = this.crc >>> 8 ^ CRC32_TABLE[(this.crc ^ byteArray[i]) & 255];
7930
+ }
7931
+ return this;
7932
+ }
7933
+ finalize() {
7934
+ this.crc = (this.crc ^ -1) >>> 0;
7935
+ return this.crc;
7936
+ }
7937
+ };
7938
+ var CRC32TAB = Uint32Array.of(0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685, 2657392035, 249268274, 2044508324, 3772115230, 2547177864, 162941995, 2125561021, 3887607047, 2428444049, 498536548, 1789927666, 4089016648, 2227061214, 450548861, 1843258603, 4107580753, 2211677639, 325883990, 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755, 2366115317, 997073096, 1281953886, 3579855332, 2724688242, 1006888145, 1258607687, 3524101629, 2768942443, 901097722, 1119000684, 3686517206, 2898065728, 853044451, 1172266101, 3705015759, 2882616665, 651767980, 1373503546, 3369554304, 3218104598, 565507253, 1454621731, 3485111705, 3099436303, 671266974, 1594198024, 3322730930, 2970347812, 795835527, 1483230225, 3244367275, 3060149565, 1994146192, 31158534, 2563907772, 4023717930, 1907459465, 112637215, 2680153253, 3904427059, 2013776290, 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719, 3865271297, 1802195444, 476864866, 2238001368, 4066508878, 1812370925, 453092731, 2181625025, 4111451223, 1706088902, 314042704, 2344532202, 4240017532, 1658658271, 366619977, 2362670323, 4224994405, 1303535960, 984961486, 2747007092, 3569037538, 1256170817, 1037604311, 2765210733, 3554079995, 1131014506, 879679996, 2909243462, 3663771856, 1141124467, 855842277, 2852801631, 3708648649, 1342533948, 654459306, 3188396048, 3373015174, 1466479909, 544179635, 3110523913, 3462522015, 1591671054, 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443, 3233442989, 3988292384, 2596254646, 62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523, 3814918930, 2489596804, 225274430, 2053790376, 3826175755, 2466906013, 167816743, 2097651377, 4027552580, 2265490386, 503444072, 1762050814, 4150417245, 2154129355, 426522225, 1852507879, 4275313526, 2312317920, 282753626, 1742555852, 4189708143, 2394877945, 397917763, 1622183637, 3604390888, 2714866558, 953729732, 1340076626, 3518719985, 2797360999, 1068828381, 1219638859, 3624741850, 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135, 1181335161, 3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3138078467, 570562233, 1426400815, 3317316542, 2998733608, 733239954, 1555261956, 3268935591, 3050360625, 752459403, 1541320221, 2607071920, 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877, 83908371, 2512341634, 3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2094854071, 198958881, 2262029012, 4057260610, 1759359992, 534414190, 2176718541, 4139329115, 1873836001, 414664567, 2282248934, 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795, 376229701, 2685067896, 3608007406, 1308918612, 956543938, 2808555105, 3495958263, 1231636301, 1047427035, 2932959818, 3654703836, 1088359270, 936918e3, 2847714899, 3736837829, 1202900863, 817233897, 3183342108, 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449, 601450431, 3009837614, 3294710456, 1567103746, 711928724, 3020668471, 3272380065, 1510334235, 755167117);
7939
+ function getCRC32Table() {
7940
+ return CRC32TAB;
7941
+ }
7942
+
7886
7943
  // ../crypto/src/lib/utils/base64-utils.ts
7887
7944
  function asciiToBase64(string) {
7888
7945
  string = `${string}`;
@@ -7934,6 +7991,16 @@ var __exports__ = (() => {
7934
7991
  }
7935
7992
 
7936
7993
  // ../crypto/src/lib/utils/digest-utils.ts
7994
+ function encodeNumber(number, encoding) {
7995
+ switch (encoding) {
7996
+ case "hex":
7997
+ return convertNumberToHex(number);
7998
+ case "base64":
7999
+ return convertHexToBase64(convertNumberToHex(number));
8000
+ default:
8001
+ throw new Error(encoding);
8002
+ }
8003
+ }
7937
8004
  function encodeHex(hex, encoding) {
7938
8005
  switch (encoding) {
7939
8006
  case "hex":
@@ -7952,6 +8019,43 @@ var __exports__ = (() => {
7952
8019
  const string = matches2.map((a) => String.fromCharCode(parseInt(a, 16))).join("");
7953
8020
  return asciiToBase64(string) || "";
7954
8021
  }
8022
+ function convertNumberToHex(cipher) {
8023
+ const hexString = cipher.toString(16);
8024
+ return hexString === "0" ? `0${hexString}` : hexString;
8025
+ }
8026
+
8027
+ // ../crypto/src/lib/crc32-hash.ts
8028
+ var CRC32Hash = class extends Hash {
8029
+ name = "crc32";
8030
+ constructor(options = {}) {
8031
+ super();
8032
+ this.options = {
8033
+ crypto: {},
8034
+ ...options
8035
+ };
8036
+ this.hashBatches = this.hashBatches.bind(this);
8037
+ }
8038
+ async hash(input, encoding) {
8039
+ return this.hashSync(input, encoding);
8040
+ }
8041
+ hashSync(input, encoding) {
8042
+ const hash = new CRC32();
8043
+ hash.update(input);
8044
+ const digest = hash.finalize();
8045
+ return encodeNumber(digest, encoding);
8046
+ }
8047
+ async *hashBatches(asyncIterator, encoding = "base64") {
8048
+ const hash = new CRC32();
8049
+ for await (const chunk of asyncIterator) {
8050
+ hash.update(chunk);
8051
+ yield chunk;
8052
+ }
8053
+ const digest = hash.finalize();
8054
+ this.options.crypto?.onEnd?.({
8055
+ hash: encodeNumber(digest, encoding)
8056
+ });
8057
+ }
8058
+ };
7955
8059
 
7956
8060
  // ../crypto/src/lib/algorithms/md5-wasm.ts
7957
8061
  var atb = typeof atob === "function" ? atob : typeof Buffer === "function" ? nodeATOB : identity;
@@ -8376,6 +8480,45 @@ var __exports__ = (() => {
8376
8480
  }
8377
8481
  };
8378
8482
 
8483
+ // src/parse-zip/zip-compozition.ts
8484
+ async function cutTheTailOff(provider) {
8485
+ const oldEoCDinfo = await parseEoCDRecord(provider);
8486
+ const oldCDStartOffset = oldEoCDinfo.cdStartOffset;
8487
+ const oldCDLength = Number(oldEoCDinfo.offsets.zip64EoCDOffset ? oldEoCDinfo.offsets.zip64EoCDOffset - oldCDStartOffset : oldEoCDinfo.offsets.zipEoCDOffset - oldCDStartOffset);
8488
+ const zipEnding = await provider.slice(oldCDStartOffset, provider.length);
8489
+ await provider.truncate(Number(oldCDStartOffset));
8490
+ const oldCDBody = zipEnding.slice(0, oldCDLength);
8491
+ const eocdBody = zipEnding.slice(oldCDLength, zipEnding.byteLength);
8492
+ return [oldCDBody, eocdBody, oldEoCDinfo];
8493
+ }
8494
+ async function generateFileHeaders(fileName, fileToAdd, localFileHeaderOffset) {
8495
+ const newFileCRC322 = parseInt(await new CRC32Hash().hash(fileToAdd, "hex"), 16);
8496
+ const newFileLocalHeader = generateLocalHeader({
8497
+ crc32: newFileCRC322,
8498
+ fileName,
8499
+ length: fileToAdd.byteLength
8500
+ });
8501
+ const newFileCDHeader = generateCDHeader({
8502
+ crc32: newFileCRC322,
8503
+ fileName,
8504
+ offset: localFileHeaderOffset,
8505
+ length: fileToAdd.byteLength
8506
+ });
8507
+ return [new Uint8Array(concatenateArrayBuffers(newFileLocalHeader, fileToAdd)), new Uint8Array(newFileCDHeader)];
8508
+ }
8509
+ async function addOneFile(zipUrl, fileToAdd, fileName) {
8510
+ const provider = new FileHandleFile(zipUrl, true);
8511
+ const [oldCDBody, eocdBody, oldEoCDinfo] = await cutTheTailOff(provider);
8512
+ const newFileOffset = provider.length;
8513
+ const [localPart, cdHeaderPart] = await generateFileHeaders(fileName, fileToAdd, newFileOffset);
8514
+ await provider.append(localPart);
8515
+ const newCDBody = concatenateArrayBuffers(oldCDBody, cdHeaderPart);
8516
+ const newCDStartOffset = provider.length;
8517
+ await provider.append(new Uint8Array(newCDBody));
8518
+ const eocdOffset = provider.length;
8519
+ await provider.append(await updateEoCD(eocdBody, oldEoCDinfo.offsets, newCDStartOffset, eocdOffset, oldEoCDinfo.cdRecordsNumber + 1n));
8520
+ }
8521
+
8379
8522
  // src/hash-file-utility.ts
8380
8523
  function parseHashTable(arrayBuffer) {
8381
8524
  const dataView = new DataView(arrayBuffer);
@@ -8403,6 +8546,23 @@ var __exports__ = (() => {
8403
8546
  }
8404
8547
  return hashTable;
8405
8548
  }
8549
+ async function composeHashFile(fileProvider) {
8550
+ const hashArray = await makeHashTableFromZipHeaders(fileProvider);
8551
+ const bufferArray = Object.entries(hashArray).map(([key, value]) => concatenateArrayBuffers(hexStringToBuffer(key), bigintToBuffer(value))).sort(compareHashes);
8552
+ return concatenateArrayBuffers(...bufferArray);
8553
+ }
8554
+ function compareHashes(arrA, arrB) {
8555
+ const a = new BigUint64Array(arrA);
8556
+ const b = new BigUint64Array(arrB);
8557
+ return Number(a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]);
8558
+ }
8559
+ function hexStringToBuffer(str) {
8560
+ const byteArray = str.match(/../g)?.map((h) => parseInt(h, 16));
8561
+ return new Uint8Array(byteArray ?? new Array(16)).buffer;
8562
+ }
8563
+ function bigintToBuffer(n) {
8564
+ return new BigUint64Array([n]).buffer;
8565
+ }
8406
8566
 
8407
8567
  // ../compression/src/lib/compression.ts
8408
8568
  var Compression = class {
@@ -11,4 +11,10 @@ export declare function parseHashTable(arrayBuffer: ArrayBuffer): Record<string,
11
11
  * @returns ready to use hash info
12
12
  */
13
13
  export declare function makeHashTableFromZipHeaders(fileProvider: FileProvider): Promise<Record<string, bigint>>;
14
+ /**
15
+ * creates hash file that later can be added to the SLPK archive
16
+ * @param fileProvider SLPK archive where we need to add hash file
17
+ * @returns ArrayBuffer containing hash file
18
+ */
19
+ export declare function composeHashFile(fileProvider: FileProvider): Promise<ArrayBuffer>;
14
20
  //# sourceMappingURL=hash-file-utility.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hash-file-utility.d.ts","sourceRoot":"","sources":["../src/hash-file-utility.ts"],"names":[],"mappings":"AAKA,OAAO,EAAC,YAAY,EAAC,MAAM,0BAA0B,CAAC;AAGtD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAY/E;AASD;;;;GAIG;AACH,wBAAsB,2BAA2B,CAC/C,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAejC"}
1
+ {"version":3,"file":"hash-file-utility.d.ts","sourceRoot":"","sources":["../src/hash-file-utility.ts"],"names":[],"mappings":"AAKA,OAAO,EAAC,YAAY,EAA0B,MAAM,0BAA0B,CAAC;AAG/E;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAY/E;AASD;;;;GAIG;AACH,wBAAsB,2BAA2B,CAC/C,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAejC;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAMtF"}
@@ -1,4 +1,5 @@
1
1
  import { MD5Hash } from '@loaders.gl/crypto';
2
+ import { concatenateArrayBuffers } from '@loaders.gl/loader-utils';
2
3
  import { makeZipCDHeaderIterator } from "./parse-zip/cd-file-header.js";
3
4
  export function parseHashTable(arrayBuffer) {
4
5
  const dataView = new DataView(arrayBuffer);
@@ -26,4 +27,25 @@ export async function makeHashTableFromZipHeaders(fileProvider) {
26
27
  }
27
28
  return hashTable;
28
29
  }
30
+ export async function composeHashFile(fileProvider) {
31
+ const hashArray = await makeHashTableFromZipHeaders(fileProvider);
32
+ const bufferArray = Object.entries(hashArray).map(_ref => {
33
+ let [key, value] = _ref;
34
+ return concatenateArrayBuffers(hexStringToBuffer(key), bigintToBuffer(value));
35
+ }).sort(compareHashes);
36
+ return concatenateArrayBuffers(...bufferArray);
37
+ }
38
+ function compareHashes(arrA, arrB) {
39
+ const a = new BigUint64Array(arrA);
40
+ const b = new BigUint64Array(arrB);
41
+ return Number(a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]);
42
+ }
43
+ function hexStringToBuffer(str) {
44
+ var _str$match;
45
+ const byteArray = (_str$match = str.match(/../g)) === null || _str$match === void 0 ? void 0 : _str$match.map(h => parseInt(h, 16));
46
+ return new Uint8Array(byteArray !== null && byteArray !== void 0 ? byteArray : new Array(16)).buffer;
47
+ }
48
+ function bigintToBuffer(n) {
49
+ return new BigUint64Array([n]).buffer;
50
+ }
29
51
  //# sourceMappingURL=hash-file-utility.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hash-file-utility.js","names":["MD5Hash","makeZipCDHeaderIterator","parseHashTable","arrayBuffer","dataView","DataView","hashMap","i","byteLength","offset","getBigUint64","hash","bufferToHex","buffer","start","length","Uint8Array","map","x","toString","padStart","join","makeHashTableFromZipHeaders","fileProvider","zipCDIterator","md5Hash","textEncoder","TextEncoder","hashTable","cdHeader","filename","fileName","split","toLocaleLowerCase","encode","md5","localHeaderOffset"],"sources":["../src/hash-file-utility.ts"],"sourcesContent":["// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {MD5Hash} from '@loaders.gl/crypto';\nimport {FileProvider} from '@loaders.gl/loader-utils';\nimport {makeZipCDHeaderIterator} from './parse-zip/cd-file-header';\n\n/**\n * Reads hash file from buffer and returns it in ready-to-use form\n * @param arrayBuffer - buffer containing hash file\n * @returns Map containing hash and offset\n */\nexport function parseHashTable(arrayBuffer: ArrayBuffer): Record<string, bigint> {\n const dataView = new DataView(arrayBuffer);\n\n const hashMap: Record<string, bigint> = {};\n\n for (let i = 0; i < arrayBuffer.byteLength; i = i + 24) {\n const offset = dataView.getBigUint64(i + 16, true);\n const hash = bufferToHex(arrayBuffer, i, 16);\n hashMap[hash] = offset;\n }\n\n return hashMap;\n}\n\nfunction bufferToHex(buffer: ArrayBuffer, start: number, length: number): string {\n // buffer is an ArrayBuffer\n return [...new Uint8Array(buffer, start, length)]\n .map((x) => x.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * generates hash info from zip files \"central directory\"\n * @param fileProvider - provider of the archive\n * @returns ready to use hash info\n */\nexport async function makeHashTableFromZipHeaders(\n fileProvider: FileProvider\n): Promise<Record<string, bigint>> {\n const zipCDIterator = makeZipCDHeaderIterator(fileProvider);\n const md5Hash = new MD5Hash();\n const textEncoder = new TextEncoder();\n\n const hashTable: Record<string, bigint> = {};\n\n for await (const cdHeader of zipCDIterator) {\n const filename = cdHeader.fileName.split('\\\\').join('/').toLocaleLowerCase();\n const arrayBuffer = textEncoder.encode(filename).buffer;\n const md5 = await md5Hash.hash(arrayBuffer, 'hex');\n hashTable[md5] = cdHeader.localHeaderOffset;\n }\n\n return hashTable;\n}\n"],"mappings":"AAIA,SAAQA,OAAO,QAAO,oBAAoB;AAAC,SAEnCC,uBAAuB;AAO/B,OAAO,SAASC,cAAcA,CAACC,WAAwB,EAA0B;EAC/E,MAAMC,QAAQ,GAAG,IAAIC,QAAQ,CAACF,WAAW,CAAC;EAE1C,MAAMG,OAA+B,GAAG,CAAC,CAAC;EAE1C,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGJ,WAAW,CAACK,UAAU,EAAED,CAAC,GAAGA,CAAC,GAAG,EAAE,EAAE;IACtD,MAAME,MAAM,GAAGL,QAAQ,CAACM,YAAY,CAACH,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC;IAClD,MAAMI,IAAI,GAAGC,WAAW,CAACT,WAAW,EAAEI,CAAC,EAAE,EAAE,CAAC;IAC5CD,OAAO,CAACK,IAAI,CAAC,GAAGF,MAAM;EACxB;EAEA,OAAOH,OAAO;AAChB;AAEA,SAASM,WAAWA,CAACC,MAAmB,EAAEC,KAAa,EAAEC,MAAc,EAAU;EAE/E,OAAO,CAAC,GAAG,IAAIC,UAAU,CAACH,MAAM,EAAEC,KAAK,EAAEC,MAAM,CAAC,CAAC,CAC9CE,GAAG,CAAEC,CAAC,IAAKA,CAAC,CAACC,QAAQ,CAAC,EAAE,CAAC,CAACC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAC3CC,IAAI,CAAC,EAAE,CAAC;AACb;AAOA,OAAO,eAAeC,2BAA2BA,CAC/CC,YAA0B,EACO;EACjC,MAAMC,aAAa,GAAGvB,uBAAuB,CAACsB,YAAY,CAAC;EAC3D,MAAME,OAAO,GAAG,IAAIzB,OAAO,CAAC,CAAC;EAC7B,MAAM0B,WAAW,GAAG,IAAIC,WAAW,CAAC,CAAC;EAErC,MAAMC,SAAiC,GAAG,CAAC,CAAC;EAE5C,WAAW,MAAMC,QAAQ,IAAIL,aAAa,EAAE;IAC1C,MAAMM,QAAQ,GAAGD,QAAQ,CAACE,QAAQ,CAACC,KAAK,CAAC,IAAI,CAAC,CAACX,IAAI,CAAC,GAAG,CAAC,CAACY,iBAAiB,CAAC,CAAC;IAC5E,MAAM9B,WAAW,GAAGuB,WAAW,CAACQ,MAAM,CAACJ,QAAQ,CAAC,CAACjB,MAAM;IACvD,MAAMsB,GAAG,GAAG,MAAMV,OAAO,CAACd,IAAI,CAACR,WAAW,EAAE,KAAK,CAAC;IAClDyB,SAAS,CAACO,GAAG,CAAC,GAAGN,QAAQ,CAACO,iBAAiB;EAC7C;EAEA,OAAOR,SAAS;AAClB"}
1
+ {"version":3,"file":"hash-file-utility.js","names":["MD5Hash","concatenateArrayBuffers","makeZipCDHeaderIterator","parseHashTable","arrayBuffer","dataView","DataView","hashMap","i","byteLength","offset","getBigUint64","hash","bufferToHex","buffer","start","length","Uint8Array","map","x","toString","padStart","join","makeHashTableFromZipHeaders","fileProvider","zipCDIterator","md5Hash","textEncoder","TextEncoder","hashTable","cdHeader","filename","fileName","split","toLocaleLowerCase","encode","md5","localHeaderOffset","composeHashFile","hashArray","bufferArray","Object","entries","_ref","key","value","hexStringToBuffer","bigintToBuffer","sort","compareHashes","arrA","arrB","a","BigUint64Array","b","Number","str","_str$match","byteArray","match","h","parseInt","Array","n"],"sources":["../src/hash-file-utility.ts"],"sourcesContent":["// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {MD5Hash} from '@loaders.gl/crypto';\nimport {FileProvider, concatenateArrayBuffers} from '@loaders.gl/loader-utils';\nimport {makeZipCDHeaderIterator} from './parse-zip/cd-file-header';\n\n/**\n * Reads hash file from buffer and returns it in ready-to-use form\n * @param arrayBuffer - buffer containing hash file\n * @returns Map containing hash and offset\n */\nexport function parseHashTable(arrayBuffer: ArrayBuffer): Record<string, bigint> {\n const dataView = new DataView(arrayBuffer);\n\n const hashMap: Record<string, bigint> = {};\n\n for (let i = 0; i < arrayBuffer.byteLength; i = i + 24) {\n const offset = dataView.getBigUint64(i + 16, true);\n const hash = bufferToHex(arrayBuffer, i, 16);\n hashMap[hash] = offset;\n }\n\n return hashMap;\n}\n\nfunction bufferToHex(buffer: ArrayBuffer, start: number, length: number): string {\n // buffer is an ArrayBuffer\n return [...new Uint8Array(buffer, start, length)]\n .map((x) => x.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * generates hash info from zip files \"central directory\"\n * @param fileProvider - provider of the archive\n * @returns ready to use hash info\n */\nexport async function makeHashTableFromZipHeaders(\n fileProvider: FileProvider\n): Promise<Record<string, bigint>> {\n const zipCDIterator = makeZipCDHeaderIterator(fileProvider);\n const md5Hash = new MD5Hash();\n const textEncoder = new TextEncoder();\n\n const hashTable: Record<string, bigint> = {};\n\n for await (const cdHeader of zipCDIterator) {\n const filename = cdHeader.fileName.split('\\\\').join('/').toLocaleLowerCase();\n const arrayBuffer = textEncoder.encode(filename).buffer;\n const md5 = await md5Hash.hash(arrayBuffer, 'hex');\n hashTable[md5] = cdHeader.localHeaderOffset;\n }\n\n return hashTable;\n}\n\n/**\n * creates hash file that later can be added to the SLPK archive\n * @param fileProvider SLPK archive where we need to add hash file\n * @returns ArrayBuffer containing hash file\n */\nexport async function composeHashFile(fileProvider: FileProvider): Promise<ArrayBuffer> {\n const hashArray = await makeHashTableFromZipHeaders(fileProvider);\n const bufferArray = Object.entries(hashArray)\n .map(([key, value]) => concatenateArrayBuffers(hexStringToBuffer(key), bigintToBuffer(value)))\n .sort(compareHashes);\n return concatenateArrayBuffers(...bufferArray);\n}\n\n/**\n * Function to compare md5 hashes according to https://github.com/Esri/i3s-spec/blob/master/docs/2.0/slpk_hashtable.pcsl.md\n * @param arrA first hash to compare\n * @param arrB second hash to compare\n * @returns 0 if equal, negative number if a<b, pozitive if a>b\n */\nfunction compareHashes(arrA: ArrayBuffer, arrB: ArrayBuffer): number {\n const a = new BigUint64Array(arrA);\n const b = new BigUint64Array(arrB);\n\n return Number(a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]);\n}\n\n/**\n * converts hex string to buffer\n * @param str hex string to convert\n * @returns conversion result\n */\nfunction hexStringToBuffer(str: string): ArrayBuffer {\n const byteArray = str.match(/../g)?.map((h) => parseInt(h, 16));\n return new Uint8Array(byteArray ?? new Array(16)).buffer;\n}\n\n/**\n * converts bigint to buffer\n * @param n bigint to convert\n * @returns convertion result\n */\nfunction bigintToBuffer(n: bigint): ArrayBuffer {\n return new BigUint64Array([n]).buffer;\n}\n"],"mappings":"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"}