Respond to review comments

This commit is contained in:
Sam Nolan 2022-10-07 11:18:13 +11:00
parent 42e9ad810d
commit 85a8c06107
4 changed files with 44 additions and 23 deletions

View File

@ -2,7 +2,6 @@ import * as React from "react";
import { import {
SqValue, SqValue,
environment, environment,
defaultEnvironment,
resultMap, resultMap,
SqValueTag, SqValueTag,
SqProject, SqProject,
@ -56,22 +55,19 @@ export type SquiggleChartProps = {
// Props needed for a standalone execution // Props needed for a standalone execution
type StandaloneExecutionProps = { type StandaloneExecutionProps = {
/** Project must be undefined */
project?: undefined; project?: undefined;
/** Includes must be undefined */ continues?: undefined;
includes?: undefined;
/** The amount of points returned to draw the distribution, not needed if using a project */ /** The amount of points returned to draw the distribution, not needed if using a project */
environment?: environment; environment?: environment;
}; };
// Props needed when executing inside a project. // Props needed when executing inside a project.
type ProjectExecutionProps = { type ProjectExecutionProps = {
/** environment must be undefined (we don't set it here, users can set the environment outside the execution) */
environment?: undefined; environment?: undefined;
/** The project that this execution is part of */ /** The project that this execution is part of */
project: SqProject; project: SqProject;
/** What other squiggle sources from the project to include. Default none */ /** What other squiggle sources from the project to continue. Default [] */
includes?: string[]; continues?: string[];
}; };
const defaultOnChange = () => {}; const defaultOnChange = () => {};
const defaultImports: JsImports = {}; const defaultImports: JsImports = {};
@ -98,18 +94,24 @@ export const SquiggleChart: React.FC<SquiggleChartProps> = React.memo(
xAxisType = "number", xAxisType = "number",
distributionChartActions, distributionChartActions,
enableLocalSettings = false, enableLocalSettings = false,
project = SqProject.create(),
code, code,
includes = [], continues = [],
} = props; } = props;
const p = project ?? SqProject.create(); const p = React.useMemo(() => {
if (!project && props.environment) { if (props.project) {
return props.project;
} else {
const p = SqProject.create();
if (props.environment) {
p.setEnvironment(props.environment); p.setEnvironment(props.environment);
} }
return p;
}
}, [props.project, props.environment]);
const { result, bindings } = useSquiggle({ const { result, bindings } = useSquiggle({
includes, continues,
project: p, project: p,
code, code,
jsImports, jsImports,

View File

@ -1,6 +1,5 @@
import { SqProject } from "@quri/squiggle-lang/"; export { SqProject } from "@quri/squiggle-lang/";
export { SquiggleChart } from "./components/SquiggleChart"; export { SquiggleChart } from "./components/SquiggleChart";
export { SquiggleEditor } from "./components/SquiggleEditor"; export { SquiggleEditor } from "./components/SquiggleEditor";
export { SquigglePlayground } from "./components/SquigglePlayground"; export { SquigglePlayground } from "./components/SquigglePlayground";
export { SquiggleContainer } from "./components/SquiggleContainer"; export { SquiggleContainer } from "./components/SquiggleContainer";
export const newProject = () => SqProject.create();

View File

@ -8,7 +8,7 @@ type SquiggleArgs = {
executionId?: number; executionId?: number;
jsImports?: JsImports; jsImports?: JsImports;
project: SqProject; project: SqProject;
includes: string[]; continues: string[];
onChange?: (expr: SqValue | undefined, sourceName: string) => void; onChange?: (expr: SqValue | undefined, sourceName: string) => void;
}; };
@ -17,18 +17,20 @@ const importSourceName = (sourceName: string) => "imports-" + sourceName;
export const useSquiggle = (args: SquiggleArgs) => { export const useSquiggle = (args: SquiggleArgs) => {
const sourceName = useMemo(() => uuid.v4(), []); const sourceName = useMemo(() => uuid.v4(), []);
const env = args.project.getEnvironment();
const result = useMemo( const result = useMemo(
() => { () => {
const project = args.project; const project = args.project;
project.setSource(sourceName, args.code); project.setSource(sourceName, args.code);
let includes = args.includes; let continues = args.continues;
if (args.jsImports && Object.keys(args.jsImports).length) { if (args.jsImports && Object.keys(args.jsImports).length) {
const importsSource = jsImportsToSquiggleCode(args.jsImports); const importsSource = jsImportsToSquiggleCode(args.jsImports);
project.setSource(importSourceName(sourceName), importsSource); project.setSource(importSourceName(sourceName), importsSource);
includes.push(importSourceName(sourceName)); continues = args.continues.concat(importSourceName(sourceName));
} }
project.setContinues(sourceName, includes); project.setContinues(sourceName, continues);
project.run(sourceName); project.run(sourceName);
const result = project.getResult(sourceName); const result = project.getResult(sourceName);
const bindings = project.getBindings(sourceName); const bindings = project.getBindings(sourceName);
@ -43,8 +45,9 @@ export const useSquiggle = (args: SquiggleArgs) => {
args.jsImports, args.jsImports,
args.executionId, args.executionId,
sourceName, sourceName,
args.includes, args.continues,
args.project, args.project,
env,
] ]
); );
@ -61,7 +64,7 @@ export const useSquiggle = (args: SquiggleArgs) => {
return () => { return () => {
args.project.removeSource(sourceName); args.project.removeSource(sourceName);
if (args.project.getSource(importSourceName(sourceName))) if (args.project.getSource(importSourceName(sourceName)))
args.project.removeSource(sourceName); args.project.removeSource(importSourceName(sourceName));
}; };
}, [args.project, sourceName]); }, [args.project, sourceName]);

View File

@ -4,7 +4,7 @@ import "@testing-library/jest-dom";
import { SquiggleChart } from "../src/index"; import { SquiggleChart } from "../src/index";
import { SqProject } from "@quri/squiggle-lang"; import { SqProject } from "@quri/squiggle-lang";
test("Creates and cleans up source with no name", async () => { test("Creates and cleans up source", async () => {
const project = SqProject.create(); const project = SqProject.create();
const { unmount } = render( const { unmount } = render(
@ -20,3 +20,20 @@ test("Creates and cleans up source with no name", async () => {
expect(project.getSourceIds().length).toBe(0); expect(project.getSourceIds().length).toBe(0);
expect(project.getSource(sourceId)).toBe(undefined); expect(project.getSource(sourceId)).toBe(undefined);
}); });
test("Creates and cleans up source and imports", async () => {
const project = SqProject.create();
const { unmount } = render(
<SquiggleChart
code={"normal($x, 1)"}
project={project}
jsImports={{ x: 3 }}
/>
);
expect(project.getSourceIds().length).toBe(2);
unmount();
expect(project.getSourceIds()).toStrictEqual([]);
});