mirror of
https://github.com/jupyter/notebook.git
synced 2025-01-06 11:35:24 +08:00
155 lines
4.3 KiB
JavaScript
155 lines
4.3 KiB
JavaScript
|
// Copyright (c) Jupyter Development Team.
|
||
|
// Distributed under the terms of the Modified BSD License.
|
||
|
|
||
|
import { PageConfig, URLExt } from '@jupyterlab/coreutils';
|
||
|
|
||
|
// Promise.allSettled polyfill, until our supported browsers implement it
|
||
|
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
|
||
|
if (Promise.allSettled === undefined) {
|
||
|
Promise.allSettled = promises =>
|
||
|
Promise.all(
|
||
|
promises.map(promise =>
|
||
|
promise.then(
|
||
|
value => ({
|
||
|
status: 'fulfilled',
|
||
|
value
|
||
|
}),
|
||
|
reason => ({
|
||
|
status: 'rejected',
|
||
|
reason
|
||
|
})
|
||
|
)
|
||
|
)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
require('./style.css');
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* The main function
|
||
|
*/
|
||
|
async function main() {
|
||
|
const App = require('@jupyterlab-classic/application').App;
|
||
|
const app = new App();
|
||
|
const mods = [
|
||
|
require('@jupyterlab-classic/application-extension'),
|
||
|
require('@jupyterlab/apputils-extension').default.filter(({ id }) =>
|
||
|
['@jupyterlab/apputils-extension:settings'].includes(id)
|
||
|
),
|
||
|
require('@jupyterlab/codemirror-extension').default.filter(({ id }) =>
|
||
|
['@jupyterlab/codemirror-extension:services'].includes(id)
|
||
|
),
|
||
|
require('@jupyterlab/mainmenu-extension'),
|
||
|
require('@jupyterlab/rendermime-extension'),
|
||
|
require('@jupyterlab/notebook-extension').default.filter(({ id }) =>
|
||
|
[
|
||
|
'@jupyterlab/notebook-extension:factory',
|
||
|
'@jupyterlab/notebook-extension:widget-factory',
|
||
|
'@jupyterlab/notebook-extension:tracker'
|
||
|
].includes(id)
|
||
|
)
|
||
|
];
|
||
|
|
||
|
const extension_data = JSON.parse(
|
||
|
PageConfig.getOption('federated_extensions')
|
||
|
);
|
||
|
|
||
|
const federatedExtensionPromises = [];
|
||
|
const federatedMimeExtensionPromises = [];
|
||
|
const federatedStylePromises = [];
|
||
|
|
||
|
const extensions = await Promise.allSettled(
|
||
|
extension_data.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') {
|
||
|
mods.push(p.value);
|
||
|
} 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);
|
||
|
});
|
||
|
|
||
|
app.registerPluginModules(mods);
|
||
|
|
||
|
await app.start();
|
||
|
}
|
||
|
|
||
|
window.addEventListener('load', main);
|