diff --git a/examples/generic.ipynb b/examples/generic.ipynb index 6849794..2bf7c2e 100644 --- a/examples/generic.ipynb +++ b/examples/generic.ipynb @@ -67,7 +67,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Some of the methods above have already been implemented in 'app.shell' on the Python object. And if you look at the code you'll see these methods use the *generic* method (technically, it is a subclass which inserts `'shell.'` infront of the path in the method `executeMethod` to match it's level in the JupyterFrontend Object. So basically the same function call is sent to the frontend.\n", + "Some of the methods above have already been implemented in 'app.shell' on the Python object. And if you look at the code you'll see these methods use the *generic* method (technically, it is a subclass which inserts `'shell.'` in front of the path in the method `executeMethod` to match it's level in the JupyterFrontend Object. So basically the same function call is sent to the frontend.\n", "\n", "In case you're interested, the custom part of message sent to the frontend looks like this:\n", "\n", diff --git a/ipylab/main_area.py b/ipylab/main_area.py index 4e93dc5..6309099 100644 --- a/ipylab/main_area.py +++ b/ipylab/main_area.py @@ -96,7 +96,7 @@ def load( content: Panel | None = None, area: Area = Area.main, activate: bool = True, - mode: InsertMode = InsertMode.split_right, + mode: InsertMode = InsertMode.tab_after, rank: int | None = None, ref: str = "", class_name="ipylab-main-area", diff --git a/ipylab/scripts.py b/ipylab/scripts.py index cb89255..0c6de17 100644 --- a/ipylab/scripts.py +++ b/ipylab/scripts.py @@ -8,7 +8,7 @@ def init_ipylab_backend(): """Initialize an ipylab backend. - Intended to run inside a kenrnel launched by Jupyter. + Intended to run inside a kernel launched by Jupyter. """ from ipylab.jupyterfrontend import JupyterFrontEnd diff --git a/package.json b/package.json index 5e8a7bf..19cfbf7 100644 --- a/package.json +++ b/package.json @@ -94,10 +94,8 @@ "@jupyterlab/launcher": "^4.1.0", "@jupyterlab/observables": "^5.1.0", "@jupyterlab/rendermime": "^4.1.0", - "@lumino/algorithm": "^2.0.1", "@lumino/commands": "^2.2.0", "@lumino/disposable": "^2.1.2", - "@lumino/messaging": "^2.0.1", "@lumino/widgets": "^2.3.1" }, "devDependencies": { diff --git a/src/widgets/frontend.ts b/src/widgets/frontend.ts index e1dfd65..07dea93 100644 --- a/src/widgets/frontend.ts +++ b/src/widgets/frontend.ts @@ -1,7 +1,7 @@ // Copyright (c) ipylab contributors // Distributed under the terms of the Modified BSD License. -import { unpack_models, uuid } from '@jupyter-widgets/base'; +import { unpack_models } from '@jupyter-widgets/base'; import { LabShell } from '@jupyterlab/application'; import { DOMUtils, @@ -172,15 +172,15 @@ export class JupyterFrontEndModel extends IpylabModel { let luminoWidget = view.luminoWidget; if (area === 'main') { luminoWidget = new IpylabMainAreaWidget({ - content: view.luminoWidget, + content: view.luminoWidget as any, kernelId: this.kernelId, name: 'Ipylab' - }); + }) as any; } if (!luminoWidget.id) { luminoWidget.id = DOMUtils.createDomID(); } - this.shell.add(luminoWidget, area, options); + this.shell.add(luminoWidget as any, area, options); onKernelLost( (this.widget_manager as any).kernel, luminoWidget.dispose, @@ -196,42 +196,41 @@ export class JupyterFrontEndModel extends IpylabModel { * @returns */ async getJupyterFrontEndModel(payload: any): Promise { - const kernelId = payload.kernelId || uuid(); - if (Private.jupyterFrontEndModels.has(kernelId)) { - return Private.jupyterFrontEndModels.get(kernelId); + if (payload.kernelId) { + if (Private.jupyterFrontEndModels.has(payload.kernelId)) { + return Private.jupyterFrontEndModels.get(payload.kernelId); + } } let kernel: Kernel.IKernelConnection; - const model = await this.app.serviceManager.kernels.findById(kernelId); + const model = await this.app.serviceManager.kernels.findById( + payload.kernelId + ); if (model) { kernel = this.app.serviceManager.kernels.connectTo({ model: model }); } else { - payload.kernelId = kernelId; - const session = await newSession({ - rendermime: IpylabModel.rendermime.clone(), - ...payload - }); + if (payload.kernelId) { + throw new Error(`Kernel does not exist: ${payload.kernelId}`); + } + const session = await newSession(payload); kernel = session.kernel; } - // Currently we need the kernel to create the JupyterFrontEnd widget. + // Currently we use the python kernel to create the JupyterFrontEnd widget. const future = kernel.requestExecute({ - code: 'import ipylab;_jfem=ipylab.JupyterFrontEnd()', + code: 'import ipylab;ipylab.JupyterFrontEnd()', store_history: false, stop_on_error: true, silent: true, - allow_stdin: false, - user_expressions: { frontendId: '_jfem.model_id' } + allow_stdin: false }); const result = (await future.done) as any; - if ( - result.content.status !== 'ok' || - !result.content.user_expressions.frontendId || - !Private.jupyterFrontEndModels.has(kernelId) - ) { + const jfem = Private.jupyterFrontEndModels.get(kernel.id); + if (!jfem) { throw new Error( - `Failed to setup the JupyterFrontEnd in the new kernel with traceback=${result.content.traceback}` + `Failed to setup the JupyterFrontEnd in the kernel ${kernel.id}! + traceback=${result.content.traceback}` ); } - return Private.jupyterFrontEndModels.get(kernelId); + return jfem; } static serializers: ISerializers = { diff --git a/src/widgets/utils.ts b/src/widgets/utils.ts index 8779025..47b5b4d 100644 --- a/src/widgets/utils.ts +++ b/src/widgets/utils.ts @@ -32,7 +32,7 @@ export async function newSession({ specsManager: IpylabModel.app.serviceManager.kernelspecs, path: path, name: name ?? path, - type: 'notebook', + type: 'ipylab', kernelPreference: { id: kernelId || `${UUID.uuid4()}`, language: language @@ -46,7 +46,10 @@ export async function newSession({ const session = sessionContext.session; const context = {}; (context as any)['sessionContext'] = sessionContext; - (context as any)['saveState'] = new Signal(null); + (context as any)['saveState'] = new Signal({}); + (context as any).saveState.connect(() => { + null; + }); registerWidgetManager(context as any, rendermime, [] as any); if (code) { const future = session.kernel.requestExecute( @@ -140,7 +143,7 @@ export async function injectCode({ */ export function getNestedObject(base: object, path: string): any { let obj: object = base; - let path_: string = ''; + let path_ = ''; const parts = path.split('.'); let attr = ''; for (let i = 0; i < parts.length; i++) { diff --git a/yarn.lock b/yarn.lock index 018c1bf..aeadcb4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4877,10 +4877,8 @@ __metadata: "@jupyterlab/launcher": ^4.1.0 "@jupyterlab/observables": ^5.1.0 "@jupyterlab/rendermime": ^4.1.0 - "@lumino/algorithm": ^2.0.1 "@lumino/commands": ^2.2.0 "@lumino/disposable": ^2.1.2 - "@lumino/messaging": ^2.0.1 "@lumino/widgets": ^2.3.1 "@types/expect.js": ^0.3.29 "@types/json-schema": ^7.0.11