sliftutils 1.7.67 → 1.7.69

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 (33) hide show
  1. package/dist/test.ts.cache +3 -3
  2. package/index.d.ts +68 -14
  3. package/package.json +1 -1
  4. package/storage/ArchivesDisk.d.ts +2 -2
  5. package/storage/ArchivesDisk.ts +8 -4
  6. package/storage/IArchives.d.ts +15 -2
  7. package/storage/IArchives.ts +19 -3
  8. package/storage/backblaze.d.ts +2 -2
  9. package/storage/backblaze.ts +20 -3
  10. package/storage/dist/ArchivesDisk.ts.cache +2 -2
  11. package/storage/dist/IArchives.ts.cache +3 -3
  12. package/storage/dist/backblaze.ts.cache +2 -2
  13. package/storage/remoteStorage/ArchivesRemote.d.ts +2 -2
  14. package/storage/remoteStorage/ArchivesRemote.ts +3 -3
  15. package/storage/remoteStorage/accessStats.d.ts +25 -0
  16. package/storage/remoteStorage/accessStats.ts +86 -0
  17. package/storage/remoteStorage/blobStore.d.ts +1 -0
  18. package/storage/remoteStorage/blobStore.ts +31 -12
  19. package/storage/remoteStorage/createArchives.d.ts +2 -2
  20. package/storage/remoteStorage/createArchives.ts +6 -3
  21. package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +2 -2
  22. package/storage/remoteStorage/dist/ArchivesUrl.ts.cache +2 -2
  23. package/storage/remoteStorage/dist/accessStats.ts.cache +78 -0
  24. package/storage/remoteStorage/dist/blobStore.ts.cache +2 -2
  25. package/storage/remoteStorage/dist/createArchives.ts.cache +2 -2
  26. package/storage/remoteStorage/dist/storageController.ts.cache +51 -14
  27. package/storage/remoteStorage/dist/storageServerState.ts.cache +25 -74
  28. package/storage/remoteStorage/storageController.d.ts +9 -1
  29. package/storage/remoteStorage/storageController.ts +52 -11
  30. package/storage/remoteStorage/storageServerState.d.ts +6 -3
  31. package/storage/remoteStorage/storageServerState.ts +46 -73
  32. package/test.ts +1 -1
  33. package/treeSummary.d.ts +31 -0
@@ -76,7 +76,7 @@ function summarize(files, weightBySize) {
76
76
  return summary.totalSize;
77
77
  return summary.count;
78
78
  },
79
- expectedOutputCount: SUMMARY_COUNT,
79
+ expectedOutputCount: 100,
80
80
  });
81
81
  let addStart = performance.now();
