From 2ca232762439d2bae24a918ae22bca7c45b39cb9 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Thu, 26 Dec 2024 17:12:04 -0300 Subject: [PATCH 1/4] compareVersions script --- .../versioned-components/package.json | 9 + .../src/compareVersions.ts | 103 ++++++ .../src/scripts/compareVersions.ts | 41 +++ pnpm-lock.yaml | 314 +++++++++++++++--- 4 files changed, 423 insertions(+), 44 deletions(-) create mode 100644 internal-packages/versioned-components/src/compareVersions.ts create mode 100644 internal-packages/versioned-components/src/scripts/compareVersions.ts diff --git a/internal-packages/versioned-components/package.json b/internal-packages/versioned-components/package.json index 271de1848d..89cdbce3cb 100644 --- a/internal-packages/versioned-components/package.json +++ b/internal-packages/versioned-components/package.json @@ -16,7 +16,9 @@ "@quri/ui": "workspace:*", "@tailwindcss/forms": "^0.5.7", "@tailwindcss/typography": "^0.5.13", + "commander": "^12.1.0", "glob": "^10.3.12", + "json-diff": "^1.0.6", "lodash": "^4.17.21", "squiggle-components-0.10.0": "npm:@quri/squiggle-components@0.10.0", "squiggle-components-0.8.5": "npm:@quri/squiggle-components@0.8.5", @@ -36,8 +38,11 @@ "squiggle-lang-0.9.5": "npm:@quri/squiggle-lang@0.9.5" }, "devDependencies": { + "@commander-js/extra-typings": "^12.1.0", "@quri/configs": "workspace:*", + "@types/json-diff": "^1.0.3", "@types/lodash": "^4.14.202", + "@types/node": "^22.10.2", "@types/react": "^18.3.3", "@typescript-eslint/eslint-plugin": "^8.17.0", "@typescript-eslint/parser": "^8.17.0", @@ -62,6 +67,10 @@ "./tailwind": { "types": "./dist/tailwind.d.cts", "default": "./dist/tailwind.cjs" + }, + "./compareVersions": { + "types": "./dist/compareVersions.d.ts", + "default": "./dist/compareVersions.js" } }, "module": "./dist/index.js", diff --git a/internal-packages/versioned-components/src/compareVersions.ts b/internal-packages/versioned-components/src/compareVersions.ts new file mode 100644 index 0000000000..6da3b14010 --- /dev/null +++ b/internal-packages/versioned-components/src/compareVersions.ts @@ -0,0 +1,103 @@ +import jsonDiff from "json-diff"; + +import { + deserializeRunResult, + result, + serializeRunResult, + SqDict, +} from "@quri/squiggle-lang"; + +import { versionSupportsSqProjectV2 } from "./predicates.js"; +import { squiggleLangByVersion } from "./versionedSquiggleLang.js"; +import { SquiggleVersion } from "./versions.js"; + +type OriginalRunResult = Extract< + ReturnType, + { ok: true } +>["value"]; + +type PatchedRunResult = { + result: OriginalRunResult["result"]; + bindings: OriginalRunResult["bindings"]; +}; + +type RunResult = result; + +function reserialize( + value: Extract< + Parameters[0], + { ok: true } + >["value"] +): RunResult { + const serialized = serializeRunResult({ + ok: true, + value, + }); + const result = deserializeRunResult(serialized); + if (!result.ok) { + return { + ok: false, + value: "Failed to deserialize result", + }; + } + return { + ok: true, + value: { + result: result.value.result, + bindings: result.value.bindings, + }, + }; +} + +async function runVersion( + version: SquiggleVersion, + code: string +): Promise { + if (versionSupportsSqProjectV2.plain(version)) { + // modern SqProject + const lang = await squiggleLangByVersion(version); + const output = await lang.run(code); + const outputResult = output.result; + if (!outputResult.ok) { + return { + ok: false, + value: "Failed to run code", + }; + } + const okResult = outputResult.value; + return reserialize({ + result: okResult.result._value as any, + bindings: okResult.bindings._value as any, + exports: okResult.exports._value as any, + profile: undefined, + }); + } else { + const lang = await squiggleLangByVersion(version); + const output = await lang.run(code); + if (!output.ok) { + return { + ok: false, + value: "Failed to run code", + }; + } + const okResult = output.value; + return reserialize({ + result: okResult.result._value as any, + bindings: (okResult.bindings as any)._value, + exports: SqDict.makeEmpty().asValue()._value, + profile: undefined, + }); + } +} + +// Note: this function is not very reliable; but if it returns `undefined`, then "result" and "bindings" are _probably_ the same. +export async function compareVersions(params: { + version1: SquiggleVersion; + version2: SquiggleVersion; + code: string; +}) { + const result1 = await runVersion(params.version1, params.code); + const result2 = await runVersion(params.version2, params.code); + + return jsonDiff.diff(result1, result2); +} diff --git a/internal-packages/versioned-components/src/scripts/compareVersions.ts b/internal-packages/versioned-components/src/scripts/compareVersions.ts new file mode 100644 index 0000000000..7a2d990fa6 --- /dev/null +++ b/internal-packages/versioned-components/src/scripts/compareVersions.ts @@ -0,0 +1,41 @@ +import { Command } from "@commander-js/extra-typings"; + +import { compareVersions } from "../compareVersions.js"; +import { checkSquiggleVersion } from "../versions.js"; + +export function makeProgram() { + const program = new Command(); + + program + .requiredOption("--v1 ", "version 1") + .requiredOption("--v2 ", "version 2") + .requiredOption("--code ", "code to run") + .action(async (options) => { + const { v1, v2, code } = options; + + if (!checkSquiggleVersion(v1)) { + program.error(`Invalid version: ${v1}`); + return; + } + if (!checkSquiggleVersion(v2)) { + program.error(`Invalid version: ${v2}`); + return; + } + + const diff = await compareVersions({ version1: v1, version2: v2, code }); + + if (!diff) { + console.log("Code output is identical"); + } else { + console.log(JSON.stringify(diff, null, 2)); + } + }); + + return program; +} + +async function main() { + await makeProgram().parseAsync(); +} + +main(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1f3cd45bb7..aafae26a84 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -232,7 +232,7 @@ importers: version: 14.0.2(@types/react@18.3.3) fumadocs-ui: specifier: 14.0.2 - version: 14.0.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(next@15.0.3(react-dom@19.0.0-rc-cae764ce-20241025(react@19.0.0-rc-cae764ce-20241025))(react@19.0.0-rc-cae764ce-20241025))(react-dom@19.0.0-rc-cae764ce-20241025(react@19.0.0-rc-cae764ce-20241025))(react@19.0.0-rc-cae764ce-20241025)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)) + version: 14.0.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(next@15.0.3(react-dom@19.0.0-rc-cae764ce-20241025(react@19.0.0-rc-cae764ce-20241025))(react@19.0.0-rc-cae764ce-20241025))(react-dom@19.0.0-rc-cae764ce-20241025(react@19.0.0-rc-cae764ce-20241025))(react@19.0.0-rc-cae764ce-20241025)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)) katex: specifier: ^0.16.11 version: 0.16.11 @@ -305,7 +305,7 @@ importers: version: 3.3.3 tailwindcss: specifier: ^3.4.14 - version: 3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)) + version: 3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)) tsx: specifier: ^4.11.0 version: 4.19.2 @@ -502,40 +502,46 @@ importers: version: link:../../packages/ui '@tailwindcss/forms': specifier: ^0.5.7 - version: 0.5.7(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3))) + version: 0.5.7(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3))) '@tailwindcss/typography': specifier: ^0.5.13 - version: 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3))) + version: 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3))) + commander: + specifier: ^12.1.0 + version: 12.1.0 glob: specifier: ^10.3.12 version: 10.4.5 + json-diff: + specifier: ^1.0.6 + version: 1.0.6 lodash: specifier: ^4.17.21 version: 4.17.21 squiggle-components-0.10.0: specifier: npm:@quri/squiggle-components@0.10.0 - version: '@quri/squiggle-components@0.10.0(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)))' + version: '@quri/squiggle-components@0.10.0(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)))' squiggle-components-0.8.5: specifier: npm:@quri/squiggle-components@0.8.5 - version: '@quri/squiggle-components@0.8.5(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)))' + version: '@quri/squiggle-components@0.8.5(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)))' squiggle-components-0.8.6: specifier: npm:@quri/squiggle-components@0.8.6 - version: '@quri/squiggle-components@0.8.6(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)))' + version: '@quri/squiggle-components@0.8.6(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)))' squiggle-components-0.9.0: specifier: npm:@quri/squiggle-components@0.9.0 - version: '@quri/squiggle-components@0.9.0(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)))' + version: '@quri/squiggle-components@0.9.0(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)))' squiggle-components-0.9.2: specifier: npm:@quri/squiggle-components@0.9.2 - version: '@quri/squiggle-components@0.9.2(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)))' + version: '@quri/squiggle-components@0.9.2(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)))' squiggle-components-0.9.3: specifier: npm:@quri/squiggle-components@0.9.3 - version: '@quri/squiggle-components@0.9.3(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)))' + version: '@quri/squiggle-components@0.9.3(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)))' squiggle-components-0.9.4: specifier: npm:@quri/squiggle-components@0.9.4 - version: '@quri/squiggle-components@0.9.4(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)))' + version: '@quri/squiggle-components@0.9.4(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)))' squiggle-components-0.9.5: specifier: npm:@quri/squiggle-components@0.9.5 - version: '@quri/squiggle-components@0.9.5(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)))' + version: '@quri/squiggle-components@0.9.5(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)))' squiggle-lang-0.10.0: specifier: npm:@quri/squiggle-lang@0.10.0 version: '@quri/squiggle-lang@0.10.0(@types/react@18.3.3)' @@ -561,12 +567,21 @@ importers: specifier: npm:@quri/squiggle-lang@0.9.5 version: '@quri/squiggle-lang@0.9.5' devDependencies: + '@commander-js/extra-typings': + specifier: ^12.1.0 + version: 12.1.0(commander@12.1.0) '@quri/configs': specifier: workspace:* version: link:../configs + '@types/json-diff': + specifier: ^1.0.3 + version: 1.0.3 '@types/lodash': specifier: ^4.14.202 version: 4.17.13 + '@types/node': + specifier: ^22.10.2 + version: 22.10.2 '@types/react': specifier: ^18.3.3 version: 18.3.3 @@ -593,7 +608,7 @@ importers: version: 18.3.1(react@18.3.1) tailwindcss: specifier: ^3.4.14 - version: 3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)) + version: 3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)) typescript: specifier: ^5.6.3 version: 5.6.3 @@ -850,10 +865,10 @@ importers: version: 29.5.14 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.10.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)) + version: 29.7.0(@types/node@22.10.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)) ts-node: specifier: ^10.9.2 - version: 10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3) + version: 10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3) typescript: specifier: ^5.6.3 version: 5.6.3 @@ -889,13 +904,13 @@ importers: version: 9.16.0(jiti@1.21.0) jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.10.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)) + version: 29.7.0(@types/node@20.17.6)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)) prettier: specifier: ^3.3.3 version: 3.3.3 ts-node: specifier: ^10.9.2 - version: 10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3) + version: 10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3) typescript: specifier: 5.6.3 version: 5.6.3 @@ -2791,6 +2806,9 @@ packages: resolution: {integrity: sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ewoudenberg/difflib@0.1.0': + resolution: {integrity: sha512-OU5P5mJyD3OoWYMWY+yIgwvgNS9cFAU10f+DDuvtogcWQOoJIsQ4Hy2McSfUfhKjq8L0FuWVb4Rt7kgA+XK86A==} + '@fal-works/esbuild-plugin-global-externals@2.1.2': resolution: {integrity: sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==} @@ -4607,6 +4625,9 @@ packages: '@types/jsdom@20.0.1': resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} + '@types/json-diff@1.0.3': + resolution: {integrity: sha512-Qvxm8fpRMv/1zZR3sQWImeRK2mBYJji20xF51Fq9Gt//Ed18u0x6/FNLogLS1xhfUWTEmDyqveJqn95ltB6Kvw==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -4649,6 +4670,9 @@ packages: '@types/node@22.10.1': resolution: {integrity: sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==} + '@types/node@22.10.2': + resolution: {integrity: sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==} + '@types/normalize-package-data@2.4.1': resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} @@ -5472,6 +5496,10 @@ packages: resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} engines: {node: '>=12.5.0'} + colors@1.4.0: + resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} + engines: {node: '>=0.1.90'} + combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -6042,6 +6070,10 @@ packages: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} + dreamopt@0.8.0: + resolution: {integrity: sha512-vyJTp8+mC+G+5dfgsY+r3ckxlz+QMX40VjPQsZc5gxVAxLmi64TBoVkP54A/pRAXMXsbu2GMMBrZPxNv23waMg==} + engines: {node: '>=0.4.0'} + dunder-proto@1.0.0: resolution: {integrity: sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==} engines: {node: '>= 0.4'} @@ -7420,6 +7452,10 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-diff@1.0.6: + resolution: {integrity: sha512-tcFIPRdlc35YkYdGxcamJjllUhXWv4n2rK9oJ2RsAzV4FBkuV4ojKEDgcZ+kpKxDmJKv+PFK65+1tVVOnSeEqA==} + hasBin: true + json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} @@ -10352,6 +10388,9 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -12283,6 +12322,10 @@ snapshots: dependencies: levn: 0.4.1 + '@ewoudenberg/difflib@0.1.0': + dependencies: + heap: 0.2.7 + '@fal-works/esbuild-plugin-global-externals@2.1.2': {} '@floating-ui/core@1.6.0': @@ -12568,6 +12611,41 @@ snapshots: - supports-color - ts-node + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3))': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.17.6 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.8.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@20.17.6)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + '@jest/environment@29.7.0': dependencies: '@jest/fake-timers': 29.7.0 @@ -13090,7 +13168,7 @@ snapshots: '@quri/serializer@1.0.0': {} - '@quri/squiggle-components@0.10.0(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)))': + '@quri/squiggle-components@0.10.0(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)))': dependencies: '@codemirror/autocomplete': 6.16.2(@codemirror/language@6.10.1)(@codemirror/state@6.4.1)(@codemirror/view@6.26.3)(@lezer/common@1.2.3) '@codemirror/commands': 6.5.0 @@ -13109,7 +13187,7 @@ snapshots: '@quri/squiggle-lang': 0.10.0(@types/react@18.3.3) '@quri/squiggle-textmate-grammar': 0.10.0 '@quri/ui': 0.2.3(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react-hook-form@7.53.2(react@18.3.1))(react@18.3.1) - '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3))) + '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3))) clsx: 2.1.1 codemirror: 6.0.1(@lezer/common@1.2.3) d3: 7.9.0 @@ -13135,7 +13213,7 @@ snapshots: - tailwindcss - utf-8-validate - '@quri/squiggle-components@0.8.5(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)))': + '@quri/squiggle-components@0.8.5(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)))': dependencies: '@codemirror/autocomplete': 6.16.2(@codemirror/language@6.10.1)(@codemirror/state@6.4.1)(@codemirror/view@6.26.3)(@lezer/common@1.2.3) '@codemirror/commands': 6.5.0 @@ -13153,7 +13231,7 @@ snapshots: '@quri/squiggle-lang': 0.8.5 '@quri/ui': 0.1.4(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-hook/size': 2.1.2(react@18.3.1) - '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3))) + '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3))) '@types/d3': 7.4.3 clsx: 2.1.1 codemirror: 6.0.1(@lezer/common@1.2.3) @@ -13174,7 +13252,7 @@ snapshots: - supports-color - tailwindcss - '@quri/squiggle-components@0.8.6(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)))': + '@quri/squiggle-components@0.8.6(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)))': dependencies: '@codemirror/autocomplete': 6.16.2(@codemirror/language@6.10.1)(@codemirror/state@6.4.1)(@codemirror/view@6.26.3)(@lezer/common@1.2.3) '@codemirror/commands': 6.5.0 @@ -13192,7 +13270,7 @@ snapshots: '@quri/squiggle-lang': 0.8.6 '@quri/ui': 0.1.5(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-hook/size': 2.1.2(react@18.3.1) - '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3))) + '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3))) '@types/d3': 7.4.3 clsx: 2.1.1 codemirror: 6.0.1(@lezer/common@1.2.3) @@ -13214,7 +13292,7 @@ snapshots: - supports-color - tailwindcss - '@quri/squiggle-components@0.9.0(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)))': + '@quri/squiggle-components@0.9.0(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)))': dependencies: '@codemirror/autocomplete': 6.16.2(@codemirror/language@6.10.1)(@codemirror/state@6.4.1)(@codemirror/view@6.26.3)(@lezer/common@1.2.3) '@codemirror/commands': 6.5.0 @@ -13232,7 +13310,7 @@ snapshots: '@quri/squiggle-lang': 0.9.0 '@quri/ui': 0.2.0(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-hook/size': 2.1.2(react@18.3.1) - '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3))) + '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3))) '@types/d3': 7.4.3 clsx: 2.1.1 codemirror: 6.0.1(@lezer/common@1.2.3) @@ -13252,7 +13330,7 @@ snapshots: - supports-color - tailwindcss - '@quri/squiggle-components@0.9.2(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)))': + '@quri/squiggle-components@0.9.2(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)))': dependencies: '@codemirror/autocomplete': 6.16.2(@codemirror/language@6.10.1)(@codemirror/state@6.4.1)(@codemirror/view@6.26.3)(@lezer/common@1.2.3) '@codemirror/commands': 6.5.0 @@ -13271,7 +13349,7 @@ snapshots: '@quri/squiggle-textmate-grammar': 0.9.2 '@quri/ui': 0.2.1(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-hook/size': 2.1.2(react@18.3.1) - '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3))) + '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3))) clsx: 2.1.1 codemirror: 6.0.1(@lezer/common@1.2.3) d3: 7.9.0 @@ -13294,7 +13372,7 @@ snapshots: - supports-color - tailwindcss - '@quri/squiggle-components@0.9.3(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)))': + '@quri/squiggle-components@0.9.3(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)))': dependencies: '@codemirror/autocomplete': 6.16.2(@codemirror/language@6.10.1)(@codemirror/state@6.4.1)(@codemirror/view@6.26.3)(@lezer/common@1.2.3) '@codemirror/commands': 6.5.0 @@ -13313,7 +13391,7 @@ snapshots: '@quri/squiggle-textmate-grammar': 0.9.3 '@quri/ui': 0.2.1(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-hook/size': 2.1.2(react@18.3.1) - '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3))) + '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3))) clsx: 2.1.1 codemirror: 6.0.1(@lezer/common@1.2.3) d3: 7.9.0 @@ -13336,7 +13414,7 @@ snapshots: - supports-color - tailwindcss - '@quri/squiggle-components@0.9.4(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)))': + '@quri/squiggle-components@0.9.4(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)))': dependencies: '@codemirror/autocomplete': 6.16.2(@codemirror/language@6.10.1)(@codemirror/state@6.4.1)(@codemirror/view@6.26.3)(@lezer/common@1.2.3) '@codemirror/commands': 6.5.0 @@ -13354,7 +13432,7 @@ snapshots: '@quri/squiggle-lang': 0.9.4 '@quri/squiggle-textmate-grammar': 0.9.4 '@quri/ui': 0.2.2(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3))) + '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3))) clsx: 2.1.1 codemirror: 6.0.1(@lezer/common@1.2.3) d3: 7.9.0 @@ -13376,7 +13454,7 @@ snapshots: - supports-color - tailwindcss - '@quri/squiggle-components@0.9.5(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)))': + '@quri/squiggle-components@0.9.5(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)))': dependencies: '@codemirror/autocomplete': 6.16.2(@codemirror/language@6.10.1)(@codemirror/state@6.4.1)(@codemirror/view@6.26.3)(@lezer/common@1.2.3) '@codemirror/commands': 6.5.0 @@ -13394,7 +13472,7 @@ snapshots: '@quri/squiggle-lang': 0.9.5 '@quri/squiggle-textmate-grammar': 0.9.5 '@quri/ui': 0.2.2(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3))) + '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3))) clsx: 2.1.1 codemirror: 6.0.1(@lezer/common@1.2.3) d3: 7.9.0 @@ -14650,10 +14728,10 @@ snapshots: mini-svg-data-uri: 1.4.4 tailwindcss: 3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)) - '@tailwindcss/forms@0.5.7(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)))': + '@tailwindcss/forms@0.5.7(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)))': dependencies: mini-svg-data-uri: 1.4.4 - tailwindcss: 3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)) + tailwindcss: 3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)) '@tailwindcss/typography@0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)))': dependencies: @@ -14663,13 +14741,13 @@ snapshots: postcss-selector-parser: 6.0.10 tailwindcss: 3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)) - '@tailwindcss/typography@0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)))': + '@tailwindcss/typography@0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)))': dependencies: lodash.castarray: 4.4.0 lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 postcss-selector-parser: 6.0.10 - tailwindcss: 3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)) + tailwindcss: 3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)) '@tanstack/react-virtual@3.10.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: @@ -14946,6 +15024,8 @@ snapshots: '@types/tough-cookie': 4.0.2 parse5: 7.1.2 + '@types/json-diff@1.0.3': {} + '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} @@ -14987,6 +15067,10 @@ snapshots: dependencies: undici-types: 6.20.0 + '@types/node@22.10.2': + dependencies: + undici-types: 6.20.0 + '@types/normalize-package-data@2.4.1': {} '@types/pako@2.0.3': {} @@ -15977,6 +16061,8 @@ snapshots: color-string: 1.9.1 optional: true + colors@1.4.0: {} + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 @@ -16090,6 +16176,21 @@ snapshots: - supports-color - ts-node + create-jest@29.7.0(@types/node@22.10.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@22.10.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + create-require@1.1.1: {} crelt@1.0.5: {} @@ -16608,6 +16709,10 @@ snapshots: dotenv@16.4.5: {} + dreamopt@0.8.0: + dependencies: + wordwrap: 1.0.0 + dunder-proto@1.0.0: dependencies: call-bind-apply-helpers: 1.0.0 @@ -17428,7 +17533,7 @@ snapshots: - sass - supports-color - fumadocs-ui@14.0.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(next@15.0.3(react-dom@19.0.0-rc-cae764ce-20241025(react@19.0.0-rc-cae764ce-20241025))(react@19.0.0-rc-cae764ce-20241025))(react-dom@19.0.0-rc-cae764ce-20241025(react@19.0.0-rc-cae764ce-20241025))(react@19.0.0-rc-cae764ce-20241025)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)): + fumadocs-ui@14.0.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(next@15.0.3(react-dom@19.0.0-rc-cae764ce-20241025(react@19.0.0-rc-cae764ce-20241025))(react@19.0.0-rc-cae764ce-20241025))(react-dom@19.0.0-rc-cae764ce-20241025(react@19.0.0-rc-cae764ce-20241025))(react@19.0.0-rc-cae764ce-20241025)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)): dependencies: '@radix-ui/react-accordion': 1.2.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@19.0.0-rc-cae764ce-20241025(react@19.0.0-rc-cae764ce-20241025))(react@19.0.0-rc-cae764ce-20241025) '@radix-ui/react-collapsible': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@19.0.0-rc-cae764ce-20241025(react@19.0.0-rc-cae764ce-20241025))(react@19.0.0-rc-cae764ce-20241025) @@ -17439,7 +17544,7 @@ snapshots: '@radix-ui/react-scroll-area': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@19.0.0-rc-cae764ce-20241025(react@19.0.0-rc-cae764ce-20241025))(react@19.0.0-rc-cae764ce-20241025) '@radix-ui/react-slot': 1.1.0(@types/react@18.3.3)(react@19.0.0-rc-cae764ce-20241025) '@radix-ui/react-tabs': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@19.0.0-rc-cae764ce-20241025(react@19.0.0-rc-cae764ce-20241025))(react@19.0.0-rc-cae764ce-20241025) - '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3))) + '@tailwindcss/typography': 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3))) class-variance-authority: 0.7.0 cmdk: 1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@19.0.0-rc-cae764ce-20241025(react@19.0.0-rc-cae764ce-20241025))(react@19.0.0-rc-cae764ce-20241025) fumadocs-core: 14.0.2(@types/react@18.3.3) @@ -17452,7 +17557,7 @@ snapshots: optionalDependencies: '@algolia/client-search': 4.24.0 algoliasearch: 4.24.0 - tailwindcss: 3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)) + tailwindcss: 3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)) transitivePeerDependencies: - '@babel/core' - '@opentelemetry/api' @@ -18279,6 +18384,25 @@ snapshots: - supports-color - ts-node + jest-cli@29.7.0(@types/node@22.10.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)): + dependencies: + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@22.10.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)) + exit: 0.1.2 + import-local: 3.1.0 + jest-config: 29.7.0(@types/node@22.10.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jest-config@29.7.0(@types/node@20.17.6)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)): dependencies: '@babel/core': 7.26.0 @@ -18341,6 +18465,37 @@ snapshots: - babel-plugin-macros - supports-color + jest-config@29.7.0(@types/node@20.17.6)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)): + dependencies: + '@babel/core': 7.26.0 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.26.0) + chalk: 4.1.2 + ci-info: 3.8.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0(babel-plugin-macros@3.1.0) + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 20.17.6 + ts-node: 10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + jest-config@29.7.0(@types/node@22.10.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)): dependencies: '@babel/core': 7.26.0 @@ -18372,6 +18527,37 @@ snapshots: - babel-plugin-macros - supports-color + jest-config@29.7.0(@types/node@22.10.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)): + dependencies: + '@babel/core': 7.26.0 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.26.0) + chalk: 4.1.2 + ci-info: 3.8.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0(babel-plugin-macros@3.1.0) + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 22.10.2 + ts-node: 10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + jest-diff@29.7.0: dependencies: chalk: 4.1.2 @@ -18626,6 +18812,18 @@ snapshots: - supports-color - ts-node + jest@29.7.0(@types/node@22.10.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)): + dependencies: + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)) + '@jest/types': 29.6.3 + import-local: 3.1.0 + jest-cli: 29.7.0(@types/node@22.10.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jiti@1.21.0: {} jose@5.9.6: {} @@ -18710,6 +18908,12 @@ snapshots: json-buffer@3.0.1: {} + json-diff@1.0.6: + dependencies: + '@ewoudenberg/difflib': 0.1.0 + colors: 1.4.0 + dreamopt: 0.8.0 + json-parse-even-better-errors@2.3.1: {} json-parse-even-better-errors@3.0.2: {} @@ -20333,13 +20537,13 @@ snapshots: postcss: 8.4.38 ts-node: 10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3) - postcss-load-config@4.0.1(postcss@8.4.38)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)): + postcss-load-config@4.0.1(postcss@8.4.38)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)): dependencies: lilconfig: 2.1.0 yaml: 2.6.0 optionalDependencies: postcss: 8.4.38 - ts-node: 10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3) + ts-node: 10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3) postcss-load-config@5.0.2(jiti@1.21.0)(postcss@8.4.38): dependencies: @@ -21837,7 +22041,7 @@ snapshots: transitivePeerDependencies: - ts-node - tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)): + tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -21856,7 +22060,7 @@ snapshots: postcss: 8.4.38 postcss-import: 15.1.0(postcss@8.4.38) postcss-js: 4.0.1(postcss@8.4.38) - postcss-load-config: 4.0.1(postcss@8.4.38)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.1)(typescript@5.6.3)) + postcss-load-config: 4.0.1(postcss@8.4.38)(ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3)) postcss-nested: 6.0.1(postcss@8.4.38) postcss-selector-parser: 6.0.13 resolve: 1.22.8 @@ -22034,6 +22238,26 @@ snapshots: optionalDependencies: '@swc/core': 1.10.1(@swc/helpers@0.5.15) + ts-node@10.9.2(@swc/core@1.10.1(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.6.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.3 + '@types/node': 22.10.2 + acorn: 8.14.0 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.6.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + optionalDependencies: + '@swc/core': 1.10.1(@swc/helpers@0.5.15) + tsconfig-paths@3.15.0: dependencies: '@types/json5': 0.0.29 @@ -22633,6 +22857,8 @@ snapshots: word-wrap@1.2.5: {} + wordwrap@1.0.0: {} + wrap-ansi@6.2.0: dependencies: ansi-styles: 4.3.0 From a4bc46edd773db10ada2bfea83d369b9ed439e10 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Thu, 26 Dec 2024 18:13:18 -0300 Subject: [PATCH 2/4] new upgrade-versions UI --- apps/hub/src/app/admin/search/page.tsx | 5 +- .../upgrade-versions/UpgradeVersionsPage.tsx | 165 +++++++++++++----- .../compare/UpgradeButton.tsx | 28 +++ .../{ => compare}/UpgradeableModel.tsx | 42 +---- .../admin/upgrade-versions/compare/page.tsx | 41 +++++ .../invite-link/AcceptGroupInvitePage.tsx | 5 +- .../members/GroupReusableInviteSection.tsx | 12 +- .../src/components/ui/SafeActionButton.tsx | 25 +-- 8 files changed, 218 insertions(+), 105 deletions(-) create mode 100644 apps/hub/src/app/admin/upgrade-versions/compare/UpgradeButton.tsx rename apps/hub/src/app/admin/upgrade-versions/{ => compare}/UpgradeableModel.tsx (59%) create mode 100644 apps/hub/src/app/admin/upgrade-versions/compare/page.tsx diff --git a/apps/hub/src/app/admin/search/page.tsx b/apps/hub/src/app/admin/search/page.tsx index 72f60e9c02..1372c658d4 100644 --- a/apps/hub/src/app/admin/search/page.tsx +++ b/apps/hub/src/app/admin/search/page.tsx @@ -12,10 +12,11 @@ export default async function AdminSearchPage() { + > + Rebuild + ); } diff --git a/apps/hub/src/app/admin/upgrade-versions/UpgradeVersionsPage.tsx b/apps/hub/src/app/admin/upgrade-versions/UpgradeVersionsPage.tsx index 1e8743e8ce..d06231846d 100644 --- a/apps/hub/src/app/admin/upgrade-versions/UpgradeVersionsPage.tsx +++ b/apps/hub/src/app/admin/upgrade-versions/UpgradeVersionsPage.tsx @@ -1,70 +1,143 @@ "use client"; -import { useRouter } from "next/navigation"; -import { FC, useState } from "react"; +import clsx from "clsx"; +import { FC, useEffect, useState } from "react"; import { Button, + CheckIcon, Dropdown, DropdownMenu, DropdownMenuActionItem, + RefreshIcon, + XIcon, } from "@quri/ui"; -import { defaultSquiggleVersion } from "@quri/versioned-squiggle-components"; +import { + checkSquiggleVersion, + defaultSquiggleVersion, +} from "@quri/versioned-squiggle-components"; +import { compareVersions } from "@quri/versioned-squiggle-components/compareVersions"; import { H2 } from "@/components/ui/Headers"; import { SafeActionButton } from "@/components/ui/SafeActionButton"; import { StyledLink } from "@/components/ui/StyledLink"; -import { modelRoute } from "@/lib/routes"; import { adminUpdateModelVersionAction } from "@/models/actions/adminUpdateModelVersionAction"; import { ModelByVersion } from "@/models/data/byVersion"; -import { UpgradeableModel } from "./UpgradeableModel"; +const ComparedCode: FC<{ + modelId: string; + version: string; + code: string; +}> = ({ modelId, version, code }) => { + const [status, setStatus] = useState< + "loading" | "success" | "error" | "upgraded" + >("loading"); + + useEffect(() => { + if (!checkSquiggleVersion(version)) { + setStatus("error"); + return; + } + + compareVersions({ + version1: version, + version2: defaultSquiggleVersion, + code: code, + }).then((result) => { + if (result) { + setStatus("error"); + } else { + setStatus("success"); + } + }); + }, [version, code]); + + const commonClasses = "w-6 h-6"; + switch (status) { + case "loading": + return ( + + ); + case "success": + return ( +
+ + setStatus("upgraded")} + theme="primary" + size="small" + > + Upgrade to {defaultSquiggleVersion} + +
+ ); + case "upgraded": + return ; + + case "error": + return ; + } +}; + +const ComparedModel: FC<{ + model: ModelByVersion["models"][number]; +}> = ({ model }) => { + const squiggleSnippet = model.currentRevision?.squiggleSnippet; + + if (!squiggleSnippet) { + return null; + } + + const version = squiggleSnippet.version; + + return ( +
+ + {model.owner.slug}/{model.slug} + + +
+ ); +}; const ModelList: FC<{ models: ModelByVersion["models"]; }> = ({ models }) => { - const router = useRouter(); - - const [pos, setPos] = useState(0); + const limitStep = 10; + const [limit, setLimit] = useState(limitStep); if (!models.length) return null; - const usedPos = Math.min(pos, models.length - 1); - const model = models[usedPos]; return (
-
-
- Model:{" "} - - {model.owner.slug}/{model.slug} - -
- router.refresh()} - title={`Upgrade to ${defaultSquiggleVersion}`} - theme="primary" - /> - - +

+ {`In the list below, you'll see the green checkmark if the model's output is identical to the output of the new version. If not, you'll see a red X, but you can go to the model's "compare" page to see the difference and upgrade it manually.`} +

+
+ {models.slice(0, limit).map((model) => ( + + ))}
- + {models.length > limit ? ( + + ) : null}
); }; @@ -100,7 +173,7 @@ export const UpgradeVersionsPage: FC<{ getEntryByVersion(defaultSquiggleVersion)?.models.length ?? 0; return ( -
+

Upgrade model versions

@@ -143,7 +216,11 @@ export const UpgradeVersionsPage: FC<{

- {selectedEntry ? : null} + {selectedEntry ? ( +
+ +
+ ) : null}
); }; diff --git a/apps/hub/src/app/admin/upgrade-versions/compare/UpgradeButton.tsx b/apps/hub/src/app/admin/upgrade-versions/compare/UpgradeButton.tsx new file mode 100644 index 0000000000..08272bfcf0 --- /dev/null +++ b/apps/hub/src/app/admin/upgrade-versions/compare/UpgradeButton.tsx @@ -0,0 +1,28 @@ +"use client"; +import { useRouter } from "next/navigation"; +import { FC } from "react"; + +import { defaultSquiggleVersion } from "@quri/versioned-squiggle-components"; + +import { SafeActionButton } from "@/components/ui/SafeActionButton"; +import { adminUpdateModelVersionAction } from "@/models/actions/adminUpdateModelVersionAction"; +import { ModelFullDTO } from "@/models/data/full"; + +export const UpgradeButton: FC<{ + model: ModelFullDTO; +}> = ({ model }) => { + const router = useRouter(); + return ( + router.refresh()} + theme="primary" + > + Upgrade to {defaultSquiggleVersion} + + ); +}; diff --git a/apps/hub/src/app/admin/upgrade-versions/UpgradeableModel.tsx b/apps/hub/src/app/admin/upgrade-versions/compare/UpgradeableModel.tsx similarity index 59% rename from apps/hub/src/app/admin/upgrade-versions/UpgradeableModel.tsx rename to apps/hub/src/app/admin/upgrade-versions/compare/UpgradeableModel.tsx index 0591fc28ab..c5cca33919 100644 --- a/apps/hub/src/app/admin/upgrade-versions/UpgradeableModel.tsx +++ b/apps/hub/src/app/admin/upgrade-versions/compare/UpgradeableModel.tsx @@ -1,6 +1,5 @@ "use client"; -import { FC, use, useEffect, useState } from "react"; -import Skeleton from "react-loading-skeleton"; +import { FC, use } from "react"; import { defaultSquiggleVersion, @@ -10,12 +9,10 @@ import { } from "@quri/versioned-squiggle-components"; import { EditSquiggleSnippetModel } from "@/app/models/[owner]/[slug]/EditSquiggleSnippetModel"; -import { loadModelFullAction } from "@/models/actions/loadModelFullAction"; -import { ModelByVersion } from "@/models/data/byVersion"; import { ModelFullDTO } from "@/models/data/full"; import { sqProjectWithHubLinker } from "@/squiggle/linker"; -const InnerUpgradeableModel: FC<{ +export const UpgradeableModel: FC<{ model: ModelFullDTO; }> = ({ model }) => { const currentRevision = model.currentRevision; @@ -33,7 +30,7 @@ const InnerUpgradeableModel: FC<{ const project = sqProjectWithHubLinker(squiggle); const updatedProject = sqProjectWithHubLinker(updatedSquiggle); - // TODO - starting from 0.9.5, we will be able to compare serialized outputs for the new and old verison. + // TODO - compare outputs with compareVersions if (versionSupportsSquiggleChart.plain(version)) { const headerClasses = "py-1 px-2 m-1 bg-slate-200 font-medium"; @@ -58,36 +55,3 @@ const InnerUpgradeableModel: FC<{ ); } }; - -export const UpgradeableModel: FC<{ - model: ModelByVersion["models"][number]; -}> = ({ model: incompleteModel }) => { - const [model, setModel] = useState( - "loading" - ); - - useEffect(() => { - // TODO - this is done with a server action, so it's not cached. - // A route would be better. - loadModelFullAction({ - owner: incompleteModel.owner.slug, - slug: incompleteModel.slug, - }).then((result) => { - if (result?.data) { - setModel(result.data); - } else { - setModel(null); - } - }); - }, [incompleteModel]); - - if (model === "loading") { - return ; - } - - if (!model) { - return
Model not found
; - } - - return ; -}; diff --git a/apps/hub/src/app/admin/upgrade-versions/compare/page.tsx b/apps/hub/src/app/admin/upgrade-versions/compare/page.tsx new file mode 100644 index 0000000000..8cb5dfc75f --- /dev/null +++ b/apps/hub/src/app/admin/upgrade-versions/compare/page.tsx @@ -0,0 +1,41 @@ +import { notFound } from "next/navigation"; + +import { StyledLink } from "@/components/ui/StyledLink"; +import { modelRoute } from "@/lib/routes"; +import { loadModelFull } from "@/models/data/full"; + +import { UpgradeableModel } from "./UpgradeableModel"; +import { UpgradeButton } from "./UpgradeButton"; + +type Props = { + searchParams: Promise<{ owner: string; slug: string }>; +}; + +export default async function CompareVersionsPage({ searchParams }: Props) { + const { owner, slug } = await searchParams; + + const model = await loadModelFull({ owner, slug }); + if (!model) { + notFound(); + } + + const { contentType } = model.currentRevision; + if (contentType !== "SquiggleSnippet") { + notFound(); + } + + return ( +
+ + {model.owner.slug}/{model.slug} + + + +
+ ); +} diff --git a/apps/hub/src/app/groups/[slug]/invite-link/AcceptGroupInvitePage.tsx b/apps/hub/src/app/groups/[slug]/invite-link/AcceptGroupInvitePage.tsx index a6e2943709..e6bd4ca1ef 100644 --- a/apps/hub/src/app/groups/[slug]/invite-link/AcceptGroupInvitePage.tsx +++ b/apps/hub/src/app/groups/[slug]/invite-link/AcceptGroupInvitePage.tsx @@ -20,7 +20,6 @@ export const AcceptGroupInvitePage: FC<{

{`You've been invited to join ${group.slug} group.`}

{ @@ -31,7 +30,9 @@ export const AcceptGroupInvitePage: FC<{ groupSlug: group.slug, inviteToken, }} - /> + > + Join this group +
); }; diff --git a/apps/hub/src/app/groups/[slug]/members/GroupReusableInviteSection.tsx b/apps/hub/src/app/groups/[slug]/members/GroupReusableInviteSection.tsx index b5b516fc98..9c623123cf 100644 --- a/apps/hub/src/app/groups/[slug]/members/GroupReusableInviteSection.tsx +++ b/apps/hub/src/app/groups/[slug]/members/GroupReusableInviteSection.tsx @@ -75,16 +75,16 @@ export const GroupReusableInviteSection: FC = ({ + > + {reusableInviteToken ? "Reset Invite Link" : "Create Invite Link"} + {reusableInviteToken ? ( + > + Delete Invite Link + ) : null}
diff --git a/apps/hub/src/components/ui/SafeActionButton.tsx b/apps/hub/src/components/ui/SafeActionButton.tsx index 309cd5c933..5aefc3c38a 100644 --- a/apps/hub/src/components/ui/SafeActionButton.tsx +++ b/apps/hub/src/components/ui/SafeActionButton.tsx @@ -4,7 +4,7 @@ import { InferSafeActionFnResult, } from "next-safe-action"; import { HookSafeActionFn, useAction } from "next-safe-action/hooks"; -import { ReactNode } from "react"; +import { PropsWithChildren, ReactNode } from "react"; import { Button, useToast } from "@quri/ui"; @@ -13,21 +13,22 @@ export function SafeActionButton< >({ action, input, - title, confirmation, onSuccess, // button props theme, size, -}: { - action: Action; - input: InferSafeActionFnInput["clientInput"]; - onSuccess?: ( - data: NonNullable["data"]> - ) => void; - title: string; - confirmation?: string; -} & Pick[0], "theme" | "size">): ReactNode { + children, +}: PropsWithChildren< + { + action: Action; + input: InferSafeActionFnInput["clientInput"]; + onSuccess?: ( + data: NonNullable["data"]> + ) => void; + confirmation?: string; + } & Pick[0], "theme" | "size"> +>): ReactNode { const toast = useToast(); const { execute, isPending } = useAction(action, { @@ -50,7 +51,7 @@ export function SafeActionButton< return (
execute(input)}>
); From 4f24c0f7bee1fa3d4d217d20cf461ebda5142b49 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Thu, 26 Dec 2024 18:13:58 -0300 Subject: [PATCH 3/4] lint fix --- internal-packages/versioned-components/src/compareVersions.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/internal-packages/versioned-components/src/compareVersions.ts b/internal-packages/versioned-components/src/compareVersions.ts index 6da3b14010..b489dac7bb 100644 --- a/internal-packages/versioned-components/src/compareVersions.ts +++ b/internal-packages/versioned-components/src/compareVersions.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import jsonDiff from "json-diff"; import { From 2ffceb259f0389540e741ca219bd829e6012cd6f Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Thu, 26 Dec 2024 18:22:28 -0300 Subject: [PATCH 4/4] tuning compare page --- .../upgrade-versions/UpgradeVersionsPage.tsx | 11 ------ .../compare/UpgradeButton.tsx | 8 +++++ .../admin/upgrade-versions/compare/page.tsx | 34 ++++++++++++++----- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/apps/hub/src/app/admin/upgrade-versions/UpgradeVersionsPage.tsx b/apps/hub/src/app/admin/upgrade-versions/UpgradeVersionsPage.tsx index d06231846d..6fdbd1bfd5 100644 --- a/apps/hub/src/app/admin/upgrade-versions/UpgradeVersionsPage.tsx +++ b/apps/hub/src/app/admin/upgrade-versions/UpgradeVersionsPage.tsx @@ -175,17 +175,6 @@ export const UpgradeVersionsPage: FC<{ return (

Upgrade model versions

-
-

- Check models with their current version and the new version, then - press the upgrade button if everything is ok. -

-

- - {`Code edits won't be saved, "Upgrade" button bumps only the model's version.`} - -

-
Dev models: {devCount}
diff --git a/apps/hub/src/app/admin/upgrade-versions/compare/UpgradeButton.tsx b/apps/hub/src/app/admin/upgrade-versions/compare/UpgradeButton.tsx index 08272bfcf0..2a85e2aca1 100644 --- a/apps/hub/src/app/admin/upgrade-versions/compare/UpgradeButton.tsx +++ b/apps/hub/src/app/admin/upgrade-versions/compare/UpgradeButton.tsx @@ -12,6 +12,14 @@ export const UpgradeButton: FC<{ model: ModelFullDTO; }> = ({ model }) => { const router = useRouter(); + + if ( + model.currentRevision.contentType === "SquiggleSnippet" && + model.currentRevision.squiggleSnippet.version === defaultSquiggleVersion + ) { + return null; + } + return ( - - {model.owner.slug}/{model.slug} - - +

+
+
+ Compare model{" "} + + {model.owner.slug}/{model.slug} + +
+ +
+

+
+

+ Check models with their current version and the new version, then + press the upgrade button if everything is ok. +

+

+ + {`Code edits won't be saved, "Upgrade" button bumps only the model's version.`} + +

+
);