Files
astrolabe/docs/architecture/00-overview.md
T

3.9 KiB

Astrolabe — Architecture Playbook

These documents capture the architectural patterns Astrolabe is built on. They are self-contained: everything needed to implement a pattern lives here, in Astrolabe's own domain terms (snippets, datasets, settings, Vega-Lite specs). You do not need any other repository to work from them.

They are the architectural counterpart to docs/spec/: the spec says what the app does (behavior, acceptance points); this playbook says how we build it (state, persistence, modals, routing, rendering, inference, relationships).

How to use this playbook

  • Building a feature? Read the relevant spec section first (the what), then the matching playbook doc (the how), then implement core-first per ../IMPLEMENTATION-PLAN.md.
  • Each doc states the pattern, the rationale (what problem it solves, what it prevents), TypeScript sketches in Astrolabe terms, and Do/Don't rules.
  • The sketches are illustrative, not finished code. Adapt them; keep the principles.

The documents

# Doc Covers
01 State & Stores Zustand stores; one source of truth; selector derivations; central useAppStore vs per-feature stores; testable action functions; debounced auto-save.
02 Persistence The infrastructure-adapter boundary; promise-wrapped IndexedDB wrapper; lazy data loading; per-record schema versioning + migration; localStorage prefs with fallback; storage tiers + quota monitoring.
03 Modal System Registry + coordinator + shell; one modal at a time; unsaved-change detection via snapshot; focus trap; backdrop/Escape/close dismissal.
04 Routing & Events URL hash as view-state (restore/sync, Back/Forward); global keyboard routing; Escape priority chain; the single-source isInInteractiveContext() helper (Monaco-aware).
05 Rendering, Theming & Preview vega-embed integration (actions:false, view.finalize()); field-name escaping; theme→config mapping; debounced non-blocking renderer; resilient error display.
06 Type Inference & Profiling Pure, portable column-type inference (number/text/date/boolean) and the dataset profile shape.
07 Naming & Relationships Unique-name enforcement + import auto-suffix; the bidirectional snippet↔dataset name link; rename propagation into specs.
08 vega/editor Techniques Reference brief: borrowable Monaco-schema wiring, vega-embed lifecycle, two-tier validation, and data-flow/debounce techniques distilled from the official Vega-Lite editor — plus where we do better.

The non-negotiable layering (every doc assumes this)

  • src/core/ — portable, pure logic. No browser APIs, no React, no Monaco. Spec operations live here and are unit-tested hardest. (Docs 06, 07, parts of 05 land here.)
  • src/app/stores/ — Zustand stores. (Doc 01.)
  • src/app/infrastructure/ — the only place that touches indexedDB, localStorage, or window.location. Everything else goes through these typed adapters. (Docs 02, 04.)
  • src/app/services/ & orchestration/ — coordination that composes stores + infrastructure + core (lifecycle, routing sync, dependency upkeep). (Docs 03, 04, 07.)
  • src/app/components/ — React + CSS Modules. Thin; pushes logic down into stores/core so it stays testable. (Docs 03, 05.)

Why a playbook at all

Patterns written down once, in one place, stop two classes of problem: drift (the same decision re-litigated inconsistently across features) and rediscovery (re-deriving why something is the way it is). When a pattern here proves wrong, change the doc — don't fork the convention silently. This is the same discipline docs/spec/ applies to behavior.