@hkdigital/lib-sveltekit 0.1.73 → 0.1.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,45 +1,3 @@
|
|
1
|
-
/**
|
2
|
-
* @fileoverview IndexedDbCache provides efficient persistent caching with
|
3
|
-
* automatic, non-blocking background cleanup.
|
4
|
-
*
|
5
|
-
* This cache automatically manages storage limits and entry expiration
|
6
|
-
* in the background using requestIdleCallback to avoid impacting application
|
7
|
-
* performance. It supports incremental cleanup, storage monitoring, and
|
8
|
-
* graceful degradation on older browsers.
|
9
|
-
*
|
10
|
-
* @example
|
11
|
-
* // Create a cache instance
|
12
|
-
* const cache = new IndexedDbCache({
|
13
|
-
* dbName: 'app-cache',
|
14
|
-
* storeName: 'http-responses',
|
15
|
-
* maxSize: 100 * 1024 * 1024, // 100MB
|
16
|
-
* maxAge: 30 * 24 * 60 * 60 * 1000 // 30 days
|
17
|
-
* });
|
18
|
-
*
|
19
|
-
* // Store a response
|
20
|
-
* const response = await fetch('https://api.example.com/data');
|
21
|
-
* await cache.set('api-data', response, {
|
22
|
-
* expiresIn: 3600000 // 1 hour
|
23
|
-
* });
|
24
|
-
*
|
25
|
-
* // Retrieve cached response
|
26
|
-
* const cached = await cache.get('api-data');
|
27
|
-
* if (cached) {
|
28
|
-
* console.log('Cache hit', cached.response);
|
29
|
-
* } else {
|
30
|
-
* console.log('Cache miss');
|
31
|
-
* }
|
32
|
-
*/
|
33
|
-
/**
|
34
|
-
* @typedef {Object} CacheEntry
|
35
|
-
* @property {Response} response - Cached Response object
|
36
|
-
* @property {Object} metadata - Cache entry metadata
|
37
|
-
* @property {string} url - Original URL
|
38
|
-
* @property {number} timestamp - When the entry was cached
|
39
|
-
* @property {number|null} expires - Expiration timestamp (null if no expiration)
|
40
|
-
* @property {string|null} etag - ETag header if present
|
41
|
-
* @property {string|null} lastModified - Last-Modified header if present
|
42
|
-
*/
|
43
1
|
/**
|
44
2
|
* IndexedDbCache with automatic background cleanup
|
45
3
|
*/
|
@@ -54,6 +12,8 @@ export default class IndexedDbCache {
|
|
54
12
|
* @param {number} [options.maxAge=604800000] - Max age in ms (7 days)
|
55
13
|
* @param {number} [options.cleanupBatchSize=100] - Items per cleanup batch
|
56
14
|
* @param {number} [options.cleanupInterval=300000] - Time between cleanup attempts (5min)
|
15
|
+
* @param {number} [options.cleanupPostponeTimeout=5000] - Time to postpone cleanup after store (5sec)
|
16
|
+
* @param {string} [options.cacheVersion='1.0.0'] - Cache version, used for cache invalidation
|
57
17
|
*/
|
58
18
|
constructor(options?: {
|
59
19
|
dbName?: string;
|
@@ -62,6 +22,8 @@ export default class IndexedDbCache {
|
|
62
22
|
maxAge?: number;
|
63
23
|
cleanupBatchSize?: number;
|
64
24
|
cleanupInterval?: number;
|
25
|
+
cleanupPostponeTimeout?: number;
|
26
|
+
cacheVersion?: string;
|
65
27
|
});
|
66
28
|
dbName: string;
|
67
29
|
storeName: string;
|
@@ -69,6 +31,13 @@ export default class IndexedDbCache {
|
|
69
31
|
maxAge: number;
|
70
32
|
cleanupBatchSize: number;
|
71
33
|
cleanupInterval: number;
|
34
|
+
cleanupPostponeTimeout: number;
|
35
|
+
cacheVersion: string;
|
36
|
+
EXPIRES_INDEX: string;
|
37
|
+
TIMESTAMP_INDEX: string;
|
38
|
+
SIZE_INDEX: string;
|
39
|
+
CACHE_VERSION_INDEX: string;
|
40
|
+
SCHEMA_VERSION: number;
|
72
41
|
/**
|
73
42
|
* Database connection promise
|
74
43
|
* @type {Promise<IDBDatabase>}
|
@@ -81,15 +50,54 @@ export default class IndexedDbCache {
|
|
81
50
|
* @private
|
82
51
|
*/
|
83
52
|
private cleanupState;
|
53
|
+
postponeCleanupTimer: number;
|
84
54
|
/**
|
85
|
-
*
|
55
|
+
* Initialize the database connection
|
56
|
+
*
|
57
|
+
* @private
|
58
|
+
*/
|
59
|
+
private _initDatabase;
|
60
|
+
/**
|
61
|
+
* Open the IndexedDB database with proper schema versioning
|
86
62
|
*
|
87
63
|
* @private
|
88
64
|
* @returns {Promise<IDBDatabase>}
|
89
65
|
*/
|
90
66
|
private _openDatabase;
|
67
|
+
/**
|
68
|
+
* Ensure an index exists in a store, create if missing
|
69
|
+
*
|
70
|
+
* @private
|
71
|
+
* @param {IDBObjectStore} store - The object store
|
72
|
+
* @param {string} indexName - Name of the index
|
73
|
+
* @param {string} keyPath - Key path for the index
|
74
|
+
* @param {Object} options - Index options (e.g. unique)
|
75
|
+
*/
|
76
|
+
private _ensureIndexExists;
|
77
|
+
/**
|
78
|
+
* Check if all required indexes exist in the database
|
79
|
+
*
|
80
|
+
* @private
|
81
|
+
* @returns {Promise<boolean>}
|
82
|
+
*/
|
83
|
+
private _validateSchema;
|
84
|
+
/**
|
85
|
+
* Postpone cleanup for the specified duration
|
86
|
+
* Resets the postpone timer if called again before timeout
|
87
|
+
*
|
88
|
+
* @private
|
89
|
+
*/
|
90
|
+
private _postponeCleanup;
|
91
|
+
/**
|
92
|
+
* Check if cleanup is postponed
|
93
|
+
*
|
94
|
+
* @private
|
95
|
+
* @returns {boolean}
|
96
|
+
*/
|
97
|
+
private _isCleanupPostponed;
|
91
98
|
/**
|
92
99
|
* Get a cached response
|
100
|
+
* Supports retrieving older cache versions and migrating them
|
93
101
|
*
|
94
102
|
* @param {string} key - Cache key
|
95
103
|
* @returns {Promise<CacheEntry|null>} Cache entry or null if not found/expired
|
@@ -104,6 +112,14 @@ export default class IndexedDbCache {
|
|
104
112
|
* @returns {Promise<void>}
|
105
113
|
*/
|
106
114
|
set(key: string, response: Response, metadata?: any): Promise<void>;
|
115
|
+
/**
|
116
|
+
* Update an existing entry in the cache
|
117
|
+
*
|
118
|
+
* @private
|
119
|
+
* @param {Object} entry - The entry to update
|
120
|
+
* @returns {Promise<boolean>}
|
121
|
+
*/
|
122
|
+
private _updateEntry;
|
107
123
|
/**
|
108
124
|
* Update last accessed timestamp (without blocking)
|
109
125
|
*
|
@@ -146,6 +162,13 @@ export default class IndexedDbCache {
|
|
146
162
|
* @param {boolean} [urgent=false] - If true, clean up sooner
|
147
163
|
*/
|
148
164
|
private _scheduleCleanup;
|
165
|
+
/**
|
166
|
+
* Get a random expiration time between 30 minutes and 90 minutes
|
167
|
+
*
|
168
|
+
* @private
|
169
|
+
* @returns {number} Expiration time in milliseconds
|
170
|
+
*/
|
171
|
+
private _getRandomExpiration;
|
149
172
|
/**
|
150
173
|
* Perform a single cleanup step
|
151
174
|
*
|
@@ -160,6 +183,14 @@ export default class IndexedDbCache {
|
|
160
183
|
* @returns {Promise<number>} Number of entries removed
|
161
184
|
*/
|
162
185
|
private _removeExpiredEntries;
|
186
|
+
/**
|
187
|
+
* Mark entries from old cache versions for gradual expiration
|
188
|
+
*
|
189
|
+
* @private
|
190
|
+
* @param {number} limit - Maximum number of entries to mark
|
191
|
+
* @returns {Promise<number>} Number of entries marked
|
192
|
+
*/
|
193
|
+
private _markOldCacheVersionsForExpiration;
|
163
194
|
/**
|
164
195
|
* Remove old entries based on age and size constraints
|
165
196
|
*
|
@@ -178,35 +209,8 @@ export default class IndexedDbCache {
|
|
178
209
|
/**
|
179
210
|
* Close the database connection
|
180
211
|
*/
|
181
|
-
close(): void
|
212
|
+
close(): Promise<void>;
|
182
213
|
}
|
183
|
-
export type CacheEntry =
|
184
|
-
|
185
|
-
|
186
|
-
*/
|
187
|
-
response: Response;
|
188
|
-
/**
|
189
|
-
* - Cache entry metadata
|
190
|
-
*/
|
191
|
-
metadata: any;
|
192
|
-
/**
|
193
|
-
* - Original URL
|
194
|
-
*/
|
195
|
-
url: string;
|
196
|
-
/**
|
197
|
-
* - When the entry was cached
|
198
|
-
*/
|
199
|
-
timestamp: number;
|
200
|
-
/**
|
201
|
-
* - Expiration timestamp (null if no expiration)
|
202
|
-
*/
|
203
|
-
expires: number | null;
|
204
|
-
/**
|
205
|
-
* - ETag header if present
|
206
|
-
*/
|
207
|
-
etag: string | null;
|
208
|
-
/**
|
209
|
-
* - Last-Modified header if present
|
210
|
-
*/
|
211
|
-
lastModified: string | null;
|
212
|
-
};
|
214
|
+
export type CacheEntry = import("./typedef").CacheEntry;
|
215
|
+
export type IDBRequestEvent = import("./typedef").IDBRequestEvent;
|
216
|
+
export type IDBVersionChangeEvent = import("./typedef").IDBVersionChangeEvent;
|