@tscircuit/cli 0.0.38 → 0.0.40
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.lockb +0 -0
- package/dev-server-api/routes/api/dev_package_examples/create.ts +3 -0
- package/dev-server-api/routes/api/dev_package_examples/get.ts +2 -0
- package/dev-server-api/routes/api/dev_package_examples/list.ts +13 -9
- package/dev-server-api/routes/api/dev_server/reset.ts +15 -0
- package/dev-server-api/src/db/create-schema.ts +1 -0
- package/dev-server-api/src/db/get-db.ts +5 -2
- package/dev-server-api/src/middlewares/with-error-response.ts +15 -2
- package/dev-server-frontend/bun.lockb +0 -0
- package/dev-server-frontend/package.json +5 -4
- package/dev-server-frontend/src/ExampleContentView.tsx +30 -1
- package/dev-server-frontend/src/components/command-k.tsx +29 -5
- package/dist/cli.js +243 -154
- package/lib/cmd-fns/config-set-runtime.ts +7 -0
- package/lib/cmd-fns/dev/index.ts +9 -6
- package/lib/cmd-fns/dev/mark-all-examples-loading.ts +18 -0
- package/lib/cmd-fns/dev/soupify-and-upload-example-file.ts +29 -14
- package/lib/cmd-fns/dev/start-watcher.ts +11 -8
- package/lib/cmd-fns/dev/upload-examples-from-directory.ts +23 -12
- package/lib/cmd-fns/dev-server-upload.ts +2 -2
- package/lib/cmd-fns/index.ts +1 -0
- package/lib/cmd-fns/package-examples-create.ts +7 -4
- package/lib/cmd-fns/publish/index.ts +7 -4
- package/lib/cmd-fns/soupify.ts +7 -4
- package/lib/create-config-manager.ts +1 -0
- package/lib/get-program.ts +7 -0
- package/lib/param-handlers/index.ts +2 -0
- package/lib/param-handlers/interact-for-runtime.ts +33 -0
- package/lib/soupify.ts +13 -8
- package/lib/util/app-context.ts +1 -0
- package/lib/util/create-context-and-run-program.ts +1 -0
- package/package.json +9 -6
package/bun.lockb
CHANGED
|
Binary file
|
|
@@ -9,6 +9,7 @@ export default withEdgeSpec({
|
|
|
9
9
|
export_name: z.string().default("default"),
|
|
10
10
|
tscircuit_soup: z.any(),
|
|
11
11
|
error: z.string().nullable().optional().default(null),
|
|
12
|
+
is_loading: z.boolean().optional(),
|
|
12
13
|
}),
|
|
13
14
|
jsonResponse: z.object({
|
|
14
15
|
dev_package_example: z.object({
|
|
@@ -31,6 +32,7 @@ export default withEdgeSpec({
|
|
|
31
32
|
export_name: req.jsonBody.export_name,
|
|
32
33
|
error: req.jsonBody.error,
|
|
33
34
|
tscircuit_soup,
|
|
35
|
+
is_loading: req.jsonBody.is_loading ? 1 : 0,
|
|
34
36
|
last_updated_at: new Date().toISOString(),
|
|
35
37
|
})
|
|
36
38
|
.onConflict((oc) =>
|
|
@@ -38,6 +40,7 @@ export default withEdgeSpec({
|
|
|
38
40
|
export_name: req.jsonBody.export_name,
|
|
39
41
|
error: req.jsonBody.error,
|
|
40
42
|
tscircuit_soup,
|
|
43
|
+
is_loading: req.jsonBody.is_loading ? 1 : 0,
|
|
41
44
|
last_updated_at: new Date().toISOString(),
|
|
42
45
|
})
|
|
43
46
|
)
|
|
@@ -12,6 +12,7 @@ export default withEdgeSpec({
|
|
|
12
12
|
dev_package_example_id: z.coerce.number(),
|
|
13
13
|
file_path: z.string(),
|
|
14
14
|
tscircuit_soup: z.any(),
|
|
15
|
+
is_loading: z.boolean(),
|
|
15
16
|
error: z.string().nullable().optional().default(null),
|
|
16
17
|
last_updated_at: z.string().datetime(),
|
|
17
18
|
}),
|
|
@@ -32,6 +33,7 @@ export default withEdgeSpec({
|
|
|
32
33
|
})
|
|
33
34
|
.then((r) => ({
|
|
34
35
|
...r,
|
|
36
|
+
is_loading: r.is_loading === 1,
|
|
35
37
|
tscircuit_soup: JSON.parse(r.tscircuit_soup),
|
|
36
38
|
})),
|
|
37
39
|
})
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { sql } from "kysely"
|
|
1
2
|
import { withEdgeSpec } from "src/with-edge-spec"
|
|
2
3
|
import { z } from "zod"
|
|
3
4
|
|
|
@@ -9,21 +10,24 @@ export default withEdgeSpec({
|
|
|
9
10
|
dev_package_example_id: z.coerce.number(),
|
|
10
11
|
file_path: z.string(),
|
|
11
12
|
export_name: z.string(),
|
|
13
|
+
is_loading: z.coerce.boolean(),
|
|
12
14
|
last_updated_at: z.string().datetime(),
|
|
13
15
|
})
|
|
14
16
|
),
|
|
15
17
|
}),
|
|
16
18
|
auth: "none",
|
|
17
19
|
})(async (req, ctx) => {
|
|
20
|
+
const dev_package_examples = await ctx.db
|
|
21
|
+
.selectFrom("dev_package_example")
|
|
22
|
+
.select([
|
|
23
|
+
"dev_package_example_id",
|
|
24
|
+
"file_path",
|
|
25
|
+
"export_name",
|
|
26
|
+
"last_updated_at",
|
|
27
|
+
sql`(is_loading = 1)`.$castTo<boolean>().as("is_loading"),
|
|
28
|
+
])
|
|
29
|
+
.execute()
|
|
18
30
|
return ctx.json({
|
|
19
|
-
dev_package_examples
|
|
20
|
-
.selectFrom("dev_package_example")
|
|
21
|
-
.select([
|
|
22
|
-
"dev_package_example_id",
|
|
23
|
-
"file_path",
|
|
24
|
-
"export_name",
|
|
25
|
-
"last_updated_at",
|
|
26
|
-
])
|
|
27
|
-
.execute(),
|
|
31
|
+
dev_package_examples,
|
|
28
32
|
})
|
|
29
33
|
})
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { sql } from "kysely"
|
|
2
|
+
import { withEdgeSpec } from "src/with-edge-spec"
|
|
3
|
+
import { z } from "zod"
|
|
4
|
+
import { unlinkSync } from "fs"
|
|
5
|
+
import { getDbFilePath } from "src/db/get-db"
|
|
6
|
+
|
|
7
|
+
export default (req: Request) => {
|
|
8
|
+
unlinkSync(getDbFilePath())
|
|
9
|
+
|
|
10
|
+
return new Response(JSON.stringify({}), {
|
|
11
|
+
headers: {
|
|
12
|
+
"content-type": "application/json",
|
|
13
|
+
},
|
|
14
|
+
})
|
|
15
|
+
}
|
|
@@ -10,6 +10,7 @@ export const createSchema = async (db: DbClient) => {
|
|
|
10
10
|
.addColumn("export_name", "text")
|
|
11
11
|
.addColumn("tscircuit_soup", "json")
|
|
12
12
|
.addColumn("error", "text")
|
|
13
|
+
.addColumn("is_loading", "boolean", (cb) => cb.defaultTo(0).notNull())
|
|
13
14
|
.addColumn("last_updated_at", "text")
|
|
14
15
|
.execute()
|
|
15
16
|
}
|
|
@@ -9,6 +9,7 @@ interface DevPackageExample {
|
|
|
9
9
|
file_path: string
|
|
10
10
|
export_name: string
|
|
11
11
|
error: string | null
|
|
12
|
+
is_loading: 1 | 0
|
|
12
13
|
last_updated_at: string
|
|
13
14
|
}
|
|
14
15
|
|
|
@@ -22,11 +23,13 @@ export type DbClient = Kysely<KyselyDatabaseSchema>
|
|
|
22
23
|
|
|
23
24
|
let globalDb: Kysely<KyselyDatabaseSchema> | undefined
|
|
24
25
|
|
|
26
|
+
export const getDbFilePath = () =>
|
|
27
|
+
process.env.TSCI_DEV_SERVER_DB ?? "./.tscircuit/dev-server.sqlite"
|
|
28
|
+
|
|
25
29
|
export const getDb = async (): Promise<Kysely<KyselyDatabaseSchema>> => {
|
|
26
30
|
if (globalDb) return globalDb
|
|
27
31
|
|
|
28
|
-
const devServerDbPath =
|
|
29
|
-
process.env.TSCI_DEV_SERVER_DB ?? "./.tscircuit/dev-server.db"
|
|
32
|
+
const devServerDbPath = getDbFilePath()
|
|
30
33
|
|
|
31
34
|
mkdirSync(Path.dirname(devServerDbPath), { recursive: true })
|
|
32
35
|
|
|
@@ -1,15 +1,28 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { NotFoundError, type Middleware } from "edgespec/middleware"
|
|
2
2
|
import kleur from "kleur"
|
|
3
3
|
|
|
4
4
|
export const withErrorResponse: Middleware<{}, {}> = async (req, ctx, next) => {
|
|
5
5
|
try {
|
|
6
6
|
return await next(req, ctx)
|
|
7
7
|
} catch (error: any) {
|
|
8
|
-
console.error(kleur.red("Intercepted error:"), error)
|
|
9
8
|
// If error is a Response, return it
|
|
10
9
|
if (error instanceof Response) {
|
|
11
10
|
return error
|
|
12
11
|
}
|
|
12
|
+
if (error instanceof NotFoundError) {
|
|
13
|
+
return (ctx as any).json(
|
|
14
|
+
{
|
|
15
|
+
ok: false,
|
|
16
|
+
error: {
|
|
17
|
+
message: error?.message,
|
|
18
|
+
error_code: "not_found",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
{ status: error?.status || 404 }
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
console.error(kleur.red("Intercepted unhandled error:"), error)
|
|
13
26
|
return (ctx as any).json(
|
|
14
27
|
{
|
|
15
28
|
ok: false,
|
|
Binary file
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
"start": "npm run dev",
|
|
13
13
|
"build": "tsc && vite build --base /preview && rm -f dist/bundle* && make-vfs --dir dist --outfile ./dist/bundle.ts",
|
|
14
14
|
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 10",
|
|
15
|
-
"preview": "vite preview"
|
|
15
|
+
"preview": "vite preview",
|
|
16
|
+
"update-deps": "bun add @tscircuit/pcb-viewer@latest @tscircuit/builder@latest @tscircuit/schematic-viewer@latest"
|
|
16
17
|
},
|
|
17
18
|
"dependencies": {
|
|
18
19
|
"@radix-ui/react-alert-dialog": "^1.0.5",
|
|
@@ -28,9 +29,9 @@
|
|
|
28
29
|
"@radix-ui/react-toggle": "^1.0.3",
|
|
29
30
|
"@radix-ui/react-toggle-group": "^1.0.4",
|
|
30
31
|
"@radix-ui/react-tooltip": "^1.0.7",
|
|
31
|
-
"@tscircuit/builder": "
|
|
32
|
-
"@tscircuit/pcb-viewer": "
|
|
33
|
-
"@tscircuit/schematic-viewer": "
|
|
32
|
+
"@tscircuit/builder": "latest",
|
|
33
|
+
"@tscircuit/pcb-viewer": "latest",
|
|
34
|
+
"@tscircuit/schematic-viewer": "latest",
|
|
34
35
|
"axios": "^1.6.7",
|
|
35
36
|
"class-variance-authority": "^0.7.0",
|
|
36
37
|
"clsx": "^2.1.0",
|
|
@@ -10,7 +10,12 @@ export const ExampleContentView = () => {
|
|
|
10
10
|
(s) => s.active_dev_example_package_id
|
|
11
11
|
)
|
|
12
12
|
|
|
13
|
-
const {
|
|
13
|
+
const {
|
|
14
|
+
data: pkg,
|
|
15
|
+
error,
|
|
16
|
+
isError,
|
|
17
|
+
isLoading,
|
|
18
|
+
} = useQuery(
|
|
14
19
|
["dev_package_example", devExamplePackageId],
|
|
15
20
|
async () =>
|
|
16
21
|
axios
|
|
@@ -20,9 +25,12 @@ export const ExampleContentView = () => {
|
|
|
20
25
|
.then((r) => r.data.dev_package_example),
|
|
21
26
|
{
|
|
22
27
|
refetchIntervalInBackground: true,
|
|
28
|
+
retry: false,
|
|
23
29
|
}
|
|
24
30
|
)
|
|
25
31
|
|
|
32
|
+
const notFound = (error as any)?.response?.status === 404
|
|
33
|
+
|
|
26
34
|
const viewMode = useGlobalStore((s) => s.view_mode)
|
|
27
35
|
const splitMode = useGlobalStore((s) => s.split_mode)
|
|
28
36
|
|
|
@@ -31,6 +39,7 @@ export const ExampleContentView = () => {
|
|
|
31
39
|
|
|
32
40
|
const itemHeight =
|
|
33
41
|
viewMode === "split" && splitMode === "vertical" ? halfHeight : editorHeight
|
|
42
|
+
console.log(pkg)
|
|
34
43
|
|
|
35
44
|
return (
|
|
36
45
|
<div
|
|
@@ -44,6 +53,26 @@ export const ExampleContentView = () => {
|
|
|
44
53
|
viewMode === "split" && splitMode === "vertical" && "grid grid-rows-2"
|
|
45
54
|
)}
|
|
46
55
|
>
|
|
56
|
+
{notFound && (
|
|
57
|
+
<div className="absolute top-0 w-full flex justify-center">
|
|
58
|
+
<div className="bg-yellow-50 shadow-lg p-4 m-16 border-yellow-200 border rounded-lg whitespace-pre max-w-[400px]">
|
|
59
|
+
Select an example from the menu above
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
)}
|
|
63
|
+
{isLoading && !isError && (
|
|
64
|
+
<div className="absolute top-0 w-full flex justify-center">
|
|
65
|
+
<div className="bg-gray-50 shadow-lg p-4 m-16 border-gray-200 border rounded-lg whitespace-pre">
|
|
66
|
+
Loading...
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
)}
|
|
70
|
+
{pkg && pkg.is_loading && (
|
|
71
|
+
<div className="absolute top-0 right-0 bg-white p-4 py-2 m-4 rounded-md flex items-center z-10 shadow-lg border border-gray-200">
|
|
72
|
+
<div className="border-2 border-blue-400 border-t-transparent rounded-full w-4 h-4 animate-spin mr-2"></div>
|
|
73
|
+
Rebuilding...
|
|
74
|
+
</div>
|
|
75
|
+
)}
|
|
47
76
|
{pkg && (viewMode === "schematic" || viewMode === "split") && (
|
|
48
77
|
<Schematic
|
|
49
78
|
key={pkg?.last_updated_at}
|
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
CommandShortcut,
|
|
10
10
|
} from "./ui/command"
|
|
11
11
|
import { useGlobalStore } from "src/hooks/use-global-store"
|
|
12
|
+
import { useDevPackageExamples } from "./select-example-search"
|
|
13
|
+
import { CommandSeparator } from "cmdk"
|
|
12
14
|
|
|
13
15
|
export const CommandK = () => {
|
|
14
16
|
const [open, setOpen] = useState(false)
|
|
@@ -19,23 +21,28 @@ export const CommandK = () => {
|
|
|
19
21
|
e.preventDefault()
|
|
20
22
|
setOpen((open) => !open)
|
|
21
23
|
}
|
|
24
|
+
if (e.key === "Escape") {
|
|
25
|
+
setOpen(false)
|
|
26
|
+
}
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
document.addEventListener("keydown", down)
|
|
25
30
|
return () => document.removeEventListener("keydown", down)
|
|
26
31
|
}, [])
|
|
27
32
|
|
|
33
|
+
const { data: examples } = useDevPackageExamples()
|
|
34
|
+
|
|
28
35
|
const close = () => {
|
|
29
36
|
setOpen(false)
|
|
30
37
|
return true
|
|
31
38
|
}
|
|
32
39
|
|
|
33
40
|
return (
|
|
34
|
-
<CommandDialog open={open}>
|
|
41
|
+
<CommandDialog open={open} onOpenChange={(open) => setOpen(open)}>
|
|
35
42
|
<Command className="rounded-lg border shadow-md">
|
|
36
43
|
<CommandInput placeholder="Type a command or search..." />
|
|
37
|
-
<
|
|
38
|
-
<
|
|
44
|
+
<CommandList>
|
|
45
|
+
<CommandGroup heading="Viewing Options">
|
|
39
46
|
<CommandItem
|
|
40
47
|
onSelect={() => close() && store.setViewMode("schematic")}
|
|
41
48
|
>
|
|
@@ -54,8 +61,25 @@ export const CommandK = () => {
|
|
|
54
61
|
Vertical Split
|
|
55
62
|
<CommandShortcut></CommandShortcut>
|
|
56
63
|
</CommandItem>
|
|
57
|
-
</
|
|
58
|
-
|
|
64
|
+
</CommandGroup>
|
|
65
|
+
<CommandSeparator />
|
|
66
|
+
<CommandGroup heading="Examples">
|
|
67
|
+
{examples?.map((ex) => (
|
|
68
|
+
<CommandItem
|
|
69
|
+
key={ex.dev_package_example_id}
|
|
70
|
+
value={ex.expath}
|
|
71
|
+
onSelect={() =>
|
|
72
|
+
close() &&
|
|
73
|
+
store.setActiveDevExamplePackageId(
|
|
74
|
+
ex.dev_package_example_id.toString()
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
>
|
|
78
|
+
{ex.expath}
|
|
79
|
+
</CommandItem>
|
|
80
|
+
))}
|
|
81
|
+
</CommandGroup>
|
|
82
|
+
</CommandList>
|
|
59
83
|
</Command>
|
|
60
84
|
</CommandDialog>
|
|
61
85
|
)
|