UCD.js Docs
FS Backend

FS Backend

Filesystem backend abstraction for local and remote storage

The @ucdjs/fs-backend package provides the filesystem abstraction used across UCD.js for local disk access, HTTP-backed storage, and custom backend implementations.

@ucdjs/fs-backend is intended to become the shared storage foundation across @ucdjs/ucd-store, lockfile utilities, and future backend-compatible tooling.

Getting Started

Installation

npm install @ucdjs/fs-backend

Pick a Built-In Backend

Use the Node backend for local disk access or the HTTP backend for read-only remote access.

node.ts
import NodeFileSystemBackend from "@ucdjs/fs-backend/backends/node";

const backend = NodeFileSystemBackend({
  basePath: "/path/to/store",
});
http.ts
import HTTPFileSystemBackend from "@ucdjs/fs-backend/backends/http";

const backend = HTTPFileSystemBackend({
  baseUrl: new URL("https://api.ucdjs.dev/api/v1/files"),
});

Use the Shared API

const text = await backend.read("/16.0.0/ucd/UnicodeData.txt");
const bytes = await backend.readBytes("/16.0.0/ucd/UnicodeData.txt");
const entries = await backend.list("/16.0.0/ucd/");
const exists = await backend.exists("/16.0.0/ucd/Blocks.txt");
const stat = await backend.stat("/16.0.0/ucd/Blocks.txt");

Core API

Required operations:

  • read(path): Promise<string>
  • readBytes(path): Promise<Uint8Array>
  • list(path, options?): Promise<BackendEntry[]>
  • exists(path): Promise<boolean>
  • stat(path): Promise<BackendStat>

Optional mutable operations:

  • write(path, data)
  • mkdir(path)
  • remove(path, options?)
  • copy(sourcePath, destinationPath, options?)

Path Contract

  • All backend paths start with /
  • Directory paths end with /
  • File paths do not end with /

Features

Mutable support is exposed through backend.features:

backend.features.has("write");
backend.features.has("copy");

Notes

  • exists() is intentionally lossy. A backend may return false both for "missing" and "could not determine existence". Use stat() when you need error detail.
  • copy() is intra-backend only.
  • File copies use destinationPath as an exact target by default, but copy into a destination directory when the destination ends with / or already exists as a directory.
  • Directory copies require recursive: true.

Built-In Backends

Documentation

  • Specification - Reference for the backend contract
    • Features - Runtime feature detection with features, hasFeature(), and assertFeature()
    • Errors - Stable backend error types and handling patterns
  • Backends - Built-in Node and HTTP backend implementations
  • Hooks - Observe backend operations for logging and instrumentation
  • HTTP Compatibility Guide - Build an HTTP application that works with the built-in HTTP backend

Creating Custom Backends

Use defineBackend() when you want to expose the same API from your own storage system.

import { defineBackend } from "@ucdjs/fs-backend";

const MemoryBackend = defineBackend({
  meta: {
    name: "Memory Backend",
  },
  setup() {
    return {
      async read(path) {
        return `value:${path}`;
      },
      async readBytes() {
        return new Uint8Array();
      },
      async list() {
        return [];
      },
      async exists() {
        return false;
      },
      async stat() {
        return {
          type: "file",
          size: 0,
        };
      },
    };
  },
});

If your backend is HTTP-based, follow the HTTP compatibility guide.

On this page