@difizen/libro-jupyter 0.0.2-alpha.0
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.
- package/LICENSE +21 -0
- package/README.md +1 -0
- package/es/add-between-cell/add-between-cell-command-contribution.d.ts +14 -0
- package/es/add-between-cell/add-between-cell-command-contribution.d.ts.map +1 -0
- package/es/add-between-cell/add-between-cell-command-contribution.js +97 -0
- package/es/add-between-cell/add-between-cell.d.ts +5 -0
- package/es/add-between-cell/add-between-cell.d.ts.map +1 -0
- package/es/add-between-cell/add-between-cell.js +243 -0
- package/es/add-between-cell/index.d.ts +3 -0
- package/es/add-between-cell/index.d.ts.map +1 -0
- package/es/add-between-cell/index.js +2 -0
- package/es/add-between-cell/index.less +103 -0
- package/es/add-between-cell/module.d.ts +3 -0
- package/es/add-between-cell/module.d.ts.map +1 -0
- package/es/add-between-cell/module.js +8 -0
- package/es/cell/index.d.ts +3 -0
- package/es/cell/index.d.ts.map +1 -0
- package/es/cell/index.js +2 -0
- package/es/cell/jupyter-code-cell-model.d.ts +12 -0
- package/es/cell/jupyter-code-cell-model.d.ts.map +1 -0
- package/es/cell/jupyter-code-cell-model.js +56 -0
- package/es/cell/jupyter-code-cell-view.d.ts +18 -0
- package/es/cell/jupyter-code-cell-view.d.ts.map +1 -0
- package/es/cell/jupyter-code-cell-view.js +280 -0
- package/es/command/command-contribution.d.ts +10 -0
- package/es/command/command-contribution.d.ts.map +1 -0
- package/es/command/command-contribution.js +161 -0
- package/es/command/index.d.ts +3 -0
- package/es/command/index.d.ts.map +1 -0
- package/es/command/index.js +2 -0
- package/es/command/keybinding-contribution.d.ts +8 -0
- package/es/command/keybinding-contribution.d.ts.map +1 -0
- package/es/command/keybinding-contribution.js +37 -0
- package/es/components/cell-execution-tip.d.ts +6 -0
- package/es/components/cell-execution-tip.d.ts.map +1 -0
- package/es/components/cell-execution-tip.js +69 -0
- package/es/components/cell-input-bottom-blank.d.ts +5 -0
- package/es/components/cell-input-bottom-blank.d.ts.map +1 -0
- package/es/components/cell-input-bottom-blank.js +21 -0
- package/es/components/icons.d.ts +5 -0
- package/es/components/icons.d.ts.map +1 -0
- package/es/components/icons.js +154 -0
- package/es/components/index.d.ts +4 -0
- package/es/components/index.d.ts.map +1 -0
- package/es/components/index.js +3 -0
- package/es/components/index.less +82 -0
- package/es/config/config-contribution.d.ts +10 -0
- package/es/config/config-contribution.d.ts.map +1 -0
- package/es/config/config-contribution.js +50 -0
- package/es/config/config.d.ts +3 -0
- package/es/config/config.d.ts.map +1 -0
- package/es/config/config.js +11 -0
- package/es/config/index.d.ts +2 -0
- package/es/config/index.d.ts.map +1 -0
- package/es/config/index.js +1 -0
- package/es/configuration/index.d.ts +3 -0
- package/es/configuration/index.d.ts.map +1 -0
- package/es/configuration/index.js +2 -0
- package/es/configuration/libro-configuration-contribution.d.ts +5 -0
- package/es/configuration/libro-configuration-contribution.d.ts.map +1 -0
- package/es/configuration/libro-configuration-contribution.js +24 -0
- package/es/configuration/libro-configuration.d.ts +3 -0
- package/es/configuration/libro-configuration.d.ts.map +1 -0
- package/es/configuration/libro-configuration.js +12 -0
- package/es/contents/content-contribution.d.ts +7 -0
- package/es/contents/content-contribution.d.ts.map +1 -0
- package/es/contents/content-contribution.js +63 -0
- package/es/contents/index.d.ts +2 -0
- package/es/contents/index.d.ts.map +1 -0
- package/es/contents/index.js +1 -0
- package/es/file/file-name-alias.d.ts +7 -0
- package/es/file/file-name-alias.d.ts.map +1 -0
- package/es/file/file-name-alias.js +26 -0
- package/es/file/file-protocol.d.ts +8 -0
- package/es/file/file-protocol.d.ts.map +1 -0
- package/es/file/file-protocol.js +7 -0
- package/es/file/file-service.d.ts +31 -0
- package/es/file/file-service.d.ts.map +1 -0
- package/es/file/file-service.js +329 -0
- package/es/file/file-tree-label-provider.d.ts +13 -0
- package/es/file/file-tree-label-provider.d.ts.map +1 -0
- package/es/file/file-tree-label-provider.js +62 -0
- package/es/file/file-view/index.d.ts +14 -0
- package/es/file/file-view/index.d.ts.map +1 -0
- package/es/file/file-view/index.js +101 -0
- package/es/file/file-view/index.less +5 -0
- package/es/file/index.d.ts +7 -0
- package/es/file/index.d.ts.map +1 -0
- package/es/file/index.js +6 -0
- package/es/file/module.d.ts +3 -0
- package/es/file/module.d.ts.map +1 -0
- package/es/file/module.js +8 -0
- package/es/file/navigatable-view.d.ts +24 -0
- package/es/file/navigatable-view.d.ts.map +1 -0
- package/es/file/navigatable-view.js +151 -0
- package/es/file/open-handler-contribution.d.ts +11 -0
- package/es/file/open-handler-contribution.d.ts.map +1 -0
- package/es/file/open-handler-contribution.js +102 -0
- package/es/index.d.ts +32 -0
- package/es/index.d.ts.map +1 -0
- package/es/index.js +31 -0
- package/es/keybind-instructions/index.d.ts +6 -0
- package/es/keybind-instructions/index.d.ts.map +1 -0
- package/es/keybind-instructions/index.js +5 -0
- package/es/keybind-instructions/index.less +177 -0
- package/es/keybind-instructions/keybind-instructions-contribution.d.ts +11 -0
- package/es/keybind-instructions/keybind-instructions-contribution.d.ts.map +1 -0
- package/es/keybind-instructions/keybind-instructions-contribution.js +84 -0
- package/es/keybind-instructions/keybind-instructions-icon.d.ts +3 -0
- package/es/keybind-instructions/keybind-instructions-icon.d.ts.map +1 -0
- package/es/keybind-instructions/keybind-instructions-icon.js +23 -0
- package/es/keybind-instructions/keybind-instructions-items.d.ts +14 -0
- package/es/keybind-instructions/keybind-instructions-items.d.ts.map +1 -0
- package/es/keybind-instructions/keybind-instructions-items.js +589 -0
- package/es/keybind-instructions/keybind-instructions-view.d.ts +16 -0
- package/es/keybind-instructions/keybind-instructions-view.d.ts.map +1 -0
- package/es/keybind-instructions/keybind-instructions-view.js +224 -0
- package/es/keybind-instructions/module.d.ts +3 -0
- package/es/keybind-instructions/module.d.ts.map +1 -0
- package/es/keybind-instructions/module.js +5 -0
- package/es/libro-jupyter-file-service.d.ts +106 -0
- package/es/libro-jupyter-file-service.d.ts.map +1 -0
- package/es/libro-jupyter-file-service.js +127 -0
- package/es/libro-jupyter-model.d.ts +49 -0
- package/es/libro-jupyter-model.d.ts.map +1 -0
- package/es/libro-jupyter-model.js +505 -0
- package/es/libro-jupyter-protocol.d.ts +38 -0
- package/es/libro-jupyter-protocol.d.ts.map +1 -0
- package/es/libro-jupyter-protocol.js +9 -0
- package/es/libro-jupyter-server-launch-manager.d.ts +11 -0
- package/es/libro-jupyter-server-launch-manager.d.ts.map +1 -0
- package/es/libro-jupyter-server-launch-manager.js +59 -0
- package/es/libro-jupyter-view.d.ts +10 -0
- package/es/libro-jupyter-view.d.ts.map +1 -0
- package/es/libro-jupyter-view.js +42 -0
- package/es/module.d.ts +3 -0
- package/es/module.d.ts.map +1 -0
- package/es/module.js +48 -0
- package/es/output/index.d.ts +2 -0
- package/es/output/index.d.ts.map +1 -0
- package/es/output/index.js +1 -0
- package/es/output/libro-jupyter-outputarea.d.ts +8 -0
- package/es/output/libro-jupyter-outputarea.d.ts.map +1 -0
- package/es/output/libro-jupyter-outputarea.js +77 -0
- package/es/rendermime/assets/plotly.svg +31 -0
- package/es/rendermime/index.d.ts +5 -0
- package/es/rendermime/index.d.ts.map +1 -0
- package/es/rendermime/index.js +4 -0
- package/es/rendermime/index.less +22 -0
- package/es/rendermime/module.d.ts +3 -0
- package/es/rendermime/module.d.ts.map +1 -0
- package/es/rendermime/module.js +3 -0
- package/es/rendermime/plotly-render.d.ts +7 -0
- package/es/rendermime/plotly-render.d.ts.map +1 -0
- package/es/rendermime/plotly-render.js +30 -0
- package/es/rendermime/plotly-renderers.d.ts +58 -0
- package/es/rendermime/plotly-renderers.d.ts.map +1 -0
- package/es/rendermime/plotly-renderers.js +211 -0
- package/es/rendermime/plotly-rendermime-contribution.d.ts +12 -0
- package/es/rendermime/plotly-rendermime-contribution.d.ts.map +1 -0
- package/es/rendermime/plotly-rendermime-contribution.js +22 -0
- package/es/theme/color-registry.d.ts +6 -0
- package/es/theme/color-registry.d.ts.map +1 -0
- package/es/theme/color-registry.js +393 -0
- package/es/theme/index.d.ts +2 -0
- package/es/theme/index.d.ts.map +1 -0
- package/es/theme/index.js +1 -0
- package/es/toolbar/index.d.ts +6 -0
- package/es/toolbar/index.d.ts.map +1 -0
- package/es/toolbar/index.js +5 -0
- package/es/toolbar/index.less +194 -0
- package/es/toolbar/kernel-selector-dropdown.d.ts +13 -0
- package/es/toolbar/kernel-selector-dropdown.d.ts.map +1 -0
- package/es/toolbar/kernel-selector-dropdown.js +165 -0
- package/es/toolbar/kernel-status-and-selector.d.ts +18 -0
- package/es/toolbar/kernel-status-and-selector.d.ts.map +1 -0
- package/es/toolbar/kernel-status-and-selector.js +164 -0
- package/es/toolbar/run-selector.d.ts +3 -0
- package/es/toolbar/run-selector.d.ts.map +1 -0
- package/es/toolbar/run-selector.js +98 -0
- package/es/toolbar/save-file-error-contribution.d.ts +5 -0
- package/es/toolbar/save-file-error-contribution.d.ts.map +1 -0
- package/es/toolbar/save-file-error-contribution.js +23 -0
- package/es/toolbar/save-file-error.d.ts +5 -0
- package/es/toolbar/save-file-error.d.ts.map +1 -0
- package/es/toolbar/save-file-error.js +27 -0
- package/es/toolbar/side-toolbar-run-selector.d.ts +3 -0
- package/es/toolbar/side-toolbar-run-selector.d.ts.map +1 -0
- package/es/toolbar/side-toolbar-run-selector.js +67 -0
- package/es/toolbar/toolbar-contribution.d.ts +9 -0
- package/es/toolbar/toolbar-contribution.d.ts.map +1 -0
- package/es/toolbar/toolbar-contribution.js +67 -0
- package/es/typings/index.d.ts +31 -0
- package/es/utils/index.d.ts +11 -0
- package/es/utils/index.d.ts.map +1 -0
- package/es/utils/index.js +47 -0
- package/package.json +75 -0
- package/src/add-between-cell/add-between-cell-command-contribution.ts +63 -0
- package/src/add-between-cell/add-between-cell.tsx +201 -0
- package/src/add-between-cell/index.less +103 -0
- package/src/add-between-cell/index.ts +2 -0
- package/src/add-between-cell/module.ts +13 -0
- package/src/cell/index.ts +2 -0
- package/src/cell/jupyter-code-cell-model.ts +36 -0
- package/src/cell/jupyter-code-cell-view.tsx +221 -0
- package/src/command/command-contribution.ts +163 -0
- package/src/command/index.ts +2 -0
- package/src/command/keybinding-contribution.ts +25 -0
- package/src/components/cell-execution-tip.tsx +107 -0
- package/src/components/cell-input-bottom-blank.tsx +24 -0
- package/src/components/icons.tsx +117 -0
- package/src/components/index.less +82 -0
- package/src/components/index.ts +3 -0
- package/src/config/config-contribution.ts +21 -0
- package/src/config/config.ts +14 -0
- package/src/config/index.ts +1 -0
- package/src/configuration/index.ts +2 -0
- package/src/configuration/libro-configuration-contribution.ts +11 -0
- package/src/configuration/libro-configuration.ts +14 -0
- package/src/contents/content-contribution.ts +32 -0
- package/src/contents/index.ts +1 -0
- package/src/file/file-name-alias.ts +15 -0
- package/src/file/file-protocol.ts +7 -0
- package/src/file/file-service.ts +179 -0
- package/src/file/file-tree-label-provider.ts +42 -0
- package/src/file/file-view/index.less +5 -0
- package/src/file/file-view/index.tsx +90 -0
- package/src/file/index.ts +6 -0
- package/src/file/module.ts +19 -0
- package/src/file/navigatable-view.tsx +93 -0
- package/src/file/open-handler-contribution.ts +44 -0
- package/src/index.ts +32 -0
- package/src/keybind-instructions/index.less +177 -0
- package/src/keybind-instructions/index.ts +5 -0
- package/src/keybind-instructions/keybind-instructions-contribution.ts +47 -0
- package/src/keybind-instructions/keybind-instructions-icon.tsx +28 -0
- package/src/keybind-instructions/keybind-instructions-items.tsx +597 -0
- package/src/keybind-instructions/keybind-instructions-view.tsx +239 -0
- package/src/keybind-instructions/module.ts +11 -0
- package/src/libro-jupyter-file-service.ts +158 -0
- package/src/libro-jupyter-model.ts +289 -0
- package/src/libro-jupyter-protocol.ts +59 -0
- package/src/libro-jupyter-server-launch-manager.ts +36 -0
- package/src/libro-jupyter-view.tsx +24 -0
- package/src/module.ts +105 -0
- package/src/output/index.ts +1 -0
- package/src/output/libro-jupyter-outputarea.tsx +71 -0
- package/src/rendermime/assets/plotly.svg +31 -0
- package/src/rendermime/index.less +13 -0
- package/src/rendermime/index.ts +4 -0
- package/src/rendermime/module.ts +7 -0
- package/src/rendermime/plotly-render.tsx +35 -0
- package/src/rendermime/plotly-renderers.ts +191 -0
- package/src/rendermime/plotly-rendermime-contribution.ts +15 -0
- package/src/theme/color-registry.ts +301 -0
- package/src/theme/index.ts +1 -0
- package/src/toolbar/index.less +194 -0
- package/src/toolbar/index.ts +5 -0
- package/src/toolbar/kernel-selector-dropdown.tsx +204 -0
- package/src/toolbar/kernel-status-and-selector.tsx +195 -0
- package/src/toolbar/run-selector.tsx +110 -0
- package/src/toolbar/save-file-error-contribution.ts +10 -0
- package/src/toolbar/save-file-error.tsx +35 -0
- package/src/toolbar/side-toolbar-run-selector.tsx +77 -0
- package/src/toolbar/toolbar-contribution.tsx +62 -0
- package/src/typings/index.d.ts +31 -0
- package/src/utils/index.ts +65 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ICellMetadata,
|
|
3
|
+
ICodeCellMetadata,
|
|
4
|
+
PartialJSONObject,
|
|
5
|
+
INotebookContent,
|
|
6
|
+
} from '@difizen/libro-common';
|
|
7
|
+
import { ExecutableCellModel } from '@difizen/libro-core';
|
|
8
|
+
import type { IContentsModel } from '@difizen/libro-kernel';
|
|
9
|
+
import type { Event as ManaEvent, Emitter } from '@difizen/mana-app';
|
|
10
|
+
|
|
11
|
+
export interface ExecutionMeta extends PartialJSONObject {
|
|
12
|
+
'shell.execute_reply.started': string; // Kernel 开始执行任务时间在 metadata 中的 key
|
|
13
|
+
'shell.execute_reply.end': string; // Kernel 结束执行任务时间在 metadata 中的 key
|
|
14
|
+
to_execute: string; // 用户点击执行任务在 metadata 中的 key
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface CodeCellMetadata extends ICodeCellMetadata {
|
|
18
|
+
execution: ExecutionMeta;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type ExecutedWithKernelCellMeta = Partial<CodeCellMetadata | ICellMetadata>;
|
|
22
|
+
|
|
23
|
+
export interface ExecutedWithKernelCellModel extends ExecutableCellModel {
|
|
24
|
+
metadata: ExecutedWithKernelCellMeta;
|
|
25
|
+
kernelExecuting: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const ExecutedWithKernelCellModel = {
|
|
29
|
+
is: (arg: Record<any, any> | undefined): arg is ExecutedWithKernelCellModel => {
|
|
30
|
+
return (
|
|
31
|
+
ExecutableCellModel.is(arg) &&
|
|
32
|
+
'kernelExecuting' in arg &&
|
|
33
|
+
typeof (arg as any).kernelExecuting === 'boolean'
|
|
34
|
+
);
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type KernelStatusAndSelectorProvider = React.FC;
|
|
39
|
+
export const KernelStatusAndSelectorProvider = Symbol(
|
|
40
|
+
'KernelStatusAndSelectorProvider',
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
export const LibroFileService = Symbol('LibroFileService');
|
|
44
|
+
export interface LibroFileService {
|
|
45
|
+
fileSaveError: ManaEvent<Partial<IContentsModel>>;
|
|
46
|
+
fileSaveErrorEmitter: Emitter<
|
|
47
|
+
Partial<IContentsModel> & { msg?: string; cause?: string }
|
|
48
|
+
>;
|
|
49
|
+
read: (path: string) => Promise<IContentsModel | undefined>;
|
|
50
|
+
write: (
|
|
51
|
+
notebookContent: INotebookContent,
|
|
52
|
+
currentFileContents: IContentsModel,
|
|
53
|
+
) => Promise<IContentsModel | undefined>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const ServerLaunchManager = Symbol('ServerLaunchManager');
|
|
57
|
+
export interface ServerLaunchManager {
|
|
58
|
+
launch: () => Promise<any>;
|
|
59
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ServerManager, ServerConnection } from '@difizen/libro-kernel';
|
|
2
|
+
import { inject, singleton } from '@difizen/mana-app';
|
|
3
|
+
import { ApplicationContribution } from '@difizen/mana-app';
|
|
4
|
+
|
|
5
|
+
import { ServerLaunchManager } from './libro-jupyter-protocol.js';
|
|
6
|
+
|
|
7
|
+
@singleton({ contrib: [ServerLaunchManager, ApplicationContribution] })
|
|
8
|
+
export class JupyterServerLaunchManager
|
|
9
|
+
implements ServerLaunchManager, ApplicationContribution
|
|
10
|
+
{
|
|
11
|
+
protected serverManager: ServerManager;
|
|
12
|
+
protected serverConnection: ServerConnection;
|
|
13
|
+
|
|
14
|
+
constructor(
|
|
15
|
+
@inject(ServerManager)
|
|
16
|
+
serverManager: ServerManager,
|
|
17
|
+
@inject(ServerConnection)
|
|
18
|
+
serverConnection: ServerConnection,
|
|
19
|
+
) {
|
|
20
|
+
this.serverManager = serverManager;
|
|
21
|
+
this.serverConnection = serverConnection;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async onStart() {
|
|
25
|
+
const host = location.host;
|
|
26
|
+
this.serverConnection.updateSettings({
|
|
27
|
+
baseUrl: `http://${host}`,
|
|
28
|
+
wsUrl: `ws://${host}`,
|
|
29
|
+
});
|
|
30
|
+
this.launch();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
launch() {
|
|
34
|
+
return this.serverManager.launch();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { NotebookOption } from '@difizen/libro-core';
|
|
2
|
+
import { CollapseServiceFactory, NotebookService } from '@difizen/libro-core';
|
|
3
|
+
import { LibroView, notebookViewFactoryId } from '@difizen/libro-core';
|
|
4
|
+
import { URI, view, ViewOption } from '@difizen/mana-app';
|
|
5
|
+
import { inject, transient } from '@difizen/mana-app';
|
|
6
|
+
|
|
7
|
+
@transient()
|
|
8
|
+
@view(notebookViewFactoryId)
|
|
9
|
+
export class LibroJupyterView extends LibroView {
|
|
10
|
+
uri: URI;
|
|
11
|
+
constructor(
|
|
12
|
+
@inject(ViewOption) options: NotebookOption,
|
|
13
|
+
@inject(CollapseServiceFactory) collapseServiceFactory: CollapseServiceFactory,
|
|
14
|
+
@inject(NotebookService) notebookService: NotebookService,
|
|
15
|
+
) {
|
|
16
|
+
super(options, collapseServiceFactory, notebookService);
|
|
17
|
+
const uri = new URI(options['resource']);
|
|
18
|
+
this.uri = uri;
|
|
19
|
+
this.title.label = uri.displayName;
|
|
20
|
+
}
|
|
21
|
+
get options() {
|
|
22
|
+
return this.model.options;
|
|
23
|
+
}
|
|
24
|
+
}
|
package/src/module.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LibroCodeCellModel,
|
|
3
|
+
LibroCodeCellView,
|
|
4
|
+
CodeCellModule,
|
|
5
|
+
} from '@difizen/libro-codemirror-code-cell';
|
|
6
|
+
import { MarkdownCellModule } from '@difizen/libro-codemirror-markdown-cell';
|
|
7
|
+
import { RawCellModule } from '@difizen/libro-codemirror-raw-cell';
|
|
8
|
+
import {
|
|
9
|
+
LibroModule,
|
|
10
|
+
LibroToolbarModule,
|
|
11
|
+
LibroKeybindRegistry,
|
|
12
|
+
LibroModel,
|
|
13
|
+
LibroAddCellModule,
|
|
14
|
+
CellExecutionTimeProvider,
|
|
15
|
+
CellInputBottonBlankProvider,
|
|
16
|
+
} from '@difizen/libro-core';
|
|
17
|
+
import { LibroKernelManageModule } from '@difizen/libro-kernel';
|
|
18
|
+
import {
|
|
19
|
+
DisplayDataOutputModule,
|
|
20
|
+
ErrorOutputModule,
|
|
21
|
+
StreamOutputModule,
|
|
22
|
+
} from '@difizen/libro-output';
|
|
23
|
+
import { LibroSearchModule } from '@difizen/libro-search';
|
|
24
|
+
import { SearchCodemirrorCellModule } from '@difizen/libro-search-codemirror-cell';
|
|
25
|
+
import { ManaModule } from '@difizen/mana-app';
|
|
26
|
+
|
|
27
|
+
import { LibroBetweenCellModule } from './add-between-cell/index.js';
|
|
28
|
+
import { JupyterCodeCellModel, JupyterCodeCellView } from './cell/index.js';
|
|
29
|
+
import {
|
|
30
|
+
LibroJupyterCommandContribution,
|
|
31
|
+
LibroJupyterKeybindingContribution,
|
|
32
|
+
} from './command/index.js';
|
|
33
|
+
import { CellExecutionTip, CellInputBottomBlank } from './components/index.js';
|
|
34
|
+
import { ConfigAppContribution } from './config/index.js';
|
|
35
|
+
import { LibroConfigurationContribution } from './configuration/libro-configuration-contribution.js';
|
|
36
|
+
import { LibroJupyterContentContribution } from './contents/index.js';
|
|
37
|
+
import { LibroJupyterFileModule } from './file/index.js';
|
|
38
|
+
import { KeybindInstructionsModule } from './keybind-instructions/index.js';
|
|
39
|
+
import { LibroJupyterFileService } from './libro-jupyter-file-service.js';
|
|
40
|
+
import { LibroJupyterModel } from './libro-jupyter-model.js';
|
|
41
|
+
import { KernelStatusAndSelectorProvider } from './libro-jupyter-protocol.js';
|
|
42
|
+
import { JupyterServerLaunchManager } from './libro-jupyter-server-launch-manager.js';
|
|
43
|
+
import { LibroJupyterView } from './libro-jupyter-view.js';
|
|
44
|
+
import { LibroJupyterOutputArea } from './output/index.js';
|
|
45
|
+
import { PlotlyModule } from './rendermime/index.js';
|
|
46
|
+
import { LibroJupyterColorContribution } from './theme/index.js';
|
|
47
|
+
import {
|
|
48
|
+
LibroJupyterToolbarContribution,
|
|
49
|
+
SaveFileErrorContribution,
|
|
50
|
+
KernelStatusSelector,
|
|
51
|
+
} from './toolbar/index.js';
|
|
52
|
+
|
|
53
|
+
export const LibroJupyterModule = ManaModule.create()
|
|
54
|
+
.register(
|
|
55
|
+
LibroJupyterFileService,
|
|
56
|
+
LibroJupyterCommandContribution,
|
|
57
|
+
LibroJupyterKeybindingContribution,
|
|
58
|
+
LibroJupyterToolbarContribution,
|
|
59
|
+
ConfigAppContribution,
|
|
60
|
+
SaveFileErrorContribution,
|
|
61
|
+
LibroKeybindRegistry,
|
|
62
|
+
LibroJupyterContentContribution,
|
|
63
|
+
LibroJupyterOutputArea,
|
|
64
|
+
LibroJupyterColorContribution,
|
|
65
|
+
JupyterServerLaunchManager,
|
|
66
|
+
LibroJupyterView,
|
|
67
|
+
LibroConfigurationContribution,
|
|
68
|
+
{
|
|
69
|
+
token: CellExecutionTimeProvider,
|
|
70
|
+
useValue: CellExecutionTip,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
token: CellInputBottonBlankProvider,
|
|
74
|
+
useValue: CellInputBottomBlank,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
token: KernelStatusAndSelectorProvider,
|
|
78
|
+
useValue: KernelStatusSelector,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
token: LibroModel,
|
|
82
|
+
useClass: LibroJupyterModel,
|
|
83
|
+
},
|
|
84
|
+
{ token: LibroCodeCellModel, useClass: JupyterCodeCellModel },
|
|
85
|
+
{ token: LibroCodeCellView, useClass: JupyterCodeCellView },
|
|
86
|
+
)
|
|
87
|
+
.dependOn(
|
|
88
|
+
LibroModule,
|
|
89
|
+
CodeCellModule,
|
|
90
|
+
MarkdownCellModule,
|
|
91
|
+
RawCellModule,
|
|
92
|
+
StreamOutputModule,
|
|
93
|
+
ErrorOutputModule,
|
|
94
|
+
DisplayDataOutputModule,
|
|
95
|
+
LibroToolbarModule,
|
|
96
|
+
LibroKernelManageModule,
|
|
97
|
+
LibroSearchModule,
|
|
98
|
+
SearchCodemirrorCellModule,
|
|
99
|
+
LibroAddCellModule,
|
|
100
|
+
// custom module
|
|
101
|
+
LibroBetweenCellModule,
|
|
102
|
+
KeybindInstructionsModule,
|
|
103
|
+
PlotlyModule,
|
|
104
|
+
LibroJupyterFileModule,
|
|
105
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './libro-jupyter-outputarea.js';
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type * as nbformat from '@difizen/libro-common';
|
|
2
|
+
import type {
|
|
3
|
+
LibroExecutableCellView,
|
|
4
|
+
ExecutableCellModel,
|
|
5
|
+
IOutputAreaOption,
|
|
6
|
+
} from '@difizen/libro-core';
|
|
7
|
+
import { LibroOutputArea } from '@difizen/libro-core';
|
|
8
|
+
import {
|
|
9
|
+
isDisplayDataMsg,
|
|
10
|
+
isStreamMsg,
|
|
11
|
+
isErrorMsg,
|
|
12
|
+
isExecuteResultMsg,
|
|
13
|
+
isExecuteReplyMsg,
|
|
14
|
+
} from '@difizen/libro-kernel';
|
|
15
|
+
import { view, inject, transient, ViewOption } from '@difizen/mana-app';
|
|
16
|
+
|
|
17
|
+
@transient()
|
|
18
|
+
@view('libro-output-area')
|
|
19
|
+
export class LibroJupyterOutputArea extends LibroOutputArea {
|
|
20
|
+
declare cell: LibroExecutableCellView;
|
|
21
|
+
|
|
22
|
+
constructor(@inject(ViewOption) option: IOutputAreaOption) {
|
|
23
|
+
super(option);
|
|
24
|
+
this.handleMsg();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
handleMsg() {
|
|
28
|
+
const cellModel = this.cell.model as ExecutableCellModel;
|
|
29
|
+
cellModel.msgChangeEmitter.event((msg) => {
|
|
30
|
+
if (msg.header.msg_type !== 'status') {
|
|
31
|
+
if (msg.header.msg_type === 'execute_input') {
|
|
32
|
+
cellModel.executeCount = msg.content.execution_count;
|
|
33
|
+
}
|
|
34
|
+
if (
|
|
35
|
+
isDisplayDataMsg(msg) ||
|
|
36
|
+
isStreamMsg(msg) ||
|
|
37
|
+
isErrorMsg(msg) ||
|
|
38
|
+
isExecuteResultMsg(msg)
|
|
39
|
+
) {
|
|
40
|
+
const output: nbformat.IOutput = {
|
|
41
|
+
...msg.content,
|
|
42
|
+
output_type: msg.header.msg_type,
|
|
43
|
+
};
|
|
44
|
+
this.add(output);
|
|
45
|
+
}
|
|
46
|
+
//Handle an execute reply message.
|
|
47
|
+
if (isExecuteReplyMsg(msg)) {
|
|
48
|
+
const content = msg.content;
|
|
49
|
+
if (content.status !== 'ok') {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const payload = content && content.payload;
|
|
53
|
+
if (!payload || !payload.length) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const pages = payload.filter((i: any) => i.source === 'page');
|
|
57
|
+
if (!pages.length) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const page = JSON.parse(JSON.stringify(pages[0]));
|
|
61
|
+
const output: nbformat.IOutput = {
|
|
62
|
+
output_type: 'display_data',
|
|
63
|
+
data: page.data as nbformat.IMimeBundle,
|
|
64
|
+
metadata: {},
|
|
65
|
+
};
|
|
66
|
+
this.add(output);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 132 132">
|
|
2
|
+
<defs>
|
|
3
|
+
<style>
|
|
4
|
+
.cls-1 {
|
|
5
|
+
fill: #119dff;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.cls-2 {
|
|
9
|
+
fill: #25fefd;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.cls-3 {
|
|
13
|
+
fill: #fff;
|
|
14
|
+
}
|
|
15
|
+
</style>
|
|
16
|
+
</defs>
|
|
17
|
+
<title>plotly-logomark</title>
|
|
18
|
+
<g id="symbol">
|
|
19
|
+
<rect class="cls-1" width="132" height="132" rx="6" ry="6"/>
|
|
20
|
+
<circle class="cls-2" cx="78" cy="54" r="6"/>
|
|
21
|
+
<circle class="cls-2" cx="102" cy="30" r="6"/>
|
|
22
|
+
<circle class="cls-2" cx="78" cy="30" r="6"/>
|
|
23
|
+
<circle class="cls-2" cx="54" cy="30" r="6"/>
|
|
24
|
+
<circle class="cls-2" cx="30" cy="30" r="6"/>
|
|
25
|
+
<circle class="cls-2" cx="30" cy="54" r="6"/>
|
|
26
|
+
<path class="cls-3" d="M30,72a6,6,0,0,0-6,6v24a6,6,0,0,0,12,0V78A6,6,0,0,0,30,72Z"/>
|
|
27
|
+
<path class="cls-3" d="M78,72a6,6,0,0,0-6,6v24a6,6,0,0,0,12,0V78A6,6,0,0,0,78,72Z"/>
|
|
28
|
+
<path class="cls-3" d="M54,48a6,6,0,0,0-6,6v48a6,6,0,0,0,12,0V54A6,6,0,0,0,54,48Z"/>
|
|
29
|
+
<path class="cls-3" d="M102,48a6,6,0,0,0-6,6v48a6,6,0,0,0,12,0V54A6,6,0,0,0,102,48Z"/>
|
|
30
|
+
</g>
|
|
31
|
+
</svg>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { BaseOutputView } from '@difizen/libro-core';
|
|
2
|
+
import { RenderMimeRegistry } from '@difizen/libro-rendermime';
|
|
3
|
+
import type { IRenderMimeRegistry } from '@difizen/libro-rendermime';
|
|
4
|
+
import { useInject } from '@difizen/mana-app';
|
|
5
|
+
import { useEffect, useRef } from 'react';
|
|
6
|
+
import type { FC } from 'react';
|
|
7
|
+
|
|
8
|
+
import { renderPlotly } from './plotly-renderers.js';
|
|
9
|
+
import './index.less';
|
|
10
|
+
|
|
11
|
+
export const PlotlyRender: FC<{ model: BaseOutputView }> = (props: {
|
|
12
|
+
model: BaseOutputView;
|
|
13
|
+
}) => {
|
|
14
|
+
const { model } = props;
|
|
15
|
+
const renderPlotlyRef = useRef<HTMLDivElement>(null);
|
|
16
|
+
const defaultRenderMime = useInject<IRenderMimeRegistry>(RenderMimeRegistry);
|
|
17
|
+
|
|
18
|
+
const mimeType = defaultRenderMime.preferredMimeType(model);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (mimeType) {
|
|
21
|
+
renderPlotly({
|
|
22
|
+
model: model,
|
|
23
|
+
host: renderPlotlyRef.current as HTMLDivElement,
|
|
24
|
+
source: model.data[mimeType],
|
|
25
|
+
mimeType: mimeType,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
29
|
+
}, []);
|
|
30
|
+
return (
|
|
31
|
+
<div className="libro-plotly-render-container">
|
|
32
|
+
<div className="libro-plotly-render" ref={renderPlotlyRef} />
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import type { JSONValue } from '@difizen/libro-common';
|
|
2
|
+
import type { BaseOutputView } from '@difizen/libro-core';
|
|
3
|
+
import type PlotlyType from 'plotly.js';
|
|
4
|
+
/**
|
|
5
|
+
* The options used to create a renderer.
|
|
6
|
+
*/
|
|
7
|
+
export interface IRendererPlotlyOptions {
|
|
8
|
+
/**
|
|
9
|
+
* The host node for the text content.
|
|
10
|
+
*/
|
|
11
|
+
host: HTMLElement;
|
|
12
|
+
/**
|
|
13
|
+
* The source text to render.
|
|
14
|
+
*/
|
|
15
|
+
source: JSONValue;
|
|
16
|
+
/**
|
|
17
|
+
* The preferred mimeType to render.
|
|
18
|
+
*/
|
|
19
|
+
mimeType: string;
|
|
20
|
+
|
|
21
|
+
model: BaseOutputView;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The MIME type for Plotly.
|
|
25
|
+
* The version of this follows the major version of Plotly.
|
|
26
|
+
*/
|
|
27
|
+
export const MIME_TYPE = 'application/vnd.plotly.v1+json';
|
|
28
|
+
|
|
29
|
+
interface IPlotlySpec {
|
|
30
|
+
data: PlotlyType.Data;
|
|
31
|
+
layout: PlotlyType.Layout;
|
|
32
|
+
frames?: PlotlyType.Frame[];
|
|
33
|
+
}
|
|
34
|
+
export class RenderedPlotly {
|
|
35
|
+
/**
|
|
36
|
+
* Create a new widget for rendering Plotly.
|
|
37
|
+
*/
|
|
38
|
+
constructor(options: IRendererPlotlyOptions) {
|
|
39
|
+
this._mimeType = options.mimeType;
|
|
40
|
+
this.node = options.host;
|
|
41
|
+
// Create image element
|
|
42
|
+
this._img_el = document.createElement('img');
|
|
43
|
+
this._img_el.className = 'plot-img';
|
|
44
|
+
this.node.appendChild(this._img_el);
|
|
45
|
+
|
|
46
|
+
// Install image hover callback
|
|
47
|
+
this._img_el.addEventListener('mouseenter', () => {
|
|
48
|
+
this.createGraph(this._model);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Render Plotly into this widget's node.
|
|
54
|
+
*/
|
|
55
|
+
renderModel(model: BaseOutputView): Promise<void> {
|
|
56
|
+
if (this.hasGraphElement()) {
|
|
57
|
+
// We already have a graph, don't overwrite it
|
|
58
|
+
return Promise.resolve();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Save off reference to model so that we can regenerate the plot later
|
|
62
|
+
this._model = model;
|
|
63
|
+
|
|
64
|
+
// Check for PNG data in mime bundle
|
|
65
|
+
const png_data = <string>model.data['image/png'];
|
|
66
|
+
if (png_data !== undefined && png_data !== null) {
|
|
67
|
+
// We have PNG data, use it
|
|
68
|
+
this.updateImage(png_data);
|
|
69
|
+
return Promise.resolve();
|
|
70
|
+
} else {
|
|
71
|
+
// Create a new graph
|
|
72
|
+
return this.createGraph(model);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private hasGraphElement() {
|
|
77
|
+
// Check for the presence of the .plot-container element that plotly.js
|
|
78
|
+
// places at the top of the figure structure
|
|
79
|
+
return this.node.querySelector('.plot-container') !== null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private updateImage(png_data: string) {
|
|
83
|
+
this.hideGraph();
|
|
84
|
+
this._img_el.src = 'data:image/png;base64,' + png_data;
|
|
85
|
+
this.showImage();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private hideGraph() {
|
|
89
|
+
// Hide the graph if there is one
|
|
90
|
+
const el = <HTMLDivElement>this.node.querySelector('.plot-container');
|
|
91
|
+
if (el !== null && el !== undefined) {
|
|
92
|
+
el.style.display = 'none';
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private showGraph() {
|
|
97
|
+
// Show the graph if there is one
|
|
98
|
+
const el = <HTMLDivElement>this.node.querySelector('.plot-container');
|
|
99
|
+
if (el !== null && el !== undefined) {
|
|
100
|
+
el.style.display = 'block';
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private hideImage() {
|
|
105
|
+
// Hide the image element
|
|
106
|
+
const el = <HTMLImageElement>this.node.querySelector('.plot-img');
|
|
107
|
+
if (el !== null && el !== undefined) {
|
|
108
|
+
el.style.display = 'none';
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private showImage() {
|
|
113
|
+
// Show the image element
|
|
114
|
+
const el = <HTMLImageElement>this.node.querySelector('.plot-img');
|
|
115
|
+
if (el !== null && el !== undefined) {
|
|
116
|
+
el.style.display = 'block';
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
private createGraph(model: BaseOutputView): Promise<void> {
|
|
121
|
+
const { data, layout, frames, config } = model.data[this._mimeType] as
|
|
122
|
+
| any
|
|
123
|
+
| IPlotlySpec;
|
|
124
|
+
|
|
125
|
+
// Load plotly asynchronously
|
|
126
|
+
const loadPlotly = async (): Promise<void> => {
|
|
127
|
+
if (RenderedPlotly.Plotly === null) {
|
|
128
|
+
RenderedPlotly.Plotly = await import('plotly.js');
|
|
129
|
+
RenderedPlotly._resolveLoadingPlotly();
|
|
130
|
+
}
|
|
131
|
+
return RenderedPlotly.loadingPlotly;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
return loadPlotly()
|
|
135
|
+
.then(() => RenderedPlotly.Plotly!.react(this.node, data, layout, config))
|
|
136
|
+
.then((plot) => {
|
|
137
|
+
this.showGraph();
|
|
138
|
+
this.hideImage();
|
|
139
|
+
// this.update();
|
|
140
|
+
if (frames) {
|
|
141
|
+
RenderedPlotly.Plotly!.addFrames(this.node, frames);
|
|
142
|
+
}
|
|
143
|
+
if (this.node.offsetWidth > 0 && this.node.offsetHeight > 0) {
|
|
144
|
+
RenderedPlotly.Plotly!.toImage(plot, {
|
|
145
|
+
format: 'png',
|
|
146
|
+
width: this.node.offsetWidth,
|
|
147
|
+
height: this.node.offsetHeight,
|
|
148
|
+
})
|
|
149
|
+
.then((url: string) => {
|
|
150
|
+
const imageData = url.split(',')[1];
|
|
151
|
+
if (model.data['image/png'] !== imageData) {
|
|
152
|
+
model.setData({
|
|
153
|
+
data: {
|
|
154
|
+
...model.data,
|
|
155
|
+
'image/png': imageData,
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return;
|
|
160
|
+
})
|
|
161
|
+
.catch(() => {
|
|
162
|
+
//
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
return;
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private _mimeType: string;
|
|
170
|
+
private _img_el: HTMLImageElement;
|
|
171
|
+
private _model: BaseOutputView;
|
|
172
|
+
private node: HTMLElement;
|
|
173
|
+
private static Plotly: typeof PlotlyType | null = null;
|
|
174
|
+
private static _resolveLoadingPlotly: () => void;
|
|
175
|
+
private static loadingPlotly = new Promise<void>((resolve) => {
|
|
176
|
+
RenderedPlotly._resolveLoadingPlotly = resolve;
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Render an plotly into a host node.
|
|
182
|
+
*
|
|
183
|
+
* @param options - The options for rendering.
|
|
184
|
+
*
|
|
185
|
+
* @returns A promise which resolves when rendering is complete.
|
|
186
|
+
*/
|
|
187
|
+
export function renderPlotly(options: IRendererPlotlyOptions): Promise<void> {
|
|
188
|
+
const plotlyRender = new RenderedPlotly(options);
|
|
189
|
+
plotlyRender.renderModel(options.model); // Return the rendered promise.
|
|
190
|
+
return Promise.resolve(undefined);
|
|
191
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { RenderMimeContribution } from '@difizen/libro-rendermime';
|
|
2
|
+
import { singleton } from '@difizen/mana-app';
|
|
3
|
+
|
|
4
|
+
import { PlotlyRender } from './plotly-render.js';
|
|
5
|
+
|
|
6
|
+
@singleton({ contrib: RenderMimeContribution })
|
|
7
|
+
export class LibroPlotlyMimeTypeContribution implements RenderMimeContribution {
|
|
8
|
+
canHandle = () => {
|
|
9
|
+
return 100;
|
|
10
|
+
};
|
|
11
|
+
renderType = 'plotlyRender';
|
|
12
|
+
safe = true;
|
|
13
|
+
mimeTypes = ['application/vnd.plotly.v1+json'];
|
|
14
|
+
render = PlotlyRender;
|
|
15
|
+
}
|