@tscircuit/fake-snippets 0.0.66 → 0.0.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/bun-tests/fake-snippets-api/fixtures/get-circuit-json.ts +5 -143
  2. package/bun-tests/fake-snippets-api/fixtures/get-test-server.ts +1 -4
  3. package/bun-tests/fake-snippets-api/fixtures/start-server.ts +7 -3
  4. package/bun-tests/fake-snippets-api/routes/order_quotes/create.test.ts +20 -56
  5. package/bun-tests/fake-snippets-api/routes/package_files/create_or_update.test.ts +2 -2
  6. package/bun-tests/fake-snippets-api/routes/package_releases/update.test.ts +1 -1
  7. package/bun-tests/fake-snippets-api/routes/packages/images.test.ts +0 -11
  8. package/bun.lock +15 -17
  9. package/dist/bundle.js +32 -39
  10. package/fake-snippets-api/routes/api/order_quotes/create.ts +30 -37
  11. package/fake-snippets-api/routes/api/order_quotes/get.ts +5 -8
  12. package/package.json +4 -3
  13. package/src/App.tsx +0 -7
  14. package/src/ContextProviders.tsx +2 -0
  15. package/src/components/DownloadButtonAndMenu.tsx +1 -4
  16. package/src/components/Footer.tsx +5 -2
  17. package/src/components/HeaderLogin.tsx +37 -54
  18. package/src/components/ImageWithFallback.tsx +37 -0
  19. package/src/components/JLCPCBImportDialog.tsx +43 -24
  20. package/src/components/PackageCard.tsx +2 -2
  21. package/src/components/{SnippetLink.tsx → PackageLink.tsx} +8 -16
  22. package/src/components/PackageSearchResults.tsx +87 -0
  23. package/src/components/PackagesList.tsx +3 -3
  24. package/src/components/PageSearchComponent.tsx +9 -9
  25. package/src/components/ViewPackagePage/components/ShikiCodeViewer.tsx +5 -28
  26. package/src/components/ViewPackagePage/components/main-content-header.tsx +8 -8
  27. package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +24 -14
  28. package/src/components/ViewPackagePage/components/package-header.tsx +6 -1
  29. package/src/components/package-port/CodeEditor.tsx +13 -10
  30. package/src/components/package-port/CodeEditorHeader.tsx +1 -1
  31. package/src/components/package-port/EditorNav.tsx +2 -2
  32. package/src/hooks/use-global-store.ts +1 -0
  33. package/src/hooks/use-shiki-highlighter.ts +13 -6
  34. package/src/lib/download-fns/download-gltf.ts +3 -10
  35. package/src/lib/handleManualEditsImport.tsx +1 -1
  36. package/src/lib/types.ts +4 -2
  37. package/src/pages/dashboard.tsx +3 -4
  38. package/src/pages/editor.tsx +20 -14
  39. package/src/pages/latest.tsx +25 -26
  40. package/src/pages/search.tsx +120 -19
  41. package/src/pages/trending.tsx +14 -58
  42. package/src/pages/user-profile.tsx +13 -8
  43. package/bun-tests/fake-snippets-api/routes/snippets/add_star.test.ts +0 -84
  44. package/bun-tests/fake-snippets-api/routes/snippets/create.test.ts +0 -53
  45. package/bun-tests/fake-snippets-api/routes/snippets/delete.test.ts +0 -82
  46. package/bun-tests/fake-snippets-api/routes/snippets/download.test.ts +0 -90
  47. package/bun-tests/fake-snippets-api/routes/snippets/generate_from_jlcpcb.test.ts +0 -16
  48. package/bun-tests/fake-snippets-api/routes/snippets/get.test.ts +0 -163
  49. package/bun-tests/fake-snippets-api/routes/snippets/get_image.test.ts +0 -117
  50. package/bun-tests/fake-snippets-api/routes/snippets/images.test.ts +0 -114
  51. package/bun-tests/fake-snippets-api/routes/snippets/list.test.ts +0 -169
  52. package/bun-tests/fake-snippets-api/routes/snippets/list_newest.test.ts +0 -50
  53. package/bun-tests/fake-snippets-api/routes/snippets/list_trending.test.ts +0 -72
  54. package/bun-tests/fake-snippets-api/routes/snippets/remove_star.test.ts +0 -80
  55. package/bun-tests/fake-snippets-api/routes/snippets/search.test.ts +0 -75
  56. package/bun-tests/fake-snippets-api/routes/snippets/star-count.test.ts +0 -51
  57. package/bun-tests/fake-snippets-api/routes/snippets/update.test.ts +0 -175
  58. package/src/components/AiChatInterface.tsx +0 -229
  59. package/src/components/CodeAndPreview.tsx +0 -289
  60. package/src/components/CodeEditor.tsx +0 -539
  61. package/src/components/CodeEditorHeader.tsx +0 -135
  62. package/src/components/EditorNav.tsx +0 -502
  63. package/src/components/PreviewContent.tsx +0 -372
  64. package/src/components/SnippetCard.tsx +0 -159
  65. package/src/components/SnippetList.tsx +0 -71
  66. package/src/hooks/use-compiled-tsx.ts +0 -37
  67. package/src/hooks/use-run-tsx/construct-circuit.tsx +0 -62
  68. package/src/hooks/use-run-tsx/index.tsx +0 -256
  69. package/src/hooks/use-save-snippet.ts +0 -66
  70. package/src/hooks/use-typecheck.ts +0 -54
  71. package/src/lib/utils/getSyntaxError.ts +0 -13
  72. package/src/pages/ai.tsx +0 -92
  73. package/src/pages/view-snippet.tsx +0 -166
@@ -1,148 +1,10 @@
1
- import * as React from "react"
2
- import { getImportsFromCode } from "@tscircuit/prompt-benchmarks/code-runner-utils"
3
- import * as tscircuitCore from "@tscircuit/core"
4
- import * as jscadFiber from "jscad-fiber"
5
1
  import type { AnyCircuitElement } from "circuit-json"
