Skip to content

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

Merged
bajrangCoder merged 13 commits into
mainfrom
worker-lsp-defaults
Jul 26, 2026
Merged

feat(lsp): add web worker language servers as defaults#2531
bajrangCoder merged 13 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 adds built-in Web Worker language servers for HTML, CSS/SCSS/Less, JSON/JSONC, and TypeScript/JavaScript, enabling LSP features without Alpine, STDIO processes, or manual installation. Previously flagged issues (pending client surviving disposal, post-ready worker crash silently hanging requests, factory rejection leaving a live worker, and formatSettings(undefined) crashing on code-action requests) have all been addressed in this revision.

  • New worker runtime: workerTransport.ts creates a CodeMirror-compatible LSP transport backed by a Web Worker, with startup timeout, host-request dispatch, and a failTransport path that correctly tears down the worker on post-ready crashes and rejects all in-flight LSP requests via NestedLspClient.fail().
  • Five new worker entry points: html.worker.ts (with embedded CSS/JS/import-map support), css.worker.ts, json.worker.ts, typescript.worker.ts, and their supporting protocol.ts protocol layer — all bundled as separate Rspack entry points.
  • Lifecycle hardening: disposeServer() now uses an AbortController per pending initialization, ClientState.dispose is idempotent (disposed flag), and onClientIdle disposes only the specific idle client rather than all clients for a server ID.

Confidence Score: 5/5

Safe to merge. The web-worker lifecycle (startup, abort-on-disable, post-ready crash) is correctly implemented, and every concern raised in the prior review round has been addressed.

All four lifecycle bugs from the previous review (pending-client survival, post-ready crash in NestedLspClient, factory rejection leaving a live worker, and formatSettings crashing on undefined options) have been fixed. The remaining findings are quality suggestions around TypeScript compiler-options fidelity and performance — none affect correctness of the shipped LSP features.

Files Needing Attention: src/cm/lsp/workers/typescript.worker.ts — getDefaultLibFileName() ignores the compiler options argument, and getProjectVersion() rebuilds the full version string on every call. Neither is a crash path, but both are worth addressing before the worker is relied on for strict TypeScript projects.

Important Files Changed

Filename Overview
src/cm/lsp/workerTransport.ts New file. Implements the Web Worker LSP transport with proper startup timeout, failTransport for post-ready OOM/crash, idempotent dispose, and host-request fan-out. Previously flagged post-ready crash issue is addressed.
src/cm/lsp/workers/protocol.ts New file. Worker-side JSON-RPC protocol: handles configure → factory → ready/error lifecycle, calls workerScope.close() on factory rejection (fixing the previous thread's concern), and implements validation debouncing.
src/cm/lsp/workers/nestedLspClient.ts New file. Manages the TypeScript sub-worker spawned inside the HTML worker. fail() method correctly rejects all in-flight requests and sets closedError tombstone; post-ready onerror calls fail() rather than relying on the settled startup-phase reject.
src/cm/lsp/workers/typescript.worker.ts New file. Full TypeScript language service in a Web Worker. formatSettings now accepts `options?: FormattingOptions
src/cm/lsp/workers/html.worker.ts New file. HTML worker with embedded CSS, importmap (JSON), and TypeScript/JS support via a nested NestedLspClient. Lifecycle (dispose, closeDocument) is complete; positions of embedded regions are correct due to whitespace-preserving extraction.
src/cm/lsp/clientManager.ts Adds disposeServer() with AbortController-based cancellation, idempotent ClientState.dispose with disposed guard, and properly handles the race where a pending client completes after abort by using Promise.allSettled.
src/lib/editorManager.js Updated onClientIdle to dispose only the specific idle client (not all clients for a server ID), then checks if any other clients for the server remain before stopping the managed server process.
src/cm/lsp/runtimes/webWorker.ts New runtime provider for web workers with priority 100 (highest). Delegates file reads to the host filesystem via hostHandlers.readFile; correctly passes originalRootUri for tsconfig discovery.
src/settings/lspServerDetail.js Now calls lspClientManager.disposeServer(serverId) before stopManagedServer when a server is disabled or removed; order is correct (clients disconnected before process stopped).
src/cm/lsp/servers/web.ts Adds new web-worker servers for HTML (id: "html"), CSS (id: "css"), JSON (id: "json"); renames STDIO equivalents to html-stdio, css-stdio, json-stdio and disables them by default — no ID conflicts.

Sequence Diagram

sequenceDiagram
    participant CM as LspClientManager
    participant WT as workerTransport
    participant W as Web Worker (protocol.ts)
    participant NLC as NestedLspClient
    participant TW as TypeScript Worker

    CM->>WT: "createWorkerTransport({ url, configure })"
    WT->>W: "postMessage({ kind: "configure", serverId, rootUri })"
    W->>W: factory() → adapter
    W-->>WT: "postMessage({ kind: "ready" })"
    WT-->>CM: ready resolves

    CM->>WT: transport.send(JSON-RPC initialize)
    WT->>W: postMessage(string)
    W-->>WT: postMessage(JSON-RPC response)
    WT-->>CM: listeners dispatch response

    Note over W,NLC: HTML worker only
    W->>NLC: new NestedLspClient("typescriptLspWorker.js")
    NLC->>TW: "postMessage({ kind: "configure" })"
    TW-->>NLC: "postMessage({ kind: "ready" })"
    NLC->>TW: JSON-RPC initialize
    TW-->>NLC: JSON-RPC response
    NLC-->>W: ready

    CM->>WT: dispose() or disposeServer()
    WT->>W: worker.terminate()
    Note over NLC,TW: HTML worker dispose
    W->>NLC: dispose()
    NLC->>TW: worker.terminate()
Loading

Reviews (10): Last reviewed commit: "fix: html , ts worker lsp" | 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.

# Conflicts:
#	src/cm/lsp/clientManager.ts
#	src/cm/lsp/servers/javascript.ts
@bajrangCoder

This comment was marked as outdated.

@bajrangCoder

This comment was marked as outdated.

@bajrangCoder
bajrangCoder added this pull request to the merge queue Jul 26, 2026
Merged via the queue into main with commit 212c398 Jul 26, 2026
11 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in The Code Board - Acode Jul 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant