index.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import { PageConfig, URLExt } from '@jupyterlab/coreutils';
  4. // Promise.allSettled polyfill, until our supported browsers implement it
  5. // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
  6. if (Promise.allSettled === undefined) {
  7. Promise.allSettled = promises =>
  8. Promise.all(
  9. promises.map(promise =>
  10. promise
  11. .then(value => ({
  12. status: "fulfilled",
  13. value,
  14. }), reason => ({
  15. status: "rejected",
  16. reason,
  17. }))
  18. )
  19. );
  20. }
  21. import('./style.js');
  22. async function createModule(scope, module) {
  23. try {
  24. const factory = await window._JUPYTERLAB[scope].get(module);
  25. return factory();
  26. } catch(e) {
  27. console.warn(`Failed to create module: package: ${scope}; module: ${module}`);
  28. throw e;
  29. }
  30. }
  31. /**
  32. * The main entry point for the application.
  33. */
  34. async function main() {
  35. var JupyterLab = require('@jupyterlab/application').JupyterLab;
  36. var disabled = [];
  37. var deferred = [];
  38. var ignorePlugins = [];
  39. var register = [];
  40. const federatedExtensionPromises = [];
  41. const federatedMimeExtensionPromises = [];
  42. const federatedStylePromises = [];
  43. // This is all the data needed to load and activate plugins. This should be
  44. // gathered by the server and put onto the initial page template.
  45. const extension_data = JSON.parse(
  46. PageConfig.getOption('federated_extensions')
  47. );
  48. const queuedFederated = [];
  49. extensions.forEach(data => {
  50. if (data.extension) {
  51. queuedFederated.push(data.name);
  52. federatedExtensionPromises.push(createModule(data.name, data.extension));
  53. }
  54. if (data.mimeExtension) {
  55. queuedFederated.push(data.name);
  56. federatedMimeExtensionPromises.push(createModule(data.name, data.mimeExtension));
  57. }
  58. if (data.style) {
  59. federatedStylePromises.push(createModule(data.name, data.style));
  60. }
  61. });
  62. /**
  63. * Iterate over active plugins in an extension.
  64. *
  65. * #### Notes
  66. * This also populates the disabled, deferred, and ignored arrays.
  67. */
  68. function* activePlugins(extension) {
  69. // Handle commonjs or es2015 modules
  70. let exports;
  71. if (extension.hasOwnProperty('__esModule')) {
  72. exports = extension.default;
  73. } else {
  74. // CommonJS exports.
  75. exports = extension;
  76. }
  77. let plugins = Array.isArray(exports) ? exports : [exports];
  78. for (let plugin of plugins) {
  79. if (PageConfig.Extension.isDisabled(plugin.id)) {
  80. disabled.push(plugin.id);
  81. continue;
  82. }
  83. if (PageConfig.Extension.isDeferred(plugin.id)) {
  84. deferred.push(plugin.id);
  85. ignorePlugins.push(plugin.id);
  86. }
  87. yield plugin;
  88. }
  89. }
  90. // Handle the registered mime extensions.
  91. const mimeExtensions = [];
  92. {{#each jupyterlab_mime_extensions}}
  93. if (!queuedFederated.includes('{{@key}}')) {
  94. try {
  95. let ext = require('{{@key}}{{#if this}}/{{this}}{{/if}}');
  96. for (let plugin of activePlugins(ext)) {
  97. mimeExtensions.push(plugin);
  98. }
  99. } catch (e) {
  100. console.error(e);
  101. }
  102. }
  103. {{/each}}
  104. // Add the federated mime extensions.
  105. const federatedMimeExtensions = await Promise.allSettled(federatedMimeExtensionPromises);
  106. federatedMimeExtensions.forEach(p => {
  107. if (p.status === "fulfilled") {
  108. for (let plugin of activePlugins(p.value)) {
  109. mimeExtensions.push(plugin);
  110. }
  111. } else {
  112. console.error(p.reason);
  113. }
  114. });
  115. // Handled the registered standard extensions.
  116. {{#each jupyterlab_extensions}}
  117. if (!queuedFederated.includes('{{@key}}')) {
  118. try {
  119. let ext = require('{{@key}}{{#if this}}/{{this}}{{/if}}');
  120. for (let plugin of activePlugins(ext)) {
  121. register.push(plugin);
  122. }
  123. } catch (e) {
  124. console.error(e);
  125. }
  126. }
  127. {{/each}}
  128. // Add the federated extensions.
  129. const federatedExtensions = await Promise.allSettled(federatedExtensionPromises);
  130. federatedExtensions.forEach(p => {
  131. if (p.status === "fulfilled") {
  132. for (let plugin of activePlugins(p.value)) {
  133. register.push(plugin);
  134. }
  135. } else {
  136. console.error(p.reason);
  137. }
  138. });
  139. // Load all federated component styles and log errors for any that do not
  140. (await Promise.allSettled(federatedStylePromises)).filter(({status}) => status === "rejected").forEach(({reason}) => {
  141. console.error(reason);
  142. });
  143. const lab = new JupyterLab({
  144. mimeExtensions,
  145. disabled: {
  146. matches: disabled,
  147. patterns: PageConfig.Extension.disabled
  148. .map(function (val) { return val.raw; })
  149. },
  150. deferred: {
  151. matches: deferred,
  152. patterns: PageConfig.Extension.deferred
  153. .map(function (val) { return val.raw; })
  154. },
  155. });
  156. register.forEach(function(item) { lab.registerPluginModule(item); });
  157. lab.start({ ignorePlugins });
  158. lab.restored.then(() => {
  159. console.debug('Example started!');
  160. });
  161. }