Developer

Content Cache (contentCache)

Bundle-writable shared cache for syncing vendor content with upsert and tombstone.

ctx.sdk.contentCache is a generic upsert plus tombstone primitive for caching synced vendor content. It is backed by the host’s wp_content.db, with rows scoped by (resourceId, table, id). Pair it with ctx.sdk.http.requestPaginated to compose a full vendor sync method end-to-end in TypeScript, replacing per-vendor cmd_*_sync_* Rust commands.

Scope required: contentCache:read / contentCache:write

Usage

// 1. Walk pages via requestPaginated (host runs the loop).
const { items: rawEdges } = await ctx.sdk.http.requestPaginated({
  resourceId, method: "POST", path: "graphql.json",
  bodyTemplate: { query: PRODUCTS_QUERY, variables: {} },
  pagination: { style: "graphql-cursor", itemsPath: "data.products.edges" },
});

// 2. Transform / filter in TS.
const items = rawEdges.map(transformEdge).filter(Boolean);

// 3. Persist via contentCache.sync (host serializes the SQLite write).
const { synced, deleted, table } = await ctx.sdk.contentCache.sync({
  resourceId,
  table: "shopify_products",
  items,
  primaryKey: "id",         // default
  deleteMissing: true,      // default: tombstone rows not in `items`
});

Other operations

const rows = await ctx.sdk.contentCache.list({
  resourceId, table: "shopify_products",
  where: { equality: { status: "active" } },     // top-level fields only, v1
  includeDeleted: false,                          // default false
  limit: 50,                                       // 0 = unbounded (default)
});
// rows: each row has _id, _syncedAt, _isDeleted appended to its data_json.

const tombstoned = await ctx.sdk.contentCache.delete({
  resourceId, table: "shopify_products", ids: ["123", "456"],
});

// Hard delete (irreversible). Omit `table` to clear every content table
// for the resource (used on disconnect).
await ctx.sdk.contentCache.clear({ resourceId, table: "shopify_products" });

Manifest configuration

{
  "scopes": [
    "contentCache:read",
    "contentCache:write"
  ]
}

Notes

  • Tables must be in the host’s CONTENT_TABLES allowlist. Adding a new table is a host edit today; a future version will let manifests declare them.
  • where.equality only. There is no range or ordering beyond synced_at DESC, and no joins. Power callers can fall back to raw SQL.
  • Soft-tombstone by default (delete); hard delete via clear.
  • One row per (resourceId, table, id). Namespace conflicts across applets are a known limitation; a future version adds manifest-declared table prefixes.