Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing issue with polyfill #961

Open
wants to merge 4 commits into
base: mainnet
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@
"comlink": "^4.4.2",
"core-js": "^3.40.0",
"mime": "^4.0.6",
"sync-request": "^6.1.0"
"sync-request": "^6.1.0",
"xmlhttprequest-ssl": "^3.1.0"
},
"devDependencies": {
"@rollup/plugin-replace": "^6.0.2",
Expand Down
1 change: 1 addition & 0 deletions sdk/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default networks.map((network) => {
"node:crypto",
"mime/lite",
"sync-request",
"xmlhttprequest-ssl",

// Used by the SDK
"comlink",
Expand Down
1 change: 1 addition & 0 deletions sdk/rollup.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default networks.map((network) => {
"node:crypto",
"mime/lite",
"sync-request",
"xmlhttprequest-ssl",

// Used by the SDK
"comlink",
Expand Down
24 changes: 23 additions & 1 deletion sdk/src/polyfill/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,35 @@ import $mime from "mime/lite";

const oldFetch = globalThis.fetch;


let supports: Promise<boolean> | null = null;

async function checkFetch() {
try {
await oldFetch(new URL("file:"));
return true;

} catch (e) {
return false;
}
}

async function supportsFetch(): Promise<boolean> {
if (supports === null) {
supports = checkFetch();
}

return await supports;
}


// We always polyfill fetch because Node's fetch doesn't support file URLs.
(globalThis.fetch as any) = async function (resource: URL | RequestInfo, options: RequestInit | undefined): Promise<Response> {
const request = new Request(resource, options);

const url = new URL(request.url);

if (url.protocol === "file:") {
if (!(await supportsFetch()) && url.protocol === "file:") {
const readStream = $fs.createReadStream(url);

const headers: HeadersInit = {};
Expand Down
142 changes: 72 additions & 70 deletions sdk/src/polyfill/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,90 +10,92 @@ if (globalThis.navigator == null) {
} as Navigator;
}

globalThis.Worker = class Worker extends EventTarget {
private _worker: import("node:worker_threads").Worker;
if (globalThis.Worker == null) {
globalThis.Worker = class Worker extends EventTarget {
private _worker: import("node:worker_threads").Worker;

constructor(url: string | URL, options?: WorkerOptions | undefined) {
super();
constructor(url: string | URL, options?: WorkerOptions | undefined) {
super();

if (url instanceof URL) {
if (url.protocol !== "file:") {
throw new Error("Worker only supports file: URLs");
if (url instanceof URL) {
if (url.protocol !== "file:") {
throw new Error("Worker only supports file: URLs");
}

url = url.href;

} else {
throw new Error("Filepaths are unreliable, use `new URL(\"...\", import.meta.url)` instead.");
}

url = url.href;
if (!options || options.type !== "module") {
throw new Error("Workers must use \`type: \"module\"\`");
}

} else {
throw new Error("Filepaths are unreliable, use `new URL(\"...\", import.meta.url)` instead.");
const code = `
import("node:worker_threads")
.then(({ workerData }) => {
return import(workerData.polyfill)
.then(() => import(workerData.url))
})
.catch((e) => {
// TODO maybe it should send a message to the parent?
console.error(e.stack);
});
`;

this._worker = new $worker.Worker(code, {
eval: true,
workerData: {
url,
polyfill: new URL("node-polyfill.js", import.meta.url).href,
},
});

this._worker.on("message", (data) => {
this.dispatchEvent(new MessageEvent("message", { data }));
});

this._worker.on("messageerror", (error) => {
throw new Error("UNIMPLEMENTED");
});

this._worker.on("error", (error) => {
// TODO attach the error to the event somehow
const event = new Event("error");
this.dispatchEvent(event);
});
}

if (!options || options.type !== "module") {
throw new Error("Workers must use \`type: \"module\"\`");
set onmessage(f: () => void) {
throw new Error("UNIMPLEMENTED");
}

const code = `
import("node:worker_threads")
.then(({ workerData }) => {
return import(workerData.polyfill)
.then(() => import(workerData.url))
})
.catch((e) => {
// TODO maybe it should send a message to the parent?
console.error(e.stack);
});
`;

this._worker = new $worker.Worker(code, {
eval: true,
workerData: {
url,
polyfill: new URL("node-polyfill.js", import.meta.url).href,
},
});

this._worker.on("message", (data) => {
this.dispatchEvent(new MessageEvent("message", { data }));
});

this._worker.on("messageerror", (error) => {
set onmessageerror(f: () => void) {
throw new Error("UNIMPLEMENTED");
});

this._worker.on("error", (error) => {
// TODO attach the error to the event somehow
const event = new Event("error");
this.dispatchEvent(event);
});
}

set onmessage(f: () => void) {
throw new Error("UNIMPLEMENTED");
}

set onmessageerror(f: () => void) {
throw new Error("UNIMPLEMENTED");
}
}

set onerror(f: () => void) {
throw new Error("UNIMPLEMENTED");
}
set onerror(f: () => void) {
throw new Error("UNIMPLEMENTED");
}

postMessage(message: any, transfer: Array<Transferable>): void;
postMessage(message: any, options?: StructuredSerializeOptions | undefined): void;
postMessage(value: any, transfer: any) {
this._worker.postMessage(value, transfer);
}
postMessage(message: any, transfer: Array<Transferable>): void;
postMessage(message: any, options?: StructuredSerializeOptions | undefined): void;
postMessage(value: any, transfer: any) {
this._worker.postMessage(value, transfer);
}

terminate() {
this._worker.terminate();
}
terminate() {
this._worker.terminate();
}

// This is Node-specific, it allows the process to exit
// even if the Worker is still running.
unref() {
this._worker.unref();
}
};
// This is Node-specific, it allows the process to exit
// even if the Worker is still running.
unref() {
this._worker.unref();
}
};
}


if (!$worker.isMainThread) {
Expand Down
Loading
Loading