Documentation Index
Fetch the complete documentation index at: https://docs.metabind.ai/llms.txt
Use this file to discover all available pages before exploring further.
The resolvedPackageData query fetches package data by its content-addressed ID. This is used with the normalized caching pattern to efficiently retrieve package data that may be shared across multiple content items.
Query
query GetPackageData($packageId: ID!) {
resolvedPackageData(packageId: $packageId) {
id
version
components
assets
cdnUrl
}
}
Parameters
| Parameter | Type | Required | Description |
|---|
packageId | ID! | Yes | Content-addressed package ID (SHA-256 hash) |
Example
query {
resolvedPackageData(packageId: "abc123def456...") {
id
version
components
assets
cdnUrl
}
}
Response:
{
"data": {
"resolvedPackageData": {
"id": "abc123def456...",
"version": "1.0.0",
"components": "{\"ArticleLayout\":\"const body = ...\",\"ProductCard\":\"const body = ...\"}",
"assets": "{\"ArticleLayout\":[{\"name\":\"hero\",\"url\":\"...\"}]}",
"cdnUrl": "https://cdn.metabind.ai/packages/abc123def456..."
}
}
}
ResolvedPackageData Fields
| Field | Type | Description |
|---|
id | ID! | Content-addressed SHA-256 hash |
version | String! | Semantic version |
components | String! | JSON object mapping component names to compiled code |
assets | String! | JSON object mapping component names to asset arrays |
cdnUrl | String | CDN URL for fetching package data |
Usage Pattern
This query is typically used with resolvedRef for efficient caching:
Step 1: Fetch Content with References
query GetContentWithCaching($id: ID!) {
content(id: $id) {
id
name
compiled
resolvedRef {
package
dependencies
}
}
}
Step 2: Check Cache and Fetch Missing Packages
const packageCache = new Map();
async function getPackageData(id) {
// Check cache first
if (packageCache.has(id)) {
return packageCache.get(id);
}
// Fetch from API
const { data } = await client.query({
query: GET_PACKAGE_DATA,
variables: { packageId: id }
});
// Cache the result (content-addressed, so safe to cache forever)
packageCache.set(id, data.resolvedPackageData);
return data.resolvedPackageData;
}
async function fetchMissingPackages(ids) {
const missing = ids.filter(id => !packageCache.has(id));
// Batch fetch missing packages
const results = await Promise.all(
missing.map(id => getPackageData(id))
);
return results;
}
Step 3: Load Content with Cached Packages
async function loadContent(id) {
// Fetch content with references only
const { data } = await client.query({
query: GET_CONTENT_WITH_CACHING,
variables: { id }
});
const content = data.content;
// Fetch any missing package data
const packageIds = [
content.resolvedRef.package,
...content.resolvedRef.dependencies
];
await fetchMissingPackages(packageIds);
// Now render with cached packages
renderContent(content, packageCache);
}
Benefits
- Smaller Payloads: Content responses only include package IDs, not full data
- Efficient Caching: Content-addressed IDs mean packages never change
- Shared Data: Multiple content items referencing the same package share cached data
- WebSocket Compliance: Subscription payloads stay under 100KB limit
- Reduced Bandwidth: Only fetch packages once, regardless of how many content items use them
Draft Packages
Draft packages use a special ID format and should not be cached long-term:
function isDraftPackage(id) {
return id.startsWith('draft:');
}
async function getPackageData(id) {
// Draft packages should not be cached long-term
if (isDraftPackage(id)) {
return await fetchPackageData(id);
}
// Published packages can be cached forever
if (packageCache.has(id)) {
return packageCache.get(id);
}
const data = await fetchPackageData(id);
packageCache.set(id, data);
return data;
}
See the Caching documentation for a complete guide to implementing normalized package caching.