mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-01-07 20:42:44 +00:00
Initial IDB functionality pass
This commit is contained in:
@@ -70,7 +70,7 @@ const Snippetbar = createClass({
|
|||||||
|
|
||||||
if(historyExists(this.props.brew) != this.state.historyExists){
|
if(historyExists(this.props.brew) != this.state.historyExists){
|
||||||
this.setState({
|
this.setState({
|
||||||
historyExists : !this.state.historyExists
|
historyExists : !this.state.historyExists
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
80
client/homebrew/utils/useIDB.js
Normal file
80
client/homebrew/utils/useIDB.js
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
import {
|
||||||
|
get as iGet,
|
||||||
|
getMany as iGetMany,
|
||||||
|
set as iSet,
|
||||||
|
setMany as iSetMany,
|
||||||
|
update as iUpdate,
|
||||||
|
del as iDel,
|
||||||
|
keys,
|
||||||
|
createStore,
|
||||||
|
Store
|
||||||
|
} from 'idb-keyval/dist/index.js'; // EcmaScript Module
|
||||||
|
|
||||||
|
const HOMEBREWERY_DB = 'HOMEBREWERY-DB';
|
||||||
|
const HOMEBREWERY_STORE = 'HOMEBREWERY-STORE';
|
||||||
|
|
||||||
|
let hbStore;
|
||||||
|
|
||||||
|
function init(){
|
||||||
|
if(hbStore) return true;
|
||||||
|
if(!hbStore && typeof window != 'undefined' && typeof window.indexedDB != 'undefined'){
|
||||||
|
hbStore = createStore(HOMEBREWERY_DB, HOMEBREWERY_STORE);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkFn(fn){
|
||||||
|
return init() && fn();
|
||||||
|
};
|
||||||
|
|
||||||
|
const get = checkFn(async (key)=>{
|
||||||
|
console.log('get:', key);
|
||||||
|
return iGet(key, hbStore);
|
||||||
|
});
|
||||||
|
|
||||||
|
const getMany = checkFn(async (keys)=>{
|
||||||
|
checkFn(async ()=>{
|
||||||
|
console.log('getMany:', keys);
|
||||||
|
return await iGetMany(keys, hbStore);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const set = checkFn(async (key, val)=>{
|
||||||
|
console.log('set:', key, val);
|
||||||
|
init();
|
||||||
|
return iSet(key, val, hbStore);
|
||||||
|
});
|
||||||
|
|
||||||
|
const setMany = checkFn(async (keyValArray)=>{
|
||||||
|
console.log('set:', keyValArray);
|
||||||
|
init();
|
||||||
|
return iSetMany(keyValArray, hbStore);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const update = checkFn(async (key, updateFn)=>{
|
||||||
|
init();
|
||||||
|
return iUpdate(key, updateFn, hbStore);
|
||||||
|
});
|
||||||
|
|
||||||
|
const remove = checkFn(async (key)=>{
|
||||||
|
console.log('remove:', key);
|
||||||
|
init();
|
||||||
|
return iDel(key, hbStore);
|
||||||
|
});
|
||||||
|
|
||||||
|
const list = checkFn(async ()=>{
|
||||||
|
init();
|
||||||
|
return await keys(hbStore);
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
get,
|
||||||
|
getMany,
|
||||||
|
set,
|
||||||
|
setMany,
|
||||||
|
update,
|
||||||
|
remove,
|
||||||
|
list
|
||||||
|
};
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import * as IDB from 'idb-keyval/dist/index.js';
|
||||||
|
|
||||||
export const HISTORY_PREFIX = 'HOMEBREWERY-HISTORY';
|
export const HISTORY_PREFIX = 'HOMEBREWERY-HISTORY';
|
||||||
export const HISTORY_SLOTS = 5;
|
export const HISTORY_SLOTS = 5;
|
||||||
|
|
||||||
@@ -27,12 +29,12 @@ function getVersionBySlot(brew, slot){
|
|||||||
// - If it exists, parse data to object
|
// - If it exists, parse data to object
|
||||||
// - If it doesn't exist, pass default object
|
// - If it doesn't exist, pass default object
|
||||||
const key = getKeyBySlot(brew, slot);
|
const key = getKeyBySlot(brew, slot);
|
||||||
const storedVersion = localStorage.getItem(key);
|
const storedVersion = IDB.get(key);
|
||||||
const output = storedVersion ? JSON.parse(storedVersion) : { expireAt: '2000-01-01T00:00:00.000Z', shareId: brew.shareId, noData: true };
|
const output = storedVersion ? storedVersion : { expireAt: '2000-01-01T00:00:00.000Z', shareId: brew.shareId, noData: true };
|
||||||
return output;
|
return output;
|
||||||
};
|
};
|
||||||
|
|
||||||
function updateStoredBrew(brew, slot = 0) {
|
function parseBrewForStorage(brew, slot = 0) {
|
||||||
const archiveBrew = {
|
const archiveBrew = {
|
||||||
title : brew.title,
|
title : brew.title,
|
||||||
text : brew.text,
|
text : brew.text,
|
||||||
@@ -46,44 +48,77 @@ function updateStoredBrew(brew, slot = 0) {
|
|||||||
archiveBrew.expireAt.setMinutes(archiveBrew.expireAt.getMinutes() + HISTORY_SAVE_DELAYS[slot]);
|
archiveBrew.expireAt.setMinutes(archiveBrew.expireAt.getMinutes() + HISTORY_SAVE_DELAYS[slot]);
|
||||||
|
|
||||||
const key = getKeyBySlot(brew, slot);
|
const key = getKeyBySlot(brew, slot);
|
||||||
localStorage.setItem(key, JSON.stringify(archiveBrew));
|
|
||||||
|
return [key, archiveBrew];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function historyExists(brew){
|
export async function historyExists(brew){
|
||||||
return Object.keys(localStorage)
|
console.log('HISTORY CHECK');
|
||||||
.some((key)=>{
|
const historyExists = await IDB.keys()
|
||||||
return key.startsWith(`${HISTORY_PREFIX}-${brew.shareId}`);
|
.then((keys)=>{
|
||||||
});
|
return [...keys].some((key)=>{
|
||||||
|
return key.startsWith(`${HISTORY_PREFIX}-${brew.shareId}`);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(()=>{return false;});
|
||||||
|
console.log('HISTORY STATE:', historyExists);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loadHistory(brew){
|
export async function loadHistory(brew){
|
||||||
const history = {};
|
const DEFAULT_HISTORY_ITEM = { expireAt: '2000-01-01T00:00:00.000Z', shareId: brew.shareId, noData: true };
|
||||||
|
|
||||||
|
const historyKeys = [];
|
||||||
|
|
||||||
// Load data from local storage to History object
|
// Load data from local storage to History object
|
||||||
for (let i = 1; i <= HISTORY_SLOTS; i++){
|
for (let i = 1; i <= HISTORY_SLOTS; i++){
|
||||||
history[i] = getVersionBySlot(brew, i);
|
historyKeys.push(getKeyBySlot(brew, i));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const history = [];
|
||||||
|
await IDB.getMany(historyKeys)
|
||||||
|
.then((dataArray)=>{
|
||||||
|
return dataArray.forEach((data)=>{
|
||||||
|
history.push(data ?? DEFAULT_HISTORY_ITEM);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(()=>{
|
||||||
|
historyKeys.forEach(()=>{
|
||||||
|
history.push(DEFAULT_HISTORY_ITEM);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return history;
|
return history;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateHistory(brew) {
|
export async function updateHistory(brew) {
|
||||||
const history = loadHistory(brew);
|
const history = await loadHistory(brew);
|
||||||
|
|
||||||
|
console.log('DATA:', history);
|
||||||
|
|
||||||
// Walk each version position
|
// Walk each version position
|
||||||
for (let slot = HISTORY_SLOTS; slot > 0; slot--){
|
for (let slot = HISTORY_SLOTS - 1; slot >= 0; slot--){
|
||||||
|
console.log('SLOT #:', slot, history[slot]);
|
||||||
const storedVersion = history[slot];
|
const storedVersion = history[slot];
|
||||||
|
|
||||||
// If slot has expired, update all lower slots and break
|
// If slot has expired, update all lower slots and break
|
||||||
if(new Date() >= new Date(storedVersion.expireAt)){
|
if(new Date() >= new Date(storedVersion.expireAt)){
|
||||||
for (let updateSlot = slot - 1; updateSlot>0; updateSlot--){
|
const historyUpdate = [];
|
||||||
|
|
||||||
|
for (let updateSlot = slot - 1; updateSlot > 0; updateSlot--){
|
||||||
|
console.log('CHECK DATA IN SLOT #:', updateSlot);
|
||||||
// Move data from updateSlot to updateSlot + 1
|
// Move data from updateSlot to updateSlot + 1
|
||||||
!history[updateSlot]?.noData && updateStoredBrew(history[updateSlot], updateSlot + 1);
|
if(!history[updateSlot - 1]?.noData) {
|
||||||
|
console.log('UPDATE SLOT #:', updateSlot - 1, '>', updateSlot);
|
||||||
|
historyUpdate.push(parseBrewForStorage(history[updateSlot - 1], updateSlot + 1));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Update the most recent brew
|
// Update the most recent brew
|
||||||
updateStoredBrew(brew, 1);
|
historyUpdate.push(parseBrewForStorage(brew, 1));
|
||||||
|
|
||||||
|
console.log('HISTORY UPDATE OBJECT:', historyUpdate);
|
||||||
|
IDB.setMany(historyUpdate);
|
||||||
|
|
||||||
// Break out of data checks because we found an expired value
|
// Break out of data checks because we found an expired value
|
||||||
break;
|
break;
|
||||||
@@ -102,15 +137,16 @@ export function getHistoryItems(brew){
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function versionHistoryGarbageCollection(){
|
export function versionHistoryGarbageCollection(){
|
||||||
Object.keys(localStorage)
|
console.log('Version History Garbage Collection');
|
||||||
.filter((key)=>{
|
// Object.keys(IDB)
|
||||||
return key.startsWith(HISTORY_PREFIX);
|
// .filter((key)=>{
|
||||||
})
|
// return key.startsWith(HISTORY_PREFIX);
|
||||||
.forEach((key)=>{
|
// })
|
||||||
const collectAt = new Date(JSON.parse(localStorage.getItem(key)).savedAt);
|
// .forEach((key)=>{
|
||||||
collectAt.setMinutes(collectAt.getMinutes() + GARBAGE_COLLECT_DELAY);
|
// const collectAt = new Date(JSON.parse(IDB.get(key)).savedAt);
|
||||||
if(new Date() > collectAt){
|
// collectAt.setMinutes(collectAt.getMinutes() + GARBAGE_COLLECT_DELAY);
|
||||||
localStorage.removeItem(key);
|
// if(new Date() > collectAt){
|
||||||
}
|
// IDB.removeItem(key);
|
||||||
});
|
// }
|
||||||
|
// });
|
||||||
};
|
};
|
||||||
6
package-lock.json
generated
6
package-lock.json
generated
@@ -27,6 +27,7 @@
|
|||||||
"express-async-handler": "^1.2.0",
|
"express-async-handler": "^1.2.0",
|
||||||
"express-static-gzip": "2.1.8",
|
"express-static-gzip": "2.1.8",
|
||||||
"fs-extra": "11.2.0",
|
"fs-extra": "11.2.0",
|
||||||
|
"idb-keyval": "^6.2.1",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"jwt-simple": "^0.5.6",
|
"jwt-simple": "^0.5.6",
|
||||||
"less": "^3.13.1",
|
"less": "^3.13.1",
|
||||||
@@ -7451,6 +7452,11 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/idb-keyval": {
|
||||||
|
"version": "6.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.1.tgz",
|
||||||
|
"integrity": "sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg=="
|
||||||
|
},
|
||||||
"node_modules/ieee754": {
|
"node_modules/ieee754": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||||
|
|||||||
@@ -102,6 +102,7 @@
|
|||||||
"express-async-handler": "^1.2.0",
|
"express-async-handler": "^1.2.0",
|
||||||
"express-static-gzip": "2.1.8",
|
"express-static-gzip": "2.1.8",
|
||||||
"fs-extra": "11.2.0",
|
"fs-extra": "11.2.0",
|
||||||
|
"idb-keyval": "^6.2.1",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"jwt-simple": "^0.5.6",
|
"jwt-simple": "^0.5.6",
|
||||||
"less": "^3.13.1",
|
"less": "^3.13.1",
|
||||||
|
|||||||
Reference in New Issue
Block a user