@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.
Files changed (146) hide show
  1. package/es/add-between-cell/add-between-cell.js +1 -1
  2. package/es/cell/jupyter-code-cell-view.d.ts +3 -1
  3. package/es/cell/jupyter-code-cell-view.d.ts.map +1 -1
  4. package/es/cell/jupyter-code-cell-view.js +12 -5
  5. package/es/command/command-contribution.d.ts.map +1 -1
  6. package/es/command/command-contribution.js +5 -5
  7. package/es/components/icons.js +1 -1
  8. package/es/contents/content-contribution.js +1 -1
  9. package/es/contents/save-content-contribution.d.ts +10 -0
  10. package/es/contents/save-content-contribution.d.ts.map +1 -0
  11. package/es/contents/save-content-contribution.js +110 -0
  12. package/es/file/file-create-modal.d.ts.map +1 -1
  13. package/es/file/file-create-modal.js +16 -5
  14. package/es/file/file-service.js +1 -1
  15. package/es/file/index.d.ts +1 -0
  16. package/es/file/index.d.ts.map +1 -1
  17. package/es/file/index.js +2 -1
  18. package/es/index.d.ts +1 -0
  19. package/es/index.d.ts.map +1 -1
  20. package/es/index.js +2 -1
  21. package/es/keybind-instructions/index.less +9 -9
  22. package/es/keybind-instructions/keybind-instructions-view.d.ts +2 -2
  23. package/es/keybind-instructions/keybind-instructions-view.d.ts.map +1 -1
  24. package/es/keybind-instructions/keybind-instructions-view.js +69 -63
  25. package/es/libro-jupyter-model.d.ts +2 -4
  26. package/es/libro-jupyter-model.d.ts.map +1 -1
  27. package/es/libro-jupyter-model.js +35 -120
  28. package/es/libro-jupyter-workspace.d.ts +18 -0
  29. package/es/libro-jupyter-workspace.d.ts.map +1 -0
  30. package/es/libro-jupyter-workspace.js +108 -0
  31. package/es/module.d.ts.map +1 -1
  32. package/es/module.js +5 -2
  33. package/es/output/libro-jupyter-outputarea.d.ts.map +1 -1
  34. package/es/output/libro-jupyter-outputarea.js +60 -56
  35. package/es/toolbar/save-file-error.d.ts.map +1 -1
  36. package/es/toolbar/save-file-error.js +20 -13
  37. package/es/widget/box/contribution.d.ts +10 -0
  38. package/es/widget/box/contribution.d.ts.map +1 -0
  39. package/es/widget/box/contribution.js +48 -0
  40. package/es/widget/box/index.d.ts +3 -0
  41. package/es/widget/box/index.d.ts.map +1 -0
  42. package/es/widget/box/index.js +2 -0
  43. package/es/widget/box/index.less +3 -0
  44. package/es/widget/box/view.d.ts +19 -0
  45. package/es/widget/box/view.d.ts.map +1 -0
  46. package/es/widget/box/view.js +114 -0
  47. package/es/widget/comm.d.ts +65 -0
  48. package/es/widget/comm.d.ts.map +1 -0
  49. package/es/widget/comm.js +153 -0
  50. package/es/widget/index.d.ts +10 -0
  51. package/es/widget/index.d.ts.map +1 -0
  52. package/es/widget/index.js +9 -0
  53. package/es/widget/index.less +7 -0
  54. package/es/widget/instance-progress/contribution.d.ts +10 -0
  55. package/es/widget/instance-progress/contribution.d.ts.map +1 -0
  56. package/es/widget/instance-progress/contribution.js +39 -0
  57. package/es/widget/instance-progress/index.d.ts +3 -0
  58. package/es/widget/instance-progress/index.d.ts.map +1 -0
  59. package/es/widget/instance-progress/index.js +2 -0
  60. package/es/widget/instance-progress/view.d.ts +30 -0
  61. package/es/widget/instance-progress/view.d.ts.map +1 -0
  62. package/es/widget/instance-progress/view.js +180 -0
  63. package/es/widget/libro-widgets.d.ts +84 -0
  64. package/es/widget/libro-widgets.d.ts.map +1 -0
  65. package/es/widget/libro-widgets.js +307 -0
  66. package/es/widget/module.d.ts +4 -0
  67. package/es/widget/module.d.ts.map +1 -0
  68. package/es/widget/module.js +38 -0
  69. package/es/widget/progress/contribution.d.ts +10 -0
  70. package/es/widget/progress/contribution.d.ts.map +1 -0
  71. package/es/widget/progress/contribution.js +39 -0
  72. package/es/widget/progress/index.d.ts +3 -0
  73. package/es/widget/progress/index.d.ts.map +1 -0
  74. package/es/widget/progress/index.js +2 -0
  75. package/es/widget/progress/progressBar.d.ts +15 -0
  76. package/es/widget/progress/progressBar.d.ts.map +1 -0
  77. package/es/widget/progress/progressBar.js +20 -0
  78. package/es/widget/progress/view.d.ts +19 -0
  79. package/es/widget/progress/view.d.ts.map +1 -0
  80. package/es/widget/progress/view.js +74 -0
  81. package/es/widget/protocol.d.ts +193 -0
  82. package/es/widget/protocol.d.ts.map +1 -0
  83. package/es/widget/protocol.js +33 -0
  84. package/es/widget/utils.d.ts +27 -0
  85. package/es/widget/utils.d.ts.map +1 -0
  86. package/es/widget/utils.js +59 -0
  87. package/es/widget/version.d.ts +3 -0
  88. package/es/widget/version.d.ts.map +1 -0
  89. package/es/widget/version.js +2 -0
  90. package/es/widget/widget-manager.d.ts +19 -0
  91. package/es/widget/widget-manager.d.ts.map +1 -0
  92. package/es/widget/widget-manager.js +77 -0
  93. package/es/widget/widget-render.d.ts +7 -0
  94. package/es/widget/widget-render.d.ts.map +1 -0
  95. package/es/widget/widget-render.js +46 -0
  96. package/es/widget/widget-rendermime-contribution.d.ts +16 -0
  97. package/es/widget/widget-rendermime-contribution.d.ts.map +1 -0
  98. package/es/widget/widget-rendermime-contribution.js +50 -0
  99. package/es/widget/widget-view-contribution.d.ts +10 -0
  100. package/es/widget/widget-view-contribution.d.ts.map +1 -0
  101. package/es/widget/widget-view-contribution.js +36 -0
  102. package/es/widget/widget-view.d.ts +71 -0
  103. package/es/widget/widget-view.d.ts.map +1 -0
  104. package/es/widget/widget-view.js +273 -0
  105. package/package.json +18 -18
  106. package/src/add-between-cell/add-between-cell.tsx +1 -1
  107. package/src/cell/jupyter-code-cell-view.tsx +14 -6
  108. package/src/command/command-contribution.ts +11 -10
  109. package/src/components/icons.tsx +1 -1
  110. package/src/contents/content-contribution.ts +1 -1
  111. package/src/contents/save-content-contribution.ts +67 -0
  112. package/src/file/file-create-modal.tsx +10 -1
  113. package/src/file/file-service.ts +1 -1
  114. package/src/file/index.ts +1 -0
  115. package/src/index.ts +1 -0
  116. package/src/keybind-instructions/index.less +9 -9
  117. package/src/keybind-instructions/keybind-instructions-view.tsx +72 -62
  118. package/src/libro-jupyter-model.ts +1 -69
  119. package/src/libro-jupyter-workspace.ts +49 -0
  120. package/src/module.ts +6 -0
  121. package/src/output/libro-jupyter-outputarea.tsx +56 -49
  122. package/src/toolbar/save-file-error.tsx +25 -15
  123. package/src/widget/box/contribution.ts +29 -0
  124. package/src/widget/box/index.less +3 -0
  125. package/src/widget/box/index.ts +2 -0
  126. package/src/widget/box/view.tsx +112 -0
  127. package/src/widget/comm.ts +152 -0
  128. package/src/widget/index.less +7 -0
  129. package/src/widget/index.ts +9 -0
  130. package/src/widget/instance-progress/contribution.ts +20 -0
  131. package/src/widget/instance-progress/index.ts +2 -0
  132. package/src/widget/instance-progress/view.tsx +155 -0
  133. package/src/widget/libro-widgets.ts +223 -0
  134. package/src/widget/module.ts +73 -0
  135. package/src/widget/progress/contribution.ts +24 -0
  136. package/src/widget/progress/index.ts +2 -0
  137. package/src/widget/progress/progressBar.tsx +29 -0
  138. package/src/widget/progress/view.tsx +70 -0
  139. package/src/widget/protocol.ts +255 -0
  140. package/src/widget/utils.ts +67 -0
  141. package/src/widget/version.ts +2 -0
  142. package/src/widget/widget-manager.ts +45 -0
  143. package/src/widget/widget-render.tsx +52 -0
  144. package/src/widget/widget-rendermime-contribution.ts +36 -0
  145. package/src/widget/widget-view-contribution.ts +14 -0
  146. 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,2 @@
1
+ export * from './contribution.js';
2
+ export * from './view.js';
@@ -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,2 @@
1
+ export const LIBRO_WIDGETS_VERSION = '2.0.0';
2
+ export const PROTOCOL_VERSION = '2.1.0';
@@ -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
+ }