@tscircuit/eval 0.0.286 → 0.0.288
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.d.ts +7 -0
- package/dist/eval/index.js +6 -6
- package/dist/lib/index.d.ts +7 -0
- package/dist/lib/index.js +47 -7
- package/dist/webworker/entrypoint.js +286 -290
- package/dist/worker.d.ts +7 -0
- package/dist/worker.js +42 -2
- package/lib/runner/setupDefaultEntrypointIfNeeded.ts +4 -3
- package/lib/shared/types.ts +7 -0
- package/lib/worker.ts +47 -1
- package/package.json +1 -1
- package/tests/example3-encoded-url.test.tsx +1 -1
- package/tests/fetch-override.test.ts +46 -0
- package/tests/fetch-proxy-validation.test.ts +97 -0
- package/tests/prioritize-default-export.test.tsx +27 -0
- package/webworker/entrypoint.ts +6 -1
- package/webworker/fetchProxy.ts +83 -0
- package/webworker/import-snippet.ts +2 -4
package/dist/worker.d.ts
CHANGED
|
@@ -17,6 +17,13 @@ interface WebWorkerConfiguration extends CircuitRunnerConfiguration {
|
|
|
17
17
|
*/
|
|
18
18
|
webWorkerUrl?: URL | string;
|
|
19
19
|
webWorkerBlobUrl?: URL | string;
|
|
20
|
+
/**
|
|
21
|
+
* Enable fetch proxy to route worker fetch requests through parent thread.
|
|
22
|
+
* Useful when running in restricted environments (like ChatGPT) where
|
|
23
|
+
* worker fetch requests are blocked.
|
|
24
|
+
* Default: false
|
|
25
|
+
*/
|
|
26
|
+
enableFetchProxy?: boolean;
|
|
20
27
|
}
|
|
21
28
|
type CircuitWebWorker = {
|
|
22
29
|
execute: (code: string) => Promise<void>;
|
package/dist/worker.js
CHANGED
|
@@ -47,7 +47,7 @@ var createCircuitWebWorker = async (configuration) => {
|
|
|
47
47
|
let workerBlobUrl = configuration.webWorkerBlobUrl ?? configuration.webWorkerUrl;
|
|
48
48
|
if (!workerBlobUrl) {
|
|
49
49
|
const cdnUrl = `https://cdn.jsdelivr.net/npm/@tscircuit/eval@${configuration.evalVersion ?? "latest"}/dist/webworker/entrypoint.js`;
|
|
50
|
-
const workerBlob = await fetch(cdnUrl).then((res) => res.blob());
|
|
50
|
+
const workerBlob = await globalThis.fetch(cdnUrl).then((res) => res.blob());
|
|
51
51
|
workerBlobUrl = URL.createObjectURL(workerBlob);
|
|
52
52
|
}
|
|
53
53
|
const rawWorker = new Worker(workerBlobUrl, { type: "module" });
|
|
@@ -66,11 +66,50 @@ var createCircuitWebWorker = async (configuration) => {
|
|
|
66
66
|
console.log("[Worker] Message in worker", event);
|
|
67
67
|
};
|
|
68
68
|
rawWorker.addEventListener("message", earlyMessageHandler);
|
|
69
|
+
rawWorker.addEventListener("message", async (event) => {
|
|
70
|
+
const data = event.data;
|
|
71
|
+
if (data?.type !== "worker_fetch") return;
|
|
72
|
+
try {
|
|
73
|
+
const response = await globalThis.fetch(data.input, data.init);
|
|
74
|
+
const body = await response.text();
|
|
75
|
+
rawWorker.postMessage({
|
|
76
|
+
type: "worker_fetch_result",
|
|
77
|
+
requestId: data.requestId,
|
|
78
|
+
success: true,
|
|
79
|
+
response: {
|
|
80
|
+
body,
|
|
81
|
+
status: response.status,
|
|
82
|
+
statusText: response.statusText,
|
|
83
|
+
headers: (() => {
|
|
84
|
+
const obj = {};
|
|
85
|
+
response.headers.forEach((value, key) => {
|
|
86
|
+
obj[key] = value;
|
|
87
|
+
});
|
|
88
|
+
return obj;
|
|
89
|
+
})()
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
} catch (err) {
|
|
93
|
+
rawWorker.postMessage({
|
|
94
|
+
type: "worker_fetch_result",
|
|
95
|
+
requestId: data.requestId,
|
|
96
|
+
success: false,
|
|
97
|
+
error: {
|
|
98
|
+
name: err.name,
|
|
99
|
+
message: err.message,
|
|
100
|
+
stack: err.stack
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
});
|
|
69
105
|
if (workerInitError) {
|
|
70
106
|
throw workerInitError;
|
|
71
107
|
}
|
|
72
108
|
const comlinkWorker = Comlink.wrap(rawWorker);
|
|
73
109
|
rawWorker.removeEventListener("message", earlyMessageHandler);
|
|
110
|
+
if (configuration.enableFetchProxy) {
|
|
111
|
+
rawWorker.postMessage({ type: "override_global_fetch" });
|
|
112
|
+
}
|
|
74
113
|
if (configuration.snippetsApiBaseUrl) {
|
|
75
114
|
await comlinkWorker.setSnippetsApiBaseUrl(configuration.snippetsApiBaseUrl);
|
|
76
115
|
}
|
|
@@ -110,6 +149,7 @@ var createCircuitWebWorker = async (configuration) => {
|
|
|
110
149
|
}
|
|
111
150
|
}
|
|
112
151
|
};
|
|
152
|
+
wrapper.__rawWorker = rawWorker;
|
|
113
153
|
globalThis.TSCIRCUIT_GLOBAL_CIRCUIT_WORKER = wrapper;
|
|
114
154
|
return wrapper;
|
|
115
155
|
};
|
|
@@ -117,4 +157,4 @@ export {
|
|
|
117
157
|
createCircuitWebWorker,
|
|
118
158
|
getImportsFromCode
|
|
119
159
|
};
|
|
120
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vbGliL3dvcmtlci50cyIsICIuLi9saWIvdXRpbHMvZ2V0LWltcG9ydHMtZnJvbS1jb2RlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgKiBhcyBDb21saW5rIGZyb20gXCJjb21saW5rXCJcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWxzL2luZGV4XCJcbmltcG9ydCB0eXBlIHtcbiAgSW50ZXJuYWxXZWJXb3JrZXJBcGksXG4gIFdlYldvcmtlckNvbmZpZ3VyYXRpb24sXG4gIENpcmN1aXRXZWJXb3JrZXIsXG59IGZyb20gXCIuL3NoYXJlZC90eXBlc1wiXG5pbXBvcnQgdHlwZSB7IFJvb3RDaXJjdWl0RXZlbnROYW1lIH0gZnJvbSBcIkB0c2NpcmN1aXQvY29yZVwiXG5cbmV4cG9ydCB0eXBlIHsgQ2lyY3VpdFdlYldvcmtlciwgV2ViV29ya2VyQ29uZmlndXJhdGlvbiB9XG5cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgaW50ZXJmYWNlIFdpbmRvdyB7XG4gICAgVFNDSVJDVUlUX0dMT0JBTF9DSVJDVUlUX1dPUktFUjogQ2lyY3VpdFdlYldvcmtlciB8IHVuZGVmaW5lZFxuICB9XG4gIHZhciBUU0NJUkNVSVRfR0xPQkFMX0NJUkNVSVRfV09SS0VSOiBDaXJjdWl0V2ViV29ya2VyIHwgdW5kZWZpbmVkXG59XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVDaXJjdWl0V2ViV29ya2VyID0gYXN5bmMgKFxuICBjb25maWd1cmF0aW9uOiBQYXJ0aWFsPFdlYldvcmtlckNvbmZpZ3VyYXRpb24+LFxuKTogUHJvbWlzZTxDaXJjdWl0V2ViV29ya2VyPiA9PiB7XG4gIC8vIEtpbGwgZXhpc3RpbmcgZ2xvYmFsIHdvcmtlciBpbnN0YW5jZSBpZiBwcmVzZW50XG4gIGNvbnN0IGV4aXN0aW5nV29ya2VyID0gZ2xvYmFsVGhpcy5UU0NJUkNVSVRfR0xPQkFMX0NJUkNVSVRfV09SS0VSXG4gIGlmIChleGlzdGluZ1dvcmtlciAmJiB0eXBlb2YgZXhpc3RpbmdXb3JrZXIua2lsbCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgaWYgKGNvbmZpZ3VyYXRpb24udmVyYm9zZSkge1xuICAgICAgY29uc29sZS5sb2coXCJbV29ya2VyXSBLaWxsaW5nIHByZXZpb3VzIGdsb2JhbCB3b3JrZXIgaW5zdGFuY2UuLi5cIilcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGV4aXN0aW5nV29ya2VyLmtpbGwoKVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChjb25maWd1cmF0aW9uLnZlcmJvc2UpIHtcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgIFwiW1dvcmtlcl0gRXJyb3Iga2lsbGluZyBwcmV2aW91cyBnbG9iYWwgd29ya2VyIGluc3RhbmNlOlwiLFxuICAgICAgICAgIGUsXG4gICAgICAgIClcbiAgICAgIH1cbiAgICAgIC8vIEVuc3VyZSB0aGUga2V5IGlzIGNsZWFyZWQgZXZlbiBpZiBraWxsIHRocm93cyBhbiBlcnJvclxuICAgICAgaWYgKGdsb2JhbFRoaXMuVFNDSVJDVUlUX0dMT0JBTF9DSVJDVUlUX1dPUktFUiA9PT0gZXhpc3RpbmdXb3JrZXIpIHtcbiAgICAgICAgZ2xvYmFsVGhpcy5UU0NJUkNVSVRfR0xPQkFMX0NJUkNVSVRfV09SS0VSID0gdW5kZWZpbmVkXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGNvbmZpZ3VyYXRpb24udmVyYm9zZSkge1xuICAgIGNvbnNvbGUubG9nKFxuICAgICAgXCJbV29ya2VyXSBDcmVhdGluZyBjaXJjdWl0IHdlYiB3b3JrZXIgd2l0aCBjb25maWc6XCIsXG4gICAgICBjb25maWd1cmF0aW9uLFxuICAgIClcbiAgfVxuXG4gIGxldCB3b3JrZXJCbG9iVXJsID1cbiAgICBjb25maWd1cmF0aW9uLndlYldvcmtlckJsb2JVcmwgPz8gY29uZmlndXJhdGlvbi53ZWJXb3JrZXJVcmxcblxuICBpZiAoIXdvcmtlckJsb2JVcmwpIHtcbiAgICBjb25zdCBjZG5VcmwgPSBgaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9AdHNjaXJjdWl0L2V2YWxAJHtjb25maWd1cmF0aW9uLmV2YWxWZXJzaW9uID8/IFwibGF0ZXN0XCJ9L2Rpc3Qvd2Vid29ya2VyL2VudHJ5cG9pbnQuanNgXG5cbiAgICBjb25zdCB3b3JrZXJCbG9iID0gYXdhaXQgZmV0Y2goY2RuVXJsKS50aGVuKChyZXMpID0+IHJlcy5ibG9iKCkpXG4gICAgd29ya2VyQmxvYlVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwod29ya2VyQmxvYilcbiAgfVxuXG4gIGNvbnN0IHJhd1dvcmtlciA9IG5ldyBXb3JrZXIod29ya2VyQmxvYlVybCwgeyB0eXBlOiBcIm1vZHVsZVwiIH0pXG4gIGxldCB3b3JrZXJJbml0RXJyb3I6IGFueVxuICByYXdXb3JrZXIuYWRkRXZlbnRMaXN0ZW5lcihcImVycm9yXCIsIChldmVudCkgPT4ge1xuICAgIGNvbnNvbGUuZXJyb3IoXCJbV29ya2VyXSBFcnJvciBpbiB3b3JrZXJcIiwgZXZlbnQpXG4gICAgd29ya2VySW5pdEVycm9yID0gZXZlbnRcbiAgfSlcbiAgcmF3V29ya2VyLmFkZEV2ZW50TGlzdGVuZXIoXCJ1bmhhbmRsZWRyZWplY3Rpb25cIiwgKGV2ZW50KSA9PiB7XG4gICAgY29uc29sZS5lcnJvcihcIltXb3JrZXJdIFVuaGFuZGxlZCByZWplY3Rpb24gaW4gd29ya2VyXCIsIGV2ZW50KVxuICB9KVxuICByYXdXb3JrZXIuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VlcnJvclwiLCAoZXZlbnQpID0+IHtcbiAgICBjb25zb2xlLmVycm9yKFwiW1dvcmtlcl0gTWVzc2FnZSBlcnJvciBpbiB3b3JrZXJcIiwgZXZlbnQpXG4gIH0pXG4gIGNvbnN0IGVhcmx5TWVzc2FnZUhhbmRsZXIgPSAoZXZlbnQ6IE1lc3NhZ2VFdmVudCkgPT4ge1xuICAgIGNvbnNvbGUubG9nKFwiW1dvcmtlcl0gTWVzc2FnZSBpbiB3b3JrZXJcIiwgZXZlbnQpXG4gIH1cbiAgcmF3V29ya2VyLmFkZEV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsIGVhcmx5TWVzc2FnZUhhbmRsZXIpXG5cbiAgaWYgKHdvcmtlckluaXRFcnJvcikge1xuICAgIHRocm93IHdvcmtlckluaXRFcnJvclxuICB9XG5cbiAgY29uc3QgY29tbGlua1dvcmtlciA9IENvbWxpbmsud3JhcDxJbnRlcm5hbFdlYldvcmtlckFwaT4ocmF3V29ya2VyKVxuXG4gIHJhd1dvcmtlci5yZW1vdmVFdmVudExpc3RlbmVyKFwibWVzc2FnZVwiLCBlYXJseU1lc3NhZ2VIYW5kbGVyKVxuXG4gIGlmIChjb25maWd1cmF0aW9uLnNuaXBwZXRzQXBpQmFzZVVybCkge1xuICAgIGF3YWl0IGNvbWxpbmtXb3JrZXIuc2V0U25pcHBldHNBcGlCYXNlVXJsKGNvbmZpZ3VyYXRpb24uc25pcHBldHNBcGlCYXNlVXJsKVxuICB9XG4gIGlmIChjb25maWd1cmF0aW9uLnBsYXRmb3JtKSB7XG4gICAgYXdhaXQgY29tbGlua1dvcmtlci5zZXRQbGF0Zm9ybUNvbmZpZyhjb25maWd1cmF0aW9uLnBsYXRmb3JtKVxuICB9XG5cbiAgbGV0IGlzVGVybWluYXRlZCA9IGZhbHNlXG5cbiAgLy8gQ3JlYXRlIGEgd3JhcHBlciB0aGF0IGhhbmRsZXMgZXZlbnRzIGRpcmVjdGx5IHRocm91Z2ggY2lyY3VpdCBpbnN0YW5jZVxuICBjb25zdCB3cmFwcGVyOiBDaXJjdWl0V2ViV29ya2VyID0ge1xuICAgIGNsZWFyRXZlbnRMaXN0ZW5lcnM6IGNvbWxpbmtXb3JrZXIuY2xlYXJFdmVudExpc3RlbmVycy5iaW5kKGNvbWxpbmtXb3JrZXIpLFxuICAgIHZlcnNpb246IGNvbWxpbmtXb3JrZXIudmVyc2lvbi5iaW5kKGNvbWxpbmtXb3JrZXIpLFxuICAgIGV4ZWN1dGU6IGFzeW5jICguLi5hcmdzKSA9PiB7XG4gICAgICBpZiAoaXNUZXJtaW5hdGVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNpcmN1aXRXZWJXb3JrZXIgd2FzIHRlcm1pbmF0ZWQsIGNhbid0IGV4ZWN1dGVcIilcbiAgICAgIH1cbiAgICAgIHJldHVybiBjb21saW5rV29ya2VyLmV4ZWN1dGUuYmluZChjb21saW5rV29ya2VyKSguLi5hcmdzKVxuICAgIH0sXG4gICAgZXhlY3V0ZVdpdGhGc01hcDogYXN5bmMgKC4uLmFyZ3MpID0+IHtcbiAgICAgIGlmIChpc1Rlcm1pbmF0ZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIFwiQ2lyY3VpdFdlYldvcmtlciB3YXMgdGVybWluYXRlZCwgY2FuJ3QgZXhlY3V0ZVdpdGhGc01hcFwiLFxuICAgICAgICApXG4gICAgICB9XG4gICAgICByZXR1cm4gY29tbGlua1dvcmtlci5leGVjdXRlV2l0aEZzTWFwLmJpbmQoY29tbGlua1dvcmtlcikoLi4uYXJncylcbiAgICB9LFxuICAgIHJlbmRlclVudGlsU2V0dGxlZDogY29tbGlua1dvcmtlci5yZW5kZXJVbnRpbFNldHRsZWQuYmluZChjb21saW5rV29ya2VyKSxcbiAgICBnZXRDaXJjdWl0SnNvbjogY29tbGlua1dvcmtlci5nZXRDaXJjdWl0SnNvbi5iaW5kKGNvbWxpbmtXb3JrZXIpLFxuICAgIG9uOiAoZXZlbnQ6IHN0cmluZywgY2FsbGJhY2s6ICguLi5hcmdzOiBhbnlbXSkgPT4gdm9pZCkgPT4ge1xuICAgICAgY29uc3QgcHJveGllZENhbGxiYWNrID0gQ29tbGluay5wcm94eShjYWxsYmFjaylcbiAgICAgIGNvbWxpbmtXb3JrZXIub24oZXZlbnQgYXMgUm9vdENpcmN1aXRFdmVudE5hbWUsIHByb3hpZWRDYWxsYmFjaylcbiAgICB9LFxuICAgIGtpbGw6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbWxpbmtXb3JrZXJbQ29tbGluay5yZWxlYXNlUHJveHldKClcbiAgICAgIHJhd1dvcmtlci50ZXJtaW5hdGUoKVxuICAgICAgaXNUZXJtaW5hdGVkID0gdHJ1ZVxuICAgICAgaWYgKGdsb2JhbFRoaXMuVFNDSVJDVUlUX0dMT0JBTF9DSVJDVUlUX1dPUktFUiA9PT0gd3JhcHBlcikge1xuICAgICAgICBnbG9iYWxUaGlzLlRTQ0lSQ1VJVF9HTE9CQUxfQ0lSQ1VJVF9XT1JLRVIgPSB1bmRlZmluZWRcbiAgICAgIH1cbiAgICB9LFxuICB9XG4gIGdsb2JhbFRoaXMuVFNDSVJDVUlUX0dMT0JBTF9DSVJDVUlUX1dPUktFUiA9IHdyYXBwZXJcbiAgcmV0dXJuIHdyYXBwZXJcbn1cbiIsICJleHBvcnQgY29uc3QgZ2V0SW1wb3J0c0Zyb21Db2RlID0gKGNvZGU6IHN0cmluZyk6IHN0cmluZ1tdID0+IHtcbiAgLy8gTWF0Y2ggYmFzaWMgaW1wb3J0IHBhdHRlcm5zIGluY2x1ZGluZyBjb21iaW5lZCBkZWZhdWx0IGFuZCBuYW1lc3BhY2UgaW1wb3J0c1xuICBjb25zdCBpbXBvcnRSZWdleCA9XG4gICAgL15cXHMqaW1wb3J0XFxzKyg/Oig/OltcXHdcXHNdKyxcXHMqKT8oPzpcXCpcXHMrYXNcXHMrW1xcd1xcc10rfFxce1tcXHNcXHcsXStcXH18XFx3KylcXHMrZnJvbVxccyspP1snXCJdKC4rPylbJ1wiXS9nbVxuICBjb25zdCBpbXBvcnRzOiBzdHJpbmdbXSA9IFtdXG4gIGxldCBtYXRjaDogUmVnRXhwRXhlY0FycmF5IHwgbnVsbFxuXG4gIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9Bc3NpZ25JbkV4cHJlc3Npb25zOiA8ZXhwbGFuYXRpb24+XG4gIHdoaWxlICgobWF0Y2ggPSBpbXBvcnRSZWdleC5leGVjKGNvZGUpKSAhPT0gbnVsbCkge1xuICAgIGltcG9ydHMucHVzaChtYXRjaFsxXSlcbiAgfVxuXG4gIC8vIE1hdGNoIHJlLWV4cG9ydHNcbiAgY29uc3QgcmVFeHBvcnRSZWdleCA9XG4gICAgL15cXHMqZXhwb3J0XFxzKyg/OlxcKnwoPzpcXHtbXFxzXFx3LF0rXFx9KSlcXHMrZnJvbVxccytbJ1wiXSguKz8pWydcIl0vZ21cbiAgbGV0IHJlRXhwb3J0TWF0Y2g6IFJlZ0V4cEV4ZWNBcnJheSB8IG51bGxcbiAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0Fzc2lnbkluRXhwcmVzc2lvbnM6IDxleHBsYW5hdGlvbj5cbiAgd2hpbGUgKChyZUV4cG9ydE1hdGNoID0gcmVFeHBvcnRSZWdleC5leGVjKGNvZGUpKSAhPT0gbnVsbCkge1xuICAgIGltcG9ydHMucHVzaChyZUV4cG9ydE1hdGNoWzFdKVxuICB9XG5cbiAgcmV0dXJuIGltcG9ydHNcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBQSxZQUFZLGFBQWE7OztBQ0FsQixJQUFNLHFCQUFxQixDQUFDLFNBQTJCO0FBRTVELFFBQU0sY0FDSjtBQUNGLFFBQU0sVUFBb0IsQ0FBQztBQUMzQixNQUFJO0FBR0osVUFBUSxRQUFRLFlBQVksS0FBSyxJQUFJLE9BQU8sTUFBTTtBQUNoRCxZQUFRLEtBQUssTUFBTSxDQUFDLENBQUM7QUFBQSxFQUN2QjtBQUdBLFFBQU0sZ0JBQ0o7QUFDRixNQUFJO0FBRUosVUFBUSxnQkFBZ0IsY0FBYyxLQUFLLElBQUksT0FBTyxNQUFNO0FBQzFELFlBQVEsS0FBSyxjQUFjLENBQUMsQ0FBQztBQUFBLEVBQy9CO0FBRUEsU0FBTztBQUNUOzs7QURKTyxJQUFNLHlCQUF5QixPQUNwQyxrQkFDOEI7QUFFOUIsUUFBTSxpQkFBaUIsV0FBVztBQUNsQyxNQUFJLGtCQUFrQixPQUFPLGVBQWUsU0FBUyxZQUFZO0FBQy9ELFFBQUksY0FBYyxTQUFTO0FBQ3pCLGNBQVEsSUFBSSxxREFBcUQ7QUFBQSxJQUNuRTtBQUNBLFFBQUk7QUFDRixZQUFNLGVBQWUsS0FBSztBQUFBLElBQzVCLFNBQVMsR0FBRztBQUNWLFVBQUksY0FBYyxTQUFTO0FBQ3pCLGdCQUFRO0FBQUEsVUFDTjtBQUFBLFVBQ0E7QUFBQSxRQUNGO0FBQUEsTUFDRjtBQUVBLFVBQUksV0FBVyxvQ0FBb0MsZ0JBQWdCO0FBQ2pFLG1CQUFXLGtDQUFrQztBQUFBLE1BQy9DO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFFQSxNQUFJLGNBQWMsU0FBUztBQUN6QixZQUFRO0FBQUEsTUFDTjtBQUFBLE1B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
|
|
160
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vbGliL3dvcmtlci50cyIsICIuLi9saWIvdXRpbHMvZ2V0LWltcG9ydHMtZnJvbS1jb2RlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgKiBhcyBDb21saW5rIGZyb20gXCJjb21saW5rXCJcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWxzL2luZGV4XCJcbmltcG9ydCB0eXBlIHtcbiAgSW50ZXJuYWxXZWJXb3JrZXJBcGksXG4gIFdlYldvcmtlckNvbmZpZ3VyYXRpb24sXG4gIENpcmN1aXRXZWJXb3JrZXIsXG59IGZyb20gXCIuL3NoYXJlZC90eXBlc1wiXG5pbXBvcnQgdHlwZSB7IFJvb3RDaXJjdWl0RXZlbnROYW1lIH0gZnJvbSBcIkB0c2NpcmN1aXQvY29yZVwiXG5cbmV4cG9ydCB0eXBlIHsgQ2lyY3VpdFdlYldvcmtlciwgV2ViV29ya2VyQ29uZmlndXJhdGlvbiB9XG5cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgaW50ZXJmYWNlIFdpbmRvdyB7XG4gICAgVFNDSVJDVUlUX0dMT0JBTF9DSVJDVUlUX1dPUktFUjogQ2lyY3VpdFdlYldvcmtlciB8IHVuZGVmaW5lZFxuICB9XG4gIHZhciBUU0NJUkNVSVRfR0xPQkFMX0NJUkNVSVRfV09SS0VSOiBDaXJjdWl0V2ViV29ya2VyIHwgdW5kZWZpbmVkXG59XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVDaXJjdWl0V2ViV29ya2VyID0gYXN5bmMgKFxuICBjb25maWd1cmF0aW9uOiBQYXJ0aWFsPFdlYldvcmtlckNvbmZpZ3VyYXRpb24+LFxuKTogUHJvbWlzZTxDaXJjdWl0V2ViV29ya2VyPiA9PiB7XG4gIC8vIEtpbGwgZXhpc3RpbmcgZ2xvYmFsIHdvcmtlciBpbnN0YW5jZSBpZiBwcmVzZW50XG4gIGNvbnN0IGV4aXN0aW5nV29ya2VyID0gZ2xvYmFsVGhpcy5UU0NJUkNVSVRfR0xPQkFMX0NJUkNVSVRfV09SS0VSXG4gIGlmIChleGlzdGluZ1dvcmtlciAmJiB0eXBlb2YgZXhpc3RpbmdXb3JrZXIua2lsbCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgaWYgKGNvbmZpZ3VyYXRpb24udmVyYm9zZSkge1xuICAgICAgY29uc29sZS5sb2coXCJbV29ya2VyXSBLaWxsaW5nIHByZXZpb3VzIGdsb2JhbCB3b3JrZXIgaW5zdGFuY2UuLi5cIilcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGV4aXN0aW5nV29ya2VyLmtpbGwoKVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChjb25maWd1cmF0aW9uLnZlcmJvc2UpIHtcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgIFwiW1dvcmtlcl0gRXJyb3Iga2lsbGluZyBwcmV2aW91cyBnbG9iYWwgd29ya2VyIGluc3RhbmNlOlwiLFxuICAgICAgICAgIGUsXG4gICAgICAgIClcbiAgICAgIH1cbiAgICAgIC8vIEVuc3VyZSB0aGUga2V5IGlzIGNsZWFyZWQgZXZlbiBpZiBraWxsIHRocm93cyBhbiBlcnJvclxuICAgICAgaWYgKGdsb2JhbFRoaXMuVFNDSVJDVUlUX0dMT0JBTF9DSVJDVUlUX1dPUktFUiA9PT0gZXhpc3RpbmdXb3JrZXIpIHtcbiAgICAgICAgZ2xvYmFsVGhpcy5UU0NJUkNVSVRfR0xPQkFMX0NJUkNVSVRfV09SS0VSID0gdW5kZWZpbmVkXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGNvbmZpZ3VyYXRpb24udmVyYm9zZSkge1xuICAgIGNvbnNvbGUubG9nKFxuICAgICAgXCJbV29ya2VyXSBDcmVhdGluZyBjaXJjdWl0IHdlYiB3b3JrZXIgd2l0aCBjb25maWc6XCIsXG4gICAgICBjb25maWd1cmF0aW9uLFxuICAgIClcbiAgfVxuXG4gIGxldCB3b3JrZXJCbG9iVXJsID1cbiAgICBjb25maWd1cmF0aW9uLndlYldvcmtlckJsb2JVcmwgPz8gY29uZmlndXJhdGlvbi53ZWJXb3JrZXJVcmxcblxuICBpZiAoIXdvcmtlckJsb2JVcmwpIHtcbiAgICBjb25zdCBjZG5VcmwgPSBgaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9AdHNjaXJjdWl0L2V2YWxAJHtjb25maWd1cmF0aW9uLmV2YWxWZXJzaW9uID8/IFwibGF0ZXN0XCJ9L2Rpc3Qvd2Vid29ya2VyL2VudHJ5cG9pbnQuanNgXG5cbiAgICBjb25zdCB3b3JrZXJCbG9iID0gYXdhaXQgZ2xvYmFsVGhpcy5mZXRjaChjZG5VcmwpLnRoZW4oKHJlcykgPT4gcmVzLmJsb2IoKSlcbiAgICB3b3JrZXJCbG9iVXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTCh3b3JrZXJCbG9iKVxuICB9XG5cbiAgY29uc3QgcmF3V29ya2VyID0gbmV3IFdvcmtlcih3b3JrZXJCbG9iVXJsLCB7IHR5cGU6IFwibW9kdWxlXCIgfSlcbiAgbGV0IHdvcmtlckluaXRFcnJvcjogYW55XG4gIHJhd1dvcmtlci5hZGRFdmVudExpc3RlbmVyKFwiZXJyb3JcIiwgKGV2ZW50KSA9PiB7XG4gICAgY29uc29sZS5lcnJvcihcIltXb3JrZXJdIEVycm9yIGluIHdvcmtlclwiLCBldmVudClcbiAgICB3b3JrZXJJbml0RXJyb3IgPSBldmVudFxuICB9KVxuICByYXdXb3JrZXIuYWRkRXZlbnRMaXN0ZW5lcihcInVuaGFuZGxlZHJlamVjdGlvblwiLCAoZXZlbnQpID0+IHtcbiAgICBjb25zb2xlLmVycm9yKFwiW1dvcmtlcl0gVW5oYW5kbGVkIHJlamVjdGlvbiBpbiB3b3JrZXJcIiwgZXZlbnQpXG4gIH0pXG4gIHJhd1dvcmtlci5hZGRFdmVudExpc3RlbmVyKFwibWVzc2FnZWVycm9yXCIsIChldmVudCkgPT4ge1xuICAgIGNvbnNvbGUuZXJyb3IoXCJbV29ya2VyXSBNZXNzYWdlIGVycm9yIGluIHdvcmtlclwiLCBldmVudClcbiAgfSlcbiAgY29uc3QgZWFybHlNZXNzYWdlSGFuZGxlciA9IChldmVudDogTWVzc2FnZUV2ZW50KSA9PiB7XG4gICAgY29uc29sZS5sb2coXCJbV29ya2VyXSBNZXNzYWdlIGluIHdvcmtlclwiLCBldmVudClcbiAgfVxuICByYXdXb3JrZXIuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgZWFybHlNZXNzYWdlSGFuZGxlcilcblxuICAvLyBIYW5kbGUgZmV0Y2ggcmVxdWVzdHMgZnJvbSB0aGUgd29ya2VyXG4gIHJhd1dvcmtlci5hZGRFdmVudExpc3RlbmVyKFwibWVzc2FnZVwiLCBhc3luYyAoZXZlbnQ6IE1lc3NhZ2VFdmVudCkgPT4ge1xuICAgIGNvbnN0IGRhdGEgPSBldmVudC5kYXRhXG4gICAgaWYgKGRhdGE/LnR5cGUgIT09IFwid29ya2VyX2ZldGNoXCIpIHJldHVyblxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZ2xvYmFsVGhpcy5mZXRjaChkYXRhLmlucHV0LCBkYXRhLmluaXQpXG4gICAgICBjb25zdCBib2R5ID0gYXdhaXQgcmVzcG9uc2UudGV4dCgpXG4gICAgICByYXdXb3JrZXIucG9zdE1lc3NhZ2Uoe1xuICAgICAgICB0eXBlOiBcIndvcmtlcl9mZXRjaF9yZXN1bHRcIixcbiAgICAgICAgcmVxdWVzdElkOiBkYXRhLnJlcXVlc3RJZCxcbiAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICBib2R5LFxuICAgICAgICAgIHN0YXR1czogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgICAgIHN0YXR1c1RleHQ6IHJlc3BvbnNlLnN0YXR1c1RleHQsXG4gICAgICAgICAgaGVhZGVyczogKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG9iajogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9XG4gICAgICAgICAgICByZXNwb25zZS5oZWFkZXJzLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IHtcbiAgICAgICAgICAgICAgb2JqW2tleV0gPSB2YWx1ZVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHJldHVybiBvYmpcbiAgICAgICAgICB9KSgpLFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgcmF3V29ya2VyLnBvc3RNZXNzYWdlKHtcbiAgICAgICAgdHlwZTogXCJ3b3JrZXJfZmV0Y2hfcmVzdWx0XCIsXG4gICAgICAgIHJlcXVlc3RJZDogZGF0YS5yZXF1ZXN0SWQsXG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBlcnJvcjoge1xuICAgICAgICAgIG5hbWU6IGVyci5uYW1lLFxuICAgICAgICAgIG1lc3NhZ2U6IGVyci5tZXNzYWdlLFxuICAgICAgICAgIHN0YWNrOiBlcnIuc3RhY2ssXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgIH1cbiAgfSlcblxuICBpZiAod29ya2VySW5pdEVycm9yKSB7XG4gICAgdGhyb3cgd29ya2VySW5pdEVycm9yXG4gIH1cblxuICBjb25zdCBjb21saW5rV29ya2VyID0gQ29tbGluay53cmFwPEludGVybmFsV2ViV29ya2VyQXBpPihyYXdXb3JrZXIpXG5cbiAgcmF3V29ya2VyLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsIGVhcmx5TWVzc2FnZUhhbmRsZXIpXG5cbiAgLy8gQ29uZGl0aW9uYWxseSBvdmVycmlkZSBnbG9iYWwgZmV0Y2ggaW5zaWRlIHRoZSB3b3JrZXIgdG8gcm91dGUgdGhyb3VnaCB0aGUgcGFyZW50XG4gIC8vIE9ubHkgZW5hYmxlIHdoZW4gZXhwbGljaXRseSByZXF1ZXN0ZWQgdmlhIGNvbmZpZ3VyYXRpb25cbiAgaWYgKGNvbmZpZ3VyYXRpb24uZW5hYmxlRmV0Y2hQcm94eSkge1xuICAgIHJhd1dvcmtlci5wb3N0TWVzc2FnZSh7IHR5cGU6IFwib3ZlcnJpZGVfZ2xvYmFsX2ZldGNoXCIgfSlcbiAgfVxuXG4gIGlmIChjb25maWd1cmF0aW9uLnNuaXBwZXRzQXBpQmFzZVVybCkge1xuICAgIGF3YWl0IGNvbWxpbmtXb3JrZXIuc2V0U25pcHBldHNBcGlCYXNlVXJsKGNvbmZpZ3VyYXRpb24uc25pcHBldHNBcGlCYXNlVXJsKVxuICB9XG4gIGlmIChjb25maWd1cmF0aW9uLnBsYXRmb3JtKSB7XG4gICAgYXdhaXQgY29tbGlua1dvcmtlci5zZXRQbGF0Zm9ybUNvbmZpZyhjb25maWd1cmF0aW9uLnBsYXRmb3JtKVxuICB9XG5cbiAgbGV0IGlzVGVybWluYXRlZCA9IGZhbHNlXG5cbiAgLy8gQ3JlYXRlIGEgd3JhcHBlciB0aGF0IGhhbmRsZXMgZXZlbnRzIGRpcmVjdGx5IHRocm91Z2ggY2lyY3VpdCBpbnN0YW5jZVxuICBjb25zdCB3cmFwcGVyOiBDaXJjdWl0V2ViV29ya2VyID0ge1xuICAgIGNsZWFyRXZlbnRMaXN0ZW5lcnM6IGNvbWxpbmtXb3JrZXIuY2xlYXJFdmVudExpc3RlbmVycy5iaW5kKGNvbWxpbmtXb3JrZXIpLFxuICAgIHZlcnNpb246IGNvbWxpbmtXb3JrZXIudmVyc2lvbi5iaW5kKGNvbWxpbmtXb3JrZXIpLFxuICAgIGV4ZWN1dGU6IGFzeW5jICguLi5hcmdzKSA9PiB7XG4gICAgICBpZiAoaXNUZXJtaW5hdGVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNpcmN1aXRXZWJXb3JrZXIgd2FzIHRlcm1pbmF0ZWQsIGNhbid0IGV4ZWN1dGVcIilcbiAgICAgIH1cbiAgICAgIHJldHVybiBjb21saW5rV29ya2VyLmV4ZWN1dGUuYmluZChjb21saW5rV29ya2VyKSguLi5hcmdzKVxuICAgIH0sXG4gICAgZXhlY3V0ZVdpdGhGc01hcDogYXN5bmMgKC4uLmFyZ3MpID0+IHtcbiAgICAgIGlmIChpc1Rlcm1pbmF0ZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIFwiQ2lyY3VpdFdlYldvcmtlciB3YXMgdGVybWluYXRlZCwgY2FuJ3QgZXhlY3V0ZVdpdGhGc01hcFwiLFxuICAgICAgICApXG4gICAgICB9XG4gICAgICByZXR1cm4gY29tbGlua1dvcmtlci5leGVjdXRlV2l0aEZzTWFwLmJpbmQoY29tbGlua1dvcmtlcikoLi4uYXJncylcbiAgICB9LFxuICAgIHJlbmRlclVudGlsU2V0dGxlZDogY29tbGlua1dvcmtlci5yZW5kZXJVbnRpbFNldHRsZWQuYmluZChjb21saW5rV29ya2VyKSxcbiAgICBnZXRDaXJjdWl0SnNvbjogY29tbGlua1dvcmtlci5nZXRDaXJjdWl0SnNvbi5iaW5kKGNvbWxpbmtXb3JrZXIpLFxuICAgIG9uOiAoZXZlbnQ6IHN0cmluZywgY2FsbGJhY2s6ICguLi5hcmdzOiBhbnlbXSkgPT4gdm9pZCkgPT4ge1xuICAgICAgY29uc3QgcHJveGllZENhbGxiYWNrID0gQ29tbGluay5wcm94eShjYWxsYmFjaylcbiAgICAgIGNvbWxpbmtXb3JrZXIub24oZXZlbnQgYXMgUm9vdENpcmN1aXRFdmVudE5hbWUsIHByb3hpZWRDYWxsYmFjaylcbiAgICB9LFxuICAgIGtpbGw6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbWxpbmtXb3JrZXJbQ29tbGluay5yZWxlYXNlUHJveHldKClcbiAgICAgIHJhd1dvcmtlci50ZXJtaW5hdGUoKVxuICAgICAgaXNUZXJtaW5hdGVkID0gdHJ1ZVxuICAgICAgaWYgKGdsb2JhbFRoaXMuVFNDSVJDVUlUX0dMT0JBTF9DSVJDVUlUX1dPUktFUiA9PT0gd3JhcHBlcikge1xuICAgICAgICBnbG9iYWxUaGlzLlRTQ0lSQ1VJVF9HTE9CQUxfQ0lSQ1VJVF9XT1JLRVIgPSB1bmRlZmluZWRcbiAgICAgIH1cbiAgICB9LFxuICB9XG4gIDsod3JhcHBlciBhcyBhbnkpLl9fcmF3V29ya2VyID0gcmF3V29ya2VyXG4gIGdsb2JhbFRoaXMuVFNDSVJDVUlUX0dMT0JBTF9DSVJDVUlUX1dPUktFUiA9IHdyYXBwZXJcbiAgcmV0dXJuIHdyYXBwZXJcbn1cbiIsICJleHBvcnQgY29uc3QgZ2V0SW1wb3J0c0Zyb21Db2RlID0gKGNvZGU6IHN0cmluZyk6IHN0cmluZ1tdID0+IHtcbiAgLy8gTWF0Y2ggYmFzaWMgaW1wb3J0IHBhdHRlcm5zIGluY2x1ZGluZyBjb21iaW5lZCBkZWZhdWx0IGFuZCBuYW1lc3BhY2UgaW1wb3J0c1xuICBjb25zdCBpbXBvcnRSZWdleCA9XG4gICAgL15cXHMqaW1wb3J0XFxzKyg/Oig/OltcXHdcXHNdKyxcXHMqKT8oPzpcXCpcXHMrYXNcXHMrW1xcd1xcc10rfFxce1tcXHNcXHcsXStcXH18XFx3KylcXHMrZnJvbVxccyspP1snXCJdKC4rPylbJ1wiXS9nbVxuICBjb25zdCBpbXBvcnRzOiBzdHJpbmdbXSA9IFtdXG4gIGxldCBtYXRjaDogUmVnRXhwRXhlY0FycmF5IHwgbnVsbFxuXG4gIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9Bc3NpZ25JbkV4cHJlc3Npb25zOiA8ZXhwbGFuYXRpb24+XG4gIHdoaWxlICgobWF0Y2ggPSBpbXBvcnRSZWdleC5leGVjKGNvZGUpKSAhPT0gbnVsbCkge1xuICAgIGltcG9ydHMucHVzaChtYXRjaFsxXSlcbiAgfVxuXG4gIC8vIE1hdGNoIHJlLWV4cG9ydHNcbiAgY29uc3QgcmVFeHBvcnRSZWdleCA9XG4gICAgL15cXHMqZXhwb3J0XFxzKyg/OlxcKnwoPzpcXHtbXFxzXFx3LF0rXFx9KSlcXHMrZnJvbVxccytbJ1wiXSguKz8pWydcIl0vZ21cbiAgbGV0IHJlRXhwb3J0TWF0Y2g6IFJlZ0V4cEV4ZWNBcnJheSB8IG51bGxcbiAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0Fzc2lnbkluRXhwcmVzc2lvbnM6IDxleHBsYW5hdGlvbj5cbiAgd2hpbGUgKChyZUV4cG9ydE1hdGNoID0gcmVFeHBvcnRSZWdleC5leGVjKGNvZGUpKSAhPT0gbnVsbCkge1xuICAgIGltcG9ydHMucHVzaChyZUV4cG9ydE1hdGNoWzFdKVxuICB9XG5cbiAgcmV0dXJuIGltcG9ydHNcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBQSxZQUFZLGFBQWE7OztBQ0FsQixJQUFNLHFCQUFxQixDQUFDLFNBQTJCO0FBRTVELFFBQU0sY0FDSjtBQUNGLFFBQU0sVUFBb0IsQ0FBQztBQUMzQixNQUFJO0FBR0osVUFBUSxRQUFRLFlBQVksS0FBSyxJQUFJLE9BQU8sTUFBTTtBQUNoRCxZQUFRLEtBQUssTUFBTSxDQUFD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
|
|
@@ -54,9 +54,10 @@ export const setupDefaultEntrypointIfNeeded = (opts: {
|
|
|
54
54
|
? `
|
|
55
55
|
const ComponentToRender = UserComponents["${opts.mainComponentName}"]
|
|
56
56
|
`
|
|
57
|
-
: `const ComponentToRender =
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
: `const ComponentToRender = UserComponents.default ||
|
|
58
|
+
Object.entries(UserComponents)
|
|
59
|
+
.filter(([name]) => !name.startsWith("use"))
|
|
60
|
+
.map(([_, component]) => component)[0] || (() => null);`
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
${
|
package/lib/shared/types.ts
CHANGED
|
@@ -16,6 +16,13 @@ export interface WebWorkerConfiguration extends CircuitRunnerConfiguration {
|
|
|
16
16
|
*/
|
|
17
17
|
webWorkerUrl?: URL | string
|
|
18
18
|
webWorkerBlobUrl?: URL | string
|
|
19
|
+
/**
|
|
20
|
+
* Enable fetch proxy to route worker fetch requests through parent thread.
|
|
21
|
+
* Useful when running in restricted environments (like ChatGPT) where
|
|
22
|
+
* worker fetch requests are blocked.
|
|
23
|
+
* Default: false
|
|
24
|
+
*/
|
|
25
|
+
enableFetchProxy?: boolean
|
|
19
26
|
}
|
|
20
27
|
|
|
21
28
|
/**
|
package/lib/worker.ts
CHANGED
|
@@ -54,7 +54,7 @@ export const createCircuitWebWorker = async (
|
|
|
54
54
|
if (!workerBlobUrl) {
|
|
55
55
|
const cdnUrl = `https://cdn.jsdelivr.net/npm/@tscircuit/eval@${configuration.evalVersion ?? "latest"}/dist/webworker/entrypoint.js`
|
|
56
56
|
|
|
57
|
-
const workerBlob = await fetch(cdnUrl).then((res) => res.blob())
|
|
57
|
+
const workerBlob = await globalThis.fetch(cdnUrl).then((res) => res.blob())
|
|
58
58
|
workerBlobUrl = URL.createObjectURL(workerBlob)
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -75,6 +75,45 @@ export const createCircuitWebWorker = async (
|
|
|
75
75
|
}
|
|
76
76
|
rawWorker.addEventListener("message", earlyMessageHandler)
|
|
77
77
|
|
|
78
|
+
// Handle fetch requests from the worker
|
|
79
|
+
rawWorker.addEventListener("message", async (event: MessageEvent) => {
|
|
80
|
+
const data = event.data
|
|
81
|
+
if (data?.type !== "worker_fetch") return
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
const response = await globalThis.fetch(data.input, data.init)
|
|
85
|
+
const body = await response.text()
|
|
86
|
+
rawWorker.postMessage({
|
|
87
|
+
type: "worker_fetch_result",
|
|
88
|
+
requestId: data.requestId,
|
|
89
|
+
success: true,
|
|
90
|
+
response: {
|
|
91
|
+
body,
|
|
92
|
+
status: response.status,
|
|
93
|
+
statusText: response.statusText,
|
|
94
|
+
headers: (() => {
|
|
95
|
+
const obj: Record<string, string> = {}
|
|
96
|
+
response.headers.forEach((value, key) => {
|
|
97
|
+
obj[key] = value
|
|
98
|
+
})
|
|
99
|
+
return obj
|
|
100
|
+
})(),
|
|
101
|
+
},
|
|
102
|
+
})
|
|
103
|
+
} catch (err: any) {
|
|
104
|
+
rawWorker.postMessage({
|
|
105
|
+
type: "worker_fetch_result",
|
|
106
|
+
requestId: data.requestId,
|
|
107
|
+
success: false,
|
|
108
|
+
error: {
|
|
109
|
+
name: err.name,
|
|
110
|
+
message: err.message,
|
|
111
|
+
stack: err.stack,
|
|
112
|
+
},
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
|
|
78
117
|
if (workerInitError) {
|
|
79
118
|
throw workerInitError
|
|
80
119
|
}
|
|
@@ -83,6 +122,12 @@ export const createCircuitWebWorker = async (
|
|
|
83
122
|
|
|
84
123
|
rawWorker.removeEventListener("message", earlyMessageHandler)
|
|
85
124
|
|
|
125
|
+
// Conditionally override global fetch inside the worker to route through the parent
|
|
126
|
+
// Only enable when explicitly requested via configuration
|
|
127
|
+
if (configuration.enableFetchProxy) {
|
|
128
|
+
rawWorker.postMessage({ type: "override_global_fetch" })
|
|
129
|
+
}
|
|
130
|
+
|
|
86
131
|
if (configuration.snippetsApiBaseUrl) {
|
|
87
132
|
await comlinkWorker.setSnippetsApiBaseUrl(configuration.snippetsApiBaseUrl)
|
|
88
133
|
}
|
|
@@ -125,6 +170,7 @@ export const createCircuitWebWorker = async (
|
|
|
125
170
|
}
|
|
126
171
|
},
|
|
127
172
|
}
|
|
173
|
+
;(wrapper as any).__rawWorker = rawWorker
|
|
128
174
|
globalThis.TSCIRCUIT_GLOBAL_CIRCUIT_WORKER = wrapper
|
|
129
175
|
return wrapper
|
|
130
176
|
}
|
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.288",
|
|
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",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createCircuitWebWorker } from "lib"
|
|
2
2
|
import { expect, test } from "bun:test"
|
|
3
3
|
// @ts-ignore
|
|
4
|
-
import blobUrl from "dist/blob-url"
|
|
4
|
+
import blobUrl from "../dist/blob-url"
|
|
5
5
|
|
|
6
6
|
test("example3-encoded-worker-url", async () => {
|
|
7
7
|
const circuitWebWorker = await createCircuitWebWorker({
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test"
|
|
2
|
+
import { createCircuitWebWorker } from "../lib"
|
|
3
|
+
|
|
4
|
+
describe("fetch override", () => {
|
|
5
|
+
it("allows worker to fetch via parent and propagates errors", async () => {
|
|
6
|
+
const originalFetch = globalThis.fetch
|
|
7
|
+
const fakeFetch = async (input: RequestInfo, init?: RequestInit) => {
|
|
8
|
+
if (typeof input === "string" && input.includes("cjs.tscircuit.com")) {
|
|
9
|
+
return new Response("module.exports = { default: 123 };", {
|
|
10
|
+
status: 200,
|
|
11
|
+
})
|
|
12
|
+
}
|
|
13
|
+
throw new Error("fake fail")
|
|
14
|
+
}
|
|
15
|
+
globalThis.fetch = fakeFetch as any
|
|
16
|
+
|
|
17
|
+
const worker = await createCircuitWebWorker({
|
|
18
|
+
webWorkerUrl: new URL("../dist/webworker/entrypoint.js", import.meta.url)
|
|
19
|
+
.href,
|
|
20
|
+
enableFetchProxy: true,
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const rawWorker: Worker = (worker as any).__rawWorker
|
|
24
|
+
const messages: any[] = []
|
|
25
|
+
rawWorker.addEventListener("message", (event) => {
|
|
26
|
+
if (event.data?.type === "fetch_error") messages.push(event.data)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
await worker.execute(`
|
|
30
|
+
import val from "@tsci/test.snippet";
|
|
31
|
+
if (val !== 123) { throw new Error("snippet failed"); }
|
|
32
|
+
fetch("https://fail.test").catch(e => {
|
|
33
|
+
postMessage({ type: "fetch_error", name: e.name, message: e.message });
|
|
34
|
+
});
|
|
35
|
+
`)
|
|
36
|
+
|
|
37
|
+
await new Promise((r) => setTimeout(r, 10))
|
|
38
|
+
|
|
39
|
+
expect(messages).toEqual([
|
|
40
|
+
{ type: "fetch_error", name: "Error", message: "fake fail" },
|
|
41
|
+
])
|
|
42
|
+
|
|
43
|
+
await worker.kill()
|
|
44
|
+
globalThis.fetch = originalFetch
|
|
45
|
+
})
|
|
46
|
+
})
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test"
|
|
2
|
+
import { createCircuitWebWorker } from "../lib"
|
|
3
|
+
|
|
4
|
+
describe("fetch proxy validation", () => {
|
|
5
|
+
it("should NOT proxy fetch requests when enableFetchProxy is false (default)", async () => {
|
|
6
|
+
const worker = await createCircuitWebWorker({
|
|
7
|
+
webWorkerUrl: new URL("../dist/webworker/entrypoint.js", import.meta.url)
|
|
8
|
+
.href,
|
|
9
|
+
// enableFetchProxy not set, should default to false
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
const rawWorker: Worker = (worker as any).__rawWorker
|
|
13
|
+
const messages: any[] = []
|
|
14
|
+
rawWorker.addEventListener("message", (event) => {
|
|
15
|
+
if (event.data?.type === "worker_fetch") messages.push(event.data)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
await worker.execute(`
|
|
19
|
+
// Test that fetch calls are NOT proxied when enableFetchProxy is false
|
|
20
|
+
fetch("https://example.com/test")
|
|
21
|
+
.catch(() => {}); // Ignore errors, we just want to see if it's proxied
|
|
22
|
+
`)
|
|
23
|
+
|
|
24
|
+
await new Promise((r) => setTimeout(r, 100))
|
|
25
|
+
|
|
26
|
+
// Should NOT have received any worker_fetch messages
|
|
27
|
+
expect(messages.length).toBe(0)
|
|
28
|
+
|
|
29
|
+
await worker.kill()
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it("should proxy fetch requests when enableFetchProxy is true", async () => {
|
|
33
|
+
const worker = await createCircuitWebWorker({
|
|
34
|
+
webWorkerUrl: new URL("../dist/webworker/entrypoint.js", import.meta.url)
|
|
35
|
+
.href,
|
|
36
|
+
enableFetchProxy: true,
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const rawWorker: Worker = (worker as any).__rawWorker
|
|
40
|
+
const messages: any[] = []
|
|
41
|
+
rawWorker.addEventListener("message", (event) => {
|
|
42
|
+
if (event.data?.type === "worker_fetch") messages.push(event.data)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
await worker.execute(`
|
|
46
|
+
// Test that fetch calls are proxied when enableFetchProxy is true
|
|
47
|
+
fetch("https://example.com/test")
|
|
48
|
+
.catch(() => {}); // Ignore errors, we just want to see if it's proxied
|
|
49
|
+
`)
|
|
50
|
+
|
|
51
|
+
await new Promise((r) => setTimeout(r, 100))
|
|
52
|
+
|
|
53
|
+
// Should have received a worker_fetch message indicating the proxy is working
|
|
54
|
+
expect(messages.length).toBeGreaterThan(0)
|
|
55
|
+
expect(messages[0].type).toBe("worker_fetch")
|
|
56
|
+
expect(messages[0].input).toBe("https://example.com/test")
|
|
57
|
+
|
|
58
|
+
await worker.kill()
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it("should handle fetch errors properly through proxy when enabled", async () => {
|
|
62
|
+
// This test verifies that the fetch proxy correctly handles and forwards errors
|
|
63
|
+
const originalFetch = globalThis.fetch
|
|
64
|
+
const fakeFetch = async () => {
|
|
65
|
+
throw new Error("Network error")
|
|
66
|
+
}
|
|
67
|
+
globalThis.fetch = fakeFetch as any
|
|
68
|
+
|
|
69
|
+
const worker = await createCircuitWebWorker({
|
|
70
|
+
webWorkerUrl: new URL("../dist/webworker/entrypoint.js", import.meta.url)
|
|
71
|
+
.href,
|
|
72
|
+
enableFetchProxy: true,
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
const rawWorker: Worker = (worker as any).__rawWorker
|
|
76
|
+
const messages: any[] = []
|
|
77
|
+
rawWorker.addEventListener("message", (event) => {
|
|
78
|
+
if (event.data?.type === "fetch_error") messages.push(event.data)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
await worker.execute(`
|
|
82
|
+
fetch("https://example.com/test")
|
|
83
|
+
.catch(e => {
|
|
84
|
+
postMessage({ type: "fetch_error", name: e.name, message: e.message });
|
|
85
|
+
});
|
|
86
|
+
`)
|
|
87
|
+
|
|
88
|
+
await new Promise((r) => setTimeout(r, 100))
|
|
89
|
+
|
|
90
|
+
expect(messages).toEqual([
|
|
91
|
+
{ type: "fetch_error", name: "Error", message: "Network error" },
|
|
92
|
+
])
|
|
93
|
+
|
|
94
|
+
await worker.kill()
|
|
95
|
+
globalThis.fetch = originalFetch
|
|
96
|
+
})
|
|
97
|
+
})
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { runTscircuitCode } from "lib/runner"
|
|
2
|
+
import { expect, test } from "bun:test"
|
|
3
|
+
|
|
4
|
+
test("example12 subdirectory relative imports", async () => {
|
|
5
|
+
const circuitJson = await runTscircuitCode(
|
|
6
|
+
{
|
|
7
|
+
"lib/resistor.tsx": `
|
|
8
|
+
export default () => (<resistor name="R1" resistance="1k" />)
|
|
9
|
+
`,
|
|
10
|
+
"user-code.tsx": `
|
|
11
|
+
import Resistor from "./lib/resistor";
|
|
12
|
+
export default () => (<resistor name="R2" resistance="2k" />)
|
|
13
|
+
export {Resistor}
|
|
14
|
+
`,
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
mainComponentPath: "user-code",
|
|
18
|
+
},
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
const resistor = circuitJson.find(
|
|
22
|
+
(element) => element.type === "source_component",
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
expect(resistor).toBeDefined()
|
|
26
|
+
expect(resistor?.name).toBe("R2")
|
|
27
|
+
})
|
package/webworker/entrypoint.ts
CHANGED
|
@@ -14,8 +14,10 @@ import { importEvalPath } from "./import-eval-path"
|
|
|
14
14
|
import { normalizeFsMap } from "../lib/runner/normalizeFsMap"
|
|
15
15
|
import type { RootCircuit } from "@tscircuit/core"
|
|
16
16
|
import { setupDefaultEntrypointIfNeeded } from "lib/runner/setupDefaultEntrypointIfNeeded"
|
|
17
|
+
import { setupFetchProxy } from "./fetchProxy"
|
|
17
18
|
|
|
18
19
|
globalThis.React = React
|
|
20
|
+
setupFetchProxy()
|
|
19
21
|
|
|
20
22
|
let executionContext: ExecutionContext | null = null
|
|
21
23
|
|
|
@@ -124,7 +126,10 @@ const webWorkerApi = {
|
|
|
124
126
|
for (const event in eventListeners) {
|
|
125
127
|
for (const listener of eventListeners[event]) {
|
|
126
128
|
const circuit = executionContext.circuit as unknown as {
|
|
127
|
-
removeListener?: (
|
|
129
|
+
removeListener?: (
|
|
130
|
+
event: string,
|
|
131
|
+
listener: (...args: any[]) => void,
|
|
132
|
+
) => void
|
|
128
133
|
}
|
|
129
134
|
if (typeof circuit.removeListener === "function") {
|
|
130
135
|
circuit.removeListener(event, listener)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export const setupFetchProxy = () => {
|
|
2
|
+
const pendingRequests = new Map<
|
|
3
|
+
number,
|
|
4
|
+
{ resolve: (value: Response) => void; reject: (reason: any) => void }
|
|
5
|
+
>()
|
|
6
|
+
let requestCounter = 0
|
|
7
|
+
|
|
8
|
+
function fetchProxy(
|
|
9
|
+
input: RequestInfo | URL,
|
|
10
|
+
init?: RequestInit,
|
|
11
|
+
): Promise<Response> {
|
|
12
|
+
const requestId = ++requestCounter
|
|
13
|
+
return new Promise((resolve, reject) => {
|
|
14
|
+
pendingRequests.set(requestId, { resolve, reject })
|
|
15
|
+
let url: string
|
|
16
|
+
let requestInit: any = init ? { ...init } : {}
|
|
17
|
+
|
|
18
|
+
if (typeof input === "string" || input instanceof URL) {
|
|
19
|
+
url = input.toString()
|
|
20
|
+
} else {
|
|
21
|
+
url = input.url
|
|
22
|
+
requestInit = {
|
|
23
|
+
...requestInit,
|
|
24
|
+
method: input.method,
|
|
25
|
+
headers: (() => {
|
|
26
|
+
const obj: Record<string, string> = {}
|
|
27
|
+
input.headers.forEach((value, key) => {
|
|
28
|
+
obj[key] = value
|
|
29
|
+
})
|
|
30
|
+
return obj
|
|
31
|
+
})(),
|
|
32
|
+
body: input.bodyUsed ? undefined : (input as any).body,
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (requestInit.headers instanceof Headers) {
|
|
37
|
+
const obj: Record<string, string> = {}
|
|
38
|
+
requestInit.headers.forEach((value: string, key: string) => {
|
|
39
|
+
obj[key] = value
|
|
40
|
+
})
|
|
41
|
+
requestInit.headers = obj
|
|
42
|
+
}
|
|
43
|
+
;(globalThis as any).postMessage({
|
|
44
|
+
type: "worker_fetch",
|
|
45
|
+
requestId,
|
|
46
|
+
input: url,
|
|
47
|
+
init: requestInit,
|
|
48
|
+
})
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function handleMessage(event: MessageEvent) {
|
|
53
|
+
const data = event.data
|
|
54
|
+
if (!data) return
|
|
55
|
+
|
|
56
|
+
if (data.type === "override_global_fetch") {
|
|
57
|
+
;(globalThis as any).fetch = fetchProxy
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (data.type === "worker_fetch_result") {
|
|
62
|
+
const handlers = pendingRequests.get(data.requestId)
|
|
63
|
+
if (!handlers) return
|
|
64
|
+
pendingRequests.delete(data.requestId)
|
|
65
|
+
|
|
66
|
+
if (data.success) {
|
|
67
|
+
const resp = new Response(data.response.body, {
|
|
68
|
+
status: data.response.status,
|
|
69
|
+
statusText: data.response.statusText,
|
|
70
|
+
headers: data.response.headers,
|
|
71
|
+
})
|
|
72
|
+
handlers.resolve(resp)
|
|
73
|
+
} else {
|
|
74
|
+
const err = new Error(data.error.message)
|
|
75
|
+
if (data.error.name) err.name = data.error.name
|
|
76
|
+
if (data.error.stack) err.stack = data.error.stack
|
|
77
|
+
handlers.reject(err)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
globalThis.addEventListener("message", handleMessage)
|
|
83
|
+
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { evalCompiledJs } from "./eval-compiled-js"
|
|
2
2
|
import type { ExecutionContext } from "./execution-context"
|
|
3
|
-
import * as Babel from "@babel/standalone"
|
|
4
|
-
import { importLocalFile } from "./import-local-file"
|
|
5
|
-
import { importEvalPath } from "./import-eval-path"
|
|
6
3
|
|
|
7
4
|
export async function importSnippet(
|
|
8
5
|
importName: string,
|
|
@@ -12,7 +9,8 @@ export async function importSnippet(
|
|
|
12
9
|
const { preSuppliedImports } = ctx
|
|
13
10
|
const fullSnippetName = importName.replace("@tsci/", "").replace(".", "/")
|
|
14
11
|
|
|
15
|
-
const { cjs, error } = await
|
|
12
|
+
const { cjs, error } = await globalThis
|
|
13
|
+
.fetch(`${ctx.cjsRegistryUrl}/${fullSnippetName}`)
|
|
16
14
|
.then(async (res) => ({ cjs: await res.text(), error: null }))
|
|
17
15
|
.catch((e) => ({ error: e, cjs: null }))
|
|
18
16
|
|