فهرست منبع

Добавлено кеширование запросов на клиенте

Book Pauk 2 سال پیش
والد
کامیت
2c51bfaf96
3فایلهای تغییر یافته به همراه111 افزوده شده و 8 حذف شده
  1. 36 8
      client/components/Search/Search.vue
  2. 74 0
      client/components/Search/authorBooksStorage.js
  3. 1 0
      client/store/root.js

+ 36 - 8
client/components/Search/Search.vue

@@ -151,6 +151,7 @@
 
 
                 <q-checkbox v-model="showCounts" size="36px" label="Показывать количество" />
                 <q-checkbox v-model="showCounts" size="36px" label="Показывать количество" />
                 <q-checkbox v-model="showDeleted" size="36px" label="Показывать удаленные" />
                 <q-checkbox v-model="showDeleted" size="36px" label="Показывать удаленные" />
+                <q-checkbox v-model="abCacheEnabled" size="36px" label="Кешировать запросы" />
             </div>
             </div>
 
 
             <template #footer>
             <template #footer>
@@ -168,6 +169,7 @@ import vueComponent from '../vueComponent.js';
 import { reactive } from 'vue';
 import { reactive } from 'vue';
 
 
 import PageScroller from './PageScroller/PageScroller.vue';
 import PageScroller from './PageScroller/PageScroller.vue';
+import authorBooksStorage from './authorBooksStorage';
 import DivBtn from '../share/DivBtn.vue';
 import DivBtn from '../share/DivBtn.vue';
 import Dialog from '../share/Dialog.vue';
 import Dialog from '../share/Dialog.vue';
 
 
@@ -218,6 +220,9 @@ const componentOptions = {
         showDeleted(newValue) {
         showDeleted(newValue) {
             this.setSetting('showDeleted', newValue);
             this.setSetting('showDeleted', newValue);
         },
         },
+        abCacheEnabled(newValue) {
+            this.setSetting('abCacheEnabled', newValue);
+        },
         totalFound() {
         totalFound() {
             this.updatePageCount();
             this.updatePageCount();
         },
         },
@@ -250,11 +255,13 @@ class Search {
     expanded = [];
     expanded = [];
     showCounts = true;
     showCounts = true;
     showDeleted = false;
     showDeleted = false;
+    abCacheEnabled = true;
 
 
     //stuff
     //stuff
     queryFound = -1;
     queryFound = -1;
     totalFound = 0;
     totalFound = 0;
     bookRowsOnPage = 100;
     bookRowsOnPage = 100;
+    inpxHash = '';
 
 
     limitOptions = [
     limitOptions = [
         {label: '10', value: 10},
         {label: '10', value: 10},
@@ -276,13 +283,17 @@ class Search {
     }
     }
 
 
     mounted() {
     mounted() {
-        this.api = this.$root.api;
+        (async() => {
+            await authorBooksStorage.init();
+
+            this.api = this.$root.api;
 
 
-        if (!this.$root.isMobileDevice)
-            this.$refs.authorInput.focus();
+            if (!this.$root.isMobileDevice)
+                this.$refs.authorInput.focus();
 
 
-        this.ready = true;
-        this.refresh();//no await
+            this.ready = true;
+            this.refresh();//no await
+        })();
     }
     }
 
 
     loadSettings() {
     loadSettings() {
@@ -290,7 +301,9 @@ class Search {
 
 
         this.limit = settings.limit;
         this.limit = settings.limit;
         this.expanded = _.cloneDeep(settings.expanded);
         this.expanded = _.cloneDeep(settings.expanded);
+        this.showCounts = settings.showCounts;
         this.showDeleted = settings.showDeleted;
         this.showDeleted = settings.showDeleted;
+        this.abCacheEnabled = settings.abCacheEnabled;
     }
     }
 
 
     get config() {
     get config() {
@@ -438,9 +451,23 @@ class Search {
         return `(${result})`;
         return `(${result})`;
     }
     }
 
 
-    async loadBooks(author, authorId) {
+    async loadBooks(authorId) {
         try {
         try {
-            const result = await this.api.getBookList(authorId);
+            let result;
+
+            const key = `${authorId}-${this.inpxHash}`;
+
+            if (this.abCacheEnabled) {
+                const data = await authorBooksStorage.getData(key);
+                if (data) {
+                    result = JSON.parse(data);
+                } else {
+                    result = await this.api.getBookList(authorId);
+                    await authorBooksStorage.setData(key, JSON.stringify(result));
+                }
+            } else {
+                result = await this.api.getBookList(authorId);
+            }
 
 
             return JSON.parse(result.books);
             return JSON.parse(result.books);
         } catch (e) {
         } catch (e) {
@@ -470,7 +497,7 @@ class Search {
                 })();
                 })();
             }
             }
 
 
-            const loadedBooks = await this.loadBooks(item.author, item.key);
+            const loadedBooks = await this.loadBooks(item.key);
 
 
             const filtered = this.filterBooks(loadedBooks);
             const filtered = this.filterBooks(loadedBooks);
 
 
@@ -561,6 +588,7 @@ class Search {
 
 
                     this.queryFound = result.author.length;
                     this.queryFound = result.author.length;
                     this.totalFound = result.totalFound;
                     this.totalFound = result.totalFound;
+                    this.inpxHash = result.inpxHash;
 
 
                     this.searchResult = result;
                     this.searchResult = result;
                     await this.updateTableData();
                     await this.updateTableData();

+ 74 - 0
client/components/Search/authorBooksStorage.js

@@ -0,0 +1,74 @@
+import localForage from 'localforage';
+//import _ from 'lodash';
+import * as utils from '../../share/utils';
+
+const maxDataSize = 100*1024*1024;
+
+const abStore = localForage.createInstance({
+    name: 'authorBooksStorage'
+});
+
+class AuthorBooksStorage {
+    constructor() {
+    }
+
+    async init() {
+        this.cleanStorage(); //no await
+    }
+
+    async setData(key, data) {
+        if (typeof data !== 'string')
+            throw new Error('AuthorBooksStorage: data must be a string');
+
+        await abStore.setItem(key, data);
+        await abStore.setItem(`addTime-${key}`, Date.now());    
+    }
+
+    async getData(key) {
+        const item = await abStore.getItem(key);
+        
+        //обновим addTime
+        if (item !== undefined)
+            abStore.setItem(`addTime-${key}`, Date.now());//no await
+
+        return item;
+    }
+
+    async removeData(key) {
+        await abStore.removeItem(key);
+        await abStore.removeItem(`addTime-${key}`);
+    }
+
+    async cleanStorage() {
+        await utils.sleep(5000);
+
+        while (1) {// eslint-disable-line no-constant-condition
+            let size = 0;
+            let min = Date.now();
+            let toDel = null;
+            for (const key of (await abStore.keys())) {
+                if (key.indexOf('addTime-') == 0)
+                    continue;
+
+                const item = await abStore.getItem(key);
+                const addTime = await abStore.getItem(`addTime-${key}`);
+
+                size += item.length;
+
+                if (addTime < min) {
+                    toDel = key;
+                    min = addTime;
+                }
+            }
+
+            if (size > maxDataSize && toDel) {
+                await this.removeData(toDel);
+            } else {
+                break;
+            }
+        }
+    }
+
+}
+
+export default new AuthorBooksStorage();

+ 1 - 0
client/store/root.js

@@ -6,6 +6,7 @@ const state = {
         expanded: [],
         expanded: [],
         showCounts: true,
         showCounts: true,
         showDeleted: false,
         showDeleted: false,
+        abCacheEnabled: true,
     },
     },
 };
 };