@cmdoss/memwal-sdk 0.6.2 → 0.7.0

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 (119) hide show
  1. package/ARCHITECTURE.md +547 -547
  2. package/BENCHMARKS.md +238 -238
  3. package/README.md +181 -181
  4. package/dist/ai-sdk/tools.d.ts +2 -2
  5. package/dist/ai-sdk/tools.js +2 -2
  6. package/dist/client/PersonalDataWallet.d.ts.map +1 -1
  7. package/dist/client/SimplePDWClient.d.ts +1 -1
  8. package/dist/client/SimplePDWClient.d.ts.map +1 -1
  9. package/dist/client/SimplePDWClient.js +16 -7
  10. package/dist/client/SimplePDWClient.js.map +1 -1
  11. package/dist/client/namespaces/EmbeddingsNamespace.d.ts +1 -1
  12. package/dist/client/namespaces/EmbeddingsNamespace.js +1 -1
  13. package/dist/client/namespaces/MemoryNamespace.d.ts +27 -0
  14. package/dist/client/namespaces/MemoryNamespace.d.ts.map +1 -1
  15. package/dist/client/namespaces/MemoryNamespace.js +104 -0
  16. package/dist/client/namespaces/MemoryNamespace.js.map +1 -1
  17. package/dist/client/namespaces/consolidated/AINamespace.d.ts +2 -2
  18. package/dist/client/namespaces/consolidated/AINamespace.js +2 -2
  19. package/dist/client/namespaces/consolidated/BlockchainNamespace.d.ts.map +1 -1
  20. package/dist/client/namespaces/consolidated/BlockchainNamespace.js +22 -2
  21. package/dist/client/namespaces/consolidated/BlockchainNamespace.js.map +1 -1
  22. package/dist/graph/GraphService.js +1 -1
  23. package/dist/graph/GraphService.js.map +1 -1
  24. package/dist/index.d.ts +3 -1
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +3 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/retrieval/MemoryRetrievalService.d.ts +31 -0
  29. package/dist/retrieval/MemoryRetrievalService.d.ts.map +1 -1
  30. package/dist/retrieval/MemoryRetrievalService.js +44 -4
  31. package/dist/retrieval/MemoryRetrievalService.js.map +1 -1
  32. package/dist/services/EmbeddingService.d.ts +28 -1
  33. package/dist/services/EmbeddingService.d.ts.map +1 -1
  34. package/dist/services/EmbeddingService.js +54 -0
  35. package/dist/services/EmbeddingService.js.map +1 -1
  36. package/dist/services/IndexManager.d.ts +5 -1
  37. package/dist/services/IndexManager.d.ts.map +1 -1
  38. package/dist/services/IndexManager.js +17 -40
  39. package/dist/services/IndexManager.js.map +1 -1
  40. package/dist/services/QueryService.js +1 -1
  41. package/dist/services/QueryService.js.map +1 -1
  42. package/dist/services/StorageService.d.ts +10 -0
  43. package/dist/services/StorageService.d.ts.map +1 -1
  44. package/dist/services/StorageService.js +13 -0
  45. package/dist/services/StorageService.js.map +1 -1
  46. package/dist/services/storage/QuiltBatchManager.d.ts +101 -1
  47. package/dist/services/storage/QuiltBatchManager.d.ts.map +1 -1
  48. package/dist/services/storage/QuiltBatchManager.js +410 -20
  49. package/dist/services/storage/QuiltBatchManager.js.map +1 -1
  50. package/dist/services/storage/index.d.ts +1 -1
  51. package/dist/services/storage/index.d.ts.map +1 -1
  52. package/dist/services/storage/index.js.map +1 -1
  53. package/dist/utils/LRUCache.d.ts +106 -0
  54. package/dist/utils/LRUCache.d.ts.map +1 -0
  55. package/dist/utils/LRUCache.js +281 -0
  56. package/dist/utils/LRUCache.js.map +1 -0
  57. package/dist/utils/index.d.ts +1 -0
  58. package/dist/utils/index.d.ts.map +1 -1
  59. package/dist/utils/index.js +2 -0
  60. package/dist/utils/index.js.map +1 -1
  61. package/dist/utils/memoryIndexOnChain.d.ts +212 -0
  62. package/dist/utils/memoryIndexOnChain.d.ts.map +1 -0
  63. package/dist/utils/memoryIndexOnChain.js +312 -0
  64. package/dist/utils/memoryIndexOnChain.js.map +1 -0
  65. package/dist/utils/rebuildIndexNode.d.ts +29 -0
  66. package/dist/utils/rebuildIndexNode.d.ts.map +1 -1
  67. package/dist/utils/rebuildIndexNode.js +366 -98
  68. package/dist/utils/rebuildIndexNode.js.map +1 -1
  69. package/dist/vector/HnswWasmService.d.ts +20 -5
  70. package/dist/vector/HnswWasmService.d.ts.map +1 -1
  71. package/dist/vector/HnswWasmService.js +73 -40
  72. package/dist/vector/HnswWasmService.js.map +1 -1
  73. package/dist/vector/IHnswService.d.ts +10 -1
  74. package/dist/vector/IHnswService.d.ts.map +1 -1
  75. package/dist/vector/IHnswService.js.map +1 -1
  76. package/dist/vector/NodeHnswService.d.ts +16 -0
  77. package/dist/vector/NodeHnswService.d.ts.map +1 -1
  78. package/dist/vector/NodeHnswService.js +84 -5
  79. package/dist/vector/NodeHnswService.js.map +1 -1
  80. package/dist/vector/createHnswService.d.ts +1 -1
  81. package/dist/vector/createHnswService.js +1 -1
  82. package/dist/vector/index.d.ts +1 -1
  83. package/dist/vector/index.js +1 -1
  84. package/package.json +157 -157
  85. package/src/access/index.ts +8 -8
  86. package/src/aggregation/index.ts +8 -8
  87. package/src/ai-sdk/tools.ts +2 -2
  88. package/src/client/SimplePDWClient.ts +23 -8
  89. package/src/client/namespaces/EmbeddingsNamespace.ts +1 -1
  90. package/src/client/namespaces/MemoryNamespace.ts +137 -0
  91. package/src/client/namespaces/consolidated/AINamespace.ts +2 -2
  92. package/src/client/namespaces/consolidated/BlockchainNamespace.ts +20 -2
  93. package/src/client/signers/DappKitSigner.ts +207 -207
  94. package/src/core/types/index.ts +1 -1
  95. package/src/generated/pdw/deps/sui/object.ts +12 -12
  96. package/src/generated/pdw/deps/sui/vec_map.ts +32 -32
  97. package/src/generated/pdw/memory.ts +1087 -1087
  98. package/src/generated/pdw/wallet.ts +123 -123
  99. package/src/generated/utils/index.ts +159 -159
  100. package/src/graph/GraphService.ts +1 -1
  101. package/src/index.ts +25 -1
  102. package/src/permissions/index.ts +9 -9
  103. package/src/retrieval/MemoryRetrievalService.ts +78 -4
  104. package/src/services/EmbeddingService.ts +66 -1
  105. package/src/services/IndexManager.ts +18 -45
  106. package/src/services/QueryService.ts +1 -1
  107. package/src/services/StorageService.ts +15 -0
  108. package/src/services/storage/QuiltBatchManager.ts +492 -22
  109. package/src/services/storage/index.ts +6 -1
  110. package/src/utils/LRUCache.ts +378 -0
  111. package/src/utils/index.ts +8 -0
  112. package/src/utils/memoryIndexOnChain.ts +507 -0
  113. package/src/utils/rebuildIndexNode.ts +453 -106
  114. package/src/vector/HnswWasmService.ts +95 -43
  115. package/src/vector/IHnswService.ts +10 -1
  116. package/src/vector/NodeHnswService.ts +103 -5
  117. package/src/vector/createHnswService.ts +1 -1
  118. package/src/vector/index.ts +1 -1
  119. package/src/wallet/index.ts +17 -17
