@asaidimu/utils-workspace 2.0.0 → 2.1.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.
- package/README.md +283 -249
- package/index.d.mts +684 -204
- package/index.d.ts +684 -204
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/package.json +5 -1
package/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { QueryFilter, PaginationOptions } from '@asaidimu/query';
|
|
2
|
+
import { SchemaDefinition, SchemaChange, DataTransform } from '@asaidimu/anansi';
|
|
3
|
+
|
|
1
4
|
type UUID = string;
|
|
2
5
|
type Timestamp = string;
|
|
3
6
|
type URI = string;
|
|
@@ -29,7 +32,7 @@ type WorkspaceError = {
|
|
|
29
32
|
};
|
|
30
33
|
interface Settings {
|
|
31
34
|
language: string;
|
|
32
|
-
defaultRole
|
|
35
|
+
defaultRole?: string;
|
|
33
36
|
prompt?: string;
|
|
34
37
|
}
|
|
35
38
|
interface Project {
|
|
@@ -61,8 +64,7 @@ type ResolvedBlob = {
|
|
|
61
64
|
};
|
|
62
65
|
/**
|
|
63
66
|
* Full registry entry for a blob. BlobRef is a Pick of this type, so
|
|
64
|
-
* a BlobRecord is always assignable to BlobRef.
|
|
65
|
-
* removed — callers that previously used BlobSummary use BlobRecord directly.
|
|
67
|
+
* a BlobRecord is always assignable to BlobRef.
|
|
66
68
|
*/
|
|
67
69
|
interface BlobRecord {
|
|
68
70
|
sha256: SHA256;
|
|
@@ -124,11 +126,26 @@ interface Turn {
|
|
|
124
126
|
role: TurnRole;
|
|
125
127
|
blocks: ContentBlock[];
|
|
126
128
|
timestamp: Timestamp;
|
|
129
|
+
/**
|
|
130
|
+
* The name of the role active when this turn was recorded.
|
|
131
|
+
* Snapshot so history is stable even if the role is later renamed.
|
|
132
|
+
*/
|
|
127
133
|
roleSnapshot?: string;
|
|
134
|
+
/**
|
|
135
|
+
* Parent pointer. Null for root turns.
|
|
136
|
+
* This is plain data stored on the document — the DAG is reconstructed
|
|
137
|
+
* in memory by TurnTree.buildNodeGraph() at session open time.
|
|
138
|
+
*/
|
|
128
139
|
parent: {
|
|
129
140
|
id: UUID;
|
|
130
141
|
version: number;
|
|
131
142
|
} | null;
|
|
143
|
+
/**
|
|
144
|
+
* Partition key. Stored on the Turn document so Collection.filter
|
|
145
|
+
* can retrieve all turns for a session in a single query.
|
|
146
|
+
* Not present on Turn objects used purely in memory (e.g. dirty buffer).
|
|
147
|
+
*/
|
|
148
|
+
sessionId?: UUID;
|
|
132
149
|
}
|
|
133
150
|
interface TurnNode {
|
|
134
151
|
id: UUID;
|
|
@@ -145,63 +162,53 @@ interface TurnNode {
|
|
|
145
162
|
children: Record<number, UUID[]>;
|
|
146
163
|
}
|
|
147
164
|
interface BranchInfo {
|
|
148
|
-
/** All sibling versions at this level, in insertion order. */
|
|
149
165
|
versions: number[];
|
|
150
|
-
/** Index of this turn within siblings (0-based). */
|
|
151
166
|
currentIndex: number;
|
|
152
|
-
/** Convenience: number of siblings (siblings.length). */
|
|
153
167
|
total: number;
|
|
154
|
-
/** True when there is a branch to the left. */
|
|
155
168
|
hasPrev: boolean;
|
|
156
|
-
/** True when there is a branch to the right. */
|
|
157
169
|
hasNext: boolean;
|
|
158
170
|
}
|
|
159
|
-
interface
|
|
171
|
+
interface Role {
|
|
160
172
|
name: string;
|
|
161
173
|
label: string;
|
|
162
174
|
description?: string;
|
|
163
|
-
|
|
175
|
+
persona: string;
|
|
176
|
+
preferences: UUID[];
|
|
164
177
|
}
|
|
165
|
-
interface
|
|
178
|
+
interface Preference {
|
|
166
179
|
id: UUID;
|
|
180
|
+
content: string;
|
|
167
181
|
topics: string[];
|
|
168
182
|
timestamp: Timestamp;
|
|
169
|
-
snippet?: string;
|
|
170
183
|
}
|
|
171
|
-
|
|
184
|
+
type ContextContent = {
|
|
185
|
+
kind: 'text';
|
|
186
|
+
value: string;
|
|
187
|
+
} | {
|
|
188
|
+
kind: 'json';
|
|
189
|
+
value: unknown;
|
|
190
|
+
} | {
|
|
191
|
+
kind: 'blob';
|
|
192
|
+
sha256: SHA256;
|
|
193
|
+
mediaType: BlobMediaType;
|
|
194
|
+
sizeBytes: number;
|
|
195
|
+
filename?: string;
|
|
196
|
+
} | {
|
|
197
|
+
kind: 'remote';
|
|
198
|
+
uri: URI;
|
|
199
|
+
mediaType?: BlobMediaType;
|
|
200
|
+
};
|
|
201
|
+
interface Context {
|
|
172
202
|
key: string;
|
|
173
203
|
topics: string[];
|
|
204
|
+
content: ContextContent;
|
|
174
205
|
timestamp: Timestamp;
|
|
175
|
-
mime?: string;
|
|
176
|
-
size?: number;
|
|
177
|
-
preview?: string;
|
|
178
|
-
source?: string;
|
|
179
206
|
metadata?: Record<string, any>;
|
|
180
207
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
metadata?: {
|
|
186
|
-
created?: Timestamp;
|
|
187
|
-
updated?: Timestamp;
|
|
188
|
-
entries?: number;
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
interface Workspace {
|
|
192
|
-
id: UUID;
|
|
193
|
-
settings: Settings;
|
|
194
|
-
project: Project;
|
|
195
|
-
index: Index;
|
|
196
|
-
}
|
|
197
|
-
interface Index {
|
|
198
|
-
format: string;
|
|
199
|
-
roles: Record<string, RoleSummary>;
|
|
200
|
-
preferences: Record<UUID, PreferenceSummary>;
|
|
201
|
-
context: Record<string, ContextSummary>;
|
|
202
|
-
sessions: Record<UUID, SessionMeta>;
|
|
203
|
-
topics: Record<string, TopicIndex>;
|
|
204
|
-
}
|
|
208
|
+
/**
|
|
209
|
+
* SessionMeta is stored as a document in the 'session' collection.
|
|
210
|
+
* The head pointer lives here — no separate session_heads store needed.
|
|
211
|
+
*/
|
|
205
212
|
interface SessionMeta {
|
|
206
213
|
id: UUID;
|
|
207
214
|
label: string;
|
|
@@ -218,69 +225,64 @@ interface SessionMeta {
|
|
|
218
225
|
version: number;
|
|
219
226
|
} | null;
|
|
220
227
|
}
|
|
221
|
-
interface
|
|
222
|
-
id: UUID;
|
|
228
|
+
interface RoleSummary {
|
|
223
229
|
name: string;
|
|
224
230
|
label: string;
|
|
225
|
-
persona: string;
|
|
226
231
|
description?: string;
|
|
227
|
-
|
|
232
|
+
/** Number of preference IDs listed on the role. */
|
|
233
|
+
preferences: number;
|
|
228
234
|
}
|
|
229
|
-
interface
|
|
235
|
+
interface PreferenceSummary {
|
|
230
236
|
id: UUID;
|
|
231
|
-
content: string;
|
|
232
237
|
topics: string[];
|
|
233
238
|
timestamp: Timestamp;
|
|
239
|
+
snippet?: string;
|
|
234
240
|
}
|
|
235
|
-
interface
|
|
241
|
+
interface ContextSummary {
|
|
236
242
|
key: string;
|
|
237
|
-
content: ContextContent;
|
|
238
243
|
topics: string[];
|
|
239
244
|
timestamp: Timestamp;
|
|
245
|
+
mime?: string;
|
|
246
|
+
size?: number;
|
|
247
|
+
preview?: string;
|
|
248
|
+
source?: string;
|
|
240
249
|
metadata?: Record<string, any>;
|
|
241
|
-
remoteIds?: Record<string, string>;
|
|
242
|
-
refCount?: number;
|
|
243
250
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
} | {
|
|
248
|
-
kind: 'json';
|
|
249
|
-
value: object;
|
|
250
|
-
} | {
|
|
251
|
-
kind: 'blob';
|
|
252
|
-
} & BlobRef | {
|
|
253
|
-
kind: 'remote';
|
|
254
|
-
uri: URI;
|
|
255
|
-
mediaType: BlobMediaType;
|
|
256
|
-
};
|
|
257
|
-
interface Session$1 {
|
|
258
|
-
id: UUID;
|
|
259
|
-
label: string;
|
|
260
|
-
role: string;
|
|
261
|
-
topics: string[];
|
|
251
|
+
interface TopicIndex {
|
|
252
|
+
topic: string;
|
|
253
|
+
contextKeys: string[];
|
|
262
254
|
preferences: UUID[];
|
|
263
|
-
|
|
264
|
-
metadata: {
|
|
255
|
+
metadata?: {
|
|
265
256
|
created?: Timestamp;
|
|
266
257
|
updated?: Timestamp;
|
|
258
|
+
entries?: number;
|
|
267
259
|
};
|
|
268
260
|
}
|
|
261
|
+
interface Index {
|
|
262
|
+
roles: Record<string, RoleSummary>;
|
|
263
|
+
preferences: Record<UUID, PreferenceSummary>;
|
|
264
|
+
context: Record<string, ContextSummary>;
|
|
265
|
+
sessions: Record<UUID, SessionMeta>;
|
|
266
|
+
topics: Record<string, TopicIndex>;
|
|
267
|
+
blobs: Record<SHA256, BlobRecord>;
|
|
268
|
+
}
|
|
269
|
+
interface Workspace {
|
|
270
|
+
id: UUID;
|
|
271
|
+
settings: Settings;
|
|
272
|
+
project: Project;
|
|
273
|
+
index: Index;
|
|
274
|
+
}
|
|
269
275
|
interface WorkspaceBundle {
|
|
270
276
|
format: 'aiworkspace/4.0';
|
|
271
277
|
workspace: Workspace;
|
|
272
278
|
roles: Record<string, Role>;
|
|
273
279
|
preferences: Record<UUID, Preference>;
|
|
274
280
|
context: Record<string, Context>;
|
|
275
|
-
sessions: Record<UUID,
|
|
281
|
+
sessions: Record<UUID, SessionMeta & {
|
|
282
|
+
turns: Turn[];
|
|
283
|
+
}>;
|
|
276
284
|
blobs: Record<SHA256, BlobRecord>;
|
|
277
285
|
}
|
|
278
|
-
interface TranscriptWindow {
|
|
279
|
-
sessionId: UUID;
|
|
280
|
-
turns: Turn[];
|
|
281
|
-
flushedCount: number;
|
|
282
|
-
hasMore: boolean;
|
|
283
|
-
}
|
|
284
286
|
interface EffectiveSession {
|
|
285
287
|
session: SessionMeta;
|
|
286
288
|
role: Role;
|
|
@@ -293,7 +295,6 @@ interface CacheConfig {
|
|
|
293
295
|
roles?: number;
|
|
294
296
|
preferences?: number;
|
|
295
297
|
context?: number;
|
|
296
|
-
transcriptWindows?: number;
|
|
297
298
|
}
|
|
298
299
|
interface FlushConfig {
|
|
299
300
|
maxBufferSize: number;
|
|
@@ -302,7 +303,6 @@ interface FlushConfig {
|
|
|
302
303
|
interface ContentStoreConfig {
|
|
303
304
|
cache?: CacheConfig;
|
|
304
305
|
flush?: FlushConfig;
|
|
305
|
-
transcriptWindowSize?: number;
|
|
306
306
|
}
|
|
307
307
|
interface BaseCommand {
|
|
308
308
|
type: string;
|
|
@@ -452,14 +452,16 @@ interface DeleteSession extends BaseCommand {
|
|
|
452
452
|
}
|
|
453
453
|
interface RegisterBlob extends BaseCommand {
|
|
454
454
|
type: 'blob:register';
|
|
455
|
-
payload:
|
|
455
|
+
payload: {
|
|
456
|
+
data: Uint8Array;
|
|
457
|
+
mediaType: BlobMediaType;
|
|
458
|
+
filename?: string;
|
|
459
|
+
};
|
|
456
460
|
}
|
|
457
|
-
interface
|
|
458
|
-
type: 'blob:
|
|
461
|
+
interface RetainBlob extends BaseCommand {
|
|
462
|
+
type: 'blob:retain';
|
|
459
463
|
payload: {
|
|
460
464
|
sha256: SHA256;
|
|
461
|
-
providerId: string;
|
|
462
|
-
fileId: string;
|
|
463
465
|
};
|
|
464
466
|
}
|
|
465
467
|
interface ReleaseBlob extends BaseCommand {
|
|
@@ -468,7 +470,22 @@ interface ReleaseBlob extends BaseCommand {
|
|
|
468
470
|
sha256: SHA256;
|
|
469
471
|
};
|
|
470
472
|
}
|
|
471
|
-
|
|
473
|
+
interface PurgeBlob extends BaseCommand {
|
|
474
|
+
type: 'blob:purge';
|
|
475
|
+
payload: {
|
|
476
|
+
sha256: SHA256;
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
interface RecordBlobRemoteId extends BaseCommand {
|
|
480
|
+
type: 'blob:record_remote_id';
|
|
481
|
+
payload: {
|
|
482
|
+
sha256: SHA256;
|
|
483
|
+
providerId: string;
|
|
484
|
+
fileId: string;
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
type BlobCommand = RegisterBlob | RetainBlob | ReleaseBlob | PurgeBlob | RecordBlobRemoteId;
|
|
488
|
+
type Command = CreateWorkspace | AddRole | UpdateRole | DeleteRole | AddPreference | UpdatePreference | DeletePreference | CreateSession | AddContext | UpdateContext | DeleteContext | AddTurn | EditTurn | BranchTurn | DeleteTurn | SwitchRole | AddSessionTopics | OverrideSessionPreferences | ForkSession | DeleteSession | BlobCommand;
|
|
472
489
|
interface TokenBudget {
|
|
473
490
|
total: number;
|
|
474
491
|
estimator?: (text: string) => number;
|
|
@@ -486,7 +503,7 @@ interface ContextRelevanceConfig {
|
|
|
486
503
|
freshnessHalfLifeDays?: number;
|
|
487
504
|
}
|
|
488
505
|
/**
|
|
489
|
-
*
|
|
506
|
+
* Prompt.transcript.turns is Turn[].
|
|
490
507
|
* Synthetic turns produced by PromptAssembler (summary blocks, truncation
|
|
491
508
|
* notices, referential attachments) carry generated UUIDs and version 0,
|
|
492
509
|
* with parent: null. They are ephemeral — never stored, never patched.
|
|
@@ -515,35 +532,455 @@ interface Prompt {
|
|
|
515
532
|
warnings: string[];
|
|
516
533
|
conflicts: PreferenceConflict[];
|
|
517
534
|
}
|
|
535
|
+
interface TranscriptWindow {
|
|
536
|
+
sessionId: UUID;
|
|
537
|
+
turns: Turn[];
|
|
538
|
+
flushedCount: number;
|
|
539
|
+
hasMore: boolean;
|
|
540
|
+
}
|
|
518
541
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
542
|
+
declare class TransactionContext {
|
|
543
|
+
readonly id: string;
|
|
544
|
+
private buffer;
|
|
545
|
+
private committed;
|
|
546
|
+
constructor();
|
|
547
|
+
addOp(store: Store<any>, type: "put" | "delete", data: any): void;
|
|
548
|
+
commit(): Promise<void>;
|
|
549
|
+
rollback(): void;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
interface CursorCallbackResult<T> {
|
|
553
|
+
value: T | null;
|
|
554
|
+
done: boolean;
|
|
555
|
+
offset?: number;
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Callback function for cursor iteration over store records.
|
|
559
|
+
*
|
|
560
|
+
* @template T - The type of records stored.
|
|
561
|
+
* @param value - The current record value (cloned, not a live reference).
|
|
562
|
+
* @param key - The key (ID) of the current record.
|
|
563
|
+
* @param cursor - The underlying cursor object (implementation‑specific; may be `null` in memory adapters).
|
|
564
|
+
* @returns A promise that resolves to an object indicating whether iteration should stop, and an optional offset to advance.
|
|
565
|
+
*/
|
|
566
|
+
type CursorCallback<T> = (value: T, key: string | number, cursor: any) => Promise<CursorCallbackResult<T>>;
|
|
567
|
+
/**
|
|
568
|
+
* A generic representation of a key range, replacing the browser-specific IDBKeyRange.
|
|
569
|
+
*/
|
|
570
|
+
interface StoreKeyRange {
|
|
571
|
+
lower?: any;
|
|
572
|
+
upper?: any;
|
|
573
|
+
lowerOpen?: boolean;
|
|
574
|
+
upperOpen?: boolean;
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Storage adapter interface for a single object store (collection).
|
|
578
|
+
*
|
|
579
|
+
* This interface abstracts all low‑level persistence operations, allowing
|
|
580
|
+
* different backends (IndexedDB, memory, remote, etc.) to be used interchangeably.
|
|
581
|
+
* All methods return promises and operate on clones of data to prevent
|
|
582
|
+
* unintended mutations.
|
|
583
|
+
*
|
|
584
|
+
* @template T - The type of objects stored in this store. Must include the key path property.
|
|
585
|
+
*/
|
|
586
|
+
interface Store<T = any> {
|
|
587
|
+
/**
|
|
588
|
+
* Adds one or more records to the store.
|
|
589
|
+
*
|
|
590
|
+
* If a record does not have a value for the store's key path, an automatic
|
|
591
|
+
* key (e.g., auto‑incremented number) may be assigned. The store's key path
|
|
592
|
+
* property is then updated on the added record(s).
|
|
593
|
+
*
|
|
594
|
+
* @param data - A single record or an array of records to add.
|
|
595
|
+
* @returns A promise that resolves to:
|
|
596
|
+
* - the key(s) of the added record(s) – a single key if `data` was a single record,
|
|
597
|
+
* or an array of keys if `data` was an array.
|
|
598
|
+
* @throws {Error} If any record lacks the key path property and auto‑keying is not supported,
|
|
599
|
+
* or if a record with the same key already exists.
|
|
600
|
+
*/
|
|
601
|
+
add(data: T | T[]): Promise<string | number | (string | number)[]>;
|
|
602
|
+
/**
|
|
603
|
+
* Removes all records from the store.
|
|
604
|
+
*
|
|
605
|
+
* @returns A promise that resolves when the store is cleared.
|
|
606
|
+
* @throws {Error} If the operation fails (e.g., store is closed).
|
|
607
|
+
*/
|
|
608
|
+
clear(): Promise<void>;
|
|
609
|
+
/**
|
|
610
|
+
* Returns the total number of records in the store.
|
|
611
|
+
*
|
|
612
|
+
* @returns A promise that resolves to the record count.
|
|
613
|
+
* @throws {Error} If the operation fails.
|
|
614
|
+
*/
|
|
615
|
+
count(): Promise<number>;
|
|
616
|
+
/**
|
|
617
|
+
* Deletes one or more records by their keys.
|
|
618
|
+
*
|
|
619
|
+
* @param id - A single key or an array of keys to delete.
|
|
620
|
+
* @returns A promise that resolves when the records are deleted.
|
|
621
|
+
* @throws {Error} If any key is `undefined` or the operation fails.
|
|
622
|
+
*/
|
|
623
|
+
delete(id: string | number | (string | number)[]): Promise<void>;
|
|
624
|
+
/**
|
|
625
|
+
* Retrieves a single record by its primary key.
|
|
626
|
+
*
|
|
627
|
+
* @param id - The key of the record to retrieve.
|
|
628
|
+
* @returns A promise that resolves to the record (cloned) if found, otherwise `undefined`.
|
|
629
|
+
* @throws {Error} If the key is `undefined` or the operation fails.
|
|
630
|
+
*/
|
|
631
|
+
getById(id: string | number): Promise<T | undefined>;
|
|
632
|
+
/**
|
|
633
|
+
* Retrieves a single record by an index and index key.
|
|
634
|
+
*
|
|
635
|
+
* @param index - The name of the index to query.
|
|
636
|
+
* @param key - The exact key value to look up in the index.
|
|
637
|
+
* @returns A promise that resolves to the first matching record (cloned), or `undefined` if none.
|
|
638
|
+
* @throws {Error} If the index does not exist, the key is `undefined`, or the operation fails.
|
|
639
|
+
*/
|
|
640
|
+
getByIndex(index: string, key: any): Promise<T | undefined>;
|
|
641
|
+
/**
|
|
642
|
+
* Retrieves multiple records from an index, optionally within a key range.
|
|
643
|
+
*
|
|
644
|
+
* @param index - The name of the index to query.
|
|
645
|
+
* @param keyRange - Optional `StoreKeyRange` to filter results. If omitted, all records are returned.
|
|
646
|
+
* @returns A promise that resolves to an array of matching records (each cloned).
|
|
647
|
+
* @throws {Error} If the index does not exist or the operation fails.
|
|
648
|
+
*/
|
|
649
|
+
getByKeyRange(index: string, keyRange?: StoreKeyRange): Promise<T[]>;
|
|
650
|
+
/**
|
|
651
|
+
* Retrieves all records from the store.
|
|
652
|
+
*
|
|
653
|
+
* @returns A promise that resolves to an array of all records (each cloned).
|
|
654
|
+
* @throws {Error} If the operation fails.
|
|
655
|
+
*/
|
|
656
|
+
getAll(): Promise<T[]>;
|
|
657
|
+
/**
|
|
658
|
+
* Inserts or replaces a record.
|
|
659
|
+
*
|
|
660
|
+
* If a record with the same key already exists, it is replaced.
|
|
661
|
+
* The record must contain the store's key path property.
|
|
662
|
+
*
|
|
663
|
+
* @param data - The record to store.
|
|
664
|
+
* @returns A promise that resolves to the key of the stored record.
|
|
665
|
+
* @throws {Error} If the record lacks the key path property or the operation fails.
|
|
666
|
+
*/
|
|
667
|
+
put(data: T): Promise<string | number>;
|
|
668
|
+
/**
|
|
669
|
+
* Iterates over records using a cursor, allowing early termination and skipping.
|
|
670
|
+
*
|
|
671
|
+
* The callback is invoked for each record in iteration order. The callback
|
|
672
|
+
* can control the iteration by returning `{ done: true }` to stop, or
|
|
673
|
+
* `{ offset: n }` to skip ahead `n` records.
|
|
674
|
+
*
|
|
675
|
+
* @param callback - Function called for each record.
|
|
676
|
+
* @param direction - Iteration direction: `"forward"` (ascending keys) or `"backward"` (descending keys).
|
|
677
|
+
* @param keyRange - An optional StoreKeyRange to start from specific points.
|
|
678
|
+
* @returns A promise that resolves to the last record processed (or `null` if none).
|
|
679
|
+
* @throws {Error} If the callback throws or the operation fails.
|
|
680
|
+
*/
|
|
681
|
+
cursor(callback: CursorCallback<T>, direction?: "forward" | "backward", keyRange?: StoreKeyRange): Promise<T | null>;
|
|
682
|
+
/**
|
|
683
|
+
* Executes a batch of write operations atomically.
|
|
684
|
+
*
|
|
685
|
+
* All operations in the batch succeed or fail together. This is useful for
|
|
686
|
+
* maintaining consistency when multiple writes are required.
|
|
687
|
+
*
|
|
688
|
+
* @param operations - An array of operations. Each operation can be:
|
|
689
|
+
* - `{ type: "add" | "put", data: T | T[] }`
|
|
690
|
+
* - `{ type: "delete", data: string | number | (string | number)[] }`
|
|
691
|
+
* @returns A promise that resolves when the batch is committed.
|
|
692
|
+
* @throws {Error} If any operation fails or the batch cannot be completed.
|
|
693
|
+
*/
|
|
694
|
+
batch(operations: Array<{
|
|
695
|
+
type: "add" | "put";
|
|
696
|
+
data: T | T[];
|
|
697
|
+
} | {
|
|
698
|
+
type: "delete";
|
|
699
|
+
data: string | number | (string | number)[];
|
|
700
|
+
}>): Promise<void>;
|
|
701
|
+
open(): Promise<void>;
|
|
702
|
+
}
|
|
703
|
+
interface Collection<T> {
|
|
704
|
+
/**
|
|
705
|
+
* Finds a single document matching the query.
|
|
706
|
+
* @param query - The query to execute.
|
|
707
|
+
* @returns A promise resolving to the matching document or `null` if not found.
|
|
708
|
+
*/
|
|
709
|
+
find: (query: QueryFilter<T>) => Promise<Document<T> | null>;
|
|
710
|
+
/**
|
|
711
|
+
* Lists documents based on the provided query.
|
|
712
|
+
* @param query - The query to list documents (supports pagination and sorting).
|
|
713
|
+
* @returns A promise resolving to an array of documents.
|
|
714
|
+
*/
|
|
715
|
+
list: (query: PaginationOptions) => Promise<AsyncIterator<Document<T>[]>>;
|
|
716
|
+
/**
|
|
717
|
+
* Filters documents based on the provided query.
|
|
718
|
+
* @param query - The query to filter documents.
|
|
719
|
+
* @returns A promise resolving to an array of matching documents.
|
|
720
|
+
*/
|
|
721
|
+
filter: (query: QueryFilter<T>) => Promise<Document<T>[]>;
|
|
722
|
+
/**
|
|
723
|
+
* Creates a new document in the schema.
|
|
724
|
+
* @param initial - The initial data for the document.
|
|
725
|
+
* @returns A promise resolving to the created document.
|
|
726
|
+
*/
|
|
727
|
+
create: (initial: T) => Promise<Document<T>>;
|
|
728
|
+
/**
|
|
729
|
+
* Subscribes to schema-level events (e.g., "create", "update", "delete", "access").
|
|
730
|
+
* @param event - The event type to subscribe to.
|
|
731
|
+
* @param callback - The function to call when the event occurs.
|
|
732
|
+
* @returns A promise resolving to an unsubscribe function.
|
|
733
|
+
*/
|
|
734
|
+
subscribe: (event: CollectionEventType | TelemetryEventType, callback: (event: CollectionEvent<T> | TelemetryEvent) => void) => Promise<() => void>;
|
|
735
|
+
/**
|
|
736
|
+
* Validate data
|
|
737
|
+
* @param data - The data to validate
|
|
738
|
+
* @returns An object containing validation results
|
|
739
|
+
*/
|
|
740
|
+
validate(data: Record<string, any>): Promise<{
|
|
741
|
+
value?: any;
|
|
742
|
+
issues: Array<{
|
|
743
|
+
message: string;
|
|
744
|
+
path: Array<string>;
|
|
745
|
+
}>;
|
|
746
|
+
}>;
|
|
546
747
|
}
|
|
748
|
+
/**
|
|
749
|
+
* Event payload for DocumentCursor events.
|
|
750
|
+
*/
|
|
751
|
+
type CollectionEventType = "document:create" | "collection:read" | "migration:start" | "migration:end";
|
|
752
|
+
type CollectionEvent<T> = {
|
|
753
|
+
type: CollectionEventType;
|
|
754
|
+
document?: T;
|
|
755
|
+
model?: string;
|
|
756
|
+
method?: keyof Collection<T>;
|
|
757
|
+
metadata?: Record<string, unknown>;
|
|
758
|
+
timestamp: number;
|
|
759
|
+
};
|
|
760
|
+
interface Database {
|
|
761
|
+
/**
|
|
762
|
+
* Accesses a schema model by name.
|
|
763
|
+
* @param schemaName - The name of the schema to access.
|
|
764
|
+
* @returns A promise resolving to the schema's DocumentCursor.
|
|
765
|
+
* @throws DatabaseError
|
|
766
|
+
*/
|
|
767
|
+
collection: <T>(schemaName: string) => Promise<Collection<T>>;
|
|
768
|
+
/**
|
|
769
|
+
* Creates a new schema model.
|
|
770
|
+
* @param schema - The schema definition.
|
|
771
|
+
* @returns A promise resolving to the created schema's DocumentCursor.
|
|
772
|
+
* @throws DatabaseError
|
|
773
|
+
*/
|
|
774
|
+
createCollection: <T>(schema: SchemaDefinition) => Promise<Collection<T>>;
|
|
775
|
+
/**
|
|
776
|
+
* Deletes a schema by name.
|
|
777
|
+
* @param schemaName - The name of the schema to delete.
|
|
778
|
+
* @returns A promise resolving to `true` if successful, or `false` if an error occurs.
|
|
779
|
+
* @throws DatabaseError
|
|
780
|
+
*/
|
|
781
|
+
deleteCollection: (schemaName: string) => Promise<boolean>;
|
|
782
|
+
/**
|
|
783
|
+
* Updates an existing schema.
|
|
784
|
+
* @param schema - The updated schema definition.
|
|
785
|
+
* @returns A promise resolving to `true` if successful, or `false` if an error occurs.
|
|
786
|
+
* @throws DatabaseError
|
|
787
|
+
*/
|
|
788
|
+
updateCollection: (schema: SchemaDefinition) => Promise<boolean>;
|
|
789
|
+
/**
|
|
790
|
+
* Migrates an existing collection's data and updates its schema definition metadata.
|
|
791
|
+
* This function processes data in a streaming fashion to prevent loading
|
|
792
|
+
* the entire collection into memory.
|
|
793
|
+
*
|
|
794
|
+
* It will:
|
|
795
|
+
* 1. Verify the target collection exists.
|
|
796
|
+
* 2. Retrieve the collection's current schema definition from a metadata store ($index).
|
|
797
|
+
* 3. Initialize a `MigrationEngine` with this schema.
|
|
798
|
+
* 4. Allow a callback to define specific data transformations using the `MigrationEngine`.
|
|
799
|
+
* 5. **Crucially, it uses `migrationEngine.dryRun()` to get the `newSchema` that results**
|
|
800
|
+
* **from the transformations defined in the callback.**
|
|
801
|
+
* 6. Execute these transformations by streaming data from the collection,
|
|
802
|
+
* through the `MigrationEngine`, and back into the same collection.
|
|
803
|
+
* 7. Finally, update the schema definition for the collection in the `$index` metadata store
|
|
804
|
+
* to reflect this `newSchema`.
|
|
805
|
+
* All these steps for data and metadata updates happen within a single atomic IndexedDB transaction.
|
|
806
|
+
*
|
|
807
|
+
* Note: This function focuses solely on *data transformation* and *metadata updates*.
|
|
808
|
+
* It does NOT handle structural IndexedDB changes like adding/removing physical indexes or object stores,
|
|
809
|
+
* which still require an `onupgradeneeded` event (i.e., a database version upgrade).
|
|
810
|
+
*
|
|
811
|
+
* @param name - The name of the collection (IndexedDB object store) to migrate.
|
|
812
|
+
* @param {Object} opts - Options for the new migration
|
|
813
|
+
* @param {SchemaChange<any>[]} opts.changes - Array of schema changes
|
|
814
|
+
* @param {string} opts.description - Description of the migration
|
|
815
|
+
* @param {SchemaChange<any>[]} [opts.rollback] - Optional rollback changes
|
|
816
|
+
* @param {DataTransform<any, any>} [opts.transform] - Optional data transform
|
|
817
|
+
* @returns A Promise resolving to `true` if the migration completes successfully,
|
|
818
|
+
* @throws {DatabaseError} If the collection does not exist, its schema metadata is missing,
|
|
819
|
+
* or any IndexedDB operation/streaming fails critically.
|
|
820
|
+
*/
|
|
821
|
+
migrateCollection: (name: string, opts: CollectionMigrationOptions, batchSize?: number) => Promise<boolean>;
|
|
822
|
+
/**
|
|
823
|
+
* Subscribes to database-level events (e.g., "schemaAdded", "schemaDeleted", "schemaAccessed", "migrate").
|
|
824
|
+
* @param event - The event type to subscribe to.
|
|
825
|
+
* @param callback - The function to call when the event occurs.
|
|
826
|
+
* @returns A promise resolving to an unsubscribe function.
|
|
827
|
+
*/
|
|
828
|
+
subscribe: (event: DatabaseEventType | "telemetry", callback: (event: DatabaseEvent | TelemetryEvent) => void) => Promise<() => void>;
|
|
829
|
+
/**
|
|
830
|
+
* Closes the connection to the database
|
|
831
|
+
*/
|
|
832
|
+
close: () => void;
|
|
833
|
+
/**
|
|
834
|
+
* Ensures a collection exists; creates it if it doesn't.
|
|
835
|
+
* Idempotent – safe to call multiple times.
|
|
836
|
+
* @param schema - The schema definition for the collection.
|
|
837
|
+
* @returns A promise that resolves when the collection exists.
|
|
838
|
+
* @throws {DatabaseError} If validation fails or an unexpected error occurs.
|
|
839
|
+
*/
|
|
840
|
+
ensureCollection: (schema: SchemaDefinition) => Promise<void>;
|
|
841
|
+
/**
|
|
842
|
+
* Ensures multiple collections exist; creates any that don't.
|
|
843
|
+
* Idempotent – safe to call multiple times.
|
|
844
|
+
* @param schemas - An array of schema definitions.
|
|
845
|
+
* @returns A promise that resolves when all collections exist.
|
|
846
|
+
* @throws {DatabaseError} If any schema validation fails or an unexpected error occurs.
|
|
847
|
+
*/
|
|
848
|
+
setupCollections: (schemas: SchemaDefinition[]) => Promise<void>;
|
|
849
|
+
}
|
|
850
|
+
type CollectionMigrationOptions = {
|
|
851
|
+
changes: SchemaChange<any>[];
|
|
852
|
+
description: string;
|
|
853
|
+
rollback?: SchemaChange<any>[];
|
|
854
|
+
transform?: string | DataTransform<any, any>;
|
|
855
|
+
};
|
|
856
|
+
/**
|
|
857
|
+
* Event payload for Database events.
|
|
858
|
+
*/
|
|
859
|
+
type DatabaseEventType = "collection:create" | "collection:delete" | "collection:update" | "collection:read" | "migrate";
|
|
860
|
+
type DatabaseEvent = {
|
|
861
|
+
type: DatabaseEventType;
|
|
862
|
+
schema?: SchemaDefinition | Partial<SchemaDefinition>;
|
|
863
|
+
timestamp: number;
|
|
864
|
+
};
|
|
865
|
+
type Document<T> = {
|
|
866
|
+
readonly [K in keyof T]: T[K];
|
|
867
|
+
} & {
|
|
868
|
+
/**
|
|
869
|
+
* Unique identifier for the document (assigned automatically if not provided).
|
|
870
|
+
*/
|
|
871
|
+
$id?: string;
|
|
872
|
+
/**
|
|
873
|
+
* Timestamp of document creation (ISO string or Date).
|
|
874
|
+
*/
|
|
875
|
+
$created?: string | Date;
|
|
876
|
+
/**
|
|
877
|
+
* Timestamp of last document update (ISO string or Date).
|
|
878
|
+
*/
|
|
879
|
+
$updated?: string | Date;
|
|
880
|
+
/**
|
|
881
|
+
* Version number incremented on each change (used for optimistic concurrency control).
|
|
882
|
+
*/
|
|
883
|
+
$version?: number;
|
|
884
|
+
/**
|
|
885
|
+
* Fetches the latest data from the database and updates the document instance.
|
|
886
|
+
* @returns A promise resolving to `true` if successful, or `false` if an error occurs.
|
|
887
|
+
*/
|
|
888
|
+
read: () => Promise<boolean>;
|
|
889
|
+
/**
|
|
890
|
+
* Saves the current document state to the database.
|
|
891
|
+
* Normally called automatically by `update()` or `delete()`, but can be used manually.
|
|
892
|
+
* @returns A promise resolving to `true` if successful, or `false` if an error occurs.
|
|
893
|
+
*/
|
|
894
|
+
save: (tx?: TransactionContext) => Promise<boolean>;
|
|
895
|
+
/**
|
|
896
|
+
* Updates the document with the provided properties.
|
|
897
|
+
* @param props - Partial object containing the fields to update.
|
|
898
|
+
* @returns A promise resolving to `true` if successful, or `false` if an error occurs.
|
|
899
|
+
*/
|
|
900
|
+
update: (props: Partial<T>) => Promise<boolean>;
|
|
901
|
+
/**
|
|
902
|
+
* Deletes the document from the database.
|
|
903
|
+
* @returns A promise resolving to `true` if successful, or `false` if an error occurs.
|
|
904
|
+
*/
|
|
905
|
+
delete: () => Promise<boolean>;
|
|
906
|
+
/**
|
|
907
|
+
* Subscribes to document events (e.g., "update", "delete", "access").
|
|
908
|
+
* @param event - The event type to subscribe to.
|
|
909
|
+
* @param callback - The function to call when the event occurs.
|
|
910
|
+
* @returns An unsubscribe function.
|
|
911
|
+
*/
|
|
912
|
+
subscribe: (event: DocumentEventType | TelemetryEventType, callback: (event: DocumentEvent<T> | TelemetryEvent) => void) => () => void;
|
|
913
|
+
/**
|
|
914
|
+
* Returns a plain object containing only the user-defined data (without system fields like $id, $version, etc.).
|
|
915
|
+
* @returns The current user data.
|
|
916
|
+
*/
|
|
917
|
+
state(): T;
|
|
918
|
+
};
|
|
919
|
+
/**
|
|
920
|
+
* Event payload for DocumentModel events.
|
|
921
|
+
*/
|
|
922
|
+
type DocumentEventType = "document:create" | "document:write" | "document:update" | "document:delete" | "document:read";
|
|
923
|
+
type DocumentEvent<T> = {
|
|
924
|
+
type: DocumentEventType;
|
|
925
|
+
data?: Partial<T>;
|
|
926
|
+
timestamp: number;
|
|
927
|
+
};
|
|
928
|
+
type TelemetryEventType = "telemetry";
|
|
929
|
+
type TelemetryEvent = {
|
|
930
|
+
type: TelemetryEventType;
|
|
931
|
+
method: string;
|
|
932
|
+
timestamp: number;
|
|
933
|
+
source: any;
|
|
934
|
+
metadata: {
|
|
935
|
+
args: any[];
|
|
936
|
+
performance: {
|
|
937
|
+
durationMs: number;
|
|
938
|
+
};
|
|
939
|
+
source: {
|
|
940
|
+
level: "database" | "collection" | "document";
|
|
941
|
+
collection?: string;
|
|
942
|
+
document?: string;
|
|
943
|
+
};
|
|
944
|
+
result?: {
|
|
945
|
+
type: 'array' | string;
|
|
946
|
+
size?: number;
|
|
947
|
+
};
|
|
948
|
+
error: {
|
|
949
|
+
message: string;
|
|
950
|
+
name: string;
|
|
951
|
+
stack?: string;
|
|
952
|
+
} | null;
|
|
953
|
+
};
|
|
954
|
+
};
|
|
955
|
+
|
|
956
|
+
interface WorkspaceDatabase {
|
|
957
|
+
/**
|
|
958
|
+
* Open the database. Registers core schemas followed by any extension
|
|
959
|
+
* schemas supplied by the caller (domain plugins).
|
|
960
|
+
*
|
|
961
|
+
* Idempotent — safe to call multiple times; subsequent calls are no-ops
|
|
962
|
+
* if the database is already open.
|
|
963
|
+
*/
|
|
964
|
+
open(extensionSchemas?: SchemaDefinition[]): Promise<void>;
|
|
965
|
+
/**
|
|
966
|
+
* Access a collection by schema name.
|
|
967
|
+
* Throws if the schema has not been registered.
|
|
968
|
+
*/
|
|
969
|
+
collection<T>(schemaName: string): Promise<Collection<T>>;
|
|
970
|
+
/**
|
|
971
|
+
* Close the database connection.
|
|
972
|
+
*/
|
|
973
|
+
close(): void;
|
|
974
|
+
}
|
|
975
|
+
declare function createWorkspaceDatabase(db: Database): WorkspaceDatabase;
|
|
976
|
+
declare const COLLECTIONS: {
|
|
977
|
+
readonly ROLE: "role";
|
|
978
|
+
readonly PREFERENCE: "preference";
|
|
979
|
+
readonly CONTEXT: "context";
|
|
980
|
+
readonly SESSION: "session";
|
|
981
|
+
readonly TURN: "turn";
|
|
982
|
+
};
|
|
983
|
+
type CollectionName = typeof COLLECTIONS[keyof typeof COLLECTIONS];
|
|
547
984
|
|
|
548
985
|
/**
|
|
549
986
|
* Utility type for representing partial updates to the state, allowing deep nesting.
|
|
@@ -560,65 +997,14 @@ declare function del<T>(): T;
|
|
|
560
997
|
declare const merge: <T extends object>(original: T, changes: DeepPartial<T> | symbol) => T;
|
|
561
998
|
declare function ok<T>(value: T): Result<T, never>;
|
|
562
999
|
declare function err<E = WorkspaceError>(error: E): Result<never, E>;
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
open(): Promise<void>;
|
|
572
|
-
private createSchema;
|
|
573
|
-
close(): void;
|
|
574
|
-
deleteDatabase(): Promise<void>;
|
|
575
|
-
private getDB;
|
|
576
|
-
private readTx;
|
|
577
|
-
private writeTx;
|
|
578
|
-
saveRole(role: Role): Promise<void>;
|
|
579
|
-
loadRole(name: string): Promise<Role | null>;
|
|
580
|
-
deleteRole(name: string): Promise<void>;
|
|
581
|
-
savePreference(preference: Preference): Promise<void>;
|
|
582
|
-
loadPreference(id: UUID): Promise<Preference | null>;
|
|
583
|
-
deletePreference(id: UUID): Promise<void>;
|
|
584
|
-
saveContext(context: Context): Promise<void>;
|
|
585
|
-
loadContext(key: string): Promise<Context | null>;
|
|
586
|
-
loadContextBatch(keys: string[]): Promise<Map<string, Context>>;
|
|
587
|
-
deleteContext(key: string): Promise<void>;
|
|
588
|
-
saveTurn(sessionId: UUID, turn: Turn): Promise<void>;
|
|
589
|
-
loadTurn(sessionId: UUID, turnId: UUID, version: number): Promise<Turn | null>;
|
|
590
|
-
loadAllTurns(sessionId: UUID): Promise<Turn[]>;
|
|
591
|
-
deleteTurn(sessionId: UUID, turnId: UUID, version: number): Promise<void>;
|
|
592
|
-
setSessionHead(sessionId: UUID, head: {
|
|
593
|
-
id: UUID;
|
|
594
|
-
version: number;
|
|
595
|
-
} | null): Promise<void>;
|
|
596
|
-
getSessionHead(sessionId: UUID): Promise<{
|
|
597
|
-
id: UUID;
|
|
598
|
-
version: number;
|
|
599
|
-
} | null>;
|
|
600
|
-
storeBytes(sha256: SHA256, data: Uint8Array): Promise<void>;
|
|
601
|
-
loadBytes(sha256: SHA256): Promise<Uint8Array | null>;
|
|
602
|
-
deleteBytes(sha256: SHA256): Promise<void>;
|
|
603
|
-
exportAllBytes(): Promise<Array<[SHA256, Uint8Array]>>;
|
|
604
|
-
saveWorkspace(state: Workspace): Promise<void>;
|
|
605
|
-
loadWorkspace(): Promise<Workspace | null>;
|
|
606
|
-
exportBundle(): Promise<{
|
|
607
|
-
roles: Record<string, Role>;
|
|
608
|
-
preferences: Record<UUID, Preference>;
|
|
609
|
-
context: Record<string, Context>;
|
|
610
|
-
transcripts: Record<UUID, Turn[]>;
|
|
611
|
-
workspace: Workspace | null;
|
|
612
|
-
}>;
|
|
613
|
-
importBundle(data: {
|
|
614
|
-
roles: Record<string, Role>;
|
|
615
|
-
preferences: Record<UUID, Preference>;
|
|
616
|
-
context: Record<string, Context>;
|
|
617
|
-
transcripts: Record<UUID, Turn[]>;
|
|
618
|
-
workspace?: Workspace;
|
|
619
|
-
}): Promise<void>;
|
|
620
|
-
private getAllFromStore;
|
|
621
|
-
}
|
|
1000
|
+
declare function omitNullUndefined<T extends Record<string, any>>(obj: T): Partial<T>;
|
|
1001
|
+
declare function createSimpleWorkspace({ name, owner, language }: {
|
|
1002
|
+
name: string;
|
|
1003
|
+
language: string;
|
|
1004
|
+
owner: string;
|
|
1005
|
+
}): Workspace;
|
|
1006
|
+
declare function extractBlobRecord(patch: DeepPartial<Workspace>): BlobRecord | null;
|
|
1007
|
+
declare function extractBlobRef(record: BlobRecord): BlobRef;
|
|
622
1008
|
|
|
623
1009
|
/**
|
|
624
1010
|
* Persistence contract for binary blob content and blob registry records.
|
|
@@ -672,19 +1058,26 @@ interface TurnRef {
|
|
|
672
1058
|
version: number;
|
|
673
1059
|
}
|
|
674
1060
|
declare class TurnTree {
|
|
675
|
-
private readonly
|
|
676
|
-
constructor(
|
|
1061
|
+
private readonly db;
|
|
1062
|
+
constructor(db: WorkspaceDatabase);
|
|
1063
|
+
private turns;
|
|
1064
|
+
private sessions;
|
|
1065
|
+
/**
|
|
1066
|
+
* Compound filter for a specific (sessionId, id, version) tuple.
|
|
1067
|
+
* Uses only declared schema fields — never $id.
|
|
1068
|
+
*/
|
|
1069
|
+
private turnFilter;
|
|
1070
|
+
getHead(sessionId: UUID): Promise<TurnRef | null>;
|
|
1071
|
+
setHead(sessionId: UUID, head: TurnRef | null): Promise<void>;
|
|
677
1072
|
append(sessionId: UUID, turn: Turn): Promise<Turn>;
|
|
678
|
-
appendBatch(sessionId: UUID, turns: Turn[]): Promise<void>;
|
|
1073
|
+
appendBatch(sessionId: UUID, turns: Turn[], finalHead: TurnRef | null): Promise<void>;
|
|
679
1074
|
replaceVersion(sessionId: UUID, newTurn: Turn): Promise<void>;
|
|
680
1075
|
branch(sessionId: UUID, newTurn: Turn): Promise<void>;
|
|
1076
|
+
loadAllTurns(sessionId: UUID): Promise<Turn[]>;
|
|
681
1077
|
getActiveChain(sessionId: UUID, dirtyBuffer?: readonly Turn[]): Promise<Turn[]>;
|
|
682
|
-
countChained(sessionId: UUID, dirtyBuffer?: readonly Turn[]): Promise<number>;
|
|
683
1078
|
buildNodeGraph(sessionId: UUID, dirtyBuffer?: readonly Turn[]): Promise<Record<UUID, TurnNode>>;
|
|
684
1079
|
deleteSubtree(sessionId: UUID, turnId: UUID, version: number, newHead: TurnRef | null): Promise<void>;
|
|
685
1080
|
copyTranscript(sourceSessionId: UUID, targetSessionId: UUID): Promise<void>;
|
|
686
|
-
getHead(sessionId: UUID): Promise<TurnRef | null>;
|
|
687
|
-
setHead(sessionId: UUID, head: TurnRef | null): Promise<void>;
|
|
688
1081
|
}
|
|
689
1082
|
|
|
690
1083
|
declare function computeSHA256(data: Uint8Array): Promise<SHA256>;
|
|
@@ -741,29 +1134,55 @@ declare class BlobStore {
|
|
|
741
1134
|
}
|
|
742
1135
|
|
|
743
1136
|
declare class ContentStore {
|
|
744
|
-
private readonly
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
1137
|
+
private readonly db;
|
|
1138
|
+
readonly tree: TurnTree;
|
|
1139
|
+
readonly blobs: BlobStore;
|
|
1140
|
+
private readonly roleCache;
|
|
1141
|
+
private readonly preferenceCache;
|
|
1142
|
+
private readonly contextCache;
|
|
1143
|
+
/**
|
|
1144
|
+
* Called after any blob registry change with the sha256 and updated
|
|
1145
|
+
* BlobRecord (null on deletion). Wire this to your state manager to
|
|
1146
|
+
* keep Index.blobs current.
|
|
1147
|
+
*
|
|
1148
|
+
* ContentStore sets this on BlobStore.onRegistryChanged internally.
|
|
1149
|
+
* Consumers set this property to receive the forwarded notifications.
|
|
1150
|
+
*/
|
|
1151
|
+
onBlobRegistryChanged?: (sha256: SHA256, record: BlobRecord | null) => void;
|
|
1152
|
+
private constructor();
|
|
1153
|
+
static create(db: WorkspaceDatabase, blobStorage: BlobStorage, config?: ContentStoreConfig): Promise<ContentStore>;
|
|
1154
|
+
private init;
|
|
748
1155
|
getTurnTree(): TurnTree;
|
|
749
1156
|
getRole(name: string): Promise<Result<Role, WorkspaceError>>;
|
|
750
|
-
getPreference(id: UUID): Promise<Result<Preference, WorkspaceError>>;
|
|
751
|
-
getContext(key: string): Promise<Result<Context, WorkspaceError>>;
|
|
752
|
-
getContextByTopics(indexState: Index, topics: string[]): Promise<Context[]>;
|
|
753
1157
|
saveRole(role: Role): Promise<void>;
|
|
754
|
-
savePreference(preference: Preference): Promise<void>;
|
|
755
|
-
saveContext(context: Context): Promise<void>;
|
|
756
1158
|
deleteRole(name: string): Promise<void>;
|
|
1159
|
+
getPreference(id: UUID): Promise<Result<Preference, WorkspaceError>>;
|
|
1160
|
+
savePreference(preference: Preference): Promise<void>;
|
|
757
1161
|
deletePreference(id: UUID): Promise<void>;
|
|
1162
|
+
getContext(key: string): Promise<Result<Context, WorkspaceError>>;
|
|
1163
|
+
saveContext(context: Context): Promise<void>;
|
|
758
1164
|
deleteContext(key: string): Promise<void>;
|
|
1165
|
+
getContextByTopics(indexState: Index, topics: string[]): Promise<Context[]>;
|
|
1166
|
+
saveSession(meta: SessionMeta): Promise<void>;
|
|
1167
|
+
updateSessionMeta(sessionId: UUID, patch: DeepPartial<SessionMeta>): Promise<void>;
|
|
1168
|
+
deleteSession(sessionId: UUID): Promise<void>;
|
|
1169
|
+
registerBlob(data: Uint8Array, mediaType: BlobMediaType, filename?: string): Promise<Result<BlobRef, WorkspaceError>>;
|
|
1170
|
+
retainBlob(sha256: SHA256): Promise<Result<void, WorkspaceError>>;
|
|
1171
|
+
releaseBlob(sha256: SHA256): Promise<Result<void, WorkspaceError>>;
|
|
1172
|
+
purgeBlob(sha256: SHA256): Promise<Result<void, WorkspaceError>>;
|
|
1173
|
+
recordBlobRemoteId(sha256: SHA256, providerId: string, fileId: string): Promise<Result<void, WorkspaceError>>;
|
|
1174
|
+
getBlobRecord(sha256: SHA256): BlobRecord | null;
|
|
1175
|
+
getAllBlobRecords(): Record<SHA256, BlobRecord>;
|
|
1176
|
+
/**
|
|
1177
|
+
* Returns the blob resolver function expected by PromptBuilder.
|
|
1178
|
+
* Closes over the internal BlobStore — no BlobStore reference leaks out.
|
|
1179
|
+
*/
|
|
1180
|
+
getBlobResolver(): BlobStore['resolveRefs'];
|
|
759
1181
|
recordTurn(sessionId: UUID, turn: Turn): Promise<Result<void, WorkspaceError>>;
|
|
760
1182
|
editTurn(sessionId: UUID, turnId: UUID, newBlocks: ContentBlock[], newVersion: number, roleSnapshot?: string): Promise<Result<void, WorkspaceError>>;
|
|
761
1183
|
branchTurn(sessionId: UUID, newTurn: Turn): Promise<Result<void, WorkspaceError>>;
|
|
762
1184
|
deleteTurnSubtree(sessionId: UUID, turnId: UUID, version: number, newHead: TurnRef | null): Promise<Result<void, WorkspaceError>>;
|
|
763
1185
|
copyTranscript(sourceSessionId: UUID, targetSessionId: UUID): Promise<void>;
|
|
764
|
-
storeBytes(sha256: SHA256, data: Uint8Array): Promise<void>;
|
|
765
|
-
loadBytes(sha256: SHA256): Promise<Uint8Array | null>;
|
|
766
|
-
deleteBytes(sha256: SHA256): Promise<void>;
|
|
767
1186
|
resolveSession(workspace: Workspace, sessionId: UUID, transcript?: Turn[]): Promise<Result<EffectiveSession, WorkspaceError>>;
|
|
768
1187
|
}
|
|
769
1188
|
|
|
@@ -771,6 +1190,12 @@ declare function workspaceReducer({ index: state }: Workspace, command: Command)
|
|
|
771
1190
|
|
|
772
1191
|
declare class WorkspaceManager {
|
|
773
1192
|
private readonly contentStore;
|
|
1193
|
+
/**
|
|
1194
|
+
* Called when BlobStore triggers a registry change outside of a dispatch()
|
|
1195
|
+
* call — e.g. eagerEviction deleting a blob on release. The caller should
|
|
1196
|
+
* merge this patch into their Workspace.
|
|
1197
|
+
*/
|
|
1198
|
+
onWorkspacePatch?: (patch: DeepPartial<Workspace>) => void;
|
|
774
1199
|
constructor(contentStore: ContentStore);
|
|
775
1200
|
reduce(workspace: Workspace, command: Command): Result<DeepPartial<Workspace>, WorkspaceError>;
|
|
776
1201
|
dispatch(workspace: Workspace, command: Command): Promise<Result<DeepPartial<Workspace>, WorkspaceError>>;
|
|
@@ -902,18 +1327,6 @@ declare function buildTurnNode(turn: Turn, children?: UUID[]): TurnNode;
|
|
|
902
1327
|
interface SessionManagerConfig {
|
|
903
1328
|
flush?: Partial<FlushConfig>;
|
|
904
1329
|
}
|
|
905
|
-
/**
|
|
906
|
-
* Returned by SessionManager.open().
|
|
907
|
-
*
|
|
908
|
-
* session — the live Session instance. Store this in your component or
|
|
909
|
-
* module; pass it to every subsequent session.* call.
|
|
910
|
-
*
|
|
911
|
-
* patch — a DeepPartial<Workspace> that the caller should merge into
|
|
912
|
-
* their Workspace immediately after open(). Currently empty
|
|
913
|
-
* (the Workspace index already holds SessionMeta), but present
|
|
914
|
-
* for forward compatibility — future versions may update head
|
|
915
|
-
* or flushedTurnCount as part of opening.
|
|
916
|
-
*/
|
|
917
1330
|
interface OpenResult {
|
|
918
1331
|
session: Session;
|
|
919
1332
|
patch: DeepPartial<Workspace>;
|
|
@@ -928,4 +1341,71 @@ declare class SessionManager {
|
|
|
928
1341
|
get workspace(): WorkspaceManager;
|
|
929
1342
|
}
|
|
930
1343
|
|
|
931
|
-
|
|
1344
|
+
/**
|
|
1345
|
+
* In-process implementation backed by plain Maps.
|
|
1346
|
+
* Suitable for development, testing, and server-side runtimes without
|
|
1347
|
+
* access to IndexedDB.
|
|
1348
|
+
*/
|
|
1349
|
+
declare class MemoryBlobStorage implements BlobStorage {
|
|
1350
|
+
private readonly bytes;
|
|
1351
|
+
private readonly records;
|
|
1352
|
+
storeBytes(sha256: SHA256, data: Uint8Array): Promise<void>;
|
|
1353
|
+
loadBytes(sha256: SHA256): Promise<Uint8Array | null>;
|
|
1354
|
+
hasBytes(sha256: SHA256): Promise<boolean>;
|
|
1355
|
+
deleteBytes(sha256: SHA256): Promise<void>;
|
|
1356
|
+
saveRecord(record: BlobRecord): Promise<void>;
|
|
1357
|
+
loadRecord(sha256: SHA256): Promise<BlobRecord | null>;
|
|
1358
|
+
deleteRecord(sha256: SHA256): Promise<void>;
|
|
1359
|
+
listRecords(): Promise<BlobRecord[]>;
|
|
1360
|
+
exportAllBytes(): Promise<Array<[SHA256, Uint8Array]>>;
|
|
1361
|
+
/**
|
|
1362
|
+
* Atomic register for MemoryBlobStorage — sequential ops are atomic
|
|
1363
|
+
* in a single-threaded JS runtime, so this is equivalent to two separate
|
|
1364
|
+
* calls, but we implement it for interface consistency.
|
|
1365
|
+
*/
|
|
1366
|
+
registerBlob(record: BlobRecord, data: Uint8Array): Promise<void>;
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
interface IndexedDBBlobConfig {
|
|
1370
|
+
/** Name of the IndexedDB database. Defaults to 'aiworkspace-blobs'. */
|
|
1371
|
+
dbName?: string;
|
|
1372
|
+
}
|
|
1373
|
+
/**
|
|
1374
|
+
* IndexedDB-backed blob storage.
|
|
1375
|
+
*
|
|
1376
|
+
* Bytes are stored as raw Uint8Array — IndexedDB handles binary natively,
|
|
1377
|
+
* no base64 encoding at rest. This is important for large files.
|
|
1378
|
+
*
|
|
1379
|
+
* Transaction discipline: never await inside an active transaction.
|
|
1380
|
+
* All multi-step operations chain synchronous IDB request handlers
|
|
1381
|
+
* inside a single Promise.
|
|
1382
|
+
*/
|
|
1383
|
+
declare class IndexedDBBlobStorage implements BlobStorage {
|
|
1384
|
+
private readonly dbName;
|
|
1385
|
+
private db;
|
|
1386
|
+
constructor(config?: IndexedDBBlobConfig);
|
|
1387
|
+
open(): Promise<void>;
|
|
1388
|
+
private createSchema;
|
|
1389
|
+
close(): void;
|
|
1390
|
+
deleteDatabase(): Promise<void>;
|
|
1391
|
+
private getDB;
|
|
1392
|
+
private readTx;
|
|
1393
|
+
private writeTx;
|
|
1394
|
+
storeBytes(sha256: SHA256, data: Uint8Array): Promise<void>;
|
|
1395
|
+
loadBytes(sha256: SHA256): Promise<Uint8Array | null>;
|
|
1396
|
+
hasBytes(sha256: SHA256): Promise<boolean>;
|
|
1397
|
+
deleteBytes(sha256: SHA256): Promise<void>;
|
|
1398
|
+
saveRecord(record: BlobRecord): Promise<void>;
|
|
1399
|
+
loadRecord(sha256: SHA256): Promise<BlobRecord | null>;
|
|
1400
|
+
deleteRecord(sha256: SHA256): Promise<void>;
|
|
1401
|
+
listRecords(): Promise<BlobRecord[]>;
|
|
1402
|
+
exportAllBytes(): Promise<Array<[SHA256, Uint8Array]>>;
|
|
1403
|
+
/**
|
|
1404
|
+
* Atomically stores bytes and saves a record together.
|
|
1405
|
+
* Preferred over calling storeBytes + saveRecord separately when both
|
|
1406
|
+
* are new — avoids a window where bytes exist without a record.
|
|
1407
|
+
*/
|
|
1408
|
+
registerBlob(record: BlobRecord, data: Uint8Array): Promise<void>;
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
export { type AddContext, type AddPreference, type AddRole, type AddSessionTopics, type AddTurn, type BaseCommand, type BlobCommand, type BlobMediaType, type BlobRecord, type BlobRef, type BlobStorage, BlobStore, type BlobStoreConfig, type BranchInfo, type BranchTurn, COLLECTIONS, type CacheConfig, type CollectionName, type Command, type ContentBlock, ContentStore, type ContentStoreConfig, type Context, type ContextContent, type ContextRelevanceConfig, type ContextSummary, type CreateSession, type CreateWorkspace, type DeleteContext, type DeletePreference, type DeleteRole, type DeleteSession, type DeleteTurn, type DocumentBlock, type DocumentMediaType, type EditTurn, type EffectiveSession, type FlushConfig, type ForkSession, type ImageBlock, type ImageMediaType, type Index, type IndexedDBBlobConfig, IndexedDBBlobStorage, MemoryBlobStorage, type OpenResult, type OverrideSessionPreferences, type Preference, type PreferenceConflict, type PreferenceSummary, type Project, type Prompt, PromptBuilder, type PurgeBlob, type RecordBlobRemoteId, type RegisterBlob, type ReleaseBlob, type ResolvedBlob, type Result, type RetainBlob, type Role, type RoleSummary, type RoleTransitionBlock, type SHA256, Session, SessionManager, type SessionManagerConfig, type SessionMeta, type Settings, type SummaryBlock, type SwitchRole, type TextBlock, type ThinkingBlock, type Timestamp, type TokenBudget, type ToolResultBlock, type ToolUseBlock, type TopicIndex, type TranscriptWindow, type Turn, type TurnNode, type TurnRef, type TurnRole, TurnTree, type URI, type UUID, type UpdateContext, type UpdatePreference, type UpdateRole, type Workspace, type WorkspaceBundle, type WorkspaceDatabase, type WorkspaceError, WorkspaceManager, buildTurnNode, computeSHA256, createSimpleWorkspace, createWorkspaceDatabase, del, err, extractBlobRecord, extractBlobRef, merge, ok, omitNullUndefined, workspaceReducer };
|