Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/ts7-language-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@0no-co/graphqlsp': minor
---

Expose hover, completion, schema definitions, fragment references and rename, quick fixes, and fragment extraction through TypeScript 7.1 language-server API sessions. Add the `graphqlsp --stdio` LSP proxy for other editors.

Preserve native TypeScript capabilities, keep GraphQL completion resolution local, reject stale cross-file edits, recover local schemas after deletion/recreation, and await named schemas before the first feature request. The VS Code integration also disposes native providers when switching back to classic TypeScript or resetting native enablement.

Drain API workers during shutdown and bound the native TS 7.1 cleanup hang with a documented two-second fallback that terminates the native child before acknowledging proxy shutdown. Document npm-only LSP setup, VS Code activation, standalone checks, session methods, configuration boundaries, platform requirements, and reproducible editor validation.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
* text=auto
**/*.generated.ts linguist-generated
**/*.graphql linguist-generated
test/** text eol=lf
34 changes: 34 additions & 0 deletions .github/workflows/package-vscode.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Package editor integration
on:
workflow_dispatch:
pull_request:
push:
branches: [main]
permissions:
contents: read
jobs:
editor:
runs-on: ${{ matrix.os }}
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 22
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
with:
version: 11.3.0
- run: pnpm install --frozen-lockfile
- run: pnpm build
- run: pnpm exec vitest run test/e2e/ts7-session.test.ts test/e2e/lsp-proxy.test.ts test/e2e/lsp-shutdown.test.ts test/unit/lspProtocol.test.ts test/unit/schemaRecovery.test.ts test/unit/editVersions.test.ts test/unit/nativeMode.test.ts test/unit/vscode-ts7-features.test.ts --no-file-parallelism
env:
GRAPHQLSP_TS7_COMPILER: typescript
- run: pnpm --filter vscode-graphqlsp package
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: graphqlsp-editor-${{ runner.os }}
path: packages/vscode-graphqlsp/*.vsix
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,10 @@ dist
packages/graphqlsp/api/*
packages/graphqlsp/api
packages/graphqlsp/check
packages/graphqlsp/lsp

# VSCode extension packaging
packages/vscode-graphqlsp/.staging
*.vsix

.tmp/
327 changes: 292 additions & 35 deletions README.md

Large diffs are not rendered by default.

170 changes: 170 additions & 0 deletions docs/typescript-7-development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# TypeScript 7 development and validation

The [root guide](../README.md#typescript-7-editor-integration) and
[npm README](../packages/graphqlsp/README.md#typescript-7-editor-integration)
describe end-user setup, including the npm-only LSP path. The
[extension README](../packages/vscode-graphqlsp/README.md) covers VS Code setup.
This document covers implementation boundaries and reproducible checks.

## How the integrations fit together

The classic TS 5/6 plugin and native API integrations share GraphQL host
operations for diagnostics, hover, completion, schema definitions, fragment
references and rename, quick fixes, and fragment extraction.

- `packages/graphqlsp/src/session.ts` owns the API connection, snapshot lifetime,
schema state, and serialized feature/check calls. It refreshes the snapshot
after initial schema loading so results use current document text.
- `packages/graphqlsp/src/languageFeatures.ts` translates shared operations into
LSP positions, ranges, locations, completion items, code actions, and edits.
- `packages/graphqlsp/src/lsp.ts` forwards native LSP traffic and augments
supported requests through a worker. It preserves native completion triggers
and code-action kinds, resolves GraphQL completion items locally, and forwards
ordinary TypeScript operations to the native server.
- `packages/vscode-graphqlsp/src/typescript7` connects to a TypeScript extension's
API session and runs GraphQL work in a child process. It owns GraphQL completion
items, uses middleware where supported, and provides adapters for older APIs.
Native-mode changes dispose providers and diagnostics; server restarts create
a fresh connection.
- `packages/graphqlsp/src/ts7/relay.ts` bridges the synchronous API client when
direct pipe connections are unavailable. It uses a Unix shell launcher;
Windows isn't supported until TypeScript's sync client connects to pipes.

Results include the source text they were computed against. Integrations must
discard stale results. Cross-file edits additionally require validation of the
affected documents' identities and versions, including close/reopen transitions.
The VS Code adapter and proxy perform these checks before returning edits.

Local schema watching covers edits, deletion, and creation after an initial
missing-file error. Changed schemas are invalidated before reload; failed loads
do not silently reuse the old schema. Named schemas await initial readiness too.

## Prerequisites and build

Local validation used Node.js 22 and pnpm 11.3.0, matching the configured CI.
From the repository root:

```sh
pnpm install --frozen-lockfile
pnpm build
pnpm --filter vscode-graphqlsp build
```

The workspace compiler remains TS 5/6 for building and compatibility tests. The
native fixture installs `typescript-7` as an alias of TypeScript 7.1.0-beta, so
native testing does not replace the workspace compiler.

## Regression tests and typechecks

Run the complete suite:

```sh
pnpm exec vitest run --no-file-parallelism
```

For native editor/session/proxy changes, the targeted CI set is:

```sh
pnpm exec vitest run test/e2e/ts7-session.test.ts test/e2e/lsp-proxy.test.ts test/e2e/lsp-shutdown.test.ts test/unit/lspProtocol.test.ts test/unit/schemaRecovery.test.ts test/unit/editVersions.test.ts test/unit/nativeMode.test.ts test/unit/vscode-ts7-features.test.ts --no-file-parallelism
```

This covers unsaved snapshots, schema recovery and initial readiness, native
capabilities, GraphQL/native completion resolution, stale edits, setting
precedence, cancellation, and shutdown with documents open and closed.

Typecheck both packages explicitly:

```sh
pnpm exec tsc -p packages/graphqlsp --noEmit --types node --module esnext --moduleResolution bundler
pnpm exec tsc -p packages/vscode-graphqlsp --noEmit
```

To save machine-readable regression evidence:

```sh
pnpm exec vitest run --no-file-parallelism --reporter=default --reporter=json --outputFile.json=.tmp/regression-results.json
```

## Packaging both installation paths

Package the npm module without installing an editor extension:

```sh
pnpm --filter @0no-co/graphqlsp build
pnpm --filter @0no-co/graphqlsp pack --pack-destination .
```

The tarball name is derived from the package's current version. Install that
`.tgz` into a separate project with `npm install -D /absolute/path/to/package.tgz`.
Install TypeScript 7.1+ there, keep the GraphQLSP tsconfig entry, and launch the
proxy using the [documented Node command](../README.md#without-a-vsix-npm-and-an-lsp-client).

Package the VS Code integration:

```sh
pnpm --filter vscode-graphqlsp package
```

This builds the extension and core, packs the local npm module, and stages a
flat dependency tree before running `vsce package`. The output is
`packages/vscode-graphqlsp/vscode-graphqlsp-<version>.vsix`; the accompanying npm
tarball is in `packages/vscode-graphqlsp/.staging/`. Both contain their respective
READMEs. Packing does not publish to npm or the VS Code Marketplace.

## Actual VS Code validation

After packaging, run the isolated editor harness from the repository root:

```sh
node scripts/dogfood-vscode.mjs --code /absolute/path/to/Code --cli /absolute/path/to/resources/app/out/cli.js --results .tmp/dogfood-results.json
```

Use the installed VS Code executable and its matching CLI JavaScript file. The
optional `--vsix /absolute/path/to/file.vsix` selects an artifact explicitly.

The harness needs a desktop session and network access to install Microsoft's
TypeScript extension. It creates fresh temporary user-data and extension
directories and a fixture workspace. It installs the local VSIX and native
TypeScript extension, runs editor commands, and leaves the user's normal
profile untouched. The console prints the retained temporary directory for
logs; the JSON report records versions, checks, and failures. Any failed check
causes an unsuccessful exit.

The checks cover native diagnostics, unsaved correction, resolved completion
and application, hover, schema definitions, cross-file references, applied
rename, applied quick fixes and fragment extraction, schema edits and
deletion/recreation, server restart, TS 5/6 versus native switching, legacy
setting scope precedence, and resetting native enablement to unset.

## Shutdown workaround

The API worker stops accepting work, drains pending operations, and disposes
its session before native LSP shutdown. The relay releases retained snapshots
and files, half-closes the API connection, and waits for remote closure.

The tested native TS 7.1 server can still stall in API-session cleanup. After
requesting native shutdown, the proxy gives it two seconds to reply. On timeout,
it logs the fallback, terminates that in-memory child, and replies to the
client's shutdown request. It keeps the client transport alive until `exit`,
rejects further feature requests, and suppresses late duplicate shutdown replies.
This contains the native cleanup race; it does not repair it upstream.

## Validation scope and release status

The editor features were first exercised on Windows with VS Code 1.136.2,
TypeScriptTeam.native-preview 1.0.1, and TypeScript 7.1.0-beta, through a
Windows relay that has since been removed. Those results don't cover the
supported macOS and Linux paths; rerun the regression suite and the editor
harness there before release. These are local validation results, not claims
about every TypeScript or editor extension version.

The released native extension uses its older API shape; the newer middleware
adapter is covered by unit tests, not an actual released-editor run. The
`package-vscode.yaml` workflow builds, tests and packages on macOS and Linux.
It does not run the actual desktop-editor harness.

The npm changeset and extension version are independent. This local work does
not publish either artifact; CI packaging and Marketplace publishing are
separate actions. Rebuild after documentation changes so the npm README and
VSIX listing match the source, and record hashes against the exact artifact
used for editor validation.
Loading
Loading