2
0
Эх сурвалжийг харах

Improvements to how things are stored.

- Use the bare JID as indexedDB dataStore
- Collapse localStorage and indexedDB stores into one `persistent` store.
- When testing, only clear test data
JC Brand 5 жил өмнө
parent
commit
03b7ae0a30

+ 1 - 0
dev.html

@@ -41,6 +41,7 @@
             'discuss@conference.conversejs.org'
         ],
         enable_smacks: true,
+        persistent_store: 'IndexedDB',
         muc_respect_autojoin: true,
         message_archiving: 'always',
         loglevel: 'debug'

+ 3 - 3
spec/login.js

@@ -29,9 +29,9 @@
             spyOn(cbview.loginpanel, 'connect');
             cbview.delegateEvents();
 
-            expect(_converse.config.get('storage')).toBe('local');
+            expect(_converse.config.get('storage')).toBe('persistent');
             cbview.el.querySelector('input[type="submit"]').click();
-            expect(_converse.config.get('storage')).toBe('local');
+            expect(_converse.config.get('storage')).toBe('persistent');
             expect(cbview.loginpanel.connect).toHaveBeenCalled();
 
             checkbox.click();
@@ -72,7 +72,7 @@
 
                 checkbox.click();
                 cbview.el.querySelector('input[type="submit"]').click();
-                expect(_converse.config.get('storage')).toBe('local');
+                expect(_converse.config.get('storage')).toBe('persistent');
                 done();
             });
         }));

+ 2 - 2
src/converse-controlbox.js

