Skip to content

Commit

Permalink
Added a way to register JS modules directly
Browse files Browse the repository at this point in the history
  • Loading branch information
WebReflection committed Nov 28, 2023
1 parent 7f84887 commit 061ef5f
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 10 deletions.
4 changes: 2 additions & 2 deletions docs/core.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/core.js.map

Large diffs are not rendered by default.

21 changes: 17 additions & 4 deletions esm/interpreter/_utils.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import '@ungap/with-resolvers';

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

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

import { all, isArray } from '../utils.js';

const calculateFetchPaths = (config_fetch) => {
// REQUIRES INTEGRATION TEST
/* c8 ignore start */
Expand Down Expand Up @@ -142,7 +140,7 @@ const calculateFilesPaths = files => {
const map = new Map;
const targets = new Set;
const sourceDest = [];
for (const [source, dest] of Object.entries(files)) {
for (const [source, dest] of entries(files)) {
if (/^\{.+\}$/.test(source)) {
if (map.has(source))
throw new SyntaxError(`Duplicated template: ${source}`);
Expand All @@ -168,4 +166,19 @@ export const fetchFiles = (module, interpreter, config_files) =>
.then((buffer) => module.writeFile(interpreter, path, buffer)),
),
);

export const fetchJSModules = (module, interpreter, js_modules) => {
const modules = [];
for (const [source, name] of entries(js_modules)) {
modules.push(import(source).then(
esm => {
module.registerJSModule(interpreter, name, { ...esm });
},
err => {
console.warn(`Unable to register ${name} due ${err}`);
}
));
}
return all(modules);
};
/* c8 ignore stop */
3 changes: 2 additions & 1 deletion esm/interpreter/micropython.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { fetchFiles, fetchPaths, stdio, writeFile } from './_utils.js';
import { fetchFiles, fetchJSModules, fetchPaths, stdio, writeFile } from './_utils.js';
import { registerJSModule, run, runAsync, runEvent } from './_python.js';

const type = 'micropython';
Expand All @@ -15,6 +15,7 @@ export default {
const interpreter = await get(loadMicroPython({ stderr, stdout, url }));
if (config.files) await fetchFiles(this, interpreter, config.files);
if (config.fetch) await fetchPaths(this, interpreter, config.fetch);
if (config.js_modules) await fetchJSModules(this, interpreter, config.js_modules);
return interpreter;
},
registerJSModule,
Expand Down
3 changes: 2 additions & 1 deletion esm/interpreter/pyodide.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { fetchFiles, fetchPaths, stdio, writeFile } from './_utils.js';
import { fetchFiles, fetchJSModules, fetchPaths, stdio, writeFile } from './_utils.js';
import { registerJSModule, run, runAsync, runEvent } from './_python.js';

const type = 'pyodide';
Expand All @@ -18,6 +18,7 @@ export default {
);
if (config.files) await fetchFiles(this, interpreter, config.files);
if (config.fetch) await fetchPaths(this, interpreter, config.fetch);
if (config.js_modules) await fetchJSModules(this, interpreter, config.js_modules);
if (config.packages) {
await interpreter.loadPackage('micropip');
const micropip = await interpreter.pyimport('micropip');
Expand Down
28 changes: 28 additions & 0 deletions mini-coi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*! coi-serviceworker v0.1.7 - Guido Zuidhof and contributors, licensed under MIT */
/*! mini-coi - Andrea Giammarchi and contributors, licensed under MIT */
(({ document: d, navigator: { serviceWorker: s } }) => {
if (d) {
const { currentScript: c } = d;
s.register(c.src, { scope: c.getAttribute('scope') || '.' }).then(r => {
r.addEventListener('updatefound', () => location.reload());
if (r.active && !s.controller) location.reload();
});
}
else {
addEventListener('install', () => skipWaiting());
addEventListener('activate', e => e.waitUntil(clients.claim()));
addEventListener('fetch', e => {
const { request: r } = e;
if (r.cache === 'only-if-cached' && r.mode !== 'same-origin') return;
e.respondWith(fetch(r).then(r => {
const { body, status, statusText } = r;
if (!status || status > 399) return r;
const h = new Headers(r.headers);
h.set('Cross-Origin-Opener-Policy', 'same-origin');
h.set('Cross-Origin-Embedder-Policy', 'require-corp');
h.set('Cross-Origin-Resource-Policy', 'cross-origin');
return new Response(body, { status, statusText, headers: h });
}));
});
}
})(self);
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,6 @@
"sticky-module": "^0.1.1"
},
"worker": {
"blob": "sha256-zpM60x/zMGRf8nMp4IjPmJSJy2ZRzNLNV6kPYAo+yzA="
"blob": "sha256-aQ7OtyRHUryC3RLcjBbLy4MowqKFvi9dR5/umApU3Sk="
}
}
70 changes: 70 additions & 0 deletions test/modules.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>python</title>
<style>#main-map, #worker-map { height: 320px; } h3 { margin-bottom: 0; }</style>
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/leaflet.css" />
<script type="module" src="../core.js"></script>
</head>
<body>
<!--
main only: npx static-handler .
main/worker: npx static-handler --coop --coep .
Note: --corp breaks the tiles server
-->

<!-- Use js_modules via config -->
<h3>Main</h3>
<div id="main-map"></div>
<script type="pyodide" config="./modules.toml">
# needed to fix pyodide proxies once passed along
from pyodide.ffi import to_js

# registered as Python module
import leaflet as L

center = to_js([51.505, -0.09])
mark = to_js([51.5, -0.09])
map = L.map('main-map').setView(center, 13);

L.tileLayer(
'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
to_js({"attribution": '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'})
).addTo(map);

L.marker(mark).addTo(map).bindPopup('A pretty CSS popup.<br> Easily customizable.').openPopup();
</script>

<hr>

<!-- Land js modules on main -->
<h3>Worker</h3>
<div id="worker-map"></div>
<script type="module">
import * as leaflet from "https://cdn.jsdelivr.net/npm/[email protected]/dist/leaflet-src.esm.js";
globalThis.leaflet = leaflet;
</script>
<script type="pyodide" worker>
# used to reach the main thread window proxy
from polyscript import xworker

# reach directly the module from main
L = xworker.window.leaflet

center = [51.505, -0.09]
mark = [51.5, -0.09]
map = L.map('worker-map').setView(center, 13);

L.tileLayer(
'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
{"attribution": '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'}
).addTo(map);

L.marker(mark).addTo(map).bindPopup('A pretty CSS popup.<br> Easily customizable.').openPopup();
</script>
</body>
</html>
2 changes: 2 additions & 0 deletions test/modules.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[js_modules]
"https://cdn.jsdelivr.net/npm/[email protected]/dist/leaflet-src.esm.js" = "leaflet"

0 comments on commit 061ef5f

Please sign in to comment.