@@ -0,0 +1,378 @@
1
+ /**
2
+ * LRUCache - Memory-efficient LRU Cache with TTL and size limits
3
+ *
4
+ * Features:
5
+ * - Least Recently Used eviction
6
+ * - Time-to-live (TTL) expiration
7
+ * - Maximum entry count limit
8
+ * - Optional memory size estimation
9
+ * - Automatic cleanup interval
10
+ */
11
+
12
+ export interface LRUCacheOptions<V> {
13
+ /** Maximum number of entries (default: 100) */
14
+ maxSize?: number;
15
+ /** Time-to-live in milliseconds (default: 30 minutes) */
16
+ ttlMs?: number;
17
+ /** Cleanup interval in milliseconds (default: 60 seconds) */
18
+ cleanupIntervalMs?: number;
19
+ /** Optional function to estimate memory size of a value */
20
+ sizeEstimator?: (value: V) => number;
21
+ /** Maximum total memory in bytes (optional, requires sizeEstimator) */
22
+ maxMemoryBytes?: number;
23
+ /** Callback when entry is evicted */
24
+ onEvict?: (key: string, value: V, reason: 'lru' | 'ttl' | 'memory' | 'manual') => void;
25
+ }
26
+
27
+ interface CacheEntry<V> {
28
+ value: V;
29
+ lastAccessed: number;
30
+ createdAt: number;
31
+ size?: number;
32
+ }
33
+
34
+ export class LRUCache<V> {
35
+ private cache: Map<string, CacheEntry<V>> = new Map();
36
+ private readonly maxSize: number;
37
+ private readonly ttlMs: number;
38
+ private readonly cleanupIntervalMs: number;
39
+ private readonly sizeEstimator?: (value: V) => number;
40
+ private readonly maxMemoryBytes?: number;
41
+ private readonly onEvict?: (key: string, value: V, reason: 'lru' | 'ttl' | 'memory' | 'manual') => void;
42
+ private cleanupTimer?: ReturnType<typeof setInterval>;
43
+ private currentMemoryBytes: number = 0;
44
+
45
+ constructor(options: LRUCacheOptions<V> = {}) {
46
+ this.maxSize = options.maxSize ?? 100;
47
+ this.ttlMs = options.ttlMs ?? 30 * 60 * 1000; // 30 minutes
48
+ this.cleanupIntervalMs = options.cleanupIntervalMs ?? 60 * 1000; // 1 minute
49
+ this.sizeEstimator = options.sizeEstimator;
50
+ this.maxMemoryBytes = options.maxMemoryBytes;
51
+ this.onEvict = options.onEvict;
52
+
53
+ this.startCleanup();
54
+ }
55
+
56
+ /**
57
+ * Get value from cache (updates last accessed time)
58
+ */
59
+ get(key: string): V | undefined {
60
+ const entry = this.cache.get(key);
61
+ if (!entry) {
62
+ return undefined;
63
+ }
64
+
65
+ // Check TTL
66
+ if (Date.now() - entry.createdAt > this.ttlMs) {
67
+ this.delete(key, 'ttl');
68
+ return undefined;
69
+ }
70
+
71
+ // Update last accessed time
72
+ entry.lastAccessed = Date.now();
73
+ return entry.value;
74
+ }
75
+
76
+ /**
77
+ * Set value in cache
78
+ */
79
+ set(key: string, value: V): void {
80
+ const now = Date.now();
81
+
82
+ // Calculate size if estimator provided
83
+ const size = this.sizeEstimator ? this.sizeEstimator(value) : undefined;
84
+
85
+ // If key exists, remove old entry first
86
+ if (this.cache.has(key)) {
87
+ this.delete(key, 'manual');
88
+ }
89
+
90
+ // Evict if necessary before adding
91
+ this.evictIfNeeded(size);
92
+
93
+ // Add new entry
94
+ const entry: CacheEntry<V> = {
95
+ value,
96
+ lastAccessed: now,
97
+ createdAt: now,
98
+ size,
99
+ };
100
+
101
+ this.cache.set(key, entry);
102
+
103
+ if (size) {
104
+ this.currentMemoryBytes += size;
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Check if key exists (without updating access time)
110
+ */
111
+ has(key: string): boolean {
112
+ const entry = this.cache.get(key);
113
+ if (!entry) {
114
+ return false;
115
+ }
116
+
117
+ // Check TTL
118
+ if (Date.now() - entry.createdAt > this.ttlMs) {
119
+ this.delete(key, 'ttl');
120
+ return false;
121
+ }
122
+
123
+ return true;
124
+ }
125
+
126
+ /**
127
+ * Delete entry from cache
128
+ */
129
+ delete(key: string, reason: 'lru' | 'ttl' | 'memory' | 'manual' = 'manual'): boolean {
130
+ const entry = this.cache.get(key);
131
+ if (!entry) {
132
+ return false;
133
+ }
134
+
135
+ if (entry.size) {
136
+ this.currentMemoryBytes -= entry.size;
137
+ }
138
+
139
+ this.cache.delete(key);
140
+
141
+ if (this.onEvict) {
142
+ this.onEvict(key, entry.value, reason);
143
+ }
144
+
145
+ return true;
146
+ }
147
+
148
+ /**
149
+ * Clear all entries
150
+ */
151
+ clear(): void {
152
+ if (this.onEvict) {
153
+ for (const [key, entry] of this.cache.entries()) {
154
+ this.onEvict(key, entry.value, 'manual');
155
+ }
156
+ }
157
+ this.cache.clear();
158
+ this.currentMemoryBytes = 0;
159
+ }
160
+
161
+ /**
162
+ * Get cache size
163
+ */
164
+ get size(): number {
165
+ return this.cache.size;
166
+ }
167
+
168
+ /**
169
+ * Get current memory usage (if sizeEstimator provided)
170
+ */
171
+ get memoryBytes(): number {
172
+ return this.currentMemoryBytes;
173
+ }
174
+
175
+ /**
176
+ * Get all keys
177
+ */
178
+ keys(): IterableIterator<string> {
179
+ return this.cache.keys();
180
+ }
181
+
182
+ /**
183
+ * Get all entries
184
+ */
185
+ entries(): IterableIterator<[string, V]> {
186
+ const self = this;
187
+ return (function* () {
188
+ for (const [key, entry] of self.cache.entries()) {
189
+ yield [key, entry.value] as [string, V];
190
+ }
191
+ })();
192
+ }
193
+
194
+ /**
195
+ * Get cache statistics
196
+ */
197
+ getStats(): {
198
+ size: number;
199
+ maxSize: number;
200
+ memoryBytes: number;
201
+ maxMemoryBytes?: number;
202
+ ttlMs: number;
203
+ oldestEntry?: number;
204
+ newestEntry?: number;
205
+ } {
206
+ let oldestEntry: number | undefined;
207
+ let newestEntry: number | undefined;
208
+
209
+ for (const entry of this.cache.values()) {
210
+ if (!oldestEntry || entry.createdAt < oldestEntry) {
211
+ oldestEntry = entry.createdAt;
212
+ }
213
+ if (!newestEntry || entry.createdAt > newestEntry) {
214
+ newestEntry = entry.createdAt;
215
+ }
216
+ }
217
+
218
+ return {
219
+ size: this.cache.size,
220
+ maxSize: this.maxSize,
221
+ memoryBytes: this.currentMemoryBytes,
222
+ maxMemoryBytes: this.maxMemoryBytes,
223
+ ttlMs: this.ttlMs,
224
+ oldestEntry,
225
+ newestEntry,
226
+ };
227
+ }
228
+
229
+ /**
230
+ * Destroy cache and cleanup resources
231
+ */
232
+ destroy(): void {
233
+ if (this.cleanupTimer) {
234
+ clearInterval(this.cleanupTimer);
235
+ this.cleanupTimer = undefined;
236
+ }
237
+ this.clear();
238
+ }
239
+
240
+ // ==================== Private Methods ====================
241
+
242
+ private startCleanup(): void {
243
+ this.cleanupTimer = setInterval(() => {
244
+ this.cleanupExpired();
245
+ }, this.cleanupIntervalMs);
246
+ }
247
+
248
+ private cleanupExpired(): void {
249
+ const now = Date.now();
250
+ const expiredKeys: string[] = [];
251
+
252
+ for (const [key, entry] of this.cache.entries()) {
253
+ if (now - entry.createdAt > this.ttlMs) {
254
+ expiredKeys.push(key);
255
+ }
256
+ }
257
+
258
+ for (const key of expiredKeys) {
259
+ this.delete(key, 'ttl');
260
+ }
261
+
262
+ if (expiredKeys.length > 0) {
263
+ console.debug(`[LRUCache] Cleaned up ${expiredKeys.length} expired entries`);
264
+ }
265
+ }
266
+
267
+ private evictIfNeeded(newEntrySize?: number): void {
268
+ // Evict by count
269
+ while (this.cache.size >= this.maxSize) {
270
+ this.evictLRU();
271
+ }
272
+
273
+ // Evict by memory (if configured)
274
+ if (this.maxMemoryBytes && newEntrySize) {
275
+ while (this.currentMemoryBytes + newEntrySize > this.maxMemoryBytes && this.cache.size > 0) {
276
+ this.evictLRU('memory');
277
+ }
278
+ }
279
+ }
280
+
281
+ private evictLRU(reason: 'lru' | 'memory' = 'lru'): void {
282
+ let oldestKey: string | null = null;
283
+ let oldestTime = Infinity;
284
+
285
+ for (const [key, entry] of this.cache.entries()) {
286
+ if (entry.lastAccessed < oldestTime) {
287
+ oldestTime = entry.lastAccessed;
288
+ oldestKey = key;
289
+ }
290
+ }
291
+
292
+ if (oldestKey) {
293
+ this.delete(oldestKey, reason);
294
+ }
295
+ }
296
+ }
297
+
298
+ /**
299
+ * Estimate memory size of common JavaScript values
300
+ */
301
+ export function estimateSize(value: unknown): number {
302
+ if (value === null || value === undefined) {
303
+ return 8;
304
+ }
305
+
306
+ if (typeof value === 'boolean') {
307
+ return 4;
308
+ }
309
+
310
+ if (typeof value === 'number') {
311
+ return 8;
312
+ }
313
+
314
+ if (typeof value === 'string') {
315
+ return value.length * 2; // UTF-16
316
+ }
317
+
318
+ if (Array.isArray(value)) {
319
+ let size = 24; // Array overhead
320
+ for (const item of value) {
321
+ size += estimateSize(item);
322
+ }
323
+ return size;
324
+ }
325
+
326
+ if (value instanceof Float32Array) {
327
+ return 24 + value.length * 4;
328
+ }
329
+
330
+ if (value instanceof Float64Array) {
331
+ return 24 + value.length * 8;
332
+ }
333
+
334
+ if (ArrayBuffer.isView(value)) {
335
+ return 24 + (value as any).byteLength;
336
+ }
337
+
338
+ if (typeof value === 'object') {
339
+ let size = 24; // Object overhead
340
+ for (const key of Object.keys(value as object)) {
341
+ size += key.length * 2; // Key
342
+ size += estimateSize((value as Record<string, unknown>)[key]); // Value
343
+ }
344
+ return size;
345
+ }
346
+
347
+ return 8; // Default
348
+ }
349
+
350
+ /**
351
+ * Estimate size of HNSW index cache entry
352
+ */
353
+ export function estimateIndexCacheSize(entry: {
354
+ vectors: Map<number, number[]>;
355
+ metadata: Map<number, unknown>;
356
+ pendingVectors?: Map<number, number[]>;
357
+ }): number {
358
+ let size = 100; // Base overhead
359
+
360
+ // Vectors: each vector is Float64 array
361
+ for (const vector of entry.vectors.values()) {
362
+ size += 24 + vector.length * 8; // Array + Float64 values
363
+ }
364
+
365
+ // Pending vectors
366
+ if (entry.pendingVectors) {
367
+ for (const vector of entry.pendingVectors.values()) {
368
+ size += 24 + vector.length * 8;
369
+ }
370
+ }
371
+
372
+ // Metadata (rough estimate)
373
+ size += entry.metadata.size * 200; // Average 200 bytes per metadata entry
374
+
375
+ return size;
376
+ }
377
+
378
+ export default LRUCache;
@@ -60,6 +60,14 @@ export {
60
60
  type RebuildIndexNodeResult,
61
61
  } from './rebuildIndexNode';
62
62
 
63
+ // LRU Cache utility with memory limits
64
+ export {
65
+ LRUCache,
66
+ estimateSize,
67
+ estimateIndexCacheSize,
68
+ type LRUCacheOptions,
69
+ } from './LRUCache';
70
+
63
71
  // Future utility exports will go here
64
72
  // export * from './crypto';
65
73
  // export * from './encoding';