UCD.js Docs
FS BackendSpecification

Overview

Complete specification for the FileSystemBackend interface

This page describes the public contract behind @ucdjs/fs-backend.

The goal of the package is to make filesystem-like operations portable across different storage implementations without hiding the important semantics.

FileSystemBackend Interface

interface FileSystemBackend
  extends FileSystemBackendOperations, FileSystemBackendMutableMethods {
  readonly features: ReadonlySet<FileSystemBackendFeature>;
  readonly meta: FileSystemBackendMeta;
  hook: HookableCore<BackendHooks>["hook"];
}

Required Operations

Every backend must implement:

interface FileSystemBackendOperations {
  read(path: string): Promise<string>;
  readBytes(path: string): Promise<Uint8Array>;
  list(path: string, options?: ListOptions): Promise<BackendEntry[]>;
  exists(path: string): Promise<boolean>;
  stat(path: string): Promise<BackendStat>;
}

read(path)

Reads a file as text.

Use this for UTF-8 and text-oriented content. For binary data, use readBytes().

readBytes(path)

Reads a file as raw bytes.

This is the binary-safe path and should be the default choice for archives, compressed assets, or unknown content types.

list(path, options?)

Lists a directory and returns backend entries.

interface ListOptions {
  recursive?: boolean;
}
  • non-recursive listings return the immediate children
  • recursive listings return a nested tree using children
  • directory entries use canonical directory paths

exists(path)

Best-effort existence check.

This intentionally returns only a boolean. It may flatten “missing” and “could not determine existence” into false, especially for remote transports.

stat(path)

Returns metadata:

interface BackendStat {
  type: "file" | "directory";
  size: number;
  mtime?: Date;
}

Use stat() when you need a typed failure mode or authoritative metadata.

Mutable Operations

interface FileSystemBackendMutableMethods {
  write(path: string, data: string | Uint8Array): Promise<void>;
  mkdir(path: string): Promise<void>;
  remove(path: string, options?: RemoveOptions): Promise<void>;
  copy(sourcePath: string, destinationPath: string, options?: CopyOptions): Promise<void>;
}

These methods are always present on a FileSystemBackend.

Use backend.features or assertFeature() to check whether a backend actually supports a mutable operation before relying on it. Unsupported operations throw BackendUnsupportedOperation.

Path Contract

Backends must return canonical paths:

  • all paths start with /
  • directories end with /
  • files do not end with /

Examples:

  • /15.1.0/ucd/
  • /15.1.0/ucd/UnicodeData.txt

Input paths may be normalized by individual backends, but consumers should still prefer canonical paths when calling backend operations.

Metadata and Identity

Every backend also exposes:

  • meta: backend name and description
  • features: runtime support for optional operations
  • hook(): lifecycle hooks for observability

Custom Backends

Use defineBackend() to implement your own backend. That gives you:

  • option validation
  • feature inference
  • hook wrapping
  • consistent unsupported-operation behavior

For HTTP-style services, follow the HTTP compatibility guide.

On this page