import { IErrorable, IErrorMessage } from "./IErrorable.js"; import IFile from "./IFile.js"; import LevelDbIndex, { ILevelDbFileIndex, ILevelDbLogIndex } from "./LevelDbIndex.js"; import LevelKeyValue from "./LevelKeyValue.js"; /** * Options for initializing LevelDb. */ export interface ILevelDbInitOptions { /** * Maximum number of keys to keep in memory when using lazy mode. * Older keys will be evicted when this limit is reached. * Default: 50000 */ maxKeysInMemory?: number; } export interface ILevelDbParsedRecord { ordinal: number; key: string; keyBytes: Uint8Array; value?: Uint8Array; isDeleted?: boolean; sourceKind: "ldb" | "log"; sourcePath?: string; } export interface ILevelDbRecordVisitorOptions { includeValues?: boolean; includeDeleted?: boolean; } export type LevelDbRecordVisitor = (record: ILevelDbParsedRecord) => void; export interface ILevelDbRecordVisitorState { ordinal: number; visitor: LevelDbRecordVisitor; options: Required; sourceKind: "ldb" | "log"; sourcePath?: string; } /** * A logger which LevelDB will call. If a method isn't present, it won't log at all. * To disable all logging, use an empty object `{}`. */ export interface ILogger { log?(message: string): void; verbose?(message: string): void; error?(message: string): void; assert?(predicate: boolean): void; } /** * Represents chunk coordinates extracted from LevelDB keys. * Used for incremental chunk updates when new LDB files are detected. */ export interface IChunkCoordinate { x: number; z: number; dimension: number; } export default class LevelDb implements IErrorable { #private; logger: ILogger; ldbFiles: IFile[]; logFiles: IFile[]; manifestFiles: IFile[]; keys: Map; isInErrorState?: boolean; errorMessages?: IErrorMessage[]; comparator?: string; logNumber?: number; previousLogNumber?: number; nextFileNumber?: number; lastSequence?: number; compactPointerLevels?: number[]; compactPointerStrings?: string[]; deletedFileLevel?: number[]; deletedFileNumber?: number[]; newFileLevel?: number[]; newFileNumber?: number[]; newFileSize?: number[]; newFileSmallest?: string[]; newFileLargest?: string[]; context?: string; /** Get whether lazy loading mode is enabled */ get isLazyMode(): boolean; /** Get the file index for lazy loading */ get index(): LevelDbIndex | undefined; /** Get the number of keys currently in memory */ get keysInMemoryCount(): number; /** * @param logger If provided, logs will go through here. If not present, it will default to console logs. To disable all logging, pass an empty object `{}`. */ constructor(ldbFileArr: IFile[], logFileArr: IFile[], manifestFilesArr: IFile[], context?: string, logger?: ILogger); init(options?: { unloadFilesAfterParse?: boolean; }): Promise; /** * Initialize in lazy loading mode - only loads manifest metadata. * Files are loaded on-demand when keys are requested. * * This dramatically reduces initial memory usage for large worlds. * Call loadAllFiles() to fully load everything, or use getKey() for on-demand loading. */ initLazy(options?: ILevelDbInitOptions): Promise; /** * Load all files in lazy mode. This is useful after initLazy() when you want * to fully populate all keys (e.g., for world enumeration). * * @param options Options for loading * @returns The number of keys loaded */ loadAllFiles(options?: { progressCallback?: (phase: string, current: number, total: number) => void; unloadFilesAfterParse?: boolean; }): Promise; /** * Load a specific file's keys into memory. * Used for on-demand loading in lazy mode. */ loadFile(fileIndex: ILevelDbFileIndex | ILevelDbLogIndex): Promise; /** * Parse a new or modified LDB/LOG file and return the chunk coordinates affected. * This is used for incremental updates when the file system detects new files. * * @param file The LDB or LOG file to parse * @returns Array of unique chunk coordinates affected by keys in this file */ parseIncrementalFile(file: IFile): Promise; /** * Get a key's value, loading the containing file if necessary (lazy mode). * In non-lazy mode, this is a simple map lookup. * * @param key The key to retrieve * @returns The LevelKeyValue, false (if deleted), or undefined (if not found) */ getKey(key: string): Promise; /** * Clear all loaded keys and reset to just the index metadata. * Useful for freeing memory after processing a world. */ clearLoadedKeys(): void; parseLdbContent(content: Uint8Array, context?: string, visitorState?: ILevelDbRecordVisitorState): number | false | undefined; parseIndexBytes(data: Uint8Array, offset: number, length: number, indexKeys: { [id: string]: LevelKeyValue | undefined; }, context?: string): boolean; parseLdbBlockBytes(data: Uint8Array, offset: number, length: number, context?: string, visitorState?: ILevelDbRecordVisitorState): number; parseLogContent(content: Uint8Array, context?: string, visitorState?: ILevelDbRecordVisitorState): number | undefined; addValueFromLog(content: Uint8Array, index: number, length: number, context?: string, visitorState?: ILevelDbRecordVisitorState): number; parseManifestContent(content: Uint8Array, context?: string): void; addValueFromManifest(content: Uint8Array, index: number, length: number, context?: string): void; }