Skip to content

Unified filesystem abstraction for browser storage (OPFS, IndexedDB)

License

Notifications You must be signed in to change notification settings

SiglumProject/siglum-filesystem

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@siglum/filesystem

Unified filesystem abstraction for browser storage with automatic fallback.

Installation

npm install @siglum/filesystem

Quick Start

import { fileSystem } from '@siglum/filesystem'

// Auto-select best backend (OPFS if available, else IndexedDB)
await fileSystem.mountAuto('/documents')

// Use unified API
await fileSystem.writeFile('/documents/main.tex', '\\documentclass{article}...')
const content = await fileSystem.readFile('/documents/main.tex')

Auto-mounting with Fallback

The mountAuto method automatically selects the best available backend:

import { fileSystem } from '@siglum/filesystem'

// Uses OPFS if available, falls back to IndexedDB
const backend = await fileSystem.mountAuto('/documents')
console.log(`Using ${backend.name} backend`)  // 'opfs' or 'indexeddb'

Force a Specific Backend

// Force OPFS (throws if not available)
await fileSystem.mountAuto('/documents', { backend: 'opfs' })

// Force IndexedDB
await fileSystem.mountAuto('/legacy', { backend: 'indexeddb' })

// Explicit auto (same as default)
await fileSystem.mountAuto('/data', { backend: 'auto' })

Check OPFS Availability

import { isOPFSAvailable } from '@siglum/filesystem'

if (isOPFSAvailable()) {
  console.log('OPFS is supported!')
}

Check Backend Type

// Get the backend type for a mounted path
const type = fileSystem.getBackendType('/documents')  // 'opfs', 'indexeddb', or null

Manual Backend Selection

For direct control, import and mount backends explicitly:

import { fileSystem, opfsBackend, indexedDBBackend } from '@siglum/filesystem'

fileSystem.mount('/documents', opfsBackend)
fileSystem.mount('/legacy', indexedDBBackend)

Batch Operations

For reading multiple files efficiently:

const paths = ['/documents/a.txt', '/documents/b.txt', '/documents/c.txt']
const results = await fileSystem.readBinaryBatch(paths)
// Returns Map<string, Uint8Array> - missing files are omitted

For writing multiple files with progress tracking:

const entries = [
  { path: '/documents/a.txt', content: new Uint8Array([1, 2, 3]) },
  { path: '/documents/b.txt', content: new Uint8Array([4, 5, 6]) },
]

await fileSystem.writeBinaryBatch(entries, {
  createParents: true,
  onProgress: (completed, total) => console.log(`${completed}/${total}`),
  concurrency: 20,  // parallel writes (default: 20)
})

Web Worker Support

For accessing the filesystem from Web Workers (including classic workers that can't use ES modules):

// In your worker
import {
  readBinaryIDB,
  writeBinaryIDB,
  readBinaryOPFS,
  writeBinaryOPFS,
  isOPFSAvailable
} from '@siglum/filesystem/worker'

// Read/write directly without the full service
const data = await readBinaryIDB('/path/to/file')
await writeBinaryOPFS('/path/to/file', new Uint8Array([1, 2, 3]))

Storage Constants

Access the underlying storage identifiers (useful for direct IndexedDB/OPFS access):

import {
  IDB_NAME,        // 'siglum_filesystem'
  IDB_VERSION,     // 1
  IDB_FILES_STORE, // 'files'
  IDB_DIRS_STORE,  // 'directories'
  OPFS_ROOT        // ''
} from '@siglum/filesystem/constants'

Backends

OPFS (Origin Private File System)

Fast, persistent storage using the browser's Origin Private File System API.

  • Best performance for large files
  • Streaming support

IndexedDB

Fallback for browsers without OPFS support.

  • Universal browser support
  • Slightly slower for large files

API

FileSystemService

Mounting

  • mount(path, backend) - Mount a backend at a path
  • mountAuto(path, options?) - Mount with automatic backend selection
  • unmount(path) - Unmount a backend
  • getMounts() - List all mount points
  • isMounted(path) - Check if a path has a mounted backend
  • getBackendType(path) - Get backend type ('opfs' | 'indexeddb' | null)

File Operations

  • readFile(path) - Read text content
  • writeFile(path, content, options?) - Write text content
  • readBinary(path) - Read binary data
  • writeBinary(path, data, options?) - Write binary data
  • readBinaryBatch(paths) - Read multiple files efficiently (returns Map<string, Uint8Array>)
  • writeBinaryBatch(entries, options?) - Write multiple files with progress tracking
  • deleteFile(path) - Delete a file
  • copyFile(src, dest) - Copy a file
  • rename(oldPath, newPath) - Rename or move a file

Directory Operations

  • mkdir(path) - Create directory (and parents)
  • rmdir(path, options?) - Remove directory ({ recursive?: boolean })
  • readdir(path) - List directory contents (returns FileEntry[])

Query Operations

  • exists(path) - Check if path exists
  • stat(path) - Get file/directory stats (returns FileStats)

Events

  • subscribe(handler) - Subscribe to filesystem events, returns unsubscribe function

Types

interface FileStats {
  size: number
  isDirectory: boolean
  isFile: boolean
  mtime: Date
}

interface FileEntry {
  name: string
  path: string
  isDirectory: boolean
}

type FileSystemEvent =
  | { type: 'file:created'; path: string }
  | { type: 'file:modified'; path: string }
  | { type: 'file:deleted'; path: string }
  | { type: 'directory:created'; path: string }
  | { type: 'directory:deleted'; path: string }

License

MIT

About

Unified filesystem abstraction for browser storage (OPFS, IndexedDB)

Resources

License

Stars

Watchers

Forks

Packages

No packages published