# Core Concepts Slices is built on four fundamental concepts that work together to create a powerful AT Protocol development platform. ``` Slices → Lexicons → Sync → APIs (Container) → (Schema) → (Data) → (Access) ``` ## **Slices**: Your Data Universe ### What is a Slice? A slice is your own independent data space within the AT Protocol network. Think of it as a database with built-in APIs, authentication, and real-time sync, all isolated from other slices. ### Why Slices Matter In the AT Protocol ecosystem, data lives on Personal Data Servers (PDS) scattered across the network. Slices acts as an **AppView** that: - Aggregates data from across the network - Applies your custom schemas - Provides instant APIs for your data - Maintains complete data isolation ### Creating Your Slice When you create a slice for `com.recordcollector`: ``` Slice Name: My Vinyl Collection Domain: com.recordcollector URI: at://did:plc:abc123/network.slices.slice/xyz789 ``` This slice becomes the container for all your vinyl collection data, completely isolated from other slices. ### Key Properties - **URI**: Unique AT Protocol identifier - **Domain**: Your namespace (e.g., `com.recordcollector`) - **Isolation**: Complete data separation between slices - **Multi-tenancy**: Multiple users can have data in the same slice ### Example: Record Collector Slice ```json { "uri": "at://did:plc:abc123/network.slices.slice/xyz789", "name": "Vinyl Collection Manager", "domain": "com.recordcollector", "createdAt": "2024-01-15T10:00:00Z" } ``` ## **Lexicons**: Data Schemas ### What are Lexicons? Lexicons are JSON schemas that define the structure of your data in AT Protocol. They're like database tables with built-in validation. In Slices, these lexicons automatically generate APIs for you. ### Defining Your Data For a record collector app, you might define an album lexicon: ```json { "lexicon": 1, "id": "com.recordcollector.album", "defs": { "main": { "type": "record", "description": "A vinyl album in the collection", "record": { "type": "object", "required": ["title", "artist", "releaseDate"], "properties": { "title": { "type": "string", "description": "Album title" }, "artist": { "type": "string", "description": "Artist or band name" }, "releaseDate": { "type": "string", "format": "datetime", "description": "Original release date" }, "genre": { "type": "array", "items": { "type": "string" }, "description": "Musical genres" }, "condition": { "type": "string", "enum": [ "Mint", "Near Mint", "Very Good Plus", "Very Good", "Good", "Fair", "Poor" ], "description": "Vinyl condition grading" }, "notes": { "type": "string", "maxLength": 1000, "description": "Collector's notes" } } } } } } ``` ### Primary vs External Lexicons **Primary Lexicons**: Match your slice domain: - `com.recordcollector.album` - `com.recordcollector.review` - `com.recordcollector.wishlist` **External Lexicons**: From other namespaces: - `app.bsky.actor.profile` (Bluesky profiles) - `sh.tangled.repo` (Tangled Repo) - `social.grain.photo` (Grain Photos) - `com.cassettecollector.tape` (Cassette Collector) ### Automatic API Generation Each lexicon with `type: "record"` automatically creates endpoints. Record types are the only lexicons that generate CRUD APIs: ``` com.recordcollector.album (type: "record") → /xrpc/com.recordcollector.album.getRecords /xrpc/com.recordcollector.album.createRecord /xrpc/com.recordcollector.album.updateRecord /xrpc/com.recordcollector.album.deleteRecord ``` Note: Other lexicon types (like `query`, `procedure`, or `subscription`) serve different purposes and don't create these standard CRUD endpoints. ## **Sync**: Data Flow ### How Data Enters Your Slice The sync engine manages how data flows into your slice from the AT Protocol network. ### Three Sync Strategies #### 1. Bulk Sync: Historical Import Perfect for initial data loading or periodic updates. When you're first starting out, you might only be syncing your own records from your PDS. But as more people adopt your app and write records to their own PDSs, you can sync from their repositories too, growing your network. Specify: - Collections to sync (e.g., `com.recordcollector.album`) - External collections (e.g., `app.bsky.actor.profile` for user profiles) - Specific repositories (DIDs) to import from #### 2. User Sync: On-Demand Automatically syncs when users log in. This is primarily for discovering and syncing external collections. When a new user authenticates for the first time, they become an actor in your slice, allowing you to discover what external collections they have (like Bluesky profiles or posts) and sync that data from their PDS. #### 3. Jetstream: Real-Time Updates Connects to the AT Protocol firehose for live updates. This tracks create, update, and delete events as they happen across the network. ``` Firehose Event → Filter by Collection → Validate → Store in Slice ``` ### Syncing External Data Import Bluesky profiles to show who owns each album and their Bluesky avatar. You can sync external collections like `app.bsky.actor.profile` to enrich your slice with user information from the broader AT Protocol network. ### Performance Features - **CID Deduplication**: Skips unchanged records - **Bulk Operations**: Processes thousands of records efficiently - **Actor Caching**: Reduces database lookups - **Auto-Recovery**: Handles network interruptions ### Example: Syncing a Vinyl Community To sync all albums from a vinyl collecting community, you would: - List primary collections (`com.recordcollector.album`, `com.recordcollector.review`) - Include external collections (`app.bsky.actor.profile`) to show collector information ## **Code Generation & XRPC Endpoints**: APIs & SDKs ### Dynamic API Creation Every record-type lexicon automatically generates REST-like XRPC endpoints. ### Generated Endpoints For `com.recordcollector.album`: #### List Albums ```http POST /xrpc/com.recordcollector.album.getRecords { "slice": "at://your-slice-uri", "where": { "genre": { "contains": "jazz" } }, "sortBy": [{ "field": "releaseDate", "direction": "desc" }], "limit": 20 } ``` #### Add Album ```http POST /xrpc/com.recordcollector.album.createRecord Authorization: Bearer YOUR_TOKEN { "slice": "at://your-slice-uri", "record": { "title": "Kind of Blue", "artist": "Miles Davis", "releaseDate": "1959-08-17T00:00:00Z", "genre": ["jazz", "modal jazz"], "condition": "Very Good Plus" } } ``` ### TypeScript SDK Generation Slices generates a fully-typed TypeScript client: ```typescript // Generated SDK with full type safety import { AtprotoClient } from "./generated_client.ts"; const client = new AtprotoClient({ baseUrl: "https://api.slices.network", sliceUri: "at://your-slice-uri", auth: oauthClient, }); // Fully typed operations const albums = await client.com.recordcollector.album.getRecords({ where: { condition: { in: ["Mint", "Near Mint"] }, genre: { contains: "jazz" }, }, sortBy: [{ field: "artist", direction: "asc" }], limit: 50, }); // Type-safe record creation const newAlbum = await client.com.recordcollector.album.createRecord({ title: "Blue Train", artist: "John Coltrane", releaseDate: "1958-01-01T00:00:00Z", genre: ["jazz", "hard bop"], condition: "Near Mint", notes: "Original Blue Note pressing", }); ``` ### OAuth Integration Built-in OAuth 2.0 with PKCE: - Read operations: Public by default - Write operations: Require authentication - Automatic token refresh - Secure session management ### SDK Features - **Type Safety**: Full TypeScript types from lexicons - **Nested APIs**: `client.com.recordcollector.album.*` - **Error Handling**: Automatic retries and graceful failures - **Blob Support**: Handle images and media files ## How It All Works Together ``` 1. Create Slice → Define namespace (com.recordcollector) ↓ 2. Add Lexicons → Define data structure (album, review, wishlist) ↓ 3. Sync Data → Import existing vinyl collections → Subscribe to real-time updates ↓ 4. Use APIs → Generated endpoints for all operations → Type-safe SDK for your app ``` ## Practical Example: Building a Vinyl Collector App ### Step 1: Create Your Slice Create a slice using the Slices CLI or web interface: - Name: "Vintage Vinyl Collectors" - Domain: "com.recordcollector" ### Step 2: Define Lexicons Upload your lexicon definitions through the web UI or CLI: - Album schema (`com.recordcollector.album`) - Review schema (`com.recordcollector.review`) - Wishlist schema (`com.recordcollector.wishlist`) ### Step 3: Sync Existing Data Start a sync job to import your existing collection: - Use the Sync tab in the web UI - Select collections to sync - Specify repositories (or leave empty for all) ### Step 4: Build Your App ```javascript // Use the generated SDK const client = new AtprotoClient(slice.uri); // List all jazz albums in mint condition const jazzMint = await client.com.recordcollector.album.getRecords({ where: { genre: { contains: "jazz" }, condition: { eq: "Mint" }, }, }); // Add a new album to the collection await client.com.recordcollector.album.createRecord({ title: "A Love Supreme", artist: "John Coltrane", releaseDate: "1965-02-01T00:00:00Z", genre: ["jazz", "spiritual jazz"], condition: "Near Mint", }); ``` ## Summary | Concept | Purpose | Record Collector Example | | ------------ | ------------------------------- | ----------------------------------------------------------- | | **Slices** | Isolated data container | `com.recordcollector` namespace with all your vinyl data | | **Lexicons** | Schema definitions | `album`, `review`, `wishlist` record types | | **Sync** | Data import & real-time updates | Import collections from network, live updates via Jetstream | | **Code Gen** | Auto-generated APIs & SDKs | TypeScript client with `getRecords`, `createRecord`, etc. | ## Next Steps - [Getting Started](./getting-started.md): Create your first slice - [API Reference](./api-reference.md): Detailed endpoint documentation - [SDK Usage](./sdk-usage.md): Advanced SDK patterns