···1+MIT License
2+3+Copyright (c) 2026 Steve Simkins
4+5+Permission is hereby granted, free of charge, to any person obtaining a copy
6+of this software and associated documentation files (the "Software"), to deal
7+in the Software without restriction, including without limitation the rights
8+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+copies of the Software, and to permit persons to whom the Software is
10+furnished to do so, subject to the following conditions:
11+12+The above copyright notice and this permission notice shall be included in all
13+copies or substantial portions of the Software.
14+15+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+SOFTWARE.
+5-112
README.md
···67```
8┌─────────────────────────────────────────────────────────────┐
9-│ Cloudflare │
10├─────────────────────────────────────────────────────────────┤
11-│ │
12│ ┌──────────────┐ ┌──────────────┐ ┌─────────────┐ │
13│ │ Pages │────▶│ Worker │────▶│ D1 │ │
14│ │ (Client) │ │ (API) │ │ (Database) │ │
15│ └──────────────┘ └──────────────┘ └─────────────┘ │
16-│ ▲ ▲ │
17-│ │ │ │
18│ ┌──────┴───────┐ ┌──────┴───────┐ │
19│ │ Queue │ │ Cron │ │
20│ │ (Resolver) │ │ (Refresh) │ │
···24 │ POST /webhook/tap
25 ┌──────────┴───────────┐
26 │ Tap Instance │
27- │ (External VPS) │
28 └──────────────────────┘
29```
30···342. **Server** (`packages/server`) - Cloudflare Worker with Hono API, D1 database, and Queue consumer
353. **Client** (`packages/client`) - Vite + React app deployed to Cloudflare Pages
3637-## Quick Start
38-39-### Prerequisites
40-41-- [Bun](https://bun.sh) installed
42-- [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/) installed and authenticated
43-- A tap instance running somewhere (VPS, Fly.io, etc.)
44-45-### Setup
46-47-1. Install dependencies:
48-49-```bash
50-bun install
51-```
52-53-2. Create the D1 database:
54-55-```bash
56-bun run db:create
57-```
58-59-Copy the database ID and update `packages/server/wrangler.toml`.
60-61-3. Create the queue:
62-63-```bash
64-wrangler queues create document-resolution
65-```
66-67-4. Run database migrations:
68-69-```bash
70-# Local development
71-bun run db:migrate
72-73-# Production
74-bun run db:migrate:prod
75-```
76-77-5. (Optional) Set webhook secret:
78-79-```bash
80-bun run secret:set
81-```
82-83-6. Deploy the worker:
84-85-```bash
86-bun run deploy
87-```
88-89-7. Configure your tap instance:
90-91-```bash
92-TAP_WEBHOOK_URL=https://your-worker.workers.dev/webhook/tap
93-TAP_SIGNAL_COLLECTION=site.standard.document
94-TAP_COLLECTION_FILTERS=site.standard.document
95-```
96-97-8. Trigger initial resolution of existing records:
98-99-```bash
100-curl -X POST https://your-worker.workers.dev/admin/resolve-all
101-```
102-103## Local Development
1041051. Start the worker locally:
···1553. **Queue consumer** resolves each document (PDS lookup → record fetch → publication URL) and stores in `resolved_documents`
1564. **Cron job** (every 15 min) refreshes stale documents and processes any missed records
1575. **`/feed` endpoint** reads directly from `resolved_documents` for instant responses
158-159-## Project Structure
160-161-```
162-.
163-├── package.json # Root workspace config
164-└── packages/
165- ├── server/ # Cloudflare Worker
166- │ ├── wrangler.toml # Worker configuration
167- │ ├── schema.sql # D1 database schema
168- │ ├── package.json
169- │ └── src/
170- │ └── index.ts # API + Queue consumer + Cron handler
171- └── client/ # Vite + React app
172- ├── package.json
173- ├── vite.config.ts
174- └── src/
175- ├── main.tsx
176- └── App.tsx
177-```
178-179-## Scripts
180-181-```bash
182-# Development
183-bun run dev # Run all packages in dev mode
184-bun run dev:server # Run worker locally
185-bun run dev:client # Run client locally
186-187-# Deployment
188-bun run deploy # Deploy worker to Cloudflare
189-bun run deploy:client # Deploy client to Cloudflare Pages
190-191-# Database
192-bun run db:create # Create D1 database
193-bun run db:migrate # Run migrations (local)
194-bun run db:migrate:prod # Run migrations (production)
195-196-# Secrets
197-bun run secret:set # Set TAP_WEBHOOK_SECRET
198-```
199200## Resources
201
···67```
8┌─────────────────────────────────────────────────────────────┐
9+│ Cloudflare │
10├─────────────────────────────────────────────────────────────┤
11+│ │
12│ ┌──────────────┐ ┌──────────────┐ ┌─────────────┐ │
13│ │ Pages │────▶│ Worker │────▶│ D1 │ │
14│ │ (Client) │ │ (API) │ │ (Database) │ │
15│ └──────────────┘ └──────────────┘ └─────────────┘ │
16+│ ▲ ▲ │
17+│ │ │ │
18│ ┌──────┴───────┐ ┌──────┴───────┐ │
19│ │ Queue │ │ Cron │ │
20│ │ (Resolver) │ │ (Refresh) │ │
···24 │ POST /webhook/tap
25 ┌──────────┴───────────┐
26 │ Tap Instance │
27+ │ (External) │
28 └──────────────────────┘
29```
30···342. **Server** (`packages/server`) - Cloudflare Worker with Hono API, D1 database, and Queue consumer
353. **Client** (`packages/client`) - Vite + React app deployed to Cloudflare Pages
3600000000000000000000000000000000000000000000000000000000000000000037## Local Development
38391. Start the worker locally:
···893. **Queue consumer** resolves each document (PDS lookup → record fetch → publication URL) and stores in `resolved_documents`
904. **Cron job** (every 15 min) refreshes stale documents and processes any missed records
915. **`/feed` endpoint** reads directly from `resolved_documents` for instant responses
000000000000000000000000000000000000000009293## Resources
94