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.
- package/dist/test.ts.cache +3 -3
- package/index.d.ts +68 -14
- package/package.json +1 -1
- package/storage/ArchivesDisk.d.ts +2 -2
- package/storage/ArchivesDisk.ts +8 -4
- package/storage/IArchives.d.ts +15 -2
- package/storage/IArchives.ts +19 -3
- package/storage/backblaze.d.ts +2 -2
- package/storage/backblaze.ts +20 -3
- package/storage/dist/ArchivesDisk.ts.cache +2 -2
- package/storage/dist/IArchives.ts.cache +3 -3
- package/storage/dist/backblaze.ts.cache +2 -2
- package/storage/remoteStorage/ArchivesRemote.d.ts +2 -2
- package/storage/remoteStorage/ArchivesRemote.ts +3 -3
- package/storage/remoteStorage/accessStats.d.ts +25 -0
- package/storage/remoteStorage/accessStats.ts +86 -0
- package/storage/remoteStorage/blobStore.d.ts +1 -0
- package/storage/remoteStorage/blobStore.ts +31 -12
- package/storage/remoteStorage/createArchives.d.ts +2 -2
- package/storage/remoteStorage/createArchives.ts +6 -3
- package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +2 -2
- package/storage/remoteStorage/dist/ArchivesUrl.ts.cache +2 -2
- package/storage/remoteStorage/dist/accessStats.ts.cache +78 -0
- package/storage/remoteStorage/dist/blobStore.ts.cache +2 -2
- package/storage/remoteStorage/dist/createArchives.ts.cache +2 -2
- package/storage/remoteStorage/dist/storageController.ts.cache +51 -14
- package/storage/remoteStorage/dist/storageServerState.ts.cache +25 -74
- package/storage/remoteStorage/storageController.d.ts +9 -1
- package/storage/remoteStorage/storageController.ts +52 -11
- package/storage/remoteStorage/storageServerState.d.ts +6 -3
- package/storage/remoteStorage/storageServerState.ts +46 -73
- package/test.ts +1 -1
- package/treeSummary.d.ts +31 -0
package/dist/test.ts.cache
CHANGED
|
@@ -76,7 +76,7 @@ function summarize(files, weightBySize) {
|
|
|
76
76
|
return summary.totalSize;
|
|
77
77
|
return summary.count;
|
|
78
78
|
},
|
|
79
|
-
expectedOutputCount:
|
|
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 = "
|
|
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
|
|
3703
|
-
export declare function clearAccountWriteStats(account: string):
|
|
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
|
|
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
|
/// <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;
|
package/storage/ArchivesDisk.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
//
|
|
323
|
-
|
|
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) {
|
package/storage/IArchives.d.ts
CHANGED
|
@@ -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;
|
package/storage/IArchives.ts
CHANGED
|
@@ -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
|
-
|
|
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>;
|
package/storage/backblaze.d.ts
CHANGED
|
@@ -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;
|
package/storage/backblaze.ts
CHANGED
|
@@ -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)
|
|
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);
|