// Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. import { JupyterLab } from '@jupyterlab/application'; 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, })) ) ); } import('./style.js'); 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 entry point for the application. */ export async function main() { const disabled = []; const deferred = []; const ignorePlugins = []; const pluginsToRegister = []; const federatedExtensionPromises = []; const federatedMimeExtensionPromises = []; const federatedStylePromises = []; // This is all the data needed to load and activate plugins. This should be // gathered by the server and put onto the initial page template. const extensions = JSON.parse( PageConfig.getOption('federated_extensions') ); // The set of federated extension names. const federatedExtensionNames = new Set(); extensions.forEach(data => { if (data.extension) { federatedExtensionNames.add(data.name); federatedExtensionPromises.push(createModule(data.name, data.extension)); } if (data.mimeExtension) { federatedExtensionNames.add(data.name); federatedMimeExtensionPromises.push(createModule(data.name, data.mimeExtension)); } if (data.style) { federatedStylePromises.push(createModule(data.name, data.style)); } }); /** * Iterate over active plugins in an extension. * * #### Notes * This also populates the disabled, deferred, and ignored arrays. */ function* activePlugins(extension) { // Handle commonjs or es2015 modules let exports; if (extension.hasOwnProperty('__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.push(plugin.id); continue; } if (PageConfig.Extension.isDeferred(plugin.id)) { deferred.push(plugin.id); ignorePlugins.push(plugin.id); } yield plugin; } } // Handle the mime extensions. const mimeExtensions = []; {{#each jupyterlab_mime_extensions}} if (!federatedExtensionNames.has('{{@key}}')) { try { let ext = require('{{@key}}{{#if this}}/{{this}}{{/if}}'); for (let plugin of activePlugins(ext)) { mimeExtensions.push(plugin); } } catch (e) { console.error(e); } } {{/each}} // 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); } }); // Handled the standard extensions. {{#each jupyterlab_extensions}} if (!federatedExtensionNames.has('{{@key}}')) { try { let ext = require('{{@key}}{{#if this}}/{{this}}{{/if}}'); for (let plugin of activePlugins(ext)) { pluginsToRegister.push(plugin); } } catch (e) { console.error(e); } } {{/each}} // Add the federated extensions. const federatedExtensions = await Promise.allSettled(federatedExtensionPromises); federatedExtensions.forEach(p => { if (p.status === "fulfilled") { for (let plugin of activePlugins(p.value)) { pluginsToRegister.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); }); // Create a new JupyterLab object and start it const lab = new JupyterLab({ mimeExtensions, disabled: { matches: disabled, patterns: PageConfig.Extension.disabled .map(function (val) { return val.raw; }) }, deferred: { matches: deferred, patterns: PageConfig.Extension.deferred .map(function (val) { return val.raw; }) }, }); lab.registerPluginModules(pluginsToRegister); lab.start({ ignorePlugins }); lab.restored.then(() => { console.debug('Example started!'); }); }