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.tsThe file path is relative to the extensions/datastores/ directory within the
extension root.