@fjell/cache 4.6.5 → 4.6.10

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.
@@ -0,0 +1,273 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-vars */
2
+ /**
3
+ * Basic Cache Example
4
+ *
5
+ * This example demonstrates the fundamental usage of fjell-cache for caching data models.
6
+ * It shows how to create caches, perform basic operations like get/set/all, and manage
7
+ * cached data with mock storage operations.
8
+ *
9
+ * Perfect for understanding the basics of fjell-cache before moving to advanced features.
10
+ */
11
+
12
+ import { createCache } from '../src/Cache';
13
+ import { createInstance } from '../src/Instance';
14
+ import { createRegistry } from '../src/Registry';
15
+ import { ClientApi } from '@fjell/client-api';
16
+ import { Item, PriKey } from '@fjell/core';
17
+ import { createCoordinate } from '@fjell/registry';
18
+
19
+ // Define our data models
20
+ interface User extends Item<'user'> {
21
+ id: string;
22
+ name: string;
23
+ email: string;
24
+ role: 'admin' | 'user' | 'guest';
25
+ }
26
+
27
+ interface Task extends Item<'task'> {
28
+ id: string;
29
+ title: string;
30
+ description: string;
31
+ assignedTo?: string;
32
+ status: 'pending' | 'in-progress' | 'completed';
33
+ priority: 'low' | 'medium' | 'high';
34
+ }
35
+
36
+ // Mock storage for demonstration (in real apps, this would be your database/API)
37
+ const mockUserStorage = new Map<string, User>();
38
+ const mockTaskStorage = new Map<string, Task>();
39
+
40
+ // Simple mock API for Users (simplified to avoid type issues)
41
+ const createUserApi = (): Partial<ClientApi<User, 'user'>> => ({
42
+ async all(query = {}) {
43
+ console.log('📦 Fetching all users from storage...');
44
+ return Array.from(mockUserStorage.values());
45
+ },
46
+
47
+ async one(query = {}) {
48
+ const users = await this.all!(query);
49
+ return users[0] || null;
50
+ },
51
+
52
+ async get(key: PriKey<'user'>) {
53
+ console.log(`🔍 Getting user with key: ${key.pk}`);
54
+ const user = mockUserStorage.get(String(key.pk));
55
+ if (!user) {
56
+ throw new Error(`User not found: ${key.pk}`);
57
+ }
58
+ return user;
59
+ },
60
+
61
+ async find(finder = 'all') {
62
+ return await this.all!({});
63
+ }
64
+ });
65
+
66
+ // Simple mock API for Tasks
67
+ const createTaskApi = (): Partial<ClientApi<Task, 'task'>> => ({
68
+ async all(query = {}) {
69
+ console.log('📦 Fetching all tasks from storage...');
70
+ return Array.from(mockTaskStorage.values());
71
+ },
72
+
73
+ async one(query = {}) {
74
+ const tasks = await this.all!(query);
75
+ return tasks[0] || null;
76
+ },
77
+
78
+ async get(key: PriKey<'task'>) {
79
+ console.log(`🔍 Getting task with key: ${key.pk}`);
80
+ const task = mockTaskStorage.get(String(key.pk));
81
+ if (!task) {
82
+ throw new Error(`Task not found: ${key.pk}`);
83
+ }
84
+ return task;
85
+ },
86
+
87
+ async find(finder = 'all') {
88
+ return await this.all!({});
89
+ }
90
+ });
91
+
92
+ // Helper function to create test data
93
+ const createTestUser = (id: string, name: string, email: string, role: 'admin' | 'user' | 'guest'): User => {
94
+ const user: User = {
95
+ id,
96
+ name,
97
+ email,
98
+ role,
99
+ key: { kt: 'user', pk: id },
100
+ events: {
101
+ created: { at: new Date() },
102
+ updated: { at: new Date() },
103
+ deleted: { at: null }
104
+ }
105
+ };
106
+ mockUserStorage.set(id, user);
107
+ console.log(`✅ Created user: ${user.name} (${user.email})`);
108
+ return user;
109
+ };
110
+
111
+ const createTestTask = (id: string, title: string, description: string, assignedTo: string, status: 'pending' | 'in-progress' | 'completed', priority: 'low' | 'medium' | 'high'): Task => {
112
+ const task: Task = {
113
+ id,
114
+ title,
115
+ description,
116
+ assignedTo,
117
+ status,
118
+ priority,
119
+ key: { kt: 'task', pk: id },
120
+ events: {
121
+ created: { at: new Date() },
122
+ updated: { at: new Date() },
123
+ deleted: { at: null }
124
+ }
125
+ };
126
+ mockTaskStorage.set(id, task);
127
+ console.log(`✅ Created task: ${task.title}`);
128
+ return task;
129
+ };
130
+
131
+ // Main example function
132
+ export const runBasicCacheExample = async (): Promise<void> => {
133
+ console.log('\n🚀 Fjell-Cache Basic Example');
134
+ console.log('============================\n');
135
+
136
+ console.log('This example demonstrates basic cache operations with User and Task models.\n');
137
+
138
+ // Step 1: Create registry and cache instances
139
+ console.log('Step 1: Setting up cache infrastructure');
140
+ console.log('--------------------------------------');
141
+
142
+ const registry = createRegistry();
143
+ console.log('✅ Created cache registry');
144
+
145
+ const userApi = createUserApi() as ClientApi<User, 'user'>;
146
+ const taskApi = createTaskApi() as ClientApi<Task, 'task'>;
147
+ console.log('✅ Created mock APIs for users and tasks');
148
+
149
+ const userCache = await createCache(userApi, 'user');
150
+ const taskCache = await createCache(taskApi, 'task');
151
+ console.log('✅ Created cache instances');
152
+
153
+ const userInstance = createInstance(registry, createCoordinate('user'), userCache);
154
+ const taskInstance = createInstance(registry, createCoordinate('task'), taskCache);
155
+ console.log('✅ Created cache model instances\n');
156
+
157
+ // Step 2: Create some test data
158
+ console.log('Step 2: Creating test data');
159
+ console.log('-------------------------');
160
+
161
+ const user1 = createTestUser('user-1', 'Alice Johnson', 'alice@example.com', 'admin');
162
+ const user2 = createTestUser('user-2', 'Bob Smith', 'bob@example.com', 'user');
163
+
164
+ const task1 = createTestTask('task-1', 'Setup project repository', 'Initialize Git repo and create basic structure', user1.id, 'completed', 'high');
165
+ const task2 = createTestTask('task-2', 'Implement user authentication', 'Add login and registration functionality', user2.id, 'in-progress', 'medium');
166
+
167
+ console.log('✅ Created test users and tasks\n');
168
+
169
+ // Step 3: Cache operations - Fetch and cache all items
170
+ console.log('Step 3: Cache operations - Fetching all items');
171
+ console.log('----------------------------------------------');
172
+
173
+ const [, allUsers] = await userInstance.cache.all();
174
+ console.log(`📋 Cached ${allUsers.length} users:`, allUsers.map(u => u.name));
175
+
176
+ const [, allTasks] = await taskInstance.cache.all();
177
+ console.log(`📋 Cached ${allTasks.length} tasks:`, allTasks.map(t => t.title));
178
+ console.log('');
179
+
180
+ // Step 4: Individual item retrieval from cache
181
+ console.log('Step 4: Individual item retrieval');
182
+ console.log('---------------------------------');
183
+
184
+ const [, cachedUser1] = await userInstance.cache.get(user1.key);
185
+ console.log(`👤 Retrieved from cache: ${cachedUser1?.name} (${cachedUser1?.email})`);
186
+
187
+ const [, cachedTask1] = await taskInstance.cache.get(task1.key);
188
+ console.log(`📝 Retrieved from cache: ${cachedTask1?.title} - Status: ${cachedTask1?.status}`);
189
+ console.log('');
190
+
191
+ // Step 5: Cache hit vs miss demonstration
192
+ console.log('Step 5: Cache behavior demonstration');
193
+ console.log('-----------------------------------');
194
+
195
+ // This should hit the cache (no API call)
196
+ console.log('🎯 Second retrieval (should hit cache):');
197
+ const [, cachedUser1Again] = await userInstance.cache.retrieve(user1.key);
198
+ console.log(`👤 Retrieved: ${cachedUser1Again?.name} (cache hit)`);
199
+
200
+ // Create a new user and demonstrate cache miss
201
+ const user3 = createTestUser('user-3', 'Charlie Brown', 'charlie@example.com', 'guest');
202
+
203
+ console.log('🎯 New item retrieval (cache miss, will fetch from API):');
204
+ const [, cachedUser3] = await userInstance.cache.get(user3.key);
205
+ console.log(`👤 Retrieved: ${cachedUser3?.name} (fetched from API and cached)`);
206
+ console.log('');
207
+
208
+ // Step 6: Cache updates
209
+ console.log('Step 6: Cache updates');
210
+ console.log('--------------------');
211
+
212
+ const updatedTask2 = { ...task2, status: 'completed' as const, description: 'Add login and registration functionality - COMPLETED!' };
213
+ mockTaskStorage.set(task2.id, updatedTask2);
214
+
215
+ // Update cache with new version
216
+ await taskInstance.cache.set(updatedTask2.key, updatedTask2);
217
+ console.log(`🔄 Updated task in cache: ${updatedTask2.title} - New status: ${updatedTask2.status}`);
218
+ console.log('');
219
+
220
+ // Step 7: Query operations
221
+ console.log('Step 7: Query operations');
222
+ console.log('-----------------------');
223
+
224
+ const [, foundTasks] = await taskInstance.cache.find('all');
225
+ console.log(`🔍 Found ${foundTasks.length} tasks through cache query`);
226
+
227
+ const [, oneTask] = await taskInstance.cache.one();
228
+ console.log(`📝 Retrieved one task: ${oneTask?.title}`);
229
+ console.log('');
230
+
231
+ // Step 8: Cache statistics and management
232
+ console.log('Step 8: Cache management');
233
+ console.log('-----------------------');
234
+
235
+ console.log('📊 Cache Statistics:');
236
+ console.log(` 👥 Users in cache: ${allUsers.length}`);
237
+ console.log(` 📝 Tasks in cache: ${allTasks.length}`);
238
+ console.log(` 🎯 User cache coordinate: ${userInstance.coordinate.kta[0]}`);
239
+ console.log(` 🎯 Task cache coordinate: ${taskInstance.coordinate.kta[0]}`);
240
+ console.log('');
241
+
242
+ // Step 9: Cleanup demonstration
243
+ console.log('Step 9: Cleanup demonstration');
244
+ console.log('-----------------------------');
245
+
246
+ mockUserStorage.delete('user-3');
247
+ console.log('🗑️ Removed user from storage');
248
+
249
+ // Cache still has the old data until next fetch
250
+ const [, stillCachedUser3] = await userInstance.cache.retrieve(user3.key);
251
+ console.log(`🎯 Cache still contains removed user: ${stillCachedUser3?.name || 'null'}`);
252
+
253
+ // Fresh fetch will update cache
254
+ const [, freshAllUsers] = await userInstance.cache.all();
255
+ console.log(`📋 Fresh fetch shows ${freshAllUsers.length} users (cache updated)`);
256
+ console.log('');
257
+
258
+ console.log('🎉 Basic Cache Example Complete!');
259
+ console.log('================================\n');
260
+
261
+ console.log('Key concepts demonstrated:');
262
+ console.log('• Cache creation with registry and instances');
263
+ console.log('• Basic cache operations (get, set, all, find, one)');
264
+ console.log('• Cache hits vs misses');
265
+ console.log('• Cache updates and management');
266
+ console.log('• Integration with mock storage APIs');
267
+ console.log('• Cache lifecycle and data consistency\n');
268
+ };
269
+
270
+ // Run the example if this file is executed directly
271
+ if (import.meta.url === `file://${process.argv[1]}`) {
272
+ runBasicCacheExample().catch(console.error);
273
+ }
@@ -0,0 +1,265 @@
1
+ /**
2
+ * Cache Map Example
3
+ *
4
+ * This example demonstrates the lower-level CacheMap functionality of fjell-cache.
5
+ * CacheMap provides direct key-value storage and retrieval with support for
6
+ * complex fjell keys and efficient item management.
7
+ *
8
+ * Shows how to:
9
+ * - Create and manage CacheMap instances directly
10
+ * - Store and retrieve items with complex keys
11
+ * - Use basic operations and key management
12
+ * - Handle key normalization and comparison
13
+ * - Manage cache lifecycle and cleanup
14
+ */
15
+
16
+ import { CacheMap } from '../src/CacheMap';
17
+ import { ComKey, Item, PriKey } from '@fjell/core';
18
+
19
+ // Define test data models
20
+ interface Document extends Item<'document'> {
21
+ id: string;
22
+ title: string;
23
+ content: string;
24
+ author: string;
25
+ tags: string[];
26
+ createdAt: Date;
27
+ }
28
+
29
+ interface Comment extends Item<'comment', 'document'> {
30
+ id: string;
31
+ documentId: string;
32
+ content: string;
33
+ author: string;
34
+ createdAt: Date;
35
+ }
36
+
37
+ // Helper to create test data
38
+ const createDocument = (id: string, title: string, content: string, author: string, tags: string[]): Document => ({
39
+ id, title, content, author, tags, createdAt: new Date(),
40
+ key: { kt: 'document', pk: id },
41
+ events: { created: { at: new Date() }, updated: { at: new Date() }, deleted: { at: null } }
42
+ });
43
+
44
+ const createComment = (id: string, documentId: string, content: string, author: string): Comment => ({
45
+ id, documentId, content, author, createdAt: new Date(),
46
+ key: { kt: 'comment', pk: id, loc: [{ kt: 'document', lk: documentId }] },
47
+ events: { created: { at: new Date() }, updated: { at: new Date() }, deleted: { at: null } }
48
+ });
49
+
50
+ export const runCacheMapExample = async (): Promise<void> => {
51
+ console.log('\n🚀 Fjell-Cache CacheMap Example');
52
+ console.log('==============================\n');
53
+
54
+ console.log('This example demonstrates direct CacheMap operations for low-level cache management.\n');
55
+
56
+ // Step 1: Create CacheMap instances
57
+ console.log('Step 1: Creating CacheMap instances');
58
+ console.log('-----------------------------------');
59
+
60
+ // Create CacheMaps for different item types
61
+ const documentCacheMap = new CacheMap<Document, 'document'>(['document']);
62
+ const commentCacheMap = new CacheMap<Comment, 'comment', 'document'>(['comment', 'document']);
63
+
64
+ console.log('✅ Created CacheMap instances for documents and comments');
65
+ console.log(` 📄 Document CacheMap: supports primary keys only`);
66
+ console.log(` 💬 Comment CacheMap: supports contained items with location hierarchy\n`);
67
+
68
+ // Step 2: Create test data
69
+ console.log('Step 2: Creating test data');
70
+ console.log('-------------------------');
71
+
72
+ const doc1 = createDocument('doc-1', 'Getting Started with Fjell', 'This is a comprehensive guide...', 'Alice', ['guide', 'tutorial']);
73
+ const doc2 = createDocument('doc-2', 'Advanced Caching Patterns', 'Learn advanced techniques...', 'Bob', ['advanced', 'caching']);
74
+ const doc3 = createDocument('doc-3', 'Performance Optimization', 'Tips for better performance...', 'Charlie', ['performance', 'optimization']);
75
+
76
+ const comment1 = createComment('comment-1', doc1.id, 'Great tutorial! Very helpful.', 'David');
77
+ const comment2 = createComment('comment-2', doc1.id, 'Thanks for sharing this.', 'Eve');
78
+ const comment3 = createComment('comment-3', doc2.id, 'Excellent advanced techniques.', 'Frank');
79
+
80
+ console.log('✅ Created test documents and comments\n');
81
+
82
+ // Step 3: Basic CacheMap operations
83
+ console.log('Step 3: Basic CacheMap operations');
84
+ console.log('---------------------------------');
85
+
86
+ // Set items in cache
87
+ documentCacheMap.set(doc1.key, doc1);
88
+ documentCacheMap.set(doc2.key, doc2);
89
+ documentCacheMap.set(doc3.key, doc3);
90
+
91
+ commentCacheMap.set(comment1.key, comment1);
92
+ commentCacheMap.set(comment2.key, comment2);
93
+ commentCacheMap.set(comment3.key, comment3);
94
+
95
+ console.log('📥 Stored all items in CacheMaps');
96
+ console.log(` 📄 Documents cached: ${documentCacheMap.values().length}`);
97
+ console.log(` 💬 Comments cached: ${commentCacheMap.values().length}`);
98
+
99
+ // Get individual items
100
+ const retrievedDoc1 = documentCacheMap.get(doc1.key);
101
+ const retrievedComment1 = commentCacheMap.get(comment1.key);
102
+
103
+ console.log(`\n🔍 Retrieved items by key:`);
104
+ console.log(` 📄 Document: "${retrievedDoc1?.title}" by ${retrievedDoc1?.author}`);
105
+ console.log(` 💬 Comment: "${retrievedComment1?.content}" by ${retrievedComment1?.author}`);
106
+
107
+ // Step 4: Key operations and checking
108
+ console.log('\n\nStep 4: Key operations and checking');
109
+ console.log('----------------------------------');
110
+
111
+ // Check if keys exist
112
+ const hasDoc1 = documentCacheMap.includesKey(doc1.key);
113
+ const hasDoc4 = documentCacheMap.includesKey({ kt: 'document', pk: 'doc-4' });
114
+
115
+ console.log(`🔑 Key existence checks:`);
116
+ console.log(` 📄 Document 1 exists: ${hasDoc1}`);
117
+ console.log(` 📄 Document 4 exists: ${hasDoc4}`);
118
+
119
+ // Get all keys
120
+ const allDocKeys = documentCacheMap.keys();
121
+ const allCommentKeys = commentCacheMap.keys();
122
+
123
+ console.log(`\n🗂️ All cached keys:`);
124
+ console.log(` 📄 Document keys: ${allDocKeys.length} items`);
125
+ allDocKeys.forEach(key => console.log(` - ${(key as PriKey<'document'>).pk}`));
126
+
127
+ console.log(` 💬 Comment keys: ${allCommentKeys.length} items`);
128
+ allCommentKeys.forEach(key => console.log(` - ${(key as ComKey<'comment', 'document'>).pk} in document ${(key as ComKey<'comment', 'document'>).loc?.[0]?.lk}`));
129
+
130
+ // Step 5: Bulk operations
131
+ console.log('\n\nStep 5: Bulk operations');
132
+ console.log('----------------------');
133
+
134
+ // Get all items
135
+ const allDocuments = documentCacheMap.allIn([]);
136
+ const allComments = commentCacheMap.allIn([]);
137
+
138
+ console.log(`📋 Retrieved all items:`);
139
+ console.log(` 📄 Documents: ${allDocuments.length} items`);
140
+ allDocuments.forEach(doc => console.log(` - "${doc.title}" (${doc.tags.join(', ')})`));
141
+
142
+ console.log(` 💬 Comments: ${allComments.length} items`);
143
+ allComments.forEach(comment => console.log(` - "${comment.content}" on doc ${comment.documentId}`));
144
+
145
+ // Get all values (another way to access items)
146
+ const allDocumentValues = documentCacheMap.values();
147
+ console.log(`\n📦 Document values count: ${allDocumentValues.length}`);
148
+
149
+ // Step 6: Location-based operations for contained items
150
+ console.log('\n\nStep 6: Location-based operations');
151
+ console.log('---------------------------------');
152
+
153
+ // Get comments for specific document (using location filtering)
154
+ const doc1Comments = commentCacheMap.allIn([{ kt: 'document' as const, lk: doc1.id }] as any);
155
+
156
+ console.log(`🔍 Location-based retrieval:`);
157
+ console.log(` 💬 Comments in document "${doc1.title}": ${doc1Comments.length} found`);
158
+ doc1Comments.forEach(comment => console.log(` - "${comment.content}" by ${comment.author}`));
159
+
160
+ // Step 7: Update operations
161
+ console.log('\n\nStep 7: Update operations');
162
+ console.log('------------------------');
163
+
164
+ // Update an existing document
165
+ const updatedDoc1 = {
166
+ ...doc1,
167
+ title: 'Getting Started with Fjell - Updated',
168
+ tags: [...doc1.tags, 'updated'],
169
+ events: { ...doc1.events, updated: { at: new Date() } }
170
+ };
171
+
172
+ documentCacheMap.set(updatedDoc1.key, updatedDoc1);
173
+ const retrievedUpdatedDoc = documentCacheMap.get(updatedDoc1.key);
174
+
175
+ console.log(`🔄 Updated document:`);
176
+ console.log(` 📄 New title: "${retrievedUpdatedDoc?.title}"`);
177
+ console.log(` 🏷️ New tags: ${retrievedUpdatedDoc?.tags.join(', ')}`);
178
+
179
+ // Step 8: Deletion operations
180
+ console.log('\n\nStep 8: Deletion operations');
181
+ console.log('--------------------------');
182
+
183
+ // Delete a specific item
184
+ documentCacheMap.delete(doc3.key);
185
+ console.log(`🗑️ Deleted document: doc-3`);
186
+ console.log(` 📄 Documents remaining: ${documentCacheMap.values().length}`);
187
+
188
+ // Try to get deleted item
189
+ const deletedDocCheck = documentCacheMap.get(doc3.key);
190
+ console.log(` 🔍 Deleted document still exists: ${deletedDocCheck !== null}`);
191
+
192
+ // Step 9: Performance and statistics
193
+ console.log('\n\nStep 9: Performance and statistics');
194
+ console.log('---------------------------------');
195
+
196
+ console.log(`📊 CacheMap Statistics:`);
197
+ console.log(` 📄 Document CacheMap:`);
198
+ console.log(` - Items: ${documentCacheMap.values().length}`);
199
+ console.log(` - Keys: ${documentCacheMap.keys().length}`);
200
+ console.log(` - Values: ${documentCacheMap.values().length}`);
201
+
202
+ console.log(` 💬 Comment CacheMap:`);
203
+ console.log(` - Items: ${commentCacheMap.values().length}`);
204
+ console.log(` - Keys: ${commentCacheMap.keys().length}`);
205
+ console.log(` - Values: ${commentCacheMap.values().length}`);
206
+
207
+ // Performance test - bulk operations
208
+ const startTime = Date.now();
209
+ for (let i = 0; i < 1000; i++) {
210
+ const tempDoc = createDocument(`temp-${i}`, `Temp Doc ${i}`, 'Content', 'Author', ['temp']);
211
+ documentCacheMap.set(tempDoc.key, tempDoc);
212
+ }
213
+ const insertTime = Date.now() - startTime;
214
+
215
+ console.log(`\n⚡ Performance test:`);
216
+ console.log(` 📥 Inserted 1000 items in ${insertTime}ms`);
217
+ console.log(` 📊 Total documents: ${documentCacheMap.values().length}`);
218
+
219
+ // Clean up performance test data
220
+ const cleanupStart = Date.now();
221
+ for (let i = 0; i < 1000; i++) {
222
+ documentCacheMap.delete({ kt: 'document', pk: `temp-${i}` });
223
+ }
224
+ const cleanupTime = Date.now() - cleanupStart;
225
+
226
+ console.log(` 🧹 Cleaned up 1000 items in ${cleanupTime}ms`);
227
+ console.log(` 📊 Documents after cleanup: ${documentCacheMap.values().length}`);
228
+
229
+ // Step 10: Clone operations
230
+ console.log('\n\nStep 10: Clone operations');
231
+ console.log('------------------------');
232
+
233
+ // Clone the cache map
234
+ const clonedDocumentCache = documentCacheMap.clone();
235
+ console.log(`📋 Cloned document cache:`);
236
+ console.log(` 📄 Original cache: ${documentCacheMap.values().length} items`);
237
+ console.log(` 📄 Cloned cache: ${clonedDocumentCache.values().length} items`);
238
+
239
+ // Modify original to show independence
240
+ const newDoc = createDocument('doc-clone-test', 'Clone Test Doc', 'Testing cloning', 'Test Author', ['test']);
241
+ documentCacheMap.set(newDoc.key, newDoc);
242
+
243
+ console.log(`\n📊 After adding to original:`);
244
+ console.log(` 📄 Original cache: ${documentCacheMap.values().length} items`);
245
+ console.log(` 📄 Cloned cache: ${clonedDocumentCache.values().length} items`);
246
+ console.log(` ✅ Clones are independent`);
247
+
248
+ console.log('\n🎉 CacheMap Example Complete!');
249
+ console.log('=============================\n');
250
+
251
+ console.log('Key concepts demonstrated:');
252
+ console.log('• Direct CacheMap instantiation and management');
253
+ console.log('• Primary key and composite key operations');
254
+ console.log('• Bulk operations (allIn, values, keys)');
255
+ console.log('• Location-based filtering for contained items');
256
+ console.log('• Update and delete operations');
257
+ console.log('• Performance characteristics');
258
+ console.log('• Key normalization and comparison');
259
+ console.log('• Cache cloning and independence\n');
260
+ };
261
+
262
+ // Run the example if this file is executed directly
263
+ if (import.meta.url === `file://${process.argv[1]}`) {
264
+ runCacheMapExample().catch(console.error);
265
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fjell/cache",
3
3
  "description": "Cache for Fjell",
4
- "version": "4.6.5",
4
+ "version": "4.6.10",
5
5
  "keywords": [
6
6
  "cache",
7
7
  "fjell"
@@ -19,30 +19,31 @@
19
19
  }
20
20
  },