6
- import { safeCompileTsx } from "@/hooks/use-compiled-tsx"
7
- import { evalCompiledJs } from "@/hooks/use-run-tsx/eval-compiled-js"
8
- import { constructCircuit } from "@/hooks/use-run-tsx/construct-circuit"
9
-
10
- type GenerateCircuitJson = {
11
- code: string
12
- type: "board" | "footprint" | "package" | "model"
13
- compiled_js: string
14
- }
15
-
16
- // Keeping track of processed imports to avoid circular dependencies
17
- const processedImports = new Set<string>()
18
-
19
- async function processImport(
20
- importName: string,
21
- preSuppliedImports: Record<string, any>,
22
- depth = 0,
23
- code: string,
24
- compiled_js: string,
25
- ): Promise<void> {
26
- if (!importName.startsWith("@tsci/")) return
27
- if (preSuppliedImports[importName]) return
28
- if (processedImports.has(importName)) return
29
- if (depth > 5) {
30
- throw new Error(
31
- `Max depth for imports reached when processing ${importName}`,
32
- )
33
- }
34
-
35
- processedImports.add(importName)
36
-
37
- try {
38
- // Process nested imports first
39
- const nestedImports = getImportsFromCode(code)
40
-
41
- // Filter out already processed imports and non-@tsci imports
42
- const validNestedImports = nestedImports.filter(
43
- (imp) =>
44
- imp.startsWith("@tsci/") &&
45
- !processedImports.has(imp) &&
46
- !preSuppliedImports[imp],
47
- )
48
-
49
- // Process each valid nested import
50
- for (const nestedImport of validNestedImports) {
51
- await processImport(
52
- nestedImport,
53
- preSuppliedImports,
54
- depth + 1,
55
- code,
56
- compiled_js,
57
- )
58
- }
59
- // Set React in the global scope before evaluation
60
- ;(globalThis as any).React = React
61
- const exports = evalCompiledJs(compiled_js).exports
62
-
63
- // Only set the import if we successfully evaluated it
64
- if (exports) {
65
- preSuppliedImports[importName] = exports
66
- }
67
- } catch (e) {
68
- processedImports.delete(importName) // Clean up on error
69
- }
70
- }
2
+ import { runTscircuitCode } from "@tscircuit/eval"
71
3
 
72
4
  export const generateCircuitJson = async ({
73
5
  code,
74
- type,
75
- compiled_js,
76
- }: GenerateCircuitJson): Promise<AnyCircuitElement[]> => {
77
- // Clear the processed imports set at the start of each generation
78
- processedImports.clear()
79
-
80
- // Set up pre-supplied imports
81
- const preSuppliedImports: Record<string, any> = {
82
- "@tscircuit/core": tscircuitCore,
83
- react: React,
84
- "jscad-fiber": jscadFiber,
85
- }
86
- ;(globalThis as any).React = React
87
- ;(globalThis as any).createElement = React.createElement
88
-
89
- try {
90
- // Process all @tsci imports
91
- const tsciImports = getImportsFromCode(code).filter((imp) =>
92
- imp.startsWith("@tsci/"),
93
- )
94
- for (const importName of tsciImports) {
95
- await processImport(importName, preSuppliedImports, 0, code, compiled_js)
96
- }
97
-
98
- // Create require function for imports
99
- const __tscircuit_require = (name: string) => {
100
- if (!preSuppliedImports[name]) {
101
- throw new Error(
102
- `Import "${name}" not found (available imports: ${Object.keys(preSuppliedImports).join(", ")})`,
103
- )
104
- }
105
- return preSuppliedImports[name]
106
- }
107
- ;(globalThis as any).__tscircuit_require = __tscircuit_require
108
-
109
- // Add a custom JSX runtime
110
- ;(globalThis as any).jsx = React.createElement
111
- ;(globalThis as any).jsxs = React.createElement
112
-
113
- const { success, compiledTsx, error } = safeCompileTsx(code)
114
- if (!success || !compiledTsx) {
115
- throw new Error(
116
- `Compile Error: ${error?.message || "Unknown compilation error"}`,
117
- )
118
- }
119
-
120
- const module = evalCompiledJs(compiledTsx)
121
- const componentExportKeys = Object.keys(module.exports).filter(
122
- (key) => !key.startsWith("use"),
123
- )
124
-
125
- if (componentExportKeys.length > 1) {
126
- throw new Error(
127
- `Too many exports, only export one component. Exports: ${JSON.stringify(componentExportKeys)}`,
128
- )
129
- }
130
-
131
- const primaryKey = componentExportKeys[0]
132
-
133
- // Create the user element with explicit React scope
134
- const UserElm = function (props: any) {
135
- return React.createElement(module.exports[primaryKey], props)
136
- }
137
-
138
- // Construct and render the circuit
139
- const circuit = constructCircuit({ UserElm, type })
140
-
141
- // Wait for the circuit to settle
142
- await circuit.renderUntilSettled()
143
-
144
- return circuit.getCircuitJson() as AnyCircuitElement[]
145
- } catch (e) {
146
- throw new Error("Circuit generation failed!")
147
- }
6
+ }: {
7
+ code: string
8
+ }): Promise<AnyCircuitElement[]> => {
9
+ return (await runTscircuitCode(code)) as any
148
10
  }
@@ -2,7 +2,6 @@ import { afterEach } from "bun:test"
2
2
  import defaultAxios from "redaxios"
3
3
  import { startServer } from "./start-server"
4
4
  import { DbClient } from "fake-snippets-api/lib/db/db-client"
5
- import getPort from "get-port"
6
5
 
7
6
  process.env.BUN_TEST = "true"
