@difizen/libro-jupyter 0.2.0 → 0.2.2
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/es/add-between-cell/add-between-cell.js +1 -1
- package/es/cell/jupyter-code-cell-view.d.ts +3 -1
- package/es/cell/jupyter-code-cell-view.d.ts.map +1 -1
- package/es/cell/jupyter-code-cell-view.js +12 -5
- package/es/command/command-contribution.d.ts.map +1 -1
- package/es/command/command-contribution.js +5 -5
- package/es/components/icons.js +1 -1
- package/es/contents/content-contribution.js +1 -1
- package/es/contents/save-content-contribution.d.ts +10 -0
- package/es/contents/save-content-contribution.d.ts.map +1 -0
- package/es/contents/save-content-contribution.js +110 -0
- package/es/file/file-create-modal.d.ts.map +1 -1
- package/es/file/file-create-modal.js +16 -5
- package/es/file/file-service.js +1 -1
- package/es/file/index.d.ts +1 -0
- package/es/file/index.d.ts.map +1 -1
- package/es/file/index.js +2 -1
- package/es/index.d.ts +1 -0
- package/es/index.d.ts.map +1 -1
- package/es/index.js +2 -1
- package/es/keybind-instructions/index.less +9 -9
- package/es/keybind-instructions/keybind-instructions-view.d.ts +2 -2
- package/es/keybind-instructions/keybind-instructions-view.d.ts.map +1 -1
- package/es/keybind-instructions/keybind-instructions-view.js +69 -63
- package/es/libro-jupyter-model.d.ts +2 -4
- package/es/libro-jupyter-model.d.ts.map +1 -1
- package/es/libro-jupyter-model.js +35 -120
- package/es/libro-jupyter-workspace.d.ts +18 -0
- package/es/libro-jupyter-workspace.d.ts.map +1 -0
- package/es/libro-jupyter-workspace.js +108 -0
- package/es/module.d.ts.map +1 -1
- package/es/module.js +5 -2
- package/es/output/libro-jupyter-outputarea.d.ts.map +1 -1
- package/es/output/libro-jupyter-outputarea.js +60 -56
- package/es/toolbar/save-file-error.d.ts.map +1 -1
- package/es/toolbar/save-file-error.js +20 -13
- package/es/widget/box/contribution.d.ts +10 -0
- package/es/widget/box/contribution.d.ts.map +1 -0
- package/es/widget/box/contribution.js +48 -0
- package/es/widget/box/index.d.ts +3 -0
- package/es/widget/box/index.d.ts.map +1 -0
- package/es/widget/box/index.js +2 -0
- package/es/widget/box/index.less +3 -0
- package/es/widget/box/view.d.ts +19 -0
- package/es/widget/box/view.d.ts.map +1 -0
- package/es/widget/box/view.js +114 -0
- package/es/widget/comm.d.ts +65 -0
- package/es/widget/comm.d.ts.map +1 -0
- package/es/widget/comm.js +153 -0
- package/es/widget/index.d.ts +10 -0
- package/es/widget/index.d.ts.map +1 -0
- package/es/widget/index.js +9 -0
- package/es/widget/index.less +7 -0
- package/es/widget/instance-progress/contribution.d.ts +10 -0
- package/es/widget/instance-progress/contribution.d.ts.map +1 -0
- package/es/widget/instance-progress/contribution.js +39 -0
- package/es/widget/instance-progress/index.d.ts +3 -0
- package/es/widget/instance-progress/index.d.ts.map +1 -0
- package/es/widget/instance-progress/index.js +2 -0
- package/es/widget/instance-progress/view.d.ts +30 -0
- package/es/widget/instance-progress/view.d.ts.map +1 -0
- package/es/widget/instance-progress/view.js +180 -0
- package/es/widget/libro-widgets.d.ts +84 -0
- package/es/widget/libro-widgets.d.ts.map +1 -0
- package/es/widget/libro-widgets.js +307 -0
- package/es/widget/module.d.ts +4 -0
- package/es/widget/module.d.ts.map +1 -0
- package/es/widget/module.js +38 -0
- package/es/widget/progress/contribution.d.ts +10 -0
- package/es/widget/progress/contribution.d.ts.map +1 -0
- package/es/widget/progress/contribution.js +39 -0
- package/es/widget/progress/index.d.ts +3 -0
- package/es/widget/progress/index.d.ts.map +1 -0
- package/es/widget/progress/index.js +2 -0
- package/es/widget/progress/progressBar.d.ts +15 -0
- package/es/widget/progress/progressBar.d.ts.map +1 -0
- package/es/widget/progress/progressBar.js +20 -0
- package/es/widget/progress/view.d.ts +19 -0
- package/es/widget/progress/view.d.ts.map +1 -0
- package/es/widget/progress/view.js +74 -0
- package/es/widget/protocol.d.ts +193 -0
- package/es/widget/protocol.d.ts.map +1 -0
- package/es/widget/protocol.js +33 -0
- package/es/widget/utils.d.ts +27 -0
- package/es/widget/utils.d.ts.map +1 -0
- package/es/widget/utils.js +59 -0
- package/es/widget/version.d.ts +3 -0
- package/es/widget/version.d.ts.map +1 -0
- package/es/widget/version.js +2 -0
- package/es/widget/widget-manager.d.ts +19 -0
- package/es/widget/widget-manager.d.ts.map +1 -0
- package/es/widget/widget-manager.js +77 -0
- package/es/widget/widget-render.d.ts +7 -0
- package/es/widget/widget-render.d.ts.map +1 -0
- package/es/widget/widget-render.js +46 -0
- package/es/widget/widget-rendermime-contribution.d.ts +16 -0
- package/es/widget/widget-rendermime-contribution.d.ts.map +1 -0
- package/es/widget/widget-rendermime-contribution.js +50 -0
- package/es/widget/widget-view-contribution.d.ts +10 -0
- package/es/widget/widget-view-contribution.d.ts.map +1 -0
- package/es/widget/widget-view-contribution.js +36 -0
- package/es/widget/widget-view.d.ts +71 -0
- package/es/widget/widget-view.d.ts.map +1 -0
- package/es/widget/widget-view.js +273 -0
- package/package.json +18 -18
- package/src/add-between-cell/add-between-cell.tsx +1 -1
- package/src/cell/jupyter-code-cell-view.tsx +14 -6
- package/src/command/command-contribution.ts +11 -10
- package/src/components/icons.tsx +1 -1
- package/src/contents/content-contribution.ts +1 -1
- package/src/contents/save-content-contribution.ts +67 -0
- package/src/file/file-create-modal.tsx +10 -1
- package/src/file/file-service.ts +1 -1
- package/src/file/index.ts +1 -0
- package/src/index.ts +1 -0
- package/src/keybind-instructions/index.less +9 -9
- package/src/keybind-instructions/keybind-instructions-view.tsx +72 -62
- package/src/libro-jupyter-model.ts +1 -69
- package/src/libro-jupyter-workspace.ts +49 -0
- package/src/module.ts +6 -0
- package/src/output/libro-jupyter-outputarea.tsx +56 -49
- package/src/toolbar/save-file-error.tsx +25 -15
- package/src/widget/box/contribution.ts +29 -0
- package/src/widget/box/index.less +3 -0
- package/src/widget/box/index.ts +2 -0
- package/src/widget/box/view.tsx +112 -0
- package/src/widget/comm.ts +152 -0
- package/src/widget/index.less +7 -0
- package/src/widget/index.ts +9 -0
- package/src/widget/instance-progress/contribution.ts +20 -0
- package/src/widget/instance-progress/index.ts +2 -0
- package/src/widget/instance-progress/view.tsx +155 -0
- package/src/widget/libro-widgets.ts +223 -0
- package/src/widget/module.ts +73 -0
- package/src/widget/progress/contribution.ts +24 -0
- package/src/widget/progress/index.ts +2 -0
- package/src/widget/progress/progressBar.tsx +29 -0
- package/src/widget/progress/view.tsx +70 -0
- package/src/widget/protocol.ts +255 -0
- package/src/widget/utils.ts +67 -0
- package/src/widget/version.ts +2 -0
- package/src/widget/widget-manager.ts +45 -0
- package/src/widget/widget-render.tsx +52 -0
- package/src/widget/widget-rendermime-contribution.ts +36 -0
- package/src/widget/widget-view-contribution.ts +14 -0
- package/src/widget/widget-view.tsx +259 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { LibroKernelManageModule } from '@difizen/libro-kernel';
|
|
2
|
+
import { ManaModule } from '@difizen/mana-app';
|
|
3
|
+
|
|
4
|
+
import { VBoxWidget, VBoxWidgetContribution } from './box/index.js';
|
|
5
|
+
import { Comm } from './comm.js';
|
|
6
|
+
import {
|
|
7
|
+
InstancesProgressWidget,
|
|
8
|
+
InstancesProgressWidgetViewContribution,
|
|
9
|
+
} from './instance-progress/index.js';
|
|
10
|
+
import { LibroWidgets } from './libro-widgets.js';
|
|
11
|
+
import { ProgressWidget, ProgressWidgetViewContribution } from './progress/index.js';
|
|
12
|
+
import {
|
|
13
|
+
LibroWidgetCommFactory,
|
|
14
|
+
LibroWidgetsFactory,
|
|
15
|
+
WidgetCommOption,
|
|
16
|
+
WidgetsOption,
|
|
17
|
+
WidgetViewContribution,
|
|
18
|
+
} from './protocol.js';
|
|
19
|
+
import { LibroWidgetManager } from './widget-manager.js';
|
|
20
|
+
import { LibroWidgetMimeContribution } from './widget-rendermime-contribution.js';
|
|
21
|
+
import { DefaultWidgetViewContribution } from './widget-view-contribution.js';
|
|
22
|
+
import { WidgetView } from './widget-view.js';
|
|
23
|
+
|
|
24
|
+
export const BaseWidgetModule = ManaModule.create()
|
|
25
|
+
.contribution(WidgetViewContribution)
|
|
26
|
+
.register(
|
|
27
|
+
Comm,
|
|
28
|
+
{
|
|
29
|
+
token: LibroWidgetCommFactory,
|
|
30
|
+
useFactory: (ctx) => {
|
|
31
|
+
return (options: WidgetCommOption) => {
|
|
32
|
+
const child = ctx.container.createChild();
|
|
33
|
+
child.register({
|
|
34
|
+
token: WidgetCommOption,
|
|
35
|
+
useValue: options,
|
|
36
|
+
});
|
|
37
|
+
return child.get(Comm);
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
LibroWidgets,
|
|
42
|
+
{
|
|
43
|
+
token: LibroWidgetsFactory,
|
|
44
|
+
useFactory: (ctx) => {
|
|
45
|
+
return (options: WidgetsOption) => {
|
|
46
|
+
const child = ctx.container.createChild();
|
|
47
|
+
child.register({
|
|
48
|
+
token: WidgetsOption,
|
|
49
|
+
useValue: options,
|
|
50
|
+
});
|
|
51
|
+
return child.get(LibroWidgets);
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
LibroWidgetManager,
|
|
56
|
+
WidgetView,
|
|
57
|
+
DefaultWidgetViewContribution,
|
|
58
|
+
LibroWidgetMimeContribution,
|
|
59
|
+
)
|
|
60
|
+
.dependOn(LibroKernelManageModule);
|
|
61
|
+
|
|
62
|
+
export const WidgetModule = ManaModule.create()
|
|
63
|
+
.register(
|
|
64
|
+
VBoxWidget,
|
|
65
|
+
VBoxWidgetContribution,
|
|
66
|
+
|
|
67
|
+
ProgressWidget,
|
|
68
|
+
ProgressWidgetViewContribution,
|
|
69
|
+
|
|
70
|
+
InstancesProgressWidget,
|
|
71
|
+
InstancesProgressWidgetViewContribution,
|
|
72
|
+
)
|
|
73
|
+
.dependOn(BaseWidgetModule);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ViewManager, inject, singleton } from '@difizen/mana-app';
|
|
2
|
+
|
|
3
|
+
import type { IWidgetViewProps } from '../protocol.js';
|
|
4
|
+
import { WidgetViewContribution } from '../protocol.js';
|
|
5
|
+
|
|
6
|
+
import { ProgressWidget } from './view.js';
|
|
7
|
+
|
|
8
|
+
@singleton({ contrib: WidgetViewContribution })
|
|
9
|
+
export class ProgressWidgetViewContribution implements WidgetViewContribution {
|
|
10
|
+
@inject(ViewManager) viewManager: ViewManager;
|
|
11
|
+
canHandle = (attributes: any) => {
|
|
12
|
+
if (
|
|
13
|
+
attributes._model_name === 'FloatProgressModel' ||
|
|
14
|
+
attributes._model_name === 'IntProgressModel' ||
|
|
15
|
+
attributes._model_name === 'TransientProgressModel'
|
|
16
|
+
) {
|
|
17
|
+
return 100;
|
|
18
|
+
}
|
|
19
|
+
return 1;
|
|
20
|
+
};
|
|
21
|
+
factory(props: IWidgetViewProps) {
|
|
22
|
+
return this.viewManager.getOrCreateView(ProgressWidget, props);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Progress } from 'antd';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Props for the ProgressBar.
|
|
5
|
+
*/
|
|
6
|
+
export interface IProgressBarProps {
|
|
7
|
+
/**
|
|
8
|
+
* The current progress percentage, from 0 to 100
|
|
9
|
+
*/
|
|
10
|
+
percent: number;
|
|
11
|
+
/**
|
|
12
|
+
* Width of progress bar in pixel.
|
|
13
|
+
*/
|
|
14
|
+
width?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function ProgressBar(props: IProgressBarProps) {
|
|
18
|
+
return (
|
|
19
|
+
<>
|
|
20
|
+
<Progress
|
|
21
|
+
strokeLinecap="butt"
|
|
22
|
+
percent={props.percent}
|
|
23
|
+
strokeWidth={18}
|
|
24
|
+
showInfo={false}
|
|
25
|
+
style={{ width: '200px' }}
|
|
26
|
+
/>
|
|
27
|
+
</>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { JSONObject } from '@difizen/libro-common';
|
|
2
|
+
import { LibroContextKey } from '@difizen/libro-core';
|
|
3
|
+
import {
|
|
4
|
+
view,
|
|
5
|
+
ViewOption,
|
|
6
|
+
transient,
|
|
7
|
+
useInject,
|
|
8
|
+
ViewInstance,
|
|
9
|
+
inject,
|
|
10
|
+
prop,
|
|
11
|
+
} from '@difizen/mana-app';
|
|
12
|
+
import { forwardRef } from 'react';
|
|
13
|
+
|
|
14
|
+
import type { IWidgetViewProps, WidgetState } from '../protocol.js';
|
|
15
|
+
import { defaultWidgetState } from '../protocol.js';
|
|
16
|
+
import { WidgetView } from '../widget-view.js';
|
|
17
|
+
|
|
18
|
+
import { ProgressBar } from './progressBar.js';
|
|
19
|
+
|
|
20
|
+
export const LibroProgressWidgetComponent = forwardRef<HTMLDivElement>(
|
|
21
|
+
function LibroProgressWidgetComponent() {
|
|
22
|
+
const widgetView = useInject<ProgressWidget>(ViewInstance);
|
|
23
|
+
const percent =
|
|
24
|
+
widgetView.state.max && widgetView.state.min
|
|
25
|
+
? widgetView.state.value / ((widgetView.state.max - widgetView.state.min) / 100)
|
|
26
|
+
: 0;
|
|
27
|
+
if (widgetView.isCommClosed) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
return (
|
|
31
|
+
<div className="libro-progress-widget">
|
|
32
|
+
<div className="libro-progress-widget-description">
|
|
33
|
+
{widgetView.state.description}
|
|
34
|
+
</div>
|
|
35
|
+
<ProgressBar percent={percent} />
|
|
36
|
+
</div>
|
|
37
|
+
);
|
|
38
|
+
},
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
interface ProgressState extends WidgetState {
|
|
42
|
+
max?: number;
|
|
43
|
+
min?: number;
|
|
44
|
+
bar_style?: string;
|
|
45
|
+
value: number;
|
|
46
|
+
}
|
|
47
|
+
@transient()
|
|
48
|
+
@view('libro-widget-progress-view')
|
|
49
|
+
export class ProgressWidget extends WidgetView {
|
|
50
|
+
override view = LibroProgressWidgetComponent;
|
|
51
|
+
|
|
52
|
+
@prop()
|
|
53
|
+
override state: JSONObject & ProgressState = {
|
|
54
|
+
...defaultWidgetState,
|
|
55
|
+
max: 1,
|
|
56
|
+
min: 0,
|
|
57
|
+
value: 0,
|
|
58
|
+
};
|
|
59
|
+
constructor(
|
|
60
|
+
@inject(ViewOption) props: IWidgetViewProps,
|
|
61
|
+
@inject(LibroContextKey) libroContextKey: LibroContextKey,
|
|
62
|
+
) {
|
|
63
|
+
super(props, libroContextKey);
|
|
64
|
+
|
|
65
|
+
const attributes = props.attributes;
|
|
66
|
+
this.state.max = attributes.max;
|
|
67
|
+
this.state.min = attributes.min;
|
|
68
|
+
this.setState(attributes);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import type { JSONObject, JSONValue } from '@difizen/libro-common';
|
|
2
|
+
import type { IComm, IKernelConnection, KernelMessage } from '@difizen/libro-kernel';
|
|
3
|
+
import { Syringe } from '@difizen/mana-app';
|
|
4
|
+
|
|
5
|
+
import type { WidgetView } from './widget-view.js';
|
|
6
|
+
|
|
7
|
+
export interface IWidgetViewOptions {
|
|
8
|
+
model_id: string;
|
|
9
|
+
comm: IClassicComm;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface IWidgetViewProps {
|
|
13
|
+
attributes: any;
|
|
14
|
+
options: IWidgetViewOptions;
|
|
15
|
+
widgetsId: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* A simple dictionary type.
|
|
20
|
+
*/
|
|
21
|
+
export type Dict<T> = Record<string, T>;
|
|
22
|
+
|
|
23
|
+
export type BufferJSON =
|
|
24
|
+
| { [property: string]: BufferJSON }
|
|
25
|
+
| BufferJSON[]
|
|
26
|
+
| string
|
|
27
|
+
| number
|
|
28
|
+
| boolean
|
|
29
|
+
| null
|
|
30
|
+
| ArrayBuffer
|
|
31
|
+
| DataView;
|
|
32
|
+
|
|
33
|
+
export interface ISerializedState {
|
|
34
|
+
state: JSONObject;
|
|
35
|
+
buffers: ArrayBuffer[];
|
|
36
|
+
buffer_paths: (string | number)[][];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The widget manager interface exposed on the Widget instances
|
|
41
|
+
*/
|
|
42
|
+
export interface IWidgets {
|
|
43
|
+
getModel: (model_id: string) => WidgetView;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Returns true if the given model is registered, otherwise false.
|
|
47
|
+
*
|
|
48
|
+
* #### Notes
|
|
49
|
+
* This is a synchronous way to check if a model is registered.
|
|
50
|
+
*/
|
|
51
|
+
hasModel: (model_id: string) => boolean;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Register a model instance promise with the manager.
|
|
55
|
+
*
|
|
56
|
+
* By registering the model, it can later be retrieved with `getModel`.
|
|
57
|
+
*/
|
|
58
|
+
registerWidgetView: (model_id: string, model: Promise<WidgetView>) => void;
|
|
59
|
+
|
|
60
|
+
newWidgetView: (attributes: any, options: IWidgetViewOptions) => Promise<WidgetView>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const LibroWidgetsFactory = Symbol('LibroWidgetsFactory');
|
|
64
|
+
export type LibroWidgetsFactory = (options: WidgetsOption) => IWidgets;
|
|
65
|
+
export const WidgetsOption = Symbol('WidgetsOption');
|
|
66
|
+
export interface WidgetsOption {
|
|
67
|
+
kc: IKernelConnection;
|
|
68
|
+
id: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface IWidgetView {
|
|
72
|
+
toJSON: () => string;
|
|
73
|
+
setState: (state: Dict<unknown>) => void;
|
|
74
|
+
handleCommMsg: (msg: KernelMessage.ICommMsgMsg) => Promise<void>;
|
|
75
|
+
model_id: string;
|
|
76
|
+
name: string;
|
|
77
|
+
module: string;
|
|
78
|
+
|
|
79
|
+
model_module: string;
|
|
80
|
+
model_name: string;
|
|
81
|
+
model_module_version: string;
|
|
82
|
+
view_module: string;
|
|
83
|
+
view_name: string | null;
|
|
84
|
+
view_module_version: string;
|
|
85
|
+
view_count: number | null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export const IWidgetView = Symbol('IWidgetView');
|
|
89
|
+
export const WidgetViewContribution = Syringe.defineToken('WidgetViewContribution');
|
|
90
|
+
export interface WidgetViewContribution {
|
|
91
|
+
canHandle: (attributes: any) => number;
|
|
92
|
+
factory: (props: IWidgetViewProps) => Promise<WidgetView>;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface InstanceRecord {
|
|
96
|
+
startDate: number;
|
|
97
|
+
endDate: number;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
interface Stage {
|
|
101
|
+
name: string;
|
|
102
|
+
backup_workers: number;
|
|
103
|
+
terminated_workers: number;
|
|
104
|
+
running_workers: number;
|
|
105
|
+
total_workers: number;
|
|
106
|
+
input_records: number;
|
|
107
|
+
output_records: number;
|
|
108
|
+
finished_percentage: number;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface Task {
|
|
112
|
+
name: string;
|
|
113
|
+
status: 'WAITING' | 'RUNNING' | 'SUCCESS' | 'FAILED' | 'SUSPENDED' | 'CANCELLED';
|
|
114
|
+
stages: Stage[];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface ProgressInstance {
|
|
118
|
+
id: string;
|
|
119
|
+
status: 'Running' | 'Suspended' | 'Terminated';
|
|
120
|
+
logview: string;
|
|
121
|
+
tasks: Task[];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface ProgressItem {
|
|
125
|
+
name: string;
|
|
126
|
+
key: string;
|
|
127
|
+
gen_time: string;
|
|
128
|
+
logView: string;
|
|
129
|
+
instances?: ProgressInstance[];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export type InstancesRecords = Record<string, InstanceRecord>;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Callbacks for services shim comms.
|
|
136
|
+
*/
|
|
137
|
+
export interface ICallbacks {
|
|
138
|
+
shell?: Record<string, (msg: KernelMessage.IShellMessage) => void>;
|
|
139
|
+
iopub?: Record<string, (msg: KernelMessage.IIOPubMessage) => void>;
|
|
140
|
+
input?: (msg: KernelMessage.IStdinMessage) => void;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export const LibroWidgetCommFactory = Symbol('LibroWidgetCommFactory');
|
|
144
|
+
export type LibroWidgetCommFactory = (options: WidgetCommOption) => IClassicComm;
|
|
145
|
+
export const WidgetCommOption = Symbol('WidgetCommOption');
|
|
146
|
+
export interface WidgetCommOption {
|
|
147
|
+
comm: IComm;
|
|
148
|
+
}
|
|
149
|
+
export interface IClassicComm {
|
|
150
|
+
/**
|
|
151
|
+
* Comm id
|
|
152
|
+
* @return {string}
|
|
153
|
+
*/
|
|
154
|
+
comm_id: string;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Target name
|
|
158
|
+
* @return {string}
|
|
159
|
+
*/
|
|
160
|
+
target_name: string;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Opens a sibling comm in the backend
|
|
164
|
+
* @param data
|
|
165
|
+
* @param callbacks
|
|
166
|
+
* @param metadata
|
|
167
|
+
* @param buffers
|
|
168
|
+
* @return msg id
|
|
169
|
+
*/
|
|
170
|
+
open(
|
|
171
|
+
data: JSONValue,
|
|
172
|
+
callbacks?: ICallbacks,
|
|
173
|
+
metadata?: JSONObject,
|
|
174
|
+
buffers?: ArrayBuffer[] | ArrayBufferView[],
|
|
175
|
+
): string;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Sends a message to the sibling comm in the backend
|
|
179
|
+
* @param data
|
|
180
|
+
* @param callbacks
|
|
181
|
+
* @param metadata
|
|
182
|
+
* @param buffers
|
|
183
|
+
* @return message id
|
|
184
|
+
*/
|
|
185
|
+
send(
|
|
186
|
+
data: JSONValue,
|
|
187
|
+
callbacks?: ICallbacks,
|
|
188
|
+
metadata?: JSONObject,
|
|
189
|
+
buffers?: ArrayBuffer[] | ArrayBufferView[],
|
|
190
|
+
): string;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Closes the sibling comm in the backend
|
|
194
|
+
* @param data
|
|
195
|
+
* @param callbacks
|
|
196
|
+
* @param metadata
|
|
197
|
+
* @param buffers
|
|
198
|
+
* @return msg id
|
|
199
|
+
*/
|
|
200
|
+
close(
|
|
201
|
+
data?: JSONValue,
|
|
202
|
+
callbacks?: ICallbacks,
|
|
203
|
+
metadata?: JSONObject,
|
|
204
|
+
buffers?: ArrayBuffer[] | ArrayBufferView[],
|
|
205
|
+
): string;
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Register a message handler
|
|
209
|
+
* @param callback, which is given a message
|
|
210
|
+
*/
|
|
211
|
+
onMsg(callback: (x: any) => void): void;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Register a handler for when the comm is closed by the backend
|
|
215
|
+
* @param callback, which is given a message
|
|
216
|
+
*/
|
|
217
|
+
onClose(callback: (x: any) => void): void;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export interface WidgetState {
|
|
221
|
+
msg_id?: string;
|
|
222
|
+
behavior?: string;
|
|
223
|
+
continuous_update: boolean;
|
|
224
|
+
description: string;
|
|
225
|
+
description_allow_html: boolean;
|
|
226
|
+
disabled: boolean;
|
|
227
|
+
layout?: string;
|
|
228
|
+
readout: boolean;
|
|
229
|
+
readout_format: string;
|
|
230
|
+
style?: string;
|
|
231
|
+
[key: string]: any;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export const defaultWidgetState: WidgetState = {
|
|
235
|
+
continuous_update: false,
|
|
236
|
+
description_allow_html: false,
|
|
237
|
+
description: '',
|
|
238
|
+
disabled: false,
|
|
239
|
+
readout: true,
|
|
240
|
+
readout_format: 'd',
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
export interface FormattableState {
|
|
244
|
+
readout: boolean;
|
|
245
|
+
readout_format: string;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export const defaultFormattableState: FormattableState = {
|
|
249
|
+
readout: true,
|
|
250
|
+
readout_format: 'd',
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
export interface OrientableState {
|
|
254
|
+
orientation: 'horizontal' | 'vertical';
|
|
255
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { BufferJSON, Dict } from './protocol.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Takes an object 'state' and fills in buffer[i] at 'path' buffer_paths[i]
|
|
5
|
+
* where buffer_paths[i] is a list indicating where in the object buffer[i] should
|
|
6
|
+
* be placed
|
|
7
|
+
* Example: state = {a: 1, b: {}, c: [0, null]}
|
|
8
|
+
* buffers = [array1, array2]
|
|
9
|
+
* buffer_paths = [['b', 'data'], ['c', 1]]
|
|
10
|
+
* Will lead to {a: 1, b: {data: array1}, c: [0, array2]}
|
|
11
|
+
*/
|
|
12
|
+
export function put_buffers(
|
|
13
|
+
state: Dict<BufferJSON>,
|
|
14
|
+
buffer_paths: (string | number)[][],
|
|
15
|
+
buffers: (DataView | ArrayBuffer | ArrayBufferView | { buffer: ArrayBuffer })[],
|
|
16
|
+
): void {
|
|
17
|
+
for (let i = 0; i < buffer_paths.length; i++) {
|
|
18
|
+
const buffer_path = buffer_paths[i];
|
|
19
|
+
// make sure the buffers are DataViews
|
|
20
|
+
let buffer = buffers[i];
|
|
21
|
+
if (!(buffer instanceof DataView)) {
|
|
22
|
+
buffer = new DataView(buffer instanceof ArrayBuffer ? buffer : buffer.buffer);
|
|
23
|
+
}
|
|
24
|
+
// say we want to set state[x][y][z] = buffer
|
|
25
|
+
let obj = state as any;
|
|
26
|
+
// we first get obj = state[x][y]
|
|
27
|
+
for (let j = 0; j < buffer_path.length - 1; j++) {
|
|
28
|
+
obj = obj[buffer_path[j]];
|
|
29
|
+
}
|
|
30
|
+
// and then set: obj[z] = buffer
|
|
31
|
+
obj[buffer_path[buffer_path.length - 1]] = buffer;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Creates a wrappable Promise rejection function.
|
|
37
|
+
*
|
|
38
|
+
* Creates a function that logs an error message before rethrowing
|
|
39
|
+
* the original error that caused the promise to reject.
|
|
40
|
+
*/
|
|
41
|
+
export function reject(message: string, log: boolean) {
|
|
42
|
+
return function promiseRejection(error: Error): never {
|
|
43
|
+
if (log) {
|
|
44
|
+
console.error(new Error(message));
|
|
45
|
+
}
|
|
46
|
+
throw error;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* A polyfill for Object.assign
|
|
52
|
+
*
|
|
53
|
+
* This is from code that Typescript 2.4 generates for a polyfill.
|
|
54
|
+
*/
|
|
55
|
+
export const assign =
|
|
56
|
+
(Object as any).assign ||
|
|
57
|
+
function (t: any, ...args: any[]): any {
|
|
58
|
+
for (let i = 1; i < args.length; i++) {
|
|
59
|
+
const s = args[i];
|
|
60
|
+
for (const p in s) {
|
|
61
|
+
if (Object.prototype.hasOwnProperty.call(s, p)) {
|
|
62
|
+
t[p] = s[p];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return t;
|
|
67
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { LibroService } from '@difizen/libro-core';
|
|
2
|
+
import type { IKernelConnection } from '@difizen/libro-kernel';
|
|
3
|
+
import { KernelConnection, LibroKernelManager } from '@difizen/libro-kernel';
|
|
4
|
+
import { inject, prop, singleton, ApplicationContribution } from '@difizen/mana-app';
|
|
5
|
+
|
|
6
|
+
import type { LibroWidgets } from './libro-widgets.js';
|
|
7
|
+
import { LibroWidgetsFactory } from './protocol.js';
|
|
8
|
+
import type { WidgetsOption } from './protocol.js';
|
|
9
|
+
|
|
10
|
+
@singleton({ contrib: ApplicationContribution })
|
|
11
|
+
export class LibroWidgetManager implements ApplicationContribution {
|
|
12
|
+
@inject(LibroWidgetsFactory) widgetsFactory!: (
|
|
13
|
+
options: WidgetsOption,
|
|
14
|
+
) => LibroWidgets;
|
|
15
|
+
@inject(LibroKernelManager) kernelManager: LibroKernelManager;
|
|
16
|
+
@inject(LibroService) libroService: LibroService;
|
|
17
|
+
|
|
18
|
+
initialize = () => {
|
|
19
|
+
this.kernelManager.onConnectToKernel((kc) => {
|
|
20
|
+
if (kc instanceof KernelConnection) {
|
|
21
|
+
this.getOrCreateWidgets(kc);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
getOrCreateWidgets = (kc: IKernelConnection) => {
|
|
27
|
+
const widgets = this.widgets.get(kc.id);
|
|
28
|
+
if (widgets) {
|
|
29
|
+
return widgets;
|
|
30
|
+
}
|
|
31
|
+
const newWidgets = this.widgetsFactory({ kc, id: kc.id });
|
|
32
|
+
this.widgets.set(kc.id, newWidgets);
|
|
33
|
+
return newWidgets;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
getWidgets(id: string) {
|
|
37
|
+
return this.widgets.get(id);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Dictionary of model ids and model instance promises
|
|
42
|
+
*/
|
|
43
|
+
@prop()
|
|
44
|
+
protected widgets: Map<string, LibroWidgets> = new Map();
|
|
45
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { BaseOutputView, LibroOutputView } from '@difizen/libro-core';
|
|
2
|
+
import { RenderMimeRegistry } from '@difizen/libro-rendermime';
|
|
3
|
+
import type { IRenderMimeRegistry } from '@difizen/libro-rendermime';
|
|
4
|
+
import { getOrigin, useInject, ViewInstance, ViewRender } from '@difizen/mana-app';
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import './index.less';
|
|
8
|
+
import { LibroJupyterModel } from '../libro-jupyter-model.js';
|
|
9
|
+
|
|
10
|
+
import { LibroWidgetManager } from './widget-manager.js';
|
|
11
|
+
|
|
12
|
+
export const WidgetRender: React.FC<{ model: BaseOutputView }> = (props: {
|
|
13
|
+
model: BaseOutputView;
|
|
14
|
+
}) => {
|
|
15
|
+
const { model } = props;
|
|
16
|
+
|
|
17
|
+
// The widget will be rendered in the output through the MIME mechanism, obtaining the output context.
|
|
18
|
+
const output = useInject<LibroOutputView>(ViewInstance);
|
|
19
|
+
|
|
20
|
+
const widgetManager = useInject(LibroWidgetManager);
|
|
21
|
+
const defaultRenderMime = useInject<IRenderMimeRegistry>(RenderMimeRegistry);
|
|
22
|
+
const libro = model.cell.parent;
|
|
23
|
+
if (!(libro.model instanceof LibroJupyterModel) || !libro.model.kernelConnection) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
const widgets = widgetManager.getOrCreateWidgets(
|
|
27
|
+
getOrigin(libro.model.kernelConnection),
|
|
28
|
+
);
|
|
29
|
+
const mimeType = defaultRenderMime.preferredMimeType(model);
|
|
30
|
+
if (mimeType) {
|
|
31
|
+
const model_id = JSON.parse(JSON.stringify(model.data[mimeType])).model_id;
|
|
32
|
+
if (model_id) {
|
|
33
|
+
const widgetView = widgets.getModel(model_id);
|
|
34
|
+
widgetView.setCell(getOrigin(output.cell));
|
|
35
|
+
if (widgetView.isCommClosed) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
return (
|
|
39
|
+
<div className="libro-widget-render-container">
|
|
40
|
+
<div className="libro-widget-render">
|
|
41
|
+
<ViewRender view={widgetView} />
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return (
|
|
48
|
+
<div className="libro-widget-render-container">
|
|
49
|
+
<div className="libro-widget-render empty" />
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { BaseOutputView } from '@difizen/libro-core';
|
|
2
|
+
import { RenderMimeContribution } from '@difizen/libro-rendermime';
|
|
3
|
+
import { inject, singleton } from '@difizen/mana-app';
|
|
4
|
+
|
|
5
|
+
import { LibroJupyterModel } from '../libro-jupyter-model.js';
|
|
6
|
+
|
|
7
|
+
import { LibroWidgetManager } from './widget-manager.js';
|
|
8
|
+
import { WidgetRender } from './widget-render.js';
|
|
9
|
+
|
|
10
|
+
@singleton({ contrib: RenderMimeContribution })
|
|
11
|
+
export class LibroWidgetMimeContribution implements RenderMimeContribution {
|
|
12
|
+
@inject(LibroWidgetManager) libroWidgetManager: LibroWidgetManager;
|
|
13
|
+
canHandle = (model: BaseOutputView) => {
|
|
14
|
+
const libroModel = model.cell.parent.model;
|
|
15
|
+
let rank = 0;
|
|
16
|
+
if (libroModel instanceof LibroJupyterModel && libroModel.kernelConnection) {
|
|
17
|
+
const kc = libroModel.kernelConnection;
|
|
18
|
+
const widget = this.libroWidgetManager.getOrCreateWidgets(kc);
|
|
19
|
+
this.mimeTypes.forEach((mimeType) => {
|
|
20
|
+
const mimeData = model.data[mimeType];
|
|
21
|
+
if (mimeData && mimeData !== null) {
|
|
22
|
+
const data = JSON.parse(JSON.stringify(mimeData)).model_id;
|
|
23
|
+
if (Object.keys(model.data).includes(mimeType) && widget.hasModel(data)) {
|
|
24
|
+
rank = 100;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
return rank;
|
|
30
|
+
};
|
|
31
|
+
renderType = 'widgetRenderer';
|
|
32
|
+
safe = true;
|
|
33
|
+
mimeTypes = ['application/vnd.jupyter.widget-view+json'];
|
|
34
|
+
allowClear = false;
|
|
35
|
+
render = WidgetRender;
|
|
36
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ViewManager, inject, singleton } from '@difizen/mana-app';
|
|
2
|
+
|
|
3
|
+
import type { IWidgetViewProps } from './protocol.js';
|
|
4
|
+
import { WidgetViewContribution } from './protocol.js';
|
|
5
|
+
import { WidgetView } from './widget-view.js';
|
|
6
|
+
|
|
7
|
+
@singleton({ contrib: WidgetViewContribution })
|
|
8
|
+
export class DefaultWidgetViewContribution implements WidgetViewContribution {
|
|
9
|
+
@inject(ViewManager) viewManager: ViewManager;
|
|
10
|
+
canHandle = () => 1;
|
|
11
|
+
factory(props: IWidgetViewProps) {
|
|
12
|
+
return this.viewManager.getOrCreateView(WidgetView, props);
|
|
13
|
+
}
|
|
14
|
+
}
|