Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a861eff
feat: add first github pages playground
thomas9911 Apr 12, 2026
aaadd55
chore: add `playground/` directory to excluded paths
micahkepe Apr 12, 2026
3f54649
chore: use same compile flags as main crate
micahkepe Apr 12, 2026
6feee8a
fix(script): `bun dev` doesn't work on clean checkout
micahkepe Apr 12, 2026
2a4c004
chore: remove dev scripts
micahkepe Apr 13, 2026
da0242c
ci(playground): only deploy on changes to playground files, use legac…
micahkepe Apr 13, 2026
18c4bcd
chore: update playground README
micahkepe Apr 13, 2026
2da1f20
chore: use `-rf` to not exit on non-existent directory (first run)
micahkepe Apr 13, 2026
c08d728
refactor(playground): create common `run_query` function, fix `None` …
micahkepe Apr 13, 2026
ea67970
chore: remove misleading comment
micahkepe Apr 13, 2026
01ef068
feat(playground): first pass of refactoring playground UI
micahkepe Apr 13, 2026
4590097
feat(playground): add light/dark toggle
micahkepe Apr 13, 2026
330e70a
fix(playground): auto-create gh-pages branch on fresh checkout
micahkepe Apr 13, 2026
a30694e
feat(playground): add border accent flash for shortcut visual feedback
micahkepe Apr 13, 2026
68343b7
chore: run formatting, add background color to inputs and results
micahkepe Apr 13, 2026
a83b110
feat(playground): global mod + enter submit bind, fixed width theme
micahkepe Apr 13, 2026
44c63ac
feat(playground): add help overlay (? toggle)
micahkepe Apr 13, 2026
eb4d1b5
fix(playground): show root value on empty query to match CLI
micahkepe Apr 13, 2026
9e6fc7c
fix(playground): show "no matches" on no results
micahkepe Apr 13, 2026
7a3e95d
feat(playground): global ESC to lose focus on current input
micahkepe Apr 13, 2026
a4d4cfe
feat(playground): link to main repo
micahkepe Apr 13, 2026
a53e9d9
fix(playground): no layout shift with many results
micahkepe Apr 13, 2026
4014992
feat(playground): URL shareable hashes, query examples
micahkepe Apr 13, 2026
d5fe0b5
test(playground): add unit tests verifying behavior
micahkepe Apr 13, 2026
7bdcd2e
chore(playground): add installation link
micahkepe Apr 13, 2026
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
62 changes: 62 additions & 0 deletions .github/workflows/deploy-playground.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Deploy playground to Pages

on:
push:
branches: [main]
paths:
- 'playground/**'
- 'src/**'
- 'Cargo.toml'
- 'Cargo.lock'
- '.github/workflows/deploy-playground.yml'
workflow_dispatch:

permissions:
contents: write

concurrency:
group: "playground-deploy"
cancel-in-progress: false

jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- uses: actions/cache@v4
with:
path: ~/.bun/install/cache
key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }}
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
target: wasm32-wasip2
cache: true
cache-directories: playground/wasm/target
- name: Install & Build
working-directory: playground
run: |
bun install
bun run build
- name: Deploy to gh-pages branch
run: |
cp -r playground/dist /tmp/playground-dist
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

# Use existing gh-pages branch, or create an orphan if it doesn't exist
if git fetch origin gh-pages 2>/dev/null; then
git checkout gh-pages
else
git checkout --orphan gh-pages
git rm -rf .
fi

rm -rf playground
cp -r /tmp/playground-dist playground
git add playground
git commit -m "Deploy playground from ${{ github.sha }}" || echo "No changes to commit"
git push origin gh-pages
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ exclude = [
"benches/",
"tests/",
"justfile",
".gitmodules"
".gitmodules",
"playground"
]

[dependencies]
Expand Down
37 changes: 37 additions & 0 deletions playground/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# dependencies (bun install)
node_modules

# output
out
dist
*.tgz

# code coverage
coverage
*.lcov

# logs
logs
_.log
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# caches
.eslintcache
.cache
*.tsbuildinfo

# IntelliJ based IDEs
.idea

# Finder (MacOS) folder config
.DS_Store

# generated from jco transpile
generated
28 changes: 28 additions & 0 deletions playground/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# JSONGrep Playground