82
82
  for (let file of files) {
@@ -195,5 +195,5 @@ main().catch(e => {
195
195
  console.error((_a = e.stack) !== null && _a !== void 0 ? _a : e);
196
196
  process.exit(1);
197
197
  });
198
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHVDQUF5QjtBQUN6QiwyQ0FBNkI7QUFDN0Isa0VBQWlGO0FBQ2pGLG1EQUFnRDtBQUNoRCwrQ0FBNEM7QUFFNUMsTUFBTSxhQUFhLEdBQUcsRUFBRSxDQUFDO0FBQ3pCLE1BQU0sV0FBVyxHQUFHLEVBQUUsQ0FBQztBQUN2QixNQUFNLFNBQVMsR0FBRztJQUNkLGtCQUFrQjtJQUNsQixtQkFBbUI7SUFDbkIsMEJBQTBCO0lBQzFCLHFCQUFxQjtJQUNyQiw0QkFBNEI7Q0FDL0IsQ0FBQztBQUVGLGdGQUFnRjtBQUNoRixNQUFNLFVBQVUsR0FBRywyQ0FBMkMsQ0FBQztBQUsvRCxLQUFLLFVBQVUsWUFBWSxDQUFDLElBQWMsRUFBRSxNQUFrQjtJQUMxRCxLQUFLLElBQUksR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ25CLElBQUksUUFBUSxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLENBQUM7UUFDckQsTUFBTSxVQUFVLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUM1QyxDQUFDO0FBQ0wsQ0FBQztBQUVELEtBQUssVUFBVSxVQUFVLENBQUMsR0FBVyxFQUFFLFFBQWdCLEVBQUUsTUFBa0I7SUFDdkUsSUFBSSxPQUFPLEdBQUcsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUN0RSxLQUFLLElBQUksS0FBSyxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQ3hCLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztR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QyxDQUFDO0lBQ3BJLE9BQU8sS0FBSyxDQUFDO0FBQ2pCLENBQUM7QUFFRCxLQUFLLFVBQVUsSUFBSTtJQUNmLElBQUksS0FBSyxHQUFHLE1BQU0sUUFBUSxFQUFFLENBQUM7SUFDN0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLElBQUEscUJBQVksRUFBQyxLQUFLLENBQUMsTUFBTSxDQUFDLGVBQWUsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDMUYsU0FBUyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN2QixTQUFTLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzVCLENBQUM7QUFFRCxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUU7O0lBQ2IsT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFDLENBQVcsQ0FBQyxLQUFLLG1DQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDcEIsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IGZvcm1hdE51bWJlciwgZm9ybWF0VGltZSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2Zvcm1hdHRpbmcvZm9ybWF0XCI7XG5pbXBvcnQgeyBzb3J0IH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvbWlzY1wiO1xuaW1wb3J0IHsgVHJlZVN1bW1hcnkgfSBmcm9tIFwiLi90cmVlU3VtbWFyeVwiO1xuXG5jb25zdCBTVU1NQVJZX0NPVU5UID0gMzA7XG5jb25zdCBUSU1JTkdfUlVOUyA9IDIwO1xuY29uc3QgU0NBTl9ESVJTID0gW1xuICAgIFwiRDovcmVwb3MvcXMtY3lvYVwiLFxuICAgIFwiRDovcmVwb3MvcXVlcnlzdWJcIixcbiAgICBcIkQ6L3JlcG9zL3NvY2tldC1mdW5jdGlvblwiLFxuICAgIFwiRDovcmVwb3Mvc2xpZnR1dGlsc1wiLFxuICAgIFwiRDovcmVwb3MvaW5mZXJlbmNlLXdlaWdodHNcIixcbl07XG5cbi8vIE1hdGNoZXMgdGhlIGdpdGlnbm9yZWQgXCJ0ZXN0Ki5qc29uXCIgcGF0dGVybiwgc28gdGhlIGNhY2hlIG5ldmVyIGdldHMgdHJhY2tlZC5cbmNvbnN0IENBQ0hFX0ZJTEUgPSBcIkQ6L3JlcG9zL3NsaWZ0dXRpbHMvdGVzdC1maWxlcy1jYWNoZS5qc29uXCI7XG5cbnR5cGUgRmlsZUluZm8gPSB7IHBhdGg6IHN0cmluZzsgc2l6ZTogbnVtYmVyIH07XG50eXBlIEZpbGVTdW1tYXJ5ID0geyBjb3VudDogbnVtYmVyOyB0b3RhbFNpemU6IG51bWJlciB9O1xuXG5hc3luYyBmdW5jdGlvbiBjb2xsZWN0RmlsZXMoZGlyczogc3RyaW5nW10sIG91dHB1dDogRmlsZUluZm9bXSkge1xuICAgIGZvciAobGV0IGRpciBvZiBkaXJzKSB7XG4gICAgICAgIGxldCBiYXNlUGF0aCA9IGRpci5lbmRzV2l0aChcIi9cIikgJiYgZGlyIHx8IGRpciArIFwiL1wiO1xuICAgICAgICBhd2FpdCBjb2xsZWN0RGlyKGRpciwgYmFzZVBhdGgsIG91dHB1dCk7XG4gICAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBjb2xsZWN0RGlyKGRpcjogc3RyaW5nLCBiYXNlUGF0aDogc3RyaW5nLCBvdXRwdXQ6IEZpbGVJbmZvW10pIHtcbiAgICBsZXQgZW50cmllcyA9IGF3YWl0IGZzLnByb21pc2VzLnJlYWRkaXIoZGlyLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSk7XG4gICAgZm9yIChsZXQgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgICBsZXQgZnVsbFBhdGggPSBwYXRoLmpvaW4oZGlyLCBlbnRyeS5uYW1lKTtcbiAgICAgICAgbGV0IGVudHJ5UGF0aCA9IGJhc2VQYXRoICsgZW50cnkubmFtZTtcbiAgICAgICAgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgICAgIGF3YWl0IGNvbGxlY3REaXIoZnVsbFBhdGgsIGVudHJ5UGF0aCArIFwiL1wiLCBvdXRwdXQpO1xuICAgICAgICB9IGVsc2UgaWYgKGVudHJ5LmlzRmlsZSgpKSB7XG4gICAgICAgICAgICBsZXQgc3RhdHMgPSBhd2FpdCBmcy5wcm9taXNlcy5zdGF0KGZ1bGxQYXRoKTtcbiAgICAgICAgICAgIG91dHB1dC5wdXNoKHsgcGF0aDogZW50cnlQYXRoLCBzaXplOiBzdGF0cy5zaXplIH0pO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBzdW1tYXJpemUoZmlsZXM6IEZpbGVJbmZvW10sIHdlaWdodEJ5U2l6ZTogYm9vbGVhbikge1xuICAgIGxldCB0cmVlID0gbmV3IFRyZWVTdW1tYXJ5PEZpbGVJbmZvLCBGaWxlU3VtbWFyeT4oe1xuICAgICAgICBnZXRQYXRoOiBmaWxlID0+IGZpbGUucGF0aCxcbiAgICAgICAgY3JlYXRlU3VtbWFyeTogKCkgPT4gKHsgY291bnQ6IDAsIHRvdGFsU2l6ZTogMCB9KSxcbiAgICAgICAgYWRkVG9TdW1tYXJ5OiAoZmlsZSwgc3VtbWFyeSkgPT4ge1xuICAgICAgICAgICAgc3VtbWFyeS5jb3VudCsrO1xuICAgICAgICAgICAgc3VtbWFyeS50b3RhbFNpemUgKz0gZmlsZS5zaXplO1xuICAgICAgICB9LFxuICAgICAgICBtZXJnZVN1bW1hcmllczogKHRhcmdldCwgc291cmNlKSA9PiB7XG4gICAgICAgICAgICB0YXJnZXQuY291bnQgKz0gc291cmNlLmNvdW50O1xuICAgICAgICAgICAgdGFyZ2V0LnRvdGFsU2l6ZSArPSBzb3VyY2UudG90YWxTaXplO1xuICAgICAgICB9LFxuICAgICAgICBnZXRXZWlnaHQ6IHN1bW1hcnkgPT4ge1xuICAgICAgICAgICAgaWYgKHdlaWdodEJ5U2l6ZSkgcmV0dXJuIHN1bW1hcnkudG90YWxTaXplO1xuICAgICAgICAgICAgcmV0dXJuIHN1bW1hcnkuY291bnQ7XG4gICAgICAgIH0sXG4gICAgICAgIGV4cGVjdGVkT3V0cHV0Q291bnQ6IFNVTU1BUllfQ09VTlQsXG4gICAgfSk7XG4gICAgbGV0IGFkZFN0YXJ0ID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgZm9yIChsZXQgZmlsZSBvZiBmaWxlcykge1xuICAgICAgICB0cmVlLmFkZChmaWxlKTtcbiAgICB9XG4gICAgbGV0IGFkZFRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKSAtIGFkZFN0YXJ0O1xuICAgIGxldCBxdWVyeVN0YXJ0ID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgbGV0IHN1bW1hcmllcyA9IHRyZWUuZ2V0U3VtbWFyaWVzKFNVTU1BUllfQ09VTlQpO1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgVElNSU5HX1JVTlM7IGkrKykge1xuICAgICAgICBzdW1tYXJpZXMgPSB0cmVlLmdldFN1bW1hcmllcyhTVU1NQVJZX0NPVU5UKTtcbiAgICB9XG4gICAgbGV0IHF1ZXJ5VGltZSA9IChwZXJmb3JtYW5jZS5ub3coKSAtIHF1ZXJ5U3RhcnQpIC8gVElNSU5HX1JVTlM7XG4gICAgbGV0IGxhYmVsID0gd2VpZ2h0QnlTaXplICYmIFwic2l6ZVwiIHx8IFwiY291bnRcIjtcbiAgICBjb25zb2xlLmxvZyhgXFxuPT09IHdlaWdodGVkIGJ5ICR7bGFiZWx9LCAke1NVTU1BUllfQ09VTlR9IGVudHJpZXMgPT09YCk7XG4gICAgY29uc29sZS5sb2coYGFkZDogJHtmb3JtYXRUaW1lKGFkZFRpbWUpfSB0b3RhbCBmb3IgJHtmb3JtYXROdW1iZXIoZmlsZXMubGVuZ3RoKX0gZmlsZXMsIHRyYWNraW5nICR7Zm9ybWF0TnVtYmVyKHRyZWUuZ2V0VHJhY2tlZE5vZGVDb3VudCgpKX0gbm9kZXMsIGdldFN1bW1hcmllczogJHtmb3JtYXRUaW1lKHF1ZXJ5VGltZSl9IGF2ZyBvdmVyICR7VElNSU5HX1JVTlN9IHJ1bnNgKTtcbiAgICBsZXQgdG90YWxXZWlnaHQgPSAwO1xuICAgIGZvciAobGV0IGVudHJ5IG9mIHN1bW1hcmllcykge1xuICAgICAgICB0b3RhbFdlaWdodCArPSBlbnRyeS53ZWlnaHQ7XG4gICAgfVxuICAgIHNvcnQoc3VtbWFyaWVzLCBlbnRyeSA9PiAtZW50cnkud2VpZ2h0KTtcbiAgICAvLyBWZXJpZnkgZWFjaCBlbnRyeSBhZ2FpbnN0IHRoZSByYXcgZmlsZSBsaXN0OiBhc3NpZ24gZXZlcnkgZmlsZSB0byBpdHMgbW9zdCBzcGVjaWZpYyBkaXNwbGF5ZWQgZW50cnkgKGV4YWN0IHBhdGhzIGJlYXQgcHJlZml4ZXMsIGxvbmdlciBwcmVmaXhlcyBiZWF0IHNob3J0ZXIpLCB3aGljaCBpcyB0aGUgcGFydGl0aW9uIHRoZSBlbnRyaWVzIGNsYWltIHRvIHJlcHJlc2VudC5cbiAgICBsZXQgYWN0dWFscyA9IHN1bW1hcmllcy5tYXAoKCkgPT4gKHsgY291bnQ6IDAsIHRvdGFsU2l6ZTogMCB9KSk7XG4gICAgbGV0IHVubWF0Y2hlZENvdW50ID0gMDtcbiAgICBsZXQgdW5tYXRjaGVkU2l6ZSA9IDA7XG4gICAgZm9yIChsZXQgZmlsZSBvZiBmaWxlcykge1xuICAgICAgICBsZXQgYmVzdEluZGV4ID0gLTE7XG4gICAgICAgIGxldCBiZXN0TGVuID0gLTE7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3VtbWFyaWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgZW50cnlQYXRoID0gc3VtbWFyaWVzW2ldLnBhdGg7XG4gICAgICAgICAgICBpZiAoZW50cnlQYXRoLmVuZHNXaXRoKFwiKlwiKSkge1xuICAgICAgICAgICAgICAgIGxldCBwcmVmaXggPSBlbnRyeVBhdGguc2xpY2UoMCwgLTEpO1xuICAgICAgICAgICAgICAgIGlmIChwcmVmaXgubGVuZ3RoID4gYmVzdExlbiAmJiBmaWxlLnBhdGguc3RhcnRzV2l0aChwcmVmaXgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGJlc3RJbmRleCA9IGk7XG4gICAgICAgICAgICAgICAgICAgIGJlc3RMZW4gPSBwcmVmaXgubGVuZ3RoO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZmlsZS5wYXRoID09PSBlbnRyeVBhdGggJiYgZW50cnlQYXRoLmxlbmd0aCArIDEgPiBiZXN0TGVuKSB7XG4gICAgICAgICAgICAgICAgYmVzdEluZGV4ID0gaTtcbiAgICAgICAgICAgICAgICBiZXN0TGVuID0gZW50cnlQYXRoLmxlbmd0aCArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJlc3RJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgIHVubWF0Y2hlZENvdW50Kys7XG4gICAgICAgICAgICB1bm1hdGNoZWRTaXplICs9IGZpbGUuc2l6ZTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGFjdHVhbHNbYmVzdEluZGV4XS5jb3VudCsrO1xuICAgICAgICBhY3R1YWxzW2Jlc3RJbmRleF0udG90YWxTaXplICs9IGZpbGUuc2l6ZTtcbiAgICB9XG4gICAgbGV0IHNob3duUGVyY2VudCA9IDA7XG4gICAgbGV0IHNwZWNpZmljUGVyY2VudCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdW1tYXJpZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IGVudHJ5ID0gc3VtbWFyaWVzW2ldO1xuICAgICAgICBsZXQgcGVyY2VudCA9IGVudHJ5LndlaWdodCAvIHRvdGFsV2VpZ2h0ICogMTAwO1xuICAgICAgICBzaG93blBlcmNlbnQgKz0gcGVyY2VudDtcbiAgICAgICAgaWYgKGVudHJ5LmtpbmQgPT09IFwic2VsZlwiIHx8IGVudHJ5LmtpbmQgPT09IFwic3VidHJlZVwiKSB7XG4gICAgICAgICAgICBzcGVjaWZpY1BlcmNlbnQgKz0gcGVyY2VudDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgYWN0dWFsID0gYWN0dWFsc1tpXTtcbiAgICAgICAgbGV0IGRpZmYgPSBcIlwiO1xuICAgICAgICBpZiAoYWN0dWFsLmNvdW50ICE9PSBlbnRyeS5zdW1tYXJ5LmNvdW50IHx8IGFjdHVhbC50b3RhbFNpemUgIT09IGVudHJ5LnN1bW1hcnkudG90YWxTaXplKSB7XG4gICAgICAgICAgICBkaWZmID0gYCAgRElGRiBhY3R1YWwgZmlsZXM9JHtmb3JtYXROdW1iZXIoYWN0dWFsLmNvdW50KX0gc2l6ZT0ke2Zvcm1hdE51bWJlcihhY3R1YWwudG90YWxTaXplKX1CYDtcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmxvZyhgJHtwZXJjZW50LnRvRml4ZWQoMSkucGFkU3RhcnQoNSl9JSAke2VudHJ5LnBhdGgucGFkRW5kKDYwKX0gZmlsZXM9JHtmb3JtYXROdW1iZXIoZW50cnkuc3VtbWFyeS5jb3VudCkucGFkU3RhcnQoNil9IHNpemU9JHsoZm9ybWF0TnVtYmVyKGVudHJ5LnN1bW1hcnkudG90YWxTaXplKSArIFwiQlwiKS5wYWRTdGFydCg4KX0ke2RpZmZ9YCk7XG4gICAgfVxuICAgIGlmICh1bm1hdGNoZWRDb3VudCA+IDApIHtcbiAgICAgICAgY29uc29sZS5sb2coYFVOTUFUQ0hFRDogJHtmb3JtYXROdW1iZXIodW5tYXRjaGVkQ291bnQpfSBmaWxlcyAoJHtmb3JtYXROdW1iZXIodW5tYXRjaGVkU2l6ZSl9QikgbWF0Y2hlZCBubyBkaXNwbGF5ZWQgZW50cnlgKTtcbiAgICB9XG4gICAgY29uc29sZS5sb2coYHRvcCAke3N1bW1hcmllcy5sZW5ndGh9IGVudHJpZXMgY292ZXIgJHtzaG93blBlcmNlbnQudG9GaXhlZCgxKX0lIChzcGVjaWZpYyBwYXRocyAke3NwZWNpZmljUGVyY2VudC50b0ZpeGVkKDEpfSUsIGNvbWJpbmVkIGxlZnRvdmVycyAkeyhzaG93blBlcmNlbnQgLSBzcGVjaWZpY1BlcmNlbnQpLnRvRml4ZWQoMSl9JSlgKTtcbiAgICAvLyBFbnRyaWVzIGFyZSBhIHN0cmljdCBwYXJ0aXRpb24gKGVhY2ggZmlsZSBpbiBleGFjdGx5IG9uZSBlbnRyeSksIHNvIHRoZXNlIG11c3QgbWF0Y2ggdGhlIHJlYWwgdG90YWxzIGV4YWN0bHkuXG4gICAgbGV0IGVudHJ5Q291bnQgPSAwO1xuICAgIGxldCBlbnRyeVNpemUgPSAwO1xuICAgIGZvciAobGV0IGVudHJ5IG9mIHN1bW1hcmllcykge1xuICAgICAgICBlbnRyeUNvdW50ICs9IGVudHJ5LnN1bW1hcnkuY291bnQ7XG4gICAgICAgIGVudHJ5U2l6ZSArPSBlbnRyeS5zdW1tYXJ5LnRvdGFsU2l6ZTtcbiAgICB9XG4gICAgbGV0IGFjdHVhbFNpemUgPSAwO1xuICAgIGZvciAobGV0IGZpbGUgb2YgZmlsZXMpIHtcbiAgICAgICAgYWN0dWFsU2l6ZSArPSBmaWxlLnNpemU7XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKGBlbnRyeSB0b3RhbHM6IGZpbGVzPSR7Zm9ybWF0TnVtYmVyKGVudHJ5Q291bnQpfSAoYWN0dWFsICR7Zm9ybWF0TnVtYmVyKGZpbGVzLmxlbmd0aCl9KSwgc2l6ZT0ke2Zvcm1hdE51bWJlcihlbnRyeVNpemUpfUIgKGFjdHVhbCAke2Zvcm1hdE51bWJlcihhY3R1YWxTaXplKX1CKWApO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRGaWxlcygpOiBQcm9taXNlPEZpbGVJbmZvW10+IHtcbiAgICB0cnkge1xuICAgICAgICBsZXQgY2FjaGVkID0gSlNPTi5wYXJzZShhd2FpdCBmcy5wcm9taXNlcy5yZWFkRmlsZShDQUNIRV9GSUxFLCBcInV0ZjhcIikpIGFzIHsgZGlyczogc3RyaW5nW107IGZpbGVzOiBGaWxlSW5mb1tdIH07XG4gICAgICAgIGlmIChKU09OLnN0cmluZ2lmeShjYWNoZWQuZGlycykgPT09IEpTT04uc3RyaW5naWZ5KFNDQU5fRElSUykpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBsb2FkZWQgJHtmb3JtYXROdW1iZXIoY2FjaGVkLmZpbGVzLmxlbmd0aCl9IGZpbGVzIGZyb20gY2FjaGUgJHtDQUNIRV9GSUxFfWApO1xuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZC5maWxlcztcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmxvZyhgY2FjaGUgZGlycyBjaGFuZ2VkIChjYWNoZWQgJHtKU09OLnN0cmluZ2lmeShjYWNoZWQuZGlycyl9LCBub3cgJHtKU09OLnN0cmluZ2lmeShTQ0FOX0RJUlMpfSksIHJlc2Nhbm5pbmdgKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgaWYgKChlcnIgYXMgeyBjb2RlPzogc3RyaW5nIH0pLmNvZGUgPT09IFwiRU5PRU5UXCIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBubyBjYWNoZSBmaWxlIGF0ICR7Q0FDSEVfRklMRX0sIHNjYW5uaW5nYCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgY2FjaGUgcmVhZCBmYWlsZWQsIHJlc2Nhbm5pbmc6YCwgKGVyciBhcyBFcnJvcikuc3RhY2sgPz8gZXJyKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBsZXQgZmlsZXM6IEZpbGVJbmZvW10gPSBbXTtcbiAgICBsZXQgc2NhblN0YXJ0ID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgYXdhaXQgY29sbGVjdEZpbGVzKFNDQU5fRElSUywgZmlsZXMpO1xuICAgIGF3YWl0IGZzLnByb21pc2VzLndyaXRlRmlsZShDQUNIRV9GSUxFLCBKU09OLnN0cmluZ2lmeSh7IGRpcnM6IFNDQU5fRElSUywgZmlsZXMgfSkpO1xuICAgIGNvbnNvbGUubG9nKGBzY2FubmVkICR7Zm9ybWF0TnVtYmVyKGZpbGVzLmxlbmd0aCl9IGZpbGVzIGluICR7Zm9ybWF0VGltZShwZXJmb3JtYW5jZS5ub3coKSAtIHNjYW5TdGFydCl9LCBjYWNoZWQgdG8gJHtDQUNIRV9GSUxFfWApO1xuICAgIHJldHVybiBmaWxlcztcbn1cblxuYXN5bmMgZnVuY3Rpb24gbWFpbigpIHtcbiAgICBsZXQgZmlsZXMgPSBhd2FpdCBnZXRGaWxlcygpO1xuICAgIGNvbnNvbGUubG9nKGBjb2xsZWN0ZWQgJHtmb3JtYXROdW1iZXIoZmlsZXMubGVuZ3RoKX0gZmlsZXMgZnJvbSAke1NDQU5fRElSUy5qb2luKFwiLCBcIil9YCk7XG4gICAgc3VtbWFyaXplKGZpbGVzLCB0cnVlKTtcbiAgICBzdW1tYXJpemUoZmlsZXMsIGZhbHNlKTtcbn1cblxubWFpbigpLmNhdGNoKGUgPT4ge1xuICAgIGNvbnNvbGUuZXJyb3IoKGUgYXMgRXJyb3IpLnN0YWNrID8/IGUpO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbn0pO1xuIl19
199
- /* _JS_SOURCE_HASH = "656b9eea92595d2b1164fb0d91cdd090fdb580dd665e47749657855c28eb87f8"; */
198
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHVDQUF5QjtBQUN6QiwyQ0FBNkI7QUFDN0Isa0VBQWlGO0FBQ2pGLG1EQUFnRDtBQUNoRCwrQ0FBNEM7QUFFNUMsTUFBTSxhQUFhLEdBQUcsRUFBRSxDQUFDO0FBQ3pCLE1BQU0sV0FBVyxHQUFHLEVBQUUsQ0FBQztBQUN2QixNQUFNLFNBQVMsR0FBRztJQUNkLGtCQUFrQjtJQUNsQixtQkFBbUI7SUFDbkIsMEJBQTBCO0lBQzFCLHFCQUFxQjtJQUNyQiw0QkFBNEI7Q0FDL0IsQ0FBQztBQUVGLGdGQUFnRjtBQUNoRixNQUFNLFVBQVUsR0FBRywyQ0FBMkMsQ0FBQztBQUsvRCxLQUFLLFVBQVUsWUFBWSxDQUFDLElBQWMsRUFBRSxNQUFrQjtJQUMxRCxLQUFLLElBQUksR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ25CLElBQUksUUFBUSxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLENBQUM7UUFDckQsTUFBTSxVQUFVLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUM1QyxDQUFDO0FBQ0wsQ0FBQztBQUVELEtBQUssVUFBVSxVQUFVLENBQUMsR0FBVyxFQUFFLFFBQWdCLEVBQUUsTUFBa0I7SUFDdkUsSUFBSSxPQUFPLEdBQUcsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUN0RSxLQUFLLElBQUksS0FBSyxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQ3hCLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztR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QyxDQUFDO0lBQ3BJLE9BQU8sS0FBSyxDQUFDO0FBQ2pCLENBQUM7QUFFRCxLQUFLLFVBQVUsSUFBSTtJQUNmLElBQUksS0FBSyxHQUFHLE1BQU0sUUFBUSxFQUFFLENBQUM7SUFDN0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLElBQUEscUJBQVksRUFBQyxLQUFLLENBQUMsTUFBTSxDQUFDLGVBQWUsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDMUYsU0FBUyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN2QixTQUFTLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzVCLENBQUM7QUFFRCxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUU7O0lBQ2IsT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFDLENBQVcsQ0FBQyxLQUFLLG1DQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDcEIsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IGZvcm1hdE51bWJlciwgZm9ybWF0VGltZSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2Zvcm1hdHRpbmcvZm9ybWF0XCI7XG5pbXBvcnQgeyBzb3J0IH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvbWlzY1wiO1xuaW1wb3J0IHsgVHJlZVN1bW1hcnkgfSBmcm9tIFwiLi90cmVlU3VtbWFyeVwiO1xuXG5jb25zdCBTVU1NQVJZX0NPVU5UID0gMzA7XG5jb25zdCBUSU1JTkdfUlVOUyA9IDIwO1xuY29uc3QgU0NBTl9ESVJTID0gW1xuICAgIFwiRDovcmVwb3MvcXMtY3lvYVwiLFxuICAgIFwiRDovcmVwb3MvcXVlcnlzdWJcIixcbiAgICBcIkQ6L3JlcG9zL3NvY2tldC1mdW5jdGlvblwiLFxuICAgIFwiRDovcmVwb3Mvc2xpZnR1dGlsc1wiLFxuICAgIFwiRDovcmVwb3MvaW5mZXJlbmNlLXdlaWdodHNcIixcbl07XG5cbi8vIE1hdGNoZXMgdGhlIGdpdGlnbm9yZWQgXCJ0ZXN0Ki5qc29uXCIgcGF0dGVybiwgc28gdGhlIGNhY2hlIG5ldmVyIGdldHMgdHJhY2tlZC5cbmNvbnN0IENBQ0hFX0ZJTEUgPSBcIkQ6L3JlcG9zL3NsaWZ0dXRpbHMvdGVzdC1maWxlcy1jYWNoZS5qc29uXCI7XG5cbnR5cGUgRmlsZUluZm8gPSB7IHBhdGg6IHN0cmluZzsgc2l6ZTogbnVtYmVyIH07XG50eXBlIEZpbGVTdW1tYXJ5ID0geyBjb3VudDogbnVtYmVyOyB0b3RhbFNpemU6IG51bWJlciB9O1xuXG5hc3luYyBmdW5jdGlvbiBjb2xsZWN0RmlsZXMoZGlyczogc3RyaW5nW10sIG91dHB1dDogRmlsZUluZm9bXSkge1xuICAgIGZvciAobGV0IGRpciBvZiBkaXJzKSB7XG4gICAgICAgIGxldCBiYXNlUGF0aCA9IGRpci5lbmRzV2l0aChcIi9cIikgJiYgZGlyIHx8IGRpciArIFwiL1wiO1xuICAgICAgICBhd2FpdCBjb2xsZWN0RGlyKGRpciwgYmFzZVBhdGgsIG91dHB1dCk7XG4gICAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBjb2xsZWN0RGlyKGRpcjogc3RyaW5nLCBiYXNlUGF0aDogc3RyaW5nLCBvdXRwdXQ6IEZpbGVJbmZvW10pIHtcbiAgICBsZXQgZW50cmllcyA9IGF3YWl0IGZzLnByb21pc2VzLnJlYWRkaXIoZGlyLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSk7XG4gICAgZm9yIChsZXQgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgICBsZXQgZnVsbFBhdGggPSBwYXRoLmpvaW4oZGlyLCBlbnRyeS5uYW1lKTtcbiAgICAgICAgbGV0IGVudHJ5UGF0aCA9IGJhc2VQYXRoICsgZW50cnkubmFtZTtcbiAgICAgICAgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgICAgIGF3YWl0IGNvbGxlY3REaXIoZnVsbFBhdGgsIGVudHJ5UGF0aCArIFwiL1wiLCBvdXRwdXQpO1xuICAgICAgICB9IGVsc2UgaWYgKGVudHJ5LmlzRmlsZSgpKSB7XG4gICAgICAgICAgICBsZXQgc3RhdHMgPSBhd2FpdCBmcy5wcm9taXNlcy5zdGF0KGZ1bGxQYXRoKTtcbiAgICAgICAgICAgIG91dHB1dC5wdXNoKHsgcGF0aDogZW50cnlQYXRoLCBzaXplOiBzdGF0cy5zaXplIH0pO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBzdW1tYXJpemUoZmlsZXM6IEZpbGVJbmZvW10sIHdlaWdodEJ5U2l6ZTogYm9vbGVhbikge1xuICAgIGxldCB0cmVlID0gbmV3IFRyZWVTdW1tYXJ5PEZpbGVJbmZvLCBGaWxlU3VtbWFyeT4oe1xuICAgICAgICBnZXRQYXRoOiBmaWxlID0+IGZpbGUucGF0aCxcbiAgICAgICAgY3JlYXRlU3VtbWFyeTogKCkgPT4gKHsgY291bnQ6IDAsIHRvdGFsU2l6ZTogMCB9KSxcbiAgICAgICAgYWRkVG9TdW1tYXJ5OiAoZmlsZSwgc3VtbWFyeSkgPT4ge1xuICAgICAgICAgICAgc3VtbWFyeS5jb3VudCsrO1xuICAgICAgICAgICAgc3VtbWFyeS50b3RhbFNpemUgKz0gZmlsZS5zaXplO1xuICAgICAgICB9LFxuICAgICAgICBtZXJnZVN1bW1hcmllczogKHRhcmdldCwgc291cmNlKSA9PiB7XG4gICAgICAgICAgICB0YXJnZXQuY291bnQgKz0gc291cmNlLmNvdW50O1xuICAgICAgICAgICAgdGFyZ2V0LnRvdGFsU2l6ZSArPSBzb3VyY2UudG90YWxTaXplO1xuICAgICAgICB9LFxuICAgICAgICBnZXRXZWlnaHQ6IHN1bW1hcnkgPT4ge1xuICAgICAgICAgICAgaWYgKHdlaWdodEJ5U2l6ZSkgcmV0dXJuIHN1bW1hcnkudG90YWxTaXplO1xuICAgICAgICAgICAgcmV0dXJuIHN1bW1hcnkuY291bnQ7XG4gICAgICAgIH0sXG4gICAgICAgIGV4cGVjdGVkT3V0cHV0Q291bnQ6IDEwMCxcbiAgICB9KTtcbiAgICBsZXQgYWRkU3RhcnQgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICBmb3IgKGxldCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgICAgIHRyZWUuYWRkKGZpbGUpO1xuICAgIH1cbiAgICBsZXQgYWRkVGltZSA9IHBlcmZvcm1hbmNlLm5vdygpIC0gYWRkU3RhcnQ7XG4gICAgbGV0IHF1ZXJ5U3RhcnQgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICBsZXQgc3VtbWFyaWVzID0gdHJlZS5nZXRTdW1tYXJpZXMoU1VNTUFSWV9DT1VOVCk7XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCBUSU1JTkdfUlVOUzsgaSsrKSB7XG4gICAgICAgIHN1bW1hcmllcyA9IHRyZWUuZ2V0U3VtbWFyaWVzKFNVTU1BUllfQ09VTlQpO1xuICAgIH1cbiAgICBsZXQgcXVlcnlUaW1lID0gKHBlcmZvcm1hbmNlLm5vdygpIC0gcXVlcnlTdGFydCkgLyBUSU1JTkdfUlVOUztcbiAgICBsZXQgbGFiZWwgPSB3ZWlnaHRCeVNpemUgJiYgXCJzaXplXCIgfHwgXCJjb3VudFwiO1xuICAgIGNvbnNvbGUubG9nKGBcXG49PT0gd2VpZ2h0ZWQgYnkgJHtsYWJlbH0sICR7U1VNTUFSWV9DT1VOVH0gZW50cmllcyA9PT1gKTtcbiAgICBjb25zb2xlLmxvZyhgYWRkOiAke2Zvcm1hdFRpbWUoYWRkVGltZSl9IHRvdGFsIGZvciAke2Zvcm1hdE51bWJlcihmaWxlcy5sZW5ndGgpfSBmaWxlcywgdHJhY2tpbmcgJHtmb3JtYXROdW1iZXIodHJlZS5nZXRUcmFja2VkTm9kZUNvdW50KCkpfSBub2RlcywgZ2V0U3VtbWFyaWVzOiAke2Zvcm1hdFRpbWUocXVlcnlUaW1lKX0gYXZnIG92ZXIgJHtUSU1JTkdfUlVOU30gcnVuc2ApO1xuICAgIGxldCB0b3RhbFdlaWdodCA9IDA7XG4gICAgZm9yIChsZXQgZW50cnkgb2Ygc3VtbWFyaWVzKSB7XG4gICAgICAgIHRvdGFsV2VpZ2h0ICs9IGVudHJ5LndlaWdodDtcbiAgICB9XG4gICAgc29ydChzdW1tYXJpZXMsIGVudHJ5ID0+IC1lbnRyeS53ZWlnaHQpO1xuICAgIC8vIFZlcmlmeSBlYWNoIGVudHJ5IGFnYWluc3QgdGhlIHJhdyBmaWxlIGxpc3Q6IGFzc2lnbiBldmVyeSBmaWxlIHRvIGl0cyBtb3N0IHNwZWNpZmljIGRpc3BsYXllZCBlbnRyeSAoZXhhY3QgcGF0aHMgYmVhdCBwcmVmaXhlcywgbG9uZ2VyIHByZWZpeGVzIGJlYXQgc2hvcnRlciksIHdoaWNoIGlzIHRoZSBwYXJ0aXRpb24gdGhlIGVudHJpZXMgY2xhaW0gdG8gcmVwcmVzZW50LlxuICAgIGxldCBhY3R1YWxzID0gc3VtbWFyaWVzLm1hcCgoKSA9PiAoeyBjb3VudDogMCwgdG90YWxTaXplOiAwIH0pKTtcbiAgICBsZXQgdW5tYXRjaGVkQ291bnQgPSAwO1xuICAgIGxldCB1bm1hdGNoZWRTaXplID0gMDtcbiAgICBmb3IgKGxldCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgICAgIGxldCBiZXN0SW5kZXggPSAtMTtcbiAgICAgICAgbGV0IGJlc3RMZW4gPSAtMTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdW1tYXJpZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBlbnRyeVBhdGggPSBzdW1tYXJpZXNbaV0ucGF0aDtcbiAgICAgICAgICAgIGlmIChlbnRyeVBhdGguZW5kc1dpdGgoXCIqXCIpKSB7XG4gICAgICAgICAgICAgICAgbGV0IHByZWZpeCA9IGVudHJ5UGF0aC5zbGljZSgwLCAtMSk7XG4gICAgICAgICAgICAgICAgaWYgKHByZWZpeC5sZW5ndGggPiBiZXN0TGVuICYmIGZpbGUucGF0aC5zdGFydHNXaXRoKHByZWZpeCkpIHtcbiAgICAgICAgICAgICAgICAgICAgYmVzdEluZGV4ID0gaTtcbiAgICAgICAgICAgICAgICAgICAgYmVzdExlbiA9IHByZWZpeC5sZW5ndGg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChmaWxlLnBhdGggPT09IGVudHJ5UGF0aCAmJiBlbnRyeVBhdGgubGVuZ3RoICsgMSA+IGJlc3RMZW4pIHtcbiAgICAgICAgICAgICAgICBiZXN0SW5kZXggPSBpO1xuICAgICAgICAgICAgICAgIGJlc3RMZW4gPSBlbnRyeVBhdGgubGVuZ3RoICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoYmVzdEluZGV4ID09PSAtMSkge1xuICAgICAgICAgICAgdW5tYXRjaGVkQ291bnQrKztcbiAgICAgICAgICAgIHVubWF0Y2hlZFNpemUgKz0gZmlsZS5zaXplO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgYWN0dWFsc1tiZXN0SW5kZXhdLmNvdW50Kys7XG4gICAgICAgIGFjdHVhbHNbYmVzdEluZGV4XS50b3RhbFNpemUgKz0gZmlsZS5zaXplO1xuICAgIH1cbiAgICBsZXQgc2hvd25QZXJjZW50ID0gMDtcbiAgICBsZXQgc3BlY2lmaWNQZXJjZW50ID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN1bW1hcmllcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgZW50cnkgPSBzdW1tYXJpZXNbaV07XG4gICAgICAgIGxldCBwZXJjZW50ID0gZW50cnkud2VpZ2h0IC8gdG90YWxXZWlnaHQgKiAxMDA7XG4gICAgICAgIHNob3duUGVyY2VudCArPSBwZXJjZW50O1xuICAgICAgICBpZiAoZW50cnkua2luZCA9PT0gXCJzZWxmXCIgfHwgZW50cnkua2luZCA9PT0gXCJzdWJ0cmVlXCIpIHtcbiAgICAgICAgICAgIHNwZWNpZmljUGVyY2VudCArPSBwZXJjZW50O1xuICAgICAgICB9XG4gICAgICAgIGxldCBhY3R1YWwgPSBhY3R1YWxzW2ldO1xuICAgICAgICBsZXQgZGlmZiA9IFwiXCI7XG4gICAgICAgIGlmIChhY3R1YWwuY291bnQgIT09IGVudHJ5LnN1bW1hcnkuY291bnQgfHwgYWN0dWFsLnRvdGFsU2l6ZSAhPT0gZW50cnkuc3VtbWFyeS50b3RhbFNpemUpIHtcbiAgICAgICAgICAgIGRpZmYgPSBgICBESUZGIGFjdHVhbCBmaWxlcz0ke2Zvcm1hdE51bWJlcihhY3R1YWwuY291bnQpfSBzaXplPSR7Zm9ybWF0TnVtYmVyKGFjdHVhbC50b3RhbFNpemUpfUJgO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUubG9nKGAke3BlcmNlbnQudG9GaXhlZCgxKS5wYWRTdGFydCg1KX0lICR7ZW50cnkucGF0aC5wYWRFbmQoNjApfSBmaWxlcz0ke2Zvcm1hdE51bWJlcihlbnRyeS5zdW1tYXJ5LmNvdW50KS5wYWRTdGFydCg2KX0gc2l6ZT0keyhmb3JtYXROdW1iZXIoZW50cnkuc3VtbWFyeS50b3RhbFNpemUpICsgXCJCXCIpLnBhZFN0YXJ0KDgpfSR7ZGlmZn1gKTtcbiAgICB9XG4gICAgaWYgKHVubWF0Y2hlZENvdW50ID4gMCkge1xuICAgICAgICBjb25zb2xlLmxvZyhgVU5NQVRDSEVEOiAke2Zvcm1hdE51bWJlcih1bm1hdGNoZWRDb3VudCl9IGZpbGVzICgke2Zvcm1hdE51bWJlcih1bm1hdGNoZWRTaXplKX1CKSBtYXRjaGVkIG5vIGRpc3BsYXllZCBlbnRyeWApO1xuICAgIH1cbiAgICBjb25zb2xlLmxvZyhgdG9wICR7c3VtbWFyaWVzLmxlbmd0aH0gZW50cmllcyBjb3ZlciAke3Nob3duUGVyY2VudC50b0ZpeGVkKDEpfSUgKHNwZWNpZmljIHBhdGhzICR7c3BlY2lmaWNQZXJjZW50LnRvRml4ZWQoMSl9JSwgY29tYmluZWQgbGVmdG92ZXJzICR7KHNob3duUGVyY2VudCAtIHNwZWNpZmljUGVyY2VudCkudG9GaXhlZCgxKX0lKWApO1xuICAgIC8vIEVudHJpZXMgYXJlIGEgc3RyaWN0IHBhcnRpdGlvbiAoZWFjaCBmaWxlIGluIGV4YWN0bHkgb25lIGVudHJ5KSwgc28gdGhlc2UgbXVzdCBtYXRjaCB0aGUgcmVhbCB0b3RhbHMgZXhhY3RseS5cbiAgICBsZXQgZW50cnlDb3VudCA9IDA7XG4gICAgbGV0IGVudHJ5U2l6ZSA9IDA7XG4gICAgZm9yIChsZXQgZW50cnkgb2Ygc3VtbWFyaWVzKSB7XG4gICAgICAgIGVudHJ5Q291bnQgKz0gZW50cnkuc3VtbWFyeS5jb3VudDtcbiAgICAgICAgZW50cnlTaXplICs9IGVudHJ5LnN1bW1hcnkudG90YWxTaXplO1xuICAgIH1cbiAgICBsZXQgYWN0dWFsU2l6ZSA9IDA7XG4gICAgZm9yIChsZXQgZmlsZSBvZiBmaWxlcykge1xuICAgICAgICBhY3R1YWxTaXplICs9IGZpbGUuc2l6ZTtcbiAgICB9XG4gICAgY29uc29sZS5sb2coYGVudHJ5IHRvdGFsczogZmlsZXM9JHtmb3JtYXROdW1iZXIoZW50cnlDb3VudCl9IChhY3R1YWwgJHtmb3JtYXROdW1iZXIoZmlsZXMubGVuZ3RoKX0pLCBzaXplPSR7Zm9ybWF0TnVtYmVyKGVudHJ5U2l6ZSl9QiAoYWN0dWFsICR7Zm9ybWF0TnVtYmVyKGFjdHVhbFNpemUpfUIpYCk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldEZpbGVzKCk6IFByb21pc2U8RmlsZUluZm9bXT4ge1xuICAgIHRyeSB7XG4gICAgICAgIGxldCBjYWNoZWQgPSBKU09OLnBhcnNlKGF3YWl0IGZzLnByb21pc2VzLnJlYWRGaWxlKENBQ0hFX0ZJTEUsIFwidXRmOFwiKSkgYXMgeyBkaXJzOiBzdHJpbmdbXTsgZmlsZXM6IEZpbGVJbmZvW10gfTtcbiAgICAgICAgaWYgKEpTT04uc3RyaW5naWZ5KGNhY2hlZC5kaXJzKSA9PT0gSlNPTi5zdHJpbmdpZnkoU0NBTl9ESVJTKSkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYGxvYWRlZCAke2Zvcm1hdE51bWJlcihjYWNoZWQuZmlsZXMubGVuZ3RoKX0gZmlsZXMgZnJvbSBjYWNoZSAke0NBQ0hFX0ZJTEV9YCk7XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkLmZpbGVzO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUubG9nKGBjYWNoZSBkaXJzIGNoYW5nZWQgKGNhY2hlZCAke0pTT04uc3RyaW5naWZ5KGNhY2hlZC5kaXJzKX0sIG5vdyAke0pTT04uc3RyaW5naWZ5KFNDQU5fRElSUyl9KSwgcmVzY2FubmluZ2ApO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBpZiAoKGVyciBhcyB7IGNvZGU/OiBzdHJpbmcgfSkuY29kZSA9PT0gXCJFTk9FTlRcIikge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYG5vIGNhY2hlIGZpbGUgYXQgJHtDQUNIRV9GSUxFfSwgc2Nhbm5pbmdgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBjYWNoZSByZWFkIGZhaWxlZCwgcmVzY2FubmluZzpgLCAoZXJyIGFzIEVycm9yKS5zdGFjayA/PyBlcnIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGxldCBmaWxlczogRmlsZUluZm9bXSA9IFtdO1xuICAgIGxldCBzY2FuU3RhcnQgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICBhd2FpdCBjb2xsZWN0RmlsZXMoU0NBTl9ESVJTLCBmaWxlcyk7XG4gICAgYXdhaXQgZnMucHJvbWlzZXMud3JpdGVGaWxlKENBQ0hFX0ZJTEUsIEpTT04uc3RyaW5naWZ5KHsgZGlyczogU0NBTl9ESVJTLCBmaWxlcyB9KSk7XG4gICAgY29uc29sZS5sb2coYHNjYW5uZWQgJHtmb3JtYXROdW1iZXIoZmlsZXMubGVuZ3RoKX0gZmlsZXMgaW4gJHtmb3JtYXRUaW1lKHBlcmZvcm1hbmNlLm5vdygpIC0gc2NhblN0YXJ0KX0sIGNhY2hlZCB0byAke0NBQ0hFX0ZJTEV9YCk7XG4gICAgcmV0dXJuIGZpbGVzO1xufVxuXG5hc3luYyBmdW5jdGlvbiBtYWluKCkge1xuICAgIGxldCBmaWxlcyA9IGF3YWl0IGdldEZpbGVzKCk7XG4gICAgY29uc29sZS5sb2coYGNvbGxlY3RlZCAke2Zvcm1hdE51bWJlcihmaWxlcy5sZW5ndGgpfSBmaWxlcyBmcm9tICR7U0NBTl9ESVJTLmpvaW4oXCIsIFwiKX1gKTtcbiAgICBzdW1tYXJpemUoZmlsZXMsIHRydWUpO1xuICAgIHN1bW1hcml6ZShmaWxlcywgZmFsc2UpO1xufVxuXG5tYWluKCkuY2F0Y2goZSA9PiB7XG4gICAgY29uc29sZS5lcnJvcigoZSBhcyBFcnJvcikuc3RhY2sgPz8gZSk7XG4gICAgcHJvY2Vzcy5leGl0KDEpO1xufSk7XG4iXX0=
199
+ /* _JS_SOURCE_HASH = "90802e23dfaf68469b5c319fa6270629c6b9178410c4c003fd4293ec3f46f4f9"; */
package/index.d.ts CHANGED
@@ -858,7 +858,7 @@ declare module "sliftutils/render-utils/observer" {
858
858
  declare module "sliftutils/storage/ArchivesDisk" {
859
859
  /// <reference types="node" />
860
860
  /// <reference types="node" />
861
- import { IArchives, ArchiveFileInfo, ArchivesConfig, ChangesAfterConfig, GetConfig, GetInfoConfig, SetConfig } from "./IArchives";
861
+ import { IArchives, ArchiveFileInfo, ArchivesConfig, ChangesAfterConfig, DelConfig, GetConfig, GetInfoConfig, SetConfig } from "./IArchives";
862
862
  export declare class ArchivesDisk implements IArchives {
863
863
  private folder;
864
864
  constructor(folder: string);
@@ -878,7 +878,7 @@ declare module "sliftutils/storage/ArchivesDisk" {
878
878
  hasWriteAccess(): Promise<boolean>;
879
879
  private filePath;
880
880
  set(key: string, data: Buffer, config?: SetConfig): Promise<string>;
881
- del(key: string): Promise<void>;
881
+ del(key: string, config?: DelConfig): Promise<void>;
882
882
  get(key: string, config?: GetConfig): Promise<Buffer | undefined>;
883
883
  get2(key: string, config?: GetConfig): Promise<{
884
884
  data: Buffer;
@@ -2149,6 +2149,14 @@ declare module "sliftutils/storage/IArchives" {
2149
2149
  /** Store-to-store call: the serving node answers purely from its own disk, completely short-circuiting its index holders - chasing its own remote holders while answering another store is how infinite get loops between stores form (A asks B, B's index points back at A, ...). No window or route checks on reads: if the bytes are on its disk, the caller may have them. */
2150
2150
  internal?: boolean;
2151
2151
  };
2152
+ export type DelConfig = {
2153
+ /** Stamps the deletion (its tombstone) with this write time instead of now. Synchronization passes the ORIGINAL deletion time, so deletion ordering survives propagation exactly like any other write's ordering. */
2154
+ lastModified?: number;
2155
+ /** See SetConfig.internal. */
2156
+ internal?: boolean;
2157
+ /** See SetConfig.noChecks. */
2158
+ noChecks?: boolean;
2159
+ };
2152
2160
  export type GetInfoConfig = {
2153
2161
  /** Also report size-0 entries (tombstones - an empty file IS a missing file). Off by default, so a deleted key reports undefined, matching get. Synchronization-style callers pass this when they need a deletion's write time (e.g. to compare it against a write they are about to make). */
2154
2162
  includeTombstones?: boolean;
@@ -2272,9 +2280,14 @@ declare module "sliftutils/storage/IArchives" {
2272
2280
  * VARIABLE_SHARD, where the shard value is materialized into the key (picked by shard latency,
2273
2281
  * see ArchivesChain) and the caller needs the returned key to ever read the value back.
2274
2282
  */
2283
+ /**
2284
+ * THROWS on an empty buffer: an empty file IS a deletion in this system (the tombstone), so a
2285
+ * set-empty would read back as "the file is gone" - which is just asking for problems. If you
2286
+ * want the file deleted, call del; deletions take their own path.
2287
+ */
2275
2288
  set(fileName: string, data: Buffer, config?: SetConfig): Promise<string>;
2276
- del(fileName: string): Promise<void>;
2277
- /** Streams a file too large to hold in memory. getNextData returns undefined when done. lastModified stamps the finished file like set's (synchronized copies need it to keep write ordering); backends that stamp their own times (backblaze) accept and ignore it. */
2289
+ del(fileName: string, config?: DelConfig): Promise<void>;
2290
+ /** Streams a file too large to hold in memory. getNextData returns undefined when done. lastModified stamps the finished file like set's (synchronized copies need it to keep write ordering); backends that stamp their own times (backblaze) accept and ignore it. THROWS when the stream produces no data at all - same rule as set: an empty file IS a deletion and would read back as missing. */
2278
2291
  setLargeFile(config: {
2279
2292
  path: string;
2280
2293
  lastModified?: number;
@@ -2576,7 +2589,7 @@ declare module "sliftutils/storage/TransactionStorage" {
2576
2589
  declare module "sliftutils/storage/backblaze" {
2577
2590
  /// <reference types="node" />
2578
2591
  /// <reference types="node" />
2579
- import { IArchives, ArchivesConfig, ChangesAfterConfig, ArchiveFileInfo, GetConfig, GetInfoConfig, SetConfig } from "./IArchives";
2592
+ import { IArchives, ArchivesConfig, ChangesAfterConfig, ArchiveFileInfo, DelConfig, GetConfig, GetInfoConfig, SetConfig } from "./IArchives";
2580
2593
  export declare class ArchivesBackblaze implements IArchives {
2581
2594
  private config;
2582
2595
  constructor(config: {
@@ -2605,7 +2618,7 @@ declare module "sliftutils/storage/backblaze" {
2605
2618
  getConfig(): Promise<ArchivesConfig>;
2606
2619
  hasWriteAccess(): Promise<boolean>;
2607
2620
  set(fileName: string, data: Buffer, config?: SetConfig): Promise<string>;
2608
- del(fileName: string): Promise<void>;
2621
+ del(fileName: string, config?: DelConfig): Promise<void>;
2609
2622
  setLargeFile(config: {
2610
2623
  path: string;
2611
2624
  lastModified?: number;
@@ -2880,7 +2893,7 @@ declare module "sliftutils/storage/remoteFileStorage" {
2880
2893
  declare module "sliftutils/storage/remoteStorage/ArchivesRemote" {
2881
2894
  /// <reference types="node" />
2882
2895
  /// <reference types="node" />
2883
- import { IArchives, ArchiveFileInfo, ArchivesConfig, ArchivesSyncStatus, ChangesAfterConfig, GetConfig, GetInfoConfig, SetConfig } from "../IArchives";
2896
+ import { IArchives, ArchiveFileInfo, ArchivesConfig, ArchivesSyncStatus, ChangesAfterConfig, DelConfig, GetConfig, GetInfoConfig, SetConfig } from "../IArchives";
2884
2897
  export type ArchivesRemoteConfig = {
2885
2898
  url: string;
2886
2899
  waitForAccess?: boolean;
@@ -2926,7 +2939,7 @@ declare module "sliftutils/storage/remoteStorage/ArchivesRemote" {
2926
2939
  size: number;
2927
2940
  } | undefined>;
2928
2941
  set(fileName: string, data: Buffer, config?: SetConfig): Promise<string>;
2929
- del(fileName: string): Promise<void>;
2942
+ del(fileName: string, config?: DelConfig): Promise<void>;
2930
2943
  getInfo(fileName: string, config?: GetInfoConfig): Promise<{
2931
2944
  writeTime: number;
2932
2945
  size: number;
@@ -3000,6 +3013,35 @@ declare module "sliftutils/storage/remoteStorage/accessPage" {
3000
3013
 
3001
3014
  }
3002
3015
 
3016
+ declare module "sliftutils/storage/remoteStorage/accessStats" {
3017
+ import { SummaryEntry } from "../../treeSummary";
3018
+ export type AccessSummaryState = {
3019
+ total: number;
3020
+ };
3021
+ export type AccessTotals = {
3022
+ [operation: string]: {
3023
+ count: number;
3024
+ size: number;
3025
+ };
3026
+ };
3027
+ /** Counts one storage access, in memory only. size is the bytes involved (0 when the target does not exist); omit it entirely for operations that only count calls, which then only get a count tree. */
3028
+ export declare function trackAccess(config: {
3029
+ account: string;
3030
+ operation: string;
3031
+ path: string;
3032
+ size?: number;
3033
+ }): void;
3034
+ export declare function getAccessTotals(account: string): AccessTotals;
3035
+ export declare function readAccessSummaries(config: {
3036
+ account: string;
3037
+ operation: string;
3038
+ maxCount: number;
3039
+ weightBySize?: boolean;
3040
+ }): SummaryEntry<AccessSummaryState>[];
3041
+ export declare function clearAccountAccessStats(account: string): void;
3042
+
3043
+ }
3044
+
3003
3045
  declare module "sliftutils/storage/remoteStorage/blobStore" {
3004
3046
  /// <reference types="node" />
3005
3047
  /// <reference types="node" />
@@ -3178,6 +3220,7 @@ declare module "sliftutils/storage/remoteStorage/blobStore" {
3178
3220
  private cacheRead;
3179
3221
  set(key: string, data: Buffer, config?: WriteConfig): Promise<string>;
3180
3222
  del(key: string, config?: WriteConfig): Promise<void>;
3223
+ private setOrDelete;
3181
3224
  private getWritableSources;
3182
3225
  private writeToSources;
3183
3226
  getInfo(key: string, config?: GetInfoConfig): Promise<{
@@ -3211,7 +3254,7 @@ declare module "sliftutils/storage/remoteStorage/cliArgs" {
3211
3254
  declare module "sliftutils/storage/remoteStorage/createArchives" {
3212
3255
  /// <reference types="node" />
3213
3256
  /// <reference types="node" />
3214
- import { IArchives, RemoteConfig, RemoteConfigBase, HostedConfig, BackblazeConfig, ArchiveFileInfo, ArchivesConfig, ArchivesSyncStatus, ChangesAfterConfig, GetConfig, GetInfoConfig, SetConfig } from "../IArchives";
3257
+ import { IArchives, RemoteConfig, RemoteConfigBase, HostedConfig, BackblazeConfig, ArchiveFileInfo, ArchivesConfig, ArchivesSyncStatus, ChangesAfterConfig, DelConfig, GetConfig, GetInfoConfig, SetConfig } from "../IArchives";
3215
3258
  import { ServerBucketInfo, ActiveBucketInfo } from "./storageServerState";
3216
3259
  /** The address, port, account, and bucket name a bucket routing URL addresses. Throws when the URL isn't a hosted bucket routing URL (https://host:port/file/<account>/<bucketName>/storage/storagerouting.json). */
3217
3260
  export { parseHostedUrl, parseBackblazeUrl, getBucketBaseUrl } from "./remoteConfig";
@@ -3307,7 +3350,7 @@ declare module "sliftutils/storage/remoteStorage/createArchives" {
3307
3350
  hasWriteAccess(): Promise<boolean>;
3308
3351
  set(fileName: string, data: Buffer, config?: SetConfig): Promise<string>;
3309
3352
  private setRoutingConfig;
3310
- del(fileName: string): Promise<void>;
3353
+ del(fileName: string, config?: DelConfig): Promise<void>;
3311
3354
  private getVariableShardTargets;
3312
3355
  /** The key setVariableShard would materialize for this VARIABLE_SHARD key (a value in the preferred shard's route range), without writing anything. */
3313
3356
  getShardKey(key: string): Promise<string>;
@@ -3544,6 +3587,8 @@ declare module "sliftutils/storage/remoteStorage/storageController" {
3544
3587
  /// <reference types="node" />
3545
3588
  import { ArchiveFileInfo, ArchivesConfig, ArchivesSyncStatus, ChangesAfterConfig } from "../IArchives";
3546
3589
  import { ServerBucketInfo, ActiveBucketInfo } from "./storageServerState";
3590
+ import { AccessTotals, AccessSummaryState } from "./accessStats";
3591
+ import type { SummaryEntry } from "../../treeSummary";
3547
3592
  export declare const REMOTE_STORAGE_CLASS_GUID = "RemoteStorageController-b7e42a91";
3548
3593
  export declare const STORAGE_AUTH_PURPOSE = "remoteStorage-auth-1";
3549
3594
  export declare const STORAGE_NOT_AUTHENTICATED = "REMOTE_STORAGE_NOT_AUTHENTICATED_cf2f7b1e";
@@ -3613,7 +3658,7 @@ declare module "sliftutils/storage/remoteStorage/storageController" {
3613
3658
  size: number;
3614
3659
  } | undefined>;
3615
3660
  set: (account: string, bucketName: string, path: string, data: Buffer, lastModified?: number, forceSetImmutable?: boolean, internal?: boolean) => Promise<void>;
3616
- del: (account: string, bucketName: string, path: string) => Promise<void>;
3661
+ del: (account: string, bucketName: string, path: string, lastModified?: number, internal?: boolean) => Promise<void>;
3617
3662
  getInfo: (account: string, bucketName: string, path: string, includeTombstones?: boolean) => Promise<{
3618
3663
  writeTime: number;
3619
3664
  size: number;
@@ -3630,6 +3675,12 @@ declare module "sliftutils/storage/remoteStorage/storageController" {
3630
3675
  clearWriteStats: (account: string) => Promise<{
3631
3676
  clearedBuckets: number;
3632
3677
  }>;
3678
+ getAccessStats: (account: string) => Promise<AccessTotals>;
3679
+ getAccessSummaries: (account: string, config: {
3680
+ operation: string;
3681
+ maxCount: number;
3682
+ weightBySize?: boolean;
3683
+ }) => Promise<SummaryEntry<AccessSummaryState>[]>;
3633
3684
  getIndexInfo: (account: string, bucketName: string) => Promise<{
3634
3685
  fileCount: number;
3635
3686
  byteCount: number;
@@ -3699,8 +3750,8 @@ declare module "sliftutils/storage/remoteStorage/storageServerState" {
3699
3750
  flushedWrites: number;
3700
3751
  flushedBytes: number;
3701
3752
  };
3702
- /** Zeroes the write statistics of every bucket in the account, including counts not yet flushed. */
3703
- export declare function clearAccountWriteStats(account: string): Promise<number>;
3753
+ /** Zeroes the write statistics of every bucket in the account. */
3754
+ export declare function clearAccountWriteStats(account: string): number;
3704
3755
  export declare function setTrustedMachines(config: {
3705
3756
  account: string;
3706
3757
  machineIds: string[];
@@ -3782,7 +3833,10 @@ declare module "sliftutils/storage/remoteStorage/storageServerState" {
3782
3833
  /** Loads a bucket that exists on this server's disk into memory, which starts its synchronization and window timers, and returns its live state. Nothing is written and no other server is contacted - unlike building an ArchivesChain for it, which would probe every source and could write the routing config. Already-loaded buckets just return their state. */
3783
3834
  export declare function activateBucket(account: string, bucketName: string): Promise<ActiveBucketInfo | string>;
3784
3835
  export declare function listAccountBuckets(account: string): Promise<ServerBucketInfo[]>;
3785
- export declare function deleteBucketFile(account: string, bucketName: string, filePath: string): Promise<void>;
3836
+ export declare function deleteBucketFile(account: string, bucketName: string, filePath: string, config?: {
3837
+ lastModified?: number;
3838
+ internal?: boolean;
3839
+ }): Promise<void>;
3786
3840
  export declare function getLocalArchives(account: string, bucketName: string): IArchives;
3787
3841
 
3788
3842
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sliftutils",
3
- "version": "1.7.67",
3
+ "version": "1.7.69",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- import { IArchives, ArchiveFileInfo, ArchivesConfig, ChangesAfterConfig, GetConfig, GetInfoConfig, SetConfig } from "./IArchives";
3
+ import { IArchives, ArchiveFileInfo, ArchivesConfig, ChangesAfterConfig, DelConfig, GetConfig, GetInfoConfig, SetConfig } from "./IArchives";
4
4
  export declare class ArchivesDisk implements IArchives {
5
5
  private folder;
6
6
  constructor(folder: string);
@@ -20,7 +20,7 @@ export declare class ArchivesDisk implements IArchives {
20
20
  hasWriteAccess(): Promise<boolean>;
21
21
  private filePath;
22
22
  set(key: string, data: Buffer, config?: SetConfig): Promise<string>;
23
- del(key: string): Promise<void>;
23
+ del(key: string, config?: DelConfig): Promise<void>;
24
24
  get(key: string, config?: GetConfig): Promise<Buffer | undefined>;
25
25
  get2(key: string, config?: GetConfig): Promise<{
26
26
  data: Buffer;
@@ -3,7 +3,7 @@ import path from "path";
3
3
  import { lazy } from "socket-function/src/caching";
4
4
  import { runInfinitePoll } from "socket-function/src/batching";
5
5
  import { sort, binarySearchBasic } from "socket-function/src/misc";
6
- import { IArchives, ArchiveFileInfo, ArchivesConfig, ChangesAfterConfig, GetConfig, GetInfoConfig, SetConfig, assertValidLastModified } from "./IArchives";
6
+ import { IArchives, ArchiveFileInfo, ArchivesConfig, ChangesAfterConfig, DelConfig, GetConfig, GetInfoConfig, SetConfig, assertValidLastModified } from "./IArchives";
7
7
  import { filterChanges } from "./remoteStorage/remoteConfig";
8
8
 
9
9
  // The base file-system IArchives: storage is one-to-one with the file system, every key is exactly one real file under <folder>/files, so the file system itself is the index. File handles are cached and reused, and closed once idle (see FileHandleCache). All operations on a file run in serial, so they can't collide with each other or with handle closing. Used as the disk synchronization source of BlobStore (see remoteStorage/blobStore.ts).
@@ -151,6 +151,9 @@ export class ArchivesDisk implements IArchives {
151
151
 
152
152
  // forceSetImmutable is accepted and needs no handling: disk sources are never immutable, and the older-write no-op below already gives synchronization its only-take-the-latest semantics
153
153
  public async set(key: string, data: Buffer, config?: SetConfig): Promise<string> {
154
+ if (!data.length) {
155
+ throw new Error(`set was called with an empty buffer for ${JSON.stringify(key)} on ${this.getDebugName()}: an empty file IS a deletion in this system and would read back as missing - call del instead`);
156
+ }
154
157
  await this.init();
155
158
  let lastModified = config?.lastModified;
156
159
  if (lastModified) {
@@ -174,7 +177,8 @@ export class ArchivesDisk implements IArchives {
174
177
  return key;
175
178
  }
176
179
 
177
- public async del(key: string): Promise<void> {
180
+ // config is accepted and ignored: a disk deletion is a physical remove (no tombstone to stamp - BlobStore's index carries the tombstone for disk sources)
181
+ public async del(key: string, config?: DelConfig): Promise<void> {
178
182
  await this.init();
179
183
  let filePath = this.filePath(key);
180
184
  await this.handles.run(filePath, async () => {
@@ -319,8 +323,8 @@ export class ArchivesDisk implements IArchives {
319
323
  await fs.promises.rename(tmpPath, filePath);
320
324
  } catch (e: any) {
321
325
  if (e.code !== "ENOENT") throw e;
322
- // Nothing was ever appended, so the upload file was never created
323
- await fs.promises.writeFile(filePath, Buffer.alloc(0));
326
+ // Either nothing was ever appended, or the temp file was destroyed under us - both must fail loudly. Materializing an empty file here (the old behavior) silently turned the upload into a DELETION, since an empty file IS a missing file in this system.
327
+ throw new Error(`Large upload of ${JSON.stringify(key)} has no data: the upload temp file ${tmpPath} does not exist. Either no data was ever appended (empty files are forbidden - they read back as deletions; use del to delete) or the temp file was removed while the upload was running.`);
324
328
  }
325
329
  // The rename preserves the temp file's mtime, which is just when the last append happened - the logical write time has to be stamped explicitly (it is the metadata scans order everything by)
326
330
  if (lastModified) {
@@ -58,6 +58,14 @@ export type GetConfig = {
58
58
  /** Store-to-store call: the serving node answers purely from its own disk, completely short-circuiting its index holders - chasing its own remote holders while answering another store is how infinite get loops between stores form (A asks B, B's index points back at A, ...). No window or route checks on reads: if the bytes are on its disk, the caller may have them. */
59
59
  internal?: boolean;
60
60
  };
61
+ export type DelConfig = {
62
+ /** Stamps the deletion (its tombstone) with this write time instead of now. Synchronization passes the ORIGINAL deletion time, so deletion ordering survives propagation exactly like any other write's ordering. */
63
+ lastModified?: number;
64
+ /** See SetConfig.internal. */
65
+ internal?: boolean;
66
+ /** See SetConfig.noChecks. */
67
+ noChecks?: boolean;
68
+ };
61
69
  export type GetInfoConfig = {
62
70
  /** Also report size-0 entries (tombstones - an empty file IS a missing file). Off by default, so a deleted key reports undefined, matching get. Synchronization-style callers pass this when they need a deletion's write time (e.g. to compare it against a write they are about to make). */
63
71
  includeTombstones?: boolean;
@@ -181,9 +189,14 @@ export interface IArchives {
181
189
  * VARIABLE_SHARD, where the shard value is materialized into the key (picked by shard latency,
182
190
  * see ArchivesChain) and the caller needs the returned key to ever read the value back.
183
191
  */
192
+ /**
193
+ * THROWS on an empty buffer: an empty file IS a deletion in this system (the tombstone), so a
194
+ * set-empty would read back as "the file is gone" - which is just asking for problems. If you
195
+ * want the file deleted, call del; deletions take their own path.
196
+ */
184
197
  set(fileName: string, data: Buffer, config?: SetConfig): Promise<string>;
185
- del(fileName: string): Promise<void>;
186
- /** Streams a file too large to hold in memory. getNextData returns undefined when done. lastModified stamps the finished file like set's (synchronized copies need it to keep write ordering); backends that stamp their own times (backblaze) accept and ignore it. */
198
+ del(fileName: string, config?: DelConfig): Promise<void>;
199
+ /** Streams a file too large to hold in memory. getNextData returns undefined when done. lastModified stamps the finished file like set's (synchronized copies need it to keep write ordering); backends that stamp their own times (backblaze) accept and ignore it. THROWS when the stream produces no data at all - same rule as set: an empty file IS a deletion and would read back as missing. */
187
200
  setLargeFile(config: {
188
201
  path: string;
189
202
  lastModified?: number;
@@ -94,6 +94,15 @@ export type GetConfig = {
94
94
  internal?: boolean;
95
95
  };
96
96
 
97
+ export type DelConfig = {
98
+ /** Stamps the deletion (its tombstone) with this write time instead of now. Synchronization passes the ORIGINAL deletion time, so deletion ordering survives propagation exactly like any other write's ordering. */
99
+ lastModified?: number;
100
+ /** See SetConfig.internal. */
101
+ internal?: boolean;
102
+ /** See SetConfig.noChecks. */
103
+ noChecks?: boolean;
104
+ };
105
+
97
106
  export type GetInfoConfig = {
98
107
  /** Also report size-0 entries (tombstones - an empty file IS a missing file). Off by default, so a deleted key reports undefined, matching get. Synchronization-style callers pass this when they need a deletion's write time (e.g. to compare it against a write they are about to make). */
99
108
  includeTombstones?: boolean;
@@ -204,7 +213,8 @@ export async function copyArchiveFile(config: {
204
213
  }
205
214
  if (size <= LARGE_COPY_THRESHOLD) {
206
215
  let result = await from.get2(path, { internal: config.internal });
207
- if (!result || !result.data) return undefined;
216
+ // Empty counts as absent, never as content to copy: an empty file IS a deletion, set refuses empty buffers, and deletions travel through their own path (del / scan tombstones)
217
+ if (!result || !result.data || !result.data.length) return undefined;
208
218
  await to.set(path, result.data, { lastModified: result.writeTime, forceSetImmutable: config.forceSetImmutable, noChecks: config.noChecks, internal: config.internal });
209
219
  return { writeTime: result.writeTime, size: result.data.length };
210
220
  }
@@ -246,6 +256,7 @@ export type ArchivesSyncStatus = {
246
256
  sources: ArchivesSyncSourceStatus[];
247
257
  };
248
258
 
259
+ // NOTE: We don't presently have an append function here because a surprising number of storage systems don't support it (backblaze, file system api). It would also complicate things as now there needs to be really a single source of truth of a file, and if you append to the wrong single source of truth, things just become very complicated.
249
260
  export interface IArchives {
250
261
  getDebugName(): string;
251
262
  /** Whether writes would be accepted (credentials exist, the account trusts this machine, etc). Checked without writing anything. */
@@ -269,9 +280,14 @@ export interface IArchives {
269
280
  * VARIABLE_SHARD, where the shard value is materialized into the key (picked by shard latency,
270
281
  * see ArchivesChain) and the caller needs the returned key to ever read the value back.
271
282
  */
283
+ /**
284
+ * THROWS on an empty buffer: an empty file IS a deletion in this system (the tombstone), so a
285
+ * set-empty would read back as "the file is gone" - which is just asking for problems. If you
286
+ * want the file deleted, call del; deletions take their own path.
287
+ */
272
288
  set(fileName: string, data: Buffer, config?: SetConfig): Promise<string>;
273
- del(fileName: string): Promise<void>;
274
- /** Streams a file too large to hold in memory. getNextData returns undefined when done. lastModified stamps the finished file like set's (synchronized copies need it to keep write ordering); backends that stamp their own times (backblaze) accept and ignore it. */
289
+ del(fileName: string, config?: DelConfig): Promise<void>;
290
+ /** Streams a file too large to hold in memory. getNextData returns undefined when done. lastModified stamps the finished file like set's (synchronized copies need it to keep write ordering); backends that stamp their own times (backblaze) accept and ignore it. THROWS when the stream produces no data at all - same rule as set: an empty file IS a deletion and would read back as missing. */
275
291
  setLargeFile(config: { path: string; lastModified?: number; getNextData(): Promise<Buffer | undefined> }): Promise<void>;
276
292
  /** writeTime is the last-write time — see ArchiveFileInfo.createTime, which is the same value. url as in get2. Size-0 entries (tombstones) report undefined unless config.includeTombstones. */
277
293
  getInfo(fileName: string, config?: GetInfoConfig): Promise<{ writeTime: number; size: number; url?: string } | undefined>;
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- import { IArchives, ArchivesConfig, ChangesAfterConfig, ArchiveFileInfo, GetConfig, GetInfoConfig, SetConfig } from "./IArchives";
3
+ import { IArchives, ArchivesConfig, ChangesAfterConfig, ArchiveFileInfo, DelConfig, GetConfig, GetInfoConfig, SetConfig } from "./IArchives";
4
4
  export declare class ArchivesBackblaze implements IArchives {
5
5
  private config;
6
6
  constructor(config: {
@@ -29,7 +29,7 @@ export declare class ArchivesBackblaze implements IArchives {
29
29
  getConfig(): Promise<ArchivesConfig>;
30
30
  hasWriteAccess(): Promise<boolean>;
31
31
  set(fileName: string, data: Buffer, config?: SetConfig): Promise<string>;
32
- del(fileName: string): Promise<void>;
32
+ del(fileName: string, config?: DelConfig): Promise<void>;
33
33
  setLargeFile(config: {
34
34
  path: string;
35
35
  lastModified?: number;
@@ -9,7 +9,7 @@ import debugbreak from "debugbreak";
9
9
  import dns from "dns";
10
10
  import { getSecret } from "../misc/getSecret";
11
11
  import { httpsRequest, HttpsResponseInfo } from "socket-function/src/https";
12
- import { IArchives, ArchivesConfig, ChangesAfterConfig, ArchiveFileInfo, GetConfig, GetInfoConfig, SetConfig, assertValidLastModified, IMMUTABLE_CACHE_TIME } from "./IArchives";
12
+ import { IArchives, ArchivesConfig, ChangesAfterConfig, ArchiveFileInfo, DelConfig, GetConfig, GetInfoConfig, SetConfig, assertValidLastModified, IMMUTABLE_CACHE_TIME } from "./IArchives";
13
13
  import { filterChanges } from "./remoteStorage/remoteConfig";
14
14
 
15
15
  type BackblazeCreds = {
@@ -703,6 +703,9 @@ export class ArchivesBackblaze implements IArchives {
703
703
  }
704
704
  }
705
705
  public async set(fileName: string, data: Buffer, config?: SetConfig): Promise<string> {
706
+ if (!data.length) {
707
+ throw new Error(`set was called with an empty buffer for ${JSON.stringify(fileName)} on ${this.getDebugName()}: an empty file IS a deletion in this system and would read back as missing - call del instead`);
708
+ }
706
709
  if (config?.forceSetImmutable && !config.lastModified) {
707
710
  throw new Error(`forceSetImmutable requires lastModified (synchronization writes are ordered by their write time), writing ${fileName} to ${this.getDebugName()}`);
708
711
  }
@@ -737,7 +740,19 @@ export class ArchivesBackblaze implements IArchives {
737
740
  }
738
741
  return fileName;
739
742
  }
740
- public async del(fileName: string): Promise<void> {
743
+ public async del(fileName: string, config?: DelConfig): Promise<void> {
744
+ if (config?.lastModified) {
745
+ // A synchronized deletion: b2's hide removes the file from listings entirely, so peers scanning the bucket could never learn of it. Instead the tombstone is stored as a REAL empty file (an empty file IS a missing file), which listings show and scans ingest as a deletion. (b2 stamps its own upload time, so the exact deletion time is not preserved here - same as every b2 write.)
746
+ if (!config.noChecks) {
747
+ let existing = await this.getInfo(fileName, { includeTombstones: true });
748
+ if (existing && config.lastModified < existing.writeTime) return;
749
+ }
750
+ this.log(`backblaze tombstone upload ${fileName}`);
751
+ await this.apiRetryLogic(`del ${fileName}`, async (api) => {
752
+ await api.uploadFile({ bucketId: this.bucketId, fileName, data: Buffer.alloc(0) });
753
+ });
754
+ return;
755
+ }
741
756
  this.log(`backblaze delete ${fileName}`);
742
757
  try {
743
758
  await this.apiRetryLogic(`hideFile ${fileName}`, async (api) => {
@@ -777,7 +792,9 @@ export class ArchivesBackblaze implements IArchives {
777
792
 
778
793
  let fileName = path;
779
794
  let data = await getNextData();
780
- if (!data?.length) return;
795
+ if (!data?.length) {
796
+ throw new Error(`setLargeFile produced no data for ${JSON.stringify(config.path)} on ${this.getDebugName()}: an empty file IS a deletion in this system - call del to delete, never write empty files`);
797
+ }
781
798
  // Backblaze disallows overly small files
782
799
  if (data.length < MIN_CHUNK_SIZE) {
783
800
  await this.set(fileName, data);