# Development This document describes the development workflow for Decodal itself. ## Rust checks Run the normal Rust checks from the repository root. ```sh cargo fmt --check cargo test cargo check -p decodal --no-default-features nix flake check ``` Regex support is optional and should be tested explicitly when touched. ```sh cargo test -p decodal --features regex cargo run -q -p decodal-cli --features regex -- examples/regex/main.dcdl ``` ## crates.io release The primary crates.io package is `decodal`, which contains the embeddable library. `decodal-derive` provides optional derive macros for Rust struct integration and is published only when the derive crate changes. Workspace support crates such as `decodal-cli` and the Rust source crate `decodal-wasm` are not published to crates.io. The generated WebAssembly package under `site/decodal-site/src/wasm/` is published to npm and JSR. The project is dual licensed as `MIT OR Apache-2.0`. ```sh cargo publish -p decodal ``` Publish `decodal-derive` first only when that crate has a new version: ```sh cargo publish -p decodal-derive ``` Before publishing, run: ```sh cargo fmt --check cargo test cargo check -p decodal --no-default-features cargo publish -p decodal --dry-run ``` If `decodal-derive` changed, also run `cargo publish -p decodal-derive --dry-run`. ## Web site and playground The Astro documentation site and browser playground are kept in: ```text site/decodal-site/ ``` The site imports Markdown files from `doc/manual/souce/` and renders them as mdBook-style pages. The playground loads `decodal-wasm` and evaluates DCDL entirely in the browser. Important files: ```text site/decodal-site/src/pages/docs/[...slug].astro site/decodal-site/src/pages/playground.astro site/decodal-site/src/scripts/playground.js site/decodal-site/src/scripts/playground-examples.js site/decodal-site/src/layouts/ManualLayout.astro site/decodal-site/src/lib/codemirror/decodal.js site/decodal-site/src/lib/codemirror/decodal-parser.js site/decodal-site/src/lib/docs.js site/decodal-site/src/lib/highlight.js crates/decodal-wasm/src/lib.rs ``` Build the WebAssembly package before building the site: ```sh cd site/decodal-site npm install npm run build:wasm npm run build ``` `npm run build:wasm` writes generated files into: ```text site/decodal-site/src/wasm/ ``` These generated files are committed so the site can be built without requiring every consumer to regenerate the wasm package first. Publish the generated WebAssembly package from its package directory: ```sh cd site/decodal-site/src/wasm npm publish npx jsr publish ``` Run dry-runs first when preparing a release: ```sh npm pack --dry-run npx jsr publish --dry-run ``` The npm package name is `decodal-wasm`. The JSR package name is `@hare/decodal-wasm`. JSR currently expects a single SPDX license identifier in `jsr.json`; the WebAssembly package metadata uses `MIT` while the Rust workspace remains dual licensed as `MIT OR Apache-2.0`. The playground editor uses CodeMirror 6 with the generated Lezer parser in `src/lib/codemirror/decodal-parser.js`. The canonical grammar is documented in `doc/manual/souce/language/grammar.md`; regenerate the Lezer parser when that grammar or `editors/lezer-decodal/decodal.grammar` changes. The documentation build still uses the lightweight JavaScript fallback highlighter so Astro can render Markdown without initializing WASM at build time. To run the site locally: ```sh cd site/decodal-site npm run dev ``` Deploy the static site to Cloudflare Pages with Wrangler direct upload: ```sh cd site/decodal-site npm run deploy ``` The deploy script runs `npm run build` and then uploads `dist/` to the Pages project named `decodal-site` on branch `master`. Cloudflare Pages treats this as production when the project production branch is `master`. Use `CLOUDFLARE_PROJECT_NAME` when deploying to a differently named Pages project. ```sh CLOUDFLARE_PROJECT_NAME=my-pages-project npm run deploy ``` If the committed WASM package must be regenerated before deploy, use: ```sh npm run deploy:wasm ``` ## Tree-sitter grammar The Tree-sitter grammar is kept in: ```text editors/tree-sitter-decodal/ ``` Important files: ```text editors/tree-sitter-decodal/grammar.js editors/tree-sitter-decodal/queries/highlights.scm editors/tree-sitter-decodal/queries/locals.scm editors/tree-sitter-decodal/corpus/basic.txt ``` The grammar is intended to be portable across editors such as Zed, Neovim, Helix, and Emacs. Zed support should consume this grammar rather than relying on a TextMate grammar. ## Tree-sitter commands From the grammar directory: ```sh cd editors/tree-sitter-decodal npm install npx tree-sitter generate npx tree-sitter test ``` To inspect a parse tree: ```sh npx tree-sitter parse ../../examples/advanced/main.dcdl ``` The generated parser files under `editors/tree-sitter-decodal/src/` are committed so editor integrations can consume the grammar without regenerating it first. `node_modules/` is ignored and must not be committed. ## Updating the grammar When the Decodal syntax changes: 1. Update the canonical EBNF in `doc/manual/souce/language/grammar.md`. 2. Update the Rust parser/lexer as needed. 3. Update `editors/tree-sitter-decodal/grammar.js` and run `npx tree-sitter generate` / `npx tree-sitter test`. 4. Update `editors/lezer-decodal/decodal.grammar` and regenerate the CodeMirror parser: ```sh cd site/decodal-site npx lezer-generator ../../editors/lezer-decodal/decodal.grammar -o src/lib/codemirror/decodal-parser.js ``` 5. Add or update corpus/tests/examples. 6. Run Rust and site checks from the repository root. ## Development shell The Nix development shell includes Rust tooling, Node.js, Tree-sitter CLI tooling, and wasm-pack tooling. ```sh nix develop ``` The shell provides: - `cargo` - `rustc` - `rustfmt` - `clippy` - `node` - `npm` - `wasm-pack` - `lld` - `tree-sitter` - `nixfmt`