Skip to content

Commit 62019ec

Browse files
committed
Added a way to register JS modules directly
1 parent 7f84887 commit 62019ec

File tree

8 files changed

+98
-10
lines changed

8 files changed

+98
-10
lines changed

docs/core.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/core.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

esm/interpreter/_utils.js

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import '@ungap/with-resolvers';
22

33
import { getBuffer } from '../fetch-utils.js';
4-
import { absoluteURL } from '../utils.js';
4+
import { absoluteURL, all, entries, isArray } from '../utils.js';
55

66
// REQUIRES INTEGRATION TEST
77
/* c8 ignore start */
@@ -73,8 +73,6 @@ const resolve = (FS, path) => {
7373
return [FS.cwd()].concat(tree).join('/').replace(/^\/+/, '/');
7474
};
7575

76-
import { all, isArray } from '../utils.js';
77-
7876
const calculateFetchPaths = (config_fetch) => {
7977
// REQUIRES INTEGRATION TEST
8078
/* c8 ignore start */
@@ -142,7 +140,7 @@ const calculateFilesPaths = files => {
142140
const map = new Map;
143141
const targets = new Set;
144142
const sourceDest = [];
145-
for (const [source, dest] of Object.entries(files)) {
143+
for (const [source, dest] of entries(files)) {
146144
if (/^\{.+\}$/.test(source)) {
147145
if (map.has(source))
148146
throw new SyntaxError(`Duplicated template: ${source}`);
@@ -168,4 +166,20 @@ export const fetchFiles = (module, interpreter, config_files) =>
168166
.then((buffer) => module.writeFile(interpreter, path, buffer)),
169167
),
170168
);
169+
170+
export const fetchJSModules = (module, interpreter, js_modules) => {
171+
const modules = [];
172+
for (const [source, name] of entries(js_modules)) {
173+
modules.push(import(source).then(
174+
esm => {
175+
// { ...esm } is needed to avoid dealing w/ module records
176+
module.registerJSModule(interpreter, name, { ...esm });
177+
},
178+
err => {
179+
console.warn(`Unable to register ${name} due ${err}`);
180+
}
181+
));
182+
}
183+
return all(modules);
184+
};
171185
/* c8 ignore stop */

esm/interpreter/micropython.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { fetchFiles, fetchPaths, stdio, writeFile } from './_utils.js';
1+
import { fetchFiles, fetchJSModules, fetchPaths, stdio, writeFile } from './_utils.js';
22
import { registerJSModule, run, runAsync, runEvent } from './_python.js';
33

44
const type = 'micropython';
@@ -15,6 +15,7 @@ export default {
1515
const interpreter = await get(loadMicroPython({ stderr, stdout, url }));
1616
if (config.files) await fetchFiles(this, interpreter, config.files);
1717
if (config.fetch) await fetchPaths(this, interpreter, config.fetch);
18+
if (config.js_modules) await fetchJSModules(this, interpreter, config.js_modules);
1819
return interpreter;
1920
},
2021
registerJSModule,

esm/interpreter/pyodide.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { fetchFiles, fetchPaths, stdio, writeFile } from './_utils.js';
1+
import { fetchFiles, fetchJSModules, fetchPaths, stdio, writeFile } from './_utils.js';
22
import { registerJSModule, run, runAsync, runEvent } from './_python.js';
33

44
const type = 'pyodide';
@@ -18,6 +18,7 @@ export default {
1818
);
1919
if (config.files) await fetchFiles(this, interpreter, config.files);
2020
if (config.fetch) await fetchPaths(this, interpreter, config.fetch);
21+
if (config.js_modules) await fetchJSModules(this, interpreter, config.js_modules);
2122
if (config.packages) {
2223
await interpreter.loadPackage('micropip');
2324
const micropip = await interpreter.pyimport('micropip');

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,6 @@
8282
"sticky-module": "^0.1.1"
8383
},
8484
"worker": {
85-
"blob": "sha256-zpM60x/zMGRf8nMp4IjPmJSJy2ZRzNLNV6kPYAo+yzA="
85+
"blob": "sha256-aQ7OtyRHUryC3RLcjBbLy4MowqKFvi9dR5/umApU3Sk="
8686
}
8787
}

test/modules.html

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width,initial-scale=1.0">
6+
<title>Polyscript JS Modules</title>
7+
<style>#main-map, #worker-map { height: 320px; } h3 { margin-bottom: 0; }</style>
8+
<link rel="stylesheet" href="style.css">
9+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/leaflet.css">
10+
<script type="module" src="../core.js"></script>
11+
</head>
12+
<body>
13+
<!--
14+
main only: npx static-handler .
15+
main/worker: npx static-handler --coop --coep .
16+
17+
Note: --corp breaks the tiles server
18+
-->
19+
20+
<h3>Main</h3>
21+
<div id="main-map"></div>
22+
<!-- Use js_modules via config -->
23+
<script type="pyodide" config="./modules.toml">
24+
# needed to fix pyodide proxies once passed along
25+
from pyodide.ffi import to_js
26+
27+
# registered as Python module
28+
import leaflet as L
29+
30+
center = to_js([51.505, -0.09])
31+
mark = to_js([51.5, -0.09])
32+
map = L.map('main-map').setView(center, 13)
33+
34+
L.tileLayer(
35+
'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
36+
to_js({"attribution": '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'})
37+
).addTo(map)
38+
39+
L.marker(mark).addTo(map).bindPopup('A pretty CSS popup.<br> Easily customizable.').openPopup()
40+
</script>
41+
42+
<hr>
43+
44+
<h3>Worker</h3>
45+
<div id="worker-map"></div>
46+
<!-- Land js modules on main -->
47+
<script type="module">
48+
import * as leaflet from "https://cdn.jsdelivr.net/npm/[email protected]/dist/leaflet-src.esm.js";
49+
globalThis.leaflet = leaflet;
50+
</script>
51+
<script type="pyodide" worker>
52+
# used to reach the main thread window proxy
53+
from polyscript import xworker
54+
55+
# reach directly the module from main
56+
L = xworker.window.leaflet
57+
58+
center = [51.505, -0.09]
59+
mark = [51.5, -0.09]
60+
map = L.map('worker-map').setView(center, 13)
61+
62+
L.tileLayer(
63+
'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
64+
{"attribution": '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'}
65+
).addTo(map)
66+
67+
L.marker(mark).addTo(map).bindPopup('A pretty CSS popup.<br> Easily customizable.').openPopup()
68+
</script>
69+
</body>
70+
</html>

test/modules.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[js_modules]
2+
"https://cdn.jsdelivr.net/npm/[email protected]/dist/leaflet-src.esm.js" = "leaflet"

0 commit comments

Comments
 (0)