Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Dec 11, 2024
0 parents commit 002e447
Show file tree
Hide file tree
Showing 291 changed files with 105,829 additions and 0 deletions.
Empty file added .nojekyll
Empty file.
59 changes: 59 additions & 0 deletions PyodideServiceWorker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const appName = 'Lumen'
const appCacheName = 'Lumen-0.7.0b4';

const preCacheFiles = [];

const cachePatterns = ['https://cdn.holoviz.org/panel/1.5.4/dist/', 'https://cdn.bokeh.org/bokeh/', 'https://cdn.jsdelivr.net/pyodide/', 'https://files.pythonhosted.org/packages/', 'https://pypi.org/pypi/'];

self.addEventListener('install', (e) => {
console.log('[Service Worker] Install');
self.skipWaiting();
e.waitUntil((async () => {
const cacheNames = await caches.keys();
for (const cacheName of cacheNames) {
if (cacheName.startsWith(appName) && cacheName !== appCacheName) {
console.log(`[Service Worker] Delete old cache ${cacheName}`);
caches.delete(cacheName);
}
}
const cache = await caches.open(appCacheName);
if (preCacheFiles.length) {
console.log('[Service Worker] Precaching ');
}
preCacheFiles.forEach(async (cacheFile) => {
const request = new Request(cacheFile);
const response = await fetch(request);
if (response.ok || response.type == 'opaque') {
cache.put(request, response);
}
})
})());
});

self.addEventListener('activate', (event) => {
console.log('[Service Worker] Activating');
return self.clients.claim();
});

self.addEventListener('fetch', (e) => {
if (e.request.method !== 'GET') {
return
}
e.respondWith((async () => {
const cache = await caches.open(appCacheName);
let response = await cache.match(e.request);
console.log(`[Service Worker] Fetching resource: ${e.request.url}`);
if (response) {
return response;
}
response = await fetch(e.request);
if (!response.ok && !(response.type == 'opaque')) {
throw Error(`[Service Worker] Fetching resource ${e.request.url} failed with response: ${response.status}`);
}
console.log(`[Service Worker] Caching new resource: ${e.request.url}`);
if (e.request.mode !== 'no-cors') {
cache.put(e.request, response.clone());
}
return response;
})());
});
Binary file added _images/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/bikes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/branch_yaml_00_firstTable.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/branch_yaml_01_finalDashboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/build_app_00.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/build_app_01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/build_app_02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/build_app_03.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/build_app_04.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/build_app_05.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/build_app_06.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/build_app_07.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/builder_dashboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/cli_bad.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/cli_good.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/config_editor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/dashboard_gallery.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/earthquakes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/layout_example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/local_components_app.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/lumen_dashboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/nyc_taxi.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/penguins.png
Binary file added _images/pipeline_diagram.png
Binary file added _images/precip.png
Binary file added _images/seattle.png
Binary file added _images/shell.png
Binary file added _images/source_editor.png
Binary file added _images/source_example.png
Binary file added _images/source_variable.png
Binary file added _images/variable_all.png
Binary file added _images/variable_editor.png
Binary file added _images/variable_selected.png
Binary file added _images/view_editor.png
Binary file added _images/view_example.png
Binary file added _images/yaml_launcher.png
101 changes: 101 additions & 0 deletions _sphinx_design_static/design-tabs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// @ts-check

// Extra JS capability for selected tabs to be synced
// The selection is stored in local storage so that it persists across page loads.

/**
* @type {Record<string, HTMLElement[]>}
*/
let sd_id_to_elements = {};
const storageKeyPrefix = "sphinx-design-tab-id-";

/**
* Create a key for a tab element.
* @param {HTMLElement} el - The tab element.
* @returns {[string, string, string] | null} - The key.
*
*/
function create_key(el) {
let syncId = el.getAttribute("data-sync-id");
let syncGroup = el.getAttribute("data-sync-group");
if (!syncId || !syncGroup) return null;
return [syncGroup, syncId, syncGroup + "--" + syncId];
}

