jupyter-specta 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/lib/app.js +1 -1
  2. package/lib/components/cellSkeleton.d.ts +6 -0
  3. package/lib/components/cellSkeleton.js +19 -0
  4. package/lib/components/divider.d.ts +2 -0
  5. package/lib/components/divider.js +4 -0
  6. package/lib/components/icon/gear.d.ts +2 -0
  7. package/lib/components/icon/gear.js +17 -0
  8. package/lib/components/iconButton.d.ts +8 -0
  9. package/lib/components/iconButton.js +4 -0
  10. package/lib/create_notebook_panel.d.ts +7 -1
  11. package/lib/create_notebook_panel.js +37 -1
  12. package/lib/document/factory.d.ts +5 -1
  13. package/lib/document/factory.js +13 -3
  14. package/lib/extension_plugins.js +11 -2
  15. package/lib/layout/article.d.ts +12 -0
  16. package/lib/layout/article.js +35 -0
  17. package/lib/layout/default.js +2 -5
  18. package/lib/layout/{plugin.js → index.js} +5 -0
  19. package/lib/layout/layout_registry.d.ts +1 -0
  20. package/lib/layout/layout_registry.js +6 -0
  21. package/lib/metadata/index.d.ts +3 -0
  22. package/lib/metadata/index.js +14 -0
  23. package/lib/shell.js +0 -1
  24. package/lib/specta_cell_output.d.ts +11 -2
  25. package/lib/specta_cell_output.js +22 -1
  26. package/lib/specta_model.d.ts +6 -4
  27. package/lib/specta_model.js +89 -13
  28. package/lib/specta_widget.d.ts +5 -1
  29. package/lib/specta_widget.js +25 -8
  30. package/lib/specta_widget_factory.js +7 -2
  31. package/lib/token.d.ts +18 -0
  32. package/lib/tool.d.ts +5 -1
  33. package/lib/tool.js +40 -6
  34. package/lib/topbar/index.d.ts +5 -0
  35. package/lib/topbar/index.js +30 -0
  36. package/lib/topbar/kernelStatus.d.ts +28 -0
  37. package/lib/topbar/kernelStatus.js +20 -0
  38. package/lib/topbar/settingDialog.d.ts +7 -0
  39. package/lib/topbar/settingDialog.js +73 -0
  40. package/lib/topbar/widget.d.ts +9 -0
  41. package/lib/topbar/widget.js +41 -0
  42. package/package.json +23 -13
  43. package/schema/app-meta.json +39 -0
  44. package/schema/cell-meta.json +37 -0
  45. package/style/article.css +314 -0
  46. package/style/base.css +125 -0
  47. package/style/index.css +2 -0
  48. package/style/index.js +3 -1
  49. package/style/skeleton.css +87 -0
  50. package/style/style.css +9 -4
  51. /package/lib/layout/{plugin.d.ts → index.d.ts} +0 -0
