Highly ambitious ATProtocol AppView service and sdks
1# Core Concepts 2 3Slices is built on four fundamental concepts that work together to create a 4powerful AT Protocol development platform. 5 6``` 7Slices → Lexicons → Sync → APIs 8(Container) → (Schema) → (Data) → (Access) 9``` 10 11## **Slices**: Your Data Universe 12 13### What is a Slice? 14 15A slice is your own independent data space within the AT Protocol network. Think 16of it as a database with built-in APIs, authentication, and real-time sync, all 17isolated from other slices. 18 19### Why Slices Matter 20 21In the AT Protocol ecosystem, data lives on Personal Data Servers (PDS) 22scattered across the network. Slices acts as an **AppView** that: 23 24- Aggregates data from across the network 25- Applies your custom schemas 26- Provides instant APIs for your data 27- Maintains complete data isolation 28 29### Creating Your Slice 30 31When you create a slice for `com.recordcollector`: 32 33``` 34Slice Name: My Vinyl Collection 35Domain: com.recordcollector 36URI: at://did:plc:abc123/network.slices.slice/xyz789 37``` 38 39This slice becomes the container for all your vinyl collection data, completely 40isolated from other slices. 41 42### Key Properties 43 44- **URI**: Unique AT Protocol identifier 45- **Domain**: Your namespace (e.g., `com.recordcollector`) 46- **Isolation**: Complete data separation between slices 47- **Multi-tenancy**: Multiple users can have data in the same slice 48 49### Example: Record Collector Slice 50 51```json 52{ 53 "uri": "at://did:plc:abc123/network.slices.slice/xyz789", 54 "name": "Vinyl Collection Manager", 55 "domain": "com.recordcollector", 56 "createdAt": "2024-01-15T10:00:00Z" 57} 58``` 59 60## **Lexicons**: Data Schemas 61 62### What are Lexicons? 63 64Lexicons are JSON schemas that define the structure of your data in AT Protocol. 65They're like database tables with built-in validation. In Slices, these lexicons 66automatically generate APIs for you. 67 68### Defining Your Data 69 70For a record collector app, you might define an album lexicon: 71 72```json 73{ 74 "lexicon": 1, 75 "id": "com.recordcollector.album", 76 "defs": { 77 "main": { 78 "type": "record", 79 "description": "A vinyl album in the collection", 80 "record": { 81 "type": "object", 82 "required": ["title", "artist", "releaseDate"], 83 "properties": { 84 "title": { 85 "type": "string", 86 "description": "Album title" 87 }, 88 "artist": { 89 "type": "string", 90 "description": "Artist or band name" 91 }, 92 "releaseDate": { 93 "type": "string", 94 "format": "datetime", 95 "description": "Original release date" 96 }, 97 "genre": { 98 "type": "array", 99 "items": { "type": "string" }, 100 "description": "Musical genres" 101 }, 102 "condition": { 103 "type": "string", 104 "enum": [ 105 "Mint", 106 "Near Mint", 107 "Very Good Plus", 108 "Very Good", 109 "Good", 110 "Fair", 111 "Poor" 112 ], 113 "description": "Vinyl condition grading" 114 }, 115 "notes": { 116 "type": "string", 117 "maxLength": 1000, 118 "description": "Collector's notes" 119 } 120 } 121 } 122 } 123 } 124} 125``` 126 127### Primary vs External Lexicons 128 129**Primary Lexicons**: Match your slice domain: 130 131- `com.recordcollector.album` 132- `com.recordcollector.review` 133- `com.recordcollector.wishlist` 134 135**External Lexicons**: From other namespaces: 136 137- `app.bsky.actor.profile` (Bluesky profiles) 138- `sh.tangled.repo` (Tangled Repo) 139- `social.grain.photo` (Grain Photos) 140- `com.cassettecollector.tape` (Cassette Collector) 141 142### Automatic API Generation 143 144Each lexicon with `type: "record"` automatically creates endpoints. Record types 145are the only lexicons that generate CRUD APIs: 146 147``` 148com.recordcollector.album (type: "record") → 149 /xrpc/com.recordcollector.album.getRecords 150 /xrpc/com.recordcollector.album.createRecord 151 /xrpc/com.recordcollector.album.updateRecord 152 /xrpc/com.recordcollector.album.deleteRecord 153``` 154 155Note: Other lexicon types (like `query`, `procedure`, or `subscription`) serve 156different purposes and don't create these standard CRUD endpoints. 157 158## **Sync**: Data Flow 159 160### How Data Enters Your Slice 161 162The sync engine manages how data flows into your slice from the AT Protocol 163network. 164 165### Three Sync Strategies 166 167#### 1. Bulk Sync: Historical Import 168 169Perfect for initial data loading or periodic updates. When you're first starting 170out, you might only be syncing your own records from your PDS. But as more 171people adopt your app and write records to their own PDSs, you can sync from 172their repositories too, growing your network. 173 174Specify: 175 176- Collections to sync (e.g., `com.recordcollector.album`) 177- External collections (e.g., `app.bsky.actor.profile` for user profiles) 178- Specific repositories (DIDs) to import from 179 180#### 2. User Sync: On-Demand 181 182Automatically syncs when users log in. This is primarily for discovering and 183syncing external collections. When a new user authenticates for the first time, 184they become an actor in your slice, allowing you to discover what external 185collections they have (like Bluesky profiles or posts) and sync that data from 186their PDS. 187 188#### 3. Jetstream: Real-Time Updates 189 190Connects to the AT Protocol firehose for live updates. This tracks create, 191update, and delete events as they happen across the network. 192 193``` 194Firehose Event → Filter by Collection → Validate → Store in Slice 195``` 196 197### Syncing External Data 198 199Import Bluesky profiles to show who owns each album and their Bluesky avatar. 200You can sync external collections like `app.bsky.actor.profile` to enrich your 201slice with user information from the broader AT Protocol network. 202 203### Performance Features 204 205- **CID Deduplication**: Skips unchanged records 206- **Bulk Operations**: Processes thousands of records efficiently 207- **Actor Caching**: Reduces database lookups 208- **Auto-Recovery**: Handles network interruptions 209 210### Example: Syncing a Vinyl Community 211 212To sync all albums from a vinyl collecting community, you would: 213 214- List primary collections (`com.recordcollector.album`, 215 `com.recordcollector.review`) 216- Include external collections (`app.bsky.actor.profile`) to show collector 217 information 218 219## **Code Generation & XRPC Endpoints**: APIs & SDKs 220 221### Dynamic API Creation 222 223Every record-type lexicon automatically generates REST-like XRPC endpoints. 224 225### Generated Endpoints 226 227For `com.recordcollector.album`: 228 229#### List Albums 230 231```http 232POST /xrpc/com.recordcollector.album.getRecords 233{ 234 "slice": "at://your-slice-uri", 235 "where": { "genre": { "contains": "jazz" } }, 236 "sortBy": [{ "field": "releaseDate", "direction": "desc" }], 237 "limit": 20 238} 239``` 240 241#### Add Album 242 243```http 244POST /xrpc/com.recordcollector.album.createRecord 245Authorization: Bearer YOUR_TOKEN 246{ 247 "slice": "at://your-slice-uri", 248 "record": { 249 "title": "Kind of Blue", 250 "artist": "Miles Davis", 251 "releaseDate": "1959-08-17T00:00:00Z", 252 "genre": ["jazz", "modal jazz"], 253 "condition": "Very Good Plus" 254 } 255} 256``` 257 258### TypeScript SDK Generation 259 260Slices generates a fully-typed TypeScript client: 261 262```typescript 263// Generated SDK with full type safety 264import { AtprotoClient } from "./generated_client.ts"; 265 266const client = new AtprotoClient({ 267 baseUrl: "https://api.slices.network", 268 sliceUri: "at://your-slice-uri", 269 auth: oauthClient, 270}); 271 272// Fully typed operations 273const albums = await client.com.recordcollector.album.getRecords({ 274 where: { 275 condition: { in: ["Mint", "Near Mint"] }, 276 genre: { contains: "jazz" }, 277 }, 278 sortBy: [{ field: "artist", direction: "asc" }], 279 limit: 50, 280}); 281 282// Type-safe record creation 283const newAlbum = await client.com.recordcollector.album.createRecord({ 284 title: "Blue Train", 285 artist: "John Coltrane", 286 releaseDate: "1958-01-01T00:00:00Z", 287 genre: ["jazz", "hard bop"], 288 condition: "Near Mint", 289 notes: "Original Blue Note pressing", 290}); 291``` 292 293### OAuth Integration 294 295Built-in OAuth 2.0 with PKCE: 296 297- Read operations: Public by default 298- Write operations: Require authentication 299- Automatic token refresh 300- Secure session management 301 302### SDK Features 303 304- **Type Safety**: Full TypeScript types from lexicons 305- **Nested APIs**: `client.com.recordcollector.album.*` 306- **Error Handling**: Automatic retries and graceful failures 307- **Blob Support**: Handle images and media files 308 309## How It All Works Together 310 311``` 3121. Create Slice → Define namespace (com.recordcollector) 3133142. Add Lexicons → Define data structure (album, review, wishlist) 3153163. Sync Data → Import existing vinyl collections 317 → Subscribe to real-time updates 3183194. Use APIs → Generated endpoints for all operations 320 → Type-safe SDK for your app 321``` 322 323## Practical Example: Building a Vinyl Collector App 324 325### Step 1: Create Your Slice 326 327Create a slice using the Slices CLI or web interface: 328 329- Name: "Vintage Vinyl Collectors" 330- Domain: "com.recordcollector" 331 332### Step 2: Define Lexicons 333 334Upload your lexicon definitions through the web UI or CLI: 335 336- Album schema (`com.recordcollector.album`) 337- Review schema (`com.recordcollector.review`) 338- Wishlist schema (`com.recordcollector.wishlist`) 339 340### Step 3: Sync Existing Data 341 342Start a sync job to import your existing collection: 343 344- Use the Sync tab in the web UI 345- Select collections to sync 346- Specify repositories (or leave empty for all) 347 348### Step 4: Build Your App 349 350```javascript 351// Use the generated SDK 352const client = new AtprotoClient(slice.uri); 353 354// List all jazz albums in mint condition 355const jazzMint = await client.com.recordcollector.album.getRecords({ 356 where: { 357 genre: { contains: "jazz" }, 358 condition: { eq: "Mint" }, 359 }, 360}); 361 362// Add a new album to the collection 363await client.com.recordcollector.album.createRecord({ 364 title: "A Love Supreme", 365 artist: "John Coltrane", 366 releaseDate: "1965-02-01T00:00:00Z", 367 genre: ["jazz", "spiritual jazz"], 368 condition: "Near Mint", 369}); 370``` 371 372## Summary 373 374| Concept | Purpose | Record Collector Example | 375| ------------ | ------------------------------- | ----------------------------------------------------------- | 376| **Slices** | Isolated data container | `com.recordcollector` namespace with all your vinyl data | 377| **Lexicons** | Schema definitions | `album`, `review`, `wishlist` record types | 378| **Sync** | Data import & real-time updates | Import collections from network, live updates via Jetstream | 379| **Code Gen** | Auto-generated APIs & SDKs | TypeScript client with `getRecords`, `createRecord`, etc. | 380 381## Next Steps 382 383- [Getting Started](./getting-started.md): Create your first slice 384- [API Reference](./api-reference.md): Detailed endpoint documentation 385- [SDK Usage](./sdk-usage.md): Advanced SDK patterns