Merge branch 'develop' into project-component
This commit is contained in:
commit
2be9d274f2
16
.github/workflows/ci.yml
vendored
16
.github/workflows/ci.yml
vendored
|
@ -26,27 +26,27 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- id: skip_lang_check
|
- id: skip_lang_check
|
||||||
name: Check if the changes are about squiggle-lang src files
|
name: Check if the changes are about squiggle-lang src files
|
||||||
uses: fkirc/skip-duplicate-actions@v5.1.0
|
uses: fkirc/skip-duplicate-actions@v5.2.0
|
||||||
with:
|
with:
|
||||||
paths: '["packages/squiggle-lang/**"]'
|
paths: '["packages/squiggle-lang/**"]'
|
||||||
- id: skip_components_check
|
- id: skip_components_check
|
||||||
name: Check if the changes are about components src files
|
name: Check if the changes are about components src files
|
||||||
uses: fkirc/skip-duplicate-actions@v5.1.0
|
uses: fkirc/skip-duplicate-actions@v5.2.0
|
||||||
with:
|
with:
|
||||||
paths: '["packages/components/**"]'
|
paths: '["packages/components/**"]'
|
||||||
- id: skip_website_check
|
- id: skip_website_check
|
||||||
name: Check if the changes are about website src files
|
name: Check if the changes are about website src files
|
||||||
uses: fkirc/skip-duplicate-actions@v5.1.0
|
uses: fkirc/skip-duplicate-actions@v5.2.0
|
||||||
with:
|
with:
|
||||||
paths: '["packages/website/**"]'
|
paths: '["packages/website/**"]'
|
||||||
- id: skip_vscodeext_check
|
- id: skip_vscodeext_check
|
||||||
name: Check if the changes are about vscode extension src files
|
name: Check if the changes are about vscode extension src files
|
||||||
uses: fkirc/skip-duplicate-actions@v5.1.0
|
uses: fkirc/skip-duplicate-actions@v5.2.0
|
||||||
with:
|
with:
|
||||||
paths: '["packages/vscode-ext/**"]'
|
paths: '["packages/vscode-ext/**"]'
|
||||||
- id: skip_cli_check
|
- id: skip_cli_check
|
||||||
name: Check if the changes are about cli src files
|
name: Check if the changes are about cli src files
|
||||||
uses: fkirc/skip-duplicate-actions@v5.1.0
|
uses: fkirc/skip-duplicate-actions@v5.2.0
|
||||||
with:
|
with:
|
||||||
paths: '["packages/cli/**"]'
|
paths: '["packages/cli/**"]'
|
||||||
|
|
||||||
|
@ -116,8 +116,8 @@ jobs:
|
||||||
dry: true
|
dry: true
|
||||||
prettier_options: --check packages/components --ignore-path packages/components/.prettierignore
|
prettier_options: --check packages/components --ignore-path packages/components/.prettierignore
|
||||||
|
|
||||||
components-bundle-build:
|
components-bundle-build-test:
|
||||||
name: Components bundle and build
|
name: Components bundle, build and test
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: pre_check
|
needs: pre_check
|
||||||
if: ${{ (needs.pre_check.outputs.should_skip_components != 'true') || (needs.pre_check.outputs.should_skip_lang != 'true') }}
|
if: ${{ (needs.pre_check.outputs.should_skip_components != 'true') || (needs.pre_check.outputs.should_skip_lang != 'true') }}
|
||||||
|
@ -135,6 +135,8 @@ jobs:
|
||||||
run: yarn bundle
|
run: yarn bundle
|
||||||
- name: Build storybook
|
- name: Build storybook
|
||||||
run: yarn build
|
run: yarn build
|
||||||
|
- name: Test components
|
||||||
|
run: yarn test
|
||||||
|
|
||||||
website-lint:
|
website-lint:
|
||||||
name: Website lint
|
name: Website lint
|
||||||
|
|
10
.github/workflows/release-please.yml
vendored
10
.github/workflows/release-please.yml
vendored
|
@ -18,27 +18,27 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- id: skip_lang_check
|
- id: skip_lang_check
|
||||||
name: Check if the changes are about squiggle-lang src files
|
name: Check if the changes are about squiggle-lang src files
|
||||||
uses: fkirc/skip-duplicate-actions@v5.1.0
|
uses: fkirc/skip-duplicate-actions@v5.2.0
|
||||||
with:
|
with:
|
||||||
paths: '["packages/squiggle-lang/**"]'
|
paths: '["packages/squiggle-lang/**"]'
|
||||||
- id: skip_components_check
|
- id: skip_components_check
|
||||||
name: Check if the changes are about components src files
|
name: Check if the changes are about components src files
|
||||||
uses: fkirc/skip-duplicate-actions@v5.1.0
|
uses: fkirc/skip-duplicate-actions@v5.2.0
|
||||||
with:
|
with:
|
||||||
paths: '["packages/components/**"]'
|
paths: '["packages/components/**"]'
|
||||||
- id: skip_website_check
|
- id: skip_website_check
|
||||||
name: Check if the changes are about website src files
|
name: Check if the changes are about website src files
|
||||||
uses: fkirc/skip-duplicate-actions@v5.1.0
|
uses: fkirc/skip-duplicate-actions@v5.2.0
|
||||||
with:
|
with:
|
||||||
paths: '["packages/website/**"]'
|
paths: '["packages/website/**"]'
|
||||||
- id: skip_vscodeext_check
|
- id: skip_vscodeext_check
|
||||||
name: Check if the changes are about vscode extension src files
|
name: Check if the changes are about vscode extension src files
|
||||||
uses: fkirc/skip-duplicate-actions@v5.1.0
|
uses: fkirc/skip-duplicate-actions@v5.2.0
|
||||||
with:
|
with:
|
||||||
paths: '["packages/vscode-ext/**"]'
|
paths: '["packages/vscode-ext/**"]'
|
||||||
- id: skip_cli_check
|
- id: skip_cli_check
|
||||||
name: Check if the changes are about cli src files
|
name: Check if the changes are about cli src files
|
||||||
uses: fkirc/skip-duplicate-actions@v5.1.0
|
uses: fkirc/skip-duplicate-actions@v5.2.0
|
||||||
with:
|
with:
|
||||||
paths: '["packages/cli/**"]'
|
paths: '["packages/cli/**"]'
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": "^5.0.1",
|
"chalk": "^5.0.1",
|
||||||
"chokidar": "^3.5.3",
|
"chokidar": "^3.5.3",
|
||||||
"commander": "^9.4.0",
|
"commander": "^9.4.1",
|
||||||
"fs": "^0.0.1-security",
|
"fs": "^0.0.1-security",
|
||||||
"glob": "^8.0.3",
|
"glob": "^8.0.3",
|
||||||
"indent-string": "^5.0.0"
|
"indent-string": "^5.0.0"
|
||||||
|
|
6
packages/components/jest.config.js
Normal file
6
packages/components/jest.config.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
||||||
|
module.exports = {
|
||||||
|
preset: "ts-jest",
|
||||||
|
setupFilesAfterEnv: ["<rootDir>/test/setup.js"],
|
||||||
|
testEnvironment: "jsdom",
|
||||||
|
};
|
|
@ -1,18 +1,18 @@
|
||||||
{
|
{
|
||||||
"name": "@quri/squiggle-components",
|
"name": "@quri/squiggle-components",
|
||||||
"version": "0.5.0-alpha.2",
|
"version": "0.5.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@floating-ui/react-dom": "^1.0.0",
|
"@floating-ui/react-dom": "^1.0.0",
|
||||||
"@floating-ui/react-dom-interactions": "^0.10.1",
|
"@floating-ui/react-dom-interactions": "^0.10.1",
|
||||||
"@headlessui/react": "^1.7.2",
|
"@headlessui/react": "^1.7.3",
|
||||||
"@heroicons/react": "^1.0.6",
|
"@heroicons/react": "^1.0.6",
|
||||||
"@hookform/resolvers": "^2.9.8",
|
"@hookform/resolvers": "^2.9.8",
|
||||||
"@quri/squiggle-lang": "^0.5.0-alpha.2",
|
"@quri/squiggle-lang": "^0.5.0",
|
||||||
"@react-hook/size": "^2.1.2",
|
"@react-hook/size": "^2.1.2",
|
||||||
"@types/uuid": "^8.3.4",
|
"@types/uuid": "^8.3.4",
|
||||||
"clsx": "^1.2.1",
|
"clsx": "^1.2.1",
|
||||||
"framer-motion": "^7.4.0",
|
"framer-motion": "^7.5.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"react": "^18.1.0",
|
"react": "^18.1.0",
|
||||||
"react-ace": "^10.1.0",
|
"react-ace": "^10.1.0",
|
||||||
|
@ -40,12 +40,16 @@
|
||||||
"@testing-library/react": "^13.4.0",
|
"@testing-library/react": "^13.4.0",
|
||||||
"@testing-library/user-event": "^14.4.3",
|
"@testing-library/user-event": "^14.4.3",
|
||||||
"@types/jest": "^27.5.0",
|
"@types/jest": "^27.5.0",
|
||||||
"@types/lodash": "^4.14.185",
|
"@types/lodash": "^4.14.186",
|
||||||
"@types/node": "^18.7.22",
|
"@types/node": "^18.8.0",
|
||||||
"@types/react": "^18.0.21",
|
"@types/react": "^18.0.21",
|
||||||
"@types/styled-components": "^5.1.26",
|
"@types/styled-components": "^5.1.26",
|
||||||
"@types/webpack": "^5.28.0",
|
"@types/webpack": "^5.28.0",
|
||||||
|
"canvas": "^2.10.1",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
|
"jest": "^29.0.3",
|
||||||
|
"jest-environment-jsdom": "^29.0.3",
|
||||||
|
"jsdom": "^20.0.0",
|
||||||
"mini-css-extract-plugin": "^2.6.1",
|
"mini-css-extract-plugin": "^2.6.1",
|
||||||
"postcss-cli": "^10.0.0",
|
"postcss-cli": "^10.0.0",
|
||||||
"postcss-import": "^15.0.0",
|
"postcss-import": "^15.0.0",
|
||||||
|
@ -55,9 +59,10 @@
|
||||||
"react-scripts": "^5.0.1",
|
"react-scripts": "^5.0.1",
|
||||||
"style-loader": "^3.3.1",
|
"style-loader": "^3.3.1",
|
||||||
"tailwindcss": "^3.1.8",
|
"tailwindcss": "^3.1.8",
|
||||||
"ts-loader": "^9.4.0",
|
"ts-jest": "^29.0.2",
|
||||||
|
"ts-loader": "^9.4.1",
|
||||||
"tsconfig-paths-webpack-plugin": "^4.0.0",
|
"tsconfig-paths-webpack-plugin": "^4.0.0",
|
||||||
"typescript": "^4.8.3",
|
"typescript": "^4.8.4",
|
||||||
"web-vitals": "^3.0.2",
|
"web-vitals": "^3.0.2",
|
||||||
"webpack": "^5.74.0",
|
"webpack": "^5.74.0",
|
||||||
"webpack-cli": "^4.10.0",
|
"webpack-cli": "^4.10.0",
|
||||||
|
@ -77,7 +82,9 @@
|
||||||
"all": "yarn bundle && yarn build",
|
"all": "yarn bundle && yarn build",
|
||||||
"lint": "prettier --check .",
|
"lint": "prettier --check .",
|
||||||
"format": "prettier --write .",
|
"format": "prettier --write .",
|
||||||
"prepack": "yarn run build:cjs && yarn run bundle"
|
"prepack": "yarn run build:cjs && yarn run bundle",
|
||||||
|
"test": "jest",
|
||||||
|
"test:debug": "node --inspect-brk node_modules/.bin/jest --runInBand"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": [
|
"extends": [
|
||||||
|
|
|
@ -83,18 +83,32 @@ export const DistributionChart: React.FC<DistributionChartProps> = (props) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const spec = buildVegaSpec(props);
|
const domain = shapes.value.flatMap((shape) =>
|
||||||
|
shape.discrete.concat(shape.continuous)
|
||||||
|
);
|
||||||
|
|
||||||
let widthProp = width ? width : size.width;
|
const spec = buildVegaSpec({
|
||||||
|
...props,
|
||||||
|
minX: props.minX ?? Math.min(...domain.map((x) => x.x)),
|
||||||
|
maxX: props.minX ?? Math.max(...domain.map((x) => x.x)),
|
||||||
|
maxY: Math.max(...domain.map((x) => x.y)),
|
||||||
|
});
|
||||||
|
|
||||||
|
// I think size.width is sometimes not finite due to the component not being in a visible context
|
||||||
|
// This occurs during testing
|
||||||
|
let widthProp = width
|
||||||
|
? width
|
||||||
|
: Number.isFinite(size.width)
|
||||||
|
? size.width
|
||||||
|
: 400;
|
||||||
if (widthProp < 20) {
|
if (widthProp < 20) {
|
||||||
console.warn(
|
console.warn(
|
||||||
`Width of Distribution is set to ${widthProp}, which is too small`
|
`Width of Distribution is set to ${widthProp}, which is too small`
|
||||||
);
|
);
|
||||||
widthProp = 20;
|
widthProp = 20;
|
||||||
}
|
}
|
||||||
const domain = shapes.value.flatMap((shape) =>
|
|
||||||
shape.discrete.concat(shape.continuous)
|
const vegaData = { data: shapes.value, samples };
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ width: widthProp }}>
|
<div style={{ width: widthProp }}>
|
||||||
|
@ -105,7 +119,7 @@ export const DistributionChart: React.FC<DistributionChartProps> = (props) => {
|
||||||
) : (
|
) : (
|
||||||
<Vega
|
<Vega
|
||||||
spec={spec}
|
spec={spec}
|
||||||
data={{ data: shapes.value, domain, samples }}
|
data={vegaData}
|
||||||
width={widthProp - 10}
|
width={widthProp - 10}
|
||||||
height={height}
|
height={height}
|
||||||
actions={actions}
|
actions={actions}
|
||||||
|
|
|
@ -298,7 +298,9 @@ export const ExpressionViewer: React.FC<Props> = ({ value, width }) => {
|
||||||
{() => (
|
{() => (
|
||||||
<div>
|
<div>
|
||||||
<span>No display for type: </span>{" "}
|
<span>No display for type: </span>{" "}
|
||||||
<span className="font-semibold text-slate-600">{(value as {tag: string}).tag}</span>
|
<span className="font-semibold text-slate-600">
|
||||||
|
{(value as { tag: string }).tag}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</VariableList>
|
</VariableList>
|
||||||
|
|
|
@ -26,7 +26,6 @@ export const linearXScale: LinearScale = {
|
||||||
range: "width",
|
range: "width",
|
||||||
zero: false,
|
zero: false,
|
||||||
nice: false,
|
nice: false,
|
||||||
domain: { data: "domain", field: "x" },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const logXScale: LogScale = {
|
export const logXScale: LogScale = {
|
||||||
|
@ -37,7 +36,6 @@ export const logXScale: LogScale = {
|
||||||
base: 10,
|
base: 10,
|
||||||
nice: false,
|
nice: false,
|
||||||
clamp: true,
|
clamp: true,
|
||||||
domain: { data: "domain", field: "x" },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const timeXScale: TimeScale = {
|
export const timeXScale: TimeScale = {
|
||||||
|
@ -46,7 +44,6 @@ export const timeXScale: TimeScale = {
|
||||||
type: "time",
|
type: "time",
|
||||||
range: "width",
|
range: "width",
|
||||||
nice: false,
|
nice: false,
|
||||||
domain: { data: "domain", field: "x" },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Y Scales */
|
/** Y Scales */
|
||||||
|
@ -55,7 +52,6 @@ export const linearYScale: LinearScale = {
|
||||||
type: "linear",
|
type: "linear",
|
||||||
range: "height",
|
range: "height",
|
||||||
zero: true,
|
zero: true,
|
||||||
domain: { data: "domain", field: "y" },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const expYScale: PowScale = {
|
export const expYScale: PowScale = {
|
||||||
|
@ -65,7 +61,6 @@ export const expYScale: PowScale = {
|
||||||
range: "height",
|
range: "height",
|
||||||
zero: true,
|
zero: true,
|
||||||
nice: false,
|
nice: false,
|
||||||
domain: { data: "domain", field: "y" },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultTickFormat = ".9~s";
|
export const defaultTickFormat = ".9~s";
|
||||||
|
@ -73,9 +68,17 @@ export const timeTickFormat = "%b %d, %Y %H:%M";
|
||||||
const width = 500;
|
const width = 500;
|
||||||
|
|
||||||
export function buildVegaSpec(
|
export function buildVegaSpec(
|
||||||
specOptions: DistributionChartSpecOptions
|
specOptions: DistributionChartSpecOptions & { maxY: number }
|
||||||
): VisualizationSpec {
|
): VisualizationSpec {
|
||||||
const { title, minX, maxX, logX, expY, xAxisType = "number" } = specOptions;
|
const {
|
||||||
|
title,
|
||||||
|
minX,
|
||||||
|
maxX,
|
||||||
|
logX,
|
||||||
|
expY,
|
||||||
|
xAxisType = "number",
|
||||||
|
maxY,
|
||||||
|
} = specOptions;
|
||||||
|
|
||||||
const dateTime = xAxisType === "dateTime";
|
const dateTime = xAxisType === "dateTime";
|
||||||
|
|
||||||
|
@ -88,13 +91,15 @@ export function buildVegaSpec(
|
||||||
|
|
||||||
let xScale = dateTime ? timeXScale : logX ? logXScale : linearXScale;
|
let xScale = dateTime ? timeXScale : logX ? logXScale : linearXScale;
|
||||||
|
|
||||||
if (minX !== undefined && Number.isFinite(minX)) {
|
xScale = {
|
||||||
xScale = { ...xScale, domainMin: minX };
|
...xScale,
|
||||||
}
|
domain: [minX ?? 0, maxX ?? 1],
|
||||||
|
domainMin: minX,
|
||||||
|
domainMax: maxX,
|
||||||
|
};
|
||||||
|
|
||||||
if (maxX !== undefined && Number.isFinite(maxX)) {
|
let yScale = expY ? expYScale : linearYScale;
|
||||||
xScale = { ...xScale, domainMax: maxX };
|
yScale = { ...yScale, domain: [0, maxY ?? 1], domainMin: 0, domainMax: maxY };
|
||||||
}
|
|
||||||
|
|
||||||
const spec: VisualizationSpec = {
|
const spec: VisualizationSpec = {
|
||||||
$schema: "https://vega.github.io/schema/vega/v5.json",
|
$schema: "https://vega.github.io/schema/vega/v5.json",
|
||||||
|
@ -128,7 +133,7 @@ export function buildVegaSpec(
|
||||||
],
|
],
|
||||||
scales: [
|
scales: [
|
||||||
xScale,
|
xScale,
|
||||||
expY ? expYScale : linearYScale,
|
yScale,
|
||||||
{
|
{
|
||||||
name: "color",
|
name: "color",
|
||||||
type: "ordinal",
|
type: "ordinal",
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
import { SquigglePartial, SquiggleEditor } from "../components/SquiggleEditor";
|
|
||||||
import { useState } from "react";
|
|
||||||
import { Canvas, Meta, Story, Props } from "@storybook/addon-docs";
|
|
||||||
|
|
||||||
<Meta title="Squiggle/SquigglePartial" component={SquigglePartial} />
|
|
||||||
|
|
||||||
export const Template = (props) => <SquigglePartial {...props} />;
|
|
||||||
|
|
||||||
# Squiggle Partial
|
|
||||||
|
|
||||||
A Squiggle Partial is an editor that does not return a graph to the user, but
|
|
||||||
instead returns bindings that can be used by further Squiggle Editors.
|
|
||||||
|
|
||||||
<Canvas>
|
|
||||||
<Story
|
|
||||||
name="Standalone"
|
|
||||||
args={{
|
|
||||||
defaultCode: "x = normal(5,2)",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{Template.bind({})}
|
|
||||||
</Story>
|
|
||||||
</Canvas>
|
|
||||||
|
|
||||||
<Canvas>
|
|
||||||
<Story
|
|
||||||
name="With Editor"
|
|
||||||
args={{
|
|
||||||
initialPartialString: "x = normal(5,2)",
|
|
||||||
initialEditorString: "x",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{(props) => {
|
|
||||||
let [bindings, setBindings] = useState({});
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<SquigglePartial
|
|
||||||
{...props}
|
|
||||||
defaultCode={props.initialPartialString}
|
|
||||||
onChange={setBindings}
|
|
||||||
/>
|
|
||||||
<SquiggleEditor
|
|
||||||
{...props}
|
|
||||||
defaultCode={props.initialEditorString}
|
|
||||||
bindings={bindings}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Story>
|
|
||||||
</Canvas>
|
|
13
packages/components/test/basic.test.tsx
Normal file
13
packages/components/test/basic.test.tsx
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { render } from "@testing-library/react";
|
||||||
|
import React from "react";
|
||||||
|
import "@testing-library/jest-dom";
|
||||||
|
import { SquiggleChart } from "../src/index";
|
||||||
|
|
||||||
|
test("Logs no warnings or errors", async () => {
|
||||||
|
debugger;
|
||||||
|
const { unmount } = render(<SquiggleChart code={"normal(0, 1)"} />);
|
||||||
|
unmount();
|
||||||
|
|
||||||
|
expect(console.warn).not.toBeCalled();
|
||||||
|
expect(console.error).not.toBeCalled();
|
||||||
|
});
|
8
packages/components/test/setup.js
Normal file
8
packages/components/test/setup.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
global.console = {
|
||||||
|
...console,
|
||||||
|
log: jest.fn(console.log),
|
||||||
|
debug: jest.fn(console.debug),
|
||||||
|
info: jest.fn(console.info),
|
||||||
|
warn: jest.fn(console.warn),
|
||||||
|
error: jest.fn(console.error),
|
||||||
|
};
|
|
@ -112,6 +112,25 @@ describe("project2", () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("removing sources", () => {
|
||||||
|
let project = Project.createProject()
|
||||||
|
Project.setContinues(project, "main", ["second"])
|
||||||
|
Project.setContinues(project, "second", ["first"])
|
||||||
|
Project.setSource(project, "first", "x=1")
|
||||||
|
Project.setSource(project, "second", "y=2")
|
||||||
|
Project.setSource(project, "main", "y")
|
||||||
|
|
||||||
|
Project.removeSource(project, "main")
|
||||||
|
|
||||||
|
test("project doesn't have source", () => {
|
||||||
|
expect(Project.getSource(project, "main")) == None
|
||||||
|
})
|
||||||
|
|
||||||
|
test("dependents get updated", () => {
|
||||||
|
expect(Project.getDependents(project, "second")) == []
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe("project with include", () => {
|
describe("project with include", () => {
|
||||||
let project = Project.createProject()
|
let project = Project.createProject()
|
||||||
Project.setContinues(project, "main", ["second"])
|
Project.setContinues(project, "main", ["second"])
|
||||||
|
|
|
@ -82,7 +82,10 @@ describe("FunctionRegistry Library", () => {
|
||||||
)
|
)
|
||||||
|
|
||||||
testEvalToBe("Dict.merge({a: 1, b: 2}, {b: 3, c: 4, d: 5})", "Ok({a: 1,b: 3,c: 4,d: 5})")
|
testEvalToBe("Dict.merge({a: 1, b: 2}, {b: 3, c: 4, d: 5})", "Ok({a: 1,b: 3,c: 4,d: 5})")
|
||||||
testEvalToBe("Dict.mergeMany([{a: 1, b: 2}, {c: 3, d: 4}, {c: 5, e: 6}])", "Ok({a: 1,b: 2,c: 5,d: 4,e: 6})")
|
testEvalToBe(
|
||||||
|
"Dict.mergeMany([{a: 1, b: 2}, {c: 3, d: 4}, {c: 5, e: 6}])",
|
||||||
|
"Ok({a: 1,b: 2,c: 5,d: 4,e: 6})",
|
||||||
|
)
|
||||||
testEvalToBe("Dict.keys({a: 1, b: 2})", "Ok(['a','b'])")
|
testEvalToBe("Dict.keys({a: 1, b: 2})", "Ok(['a','b'])")
|
||||||
testEvalToBe("Dict.values({a: 1, b: 2})", "Ok([1,2])")
|
testEvalToBe("Dict.values({a: 1, b: 2})", "Ok([1,2])")
|
||||||
testEvalToBe("Dict.toList({a: 1, b: 2})", "Ok([['a',1],['b',2]])")
|
testEvalToBe("Dict.toList({a: 1, b: 2})", "Ok([['a',1],['b',2]])")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@quri/squiggle-lang",
|
"name": "@quri/squiggle-lang",
|
||||||
"version": "0.5.0-alpha.2",
|
"version": "0.5.0",
|
||||||
"homepage": "https://squiggle-language.com",
|
"homepage": "https://squiggle-language.com",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -68,9 +68,9 @@
|
||||||
"rescript-fast-check": "^1.1.1",
|
"rescript-fast-check": "^1.1.1",
|
||||||
"rescript-js-map": "^1.1.0",
|
"rescript-js-map": "^1.1.0",
|
||||||
"ts-jest": "^27.1.4",
|
"ts-jest": "^27.1.4",
|
||||||
"ts-loader": "^9.4.0",
|
"ts-loader": "^9.4.1",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"typescript": "^4.8.3",
|
"typescript": "^4.8.4",
|
||||||
"webpack": "^5.74.0",
|
"webpack": "^5.74.0",
|
||||||
"webpack-cli": "^4.10.0"
|
"webpack-cli": "^4.10.0"
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,6 +22,10 @@ export class SqProject {
|
||||||
return RSProject.setSource(this._value, sourceId, value);
|
return RSProject.setSource(this._value, sourceId, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeSource(sourceId: string) {
|
||||||
|
RSProject.removeSource(this._value, sourceId);
|
||||||
|
}
|
||||||
|
|
||||||
getSource(sourceId: string) {
|
getSource(sourceId: string) {
|
||||||
return RSProject.getSource(this._value, sourceId);
|
return RSProject.getSource(this._value, sourceId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,6 @@ let library = [
|
||||||
],
|
],
|
||||||
(),
|
(),
|
||||||
),
|
),
|
||||||
|
|
||||||
Function.make(
|
Function.make(
|
||||||
~name="mergeMany",
|
~name="mergeMany",
|
||||||
~nameSpace,
|
~nameSpace,
|
||||||
|
@ -72,12 +71,16 @@ let library = [
|
||||||
~inputs=[FRTypeArray(FRTypeDict(FRTypeAny))],
|
~inputs=[FRTypeArray(FRTypeDict(FRTypeAny))],
|
||||||
~run=(inputs, _, _) => {
|
~run=(inputs, _, _) => {
|
||||||
switch inputs {
|
switch inputs {
|
||||||
| [IEvArray(dicts)] => {
|
| [IEvArray(dicts)] =>
|
||||||
dicts->Belt.Array.map(dictValue => switch dictValue {
|
dicts
|
||||||
|
->Belt.Array.map(dictValue =>
|
||||||
|
switch dictValue {
|
||||||
| IEvRecord(dict) => dict
|
| IEvRecord(dict) => dict
|
||||||
| _ => impossibleError->Reducer_ErrorValue.toException
|
| _ => impossibleError->Reducer_ErrorValue.toException
|
||||||
})->Internals.mergeMany->Ok
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
->Internals.mergeMany
|
||||||
|
->Ok
|
||||||
| _ => impossibleError->Error
|
| _ => impossibleError->Error
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,8 +22,7 @@ module DistributionCreation = {
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name,
|
~name,
|
||||||
~inputs=[FRTypeDistOrNumber, FRTypeDistOrNumber],
|
~inputs=[FRTypeDistOrNumber, FRTypeDistOrNumber],
|
||||||
~run=(inputs, env, _) =>
|
~run=(inputs, env, _) => inputs->Prepare.ToValueTuple.twoDistOrNumber->process(~fn, ~env),
|
||||||
inputs->Prepare.ToValueTuple.twoDistOrNumber->process(~fn, ~env),
|
|
||||||
(),
|
(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -43,7 +42,9 @@ module DistributionCreation = {
|
||||||
~name,
|
~name,
|
||||||
~inputs=[FRTypeRecord([("mean", FRTypeDistOrNumber), ("stdev", FRTypeDistOrNumber)])],
|
~inputs=[FRTypeRecord([("mean", FRTypeDistOrNumber), ("stdev", FRTypeDistOrNumber)])],
|
||||||
~run=(inputs, env, _) =>
|
~run=(inputs, env, _) =>
|
||||||
inputs->Prepare.ToValueTuple.Record.twoDistOrNumber(("mean", "stdev"))->process(~fn, ~env),
|
inputs
|
||||||
|
->Prepare.ToValueTuple.Record.twoDistOrNumber(("mean", "stdev"))
|
||||||
|
->process(~fn, ~env),
|
||||||
(),
|
(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -60,8 +61,7 @@ module DistributionCreation = {
|
||||||
FnDefinition.make(
|
FnDefinition.make(
|
||||||
~name,
|
~name,
|
||||||
~inputs=[FRTypeDistOrNumber],
|
~inputs=[FRTypeDistOrNumber],
|
||||||
~run=(inputs, env, _) =>
|
~run=(inputs, env, _) => inputs->Prepare.ToValueTuple.oneDistOrNumber->process(~fn, ~env),
|
||||||
inputs->Prepare.ToValueTuple.oneDistOrNumber->process(~fn, ~env),
|
|
||||||
(),
|
(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,9 @@ let requiresNamespace = true
|
||||||
let inputsToDist = (inputs: array<Reducer_T.value>, xyShapeToPointSetDist) => {
|
let inputsToDist = (inputs: array<Reducer_T.value>, xyShapeToPointSetDist) => {
|
||||||
// TODO - rewrite in more functional/functor-based style
|
// TODO - rewrite in more functional/functor-based style
|
||||||
switch inputs {
|
switch inputs {
|
||||||
| [IEvArray(items)] => {
|
| [IEvArray(items)] =>
|
||||||
items->Belt.Array.map(
|
items
|
||||||
item =>
|
->Belt.Array.map(item =>
|
||||||
switch item {
|
switch item {
|
||||||
| IEvRecord(map) => {
|
| IEvRecord(map) => {
|
||||||
let xValue = map->Belt.Map.String.get("x")
|
let xValue = map->Belt.Map.String.get("x")
|
||||||
|
@ -21,9 +21,10 @@ let inputsToDist = (inputs: array<Reducer_T.value>, xyShapeToPointSetDist) => {
|
||||||
}
|
}
|
||||||
| _ => impossibleError->Reducer_ErrorValue.toException
|
| _ => impossibleError->Reducer_ErrorValue.toException
|
||||||
}
|
}
|
||||||
)->Ok->E.R.bind(r => r->XYShape.T.makeFromZipped->E.R2.errMap(XYShape.Error.toString))
|
)
|
||||||
|
->Ok
|
||||||
|
->E.R.bind(r => r->XYShape.T.makeFromZipped->E.R2.errMap(XYShape.Error.toString))
|
||||||
->E.R2.fmap(r => Reducer_T.IEvDistribution(PointSet(r->xyShapeToPointSetDist)))
|
->E.R2.fmap(r => Reducer_T.IEvDistribution(PointSet(r->xyShapeToPointSetDist)))
|
||||||
}
|
|
||||||
| _ => impossibleError->Reducer_ErrorValue.toException
|
| _ => impossibleError->Reducer_ErrorValue.toException
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,9 +115,8 @@ let libaryBase = [
|
||||||
~inputs=[FRTypeArray(FRTypeNumber)],
|
~inputs=[FRTypeArray(FRTypeNumber)],
|
||||||
~run=(inputs, _, _) => {
|
~run=(inputs, _, _) => {
|
||||||
let sampleSet =
|
let sampleSet =
|
||||||
inputs->Prepare.ToTypedArray.numbers |> E.R2.bind(r =>
|
inputs->Prepare.ToTypedArray.numbers
|
||||||
SampleSetDist.make(r)->E.R2.errMap(_ => "AM I HERE? WHYERE AMI??")
|
|> E.R2.bind(r => SampleSetDist.make(r)->E.R2.errMap(_ => "AM I HERE? WHYERE AMI??"))
|
||||||
)
|
|
||||||
sampleSet
|
sampleSet
|
||||||
->E.R2.fmap(Wrappers.sampleSet)
|
->E.R2.fmap(Wrappers.sampleSet)
|
||||||
->E.R2.fmap(Wrappers.evDistribution)
|
->E.R2.fmap(Wrappers.evDistribution)
|
||||||
|
|
|
@ -31,14 +31,13 @@ let library = [
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
~run=(inputs, environment, _) => {
|
~run=(inputs, environment, _) => {
|
||||||
switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.threeArgs(inputs, ("estimate", "answer", "prior")) {
|
switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.threeArgs(
|
||||||
|
inputs,
|
||||||
|
("estimate", "answer", "prior"),
|
||||||
|
) {
|
||||||
| Ok([IEvDistribution(estimate), IEvDistribution(d), IEvDistribution(prior)]) =>
|
| Ok([IEvDistribution(estimate), IEvDistribution(d), IEvDistribution(prior)]) =>
|
||||||
runScoring(estimate, Score_Dist(d), Some(prior), environment)
|
runScoring(estimate, Score_Dist(d), Some(prior), environment)
|
||||||
| Ok([
|
| Ok([IEvDistribution(estimate), IEvNumber(d), IEvDistribution(prior)]) =>
|
||||||
IEvDistribution(estimate),
|
|
||||||
IEvNumber(d),
|
|
||||||
IEvDistribution(prior),
|
|
||||||
]) =>
|
|
||||||
runScoring(estimate, Score_Scalar(d), Some(prior), environment)
|
runScoring(estimate, Score_Scalar(d), Some(prior), environment)
|
||||||
| Error(e) => Error(e->FunctionRegistry_Helpers.wrapError)
|
| Error(e) => Error(e->FunctionRegistry_Helpers.wrapError)
|
||||||
| _ => Error(FunctionRegistry_Helpers.impossibleError)
|
| _ => Error(FunctionRegistry_Helpers.impossibleError)
|
||||||
|
@ -50,7 +49,10 @@ let library = [
|
||||||
~name="logScore",
|
~name="logScore",
|
||||||
~inputs=[FRTypeRecord([("estimate", FRTypeDist), ("answer", FRTypeDistOrNumber)])],
|
~inputs=[FRTypeRecord([("estimate", FRTypeDist), ("answer", FRTypeDistOrNumber)])],
|
||||||
~run=(inputs, environment, _) => {
|
~run=(inputs, environment, _) => {
|
||||||
switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.twoArgs(inputs, ("estimate", "answer")) {
|
switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.twoArgs(
|
||||||
|
inputs,
|
||||||
|
("estimate", "answer"),
|
||||||
|
) {
|
||||||
| Ok([IEvDistribution(estimate), IEvDistribution(d)]) =>
|
| Ok([IEvDistribution(estimate), IEvDistribution(d)]) =>
|
||||||
runScoring(estimate, Score_Dist(d), None, environment)
|
runScoring(estimate, Score_Dist(d), None, environment)
|
||||||
| Ok([IEvDistribution(estimate), IEvNumber(d)]) =>
|
| Ok([IEvDistribution(estimate), IEvNumber(d)]) =>
|
||||||
|
|
|
@ -50,6 +50,13 @@ Sets the source for a given source Id.
|
||||||
let setSource = (project: reducerProject, sourceId: string, value: string): unit =>
|
let setSource = (project: reducerProject, sourceId: string, value: string): unit =>
|
||||||
project->Private.setSource(sourceId, value)
|
project->Private.setSource(sourceId, value)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Removes the source for a given source Id.
|
||||||
|
*/
|
||||||
|
@genType
|
||||||
|
let removeSource = (project: reducerProject, sourceId: string): unit =>
|
||||||
|
project->Private.removeSource(sourceId)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Gets the source for a given source id.
|
Gets the source for a given source id.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -83,19 +83,17 @@ module FRType = {
|
||||||
| (FRTypeNumeric, IEvNumber(_)) => true
|
| (FRTypeNumeric, IEvNumber(_)) => true
|
||||||
| (FRTypeNumeric, IEvDistribution(Symbolic(#Float(_)))) => true
|
| (FRTypeNumeric, IEvDistribution(Symbolic(#Float(_)))) => true
|
||||||
| (FRTypeLambda, IEvLambda(_)) => true
|
| (FRTypeLambda, IEvLambda(_)) => true
|
||||||
| (FRTypeArray(intendedType), IEvArray(elements)) => {
|
| (FRTypeArray(intendedType), IEvArray(elements)) =>
|
||||||
elements->Belt.Array.every(v => matchWithValue(intendedType, v))
|
elements->Belt.Array.every(v => matchWithValue(intendedType, v))
|
||||||
}
|
|
||||||
| (FRTypeDict(r), IEvRecord(map)) =>
|
| (FRTypeDict(r), IEvRecord(map)) =>
|
||||||
map->Belt.Map.String.valuesToArray->Belt.Array.every(v => matchWithValue(r, v))
|
map->Belt.Map.String.valuesToArray->Belt.Array.every(v => matchWithValue(r, v))
|
||||||
| (FRTypeRecord(recordParams), IEvRecord(map)) => {
|
| (FRTypeRecord(recordParams), IEvRecord(map)) =>
|
||||||
recordParams->Belt.Array.every(((name, input)) => {
|
recordParams->Belt.Array.every(((name, input)) => {
|
||||||
switch map->Belt.Map.String.get(name) {
|
switch map->Belt.Map.String.get(name) {
|
||||||
| Some(v) => matchWithValue(input, v)
|
| Some(v) => matchWithValue(input, v)
|
||||||
| None => false
|
| None => false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
|
||||||
| _ => false
|
| _ => false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,8 +102,7 @@ module FRType = {
|
||||||
if !isSameLength {
|
if !isSameLength {
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
E.A.zip(inputs, args)
|
E.A.zip(inputs, args)->Belt.Array.every(((input, arg)) => matchWithValue(input, arg))
|
||||||
->Belt.Array.every(((input, arg)) => matchWithValue(input, arg))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,8 +108,10 @@ module Prepare = {
|
||||||
}
|
}
|
||||||
|
|
||||||
module Record = {
|
module Record = {
|
||||||
let twoDistOrNumber = (values: ts, labels: (string, string)): result<(frValueDistOrNumber, frValueDistOrNumber), err> =>
|
let twoDistOrNumber = (values: ts, labels: (string, string)): result<
|
||||||
values->ToValueArray.Record.twoArgs(labels)->E.R.bind(twoDistOrNumber)
|
(frValueDistOrNumber, frValueDistOrNumber),
|
||||||
|
err,
|
||||||
|
> => values->ToValueArray.Record.twoArgs(labels)->E.R.bind(twoDistOrNumber)
|
||||||
|
|
||||||
let twoDist = (values: ts, labels: (string, string)): result<
|
let twoDist = (values: ts, labels: (string, string)): result<
|
||||||
(DistributionTypes.genericDist, DistributionTypes.genericDist),
|
(DistributionTypes.genericDist, DistributionTypes.genericDist),
|
||||||
|
|
|
@ -61,6 +61,10 @@ let setSource = (project: t, sourceId: string, value: string): unit => {
|
||||||
touchDependents(project, sourceId)
|
touchDependents(project, sourceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let removeSource = (project: t, sourceId: string): unit => {
|
||||||
|
Belt.MutableMap.String.remove(project.items, sourceId)
|
||||||
|
}
|
||||||
|
|
||||||
let clean = (project: t, sourceId: string): unit => {
|
let clean = (project: t, sourceId: string): unit => {
|
||||||
let newItem = project->getItem(sourceId)->ProjectItem.clean
|
let newItem = project->getItem(sourceId)->ProjectItem.clean
|
||||||
project->setItem(sourceId, newItem)
|
project->setItem(sourceId, newItem)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"displayName": "Squiggle",
|
"displayName": "Squiggle",
|
||||||
"description": "Squiggle language support",
|
"description": "Squiggle language support",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"version": "0.5.0-alpha.2",
|
"version": "0.5.0",
|
||||||
"publisher": "QURI",
|
"publisher": "QURI",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -131,7 +131,7 @@
|
||||||
"@types/vscode": "^1.70.0",
|
"@types/vscode": "^1.70.0",
|
||||||
"glob": "^8.0.3",
|
"glob": "^8.0.3",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"typescript": "^4.8.3",
|
"typescript": "^4.8.4",
|
||||||
"vsce-yarn-patch": "^1.66.2"
|
"vsce-yarn-patch": "^1.66.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -12,7 +12,7 @@ All regular distribution function work on sample set distributions. In addition,
|
||||||
### fromDist
|
### fromDist
|
||||||
|
|
||||||
```
|
```
|
||||||
SampleSet.fromDist: (list<number>) => sampleSet
|
SampleSet.fromDist: (distribution) => sampleSet
|
||||||
```
|
```
|
||||||
|
|
||||||
### fromList
|
### fromList
|
||||||
|
|
|
@ -52,29 +52,30 @@ const config = {
|
||||||
themeConfig:
|
themeConfig:
|
||||||
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
|
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
|
||||||
({
|
({
|
||||||
algolia: {
|
// TODO - disabled until we fix algolia search
|
||||||
// The application ID provided by Algolia
|
// algolia: {
|
||||||
appId: "KBED3M1CMD",
|
// // The application ID provided by Algolia
|
||||||
|
// appId: "KBED3M1CMD",
|
||||||
|
|
||||||
// Public API key: it is safe to commit it
|
// // Public API key: it is safe to commit it
|
||||||
apiKey: "c61bc7603893cf287ed6971983af8bad",
|
// apiKey: "c61bc7603893cf287ed6971983af8bad",
|
||||||
|
|
||||||
indexName: "squiggle_docs",
|
// indexName: "squiggle_docs",
|
||||||
|
|
||||||
// Optional: see doc section below
|
// // Optional: see doc section below
|
||||||
contextualSearch: true,
|
// contextualSearch: true,
|
||||||
|
|
||||||
// Optional: Specify domains where the navigation should occur through window.location instead on history.push. Useful when our Algolia config crawls multiple documentation sites and we want to navigate with window.location.href to them.
|
// // Optional: Specify domains where the navigation should occur through window.location instead on history.push. Useful when our Algolia config crawls multiple documentation sites and we want to navigate with window.location.href to them.
|
||||||
// externalUrlRegex: 'external\\.com|domain\\.com',
|
// // externalUrlRegex: 'external\\.com|domain\\.com',
|
||||||
|
|
||||||
// Optional: Algolia search parameters
|
// // Optional: Algolia search parameters
|
||||||
searchParameters: {},
|
// searchParameters: {},
|
||||||
|
|
||||||
// Optional: path for search page that enabled by default (`false` to disable it)
|
// // Optional: path for search page that enabled by default (`false` to disable it)
|
||||||
searchPagePath: "search",
|
// searchPagePath: "search",
|
||||||
|
|
||||||
//... other Algolia params
|
// //... other Algolia params
|
||||||
},
|
// },
|
||||||
navbar: {
|
navbar: {
|
||||||
title: "Squiggle",
|
title: "Squiggle",
|
||||||
hideOnScroll: true,
|
hideOnScroll: true,
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
"@docusaurus/core": "2.1.0",
|
"@docusaurus/core": "2.1.0",
|
||||||
"@docusaurus/preset-classic": "2.1.0",
|
"@docusaurus/preset-classic": "2.1.0",
|
||||||
"@heroicons/react": "^1.0.6",
|
"@heroicons/react": "^1.0.6",
|
||||||
"@quri/squiggle-components": "^0.5.0-alpha.2",
|
"@quri/squiggle-components": "^0.5.0",
|
||||||
"base64-js": "^1.5.1",
|
"base64-js": "^1.5.1",
|
||||||
"clsx": "^1.2.1",
|
"clsx": "^1.2.1",
|
||||||
"hast-util-is-element": "2.1.2",
|
"hast-util-is-element": "2.1.2",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user