@orkestrel/workspace 0.0.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.
@@ -0,0 +1,701 @@
1
+ import { DriverInterface } from '@orkestrel/database';
2
+ import { EmitterErrorHandler } from '@orkestrel/emitter';
3
+ import { EmitterHooks } from '@orkestrel/emitter';
4
+ import { EmitterInterface } from '@orkestrel/emitter';
5
+ import { TableInterface } from '@orkestrel/database';
6
+
7
+ /** The binary MIME labels supported by a binary {@link FileContent} arm. */
8
+ export declare type BinaryMIME = 'image/png' | 'image/jpeg' | 'image/gif' | 'image/webp';
9
+
10
+ /**
11
+ * Clamp a position to text bounds.
12
+ *
13
+ * @param text - The addressed text
14
+ * @param position - The requested position
15
+ * @returns The clamped position
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * clampPosition('ab', { line: 9, column: 9 }) // { line: 1, column: 3 }
20
+ * ```
21
+ */
22
+ export declare function clampPosition(text: string, position: Position): Position;
23
+
24
+ /**
25
+ * Clamp both positions in a range to text bounds.
26
+ *
27
+ * @param text - The addressed text
28
+ * @param range - The requested range
29
+ * @returns The clamped range
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * clampRange('ab', { start: { line: 1, column: 1 }, end: { line: 9, column: 9 } })
34
+ * ```
35
+ */
36
+ export declare function clampRange(text: string, range: Range): Range;
37
+
38
+ /**
39
+ * Compute the byte size of file content.
40
+ *
41
+ * @param content - The content to measure
42
+ * @returns UTF-8 bytes for text or decoded bytes for binary content
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * computeSize({ text: 'café', language: 'text' }) // 5
47
+ * ```
48
+ */
49
+ export declare function computeSize(content: FileContent): number;
50
+
51
+ /**
52
+ * Count the lines in file content.
53
+ *
54
+ * @param content - The content to inspect
55
+ * @returns The text line count, or zero for empty text and binary content
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * countLines({ text: 'a\nb', language: 'text' }) // 2
60
+ * ```
61
+ */
62
+ export declare function countLines(content: FileContent): number;
63
+
64
+ /**
65
+ * Create the binary arm of {@link FileContent}.
66
+ *
67
+ * @param data - The base64 payload
68
+ * @param mime - The binary MIME
69
+ * @returns Binary file content
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * import { createBinaryContent } from '@orkestrel/workspace'
74
+ *
75
+ * createBinaryContent('AAAA', 'image/png')
76
+ * ```
77
+ */
78
+ export declare function createBinaryContent(data: string, mime: BinaryMIME): FileContent;
79
+
80
+ /**
81
+ * Create a database-backed workspace snapshot store.
82
+ *
83
+ * @param driver - The database driver; defaults to an in-memory driver
84
+ * @returns A workspace store backed by the supplied driver
85
+ *
86
+ * @example
87
+ * ```ts
88
+ * import { createDatabaseWorkspaceStore } from '@orkestrel/workspace'
89
+ *
90
+ * const store = createDatabaseWorkspaceStore()
91
+ * ```
92
+ */
93
+ export declare function createDatabaseWorkspaceStore(driver?: DriverInterface): WorkspaceStoreInterface;
94
+
95
+ /**
96
+ * Create an immutable file with derived size and line counts.
97
+ *
98
+ * @param input - The file path, content, and optional state
99
+ * @returns A frozen file record
100
+ *
101
+ * @example
102
+ * ```ts
103
+ * import { createFile, createTextContent } from '@orkestrel/workspace'
104
+ *
105
+ * createFile({ path: 'a.txt', content: createTextContent('hello', 'text') })
106
+ * ```
107
+ */
108
+ export declare function createFile(input: FileInput): FileInterface;
109
+
110
+ /**
111
+ * Create an in-memory workspace snapshot store.
112
+ *
113
+ * @returns A process-local workspace store
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * import { createMemoryWorkspaceStore } from '@orkestrel/workspace'
118
+ *
119
+ * const store = createMemoryWorkspaceStore()
120
+ * ```
121
+ */
122
+ export declare function createMemoryWorkspaceStore(): WorkspaceStoreInterface;
123
+
124
+ /**
125
+ * Create the text arm of {@link FileContent}.
126
+ *
127
+ * @param text - The text body
128
+ * @param language - The language tag
129
+ * @returns Text file content
130
+ *
131
+ * @example
132
+ * ```ts
133
+ * import { createTextContent } from '@orkestrel/workspace'
134
+ *
135
+ * createTextContent('hello', 'text')
136
+ * ```
137
+ */
138
+ export declare function createTextContent(text: string, language: string): FileContent;
139
+
140
+ /**
141
+ * Create a workspace.
142
+ *
143
+ * @param options - Optional identity, emitter configuration, and initial files
144
+ * @returns A working workspace
145
+ *
146
+ * @example
147
+ * ```ts
148
+ * import { createWorkspace } from '@orkestrel/workspace'
149
+ *
150
+ * const workspace = createWorkspace()
151
+ * workspace.write('a.txt', 'hello')
152
+ * ```
153
+ */
154
+ export declare function createWorkspace(options?: WorkspaceOptions): WorkspaceInterface;
155
+
156
+ /**
157
+ * Create an empty workspace registry.
158
+ *
159
+ * @param options - Default event hooks and optional durability
160
+ * @returns A workspace manager
161
+ *
162
+ * @example
163
+ * ```ts
164
+ * import { createWorkspaceManager } from '@orkestrel/workspace'
165
+ *
166
+ * const manager = createWorkspaceManager()
167
+ * manager.add()
168
+ * ```
169
+ */
170
+ export declare function createWorkspaceManager(options?: WorkspaceManagerOptions): WorkspaceManagerInterface;
171
+
172
+ /**
173
+ * A workspace snapshot store over a database table.
174
+ *
175
+ * Snapshots occupy one opaque column and are narrowed when read back from the storage boundary.
176
+ *
177
+ * @example
178
+ * ```ts
179
+ * import { createDatabaseWorkspaceStore } from '@orkestrel/workspace'
180
+ *
181
+ * const store = createDatabaseWorkspaceStore()
182
+ * ```
183
+ */
184
+ export declare class DatabaseWorkspaceStore implements WorkspaceStoreInterface {
185
+ #private;
186
+ /**
187
+ * Wrap a workspace snapshot table.
188
+ *
189
+ * @param table - The table keyed by workspace identifier
190
+ */
191
+ constructor(table: TableInterface<WorkspaceSnapshotRow>);
192
+ get(id: string): Promise<WorkspaceSnapshot | undefined>;
193
+ set(snapshot: WorkspaceSnapshot): Promise<void>;
194
+ delete(id: string): Promise<void>;
195
+ }
196
+
197
+ /**
198
+ * Compute the decoded byte length of a base64 string.
199
+ *
200
+ * @param base64 - The base64 data
201
+ * @returns The decoded byte count
202
+ *
203
+ * @example
204
+ * ```ts
205
+ * decodedSize('AAAA') // 3
206
+ * ```
207
+ */
208
+ export declare function decodedSize(base64: string): number;
209
+
210
+ /**
211
+ * Escape regular-expression metacharacters for literal matching.
212
+ *
213
+ * @param value - The literal text
214
+ * @returns The escaped regular-expression source
215
+ *
216
+ * @example
217
+ * ```ts
218
+ * escapeRegExp('a.b') // 'a\\.b'
219
+ * ```
220
+ */
221
+ export declare function escapeRegExp(value: string): string;
222
+
223
+ /**
224
+ * File extensions mapped to language tags for text content.
225
+ *
226
+ * Unknown extensions intentionally fall back to `text` in
227
+ * {@link import('./helpers.js').inferLanguage}.
228
+ */
229
+ export declare const EXTENSION_LANGUAGES: Readonly<Record<string, string>>;
230
+
231
+ /**
232
+ * The immutable content of a file: either text with a language tag or base64 data with a MIME.
233
+ */
234
+ export declare type FileContent = {
235
+ readonly text: string;
236
+ readonly language: string;
237
+ } | {
238
+ readonly data: string;
239
+ readonly mime: BinaryMIME;
240
+ };
241
+
242
+ /** The caller-supplied data used to create an immutable file. */
243
+ export declare interface FileInput {
244
+ readonly path: string;
245
+ readonly content: FileContent;
246
+ readonly state?: FileState;
247
+ }
248
+
249
+ /** An immutable path-addressed file with derived byte and line counts. */
250
+ export declare interface FileInterface {
251
+ readonly path: string;
252
+ readonly content: FileContent;
253
+ readonly state: FileState;
254
+ readonly size: number;
255
+ readonly lines: number;
256
+ }
257
+
258
+ /** The edit state of an immutable file value. */
259
+ export declare type FileState = 'created' | 'modified';
260
+
261
+ /**
262
+ * Infer a language tag from the final file extension.
263
+ *
264
+ * @param path - The file path
265
+ * @returns The mapped language, or `text` when the extension is absent or unknown
266
+ *
267
+ * @example
268
+ * ```ts
269
+ * inferLanguage('src/main.ts') // 'typescript'
270
+ * ```
271
+ */
272
+ export declare function inferLanguage(path: string): string;
273
+
274
+ /**
275
+ * Determine whether content is the binary arm.
276
+ *
277
+ * @param content - The file content
278
+ * @returns Whether the content carries base64 data and a MIME
279
+ *
280
+ * @example
281
+ * ```ts
282
+ * isBinary({ data: 'AAAA', mime: 'image/png' }) // true
283
+ * ```
284
+ */
285
+ export declare function isBinary(content: FileContent): content is {
286
+ readonly data: string;
287
+ readonly mime: BinaryMIME;
288
+ };
289
+
290
+ /**
291
+ * Narrow an unknown value to an immutable file record.
292
+ *
293
+ * @param value - The value to inspect
294
+ * @returns Whether the value has the file shape
295
+ *
296
+ * @example
297
+ * ```ts
298
+ * isFile({ path: 'a.txt', content: { text: 'a', language: 'text' }, state: 'created', size: 1, lines: 1 })
299
+ * ```
300
+ */
301
+ export declare function isFile(value: unknown): value is FileInterface;
302
+
303
+ /**
304
+ * Determine whether content is the text arm.
305
+ *
306
+ * @param content - The file content
307
+ * @returns Whether the content carries text and a language
308
+ *
309
+ * @example
310
+ * ```ts
311
+ * isText({ text: 'hello', language: 'text' }) // true
312
+ * ```
313
+ */
314
+ export declare function isText(content: FileContent): content is {
315
+ readonly text: string;
316
+ readonly language: string;
317
+ };
318
+
319
+ /**
320
+ * Determine whether a 1-based range is structurally valid.
321
+ *
322
+ * @param range - The range to inspect
323
+ * @returns Whether both positions are positive and ordered
324
+ *
325
+ * @example
326
+ * ```ts
327
+ * isValidRange({ start: { line: 1, column: 1 }, end: { line: 1, column: 2 } }) // true
328
+ * ```
329
+ */
330
+ export declare function isValidRange(range: Range): boolean;
331
+
332
+ /**
333
+ * Narrow a caught value to a {@link WorkspaceError}.
334
+ *
335
+ * @param value - The caught value
336
+ * @returns Whether the value is a workspace error
337
+ *
338
+ * @example
339
+ * ```ts
340
+ * if (isWorkspaceError(error)) error.code
341
+ * ```
342
+ */
343
+ export declare function isWorkspaceError(value: unknown): value is WorkspaceError;
344
+
345
+ /**
346
+ * Narrow an unknown value to a workspace snapshot.
347
+ *
348
+ * @param value - The value read from a persistence boundary
349
+ * @returns Whether the value has the workspace snapshot shape
350
+ *
351
+ * @example
352
+ * ```ts
353
+ * isWorkspaceSnapshot({ id: 'work', files: [] }) // true
354
+ * ```
355
+ */
356
+ export declare function isWorkspaceSnapshot(value: unknown): value is WorkspaceSnapshot;
357
+
358
+ /**
359
+ * A process-local workspace snapshot store.
360
+ *
361
+ * @example
362
+ * ```ts
363
+ * import { MemoryWorkspaceStore } from '@orkestrel/workspace'
364
+ *
365
+ * const store = new MemoryWorkspaceStore()
366
+ * ```
367
+ */
368
+ export declare class MemoryWorkspaceStore implements WorkspaceStoreInterface {
369
+ #private;
370
+ get(id: string): Promise<WorkspaceSnapshot | undefined>;
371
+ set(snapshot: WorkspaceSnapshot): Promise<void>;
372
+ delete(id: string): Promise<void>;
373
+ }
374
+
375
+ /**
376
+ * Convert a 1-based position to a zero-based string offset.
377
+ *
378
+ * @param text - The addressed text
379
+ * @param position - The requested position
380
+ * @returns The bounded string offset
381
+ *
382
+ * @example
383
+ * ```ts
384
+ * offsetAt('ab\ncd', { line: 2, column: 1 }) // 3
385
+ * ```
386
+ */
387
+ export declare function offsetAt(text: string, position: Position): number;
388
+
389
+ /** A 1-based caret position inside text. */
390
+ export declare interface Position {
391
+ readonly line: number;
392
+ readonly column: number;
393
+ }
394
+
395
+ /** A half-open text span whose start is inclusive and end is exclusive. */
396
+ export declare interface Range {
397
+ readonly start: Position;
398
+ readonly end: Position;
399
+ }
400
+
401
+ /**
402
+ * Assemble a nested range from four 1-based coordinates.
403
+ *
404
+ * @param fromLine - The start line
405
+ * @param fromColumn - The start column
406
+ * @param toLine - The end line
407
+ * @param toColumn - The end column
408
+ * @returns The assembled range without validation
409
+ *
410
+ * @example
411
+ * ```ts
412
+ * rangeOf(1, 1, 1, 2)
413
+ * ```
414
+ */
415
+ export declare function rangeOf(fromLine: number, fromColumn: number, toLine: number, toColumn: number): Range;
416
+
417
+ /** The content and clamped span returned by a ranged read. */
418
+ export declare interface ReadResult {
419
+ readonly content: string;
420
+ readonly range: Range;
421
+ }
422
+
423
+ /** The tallies produced by a replacement operation. */
424
+ export declare interface ReplaceResult {
425
+ readonly occurrences: number;
426
+ readonly files: number;
427
+ }
428
+
429
+ /** One 1-based search hit and the full line that contains it. */
430
+ export declare interface SearchMatch {
431
+ readonly path: string;
432
+ readonly line: number;
433
+ readonly column: number;
434
+ readonly length: number;
435
+ readonly content: string;
436
+ }
437
+
438
+ /**
439
+ * Search and replacement behavior.
440
+ *
441
+ * @remarks
442
+ * `regex` treats the query as regular-expression source, `sensitive` controls case sensitivity,
443
+ * and `limit` caps the search or replacement count.
444
+ */
445
+ export declare interface SearchOptions {
446
+ readonly regex?: boolean;
447
+ readonly sensitive?: boolean;
448
+ readonly limit?: number;
449
+ }
450
+
451
+ /**
452
+ * Slice a clamped half-open text range.
453
+ *
454
+ * @param text - The source text
455
+ * @param range - The requested range
456
+ * @returns The ranged substring
457
+ *
458
+ * @example
459
+ * ```ts
460
+ * sliceRange('hello', { start: { line: 1, column: 1 }, end: { line: 1, column: 6 } }) // 'hello'
461
+ * ```
462
+ */
463
+ export declare function sliceRange(text: string, range: Range): string;
464
+
465
+ /**
466
+ * Replace a clamped half-open text range.
467
+ *
468
+ * @param text - The source text
469
+ * @param range - The requested range
470
+ * @param replacement - The replacement text
471
+ * @returns The spliced text
472
+ *
473
+ * @example
474
+ * ```ts
475
+ * spliceRange('hello', { start: { line: 1, column: 1 }, end: { line: 1, column: 6 } }, 'bye')
476
+ * ```
477
+ */
478
+ export declare function spliceRange(text: string, range: Range, replacement: string): string;
479
+
480
+ /**
481
+ * A mutable path-keyed editing surface over immutable files.
482
+ *
483
+ * Whole-file edits create text files, ranged edits operate only on existing text files, and
484
+ * binary files remain available through construction-time hydration. Mutations emit after the
485
+ * registry has changed.
486
+ *
487
+ * @example
488
+ * ```ts
489
+ * import { Workspace } from '@orkestrel/workspace'
490
+ *
491
+ * const workspace = new Workspace()
492
+ * workspace.write('notes.txt', 'hello')
493
+ * workspace.append('notes.txt', ' world')
494
+ * workspace.read('notes.txt') // 'hello world'
495
+ * ```
496
+ */
497
+ export declare class Workspace implements WorkspaceInterface {
498
+ #private;
499
+ /**
500
+ * Create a workspace.
501
+ *
502
+ * @param options - Optional identity, emitter configuration, and initial files
503
+ */
504
+ constructor(options?: WorkspaceOptions);
505
+ get id(): string;
506
+ get emitter(): EmitterInterface<WorkspaceEventMap>;
507
+ get count(): number;
508
+ file(path: string): FileInterface | undefined;
509
+ files(): readonly FileInterface[];
510
+ read(path: string): string | undefined;
511
+ read(path: string, range: Range): ReadResult | undefined;
512
+ read(paths: readonly string[]): Readonly<Record<string, string>>;
513
+ has(path: string): boolean;
514
+ has(paths: readonly string[]): boolean;
515
+ search(query: string, options?: SearchOptions): readonly SearchMatch[];
516
+ replace(query: string, replacement: string, options?: SearchOptions): ReplaceResult;
517
+ write(path: string, content: string): void;
518
+ write(path: string, content: string, range: Range): void;
519
+ write(files: Readonly<Record<string, string>>): void;
520
+ prepend(path: string, content: string): void;
521
+ prepend(files: Readonly<Record<string, string>>): void;
522
+ append(path: string, content: string): void;
523
+ append(files: Readonly<Record<string, string>>): void;
524
+ move(from: string, to: string): boolean;
525
+ move(mapping: Readonly<Record<string, string>>): boolean;
526
+ remove(path: string): boolean;
527
+ remove(paths: readonly string[]): boolean;
528
+ clear(): void;
529
+ snapshot(): WorkspaceSnapshot;
530
+ destroy(): void;
531
+ }
532
+
533
+ /** An invalid workspace edit or search operation. */
534
+ export declare class WorkspaceError extends Error {
535
+ readonly code: WorkspaceErrorCode;
536
+ readonly context?: Readonly<Record<string, unknown>>;
537
+ /**
538
+ * Create a workspace error.
539
+ *
540
+ * @param code - The machine-readable failure code
541
+ * @param message - The human-readable failure message
542
+ * @param context - Optional values associated with the failed operation
543
+ */
544
+ constructor(code: WorkspaceErrorCode, message: string, context?: Readonly<Record<string, unknown>>);
545
+ }
546
+
547
+ /** The machine-readable failure codes raised by the workspace edit surface. */
548
+ export declare type WorkspaceErrorCode = 'MODALITY' | 'PATTERN' | 'RANGE';
549
+
550
+ /** Events emitted after workspace mutations complete. */
551
+ export declare type WorkspaceEventMap = {
552
+ readonly write: readonly [file: FileInterface];
553
+ readonly remove: readonly [path: string];
554
+ readonly move: readonly [from: string, to: string];
555
+ readonly clear: readonly [];
556
+ };
557
+
558
+ /** A mutable path-keyed editing surface over immutable file values. */
559
+ export declare interface WorkspaceInterface {
560
+ readonly id: string;
561
+ readonly emitter: EmitterInterface<WorkspaceEventMap>;
562
+ readonly count: number;
563
+ file(path: string): FileInterface | undefined;
564
+ files(): readonly FileInterface[];
565
+ read(path: string): string | undefined;
566
+ read(path: string, range: Range): ReadResult | undefined;
567
+ read(paths: readonly string[]): Readonly<Record<string, string>>;
568
+ has(path: string): boolean;
569
+ has(paths: readonly string[]): boolean;
570
+ search(query: string, options?: SearchOptions): readonly SearchMatch[];
571
+ replace(query: string, replacement: string, options?: SearchOptions): ReplaceResult;
572
+ write(path: string, content: string): void;
573
+ write(path: string, content: string, range: Range): void;
574
+ write(files: Readonly<Record<string, string>>): void;
575
+ prepend(path: string, content: string): void;
576
+ prepend(files: Readonly<Record<string, string>>): void;
577
+ append(path: string, content: string): void;
578
+ append(files: Readonly<Record<string, string>>): void;
579
+ move(from: string, to: string): boolean;
580
+ move(mapping: Readonly<Record<string, string>>): boolean;
581
+ remove(path: string): boolean;
582
+ remove(paths: readonly string[]): boolean;
583
+ clear(): void;
584
+ snapshot(): WorkspaceSnapshot;
585
+ destroy(): void;
586
+ }
587
+
588
+ /**
589
+ * An insertion-ordered workspace registry with an active selection.
590
+ *
591
+ * A supplied store adds lenient snapshot `open` and `save` operations. Event defaults flow into
592
+ * workspaces created through the registry, while observability remains owned by each workspace.
593
+ *
594
+ * @example
595
+ * ```ts
596
+ * import { WorkspaceManager } from '@orkestrel/workspace'
597
+ *
598
+ * const manager = new WorkspaceManager()
599
+ * const workspace = manager.add({ id: 'scratch' })
600
+ * manager.active === workspace
601
+ * ```
602
+ */
603
+ export declare class WorkspaceManager implements WorkspaceManagerInterface {
604
+ #private;
605
+ /**
606
+ * Create a registry.
607
+ *
608
+ * @param options - Default event hooks and optional snapshot store
609
+ */
610
+ constructor(options?: WorkspaceManagerOptions);
611
+ get count(): number;
612
+ get active(): WorkspaceInterface | undefined;
613
+ workspace(id: string): WorkspaceInterface | undefined;
614
+ workspaces(): readonly WorkspaceInterface[];
615
+ add(options?: WorkspaceOptions): WorkspaceInterface;
616
+ switch(id: string): WorkspaceInterface | undefined;
617
+ open(id: string): Promise<WorkspaceInterface | undefined>;
618
+ save(id: string): Promise<boolean>;
619
+ remove(id: string): boolean;
620
+ remove(ids: readonly string[]): boolean;
621
+ clear(): void;
622
+ }
623
+
624
+ /** An insertion-ordered workspace registry with an active selection and optional durability. */
625
+ export declare interface WorkspaceManagerInterface {
626
+ readonly count: number;
627
+ readonly active: WorkspaceInterface | undefined;
628
+ workspace(id: string): WorkspaceInterface | undefined;
629
+ workspaces(): readonly WorkspaceInterface[];
630
+ add(options?: WorkspaceOptions): WorkspaceInterface;
631
+ switch(id: string): WorkspaceInterface | undefined;
632
+ open(id: string): Promise<WorkspaceInterface | undefined>;
633
+ save(id: string): Promise<boolean>;
634
+ remove(id: string): boolean;
635
+ remove(ids: readonly string[]): boolean;
636
+ clear(): void;
637
+ }
638
+
639
+ /**
640
+ * Workspace-manager construction options.
641
+ *
642
+ * `on` and `error` become defaults for created workspaces; `store` supplies optional durability.
643
+ */
644
+ export declare interface WorkspaceManagerOptions {
645
+ readonly on?: EmitterHooks<WorkspaceEventMap>;
646
+ readonly error?: EmitterErrorHandler;
647
+ readonly store?: WorkspaceStoreInterface;
648
+ }
649
+
650
+ /**
651
+ * Workspace construction options.
652
+ *
653
+ * @remarks
654
+ * `id` supplies the registry key, `on` supplies initial event listeners, `error` receives isolated
655
+ * listener failures, and `seed` hydrates initial immutable files without emitting edits.
656
+ */
657
+ export declare interface WorkspaceOptions {
658
+ readonly id?: string;
659
+ readonly on?: EmitterHooks<WorkspaceEventMap>;
660
+ readonly error?: EmitterErrorHandler;
661
+ readonly seed?: Iterable<FileInterface>;
662
+ }
663
+
664
+ /** A JSON-serializable workspace snapshot. */
665
+ export declare interface WorkspaceSnapshot {
666
+ readonly id: string;
667
+ readonly files: readonly FileInterface[];
668
+ }
669
+
670
+ /** The database row used to persist one opaque workspace snapshot. */
671
+ export declare interface WorkspaceSnapshotRow {
672
+ readonly id: string;
673
+ readonly snapshot: unknown;
674
+ }
675
+
676
+ /** The asynchronous point-access persistence contract for workspace snapshots. */
677
+ export declare interface WorkspaceStoreInterface {
678
+ /**
679
+ * Resolve a snapshot.
680
+ *
681
+ * @param id - The workspace identifier
682
+ * @returns The snapshot, or `undefined` when absent
683
+ */
684
+ get(id: string): Promise<WorkspaceSnapshot | undefined>;
685
+ /**
686
+ * Insert or replace a snapshot under its own identifier.
687
+ *
688
+ * @param snapshot - The snapshot to persist
689
+ * @returns A promise that resolves when persistence completes
690
+ */
691
+ set(snapshot: WorkspaceSnapshot): Promise<void>;
692
+ /**
693
+ * Delete a snapshot when present.
694
+ *
695
+ * @param id - The workspace identifier
696
+ * @returns A promise that resolves when deletion completes
697
+ */
698
+ delete(id: string): Promise<void>;
699
+ }
700
+
701
+ export { }