Add language tools package
This commit is contained in:
Generated
+9
@@ -16,6 +16,7 @@
|
||||
"astro": "^4.16.18",
|
||||
"codemirror": "^6.0.2",
|
||||
"decodal-codemirror": "file:../../packages/decodal-codemirror",
|
||||
"decodal-language-tools": "file:../../packages/decodal-language-tools",
|
||||
"decodal-wasm": "file:../../packages/decodal-wasm",
|
||||
"marked": "^12.0.2"
|
||||
},
|
||||
@@ -33,6 +34,10 @@
|
||||
"@lezer/lr": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"../../packages/decodal-language-tools": {
|
||||
"version": "0.1.2",
|
||||
"license": "MIT OR Apache-2.0"
|
||||
},
|
||||
"../../packages/decodal-wasm": {
|
||||
"version": "0.1.2",
|
||||
"license": "MIT OR Apache-2.0"
|
||||
@@ -3255,6 +3260,10 @@
|
||||
"resolved": "../../packages/decodal-codemirror",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/decodal-language-tools": {
|
||||
"resolved": "../../packages/decodal-language-tools",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/decodal-wasm": {
|
||||
"resolved": "../../packages/decodal-wasm",
|
||||
"link": true
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
"preview": "astro preview --host 0.0.0.0",
|
||||
"build:wasm": "wasm-pack build ../../crates/decodal-wasm --target web --out-dir ../../packages/decodal-wasm --release && node scripts/prepare-wasm-package.mjs",
|
||||
"deploy": "npm run build && node scripts/deploy-pages.mjs",
|
||||
"deploy:wasm": "npm run build:wasm && npm run deploy"
|
||||
"deploy:wasm": "npm run build:wasm && npm run deploy",
|
||||
"build:tools": "wasm-pack build ../../crates/decodal-language-tools --target web --out-dir ../../packages/decodal-language-tools --release && node scripts/prepare-language-tools-package.mjs",
|
||||
"build:packages": "npm run build:wasm && npm run build:tools"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/check": "^0.9.4",
|
||||
@@ -20,6 +22,7 @@
|
||||
"astro": "^4.16.18",
|
||||
"codemirror": "^6.0.2",
|
||||
"decodal-codemirror": "file:../../packages/decodal-codemirror",
|
||||
"decodal-language-tools": "file:../../packages/decodal-language-tools",
|
||||
"decodal-wasm": "file:../../packages/decodal-wasm",
|
||||
"marked": "^12.0.2"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
import { writeFileSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
const packageDir = resolve(import.meta.dirname, '../../../packages/decodal-language-tools');
|
||||
|
||||
writeFileSync(
|
||||
resolve(packageDir, '.gitignore'),
|
||||
'# wasm-pack output is committed for the browser language tools package.\n',
|
||||
);
|
||||
|
||||
writeFileSync(
|
||||
resolve(packageDir, 'README.md'),
|
||||
`# decodal-language-tools
|
||||
|
||||
Source-level language tooling for Decodal.
|
||||
|
||||
This package is generated from the Rust crate in \`crates/decodal-language-tools\` with \`wasm-pack\`.
|
||||
It currently exposes a comment-preserving formatter that is shared by the official playground and future editor/LSP tooling.
|
||||
|
||||
Use \`decodal-codemirror\` separately when you need CodeMirror 6 language support.
|
||||
Use \`decodal-wasm\` separately when you need to evaluate Decodal in a browser.
|
||||
|
||||
## Install
|
||||
|
||||
\`\`\`sh
|
||||
npm install decodal-language-tools
|
||||
\`\`\`
|
||||
|
||||
JSR:
|
||||
|
||||
\`\`\`sh
|
||||
deno add jsr:@hare/decodal-language-tools
|
||||
\`\`\`
|
||||
|
||||
## Usage
|
||||
|
||||
\`\`\`js
|
||||
import init, { formatSource } from 'decodal-language-tools';
|
||||
|
||||
await init();
|
||||
|
||||
const result = JSON.parse(formatSource('Server={# host\\nhost=String default "localhost";};'));
|
||||
|
||||
if (result.ok) {
|
||||
console.log(result.source);
|
||||
} else {
|
||||
console.error(result.error);
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
The exported functions return JSON strings so callers can handle diagnostics without depending on Rust data structures.
|
||||
`,
|
||||
);
|
||||
|
||||
writeFileSync(
|
||||
resolve(packageDir, 'jsr.json'),
|
||||
JSON.stringify(
|
||||
{
|
||||
name: '@hare/decodal-language-tools',
|
||||
version: '0.1.2',
|
||||
license: 'MIT',
|
||||
exports: './decodal_language_tools.js',
|
||||
publish: {
|
||||
include: [
|
||||
'README.md',
|
||||
'decodal_language_tools.js',
|
||||
'decodal_language_tools.d.ts',
|
||||
'decodal_language_tools_bg.wasm',
|
||||
'package.json',
|
||||
],
|
||||
},
|
||||
},
|
||||
null,
|
||||
2,
|
||||
) + '\n',
|
||||
);
|
||||
@@ -40,6 +40,14 @@ Production = Server & {
|
||||
<span>JSR package</span>
|
||||
<strong>jsr.io/@hare/decodal-wasm</strong>
|
||||
</a>
|
||||
<a href="https://www.npmjs.com/package/decodal-language-tools">
|
||||
<span>Language tools package</span>
|
||||
<strong>npmjs.com/package/decodal-language-tools</strong>
|
||||
</a>
|
||||
<a href="https://jsr.io/@hare/decodal-language-tools@0.1.2">
|
||||
<span>Language tools on JSR</span>
|
||||
<strong>jsr.io/@hare/decodal-language-tools</strong>
|
||||
</a>
|
||||
<a href="https://www.npmjs.com/package/decodal-codemirror">
|
||||
<span>CodeMirror package</span>
|
||||
<strong>npmjs.com/package/decodal-codemirror</strong>
|
||||
@@ -62,8 +70,8 @@ Production = Server & {
|
||||
<article class="home-card">
|
||||
<h2>Where it runs</h2>
|
||||
<p>
|
||||
Use the Rust crate for runtime embedding, the WASM package in browsers, CodeMirror/Lezer for the Web editor,
|
||||
and Tree-sitter for general editor integration.
|
||||
Use the Rust crate for runtime embedding, the WASM package in browsers, language-tools for formatting,
|
||||
CodeMirror/Lezer for the Web editor, and Tree-sitter for general editor integration.
|
||||
</p>
|
||||
</article>
|
||||
<article class="home-card">
|
||||
|
||||
@@ -15,6 +15,7 @@ import ManualLayout from '../layouts/ManualLayout.astro';
|
||||
</label>
|
||||
<button id="load-example" type="button">Load</button>
|
||||
<p id="status" class="status">Loading WASM...</p>
|
||||
<button id="format" disabled>Format</button>
|
||||
<button id="run" disabled>Run</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import init, { evaluateProject } from 'decodal-wasm';
|
||||
import initRuntime, { evaluateProject } from 'decodal-wasm';
|
||||
import initTools, { formatSource } from 'decodal-language-tools';
|
||||
import { EditorView, basicSetup } from 'codemirror';
|
||||
import { keymap } from '@codemirror/view';
|
||||
import { decodal } from 'decodal-codemirror';
|
||||
@@ -10,6 +11,7 @@ const starterProject = playgroundExamples[0];
|
||||
const editorHost = document.getElementById('editor');
|
||||
const output = document.getElementById('output');
|
||||
const run = document.getElementById('run');
|
||||
const formatButton = document.getElementById('format');
|
||||
const status = document.getElementById('status');
|
||||
const fileTree = document.getElementById('file-tree');
|
||||
const activeFile = document.getElementById('active-file');
|
||||
@@ -176,6 +178,20 @@ function execute() {
|
||||
output.classList.toggle('error', !result.ok);
|
||||
}
|
||||
|
||||
function formatActiveFile() {
|
||||
const result = JSON.parse(formatSource(getEditorText()));
|
||||
if (!result.ok) {
|
||||
output.textContent = result.error;
|
||||
output.classList.add('error');
|
||||
return;
|
||||
}
|
||||
setEditorText(result.source);
|
||||
project.files[project.activePath] = result.source;
|
||||
saveProject();
|
||||
output.textContent = 'Formatted.';
|
||||
output.classList.remove('error');
|
||||
}
|
||||
|
||||
function renderFileTree() {
|
||||
const tree = buildTree(Object.keys(project.files).sort());
|
||||
fileTree.replaceChildren(renderTreeList(tree.children));
|
||||
@@ -227,8 +243,9 @@ function compareNodes(a, b) {
|
||||
}
|
||||
|
||||
try {
|
||||
await init();
|
||||
await Promise.all([initRuntime(), initTools()]);
|
||||
run.disabled = false;
|
||||
formatButton.disabled = false;
|
||||
status.textContent = '';
|
||||
execute();
|
||||
} catch (error) {
|
||||
@@ -236,6 +253,7 @@ try {
|
||||
}
|
||||
|
||||
run.addEventListener('click', execute);
|
||||
formatButton.addEventListener('click', formatActiveFile);
|
||||
loadExample.addEventListener('click', () => {
|
||||
const example = playgroundExamples.find((item) => item.id === exampleSelect.value);
|
||||
if (!example) return;
|
||||
|
||||
Reference in New Issue
Block a user