From 702a7a73de0f7fb891f5fe53caf1811bea150677 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Mon, 30 Mar 2026 17:49:29 -0400 Subject: [PATCH] docs: update architecture notes and TODO with Svelte 5 store migration plan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AE__Architecture.md: minor wording fix - TODO__Agents.md: add Svelte 4→5 store migration task (root cause of IDAA Novi re-auth bug; prerequisite for Phase 2c store refactor) - PROJECT__Stores_Svelte5_Migration.md: new migration planning doc Co-Authored-By: Claude Sonnet 4.6 --- documentation/AE__Architecture.md | 2 +- .../PROJECT__Stores_Svelte5_Migration.md | 97 +++++++++++++++++++ documentation/TODO__Agents.md | 38 ++++++++ 3 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 documentation/PROJECT__Stores_Svelte5_Migration.md diff --git a/documentation/AE__Architecture.md b/documentation/AE__Architecture.md index 820f07d5..1546ec3a 100644 --- a/documentation/AE__Architecture.md +++ b/documentation/AE__Architecture.md @@ -153,7 +153,7 @@ The Electron app (`aether_app_native_electron/`) exists **solely** to support th - Hardware telemetry for connected devices **What Electron is NOT used for:** -- Badge printing (browser works fine) +- Badge printing (browser works well) - Any other Aether module - Any general-purpose Aether functionality diff --git a/documentation/PROJECT__Stores_Svelte5_Migration.md b/documentation/PROJECT__Stores_Svelte5_Migration.md new file mode 100644 index 00000000..8f8e7261 --- /dev/null +++ b/documentation/PROJECT__Stores_Svelte5_Migration.md @@ -0,0 +1,97 @@ +# Project: Svelte 4 Store → Svelte 5 State Migration + +**Status:** Execution / Phase B (In Progress) +**Priority:** High (post-April 2026 conference) +**Created:** 2026-03-30 +**Related:** `TODO__Agents.md` — [Stores] Svelte 5 State Migration entry + +--- + +## Background + +All core Aether stores (`ae_loc`, `idaa_loc`, `ae_events_loc`, etc.) are being migrated from +Svelte 4 stores to Svelte 5 `$state` using the `runed` library's `PersistedState`. This provides +fine-grained reactivity, ensuring that effects only re-run when specific fields they access are +updated, rather than on every write to the store object. + +### Phase B Progress & Learnings (Updated 2026-03-30) + +1. **Dependency Installed**: `runed` is now a project dependency. +2. **Module Resolution Strategy**: + - Core store files renamed: `ae_stores.ts` → `ae_stores.svelte.ts`, etc. + - **Critical Discovery**: SvelteKit and CLI tools (`svelte-check`) struggled to resolve + extension-less imports (like `$lib/stores/ae_stores`) when only `.svelte.ts` existed. + - **Solution**: Created `.ts` wrapper files (e.g., `src/lib/stores/ae_stores.ts`) that + simply re-export everything via `export * from './ae_stores.svelte'`. This maintains + backward compatibility for all existing import paths without manual updates. +3. **API Confirmation**: Confirmed that `runed`'s `PersistedState` uses `.current` to access + the state object, matching the intended migration syntax. +4. **Mass Replacement**: + - `$ae_loc` → `ae_loc_v5.current` + - `$idaa_loc` → `idaa_loc_v5.current` + - `$events_loc` → `events_loc_v5.current` + - These replacements have been applied across the entire `src/` directory (~2000+ sites). +5. **Import Updates**: A robust Python script was used to surgically add `ae_loc_v5`, + `idaa_loc_v5`, and `events_loc_v5` to existing import blocks, avoiding `import type` + lines and duplicates. + +--- + +## Syntax Changes: Before / After + +### Store declaration + +```typescript +// BEFORE (ae_stores.svelte.ts) +export const ae_loc: Writable = persisted('ae_loc', defaults); + +// AFTER (ae_stores.svelte.ts) +export const ae_loc_v5 = new PersistedState('ae_loc', defaults); +``` + +### Reading/Writing (Consumers) + +```svelte + +{$ae_loc.theme_mode} +{#if $ae_loc.trusted_access} + + +{ae_loc_v5.current.theme_mode} +{#if ae_loc_v5.current.trusted_access} +``` + +### Batch Update Pattern + +```typescript +// Use Object.assign for multi-field updates to maintain fine-grained reactivity +Object.assign(ae_loc_v5.current, { theme_mode: 'dark', edit_mode: true }); +``` + +--- + +## Implementation Notes + +### Prettier & Formatting +Because the mass migration touches ~250 files, formatting may be inconsistent (especially in +import blocks). It is recommended to run `npm run format` (if available) or rely on standard +linting after the imports are stabilized. + +### Batching vs. "Big Sweep" +While the original plan suggested smaller batches, the global nature of `ae_loc` and the +hundreds of interdependent files made a "Big Sweep" more efficient to ensure the app remains +in a consistent state. However, verification should still be done module-by-module. + +--- + +## Current Status (Pause Point) + +- [x] Phase A: Plan written. +- [x] Phase B: Core infrastructure setup (runed, renames, wrappers). +- [x] Phase B: Mass variable replacement ($ae_loc -> ae_loc_v5.current). +- [/] Phase B: Mass import update (In Progress/Verifying). +- [ ] Phase B: Final validation (`svelte-check` clean). + +**Do NOT stage or commit until `npx svelte-check` is fully verified.** +The app currently has a high error count due to the transition period where imports are being +re-aligned. Final verification is the next step after the pause. diff --git a/documentation/TODO__Agents.md b/documentation/TODO__Agents.md index 6c36b498..15594ea7 100644 --- a/documentation/TODO__Agents.md +++ b/documentation/TODO__Agents.md @@ -5,6 +5,44 @@ ## 🚧 Upcoming High Priority +### [Stores] Svelte 4 → Svelte 5 State Migration (prerequisite for Phase 2c) +The app uses `svelte-persisted-store` (Svelte 4 store contract) for all core persisted state +(`ae_loc`, `idaa_loc`, `ae_api`, `ae_sess`, etc.). In Svelte 5 `$effect`, reading **any field** +of a Svelte 4 store subscribes to the **entire store** — coarse-grained reactivity. This is the +root cause of the IDAA Novi re-auth bug (2026-03-30): unrelated `$ae_loc` writes (e.g. iframe +height, SWR cfg reload) triggered the Novi verification effect repeatedly. + +Migration target: replace `svelte-persisted-store` with Svelte 5 `$state`-based persistence +(e.g. `runed` `PersistedState`, or a lightweight custom wrapper). This gives fine-grained +reactivity — only effects that actually read a changed field re-run. + +**Phased approach (do NOT do all at once):** + +- [ ] **Phase A — Project plan + wrapper decision:** Write `PROJECT__Stores_Svelte5_Migration.md`. + Decide: `runed` library vs. custom `$state` + localStorage wrapper. Audit all store consumers. + Identify stores in priority order. Estimate blast radius per store. + +- [ ] **Phase B — Core auth stores (highest impact, start here):** + - `ae_loc` (persisted) — auth flags, site cfg, UI state; ~471 consumer sites across 150+ files + - `idaa_loc` (persisted) — Novi auth, IDAA query prefs + These two cause the most reactive noise. Migrating them also unlocks Phase 2c (separate `ae_auth` + store) since the callsite sweep is now required anyway. + +- [ ] **Phase C — Remaining persisted stores:** + - `ae_api` (persisted) — API config / JWT + - `ae_events_stores` persisted entries (badges, launcher, leads, pres_mgmt loc stores) + +- [ ] **Phase D — Non-persisted writable stores:** + - `ae_sess`, `idaa_sess`, `slct`, `slct_trigger`, `ae_auth_error`, `ae_trig`, `ae_snip`, etc. + - Lower urgency (no localStorage churn), but fine-grained reactivity still beneficial. + +- [ ] **Phase E — Phase 2c (unblocked after B):** Split `ae_loc` into `ae_auth` + `ae_app` + (see entry below — ~471 callsites, but sweep is cheap once already touching every consumer). + +**Project plan doc needed:** Yes — scope is app-wide. Do NOT start Phase B without Phase A. + +--- + ### [Stores] Refactor — Phase 2c (deferred) Phases 1, 2a, 2b are complete (see ✅ Completed below). One phase remaining: