@tscircuit/eval 0.0.363 → 0.0.365
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/dist/blob-url.js +1 -1
- package/dist/webworker/entrypoint.js +28 -28
- package/package.json +6 -3
- package/.github/workflows/bun-formatcheck.yml +0 -27
- package/.github/workflows/bun-pver-release.yml +0 -70
- package/.github/workflows/bun-test.yml +0 -87
- package/.github/workflows/bun-typecheck.yml +0 -27
- package/.github/workflows/playwright.yml +0 -40
- package/.github/workflows/update-deps.yml +0 -47
- package/.github/workflows/update-tscircuit-core.yml +0 -59
- package/biome.json +0 -50
- package/browser-tests/browser.test.ts +0 -15
- package/browser-tests/browsertest.html +0 -15
- package/browser-tests/browsertest.ts +0 -53
- package/bunfig.toml +0 -6
- package/lib/getPlatformConfig.ts +0 -41
- package/lib/getPossibleEntrypointComponentPaths.ts +0 -42
- package/lib/index.ts +0 -5
- package/lib/runner/CircuitRunner.ts +0 -201
- package/lib/runner/index.ts +0 -4
- package/lib/runner/normalizeFsMap.ts +0 -20
- package/lib/runner/resolveFilePath.ts +0 -90
- package/lib/runner/runTscircuitCode.ts +0 -30
- package/lib/runner/runTscircuitModule.ts +0 -37
- package/lib/runner/setupDefaultEntrypointIfNeeded.ts +0 -81
- package/lib/shared/static-asset-extensions.ts +0 -10
- package/lib/shared/types.ts +0 -79
- package/lib/utils/dirname.ts +0 -21
- package/lib/utils/get-imports-from-code.ts +0 -23
- package/lib/utils/index.ts +0 -1
- package/lib/utils/resolve-node-module.ts +0 -193
- package/lib/worker.ts +0 -246
- package/playwright.config.ts +0 -23
- package/scripts/build-worker-blob-url.ts +0 -27
- package/scripts/copy-core-versions.ts +0 -81
- package/scripts/validate-test-matrix.js +0 -148
- package/tests/circuit-runner/circuitrunner1-readme-example.test.tsx +0 -29
- package/tests/custom-component-with-fsmap/should-reject-invalid-main-component-path.test.ts +0 -26
- package/tests/custom-component-with-fsmap/should-render-multiple-components-from-fsmap.test.ts +0 -46
- package/tests/custom-component-with-fsmap/should-render-single-component-from-fsmap.test.ts +0 -38
- package/tests/examples/__snapshots__/example18-kicad-footprint-server.snap.svg +0 -1
- package/tests/examples/example01-readme-example.test.tsx +0 -30
- package/tests/examples/example02-multiple-files.test.tsx +0 -45
- package/tests/examples/example03-encoded-url.test.tsx +0 -28
- package/tests/examples/example04-root-child-issue.test.tsx +0 -37
- package/tests/examples/example05-event-recording.test.tsx +0 -44
- package/tests/examples/example06-dynamic-load-blob-url.test.tsx +0 -29
- package/tests/examples/example07-import-default-and-namespace.test.tsx +0 -74
- package/tests/examples/example08-footprinter-to220.test.tsx +0 -30
- package/tests/examples/example09-not-defined-component.test.tsx +0 -24
- package/tests/examples/example10-run-tscircuit-code.test.tsx +0 -14
- package/tests/examples/example11-flexible-import-extensions.test.tsx +0 -20
- package/tests/examples/example12-import-from-subdirectory.test.tsx +0 -26
- package/tests/examples/example13-webworker-without-entrypoint.test.tsx +0 -32
- package/tests/examples/example14-run-tscircuit-module.test.tsx +0 -20
- package/tests/examples/example15-run-tscircuit-module-with-props.test.tsx +0 -24
- package/tests/examples/example16-parts-engine.test.tsx +0 -118
- package/tests/examples/example17-parse-tscircuit-config.test.tsx +0 -49
- package/tests/examples/example18-kicad-footprint-server.test.tsx +0 -39
- package/tests/examples/example19-support-backwards-compat.test.tsx +0 -31
- package/tests/examples/example20-kicad-import.test.tsx +0 -48
- package/tests/features/circuit-event-forwarding.test.tsx +0 -45
- package/tests/features/enable-debug.test.ts +0 -26
- package/tests/features/execute-component-runner.test.tsx +0 -47
- package/tests/features/execute-component-worker.test.tsx +0 -25
- package/tests/features/fetch-proxy/fetch-override.test.ts +0 -46
- package/tests/features/fetch-proxy/fetch-proxy-validation.test.ts +0 -95
- package/tests/features/kill.test.ts +0 -24
- package/tests/features/manual-edits.test.tsx +0 -118
- package/tests/features/npm-import.test.tsx +0 -47
- package/tests/features/parent-directory-import.test.tsx +0 -26
- package/tests/features/platform-config.test.tsx +0 -23
- package/tests/features/prioritize-default-export.test.tsx +0 -27
- package/tests/features/project-config.test.tsx +0 -25
- package/tests/features/static-file-imports/static-file-import.test.ts +0 -50
- package/tests/fixtures/preload.ts +0 -10
- package/tests/fixtures/resourcePaths.ts +0 -3
- package/tests/node-resolution/node-module-resolution-1.test.tsx +0 -32
- package/tests/node-resolution/node-module-resolution-10.test.tsx +0 -30
- package/tests/node-resolution/node-module-resolution-11.test.tsx +0 -41
- package/tests/node-resolution/node-module-resolution-2.test.tsx +0 -33
- package/tests/node-resolution/node-module-resolution-3.test.tsx +0 -38
- package/tests/node-resolution/node-module-resolution-4.test.tsx +0 -29
- package/tests/node-resolution/node-module-resolution-5.test.tsx +0 -38
- package/tests/node-resolution/node-module-resolution-6.test.tsx +0 -40
- package/tests/node-resolution/node-module-resolution-7.test.tsx +0 -43
- package/tests/node-resolution/node-module-resolution-8.test.tsx +0 -32
- package/tests/node-resolution/node-module-resolution-9.test.tsx +0 -29
- package/tests/node-resolution/node-modules-resolution-12.test.tsx +0 -30
- package/tests/repros/group-wrapper.test.tsx +0 -18
- package/tests/repros/nine-keyboard-default-export.test.tsx +0 -26
- package/tests/util-fns/get-imports-from-code.test.tsx +0 -93
- package/tests/util-fns/getPossibleEntrypointComponentPaths.test.ts +0 -35
- package/tsconfig.json +0 -34
- package/tsup-lib.config.ts +0 -11
- package/tsup-runner.config.ts +0 -12
- package/tsup-webworker.config.ts +0 -21
- package/webworker/entrypoint.ts +0 -227
- package/webworker/eval-compiled-js.ts +0 -61
- package/webworker/execution-context.ts +0 -64
- package/webworker/fetchProxy.ts +0 -83
- package/webworker/import-eval-path.ts +0 -78
- package/webworker/import-local-file.ts +0 -93
- package/webworker/import-node-module.ts +0 -54
- package/webworker/import-npm-package.ts +0 -77
- package/webworker/import-snippet.ts +0 -30
- package/webworker/index.ts +0 -1
- package/webworker/transform-with-sucrase.ts +0 -68
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
import type { AnyCircuitElement } from "circuit-json"
|
|
2
|
-
import type {
|
|
3
|
-
CircuitRunnerApi,
|
|
4
|
-
CircuitRunnerConfiguration,
|
|
5
|
-
} from "lib/shared/types"
|
|
6
|
-
import type { PlatformConfig } from "@tscircuit/props"
|
|
7
|
-
import { createExecutionContext } from "../../webworker/execution-context"
|
|
8
|
-
import { normalizeFsMap } from "./normalizeFsMap"
|
|
9
|
-
import type { RootCircuit } from "@tscircuit/core"
|
|
10
|
-
import * as React from "react"
|
|
11
|
-
import { importEvalPath } from "webworker/import-eval-path"
|
|
12
|
-
import { setupDefaultEntrypointIfNeeded } from "./setupDefaultEntrypointIfNeeded"
|
|
13
|
-
import Debug from "debug"
|
|
14
|
-
|
|
15
|
-
const debug = Debug("tsci:eval:CircuitRunner")
|
|
16
|
-
|
|
17
|
-
export class CircuitRunner implements CircuitRunnerApi {
|
|
18
|
-
_executionContext: ReturnType<typeof createExecutionContext> | null = null
|
|
19
|
-
_circuitRunnerConfiguration: CircuitRunnerConfiguration = {
|
|
20
|
-
snippetsApiBaseUrl: "https://registry-api.tscircuit.com",
|
|
21
|
-
cjsRegistryUrl: "https://cjs.tscircuit.com",
|
|
22
|
-
verbose: false,
|
|
23
|
-
}
|
|
24
|
-
_eventListeners: Record<string, ((...args: any[]) => void)[]> = {}
|
|
25
|
-
_debugNamespace: string | undefined
|
|
26
|
-
|
|
27
|
-
constructor(configuration: Partial<CircuitRunnerConfiguration> = {}) {
|
|
28
|
-
Object.assign(this._circuitRunnerConfiguration, configuration)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async version(): Promise<string> {
|
|
32
|
-
return "0.0.0"
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async executeWithFsMap(ogOpts: {
|
|
36
|
-
entrypoint?: string
|
|
37
|
-
mainComponentPath?: string
|
|
38
|
-
mainComponentName?: string
|
|
39
|
-
fsMap: Record<string, string>
|
|
40
|
-
name?: string
|
|
41
|
-
mainComponentProps?: Record<string, any>
|
|
42
|
-
}): Promise<void> {
|
|
43
|
-
const opts = { ...ogOpts }
|
|
44
|
-
|
|
45
|
-
if (this._circuitRunnerConfiguration.verbose) {
|
|
46
|
-
Debug.enable("tsci:eval:*")
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
debug("executeWithFsMap called with:", {
|
|
50
|
-
entrypoint: opts.entrypoint,
|
|
51
|
-
fsMapKeys: Object.keys(opts.fsMap),
|
|
52
|
-
name: opts.name,
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
setupDefaultEntrypointIfNeeded(opts)
|
|
56
|
-
|
|
57
|
-
debug("entrypoint after setupDefaultEntrypointIfNeeded:", {
|
|
58
|
-
entrypoint: opts.entrypoint,
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
this._executionContext = createExecutionContext(
|
|
62
|
-
this._circuitRunnerConfiguration,
|
|
63
|
-
{
|
|
64
|
-
name: opts.name,
|
|
65
|
-
platform: this._circuitRunnerConfiguration.platform,
|
|
66
|
-
projectConfig: this._circuitRunnerConfiguration.projectConfig,
|
|
67
|
-
debugNamespace: this._debugNamespace,
|
|
68
|
-
},
|
|
69
|
-
)
|
|
70
|
-
this._bindEventListeners(this._executionContext.circuit)
|
|
71
|
-
|
|
72
|
-
this._executionContext.fsMap = normalizeFsMap(opts.fsMap)
|
|
73
|
-
if (!this._executionContext.fsMap[opts.entrypoint!]) {
|
|
74
|
-
throw new Error(`Entrypoint "${opts.entrypoint}" not found`)
|
|
75
|
-
}
|
|
76
|
-
;(globalThis as any).__tscircuit_circuit = this._executionContext.circuit
|
|
77
|
-
|
|
78
|
-
const entrypoint = opts.entrypoint!.startsWith("./")
|
|
79
|
-
? opts.entrypoint
|
|
80
|
-
: `./${opts.entrypoint}`
|
|
81
|
-
|
|
82
|
-
debug("final entrypoint:", entrypoint)
|
|
83
|
-
await importEvalPath(entrypoint!, this._executionContext)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
async execute(code: string, opts: { name?: string } = {}) {
|
|
87
|
-
if (this._circuitRunnerConfiguration.verbose) {
|
|
88
|
-
console.log(
|
|
89
|
-
"[CircuitRunner] execute called with code length:",
|
|
90
|
-
code.length,
|
|
91
|
-
)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
this._executionContext = createExecutionContext(
|
|
95
|
-
this._circuitRunnerConfiguration,
|
|
96
|
-
{
|
|
97
|
-
...opts,
|
|
98
|
-
platform: this._circuitRunnerConfiguration.platform,
|
|
99
|
-
projectConfig: this._circuitRunnerConfiguration.projectConfig,
|
|
100
|
-
debugNamespace: this._debugNamespace,
|
|
101
|
-
},
|
|
102
|
-
)
|
|
103
|
-
this._bindEventListeners(this._executionContext.circuit)
|
|
104
|
-
this._executionContext.fsMap["entrypoint.tsx"] = code
|
|
105
|
-
;(globalThis as any).__tscircuit_circuit = this._executionContext.circuit
|
|
106
|
-
|
|
107
|
-
await importEvalPath("./entrypoint.tsx", this._executionContext)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
async executeComponent(component: any, opts: { name?: string } = {}) {
|
|
111
|
-
if (this._circuitRunnerConfiguration.verbose) {
|
|
112
|
-
console.log("[CircuitRunner] executeComponent called")
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
this._executionContext = createExecutionContext(
|
|
116
|
-
this._circuitRunnerConfiguration,
|
|
117
|
-
{
|
|
118
|
-
...opts,
|
|
119
|
-
platform: this._circuitRunnerConfiguration.platform,
|
|
120
|
-
projectConfig: this._circuitRunnerConfiguration.projectConfig,
|
|
121
|
-
debugNamespace: this._debugNamespace,
|
|
122
|
-
},
|
|
123
|
-
)
|
|
124
|
-
this._bindEventListeners(this._executionContext.circuit)
|
|
125
|
-
;(globalThis as any).__tscircuit_circuit = this._executionContext.circuit
|
|
126
|
-
|
|
127
|
-
const element = typeof component === "function" ? component() : component
|
|
128
|
-
this._executionContext.circuit.add(element as any)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
on(event: string, callback: (...args: any[]) => void) {
|
|
132
|
-
this._eventListeners[event] ??= []
|
|
133
|
-
this._eventListeners[event].push(callback)
|
|
134
|
-
this._executionContext?.circuit.on(event as any, callback)
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
async renderUntilSettled(): Promise<void> {
|
|
138
|
-
if (!this._executionContext) {
|
|
139
|
-
throw new Error("No circuit has been created")
|
|
140
|
-
}
|
|
141
|
-
await this._executionContext.circuit.renderUntilSettled()
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
async getCircuitJson(): Promise<AnyCircuitElement[]> {
|
|
145
|
-
if (!this._executionContext) {
|
|
146
|
-
throw new Error("No circuit has been created")
|
|
147
|
-
}
|
|
148
|
-
return this._executionContext.circuit.getCircuitJson()
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
clearEventListeners() {
|
|
152
|
-
if (this._executionContext?.circuit) {
|
|
153
|
-
for (const event in this._eventListeners) {
|
|
154
|
-
for (const listener of this._eventListeners[event]) {
|
|
155
|
-
const circuit = this._executionContext.circuit as unknown as {
|
|
156
|
-
// biome-ignore lint/complexity/noBannedTypes: <explanation>
|
|
157
|
-
removeListener?: (event: string, listener: Function) => void
|
|
158
|
-
}
|
|
159
|
-
circuit.removeListener?.(event, listener)
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
for (const event in this._eventListeners) {
|
|
165
|
-
delete this._eventListeners[event]
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
async kill() {
|
|
170
|
-
// Cleanup resources
|
|
171
|
-
this._executionContext = null
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
async setSnippetsApiBaseUrl(baseUrl: string) {
|
|
175
|
-
this._circuitRunnerConfiguration.snippetsApiBaseUrl = baseUrl
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
async setPlatformConfig(platform: PlatformConfig) {
|
|
179
|
-
this._circuitRunnerConfiguration.platform = platform
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
async setProjectConfig(project: Partial<PlatformConfig>) {
|
|
183
|
-
this._circuitRunnerConfiguration.projectConfig = project
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
async enableDebug(namespace: string) {
|
|
187
|
-
this._debugNamespace = namespace
|
|
188
|
-
if (this._executionContext) {
|
|
189
|
-
const circuit = this._executionContext.circuit as any
|
|
190
|
-
circuit.enableDebug?.(namespace)
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
private _bindEventListeners(circuit: RootCircuit) {
|
|
195
|
-
for (const event in this._eventListeners) {
|
|
196
|
-
for (const listener of this._eventListeners[event]) {
|
|
197
|
-
circuit.on(event as any, listener as any)
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
package/lib/runner/index.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export function normalizeFilePath(filePath: string) {
|
|
2
|
-
let normFilePath = filePath
|
|
3
|
-
normFilePath = normFilePath.replace(/\\/g, "/")
|
|
4
|
-
normFilePath = normFilePath.trim()
|
|
5
|
-
if (normFilePath.startsWith("./")) {
|
|
6
|
-
normFilePath = normFilePath.slice(2)
|
|
7
|
-
}
|
|
8
|
-
if (normFilePath.startsWith("/")) {
|
|
9
|
-
normFilePath = normFilePath.slice(1)
|
|
10
|
-
}
|
|
11
|
-
return normFilePath
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function normalizeFsMap(fsMap: Record<string, string>) {
|
|
15
|
-
const normalizedFsMap: Record<string, string> = {}
|
|
16
|
-
for (const [fsPath, fileContent] of Object.entries(fsMap)) {
|
|
17
|
-
normalizedFsMap[normalizeFilePath(fsPath)] = fileContent
|
|
18
|
-
}
|
|
19
|
-
return normalizedFsMap
|
|
20
|
-
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { normalizeFilePath } from "./normalizeFsMap"
|
|
2
|
-
import { dirname } from "lib/utils/dirname"
|
|
3
|
-
|
|
4
|
-
function resolveRelativePath(importPath: string, cwd: string): string {
|
|
5
|
-
// Handle parent directory navigation
|
|
6
|
-
if (importPath.startsWith("../")) {
|
|
7
|
-
const parentDir = dirname(cwd)
|
|
8
|
-
return resolveRelativePath(importPath.slice(3), parentDir)
|
|
9
|
-
}
|
|
10
|
-
// Handle current directory
|
|
11
|
-
if (importPath.startsWith("./")) {
|
|
12
|
-
return resolveRelativePath(importPath.slice(2), cwd)
|
|
13
|
-
}
|
|
14
|
-
// Handle absolute path
|
|
15
|
-
if (importPath.startsWith("/")) {
|
|
16
|
-
return importPath.slice(1)
|
|
17
|
-
}
|
|
18
|
-
// Handle relative path
|
|
19
|
-
return `${cwd}/${importPath}`
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export const resolveFilePath = (
|
|
23
|
-
unknownFilePath: string,
|
|
24
|
-
fsMapOrAllFilePaths: Record<string, string> | string[],
|
|
25
|
-
cwd?: string,
|
|
26
|
-
) => {
|
|
27
|
-
// Handle parent directory navigation properly
|
|
28
|
-
const resolvedPath = cwd
|
|
29
|
-
? resolveRelativePath(unknownFilePath, cwd)
|
|
30
|
-
: unknownFilePath
|
|
31
|
-
|
|
32
|
-
const filePaths = new Set(
|
|
33
|
-
Array.isArray(fsMapOrAllFilePaths)
|
|
34
|
-
? fsMapOrAllFilePaths
|
|
35
|
-
: Object.keys(fsMapOrAllFilePaths),
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
if (filePaths.has(resolvedPath)) {
|
|
39
|
-
return resolvedPath
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const normalizedFilePathMap = new Map<string, string>()
|
|
43
|
-
for (const filePath of filePaths) {
|
|
44
|
-
normalizedFilePathMap.set(normalizeFilePath(filePath), filePath)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const normalizedResolvedPath = normalizeFilePath(resolvedPath)
|
|
48
|
-
|
|
49
|
-
if (normalizedFilePathMap.has(normalizedResolvedPath)) {
|
|
50
|
-
return normalizedFilePathMap.get(normalizedResolvedPath)!
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Search for file with a set of different extensions
|
|
54
|
-
const extension = ["tsx", "ts", "json", "js", "jsx", "obj", "gltf", "glb"]
|
|
55
|
-
for (const ext of extension) {
|
|
56
|
-
const possibleFilePath = `${normalizedResolvedPath}.${ext}`
|
|
57
|
-
if (normalizedFilePathMap.has(possibleFilePath)) {
|
|
58
|
-
return normalizedFilePathMap.get(possibleFilePath)!
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Check if it's an absolute import
|
|
63
|
-
if (!unknownFilePath.startsWith("./") && !unknownFilePath.startsWith("../")) {
|
|
64
|
-
const normalizedUnknownFilePath = normalizeFilePath(unknownFilePath)
|
|
65
|
-
if (normalizedFilePathMap.has(normalizedUnknownFilePath)) {
|
|
66
|
-
return normalizedFilePathMap.get(normalizedUnknownFilePath)!
|
|
67
|
-
}
|
|
68
|
-
for (const ext of extension) {
|
|
69
|
-
const possibleFilePath = `${normalizedUnknownFilePath}.${ext}`
|
|
70
|
-
if (normalizedFilePathMap.has(possibleFilePath)) {
|
|
71
|
-
return normalizedFilePathMap.get(possibleFilePath)!
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return null
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export const resolveFilePathOrThrow = (
|
|
80
|
-
unknownFilePath: string,
|
|
81
|
-
fsMapOrAllFilePaths: Record<string, string> | string[],
|
|
82
|
-
) => {
|
|
83
|
-
const resolvedFilePath = resolveFilePath(unknownFilePath, fsMapOrAllFilePaths)
|
|
84
|
-
if (!resolvedFilePath) {
|
|
85
|
-
throw new Error(
|
|
86
|
-
`File not found "${unknownFilePath}", available paths:\n\n${Object.keys(fsMapOrAllFilePaths).join(", ")}`,
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
return resolvedFilePath
|
|
90
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { CircuitRunner } from "./CircuitRunner"
|
|
2
|
-
|
|
3
|
-
export async function runTscircuitCode(
|
|
4
|
-
filesystemOrCodeString: Record<string, string> | string,
|
|
5
|
-
opts?: Omit<Parameters<CircuitRunner["executeWithFsMap"]>[0], "fsMap">,
|
|
6
|
-
) {
|
|
7
|
-
if (
|
|
8
|
-
typeof filesystemOrCodeString === "string" &&
|
|
9
|
-
!filesystemOrCodeString.includes("export")
|
|
10
|
-
) {
|
|
11
|
-
throw new Error(
|
|
12
|
-
`The "export" keyword wasn't found in your provided code. You need to export a component in your code, e.g.\n\nexport default () => (\n <resistor name="R1" resistance="1k" />\n)`,
|
|
13
|
-
)
|
|
14
|
-
}
|
|
15
|
-
const filesystem =
|
|
16
|
-
typeof filesystemOrCodeString === "string"
|
|
17
|
-
? { "user-code.tsx": filesystemOrCodeString }
|
|
18
|
-
: filesystemOrCodeString
|
|
19
|
-
|
|
20
|
-
const circuitRunner = new CircuitRunner()
|
|
21
|
-
|
|
22
|
-
await circuitRunner.executeWithFsMap({
|
|
23
|
-
fsMap: filesystem,
|
|
24
|
-
...opts,
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
await circuitRunner.renderUntilSettled()
|
|
28
|
-
|
|
29
|
-
return await circuitRunner.getCircuitJson()
|
|
30
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { runTscircuitCode } from "./runTscircuitCode"
|
|
2
|
-
|
|
3
|
-
export const runTscircuitModule = async (
|
|
4
|
-
module: string,
|
|
5
|
-
opts: { props?: Record<string, any>; exportName?: string } = {},
|
|
6
|
-
) => {
|
|
7
|
-
if (!module.startsWith("@")) {
|
|
8
|
-
module = `@tsci/${module.replace(/\//, ".")}`
|
|
9
|
-
}
|
|
10
|
-
const circuitJson = await runTscircuitCode(
|
|
11
|
-
{
|
|
12
|
-
// TODO handle exports that are not the default export by scanning
|
|
13
|
-
// otherExports for components
|
|
14
|
-
"user-code.tsx": `
|
|
15
|
-
import Module, * as otherExports from "${module}";
|
|
16
|
-
|
|
17
|
-
let exportName = "${opts.exportName ?? ""}"
|
|
18
|
-
|
|
19
|
-
if ((!Module || typeof Module !== "function") && !Boolean(exportName)) {
|
|
20
|
-
exportName = Object.keys(otherExports).filter(key => key[0] === key[0].toUpperCase() && typeof otherExports[key] === "function")[0]
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const defaultExport = exportName ? otherExports[exportName] : Module
|
|
24
|
-
|
|
25
|
-
if (!defaultExport) {
|
|
26
|
-
throw new Error(\`No export found for module "\${module}" (tried "\${exportName ?? "default"}")\`)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export default defaultExport;
|
|
30
|
-
`,
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
mainComponentProps: opts.props,
|
|
34
|
-
},
|
|
35
|
-
)
|
|
36
|
-
return circuitJson
|
|
37
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { resolveFilePathOrThrow } from "./resolveFilePath"
|
|
2
|
-
import Debug from "debug"
|
|
3
|
-
|
|
4
|
-
const debug = Debug("tsci:eval:setupDefaultEntrypointIfNeeded")
|
|
5
|
-
|
|
6
|
-
export const setupDefaultEntrypointIfNeeded = (opts: {
|
|
7
|
-
entrypoint?: string
|
|
8
|
-
fsMap: Record<string, string>
|
|
9
|
-
mainComponentPath?: string
|
|
10
|
-
mainComponentName?: string
|
|
11
|
-
name?: string
|
|
12
|
-
mainComponentProps?: Record<string, any>
|
|
13
|
-
}) => {
|
|
14
|
-
if (!opts.entrypoint && !opts.mainComponentPath) {
|
|
15
|
-
if ("index.tsx" in opts.fsMap) {
|
|
16
|
-
opts.mainComponentPath = "index.tsx"
|
|
17
|
-
} else if ("index.ts" in opts.fsMap) {
|
|
18
|
-
opts.mainComponentPath = "index.ts"
|
|
19
|
-
} else if (
|
|
20
|
-
Object.keys(opts.fsMap).filter((k) => k.endsWith(".tsx")).length === 1
|
|
21
|
-
) {
|
|
22
|
-
opts.mainComponentPath = Object.keys(opts.fsMap)[0]
|
|
23
|
-
} else if ("tscircuit.config.json" in opts.fsMap) {
|
|
24
|
-
const configContent = opts.fsMap["tscircuit.config.json"]
|
|
25
|
-
try {
|
|
26
|
-
const config = JSON.parse(configContent)
|
|
27
|
-
if (config.mainEntrypoint) {
|
|
28
|
-
opts.entrypoint = config.mainEntrypoint
|
|
29
|
-
}
|
|
30
|
-
} catch (e) {
|
|
31
|
-
console.warn("Failed to parse tscircuit.config.json:", e)
|
|
32
|
-
}
|
|
33
|
-
} else {
|
|
34
|
-
throw new Error(
|
|
35
|
-
"Either entrypoint or mainComponentPath must be provided (no index file, could not infer entrypoint)",
|
|
36
|
-
)
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (!opts.entrypoint && opts.mainComponentPath) {
|
|
41
|
-
opts.entrypoint = "entrypoint.tsx"
|
|
42
|
-
const mainComponentCode =
|
|
43
|
-
opts.fsMap[resolveFilePathOrThrow(opts.mainComponentPath, opts.fsMap)]
|
|
44
|
-
if (!mainComponentCode) {
|
|
45
|
-
throw new Error(
|
|
46
|
-
`Main component path "${opts.mainComponentPath}" not found in fsMap. Available paths: ${Object.keys(opts.fsMap).join(", ")}`,
|
|
47
|
-
)
|
|
48
|
-
}
|
|
49
|
-
opts.fsMap[opts.entrypoint] = `
|
|
50
|
-
import * as UserComponents from "./${opts.mainComponentPath}";
|
|
51
|
-
|
|
52
|
-
${
|
|
53
|
-
opts.mainComponentName
|
|
54
|
-
? `
|
|
55
|
-
const ComponentToRender = UserComponents["${opts.mainComponentName}"]
|
|
56
|
-
`
|
|
57
|
-
: `const ComponentToRender = UserComponents.default ||
|
|
58
|
-
Object.entries(UserComponents)
|
|
59
|
-
.filter(([name]) => !name.startsWith("use"))
|
|
60
|
-
.map(([_, component]) => component)[0] || (() => null);`
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
${
|
|
64
|
-
debug.enabled
|
|
65
|
-
? `
|
|
66
|
-
console.log({ UserComponents })
|
|
67
|
-
console.log("ComponentToRender " + ComponentToRender.toString(), { ComponentToRender })
|
|
68
|
-
`
|
|
69
|
-
: ""
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
circuit.add(
|
|
73
|
-
<ComponentToRender ${opts.mainComponentProps ? `{...${JSON.stringify(opts.mainComponentProps, null, 2)}}` : ""} />
|
|
74
|
-
);
|
|
75
|
-
`
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (!opts.name && opts.mainComponentName) {
|
|
79
|
-
opts.name = opts.mainComponentName
|
|
80
|
-
}
|
|
81
|
-
}
|
package/lib/shared/types.ts
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import type { AnyCircuitElement } from "circuit-json"
|
|
2
|
-
import type { RootCircuitEventName as CoreRootCircuitEventName } from "@tscircuit/core"
|
|
3
|
-
import type { PlatformConfig } from "@tscircuit/props"
|
|
4
|
-
|
|
5
|
-
export type RootCircuitEventName = CoreRootCircuitEventName | "debug:logOutput"
|
|
6
|
-
|
|
7
|
-
export interface CircuitRunnerConfiguration {
|
|
8
|
-
snippetsApiBaseUrl: string
|
|
9
|
-
cjsRegistryUrl: string
|
|
10
|
-
verbose?: boolean
|
|
11
|
-
platform?: PlatformConfig
|
|
12
|
-
projectConfig?: Partial<PlatformConfig>
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface WebWorkerConfiguration extends CircuitRunnerConfiguration {
|
|
16
|
-
evalVersion?: string
|
|
17
|
-
/**
|
|
18
|
-
* @deprecated, renamed to webWorkerBlobUrl
|
|
19
|
-
*/
|
|
20
|
-
webWorkerUrl?: URL | string
|
|
21
|
-
webWorkerBlobUrl?: URL | string
|
|
22
|
-
/**
|
|
23
|
-
* Enable fetch proxy to route worker fetch requests through parent thread.
|
|
24
|
-
* Useful when running in restricted environments (like ChatGPT) where
|
|
25
|
-
* worker fetch requests are blocked.
|
|
26
|
-
* Default: false
|
|
27
|
-
*/
|
|
28
|
-
enableFetchProxy?: boolean
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* API for the CircuitRunner class, used for eval'ing circuits
|
|
33
|
-
*/
|
|
34
|
-
export interface CircuitRunnerApi {
|
|
35
|
-
version: () => Promise<string>
|
|
36
|
-
execute: (
|
|
37
|
-
code: string,
|
|
38
|
-
opts?: {
|
|
39
|
-
name?: string
|
|
40
|
-
},
|
|
41
|
-
) => Promise<void>
|
|
42
|
-
executeComponent: (component: any) => Promise<void>
|
|
43
|
-
executeWithFsMap(opts: {
|
|
44
|
-
entrypoint?: string
|
|
45
|
-
fsMap: Record<string, string>
|
|
46
|
-
name?: string
|
|
47
|
-
}): Promise<void>
|
|
48
|
-
renderUntilSettled: () => Promise<void>
|
|
49
|
-
getCircuitJson: () => Promise<AnyCircuitElement[]>
|
|
50
|
-
setSnippetsApiBaseUrl: (baseUrl: string) => Promise<void>
|
|
51
|
-
setPlatformConfig: (platform: PlatformConfig) => Promise<void>
|
|
52
|
-
setProjectConfig: (project: Partial<PlatformConfig>) => Promise<void>
|
|
53
|
-
enableDebug: (namespace: string) => Promise<void>
|
|
54
|
-
on: (event: RootCircuitEventName, callback: (...args: any[]) => void) => void
|
|
55
|
-
clearEventListeners: () => void
|
|
56
|
-
kill: () => Promise<void>
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* @deprecated, use CircuitRunnerApi instead
|
|
61
|
-
*/
|
|
62
|
-
export type InternalWebWorkerApi = CircuitRunnerApi
|
|
63
|
-
|
|
64
|
-
export type CircuitWebWorker = {
|
|
65
|
-
execute: (code: string) => Promise<void>
|
|
66
|
-
executeComponent: (component: any) => Promise<void>
|
|
67
|
-
executeWithFsMap: (opts: {
|
|
68
|
-
entrypoint?: string
|
|
69
|
-
mainComponentPath?: string
|
|
70
|
-
fsMap: Record<string, string>
|
|
71
|
-
}) => Promise<void>
|
|
72
|
-
renderUntilSettled: () => Promise<void>
|
|
73
|
-
getCircuitJson: () => Promise<AnyCircuitElement[]>
|
|
74
|
-
on: (event: RootCircuitEventName, callback: (...args: any[]) => void) => void
|
|
75
|
-
clearEventListeners: () => void
|
|
76
|
-
enableDebug: (namespace: string) => Promise<void>
|
|
77
|
-
version: () => Promise<string>
|
|
78
|
-
kill: () => Promise<void>
|
|
79
|
-
}
|
package/lib/utils/dirname.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns the directory name of a path, similar to Node.js path.dirname
|
|
3
|
-
* Works on both Unix and Windows paths
|
|
4
|
-
* @param path The path to extract the directory from
|
|
5
|
-
* @returns The directory part of the path
|
|
6
|
-
*/
|
|
7
|
-
export function dirname(path: string): string {
|
|
8
|
-
if (!path) return "."
|
|
9
|
-
|
|
10
|
-
// Normalize path separators to forward slashes
|
|
11
|
-
const normalizedPath = path.replace(/\\/g, "/")
|
|
12
|
-
|
|
13
|
-
// Remove trailing slashes
|
|
14
|
-
const cleanPath = normalizedPath.replace(/\/+$/, "")
|
|
15
|
-
|
|
16
|
-
// If there are no slashes, return "."
|
|
17
|
-
if (cleanPath.indexOf("/") === -1) return "."
|
|
18
|
-
|
|
19
|
-
// Return everything up to the last slash
|
|
20
|
-
return cleanPath.substring(0, cleanPath.lastIndexOf("/")) || "/"
|
|
21
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export const getImportsFromCode = (code: string): string[] => {
|
|
2
|
-
// Match basic import patterns including combined default and namespace imports
|
|
3
|
-
const importRegex =
|
|
4
|
-
/^\s*import\s+(?:(?:[\w\s]+,\s*)?(?:\*\s+as\s+[\w\s]+|\{[\s\w,]+\}|\w+)\s+from\s*)?['"](.+?)['"]/gm
|
|
5
|
-
const imports: string[] = []
|
|
6
|
-
let match: RegExpExecArray | null
|
|
7
|
-
|
|
8
|
-
// biome-ignore lint/suspicious/noAssignInExpressions: <explanation>
|
|
9
|
-
while ((match = importRegex.exec(code)) !== null) {
|
|
10
|
-
imports.push(match[1])
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// Match re-exports
|
|
14
|
-
const reExportRegex =
|
|
15
|
-
/^\s*export\s+(?:\*|(?:\{[\s\w,]+\}))\s+from\s*['"](.+?)['"]/gm
|
|
16
|
-
let reExportMatch: RegExpExecArray | null
|
|
17
|
-
// biome-ignore lint/suspicious/noAssignInExpressions: <explanation>
|
|
18
|
-
while ((reExportMatch = reExportRegex.exec(code)) !== null) {
|
|
19
|
-
imports.push(reExportMatch[1])
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return imports
|
|
23
|
-
}
|
package/lib/utils/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./get-imports-from-code"
|