@minecraft/creator-tools
Version:
Minecraft Creator Tools command line and libraries.
286 lines (285 loc) • 12.3 kB
JavaScript
"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;