Skip to content

Commit

Permalink
implement seeding for dts
Browse files Browse the repository at this point in the history
  • Loading branch information
seveibar committed Oct 7, 2024
1 parent e379ea3 commit a1d3036
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 22 deletions.
1 change: 1 addition & 0 deletions fake-snippets-api/lib/db/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const snippetSchema = z.object({
unscoped_name: z.string(),
owner_name: z.string(),
code: z.string(),
dts: z.string().optional(),
created_at: z.string(),
updated_at: z.string(),
snippet_type: z.enum(["board", "package", "model", "footprint"]),
Expand Down
6 changes: 6 additions & 0 deletions fake-snippets-api/lib/db/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ export const A555Timer = ({ name }: { name: string }) => (
<chip name={name} footprint="dip8" />
)
`.trim(),
dts: `
export declare const A555Timer: ({ name }: {
name: string;
}) => any;
`.trim(),

created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
snippet_type: "package",
Expand Down
Empty file.
4 changes: 1 addition & 3 deletions fake-snippets-api/routes/api/snippets/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ export default withRouteSpec({
jsonBody: z.any().optional(),
jsonResponse: z.object({
ok: z.boolean(),
snippet: snippetSchema.extend({
snippet_type: z.enum(["board", "package", "model", "footprint"]),
}),
snippet: snippetSchema,
}),
})(async (req, ctx) => {
const { snippet_id, name, owner_name, unscoped_name } = req.commonParams
Expand Down
4 changes: 3 additions & 1 deletion fake-snippets-api/routes/api/snippets/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default withRouteSpec({
code: z.string().optional(),
description: z.string().optional(),
unscoped_name: z.string().optional(),
dts: z.string().optional(),
}),
jsonResponse: z.object({
ok: z.boolean(),
Expand All @@ -18,7 +19,7 @@ export default withRouteSpec({
}),
}),
})(async (req, ctx) => {
const { snippet_id, code, description, unscoped_name } = req.jsonBody
const { snippet_id, code, description, unscoped_name, dts } = req.jsonBody

const snippetIndex = ctx.db.snippets.findIndex(
(s) => s.snippet_id === snippet_id,
Expand Down Expand Up @@ -48,6 +49,7 @@ export default withRouteSpec({
name: unscoped_name
? `${ctx.auth.github_username}/${unscoped_name}`
: snippet.name,
dts: dts ?? snippet.dts,
updated_at: new Date().toISOString(),
}

Expand Down
3 changes: 3 additions & 0 deletions src/components/CodeAndPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export function CodeAndPreview({ snippet }: Props) {
return decodeUrlHashToText(window.location.toString()) ?? snippet?.code
}, [])
const [code, setCode] = useState(defaultCode ?? "")
const [dts, setDts] = useState("")
const [showPreview, setShowPreview] = useState(true)

useEffect(() => {
Expand All @@ -49,6 +50,7 @@ export function CodeAndPreview({ snippet }: Props) {
const response = await axios.post("/snippets/update", {
snippet_id: snippet.snippet_id,
code: code,
dts: dts,
})
if (response.status !== 200) {
throw new Error("Failed to save snippet")
Expand Down Expand Up @@ -103,6 +105,7 @@ export function CodeAndPreview({ snippet }: Props) {
<CodeEditor
code={code}
onCodeChange={(newCode) => setCode(newCode)}
onDtsChange={(newDts) => setDts(newDts)}
/>
</div>
{showPreview && (
Expand Down
50 changes: 32 additions & 18 deletions src/components/CodeEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,52 +18,53 @@ import {
import ts from "typescript"
import { setupTypeAcquisition } from "@typescript/ata"
import { ATABootstrapConfig } from "@typescript/ata"
import { useAxios } from "@/hooks/use-axios"
import { useSnippetsBaseApiUrl } from "@/hooks/use-snippets-base-api-url"

export const CodeEditor = ({
onCodeChange,
onDtsChange,
readOnly = false,
code,
}: {
onCodeChange: (code: string) => void
onDtsChange?: (dts: string) => void
code: string
readOnly?: boolean
}) => {
const editorRef = useRef<HTMLDivElement>(null)
const viewRef = useRef<EditorView | null>(null)
const apiUrl = useSnippetsBaseApiUrl()

useEffect(() => {
if (!editorRef.current) return

const fsMap = new Map<string, string>()
fsMap.set("index.tsx", code)
fsMap.set("package.json", `{"dependencies": {"react": "18.3.1"}}`)

// fsMap.set(
// "tscircuit-core.d.ts",
// `

// declare global {
// namespace JSX {
// interface IntrinsicElements {
// board: any
// }
// }
// }

// `.trim(),
// )

const system = createSystem(fsMap)
const env = createVirtualTypeScriptEnvironment(system, [], ts, {
jsx: ts.JsxEmit.ReactJSX,
declaration: true,
})

const ataConfig: ATABootstrapConfig = {
projectName: "my-project",
typescript: ts,
logger: console,
fetcher: (input, init) => {
// TODO redirect @tsci/* stuff to our api registry
fetcher: (input: RequestInfo | URL, init?: RequestInit) => {
const registryPrefix =
"https://data.jsdelivr.com/v1/package/resolve/npm/@tsci/"
if (typeof input === "string" && input.startsWith(registryPrefix)) {
const fullPackageName = input.split(registryPrefix)[1]
// TODO: Implement redirection to our API registry for @tsci/* packages
// For now, we'll just log the package name
console.log(`Intercepted @tsci package: ${fullPackageName}`)
return fetch(
`${apiUrl}/snippets/download?path=${encodeURIComponent(fullPackageName)}`,
)
}
// For all other cases, proceed with the original fetch
return fetch(input, init)
},
delegate: {
Expand All @@ -78,6 +79,7 @@ export const CodeEditor = ({
ata(`
import React from "@types/react"
import { Circuit } from "@tscircuit/core"
${code}
`)

const state = EditorState.create({
Expand All @@ -93,6 +95,18 @@ import { Circuit } from "@tscircuit/core"
EditorView.updateListener.of((update) => {
if (update.docChanged) {
onCodeChange(update.state.doc.toString())

const { outputFiles } = env.languageService.getEmitOutput(
"index.tsx",
true,
)

const indexDts = outputFiles.find(
(file) => file.name === "index.d.ts",
)
if (indexDts?.text && onDtsChange) {
onDtsChange(indexDts.text)
}
}
}),
EditorState.readOnly.of(readOnly),
Expand Down

0 comments on commit a1d3036

Please sign in to comment.