Skip to main content

API

The entire surface of datavolve: one factory, three builder members, and the result types they produce.

datavolve()

Creates an empty, immutable datavolve instance.

.add(version, evolve)

Appends an evolution and returns a new datavolve instance whose output type is inferred from evolve’s return value.

  • version - a positive integer, sequential from 1. Adding a non-sequential version throws immediately (a build-time programmer error), which also protects you from silently misaligning stored data if an evolution is deleted.
  • evolve - (prev) => next. prev is unknown for version 1, and the previous evolution’s output type thereafter.

.run(data, fromVersion)

Runs the applicable evolutions. Total - it never throws; an evolution that itself throws is caught and reported. Returns an EvolveResult.

  • data: unknown - the stored value.
  • fromVersion: number - the version data is currently at. Required.

.latestVersion

The highest version datavolve knows about. Use it to stamp data on write-back:

storage.setItem(
  key,
  JSON.stringify({ version: settings.latestVersion, value }),
);

Types

type EvolveResult<T> =
  | { success: true; value: T; version: number } // version = the version `value` is now at (always latestVersion)
  | { success: false; error: EvolveError };

type EvolveError =
  | { code: "ahead"; fromVersion: number; latestVersion: number }
  | { code: "malformed"; fromVersion: number }
  | { code: "failed"; failedVersion: number; cause: unknown };

type Datavolve<T>; // the datavolve instance, generic over its latest output type

Version Behavior

fromVersionResult
=== latestVersionsuccess, value returned unchanged (no-op fast path)
0 ≤ fromVersion < latestVersionsuccess, evolutions (fromVersion, latestVersion] applied in order
> latestVersionfailure ahead
< 0 or non-integerfailure malformed
an evolution throwsfailure failed (with cause)