@fjell/cache 4.6.10 → 4.6.13

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.
Files changed (81) hide show
  1. package/README.md +96 -0
  2. package/dist/Aggregator.cjs.js +26 -20
  3. package/dist/Aggregator.d.ts +17 -1
  4. package/dist/Aggregator.es.js +26 -20
  5. package/dist/Cache.cjs.js +22 -345
  6. package/dist/Cache.d.ts +25 -20
  7. package/dist/Cache.es.js +22 -346
  8. package/dist/Instance.cjs.js +7 -11
  9. package/dist/Instance.d.ts +5 -8
  10. package/dist/Instance.es.js +6 -10
  11. package/dist/InstanceFactory.cjs.js +17 -5
  12. package/dist/InstanceFactory.d.ts +3 -3
  13. package/dist/InstanceFactory.es.js +17 -5
  14. package/dist/Operations.cjs.js +43 -0
  15. package/dist/Operations.d.ts +70 -0
  16. package/dist/Operations.es.js +39 -0
  17. package/dist/index.cjs +416 -369
  18. package/dist/index.cjs.js +4 -1
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.ts +1 -0
  21. package/dist/index.es.js +3 -2
  22. package/dist/ops/action.cjs.js +28 -0
  23. package/dist/ops/action.d.ts +4 -0
  24. package/dist/ops/action.es.js +24 -0
  25. package/dist/ops/all.cjs.js +33 -0
  26. package/dist/ops/all.d.ts +4 -0
  27. package/dist/ops/all.es.js +29 -0
  28. package/dist/ops/allAction.cjs.js +35 -0
  29. package/dist/ops/allAction.d.ts +4 -0
  30. package/dist/ops/allAction.es.js +31 -0
  31. package/dist/ops/allFacet.cjs.js +22 -0
  32. package/dist/ops/allFacet.d.ts +4 -0
  33. package/dist/ops/allFacet.es.js +18 -0
  34. package/dist/ops/create.cjs.js +23 -0
  35. package/dist/ops/create.d.ts +4 -0
  36. package/dist/ops/create.es.js +19 -0
  37. package/dist/ops/facet.cjs.js +21 -0
  38. package/dist/ops/facet.d.ts +4 -0
  39. package/dist/ops/facet.es.js +17 -0
  40. package/dist/ops/find.cjs.js +26 -0
  41. package/dist/ops/find.d.ts +4 -0
  42. package/dist/ops/find.es.js +22 -0
  43. package/dist/ops/findOne.cjs.js +24 -0
  44. package/dist/ops/findOne.d.ts +4 -0
  45. package/dist/ops/findOne.es.js +20 -0
  46. package/dist/ops/get.cjs.js +38 -0
  47. package/dist/ops/get.d.ts +4 -0
  48. package/dist/ops/get.es.js +34 -0
  49. package/dist/ops/one.cjs.js +33 -0
  50. package/dist/ops/one.d.ts +4 -0
  51. package/dist/ops/one.es.js +29 -0
  52. package/dist/ops/remove.cjs.js +30 -0
  53. package/dist/ops/remove.d.ts +4 -0
  54. package/dist/ops/remove.es.js +26 -0
  55. package/dist/ops/reset.cjs.js +15 -0
  56. package/dist/ops/reset.d.ts +4 -0
  57. package/dist/ops/reset.es.js +11 -0
  58. package/dist/ops/retrieve.cjs.js +37 -0
  59. package/dist/ops/retrieve.d.ts +4 -0
  60. package/dist/ops/retrieve.es.js +33 -0
  61. package/dist/ops/set.cjs.js +71 -0
  62. package/dist/ops/set.d.ts +3 -0
  63. package/dist/ops/set.es.js +67 -0
  64. package/dist/ops/update.cjs.js +34 -0
  65. package/dist/ops/update.d.ts +4 -0
  66. package/dist/ops/update.es.js +30 -0
  67. package/docs/docs.config.ts +75 -0
  68. package/docs/index.html +18 -0
  69. package/docs/package.json +34 -0
  70. package/docs/public/README.md +96 -0
  71. package/docs/public/examples-README.md +302 -0
  72. package/docs/public/test.txt +0 -0
  73. package/docs/src/index.css +3 -0
  74. package/docs/src/main.tsx +12 -0
  75. package/docs/src/test/setup.ts +1 -0
  76. package/docs/tsconfig.node.json +15 -0
  77. package/examples/README.md +34 -39
  78. package/examples/aggregator-example.ts +9 -14
  79. package/examples/basic-cache-example.ts +18 -21
  80. package/package.json +16 -11
  81. package/vitest.config.ts +1 -1
