social components inlay-proto.up.railway.app/
atproto components sdui

restructure view to pull prop name out

+397 -289
+49 -33
generated/at/inlay/component.defs.ts
··· 27 | l.Unknown$TypedObject; 28 29 /** 30 - * What data types this component is a view for 31 */ 32 - view?: ( 33 - | l.$Typed<ViewRecord> 34 - | l.$Typed<ViewPrimitive> 35 - | l.Unknown$TypedObject 36 - )[]; 37 38 /** 39 * Ordered list of pack URIs (import stack). First pack that exports an NSID wins. ··· 70 false 71 ) 72 ), 73 - view: l.optional( 74 - l.array( 75 - l.typedUnion( 76 - [ 77 - l.typedRef<ViewRecord>((() => viewRecord) as any), 78 - l.typedRef<ViewPrimitive>((() => viewPrimitive) as any), 79 - ], 80 - false 81 - ) 82 - ) 83 - ), 84 imports: l.optional(l.array(l.string({ format: "at-uri" }))), 85 via: l.optional( 86 l.typedUnion( ··· 151 152 export { bodyTemplate }; 153 154 - /** Component is a view for individual records of a collection. Omit collection for a generic record view. When rkey is present, the component accepts bare DIDs (expanded to full AT URIs) and appears on identity pages. */ 155 type ViewRecord = { 156 $type?: "at.inlay.component#viewRecord"; 157 ··· 164 * The record key, baked from the collection's lexicon at authoring time. Presence enables DID expansion and identity page routing. 165 */ 166 rkey?: string; 167 - 168 - /** 169 - * Which prop receives the AT URI. 170 - */ 171 - prop: string; 172 }; 173 174 export type { ViewRecord }; 175 176 - /** Component is a view for individual records of a collection. Omit collection for a generic record view. When rkey is present, the component accepts bare DIDs (expanded to full AT URIs) and appears on identity pages. */ 177 const viewRecord = l.typedObject<ViewRecord>( 178 $nsid, 179 "viewRecord", 180 l.object({ 181 collection: l.optional(l.string({ format: "nsid" })), 182 rkey: l.optional(l.string({ maxLength: 512 })), 183 - prop: l.string({ maxLength: 256 }), 184 }) 185 ); 186 187 export { viewRecord }; 188 189 - /** Component is a view for a primitive value type. */ 190 type ViewPrimitive = { 191 $type?: "at.inlay.component#viewPrimitive"; 192 ··· 218 | "record-key" 219 | "tid" 220 | l.UnknownString; 221 - 222 - /** 223 - * Which prop receives the value. 224 - */ 225 - prop: string; 226 }; 227 228 export type { ViewPrimitive }; 229 230 - /** Component is a view for a primitive value type. */ 231 const viewPrimitive = l.typedObject<ViewPrimitive>( 232 $nsid, 233 "viewPrimitive", ··· 261 ]; 262 }>({ maxLength: 64 }) 263 ), 264 - prop: l.string({ maxLength: 256 }), 265 }) 266 ); 267
··· 27 | l.Unknown$TypedObject; 28 29 /** 30 + * What data this component views and which prop receives it 31 */ 32 + view?: View; 33 34 /** 35 * Ordered list of pack URIs (import stack). First pack that exports an NSID wins. ··· 66 false 67 ) 68 ), 69 + view: l.optional(l.ref<View>((() => view) as any)), 70 imports: l.optional(l.array(l.string({ format: "at-uri" }))), 71 via: l.optional( 72 l.typedUnion( ··· 137 138 export { bodyTemplate }; 139 140 + /** Declares what data this component views and which prop receives it. */ 141 + type View = { 142 + $type?: "at.inlay.component#view"; 143 + 144 + /** 145 + * Which component prop receives the view data. 146 + */ 147 + prop: string; 148 + 149 + /** 150 + * Data types this view accepts. 151 + */ 152 + accepts: ( 153 + | l.$Typed<ViewRecord> 154 + | l.$Typed<ViewPrimitive> 155 + | l.Unknown$TypedObject 156 + )[]; 157 + }; 158 + 159 + export type { View }; 160 + 161 + /** Declares what data this component views and which prop receives it. */ 162 + const view = l.typedObject<View>( 163 + $nsid, 164 + "view", 165 + l.object({ 166 + prop: l.string({ maxLength: 256 }), 167 + accepts: l.array( 168 + l.typedUnion( 169 + [ 170 + l.typedRef<ViewRecord>((() => viewRecord) as any), 171 + l.typedRef<ViewPrimitive>((() => viewPrimitive) as any), 172 + ], 173 + false 174 + ), 175 + { minLength: 1 } 176 + ), 177 + }) 178 + ); 179 + 180 + export { view }; 181 + 182 + /** View accepts individual records of a collection. Omit collection for a generic record view. When rkey is present, the component accepts bare DIDs (expanded to full AT URIs) and appears on identity pages. */ 183 type ViewRecord = { 184 $type?: "at.inlay.component#viewRecord"; 185 ··· 192 * The record key, baked from the collection's lexicon at authoring time. Presence enables DID expansion and identity page routing. 193 */ 194 rkey?: string; 195 }; 196 197 export type { ViewRecord }; 198 199 + /** View accepts individual records of a collection. Omit collection for a generic record view. When rkey is present, the component accepts bare DIDs (expanded to full AT URIs) and appears on identity pages. */ 200 const viewRecord = l.typedObject<ViewRecord>( 201 $nsid, 202 "viewRecord", 203 l.object({ 204 collection: l.optional(l.string({ format: "nsid" })), 205 rkey: l.optional(l.string({ maxLength: 512 })), 206 }) 207 ); 208 209 export { viewRecord }; 210 211 + /** View accepts a primitive value type. */ 212 type ViewPrimitive = { 213 $type?: "at.inlay.component#viewPrimitive"; 214 ··· 240 | "record-key" 241 | "tid" 242 | l.UnknownString; 243 }; 244 245 export type { ViewPrimitive }; 246 247 + /** View accepts a primitive value type. */ 248 const viewPrimitive = l.typedObject<ViewPrimitive>( 249 $nsid, 250 "viewPrimitive", ··· 278 ]; 279 }>({ maxLength: 64 }) 280 ), 281 }) 282 ); 283
+27 -20
lexicons/at/inlay/component.json
··· 21 "description": "How this component is rendered. Omit for primitives rendered by the host." 22 }, 23 "view": { 24 - "type": "array", 25 - "items": { 26 - "type": "union", 27 - "refs": ["#viewRecord", "#viewPrimitive"] 28 - }, 29 - "description": "What data types this component is a view for" 30 }, 31 "imports": { 32 "type": "array", ··· 81 } 82 } 83 }, 84 "viewRecord": { 85 "type": "object", 86 - "description": "Component is a view for individual records of a collection. Omit collection for a generic record view. When rkey is present, the component accepts bare DIDs (expanded to full AT URIs) and appears on identity pages.", 87 - "required": ["prop"], 88 "properties": { 89 "collection": { 90 "type": "string", ··· 95 "type": "string", 96 "maxLength": 512, 97 "description": "The record key, baked from the collection's lexicon at authoring time. Presence enables DID expansion and identity page routing." 98 - }, 99 - "prop": { 100 - "type": "string", 101 - "maxLength": 256, 102 - "description": "Which prop receives the AT URI." 103 } 104 } 105 }, 106 "viewPrimitive": { 107 "type": "object", 108 - "description": "Component is a view for a primitive value type.", 109 - "required": ["type", "prop"], 110 "properties": { 111 "type": { 112 "type": "string", ··· 138 "record-key", 139 "tid" 140 ] 141 - }, 142 - "prop": { 143 - "type": "string", 144 - "maxLength": 256, 145 - "description": "Which prop receives the value." 146 } 147 } 148 }
··· 21 "description": "How this component is rendered. Omit for primitives rendered by the host." 22 }, 23 "view": { 24 + "type": "ref", 25 + "ref": "#view", 26 + "description": "What data this component views and which prop receives it" 27 }, 28 "imports": { 29 "type": "array", ··· 78 } 79 } 80 }, 81 + "view": { 82 + "type": "object", 83 + "description": "Declares what data this component views and which prop receives it.", 84 + "required": ["prop", "accepts"], 85 + "properties": { 86 + "prop": { 87 + "type": "string", 88 + "maxLength": 256, 89 + "description": "Which component prop receives the view data." 90 + }, 91 + "accepts": { 92 + "type": "array", 93 + "minLength": 1, 94 + "items": { 95 + "type": "union", 96 + "refs": ["#viewRecord", "#viewPrimitive"] 97 + }, 98 + "description": "Data types this view accepts." 99 + } 100 + } 101 + }, 102 "viewRecord": { 103 "type": "object", 104 + "description": "View accepts individual records of a collection. Omit collection for a generic record view. When rkey is present, the component accepts bare DIDs (expanded to full AT URIs) and appears on identity pages.", 105 "properties": { 106 "collection": { 107 "type": "string", ··· 112 "type": "string", 113 "maxLength": 512, 114 "description": "The record key, baked from the collection's lexicon at authoring time. Presence enables DID expansion and identity page routing." 115 } 116 } 117 }, 118 "viewPrimitive": { 119 "type": "object", 120 + "description": "View accepts a primitive value type.", 121 + "required": ["type"], 122 "properties": { 123 "type": { 124 "type": "string", ··· 150 "record-key", 151 "tid" 152 ] 153 } 154 } 155 }
+64 -43
packages/@inlay/render/src/index.ts
··· 18 } from "@atproto/syntax"; 19 import { validateProps } from "./validate.js"; 20 21 - import type { Main as ComponentRecord } from "../../../../generated/at/inlay/component.defs.js"; 22 import { viewRecord as viewRecordSchema } from "../../../../generated/at/inlay/component.defs.js"; 23 import type { Main as PackRecord } from "../../../../generated/at/inlay/pack.defs.js"; 24 import type { CachePolicy } from "../../../../generated/at/inlay/defs.defs.js"; ··· 205 export function resolvePath(obj: unknown, path: string[]): unknown { 206 let current: unknown = obj; 207 for (const seg of path) { 208 - if (current == null) return undefined; 209 if (typeof current === "string") { 210 - if (!current.startsWith("at://")) return undefined; 211 try { 212 const parsed = new AtUri(current); 213 const uriParts: Record<string, string> = { ··· 221 } 222 continue; 223 } 224 - if (typeof current !== "object") return undefined; 225 - if (!Object.hasOwn(current, seg)) return undefined; 226 current = (current as Record<string, unknown>)[seg]; 227 } 228 return current; ··· 257 const type = element.type; 258 let resolvedProps = props; 259 if (component.view) { 260 - resolvedProps = expandBareDid(props, component); 261 } 262 263 if (validate) { ··· 295 296 for (let i = 0; i < importStack.length; i++) { 297 const pack = (await packPromises[i]) as PackRecord | null; 298 - if (!pack || !pack.exports) continue; 299 300 const entry = pack.exports.find((e) => e.type === nsid); 301 - if (!entry) continue; 302 303 const component = (await resolver.fetchRecord( 304 entry.component 305 )) as ComponentRecord | null; 306 - if (!component) continue; 307 308 return { 309 componentUri: entry.component, ··· 353 let cache: CachePolicy | undefined; 354 355 // Find a matching viewRecord and resolve its AT URI prop 356 - const viewRecords = (component.view ?? []).filter((v) => 357 - viewRecordSchema.isTypeOf(v) 358 - ); 359 360 - for (const vr of viewRecords) { 361 - const prop = vr.prop; 362 - const uri = props[prop] as string | undefined; 363 - if (!uri || !uri.startsWith("at://")) { 364 - continue; 365 } 366 - const parsed = new AtUri(uri); 367 - ensureValidNsid(parsed.collection); 368 - if (!parsed.collection || !parsed.rkey) { 369 - continue; 370 - } 371 - if (vr.collection && vr.collection !== parsed.collection) { 372 - continue; 373 - } 374 - const built = await buildRecord( 375 - parsed.host, 376 - parsed.collection, 377 - parsed.rkey, 378 - tree, 379 - resolver 380 - ); 381 - scope = { props: slottedProps, record: built.record }; 382 - cache = built.cache; 383 - break; 384 } 385 386 const node = resolveBindings(tree, scopeResolver(scope)); ··· 454 const refSlots = new Set<object>(); 455 const wireProps = serializeTree(props, (el) => { 456 if (el.type === "at.inlay.Slot") { 457 - if (refSlots.has(el)) return el; 458 throw new Error("Unexpected Slot in props"); 459 } 460 const id = String(refs.size); ··· 511 512 function expandBareDid( 513 props: Record<string, unknown>, 514 - component: ComponentRecord 515 ): Record<string, unknown> { 516 - const view = component.view!; 517 518 // Find the first viewRecord with both collection and rkey — that enables DID expansion 519 - const entry = view 520 .filter((v) => viewRecordSchema.isTypeOf(v)) 521 .find((v) => v.collection && v.rkey); 522 - if (!entry) return props; 523 - 524 - const prop = entry.prop ?? "uri"; 525 const value = props[prop] as string | undefined; 526 - if (!value || !value.startsWith("did:")) return props; 527 528 return { 529 ...props,
··· 18 } from "@atproto/syntax"; 19 import { validateProps } from "./validate.js"; 20 21 + import type { 22 + Main as ComponentRecord, 23 + View, 24 + } from "../../../../generated/at/inlay/component.defs.js"; 25 import { viewRecord as viewRecordSchema } from "../../../../generated/at/inlay/component.defs.js"; 26 import type { Main as PackRecord } from "../../../../generated/at/inlay/pack.defs.js"; 27 import type { CachePolicy } from "../../../../generated/at/inlay/defs.defs.js"; ··· 208 export function resolvePath(obj: unknown, path: string[]): unknown { 209 let current: unknown = obj; 210 for (const seg of path) { 211 + if (current == null) { 212 + return undefined; 213 + } 214 if (typeof current === "string") { 215 + if (!current.startsWith("at://")) { 216 + return undefined; 217 + } 218 try { 219 const parsed = new AtUri(current); 220 const uriParts: Record<string, string> = { ··· 228 } 229 continue; 230 } 231 + if (typeof current !== "object") { 232 + return undefined; 233 + } 234 + if (!Object.hasOwn(current, seg)) { 235 + return undefined; 236 + } 237 current = (current as Record<string, unknown>)[seg]; 238 } 239 return current; ··· 268 const type = element.type; 269 let resolvedProps = props; 270 if (component.view) { 271 + resolvedProps = expandBareDid(props, component.view); 272 } 273 274 if (validate) { ··· 306 307 for (let i = 0; i < importStack.length; i++) { 308 const pack = (await packPromises[i]) as PackRecord | null; 309 + if (!pack || !pack.exports) { 310 + continue; 311 + } 312 313 const entry = pack.exports.find((e) => e.type === nsid); 314 + if (!entry) { 315 + continue; 316 + } 317 318 const component = (await resolver.fetchRecord( 319 entry.component 320 )) as ComponentRecord | null; 321 + if (!component) { 322 + continue; 323 + } 324 325 return { 326 componentUri: entry.component, ··· 370 let cache: CachePolicy | undefined; 371 372 // Find a matching viewRecord and resolve its AT URI prop 373 + if (component.view) { 374 + const { prop, accepts } = component.view; 375 + const viewRecords = accepts.filter((v) => viewRecordSchema.isTypeOf(v)); 376 377 + for (const vr of viewRecords) { 378 + const uri = props[prop] as string | undefined; 379 + if (!uri || !uri.startsWith("at://")) { 380 + continue; 381 + } 382 + const parsed = new AtUri(uri); 383 + ensureValidNsid(parsed.collection); 384 + if (!parsed.collection || !parsed.rkey) { 385 + continue; 386 + } 387 + if (vr.collection && vr.collection !== parsed.collection) { 388 + continue; 389 + } 390 + const built = await buildRecord( 391 + parsed.host, 392 + parsed.collection, 393 + parsed.rkey, 394 + tree, 395 + resolver 396 + ); 397 + scope = { props: slottedProps, record: built.record }; 398 + cache = built.cache; 399 + break; 400 } 401 } 402 403 const node = resolveBindings(tree, scopeResolver(scope)); ··· 471 const refSlots = new Set<object>(); 472 const wireProps = serializeTree(props, (el) => { 473 if (el.type === "at.inlay.Slot") { 474 + if (refSlots.has(el)) { 475 + return el; 476 + } 477 throw new Error("Unexpected Slot in props"); 478 } 479 const id = String(refs.size); ··· 530 531 function expandBareDid( 532 props: Record<string, unknown>, 533 + view: View 534 ): Record<string, unknown> { 535 + const { prop, accepts } = view; 536 537 // Find the first viewRecord with both collection and rkey — that enables DID expansion 538 + const entry = accepts 539 .filter((v) => viewRecordSchema.isTypeOf(v)) 540 .find((v) => v.collection && v.rkey); 541 + if (!entry) { 542 + return props; 543 + } 544 const value = props[prop] as string | undefined; 545 + if (!value || !value.startsWith("did:")) { 546 + return props; 547 + } 548 549 return { 550 ...props,
+43 -42
packages/@inlay/render/src/validate.ts
··· 11 12 const lexiconCache = new Map<string, Lexicons>(); 13 14 - // --- Helpers --- 15 - 16 - function getViewPrimitives(component: ComponentRecord) { 17 - return (component.view ?? []).filter((v) => viewPrimitiveSchema.isTypeOf(v)); 18 - } 19 - 20 - function getViewRecords(component: ComponentRecord) { 21 - return (component.view ?? []).filter((v) => viewRecordSchema.isTypeOf(v)); 22 - } 23 - 24 // --- Public API --- 25 26 export async function validateProps( ··· 37 lexiconCache.set(type, lexicons); 38 } 39 lexicons.assertValidXrpcInput(type, props); 40 - } else { 41 // Synthesize validation from view entries (viewPrimitive + viewRecord) 42 - const primitives = getViewPrimitives(component); 43 - const records = getViewRecords(component); 44 45 if (primitives.length > 0 || records.length > 0) { 46 const propEntries = new Map< ··· 50 51 // viewPrimitive entries define typed props 52 for (const vp of primitives) { 53 - if (!vp.prop) continue; 54 - const existing = propEntries.get(vp.prop); 55 if (existing) { 56 if (vp.format) existing.formats.add(vp.format); 57 } else { 58 const formats = new Set<string>(); 59 if (vp.format) formats.add(vp.format); 60 - propEntries.set(vp.prop, { type: vp.type, formats }); 61 } 62 } 63 64 // viewRecord entries imply a string prop (at-uri or did format) 65 for (const vr of records) { 66 - const prop = vr.prop ?? "uri"; 67 - const existing = propEntries.get(prop); 68 if (existing) { 69 existing.formats.add("at-uri"); 70 if (vr.rkey) existing.formats.add("did"); 71 } else { 72 const formats = new Set<string>(["at-uri"]); 73 if (vr.rkey) formats.add("did"); 74 - propEntries.set(prop, { type: "string", formats }); 75 } 76 } 77 ··· 103 } 104 105 // Collection constraint checking from viewRecord entries 106 - const records = getViewRecords(component); 107 - if (records.length > 0) { 108 - const allowedCollections = new Map<string, Set<string>>(); 109 - for (const vr of records) { 110 - if (!vr.collection) continue; 111 - const prop = vr.prop ?? "uri"; 112 - let set = allowedCollections.get(prop); 113 - if (!set) { 114 - set = new Set(); 115 - allowedCollections.set(prop, set); 116 } 117 - set.add(vr.collection); 118 - } 119 - for (const [prop, allowed] of allowedCollections) { 120 - const value = props[prop]; 121 - if (typeof value !== "string" || !value.startsWith("at://")) continue; 122 - const parsed = new AtUri(value); 123 - if (!parsed.collection) continue; 124 - if (!allowed.has(parsed.collection)) { 125 - throw new Error( 126 - `${type}: ${prop} expects ${[...allowed].join(" or ")}, got ${parsed.collection}` 127 - ); 128 } 129 } 130 } ··· 140 141 function unionFormats(formats: Set<string>): string | undefined { 142 const arr = [...formats]; 143 - if (arr.length <= 1) return arr[0]; 144 const ancestorSets = arr.map( 145 (f) => new Set([f, ...(FORMAT_ANCESTORS[f] ?? [])]) 146 ); 147 const common = [...ancestorSets[0]].filter((f) => 148 ancestorSets.every((s) => s.has(f)) 149 ); 150 - if (common.length === 0) return undefined; 151 if (common.length === 1) return common[0]; 152 return common.find( 153 (f) =>
··· 11 12 const lexiconCache = new Map<string, Lexicons>(); 13 14 // --- Public API --- 15 16 export async function validateProps( ··· 27 lexiconCache.set(type, lexicons); 28 } 29 lexicons.assertValidXrpcInput(type, props); 30 + } else if (component.view) { 31 // Synthesize validation from view entries (viewPrimitive + viewRecord) 32 + const { prop: viewProp, accepts } = component.view; 33 + const primitives = accepts.filter((v) => viewPrimitiveSchema.isTypeOf(v)); 34 + const records = accepts.filter((v) => viewRecordSchema.isTypeOf(v)); 35 36 if (primitives.length > 0 || records.length > 0) { 37 const propEntries = new Map< ··· 41 42 // viewPrimitive entries define typed props 43 for (const vp of primitives) { 44 + const existing = propEntries.get(viewProp); 45 if (existing) { 46 if (vp.format) existing.formats.add(vp.format); 47 } else { 48 const formats = new Set<string>(); 49 if (vp.format) formats.add(vp.format); 50 + propEntries.set(viewProp, { type: vp.type, formats }); 51 } 52 } 53 54 // viewRecord entries imply a string prop (at-uri or did format) 55 for (const vr of records) { 56 + const existing = propEntries.get(viewProp); 57 if (existing) { 58 existing.formats.add("at-uri"); 59 if (vr.rkey) existing.formats.add("did"); 60 } else { 61 const formats = new Set<string>(["at-uri"]); 62 if (vr.rkey) formats.add("did"); 63 + propEntries.set(viewProp, { type: "string", formats }); 64 } 65 } 66 ··· 92 } 93 94 // Collection constraint checking from viewRecord entries 95 + if (component.view) { 96 + const { prop: collectionProp, accepts } = component.view; 97 + const records = accepts.filter((v) => viewRecordSchema.isTypeOf(v)); 98 + if (records.length > 0) { 99 + const allowedCollections = new Map<string, Set<string>>(); 100 + for (const vr of records) { 101 + if (!vr.collection) { 102 + continue; 103 + } 104 + let set = allowedCollections.get(collectionProp); 105 + if (!set) { 106 + set = new Set(); 107 + allowedCollections.set(collectionProp, set); 108 + } 109 + set.add(vr.collection); 110 } 111 + for (const [prop, allowed] of allowedCollections) { 112 + const value = props[prop]; 113 + if (typeof value !== "string" || !value.startsWith("at://")) { 114 + continue; 115 + } 116 + const parsed = new AtUri(value); 117 + if (!parsed.collection) { 118 + continue; 119 + } 120 + if (!allowed.has(parsed.collection)) { 121 + throw new Error( 122 + `${type}: ${prop} expects ${[...allowed].join(" or ")}, got ${parsed.collection}` 123 + ); 124 + } 125 } 126 } 127 } ··· 137 138 function unionFormats(formats: Set<string>): string | undefined { 139 const arr = [...formats]; 140 + if (arr.length <= 1) { 141 + return arr[0]; 142 + } 143 const ancestorSets = arr.map( 144 (f) => new Set([f, ...(FORMAT_ANCESTORS[f] ?? [])]) 145 ); 146 const common = [...ancestorSets[0]].filter((f) => 147 ancestorSets.every((s) => s.has(f)) 148 ); 149 + if (common.length === 0) { 150 + return undefined; 151 + } 152 if (common.length === 1) return common[0]; 153 return common.find( 154 (f) =>
+214 -151
packages/@inlay/render/test/render.test.ts
··· 758 ), 759 }, 760 imports: [HOST_PACK_URI], 761 - view: [ 762 - { 763 - $type: "at.inlay.component#viewRecord", 764 - prop: "uri", 765 - collection: "app.bsky.feed.post", 766 - }, 767 - ], 768 }; 769 770 const { options, log } = world({ ··· 816 ), 817 }, 818 imports: [HOST_PACK_URI], 819 - view: [ 820 - { 821 - $type: "at.inlay.component#viewRecord", 822 - prop: "uri", 823 - collection: "app.bsky.feed.post", 824 - }, 825 - ], 826 }; 827 828 const { options, log } = world({ ··· 869 ), 870 }, 871 imports: [HOST_PACK_URI], 872 - view: [ 873 - { 874 - $type: "at.inlay.component#viewRecord", 875 - prop: "uri", 876 - collection: "app.bsky.feed.post", 877 - }, 878 - ], 879 }; 880 881 const { options, log } = world({ ··· 1988 ), 1989 }, 1990 imports: ["at://did:plc:test/at.inlay.pack/child"] as AtUriString[], 1991 - view: [ 1992 - { 1993 - $type: "at.inlay.component#viewRecord", 1994 - prop: "uri", 1995 - collection: "app.bsky.feed.post", 1996 - }, 1997 - ], 1998 }; 1999 2000 const { options, log } = testResolver({ ··· 2211 ), 2212 }, 2213 imports: [HOST_PACK_URI], 2214 - view: [ 2215 - { 2216 - $type: "at.inlay.component#viewRecord", 2217 - prop: "uri", 2218 - collection: "app.bsky.feed.post", 2219 - }, 2220 - ], 2221 }; 2222 2223 const postUri = "at://did:plc:alice/app.bsky.feed.post/123"; ··· 2371 ), 2372 }, 2373 imports: [HOST_PACK_URI], 2374 - view: [ 2375 - { 2376 - $type: "at.inlay.component#viewRecord", 2377 - prop: "uri", 2378 - collection: "app.bsky.feed.post", 2379 - }, 2380 - ], 2381 }; 2382 2383 const postUri = "at://did:plc:alice/app.bsky.feed.post/123"; ··· 2520 ), 2521 }, 2522 imports: [HOST_PACK_URI], 2523 - view: [ 2524 - { 2525 - $type: "at.inlay.component#viewRecord", 2526 - prop: "uri", 2527 - collection: "app.bsky.actor.profile", 2528 - rkey: "self", 2529 - }, 2530 - ], 2531 }; 2532 2533 const { options } = world({ ··· 2557 ), 2558 }, 2559 imports: [HOST_PACK_URI], 2560 - view: [ 2561 - { 2562 - $type: "at.inlay.component#viewRecord", 2563 - prop: "uri", 2564 - collection: "app.bsky.actor.profile", 2565 - rkey: "main", 2566 - }, 2567 - ], 2568 }; 2569 2570 const { options } = world({ ··· 2594 ), 2595 }, 2596 imports: [HOST_PACK_URI], 2597 - view: [ 2598 - { 2599 - $type: "at.inlay.component#viewRecord", 2600 - prop: "uri", 2601 - collection: "app.bsky.actor.profile", 2602 - rkey: "self", 2603 - }, 2604 - ], 2605 }; 2606 2607 const { options } = world({ ··· 2635 ), 2636 }, 2637 imports: [HOST_PACK_URI], 2638 - view: [ 2639 - { 2640 - $type: "at.inlay.component#viewRecord", 2641 - prop: "uri", 2642 - collection: "app.bsky.feed.post", 2643 - }, 2644 - ], 2645 }; 2646 2647 const { resolver } = world(); ··· 2729 node: { $: "$", type: Text, props: {} }, 2730 }, 2731 imports: [HOST_PACK_URI], 2732 - view: [ 2733 - { 2734 - $type: "at.inlay.component#viewRecord", 2735 - prop: "uri", 2736 - collection: "app.bsky.feed.post", 2737 - }, 2738 - ], 2739 }; 2740 2741 const { options } = world(); ··· 2765 node: { $: "$", type: Text, props: {} }, 2766 }, 2767 imports: [HOST_PACK_URI], 2768 - view: [ 2769 - { 2770 - $type: "at.inlay.component#viewPrimitive", 2771 - type: "string", 2772 - format: "datetime", 2773 - prop: "value", 2774 - }, 2775 - ], 2776 }; 2777 2778 const { options } = world(); ··· 2802 node: { $: "$", type: Text, props: {} }, 2803 }, 2804 imports: [HOST_PACK_URI], 2805 - view: [ 2806 - { 2807 - $type: "at.inlay.component#viewRecord", 2808 - prop: "uri", 2809 - collection: "app.bsky.feed.post", 2810 - }, 2811 - ], 2812 }; 2813 2814 const { options } = world(); ··· 2898 ), 2899 }, 2900 imports: [HOST_PACK_URI], 2901 - view: [ 2902 - { 2903 - $type: "at.inlay.component#viewRecord", 2904 - prop: "uri", 2905 - collection: "app.bsky.feed.post", 2906 - }, 2907 - ], 2908 }; 2909 2910 const { options } = world({ ··· 2992 ), 2993 }, 2994 imports: [HOST_PACK_URI], 2995 - view: [ 2996 - { 2997 - $type: "at.inlay.component#viewRecord", 2998 - prop: "uri", 2999 - collection: "app.bsky.feed.post", 3000 - }, 3001 - ], 3002 }; 3003 3004 const { options } = world({ ··· 3062 ), 3063 }, 3064 imports: [HOST_PACK_URI], 3065 - view: [ 3066 - { 3067 - $type: "at.inlay.component#viewRecord", 3068 - prop: "uri", 3069 - collection: "app.bsky.feed.post", 3070 - }, 3071 - ], 3072 }; 3073 3074 const { options } = world({ ··· 3146 ), 3147 }, 3148 imports: [HOST_PACK_URI], 3149 - view: [ 3150 - { 3151 - $type: "at.inlay.component#viewRecord", 3152 - prop: "uri", 3153 - collection: "app.bsky.feed.post", 3154 - }, 3155 - ], 3156 }; 3157 3158 const { options } = world({ ··· 3196 HOST_PACK_URI, 3197 "at://did:plc:test/at.inlay.pack/app", 3198 ] as AtUriString[], 3199 - view: [ 3200 - { 3201 - $type: "at.inlay.component#viewRecord", 3202 - prop: "uri", 3203 - collection: "app.bsky.feed.post", 3204 - }, 3205 - ], 3206 }; 3207 3208 const { options } = world({ ··· 3267 HOST_PACK_URI, 3268 "at://did:plc:test/at.inlay.pack/app", 3269 ] as AtUriString[], 3270 - view: [ 3271 - { 3272 - $type: "at.inlay.component#viewRecord", 3273 - prop: "uri", 3274 - collection: "app.bsky.feed.post", 3275 - }, 3276 - ], 3277 }; 3278 3279 const { options } = world({ ··· 3337 HOST_PACK_URI, 3338 "at://did:plc:test/at.inlay.pack/app", 3339 ] as AtUriString[], 3340 - view: [ 3341 - { 3342 - $type: "at.inlay.component#viewRecord", 3343 - prop: "uri", 3344 - collection: "app.bsky.feed.post", 3345 - }, 3346 - ], 3347 }; 3348 3349 const { options } = world({ ··· 3432 HOST_PACK_URI, 3433 "at://did:plc:test/at.inlay.pack/safe", 3434 ] as AtUriString[], 3435 - view: [ 3436 - { 3437 - $type: "at.inlay.component#viewRecord", 3438 - prop: "uri", 3439 - collection: "app.bsky.feed.post", 3440 - }, 3441 - ], 3442 }; 3443 3444 const { options } = world({
··· 758 ), 759 }, 760 imports: [HOST_PACK_URI], 761 + view: { 762 + $type: "at.inlay.component#view", 763 + prop: "uri", 764 + accepts: [ 765 + { 766 + $type: "at.inlay.component#viewRecord", 767 + collection: "app.bsky.feed.post", 768 + }, 769 + ], 770 + }, 771 }; 772 773 const { options, log } = world({ ··· 819 ), 820 }, 821 imports: [HOST_PACK_URI], 822 + view: { 823 + $type: "at.inlay.component#view", 824 + prop: "uri", 825 + accepts: [ 826 + { 827 + $type: "at.inlay.component#viewRecord", 828 + collection: "app.bsky.feed.post", 829 + }, 830 + ], 831 + }, 832 }; 833 834 const { options, log } = world({ ··· 875 ), 876 }, 877 imports: [HOST_PACK_URI], 878 + view: { 879 + $type: "at.inlay.component#view", 880 + prop: "uri", 881 + accepts: [ 882 + { 883 + $type: "at.inlay.component#viewRecord", 884 + collection: "app.bsky.feed.post", 885 + }, 886 + ], 887 + }, 888 }; 889 890 const { options, log } = world({ ··· 1997 ), 1998 }, 1999 imports: ["at://did:plc:test/at.inlay.pack/child"] as AtUriString[], 2000 + view: { 2001 + $type: "at.inlay.component#view", 2002 + prop: "uri", 2003 + accepts: [ 2004 + { 2005 + $type: "at.inlay.component#viewRecord", 2006 + collection: "app.bsky.feed.post", 2007 + }, 2008 + ], 2009 + }, 2010 }; 2011 2012 const { options, log } = testResolver({ ··· 2223 ), 2224 }, 2225 imports: [HOST_PACK_URI], 2226 + view: { 2227 + $type: "at.inlay.component#view", 2228 + prop: "uri", 2229 + accepts: [ 2230 + { 2231 + $type: "at.inlay.component#viewRecord", 2232 + collection: "app.bsky.feed.post", 2233 + }, 2234 + ], 2235 + }, 2236 }; 2237 2238 const postUri = "at://did:plc:alice/app.bsky.feed.post/123"; ··· 2386 ), 2387 }, 2388 imports: [HOST_PACK_URI], 2389 + view: { 2390 + $type: "at.inlay.component#view", 2391 + prop: "uri", 2392 + accepts: [ 2393 + { 2394 + $type: "at.inlay.component#viewRecord", 2395 + collection: "app.bsky.feed.post", 2396 + }, 2397 + ], 2398 + }, 2399 }; 2400 2401 const postUri = "at://did:plc:alice/app.bsky.feed.post/123"; ··· 2538 ), 2539 }, 2540 imports: [HOST_PACK_URI], 2541 + view: { 2542 + $type: "at.inlay.component#view", 2543 + prop: "uri", 2544 + accepts: [ 2545 + { 2546 + $type: "at.inlay.component#viewRecord", 2547 + collection: "app.bsky.actor.profile", 2548 + rkey: "self", 2549 + }, 2550 + ], 2551 + }, 2552 }; 2553 2554 const { options } = world({ ··· 2578 ), 2579 }, 2580 imports: [HOST_PACK_URI], 2581 + view: { 2582 + $type: "at.inlay.component#view", 2583 + prop: "uri", 2584 + accepts: [ 2585 + { 2586 + $type: "at.inlay.component#viewRecord", 2587 + collection: "app.bsky.actor.profile", 2588 + rkey: "main", 2589 + }, 2590 + ], 2591 + }, 2592 }; 2593 2594 const { options } = world({ ··· 2618 ), 2619 }, 2620 imports: [HOST_PACK_URI], 2621 + view: { 2622 + $type: "at.inlay.component#view", 2623 + prop: "uri", 2624 + accepts: [ 2625 + { 2626 + $type: "at.inlay.component#viewRecord", 2627 + collection: "app.bsky.actor.profile", 2628 + rkey: "self", 2629 + }, 2630 + ], 2631 + }, 2632 }; 2633 2634 const { options } = world({ ··· 2662 ), 2663 }, 2664 imports: [HOST_PACK_URI], 2665 + view: { 2666 + $type: "at.inlay.component#view", 2667 + prop: "uri", 2668 + accepts: [ 2669 + { 2670 + $type: "at.inlay.component#viewRecord", 2671 + collection: "app.bsky.feed.post", 2672 + }, 2673 + ], 2674 + }, 2675 }; 2676 2677 const { resolver } = world(); ··· 2759 node: { $: "$", type: Text, props: {} }, 2760 }, 2761 imports: [HOST_PACK_URI], 2762 + view: { 2763 + $type: "at.inlay.component#view", 2764 + prop: "uri", 2765 + accepts: [ 2766 + { 2767 + $type: "at.inlay.component#viewRecord", 2768 + collection: "app.bsky.feed.post", 2769 + }, 2770 + ], 2771 + }, 2772 }; 2773 2774 const { options } = world(); ··· 2798 node: { $: "$", type: Text, props: {} }, 2799 }, 2800 imports: [HOST_PACK_URI], 2801 + view: { 2802 + $type: "at.inlay.component#view", 2803 + prop: "value", 2804 + accepts: [ 2805 + { 2806 + $type: "at.inlay.component#viewPrimitive", 2807 + type: "string", 2808 + format: "datetime", 2809 + }, 2810 + ], 2811 + }, 2812 }; 2813 2814 const { options } = world(); ··· 2838 node: { $: "$", type: Text, props: {} }, 2839 }, 2840 imports: [HOST_PACK_URI], 2841 + view: { 2842 + $type: "at.inlay.component#view", 2843 + prop: "uri", 2844 + accepts: [ 2845 + { 2846 + $type: "at.inlay.component#viewRecord", 2847 + collection: "app.bsky.feed.post", 2848 + }, 2849 + ], 2850 + }, 2851 }; 2852 2853 const { options } = world(); ··· 2937 ), 2938 }, 2939 imports: [HOST_PACK_URI], 2940 + view: { 2941 + $type: "at.inlay.component#view", 2942 + prop: "uri", 2943 + accepts: [ 2944 + { 2945 + $type: "at.inlay.component#viewRecord", 2946 + collection: "app.bsky.feed.post", 2947 + }, 2948 + ], 2949 + }, 2950 }; 2951 2952 const { options } = world({ ··· 3034 ), 3035 }, 3036 imports: [HOST_PACK_URI], 3037 + view: { 3038 + $type: "at.inlay.component#view", 3039 + prop: "uri", 3040 + accepts: [ 3041 + { 3042 + $type: "at.inlay.component#viewRecord", 3043 + collection: "app.bsky.feed.post", 3044 + }, 3045 + ], 3046 + }, 3047 }; 3048 3049 const { options } = world({ ··· 3107 ), 3108 }, 3109 imports: [HOST_PACK_URI], 3110 + view: { 3111 + $type: "at.inlay.component#view", 3112 + prop: "uri", 3113 + accepts: [ 3114 + { 3115 + $type: "at.inlay.component#viewRecord", 3116 + collection: "app.bsky.feed.post", 3117 + }, 3118 + ], 3119 + }, 3120 }; 3121 3122 const { options } = world({ ··· 3194 ), 3195 }, 3196 imports: [HOST_PACK_URI], 3197 + view: { 3198 + $type: "at.inlay.component#view", 3199 + prop: "uri", 3200 + accepts: [ 3201 + { 3202 + $type: "at.inlay.component#viewRecord", 3203 + collection: "app.bsky.feed.post", 3204 + }, 3205 + ], 3206 + }, 3207 }; 3208 3209 const { options } = world({ ··· 3247 HOST_PACK_URI, 3248 "at://did:plc:test/at.inlay.pack/app", 3249 ] as AtUriString[], 3250 + view: { 3251 + $type: "at.inlay.component#view", 3252 + prop: "uri", 3253 + accepts: [ 3254 + { 3255 + $type: "at.inlay.component#viewRecord", 3256 + collection: "app.bsky.feed.post", 3257 + }, 3258 + ], 3259 + }, 3260 }; 3261 3262 const { options } = world({ ··· 3321 HOST_PACK_URI, 3322 "at://did:plc:test/at.inlay.pack/app", 3323 ] as AtUriString[], 3324 + view: { 3325 + $type: "at.inlay.component#view", 3326 + prop: "uri", 3327 + accepts: [ 3328 + { 3329 + $type: "at.inlay.component#viewRecord", 3330 + collection: "app.bsky.feed.post", 3331 + }, 3332 + ], 3333 + }, 3334 }; 3335 3336 const { options } = world({ ··· 3394 HOST_PACK_URI, 3395 "at://did:plc:test/at.inlay.pack/app", 3396 ] as AtUriString[], 3397 + view: { 3398 + $type: "at.inlay.component#view", 3399 + prop: "uri", 3400 + accepts: [ 3401 + { 3402 + $type: "at.inlay.component#viewRecord", 3403 + collection: "app.bsky.feed.post", 3404 + }, 3405 + ], 3406 + }, 3407 }; 3408 3409 const { options } = world({ ··· 3492 HOST_PACK_URI, 3493 "at://did:plc:test/at.inlay.pack/safe", 3494 ] as AtUriString[], 3495 + view: { 3496 + $type: "at.inlay.component#view", 3497 + prop: "uri", 3498 + accepts: [ 3499 + { 3500 + $type: "at.inlay.component#viewRecord", 3501 + collection: "app.bsky.feed.post", 3502 + }, 3503 + ], 3504 + }, 3505 }; 3506 3507 const { options } = world({