@fails-components/jupyter-launcher 0.0.1-alpha.9 → 0.0.3
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/lib/index.d.ts +3 -49
- package/lib/index.js +72 -46
- package/lib/tokens.d.ts +33 -0
- package/lib/tokens.js +2 -0
- package/package.json +22 -17
- package/src/index.ts +81 -114
- package/src/tokens.ts +43 -0
package/lib/index.d.ts
CHANGED
|
@@ -1,59 +1,13 @@
|
|
|
1
1
|
import { JupyterFrontEndPlugin } from '@jupyterlab/application';
|
|
2
|
-
import { JSONObject
|
|
3
|
-
import {
|
|
2
|
+
import { JSONObject } from '@lumino/coreutils';
|
|
3
|
+
import { IFailsAppletSize } from './tokens';
|
|
4
|
+
export * from './tokens';
|
|
4
5
|
export interface IScreenShotOpts {
|
|
5
6
|
dpi: number;
|
|
6
7
|
}
|
|
7
8
|
export interface IAppletScreenshottaker {
|
|
8
9
|
takeAppScreenshot: (opts: IScreenShotOpts) => Promise<Blob | undefined>;
|
|
9
10
|
}
|
|
10
|
-
interface IContentEvent {
|
|
11
|
-
task: string;
|
|
12
|
-
}
|
|
13
|
-
export interface ILoadJupyterContentEvent extends IContentEvent {
|
|
14
|
-
task: 'loadFile';
|
|
15
|
-
fileData: object | undefined;
|
|
16
|
-
fileName: string;
|
|
17
|
-
}
|
|
18
|
-
export interface ISavedJupyterContentEvent extends IContentEvent {
|
|
19
|
-
task: 'savedFile';
|
|
20
|
-
fileName: string;
|
|
21
|
-
}
|
|
22
|
-
export type IContentEventType = ILoadJupyterContentEvent | ISavedJupyterContentEvent;
|
|
23
|
-
export interface IFailsCallbacks {
|
|
24
|
-
callContents?: (event: IContentEventType) => Promise<any>;
|
|
25
|
-
postMessageToFails?: (message: any, transfer?: Transferable[]) => void;
|
|
26
|
-
}
|
|
27
|
-
export declare const IFailsLauncherInfo: Token<IFailsLauncherInfo>;
|
|
28
|
-
export interface IFailsLauncherInit {
|
|
29
|
-
inLecture: boolean;
|
|
30
|
-
selectedAppid: string | undefined;
|
|
31
|
-
reportMetadata?: (metadata: PartialJSONObject) => void;
|
|
32
|
-
}
|
|
33
|
-
export interface IFailsAppletSize {
|
|
34
|
-
appid: string;
|
|
35
|
-
width: number;
|
|
36
|
-
height: number;
|
|
37
|
-
}
|
|
38
|
-
export interface IAppletWidgetRegistry {
|
|
39
|
-
}
|
|
40
|
-
export interface IFailsInterceptorUpdateMessage {
|
|
41
|
-
path: string;
|
|
42
|
-
mime: string;
|
|
43
|
-
state: JSONObject;
|
|
44
|
-
}
|
|
45
|
-
export interface IFailsLauncherInfo extends IFailsLauncherInit {
|
|
46
|
-
inLectureChanged: ISignal<IFailsLauncherInfo, boolean>;
|
|
47
|
-
selectedAppidChanged: ISignal<this, string | undefined>;
|
|
48
|
-
appletSizes: {
|
|
49
|
-
[key: string]: IFailsAppletSize;
|
|
50
|
-
};
|
|
51
|
-
appletSizesChanged: ISignal<this, {
|
|
52
|
-
[key: string]: IFailsAppletSize;
|
|
53
|
-
}>;
|
|
54
|
-
updateMessageArrived?: ISignal<IAppletWidgetRegistry, IFailsInterceptorUpdateMessage>;
|
|
55
|
-
remoteUpdateMessageArrived: ISignal<IFailsLauncherInfo, IFailsInterceptorUpdateMessage>;
|
|
56
|
-
}
|
|
57
11
|
export interface IReplyJupyter {
|
|
58
12
|
requestId?: number;
|
|
59
13
|
}
|
package/lib/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { ILabStatus } from '@jupyterlab/application';
|
|
2
2
|
import { IDocumentManager } from '@jupyterlab/docmanager';
|
|
3
|
-
import {
|
|
4
|
-
import { PageConfig, URLExt } from '@jupyterlab/coreutils';
|
|
3
|
+
import { ILicensesClient } from '@jupyterlab/apputils';
|
|
5
4
|
import { INotebookShell } from '@jupyter-notebook/application';
|
|
6
5
|
import { NotebookActions } from '@jupyterlab/notebook';
|
|
7
|
-
import { Token } from '@lumino/coreutils';
|
|
8
6
|
import { Signal } from '@lumino/signaling';
|
|
9
|
-
|
|
7
|
+
import { IFailsDriveMessages } from '@fails-components/jupyter-filesystem-extension';
|
|
8
|
+
import { IFailsLauncherInfo } from './tokens';
|
|
9
|
+
export * from './tokens';
|
|
10
10
|
let screenShotPatchInstalled = false;
|
|
11
11
|
const installScreenShotPatches = () => {
|
|
12
12
|
if (screenShotPatchInstalled) {
|
|
@@ -80,6 +80,20 @@ const installFetchPatches = ({ allowedSites = undefined, proxySites = undefined,
|
|
|
80
80
|
headers: { 'Content-Type': 'text/plain' }
|
|
81
81
|
});
|
|
82
82
|
};
|
|
83
|
+
const oldImportScripts = globalThis.importScripts;
|
|
84
|
+
globalThis.importScripts = (...args) => {
|
|
85
|
+
const newargs = args.map(url => {
|
|
86
|
+
const urlObj = new URL(url, location.href);
|
|
87
|
+
if (allowedOrigins.includes(urlObj.origin)) {
|
|
88
|
+
return url;
|
|
89
|
+
}
|
|
90
|
+
if (proxySites && proxySites.includes(urlObj.origin)) {
|
|
91
|
+
return proxyURL + urlObj.hostname + urlObj.pathname;
|
|
92
|
+
}
|
|
93
|
+
throw new Error('Script is from blocked URL');
|
|
94
|
+
});
|
|
95
|
+
return oldImportScripts(...newargs);
|
|
96
|
+
};
|
|
83
97
|
const oldWorker = Worker;
|
|
84
98
|
const NewWorker = function (script, options) {
|
|
85
99
|
const scriptURL = script instanceof URL ? script : new URL(script, location.href);
|
|
@@ -132,6 +146,20 @@ const installFetchPatches = ({ allowedSites = undefined, proxySites = undefined,
|
|
|
132
146
|
headers: { 'Content-Type': 'text/plain' }
|
|
133
147
|
});
|
|
134
148
|
};
|
|
149
|
+
const oldImportScripts = globalThis.importScripts;
|
|
150
|
+
globalThis.importScripts = (...args) => {
|
|
151
|
+
const newargs = args.map(url => {
|
|
152
|
+
const urlObj = new URL(url, location.href);
|
|
153
|
+
if (allowedOrigins.includes(urlObj.origin)) {
|
|
154
|
+
return url;
|
|
155
|
+
}
|
|
156
|
+
if (proxySites && proxySites.includes(urlObj.origin)) {
|
|
157
|
+
return proxyURL + urlObj.hostname + urlObj.pathname;
|
|
158
|
+
}
|
|
159
|
+
throw new Error('Script is from blocked URL');
|
|
160
|
+
});
|
|
161
|
+
return oldImportScripts(...newargs);
|
|
162
|
+
};
|
|
135
163
|
Object.defineProperty(globalThis, 'location', {
|
|
136
164
|
value: new URL('${scriptURL.href}'),
|
|
137
165
|
writable: false,
|
|
@@ -246,9 +274,10 @@ class FailsLauncherInfo {
|
|
|
246
274
|
this._remoteUpdateMessageArrived.emit(message);
|
|
247
275
|
}
|
|
248
276
|
}
|
|
249
|
-
function activateFailsLauncher(app, docManager, status, shell) {
|
|
277
|
+
function activateFailsLauncher(app, docManager, status, licenseClient, driveMessages, shell) {
|
|
250
278
|
// parts taken from repl-extension
|
|
251
279
|
const { /* commands, */ serviceManager, started } = app;
|
|
280
|
+
const sendMessageToDrive = driveMessages.sendMessage;
|
|
252
281
|
Promise.all([started, serviceManager.ready]).then(async () => {
|
|
253
282
|
/* commands.execute('notebook:create-new', {
|
|
254
283
|
kernelId: undefined,
|
|
@@ -260,28 +289,20 @@ function activateFailsLauncher(app, docManager, status, shell) {
|
|
|
260
289
|
const { docRegistry } = app;
|
|
261
290
|
const failsLauncherInfo = new FailsLauncherInfo();
|
|
262
291
|
let currentDocWidget;
|
|
263
|
-
const serverSettings = app.serviceManager.serverSettings;
|
|
264
|
-
const licensesUrl = URLExt.join(PageConfig.getBaseUrl(), PageConfig.getOption('licensesUrl')) +
|
|
265
|
-
'/';
|
|
266
|
-
// Install Messagehandler
|
|
267
|
-
if (!window.failsCallbacks) {
|
|
268
|
-
window.failsCallbacks = {};
|
|
269
|
-
}
|
|
270
292
|
let senderOrigin;
|
|
271
|
-
const
|
|
272
|
-
_failsCallbacks.postMessageToFails = (message, transfer) => {
|
|
293
|
+
const postMessageToFails = (message, transfer) => {
|
|
273
294
|
if (typeof senderOrigin !== 'undefined') {
|
|
274
295
|
window.parent.postMessage(message, senderOrigin, transfer);
|
|
275
296
|
}
|
|
276
297
|
};
|
|
277
298
|
status.dirtySignal.connect((sender, dirty) => {
|
|
278
|
-
|
|
299
|
+
postMessageToFails({
|
|
279
300
|
task: 'docDirty',
|
|
280
301
|
dirty
|
|
281
302
|
});
|
|
282
303
|
});
|
|
283
304
|
failsLauncherInfo.reportMetadata = metadata => {
|
|
284
|
-
|
|
305
|
+
postMessageToFails({
|
|
285
306
|
task: 'reportMetadata',
|
|
286
307
|
metadata
|
|
287
308
|
});
|
|
@@ -292,14 +313,14 @@ function activateFailsLauncher(app, docManager, status, shell) {
|
|
|
292
313
|
}
|
|
293
314
|
});
|
|
294
315
|
failsLauncherInfo.appletSizesChanged.connect((sender, appletSizes) => {
|
|
295
|
-
|
|
316
|
+
postMessageToFails({
|
|
296
317
|
task: 'reportFailsAppletSizes',
|
|
297
318
|
appletSizes
|
|
298
319
|
});
|
|
299
320
|
});
|
|
300
321
|
let interceptorActivated = false;
|
|
301
322
|
const sendInterceptorUpdate = (sender, message) => {
|
|
302
|
-
|
|
323
|
+
postMessageToFails({
|
|
303
324
|
task: 'sendInterceptorUpdate',
|
|
304
325
|
...message
|
|
305
326
|
});
|
|
@@ -328,7 +349,7 @@ function activateFailsLauncher(app, docManager, status, shell) {
|
|
|
328
349
|
// may be use a promise for fullfillment, e.g. pass a resolve
|
|
329
350
|
// afterwards we load the file or new file into to the contexts
|
|
330
351
|
// we may also send license information
|
|
331
|
-
|
|
352
|
+
sendMessageToDrive({
|
|
332
353
|
task: 'loadFile',
|
|
333
354
|
fileData: loadJupyterInfo.fileData,
|
|
334
355
|
fileName: loadJupyterInfo.fileName
|
|
@@ -350,7 +371,7 @@ function activateFailsLauncher(app, docManager, status, shell) {
|
|
|
350
371
|
if (typeof currentDocWidget !== 'undefined') {
|
|
351
372
|
const notebookPanel = currentDocWidget;
|
|
352
373
|
notebookPanel.sessionContext.statusChanged.connect((context, status) => {
|
|
353
|
-
|
|
374
|
+
postMessageToFails({
|
|
354
375
|
task: 'reportKernelStatus',
|
|
355
376
|
status
|
|
356
377
|
});
|
|
@@ -370,7 +391,7 @@ function activateFailsLauncher(app, docManager, status, shell) {
|
|
|
370
391
|
});
|
|
371
392
|
}
|
|
372
393
|
})
|
|
373
|
-
.catch(error => {
|
|
394
|
+
.catch((error) => {
|
|
374
395
|
console.log('Problem task load file', error);
|
|
375
396
|
});
|
|
376
397
|
}
|
|
@@ -379,7 +400,7 @@ function activateFailsLauncher(app, docManager, status, shell) {
|
|
|
379
400
|
{
|
|
380
401
|
const saveJupyter = event.data;
|
|
381
402
|
if (typeof currentDocWidget === 'undefined') {
|
|
382
|
-
|
|
403
|
+
postMessageToFails({
|
|
383
404
|
requestId: event.data.requestId,
|
|
384
405
|
task: 'saveJupyter',
|
|
385
406
|
error: 'No document loaded'
|
|
@@ -388,7 +409,7 @@ function activateFailsLauncher(app, docManager, status, shell) {
|
|
|
388
409
|
}
|
|
389
410
|
const context = docManager.contextForWidget(currentDocWidget);
|
|
390
411
|
if (typeof context === 'undefined') {
|
|
391
|
-
|
|
412
|
+
postMessageToFails({
|
|
392
413
|
requestId: event.data.requestId,
|
|
393
414
|
task: 'saveJupyter',
|
|
394
415
|
error: 'No document context'
|
|
@@ -397,22 +418,22 @@ function activateFailsLauncher(app, docManager, status, shell) {
|
|
|
397
418
|
}
|
|
398
419
|
context
|
|
399
420
|
.save()
|
|
400
|
-
.then(() => {
|
|
421
|
+
.then(async () => {
|
|
401
422
|
// ok it was save to our virtual disk
|
|
402
|
-
return
|
|
423
|
+
return await sendMessageToDrive({
|
|
403
424
|
task: 'savedFile',
|
|
404
425
|
fileName: saveJupyter.fileName
|
|
405
426
|
});
|
|
406
427
|
})
|
|
407
428
|
.then(({ fileData }) => {
|
|
408
|
-
|
|
429
|
+
postMessageToFails({
|
|
409
430
|
requestId: event.data.requestId,
|
|
410
431
|
task: 'saveJupyter',
|
|
411
432
|
fileData
|
|
412
433
|
});
|
|
413
434
|
})
|
|
414
435
|
.catch((error) => {
|
|
415
|
-
|
|
436
|
+
postMessageToFails({
|
|
416
437
|
requestId: event.data.requestId,
|
|
417
438
|
task: 'saveJupyter',
|
|
418
439
|
error: error.toString()
|
|
@@ -429,7 +450,7 @@ function activateFailsLauncher(app, docManager, status, shell) {
|
|
|
429
450
|
else {
|
|
430
451
|
failsLauncherInfo.inLecture = false;
|
|
431
452
|
}
|
|
432
|
-
|
|
453
|
+
postMessageToFails({
|
|
433
454
|
requestId: event.data.requestId,
|
|
434
455
|
task: 'activateApp'
|
|
435
456
|
});
|
|
@@ -440,7 +461,7 @@ function activateFailsLauncher(app, docManager, status, shell) {
|
|
|
440
461
|
const screenshotApp = event.data;
|
|
441
462
|
const notebookPanel = currentDocWidget;
|
|
442
463
|
if (!(typeof notebookPanel['takeAppScreenshot'] === 'function')) {
|
|
443
|
-
|
|
464
|
+
postMessageToFails({
|
|
444
465
|
requestId: event.data.requestId,
|
|
445
466
|
task: 'screenshotApp',
|
|
446
467
|
error: 'Take App Screenshot unsupported'
|
|
@@ -450,17 +471,16 @@ function activateFailsLauncher(app, docManager, status, shell) {
|
|
|
450
471
|
screenShotTaker
|
|
451
472
|
.takeAppScreenshot({ dpi: screenshotApp.dpi })
|
|
452
473
|
.then(async (screenshot) => {
|
|
453
|
-
var _a, _b;
|
|
454
474
|
if (screenshot) {
|
|
455
475
|
const data = await screenshot.arrayBuffer();
|
|
456
|
-
|
|
476
|
+
postMessageToFails === null || postMessageToFails === void 0 ? void 0 : postMessageToFails({
|
|
457
477
|
requestId: event.data.requestId,
|
|
458
478
|
task: 'screenshotApp',
|
|
459
479
|
screenshot: { data, type: screenshot.type }
|
|
460
480
|
}, [data]); // TODO add transferable
|
|
461
481
|
}
|
|
462
482
|
else {
|
|
463
|
-
|
|
483
|
+
postMessageToFails === null || postMessageToFails === void 0 ? void 0 : postMessageToFails({
|
|
464
484
|
requestId: event.data.requestId,
|
|
465
485
|
task: 'screenshotApp',
|
|
466
486
|
error: 'Screenshot failed?'
|
|
@@ -469,7 +489,7 @@ function activateFailsLauncher(app, docManager, status, shell) {
|
|
|
469
489
|
})
|
|
470
490
|
.catch((error) => {
|
|
471
491
|
console.log('Screenshot error', error);
|
|
472
|
-
|
|
492
|
+
postMessageToFails({
|
|
473
493
|
requestId: event.data.requestId,
|
|
474
494
|
task: 'screenshotApp',
|
|
475
495
|
error: error.toString()
|
|
@@ -491,7 +511,7 @@ function activateFailsLauncher(app, docManager, status, shell) {
|
|
|
491
511
|
interceptorActivated = false;
|
|
492
512
|
}
|
|
493
513
|
}
|
|
494
|
-
|
|
514
|
+
postMessageToFails({
|
|
495
515
|
requestId: event.data.requestId,
|
|
496
516
|
task: 'activateInterceptor'
|
|
497
517
|
});
|
|
@@ -503,7 +523,7 @@ function activateFailsLauncher(app, docManager, status, shell) {
|
|
|
503
523
|
const { path, mime, state } = receiveInterceptorUpdate;
|
|
504
524
|
const launcherInfo = failsLauncherInfo;
|
|
505
525
|
launcherInfo.receiveRemoteUpdateMessage({ path, mime, state });
|
|
506
|
-
|
|
526
|
+
postMessageToFails({
|
|
507
527
|
requestId: event.data.requestId,
|
|
508
528
|
task: 'receiveInterceptorUpdate'
|
|
509
529
|
});
|
|
@@ -512,7 +532,7 @@ function activateFailsLauncher(app, docManager, status, shell) {
|
|
|
512
532
|
case 'restartKernelAndRerunCells':
|
|
513
533
|
{
|
|
514
534
|
if (typeof currentDocWidget === 'undefined') {
|
|
515
|
-
|
|
535
|
+
postMessageToFails({
|
|
516
536
|
requestId: event.data.requestId,
|
|
517
537
|
task: 'restartKernelAndRerunCell',
|
|
518
538
|
error: 'No document loaded'
|
|
@@ -527,14 +547,14 @@ function activateFailsLauncher(app, docManager, status, shell) {
|
|
|
527
547
|
.restartKernel()
|
|
528
548
|
.then(async () => {
|
|
529
549
|
await NotebookActions.runCells(content, cells, context.sessionContext);
|
|
530
|
-
|
|
550
|
+
postMessageToFails({
|
|
531
551
|
requestId: event.data.requestId,
|
|
532
552
|
task: 'restartKernelAndRerunCell',
|
|
533
553
|
success: true
|
|
534
554
|
});
|
|
535
555
|
})
|
|
536
556
|
.catch((error) => {
|
|
537
|
-
|
|
557
|
+
postMessageToFails({
|
|
538
558
|
requestId: event.data.requestId,
|
|
539
559
|
task: 'restartKernelAndRerunCell',
|
|
540
560
|
error: error.toString()
|
|
@@ -544,17 +564,18 @@ function activateFailsLauncher(app, docManager, status, shell) {
|
|
|
544
564
|
break;
|
|
545
565
|
case 'getLicenses':
|
|
546
566
|
{
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
567
|
+
// broken
|
|
568
|
+
licenseClient
|
|
569
|
+
.getBundles()
|
|
570
|
+
.then(async (licenses) => {
|
|
571
|
+
postMessageToFails({
|
|
551
572
|
requestId: event.data.requestId,
|
|
552
573
|
task: 'getLicenses',
|
|
553
|
-
licenses
|
|
574
|
+
licenses
|
|
554
575
|
});
|
|
555
576
|
})
|
|
556
577
|
.catch(error => {
|
|
557
|
-
|
|
578
|
+
postMessageToFails({
|
|
558
579
|
requestId: event.data.requestId,
|
|
559
580
|
task: 'getLicenses',
|
|
560
581
|
error: error.toString()
|
|
@@ -585,12 +606,17 @@ function activateFailsLauncher(app, docManager, status, shell) {
|
|
|
585
606
|
return failsLauncherInfo;
|
|
586
607
|
}
|
|
587
608
|
const failsLauncher = {
|
|
588
|
-
id: '@fails-components/jupyter-
|
|
609
|
+
id: '@fails-components/jupyter-applet-widget:launcher',
|
|
589
610
|
description: 'Configures the notebooks application over messages',
|
|
590
611
|
autoStart: true,
|
|
591
612
|
activate: activateFailsLauncher,
|
|
592
613
|
provides: IFailsLauncherInfo,
|
|
593
|
-
requires: [
|
|
614
|
+
requires: [
|
|
615
|
+
IDocumentManager,
|
|
616
|
+
ILabStatus,
|
|
617
|
+
ILicensesClient,
|
|
618
|
+
IFailsDriveMessages
|
|
619
|
+
],
|
|
594
620
|
optional: [INotebookShell]
|
|
595
621
|
};
|
|
596
622
|
/**
|
package/lib/tokens.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Token } from '@lumino/coreutils';
|
|
2
|
+
import { ISignal } from '@lumino/signaling';
|
|
3
|
+
import { JSONObject, PartialJSONObject } from '@lumino/coreutils';
|
|
4
|
+
export interface IAppletWidgetRegistry {
|
|
5
|
+
}
|
|
6
|
+
export interface IFailsAppletSize {
|
|
7
|
+
appid: string;
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
}
|
|
11
|
+
export interface IFailsLauncherInit {
|
|
12
|
+
inLecture: boolean;
|
|
13
|
+
selectedAppid: string | undefined;
|
|
14
|
+
reportMetadata?: (metadata: PartialJSONObject) => void;
|
|
15
|
+
}
|
|
16
|
+
export interface IFailsInterceptorUpdateMessage {
|
|
17
|
+
path: string;
|
|
18
|
+
mime: string;
|
|
19
|
+
state: JSONObject;
|
|
20
|
+
}
|
|
21
|
+
export interface IFailsLauncherInfo extends IFailsLauncherInit {
|
|
22
|
+
inLectureChanged: ISignal<IFailsLauncherInfo, boolean>;
|
|
23
|
+
selectedAppidChanged: ISignal<this, string | undefined>;
|
|
24
|
+
appletSizes: {
|
|
25
|
+
[key: string]: IFailsAppletSize;
|
|
26
|
+
};
|
|
27
|
+
appletSizesChanged: ISignal<this, {
|
|
28
|
+
[key: string]: IFailsAppletSize;
|
|
29
|
+
}>;
|
|
30
|
+
updateMessageArrived?: ISignal<IAppletWidgetRegistry, IFailsInterceptorUpdateMessage>;
|
|
31
|
+
remoteUpdateMessageArrived: ISignal<IFailsLauncherInfo, IFailsInterceptorUpdateMessage>;
|
|
32
|
+
}
|
|
33
|
+
export declare const IFailsLauncherInfo: Token<IFailsLauncherInfo>;
|
package/lib/tokens.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fails-components/jupyter-launcher",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "A collections of plugins steering an iframe with jupyter remotely",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jupyter",
|
|
@@ -60,21 +60,19 @@
|
|
|
60
60
|
"watch:labextension": "jupyter labextension watch ."
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@jupyter-
|
|
64
|
-
"@jupyter-
|
|
65
|
-
"@jupyterlab/application": "^4.3
|
|
66
|
-
"@jupyterlab/apputils": "^4.3
|
|
67
|
-
"@jupyterlab/
|
|
68
|
-
"@jupyterlab/
|
|
69
|
-
"@jupyterlab/
|
|
70
|
-
"@jupyterlab/
|
|
71
|
-
"@jupyterlite/application-extension": "^0.
|
|
72
|
-
"@jupyterlite/
|
|
73
|
-
"@
|
|
74
|
-
"@
|
|
75
|
-
"@lumino/
|
|
76
|
-
"@lumino/signaling": "^2.1.2",
|
|
77
|
-
"@lumino/widgets": "^2.3.2",
|
|
63
|
+
"@fails-components/jupyter-filesystem-extension": "^0.0.3",
|
|
64
|
+
"@jupyter-notebook/application": "^7.4.3",
|
|
65
|
+
"@jupyterlab/application": "^4.4.3",
|
|
66
|
+
"@jupyterlab/apputils": "^4.5.3",
|
|
67
|
+
"@jupyterlab/docmanager": "^4.4.3",
|
|
68
|
+
"@jupyterlab/docregistry": "^4.4.3",
|
|
69
|
+
"@jupyterlab/notebook": "^4.4.3",
|
|
70
|
+
"@jupyterlab/services": "^7.4.3",
|
|
71
|
+
"@jupyterlite/application-extension": "^0.6.1",
|
|
72
|
+
"@jupyterlite/server": "^0.6.1",
|
|
73
|
+
"@lumino/coreutils": "^2.2.1",
|
|
74
|
+
"@lumino/signaling": "^2.1.4",
|
|
75
|
+
"@lumino/widgets": "^2.7.1",
|
|
78
76
|
"json5": "^2.2.3"
|
|
79
77
|
},
|
|
80
78
|
"devDependencies": {
|
|
@@ -115,7 +113,14 @@
|
|
|
115
113
|
"jupyterlab": {
|
|
116
114
|
"extension": true,
|
|
117
115
|
"outputDir": "fails_components_jupyter_launcher/labextension",
|
|
118
|
-
"schemaDir": "schema"
|
|
116
|
+
"schemaDir": "schema",
|
|
117
|
+
"sharedPackages": {
|
|
118
|
+
"@fails-components/jupyter-filesystem-extension": {
|
|
119
|
+
"singleton": true,
|
|
120
|
+
"requiredVersion": "^0.0.1-alpha.18",
|
|
121
|
+
"import": false
|
|
122
|
+
}
|
|
123
|
+
}
|
|
119
124
|
},
|
|
120
125
|
"eslintIgnore": [
|
|
121
126
|
"node_modules",
|
package/src/index.ts
CHANGED
|
@@ -4,15 +4,23 @@ import {
|
|
|
4
4
|
JupyterFrontEndPlugin
|
|
5
5
|
} from '@jupyterlab/application';
|
|
6
6
|
import { IDocumentManager } from '@jupyterlab/docmanager';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { ISessionContext } from '@jupyterlab/apputils';
|
|
7
|
+
import { Kernel } from '@jupyterlab/services';
|
|
8
|
+
import { ISessionContext, ILicensesClient } from '@jupyterlab/apputils';
|
|
10
9
|
import { IDocumentWidget } from '@jupyterlab/docregistry';
|
|
11
10
|
import { INotebookShell } from '@jupyter-notebook/application';
|
|
12
11
|
import { NotebookActions, NotebookPanel } from '@jupyterlab/notebook';
|
|
13
|
-
import { JSONObject
|
|
12
|
+
import { JSONObject } from '@lumino/coreutils';
|
|
14
13
|
import { ISignal, Signal } from '@lumino/signaling';
|
|
15
14
|
import { Panel } from '@lumino/widgets';
|
|
15
|
+
import { IFailsDriveMessages } from '@fails-components/jupyter-filesystem-extension';
|
|
16
|
+
import {
|
|
17
|
+
IFailsLauncherInfo,
|
|
18
|
+
IFailsAppletSize,
|
|
19
|
+
IAppletWidgetRegistry,
|
|
20
|
+
IFailsInterceptorUpdateMessage
|
|
21
|
+
} from './tokens';
|
|
22
|
+
|
|
23
|
+
export * from './tokens';
|
|
16
24
|
|
|
17
25
|
export interface IScreenShotOpts {
|
|
18
26
|
dpi: number;
|
|
@@ -22,70 +30,6 @@ export interface IAppletScreenshottaker {
|
|
|
22
30
|
takeAppScreenshot: (opts: IScreenShotOpts) => Promise<Blob | undefined>;
|
|
23
31
|
}
|
|
24
32
|
|
|
25
|
-
interface IContentEvent {
|
|
26
|
-
task: string;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface ILoadJupyterContentEvent extends IContentEvent {
|
|
30
|
-
task: 'loadFile';
|
|
31
|
-
fileData: object | undefined;
|
|
32
|
-
fileName: string;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface ISavedJupyterContentEvent extends IContentEvent {
|
|
36
|
-
task: 'savedFile';
|
|
37
|
-
fileName: string;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export type IContentEventType =
|
|
41
|
-
| ILoadJupyterContentEvent
|
|
42
|
-
| ISavedJupyterContentEvent; // use union
|
|
43
|
-
|
|
44
|
-
export interface IFailsCallbacks {
|
|
45
|
-
callContents?: (event: IContentEventType) => Promise<any>;
|
|
46
|
-
postMessageToFails?: (message: any, transfer?: Transferable[]) => void;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export const IFailsLauncherInfo = new Token<IFailsLauncherInfo>(
|
|
50
|
-
'@fails-components/jupyter-fails:IFailsLauncherInfo',
|
|
51
|
-
'A service to communicate with FAILS.'
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
export interface IFailsLauncherInit {
|
|
55
|
-
inLecture: boolean;
|
|
56
|
-
selectedAppid: string | undefined;
|
|
57
|
-
reportMetadata?: (metadata: PartialJSONObject) => void;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export interface IFailsAppletSize {
|
|
61
|
-
appid: string;
|
|
62
|
-
width: number;
|
|
63
|
-
height: number;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export interface IAppletWidgetRegistry {}
|
|
67
|
-
|
|
68
|
-
export interface IFailsInterceptorUpdateMessage {
|
|
69
|
-
path: string;
|
|
70
|
-
mime: string;
|
|
71
|
-
state: JSONObject;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export interface IFailsLauncherInfo extends IFailsLauncherInit {
|
|
75
|
-
inLectureChanged: ISignal<IFailsLauncherInfo, boolean>;
|
|
76
|
-
selectedAppidChanged: ISignal<this, string | undefined>;
|
|
77
|
-
appletSizes: { [key: string]: IFailsAppletSize };
|
|
78
|
-
appletSizesChanged: ISignal<this, { [key: string]: IFailsAppletSize }>;
|
|
79
|
-
updateMessageArrived?: ISignal<
|
|
80
|
-
IAppletWidgetRegistry,
|
|
81
|
-
IFailsInterceptorUpdateMessage
|
|
82
|
-
>;
|
|
83
|
-
remoteUpdateMessageArrived: ISignal<
|
|
84
|
-
IFailsLauncherInfo,
|
|
85
|
-
IFailsInterceptorUpdateMessage
|
|
86
|
-
>;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
33
|
export interface IReplyJupyter {
|
|
90
34
|
requestId?: number;
|
|
91
35
|
}
|
|
@@ -283,6 +227,20 @@ const installFetchPatches = ({
|
|
|
283
227
|
headers: { 'Content-Type': 'text/plain' }
|
|
284
228
|
});
|
|
285
229
|
};
|
|
230
|
+
const oldImportScripts = globalThis.importScripts;
|
|
231
|
+
globalThis.importScripts = (...args) => {
|
|
232
|
+
const newargs = args.map(url => {
|
|
233
|
+
const urlObj = new URL(url, location.href);
|
|
234
|
+
if (allowedOrigins.includes(urlObj.origin)) {
|
|
235
|
+
return url;
|
|
236
|
+
}
|
|
237
|
+
if (proxySites && proxySites.includes(urlObj.origin)) {
|
|
238
|
+
return proxyURL + urlObj.hostname + urlObj.pathname;
|
|
239
|
+
}
|
|
240
|
+
throw new Error('Script is from blocked URL');
|
|
241
|
+
});
|
|
242
|
+
return oldImportScripts(...newargs);
|
|
243
|
+
};
|
|
286
244
|
const oldWorker = Worker;
|
|
287
245
|
const NewWorker = function (
|
|
288
246
|
script: string | URL,
|
|
@@ -339,6 +297,20 @@ const installFetchPatches = ({
|
|
|
339
297
|
headers: { 'Content-Type': 'text/plain' }
|
|
340
298
|
});
|
|
341
299
|
};
|
|
300
|
+
const oldImportScripts = globalThis.importScripts;
|
|
301
|
+
globalThis.importScripts = (...args) => {
|
|
302
|
+
const newargs = args.map(url => {
|
|
303
|
+
const urlObj = new URL(url, location.href);
|
|
304
|
+
if (allowedOrigins.includes(urlObj.origin)) {
|
|
305
|
+
return url;
|
|
306
|
+
}
|
|
307
|
+
if (proxySites && proxySites.includes(urlObj.origin)) {
|
|
308
|
+
return proxyURL + urlObj.hostname + urlObj.pathname;
|
|
309
|
+
}
|
|
310
|
+
throw new Error('Script is from blocked URL');
|
|
311
|
+
});
|
|
312
|
+
return oldImportScripts(...newargs);
|
|
313
|
+
};
|
|
342
314
|
Object.defineProperty(globalThis, 'location', {
|
|
343
315
|
value: new URL('${scriptURL.href}'),
|
|
344
316
|
writable: false,
|
|
@@ -496,10 +468,13 @@ function activateFailsLauncher(
|
|
|
496
468
|
app: JupyterFrontEnd,
|
|
497
469
|
docManager: IDocumentManager,
|
|
498
470
|
status: ILabStatus,
|
|
471
|
+
licenseClient: ILicensesClient,
|
|
472
|
+
driveMessages: IFailsDriveMessages,
|
|
499
473
|
shell: INotebookShell | null
|
|
500
474
|
): IFailsLauncherInfo {
|
|
501
475
|
// parts taken from repl-extension
|
|
502
476
|
const { /* commands, */ serviceManager, started } = app;
|
|
477
|
+
const sendMessageToDrive = driveMessages.sendMessage;
|
|
503
478
|
Promise.all([started, serviceManager.ready]).then(async () => {
|
|
504
479
|
/* commands.execute('notebook:create-new', {
|
|
505
480
|
kernelId: undefined,
|
|
@@ -512,33 +487,20 @@ function activateFailsLauncher(
|
|
|
512
487
|
const failsLauncherInfo: IFailsLauncherInfo = new FailsLauncherInfo();
|
|
513
488
|
let currentDocWidget: IDocumentWidget | undefined;
|
|
514
489
|
|
|
515
|
-
const serverSettings = app.serviceManager.serverSettings;
|
|
516
|
-
const licensesUrl =
|
|
517
|
-
URLExt.join(PageConfig.getBaseUrl(), PageConfig.getOption('licensesUrl')) +
|
|
518
|
-
'/';
|
|
519
|
-
|
|
520
|
-
// Install Messagehandler
|
|
521
|
-
if (!(window as any).failsCallbacks) {
|
|
522
|
-
(window as any).failsCallbacks = {};
|
|
523
|
-
}
|
|
524
490
|
let senderOrigin: string | undefined;
|
|
525
|
-
const
|
|
526
|
-
_failsCallbacks.postMessageToFails = (
|
|
527
|
-
message: any,
|
|
528
|
-
transfer?: Transferable[]
|
|
529
|
-
) => {
|
|
491
|
+
const postMessageToFails = (message: any, transfer?: Transferable[]) => {
|
|
530
492
|
if (typeof senderOrigin !== 'undefined') {
|
|
531
493
|
window.parent.postMessage(message, senderOrigin, transfer);
|
|
532
494
|
}
|
|
533
495
|
};
|
|
534
496
|
status.dirtySignal.connect((sender, dirty) => {
|
|
535
|
-
|
|
497
|
+
postMessageToFails!({
|
|
536
498
|
task: 'docDirty',
|
|
537
499
|
dirty
|
|
538
500
|
});
|
|
539
501
|
});
|
|
540
502
|
failsLauncherInfo.reportMetadata = metadata => {
|
|
541
|
-
|
|
503
|
+
postMessageToFails!({
|
|
542
504
|
task: 'reportMetadata',
|
|
543
505
|
metadata
|
|
544
506
|
});
|
|
@@ -555,7 +517,7 @@ function activateFailsLauncher(
|
|
|
555
517
|
sender: IFailsLauncherInfo,
|
|
556
518
|
appletSizes: { [key: string]: IFailsAppletSize }
|
|
557
519
|
) => {
|
|
558
|
-
|
|
520
|
+
postMessageToFails!({
|
|
559
521
|
task: 'reportFailsAppletSizes',
|
|
560
522
|
appletSizes
|
|
561
523
|
});
|
|
@@ -566,7 +528,7 @@ function activateFailsLauncher(
|
|
|
566
528
|
sender: IAppletWidgetRegistry,
|
|
567
529
|
message: IFailsInterceptorUpdateMessage
|
|
568
530
|
): void => {
|
|
569
|
-
|
|
531
|
+
postMessageToFails!({
|
|
570
532
|
task: 'sendInterceptorUpdate',
|
|
571
533
|
...message
|
|
572
534
|
});
|
|
@@ -595,7 +557,7 @@ function activateFailsLauncher(
|
|
|
595
557
|
// may be use a promise for fullfillment, e.g. pass a resolve
|
|
596
558
|
// afterwards we load the file or new file into to the contexts
|
|
597
559
|
// we may also send license information
|
|
598
|
-
|
|
560
|
+
sendMessageToDrive({
|
|
599
561
|
task: 'loadFile',
|
|
600
562
|
fileData: loadJupyterInfo.fileData,
|
|
601
563
|
fileName: loadJupyterInfo.fileName
|
|
@@ -625,7 +587,7 @@ function activateFailsLauncher(
|
|
|
625
587
|
const notebookPanel = currentDocWidget as NotebookPanel;
|
|
626
588
|
notebookPanel.sessionContext.statusChanged.connect(
|
|
627
589
|
(context: ISessionContext, status: Kernel.Status) => {
|
|
628
|
-
|
|
590
|
+
postMessageToFails!({
|
|
629
591
|
task: 'reportKernelStatus',
|
|
630
592
|
status
|
|
631
593
|
});
|
|
@@ -654,7 +616,7 @@ function activateFailsLauncher(
|
|
|
654
616
|
);
|
|
655
617
|
}
|
|
656
618
|
})
|
|
657
|
-
.catch(error => {
|
|
619
|
+
.catch((error: any) => {
|
|
658
620
|
console.log('Problem task load file', error);
|
|
659
621
|
});
|
|
660
622
|
}
|
|
@@ -663,7 +625,7 @@ function activateFailsLauncher(
|
|
|
663
625
|
{
|
|
664
626
|
const saveJupyter = event.data as ISaveJupyter;
|
|
665
627
|
if (typeof currentDocWidget === 'undefined') {
|
|
666
|
-
|
|
628
|
+
postMessageToFails!({
|
|
667
629
|
requestId: event.data.requestId,
|
|
668
630
|
task: 'saveJupyter',
|
|
669
631
|
error: 'No document loaded'
|
|
@@ -672,7 +634,7 @@ function activateFailsLauncher(
|
|
|
672
634
|
}
|
|
673
635
|
const context = docManager.contextForWidget(currentDocWidget);
|
|
674
636
|
if (typeof context === 'undefined') {
|
|
675
|
-
|
|
637
|
+
postMessageToFails!({
|
|
676
638
|
requestId: event.data.requestId,
|
|
677
639
|
task: 'saveJupyter',
|
|
678
640
|
error: 'No document context'
|
|
@@ -681,22 +643,22 @@ function activateFailsLauncher(
|
|
|
681
643
|
}
|
|
682
644
|
context
|
|
683
645
|
.save()
|
|
684
|
-
.then(() => {
|
|
646
|
+
.then(async () => {
|
|
685
647
|
// ok it was save to our virtual disk
|
|
686
|
-
return
|
|
648
|
+
return await sendMessageToDrive({
|
|
687
649
|
task: 'savedFile',
|
|
688
650
|
fileName: saveJupyter.fileName
|
|
689
651
|
});
|
|
690
652
|
})
|
|
691
653
|
.then(({ fileData }) => {
|
|
692
|
-
|
|
654
|
+
postMessageToFails!({
|
|
693
655
|
requestId: event.data.requestId,
|
|
694
656
|
task: 'saveJupyter',
|
|
695
657
|
fileData
|
|
696
658
|
});
|
|
697
659
|
})
|
|
698
660
|
.catch((error: Error) => {
|
|
699
|
-
|
|
661
|
+
postMessageToFails!({
|
|
700
662
|
requestId: event.data.requestId,
|
|
701
663
|
task: 'saveJupyter',
|
|
702
664
|
error: error.toString()
|
|
@@ -712,7 +674,7 @@ function activateFailsLauncher(
|
|
|
712
674
|
} else {
|
|
713
675
|
failsLauncherInfo.inLecture = false;
|
|
714
676
|
}
|
|
715
|
-
|
|
677
|
+
postMessageToFails!({
|
|
716
678
|
requestId: event.data.requestId,
|
|
717
679
|
task: 'activateApp'
|
|
718
680
|
});
|
|
@@ -725,7 +687,7 @@ function activateFailsLauncher(
|
|
|
725
687
|
if (
|
|
726
688
|
!(typeof (notebookPanel as any)['takeAppScreenshot'] === 'function')
|
|
727
689
|
) {
|
|
728
|
-
|
|
690
|
+
postMessageToFails!({
|
|
729
691
|
requestId: event.data.requestId,
|
|
730
692
|
task: 'screenshotApp',
|
|
731
693
|
error: 'Take App Screenshot unsupported'
|
|
@@ -738,7 +700,7 @@ function activateFailsLauncher(
|
|
|
738
700
|
.then(async screenshot => {
|
|
739
701
|
if (screenshot) {
|
|
740
702
|
const data = await screenshot.arrayBuffer();
|
|
741
|
-
|
|
703
|
+
postMessageToFails?.(
|
|
742
704
|
{
|
|
743
705
|
requestId: event.data.requestId,
|
|
744
706
|
task: 'screenshotApp',
|
|
@@ -747,7 +709,7 @@ function activateFailsLauncher(
|
|
|
747
709
|
[data]
|
|
748
710
|
); // TODO add transferable
|
|
749
711
|
} else {
|
|
750
|
-
|
|
712
|
+
postMessageToFails?.({
|
|
751
713
|
requestId: event.data.requestId,
|
|
752
714
|
task: 'screenshotApp',
|
|
753
715
|
error: 'Screenshot failed?'
|
|
@@ -756,7 +718,7 @@ function activateFailsLauncher(
|
|
|
756
718
|
})
|
|
757
719
|
.catch((error: Error) => {
|
|
758
720
|
console.log('Screenshot error', error);
|
|
759
|
-
|
|
721
|
+
postMessageToFails!({
|
|
760
722
|
requestId: event.data.requestId,
|
|
761
723
|
task: 'screenshotApp',
|
|
762
724
|
error: error.toString()
|
|
@@ -783,7 +745,7 @@ function activateFailsLauncher(
|
|
|
783
745
|
interceptorActivated = false;
|
|
784
746
|
}
|
|
785
747
|
}
|
|
786
|
-
|
|
748
|
+
postMessageToFails!({
|
|
787
749
|
requestId: event.data.requestId,
|
|
788
750
|
task: 'activateInterceptor'
|
|
789
751
|
});
|
|
@@ -796,7 +758,7 @@ function activateFailsLauncher(
|
|
|
796
758
|
const { path, mime, state } = receiveInterceptorUpdate;
|
|
797
759
|
const launcherInfo = failsLauncherInfo as FailsLauncherInfo;
|
|
798
760
|
launcherInfo.receiveRemoteUpdateMessage({ path, mime, state });
|
|
799
|
-
|
|
761
|
+
postMessageToFails!({
|
|
800
762
|
requestId: event.data.requestId,
|
|
801
763
|
task: 'receiveInterceptorUpdate'
|
|
802
764
|
});
|
|
@@ -805,7 +767,7 @@ function activateFailsLauncher(
|
|
|
805
767
|
case 'restartKernelAndRerunCells':
|
|
806
768
|
{
|
|
807
769
|
if (typeof currentDocWidget === 'undefined') {
|
|
808
|
-
|
|
770
|
+
postMessageToFails!({
|
|
809
771
|
requestId: event.data.requestId,
|
|
810
772
|
task: 'restartKernelAndRerunCell',
|
|
811
773
|
error: 'No document loaded'
|
|
@@ -825,14 +787,14 @@ function activateFailsLauncher(
|
|
|
825
787
|
cells,
|
|
826
788
|
context.sessionContext
|
|
827
789
|
);
|
|
828
|
-
|
|
790
|
+
postMessageToFails!({
|
|
829
791
|
requestId: event.data.requestId,
|
|
830
792
|
task: 'restartKernelAndRerunCell',
|
|
831
793
|
success: true
|
|
832
794
|
});
|
|
833
795
|
})
|
|
834
796
|
.catch((error: Error) => {
|
|
835
|
-
|
|
797
|
+
postMessageToFails!({
|
|
836
798
|
requestId: event.data.requestId,
|
|
837
799
|
task: 'restartKernelAndRerunCell',
|
|
838
800
|
error: error.toString()
|
|
@@ -842,17 +804,18 @@ function activateFailsLauncher(
|
|
|
842
804
|
break;
|
|
843
805
|
case 'getLicenses':
|
|
844
806
|
{
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
807
|
+
// broken
|
|
808
|
+
licenseClient
|
|
809
|
+
.getBundles()
|
|
810
|
+
.then(async licenses => {
|
|
811
|
+
postMessageToFails!({
|
|
849
812
|
requestId: event.data.requestId,
|
|
850
813
|
task: 'getLicenses',
|
|
851
|
-
licenses
|
|
814
|
+
licenses
|
|
852
815
|
});
|
|
853
816
|
})
|
|
854
817
|
.catch(error => {
|
|
855
|
-
|
|
818
|
+
postMessageToFails!({
|
|
856
819
|
requestId: event.data.requestId,
|
|
857
820
|
task: 'getLicenses',
|
|
858
821
|
error: error.toString()
|
|
@@ -887,12 +850,17 @@ function activateFailsLauncher(
|
|
|
887
850
|
}
|
|
888
851
|
|
|
889
852
|
const failsLauncher: JupyterFrontEndPlugin<IFailsLauncherInfo> = {
|
|
890
|
-
id: '@fails-components/jupyter-
|
|
853
|
+
id: '@fails-components/jupyter-applet-widget:launcher',
|
|
891
854
|
description: 'Configures the notebooks application over messages',
|
|
892
855
|
autoStart: true,
|
|
893
856
|
activate: activateFailsLauncher,
|
|
894
857
|
provides: IFailsLauncherInfo,
|
|
895
|
-
requires: [
|
|
858
|
+
requires: [
|
|
859
|
+
IDocumentManager,
|
|
860
|
+
ILabStatus,
|
|
861
|
+
ILicensesClient,
|
|
862
|
+
IFailsDriveMessages
|
|
863
|
+
],
|
|
896
864
|
optional: [INotebookShell]
|
|
897
865
|
};
|
|
898
866
|
|
|
@@ -901,7 +869,6 @@ const failsLauncher: JupyterFrontEndPlugin<IFailsLauncherInfo> = {
|
|
|
901
869
|
*/
|
|
902
870
|
const plugins: JupyterFrontEndPlugin<any>[] = [
|
|
903
871
|
// all JupyterFrontEndPlugins
|
|
904
|
-
|
|
905
872
|
failsLauncher
|
|
906
873
|
];
|
|
907
874
|
|
package/src/tokens.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Token } from '@lumino/coreutils';
|
|
2
|
+
import { ISignal } from '@lumino/signaling';
|
|
3
|
+
import { JSONObject, PartialJSONObject } from '@lumino/coreutils';
|
|
4
|
+
|
|
5
|
+
export interface IAppletWidgetRegistry {}
|
|
6
|
+
|
|
7
|
+
export interface IFailsAppletSize {
|
|
8
|
+
appid: string;
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface IFailsLauncherInit {
|
|
14
|
+
inLecture: boolean;
|
|
15
|
+
selectedAppid: string | undefined;
|
|
16
|
+
reportMetadata?: (metadata: PartialJSONObject) => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface IFailsInterceptorUpdateMessage {
|
|
20
|
+
path: string;
|
|
21
|
+
mime: string;
|
|
22
|
+
state: JSONObject;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface IFailsLauncherInfo extends IFailsLauncherInit {
|
|
26
|
+
inLectureChanged: ISignal<IFailsLauncherInfo, boolean>;
|
|
27
|
+
selectedAppidChanged: ISignal<this, string | undefined>;
|
|
28
|
+
appletSizes: { [key: string]: IFailsAppletSize };
|
|
29
|
+
appletSizesChanged: ISignal<this, { [key: string]: IFailsAppletSize }>;
|
|
30
|
+
updateMessageArrived?: ISignal<
|
|
31
|
+
IAppletWidgetRegistry,
|
|
32
|
+
IFailsInterceptorUpdateMessage
|
|
33
|
+
>;
|
|
34
|
+
remoteUpdateMessageArrived: ISignal<
|
|
35
|
+
IFailsLauncherInfo,
|
|
36
|
+
IFailsInterceptorUpdateMessage
|
|
37
|
+
>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const IFailsLauncherInfo = new Token<IFailsLauncherInfo>(
|
|
41
|
+
'@fails-components/jupyter-fails:IFailsLauncherInfo',
|
|
42
|
+
'A service to communicate with FAILS.'
|
|
43
|
+
);
|