import { createEffect, createSignal, onCleanup, Show } from "solid-js"; import { Digith } from "src/ui/Digith"; import { useProgram } from "src/ui/ProgramProvider"; import { CodeEditor } from "src/ui/Component/CodeEditor"; import { sourceText } from "source-region"; import { Program } from "src/lang/program"; import { V, Validation, letValidate } from "src/ui/validation"; import { validateSignalExprRaw } from "src/ui/validation/helpers"; import { updateDigith } from "src/ui/Scrowl/scrowlStore"; import { DigithError } from "src/ui/Digith/DigithError"; import { Value } from "src/lang/eval/value"; import { Val } from "src/ui/Component/Value"; import { externalSubscribe } from "src/lang/eval/signalValue"; type Input = { raw_body: string, } const validator: Validation = letValidate( (input) => ({ body: V.elseErr(validateSignalExprRaw(input.raw_body), err => ({ payload: { tag: "Parse", field: "body", err, src: sourceText(input.raw_body).fullRegion() }, ids: ["body"], tags: ["footer"], config: { title: "Signal Body" }, })), }), (fields, input) => { return V.ok({ body: fields.body, raw_body: input.raw_body }); } ); export function SignalDigith(props: { signal: Digith.Signal }) { const program = useProgram(); const [value, setValue] = createSignal(null); const [body, setBody] = createSignal(props.signal.raw_body); const [errors, setErrors] = createSignal([]); const isDirty = () => body() !== props.signal.raw_body; createEffect(() => { // TODO: Improve runtime error view try { const signal = Program.get_or_create_signal(program, props.signal.name); // TODO: Not sure about this one. Setting a signal in `setValue` is discouraged. setTimeout(() => setValue(signal.currentValue), 0); const cancel = externalSubscribe(signal, (newValue) => { setValue(newValue); }); onCleanup(cancel); } catch (e) { // TODO: setErrors... but how? Shouldn't this be independent of `errors`? console.log("Failed to link Signal: ", e); } }); function handleRedefine() { setErrors([]); const validRes = validator({ raw_body: body() }); if (validRes.tag === "errors") { setErrors(validRes.errors); return; } const updateData = validRes.value; const progRes = Program.updateSignal(program, props.signal.name, { body: updateData.body, raw_body: updateData.raw_body }); if (progRes.tag === "error") { setErrors([{ payload: { tag: "Program", err: progRes.error }, ids: ["program"], tags: ["footer"], config: { title: "Update Failed" }, }]); return; } // reloading the digith updateDigith(props.signal.id, { ...props.signal, raw_body: updateData.raw_body }); } // TODO return (
Signal {/* Dirty Indicator / Status */}
Synced}> ● Unsaved Changes
Name
Initializing...}> {(value) => (
)}
); }