/**
* Initialize the tab selection.
*
*/
function ready() {
// Find all tabs with sync data

/** @type {string[]} */
let groups = [];

document.querySelectorAll(".sd-tab-label").forEach((label) => {
if (label instanceof HTMLElement) {
let data = create_key(label);
if (data) {
let [group, id, key] = data;

// add click event listener
// @ts-ignore
label.onclick = onSDLabelClick;

// store map of key to elements
if (!sd_id_to_elements[key]) {
sd_id_to_elements[key] = [];
}
sd_id_to_elements[key].push(label);

if (groups.indexOf(group) === -1) {
groups.push(group);
// Check if a specific tab has been selected via URL parameter
const tabParam = new URLSearchParams(window.location.search).get(
group
);
if (tabParam) {
console.log(
"sphinx-design: Selecting tab id for group '" +
group +
"' from URL parameter: " +
tabParam
);
window.sessionStorage.setItem(storageKeyPrefix + group, tabParam);
}
}

// Check is a specific tab has been selected previously
let previousId = window.sessionStorage.getItem(
storageKeyPrefix + group
);
if (previousId === id) {
// console.log(
// "sphinx-design: Selecting tab from session storage: " + id
// );
// @ts-ignore
label.previousElementSibling.checked = true;
}
}
}
});
}

/**
* Activate other tabs with the same sync id.
*
* @this {HTMLElement} - The element that was clicked.
*/
function onSDLabelClick() {
let data = create_key(this);
if (!data) return;
let [group, id, key] = data;
for (const label of sd_id_to_elements[key]) {
if (label === this) continue;
// @ts-ignore
label.previousElementSibling.checked = true;
}
window.sessionStorage.setItem(storageKeyPrefix + group, id);
}

document.addEventListener("DOMContentLoaded", ready, false);
1 change: 1 addition & 0 deletions _sphinx_design_static/sphinx-design.min.css

Large diffs are not rendered by default.

224 changes: 224 additions & 0 deletions _static/PyodideWebWorker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
importScripts("https://cdn.jsdelivr.net/pyodide/v0.25.0/full/pyodide.js");

const QUEUE = [];

const REQUIRES = {}

function sendPatch(patch, buffers, cell_id) {
self.postMessage({
type: 'patch',
patch: patch,
buffers: buffers,
id: cell_id
})
}

function sendStdout(cell_id, stdout) {
self.postMessage({
type: 'stdout',
content: stdout,
id: cell_id
})
}
function sendStderr(cell_id, stderr) {
self.postMessage({
type: 'stderr',
content: stderr,
id: cell_id
})
}

async function loadApplication(cell_id, path) {
console.log("Loading pyodide!");
self.pyodide = await loadPyodide();
self.pyodide.globals.set("sendPatch", sendPatch);
self.pyodide.globals.set("sendStdout", sendStdout);
self.pyodide.globals.set("sendStderr", sendStderr);
console.log("Loaded!");
await self.pyodide.loadPackage("micropip");
const packages = ['https://cdn.holoviz.org/panel/1.5.4/dist/wheels/bokeh-3.6.2-py3-none-any.whl', 'https://cdn.holoviz.org/panel/1.5.4/dist/wheels/panel-1.5.4-py3-none-any.whl', 'lumen==0.7.0b4', 'requests', 'pandas', 'pyodide-http', 'holoviews>=1.15.1'];
if (path != null) {
for (const key of Object.keys(REQUIRES)) {
if (path.replace('.html', '').endsWith(key.replace('.md', ''))) {
for (const req of REQUIRES[key]) {
packages.push(req)
}
}
}
}

await self.pyodide.runPythonAsync("")
self.pyodide.runPython("import micropip")
for (const pkg of packages) {
self.postMessage({
type: 'loading',
msg: `Loading ${pkg}`,
id: cell_id
});
await self.pyodide.runPythonAsync(`
await micropip.install('${pkg}', keep_going=True);
`);
}
console.log("Packages loaded!");
}

