@minecraft/creator-tools
Version:
Minecraft Creator Tools command line and libraries.
162 lines (160 loc) • 6.59 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 FileBase_1 = __importDefault(require("./FileBase"));
const BrowserStorage_1 = __importDefault(require("./BrowserStorage"));
const StorageUtilities_1 = __importDefault(require("./StorageUtilities"));
const localforage_1 = __importDefault(require("localforage"));
const Log_1 = __importDefault(require("../core/Log"));
class BrowserFile extends FileBase_1.default {
_name;
_parentFolder;
_lastLoadedPath;
sizeAtLoad;
get name() {
return this._name;
}
get parentFolder() {
return this._parentFolder;
}
get fullPath() {
return this._parentFolder.fullPath + BrowserStorage_1.default.slashFolderDelimiter + this.name;
}
get size() {
if (this.content == null) {
return -1;
}
return this.content.length;
}
constructor(parentFolder, fileName) {
super();
this.sizeAtLoad = undefined;
this._parentFolder = parentFolder;
this._name = fileName;
}
get isContentLoaded() {
return this.lastLoadedOrSaved != null || this.modified != null;
}
async deleteThisFile(skipRemoveFromParent) {
if (this.parentFolder.storage.readOnly) {
throw new Error("Can't save read-only file.");
}
if (skipRemoveFromParent !== true) {
this._parentFolder._removeFile(this);
await this._parentFolder.save(false);
}
await localforage_1.default.removeItem(this.fullPath);
return true;
}
async moveTo(newStorageRelativePath) {
const newFolderPath = StorageUtilities_1.default.getFolderPath(newStorageRelativePath);
const newFileName = StorageUtilities_1.default.getLeafName(newStorageRelativePath);
if (newFileName.length < 2) {
throw new Error("New path is not correct.");
}
const newParentFolder = await this._parentFolder.storage.ensureFolderFromStorageRelativePath(newFolderPath);
if (newParentFolder.files[newFileName] !== undefined) {
throw new Error("File exists at specified path.");
}
await this.loadContent();
const originalPath = this.fullPath;
const oldParentFolder = this._parentFolder;
const oldName = this._name;
this._name = newFileName;
this._parentFolder = newParentFolder;
this.modified = new Date();
// Remove from old parent folder's files collection
const oldNameCanon = StorageUtilities_1.default.canonicalizeName(oldName);
delete oldParentFolder.files[oldNameCanon];
newParentFolder._addExistingFile(this);
await localforage_1.default.removeItem(originalPath);
return true;
}
async loadContent(force) {
if (force || !this.lastLoadedOrSaved) {
this._lastLoadedPath = this.fullPath;
let content = await localforage_1.default.getItem(this.fullPath);
// LocalForage may return ArrayBuffer for binary content instead of Uint8Array
// Convert ArrayBuffer to Uint8Array for consistent handling
if (content instanceof ArrayBuffer) {
content = new Uint8Array(content);
}
else if (content !== null && typeof content !== "string" && !(content instanceof Uint8Array)) {
Log_1.default.debug("BrowserFile: Unexpected content type for " + this.fullPath);
content = null;
}
this._content = content;
this.lastLoadedOrSaved = new Date();
}
return this.lastLoadedOrSaved;
}
async resaveAfterMove() {
if (this._lastLoadedPath === undefined) {
return;
}
if (this._lastLoadedPath !== this.fullPath) {
// store old path because saving will change _lastLoadedPath
const oldPath = this._lastLoadedPath;
await this.saveContent(true, true);
await localforage_1.default.removeItem(oldPath);
}
}
async scanForChanges() {
// No-op for browser storage
}
setContent(newContent, updateType, sourceId) {
const areEqual = StorageUtilities_1.default.contentsAreEqual(this._content, newContent);
if (areEqual) {
return false;
}
if (!this.lastLoadedOrSaved) {
this.lastLoadedOrSaved = new Date();
this.lastLoadedOrSaved = new Date(this.lastLoadedOrSaved.getTime() - 1);
// Log.debugAlert("Setting a file without loading it first.");
}
let oldContent = this._content;
this._content = newContent;
if (this.isInErrorState &&
typeof newContent === "string" &&
StorageUtilities_1.default.getMimeType(this) === "application/json") {
StorageUtilities_1.default.getJsonObject(this);
}
this.contentWasModified(oldContent, updateType, sourceId);
return true;
}
async saveContent(force, skipParentFolderSave) {
if (this.parentFolder.storage.readOnly) {
throw new Error("Can't save read-only file.");
}
if (this.needsSave || force) {
/*let contentDescript = "null";
if (this.content instanceof Uint8Array) {
contentDescript = this.content.length + " bytes";
} else if (typeof this.content === "string") {
contentDescript = this.content.length + " text";
}*/
Log_1.default.assert(this.content !== null, "Null content found.");
// Log.debug("Saving file " + contentDescript + " to '" + this.fullPath + "'");
this._lastLoadedPath = this.fullPath;
try {
await localforage_1.default.setItem(this.fullPath, this.content);
}
catch (err) {
Log_1.default.debug("BrowserFile: Failed to save " + this.fullPath + ": " + err);
}
this.lastLoadedOrSaved = new Date();
if (skipParentFolderSave !== true) {
await this._parentFolder.save(false);
}
}
if (this.lastLoadedOrSaved === null) {
this.lastLoadedOrSaved = new Date();
}
return this.lastLoadedOrSaved;
}
}
exports.default = BrowserFile;