Skip to main content
The storage system provides three core interfaces for working with files and folders across different storage backends.

IStorage

Represents a storage system with a root folder. All storage implementations (NodeStorage, BrowserStorage, etc.) implement this interface.

Properties

interface IStorage {
  // The root folder of the storage system
  rootFolder: IFolder;
  
  // Path to the storage location (if applicable)
  storagePath: string | undefined;
  
  // The file that contains this storage (for ZipStorage)
  containerFile?: IFile;
  
  // Whether storage updates via polling (vs. file system events)
  getUsesPollingBasedUpdating(): boolean;
  
  // Path separator for this storage system
  readonly folderDelimiter: string;
  
  // Version history
  priorVersions: IVersionContent[];
  currentVersionId?: string;
  
  // Change tracking
  isContentUpdated: boolean;
  readOnly: boolean;
  
  // Availability
  available?: boolean;
  getAvailable(): Promise<boolean>;
  
  // Error status
  errorStatus?: StorageErrorStatus;
  errorMessage?: string;
  
  // Unique channel identifier for multi-tab coordination
  channelId?: string;
}

Events

// File events
onFileAdded: IEvent<IStorage, IFile>;
onFileRemoved: IEvent<IStorage, string>;
onFileContentsUpdated: IEvent<IStorage, IFileUpdateEvent>;

// Folder events
onFolderMoved: IEvent<IStorage, IFolderMove>;

Methods

// Reset the content updated flag
resetContentUpdated(): void;

// Scan for changes (full or incremental)
scanForChanges(): Promise<void>;
incrementalScanForChanges(): Promise<void>;

// Version management
addVersion(versionContent: IVersionContent, updateType: FileUpdateType): void;
trimAfterVersion(versionId: string): void;
setToVersion(versionId: string): void;

// Notify of file updates
notifyFileContentsUpdated(fileEvent: IFileUpdateEvent): void;

// Path utilities
joinPath(pathA: string, pathB: string): string;
ensureFolderFromStorageRelativePath(path: string): Promise<IFolder>;

StorageErrorStatus Enum

enum StorageErrorStatus {
  none = 0,
  unprocessable = 1,
  notPresent = 2,
}
Source: ~/workspace/source/app/src/storage/IStorage.ts:9-13

IFolder

Represents a folder/directory in a storage system.

Properties

interface IFolder extends IStorageObject {
  // Timestamps
  lastLoadedOrSaved: Date | null;
  
  // Hierarchy
  parentFolder: IFolder | null;
  storage: IStorage;
  
  // Name utilities
  ensuredName: string;  // Canonical name for the folder
  extendedPath: string; // Full path including container paths
  
  // Counts
  fileCount: number;
  folderCount: number;
  
  // Children
  folders: { [name: string]: IFolder | undefined };
  files: { [name: string]: IFile | undefined };
  
  // Async iteration over all files recursively
  allFiles: AsyncIterable<IFile>;
  
  // State
  isLoaded: boolean;
  canIgnore: boolean;
  
  // Errors
  errorStatus?: FolderErrorStatus;
}

Events

onFolderMoved: IEvent<IFolder, IFolderMove>;
onChildFolderMoved: IEvent<IFolder, IFolderMove>;

Methods

Loading and Existence

// Load folder contents
load(force?: boolean): Promise<Date>;

// Check/ensure folder exists
exists(): Promise<boolean>;
ensureExists(): Promise<boolean>;

File Operations

// Get files
getFileFromRelativePath(path: string): Promise<IFile | undefined>;
fileExists(name: string): boolean;
getSortedFileKeys(): string[];

// Create/ensure files
ensureFile(name: string): IFile;
ensureFileFromRelativePath(path: string): Promise<IFile>;
createFile(name: string): Promise<IFile>;

// Delete files
deleteFile(name: string): Promise<boolean>;
deleteFileFromRelativePath(path: string): Promise<boolean>;

Folder Operations

// Get folders
getFolderFromRelativePath(path: string): Promise<IFolder | undefined>;
getFolderFromRelativePathLocal(path: string): IFolder | undefined;
getFolderByIndex(index: number): IFolder | undefined;
folderExists(name: string): boolean;
getSortedFolderKeys(): string[];

// Create/ensure folders
ensureFolder(name: string): IFolder;
ensureFolderFromRelativePath(path: string): Promise<IFolder>;

// Delete folders
removeFolder(name: string): boolean;
deleteThisFolder(): Promise<boolean>;
deleteAllFolderContents(): Promise<boolean>;

Movement and Renaming

rename(name: string): Promise<boolean>;
moveTo(newStorageRelativePath: string): Promise<boolean>;

Utilities

// Scan for external changes
scanForChanges(): Promise<void>;

// Build structure from file list
setStructureFromFileList(fileList: string[]): Promise<void>;

// Save all modified files
saveAll(force?: boolean): Promise<boolean>;

// Clear cached managers
clearAllManagers(): void;

// Path calculations
getFolderRelativePath(toFolder: IFolder): string | undefined;

// Cleanup
dispose(): void;

FolderErrorStatus Enum

enum FolderErrorStatus {
  none = 0,
  unreadable = 1,
}
Source: ~/workspace/source/app/src/storage/IFolder.ts:9-12