package/lib/app.js CHANGED
@@ -8,7 +8,7 @@ export class SpectaApp extends JupyterFrontEnd {
8
8
  /**
9
9
  * The name of the application.
10
10
  */
11
- this.name = 'Voila';
11
+ this.name = 'specta';
12
12
  /**
13
13
  * A namespace/prefix plugins may use to denote their provenance.
14
14
  */
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export declare function SkeletonBarChart({ bars }: {
3
+ bars?: number;
4
+ }): React.JSX.Element;
5
+ export declare function SkeletonLineChart(): React.JSX.Element;
6
+ export declare function RandomSkeleton(): React.JSX.Element;
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ export function SkeletonBarChart({ bars = 5 }) {
3
+ return (React.createElement("div", { className: "skeleton-bar-chart vertical" },
4
+ React.createElement("div", { className: "skeleton-label" }, "Executing cell"),
5
+ Array.from({ length: bars }).map((_, i) => (React.createElement("div", { key: i, className: "bar vertical-bar", style: { animationDelay: `${i * 0.4}s` } })))));
6
+ }
7
+ export function SkeletonLineChart() {
8
+ return (React.createElement("div", { className: "skeleton-line-chart" },
9
+ React.createElement("div", { className: "skeleton-label" }, "Executing cell"),
10
+ React.createElement("svg", { viewBox: "0 0 100 40", preserveAspectRatio: "none" },
11
+ React.createElement("polyline", { points: "0,30 20,20 40,25 60,15 80,10 100,20" }))));
12
+ }
13
+ export function RandomSkeleton() {
14
+ const random = Math.random();
15
+ if (random < 0.5) {
16
+ return React.createElement(SkeletonLineChart, null);
17
+ }
18
+ return React.createElement(SkeletonBarChart, null);
19
+ }
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare const Divider: () => React.JSX.Element;
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ export const Divider = () => {
3
+ return React.createElement("div", { className: "specta-divider" });
4
+ };
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare const GearIcon: ({ ...props }: React.SVGProps<SVGSVGElement>) => React.JSX.Element;
@@ -0,0 +1,17 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import React from 'react';
13
+ export const GearIcon = (_a) => {
14
+ var props = __rest(_a, []);
15
+ return (React.createElement("svg", Object.assign({ xmlns: "http://www.w3.org/2000/svg", height: "24px", viewBox: "0 -960 960 960", width: "24px" }, props),
16
+ React.createElement("path", { d: "m370-80-16-128q-13-5-24.5-12T307-235l-119 50L78-375l103-78q-1-7-1-13.5v-27q0-6.5 1-13.5L78-585l110-190 119 50q11-8 23-15t24-12l16-128h220l16 128q13 5 24.5 12t22.5 15l119-50 110 190-103 78q1 7 1 13.5v27q0 6.5-2 13.5l103 78-110 190-118-50q-11 8-23 15t-24 12L590-80H370Zm70-80h79l14-106q31-8 57.5-23.5T639-327l99 41 39-68-86-65q5-14 7-29.5t2-31.5q0-16-2-31.5t-7-29.5l86-65-39-68-99 42q-22-23-48.5-38.5T533-694l-13-106h-79l-14 106q-31 8-57.5 23.5T321-633l-99-41-39 68 86 64q-5 15-7 30t-2 32q0 16 2 31t7 30l-86 65 39 68 99-42q22 23 48.5 38.5T427-266l13 106Zm42-180q58 0 99-41t41-99q0-58-41-99t-99-41q-59 0-99.5 41T342-480q0 58 40.5 99t99.5 41Zm-2-140Z" })));
17
+ };
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ export declare const IconButton: React.ForwardRefExoticComponent<{
3
+ icon: JSX.Element;
4
+ onClick: () => void;
5
+ title?: string | undefined;
6
+ disabled?: boolean | undefined;
7
+ className?: string | undefined;
8
+ } & React.RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1,4 @@
1
+ import React, { forwardRef } from 'react';
2
+ export const IconButton = forwardRef(({ icon, onClick, title, disabled, className }, ref) => {
3
+ return (React.createElement("button", { ref: ref, className: `jp-Button specta-icon-button ${className !== null && className !== void 0 ? className : ''}`, title: title, disabled: disabled, onClick: onClick }, icon));
4
+ });
@@ -1,7 +1,13 @@
1
+ import { ISessionContext } from '@jupyterlab/apputils';
1
2
  import { IEditorServices } from '@jupyterlab/codeeditor';
2
- import { DocumentRegistry } from '@jupyterlab/docregistry';
3
+ import { Context, DocumentRegistry } from '@jupyterlab/docregistry';
3
4
  import { INotebookModel, NotebookPanel } from '@jupyterlab/notebook';
4
5
  import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
6
+ import { ServiceManager } from '@jupyterlab/services';
7
+ export declare function createNotebookContext(options: {
8
+ manager: ServiceManager.IManager;
9
+ kernelPreference: ISessionContext.IKernelPreference;
10
+ }): Promise<Context<INotebookModel>>;
5
11
  export declare function createNotebookPanel(options: {
6
12
  context: DocumentRegistry.IContext<INotebookModel>;
7
13
  rendermime: IRenderMimeRegistry;
@@ -1,4 +1,40 @@
1
- import { Notebook, NotebookPanel } from '@jupyterlab/notebook';
1
+ import { Context } from '@jupyterlab/docregistry';
2
+ import { Notebook, NotebookModelFactory, NotebookPanel } from '@jupyterlab/notebook';
3
+ import { UUID } from '@lumino/coreutils';
4
+ class CustomContext extends Context {
5
+ /**
6
+ * Save the document contents to disk.
7
+ */
8
+ async save() {
9
+ await this.ready;
10
+ return;
11
+ }
12
+ async saveAs() {
13
+ await this.ready;
14
+ return;
15
+ }
16
+ async revert() {
17
+ await this.ready;
18
+ return;
19
+ }
20
+ }
21
+ export async function createNotebookContext(options) {
22
+ const factory = new NotebookModelFactory({
23
+ disableDocumentWideUndoRedo: false
24
+ });
25
+ const { manager, kernelPreference } = options;
26
+ const path = UUID.uuid4() + '.ipynb';
27
+ await manager.ready;
28
+ await manager.kernelspecs.ready;
29
+ const context = new CustomContext({
30
+ manager,
31
+ factory,
32
+ path,
33
+ kernelPreference: kernelPreference
34
+ });
35
+ await context.sessionContext.initialize();
36
+ return context;
37
+ }
2
38
  export function createNotebookPanel(options) {
3
39
  const { context, rendermime, editorServices } = options;
4
40
  const editorFactory = editorServices.factoryService.newInlineEditor;
@@ -1,9 +1,13 @@
1
+ import { IThemeManager } from '@jupyterlab/apputils';
1
2
  import { ABCWidgetFactory, DocumentRegistry } from '@jupyterlab/docregistry';
2
- import { NotebookSpectaDocWidget } from './widget';
3
3
  import { INotebookModel } from '@jupyterlab/notebook';
4
4
  import { SpectaWidgetFactory } from '../specta_widget_factory';
5
+ import { ISpectaLayoutRegistry } from '../token';
6
+ import { NotebookSpectaDocWidget } from './widget';
5
7
  interface IOptions extends DocumentRegistry.IWidgetFactoryOptions {
6
8
  spectaWidgetFactory: SpectaWidgetFactory;
9
+ layoutRegistry?: ISpectaLayoutRegistry;
10
+ themeManager?: IThemeManager;
7
11
  }
8
12
  export declare class NotebookGridWidgetFactory extends ABCWidgetFactory<NotebookSpectaDocWidget, INotebookModel> {
9
13
  constructor(options: IOptions);
@@ -1,20 +1,30 @@
1
1
  import { ABCWidgetFactory } from '@jupyterlab/docregistry';
2
+ import { ReactWidget } from '@jupyterlab/ui-components';
3
+ import { Panel } from '@lumino/widgets';
4
+ import * as React from 'react';
5
+ import { isSpectaApp, readSpectaConfig } from '../tool';
6
+ import { TopbarElement } from '../topbar/widget';
2
7
  import { NotebookSpectaDocWidget } from './widget';
3
- import { Widget } from '@lumino/widgets';
4
8
  export class NotebookGridWidgetFactory extends ABCWidgetFactory {
5
9
  constructor(options) {
6
10
  super(options);
7
11
  this._spectaWidgetFactory = options.spectaWidgetFactory;
8
12
  }
9
13
  createNewWidget(context) {
10
- const content = new Widget();
14
+ const content = new Panel();
11
15
  content.addClass('jp-specta-notebook-panel');
16
+ const spectaConfig = readSpectaConfig(context.model.metadata);
17
+ if (!isSpectaApp() && !spectaConfig.hideTopbar) {
18
+ // Not a specta app, add topbar to document widget
19
+ const topbar = ReactWidget.create(React.createElement(TopbarElement, null));
20
+ content.addWidget(topbar);
21
+ }
12
22
  context.ready.then(async () => {
13
23
  const spectaWidget = await this._spectaWidgetFactory.createNew({
14
24
  context
15
25
  });
16
26
  if (spectaWidget) {
17
- Widget.attach(spectaWidget, content.node);
27
+ content.addWidget(spectaWidget);
18
28
  }
19
29
  });
20
30
  const widget = new NotebookSpectaDocWidget({
@@ -1,5 +1,14 @@
1
1
  import { spectaDocument, spectaOpener } from './document/plugin';
2
- import { spectaLayoutRegistry } from './layout/plugin';
2
+ import { spectaLayoutRegistry } from './layout';
3
+ import { appMeta, cellMeta } from './metadata';
4
+ import { topbarPlugin } from './topbar';
3
5
  export * from './tool';
4
6
  export * from './token';
5
- export default [spectaDocument, spectaOpener, spectaLayoutRegistry];
7
+ export default [
8
+ spectaDocument,
9
+ spectaOpener,
10
+ spectaLayoutRegistry,
11
+ topbarPlugin,
12
+ appMeta,
13
+ cellMeta
14
+ ];
@@ -0,0 +1,12 @@
1
+ import { Panel } from '@lumino/widgets';
2
+ import { SpectaCellOutput } from '../specta_cell_output';
3
+ import * as nbformat from '@jupyterlab/nbformat';
4
+ import { ISpectaLayout } from '../token';
5
+ export declare class ArticleLayout implements ISpectaLayout {
6
+ render(options: {
7
+ host: Panel;
8
+ items: SpectaCellOutput[];
9
+ notebook: nbformat.INotebookContent;
10
+ readyCallback: () => Promise<void>;
11
+ }): Promise<void>;
12
+ }
@@ -0,0 +1,35 @@
1
+ import { Panel } from '@lumino/widgets';
2
+ class HostPanel extends Panel {
3
+ constructor() {
4
+ super();
5
+ this.addClass('specta-article-host-widget');
6
+ this._outputs = new Panel();
7
+ this._outputs.addClass('specta-article-outputs-panel');
8
+ this.addWidget(this._outputs);
9
+ }
10
+ addOutput(widget) {
11
+ this._outputs.addWidget(widget);
12
+ }
13
+ }
14
+ export class ArticleLayout {
15
+ async render(options) {
16
+ const { host, items, readyCallback } = options;
17
+ const hostPanel = new HostPanel();
18
+ for (const el of items) {
19
+ const cellModel = el.info.cellModel;
20
+ const info = el.info;
21
+ if ((cellModel === null || cellModel === void 0 ? void 0 : cellModel.cell_type) === 'code') {
22
+ if (!info.hidden) {
23
+ hostPanel.addOutput(el);
24
+ }
25
+ }
26
+ else {
27
+ if (!info.hidden) {
28
+ hostPanel.addOutput(el);
29
+ }
30
+ }
31
+ }
32
+ host.addWidget(hostPanel);
33
+ await readyCallback();
34
+ }
35
+ }
@@ -2,14 +2,11 @@ export class DefaultLayout {
2
2
  async render(options) {
3
3
  const { host, items, readyCallback } = options;
4
4
  for (const el of items) {
5
- const outputNode = el.cellOutput.node;
6
5
  const cellModel = el.info.cellModel;
7
6
  const info = el.info;
8
7
  if ((cellModel === null || cellModel === void 0 ? void 0 : cellModel.cell_type) === 'code') {
9
- if (outputNode.childNodes.length > 0) {
10
- if (!info.hidden) {
11
- host.addWidget(el);
12
- }
8
+ if (!info.hidden) {
9
+ host.addWidget(el);
13
10
  }
14
11
  }
15
12
  else {
@@ -1,11 +1,16 @@
1
1
  import { SpectaLayoutRegistry } from './layout_registry';
2
2
  import { ISpectaLayoutRegistry } from '../token';
3
+ import { readSpectaConfig } from '../tool';
3
4
  export const spectaLayoutRegistry = {
4
5
  id: 'specta:layout-registry',
5
6
  autoStart: true,
6
7
  provides: ISpectaLayoutRegistry,
7
8
  activate: (app) => {
9
+ var _a;
8
10
  const layoutRegistry = new SpectaLayoutRegistry();
11
+ const spectaConfig = readSpectaConfig();
12
+ const defaultLayout = (_a = spectaConfig.defaultLayout) !== null && _a !== void 0 ? _a : 'default';
13
+ layoutRegistry.setSelectedLayout(defaultLayout);
9
14
  return layoutRegistry;
10
15
  }
11
16
  };
@@ -12,6 +12,7 @@ export declare class SpectaLayoutRegistry implements ISpectaLayoutRegistry {
12
12
  layout: ISpectaLayout;
13
13
  }>;
14
14
  get(name: string): ISpectaLayout | undefined;
15
+ getDefaultLayout(): ISpectaLayout;
15
16
  setSelectedLayout(name: string): void;
16
17
  register(name: string, layout: ISpectaLayout): void;
17
18
  allLayouts(): string[];
@@ -1,5 +1,6 @@
1
1
  import { Signal } from '@lumino/signaling';
2
2
  import { DefaultLayout } from './default';
3
+ import { ArticleLayout } from './article';
3
4
  export class SpectaLayoutRegistry {
4
5
  constructor() {
5
6
  this._registry = new Map();
@@ -8,6 +9,7 @@ export class SpectaLayoutRegistry {
8
9
  const defaultLayout = new DefaultLayout();
9
10
  this._registry = new Map();
10
11
  this._registry.set('default', defaultLayout);
12
+ this._registry.set('article', new ArticleLayout());
11
13
  this._selectedLayout = {
12
14
  name: 'default',
13
15
  layout: defaultLayout
@@ -25,11 +27,15 @@ export class SpectaLayoutRegistry {
25
27
  get(name) {
26
28
  return this._registry.get(name);
27
29
  }
30
+ getDefaultLayout() {
31
+ return this._registry.get('default');
32
+ }
28
33
  setSelectedLayout(name) {
29
34
  if (!this._registry.has(name)) {
30
35
  throw new Error(`Layout with name ${name} does not exist`);
31
36
  }
32
37
  this._selectedLayout = { name, layout: this._registry.get(name) };
38
+ this._selectedLayoutChanged.emit(this._selectedLayout);
33
39
  }
34
40
  register(name, layout) {
35
41
  if (this._registry.has(name)) {
@@ -0,0 +1,3 @@
1
+ import { JupyterFrontEndPlugin } from '@jupyterlab/application';
2
+ export declare const cellMeta: JupyterFrontEndPlugin<void>;
3
+ export declare const appMeta: JupyterFrontEndPlugin<void>;
@@ -0,0 +1,14 @@
1
+ export const cellMeta = {
2
+ id: 'jupyter-specta:cell-meta',
3
+ autoStart: true,
4
+ activate: (app) => {
5
+ // no-op
6
+ }
7
+ };
8
+ export const appMeta = {
9
+ id: 'jupyter-specta:app-meta',
10
+ autoStart: true,
11
+ activate: (app) => {
12
+ // no-op
13
+ }
14
+ };
package/lib/shell.js CHANGED
@@ -30,7 +30,6 @@ export class SpectaShell extends Widget {
30
30
  topHandler.panel.id = 'specta-top-panel';
31
31
  topHandler.panel.node.setAttribute('role', 'banner');
32
32
  BoxLayout.setStretch(topHandler.panel, 0);
33
- topHandler.panel.hide();
34
33
  rootLayout.addWidget(topHandler.panel);
35
34
  const hboxPanel = (this._mainPanel = new BoxPanel());
36
35
  hboxPanel.id = 'jp-main-content-panel';
@@ -1,14 +1,23 @@
1
- import { Panel, Widget } from '@lumino/widgets';
2
1
  import * as nbformat from '@jupyterlab/nbformat';
2
+ import { Panel, Widget } from '@lumino/widgets';
3
+ import { ISpectaCellConfig } from './token';
3
4
  export interface ICellInfo {
4
5
  hidden?: boolean;
5
6
  cellModel?: nbformat.ICell;
6
7
  }
7
8
  export declare class SpectaCellOutput extends Panel {
8
- constructor(cellIdentity: string, cell: Widget, info: ICellInfo);
9
+ constructor({ cellIdentity, cell, sourceCell, info, cellConfig }: {
10
+ cellIdentity: string;
11
+ cell: Widget;
12
+ sourceCell?: Widget;
13
+ info: ICellInfo;
14
+ cellConfig: Required<ISpectaCellConfig>;
15
+ });
9
16
  readonly cellIdentity: string;
10
17
  get cellOutput(): Widget;
11
18
  get info(): ICellInfo;
19
+ removePlaceholder(): void;
12
20
  private _info;
13
21
  private _cellOutput;
22
+ private _placeholder?;
14
23
  }
@@ -1,19 +1,34 @@
1
+ import { ReactWidget } from '@jupyterlab/ui-components';
1
2
  import { Panel } from '@lumino/widgets';
3
+ import React from 'react';
4
+ import { RandomSkeleton } from './components/cellSkeleton';
2
5
  export class SpectaCellOutput extends Panel {
3
- constructor(cellIdentity, cell, info) {
6
+ constructor({ cellIdentity, cell, sourceCell, info, cellConfig }) {
7
+ var _a;
4
8
  super();
5
9
  this._info = {};
10
+ this._placeholder = undefined;
6
11
  this.removeClass('lm-Widget');
7
12
  this.removeClass('p-Widget');
8
13
  this.addClass('specta-cell-output');
9
14
  const content = new Panel();
10
15
  content.addClass('specta-cell-content');
11
16
  cell.addClass('specta-item-widget');
17
+ if (sourceCell) {
18
+ content.addWidget(sourceCell);
19
+ }
12
20
  content.addWidget(cell);
13
21
  this.addWidget(content);
14
22
  this._cellOutput = cell;
15
23
  this.cellIdentity = cellIdentity;
16
24
  this._info = info !== null && info !== void 0 ? info : {};
25
+ if (((_a = info.cellModel) === null || _a === void 0 ? void 0 : _a.cell_type) === 'code') {
26
+ if (cellConfig.showOutput) {
27
+ this._placeholder = ReactWidget.create(React.createElement(RandomSkeleton, null));
28
+ this._placeholder.addClass('specta-cell-placeholder');
29
+ this.addWidget(this._placeholder);
30
+ }
31
+ }
17
32
  }
18
33
  get cellOutput() {
19
34
  return this._cellOutput;
@@ -21,4 +36,10 @@ export class SpectaCellOutput extends Panel {
21
36
  get info() {
22
37
  return this._info;
23
38
  }
39
+ removePlaceholder() {
40
+ var _a;
41
+ if (this._placeholder) {
42
+ (_a = this._placeholder) === null || _a === void 0 ? void 0 : _a.dispose();
43
+ }
44
+ }
24
45
  }
@@ -2,7 +2,6 @@ import { ICellModel } from '@jupyterlab/cells';
2
2
  import { IEditorMimeTypeService, IEditorServices } from '@jupyterlab/codeeditor';
3
3
  import { DocumentRegistry } from '@jupyterlab/docregistry';
4
4
  import { CellList, INotebookModel, INotebookTracker, NotebookPanel, StaticNotebook } from '@jupyterlab/notebook';
5
- import { SimplifiedOutputArea } from '@jupyterlab/outputarea';
6
5
  import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
7
6
  import { ServiceManager } from '@jupyterlab/services';
8
7
  import { IExecuteReplyMsg } from '@jupyterlab/services/lib/kernel/messages';
@@ -18,14 +17,17 @@ export declare class AppModel {
18
17
  dispose(): void;
19
18
  get rendermime(): IRenderMimeRegistry;
20
19
  get cells(): CellList | undefined;
21
- get context(): DocumentRegistry.IContext<INotebookModel>;
20
+ get context(): DocumentRegistry.IContext<INotebookModel> | undefined;
22
21
  get panel(): NotebookPanel | undefined;
23
22
  initialize(): Promise<void>;
24
23
  createCell(cellModel: ICellModel): SpectaCellOutput;
25
- executeCell(cell: ICellModel, output: SimplifiedOutputArea): Promise<IExecuteReplyMsg | undefined>;
24
+ executeCell(cell: ICellModel, outputWrapper: SpectaCellOutput): Promise<IExecuteReplyMsg | undefined>;
26
25
  private _notebookPanel?;
27
- private _context;
26
+ private _context?;
27
+ private _notebookModelJson;
28
28
  private _isDisposed;
29
+ private _manager;
30
+ private _kernelPreference;
29
31
  }
30
32
  export declare namespace AppModel {
31
33
  interface IOptions {
@@ -1,13 +1,24 @@
1
- import { MarkdownCell, RawCell } from '@jupyterlab/cells';
1
+ import { CodeCell, MarkdownCell, RawCell } from '@jupyterlab/cells';
2
2
  import { OutputAreaModel, SimplifiedOutputArea } from '@jupyterlab/outputarea';
3
- import { createNotebookPanel } from './create_notebook_panel';
3
+ import { createNotebookContext, createNotebookPanel } from './create_notebook_panel';
4
4
  import { SpectaCellOutput } from './specta_cell_output';
5
+ import { PromiseDelegate } from '@lumino/coreutils';
6
+ import { readCellConfig } from './tool';
5
7
  export const VIEW = 'grid_default';
6
8
  export class AppModel {
7
9
  constructor(options) {
8
10
  this.options = options;
9
11
  this._isDisposed = false;
10
- this._context = options.context;
12
+ this._notebookModelJson = options.context.model.toJSON();
13
+ this._kernelPreference = {
14
+ shouldStart: true,
15
+ canStart: true,
16
+ shutdownOnDispose: true,
17
+ name: options.context.model.defaultKernelName,
18
+ autoStartDefault: true,
19
+ language: options.context.model.defaultKernelLanguage
20
+ };
21
+ this._manager = options.manager;
11
22
  }
12
23
  /**
13
24
  * Whether the handler is disposed.
@@ -39,13 +50,40 @@ export class AppModel {
39
50
  }
40
51
  async initialize() {
41
52
  var _a;
42
- await ((_a = this._context) === null || _a === void 0 ? void 0 : _a.sessionContext.ready);
43
- this._notebookPanel = createNotebookPanel({
44
- context: this._context,
45
- rendermime: this.options.rendermime,
46
- editorServices: this.options.editorServices
53
+ const pd = new PromiseDelegate();
54
+ this._context = await createNotebookContext({
55
+ manager: this._manager,
56
+ kernelPreference: this._kernelPreference
47
57
  });
48
- this.options.tracker.widgetAdded.emit(this._notebookPanel);
58
+ this._context.model.fromJSON(this._notebookModelJson);
59
+ const connectKernel = () => {
60
+ pd.resolve();
61
+ this._notebookPanel = createNotebookPanel({
62
+ context: this._context,
63
+ rendermime: this.options.rendermime,
64
+ editorServices: this.options.editorServices
65
+ });
66
+ this.options.tracker.widgetAdded.emit(this._notebookPanel);
67
+ };
68
+ const kernel = (_a = this._context.sessionContext.session) === null || _a === void 0 ? void 0 : _a.kernel;
69
+ if (kernel) {
70
+ const status = kernel.status;
71
+ if (status !== 'unknown') {
72
+ // Connected to an existing kernel.
73
+ connectKernel();
74
+ return;
75
+ }
76
+ }
77
+ this._context.sessionContext.connectionStatusChanged.connect((_, status) => {
78
+ var _a;
79
+ if (status === 'connected') {
80
+ const kernel = (_a = this._context.sessionContext.session) === null || _a === void 0 ? void 0 : _a.kernel;
81
+ if (kernel) {
82
+ connectKernel();
83
+ }
84
+ }
85
+ }, this);
86
+ return pd.promise;
49
87
  }
50
88
  createCell(cellModel) {
51
89
  let item;
@@ -53,14 +91,37 @@ export class AppModel {
53
91
  const info = {
54
92
  cellModel: cellModelJson
55
93
  };
94
+ const cellConfig = readCellConfig(cellModelJson);
56
95
  switch (cellModel.type) {
57
96
  case 'code': {
97
+ let sourceCell;
98
+ if (cellConfig.showSource) {
99
+ sourceCell = new CodeCell({
100
+ model: cellModel,
101
+ rendermime: this.options.rendermime,
102
+ contentFactory: this.options.contentFactory,
103
+ editorConfig: {
104
+ lineNumbers: false,
105
+ lineWrap: false,
106
+ tabFocusable: false,
107
+ editable: false
108
+ }
109
+ });
110
+ sourceCell.syncEditable = false;
111
+ sourceCell.readOnly = true;
112
+ }
58
113
  const outputareamodel = new OutputAreaModel({ trusted: true });
59
114
  const out = new SimplifiedOutputArea({
60
115
  model: outputareamodel,
61
116
  rendermime: this.options.rendermime
62
117
  });
63
- item = new SpectaCellOutput(cellModel.id, out, info);
118
+ item = new SpectaCellOutput({
119
+ cellIdentity: cellModel.id,
120
+ cell: out,
121
+ sourceCell,
122
+ cellConfig,
123
+ info
124
+ });
64
125
  break;
65
126
  }
66
127
  case 'markdown': {
@@ -70,11 +131,17 @@ export class AppModel {
70
131
  contentFactory: this.options.contentFactory,
71
132
  editorConfig: this.options.editorConfig.markdown
72
133
  });
134
+ markdownCell.initializeState();
73
135
  markdownCell.inputHidden = false;
74
136
  markdownCell.rendered = true;
75
137
  Private.removeElements(markdownCell.node, 'jp-Collapser');
76
138
  Private.removeElements(markdownCell.node, 'jp-InputPrompt');
77
- item = new SpectaCellOutput(cellModel.id, markdownCell, info);
139
+ item = new SpectaCellOutput({
140
+ cellIdentity: cellModel.id,
141
+ cell: markdownCell,
142
+ info,
143
+ cellConfig
144
+ });
78
145
  break;
79
146
  }
80
147
  default: {
@@ -86,18 +153,27 @@ export class AppModel {
86
153
  rawCell.inputHidden = false;
87
154
  Private.removeElements(rawCell.node, 'jp-Collapser');
88
155
  Private.removeElements(rawCell.node, 'jp-InputPrompt');
89
- item = new SpectaCellOutput(cellModel.id, rawCell, info);
156
+ item = new SpectaCellOutput({
157
+ cellIdentity: cellModel.id,
158
+ cell: rawCell,
159
+ info,
160
+ cellConfig
161
+ });
90
162
  break;
91
163
  }
92
164
  }
93
165
  return item;
94
166
  }
95
- async executeCell(cell, output) {
167
+ async executeCell(cell, outputWrapper) {
96
168
  if (cell.type !== 'code' || !this._context) {
97
169
  return;
98
170
  }
171
+ const output = outputWrapper.cellOutput;
99
172
  const source = cell.sharedModel.source;
100
173
  const rep = await SimplifiedOutputArea.execute(source, output, this._context.sessionContext);
174
+ output.future.done.then(() => {
175
+ outputWrapper.removePlaceholder();
176
+ });
101
177
  return rep;
102
178
  }
103
179
  }