architecture.md (2974B)
1 --- 2 label: Architecture & State 3 icon: cpu 4 order: 580 5 --- 6 7 # Architecture & State Management 8 9 ## Visual system design 10 11 Data flows through three strictly isolated layers: 12 13 - **Presentation layer** — Ace Editor & vanilla DOM UI, reading via `state.editor.getValue()` 14 - **Local persistence** — IndexedDB (`VeyrixFS`), written via `DB.save(state.files)` 15 - **Cloud share (lazy)** — Firebase Firestore, written via `addDoc(shared_snippets)` — only touched when the user explicitly shares to the cloud 16 17 ## State management pattern 18 19 To maintain extreme performance on low-end mobile devices, Veyrix eschews frameworks like React or Vue. Instead it relies on a mutable, global singleton `state` object. UI updates happen through explicit imperative functions triggered by state mutations, avoiding full tree diffing. 20 21 ```javascript 22 // Global State Singleton 23 const state = { 24 files: [], // Array of File objects 25 activeFileId: null, // ID of currently rendered file 26 editor: null, // Ace Editor instance reference 27 db: null, // IndexedDB connection instance 28 renameTargetId: null // Transient state for UI modals 29 }; 30 ``` 31 32 **Architectural decision record (ADR):** the Ace Editor manages its own complex internal state (cursors, selections, undo stacks). Wrapping it in a reactive framework often causes race conditions during rapid typing. By keeping the source of truth in `state.editor` and extracting `value` asynchronously via debounced events, Veyrix achieves sub-16ms frame times. 33 34 ## Local storage model (IndexedDB) 35 36 Persistence is managed entirely via the browser's native IndexedDB API through a Promisified wrapper. The database is named `VeyrixFS` (Version 1). 37 38 ### Schema: `files` ObjectStore 39 40 KeyPath: `id` 41 42 ```typescript 43 // TypeScript representation of the IndexedDB record 44 interface VeyrixFile { 45 id: string; // e.g., "f_a1b2c3d4e_1679000000" 46 name: string; // Base filename (e.g., "app") 47 ext: string; // Extension (e.g., "js", "html") 48 content: string; // Raw string payload of the editor 49 unsaved: boolean; // Tracks dirty state for the UI 50 lastModified: number; // Epoch timestamp 51 snapshotCounter?: number; 52 snapshots?: Snapshot[]; // Array (max length: 5, FIFO eviction) 53 } 54 ``` 55 56 ## Cloud & synchronization strategy 57 58 Veyrix uses a zero-cost initial load strategy: Firebase SDKs (App, Auth, Firestore) are **not** bundled or loaded on startup. They're dynamically imported via ES Modules only when a user initiates a "Cloud Share." 59 60 ### 1. Fast local share (LZ-String) 61 62 Compresses the payload with `LZString.compressToEncodedURIComponent`, yielding a base64-like URI-safe string appended directly to the URL. Entirely offline, entirely client-side. 63 64 ### 2. Cloud share (Firestore) 65 66 Authenticates using `signInAnonymously()`, pushes the payload to the `shared_snippets` root collection, and returns a lightweight document ID reference in the URL.