@tscircuit/eval 0.0.311 → 0.0.312
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/eval/index.js +70 -14
- package/dist/lib/index.js +70 -14
- package/dist/webworker/entrypoint.js +262 -262
- package/package.json +1 -1
- package/tests/features/npm-import.test.tsx +42 -0
- package/webworker/import-eval-path.ts +5 -0
- package/webworker/import-npm-package.ts +69 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/eval",
|
|
3
3
|
"main": "dist/lib/index.js",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.312",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "bun run build:lib && bun run build:webworker && bun run build:blob-url && bun run build:runner && bun run build:worker-wrapper",
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { test, expect } from "bun:test"
|
|
2
|
+
import { runTscircuitCode } from "lib/runner"
|
|
3
|
+
|
|
4
|
+
test(
|
|
5
|
+
"should support importing various npm packages",
|
|
6
|
+
async () => {
|
|
7
|
+
const circuitJson = await runTscircuitCode(
|
|
8
|
+
`
|
|
9
|
+
import _ from "lodash"
|
|
10
|
+
import { v4 as uuidv4 } from "uuid"
|
|
11
|
+
import dayjs from "dayjs"
|
|
12
|
+
|
|
13
|
+
export default () => {
|
|
14
|
+
// Test lodash
|
|
15
|
+
if (!_.isEqual({ a: 1 }, { a: 1 })) {
|
|
16
|
+
throw new Error("_.isEqual failed")
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Test uuid
|
|
20
|
+
const uuid = uuidv4()
|
|
21
|
+
if (typeof uuid !== "string" || uuid.length < 36) {
|
|
22
|
+
throw new Error("uuid.v4 failed to generate a valid uuid")
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Test dayjs
|
|
26
|
+
if (!dayjs().isValid()) {
|
|
27
|
+
throw new Error("dayjs().isValid() failed")
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return <resistor name="R1" resistance="1k" />
|
|
31
|
+
}
|
|
32
|
+
`,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
const resistor = circuitJson.find(
|
|
36
|
+
(element) => element.type === "source_component" && element.name === "R1",
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
expect(resistor).toBeDefined()
|
|
40
|
+
},
|
|
41
|
+
{ timeout: 15000 },
|
|
42
|
+
)
|
|
@@ -6,6 +6,7 @@ import { importSnippet } from "./import-snippet"
|
|
|
6
6
|
import { resolveFilePath } from "lib/runner/resolveFilePath"
|
|
7
7
|
import { resolveNodeModule } from "lib/utils/resolve-node-module"
|
|
8
8
|
import { importNodeModule } from "./import-node-module"
|
|
9
|
+
import { importNpmPackage } from "./import-npm-package"
|
|
9
10
|
import Debug from "debug"
|
|
10
11
|
|
|
11
12
|
const debug = Debug("tsci:eval:import-eval-path")
|
|
@@ -59,6 +60,10 @@ export async function importEvalPath(
|
|
|
59
60
|
return importSnippet(importName, ctx, depth)
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
if (!importName.startsWith(".") && !importName.startsWith("/")) {
|
|
64
|
+
return importNpmPackage(importName, ctx)
|
|
65
|
+
}
|
|
66
|
+
|
|
62
67
|
throw new Error(
|
|
63
68
|
`Unresolved import "${importName}" ${opts.cwd ? `from directory "${opts.cwd}"` : ""}`,
|
|
64
69
|
)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { evalCompiledJs } from "./eval-compiled-js"
|
|
2
|
+
import type { ExecutionContext } from "./execution-context"
|
|
3
|
+
import * as Babel from "@babel/standalone"
|
|
4
|
+
import { dirname } from "lib/utils/dirname"
|
|
5
|
+
import Debug from "debug"
|
|
6
|
+
|
|
7
|
+
const debug = Debug("tsci:eval:import-npm-package")
|
|
8
|
+
|
|
9
|
+
function extractPackagePathFromJSDelivr(url: string) {
|
|
10
|
+
const prefix = "https://cdn.jsdelivr.net/npm/"
|
|
11
|
+
if (url.startsWith(prefix)) {
|
|
12
|
+
return url.substring(prefix.length).replace(/\/\+esm$/, "")
|
|
13
|
+
}
|
|
14
|
+
return url
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function importNpmPackage(
|
|
18
|
+
importName: string,
|
|
19
|
+
ctx: ExecutionContext,
|
|
20
|
+
) {
|
|
21
|
+
debug(`importing npm package: ${importName}`)
|
|
22
|
+
const { preSuppliedImports } = ctx
|
|
23
|
+
|
|
24
|
+
if (preSuppliedImports[importName]) return
|
|
25
|
+
|
|
26
|
+
const npmCdnUrl = `https://cdn.jsdelivr.net/npm/${importName}/+esm`
|
|
27
|
+
|
|
28
|
+
let finalUrl: string | undefined
|
|
29
|
+
const { content, error } = await globalThis
|
|
30
|
+
.fetch(npmCdnUrl)
|
|
31
|
+
.then(async (res) => {
|
|
32
|
+
finalUrl = res.url
|
|
33
|
+
if (!res.ok)
|
|
34
|
+
throw new Error(
|
|
35
|
+
`Could not fetch "${importName}" from jsdelivr: ${res.statusText}`,
|
|
36
|
+
)
|
|
37
|
+
return { content: await res.text(), error: null }
|
|
38
|
+
})
|
|
39
|
+
.catch((e) => ({ error: e, content: null }))
|
|
40
|
+
|
|
41
|
+
if (error) {
|
|
42
|
+
console.error("Error fetching npm import", importName, error)
|
|
43
|
+
throw error
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const transpiled = Babel.transform(content!, {
|
|
47
|
+
presets: ["react", "env"],
|
|
48
|
+
plugins: ["transform-modules-commonjs"],
|
|
49
|
+
filename: importName,
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
if (!transpiled.code) {
|
|
53
|
+
throw new Error(`Babel transpilation failed for ${importName}`)
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
const finalImportName = extractPackagePathFromJSDelivr(finalUrl!)
|
|
57
|
+
const cwd = dirname(finalImportName)
|
|
58
|
+
const exports = evalCompiledJs(
|
|
59
|
+
transpiled.code!,
|
|
60
|
+
preSuppliedImports,
|
|
61
|
+
cwd,
|
|
62
|
+
).exports
|
|
63
|
+
preSuppliedImports[importName] = exports
|
|
64
|
+
preSuppliedImports[finalImportName] = exports
|
|
65
|
+
preSuppliedImports[finalUrl!] = exports
|
|
66
|
+
} catch (e: any) {
|
|
67
|
+
throw new Error(`Eval npm package error for "${importName}": ${e.message}`)
|
|
68
|
+
}
|
|
69
|
+
}
|