added localDbSvc

This commit is contained in:
benweet 2017-07-27 09:23:54 +01:00
parent f06f872a04
commit 97172e28b3
13 changed files with 474 additions and 51 deletions

View File

@ -13,7 +13,9 @@
"dependencies": { "dependencies": {
"bezier-easing": "^1.1.0", "bezier-easing": "^1.1.0",
"clunderscore": "^1.0.3", "clunderscore": "^1.0.3",
"debug": "^2.6.8",
"diff-match-patch": "^1.0.0", "diff-match-patch": "^1.0.0",
"indexeddbshim": "^3.0.4",
"katex": "^0.7.1", "katex": "^0.7.1",
"markdown-it": "^8.3.1", "markdown-it": "^8.3.1",
"markdown-it-abbr": "^1.0.4", "markdown-it-abbr": "^1.0.4",
@ -35,6 +37,7 @@
"babel-eslint": "^7.1.1", "babel-eslint": "^7.1.1",
"babel-loader": "^6.2.10", "babel-loader": "^6.2.10",
"babel-plugin-transform-runtime": "^6.22.0", "babel-plugin-transform-runtime": "^6.22.0",
"babel-polyfill": "^6.23.0",
"babel-preset-env": "^1.3.2", "babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0", "babel-preset-stage-2": "^6.22.0",
"babel-register": "^6.22.0", "babel-register": "^6.22.0",

View File

@ -104,41 +104,4 @@ textarea {
} }
} }
} }
$r: 9px;
$d: $r * 2;
$t: 1500ms;
.spinner {
width: $d;
height: $d;
display: block;
position: relative;
border: $d/10 solid currentColor;
border-radius: 50%;
&::before,
&::after {
content: "";
position: absolute;
display: block;
width: $d/10;
background-color: currentColor;
border-radius: ($d/10)/2;
transform-origin: 50% 0;
}
&::before {
height: $r - $d/5;
left: $r - $d/10 - $d/20;
top: 50%;
animation: spin $t linear infinite;
}
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
</style> </style>

View File

@ -206,4 +206,42 @@ export default {
margin: 10px 5px 0; margin: 10px 5px 0;
color: rgba(255, 255, 255, 0.33); color: rgba(255, 255, 255, 0.33);
} }
$r: 9px;
$d: $r * 2;
$b: $d/10;
$t: 1500ms;
.spinner {
width: $d;
height: $d;
display: block;
position: relative;
border: $b solid currentColor;
border-radius: 50%;
&::before,
&::after {
content: "";
position: absolute;
display: block;
width: $b;
background-color: currentColor;
border-radius: $b * 0.5;
transform-origin: 50% 0;
}
&::before {
height: $r * 0.5;
left: $r - $b * 1.5;
top: 50%;
animation: spin $t linear infinite;
}
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
</style> </style>

View File

@ -1,5 +1,5 @@
<template> <template>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" class="icon" width="100%" height="100%" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" class="icon" width="100%" height="100%" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve">
<path fill="#000000" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M13.125,16.5l-3.5,0l0,-3l3.5,0c0.828,0 1.5,0.672 1.5,1.5c0,0.828 -0.672,1.5 -1.5,1.5Zm-3.5,-9l3,0c0.828,0 1.5,0.672 1.5,1.5c0,0.828 -0.672,1.5 -1.5,1.5l-3,0m5.6,1.288c0.966,-0.674 1.65,-1.767 1.65,-2.788c0,-2.255 -1.745,-4 -4,-4l-6.25,0l0,14l7.042,0c2.094,0 3.708,-1.698 3.708,-3.792c0,-1.516 -0.863,-2.814 -2.15,-3.42Z" /> <path d="M13.35,17.401l-4.201,0l0,-3.601l4.201,0c0.997,0 1.801,0.805 1.801,1.801c0,0.996 -0.804,1.8 -1.801,1.8m-4.201,-10.802l3.601,0c0.996,0 1.801,0.804 1.801,1.8c0,0.996 -0.805,1.801 -1.801,1.801l-3.601,0m6.722,1.548c1.164,-0.816 1.98,-2.149 1.98,-3.349c0,-2.712 -2.1,-4.801 -4.801,-4.801l-7.502,0l0,16.804l8.45,0c2.521,0 4.454,-2.04 4.454,-4.549c0,-1.825 -1.033,-3.385 -2.581,-4.105Z" style="fill-rule:nonzero;"/>
</svg> </svg>
</template> </template>

View File

@ -1,5 +1,5 @@
<template> <template>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" class="icon" width="100%" height="100%" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" class="icon" width="100%" height="100%" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve">
<path fill="#000000" fill-opacity="1" stroke-linejoin="round" d="M10,5l0,3l2.214,0l-3.428,8l-2.786,0l0,3l8,0l0,-3l-2.214,0l3.428,-8l2.786,0l0,-3l-8,0Z" /> <path d="M8.617,3.658l0,3.575l2.633,0l-2.075,9.534l-3.325,0l0,3.575l9.533,0l0,-3.575l-2.633,0l2.075,-9.534l3.325,0l0,-3.575l-9.533,0Z" style="fill-rule:nonzero;"/>
</svg> </svg>
</template> </template>

View File

@ -1,5 +1,5 @@
<template> <template>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" class="icon" width="100%" height="100%" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" class="icon" width="100%" height="100%" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve">
<path fill="#000000" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 7,5L 21,5L 21,7L 7,7L 7,5 Z M 7,13L 7,11L 21,11L 21,13L 7,13 Z M 4,4.50001C 4.83,4.50001 5.5,5.16993 5.5,6.00001C 5.5,6.83008 4.83,7.50001 4,7.50001C 3.17,7.50001 2.5,6.83008 2.5,6.00001C 2.5,5.16993 3.17,4.50001 4,4.50001 Z M 4,10.5C 4.83,10.5 5.5,11.17 5.5,12C 5.5,12.83 4.83,13.5 4,13.5C 3.17,13.5 2.5,12.83 2.5,12C 2.5,11.17 3.17,10.5 4,10.5 Z M 7,19L 7,17L 21,17L 21,19L 7,19 Z M 4,16.5C 4.83,16.5 5.5,17.17 5.5,18C 5.5,18.83 4.83,19.5 4,19.5C 3.17,19.5 2.5,18.83 2.5,18C 2.5,17.17 3.17,16.5 4,16.5 Z " /> <path d="M7.043,4.695l14.61,0l0,2.087l-14.61,0l0,-2.087m0,8.349l0,-2.088l14.61,0l0,2.088l-14.61,0m-3.131,-8.871c0.866,0 1.566,0.699 1.566,1.565c0,0.867 -0.7,1.566 -1.566,1.566c-0.866,0 -1.565,-0.699 -1.565,-1.566c0,-0.866 0.699,-1.565 1.565,-1.565m0,6.262c0.866,0 1.566,0.699 1.566,1.565c0,0.866 -0.7,1.565 -1.566,1.565c-0.866,0 -1.565,-0.699 -1.565,-1.565c0,-0.866 0.699,-1.565 1.565,-1.565m3.131,8.87l0,-2.087l14.61,0l0,2.087l-14.61,0m-3.131,-2.609c0.866,0 1.566,0.699 1.566,1.566c0,0.866 -0.7,1.565 -1.566,1.565c-0.866,0 -1.565,-0.699 -1.565,-1.565c0,-0.867 0.699,-1.566 1.565,-1.566Z" style="fill-rule:nonzero;"/>
</svg> </svg>
</template> </template>

View File

@ -1,5 +1,5 @@
<template> <template>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" class="icon" width="100%" height="100%" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" class="icon" width="100%" height="100%" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve">
<path fill="#000000" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 6.99938,12.998L 20.9994,12.998L 20.9994,10.998L 6.99938,10.998M 6.99938,18.998L 20.9994,18.998L 20.9994,16.998L 6.99938,16.998M 6.99938,6.99805L 20.9994,6.99805L 20.9994,4.99805L 6.99938,4.99805M 1.99938,10.998L 3.79939,10.998L 1.99938,13.0981L 1.99938,13.998L 4.99938,13.998L 4.99938,12.998L 3.19938,12.998L 4.99938,10.898L 4.99938,9.99805L 1.99938,9.99805M 2.99938,7.99805L 3.99938,7.99805L 3.99938,3.99805L 1.99938,3.99805L 1.99938,4.99805L 2.99938,4.99805M 1.99938,16.998L 3.99938,16.998L 3.99938,17.498L 2.99938,17.498L 2.99938,18.498L 3.99938,18.498L 3.99938,18.998L 1.99938,18.998L 1.99938,19.998L 4.99938,19.998L 4.99938,15.998L 1.99938,15.998L 1.99938,16.998 Z " /> <path d="M7.235,13.059l14.825,0l0,-2.118l-14.825,0m0,8.471l14.825,0l0,-2.117l-14.825,0m0,-10.59l14.825,0l0,-2.117l-14.825,0m-5.295,6.353l1.906,0l-1.906,2.224l0,0.953l3.177,0l0,-1.059l-1.906,0l1.906,-2.224l0,-0.953l-3.177,0m1.059,-2.118l1.059,0l0,-4.235l-2.118,0l0,1.059l1.059,0m-1.059,12.707l2.118,0l0,0.529l-1.059,0l0,1.059l1.059,0l0,0.529l-2.118,0l0,1.059l3.177,0l0,-4.235l-3.177,0l0,1.059Z" style="fill-rule:nonzero;"/>
</svg> </svg>
</template> </template>

View File

@ -1,5 +1,5 @@
<template> <template>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" class="icon" width="100%" height="100%" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" class="icon" width="100%" height="100%" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve">
<path fill="#000000" fill-opacity="1" stroke-linejoin="round" d="M 14,17L 17,17L 19,13L 19,7L 13,7L 13,13L 16,13M 6,17L 9,17L 11,13L 11,7L 5,7L 5,13L 8,13L 6,17 Z " /> <path d="M14.446,18.235l2.92,0l1.946,-4.988l0,-7.482l-5.839,0l0,7.482l2.92,0m-10.732,4.988l2.919,0l1.947,-4.988l0,-7.482l-5.839,0l0,7.482l2.919,0l-1.946,4.988Z" style="fill-rule:nonzero;"/>
</svg> </svg>
</template> </template>

View File

@ -1,5 +1,5 @@
<template> <template>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" class="icon" width="100%" height="100%" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" class="icon" width="100%" height="100%" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve">
<path fill="#000000" fill-opacity="1" stroke-linejoin="round" d="M 3,12L 6,12L 6,19L 9,19L 9,12L 12,12L 12,9L 3,9M 9,4L 9,7L 14,7L 14,19L 17,19L 17,7L 22,7L 22,4L 9,4 Z " /> <path d="M2.007,12.526l3.156,0l0,7.363l3.155,0l0,-7.363l3.156,0l0,-3.156l-9.467,0m6.311,-5.259l0,3.155l5.26,0l0,12.623l3.156,0l0,-12.623l5.259,0l0,-3.155l-13.675,0Z" style="fill-rule:nonzero;"/>
</svg> </svg>
</template> </template>

View File

@ -1,5 +1,5 @@
<template> <template>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" class="icon" width="100%" height="100%" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" class="icon" width="100%" height="100%" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve">
<path fill="#000000" fill-opacity="1" stroke-width="0.2" stroke-linejoin="miter" d="M20.275,12.05l0,1.505l-3.305,0c0.756,1.61 0.72,6.009 -4.682,6.03c-6.265,0.023 -6.03,-4.89 -6.03,-4.89l2.986,0.023c0.023,2.539 2.362,2.539 2.844,2.504c0.482,-0.035 2.28,-0.023 2.421,-1.787c0.066,-0.818 -0.761,-1.444 -1.665,-1.88l-9.119,0l0,-1.505l16.55,0Zm-2.698,-3.091l-2.997,-0.024c0,0 0.129,-2.08 -2.468,-2.092c-2.598,-0.012 -2.386,1.658 -2.363,1.869c0.024,0.212 0.247,1.246 2.257,1.74l-4.737,0c0,0 -2.624,-5.062 3.785,-5.936c6.547,-0.893 6.535,4.455 6.523,4.443Z" /> <path d="M20.874,12.059l0,1.729l-3.541,0c0.806,1.851 0.766,6.918 -5.026,6.918c-6.721,0.043 -6.463,-5.621 -6.463,-5.621l3.203,0.044c0.024,2.914 2.55,2.914 3.05,2.879c0.516,-0.043 2.444,-0.034 2.598,-2.058c0.064,-0.942 -0.823,-1.66 -1.791,-2.162l-9.778,0l0,-1.729l17.748,0m-2.896,-3.554l-3.211,-0.026c0,0 0.137,-2.395 -2.646,-2.404c-2.783,-0.017 -2.541,1.902 -2.541,2.144c0.032,0.243 0.274,1.436 2.42,2.007l-5.074,0c0,0 -2.816,-5.82 4.057,-6.814c7.027,-1.038 7.011,5.11 6.995,5.093Z" style="fill-rule:nonzero;"/>
</svg> </svg>
</template> </template>

363
src/services/localDbSvc.js Normal file
View File

@ -0,0 +1,363 @@
import 'babel-polyfill';
import 'indexeddbshim';
import utils from './utils';
let indexedDB = window.indexedDB;
const localStorage = window.localStorage;
const dbVersion = 1;
// Use the shim on Safari or if indexedDB is not available
if (window.shimIndexedDB && (!indexedDB || (navigator.userAgent.indexOf('Chrome') === -1 && navigator.userAgent.indexOf('Safari') !== -1))) {
indexedDB = window.shimIndexedDB;
}
const deletedMarkerMaxAge = 1000;
function identity(value) {
return value;
}
function makeStore(storeName, schemaParameter) {
const schema = {
...schemaParameter,
updated: 'int',
};
const schemaKeys = Object.keys(schema);
const schemaKeysLen = schemaKeys.length;
const complexKeys = [];
let complexKeysLen = 0;
const attributeCheckers = {};
const attributeReaders = {};
const attributeWriters = {};
class Dao {
constructor(id, skipInit) {
this.id = id || utils.uid();
if (!skipInit) {
const fakeItem = {};
for (let i = 0; i < schemaKeysLen; i += 1) {
attributeReaders[schemaKeys[i]](fakeItem, this);
}
this.$dirty = true;
}
}
}
function createDao(id) {
return new Dao(id);
}
Object.keys(schema).forEach((key) => {
const value = schema[key];
const storedValueKey = `_${key}`;
let defaultValue = value.default === undefined ? '' : value.default;
let serializer = value.serializer || identity;
let parser = value.parser || identity;
if (value === 'int') {
defaultValue = 0;
} else if (value === 'object') {
defaultValue = 'null';
parser = JSON.parse;
serializer = JSON.stringify;
}
attributeReaders[key] = (dbItem, dao) => {
dao[storedValueKey] = dbItem[key] || defaultValue;
};
attributeWriters[key] = (dbItem, dao) => {
const storedValue = dao[storedValueKey];
if (storedValue && storedValue !== defaultValue) {
dbItem[key] = storedValue;
}
};
function getter() {
return this[storedValueKey];
}
function setter(param) {
const val = param || defaultValue;
if (this[storedValueKey] === val) {
return false;
}
this[storedValueKey] = val;
this.$dirty = true;
return true;
}
if (key === 'updated') {
Object.defineProperty(Dao.prototype, key, {
get: getter,
set: (value) => {
if (setter.call(this, value)) {
this.$dirtyUpdated = true;
}
}
})
} else if (value === 'string' || value === 'int') {
Object.defineProperty(Dao.prototype, key, {
get: getter,
set: setter
})
} else if (![64, 128] // Handle string64 and string128
.cl_some(function (length) {
if (value === 'string' + length) {
Object.defineProperty(Dao.prototype, key, {
get: getter,
set: function (value) {
if (value && value.length > length) {
value = value.slice(0, length)
}
setter.call(this, value)
}
})
return true
}
})
) {
// Other types go to complexKeys list
complexKeys.push(key)
complexKeysLen++
// And have complex readers/writers
attributeReaders[key] = function (dbItem, dao) {
const storedValue = dbItem[key]
if (!storedValue) {
storedValue = defaultValue
}
dao[storedValueKey] = storedValue
dao[key] = parser(storedValue)
}
attributeWriters[key] = function (dbItem, dao) {
const storedValue = serializer(dao[key])
dao[storedValueKey] = storedValue
if (storedValue && storedValue !== defaultValue) {
dbItem[key] = storedValue
}
}
// Checkers are only for complex types
attributeCheckers[key] = function (dao) {
return serializer(dao[key]) !== dao[storedValueKey]
}
}
})
const lastTx = 0
const storedSeqs = Object.create(null)
function readDbItem(item, daoMap) {
const dao = daoMap[item.id] || new Dao(item.id, true)
if (!item.updated) {
delete storedSeqs[item.id]
if (dao.updated) {
delete daoMap[item.id]
return true
}
return
}
if (storedSeqs[item.id] === item.seq) {
return
}
storedSeqs[item.id] = item.seq
for (const i = 0; i < schemaKeysLen; i++) {
attributeReaders[schemaKeys[i]](item, dao)
}
dao.$dirty = false
dao.$dirtyUpdated = false
daoMap[item.id] = dao
return true
}
function getPatch(tx, cb) {
let resetMap;
// We may have missed some deleted markers
if (lastTx && tx.txCounter - lastTx > deletedMarkerMaxAge) {
// Delete all dirty daos, user was asleep anyway...
resetMap = true
// And retrieve everything from DB
lastTx = 0
}
const hasChanged = !lastTx
const store = tx.objectStore(storeName)
const index = store.index('seq')
const range = $window.IDBKeyRange.lowerBound(lastTx, true)
const items = []
const itemsToDelete = []
index.openCursor(range).onsuccess = function (event) {
const cursor = event.target.result
if (!cursor) {
itemsToDelete.cl_each(function (item) {
store.delete(item.id)
})
items.length && debug('Got ' + items.length + ' ' + storeName + ' items')
// Return a patch, to apply changes later
return cb(function (daoMap) {
if (resetMap) {
Object.keys(daoMap).cl_each(function (key) {
delete daoMap[key]
})
storedSeqs = Object.create(null)
}
items.cl_each(function (item) {
hasChanged |= readDbItem(item, daoMap)
})
return hasChanged
})
}
const item = cursor.value
items.push(item)
// Remove old deleted markers
if (!item.updated && tx.txCounter - item.seq > deletedMarkerMaxAge) {
itemsToDelete.push(item)
}
cursor.continue()
}
}
function writeAll(daoMap, tx) {
lastTx = tx.txCounter
const store = tx.objectStore(storeName)
// Remove deleted daos
const storedIds = Object.keys(storedSeqs)
const storedIdsLen = storedIds.length
for (const i = 0; i < storedIdsLen; i++) {
const id = storedIds[i]
if (!daoMap[id]) {
// Put a deleted marker to notify other tabs
store.put({
id: id,
seq: lastTx
})
delete storedSeqs[id]
}
}
// Put changes
const daoIds = Object.keys(daoMap)
const daoIdsLen = daoIds.length
for (i = 0; i < daoIdsLen; i++) {
const dao = daoMap[daoIds[i]]
const dirty = dao.$dirty
for (const j = 0; !dirty && j < complexKeysLen; j++) {
dirty |= attributeCheckers[complexKeys[j]](dao)
}
if (dirty) {
if (!dao.$dirtyUpdated) {
// Force update the `updated` attribute
dao.updated = Date.now()
}
const item = {
id: daoIds[i],
seq: lastTx
}
for (j = 0; j < schemaKeysLen; j++) {
attributeWriters[schemaKeys[j]](item, dao)
}
debug('Put ' + storeName + ' item')
store.put(item)
storedSeqs[item.id] = item.seq
dao.$dirty = false
dao.$dirtyUpdated = false
}
}
}
return {
getPatch,
writeAll,
createDao,
Dao,
};
}
class Connection {
constructor() {
this.getTxCbs = [];
// Init connexion
const request = indexedDB.open('classeur-db', dbVersion);
request.onerror = () => {
throw new Error("Can't connect to IndexedDB.");
};
request.onsuccess = (event) => {
this.db = event.target.result;
localStorage.localDbVersion = this.db.version; // Safari does not support onversionchange
this.db.onversionchange = () => window.location.reload();
this.getTxCbs.forEach(cb => this.createTx(cb));
this.getTxCbs = null;
};
request.onupgradeneeded = (event) => {
const eventDb = event.target.result;
const oldVersion = event.oldVersion || 0;
function createStore(name) {
const store = eventDb.createObjectStore(name, { keyPath: 'id' });
store.createIndex('seq', 'seq', { unique: false });
}
// We don't use 'break' in this switch statement,
// the fall-through behaviour is what we want.
/* eslint-disable no-fallthrough */
switch (oldVersion) {
case 0:
[
'contents',
'files',
'folders',
'objects',
'app',
].forEach(createStore);
default:
}
/* eslint-enable no-fallthrough */
};
}
createTx(cb) {
if (!this.db) {
this.getTxCbs.push(cb);
return;
}
// If DB version has changed (Safari support)
if (parseInt(localStorage.localDbVersion, 10) !== this.db.version) {
window.location.reload();
return;
}
const tx = this.db.transaction(this.db.objectStoreNames, 'readwrite');
// tx.onerror = (evt) => {
// dbg('Rollback transaction', evt);
// };
const store = tx.objectStore('app');
const request = store.get('txCounter');
request.onsuccess = () => {
tx.txCounter = request.result ? request.result.value : 0;
tx.txCounter += 1;
store.put({
id: 'txCounter',
value: tx.txCounter,
});
cb(tx);
};
}
}
class LocalDbStorage {
init(store) {
this.store = store;
store.subscribe((mutation, state) => {
console.log(mutation, state);
});
this.connection = new Connection();
}
}
export default LocalDbStorage;

View File

@ -4,11 +4,14 @@ import Vuex from 'vuex';
import files from './modules/files'; import files from './modules/files';
import layout from './modules/layout'; import layout from './modules/layout';
import editor from './modules/editor'; import editor from './modules/editor';
import LocalDbStorage from '../services/localDbSvc';
Vue.use(Vuex); Vue.use(Vuex);
const debug = process.env.NODE_ENV !== 'production'; const debug = process.env.NODE_ENV !== 'production';
const localDbStorage = new LocalDbStorage();
const store = new Vuex.Store({ const store = new Vuex.Store({
modules: { modules: {
files, files,
@ -16,7 +19,7 @@ const store = new Vuex.Store({
editor, editor,
}, },
strict: debug, strict: debug,
plugins: debug ? [createLogger()] : [], plugins: [_store => localDbStorage.init(_store)].concat(debug ? [createLogger()] : []),
}); });
export default store; export default store;

View File

@ -115,6 +115,10 @@ argparse@^1.0.7:
dependencies: dependencies:
sprintf-js "~1.0.2" sprintf-js "~1.0.2"
argsarray@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/argsarray/-/argsarray-0.0.1.tgz#6e7207b4ecdb39b0af88303fa5ae22bda8df61cb"
arr-diff@^2.0.0: arr-diff@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf"
@ -692,6 +696,14 @@ babel-plugin-transform-strict-mode@^6.24.1:
babel-runtime "^6.22.0" babel-runtime "^6.22.0"
babel-types "^6.24.1" babel-types "^6.24.1"
babel-polyfill@6.23.0, babel-polyfill@^6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d"
dependencies:
babel-runtime "^6.22.0"
core-js "^2.4.0"
regenerator-runtime "^0.10.0"
babel-preset-env@^1.3.2: babel-preset-env@^1.3.2:
version "1.5.1" version "1.5.1"
resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.5.1.tgz#d2eca6af179edf27cdc305a84820f601b456dd0b" resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.5.1.tgz#d2eca6af179edf27cdc305a84820f601b456dd0b"
@ -1587,7 +1599,7 @@ debug@2.6.7:
dependencies: dependencies:
ms "2.0.0" ms "2.0.0"
debug@^2.1.1, debug@^2.2.0, debug@^2.6.0: debug@^2.1.1, debug@^2.2.0, debug@^2.6.0, debug@^2.6.8:
version "2.6.8" version "2.6.8"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
dependencies: dependencies:
@ -2933,6 +2945,10 @@ ignore@^3.2.0:
version "3.3.3" version "3.3.3"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d"
immediate@^3.2.2:
version "3.2.3"
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c"
imurmurhash@^0.1.4: imurmurhash@^0.1.4:
version "0.1.4" version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
@ -2947,6 +2963,13 @@ indent-string@^2.1.0:
dependencies: dependencies:
repeating "^2.0.0" repeating "^2.0.0"
indexeddbshim@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/indexeddbshim/-/indexeddbshim-3.0.4.tgz#b4d9a4fb3fce7532b66e19790a15692f9b2c7b56"
dependencies:
babel-polyfill "6.23.0"
websql "https://github.com/brettz9/node-websql#configurable"
indexes-of@^1.0.1: indexes-of@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607"
@ -3701,10 +3724,6 @@ markdown-it-footnote@^3.0.1:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/markdown-it-footnote/-/markdown-it-footnote-3.0.1.tgz#7f3730747cacc86e2fe0bf8a17a710f34791517a" resolved "https://registry.yarnpkg.com/markdown-it-footnote/-/markdown-it-footnote-3.0.1.tgz#7f3730747cacc86e2fe0bf8a17a710f34791517a"
markdown-it-mathjax@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/markdown-it-mathjax/-/markdown-it-mathjax-2.0.0.tgz#ae2b4f4c5c719a03f9e475c664f7b2685231d9e9"
markdown-it-pandoc-renderer@1.1.3: markdown-it-pandoc-renderer@1.1.3:
version "1.1.3" version "1.1.3"
resolved "https://registry.yarnpkg.com/markdown-it-pandoc-renderer/-/markdown-it-pandoc-renderer-1.1.3.tgz#77f1a5b488c5460ab1e1dcbcfcc07d12674f7a3a" resolved "https://registry.yarnpkg.com/markdown-it-pandoc-renderer/-/markdown-it-pandoc-renderer-1.1.3.tgz#77f1a5b488c5460ab1e1dcbcfcc07d12674f7a3a"
@ -3903,6 +3922,10 @@ nan@^2.3.0, nan@^2.3.2:
version "2.6.2" version "2.6.2"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45" resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45"
nan@~2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.4.0.tgz#fb3c59d45fe4effe215f0b890f8adf6eb32d2232"
natives@^1.1.0: natives@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.0.tgz#e9ff841418a6b2ec7a495e939984f78f163e6e31" resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.0.tgz#e9ff841418a6b2ec7a495e939984f78f163e6e31"
@ -4007,7 +4030,7 @@ node-libs-browser@^2.0.0:
util "^0.10.3" util "^0.10.3"
vm-browserify "0.0.4" vm-browserify "0.0.4"
node-pre-gyp@^0.6.29: node-pre-gyp@^0.6.29, node-pre-gyp@~0.6.31:
version "0.6.36" version "0.6.36"
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz#db604112cb74e0d477554e9b505b17abddfab786" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz#db604112cb74e0d477554e9b505b17abddfab786"
dependencies: dependencies:
@ -4044,6 +4067,10 @@ node-sass@^4.5.3:
sass-graph "^2.1.1" sass-graph "^2.1.1"
stdout-stream "^1.4.0" stdout-stream "^1.4.0"
noop-fn@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/noop-fn/-/noop-fn-1.0.0.tgz#5f33d47f13d2150df93e0cb036699e982f78ffbf"
"nopt@2 || 3", nopt@~3.0.1: "nopt@2 || 3", nopt@~3.0.1:
version "3.0.6" version "3.0.6"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
@ -4735,6 +4762,10 @@ postcss@^6.0.1:
source-map "^0.5.6" source-map "^0.5.6"
supports-color "^3.2.3" supports-color "^3.2.3"
pouchdb-collections@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/pouchdb-collections/-/pouchdb-collections-1.0.1.tgz#fe63a17da977611abef7cb8026cb1a9553fd8359"
prelude-ls@~1.1.2: prelude-ls@~1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
@ -5401,6 +5432,13 @@ sprintf-js@~1.0.2:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
sqlite3@^3.1.3:
version "3.1.8"
resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-3.1.8.tgz#4cbcf965d8b901d1b1015cbc7fc415aae157dfaa"
dependencies:
nan "~2.4.0"
node-pre-gyp "~0.6.31"
sshpk@^1.7.0: sshpk@^1.7.0:
version "1.13.0" version "1.13.0"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.0.tgz#ff2a3e4fd04497555fed97b39a0fd82fafb3a33c" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.0.tgz#ff2a3e4fd04497555fed97b39a0fd82fafb3a33c"
@ -5756,6 +5794,10 @@ tiny-emitter@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.0.0.tgz#bad327adb1804b42a231afa741532bd884cd09ad" resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.0.0.tgz#bad327adb1804b42a231afa741532bd884cd09ad"
tiny-queue@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/tiny-queue/-/tiny-queue-0.2.1.tgz#25a67f2c6e253b2ca941977b5ef7442ef97a6046"
to-arraybuffer@^1.0.0: to-arraybuffer@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
@ -6141,6 +6183,17 @@ webpack@^2.6.1:
webpack-sources "^0.2.3" webpack-sources "^0.2.3"
yargs "^6.0.0" yargs "^6.0.0"
"websql@https://github.com/brettz9/node-websql#configurable":
version "0.4.4"
resolved "https://github.com/brettz9/node-websql#c9828a34c92eced64858fc19151ec099fd60e8dd"
dependencies:
argsarray "^0.0.1"
immediate "^3.2.2"
noop-fn "^1.0.0"
pouchdb-collections "^1.0.1"
sqlite3 "^3.1.3"
tiny-queue "^0.2.1"
whet.extend@~0.9.9: whet.extend@~0.9.9:
version "0.9.9" version "0.9.9"
resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1"