@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
- * Open the IndexedDB database
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
- * - Cached Response object
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;