/// import { computed, Default, handler, NAME, pattern, Stream, UI, type VNode, Writable, } from "commontools"; const VERSION = "v26"; function describeValue(val: any): string { const type = typeof val; let repr: string; if (val === undefined) repr = "undefined"; else if (val === null) repr = "null"; else if (val !== val) repr = "NaN"; else if (val === Infinity) repr = "Infinity"; else if (val === -Infinity) repr = "-Infinity"; else { try { repr = JSON.stringify(val, null, 2); } catch { repr = String(val); } } return `typeof: ${type}\n\nvalue: ${repr}`; } function nowTimestamp(): string { const d = new Date(); const pad = (n: number) => String(n).padStart(2, "0"); return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${ pad(d.getHours()) }:${pad(d.getMinutes())}:${pad(d.getSeconds())}`; } interface Input { value?: Writable>; inputText?: Writable>; errorMsg?: Writable>; evalTime?: Writable>; } interface Output { [NAME]: string; [UI]: VNode; value: any; evalAndStore: Stream; rerenderDisplay: Stream; } const evalAndStore = handler< void, { value: Writable; inputText: Writable; errorMsg: Writable; evalTime: Writable; } >((_, { value, inputText, errorMsg, evalTime }) => { const expr = inputText.get(); console.log(`[data-model-test] evaluating: ${expr}`); try { // Intentional use of `new Function` for testing: This pattern exists to // exercise the data model's serialization of arbitrary JS values. Patterns // run inside the sandboxed piece runtime, not the host. const result = new Function(`return (${expr})`)(); console.log(`[data-model-test] result:`, result); value.set(result); errorMsg.set(""); evalTime.set(nowTimestamp()); } catch (e: any) { console.log(`[data-model-test] error:`, e); errorMsg.set(String(e)); } }); const rerenderDisplay = handler< void, { value: Writable; evalTime: Writable } >( (_, { value, evalTime }) => { const v = value.get(); console.log(`[data-model-test] rerender from stored value:`, v); evalTime.set(nowTimestamp()); }, ); export default pattern( ({ value, inputText, errorMsg, evalTime }) => { console.log(`[data-model-test] loaded ${VERSION}`); const boundEvalAndStore = evalAndStore({ value, inputText, errorMsg, evalTime, }); const boundRerenderDisplay = rerenderDisplay({ value, evalTime }); const display = computed(() => { const ts = evalTime.get(); const desc = describeValue(value.get()); return `evaluated at: ${ts}\n${desc}`; }); return { [NAME]: "Data Model Test", [UI]: (

Data Model Test

Evaluate & Store Rerender Display
          {display}
          
{errorMsg}
{VERSION}
), value, evalAndStore: boundEvalAndStore, rerenderDisplay: boundRerenderDisplay, }; }, );