Files
suaveplan/packages/persistence/storage/storage-uri-plugin-fallback/src/ops/metadata.md
2026-05-27 23:47:53 +01:00

2.3 KiB

ops/metadata

Purpose

The ops/metadata module hosts fallbackExists and fallbackStat, the metadata-side adapter operations. Both walk the candidate list sequentially and return as soon as a candidate produces an authoritative answer. Failures fall through cleanly: exists resolves false when no candidate confirms presence, and stat resolves undefined when no candidate can answer cheaply.

Features

  • Sequential walk with first-truthy semantics for exists.
  • Sequential walk returning the first defined StatResult for stat.
  • Soft failures: aggregate exhaustion does not raise, mirroring the semantics of StorageLike.exists.
  • Recursion-context propagation via the shared DepthContext.

Usage: Basic Example

import {
    fallbackExists,
    fallbackStat,
} from "@suaveplan/storage-uri-plugin-fallback/ops";

const present = await fallbackExists(uri, ctx, deps, signal);
const meta = await fallbackStat(uri, ctx, deps, signal);

Usage: Advanced Example

import { fallbackStat } from "@suaveplan/storage-uri-plugin-fallback/ops";

const meta = await fallbackStat(
    uri,
    ctx,
    { resolver, policy: { ...policy, errorClass: "any" }, events },
    signal,
);
if (meta?.etag) console.log("etag:", meta.etag);

API Reference

  • fallbackExists(uri, ctx, deps, signal): Promise<boolean>
  • fallbackStat(uri, ctx, deps, signal): Promise<StatResult | undefined>
  • MetadataDeps — { resolver, policy, events }.

Implementation Notes

Both functions internally throw a sentinel error when a candidate answers "no" or "no-stat" so the shared walk machinery treats the leg as a transient failure and continues. The outer try/catch collapses the walk-exhausted ALL_CANDIDATES_FAILED into the soft return values the StorageLike contract expects from these methods.

This module is part of the universal fallback URI plugin family. It coordinates with the recursion, walk, ops, observability, and classification modules through small, narrowly-typed value contracts. The implementation deliberately keeps surface area small so each piece can be substituted or instrumented independently without touching consumers. Refer to the package README for the end-to-end picture and to the spec delta for the requirement matrix this module helps satisfy.