UNPKG

@firesystem/memory

Version:

In-memory implementation of Virtual File System

323 lines (246 loc) โ€ข 8.05 kB
# @firesystem/memory In-memory implementation of the Virtual File System (VFS) interface. Perfect for testing, prototyping, and scenarios where you need a temporary file system that lives only in memory. ## Features - ๐Ÿš€ **Lightning Fast** - All operations happen in memory - ๐Ÿงช **Perfect for Testing** - No disk I/O, fully deterministic - ๐Ÿ’พ **Zero Persistence** - Data cleared on process exit - ๐Ÿ”„ **Full VFS API** - Implements complete @firesystem/core interface - ๐Ÿ“ฆ **Lightweight** - Minimal overhead, no dependencies - ๐Ÿ”Œ **Workspace Ready** - Optional integration with @workspace-fs/core - โšก **Native Events** - Built-in reactive event system for all operations - ๐Ÿ“Š **Progress Tracking** - Monitor initialization and batch operations - ๐Ÿ”” **Real-time Updates** - Get notified of all file system changes ## Installation ```bash npm install @firesystem/memory # or yarn add @firesystem/memory # or pnpm add @firesystem/memory ``` ## Usage ```typescript import { MemoryFileSystem } from "@firesystem/memory"; // Create a new in-memory file system const fs = new MemoryFileSystem(); // Use it like any other VFS implementation await fs.writeFile("/hello.txt", "Hello, World!"); const file = await fs.readFile("/hello.txt"); console.log(file.content); // "Hello, World!" // NEW: Native event support fs.events.on("file:written", ({ path, size }) => { console.log(`File ${path} written (${size} bytes)`); }); // Perfect for testing describe("My App", () => { let fs: MemoryFileSystem; beforeEach(() => { fs = new MemoryFileSystem(); // Fresh instance for each test }); it("should save user data", async () => { await saveUserData(fs, { name: "John" }); const file = await fs.readFile("/users/john.json"); expect(file.content.name).toBe("John"); }); }); ``` ## Event System MemoryFileSystem now includes a native event system that emits events for all operations: ### Basic Events ```typescript import { MemoryFileSystem, FileSystemEvents } from "@firesystem/memory"; const fs = new MemoryFileSystem(); // Listen to file operations fs.events.on(FileSystemEvents.FILE_WRITTEN, ({ path, size }) => { console.log(`File written: ${path} (${size} bytes)`); }); fs.events.on(FileSystemEvents.FILE_DELETED, ({ path }) => { console.log(`File deleted: ${path}`); }); // Listen to directory operations fs.events.on(FileSystemEvents.DIR_CREATED, ({ path }) => { console.log(`Directory created: ${path}`); }); // Operation tracking fs.events.on(FileSystemEvents.OPERATION_START, ({ operation, path }) => { console.log(`Starting ${operation} on ${path}`); }); fs.events.on(FileSystemEvents.OPERATION_END, ({ operation, duration }) => { console.log(`${operation} completed in ${duration}ms`); }); ``` ### Initialization with Progress ```typescript const fs = new MemoryFileSystem({ initialFiles: [ { path: "/file1.txt", type: "file", content: "Hello" }, { path: "/file2.txt", type: "file", content: "World" }, { path: "/docs", type: "directory" }, { path: "/docs/readme.md", type: "file", content: "# Docs" }, ], }); // Track initialization progress fs.events.on(FileSystemEvents.INIT_PROGRESS, ({ loaded, total }) => { console.log(`Loading: ${loaded}/${total} files`); }); // Get notified of each file during initialization fs.events.on(FileSystemEvents.FILE_READ, ({ path, size }) => { console.log(`Loaded file: ${path}`); }); // Initialize and load all files await fs.initialize(); ``` ### Integration with State Management ```typescript // Example with Zustand import { create } from 'zustand'; const useFileStore = create((set) => ({ files: [], initializeFS: async () => { const fs = new MemoryFileSystem({ initialFiles: [...] }); // Listen to files being loaded during initialization fs.events.on(FileSystemEvents.FILE_READ, ({ path, size }) => { set(state => ({ files: [...state.files, { path, size }] })); }); // Listen to future changes fs.events.on(FileSystemEvents.FILE_WRITTEN, ({ path }) => { // Update state when files change }); // Initialize and populate state await fs.initialize(); } })); ``` ## Workspace Integration MemoryFileSystem can be integrated with `@workspace-fs/core` through the `MemoryWorkspaceProvider`: ### Standalone Usage (Default) ```typescript import { MemoryFileSystem } from "@firesystem/memory"; // Use directly without workspace const fs = new MemoryFileSystem(); await fs.writeFile("/test.txt", "Hello World"); ``` ### With Workspace ```typescript import { WorkspaceFileSystem } from "@workspace-fs/core"; import { memoryProvider } from "@firesystem/memory/provider"; // Register the provider const workspace = new WorkspaceFileSystem(); workspace.registerProvider(memoryProvider); // Create memory-based projects const project = await workspace.loadProject({ id: "temp-project", name: "Temporary Project", source: { type: "memory", config: { initialData: { "/README.md": "# My Project", "/src/index.js": "console.log('Hello');", "/package.json": { content: JSON.stringify({ name: "my-project" }, null, 2), metadata: { description: "Package manifest" }, }, }, }, }, }); // Work with the project await workspace.writeFile("/src/utils.js", "export const helper = () => {};"); ``` ### Provider Configuration The memory provider accepts the following configuration: ```typescript interface MemoryProviderConfig { // Initial files to populate initialData?: { [path: string]: | string | { content: any; metadata?: Record<string, any>; }; }; // Maximum storage size (future feature) maxSize?: number; } ``` ## Use Cases ### 1. Testing ```typescript import { MemoryFileSystem } from "@firesystem/memory"; import { MyApp } from "./my-app"; test("file operations", async () => { const fs = new MemoryFileSystem(); const app = new MyApp(fs); await app.saveConfig({ theme: "dark" }); const config = await fs.readFile("/config.json"); expect(config.content.theme).toBe("dark"); }); ``` ### 2. Temporary Processing ```typescript const fs = new MemoryFileSystem(); // Process files without touching disk await fs.writeFile("/input.csv", csvData); await processCSV(fs, "/input.csv", "/output.json"); const result = await fs.readFile("/output.json"); ``` ### 3. Prototyping ```typescript // Quickly prototype without setting up real storage const fs = new MemoryFileSystem(); const cms = new SimpleCMS(fs); await cms.createPost({ title: "Hello World", content: "My first post", }); ``` ## Memory Management The memory file system stores all data in JavaScript objects. Be mindful of memory usage when working with large files: ```typescript const fs = new MemoryFileSystem(); // Monitor storage size with events fs.events.on(FileSystemEvents.STORAGE_SIZE_CALCULATED, ({ size }) => { console.log(`Storage size: ${size} bytes`); }); // Check total size const size = await fs.size(); console.log(`Using ${size} bytes`); // Clear all data with progress tracking fs.events.on(FileSystemEvents.STORAGE_CLEARING, () => { console.log("Clearing storage..."); }); fs.events.on(FileSystemEvents.STORAGE_CLEARED, ({ duration }) => { console.log(`Storage cleared in ${duration}ms`); }); await fs.clear(); ``` ## Constructor Options ```typescript interface MemoryFileSystemOptions { initialFiles?: Array<{ path: string; type: "file" | "directory"; content?: any; size?: number; created?: Date; modified?: Date; metadata?: Record<string, any>; }>; } // Example with initial files const fs = new MemoryFileSystem({ initialFiles: [ { path: "/config.json", type: "file", content: { theme: "dark" } }, { path: "/data", type: "directory" }, { path: "/data/users.json", type: "file", content: [] }, ], }); ``` ## API Reference See [@firesystem/core](../core) for the complete VFS API documentation. ## License MIT ยฉ Anderson D. Rosa