diff --git a/.gitignore b/.gitignore index 62f195a..b9fdc42 100644 --- a/.gitignore +++ b/.gitignore @@ -174,4 +174,6 @@ dist # Finder (MacOS) folder config .DS_Store -.vscode \ No newline at end of file +.vscode +.aider* +package-lock.json \ No newline at end of file diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..8249be5 --- /dev/null +++ b/biome.json @@ -0,0 +1,49 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.3/schema.json", + "organizeImports": { + "enabled": true + }, + "formatter": { + "enabled": true, + "indentStyle": "space" + }, + "files": { + "ignore": ["cosmos-export", "dist", "package.json"] + }, + "javascript": { + "formatter": { + "jsxQuoteStyle": "double", + "quoteProperties": "asNeeded", + "trailingCommas": "all", + "semicolons": "asNeeded", + "arrowParentheses": "always", + "bracketSpacing": true, + "bracketSameLine": false + } + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "suspicious": { + "noExplicitAny": "off" + }, + "complexity": { + "noForEach": "info" + }, + "style": { + "noUselessElse": "off", + "noNonNullAssertion": "off", + "useNumberNamespace": "off", + "useFilenamingConvention": { + "level": "error", + "options": { + "strictCase": true, + "requireAscii": true, + "filenameCases": ["kebab-case", "export"] + } + } + } + } + } +} diff --git a/bun.lockb b/bun.lockb index 784445f..64f1781 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/cli/main.ts b/cli/main.ts index e69de29..3dcda7c 100644 --- a/cli/main.ts +++ b/cli/main.ts @@ -0,0 +1,79 @@ +#!/usr/bin/env node +import { Command } from "commander" +import * as path from "path" +import * as chokidar from "chokidar" +import * as fs from "fs" +import { createServer } from "../lib/server/createServer" +import { getLocalFileDependencies } from "../lib/dependency-analysis/getLocalFileDependencies" + +const program = new Command() + +program + .name("snippets") + .description("CLI for developing tscircuit snippets") + .version("1.0.0") + +program + .command("dev") + .description("Start development server for a snippet") + .argument("", "Path to the snippet file") + .option("-p, --port ", "Port to run server on", "3000") + .action(async (file: string, options: { port: string }) => { + const absolutePath = path.resolve(file) + const port = parseInt(options.port) + + // Start the server + await createServer(port) + + // Function to update file content + const updateFile = async (filePath: string) => { + try { + const content = await fs.promises.readFile(filePath, "utf-8") + const response = await fetch( + `http://localhost:${port}/api/files/upsert`, + { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + file_path: path.relative(process.cwd(), filePath), + text_content: content, + }), + }, + ) + if (!response.ok) { + console.error(`Failed to update ${filePath}`) + } + } catch (error) { + console.error(`Error updating ${filePath}:`, error) + } + } + + // Get initial dependencies + let dependencies = new Set([absolutePath]) + try { + const deps = getLocalFileDependencies(absolutePath) + deps.forEach((dep) => dependencies.add(dep)) + } catch (error) { + console.warn("Failed to analyze dependencies:", error) + } + + // Watch the main file and its dependencies + const watcher = chokidar.watch(Array.from(dependencies), { + persistent: true, + ignoreInitial: false, + }) + + watcher.on("change", async (filePath) => { + console.log(`File ${filePath} changed`) + await updateFile(filePath) + }) + + watcher.on("add", async (filePath) => { + console.log(`File ${filePath} added`) + await updateFile(filePath) + }) + + console.log(`Watching ${file} and its dependencies...`) + }) + +program.parse() diff --git a/example-dir/snippet.tsx b/example-dir/snippet.tsx new file mode 100644 index 0000000..83df69b --- /dev/null +++ b/example-dir/snippet.tsx @@ -0,0 +1,18 @@ +import { useRedLed } from "@tsci/seveibar.red-led" +import { usePushButton } from "@tsci/seveibar.push-button" +import { useUsbC } from "@tsci/seveibar.smd-usb-c" + +export default () => { + const USBC = useUsbC("USBC") + const Button = usePushButton("SW1") + const Led = useRedLed("LED") + return ( + + + +