import { bindings, environment, jsImports, run, runPartial, } from "@quri/squiggle-lang"; import { useEffect, useMemo, useState } from "react"; type SquiggleArgs> = { code: string; bindings?: bindings; jsImports?: jsImports; environment?: environment; onChange?: (expr: Extract["value"] | undefined) => void; }; const useSquiggleAny = >( args: SquiggleArgs, f: (...args: Parameters) => T ) => { const result: T = useMemo( () => f(args.code, args.bindings, args.environment, args.jsImports), [f, args.code, args.bindings, args.environment, args.jsImports] ); const { onChange } = args; useEffect(() => { onChange?.(result.tag === "Ok" ? result.value : undefined); }, [result, onChange]); return result; }; export const useSquigglePartial = ( args: SquiggleArgs> ) => { return useSquiggleAny(args, runPartial); }; export const useSquiggle = (args: SquiggleArgs>) => { return useSquiggleAny(args, run); }; type ControlledValueArgs = { value?: T; defaultValue: T; onChange?: (x: T) => void; }; export function useMaybeControlledValue( args: ControlledValueArgs ): [T, (x: T) => void] { let [uncontrolledValue, setUncontrolledValue] = useState(args.defaultValue); let value = args.value ?? uncontrolledValue; let onChange = (newValue: T) => { if (args.value === undefined) { // uncontrolled mode setUncontrolledValue(newValue); } args.onChange?.(newValue); }; return [value, onChange]; }