social components
inlay.at
atproto
components
sdui
1// @inlay/cache — Cache declaration primitives for inlay components.
2//
3// Pure JavaScript, no dependencies. Reads from a well-known global
4// set up by the inlay server SDK at runtime. Crashes if the global
5// is absent — calling cache functions outside an inlay server is a bug.
6//
7// Types mirror at.inlay.defs (cachePolicy, tagRecord, tagLink).
8
9// -- Types (from at.inlay.defs lexicon) --
10
11type Life = "seconds" | "minutes" | "hours" | "max";
12
13type TagRecord = {
14 $type: "at.inlay.defs#tagRecord";
15 uri: string;
16};
17
18type TagLink = {
19 $type: "at.inlay.defs#tagLink";
20 subject: string;
21 from?: string;
22};
23
24type CacheTag = TagRecord | TagLink;
25
26// -- Dispatcher (set by server SDK) --
27
28interface Dispatcher {
29 cacheLife(life: Life): void;
30 cacheTag(tag: CacheTag): void;
31}
32
33const GLOBAL_KEY = Symbol.for("inlay.cache");
34
35function getDispatcher(): Dispatcher {
36 const d = (globalThis as Record<symbol, Dispatcher | undefined>)[GLOBAL_KEY];
37 if (!d) {
38 throw new Error(
39 "@inlay/cache: server SDK not initialized. " +
40 "Cache functions can only be called inside an inlay component handler."
41 );
42 }
43 return d;
44}
45
46// -- Public API --
47
48/**
49 * Declare how frequently the component's data changes.
50 * Multiple calls are collected — the strictest (shortest) life wins.
51 */
52export function cacheLife(life: Life): void {
53 getDispatcher().cacheLife(life);
54}
55
56/**
57 * Declare a cache dependency on a record, collection, or identity.
58 */
59export function cacheTagRecord(uri: string): void {
60 getDispatcher().cacheTag({ $type: "at.inlay.defs#tagRecord", uri });
61}
62
63/**
64 * Declare a cache dependency on backlinks to a subject.
65 */
66export function cacheTagLink(subject: string, from?: string): void {
67 const tag: TagLink = { $type: "at.inlay.defs#tagLink", subject };
68 if (from) tag.from = from;
69 getDispatcher().cacheTag(tag);
70}
71
72export type { Life, CacheTag, TagRecord, TagLink, Dispatcher };