8
7
  interface TestFixture {
@@ -16,12 +15,10 @@ interface TestFixture {
16
15
  }
17
16
 
18
17
  export const getTestServer = async (): Promise<TestFixture> => {
19
- const port = await getPort()
20
18
  const testInstanceId = Math.random().toString(36).substring(2, 15)
21
19
  const testDbName = `testdb${testInstanceId}`
22
20
 
23
- const { server, db } = await startServer({
24
- port,
21
+ const { server, db, port } = await startServer({
25
22
  testDbName,
26
23
  })
27
24
 
@@ -11,7 +11,7 @@ import { createDatabase } from "fake-snippets-api/lib/db/db-client"
11
11
  export const startServer = async ({
12
12
  port,
13
13
  testDbName,
14
- }: { port: number; testDbName: string }) => {
14
+ }: { port?: number; testDbName: string }) => {
15
15
  const winterspecBundle = await createWinterSpecBundleFromDir(
16
16
  join(import.meta.dir, "../../../fake-snippets-api/routes"),
17
17
  )
@@ -37,8 +37,12 @@ export const startServer = async ({
37
37
  middleware,
38
38
  })
39
39
  },
40
- port,
40
+ port: port ?? 0,
41
41
  })
42
42
 
43
- return { server: { ...server, stop: () => server.stop() }, db }
43
+ return {
44
+ server: { ...server, stop: () => server.stop() },
45
+ db,
46
+ port: server.port,
47
+ }
44
48
  }
@@ -1,69 +1,33 @@
1
1
  import { getTestServer } from "bun-tests/fake-snippets-api/fixtures/get-test-server"
2
2
  import { test, expect } from "bun:test"
3
3
 
4
- test("create order_quote with only circuit_json (✅)", async () => {
5
- const {
6
- axios,
7
- seed: { order },
8
- } = await getTestServer()
9
-
10
- const response = await axios.post("/api/order_quotes/create", {
11
- vendor_name: "jlcpcb",
12
- circuit_json: order.circuit_json,
13
- })
4
+ test("create order_quote with only package_release_id (✅)", async () => {
5
+ const { axios, jane_axios } = await getTestServer()
14
6
 
15
- expect(response.status).toBe(200)
16
- expect(response.data.order_quote_id).toBeDefined()
17
- })
7
+ const pkg = await jane_axios
8
+ .post("/api/packages/create", {
9
+ name: "jane/test-package",
10
+ })
11
+ .then((res) => res.data.package)
18
12
 
19
- test("create order_quote with only package_release_id (✅)", async () => {
20
- const {
21
- axios,
22
- seed: { packageRelease },
23
- } = await getTestServer()
13
+ const packageRelease = await jane_axios
14
+ .post("/api/package_releases/create", {
15
+ package_id: pkg.package_id,
16
+ version: "1.0.0",
17
+ is_latest: true,
18
+ })
19
+ .then((res) => res.data.package_release)
24
20
 
21
+ await jane_axios.post(`/api/package_files/create`, {
22
+ package_release_id: packageRelease.package_release_id,
23
+ file_path: "/dist/index.js",
24
+ content_text: "console.log('Hello, world!');",
25
+ })
25
26
  const response = await axios.post("/api/order_quotes/create", {
26
27
  vendor_name: "jlcpcb",
27
- package_release_id: packageRelease!.package_release_id,
28
+ package_release_id: packageRelease.package_release_id,
28
29
  })
29
30
 
30
31
  expect(response.status).toBe(200)
31
32
  expect(response.data.order_quote_id).toBeDefined()
32
33
  })
33
-
34
- test("create order_quote with both circuit_json and package_release_id (✅)", async () => {
35
- const {
36
- axios,
37
- seed: { order, packageRelease },
38
- } = await getTestServer()
39
-
40
- const response = await axios
41
- .post("/api/order_quotes/create", {
42
- vendor_name: "jlcpcb",
43
- circuit_json: order.circuit_json,
44
- package_release_id: packageRelease!.package_release_id,
45
- })
46
- .catch((error) => error) // Capture response even on error
47
-
48
- // Expecting backend to fail with 400
49
- expect(response?.status).toBe(400)
50
- expect(response?.data.message).toContain(
51
- "You must provide either circuit_json or package_release_id, but not both.",
52
- )
53
- })
54
-
55
- test("create order_quote with neither circuit_json nor package_release_id (✅)", async () => {
56
- const { axios } = await getTestServer()
57
-
58
- const response = await axios
59
- .post("/api/order_quotes/create", {
60
- vendor_name: "jlcpcb",
61
- })
62
- .catch((error) => error) // Capture response even on error
63
-
64
- // Expecting backend to fail with 400
65
- expect(response?.status).toBe(400)
66
- expect(response?.data.message).toContain(
67
- "You must provide either circuit_json or package_release_id.",
68
- )
69
- })
@@ -398,7 +398,7 @@ test("create_or_update - 404 for npm_pack_output without is_release_tarball", as
398
398
  }
399
399
  })
400
400
 
