Public
Like
1
location-feed-generator
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data β all from the browser, and deployed in milliseconds.
Viewing readonly version of main branch: v34View latest version
A complete location-based social feed generator built on the AT Protocol for decentralized social networking.
The system consists of 3 main components:
- Ingestion - Real-time check-in data ingestion from AT Protocol Jetstream
- API - Feed APIs for global, nearby, user, and following feeds
- Social - Social graph sync from Bluesky for following feeds
src/
βββ ingestion/ # Data ingestion from AT Protocol
β βββ jetstream-poller.ts
βββ api/ # HTTP API endpoints
β βββ anchor-api.ts
βββ social/ # Social graph management
β βββ social-graph-sync.ts
βββ utils/ # Shared utilities
βββ handle-resolver.ts
βββ address-resolver.ts
βββ address-cache.ts # Val Town blob storage cache
database/
βββ database-schema.sql # SQLite schema and indexes
docs/
βββ deployment-guide.md # Deployment instructions
scripts/
βββ deploy.sh # One-click deployment script
βββ test.sh # Run complete test suite
βββ test-api.sh # API testing script
tests/
βββ unit/ # Unit tests for individual functions
β βββ handle-resolver.test.ts
β βββ address-cache.test.ts
β βββ database.test.ts
β βββ spatial.test.ts
βββ integration/ # Integration tests for API endpoints
β βββ api.test.ts
βββ fixtures/ # Test data and fixtures
βββ test-data.ts
# Install Val Town CLI npm install -g @valtown/cli # Login to Val Town vt login # Run tests first ./scripts/test.sh # Deploy all functions ./scripts/deploy.sh # Test the deployment ./scripts/test-api.sh
# Deploy individual functions vt create cron jetstreamPoller --file src/ingestion/jetstream-poller.ts --schedule "*/5 * * * *" vt create http anchorAPI --file src/api/anchor-api.ts vt create cron socialGraphSync --file src/social/social-graph-sync.ts --schedule "0 2 * * *"
Note: No manual database setup required! Tables are created automatically when functions first run.
GET /global?limit=50&cursor=2025-06-29T15:00:00Z
Recent check-ins from all users with pagination.
GET /nearby?lat=52.0705&lng=4.3007&radius=5&limit=50
Spatial query for check-ins within specified radius (km).
GET /user?did=did:plc:abc123&limit=50
All check-ins from a specific user.
GET /following?user=did:plc:abc123&limit=50&cursor=2025-06-29T15:00:00Z
Check-ins from people the specified user follows on Bluesky.
GET /stats
AppView health metrics and processing statistics.
The system uses 4 main SQLite tables:
checkins_v1- Main check-ins with coordinates and cached address dataaddress_cache_v1- Resolved venue/address information from strongrefsuser_follows_v1- Social graph data for following-based feedsprocessing_log_v1- Monitoring and operational logging
- Real-time Ingestion: WebSocket polling every 5 minutes from Jetstream
- Address Resolution: Automatic strongref resolution with caching
- Spatial Queries: Nearby check-ins using Haversine distance calculations
- Social Integration: Following feeds leveraging Bluesky's social graph
- Performance: SQLite with proper indexing for fast queries
- Error Handling: Comprehensive error tracking and retry logic
# Run all tests ./scripts/test.sh # Run specific test suites deno task test:unit # Unit tests only deno task test:integration # Integration tests only # Run tests in watch mode deno task test:watch # Run with coverage ./scripts/test.sh --coverage
- Use TypeScript for all functions
- Import SQLite:
import { sqlite } from "https://esm.town/v/stevekrouse/sqlite" - Import blob storage:
import { blob } from "https://esm.town/v/std/blob" - Use
https://esm.shfor external dependencies - Never hardcode secrets - use
Deno.env.get('keyname') - Let errors bubble up with full context rather than catching and logging
- SQLite: Primary data (checkins, social graph, processing logs)
- Blob Storage: Caching layer for address resolution with automatic expiry
- Schema Changes: Increment table versions (e.g.,
checkins_v1βcheckins_v2) - Always create tables with
IF NOT EXISTSon function startup
- Monitor
/statsendpoint for system health - Check
processing_log_v1for ingestion metrics - Use built-in logging and debugging tools
- Monitor SQLite performance as data grows
- All API endpoints include proper CORS headers
- Public APIs only - no authentication required
- Rate limiting built into external service calls
- No sensitive data logged or stored
The AppView is fully compatible with the AT Protocol ecosystem:
- Ingests from Jetstream (official AT Protocol firehose)
- Resolves DIDs using PLC directory
- Fetches records via
com.atproto.repo.getRecord - Integrates with Bluesky social graph APIs
This implementation is part of the Anchor project for location-based social networking on the AT Protocol.