Skip to content

Commit add87aa

Browse files
committed
fix: update playground link in editor playground tutorial
refactor: modify React widget to use new wasm options structure style: adjust button styles and colors in home page and run example component feat: add LayerDiagram component to visualize architecture layers style: enhance tooltip styling for CodeMirror in both light and dark modes fix: improve theme handling in RunExample component for better UI consistency chore: update tokyo night light theme colors for better syntax highlighting
1 parent 8a24868 commit add87aa

36 files changed

Lines changed: 1335 additions & 495 deletions

.github/workflows/pages.yml

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Deploy Playground to GitHub Pages
1+
name: Deploy to GitHub Pages
22
on:
33
push:
44
branches: [main]
@@ -23,23 +23,56 @@ jobs:
2323
with:
2424
go-version-file: go.mod
2525

26+
- uses: pnpm/action-setup@v4
27+
28+
- uses: actions/setup-node@v4
29+
with:
30+
node-version: 22
31+
cache: pnpm
32+
2633
- name: Install TinyGo
2734
run: |
2835
wget -q https://github.com/tinygo-org/tinygo/releases/download/v0.40.1/tinygo_0.40.1_amd64.deb -O /tmp/tinygo.deb
2936
sudo dpkg -i /tmp/tinygo.deb
3037
31-
- name: Build WASM artifacts
38+
- name: Build WASM
3239
run: |
3340
GOOS=js GOARCH=wasm go build -ldflags="-s -w" -trimpath -o gnata.wasm ./wasm/
3441
cp "$(go env GOROOT)/lib/wasm/wasm_exec.js" wasm_exec.js
3542
tinygo build -o gnata-lsp.wasm -no-debug -gc=conservative -target wasm ./editor/
3643
cp "$(tinygo env TINYGOROOT)/targets/wasm_exec.js" lsp-wasm_exec.js
3744
38-
- name: Prepare site
45+
- name: Install dependencies
46+
run: pnpm install --frozen-lockfile
47+
48+
- name: Build React widget
49+
run: cd react && pnpm run build
50+
51+
# Build docs site (Fumadocs static export)
52+
- name: Copy WASM to website
53+
run: cp gnata.wasm gnata-lsp.wasm wasm_exec.js lsp-wasm_exec.js website/public/
54+
55+
- name: Build website
56+
run: cd website && pnpm build
57+
env:
58+
GITHUB_PAGES: true
59+
60+
# Build playground (Vite static build)
61+
- name: Copy WASM to playground
62+
run: cp gnata.wasm gnata-lsp.wasm wasm_exec.js lsp-wasm_exec.js playground/public/
63+
64+
- name: Build playground
65+
run: cd playground && pnpm build
66+
env:
67+
GITHUB_PAGES: true
68+
69+
# Combine: docs site at root, playground nested at /playground/
70+
- name: Assemble site
3971
run: |
4072
mkdir -p _site
41-
cp playground.html _site/index.html
42-
cp gnata.wasm gnata-lsp.wasm wasm_exec.js lsp-wasm_exec.js _site/
73+
cp -r website/out/* _site/
74+
mkdir -p _site/playground
75+
cp -r playground/dist/* _site/playground/
4376
4477
- uses: actions/upload-pages-artifact@v3
4578

README.md

Lines changed: 99 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,136 @@
11
# gnata-sqlite
22

3-
End-to-end [JSONata 2.x](https://jsonata.org) in Go — from a loadable SQLite extension to a composable React editor with context-aware autocomplete, everything needed to run, write, and edit JSONata expressions.
3+
End-to-end [JSONata 2.x](https://jsonata.org) in Go — let end users write their own JSONata expressions against SQLite data, with a composable React editor that provides autocomplete, hover docs, and live diagnostics out of the box.
44

55
[![CI](https://github.com/rbbydotdev/gnata-sqlite/actions/workflows/ci.yml/badge.svg)](https://github.com/rbbydotdev/gnata-sqlite/actions/workflows/ci.yml)
66
[![Go Reference](https://pkg.go.dev/badge/github.com/rbbydotdev/gnata-sqlite.svg)](https://pkg.go.dev/github.com/rbbydotdev/gnata-sqlite)
77
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
88
[![Go 1.25](https://img.shields.io/badge/Go-1.25-00ADD8.svg)](https://go.dev)
99

10-
## Highlights
10+
**[Docs](https://rbby.dev/gnata-sqlite/)** · **[Playground](https://rbby.dev/gnata-sqlite/playground)** · **[Getting Started](https://rbby.dev/gnata-sqlite/docs/tutorials/getting-started)** · **[React Widget](https://rbby.dev/gnata-sqlite/docs/tutorials/react-widget)** · **[Architecture](https://rbby.dev/gnata-sqlite/docs/explanation/architecture)**
1111

12-
- **Full JSONata 2.x spec** — paths, wildcards, lambdas, closures, higher-order functions, 50+ stdlib functions. 1,778 conformance tests, 0 failures
13-
- **SQLite extension**`jsonata()`, `jsonata_query()`, `jsonata_each()` as loadable functions with a built-in query planner that matches native SQL performance
14-
- **React editor widget** — composable hooks and components (`@gnata-sqlite/react`) for embedding a JSONata editor in any app, with autocomplete, hover docs, and live diagnostics
15-
- **85KB WASM LSP** — TinyGo-compiled language server powering in-browser editor features from the same Go codebase as the native LSP
16-
- **Context-aware autocomplete** — the editor evaluates prefix expressions against live data to suggest nested keys, enabling end users to explore and write expressions without knowing the schema upfront
17-
- **5M+ eval ops/sec** — two-tier evaluator with GJSON fast path hitting 10M+ ops/sec for simple paths
12+
---
1813

19-
## Quick Start
14+
## The Problem
2015

21-
```go
22-
import "github.com/rbbydotdev/gnata-sqlite"
16+
Applications store JSON in SQLite. Querying and transforming that data requires custom code for every new report, filter, or dashboard widget. End users can't explore the data themselves — they depend on developers to write each query.
2317

24-
expr, _ := gnata.Compile(`Account.Order.Product.Price`)
25-
result, _ := expr.Eval(context.Background(), data)
26-
fmt.Println(result) // [34.45 21.67]
27-
```
18+
## The Solution
19+
20+
gnata-sqlite makes SQLite JSON data queryable with [JSONata](https://jsonata.org) — a lightweight, expressive language end users can learn — and provides everything needed to embed an expression editor in any app:
21+
22+
1. **Load the SQLite extension** → JSON columns become queryable with JSONata
23+
2. **Embed the React editor** → end users write expressions with autocomplete and live feedback
24+
3. **Connect via schema** → the editor suggests fields from the actual database structure
25+
26+
No custom query builder UI. No hardcoded report logic. End users write expressions; the extension runs them.
2827

2928
## SQLite Extension
3029

30+
A loadable extension that brings JSONata into SQL queries. Install once, use from any SQLite client.
31+
32+
<img src="assets/playground-sqlite-dashboard.png" alt="SQLite dashboard query" width="720" />
33+
3134
```sql
3235
.load ./gnata_jsonata sqlite3_jsonata_init
3336

34-
SELECT jsonata(data, 'Account.Name') FROM events;
35-
-- "Firefly"
37+
-- Per-row: extract, transform, filter
38+
SELECT jsonata('items[price > 100].name', data) FROM orders;
3639

37-
SELECT jsonata_query('$sum(amount)', data) FROM orders;
38-
-- 4250
40+
-- Aggregate: build a full report in one expression
41+
SELECT jsonata_query('{
42+
"revenue": $sum($filter($, function($v){ $v.status = "shipped" }).total),
43+
"orders": $count($),
44+
"avg": $round($average(total), 2)
45+
}', data) FROM orders;
3946
```
4047

41-
| Function | Description |
42-
|----------|-------------|
43-
| `jsonata(json, expr)` | Evaluate expression against JSON |
44-
| `jsonata_query(expr, json)` | Expression-first argument order |
45-
| `jsonata_each(expr, json)` | Expand results into rows (table-valued) |
48+
The query planner decomposes complex expressions into streaming accumulators — matching hand-tuned SQL performance on 100K+ rows. See [sqlite/OPTIMIZATION.md](sqlite/OPTIMIZATION.md).
49+
50+
| Function | Purpose |
51+
|----------|---------|
52+
| `jsonata(json, expr)` | Evaluate per row |
53+
| `jsonata_query(expr, json)` | Aggregate across rows |
54+
| `jsonata_each(expr, json)` | Expand results into rows |
4655
| `jsonata_set(json, path, val)` | Set a value at a path |
4756
| `jsonata_delete(json, path)` | Delete a value at a path |
4857

49-
See [sqlite/README.md](sqlite/README.md) for full docs. Query optimization details in [sqlite/OPTIMIZATION.md](sqlite/OPTIMIZATION.md).
58+
## React Editor
59+
60+
A composable React package (`@gnata-sqlite/react`) for embedding a JSONata expression editor. Developers ship the editor; end users write expressions.
61+
62+
### Hover Documentation
63+
64+
<img src="assets/playground-gnata-hover.png" alt="Hover documentation showing $sum function" width="720" />
65+
66+
Hover over any function to see its signature, description, and examples — powered by the 85KB TinyGo WASM LSP.
67+
68+
### Context-Aware Autocomplete
5069

51-
## Benchmarks
70+
<img src="assets/playground-gnata-autocomplete.png" alt="Autocomplete suggesting Account.Name and Account.Order" width="720" />
5271

53-
![Eval Performance](assets/benchmark-eval.png)
72+
Type `Account.` and the editor evaluates the prefix expression against the input data to discover available keys — suggesting `Name`, `Order`, etc. with types.
5473

55-
![GJSON Fast Path](assets/benchmark-fastpath.png)
74+
### Expression Editor
5675

57-
<details>
58-
<summary>Raw numbers (Apple M1)</summary>
76+
<img src="assets/playground-gnata-transform.png" alt="JSONata transform expression with syntax highlighting" width="720" />
5977

60-
| Benchmark | ops/sec | ns/op | allocs/op |
61-
|-----------|---------|-------|-----------|
62-
| Eval `Account.Name` | **5,037,783** | 198 | 4 |
63-
| Eval `Order.Product.SKU` | 2,160,554 | 463 | 10 |
64-
| Eval `Product[Price>50].SKU` | 895,255 | 1,117 | 26 |
65-
| Eval `$sum(Product.*)` | 654,006 | 1,529 | 44 |
66-
| EvalBytes `Account.Name` | **10,280,965** | 97 | 2 |
67-
| Compile `Account.Name` | 1,757,469 | 569 | 13 |
78+
Full JSONata syntax highlighting, live evaluation, and diagnostics (red underlines on errors).
6879

69-
</details>
80+
### Quick Start
81+
82+
```tsx
83+
import { useJsonataLsp, JsonataEditor } from '@gnata-sqlite/react'
84+
import '@gnata-sqlite/react/tooltips.css'
85+
86+
function ExpressionBuilder() {
87+
const lsp = useJsonataLsp({
88+
lspWasmUrl: '/gnata-lsp.wasm',
89+
lspExecUrl: '/lsp-wasm_exec.js',
90+
})
91+
92+
return (
93+
<JsonataEditor
94+
value={expression}
95+
onChange={setExpression}
96+
schema={schemaFromBackend}
97+
gnataDiagnostics={lsp.gnataDiagnostics}
98+
gnataCompletions={lsp.gnataCompletions}
99+
gnataHover={lsp.gnataHover}
100+
/>
101+
)
102+
}
103+
```
104+
105+
**What end users get:** autocomplete, hover docs, live diagnostics, syntax highlighting
106+
107+
**What developers get:** 85KB WASM LSP, hooks-first API, no eval required, schema-driven
108+
109+
## How It Fits Together
110+
111+
The SQLite extension runs expressions on the backend. The React editor lets end users write those expressions in the browser. The schema protocol connects them.
112+
113+
```
114+
Backend Frontend
115+
┌──────────────────┐ ┌──────────────────────────┐
116+
│ SQLite + gnata │ │ @gnata-sqlite/react │
117+
│ extension │ schema → │ CodeMirror 6 editor │
118+
│ │ │ + 85KB WASM LSP │
119+
│ Runs expressions │ ← expr │ Autocomplete, hover, │
120+
│ against JSON data│ │ diagnostics │
121+
└──────────────────┘ └──────────────────────────┘
122+
```
70123

71124
## Packages
72125

73126
| Package | Description |
74127
|---------|-------------|
75-
| `gnata` (root) | Core JSONata 2.x engine — full spec, two-tier eval, streaming |
76-
| [`sqlite/`](sqlite/README.md) | SQLite extension — loadable functions, query planner, mutations |
128+
| `gnata` (root) | Core JSONata 2.x engine — 1,778 conformance tests, 0 failures |
129+
| [`sqlite/`](sqlite/README.md) | Loadable SQLite extension with streaming query planner |
77130
| [`editor/`](editor/README.md) | CodeMirror 6 language support + TinyGo WASM LSP |
78-
| [`react/`](react/README.md) | Composable React widget — hooks, components, and full playground |
131+
| [`react/`](react/README.md) | Composable React hooks and components |
132+
| [`playground/`](playground/) | Interactive playground (Vite + React) |
133+
| [`website/`](website/) | Documentation site (Fumadocs) |
79134

80135
## Building
81136

@@ -88,11 +143,9 @@ make playground # Build WASM + start playground dev server
88143
make website # Start docs site dev server
89144
```
90145

91-
See `Makefile` for all targets.
92-
93146
## Playground
94147

95-
Visit the [live playground](https://rbbydotdev.github.io/gnata-sqlite/) for interactive testing of JSONata expressions and the SQLite extension. To run locally:
148+
Visit the [live playground](https://rbby.dev/gnata-sqlite/playground) to try JSONata expressions against SQLite data in the browser. To run locally:
96149

97150
```bash
98151
cd playground && pnpm install && pnpm dev
@@ -104,7 +157,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.
104157

105158
## Fork Notice
106159

107-
Forked from [RecoLabs/gnata](https://github.com/RecoLabs/gnata), which provides a production-grade JSONata 2.x engine in pure Go. This project extends the core engine with a SQLite extension, editor tooling, and query optimizer.
160+
Forked from [RecoLabs/gnata](https://github.com/RecoLabs/gnata), a JSONata 2.x engine in pure Go. This project extends it with a SQLite extension, query planner, TinyGo WASM LSP, CodeMirror editor, and composable React package.
108161

109162
## License
110163

assets/benchmark-eval.png

-79.2 KB
Binary file not shown.

assets/benchmark-fastpath.png

-57.3 KB
Binary file not shown.

assets/code-card-sql.png

73.5 KB
Loading

assets/og-image.png

205 KB
Loading
148 KB
Loading

assets/playground-gnata-hover.png

170 KB
Loading
229 KB
Loading
212 KB
Loading

0 commit comments

Comments
 (0)