@@ -442,12 +442,12 @@ converse.plugins.add('converse-controlbox', {
                 if (_converse.trusted === 'on' || _converse.trusted === 'off') {
                     _converse.config.save({
                         'trusted': _converse.trusted === 'on',
-                        'storage': _converse.trusted === 'on' ? 'local' : 'session'
+                        'storage': _converse.trusted === 'on' ? 'persistent' : 'session'
                     });
                 } else {
                     _converse.config.save({
                         'trusted': form_data.get('trusted') && true || false,
-                        'storage': form_data.get('trusted') ? 'local' : 'session'
+                        'storage': form_data.get('trusted') ? 'persistent' : 'session'
                     });
                 }
 

+ 9 - 10
src/converse-minimize.js

@@ -471,12 +471,11 @@ converse.plugins.add('converse-minimize', {
             },
 
             initToggle () {
-                const storage = _converse.config.get('storage'),
-                      id = `converse.minchatstoggle-${_converse.bare_jid}`;
+                const id = `converse.minchatstoggle-${_converse.bare_jid}`;
                 this.toggleview = new _converse.MinimizedChatsToggleView({
                     'model': new _converse.MinimizedChatsToggle({'id': id})
                 });
-                this.toggleview.model.browserStorage = _converse.createStore(id, storage);
+                this.toggleview.model.browserStorage = _converse.createStore(id);
                 this.toggleview.model.fetch();
             },
 
@@ -568,22 +567,22 @@ converse.plugins.add('converse-minimize', {
             }
         });
 
-        /************************ BEGIN Event Handlers ************************/
-        _converse.api.waitUntil('chatBoxViewsInitialized').then(() => {
-            _converse.minimized_chats = new _converse.MinimizedChats({
-                model: _converse.chatboxes
-            });
+        function initMinimizedChats () {
+            _converse.minimized_chats = new _converse.MinimizedChats({model: _converse.chatboxes});
             /**
              * Triggered once the _converse.MinimizedChats instance has been * initialized
              * @event _converse#minimizedChatsInitialized
              * @example _converse.api.listen.on('minimizedChatsInitialized', () => { ... });
              */
             _converse.api.trigger('minimizedChatsInitialized');
-        }).catch(e => log.fatal(e));
+        }
 
-        const debouncedTrimChats = _.debounce(() => _converse.chatboxviews.trimChats(), 250);
+        /************************ BEGIN Event Handlers ************************/
+        _converse.api.listen.on('userSessionInitialized', () => initMinimizedChats());
         _converse.api.listen.on('chatBoxInsertedIntoDOM', view => _converse.chatboxviews.trimChats(view));
         _converse.api.listen.on('controlBoxOpened', view => _converse.chatboxviews.trimChats(view));
+
+        const debouncedTrimChats = _.debounce(() => _converse.chatboxviews.trimChats(), 250);
         _converse.api.listen.on('registeredGlobalEventHandlers', () => window.addEventListener("resize", debouncedTrimChats));
         _converse.api.listen.on('unregisteredGlobalEventHandlers', () => window.removeEventListener("resize", debouncedTrimChats));
         /************************ END Event Handlers ************************/

+ 1 - 1
src/converse-muc-views.js

@@ -131,7 +131,7 @@ converse.plugins.add('converse-muc-views', {
                 this.roomspanel = new _converse.RoomsPanel({
                     'model': new (_converse.RoomsPanelModel.extend({
                         id,
-                        'browserStorage': _converse.createStore(id, _converse.config.get('storage'))
+                        'browserStorage': _converse.createStore(id)
                     }))()
                 });
                 this.roomspanel.model.fetch();

+ 1 - 2
src/headless/converse-bookmarks.js

@@ -112,10 +112,9 @@ converse.plugins.add('converse-bookmarks', {
                 this.on('remove', this.markRoomAsUnbookmarked, this);
                 this.on('remove', this.sendBookmarkStanza, this);
 
-                const storage = _converse.config.get('storage');
                 const cache_key = `converse.room-bookmarks${_converse.bare_jid}`;
                 this.fetched_flag = cache_key+'fetched';
-                this.browserStorage = _converse.createStore(cache_key, storage);
+                this.browserStorage = _converse.createStore(cache_key);
             },
 
             async openBookmarkedRoom (bookmark) {

+ 31 - 35
src/headless/converse-core.js

@@ -359,33 +359,34 @@ _converse.isUniView = function () {
 };
 
 
-async function initStorage () {
+async function initSessionStorage () {
     await BrowserStorage.sessionStorageInitialized;
+    _converse.storage = {
+        'session': BrowserStorage.localForage.createInstance({
+            'name': _converse.isTestEnv() ? 'converse-test-session' : 'converse-session',
+            'description': 'sessionStorage instance',
+            'driver': ['sessionStorageWrapper']
+        })
+    };
+}
 
-    // Sets up Backbone.BrowserStorage and localForage for the 3 different stores.
-    _converse.localStorage = BrowserStorage.localForage.createInstance({
-        'name': 'local',
-        'description': 'localStorage instance',
-        'driver': [BrowserStorage.localForage.LOCALSTORAGE]
-    });
-
-    _converse.indexedDB = BrowserStorage.localForage.createInstance({
-        'name': 'indexed',
-        'description': 'indexedDB instance',
-        'driver': [BrowserStorage.localForage.INDEXEDDB]
-    });
-
-    _converse.sessionStorage = BrowserStorage.localForage.createInstance({
-        'name': 'session',
-        'description': 'sessionStorage instance',
-        'driver': ['sessionStorageWrapper']
-    });
 
-    _converse.storage = {
-        'session': _converse.sessionStorage,
-        'local': _converse.localStorage,
-        'indexed': _converse.indexedDB
+function initPersistentStorage () {
+    if (_converse.config.get('storage') !== 'persistent') {
+        return;
+    }
+    const config = {
+        'name': _converse.isTestEnv() ? 'converse-test-persistent' : 'converse-persistent',
+        'storeName': _converse.bare_jid
     }
+    if (_converse.persistent_store === 'localStorage') {
+        config['description'] = 'localStorage instance';
+        config['driver'] = [BrowserStorage.localForage.LOCALSTORAGE];
+    } else if (_converse.persistent_store === 'IndexedDB') {
+        config['description'] = 'indexedDB instance';
+        config['driver'] = [BrowserStorage.localForage.INDEXEDDB];
+    }
+    _converse.storage['persistent'] = BrowserStorage.localForage.createInstance(config);
 }
 
 
@@ -447,11 +448,10 @@ function initClientConfig () {
      * user sessions.
      */
     const id = 'converse.client-config';
-    const store_map = { 'localStorage': 'local', 'IndexedDB': 'indexed' };
     _converse.config = new Backbone.Model({
         'id': id,
         'trusted': _converse.trusted && true || false,
-        'storage': _converse.trusted ? store_map[_converse.persistent_store] : 'session'
+        'storage': _converse.trusted ? 'persistent' : 'session'
     });
     _converse.config.browserStorage = _converse.createStore(id, "session");
     _converse.config.fetch();
@@ -684,6 +684,7 @@ async function initSession (jid) {
             _converse.session.save({id});
         }
         saveJIDtoSession(jid);
+        initPersistentStorage();
         /**
          * Triggered once the user's session has been initialized. The session is a
          * cache which stores information about the user's current session.
@@ -831,7 +832,7 @@ function setUpXMLLogging () {
 
 
 async function finishInitialization () {
-    await initStorage();
+    await initSessionStorage();
     initClientConfig();
     initPlugins();
     registerGlobalEventHandlers();
@@ -976,15 +977,10 @@ function unregisterGlobalEventHandlers () {
     _converse.api.trigger('unregisteredGlobalEventHandlers');
 }
 
-async function cleanup () {
+
+function cleanup () {
     // Make sure everything is reset in case this is a subsequent call to
     // convesre.initialize (happens during tests).
-    if (_converse.localStorage) {
-        await Promise.all([
-            BrowserStorage.localForage.dropInstance({'name': 'local'}),
-            BrowserStorage.localForage.dropInstance({'name': 'indexed'}),
-            BrowserStorage.localForage.dropInstance({'name': 'session'})]);
-    }
     Backbone.history.stop();
     unregisterGlobalEventHandlers();
     delete _converse.controlboxtoggle;
@@ -1000,7 +996,7 @@ async function cleanup () {
 
 
 _converse.initialize = async function (settings, callback) {
-    await cleanup();
+    cleanup();
 
     settings = settings !== undefined ? settings : {};
     PROMISES.forEach(addPromise);
@@ -1802,7 +1798,7 @@ Object.assign(window.converse, {
      * @property {function} converse.env.sizzle    - [Sizzle](https://sizzlejs.com) CSS selector engine.
      * @property {object} converse.env.utils       - Module containing common utility methods used by Converse.
      */
-    'env': { $build, $iq, $msg, $pres, Backbone, Promise, Strophe, _, dayjs, log, sizzle, stanza_utils, u, 'utils': u }
+    'env': { $build, $iq, $msg, $pres, Backbone, BrowserStorage, Promise, Strophe, _, dayjs, log, sizzle, stanza_utils, u, 'utils': u }
 });
 
 /**

+ 2 - 1
src/headless/converse-disco.js

@@ -236,7 +236,8 @@ converse.plugins.add('converse-disco', {
                     this.fetch({
                         add: true,
                         success: resolve,
-                        error () {
+                        error (m, e) {
+                            log.error(e);
                             reject (new Error("Could not fetch disco entities"));
                         }
                     });

+ 3 - 4
src/headless/converse-roster.js

@@ -970,20 +970,19 @@ converse.plugins.add('converse-roster', {
             // Initialize the Bakcbone collections that represent the contats
             // roster and the roster groups.
             await _converse.api.waitUntil('VCardsInitialized');
-            const storage = _converse.config.get('storage');
             _converse.roster = new _converse.RosterContacts();
             let id = `converse.contacts-${_converse.bare_jid}`;
-            _converse.roster.browserStorage = _converse.createStore(id, storage);
+            _converse.roster.browserStorage = _converse.createStore(id);
 
             _converse.roster.data = new Backbone.Model();
             id = `converse-roster-model-${_converse.bare_jid}`;
             _converse.roster.data.id = id;
-            _converse.roster.data.browserStorage = _converse.createStore(id, storage);
+            _converse.roster.data.browserStorage = _converse.createStore(id);
             _converse.roster.data.fetch();
 
             id = `converse.roster.groups${_converse.bare_jid}`;
             _converse.rostergroups = new _converse.RosterGroups();
-            _converse.rostergroups.browserStorage = _converse.createStore(id, storage);
+            _converse.rostergroups.browserStorage = _converse.createStore(id);
             /**
              * Triggered once the `_converse.RosterContacts` and `_converse.RosterGroups` have
              * been created, but not yet populated with data.

+ 27 - 3
tests/mock.js

@@ -5,6 +5,7 @@
     converse.load();
 
     const _ = converse.env._;
+    const u = converse.env.utils;
     const Promise = converse.env.Promise;
     const Strophe = converse.env.Strophe;
     const dayjs = converse.env.dayjs;
@@ -220,9 +221,30 @@
     Strophe.Connection = MockConnection;
 
 
+    function clearIndexedDB () {
+        const promise = u.getResolveablePromise();
+        const DBOpenRequest = window.indexedDB.open("converse-test-persistent");
+        DBOpenRequest.onsuccess = function () {
+            const db = DBOpenRequest.result;
+            const bare_jid = "romeo@montague.lit";
+            const objectStore = db.transaction([bare_jid], "readwrite").objectStore(bare_jid);
+            const objectStoreRequest = objectStore.clear();
+            objectStoreRequest.onsuccess = promise.resolve();
+            objectStoreRequest.onerror = promise.resolve();
+        };
+        return promise;
+    }
+
+    function clearStores () {
+        [localStorage, sessionStorage].forEach(
+            s => Object.keys(s).forEach(k => k.match(/^converse-test-/) && s.removeItem(k))
+        );
+    }
+
+
     async function initConverse (settings) {
-        window.localStorage.clear();
-        window.sessionStorage.clear();
+        clearStores();
+        await clearIndexedDB();
 
         const _converse = await converse.initialize(Object.assign({
             'animate': false,
@@ -230,6 +252,7 @@
             'bosh_service_url': 'montague.lit/http-bind',
             'enable_smacks': false,
             'i18n': 'en',
+            // 'persistent_store': 'IndexedDB',
             'loglevel': 'warn',
             'no_trimming': true,
             'play_sounds': false,
@@ -282,6 +305,7 @@
             promise_names = []
             settings = null;
         }
+
         return async done => {
             const _converse = await initConverse(settings);
             async function _done () {
@@ -301,7 +325,7 @@
             } catch(e) {
                 console.error(e);
                 fail(e);
-                _done();
+                await _done();
             }
         }
     };