401
- test("update package file with content_base64", async () => {
401
+ test.skip("update package file with content_base64", async () => {
402
402
  const { axios } = await getTestServer()
403
403
 
404
404
  const packageResponse = await axios.post("/api/packages/create", {
@@ -506,7 +506,7 @@ test("create_or_update detects correct content mimetype", async () => {
506
506
  }
507
507
  })
508
508
 
509
- test("create_or_update respects provided content_mimetype", async () => {
509
+ test.skip("create_or_update respects provided content_mimetype", async () => {
510
510
  const { axios } = await getTestServer()
511
511
 
512
512
  const packageResponse = await axios.post("/api/packages/create", {
@@ -69,7 +69,7 @@ test("update package release using package_name_with_version", async () => {
69
69
  expect(updatedRelease?.is_locked).toBe(true)
70
70
  })
71
71
 
72
- test("update package release - handle is_latest flag", async () => {
72
+ test.skip("update package release - handle is_latest flag", async () => {
73
73
  const { axios, db } = await getTestServer()
74
74
 
75
75
  // Create a package
@@ -27,17 +27,6 @@ export default () => (
27
27
  <A555Timer name="U1" />
28
28
  </board>
29
29
  )`.trim(),
30
- type: "board",
31
- compiled_js: `
32
- "use strict";
33
- Object.defineProperty(exports, "__esModule", { value: true });
34
- exports.A555Timer = void 0;
35
- const A555Timer = ({ name }) => /*#__PURE__*/React.createElement("chip", {
36
- name: name,
37
- footprint: "dip8"
38
- });
39
- exports.A555Timer = A555Timer;
40
- `.trim(),
41
30
  })
42
31
  // create a package file
43
32
  const pkg_file = await axios.post("/api/package_files/create", {
package/bun.lock CHANGED
@@ -42,7 +42,7 @@
42
42
  "@radix-ui/react-toggle-group": "^1.1.0",
43
43
  "@radix-ui/react-tooltip": "^1.1.2",
44
44
  "@tscircuit/3d-viewer": "^0.0.142",
45
- "@tscircuit/eval": "^0.0.170",
45
+ "@tscircuit/eval": "^0.0.198",
46
46
  "@tscircuit/footprinter": "^0.0.124",
47
47
  "@tscircuit/layout": "^0.0.29",
48
48
  "@tscircuit/math-utils": "^0.0.10",
@@ -119,7 +119,7 @@
119
119
  "@tailwindcss/typography": "^0.5.16",
120
120
  "@tscircuit/core": "^0.0.384",
121
121
  "@tscircuit/prompt-benchmarks": "^0.0.28",
122
- "@tscircuit/runframe": "^0.0.439",
122
+ "@tscircuit/runframe": "^0.0.461",
123
123
  "@types/babel__standalone": "^7.1.7",
124
124
  "@types/bun": "^1.1.10",
125
125
  "@types/country-list": "^2.1.4",
@@ -709,7 +709,7 @@
709
709
 
710
710
  "@tscircuit/create-snippet-url": ["@tscircuit/create-snippet-url@0.0.8", "", { "dependencies": { "fflate": "^0.8.2" }, "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-VMixgwQRsOXlQGwVh2RZIFLLtsn8YWl2Bht61T26MHNM71A1Wzo5qGZtqcdbVkFnvlA42KmdVVjvxYDvEyWdJw=="],
711
711
 
712
- "@tscircuit/eval": ["@tscircuit/eval@0.0.170", "", { "peerDependencies": { "@tscircuit/core": "*", "circuit-json": "*", "jscad-fiber": "*", "typescript": "^5.0.0" } }, "sha512-pL8zxhjlXnP4eBenLRycOcVH32BM8akDdig8hZ895/HqNeMLBSJOfWll1trXnEMaOzgPkK6O53OY8D7jkhsLTw=="],
712
+ "@tscircuit/eval": ["@tscircuit/eval@0.0.198", "", { "peerDependencies": { "@tscircuit/core": "*", "circuit-json": "*", "jscad-fiber": "*", "typescript": "^5.0.0" } }, "sha512-OQxb01iPAze88US0jotwdorIaNB5rwzrOyD5CvBqeHrcYKXkeEYXcMmps0frOLwIen3Q8TcOcf2xP3XpQd5wjA=="],
713
713
 
714
714
  "@tscircuit/featured-snippets": ["@tscircuit/featured-snippets@0.0.1", "", { "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-SNUbCQmyaAaWq7DqqDbYlZkYttbfaObtp5rOheZvlJ2TGYvooECFpB8SzNo06bqKGoIwNjgaAGUTB2DcxdX7ow=="],
715
715
 
@@ -727,7 +727,7 @@
727
727
 
728
728
  "@tscircuit/mm": ["@tscircuit/mm@0.0.8", "", { "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-nl7nxE7AhARbKuobflI0LUzoir7+wJyvwfPw6bzA/O0Q3YTcH3vBkU/Of+V/fp6ht+AofiCXj7YAH9E446138Q=="],
729
729
 
730
- "@tscircuit/pcb-viewer": ["@tscircuit/pcb-viewer@1.11.120", "", { "dependencies": { "@emotion/css": "^11.11.2", "@tscircuit/core": "^0.0.387", "@tscircuit/math-utils": "^0.0.18", "circuit-json-to-connectivity-map": "^0.0.20", "circuit-to-svg": "^0.0.36", "color": "^4.2.3", "graphics-debug": "^0.0.24", "react-supergrid": "^1.0.10", "react-toastify": "^10.0.5", "transformation-matrix": "^2.13.0", "zustand": "^4.5.2" }, "peerDependencies": { "react": "*" } }, "sha512-E8425jmsy85T6jdEO2f3KLRYvnPmBEY5faj5QIg8njd/4C67XPmUS6VtQnSrSv/fjF9DzPaPa/VtyNHxaNYGYw=="],
730
+ "@tscircuit/pcb-viewer": ["@tscircuit/pcb-viewer@1.11.133", "", { "dependencies": { "@emotion/css": "^11.11.2", "@tscircuit/core": "^0.0.403", "@tscircuit/math-utils": "^0.0.18", "circuit-json-to-connectivity-map": "^0.0.22", "circuit-to-svg": "^0.0.36", "color": "^4.2.3", "graphics-debug": "^0.0.24", "react-supergrid": "^1.0.10", "react-toastify": "^10.0.5", "transformation-matrix": "^2.13.0", "zustand": "^4.5.2" }, "peerDependencies": { "react": "*" } }, "sha512-i4b7+fU9ce/w7axfzNEHxy9o6El//8+tYwnpqS+qNmqEepthwfEFJ/ixoqPDwo2MOYbimLqZA6VaYtMgwYWxcw=="],
731
731
 
732
732
  "@tscircuit/prompt-benchmarks": ["@tscircuit/prompt-benchmarks@0.0.28", "", { "dependencies": { "@babel/standalone": "^7.25.7", "@tscircuit/featured-snippets": "^0.0.1", "@tscircuit/footprinter": "^0.0.102", "debug": "^4.3.7", "dotenv": "^16.4.7", "evalite": "^0.8.2", "extract-codefence": "^0.0.4", "toml": "^3.0.0" }, "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-SOhKWAWp3bSvUvbGbtl1ygyyDhF42IbezS965fyUz5cUMJVFyGOoRD0kJak78NVqmHHDMRRPf1R8c5UUaIdBnw=="],
733
733
 
@@ -735,7 +735,7 @@
735
735
 
736
736
  "@tscircuit/routing": ["@tscircuit/routing@1.3.5", "", { "dependencies": { "bs58": "^5.0.0", "pathfinding": "^0.4.18", "react-error-boundary": "^4.0.11" } }, "sha512-6qHGsKC731TbeaqiQToHS5Zao+93nv99LjbpI479Bqz8Avc8CAUax9QnhMhJ5KvYQv5zLtjv2ywezzRxZf09ZA=="],
737
737
 
738
- "@tscircuit/runframe": ["@tscircuit/runframe@0.0.439", "", { "dependencies": { "@radix-ui/react-alert-dialog": "^1.1.6", "@radix-ui/react-checkbox": "^1.1.4", "@radix-ui/react-dialog": "^1.1.11", "@radix-ui/react-dropdown-menu": "^2.1.4", "@radix-ui/react-icons": "^1.3.2", "@radix-ui/react-progress": "^1.1.2", "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-tabs": "^1.1.2", "@tscircuit/3d-viewer": "^0.0.214", "@tscircuit/assembly-viewer": "^0.0.1", "@tscircuit/core": "^0.0.401", "@tscircuit/create-snippet-url": "^0.0.8", "@tscircuit/eval": "^0.0.194", "@tscircuit/file-server": "^0.0.23", "@tscircuit/pcb-viewer": "^1.11.111", "@tscircuit/props": "^0.0.177", "@tscircuit/schematic-viewer": "2.0.19", "circuit-to-svg": "^0.0.123", "clsx": "^2.1.1", "comlink": "^4.4.2", "cssnano": "^7.0.6", "jscad-fiber": "^0.0.77", "lucide-react": "^0.488.0", "react-query": "^3.39.3", "schematic-symbols": "^0.0.111", "tailwind-merge": "^2.6.0", "tailwindcss-animate": "^1.0.7" }, "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-4o9/RG0uo4wgyRF0XTM5YO6XEqZhds8wr9AOXLU8UOo9QlgXYsXRpsiL2aZBuTrNtLmzyIrPqWKzbqJZ18p7Dg=="],
738
+ "@tscircuit/runframe": ["@tscircuit/runframe@0.0.461", "", { "dependencies": { "@radix-ui/react-alert-dialog": "^1.1.6", "@radix-ui/react-checkbox": "^1.1.4", "@radix-ui/react-dialog": "^1.1.11", "@radix-ui/react-dropdown-menu": "^2.1.4", "@radix-ui/react-icons": "^1.3.2", "@radix-ui/react-progress": "^1.1.2", "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-tabs": "^1.1.2", "@tscircuit/3d-viewer": "^0.0.220", "@tscircuit/assembly-viewer": "^0.0.1", "@tscircuit/core": "^0.0.408", "@tscircuit/create-snippet-url": "^0.0.8", "@tscircuit/eval": "^0.0.203", "@tscircuit/file-server": "^0.0.23", "@tscircuit/pcb-viewer": "^1.11.133", "@tscircuit/props": "^0.0.179", "@tscircuit/schematic-viewer": "2.0.19", "circuit-to-svg": "^0.0.123", "clsx": "^2.1.1", "comlink": "^4.4.2", "cssnano": "^7.0.6", "jscad-fiber": "^0.0.77", "lucide-react": "^0.488.0", "react-query": "^3.39.3", "schematic-symbols": "^0.0.111", "tailwind-merge": "^2.6.0", "tailwindcss-animate": "^1.0.7" }, "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-AKV+4VbYttD0Z2oLZ6BtFF76BcGO0mZGZm54VOsqR2ydWa1std0DVugtGM5kFgQlua+7nXsz7vlGiTqj+U5VRA=="],
739
739
 
740
740
  "@tscircuit/schematic-autolayout": ["@tscircuit/schematic-autolayout@0.0.6", "", { "dependencies": { "@tscircuit/soup-util": "^0.0.38", "transformation-matrix": "^2.16.1" } }, "sha512-34cQxtlSylBKyHkzaMBCynaWJgN9c/mWm7cz63StTYIafKmfFs383K8Xoc4QX8HXCvVrHYl1aK15onZua9MxeA=="],
741
741
 
@@ -2809,23 +2809,25 @@
2809
2809
 
2810
2810
  "@tscircuit/file-server/winterspec": ["winterspec@0.0.86", "", { "dependencies": { "@anatine/zod-openapi": "^2.2.3", "@edge-runtime/node-utils": "^2.3.0", "@edge-runtime/primitives": "^4.1.0", "async-mutex": "^0.4.1", "birpc": "^0.2.17", "bundle-require": "^4.0.2", "camelcase": "^8.0.0", "clipanion": "^4.0.0-rc.3", "edge-runtime": "^2.5.9", "esbuild": "^0.19.11", "globby": "^14.0.0", "human-readable": "^0.2.1", "kleur": "^4.1.5", "make-vfs": "^1.1.0", "next-route-matcher": "^1.0.2", "object-hash": "^3.0.0", "ora": "^8.0.1", "ts-morph": "^21.0.1", "watcher": "^2.3.0", "yargs": "^17.7.2", "zod": "^3.22.4" }, "peerDependencies": { "@ava/get-port": ">=2.0.0", "typescript": ">=4.0.0" }, "optionalPeers": ["@ava/get-port", "typescript"], "bin": { "winterspec": "dist/cli/cli.js" } }, "sha512-lErhEec/+hflbzyAHywJsyKs6nl5G/trBQX32D9R4YD3CJQ7BgSKgkaHu7Gm3Yk9Rr6KlvLTm6lYyPfDCTY6mA=="],
2811
2811
 
2812
- "@tscircuit/pcb-viewer/@tscircuit/core": ["@tscircuit/core@0.0.387", "", { "dependencies": { "@lume/kiwi": "^0.4.3", "@tscircuit/capacity-autorouter": "^0.0.52", "@tscircuit/checks": "^0.0.37", "@tscircuit/circuit-json-util": "^0.0.47", "@tscircuit/infgrid-ijump-astar": "^0.0.33", "@tscircuit/math-utils": "^0.0.14", "@tscircuit/props": "^0.0.172", "@tscircuit/schematic-autolayout": "^0.0.6", "circuit-json": "0.0.160", "circuit-json-to-connectivity-map": "^0.0.20", "css-select": "^5.1.0", "format-si-unit": "^0.0.3", "nanoid": "^5.0.7", "performance-now": "^2.1.0", "react-reconciler": "^0.31.0", "react-reconciler-18": "npm:react-reconciler@0.29.2", "schematic-symbols": "^0.0.121", "transformation-matrix": "^2.16.1", "zod": "^3.23.8" }, "peerDependencies": { "@tscircuit/footprinter": "*", "typescript": "^5.0.0" } }, "sha512-ucqmPhbn46782V00Wf79WPj4c6qTBvykkkdXYKSSMFRJBU0Sne8X/Q85emdR+cxiPO0/lLWw6Ln1H4gFZjsdFQ=="],
2812
+ "@tscircuit/pcb-viewer/@tscircuit/core": ["@tscircuit/core@0.0.403", "", { "dependencies": { "@lume/kiwi": "^0.4.3", "css-select": "^5.1.0", "format-si-unit": "^0.0.3", "nanoid": "^5.0.7", "performance-now": "^2.1.0", "react-reconciler": "^0.31.0", "react-reconciler-18": "npm:react-reconciler@0.29.2", "transformation-matrix": "^2.16.1", "zod": "^3.23.8" }, "peerDependencies": { "@tscircuit/capacity-autorouter": "*", "@tscircuit/checks": "*", "@tscircuit/circuit-json-util": "*", "@tscircuit/footprinter": "*", "@tscircuit/infgrid-ijump-astar": "*", "@tscircuit/math-utils": "*", "@tscircuit/props": "*", "@tscircuit/schematic-autolayout": "*", "circuit-json": "*", "circuit-json-to-connectivity-map": "*", "schematic-symbols": "*", "typescript": "^5.0.0" } }, "sha512-D1XIyyfWpSfc7Tq4+dOCABLgeoWs11tPNynL2uC5jhc6YFdtAAHzKo7/xnnzzpyiLb33b5Rh7722KRFTZ0nz0g=="],
2813
2813
 
2814
2814
  "@tscircuit/pcb-viewer/@tscircuit/math-utils": ["@tscircuit/math-utils@0.0.18", "", { "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-P45v7V/BiVZZjXTUzjWSUsy0M8GpI5o6d+JWhPWE5+JwI/sYZARuLT4e1xzV7LaavEX4GQ0NKG9hKN48xTZJsw=="],
2815
2815
 
2816
+ "@tscircuit/pcb-viewer/circuit-json-to-connectivity-map": ["circuit-json-to-connectivity-map@0.0.22", "", { "dependencies": { "@tscircuit/math-utils": "^0.0.9" }, "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-HN8DiISjZZLTglGEkYNRpKeQ/DMG4dDo5j4Hck0UGSJbpux9aFwtJOGszMf06Inh/gu5oKBrpZJIeWxaNacKUg=="],
2817
+
2816
2818
  "@tscircuit/pcb-viewer/circuit-to-svg": ["circuit-to-svg@0.0.36", "", { "dependencies": { "@tscircuit/footprinter": "^0.0.57", "@tscircuit/routing": "^1.3.5", "@tscircuit/soup": "*", "@tscircuit/soup-util": "^0.0.28", "@types/node": "^22.5.5", "schematic-symbols": "^0.0.17", "svgson": "^5.3.1", "transformation-matrix": "^2.16.1" } }, "sha512-TGsi4htATqGIJULmUn1NZlN/6ORmZYxiXzBex4fSjzDjPmeMnbSPVefR1SZfxBCE/ucIwCdffRw8v9/ydIu6Wg=="],
2817
2819
 
2818
2820
  "@tscircuit/prompt-benchmarks/@tscircuit/footprinter": ["@tscircuit/footprinter@0.0.102", "", { "dependencies": { "@tscircuit/mm": "^0.0.8", "zod": "^3.23.8" }, "peerDependencies": { "circuit-json": "*" } }, "sha512-cuc5iUU42uIa6FpQzMILSaa41TZnEGxvXDn3SoE/tnDFvUrJ+DPsCuiGu7PMnWjy+ip7XjCbghrVkFB4GK3kCg=="],
2819
2821
 
2820
2822
  "@tscircuit/runframe/@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.7", "@radix-ui/react-focus-guards": "1.1.2", "@radix-ui/react-focus-scope": "1.1.4", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.6", "@radix-ui/react-presence": "1.1.4", "@radix-ui/react-primitive": "2.1.0", "@radix-ui/react-slot": "1.2.0", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-yI7S1ipkP5/+99qhSI6nthfo/tR6bL6Zgxi/+1UO6qPa6UeM6nlafWcQ65vB4rU2XjgjMfMhI3k9Y5MztA62VQ=="],
2821
2823
 
2822
- "@tscircuit/runframe/@tscircuit/3d-viewer": ["@tscircuit/3d-viewer@0.0.214", "", { "dependencies": { "@jscad/regl-renderer": "^2.6.12", "@jscad/stl-serializer": "^2.1.20", "@react-three/drei": "^9.121.4", "@react-three/fiber": "^8.17.14", "@tscircuit/core": "^0.0.398", "@tscircuit/props": "^0.0.177", "@tscircuit/soup-util": "^0.0.41", "jscad-electronics": "^0.0.27", "jscad-fiber": "^0.0.79", "jscad-planner": "^0.0.13", "react": "^18.3.1", "react-dom": "^18.3.1", "react-use-gesture": "^9.1.3" }, "peerDependencies": { "three": "*" } }, "sha512-jmEyM7UeNv1BRknFWlXaaGAphP6L9bMkmC2z2ZdCiCw6duA4x/aggfLUqdFe5G9i/zaQuoPw398zawHOwHYjBQ=="],
2824
+ "@tscircuit/runframe/@tscircuit/3d-viewer": ["@tscircuit/3d-viewer@0.0.220", "", { "dependencies": { "@jscad/regl-renderer": "^2.6.12", "@jscad/stl-serializer": "^2.1.20", "@react-three/drei": "^9.121.4", "@react-three/fiber": "^8.17.14", "@tscircuit/core": "^0.0.398", "@tscircuit/props": "^0.0.181", "@tscircuit/soup-util": "^0.0.41", "jscad-electronics": "^0.0.27", "jscad-fiber": "^0.0.79", "jscad-planner": "^0.0.13", "react": "^18.3.1", "react-dom": "^18.3.1", "react-use-gesture": "^9.1.3" }, "peerDependencies": { "three": "*" } }, "sha512-lafuJN+uMkfGrDXm6ihnUhYYln2gsDfDoJybStg2uUCDSJ+nnFy5231b1NlD4llo2zvMsZTcxV96/CgOU11vwg=="],
2823
2825
 
2824
- "@tscircuit/runframe/@tscircuit/core": ["@tscircuit/core@0.0.401", "", { "dependencies": { "@lume/kiwi": "^0.4.3", "css-select": "^5.1.0", "format-si-unit": "^0.0.3", "nanoid": "^5.0.7", "performance-now": "^2.1.0", "react-reconciler": "^0.31.0", "react-reconciler-18": "npm:react-reconciler@0.29.2", "transformation-matrix": "^2.16.1", "zod": "^3.23.8" }, "peerDependencies": { "@tscircuit/capacity-autorouter": "*", "@tscircuit/checks": "*", "@tscircuit/circuit-json-util": "*", "@tscircuit/footprinter": "*", "@tscircuit/infgrid-ijump-astar": "*", "@tscircuit/math-utils": "*", "@tscircuit/props": "*", "@tscircuit/schematic-autolayout": "*", "circuit-json": "*", "circuit-json-to-connectivity-map": "*", "schematic-symbols": "*", "typescript": "^5.0.0" } }, "sha512-Z4Epv3GHMwjvsfQ3jPua+E1H1NvoJkyGLBMEC2vku9kTF4yBixyKGiVqZAK1I6lQUQE4w8qjygnqyRtRtFwTkg=="],
2826
+ "@tscircuit/runframe/@tscircuit/core": ["@tscircuit/core@0.0.408", "", { "dependencies": { "@lume/kiwi": "^0.4.3", "css-select": "^5.1.0", "format-si-unit": "^0.0.3", "nanoid": "^5.0.7", "performance-now": "^2.1.0", "react-reconciler": "^0.31.0", "react-reconciler-18": "npm:react-reconciler@0.29.2", "transformation-matrix": "^2.16.1", "zod": "^3.23.8" }, "peerDependencies": { "@tscircuit/capacity-autorouter": "*", "@tscircuit/checks": "*", "@tscircuit/circuit-json-util": "*", "@tscircuit/footprinter": "*", "@tscircuit/infgrid-ijump-astar": "*", "@tscircuit/math-utils": "*", "@tscircuit/props": "*", "@tscircuit/schematic-autolayout": "*", "circuit-json": "*", "circuit-json-to-connectivity-map": "*", "schematic-symbols": "*", "typescript": "^5.0.0" } }, "sha512-iQedOxZFUqspEsFOu8aZdT4KjQr1nu/MJlhHLQ35JCiugQ9WWFy0GL3CuVQEEInYGcFG55TktloRhQLkp+JGdQ=="],
2825
2827
 
2826
- "@tscircuit/runframe/@tscircuit/eval": ["@tscircuit/eval@0.0.194", "", { "peerDependencies": { "@tscircuit/core": "*", "circuit-json": "*", "jscad-fiber": "*", "typescript": "^5.0.0" } }, "sha512-Ew9cK/veXdcbDOSuCJ0akRaoDQgi5wG2csXUX3KSelhwL9IeWDsh1OdFHiM8B7qbOTL9wD6OCsaVtQRZfbtWlQ=="],
2828
+ "@tscircuit/runframe/@tscircuit/eval": ["@tscircuit/eval@0.0.203", "", { "peerDependencies": { "@tscircuit/core": "*", "circuit-json": "*", "jscad-fiber": "*", "typescript": "^5.0.0" } }, "sha512-plvJNEI6puqgl4y+gXxXyhDRP9Pt8pHQsLtTOzsJdDOVg5Q+orQumKerB38NWWHk+ow9tYsgC4GT4BMcuA7e9Q=="],
2827
2829
 
2828
- "@tscircuit/runframe/@tscircuit/props": ["@tscircuit/props@0.0.177", "", { "peerDependencies": { "@tscircuit/layout": "*", "circuit-json": "*", "react": "*", "zod": "*" } }, "sha512-ii2YvVzvFxj5RH7QfMsv51InPTIKS6DulA1RW+vnj8mQnLa37zZTJ1MZ65n40UkDzDgE0ZQsskEApuTjT95Xfg=="],
2830
+ "@tscircuit/runframe/@tscircuit/props": ["@tscircuit/props@0.0.179", "", { "peerDependencies": { "@tscircuit/layout": "*", "circuit-json": "*", "react": "*", "zod": "*" } }, "sha512-PNvhEmJ3LfC+m2w1C0I5a2b91720qn3/3hONa7SRHnuWz2xf6wPlrgfWSqcYE1AxMzosVCOySZUtXJ/1r4tyNw=="],
2829
2831
 
2830
2832
  "@tscircuit/runframe/circuit-to-svg": ["circuit-to-svg@0.0.123", "", { "dependencies": { "@tscircuit/checks": "^0.0.44", "@tscircuit/circuit-json-util": "^0.0.47", "@tscircuit/footprinter": "^0.0.91", "@tscircuit/routing": "^1.3.5", "@tscircuit/soup-util": "^0.0.41", "@types/node": "^22.5.5", "bun-types": "^1.1.40", "svgson": "^5.3.1", "transformation-matrix": "^2.16.1" }, "peerDependencies": { "circuit-json": "*", "schematic-symbols": "*" } }, "sha512-T5WknY3CZ/o8Xdf+ZedqJ/q6TiPlu5n67OF5Ie8VbejdbZH+B4vwFnkMdyN378aV3xnw6I4F/whaOXvcot8KbQ=="],
2831
2833
 
@@ -3175,13 +3177,7 @@
3175
3177
 
3176
3178
  "@tscircuit/file-server/winterspec/kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="],
3177
3179
 
3178
- "@tscircuit/pcb-viewer/@tscircuit/core/@tscircuit/math-utils": ["@tscircuit/math-utils@0.0.14", "", { "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-sCkCnxW2yPb88OrMs52hM//sjQDy9stqchHo0WeMi6eZjo5zl4CXcDFYWmsG0UIrzkAVuoddhvrYPwDuyqayOA=="],
3179
-
3180
- "@tscircuit/pcb-viewer/@tscircuit/core/@tscircuit/props": ["@tscircuit/props@0.0.172", "", { "peerDependencies": { "@tscircuit/layout": "*", "circuit-json": "*", "react": "*", "zod": "*" } }, "sha512-RKC8g5kBy8+XnT7gjvhXPYR9hogEQJ9Nh0MMRAC3rMyqO3kBCuB2UZduEUwvREyoo42mwN2qlyydDlnIu41Ztg=="],
3181
-
3182
- "@tscircuit/pcb-viewer/@tscircuit/core/circuit-json": ["circuit-json@0.0.160", "", { "dependencies": { "nanoid": "^5.0.7", "zod": "^3.23.6" } }, "sha512-mCKydMDzzdio8KtsgJH6nEAmdL0T+fyPBN1DmpNBGAvPH/GZiWER5HpthXGq/JqO9mrb+1Q9OWHs2FKz0sTZMw=="],
3183
-
3184
- "@tscircuit/pcb-viewer/@tscircuit/core/schematic-symbols": ["schematic-symbols@0.0.121", "", { "peerDependencies": { "typescript": "^5.5.4" } }, "sha512-xqWY43VC10wIVL+Kf8PlHj27Ojr7JdFeFHTRoSvmc6zvHirPQiXlnb3l70BerZQy6S/EOH+Q9yGRADYU0m8T1w=="],
3180
+ "@tscircuit/pcb-viewer/circuit-json-to-connectivity-map/@tscircuit/math-utils": ["@tscircuit/math-utils@0.0.9", "", { "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-sPzfXndijet8z29X6f5vnSZddiso2tRg7m6rB+268bVj60mxnxUMD14rKuMlLn6n84fMOpD/X7pRTZUfi6M+Tg=="],
3185
3181
 
3186
3182
  "@tscircuit/pcb-viewer/circuit-to-svg/@tscircuit/footprinter": ["@tscircuit/footprinter@0.0.57", "", { "dependencies": { "@tscircuit/mm": "^0.0.7", "zod": "^3.23.8" }, "peerDependencies": { "@tscircuit/soup": "*" } }, "sha512-aLUuh3LqeDusjTzp6nyOqss6Et4adTVeCGJpvvq3dosuyfdk5L79l64jdNFK0Bf5fps1SJAHISpPC4nDSJEVfw=="],
3187
3183
 
@@ -3205,6 +3201,8 @@
3205
3201
 
3206
3202
  "@tscircuit/runframe/@tscircuit/3d-viewer/@tscircuit/core": ["@tscircuit/core@0.0.398", "", { "dependencies": { "@lume/kiwi": "^0.4.3", "@tscircuit/capacity-autorouter": "^0.0.52", "@tscircuit/checks": "^0.0.46", "@tscircuit/circuit-json-util": "^0.0.47", "@tscircuit/infgrid-ijump-astar": "^0.0.33", "@tscircuit/math-utils": "^0.0.14", "@tscircuit/props": "^0.0.178", "@tscircuit/schematic-autolayout": "^0.0.6", "circuit-json": "0.0.170", "circuit-json-to-connectivity-map": "^0.0.22", "css-select": "^5.1.0", "format-si-unit": "^0.0.3", "nanoid": "^5.0.7", "performance-now": "^2.1.0", "react-reconciler": "^0.31.0", "react-reconciler-18": "npm:react-reconciler@0.29.2", "schematic-symbols": "^0.0.132", "transformation-matrix": "^2.16.1", "zod": "^3.23.8" }, "peerDependencies": { "@tscircuit/footprinter": "*", "typescript": "^5.0.0" } }, "sha512-pJkPwTtroKR/AX3MzDDnLAq1IK6+8xg2k8d8Ahz2yg/akH+n4j6VdGZsd3PbOZJtcU2jABXp2feWIOAA6RSAcQ=="],
3207
3203
 
3204
+ "@tscircuit/runframe/@tscircuit/3d-viewer/@tscircuit/props": ["@tscircuit/props@0.0.181", "", { "peerDependencies": { "@tscircuit/layout": "*", "circuit-json": "*", "react": "*", "zod": "*" } }, "sha512-Oqt6Tyzo4diMepQog7WV5lOCtR1mcB10vnXeDWrzEIDKfLOt0kqNSeB9Le+Ew2JtD5l83ujZZZDOqHue02ZryA=="],
3205
+
3208
3206
  "@tscircuit/runframe/@tscircuit/3d-viewer/jscad-electronics": ["jscad-electronics@0.0.27", "", { "dependencies": { "@tscircuit/footprinter": "^0.0.132", "circuit-json": "^0.0.92" } }, "sha512-oczsbRWTRxkHfXcmyCVHuBa2ZWVGFJbrjWKR4Xhz4+4DxRk1+qG2hceAFZjYe1jTa57Yg3uct1naG+96tHo/zw=="],
3209
3207
 
3210
3208
  "@tscircuit/runframe/@tscircuit/3d-viewer/jscad-fiber": ["jscad-fiber@0.0.79", "", { "dependencies": { "color": "^4.2.3", "lucide-react": "^0.456.0", "react-code-blocks": "^0.1.6", "react-reconciler": "^0.29.2" }, "peerDependencies": { "@jscad/modeling": "*", "@react-three/fiber": "*", "react": "*", "three": "*" } }, "sha512-pSj1vwBxKxW0c7xnE82nElPecKUfUMR/Gl2SHRPIqaibPvn4wxu+Pp0sB6KDLnB1nmnKa4F2queRdGDN9AeZxw=="],