@@ -0,0 +1,302 @@
1
+ # Fjell-Cache Examples
2
+
3
+ This directory contains examples demonstrating how to use fjell-cache for caching data models and managing complex business relationships with different patterns and complexity levels.
4
+
5
+ ## Examples
6
+
7
+ ### 1. `basic-cache-example.ts` ⭐ **Start Here!**
8
+ **Perfect for beginners!** Demonstrates the fundamental way to use fjell-cache for data caching:
9
+ - **Basic cache operations** - Create caches with coordinates and registries, use operations API
10
+ - **Simple data models** - User and Task entities with mock storage
11
+ - **Cache-as-Instance architecture** - Caches extend Instance from fjell-registry
12
+ - **Cache hits vs misses** - Understand cache behavior and performance benefits
13
+ - **Cache management** - Updates, deletions, and data consistency through operations
14
+
15
+ Great for understanding the fundamentals of fjell-cache data management.
16
+
17
+ ### 2. `aggregator-example.ts` 🏗️ **Advanced Business Relationships**
18
+ **Complete business relationship management!** Demonstrates advanced caching patterns with entity relationships:
19
+ - **Multiple interconnected models**: Customer, Order, Product, SupportTicket
20
+ - **Automatic reference population**: Orders automatically include customer data
21
+ - **Required vs optional aggregates**: Flexible relationship management
22
+ - **Complex business scenarios**: E-commerce platform with customer management
23
+ - **Performance optimization**: Cache efficiency through aggregated data
24
+
25
+ Shows how fjell-cache handles enterprise data relationship patterns.
26
+
27
+ ### 3. `cache-map-example.ts` 🔧 **Low-Level Cache Operations**
28
+ **Direct cache management!** Demonstrates lower-level CacheMap functionality:
29
+ - **Direct CacheMap usage**: Create and manage cache maps without higher-level abstractions
30
+ - **Primary and composite keys**: Handle both simple and complex key structures
31
+ - **Location-based operations**: Filter contained items by location hierarchy
32
+ - **Performance characteristics**: Bulk operations and efficiency testing
33
+ - **Cache lifecycle**: Cloning, cleanup, and memory management
34
+
35
+ Perfect for understanding the underlying cache mechanisms and advanced use cases.
36
+
37
+ ## Key Concepts Demonstrated
38
+
39
+ ### Basic Caching Operations (basic-cache-example.ts)
40
+ ```typescript
41
+ // Import fjell-cache functionality
42
+ import { createCache } from '@fjell/cache';
43
+ import { createCoordinate, createRegistry } from '@fjell/registry';
44
+ import { ClientApi } from '@fjell/client-api';
45
+
46
+ // Create a registry for cache management
47
+ const registry = createRegistry();
48
+
49
+ // Create a cache instance with API integration
50
+ const userApi = createUserApi(); // Your API implementation
51
+ const userCache = await createCache(userApi, createCoordinate('user'), registry);
52
+
53
+ // Cache is now an instance - no need for separate createInstance call
54
+ // Perform cache operations through the operations API
55
+ const [cacheMap, allUsers] = await userCache.operations.all();
56
+ const [, cachedUser] = await userCache.operations.get(userKey);
57
+ const [, retrievedUser] = await userCache.operations.retrieve(userKey); // Cache hit!
58
+
59
+ await userCache.operations.set(userKey, updatedUser);
60
+ ```
61
+
62
+ ### Advanced Aggregation (aggregator-example.ts)
63
+ ```typescript
64
+ // Create aggregated cache with relationships
65
+ const orderAggregator = await createAggregator(orderCache, {
66
+ aggregates: {
67
+ customer: { cache: customerCache, optional: false }, // Required reference
68
+ product: { cache: productCache, optional: true }, // Optional reference
69
+ },
70
+ events: {}
71
+ });
72
+
73
+ // Automatically populate related entities
74
+ const populatedOrder = await orderAggregator.populate(order);
75
+ if (populatedOrder.aggs?.customer?.item) {
76
+ const customer = populatedOrder.aggs.customer.item;
77
+ console.log(`Order for: ${customer.name} (${customer.email})`);
78
+ }
79
+
80
+ // Aggregator is now itself an instance - access operations directly
81
+ const [, orders] = await orderAggregator.all();
82
+ ```
83
+
84
+ ### Direct Cache Management (cache-map-example.ts)
85
+ ```typescript
86
+ // Create CacheMap instances directly
87
+ const documentCacheMap = new CacheMap<Document, 'document'>(['document']);
88
+ const commentCacheMap = new CacheMap<Comment, 'comment', 'document'>(['comment', 'document']);
89
+
90
+ // Basic operations
91
+ documentCacheMap.set(documentKey, document);
92
+ const retrievedDoc = documentCacheMap.get(documentKey);
93
+ const hasDoc = documentCacheMap.includesKey(documentKey);
94
+
95
+ // Bulk operations
96
+ const allDocuments = documentCacheMap.allIn([]);
97
+ const allKeys = documentCacheMap.keys();
98
+ const allValues = documentCacheMap.values();
99
+
100
+ // Location-based filtering for contained items
101
+ const commentsInDoc = commentCacheMap.allIn([{ kt: 'document', lk: documentId }]);
102
+
103
+ // Performance operations
104
+ const clonedCache = documentCacheMap.clone();
105
+ documentCacheMap.delete(documentKey);
106
+ ```
107
+
108
+ ### Data Model Patterns
109
+
110
+ #### Primary Items
111
+ - Standalone entities (User, Customer, Document)
112
+ - No location hierarchy constraints
113
+ - Simple key structure: `Item<'keyType'>`
114
+
115
+ #### Contained Items
116
+ - Nested within other entities or locations
117
+ - Multi-level location keys for organization
118
+ - Complex key structure: `Item<'keyType', 'location1', 'location2', ...>`
119
+
120
+ #### Aggregated Items
121
+ - Items with automatic reference population
122
+ - Business relationships through cache aggregation
123
+ - Performance optimized through cached references
124
+
125
+ ## Running Examples
126
+
127
+ ```bash
128
+ # Start with the basic example (recommended)
129
+ npx tsx examples/basic-cache-example.ts
130
+
131
+ # Run the aggregator example
132
+ npx tsx examples/aggregator-example.ts
133
+
134
+ # Run the cache map example
135
+ npx tsx examples/cache-map-example.ts
136
+
137
+ # Or with Node.js
138
+ node -r esbuild-register examples/basic-cache-example.ts
139
+ ```
140
+
141
+ ## Integration with Real Applications
142
+
143
+ All examples use the actual fjell-cache functionality! In production applications:
144
+
145
+ ```typescript
146
+ import { createCache, createRegistry, createInstance, createAggregator } from '@fjell/cache';
147
+ import { ClientApi } from '@fjell/client-api';
148
+
149
+ // Basic cache setup
150
+ const registry = createRegistry();
151
+
152
+ const userCache = await createCache(userApi, 'user');
153
+ const userInstance = createInstance(registry, createCoordinate('user'), userCache);
154
+
155
+ // With aggregation for business relationships
156
+ const orderAggregator = await createAggregator(orderCache, {
157
+ aggregates: {
158
+ customer: { cache: customerCache, optional: false },
159
+ items: { cache: productCache, optional: true }
160
+ },
161
+ events: {
162
+ orderUpdated: async (key, item) => {
163
+ // Custom event handling
164
+ await notifyCustomer(item);
165
+ }
166
+ }
167
+ });
168
+
169
+ // Advanced cache configuration
170
+ const options = {
171
+ cacheSize: 10000,
172
+ ttl: 3600000, // 1 hour
173
+ refreshThreshold: 0.8,
174
+ compression: true
175
+ };
176
+ ```
177
+
178
+ ## Cache Operation Types
179
+
180
+ ### Basic Operations
181
+ - **all()**: Get all items and update cache
182
+ - **get()**: Get item by key, fetch from API if not cached
183
+ - **retrieve()**: Get item by key, return null if not cached
184
+ - **set()**: Store item in cache
185
+ - **one()**: Get single item
186
+ - **find()**: Search items with finder methods
187
+
188
+ ### Aggregation Operations
189
+ - **populate()**: Automatically populate item with related entities
190
+ - **populateAggregate()**: Populate specific aggregate relationship
191
+ - **populateEvent()**: Handle population events
192
+
193
+ ### Cache Management
194
+ - **allIn()**: Get items by location (for contained items)
195
+ - **queryIn()**: Query items by location with filtering
196
+ - **clone()**: Create independent cache copy
197
+ - **delete()**: Remove item from cache
198
+ - **clear()**: Clear all cache contents
199
+
200
+ ### Business Operations
201
+ ```typescript
202
+ // Cache with business logic integration
203
+ const cache = await createCache(api, 'order', {
204
+ hooks: {
205
+ beforeGet: async (key) => { /* validation */ },
206
+ afterSet: async (key, item) => { /* notifications */ }
207
+ },
208
+ validators: {
209
+ status: (status) => ['pending', 'shipped', 'delivered'].includes(status)
210
+ },
211
+ aggregates: {
212
+ customer: customerCache,
213
+ items: productCache
214
+ }
215
+ });
216
+ ```
217
+
218
+ ## When to Use What
219
+
220
+ **Use `basic-cache-example.ts` approach when:**
221
+ - Learning fjell-cache fundamentals
222
+ - Building simple applications with caching needs
223
+ - Need basic get/set cache operations
224
+ - Working with independent data models
225
+
226
+ **Use `aggregator-example.ts` approach when:**
227
+ - Managing complex business relationships
228
+ - Need automatic population of related entities
229
+ - Building enterprise applications with interconnected data
230
+ - Require performance optimization through aggregated caching
231
+ - Working with customer/order/product type relationships
232
+
233
+ **Use `cache-map-example.ts` approach when:**
234
+ - Need direct control over cache operations
235
+ - Building custom caching solutions
236
+ - Working with contained items and location hierarchies
237
+ - Require maximum performance and minimal overhead
238
+ - Implementing cache-based data structures
239
+
240
+ ## Advanced Features
241
+
242
+ ### Cache Aggregation
243
+ ```typescript
244
+ // Complex aggregation with optional and required references
245
+ const ticketAggregator = await createAggregator(ticketCache, {
246
+ aggregates: {
247
+ customer: { cache: customerCache, optional: false }, // Always populated
248
+ order: { cache: orderCache, optional: true }, // Only if orderId exists
249
+ assignee: { cache: userCache, optional: true } // Only if assigned
250
+ },
251
+ events: {
252
+ ticketAssigned: async (key, ticket) => {
253
+ await notifyAssignee(ticket);
254
+ }
255
+ }
256
+ });
257
+
258
+ // Automatic population includes all available references
259
+ const populatedTicket = await ticketAggregator.populate(ticket);
260
+ ```
261
+
262
+ ### Performance Optimization
263
+ ```typescript
264
+ // Cache with coordinate and registry
265
+ const cache = await createCache(api, createCoordinate('product'), registry);
266
+
267
+ // Bulk operations for efficiency
268
+ const [cacheMap, allProducts] = await cache.operations.all();
269
+ const productMap = new Map(allProducts.map(p => [p.id, p]));
270
+
271
+ // Access cache properties for optimization
272
+ console.log(`Cache coordinate: ${cache.coordinate.kta.join(', ')}`);
273
+ console.log(`Cached items: ${cache.cacheMap.size()}`);
274
+ ```
275
+
276
+ ### Storage Integration
277
+ Fjell-cache works with any storage backend through the ClientApi interface:
278
+ - SQL databases (PostgreSQL, MySQL, SQLite)
279
+ - NoSQL databases (MongoDB, DynamoDB, Redis)
280
+ - REST APIs and GraphQL endpoints
281
+ - In-memory stores and mock data
282
+ - File systems and cloud storage
283
+ - Custom data sources
284
+
285
+ ### Error Handling and Resilience
286
+ ```typescript
287
+ // Cache with proper error handling through the API layer
288
+ const resilientCache = await createCache(api, createCoordinate('user'), registry);
289
+
290
+ // Error handling in operations
291
+ try {
292
+ const [, user] = await resilientCache.operations.get(userKey);
293
+ return user;
294
+ } catch (error) {
295
+ // Handle cache errors gracefully
296
+ console.error('Cache operation failed:', error);
297
+ // Fallback to direct API call
298
+ return await api.get(userKey);
299
+ }
300
+ ```
301
+
302
+ This provides the foundation for building scalable, maintainable applications with intelligent caching using fjell-cache.
File without changes
@@ -0,0 +1,3 @@
1
+ /* Custom styles for fjell-cache docs */
2
+
3
+ /* Additional styles can be added here to customize the cache theme */
@@ -0,0 +1,12 @@
1
+ import React from 'react'
2
+ import ReactDOM from 'react-dom/client'
3
+ import { DocsApp } from '@fjell/docs-template'
4
+ import '@fjell/docs-template/dist/index.css'
5
+ import config from '../docs.config'
6
+ import './index.css'
7
+
8
+ ReactDOM.createRoot(document.getElementById('root')!).render(
9
+ <React.StrictMode>
10
+ <DocsApp config={config} />
11
+ </React.StrictMode>
12
+ )
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom'
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "composite": true,
4
+ "skipLibCheck": true,
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "allowSyntheticDefaultImports": true,
8
+ "strict": true,
9
+ "noEmit": true
10
+ },
11
+ "include": [
12
+ "vite.config.ts",
13
+ "docs.config.ts"
14
+ ]
15
+ }
@@ -6,11 +6,11 @@ This directory contains examples demonstrating how to use fjell-cache for cachin
6
6
 
