@@ -2,25 +2,23 @@ import Dexie from 'dexie';
22import UnityCacheError from './error' ;
33
44const RE_BIN = / ^ \w + $ / ;
5- const EXPIRE_BIN = '___expire___' ;
6- const EXPIRE_GLUE = '::' ;
75const DEFAULT_NAME = 'unity' ;
86const DEFAULT_VERSION = 1 ;
97
108const cacheInstance = {
11- config : { } ,
12- db : null
9+ db : null ,
10+ config : { }
1311} ;
1412
15- function setCacheConfig ( name , stores , version ) {
16- stores = [ ] . concat ( stores , EXPIRE_BIN ) ;
17-
13+ function initCacheConfig ( stores = [ ] , name = DEFAULT_NAME , version = DEFAULT_VERSION ) {
14+ stores = [ ] . concat ( stores ) ;
1815 stores = stores . reduce ( ( result , storeName ) => {
1916 if ( ! RE_BIN . test ( storeName ) ) {
2017 throw new UnityCacheError ( `Store names can only be alphanumeric, '${ storeName } ' given` ) ;
2118 }
2219
23- result [ storeName ] = '&' ;
20+ result [ storeName ] = '&key, value, expire' ;
21+
2422 return result ;
2523 } , { } ) ;
2624
@@ -34,16 +32,18 @@ function setCacheConfig(name, stores, version) {
3432function initCacheStores ( ) {
3533 const { name, stores, version } = cacheInstance . config ;
3634
35+ if ( cacheInstance . db ) {
36+ closeDB ( ) ;
37+ }
38+
3739 cacheInstance . db = new Dexie ( name ) ;
3840
3941 if ( ! cacheInstance . db ) {
4042 /* istanbul ignore next: error new Dexie */
4143 throw new UnityCacheError ( 'Database is undefined or null' ) ;
4244 }
4345
44- cacheInstance . db
45- . version ( version )
46- . stores ( stores ) ;
46+ cacheInstance . db . version ( version ) . stores ( stores ) ;
4747}
4848
4949function errorHandlerWrapper ( method ) {
@@ -54,6 +54,8 @@ function errorHandlerWrapper(method) {
5454 switch ( e . name ) {
5555 case Dexie . errnames . Upgrade :
5656 case Dexie . errnames . Version :
57+ case Dexie . errnames . InvalidState :
58+ case Dexie . errnames . QuotaExceeded :
5759 await upgradeDB ( ) ;
5860 return null ;
5961
@@ -70,8 +72,20 @@ function errorHandlerWrapper(method) {
7072 } ;
7173}
7274
75+ function closeDB ( ) {
76+ if ( ! cacheInstance . db ) {
77+ /* istanbul ignore next: db is not defined */
78+ throw new UnityCacheError ( 'Database is undefined or null' ) ;
79+ }
80+
81+ if ( cacheInstance . db . isOpen ( ) ) {
82+ cacheInstance . db . close ( ) ;
83+ }
84+ }
85+
7386async function openDB ( ) {
7487 if ( ! cacheInstance . db ) {
88+ /* istanbul ignore next: db is not defined */
7589 throw new UnityCacheError ( 'Database is undefined or null' ) ;
7690 }
7791
@@ -88,6 +102,11 @@ async function openDB() {
88102}
89103
90104async function upgradeDB ( ) {
105+ if ( ! cacheInstance . db ) {
106+ /* istanbul ignore next: db is not defined */
107+ throw new UnityCacheError ( 'Database is undefined or null' ) ;
108+ }
109+
91110 return await deleteDB ( )
92111 . then ( ( ) => {
93112 initCacheStores ( ) ;
@@ -100,10 +119,11 @@ async function upgradeDB() {
100119
101120async function deleteDB ( ) {
102121 if ( ! cacheInstance . db ) {
122+ /* istanbul ignore next: db is not defined */
103123 throw new UnityCacheError ( 'Database is undefined or null' ) ;
104124 }
105125
106- cacheInstance . db . close ( ) ;
126+ closeDB ( ) ;
107127
108128 return await cacheInstance . db
109129 . delete ( )
@@ -113,30 +133,23 @@ async function deleteDB() {
113133 } ) ;
114134}
115135
116- function getExpireKey ( store , key ) {
117- return store + EXPIRE_GLUE + key ;
118- }
119-
120136async function get ( store , key , validate = true ) {
121137 const { db } = cacheInstance ;
122-
123- const expired = await db [ EXPIRE_BIN ] . get ( getExpireKey ( store , key ) ) ;
124- const isValid = validate && db [ store ] ? expired > Date . now ( ) : true ;
138+ const { value = null , expire = 0 } = await db [ store ] . get ( key ) || { } ;
139+ const isValid = validate ? expire > Date . now ( ) : true ;
125140
126141 if ( ! isValid ) {
127- await db [ EXPIRE_BIN ] . delete ( getExpireKey ( store , key ) ) ;
142+ await db [ store ] . delete ( key ) ;
128143 }
129144
130- return isValid ? await db [ store ] . get ( key ) : null ;
145+ return isValid ? value : null ;
131146}
132147
133- async function set ( store , key , value , expire = Number . MAX_SAFE_INTEGER ) {
148+ async function set ( store , key , value , ttl = Number . MAX_SAFE_INTEGER ) {
134149 const { db } = cacheInstance ;
150+ const expire = Date . now ( ) + Number ( ttl ) ;
135151
136- return await Promise . all ( [
137- db [ EXPIRE_BIN ] . put ( Date . now ( ) + Number ( expire ) , getExpireKey ( store , key ) ) ,
138- db [ store ] . put ( value , key )
139- ] ) ;
152+ return await db [ store ] . put ( { key, value, expire } ) ;
140153}
141154
142155async function remove ( store , key ) {
@@ -146,28 +159,26 @@ async function remove(store, key) {
146159
147160 const { db } = cacheInstance ;
148161
149- return await Promise . all ( [
150- db [ EXPIRE_BIN ] . delete ( getExpireKey ( store , key ) ) ,
151- db [ store ] . delete ( key )
152- ] ) ;
162+ return await db [ store ] . delete ( key ) ;
153163}
154164
155165async function drop ( stores ) {
156166 const { db } = cacheInstance ;
157167
158168 stores = [ ] . concat ( stores ) ;
169+
159170 return await Promise . all ( stores . map ( store => db [ store ] . clear ( ) ) ) ;
160171}
161172
162- function createCache ( stores , name = DEFAULT_NAME , version = DEFAULT_VERSION ) {
163- setCacheConfig ( name , stores , version ) ;
173+ function createCache ( stores = [ ] , name = DEFAULT_NAME , version = DEFAULT_VERSION ) {
174+ initCacheConfig ( stores , name , version ) ;
164175 initCacheStores ( ) ;
165176
166177 return {
167178 get : errorHandlerWrapper ( get ) ,
168179 set : errorHandlerWrapper ( set ) ,
169- remove : errorHandlerWrapper ( remove ) ,
170- drop : errorHandlerWrapper ( drop )
180+ drop : errorHandlerWrapper ( drop ) ,
181+ remove : errorHandlerWrapper ( remove )
171182 } ;
172183}
173184
0 commit comments