mindcache 2.4.1 → 3.2.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.
@@ -1,3 +1,5 @@
1
+ import * as Y from 'yjs';
2
+
1
3
  /**
2
4
  * Access level for MindCache operations
3
5
  * - 'user': Can only manage content tags (default)
@@ -22,7 +24,7 @@ type SystemTag = 'SystemPrompt' | 'LLMRead' | 'LLMWrite' | 'protected' | 'ApplyT
22
24
  */
23
25
  interface KeyAttributes {
24
26
  /** The type of value stored */
25
- type: 'text' | 'image' | 'file' | 'json';
27
+ type: 'text' | 'image' | 'file' | 'json' | 'document';
26
28
  /** MIME type for files/images */
27
29
  contentType?: string;
28
30
  /** User-defined tags for organizing keys */
@@ -69,6 +71,26 @@ type GlobalListener = () => void;
69
71
  * Default attributes for new keys
70
72
  */
71
73
  declare const DEFAULT_KEY_ATTRIBUTES: KeyAttributes;
74
+ /**
75
+ * A single entry in the global history log
76
+ */
77
+ interface HistoryEntry {
78
+ /** Unique identifier for this history entry */
79
+ id: string;
80
+ /** Timestamp when the change occurred */
81
+ timestamp: number;
82
+ /** Keys that were affected by this change */
83
+ keysAffected?: string[];
84
+ }
85
+ /**
86
+ * History options for offline and cloud modes
87
+ */
88
+ interface HistoryOptions {
89
+ /** Max history entries to keep (default: 100) */
90
+ maxEntries?: number;
91
+ /** Save full snapshot every N entries for fast restore (default: 10) */
92
+ snapshotInterval?: number;
93
+ }
72
94
 
73
95
  /**
74
96
  * Cloud configuration options for MindCache constructor
@@ -80,6 +102,8 @@ interface MindCacheCloudOptions {
80
102
  projectId?: string;
81
103
  /** API endpoint to fetch WS token (recommended for browser) */
82
104
  tokenEndpoint?: string;
105
+ /** Function to fetch token dynamically (overrides tokenEndpoint) */
106
+ tokenProvider?: () => Promise<string>;
83
107
  /** Direct API key (server-side only, never expose in browser!) */
84
108
  apiKey?: string;
85
109
  /** WebSocket base URL (defaults to production) */
@@ -99,206 +123,179 @@ interface MindCacheIndexedDBOptions {
99
123
  * Constructor options for MindCache
100
124
  */
101
125
  interface MindCacheOptions {
102
- /** Cloud sync configuration. If omitted, runs in local-only mode. */
126
+ /** Cloud sync configuration. If omitted, runs in local-only mode. IndexedDB auto-enabled for offline support. */
103
127
  cloud?: MindCacheCloudOptions;
104
- /** IndexedDB configuration */
128
+ /** IndexedDB configuration. Ignored in cloud mode (auto-enabled). */
105
129
  indexedDB?: MindCacheIndexedDBOptions;
130
+ /** History tracking options (enabled in IndexedDB and Cloud modes) */
131
+ history?: HistoryOptions;
106
132
  /** Access level for tag operations. 'system' allows managing system tags. */
107
133
  accessLevel?: AccessLevel;
108
134
  }
109
135
  type ConnectionState$1 = 'disconnected' | 'connecting' | 'connected' | 'error';
110
136
  declare class MindCache {
111
- private stm;
137
+ doc: Y.Doc;
138
+ private rootMap;
112
139
  private listeners;
113
140
  private globalListeners;
141
+ readonly version = "3.1.0";
114
142
  private _isRemoteUpdate;
115
- /**
116
- * Normalize system tags: migrate old tags to new ones
117
- * - 'prompt' → 'SystemPrompt'
118
- * - 'readonly' → remove 'LLMWrite' (or add if not readonly)
119
- */
120
143
  private normalizeSystemTags;
121
- /**
122
- * Check if key should be visible in system prompt
123
- */
124
- private hasSystemPrompt;
125
- /**
126
- * Check if key can be read by LLM (has LLMRead or SystemPrompt)
127
- */
128
- private hasLLMRead;
129
- /**
130
- * Check if key can be written by LLM (has LLMWrite and not readonly)
131
- */
132
- private hasLLMWrite;
133
144
  private _cloudAdapter;
134
145
  private _connectionState;
135
146
  private _isLoaded;
136
147
  private _cloudConfig;
137
148
  private _accessLevel;
138
149
  private _initPromise;
150
+ private _idbProvider;
151
+ private _undoManagers;
152
+ private _globalUndoManager;
153
+ private _history;
154
+ private _historyOptions;
155
+ private _historyEnabled;
139
156
  constructor(options?: MindCacheOptions);
157
+ private getUndoManager;
140
158
  /**
141
- * Get the current access level
159
+ * Undo changes for a specific key
142
160
  */
143
- get accessLevel(): AccessLevel;
161
+ undo(key: string): void;
144
162
  /**
145
- * Check if this instance has system-level access
163
+ * Redo changes for a specific key
146
164
  */
147
- get hasSystemAccess(): boolean;
148
- private _initCloud;
149
- private _initIndexedDB;
150
- protected _getIndexedDBAdapterClass(): Promise<any>;
165
+ redo(key: string): void;
166
+ getHistory(key: string): any[];
167
+ private initGlobalUndoManager;
151
168
  /**
152
- * Get the current cloud connection state
169
+ * Undo all recent local changes (across all keys)
170
+ * Only undoes YOUR changes, not changes from other users in cloud mode
153
171
  */
154
- get connectionState(): ConnectionState$1;
172
+ undoAll(): void;
155
173
  /**
156
- * Check if data is loaded (true for local, true after sync for cloud)
174
+ * Redo previously undone local changes
157
175
  */
158
- get isLoaded(): boolean;
176
+ redoAll(): void;
159
177
  /**
160
- * Protected method to load CloudAdapter class.
161
- * Can be overridden/mocked for testing.
178
+ * Check if there are changes to undo globally
162
179
  */
163
- protected _getCloudAdapterClass(): Promise<any>;
180
+ canUndoAll(): boolean;
164
181
  /**
165
- * Check if this instance is connected to cloud
182
+ * Check if there are changes to redo globally
166
183
  */
167
- get isCloud(): boolean;
184
+ canRedoAll(): boolean;
185
+ private enableHistory;
186
+ private generateId;
168
187
  /**
169
- * Wait for initial sync to complete (or resolve immediately if already synced/local).
170
- * Useful for scripts or linear execution flows.
188
+ * Get global history of all changes (available in IndexedDB and Cloud modes)
171
189
  */
172
- waitForSync(): Promise<void>;
190
+ getGlobalHistory(): HistoryEntry[];
173
191
  /**
174
- * Disconnect from cloud (if connected)
192
+ * Check if history tracking is enabled
175
193
  */
194
+ get historyEnabled(): boolean;
195
+ /**
196
+ * Restore to a specific version (time travel)
197
+ * Note: Full implementation requires storing update binaries, which is not yet implemented.
198
+ * @returns false - not yet fully implemented
199
+ */
200
+ restoreToVersion(_versionId: string): boolean;
201
+ get accessLevel(): AccessLevel;
202
+ get hasSystemAccess(): boolean;
203
+ private _initCloud;
204
+ private _initYIndexedDB;
205
+ private _initIndexedDB;
206
+ protected _getIndexedDBAdapterClass(): Promise<any>;
207
+ get connectionState(): ConnectionState$1;
208
+ get isLoaded(): boolean;
209
+ protected _getCloudAdapterClass(): Promise<any>;
210
+ get isCloud(): boolean;
211
+ waitForSync(): Promise<void>;
176
212
  disconnect(): void;
213
+ isRemoteUpdate(): boolean;
214
+ serialize(): STM;
215
+ deserialize(data: STM): void;
177
216
  private encodeFileToBase64;
178
217
  private createDataUrl;
179
218
  private validateContentType;
180
- /** @deprecated Use get_value instead */
181
- get(key: string): any;
219
+ private injectSTM;
220
+ getAll(): STM;
182
221
  get_value(key: string, _processingStack?: Set<string>): any;
183
222
  get_attributes(key: string): KeyAttributes | undefined;
184
- set_value(key: string, value: any, attributes?: Partial<KeyAttributes>): void;
185
- _setFromRemote(key: string, value: any, attributes: KeyAttributes): void;
186
- isRemoteUpdate(): boolean;
187
- _deleteFromRemote(key: string): void;
188
- _clearFromRemote(): void;
189
- set_attributes(key: string, attributes: Partial<KeyAttributes>): boolean;
190
- set(key: string, value: any): void;
191
- set_file(key: string, file: File, attributes?: Partial<KeyAttributes>): Promise<void>;
192
- set_base64(key: string, base64Data: string, contentType: string, type?: 'image' | 'file', attributes?: Partial<KeyAttributes>): void;
193
- add_image(key: string, base64Data: string, contentType?: string, attributes?: Partial<KeyAttributes>): void;
194
- get_data_url(key: string): string | undefined;
195
- get_base64(key: string): string | undefined;
196
- has(key: string): boolean;
197
- delete(key: string): boolean;
198
- clear(): void;
199
- /**
200
- * Get keys sorted by zIndex (ascending), then by key name
201
- */
202
- private getSortedKeys;
203
- keys(): string[];
204
- values(): any[];
205
- entries(): [string, any][];
206
- size(): number;
207
- getAll(): Record<string, any>;
208
- update(newValues: Record<string, any>): void;
209
- subscribe(key: string, listener: Listener): void;
210
- unsubscribe(key: string, listener: Listener): void;
211
- subscribeToAll(listener: GlobalListener): void;
212
- unsubscribeFromAll(listener: GlobalListener): void;
213
- private notifyGlobalListeners;
214
- injectSTM(template: string, _processingStack?: Set<string>): string;
215
- getSTM(): string;
216
- getSTMObject(): Record<string, any>;
217
- getSTMForAPI(): Array<{
218
- key: string;
219
- value: any;
220
- type: string;
221
- contentType?: string;
222
- }>;
223
- getVisibleImages(): Array<{
224
- type: 'file';
225
- mediaType: string;
226
- url: string;
227
- filename?: string;
228
- }>;
229
- toJSON(): string;
230
- fromJSON(jsonString: string): void;
231
- serialize(): Record<string, STMEntry>;
232
- deserialize(data: Record<string, STMEntry>): void;
233
- get_system_prompt(): string;
234
- private findKeyFromToolName;
235
- get_aisdk_tools(): Record<string, any>;
236
- executeToolCall(toolName: string, value: any): {
237
- result: string;
238
- key: string;
239
- value: any;
240
- } | null;
241
- /**
242
- * Add a content tag to a key (user-level organization)
243
- */
244
- addTag(key: string, tag: string): boolean;
245
- /**
246
- * Remove a content tag from a key
247
- */
248
- removeTag(key: string, tag: string): boolean;
249
223
  /**
250
- * Get all content tags for a key
224
+ * Update only the attributes of a key without modifying the value.
225
+ * Useful for updating tags, permissions etc. on document type keys.
251
226
  */
252
- getTags(key: string): string[];
253
- /**
254
- * Get all unique content tags across all keys
255
- */
256
- getAllTags(): string[];
257
- /**
258
- * Check if a key has a specific content tag
259
- */
260
- hasTag(key: string, tag: string): boolean;
227
+ set_attributes(key: string, attributes: Partial<KeyAttributes>): void;
228
+ set_value(key: string, value: any, attributes?: Partial<KeyAttributes>): void;
229
+ delete_key(key: string): void;
230
+ clear(): void;
231
+ set_file(key: string, file: File, attributes?: Partial<KeyAttributes>): Promise<void>;
232
+ set_image(key: string, file: File, attributes?: Partial<KeyAttributes>): Promise<void>;
261
233
  /**
262
- * Get all keys with a specific content tag as formatted string
234
+ * Create or get a collaborative document key.
235
+ * Uses Y.Text for character-level concurrent editing.
236
+ *
237
+ * Note: This exposes Yjs Y.Text directly for editor bindings (y-quill, y-codemirror, etc.)
263
238
  */
264
- getTagged(tag: string): string;
239
+ set_document(key: string, initialText?: string, attributes?: Partial<KeyAttributes>): void;
265
240
  /**
266
- * Get all keys with a specific content tag
241
+ * Get the Y.Text object for a document key.
242
+ * Use this to bind to editors (Quill, CodeMirror, Monaco, etc.)
243
+ *
244
+ * @returns Y.Text or undefined if key doesn't exist or isn't a document
267
245
  */
268
- getKeysByTag(tag: string): string[];
246
+ get_document(key: string): Y.Text | undefined;
269
247
  /**
270
- * Add a system tag to a key (requires system access)
271
- * System tags: 'prompt', 'readonly', 'protected', 'template'
248
+ * Get plain text content of a document key.
249
+ * For collaborative editing, use get_document() and bind to an editor.
272
250
  */
273
- systemAddTag(key: string, tag: SystemTag): boolean;
251
+ get_document_text(key: string): string | undefined;
274
252
  /**
275
- * Remove a system tag from a key (requires system access)
253
+ * Insert text at a position in a document key.
276
254
  */
277
- systemRemoveTag(key: string, tag: SystemTag): boolean;
255
+ insert_text(key: string, index: number, text: string): void;
278
256
  /**
279
- * Get all system tags for a key (requires system access)
257
+ * Delete text from a document key.
280
258
  */
281
- systemGetTags(key: string): SystemTag[];
259
+ delete_text(key: string, index: number, length: number): void;
282
260
  /**
283
- * Check if a key has a specific system tag (requires system access)
261
+ * Replace all text in a document key.
262
+ * Uses diff-based updates when changes are < diffThreshold (default 80%).
263
+ * This preserves concurrent edits and provides better undo granularity.
264
+ *
265
+ * @param key - The document key
266
+ * @param newText - The new text content
267
+ * @param diffThreshold - Percentage (0-1) of change above which full replace is used (default: 0.8)
284
268
  */
285
- systemHasTag(key: string, tag: SystemTag): boolean;
269
+ replace_document_text(key: string, newText: string, diffThreshold?: number): void;
270
+ subscribe(key: string, listener: Listener): () => void;
271
+ subscribeToAll(listener: GlobalListener): () => void;
272
+ unsubscribeFromAll(listener: GlobalListener): void;
273
+ private notifyGlobalListeners;
274
+ private sanitizeKeyForTool;
275
+ private findKeyFromSanitizedTool;
286
276
  /**
287
- * Set all system tags for a key at once (requires system access)
277
+ * Generate Vercel AI SDK compatible tools for writable keys.
278
+ * For document type keys, generates additional tools: append_, insert_, edit_
288
279
  */
289
- systemSetTags(key: string, tags: SystemTag[]): boolean;
280
+ get_aisdk_tools(): Record<string, any>;
290
281
  /**
291
- * Get all keys with a specific system tag (requires system access)
282
+ * Generate a system prompt containing all visible STM keys and their values.
283
+ * Indicates which tools can be used to modify writable keys.
292
284
  */
293
- systemGetKeysByTag(tag: SystemTag): string[];
285
+ get_system_prompt(): string;
294
286
  /**
295
- * Helper to sync legacy boolean attributes from system tags
287
+ * Execute a tool call by name with the given value.
288
+ * Returns the result or null if tool not found.
296
289
  */
297
- private syncLegacyFromSystemTags;
298
- toMarkdown(): string;
299
- fromMarkdown(markdown: string): void;
290
+ executeToolCall(toolName: string, value: any): {
291
+ result: string;
292
+ key: string;
293
+ value?: any;
294
+ } | null;
295
+ _setFromRemote(_key: string, _value: any, _attributes: KeyAttributes): void;
296
+ _deleteFromRemote(_key: string): void;
297
+ _clearFromRemote(): void;
300
298
  }
301
- declare const mindcache: MindCache;
302
299
 
303
300
  /**
304
301
  * Configuration for connecting to MindCache Cloud
@@ -346,24 +343,9 @@ interface CloudAdapterEvents {
346
343
  synced: () => void;
347
344
  }
348
345
 
349
- /**
350
- * CloudAdapter connects a MindCache instance to the cloud service
351
- * for real-time sync and persistence.
352
- *
353
- * Auth flow:
354
- * 1. SDK calls POST /api/ws-token with apiKey to get short-lived token
355
- * 2. SDK connects to WebSocket with token in query string
356
- * 3. Server validates token and upgrades to WebSocket
357
- *
358
- * Usage patterns:
359
- * - apiKey: SDK fetches tokens automatically (simple, good for demos)
360
- * - tokenEndpoint: Your backend fetches tokens (secure, apiKey stays server-side)
361
- * - tokenProvider: Custom token logic (advanced)
362
- */
363
346
  declare class CloudAdapter {
364
347
  private config;
365
348
  private ws;
366
- private queue;
367
349
  private mindcache;
368
350
  private unsubscribe;
369
351
  private reconnectAttempts;
@@ -372,64 +354,20 @@ declare class CloudAdapter {
372
354
  private listeners;
373
355
  private token;
374
356
  constructor(config: CloudConfig);
375
- /**
376
- * Set auth token (short-lived, from /api/ws-token)
377
- * Call this before connect() or use setTokenProvider for auto-refresh
378
- */
379
357
  setToken(token: string): void;
380
- /**
381
- * Set a function that returns a fresh token
382
- * Used for automatic token refresh on reconnect
383
- */
384
358
  setTokenProvider(provider: () => Promise<string>): void;
385
- /**
386
- * Get current connection state
387
- */
388
359
  get state(): ConnectionState;
389
- /**
390
- * Attach to a MindCache instance and start syncing
391
- */
392
360
  attach(mc: MindCache): void;
393
- /**
394
- * Detach from the MindCache instance
395
- */
396
361
  detach(): void;
397
- /**
398
- * Fetch a short-lived WebSocket token from the API using the API key.
399
- * This keeps the API key secure by only using it for a single HTTPS request,
400
- * then using the short-lived token for the WebSocket connection.
401
- *
402
- * Supports two key formats:
403
- * - API keys: mc_live_xxx or mc_test_xxx → Bearer token
404
- * - Delegate keys: del_xxx:sec_xxx → ApiKey format
405
- */
406
362
  private fetchTokenWithApiKey;
407
- /**
408
- * Connect to the cloud service
409
- */
410
363
  connect(): Promise<void>;
411
- /**
412
- * Disconnect from the cloud service
413
- */
414
364
  disconnect(): void;
415
- /**
416
- * Push an operation to the cloud
417
- */
418
- push(op: Operation): void;
419
- /**
420
- * Add event listener
421
- */
422
365
  on<K extends keyof CloudAdapterEvents>(event: K, listener: CloudAdapterEvents[K]): void;
423
- /**
424
- * Remove event listener
425
- */
426
366
  off<K extends keyof CloudAdapterEvents>(event: K, listener: CloudAdapterEvents[K]): void;
427
367
  private emit;
428
368
  private setupWebSocket;
429
- private handleMessage;
430
- private flushQueue;
369
+ private sendBinary;
431
370
  private scheduleReconnect;
432
- private syncLocalChanges;
433
371
  }
434
372
 
435
- export { CloudAdapter as C, DEFAULT_KEY_ATTRIBUTES as D, type KeyAttributes as K, type Listener as L, MindCache as M, type Operation as O, type STM as S, type MindCacheOptions as a, type STMEntry as b, type MindCacheCloudOptions as c, type MindCacheIndexedDBOptions as d, type CloudConfig as e, type ConnectionState as f, type CloudAdapterEvents as g, type SetOperation as h, type DeleteOperation as i, type ClearOperation as j, mindcache as m };
373
+ export { CloudAdapter as C, DEFAULT_KEY_ATTRIBUTES as D, type KeyAttributes as K, type Listener as L, MindCache as M, type Operation as O, type STM as S, type MindCacheOptions as a, type STMEntry as b, type MindCacheCloudOptions as c, type MindCacheIndexedDBOptions as d, type CloudConfig as e, type ConnectionState as f, type CloudAdapterEvents as g, type SetOperation as h, type DeleteOperation as i, type ClearOperation as j };