interaqt 0.3.0 → 0.3.1

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 (35) hide show
  1. package/agent/.claude/agents/code-generation-handler.md +2 -0
  2. package/agent/.claude/agents/computation-generation-handler.md +1 -0
  3. package/agent/.claude/agents/implement-design-handler.md +4 -13
  4. package/agent/.claude/agents/requirements-analysis-handler.md +46 -14
  5. package/agent/agentspace/knowledge/generator/api-reference.md +3378 -0
  6. package/agent/agentspace/knowledge/generator/basic-interaction-generation.md +377 -0
  7. package/agent/agentspace/knowledge/generator/computation-analysis.md +307 -0
  8. package/agent/agentspace/knowledge/generator/computation-implementation.md +959 -0
  9. package/agent/agentspace/knowledge/generator/data-analysis.md +463 -0
  10. package/agent/agentspace/knowledge/generator/entity-relation-generation.md +395 -0
  11. package/agent/agentspace/knowledge/generator/permission-implementation.md +460 -0
  12. package/agent/agentspace/knowledge/generator/permission-test-implementation.md +870 -0
  13. package/agent/agentspace/knowledge/generator/test-implementation.md +674 -0
  14. package/agent/agentspace/knowledge/usage/00-mindset-shift.md +322 -0
  15. package/agent/agentspace/knowledge/usage/01-core-concepts.md +131 -0
  16. package/agent/agentspace/knowledge/usage/02-define-entities-properties.md +407 -0
  17. package/agent/agentspace/knowledge/usage/03-entity-relations.md +599 -0
  18. package/agent/agentspace/knowledge/usage/04-reactive-computations.md +2186 -0
  19. package/agent/agentspace/knowledge/usage/05-interactions.md +1411 -0
  20. package/agent/agentspace/knowledge/usage/06-attributive-permissions.md +10 -0
  21. package/agent/agentspace/knowledge/usage/07-payload-parameters.md +593 -0
  22. package/agent/agentspace/knowledge/usage/08-activities.md +863 -0
  23. package/agent/agentspace/knowledge/usage/09-filtered-entities.md +784 -0
  24. package/agent/agentspace/knowledge/usage/10-async-computations.md +734 -0
  25. package/agent/agentspace/knowledge/usage/11-global-dictionaries.md +942 -0
  26. package/agent/agentspace/knowledge/usage/12-data-querying.md +1033 -0
  27. package/agent/agentspace/knowledge/usage/13-testing.md +1201 -0
  28. package/agent/agentspace/knowledge/usage/14-api-reference.md +1606 -0
  29. package/agent/agentspace/knowledge/usage/15-entity-crud-patterns.md +1122 -0
  30. package/agent/agentspace/knowledge/usage/16-frontend-page-design-guide.md +485 -0
  31. package/agent/agentspace/knowledge/usage/17-performance-optimization.md +283 -0
  32. package/agent/agentspace/knowledge/usage/18-api-exports-reference.md +176 -0
  33. package/agent/agentspace/knowledge/usage/19-common-anti-patterns.md +563 -0
  34. package/agent/agentspace/knowledge/usage/README.md +148 -0
  35. package/package.json +1 -1
