@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.
- package/LICENSE +21 -0
- package/README.md +54 -0
- package/dist/src/core/index.cjs +976 -0
- package/dist/src/core/index.cjs.map +1 -0
- package/dist/src/core/index.d.cts +701 -0
- package/dist/src/core/index.d.ts +701 -0
- package/dist/src/core/index.js +946 -0
- package/dist/src/core/index.js.map +1 -0
- package/package.json +86 -0
|
@@ -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 { }
|