@tscircuit/fake-snippets 0.0.7 → 0.0.9
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.
- package/bun-tests/fake-snippets-api/fixtures/get-test-server.ts +2 -5
- package/bun-tests/fake-snippets-api/routes/packages/{list.test.ts → list-1.test.ts} +0 -55
- package/bun-tests/fake-snippets-api/routes/packages/list-2.test.ts +59 -0
- package/bun-tests/fake-snippets-api/routes/snippets/add_star.test.ts +32 -27
- package/bun-tests/fake-snippets-api/routes/snippets/create.test.ts +34 -1
- package/bun-tests/fake-snippets-api/routes/snippets/get.test.ts +114 -0
- package/bun-tests/fake-snippets-api/routes/snippets/get_image.test.ts +10 -6
- package/bun-tests/fake-snippets-api/routes/snippets/images.test.ts +8 -6
- package/bun-tests/fake-snippets-api/routes/snippets/list_newest.test.ts +2 -2
- package/bun-tests/fake-snippets-api/routes/snippets/list_trending.test.ts +10 -10
- package/bun-tests/fake-snippets-api/routes/snippets/remove_star.test.ts +8 -6
- package/bun-tests/fake-snippets-api/routes/snippets/search.test.ts +1 -1
- package/bun-tests/fake-snippets-api/routes/snippets/star-count.test.ts +19 -12
- package/bun-tests/fake-snippets-api/routes/snippets/update.test.ts +57 -16
- package/bun.lock +148 -569
- package/dist/bundle.js +844 -194
- package/fake-snippets-api/lib/db/db-client.ts +761 -147
- package/fake-snippets-api/lib/db/schema.ts +27 -6
- package/fake-snippets-api/lib/public-mapping/public-map-package.ts +8 -0
- package/fake-snippets-api/routes/api/packages/list.ts +4 -1
- package/fake-snippets-api/routes/api/snippets/add_star.ts +30 -8
- package/fake-snippets-api/routes/api/snippets/create.ts +123 -29
- package/fake-snippets-api/routes/api/snippets/delete.ts +5 -5
- package/fake-snippets-api/routes/api/snippets/download.ts +24 -10
- package/fake-snippets-api/routes/api/snippets/get.ts +46 -13
- package/fake-snippets-api/routes/api/snippets/list.ts +37 -2
- package/fake-snippets-api/routes/api/snippets/update.ts +36 -14
- package/package.json +4 -5
- package/src/components/CodeAndPreview.tsx +13 -48
- package/src/components/CodeEditor.tsx +10 -7
- package/src/components/EditorNav.tsx +0 -21
- package/src/components/PreviewContent.tsx +2 -2
- package/src/components/ViewSnippetHeader.tsx +4 -0
- package/src/hooks/use-global-store.ts +0 -5
- package/src/hooks/use-package-as-snippet.ts +78 -0
- package/src/hooks/use-run-tsx/index.tsx +4 -0
- package/src/lib/jlc-parts-engine.ts +4 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/fake-snippets",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -66,9 +66,7 @@
|
|
|
66
66
|
"@tscircuit/layout": "^0.0.29",
|
|
67
67
|
"@tscircuit/math-utils": "^0.0.10",
|
|
68
68
|
"@tscircuit/mm": "^0.0.8",
|
|
69
|
-
"@tscircuit/pcb-viewer": "^1.11.12",
|
|
70
69
|
"@tscircuit/props": "^0.0.143",
|
|
71
|
-
"@tscircuit/schematic-viewer": "^1.4.3",
|
|
72
70
|
"@types/file-saver": "^2.0.7",
|
|
73
71
|
"@types/ms": "^0.7.34",
|
|
74
72
|
"@typescript/ata": "^0.9.7",
|
|
@@ -130,9 +128,9 @@
|
|
|
130
128
|
"@babel/standalone": "^7.26.2",
|
|
131
129
|
"@biomejs/biome": "^1.9.2",
|
|
132
130
|
"@playwright/test": "^1.48.0",
|
|
133
|
-
"@tscircuit/core": "^0.0.
|
|
131
|
+
"@tscircuit/core": "^0.0.345",
|
|
134
132
|
"@tscircuit/prompt-benchmarks": "^0.0.28",
|
|
135
|
-
"@tscircuit/runframe": "^0.0.
|
|
133
|
+
"@tscircuit/runframe": "^0.0.231",
|
|
136
134
|
"@types/babel__standalone": "^7.1.7",
|
|
137
135
|
"@types/bun": "^1.1.10",
|
|
138
136
|
"@types/country-list": "^2.1.4",
|
|
@@ -146,6 +144,7 @@
|
|
|
146
144
|
"@vitejs/plugin-react": "^4.3.1",
|
|
147
145
|
"autoprefixer": "^10.4.20",
|
|
148
146
|
"circuit-to-svg": "^0.0.101",
|
|
147
|
+
"get-port": "^7.1.0",
|
|
149
148
|
"globals": "^15.9.0",
|
|
150
149
|
"postcss": "^8.4.47",
|
|
151
150
|
"prismjs": "^1.29.0",
|
|
@@ -2,7 +2,6 @@ import { CodeEditor } from "@/components/CodeEditor"
|
|
|
2
2
|
import { useAxios } from "@/hooks/use-axios"
|
|
3
3
|
import { useCreateSnippetMutation } from "@/hooks/use-create-snippet-mutation"
|
|
4
4
|
import { useGlobalStore } from "@/hooks/use-global-store"
|
|
5
|
-
import { useRunTsx } from "@/hooks/use-run-tsx"
|
|
6
5
|
import { useToast } from "@/hooks/use-toast"
|
|
7
6
|
import { useUrlParams } from "@/hooks/use-url-params"
|
|
8
7
|
import useWarnUserOnPageChange from "@/hooks/use-warn-user-on-page-change"
|
|
@@ -16,7 +15,6 @@ import { useEffect, useMemo, useState } from "react"
|
|
|
16
15
|
import { useMutation, useQueryClient } from "react-query"
|
|
17
16
|
import EditorNav from "./EditorNav"
|
|
18
17
|
import { parseJsonOrNull } from "@/lib/utils/parseJsonOrNull"
|
|
19
|
-
import { PreviewContent } from "./PreviewContent"
|
|
20
18
|
import { SuspenseRunFrame } from "./SuspenseRunFrame"
|
|
21
19
|
|
|
22
20
|
interface Props {
|
|
@@ -51,9 +49,7 @@ export function CodeAndPreview({ snippet }: Props) {
|
|
|
51
49
|
const [showPreview, setShowPreview] = useState(true)
|
|
52
50
|
const [lastRunCode, setLastRunCode] = useState(defaultCode ?? "")
|
|
53
51
|
const [fullScreen, setFullScreen] = useState(false)
|
|
54
|
-
const
|
|
55
|
-
(s) => s.should_use_webworker_for_run,
|
|
56
|
-
)
|
|
52
|
+
const [circuitJson, setCircuitJson] = useState<any>(null)
|
|
57
53
|
|
|
58
54
|
const snippetType: "board" | "package" | "model" | "footprint" =
|
|
59
55
|
snippet?.snippet_type ??
|
|
@@ -82,26 +78,6 @@ export function CodeAndPreview({ snippet }: Props) {
|
|
|
82
78
|
[manualEditsFileContent],
|
|
83
79
|
)
|
|
84
80
|
|
|
85
|
-
const {
|
|
86
|
-
message,
|
|
87
|
-
circuitJson,
|
|
88
|
-
compiledJs,
|
|
89
|
-
triggerRunTsx,
|
|
90
|
-
tsxRunTriggerCount,
|
|
91
|
-
circuitJsonKey,
|
|
92
|
-
isRunningCode,
|
|
93
|
-
} = useRunTsx({
|
|
94
|
-
code,
|
|
95
|
-
userImports,
|
|
96
|
-
type: snippetType,
|
|
97
|
-
circuitDisplayName: snippet?.name,
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
// Update lastRunCode whenever the code is run
|
|
101
|
-
useEffect(() => {
|
|
102
|
-
setLastRunCode(code)
|
|
103
|
-
}, [tsxRunTriggerCount])
|
|
104
|
-
|
|
105
81
|
const qc = useQueryClient()
|
|
106
82
|
|
|
107
83
|
const updateSnippetMutation = useMutation({
|
|
@@ -112,7 +88,7 @@ export function CodeAndPreview({ snippet }: Props) {
|
|
|
112
88
|
snippet_id: snippet.snippet_id,
|
|
113
89
|
code: code,
|
|
114
90
|
dts: dts,
|
|
115
|
-
compiled_js: compiledJs,
|
|
91
|
+
// compiled_js: compiledJs,
|
|
116
92
|
circuit_json: circuitJson,
|
|
117
93
|
manual_edits_json_content: manualEditsFileContent,
|
|
118
94
|
}
|
|
@@ -276,28 +252,7 @@ export function CodeAndPreview({ snippet }: Props) {
|
|
|
276
252
|
onDtsChange={(newDts) => setDts(newDts)}
|
|
277
253
|
/>
|
|
278
254
|
</div>
|
|
279
|
-
{showPreview &&
|
|
280
|
-
<PreviewContent
|
|
281
|
-
className={cn(
|
|
282
|
-
"flex p-2 flex-col min-h-[640px]",
|
|
283
|
-
fullScreen
|
|
284
|
-
? "fixed inset-0 z-50 bg-white p-4 overflow-hidden"
|
|
285
|
-
: "w-full md:w-1/2",
|
|
286
|
-
)}
|
|
287
|
-
code={code}
|
|
288
|
-
triggerRunTsx={triggerRunTsx}
|
|
289
|
-
tsxRunTriggerCount={tsxRunTriggerCount}
|
|
290
|
-
errorMessage={message}
|
|
291
|
-
circuitJsonKey={circuitJsonKey}
|
|
292
|
-
circuitJson={circuitJson}
|
|
293
|
-
isRunningCode={isRunningCode}
|
|
294
|
-
manualEditsFileContent={manualEditsFileContent ?? ""}
|
|
295
|
-
onManualEditsFileContentChange={setManualEditsFileContent}
|
|
296
|
-
onToggleFullScreen={() => setFullScreen(!fullScreen)}
|
|
297
|
-
isFullScreen={fullScreen}
|
|
298
|
-
/>
|
|
299
|
-
)}
|
|
300
|
-
{showPreview && shouldUseWebworkerForRun && (
|
|
255
|
+
{showPreview && (
|
|
301
256
|
<div
|
|
302
257
|
className={cn(
|
|
303
258
|
"flex p-0 flex-col min-h-[640px]",
|
|
@@ -308,8 +263,18 @@ export function CodeAndPreview({ snippet }: Props) {
|
|
|
308
263
|
>
|
|
309
264
|
<SuspenseRunFrame
|
|
310
265
|
showRunButton
|
|
266
|
+
forceLatestEvalVersion
|
|
267
|
+
onRenderStarted={() => {
|
|
268
|
+
setLastRunCode(code)
|
|
269
|
+
}}
|
|
270
|
+
onRenderFinished={({ circuitJson }) => {
|
|
271
|
+
setCircuitJson(circuitJson)
|
|
272
|
+
}}
|
|
311
273
|
onEditEvent={() => {
|
|
312
274
|
// TODO
|
|
275
|
+
window.alert(
|
|
276
|
+
"Edit events are temporarily disabled on tscircuit.com, use the CLI",
|
|
277
|
+
)
|
|
313
278
|
}}
|
|
314
279
|
fsMap={fsMap}
|
|
315
280
|
entrypoint="main.tsx"
|
|
@@ -27,7 +27,7 @@ import { EditorView } from "codemirror"
|
|
|
27
27
|
import { useEffect, useMemo, useRef, useState } from "react"
|
|
28
28
|
import ts from "typescript"
|
|
29
29
|
import CodeEditorHeader from "./CodeEditorHeader"
|
|
30
|
-
import { copilotPlugin, Language } from "@valtown/codemirror-codeium"
|
|
30
|
+
// import { copilotPlugin, Language } from "@valtown/codemirror-codeium"
|
|
31
31
|
import { useCodeCompletionApi } from "@/hooks/use-code-completion-ai-api"
|
|
32
32
|
const defaultImports = `
|
|
33
33
|
import React from "@types/react/jsx-runtime"
|
|
@@ -86,7 +86,6 @@ export const CodeEditor = ({
|
|
|
86
86
|
// Whenever streaming completes, reset the code to the initial code
|
|
87
87
|
useEffect(() => {
|
|
88
88
|
if (!isStreaming && code !== initialCode && initialCode) {
|
|
89
|
-
console.log("Resetting code to initial code", initialCode)
|
|
90
89
|
setCode(initialCode)
|
|
91
90
|
|
|
92
91
|
// HACK: Timeout because we need to wait for the editor to mount again
|
|
@@ -187,6 +186,8 @@ export const CodeEditor = ({
|
|
|
187
186
|
const ata = setupTypeAcquisition(ataConfig)
|
|
188
187
|
ataRef.current = ata
|
|
189
188
|
|
|
189
|
+
const lastFilesEventContent: Record<string, string> = {}
|
|
190
|
+
|
|
190
191
|
// Set up base extensions
|
|
191
192
|
const baseExtensions = [
|
|
192
193
|
basicSetup,
|
|
@@ -198,7 +199,9 @@ export const CodeEditor = ({
|
|
|
198
199
|
EditorView.updateListener.of((update) => {
|
|
199
200
|
if (update.docChanged) {
|
|
200
201
|
const newContent = update.state.doc.toString()
|
|
201
|
-
|
|
202
|
+
|
|
203
|
+
if (newContent === lastFilesEventContent[currentFile]) return
|
|
204
|
+
lastFilesEventContent[currentFile] = newContent
|
|
202
205
|
|
|
203
206
|
if (currentFile === "index.tsx") {
|
|
204
207
|
setCode(newContent)
|
|
@@ -228,10 +231,10 @@ export const CodeEditor = ({
|
|
|
228
231
|
]
|
|
229
232
|
if (codeCompletionApi?.apiKey) {
|
|
230
233
|
baseExtensions.push(
|
|
231
|
-
copilotPlugin({
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}),
|
|
234
|
+
// copilotPlugin({
|
|
235
|
+
// apiKey: codeCompletionApi.apiKey,
|
|
236
|
+
// language: Language.TYPESCRIPT,
|
|
237
|
+
// }),
|
|
235
238
|
EditorView.theme({
|
|
236
239
|
".cm-ghostText, .cm-ghostText *": {
|
|
237
240
|
opacity: "0.6",
|
|
@@ -76,12 +76,6 @@ export default function EditorNav({
|
|
|
76
76
|
const [, navigate] = useLocation()
|
|
77
77
|
const isLoggedIn = useGlobalStore((s) => Boolean(s.session))
|
|
78
78
|
const session = useGlobalStore((s) => s.session)
|
|
79
|
-
const shouldUseWebworkerForRun = useGlobalStore(
|
|
80
|
-
(s) => s.should_use_webworker_for_run,
|
|
81
|
-
)
|
|
82
|
-
const setShouldUseWebworkerForRun = useGlobalStore(
|
|
83
|
-
(s) => s.setShouldUseWebworkerForRun,
|
|
84
|
-
)
|
|
85
79
|
const { Dialog: RenameDialog, openDialog: openRenameDialog } =
|
|
86
80
|
useRenameSnippetDialog()
|
|
87
81
|
const {
|
|
@@ -278,21 +272,6 @@ export default function EditorNav({
|
|
|
278
272
|
<Share className="mr-1 h-3 w-3" />
|
|
279
273
|
Copy URL
|
|
280
274
|
</Button>
|
|
281
|
-
<Button
|
|
282
|
-
variant="ghost"
|
|
283
|
-
size="sm"
|
|
284
|
-
className="hidden md:flex px-2 text-xs"
|
|
285
|
-
onClick={() =>
|
|
286
|
-
setShouldUseWebworkerForRun(!shouldUseWebworkerForRun)
|
|
287
|
-
}
|
|
288
|
-
>
|
|
289
|
-
{shouldUseWebworkerForRun ? (
|
|
290
|
-
<CircleCheckBig className="mr-1 h-3 w-3" />
|
|
291
|
-
) : (
|
|
292
|
-
<Square className="mr-1 h-3 w-3" />
|
|
293
|
-
)}
|
|
294
|
-
Webworker (Beta)
|
|
295
|
-
</Button>
|
|
296
275
|
{/* <Button
|
|
297
276
|
variant="ghost"
|
|
298
277
|
size="sm"
|
|
@@ -3,8 +3,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
|
|
3
3
|
import { cn } from "@/lib/utils"
|
|
4
4
|
import { applyPcbEditEvents } from "@/lib/utils/pcbManualEditEventHandler"
|
|
5
5
|
import { CadViewer } from "@tscircuit/3d-viewer"
|
|
6
|
-
import { PCBViewer } from "@tscircuit/pcb-viewer"
|
|
7
|
-
import {
|
|
6
|
+
// import { PCBViewer } from "@tscircuit/pcb-viewer"
|
|
7
|
+
// import { SchematicViewer } from "@tscircuit/schematic-viewer"
|
|
8
8
|
import { useEffect, useRef, useState } from "react"
|
|
9
9
|
import { ErrorFallback } from "./ErrorFallback"
|
|
10
10
|
import { ErrorBoundary } from "react-error-boundary"
|
|
@@ -18,6 +18,10 @@ export default function ViewSnippetHeader() {
|
|
|
18
18
|
const session = useGlobalStore((s) => s.session)
|
|
19
19
|
const [isStarred, setIsStarred] = useState(snippet?.is_starred || false)
|
|
20
20
|
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
setIsStarred(snippet?.is_starred || false)
|
|
23
|
+
}, [snippet?.is_starred])
|
|
24
|
+
|
|
21
25
|
const useForkSnippetMutation = ({
|
|
22
26
|
snippet,
|
|
23
27
|
onSuccess,
|
|
@@ -10,8 +10,6 @@ export type Store = {
|
|
|
10
10
|
} | null
|
|
11
11
|
setSession: (session: Store["session"]) => any
|
|
12
12
|
should_onboarding_tips_be_closed: boolean
|
|
13
|
-
should_use_webworker_for_run?: boolean
|
|
14
|
-
setShouldUseWebworkerForRun: (should_use_webworker_for_run: boolean) => any
|
|
15
13
|
setOnboardingTipsClosed: (closed: boolean) => any
|
|
16
14
|
}
|
|
17
15
|
|
|
@@ -19,9 +17,6 @@ export const useGlobalStore = create<Store>()(
|
|
|
19
17
|
persist(
|
|
20
18
|
(set) => ({
|
|
21
19
|
session: null,
|
|
22
|
-
should_use_webworker_for_run: false,
|
|
23
|
-
setShouldUseWebworkerForRun: (should_use_webworker_for_run: boolean) =>
|
|
24
|
-
set({ should_use_webworker_for_run }),
|
|
25
20
|
setSession: (session) => set({ session }),
|
|
26
21
|
should_onboarding_tips_be_closed: false,
|
|
27
22
|
setOnboardingTipsClosed: (closed) =>
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { useAxios } from "@/hooks/use-axios"
|
|
2
|
+
import type {
|
|
3
|
+
Package,
|
|
4
|
+
PackageFile,
|
|
5
|
+
Snippet,
|
|
6
|
+
} from "fake-snippets-api/lib/db/schema"
|
|
7
|
+
import { useQuery } from "react-query"
|
|
8
|
+
|
|
9
|
+
export const usePackageAsSnippet = (packageId: string | null) => {
|
|
10
|
+
const axios = useAxios()
|
|
11
|
+
|
|
12
|
+
console.log("packageId", packageId)
|
|
13
|
+
|
|
14
|
+
const packageQuery = useQuery<Package, Error & { status: number }>(
|
|
15
|
+
["packages", packageId],
|
|
16
|
+
async () => {
|
|
17
|
+
if (!packageId) {
|
|
18
|
+
throw new Error("Package ID is required")
|
|
19
|
+
}
|
|
20
|
+
const { data } = await axios.get("/packages/get", {
|
|
21
|
+
params: { package_id: packageId },
|
|
22
|
+
})
|
|
23
|
+
return data.package
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
enabled: Boolean(packageId),
|
|
27
|
+
retry: false,
|
|
28
|
+
},
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
const filesQuery = useQuery<PackageFile[], Error & { status: number }>(
|
|
32
|
+
["package-files", packageQuery.data?.latest_package_release_id],
|
|
33
|
+
async () => {
|
|
34
|
+
if (!packageQuery.data?.latest_package_release_id) {
|
|
35
|
+
throw new Error("No latest release ID available")
|
|
36
|
+
}
|
|
37
|
+
const { data } = await axios.post("/package_files/list", {
|
|
38
|
+
package_release_id: packageQuery.data.latest_package_release_id,
|
|
39
|
+
})
|
|
40
|
+
return data.package_files
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
enabled: Boolean(packageQuery.data?.latest_package_release_id),
|
|
44
|
+
retry: false,
|
|
45
|
+
// Add these options to ensure proper sequencing
|
|
46
|
+
staleTime: 0,
|
|
47
|
+
cacheTime: 0,
|
|
48
|
+
},
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
// Map package data to match Snippet structure
|
|
52
|
+
const snippetData: Snippet | undefined = packageQuery.data && {
|
|
53
|
+
snippet_id: packageId!,
|
|
54
|
+
package_release_id: packageQuery.data.latest_package_release_id || "",
|
|
55
|
+
unscoped_name: packageQuery.data.unscoped_name,
|
|
56
|
+
name: packageQuery.data.name,
|
|
57
|
+
is_starred: false,
|
|
58
|
+
version: packageQuery.data.latest_version || "",
|
|
59
|
+
owner_name: packageQuery.data.owner_github_username || "",
|
|
60
|
+
description: packageQuery.data.description || "",
|
|
61
|
+
snippet_type: "board",
|
|
62
|
+
code:
|
|
63
|
+
filesQuery.data?.find((file) => file.file_path === "index.tsx")
|
|
64
|
+
?.content_text || "",
|
|
65
|
+
manual_edits_json_content:
|
|
66
|
+
filesQuery.data?.find((file) => file.file_path === "manual-edits.json")
|
|
67
|
+
?.content_text || "",
|
|
68
|
+
created_at: packageQuery.data.created_at,
|
|
69
|
+
updated_at: packageQuery.data.updated_at,
|
|
70
|
+
star_count: packageQuery.data.star_count,
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
data: snippetData,
|
|
75
|
+
isLoading: packageQuery.isLoading || filesQuery.isLoading,
|
|
76
|
+
error: packageQuery.error || filesQuery.error,
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { type PartsEngine, SupplierPartNumbers } from "@tscircuit/props"
|
|
2
2
|
import { AnySourceComponent } from "circuit-json"
|
|
3
|
-
import qs from "qs"
|
|
4
3
|
|
|
5
4
|
const cache = new Map<string, any>()
|
|
6
5
|
const getJlcPartsCached = async (name: any, params: any) => {
|
|
7
|
-
const paramString =
|
|
6
|
+
const paramString = new URLSearchParams({
|
|
7
|
+
...params,
|
|
8
|
+
json: "true",
|
|
9
|
+
}).toString()
|
|
8
10
|
if (cache.has(paramString)) {
|
|
9
11
|
return cache.get(paramString)
|
|
10
12
|
}
|