A personal website powered by Astro and ATProto
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

at dev 62 lines 1.6 kB view raw
1import type { GeneratedLexiconUnion, GeneratedLexiconTypeMap } from '../generated/lexicon-types'; 2 3// Type-safe component registry 4export interface ComponentRegistryEntry<T = any> { 5 component: string; 6 props?: T; 7} 8 9export type ComponentRegistry = { 10 [K in keyof GeneratedLexiconTypeMap]?: ComponentRegistryEntry; 11} & { 12 [key: string]: ComponentRegistryEntry; // Fallback for unknown types 13}; 14 15// Default registry - add your components here 16export const registry: ComponentRegistry = { 17 'ComWhtwndBlogEntry': { 18 component: 'WhitewindBlogPost', 19 props: {} 20 }, 21 'AStatusUpdate': { 22 component: 'StatusUpdate', 23 props: {} 24 }, 25 // Bluesky posts (not in generated types, but used by components) 26 'app.bsky.feed.post': { 27 component: 'BlueskyPost', 28 props: {} 29 }, 30 31}; 32 33// Type-safe component lookup 34export function getComponentInfo<T extends keyof GeneratedLexiconTypeMap>( 35 $type: T 36): ComponentRegistryEntry | null { 37 return registry[$type] || null; 38} 39 40// Helper to register a new component 41export function registerComponent<T extends keyof GeneratedLexiconTypeMap>( 42 $type: T, 43 component: string, 44 props?: any 45): void { 46 registry[$type] = { component, props }; 47} 48 49// Auto-assignment for unknown types (fallback) 50export function autoAssignComponent($type: string): ComponentRegistryEntry { 51 // Convert NSID to component name 52 const parts = $type.split('.'); 53 const componentName = parts[parts.length - 1] 54 .split('-') 55 .map(part => part.charAt(0).toUpperCase() + part.slice(1)) 56 .join(''); 57 58 return { 59 component: componentName, 60 props: {} 61 }; 62}