-
Notifications
You must be signed in to change notification settings - Fork 505
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ee2637a
commit 1063ba1
Showing
13 changed files
with
568 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
/*************************************************************************** | ||
* 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. * | ||
****************************************************************************/ | ||
|
||
// Copyright (c) Jupyter Development Team. | ||
// Distributed under the terms of the Modified BSD License. | ||
|
||
// Inspired by: https://github.com/jupyterlab/jupyterlab/blob/master/dev_mode/index.js | ||
|
||
import './style.css'; | ||
|
||
import { PageConfig, URLExt } from '@jupyterlab/coreutils'; | ||
|
||
import { VoilaApp } from '@voila-dashboards/voila'; | ||
|
||
function loadScript(url) { | ||
return new Promise((resolve, reject) => { | ||
const newScript = document.createElement('script'); | ||
newScript.onerror = reject; | ||
newScript.onload = resolve; | ||
newScript.async = true; | ||
document.head.appendChild(newScript); | ||
newScript.src = url; | ||
}); | ||
} | ||
async function loadComponent(url, scope) { | ||
await loadScript(url); | ||
|
||
// From MIT-licensed https://github.com/module-federation/module-federation-examples/blob/af043acd6be1718ee195b2511adf6011fba4233c/advanced-api/dynamic-remotes/app1/src/App.js#L6-L12 | ||
// eslint-disable-next-line no-undef | ||
await __webpack_init_sharing__('default'); | ||
const container = window._JUPYTERLAB[scope]; | ||
// Initialize the container, it may provide shared modules and may need ours | ||
// eslint-disable-next-line no-undef | ||
await container.init(__webpack_share_scopes__.default); | ||
} | ||
|
||
async function createModule(scope, module) { | ||
try { | ||
const factory = await window._JUPYTERLAB[scope].get(module); | ||
return factory(); | ||
} catch (e) { | ||
console.warn( | ||
`Failed to create module: package: ${scope}; module: ${module}` | ||
); | ||
throw e; | ||
} | ||
} | ||
|
||
const disabled = ['@jupyter-widgets/jupyterlab-manager']; | ||
|
||
/** | ||
* The main function | ||
*/ | ||
async function main() { | ||
let mods = [ | ||
// @jupyterlab plugins | ||
require('@jupyterlab/markdownviewer-extension'), | ||
require('@jupyterlab/mathjax2-extension'), | ||
require('@jupyterlab/rendermime-extension') | ||
// TODO: add the settings endpoint to re-enable the theme plugins? | ||
// This would also need the theme manager plugin and settings | ||
// require('@jupyterlab/theme-light-extension'), | ||
// require('@jupyterlab/theme-dark-extension'), | ||
// require('./plugins') | ||
]; | ||
|
||
const mimeExtensions = [require('@jupyterlab/json-extension')]; | ||
|
||
/** | ||
* Iterate over active plugins in an extension. | ||
* | ||
* #### Notes | ||
* This also populates the disabled | ||
*/ | ||
function* activePlugins(extension) { | ||
// Handle commonjs or es2015 modules | ||
let exports; | ||
if (Object.prototype.hasOwnProperty.call(extension, '__esModule')) { | ||
exports = extension.default; | ||
} else { | ||
// CommonJS exports. | ||
exports = extension; | ||
} | ||
|
||
let plugins = Array.isArray(exports) ? exports : [exports]; | ||
for (let plugin of plugins) { | ||
if ( | ||
PageConfig.Extension.isDisabled(plugin.id) || | ||
disabled.includes(plugin.id) || | ||
disabled.includes(plugin.id.split(':')[0]) | ||
) { | ||
continue; | ||
} | ||
yield plugin; | ||
} | ||
} | ||
|
||
const extensionData = JSON.parse( | ||
PageConfig.getOption('federated_extensions') | ||
); | ||
|
||
const federatedExtensionPromises = []; | ||
const federatedMimeExtensionPromises = []; | ||
const federatedStylePromises = []; | ||
|
||
const extensions = await Promise.allSettled( | ||
extensionData.map(async data => { | ||
await loadComponent( | ||
`${URLExt.join( | ||
PageConfig.getOption('fullLabextensionsUrl'), | ||
data.name, | ||
data.load | ||
)}`, | ||
data.name | ||
); | ||
return data; | ||
}) | ||
); | ||
|
||
extensions.forEach(p => { | ||
if (p.status === 'rejected') { | ||
// There was an error loading the component | ||
console.error(p.reason); | ||
return; | ||
} | ||
|
||
const data = p.value; | ||
if (data.extension) { | ||
federatedExtensionPromises.push(createModule(data.name, data.extension)); | ||
} | ||
if (data.mimeExtension) { | ||
federatedMimeExtensionPromises.push( | ||
createModule(data.name, data.mimeExtension) | ||
); | ||
} | ||
if (data.style) { | ||
federatedStylePromises.push(createModule(data.name, data.style)); | ||
} | ||
}); | ||
|
||
// Add the federated extensions. | ||
const federatedExtensions = await Promise.allSettled( | ||
federatedExtensionPromises | ||
); | ||
federatedExtensions.forEach(p => { | ||
if (p.status === 'fulfilled') { | ||
for (let plugin of activePlugins(p.value)) { | ||
mods.push(plugin); | ||
} | ||
} else { | ||
console.error(p.reason); | ||
} | ||
}); | ||
|
||
// Add the federated mime extensions. | ||
const federatedMimeExtensions = await Promise.allSettled( | ||
federatedMimeExtensionPromises | ||
); | ||
federatedMimeExtensions.forEach(p => { | ||
if (p.status === 'fulfilled') { | ||
for (let plugin of activePlugins(p.value)) { | ||
mimeExtensions.push(plugin); | ||
} | ||
} else { | ||
console.error(p.reason); | ||
} | ||
}); | ||
|
||
// Load all federated component styles and log errors for any that do not | ||
(await Promise.allSettled(federatedStylePromises)) | ||
.filter(({ status }) => status === 'rejected') | ||
.forEach(({ reason }) => { | ||
console.error(reason); | ||
}); | ||
|
||
const app = new VoilaApp({ mimeExtensions }); | ||
app.registerPluginModules(mods); | ||
await app.start(); | ||
|
||
window.jupyterapp = app; | ||
} | ||
|
||
window.addEventListener('load', main); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
{ | ||
"name": "@voila-dashboards/voilite", | ||
"version": "0.4.0-beta.0", | ||
"description": "The Voilite Frontend", | ||
"author": "Voilà contributors", | ||
"license": "BSD-3-Clause", | ||
"main": "lib/index.js", | ||
"browserslist": ">0.8%, not ie 11, not op_mini all, not dead", | ||
"dependencies": { | ||
"@jupyter-widgets/base": "^6.0.1", | ||
"@jupyter-widgets/controls": "^5.0.1", | ||
"@jupyter-widgets/jupyterlab-manager": "^5.0.3", | ||
"@jupyter-widgets/output": "^6.0.1", | ||
"@jupyterlab/application": "^3.0.0", | ||
"@jupyterlab/apputils": "^3.0.0", | ||
"@jupyterlab/coreutils": "^5.0.0", | ||
"@jupyterlab/docregistry": "^3.0.0", | ||
"@jupyterlab/json-extension": "^3.0.0", | ||
"@jupyterlab/logconsole": "^3.0.0", | ||
"@jupyterlab/mainmenu": "^3.0.0", | ||
"@jupyterlab/markdownviewer-extension": "^3.0.0", | ||
"@jupyterlab/mathjax2-extension": "^3.0.0", | ||
"@jupyterlab/nbformat": "^3.0.0", | ||
"@jupyterlab/notebook": "^3.0.0", | ||
"@jupyterlab/outputarea": "^3.0.0", | ||
"@jupyterlab/rendermime": "^3.0.0", | ||
"@jupyterlab/rendermime-extension": "^3.0.0", | ||
"@jupyterlab/services": "^6.1.8", | ||
"@jupyterlab/settingregistry": "^3.0.0", | ||
"@jupyterlab/translation": "^3.0.0", | ||
"@jupyterlab/ui-components": "^3.0.0", | ||
"@lumino/algorithm": "^1.6.2", | ||
"@lumino/commands": "^1.15.2", | ||
"@lumino/coreutils": "^1.8.2", | ||
"@lumino/disposable": "^1.7.2", | ||
"@lumino/domutils": "^1.5.2", | ||
"@lumino/dragdrop": "^1.10.2", | ||
"@lumino/messaging": "^1.7.2", | ||
"@lumino/properties": "^1.5.2", | ||
"@lumino/signaling": "^1.7.2", | ||
"@lumino/virtualdom": "^1.11.2", | ||
"@lumino/widgets": "^1.26.2", | ||
"react": "^17.0.1" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "^7.2.2", | ||
"@babel/preset-env": "^7.3.1", | ||
"@jupyterlab/builder": "^3.0.0", | ||
"@types/node": "^18.8.3", | ||
"babel-loader": "^8.0.5", | ||
"css-loader": "~5.0.2", | ||
"file-loader": "^6.2.0", | ||
"fs-extra": "^9.1.0", | ||
"glob": "~7.1.6", | ||
"mini-css-extract-plugin": "~0.9.0", | ||
"npm-run-all": "^4.1.5", | ||
"p-limit": "^2.2.2", | ||
"raw-loader": "^4.0.2", | ||
"rimraf": "^3.0.2", | ||
"style-loader": "^2.0.0", | ||
"svg-url-loader": "^7.1.1", | ||
"typescript": "~4.1.3", | ||
"url-loader": "^4.1.1", | ||
"watch": "^1.0.2", | ||
"webpack": "^5.24.1", | ||
"webpack-bundle-analyzer": "^4.4.0", | ||
"webpack-cli": "^4.5.0", | ||
"webpack-merge": "^5.7.3", | ||
"whatwg-fetch": "^3.0.0" | ||
}, | ||
"scripts": { | ||
"build": "npm run build:lib && webpack --mode=development", | ||
"build:lib": "tsc", | ||
"build:prod": "npm run build:lib && webpack --mode=production", | ||
"clean": "jlpm run clean:lib && rimraf build", | ||
"clean:lib": "rimraf lib tsconfig.tsbuildinfo", | ||
"test": "echo \"Error: no test specified\" && exit 1", | ||
"watch": "npm-run-all -p watch:*", | ||
"watch:lib": "tsc -w", | ||
"watch:bundle": "webpack --watch --mode=development" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Copyright (c) Jupyter Development Team. | ||
// Distributed under the terms of the Modified BSD License. | ||
|
||
// We dynamically set the webpack public path based on the page config | ||
// settings from the JupyterLab app. We copy some of the pageconfig parsing | ||
// logic in @jupyterlab/coreutils below, since this must run before any other | ||
// files are loaded (including @jupyterlab/coreutils). | ||
|
||
/** | ||
* Get global configuration data for the Jupyter application. | ||
* | ||
* @param name - The name of the configuration option. | ||
* | ||
* @returns The config value or an empty string if not found. | ||
* | ||
* #### Notes | ||
* All values are treated as strings. | ||
* For browser based applications, it is assumed that the page HTML | ||
* includes a script tag with the id `jupyter-config-data` containing the | ||
* configuration as valid JSON. In order to support the classic Notebook, | ||
* we fall back on checking for `body` data of the given `name`. | ||
*/ | ||
function getOption(name) { | ||
let configData = Object.create(null); | ||
// Use script tag if available. | ||
if (typeof document !== 'undefined' && document) { | ||
const el = document.getElementById('jupyter-config-data'); | ||
|
||
if (el) { | ||
configData = JSON.parse(el.textContent || '{}'); | ||
} | ||
} | ||
return configData[name] || ''; | ||
} | ||
|
||
// eslint-disable-next-line no-undef | ||
__webpack_public_path__ = getOption('fullStaticUrl') + '/'; |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
@import url('~@lumino/widgets/style/index.css'); | ||
|
||
@import url('~@jupyter-widgets/controls/css/widgets.built.css'); |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"extends": "../../tsconfigbase", | ||
"compilerOptions": { | ||
"outDir": "lib", | ||
"rootDir": "src", | ||
"types": ["node"] | ||
}, | ||
"include": ["src/**/*"] | ||
} |
Oops, something went wrong.