CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-wasmer--wasi

Isomorphic JavaScript library for interacting with WASI modules across Node.js, browsers, and Deno

Pending
Overview
Eval results
Files

filesystem.mddocs/

Filesystem

In-memory filesystem operations enabling WASI programs to work with files and directories without requiring host filesystem access. The MemFS (Memory Filesystem) provides a complete sandboxed filesystem that exists only in memory, perfect for secure WebAssembly execution across all JavaScript environments.

Capabilities

MemFS Class

In-memory filesystem providing POSIX-like file operations.

/**
 * In-memory filesystem for WASI sandboxed file operations
 */
class MemFS {
  /**
   * Create a new empty in-memory filesystem
   */
  constructor();
  
  /**
   * Create MemFS instance from JavaScript object structure
   * @param jso - JavaScript object representing filesystem structure
   * @returns New MemFS instance
   */
  static from_js(jso: any): MemFS;
  
  /**
   * Read directory contents
   * @param path - Directory path to read
   * @returns Array of directory entries with path and metadata
   */
  readDir(path: string): Array<any>;
  
  /**
   * Create a directory
   * @param path - Directory path to create
   */
  createDir(path: string): void;
  
  /**
   * Remove a directory (must be empty)
   * @param path - Directory path to remove
   */
  removeDir(path: string): void;
  
  /**
   * Remove a file
   * @param path - File path to remove
   */
  removeFile(path: string): void;
  
  /**
   * Rename or move a file or directory
   * @param path - Current path
   * @param to - New path
   */
  rename(path: string, to: string): void;
  
  /**
   * Get file or directory metadata
   * @param path - Path to get metadata for
   * @returns Object containing file metadata (size, timestamps, type)
   */
  metadata(path: string): object;
  
  /**
   * Open a file for reading/writing
   * @param path - File path to open
   * @param options - File open options (read, write, create, etc.)
   * @returns JSVirtualFile handle for file operations
   */
  open(path: string, options: any): JSVirtualFile;
  
  /**
   * Free WebAssembly resources
   * Call when done with the filesystem to clean up memory
   */
  free(): void;
}

Usage Examples:

import { MemFS } from "@wasmer/wasi";

// Create filesystem and directory structure
const fs = new MemFS();
fs.createDir("/app");
fs.createDir("/data");
fs.createDir("/tmp");

// List directory contents
const rootContents = fs.readDir("/");
console.log("Root directory:", rootContents.map(entry => entry.path));

// Work with files
const file = fs.open("/data/config.json", { 
  read: true, 
  write: true, 
  create: true 
});

file.writeString('{"setting": "value"}');
file.seek(0);
const content = file.readString();
console.log("File content:", content);

// File operations
fs.rename("/data/config.json", "/data/settings.json");
const metadata = fs.metadata("/data/settings.json");
console.log("File size:", metadata.size);

// Cleanup
fs.removeFile("/data/settings.json");
fs.removeDir("/data");

JSVirtualFile Class

Virtual file handle providing comprehensive file I/O operations.

/**
 * Virtual file handle for in-memory filesystem operations
 */
class JSVirtualFile {
  /**
   * Get last access time
   * @returns Last access timestamp as BigInt
   */
  lastAccessed(): bigint;
  
  /**
   * Get last modification time
   * @returns Last modification timestamp as BigInt
   */
  lastModified(): bigint;
  
  /**
   * Get file creation time
   * @returns Creation timestamp as BigInt
   */
  createdTime(): bigint;
  
  /**
   * Get current file size
   * @returns File size in bytes as BigInt
   */
  size(): bigint;
  
  /**
   * Set file size (truncate or extend)
   * @param new_size - New file size in bytes
   */
  setLength(new_size: bigint): void;
  
  /**
   * Read entire file contents as bytes
   * @returns File contents as Uint8Array
   */
  read(): Uint8Array;
  
  /**
   * Read entire file contents as string
   * @returns File contents as UTF-8 string
   */
  readString(): string;
  
  /**
   * Write bytes to file at current position
   * @param buf - Data to write as Uint8Array
   * @returns Number of bytes written
   */
  write(buf: Uint8Array): number;
  
  /**
   * Write string to file at current position
   * @param buf - Data to write as UTF-8 string
   * @returns Number of bytes written
   */
  writeString(buf: string): number;
  
  /**
   * Flush any pending writes to the filesystem
   */
  flush(): void;
  
