소스 검색

Update state database extension with initialization data loading.

Afshin Darian 7 년 전
부모
커밋
cfff732c4a
3개의 변경된 파일54개의 추가작업 그리고 20개의 파일을 삭제
  1. 1 1
      packages/application-extension/src/index.ts
  2. 46 18
      packages/apputils-extension/src/index.ts
  3. 7 1
      packages/coreutils/src/statedb.ts

+ 1 - 1
packages/application-extension/src/index.ts

@@ -191,8 +191,8 @@ const router: JupyterLabPlugin<IRouter> = {
     commands.addCommand(CommandIDs.url, {
       execute: args => URLExt.join(tree, (args.path as string))
     });
-    app.started.then(() => { router.route(window.location.href); });
     router.register({ command: CommandIDs.tree, pattern: /^\/tree\/.+/ });
+    app.started.then(() => { router.route(window.location.href); });
 
     return router;
   },

+ 46 - 18
packages/apputils-extension/src/index.ts

@@ -4,7 +4,7 @@
 |----------------------------------------------------------------------------*/
 
 import {
-  ILayoutRestorer, JupyterLab, JupyterLabPlugin
+  ILayoutRestorer, IRouter, JupyterLab, JupyterLabPlugin
 } from '@jupyterlab/application';
 
 import {
@@ -28,11 +28,11 @@ import {
 } from '@phosphor/algorithm';
 
 import {
-  JSONObject
+  PromiseDelegate
 } from '@phosphor/coreutils';
 
 import {
-  DisposableDelegate, IDisposable
+  DisposableDelegate, DisposableSet, IDisposable
 } from '@phosphor/disposable';
 
 import {
@@ -217,31 +217,59 @@ const state: JupyterLabPlugin<IStateDB> = {
   provides: IStateDB,
   requires: [IRouter],
   activate: (app: JupyterLab, router: IRouter) => {
-    const { commands, info, restored } = app;
+    const { commands, info } = app;
+    const delegate = new PromiseDelegate<StateDB.DataChange>();
     const state = new StateDB({
       namespace: info.namespace,
-      when: restored.then(() => { /* no-op */ })
+      load: delegate.promise
     });
-    const version = info.version;
-    const key = 'statedb:version';
-    const fetch = state.fetch(key);
-    const save = () => state.save(key, { version });
-    const reset = () => state.clear().then(save);
-    const check = (value: JSONObject) => {
-      let old = value && value['version'];
-      if (!old || old !== version) {
-        const previous = old || 'unknown';
-        console.log(`Upgraded: ${previous} to ${version}; Resetting DB.`);
-        return reset();
+    let resolved = false;
+    const disposables = new DisposableSet();
+    const pattern = /^\/workspaces\/(.+)/;
+    const unload = () => {
+      disposables.dispose();
+      router.routed.disconnect(unload, state);
+
+      // If the request that was routed did not contain a workspace,
+      // leave the database intact.
+      if (!resolved) {
+        console.log('No workspace requested. Leaving state database intact.');
+        delegate.resolve({ type: 'cancel', contents: null });
       }
     };
 
-    app.commands.addCommand(CommandIDs.clearStateDB, {
+    let command = CommandIDs.clearStateDB;
+    commands.addCommand(command, {
       label: 'Clear Application Restore State',
       execute: () => state.clear()
     });
 
-    return fetch.then(check, reset).then(() => state);
+    command = CommandIDs.loadState;
+    disposables.add(commands.addCommand(command, {
+      execute: (args: IRouter.ICommandArgs) => {
+        const workspace = (args.path || '').match(pattern)[1];
+
+        // If there is no workspace, leave the state database intact.
+        if (!workspace) {
+          console.log('No workspace found. Leaving state database intact.');
+          resolved = true;
+          delegate.resolve({ type: 'cancel', contents: null });
+          return;
+        }
+
+        // Fetch the workspace and overwrite the state database.
+        console.log('Fetch the workspace:', workspace);
+        resolved = true;
+        delegate.resolve({ type: 'merge', contents: { } });
+      }
+    }));
+    disposables.add(router.register({ command, pattern }));
+
+    // After the first route in the application lifecycle has been routed,
+    // stop listening to routing events.
+    router.routed.connect(unload, state);
+
+    return state;
   }
 };
 

+ 7 - 1
packages/coreutils/src/statedb.ts

@@ -352,6 +352,12 @@ class StateDB implements IStateDB {
  */
 export
 namespace StateDB {
+  export
+  type DataChange = {
+    type: 'cancel' | 'clear' | 'merge' | 'overwrite',
+    contents: ReadonlyJSONObject | null
+  };
+
   /**
    * The instantiation options for a state database.
    */
@@ -371,7 +377,7 @@ namespace StateDB {
      * be cleared, merged with the `contents` data, or if it should be
      * overwritten with the `contents` data.
      */
-    load?: Promise<{ type: 'clear' | 'merge' | 'overwrite', contents?: ReadonlyJSONObject}>;
+    load?: Promise<DataChange>;
   }
 }