Skip to content

Commit da6352e

Browse files
authored
Expose createProxy (#43)
* Provide `createProxy` * Document use of callbacks * add note about proxy
1 parent a458cad commit da6352e

File tree

3 files changed

+86
-2
lines changed

3 files changed

+86
-2
lines changed

README.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,74 @@ For further information please consult the Jupyter documentation:
128128
- Creating an extension: https://jupyterlab.readthedocs.io/en/stable/extension/extension_dev.html
129129
- Adding commands to the command registry: https://jupyterlab.readthedocs.io/en/stable/extension/extension_points.html#commands
130130

131+
### Registering Callbacks
132+
133+
If you would like to register a callback to be executed when a particular event occurs in the JupyterLab, you can make use of the `createProxy` function from the `jupyter-iframe-commands-host` package. This function allows you to create a proxy to be passed to the IFrame as a command `args`, so it can be invoked in a JupyterLab command.
134+
135+
On the host, define the callback function:
136+
137+
```js
138+
import { createBridge, createProxy } from 'jupyter-iframe-commands-host';
139+
140+
const commandBridge = createBridge({ iframeId: 'jupyterlab' });
141+
142+
const kernelStatus = async ({ displayName, isBusy }) => {
143+
console.log('Received kernel status update from the iframe');
144+
console.log('Display Name:', displayName);
145+
console.log('Is Busy:', isBusy);
146+
};
147+
148+
await commandBridge.execute('kernel-status', createProxy({ kernelStatus }));
149+
```
150+
151+
In your custom JupyterLab extension, you can define a command:
152+
153+
```ts
154+
const demoPlugin: JupyterFrontEndPlugin<void> = {
155+
id: 'jupyter-iframe-commands:demo-callback',
156+
autoStart: true,
157+
description: 'Using host callbacks',
158+
requires: [ILabStatus, INotebookTracker],
159+
activate: async (
160+
app: JupyterFrontEnd,
161+
labStatus: ILabStatus,
162+
tracker: INotebookTracker
163+
) => {
164+
const { commands } = app;
165+
166+
commands.addCommand('kernel-status', {
167+
label: 'Kernel Status',
168+
execute: args => {
169+
const kernelStatus = args['kernelStatus'] as unknown as (
170+
args?: any
171+
) => void;
172+
173+
labStatus.busySignal.connect(async () => {
174+
const kernelSpec =
175+
await tracker.currentWidget?.sessionContext?.session?.kernel?.spec;
176+
const displayName = kernelSpec
177+
? kernelSpec.display_name
178+
: 'Loading...';
179+
kernelStatus({ displayName, isBusy: labStatus.isBusy });
180+
});
181+
}
182+
});
183+
}
184+
};
185+
```
186+
187+
> [!WARNING]
188+
> The returned value of `createProxy` must be passed as the `args` of the command so the underlying proxy can properly be transferred by Comlink. `createProxy` can proxy an entire object, so you can pass multiple callbacks and other data as well at once. For example:
189+
>
190+
> ```js
191+
> const proxy = createProxy({
192+
> kernelStatus,
193+
> anotherCallback,
194+
> someData: { foo: 'bar' }
195+
> });
196+
> await commandBridge.execute('kernel-status', proxy);
197+
> ```
198+
131199
## Demos
132200
133201
### Local Demo

packages/host/src/index.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) TileDB, Inc.
22
// Distributed under the terms of the Modified BSD License.
3-
import { windowEndpoint, wrap } from 'comlink';
3+
import { windowEndpoint, wrap, proxy, ProxyOrClone } from 'comlink';
4+
45
import { ICommandBridgeRemote } from 'jupyter-iframe-commands';
56
/**
67
* A bridge to expose actions on JupyterLab commands.
@@ -22,3 +23,13 @@ export function createBridge({ iframeId }: { iframeId: string }) {
2223

2324
return wrap<ICommandBridgeRemote>(windowEndpoint(iframe.contentWindow));
2425
}
26+
27+
/**
28+
* Creates a proxy for the given object.
29+
*
30+
* @param args - The object to create a proxy for.
31+
* @returns A proxy for the given object.
32+
*/
33+
export function createProxy(args: any): ProxyOrClone<any> {
34+
return proxy(args);
35+
}

packages/host/tsconfig.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,10 @@
44
"outDir": "lib",
55
"rootDir": "src"
66
},
7-
"include": ["src/**/*"]
7+
"include": ["src/**/*"],
8+
"references": [
9+
{
10+
"path": "../extension"
11+
}
12+
]
813
}

0 commit comments

Comments
 (0)