  /**
   * Seek to a specific position in the file
   * @param position - Byte position to seek to
   * @returns New current position
   */
  seek(position: number): number;
  
  /**
   * Free WebAssembly resources
   * Call when done with the file handle to clean up memory
   */
  free(): void;
}

File Operation Examples:

import { MemFS } from "@wasmer/wasi";

const fs = new MemFS();

// Create and write to a text file
const textFile = fs.open("/example.txt", { 
  read: true, 
  write: true, 
  create: true 
});

textFile.writeString("Hello, WASI filesystem!\n");
textFile.writeString("This is line 2.\n");
textFile.flush();

console.log("File size:", textFile.size());
console.log("Created:", new Date(Number(textFile.createdTime())));

// Read from beginning
textFile.seek(0);
const content = textFile.readString();
console.log("File content:", content);

// Binary file operations
const binaryFile = fs.open("/data.bin", { 
  read: true, 
  write: true, 
  create: true 
});

// Write binary data
const data = new Uint8Array([0x48, 0x65, 0x6C, 0x6C, 0x6F]); // "Hello"
const bytesWritten = binaryFile.write(data);
console.log("Wrote", bytesWritten, "bytes");

// Read binary data
binaryFile.seek(0);
const readData = binaryFile.read();
console.log("Read bytes:", Array.from(readData).map(b => b.toString(16)));

// File manipulation
textFile.seek(0);
textFile.setLength(5n); // Truncate to 5 bytes
textFile.seek(0);
const truncated = textFile.readString();
console.log("Truncated:", truncated); // "Hello"

File Open Options

File opening options for controlling access mode and behavior.

// File open options (passed to MemFS.open)
interface FileOpenOptions {
  read?: boolean;      // Allow reading from file
  write?: boolean;     // Allow writing to file  
  create?: boolean;    // Create file if it doesn't exist
  truncate?: boolean;  // Truncate file to zero length on open
  append?: boolean;    // Start writing at end of file
}

File Mode Examples:

// Read-only access
const readFile = fs.open("/readonly.txt", { read: true });

// Write-only with creation
const writeFile = fs.open("/output.log", { 
  write: true, 
  create: true 
});

// Read-write with truncation
const rwFile = fs.open("/temp.dat", { 
  read: true, 
  write: true, 
  create: true, 
  truncate: true 
});

// Append mode
const logFile = fs.open("/app.log", { 
  write: true, 
  create: true, 
  append: true 
});

Filesystem Integration with WASI

The MemFS integrates seamlessly with WASI instances for program file access.

Integration Examples:

import { init, WASI, MemFS } from "@wasmer/wasi";

await init();

// Set up filesystem before WASI execution
const fs = new MemFS();
fs.createDir("/input");
fs.createDir("/output");

// Create input files
const inputFile = fs.open("/input/data.txt", { 
  write: true, 
  create: true 
});
inputFile.writeString("Processing this data...\n");

// Configure WASI with custom filesystem
const wasi = new WASI({
  args: ["processor", "/input/data.txt", "/output/result.txt"],
  fs: fs
});

// Run WASI program
const module = await WebAssembly.compileStreaming(fetch("processor.wasm"));
await wasi.instantiate(module, {});
const exitCode = wasi.start();

// Access results through the same filesystem
if (fs.metadata("/output/result.txt")) {
  const resultFile = fs.open("/output/result.txt", { read: true });
  const result = resultFile.readString();
  console.log("Processing result:", result);
}

Filesystem Utilities

Common filesystem operations and patterns.

Directory Operations:

// Recursive directory creation
function createPath(fs: MemFS, path: string) {
  const parts = path.split('/').filter(p => p);
  let current = '';
  
  for (const part of parts) {
    current += '/' + part;
    try {
      fs.createDir(current);
    } catch (e) {
      // Directory might already exist
    }
  }
}

// List all files recursively
function listAllFiles(fs: MemFS, dir: string = '/'): string[] {
  const files: string[] = [];
  const entries = fs.readDir(dir);
  
  for (const entry of entries) {
    const fullPath = dir === '/' ? entry.path : `${dir}${entry.path}`;
    
    if (entry.is_dir) {
      files.push(...listAllFiles(fs, fullPath));
    } else {
      files.push(fullPath);
    }
  }
  
  return files;
}

Install with Tessl CLI

npx tessl i tessl/npm-wasmer--wasi

docs

filesystem.md

index.md

wasi-runtime.md

tile.json