7
7
  ### 1. `basic-cache-example.ts` ⭐ **Start Here!**
8
8
  **Perfect for beginners!** Demonstrates the fundamental way to use fjell-cache for data caching:
9
- - **Basic cache operations** - Create caches, get/set items, manage cache lifecycle
9
+ - **Basic cache operations** - Create caches with coordinates and registries, use operations API
10
10
  - **Simple data models** - User and Task entities with mock storage
11
- - **Registry and Instance creation** - Set up cache model instances
11
+ - **Cache-as-Instance architecture** - Caches extend Instance from fjell-registry
12
12
  - **Cache hits vs misses** - Understand cache behavior and performance benefits
13
- - **Cache management** - Updates, deletions, and data consistency
13
+ - **Cache management** - Updates, deletions, and data consistency through operations
14
14
 
15
15
  Great for understanding the fundamentals of fjell-cache data management.
16
16
 
@@ -39,7 +39,8 @@ Perfect for understanding the underlying cache mechanisms and advanced use cases
39
39
  ### Basic Caching Operations (basic-cache-example.ts)
40
40
  ```typescript
41
41
  // Import fjell-cache functionality
42
- import { createCache, createRegistry, createInstance } from '@fjell/cache';
42
+ import { createCache } from '@fjell/cache';
43
+ import { createCoordinate, createRegistry } from '@fjell/registry';
43
44
  import { ClientApi } from '@fjell/client-api';
44
45
 
45
46
  // Create a registry for cache management
@@ -47,17 +48,15 @@ const registry = createRegistry();
47
48
 
48
49
  // Create a cache instance with API integration
49
50
  const userApi = createUserApi(); // Your API implementation
50
- const userCache = await createCache(userApi, 'user');
51
-
52
- // Create cache model instance
53
- const userInstance = createInstance(registry, createCoordinate('user'), userCache);
51
+ const userCache = await createCache(userApi, createCoordinate('user'), registry);
54
52
 
55
- // Perform cache operations
56
- const [cacheMap, allUsers] = await userInstance.cache.all();
57
- const [, cachedUser] = await userInstance.cache.get(userKey);
58
- const [, retrievedUser] = await userInstance.cache.retrieve(userKey); // Cache hit!
53
+ // Cache is now an instance - no need for separate createInstance call
54
+ // Perform cache operations through the operations API
55
+ const [cacheMap, allUsers] = await userCache.operations.all();
56
+ const [, cachedUser] = await userCache.operations.get(userKey);
57
+ const [, retrievedUser] = await userCache.operations.retrieve(userKey); // Cache hit!
59
58
 
60
- await userInstance.cache.set(userKey, updatedUser);
59
+ await userCache.operations.set(userKey, updatedUser);
61
60
  ```
