@fails-components/jupyter-filesystem-extension 0.0.1-alpha.8 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/drive.d.ts +50 -0
- package/lib/{contents.js → drive.js} +64 -21
- package/lib/index.d.ts +3 -4
- package/lib/index.js +45 -22
- package/lib/settings.d.ts +12 -12
- package/lib/settings.js +29 -25
- package/lib/token.d.ts +8 -0
- package/lib/token.js +2 -0
- package/package.json +6 -13
- package/src/{contents.ts → drive.ts} +100 -53
- package/src/index.ts +56 -27
- package/src/settings.ts +45 -31
- package/src/token.ts +15 -0
- package/lib/contents.d.ts +0 -31
package/lib/drive.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Contents, Drive, ServerConnection } from '@jupyterlab/services';
|
|
2
|
+
import { ISignal } from '@lumino/signaling';
|
|
3
|
+
interface IContentEvent {
|
|
4
|
+
task: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ILoadJupyterContentEvent extends IContentEvent {
|
|
7
|
+
task: 'loadFile';
|
|
8
|
+
fileData: object | undefined;
|
|
9
|
+
fileName: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ISavedJupyterContentEvent extends IContentEvent {
|
|
12
|
+
task: 'savedFile';
|
|
13
|
+
fileName: string;
|
|
14
|
+
}
|
|
15
|
+
export type IContentEventType = ILoadJupyterContentEvent | ISavedJupyterContentEvent;
|
|
16
|
+
type IModel = Contents.IModel;
|
|
17
|
+
export declare class FailsDrive implements Contents.IDrive {
|
|
18
|
+
constructor(options: Drive.IOptions);
|
|
19
|
+
dispose(): void;
|
|
20
|
+
get isDisposed(): boolean;
|
|
21
|
+
get name(): string;
|
|
22
|
+
get serverSettings(): ServerConnection.ISettings;
|
|
23
|
+
get fileChanged(): ISignal<Contents.IDrive, Contents.IChangedArgs>;
|
|
24
|
+
getDownloadUrl(path: string): Promise<string>;
|
|
25
|
+
onMessage(event: IContentEventType): Promise<any>;
|
|
26
|
+
get(path: string, options?: Contents.IFetchOptions): Promise<IModel>;
|
|
27
|
+
save(path: string, options?: Partial<Contents.IModel>): Promise<Contents.IModel>;
|
|
28
|
+
newUntitled(options?: Contents.ICreateOptions): Promise<IModel>;
|
|
29
|
+
rename(oldLocalPath: string, newLocalPath: string): Promise<IModel>;
|
|
30
|
+
delete(path: string): Promise<void>;
|
|
31
|
+
copy(path: string, toDir: string): Promise<IModel>;
|
|
32
|
+
createCheckpoint(path: string): Promise<Contents.ICheckpointModel>;
|
|
33
|
+
listCheckpoints(path: string): Promise<Contents.ICheckpointModel[]>;
|
|
34
|
+
restoreCheckpoint(path: string, checkpointID: string): Promise<void>;
|
|
35
|
+
deleteCheckpoint(path: string, checkpointID: string): Promise<void>;
|
|
36
|
+
static EMPTY_NB: {
|
|
37
|
+
metadata: {
|
|
38
|
+
orig_nbformat: number;
|
|
39
|
+
};
|
|
40
|
+
nbformat_minor: number;
|
|
41
|
+
nbformat: number;
|
|
42
|
+
cells: never[];
|
|
43
|
+
};
|
|
44
|
+
private _fileContent;
|
|
45
|
+
private _isDisposed;
|
|
46
|
+
private _fileChanged;
|
|
47
|
+
private _fileName;
|
|
48
|
+
private _serverSettings;
|
|
49
|
+
}
|
|
50
|
+
export {};
|
|
@@ -1,21 +1,44 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ServerConnection } from '@jupyterlab/services';
|
|
2
|
+
import { Signal } from '@lumino/signaling';
|
|
2
3
|
// portions used from Jupyterlab:
|
|
3
4
|
/* -----------------------------------------------------------------------------
|
|
4
5
|
| Copyright (c) Jupyter Development Team.
|
|
5
6
|
| Distributed under the terms of the Modified BSD License.
|
|
6
7
|
|----------------------------------------------------------------------------*/
|
|
7
8
|
// This code contains portions from or is inspired by Jupyter lab and lite
|
|
9
|
+
// especially the Drive implementation
|
|
8
10
|
const jsonMime = 'application/json';
|
|
9
|
-
class
|
|
10
|
-
constructor() {
|
|
11
|
-
|
|
11
|
+
class FailsDrive {
|
|
12
|
+
constructor(options) {
|
|
13
|
+
var _a;
|
|
14
|
+
this._fileContent = JSON.stringify(FailsDrive.EMPTY_NB);
|
|
15
|
+
this._isDisposed = false;
|
|
16
|
+
this._fileChanged = new Signal(this);
|
|
12
17
|
this._fileName = 'unloaded.ipynb';
|
|
13
|
-
this.
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
this._serverSettings =
|
|
19
|
+
(_a = options.serverSettings) !== null && _a !== void 0 ? _a : ServerConnection.makeSettings();
|
|
20
|
+
}
|
|
21
|
+
dispose() {
|
|
22
|
+
if (this.isDisposed) {
|
|
23
|
+
return;
|
|
16
24
|
}
|
|
17
|
-
this.
|
|
18
|
-
|
|
25
|
+
this._isDisposed = true;
|
|
26
|
+
Signal.clearData(this);
|
|
27
|
+
}
|
|
28
|
+
get isDisposed() {
|
|
29
|
+
return this._isDisposed;
|
|
30
|
+
}
|
|
31
|
+
get name() {
|
|
32
|
+
return 'JupyterFailsSingleFileDrive';
|
|
33
|
+
}
|
|
34
|
+
get serverSettings() {
|
|
35
|
+
return this._serverSettings;
|
|
36
|
+
}
|
|
37
|
+
get fileChanged() {
|
|
38
|
+
return this._fileChanged;
|
|
39
|
+
}
|
|
40
|
+
async getDownloadUrl(path) {
|
|
41
|
+
throw new Error('Method not implemented.');
|
|
19
42
|
}
|
|
20
43
|
async onMessage(event) {
|
|
21
44
|
// todo handle events
|
|
@@ -23,8 +46,24 @@ class FailsContents {
|
|
|
23
46
|
case 'loadFile':
|
|
24
47
|
{
|
|
25
48
|
const loadevent = event;
|
|
26
|
-
this._fileContent = JSON.stringify(loadevent.fileData ||
|
|
49
|
+
this._fileContent = JSON.stringify(loadevent.fileData || FailsDrive.EMPTY_NB);
|
|
27
50
|
this._fileName = loadevent.fileName;
|
|
51
|
+
this._fileChanged.emit({
|
|
52
|
+
type: 'save',
|
|
53
|
+
oldValue: null,
|
|
54
|
+
newValue: {
|
|
55
|
+
name: this._fileName,
|
|
56
|
+
path: this._fileName,
|
|
57
|
+
last_modified: new Date(0).toISOString(),
|
|
58
|
+
created: new Date(0).toISOString(),
|
|
59
|
+
format: 'json',
|
|
60
|
+
mimetype: jsonMime,
|
|
61
|
+
content: JSON.parse(this._fileContent),
|
|
62
|
+
size: 0,
|
|
63
|
+
writable: true,
|
|
64
|
+
type: 'notebook'
|
|
65
|
+
}
|
|
66
|
+
});
|
|
28
67
|
}
|
|
29
68
|
break;
|
|
30
69
|
case 'savedFile':
|
|
@@ -40,12 +79,6 @@ class FailsContents {
|
|
|
40
79
|
break;
|
|
41
80
|
}
|
|
42
81
|
}
|
|
43
|
-
get ready() {
|
|
44
|
-
return this._ready.promise;
|
|
45
|
-
}
|
|
46
|
-
async initialize() {
|
|
47
|
-
this._ready.resolve(void 0);
|
|
48
|
-
}
|
|
49
82
|
async get(path, options) {
|
|
50
83
|
// remove leading slash
|
|
51
84
|
path = decodeURIComponent(path.replace(/^\//, ''));
|
|
@@ -79,13 +112,13 @@ class FailsContents {
|
|
|
79
112
|
if (path === this._fileName) {
|
|
80
113
|
return serverFile;
|
|
81
114
|
}
|
|
82
|
-
|
|
115
|
+
throw Error(`Could not find content with path ${path}`);
|
|
83
116
|
}
|
|
84
117
|
async save(path, options = {}) {
|
|
85
118
|
path = decodeURIComponent(path);
|
|
86
119
|
if (path !== this._fileName) {
|
|
87
120
|
// we only allow the proxy object
|
|
88
|
-
|
|
121
|
+
throw Error(`File ${path} is not the proxy file`);
|
|
89
122
|
}
|
|
90
123
|
const chunk = options.chunk;
|
|
91
124
|
const chunked = chunk ? chunk > 1 || chunk === -1 : false;
|
|
@@ -93,7 +126,7 @@ class FailsContents {
|
|
|
93
126
|
content: chunked
|
|
94
127
|
});
|
|
95
128
|
if (!item) {
|
|
96
|
-
|
|
129
|
+
throw Error(`Could not find file with path ${path}`);
|
|
97
130
|
}
|
|
98
131
|
const modified = new Date().toISOString();
|
|
99
132
|
// override with the new values
|
|
@@ -122,9 +155,19 @@ class FailsContents {
|
|
|
122
155
|
size: newcontent.length
|
|
123
156
|
};
|
|
124
157
|
this._fileContent = JSON.stringify(newcontent); // no parsing
|
|
158
|
+
this._fileChanged.emit({
|
|
159
|
+
type: 'save',
|
|
160
|
+
oldValue: null,
|
|
161
|
+
newValue: item
|
|
162
|
+
});
|
|
125
163
|
return item;
|
|
126
164
|
}
|
|
127
165
|
this._fileContent = JSON.stringify(item.content); // no parsing
|
|
166
|
+
this._fileChanged.emit({
|
|
167
|
+
type: 'save',
|
|
168
|
+
oldValue: null,
|
|
169
|
+
newValue: item
|
|
170
|
+
});
|
|
128
171
|
return item;
|
|
129
172
|
}
|
|
130
173
|
// For fails creating a new file is not allowed, so no need to implment it
|
|
@@ -154,7 +197,7 @@ class FailsContents {
|
|
|
154
197
|
throw new Error('deleteCheckpoint not (yet?) implemented');
|
|
155
198
|
}
|
|
156
199
|
}
|
|
157
|
-
|
|
200
|
+
FailsDrive.EMPTY_NB = {
|
|
158
201
|
metadata: {
|
|
159
202
|
orig_nbformat: 4
|
|
160
203
|
},
|
|
@@ -162,4 +205,4 @@ FailsContents.EMPTY_NB = {
|
|
|
162
205
|
nbformat: 4,
|
|
163
206
|
cells: []
|
|
164
207
|
};
|
|
165
|
-
export {
|
|
208
|
+
export { FailsDrive };
|
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
declare const plugins: JupyterLiteServerPlugin<any>[];
|
|
1
|
+
import { ServiceManagerPlugin } from '@jupyterlab/services';
|
|
2
|
+
export * from './token';
|
|
3
|
+
declare const plugins: ServiceManagerPlugin<any>[];
|
|
5
4
|
export default plugins;
|
package/lib/index.js
CHANGED
|
@@ -1,37 +1,60 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { FailsContents } from './contents';
|
|
1
|
+
import { IDefaultDrive, ISettingManager, IServerSettings } from '@jupyterlab/services';
|
|
2
|
+
import { FailsDrive } from './drive';
|
|
4
3
|
import { FailsSettings } from './settings';
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
import { IFailsDriveMessages } from './token';
|
|
5
|
+
export * from './token';
|
|
6
|
+
const failsDriveMessages = {
|
|
7
|
+
id: '@fails-components/jupyter-applet-widget:drivemessages',
|
|
7
8
|
requires: [],
|
|
8
9
|
autoStart: true,
|
|
9
|
-
provides:
|
|
10
|
-
activate: (
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
provides: IFailsDriveMessages,
|
|
11
|
+
activate: (_) => {
|
|
12
|
+
let initialWaitRes;
|
|
13
|
+
const initialWait = new Promise(resolve => (initialWaitRes = resolve));
|
|
14
|
+
let messageHandler;
|
|
15
|
+
const driveMessages = {
|
|
16
|
+
registerMessageHandler: (handler) => {
|
|
17
|
+
messageHandler = handler;
|
|
18
|
+
if (initialWaitRes) {
|
|
19
|
+
initialWaitRes(undefined);
|
|
20
|
+
}
|
|
21
|
+
initialWaitRes = undefined;
|
|
22
|
+
},
|
|
23
|
+
sendMessage: async (msg) => {
|
|
24
|
+
await initialWait;
|
|
25
|
+
return messageHandler(msg);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
return driveMessages;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const failsDrivePlugin = {
|
|
32
|
+
id: '@fails-components/jupyter-applet-widget:drive',
|
|
33
|
+
requires: [IFailsDriveMessages],
|
|
34
|
+
autoStart: true,
|
|
35
|
+
provides: IDefaultDrive,
|
|
36
|
+
activate: (_, driveMessages) => {
|
|
37
|
+
const drive = new FailsDrive({});
|
|
38
|
+
driveMessages.registerMessageHandler(msg => drive.onMessage(msg));
|
|
39
|
+
return drive;
|
|
17
40
|
}
|
|
18
41
|
};
|
|
19
42
|
const failsSettingsPlugin = {
|
|
20
|
-
id: '@fails-components/jupyter-
|
|
43
|
+
id: '@fails-components/jupyter-applet-widget:settings',
|
|
21
44
|
requires: [],
|
|
22
45
|
autoStart: true,
|
|
23
|
-
provides:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
app.started.then(() => settings.initialize().catch(console.warn));
|
|
46
|
+
provides: ISettingManager,
|
|
47
|
+
optional: [IServerSettings],
|
|
48
|
+
activate: (_, serverSettings) => {
|
|
49
|
+
const settings = new FailsSettings({
|
|
50
|
+
serverSettings: serverSettings !== null && serverSettings !== void 0 ? serverSettings : undefined
|
|
51
|
+
});
|
|
30
52
|
return settings;
|
|
31
53
|
}
|
|
32
54
|
};
|
|
33
55
|
const plugins = [
|
|
34
|
-
|
|
56
|
+
failsDriveMessages,
|
|
57
|
+
failsDrivePlugin,
|
|
35
58
|
failsSettingsPlugin
|
|
36
59
|
];
|
|
37
60
|
export default plugins;
|
package/lib/settings.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import { Setting, SettingManager } from '@jupyterlab/services';
|
|
2
|
+
import { ISettingRegistry } from '@jupyterlab/settingregistry';
|
|
3
|
+
export type SettingsFile = 'all.json' | 'all_federated.json';
|
|
4
|
+
export declare class FailsSettings extends SettingManager implements Setting.IManager {
|
|
5
|
+
static _overrides: Record<string, ISettingRegistry.IPlugin['schema']['default']>;
|
|
6
|
+
static override(plugin: ISettingRegistry.IPlugin): ISettingRegistry.IPlugin;
|
|
7
|
+
constructor(options: SettingManager.IOptions);
|
|
8
|
+
fetch(pluginId: string): Promise<ISettingRegistry.IPlugin>;
|
|
9
|
+
list(query?: 'ids'): Promise<{
|
|
10
|
+
ids: string[];
|
|
11
|
+
values: ISettingRegistry.IPlugin[];
|
|
11
12
|
}>;
|
|
12
13
|
private _getAll;
|
|
13
|
-
save(
|
|
14
|
-
private _ready;
|
|
14
|
+
save(id: string, raw: string): Promise<void>;
|
|
15
15
|
}
|
package/lib/settings.js
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import { PageConfig, URLExt } from '@jupyterlab/coreutils';
|
|
2
|
-
import {
|
|
2
|
+
import { SettingManager } from '@jupyterlab/services';
|
|
3
3
|
import * as json5 from 'json5';
|
|
4
|
-
|
|
5
|
-
/* -----------------------------------------------------------------------------
|
|
6
|
-
| Copyright (c) Jupyter Development Team.
|
|
7
|
-
| Distributed under the terms of the Modified BSD License.
|
|
8
|
-
|----------------------------------------------------------------------------*/
|
|
9
|
-
// This code contains portions from or is inspired by Jupyter lab and lite
|
|
10
|
-
class FailsSettings {
|
|
4
|
+
class FailsSettings extends SettingManager {
|
|
11
5
|
static override(plugin) {
|
|
12
6
|
if (FailsSettings._overrides[plugin.id]) {
|
|
13
7
|
if (!plugin.schema.properties) {
|
|
@@ -20,32 +14,32 @@ class FailsSettings {
|
|
|
20
14
|
}
|
|
21
15
|
return plugin;
|
|
22
16
|
}
|
|
23
|
-
constructor() {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return this._ready.promise;
|
|
28
|
-
}
|
|
29
|
-
async initialize() {
|
|
30
|
-
this._ready.resolve(void 0);
|
|
17
|
+
constructor(options) {
|
|
18
|
+
super({
|
|
19
|
+
serverSettings: options.serverSettings
|
|
20
|
+
});
|
|
31
21
|
}
|
|
32
|
-
// copied from the original settings
|
|
33
|
-
async
|
|
34
|
-
const all = await this.
|
|
35
|
-
const settings = all.
|
|
22
|
+
// copied from the original settings (updated)
|
|
23
|
+
async fetch(pluginId) {
|
|
24
|
+
const all = await this.list();
|
|
25
|
+
const settings = all.values;
|
|
36
26
|
const setting = settings.find((setting) => {
|
|
37
27
|
return setting.id === pluginId;
|
|
38
28
|
});
|
|
29
|
+
if (!setting) {
|
|
30
|
+
throw new Error(`Setting ${pluginId} not found`);
|
|
31
|
+
}
|
|
39
32
|
return setting;
|
|
40
33
|
}
|
|
41
|
-
// copied from the original settings
|
|
42
|
-
async
|
|
34
|
+
// copied from the original settings (updated)
|
|
35
|
+
async list(query) {
|
|
36
|
+
var _a, _b;
|
|
43
37
|
const allCore = await this._getAll('all.json');
|
|
44
38
|
let allFederated = [];
|
|
45
39
|
try {
|
|
46
40
|
allFederated = await this._getAll('all_federated.json');
|
|
47
41
|
}
|
|
48
|
-
catch (
|
|
42
|
+
catch (_c) {
|
|
49
43
|
// handle the case where there is no federated extension
|
|
50
44
|
}
|
|
51
45
|
// JupyterLab 4 expects all settings to be returned in one go
|
|
@@ -61,7 +55,17 @@ class FailsSettings {
|
|
|
61
55
|
settings: json5.parse(raw)
|
|
62
56
|
};
|
|
63
57
|
}));
|
|
64
|
-
|
|
58
|
+
// format the settings
|
|
59
|
+
const ids = (_a = settings.map((plugin) => plugin.id)) !== null && _a !== void 0 ? _a : [];
|
|
60
|
+
let values = [];
|
|
61
|
+
if (!query) {
|
|
62
|
+
values =
|
|
63
|
+
(_b = settings.map((plugin) => {
|
|
64
|
+
plugin.data = { composite: {}, user: {} };
|
|
65
|
+
return plugin;
|
|
66
|
+
})) !== null && _b !== void 0 ? _b : [];
|
|
67
|
+
}
|
|
68
|
+
return { ids, values };
|
|
65
69
|
}
|
|
66
70
|
// one to one copy from settings of the original JupyterLite
|
|
67
71
|
async _getAll(file) {
|
|
@@ -70,7 +74,7 @@ class FailsSettings {
|
|
|
70
74
|
const all = (await (await fetch(URLExt.join(settingsUrl, file))).json());
|
|
71
75
|
return all;
|
|
72
76
|
}
|
|
73
|
-
async save(
|
|
77
|
+
async save(id, raw) {
|
|
74
78
|
// we do nothing
|
|
75
79
|
}
|
|
76
80
|
}
|
package/lib/token.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Token } from '@lumino/coreutils';
|
|
2
|
+
import { IContentEventType } from './drive';
|
|
3
|
+
export type IFailsDriveMessageHandler = (msg: IContentEventType) => Promise<void> | void;
|
|
4
|
+
export interface IFailsDriveMessages {
|
|
5
|
+
registerMessageHandler: (handler: IFailsDriveMessageHandler) => void;
|
|
6
|
+
sendMessage: (msg: IContentEventType) => Promise<any>;
|
|
7
|
+
}
|
|
8
|
+
export declare const IFailsDriveMessages: Token<IFailsDriveMessages>;
|
package/lib/token.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fails-components/jupyter-filesystem-extension",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "A collection of extensions, that redirect's filesystems access to fails and let fails puppeteer Jupyter lite. ",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jupyter",
|
|
@@ -60,15 +60,11 @@
|
|
|
60
60
|
"watch:labextension": "jupyter labextension watch ."
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@
|
|
64
|
-
"@
|
|
65
|
-
"@jupyterlab/
|
|
66
|
-
"@
|
|
67
|
-
"@
|
|
68
|
-
"@jupyterlite/contents": "^0.5.0",
|
|
69
|
-
"@jupyterlite/server": "^0.5.0",
|
|
70
|
-
"@jupyterlite/settings": "^0.5.0",
|
|
71
|
-
"@lumino/coreutils": "^2.2.0",
|
|
63
|
+
"@jupyterlab/coreutils": "^6.4.3",
|
|
64
|
+
"@jupyterlab/services": "^7.4.3",
|
|
65
|
+
"@jupyterlab/settingregistry": "^4.4.3",
|
|
66
|
+
"@lumino/coreutils": "^2.2.1",
|
|
67
|
+
"@lumino/signaling": "^2.1.4",
|
|
72
68
|
"json5": "^2.2.3"
|
|
73
69
|
},
|
|
74
70
|
"devDependencies": {
|
|
@@ -111,9 +107,6 @@
|
|
|
111
107
|
"outputDir": "fails_components_jupyter_filesystem_extension/labextension",
|
|
112
108
|
"schemaDir": "schema"
|
|
113
109
|
},
|
|
114
|
-
"jupyterlite": {
|
|
115
|
-
"liteExtension": true
|
|
116
|
-
},
|
|
117
110
|
"eslintIgnore": [
|
|
118
111
|
"node_modules",
|
|
119
112
|
"dist",
|
|
@@ -1,12 +1,24 @@
|
|
|
1
|
-
import { Contents
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { Contents, Drive, ServerConnection } from '@jupyterlab/services';
|
|
2
|
+
import { ISignal, Signal } from '@lumino/signaling';
|
|
3
|
+
|
|
4
|
+
interface IContentEvent {
|
|
5
|
+
task: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface ILoadJupyterContentEvent extends IContentEvent {
|
|
9
|
+
task: 'loadFile';
|
|
10
|
+
fileData: object | undefined;
|
|
11
|
+
fileName: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ISavedJupyterContentEvent extends IContentEvent {
|
|
15
|
+
task: 'savedFile';
|
|
16
|
+
fileName: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type IContentEventType =
|
|
20
|
+
| ILoadJupyterContentEvent
|
|
21
|
+
| ISavedJupyterContentEvent; // use union
|
|
10
22
|
|
|
11
23
|
// portions used from Jupyterlab:
|
|
12
24
|
/* -----------------------------------------------------------------------------
|
|
@@ -14,17 +26,43 @@ import {
|
|
|
14
26
|
| Distributed under the terms of the Modified BSD License.
|
|
15
27
|
|----------------------------------------------------------------------------*/
|
|
16
28
|
// This code contains portions from or is inspired by Jupyter lab and lite
|
|
29
|
+
// especially the Drive implementation
|
|
17
30
|
|
|
18
31
|
const jsonMime = 'application/json';
|
|
32
|
+
type IModel = Contents.IModel;
|
|
19
33
|
|
|
20
|
-
export class
|
|
21
|
-
constructor() {
|
|
22
|
-
this.
|
|
23
|
-
|
|
24
|
-
|
|
34
|
+
export class FailsDrive implements Contents.IDrive {
|
|
35
|
+
constructor(options: Drive.IOptions) {
|
|
36
|
+
this._serverSettings =
|
|
37
|
+
options.serverSettings ?? ServerConnection.makeSettings();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
dispose(): void {
|
|
41
|
+
if (this.isDisposed) {
|
|
42
|
+
return;
|
|
25
43
|
}
|
|
26
|
-
this.
|
|
27
|
-
|
|
44
|
+
this._isDisposed = true;
|
|
45
|
+
Signal.clearData(this);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get isDisposed(): boolean {
|
|
49
|
+
return this._isDisposed;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
get name(): string {
|
|
53
|
+
return 'JupyterFailsSingleFileDrive';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get serverSettings(): ServerConnection.ISettings {
|
|
57
|
+
return this._serverSettings;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get fileChanged(): ISignal<Contents.IDrive, Contents.IChangedArgs> {
|
|
61
|
+
return this._fileChanged;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async getDownloadUrl(path: string): Promise<string> {
|
|
65
|
+
throw new Error('Method not implemented.');
|
|
28
66
|
}
|
|
29
67
|
|
|
30
68
|
async onMessage(event: IContentEventType): Promise<any> {
|
|
@@ -34,9 +72,25 @@ export class FailsContents implements IContents {
|
|
|
34
72
|
{
|
|
35
73
|
const loadevent = event as ILoadJupyterContentEvent;
|
|
36
74
|
this._fileContent = JSON.stringify(
|
|
37
|
-
loadevent.fileData ||
|
|
75
|
+
loadevent.fileData || FailsDrive.EMPTY_NB
|
|
38
76
|
);
|
|
39
77
|
this._fileName = loadevent.fileName;
|
|
78
|
+
this._fileChanged.emit({
|
|
79
|
+
type: 'save',
|
|
80
|
+
oldValue: null,
|
|
81
|
+
newValue: {
|
|
82
|
+
name: this._fileName,
|
|
83
|
+
path: this._fileName,
|
|
84
|
+
last_modified: new Date(0).toISOString(),
|
|
85
|
+
created: new Date(0).toISOString(),
|
|
86
|
+
format: 'json' as Contents.FileFormat,
|
|
87
|
+
mimetype: jsonMime,
|
|
88
|
+
content: JSON.parse(this._fileContent),
|
|
89
|
+
size: 0,
|
|
90
|
+
writable: true,
|
|
91
|
+
type: 'notebook'
|
|
92
|
+
}
|
|
93
|
+
});
|
|
40
94
|
}
|
|
41
95
|
break;
|
|
42
96
|
case 'savedFile':
|
|
@@ -53,18 +107,7 @@ export class FailsContents implements IContents {
|
|
|
53
107
|
}
|
|
54
108
|
}
|
|
55
109
|
|
|
56
|
-
get
|
|
57
|
-
return this._ready.promise;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async initialize() {
|
|
61
|
-
this._ready.resolve(void 0);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async get(
|
|
65
|
-
path: string,
|
|
66
|
-
options?: ServerContents.IFetchOptions
|
|
67
|
-
): Promise<ServerContents.IModel | null> {
|
|
110
|
+
async get(path: string, options?: Contents.IFetchOptions): Promise<IModel> {
|
|
68
111
|
// remove leading slash
|
|
69
112
|
path = decodeURIComponent(path.replace(/^\//, ''));
|
|
70
113
|
|
|
@@ -73,7 +116,7 @@ export class FailsContents implements IContents {
|
|
|
73
116
|
path: this._fileName,
|
|
74
117
|
last_modified: new Date(0).toISOString(),
|
|
75
118
|
created: new Date(0).toISOString(),
|
|
76
|
-
format: 'json' as
|
|
119
|
+
format: 'json' as Contents.FileFormat,
|
|
77
120
|
mimetype: jsonMime,
|
|
78
121
|
content: JSON.parse(this._fileContent),
|
|
79
122
|
size: 0,
|
|
@@ -99,27 +142,27 @@ export class FailsContents implements IContents {
|
|
|
99
142
|
if (path === this._fileName) {
|
|
100
143
|
return serverFile;
|
|
101
144
|
}
|
|
102
|
-
|
|
145
|
+
throw Error(`Could not find content with path ${path}`);
|
|
103
146
|
}
|
|
104
147
|
|
|
105
148
|
async save(
|
|
106
149
|
path: string,
|
|
107
|
-
options: Partial<
|
|
108
|
-
): Promise<
|
|
150
|
+
options: Partial<Contents.IModel> = {}
|
|
151
|
+
): Promise<Contents.IModel> {
|
|
109
152
|
path = decodeURIComponent(path);
|
|
110
153
|
if (path !== this._fileName) {
|
|
111
154
|
// we only allow the proxy object
|
|
112
|
-
|
|
155
|
+
throw Error(`File ${path} is not the proxy file`);
|
|
113
156
|
}
|
|
114
157
|
const chunk = options.chunk;
|
|
115
158
|
const chunked = chunk ? chunk > 1 || chunk === -1 : false;
|
|
116
159
|
|
|
117
|
-
let item:
|
|
160
|
+
let item: Contents.IModel | null = await this.get(path, {
|
|
118
161
|
content: chunked
|
|
119
162
|
});
|
|
120
163
|
|
|
121
164
|
if (!item) {
|
|
122
|
-
|
|
165
|
+
throw Error(`Could not find file with path ${path}`);
|
|
123
166
|
}
|
|
124
167
|
|
|
125
168
|
const modified = new Date().toISOString();
|
|
@@ -152,24 +195,29 @@ export class FailsContents implements IContents {
|
|
|
152
195
|
size: newcontent.length
|
|
153
196
|
};
|
|
154
197
|
this._fileContent = JSON.stringify(newcontent); // no parsing
|
|
198
|
+
this._fileChanged.emit({
|
|
199
|
+
type: 'save',
|
|
200
|
+
oldValue: null,
|
|
201
|
+
newValue: item
|
|
202
|
+
});
|
|
155
203
|
return item;
|
|
156
204
|
}
|
|
157
205
|
|
|
158
206
|
this._fileContent = JSON.stringify(item.content); // no parsing
|
|
207
|
+
this._fileChanged.emit({
|
|
208
|
+
type: 'save',
|
|
209
|
+
oldValue: null,
|
|
210
|
+
newValue: item
|
|
211
|
+
});
|
|
159
212
|
return item;
|
|
160
213
|
}
|
|
161
214
|
|
|
162
215
|
// For fails creating a new file is not allowed, so no need to implment it
|
|
163
|
-
async newUntitled(
|
|
164
|
-
options?: ServerContents.ICreateOptions
|
|
165
|
-
): Promise<ServerContents.IModel | null> {
|
|
216
|
+
async newUntitled(options?: Contents.ICreateOptions): Promise<IModel> {
|
|
166
217
|
throw new Error('NewUntitled not implemented');
|
|
167
218
|
}
|
|
168
219
|
|
|
169
|
-
async rename(
|
|
170
|
-
oldLocalPath: string,
|
|
171
|
-
newLocalPath: string
|
|
172
|
-
): Promise<ServerContents.IModel> {
|
|
220
|
+
async rename(oldLocalPath: string, newLocalPath: string): Promise<IModel> {
|
|
173
221
|
throw new Error('rename not implemented');
|
|
174
222
|
}
|
|
175
223
|
|
|
@@ -177,19 +225,15 @@ export class FailsContents implements IContents {
|
|
|
177
225
|
throw new Error('delete not implemented');
|
|
178
226
|
}
|
|
179
227
|
|
|
180
|
-
async copy(path: string, toDir: string): Promise<
|
|
228
|
+
async copy(path: string, toDir: string): Promise<IModel> {
|
|
181
229
|
throw new Error('copy not implemented');
|
|
182
230
|
}
|
|
183
231
|
|
|
184
|
-
async createCheckpoint(
|
|
185
|
-
path: string
|
|
186
|
-
): Promise<ServerContents.ICheckpointModel> {
|
|
232
|
+
async createCheckpoint(path: string): Promise<Contents.ICheckpointModel> {
|
|
187
233
|
throw new Error('createCheckpoint not (yet?) implemented');
|
|
188
234
|
}
|
|
189
235
|
|
|
190
|
-
async listCheckpoints(
|
|
191
|
-
path: string
|
|
192
|
-
): Promise<ServerContents.ICheckpointModel[]> {
|
|
236
|
+
async listCheckpoints(path: string): Promise<Contents.ICheckpointModel[]> {
|
|
193
237
|
// throw new Error('listCheckpoints not (yet?) implemented');
|
|
194
238
|
return [{ id: 'fakeCheckpoint', last_modified: new Date().toISOString() }];
|
|
195
239
|
}
|
|
@@ -211,8 +255,11 @@ export class FailsContents implements IContents {
|
|
|
211
255
|
cells: []
|
|
212
256
|
};
|
|
213
257
|
|
|
214
|
-
private
|
|
215
|
-
private
|
|
258
|
+
private _fileContent: string = JSON.stringify(FailsDrive.EMPTY_NB);
|
|
259
|
+
private _isDisposed = false;
|
|
260
|
+
private _fileChanged = new Signal<Contents.IDrive, Contents.IChangedArgs>(
|
|
261
|
+
this
|
|
262
|
+
);
|
|
216
263
|
private _fileName: string = 'unloaded.ipynb';
|
|
217
|
-
private
|
|
264
|
+
private _serverSettings: ServerConnection.ISettings;
|
|
218
265
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,44 +1,73 @@
|
|
|
1
|
-
import { IContents } from '@jupyterlite/contents';
|
|
2
1
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
IDefaultDrive,
|
|
3
|
+
Contents,
|
|
4
|
+
ServerConnection,
|
|
5
|
+
Setting,
|
|
6
|
+
ISettingManager,
|
|
7
|
+
IServerSettings,
|
|
8
|
+
ServiceManagerPlugin
|
|
9
|
+
} from '@jupyterlab/services';
|
|
10
|
+
import { FailsDrive, IContentEventType } from './drive';
|
|
8
11
|
import { FailsSettings } from './settings';
|
|
12
|
+
import { IFailsDriveMessageHandler, IFailsDriveMessages } from './token';
|
|
9
13
|
|
|
10
|
-
export
|
|
11
|
-
|
|
14
|
+
export * from './token';
|
|
15
|
+
|
|
16
|
+
const failsDriveMessages: ServiceManagerPlugin<IFailsDriveMessages> = {
|
|
17
|
+
id: '@fails-components/jupyter-applet-widget:drivemessages',
|
|
12
18
|
requires: [],
|
|
13
19
|
autoStart: true,
|
|
14
|
-
provides:
|
|
15
|
-
activate: (
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
provides: IFailsDriveMessages,
|
|
21
|
+
activate: (_: null) => {
|
|
22
|
+
let initialWaitRes: ((val: unknown) => void) | undefined;
|
|
23
|
+
const initialWait = new Promise(resolve => (initialWaitRes = resolve));
|
|
24
|
+
let messageHandler: IFailsDriveMessageHandler;
|
|
25
|
+
const driveMessages = {
|
|
26
|
+
registerMessageHandler: (handler: IFailsDriveMessageHandler) => {
|
|
27
|
+
messageHandler = handler;
|
|
28
|
+
if (initialWaitRes) {
|
|
29
|
+
initialWaitRes(undefined);
|
|
30
|
+
}
|
|
31
|
+
initialWaitRes = undefined;
|
|
32
|
+
},
|
|
33
|
+
sendMessage: async (msg: IContentEventType) => {
|
|
34
|
+
await initialWait;
|
|
35
|
+
return messageHandler(msg);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
return driveMessages;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const failsDrivePlugin: ServiceManagerPlugin<Contents.IDrive> = {
|
|
43
|
+
id: '@fails-components/jupyter-applet-widget:drive',
|
|
44
|
+
requires: [IFailsDriveMessages],
|
|
45
|
+
autoStart: true,
|
|
46
|
+
provides: IDefaultDrive,
|
|
47
|
+
activate: (_: null, driveMessages: IFailsDriveMessages) => {
|
|
48
|
+
const drive = new FailsDrive({});
|
|
49
|
+
driveMessages.registerMessageHandler(msg => drive.onMessage(msg));
|
|
50
|
+
return drive;
|
|
22
51
|
}
|
|
23
52
|
};
|
|
24
53
|
|
|
25
|
-
const failsSettingsPlugin:
|
|
26
|
-
id: '@fails-components/jupyter-
|
|
54
|
+
const failsSettingsPlugin: ServiceManagerPlugin<Setting.IManager> = {
|
|
55
|
+
id: '@fails-components/jupyter-applet-widget:settings',
|
|
27
56
|
requires: [],
|
|
28
57
|
autoStart: true,
|
|
29
|
-
provides:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
app.started.then(() => settings.initialize().catch(console.warn));
|
|
58
|
+
provides: ISettingManager,
|
|
59
|
+
optional: [IServerSettings],
|
|
60
|
+
activate: (_: null, serverSettings: ServerConnection.ISettings | null) => {
|
|
61
|
+
const settings = new FailsSettings({
|
|
62
|
+
serverSettings: serverSettings ?? undefined
|
|
63
|
+
});
|
|
36
64
|
return settings;
|
|
37
65
|
}
|
|
38
66
|
};
|
|
39
67
|
|
|
40
|
-
const plugins:
|
|
41
|
-
|
|
68
|
+
const plugins: ServiceManagerPlugin<any>[] = [
|
|
69
|
+
failsDriveMessages,
|
|
70
|
+
failsDrivePlugin,
|
|
42
71
|
failsSettingsPlugin
|
|
43
72
|
];
|
|
44
73
|
|
package/src/settings.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PageConfig, URLExt } from '@jupyterlab/coreutils';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { Setting, SettingManager } from '@jupyterlab/services';
|
|
3
|
+
import { ISettingRegistry } from '@jupyterlab/settingregistry';
|
|
4
4
|
import * as json5 from 'json5';
|
|
5
5
|
|
|
6
6
|
// portions used from Jupyterlab:
|
|
@@ -9,13 +9,16 @@ import * as json5 from 'json5';
|
|
|
9
9
|
| Distributed under the terms of the Modified BSD License.
|
|
10
10
|
|----------------------------------------------------------------------------*/
|
|
11
11
|
// This code contains portions from or is inspired by Jupyter lab and lite
|
|
12
|
+
export type SettingsFile = 'all.json' | 'all_federated.json';
|
|
12
13
|
|
|
13
|
-
export class FailsSettings implements
|
|
14
|
+
export class FailsSettings extends SettingManager implements Setting.IManager {
|
|
14
15
|
// the following is copied from the original Jupyter Lite Settings Object
|
|
15
|
-
static _overrides: Record<
|
|
16
|
-
|
|
16
|
+
static _overrides: Record<
|
|
17
|
+
string,
|
|
18
|
+
ISettingRegistry.IPlugin['schema']['default']
|
|
19
|
+
> = JSON.parse(PageConfig.getOption('settingsOverrides') || '{}');
|
|
17
20
|
|
|
18
|
-
static override(plugin:
|
|
21
|
+
static override(plugin: ISettingRegistry.IPlugin): ISettingRegistry.IPlugin {
|
|
19
22
|
if (FailsSettings._overrides[plugin.id]) {
|
|
20
23
|
if (!plugin.schema.properties) {
|
|
21
24
|
// probably malformed, or only provides keyboard shortcuts, etc.
|
|
@@ -30,32 +33,31 @@ export class FailsSettings implements ISettings {
|
|
|
30
33
|
return plugin;
|
|
31
34
|
}
|
|
32
35
|
|
|
33
|
-
constructor() {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
get ready(): Promise<void> {
|
|
38
|
-
return this._ready.promise;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async initialize() {
|
|
42
|
-
this._ready.resolve(void 0);
|
|
36
|
+
constructor(options: SettingManager.IOptions) {
|
|
37
|
+
super({
|
|
38
|
+
serverSettings: options.serverSettings
|
|
39
|
+
});
|
|
43
40
|
}
|
|
44
41
|
|
|
45
|
-
// copied from the original settings
|
|
46
|
-
async
|
|
47
|
-
const all = await this.
|
|
48
|
-
const settings = all.
|
|
49
|
-
const setting = settings.find((setting:
|
|
42
|
+
// copied from the original settings (updated)
|
|
43
|
+
async fetch(pluginId: string): Promise<ISettingRegistry.IPlugin> {
|
|
44
|
+
const all = await this.list();
|
|
45
|
+
const settings = all.values as ISettingRegistry.IPlugin[];
|
|
46
|
+
const setting = settings.find((setting: ISettingRegistry.IPlugin) => {
|
|
50
47
|
return setting.id === pluginId;
|
|
51
48
|
});
|
|
49
|
+
if (!setting) {
|
|
50
|
+
throw new Error(`Setting ${pluginId} not found`);
|
|
51
|
+
}
|
|
52
52
|
return setting;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
// copied from the original settings
|
|
56
|
-
async
|
|
55
|
+
// copied from the original settings (updated)
|
|
56
|
+
async list(
|
|
57
|
+
query?: 'ids'
|
|
58
|
+
): Promise<{ ids: string[]; values: ISettingRegistry.IPlugin[] }> {
|
|
57
59
|
const allCore = await this._getAll('all.json');
|
|
58
|
-
let allFederated:
|
|
60
|
+
let allFederated: ISettingRegistry.IPlugin[] = [];
|
|
59
61
|
try {
|
|
60
62
|
allFederated = await this._getAll('all_federated.json');
|
|
61
63
|
} catch {
|
|
@@ -78,23 +80,35 @@ export class FailsSettings implements ISettings {
|
|
|
78
80
|
};
|
|
79
81
|
})
|
|
80
82
|
);
|
|
81
|
-
|
|
83
|
+
|
|
84
|
+
// format the settings
|
|
85
|
+
const ids =
|
|
86
|
+
settings.map((plugin: ISettingRegistry.IPlugin) => plugin.id) ?? [];
|
|
87
|
+
|
|
88
|
+
let values: ISettingRegistry.IPlugin[] = [];
|
|
89
|
+
if (!query) {
|
|
90
|
+
values =
|
|
91
|
+
settings.map((plugin: ISettingRegistry.IPlugin) => {
|
|
92
|
+
plugin.data = { composite: {}, user: {} };
|
|
93
|
+
return plugin;
|
|
94
|
+
}) ?? [];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return { ids, values };
|
|
82
98
|
}
|
|
83
99
|
|
|
84
100
|
// one to one copy from settings of the original JupyterLite
|
|
85
101
|
private async _getAll(
|
|
86
|
-
file:
|
|
87
|
-
): Promise<
|
|
102
|
+
file: SettingsFile
|
|
103
|
+
): Promise<ISettingRegistry.IPlugin[]> {
|
|
88
104
|
const settingsUrl = PageConfig.getOption('settingsUrl') ?? '/';
|
|
89
105
|
const all = (await (
|
|
90
106
|
await fetch(URLExt.join(settingsUrl, file))
|
|
91
|
-
).json()) as
|
|
107
|
+
).json()) as ISettingRegistry.IPlugin[];
|
|
92
108
|
return all;
|
|
93
109
|
}
|
|
94
110
|
|
|
95
|
-
async save(
|
|
111
|
+
async save(id: string, raw: string): Promise<void> {
|
|
96
112
|
// we do nothing
|
|
97
113
|
}
|
|
98
|
-
|
|
99
|
-
private _ready: PromiseDelegate<void>;
|
|
100
114
|
}
|
package/src/token.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Token } from '@lumino/coreutils';
|
|
2
|
+
import { IContentEventType } from './drive';
|
|
3
|
+
|
|
4
|
+
export type IFailsDriveMessageHandler = (
|
|
5
|
+
msg: IContentEventType
|
|
6
|
+
) => Promise<void> | void;
|
|
7
|
+
export interface IFailsDriveMessages {
|
|
8
|
+
registerMessageHandler: (handler: IFailsDriveMessageHandler) => void;
|
|
9
|
+
sendMessage: (msg: IContentEventType) => Promise<any>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const IFailsDriveMessages = new Token<IFailsDriveMessages>(
|
|
13
|
+
'@fails-components/jupyter-fails:IFailsDriveMessages',
|
|
14
|
+
'A service to communicate to the FAILS single file drive.'
|
|
15
|
+
);
|
package/lib/contents.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { Contents as ServerContents } from '@jupyterlab/services';
|
|
2
|
-
import { IContents } from '@jupyterlite/contents';
|
|
3
|
-
import { IContentEventType } from '@fails-components/jupyter-launcher';
|
|
4
|
-
export declare class FailsContents implements IContents {
|
|
5
|
-
constructor();
|
|
6
|
-
onMessage(event: IContentEventType): Promise<any>;
|
|
7
|
-
get ready(): Promise<void>;
|
|
8
|
-
initialize(): Promise<void>;
|
|
9
|
-
get(path: string, options?: ServerContents.IFetchOptions): Promise<ServerContents.IModel | null>;
|
|
10
|
-
save(path: string, options?: Partial<ServerContents.IModel>): Promise<ServerContents.IModel | null>;
|
|
11
|
-
newUntitled(options?: ServerContents.ICreateOptions): Promise<ServerContents.IModel | null>;
|
|
12
|
-
rename(oldLocalPath: string, newLocalPath: string): Promise<ServerContents.IModel>;
|
|
13
|
-
delete(path: string): Promise<void>;
|
|
14
|
-
copy(path: string, toDir: string): Promise<ServerContents.IModel>;
|
|
15
|
-
createCheckpoint(path: string): Promise<ServerContents.ICheckpointModel>;
|
|
16
|
-
listCheckpoints(path: string): Promise<ServerContents.ICheckpointModel[]>;
|
|
17
|
-
restoreCheckpoint(path: string, checkpointID: string): Promise<void>;
|
|
18
|
-
deleteCheckpoint(path: string, checkpointID: string): Promise<void>;
|
|
19
|
-
static EMPTY_NB: {
|
|
20
|
-
metadata: {
|
|
21
|
-
orig_nbformat: number;
|
|
22
|
-
};
|
|
23
|
-
nbformat_minor: number;
|
|
24
|
-
nbformat: number;
|
|
25
|
-
cells: never[];
|
|
26
|
-
};
|
|
27
|
-
private _ready;
|
|
28
|
-
private _fileContent;
|
|
29
|
-
private _fileName;
|
|
30
|
-
private _failsCallbacks;
|
|
31
|
-
}
|