-
-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add file:// schema to the Pyodide ESM path in the desktop package (#959)
* Add file:// schema to the Pyodide ESM path in the desktop package * Add comment * Fix to attach the file:// scheme only to the url passed to import() * Add .ports to MessageEventLike for NodeJS worker mode * Fix * Fix * Write tests for pyodide load url resolution * Add comment
- Loading branch information
Showing
5 changed files
with
119 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { describe, it, expect } from "vitest"; | ||
import { resolvePyodideUrl } from "./pyodide-loader"; | ||
|
||
describe("resolvePyodideUrl", () => { | ||
it("resolves a non-ESM remote URL", async () => { | ||
const result = await resolvePyodideUrl( | ||
"https://cdn.jsdelivr.net/pyodide/v0.26.0/full/pyodide.js", | ||
); | ||
expect(result).toEqual({ | ||
scriptURL: "https://cdn.jsdelivr.net/pyodide/v0.26.0/full/pyodide.js", | ||
pyodideIndexURL: "https://cdn.jsdelivr.net/pyodide/v0.26.0/full/", | ||
isESModule: false, | ||
}); | ||
}); | ||
|
||
it("resolves an ESM remote URL", async () => { | ||
const result = await resolvePyodideUrl( | ||
"https://cdn.jsdelivr.net/pyodide/v0.26.0/full/pyodide.mjs", | ||
); | ||
expect(result).toEqual({ | ||
scriptURL: "https://cdn.jsdelivr.net/pyodide/v0.26.0/full/pyodide.mjs", | ||
pyodideIndexURL: "https://cdn.jsdelivr.net/pyodide/v0.26.0/full/", | ||
isESModule: true, | ||
}); | ||
}); | ||
|
||
it("resolves a non-ESM local URL", async () => { | ||
const result = await resolvePyodideUrl("/path/to/pyodide.js"); | ||
expect(result).toEqual({ | ||
scriptURL: "/path/to/pyodide.js", | ||
pyodideIndexURL: "/path/to/", | ||
isESModule: false, | ||
}); | ||
}); | ||
|
||
it("resolves an ESM local URL", async () => { | ||
const result = await resolvePyodideUrl("/path/to/pyodide.mjs"); | ||
expect(result).toEqual({ | ||
scriptURL: "file:///path/to/pyodide.mjs", // import() requires the `file://` scheme on Windows | ||
pyodideIndexURL: "/path/to/", | ||
isESModule: true, | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import type Pyodide from "pyodide"; | ||
|
||
interface ResolvePyodideUrlResult { | ||
scriptURL: string; | ||
pyodideIndexURL: string; | ||
isESModule: boolean; | ||
} | ||
export async function resolvePyodideUrl( | ||
pyodideUrl: string, | ||
): Promise<ResolvePyodideUrlResult> { | ||
const isNode = typeof process !== "undefined" && process.versions?.node; | ||
|
||
let sep: string; | ||
if (isNode) { | ||
const nodePath = await import(/* webpackIgnore: true */ "node:path"); | ||
sep = nodePath.sep; | ||
} else { | ||
sep = "/"; // URL path separator | ||
} | ||
|
||
// Ref: https://github.com/jupyterlite/pyodide-kernel/blob/v0.1.3/packages/pyodide-kernel/src/kernel.ts#L55 | ||
const pyodideIndexURL = pyodideUrl.slice(0, pyodideUrl.lastIndexOf(sep) + 1); | ||
|
||
// Ref: https://github.com/jupyterlite/pyodide-kernel/blob/v0.1.3/packages/pyodide-kernel/src/worker.ts#L40-L54 | ||
if (pyodideUrl.endsWith(".mjs")) { | ||
if (isNode) { | ||
// Special care for Node.js on Windows because the `file://` scheme is required in the URL passed to import() on Windows. See https://github.com/whitphx/stlite/issues/957 | ||
const nodePath = await import(/* webpackIgnore: true */ "node:path"); | ||
const nodeUrl = await import(/* webpackIgnore: true */ "node:url"); | ||
const possiblyLocalFilePath = !pyodideUrl.includes("://"); | ||
if (possiblyLocalFilePath && nodePath.isAbsolute(pyodideUrl)) { | ||
pyodideUrl = nodeUrl.pathToFileURL(pyodideUrl).href; | ||
} | ||
} | ||
return { | ||
scriptURL: pyodideUrl, | ||
pyodideIndexURL, | ||
isESModule: true, | ||
}; | ||
} else { | ||
return { | ||
scriptURL: pyodideUrl, | ||
pyodideIndexURL, | ||
isESModule: false, | ||
}; | ||
} | ||
} | ||
|
||
export async function initPyodide( | ||
pyodideUrl: string, | ||
loadPyodideOptions: Parameters<typeof Pyodide.loadPyodide>[0], | ||
): Promise<Pyodide.PyodideInterface> { | ||
const { scriptURL, pyodideIndexURL, isESModule } = | ||
await resolvePyodideUrl(pyodideUrl); | ||
|
||
// Ref: https://github.com/jupyterlite/pyodide-kernel/blob/v0.1.3/packages/pyodide-kernel/src/worker.ts#L40-L54 | ||
let loadPyodide: typeof Pyodide.loadPyodide; | ||
if (isESModule) { | ||
// note: this does not work at all in firefox | ||
const pyodideModule: typeof Pyodide = await import( | ||
/* webpackIgnore: true */ scriptURL | ||
); | ||
loadPyodide = pyodideModule.loadPyodide; | ||
} else { | ||
importScripts(scriptURL); | ||
loadPyodide = (self as any).loadPyodide; | ||
} | ||
return loadPyodide({ ...loadPyodideOptions, indexURL: pyodideIndexURL }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters