Skip to content

Commit 498a263

Browse files
committed
Use browsingContextId for drive access
1 parent b805274 commit 498a263

File tree

6 files changed

+310
-314
lines changed

6 files changed

+310
-314
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: 17 additions & 6 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,9 @@ export class LiteTerminalManager
4445
const { model } = options;
4546
const { name } = model;
4647
console.log('==> LiteTerminalManager.connectTo', name);
47-
const { serverSettings } = this;
48-
49-
const terminal = new LiteTerminalConnection({ model, serverSettings });
48+
const { browsingContextId, serverSettings } = this;
49+
50+
const terminal = new LiteTerminalConnection({ browsingContextId, model, serverSettings });
5051
terminal.disposed.connect(() => this.shutdown(name));
5152
return terminal;
5253
}
@@ -139,9 +140,9 @@ export class LiteTerminalManager
139140
): Promise<Terminal.ITerminalConnection> {
140141
const name = options.name ?? this._nextAvailableName();
141142
const model: Terminal.IModel = { name };
142-
const { serverSettings } = this;
143+
const { browsingContextId, serverSettings } = this;
143144

144-
const terminal = new LiteTerminalConnection({ model, serverSettings });
145+
const terminal = new LiteTerminalConnection({ browsingContextId, model, serverSettings });
145146
terminal.disposed.connect(() => this.shutdown(name));
146147
this._terminalConnections.set(name, terminal);
147148
await this.refreshRunning();
@@ -163,6 +164,7 @@ export class LiteTerminalManager
163164
}
164165
}
165166

167+
private readonly browsingContextId?: string;
166168
private _connectionFailure = new Signal<this, Error>(this);
167169
private _isReady = false;
168170
private _ready: Promise<void>;
@@ -172,3 +174,12 @@ export class LiteTerminalManager
172174
Terminal.ITerminalConnection
173175
>();
174176
}
177+
178+
export namespace LiteTerminalManager {
179+
export interface IOptions extends TerminalManager.IOptions {
180+
/**
181+
* The ID of the browsing context where the request originated.
182+
*/
183+
browsingContextId?: string;
184+
}
185+
}

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: 22 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,35 @@
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 } = options;
16+
console.log('Terminal initDriveFS', driveFsBaseUrl, mountpoint, browsingContextId);
17+
if (mountpoint !== '' && driveFsBaseUrl !== undefined && browsingContextId !== undefined) {
18+
const { FS, ERRNO_CODES, PATH } = fileSystem;
19+
const driveFS = new DriveFS({
20+
FS,
21+
PATH,
22+
ERRNO_CODES,
23+
baseUrl: driveFsBaseUrl,
24+
driveName: '',
25+
mountpoint,
26+
browsingContextId
27+
});
28+
FS.mount(driveFS, {}, mountpoint);
29+
console.log('Terminal connected to shared drive');
30+
} else {
31+
console.warn("Terminal not connected to shared drive");
32+
}
4933
}
5034
}
5135

0 commit comments

Comments
 (0)