Compare commits
No commits in common. "develop" and "experiment-10.0rc1" have entirely different histories.
develop
...
experiment
|
@ -65,12 +65,6 @@ turbo run build --filter=@quri/squiggle-components
|
||||||
|
|
||||||
You can also run specific npm scripts for the package you're working on. See `packages/*/README.md` for the details.
|
You can also run specific npm scripts for the package you're working on. See `packages/*/README.md` for the details.
|
||||||
|
|
||||||
# NixOS users
|
|
||||||
|
|
||||||
This repository requires the use of bundled binaries from node_modules, which
|
|
||||||
are not linked statically. The easiest way to get them working is to enable
|
|
||||||
[nix-ld](https://github.com/Mic92/nix-ld).
|
|
||||||
|
|
||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
See `CONTRIBUTING.md`.
|
See `CONTRIBUTING.md`.
|
||||||
|
|
18
nixos.sh
Executable file
18
nixos.sh
Executable file
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# This script is only relevant if you're rolling nixos.
|
||||||
|
|
||||||
|
# Esy (a bisect_ppx dependency/build tool) is borked on nixos without using an FHS shell. https://github.com/esy/esy/issues/858
|
||||||
|
# We need to patchelf rescript executables. https://github.com/NixOS/nixpkgs/issues/107375
|
||||||
|
set -x
|
||||||
|
|
||||||
|
fhsShellName="squiggle-fhs-development"
|
||||||
|
fhsShellDotNix="{pkgs ? import <nixpkgs> {} }: (pkgs.buildFHSUserEnv { name = \"${fhsShellName}\"; targetPkgs = pkgs: [pkgs.yarn pkgs.glibc]; runScript = \"yarn\"; }).env"
|
||||||
|
nix-shell - <<<"$fhsShellDotNix"
|
||||||
|
|
||||||
|
theLd=$(patchelf --print-interpreter $(which mkdir))
|
||||||
|
patchelf --set-interpreter $theLd ./node_modules/gentype/gentype.exe
|
||||||
|
patchelf --set-interpreter $theLd ./node_modules/rescript/linux/*.exe
|
||||||
|
patchelf --set-interpreter $theLd ./node_modules/bisect_ppx/ppx
|
||||||
|
patchelf --set-interpreter $theLd ./node_modules/bisect_ppx/bisect-ppx-report
|
||||||
|
theSo=$(find /nix/store/*$fhsShellName*/lib64 -name libstdc++.so.6 | head -n 1)
|
||||||
|
patchelf --replace-needed libstdc++.so.6 $theSo ./node_modules/rescript/linux/ninja.exe
|
|
@ -24,7 +24,7 @@ export const Alert: React.FC<{
|
||||||
children,
|
children,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className={clsx("rounded-md p-4", backgroundColor)} role="status">
|
<div className={clsx("rounded-md p-4", backgroundColor)}>
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<Icon
|
<Icon
|
||||||
className={clsx("h-5 w-5 flex-shrink-0", iconColor)}
|
className={clsx("h-5 w-5 flex-shrink-0", iconColor)}
|
||||||
|
|
|
@ -55,7 +55,10 @@ export const CodeEditor: FC<CodeEditorProps> = ({
|
||||||
editorProps={{
|
editorProps={{
|
||||||
$blockScrolling: true,
|
$blockScrolling: true,
|
||||||
}}
|
}}
|
||||||
setOptions={{}}
|
setOptions={{
|
||||||
|
enableBasicAutocompletion: false,
|
||||||
|
enableLiveAutocompletion: false,
|
||||||
|
}}
|
||||||
commands={[
|
commands={[
|
||||||
{
|
{
|
||||||
name: "submit",
|
name: "submit",
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {
|
import { SqValue, environment, SqProject } from "@quri/squiggle-lang";
|
||||||
SqValue,
|
|
||||||
environment,
|
|
||||||
SqProject,
|
|
||||||
defaultEnvironment,
|
|
||||||
} from "@quri/squiggle-lang";
|
|
||||||
import { useSquiggle } from "../lib/hooks";
|
import { useSquiggle } from "../lib/hooks";
|
||||||
import { SquiggleViewer } from "./SquiggleViewer";
|
import { SquiggleViewer } from "./SquiggleViewer";
|
||||||
import { JsImports } from "../lib/jsImports";
|
import { JsImports } from "../lib/jsImports";
|
||||||
|
@ -71,6 +66,7 @@ type ProjectExecutionProps = {
|
||||||
};
|
};
|
||||||
const defaultOnChange = () => {};
|
const defaultOnChange = () => {};
|
||||||
const defaultImports: JsImports = {};
|
const defaultImports: JsImports = {};
|
||||||
|
const defaultContinues: string[] = [];
|
||||||
|
|
||||||
export const splitSquiggleChartSettings = (props: SquiggleChartProps) => {
|
export const splitSquiggleChartSettings = (props: SquiggleChartProps) => {
|
||||||
const {
|
const {
|
||||||
|
@ -124,15 +120,24 @@ export const SquiggleChart: React.FC<SquiggleChartProps> = React.memo(
|
||||||
width,
|
width,
|
||||||
height = 200,
|
height = 200,
|
||||||
enableLocalSettings = false,
|
enableLocalSettings = false,
|
||||||
continues,
|
continues = defaultContinues,
|
||||||
project,
|
|
||||||
environment,
|
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const p = React.useMemo(() => {
|
||||||
|
if (props.project) {
|
||||||
|
return props.project;
|
||||||
|
} else {
|
||||||
|
const p = SqProject.create();
|
||||||
|
if (props.environment) {
|
||||||
|
p.setEnvironment(props.environment);
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}, [props.project, props.environment]);
|
||||||
|
|
||||||
const resultAndBindings = useSquiggle({
|
const resultAndBindings = useSquiggle({
|
||||||
environment,
|
|
||||||
continues,
|
continues,
|
||||||
project,
|
project: p,
|
||||||
code,
|
code,
|
||||||
jsImports,
|
jsImports,
|
||||||
onChange,
|
onChange,
|
||||||
|
@ -148,9 +153,7 @@ export const SquiggleChart: React.FC<SquiggleChartProps> = React.memo(
|
||||||
height={height}
|
height={height}
|
||||||
distributionPlotSettings={distributionPlotSettings}
|
distributionPlotSettings={distributionPlotSettings}
|
||||||
chartSettings={chartSettings}
|
chartSettings={chartSettings}
|
||||||
environment={
|
environment={p.getEnvironment()}
|
||||||
project ? project.getEnvironment() : environment ?? defaultEnvironment
|
|
||||||
}
|
|
||||||
enableLocalSettings={enableLocalSettings}
|
enableLocalSettings={enableLocalSettings}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -54,13 +54,17 @@ export const SquiggleEditor: React.FC<SquiggleEditorProps> = (props) => {
|
||||||
width,
|
width,
|
||||||
height = 200,
|
height = 200,
|
||||||
enableLocalSettings = false,
|
enableLocalSettings = false,
|
||||||
continues,
|
|
||||||
project,
|
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const project = React.useMemo(() => {
|
||||||
|
const p = SqProject.create();
|
||||||
|
if (environment) {
|
||||||
|
p.setEnvironment(environment);
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}, [environment]);
|
||||||
|
|
||||||
const resultAndBindings = useSquiggle({
|
const resultAndBindings = useSquiggle({
|
||||||
environment,
|
|
||||||
continues,
|
|
||||||
code,
|
code,
|
||||||
project,
|
project,
|
||||||
jsImports,
|
jsImports,
|
||||||
|
|
|
@ -251,8 +251,6 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
|
||||||
onSettingsChange,
|
onSettingsChange,
|
||||||
showEditor = true,
|
showEditor = true,
|
||||||
showShareButton = false,
|
showShareButton = false,
|
||||||
continues,
|
|
||||||
project,
|
|
||||||
}) => {
|
}) => {
|
||||||
const [code, setCode] = useMaybeControlledValue({
|
const [code, setCode] = useMaybeControlledValue({
|
||||||
value: controlledCode,
|
value: controlledCode,
|
||||||
|
@ -307,9 +305,15 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
|
||||||
executionId,
|
executionId,
|
||||||
} = useRunnerState(code);
|
} = useRunnerState(code);
|
||||||
|
|
||||||
|
const project = React.useMemo(() => {
|
||||||
|
const p = SqProject.create();
|
||||||
|
if (environment) {
|
||||||
|
p.setEnvironment(environment);
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}, [environment]);
|
||||||
|
|
||||||
const resultAndBindings = useSquiggle({
|
const resultAndBindings = useSquiggle({
|
||||||
environment,
|
|
||||||
continues,
|
|
||||||
code: renderedCode,
|
code: renderedCode,
|
||||||
project,
|
project,
|
||||||
jsImports: imports,
|
jsImports: imports,
|
||||||
|
|
|
@ -45,7 +45,7 @@ export const VariableBox: React.FC<VariableBoxProps> = ({
|
||||||
: location.path.items[location.path.items.length - 1];
|
: location.path.items[location.path.items.length - 1];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div role={isTopLevel ? "status" : undefined}>
|
<div>
|
||||||
<header className="inline-flex space-x-1">
|
<header className="inline-flex space-x-1">
|
||||||
<Tooltip text={heading}>
|
<Tooltip text={heading}>
|
||||||
<span
|
<span
|
||||||
|
|
|
@ -4,18 +4,16 @@ import {
|
||||||
SqProject,
|
SqProject,
|
||||||
SqRecord,
|
SqRecord,
|
||||||
SqValue,
|
SqValue,
|
||||||
environment,
|
|
||||||
} from "@quri/squiggle-lang";
|
} from "@quri/squiggle-lang";
|
||||||
import { useEffect, useMemo } from "react";
|
import { useEffect, useMemo } from "react";
|
||||||
import { JsImports, jsImportsToSquiggleCode } from "../jsImports";
|
import { JsImports, jsImportsToSquiggleCode } from "../jsImports";
|
||||||
import * as uuid from "uuid";
|
import * as uuid from "uuid";
|
||||||
|
|
||||||
type SquiggleArgs = {
|
type SquiggleArgs = {
|
||||||
environment?: environment;
|
|
||||||
code: string;
|
code: string;
|
||||||
executionId?: number;
|
executionId?: number;
|
||||||
jsImports?: JsImports;
|
jsImports?: JsImports;
|
||||||
project?: SqProject;
|
project: SqProject;
|
||||||
continues?: string[];
|
continues?: string[];
|
||||||
onChange?: (expr: SqValue | undefined, sourceName: string) => void;
|
onChange?: (expr: SqValue | undefined, sourceName: string) => void;
|
||||||
};
|
};
|
||||||
|
@ -29,25 +27,15 @@ const importSourceName = (sourceName: string) => "imports-" + sourceName;
|
||||||
const defaultContinues = [];
|
const defaultContinues = [];
|
||||||
|
|
||||||
export const useSquiggle = (args: SquiggleArgs): ResultAndBindings => {
|
export const useSquiggle = (args: SquiggleArgs): ResultAndBindings => {
|
||||||
const project = useMemo(() => {
|
|
||||||
if (args.project) {
|
|
||||||
return args.project;
|
|
||||||
} else {
|
|
||||||
const p = SqProject.create();
|
|
||||||
if (args.environment) {
|
|
||||||
p.setEnvironment(args.environment);
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
}, [args.project, args.environment]);
|
|
||||||
|
|
||||||
const sourceName = useMemo(() => uuid.v4(), []);
|
const sourceName = useMemo(() => uuid.v4(), []);
|
||||||
|
|
||||||
const env = project.getEnvironment();
|
const env = args.project.getEnvironment();
|
||||||
const continues = args.continues || defaultContinues;
|
const continues = args.continues || defaultContinues;
|
||||||
|
|
||||||
const result = useMemo(
|
const result = useMemo(
|
||||||
() => {
|
() => {
|
||||||
|
const project = args.project;
|
||||||
|
|
||||||
project.setSource(sourceName, args.code);
|
project.setSource(sourceName, args.code);
|
||||||
let fullContinues = continues;
|
let fullContinues = continues;
|
||||||
if (args.jsImports && Object.keys(args.jsImports).length) {
|
if (args.jsImports && Object.keys(args.jsImports).length) {
|
||||||
|
@ -71,7 +59,7 @@ export const useSquiggle = (args: SquiggleArgs): ResultAndBindings => {
|
||||||
args.executionId,
|
args.executionId,
|
||||||
sourceName,
|
sourceName,
|
||||||
continues,
|
continues,
|
||||||
project,
|
args.project,
|
||||||
env,
|
env,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
@ -87,11 +75,11 @@ export const useSquiggle = (args: SquiggleArgs): ResultAndBindings => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
project.removeSource(sourceName);
|
args.project.removeSource(sourceName);
|
||||||
if (project.getSource(importSourceName(sourceName)))
|
if (args.project.getSource(importSourceName(sourceName)))
|
||||||
project.removeSource(importSourceName(sourceName));
|
args.project.removeSource(importSourceName(sourceName));
|
||||||
};
|
};
|
||||||
}, [project, sourceName]);
|
}, [args.project, sourceName]);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,14 +1,9 @@
|
||||||
import { render, screen } from "@testing-library/react";
|
import { render } from "@testing-library/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import "@testing-library/jest-dom";
|
import "@testing-library/jest-dom";
|
||||||
import {
|
import { SquiggleChart } from "../src/index";
|
||||||
SquiggleChart,
|
|
||||||
SquiggleEditor,
|
|
||||||
SquigglePlayground,
|
|
||||||
} from "../src/index";
|
|
||||||
import { SqProject } from "@quri/squiggle-lang";
|
|
||||||
|
|
||||||
test("Chart logs nothing on render", async () => {
|
test("Logs nothing on render", async () => {
|
||||||
const { unmount } = render(<SquiggleChart code={"normal(0, 1)"} />);
|
const { unmount } = render(<SquiggleChart code={"normal(0, 1)"} />);
|
||||||
unmount();
|
unmount();
|
||||||
|
|
||||||
|
@ -16,38 +11,3 @@ test("Chart logs nothing on render", async () => {
|
||||||
expect(console.warn).not.toBeCalled();
|
expect(console.warn).not.toBeCalled();
|
||||||
expect(console.error).not.toBeCalled();
|
expect(console.error).not.toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Editor logs nothing on render", async () => {
|
|
||||||
const { unmount } = render(<SquiggleEditor code={"normal(0, 1)"} />);
|
|
||||||
unmount();
|
|
||||||
|
|
||||||
expect(console.log).not.toBeCalled();
|
|
||||||
expect(console.warn).not.toBeCalled();
|
|
||||||
expect(console.error).not.toBeCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
test("Project dependencies work in editors", async () => {
|
|
||||||
const project = SqProject.create();
|
|
||||||
|
|
||||||
render(<SquiggleEditor code={"x = 1"} project={project} />);
|
|
||||||
const source = project.getSourceIds()[0];
|
|
||||||
const { container } = render(
|
|
||||||
<SquiggleEditor code={"x + 1"} project={project} continues={[source]} />
|
|
||||||
);
|
|
||||||
expect(container).toHaveTextContent("2");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("Project dependencies work in playgrounds", async () => {
|
|
||||||
const project = SqProject.create();
|
|
||||||
project.setSource("depend", "x = 1");
|
|
||||||
|
|
||||||
render(
|
|
||||||
<SquigglePlayground
|
|
||||||
code={"x + 1"}
|
|
||||||
project={project}
|
|
||||||
continues={["depend"]}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
// We must await here because SquigglePlayground loads results asynchronously
|
|
||||||
expect(await screen.findByRole("status")).toHaveTextContent("2");
|
|
||||||
});
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user