@@ -0,0 +1,942 @@
1
+ # 10. How to Use Global Dictionaries
2
+
3
+ Global dictionaries are an important mechanism in the interaqt framework for managing global state and configuration. They provide a declarative way to define and maintain system-level data that can be referenced and reacted to by other components throughout the application.
4
+
5
+ ## 10.1 Understanding Dictionary Concepts
6
+
7
+ ### 10.1.1 Global State Management
8
+
9
+ Global dictionaries provide a centralized state management solution:
10
+
11
+ ```typescript
12
+ // Traditional global state management problems
13
+ let globalConfig = {
14
+ maxUsers: 1000,
15
+ maintenanceMode: false,
16
+ currentTheme: 'light'
17
+ };
18
+
19
+ // Problem: Need to manually notify all dependents when state changes
20
+ function updateConfig(key: string, value: any) {
21
+ globalConfig[key] = value;
22
+ // Need to manually notify all dependent components ❌
23
+ notifyAllComponents();
24
+ }
25
+
26
+ // Reactive solution using dictionaries
27
+ const maxUsersDict = Dictionary.create({
28
+ name: 'maxUsers',
29
+ type: 'number',
30
+ collection: false
31
+ });
32
+
33
+ const maintenanceModeDict = Dictionary.create({
34
+ name: 'maintenanceMode',
35
+ type: 'boolean',
36
+ collection: false
37
+ });
38
+
39
+ // ✅ When dictionary values change, all dependent computations automatically update
40
+ ```
41
+
42
+ ### 10.1.2 Dictionary vs Entity
43
+
44
+ Main differences between dictionaries and entities:
45
+
46
+ | Feature | Dictionary | Entity |
47
+ |---------|------------|--------|
48
+ | **Scope** | Globally unique | Can have multiple instances |
49
+ | **Storage Location** | `state` table | Dedicated entity table |
50
+ | **Identification** | By name | By ID |
51
+ | **Relationship Support** | No relationships | Supports complex relationships |
52
+ | **Purpose** | Global config, statistics | Business data |
53
+
54
+ ```typescript
55
+ // Dictionary: Globally unique configuration
56
+ const systemConfig = Dictionary.create({
57
+ name: 'systemConfig',
58
+ type: 'object',
59
+ collection: false
60
+ });
61
+
62
+ // Entity: Can have multiple user instances
63
+ const userEntity = Entity.create({
64
+ name: 'User',
65
+ properties: [
66
+ Property.create({name: 'username', type: 'string'})
67
+ ]
68
+ });
69
+ ```
70
+
71
+ ### 10.1.3 Use Cases
72
+
73
+ Global dictionaries are suitable for:
74
+
75
+ - **System Configuration**: Application settings, feature flags
76
+ - **Global Statistics**: Total users, total sales
77
+ - **Cached Data**: Frequently accessed computation results
78
+ - **Status Flags**: Maintenance mode, system status
79
+ - **External Data**: Local cache of third-party API data
80
+
81
+ ## 10.2 Defining Dictionaries
82
+
83
+ ### 10.2.1 Basic Dictionary Definition
84
+
85
+ ```typescript
86
+ import { Dictionary } from 'interaqt';
87
+
88
+ // Define system configuration dictionary
89
+ const systemConfig = Dictionary.create({
90
+ name: 'systemConfig', // Dictionary name, globally unique
91
+ type: 'object', // Data type
92
+ collection: false, // Whether it's a collection type
93
+ args: { // Type parameters (optional)
94
+ maxLength: 1000
95
+ }
96
+ });
97
+
98
+ // Define total user count statistics
99
+ const totalUsers = Dictionary.create({
100
+ name: 'totalUsers',
101
+ type: 'number',
102
+ collection: false
103
+ });
104
+
105
+ // Define system tags list
106
+ const systemTags = Dictionary.create({
107
+ name: 'systemTags',
108
+ type: 'string',
109
+ collection: true // Collection type, stores string array
110
+ });
111
+ ```
112
+
113
+ ### 10.2.2 Supported Data Types
114
+
115
+ ```typescript
116
+ // String type
117
+ const appName = Dictionary.create({
118
+ name: 'appName',
119
+ type: 'string',
120
+ collection: false
121
+ });
122
+
123
+ // Number type
124
+ const version = Dictionary.create({
125
+ name: 'version',
126
+ type: 'number',
127
+ collection: false
128
+ });
129
+
130
+ // Boolean type
131
+ const isMaintenanceMode = Dictionary.create({
132
+ name: 'isMaintenanceMode',
133
+ type: 'boolean',
134
+ collection: false
135
+ });
136
+
137
+ // Object type
138
+ const appSettings = Dictionary.create({
139
+ name: 'appSettings',
140
+ type: 'object',
141
+ collection: false
142
+ });
143
+
144
+ // Collection type
145
+ const supportedLanguages = Dictionary.create({
146
+ name: 'supportedLanguages',
147
+ type: 'string',
148
+ collection: true
149
+ });
150
+
151
+ const dailyStats = Dictionary.create({
152
+ name: 'dailyStats',
153
+ type: 'object',
154
+ collection: true
155
+ });
156
+ ```
157
+
158
+ ### 10.2.3 Dictionary Naming Conventions
159
+
160
+ ```typescript
161
+ // ✅ Good naming examples
162
+ const userCount = Dictionary.create({
163
+ name: 'userCount', // Camel case
164
+ type: 'number',
165
+ collection: false
166
+ });
167
+
168
+ const systemConfig = Dictionary.create({
169
+ name: 'sysConfig', // Concise and clear
170
+ type: 'object',
171
+ collection: false
172
+ });
173
+
174
+ // ❌ Naming patterns to avoid
175
+ const dict1 = Dictionary.create({
176
+ name: 'dict1', // Unclear name
177
+ type: 'string',
178
+ collection: false
179
+ });
180
+
181
+ const user_total_count = Dictionary.create({
182
+ name: 'user_total_count', // Using underscores (not recommended)
183
+ type: 'number',
184
+ collection: false
185
+ });
186
+ ```
187
+
188
+ ## 10.3 Reactive Computations with Dictionaries
189
+
190
+ ### 10.3.1 Global Statistics Based on Entities
191
+
192
+ ```typescript
193
+ // Create user entity
194
+ const userEntity = Entity.create({
195
+ name: 'User',
196
+ properties: [
197
+ Property.create({name: 'username', type: 'string'}),
198
+ Property.create({name: 'email', type: 'string'}),
199
+ Property.create({name: 'isActive', type: 'boolean'})
200
+ ]
201
+ });
202
+
203
+ // Create total user count statistics dictionary
204
+ const totalUsers = Dictionary.create({
205
+ name: 'totalUsers',
206
+ type: 'number',
207
+ collection: false,
208
+ defaultValue: () => 0,
209
+ computation: Count.create({
210
+ record: userEntity
211
+ })
212
+ });
213
+
214
+ // Create active user count statistics dictionary
215
+ const activeUsers = Dictionary.create({
216
+ name: 'activeUsers',
217
+ type: 'number',
218
+ collection: false,
219
+ defaultValue: () => 0,
220
+ computation: Count.create({
221
+ record: userEntity
222
+ })
223
+ });
224
+
225
+ // Usage example
226
+ const controller = new Controller({
227
+ system,
228
+ entities: [userEntity], // Entities
229
+ relations: [], // Relations
230
+ activities: [], // Activities
231
+ interactions: [], // Interactions
232
+ dict: [totalUsers, activeUsers], // Dictionaries
233
+ recordMutationSideEffects: [] // recordMutationSideEffects
234
+ });
235
+
236
+ await controller.setup(true);
237
+
238
+ // When creating users, statistics automatically update
239
+ await system.storage.create('User', {
240
+ username: 'alice',
241
+ email: 'alice@example.com',
242
+ isActive: true
243
+ });
244
+
245
+ // Get statistics results
246
+ const total = await system.storage.get('state', 'totalUsers');
247
+ const active = await system.storage.get('state', 'activeUsers');
248
+ console.log(`Total users: ${total}, Active users: ${active}`);
249
+ ```
250
+
251
+ ### 10.3.2 Global Statistics Based on Relations
252
+
253
+ ```typescript
254
+ // Create friend relation
255
+ const friendRelation = Relation.create({
256
+ name: 'Friend',
257
+ source: userEntity,
258
+ sourceProperty: 'friends',
259
+ target: userEntity,
260
+ targetProperty: 'friendOf',
261
+ type: 'n:n',
262
+ properties: [
263
+ Property.create({name: 'since', type: 'string'}),
264
+ Property.create({name: 'closeness', type: 'number'})
265
+ ]
266
+ });
267
+
268
+ // Count total friendships
269
+ const totalFriendships = Dictionary.create({
270
+ name: 'totalFriendships',
271
+ type: 'number',
272
+ collection: false,
273
+ defaultValue: () => 0,
274
+ computation: Count.create({
275
+ record: friendRelation
276
+ })
277
+ });
278
+
279
+ // Count close friendships (closeness > 8)
280
+ const closeFriendships = Dictionary.create({
281
+ name: 'closeFriendships',
282
+ type: 'number',
283
+ collection: false,
284
+ defaultValue: () => 0,
285
+ computation: Count.create({
286
+ record: friendRelation
287
+ })
288
+ });
289
+
290
+ // Calculate average closeness
291
+ const averageCloseness = Dictionary.create({
292
+ name: 'averageCloseness',
293
+ type: 'number',
294
+ collection: false,
295
+ defaultValue: () => 0,
296
+ computation: WeightedSummation.create({
297
+ record: friendRelation,
298
+ attributeQuery: ['closeness'],
299
+ callback: (friendship: any) => ({
300
+ weight: 1,
301
+ value: friendship.closeness || 0
302
+ })
303
+ })
304
+ });
305
+ ```
306
+
307
+ ### 10.3.3 Global Counting Based on Interactions
308
+
309
+ ```typescript
310
+ // Create login interaction
311
+ const loginInteraction = Interaction.create({
312
+ name: 'login',
313
+ action: Action.create({name: 'login'}),
314
+ payload: Payload.create({
315
+ items: [
316
+ PayloadItem.create({
317
+ name: 'user',
318
+ base: userEntity,
319
+ isRef: true
320
+ })
321
+ ]
322
+ })
323
+ });
324
+
325
+ // Count total logins
326
+ const totalLogins = Dictionary.create({
327
+ name: 'totalLogins',
328
+ type: 'number',
329
+ collection: false,
330
+ defaultValue: () => 0,
331
+ computation: Count.create({
332
+ record: InteractionEventEntity
333
+ })
334
+ });
335
+
336
+ // Count today's logins
337
+ const todayLogins = Dictionary.create({
338
+ name: 'todayLogins',
339
+ type: 'number',
340
+ collection: false,
341
+ defaultValue: () => 0,
342
+ computation: Count.create({
343
+ record: InteractionEventEntity
344
+ })
345
+ });
346
+ ```
347
+
348
+ ### 10.3.4 Complex Global Computations
349
+
350
+ ```typescript
351
+ // Create order entity
352
+ const orderEntity = Entity.create({
353
+ name: 'Order',
354
+ properties: [
355
+ Property.create({name: 'amount', type: 'number'}),
356
+ Property.create({name: 'status', type: 'string'}),
357
+ Property.create({name: 'createdAt', type: 'string'})
358
+ ]
359
+ });
360
+
361
+ // Use Transform for complex global statistics
362
+ const salesSummary = Dictionary.create({
363
+ name: 'salesSummary',
364
+ type: 'object',
365
+ collection: false,
366
+ defaultValue: () => ({}),
367
+ computation: Transform.create({
368
+ record: orderEntity,
369
+ attributeQuery: ['amount', 'status', 'createdAt'],
370
+ callback: (orders: any[]) => {
371
+ const completed = orders.filter(order => order.status === 'completed');
372
+ const pending = orders.filter(order => order.status === 'pending');
373
+
374
+ const totalRevenue = completed.reduce((sum, order) => sum + order.amount, 0);
375
+ const averageOrderValue = completed.length > 0 ? totalRevenue / completed.length : 0;
376
+
377
+ // Calculate monthly statistics
378
+ const monthlyStats = {};
379
+ completed.forEach(order => {
380
+ const month = new Date(order.createdAt).toISOString().slice(0, 7); // YYYY-MM
381
+ if (!monthlyStats[month]) {
382
+ monthlyStats[month] = { count: 0, revenue: 0 };
383
+ }
384
+ monthlyStats[month].count++;
385
+ monthlyStats[month].revenue += order.amount;
386
+ });
387
+
388
+ return {
389
+ totalOrders: orders.length,
390
+ completedOrders: completed.length,
391
+ pendingOrders: pending.length,
392
+ totalRevenue,
393
+ averageOrderValue,
394
+ monthlyStats,
395
+ lastUpdated: new Date().toISOString()
396
+ };
397
+ }
398
+ })
399
+ });
400
+ ```
401
+
402
+ ## 10.4 Using Dictionaries in Business Logic
403
+
404
+ ### 10.4.1 Reading Dictionary Values
405
+
406
+ ```typescript
407
+ // Basic reading
408
+ const userCount = await system.storage.get('state', 'totalUsers');
409
+ console.log(`Current user count: ${userCount}`);
410
+
411
+ // Reading object type dictionary
412
+ const salesSummary = await system.storage.get('state', 'salesSummary');
413
+ console.log(`Total revenue: ${salesSummary.totalRevenue}`);
414
+ console.log(`Average order value: ${salesSummary.averageOrderValue}`);
415
+
416
+ // Reading collection type dictionary
417
+ const supportedLanguages = await system.storage.get('state', 'supportedLanguages');
418
+ console.log(`Supported languages: ${supportedLanguages.join(', ')}`);
419
+
420
+ // Batch reading multiple dictionary values
421
+ async function getSystemStatus() {
422
+ const [userCount, activeUsers, maintenanceMode] = await Promise.all([
423
+ system.storage.get('state', 'totalUsers'),
424
+ system.storage.get('state', 'activeUsers'),
425
+ system.storage.get('state', 'maintenanceMode')
426
+ ]);
427
+
428
+ return {
429
+ userCount,
430
+ activeUsers,
431
+ maintenanceMode,
432
+ timestamp: Date.now()
433
+ };
434
+ }
435
+ ```
436
+
437
+ ### 10.4.2 Setting Dictionary Values
438
+
439
+ ```typescript
440
+ // Set simple values
441
+ await system.storage.set('state', 'maxUsers', 5000);
442
+ await system.storage.set('state', 'maintenanceMode', true);
443
+
444
+ // Set object values
445
+ await system.storage.set('state', 'systemConfig', {
446
+ theme: 'dark',
447
+ language: 'zh-CN',
448
+ notifications: true,
449
+ maxFileSize: 10 * 1024 * 1024 // 10MB
450
+ });
451
+
452
+ // Set collection values
453
+ await system.storage.set('state', 'supportedLanguages', [
454
+ 'zh-CN', 'en-US', 'ja-JP', 'ko-KR'
455
+ ]);
456
+
457
+ // Conditional setting (only set if doesn't exist)
458
+ async function setDefaultConfig() {
459
+ const existingConfig = await system.storage.get('state', 'systemConfig');
460
+ if (!existingConfig) {
461
+ await system.storage.set('state', 'systemConfig', {
462
+ theme: 'light',
463
+ language: 'en-US',
464
+ notifications: false
465
+ });
466
+ }
467
+ }
468
+ ```
469
+
470
+ ### 10.4.3 Conditional Logic Based on Dictionaries
471
+
472
+ ```typescript
473
+ // Using dictionary values for conditional logic in interactions
474
+ const createUserInteraction = Interaction.create({
475
+ name: 'createUser',
476
+ action: Action.create({name: 'createUser'}),
477
+ payload: Payload.create({
478
+ items: [
479
+ PayloadItem.create({
480
+ name: 'userData',
481
+ base: userEntity
482
+ })
483
+ ]
484
+ })
485
+ });
486
+
487
+ // Use Attributive to control permissions based on dictionary values
488
+ const MaxUsersReachedAttributive = Attributive.create({
489
+ name: 'MaxUsersNotReached',
490
+ content: async function(context: any) {
491
+ const currentUserCount = await context.system.storage.get('state', 'totalUsers');
492
+ const maxUsers = await context.system.storage.get('state', 'maxUsers');
493
+ return currentUserCount < maxUsers;
494
+ }
495
+ });
496
+
497
+ // Add dictionary-based permission control to interaction
498
+ createUserInteraction.attributives = [MaxUsersReachedAttributive];
499
+ ```
500
+
501
+ ### 10.4.4 Combining Dictionaries with Computations
502
+
503
+ ```typescript
504
+ // Create a property computation that depends on global dictionaries
505
+ const UserScoreComputed = createClass({
506
+ name: 'UserScoreComputed',
507
+ public: {
508
+ baseScore: {
509
+ type: 'number',
510
+ required: false
511
+ }
512
+ }
513
+ });
514
+
515
+ class UserScoreComputation implements DataBasedComputation {
516
+ static computationType = UserScoreComputed
517
+ static contextType = 'property' as const
518
+ state = {}
519
+ dataDeps: {[key: string]: DataDep} = {}
520
+
521
+ constructor(
522
+ public controller: Controller,
523
+ public args: KlassInstance<typeof UserScoreComputed>,
524
+ public dataContext: PropertyDataContext
525
+ ) {
526
+ // Depend on global configuration dictionary
527
+ this.dataDeps = {
528
+ globalConfig: {
529
+ type: 'global',
530
+ source: Dictionary.create({
531
+ name: 'scoringConfig',
532
+ type: 'object',
533
+ collection: false
534
+ })
535
+ }
536
+ }
537
+ }
538
+
539
+ async compute(deps: {globalConfig: any}, context: any) {
540
+ const baseScore = this.args.baseScore || 0;
541
+ const config = deps.globalConfig || {};
542
+
543
+ // Calculate user score based on global configuration
544
+ const multiplier = config.scoreMultiplier || 1;
545
+ const bonus = config.newUserBonus || 0;
546
+
547
+ return (baseScore * multiplier) + bonus;
548
+ }
549
+ }
550
+
551
+ // Export computation handler
552
+ export const UserScoreHandles = [UserScoreComputation];
553
+
554
+ // Use in user entity
555
+ userEntity.properties.push(
556
+ Property.create({
557
+ name: 'score',
558
+ type: 'number',
559
+ computation: UserScoreComputed.create({
560
+ baseScore: 100
561
+ })
562
+ })
563
+ );
564
+
565
+ // Create scoring configuration dictionary
566
+ const scoringConfig = Dictionary.create({
567
+ name: 'scoringConfig',
568
+ type: 'object',
569
+ collection: false
570
+ });
571
+
572
+ // Set configuration values
573
+ await system.storage.set('state', 'scoringConfig', {
574
+ scoreMultiplier: 1.5,
575
+ newUserBonus: 50
576
+ });
577
+ ```
578
+
579
+ ## 10.5 Advanced Dictionary Usage
580
+
581
+ ### 10.5.1 Dynamic Configuration Management
582
+
583
+ ```typescript
584
+ // Create feature flags dictionary
585
+ const featureFlags = Dictionary.create({
586
+ name: 'featureFlags',
587
+ type: 'object',
588
+ collection: false
589
+ });
590
+
591
+ // Set feature flags
592
+ await system.storage.set('state', 'featureFlags', {
593
+ enableNewUI: true,
594
+ enableBetaFeatures: false,
595
+ enableAnalytics: true,
596
+ maxUploadSize: 50 * 1024 * 1024 // 50MB
597
+ });
598
+
599
+ // Create configuration management utility class
600
+ class ConfigManager {
601
+ constructor(private system: MonoSystem) {}
602
+
603
+ async isFeatureEnabled(featureName: string): Promise<boolean> {
604
+ const flags = await this.system.storage.get('state', 'featureFlags');
605
+ return flags?.[featureName] === true;
606
+ }
607
+
608
+ async getFeatureConfig(featureName: string): Promise<any> {
609
+ const flags = await this.system.storage.get('state', 'featureFlags');
610
+ return flags?.[featureName];
611
+ }
612
+
613
+ async enableFeature(featureName: string): Promise<void> {
614
+ const flags = await this.system.storage.get('state', 'featureFlags') || {};
615
+ flags[featureName] = true;
616
+ await this.system.storage.set('state', 'featureFlags', flags);
617
+ }
618
+
619
+ async disableFeature(featureName: string): Promise<void> {
620
+ const flags = await this.system.storage.get('state', 'featureFlags') || {};
621
+ flags[featureName] = false;
622
+ await this.system.storage.set('state', 'featureFlags', flags);
623
+ }
624
+
625
+ async updateFeatureConfig(featureName: string, config: any): Promise<void> {
626
+ const flags = await this.system.storage.get('state', 'featureFlags') || {};
627
+ flags[featureName] = config;
628
+ await this.system.storage.set('state', 'featureFlags', flags);
629
+ }
630
+ }
631
+
632
+ // Use configuration manager
633
+ const configManager = new ConfigManager(system);
634
+
635
+ // Check if feature is enabled
636
+ if (await configManager.isFeatureEnabled('enableNewUI')) {
637
+ console.log('New UI is enabled');
638
+ }
639
+
640
+ // Get upload size limit
641
+ const maxUploadSize = await configManager.getFeatureConfig('maxUploadSize');
642
+ console.log(`Max upload size: ${maxUploadSize} bytes`);
643
+ ```
644
+
645
+ ### 10.5.2 Caching Mechanism
646
+
647
+ ```typescript
648
+ // Create cache dictionary
649
+ const apiCache = Dictionary.create({
650
+ name: 'apiCache',
651
+ type: 'object',
652
+ collection: false
653
+ });
654
+
655
+ // Cache manager
656
+ class CacheManager {
657
+ constructor(private system: MonoSystem, private ttl: number = 3600000) {} // Default 1 hour TTL
658
+
659
+ async get(key: string): Promise<any> {
660
+ const cache = await this.system.storage.get('state', 'apiCache') || {};
661
+ const item = cache[key];
662
+
663
+ if (!item) return null;
664
+
665
+ // Check if expired
666
+ if (Date.now() - item.timestamp > this.ttl) {
667
+ await this.delete(key);
668
+ return null;
669
+ }
670
+
671
+ return item.data;
672
+ }
673
+
674
+ async set(key: string, data: any): Promise<void> {
675
+ const cache = await this.system.storage.get('state', 'apiCache') || {};
676
+ cache[key] = {
677
+ data,
678
+ timestamp: Date.now()
679
+ };
680
+ await this.system.storage.set('state', 'apiCache', cache);
681
+ }
682
+
683
+ async delete(key: string): Promise<void> {
684
+ const cache = await this.system.storage.get('state', 'apiCache') || {};
685
+ delete cache[key];
686
+ await this.system.storage.set('state', 'apiCache', cache);
687
+ }
688
+
689
+ async clear(): Promise<void> {
690
+ await this.system.storage.set('state', 'apiCache', {});
691
+ }
692
+
693
+ async cleanup(): Promise<void> {
694
+ const cache = await this.system.storage.get('state', 'apiCache') || {};
695
+ const now = Date.now();
696
+
697
+ Object.keys(cache).forEach(key => {
698
+ if (now - cache[key].timestamp > this.ttl) {
699
+ delete cache[key];
700
+ }
701
+ });
702
+
703
+ await this.system.storage.set('state', 'apiCache', cache);
704
+ }
705
+ }
706
+
707
+ // Use cache manager
708
+ const cacheManager = new CacheManager(system, 1800000); // 30-minute TTL
709
+
710
+ // Cache API responses
711
+ async function fetchUserProfile(userId: string) {
712
+ const cacheKey = `user_profile_${userId}`;
713
+
714
+ // Try to get from cache
715
+ let profile = await cacheManager.get(cacheKey);
716
+ if (profile) {
717
+ console.log('Cache hit');
718
+ return profile;
719
+ }
720
+
721
+ // Cache miss, call API
722
+ console.log('Cache miss, fetching from API');
723
+ profile = await callExternalAPI(`/users/${userId}`);
724
+
725
+ // Store in cache
726
+ await cacheManager.set(cacheKey, profile);
727
+
728
+ return profile;
729
+ }
730
+ ```
731
+
732
+ ### 10.5.3 Real-time Statistics Dashboard
733
+
734
+ ```typescript
735
+ // Create real-time statistics dictionary
736
+ const realtimeStats = Dictionary.create({
737
+ name: 'realtimeStats',
738
+ type: 'object',
739
+ collection: false,
740
+ computation: Transform.create({
741
+ record: userEntity,
742
+ attributeQuery: ['isActive', 'createdAt', 'lastLoginAt'],
743
+ callback: (users: any[]) => {
744
+ const now = Date.now();
745
+ const oneHourAgo = now - 3600000;
746
+ const oneDayAgo = now - 86400000;
747
+ const oneWeekAgo = now - 604800000;
748
+
749
+ const activeUsers = users.filter(user => user.isActive);
750
+ const recentLogins = users.filter(user =>
751
+ user.lastLoginAt && new Date(user.lastLoginAt).getTime() > oneHourAgo
752
+ );
753
+ const newUsersToday = users.filter(user =>
754
+ new Date(user.createdAt).getTime() > oneDayAgo
755
+ );
756
+ const newUsersThisWeek = users.filter(user =>
757
+ new Date(user.createdAt).getTime() > oneWeekAgo
758
+ );
759
+
760
+ return {
761
+ totalUsers: users.length,
762
+ activeUsers: activeUsers.length,
763
+ inactiveUsers: users.length - activeUsers.length,
764
+ recentLogins: recentLogins.length,
765
+ newUsersToday: newUsersToday.length,
766
+ newUsersThisWeek: newUsersThisWeek.length,
767
+ userGrowthRate: newUsersThisWeek.length / Math.max(users.length - newUsersThisWeek.length, 1),
768
+ timestamp: now
769
+ };
770
+ }
771
+ })
772
+ });
773
+
774
+ // Dashboard data accessor
775
+ class Dashboard {
776
+ constructor(private system: MonoSystem) {}
777
+
778
+ async getRealtimeStats() {
779
+ return await this.system.storage.get('state', 'realtimeStats');
780
+ }
781
+
782
+ async getSystemHealth() {
783
+ const [stats, config, cache] = await Promise.all([
784
+ this.system.storage.get('state', 'realtimeStats'),
785
+ this.system.storage.get('state', 'systemConfig'),
786
+ this.system.storage.get('state', 'apiCache')
787
+ ]);
788
+
789
+ return {
790
+ userStats: stats,
791
+ systemConfig: config,
792
+ cacheSize: Object.keys(cache || {}).length,
793
+ lastUpdated: Date.now()
794
+ };
795
+ }
796
+
797
+ async getPerformanceMetrics() {
798
+ const stats = await this.getRealtimeStats();
799
+ const cacheHitRate = await this.calculateCacheHitRate();
800
+
801
+ return {
802
+ userEngagement: stats.recentLogins / stats.activeUsers,
803
+ growthRate: stats.userGrowthRate,
804
+ cacheHitRate,
805
+ systemLoad: await this.getSystemLoad()
806
+ };
807
+ }
808
+
809
+ private async calculateCacheHitRate(): Promise<number> {
810
+ // Cache hit rate calculation logic can be implemented here
811
+ return 0.85; // Example value
812
+ }
813
+
814
+ private async getSystemLoad(): Promise<number> {
815
+ // System load calculation logic can be implemented here
816
+ return 0.3; // Example value
817
+ }
818
+ }
819
+ ```
820
+
821
+ ## 10.6 Best Practices
822
+
823
+ ### 10.6.1 Naming and Organization
824
+
825
+ ```typescript
826
+ // ✅ Good naming examples grouped by function
827
+ const userStats = Dictionary.create({
828
+ name: 'userStats',
829
+ type: 'object',
830
+ collection: false
831
+ });
832
+
833
+ const systemConfig = Dictionary.create({
834
+ name: 'systemConfig',
835
+ type: 'object',
836
+ collection: false
837
+ });
838
+
839
+ const featureFlags = Dictionary.create({
840
+ name: 'featureFlags',
841
+ type: 'object',
842
+ collection: false
843
+ });
844
+
845
+ // ✅ Use constants to manage dictionary names
846
+ const DICT_NAMES = {
847
+ USER_STATS: 'userStats',
848
+ SYSTEM_CONFIG: 'systemConfig',
849
+ FEATURE_FLAGS: 'featureFlags',
850
+ API_CACHE: 'apiCache'
851
+ } as const;
852
+
853
+ // Use constants
854
+ const userStatsValue = await system.storage.get('state', DICT_NAMES.USER_STATS);
855
+ ```
856
+
857
+ ### 10.6.2 Type Safety
858
+
859
+ ```typescript
860
+ // Define dictionary value types
861
+ interface SystemConfig {
862
+ theme: 'light' | 'dark';
863
+ language: string;
864
+ notifications: boolean;
865
+ maxFileSize: number;
866
+ }
867
+
868
+ interface UserStats {
869
+ totalUsers: number;
870
+ activeUsers: number;
871
+ newUsersToday: number;
872
+ lastUpdated: number;
873
+ }
874
+
875
+ // Create type-safe dictionary accessor
876
+ class TypedDictionary {
877
+ constructor(private system: MonoSystem) {}
878
+
879
+ async getSystemConfig(): Promise<SystemConfig | null> {
880
+ return await this.system.storage.get('state', 'systemConfig');
881
+ }
882
+
883
+ async setSystemConfig(config: SystemConfig): Promise<void> {
884
+ await this.system.storage.set('state', 'systemConfig', config);
885
+ }
886
+
887
+ async getUserStats(): Promise<UserStats | null> {
888
+ return await this.system.storage.get('state', 'userStats');
889
+ }
890
+
891
+ async updateSystemConfig(updates: Partial<SystemConfig>): Promise<void> {
892
+ const current = await this.getSystemConfig() || {} as SystemConfig;
893
+ const updated = { ...current, ...updates };
894
+ await this.setSystemConfig(updated);
895
+ }
896
+ }
897
+ ```
898
+
899
+ ### 10.6.3 Performance Optimization
900
+
901
+ ```typescript
902
+ // Batch reading dictionary values
903
+ class DictionaryBatch {
904
+ constructor(private system: MonoSystem) {}
905
+
906
+ async getMultiple(keys: string[]): Promise<Record<string, any>> {
907
+ const promises = keys.map(key =>
908
+ this.system.storage.get('state', key).then(value => [key, value])
909
+ );
910
+
911
+ const results = await Promise.all(promises);
912
+ return Object.fromEntries(results);
913
+ }
914
+
915
+ async setMultiple(updates: Record<string, any>): Promise<void> {
916
+ const promises = Object.entries(updates).map(([key, value]) =>
917
+ this.system.storage.set('state', key, value)
918
+ );
919
+
920
+ await Promise.all(promises);
921
+ }
922
+ }
923
+
924
+ // Usage example
925
+ const batch = new DictionaryBatch(system);
926
+
927
+ // Batch reading
928
+ const configs = await batch.getMultiple([
929
+ 'systemConfig',
930
+ 'featureFlags',
931
+ 'userStats'
932
+ ]);
933
+
934
+ // Batch updating
935
+ await batch.setMultiple({
936
+ 'systemConfig': { theme: 'dark' },
937
+ 'featureFlags': { enableNewUI: true },
938
+ 'lastUpdated': Date.now()
939
+ });
940
+ ```
941
+
942
+ Global dictionaries provide the interaqt framework with powerful global state management capabilities. Through proper use of dictionaries, you can implement system configuration management, real-time statistics, caching mechanisms, and other features, providing a solid foundation for building complex reactive applications.