@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,62 +0,0 @@
1
- import { Circuit } from "@tscircuit/core"
2
- import { useEffect, useMemo, useState } from "react"
3
- import * as React from "react"
4
- import { useCompiledTsx } from "../use-compiled-tsx"
5
- import { createJSCADRenderer } from "jscad-fiber"
6
- import { jscadPlanner } from "jscad-planner"
7
-
8
- export const constructCircuit = ({
9
- UserElm,
10
- type,
11
- circuitDisplayName,
12
- }: {
13
- UserElm: any
14
- type: "board" | "footprint" | "package" | "model"
15
- circuitDisplayName?: string
16
- }) => {
17
- const circuit = new Circuit()
18
-
19
- if (circuitDisplayName) {
20
- circuit.name = circuitDisplayName
21
- }
22
-
23
- if (type === "board") {
24
- circuit.add(<UserElm />)
25
- // HACK: switch to selectOne when root fixes bug with selecting board
26
- const board = circuit.root?.children[0]
27
- // const board = circuit.selectOne("board")
28
- if (board) {
29
- board.setProps({
30
- ...board.props,
31
- })
32
- }
33
- } else if (type === "package") {
34
- circuit.add(
35
- <board width="50mm" height="50mm">
36
- <UserElm name="U1" />
37
- </board>,
38
- )
39
- } else if (type === "footprint") {
40
- circuit.add(
41
- <board width="10mm" height="10mm">
42
- <chip name="U1" footprint={<UserElm />} />
43
- </board>,
44
- )
45
- } else if (type === "model") {
46
- const jscadGeoms: any[] = []
47
- const { createJSCADRoot } = createJSCADRenderer(jscadPlanner as any)
48
- const jscadRoot = createJSCADRoot(jscadGeoms)
49
- jscadRoot.render(<UserElm />)
50
- circuit.add(
51
- <board width="10mm" height="10mm">
52
- <chip
53
- name="U1"
54
- cadModel={{
55
- jscad: jscadGeoms[0],
56
- }}
57
- />
58
- </board>,
59
- )
60
- }
61
- return circuit
62
- }
@@ -1,256 +0,0 @@
1
- import * as tscircuitCore from "@tscircuit/core"
2
- import { getImportsFromCode } from "@tscircuit/prompt-benchmarks/code-runner-utils"
3
- import type { AnyCircuitElement } from "circuit-json"
4
- import * as jscadFiber from "jscad-fiber"
5
- import * as React from "react"
6
- import * as tscircuitMathUtils from "@tscircuit/math-utils"
7
- import { useEffect, useMemo, useReducer, useRef, useState } from "react"
8
- import { safeCompileTsx } from "../use-compiled-tsx"
9
- import { useSnippetsBaseApiUrl } from "../use-snippets-base-api-url"
10
- import { constructCircuit } from "./construct-circuit"
11
- import { evalCompiledJs } from "./eval-compiled-js"
12
- import { getSyntaxError } from "@/lib/utils/getSyntaxError"
13
-
14
- type RunTsxResult = {
15
- compiledModule: any
16
- message: string
17
- circuitJson: AnyCircuitElement[] | null
18
- compiledJs?: string
19
- isRunningCode: boolean
20
- }
21
-
22
- /**
23
- * @deprecated will be removed in future version, use @tscircuit/eval or
24
- * @tscircuit/runframe
25
- */
26
- export const useRunTsx = ({
27
- code,
28
- userImports,
29
- type,
30
- isStreaming = false,
31
- circuitDisplayName,
32
- }: {
33
- code?: string
34
- userImports?: Record<string, object>
35
- type?: "board" | "footprint" | "package" | "model"
36
- isStreaming?: boolean
37
- circuitDisplayName?: string
38
- } = {}): RunTsxResult & {
39
- circuitJsonKey: string
40
- triggerRunTsx: () => void
41
- tsxRunTriggerCount: number
42
- } => {
43
- type ??= "board"
44
- const [tsxRunTriggerCount, incTsxRunTriggerCount] = useReducer(
45
- (c) => c + 1,
46
- 0,
47
- )
48
- const [tsxResult, setTsxResult] = useState<RunTsxResult>({
49
- compiledModule: null,
50
- message: "",
51
- circuitJson: null,
52
- isRunningCode: false,
53
- })
54
- const apiBaseUrl = useSnippetsBaseApiUrl()
55
- const preSuppliedImportsRef = useRef<Record<string, any>>({})
56
-
57
- useEffect(() => {
58
- if (tsxRunTriggerCount === 0) return
59
- if (isStreaming) {
60
- setTsxResult({
61
- compiledModule: null,
62
- message: "",
63
- circuitJson: null,
64
- isRunningCode: false,
65
- })
66
- }
67
- if (!code) return
68
- const syntaxError = getSyntaxError(code)
69
- if (syntaxError) {
70
- setTsxResult({
71
- compiledModule: null,
72
- message: syntaxError,
73
- circuitJson: null,
74
- isRunningCode: false,
75
- })
76
- return
77
- }
78
- async function run() {
79
- setTsxResult({
80
- compiledModule: null,
81
- message: "",
82
- circuitJson: null,
83
- isRunningCode: true,
84
- })
85
-
86
- const userCodeTsciImports = getImportsFromCode(code!).filter((imp) =>
87
- imp.startsWith("@tsci/"),
88
- )
89
-
90
- const preSuppliedImports: Record<string, any> =
91
- preSuppliedImportsRef.current
92
-
93
- for (const [importName, importValue] of Object.entries(
94
- userImports ?? {},
95
- )) {
96
- preSuppliedImports[importName] = importValue
97
- }
98
-
99
- const __tscircuit_require = (name: string) => {
100
- if (
101
- name === "./manual-edits.json" &&
102
- preSuppliedImports["./manual-edits.json"] === ""
103
- ) {
104
- return preSuppliedImports["./manual-edits.json"]
105
- }
106
- if (!preSuppliedImports[name]) {
107
- throw new Error(
108
- `Import "${name}" not found (imports available: ${Object.keys(preSuppliedImports).join(",")})`,
109
- )
110
- }
111
- return preSuppliedImports[name]
112
- }
113
- ;(globalThis as any).__tscircuit_require = __tscircuit_require
114
- preSuppliedImports["@tscircuit/core"] = tscircuitCore
115
- preSuppliedImports["tscircuit"] = tscircuitCore
116
- preSuppliedImports["@tscircuit/math-utils"] = tscircuitMathUtils
117
- preSuppliedImports["react"] = React
118
- preSuppliedImports["jscad-fiber"] = jscadFiber
119
- globalThis.React = React
120
-
121
- async function addImport(importName: string, depth = 0) {
122
- if (!importName.startsWith("@tsci/")) return
123
- if (preSuppliedImports[importName]) return
124
- if (depth > 5) {
125
- console.log("Max depth for imports reached")
126
- return
127
- }
128
-
129
- const fullSnippetName = importName
130
- .replace("@tsci/", "")
131
- .replace(".", "/")
132
- const { snippet: importedSnippet, error } = await fetch(
133
- `${apiBaseUrl}/snippets/get?name=${fullSnippetName}`,
134
- )
135
- .then((res) => res.json())
136
- .catch((e) => ({ error: e }))
137
-
138
- if (error) {
139
- console.error("Error fetching import", importName, error)
140
- return
141
- }
142
-
143
- const { compiled_js, code } = importedSnippet
144
-
145
- const importNames = getImportsFromCode(code!)
146
-
147
- for (const importName of importNames) {
148
- if (!preSuppliedImports[importName]) {
149
- await addImport(importName, depth + 1)
150
- }
151
- }
152
-
153
- try {
154
- preSuppliedImports[importName] = evalCompiledJs(compiled_js).exports
155
- } catch (e) {
156
- console.error("Error importing snippet", e)
157
- }
158
- }
159
-
160
- for (const userCodeTsciImport of userCodeTsciImports) {
161
- await addImport(userCodeTsciImport)
162
- }
163
-
164
- const { success, compiledTsx: compiledJs, error } = safeCompileTsx(code!)
165
-
166
- if (!success) {
167
- setTsxResult({
168
- compiledModule: null,
169
- message: `Compile Error: ${error.message}`,
170
- circuitJson: null,
171
- isRunningCode: false,
172
- })
173
- }
174
-
175
- try {
176
- const module = evalCompiledJs(compiledJs!)
177
-
178
- const componentExportKeys = Object.keys(module.exports).filter(
179
- (key) => !key.startsWith("use"),
180
- )
181
-
182
- if (componentExportKeys.length > 1) {
183
- throw new Error(
184
- `Too many exports, only export one component. You exported: ${JSON.stringify(Object.keys(module.exports))}`,
185
- )
186
- }
187
-
188
- const primaryKey = componentExportKeys[0]
189
-
190
- const UserElm = (props: any) =>
191
- React.createElement(module.exports[primaryKey], props)
192
-
193
- try {
194
- const circuit = constructCircuit({
195
- UserElm,
196
- type: type as any,
197
- circuitDisplayName,
198
- })
199
- const renderPromise = circuit.renderUntilSettled()
200
-
201
- // wait one tick to allow a single render pass
202
- await new Promise((resolve) => setTimeout(resolve, 1))
203
-
204
- let circuitJson = circuit.getCircuitJson()
205
- setTsxResult({
206
- compiledModule: module,
207
- compiledJs,
208
- message: "",
209
- circuitJson: circuitJson as AnyCircuitElement[],
210
- isRunningCode: true,
211
- })
212
-
213
- await renderPromise
214
-
215
- circuitJson = circuit.getCircuitJson()
216
- setTsxResult({
217
- compiledModule: module,
218
- compiledJs,
219
- message: "",
220
- circuitJson: circuitJson as AnyCircuitElement[],
221
- isRunningCode: false,
222
- })
223
- } catch (error: any) {
224
- console.error("Evaluation error:", error)
225
- setTsxResult({
226
- compiledModule: module,
227
- message: `Render Error: ${error.message}`,
228
- circuitJson: null,
229
- isRunningCode: false,
230
- })
231
- }
232
- } catch (error: any) {
233
- console.error("Evaluation error:", error)
234
- setTsxResult({
235
- compiledModule: null,
236
- message: `Eval Error: ${error.message}\n\n${error.stack}`,
237
- circuitJson: null,
238
- isRunningCode: false,
239
- })
240
- }
241
- }
242
- run()
243
- }, [tsxRunTriggerCount])
244
-
245
- const circuitJsonKey: string = useMemo(() => {
246
- if (!tsxResult.circuitJson) return ""
247
- return `cj-${Math.random().toString(36).substring(2, 15)}`
248
- }, [tsxResult.circuitJson, tsxResult.circuitJson?.length])
249
-
250
- return {
251
- ...tsxResult,
252
- circuitJsonKey: circuitJsonKey,
253
- triggerRunTsx: incTsxRunTriggerCount,
254
- tsxRunTriggerCount,
255
- }
256
- }
@@ -1,66 +0,0 @@
1
- import { Snippet } from "fake-snippets-api/lib/db/schema"
2
- import { useMutation } from "react-query"
3
- import { useAxios } from "./use-axios"
4
- import { safeCompileTsx } from "./use-compiled-tsx"
5
- import { useCurrentSnippetId } from "./use-current-snippet-id"
6
-
7
- export const useSaveSnippet = () => {
8
- const axios = useAxios()
9
-
10
- const { snippetId } = useCurrentSnippetId()
11
-
12
- const saveSnippetMutation = useMutation<
13
- Snippet,
14
- Error,
15
- { code: string; snippet_type: string; dts?: string; circuit_json?: any[] }
16
- >({
17
- mutationFn: async ({ code, snippet_type, dts, circuit_json }) => {
18
- const compileResult = safeCompileTsx(code)
19
-
20
- if (snippetId) {
21
- const response = await axios.post("/snippets/update", {
22
- snippet_id: snippetId,
23
- code,
24
- snippet_type,
25
- compiled_js: compileResult.success
26
- ? compileResult.compiledTsx
27
- : undefined,
28
- circuit_json: circuit_json,
29
- dts,
30
- })
31
- return response.data.snippet
32
- } else {
33
- const response = await axios.post("/snippets/create", {
34
- code,
35
- snippet_type,
36
- owner_name: "seveibar", // Replace with actual user name or fetch from user context
37
- compiled_js: compileResult.success
38
- ? compileResult.compiledTsx
39
- : undefined,
40
- dts,
41
- })
42
- return response.data.snippet
43
- }
44
- },
45
- })
46
-
47
- const saveSnippet = async (
48
- code: string,
49
- snippet_type: string,
50
- dts?: string,
51
- circuit_json?: any[],
52
- ) => {
53
- return saveSnippetMutation.mutateAsync({
54
- code,
55
- snippet_type,
56
- dts,
57
- circuit_json,
58
- })
59
- }
60
-
61
- return {
62
- saveSnippet,
63
- isLoading: saveSnippetMutation.isLoading,
64
- error: saveSnippetMutation.error,
65
- }
66
- }
@@ -1,54 +0,0 @@
1
- // import * as ts from "typescript"
2
-
3
- // export function checkTypeScriptErrors(code: string): ts.Diagnostic[] {
4
- // // Create a virtual TypeScript compiler
5
- // const compilerOptions: ts.CompilerOptions = {
6
- // noEmit: true,
7
- // allowJs: true,
8
- // checkJs: true,
9
- // strict: true,
10
- // }
11
-
12
- // // Create a virtual file system
13
- // const fileSystem = {
14
- // "example.ts": code,
15
- // }
16
-
17
- // // Create a compiler host
18
- // const compilerHost = ts.createCompilerHost(compilerOptions)
19
- // compilerHost.getSourceFile = (fileName: string) => {
20
- // return ts.createSourceFile(
21
- // fileName,
22
- // fileSystem[fileName] || "",
23
- // ts.ScriptTarget.Latest,
24
- // )
25
- // }
26
- // compilerHost.writeFile = () => {}
27
- // compilerHost.getCurrentDirectory = () => "/"
28
- // compilerHost.getDefaultLibFileName = () => "lib.d.ts"
29
-
30
- // // Create a program
31
- // const program = ts.createProgram(
32
- // ["example.ts"],
33
- // compilerOptions,
34
- // compilerHost,
35
- // )
36
-
37
- // // Get the diagnostics (errors)
38
- // const diagnostics = ts.getPreEmitDiagnostics(program)
39
-
40
- // return diagnostics
41
- // }
42
-
43
- // // Example usage
44
- // const code = `
45
- // let x: number = "string"; // Type error
46
- // let y: string = 5; // Another type error
47
- // let z: number = 10; // No error
48
- // `
49
-
50
- // const errors = checkTypeScriptErrors(code)
51
- // console.log("Errors found:", errors.length)
52
- // errors.forEach((error) => {
53
- // console.log(`Error on line ${error.start}: ${error.messageText}`)
54
- // })
@@ -1,13 +0,0 @@
1
- import * as Babel from "@babel/standalone"
2
-
3
- export function getSyntaxError(code: string): string | null {
4
- try {
5
- Babel.transform(code, {
6
- filename: "index.tsx",
7
- presets: ["react", "typescript"],
8
- })
9
- return null
10
- } catch (error: unknown) {
11
- return (error as Error).message
12
- }
13
- }
package/src/pages/ai.tsx DELETED
@@ -1,92 +0,0 @@
1
- import AIChatInterface from "@/components/AiChatInterface"
2
- import Header from "@/components/Header"
3
- import { PreviewContent } from "@/components/PreviewContent"
4
- import { useRunTsx } from "@/hooks/use-run-tsx"
5
- import { useSaveSnippet } from "@/hooks/use-save-snippet"
6
- import { useSnippet } from "@/hooks/use-snippet"
7
- import { useToast } from "@/hooks/use-toast"
8
- import { useEffect, useState } from "react"
9
- import { useLocation } from "wouter"
10
-
11
- export const AiPage = () => {
12
- const [code, setCode] = useState("")
13
- const [manualEditsFileContent, setManualEditsFileContent] = useState("")
14
- const [dts, setDts] = useState("")
15
- const [isStreaming, setIsStreaming] = useState(false)
16
- const { saveSnippet, isLoading: isSaving } = useSaveSnippet()
17
- const snippetIdFromUrl = new URLSearchParams(window.location.search).get(
18
- "snippet_id",
19
- )
20
- const [snippetId, setSnippetId] = useState<string | null>(snippetIdFromUrl)
21
- const { data: snippet } = useSnippet(snippetId)
22
- const { toast } = useToast()
23
- const [, navigate] = useLocation()
24
- const {
25
- message: errorMessage,
26
- circuitJson,
27
- triggerRunTsx,
28
- isRunningCode,
29
- tsxRunTriggerCount,
30
- circuitJsonKey,
31
- } = useRunTsx({
32
- code,
33
- type: "board",
34
- isStreaming,
35
- circuitDisplayName: snippet?.name,
36
- })
37
-
38
- useEffect(() => {
39
- if (!code && snippet && snippetIdFromUrl) {
40
- setCode(snippet.code)
41
- }
42
- }, [code, snippet])
43
-
44
- const hasUnsavedChanges = snippet?.code !== code
45
-
46
- return (
47
- <div>
48
- <Header />
49
- <div className="flex bg-gray-100">
50
- <div className="w-1/2">
51
- <AIChatInterface
52
- code={code}
53
- hasUnsavedChanges={hasUnsavedChanges}
54
- snippetId={snippet?.snippet_id}
55
- onCodeChange={setCode}
56
- errorMessage={errorMessage}
57
- onStartStreaming={() => {
58
- setIsStreaming(true)
59
- }}
60
- onStopStreaming={() => {
61
- setIsStreaming(false)
62
- }}
63
- />
64
- </div>
65
- <div className="w-1/2">
66
- <div className="p-4 h-full">
67
- <PreviewContent
68
- className="bg-white h-full p-4 rounded-lg shadow"
69
- code={code}
70
- isStreaming={isStreaming}
71
- isRunningCode={isRunningCode}
72
- onCodeChange={setCode}
73
- onDtsChange={setDts}
74
- showCodeTab
75
- triggerRunTsx={triggerRunTsx}
76
- errorMessage={errorMessage}
77
- circuitJson={circuitJson}
78
- circuitJsonKey={circuitJsonKey}
79
- manualEditsFileContent={manualEditsFileContent}
80
- onManualEditsFileContentChange={(
81
- newManualEditsFileContent: string,
82
- ) => {
83
- setManualEditsFileContent(newManualEditsFileContent)
84
- }}
85
- tsxRunTriggerCount={tsxRunTriggerCount}
86
- />
87
- </div>
88
- </div>
89
- </div>
90
- </div>
91
- )
92
- }