Skip to content

CodeMirror stack 3/4: datasette-sql-editor ESM primitives module#2836

Draft
asg017 wants to merge 1 commit into
asg017/codemirror-2-schemafrom
asg017/codemirror-3-primitives
Draft

CodeMirror stack 3/4: datasette-sql-editor ESM primitives module#2836
asg017 wants to merge 1 commit into
asg017/codemirror-2-schemafrom
asg017/codemirror-3-primitives

Conversation

@asg017

@asg017 asg017 commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Part 3 of the CodeMirror stack (integration view: #2833). Pure addition — no behavior change to any page.

What

New ESM module datasette/static/datasette-sql-editor.js (built to an importable datasette-sql-editor.bundle.js), now the single source of truth for Datasette's CodeMirror setup — the IIFE entry cm-editor.js becomes a thin consumer of it.

Exports:

  • SQLiteDialect — the curated dialect (moved here)
  • createSqlEditor(parent, opts){view, updateSchema(conf), destroy(), value} with:
    • Delegable history: history: false builds the basicSetup-equivalent without CM undo and forwards Mod-z / Mod-y / Mod-Shift-z to onHostUndo/onHostRedo — for hosts whose collab/ProseMirror stack owns undo (datasette-paper's headline requirement)
    • hostChange annotation: host-pushed edits don't echo back through onChange
    • onSubmit (Mod-Enter / Shift-Enter, highest precedence), onEscape, fixedTooltips (for overflow-clipped containers), extensions, lineWrapping
  • datasetteSchema(baseUrl, database) — fetches /-/editor-schema.json (part 2) and maps it to a lang-sql SQLNamespace identically to the server-inlined shape
  • Re-exports of the CM modules used (EditorView, EditorState, Compartment, keymap, sql, …) so plugin code shares one CodeMirror instance per page — avoiding the classic duplicate-@codemirror/state breakage

Why this shape

datasette-paper's CodeMirror branch built an entire parallel CM stack with an explicit seam (cmCore.ts) documented as "the seam for a future swap to a Datasette-core-provided CM setup" — this module is that setup. The custom element in part 4 builds on it; hosts needing deep integration (minimal-diff sync, delegated history) use these primitives directly.

Review focus

The createSqlEditor options surface — it's the public API contract for embedders. baseSetup() replicates codemirror's basicSetup extension-for-extension (verified against the package source) minus optional history.

Testing

Both bundles build (npm run build:codemirror); IIFE behavior preserved (Datasette's own pages route through the refactored entry); full suite green. Rollup inlines the shared module into the IIFE so pages still make one script fetch.

The stack

# PR Content
1/4 #2834 CM 6.x upgrade, option-name bugfix, rollup build
2/4 #2835 Rich schema autocomplete, /-/editor-schema.json, defaultTable
3/4 #2836 datasette-sql-editor ESM primitives
4/4 #2837 <datasette-sql-editor> element + core-page dogfood

Each PR is based on the previous branch; merge top-down, retargeting the next base to main as each lands. Bundle files (*.bundle.js) conflict on rebase by nature — resolve by re-running npm run build:codemirror, never by merging. Integration view of the whole branch: #2833.

🤖 Generated with Claude Code

Single source of truth for the CodeMirror setup: SQLiteDialect,
createSqlEditor() (delegable history with host undo/redo forwarding,
hostChange annotation for echo suppression, submit/escape callbacks,
fixed-tooltip mode, per-editor Compartment updateSchema), and
datasetteSchema() which fetches /-/editor-schema.json and maps it to a
lang-sql SQLNamespace identical to the server-inlined shape.
cm-editor.js is now a thin consumer; rollup emits both the IIFE and an
importable ESM bundle. Submit key is Mod-Enter (Cmd on mac as before,
now also Ctrl elsewhere) plus Shift-Enter.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant