Skip to content

Commit a7a1680

Browse files
authored
Dynamically load the webworker blob (#83)
* dynamically load the webworker blob * dynamic loading of web worker * switch to jsdelivr
1 parent cfb30b1 commit a7a1680

File tree

4 files changed

+54
-15
lines changed

4 files changed

+54
-15
lines changed

lib/index.ts

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,37 @@ export const createCircuitWebWorker = async (
1818
)
1919
}
2020

21-
const rawWorker = new Worker(
22-
configuration.webWorkerUrl ??
23-
"https://unpkg.com/@tscircuit/eval-webworker/dist/webworker/index.js",
24-
{ type: "module" },
25-
)
26-
const webWorker = Comlink.wrap<InternalWebWorkerApi>(rawWorker)
21+
let workerBlobUrl =
22+
configuration.webWorkerBlobUrl ?? configuration.webWorkerUrl
23+
24+
if (!workerBlobUrl) {
25+
const cdnUrl =
26+
"https://cdn.jsdelivr.net/npm/@tscircuit/eval-webworker/dist/webworker/index.js"
27+
28+
const workerBlob = await fetch(cdnUrl).then((res) => res.blob())
29+
workerBlobUrl = URL.createObjectURL(workerBlob)
30+
}
31+
32+
const rawWorker = new Worker(workerBlobUrl, { type: "module" })
33+
const comlinkWorker = Comlink.wrap<InternalWebWorkerApi>(rawWorker)
2734

2835
if (configuration.snippetsApiBaseUrl) {
29-
await webWorker.setSnippetsApiBaseUrl(configuration.snippetsApiBaseUrl)
36+
await comlinkWorker.setSnippetsApiBaseUrl(configuration.snippetsApiBaseUrl)
3037
}
3138

3239
// Create a wrapper that handles events directly through circuit instance
3340
const wrapper: CircuitWebWorker = {
34-
clearEventListeners: webWorker.clearEventListeners.bind(webWorker),
35-
execute: webWorker.execute.bind(webWorker),
36-
executeWithFsMap: webWorker.executeWithFsMap.bind(webWorker),
37-
renderUntilSettled: webWorker.renderUntilSettled.bind(webWorker),
38-
getCircuitJson: webWorker.getCircuitJson.bind(webWorker),
41+
clearEventListeners: comlinkWorker.clearEventListeners.bind(comlinkWorker),
42+
execute: comlinkWorker.execute.bind(comlinkWorker),
43+
executeWithFsMap: comlinkWorker.executeWithFsMap.bind(comlinkWorker),
44+
renderUntilSettled: comlinkWorker.renderUntilSettled.bind(comlinkWorker),
45+
getCircuitJson: comlinkWorker.getCircuitJson.bind(comlinkWorker),
3946
on: (event: string, callback: (...args: any[]) => void) => {
4047
const proxiedCallback = Comlink.proxy(callback)
41-
webWorker.on(event, proxiedCallback)
48+
comlinkWorker.on(event, proxiedCallback)
4249
},
4350
kill: async () => {
44-
webWorker[Comlink.releaseProxy]()
51+
comlinkWorker[Comlink.releaseProxy]()
4552
rawWorker.terminate()
4653
},
4754
}

lib/shared/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import type { AnyCircuitElement } from "circuit-json"
33
export interface WebWorkerConfiguration {
44
snippetsApiBaseUrl: string
55
cjsRegistryUrl: string
6+
/**
7+
* @deprecated, renamed to webWorkerBlobUrl
8+
*/
69
webWorkerUrl?: URL | string
10+
webWorkerBlobUrl?: URL | string
711
verbose?: boolean
812
}
913

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"scripts": {
77
"build": "bun run build:lib && bun run build:webworker && bun run build:blob-url",
88
"build:lib": "tsup-node ./lib/index.ts --format esm --sourcemap inline --dts -d dist/lib",
9-
"build:webworker": "tsup ./webworker/index.ts --platform browser ./metadata.json --format esm --sourcemap inline -d dist/webworker",
9+
"build:webworker": "tsup ./webworker/index.ts --platform browser --format esm --sourcemap inline -d dist/webworker",
10+
"build:webworker:analyze": "tsup ./webworker/index.ts --platform browser --metafile ./metadata.json --format esm --sourcemap inline -d dist/webworker",
1011
"build:blob-url": "bun run ./scripts/build-worker-blob-url.ts",
1112
"format": "biome format --write .",
1213
"format:check": "biome format ."
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { createCircuitWebWorker } from "lib"
2+
import { expect, test } from "bun:test"
3+
4+
// TODO should skip b/c uses network
5+
test("example6-dynamic-load-blob-url", async () => {
6+
const circuitWebWorker = await createCircuitWebWorker({})
7+
8+
await circuitWebWorker.execute(`
9+
import { RedLed } from "@tsci/seveibar.red-led"
10+
11+
circuit.add(
12+
<board width="10mm" height="10mm">
13+
<RedLed name="LED1" />
14+
</board>
15+
)
16+
`)
17+
18+
await circuitWebWorker.renderUntilSettled()
19+
20+
const circuitJson = await circuitWebWorker.getCircuitJson()
21+
22+
expect(circuitJson).toBeDefined()
23+
24+
const led = circuitJson.find((el: any) => el.name === "LED1")
25+
expect(led).toBeDefined()
26+
expect(led?.type).toBe("source_component")
27+
})

0 commit comments

Comments
 (0)