21
21
  "dependencies": {
22
- "@fjell/client-api": "^4.4.5",
23
- "@fjell/core": "^4.4.6",
24
- "@fjell/http-api": "^4.4.4",
25
- "@fjell/logging": "^4.4.6"
22
+ "@fjell/client-api": "^4.4.7",
23
+ "@fjell/core": "^4.4.7",
24
+ "@fjell/http-api": "^4.4.5",
25
+ "@fjell/logging": "^4.4.7",
26
+ "@fjell/registry": "^4.4.7"
26
27
  },
27
28
  "devDependencies": {
28
29
  "@eslint/eslintrc": "^3.3.1",
29
- "@eslint/js": "^9.30.1",
30
- "@swc/core": "^1.12.11",
30
+ "@eslint/js": "^9.31.0",
31
+ "@swc/core": "^1.13.1",
31
32
  "@tsconfig/recommended": "^1.0.10",
32
33
  "@types/multer": "^2.0.0",
33
- "@types/node": "^24.0.12",
34
- "@typescript-eslint/eslint-plugin": "^8.36.0",
35
- "@typescript-eslint/parser": "^8.36.0",
34
+ "@types/node": "^24.0.15",
35
+ "@typescript-eslint/eslint-plugin": "^8.37.0",
36
+ "@typescript-eslint/parser": "^8.37.0",
36
37
  "@vitest/coverage-v8": "^3.2.4",
37
38
  "@vitest/ui": "^3.2.4",
38
39
  "concurrently": "^9.2.0",
39
- "eslint": "^9.30.1",
40
+ "eslint": "^9.31.0",
40
41
  "nodemon": "^3.1.10",
41
42
  "rimraf": "^6.0.1",
42
43
  "ts-node": "^10.9.2",
43
44
  "tsc-alias": "^1.8.16",
44
45
  "typescript": "^5.8.3",
45
- "vite": "^7.0.3",
46
+ "vite": "^7.0.5",
46
47
  "vite-plugin-dts": "^4.5.4",
47
48
  "vite-plugin-node": "^7.0.0",
48
49
  "vitest": "^3.2.4"
package/vitest.config.ts CHANGED
@@ -21,7 +21,7 @@ export default defineConfig({
21
21
  thresholds: {
22
22
  lines: 89,
23
23
  functions: 85,
24
- branches: 94,
24
+ branches: 93,
25
25
  statements: 89,
26
26
  },
27
27
  },
@@ -41,4 +41,4 @@ export default defineConfig({
41
41
  build: {
42
42
  sourcemap: true,
43
43
  },
44
- })
44
+ })
@@ -1,66 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
-
5
- const logger$1 = require('./logger.cjs.js');
6
-
7
- function _define_property(obj, key, value) {
8
- if (key in obj) {
9
- Object.defineProperty(obj, key, {
10
- value: value,
11
- enumerable: true,
12
- configurable: true,
13
- writable: true
14
- });
15
- } else {
16
- obj[key] = value;
17
- }
18
- return obj;
19
- }
20
- const logger = logger$1.default.get('CacheRegistry');
21
- class CacheRegistry {
22
- constructor(){
23
- // TODO: My use of Generics has Boxed me into a corner where I can't reference AbstractCache without the types
24
- _define_property(this, "cacheMap", {});
25
- _define_property(this, "registerCache", async (cache)=>{
26
- try {
27
- logger.debug('Attempting to register cache with pkTypes:', cache.pkTypes);
28
- const key = JSON.stringify(cache.pkTypes);
29
- if (this.cacheMap[key]) {
30
- logger.debug(`Cache with pkTypes ${key} already exists, will be overwritten`);
31
- }
32
- this.cacheMap[key] = cache;
33
- logger.debug('Cache registered successfully with key:', key);
34
- } catch (error) {
35
- logger.error('Failed to register cache:', error);
36
- throw error;
37
- }
38
- });
39
- _define_property(this, "getCache", (kts)=>{
40
- logger.debug('Attempting to get cache for key types:', kts);
41
- const key = JSON.stringify(kts);
42
- logger.debug('Looking up cache with key:', key);
43
- const cache = this.cacheMap[key];
44
- if (!cache) {
45
- logger.warning(`No cache found for key types: ${key}`);
46
- }
47
- return cache;
48
- });
49
- _define_property(this, "printRegisteredCaches", ()=>{
50
- logger.debug('Printing all registered caches:');
51
- const cacheCount = Object.keys(this.cacheMap).length;
52
- logger.debug(`Total number of registered caches: ${cacheCount}`);
53
- if (cacheCount === 0) {
54
- logger.debug('No caches are currently registered');
55
- }
56
- Object.entries(this.cacheMap).forEach(([keyTypes])=>{
57
- logger.debug(`Cache with key types: ${keyTypes}`);
58
- });
59
- });
60
- logger.debug('CacheRegistry instance created');
61
- }
62
- }
63
- _define_property(CacheRegistry, "instance", void 0);
64
-
65
- exports.CacheRegistry = CacheRegistry;
66
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2FjaGVSZWdpc3RyeS5janMuanMiLCJzb3VyY2VzIjpbXSwic291cmNlc0NvbnRlbnQiOltdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7In0=
@@ -1,10 +0,0 @@
1
- import { Item } from '@fjell/core';
2
- import { Cache } from './Cache';
3
- export declare class CacheRegistry {
4
- private static instance;
5
- constructor();
6
- private cacheMap;
7
- registerCache: <S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(cache: Cache<Item<S, L1, L2, L3, L4, L5>, S, L1, L2, L3, L4, L5>) => Promise<void>;
8
- getCache: (kts: string[]) => any;
9
- printRegisteredCaches: () => void;
10
- }