IFile

Represents a file in a storage system.

Properties

interface IFile extends IStorageObject {
  // Timestamps
  modified: Date | null;           // Last modified time
  modifiedAtLoad: Date | null;     // Modified time when loaded
  latestModified: Date | null;     // Most recent modification
  lastLoadedOrSaved: Date | null;
  
  // Content
  content: string | Uint8Array | null;
  isContentLoaded: boolean;
  needsSave: boolean;
  
  // File type
  readonly coreContentLength: number;
  readonly type: string;  // File extension
  isBinary: boolean;
  isString: boolean;
  canIgnore: boolean;
  
  // Container files (for .zip, .mcpack, etc.)
  fileContainerStorage: IStorage | null;
  
  // Hierarchy
  parentFolder: IFolder;
  extendedPath: string;  // Full path including containers
  
  // Version history
  priorVersions: IVersionContent[];
  
  // Error state
  isInErrorState?: boolean;
  errorStateMessage?: string;
}

Events

onFileContentUpdated: IEvent<IFile, IFile>;

Methods

Loading and Saving

// Load file content
loadContent(force?: boolean, forceEncoding?: EncodingType): Promise<Date>;

// Save file content
saveContent(force?: boolean): Promise<Date>;

// Unload content from memory
unload(): void;

Content Manipulation

// Set content (raw)
setContent(
  content: string | Uint8Array,
  updateType?: FileUpdateType,
  sourceId?: string
): boolean;

// Set content with semantic comparison
setContentIfSemanticallyDifferent(
  content: string | Uint8Array,
  updateType?: FileUpdateType,
  sourceId?: string
): boolean;

// Set object content (for JSON files)
setObjectContentIfSemanticallyDifferent(
  value: object | null | undefined,
  updateType?: FileUpdateType,
  sourceId?: string
): boolean;

File Operations

// Check existence
exists(): Promise<boolean>;

// Delete
deleteThisFile(skipRemoveFromParent?: boolean): Promise<boolean>;

// Move
moveTo(newStorageRelativePath: string): Promise<boolean>;

// Scan for external changes
scanForChanges(): Promise<void>;

Utilities

// Get file hash
getHash(): Promise<string | undefined>;

// Calculate relative paths
getRelativePathFor(file: IFile): string | undefined;
getRootRelativePath(): string | undefined;
getFolderRelativePath(toFolder: IFolder): string | undefined;

// Cleanup
dispose(): void;

FileUpdateType Enum

enum FileUpdateType {
  regularEdit = 0,               // Normal edit, add to version history
  versionlessEdit = 1,           // Edit without version tracking
  externalChange = 2,            // Change from outside the tool
  versionRestoration = 3,        // Restoring to a version (no history change)
  versionRestorationRetainCurrent = 4, // Restore but keep current in history
}
Source: ~/workspace/source/app/src/storage/IFile.ts:11-17

IStorageObject

Base interface for both files and folders.
interface IStorageObject {
  name: string;                 // Name of the file/folder
  storageRelativePath: string;  // Path relative to storage root
  fullPath: string;             // Full path including storage path
  manager?: any;                // Associated manager object
  tag?: any;                    // Custom tag for your use
}
Source: ~/workspace/source/app/src/storage/IStorageObject.ts:4-10

IVersionContent

Represents a version snapshot of file content.
interface IVersionContent {
  id: string;                        // Unique version ID
  content: string | Uint8Array | null; // Content at this version
  description?: string;              // Optional description
  versionTime: Date | null;          // When version was created
  startVersionTime?: Date | null;    // Start of version range (for coalesced versions)
  file: IFile;                       // The file this version belongs to
}
Source: ~/workspace/source/app/src/storage/IVersionContent.ts:3-10

Usage Examples

Working with Folders

import { IFolder } from "@minecraft/creator-tools";

const folder: IFolder = /* ... */;

// Load folder structure
await folder.load();

// Access files and folders
for (const fileName in folder.files) {
  const file = folder.files[fileName];
  if (file) {
    console.log(file.name);
  }
}

// Iterate all files recursively
for await (const file of folder.allFiles) {
  await file.loadContent();
  console.log(file.fullPath, file.content?.length);
}

// Create nested structure
const scriptsFolder = await folder.ensureFolderFromRelativePath("scripts/server");
const file = await scriptsFolder.ensureFileFromRelativePath("main.js");

Working with Files

import { IFile, FileUpdateType } from "@minecraft/creator-tools";

const file: IFile = /* ... */;

// Load content
await file.loadContent();

if (file.isString && typeof file.content === "string") {
  console.log(file.content);
}

// Modify content
file.setContent("new content", FileUpdateType.regularEdit);

// Save
if (file.needsSave) {
  await file.saveContent();
}

// Check version history
console.log("Versions:", file.priorVersions.length);

Comparing Files

import { StorageUtilities } from "@minecraft/creator-tools";

const areEqual = await StorageUtilities.fileContentsEqual(
  fileA,
  fileB,
  true,  // whitespaceAgnostic
  ["timestamp"]  // ignoreAttributes in JSON
);

if (!areEqual) {
  console.log("Files differ");
}

Build docs developers (and LLMs) love