Skip to content

feat(lsp): add web worker language servers as defaults#2531

Open
bajrangCoder wants to merge 10 commits into
mainfrom
worker-lsp-defaults
Open

feat(lsp): add web worker language servers as defaults#2531
bajrangCoder wants to merge 10 commits into
mainfrom
worker-lsp-defaults

Conversation

@bajrangCoder

Copy link
Copy Markdown
Member

Summary

Add bundled Web Worker-based language servers as the default LSP experience for users.

HTML, CSS, JSON, JavaScript, and TypeScript now work without requiring Alpine, STDIO processes, manual installation, WebSocket URLs, or launcher bridges. Existing STDIO servers remain available as optional alternatives for advanced users who wants full workspace level stdio based lsp.

Changes

  • Add a built-in Web Worker LSP runtime
  • Enable Web Worker servers by default for:
    • HTML
    • CSS, SCSS, and Less
    • JSON and JSONC
    • JavaScript, JSX, TypeScript, and TSX
  • Keep equivalent STDIO servers available but disabled by default
  • Support arbitrary document URIs, including Android SAF and content:// locations
  • Add HTML embedded-language support for CSS and JavaScript/TypeScript
  • Add JSON schema discovery and configuration support
  • Add TypeScript library loading and nested file resolution
  • Preserve Markdown formatting in TypeScript completion and signature-help documentation
  • Correctly dispose workers when:
    • A server is disabled
    • The last associated editor is closed
    • A custom server is removed
  • Avoid starting workers when their LSP servers are disabled

@bajrangCoder
bajrangCoder marked this pull request as ready for review July 23, 2026 16:29
@greptile-apps

greptile-apps Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR introduces built-in Web Worker-based LSP servers for HTML, CSS/SCSS/Less, JSON/JSONC, and TypeScript/JavaScript, so those languages work out of the box without Alpine, STDIO processes, or WebSocket bridges. The STDIO equivalents are kept but disabled by default for advanced users. Significant infrastructure work accompanies the feature: a generic createWorkerTransport factory, disposeServer on LspClientManager, proper AbortController-based cancellation for in-flight initialization, and a multi-layer embedded-language pipeline in the HTML worker (CSS, import-map JSON, and TypeScript via a nested sub-worker).

  • New files: workerTransport.ts, runtimes/webWorker.ts, and four language workers (html, css, json, typescript) plus supporting modules (protocol, nestedLspClient, htmlEmbeddedSupport, typescriptLibs, jsonSchemas).
  • ClientManager changes: disposeServer() now correctly aborts pending initializations via AbortController before terminating workers; the onClientIdle callback in editorManager.js now disposes only the single idle client rather than the whole server.
  • Settings page: lspServerDetail.js calls disposeServer before stopManagedServer when a server is disabled or removed, preventing orphaned workers.

Confidence Score: 5/5

Safe to merge. The new web-worker runtime is a significant addition but the previous blocking issues (pending-client disposal race, post-crash worker leaks, factory rejection leaving the worker alive, codeAction crash with undefined formatting options) are all addressed in this PR. The remaining findings are minor behavioral quirks.

The infrastructure changes are well-structured: AbortController cancellation for in-flight initialization, failTransport/fail() for post-ready crash propagation, workerScope.close() on factory rejection, and idempotent dispose() with a disposed guard. The three findings are non-blocking: inlay hints in HTML use a position-based language check that suppresses results for range-based requests starting before a script tag; completionItem/resolve in the JSON worker ignores the JSONC service; and WEB_WORKER_RUNTIME_ID is duplicated across two modules.

Files Needing Attention: src/cm/lsp/workers/html.worker.ts (inlay-hint language check) and src/cm/lsp/workers/json.worker.ts (completionItem/resolve service dispatch).

Important Files Changed

