@@ -2,23 +2,34 @@ import { log, canUseCache } from './utils.js'
22
33var db
44
5- function openDB ( config ) {
5+ function openCache ( config ) {
66 if ( config . cache && typeof window !== 'undefined' ) {
7- const request = window . indexedDB . open ( "pokeapi-js-wrapper" , 3 ) ;
7+ const request = window . indexedDB . open ( "pokeapi-js-wrapper" , 8 ) ;
88 return new Promise ( ( resolve , reject ) => {
99 request . onerror = ( event ) => {
1010 log ( 'IndexedDB not available' )
1111 reject ( )
1212 }
1313 request . onupgradeneeded = ( event ) => {
14- db = event . target . result ;
15- log ( 'db opened and cache created' )
16- db . createObjectStore ( "cache" , { autoIncrement : false } ) ;
17- resolve ( db )
14+ const db = event . target . result ;
15+ const transaction = event . target . transaction ;
16+ let objectStore ;
17+
18+ if ( ! db . objectStoreNames . contains ( 'cache' ) ) {
19+ objectStore = db . createObjectStore ( "cache" , { autoIncrement : false } ) ;
20+ log ( 'Object store "cache" created' ) ;
21+ } else {
22+ objectStore = transaction . objectStore ( "cache" ) ;
23+ }
24+
25+ if ( ! objectStore . indexNames . contains ( "deploy_date_index" ) ) {
26+ objectStore . createIndex ( "deploy_date_index" , "meta.deploy_date" , { unique : false } ) ;
27+ log ( 'Index "deploy_date_index" created' ) ;
28+ }
1829 }
1930 request . onsuccess = ( event ) => {
20- log ( 'db opened' )
2131 db = event . target . result ;
32+ log ( 'db opened' )
2233 resolve ( db )
2334 }
2435 request . onversionchange = ( event ) => {
@@ -43,8 +54,11 @@ function getFromDB(objectStore, url) {
4354
4455async function loadResource ( config , url ) {
4556 if ( ! url . includes ( '://' ) ) {
46- url = url . replace ( / ^ \/ / , '' ) ;
47- url = `${ config . protocol } ://${ config . hostName } /${ url } `
57+ if ( url . startsWith ( '/api/v2/' ) ) {
58+ url = `${ config . protocol } ://${ config . hostName } ${ url } `
59+ } else if ( ! url . includes ( '://' ) ) {
60+ url = `${ config . protocol } ://${ config . hostName } ${ config . versionPath } ${ url } `
61+ }
4862 }
4963 if ( canUseCache ( config , db ) ) {
5064 const transaction = db . transaction ( "cache" , "readonly" ) ;
@@ -66,10 +80,14 @@ async function loadUrl(config, url) {
6680 const body = await response . json ( )
6781 if ( response . status === 200 ) {
6882 if ( canUseCache ( config , db ) ) {
83+ const deploy_date = parseInt ( response . headers . get ( 'X-PokeAPI-Deploy-Date' ) )
84+ body . meta = { deploy_date }
6985 const transaction = db . transaction ( "cache" , "readwrite" ) ;
7086 const objectStore = transaction . objectStore ( "cache" ) ;
7187 const request = objectStore . add ( body , url )
72- request . onsuccess = ( ) => log ( `object cached ${ url } ` ) ;
88+ request . onsuccess = ( ) => {
89+ log ( `object cached ${ url } ` ) ;
90+ }
7391 request . onerror = ( ) => {
7492 log ( request . error )
7593 }
@@ -79,7 +97,7 @@ async function loadUrl(config, url) {
7997 return body
8098}
8199
82- function sizeDB ( config ) {
100+ function sizeCache ( config ) {
83101 if ( canUseCache ( config , db ) ) {
84102 return new Promise ( ( resolve , reject ) => {
85103 const transaction = db . transaction ( "cache" , "readwrite" ) ;
@@ -89,11 +107,39 @@ function sizeDB(config) {
89107 request . onerror = ( ) => reject ( request . error ) ;
90108 } ) ;
91109 } else {
92- return Promise . reject ( )
110+ return Promise . reject ( new Error ( 'Cache not available' ) )
111+ }
112+ }
113+
114+ async function invalidateCache ( config ) {
115+ if ( canUseCache ( config , db ) ) {
116+ const meta = await loadResource ( { ...config , cache : false } , 'meta' ) ;
117+ const upstream_deploy_date = parseInt ( meta . deploy_date ) ;
118+
119+ return new Promise ( ( resolve , reject ) => {
120+ const transaction = db . transaction ( "cache" , "readwrite" ) ;
121+ const objectStore = transaction . objectStore ( "cache" ) ;
122+ const index = objectStore . index ( "deploy_date_index" ) ;
123+
124+ const range = IDBKeyRange . upperBound ( upstream_deploy_date , true ) ;
125+ const request = index . getAllKeys ( range ) ;
126+
127+ request . onsuccess = ( ) => {
128+ const keys = request . result ;
129+ keys . forEach ( pk => {
130+ objectStore . delete ( pk ) ;
131+ log ( `invalidated ${ pk } ` ) ;
132+ } ) ;
133+ resolve ( true ) ;
134+ } ;
135+ request . onerror = ( ) => reject ( new Error ( request . error ) ) ;
136+ } ) ;
137+ } else {
138+ throw new Error ( 'cache not available' ) ;
93139 }
94140}
95141
96- function clearDB ( config ) {
142+ function clearCache ( config ) {
97143 if ( canUseCache ( config , db ) ) {
98144 return new Promise ( ( resolve , reject ) => {
99145 const transaction = db . transaction ( "cache" , "readwrite" ) ;
@@ -103,8 +149,8 @@ function clearDB(config) {
103149 request . onerror = ( ) => reject ( request . error ) ;
104150 } ) ;
105151 } else {
106- return Promise . reject ( )
152+ return Promise . reject ( new Error ( 'Cache not available' ) )
107153 }
108154}
109155
110- export { loadResource , openDB , sizeDB , clearDB }
156+ export { loadResource , openCache , sizeCache , clearCache , invalidateCache }
0 commit comments