Skip to content

Commit 2593bc6

Browse files
committed
Use browsingContextId for drive access
1 parent b805274 commit 2593bc6

File tree

6 files changed

+327
-313
lines changed

6 files changed

+327
-313
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"@jupyterlab/services": "^7.4.0",
6464
"@jupyterlab/terminal": "^4.4.0",
6565
"@jupyterlab/terminal-extension": "^4.4.0",
66-
"@jupyterlite/cockle": "^0.0.18",
66+
"@jupyterlite/cockle": "^0.0.19",
6767
"@jupyterlite/contents": "0.6.0-alpha.9",
6868
"@jupyterlite/server": "0.6.0-alpha.9",
6969
"@lumino/coreutils": "^2.2.0",

src/index.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
JupyterFrontEndPlugin
77
} from '@jupyterlab/application';
88
import { ITerminalManager, Terminal } from '@jupyterlab/services';
9+
import { IServiceWorkerManager } from '@jupyterlite/server';
910

1011
import { LiteTerminalManager } from './manager';
1112

@@ -16,12 +17,23 @@ const terminalManagerPlugin: JupyterFrontEndPlugin<Terminal.IManager> = {
1617
id: '@jupyterlite/terminal:plugin',
1718
description: 'A terminal for JupyterLite',
1819
autoStart: true,
20+
optional: [IServiceWorkerManager],
1921
provides: ITerminalManager,
20-
activate: async (app: JupyterFrontEnd): Promise<Terminal.IManager> => {
22+
activate: async (
23+
app: JupyterFrontEnd,
24+
serviceWorkerManager?: IServiceWorkerManager
25+
): Promise<Terminal.IManager> => {
2126
console.log(
2227
'JupyterLite extension @jupyterlite/terminal:plugin is activated!'
2328
);
24-
return new LiteTerminalManager();
29+
30+
console.log('DEBUG app:', app);
31+
console.log('DEBUG IServiceWorkerManager:', serviceWorkerManager);
32+
33+
const browsingContextId = serviceWorkerManager?.browsingContextId;
34+
console.log('DEBUG browsingContextId:', browsingContextId);
35+
36+
return new LiteTerminalManager({ browsingContextId });
2537
}
2638
};
2739

src/manager.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ export class LiteTerminalManager
1212
/**
1313
* Construct a new terminal manager.
1414
*/
15-
constructor(options: TerminalManager.IOptions = {}) {
15+
constructor(options: LiteTerminalManager.IOptions) {
1616
super(options);
17+
this.browsingContextId = options.browsingContextId;
1718

1819
// Initialize internal data.
1920
this._ready = (async () => {
@@ -44,9 +45,13 @@ export class LiteTerminalManager
4445
const { model } = options;
4546
const { name } = model;
4647
console.log('==> LiteTerminalManager.connectTo', name);
47-
const { serverSettings } = this;
48+
const { browsingContextId, serverSettings } = this;
4849

49-
const terminal = new LiteTerminalConnection({ model, serverSettings });
50+
const terminal = new LiteTerminalConnection({
51+
browsingContextId,
52+
model,
53+
serverSettings
54+
});
5055
terminal.disposed.connect(() => this.shutdown(name));
5156
return terminal;
5257
}
@@ -139,9 +144,13 @@ export class LiteTerminalManager
139144
): Promise<Terminal.ITerminalConnection> {
140145
const name = options.name ?? this._nextAvailableName();
141146
const model: Terminal.IModel = { name };
142-
const { serverSettings } = this;
147+
const { browsingContextId, serverSettings } = this;
143148

144-
const terminal = new LiteTerminalConnection({ model, serverSettings });
149+
const terminal = new LiteTerminalConnection({
150+
browsingContextId,
151+
model,
152+
serverSettings
153+
});
145154
terminal.disposed.connect(() => this.shutdown(name));
146155
this._terminalConnections.set(name, terminal);
147156
await this.refreshRunning();
@@ -163,6 +172,7 @@ export class LiteTerminalManager
163172
}
164173
}
165174

175+
private readonly browsingContextId?: string;
166176
private _connectionFailure = new Signal<this, Error>(this);
167177
private _isReady = false;
168178
private _ready: Promise<void>;
@@ -172,3 +182,12 @@ export class LiteTerminalManager
172182
Terminal.ITerminalConnection
173183
>();
174184
}
185+
186+
export namespace LiteTerminalManager {
187+
export interface IOptions extends TerminalManager.IOptions {
188+
/**
189+
* The ID of the browsing context where the request originated.
190+
*/
191+
browsingContextId?: string;
192+
}
193+
}

src/terminal.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,18 @@ export class LiteTerminalConnection implements Terminal.ITerminalConnection {
1010
/**
1111
* Construct a new terminal session.
1212
*/
13-
constructor(options: Terminal.ITerminalConnection.IOptions) {
13+
constructor(options: LiteTerminalConnection.IOptions) {
1414
this._name = options.model.name;
1515
this._serverSettings = options.serverSettings!;
1616
const { baseUrl } = this._serverSettings;
17+
const { browsingContextId } = options;
1718

1819
this._shell = new Shell({
1920
mountpoint: '/drive',
2021
driveFsBaseUrl: baseUrl,
2122
wasmBaseUrl: baseUrl + 'extensions/@jupyterlite/terminal/static/wasm/',
22-
outputCallback: this._outputCallback.bind(this)
23+
outputCallback: this._outputCallback.bind(this),
24+
browsingContextId
2325
});
2426
this._shell.disposed.connect(() => this.dispose());
2527

@@ -182,3 +184,12 @@ export class LiteTerminalConnection implements Terminal.ITerminalConnection {
182184

183185
private _shell: IShell;
184186
}
187+
188+
export namespace LiteTerminalConnection {
189+
export interface IOptions extends Terminal.ITerminalConnection.IOptions {
190+
/**
191+
* The ID of the browsing context where the request originated.
192+
*/
193+
browsingContextId?: string;
194+
}
195+
}

src/worker.ts

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,45 @@
11
import { expose } from 'comlink';
22

3-
import { BaseShellWorker, IFileSystem } from '@jupyterlite/cockle';
4-
import {
5-
ContentsAPI,
6-
DriveFS,
7-
ServiceWorkerContentsAPI
8-
} from '@jupyterlite/contents';
9-
10-
/**
11-
* Custom DriveFS implementation using the service worker.
12-
*/
13-
class MyDriveFS extends DriveFS {
14-
createAPI(options: DriveFS.IOptions): ContentsAPI {
15-
return new ServiceWorkerContentsAPI(
16-
options.baseUrl,
17-
options.driveName,
18-
options.mountpoint,
19-
options.FS,
20-
options.ERRNO_CODES
21-
);
22-
}
23-
}
3+
import { BaseShellWorker, IDriveFSOptions } from '@jupyterlite/cockle';
4+
import { DriveFS } from '@jupyterlite/contents';
245

256
/**
267
* Shell web worker that uses DriveFS via service worker.
278
* Note that this is not exported as it is accessed from Shell via the filename.
289
*/
2910
class ShellWorker extends BaseShellWorker {
3011
/**
31-
* Initialize the DriveFS to mount an external file system.
12+
* Initialize the DriveFS to mount an external file system, if available.
3213
*/
33-
protected override initDriveFS(
34-
driveFsBaseUrl: string,
35-
mountpoint: string,
36-
fileSystem: IFileSystem
37-
): void {
38-
console.log('Terminal initDriveFS', driveFsBaseUrl, mountpoint);
39-
const { FS, ERRNO_CODES, PATH } = fileSystem;
40-
const driveFS = new MyDriveFS({
41-
FS,
42-
PATH,
43-
ERRNO_CODES,
44-
baseUrl: driveFsBaseUrl,
45-
driveName: '',
46-
mountpoint
47-
});
48-
FS.mount(driveFS, {}, mountpoint);
14+
protected override initDriveFS(options: IDriveFSOptions): void {
15+
const { browsingContextId, driveFsBaseUrl, fileSystem, mountpoint } =
16+
options;
17+
console.log(
18+
'Terminal initDriveFS',
19+
driveFsBaseUrl,
20+
mountpoint,
21+
browsingContextId
22+
);
23+
if (
24+
mountpoint !== '' &&
25+
driveFsBaseUrl !== undefined &&
26+
browsingContextId !== undefined
27+
) {
28+
const { FS, ERRNO_CODES, PATH } = fileSystem;
29+
const driveFS = new DriveFS({
30+
FS,
31+
PATH,
32+
ERRNO_CODES,
33+
baseUrl: driveFsBaseUrl,
34+
driveName: '',
35+
mountpoint,
36+
browsingContextId
37+
});
38+
FS.mount(driveFS, {}, mountpoint);
39+
console.log('Terminal connected to shared drive');
40+
} else {
41+
console.warn('Terminal not connected to shared drive');
42+
}
4943
}
5044
}
5145

0 commit comments

Comments
 (0)