Skip to content

Storage

Persistent config storage with local, remote, and hybrid strategies.

typescript
import {
  createIndexedDBStore,
  createRemoteStore,
  createHybridStore,
} from 'alap/storage';

ConfigStore interface

All store implementations share this contract. One store manages many named configs.

MethodSignatureDescription
save()(name: string, config: AlapConfig) => Promise<void>Save or overwrite a config
load()(name: string) => Promise<AlapConfig | null>Load by name. null if not found.
loadEntry()(name: string) => Promise<ConfigEntry | null>Load config + metadata
list()() => Promise<string[]>List all saved config names
remove()(name: string) => Promise<void>Delete by name. No-op if not found.
typescript
const store = await createIndexedDBStore();

await store.save('news-page', newsConfig);
await store.save('docs-page', docsConfig);

const names = await store.list();
// → ['docs-page', 'news-page']

const docs = await store.load('docs-page');

const entry = await store.loadEntry('docs-page');
console.log(`Last saved: ${entry.meta.updatedAt}`);

await store.remove('news-page');

createIndexedDBStore()

Browser-local persistence. Requires idb peer dependency.

bash
npm install idb
typescript
const store = await createIndexedDBStore();
await store.save('myconfig', config);
const loaded = await store.load('myconfig');

createRemoteStore(options)

REST API client. Works in both browser and Node.js (uses fetch).

typescript
const store = createRemoteStore({
  baseUrl: 'http://localhost:3000',
  token: 'optional-bearer-token',
  headers: { 'X-Custom': 'value' },
});
OptionTypeDescription
baseUrlstringAPI server URL
tokenstringBearer token for Authorization header
headersRecord<string, string>Extra headers on every request

REST endpoints

OperationHTTPURL
savePUT /configs/:nameBody: JSON config
loadGET /configs/:nameResponse: JSON config
listGET /configsResponse: string array
removeDELETE /configs/:name

createHybridStore(options)

Write-through local + remote. Reads from local first, syncs remote in background.

typescript
const local = await createIndexedDBStore();
const remote = createRemoteStore({ baseUrl: '...' });
const store = createHybridStore({
  local,
  remote,
  onRemoteError: (op, name, err) => console.warn(`${op} failed for ${name}`, err),
});
OptionTypeDescription
localConfigStoreLocal store (e.g. IndexedDB)
remoteConfigStoreRemote store (e.g. REST API)
onRemoteError(op, name, err) => voidError callback. Store continues from local on failure.
typescript
// Offline-resilient config loading
const store = createHybridStore({
  local: await createIndexedDBStore(),
  remote: createRemoteStore({ baseUrl: 'https://api.example.com' }),
  onRemoteError: (op, name, err) => {
    showToast(`Offline — using cached "${name}"`);
  },
});

// First load: fetches from remote, caches locally
// Subsequent loads: instant from IndexedDB, background sync
const config = await store.load('main');