From 90a48e251ab859516240e9c6c28ebe7dbbff40b3 Mon Sep 17 00:00:00 2001 From: martinRenou Date: Thu, 14 Sep 2023 11:39:29 +0200 Subject: [PATCH] Separate jupyter widgets manager extension --- .github/workflows/build.yml | 1 + .github/workflows/packaging.yml | 1 + .gitignore | 2 +- packages/jupyterlab-preview/package.json | 4 +- packages/voila/package.json | 4 +- packages/voila/src/index.ts | 2 +- packages/voila/src/main.ts | 5 +- .../src/{voilaplugins.ts => plugins/index.ts} | 10 +- .../voila/src/plugins/outputs_rendering.ts | 73 +++++ packages/voila/src/plugins/widget.ts | 157 ---------- packages/voila/src/sharedscope.ts | 8 + packages/voila/src/tree.ts | 6 +- packages/widgets-manager/README.md | 7 + packages/widgets-manager/package.json | 74 +++++ packages/widgets-manager/schema/plugin.json | 16 + packages/widgets-manager/src/index.ts | 108 +++++++ packages/widgets-manager/tsconfig.json | 8 + pyproject.toml | 10 +- voila/__init__.py | 5 +- yarn.lock | 281 +++++++++++++++++- 20 files changed, 595 insertions(+), 187 deletions(-) rename packages/voila/src/{voilaplugins.ts => plugins/index.ts} (78%) create mode 100644 packages/voila/src/plugins/outputs_rendering.ts delete mode 100644 packages/voila/src/plugins/widget.ts create mode 100644 packages/widgets-manager/README.md create mode 100644 packages/widgets-manager/package.json create mode 100644 packages/widgets-manager/schema/plugin.json create mode 100644 packages/widgets-manager/src/index.ts create mode 100644 packages/widgets-manager/tsconfig.json diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8de6e8ccc..d2015a7e0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,6 +32,7 @@ jobs: run: | jupyter nbextension list 2>&1 | grep -ie "voila/extension.*enabled" - jupyter labextension list 2>&1 | grep -ie "@voila-dashboards/jupyterlab-preview.*enabled.*ok" - + jupyter labextension list 2>&1 | grep -ie "@voila-dashboards/widgets-manager.*enabled.*ok" - jupyter server extension list 2>&1 | grep -ie "voila\.server_extension.*enabled" - - name: Browser check diff --git a/.github/workflows/packaging.yml b/.github/workflows/packaging.yml index bc3c1ab07..e974f4b07 100644 --- a/.github/workflows/packaging.yml +++ b/.github/workflows/packaging.yml @@ -95,6 +95,7 @@ jobs: run: | jupyter labextension list jupyter labextension list 2>&1 | grep -ie "@voila-dashboards/jupyterlab-preview.*enabled.*ok" - + jupyter labextension list 2>&1 | grep -ie "@voila-dashboards/widgets-manager.*enabled.*ok" - jupyter server extension list jupyter server extension list 2>&1 | grep -ie "voila.server_extension.*enabled" - jupyter nbextension list diff --git a/.gitignore b/.gitignore index 089503701..1b8b9828e 100644 --- a/.gitignore +++ b/.gitignore @@ -44,7 +44,7 @@ share/jupyter/voila/templates/base/static/*.LICENSE.txt lib -voila/labextension +voila/labextensions tsconfig.tsbuildinfo ui-tests/playwright-report diff --git a/packages/jupyterlab-preview/package.json b/packages/jupyterlab-preview/package.json index f13c8a815..249e00297 100644 --- a/packages/jupyterlab-preview/package.json +++ b/packages/jupyterlab-preview/package.json @@ -38,7 +38,7 @@ "build:prod": "jlpm run build:lib && jlpm run build:labextension", "build:test": "tsc --build tsconfig.test.json", "clean": "jlpm run clean:lib && jlpm run clean:labextension", - "clean:labextension": "rimraf ../../voila/labextension", + "clean:labextension": "rimraf ../../voila/labextensions/jupyterlab-preview", "clean:lib": "rimraf lib tsconfig.tsbuildinfo", "test": "jest", "watch": "run-p watch:src watch:labextension", @@ -75,7 +75,7 @@ "jupyterlab": { "extension": true, "schemaDir": "schema", - "outputDir": "../../voila/labextension", + "outputDir": "../../voila/labextensions/jupyterlab-preview", "discovery": { "server": { "managers": [ diff --git a/packages/voila/package.json b/packages/voila/package.json index ae75c5e60..81d938a11 100644 --- a/packages/voila/package.json +++ b/packages/voila/package.json @@ -7,7 +7,6 @@ "main": "lib/index.js", "browserslist": ">0.8%, not ie 11, not op_mini all, not dead", "dependencies": { - "@jupyter-widgets/base": "^6.0.6", "@jupyter-widgets/jupyterlab-manager": "^5.0.9", "@jupyterlab/application": "^4.0.0", "@jupyterlab/apputils": "^4.0.0", @@ -18,7 +17,7 @@ "@jupyterlab/docregistry": "^4.0.0", "@jupyterlab/javascript-extension": "^4.0.0", "@jupyterlab/json-extension": "^4.0.0", - "@jupyterlab/logconsole": "^4.0.0", + "@jupyterlab/logconsole": "^4.0.5", "@jupyterlab/mainmenu": "^4.0.0", "@jupyterlab/markdownviewer-extension": "^4.0.0", "@jupyterlab/markedparser-extension": "^4.0.0", @@ -43,6 +42,7 @@ "@lumino/domutils": "^2.0.0", "@lumino/dragdrop": "^2.0.0", "@lumino/messaging": "^2.0.0", + "@lumino/polling": "^2.0.0", "@lumino/properties": "^2.0.0", "@lumino/signaling": "^2.0.0", "@lumino/virtualdom": "^2.0.0", diff --git a/packages/voila/src/index.ts b/packages/voila/src/index.ts index a185926a7..16cc66268 100644 --- a/packages/voila/src/index.ts +++ b/packages/voila/src/index.ts @@ -9,7 +9,7 @@ export * from './app'; export * from './shell'; -export * from './voilaplugins'; +export * from './plugins'; export * from './tools'; export * from './plugins/tree/browser'; export * from './plugins/tree/listing'; diff --git a/packages/voila/src/main.ts b/packages/voila/src/main.ts index bcf1089e3..62827ac05 100644 --- a/packages/voila/src/main.ts +++ b/packages/voila/src/main.ts @@ -13,7 +13,7 @@ import './sharedscope'; import { PageConfig, URLExt } from '@jupyterlab/coreutils'; import { VoilaApp } from './app'; -import plugins from './voilaplugins'; +import plugins from './plugins'; import { VoilaServiceManager } from './services/servicemanager'; import { VoilaShell } from './shell'; import { @@ -23,7 +23,7 @@ import { loadComponent } from './tools'; -//Inspired by: https://github.com/jupyterlab/jupyterlab/blob/master/dev_mode/index.js +// Inspired by: https://github.com/jupyterlab/jupyterlab/blob/master/dev_mode/index.js const disabled = [ '@jupyter-widgets/jupyterlab-manager:plugin', @@ -137,6 +137,7 @@ async function main() { }); app.registerPluginModules(mods); await app.start(); + window.jupyterapp = app; } diff --git a/packages/voila/src/voilaplugins.ts b/packages/voila/src/plugins/index.ts similarity index 78% rename from packages/voila/src/voilaplugins.ts rename to packages/voila/src/plugins/index.ts index 7e52e7113..baf4e9423 100644 --- a/packages/voila/src/voilaplugins.ts +++ b/packages/voila/src/plugins/index.ts @@ -8,10 +8,10 @@ ****************************************************************************/ import { JupyterFrontEndPlugin } from '@jupyterlab/application'; -import { pathsPlugin } from './plugins/path'; -import { translatorPlugin } from './plugins/translator'; -import { renderOutputsPlugin, widgetManager } from './plugins/widget'; -import { themePlugin, themesManagerPlugin } from './plugins/themes'; +import { pathsPlugin } from './path'; +import { translatorPlugin } from './translator'; +import { renderOutputsPlugin } from './outputs_rendering'; +import { themePlugin, themesManagerPlugin } from './themes'; /** * Export the plugins as default. @@ -19,7 +19,6 @@ import { themePlugin, themesManagerPlugin } from './plugins/themes'; const plugins: JupyterFrontEndPlugin[] = [ pathsPlugin, translatorPlugin, - widgetManager, renderOutputsPlugin, themesManagerPlugin, themePlugin @@ -30,7 +29,6 @@ export default plugins; export { pathsPlugin, translatorPlugin, - widgetManager, renderOutputsPlugin, themesManagerPlugin, themePlugin diff --git a/packages/voila/src/plugins/outputs_rendering.ts b/packages/voila/src/plugins/outputs_rendering.ts new file mode 100644 index 000000000..454fa211d --- /dev/null +++ b/packages/voila/src/plugins/outputs_rendering.ts @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (c) 2018, Voilà contributors * + * Copyright (c) 2018, QuantStack * + * * + * Distributed under the terms of the BSD 3-Clause License. * + * * + * The full license is in the file LICENSE, distributed with this software. * + ****************************************************************************/ + +import { + JupyterFrontEnd, + JupyterFrontEndPlugin +} from '@jupyterlab/application'; + +import { IRenderMimeRegistry } from '@jupyterlab/rendermime'; + +import { Widget } from '@lumino/widgets'; + +/** + * The plugin that renders outputs. + */ +export const renderOutputsPlugin: JupyterFrontEndPlugin = { + id: '@voila-dashboards/voila:render-outputs', + autoStart: true, + requires: [IRenderMimeRegistry], + activate: (app: JupyterFrontEnd, rendermime: IRenderMimeRegistry): void => { + // This "app.started.then" is a trick to make sure we render the output only when all plugins are loaded + // Not using await here because we want this function to return immediately + // Otherwise it prevents the application to start and resolve the "started" promise... + app.started.then(() => { + // Render outputs + const cellOutputs = document.body.querySelectorAll( + 'script[type="application/vnd.voila.cell-output+json"]' + ); + cellOutputs.forEach(async (cellOutput) => { + const model = JSON.parse(cellOutput.innerHTML); + + const mimeType = rendermime.preferredMimeType(model.data, 'any'); + + if (!mimeType) { + return null; + } + const output = rendermime.createRenderer(mimeType); + output.renderModel(model).catch((error) => { + // Manually append error message to output + const pre = document.createElement('pre'); + pre.textContent = `Javascript Error: ${error.message}`; + output.node.appendChild(pre); + + // Remove mime-type-specific CSS classes + pre.className = 'lm-Widget jp-RenderedText'; + pre.setAttribute('data-mime-type', 'application/vnd.jupyter.stderr'); + }); + + output.addClass('jp-OutputArea-output'); + + if (cellOutput.parentElement) { + const container = cellOutput.parentElement; + + container.removeChild(cellOutput); + + // Attach output + Widget.attach(output, container); + } + }); + const node = document.getElementById('rendered_cells'); + if (node) { + const cells = new Widget({ node }); + app.shell.add(cells, 'main'); + } + }); + } +}; diff --git a/packages/voila/src/plugins/widget.ts b/packages/voila/src/plugins/widget.ts deleted file mode 100644 index 59d579318..000000000 --- a/packages/voila/src/plugins/widget.ts +++ /dev/null @@ -1,157 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2018, Voilà contributors * - * Copyright (c) 2018, QuantStack * - * * - * Distributed under the terms of the BSD 3-Clause License. * - * * - * The full license is in the file LICENSE, distributed with this software. * - ****************************************************************************/ - -import { - JupyterFrontEnd, - JupyterFrontEndPlugin -} from '@jupyterlab/application'; - -import { PageConfig } from '@jupyterlab/coreutils'; - -import { IRenderMimeRegistry } from '@jupyterlab/rendermime'; - -import { KernelAPI, ServerConnection } from '@jupyterlab/services'; - -import { KernelConnection } from '@jupyterlab/services/lib/kernel/default'; - -import { - WidgetRenderer, - KernelWidgetManager -} from '@jupyter-widgets/jupyterlab-manager'; - -import { - IJupyterWidgetRegistry, - IWidgetRegistryData -} from '@jupyter-widgets/base'; - -import { VoilaApp } from '../app'; - -import { Widget } from '@lumino/widgets'; - -const WIDGET_MIMETYPE = 'application/vnd.jupyter.widget-view+json'; - -/** - * The Voila widgets manager plugin. - */ -export const widgetManager: JupyterFrontEndPlugin = { - id: '@voila-dashboards/voila:widget-manager', - autoStart: true, - requires: [IRenderMimeRegistry], - provides: IJupyterWidgetRegistry, - activate: async ( - app: JupyterFrontEnd, - rendermime: IRenderMimeRegistry - ): Promise => { - if (!(app instanceof VoilaApp)) { - throw Error( - 'The Voila Widget Manager plugin must be activated in a VoilaApp' - ); - } - const baseUrl = PageConfig.getBaseUrl(); - const kernelId = PageConfig.getOption('kernelId'); - const serverSettings = ServerConnection.makeSettings({ baseUrl }); - - const model = await KernelAPI.getKernelModel(kernelId, serverSettings); - if (!model) { - return { - registerWidget(data: IWidgetRegistryData): void { - throw Error(`The model for kernel id ${kernelId} does not exist`); - } - }; - } - const kernel = new KernelConnection({ model, serverSettings }); - const manager = new KernelWidgetManager(kernel, rendermime); - app.widgetManager = manager; - - rendermime.removeMimeType(WIDGET_MIMETYPE); - rendermime.addFactory( - { - safe: false, - mimeTypes: [WIDGET_MIMETYPE], - createRenderer: (options) => new WidgetRenderer(options, manager) - }, - -10 - ); - - window.addEventListener('beforeunload', (e) => { - const data = new FormData(); - // it seems if we attach this to early, it will not be called - const matches = document.cookie.match('\\b_xsrf=([^;]*)\\b'); - const xsrfToken = (matches && matches[1]) || ''; - data.append('_xsrf', xsrfToken); - window.navigator.sendBeacon( - `${baseUrl}voila/api/shutdown/${kernel.id}`, - data - ); - kernel.dispose(); - }); - - return { - registerWidget: async (data: IWidgetRegistryData) => { - const manager = await app.widgetManagerPromise.promise; - - manager.register(data); - } - }; - } -}; - -/** - * The plugin that renders outputs. - */ -export const renderOutputsPlugin: JupyterFrontEndPlugin = { - id: '@voila-dashboards/voila:render-outputs', - autoStart: true, - requires: [IRenderMimeRegistry, IJupyterWidgetRegistry], - activate: async ( - app: JupyterFrontEnd, - rendermime: IRenderMimeRegistry - ): Promise => { - // Render outputs - const cellOutputs = document.body.querySelectorAll( - 'script[type="application/vnd.voila.cell-output+json"]' - ); - cellOutputs.forEach(async (cellOutput) => { - const model = JSON.parse(cellOutput.innerHTML); - - const mimeType = rendermime.preferredMimeType(model.data, 'any'); - - if (!mimeType) { - return null; - } - const output = rendermime.createRenderer(mimeType); - output.renderModel(model).catch((error) => { - // Manually append error message to output - const pre = document.createElement('pre'); - pre.textContent = `Javascript Error: ${error.message}`; - output.node.appendChild(pre); - - // Remove mime-type-specific CSS classes - pre.className = 'lm-Widget jp-RenderedText'; - pre.setAttribute('data-mime-type', 'application/vnd.jupyter.stderr'); - }); - - output.addClass('jp-OutputArea-output'); - - if (cellOutput.parentElement) { - const container = cellOutput.parentElement; - - container.removeChild(cellOutput); - - // Attach output - Widget.attach(output, container); - } - }); - const node = document.getElementById('rendered_cells'); - if (node) { - const cells = new Widget({ node }); - app.shell.add(cells, 'main'); - } - } -}; diff --git a/packages/voila/src/sharedscope.ts b/packages/voila/src/sharedscope.ts index 26ac31571..e33db2923 100644 --- a/packages/voila/src/sharedscope.ts +++ b/packages/voila/src/sharedscope.ts @@ -1,3 +1,11 @@ +import '@jupyterlab/application'; +import '@jupyterlab/coreutils'; +import '@jupyterlab/rendermime'; +import '@jupyterlab/services'; +import '@jupyterlab/statedb'; +import '@jupyterlab/notebook'; +import '@jupyterlab/mainmenu'; +import '@jupyterlab/logconsole'; import '@lumino/algorithm'; import '@lumino/application'; import '@lumino/coreutils'; diff --git a/packages/voila/src/tree.ts b/packages/voila/src/tree.ts index 53cbc4cf1..50c6a10b9 100644 --- a/packages/voila/src/tree.ts +++ b/packages/voila/src/tree.ts @@ -22,9 +22,8 @@ import { pathsPlugin, themePlugin, themesManagerPlugin, - translatorPlugin, - widgetManager -} from './voilaplugins'; + translatorPlugin +} from './plugins'; export const TREE_DISABLED_EXTENSIONS = [ '@jupyter-widgets/jupyterlab-manager:plugin', @@ -45,7 +44,6 @@ async function main() { pathsPlugin, translatorPlugin, themePlugin, - widgetManager, themesManagerPlugin, treeWidgetPlugin ]; diff --git a/packages/widgets-manager/README.md b/packages/widgets-manager/README.md new file mode 100644 index 000000000..1e97cf70f --- /dev/null +++ b/packages/widgets-manager/README.md @@ -0,0 +1,7 @@ +# @voila-dashboards/jupyterlab-preview + +A JupyterLab preview extension for Voilà. + +## Prerequisites + +- JupyterLab 1.0+ diff --git a/packages/widgets-manager/package.json b/packages/widgets-manager/package.json new file mode 100644 index 000000000..ffbd6c9ac --- /dev/null +++ b/packages/widgets-manager/package.json @@ -0,0 +1,74 @@ +{ + "name": "@voila-dashboards/widgets-manager", + "version": "0.1.0", + "description": "The Voilà jupyter-widgets manager", + "keywords": [ + "jupyter", + "jupyterlab", + "jupyterlab-extension" + ], + "homepage": "https://github.com/voila-dashboards/voila", + "bugs": { + "url": "https://github.com/voila-dashboards/voila/issues" + }, + "license": "BSD-3-Clause", + "author": "Voilà contributors", + "files": [ + "lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}", + "schema/*.json" + ], + "main": "lib/index.js", + "types": "lib/index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/voila-dashboards/voila.git" + }, + "scripts": { + "build": "jlpm run build:lib && jlpm run build:labextension:dev", + "build:labextension": "jupyter labextension build .", + "build:labextension:dev": "jupyter labextension build --development True .", + "build:lib": "tsc", + "build:prod": "jlpm run build:lib && jlpm run build:labextension", + "build:test": "tsc --build tsconfig.test.json", + "clean": "jlpm run clean:lib && jlpm run clean:labextension", + "clean:labextension": "rimraf ../../voila/labextensions/widgets-manager", + "clean:lib": "rimraf lib tsconfig.tsbuildinfo", + "test": "jest", + "watch": "run-p watch:src watch:labextension", + "watch:labextension": "jupyter labextension watch .", + "watch:src": "tsc -w" + }, + "dependencies": { + "@jupyter-widgets/base": "^6.0.6", + "@jupyter-widgets/jupyterlab-manager": "^5.0.9", + "@jupyterlab/application": "^4.0.0", + "@jupyterlab/coreutils": "^6.0.5", + "@jupyterlab/rendermime": "^4.0.0", + "@jupyterlab/services": "^7.0.0", + "@voila-dashboards/voila": "^0.5" + }, + "devDependencies": { + "@babel/core": "^7.10.2", + "@babel/preset-env": "^7.10.2", + "@jupyterlab/builder": "^4.0.0", + "@jupyterlab/testutils": "^4.0.0", + "npm-run-all": "^4.1.5", + "rimraf": "^2.6.1", + "source-map-loader": "~1.0.2", + "typescript": "~5.0.2" + }, + "jupyterlab": { + "extension": true, + "outputDir": "../../voila/labextensions/widgets-manager", + "sharedPackages": { + "@jupyter-widgets/base": { + "bundled": false, + "singleton": true + }, + "@jupyter-widgets/jupyterlab-manager": { + "bundled": false, + "singleton": true + } + } + } +} diff --git a/packages/widgets-manager/schema/plugin.json b/packages/widgets-manager/schema/plugin.json new file mode 100644 index 000000000..7170ad94a --- /dev/null +++ b/packages/widgets-manager/schema/plugin.json @@ -0,0 +1,16 @@ +{ + "jupyter.lab.setting-icon-class": "jp-VoilaIcon", + "jupyter.lab.setting-icon-label": "Voilà Preview", + "title": "Voilà Preview", + "description": "Voilà Preview Extension", + "properties": { + "renderOnSave": { + "title": "Render Preview on Save", + "description": "Render the Voilà preview automatically after saving the notebook", + "default": false, + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object" +} diff --git a/packages/widgets-manager/src/index.ts b/packages/widgets-manager/src/index.ts new file mode 100644 index 000000000..d7859ccdd --- /dev/null +++ b/packages/widgets-manager/src/index.ts @@ -0,0 +1,108 @@ +/*************************************************************************** + * Copyright (c) 2018, Voilà contributors * + * Copyright (c) 2018, QuantStack * + * * + * Distributed under the terms of the BSD 3-Clause License. * + * * + * The full license is in the file LICENSE, distributed with this software. * + ****************************************************************************/ + +import { + JupyterFrontEnd, + JupyterFrontEndPlugin +} from '@jupyterlab/application'; + +import { PageConfig } from '@jupyterlab/coreutils'; + +import { IRenderMimeRegistry } from '@jupyterlab/rendermime'; + +import { + KernelConnection, + KernelAPI, + ServerConnection +} from '@jupyterlab/services'; + +import { + WidgetRenderer, + KernelWidgetManager +} from '@jupyter-widgets/jupyterlab-manager'; + +import { + IJupyterWidgetRegistry, + IWidgetRegistryData +} from '@jupyter-widgets/base'; + +import { VoilaApp } from '@voila-dashboards/voila'; + +const WIDGET_MIMETYPE = 'application/vnd.jupyter.widget-view+json'; + +/** + * The Voila widgets manager plugin. + */ +export const widgetManagerPlugin: JupyterFrontEndPlugin = + { + id: '@voila-dashboards/voila:widget-manager', + autoStart: true, + requires: [IRenderMimeRegistry], + provides: IJupyterWidgetRegistry, + activate: async ( + app: JupyterFrontEnd, + rendermime: IRenderMimeRegistry + ): Promise => { + if (!(app instanceof VoilaApp)) { + throw Error( + 'The Voila Widget Manager plugin must be activated in a VoilaApp' + ); + } + const baseUrl = PageConfig.getBaseUrl(); + const kernelId = PageConfig.getOption('kernelId'); + const serverSettings = ServerConnection.makeSettings({ baseUrl }); + + const model = await KernelAPI.getKernelModel(kernelId, serverSettings); + if (!model) { + return { + registerWidget(data: IWidgetRegistryData): void { + throw Error(`The model for kernel id ${kernelId} does not exist`); + } + }; + } + const kernel = new KernelConnection({ model, serverSettings }); + const manager = new KernelWidgetManager(kernel, rendermime); + app.widgetManager = manager; + + rendermime.removeMimeType(WIDGET_MIMETYPE); + rendermime.addFactory( + { + safe: false, + mimeTypes: [WIDGET_MIMETYPE], + createRenderer: (options) => new WidgetRenderer(options, manager) + }, + -10 + ); + + window.addEventListener('beforeunload', (e) => { + const data = new FormData(); + // it seems if we attach this to early, it will not be called + const matches = document.cookie.match('\\b_xsrf=([^;]*)\\b'); + const xsrfToken = (matches && matches[1]) || ''; + data.append('_xsrf', xsrfToken); + window.navigator.sendBeacon( + `${baseUrl}voila/api/shutdown/${kernel.id}`, + data + ); + kernel.dispose(); + }); + + return { + registerWidget: async (data: IWidgetRegistryData) => { + const manager = await app.widgetManagerPromise.promise; + + manager.register(data); + } + }; + } + }; + +const plugins: JupyterFrontEndPlugin[] = [widgetManagerPlugin]; + +export default plugins; diff --git a/packages/widgets-manager/tsconfig.json b/packages/widgets-manager/tsconfig.json new file mode 100644 index 000000000..399b75b7a --- /dev/null +++ b/packages/widgets-manager/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfigbase", + "compilerOptions": { + "outDir": "lib", + "rootDir": "src" + }, + "include": ["src/**/*"] +} diff --git a/pyproject.toml b/pyproject.toml index 1d9f96b78..0b2d52b8b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -88,7 +88,8 @@ path = "voila/_version.py" [tool.hatch.build] artifacts = [ - "voila/labextension", + "voila/labextensions/jupyterlab-preview", + "voila/labextensions/widgets-manager", "share/jupyter/voila/templates", "share/jupyter/voila/schemas", "share/jupyter/voila/themes" @@ -99,7 +100,8 @@ path = "hatch_build.py" [tool.hatch.build.targets.wheel.shared-data] "etc/jupyter" = "etc/jupyter" -"voila/labextension" = "share/jupyter/labextensions/@voila-dashboards/jupyterlab-preview" +"voila/labextensions/jupyterlab-preview" = "share/jupyter/labextensions/@voila-dashboards/jupyterlab-preview" +"voila/labextensions/widgets-manager" = "share/jupyter/labextensions/@voila-dashboards/widgets-manager" "install.json" = "share/jupyter/labextensions/@voila-dashboards/jupyterlab-preview/install.json" "share/jupyter/voila/templates" = "share/jupyter/voila/templates" "share/jupyter/voila/schemas" = "share/jupyter/voila/schemas" @@ -117,13 +119,13 @@ dependencies = [ ] build-function = "hatch_jupyter_builder.npm_builder" ensured-targets = [ - "voila/labextension/static/style.js", + "voila/labextensions/jupyterlab-preview/static/style.js", "share/jupyter/voila/templates/base/static/materialcolors.css", "share/jupyter/voila/templates/base/static/labvariables.css", "share/jupyter/voila/themes/@jupyterlab/theme-dark-extension/index.css" ] skip-if-exists = [ - "voila/labextension/static/style.js", + "voila/labextensions/jupyterlab-preview/static/style.js", "share/jupyter/voila/templates/base/static/materialcolors.css", "share/jupyter/voila/templates/base/static/labvariables.css", "share/jupyter/voila/themes/@jupyterlab/theme-dark-extension/index.css" diff --git a/voila/__init__.py b/voila/__init__.py index 73d8004f0..4a1184902 100644 --- a/voila/__init__.py +++ b/voila/__init__.py @@ -27,4 +27,7 @@ def _jupyter_nbextension_paths(): def _jupyter_labextension_paths(): - return [{"src": "labextension", "dest": "@voila-dashboards/jupyterlab-preview"}] + return [ + {"src": "labextensions/jupyterlab-preview", "dest": "@voila-dashboards/jupyterlab-preview"}, + {"src": "labextensions/widgets-manager", "dest": "@voila-dashboards/widgets-manager"}, + ] diff --git a/yarn.lock b/yarn.lock index b683750e2..f8ade0007 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2416,6 +2416,35 @@ __metadata: languageName: node linkType: hard +"@jupyterlab/apputils@npm:^4.1.5": + version: 4.1.5 + resolution: "@jupyterlab/apputils@npm:4.1.5" + dependencies: + "@jupyterlab/coreutils": ^6.0.5 + "@jupyterlab/observables": ^5.0.5 + "@jupyterlab/rendermime-interfaces": ^3.8.5 + "@jupyterlab/services": ^7.0.5 + "@jupyterlab/settingregistry": ^4.0.5 + "@jupyterlab/statedb": ^4.0.5 + "@jupyterlab/statusbar": ^4.0.5 + "@jupyterlab/translation": ^4.0.5 + "@jupyterlab/ui-components": ^4.0.5 + "@lumino/algorithm": ^2.0.1 + "@lumino/commands": ^2.1.3 + "@lumino/coreutils": ^2.1.2 + "@lumino/disposable": ^2.1.2 + "@lumino/domutils": ^2.0.1 + "@lumino/messaging": ^2.0.1 + "@lumino/signaling": ^2.1.2 + "@lumino/virtualdom": ^2.0.1 + "@lumino/widgets": ^2.3.0 + "@types/react": ^18.0.26 + react: ^18.2.0 + sanitize-html: ~2.7.3 + checksum: b569303e8b38173de8612a3c04bac349f25c151bbb83b4f594311d679896aed37ba1467e9ff123e605c0d5400c89cf0d66fce697440ea07fff9dd4a408148e2f + languageName: node + linkType: hard + "@jupyterlab/attachments@npm:^4.0.3": version: 4.0.3 resolution: "@jupyterlab/attachments@npm:4.0.3" @@ -2610,6 +2639,20 @@ __metadata: languageName: node linkType: hard +"@jupyterlab/coreutils@npm:^6.0.5": + version: 6.0.5 + resolution: "@jupyterlab/coreutils@npm:6.0.5" + dependencies: + "@lumino/coreutils": ^2.1.2 + "@lumino/disposable": ^2.1.2 + "@lumino/signaling": ^2.1.2 + minimist: ~1.2.0 + path-browserify: ^1.0.0 + url-parse: ~1.5.4 + checksum: c09be7c8f389bb7f019fb868acfc528a0bc553a7b091412b7e0bfb1d0f2c71223ada8d6972d42df25fb6f70be21ecac00703e12d1df62a44dc2a512baac54dac + languageName: node + linkType: hard + "@jupyterlab/docmanager@npm:^4.0.3": version: 4.0.3 resolution: "@jupyterlab/docmanager@npm:4.0.3" @@ -2761,7 +2804,7 @@ __metadata: languageName: node linkType: hard -"@jupyterlab/logconsole@npm:^3.0.0 || ^4.0.0, @jupyterlab/logconsole@npm:^4.0.0": +"@jupyterlab/logconsole@npm:^3.0.0 || ^4.0.0": version: 4.0.3 resolution: "@jupyterlab/logconsole@npm:4.0.3" dependencies: @@ -2780,6 +2823,25 @@ __metadata: languageName: node linkType: hard +"@jupyterlab/logconsole@npm:^4.0.5": + version: 4.0.5 + resolution: "@jupyterlab/logconsole@npm:4.0.5" + dependencies: + "@jupyterlab/coreutils": ^6.0.5 + "@jupyterlab/nbformat": ^4.0.5 + "@jupyterlab/outputarea": ^4.0.5 + "@jupyterlab/rendermime": ^4.0.5 + "@jupyterlab/services": ^7.0.5 + "@jupyterlab/translation": ^4.0.5 + "@lumino/coreutils": ^2.1.2 + "@lumino/disposable": ^2.1.2 + "@lumino/messaging": ^2.0.1 + "@lumino/signaling": ^2.1.2 + "@lumino/widgets": ^2.3.0 + checksum: e18e395e38ce3994c2a5ccc637a6a2bf2beeb3e8b727f0aa5d8c816e47a1ffbb681af592596e55fb67cf2e66f7d05ce6e969cf7983d9d41d5a98832dcfed2ec5 + languageName: node + linkType: hard + "@jupyterlab/lsp@npm:^4.0.3": version: 4.0.3 resolution: "@jupyterlab/lsp@npm:4.0.3" @@ -2885,6 +2947,15 @@ __metadata: languageName: node linkType: hard +"@jupyterlab/nbformat@npm:^4.0.5": + version: 4.0.5 + resolution: "@jupyterlab/nbformat@npm:4.0.5" + dependencies: + "@lumino/coreutils": ^2.1.2 + checksum: 51611e95e6b16dc3e952b731e0ef036d1e0f7eec497555e3bf8394f181da4184dc37c6b25a1b11b5ea031f22fd4b9602fb6a2e675d65fddc2ccb099236cf3e01 + languageName: node + linkType: hard + "@jupyterlab/notebook@npm:^3.0.0 || ^4.0.0, @jupyterlab/notebook@npm:^4.0.0, @jupyterlab/notebook@npm:^4.0.3": version: 4.0.3 resolution: "@jupyterlab/notebook@npm:4.0.3" @@ -2934,6 +3005,19 @@ __metadata: languageName: node linkType: hard +"@jupyterlab/observables@npm:^5.0.5": + version: 5.0.5 + resolution: "@jupyterlab/observables@npm:5.0.5" + dependencies: + "@lumino/algorithm": ^2.0.1 + "@lumino/coreutils": ^2.1.2 + "@lumino/disposable": ^2.1.2 + "@lumino/messaging": ^2.0.1 + "@lumino/signaling": ^2.1.2 + checksum: e94d5a187a356f19db176d16a93e2b380c245a8bcf54eb283b405fc9a39cc937b790a0684defadd0eb103359838751d0184c23c5816c5fc36b86c90e2cbb96b9 + languageName: node + linkType: hard + "@jupyterlab/outputarea@npm:^3.0.0 || ^4.0.0, @jupyterlab/outputarea@npm:^4.0.0, @jupyterlab/outputarea@npm:^4.0.3": version: 4.0.3 resolution: "@jupyterlab/outputarea@npm:4.0.3" @@ -2956,6 +3040,28 @@ __metadata: languageName: node linkType: hard +"@jupyterlab/outputarea@npm:^4.0.5": + version: 4.0.5 + resolution: "@jupyterlab/outputarea@npm:4.0.5" + dependencies: + "@jupyterlab/apputils": ^4.1.5 + "@jupyterlab/nbformat": ^4.0.5 + "@jupyterlab/observables": ^5.0.5 + "@jupyterlab/rendermime": ^4.0.5 + "@jupyterlab/rendermime-interfaces": ^3.8.5 + "@jupyterlab/services": ^7.0.5 + "@jupyterlab/translation": ^4.0.5 + "@lumino/algorithm": ^2.0.1 + "@lumino/coreutils": ^2.1.2 + "@lumino/disposable": ^2.1.2 + "@lumino/messaging": ^2.0.1 + "@lumino/properties": ^2.0.1 + "@lumino/signaling": ^2.1.2 + "@lumino/widgets": ^2.3.0 + checksum: fc7f49b09ad8104fd0ac022366877eee228beb63f237afa76e785e170cb17e9ae18a686e7ac09f5f74bf25735ebc089812ea9374cc7920f4a0a641b9d565a046 + languageName: node + linkType: hard + "@jupyterlab/rendermime-extension@npm:^4.0.0": version: 4.0.3 resolution: "@jupyterlab/rendermime-extension@npm:4.0.3" @@ -2989,6 +3095,16 @@ __metadata: languageName: node linkType: hard +"@jupyterlab/rendermime-interfaces@npm:^3.8.5": + version: 3.8.5 + resolution: "@jupyterlab/rendermime-interfaces@npm:3.8.5" + dependencies: + "@lumino/coreutils": ^1.11.0 || ^2.1.2 + "@lumino/widgets": ^1.37.2 || ^2.3.0 + checksum: 3824c1aa0fa4b946211fd342ff73b0ebc7722dfeaf9794a8c64740dcc53151c0e6b81468f92d83fbe9a6da75d54fe4b176bd3ec98e1a526b50bbc0f91057c1aa + languageName: node + linkType: hard + "@jupyterlab/rendermime@npm:^3.0.0 || ^4.0.0, @jupyterlab/rendermime@npm:^4.0.0, @jupyterlab/rendermime@npm:^4.0.3": version: 4.0.3 resolution: "@jupyterlab/rendermime@npm:4.0.3" @@ -3009,6 +3125,26 @@ __metadata: languageName: node linkType: hard +"@jupyterlab/rendermime@npm:^4.0.5": + version: 4.0.5 + resolution: "@jupyterlab/rendermime@npm:4.0.5" + dependencies: + "@jupyterlab/apputils": ^4.1.5 + "@jupyterlab/coreutils": ^6.0.5 + "@jupyterlab/nbformat": ^4.0.5 + "@jupyterlab/observables": ^5.0.5 + "@jupyterlab/rendermime-interfaces": ^3.8.5 + "@jupyterlab/services": ^7.0.5 + "@jupyterlab/translation": ^4.0.5 + "@lumino/coreutils": ^2.1.2 + "@lumino/messaging": ^2.0.1 + "@lumino/signaling": ^2.1.2 + "@lumino/widgets": ^2.3.0 + lodash.escape: ^4.0.1 + checksum: 472e25ebdee77599a90fef33402ef7c8f05d3c5266c9617805602b4e26022962e8973d55ab0b11bc24982c3aea1dc7d0b151064c822c2d1093111c17e87d1e80 + languageName: node + linkType: hard + "@jupyterlab/services@npm:^6.0.0 || ^7.0.0, @jupyterlab/services@npm:^7.0.0, @jupyterlab/services@npm:^7.0.3": version: 7.0.3 resolution: "@jupyterlab/services@npm:7.0.3" @@ -3028,6 +3164,25 @@ __metadata: languageName: node linkType: hard +"@jupyterlab/services@npm:^7.0.5": + version: 7.0.5 + resolution: "@jupyterlab/services@npm:7.0.5" + dependencies: + "@jupyter/ydoc": ^1.0.2 + "@jupyterlab/coreutils": ^6.0.5 + "@jupyterlab/nbformat": ^4.0.5 + "@jupyterlab/settingregistry": ^4.0.5 + "@jupyterlab/statedb": ^4.0.5 + "@lumino/coreutils": ^2.1.2 + "@lumino/disposable": ^2.1.2 + "@lumino/polling": ^2.1.2 + "@lumino/properties": ^2.0.1 + "@lumino/signaling": ^2.1.2 + ws: ^8.11.0 + checksum: cf4176dbb73c08e777b5e6ca26cba6ad7a142fc76ae6b46ef17ac7d8c8021f62d66e95e2ee0dbce5c33a0b2380750d440783d0398d787b8e8028920e04dd1d0b + languageName: node + linkType: hard + "@jupyterlab/settingregistry@npm:^3.0.0 || ^4.0.0, @jupyterlab/settingregistry@npm:^4.0.0, @jupyterlab/settingregistry@npm:^4.0.3": version: 4.0.3 resolution: "@jupyterlab/settingregistry@npm:4.0.3" @@ -3047,6 +3202,25 @@ __metadata: languageName: node linkType: hard +"@jupyterlab/settingregistry@npm:^4.0.5": + version: 4.0.5 + resolution: "@jupyterlab/settingregistry@npm:4.0.5" + dependencies: + "@jupyterlab/nbformat": ^4.0.5 + "@jupyterlab/statedb": ^4.0.5 + "@lumino/commands": ^2.1.3 + "@lumino/coreutils": ^2.1.2 + "@lumino/disposable": ^2.1.2 + "@lumino/signaling": ^2.1.2 + "@rjsf/utils": ^5.1.0 + ajv: ^8.12.0 + json5: ^2.2.3 + peerDependencies: + react: ">=16" + checksum: b7d686e0f9629f25f423fbd114e598f5af2ae1cc7b683f3e236ff8c94f6d05b20e13ee4555e0eba6277b58fbcdf3c75dbcd66d4e79884b49bed649372d871540 + languageName: node + linkType: hard + "@jupyterlab/statedb@npm:^4.0.3": version: 4.0.3 resolution: "@jupyterlab/statedb@npm:4.0.3" @@ -3060,6 +3234,19 @@ __metadata: languageName: node linkType: hard +"@jupyterlab/statedb@npm:^4.0.5": + version: 4.0.5 + resolution: "@jupyterlab/statedb@npm:4.0.5" + dependencies: + "@lumino/commands": ^2.1.3 + "@lumino/coreutils": ^2.1.2 + "@lumino/disposable": ^2.1.2 + "@lumino/properties": ^2.0.1 + "@lumino/signaling": ^2.1.2 + checksum: 8e01de74a2168d19124773fa2b72329cfb43601c702127845a4172e87ee67b1304d34f53f65a6db214d832bd8c244c333936a22e08bbf1ea02e458e245140f62 + languageName: node + linkType: hard + "@jupyterlab/statusbar@npm:^4.0.3": version: 4.0.3 resolution: "@jupyterlab/statusbar@npm:4.0.3" @@ -3076,6 +3263,22 @@ __metadata: languageName: node linkType: hard +"@jupyterlab/statusbar@npm:^4.0.5": + version: 4.0.5 + resolution: "@jupyterlab/statusbar@npm:4.0.5" + dependencies: + "@jupyterlab/ui-components": ^4.0.5 + "@lumino/algorithm": ^2.0.1 + "@lumino/coreutils": ^2.1.2 + "@lumino/disposable": ^2.1.2 + "@lumino/messaging": ^2.0.1 + "@lumino/signaling": ^2.1.2 + "@lumino/widgets": ^2.3.0 + react: ^18.2.0 + checksum: eac3bc5cc191885fe0fb35466a015ecd8df103a38bc8fac0e2a2c0c7bc783d47e43a31679f83777c0a059091988d9dd2e191624c774fd32cb80c05f2d1166163 + languageName: node + linkType: hard + "@jupyterlab/testing@npm:^4.0.3": version: 4.0.3 resolution: "@jupyterlab/testing@npm:4.0.3" @@ -3170,6 +3373,19 @@ __metadata: languageName: node linkType: hard +"@jupyterlab/translation@npm:^4.0.5": + version: 4.0.5 + resolution: "@jupyterlab/translation@npm:4.0.5" + dependencies: + "@jupyterlab/coreutils": ^6.0.5 + "@jupyterlab/rendermime-interfaces": ^3.8.5 + "@jupyterlab/services": ^7.0.5 + "@jupyterlab/statedb": ^4.0.5 + "@lumino/coreutils": ^2.1.2 + checksum: ba879b7ed27f9398f409333624f679ad4c6d02f668a832eb7ee0cc27998e17d12938192dc32cdf74eff9c1b76116215543b1218093c32717d465568794b49660 + languageName: node + linkType: hard + "@jupyterlab/ui-components@npm:^4.0.0, @jupyterlab/ui-components@npm:^4.0.3": version: 4.0.3 resolution: "@jupyterlab/ui-components@npm:4.0.3" @@ -3199,6 +3415,35 @@ __metadata: languageName: node linkType: hard +"@jupyterlab/ui-components@npm:^4.0.5": + version: 4.0.5 + resolution: "@jupyterlab/ui-components@npm:4.0.5" + dependencies: + "@jupyterlab/coreutils": ^6.0.5 + "@jupyterlab/observables": ^5.0.5 + "@jupyterlab/rendermime-interfaces": ^3.8.5 + "@jupyterlab/translation": ^4.0.5 + "@lumino/algorithm": ^2.0.1 + "@lumino/commands": ^2.1.3 + "@lumino/coreutils": ^2.1.2 + "@lumino/disposable": ^2.1.2 + "@lumino/messaging": ^2.0.1 + "@lumino/polling": ^2.1.2 + "@lumino/properties": ^2.0.1 + "@lumino/signaling": ^2.1.2 + "@lumino/virtualdom": ^2.0.1 + "@lumino/widgets": ^2.3.0 + "@rjsf/core": ^5.1.0 + "@rjsf/utils": ^5.1.0 + react: ^18.2.0 + react-dom: ^18.2.0 + typestyle: ^2.0.4 + peerDependencies: + react: ^18.2.0 + checksum: 4dfae7b37d7e7b58b83bdc75d260126fcdabfb9fd52cc3f04e3bf3c481c8f05c3b3323953389408f793ec7ec6580fd582667a83ab906a308361f0f20f766ad7a + languageName: node + linkType: hard + "@jupyterlab/vega5-extension@npm:^4.0.0": version: 4.0.3 resolution: "@jupyterlab/vega5-extension@npm:4.0.3" @@ -4208,7 +4453,7 @@ __metadata: languageName: node linkType: hard -"@lumino/coreutils@npm:^1.11.0 || ^2.0.0, @lumino/coreutils@npm:^1.11.0 || ^2.1.1, @lumino/coreutils@npm:^1.11.1 || ^2, @lumino/coreutils@npm:^1.11.1 || ^2.1, @lumino/coreutils@npm:^2.0.0, @lumino/coreutils@npm:^2.1.0, @lumino/coreutils@npm:^2.1.1, @lumino/coreutils@npm:^2.1.2": +"@lumino/coreutils@npm:^1.11.0 || ^2.0.0, @lumino/coreutils@npm:^1.11.0 || ^2.1.1, @lumino/coreutils@npm:^1.11.0 || ^2.1.2, @lumino/coreutils@npm:^1.11.1 || ^2, @lumino/coreutils@npm:^1.11.1 || ^2.1, @lumino/coreutils@npm:^2.0.0, @lumino/coreutils@npm:^2.1.0, @lumino/coreutils@npm:^2.1.1, @lumino/coreutils@npm:^2.1.2": version: 2.1.2 resolution: "@lumino/coreutils@npm:2.1.2" checksum: 7865317ac0676b448d108eb57ab5d8b2a17c101995c0f7a7106662d9fe6c859570104525f83ee3cda12ae2e326803372206d6f4c1f415a5b59e4158a7b81066f @@ -4292,7 +4537,7 @@ __metadata: languageName: node linkType: hard -"@lumino/polling@npm:^2.1.1": +"@lumino/polling@npm:^2.0.0, @lumino/polling@npm:^2.1.1, @lumino/polling@npm:^2.1.2": version: 2.1.2 resolution: "@lumino/polling@npm:2.1.2" dependencies: @@ -4336,7 +4581,7 @@ __metadata: languageName: node linkType: hard -"@lumino/widgets@npm:^1.30.0 || ^2.1, @lumino/widgets@npm:^1.37.2 || ^2.1.1, @lumino/widgets@npm:^2.0.0, @lumino/widgets@npm:^2.1.1, @lumino/widgets@npm:^2.3.0": +"@lumino/widgets@npm:^1.30.0 || ^2.1, @lumino/widgets@npm:^1.37.2 || ^2.1.1, @lumino/widgets@npm:^1.37.2 || ^2.3.0, @lumino/widgets@npm:^2.0.0, @lumino/widgets@npm:^2.1.1, @lumino/widgets@npm:^2.3.0": version: 2.3.0 resolution: "@lumino/widgets@npm:2.3.0" dependencies: @@ -5203,11 +5448,10 @@ __metadata: languageName: unknown linkType: soft -"@voila-dashboards/voila@workspace:packages/voila": +"@voila-dashboards/voila@^0.5, @voila-dashboards/voila@workspace:packages/voila": version: 0.0.0-use.local resolution: "@voila-dashboards/voila@workspace:packages/voila" dependencies: - "@jupyter-widgets/base": ^6.0.6 "@jupyter-widgets/jupyterlab-manager": ^5.0.9 "@jupyterlab/application": ^4.0.0 "@jupyterlab/apputils": ^4.0.0 @@ -5219,7 +5463,7 @@ __metadata: "@jupyterlab/docregistry": ^4.0.0 "@jupyterlab/javascript-extension": ^4.0.0 "@jupyterlab/json-extension": ^4.0.0 - "@jupyterlab/logconsole": ^4.0.0 + "@jupyterlab/logconsole": ^4.0.5 "@jupyterlab/mainmenu": ^4.0.0 "@jupyterlab/markdownviewer-extension": ^4.0.0 "@jupyterlab/markedparser-extension": ^4.0.0 @@ -5244,6 +5488,7 @@ __metadata: "@lumino/domutils": ^2.0.0 "@lumino/dragdrop": ^2.0.0 "@lumino/messaging": ^2.0.0 + "@lumino/polling": ^2.0.0 "@lumino/properties": ^2.0.0 "@lumino/signaling": ^2.0.0 "@lumino/virtualdom": ^2.0.0 @@ -5270,6 +5515,28 @@ __metadata: languageName: unknown linkType: soft +"@voila-dashboards/widgets-manager@workspace:packages/widgets-manager": + version: 0.0.0-use.local + resolution: "@voila-dashboards/widgets-manager@workspace:packages/widgets-manager" + dependencies: + "@babel/core": ^7.10.2 + "@babel/preset-env": ^7.10.2 + "@jupyter-widgets/base": ^6.0.6 + "@jupyter-widgets/jupyterlab-manager": ^5.0.9 + "@jupyterlab/application": ^4.0.0 + "@jupyterlab/builder": ^4.0.0 + "@jupyterlab/coreutils": ^6.0.5 + "@jupyterlab/rendermime": ^4.0.0 + "@jupyterlab/services": ^7.0.0 + "@jupyterlab/testutils": ^4.0.0 + "@voila-dashboards/voila": ^0.5 + npm-run-all: ^4.1.5 + rimraf: ^2.6.1 + source-map-loader: ~1.0.2 + typescript: ~5.0.2 + languageName: unknown + linkType: soft + "@webassemblyjs/ast@npm:1.11.6, @webassemblyjs/ast@npm:^1.11.5": version: 1.11.6 resolution: "@webassemblyjs/ast@npm:1.11.6"