Modernize eXide: CM6 editor, REx parser, Roaster API, LSP integration#794
Open
joewiz wants to merge 22 commits into
Open
Modernize eXide: CM6 editor, REx parser, Roaster API, LSP integration#794joewiz wants to merge 22 commits into
joewiz wants to merge 22 commits into
Conversation
19 tasks
Replace eXide's bundled xqlint parser with a REx-generated parser built from the W3C XQuery 3.1 + Update 3.0 + Full Text 1.0 EBNF grammar. Includes adapter layer, static analysis, and comprehensive tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Migrate from Ace to CM6 with full language support, syntax highlighting, autocompletion, and keybinding infrastructure. Includes editor-utils shim layer and CM6 bundling script. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bundle Prettier with plugins via esbuild. Replaces xqlint CodeFormatter with multi-language formatting support. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace jQuery AJAX with fetch, jQuery UI dialogs with native <dialog> via dialog-utils.js, and AG Grid with vanilla HTML tables. Remove all jQuery/AG Grid CSS themes and scripts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace 15+ legacy XQuery modules with a Roaster-based OpenAPI REST API. Endpoints for storage, query execution, packages, authentication, templates, search, admin, sync, and editor operations. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comprehensive UI overhaul including redesigned toolbar, status bar with mode selector, native dialog system, tab overflow controls, filterable outline panel, dark mode with system theme detection, keyboard shortcuts dialog, and responsive layout improvements. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CM6 autocompletion with LSP-aware function completions, semantic highlighting via CM6 decorations, hover tooltips, function documentation, and language helpers for JSON, Less, Markdown, JavaScript, CSS, and XML. Remove dead Ace-era code (ace-modes.js, popup.js, splitter.js). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cypress E2E tests for autocomplete, diagnostics, outline, query execution, preferences, formatting, and more. Remaining frontend updates: layout, find/replace, menus, directory browser, drag-and-drop, history, and monitoring panel. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Editor features: - Matching tag highlight for XML/HTML (open/close tag partner) - XML/HTML scope breadcrumb in status bar (XPath at cursor) - XML Rename Element with multi-cursor (both tags updated) - XPath signatures with positional predicates in outline - Navigation flash on all jump-to actions (gotoLine, gotoSymbol, gotoDefinition, outline click, rename element) - Selection match highlighting, Cmd+D multi-select - Diagnostics panel (Cmd+Shift+D), autocomplete-on-type preference - Dynamic namespace registry from server, local hover fallback - Deferred splash screen, bracket matching restyled blue - Dialog focus on primary action button instead of close × - Enable multiple selections for multi-cursor operations - Unprefixed default namespace completion (conc → fn:concat) - Preserve namespace prefix on completion acceptance - Fix duplicate outline entries for self-closing XML elements - Fix JS gotoSymbol when outline not yet populated exist-next compatibility: - controller.xq, auth.xqm: xs:dayTimeDuration cast - admin.xqm: dynamic file module detection via util:eval - sync.xqm: dynamic file:sync() via util:eval - packages.xqm: fix collection-to-package resolution - query.xqm: make lsp:* import optional - compileError: parse line/column from message when lsp returns line 0 CI: - Skip autocomplete/outline tests when lsp:* unavailable - Move LSP-dependent Cypress tests to lsp/ subdirectory - Add 4 Cypress tests for prefix/unprefixed completion scenarios Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
POST /api/query/references with {query, line, column, base} returns
all references to the symbol at position. Uses dynamic function-lookup
for lsp:references (gracefully returns empty when unavailable).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Client-side WebSocket transport (src/ws-transport.js) providing: - Persistent bidirectional connection to eXist-db - JSON-RPC message framing (compatible with LSP protocol) - Request/response with callbacks for hover, completions, etc. - Server-push notifications for diagnostics, monitoring events - Auto-reconnect with exponential backoff - Auto-connect deriving WebSocket URL from page location - Graceful fallback when WebSocket unavailable API: eXide.ws.connect(), .send(), .notify(), .on(), .off() Designed for use with eXist-db's WebSocket support (PR #6145). Phase 1 target: real-time monitoring (replace HTTP polling). Phase 2: LSP over WebSocket (push diagnostics, incremental edits). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ncoding Autocomplete was doubling namespace prefixes (e.g. repo:repo:deploy) when the user typed a prefixed name like "repo:" — the nsPart logic now checks whether the server result already includes the prefix before prepending it. Storage API calls in eXide.js and directory.js used encodeURIComponent on full paths, encoding slashes as %2F and causing 400 errors. Fixed by using the existing apiPath() helper that encodes each segment individually. Also replaced fixed cy.wait() sleeps in monitor and websocket specs with assertion-based retries, cutting suite time by ~2 minutes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…omplete_spec cy.wait(300/200/500) was used as a proxy for "completions API response arrived". Now each test that accepts a completion intercepts POST /api/query/completions and waits on the named alias, making timing deterministic rather than guessed. Also converts leftover var → const in the filter test. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ground Generated from the x.svg in dashboard/resources/images at 16x16, 32x32, and 48x48. Added favicon link to src-tauri/connect.html (the only page template that was missing it). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…al/fetch
Replaces the old XQueryServlet + session.xq flow and the WebSocket streaming
approach with a cursor-based architecture using the new lsp:eval/lsp:fetch/
lsp:close functions from the exist-lsp package.
How it works:
- POST /api/query calls lsp:eval() → stores result sequence in Caffeine cache,
returns cursor ID + item count + elapsed time
- GET /api/query/{id}/results?start=N&count=M calls lsp:fetch() → serializes
only the requested page, includes documentURI and nodeId per item
- DELETE /api/query/{id} calls lsp:close() → releases the cursor
- Cursors auto-expire after 5 minutes of inactivity
This restores the key qualities of the old flow:
- Lazy serialization (only viewed page is serialized)
- No client-side buffering (results stay on server)
- Pagination (identical UX with next/previous/first/last)
- Document links (documentURI field for clickable result badges)
Also adds:
- Cancel button in toolbar (visible during execution)
- Timing display bar below results navbar
- WebSocket eval transport (ws-eval.js) for future progress/cancel support
- exist-lsp package dependency in expath-pkg.xml
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously, "Copy all displayed results to clipboard" concatenated items without any separator. Now each item is joined with a newline, making the pasted output readable when the query returns multiple items. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The Indent and Highlight Matches buttons previously used identical colors for both hover and active states. Active buttons now show a solid blue background with white text (dark mode: semi-opaque blue), making it clear at a glance whether the option is on or off. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously, clicking an already-open menu header would close it and immediately re-open it. Now clicking an open menu header closes it, consistent with standard menubar behaviour. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ry library modules Quick fix system: - Update quickfix regexes to match new static analysis error formats (XPST0081 for namespace prefixes, XPST0008 for undeclared variables) - Add Quick Fix to XQuery menu and command palette - Change keybinding from Cmd+Ctrl+Q (conflicts with macOS Lock Screen) to Ctrl+. - Import action resolves namespace URI from cached module registry instantly - Filter out java: class references from import location hints - Add CM6 diagnostic actions so "Import module" appears in error tooltips - Style diagnostic actions as block-level links below the error message - Auto-refresh module cache on cache miss; expose app.refreshModuleCache() Completions for XQuery library modules: - Supplement lsp:completions() with inspect:inspect-module-uri() for modules like kwic, templating that are bundled as .xql files in the uber jar - Build proper function signatures with XQuery cardinality symbols (?, *, +) - Filter out stub entries from inspect XML Hover documentation: - Enhance hover fallback to fetch full function docs from api/editor/completions for prefixed function calls when lsp:hover() returns nothing Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
d05848c to
942f8f2
Compare
eXide 4.0 declares a dependency on the exist-api package (which provides the lsp:* functions). Fetch it from the joewiz/exist-api pre-release in the same manner as roaster, so the eXist Docker container can deploy eXide on startup. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
a352168 to
1e427a3
Compare
9e2862d to
4e11813
Compare
Coordinated update for the breaking rename in eXist-db/existdb-openapi#18 (formerly eXist-db/exist-api). All four known consumers (eXide, monex, existdb-langserver, notebook) move together — no backward-compat aliases. XQuery namespace switches in modules/api/query.xqm: - import lsp: -> import lang: (language services) and cursor: (server-side cursor) - lsp:diagnostics/completions/hover/definition/references/symbols -> lang:* - lsp:eval/fetch/close -> cursor:* - function-lookup QName URI updated to .../xquery/cursor URL/XAR coordinate updates: - ../exist-api/api/* -> ../existdb-openapi/api/* in src/eXide.js - CI: download from joewiz/existdb-openapi, pattern existdb-openapi-*.xar - Note: CI is pinned to v0.9.0-pre.2 — a new pre-release tag will be cut from existdb-openapi after PR #18 lands. CI stays red until then. File renames for naming hygiene: - src/lsp-hover.js -> src/lang-hover.js - resources/css/lsp-hover.css -> resources/css/lang-hover.css - CSS classes cm-lsp-hover* -> cm-lang-hover* - Updated import in scripts/bundle.js and link in index.html Comments/docs updated. References to "LSP" as a protocol (e.g., "LSP-aware completions", "LSP protocol messages") are preserved since they describe interop-with-LSP semantics, not the renamed namespace. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4e11813 to
a323000
Compare
…-clean # Conflicts: # modules/outline.xq # src/util.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Modernizes the eXide web application, replacing core dependencies and adding language-service-powered intelligence, real-time monitoring, and a REST API. This PR contains only the web-app modernization — the eXide Desktop (Tauri) work that was part of #778 is deferred to a follow-on PR per @line-o's request.
Reviewers familiar with eXide pre-modernization and the goals discussed in #778 should find this PR much easier to follow: 19 topical commits instead of 56, no desktop scope, end-state dependencies (
existdb-openapi,roaster) assumed final.Highlights
<dialog>viadialog-utils.js.textDocument/publishDiagnostics); see alsoexistdb-openapifor the underlying language-service endpoints.cursor:eval/cursor:fetch, with AbortController cancel, update-query warning, and adaptive serialization.Dependencies
develop(eXist 7.0+) with Upgrade Jetty 11→12 (EE10, Jakarta Servlet 6.0) and add WebSocket module with streaming query evaluation exist#6145 (Jetty 12 / WebSocket support, merged). CI runs againstexistdb/existdb:latest; the eXist-db release-version matrix entry is dropped because eXide 4.0 requires the 7.0lang:*/cursor:*modules from existdb-openapi, which are only available against develop.existdb-openapi(formerlyexist-api) — provides thelang:*(language services: diagnostics, completions, hover, definition, references, symbols) andcursor:*(server-side cursor: eval, fetch, close) functions consumed by eXide. Replaces the standaloneexist-lsppackage. CI downloads the release XAR like roaster.roaster≥ 1.8.0 — Roaster REST API framework.Test plan
npm test— Node unit tests (179 tests) ✅ verified in latest CI run (# tests 179 # pass 179 # fail 0)npm run buildproducesbuild/eXide-4.0.0.xar✅ verified in latest CI run (Creating xar eXide-4.0.0.xar)existdb-openapi+roaster; eXide loads at/exist/apps/eXide/npx cypress run— full E2E suiteSupersedes #778.