A browser-based playground for
[jsongrep](https://github.com/micahkepe/jsongrep), powered by WebAssembly.

## Prerequisites

- [Bun](https://bun.sh)
- [Rust](https://rustup.rs) with the `wasm32-wasip2` target:

```bash
rustup target add wasm32-wasip2
```

## Development

```bash
bun install
bun dev
```

## Production build

```bash
bun run build
```

The output is written to `dist/` and can be served as a static site.
17 changes: 17 additions & 0 deletions playground/bun-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Generated by `bun init`

declare module "*.svg" {
/**
* A path to the SVG file
*/
const path: `${string}.svg`;
export = path;
}

declare module "*.module.css" {
/**
* A record of class names to their corresponding CSS module classes
*/
const classes: { readonly [key: string]: string };
export = classes;
}
172 changes: 172 additions & 0 deletions playground/bun.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions playground/bunfig.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[serve.static]
env = "BUN_PUBLIC_*"
29 changes: 29 additions & 0 deletions playground/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "jsongrep-playground",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"setup": "bun run wasm:build && bun run wasm:transpile",
"dev": "bun run setup && bun --hot src/index.ts",
"build": "bun run setup && bun build ./src/index.html --outdir=dist --sourcemap --target=browser --minify --define:process.env.NODE_ENV='\"production\"' --env='BUN_PUBLIC_*' && bun run wasm:move",
"start": "NODE_ENV=production bun src/index.ts",
"clean": "rm -rf generated dist",
"wasm:build": "cd wasm && cargo build --release --target wasm32-wasip2",
"wasm:sanity-check": "bun run wasm:build && cd wasm && sh ./sanity-check.sh",
"wasm:move": "cp generated/*.wasm dist",
"wasm:transpile": "bun run wasm:jco:types && bun run wasm:jco:transpile",
"wasm:jco:transpile": "bun run jco transpile ./wasm/target/wasm32-wasip2/release/jsongrep_wasm.wasm -o generated",
"wasm:jco:types": "rm -rf generated && bun run jco types -o generated ./wasm/wit"
},
"dependencies": {
"@bytecodealliance/jco": "^1.17.6",
"react": "^19",
"react-dom": "^19"
},
"devDependencies": {
"@types/react": "^19",
"@types/react-dom": "^19",
"@types/bun": "latest"
}
}
74 changes: 74 additions & 0 deletions playground/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { useCallback, useEffect, useState } from "react";
import { Playground } from "./Playground";
import "./index.css";

type Theme = "light" | "dark";

function getInitialTheme(): Theme {
const stored = localStorage.getItem("theme");
if (stored === "light" || stored === "dark") return stored;
return window.matchMedia("(prefers-color-scheme: light)").matches
? "light"
: "dark";
}

export function App() {
const [theme, setTheme] = useState<Theme>(getInitialTheme);

useEffect(() => {
document.documentElement.setAttribute("data-theme", theme);
localStorage.setItem("theme", theme);
}, [theme]);

const toggleTheme = useCallback(() => {
setTheme((t) => (t === "dark" ? "light" : "dark"));
}, []);

return (
<div className="app">
<header>
<hgroup>
<h1>jsongrep</h1>
<p className="subtitle">
interactive playground &mdash;{" "}
<a href="https://github.com/micahkepe/jsongrep/tree/main/playground">source</a>
</p>
</hgroup>
<nav className="header-actions" aria-label="Site actions">
<a
href="https://github.com/micahkepe/jsongrep#installation"
className="install-link"
>
install
</a>
<a
href="https://github.com/micahkepe/jsongrep"
className="github-link"
aria-label="jsongrep on GitHub"
target="_blank"
rel="noopener noreferrer"
>
<svg
viewBox="0 0 16 16"
width="20"
height="20"
fill="currentColor"
aria-hidden="true"
>
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z" />
</svg>
</a>
<button
type="button"
className="theme-toggle"
onClick={toggleTheme}
aria-label={`Switch to ${theme === "dark" ? "light" : "dark"} mode`}
>
{theme === "dark" ? "light" : "dark"}
</button>
</nav>
</header>
<Playground />
</div>
);
}
Loading