62
61
 
63
62
  ### Advanced Aggregation (aggregator-example.ts)
@@ -78,8 +77,8 @@ if (populatedOrder.aggs?.customer?.item) {
78
77
  console.log(`Order for: ${customer.name} (${customer.email})`);
79
78
  }
80
79
 
81
- // Create aggregated cache instance
82
- const orderInstance = createInstance(registry, createCoordinate('order'), orderAggregator);
80
+ // Aggregator is now itself an instance - access operations directly
81
+ const [, orders] = await orderAggregator.all();
83
82
  ```
84
83
 
85
84
  ### Direct Cache Management (cache-map-example.ts)
@@ -262,18 +261,16 @@ const populatedTicket = await ticketAggregator.populate(ticket);
262
261
 
263
262
  ### Performance Optimization
264
263
  ```typescript
265
- // Cache with performance tuning
266
- const cache = await createCache(api, 'product', {
267
- batchSize: 100, // Batch operations
268
- prefetch: true, // Prefetch related items
269
- compression: true, // Compress cached data
270
- ttl: 3600000, // 1 hour cache lifetime
271
- maxSize: 10000 // Maximum cached items
272
- });
264
+ // Cache with coordinate and registry
265
+ const cache = await createCache(api, createCoordinate('product'), registry);
273
266
 
