mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
Format entire codebase with Prettier (mechanical, no behavior change)
This commit is contained in:
+60
-32
@@ -42,19 +42,19 @@ doc before implementing.
|
||||
|
||||
## Milestone map
|
||||
|
||||
| # | Milestone | Outcome | Spec |
|
||||
|---|-----------|---------|------|
|
||||
| **M0** | Skeleton ✅ | Repo builds, tests run, empty shell renders | — |
|
||||
| **M1** | **MVP core loop** | Author a Vega-Lite snippet, see it render live, it persists | §02, §03A–C, §04, §09A |
|
||||
| # | Milestone | Outcome | Spec |
|
||||
| -------- | --------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------- |
|
||||
| **M0** | Skeleton ✅ | Repo builds, tests run, empty shell renders | — |
|
||||
| **M1** | **MVP core loop** | Author a Vega-Lite snippet, see it render live, it persists | §02, §03A–C, §04, §09A |
|
||||
| **M1.5** | Visual design foundation ✅ | Apply the design language: tokens, IBM Plex, restyled M1 surfaces, chart theme | [arch 09](architecture/09-visual-design.md) |
|
||||
| **M2** | Editor robustness | Draft/Published, validation, schema autocomplete, fit modes | §03D–E, §04, §07(editor) |
|
||||
| **M3** | Datasets | Named reusable data + reference resolution in preview | §05, §03F, §09B |
|
||||
| **M4** | Chart Builder | No-JSON chart composition from a dataset | §06 |
|
||||
| **M5** | Settings + Import/Export | Preferences + workspace backup/transfer | §07, §08, §09C |
|
||||
| **M6** | Shell polish | Resize/toggle panes, routing, shortcuts, toasts, a11y, offline | §01, §10 |
|
||||
| **M2** | Editor robustness | Draft/Published, validation, schema autocomplete, fit modes | §03D–E, §04, §07(editor) |
|
||||
| **M3** | Datasets | Named reusable data + reference resolution in preview | §05, §03F, §09B |
|
||||
| **M4** | Chart Builder | No-JSON chart composition from a dataset | §06 |
|
||||
| **M5** | Settings + Import/Export | Preferences + workspace backup/transfer | §07, §08, §09C |
|
||||
| **M6** | Shell polish | Resize/toggle panes, routing, shortcuts, toasts, a11y, offline | §01, §10 |
|
||||
|
||||
**MVP boundary = end of M1** (a genuinely usable single-user chart authoring loop).
|
||||
M1.5 makes it *look right*; M2 makes it *robust*; M3–M6 make it *complete*.
|
||||
M1.5 makes it _look right_; M2 makes it _robust_; M3–M6 make it _complete_.
|
||||
Ship/dogfood after M1, iterate.
|
||||
|
||||
---
|
||||
@@ -69,13 +69,14 @@ shell, first core module (`format-detection`) with tests.
|
||||
|
||||
---
|
||||
|
||||
## M1 · MVP core loop → *the quickest usable Astrolabe*
|
||||
## M1 · MVP core loop → _the quickest usable Astrolabe_
|
||||
|
||||
**Goal:** select/create a snippet, edit its spec JSON, watch a live Vega-Lite
|
||||
preview, and have it survive reload. Single source kind: inline-data specs only
|
||||
(datasets come in M3). No draft/published yet — edits save directly.
|
||||
|
||||
**Core (`src/core/`)**
|
||||
|
||||
- `snippet.ts` — the Snippet type (spec §09A) + factory (`createSnippet`,
|
||||
default sample bar-chart template, auto-generated date/time name).
|
||||
- `rendering.ts` — `prepareSpecForRender(spec, { fitMode })` skeleton; in M1 it's
|
||||
@@ -83,11 +84,13 @@ preview, and have it survive reload. Single source kind: inline-data specs only
|
||||
Establish the "transform a copy, never mutate stored spec" contract now.
|
||||
|
||||
**Infrastructure (`src/app/infrastructure/`)**
|
||||
|
||||
- `idb.ts` — thin IndexedDB wrapper (open, get/put/delete/getAll by store).
|
||||
*(see [Architecture 02 · Persistence](architecture/02-persistence.md))*
|
||||
_(see [Architecture 02 · Persistence](architecture/02-persistence.md))_
|
||||
- `snippet-store.ts` — persist snippets (object store `snippets`).
|
||||
|
||||
**App**
|
||||
|
||||
- `stores/SnippetStore.ts` — `useSnippetStore` with `snippets`, `activeSnippetId`,
|
||||
selector-derived `activeSnippet`; load-on-startup; create/select/delete/update actions
|
||||
(debounced auto-save of edits, spec §03B). Seed one sample snippet on first run.
|
||||
@@ -100,12 +103,14 @@ preview, and have it survive reload. Single source kind: inline-data specs only
|
||||
- Fill the three panes in `App.tsx` with these.
|
||||
|
||||
**Tests (core-first)**
|
||||
|
||||
- `snippet.test.ts` — factory defaults, sample template validity, unique naming.
|
||||
- `rendering.test.ts` — copy-not-mutate invariant; pass-through shape.
|
||||
- A store test for create/select/delete/auto-save reducer logic (logic extracted
|
||||
from the component so it's testable without DOM).
|
||||
|
||||
**Manual checks**
|
||||
|
||||
- Fresh load seeds a sample snippet that renders a bar chart.
|
||||
- Type in the editor → preview updates after the debounce; bad JSON → editor keeps
|
||||
working, preview shows an error, recovers when fixed.
|
||||
@@ -113,15 +118,16 @@ preview, and have it survive reload. Single source kind: inline-data specs only
|
||||
|
||||
---
|
||||
|
||||
## M1.5 · Visual design foundation ✅ (done) → *make the MVP look like itself*
|
||||
## M1.5 · Visual design foundation ✅ (done) → _make the MVP look like itself_
|
||||
|
||||
**Goal:** apply our design language so the running MVP looks deliberate, and every
|
||||
later milestone builds on settled tokens instead of placeholders. The expensive part
|
||||
(the design decisions) is already done — this milestone is *application*, not
|
||||
(the design decisions) is already done — this milestone is _application_, not
|
||||
invention. See [Architecture 09 · Visual Design Language](architecture/09-visual-design.md)
|
||||
and the companion `visual-specimen.html`.
|
||||
|
||||
**Styles**
|
||||
|
||||
- Port the settled specimen tokens into `styles/tokens.css` (IBM-Plex type scale,
|
||||
8px-based spacing, role-based color, square chrome, motion); light + dark themes
|
||||
via `[data-theme]`.
|
||||
@@ -129,6 +135,7 @@ and the companion `visual-specimen.html`.
|
||||
(offline/PWA — never a CDN).
|
||||
|
||||
**App**
|
||||
|
||||
- Restyle the four M1 surfaces against the tokens: App shell, SnippetLibrary,
|
||||
SpecEditor (Monaco theme follows `[data-theme]`), LivePreview. Tokens only — no
|
||||
raw hexes, no hardcoded hues in components.
|
||||
@@ -141,14 +148,17 @@ and the companion `visual-specimen.html`.
|
||||
so dogfooding dark mode through M2–M4 beat waiting for the Settings modal.
|
||||
|
||||
**Core**
|
||||
|
||||
- Align `src/core/vega-themes.ts`: chart `Config` per theme + a categorical
|
||||
`range.category` palette (clone `carbon-design-system/carbon-charts` for the
|
||||
sequence — see Architecture 09 §7).
|
||||
|
||||
**Tests**
|
||||
|
||||
- Light: the design is mostly visual — a token/theme smoke check, trust the eye.
|
||||
|
||||
**Manual checks**
|
||||
|
||||
- The real app looks deliberate in both themes; theme flip repaints UI + chart.
|
||||
- Keyboard focus ring visible; text/UI contrast passes AA in light and dark.
|
||||
- No placeholder styling remains on the M1 surfaces.
|
||||
@@ -170,6 +180,7 @@ set to Plex Mono explicitly since it can't read the CSS token.
|
||||
assistance, and the fit-mode rendering contract.
|
||||
|
||||
**Core**
|
||||
|
||||
- `rendering.ts` — implement **fit-mode** transform (Original/Width/Height/Full →
|
||||
Vega-Lite `"container"`), recursing into layered/concat/child specs (spec §04
|
||||
Rendering Contract, step 2).
|
||||
@@ -177,6 +188,7 @@ assistance, and the fit-mode rendering contract.
|
||||
validation/autocomplete (mine vega-editor for sourcing/versioning the schema).
|
||||
|
||||
**App**
|
||||
|
||||
- Snippet gains `spec` (published) + `draftSpec` (working) per §09A; editing
|
||||
touches `draftSpec` only.
|
||||
- `SpecEditor` header: Draft/Published toggle; **Publish** (promotes draft, recomputes
|
||||
@@ -187,10 +199,12 @@ assistance, and the fit-mode rendering contract.
|
||||
- Preview **Fit control** (4 modes), persisted (`previewFitMode`).
|
||||
|
||||
**Tests**
|
||||
|
||||
- Fit-mode transforms for each mode incl. nested specs; copy-not-mutate.
|
||||
- Draft/publish/revert reducer logic; "has unpublished changes" derivation.
|
||||
|
||||
**Manual checks**
|
||||
|
||||
- Edit draft, see status flip to "draft"; Publish → status clears; Revert →
|
||||
draft restored with confirmation.
|
||||
- Invalid spec shows inline error; autocomplete suggests Vega-Lite properties.
|
||||
@@ -204,18 +218,21 @@ assistance, and the fit-mode rendering contract.
|
||||
the reference.
|
||||
|
||||
**Core**
|
||||
|
||||
- `profiling.ts` — row/column counts, column names, **per-column type inference**
|
||||
(number/text/date/boolean). *(see [Architecture 06 · Type Inference](architecture/06-type-inference.md))*
|
||||
(number/text/date/boolean). _(see [Architecture 06 · Type Inference](architecture/06-type-inference.md))_
|
||||
- `rendering.ts` — implement **dataset reference resolution** (§04 Rendering
|
||||
Contract, step 1): `{data:{name}}` → inline values / raw text+format / URL+format,
|
||||
recursing into sub-specs; "dataset not found" error.
|
||||
- `dataset.ts` — Dataset type (§09B); name uniqueness helpers; rename-propagation
|
||||
into referencing specs. *(see [Architecture 07 · Naming & Relationships](architecture/07-naming-and-relationships.md))*
|
||||
into referencing specs. _(see [Architecture 07 · Naming & Relationships](architecture/07-naming-and-relationships.md))_
|
||||
|
||||
**Infrastructure**
|
||||
|
||||
- `dataset-store.ts` — separate high-capacity IndexedDB store (§09E).
|
||||
|
||||
**App**
|
||||
|
||||
- `stores/DatasetStore.ts` + Datasets **modal** (list/detail panes, create form,
|
||||
edit, delete, copy-reference) via the modal registry/coordinator.
|
||||
- Snippet `datasetRefs` maintained on publish; library shows dataset icon +
|
||||
@@ -224,11 +241,13 @@ the reference.
|
||||
- URL-sourced datasets fetched at render time.
|
||||
|
||||
**Tests**
|
||||
|
||||
- Reference resolution per source/format incl. nested; not-found error.
|
||||
- Profiling/type inference across mixed columns, nulls, booleans.
|
||||
- Rename propagation; name-uniqueness + import-style auto-suffix.
|
||||
|
||||
**Manual checks**
|
||||
|
||||
- Create a dataset, reference it by name in a snippet → preview renders.
|
||||
- Extract inline data → spec rewritten to a reference, dataset appears, links show both ways.
|
||||
- Delete/rename a referenced dataset behaves per spec.
|
||||
@@ -240,21 +259,25 @@ the reference.
|
||||
**Goal:** no-JSON chart composition from a dataset → a new snippet.
|
||||
|
||||
**Core**
|
||||
|
||||
- `chart-builder.ts` — pure spec assembler: (mark ∈ Bar/Line/Point/Area/Circle) +
|
||||
channels (X/Y/Color/Size) with field types (Quantitative/Nominal/Ordinal/Temporal)
|
||||
+ optional width/height → complete Vega-Lite spec with tooltips + named data ref
|
||||
(§06 Output). Field-type defaults from inferred column type.
|
||||
- optional width/height → complete Vega-Lite spec with tooltips + named data ref
|
||||
(§06 Output). Field-type defaults from inferred column type.
|
||||
|
||||
**App**
|
||||
|
||||
- Chart Builder **modal** (config pane + live preview pane), launched from a
|
||||
selected dataset; default pre-population (first col→X, second→Y); validation
|
||||
(≥1 channel); Create Snippet → new linked snippet becomes active.
|
||||
|
||||
**Tests**
|
||||
|
||||
- Spec assembly: mark/channel/type permutations, unmapped channels omitted,
|
||||
width/height inclusion, field-type derivation, validation gate.
|
||||
|
||||
**Manual checks**
|
||||
|
||||
- Build a bar chart from a dataset in a few clicks; preview live-updates;
|
||||
Create → new snippet opens and renders.
|
||||
|
||||
@@ -265,6 +288,7 @@ the reference.
|
||||
**Goal:** preferences and whole-workspace backup/transfer.
|
||||
|
||||
**Core**
|
||||
|
||||
- `settings.ts` — UserSettings shape + defaults + load-with-fallback (§07, §09C);
|
||||
unknown/missing values fall back silently.
|
||||
- `import-normalize.ts` — accept envelope / bare array / single snippet / foreign
|
||||
@@ -274,11 +298,13 @@ the reference.
|
||||
- `export-envelope.ts` — build the `{version, exportedAt, exportedBy, snippets, datasets}` envelope.
|
||||
|
||||
**Infrastructure**
|
||||
|
||||
- `settings-store.ts` (localStorage): **extend** the minimal M1.5 adapter (which
|
||||
already persists `ui.theme`) to the full UserSettings record; `ux-prefs` for sort
|
||||
+ panel layout (§09D).
|
||||
- panel layout (§09D).
|
||||
|
||||
**App**
|
||||
|
||||
- Settings **modal** (Appearance/Editor/Performance/Formatting), Apply/Cancel/Reset,
|
||||
dirty indicator; wire render-debounce + theme + date-format through to the app.
|
||||
Theme already switches (M1.5 header toggle + chart/editor themes) — M5 surfaces
|
||||
@@ -287,11 +313,13 @@ the reference.
|
||||
- Date formatting util (smart/iso/custom) used by the library list.
|
||||
|
||||
**Tests**
|
||||
|
||||
- Import normalization across all accepted shapes; merge/collision/rename logic;
|
||||
quota-overage messaging path. Envelope round-trip (export→import idempotence).
|
||||
- Settings load-with-fallback for partial/unknown records.
|
||||
|
||||
**Manual checks**
|
||||
|
||||
- Change theme/debounce/date-format → takes effect; Cancel reverts; Reset confirms.
|
||||
- Export → reimport into a populated workspace merges without overwrite; renames reported.
|
||||
|
||||
@@ -304,9 +332,9 @@ the reference.
|
||||
- **Panes:** drag-resize handles with min widths; per-pane show/hide toggle strip;
|
||||
widths + visibility persist (§01A, §09D).
|
||||
- **Routing:** URL hash view-state (`#snippet-<id>`, `#datasets/...`) with Back/Forward;
|
||||
restore on load (§01E). *(see [Architecture 04 · Routing & Events](architecture/04-routing-and-events.md))*
|
||||
restore on load (§01E). _(see [Architecture 04 · Routing & Events](architecture/04-routing-and-events.md))_
|
||||
- **Shortcuts:** Cmd/Ctrl+Shift+N / +K / +S / +, / Esc via a single key router
|
||||
(§01D). *(see [Architecture 04 · Routing & Events](architecture/04-routing-and-events.md))*
|
||||
(§01D). _(see [Architecture 04 · Routing & Events](architecture/04-routing-and-events.md))_
|
||||
- **Toasts:** success/error/warning/info, stacking, auto-dismiss, reduced-motion (§01F).
|
||||
- **Storage monitor** for the snippet tier (§02).
|
||||
- **A11y:** modal focus trap + return, labelled icon buttons, contrast in both themes (§10).
|
||||
@@ -339,14 +367,14 @@ offline reload works; install as standalone; reduced-motion honored.
|
||||
The **how** behind each milestone is documented self-containedly in
|
||||
[`docs/architecture/`](architecture/00-overview.md) — no external repo needed:
|
||||
|
||||
| Need | Doc |
|
||||
|------|-----|
|
||||
| Zustand stores, selector derivations, debounced auto-save | [01 · State & Stores](architecture/01-state-and-stores.md) |
|
||||
| IndexedDB wrapper, lazy loading, migrations, localStorage prefs, storage tiers | [02 · Persistence](architecture/02-persistence.md) |
|
||||
| Modal registry + coordinator + shell, unsaved-change detection, focus trap | [03 · Modal System](architecture/03-modal-system.md) |
|
||||
| URL hash view-state, keyboard routing, interactive-context detection | [04 · Routing & Events](architecture/04-routing-and-events.md) |
|
||||
| vega-embed integration, theming, debounced preview, error display | [05 · Rendering, Theming & Preview](architecture/05-rendering-theming-preview.md) |
|
||||
| Column type inference + dataset profiling | [06 · Type Inference & Profiling](architecture/06-type-inference.md) |
|
||||
| Unique names + import auto-suffix, snippet↔dataset links, rename propagation | [07 · Naming & Relationships](architecture/07-naming-and-relationships.md) |
|
||||
| Monaco setup, Vega-Lite schema service, editor patterns mined from vega/editor | [08 · Vega Editor Techniques](architecture/08-vega-editor-techniques.md) |
|
||||
| Design language: tokens, type, spacing, color roles, components, themes | [09 · Visual Design Language](architecture/09-visual-design.md) |
|
||||
| Need | Doc |
|
||||
| ------------------------------------------------------------------------------ | --------------------------------------------------------------------------------- |
|
||||
| Zustand stores, selector derivations, debounced auto-save | [01 · State & Stores](architecture/01-state-and-stores.md) |
|
||||
| IndexedDB wrapper, lazy loading, migrations, localStorage prefs, storage tiers | [02 · Persistence](architecture/02-persistence.md) |
|
||||
| Modal registry + coordinator + shell, unsaved-change detection, focus trap | [03 · Modal System](architecture/03-modal-system.md) |
|
||||
| URL hash view-state, keyboard routing, interactive-context detection | [04 · Routing & Events](architecture/04-routing-and-events.md) |
|
||||
| vega-embed integration, theming, debounced preview, error display | [05 · Rendering, Theming & Preview](architecture/05-rendering-theming-preview.md) |
|
||||
| Column type inference + dataset profiling | [06 · Type Inference & Profiling](architecture/06-type-inference.md) |
|
||||
| Unique names + import auto-suffix, snippet↔dataset links, rename propagation | [07 · Naming & Relationships](architecture/07-naming-and-relationships.md) |
|
||||
| Monaco setup, Vega-Lite schema service, editor patterns mined from vega/editor | [08 · Vega Editor Techniques](architecture/08-vega-editor-techniques.md) |
|
||||
| Design language: tokens, type, spacing, color roles, components, themes | [09 · Visual Design Language](architecture/09-visual-design.md) |
|
||||
|
||||
Reference in New Issue
Block a user