index.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*-----------------------------------------------------------------------------
  2. | Copyright (c) Jupyter Development Team.
  3. | Distributed under the terms of the Modified BSD License.
  4. |----------------------------------------------------------------------------*/
  5. import { PageConfig } from '@jupyterlab/coreutils';
  6. import './style.js';
  7. async function createModule(scope, module) {
  8. try {
  9. const factory = await window._JUPYTERLAB[scope].get(module);
  10. return factory();
  11. } catch(e) {
  12. console.warn(`Failed to create module: package: ${scope}; module: ${module}`);
  13. throw e;
  14. }
  15. }
  16. /**
  17. * The main entry point for the application.
  18. */
  19. export async function main() {
  20. var JupyterLab = require('@jupyterlab/application').JupyterLab;
  21. var disabled = [];
  22. var deferred = [];
  23. var ignorePlugins = [];
  24. var register = [];
  25. const federatedExtensionPromises = [];
  26. const federatedMimeExtensionPromises = [];
  27. const federatedStylePromises = [];
  28. // Start initializing the federated extensions
  29. const extensions = JSON.parse(
  30. PageConfig.getOption('federated_extensions')
  31. );
  32. extensions.forEach(data => {
  33. if (data.extension) {
  34. federatedExtensionPromises.push(createModule(data.name, data.extension));
  35. }
  36. if (data.mimeExtension) {
  37. federatedMimeExtensionPromises.push(createModule(data.name, data.mimeExtension));
  38. }
  39. if (data.style) {
  40. federatedStylePromises.push(createModule(data.name, data.style));
  41. }
  42. });
  43. /**
  44. * Iterate over active plugins in an extension.
  45. *
  46. * #### Notes
  47. * This also populates the disabled, deferred, and ignored arrays.
  48. */
  49. function* activePlugins(extension) {
  50. // Handle commonjs or es2015 modules
  51. let exports;
  52. if (extension.hasOwnProperty('__esModule')) {
  53. exports = extension.default;
  54. } else {
  55. // CommonJS exports.
  56. exports = extension;
  57. }
  58. let plugins = Array.isArray(exports) ? exports : [exports];
  59. for (let plugin of plugins) {
  60. if (PageConfig.Extension.isDisabled(plugin.id)) {
  61. disabled.push(plugin.id);
  62. continue;
  63. }
  64. if (PageConfig.Extension.isDeferred(plugin.id)) {
  65. deferred.push(plugin.id);
  66. ignorePlugins.push(plugin.id);
  67. }
  68. yield plugin;
  69. }
  70. }
  71. // Handle the registered mime extensions.
  72. const mimeExtensions = [];
  73. {{#each jupyterlab_mime_extensions}}
  74. try {
  75. let ext = require('{{@key}}{{#if this}}/{{this}}{{/if}}');
  76. for (let plugin of activePlugins(ext)) {
  77. mimeExtensions.push(plugin);
  78. }
  79. } catch (e) {
  80. console.error(e);
  81. }
  82. {{/each}}
  83. // Add the federated mime extensions.
  84. const federatedMimeExtensions = await Promise.allSettled(federatedMimeExtensionPromises);
  85. federatedMimeExtensions.forEach(p => {
  86. if (p.status === "fulfilled") {
  87. for (let plugin of activePlugins(p.value)) {
  88. mimeExtensions.push(plugin);
  89. }
  90. } else {
  91. console.error(p.reason);
  92. }
  93. });
  94. // Handled the registered standard extensions.
  95. {{#each jupyterlab_extensions}}
  96. try {
  97. let ext = require('{{@key}}{{#if this}}/{{this}}{{/if}}');
  98. for (let plugin of activePlugins(ext)) {
  99. register.push(plugin);
  100. }
  101. } catch (e) {
  102. console.error(e);
  103. }
  104. {{/each}}
  105. // Add the federated extensions.
  106. const federatedExtensions = await Promise.allSettled(federatedExtensionPromises);
  107. federatedExtensions.forEach(p => {
  108. if (p.status === "fulfilled") {
  109. for (let plugin of activePlugins(p.value)) {
  110. register.push(plugin);
  111. }
  112. } else {
  113. console.error(p.reason);
  114. }
  115. });
  116. // Load all federated component styles and log errors for any that do not
  117. (await Promise.allSettled(federatedStylePromises)).filter(({status}) => status === "rejected").forEach(({reason}) => {
  118. console.error(reason);
  119. });
  120. const lab = new JupyterLab({
  121. mimeExtensions,
  122. disabled: {
  123. matches: disabled,
  124. patterns: PageConfig.Extension.disabled
  125. .map(function (val) { return val.raw; })
  126. },
  127. deferred: {
  128. matches: deferred,
  129. patterns: PageConfig.Extension.deferred
  130. .map(function (val) { return val.raw; })
  131. },
  132. });
  133. register.forEach(function(item) { lab.registerPluginModule(item); });
  134. lab.start({ ignorePlugins });
  135. // Expose global app instance when in dev mode or when toggled explicitly.
  136. var exposeAppInBrowser = (PageConfig.getOption('exposeAppInBrowser') || '').toLowerCase() === 'true';
  137. var devMode = (PageConfig.getOption('devMode') || '').toLowerCase() === 'true';
  138. if (exposeAppInBrowser || devMode) {
  139. window.jupyterlab = lab;
  140. }
  141. // Handle a browser test.
  142. var browserTest = PageConfig.getOption('browserTest');
  143. if (browserTest.toLowerCase() === 'true') {
  144. var el = document.createElement('div');
  145. el.id = 'browserTest';
  146. document.body.appendChild(el);
  147. el.textContent = '[]';
  148. el.style.display = 'none';
  149. var errors = [];
  150. var reported = false;
  151. var timeout = 25000;
  152. var report = function() {
  153. if (reported) {
  154. return;
  155. }
  156. reported = true;
  157. el.className = 'completed';
  158. }
  159. window.onerror = function(msg, url, line, col, error) {
  160. errors.push(String(error));
  161. el.textContent = JSON.stringify(errors)
  162. };
  163. console.error = function(message) {
  164. errors.push(String(message));
  165. el.textContent = JSON.stringify(errors)
  166. };
  167. lab.restored
  168. .then(function() { report(errors); })
  169. .catch(function(reason) { report([`RestoreError: ${reason.message}`]); });
  170. // Handle failures to restore after the timeout has elapsed.
  171. window.setTimeout(function() { report(errors); }, timeout);
  172. }
  173. }