diff --git a/py/h2o_nitro/core.py b/py/h2o_nitro/core.py index 7d6a5694..a05d9035 100644 --- a/py/h2o_nitro/core.py +++ b/py/h2o_nitro/core.py @@ -17,12 +17,32 @@ import random from pathlib import Path from collections import OrderedDict -import msgpack from enum import Enum, IntEnum -from .version import __version__ +from .version import __version__, __nitride__ web_directory = str(Path(__file__).parent / 'www') +if __nitride__: + import json + + + def _marshal(d: dict): + return json.dumps(d) + + + def _unmarshal(b) -> dict: + return json.loads(b) +else: + import msgpack + + + def _marshal(d: dict): + return msgpack.packb(d) + + + def _unmarshal(b) -> dict: + return msgpack.unpackb(b) + __xid = 0 @@ -71,14 +91,6 @@ def __init__(self): super().__init__('Interrupted') -def _marshal(d: dict): - return msgpack.packb(d) - - -def _unmarshal(b) -> dict: - return msgpack.unpackb(b) - - def _dump(x): # recursive if isinstance(x, OrderedDict): return _dump([(k, v) for k, v in x.items()]) @@ -607,7 +619,7 @@ def _unwrap_input(x): return None if x is None else x[1] -def _marshal_error(code: int, text: str) -> dict: +def _marshal_error(code: int, text: str): return _marshal(dict(t=_MsgType.Error, code=code, text=text)) @@ -619,7 +631,7 @@ def _marshal_set( theme: Optional[Theme] = None, plugins: Optional[Iterable[Plugin]] = None, mode: Optional[str] = None, -) -> dict: +): return _marshal(dict( t=_MsgType.Set, xid=_xid(), diff --git a/py/h2o_nitro/version.py b/py/h2o_nitro/version.py index 1f4c4d43..afe6f02a 100644 --- a/py/h2o_nitro/version.py +++ b/py/h2o_nitro/version.py @@ -1 +1,2 @@ __version__ = "0.10.1" +__nitride__ = False diff --git a/web/public/nitride.js b/web/public/nitride.js new file mode 100644 index 00000000..8f416e91 --- /dev/null +++ b/web/public/nitride.js @@ -0,0 +1,34 @@ + +const pollInterval = 100 + +let _poller = 0; + +async function init(runtime, program, autoload) { + importScripts(runtime); + self.pyodide = await loadPyodide(); + await self.pyodide.loadPackage(["micropip"]); + if (autoload) await self.pyodide.loadPackagesFromImports(program); + await self.pyodide.runPythonAsync(program); + clearInterval(_poller); + _poller = setInterval(() => { + const message = self.pyodide.globals.get('_nitro_io').read(); + if (message) self.postMessage({ t: 1, message }); + }, pollInterval); +} + +self.onmessage = async (event) => { + const c = event.data; + try { + switch (c.t) { + case 1: + self.pyodide.globals.get('_nitro_io').write(c.message); + break; + case 2: + await init(c.runtime, c.program, c.autoload); + self.postMessage({ t: 3 }); + break; + } + } catch (error) { + self.postMessage({ t: 0, error: error.message }); + } +}