PyodideRuntime should be one of the runtimes (#698)

* PyodideRuntime should be one of the runtimes

* subsume interpreter into runtime API

* fix eslint

* add comments

* move initializers, postInitializers, scriptsQueue, etc. to initialize() of Runtime Super Class

* modify comment for initialize

* small renaming

* change id to default

* fix pyscript.py import

* try adding tests

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add inlineDynamicImports option

* Make jest happy about ESM modules

* Attempt to make jest happy about pyodide

* point to version in accordance with node module being used

* fix base.ts

* fix tests

* fix indexURL path determination

* edit pyodide.asm.js as a part of setup process

* load runtime beforeAll tests

* add test for loading a package

* use only runPythonAsync underneath for pyodide

* import PyodideInterface type directly from pyodide

* add some comments

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Philipp Rudiger <prudiger@anaconda.com>
This commit is contained in:
Madhur Tandon
2022-08-25 02:33:36 +05:30
committed by GitHub
parent 1054e8e644
commit 1db155570d
17 changed files with 438 additions and 270 deletions

View File

@@ -3,19 +3,20 @@ import {
addPostInitializer,
addToScriptsQueue,
loadedEnvironments,
pyodideLoaded,
runtimeLoaded,
type Environment,
} from '../stores';
import { addClasses, htmlDecode } from '../utils';
import { BaseEvalElement } from './base';
import type { PyodideInterface } from '../pyodide';
import type { Runtime } from '../runtime';
// Premise used to connect to the first available pyodide interpreter
let pyodideReadyPromise: PyodideInterface;
// Premise used to connect to the first available runtime (can be pyodide or others)
let runtime: Runtime;
let environments: Record<Environment['id'], Environment> = {};
pyodideLoaded.subscribe(value => {
pyodideReadyPromise = value;
runtimeLoaded.subscribe(value => {
runtime = value;
});
loadedEnvironments.subscribe(value => {
environments = value;
@@ -78,7 +79,7 @@ export class PyScript extends BaseEvalElement {
}
}
protected async _register_esm(pyodide: PyodideInterface): Promise<void> {
protected async _register_esm(runtime: Runtime): Promise<void> {
for (const node of document.querySelectorAll("script[type='importmap']")) {
const importmap = (() => {
try {
@@ -103,7 +104,7 @@ export class PyScript extends BaseEvalElement {
continue;
}
pyodide.registerJsModule(name, exports);
runtime.registerJsModule(name, exports);
}
}
}
@@ -211,14 +212,13 @@ const pyAttributeToEvent: Map<string, string> = new Map<string, string>([
/** Initialize all elements with py-on* handlers attributes */
async function initHandlers() {
console.log('Collecting nodes...');
const pyodide = pyodideReadyPromise;
for (const pyAttribute of pyAttributeToEvent.keys()) {
await createElementsWithEventListeners(pyodide, pyAttribute);
await createElementsWithEventListeners(runtime, pyAttribute);
}
}
/** Initializes an element with the given py-on* attribute and its handler */
async function createElementsWithEventListeners(pyodide: PyodideInterface, pyAttribute: string): Promise<void> {
async function createElementsWithEventListeners(runtime: Runtime, pyAttribute: string): Promise<void> {
const matches: NodeListOf<HTMLElement> = document.querySelectorAll(`[${pyAttribute}]`);
for (const el of matches) {
if (el.id.length === 0) {
@@ -230,7 +230,7 @@ async function createElementsWithEventListeners(pyodide: PyodideInterface, pyAtt
from pyodide import create_proxy
Element("${el.id}").element.addEventListener("${event}", create_proxy(${handlerCode}))
`;
await pyodide.runPythonAsync(source);
await runtime.run(source);
// TODO: Should we actually map handlers in JS instead of Python?
// el.onclick = (evt: any) => {
@@ -252,7 +252,6 @@ async function createElementsWithEventListeners(pyodide: PyodideInterface, pyAtt
/** Mount all elements with attribute py-mount into the Python namespace */
async function mountElements() {
console.log('Collecting nodes to be mounted into python namespace...');
const pyodide = pyodideReadyPromise;
const matches: NodeListOf<HTMLElement> = document.querySelectorAll('[py-mount]');
let source = '';
@@ -260,7 +259,7 @@ async function mountElements() {
const mountName = el.getAttribute('py-mount') || el.id.split('-').join('_');
source += `\n${mountName} = Element("${el.id}")`;
}
await pyodide.runPythonAsync(source);
await runtime.run(source);
}
addInitializer(mountElements);
addPostInitializer(initHandlers);