/ concept-collection / jupyterlite-numbl-kernel
Sign in
concept-collection / jupyterlite-numbl-kernel
jupyterlite-numbl-kernel / README.md
159 lines · 7.1 KBCodeBlameHistory
41c072cjupyterlite-numbl-kernel: MATLAB-syntax kernel for JupyterLiteJeremy Magland 1# jupyterlite-numbl-kernel
80cd178Update numbl links and tidy copyJeremy Magland 3Run [**numbl**](https://numbl.org), numerical computing with **MATLAB
4syntax**, in [JupyterLite](https://jupyterlite.readthedocs.io/) notebooks,
5**entirely in the browser**, with no server, no kernel process, and nothing
6for the reader to install.
f44f6a3Rebrand numbl-first: this runs numbl (which uses MATLAB syntax)Jeremy Magland 8numbl is an open-source numerical-computing engine, written in TypeScript,
80cd178Update numbl links and tidy copyJeremy Magland 9that uses MATLAB syntax, so `.m` code runs unchanged. This kernel runs a
41c072cjupyterlite-numbl-kernel: MATLAB-syntax kernel for JupyterLiteJeremy Magland 10numbl session in a Web Worker in the page: variables persist across cells,
f44f6a3Rebrand numbl-first: this runs numbl (which uses MATLAB syntax)Jeremy Magland 11console output streams into the running cell, plots render as figures in cell
12outputs (including interactive 3-D), the `mip` package manager can install
13numbl packages from GitHub, and `.m` files next to the notebook are part of
80cd178Update numbl links and tidy copyJeremy Magland 14the workspace (named functions, called from cells). Everything runs
15client-side.
17**Demo site:**
18<https://concept-collection.github.io/jupyterlite-numbl-kernel/> (deployed
80cd178Update numbl links and tidy copyJeremy Magland 19from this repo via GitHub Pages; see `.github/workflows/deploy.yml`)
21## Why
f44f6a3Rebrand numbl-first: this runs numbl (which uses MATLAB syntax)Jeremy Magland 23This kernel is a proof of concept that a numbl notebook can be a static web
24page: hostable on GitHub Pages, shareable as a link, and executable by anyone
25with a browser. Because numbl uses MATLAB syntax and needs no MATLAB/Octave
26install (or any server process), the same `.m` code that would otherwise
27require a licensed product behind a server just runs in the tab.
29## How it works
31Three small pieces, all in this repo:
80cd178Update numbl links and tidy copyJeremy Magland 33- **Kernel** (`src/kernel.ts`): implements JupyterLite's `BaseKernel` from
6b31a9aSync .m workspace files from the notebook directory into the sessionJeremy Magland 34 `@jupyterlite/services`. Before each `execute_request`, `.m` files in the
35 notebook's directory (read via the JupyterLite contents manager) are
36 synced into the numbl session; the cell source then runs against the
37 session's persistent workspace (`createNumblSession` /
38 `session.execute` from `numbl/browser`, a Web Worker that numbl manages).
39 Output streams back as `stream` messages; the run's plot instructions are
40 published as `display_data` with the mime type
41 `application/vnd.numbl.figure+json`.
80cd178Update numbl links and tidy copyJeremy Magland 42- **Figure renderer** (`src/mime.tsx`): a JupyterLab mime renderer for that
41c072cjupyterlite-numbl-kernel: MATLAB-syntax kernel for JupyterLiteJeremy Magland 43 mime type: it replays the instructions through numbl's figures reducer and
44 mounts numbl's React `FigureView` (from `numbl/graphics`). Outputs are
45 plain JSON, so saved notebooks re-render wherever the extension is
46 installed.
80cd178Update numbl links and tidy copyJeremy Magland 47- **Kernel registration** (`src/index.ts`): registers the kernelspec with
41c072cjupyterlite-numbl-kernel: MATLAB-syntax kernel for JupyterLiteJeremy Magland 48 JupyterLite's `IKernelSpecs`.
50## Build a site with it
52```bash
53pip install jupyterlite-core jupyterlite-numbl-kernel
54jupyter lite build --contents my-notebooks --output-dir dist
80cd178Update numbl links and tidy copyJeremy Magland 55# dist/ is a static site; serve it anywhere
58The `demo/` directory in this repo contains the demo site sources
59(notebooks + requirements); `.github/workflows/deploy.yml` builds and
9ff4e5bRestructure demo into a full guided tour with OOP and namespacesJeremy Magland 60deploys it to GitHub Pages. `demo/content/` is a numbered walkthrough: an
61intro (with plotting), a systematic language tour (data types, matrices,
62control flow, linear algebra, data structures, numerical methods,
63plotting), the advanced MATLAB object model (classes and OOP, namespaces
64and packages), and finally installing packages with `mip`. The class and
65package `.m` files live next to the notebooks (e.g. `Vec2.m`, `+geom/`,
66`@Poly/`) and are synced into the session recursively.
8befa62Demo: use in-memory JupyterLite storage so reloads show fresh contentJeremy Magland 68### Always-fresh content (demo choice)
0fd7818Demo: disable the JupyterLite service worker so redeploys show on reloadJeremy Magland 70JupyterLite caches content in two layers that both defeat redeploys:
721. It copies notebooks into the browser's IndexedDB on first visit, and that
73 local copy then wins over the deployed files **even after a redeploy**.
742. Its **service worker** is an offline caching proxy for the app itself and
75 for content files, so it can keep serving the old app and old notebooks
76 after a redeploy until it happens to update.
78Since this is a demo, `demo/jupyter-lite.json` neutralizes both: it uses
79JupyterLite's in-memory storage (so every reload re-seeds the latest
80deployed notebooks) and disables the service-worker plugin (which the numbl
80cd178Update numbl links and tidy copyJeremy Magland 81kernel doesn't need, since it reads content on the main thread, not via the
0fd7818Demo: disable the JupyterLite service worker so redeploys show on reloadJeremy Magland 82service worker's kernel drive):
84```json
86 "jupyter-config-data": {
87 "enableMemoryStorage": true,
88 "contentsStorageDrivers": ["memoryStorageDriver"],
89 "settingsStorageDrivers": ["memoryStorageDriver"],
0fd7818Demo: disable the JupyterLite service worker so redeploys show on reloadJeremy Magland 90 "workspacesStorageDrivers": ["memoryStorageDriver"],
91 "disabledExtensions": [
92 "@jupyterlite/application-extension:service-worker-manager"
93 ]
96```
98The trade-off is that a visitor's edits live only for the session and are
0fd7818Demo: disable the JupyterLite service worker so redeploys show on reloadJeremy Magland 99discarded on reload. A visitor who loaded the site **before** the service
100worker was disabled still has it registered and must clear browser data
101(or `Help > Clear Browser Data`) once to get past it. For a real deployment where users should keep their
8befa62Demo: use in-memory JupyterLite storage so reloads show fresh contentJeremy Magland 102work, omit these keys (the default persistent storage) and bump
103`contentsStorageName` when you want to force-refresh shipped content.
104numbl's own package cache (installed via `mip`) lives in a separate
105IndexedDB store and is unaffected, so `mip`-installed packages still
106persist across reloads.
41c072cjupyterlite-numbl-kernel: MATLAB-syntax kernel for JupyterLiteJeremy Magland 108## Limitations (proof of concept)
110- **No interrupt**: a runaway cell can only be stopped by restarting the
111 kernel (restart works and gives a fresh workspace). Cooperative
112 cancellation exists in numbl but needs `SharedArrayBuffer`, i.e.
113 cross-origin isolation headers, which plain GitHub Pages doesn't set.
114- **No `input()`** (stdin), for the same reason.
115- **Figures are per-cell** (like inline matplotlib): each cell renders the
116 figures its own commands produce; `hold on` does not span cells.
117- **Named function definitions are not supported inside cells** (a numbl
80cd178Update numbl links and tidy copyJeremy Magland 118 REPL limitation): anonymous functions work, and named functions belong in
6b31a9aSync .m workspace files from the notebook directory into the sessionJeremy Magland 119 `.m` files next to the notebook (see `demo/content/statsutils.m`), which
120 this kernel syncs into the session automatically.
121- The `.m`-file sync is **one-way**: deleting a `.m` file from the file
122 browser leaves its function defined until the kernel restarts, and files
123 written by cell code (e.g. via `fopen`) don't appear back in the file
124 browser.
41c072cjupyterlite-numbl-kernel: MATLAB-syntax kernel for JupyterLiteJeremy Magland 125- **uihtml** components render display-only; the MATLAB↔HTML event bridge
126 is not wired into outputs yet.
127- numbl itself is not MATLAB: it covers a large, tested subset of the
80cd178Update numbl links and tidy copyJeremy Magland 128 language and toolbox surface. See [numbl](https://numbl.org) for scope.
130## Development
132Requires Python ≥ 3.9 and NodeJS ≥ 20, and `numbl >= 0.4.14` on npm (the
133first release with the incremental `session.execute` browser API). To
134develop against an unreleased numbl checkout, run `npm pack` there and
135point the `numbl` dependency at the tarball.
137```bash
138python -m venv .venv && source .venv/bin/activate
139pip install "jupyterlab~=4.6.0" "jupyterlite-core==0.8.1"
141jlpm install
142jlpm build # tsc + labextension (dev)
143pip install -e . # editable install, registers the labextension
145# Build and serve the demo site locally
146pip install -r demo/requirements.txt
147jupyter lite build --lite-dir demo --contents content --output-dir demo/_output
148python -m http.server -d demo/_output 8000
149```
151`jlpm watch` rebuilds on change during development.
153## License
80cd178Update numbl links and tidy copyJeremy Magland 155Apache-2.0. Built on [numbl](https://numbl.org) and
41c072cjupyterlite-numbl-kernel: MATLAB-syntax kernel for JupyterLiteJeremy Magland 156the [JupyterLite](https://github.com/jupyterlite/jupyterlite) kernel API;
157scaffolding follows the
158[jupyterlite/echo-kernel](https://github.com/jupyterlite/echo-kernel)
159template.
moveopenescclose