architecture.mdx (3033B)
1 --- 2 title: "Architecture & State Management" 3 sidebarTitle: "Architecture & State" 4 --- 5 6 import Copyright from "/snippets/copyright.mdx"; 7 8 ## Visual system design 9 10 Data flows through three strictly isolated layers: 11 12 - **Presentation layer** — Ace Editor & vanilla DOM UI, reading via `state.editor.getValue()` 13 - **Local persistence** — IndexedDB (`VeyrixFS`), written via `DB.save(state.files)` 14 - **Cloud share (lazy)** — Firebase Firestore, written via `addDoc(shared_snippets)` — only touched when the user explicitly shares to the cloud 15 16 ## State management pattern 17 18 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. 19 20 ```javascript 21 // Global State Singleton 22 const state = { 23 files: [], // Array of File objects 24 activeFileId: null, // ID of currently rendered file 25 editor: null, // Ace Editor instance reference 26 db: null, // IndexedDB connection instance 27 renameTargetId: null // Transient state for UI modals 28 }; 29 ``` 30 31 **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. 32 33 ## Local storage model (IndexedDB) 34 35 Persistence is managed entirely via the browser's native IndexedDB API through a Promisified wrapper. The database is named `VeyrixFS` (Version 1). 36 37 ### Schema: `files` ObjectStore 38 39 KeyPath: `id` 40 41 ```typescript 42 // TypeScript representation of the IndexedDB record 43 interface VeyrixFile { 44 id: string; // e.g., "f_a1b2c3d4e_1679000000" 45 name: string; // Base filename (e.g., "app") 46 ext: string; // Extension (e.g., "js", "html") 47 content: string; // Raw string payload of the editor 48 unsaved: boolean; // Tracks dirty state for the UI 49 lastModified: number; // Epoch timestamp 50 snapshotCounter?: number; 51 snapshots?: Snapshot[]; // Array (max length: 5, FIFO eviction) 52 } 53 ``` 54 55 ## Cloud & synchronization strategy 56 57 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." 58 59 ### 1. Fast local share (LZ-String) 60 61 Compresses the payload with `LZString.compressToEncodedURIComponent`, yielding a base64-like URI-safe string appended directly to the URL. Entirely offline, entirely client-side. 62 63 ### 2. Cloud share (Firestore) 64 65 Authenticates using `signInAnonymously()`, pushes the payload to the `shared_snippets` root collection, and returns a lightweight document ID reference in the URL. 66 67 <Copyright />