Skip to content

Commit c68c674

Browse files
authored
feat(wasm): WASM bindings for browser use (#638)
## Summary Add WebAssembly bindings for using the Postgres Language Server in the browser. This enables: - SQL parsing and linting in web applications - Monaco editor integration with LSP support - Schema-aware completions and hover information ## Two APIs The package provides two independent APIs: | API | Use Case | Import Path | |-----|----------|-------------| | **Workspace** | Direct parse, lint, complete, hover | `@postgres-language-server/wasm/workspace` | | **LanguageServer** | Full LSP JSON-RPC protocol | `@postgres-language-server/wasm/lsp` | ### Workspace API Example ```typescript import { createWorkspace } from '@postgres-language-server/wasm/workspace'; const workspace = await createWorkspace(); workspace.insertFile('/query.sql', 'SELECT * FROM users;'); const diagnostics = workspace.lint('/query.sql'); const completions = workspace.complete('/query.sql', 14); ``` ### LanguageServer API Example ```typescript import { createLanguageServer } from '@postgres-language-server/wasm/lsp'; const lsp = await createLanguageServer(); const responses = lsp.handleMessage({ jsonrpc: '2.0', id: 1, method: 'initialize', params: { capabilities: {} } }); ``` ## Implementation - `pgls_wasm` Rust crate with Emscripten target - `@postgres-language-server/wasm` TypeScript package - Web worker integration for Monaco editor ## Test plan - [x] Unit tests for Workspace API (parse, lint, complete, hover) - [x] Unit tests for LanguageServer API (LSP messages) - [x] E2E tests with Monaco editor via Playwright - [x] Web worker integration tests
1 parent d9964c1 commit c68c674

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+5293
-393
lines changed

.cargo/config.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[target.wasm32-unknown-emscripten]
2+
rustflags = [
3+
"-C",
4+
"link-args=-sSTANDALONE_WASM=0",
5+
"-C",
6+
"link-args=-sERROR_ON_UNDEFINED_SYMBOLS=0",
7+
"-C",
8+
"link-args=-sDISABLE_EXCEPTION_CATCHING=1",
9+
"-C",
10+
"link-args=-sEXPORTED_FUNCTIONS=['_pgls_init','_pgls_free_string','_pgls_set_schema','_pgls_clear_schema','_pgls_insert_file','_pgls_remove_file','_pgls_lint','_pgls_complete','_pgls_hover','_pgls_parse','_pgls_version','_pgls_handle_message','_malloc','_free']",
11+
]

.github/workflows/pull_request.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,42 @@ jobs:
241241
working-directory: packages/@postgres-language-server/cli
242242
run: bun run test
243243

244+
test-wasm:
245+
name: Test WASM Package
246+
runs-on: ubuntu-22.04
247+
steps:
248+
- name: Checkout PR branch
249+
uses: actions/checkout@v4
250+
with:
251+
submodules: true
252+
253+
- name: Free Disk Space
254+
uses: ./.github/actions/free-disk-space
255+
256+
- name: Install Nix
257+
uses: DeterminateSystems/nix-installer-action@main
258+
259+
- name: Setup Magic Nix Cache
260+
uses: DeterminateSystems/magic-nix-cache-action@main
261+
262+
- name: Install root JS dependencies
263+
run: nix develop --command bun install
264+
265+
- name: Install WASM package dependencies
266+
run: nix develop --command bash -c "cd packages/@postgres-language-server/wasm && bun install"
267+
268+
- name: Build WASM package
269+
run: nix develop --command bash -c "cd packages/@postgres-language-server/wasm && bun run build"
270+
271+
- name: Run WASM unit tests
272+
run: nix develop --command bash -c "cd packages/@postgres-language-server/wasm && bun test"
273+
274+
- name: Install Playwright
275+
run: nix develop --command bash -c "cd packages/@postgres-language-server/wasm && bun run test:e2e:install"
276+
277+
- name: Run WASM e2e tests
278+
run: nix develop --command bash -c "cd packages/@postgres-language-server/wasm && bun run test:e2e"
279+
244280
codegen:
245281
name: Check Codegen
246282
runs-on: ubuntu-22.04

.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@ crates/pgt_treesitter_grammar/src/grammar.json
3333
crates/pgt_treesitter_grammar/src/node-types.json
3434
crates/pgt_treesitter_grammar/src/parser.c
3535
crates/pgt_treesitter_grammar/src/parser.c.codex-session-id
36+
crates/pgls_treesitter_grammar/src/grammar.json
37+
crates/pgls_treesitter_grammar/src/node-types.json
38+
crates/pgls_treesitter_grammar/src/parser.c
39+
40+
# WASM package build artifacts
41+
crates/pgls_wasm/dist/
42+
packages/@postgres-language-server/wasm/wasm/pgls.js
43+
packages/@postgres-language-server/wasm/wasm/pgls.wasm
44+
45+
# Playwright
46+
playwright-report/
47+
test-results/
3648
.codex-session-id
3749

3850
site/
51+
52+
biome-main/

Cargo.lock

Lines changed: 44 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ rayon = "1.10.0"
3737
regex = "1.11.1"
3838
rustc-hash = "2.0.0"
3939
schemars = { version = "0.8.22", features = ["indexmap2", "smallvec"] }
40-
serde = "1.0.195"
40+
serde = { version = "1.0.195", features = ["rc"] }
4141
serde_json = "1.0.114"
4242
similar = "2.6.0"
4343
slotmap = "1.0.7"
@@ -82,7 +82,7 @@ pgls_plpgsql_check = { path = "./crates/pgls_plpgsql_check", version =
8282
pgls_query = { path = "./crates/pgls_query", version = "0.0.0" }
8383
pgls_query_ext = { path = "./crates/pgls_query_ext", version = "0.0.0" }
8484
pgls_query_macros = { path = "./crates/pgls_query_macros", version = "0.0.0" }
85-
pgls_schema_cache = { path = "./crates/pgls_schema_cache", version = "0.0.0" }
85+
pgls_schema_cache = { path = "./crates/pgls_schema_cache", version = "0.0.0", default-features = false }
8686
pgls_splinter = { path = "./crates/pgls_splinter", version = "0.0.0" }
8787
pgls_statement_splitter = { path = "./crates/pgls_statement_splitter", version = "0.0.0" }
8888
pgls_suppressions = { path = "./crates/pgls_suppressions", version = "0.0.0" }
@@ -92,6 +92,7 @@ pgls_tokenizer = { path = "./crates/pgls_tokenizer", version = "0.0
9292
pgls_treesitter = { path = "./crates/pgls_treesitter", version = "0.0.0" }
9393
pgls_treesitter_grammar = { path = "./crates/pgls_treesitter_grammar", version = "0.0.0" }
9494
pgls_typecheck = { path = "./crates/pgls_typecheck", version = "0.0.0" }
95+
pgls_wasm = { path = "./crates/pgls_wasm", version = "0.0.0" }
9596
pgls_workspace = { path = "./crates/pgls_workspace", version = "0.0.0" }
9697
pgls_workspace_macros = { path = "./crates/pgls_workspace_macros", version = "0.0.0" }
9798

0 commit comments

Comments
 (0)