UNPKG

@minecraft/creator-tools

Version:

Minecraft Creator Tools command line and libraries.

286 lines (285 loc) 12.3 kB
"use strict"; // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const ContentIndex_1 = __importDefault(require("../core/ContentIndex")); const Utilities_1 = __importDefault(require("../core/Utilities")); const StorageUtilities_1 = __importDefault(require("./StorageUtilities")); class DistributedContentIndex { #fileIndexes = {}; #rootFolder; #isLoaded = false; #isError = false; #items = []; get items() { return this.#items; } get isError() { return this.#isError; } get startLength() { return 6; } constructor(rootFolder) { this.#rootFolder = rootFolder; } getValuesFromIndexArray(indices) { const results = []; if (!this.#items) { return results; } for (const index of indices) { if (typeof index === "object") { const indexN = index.n; if (indexN >= 0 && indexN < this.#items.length) { results.push({ value: this.#items[indexN], annotation: index.a }); } } else if (index >= 0 && index < this.#items.length) { results.push({ value: this.#items[index], annotation: undefined }); } } return results; } async ensureLoaded() { if (this.#isLoaded === true) { return; } const cItemsFile = this.#rootFolder.ensureFile("citems.json"); const itemsExists = await cItemsFile.exists(); if (!itemsExists) { this.#isError = true; this.#isLoaded = true; return; } if (!cItemsFile.isContentLoaded) { await cItemsFile.loadContent(); } const jsonO = StorageUtilities_1.default.getJsonObject(cItemsFile); if (jsonO === undefined) { this.#isError = true; this.#isLoaded = true; return; } this.#items = jsonO; this.#isLoaded = true; } async getMatches(searchString, wholeTermSearch, withAnyAnnotation) { if (typeof searchString !== "string") { return undefined; } searchString = searchString.trim().toLowerCase(); let terms = [searchString]; if (!wholeTermSearch) { terms = searchString.split(" "); } let termWasSearched = false; let andResults; for (const term of terms) { if (term.length > 3) { const results = await this.getTermMatch(term); termWasSearched = true; if (results && results.length) { if (andResults === undefined) { andResults = results; } else { const newArr = []; for (let num of results) { if (andResults.includes(num)) { newArr.push(num); } } } } } } if (andResults === undefined || andResults.length === 0) { if (termWasSearched) { return []; } return undefined; } return ContentIndex_1.default.processResultValues(this.getValuesFromIndexArray(andResults), withAnyAnnotation); } async getTermMatch(term) { await this.ensureLoaded(); if (term.length >= 7) { const indexAddress = term.substring(0, 6); let res = this.#fileIndexes[indexAddress]; if (res === false || res === true) { return undefined; } else if (res === undefined) { const firstFolder = this.#rootFolder.ensureFolder(StorageUtilities_1.default.sanitizePath(term.substring(0, 2))); const secondFolder = firstFolder.ensureFolder(StorageUtilities_1.default.sanitizePath(term.substring(2, 4))); const file = secondFolder.ensureFile(StorageUtilities_1.default.sanitizePath(term.substring(4, 6)) + ".json"); const fileExists = await file.exists(); if (!fileExists) { this.#fileIndexes[indexAddress] = false; return undefined; } if (!file.isContentLoaded) { await file.loadContent(); } const jsonO = StorageUtilities_1.default.getJsonObject(file); if (jsonO === undefined) { this.#fileIndexes[indexAddress] = false; return undefined; } const contentIndex = new ContentIndex_1.default(); contentIndex.setTrie(jsonO); if (this.#items) { contentIndex.setItems(this.#items); } res = { file: file, index: contentIndex, }; this.#fileIndexes[indexAddress] = res; } return res.index.getTermMatch(term.substring(6)); } else if (term.length >= 3) { const indexAddress = term.substring(0, 3); let res = this.#fileIndexes[indexAddress]; if (res === false || res === true) { return undefined; } else if (res === undefined) { const firstFolder = this.#rootFolder.ensureFolder(StorageUtilities_1.default.sanitizePath(term.substring(0, 2))); const file = firstFolder.ensureFile(StorageUtilities_1.default.sanitizePath(term.substring(2, 3)) + ".json"); const fileExists = await file.exists(); if (!fileExists) { this.#fileIndexes[indexAddress] = false; return undefined; } if (!file.isContentLoaded) { await file.loadContent(); } const jsonO = StorageUtilities_1.default.getJsonObject(file); if (jsonO === undefined) { this.#fileIndexes[indexAddress] = false; return undefined; } const contentIndex = new ContentIndex_1.default(); contentIndex.setTrie(jsonO); if (this.#items) { contentIndex.setItems(this.#items); } res = { file: file, index: contentIndex, }; this.#fileIndexes[indexAddress] = res; } return res.index.getTermMatch(term.substring(3)); } } async getDescendentStrings(term) { await this.ensureLoaded(); if (term.length >= 7) { const indexAddress = term.substring(0, 6); const newResults = {}; if (Utilities_1.default.isUsableAsObjectKey(indexAddress)) { let res = this.#fileIndexes[indexAddress]; if (res === false || res === true) { return undefined; } else if (res === undefined) { const firstFolder = this.#rootFolder.ensureFolder(StorageUtilities_1.default.sanitizePath(term.substring(0, 2))); const secondFolder = firstFolder.ensureFolder(StorageUtilities_1.default.sanitizePath(term.substring(2, 4))); const file = secondFolder.ensureFile(StorageUtilities_1.default.sanitizePath(term.substring(4, 6)) + ".json"); const fileExists = await file.exists(); if (!fileExists) { this.#fileIndexes[indexAddress] = false; return undefined; } if (!file.isContentLoaded) { await file.loadContent(); } const jsonO = StorageUtilities_1.default.getJsonObject(file); if (jsonO === undefined) { this.#fileIndexes[indexAddress] = false; return undefined; } const contentIndex = new ContentIndex_1.default(); contentIndex.setTrie(jsonO); if (this.#items) { contentIndex.setItems(this.#items); } res = { file: file, index: contentIndex, }; this.#fileIndexes[indexAddress] = res; } const results = await res.index.getDescendentStrings(term.substring(6)); if (!results) { return undefined; } for (const key in results) { if (results[key] !== undefined) { if (Utilities_1.default.isUsableAsObjectKey(indexAddress + key)) { newResults[indexAddress + key] = results[key]; } } } } return newResults; } return undefined; } static async saveContentIndexToFolder(contentIndex, folder) { const all = contentIndex.getAll(); const fileIndexes = {}; const cItemsFile = folder.ensureFile("citems.json"); Utilities_1.default.encodeObjectWithSequentialRunLengthEncodeUsingNegative(contentIndex.data.trie); cItemsFile.setContent(JSON.stringify(contentIndex.data.items)); await cItemsFile.saveContent(); for (const key in all) { if (key.length >= 3) { const firstFolder = folder.ensureFolder(StorageUtilities_1.default.sanitizePath(key.substring(0, 2))); if (key.length >= 7) { const secondFolder = firstFolder.ensureFolder(StorageUtilities_1.default.sanitizePath(key.substring(2, 4))); // /ab/cd/ef[g..] const res = fileIndexes[key.substring(0, 6)]; if (!res) { const file = secondFolder.ensureFile(StorageUtilities_1.default.sanitizePath(key.substring(4, 6)) + ".json"); const newContentIndex = new ContentIndex_1.default(); newContentIndex.setItems(contentIndex.data.items); newContentIndex.insertArray(key.substring(6), all[key]); fileIndexes[key.substring(0, 6)] = { file: file, index: newContentIndex }; } else { res.index.insertArray(key.substring(6), all[key]); } } else { // /ab/c[d|de|def] const res = fileIndexes[key.substring(0, 3)]; if (!res) { const file = firstFolder.ensureFile(StorageUtilities_1.default.sanitizePath(key.substring(2, 3)) + ".json"); const newContentIndex = new ContentIndex_1.default(); newContentIndex.setItems(newContentIndex.data.items); newContentIndex.insertArray(key.substring(3), all[key]); fileIndexes[key.substring(0, 3)] = { file: file, index: newContentIndex }; } else { res.index.insertArray(key.substring(3), all[key]); } } } } for (const fileIndexKey in fileIndexes) { const fileIndex = fileIndexes[fileIndexKey]; Utilities_1.default.encodeObjectWithSequentialRunLengthEncodeUsingNegative(fileIndex.index.data.trie); fileIndex.file.setContent(JSON.stringify(fileIndex.index.data.trie)); await fileIndex.file.saveContent(); } } } exports.default = DistributedContentIndex;