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:
@@ -14,6 +14,14 @@ not components" architecture, and it carries no build-time magic. The principles
|
||||
(one source of truth, derive-don't-duplicate, actions outside components, thin components)
|
||||
are the durable part — they would survive a change of library.
|
||||
|
||||
**Lineage (why React + Zustand).** The UI began on Preact + `@preact/signals` and migrated to
|
||||
**React + Zustand** at M0, before feature work. The driver was *React-ecosystem friction* —
|
||||
real-React-only libraries not cooperating with `preact/compat` — **not** the signals model.
|
||||
Switching framework while nothing was implemented yet was also the one cheap moment to pick
|
||||
the lowest-migration-risk state library, so signals gave way to Zustand. A bonus: borrowing
|
||||
from the React-based vega/editor reference (see [08](08-vega-editor-techniques.md)) then ports
|
||||
directly rather than through `preact/compat`.
|
||||
|
||||
---
|
||||
|
||||
## 1. The Primitives
|
||||
|
||||
@@ -73,6 +73,29 @@ self-hosting.
|
||||
**Accepted cost:** the explicit worker wiring (§1) is inherent to self-hosting — it is the
|
||||
price of offline, paid in any non-CDN setup, and the wrapper would not remove it.
|
||||
|
||||
### Entry point: `edcore.main`, never `editor.api` (trim languages, not features)
|
||||
|
||||
Self-hosting raw Monaco forces a choice of ESM entry point, and the granularity matters:
|
||||
|
||||
| Import | What you get | Use? |
|
||||
|---|---|---|
|
||||
| `monaco-editor` (barrel) | All features **+ every basic language** (sql, abap, solidity, …) | ❌ language bloat (~20 dead chunks) |
|
||||
| `esm/vs/editor/editor.api` | The API surface only — **zero feature contributions** | ❌ a text box: no folding, suggest widget, `Cmd+Backspace`, find, bracket colorization |
|
||||
| `esm/vs/editor/edcore.main` | `editor.all` (all 59 feature contributions) + API, **no languages** | ✅ full editor UX, JSON-only weight |
|
||||
|
||||
Import **`edcore.main`** and add only the JSON language service
|
||||
(`esm/vs/language/json/monaco.contribution`). `edcore.main` ships no `.d.ts` of its own —
|
||||
add an ambient `declare module … { export * from '…/editor.api'; }` so types (and Monaco's
|
||||
global `MonacoEnvironment` augmentation) resolve. Two editor options worth setting because
|
||||
they bite Vega-Lite specs specifically: `showFoldingControls: 'always'` (fold arrows always
|
||||
visible), and `quickSuggestions: { strings: true }` (VL enum values like `"bar"` live inside
|
||||
JSON strings, where Monaco disables auto-suggest by default).
|
||||
|
||||
> Reaching for `editor.api` to "drop unused languages" silently strips every editor feature —
|
||||
> the languages live elsewhere. This is the concrete case behind AGENTS.md's **"trim content,
|
||||
> not capability"** rule: cut the unwanted _content_, keep the _behavior_, and verify the
|
||||
> behavior survived by exercising the editor, not by a green build.
|
||||
|
||||
---
|
||||
|
||||
> **The single biggest surprise:** vega/editor does **not** use `vega-embed` for its live
|
||||
|
||||
Reference in New Issue
Block a user