mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
Implement M1 authoring loop: library, editor, live preview, persistence
M1 MVP from docs/IMPLEMENTATION-PLAN.md, with the /alignment pass applied. - core: Snippet model + factory; prepareSpecForRender (copy-not-mutate); per-theme Vega chart config - state/orchestration: SnippetStore with debounced auto-save; IndexedDB adapter + read-time migration; startup hydration + write-through persistence - ui: SnippetLibrary, SpecEditor (Monaco edcore.main — full editor features, JSON-only languages), LivePreview - build: Monaco/Vega manual chunks; raised PWA precache ceiling - alignment: flush a valid draft on snippet switch (+regression tests); TODO breadcrumbs for the preview render race and the window.confirm delete - housekeeping: gitignore .claude/projects/
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
- [vega-editor reference clone](vega-editor-reference-clone.md) — local vega/editor at /Users/oleh/code/reference/vega-editor for Monaco/render/validation techniques
|
||||
- [Stack: React + Zustand](stack-moving-to-react.md) — final UI stack is React + Zustand (migrated off Preact + signals at M0); doc sweep done
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
name: stack-moving-to-react
|
||||
description: Astrolabe's UI stack is React + Zustand (migrated from Preact + signals at M0)
|
||||
metadata:
|
||||
type: project
|
||||
---
|
||||
|
||||
The UI stack is **React + Zustand** (user decision, 2026-06-03, executed at M0 before feature
|
||||
work). It started as Preact + `@preact/signals`; a brief intermediate step migrated to React +
|
||||
`@preact/signals-react`, but the final call is **React + Zustand** — signals were dropped.
|
||||
|
||||
**Why React:** the Preact pain was React-ecosystem friction (real-React-only libraries not
|
||||
cooperating with `preact/compat`) — *not* the signals model. Real React removes that whole
|
||||
class of problem and makes borrowing from the reference [[vega-editor-reference-clone]] (a
|
||||
React app) port directly.
|
||||
|
||||
**Why Zustand over keeping signals:** signals were never the problem, but switching framework
|
||||
was the one cheap moment (M0, ~nothing implemented) to also pick the lowest-future-migration-risk
|
||||
state lib. Zustand is idiomatic React, has first-class outside-React access
|
||||
(`getState`/`setState`/`subscribe`) that fits the "logic lives in core/services, not components"
|
||||
architecture, and carries no build-time transform. The signals→Zustand cost was only rewriting
|
||||
unimplemented docs.
|
||||
|
||||
**How to apply:** Stores are `create<State>()` modules exporting a `useXStore` hook (state +
|
||||
actions in one object); components read via `useXStore(selector)` (+ `useShallow` for object
|
||||
selections); non-component code uses `getState()/setState()/subscribe()`; derive in selectors,
|
||||
never store derived fields. See `docs/architecture/01-state-and-stores.md`. The repo-wide
|
||||
Preact/signals→React/Zustand doc sweep is **done** — no stale "Preact"/"signals" wording should
|
||||
remain except where it describes the sibling project Syto, Vega's own signals, or plain English.
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
name: vega-editor-reference-clone
|
||||
description: Location and nature of the local vega/editor clone used as a technique reference for Astrolabe's Monaco/vega-embed/validation work
|
||||
metadata:
|
||||
type: reference
|
||||
---
|
||||
|
||||
The canonical Vega-Lite editor (vega/editor) is cloned locally at
|
||||
`/Users/oleh/code/reference/vega-editor` (shallow clone of `main`, HEAD 4fdbb59). It is the
|
||||
reference for the "editor + renderer" wiring Astrolabe's M1/M2 call out ("mine vega-editor
|
||||
for how it wires the schema"). Re-clone with `git clone --depth 1 https://github.com/vega/editor`.
|
||||
|
||||
Key divergences to remember when borrowing — it is **React + Redux/context**, uses
|
||||
`@monaco-editor/react` + `@monaco-editor/loader` (CDN-loaded Monaco, no explicit worker
|
||||
config), and — surprisingly — **does NOT use vega-embed for its live preview** (it hand-rolls
|
||||
`vegaLite.compile` → `vega.parse` → `new vega.View().runAsync()`; vega-embed is imported only
|
||||
for types + the exported standalone HTML). Astrolabe is React (see [[stack-moving-to-react]]) +
|
||||
Zustand stores + raw `monaco-editor` + `vegaEmbed()`. Since both are now React, vega/editor's
|
||||
component lifecycle patterns port fairly directly; the friction is state (their flat Redux →
|
||||
our Zustand stores) and Monaco worker wiring (their CDN loader → our explicit Vite workers).
|
||||
The Monaco choice (self-hosted from npm + raw API, not the CDN loader / `@monaco-editor/react`
|
||||
route) is a recorded decision — see `docs/architecture/08` § Decision · Monaco integration.
|
||||
|
||||
The highest-value files: `src/utils/monaco.ts` (schema wiring), `src/utils/validate.ts` (ajv),
|
||||
`src/utils/jsonc-parser.ts`, `src/utils/logger.ts` (LocalLogger), `src/components/renderer/renderer.tsx`
|
||||
(View lifecycle), `src/components/app.tsx:188-365` (parse→validate→compile→render flow),
|
||||
`src/constants/default-state.ts` (state shape). Relevant to [[]] M1/M2 of the implementation plan.
|
||||
Reference in New Issue
Block a user