Skip to content

Commit 39fe264

Browse files
committed
WIP: docprovider updates.
1 parent 98482ff commit 39fe264

File tree

14 files changed

+2281
-29
lines changed

14 files changed

+2281
-29
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,7 @@ dmypy.json
123123

124124
# Yarn cache
125125
.yarn/
126+
127+
128+
.vscode/
129+
playground/

devenv-jcollab-backend.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: rtccore-jcollab-backend
2+
channels:
3+
- conda-forge
4+
dependencies:
5+
- python
6+
- nodejs=22
7+
- uv
8+
- jupyterlab
9+
- pip:
10+
- jupyter_docprovider>=2.0.2,<3
11+
- "jupyter_server_ydoc>=2.0.2,<3"
12+
- "jupyterlab>=4.4.0,<5.0.0"

package.json

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,30 @@
5959
"watch:labextension": "jupyter labextension watch ."
6060
},
6161
"dependencies": {
62-
"@jupyterlab/application": "^4.0.0",
63-
"@jupyterlab/coreutils": "^6.0.0",
64-
"@jupyterlab/services": "^7.0.0",
65-
"@jupyterlab/settingregistry": "^4.0.0"
62+
"@jupyter/collaborative-drive": "^4.0.2",
63+
"@jupyter/ydoc": "^2.1.3 || ^3.0.0",
64+
"@jupyterlab/application": "^4.4.0",
65+
"@jupyterlab/apputils": "^4.4.0",
66+
"@jupyterlab/cells": "^4.4.0",
67+
"@jupyterlab/coreutils": "^6.4.0",
68+
"@jupyterlab/docregistry": "^4.4.0",
69+
"@jupyterlab/filebrowser": "^4.4.0",
70+
"@jupyterlab/fileeditor": "^4.4.0",
71+
"@jupyterlab/logconsole": "^4.4.0",
72+
"@jupyterlab/notebook": "^4.4.0",
73+
"@jupyterlab/services": "^7.4.0",
74+
"@jupyterlab/settingregistry": "^4.4.0",
75+
"@jupyterlab/translation": "^4.4.0",
76+
"@lumino/coreutils": "^2.2.1",
77+
"@lumino/disposable": "^2.1.4",
78+
"@lumino/signaling": "^2.1.4",
79+
"y-protocols": "^1.0.5",
80+
"y-websocket": "^1.3.15",
81+
"yjs": "^13.5.40"
6682
},
6783
"devDependencies": {
6884
"@jupyterlab/builder": "^4.0.0",
85+
"@jupyterlab/testing": "^4.4.0",
6986
"@jupyterlab/testutils": "^4.0.0",
7087
"@types/jest": "^29.2.0",
7188
"@types/json-schema": "^7.0.11",

src/docprovider/awareness.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/* -----------------------------------------------------------------------------
2+
| Copyright (c) Jupyter Development Team.
3+
| Distributed under the terms of the Modified BSD License.
4+
|----------------------------------------------------------------------------*/
5+
6+
import { User } from '@jupyterlab/services';
7+
8+
import { IDisposable } from '@lumino/disposable';
9+
10+
import { IAwareness } from '@jupyter/ydoc';
11+
12+
import { WebsocketProvider } from 'y-websocket';
13+
14+
export interface IContent {
15+
type: string;
16+
body: string;
17+
}
18+
19+
/**
20+
* A class to provide Yjs synchronization over WebSocket.
21+
*
22+
* We specify custom messages that the server can interpret. For reference please look in yjs_ws_server.
23+
*
24+
*/
25+
export class WebSocketAwarenessProvider
26+
extends WebsocketProvider
27+
implements IDisposable
28+
{
29+
/**
30+
* Construct a new WebSocketAwarenessProvider
31+
*
32+
* @param options The instantiation options for a WebSocketAwarenessProvider
33+
*/
34+
constructor(options: WebSocketAwarenessProvider.IOptions) {
35+
super(options.url, options.roomID, options.awareness.doc, {
36+
awareness: options.awareness
37+
});
38+
39+
this._awareness = options.awareness;
40+
41+
this._user = options.user;
42+
this._user.ready
43+
.then(() => this._onUserChanged(this._user))
44+
.catch(e => console.error(e));
45+
this._user.userChanged.connect(this._onUserChanged, this);
46+
}
47+
48+
get isDisposed(): boolean {
49+
return this._isDisposed;
50+
}
51+
52+
dispose(): void {
53+
if (this._isDisposed) {
54+
return;
55+
}
56+
57+
this._user.userChanged.disconnect(this._onUserChanged, this);
58+
this._isDisposed = true;
59+
this.destroy();
60+
}
61+
62+
private _onUserChanged(user: User.IManager): void {
63+
this._awareness.setLocalStateField('user', user.identity);
64+
}
65+
66+
private _isDisposed = false;
67+
private _user: User.IManager;
68+
private _awareness: IAwareness;
69+
}
70+
71+
/**
72+
* A namespace for WebSocketAwarenessProvider statics.
73+
*/
74+
export namespace WebSocketAwarenessProvider {
75+
/**
76+
* The instantiation options for a WebSocketAwarenessProvider.
77+
*/
78+
export interface IOptions {
79+
/**
80+
* The server URL
81+
*/
82+
url: string;
83+
84+
/**
85+
* The room ID
86+
*/
87+
roomID: string;
88+
89+
/**
90+
* The awareness object
91+
*/
92+
awareness: IAwareness;
93+
94+
/**
95+
* The user data
96+
*/
97+
user: User.IManager;
98+
}
99+
}

src/docprovider/executor.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) Jupyter Development Team.
2+
// Distributed under the terms of the Modified BSD License.
3+
/**
4+
* @packageDocumentation
5+
* @module docprovider-extension
6+
*/
7+
8+
import { NotebookCellServerExecutor } from "./notebookCellExecutor"
9+
import {
10+
JupyterFrontEnd,
11+
JupyterFrontEndPlugin
12+
} from '@jupyterlab/application';
13+
import { PageConfig } from '@jupyterlab/coreutils';
14+
import { INotebookCellExecutor, runCell } from '@jupyterlab/notebook';
15+
16+
export const notebookCellExecutor: JupyterFrontEndPlugin<INotebookCellExecutor> =
17+
{
18+
id: '@jupyter/rtc-core/docprovider-extension:notebook-cell-executor',
19+
description:
20+
'Add notebook cell executor that uses REST API instead of kernel protocol over WebSocket.',
21+
autoStart: true,
22+
provides: INotebookCellExecutor,
23+
activate: (app: JupyterFrontEnd): INotebookCellExecutor => {
24+
if (PageConfig.getOption('serverSideExecution') === 'true') {
25+
return new NotebookCellServerExecutor({
26+
serverSettings: app.serviceManager.serverSettings
27+
});
28+
}
29+
return Object.freeze({ runCell });
30+
}
31+
};

0 commit comments

Comments
 (0)