@orkestrel/workspace 0.0.17 → 0.0.18
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/dist/src/core/index.cjs
CHANGED
|
@@ -94,7 +94,7 @@ function isWorkspaceError(value) {
|
|
|
94
94
|
if (!(value instanceof Error) || _orkestrel_contract.INTRINSICS.prototype(value) === Error.prototype) return false;
|
|
95
95
|
if (_orkestrel_contract.INTRINSICS.describe(value, Symbol.for("@orkestrel/workspace.WorkspaceError"))?.value !== value) return false;
|
|
96
96
|
const code = _orkestrel_contract.INTRINSICS.reflect.read(value, "code");
|
|
97
|
-
if (code !== "MISSING" && code !== "MODALITY" && code !== "PATTERN" && code !== "RANGE") return false;
|
|
97
|
+
if (code !== "MISSING" && code !== "MODALITY" && code !== "PATHS" && code !== "PATTERN" && code !== "RANGE") return false;
|
|
98
98
|
const context = _orkestrel_contract.INTRINSICS.reflect.read(value, "context");
|
|
99
99
|
return context === void 0 || (0, _orkestrel_contract.isObject)(context) || (0, _orkestrel_contract.isFunction)(context);
|
|
100
100
|
});
|
|
@@ -435,10 +435,12 @@ var Workspace = class {
|
|
|
435
435
|
}
|
|
436
436
|
search(query, options) {
|
|
437
437
|
const pattern = this.#pattern(query, options);
|
|
438
|
+
const paths = this.#paths(options);
|
|
438
439
|
const limit = options?.limit;
|
|
439
440
|
const matches = [];
|
|
440
441
|
for (const file of this.#files.values()) {
|
|
441
442
|
if (limit !== void 0 && matches.length >= limit) break;
|
|
443
|
+
if (paths !== void 0 && !paths.has(file.path)) continue;
|
|
442
444
|
if (!isTextContent(file.content)) continue;
|
|
443
445
|
const lines = file.content.text.split(/\r\n|\n/);
|
|
444
446
|
for (const [index, lineText] of lines.entries()) {
|
|
@@ -460,11 +462,13 @@ var Workspace = class {
|
|
|
460
462
|
}
|
|
461
463
|
replace(query, replacement, options) {
|
|
462
464
|
const pattern = this.#pattern(query, options);
|
|
465
|
+
const paths = this.#paths(options);
|
|
463
466
|
const limit = options?.limit;
|
|
464
467
|
const changes = [];
|
|
465
468
|
for (const [path, file] of this.#files) {
|
|
466
469
|
const occurrences = changes.reduce((total, count) => total + count, 0);
|
|
467
470
|
if (limit !== void 0 && occurrences >= limit) break;
|
|
471
|
+
if (paths !== void 0 && !paths.has(path)) continue;
|
|
468
472
|
if (!isTextContent(file.content)) continue;
|
|
469
473
|
const remaining = limit === void 0 ? void 0 : limit - occurrences;
|
|
470
474
|
pattern.lastIndex = 0;
|
|
@@ -613,6 +617,12 @@ var Workspace = class {
|
|
|
613
617
|
throw new WorkspaceError("PATTERN", `Invalid search pattern: ${query}`, { query });
|
|
614
618
|
}
|
|
615
619
|
}
|
|
620
|
+
#paths(options) {
|
|
621
|
+
const paths = options?.paths;
|
|
622
|
+
if (paths === void 0) return void 0;
|
|
623
|
+
if (!(0, _orkestrel_contract.arrayOf)(_orkestrel_contract.isString)(paths)) throw new WorkspaceError("PATHS", "Invalid search paths: expected an array of path strings", { paths });
|
|
624
|
+
return new Set(paths);
|
|
625
|
+
}
|
|
616
626
|
};
|
|
617
627
|
// src/core/workspaces/WorkspaceManager.ts
|
|
618
628
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["holds","INTRINSICS","isObject","isFunction","holds","isRecord","isString","literalOf","isNumber","arrayOf","Emitter","isArray","isRecord","escapeRegExp","isArray","createMemoryDriver","stringShape","rawShape","createDatabase"],"sources":["../../../src/core/constants.ts","../../../src/core/errors.ts","../../../src/core/helpers.ts","../../../src/core/validators.ts","../../../src/core/workspaces/Workspace.ts","../../../src/core/workspaces/WorkspaceManager.ts","../../../src/core/workspaces/stores/DatabaseWorkspaceStore.ts","../../../src/core/workspaces/stores/MemoryWorkspaceStore.ts","../../../src/core/factories.ts"],"sourcesContent":["/**\n * Maps file extensions to language tags for text content.\n *\n * The table is frozen, and an extension it does not list falls back to `text` in\n * {@link import('./helpers.js').inferLanguage}.\n */\nexport const EXTENSION_LANGUAGES: Readonly<Record<string, string>> = Object.freeze({\n\tts: 'typescript',\n\ttsx: 'typescript',\n\tjs: 'javascript',\n\tjsx: 'javascript',\n\tmjs: 'javascript',\n\tcjs: 'javascript',\n\tjson: 'json',\n\tmd: 'markdown',\n\thtml: 'html',\n\thtm: 'html',\n\tcss: 'css',\n\tscss: 'scss',\n\tsass: 'sass',\n\tless: 'less',\n\tvue: 'vue',\n\tsvelte: 'svelte',\n\tpy: 'python',\n\trb: 'ruby',\n\trs: 'rust',\n\tgo: 'go',\n\tjava: 'java',\n\tkt: 'kotlin',\n\tswift: 'swift',\n\tc: 'c',\n\tcpp: 'cpp',\n\th: 'c',\n\thpp: 'cpp',\n\tcs: 'csharp',\n\tphp: 'php',\n\tsql: 'sql',\n\tsh: 'bash',\n\tbash: 'bash',\n\tzsh: 'bash',\n\tps1: 'powershell',\n\tyaml: 'yaml',\n\tyml: 'yaml',\n\ttoml: 'toml',\n\txml: 'xml',\n\tsvg: 'xml',\n\ttxt: 'text',\n})\n","import type { WorkspaceErrorCode } from './types.js'\nimport { holds, INTRINSICS, isFunction, isObject } from '@orkestrel/contract'\n\n/**\n * Reports an invalid workspace edit or search operation, carrying a {@link WorkspaceErrorCode}\n * and, when the operation had one, the context it ran under.\n */\nexport class WorkspaceError extends Error {\n\treadonly code: WorkspaceErrorCode\n\treadonly context?: Readonly<Record<string, unknown>>\n\n\t/**\n\t * Creates a workspace error.\n\t *\n\t * @param code - The machine-readable failure code\n\t * @param message - The human-readable failure message\n\t * @param context - Optional values associated with the failed operation\n\t */\n\tconstructor(\n\t\tcode: WorkspaceErrorCode,\n\t\tmessage: string,\n\t\tcontext?: Readonly<Record<string, unknown>>,\n\t) {\n\t\tsuper(message)\n\t\tINTRINSICS.define(this, Symbol.for('@orkestrel/workspace.WorkspaceError'), { value: this })\n\t\tthis.name = 'WorkspaceError'\n\t\tthis.code = code\n\t\tif (context !== undefined) this.context = context\n\t}\n}\n\n/**\n * Narrows a caught value to a {@link WorkspaceError}.\n *\n * @remarks\n * Checks the identity brand and declared members across package copies, accepting subclasses\n * and refusing transparent proxies. Inspection failures return false.\n *\n * @param value - The caught value\n * @returns True if the value is a workspace error; false otherwise\n *\n * @example\n * ```ts\n * if (isWorkspaceError(error)) error.code\n * ```\n */\nexport function isWorkspaceError(value: unknown): value is WorkspaceError {\n\treturn holds(() => {\n\t\tif (!(value instanceof Error) || INTRINSICS.prototype(value) === Error.prototype) return false\n\t\tconst brand = INTRINSICS.describe(value, Symbol.for('@orkestrel/workspace.WorkspaceError'))\n\t\tif (brand?.value !== value) return false\n\t\tconst code: unknown = INTRINSICS.reflect.read(value, 'code')\n\t\tif (code !== 'MISSING' && code !== 'MODALITY' && code !== 'PATTERN' && code !== 'RANGE')\n\t\t\treturn false\n\t\tconst context: unknown = INTRINSICS.reflect.read(value, 'context')\n\t\treturn context === undefined || isObject(context) || isFunction(context)\n\t})\n}\n","import type { BinaryContent, Caret, FileContent, Range, TextContent } from './types.js'\nimport { EXTENSION_LANGUAGES } from './constants.js'\n\n/**\n * Infers a language tag from the final file extension.\n *\n * @param path - The file path\n * @returns The mapped language, or `text` when the extension is absent or unknown\n *\n * @example\n * ```ts\n * inferLanguage('src/main.ts') // 'typescript'\n * ```\n */\nexport function inferLanguage(path: string): string {\n\tconst dot = path.lastIndexOf('.')\n\tif (dot === -1) return 'text'\n\tconst extension = path.slice(dot + 1).toLowerCase()\n\treturn EXTENSION_LANGUAGES[extension] ?? 'text'\n}\n\n/**\n * Determines whether content is the text arm.\n *\n * @param content - The file content\n * @returns True if the content carries text and a language; false otherwise\n *\n * @example\n * ```ts\n * isTextContent({ text: 'hello', language: 'text' }) // true\n * ```\n */\nexport function isTextContent(content: FileContent): content is TextContent {\n\treturn 'text' in content\n}\n\n/**\n * Determines whether content is the binary arm.\n *\n * @param content - The file content\n * @returns True if the content carries a base64 string and a MIME; false otherwise\n *\n * @example\n * ```ts\n * isBinary({ base64: 'AAAA', mime: 'image/png' }) // true\n * ```\n */\nexport function isBinary(content: FileContent): content is BinaryContent {\n\treturn 'base64' in content\n}\n\n/**\n * Computes the byte size of file content.\n *\n * @param content - The content to measure\n * @returns UTF-8 bytes for text or decoded bytes for binary content\n *\n * @example\n * ```ts\n * computeSize({ text: 'café', language: 'text' }) // 5\n * ```\n */\nexport function computeSize(content: FileContent): number {\n\tif (isTextContent(content)) return new TextEncoder().encode(content.text).length\n\treturn computeDecodedSize(content.base64)\n}\n\n/**\n * Counts the lines in file content.\n *\n * @param content - The content to inspect\n * @returns The text line count, or zero for empty text and binary content\n *\n * @example\n * ```ts\n * countLines({ text: 'a\\nb', language: 'text' }) // 2\n * ```\n */\nexport function countLines(content: FileContent): number {\n\tif (!isTextContent(content)) return 0\n\tif (content.text.length === 0) return 0\n\treturn content.text.split(/\\r\\n|\\n/).length\n}\n\n/**\n * Computes the decoded byte length of a base64 string, arithmetically rather than by decoding it.\n *\n * @param base64 - The base64 string\n * @returns The decoded byte count\n *\n * @example\n * ```ts\n * computeDecodedSize('AAAA') // 3\n * ```\n */\nexport function computeDecodedSize(base64: string): number {\n\tconst padding = base64.endsWith('==') ? 2 : base64.endsWith('=') ? 1 : 0\n\treturn Math.floor((base64.length * 3) / 4) - padding\n}\n\n/**\n * Determines whether a 1-based range is structurally valid.\n *\n * @param range - The range to inspect\n * @returns True if both carets are positive and ordered; false otherwise\n *\n * @example\n * ```ts\n * isValidRange({ start: { line: 1, column: 1 }, end: { line: 1, column: 2 } }) // true\n * ```\n */\nexport function isValidRange(range: Range): boolean {\n\tif (range.start.line < 1 || range.start.column < 1) return false\n\tif (range.end.line < 1 || range.end.column < 1) return false\n\tif (range.start.line > range.end.line) return false\n\treturn !(range.start.line === range.end.line && range.start.column > range.end.column)\n}\n\n/**\n * Clamps a caret to text bounds.\n *\n * @param text - The addressed text\n * @param caret - The requested caret\n * @returns The clamped caret\n *\n * @example\n * ```ts\n * clampCaret('ab', { line: 9, column: 9 }) // { line: 1, column: 3 }\n * ```\n */\nexport function clampCaret(text: string, caret: Caret): Caret {\n\tconst lines = text.split('\\n')\n\tconst line = Math.max(1, Math.min(caret.line, lines.length))\n\tconst lineText = lines[line - 1] ?? ''\n\tconst column = Math.max(1, Math.min(caret.column, lineText.length + 1))\n\treturn { line, column }\n}\n\n/**\n * Clamps both carets in a range to text bounds.\n *\n * @param text - The addressed text\n * @param range - The requested range\n * @returns The clamped range\n *\n * @example\n * ```ts\n * clampRange('ab', { start: { line: 1, column: 1 }, end: { line: 9, column: 9 } })\n * ```\n */\nexport function clampRange(text: string, range: Range): Range {\n\treturn { start: clampCaret(text, range.start), end: clampCaret(text, range.end) }\n}\n\n/**\n * Converts a 1-based caret to a zero-based string offset.\n *\n * @param text - The addressed text\n * @param caret - The requested caret\n * @returns The bounded string offset\n *\n * @example\n * ```ts\n * offsetAt('ab\\ncd', { line: 2, column: 1 }) // 3\n * ```\n */\nexport function offsetAt(text: string, caret: Caret): number {\n\tconst lines = text.split('\\n')\n\tconst offset = lines\n\t\t.filter((_, index) => index < caret.line - 1)\n\t\t.reduce((total, line) => total + line.length + 1, 0)\n\treturn Math.min(offset + (caret.column - 1), text.length)\n}\n\n/**\n * Slices a clamped half-open text range.\n *\n * @param text - The source text\n * @param range - The requested range\n * @returns The ranged substring\n *\n * @example\n * ```ts\n * sliceRange('hello', { start: { line: 1, column: 1 }, end: { line: 1, column: 6 } }) // 'hello'\n * ```\n */\nexport function sliceRange(text: string, range: Range): string {\n\tconst clamped = clampRange(text, range)\n\treturn text.slice(offsetAt(text, clamped.start), offsetAt(text, clamped.end))\n}\n\n/**\n * Replaces a clamped half-open text range.\n *\n * @param text - The source text\n * @param range - The requested range\n * @param replacement - The replacement text\n * @returns The spliced text\n *\n * @example\n * ```ts\n * spliceRange('hello', { start: { line: 1, column: 1 }, end: { line: 1, column: 6 } }, 'bye')\n * ```\n */\nexport function spliceRange(text: string, range: Range, replacement: string): string {\n\tconst clamped = clampRange(text, range)\n\tconst start = offsetAt(text, clamped.start)\n\tconst end = offsetAt(text, clamped.end)\n\treturn text.slice(0, start) + replacement + text.slice(end)\n}\n\n/**\n * Assembles a nested range from four 1-based coordinates.\n *\n * @param fromLine - The start line\n * @param fromColumn - The start column\n * @param toLine - The end line\n * @param toColumn - The end column\n * @returns The assembled range without validation\n *\n * @example\n * ```ts\n * rangeOf(1, 1, 1, 2)\n * ```\n */\nexport function rangeOf(\n\tfromLine: number,\n\tfromColumn: number,\n\ttoLine: number,\n\ttoColumn: number,\n): Range {\n\treturn { start: { line: fromLine, column: fromColumn }, end: { line: toLine, column: toColumn } }\n}\n","import type { FileInterface, WorkspaceSnapshot } from './types.js'\nimport { arrayOf, holds, isNumber, isRecord, isString, literalOf } from '@orkestrel/contract'\n\n/**\n * Narrows an unknown value to an immutable file record.\n *\n * @param value - The value to inspect\n * @returns True if the value has the file shape; false otherwise\n *\n * @example\n * ```ts\n * isFile({ path: 'a.txt', content: { text: 'a', language: 'text' }, state: 'created', size: 1, lines: 1 })\n * ```\n */\nexport function isFile(value: unknown): value is FileInterface {\n\treturn holds(() => {\n\t\tif (!isRecord(value)) return false\n\t\tif (!isString(value.path) || !literalOf('created', 'modified')(value.state)) return false\n\t\tif (!isNumber(value.size) || !isNumber(value.lines)) return false\n\t\tif (!isRecord(value.content)) return false\n\t\tconst text = isString(value.content.text) && isString(value.content.language)\n\t\tconst binary =\n\t\t\tisString(value.content.base64) &&\n\t\t\tliteralOf('image/png', 'image/jpeg', 'image/gif', 'image/webp')(value.content.mime)\n\t\treturn text || binary\n\t})\n}\n\n/**\n * Narrows an unknown value to a workspace snapshot.\n *\n * @param value - The value read from a persistence boundary\n * @returns True if the value has the workspace snapshot shape; false otherwise\n *\n * @example\n * ```ts\n * isWorkspaceSnapshot({ id: 'work', files: [] }) // true\n * ```\n */\nexport function isWorkspaceSnapshot(value: unknown): value is WorkspaceSnapshot {\n\treturn holds(() => isRecord(value) && isString(value.id) && arrayOf(isFile)(value.files))\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tFileInterface,\n\tRange,\n\tReadResult,\n\tReplaceResult,\n\tSearchMatch,\n\tSearchOptions,\n\tWorkspaceEventMap,\n\tWorkspaceInterface,\n\tWorkspaceOptions,\n\tWorkspaceSnapshot,\n} from '../types.js'\nimport { escapeRegExp, isArray, isRecord } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { WorkspaceError } from '../errors.js'\nimport { createFile } from '../factories.js'\nimport {\n\tclampRange,\n\tinferLanguage,\n\tisTextContent,\n\tisValidRange,\n\tsliceRange,\n\tspliceRange,\n} from '../helpers.js'\n\n/**\n * Implements `WorkspaceInterface` over one insertion-ordered path map the instance owns,\n * projecting fresh arrays on every read.\n *\n * Whole-file edits create text files, ranged edits operate only on existing text files, and\n * binary files remain available through construction-time hydration. Mutations emit after the\n * file map has changed.\n *\n * @example\n * ```ts\n * import { Workspace } from '@orkestrel/workspace'\n *\n * const workspace = new Workspace()\n * workspace.write('notes.txt', 'hello')\n * workspace.append('notes.txt', ' world')\n * workspace.read('notes.txt') // 'hello world'\n * ```\n */\nexport class Workspace implements WorkspaceInterface {\n\treadonly #id: string\n\treadonly #files = new Map<string, FileInterface>()\n\treadonly #emitter: Emitter<WorkspaceEventMap>\n\n\t/**\n\t * Creates a workspace.\n\t *\n\t * @param options - Optional identity, emitter configuration, and initial files\n\t */\n\tconstructor(options?: WorkspaceOptions) {\n\t\tthis.#id = options?.id ?? crypto.randomUUID()\n\t\tthis.#emitter = new Emitter<WorkspaceEventMap>({\n\t\t\t...(options?.on === undefined ? {} : { on: options.on }),\n\t\t\t...(options?.error === undefined ? {} : { error: options.error }),\n\t\t})\n\t\tif (options?.seed) for (const file of options.seed) this.#files.set(file.path, file)\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tget emitter(): EmitterInterface<WorkspaceEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget count(): number {\n\t\treturn this.#files.size\n\t}\n\n\tfile(path: string): FileInterface | undefined {\n\t\treturn this.#files.get(path)\n\t}\n\n\tfiles(): readonly FileInterface[] {\n\t\treturn [...this.#files.values()]\n\t}\n\n\tread(path: string): string | undefined\n\tread(path: string, range: Range): ReadResult | undefined\n\tread(paths: readonly string[]): Readonly<Record<string, string>>\n\tread(\n\t\tpath: string | readonly string[],\n\t\trange?: Range,\n\t): string | ReadResult | undefined | Readonly<Record<string, string>> {\n\t\tif (isArray(path)) {\n\t\t\tconst result: Record<string, string> = {}\n\t\t\tfor (const one of path) {\n\t\t\t\tconst file = this.#files.get(one)\n\t\t\t\tif (file && isTextContent(file.content)) result[one] = file.content.text\n\t\t\t}\n\t\t\treturn result\n\t\t}\n\t\tconst file = this.#files.get(path)\n\t\tif (!file) return undefined\n\t\tif (!range) return isTextContent(file.content) ? file.content.text : undefined\n\t\tif (!isTextContent(file.content)) {\n\t\t\tthrow new WorkspaceError('MODALITY', `Cannot read a range of a binary file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\treturn {\n\t\t\tcontent: sliceRange(file.content.text, range),\n\t\t\trange: clampRange(file.content.text, range),\n\t\t}\n\t}\n\n\thas(path: string): boolean\n\thas(paths: readonly string[]): boolean\n\thas(path: string | readonly string[]): boolean {\n\t\tif (isArray(path)) return path.every((one) => this.#files.has(one))\n\t\treturn this.#files.has(path)\n\t}\n\n\tsearch(query: string, options?: SearchOptions): readonly SearchMatch[] {\n\t\tconst pattern = this.#pattern(query, options)\n\t\tconst limit = options?.limit\n\t\tconst matches: SearchMatch[] = []\n\t\tfor (const file of this.#files.values()) {\n\t\t\tif (limit !== undefined && matches.length >= limit) break\n\t\t\tif (!isTextContent(file.content)) continue\n\t\t\tconst lines = file.content.text.split(/\\r\\n|\\n/)\n\t\t\tfor (const [index, lineText] of lines.entries()) {\n\t\t\t\tif (limit !== undefined && matches.length >= limit) break\n\t\t\t\tpattern.lastIndex = 0\n\t\t\t\tfor (const hit of lineText.matchAll(pattern)) {\n\t\t\t\t\tif (limit !== undefined && matches.length >= limit) break\n\t\t\t\t\tmatches.push({\n\t\t\t\t\t\tpath: file.path,\n\t\t\t\t\t\tline: index + 1,\n\t\t\t\t\t\tcolumn: hit.index + 1,\n\t\t\t\t\t\tlength: hit[0].length,\n\t\t\t\t\t\tcontent: lineText,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn matches\n\t}\n\n\treplace(query: string, replacement: string, options?: SearchOptions): ReplaceResult {\n\t\tconst pattern = this.#pattern(query, options)\n\t\tconst limit = options?.limit\n\t\tconst changes: number[] = []\n\t\tfor (const [path, file] of this.#files) {\n\t\t\tconst occurrences = changes.reduce((total, count) => total + count, 0)\n\t\t\tif (limit !== undefined && occurrences >= limit) break\n\t\t\tif (!isTextContent(file.content)) continue\n\t\t\tconst remaining = limit === undefined ? undefined : limit - occurrences\n\t\t\tpattern.lastIndex = 0\n\t\t\tconst text = file.content.text\n\t\t\tconst matches = Array.from(text.matchAll(pattern))\n\t\t\tconst count = matches.filter(\n\t\t\t\t(_, index) => remaining === undefined || !(index >= remaining),\n\t\t\t).length\n\t\t\tconst positions = matches.keys()\n\t\t\tconst next = text.replace(pattern, (match) =>\n\t\t\t\t(positions.next().value ?? Number.POSITIVE_INFINITY) < count ? replacement : match,\n\t\t\t)\n\t\t\tif (count > 0) {\n\t\t\t\tchanges.push(count)\n\t\t\t\tthis.write(path, next)\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\toccurrences: changes.reduce((total, count) => total + count, 0),\n\t\t\tfiles: changes.length,\n\t\t}\n\t}\n\n\twrite(path: string, content: string): void\n\twrite(path: string, content: string, range: Range): void\n\twrite(files: Readonly<Record<string, string>>): void\n\twrite(path: string | Readonly<Record<string, string>>, content?: string, range?: Range): void {\n\t\tif (isRecord(path)) {\n\t\t\tfor (const [one, text] of Object.entries(path)) this.#write(one, text)\n\t\t\treturn\n\t\t}\n\t\tif (content === undefined) return\n\t\tif (!range) {\n\t\t\tthis.#write(path, content)\n\t\t\treturn\n\t\t}\n\t\tthis.#splice(path, content, range)\n\t}\n\n\tprepend(path: string, content: string): void\n\tprepend(files: Readonly<Record<string, string>>): void\n\tprepend(path: string | Readonly<Record<string, string>>, content?: string): void {\n\t\tif (isRecord(path)) {\n\t\t\tfor (const [one, text] of Object.entries(path)) this.#prepend(one, text)\n\t\t\treturn\n\t\t}\n\t\tif (content === undefined) return\n\t\tthis.#prepend(path, content)\n\t}\n\n\tappend(path: string, content: string): void\n\tappend(files: Readonly<Record<string, string>>): void\n\tappend(path: string | Readonly<Record<string, string>>, content?: string): void {\n\t\tif (isRecord(path)) {\n\t\t\tfor (const [one, text] of Object.entries(path)) this.#append(one, text)\n\t\t\treturn\n\t\t}\n\t\tif (content === undefined) return\n\t\tthis.#append(path, content)\n\t}\n\n\tmove(from: string, to: string): boolean\n\tmove(mapping: Readonly<Record<string, string>>): boolean\n\tmove(from: string | Readonly<Record<string, string>>, to?: string): boolean {\n\t\tif (isRecord(from)) {\n\t\t\treturn Object.entries(from).reduce(\n\t\t\t\t(moved, [one, target]) => this.#move(one, target) && moved,\n\t\t\t\ttrue,\n\t\t\t)\n\t\t}\n\t\tif (to === undefined) return false\n\t\treturn this.#move(from, to)\n\t}\n\n\tremove(path: string): boolean\n\tremove(paths: readonly string[]): boolean\n\tremove(path: string | readonly string[]): boolean {\n\t\tif (isArray(path)) {\n\t\t\treturn Iterator.from(path).reduce((removed, one) => this.#remove(one) && removed, true)\n\t\t}\n\t\treturn this.#remove(path)\n\t}\n\n\tclear(): void {\n\t\tthis.#files.clear()\n\t\tthis.#emitter.emit('clear')\n\t}\n\n\tsnapshot(): WorkspaceSnapshot {\n\t\treturn { id: this.#id, files: this.files() }\n\t}\n\n\tdestroy(): void {\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#write(path: string, content: string): void {\n\t\tconst existing = this.#files.get(path)\n\t\tconst language =\n\t\t\texisting && isTextContent(existing.content) ? existing.content.language : inferLanguage(path)\n\t\tconst file = createFile({\n\t\t\tpath,\n\t\t\tcontent: { text: content, language },\n\t\t\tstate: existing ? 'modified' : 'created',\n\t\t})\n\t\tthis.#files.set(path, file)\n\t\tthis.#emitter.emit('write', file)\n\t}\n\n\t#splice(path: string, content: string, range: Range): void {\n\t\tconst existing = this.#files.get(path)\n\t\tif (!existing) {\n\t\t\tthrow new WorkspaceError('MISSING', `Cannot splice a range of a missing file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\tif (!isTextContent(existing.content)) {\n\t\t\tthrow new WorkspaceError('MODALITY', `Cannot splice a range of a binary file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\tif (!isValidRange(range)) {\n\t\t\tthrow new WorkspaceError('RANGE', `Invalid range for file: ${path}`, { path, range })\n\t\t}\n\t\tconst file = createFile({\n\t\t\tpath,\n\t\t\tcontent: {\n\t\t\t\ttext: spliceRange(existing.content.text, range, content),\n\t\t\t\tlanguage: existing.content.language,\n\t\t\t},\n\t\t\tstate: 'modified',\n\t\t})\n\t\tthis.#files.set(path, file)\n\t\tthis.#emitter.emit('write', file)\n\t}\n\n\t#prepend(path: string, content: string): void {\n\t\tconst existing = this.#files.get(path)\n\t\tif (existing === undefined) {\n\t\t\tthis.#write(path, content)\n\t\t\treturn\n\t\t}\n\t\tif (!isTextContent(existing.content)) {\n\t\t\tthrow new WorkspaceError('MODALITY', `Cannot prepend text to a binary file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\tthis.#write(path, content + existing.content.text)\n\t}\n\n\t#append(path: string, content: string): void {\n\t\tconst existing = this.#files.get(path)\n\t\tif (existing === undefined) {\n\t\t\tthis.#write(path, content)\n\t\t\treturn\n\t\t}\n\t\tif (!isTextContent(existing.content)) {\n\t\t\tthrow new WorkspaceError('MODALITY', `Cannot append text to a binary file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\tthis.#write(path, existing.content.text + content)\n\t}\n\n\t#move(from: string, to: string): boolean {\n\t\tif (from === to) return false\n\t\tconst file = this.#files.get(from)\n\t\tif (!file) return false\n\t\tconst moved = createFile({ path: to, content: file.content, state: 'modified' })\n\t\tconst entries = [...this.#files]\n\t\tthis.#files.clear()\n\t\tfor (const [path, current] of entries) {\n\t\t\tif (path === from) this.#files.set(to, moved)\n\t\t\telse if (path !== to) this.#files.set(path, current)\n\t\t}\n\t\tthis.#emitter.emit('move', from, to)\n\t\treturn true\n\t}\n\n\t#remove(path: string): boolean {\n\t\tconst removed = this.#files.delete(path)\n\t\tif (removed) this.#emitter.emit('remove', path)\n\t\treturn removed\n\t}\n\n\t#pattern(query: string, options?: SearchOptions): RegExp {\n\t\tconst source = options?.regex === true ? query : escapeRegExp(query)\n\t\tconst flags = options?.sensitive === false ? 'gi' : 'g'\n\t\ttry {\n\t\t\treturn new RegExp(source, flags)\n\t\t} catch {\n\t\t\tthrow new WorkspaceError('PATTERN', `Invalid search pattern: ${query}`, { query })\n\t\t}\n\t}\n}\n","import type { EmitterErrorHandler, EmitterHooks } from '@orkestrel/emitter'\nimport type {\n\tWorkspaceEventMap,\n\tWorkspaceInterface,\n\tWorkspaceManagerInterface,\n\tWorkspaceManagerOptions,\n\tWorkspaceOptions,\n\tWorkspaceStoreInterface,\n} from '../types.js'\nimport { isArray } from '@orkestrel/contract'\nimport { Workspace } from './Workspace.js'\n\n/**\n * Implements `WorkspaceManagerInterface` over an insertion-ordered id map and one active id\n * the instance owns, resolving `active` through that map on every read and holding no emitter.\n *\n * A supplied store adds lenient snapshot `open` and `save` operations. Event defaults flow into\n * workspaces created through the registry, while observability remains owned by each workspace.\n *\n * @example\n * ```ts\n * import { WorkspaceManager } from '@orkestrel/workspace'\n *\n * const manager = new WorkspaceManager()\n * const workspace = manager.add({ id: 'scratch' })\n * manager.active === workspace\n * ```\n */\nexport class WorkspaceManager implements WorkspaceManagerInterface {\n\treadonly #workspaces = new Map<string, WorkspaceInterface>()\n\t#active: string | undefined\n\treadonly #on: EmitterHooks<WorkspaceEventMap> | undefined\n\treadonly #error: EmitterErrorHandler | undefined\n\treadonly #store: WorkspaceStoreInterface | undefined\n\n\t/**\n\t * Creates a registry.\n\t *\n\t * @param options - Default event hooks and optional snapshot store\n\t */\n\tconstructor(options?: WorkspaceManagerOptions) {\n\t\tthis.#on = options?.on\n\t\tthis.#error = options?.error\n\t\tthis.#store = options?.store\n\t}\n\n\tget count(): number {\n\t\treturn this.#workspaces.size\n\t}\n\n\tget active(): WorkspaceInterface | undefined {\n\t\treturn this.#active === undefined ? undefined : this.#workspaces.get(this.#active)\n\t}\n\n\tworkspace(id: string): WorkspaceInterface | undefined {\n\t\treturn this.#workspaces.get(id)\n\t}\n\n\tworkspaces(): readonly WorkspaceInterface[] {\n\t\treturn [...this.#workspaces.values()]\n\t}\n\n\tadd(options?: WorkspaceOptions): WorkspaceInterface {\n\t\tconst on = options?.on ?? this.#on\n\t\tconst error = options?.error ?? this.#error\n\t\tconst workspace = new Workspace({\n\t\t\t...(options?.id === undefined ? {} : { id: options.id }),\n\t\t\t...(on === undefined ? {} : { on }),\n\t\t\t...(error === undefined ? {} : { error }),\n\t\t\t...(options?.seed === undefined ? {} : { seed: options.seed }),\n\t\t})\n\t\tthis.#workspaces.set(workspace.id, workspace)\n\t\tif (this.#active === undefined) this.#active = workspace.id\n\t\treturn workspace\n\t}\n\n\tswitch(id: string): WorkspaceInterface | undefined {\n\t\tconst workspace = this.#workspaces.get(id)\n\t\tif (workspace === undefined) return undefined\n\t\tthis.#active = id\n\t\treturn workspace\n\t}\n\n\tasync open(id: string): Promise<WorkspaceInterface | undefined> {\n\t\tconst existing = this.#workspaces.get(id)\n\t\tif (existing !== undefined) {\n\t\t\tthis.#active = id\n\t\t\treturn existing\n\t\t}\n\t\tif (this.#store === undefined) return undefined\n\t\tconst snapshot = await this.#store.get(id)\n\t\tif (snapshot === undefined) return undefined\n\t\tconst workspace = this.add({ id, seed: snapshot.files })\n\t\tthis.#active = workspace.id\n\t\treturn workspace\n\t}\n\n\tasync save(id: string): Promise<boolean> {\n\t\tconst workspace = this.#workspaces.get(id)\n\t\tif (this.#store === undefined || workspace === undefined) return false\n\t\tawait this.#store.set(workspace.snapshot())\n\t\treturn true\n\t}\n\n\tremove(id: string): boolean\n\tremove(ids: readonly string[]): boolean\n\tremove(ids: string | readonly string[]): boolean {\n\t\tif (isArray(ids)) {\n\t\t\treturn Iterator.from(ids).reduce((removed, id) => this.#drop(id) && removed, true)\n\t\t}\n\t\treturn this.#drop(ids)\n\t}\n\n\tclear(): void {\n\t\tfor (const workspace of this.#workspaces.values()) workspace.destroy()\n\t\tthis.#workspaces.clear()\n\t\tthis.#active = undefined\n\t}\n\n\t#drop(id: string): boolean {\n\t\tconst workspace = this.#workspaces.get(id)\n\t\tif (workspace === undefined) return false\n\t\tthis.#workspaces.delete(id)\n\t\tworkspace.destroy()\n\t\tif (this.#active === id) this.#active = undefined\n\t\treturn true\n\t}\n}\n","import type {\n\tWorkspaceSnapshot,\n\tWorkspaceSnapshotRow,\n\tWorkspaceStoreInterface,\n} from '../../types.js'\nimport type { TableInterface } from '@orkestrel/database'\nimport { isWorkspaceSnapshot } from '../../validators.js'\n\n/**\n * Persists workspace snapshots in a database table.\n *\n * Snapshots occupy one opaque column and are narrowed when read back from the storage boundary.\n *\n * @example\n * ```ts\n * import { rawShape, stringShape } from '@orkestrel/contract'\n * import { createDatabase, createMemoryDriver } from '@orkestrel/database'\n * import { DatabaseWorkspaceStore } from '@orkestrel/workspace'\n *\n * const database = createDatabase({\n * \tdriver: createMemoryDriver(),\n * \ttables: { workspaces: { id: stringShape(), snapshot: rawShape({}) } },\n * })\n * const store = new DatabaseWorkspaceStore(database.table('workspaces'))\n * ```\n */\nexport class DatabaseWorkspaceStore implements WorkspaceStoreInterface {\n\treadonly #table: TableInterface<WorkspaceSnapshotRow>\n\n\t/**\n\t * Wraps a workspace snapshot table.\n\t *\n\t * @param table - The table keyed by workspace identifier\n\t */\n\tconstructor(table: TableInterface<WorkspaceSnapshotRow>) {\n\t\tthis.#table = table\n\t}\n\n\tasync get(id: string): Promise<WorkspaceSnapshot | undefined> {\n\t\tconst row = await this.#table.get(id)\n\t\tif (row === undefined) return undefined\n\t\treturn isWorkspaceSnapshot(row.snapshot) ? row.snapshot : undefined\n\t}\n\n\tasync set(snapshot: WorkspaceSnapshot): Promise<void> {\n\t\tawait this.#table.set({ id: snapshot.id, snapshot })\n\t}\n\n\tasync delete(id: string): Promise<void> {\n\t\tawait this.#table.remove(id)\n\t}\n}\n","import type { WorkspaceSnapshot, WorkspaceStoreInterface } from '../../types.js'\n\n/**\n * Holds workspace snapshots in the current process.\n *\n * @example\n * ```ts\n * import { MemoryWorkspaceStore } from '@orkestrel/workspace'\n *\n * const store = new MemoryWorkspaceStore()\n * ```\n */\nexport class MemoryWorkspaceStore implements WorkspaceStoreInterface {\n\treadonly #snapshots = new Map<string, WorkspaceSnapshot>()\n\n\tget(id: string): Promise<WorkspaceSnapshot | undefined> {\n\t\treturn Promise.resolve(this.#snapshots.get(id))\n\t}\n\n\tset(snapshot: WorkspaceSnapshot): Promise<void> {\n\t\tthis.#snapshots.set(snapshot.id, snapshot)\n\t\treturn Promise.resolve()\n\t}\n\n\tdelete(id: string): Promise<void> {\n\t\tthis.#snapshots.delete(id)\n\t\treturn Promise.resolve()\n\t}\n}\n","import type {\n\tBinaryContent,\n\tBinaryMIME,\n\tFileInput,\n\tFileInterface,\n\tTextContent,\n\tWorkspaceInterface,\n\tWorkspaceManagerInterface,\n\tWorkspaceManagerOptions,\n\tWorkspaceOptions,\n\tWorkspaceSnapshotRow,\n\tWorkspaceStoreInterface,\n} from './types.js'\nimport type { DriverInterface, TableInterface } from '@orkestrel/database'\nimport { rawShape, stringShape } from '@orkestrel/contract'\nimport { createDatabase, createMemoryDriver } from '@orkestrel/database'\nimport { computeSize, countLines } from './helpers.js'\nimport { Workspace } from './workspaces/Workspace.js'\nimport { WorkspaceManager } from './workspaces/WorkspaceManager.js'\nimport { DatabaseWorkspaceStore } from './workspaces/stores/DatabaseWorkspaceStore.js'\nimport { MemoryWorkspaceStore } from './workspaces/stores/MemoryWorkspaceStore.js'\n\n/**\n * Creates an immutable file with derived size and line counts.\n *\n * @param input - The file path, content, and optional state\n * @returns A frozen file record\n *\n * @example Files and content\n * ```ts\n * import {\n * \tcomputeSize,\n * \tcountLines,\n * \tcreateBinaryContent,\n * \tcreateFile,\n * \tcreateTextContent,\n * \tinferLanguage,\n * \tisBinary,\n * \tisTextContent,\n * } from '@orkestrel/workspace'\n *\n * const note = createFile({\n * \tpath: 'notes.md',\n * \tcontent: createTextContent('# Title\\nBody', inferLanguage('notes.md')), // 'markdown'\n * })\n *\n * note.size // 12 — UTF-8 bytes, through computeSize\n * note.lines // 2 — through countLines\n * note.state // 'created'\n * isTextContent(note.content) // true\n *\n * const icon = createFile({ path: 'icon.png', content: createBinaryContent('AAAA', 'image/png') })\n * isBinary(icon.content) // true\n * icon.size // 3 — decoded base64 bytes, through computeDecodedSize\n * ```\n */\nexport function createFile(input: FileInput): FileInterface {\n\treturn Object.freeze({\n\t\tpath: input.path,\n\t\tcontent: input.content,\n\t\tstate: input.state ?? 'created',\n\t\tsize: computeSize(input.content),\n\t\tlines: countLines(input.content),\n\t})\n}\n\n/**\n * Creates the text arm of {@link FileContent}, returned as {@link TextContent} rather than as\n * the whole union.\n *\n * @param text - The text body\n * @param language - The language tag\n * @returns Text file content\n *\n * @example\n * ```ts\n * import { createTextContent } from '@orkestrel/workspace'\n *\n * createTextContent('hello', 'text')\n * ```\n */\nexport function createTextContent(text: string, language: string): TextContent {\n\treturn { text, language }\n}\n\n/**\n * Creates the binary arm of {@link FileContent}, returned as {@link BinaryContent} rather than\n * as the whole union.\n *\n * @param base64 - The base64 payload\n * @param mime - The binary MIME\n * @returns Binary file content\n *\n * @example\n * ```ts\n * import { createBinaryContent } from '@orkestrel/workspace'\n *\n * createBinaryContent('AAAA', 'image/png')\n * ```\n */\nexport function createBinaryContent(base64: string, mime: BinaryMIME): BinaryContent {\n\treturn { base64, mime }\n}\n\n/**\n * Creates a workspace with the same identity, emitter, and seed options the constructor takes.\n *\n * @param options - Optional identity, emitter configuration, and initial files\n * @returns A working workspace\n *\n * @example\n * ```ts\n * import { createWorkspace } from '@orkestrel/workspace'\n *\n * const workspace = createWorkspace()\n * workspace.write('a.txt', 'hello')\n * ```\n */\nexport function createWorkspace(options?: WorkspaceOptions): WorkspaceInterface {\n\treturn new Workspace(options)\n}\n\n/**\n * Creates an in-memory workspace snapshot store.\n *\n * @returns A process-local workspace store\n *\n * @example\n * ```ts\n * import { createMemoryWorkspaceStore } from '@orkestrel/workspace'\n *\n * const store = createMemoryWorkspaceStore()\n * ```\n */\nexport function createMemoryWorkspaceStore(): WorkspaceStoreInterface {\n\treturn new MemoryWorkspaceStore()\n}\n\n/**\n * Creates a database-backed workspace snapshot store, over an in-memory driver when the caller\n * supplies none.\n *\n * @param driver - The database driver. Default: an in-memory driver.\n * @returns A workspace store backed by the supplied driver\n *\n * @example\n * ```ts\n * import { createDatabaseWorkspaceStore } from '@orkestrel/workspace'\n *\n * const store = createDatabaseWorkspaceStore()\n * ```\n */\nexport function createDatabaseWorkspaceStore(\n\tdriver: DriverInterface = createMemoryDriver(),\n): WorkspaceStoreInterface {\n\tconst columns = { id: stringShape(), snapshot: rawShape({}) }\n\tconst database = createDatabase({ driver, tables: { workspaces: columns } })\n\tconst table: TableInterface<WorkspaceSnapshotRow> = database.table('workspaces')\n\treturn new DatabaseWorkspaceStore(table)\n}\n\n/**\n * Creates an empty workspace registry.\n *\n * @param options - Default event hooks and optional durability\n * @returns A workspace manager\n *\n * @example\n * ```ts\n * import { createWorkspaceManager } from '@orkestrel/workspace'\n *\n * const manager = createWorkspaceManager()\n * manager.add()\n * ```\n */\nexport function createWorkspaceManager(\n\toptions?: WorkspaceManagerOptions,\n): WorkspaceManagerInterface {\n\treturn new WorkspaceManager(options)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["holds","INTRINSICS","isObject","isFunction","holds","isRecord","isString","literalOf","isNumber","arrayOf","Emitter","isArray","isRecord","escapeRegExp","arrayOf","isString","isArray","createMemoryDriver","stringShape","rawShape","createDatabase"],"sources":["../../../src/core/constants.ts","../../../src/core/errors.ts","../../../src/core/helpers.ts","../../../src/core/validators.ts","../../../src/core/workspaces/Workspace.ts","../../../src/core/workspaces/WorkspaceManager.ts","../../../src/core/workspaces/stores/DatabaseWorkspaceStore.ts","../../../src/core/workspaces/stores/MemoryWorkspaceStore.ts","../../../src/core/factories.ts"],"sourcesContent":["/**\n * Maps file extensions to language tags for text content.\n *\n * The table is frozen, and an extension it does not list falls back to `text` in\n * {@link import('./helpers.js').inferLanguage}.\n */\nexport const EXTENSION_LANGUAGES: Readonly<Record<string, string>> = Object.freeze({\n\tts: 'typescript',\n\ttsx: 'typescript',\n\tjs: 'javascript',\n\tjsx: 'javascript',\n\tmjs: 'javascript',\n\tcjs: 'javascript',\n\tjson: 'json',\n\tmd: 'markdown',\n\thtml: 'html',\n\thtm: 'html',\n\tcss: 'css',\n\tscss: 'scss',\n\tsass: 'sass',\n\tless: 'less',\n\tvue: 'vue',\n\tsvelte: 'svelte',\n\tpy: 'python',\n\trb: 'ruby',\n\trs: 'rust',\n\tgo: 'go',\n\tjava: 'java',\n\tkt: 'kotlin',\n\tswift: 'swift',\n\tc: 'c',\n\tcpp: 'cpp',\n\th: 'c',\n\thpp: 'cpp',\n\tcs: 'csharp',\n\tphp: 'php',\n\tsql: 'sql',\n\tsh: 'bash',\n\tbash: 'bash',\n\tzsh: 'bash',\n\tps1: 'powershell',\n\tyaml: 'yaml',\n\tyml: 'yaml',\n\ttoml: 'toml',\n\txml: 'xml',\n\tsvg: 'xml',\n\ttxt: 'text',\n})\n","import type { WorkspaceErrorCode } from './types.js'\nimport { holds, INTRINSICS, isFunction, isObject } from '@orkestrel/contract'\n\n/**\n * Reports an invalid workspace edit or search operation, carrying a {@link WorkspaceErrorCode}\n * and, when the operation had one, the context it ran under.\n */\nexport class WorkspaceError extends Error {\n\treadonly code: WorkspaceErrorCode\n\treadonly context?: Readonly<Record<string, unknown>>\n\n\t/**\n\t * Creates a workspace error.\n\t *\n\t * @param code - The machine-readable failure code\n\t * @param message - The human-readable failure message\n\t * @param context - Optional values associated with the failed operation\n\t */\n\tconstructor(\n\t\tcode: WorkspaceErrorCode,\n\t\tmessage: string,\n\t\tcontext?: Readonly<Record<string, unknown>>,\n\t) {\n\t\tsuper(message)\n\t\tINTRINSICS.define(this, Symbol.for('@orkestrel/workspace.WorkspaceError'), { value: this })\n\t\tthis.name = 'WorkspaceError'\n\t\tthis.code = code\n\t\tif (context !== undefined) this.context = context\n\t}\n}\n\n/**\n * Narrows a caught value to a {@link WorkspaceError}.\n *\n * @remarks\n * Checks the identity brand and declared members across package copies, accepting subclasses\n * and refusing transparent proxies. Inspection failures return false.\n *\n * @param value - The caught value\n * @returns True if the value is a workspace error; false otherwise\n *\n * @example\n * ```ts\n * if (isWorkspaceError(error)) error.code\n * ```\n */\nexport function isWorkspaceError(value: unknown): value is WorkspaceError {\n\treturn holds(() => {\n\t\tif (!(value instanceof Error) || INTRINSICS.prototype(value) === Error.prototype) return false\n\t\tconst brand = INTRINSICS.describe(value, Symbol.for('@orkestrel/workspace.WorkspaceError'))\n\t\tif (brand?.value !== value) return false\n\t\tconst code: unknown = INTRINSICS.reflect.read(value, 'code')\n\t\tif (\n\t\t\tcode !== 'MISSING' &&\n\t\t\tcode !== 'MODALITY' &&\n\t\t\tcode !== 'PATHS' &&\n\t\t\tcode !== 'PATTERN' &&\n\t\t\tcode !== 'RANGE'\n\t\t)\n\t\t\treturn false\n\t\tconst context: unknown = INTRINSICS.reflect.read(value, 'context')\n\t\treturn context === undefined || isObject(context) || isFunction(context)\n\t})\n}\n","import type { BinaryContent, Caret, FileContent, Range, TextContent } from './types.js'\nimport { EXTENSION_LANGUAGES } from './constants.js'\n\n/**\n * Infers a language tag from the final file extension.\n *\n * @param path - The file path\n * @returns The mapped language, or `text` when the extension is absent or unknown\n *\n * @example\n * ```ts\n * inferLanguage('src/main.ts') // 'typescript'\n * ```\n */\nexport function inferLanguage(path: string): string {\n\tconst dot = path.lastIndexOf('.')\n\tif (dot === -1) return 'text'\n\tconst extension = path.slice(dot + 1).toLowerCase()\n\treturn EXTENSION_LANGUAGES[extension] ?? 'text'\n}\n\n/**\n * Determines whether content is the text arm.\n *\n * @param content - The file content\n * @returns True if the content carries text and a language; false otherwise\n *\n * @example\n * ```ts\n * isTextContent({ text: 'hello', language: 'text' }) // true\n * ```\n */\nexport function isTextContent(content: FileContent): content is TextContent {\n\treturn 'text' in content\n}\n\n/**\n * Determines whether content is the binary arm.\n *\n * @param content - The file content\n * @returns True if the content carries a base64 string and a MIME; false otherwise\n *\n * @example\n * ```ts\n * isBinary({ base64: 'AAAA', mime: 'image/png' }) // true\n * ```\n */\nexport function isBinary(content: FileContent): content is BinaryContent {\n\treturn 'base64' in content\n}\n\n/**\n * Computes the byte size of file content.\n *\n * @param content - The content to measure\n * @returns UTF-8 bytes for text or decoded bytes for binary content\n *\n * @example\n * ```ts\n * computeSize({ text: 'café', language: 'text' }) // 5\n * ```\n */\nexport function computeSize(content: FileContent): number {\n\tif (isTextContent(content)) return new TextEncoder().encode(content.text).length\n\treturn computeDecodedSize(content.base64)\n}\n\n/**\n * Counts the lines in file content.\n *\n * @param content - The content to inspect\n * @returns The text line count, or zero for empty text and binary content\n *\n * @example\n * ```ts\n * countLines({ text: 'a\\nb', language: 'text' }) // 2\n * ```\n */\nexport function countLines(content: FileContent): number {\n\tif (!isTextContent(content)) return 0\n\tif (content.text.length === 0) return 0\n\treturn content.text.split(/\\r\\n|\\n/).length\n}\n\n/**\n * Computes the decoded byte length of a base64 string, arithmetically rather than by decoding it.\n *\n * @param base64 - The base64 string\n * @returns The decoded byte count\n *\n * @example\n * ```ts\n * computeDecodedSize('AAAA') // 3\n * ```\n */\nexport function computeDecodedSize(base64: string): number {\n\tconst padding = base64.endsWith('==') ? 2 : base64.endsWith('=') ? 1 : 0\n\treturn Math.floor((base64.length * 3) / 4) - padding\n}\n\n/**\n * Determines whether a 1-based range is structurally valid.\n *\n * @param range - The range to inspect\n * @returns True if both carets are positive and ordered; false otherwise\n *\n * @example\n * ```ts\n * isValidRange({ start: { line: 1, column: 1 }, end: { line: 1, column: 2 } }) // true\n * ```\n */\nexport function isValidRange(range: Range): boolean {\n\tif (range.start.line < 1 || range.start.column < 1) return false\n\tif (range.end.line < 1 || range.end.column < 1) return false\n\tif (range.start.line > range.end.line) return false\n\treturn !(range.start.line === range.end.line && range.start.column > range.end.column)\n}\n\n/**\n * Clamps a caret to text bounds.\n *\n * @param text - The addressed text\n * @param caret - The requested caret\n * @returns The clamped caret\n *\n * @example\n * ```ts\n * clampCaret('ab', { line: 9, column: 9 }) // { line: 1, column: 3 }\n * ```\n */\nexport function clampCaret(text: string, caret: Caret): Caret {\n\tconst lines = text.split('\\n')\n\tconst line = Math.max(1, Math.min(caret.line, lines.length))\n\tconst lineText = lines[line - 1] ?? ''\n\tconst column = Math.max(1, Math.min(caret.column, lineText.length + 1))\n\treturn { line, column }\n}\n\n/**\n * Clamps both carets in a range to text bounds.\n *\n * @param text - The addressed text\n * @param range - The requested range\n * @returns The clamped range\n *\n * @example\n * ```ts\n * clampRange('ab', { start: { line: 1, column: 1 }, end: { line: 9, column: 9 } })\n * ```\n */\nexport function clampRange(text: string, range: Range): Range {\n\treturn { start: clampCaret(text, range.start), end: clampCaret(text, range.end) }\n}\n\n/**\n * Converts a 1-based caret to a zero-based string offset.\n *\n * @param text - The addressed text\n * @param caret - The requested caret\n * @returns The bounded string offset\n *\n * @example\n * ```ts\n * offsetAt('ab\\ncd', { line: 2, column: 1 }) // 3\n * ```\n */\nexport function offsetAt(text: string, caret: Caret): number {\n\tconst lines = text.split('\\n')\n\tconst offset = lines\n\t\t.filter((_, index) => index < caret.line - 1)\n\t\t.reduce((total, line) => total + line.length + 1, 0)\n\treturn Math.min(offset + (caret.column - 1), text.length)\n}\n\n/**\n * Slices a clamped half-open text range.\n *\n * @param text - The source text\n * @param range - The requested range\n * @returns The ranged substring\n *\n * @example\n * ```ts\n * sliceRange('hello', { start: { line: 1, column: 1 }, end: { line: 1, column: 6 } }) // 'hello'\n * ```\n */\nexport function sliceRange(text: string, range: Range): string {\n\tconst clamped = clampRange(text, range)\n\treturn text.slice(offsetAt(text, clamped.start), offsetAt(text, clamped.end))\n}\n\n/**\n * Replaces a clamped half-open text range.\n *\n * @param text - The source text\n * @param range - The requested range\n * @param replacement - The replacement text\n * @returns The spliced text\n *\n * @example\n * ```ts\n * spliceRange('hello', { start: { line: 1, column: 1 }, end: { line: 1, column: 6 } }, 'bye')\n * ```\n */\nexport function spliceRange(text: string, range: Range, replacement: string): string {\n\tconst clamped = clampRange(text, range)\n\tconst start = offsetAt(text, clamped.start)\n\tconst end = offsetAt(text, clamped.end)\n\treturn text.slice(0, start) + replacement + text.slice(end)\n}\n\n/**\n * Assembles a nested range from four 1-based coordinates.\n *\n * @param fromLine - The start line\n * @param fromColumn - The start column\n * @param toLine - The end line\n * @param toColumn - The end column\n * @returns The assembled range without validation\n *\n * @example\n * ```ts\n * rangeOf(1, 1, 1, 2)\n * ```\n */\nexport function rangeOf(\n\tfromLine: number,\n\tfromColumn: number,\n\ttoLine: number,\n\ttoColumn: number,\n): Range {\n\treturn { start: { line: fromLine, column: fromColumn }, end: { line: toLine, column: toColumn } }\n}\n","import type { FileInterface, WorkspaceSnapshot } from './types.js'\nimport { arrayOf, holds, isNumber, isRecord, isString, literalOf } from '@orkestrel/contract'\n\n/**\n * Narrows an unknown value to an immutable file record.\n *\n * @param value - The value to inspect\n * @returns True if the value has the file shape; false otherwise\n *\n * @example\n * ```ts\n * isFile({ path: 'a.txt', content: { text: 'a', language: 'text' }, state: 'created', size: 1, lines: 1 })\n * ```\n */\nexport function isFile(value: unknown): value is FileInterface {\n\treturn holds(() => {\n\t\tif (!isRecord(value)) return false\n\t\tif (!isString(value.path) || !literalOf('created', 'modified')(value.state)) return false\n\t\tif (!isNumber(value.size) || !isNumber(value.lines)) return false\n\t\tif (!isRecord(value.content)) return false\n\t\tconst text = isString(value.content.text) && isString(value.content.language)\n\t\tconst binary =\n\t\t\tisString(value.content.base64) &&\n\t\t\tliteralOf('image/png', 'image/jpeg', 'image/gif', 'image/webp')(value.content.mime)\n\t\treturn text || binary\n\t})\n}\n\n/**\n * Narrows an unknown value to a workspace snapshot.\n *\n * @param value - The value read from a persistence boundary\n * @returns True if the value has the workspace snapshot shape; false otherwise\n *\n * @example\n * ```ts\n * isWorkspaceSnapshot({ id: 'work', files: [] }) // true\n * ```\n */\nexport function isWorkspaceSnapshot(value: unknown): value is WorkspaceSnapshot {\n\treturn holds(() => isRecord(value) && isString(value.id) && arrayOf(isFile)(value.files))\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tFileInterface,\n\tRange,\n\tReadResult,\n\tReplaceResult,\n\tSearchMatch,\n\tSearchOptions,\n\tWorkspaceEventMap,\n\tWorkspaceInterface,\n\tWorkspaceOptions,\n\tWorkspaceSnapshot,\n} from '../types.js'\nimport { arrayOf, escapeRegExp, isArray, isRecord, isString } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { WorkspaceError } from '../errors.js'\nimport { createFile } from '../factories.js'\nimport {\n\tclampRange,\n\tinferLanguage,\n\tisTextContent,\n\tisValidRange,\n\tsliceRange,\n\tspliceRange,\n} from '../helpers.js'\n\n/**\n * Implements `WorkspaceInterface` over one insertion-ordered path map the instance owns,\n * projecting fresh arrays on every read.\n *\n * Whole-file edits create text files, ranged edits operate only on existing text files, and\n * binary files remain available through construction-time hydration. Mutations emit after the\n * file map has changed.\n *\n * @example\n * ```ts\n * import { Workspace } from '@orkestrel/workspace'\n *\n * const workspace = new Workspace()\n * workspace.write('notes.txt', 'hello')\n * workspace.append('notes.txt', ' world')\n * workspace.read('notes.txt') // 'hello world'\n * ```\n */\nexport class Workspace implements WorkspaceInterface {\n\treadonly #id: string\n\treadonly #files = new Map<string, FileInterface>()\n\treadonly #emitter: Emitter<WorkspaceEventMap>\n\n\t/**\n\t * Creates a workspace.\n\t *\n\t * @param options - Optional identity, emitter configuration, and initial files\n\t */\n\tconstructor(options?: WorkspaceOptions) {\n\t\tthis.#id = options?.id ?? crypto.randomUUID()\n\t\tthis.#emitter = new Emitter<WorkspaceEventMap>({\n\t\t\t...(options?.on === undefined ? {} : { on: options.on }),\n\t\t\t...(options?.error === undefined ? {} : { error: options.error }),\n\t\t})\n\t\tif (options?.seed) for (const file of options.seed) this.#files.set(file.path, file)\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tget emitter(): EmitterInterface<WorkspaceEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget count(): number {\n\t\treturn this.#files.size\n\t}\n\n\tfile(path: string): FileInterface | undefined {\n\t\treturn this.#files.get(path)\n\t}\n\n\tfiles(): readonly FileInterface[] {\n\t\treturn [...this.#files.values()]\n\t}\n\n\tread(path: string): string | undefined\n\tread(path: string, range: Range): ReadResult | undefined\n\tread(paths: readonly string[]): Readonly<Record<string, string>>\n\tread(\n\t\tpath: string | readonly string[],\n\t\trange?: Range,\n\t): string | ReadResult | undefined | Readonly<Record<string, string>> {\n\t\tif (isArray(path)) {\n\t\t\tconst result: Record<string, string> = {}\n\t\t\tfor (const one of path) {\n\t\t\t\tconst file = this.#files.get(one)\n\t\t\t\tif (file && isTextContent(file.content)) result[one] = file.content.text\n\t\t\t}\n\t\t\treturn result\n\t\t}\n\t\tconst file = this.#files.get(path)\n\t\tif (!file) return undefined\n\t\tif (!range) return isTextContent(file.content) ? file.content.text : undefined\n\t\tif (!isTextContent(file.content)) {\n\t\t\tthrow new WorkspaceError('MODALITY', `Cannot read a range of a binary file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\treturn {\n\t\t\tcontent: sliceRange(file.content.text, range),\n\t\t\trange: clampRange(file.content.text, range),\n\t\t}\n\t}\n\n\thas(path: string): boolean\n\thas(paths: readonly string[]): boolean\n\thas(path: string | readonly string[]): boolean {\n\t\tif (isArray(path)) return path.every((one) => this.#files.has(one))\n\t\treturn this.#files.has(path)\n\t}\n\n\tsearch(query: string, options?: SearchOptions): readonly SearchMatch[] {\n\t\tconst pattern = this.#pattern(query, options)\n\t\tconst paths = this.#paths(options)\n\t\tconst limit = options?.limit\n\t\tconst matches: SearchMatch[] = []\n\t\tfor (const file of this.#files.values()) {\n\t\t\tif (limit !== undefined && matches.length >= limit) break\n\t\t\tif (paths !== undefined && !paths.has(file.path)) continue\n\t\t\tif (!isTextContent(file.content)) continue\n\t\t\tconst lines = file.content.text.split(/\\r\\n|\\n/)\n\t\t\tfor (const [index, lineText] of lines.entries()) {\n\t\t\t\tif (limit !== undefined && matches.length >= limit) break\n\t\t\t\tpattern.lastIndex = 0\n\t\t\t\tfor (const hit of lineText.matchAll(pattern)) {\n\t\t\t\t\tif (limit !== undefined && matches.length >= limit) break\n\t\t\t\t\tmatches.push({\n\t\t\t\t\t\tpath: file.path,\n\t\t\t\t\t\tline: index + 1,\n\t\t\t\t\t\tcolumn: hit.index + 1,\n\t\t\t\t\t\tlength: hit[0].length,\n\t\t\t\t\t\tcontent: lineText,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn matches\n\t}\n\n\treplace(query: string, replacement: string, options?: SearchOptions): ReplaceResult {\n\t\tconst pattern = this.#pattern(query, options)\n\t\tconst paths = this.#paths(options)\n\t\tconst limit = options?.limit\n\t\tconst changes: number[] = []\n\t\tfor (const [path, file] of this.#files) {\n\t\t\tconst occurrences = changes.reduce((total, count) => total + count, 0)\n\t\t\tif (limit !== undefined && occurrences >= limit) break\n\t\t\tif (paths !== undefined && !paths.has(path)) continue\n\t\t\tif (!isTextContent(file.content)) continue\n\t\t\tconst remaining = limit === undefined ? undefined : limit - occurrences\n\t\t\tpattern.lastIndex = 0\n\t\t\tconst text = file.content.text\n\t\t\tconst matches = Array.from(text.matchAll(pattern))\n\t\t\tconst count = matches.filter(\n\t\t\t\t(_, index) => remaining === undefined || !(index >= remaining),\n\t\t\t).length\n\t\t\tconst positions = matches.keys()\n\t\t\tconst next = text.replace(pattern, (match) =>\n\t\t\t\t(positions.next().value ?? Number.POSITIVE_INFINITY) < count ? replacement : match,\n\t\t\t)\n\t\t\tif (count > 0) {\n\t\t\t\tchanges.push(count)\n\t\t\t\tthis.write(path, next)\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\toccurrences: changes.reduce((total, count) => total + count, 0),\n\t\t\tfiles: changes.length,\n\t\t}\n\t}\n\n\twrite(path: string, content: string): void\n\twrite(path: string, content: string, range: Range): void\n\twrite(files: Readonly<Record<string, string>>): void\n\twrite(path: string | Readonly<Record<string, string>>, content?: string, range?: Range): void {\n\t\tif (isRecord(path)) {\n\t\t\tfor (const [one, text] of Object.entries(path)) this.#write(one, text)\n\t\t\treturn\n\t\t}\n\t\tif (content === undefined) return\n\t\tif (!range) {\n\t\t\tthis.#write(path, content)\n\t\t\treturn\n\t\t}\n\t\tthis.#splice(path, content, range)\n\t}\n\n\tprepend(path: string, content: string): void\n\tprepend(files: Readonly<Record<string, string>>): void\n\tprepend(path: string | Readonly<Record<string, string>>, content?: string): void {\n\t\tif (isRecord(path)) {\n\t\t\tfor (const [one, text] of Object.entries(path)) this.#prepend(one, text)\n\t\t\treturn\n\t\t}\n\t\tif (content === undefined) return\n\t\tthis.#prepend(path, content)\n\t}\n\n\tappend(path: string, content: string): void\n\tappend(files: Readonly<Record<string, string>>): void\n\tappend(path: string | Readonly<Record<string, string>>, content?: string): void {\n\t\tif (isRecord(path)) {\n\t\t\tfor (const [one, text] of Object.entries(path)) this.#append(one, text)\n\t\t\treturn\n\t\t}\n\t\tif (content === undefined) return\n\t\tthis.#append(path, content)\n\t}\n\n\tmove(from: string, to: string): boolean\n\tmove(mapping: Readonly<Record<string, string>>): boolean\n\tmove(from: string | Readonly<Record<string, string>>, to?: string): boolean {\n\t\tif (isRecord(from)) {\n\t\t\treturn Object.entries(from).reduce(\n\t\t\t\t(moved, [one, target]) => this.#move(one, target) && moved,\n\t\t\t\ttrue,\n\t\t\t)\n\t\t}\n\t\tif (to === undefined) return false\n\t\treturn this.#move(from, to)\n\t}\n\n\tremove(path: string): boolean\n\tremove(paths: readonly string[]): boolean\n\tremove(path: string | readonly string[]): boolean {\n\t\tif (isArray(path)) {\n\t\t\treturn Iterator.from(path).reduce((removed, one) => this.#remove(one) && removed, true)\n\t\t}\n\t\treturn this.#remove(path)\n\t}\n\n\tclear(): void {\n\t\tthis.#files.clear()\n\t\tthis.#emitter.emit('clear')\n\t}\n\n\tsnapshot(): WorkspaceSnapshot {\n\t\treturn { id: this.#id, files: this.files() }\n\t}\n\n\tdestroy(): void {\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#write(path: string, content: string): void {\n\t\tconst existing = this.#files.get(path)\n\t\tconst language =\n\t\t\texisting && isTextContent(existing.content) ? existing.content.language : inferLanguage(path)\n\t\tconst file = createFile({\n\t\t\tpath,\n\t\t\tcontent: { text: content, language },\n\t\t\tstate: existing ? 'modified' : 'created',\n\t\t})\n\t\tthis.#files.set(path, file)\n\t\tthis.#emitter.emit('write', file)\n\t}\n\n\t#splice(path: string, content: string, range: Range): void {\n\t\tconst existing = this.#files.get(path)\n\t\tif (!existing) {\n\t\t\tthrow new WorkspaceError('MISSING', `Cannot splice a range of a missing file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\tif (!isTextContent(existing.content)) {\n\t\t\tthrow new WorkspaceError('MODALITY', `Cannot splice a range of a binary file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\tif (!isValidRange(range)) {\n\t\t\tthrow new WorkspaceError('RANGE', `Invalid range for file: ${path}`, { path, range })\n\t\t}\n\t\tconst file = createFile({\n\t\t\tpath,\n\t\t\tcontent: {\n\t\t\t\ttext: spliceRange(existing.content.text, range, content),\n\t\t\t\tlanguage: existing.content.language,\n\t\t\t},\n\t\t\tstate: 'modified',\n\t\t})\n\t\tthis.#files.set(path, file)\n\t\tthis.#emitter.emit('write', file)\n\t}\n\n\t#prepend(path: string, content: string): void {\n\t\tconst existing = this.#files.get(path)\n\t\tif (existing === undefined) {\n\t\t\tthis.#write(path, content)\n\t\t\treturn\n\t\t}\n\t\tif (!isTextContent(existing.content)) {\n\t\t\tthrow new WorkspaceError('MODALITY', `Cannot prepend text to a binary file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\tthis.#write(path, content + existing.content.text)\n\t}\n\n\t#append(path: string, content: string): void {\n\t\tconst existing = this.#files.get(path)\n\t\tif (existing === undefined) {\n\t\t\tthis.#write(path, content)\n\t\t\treturn\n\t\t}\n\t\tif (!isTextContent(existing.content)) {\n\t\t\tthrow new WorkspaceError('MODALITY', `Cannot append text to a binary file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\tthis.#write(path, existing.content.text + content)\n\t}\n\n\t#move(from: string, to: string): boolean {\n\t\tif (from === to) return false\n\t\tconst file = this.#files.get(from)\n\t\tif (!file) return false\n\t\tconst moved = createFile({ path: to, content: file.content, state: 'modified' })\n\t\tconst entries = [...this.#files]\n\t\tthis.#files.clear()\n\t\tfor (const [path, current] of entries) {\n\t\t\tif (path === from) this.#files.set(to, moved)\n\t\t\telse if (path !== to) this.#files.set(path, current)\n\t\t}\n\t\tthis.#emitter.emit('move', from, to)\n\t\treturn true\n\t}\n\n\t#remove(path: string): boolean {\n\t\tconst removed = this.#files.delete(path)\n\t\tif (removed) this.#emitter.emit('remove', path)\n\t\treturn removed\n\t}\n\n\t#pattern(query: string, options?: SearchOptions): RegExp {\n\t\tconst source = options?.regex === true ? query : escapeRegExp(query)\n\t\tconst flags = options?.sensitive === false ? 'gi' : 'g'\n\t\ttry {\n\t\t\treturn new RegExp(source, flags)\n\t\t} catch {\n\t\t\tthrow new WorkspaceError('PATTERN', `Invalid search pattern: ${query}`, { query })\n\t\t}\n\t}\n\n\t// Reads the `paths` option into one membership set for the call, refusing a malformed list.\n\t#paths(options?: SearchOptions): ReadonlySet<string> | undefined {\n\t\tconst paths: unknown = options?.paths\n\t\tif (paths === undefined) return undefined\n\t\tif (!arrayOf(isString)(paths)) {\n\t\t\tthrow new WorkspaceError('PATHS', 'Invalid search paths: expected an array of path strings', {\n\t\t\t\tpaths,\n\t\t\t})\n\t\t}\n\t\treturn new Set(paths)\n\t}\n}\n","import type { EmitterErrorHandler, EmitterHooks } from '@orkestrel/emitter'\nimport type {\n\tWorkspaceEventMap,\n\tWorkspaceInterface,\n\tWorkspaceManagerInterface,\n\tWorkspaceManagerOptions,\n\tWorkspaceOptions,\n\tWorkspaceStoreInterface,\n} from '../types.js'\nimport { isArray } from '@orkestrel/contract'\nimport { Workspace } from './Workspace.js'\n\n/**\n * Implements `WorkspaceManagerInterface` over an insertion-ordered id map and one active id\n * the instance owns, resolving `active` through that map on every read and holding no emitter.\n *\n * A supplied store adds lenient snapshot `open` and `save` operations. Event defaults flow into\n * workspaces created through the registry, while observability remains owned by each workspace.\n *\n * @example\n * ```ts\n * import { WorkspaceManager } from '@orkestrel/workspace'\n *\n * const manager = new WorkspaceManager()\n * const workspace = manager.add({ id: 'scratch' })\n * manager.active === workspace\n * ```\n */\nexport class WorkspaceManager implements WorkspaceManagerInterface {\n\treadonly #workspaces = new Map<string, WorkspaceInterface>()\n\t#active: string | undefined\n\treadonly #on: EmitterHooks<WorkspaceEventMap> | undefined\n\treadonly #error: EmitterErrorHandler | undefined\n\treadonly #store: WorkspaceStoreInterface | undefined\n\n\t/**\n\t * Creates a registry.\n\t *\n\t * @param options - Default event hooks and optional snapshot store\n\t */\n\tconstructor(options?: WorkspaceManagerOptions) {\n\t\tthis.#on = options?.on\n\t\tthis.#error = options?.error\n\t\tthis.#store = options?.store\n\t}\n\n\tget count(): number {\n\t\treturn this.#workspaces.size\n\t}\n\n\tget active(): WorkspaceInterface | undefined {\n\t\treturn this.#active === undefined ? undefined : this.#workspaces.get(this.#active)\n\t}\n\n\tworkspace(id: string): WorkspaceInterface | undefined {\n\t\treturn this.#workspaces.get(id)\n\t}\n\n\tworkspaces(): readonly WorkspaceInterface[] {\n\t\treturn [...this.#workspaces.values()]\n\t}\n\n\tadd(options?: WorkspaceOptions): WorkspaceInterface {\n\t\tconst on = options?.on ?? this.#on\n\t\tconst error = options?.error ?? this.#error\n\t\tconst workspace = new Workspace({\n\t\t\t...(options?.id === undefined ? {} : { id: options.id }),\n\t\t\t...(on === undefined ? {} : { on }),\n\t\t\t...(error === undefined ? {} : { error }),\n\t\t\t...(options?.seed === undefined ? {} : { seed: options.seed }),\n\t\t})\n\t\tthis.#workspaces.set(workspace.id, workspace)\n\t\tif (this.#active === undefined) this.#active = workspace.id\n\t\treturn workspace\n\t}\n\n\tswitch(id: string): WorkspaceInterface | undefined {\n\t\tconst workspace = this.#workspaces.get(id)\n\t\tif (workspace === undefined) return undefined\n\t\tthis.#active = id\n\t\treturn workspace\n\t}\n\n\tasync open(id: string): Promise<WorkspaceInterface | undefined> {\n\t\tconst existing = this.#workspaces.get(id)\n\t\tif (existing !== undefined) {\n\t\t\tthis.#active = id\n\t\t\treturn existing\n\t\t}\n\t\tif (this.#store === undefined) return undefined\n\t\tconst snapshot = await this.#store.get(id)\n\t\tif (snapshot === undefined) return undefined\n\t\tconst workspace = this.add({ id, seed: snapshot.files })\n\t\tthis.#active = workspace.id\n\t\treturn workspace\n\t}\n\n\tasync save(id: string): Promise<boolean> {\n\t\tconst workspace = this.#workspaces.get(id)\n\t\tif (this.#store === undefined || workspace === undefined) return false\n\t\tawait this.#store.set(workspace.snapshot())\n\t\treturn true\n\t}\n\n\tremove(id: string): boolean\n\tremove(ids: readonly string[]): boolean\n\tremove(ids: string | readonly string[]): boolean {\n\t\tif (isArray(ids)) {\n\t\t\treturn Iterator.from(ids).reduce((removed, id) => this.#drop(id) && removed, true)\n\t\t}\n\t\treturn this.#drop(ids)\n\t}\n\n\tclear(): void {\n\t\tfor (const workspace of this.#workspaces.values()) workspace.destroy()\n\t\tthis.#workspaces.clear()\n\t\tthis.#active = undefined\n\t}\n\n\t#drop(id: string): boolean {\n\t\tconst workspace = this.#workspaces.get(id)\n\t\tif (workspace === undefined) return false\n\t\tthis.#workspaces.delete(id)\n\t\tworkspace.destroy()\n\t\tif (this.#active === id) this.#active = undefined\n\t\treturn true\n\t}\n}\n","import type {\n\tWorkspaceSnapshot,\n\tWorkspaceSnapshotRow,\n\tWorkspaceStoreInterface,\n} from '../../types.js'\nimport type { TableInterface } from '@orkestrel/database'\nimport { isWorkspaceSnapshot } from '../../validators.js'\n\n/**\n * Persists workspace snapshots in a database table.\n *\n * Snapshots occupy one opaque column and are narrowed when read back from the storage boundary.\n *\n * @example\n * ```ts\n * import { rawShape, stringShape } from '@orkestrel/contract'\n * import { createDatabase, createMemoryDriver } from '@orkestrel/database'\n * import { DatabaseWorkspaceStore } from '@orkestrel/workspace'\n *\n * const database = createDatabase({\n * \tdriver: createMemoryDriver(),\n * \ttables: { workspaces: { id: stringShape(), snapshot: rawShape({}) } },\n * })\n * const store = new DatabaseWorkspaceStore(database.table('workspaces'))\n * ```\n */\nexport class DatabaseWorkspaceStore implements WorkspaceStoreInterface {\n\treadonly #table: TableInterface<WorkspaceSnapshotRow>\n\n\t/**\n\t * Wraps a workspace snapshot table.\n\t *\n\t * @param table - The table keyed by workspace identifier\n\t */\n\tconstructor(table: TableInterface<WorkspaceSnapshotRow>) {\n\t\tthis.#table = table\n\t}\n\n\tasync get(id: string): Promise<WorkspaceSnapshot | undefined> {\n\t\tconst row = await this.#table.get(id)\n\t\tif (row === undefined) return undefined\n\t\treturn isWorkspaceSnapshot(row.snapshot) ? row.snapshot : undefined\n\t}\n\n\tasync set(snapshot: WorkspaceSnapshot): Promise<void> {\n\t\tawait this.#table.set({ id: snapshot.id, snapshot })\n\t}\n\n\tasync delete(id: string): Promise<void> {\n\t\tawait this.#table.remove(id)\n\t}\n}\n","import type { WorkspaceSnapshot, WorkspaceStoreInterface } from '../../types.js'\n\n/**\n * Holds workspace snapshots in the current process.\n *\n * @example\n * ```ts\n * import { MemoryWorkspaceStore } from '@orkestrel/workspace'\n *\n * const store = new MemoryWorkspaceStore()\n * ```\n */\nexport class MemoryWorkspaceStore implements WorkspaceStoreInterface {\n\treadonly #snapshots = new Map<string, WorkspaceSnapshot>()\n\n\tget(id: string): Promise<WorkspaceSnapshot | undefined> {\n\t\treturn Promise.resolve(this.#snapshots.get(id))\n\t}\n\n\tset(snapshot: WorkspaceSnapshot): Promise<void> {\n\t\tthis.#snapshots.set(snapshot.id, snapshot)\n\t\treturn Promise.resolve()\n\t}\n\n\tdelete(id: string): Promise<void> {\n\t\tthis.#snapshots.delete(id)\n\t\treturn Promise.resolve()\n\t}\n}\n","import type {\n\tBinaryContent,\n\tBinaryMIME,\n\tFileInput,\n\tFileInterface,\n\tTextContent,\n\tWorkspaceInterface,\n\tWorkspaceManagerInterface,\n\tWorkspaceManagerOptions,\n\tWorkspaceOptions,\n\tWorkspaceSnapshotRow,\n\tWorkspaceStoreInterface,\n} from './types.js'\nimport type { DriverInterface, TableInterface } from '@orkestrel/database'\nimport { rawShape, stringShape } from '@orkestrel/contract'\nimport { createDatabase, createMemoryDriver } from '@orkestrel/database'\nimport { computeSize, countLines } from './helpers.js'\nimport { Workspace } from './workspaces/Workspace.js'\nimport { WorkspaceManager } from './workspaces/WorkspaceManager.js'\nimport { DatabaseWorkspaceStore } from './workspaces/stores/DatabaseWorkspaceStore.js'\nimport { MemoryWorkspaceStore } from './workspaces/stores/MemoryWorkspaceStore.js'\n\n/**\n * Creates an immutable file with derived size and line counts.\n *\n * @param input - The file path, content, and optional state\n * @returns A frozen file record\n *\n * @example Files and content\n * ```ts\n * import {\n * \tcomputeSize,\n * \tcountLines,\n * \tcreateBinaryContent,\n * \tcreateFile,\n * \tcreateTextContent,\n * \tinferLanguage,\n * \tisBinary,\n * \tisTextContent,\n * } from '@orkestrel/workspace'\n *\n * const note = createFile({\n * \tpath: 'notes.md',\n * \tcontent: createTextContent('# Title\\nBody', inferLanguage('notes.md')), // 'markdown'\n * })\n *\n * note.size // 12 — UTF-8 bytes, through computeSize\n * note.lines // 2 — through countLines\n * note.state // 'created'\n * isTextContent(note.content) // true\n *\n * const icon = createFile({ path: 'icon.png', content: createBinaryContent('AAAA', 'image/png') })\n * isBinary(icon.content) // true\n * icon.size // 3 — decoded base64 bytes, through computeDecodedSize\n * ```\n */\nexport function createFile(input: FileInput): FileInterface {\n\treturn Object.freeze({\n\t\tpath: input.path,\n\t\tcontent: input.content,\n\t\tstate: input.state ?? 'created',\n\t\tsize: computeSize(input.content),\n\t\tlines: countLines(input.content),\n\t})\n}\n\n/**\n * Creates the text arm of {@link FileContent}, returned as {@link TextContent} rather than as\n * the whole union.\n *\n * @param text - The text body\n * @param language - The language tag\n * @returns Text file content\n *\n * @example\n * ```ts\n * import { createTextContent } from '@orkestrel/workspace'\n *\n * createTextContent('hello', 'text')\n * ```\n */\nexport function createTextContent(text: string, language: string): TextContent {\n\treturn { text, language }\n}\n\n/**\n * Creates the binary arm of {@link FileContent}, returned as {@link BinaryContent} rather than\n * as the whole union.\n *\n * @param base64 - The base64 payload\n * @param mime - The binary MIME\n * @returns Binary file content\n *\n * @example\n * ```ts\n * import { createBinaryContent } from '@orkestrel/workspace'\n *\n * createBinaryContent('AAAA', 'image/png')\n * ```\n */\nexport function createBinaryContent(base64: string, mime: BinaryMIME): BinaryContent {\n\treturn { base64, mime }\n}\n\n/**\n * Creates a workspace with the same identity, emitter, and seed options the constructor takes.\n *\n * @param options - Optional identity, emitter configuration, and initial files\n * @returns A working workspace\n *\n * @example\n * ```ts\n * import { createWorkspace } from '@orkestrel/workspace'\n *\n * const workspace = createWorkspace()\n * workspace.write('a.txt', 'hello')\n * ```\n */\nexport function createWorkspace(options?: WorkspaceOptions): WorkspaceInterface {\n\treturn new Workspace(options)\n}\n\n/**\n * Creates an in-memory workspace snapshot store.\n *\n * @returns A process-local workspace store\n *\n * @example\n * ```ts\n * import { createMemoryWorkspaceStore } from '@orkestrel/workspace'\n *\n * const store = createMemoryWorkspaceStore()\n * ```\n */\nexport function createMemoryWorkspaceStore(): WorkspaceStoreInterface {\n\treturn new MemoryWorkspaceStore()\n}\n\n/**\n * Creates a database-backed workspace snapshot store, over an in-memory driver when the caller\n * supplies none.\n *\n * @param driver - The database driver. Default: an in-memory driver.\n * @returns A workspace store backed by the supplied driver\n *\n * @example\n * ```ts\n * import { createDatabaseWorkspaceStore } from '@orkestrel/workspace'\n *\n * const store = createDatabaseWorkspaceStore()\n * ```\n */\nexport function createDatabaseWorkspaceStore(\n\tdriver: DriverInterface = createMemoryDriver(),\n): WorkspaceStoreInterface {\n\tconst columns = { id: stringShape(), snapshot: rawShape({}) }\n\tconst database = createDatabase({ driver, tables: { workspaces: columns } })\n\tconst table: TableInterface<WorkspaceSnapshotRow> = database.table('workspaces')\n\treturn new DatabaseWorkspaceStore(table)\n}\n\n/**\n * Creates an empty workspace registry.\n *\n * @param options - Default event hooks and optional durability\n * @returns A workspace manager\n *\n * @example\n * ```ts\n * import { createWorkspaceManager } from '@orkestrel/workspace'\n *\n * const manager = createWorkspaceManager()\n * manager.add()\n * ```\n */\nexport function createWorkspaceManager(\n\toptions?: WorkspaceManagerOptions,\n): WorkspaceManagerInterface {\n\treturn new WorkspaceManager(options)\n}\n"],"mappings":"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"}
|
|
@@ -464,12 +464,14 @@ export declare interface SearchMatch {
|
|
|
464
464
|
* If `regex` is `true`, the query is treated as regular-expression source; if `false`, it is
|
|
465
465
|
* escaped and matched literally. Default: `false`. If `sensitive` is `false`, matching ignores
|
|
466
466
|
* case; if `true`, it does not. Default: `true`. `limit` caps the search or replacement count.
|
|
467
|
-
* Default: unlimited.
|
|
467
|
+
* Default: unlimited. `paths` limits the scan to the listed paths; a file outside the list is
|
|
468
|
+
* skipped. Default: every file.
|
|
468
469
|
*/
|
|
469
470
|
export declare interface SearchOptions {
|
|
470
471
|
readonly regex?: boolean;
|
|
471
472
|
readonly sensitive?: boolean;
|
|
472
473
|
readonly limit?: number;
|
|
474
|
+
readonly paths?: readonly string[];
|
|
473
475
|
}
|
|
474
476
|
|
|
475
477
|
/**
|
|
@@ -579,7 +581,7 @@ export declare class WorkspaceError extends Error {
|
|
|
579
581
|
}
|
|
580
582
|
|
|
581
583
|
/** Names the machine-readable failure codes raised by the workspace edit surface. */
|
|
582
|
-
export declare type WorkspaceErrorCode = 'MISSING' | 'MODALITY' | 'PATTERN' | 'RANGE';
|
|
584
|
+
export declare type WorkspaceErrorCode = 'MISSING' | 'MODALITY' | 'PATHS' | 'PATTERN' | 'RANGE';
|
|
583
585
|
|
|
584
586
|
/** Names the events emitted after workspace mutations complete. */
|
|
585
587
|
export declare type WorkspaceEventMap = {
|
|
@@ -653,7 +655,8 @@ export declare interface WorkspaceInterface {
|
|
|
653
655
|
* @param query - The literal text, or regular-expression source under `regex`
|
|
654
656
|
* @param options - Optional matching controls
|
|
655
657
|
* @returns Each hit in insertion order across files, then line order within a file
|
|
656
|
-
* @throws Thrown when the pattern source will not compile (`PATTERN`)
|
|
658
|
+
* @throws Thrown when the pattern source will not compile (`PATTERN`), or when `paths` is not an
|
|
659
|
+
* array of strings (`PATHS`).
|
|
657
660
|
*/
|
|
658
661
|
search(query: string, options?: SearchOptions): readonly SearchMatch[];
|
|
659
662
|
/**
|
|
@@ -663,7 +666,8 @@ export declare interface WorkspaceInterface {
|
|
|
663
666
|
* @param replacement - The text each match becomes
|
|
664
667
|
* @param options - Optional matching controls
|
|
665
668
|
* @returns The occurrences replaced and the files changed
|
|
666
|
-
* @throws Thrown when the pattern source will not compile (`PATTERN`)
|
|
669
|
+
* @throws Thrown when the pattern source will not compile (`PATTERN`), or when `paths` is not an
|
|
670
|
+
* array of strings (`PATHS`).
|
|
667
671
|
*/
|
|
668
672
|
replace(query: string, replacement: string, options?: SearchOptions): ReplaceResult;
|
|
669
673
|
/**
|
package/dist/src/core/index.d.ts
CHANGED
|
@@ -464,12 +464,14 @@ export declare interface SearchMatch {
|
|
|
464
464
|
* If `regex` is `true`, the query is treated as regular-expression source; if `false`, it is
|
|
465
465
|
* escaped and matched literally. Default: `false`. If `sensitive` is `false`, matching ignores
|
|
466
466
|
* case; if `true`, it does not. Default: `true`. `limit` caps the search or replacement count.
|
|
467
|
-
* Default: unlimited.
|
|
467
|
+
* Default: unlimited. `paths` limits the scan to the listed paths; a file outside the list is
|
|
468
|
+
* skipped. Default: every file.
|
|
468
469
|
*/
|
|
469
470
|
export declare interface SearchOptions {
|
|
470
471
|
readonly regex?: boolean;
|
|
471
472
|
readonly sensitive?: boolean;
|
|
472
473
|
readonly limit?: number;
|
|
474
|
+
readonly paths?: readonly string[];
|
|
473
475
|
}
|
|
474
476
|
|
|
475
477
|
/**
|
|
@@ -579,7 +581,7 @@ export declare class WorkspaceError extends Error {
|
|
|
579
581
|
}
|
|
580
582
|
|
|
581
583
|
/** Names the machine-readable failure codes raised by the workspace edit surface. */
|
|
582
|
-
export declare type WorkspaceErrorCode = 'MISSING' | 'MODALITY' | 'PATTERN' | 'RANGE';
|
|
584
|
+
export declare type WorkspaceErrorCode = 'MISSING' | 'MODALITY' | 'PATHS' | 'PATTERN' | 'RANGE';
|
|
583
585
|
|
|
584
586
|
/** Names the events emitted after workspace mutations complete. */
|
|
585
587
|
export declare type WorkspaceEventMap = {
|
|
@@ -653,7 +655,8 @@ export declare interface WorkspaceInterface {
|
|
|
653
655
|
* @param query - The literal text, or regular-expression source under `regex`
|
|
654
656
|
* @param options - Optional matching controls
|
|
655
657
|
* @returns Each hit in insertion order across files, then line order within a file
|
|
656
|
-
* @throws Thrown when the pattern source will not compile (`PATTERN`)
|
|
658
|
+
* @throws Thrown when the pattern source will not compile (`PATTERN`), or when `paths` is not an
|
|
659
|
+
* array of strings (`PATHS`).
|
|
657
660
|
*/
|
|
658
661
|
search(query: string, options?: SearchOptions): readonly SearchMatch[];
|
|
659
662
|
/**
|
|
@@ -663,7 +666,8 @@ export declare interface WorkspaceInterface {
|
|
|
663
666
|
* @param replacement - The text each match becomes
|
|
664
667
|
* @param options - Optional matching controls
|
|
665
668
|
* @returns The occurrences replaced and the files changed
|
|
666
|
-
* @throws Thrown when the pattern source will not compile (`PATTERN`)
|
|
669
|
+
* @throws Thrown when the pattern source will not compile (`PATTERN`), or when `paths` is not an
|
|
670
|
+
* array of strings (`PATHS`).
|
|
667
671
|
*/
|
|
668
672
|
replace(query: string, replacement: string, options?: SearchOptions): ReplaceResult;
|
|
669
673
|
/**
|
package/dist/src/core/index.js
CHANGED
|
@@ -93,7 +93,7 @@ function isWorkspaceError(value) {
|
|
|
93
93
|
if (!(value instanceof Error) || INTRINSICS.prototype(value) === Error.prototype) return false;
|
|
94
94
|
if (INTRINSICS.describe(value, Symbol.for("@orkestrel/workspace.WorkspaceError"))?.value !== value) return false;
|
|
95
95
|
const code = INTRINSICS.reflect.read(value, "code");
|
|
96
|
-
if (code !== "MISSING" && code !== "MODALITY" && code !== "PATTERN" && code !== "RANGE") return false;
|
|
96
|
+
if (code !== "MISSING" && code !== "MODALITY" && code !== "PATHS" && code !== "PATTERN" && code !== "RANGE") return false;
|
|
97
97
|
const context = INTRINSICS.reflect.read(value, "context");
|
|
98
98
|
return context === void 0 || isObject(context) || isFunction(context);
|
|
99
99
|
});
|
|
@@ -434,10 +434,12 @@ var Workspace = class {
|
|
|
434
434
|
}
|
|
435
435
|
search(query, options) {
|
|
436
436
|
const pattern = this.#pattern(query, options);
|
|
437
|
+
const paths = this.#paths(options);
|
|
437
438
|
const limit = options?.limit;
|
|
438
439
|
const matches = [];
|
|
439
440
|
for (const file of this.#files.values()) {
|
|
440
441
|
if (limit !== void 0 && matches.length >= limit) break;
|
|
442
|
+
if (paths !== void 0 && !paths.has(file.path)) continue;
|
|
441
443
|
if (!isTextContent(file.content)) continue;
|
|
442
444
|
const lines = file.content.text.split(/\r\n|\n/);
|
|
443
445
|
for (const [index, lineText] of lines.entries()) {
|
|
@@ -459,11 +461,13 @@ var Workspace = class {
|
|
|
459
461
|
}
|
|
460
462
|
replace(query, replacement, options) {
|
|
461
463
|
const pattern = this.#pattern(query, options);
|
|
464
|
+
const paths = this.#paths(options);
|
|
462
465
|
const limit = options?.limit;
|
|
463
466
|
const changes = [];
|
|
464
467
|
for (const [path, file] of this.#files) {
|
|
465
468
|
const occurrences = changes.reduce((total, count) => total + count, 0);
|
|
466
469
|
if (limit !== void 0 && occurrences >= limit) break;
|
|
470
|
+
if (paths !== void 0 && !paths.has(path)) continue;
|
|
467
471
|
if (!isTextContent(file.content)) continue;
|
|
468
472
|
const remaining = limit === void 0 ? void 0 : limit - occurrences;
|
|
469
473
|
pattern.lastIndex = 0;
|
|
@@ -612,6 +616,12 @@ var Workspace = class {
|
|
|
612
616
|
throw new WorkspaceError("PATTERN", `Invalid search pattern: ${query}`, { query });
|
|
613
617
|
}
|
|
614
618
|
}
|
|
619
|
+
#paths(options) {
|
|
620
|
+
const paths = options?.paths;
|
|
621
|
+
if (paths === void 0) return void 0;
|
|
622
|
+
if (!arrayOf(isString)(paths)) throw new WorkspaceError("PATHS", "Invalid search paths: expected an array of path strings", { paths });
|
|
623
|
+
return new Set(paths);
|
|
624
|
+
}
|
|
615
625
|
};
|
|
616
626
|
// src/core/workspaces/WorkspaceManager.ts
|
|
617
627
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/core/constants.ts","../../../src/core/errors.ts","../../../src/core/helpers.ts","../../../src/core/validators.ts","../../../src/core/workspaces/Workspace.ts","../../../src/core/workspaces/WorkspaceManager.ts","../../../src/core/workspaces/stores/DatabaseWorkspaceStore.ts","../../../src/core/workspaces/stores/MemoryWorkspaceStore.ts","../../../src/core/factories.ts"],"sourcesContent":["/**\n * Maps file extensions to language tags for text content.\n *\n * The table is frozen, and an extension it does not list falls back to `text` in\n * {@link import('./helpers.js').inferLanguage}.\n */\nexport const EXTENSION_LANGUAGES: Readonly<Record<string, string>> = Object.freeze({\n\tts: 'typescript',\n\ttsx: 'typescript',\n\tjs: 'javascript',\n\tjsx: 'javascript',\n\tmjs: 'javascript',\n\tcjs: 'javascript',\n\tjson: 'json',\n\tmd: 'markdown',\n\thtml: 'html',\n\thtm: 'html',\n\tcss: 'css',\n\tscss: 'scss',\n\tsass: 'sass',\n\tless: 'less',\n\tvue: 'vue',\n\tsvelte: 'svelte',\n\tpy: 'python',\n\trb: 'ruby',\n\trs: 'rust',\n\tgo: 'go',\n\tjava: 'java',\n\tkt: 'kotlin',\n\tswift: 'swift',\n\tc: 'c',\n\tcpp: 'cpp',\n\th: 'c',\n\thpp: 'cpp',\n\tcs: 'csharp',\n\tphp: 'php',\n\tsql: 'sql',\n\tsh: 'bash',\n\tbash: 'bash',\n\tzsh: 'bash',\n\tps1: 'powershell',\n\tyaml: 'yaml',\n\tyml: 'yaml',\n\ttoml: 'toml',\n\txml: 'xml',\n\tsvg: 'xml',\n\ttxt: 'text',\n})\n","import type { WorkspaceErrorCode } from './types.js'\nimport { holds, INTRINSICS, isFunction, isObject } from '@orkestrel/contract'\n\n/**\n * Reports an invalid workspace edit or search operation, carrying a {@link WorkspaceErrorCode}\n * and, when the operation had one, the context it ran under.\n */\nexport class WorkspaceError extends Error {\n\treadonly code: WorkspaceErrorCode\n\treadonly context?: Readonly<Record<string, unknown>>\n\n\t/**\n\t * Creates a workspace error.\n\t *\n\t * @param code - The machine-readable failure code\n\t * @param message - The human-readable failure message\n\t * @param context - Optional values associated with the failed operation\n\t */\n\tconstructor(\n\t\tcode: WorkspaceErrorCode,\n\t\tmessage: string,\n\t\tcontext?: Readonly<Record<string, unknown>>,\n\t) {\n\t\tsuper(message)\n\t\tINTRINSICS.define(this, Symbol.for('@orkestrel/workspace.WorkspaceError'), { value: this })\n\t\tthis.name = 'WorkspaceError'\n\t\tthis.code = code\n\t\tif (context !== undefined) this.context = context\n\t}\n}\n\n/**\n * Narrows a caught value to a {@link WorkspaceError}.\n *\n * @remarks\n * Checks the identity brand and declared members across package copies, accepting subclasses\n * and refusing transparent proxies. Inspection failures return false.\n *\n * @param value - The caught value\n * @returns True if the value is a workspace error; false otherwise\n *\n * @example\n * ```ts\n * if (isWorkspaceError(error)) error.code\n * ```\n */\nexport function isWorkspaceError(value: unknown): value is WorkspaceError {\n\treturn holds(() => {\n\t\tif (!(value instanceof Error) || INTRINSICS.prototype(value) === Error.prototype) return false\n\t\tconst brand = INTRINSICS.describe(value, Symbol.for('@orkestrel/workspace.WorkspaceError'))\n\t\tif (brand?.value !== value) return false\n\t\tconst code: unknown = INTRINSICS.reflect.read(value, 'code')\n\t\tif (code !== 'MISSING' && code !== 'MODALITY' && code !== 'PATTERN' && code !== 'RANGE')\n\t\t\treturn false\n\t\tconst context: unknown = INTRINSICS.reflect.read(value, 'context')\n\t\treturn context === undefined || isObject(context) || isFunction(context)\n\t})\n}\n","import type { BinaryContent, Caret, FileContent, Range, TextContent } from './types.js'\nimport { EXTENSION_LANGUAGES } from './constants.js'\n\n/**\n * Infers a language tag from the final file extension.\n *\n * @param path - The file path\n * @returns The mapped language, or `text` when the extension is absent or unknown\n *\n * @example\n * ```ts\n * inferLanguage('src/main.ts') // 'typescript'\n * ```\n */\nexport function inferLanguage(path: string): string {\n\tconst dot = path.lastIndexOf('.')\n\tif (dot === -1) return 'text'\n\tconst extension = path.slice(dot + 1).toLowerCase()\n\treturn EXTENSION_LANGUAGES[extension] ?? 'text'\n}\n\n/**\n * Determines whether content is the text arm.\n *\n * @param content - The file content\n * @returns True if the content carries text and a language; false otherwise\n *\n * @example\n * ```ts\n * isTextContent({ text: 'hello', language: 'text' }) // true\n * ```\n */\nexport function isTextContent(content: FileContent): content is TextContent {\n\treturn 'text' in content\n}\n\n/**\n * Determines whether content is the binary arm.\n *\n * @param content - The file content\n * @returns True if the content carries a base64 string and a MIME; false otherwise\n *\n * @example\n * ```ts\n * isBinary({ base64: 'AAAA', mime: 'image/png' }) // true\n * ```\n */\nexport function isBinary(content: FileContent): content is BinaryContent {\n\treturn 'base64' in content\n}\n\n/**\n * Computes the byte size of file content.\n *\n * @param content - The content to measure\n * @returns UTF-8 bytes for text or decoded bytes for binary content\n *\n * @example\n * ```ts\n * computeSize({ text: 'café', language: 'text' }) // 5\n * ```\n */\nexport function computeSize(content: FileContent): number {\n\tif (isTextContent(content)) return new TextEncoder().encode(content.text).length\n\treturn computeDecodedSize(content.base64)\n}\n\n/**\n * Counts the lines in file content.\n *\n * @param content - The content to inspect\n * @returns The text line count, or zero for empty text and binary content\n *\n * @example\n * ```ts\n * countLines({ text: 'a\\nb', language: 'text' }) // 2\n * ```\n */\nexport function countLines(content: FileContent): number {\n\tif (!isTextContent(content)) return 0\n\tif (content.text.length === 0) return 0\n\treturn content.text.split(/\\r\\n|\\n/).length\n}\n\n/**\n * Computes the decoded byte length of a base64 string, arithmetically rather than by decoding it.\n *\n * @param base64 - The base64 string\n * @returns The decoded byte count\n *\n * @example\n * ```ts\n * computeDecodedSize('AAAA') // 3\n * ```\n */\nexport function computeDecodedSize(base64: string): number {\n\tconst padding = base64.endsWith('==') ? 2 : base64.endsWith('=') ? 1 : 0\n\treturn Math.floor((base64.length * 3) / 4) - padding\n}\n\n/**\n * Determines whether a 1-based range is structurally valid.\n *\n * @param range - The range to inspect\n * @returns True if both carets are positive and ordered; false otherwise\n *\n * @example\n * ```ts\n * isValidRange({ start: { line: 1, column: 1 }, end: { line: 1, column: 2 } }) // true\n * ```\n */\nexport function isValidRange(range: Range): boolean {\n\tif (range.start.line < 1 || range.start.column < 1) return false\n\tif (range.end.line < 1 || range.end.column < 1) return false\n\tif (range.start.line > range.end.line) return false\n\treturn !(range.start.line === range.end.line && range.start.column > range.end.column)\n}\n\n/**\n * Clamps a caret to text bounds.\n *\n * @param text - The addressed text\n * @param caret - The requested caret\n * @returns The clamped caret\n *\n * @example\n * ```ts\n * clampCaret('ab', { line: 9, column: 9 }) // { line: 1, column: 3 }\n * ```\n */\nexport function clampCaret(text: string, caret: Caret): Caret {\n\tconst lines = text.split('\\n')\n\tconst line = Math.max(1, Math.min(caret.line, lines.length))\n\tconst lineText = lines[line - 1] ?? ''\n\tconst column = Math.max(1, Math.min(caret.column, lineText.length + 1))\n\treturn { line, column }\n}\n\n/**\n * Clamps both carets in a range to text bounds.\n *\n * @param text - The addressed text\n * @param range - The requested range\n * @returns The clamped range\n *\n * @example\n * ```ts\n * clampRange('ab', { start: { line: 1, column: 1 }, end: { line: 9, column: 9 } })\n * ```\n */\nexport function clampRange(text: string, range: Range): Range {\n\treturn { start: clampCaret(text, range.start), end: clampCaret(text, range.end) }\n}\n\n/**\n * Converts a 1-based caret to a zero-based string offset.\n *\n * @param text - The addressed text\n * @param caret - The requested caret\n * @returns The bounded string offset\n *\n * @example\n * ```ts\n * offsetAt('ab\\ncd', { line: 2, column: 1 }) // 3\n * ```\n */\nexport function offsetAt(text: string, caret: Caret): number {\n\tconst lines = text.split('\\n')\n\tconst offset = lines\n\t\t.filter((_, index) => index < caret.line - 1)\n\t\t.reduce((total, line) => total + line.length + 1, 0)\n\treturn Math.min(offset + (caret.column - 1), text.length)\n}\n\n/**\n * Slices a clamped half-open text range.\n *\n * @param text - The source text\n * @param range - The requested range\n * @returns The ranged substring\n *\n * @example\n * ```ts\n * sliceRange('hello', { start: { line: 1, column: 1 }, end: { line: 1, column: 6 } }) // 'hello'\n * ```\n */\nexport function sliceRange(text: string, range: Range): string {\n\tconst clamped = clampRange(text, range)\n\treturn text.slice(offsetAt(text, clamped.start), offsetAt(text, clamped.end))\n}\n\n/**\n * Replaces a clamped half-open text range.\n *\n * @param text - The source text\n * @param range - The requested range\n * @param replacement - The replacement text\n * @returns The spliced text\n *\n * @example\n * ```ts\n * spliceRange('hello', { start: { line: 1, column: 1 }, end: { line: 1, column: 6 } }, 'bye')\n * ```\n */\nexport function spliceRange(text: string, range: Range, replacement: string): string {\n\tconst clamped = clampRange(text, range)\n\tconst start = offsetAt(text, clamped.start)\n\tconst end = offsetAt(text, clamped.end)\n\treturn text.slice(0, start) + replacement + text.slice(end)\n}\n\n/**\n * Assembles a nested range from four 1-based coordinates.\n *\n * @param fromLine - The start line\n * @param fromColumn - The start column\n * @param toLine - The end line\n * @param toColumn - The end column\n * @returns The assembled range without validation\n *\n * @example\n * ```ts\n * rangeOf(1, 1, 1, 2)\n * ```\n */\nexport function rangeOf(\n\tfromLine: number,\n\tfromColumn: number,\n\ttoLine: number,\n\ttoColumn: number,\n): Range {\n\treturn { start: { line: fromLine, column: fromColumn }, end: { line: toLine, column: toColumn } }\n}\n","import type { FileInterface, WorkspaceSnapshot } from './types.js'\nimport { arrayOf, holds, isNumber, isRecord, isString, literalOf } from '@orkestrel/contract'\n\n/**\n * Narrows an unknown value to an immutable file record.\n *\n * @param value - The value to inspect\n * @returns True if the value has the file shape; false otherwise\n *\n * @example\n * ```ts\n * isFile({ path: 'a.txt', content: { text: 'a', language: 'text' }, state: 'created', size: 1, lines: 1 })\n * ```\n */\nexport function isFile(value: unknown): value is FileInterface {\n\treturn holds(() => {\n\t\tif (!isRecord(value)) return false\n\t\tif (!isString(value.path) || !literalOf('created', 'modified')(value.state)) return false\n\t\tif (!isNumber(value.size) || !isNumber(value.lines)) return false\n\t\tif (!isRecord(value.content)) return false\n\t\tconst text = isString(value.content.text) && isString(value.content.language)\n\t\tconst binary =\n\t\t\tisString(value.content.base64) &&\n\t\t\tliteralOf('image/png', 'image/jpeg', 'image/gif', 'image/webp')(value.content.mime)\n\t\treturn text || binary\n\t})\n}\n\n/**\n * Narrows an unknown value to a workspace snapshot.\n *\n * @param value - The value read from a persistence boundary\n * @returns True if the value has the workspace snapshot shape; false otherwise\n *\n * @example\n * ```ts\n * isWorkspaceSnapshot({ id: 'work', files: [] }) // true\n * ```\n */\nexport function isWorkspaceSnapshot(value: unknown): value is WorkspaceSnapshot {\n\treturn holds(() => isRecord(value) && isString(value.id) && arrayOf(isFile)(value.files))\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tFileInterface,\n\tRange,\n\tReadResult,\n\tReplaceResult,\n\tSearchMatch,\n\tSearchOptions,\n\tWorkspaceEventMap,\n\tWorkspaceInterface,\n\tWorkspaceOptions,\n\tWorkspaceSnapshot,\n} from '../types.js'\nimport { escapeRegExp, isArray, isRecord } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { WorkspaceError } from '../errors.js'\nimport { createFile } from '../factories.js'\nimport {\n\tclampRange,\n\tinferLanguage,\n\tisTextContent,\n\tisValidRange,\n\tsliceRange,\n\tspliceRange,\n} from '../helpers.js'\n\n/**\n * Implements `WorkspaceInterface` over one insertion-ordered path map the instance owns,\n * projecting fresh arrays on every read.\n *\n * Whole-file edits create text files, ranged edits operate only on existing text files, and\n * binary files remain available through construction-time hydration. Mutations emit after the\n * file map has changed.\n *\n * @example\n * ```ts\n * import { Workspace } from '@orkestrel/workspace'\n *\n * const workspace = new Workspace()\n * workspace.write('notes.txt', 'hello')\n * workspace.append('notes.txt', ' world')\n * workspace.read('notes.txt') // 'hello world'\n * ```\n */\nexport class Workspace implements WorkspaceInterface {\n\treadonly #id: string\n\treadonly #files = new Map<string, FileInterface>()\n\treadonly #emitter: Emitter<WorkspaceEventMap>\n\n\t/**\n\t * Creates a workspace.\n\t *\n\t * @param options - Optional identity, emitter configuration, and initial files\n\t */\n\tconstructor(options?: WorkspaceOptions) {\n\t\tthis.#id = options?.id ?? crypto.randomUUID()\n\t\tthis.#emitter = new Emitter<WorkspaceEventMap>({\n\t\t\t...(options?.on === undefined ? {} : { on: options.on }),\n\t\t\t...(options?.error === undefined ? {} : { error: options.error }),\n\t\t})\n\t\tif (options?.seed) for (const file of options.seed) this.#files.set(file.path, file)\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tget emitter(): EmitterInterface<WorkspaceEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget count(): number {\n\t\treturn this.#files.size\n\t}\n\n\tfile(path: string): FileInterface | undefined {\n\t\treturn this.#files.get(path)\n\t}\n\n\tfiles(): readonly FileInterface[] {\n\t\treturn [...this.#files.values()]\n\t}\n\n\tread(path: string): string | undefined\n\tread(path: string, range: Range): ReadResult | undefined\n\tread(paths: readonly string[]): Readonly<Record<string, string>>\n\tread(\n\t\tpath: string | readonly string[],\n\t\trange?: Range,\n\t): string | ReadResult | undefined | Readonly<Record<string, string>> {\n\t\tif (isArray(path)) {\n\t\t\tconst result: Record<string, string> = {}\n\t\t\tfor (const one of path) {\n\t\t\t\tconst file = this.#files.get(one)\n\t\t\t\tif (file && isTextContent(file.content)) result[one] = file.content.text\n\t\t\t}\n\t\t\treturn result\n\t\t}\n\t\tconst file = this.#files.get(path)\n\t\tif (!file) return undefined\n\t\tif (!range) return isTextContent(file.content) ? file.content.text : undefined\n\t\tif (!isTextContent(file.content)) {\n\t\t\tthrow new WorkspaceError('MODALITY', `Cannot read a range of a binary file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\treturn {\n\t\t\tcontent: sliceRange(file.content.text, range),\n\t\t\trange: clampRange(file.content.text, range),\n\t\t}\n\t}\n\n\thas(path: string): boolean\n\thas(paths: readonly string[]): boolean\n\thas(path: string | readonly string[]): boolean {\n\t\tif (isArray(path)) return path.every((one) => this.#files.has(one))\n\t\treturn this.#files.has(path)\n\t}\n\n\tsearch(query: string, options?: SearchOptions): readonly SearchMatch[] {\n\t\tconst pattern = this.#pattern(query, options)\n\t\tconst limit = options?.limit\n\t\tconst matches: SearchMatch[] = []\n\t\tfor (const file of this.#files.values()) {\n\t\t\tif (limit !== undefined && matches.length >= limit) break\n\t\t\tif (!isTextContent(file.content)) continue\n\t\t\tconst lines = file.content.text.split(/\\r\\n|\\n/)\n\t\t\tfor (const [index, lineText] of lines.entries()) {\n\t\t\t\tif (limit !== undefined && matches.length >= limit) break\n\t\t\t\tpattern.lastIndex = 0\n\t\t\t\tfor (const hit of lineText.matchAll(pattern)) {\n\t\t\t\t\tif (limit !== undefined && matches.length >= limit) break\n\t\t\t\t\tmatches.push({\n\t\t\t\t\t\tpath: file.path,\n\t\t\t\t\t\tline: index + 1,\n\t\t\t\t\t\tcolumn: hit.index + 1,\n\t\t\t\t\t\tlength: hit[0].length,\n\t\t\t\t\t\tcontent: lineText,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn matches\n\t}\n\n\treplace(query: string, replacement: string, options?: SearchOptions): ReplaceResult {\n\t\tconst pattern = this.#pattern(query, options)\n\t\tconst limit = options?.limit\n\t\tconst changes: number[] = []\n\t\tfor (const [path, file] of this.#files) {\n\t\t\tconst occurrences = changes.reduce((total, count) => total + count, 0)\n\t\t\tif (limit !== undefined && occurrences >= limit) break\n\t\t\tif (!isTextContent(file.content)) continue\n\t\t\tconst remaining = limit === undefined ? undefined : limit - occurrences\n\t\t\tpattern.lastIndex = 0\n\t\t\tconst text = file.content.text\n\t\t\tconst matches = Array.from(text.matchAll(pattern))\n\t\t\tconst count = matches.filter(\n\t\t\t\t(_, index) => remaining === undefined || !(index >= remaining),\n\t\t\t).length\n\t\t\tconst positions = matches.keys()\n\t\t\tconst next = text.replace(pattern, (match) =>\n\t\t\t\t(positions.next().value ?? Number.POSITIVE_INFINITY) < count ? replacement : match,\n\t\t\t)\n\t\t\tif (count > 0) {\n\t\t\t\tchanges.push(count)\n\t\t\t\tthis.write(path, next)\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\toccurrences: changes.reduce((total, count) => total + count, 0),\n\t\t\tfiles: changes.length,\n\t\t}\n\t}\n\n\twrite(path: string, content: string): void\n\twrite(path: string, content: string, range: Range): void\n\twrite(files: Readonly<Record<string, string>>): void\n\twrite(path: string | Readonly<Record<string, string>>, content?: string, range?: Range): void {\n\t\tif (isRecord(path)) {\n\t\t\tfor (const [one, text] of Object.entries(path)) this.#write(one, text)\n\t\t\treturn\n\t\t}\n\t\tif (content === undefined) return\n\t\tif (!range) {\n\t\t\tthis.#write(path, content)\n\t\t\treturn\n\t\t}\n\t\tthis.#splice(path, content, range)\n\t}\n\n\tprepend(path: string, content: string): void\n\tprepend(files: Readonly<Record<string, string>>): void\n\tprepend(path: string | Readonly<Record<string, string>>, content?: string): void {\n\t\tif (isRecord(path)) {\n\t\t\tfor (const [one, text] of Object.entries(path)) this.#prepend(one, text)\n\t\t\treturn\n\t\t}\n\t\tif (content === undefined) return\n\t\tthis.#prepend(path, content)\n\t}\n\n\tappend(path: string, content: string): void\n\tappend(files: Readonly<Record<string, string>>): void\n\tappend(path: string | Readonly<Record<string, string>>, content?: string): void {\n\t\tif (isRecord(path)) {\n\t\t\tfor (const [one, text] of Object.entries(path)) this.#append(one, text)\n\t\t\treturn\n\t\t}\n\t\tif (content === undefined) return\n\t\tthis.#append(path, content)\n\t}\n\n\tmove(from: string, to: string): boolean\n\tmove(mapping: Readonly<Record<string, string>>): boolean\n\tmove(from: string | Readonly<Record<string, string>>, to?: string): boolean {\n\t\tif (isRecord(from)) {\n\t\t\treturn Object.entries(from).reduce(\n\t\t\t\t(moved, [one, target]) => this.#move(one, target) && moved,\n\t\t\t\ttrue,\n\t\t\t)\n\t\t}\n\t\tif (to === undefined) return false\n\t\treturn this.#move(from, to)\n\t}\n\n\tremove(path: string): boolean\n\tremove(paths: readonly string[]): boolean\n\tremove(path: string | readonly string[]): boolean {\n\t\tif (isArray(path)) {\n\t\t\treturn Iterator.from(path).reduce((removed, one) => this.#remove(one) && removed, true)\n\t\t}\n\t\treturn this.#remove(path)\n\t}\n\n\tclear(): void {\n\t\tthis.#files.clear()\n\t\tthis.#emitter.emit('clear')\n\t}\n\n\tsnapshot(): WorkspaceSnapshot {\n\t\treturn { id: this.#id, files: this.files() }\n\t}\n\n\tdestroy(): void {\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#write(path: string, content: string): void {\n\t\tconst existing = this.#files.get(path)\n\t\tconst language =\n\t\t\texisting && isTextContent(existing.content) ? existing.content.language : inferLanguage(path)\n\t\tconst file = createFile({\n\t\t\tpath,\n\t\t\tcontent: { text: content, language },\n\t\t\tstate: existing ? 'modified' : 'created',\n\t\t})\n\t\tthis.#files.set(path, file)\n\t\tthis.#emitter.emit('write', file)\n\t}\n\n\t#splice(path: string, content: string, range: Range): void {\n\t\tconst existing = this.#files.get(path)\n\t\tif (!existing) {\n\t\t\tthrow new WorkspaceError('MISSING', `Cannot splice a range of a missing file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\tif (!isTextContent(existing.content)) {\n\t\t\tthrow new WorkspaceError('MODALITY', `Cannot splice a range of a binary file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\tif (!isValidRange(range)) {\n\t\t\tthrow new WorkspaceError('RANGE', `Invalid range for file: ${path}`, { path, range })\n\t\t}\n\t\tconst file = createFile({\n\t\t\tpath,\n\t\t\tcontent: {\n\t\t\t\ttext: spliceRange(existing.content.text, range, content),\n\t\t\t\tlanguage: existing.content.language,\n\t\t\t},\n\t\t\tstate: 'modified',\n\t\t})\n\t\tthis.#files.set(path, file)\n\t\tthis.#emitter.emit('write', file)\n\t}\n\n\t#prepend(path: string, content: string): void {\n\t\tconst existing = this.#files.get(path)\n\t\tif (existing === undefined) {\n\t\t\tthis.#write(path, content)\n\t\t\treturn\n\t\t}\n\t\tif (!isTextContent(existing.content)) {\n\t\t\tthrow new WorkspaceError('MODALITY', `Cannot prepend text to a binary file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\tthis.#write(path, content + existing.content.text)\n\t}\n\n\t#append(path: string, content: string): void {\n\t\tconst existing = this.#files.get(path)\n\t\tif (existing === undefined) {\n\t\t\tthis.#write(path, content)\n\t\t\treturn\n\t\t}\n\t\tif (!isTextContent(existing.content)) {\n\t\t\tthrow new WorkspaceError('MODALITY', `Cannot append text to a binary file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\tthis.#write(path, existing.content.text + content)\n\t}\n\n\t#move(from: string, to: string): boolean {\n\t\tif (from === to) return false\n\t\tconst file = this.#files.get(from)\n\t\tif (!file) return false\n\t\tconst moved = createFile({ path: to, content: file.content, state: 'modified' })\n\t\tconst entries = [...this.#files]\n\t\tthis.#files.clear()\n\t\tfor (const [path, current] of entries) {\n\t\t\tif (path === from) this.#files.set(to, moved)\n\t\t\telse if (path !== to) this.#files.set(path, current)\n\t\t}\n\t\tthis.#emitter.emit('move', from, to)\n\t\treturn true\n\t}\n\n\t#remove(path: string): boolean {\n\t\tconst removed = this.#files.delete(path)\n\t\tif (removed) this.#emitter.emit('remove', path)\n\t\treturn removed\n\t}\n\n\t#pattern(query: string, options?: SearchOptions): RegExp {\n\t\tconst source = options?.regex === true ? query : escapeRegExp(query)\n\t\tconst flags = options?.sensitive === false ? 'gi' : 'g'\n\t\ttry {\n\t\t\treturn new RegExp(source, flags)\n\t\t} catch {\n\t\t\tthrow new WorkspaceError('PATTERN', `Invalid search pattern: ${query}`, { query })\n\t\t}\n\t}\n}\n","import type { EmitterErrorHandler, EmitterHooks } from '@orkestrel/emitter'\nimport type {\n\tWorkspaceEventMap,\n\tWorkspaceInterface,\n\tWorkspaceManagerInterface,\n\tWorkspaceManagerOptions,\n\tWorkspaceOptions,\n\tWorkspaceStoreInterface,\n} from '../types.js'\nimport { isArray } from '@orkestrel/contract'\nimport { Workspace } from './Workspace.js'\n\n/**\n * Implements `WorkspaceManagerInterface` over an insertion-ordered id map and one active id\n * the instance owns, resolving `active` through that map on every read and holding no emitter.\n *\n * A supplied store adds lenient snapshot `open` and `save` operations. Event defaults flow into\n * workspaces created through the registry, while observability remains owned by each workspace.\n *\n * @example\n * ```ts\n * import { WorkspaceManager } from '@orkestrel/workspace'\n *\n * const manager = new WorkspaceManager()\n * const workspace = manager.add({ id: 'scratch' })\n * manager.active === workspace\n * ```\n */\nexport class WorkspaceManager implements WorkspaceManagerInterface {\n\treadonly #workspaces = new Map<string, WorkspaceInterface>()\n\t#active: string | undefined\n\treadonly #on: EmitterHooks<WorkspaceEventMap> | undefined\n\treadonly #error: EmitterErrorHandler | undefined\n\treadonly #store: WorkspaceStoreInterface | undefined\n\n\t/**\n\t * Creates a registry.\n\t *\n\t * @param options - Default event hooks and optional snapshot store\n\t */\n\tconstructor(options?: WorkspaceManagerOptions) {\n\t\tthis.#on = options?.on\n\t\tthis.#error = options?.error\n\t\tthis.#store = options?.store\n\t}\n\n\tget count(): number {\n\t\treturn this.#workspaces.size\n\t}\n\n\tget active(): WorkspaceInterface | undefined {\n\t\treturn this.#active === undefined ? undefined : this.#workspaces.get(this.#active)\n\t}\n\n\tworkspace(id: string): WorkspaceInterface | undefined {\n\t\treturn this.#workspaces.get(id)\n\t}\n\n\tworkspaces(): readonly WorkspaceInterface[] {\n\t\treturn [...this.#workspaces.values()]\n\t}\n\n\tadd(options?: WorkspaceOptions): WorkspaceInterface {\n\t\tconst on = options?.on ?? this.#on\n\t\tconst error = options?.error ?? this.#error\n\t\tconst workspace = new Workspace({\n\t\t\t...(options?.id === undefined ? {} : { id: options.id }),\n\t\t\t...(on === undefined ? {} : { on }),\n\t\t\t...(error === undefined ? {} : { error }),\n\t\t\t...(options?.seed === undefined ? {} : { seed: options.seed }),\n\t\t})\n\t\tthis.#workspaces.set(workspace.id, workspace)\n\t\tif (this.#active === undefined) this.#active = workspace.id\n\t\treturn workspace\n\t}\n\n\tswitch(id: string): WorkspaceInterface | undefined {\n\t\tconst workspace = this.#workspaces.get(id)\n\t\tif (workspace === undefined) return undefined\n\t\tthis.#active = id\n\t\treturn workspace\n\t}\n\n\tasync open(id: string): Promise<WorkspaceInterface | undefined> {\n\t\tconst existing = this.#workspaces.get(id)\n\t\tif (existing !== undefined) {\n\t\t\tthis.#active = id\n\t\t\treturn existing\n\t\t}\n\t\tif (this.#store === undefined) return undefined\n\t\tconst snapshot = await this.#store.get(id)\n\t\tif (snapshot === undefined) return undefined\n\t\tconst workspace = this.add({ id, seed: snapshot.files })\n\t\tthis.#active = workspace.id\n\t\treturn workspace\n\t}\n\n\tasync save(id: string): Promise<boolean> {\n\t\tconst workspace = this.#workspaces.get(id)\n\t\tif (this.#store === undefined || workspace === undefined) return false\n\t\tawait this.#store.set(workspace.snapshot())\n\t\treturn true\n\t}\n\n\tremove(id: string): boolean\n\tremove(ids: readonly string[]): boolean\n\tremove(ids: string | readonly string[]): boolean {\n\t\tif (isArray(ids)) {\n\t\t\treturn Iterator.from(ids).reduce((removed, id) => this.#drop(id) && removed, true)\n\t\t}\n\t\treturn this.#drop(ids)\n\t}\n\n\tclear(): void {\n\t\tfor (const workspace of this.#workspaces.values()) workspace.destroy()\n\t\tthis.#workspaces.clear()\n\t\tthis.#active = undefined\n\t}\n\n\t#drop(id: string): boolean {\n\t\tconst workspace = this.#workspaces.get(id)\n\t\tif (workspace === undefined) return false\n\t\tthis.#workspaces.delete(id)\n\t\tworkspace.destroy()\n\t\tif (this.#active === id) this.#active = undefined\n\t\treturn true\n\t}\n}\n","import type {\n\tWorkspaceSnapshot,\n\tWorkspaceSnapshotRow,\n\tWorkspaceStoreInterface,\n} from '../../types.js'\nimport type { TableInterface } from '@orkestrel/database'\nimport { isWorkspaceSnapshot } from '../../validators.js'\n\n/**\n * Persists workspace snapshots in a database table.\n *\n * Snapshots occupy one opaque column and are narrowed when read back from the storage boundary.\n *\n * @example\n * ```ts\n * import { rawShape, stringShape } from '@orkestrel/contract'\n * import { createDatabase, createMemoryDriver } from '@orkestrel/database'\n * import { DatabaseWorkspaceStore } from '@orkestrel/workspace'\n *\n * const database = createDatabase({\n * \tdriver: createMemoryDriver(),\n * \ttables: { workspaces: { id: stringShape(), snapshot: rawShape({}) } },\n * })\n * const store = new DatabaseWorkspaceStore(database.table('workspaces'))\n * ```\n */\nexport class DatabaseWorkspaceStore implements WorkspaceStoreInterface {\n\treadonly #table: TableInterface<WorkspaceSnapshotRow>\n\n\t/**\n\t * Wraps a workspace snapshot table.\n\t *\n\t * @param table - The table keyed by workspace identifier\n\t */\n\tconstructor(table: TableInterface<WorkspaceSnapshotRow>) {\n\t\tthis.#table = table\n\t}\n\n\tasync get(id: string): Promise<WorkspaceSnapshot | undefined> {\n\t\tconst row = await this.#table.get(id)\n\t\tif (row === undefined) return undefined\n\t\treturn isWorkspaceSnapshot(row.snapshot) ? row.snapshot : undefined\n\t}\n\n\tasync set(snapshot: WorkspaceSnapshot): Promise<void> {\n\t\tawait this.#table.set({ id: snapshot.id, snapshot })\n\t}\n\n\tasync delete(id: string): Promise<void> {\n\t\tawait this.#table.remove(id)\n\t}\n}\n","import type { WorkspaceSnapshot, WorkspaceStoreInterface } from '../../types.js'\n\n/**\n * Holds workspace snapshots in the current process.\n *\n * @example\n * ```ts\n * import { MemoryWorkspaceStore } from '@orkestrel/workspace'\n *\n * const store = new MemoryWorkspaceStore()\n * ```\n */\nexport class MemoryWorkspaceStore implements WorkspaceStoreInterface {\n\treadonly #snapshots = new Map<string, WorkspaceSnapshot>()\n\n\tget(id: string): Promise<WorkspaceSnapshot | undefined> {\n\t\treturn Promise.resolve(this.#snapshots.get(id))\n\t}\n\n\tset(snapshot: WorkspaceSnapshot): Promise<void> {\n\t\tthis.#snapshots.set(snapshot.id, snapshot)\n\t\treturn Promise.resolve()\n\t}\n\n\tdelete(id: string): Promise<void> {\n\t\tthis.#snapshots.delete(id)\n\t\treturn Promise.resolve()\n\t}\n}\n","import type {\n\tBinaryContent,\n\tBinaryMIME,\n\tFileInput,\n\tFileInterface,\n\tTextContent,\n\tWorkspaceInterface,\n\tWorkspaceManagerInterface,\n\tWorkspaceManagerOptions,\n\tWorkspaceOptions,\n\tWorkspaceSnapshotRow,\n\tWorkspaceStoreInterface,\n} from './types.js'\nimport type { DriverInterface, TableInterface } from '@orkestrel/database'\nimport { rawShape, stringShape } from '@orkestrel/contract'\nimport { createDatabase, createMemoryDriver } from '@orkestrel/database'\nimport { computeSize, countLines } from './helpers.js'\nimport { Workspace } from './workspaces/Workspace.js'\nimport { WorkspaceManager } from './workspaces/WorkspaceManager.js'\nimport { DatabaseWorkspaceStore } from './workspaces/stores/DatabaseWorkspaceStore.js'\nimport { MemoryWorkspaceStore } from './workspaces/stores/MemoryWorkspaceStore.js'\n\n/**\n * Creates an immutable file with derived size and line counts.\n *\n * @param input - The file path, content, and optional state\n * @returns A frozen file record\n *\n * @example Files and content\n * ```ts\n * import {\n * \tcomputeSize,\n * \tcountLines,\n * \tcreateBinaryContent,\n * \tcreateFile,\n * \tcreateTextContent,\n * \tinferLanguage,\n * \tisBinary,\n * \tisTextContent,\n * } from '@orkestrel/workspace'\n *\n * const note = createFile({\n * \tpath: 'notes.md',\n * \tcontent: createTextContent('# Title\\nBody', inferLanguage('notes.md')), // 'markdown'\n * })\n *\n * note.size // 12 — UTF-8 bytes, through computeSize\n * note.lines // 2 — through countLines\n * note.state // 'created'\n * isTextContent(note.content) // true\n *\n * const icon = createFile({ path: 'icon.png', content: createBinaryContent('AAAA', 'image/png') })\n * isBinary(icon.content) // true\n * icon.size // 3 — decoded base64 bytes, through computeDecodedSize\n * ```\n */\nexport function createFile(input: FileInput): FileInterface {\n\treturn Object.freeze({\n\t\tpath: input.path,\n\t\tcontent: input.content,\n\t\tstate: input.state ?? 'created',\n\t\tsize: computeSize(input.content),\n\t\tlines: countLines(input.content),\n\t})\n}\n\n/**\n * Creates the text arm of {@link FileContent}, returned as {@link TextContent} rather than as\n * the whole union.\n *\n * @param text - The text body\n * @param language - The language tag\n * @returns Text file content\n *\n * @example\n * ```ts\n * import { createTextContent } from '@orkestrel/workspace'\n *\n * createTextContent('hello', 'text')\n * ```\n */\nexport function createTextContent(text: string, language: string): TextContent {\n\treturn { text, language }\n}\n\n/**\n * Creates the binary arm of {@link FileContent}, returned as {@link BinaryContent} rather than\n * as the whole union.\n *\n * @param base64 - The base64 payload\n * @param mime - The binary MIME\n * @returns Binary file content\n *\n * @example\n * ```ts\n * import { createBinaryContent } from '@orkestrel/workspace'\n *\n * createBinaryContent('AAAA', 'image/png')\n * ```\n */\nexport function createBinaryContent(base64: string, mime: BinaryMIME): BinaryContent {\n\treturn { base64, mime }\n}\n\n/**\n * Creates a workspace with the same identity, emitter, and seed options the constructor takes.\n *\n * @param options - Optional identity, emitter configuration, and initial files\n * @returns A working workspace\n *\n * @example\n * ```ts\n * import { createWorkspace } from '@orkestrel/workspace'\n *\n * const workspace = createWorkspace()\n * workspace.write('a.txt', 'hello')\n * ```\n */\nexport function createWorkspace(options?: WorkspaceOptions): WorkspaceInterface {\n\treturn new Workspace(options)\n}\n\n/**\n * Creates an in-memory workspace snapshot store.\n *\n * @returns A process-local workspace store\n *\n * @example\n * ```ts\n * import { createMemoryWorkspaceStore } from '@orkestrel/workspace'\n *\n * const store = createMemoryWorkspaceStore()\n * ```\n */\nexport function createMemoryWorkspaceStore(): WorkspaceStoreInterface {\n\treturn new MemoryWorkspaceStore()\n}\n\n/**\n * Creates a database-backed workspace snapshot store, over an in-memory driver when the caller\n * supplies none.\n *\n * @param driver - The database driver. Default: an in-memory driver.\n * @returns A workspace store backed by the supplied driver\n *\n * @example\n * ```ts\n * import { createDatabaseWorkspaceStore } from '@orkestrel/workspace'\n *\n * const store = createDatabaseWorkspaceStore()\n * ```\n */\nexport function createDatabaseWorkspaceStore(\n\tdriver: DriverInterface = createMemoryDriver(),\n): WorkspaceStoreInterface {\n\tconst columns = { id: stringShape(), snapshot: rawShape({}) }\n\tconst database = createDatabase({ driver, tables: { workspaces: columns } })\n\tconst table: TableInterface<WorkspaceSnapshotRow> = database.table('workspaces')\n\treturn new DatabaseWorkspaceStore(table)\n}\n\n/**\n * Creates an empty workspace registry.\n *\n * @param options - Default event hooks and optional durability\n * @returns A workspace manager\n *\n * @example\n * ```ts\n * import { createWorkspaceManager } from '@orkestrel/workspace'\n *\n * const manager = createWorkspaceManager()\n * manager.add()\n * ```\n */\nexport function createWorkspaceManager(\n\toptions?: WorkspaceManagerOptions,\n): WorkspaceManagerInterface {\n\treturn new WorkspaceManager(options)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/core/constants.ts","../../../src/core/errors.ts","../../../src/core/helpers.ts","../../../src/core/validators.ts","../../../src/core/workspaces/Workspace.ts","../../../src/core/workspaces/WorkspaceManager.ts","../../../src/core/workspaces/stores/DatabaseWorkspaceStore.ts","../../../src/core/workspaces/stores/MemoryWorkspaceStore.ts","../../../src/core/factories.ts"],"sourcesContent":["/**\n * Maps file extensions to language tags for text content.\n *\n * The table is frozen, and an extension it does not list falls back to `text` in\n * {@link import('./helpers.js').inferLanguage}.\n */\nexport const EXTENSION_LANGUAGES: Readonly<Record<string, string>> = Object.freeze({\n\tts: 'typescript',\n\ttsx: 'typescript',\n\tjs: 'javascript',\n\tjsx: 'javascript',\n\tmjs: 'javascript',\n\tcjs: 'javascript',\n\tjson: 'json',\n\tmd: 'markdown',\n\thtml: 'html',\n\thtm: 'html',\n\tcss: 'css',\n\tscss: 'scss',\n\tsass: 'sass',\n\tless: 'less',\n\tvue: 'vue',\n\tsvelte: 'svelte',\n\tpy: 'python',\n\trb: 'ruby',\n\trs: 'rust',\n\tgo: 'go',\n\tjava: 'java',\n\tkt: 'kotlin',\n\tswift: 'swift',\n\tc: 'c',\n\tcpp: 'cpp',\n\th: 'c',\n\thpp: 'cpp',\n\tcs: 'csharp',\n\tphp: 'php',\n\tsql: 'sql',\n\tsh: 'bash',\n\tbash: 'bash',\n\tzsh: 'bash',\n\tps1: 'powershell',\n\tyaml: 'yaml',\n\tyml: 'yaml',\n\ttoml: 'toml',\n\txml: 'xml',\n\tsvg: 'xml',\n\ttxt: 'text',\n})\n","import type { WorkspaceErrorCode } from './types.js'\nimport { holds, INTRINSICS, isFunction, isObject } from '@orkestrel/contract'\n\n/**\n * Reports an invalid workspace edit or search operation, carrying a {@link WorkspaceErrorCode}\n * and, when the operation had one, the context it ran under.\n */\nexport class WorkspaceError extends Error {\n\treadonly code: WorkspaceErrorCode\n\treadonly context?: Readonly<Record<string, unknown>>\n\n\t/**\n\t * Creates a workspace error.\n\t *\n\t * @param code - The machine-readable failure code\n\t * @param message - The human-readable failure message\n\t * @param context - Optional values associated with the failed operation\n\t */\n\tconstructor(\n\t\tcode: WorkspaceErrorCode,\n\t\tmessage: string,\n\t\tcontext?: Readonly<Record<string, unknown>>,\n\t) {\n\t\tsuper(message)\n\t\tINTRINSICS.define(this, Symbol.for('@orkestrel/workspace.WorkspaceError'), { value: this })\n\t\tthis.name = 'WorkspaceError'\n\t\tthis.code = code\n\t\tif (context !== undefined) this.context = context\n\t}\n}\n\n/**\n * Narrows a caught value to a {@link WorkspaceError}.\n *\n * @remarks\n * Checks the identity brand and declared members across package copies, accepting subclasses\n * and refusing transparent proxies. Inspection failures return false.\n *\n * @param value - The caught value\n * @returns True if the value is a workspace error; false otherwise\n *\n * @example\n * ```ts\n * if (isWorkspaceError(error)) error.code\n * ```\n */\nexport function isWorkspaceError(value: unknown): value is WorkspaceError {\n\treturn holds(() => {\n\t\tif (!(value instanceof Error) || INTRINSICS.prototype(value) === Error.prototype) return false\n\t\tconst brand = INTRINSICS.describe(value, Symbol.for('@orkestrel/workspace.WorkspaceError'))\n\t\tif (brand?.value !== value) return false\n\t\tconst code: unknown = INTRINSICS.reflect.read(value, 'code')\n\t\tif (\n\t\t\tcode !== 'MISSING' &&\n\t\t\tcode !== 'MODALITY' &&\n\t\t\tcode !== 'PATHS' &&\n\t\t\tcode !== 'PATTERN' &&\n\t\t\tcode !== 'RANGE'\n\t\t)\n\t\t\treturn false\n\t\tconst context: unknown = INTRINSICS.reflect.read(value, 'context')\n\t\treturn context === undefined || isObject(context) || isFunction(context)\n\t})\n}\n","import type { BinaryContent, Caret, FileContent, Range, TextContent } from './types.js'\nimport { EXTENSION_LANGUAGES } from './constants.js'\n\n/**\n * Infers a language tag from the final file extension.\n *\n * @param path - The file path\n * @returns The mapped language, or `text` when the extension is absent or unknown\n *\n * @example\n * ```ts\n * inferLanguage('src/main.ts') // 'typescript'\n * ```\n */\nexport function inferLanguage(path: string): string {\n\tconst dot = path.lastIndexOf('.')\n\tif (dot === -1) return 'text'\n\tconst extension = path.slice(dot + 1).toLowerCase()\n\treturn EXTENSION_LANGUAGES[extension] ?? 'text'\n}\n\n/**\n * Determines whether content is the text arm.\n *\n * @param content - The file content\n * @returns True if the content carries text and a language; false otherwise\n *\n * @example\n * ```ts\n * isTextContent({ text: 'hello', language: 'text' }) // true\n * ```\n */\nexport function isTextContent(content: FileContent): content is TextContent {\n\treturn 'text' in content\n}\n\n/**\n * Determines whether content is the binary arm.\n *\n * @param content - The file content\n * @returns True if the content carries a base64 string and a MIME; false otherwise\n *\n * @example\n * ```ts\n * isBinary({ base64: 'AAAA', mime: 'image/png' }) // true\n * ```\n */\nexport function isBinary(content: FileContent): content is BinaryContent {\n\treturn 'base64' in content\n}\n\n/**\n * Computes the byte size of file content.\n *\n * @param content - The content to measure\n * @returns UTF-8 bytes for text or decoded bytes for binary content\n *\n * @example\n * ```ts\n * computeSize({ text: 'café', language: 'text' }) // 5\n * ```\n */\nexport function computeSize(content: FileContent): number {\n\tif (isTextContent(content)) return new TextEncoder().encode(content.text).length\n\treturn computeDecodedSize(content.base64)\n}\n\n/**\n * Counts the lines in file content.\n *\n * @param content - The content to inspect\n * @returns The text line count, or zero for empty text and binary content\n *\n * @example\n * ```ts\n * countLines({ text: 'a\\nb', language: 'text' }) // 2\n * ```\n */\nexport function countLines(content: FileContent): number {\n\tif (!isTextContent(content)) return 0\n\tif (content.text.length === 0) return 0\n\treturn content.text.split(/\\r\\n|\\n/).length\n}\n\n/**\n * Computes the decoded byte length of a base64 string, arithmetically rather than by decoding it.\n *\n * @param base64 - The base64 string\n * @returns The decoded byte count\n *\n * @example\n * ```ts\n * computeDecodedSize('AAAA') // 3\n * ```\n */\nexport function computeDecodedSize(base64: string): number {\n\tconst padding = base64.endsWith('==') ? 2 : base64.endsWith('=') ? 1 : 0\n\treturn Math.floor((base64.length * 3) / 4) - padding\n}\n\n/**\n * Determines whether a 1-based range is structurally valid.\n *\n * @param range - The range to inspect\n * @returns True if both carets are positive and ordered; false otherwise\n *\n * @example\n * ```ts\n * isValidRange({ start: { line: 1, column: 1 }, end: { line: 1, column: 2 } }) // true\n * ```\n */\nexport function isValidRange(range: Range): boolean {\n\tif (range.start.line < 1 || range.start.column < 1) return false\n\tif (range.end.line < 1 || range.end.column < 1) return false\n\tif (range.start.line > range.end.line) return false\n\treturn !(range.start.line === range.end.line && range.start.column > range.end.column)\n}\n\n/**\n * Clamps a caret to text bounds.\n *\n * @param text - The addressed text\n * @param caret - The requested caret\n * @returns The clamped caret\n *\n * @example\n * ```ts\n * clampCaret('ab', { line: 9, column: 9 }) // { line: 1, column: 3 }\n * ```\n */\nexport function clampCaret(text: string, caret: Caret): Caret {\n\tconst lines = text.split('\\n')\n\tconst line = Math.max(1, Math.min(caret.line, lines.length))\n\tconst lineText = lines[line - 1] ?? ''\n\tconst column = Math.max(1, Math.min(caret.column, lineText.length + 1))\n\treturn { line, column }\n}\n\n/**\n * Clamps both carets in a range to text bounds.\n *\n * @param text - The addressed text\n * @param range - The requested range\n * @returns The clamped range\n *\n * @example\n * ```ts\n * clampRange('ab', { start: { line: 1, column: 1 }, end: { line: 9, column: 9 } })\n * ```\n */\nexport function clampRange(text: string, range: Range): Range {\n\treturn { start: clampCaret(text, range.start), end: clampCaret(text, range.end) }\n}\n\n/**\n * Converts a 1-based caret to a zero-based string offset.\n *\n * @param text - The addressed text\n * @param caret - The requested caret\n * @returns The bounded string offset\n *\n * @example\n * ```ts\n * offsetAt('ab\\ncd', { line: 2, column: 1 }) // 3\n * ```\n */\nexport function offsetAt(text: string, caret: Caret): number {\n\tconst lines = text.split('\\n')\n\tconst offset = lines\n\t\t.filter((_, index) => index < caret.line - 1)\n\t\t.reduce((total, line) => total + line.length + 1, 0)\n\treturn Math.min(offset + (caret.column - 1), text.length)\n}\n\n/**\n * Slices a clamped half-open text range.\n *\n * @param text - The source text\n * @param range - The requested range\n * @returns The ranged substring\n *\n * @example\n * ```ts\n * sliceRange('hello', { start: { line: 1, column: 1 }, end: { line: 1, column: 6 } }) // 'hello'\n * ```\n */\nexport function sliceRange(text: string, range: Range): string {\n\tconst clamped = clampRange(text, range)\n\treturn text.slice(offsetAt(text, clamped.start), offsetAt(text, clamped.end))\n}\n\n/**\n * Replaces a clamped half-open text range.\n *\n * @param text - The source text\n * @param range - The requested range\n * @param replacement - The replacement text\n * @returns The spliced text\n *\n * @example\n * ```ts\n * spliceRange('hello', { start: { line: 1, column: 1 }, end: { line: 1, column: 6 } }, 'bye')\n * ```\n */\nexport function spliceRange(text: string, range: Range, replacement: string): string {\n\tconst clamped = clampRange(text, range)\n\tconst start = offsetAt(text, clamped.start)\n\tconst end = offsetAt(text, clamped.end)\n\treturn text.slice(0, start) + replacement + text.slice(end)\n}\n\n/**\n * Assembles a nested range from four 1-based coordinates.\n *\n * @param fromLine - The start line\n * @param fromColumn - The start column\n * @param toLine - The end line\n * @param toColumn - The end column\n * @returns The assembled range without validation\n *\n * @example\n * ```ts\n * rangeOf(1, 1, 1, 2)\n * ```\n */\nexport function rangeOf(\n\tfromLine: number,\n\tfromColumn: number,\n\ttoLine: number,\n\ttoColumn: number,\n): Range {\n\treturn { start: { line: fromLine, column: fromColumn }, end: { line: toLine, column: toColumn } }\n}\n","import type { FileInterface, WorkspaceSnapshot } from './types.js'\nimport { arrayOf, holds, isNumber, isRecord, isString, literalOf } from '@orkestrel/contract'\n\n/**\n * Narrows an unknown value to an immutable file record.\n *\n * @param value - The value to inspect\n * @returns True if the value has the file shape; false otherwise\n *\n * @example\n * ```ts\n * isFile({ path: 'a.txt', content: { text: 'a', language: 'text' }, state: 'created', size: 1, lines: 1 })\n * ```\n */\nexport function isFile(value: unknown): value is FileInterface {\n\treturn holds(() => {\n\t\tif (!isRecord(value)) return false\n\t\tif (!isString(value.path) || !literalOf('created', 'modified')(value.state)) return false\n\t\tif (!isNumber(value.size) || !isNumber(value.lines)) return false\n\t\tif (!isRecord(value.content)) return false\n\t\tconst text = isString(value.content.text) && isString(value.content.language)\n\t\tconst binary =\n\t\t\tisString(value.content.base64) &&\n\t\t\tliteralOf('image/png', 'image/jpeg', 'image/gif', 'image/webp')(value.content.mime)\n\t\treturn text || binary\n\t})\n}\n\n/**\n * Narrows an unknown value to a workspace snapshot.\n *\n * @param value - The value read from a persistence boundary\n * @returns True if the value has the workspace snapshot shape; false otherwise\n *\n * @example\n * ```ts\n * isWorkspaceSnapshot({ id: 'work', files: [] }) // true\n * ```\n */\nexport function isWorkspaceSnapshot(value: unknown): value is WorkspaceSnapshot {\n\treturn holds(() => isRecord(value) && isString(value.id) && arrayOf(isFile)(value.files))\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tFileInterface,\n\tRange,\n\tReadResult,\n\tReplaceResult,\n\tSearchMatch,\n\tSearchOptions,\n\tWorkspaceEventMap,\n\tWorkspaceInterface,\n\tWorkspaceOptions,\n\tWorkspaceSnapshot,\n} from '../types.js'\nimport { arrayOf, escapeRegExp, isArray, isRecord, isString } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { WorkspaceError } from '../errors.js'\nimport { createFile } from '../factories.js'\nimport {\n\tclampRange,\n\tinferLanguage,\n\tisTextContent,\n\tisValidRange,\n\tsliceRange,\n\tspliceRange,\n} from '../helpers.js'\n\n/**\n * Implements `WorkspaceInterface` over one insertion-ordered path map the instance owns,\n * projecting fresh arrays on every read.\n *\n * Whole-file edits create text files, ranged edits operate only on existing text files, and\n * binary files remain available through construction-time hydration. Mutations emit after the\n * file map has changed.\n *\n * @example\n * ```ts\n * import { Workspace } from '@orkestrel/workspace'\n *\n * const workspace = new Workspace()\n * workspace.write('notes.txt', 'hello')\n * workspace.append('notes.txt', ' world')\n * workspace.read('notes.txt') // 'hello world'\n * ```\n */\nexport class Workspace implements WorkspaceInterface {\n\treadonly #id: string\n\treadonly #files = new Map<string, FileInterface>()\n\treadonly #emitter: Emitter<WorkspaceEventMap>\n\n\t/**\n\t * Creates a workspace.\n\t *\n\t * @param options - Optional identity, emitter configuration, and initial files\n\t */\n\tconstructor(options?: WorkspaceOptions) {\n\t\tthis.#id = options?.id ?? crypto.randomUUID()\n\t\tthis.#emitter = new Emitter<WorkspaceEventMap>({\n\t\t\t...(options?.on === undefined ? {} : { on: options.on }),\n\t\t\t...(options?.error === undefined ? {} : { error: options.error }),\n\t\t})\n\t\tif (options?.seed) for (const file of options.seed) this.#files.set(file.path, file)\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tget emitter(): EmitterInterface<WorkspaceEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget count(): number {\n\t\treturn this.#files.size\n\t}\n\n\tfile(path: string): FileInterface | undefined {\n\t\treturn this.#files.get(path)\n\t}\n\n\tfiles(): readonly FileInterface[] {\n\t\treturn [...this.#files.values()]\n\t}\n\n\tread(path: string): string | undefined\n\tread(path: string, range: Range): ReadResult | undefined\n\tread(paths: readonly string[]): Readonly<Record<string, string>>\n\tread(\n\t\tpath: string | readonly string[],\n\t\trange?: Range,\n\t): string | ReadResult | undefined | Readonly<Record<string, string>> {\n\t\tif (isArray(path)) {\n\t\t\tconst result: Record<string, string> = {}\n\t\t\tfor (const one of path) {\n\t\t\t\tconst file = this.#files.get(one)\n\t\t\t\tif (file && isTextContent(file.content)) result[one] = file.content.text\n\t\t\t}\n\t\t\treturn result\n\t\t}\n\t\tconst file = this.#files.get(path)\n\t\tif (!file) return undefined\n\t\tif (!range) return isTextContent(file.content) ? file.content.text : undefined\n\t\tif (!isTextContent(file.content)) {\n\t\t\tthrow new WorkspaceError('MODALITY', `Cannot read a range of a binary file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\treturn {\n\t\t\tcontent: sliceRange(file.content.text, range),\n\t\t\trange: clampRange(file.content.text, range),\n\t\t}\n\t}\n\n\thas(path: string): boolean\n\thas(paths: readonly string[]): boolean\n\thas(path: string | readonly string[]): boolean {\n\t\tif (isArray(path)) return path.every((one) => this.#files.has(one))\n\t\treturn this.#files.has(path)\n\t}\n\n\tsearch(query: string, options?: SearchOptions): readonly SearchMatch[] {\n\t\tconst pattern = this.#pattern(query, options)\n\t\tconst paths = this.#paths(options)\n\t\tconst limit = options?.limit\n\t\tconst matches: SearchMatch[] = []\n\t\tfor (const file of this.#files.values()) {\n\t\t\tif (limit !== undefined && matches.length >= limit) break\n\t\t\tif (paths !== undefined && !paths.has(file.path)) continue\n\t\t\tif (!isTextContent(file.content)) continue\n\t\t\tconst lines = file.content.text.split(/\\r\\n|\\n/)\n\t\t\tfor (const [index, lineText] of lines.entries()) {\n\t\t\t\tif (limit !== undefined && matches.length >= limit) break\n\t\t\t\tpattern.lastIndex = 0\n\t\t\t\tfor (const hit of lineText.matchAll(pattern)) {\n\t\t\t\t\tif (limit !== undefined && matches.length >= limit) break\n\t\t\t\t\tmatches.push({\n\t\t\t\t\t\tpath: file.path,\n\t\t\t\t\t\tline: index + 1,\n\t\t\t\t\t\tcolumn: hit.index + 1,\n\t\t\t\t\t\tlength: hit[0].length,\n\t\t\t\t\t\tcontent: lineText,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn matches\n\t}\n\n\treplace(query: string, replacement: string, options?: SearchOptions): ReplaceResult {\n\t\tconst pattern = this.#pattern(query, options)\n\t\tconst paths = this.#paths(options)\n\t\tconst limit = options?.limit\n\t\tconst changes: number[] = []\n\t\tfor (const [path, file] of this.#files) {\n\t\t\tconst occurrences = changes.reduce((total, count) => total + count, 0)\n\t\t\tif (limit !== undefined && occurrences >= limit) break\n\t\t\tif (paths !== undefined && !paths.has(path)) continue\n\t\t\tif (!isTextContent(file.content)) continue\n\t\t\tconst remaining = limit === undefined ? undefined : limit - occurrences\n\t\t\tpattern.lastIndex = 0\n\t\t\tconst text = file.content.text\n\t\t\tconst matches = Array.from(text.matchAll(pattern))\n\t\t\tconst count = matches.filter(\n\t\t\t\t(_, index) => remaining === undefined || !(index >= remaining),\n\t\t\t).length\n\t\t\tconst positions = matches.keys()\n\t\t\tconst next = text.replace(pattern, (match) =>\n\t\t\t\t(positions.next().value ?? Number.POSITIVE_INFINITY) < count ? replacement : match,\n\t\t\t)\n\t\t\tif (count > 0) {\n\t\t\t\tchanges.push(count)\n\t\t\t\tthis.write(path, next)\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\toccurrences: changes.reduce((total, count) => total + count, 0),\n\t\t\tfiles: changes.length,\n\t\t}\n\t}\n\n\twrite(path: string, content: string): void\n\twrite(path: string, content: string, range: Range): void\n\twrite(files: Readonly<Record<string, string>>): void\n\twrite(path: string | Readonly<Record<string, string>>, content?: string, range?: Range): void {\n\t\tif (isRecord(path)) {\n\t\t\tfor (const [one, text] of Object.entries(path)) this.#write(one, text)\n\t\t\treturn\n\t\t}\n\t\tif (content === undefined) return\n\t\tif (!range) {\n\t\t\tthis.#write(path, content)\n\t\t\treturn\n\t\t}\n\t\tthis.#splice(path, content, range)\n\t}\n\n\tprepend(path: string, content: string): void\n\tprepend(files: Readonly<Record<string, string>>): void\n\tprepend(path: string | Readonly<Record<string, string>>, content?: string): void {\n\t\tif (isRecord(path)) {\n\t\t\tfor (const [one, text] of Object.entries(path)) this.#prepend(one, text)\n\t\t\treturn\n\t\t}\n\t\tif (content === undefined) return\n\t\tthis.#prepend(path, content)\n\t}\n\n\tappend(path: string, content: string): void\n\tappend(files: Readonly<Record<string, string>>): void\n\tappend(path: string | Readonly<Record<string, string>>, content?: string): void {\n\t\tif (isRecord(path)) {\n\t\t\tfor (const [one, text] of Object.entries(path)) this.#append(one, text)\n\t\t\treturn\n\t\t}\n\t\tif (content === undefined) return\n\t\tthis.#append(path, content)\n\t}\n\n\tmove(from: string, to: string): boolean\n\tmove(mapping: Readonly<Record<string, string>>): boolean\n\tmove(from: string | Readonly<Record<string, string>>, to?: string): boolean {\n\t\tif (isRecord(from)) {\n\t\t\treturn Object.entries(from).reduce(\n\t\t\t\t(moved, [one, target]) => this.#move(one, target) && moved,\n\t\t\t\ttrue,\n\t\t\t)\n\t\t}\n\t\tif (to === undefined) return false\n\t\treturn this.#move(from, to)\n\t}\n\n\tremove(path: string): boolean\n\tremove(paths: readonly string[]): boolean\n\tremove(path: string | readonly string[]): boolean {\n\t\tif (isArray(path)) {\n\t\t\treturn Iterator.from(path).reduce((removed, one) => this.#remove(one) && removed, true)\n\t\t}\n\t\treturn this.#remove(path)\n\t}\n\n\tclear(): void {\n\t\tthis.#files.clear()\n\t\tthis.#emitter.emit('clear')\n\t}\n\n\tsnapshot(): WorkspaceSnapshot {\n\t\treturn { id: this.#id, files: this.files() }\n\t}\n\n\tdestroy(): void {\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#write(path: string, content: string): void {\n\t\tconst existing = this.#files.get(path)\n\t\tconst language =\n\t\t\texisting && isTextContent(existing.content) ? existing.content.language : inferLanguage(path)\n\t\tconst file = createFile({\n\t\t\tpath,\n\t\t\tcontent: { text: content, language },\n\t\t\tstate: existing ? 'modified' : 'created',\n\t\t})\n\t\tthis.#files.set(path, file)\n\t\tthis.#emitter.emit('write', file)\n\t}\n\n\t#splice(path: string, content: string, range: Range): void {\n\t\tconst existing = this.#files.get(path)\n\t\tif (!existing) {\n\t\t\tthrow new WorkspaceError('MISSING', `Cannot splice a range of a missing file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\tif (!isTextContent(existing.content)) {\n\t\t\tthrow new WorkspaceError('MODALITY', `Cannot splice a range of a binary file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\tif (!isValidRange(range)) {\n\t\t\tthrow new WorkspaceError('RANGE', `Invalid range for file: ${path}`, { path, range })\n\t\t}\n\t\tconst file = createFile({\n\t\t\tpath,\n\t\t\tcontent: {\n\t\t\t\ttext: spliceRange(existing.content.text, range, content),\n\t\t\t\tlanguage: existing.content.language,\n\t\t\t},\n\t\t\tstate: 'modified',\n\t\t})\n\t\tthis.#files.set(path, file)\n\t\tthis.#emitter.emit('write', file)\n\t}\n\n\t#prepend(path: string, content: string): void {\n\t\tconst existing = this.#files.get(path)\n\t\tif (existing === undefined) {\n\t\t\tthis.#write(path, content)\n\t\t\treturn\n\t\t}\n\t\tif (!isTextContent(existing.content)) {\n\t\t\tthrow new WorkspaceError('MODALITY', `Cannot prepend text to a binary file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\tthis.#write(path, content + existing.content.text)\n\t}\n\n\t#append(path: string, content: string): void {\n\t\tconst existing = this.#files.get(path)\n\t\tif (existing === undefined) {\n\t\t\tthis.#write(path, content)\n\t\t\treturn\n\t\t}\n\t\tif (!isTextContent(existing.content)) {\n\t\t\tthrow new WorkspaceError('MODALITY', `Cannot append text to a binary file: ${path}`, {\n\t\t\t\tpath,\n\t\t\t})\n\t\t}\n\t\tthis.#write(path, existing.content.text + content)\n\t}\n\n\t#move(from: string, to: string): boolean {\n\t\tif (from === to) return false\n\t\tconst file = this.#files.get(from)\n\t\tif (!file) return false\n\t\tconst moved = createFile({ path: to, content: file.content, state: 'modified' })\n\t\tconst entries = [...this.#files]\n\t\tthis.#files.clear()\n\t\tfor (const [path, current] of entries) {\n\t\t\tif (path === from) this.#files.set(to, moved)\n\t\t\telse if (path !== to) this.#files.set(path, current)\n\t\t}\n\t\tthis.#emitter.emit('move', from, to)\n\t\treturn true\n\t}\n\n\t#remove(path: string): boolean {\n\t\tconst removed = this.#files.delete(path)\n\t\tif (removed) this.#emitter.emit('remove', path)\n\t\treturn removed\n\t}\n\n\t#pattern(query: string, options?: SearchOptions): RegExp {\n\t\tconst source = options?.regex === true ? query : escapeRegExp(query)\n\t\tconst flags = options?.sensitive === false ? 'gi' : 'g'\n\t\ttry {\n\t\t\treturn new RegExp(source, flags)\n\t\t} catch {\n\t\t\tthrow new WorkspaceError('PATTERN', `Invalid search pattern: ${query}`, { query })\n\t\t}\n\t}\n\n\t// Reads the `paths` option into one membership set for the call, refusing a malformed list.\n\t#paths(options?: SearchOptions): ReadonlySet<string> | undefined {\n\t\tconst paths: unknown = options?.paths\n\t\tif (paths === undefined) return undefined\n\t\tif (!arrayOf(isString)(paths)) {\n\t\t\tthrow new WorkspaceError('PATHS', 'Invalid search paths: expected an array of path strings', {\n\t\t\t\tpaths,\n\t\t\t})\n\t\t}\n\t\treturn new Set(paths)\n\t}\n}\n","import type { EmitterErrorHandler, EmitterHooks } from '@orkestrel/emitter'\nimport type {\n\tWorkspaceEventMap,\n\tWorkspaceInterface,\n\tWorkspaceManagerInterface,\n\tWorkspaceManagerOptions,\n\tWorkspaceOptions,\n\tWorkspaceStoreInterface,\n} from '../types.js'\nimport { isArray } from '@orkestrel/contract'\nimport { Workspace } from './Workspace.js'\n\n/**\n * Implements `WorkspaceManagerInterface` over an insertion-ordered id map and one active id\n * the instance owns, resolving `active` through that map on every read and holding no emitter.\n *\n * A supplied store adds lenient snapshot `open` and `save` operations. Event defaults flow into\n * workspaces created through the registry, while observability remains owned by each workspace.\n *\n * @example\n * ```ts\n * import { WorkspaceManager } from '@orkestrel/workspace'\n *\n * const manager = new WorkspaceManager()\n * const workspace = manager.add({ id: 'scratch' })\n * manager.active === workspace\n * ```\n */\nexport class WorkspaceManager implements WorkspaceManagerInterface {\n\treadonly #workspaces = new Map<string, WorkspaceInterface>()\n\t#active: string | undefined\n\treadonly #on: EmitterHooks<WorkspaceEventMap> | undefined\n\treadonly #error: EmitterErrorHandler | undefined\n\treadonly #store: WorkspaceStoreInterface | undefined\n\n\t/**\n\t * Creates a registry.\n\t *\n\t * @param options - Default event hooks and optional snapshot store\n\t */\n\tconstructor(options?: WorkspaceManagerOptions) {\n\t\tthis.#on = options?.on\n\t\tthis.#error = options?.error\n\t\tthis.#store = options?.store\n\t}\n\n\tget count(): number {\n\t\treturn this.#workspaces.size\n\t}\n\n\tget active(): WorkspaceInterface | undefined {\n\t\treturn this.#active === undefined ? undefined : this.#workspaces.get(this.#active)\n\t}\n\n\tworkspace(id: string): WorkspaceInterface | undefined {\n\t\treturn this.#workspaces.get(id)\n\t}\n\n\tworkspaces(): readonly WorkspaceInterface[] {\n\t\treturn [...this.#workspaces.values()]\n\t}\n\n\tadd(options?: WorkspaceOptions): WorkspaceInterface {\n\t\tconst on = options?.on ?? this.#on\n\t\tconst error = options?.error ?? this.#error\n\t\tconst workspace = new Workspace({\n\t\t\t...(options?.id === undefined ? {} : { id: options.id }),\n\t\t\t...(on === undefined ? {} : { on }),\n\t\t\t...(error === undefined ? {} : { error }),\n\t\t\t...(options?.seed === undefined ? {} : { seed: options.seed }),\n\t\t})\n\t\tthis.#workspaces.set(workspace.id, workspace)\n\t\tif (this.#active === undefined) this.#active = workspace.id\n\t\treturn workspace\n\t}\n\n\tswitch(id: string): WorkspaceInterface | undefined {\n\t\tconst workspace = this.#workspaces.get(id)\n\t\tif (workspace === undefined) return undefined\n\t\tthis.#active = id\n\t\treturn workspace\n\t}\n\n\tasync open(id: string): Promise<WorkspaceInterface | undefined> {\n\t\tconst existing = this.#workspaces.get(id)\n\t\tif (existing !== undefined) {\n\t\t\tthis.#active = id\n\t\t\treturn existing\n\t\t}\n\t\tif (this.#store === undefined) return undefined\n\t\tconst snapshot = await this.#store.get(id)\n\t\tif (snapshot === undefined) return undefined\n\t\tconst workspace = this.add({ id, seed: snapshot.files })\n\t\tthis.#active = workspace.id\n\t\treturn workspace\n\t}\n\n\tasync save(id: string): Promise<boolean> {\n\t\tconst workspace = this.#workspaces.get(id)\n\t\tif (this.#store === undefined || workspace === undefined) return false\n\t\tawait this.#store.set(workspace.snapshot())\n\t\treturn true\n\t}\n\n\tremove(id: string): boolean\n\tremove(ids: readonly string[]): boolean\n\tremove(ids: string | readonly string[]): boolean {\n\t\tif (isArray(ids)) {\n\t\t\treturn Iterator.from(ids).reduce((removed, id) => this.#drop(id) && removed, true)\n\t\t}\n\t\treturn this.#drop(ids)\n\t}\n\n\tclear(): void {\n\t\tfor (const workspace of this.#workspaces.values()) workspace.destroy()\n\t\tthis.#workspaces.clear()\n\t\tthis.#active = undefined\n\t}\n\n\t#drop(id: string): boolean {\n\t\tconst workspace = this.#workspaces.get(id)\n\t\tif (workspace === undefined) return false\n\t\tthis.#workspaces.delete(id)\n\t\tworkspace.destroy()\n\t\tif (this.#active === id) this.#active = undefined\n\t\treturn true\n\t}\n}\n","import type {\n\tWorkspaceSnapshot,\n\tWorkspaceSnapshotRow,\n\tWorkspaceStoreInterface,\n} from '../../types.js'\nimport type { TableInterface } from '@orkestrel/database'\nimport { isWorkspaceSnapshot } from '../../validators.js'\n\n/**\n * Persists workspace snapshots in a database table.\n *\n * Snapshots occupy one opaque column and are narrowed when read back from the storage boundary.\n *\n * @example\n * ```ts\n * import { rawShape, stringShape } from '@orkestrel/contract'\n * import { createDatabase, createMemoryDriver } from '@orkestrel/database'\n * import { DatabaseWorkspaceStore } from '@orkestrel/workspace'\n *\n * const database = createDatabase({\n * \tdriver: createMemoryDriver(),\n * \ttables: { workspaces: { id: stringShape(), snapshot: rawShape({}) } },\n * })\n * const store = new DatabaseWorkspaceStore(database.table('workspaces'))\n * ```\n */\nexport class DatabaseWorkspaceStore implements WorkspaceStoreInterface {\n\treadonly #table: TableInterface<WorkspaceSnapshotRow>\n\n\t/**\n\t * Wraps a workspace snapshot table.\n\t *\n\t * @param table - The table keyed by workspace identifier\n\t */\n\tconstructor(table: TableInterface<WorkspaceSnapshotRow>) {\n\t\tthis.#table = table\n\t}\n\n\tasync get(id: string): Promise<WorkspaceSnapshot | undefined> {\n\t\tconst row = await this.#table.get(id)\n\t\tif (row === undefined) return undefined\n\t\treturn isWorkspaceSnapshot(row.snapshot) ? row.snapshot : undefined\n\t}\n\n\tasync set(snapshot: WorkspaceSnapshot): Promise<void> {\n\t\tawait this.#table.set({ id: snapshot.id, snapshot })\n\t}\n\n\tasync delete(id: string): Promise<void> {\n\t\tawait this.#table.remove(id)\n\t}\n}\n","import type { WorkspaceSnapshot, WorkspaceStoreInterface } from '../../types.js'\n\n/**\n * Holds workspace snapshots in the current process.\n *\n * @example\n * ```ts\n * import { MemoryWorkspaceStore } from '@orkestrel/workspace'\n *\n * const store = new MemoryWorkspaceStore()\n * ```\n */\nexport class MemoryWorkspaceStore implements WorkspaceStoreInterface {\n\treadonly #snapshots = new Map<string, WorkspaceSnapshot>()\n\n\tget(id: string): Promise<WorkspaceSnapshot | undefined> {\n\t\treturn Promise.resolve(this.#snapshots.get(id))\n\t}\n\n\tset(snapshot: WorkspaceSnapshot): Promise<void> {\n\t\tthis.#snapshots.set(snapshot.id, snapshot)\n\t\treturn Promise.resolve()\n\t}\n\n\tdelete(id: string): Promise<void> {\n\t\tthis.#snapshots.delete(id)\n\t\treturn Promise.resolve()\n\t}\n}\n","import type {\n\tBinaryContent,\n\tBinaryMIME,\n\tFileInput,\n\tFileInterface,\n\tTextContent,\n\tWorkspaceInterface,\n\tWorkspaceManagerInterface,\n\tWorkspaceManagerOptions,\n\tWorkspaceOptions,\n\tWorkspaceSnapshotRow,\n\tWorkspaceStoreInterface,\n} from './types.js'\nimport type { DriverInterface, TableInterface } from '@orkestrel/database'\nimport { rawShape, stringShape } from '@orkestrel/contract'\nimport { createDatabase, createMemoryDriver } from '@orkestrel/database'\nimport { computeSize, countLines } from './helpers.js'\nimport { Workspace } from './workspaces/Workspace.js'\nimport { WorkspaceManager } from './workspaces/WorkspaceManager.js'\nimport { DatabaseWorkspaceStore } from './workspaces/stores/DatabaseWorkspaceStore.js'\nimport { MemoryWorkspaceStore } from './workspaces/stores/MemoryWorkspaceStore.js'\n\n/**\n * Creates an immutable file with derived size and line counts.\n *\n * @param input - The file path, content, and optional state\n * @returns A frozen file record\n *\n * @example Files and content\n * ```ts\n * import {\n * \tcomputeSize,\n * \tcountLines,\n * \tcreateBinaryContent,\n * \tcreateFile,\n * \tcreateTextContent,\n * \tinferLanguage,\n * \tisBinary,\n * \tisTextContent,\n * } from '@orkestrel/workspace'\n *\n * const note = createFile({\n * \tpath: 'notes.md',\n * \tcontent: createTextContent('# Title\\nBody', inferLanguage('notes.md')), // 'markdown'\n * })\n *\n * note.size // 12 — UTF-8 bytes, through computeSize\n * note.lines // 2 — through countLines\n * note.state // 'created'\n * isTextContent(note.content) // true\n *\n * const icon = createFile({ path: 'icon.png', content: createBinaryContent('AAAA', 'image/png') })\n * isBinary(icon.content) // true\n * icon.size // 3 — decoded base64 bytes, through computeDecodedSize\n * ```\n */\nexport function createFile(input: FileInput): FileInterface {\n\treturn Object.freeze({\n\t\tpath: input.path,\n\t\tcontent: input.content,\n\t\tstate: input.state ?? 'created',\n\t\tsize: computeSize(input.content),\n\t\tlines: countLines(input.content),\n\t})\n}\n\n/**\n * Creates the text arm of {@link FileContent}, returned as {@link TextContent} rather than as\n * the whole union.\n *\n * @param text - The text body\n * @param language - The language tag\n * @returns Text file content\n *\n * @example\n * ```ts\n * import { createTextContent } from '@orkestrel/workspace'\n *\n * createTextContent('hello', 'text')\n * ```\n */\nexport function createTextContent(text: string, language: string): TextContent {\n\treturn { text, language }\n}\n\n/**\n * Creates the binary arm of {@link FileContent}, returned as {@link BinaryContent} rather than\n * as the whole union.\n *\n * @param base64 - The base64 payload\n * @param mime - The binary MIME\n * @returns Binary file content\n *\n * @example\n * ```ts\n * import { createBinaryContent } from '@orkestrel/workspace'\n *\n * createBinaryContent('AAAA', 'image/png')\n * ```\n */\nexport function createBinaryContent(base64: string, mime: BinaryMIME): BinaryContent {\n\treturn { base64, mime }\n}\n\n/**\n * Creates a workspace with the same identity, emitter, and seed options the constructor takes.\n *\n * @param options - Optional identity, emitter configuration, and initial files\n * @returns A working workspace\n *\n * @example\n * ```ts\n * import { createWorkspace } from '@orkestrel/workspace'\n *\n * const workspace = createWorkspace()\n * workspace.write('a.txt', 'hello')\n * ```\n */\nexport function createWorkspace(options?: WorkspaceOptions): WorkspaceInterface {\n\treturn new Workspace(options)\n}\n\n/**\n * Creates an in-memory workspace snapshot store.\n *\n * @returns A process-local workspace store\n *\n * @example\n * ```ts\n * import { createMemoryWorkspaceStore } from '@orkestrel/workspace'\n *\n * const store = createMemoryWorkspaceStore()\n * ```\n */\nexport function createMemoryWorkspaceStore(): WorkspaceStoreInterface {\n\treturn new MemoryWorkspaceStore()\n}\n\n/**\n * Creates a database-backed workspace snapshot store, over an in-memory driver when the caller\n * supplies none.\n *\n * @param driver - The database driver. Default: an in-memory driver.\n * @returns A workspace store backed by the supplied driver\n *\n * @example\n * ```ts\n * import { createDatabaseWorkspaceStore } from '@orkestrel/workspace'\n *\n * const store = createDatabaseWorkspaceStore()\n * ```\n */\nexport function createDatabaseWorkspaceStore(\n\tdriver: DriverInterface = createMemoryDriver(),\n): WorkspaceStoreInterface {\n\tconst columns = { id: stringShape(), snapshot: rawShape({}) }\n\tconst database = createDatabase({ driver, tables: { workspaces: columns } })\n\tconst table: TableInterface<WorkspaceSnapshotRow> = database.table('workspaces')\n\treturn new DatabaseWorkspaceStore(table)\n}\n\n/**\n * Creates an empty workspace registry.\n *\n * @param options - Default event hooks and optional durability\n * @returns A workspace manager\n *\n * @example\n * ```ts\n * import { createWorkspaceManager } from '@orkestrel/workspace'\n *\n * const manager = createWorkspaceManager()\n * manager.add()\n * ```\n */\nexport function createWorkspaceManager(\n\toptions?: WorkspaceManagerOptions,\n): WorkspaceManagerInterface {\n\treturn new WorkspaceManager(options)\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orkestrel/workspace",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.18",
|
|
4
4
|
"description": "A virtual file workspace for the @orkestrel line — path-keyed immutable files, an edit and search surface, registries with an active pointer, and pluggable snapshot stores. Part of the @orkestrel line.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"edit",
|
|
@@ -76,9 +76,9 @@
|
|
|
76
76
|
"devDependencies": {
|
|
77
77
|
"@microsoft/api-extractor": "^7.60.1",
|
|
78
78
|
"@orkestrel/guide": "^0.0.31",
|
|
79
|
-
"@orkestrel/probe": "^0.0.
|
|
80
|
-
"@orkestrel/scaffold": "^0.0.
|
|
81
|
-
"@orkestrel/test": "^0.0.
|
|
79
|
+
"@orkestrel/probe": "^0.0.30",
|
|
80
|
+
"@orkestrel/scaffold": "^0.0.133",
|
|
81
|
+
"@orkestrel/test": "^0.0.37",
|
|
82
82
|
"@types/node": "^26.6.6",
|
|
83
83
|
"oxfmt": "^0.78.0",
|
|
84
84
|
"oxlint": "^1.93.0",
|