-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
637991e
commit 3ecafae
Showing
19 changed files
with
306 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,38 @@ | ||
import { DBDriver } from '../driver/abstract' | ||
import { delProperty, dispatch, expire, reactCache, verifyEntry } from '../shared' | ||
import { delProperty, dispatch, expire, Keys, reactCache, verifyEntry } from '../shared' | ||
|
||
export async function clear( | ||
cache: reactCache, | ||
driver: DBDriver, | ||
expire?: expire, | ||
): Promise<void> { | ||
await (expire | ||
? driver.entries() | ||
.then(entries => driver.setMany( | ||
entries | ||
.filter(([, obj]) => !verifyEntry({ obj }, expire)) | ||
.map(([key]) => [key, undefined]), | ||
)) | ||
: driver.clear() | ||
) | ||
const updateKeys: Array<keyof reactCache> = [] | ||
|
||
const keys: string[] = [] | ||
Object.entries(cache).forEach(([key, entry]) => { | ||
if (expire) { | ||
if (!verifyEntry({ obj: entry.obj }, expire)) { | ||
keys.push(key) | ||
if (expire) { | ||
const dbEntries = await driver.entries() | ||
await driver.setMany(dbEntries | ||
.filter(([, obj]) => !verifyEntry({ obj }, expire)) | ||
.map(([key]) => [key, undefined]), | ||
) | ||
for (const [key, entry] of Object.entries(cache)) { | ||
if (entry.obj !== undefined && !verifyEntry(entry, expire)) { | ||
updateKeys.push(key) | ||
delProperty(cache, [key, 'obj']) | ||
} | ||
} else { | ||
keys.push(key) | ||
delProperty(cache, [key, 'obj']) | ||
} | ||
}) | ||
} else { | ||
await driver.clear() | ||
|
||
dispatch(cache, keys) | ||
for (const [key, entry] of Object.entries(cache)) { | ||
if (entry.obj !== undefined) { | ||
updateKeys.push(key) | ||
delProperty(cache, [key, 'obj']) | ||
} | ||
} | ||
} | ||
|
||
if (updateKeys.length) { | ||
updateKeys.push(Keys) | ||
dispatch(cache, updateKeys) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,20 @@ | ||
import { DBDriver } from '../driver/abstract' | ||
import { delProperty, dispatch, reactCache } from '../shared' | ||
import { delProperty, dispatch, Keys, reactCache } from '../shared' | ||
|
||
export async function del( | ||
cache: reactCache, | ||
driver: DBDriver, | ||
key: string, | ||
): Promise<void> { | ||
const hasCacheKey = !!cache[key]?.obj | ||
|
||
await driver.del(key) | ||
delProperty(cache, [key, 'obj']) | ||
|
||
if (hasCacheKey) { | ||
delProperty(cache, [key, 'obj']) | ||
|
||
dispatch(cache, [Keys]) | ||
} | ||
|
||
dispatch(cache, [key]) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { DBDriver } from '../driver/abstract' | ||
import { addListener, debugLog, delProperty, dispatch, expire, Keys, reactCache, setProperty, verifyEntry } from '../shared' | ||
|
||
export function entries<T = unknown>( | ||
cache: reactCache, | ||
driver: DBDriver, | ||
id: string, | ||
rerender: () => void, | ||
expire?: expire, | ||
): Array<[string, T]> { | ||
addListener(cache, [Keys], id, rerender) | ||
|
||
// addListener creates the entry if it does not exists | ||
const keysEntry = cache[Keys] as NonNullable<reactCache[typeof Keys]> | ||
|
||
const isFetchingOrValid = keysEntry.promise || verifyEntry(keysEntry, expire) | ||
if (!isFetchingOrValid) { | ||
debugLog('Get entries from idb') | ||
|
||
const idbPromise: Promise<[string, unknown][]> = driver.entries().then( | ||
(entries) => { | ||
debugLog(' -> received entries from idb: %d', entries.length) | ||
|
||
const dbKeys = new Set() | ||
for (const [key, entry] of entries) { | ||
/* istanbul ignore next */ | ||
if (typeof key !== 'string') { | ||
continue | ||
} | ||
|
||
dbKeys.add(key) | ||
setProperty(cache, [key, 'obj'], entry) | ||
delProperty(cache, [key, 'isVolatile']) | ||
} | ||
|
||
for (const [key, entry] of Object.entries(cache)) { | ||
if (!entry.isVolatile && !dbKeys.has(key)) { | ||
delProperty(cache, [key, 'obj']) | ||
} | ||
} | ||
|
||
keysEntry.obj = {data: null, meta: {date: new Date()}} | ||
delete keysEntry.promise | ||
dispatch(cache, [Keys]) | ||
|
||
return getDataEntries(cache) | ||
}, | ||
) | ||
|
||
keysEntry.promise = idbPromise | ||
} | ||
|
||
return getDataEntries(cache) as Array<[string, T]> | ||
} | ||
|
||
function getDataEntries( | ||
cache: reactCache, | ||
) { | ||
const entries: [string, unknown][] = [] | ||
|
||
for (const [key, entry] of Object.entries(cache)) { | ||
if (entry.obj) { | ||
entries.push([key, entry.obj.data]) | ||
} | ||
} | ||
|
||
return entries | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,28 @@ | ||
export interface reactCacheEntry<T extends unknown = unknown> { | ||
promise?: Promise<cachedObj<T> | undefined>, | ||
obj?: cachedObj<T>, | ||
listeners?: Record<string, () => void>, | ||
promise?: Promise<cachedObj<T> | undefined> | ||
obj?: cachedObj<T> | ||
listeners?: Record<string | symbol, () => void> | ||
/** only set in react cache - not received from or written to db */ | ||
isVolatile?: boolean | ||
} | ||
|
||
export type reactCache = Record<string, reactCacheEntry> | ||
export const Keys = Symbol('keys') | ||
export type Keys = Set<string> | ||
|
||
export type reactCache = Record<string, reactCacheEntry> & { | ||
[Keys]?: { | ||
promise?: Promise<[string, unknown][]> | ||
obj?: cachedObj<null> | ||
listeners?: Record<string | symbol, () => void> | ||
} | ||
} | ||
|
||
export type expire = number | ((obj: cachedObj) => boolean) | ||
|
||
export type cachedObj<T extends unknown = unknown> = { | ||
data: T, | ||
data: T | ||
meta: { | ||
date?: Date | string, | ||
[k: string]: unknown, | ||
}, | ||
date?: Date | string | ||
[k: string]: unknown | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.