executionId for code re-runs
This commit is contained in:
parent
724fb4956d
commit
eacc1adf1d
|
@ -14,6 +14,8 @@ import { SquiggleViewer } from "./SquiggleViewer";
|
||||||
export interface SquiggleChartProps {
|
export interface SquiggleChartProps {
|
||||||
/** The input string for squiggle */
|
/** The input string for squiggle */
|
||||||
code?: string;
|
code?: string;
|
||||||
|
/** Allows to re-run the code if code hasn't changed */
|
||||||
|
executionId?: number;
|
||||||
/** If the output requires monte carlo sampling, the amount of samples */
|
/** If the output requires monte carlo sampling, the amount of samples */
|
||||||
sampleCount?: number;
|
sampleCount?: number;
|
||||||
/** The amount of points returned to draw the distribution */
|
/** The amount of points returned to draw the distribution */
|
||||||
|
@ -59,6 +61,7 @@ const defaultOnChange = () => {};
|
||||||
export const SquiggleChart: React.FC<SquiggleChartProps> = React.memo(
|
export const SquiggleChart: React.FC<SquiggleChartProps> = React.memo(
|
||||||
({
|
({
|
||||||
code = "",
|
code = "",
|
||||||
|
executionId = 0,
|
||||||
environment,
|
environment,
|
||||||
onChange = defaultOnChange, // defaultOnChange must be constant, don't move its definition here
|
onChange = defaultOnChange, // defaultOnChange must be constant, don't move its definition here
|
||||||
height = 200,
|
height = 200,
|
||||||
|
|
|
@ -269,12 +269,19 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
|
||||||
[vars.sampleCount, vars.xyPointLength]
|
[vars.sampleCount, vars.xyPointLength]
|
||||||
);
|
);
|
||||||
|
|
||||||
const { run, autorunMode, setAutorunMode, isRunning, renderedCode } =
|
const {
|
||||||
useRunnerState(code);
|
run,
|
||||||
|
autorunMode,
|
||||||
|
setAutorunMode,
|
||||||
|
isRunning,
|
||||||
|
renderedCode,
|
||||||
|
executionId,
|
||||||
|
} = useRunnerState(code);
|
||||||
|
|
||||||
const squiggleChart = (
|
const squiggleChart = (
|
||||||
<SquiggleChart
|
<SquiggleChart
|
||||||
code={renderedCode}
|
code={renderedCode}
|
||||||
|
executionId={executionId}
|
||||||
environment={env}
|
environment={env}
|
||||||
{...vars}
|
{...vars}
|
||||||
bindings={defaultBindings}
|
bindings={defaultBindings}
|
||||||
|
|
|
@ -3,15 +3,16 @@ import { useEffect, useReducer } from "react";
|
||||||
type State = {
|
type State = {
|
||||||
autorunMode: boolean;
|
autorunMode: boolean;
|
||||||
renderedCode: string;
|
renderedCode: string;
|
||||||
isRunning: boolean;
|
// "prepared" is for rendering a spinner; "run" for executing squiggle code; then it gets back to "none" on the next render
|
||||||
|
runningState: "none" | "prepared" | "run";
|
||||||
executionId: number;
|
executionId: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildInitialState = (code: string) => ({
|
const buildInitialState = (code: string): State => ({
|
||||||
autorunMode: true,
|
autorunMode: true,
|
||||||
renderedCode: code,
|
renderedCode: code,
|
||||||
isRunning: false,
|
runningState: "none",
|
||||||
executionId: 0,
|
executionId: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
type Action =
|
type Action =
|
||||||
|
@ -41,18 +42,19 @@ const reducer = (state: State, action: Action): State => {
|
||||||
case "PREPARE_RUN":
|
case "PREPARE_RUN":
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
isRunning: true,
|
runningState: "prepared",
|
||||||
};
|
};
|
||||||
case "RUN":
|
case "RUN":
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
runningState: "run",
|
||||||
renderedCode: action.code,
|
renderedCode: action.code,
|
||||||
executionId: state.executionId + 1,
|
executionId: state.executionId + 1,
|
||||||
};
|
};
|
||||||
case "STOP_RUN":
|
case "STOP_RUN":
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
isRunning: false,
|
runningState: "none",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -61,21 +63,23 @@ export const useRunnerState = (code: string) => {
|
||||||
const [state, dispatch] = useReducer(reducer, buildInitialState(code));
|
const [state, dispatch] = useReducer(reducer, buildInitialState(code));
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (state.isRunning) {
|
if (state.runningState === "prepared") {
|
||||||
if (state.renderedCode !== code) {
|
dispatch({ type: "RUN", code });
|
||||||
dispatch({ type: "RUN", code });
|
} else if (state.runningState === "run") {
|
||||||
} else {
|
dispatch({ type: "STOP_RUN" });
|
||||||
dispatch({ type: "STOP_RUN" });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, [state.isRunning, state.renderedCode, code]);
|
}, [state.runningState, code]);
|
||||||
|
|
||||||
const run = () => {
|
const run = () => {
|
||||||
// The rest will be handled by dispatches above on following renders, but we need to update the spinner first.
|
// The rest will be handled by dispatches above on following renders, but we need to update the spinner first.
|
||||||
dispatch({ type: "PREPARE_RUN" });
|
dispatch({ type: "PREPARE_RUN" });
|
||||||
};
|
};
|
||||||
|
|
||||||
if (state.autorunMode && state.renderedCode !== code && !state.isRunning) {
|
if (
|
||||||
|
state.autorunMode &&
|
||||||
|
state.renderedCode !== code &&
|
||||||
|
state.runningState === "none"
|
||||||
|
) {
|
||||||
run();
|
run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +87,7 @@ export const useRunnerState = (code: string) => {
|
||||||
run,
|
run,
|
||||||
autorunMode: state.autorunMode,
|
autorunMode: state.autorunMode,
|
||||||
renderedCode: state.renderedCode,
|
renderedCode: state.renderedCode,
|
||||||
isRunning: state.isRunning,
|
isRunning: state.runningState !== "none",
|
||||||
executionId: state.executionId,
|
executionId: state.executionId,
|
||||||
setAutorunMode: (newValue: boolean) => {
|
setAutorunMode: (newValue: boolean) => {
|
||||||
dispatch({ type: "SET_AUTORUN_MODE", value: newValue, code });
|
dispatch({ type: "SET_AUTORUN_MODE", value: newValue, code });
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { useEffect, useMemo } from "react";
|
||||||
|
|
||||||
type SquiggleArgs<T extends ReturnType<typeof run | typeof runPartial>> = {
|
type SquiggleArgs<T extends ReturnType<typeof run | typeof runPartial>> = {
|
||||||
code: string;
|
code: string;
|
||||||
|
executionId?: number;
|
||||||
bindings?: bindings;
|
bindings?: bindings;
|
||||||
jsImports?: jsImports;
|
jsImports?: jsImports;
|
||||||
environment?: environment;
|
environment?: environment;
|
||||||
|
@ -21,7 +22,15 @@ const useSquiggleAny = <T extends ReturnType<typeof run | typeof runPartial>>(
|
||||||
) => {
|
) => {
|
||||||
const result: T = useMemo<T>(
|
const result: T = useMemo<T>(
|
||||||
() => f(args.code, args.bindings, args.environment, args.jsImports),
|
() => f(args.code, args.bindings, args.environment, args.jsImports),
|
||||||
[f, args.code, args.bindings, args.environment, args.jsImports]
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
[
|
||||||
|
f,
|
||||||
|
args.code,
|
||||||
|
args.bindings,
|
||||||
|
args.environment,
|
||||||
|
args.jsImports,
|
||||||
|
args.executionId,
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
const { onChange } = args;
|
const { onChange } = args;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user