Skip to content

Commit d3f8658

Browse files
committed
better readmes and apis
1 parent 0bde0a8 commit d3f8658

File tree

4 files changed

+161
-411
lines changed

4 files changed

+161
-411
lines changed

editor/codemirror/README.md

Lines changed: 50 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,76 @@
11
# @gnata-sqlite/codemirror
22

3-
CodeMirror 6 language support for [JSONata](https://jsonata.org) expressions — syntax highlighting, error diagnostics, autocomplete, and hover documentation, powered by a 380 KB WASM module (145 KB gzipped).
4-
5-
## Features
6-
7-
- **Syntax highlighting** — Lezer grammar with full JSONata 2.x coverage (works without WASM)
8-
- **Error diagnostics** — real-time squiggly underlines from the gnata parser
9-
- **Autocomplete** — context-aware: `$` triggers function completions with signatures, `.` triggers field completions from your data schema
10-
- **Hover documentation** — hover any `$function`, operator, keyword, or data field to see docs, signatures, and examples
3+
CodeMirror 6 language support for [JSONata](https://jsonata.org) — syntax highlighting, error diagnostics, autocomplete, and hover documentation.
114

125
## Install
136

147
```bash
158
npm install @gnata-sqlite/codemirror
169
```
1710

18-
You also need the WASM files served from your app:
19-
- `gnata-lsp.wasm` (380 KB, 145 KB gzipped)
20-
- `lsp-wasm_exec.js` (TinyGo runtime)
11+
Serve the WASM files from your app's public directory:
12+
- `gnata-lsp.wasm`
13+
- `lsp-wasm_exec.js`
14+
15+
If you're using `@gnata-sqlite/react`, the WASM files are already included — run `npx @gnata-sqlite/react` to copy them into place.
2116

2217
## Quick Start
2318

2419
```ts
2520
import { EditorView, basicSetup } from "codemirror"
2621
import { initWasm, jsonataFull } from "@gnata-sqlite/codemirror"
22+
import "@gnata-sqlite/codemirror/styles.css"
2723

28-
// 1. Load WASM (once, at startup)
2924
await initWasm("/gnata-lsp.wasm", "/lsp-wasm_exec.js")
3025

31-
// 2. Create editor with full JSONata support
3226
new EditorView({
33-
doc: '$sum(items.(price * quantity))',
34-
extensions: [
35-
basicSetup,
36-
jsonataFull(),
37-
],
27+
doc: '$sum(Account.Order.Product.(Price * Quantity))',
28+
extensions: [basicSetup, jsonataFull()],
3829
parent: document.getElementById("editor")!,
3930
})
4031
```
4132

42-
That's it. You get syntax highlighting, diagnostics, autocomplete, and hover docs.
43-
44-
## API
33+
That gives you syntax highlighting, diagnostics, autocomplete, and hover docs.
4534

46-
### `initWasm(wasmUrl, execUrl)`
35+
## Data-Aware Completions
4736

48-
Load the WASM module. Call once before creating editors. Returns a promise.
37+
Pass a schema to get field suggestions when typing after `.`:
4938

5039
```ts
51-
await initWasm("/assets/gnata-lsp.wasm", "/assets/lsp-wasm_exec.js")
52-
```
53-
54-
### `jsonataFull(config?)`
55-
56-
All-in-one extension: syntax highlighting + linting + autocomplete + hover.
40+
const schema = JSON.stringify({
41+
fields: {
42+
Account: {
43+
type: "object",
44+
fields: {
45+
Order: { type: "array", fields: {
46+
Product: { type: "array", fields: {
47+
Price: { type: "number" },
48+
Quantity: { type: "number" },
49+
}}
50+
}}
51+
}
52+
}
53+
}
54+
})
5755

58-
```ts
59-
jsonataFull() // basic — no schema
60-
jsonataFull({ schema: schemaString }) // with static schema
61-
jsonataFull({ schema: () => getSchema() }) // with dynamic schema
56+
jsonataFull({ schema })
57+
// or pass a getter for dynamic schemas:
58+
jsonataFull({ schema: () => currentSchema })
6259
```
6360

64-
The `schema` option enables field-aware autocomplete and hover. Pass a JSON string describing your data shape (see [Schema Format](#schema-format) below), or a getter function for dynamic schemas.
61+
Type `Account.Order.` and it suggests `Product` with type info. The `@gnata-sqlite/react` package exports a `buildSchema()` helper that generates this from sample JSON data.
6562

66-
### Individual Extensions
63+
## Individual Extensions
6764

68-
Use these for fine-grained control:
65+
`jsonataFull()` bundles everything. For fine-grained control, use the individual extensions:
6966

7067
```ts
7168
import {
7269
jsonata, // syntax highlighting only (no WASM needed)
7370
jsonataLint, // error diagnostics
7471
jsonataCompletion, // autocomplete
7572
jsonataHover, // hover tooltips
73+
jsonataLanguage, // underlying language definition
7674
} from "@gnata-sqlite/codemirror"
7775

7876
extensions: [
@@ -85,136 +83,33 @@ extensions: [
8583
]
8684
```
8785

88-
### `jsonata()`
89-
90-
Syntax highlighting only. Works without WASM — no `initWasm()` needed.
91-
92-
## Schema Format
93-
94-
The schema is a JSON string describing the shape of the input data. It enables field completions after `.` and type info on hover.
95-
96-
```json
97-
{
98-
"fields": {
99-
"event": {
100-
"type": "object",
101-
"fields": {
102-
"action": { "type": "string" },
103-
"severity": { "type": "number" },
104-
"user": { "type": "string" },
105-
"metadata": {
106-
"type": "object",
107-
"fields": {
108-
"ip": { "type": "string" },
109-
"geo": { "type": "string" }
110-
}
111-
}
112-
}
113-
}
114-
}
115-
}
116-
```
117-
118-
You can build this from your data at runtime:
119-
120-
```ts
121-
function buildSchema(data) {
122-
if (!data || typeof data !== "object") return {}
123-
if (Array.isArray(data)) {
124-
return data.length > 0 ? buildSchema(data[0]) : {}
125-
}
126-
const fields = {}
127-
for (const [key, val] of Object.entries(data)) {
128-
const type = val === null ? "null"
129-
: Array.isArray(val) ? "array"
130-
: typeof val
131-
const child = { type }
132-
if (typeof val === "object" && val !== null) {
133-
const nested = buildSchema(val)
134-
if (nested.fields) child.fields = nested.fields
135-
}
136-
fields[key] = child
137-
}
138-
return { fields }
139-
}
140-
141-
// Use it:
142-
const schema = JSON.stringify(buildSchema(myInputData))
143-
jsonataFull({ schema })
144-
```
86+
`jsonata()` works without WASM — use it for syntax highlighting only, no `initWasm()` needed.
14587

14688
## Styles
14789

14890
Import the bundled stylesheet for Tokyo Night-themed tooltips, autocomplete, and lint styling:
14991

15092
```ts
151-
import '@gnata-sqlite/codemirror/styles.css'
93+
import "@gnata-sqlite/codemirror/styles.css"
15294
```
15395

15496
Includes dark mode (default) and light mode (when `<html>` lacks a `.dark` class). Override any class in your own CSS to customize.
15597

156-
## Minimal Example
157-
158-
```ts
159-
import { EditorView, basicSetup } from "codemirror"
160-
import { initWasm, jsonataFull } from "@gnata-sqlite/codemirror"
161-
162-
await initWasm("/gnata-lsp.wasm", "/lsp-wasm_exec.js")
98+
## API Reference
16399

164-
new EditorView({
165-
doc: '$sum(Account.Order.Product.(Price * Quantity))',
166-
extensions: [basicSetup, jsonataFull()],
167-
parent: document.getElementById("editor")!,
168-
})
169-
```
100+
| Export | Description |
101+
|--------|-------------|
102+
| `initWasm(wasmUrl, execUrl)` | Load the WASM module. Call once at startup. Returns a promise. |
103+
| `jsonataFull(config?)` | All-in-one extension: highlighting + linting + autocomplete + hover. |
104+
| `jsonata()` | Syntax highlighting only. No WASM required. |
105+
| `jsonataLint()` | Error diagnostics extension. |
106+
| `jsonataCompletion(config?)` | Autocomplete source. Pass `{ schema }` for field completions. |
107+
| `jsonataHover(config?)` | Hover tooltip extension. Pass `{ schema }` for field type info. |
108+
| `jsonataLanguage` | Underlying Lezer language definition. |
109+
| `jsonataHighlighting` | Syntax highlighting style tags. |
170110

171-
With a schema for field-aware autocomplete and hover:
111+
Schema config accepts `{ schema: string | (() => string) }`.
172112

173-
```ts
174-
const schema = JSON.stringify({
175-
fields: {
176-
Account: {
177-
type: "object",
178-
fields: {
179-
Order: { type: "array", fields: {
180-
Product: { type: "array", fields: {
181-
Price: { type: "number" },
182-
Quantity: { type: "number" },
183-
}}
184-
}}
185-
}
186-
}
187-
}
188-
})
189-
190-
new EditorView({
191-
doc: 'Account.Order.',
192-
extensions: [basicSetup, jsonataFull({ schema })],
193-
parent: document.getElementById("editor")!,
194-
})
195-
```
196-
197-
## Architecture
198-
199-
```
200-
┌─────────────────────────────┐ ┌───────────────────────────────┐
201-
│ Your App (browser) │ │ gnata-lsp.wasm (145 KB) │
202-
│ │ │ TinyGo WASM module │
203-
│ CodeMirror Editor │────▶│ │
204-
│ + @gnata-sqlite/codemirror │ │ _gnataDiagnostics(expr) │
205-
│ │◀────│ _gnataCompletions(...) │
206-
│ │ │ _gnataHover(expr, pos) │
207-
└─────────────────────────────┘ └───────────────────────────────┘
208-
```
209-
210-
The WASM module contains the gnata parser and a catalog of 89 built-in JSONata functions with full documentation. It runs entirely in the browser — no server calls needed.
211-
212-
## Native LSP
213-
214-
The same Go code also builds as a native LSP server for VS Code / Neovim:
215-
216-
```bash
217-
go build -o gnata-lsp ./editor/
218-
```
113+
## License
219114

220-
Supports `textDocument/didOpen`, `textDocument/didChange`, `textDocument/completion`, `textDocument/hover`, and diagnostics.
115+
MIT

playground/src/App.css

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,18 @@ kbd { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; fo
172172

173173
/* gnata mode wrapper */
174174
.gnata-mode-wrapper { display: flex; flex-direction: column; flex: 1; overflow: hidden; min-height: 0; }
175-
176-
/* Ensure CodeMirror editors fill their containers in gnata mode */
177175
.gnata-mode-wrapper .cm-editor { height: 100%; }
178176
.gnata-mode-wrapper .cm-scroller { overflow: auto !important; }
179177

178+
/* gnata expression bar */
179+
.expression-bar { display: flex; align-items: stretch; border-bottom: 1px solid var(--border); background: var(--surface); flex-shrink: 0; }
180+
.expression-bar-label { padding: 10px 16px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.8px; color: var(--muted); border-right: 1px solid var(--border); display: flex; align-items: center; min-width: 120px; }
181+
182+
/* gnata panels */
183+
.gnata-panels { display: grid; grid-template-columns: 1fr 1fr; flex: 1; overflow: hidden; min-height: 0; }
184+
.gnata-panel { display: flex; flex-direction: column; overflow: hidden; }
185+
.gnata-panel + .gnata-panel { border-left: 1px solid var(--border); }
186+
180187
@media (max-width: 768px) {
181188
.panels { grid-template-columns: 1fr; }
182189
.editor-panel { border-right: none; border-bottom: 1px solid var(--border); min-height: 200px; }

0 commit comments

Comments
 (0)