A lexicon-driven AppView for ATProto. happyview.dev
backfill firehose jetstream atproto appview oauth lexicon
8
fork

Configure Feed

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

docs: clarity improvements

Trezy 0941aa37 066b0f7b

+85 -50
+2
.gitignore
··· 7 7 dist/ 8 8 build/ 9 9 .docusaurus/ 10 + .vercel 11 + .env*.local
+4
.vercelignore
··· 1 + node_modules 2 + target 3 + .next 4 + *.wasm
+2
packages/docs/.gitignore
··· 1 + .vercel 2 + .env*.local
+9 -5
packages/docs/docs/README.md
··· 6 6 7 7 ## Features 8 8 9 - - **Schema-driven endpoints.** Upload a [lexicon](guides/lexicons.md) and HappyView generates XRPC query and procedure routes, storage, and indexing from it — updatable at runtime with no restart. 10 - - **Network sync built in.** Real-time record streaming via [Jetstream](https://github.com/bluesky-social/jetstream), historical [backfill](guides/backfill.md) from each user's PDS, and AT Protocol OAuth with DPoP-bound proxy writes back to the PDS. 11 - - **Customize with Lua, hooks, and plugins.** [Lua scripts](guides/scripting.md) for query and procedure logic, [index hooks](guides/index-hooks.md) that fire on every record change, WASM [plugins](guides/plugins.md) for external platform integration, and [labeler](guides/labelers.md) subscriptions for content moderation. 12 - - **Protocol-native.** Works with any PDS, resolves DIDs through the directory, and fetches [network lexicons](guides/lexicons.md#network-lexicons) via DNS authority resolution. 13 - - **Full admin surface.** Built-in [dashboard](getting-started/dashboard.md) and [admin API](reference/admin-api.md) for managing lexicons, users, API keys, API clients, backfill jobs, and plugins. 9 + - **Schema-driven endpoints:** Upload a [lexicon](guides/lexicons.md) and HappyView generates XRPC query and procedure routes, storage, and indexing from it — updatable at runtime with no restart. 10 + 11 + - **Network sync built in:** Real-time record streaming via [Jetstream](https://github.com/bluesky-social/jetstream), historical [backfill](guides/backfill.md) from each user's PDS, and AT Protocol OAuth with DPoP-bound proxy writes back to the PDS. 12 + 13 + - **Customize with Lua, hooks, and plugins:** [Lua scripts](guides/scripting.md) for query and procedure logic, [index hooks](guides/index-hooks.md) that fire on every record change, WASM [plugins](guides/plugins.md) for external platform integration, and [labeler](guides/labelers.md) subscriptions for content moderation. 14 + 15 + - **Protocol-native:** Works with any PDS, resolves DIDs through the directory, and fetches [network lexicons](guides/lexicons.md#network-lexicons) via DNS authority resolution. 16 + 17 + - **Full admin surface:** Built-in [dashboard](getting-started/dashboard.md) and [admin API](reference/admin-api.md) for managing lexicons, users, API keys, API clients, backfill jobs, and plugins. 14 18 15 19 ## Design Principles 16 20
+2 -2
packages/docs/docs/getting-started/dashboard.md
··· 19 19 20 20 The Lua panel only appears when the lexicon's `defs.main.type` is `query` or `procedure`. For record-type lexicons, only the JSON panel is shown. 21 21 22 - A default Lua script is auto-generated when you first set the type to query or procedure. The template updates automatically when the type changes, but once you manually edit the script your changes are preserved. 22 + HappyView generates a default Lua script when you first set the type to query or procedure. The template updates when the type changes, but once you edit the script your changes are preserved. 23 23 24 24 Toggle **Enable backfill** to index historical records when uploading a record-type lexicon. 25 25 ··· 35 35 36 36 ### Lua editor 37 37 38 - The Lua editor provides context-aware code completions, including suggestions for the `Record`, `db`, `input`, and `params` APIs as well as Lua keywords, builtins, and standard library functions. It also offers snippet templates for common constructs like `if`, `for`, and `function`. 38 + The Lua editor provides context-aware code completions, including suggestions for the `Record`, `db`, `input`, and `params` APIs as well as Lua keywords, builtins, and standard library functions. It also has snippets for `if`, `for`, `function`, etc. 39 39 40 40 See [Lua Scripting](../guides/scripting.md) for the full runtime reference and examples. 41 41
+4 -4
packages/docs/docs/getting-started/quickstart.md
··· 24 24 25 25 1. In the dashboard, go to **Lexicons > Add Lexicon > Network** 26 26 2. Enter an NSID (e.g. `xyz.statusphere.status`) 27 - 3. HappyView resolves the schema from the AT Protocol network and shows a preview 27 + 3. HappyView [resolves the schema](https://atproto.com/specs/lexicon#lexicon-publication-and-resolution) from its authority domain records and shows a preview 28 28 4. Click **Add** 29 29 30 - HappyView immediately starts indexing records for that collection. A backfill job is created to fetch historical records, and new records stream in via Jetstream in real time. 30 + HappyView starts indexing records for that collection. A backfill job fetches historical records, and new records stream in via Jetstream. 31 31 32 32 You can also upload lexicons manually via the dashboard or the [admin API](../reference/admin-api.md). See [Lexicons](../guides/lexicons.md) for the full details. 33 33 ··· 37 37 38 38 ## 5. Query your data 39 39 40 - Once you have a record lexicon indexed, add a query lexicon to expose a read endpoint. Go to **Lexicons > Add Lexicon > Local** and create a query lexicon with `target_collection` set to your record collection's NSID. 40 + Once you have a record lexicon indexed, add a query lexicon to expose a read endpoint. Go to **Lexicons > Add Lexicon > Local** and create a query lexicon with `target_collection` set to your record collection's NSID. (`target_collection` is a HappyView-specific field that tells a query or procedure which record collection it operates on.) 41 41 42 42 Without a Lua script, HappyView generates a default query endpoint that supports `limit`, `cursor`, `did`, and `uri` parameters: 43 43 ··· 49 49 50 50 ## Next steps 51 51 52 - You now have a working AppView. Here's where to go from here: 52 + Here's where to go from here: 53 53 54 54 - [**Statusphere tutorial**](../tutorials/statusphere.md): end-to-end walkthrough building a complete AppView with record, query, and procedure lexicons 55 55 - [**Lexicons guide**](../guides/lexicons.md): target collections, backfill flag, network lexicons
+2 -2
packages/docs/docs/guides/developing-plugins.md
··· 2 2 3 3 This guide covers how to build your own HappyView WASM plugins. For installing and configuring plugins, see the [Plugins guide](plugins.md). 4 4 5 - See the [happyview-plugins](https://github.com/gamesgamesgamesgames/happyview-plugins) repository for examples and the plugin SDK. 5 + See the [happyview-plugins](https://github.com/gamesgamesgamesgamesgames/happyview-plugins) repository for examples and the plugin SDK. 6 6 7 7 ## Plugin Manifest 8 8 ··· 99 99 100 100 ## Next steps 101 101 102 - - [Official plugins repository](https://github.com/gamesgamesgamesgames/happyview-plugins) — ready-to-use plugins and the plugin SDK 102 + - [Official plugins repository](https://github.com/gamesgamesgamesgamesgames/happyview-plugins) — ready-to-use plugins and the plugin SDK 103 103 - [Plugins guide](plugins.md) — install and configure plugins 104 104 - [API Keys](api-keys.md) — authenticate programmatic access to admin endpoints 105 105 - [Permissions](permissions.md) — configure user access to plugin management
+3 -2
packages/docs/docs/guides/index-hooks.md
··· 1 1 # Index Hooks 2 2 3 - Index hooks are Lua scripts that run automatically whenever a record in a collection is created, updated, or deleted on the network. They run **before** the record is indexed, giving you the ability to filter out unwanted records, transform record data before storage, or trigger side effects like syncing with external services. 3 + Index hooks are Lua scripts that run whenever a record in a collection is created, updated, or deleted. They run **before** the record is indexed, giving you the ability to filter out unwanted records, transform record data before storage, or trigger side effects like syncing with external services. 4 4 5 - Unlike [query and procedure scripts](scripting.md) that run in response to XRPC requests, index hooks are triggered by incoming Jetstream events. 5 + Index hooks fire on **all** record events for the collection — including records created by HappyView procedure endpoints, not just events from the network. Unlike [query and procedure scripts](scripting.md) that run in response to XRPC requests, index hooks are triggered by incoming Jetstream events (which include events caused by HappyView's own PDS writes). 6 6 7 7 ## Attaching a hook 8 8 ··· 19 19 else 20 20 log(action .. " " .. uri) 21 21 end 22 + return true 22 23 end 23 24 ``` 24 25
+2 -2
packages/docs/docs/guides/labelers.md
··· 1 1 # Labelers 2 2 3 - Labelers are external services in the AT Protocol network that apply content labels to records. HappyView can subscribe to labelers and store the labels they emit, making them available on records in the admin dashboard and via Lua scripts. 3 + Labelers are external services that apply content labels to records. They operate out-of-band — labeler data does not appear in repos or flow through relays. HappyView can subscribe to labelers and store the labels they emit, making them available on records in the admin dashboard and via Lua scripts. 4 4 5 5 ## How labelers work 6 6 7 - A labeler is identified by its DID and runs as a service on the AT Protocol network. When you subscribe to a labeler, HappyView connects directly to the labeler's WebSocket and streams label events in real time. Each label targets a specific record URI and carries a value like `nudity`, `spam`, or any custom string the labeler defines. 7 + A labeler is identified by its DID. When you subscribe to a labeler, HappyView connects directly to the labeler's WebSocket and streams label events in real time. Each label targets a specific record URI and carries a value like `nudity`, `spam`, or any custom string the labeler defines. 8 8 9 9 Labels are stored in a `labels` table in the database. HappyView tracks a cursor per labeler subscription so it can resume from where it left off after a restart. 10 10
+2 -2
packages/docs/docs/guides/plugins.md
··· 2 2 3 3 HappyView uses WASM plugins to extend its functionality. Plugins can integrate with external platforms, sync data to users' AT Protocol identities, and more. Auth plugins — the first supported plugin type — enable users to link accounts from platforms like Steam, Xbox, itch.io, and others, then sync data like game libraries. 4 4 5 - Official plugins for Steam, Xbox, itch.io, and other platforms are available in the [happyview-plugins](https://github.com/gamesgamesgamesgames/happyview-plugins) repository. 5 + Official plugins for Steam, Xbox, itch.io, and other platforms are available in the [happyview-plugins](https://github.com/gamesgamesgamesgamesgames/happyview-plugins) repository. 6 6 7 7 ## Installing Plugins 8 8 ··· 74 74 ## Next steps 75 75 76 76 - [Developing Plugins](developing-plugins.md) — create your own plugins with the WASM plugin API 77 - - [Official plugins repository](https://github.com/gamesgamesgamesgames/happyview-plugins) — ready-to-use plugins for Steam, Xbox, itch.io, and more 77 + - [Official plugins repository](https://github.com/gamesgamesgamesgamesgames/happyview-plugins) — ready-to-use plugins for Steam, Xbox, itch.io, and more 78 78 - [API Keys](api-keys.md) — authenticate programmatic access to admin endpoints 79 79 - [Permissions](permissions.md) — configure user access to plugin management
+5 -3
packages/docs/docs/reference/admin/api-clients.md
··· 1 1 # Admin API: API Clients 2 2 3 - API clients represent third-party applications that call HappyView's XRPC endpoints. **Every XRPC request** — including unauthenticated queries — must identify itself with a registered client via the `X-Client-Key` header (or `client_key` query param). The client key is HappyView's rate-limit bucket and caller identity; a request without one gets `401 Unauthorized`. 3 + API clients identify third-party applications that call HappyView's XRPC endpoints. Every request — authenticated or not — needs an `X-Client-Key` header (or `client_key` query param). Requests without one get `401 Unauthorized`. The client key is HappyView's rate-limit bucket. 4 4 5 - Each client has an `hvc_`-prefixed client key and an `hvs_`-prefixed client secret. The secret is only returned once (at creation) and is sha256-hashed in the database. Server-to-server callers pass the secret as `X-Client-Secret`; browser callers rely on the `Origin` header matching the client's registered `client_uri`. Both checks currently log warnings on mismatch rather than rejecting the request, but the rate-limit bucket is applied either way. See [Authentication — XRPC](../../getting-started/authentication.md#xrpc-api-client-identification) for the client-side view, and the [API Keys guide](../../guides/api-keys.md) for how admin API keys differ from API clients. 5 + A single API client represents your application, not individual users. Create one client for your app and use the same client key across all instances. Users authenticate separately via OAuth — the client key identifies _your app_, not _who is using it_. 6 + 7 + Each client has an `hvc_`-prefixed client key and an `hvs_`-prefixed client secret. The secret is only returned at creation and is sha256-hashed in the database. Server-to-server callers pass the secret as `X-Client-Secret`. Browser callers use the `Origin` header, which is matched against the client's `client_uri`. Mismatches currently log warnings rather than rejecting the request, but rate limiting applies either way. See [Authentication — XRPC](../../getting-started/authentication.md#xrpc-api-client-identification) for the client-side view, and the [API Keys guide](../../guides/api-keys.md) for how admin API keys differ from API clients. 6 8 7 9 ```sh 8 10 # All examples assume $TOKEN is an API key (hv_...) ··· 49 51 POST /admin/api-clients 50 52 ``` 51 53 52 - Requires `api-clients:create`. Generates a fresh `client_key` and `client_secret`. **The secret is only returned in this response** — store it immediately. 54 + Requires `api-clients:create`. Generates a `client_key` and `client_secret`. Store the secret — it won't be shown again. 53 55 54 56 ```sh 55 57 curl -X POST http://localhost:3000/admin/api-clients \
+4 -4
packages/docs/docs/reference/admin/domains.md
··· 1 1 # Admin API: Domains 2 2 3 - Manage the domains a HappyView instance serves. Each domain gets its own AT Protocol OAuth client identity. The primary domain is auto-seeded from `PUBLIC_URL` on first boot. All endpoints require the `settings:manage` permission. 3 + Manage the domains a HappyView instance serves. Each domain gets its own AT Protocol OAuth client identity. The primary domain is set from `PUBLIC_URL` on first boot. All endpoints require the `settings:manage` permission. 4 4 5 5 ```sh 6 6 # All examples assume $TOKEN is an API key (hv_...) ··· 62 62 } 63 63 ``` 64 64 65 - Side effects: builds an OAuth client for the domain, updates the in-memory domain cache. 65 + Also builds an OAuth client for the domain and updates the in-memory cache. 66 66 67 67 ## Remove a domain 68 68 ··· 79 79 80 80 **Response**: `204 No Content` 81 81 82 - Side effects: removes the domain's OAuth client and cache entry. 82 + Also removes the domain's OAuth client and cache entry. 83 83 84 84 ## Set primary domain 85 85 ··· 96 96 97 97 **Response**: `204 No Content` 98 98 99 - Side effects: updates the in-memory cache and the OAuth client registry's primary client reference. 99 + Also updates the in-memory cache and primary client reference.
+1 -1
packages/docs/docs/reference/admin/events.md
··· 1 1 # Admin API: Event Logs 2 2 3 - HappyView records an audit trail of system events: lexicon changes, record operations, Lua script executions and errors, user actions, backfill jobs, and Jetstream connectivity. See the [Event Logs guide](../../guides/event-logs.md) for details on event types and retention. 3 + HappyView logs system events — lexicon changes, record operations, script errors, user actions, and more. See the [Event Logs guide](../../guides/event-logs.md) for details on event types and retention. 4 4 5 5 ```sh 6 6 # All examples assume $TOKEN is an API key (hv_...)
+1 -1
packages/docs/docs/reference/admin/plugins.md
··· 145 145 DELETE /admin/plugins/{id} 146 146 ``` 147 147 148 - Requires `plugins:delete`. Unregisters the plugin from the runtime and deletes its row from the `plugins` table. Plugin secrets in `plugin_configs` are not removed automatically — they're available again if you reinstall the same plugin. 148 + Requires `plugins:delete`. Unregisters the plugin from the runtime and deletes its row from the `plugins` table. Secrets stay in `plugin_configs`, so they're reused if you reinstall. 149 149 150 150 **Response**: `204 No Content`. Returns `404 Not Found` if no plugin with that id is loaded. 151 151
+1 -1
packages/docs/docs/reference/admin/settings.md
··· 1 1 # Admin API: Instance Settings 2 2 3 - Instance settings are key/value entries used to override environment-variable defaults at runtime (for example, the application name, terms-of-service URL, privacy policy URL, and uploaded logo). Settings stored here take precedence over the corresponding environment variables. All endpoints require the `settings:manage` permission. 3 + Instance settings override environment variables at runtime — things like app name, ToS URL, privacy policy URL, and logo. Settings stored here take precedence over their env var equivalents. All endpoints require the `settings:manage` permission. 4 4 5 5 ```sh 6 6 # All examples assume $TOKEN is an API key (hv_...)
+1 -1
packages/docs/docs/reference/architecture.md
··· 29 29 Backfill --> DB 30 30 ``` 31 31 32 - Reads flow top-down through the query handler to the database (SQLite by default, or Postgres). Writes flow through the procedure handler to the user's PDS, then HappyView indexes the record locally. Real-time record events stream in via [Jetstream](https://github.com/bluesky-social/jetstream); historical records are backfilled in-process by discovering repos via the relay's `listReposByCollection` and fetching records directly from each PDS. 32 + Queries go through the query handler to the database (SQLite by default, or Postgres). Writes go through the procedure handler to the user's PDS, then HappyView indexes the record locally. Real-time record events stream in via [Jetstream](https://github.com/bluesky-social/jetstream); historical records are backfilled in-process by discovering repos via the relay's `listReposByCollection` and fetching records directly from each PDS. 33 33 34 34 ## Request flow 35 35
+3 -3
packages/docs/docs/reference/glossary.md
··· 10 10 11 11 **Firehose** — A real-time stream of all record events (creates, updates, deletes) across the AT Protocol network. HappyView consumes a filtered slice of this via [Jetstream](https://github.com/bluesky-social/jetstream). 12 12 13 - **Handle** — A human-readable name for an account (e.g. `user.bsky.social`). Handles resolve to a DID via DNS or the PLC directory. 13 + **Handle** — A human-readable name for an account (e.g. `user.bsky.social`). Handles resolve to a DID via a DNS TXT record or an HTTP `.well-known/atproto-did` lookup. 14 14 15 15 **Lexicon** — A schema definition for AT Protocol data types and API methods. Lexicons define what records look like, what endpoints exist, and what parameters they accept. See [Lexicons](../guides/lexicons.md). 16 16 ··· 30 30 31 31 **XRPC** — The HTTP-based RPC protocol used by the AT Protocol. Query methods map to GET requests, procedure methods map to POST requests. See [XRPC API](xrpc-api.md). 32 32 33 + **Jetstream** — A [filtered firehose](https://github.com/bluesky-social/jetstream) that delivers atproto record commit events as JSON over WebSocket. Not part of the core AT Protocol spec, but widely used. HappyView subscribes to Jetstream with a collection filter built from its indexed record lexicons, and persists a cursor for resume on reconnect. 34 + 33 35 ## HappyView-specific terms 34 36 35 37 **Backfill** — The process of bulk-indexing existing records from the network. HappyView discovers repos via the relay and fetches each repo's records directly from its PDS. Runs when a new record-type lexicon is uploaded or triggered manually. See [Backfill](../guides/backfill.md). 36 - 37 - **Jetstream** — A [filtered firehose](https://github.com/bluesky-social/jetstream) maintained by Bluesky that delivers AT Protocol record commit events as JSON over WebSocket. HappyView subscribes to Jetstream with a collection filter built from its indexed record lexicons, and persists a cursor for resume on reconnect. 38 38 39 39 **Network lexicon** — A lexicon fetched directly from the AT Protocol network via DNS authority resolution, rather than uploaded manually. See [Lexicons - Network lexicons](../guides/lexicons.md#network-lexicons). 40 40
+13 -9
packages/docs/docs/reference/lua/database-api.md
··· 93 93 94 94 Parameters are passed as an array and bound to `$1`, `$2`, etc. Supported parameter types: strings, integers, numbers, booleans, and nil. 95 95 96 + ### SQL dialect 97 + 98 + Write SQL in **SQLite syntax** — HappyView translates it to Postgres at runtime if you're using Postgres. See [Database Setup](../../guides/database-setup.md) for details on what gets translated. If you need database-specific SQL that can't be translated, check `db.is_postgres()` at runtime. 99 + 96 100 ### Column type mapping 97 101 98 - | Postgres type | Lua type | 99 - | ---------------------- | -------- | 100 - | `TEXT`, `VARCHAR` | string | 101 - | `INT4`, `INT8` | integer | 102 - | `FLOAT4`, `FLOAT8` | number | 103 - | `BOOL` | boolean | 104 - | `JSON`, `JSONB` | table | 105 - | `TIMESTAMPTZ` | string (ISO 8601) | 106 - | Other | string (fallback) | 102 + | SQLite type | Postgres type | Lua type | 103 + | ---------------------- | ---------------------- | -------- | 104 + | `TEXT` | `TEXT`, `VARCHAR` | string | 105 + | `INTEGER` | `INT4`, `INT8` | integer | 106 + | `REAL` | `FLOAT4`, `FLOAT8` | number | 107 + | `INTEGER` (0/1) | `BOOL` | boolean | 108 + | `TEXT` (JSON) | `JSON`, `JSONB` | table | 109 + | `TEXT` (ISO 8601) | `TIMESTAMPTZ` | string (ISO 8601) | 110 + | Other | Other | string (fallback) |
+1 -1
packages/docs/docs/reference/production-deployment.md
··· 73 73 - **SQLite**: back up the database file (e.g. `data/happyview.db`) plus its `-wal` and `-shm` sidecar files. Use `sqlite3 happyview.db ".backup '/path/backup.db'"` for a consistent snapshot while HappyView is running. 74 74 - **Postgres**: standard `pg_dump` / managed-Postgres snapshots. 75 75 76 - Most of what HappyView stores is derivable from the network — lost records can be re-indexed via [backfill](../guides/backfill.md). What you cannot recover from the network: user accounts and permissions, API keys, API clients, plugin secrets, and the Jetstream cursor. Prioritize those in your backup plan. 76 + Most of what HappyView stores is derivable from the network — lost records can be re-indexed via [backfill](../guides/backfill.md). You can't recover from the network: user accounts and permissions, API keys, API clients, plugin secrets, and the Jetstream cursor. Prioritize those in your backup plan. 77 77 78 78 ## Next steps 79 79
+1
packages/docs/docs/reference/scripts/batch-save.md
··· 31 31 32 32 ```sh 33 33 curl -X POST http://localhost:3000/xrpc/xyz.statusphere.batchCreate \ 34 + -H "X-Client-Key: $CLIENT_KEY" \ 34 35 -H "Authorization: Bearer $TOKEN" \ 35 36 -H "Content-Type: application/json" \ 36 37 -d '{
+1
packages/docs/docs/reference/scripts/cascading-delete.md
··· 56 56 57 57 ```sh 58 58 curl -X POST http://localhost:3000/xrpc/xyz.statusphere.deletePost \ 59 + -H "X-Client-Key: $CLIENT_KEY" \ 59 60 -H "Authorization: Bearer $TOKEN" \ 60 61 -H "Content-Type: application/json" \ 61 62 -d '{ "uri": "at://did:plc:abc/xyz.statusphere.post/abc123" }'
+1
packages/docs/docs/reference/scripts/complex-mutations.md
··· 68 68 69 69 ```sh 70 70 curl -X POST http://localhost:3000/xrpc/xyz.statusphere.updatePost \ 71 + -H "X-Client-Key: $CLIENT_KEY" \ 71 72 -H "Authorization: Bearer $TOKEN" \ 72 73 -H "Content-Type: application/json" \ 73 74 -d '{
+1
packages/docs/docs/reference/scripts/create-record.md
··· 22 22 23 23 ```sh 24 24 curl -X POST http://localhost:3000/xrpc/xyz.statusphere.createRecord \ 25 + -H "X-Client-Key: $CLIENT_KEY" \ 25 26 -H "Authorization: Bearer $TOKEN" \ 26 27 -H "Content-Type: application/json" \ 27 28 -d '{ "text": "Hello world", "createdAt": "2025-01-01T00:00:00Z" }'
+2 -2
packages/docs/docs/reference/scripts/expanded-query.md
··· 78 78 79 79 ## Use case 80 80 81 - This pattern avoids N+1 queries (fetching each author's profile individually) on the client side. Instead of fetching statuses and then making a separate request for each user's profile, the client gets everything in one call. The deduplication step ensures each profile is loaded only once even if multiple statuses are from the same user. 81 + This avoids N+1 queries on the client side — the client gets statuses and profiles in one call. The deduplication step loads each profile only once even if multiple statuses share an author. 82 82 83 - Note that `Record.load_all` reads from HappyView's local index. Profiles only appear if `app.bsky.actor.profile` is also being indexed. If a profile hasn't been indexed yet, it's silently omitted from the response. 83 + `Record.load_all` reads from HappyView's local index. Profiles only appear if `app.bsky.actor.profile` is also indexed. Missing profiles are skipped.
+1 -1
packages/docs/docs/reference/scripts/list-or-fetch.md
··· 38 38 39 39 ## Use case 40 40 41 - This is a good default query script when you want a single endpoint that serves double duty: list browsing for feeds/timelines and direct record fetching for detail views. 41 + Useful when one endpoint needs to handle both listing and single-record fetches.
+1
packages/docs/docs/reference/scripts/sidecar-records.md
··· 41 41 42 42 ```sh 43 43 curl -X POST http://localhost:3000/xrpc/xyz.statusphere.createPost \ 44 + -H "X-Client-Key: $CLIENT_KEY" \ 44 45 -H "Authorization: Bearer $TOKEN" \ 45 46 -H "Content-Type: application/json" \ 46 47 -d '{ "text": "Hello world", "lang": "en", "source": "web" }'
+3
packages/docs/docs/reference/scripts/update-or-delete.md
··· 39 39 ```sh 40 40 # Create 41 41 curl -X POST http://localhost:3000/xrpc/xyz.statusphere.setRecord \ 42 + -H "X-Client-Key: $CLIENT_KEY" \ 42 43 -H "Authorization: Bearer $TOKEN" \ 43 44 -H "Content-Type: application/json" \ 44 45 -d '{ "status": "hello" }' 45 46 46 47 # Update 47 48 curl -X POST http://localhost:3000/xrpc/xyz.statusphere.setRecord \ 49 + -H "X-Client-Key: $CLIENT_KEY" \ 48 50 -H "Authorization: Bearer $TOKEN" \ 49 51 -H "Content-Type: application/json" \ 50 52 -d '{ "uri": "at://did:plc:abc/xyz.statusphere.record/abc123", "status": "updated" }' 51 53 52 54 # Delete 53 55 curl -X POST http://localhost:3000/xrpc/xyz.statusphere.setRecord \ 56 + -H "X-Client-Key: $CLIENT_KEY" \ 54 57 -H "Authorization: Bearer $TOKEN" \ 55 58 -H "Content-Type: application/json" \ 56 59 -d '{ "uri": "at://did:plc:abc/xyz.statusphere.record/abc123", "delete": true }'
+2
packages/docs/docs/reference/scripts/upsert-record.md
··· 42 42 ```sh 43 43 # Create: no rkey, so a new TID is generated 44 44 curl -X POST http://localhost:3000/xrpc/xyz.statusphere.setStatus \ 45 + -H "X-Client-Key: $CLIENT_KEY" \ 45 46 -H "Authorization: Bearer $TOKEN" \ 46 47 -H "Content-Type: application/json" \ 47 48 -d '{ "status": "hello" }' ··· 49 50 50 51 # Update: pass the rkey back to update the same record 51 52 curl -X POST http://localhost:3000/xrpc/xyz.statusphere.setStatus \ 53 + -H "X-Client-Key: $CLIENT_KEY" \ 52 54 -H "Authorization: Bearer $TOKEN" \ 53 55 -H "Content-Type: application/json" \ 54 56 -d '{ "rkey": "3abc123", "status": "updated" }'
+8 -2
packages/docs/docs/reference/xrpc-api.md
··· 37 37 38 38 ```sh 39 39 curl http://localhost:3000/xrpc/app.bsky.actor.getProfile \ 40 + -H "X-Client-Key: $CLIENT_KEY" \ 40 41 -H "Authorization: Bearer $TOKEN" 41 42 ``` 42 43 ··· 62 63 63 64 ```sh 64 65 curl -X POST http://localhost:3000/xrpc/com.atproto.repo.uploadBlob \ 66 + -H "X-Client-Key: $CLIENT_KEY" \ 65 67 -H "Authorization: Bearer $TOKEN" \ 66 68 -H "Content-Type: image/png" \ 67 69 --data-binary @image.png ··· 80 82 ``` 81 83 82 84 ```sh 83 - curl "http://localhost:3000/xrpc/xyz.statusphere.listStatuses?uri=at%3A%2F%2Fdid%3Aplc%3Aabc%2Fxyz.statusphere.status%2Fabc123" 85 + curl "http://localhost:3000/xrpc/xyz.statusphere.listStatuses?uri=at%3A%2F%2Fdid%3Aplc%3Aabc%2Fxyz.statusphere.status%2Fabc123" \ 86 + -H "X-Client-Key: $CLIENT_KEY" 84 87 ``` 85 88 86 89 **Response**: `200 OK` ··· 111 114 | `did` | string | --- | Filter records by DID | 112 115 113 116 ```sh 114 - curl "http://localhost:3000/xrpc/xyz.statusphere.listStatuses?limit=10&did=did:plc:abc" 117 + curl "http://localhost:3000/xrpc/xyz.statusphere.listStatuses?limit=10&did=did:plc:abc" \ 118 + -H "X-Client-Key: $CLIENT_KEY" 115 119 ``` 116 120 117 121 **Response**: `200 OK` ··· 145 149 146 150 ```sh 147 151 curl -X POST http://localhost:3000/xrpc/xyz.statusphere.setStatus \ 152 + -H "X-Client-Key: $CLIENT_KEY" \ 148 153 -H "Authorization: Bearer $TOKEN" \ 149 154 -H "Content-Type: application/json" \ 150 155 -d '{ "status": "\ud83d\ude0a", "createdAt": "2025-01-01T12:00:00Z" }' ··· 158 163 159 164 ```sh 160 165 curl -X POST http://localhost:3000/xrpc/xyz.statusphere.setStatus \ 166 + -H "X-Client-Key: $CLIENT_KEY" \ 161 167 -H "Authorization: Bearer $TOKEN" \ 162 168 -H "Content-Type: application/json" \ 163 169 -d '{
+1 -1
packages/docs/docs/tutorials/statusphere.md
··· 2 2 3 3 [Statusphere](https://github.com/bluesky-social/statusphere-example-app) is an example AT Protocol application where users set their current status as a single emoji. It's a great way to learn how HappyView works because the data model is simple but the queries are interesting. 4 4 5 - In this tutorial, you'll set up HappyView to act as the AppView for Statusphere. By the end, you'll have automatically indexed records and automatically generated XPRC endpoints. 5 + In this tutorial, you'll set up HappyView to act as the AppView for Statusphere. By the end, you'll have indexed records and working XRPC endpoints. 6 6 7 7 :::tip 8 8 This tutorial assumes you have a running HappyView instance. If you don't, start with the [Quickstart](../getting-started/deployment/railway.md) or one of the local development guides ([Docker](../getting-started/deployment/docker.md), [from source](../getting-started/deployment/other.md)).
+1 -1
packages/docs/docusaurus.config.ts
··· 62 62 additionalLanguages: ["lua"], 63 63 }, 64 64 footer: { 65 - copyright: `Copyright \u00a9 ${new Date().getFullYear()} [Birbhouse Games](https://birb.house).`, 65 + copyright: `Copyright \u00a9 ${new Date().getFullYear()} <a href="https://birb.house">Birbhouse Games</a>.`, 66 66 }, 67 67 } satisfies Preset.ThemeConfig, 68 68 };