diff --git a/.env.development b/.env.development index 2c23d66..37baa9d 100644 --- a/.env.development +++ b/.env.development @@ -1,4 +1,4 @@ -SERVICE_WORKER_FILE='service-worker.js' +SERVICE_WORKER_FILE='service-worker.js${Math.random()}' APP_ID='1' VUE_APP_URL='prova SVILUPPO!' PROVA_PAOLO='PROVA SVILUPPO' diff --git a/package-lock.json b/package-lock.json index 0c848f1..2b2bcf6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11193,6 +11193,11 @@ } } }, + "idb-keyval": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-3.1.0.tgz", + "integrity": "sha512-iFwFN5n00KNNnVxlOOK280SJJfXWY7pbMUOQXdIXehvvc/mGCV/6T2Ae+Pk2KwAkkATDTwfMavOiDH5lrJKWXQ==" + }, "ieee754": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", @@ -11216,6 +11221,15 @@ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" }, + "immortal-db": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/immortal-db/-/immortal-db-1.0.2.tgz", + "integrity": "sha512-7EaVr6vUaaqsl9Jnp+CY4FzA1jIQD+o1tFEY2+O4ibYgmVB+FEWDoyUNN/naq9ZfiYKw4+uly1fpxk0xyE358w==", + "requires": { + "idb-keyval": "3.1.0", + "js-cookie": "2.2.0" + } + }, "import-cwd": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", diff --git a/package.json b/package.json index 8c23234..32143ff 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "graphql": "^0.13.2", "graphql-tag": "^2.8.0", "gsap": "^2.0.2", + "immortal-db": "^1.0.2", "jquery": "^3.3.1", "js-cookie": "^2.2.0", "localforage": "^1.7.3", diff --git a/quasar.conf.js b/quasar.conf.js index 6a82163..b19d814 100644 --- a/quasar.conf.js +++ b/quasar.conf.js @@ -59,7 +59,7 @@ module.exports = function (ctx) { store: 'src/store/index.ts' }, // app plugins (/src/plugins) - plugins: ['i18n', 'axios', 'vee-validate', 'myconfig', 'local-storage', 'error-handler', 'indexdb', 'vue-idb'], + plugins: ['i18n', 'axios', 'vee-validate', 'myconfig', 'local-storage', 'error-handler', 'globalroutines', 'vue-idb'], css: [ 'app.styl' ], diff --git a/src-pwa/custom-service-worker.js b/src-pwa/custom-service-worker.js index c3a2d27..2f73450 100644 --- a/src-pwa/custom-service-worker.js +++ b/src-pwa/custom-service-worker.js @@ -9,13 +9,50 @@ console.log('05 ___________________________ PAO: this is my custom service worker'); importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.0.0/workbox-sw.js'); //++Todo: Replace with local workbox.js -importScripts('js/idb.js'); -importScripts('js/utility.js'); +importScripts('../statics/js/idb.js'); +importScripts('js/globalenv.js'); +// importScripts('js/utility.js'); +importScripts('../statics/js/storage.js'); + +const cfgenv = { + website: 'http://localhost:8080', + serverweb: 'http://localhost:3000', + dbname: 'mydb3', + dbversion: 11, +} + +async function writeData(table, data) { + console.log('writeData', table, data); + await idbKeyval.setdata(table, data); +} + +async function readAllData(table) { + console.log('readAllData', table); + return await idbKeyval.getalldata(table); +} + +async function clearAllData(table) { + console.log('clearAllData', table); + await idbKeyval.clearalldata(table) +} + +async function deleteItemFromData(table, id) { + console.log('deleteItemFromData', table, 'ID:', id); + + await idbKeyval.deletedata(table, id) +} + + + +// self.addEventListener('activate', function(event) { +// event.waitUntil( +// // createDB() +// ); +// }); if (!workbox) { let workbox = new self.WorkboxSW(); - } if (workbox) { @@ -38,7 +75,7 @@ if (workbox) { // workbox.routing.registerRoute(/^http/, workbox.strategies.networkFirst(), 'GET'); workbox.routing.registerRoute( - /\.(?:png|gif|jpg|jpeg|svg)$/, + new RegExp(/\.(?:png|gif|jpg|jpeg|svg)$/), workbox.strategies.staleWhileRevalidate({ cacheName: 'images', plugins: [ @@ -62,22 +99,28 @@ if (workbox) { }) ); - workbox.routing.registerRoute('http://localhost:3000/todos', function (args) { - return fetch(args.event.request) - .then(function (res) { - var clonedRes = res.clone(); - clearAllData('todos') - .then(function () { - return clonedRes.json(); - }) - .then(function (data) { - for (let key in data) { - writeData('todos', data[key]) - } - }); - return res; - }); - }); + + workbox.routing.registerRoute( + new RegExp(cfgenv.serverweb + '/todos/'), + function (args) { + return fetch(args.event.request, args.event.headers) + .then(function (res) { + console.log('******* registerRoute fetch: (1) ', args.event) + var clonedRes = res.clone(); + clearAllData('todos') + .then(function () { + return clonedRes.json(); + }) + .then(function (data) { + console.log('2) data Received ', data.todos) + for (let key in data.todos) { + writeData('todos', data.todos[key]) + } + }); + return res + }) + } + ); workbox.routing.registerRoute( @@ -158,28 +201,6 @@ if (workbox) { }) ); - // workbox.core.setLogLevel(workbox.core.LOG_LEVELS.debug); - - workbox.routing.registerRoute( - new RegExp('http://localhost:8080/todos'), - function (args) { - return fetch(args.event.request) - .then(function (res) { - console.log('******* fetch: ', args.event) - var clonedRes = res.clone(); - clearAllData('todos') - .then(function () { - return clonedRes.json(); - }) - .then(function (data) { - for (let key in data) { - writeData('todos', data[key]) - } - }); - return res - }) - } - ); } @@ -189,68 +210,107 @@ if ('serviceWorker' in navigator) { } - // self.addEventListener('fetch', function (event) { - // console.log('[Service Worker] Fetching something ....', event); - // console.log('event.request.cache=', event.request.cache) - // if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') { - // console.log('SAME ORIGIN!', event); - // return; - // } - // event.respondWith(caches.match(event.request)); - // }); +// self.addEventListener('fetch', function (event) { +// console.log('[Service Worker] Fetching something ....', event); +// console.log('event.request.cache=', event.request.cache) +// if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') { +// console.log('SAME ORIGIN!', event); +// return; +// } +// event.respondWith(caches.match(event.request)); +// }); - self.addEventListener('sync', function (event) { - console.log('[Service Worker] Background syncing', event); +// const syncStore = {} +// self.addEventListener('message', event => { +// if (event.data.type === 'sync') { +// // get a unique id to save the data +// const id = uuid() +// syncStore[id] = event.data +// // register a sync and pass the id as tag for it to get the data +// self.registration.sync.register(id) +// } +// console.log(event.data) +// }) - if (event.tag === 'sync-new-todos') { - console.log('[Service Worker] Syncing new Todos'); +self.addEventListener('sync', function (event) { + console.log('[Service Worker V5] Background syncing', event); - let authHeader = [] - authHeader['content-type'] = 'application/json'; - authHeader['accept-language'] = 'en'; - // authHeader.append('x-auth', mytok) + let multiparams = event.tag.split('|') + if (multiparams && multiparams.length > 3) { + let cmd = multiparams[0] + let table = multiparams[1] + let method = multiparams[2] + let token = multiparams[3] + // let lang = multiparams[3] + + if ((cmd === 'sync-new-todos') || (cmd === 'sync-delete-todos')) { + console.log('[Service Worker] Syncing', cmd, table, method); + + const headers = new Headers() + headers.append('content-Type', 'application/json') + headers.append('Accept', 'application/json') + headers.append('x-auth', token) event.waitUntil( - readAllData('sync_todos') - .then(function (data) { - for (var dt of data) { - // var postData = new FormData(); - // postData.append('_id', dt._id); - // postData.append('title', dt.title); - // postData.append('location', dt.location); - // postData.append('rawLocationLat', dt.rawLocation.lat); - // postData.append('rawLocationLng', dt.rawLocation.lng); - // postData.append('file', dt.picture, dt._id + '.png'); + readAllData(table) + .then(function (alldata) { + console.log('data: ', alldata) + if (alldata) { + for (var rec of alldata) { + let link = cfgenv.serverweb + '/todos/' + rec._id + console.log('FETCH: ', method, link, 'data:', JSON.stringify(rec)) - console.log('Data to Send 6: ', JSON.stringify(dt)) - - // Update myTodo to the server - fetch('http://localhost:3000/todos', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Accept': 'application/json' - }, - // mode: 'no-cors', - mode: 'cors', - body: JSON.stringify(dt) - }) - .then(function (resData) { - console.log('Sent data Todo:', resData); - if (resData.ok) { - deleteItemFromData('sync_todos', dt.id); - } + // Insert/Delete/Update table to the server + fetch(link, { + method: method, + headers: headers, + mode: 'cors', // 'no-cors', + body: JSON.stringify(rec) }) - .catch(function (err) { - console.log('Error while sending data', err); - }); + .then(function (resData) { + console.log('Result data Todo:', resData); + if (resData.ok) { + deleteItemFromData(table, rec._id); + } + }) + .catch(function (err) { + console.log('Error while sending data', err); + }); + } } - }) ); } - }); + } +}) +; -// } +/* + +// send message to serviceWorker +function sync (url, options) { + navigator.serviceWorker.controller.postMessage({type: 'sync', url, options}) +} + + +const syncStore = {} +self.addEventListener('message', event => { + if(event.data.type === 'sync') { + // get a unique id to save the data + const id = uuid() + syncStore[id] = event.data + // register a sync and pass the id as tag for it to get the data + self.registration.sync.register(id) + } + console.log(event.data) +}) + + +self.addEventListener('sync', event => { + // get the data by tag + const {url, options} = syncStore[event.tag] + event.waitUntil(fetch(url, options)) +}) +*/ diff --git a/src-pwa/register-service-worker.js b/src-pwa/register-service-worker.js index 5205056..b331a7e 100644 --- a/src-pwa/register-service-worker.js +++ b/src-pwa/register-service-worker.js @@ -14,13 +14,13 @@ register(process.env.SERVICE_WORKER_FILE, { console.log('REGISTERED::: !!!', process.env.SERVICE_WORKER_FILE) }, - cached(registration) { // registration -> a ServiceWorkerRegistration instance + cached(registration) { console.log('CACHED::: Content has been cached for offline use.') }, - updatefound(registration) { // registration -> a ServiceWorkerRegistration instance + updatefound(registration) { console.log('UPDATEFOUND::: New content is downloading.') }, - updated(registration) { // registration -> a ServiceWorkerRegistration instance + updated(registration) { console.log('New content is available; please refresh.') }, offline() { diff --git a/src/App.vue b/src/App.vue index 072e1c5..fd1fe53 100644 --- a/src/App.vue +++ b/src/App.vue @@ -26,6 +26,8 @@ import Header from './components/Header.vue' + import globalroutines from './globalroutines/index' + @Component({ components: { appHeader: Header, @@ -49,6 +51,7 @@ UserStore.actions.autologin() .then((loginEseguito) => { if (loginEseguito) { + globalroutines(this, 'loadapp', '') // this.$router.replace('/') } }) diff --git a/src/components/categories/category/category.ts b/src/components/categories/category/category.ts index 0cbfb38..eec08f6 100644 --- a/src/components/categories/category/category.ts +++ b/src/components/categories/category/category.ts @@ -80,7 +80,7 @@ export default class Category extends Vue { } async loadCat() { - await this.$db.categories.toArray().then(ris => this.categories_loc = ris) + // await this.$db.categories.toArray().then(ris => this.categories_loc = ris) this.updatetable() } diff --git a/src/components/categories/tabledata/tabledata.ts b/src/components/categories/tabledata/tabledata.ts index 7bb46c1..b27f197 100644 --- a/src/components/categories/tabledata/tabledata.ts +++ b/src/components/categories/tabledata/tabledata.ts @@ -100,7 +100,7 @@ export default class Tabledata extends Vue { objcat.descr_it = this.category // Add to Indexdb - await this.$db.categories.add(objcat + await this.$db.categories.put(objcat ).then(ris => { myid = ris }) diff --git a/src/components/todos/SingleTodo/SingleTodo.scss b/src/components/todos/SingleTodo/SingleTodo.scss index b8247e6..9ea75a7 100644 --- a/src/components/todos/SingleTodo/SingleTodo.scss +++ b/src/components/todos/SingleTodo/SingleTodo.scss @@ -57,15 +57,7 @@ $heightitem: 19px; font-size: 0.75rem; } -.todo-menu { - min-width: 202px; -} - -.item-menu{ - font-size: 1rem; - -} .titleLista-item { max-width: 92px; @@ -144,9 +136,6 @@ $heightitem: 19px; color: #888; } -.menuProgress { - -} .colProgress { } diff --git a/src/components/todos/SubMenus/SubMenus.scss b/src/components/todos/SubMenus/SubMenus.scss index e69de29..6cbbff6 100644 --- a/src/components/todos/SubMenus/SubMenus.scss +++ b/src/components/todos/SubMenus/SubMenus.scss @@ -0,0 +1,16 @@ +.todo-menu { + min-width: 202px; + +} + +.item-menu{ + font-size: 1rem; +} + +.item-menu:hover { + cursor: pointer; +} + +.menuProgress { + +} diff --git a/src/components/todos/SubMenus/SubMenus.vue b/src/components/todos/SubMenus/SubMenus.vue index f6fda08..73c166d 100644 --- a/src/components/todos/SubMenus/SubMenus.vue +++ b/src/components/todos/SubMenus/SubMenus.vue @@ -30,7 +30,7 @@ - {{field.label}} + {{field.label}} @@ -60,3 +60,7 @@ + + diff --git a/src/components/todos/todo/todo.ts b/src/components/todos/todo/todo.ts index 0de8502..7ddae5a 100644 --- a/src/components/todos/todo/todo.ts +++ b/src/components/todos/todo/todo.ts @@ -13,6 +13,10 @@ import _ from 'lodash' import draggable from 'vuedraggable' +import VueIdb from 'vue-idb' + +import globalroutines from '../../../globalroutines/index' + import $ from 'jquery' @Component({ @@ -93,8 +97,8 @@ export default class Todo extends Vue { // console.log('updateLinkedList', this.todos_arr) - let idprev = -1 - let idnext = -1 + let idprev = '' + let idnext = '' let pos = 1 if (arr.length > 0) { idprev = arr[0].id_prev @@ -221,6 +225,7 @@ export default class Todo extends Vue { let update = false await this.todos_arr.forEach((elem: ITodo) => { if (elem.modified) { + console.log('calling MODIFY 3') this.modify(elem, false) update = true } @@ -275,6 +280,7 @@ export default class Todo extends Vue { console.log('User:' + UserStore.state.userId) const objtodo: ITodo = { + _id: new Date().toISOString(), // Create NEW userId: UserStore.state.userId, descr: '', priority: rescodes.Todos.PRIORITY_NORMAL, @@ -285,8 +291,8 @@ export default class Todo extends Vue { category: '', expiring_at: mydateexp, enableExpiring: false, - id_prev: 0, - id_next: 0, + id_prev: '', + id_next: '', pos: 0, modified: true, progress: 0 @@ -304,7 +310,7 @@ export default class Todo extends Vue { return '' } - insertTodo() { + async insertTodo() { if (this.todo.trim() === '') return @@ -314,7 +320,7 @@ export default class Todo extends Vue { objtodo.descr = this.todo objtodo.category = this.getCategory() - const lastelem = this.getLastList() + const lastelem: ITodo = this.getLastList() objtodo.id_prev = (lastelem !== null) ? lastelem._id : rescodes.LIST_START objtodo.id_next = rescodes.LIST_END objtodo.pos = (lastelem !== null) ? lastelem.pos + 1 : 1 @@ -325,24 +331,31 @@ export default class Todo extends Vue { return } - this.$db.todos.add(objtodo) // Add to Indexdb + await globalroutines(this, 'write', 'todos', objtodo) .then((id) => { - console.log('*** IDNEW = ', id) + console.log('*** IDNEW (2) = ', id) // update also the last elem if (lastelem !== null) { lastelem.id_next = id lastelem.modified = true + console.log('calling MODIFY 4', lastelem) this.modify(lastelem, false) + .then(ris => { + console.log('END calling MODIFY 4') + + this.saveItemToSyncAndDb(rescodes.DB.TABLE_SYNC_TODOS, 'POST', objtodo) + this.updatetable(false) + + }) + } else { + this.saveItemToSyncAndDb(rescodes.DB.TABLE_SYNC_TODOS, 'POST', objtodo) + this.updatetable(false) } - this.saveItemToSyncAndDb(objtodo) - - // this.modify(objtodo, true) - this.updatetable(false) }).catch(err => { - console.log('Errore: ' + err.message) - }) + console.log('Errore: ' + err.message) + }) console.log('ESCO.........') @@ -350,40 +363,69 @@ export default class Todo extends Vue { this.todo = '' } - saveItemToSyncAndDb(item: ITodo) { + cmdToSyncAndDb(cmd, table, method, itemOrId, msg: String) { // Send to Server to Sync + + console.log('cmdToSyncAndDb', cmd, table, method, itemOrId, msg) + const mythis = this - console.log('saveItemToSyncAndDb') if ('serviceWorker' in navigator && 'SyncManager' in window) { navigator.serviceWorker.ready .then(function (sw) { // _id: new Date().toISOString(), console.log('---------------------- navigator.serviceWorker.ready') - // check if exist _id, delete it - mythis.$db.sync_todos - .where('id').equals(item._id) - .delete() + // mythis.sendMessageToSW(item, method) - mythis.$db.sync_todos.add(item) - .then(function () { - return sw.sync.register('sync-new-todos') + globalroutines(mythis, 'write', table, itemOrId) + .then(function (id) { + console.log('id', id) + const sep = '|' + + let multiparams = cmd + sep + table + sep + method + sep + UserStore.state.idToken + sep + UserStore.state.lang + return sw.sync.register(multiparams) }) .then(function () { let snackbarContainer = document.querySelector('#confirmation-toast') - let data = { message: 'Your Post was saved for syncing!' } + let data = { message: msg } // snackbarContainer.MaterialSnackbar.showSnackbar(data) }) .catch(function (err) { - console.log(err) + console.error('Errore in globalroutines', table, err) }) }) } else { - Todos.actions.dbSaveTodo(item) + if (cmd === rescodes.DB.CMD_SYNC_TODOS) + Todos.actions.dbSaveTodo(itemOrId) + else if (cmd === rescodes.DB.CMD_DELETE_TODOS) + Todos.actions.dbDeleteTodo(itemOrId) } - } + saveItemToSyncAndDb(table: String, method, item: ITodo) { + return this.cmdToSyncAndDb(rescodes.DB.CMD_SYNC_TODOS, table, method, item, 'Your Post was saved for syncing!') + } + + + deleteItemToSyncAndDb(table: String, id: String) { + return this.cmdToSyncAndDb(rescodes.DB.CMD_DELETE_TODOS, table, 'DELETE', id, 'Your Post was canceled for syncing!') + } + +/* + sendMessageToSW(recdata, method) { + + navigator.serviceWorker.controller.postMessage({ + type: 'sync', + recdata, + method, + cmd: 'sync-new-todos', + token: UserStore.state.idToken, + lang: UserStore.state.lang + }) + } +*/ + + getElemById(id, lista = this.todos_arr) { let myobj: ITodo for (myobj of lista) { @@ -407,27 +449,28 @@ export default class Todo extends Vue { if (myobjprev !== null) { myobjprev.id_next = myobjtrov.id_next myobjprev.modified = true + console.log('calling MODIFY 2') this.modify(myobjprev, false) } if (myobjnext !== null) { myobjnext.id_prev = myobjtrov.id_prev myobjnext.modified = true + console.log('calling MODIFY 1') this.modify(myobjnext, false) } - console.log('ENTRATO') + this.deleteItemToSyncAndDb(rescodes.DB.TABLE_DELETE_TODOS, id) + const mythis = this // Delete item - await this.$db.todos - .where('id').equals(id) - .delete() - .then(() => { - console.log('UpdateTable') + await globalroutines(this, 'delete', 'todos', id) + .then((ris) => { + console.log('UpdateTable', ris) mythis.updatetable() }).catch((error) => { - console.log('err: ', error) - }) + console.log('err: ', error) + }) } console.log('FINE deleteitem') @@ -498,7 +541,7 @@ export default class Todo extends Vue { } async filtertodos(refresh: boolean = false) { - // console.log('filtertodos') + console.log('filtertodos') return await Todos.actions.getTodosByCategory(this.getCategory()) .then(arrtemp => { @@ -583,45 +626,51 @@ export default class Todo extends Vue { if (recOut[field] !== recIn[field]) { recOut.modified = true recOut[field] = recIn[field] - return true + return recOut[field] } return false } async modify(myobj: ITodo, update: boolean) { - await this.$db.transaction('rw', [this.$db.todos], async () => { - const miorec = await this.$db.todos.get(myobj._id) + await globalroutines(this, 'read', 'todos', myobj._id) + .then(miorec => { + console.log('ArrTodos: ', myobj.descr, '[', myobj._id, ']') - this.modifyField(miorec, myobj, 'descr') - if (this.modifyField(miorec, myobj, 'completed')) - miorec.completed_at = new Date() + if (miorec === undefined) { + console.log('Record not Found !!!!!! id=', myobj._id) + return + } - this.modifyField(miorec, myobj, 'category') - this.modifyField(miorec, myobj, 'expiring_at') - this.modifyField(miorec, myobj, 'priority') - this.modifyField(miorec, myobj, 'id_prev') - this.modifyField(miorec, myobj, 'id_next') - this.modifyField(miorec, myobj, 'pos') - this.modifyField(miorec, myobj, 'enableExpiring') - this.modifyField(miorec, myobj, 'progress') + this.modifyField(miorec, myobj, 'descr') + if (this.modifyField(miorec, myobj, 'completed')) + miorec.completed_at = new Date() + + this.modifyField(miorec, myobj, 'category') + this.modifyField(miorec, myobj, 'expiring_at') + this.modifyField(miorec, myobj, 'priority') + this.modifyField(miorec, myobj, 'id_prev') + this.modifyField(miorec, myobj, 'id_next') + this.modifyField(miorec, myobj, 'pos') + this.modifyField(miorec, myobj, 'enableExpiring') + this.modifyField(miorec, myobj, 'progress') - if (miorec.modified) { - miorec.modify_at = new Date() + if (miorec.modified) { + miorec.modify_at = new Date() - // this.logelem('modify', miorec) + // this.logelem('modify', miorec) - await this.$db.todos.put(miorec) + globalroutines(this, 'write', 'todos', miorec) + .then(ris => { - this.saveItemToSyncAndDb(miorec) - - if (update) - await this.updatetable(false) - } - }) + this.saveItemToSyncAndDb(rescodes.DB.TABLE_SYNC_TODOS, 'PATCH', miorec) + if (update) + this.updatetable(false) + }) + } + }) } - } diff --git a/src/globalroutines/index.js b/src/globalroutines/index.js new file mode 100644 index 0000000..41568e9 --- /dev/null +++ b/src/globalroutines/index.js @@ -0,0 +1,6 @@ +import indexdb from './indexdb' + +export default async (context, cmd, table, data = null) => { + console.log('globalroutines', cmd, table, data) + return await indexdb(context, cmd, table, data) +} diff --git a/src/globalroutines/indexdb.js b/src/globalroutines/indexdb.js new file mode 100644 index 0000000..cbda898 --- /dev/null +++ b/src/globalroutines/indexdb.js @@ -0,0 +1,63 @@ +import store from '../store' +import _ from 'lodash' +import { UserStore } from '@modules' +import { i18n } from '../plugins/i18n' + +import {idbKeyval as storage} from '../js/storage.js'; + +function saveConfigIndexDb(context) { + + let data = [] + data['_id'] = 1 + data['lang'] = UserStore.state.lang + data['token'] = UserStore.state.idToken + data['userId'] = UserStore.state.userId + + writeConfigIndexDb('config', data) +} + +function writeConfigIndexDb(context, data) { + console.log('writeConfigIndexDb', data) + + storage.setdata('config', data) + .then(ris => { + return true + }) + +} + +async function readfromIndexDbToStateTodos(context) { + console.log('*** read from IndexDb to state.todos') + + return await storage.getalldata('todos') + .then(ristodos => { + console.log('&&&&&&& readfromIndexDbToStateTodos OK: Num RECORD: ', ristodos.length) + UserStore.state.todos = ristodos + }).catch((error) => { + console.log('err: ', error) + }) + +} + +export default async (context, cmd, table, datakey) => { + if (cmd === 'loadapp') { + // ****** LOAD APP AL CARICAMENTO ! ******* + return saveConfigIndexDb(context, datakey) + + + if ('indexedDB' in window) { + if (!UserStore.state.networkDataReceived) { + return await readfromIndexDbToStateTodos(context) + } + } + + } else if (cmd === 'write') { + return await storage.setdata(table, datakey) + } else if (cmd === 'readall') { + return await storage.getalldata(table) + } else if (cmd === 'read') { + return await storage.getdata(table, datakey) + } else if (cmd === 'delete') { + return await storage.deletedata(table, datakey) + } +} diff --git a/src/index.template.html b/src/index.template.html index cb87612..aa2c291 100644 --- a/src/index.template.html +++ b/src/index.template.html @@ -17,6 +17,16 @@ + + diff --git a/src/js/fetch.js b/src/js/fetch.js index 6bac6b3..30ea634 100644 --- a/src/js/fetch.js +++ b/src/js/fetch.js @@ -295,7 +295,7 @@ } // HTTP methods whose capitalization should be normalized - var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'] + var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT', 'PATCH'] function normalizeMethod(method) { var upcased = method.toUpperCase() diff --git a/src/js/globalenv.js b/src/js/globalenv.js new file mode 100644 index 0000000..745dd1a --- /dev/null +++ b/src/js/globalenv.js @@ -0,0 +1,24 @@ + +// importScripts('/statics/js/immortal-db.min.js'); + +// const cfgenv = { +// website: 'http://localhost:8080', +// serverweb: 'http://localhost:3000', +// dbname: 'mydb3', +// dbversion: 10, +// } + +/* +async function clearAllDataImmortal(table) { + console.log('clearAllDataImmortal', table) + const db = ImmortalDB.ImmortalDB + await db.remove(table) +} + +async function writeDataImmortal(table, datavalue) { + console.log('writeDataImmortal', table, datavalue) + const db = ImmortalDB.ImmortalDB + await db.set(table, datavalue) +} + +*/ diff --git a/src/js/idb.js b/src/js/idb.js deleted file mode 100644 index 9835513..0000000 --- a/src/js/idb.js +++ /dev/null @@ -1,311 +0,0 @@ -'use strict'; - -(function() { - function toArray(arr) { - return Array.prototype.slice.call(arr); - } - - function promisifyRequest(request) { - return new Promise(function(resolve, reject) { - request.onsuccess = function() { - resolve(request.result); - }; - - request.onerror = function() { - reject(request.error); - }; - }); - } - - function promisifyRequestCall(obj, method, args) { - var request; - var p = new Promise(function(resolve, reject) { - request = obj[method].apply(obj, args); - promisifyRequest(request).then(resolve, reject); - }); - - p.request = request; - return p; - } - - function promisifyCursorRequestCall(obj, method, args) { - var p = promisifyRequestCall(obj, method, args); - return p.then(function(value) { - if (!value) return; - return new Cursor(value, p.request); - }); - } - - function proxyProperties(ProxyClass, targetProp, properties) { - properties.forEach(function(prop) { - Object.defineProperty(ProxyClass.prototype, prop, { - get: function() { - return this[targetProp][prop]; - }, - set: function(val) { - this[targetProp][prop] = val; - } - }); - }); - } - - function proxyRequestMethods(ProxyClass, targetProp, Constructor, properties) { - properties.forEach(function(prop) { - if (!(prop in Constructor.prototype)) return; - ProxyClass.prototype[prop] = function() { - return promisifyRequestCall(this[targetProp], prop, arguments); - }; - }); - } - - function proxyMethods(ProxyClass, targetProp, Constructor, properties) { - properties.forEach(function(prop) { - if (!(prop in Constructor.prototype)) return; - ProxyClass.prototype[prop] = function() { - return this[targetProp][prop].apply(this[targetProp], arguments); - }; - }); - } - - function proxyCursorRequestMethods(ProxyClass, targetProp, Constructor, properties) { - properties.forEach(function(prop) { - if (!(prop in Constructor.prototype)) return; - ProxyClass.prototype[prop] = function() { - return promisifyCursorRequestCall(this[targetProp], prop, arguments); - }; - }); - } - - function Index(index) { - this._index = index; - } - - proxyProperties(Index, '_index', [ - 'name', - 'keyPath', - 'multiEntry', - 'unique' - ]); - - proxyRequestMethods(Index, '_index', IDBIndex, [ - 'get', - 'getKey', - 'getAll', - 'getAllKeys', - 'count' - ]); - - proxyCursorRequestMethods(Index, '_index', IDBIndex, [ - 'openCursor', - 'openKeyCursor' - ]); - - function Cursor(cursor, request) { - this._cursor = cursor; - this._request = request; - } - - proxyProperties(Cursor, '_cursor', [ - 'direction', - 'key', - 'primaryKey', - 'value' - ]); - - proxyRequestMethods(Cursor, '_cursor', IDBCursor, [ - 'update', - 'delete' - ]); - - // proxy 'next' methods - ['advance', 'continue', 'continuePrimaryKey'].forEach(function(methodName) { - if (!(methodName in IDBCursor.prototype)) return; - Cursor.prototype[methodName] = function() { - var cursor = this; - var args = arguments; - return Promise.resolve().then(function() { - cursor._cursor[methodName].apply(cursor._cursor, args); - return promisifyRequest(cursor._request).then(function(value) { - if (!value) return; - return new Cursor(value, cursor._request); - }); - }); - }; - }); - - function ObjectStore(store) { - this._store = store; - } - - ObjectStore.prototype.createIndex = function() { - return new Index(this._store.createIndex.apply(this._store, arguments)); - }; - - ObjectStore.prototype.index = function() { - return new Index(this._store.index.apply(this._store, arguments)); - }; - - proxyProperties(ObjectStore, '_store', [ - 'name', - 'keyPath', - 'indexNames', - 'autoIncrement' - ]); - - proxyRequestMethods(ObjectStore, '_store', IDBObjectStore, [ - 'put', - 'add', - 'delete', - 'clear', - 'get', - 'getAll', - 'getKey', - 'getAllKeys', - 'count' - ]); - - proxyCursorRequestMethods(ObjectStore, '_store', IDBObjectStore, [ - 'openCursor', - 'openKeyCursor' - ]); - - proxyMethods(ObjectStore, '_store', IDBObjectStore, [ - 'deleteIndex' - ]); - - function Transaction(idbTransaction) { - this._tx = idbTransaction; - this.complete = new Promise(function(resolve, reject) { - idbTransaction.oncomplete = function() { - resolve(); - }; - idbTransaction.onerror = function() { - reject(idbTransaction.error); - }; - idbTransaction.onabort = function() { - reject(idbTransaction.error); - }; - }); - } - - Transaction.prototype.objectStore = function() { - return new ObjectStore(this._tx.objectStore.apply(this._tx, arguments)); - }; - - proxyProperties(Transaction, '_tx', [ - 'objectStoreNames', - 'mode' - ]); - - proxyMethods(Transaction, '_tx', IDBTransaction, [ - 'abort' - ]); - - function UpgradeDB(db, oldVersion, transaction) { - this._db = db; - this.oldVersion = oldVersion; - this.transaction = new Transaction(transaction); - } - - UpgradeDB.prototype.createObjectStore = function() { - return new ObjectStore(this._db.createObjectStore.apply(this._db, arguments)); - }; - - proxyProperties(UpgradeDB, '_db', [ - 'name', - 'version', - 'objectStoreNames' - ]); - - proxyMethods(UpgradeDB, '_db', IDBDatabase, [ - 'deleteObjectStore', - 'close' - ]); - - function DB(db) { - this._db = db; - } - - DB.prototype.transaction = function() { - return new Transaction(this._db.transaction.apply(this._db, arguments)); - }; - - proxyProperties(DB, '_db', [ - 'name', - 'version', - 'objectStoreNames' - ]); - - proxyMethods(DB, '_db', IDBDatabase, [ - 'close' - ]); - - // Add cursor iterators - // TODO: remove this once browsers do the right thing with promises - ['openCursor', 'openKeyCursor'].forEach(function(funcName) { - [ObjectStore, Index].forEach(function(Constructor) { - Constructor.prototype[funcName.replace('open', 'iterate')] = function() { - var args = toArray(arguments); - var callback = args[args.length - 1]; - var nativeObject = this._store || this._index; - var request = nativeObject[funcName].apply(nativeObject, args.slice(0, -1)); - request.onsuccess = function() { - callback(request.result); - }; - }; - }); - }); - - // polyfill getAll - [Index, ObjectStore].forEach(function(Constructor) { - if (Constructor.prototype.getAll) return; - Constructor.prototype.getAll = function(query, count) { - var instance = this; - var items = []; - - return new Promise(function(resolve) { - instance.iterateCursor(query, function(cursor) { - if (!cursor) { - resolve(items); - return; - } - items.push(cursor.value); - - if (count !== undefined && items.length == count) { - resolve(items); - return; - } - cursor.continue(); - }); - }); - }; - }); - - var exp = { - open: function(name, version, upgradeCallback) { - var p = promisifyRequestCall(indexedDB, 'open', [name, version]); - var request = p.request; - - request.onupgradeneeded = function(event) { - if (upgradeCallback) { - upgradeCallback(new UpgradeDB(request.result, event.oldVersion, request.transaction)); - } - }; - - return p.then(function(db) { - return new DB(db); - }); - }, - delete: function(name) { - return promisifyRequestCall(indexedDB, 'deleteDatabase', [name]); - } - }; - - if (typeof module !== 'undefined') { - module.exports = exp; - module.exports.default = module.exports; - } - else { - self.idb = exp; - } -}()); diff --git a/src/js/immortal-db.min.js b/src/js/immortal-db.min.js new file mode 100644 index 0000000..7735d36 --- /dev/null +++ b/src/js/immortal-db.min.js @@ -0,0 +1,8 @@ +var ImmortalDB=function(t){var r={};function n(e){if(r[e])return r[e].exports;var o=r[e]={i:e,l:!1,exports:{}};return t[e].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=r,n.d=function(t,r,e){n.o(t,r)||Object.defineProperty(t,r,{enumerable:!0,get:e})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,r){if(1&r&&(t=n(t)),8&r)return t;if(4&r&&"object"==typeof t&&t&&t.__esModule)return t;var e=Object.create(null);if(n.r(e),Object.defineProperty(e,"default",{enumerable:!0,value:t}),2&r&&"string"!=typeof t)for(var o in t)n.d(e,o,function(r){return t[r]}.bind(null,o));return e},n.n=function(t){var r=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(r,"a",r),r},n.o=function(t,r){return Object.prototype.hasOwnProperty.call(t,r)},n.p="",n(n.s=68)}([function(t,r,n){var e=n(39)("wks"),o=n(19),i=n(1).Symbol,u="function"==typeof i;(t.exports=function(t){return e[t]||(e[t]=u&&i[t]||(u?i:o)("Symbol."+t))}).store=e},function(t,r){var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(t,r){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,r,n){var e=n(1),o=n(13),i=n(10),u=n(12),c=n(7),a=function(t,r,n){var s,f,l,p,h=t&a.F,v=t&a.G,y=t&a.S,d=t&a.P,m=t&a.B,g=v?e:y?e[r]||(e[r]={}):(e[r]||{}).prototype,w=v?o:o[r]||(o[r]={}),x=w.prototype||(w.prototype={});for(s in v&&(n=r),n)l=((f=!h&&g&&void 0!==g[s])?g:n)[s],p=m&&f?c(l,e):d&&"function"==typeof l?c(Function.call,l):l,g&&u(g,s,l,t&a.U),w[s]!=l&&i(w,s,p),d&&x[s]!=l&&(x[s]=l)};e.core=o,a.F=1,a.G=2,a.S=4,a.P=8,a.B=16,a.W=32,a.U=64,a.R=128,t.exports=a},function(t,r,n){var e=n(6),o=n(67),i=n(43),u=Object.defineProperty;r.f=n(5)?Object.defineProperty:function(t,r,n){if(e(t),r=i(r,!0),e(n),o)try{return u(t,r,n)}catch(t){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(t[r]=n.value),t}},function(t,r,n){t.exports=!n(9)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,r,n){var e=n(2);t.exports=function(t){if(!e(t))throw TypeError(t+" is not an object!");return t}},function(t,r,n){var e=n(18);t.exports=function(t,r,n){if(e(t),void 0===r)return t;switch(n){case 1:return function(n){return t.call(r,n)};case 2:return function(n,e){return t.call(r,n,e)};case 3:return function(n,e,o){return t.call(r,n,e,o)}}return function(){return t.apply(r,arguments)}}},function(t,r){var n={}.hasOwnProperty;t.exports=function(t,r){return n.call(t,r)}},function(t,r){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,r,n){var e=n(4),o=n(20);t.exports=n(5)?function(t,r,n){return e.f(t,r,o(1,n))}:function(t,r,n){return t[r]=n,t}},function(t,r,n){var e=n(61),o=n(41);t.exports=function(t){return e(o(t))}},function(t,r,n){var e=n(1),o=n(10),i=n(8),u=n(19)("src"),c=Function.toString,a=(""+c).split("toString");n(13).inspectSource=function(t){return c.call(t)},(t.exports=function(t,r,n,c){var s="function"==typeof n;s&&(i(n,"name")||o(n,"name",r)),t[r]!==n&&(s&&(i(n,u)||o(n,u,t[r]?""+t[r]:a.join(String(r)))),t===e?t[r]=n:c?t[r]?t[r]=n:o(t,r,n):(delete t[r],o(t,r,n)))})(Function.prototype,"toString",function(){return"function"==typeof this&&this[u]||c.call(this)})},function(t,r){var n=t.exports={version:"2.6.1"};"number"==typeof __e&&(__e=n)},function(t,r,n){var e=n(4).f,o=n(8),i=n(0)("toStringTag");t.exports=function(t,r,n){t&&!o(t=n?t:t.prototype,i)&&e(t,i,{configurable:!0,value:r})}},function(t,r){t.exports=!1},function(t,r){t.exports={}},function(t,r){var n={}.toString;t.exports=function(t){return n.call(t).slice(8,-1)}},function(t,r){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,r){var n=0,e=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++n+e).toString(36))}},function(t,r){t.exports=function(t,r){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:r}}},function(t,r,n){var e=n(6),o=n(83),i=n(31),u=n(32)("IE_PROTO"),c=function(){},a=function(){var t,r=n(44)("iframe"),e=i.length;for(r.style.display="none",n(59).appendChild(r),r.src="javascript:",(t=r.contentWindow.document).open(),t.write("