From d0f0ebc6c35c4d028728b7068a6466401f8284a9 Mon Sep 17 00:00:00 2001 From: Mateusz Paprocki Date: Fri, 15 Apr 2022 14:28:51 +0200 Subject: [PATCH 1/2] Very rudimentary support for ESM and import maps --- pyscriptjs/src/components/pyscript.ts | 44 +++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/pyscriptjs/src/components/pyscript.ts b/pyscriptjs/src/components/pyscript.ts index 80cfcbe..30aef4a 100644 --- a/pyscriptjs/src/components/pyscript.ts +++ b/pyscriptjs/src/components/pyscript.ts @@ -45,6 +45,11 @@ function htmlDecode(input) { return doc.documentElement.textContent; } +// TODO: use type declaractions +type PyodideInterface = { + registerJsModule(name: string, module: object): void +} + class Script { source: string; state: string; @@ -241,17 +246,50 @@ export class PyScript extends HTMLElement { // pkg.do_something(); } - async evaluate() { + protected async _register_esm(pyodide: PyodideInterface): Promise { + const imports: {[key: string]: unknown} = {} + for (const node of document.querySelectorAll("script[type='importmap']")) { + const importmap = (() => { + try { + return JSON.parse(node.textContent) + } catch { + return null + } + })() + + if (importmap?.imports == null) + continue + + for (const [name, url] of Object.entries(importmap.imports)) { + if (typeof name != "string" || typeof url != "string") + continue + + try { + // XXX: pyodide doesn't like Module(), failing with + // "can't read 'name' of undefined" at import time + imports[name] = {...await import(url)} + } catch { + console.error(`failed to fetch '${url}' for '${name}'`) + } + } + } + + pyodide.registerJsModule("esm", imports) + } + + async evaluate(): Promise { console.log('evaluate'); + if (this.source){ this.loadFromFile(this.source) }else{ - let pyodide = await pyodideReadyPromise; + const pyodide = await pyodideReadyPromise; + await this._register_esm(pyodide) // debugger try { // @ts-ignore - let source = htmlDecode(this.editor.state.doc.toString()); + const source = htmlDecode(this.editor.state.doc.toString()); let output; if (source.includes("asyncio")){ output = await pyodide.runPythonAsync(source); From a80dcf13d35523f8001f38da507f45827f808617 Mon Sep 17 00:00:00 2001 From: Mateusz Paprocki Date: Fri, 15 Apr 2022 14:30:32 +0200 Subject: [PATCH 2/2] Use ESM and import maps in d3 example --- pyscriptjs/examples/d3.html | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/pyscriptjs/examples/d3.html b/pyscriptjs/examples/d3.html index c5bdc68..fcae36f 100644 --- a/pyscriptjs/examples/d3.html +++ b/pyscriptjs/examples/d3.html @@ -3,8 +3,6 @@ d3: JavaScript & PyScript visualizations side-by-side - - @@ -46,7 +44,17 @@ - + +