learn and share notes on atproto (wip) 馃 malfestio.stormlightlabs.org/
readability solid axum atproto srs
at main 84 lines 2.0 kB view raw
1import Dexie, { type EntityTable } from "dexie"; 2import type { CardType, Visibility } from "./model"; 3 4export type SyncStatus = "local_only" | "synced" | "pending_push" | "conflict"; 5 6type EntityKind = "deck" | "card" | "note"; 7 8type OperationKind = "push" | "delete"; 9 10type SyncTracking = { syncStatus: SyncStatus; localVersion: number; pdsCid?: string }; 11 12export type LocalDeck = SyncTracking & { 13 id: string; 14 ownerDid: string; 15 title: string; 16 description: string; 17 tags: string[]; 18 visibility: Visibility; 19 publishedAt?: string; 20 forkOf?: string; 21 pdsUri?: string; 22 updatedAt: string; 23}; 24 25export type LocalCard = SyncTracking & { 26 id: string; 27 deckId: string; 28 front: string; 29 back: string; 30 mediaUrl?: string; 31 cardType: CardType; 32 hints: string[]; 33}; 34 35export type LocalNote = SyncTracking & { 36 id: string; 37 ownerDid: string; 38 title: string; 39 body: string; 40 tags: string[]; 41 visibility: Visibility; 42 publishedAt?: string; 43 links: string[]; 44 pdsUri?: string; 45 updatedAt: string; 46}; 47 48export type SyncQueueItem = { 49 id?: number; 50 entityType: EntityKind; 51 entityId: string; 52 operation: OperationKind; 53 createdAt: string; 54 retryCount: number; 55 lastError?: string; 56}; 57 58class MalfestioDatabase extends Dexie { 59 decks!: EntityTable<LocalDeck, "id">; 60 cards!: EntityTable<LocalCard, "id">; 61 notes!: EntityTable<LocalNote, "id">; 62 syncQueue!: EntityTable<SyncQueueItem, "id">; 63 64 constructor() { 65 super("malfestio"); 66 67 this.version(1).stores({ 68 decks: "id, ownerDid, syncStatus, updatedAt", 69 cards: "id, deckId, syncStatus", 70 notes: "id, ownerDid, syncStatus, updatedAt", 71 syncQueue: "++id, entityType, entityId, createdAt", 72 }); 73 } 74} 75 76export const db = new MalfestioDatabase(); 77 78export function generateLocalId(): string { 79 return `local_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`; 80} 81 82export function isLocalId(id: string): boolean { 83 return id.startsWith("local_"); 84}