2021-11-14 12:24:33 +00:00
import localforage from "localforage" ;
2024-05-17 14:59:34 +00:00
import { extendPrototype as ep1 } from "localforage-getitems" ;
import { extendPrototype as ep2 } from "localforage-removeitems" ;
ep1 ( localforage ) ;
ep2 ( localforage ) ;
2022-04-05 16:24:27 +00:00
export type LocalForage = typeof localforage ;
import { nanoid } from "nanoid" ;
2021-10-23 04:02:03 +00:00
2024-05-07 16:20:15 +00:00
import type { Entity , SUPPORTED_SERVICES_TYPE } from "./baseTypes" ;
2024-04-26 18:27:24 +00:00
import { unixTimeToStr } from "./misc" ;
2024-05-07 16:20:15 +00:00
import type { SyncPlanType } from "./sync" ;
2021-10-24 16:41:13 +00:00
2024-02-24 00:21:05 +00:00
const DB_VERSION_NUMBER_IN_HISTORY = [ 20211114 , 20220108 , 20220326 , 20240220 ] ;
export const DEFAULT_DB_VERSION_NUMBER : number = 20240220 ;
2021-11-14 14:34:07 +00:00
export const DEFAULT_DB_NAME = "remotelysavedb" ;
2021-11-14 12:24:33 +00:00
export const DEFAULT_TBL_VERSION = "schemaversion" ;
2021-11-07 05:58:51 +00:00
export const DEFAULT_SYNC_PLANS_HISTORY = "syncplanshistory" ;
2022-03-26 16:52:10 +00:00
export const DEFAULT_TBL_VAULT_RANDOM_ID_MAPPING = "vaultrandomidmapping" ;
2022-04-05 16:24:27 +00:00
export const DEFAULT_TBL_LOGGER_OUTPUT = "loggeroutput" ;
2024-01-05 16:03:53 +00:00
export const DEFAULT_TBL_SIMPLE_KV_FOR_MISC = "simplekvformisc" ;
2024-02-24 00:21:05 +00:00
export const DEFAULT_TBL_PREV_SYNC_RECORDS = "prevsyncrecords" ;
2024-04-04 13:52:01 +00:00
export const DEFAULT_TBL_PROFILER_RESULTS = "profilerresults" ;
2021-10-23 04:02:03 +00:00
2024-02-24 00:21:05 +00:00
/ * *
* @deprecated
* /
export const DEFAULT_TBL_FILE_HISTORY = "filefolderoperationhistory" ;
/ * *
* @deprecated
* /
export const DEFAULT_TBL_SYNC_MAPPING = "syncmetadatahistory" ;
2021-10-23 04:02:03 +00:00
2024-02-24 00:21:05 +00:00
/ * *
* @deprecated
* But we cannot remove it . Because we want to migrate the old data .
* /
2021-11-14 12:24:33 +00:00
interface SyncMetaMappingRecord {
localKey : string ;
remoteKey : string ;
localSize : number ;
remoteSize : number ;
localMtime : number ;
remoteMtime : number ;
remoteExtraKey : string ;
remoteType : SUPPORTED_SERVICES_TYPE ;
keyType : "folder" | "file" ;
2022-01-08 10:41:11 +00:00
vaultRandomID : string ;
2021-10-24 16:41:13 +00:00
}
2021-11-07 05:58:51 +00:00
interface SyncPlanRecord {
ts : number ;
2021-11-14 12:24:33 +00:00
remoteType : string ;
syncPlan : string ;
2022-01-08 10:41:11 +00:00
vaultRandomID : string ;
2021-11-07 05:58:51 +00:00
}
2021-11-14 12:24:33 +00:00
export interface InternalDBs {
versionTbl : LocalForage ;
syncPlansTbl : LocalForage ;
2022-03-26 16:52:10 +00:00
vaultRandomIDMappingTbl : LocalForage ;
2022-04-05 16:24:27 +00:00
loggerOutputTbl : LocalForage ;
2024-01-05 16:03:53 +00:00
simpleKVForMiscTbl : LocalForage ;
2024-02-24 00:21:05 +00:00
prevSyncRecordsTbl : LocalForage ;
2024-04-04 13:52:01 +00:00
profilerResultsTbl : LocalForage ;
2024-02-24 00:21:05 +00:00
/ * *
* @deprecated
* But we cannot remove it . Because we want to migrate the old data .
* /
fileHistoryTbl : LocalForage ;
/ * *
* @deprecated
* But we cannot remove it . Because we want to migrate the old data .
* /
syncMappingTbl : LocalForage ;
2021-11-14 12:24:33 +00:00
}
2021-10-24 16:41:13 +00:00
2022-01-08 10:41:11 +00:00
/ * *
2024-02-24 00:21:05 +00:00
* TODO
* @param syncMappings
* @returns
* /
const fromSyncMappingsToPrevSyncRecords = (
2024-02-25 15:21:42 +00:00
oldSyncMappings : SyncMetaMappingRecord [ ]
2024-02-24 00:21:05 +00:00
) : Entity [ ] = > {
2024-02-25 15:21:42 +00:00
const res : Entity [ ] = [ ] ;
for ( const oldMapping of oldSyncMappings ) {
const newEntity : Entity = {
key : oldMapping.localKey ,
keyEnc : oldMapping.remoteKey ,
keyRaw :
oldMapping . remoteKey !== undefined && oldMapping . remoteKey !== ""
? oldMapping . remoteKey
: oldMapping . localKey ,
mtimeCli : oldMapping.localMtime ,
mtimeSvr : oldMapping.remoteMtime ,
size : oldMapping.localSize ,
sizeEnc : oldMapping.remoteSize ,
sizeRaw :
oldMapping . remoteKey !== undefined && oldMapping . remoteKey !== ""
? oldMapping . remoteSize
: oldMapping . localSize ,
etag : oldMapping.remoteExtraKey ,
} ;
res . push ( newEntity ) ;
}
return res ;
2024-02-24 00:21:05 +00:00
} ;
2022-03-26 07:06:34 +00:00
/ * *
2024-02-24 00:21:05 +00:00
*
2022-03-26 07:06:34 +00:00
* @param db
* @param vaultRandomID
2024-02-24 00:21:05 +00:00
* Migrate the sync mapping record to sync Entity .
2022-03-26 07:06:34 +00:00
* /
2024-02-24 00:21:05 +00:00
const migrateDBsFrom20220326To20240220 = async (
2022-03-26 07:06:34 +00:00
db : InternalDBs ,
2024-03-17 08:35:02 +00:00
vaultRandomID : string ,
profileID : string
2022-03-26 07:06:34 +00:00
) = > {
2024-02-24 00:21:05 +00:00
const oldVer = 20220326 ;
const newVer = 20240220 ;
2024-03-17 08:03:40 +00:00
console . debug ( ` start upgrading internal db from ${ oldVer } to ${ newVer } ` ) ;
2024-02-24 00:21:05 +00:00
// from sync mapping to prev sync
const syncMappings = await getAllSyncMetaMappingByVault ( db , vaultRandomID ) ;
const prevSyncRecords = fromSyncMappingsToPrevSyncRecords ( syncMappings ) ;
for ( const prevSyncRecord of prevSyncRecords ) {
2024-03-17 08:35:02 +00:00
await upsertPrevSyncRecordByVaultAndProfile (
db ,
vaultRandomID ,
profileID ,
prevSyncRecord
) ;
2024-02-24 00:21:05 +00:00
}
2024-02-25 15:21:42 +00:00
// // clear not used data
// // as of 20240220, we don't call them,
// // for the opportunity for users to downgrade
// await clearFileHistoryOfEverythingByVault(db, vaultRandomID);
// await clearAllSyncMetaMappingByVault(db, vaultRandomID);
2024-02-24 00:21:05 +00:00
await db . versionTbl . setItem ( ` ${ vaultRandomID } \ tversion ` , newVer ) ;
2024-03-17 08:03:40 +00:00
console . debug ( ` finish upgrading internal db from ${ oldVer } to ${ newVer } ` ) ;
2022-03-26 07:06:34 +00:00
} ;
2022-01-08 10:41:11 +00:00
const migrateDBs = async (
db : InternalDBs ,
oldVer : number ,
newVer : number ,
2024-03-17 08:35:02 +00:00
vaultRandomID : string ,
profileID : string
2022-01-08 10:41:11 +00:00
) = > {
if ( oldVer === newVer ) {
return ;
}
2024-02-24 00:21:05 +00:00
// as of 20240220, we assume everyone is using 20220326 already
// drop any old code to reduce the verbose
if ( oldVer < 20220326 ) {
throw Error (
"You are using a very old version of Remotely Save. No way to auto update internal DB. Please install and enable 0.3.40 firstly, then install a later version."
) ;
2022-03-26 07:06:34 +00:00
}
2024-02-24 00:21:05 +00:00
if ( oldVer === 20220326 && newVer === 20240220 ) {
2024-03-17 08:35:02 +00:00
return await migrateDBsFrom20220326To20240220 ( db , vaultRandomID , profileID ) ;
2022-03-26 07:06:34 +00:00
}
2024-02-24 00:21:05 +00:00
2022-03-26 07:06:34 +00:00
if ( newVer < oldVer ) {
throw Error (
"You've installed a new version, but then downgrade to an old version. Stop working!"
) ;
}
2022-01-08 10:41:11 +00:00
// not implemented
throw Error ( ` not supported internal db changes from ${ oldVer } to ${ newVer } ` ) ;
} ;
2022-03-26 16:52:10 +00:00
export const prepareDBs = async (
vaultBasePath : string ,
2024-03-17 08:35:02 +00:00
vaultRandomIDFromOldConfigFile : string ,
profileID : string
2022-03-26 16:52:10 +00:00
) = > {
2021-11-14 12:24:33 +00:00
const db = {
versionTbl : localforage.createInstance ( {
name : DEFAULT_DB_NAME ,
storeName : DEFAULT_TBL_VERSION ,
} ) ,
syncPlansTbl : localforage.createInstance ( {
name : DEFAULT_DB_NAME ,
storeName : DEFAULT_SYNC_PLANS_HISTORY ,
} ) ,
2022-03-26 16:52:10 +00:00
vaultRandomIDMappingTbl : localforage.createInstance ( {
name : DEFAULT_DB_NAME ,
storeName : DEFAULT_TBL_VAULT_RANDOM_ID_MAPPING ,
} ) ,
2022-04-05 16:24:27 +00:00
loggerOutputTbl : localforage.createInstance ( {
name : DEFAULT_DB_NAME ,
storeName : DEFAULT_TBL_LOGGER_OUTPUT ,
} ) ,
2024-01-05 16:03:53 +00:00
simpleKVForMiscTbl : localforage.createInstance ( {
name : DEFAULT_DB_NAME ,
storeName : DEFAULT_TBL_SIMPLE_KV_FOR_MISC ,
} ) ,
2024-02-24 00:21:05 +00:00
prevSyncRecordsTbl : localforage.createInstance ( {
name : DEFAULT_DB_NAME ,
storeName : DEFAULT_TBL_PREV_SYNC_RECORDS ,
} ) ,
2024-04-04 13:52:01 +00:00
profilerResultsTbl : localforage.createInstance ( {
name : DEFAULT_DB_NAME ,
storeName : DEFAULT_TBL_PROFILER_RESULTS ,
} ) ,
2024-02-24 00:21:05 +00:00
fileHistoryTbl : localforage.createInstance ( {
name : DEFAULT_DB_NAME ,
storeName : DEFAULT_TBL_FILE_HISTORY ,
} ) ,
syncMappingTbl : localforage.createInstance ( {
name : DEFAULT_DB_NAME ,
storeName : DEFAULT_TBL_SYNC_MAPPING ,
} ) ,
2021-11-14 12:24:33 +00:00
} as InternalDBs ;
2021-10-24 16:41:13 +00:00
2022-03-26 16:52:10 +00:00
// try to get vaultRandomID firstly
let vaultRandomID = "" ;
const vaultRandomIDInDB : string | null =
await db . vaultRandomIDMappingTbl . getItem ( ` path2id \ t ${ vaultBasePath } ` ) ;
if ( vaultRandomIDInDB === null ) {
if ( vaultRandomIDFromOldConfigFile !== "" ) {
// reuse the old config id
vaultRandomID = vaultRandomIDFromOldConfigFile ;
} else {
// no old config id, we create a random one
vaultRandomID = nanoid ( ) ;
}
// save the id back
await db . vaultRandomIDMappingTbl . setItem (
` path2id \ t ${ vaultBasePath } ` ,
vaultRandomID
) ;
await db . vaultRandomIDMappingTbl . setItem (
` id2path \ t ${ vaultRandomID } ` ,
vaultBasePath
) ;
} else {
vaultRandomID = vaultRandomIDInDB ;
}
if ( vaultRandomID === "" ) {
throw Error ( "no vaultRandomID found or generated" ) ;
}
2024-02-24 00:21:05 +00:00
// as of 20240220, we set the version per vault, instead of global "version"
const originalVersion : number | null =
( await db . versionTbl . getItem ( ` ${ vaultRandomID } \ tversion ` ) ) ? ?
( await db . versionTbl . getItem ( "version" ) ) ;
2021-11-14 12:24:33 +00:00
if ( originalVersion === null ) {
2024-03-17 08:03:40 +00:00
console . debug (
2022-01-08 10:41:11 +00:00
` no internal db version, setting it to ${ DEFAULT_DB_VERSION_NUMBER } `
) ;
2024-02-24 00:21:05 +00:00
// as of 20240220, we set the version per vault, instead of global "version"
await db . versionTbl . setItem (
` ${ vaultRandomID } \ tversion ` ,
DEFAULT_DB_VERSION_NUMBER
) ;
2021-11-14 12:24:33 +00:00
} else if ( originalVersion === DEFAULT_DB_VERSION_NUMBER ) {
// do nothing
} else {
2024-03-17 08:03:40 +00:00
console . debug (
2022-01-08 10:41:11 +00:00
` trying to upgrade db version from ${ originalVersion } to ${ DEFAULT_DB_VERSION_NUMBER } `
) ;
await migrateDBs (
db ,
originalVersion ,
DEFAULT_DB_VERSION_NUMBER ,
2024-03-17 08:35:02 +00:00
vaultRandomID ,
profileID
2022-01-08 10:41:11 +00:00
) ;
2021-11-14 12:24:33 +00:00
}
2021-11-07 05:58:51 +00:00
2024-03-17 08:03:40 +00:00
console . info ( "db connected" ) ;
2022-03-26 16:52:10 +00:00
return {
db : db ,
vaultRandomID : vaultRandomID ,
} ;
2021-10-24 12:38:04 +00:00
} ;
2021-10-23 04:02:03 +00:00
2021-11-14 12:24:33 +00:00
export const destroyDBs = async ( ) = > {
2021-11-14 12:51:29 +00:00
// await localforage.dropInstance({
// name: DEFAULT_DB_NAME,
// });
2024-03-17 08:03:40 +00:00
// console.info("db deleted");
2021-11-14 12:51:29 +00:00
const req = indexedDB . deleteDatabase ( DEFAULT_DB_NAME ) ;
req . onsuccess = ( event ) = > {
2024-03-17 08:03:40 +00:00
console . info ( "db deleted" ) ;
2021-11-14 12:51:29 +00:00
} ;
req . onblocked = ( event ) = > {
2024-03-17 08:03:40 +00:00
console . warn ( "trying to delete db but it was blocked" ) ;
2021-11-14 12:51:29 +00:00
} ;
req . onerror = ( event ) = > {
2024-03-17 08:03:40 +00:00
console . error ( "tried to delete db but something goes wrong!" ) ;
console . error ( event ) ;
2021-11-14 12:51:29 +00:00
} ;
2021-10-24 12:38:04 +00:00
} ;
2024-02-24 00:21:05 +00:00
export const clearFileHistoryOfEverythingByVault = async (
2022-01-08 10:41:11 +00:00
db : InternalDBs ,
vaultRandomID : string
) = > {
2024-05-17 14:59:34 +00:00
const keys = ( await db . fileHistoryTbl . keys ( ) ) . filter ( ( x ) = >
x . startsWith ( ` ${ vaultRandomID } \ t ` )
) ;
await db . fileHistoryTbl . removeItems ( keys ) ;
// for (const key of keys) {
// if (key.startsWith(`${vaultRandomID}\t`)) {
// await db.fileHistoryTbl.removeItem(key);
// }
// }
2021-10-24 12:38:04 +00:00
} ;
2022-03-26 07:06:34 +00:00
/ * *
2024-02-24 00:21:05 +00:00
* @deprecated But we cannot remove it . Because we want to migrate the old data .
2022-03-26 07:06:34 +00:00
* @param db
* @param vaultRandomID
2024-02-24 00:21:05 +00:00
* @returns
2022-03-26 07:06:34 +00:00
* /
2024-02-24 00:21:05 +00:00
export const getAllSyncMetaMappingByVault = async (
2021-11-14 12:24:33 +00:00
db : InternalDBs ,
2022-01-08 10:41:11 +00:00
vaultRandomID : string
2021-10-24 16:41:13 +00:00
) = > {
2024-02-24 00:21:05 +00:00
return await Promise . all (
( ( await db . syncMappingTbl . keys ( ) ) ? ? [ ] )
. filter ( ( key ) = > key . startsWith ( ` ${ vaultRandomID } \ t ` ) )
. map (
async ( key ) = >
( await db . syncMappingTbl . getItem ( key ) ) as SyncMetaMappingRecord
)
2022-01-08 10:41:11 +00:00
) ;
2021-10-24 16:41:13 +00:00
} ;
2024-02-24 00:21:05 +00:00
export const clearAllSyncMetaMappingByVault = async (
2021-11-14 12:24:33 +00:00
db : InternalDBs ,
2022-01-08 10:41:11 +00:00
vaultRandomID : string
2021-10-24 16:41:13 +00:00
) = > {
2024-05-17 14:59:34 +00:00
const keys = ( await db . syncMappingTbl . keys ( ) ) . filter ( ( x ) = >
x . startsWith ( ` ${ vaultRandomID } \ t ` )
) ;
await db . syncMappingTbl . removeItems ( keys ) ;
// for (const key of keys) {
// if (key.startsWith(`${vaultRandomID}\t`)) {
// await db.syncMappingTbl.removeItem(key);
// }
// }
2021-10-24 16:41:13 +00:00
} ;
2021-11-07 05:58:51 +00:00
2022-01-08 10:41:11 +00:00
export const insertSyncPlanRecordByVault = async (
2021-11-14 12:24:33 +00:00
db : InternalDBs ,
2022-01-08 10:41:11 +00:00
syncPlan : SyncPlanType ,
2024-02-24 03:31:23 +00:00
vaultRandomID : string ,
remoteType : SUPPORTED_SERVICES_TYPE
2021-11-07 05:58:51 +00:00
) = > {
2024-02-24 03:31:23 +00:00
const now = Date . now ( ) ;
2021-11-14 12:24:33 +00:00
const record = {
2024-02-24 03:31:23 +00:00
ts : now ,
tsFmt : unixTimeToStr ( now ) ,
2022-01-08 10:41:11 +00:00
vaultRandomID : vaultRandomID ,
2024-02-24 03:31:23 +00:00
remoteType : remoteType ,
2021-11-14 12:24:33 +00:00
syncPlan : JSON.stringify ( syncPlan /* directly stringify */ , null , 2 ) ,
} as SyncPlanRecord ;
2024-02-24 03:31:23 +00:00
await db . syncPlansTbl . setItem ( ` ${ vaultRandomID } \ t ${ now } ` , record ) ;
2021-11-07 05:58:51 +00:00
} ;
2021-11-14 12:24:33 +00:00
export const clearAllSyncPlanRecords = async ( db : InternalDBs ) = > {
await db . syncPlansTbl . clear ( ) ;
2021-11-07 05:58:51 +00:00
} ;
2022-01-08 10:41:11 +00:00
export const readAllSyncPlanRecordTextsByVault = async (
db : InternalDBs ,
vaultRandomID : string
) = > {
2021-11-14 12:24:33 +00:00
const records = [ ] as SyncPlanRecord [ ] ;
await db . syncPlansTbl . iterate ( ( value , key , iterationNumber ) = > {
2022-01-08 10:41:11 +00:00
if ( key . startsWith ( ` ${ vaultRandomID } \ t ` ) ) {
records . push ( value as SyncPlanRecord ) ;
}
2021-11-14 12:24:33 +00:00
} ) ;
records . sort ( ( a , b ) = > - ( a . ts - b . ts ) ) ; // descending
2021-11-07 05:58:51 +00:00
if ( records === undefined ) {
return [ ] as string [ ] ;
} else {
2021-11-14 12:24:33 +00:00
return records . map ( ( x ) = > x . syncPlan ) ;
2021-11-07 05:58:51 +00:00
}
} ;
2022-04-05 16:24:27 +00:00
2022-04-05 16:35:21 +00:00
/ * *
2024-04-02 16:21:43 +00:00
* We remove records that are older than 1 days or 20 records .
2022-04-05 16:35:21 +00:00
* It ' s a heavy operation , so we shall not place it in the start up .
* @param db
* /
export const clearExpiredSyncPlanRecords = async ( db : InternalDBs ) = > {
2024-04-02 16:21:43 +00:00
const MILLISECONDS_OLD = 1000 * 60 * 60 * 24 * 1 ; // 1 days
const COUNT_TO_MANY = 20 ;
2022-04-05 16:35:21 +00:00
const currTs = Date . now ( ) ;
const expiredTs = currTs - MILLISECONDS_OLD ;
let records = ( await db . syncPlansTbl . keys ( ) ) . map ( ( key ) = > {
2024-05-07 16:20:15 +00:00
const ts = Number . parseInt ( key . split ( "\t" ) [ 1 ] ) ;
2022-04-05 16:35:21 +00:00
const expired = ts <= expiredTs ;
return {
ts : ts ,
key : key ,
expired : expired ,
} ;
} ) ;
const keysToRemove = new Set (
records . filter ( ( x ) = > x . expired ) . map ( ( x ) = > x . key )
) ;
if ( records . length - keysToRemove . size > COUNT_TO_MANY ) {
2024-01-13 08:59:51 +00:00
// we need to find out records beyond 100 records
2022-04-05 16:35:21 +00:00
records = records . filter ( ( x ) = > ! x . expired ) ; // shrink the array
records . sort ( ( a , b ) = > - ( a . ts - b . ts ) ) ; // descending
records . slice ( COUNT_TO_MANY ) . forEach ( ( element ) = > {
keysToRemove . add ( element . key ) ;
} ) ;
}
2024-05-17 14:59:34 +00:00
// const ps = [] as Promise<void>[];
// keysToRemove.forEach((element) => {
// ps.push(db.syncPlansTbl.removeItem(element));
// });
// await Promise.all(ps);
await db . syncPlansTbl . removeItems ( Array . from ( keysToRemove ) ) ;
2022-04-05 16:35:21 +00:00
} ;
2024-03-17 08:35:02 +00:00
export const getAllPrevSyncRecordsByVaultAndProfile = async (
2024-02-24 03:31:23 +00:00
db : InternalDBs ,
2024-03-17 08:35:02 +00:00
vaultRandomID : string ,
profileID : string
2024-02-24 03:31:23 +00:00
) = > {
const res : Entity [ ] = [ ] ;
2024-04-04 15:37:09 +00:00
const kv : Record < string , Entity | null > =
await db . prevSyncRecordsTbl . getItems ( ) ;
for ( const key of Object . getOwnPropertyNames ( kv ) ) {
2024-03-17 08:35:02 +00:00
if ( key . startsWith ( ` ${ vaultRandomID } \ t ${ profileID } \ t ` ) ) {
2024-04-04 15:37:09 +00:00
const val = kv [ key ] ;
2024-02-24 03:31:23 +00:00
if ( val !== null ) {
res . push ( val ) ;
}
}
}
return res ;
} ;
2024-03-17 08:35:02 +00:00
export const upsertPrevSyncRecordByVaultAndProfile = async (
2024-02-24 00:21:05 +00:00
db : InternalDBs ,
vaultRandomID : string ,
2024-03-17 08:35:02 +00:00
profileID : string ,
2024-02-24 00:21:05 +00:00
prevSync : Entity
) = > {
await db . prevSyncRecordsTbl . setItem (
2024-03-17 08:35:02 +00:00
` ${ vaultRandomID } \ t ${ profileID } \ t ${ prevSync . key } ` ,
2024-02-24 00:21:05 +00:00
prevSync
) ;
} ;
2024-03-17 08:35:02 +00:00
export const clearPrevSyncRecordByVaultAndProfile = async (
2024-02-24 00:21:05 +00:00
db : InternalDBs ,
vaultRandomID : string ,
2024-03-17 08:35:02 +00:00
profileID : string ,
2024-02-24 00:21:05 +00:00
key : string
) = > {
2024-03-17 08:35:02 +00:00
await db . prevSyncRecordsTbl . removeItem (
` ${ vaultRandomID } \ t ${ profileID } \ t ${ key } `
) ;
2024-02-24 00:21:05 +00:00
} ;
export const clearAllPrevSyncRecordByVault = async (
db : InternalDBs ,
vaultRandomID : string
) = > {
2024-05-17 14:59:34 +00:00
const keys = ( await db . prevSyncRecordsTbl . keys ( ) ) . filter ( ( x ) = >
x . startsWith ( ` ${ vaultRandomID } \ t ` )
) ;
await db . prevSyncRecordsTbl . removeItems ( keys ) ;
2024-02-24 00:21:05 +00:00
} ;
2022-04-05 16:24:27 +00:00
export const clearAllLoggerOutputRecords = async ( db : InternalDBs ) = > {
await db . loggerOutputTbl . clear ( ) ;
2024-03-17 08:03:40 +00:00
console . debug ( ` successfully clearAllLoggerOutputRecords ` ) ;
2022-04-05 16:24:27 +00:00
} ;
2024-01-05 16:03:53 +00:00
2024-02-24 03:31:23 +00:00
export const upsertLastSuccessSyncTimeByVault = async (
2024-01-05 16:03:53 +00:00
db : InternalDBs ,
vaultRandomID : string ,
millis : number
) = > {
await db . simpleKVForMiscTbl . setItem (
` ${ vaultRandomID } -lastSuccessSyncMillis ` ,
millis
) ;
} ;
2024-02-24 03:31:23 +00:00
export const getLastSuccessSyncTimeByVault = async (
2024-01-05 16:03:53 +00:00
db : InternalDBs ,
vaultRandomID : string
) = > {
return ( await db . simpleKVForMiscTbl . getItem (
` ${ vaultRandomID } -lastSuccessSyncMillis `
) ) as number ;
} ;
2024-01-07 03:20:57 +00:00
export const upsertPluginVersionByVault = async (
db : InternalDBs ,
vaultRandomID : string ,
newVersion : string
) = > {
let oldVersion : string | null = await db . simpleKVForMiscTbl . getItem (
` ${ vaultRandomID } -pluginversion `
) ;
if ( oldVersion === null ) {
oldVersion = "0.0.0" ;
}
await db . simpleKVForMiscTbl . setItem (
` ${ vaultRandomID } -pluginversion ` ,
newVersion
) ;
return {
oldVersion : oldVersion ,
newVersion : newVersion ,
} ;
} ;
2024-04-04 13:52:01 +00:00
export const insertProfilerResultByVault = async (
db : InternalDBs ,
profilerStr : string ,
vaultRandomID : string ,
remoteType : SUPPORTED_SERVICES_TYPE
) = > {
const now = Date . now ( ) ;
await db . profilerResultsTbl . setItem ( ` ${ vaultRandomID } \ t ${ now } ` , profilerStr ) ;
// clear older one while writing
const records = ( await db . profilerResultsTbl . keys ( ) )
. filter ( ( x ) = > x . startsWith ( ` ${ vaultRandomID } \ t ` ) )
2024-05-07 16:20:15 +00:00
. map ( ( x ) = > Number . parseInt ( x . split ( "\t" ) [ 1 ] ) ) ;
2024-04-04 13:52:01 +00:00
records . sort ( ( a , b ) = > - ( a - b ) ) ; // descending
while ( records . length > 5 ) {
const ts = records . pop ( ) ! ;
await db . profilerResultsTbl . removeItem ( ` ${ vaultRandomID } \ t ${ ts } ` ) ;
}
} ;
export const readAllProfilerResultsByVault = async (
db : InternalDBs ,
vaultRandomID : string
) = > {
const records = [ ] as { val : string ; ts : number } [ ] ;
await db . profilerResultsTbl . iterate ( ( value , key , iterationNumber ) = > {
if ( key . startsWith ( ` ${ vaultRandomID } \ t ` ) ) {
records . push ( {
val : value as string ,
2024-05-07 16:20:15 +00:00
ts : Number.parseInt ( key . split ( "\t" ) [ 1 ] ) ,
2024-04-04 13:52:01 +00:00
} ) ;
}
} ) ;
records . sort ( ( a , b ) = > - ( a . ts - b . ts ) ) ; // descending
if ( records === undefined ) {
return [ ] as string [ ] ;
} else {
return records . map ( ( x ) = > x . val ) ;
}
} ;