Filename Overview
src/cm/lsp/workerTransport.ts New generic transport factory; correctly handles startup timeout, post-ready crashes via failTransport (sets disposed=true, clears listeners, terminates worker), and host-request dispatch.
src/cm/lsp/workers/protocol.ts Worker-side JSON-RPC runtime; factory rejection now calls workerScope.close() before sending the error message, so the host detects failure immediately rather than waiting for the startup timeout.
src/cm/lsp/workers/nestedLspClient.ts HTML-embedded TypeScript sub-worker client; post-ready crashes are now handled via fail() which rejects all pending requests and sets closedError to block new ones.
src/cm/lsp/workers/html.worker.ts HTML LSP worker with embedded CSS/import-map JSON/JS support; inlayHintProvider capability is advertised but inlay hints silently return [] when the requested range starts outside a JS region.
src/cm/lsp/workers/typescript.worker.ts Full in-browser TypeScript/JavaScript language service; formatSettings now accepts undefined/null options with safe defaults, fixing the previous codeAction crash.
src/cm/lsp/workers/json.worker.ts JSON/JSONC language worker; completionItem/resolve always delegates to services.json regardless of the document language ID, so JSONC completion details use the non-comment-aware service.
src/cm/lsp/clientManager.ts New disposeServer() correctly aborts pending initializations via AbortController; dispose() also flushes pending clients; race between pending resolution and abort is handled by waitForInitialization().
src/cm/lsp/runtimes/webWorker.ts New web-worker runtime provider; duplicates WEB_WORKER_RUNTIME_ID string constant already exported from runtimeProviders.ts, creating a divergence risk.
src/cm/lsp/workers/css.worker.ts CSS/SCSS/Less language worker with per-document stylesheet caching; correctly delegates to language-specific services.
src/lib/editorManager.js onClientIdle now disposes only the single idle client instance and calls stopManagedServer only when no other clients for that server ID remain active.
src/settings/lspServerDetail.js disposeServer is now called before stopManagedServer when a server is disabled or a custom server is removed, ensuring web-worker clients are cleaned up.

Sequence Diagram

sequenceDiagram
    participant Editor as Editor (CodeMirror)
    participant CM as LspClientManager
    participant WR as WebWorker Runtime
    participant WT as WorkerTransport
    participant W as LSP Worker (e.g. html.worker)
    participant NW as Nested TS Worker

    Editor->>CM: open document (html/css/json/ts)
    CM->>WR: selectRuntimeProvider(server)
    WR->>WT: "createWorkerTransport({url, configure, hostHandlers})"
    WT->>W: new Worker(url)
    WT->>W: "postMessage({kind:configure, serverId, rootUri})"
    W-->>WT: "postMessage({kind:ready})"
    WT-->>CM: ready resolved
    CM->>W: initialize (JSON-RPC)
    W-->>CM: capabilities
    Note over W,NW: HTML worker lazily spawns nested TS sub-worker
    Editor->>CM: textDocument/completion
    CM->>W: JSON-RPC request
    W->>NW: (if JS region) forward request
    NW-->>W: result
    W-->>CM: JSON-RPC response
    CM-->>Editor: completion items
    Editor->>CM: close last document for server
    CM->>CM: onClientIdle - dispose()
    CM->>WT: dispose()
    WT->>W: worker.terminate()
    Note over NW: nested TS worker terminated by W dispose()
Loading

Reviews (8): Last reviewed commit: "fix: dispose" | Re-trigger Greptile

Comment thread src/cm/lsp/clientManager.ts
@bajrangCoder

This comment was marked as outdated.

@bajrangCoder

This comment was marked as outdated.

Comment thread src/cm/lsp/workers/nestedLspClient.ts Outdated
Comment thread src/cm/lsp/workers/protocol.ts
@bajrangCoder

This comment was marked as outdated.

Comment thread src/cm/lsp/workerTransport.ts
@bajrangCoder

This comment was marked as outdated.

@bajrangCoder

This comment was marked as outdated.

@bajrangCoder

This comment was marked as outdated.

@bajrangCoder

This comment was marked as outdated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

1 participant