Surfaces ↓
Asset
client.asset Daemon-side asset events. Got and NotFound resolve a webapp Get
(correlated by request_id). Ready broadcasts to all connected
webapps whenever the cache gains an asset, regardless of source
(companion push, iAP2 FileTransfer, request fulfilment, lazy disk
load). Cleared broadcasts on every eviction path - LRU pressure,
TTL expiry, companion-issued Clear, daemon shutdown - so SDK
consumers can drop Blob URLs and refetch as needed.
Requests
you ask, the daemon answers; await the tagged result and check .ok
get(AssetGet): Promise<TypedRequestResult<AssetGot, AssetNotFound>>
push form: onGot (subscribe instead of awaiting)
Webapp request: read an asset by id. Bridge replies with Got on hit
or NotFound (domain) when neither cache nor companion has it.
const res = await client.asset.get({ id: '...', requestId: '...' });
if (res.ok) {
console.log(res.response.requestId);
} else {
console.warn(res.kind, res.error);
} type Result =
| { ok: true; response: AssetGot }
| { ok: false; kind: 'domain'; error: AssetNotFound }
| { ok: false; kind: 'protocol'; error: WireError }; Commands
fire-and-forget; the promise resolves once the daemon has taken the message
preload(AssetPreload): Promise<void>
await client.asset.preload({ ids: [] }); Events
the daemon pushes these unprompted; subscribing returns an unsubscribe function
onReady(handler: (AssetReady) => void): () => void
const off = client.asset.onReady((assetReady) => {
console.log(assetReady.id);
});
// call off() to unsubscribe onCleared(handler: (AssetCleared) => void): () => void
const off = client.asset.onCleared((assetCleared) => {
console.log(assetCleared.id);
});
// call off() to unsubscribe Types
shapes referenced above, as the SDK types them
An asset became fetchable in the cache; a subsequent AssetGet for this
id will resolve without a companion round trip.
type AssetReady = {
id: string;
}; An asset was evicted from the cache; webapps should drop any cached Blob URL for it and refetch on next use.
type AssetCleared = {
id: string;
}; Webapp request: read an asset by id. Bridge replies with Got on hit
or NotFound (domain) when neither cache nor companion has it.
type AssetGet = {
id: string; // Opaque asset id, e.g. `iap2/art/<persistent-hex>/<n>` for iAP2 art or a companion-defined shape like `spotify/img/<id>`.
requestId: string; // Correlates the `Got` or `NotFound` reply back to this request.
}; Successful reply to AssetGet: the requested bytes.
type AssetGot = {
requestId: string; // Echoes the `AssetGet.request_id` this reply resolves.
id: string; // Echoes the requested asset id.
bytes: number[]; // Raw asset bytes, already reassembled if the companion sent them as a chunked BT transfer.
mime?: string; // Best-effort content type; `None` when the source didn't provide one.
}; Domain-error reply to AssetGet: neither the cache nor a connected
companion has an asset for this id.
type AssetNotFound = {
requestId: string; // Echoes the `AssetGet.request_id` this reply resolves.
id: string; // Echoes the requested asset id.
}; Webapp hint to warm the asset cache for a set of ids so subsequent
Get calls hit cache. Fire-and-forget; webapps observe completion
via Asset.Ready events.
type AssetPreload = {
ids: string[]; // Ids to prefetch, capped at 64 per call. Ids already cached and ids under the `iap2/art/` prefix are skipped, since iAP2 art only ever arrives via a push from the phone, not a pull request.
};