@jupyterlite/application 0.2.2 → 0.3.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +10 -9
- package/src/index.ts +5 -0
- package/src/singleWidgetApp.ts +155 -0
- package/src/singleWidgetShell.ts +121 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jupyterlite/application",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-alpha.0",
|
|
4
4
|
"description": "JupyterLite - Application",
|
|
5
5
|
"homepage": "https://github.com/jupyterlite/jupyterlite",
|
|
6
6
|
"bugs": {
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
"lib/*.js.map",
|
|
28
28
|
"lib/*.js",
|
|
29
29
|
"style/*.css",
|
|
30
|
-
"style/index.js"
|
|
30
|
+
"style/index.js",
|
|
31
|
+
"src/**/*.{ts,tsx}"
|
|
31
32
|
],
|
|
32
33
|
"scripts": {
|
|
33
34
|
"build": "tsc -b",
|
|
@@ -37,23 +38,23 @@
|
|
|
37
38
|
"watch": "tsc -b --watch"
|
|
38
39
|
},
|
|
39
40
|
"dependencies": {
|
|
40
|
-
"@jupyterlab/application": "~4.
|
|
41
|
-
"@jupyterlab/coreutils": "~6.
|
|
42
|
-
"@jupyterlab/docregistry": "~4.
|
|
43
|
-
"@jupyterlab/rendermime-interfaces": "~3.
|
|
41
|
+
"@jupyterlab/application": "~4.1.1",
|
|
42
|
+
"@jupyterlab/coreutils": "~6.1.1",
|
|
43
|
+
"@jupyterlab/docregistry": "~4.1.1",
|
|
44
|
+
"@jupyterlab/rendermime-interfaces": "~3.9.1",
|
|
44
45
|
"@lumino/coreutils": "^2.1.2",
|
|
45
46
|
"@lumino/signaling": "^2.1.2",
|
|
46
|
-
"@lumino/widgets": "^2.3.
|
|
47
|
+
"@lumino/widgets": "^2.3.1"
|
|
47
48
|
},
|
|
48
49
|
"devDependencies": {
|
|
49
50
|
"@babel/core": "^7.11.6",
|
|
50
51
|
"@babel/preset-env": "^7.12.1",
|
|
51
|
-
"@jupyterlab/testutils": "~4.
|
|
52
|
+
"@jupyterlab/testutils": "~4.1.1",
|
|
52
53
|
"@types/jest": "^29.5.3",
|
|
53
54
|
"jest": "^29.6.2",
|
|
54
55
|
"rimraf": "~5.0.1",
|
|
55
56
|
"ts-jest": "^29.1.1",
|
|
56
|
-
"typescript": "~5.
|
|
57
|
+
"typescript": "~5.1.6"
|
|
57
58
|
},
|
|
58
59
|
"publishConfig": {
|
|
59
60
|
"access": "public"
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// Copyright (c) Jupyter Development Team.
|
|
2
|
+
// Distributed under the terms of the Modified BSD License.
|
|
3
|
+
|
|
4
|
+
import { JupyterFrontEnd, JupyterFrontEndPlugin } from '@jupyterlab/application';
|
|
5
|
+
|
|
6
|
+
import { createRendermimePlugins } from '@jupyterlab/application/lib/mimerenderers';
|
|
7
|
+
|
|
8
|
+
import { LabStatus } from '@jupyterlab/application/lib/status';
|
|
9
|
+
|
|
10
|
+
import { PageConfig } from '@jupyterlab/coreutils';
|
|
11
|
+
|
|
12
|
+
import { IRenderMime } from '@jupyterlab/rendermime-interfaces';
|
|
13
|
+
|
|
14
|
+
import { ISingleWidgetShell, SingleWidgetShell } from './singleWidgetShell';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* App is the main application class. It is instantiated once and shared.
|
|
18
|
+
*/
|
|
19
|
+
export class SingleWidgetApp extends JupyterFrontEnd<ISingleWidgetShell> {
|
|
20
|
+
/**
|
|
21
|
+
* Construct a new SingleWidgetApp object.
|
|
22
|
+
*
|
|
23
|
+
* @param options The instantiation options for an application.
|
|
24
|
+
*/
|
|
25
|
+
constructor(options: SingleWidgetApp.IOptions = { shell: new SingleWidgetShell() }) {
|
|
26
|
+
super({
|
|
27
|
+
...options,
|
|
28
|
+
shell: options.shell ?? new SingleWidgetShell(),
|
|
29
|
+
});
|
|
30
|
+
if (options.mimeExtensions) {
|
|
31
|
+
for (const plugin of createRendermimePlugins(options.mimeExtensions)) {
|
|
32
|
+
this.registerPlugin(plugin);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The name of the application.
|
|
39
|
+
*/
|
|
40
|
+
readonly name = 'Single Widget Application';
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A namespace/prefix plugins may use to denote their provenance.
|
|
44
|
+
*/
|
|
45
|
+
readonly namespace = this.name;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The application busy and dirty status signals and flags.
|
|
49
|
+
*/
|
|
50
|
+
readonly status = new LabStatus(this);
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The version of the application.
|
|
54
|
+
*/
|
|
55
|
+
readonly version = PageConfig.getOption('appVersion') ?? 'unknown';
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The JupyterLab application paths dictionary.
|
|
59
|
+
*/
|
|
60
|
+
get paths(): JupyterFrontEnd.IPaths {
|
|
61
|
+
return {
|
|
62
|
+
urls: {
|
|
63
|
+
base: PageConfig.getOption('baseUrl'),
|
|
64
|
+
notFound: PageConfig.getOption('notFoundUrl'),
|
|
65
|
+
app: PageConfig.getOption('appUrl'),
|
|
66
|
+
static: PageConfig.getOption('staticUrl'),
|
|
67
|
+
settings: PageConfig.getOption('settingsUrl'),
|
|
68
|
+
themes: PageConfig.getOption('themesUrl'),
|
|
69
|
+
doc: PageConfig.getOption('docUrl'),
|
|
70
|
+
translations: PageConfig.getOption('translationsApiUrl'),
|
|
71
|
+
hubHost: PageConfig.getOption('hubHost') || undefined,
|
|
72
|
+
hubPrefix: PageConfig.getOption('hubPrefix') || undefined,
|
|
73
|
+
hubUser: PageConfig.getOption('hubUser') || undefined,
|
|
74
|
+
hubServerName: PageConfig.getOption('hubServerName') || undefined,
|
|
75
|
+
},
|
|
76
|
+
directories: {
|
|
77
|
+
appSettings: PageConfig.getOption('appSettingsDir'),
|
|
78
|
+
schemas: PageConfig.getOption('schemasDir'),
|
|
79
|
+
static: PageConfig.getOption('staticDir'),
|
|
80
|
+
templates: PageConfig.getOption('templatesDir'),
|
|
81
|
+
themes: PageConfig.getOption('themesDir'),
|
|
82
|
+
userSettings: PageConfig.getOption('userSettingsDir'),
|
|
83
|
+
serverRoot: PageConfig.getOption('serverRoot'),
|
|
84
|
+
workspaces: PageConfig.getOption('workspacesDir'),
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Register plugins from a plugin module.
|
|
91
|
+
*
|
|
92
|
+
* @param mod - The plugin module to register.
|
|
93
|
+
*/
|
|
94
|
+
registerPluginModule(mod: SingleWidgetApp.IPluginModule): void {
|
|
95
|
+
let data = mod.default;
|
|
96
|
+
// Handle commonjs exports.
|
|
97
|
+
if (!Object.prototype.hasOwnProperty.call(mod, '__esModule')) {
|
|
98
|
+
data = mod as any;
|
|
99
|
+
}
|
|
100
|
+
if (!Array.isArray(data)) {
|
|
101
|
+
data = [data];
|
|
102
|
+
}
|
|
103
|
+
data.forEach((item) => {
|
|
104
|
+
try {
|
|
105
|
+
this.registerPlugin(item);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.error(error);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Register the plugins from multiple plugin modules.
|
|
114
|
+
*
|
|
115
|
+
* @param mods - The plugin modules to register.
|
|
116
|
+
*/
|
|
117
|
+
registerPluginModules(mods: SingleWidgetApp.IPluginModule[]): void {
|
|
118
|
+
mods.forEach((mod) => {
|
|
119
|
+
this.registerPluginModule(mod);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* A namespace for App statics.
|
|
126
|
+
*/
|
|
127
|
+
export namespace SingleWidgetApp {
|
|
128
|
+
/**
|
|
129
|
+
* The instantiation options for an App application.
|
|
130
|
+
*/
|
|
131
|
+
export interface IOptions
|
|
132
|
+
extends JupyterFrontEnd.IOptions<ISingleWidgetShell>,
|
|
133
|
+
Partial<IInfo> {}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* The information about a Jupyter Notebook application.
|
|
137
|
+
*/
|
|
138
|
+
export interface IInfo {
|
|
139
|
+
/**
|
|
140
|
+
* The mime renderer extensions.
|
|
141
|
+
*/
|
|
142
|
+
readonly mimeExtensions: IRenderMime.IExtensionModule[];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* The interface for a module that exports a plugin or plugins as
|
|
147
|
+
* the default value.
|
|
148
|
+
*/
|
|
149
|
+
export interface IPluginModule {
|
|
150
|
+
/**
|
|
151
|
+
* The default export.
|
|
152
|
+
*/
|
|
153
|
+
default: JupyterFrontEndPlugin<any> | JupyterFrontEndPlugin<any>[];
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// Copyright (c) Jupyter Development Team.
|
|
2
|
+
// Distributed under the terms of the Modified BSD License.
|
|
3
|
+
|
|
4
|
+
import { JupyterFrontEnd } from '@jupyterlab/application';
|
|
5
|
+
|
|
6
|
+
import { DocumentRegistry } from '@jupyterlab/docregistry';
|
|
7
|
+
|
|
8
|
+
import { find } from '@lumino/algorithm';
|
|
9
|
+
|
|
10
|
+
import { Token } from '@lumino/coreutils';
|
|
11
|
+
|
|
12
|
+
import { ISignal, Signal } from '@lumino/signaling';
|
|
13
|
+
|
|
14
|
+
import { Panel, Widget, PanelLayout } from '@lumino/widgets';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The single widget application shell token.
|
|
18
|
+
*/
|
|
19
|
+
export const ISingleWidgetShell = new Token<ISingleWidgetShell>(
|
|
20
|
+
'@jupyterlite/application:ISingleWidgetShell',
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The single widget application shell interface.
|
|
25
|
+
*/
|
|
26
|
+
export interface ISingleWidgetShell extends SingleWidgetShell {}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The application shell.
|
|
30
|
+
*/
|
|
31
|
+
export class SingleWidgetShell extends Widget implements JupyterFrontEnd.IShell {
|
|
32
|
+
constructor() {
|
|
33
|
+
super();
|
|
34
|
+
this.id = 'main';
|
|
35
|
+
|
|
36
|
+
const rootLayout = new PanelLayout();
|
|
37
|
+
this._main = new Panel();
|
|
38
|
+
this._main.id = 'single-widget-panel';
|
|
39
|
+
rootLayout.addWidget(this._main);
|
|
40
|
+
this.layout = rootLayout;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* A signal emitted when the current widget changes.
|
|
45
|
+
*/
|
|
46
|
+
get currentChanged(): ISignal<ISingleWidgetShell, void> {
|
|
47
|
+
return this._currentChanged;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The current widget in the shell's main area.
|
|
52
|
+
*/
|
|
53
|
+
get currentWidget(): Widget | null {
|
|
54
|
+
return this._main.widgets[0] ?? null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Activate a widget in its area.
|
|
59
|
+
*/
|
|
60
|
+
activateById(id: string): void {
|
|
61
|
+
const widget = find(this.widgets('main'), (w) => w.id === id);
|
|
62
|
+
if (widget) {
|
|
63
|
+
widget.activate();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Add a widget to the application shell.
|
|
69
|
+
*
|
|
70
|
+
* @param widget - The widget being added.
|
|
71
|
+
*
|
|
72
|
+
* @param area - Optional region in the shell into which the widget should
|
|
73
|
+
* be added.
|
|
74
|
+
*
|
|
75
|
+
* @param options - Optional open options.
|
|
76
|
+
*
|
|
77
|
+
*/
|
|
78
|
+
add(
|
|
79
|
+
widget: Widget,
|
|
80
|
+
area?: Shell.Area,
|
|
81
|
+
options?: DocumentRegistry.IOpenOptions,
|
|
82
|
+
): void {
|
|
83
|
+
if (area === 'main' || area === undefined) {
|
|
84
|
+
if (this._main.widgets.length > 0) {
|
|
85
|
+
// do not add the widget if there is already one
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
this._main.addWidget(widget);
|
|
89
|
+
this._main.update();
|
|
90
|
+
this._currentChanged.emit(void 0);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Return the list of widgets for the given area.
|
|
96
|
+
*
|
|
97
|
+
* @param area The area
|
|
98
|
+
*/
|
|
99
|
+
*widgets(area: Shell.Area): IterableIterator<Widget> {
|
|
100
|
+
switch (area ?? 'main') {
|
|
101
|
+
case 'main':
|
|
102
|
+
yield* this._main.widgets;
|
|
103
|
+
break;
|
|
104
|
+
default:
|
|
105
|
+
throw new Error(`Invalid area: ${area}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private _main: Panel;
|
|
110
|
+
private _currentChanged = new Signal<this, void>(this);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* A namespace for Shell statics
|
|
115
|
+
*/
|
|
116
|
+
export namespace Shell {
|
|
117
|
+
/**
|
|
118
|
+
* The areas of the application shell where widgets can reside.
|
|
119
|
+
*/
|
|
120
|
+
export type Area = 'main';
|
|
121
|
+
}
|