social components inlay.at
atproto components sdui
86
fork

Configure Feed

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

at main 38 lines 2.5 kB view raw view rendered
1# proto 2 3A prototype Inlay host built with [Hono](https://hono.dev/) and [htmx](https://htmx.org/). It resolves Inlay component trees into HTML and streams the result to the browser. 4 5**Live demo:** https://inlay-proto.up.railway.app/ 6 7## Running 8 9```bash 10npm install # from the repo root 11npm run dev # starts on http://localhost:3001 12``` 13 14Expects a Redis instance for caching. Set `REDIS_URL` in `.env` or `.env.local` at the repo root (defaults to `redis://localhost:6379`). Records and DID resolution go through [Slingshot](https://slingshot.microcosm.blue). 15 16## How it works 17 18The main route is `/at/:did/:collection/:rkey?componentUri=...`. It fetches the component record, creates an element (`$(componentType, { uri })`), and calls [`@inlay/render`](../packages/@inlay/render) in a loop until everything bottoms out in primitives. Each primitive maps to a custom HTML element (`org-atsui-stack`, `org-atsui-text`, etc.) styled by two CSS files. 19 20The response is streamed with Hono's `renderToReadableStream`. Slow XRPC calls don't block the whole page — `at.inlay.Loading` components use `<Suspense>` to show a fallback while the rest of the page streams. 21 22## Primitives 23 24This host implements the [Atsui](https://pdsls.dev/at://did:plc:e4fjueijznwqm2yxvt7q4mba/com.atproto.lexicon.schema) primitives. Each primitive is a function in `src/primitives.tsx` that takes `{ ctx, props }` and returns Hono JSX. A `componentMap` at the bottom registers them by NSID. 25 26## Caching 27 28Records and XRPC responses are cached in Redis. Cache keys are tagged using the same scheme as `@inlay/cache``tagRecord` for AT URIs, `tagLink` for backlink patterns. The existing [invalidator](../invalidator/) (a Jetstream firehose listener) can flush entries when records change. 29 30TTLs follow the `life` values from component responses: `seconds` (30s), `minutes` (5m), `hours` (1h), `max` (24h). 31 32## Infinite scroll 33 34`org.atsui.List` renders the first page server-side, then uses htmx to load more pages as the user scrolls. The `/htmx/list` endpoint handles pagination — it takes a cursor, fetches the next page from the component's XRPC query, renders the items, and returns an HTML fragment with a new sentinel `div` for the next page. 35 36## Link prefetching 37 38An `IntersectionObserver` watches for `<a>` tags pointing to `/at/...` routes. When one scrolls into view, it injects a `<link rel="prefetch">` so the browser fetches the page before the user clicks.