Skip to main content

API Reference: Storage & Persistence Utilities

The Storage & Persistence API in Siglo provides durable checkpointing, execution stack snapshots, optimistic concurrency control (OCC), multi-tenant namespace isolation, and pluggable storage adapters for distributed backends (e.g. PostgreSQL, Redis).

Table of Contents


The StorageAdapter Interface

Custom persistence adapters (such as @siglo/postgres and @siglo/redis) implement the StorageAdapter interface:

Adapter Management

useStorage(adapter)

Registers the global storage adapter for the Siglo runtime. Once registered, all workflow checkpoints, context updates, and distributed caching route through this adapter.

Signature

Example


getStorageAdapter()

Returns the currently registered StorageAdapter, or undefined if Siglo is operating on the default in-memory storage manager.

Signature


setErrorMode(mode)

Configures how Siglo responds when storage adapter operations fail (e.g. database disconnect during checkpoint save).

Signature

Modes

  1. 'best-effort' (default): Catches storage errors silently; execution continues without interrupting the running workflow.
  2. 'warn': Logs warnings to console.warn when a storage operation fails, but allows workflow execution to continue.
  3. 'strict': Rejects unhandled storage promises and throws StorageAdapterException when StorageManager.saveCheckpoint is awaited. Note that inline checkpoint() calls capture snapshots synchronously and attach background rejection handlers; distinguish synchronous snapshot capture from awaited checkpoint persistence before assuming fail-closed execution.

Example


getErrorMode()

Returns the active StorageErrorMode.

Signature


Checkpointing and Resumption

checkpoint(stackId, options?)

Captures an instantaneous, immutable checkpoint snapshot of the execution stack, serializing all step contexts, revision counter, and status.

Signature

Throws

  • CheckpointConflictException: If options.expectedRevision does not match the stack’s current revision.
  • StorageAdapterException: In strict error mode if the adapter fails to persist.

getCheckpoint(stackId)

Retrieves the serialized checkpoint snapshot for a given execution stack ID from the active adapter or in-memory manager.

Signature

Example


restoreCheckpoint(data, options?)

Restores an execution stack and all step contexts into active memory from a serialized checkpoint snapshot.

Signature

Throws

  • CheckpointVersionException: If checkpoint schema version exceeds supported runtime version.
  • NamespaceMismatchException: If options.expectedNamespace does not match checkpointData.namespace.

cleanExpiredCheckpoints()

Scans all active checkpoints and deletes those whose expiresAt timestamp has elapsed.

Signature

Example


Serialization and Hydration

serializeState(stackId?)

Serializes workflow state into a portable JSON string.
  • If stackId is provided, serializes only that specific execution stack.
  • If omitted, serializes all stacks, step contexts, and configuration into a global state snapshot.

Signature


hydrateState(serialized, options?)

Restores complete workflow storage state from a serialized JSON string.

Signature


Checkpoint Schema v2.0.0

Checkpoints are serialized using standard Schema v2.0.0:

Optimistic Concurrency Control (OCC)

Siglo uses optimistic concurrency control to prevent multiple distributed workers from overwriting checkpoints concurrently.
  1. Every checkpoint increments an integer revision counter (0, 1, 2, ...).
  2. When saving with options.expectedRevision, Siglo verifies that expectedRevision === currentRevision.
  3. If another worker updated the checkpoint in the interim, CheckpointConflictException is thrown, allowing the caller to reload and retry.

Namespace Scoping and Partitioning

namespace provides key partitioning and scoping metadata across storage adapters:
  • Scopes cache keys, checkpoints, and wait records to prevent key collisions across tenants.
  • restoreCheckpoint checks the supplied expected namespace against the stored checkpoint namespace when both are explicitly provided.
  • Important: Namespace scoping is logical key partitioning, not an enforced authenticated tenant boundary. Application-level authorization and explicit validation are required to prevent unauthorized resumption or cross-tenant access.