const autodetect_deps_code = `
import json
try:
from panel.io.mime_render import find_requirements
except Exception:
from panel.io.mime_render import find_imports as find_requirements
json.dumps(find_requirements(msg.to_py()['code']))`

const exec_code = `
from functools import partial
from panel.io.pyodide import pyrender
from js import console
msg = msg.to_py()
code = msg['code']
stdout_cb = partial(sendStdout, msg['id'])
stderr_cb = partial(sendStderr, msg['id'])
target = f"output-{msg['id']}"
pyrender(code, stdout_cb, stderr_cb, target)`

const onload_code = `
msg = msg.to_py()
if msg['mime'] == 'application/bokeh':
from panel.io.pyodide import _link_docs_worker
from panel.io.state import state
doc = state.cache[f"output-{msg['id']}"]
_link_docs_worker(doc, sendPatch, msg['id'], 'js')`

const patch_code = `
from panel import state
try:
from pane.io.pyodide import _convert_json_patch
patch = _convert_json_patch(msg.patch)
except:
patch = msg.patch.to_py()
doc = state.cache[f"output-{msg.id}"]
doc.apply_json_patch(patch, setter='js')`

const MESSAGES = {
patch: patch_code,
execute: exec_code,
rendered: onload_code
}

self.onmessage = async (event) => {
let resolveExecution, rejectExecution;
const executing = new Promise(function(resolve, reject){
resolveExecution = resolve;
rejectExecution = reject;
});

const prev_msg = QUEUE[0]
const msg = {...event.data, executing}
QUEUE.unshift(msg)

if (prev_msg) {
self.postMessage({
type: 'loading',
msg: 'Awaiting previous cells',
id: msg.id
});
await prev_msg.executing
}

// Init pyodide
if (self.pyodide == null) {
self.postMessage({
type: 'loading',
msg: 'Loading pyodide',
id: msg.id
});
await loadApplication(msg.id, msg.path)
self.postMessage({
type: 'loaded',
id: msg.id
});
}

// Handle message
if (!MESSAGES.hasOwnProperty(msg.type)) {
console.warn(`Service worker received unknown message type '${msg.type}'.`)
resolveExecution()
self.postMessage({
type: 'idle',
id: msg.id
});
return
}

if (msg.type === 'execute') {
let deps
try {
self.pyodide.globals.set('msg', msg)
deps = self.pyodide.runPython(autodetect_deps_code)
} catch(e) {
deps = '[]'
console.warn(`Auto-detection of dependencies failed with error: ${e}`)
}
for (const pkg of JSON.parse(deps)) {
self.postMessage({
type: 'loading',
msg: `Loading ${pkg}`,
id: msg.id
});
try {
await self.pyodide.runPythonAsync(`await micropip.install('${pkg}', keep_going=True)`)
} catch(e) {
console.log(`Auto-detected dependency ${pkg} could not be installed.`)
}
}
}

try {
self.pyodide.globals.set('msg', msg)
let out = await self.pyodide.runPythonAsync(MESSAGES[msg.type])
resolveExecution()
if (out == null) {
out = new Map()
}
if (out.has('content')) {
self.postMessage({
type: 'render',
id: msg.id,
content: out.get('content'),
mime: out.get('mime_type')
});
}
if (out.has('stdout') && out.get('stdout').length) {
self.postMessage({
type: 'stdout',
content: out.get('stdout'),
id: msg.id
});
}
if (out.has('stderr') && out.get('stderr').length) {
self.postMessage({
type: 'stderr',
content: out.get('stderr'),
id: msg.id
});
}
self.postMessage({
type: 'idle',
id: msg.id,
uuid: msg.uuid
});
} catch (e) {
const traceback = `${e}`
const tblines = traceback.split('\n')
self.postMessage({
type: 'error',
traceback: traceback,
msg: tblines[tblines.length-2],
id: msg.id
});
resolveExecution()
throw(e)
}
}
Loading

0 comments on commit 002e447

Please sign in to comment.