feat(dashboard): Rhai source formatter with Format button

AST-based pretty-printer: tab-indented, 100-col print width, normalized
operator spacing, predictable reflow of long argument lists, comments
preserved verbatim. Refuses to emit on a parse failure and returns the
first error, so the Edit-tab button mirrors the JSON Format UX —
inline `.error.inline` banner; doc untouched on failure.

Patch bump to `0.5.1` across Cargo.toml workspace.package, the
dashboard package.json, and the docs/versioning.md Current versions
table.

Bundle delta versus the previous build: +6 KB raw, +1.5 KB gzipped.
Cumulative since the start of this work: +28 KB raw, +7.3 KB gzipped —
well under the +100 KB budget.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-05-23 23:51:19 +02:00
parent 1dc53a0226
commit 267c40f59c
7 changed files with 592 additions and 4 deletions

View File

@@ -14,6 +14,7 @@
import { logLevelColor, statusColor } from '$lib/styles';
import { guessHostKind, guessPathKind, pathKindMismatchWarning } from '$lib/route-utils';
import CodeEditor from '$lib/CodeEditor.svelte';
import { format as formatRhai } from '$lib/rhai';
/// Pretty-print a JSON string in place, leaving it untouched if the
/// input doesn't parse. The error state is shown next to the button
@@ -67,6 +68,17 @@
let editableSource = $state('');
let savingSource = $state(false);
let saveSourceError = $state<string | null>(null);
let rhaiFormatError = $state<string | null>(null);
function formatRhaiSource() {
const r = formatRhai(editableSource);
if (r.ok) {
editableSource = r.text;
rhaiFormatError = null;
} else {
rhaiFormatError = `Parse error at offset ${r.error.offset}: ${r.error.message}`;
}
}
async function saveSource() {
if (!script) return;
@@ -384,8 +396,16 @@
{#if tab === 'edit'}
<div class="grid">
<section class="card">
<h2>Source</h2>
<header class="editor-header">
<h2>Source</h2>
<button type="button" class="ghost small" onclick={formatRhaiSource}>
Format
</button>
</header>
<CodeEditor bind:value={editableSource} language="rhai" minHeight="22rem" />
{#if rhaiFormatError}
<div class="error inline">{rhaiFormatError}</div>
{/if}
{#if saveSourceError}
<div class="error inline">{saveSourceError}</div>
{/if}
@@ -794,6 +814,14 @@
font-size: 0.85rem;
color: #cbd5e1;
}
.editor-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.editor-header h2 {
margin: 0;
}
button.link {
background: transparent;
color: #94a3b8;