trellis
Version:
Agentic State Engine — event-sourced causal graph with branching, decision traces, and realtime sync for AI-native applications
85 lines • 3.61 kB
TypeScript
/**
* Trellis CMS Client
*
* Thin HTTP client for reading content collections from a Trellis-compatible store
* (currently opencode's /store/* routes). Reads only; writes happen through the
* IDE's CMS panel or the agent's `cms` tool.
*
* @example
* import { createCmsClient } from "trellis/cms";
*
* const cms = createCmsClient({ url: "http://localhost:4096" });
*
* // List published blog posts with author resolved
* const posts = await cms.collection("blog_post").list({
* status: "published",
* expand: ["author"],
* });
*
* // Subscribe to live updates (polling for now, SSE later)
* const off = cms.collection("blog_post").subscribe((entries) => {
* console.log(entries);
* });
*
* @module trellis/cms
*/
import type { CmsClientOptions, Collection, Entry, EntrySubscribeOptions, EntrySubscriber, GetOptions, ListOptions, ListSubscribeOptions, ListSubscriber, Unsubscribe, FieldDefinition } from './types.js';
import { type RawEntity, type RawFact } from './internal.js';
export declare class CmsClient {
private readonly url;
private readonly basePath;
private readonly directory?;
readonly pollIntervalMs: number;
private readonly fetchFn;
private readonly apiKey?;
private readonly subscriptions;
constructor(opts: CmsClientOptions);
collection<T extends Record<string, unknown> = Record<string, unknown>>(key: string): CollectionRef<T>;
entry<T extends Record<string, unknown> = Record<string, unknown>>(id: string): EntryRef<T>;
/** List CMS collections (TypeSchema entities marked cms=true). */
collections(): Promise<Collection[]>;
close(): void;
/**
* Shared polling subscription. Multiple subscribers to the same key share a
* single timer and one HTTP request per poll cycle. New subscribers receive
* the most recently fetched value immediately if one is cached.
*
* @internal
*/
_share<T>(key: string, fetcher: () => Promise<T>, callback: (value: T) => void, extras?: {
equals?: (prev: unknown, next: unknown) => boolean;
onError?: (err: unknown) => void;
}): Unsubscribe;
/** @internal */
_get<T>(path: string): Promise<T | undefined>;
/** @internal */
_entities(): Promise<RawEntity[]>;
_facts(): Promise<RawFact[]>;
/** @internal */
_entryById(id: string, schemaFacts?: RawFact[]): Promise<Entry | null>;
}
export declare class CollectionRef<T extends Record<string, unknown> = Record<string, unknown>> {
private readonly client;
readonly key: string;
constructor(client: CmsClient, key: string);
list(opts?: ListOptions): Promise<Entry<T>[]>;
get(id: string, opts?: GetOptions): Promise<Entry<T> | null>;
/**
* Subscribe to changes. Currently implemented as polling; a future SSE-backed
* upgrade will replace the transport without changing this API.
*
* Multiple subscribers to the same collection + opts share one polling timer
* and one HTTP request per cycle.
*/
subscribe(callback: ListSubscriber<T>, opts?: ListSubscribeOptions): Unsubscribe;
schema(): Promise<FieldDefinition[]>;
}
export declare class EntryRef<T extends Record<string, unknown> = Record<string, unknown>> {
private readonly client;
readonly id: string;
constructor(client: CmsClient, id: string);
get(opts?: GetOptions): Promise<Entry<T> | null>;
subscribe(callback: EntrySubscriber<T>, opts?: EntrySubscribeOptions): Unsubscribe;
}
export declare function createCmsClient(opts: CmsClientOptions): CmsClient;
//# sourceMappingURL=client.d.ts.map