274
267
  // Bulk operations for efficiency
275
- const [cacheMap, allProducts] = await cache.all();
268
+ const [cacheMap, allProducts] = await cache.operations.all();
276
269
  const productMap = new Map(allProducts.map(p => [p.id, p]));
270
+
271
+ // Access cache properties for optimization
272
+ console.log(`Cache coordinate: ${cache.coordinate.kta.join(', ')}`);
273
+ console.log(`Cached items: ${cache.cacheMap.size()}`);
277
274
  ```
278
275
 
279
276
  ### Storage Integration
@@ -287,21 +284,19 @@ Fjell-cache works with any storage backend through the ClientApi interface:
287
284
 
288
285
  ### Error Handling and Resilience
289
286
  ```typescript
290
- // Cache with error handling
291
- const resilientCache = await createCache(api, 'user', {
292
- fallback: async (key) => {
293
- // Fallback to secondary storage
294
- return await secondaryStorage.get(key);
295
- },
296
- retryPolicy: {
297
- attempts: 3,
298
- backoff: 'exponential'
299
- },
300
- circuit: {
301
- failureThreshold: 5,
302
- resetTimeout: 30000
303
- }
304
- });
287
+ // Cache with proper error handling through the API layer
288
+ const resilientCache = await createCache(api, createCoordinate('user'), registry);
289
+
290
+ // Error handling in operations
291
+ try {
292
+ const [, user] = await resilientCache.operations.get(userKey);
293
+ return user;
294
+ } catch (error) {
295
+ // Handle cache errors gracefully
296
+ console.error('Cache operation failed:', error);
297
+ // Fallback to direct API call
298
+ return await api.get(userKey);
299
+ }
305
300
  ```
306
301
 
307
302
  This provides the foundation for building scalable, maintainable applications with intelligent caching using fjell-cache.
@@ -128,6 +128,7 @@ const createSupportTicket = (
128
128
  priority: 'low' | 'medium' | 'high' | 'urgent',
129
129
  status: 'open' | 'in-progress' | 'resolved' | 'closed',
130
130
  description: string,
131
+ // eslint-disable-next-line max-params
131
132
  orderId?: string): SupportTicket => {
132
133
  const ticket: SupportTicket = {
133
134
  id, customerId, subject, priority, status, description, orderId,
@@ -181,10 +182,10 @@ export const runAggregatorExample = async (): Promise<void> => {
181
182
  const productApi = createMockApi(mockProducts) as ClientApi<Product, 'product'>;
182
183
  const ticketApi = createMockApi(mockTickets) as ClientApi<SupportTicket, 'ticket'>;
183
184
 
184
- const customerCache = await createCache(customerApi, 'customer');
185
- const orderCache = await createCache(orderApi, 'order');
186
- const productCache = await createCache(productApi, 'product');
187
- const ticketCache = await createCache(ticketApi, 'ticket');
185
+ const customerCache = await createCache(customerApi, createCoordinate('customer'), registry);
186
+ const orderCache = await createCache(orderApi, createCoordinate('order'), registry);
187
+ const productCache = await createCache(productApi, createCoordinate('product'), registry);
188
+ const ticketCache = await createCache(ticketApi, createCoordinate('ticket'), registry);
188
189
 
189
190
  console.log('✅ Created individual caches for each entity type');
190
191
 
@@ -209,19 +210,13 @@ export const runAggregatorExample = async (): Promise<void> => {
209
210
  events: {}
210
211
  });
211
212
 
212
- console.log('✅ Created aggregated caches with relationship mappings');
213
-
214
- // Create instances for easier management
215
- const orderInstance = createInstance(registry, createCoordinate('order'), orderAggregator);
216
- const ticketInstance = createInstance(registry, createCoordinate('ticket'), ticketAggregator);
217
-
218
- console.log('✅ Created aggregated cache instances\n');
213
+ console.log('✅ Created aggregated caches with relationship mappings (aggregators are now instances)\n');
219
214
 
220
215
  // Step 4: Basic aggregation - Fetch orders with customer data
221
216
  console.log('Step 4: Order aggregation with customer data');
222
217
  console.log('--------------------------------------------');
223
218
 
224
- const [, orders] = await orderInstance.cache.all();
219
+ const [, orders] = await orderAggregator.all();
225
220
  console.log(`📋 Fetched ${orders.length} orders`);
226
221
 
227
222
  for (const order of orders) {
@@ -243,7 +238,7 @@ export const runAggregatorExample = async (): Promise<void> => {
243
238
  console.log('\n\nStep 5: Support ticket aggregation with multiple references');
244
239
  console.log('----------------------------------------------------------');
245
240
 
246
- const [, tickets] = await ticketInstance.cache.all();
241
+ const [, tickets] = await ticketAggregator.all();
247
242
  console.log(`🎫 Fetched ${tickets.length} support tickets`);
248
243
 
249
244
  for (const ticket of tickets) {
@@ -275,7 +270,7 @@ export const runAggregatorExample = async (): Promise<void> => {
275
270
  console.log('\n\nStep 6: Individual item retrieval with aggregation');
276
271
  console.log('-------------------------------------------------');
277
272
 
278
- const [, specificOrder] = await orderInstance.cache.get(order1.key);
273
+ const [, specificOrder] = await orderAggregator.get(order1.key);
279
274
  if (specificOrder) {
280
275
  console.log(`🔍 Retrieved specific order: ${specificOrder.id}`);
281
276
 
@@ -146,12 +146,9 @@ export const runBasicCacheExample = async (): Promise<void> => {
146
146
  const taskApi = createTaskApi() as ClientApi<Task, 'task'>;
147
147
  console.log('✅ Created mock APIs for users and tasks');
148
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);
149
+ const userCache = await createCache(userApi, createCoordinate('user'), registry);
150
+ const taskCache = await createCache(taskApi, createCoordinate('task'), registry);
151
+ console.log('✅ Created cache instances (which are now also instances)');
155
152
  console.log('✅ Created cache model instances\n');
156
153
 
157
154
  // Step 2: Create some test data
@@ -170,21 +167,21 @@ export const runBasicCacheExample = async (): Promise<void> => {
170
167
  console.log('Step 3: Cache operations - Fetching all items');
171
168
  console.log('----------------------------------------------');
172
169
 
173
- const [, allUsers] = await userInstance.cache.all();
174
- console.log(`📋 Cached ${allUsers.length} users:`, allUsers.map(u => u.name));
170
+ const [, allUsers] = await userCache.operations.all();
171
+ console.log(`📋 Cached ${allUsers.length} users:`, allUsers.map((u: User) => u.name));
175
172
 
176
- const [, allTasks] = await taskInstance.cache.all();
177
- console.log(`📋 Cached ${allTasks.length} tasks:`, allTasks.map(t => t.title));
173
+ const [, allTasks] = await taskCache.operations.all();
174
+ console.log(`📋 Cached ${allTasks.length} tasks:`, allTasks.map((t: Task) => t.title));
178
175
  console.log('');
179
176
 
180
177
  // Step 4: Individual item retrieval from cache
181
178
  console.log('Step 4: Individual item retrieval');
182
179
  console.log('---------------------------------');
183
180
 
184
- const [, cachedUser1] = await userInstance.cache.get(user1.key);
181
+ const [, cachedUser1] = await userCache.operations.get(user1.key);
185
182
  console.log(`👤 Retrieved from cache: ${cachedUser1?.name} (${cachedUser1?.email})`);
186
183
 
187
- const [, cachedTask1] = await taskInstance.cache.get(task1.key);
184
+ const [, cachedTask1] = await taskCache.operations.get(task1.key);
188
185
  console.log(`📝 Retrieved from cache: ${cachedTask1?.title} - Status: ${cachedTask1?.status}`);
189
186
  console.log('');
190
187
 
@@ -194,14 +191,14 @@ export const runBasicCacheExample = async (): Promise<void> => {
194
191
 
195
192
  // This should hit the cache (no API call)
196
193
  console.log('🎯 Second retrieval (should hit cache):');
197
- const [, cachedUser1Again] = await userInstance.cache.retrieve(user1.key);
194
+ const [, cachedUser1Again] = await userCache.operations.retrieve(user1.key);
198
195
  console.log(`👤 Retrieved: ${cachedUser1Again?.name} (cache hit)`);
199
196
 
200
197
  // Create a new user and demonstrate cache miss
201
198
  const user3 = createTestUser('user-3', 'Charlie Brown', 'charlie@example.com', 'guest');
202
199
 
203
200
  console.log('🎯 New item retrieval (cache miss, will fetch from API):');
204
- const [, cachedUser3] = await userInstance.cache.get(user3.key);
201
+ const [, cachedUser3] = await userCache.operations.get(user3.key);
205
202
  console.log(`👤 Retrieved: ${cachedUser3?.name} (fetched from API and cached)`);
206
203
  console.log('');
207
204
 
@@ -213,7 +210,7 @@ export const runBasicCacheExample = async (): Promise<void> => {
213
210
  mockTaskStorage.set(task2.id, updatedTask2);
214
211
 
215
212
  // Update cache with new version
216
- await taskInstance.cache.set(updatedTask2.key, updatedTask2);
213
+ await taskCache.operations.set(updatedTask2.key, updatedTask2);
217
214
  console.log(`🔄 Updated task in cache: ${updatedTask2.title} - New status: ${updatedTask2.status}`);
218
215
  console.log('');
219
216
 
@@ -221,10 +218,10 @@ export const runBasicCacheExample = async (): Promise<void> => {
221
218
  console.log('Step 7: Query operations');
222
219
  console.log('-----------------------');
223
220
 
224
- const [, foundTasks] = await taskInstance.cache.find('all');
221
+ const [, foundTasks] = await taskCache.operations.find('all');
225
222
  console.log(`🔍 Found ${foundTasks.length} tasks through cache query`);
226
223
 
227
- const [, oneTask] = await taskInstance.cache.one();
224
+ const [, oneTask] = await taskCache.operations.one();
228
225
  console.log(`📝 Retrieved one task: ${oneTask?.title}`);
229
226
  console.log('');
230
227
 
@@ -235,8 +232,8 @@ export const runBasicCacheExample = async (): Promise<void> => {
235
232
  console.log('📊 Cache Statistics:');
236
233
  console.log(` 👥 Users in cache: ${allUsers.length}`);
237
234
  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]}`);
235
+ console.log(` 🎯 User cache coordinate: ${userCache.coordinate.kta[0]}`);
236
+ console.log(` 🎯 Task cache coordinate: ${taskCache.coordinate.kta[0]}`);
240
237
  console.log('');
241
238
 
242
239
  // Step 9: Cleanup demonstration
@@ -247,11 +244,11 @@ export const runBasicCacheExample = async (): Promise<void> => {
247
244
  console.log('🗑️ Removed user from storage');
248
245
 
249
246
  // Cache still has the old data until next fetch
250
- const [, stillCachedUser3] = await userInstance.cache.retrieve(user3.key);
247
+ const [, stillCachedUser3] = await userCache.operations.retrieve(user3.key);
251
248
  console.log(`🎯 Cache still contains removed user: ${stillCachedUser3?.name || 'null'}`);
252
249
 
253
250
  // Fresh fetch will update cache
254
- const [, freshAllUsers] = await userInstance.cache.all();
251
+ const [, freshAllUsers] = await userCache.operations.all();
255
252
  console.log(`📋 Fresh fetch shows ${freshAllUsers.length} users (cache updated)`);
256
253
  console.log('');
257
254