Skip to main content

DATASTORE PROVIDER

A datastore provider is a TypeScript module that implements data persistence for a custom backend (cloud object storage, networked filesystem, etc.). The file lives in extensions/datastores/ and exports a datastore object that swamp loads at runtime.

For datastore configuration and usage (setup, sync, locking, CLI commands), see the Datastore Configuration reference.

Export Shape

import { z } from "npm:zod@4";

export const datastore = {
  type: "@mycollective/my-datastore",
  name: "My Datastore",
  description: "Store data in my backend",
  configSchema: z.object({
    bucket: z.string().describe("Storage bucket name"),
    region: z.string().optional().describe("Region"),
  }),
  createProvider(config: Record<string, unknown>): DatastoreProvider {
    // validate config, return provider instance
  },
};

Fields

Field Type Description
type string Unique identifier in @collective/name format. Reserved collectives: swamp, si.
name string Human-readable display name.
description string Short description shown in swamp datastore output.
configSchema z.ZodTypeAny Zod schema that validates the config object in .swamp.yaml.
createProvider (config: Record<string, unknown>) => DatastoreProvider Factory that returns a provider instance.

DatastoreProvider Interface

The object returned by createProvider must implement the following methods.

Method Signature Required Description
createLock (datastorePath: string, options?: LockOptions) => DistributedLock Yes Create a distributed lock for the given path.
createVerifier () => DatastoreVerifier Yes Create a health-check verifier.
resolveDatastorePath (repoDir: string) => string Yes Resolve the datastore path for a given repo.
createSyncService (repoDir: string, cachePath: string) => DatastoreSyncService No Create a sync service for bidirectional transfer.
resolveCachePath (repoDir: string) => string | undefined No Resolve the local cache path. Return undefined if no cache is used.

Supporting Interfaces

DistributedLock

Coordinates exclusive access to prevent concurrent writers from corrupting data.

Method Signature Description
acquire () => Promise<void> Acquire the lock. Retries until timeout.
release () => Promise<void> Release the lock.
withLock <T>(fn: () => Promise<T>) => Promise<T> Acquire, run fn, release. Releases on error.
inspect () => Promise<LockInfo | null> Return current lock metadata, or null if unheld.
forceRelease (expectedNonce: string) => Promise<boolean> Force-release a stale lock matching the nonce.

LockOptions

Field Type Default Description
lockKey string Custom lock key (overrides default).
ttlMs number 30000 Lock lifetime before considered stale.
retryIntervalMs number 1000 Retry interval when lock is held.
maxWaitMs number 60000 Maximum wait before giving up.

DatastoreVerifier

Method Signature Description
verify () => Promise<DatastoreHealthResult> Run a health check.

DatastoreHealthResult

Field Type Description
healthy boolean Whether the backend is reachable.
message string Human-readable status message.
latencyMs number Round-trip latency in milliseconds.
datastoreType string The provider type identifier.
details Record<string, string> (optional) Extra diagnostic data.

DatastoreSyncService

Implement this if the backend supports bidirectional file synchronization.

Method Signature Description
pullChanged () => Promise<number | void> Download changed files from the remote.
pushChanged () => Promise<number | void> Upload changed files to the remote.

Return the number of files transferred, or void.


Packaging

Declare the datastore in your extension's manifest:

datastores:
  - my_datastore.ts

The file path is relative to the extensions/datastores/ directory within the extension root.