wiki-graph-sdk 0.7.1 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -1
- package/dist/archives.cjs +494 -656
- package/dist/archives.cjs.map +1 -1
- package/dist/archives.d.ts +48 -80
- package/dist/archives.js +431 -585
- package/dist/archives.js.map +1 -1
- package/dist/conversions.cjs +183 -33
- package/dist/conversions.cjs.map +1 -1
- package/dist/conversions.d.ts +8 -1
- package/dist/conversions.js +188 -29
- package/dist/conversions.js.map +1 -1
- package/dist/default-worker.cjs +322 -62
- package/dist/default-worker.cjs.map +1 -1
- package/dist/default-worker.d.ts +1 -0
- package/dist/default-worker.js +336 -60
- package/dist/default-worker.js.map +1 -1
- package/dist/embedding.cjs +2 -1
- package/dist/embedding.cjs.map +1 -1
- package/dist/embedding.d.ts +4 -4
- package/dist/embedding.js +2 -1
- package/dist/embedding.js.map +1 -1
- package/dist/index.cjs +1295 -949
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +58 -24
- package/dist/index.js +1164 -805
- package/dist/index.js.map +1 -1
- package/dist/{jobs-Dd5PMSId.d.ts → jobs-CRK-DZ40.d.ts} +27 -14
- package/dist/local-config.cjs +2 -1
- package/dist/local-config.cjs.map +1 -1
- package/dist/local-config.js +2 -1
- package/dist/local-config.js.map +1 -1
- package/dist/maintenance.cjs +140 -30
- package/dist/maintenance.cjs.map +1 -1
- package/dist/maintenance.d.ts +5 -1
- package/dist/maintenance.js +145 -26
- package/dist/maintenance.js.map +1 -1
- package/dist/runtime-config.cjs +4 -3
- package/dist/runtime-config.cjs.map +1 -1
- package/dist/runtime-config.d.ts +4 -1
- package/dist/runtime-config.js +4 -3
- package/dist/runtime-config.js.map +1 -1
- package/dist/stage-BnWI3Rqt.d.ts +33 -0
- package/dist/stage.cjs +22 -12
- package/dist/stage.cjs.map +1 -1
- package/dist/stage.d.ts +2 -14
- package/dist/stage.js +22 -12
- package/dist/stage.js.map +1 -1
- package/dist/target-CZ7elwmj.d.ts +14 -0
- package/dist/wikispine.cjs +14 -10
- package/dist/wikispine.cjs.map +1 -1
- package/dist/wikispine.js +14 -10
- package/dist/wikispine.js.map +1 -1
- package/dist/worker.cjs +295 -25
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.d.ts +28 -5
- package/dist/worker.js +313 -28
- package/dist/worker.js.map +1 -1
- package/package.json +2 -2
package/dist/local-config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/local-config.ts","../src/runtime-context.ts","../src/node-platform.ts"],"sourcesContent":["import { openSharedStateDatabase } from \"wiki-graph-core\";\nimport { getWikiGraphSDKStateDir } from \"./runtime-context.js\";\nimport { NodeFile } from \"./node-platform.js\";\nimport { join } from \"path\";\nimport { homedir } from \"os\";\nimport type { Database } from \"wiki-graph-core\";\n\nexport const LOCAL_CONFIG_SECTIONS = [\n \"concurrent\",\n \"embeddings\",\n \"llm\",\n \"wikimedia\",\n \"wikispine\",\n] as const;\n\nexport type LocalConfigSection = (typeof LOCAL_CONFIG_SECTIONS)[number];\n\nexport type LocalConfigObject = Readonly<Record<string, unknown>>;\n\nconst LOCAL_CONFIG_SCHEMA_SQL = `\nCREATE TABLE IF NOT EXISTS config_sections (\n section TEXT PRIMARY KEY,\n value_json TEXT NOT NULL,\n updated_at INTEGER NOT NULL\n);\n`;\n\nexport async function readLocalConfigSection(\n section: LocalConfigSection,\n): Promise<LocalConfigObject> {\n return await withLocalConfigDatabase(async (database) => {\n return await readLocalConfigSectionInDatabase(database, section);\n });\n}\n\nexport async function replaceLocalConfigSection(\n section: LocalConfigSection,\n value: LocalConfigObject,\n): Promise<LocalConfigObject> {\n const normalized = validateLocalConfigSection(section, value);\n\n return await withLocalConfigDatabase(async (database) => {\n await writeLocalConfigSectionInDatabase(database, section, normalized);\n return normalized;\n });\n}\n\nexport async function putLocalConfigValue(\n section: LocalConfigSection,\n key: string,\n value: unknown,\n): Promise<LocalConfigObject> {\n return await withLocalConfigDatabase(async (database) => {\n const current = await readLocalConfigSectionInDatabase(database, section);\n const next = validateLocalConfigSection(section, {\n ...current,\n [normalizeLocalConfigKey(section, key)]: value,\n });\n\n await writeLocalConfigSectionInDatabase(database, section, next);\n return next;\n });\n}\n\nexport async function deleteLocalConfigValue(\n section: LocalConfigSection,\n key: string,\n): Promise<LocalConfigObject> {\n return await withLocalConfigDatabase(async (database) => {\n const current = await readLocalConfigSectionInDatabase(database, section);\n const normalizedKey = normalizeLocalConfigKey(section, key);\n const { [normalizedKey]: _removed, ...nextInput } = current;\n const next = validateLocalConfigSection(section, nextInput);\n\n await writeLocalConfigSectionInDatabase(database, section, next);\n return next;\n });\n}\n\nexport async function clearLocalConfigSection(\n section: LocalConfigSection,\n): Promise<LocalConfigObject> {\n return await replaceLocalConfigSection(section, {});\n}\n\nexport function parseLocalConfigSection(\n value: string | undefined,\n): LocalConfigSection | undefined {\n if (value === \"embedding\") {\n return \"embeddings\";\n }\n\n return LOCAL_CONFIG_SECTIONS.find((section) => section === value);\n}\n\nexport function maskLocalConfigSection(\n section: LocalConfigSection,\n value: LocalConfigObject,\n): LocalConfigObject {\n if (\n (section !== \"llm\" &&\n section !== \"embeddings\" &&\n section !== \"wikimedia\" &&\n section !== \"wikispine\") ||\n (value.apiKey === undefined && value.token === undefined)\n ) {\n return value;\n }\n\n return {\n ...value,\n ...(value.apiKey === undefined ? {} : { apiKey: \"****\" }),\n ...(value.token === undefined ? {} : { token: \"****\" }),\n };\n}\n\nexport function normalizeLocalConfigKey(\n section: LocalConfigSection,\n key: string,\n): string {\n const normalized = key.trim();\n\n if (normalized === \"\") {\n throw new Error(\"Config key cannot be empty.\");\n }\n\n if (section === \"llm\" || section === \"embeddings\") {\n switch (normalized) {\n case \"api-key\":\n return \"apiKey\";\n case \"base-url\":\n return \"baseURL\";\n default:\n return normalized;\n }\n }\n return normalized;\n}\n\nexport function validateLocalConfigSection(\n section: LocalConfigSection,\n value: LocalConfigObject,\n): LocalConfigObject {\n switch (section) {\n case \"embeddings\":\n return validateEmbeddingsConfig(value);\n case \"llm\":\n return validateLLMConfig(value);\n case \"concurrent\":\n return validateConcurrentConfig(value);\n case \"wikimedia\":\n return validateWikimediaConfig(value);\n case \"wikispine\":\n return validateWikispineConfig(value);\n }\n}\n\nasync function withLocalConfigDatabase<T>(\n operation: (database: Database) => Promise<T>,\n): Promise<T> {\n const database = await openSharedStateDatabase(\n new NodeFile(\n join(\n getWikiGraphSDKStateDir() ?? join(homedir(), \".wikigraph\"),\n \"core.sqlite\",\n ),\n ),\n LOCAL_CONFIG_SCHEMA_SQL,\n );\n\n try {\n return await operation(database);\n } finally {\n await database.close();\n }\n}\n\nasync function readLocalConfigSectionInDatabase(\n database: Database,\n section: LocalConfigSection,\n): Promise<LocalConfigObject> {\n const value = await database.queryOne(\n \"SELECT value_json FROM config_sections WHERE section = ?\",\n [section],\n (row) => String(row.value_json),\n );\n\n return value === undefined ? {} : parseSectionJSON(section, value);\n}\n\nasync function writeLocalConfigSectionInDatabase(\n database: Database,\n section: LocalConfigSection,\n value: LocalConfigObject,\n): Promise<void> {\n await database.run(\n `\nINSERT INTO config_sections (section, value_json, updated_at)\nVALUES (?, ?, ?)\nON CONFLICT(section) DO UPDATE SET\n value_json = excluded.value_json,\n updated_at = excluded.updated_at\n`,\n [section, JSON.stringify(value), Date.now()],\n );\n}\n\nfunction parseSectionJSON(\n section: LocalConfigSection,\n value: string,\n): LocalConfigObject {\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(value);\n } catch (error) {\n throw new Error(\n `Invalid local config JSON for ${section}: ${formatError(error)}`,\n );\n }\n\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\n `Invalid local config section ${section}: expected object.`,\n );\n }\n\n return validateLocalConfigSection(section, parsed as LocalConfigObject);\n}\n\nfunction validateEmbeddingsConfig(value: LocalConfigObject): LocalConfigObject {\n const allowedKeys = new Set([\n \"apiKey\",\n \"baseURL\",\n \"dimensions\",\n \"model\",\n \"name\",\n \"provider\",\n ]);\n const allowedProviders = new Set([\"openai\", \"openai-compatible\"]);\n const next: Record<string, unknown> = {};\n\n for (const [key, entry] of Object.entries(value)) {\n if (!allowedKeys.has(key)) {\n throw new Error(`Unknown embeddings config key: ${key}`);\n }\n if (key === \"dimensions\") {\n const parsed =\n typeof entry === \"number\"\n ? entry\n : typeof entry === \"string\"\n ? Number(entry)\n : NaN;\n\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new Error(\"embeddings.dimensions must be a positive integer.\");\n }\n next[key] = parsed;\n continue;\n }\n if (typeof entry !== \"string\" || entry.trim() === \"\") {\n throw new Error(`embeddings.${key} must be a non-empty string.`);\n }\n const normalized = entry.trim();\n\n if (key === \"provider\" && !allowedProviders.has(normalized)) {\n throw new Error(`Unknown embeddings.provider: ${normalized}`);\n }\n\n next[key] = normalized;\n }\n\n return next;\n}\n\nfunction validateLLMConfig(value: LocalConfigObject): LocalConfigObject {\n const allowedKeys = new Set([\n \"apiKey\",\n \"baseURL\",\n \"model\",\n \"name\",\n \"provider\",\n ]);\n const allowedProviders = new Set([\n \"anthropic\",\n \"google\",\n \"openai\",\n \"openai-compatible\",\n ]);\n const next: Record<string, unknown> = {};\n\n for (const [key, entry] of Object.entries(value)) {\n if (!allowedKeys.has(key)) {\n throw new Error(`Unknown llm config key: ${key}`);\n }\n if (typeof entry !== \"string\" || entry.trim() === \"\") {\n throw new Error(`llm.${key} must be a non-empty string.`);\n }\n const normalized = entry.trim();\n\n if (key === \"provider\" && !allowedProviders.has(normalized)) {\n throw new Error(`Unknown llm.provider: ${normalized}`);\n }\n\n next[key] = normalized;\n }\n\n return next;\n}\n\nfunction validateConcurrentConfig(value: LocalConfigObject): LocalConfigObject {\n const allowedKeys = new Set([\"job\", \"request\"]);\n const next: Record<string, unknown> = {};\n\n for (const [key, entry] of Object.entries(value)) {\n if (!allowedKeys.has(key)) {\n throw new Error(`Unknown concurrent config key: ${key}`);\n }\n const parsed =\n typeof entry === \"number\"\n ? entry\n : typeof entry === \"string\"\n ? Number(entry)\n : NaN;\n\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new Error(`concurrent.${key} must be a positive integer.`);\n }\n next[key] = parsed;\n }\n\n return next;\n}\n\nfunction validateWikispineConfig(value: LocalConfigObject): LocalConfigObject {\n const allowedKeys = new Set([\"endpoint\", \"provider\", \"token\"]);\n const allowedProviders = new Set([\"cli\", \"fetch\"]);\n const next: Record<string, unknown> = {};\n\n for (const [key, entry] of Object.entries(value)) {\n if (!allowedKeys.has(key)) {\n throw new Error(`Unknown wikispine config key: ${key}`);\n }\n if (typeof entry !== \"string\" || entry.trim() === \"\") {\n throw new Error(`wikispine.${key} must be a non-empty string.`);\n }\n const normalized = entry.trim();\n\n if (key === \"provider\" && !allowedProviders.has(normalized)) {\n throw new Error(`Unknown wikispine.provider: ${normalized}`);\n }\n\n next[key] = normalized;\n }\n\n return next;\n}\n\nfunction validateWikimediaConfig(value: LocalConfigObject): LocalConfigObject {\n return validateEndpointConfig(\"wikimedia\", value);\n}\n\nfunction validateEndpointConfig(\n section: \"wikimedia\",\n value: LocalConfigObject,\n): LocalConfigObject {\n const allowedKeys = new Set([\"endpoint\", \"token\"]);\n const next: Record<string, unknown> = {};\n\n for (const [key, entry] of Object.entries(value)) {\n if (!allowedKeys.has(key)) {\n throw new Error(`Unknown ${section} config key: ${key}`);\n }\n if (typeof entry !== \"string\" || entry.trim() === \"\") {\n throw new Error(`${section}.${key} must be a non-empty string.`);\n }\n next[key] = entry.trim();\n }\n\n return next;\n}\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import { AsyncLocalStorage } from \"async_hooks\";\n\nexport type WikiGraphSDKEnvPolicy = \"development\" | \"production\";\n\nexport interface WikiGraphSDKRuntimeContext {\n readonly cwd: string;\n readonly env: NodeJS.ProcessEnv;\n readonly envPolicy: WikiGraphSDKEnvPolicy;\n readonly stateDir?: string | undefined;\n}\n\n/** Shared by independently bundled SDK entry points in the same process. */\nconst RUNTIME_CONTEXT_KEY = Symbol.for(\"wiki-graph-sdk.runtime-context.v1\");\nconst runtimeContext = getRuntimeContextStorage();\n\nfunction getRuntimeContextStorage(): AsyncLocalStorage<WikiGraphSDKRuntimeContext> {\n const runtimeGlobal = globalThis as unknown as Record<PropertyKey, unknown>;\n const existing = runtimeGlobal[RUNTIME_CONTEXT_KEY];\n if (existing !== undefined) {\n return existing as AsyncLocalStorage<WikiGraphSDKRuntimeContext>;\n }\n\n const storage = new AsyncLocalStorage<WikiGraphSDKRuntimeContext>();\n Object.defineProperty(runtimeGlobal, RUNTIME_CONTEXT_KEY, {\n configurable: false,\n enumerable: false,\n value: storage,\n writable: false,\n });\n return storage;\n}\n\nexport async function withWikiGraphSDKRuntimeContext<T>(\n context: WikiGraphSDKRuntimeContext,\n operation: () => Promise<T> | T,\n): Promise<T> {\n return await runtimeContext.run(context, operation);\n}\n\nexport function getWikiGraphSDKRuntimeContext(): WikiGraphSDKRuntimeContext {\n return (\n runtimeContext.getStore() ?? {\n cwd: process.cwd(),\n env: process.env,\n envPolicy: \"production\",\n }\n );\n}\n\nexport function getWikiGraphSDKStateDir(): string | undefined {\n return getWikiGraphSDKRuntimeContext().stateDir;\n}\n","/* eslint-disable no-restricted-syntax, @typescript-eslint/parameter-properties */\nimport * as asyncHooks from \"node:async_hooks\";\nimport * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport * as fsPromises from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport * as pathModule from \"node:path\";\nimport * as process from \"node:process\";\nimport { Readable, Writable } from \"node:stream\";\nimport { pipeline } from \"node:stream/promises\";\nimport * as sqlite3 from \"sqlite3\";\nimport * as yauzl from \"yauzl\";\nimport * as yazl from \"yazl\";\nimport { Environment, Loader, type LoaderSource } from \"nunjucks\";\n\nconst nodeProcess =\n (process as unknown as { default?: typeof process }).default ?? process;\nconst nodeSqlite3 =\n (sqlite3 as unknown as { default?: typeof sqlite3 }).default ?? sqlite3;\n\nimport {\n getWikiGraphStorage,\n installWikiGraphPlatform,\n installWikiGraphStorage,\n withWikiGraphStorage,\n type Directory,\n type File,\n type FileReader,\n type ReadonlyFile,\n type FileWriter,\n type HostDatabaseConnection,\n type HostDatabaseOpenOptions,\n type HostDatabaseRow,\n type HostDatabaseValue,\n type HostZipWriteEntry,\n type HostZipReader,\n type WikiGraphPlatform,\n type WikiGraphStorage,\n normalizeTemplateName,\n} from \"wiki-graph-core/platform\";\n\n/** Stable across independently bundled SDK entry points. */\nconst NODE_RESOURCE_KIND = Symbol.for(\"wiki-graph-sdk.node-resource.v1\");\n\n/** Install the Node implementation used by the CLI and its workers. */\nexport class NodeFile implements File {\n public readonly kind = \"file\" as const;\n public readonly [NODE_RESOURCE_KIND] = \"file\" as const;\n public readonly identity: string;\n public readonly name: string;\n\n public constructor(\n public readonly path: string,\n name = pathModule.basename(path),\n ) {\n this.identity = encodeNodeResourceIdentity(\"file\", path);\n this.name = name;\n }\n\n public async openReader(): Promise<FileReader> {\n const handle = await fsPromises.open(this.path, \"r\");\n let closed = false;\n try {\n const stats = await handle.stat();\n if (!stats.isFile())\n throw new Error(\"File reader requires a regular file\");\n const { size } = stats;\n return {\n size,\n close: async () => {\n if (!closed) await handle.close();\n closed = true;\n },\n read: async (offset, length) => {\n if (closed) throw new Error(\"Cannot read from a closed FileReader\");\n assertFileRange(offset, length, size);\n const buffer = Buffer.allocUnsafe(length);\n let bytesRead = 0;\n while (bytesRead < length) {\n const result = await handle.read(\n buffer,\n bytesRead,\n length - bytesRead,\n offset + bytesRead,\n );\n if (result.bytesRead === 0) {\n throw new Error(\"File changed while reading its byte range\");\n }\n bytesRead += result.bytesRead;\n }\n return new Uint8Array(buffer.buffer, buffer.byteOffset, bytesRead);\n },\n };\n } catch (error) {\n await handle.close();\n throw error;\n }\n }\n\n public async getLastModified(): Promise<number | undefined> {\n try {\n return (await fsPromises.stat(this.path)).mtimeMs;\n } catch (error) {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return undefined;\n }\n throw error;\n }\n }\n\n public async openWriter(): Promise<FileWriter> {\n await fsPromises.mkdir(pathModule.dirname(this.path), { recursive: true });\n const temporary = `${this.path}.tmp-${crypto.randomUUID()}`;\n const handle = await fsPromises.open(temporary, \"wx\");\n let closed = false;\n return {\n write: async (data) => {\n if (closed) throw new Error(\"Cannot write to a closed FileWriter\");\n await writeNodeFileHandle(handle, data);\n },\n writeAt: async (offset, data) => {\n if (closed) throw new Error(\"Cannot write to a closed FileWriter\");\n assertFileOffset(offset);\n await writeNodeFileHandle(handle, data, offset);\n },\n commit: async () => {\n if (!closed) {\n await handle.close();\n await fsPromises.rename(temporary, this.path);\n }\n closed = true;\n },\n abort: async () => {\n if (!closed) {\n await handle.close();\n await fsPromises.rm(temporary, { force: true });\n }\n closed = true;\n },\n };\n }\n}\n\n/** @internal Completes writes even when the Node file handle reports a short write. */\nexport async function writeNodeFileHandle(\n handle: Pick<fsPromises.FileHandle, \"write\">,\n data: Uint8Array | string,\n position?: number,\n): Promise<void> {\n const buffer = Buffer.from(data);\n let written = 0;\n while (written < buffer.byteLength) {\n const result = await handle.write(\n buffer,\n written,\n buffer.byteLength - written,\n position === undefined ? null : position + written,\n );\n if (result.bytesWritten === 0) {\n throw new Error(\"File writer made no progress\");\n }\n written += result.bytesWritten;\n }\n}\n\nfunction assertFileRange(offset: number, length: number, size: number): void {\n assertFileOffset(offset);\n if (!Number.isSafeInteger(length) || length < 0) {\n throw new RangeError(\n \"File read length must be a non-negative safe integer\",\n );\n }\n if (offset > size || length > size - offset) {\n throw new RangeError(\"File read range exceeds the file size\");\n }\n}\n\nfunction assertFileOffset(offset: number): void {\n if (!Number.isSafeInteger(offset) || offset < 0) {\n throw new RangeError(\"File offset must be a non-negative safe integer\");\n }\n}\n\nexport class NodeDirectory implements Directory {\n public readonly kind = \"directory\" as const;\n public readonly [NODE_RESOURCE_KIND] = \"directory\" as const;\n public readonly identity: string;\n public readonly name: string;\n\n public constructor(public readonly path: string) {\n this.identity = encodeNodeResourceIdentity(\"directory\", path);\n this.name = pathModule.basename(path);\n }\n\n public async getFile(name: string): Promise<File | undefined> {\n assertChildName(name);\n const file = new NodeFile(pathModule.join(this.path, name));\n try {\n return (await fsPromises.stat(file.path)).isFile() ? file : undefined;\n } catch {\n return undefined;\n }\n }\n\n public async getLastModified(): Promise<number | undefined> {\n try {\n return (await fsPromises.stat(this.path)).mtimeMs;\n } catch (error) {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return undefined;\n }\n throw error;\n }\n }\n\n public async getDirectory(name: string): Promise<Directory | undefined> {\n assertChildName(name);\n const directory = new NodeDirectory(pathModule.join(this.path, name));\n try {\n return (await fsPromises.stat(directory.path)).isDirectory()\n ? directory\n : undefined;\n } catch {\n return undefined;\n }\n }\n\n public async list(): Promise<ReadonlyArray<File | Directory>> {\n const entries = await fsPromises.readdir(this.path, {\n withFileTypes: true,\n });\n return entries.map((entry) =>\n entry.isDirectory()\n ? new NodeDirectory(pathModule.join(this.path, entry.name))\n : new NodeFile(pathModule.join(this.path, entry.name), entry.name),\n );\n }\n\n public async createFile(name: string): Promise<File> {\n assertChildName(name);\n await fsPromises.mkdir(this.path, { recursive: true });\n const file = new NodeFile(pathModule.join(this.path, name));\n await fsPromises.writeFile(file.path, \"\", { flag: \"wx\" });\n return file;\n }\n\n public async createDirectory(name: string): Promise<Directory> {\n assertChildName(name);\n await fsPromises.mkdir(this.path, { recursive: true });\n const directory = new NodeDirectory(pathModule.join(this.path, name));\n await fsPromises.mkdir(directory.path);\n return directory;\n }\n\n public async remove(\n name: string,\n options?: { readonly recursive?: boolean },\n ): Promise<void> {\n assertChildName(name);\n await fsPromises.rm(pathModule.join(this.path, name), {\n force: true,\n recursive: options?.recursive === true,\n });\n }\n}\n\nfunction encodeNodeResourceIdentity(\n kind: \"directory\" | \"file\",\n path: string,\n): string {\n return `node-${kind}:${Buffer.from(pathModule.resolve(path), \"utf8\").toString(\"base64url\")}`;\n}\n\nfunction decodeNodeResourceIdentity(\n identity: string,\n kind: \"directory\" | \"file\",\n): string | undefined {\n const prefix = `node-${kind}:`;\n if (!identity.startsWith(prefix)) {\n // State created before opaque resource identities stored native paths.\n return pathModule.isAbsolute(identity) ? identity : undefined;\n }\n try {\n return Buffer.from(identity.slice(prefix.length), \"base64url\").toString(\n \"utf8\",\n );\n } catch {\n return undefined;\n }\n}\n\nexport function getNodeResourcePath(resource: File | Directory): string {\n const brandedPath = getBrandedNodeResourcePath(resource, resource.kind);\n if (brandedPath !== undefined) return brandedPath;\n if (\n typeof resource === \"object\" &&\n resource !== null &&\n \"path\" in resource &&\n typeof resource.path === \"string\"\n ) {\n return resource.path;\n }\n throw new TypeError(\"Expected a Node File or Directory resource\");\n}\n\nfunction assertChildName(name: string): void {\n if (\n name.length === 0 ||\n name === \".\" ||\n name === \"..\" ||\n pathModule.isAbsolute(name) ||\n name.includes(\"/\") ||\n name.includes(\"\\\\\")\n ) {\n throw new TypeError(`Directory child must be a relative name: ${name}`);\n }\n}\n\nclass NodeDatabaseConnection implements HostDatabaseConnection {\n public constructor(private readonly database: sqlite3.Database) {}\n\n public async close(): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n this.database.close((error) => {\n if (error) reject(error);\n else resolve();\n });\n });\n }\n\n public async execute(sql: string): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n this.database.exec(sql, (error) => {\n if (error) reject(error);\n else resolve();\n });\n });\n }\n\n public async queryAll(\n sql: string,\n params: readonly HostDatabaseValue[] = [],\n ): Promise<readonly HostDatabaseRow[]> {\n return await new Promise((resolve, reject) => {\n this.database.all(sql, [...params], (error, rows: HostDatabaseRow[]) => {\n if (error) reject(error);\n else resolve(rows);\n });\n });\n }\n\n public async queryOne(\n sql: string,\n params: readonly HostDatabaseValue[] = [],\n ): Promise<HostDatabaseRow | undefined> {\n return await new Promise((resolve, reject) => {\n this.database.get(sql, [...params], (error, row: HostDatabaseRow) => {\n if (error) reject(error);\n else resolve(row);\n });\n });\n }\n\n public async run(\n sql: string,\n params: readonly HostDatabaseValue[] = [],\n ): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n this.database.run(sql, [...params], (error) => {\n if (error) reject(error);\n else resolve();\n });\n });\n }\n}\n\nasync function openNodeDatabase(\n file: ReadonlyFile,\n options: HostDatabaseOpenOptions,\n): Promise<NodeDatabaseConnection> {\n const flags =\n (options.mode === \"readonly\"\n ? nodeSqlite3.OPEN_READONLY\n : nodeSqlite3.OPEN_READWRITE |\n (options.create ? nodeSqlite3.OPEN_CREATE : 0)) |\n nodeSqlite3.OPEN_FULLMUTEX;\n return new NodeDatabaseConnection(await openNativeNodeDatabase(file, flags));\n}\n\nasync function openNativeNodeDatabase(\n file: ReadonlyFile,\n flags: number,\n): Promise<sqlite3.Database> {\n const path = getBrandedNodeResourcePath(file, \"file\");\n if (path === undefined) {\n throw new TypeError(\"The Node database adapter requires a NodeFile\");\n }\n return await new Promise((resolve, reject) => {\n const database = new nodeSqlite3.Database(path, flags, (error) => {\n if (error) reject(error);\n else resolve(database);\n });\n });\n}\n\nasync function openNodeZip(file: ReadonlyFile): Promise<HostZipReader> {\n const path = getBrandedNodeResourcePath(file, \"file\");\n if (path === undefined) {\n throw new TypeError(\"The Node ZIP adapter requires a NodeFile\");\n }\n const zipFile = await new Promise<yauzl.ZipFile>((resolve, reject) => {\n yauzl.open(\n path,\n { autoClose: false, lazyEntries: true },\n (error, opened) => {\n if (error || opened === undefined)\n reject(error ?? new Error(\"Cannot open ZIP\"));\n else resolve(opened);\n },\n );\n });\n\n const entries = await new Promise<Map<string, yauzl.Entry>>(\n (resolve, reject) => {\n const discovered = new Map<string, yauzl.Entry>();\n const rejectAndClose = (error: unknown) => {\n zipFile.close();\n reject(\n error instanceof Error\n ? error\n : new Error(\"Cannot scan ZIP central directory\"),\n );\n };\n const resolveEntries = () => {\n zipFile.off(\"error\", rejectAndClose);\n resolve(discovered);\n };\n zipFile.on(\"entry\", (entry: yauzl.Entry) => {\n if (!entry.fileName.endsWith(\"/\")) {\n discovered.set(entry.fileName, entry);\n }\n zipFile.readEntry();\n });\n zipFile.once(\"error\", rejectAndClose);\n zipFile.once(\"end\", resolveEntries);\n zipFile.readEntry();\n },\n );\n\n let closed = false;\n return {\n close: () => {\n if (!closed) zipFile.close();\n closed = true;\n return Promise.resolve();\n },\n copyEntry: async (name, target) => {\n if (closed) throw new Error(\"Cannot read a closed ZIP archive\");\n const entry = entries.get(name);\n if (entry === undefined) return false;\n await copyNodeZipEntry(zipFile, entry, target);\n return true;\n },\n getEntrySize: (name) => {\n if (closed) throw new Error(\"Cannot read a closed ZIP archive\");\n return Promise.resolve(entries.get(name)?.uncompressedSize);\n },\n listEntries: () => Promise.resolve([...entries.keys()]),\n readEntryRange: async (name, offset, length) => {\n if (closed) throw new Error(\"Cannot read a closed ZIP archive\");\n const entry = entries.get(name);\n if (entry === undefined) return undefined;\n return await readNodeZipEntryRange(zipFile, entry, offset, length);\n },\n readEntry: async (name) => {\n if (closed) throw new Error(\"Cannot read a closed ZIP archive\");\n const entry = entries.get(name);\n if (entry === undefined) return undefined;\n return await readNodeZipEntry(zipFile, entry);\n },\n };\n}\n\nasync function copyNodeZipEntry(\n zipFile: yauzl.ZipFile,\n entry: yauzl.Entry,\n target: File,\n): Promise<void> {\n const writer = await target.openWriter();\n try {\n const stream = await openNodeZipEntryStream(zipFile, entry);\n await writeNodeStream(stream, writer);\n await writer.commit();\n } catch (error) {\n await writer.abort().catch(() => undefined);\n throw error;\n }\n}\n\nasync function readNodeZipEntry(\n zipFile: yauzl.ZipFile,\n entry: yauzl.Entry,\n): Promise<Uint8Array> {\n return await collectNodeStream(await openNodeZipEntryStream(zipFile, entry));\n}\n\nasync function readNodeZipEntryRange(\n zipFile: yauzl.ZipFile,\n entry: yauzl.Entry,\n offset: number,\n length: number,\n): Promise<Uint8Array> {\n assertFileRange(offset, length, entry.uncompressedSize);\n if (length === 0) return new Uint8Array();\n if (entry.compressionMethod !== 0) {\n const content = await collectDecodedNodeStreamRange(\n await openNodeZipEntryStream(zipFile, entry),\n offset,\n length,\n );\n return new Uint8Array(\n content.buffer,\n content.byteOffset,\n content.byteLength,\n );\n }\n const content = await collectNodeStream(\n await openNodeZipEntryStream(zipFile, entry, {\n decompress: null,\n decrypt: null,\n end: offset + length,\n start: offset,\n }),\n );\n return new Uint8Array(content.buffer, content.byteOffset, content.byteLength);\n}\n\nasync function collectDecodedNodeStreamRange(\n input: NodeJS.ReadableStream,\n offset: number,\n length: number,\n): Promise<Buffer> {\n const chunks: Buffer[] = [];\n const end = offset + length;\n let position = 0;\n let collected = 0;\n for await (const value of input) {\n const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value);\n const chunkEnd = position + chunk.byteLength;\n if (chunkEnd > offset && position < end) {\n const selected = chunk.subarray(\n Math.max(0, offset - position),\n Math.min(chunk.byteLength, end - position),\n );\n chunks.push(selected);\n collected += selected.byteLength;\n }\n position = chunkEnd;\n if (position >= end) break;\n }\n if (collected !== length) {\n throw new Error(\"ZIP entry changed while reading its byte range\");\n }\n return Buffer.concat(chunks, collected);\n}\n\nasync function openNodeZipEntryStream(\n zipFile: yauzl.ZipFile,\n entry: yauzl.Entry,\n options?: yauzl.ZipFileOptions,\n): Promise<NodeJS.ReadableStream> {\n return await new Promise<NodeJS.ReadableStream>((resolve, reject) => {\n const callback = (error: Error | null, opened: Readable) => {\n if (error || opened === undefined) {\n reject(error ?? new Error(`Cannot read ZIP entry: ${entry.fileName}`));\n } else {\n resolve(opened);\n }\n };\n if (options === undefined) zipFile.openReadStream(entry, callback);\n else zipFile.openReadStream(entry, options, callback);\n });\n}\n\nasync function writeNodeZip(\n file: File,\n entries: Iterable<HostZipWriteEntry> | AsyncIterable<HostZipWriteEntry>,\n): Promise<void> {\n const zipFile = new yazl.ZipFile();\n const writer = await file.openWriter();\n const outputStream = zipFile.outputStream as Readable;\n const outputDone = writeNodeStream(outputStream, writer);\n const entryState = { cancelled: false, complete: false };\n let iterator:\n | Iterator<HostZipWriteEntry>\n | AsyncIterator<HostZipWriteEntry>\n | undefined;\n\n try {\n iterator = getNodeZipEntryIterator(entries);\n const entriesDone = addNodeZipEntries(zipFile, iterator, entryState);\n await Promise.race([entriesDone, outputDone]);\n if (!entryState.complete) {\n throw new Error(\"ZIP output ended before entry production completed\");\n }\n zipFile.end();\n await outputDone;\n await writer.commit();\n } catch (error) {\n entryState.cancelled = true;\n if (!entryState.complete && iterator !== undefined) {\n closeNodeZipEntryIterator(iterator);\n }\n if (!outputStream.destroyed) {\n outputStream.destroy(\n error instanceof Error ? error : new Error(\"Cannot write ZIP archive\"),\n );\n }\n await outputDone.catch(() => undefined);\n await writer.abort().catch(() => undefined);\n throw error;\n }\n}\n\nasync function addNodeZipEntries(\n zipFile: yazl.ZipFile,\n iterator: Iterator<HostZipWriteEntry> | AsyncIterator<HostZipWriteEntry>,\n state: { cancelled: boolean; complete: boolean },\n): Promise<void> {\n while (!state.cancelled) {\n const result = await iterator.next();\n if (state.cancelled) return;\n if (result.done) {\n state.complete = true;\n return;\n }\n if (\"file\" in result.value) {\n zipFile.addReadStream(\n createNodeFileReadStream(result.value.file),\n result.value.name,\n { compress: false },\n );\n } else if (\"data\" in result.value) {\n zipFile.addBuffer(Buffer.from(result.value.data), result.value.name, {\n compress: false,\n });\n } else {\n zipFile.addReadStream(\n createNodeRangeReadStream(result.value),\n result.value.name,\n { compress: false, size: result.value.size },\n );\n }\n }\n}\n\nfunction createNodeFileReadStream(file: ReadonlyFile): Readable {\n return Readable.from(\n (async function* () {\n const reader = await file.openReader();\n try {\n for (let offset = 0; offset < reader.size; ) {\n const chunk = await reader.read(\n offset,\n Math.min(64 * 1024, reader.size - offset),\n );\n offset += chunk.byteLength;\n yield chunk;\n }\n } finally {\n await reader.close();\n }\n })(),\n );\n}\n\nfunction getBrandedNodeResourcePath(\n resource: unknown,\n kind: \"directory\" | \"file\",\n): string | undefined {\n if (typeof resource !== \"object\" || resource === null) return undefined;\n const candidate = resource as {\n readonly [NODE_RESOURCE_KIND]?: unknown;\n readonly path?: unknown;\n };\n return candidate[NODE_RESOURCE_KIND] === kind &&\n typeof candidate.path === \"string\"\n ? candidate.path\n : undefined;\n}\n\nfunction createNodeRangeReadStream(\n entry: Extract<HostZipWriteEntry, { readonly size: number }>,\n): Readable {\n return Readable.from(\n (async function* () {\n for (let offset = 0; offset < entry.size; ) {\n const chunk = await entry.read(\n offset,\n Math.min(64 * 1024, entry.size - offset),\n );\n offset += chunk.byteLength;\n yield chunk;\n }\n })(),\n );\n}\n\nfunction getNodeZipEntryIterator(\n entries: Iterable<HostZipWriteEntry> | AsyncIterable<HostZipWriteEntry>,\n): Iterator<HostZipWriteEntry> | AsyncIterator<HostZipWriteEntry> {\n const asyncIterator = (entries as AsyncIterable<HostZipWriteEntry>)[\n Symbol.asyncIterator\n ];\n return asyncIterator === undefined\n ? (entries as Iterable<HostZipWriteEntry>)[Symbol.iterator]()\n : asyncIterator.call(entries);\n}\n\nfunction closeNodeZipEntryIterator(\n iterator: Iterator<HostZipWriteEntry> | AsyncIterator<HostZipWriteEntry>,\n): void {\n if (iterator.return === undefined) return;\n try {\n void Promise.resolve(iterator.return()).catch(() => undefined);\n } catch {\n // Preserve the failure that caused iteration to stop.\n }\n}\n\nasync function writeNodeStream(\n input: NodeJS.ReadableStream,\n writer: FileWriter,\n): Promise<void> {\n await pipeline(\n input,\n new Writable({\n write: (chunk: Buffer, _encoding, callback) => {\n void writer.write(chunk).then(\n () => callback(),\n (error: unknown) =>\n callback(\n error instanceof Error\n ? error\n : new Error(\"Cannot stream ZIP archive\"),\n ),\n );\n },\n }),\n );\n}\n\nasync function collectNodeStream(\n input: NodeJS.ReadableStream,\n): Promise<Buffer> {\n return await new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n input.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n input.once(\"error\", reject);\n input.once(\"end\", () => resolve(Buffer.concat(chunks)));\n });\n}\n\nexport const nodeWikiGraphPlatform: WikiGraphPlatform = {\n asyncContext: {\n create: <T>() => new asyncHooks.AsyncLocalStorage<T>(),\n },\n database: { open: openNodeDatabase },\n lifecycle: {\n instanceId: `node-process:${nodeProcess.pid}`,\n isInstanceAlive: (instanceId) => {\n const match = /^node-process:(\\d+)$/u.exec(instanceId);\n if (match === null) return Promise.resolve(undefined);\n try {\n nodeProcess.kill(Number(match[1]), 0);\n return Promise.resolve(true);\n } catch (error) {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"ESRCH\"\n ) {\n return Promise.resolve(false);\n }\n return Promise.resolve(true);\n }\n },\n },\n resources: {\n getDirectory: (identity) => {\n const path = decodeNodeResourceIdentity(identity, \"directory\");\n return Promise.resolve(\n path === undefined ? undefined : new NodeDirectory(path),\n );\n },\n getFile: (identity) => {\n const path = decodeNodeResourceIdentity(identity, \"file\");\n return Promise.resolve(\n path === undefined ? undefined : new NodeFile(path),\n );\n },\n resolveLegacyDirectory: (reference) => {\n const path = decodeNodeResourceIdentity(reference, \"directory\");\n return Promise.resolve(\n path === undefined ? undefined : new NodeDirectory(path),\n );\n },\n },\n templates: {\n createEnvironment: (options) =>\n new Environment(new NodeTemplateLoader(), options),\n },\n zip: {\n open: openNodeZip,\n write: writeNodeZip,\n },\n};\n\nclass NodeTemplateLoader extends Loader {\n readonly #dataDirectory: string | undefined;\n\n public constructor(dataDirectory?: string) {\n super();\n this.#dataDirectory = dataDirectory;\n }\n\n public getSource(templateName: string): LoaderSource {\n const name = normalizeTemplateName(templateName);\n const filePath = pathModule.join(\n this.#dataDirectory ?? resolveNodeDataDirectory(),\n name,\n );\n return {\n noCache: false,\n path: name,\n src: fs.readFileSync(filePath, \"utf8\"),\n };\n }\n}\n\nexport function createNodeTemplateEnvironment(\n dataDirectory: string,\n options: {\n readonly autoescape?: boolean;\n readonly trimBlocks?: boolean;\n } = {},\n): Environment {\n return new Environment(new NodeTemplateLoader(dataDirectory), {\n autoescape: options.autoescape ?? true,\n trimBlocks: options.trimBlocks ?? true,\n });\n}\n\nfunction resolveNodeDataDirectory(): string {\n const injected = (globalThis as { __WIKIGRAPH_DATA_DIR__?: unknown })\n .__WIKIGRAPH_DATA_DIR__;\n if (typeof injected === \"string\" && injected !== \"\") return injected;\n let directory = nodeProcess.cwd();\n while (true) {\n for (const candidate of [\n pathModule.join(directory, \"data\"),\n pathModule.join(directory, \"packages\", \"core\", \"data\"),\n ]) {\n try {\n if (fs.statSync(candidate).isDirectory()) return candidate;\n } catch {\n // Keep looking toward the filesystem root.\n }\n }\n const parent = pathModule.dirname(directory);\n if (parent === directory)\n throw new Error(\"Could not locate data directory\");\n directory = parent;\n }\n}\n\nexport function createNodeWikiGraphStorage(\n stateRoot = pathModule.join(os.homedir(), \".wikigraph\"),\n): WikiGraphStorage {\n return {\n library: new NodeDirectory(stateRoot),\n documentStore: new NodeDirectory(pathModule.join(stateRoot, \"documents\")),\n };\n}\n\nexport function installNodeWikiGraphPlatform(stateRoot?: string): void {\n installWikiGraphPlatform(nodeWikiGraphPlatform);\n installWikiGraphStorage(createNodeWikiGraphStorage(stateRoot));\n}\n\nexport function ensureNodeWikiGraphPlatform(): void {\n installWikiGraphPlatform(nodeWikiGraphPlatform);\n try {\n getWikiGraphStorage();\n } catch {\n installWikiGraphStorage(createNodeWikiGraphStorage());\n }\n}\n\nexport async function withNodeWikiGraphStorage<T>(\n stateRoot: string | undefined,\n operation: () => Promise<T> | T,\n): Promise<T> {\n return await withWikiGraphStorage(\n stateRoot === undefined ? undefined : createNodeWikiGraphStorage(stateRoot),\n operation,\n );\n}\n"],"mappings":";;;;;AAAA,SAAS,+BAA+B;;;ACAxC,SAAS,yBAAyB;AAYlC,IAAM,sBAAsB,uBAAO,IAAI,mCAAmC;AAC1E,IAAM,iBAAiB,yBAAyB;AAEhD,SAAS,2BAA0E;AACjF,QAAM,gBAAgB;AACtB,QAAM,WAAW,cAAc,mBAAmB;AAClD,MAAI,aAAa,QAAW;AAC1B,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,IAAI,kBAA8C;AAClE,SAAO,eAAe,eAAe,qBAAqB;AAAA,IACxD,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,UAAU;AAAA,EACZ,CAAC;AACD,SAAO;AACT;AASO,SAAS,gCAA4D;AAC1E,SACE,eAAe,SAAS,KAAK;AAAA,IAC3B,KAAK,QAAQ,IAAI;AAAA,IACjB,KAAK,QAAQ;AAAA,IACb,WAAW;AAAA,EACb;AAEJ;AAEO,SAAS,0BAA8C;AAC5D,SAAO,8BAA8B,EAAE;AACzC;;;AClDA,YAAY,gBAAgB;AAC5B,YAAY,YAAY;AACxB,YAAY,QAAQ;AACpB,YAAY,gBAAgB;AAC5B,YAAY,QAAQ;AACpB,YAAY,gBAAgB;AAC5B,YAAYA,cAAa;AACzB,SAAS,UAAU,gBAAgB;AACnC,SAAS,gBAAgB;AACzB,YAAY,aAAa;AACzB,YAAY,WAAW;AACvB,YAAY,UAAU;AACtB,SAAS,aAAa,cAAiC;AAOvD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAcA;AAAA,OACK;AAxBP,IAAM,cACiD,oBAAWA;AAClE,IAAM,cACiD,mBAAW;AAwBlE,IAAM,qBAAqB,uBAAO,IAAI,iCAAiC;AAGhE,IAAM,WAAN,MAA+B;AAAA,EAM7B,YACW,MAChB,OAAkB,oBAAS,IAAI,GAC/B;AAFgB;AAGhB,SAAK,WAAW,2BAA2B,QAAQ,IAAI;AACvD,SAAK,OAAO;AAAA,EACd;AAAA,EALkB;AAAA,EANF,OAAO;AAAA,EACvB,CAAiB,kBAAkB,IAAI;AAAA,EACvB;AAAA,EACA;AAAA,EAUhB,MAAa,aAAkC;AAC7C,UAAM,SAAS,MAAiB,gBAAK,KAAK,MAAM,GAAG;AACnD,QAAI,SAAS;AACb,QAAI;AACF,YAAM,QAAQ,MAAM,OAAO,KAAK;AAChC,UAAI,CAAC,MAAM,OAAO;AAChB,cAAM,IAAI,MAAM,qCAAqC;AACvD,YAAM,EAAE,KAAK,IAAI;AACjB,aAAO;AAAA,QACL;AAAA,QACA,OAAO,YAAY;AACjB,cAAI,CAAC,OAAQ,OAAM,OAAO,MAAM;AAChC,mBAAS;AAAA,QACX;AAAA,QACA,MAAM,OAAO,QAAQ,WAAW;AAC9B,cAAI,OAAQ,OAAM,IAAI,MAAM,sCAAsC;AAClE,0BAAgB,QAAQ,QAAQ,IAAI;AACpC,gBAAM,SAAS,OAAO,YAAY,MAAM;AACxC,cAAI,YAAY;AAChB,iBAAO,YAAY,QAAQ;AACzB,kBAAM,SAAS,MAAM,OAAO;AAAA,cAC1B;AAAA,cACA;AAAA,cACA,SAAS;AAAA,cACT,SAAS;AAAA,YACX;AACA,gBAAI,OAAO,cAAc,GAAG;AAC1B,oBAAM,IAAI,MAAM,2CAA2C;AAAA,YAC7D;AACA,yBAAa,OAAO;AAAA,UACtB;AACA,iBAAO,IAAI,WAAW,OAAO,QAAQ,OAAO,YAAY,SAAS;AAAA,QACnE;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,OAAO,MAAM;AACnB,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAa,kBAA+C;AAC1D,QAAI;AACF,cAAQ,MAAiB,gBAAK,KAAK,IAAI,GAAG;AAAA,IAC5C,SAAS,OAAO;AACd,UACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,UACf;AACA,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAa,aAAkC;AAC7C,UAAiB,iBAAiB,mBAAQ,KAAK,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACzE,UAAM,YAAY,GAAG,KAAK,IAAI,QAAe,kBAAW,CAAC;AACzD,UAAM,SAAS,MAAiB,gBAAK,WAAW,IAAI;AACpD,QAAI,SAAS;AACb,WAAO;AAAA,MACL,OAAO,OAAO,SAAS;AACrB,YAAI,OAAQ,OAAM,IAAI,MAAM,qCAAqC;AACjE,cAAM,oBAAoB,QAAQ,IAAI;AAAA,MACxC;AAAA,MACA,SAAS,OAAO,QAAQ,SAAS;AAC/B,YAAI,OAAQ,OAAM,IAAI,MAAM,qCAAqC;AACjE,yBAAiB,MAAM;AACvB,cAAM,oBAAoB,QAAQ,MAAM,MAAM;AAAA,MAChD;AAAA,MACA,QAAQ,YAAY;AAClB,YAAI,CAAC,QAAQ;AACX,gBAAM,OAAO,MAAM;AACnB,gBAAiB,kBAAO,WAAW,KAAK,IAAI;AAAA,QAC9C;AACA,iBAAS;AAAA,MACX;AAAA,MACA,OAAO,YAAY;AACjB,YAAI,CAAC,QAAQ;AACX,gBAAM,OAAO,MAAM;AACnB,gBAAiB,cAAG,WAAW,EAAE,OAAO,KAAK,CAAC;AAAA,QAChD;AACA,iBAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;AAGA,eAAsB,oBACpB,QACA,MACA,UACe;AACf,QAAM,SAAS,OAAO,KAAK,IAAI;AAC/B,MAAI,UAAU;AACd,SAAO,UAAU,OAAO,YAAY;AAClC,UAAM,SAAS,MAAM,OAAO;AAAA,MAC1B;AAAA,MACA;AAAA,MACA,OAAO,aAAa;AAAA,MACpB,aAAa,SAAY,OAAO,WAAW;AAAA,IAC7C;AACA,QAAI,OAAO,iBAAiB,GAAG;AAC7B,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AACA,eAAW,OAAO;AAAA,EACpB;AACF;AAEA,SAAS,gBAAgB,QAAgB,QAAgB,MAAoB;AAC3E,mBAAiB,MAAM;AACvB,MAAI,CAAC,OAAO,cAAc,MAAM,KAAK,SAAS,GAAG;AAC/C,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,MAAI,SAAS,QAAQ,SAAS,OAAO,QAAQ;AAC3C,UAAM,IAAI,WAAW,uCAAuC;AAAA,EAC9D;AACF;AAEA,SAAS,iBAAiB,QAAsB;AAC9C,MAAI,CAAC,OAAO,cAAc,MAAM,KAAK,SAAS,GAAG;AAC/C,UAAM,IAAI,WAAW,iDAAiD;AAAA,EACxE;AACF;AAEO,IAAM,gBAAN,MAAM,eAAmC;AAAA,EAMvC,YAA4B,MAAc;AAAd;AACjC,SAAK,WAAW,2BAA2B,aAAa,IAAI;AAC5D,SAAK,OAAkB,oBAAS,IAAI;AAAA,EACtC;AAAA,EAHmC;AAAA,EALnB,OAAO;AAAA,EACvB,CAAiB,kBAAkB,IAAI;AAAA,EACvB;AAAA,EACA;AAAA,EAOhB,MAAa,QAAQ,MAAyC;AAC5D,oBAAgB,IAAI;AACpB,UAAM,OAAO,IAAI,SAAoB,gBAAK,KAAK,MAAM,IAAI,CAAC;AAC1D,QAAI;AACF,cAAQ,MAAiB,gBAAK,KAAK,IAAI,GAAG,OAAO,IAAI,OAAO;AAAA,IAC9D,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAa,kBAA+C;AAC1D,QAAI;AACF,cAAQ,MAAiB,gBAAK,KAAK,IAAI,GAAG;AAAA,IAC5C,SAAS,OAAO;AACd,UACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,UACf;AACA,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAa,aAAa,MAA8C;AACtE,oBAAgB,IAAI;AACpB,UAAM,YAAY,IAAI,eAAyB,gBAAK,KAAK,MAAM,IAAI,CAAC;AACpE,QAAI;AACF,cAAQ,MAAiB,gBAAK,UAAU,IAAI,GAAG,YAAY,IACvD,YACA;AAAA,IACN,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAa,OAAiD;AAC5D,UAAM,UAAU,MAAiB,mBAAQ,KAAK,MAAM;AAAA,MAClD,eAAe;AAAA,IACjB,CAAC;AACD,WAAO,QAAQ;AAAA,MAAI,CAAC,UAClB,MAAM,YAAY,IACd,IAAI,eAAyB,gBAAK,KAAK,MAAM,MAAM,IAAI,CAAC,IACxD,IAAI,SAAoB,gBAAK,KAAK,MAAM,MAAM,IAAI,GAAG,MAAM,IAAI;AAAA,IACrE;AAAA,EACF;AAAA,EAEA,MAAa,WAAW,MAA6B;AACnD,oBAAgB,IAAI;AACpB,UAAiB,iBAAM,KAAK,MAAM,EAAE,WAAW,KAAK,CAAC;AACrD,UAAM,OAAO,IAAI,SAAoB,gBAAK,KAAK,MAAM,IAAI,CAAC;AAC1D,UAAiB,qBAAU,KAAK,MAAM,IAAI,EAAE,MAAM,KAAK,CAAC;AACxD,WAAO;AAAA,EACT;AAAA,EAEA,MAAa,gBAAgB,MAAkC;AAC7D,oBAAgB,IAAI;AACpB,UAAiB,iBAAM,KAAK,MAAM,EAAE,WAAW,KAAK,CAAC;AACrD,UAAM,YAAY,IAAI,eAAyB,gBAAK,KAAK,MAAM,IAAI,CAAC;AACpE,UAAiB,iBAAM,UAAU,IAAI;AACrC,WAAO;AAAA,EACT;AAAA,EAEA,MAAa,OACX,MACA,SACe;AACf,oBAAgB,IAAI;AACpB,UAAiB,cAAc,gBAAK,KAAK,MAAM,IAAI,GAAG;AAAA,MACpD,OAAO;AAAA,MACP,WAAW,SAAS,cAAc;AAAA,IACpC,CAAC;AAAA,EACH;AACF;AAEA,SAAS,2BACP,MACA,MACQ;AACR,SAAO,QAAQ,IAAI,IAAI,OAAO,KAAgB,mBAAQ,IAAI,GAAG,MAAM,EAAE,SAAS,WAAW,CAAC;AAC5F;AAEA,SAAS,2BACP,UACA,MACoB;AACpB,QAAM,SAAS,QAAQ,IAAI;AAC3B,MAAI,CAAC,SAAS,WAAW,MAAM,GAAG;AAEhC,WAAkB,sBAAW,QAAQ,IAAI,WAAW;AAAA,EACtD;AACA,MAAI;AACF,WAAO,OAAO,KAAK,SAAS,MAAM,OAAO,MAAM,GAAG,WAAW,EAAE;AAAA,MAC7D;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAgBA,SAAS,gBAAgB,MAAoB;AAC3C,MACE,KAAK,WAAW,KAChB,SAAS,OACT,SAAS,QACE,sBAAW,IAAI,KAC1B,KAAK,SAAS,GAAG,KACjB,KAAK,SAAS,IAAI,GAClB;AACA,UAAM,IAAI,UAAU,4CAA4C,IAAI,EAAE;AAAA,EACxE;AACF;AAEA,IAAM,yBAAN,MAA+D;AAAA,EACtD,YAA6B,UAA4B;AAA5B;AAAA,EAA6B;AAAA,EAA7B;AAAA,EAEpC,MAAa,QAAuB;AAClC,UAAM,IAAI,QAAc,CAACC,UAAS,WAAW;AAC3C,WAAK,SAAS,MAAM,CAAC,UAAU;AAC7B,YAAI,MAAO,QAAO,KAAK;AAAA,YAClB,CAAAA,SAAQ;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,QAAQ,KAA4B;AAC/C,UAAM,IAAI,QAAc,CAACA,UAAS,WAAW;AAC3C,WAAK,SAAS,KAAK,KAAK,CAAC,UAAU;AACjC,YAAI,MAAO,QAAO,KAAK;AAAA,YAClB,CAAAA,SAAQ;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,SACX,KACA,SAAuC,CAAC,GACH;AACrC,WAAO,MAAM,IAAI,QAAQ,CAACA,UAAS,WAAW;AAC5C,WAAK,SAAS,IAAI,KAAK,CAAC,GAAG,MAAM,GAAG,CAAC,OAAO,SAA4B;AACtE,YAAI,MAAO,QAAO,KAAK;AAAA,YAClB,CAAAA,SAAQ,IAAI;AAAA,MACnB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,SACX,KACA,SAAuC,CAAC,GACF;AACtC,WAAO,MAAM,IAAI,QAAQ,CAACA,UAAS,WAAW;AAC5C,WAAK,SAAS,IAAI,KAAK,CAAC,GAAG,MAAM,GAAG,CAAC,OAAO,QAAyB;AACnE,YAAI,MAAO,QAAO,KAAK;AAAA,YAClB,CAAAA,SAAQ,GAAG;AAAA,MAClB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,IACX,KACA,SAAuC,CAAC,GACzB;AACf,UAAM,IAAI,QAAc,CAACA,UAAS,WAAW;AAC3C,WAAK,SAAS,IAAI,KAAK,CAAC,GAAG,MAAM,GAAG,CAAC,UAAU;AAC7C,YAAI,MAAO,QAAO,KAAK;AAAA,YAClB,CAAAA,SAAQ;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;AAEA,eAAe,iBACb,MACA,SACiC;AACjC,QAAM,SACH,QAAQ,SAAS,aACd,YAAY,gBACZ,YAAY,kBACX,QAAQ,SAAS,YAAY,cAAc,MAChD,YAAY;AACd,SAAO,IAAI,uBAAuB,MAAM,uBAAuB,MAAM,KAAK,CAAC;AAC7E;AAEA,eAAe,uBACb,MACA,OAC2B;AAC3B,QAAM,OAAO,2BAA2B,MAAM,MAAM;AACpD,MAAI,SAAS,QAAW;AACtB,UAAM,IAAI,UAAU,+CAA+C;AAAA,EACrE;AACA,SAAO,MAAM,IAAI,QAAQ,CAACA,UAAS,WAAW;AAC5C,UAAM,WAAW,IAAI,YAAY,SAAS,MAAM,OAAO,CAAC,UAAU;AAChE,UAAI,MAAO,QAAO,KAAK;AAAA,UAClB,CAAAA,SAAQ,QAAQ;AAAA,IACvB,CAAC;AAAA,EACH,CAAC;AACH;AAEA,eAAe,YAAY,MAA4C;AACrE,QAAM,OAAO,2BAA2B,MAAM,MAAM;AACpD,MAAI,SAAS,QAAW;AACtB,UAAM,IAAI,UAAU,0CAA0C;AAAA,EAChE;AACA,QAAM,UAAU,MAAM,IAAI,QAAuB,CAACA,UAAS,WAAW;AACpE,IAAM;AAAA,MACJ;AAAA,MACA,EAAE,WAAW,OAAO,aAAa,KAAK;AAAA,MACtC,CAAC,OAAO,WAAW;AACjB,YAAI,SAAS,WAAW;AACtB,iBAAO,SAAS,IAAI,MAAM,iBAAiB,CAAC;AAAA,YACzC,CAAAA,SAAQ,MAAM;AAAA,MACrB;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,UAAU,MAAM,IAAI;AAAA,IACxB,CAACA,UAAS,WAAW;AACnB,YAAM,aAAa,oBAAI,IAAyB;AAChD,YAAM,iBAAiB,CAAC,UAAmB;AACzC,gBAAQ,MAAM;AACd;AAAA,UACE,iBAAiB,QACb,QACA,IAAI,MAAM,mCAAmC;AAAA,QACnD;AAAA,MACF;AACA,YAAM,iBAAiB,MAAM;AAC3B,gBAAQ,IAAI,SAAS,cAAc;AACnC,QAAAA,SAAQ,UAAU;AAAA,MACpB;AACA,cAAQ,GAAG,SAAS,CAAC,UAAuB;AAC1C,YAAI,CAAC,MAAM,SAAS,SAAS,GAAG,GAAG;AACjC,qBAAW,IAAI,MAAM,UAAU,KAAK;AAAA,QACtC;AACA,gBAAQ,UAAU;AAAA,MACpB,CAAC;AACD,cAAQ,KAAK,SAAS,cAAc;AACpC,cAAQ,KAAK,OAAO,cAAc;AAClC,cAAQ,UAAU;AAAA,IACpB;AAAA,EACF;AAEA,MAAI,SAAS;AACb,SAAO;AAAA,IACL,OAAO,MAAM;AACX,UAAI,CAAC,OAAQ,SAAQ,MAAM;AAC3B,eAAS;AACT,aAAO,QAAQ,QAAQ;AAAA,IACzB;AAAA,IACA,WAAW,OAAO,MAAM,WAAW;AACjC,UAAI,OAAQ,OAAM,IAAI,MAAM,kCAAkC;AAC9D,YAAM,QAAQ,QAAQ,IAAI,IAAI;AAC9B,UAAI,UAAU,OAAW,QAAO;AAChC,YAAM,iBAAiB,SAAS,OAAO,MAAM;AAC7C,aAAO;AAAA,IACT;AAAA,IACA,cAAc,CAAC,SAAS;AACtB,UAAI,OAAQ,OAAM,IAAI,MAAM,kCAAkC;AAC9D,aAAO,QAAQ,QAAQ,QAAQ,IAAI,IAAI,GAAG,gBAAgB;AAAA,IAC5D;AAAA,IACA,aAAa,MAAM,QAAQ,QAAQ,CAAC,GAAG,QAAQ,KAAK,CAAC,CAAC;AAAA,IACtD,gBAAgB,OAAO,MAAM,QAAQ,WAAW;AAC9C,UAAI,OAAQ,OAAM,IAAI,MAAM,kCAAkC;AAC9D,YAAM,QAAQ,QAAQ,IAAI,IAAI;AAC9B,UAAI,UAAU,OAAW,QAAO;AAChC,aAAO,MAAM,sBAAsB,SAAS,OAAO,QAAQ,MAAM;AAAA,IACnE;AAAA,IACA,WAAW,OAAO,SAAS;AACzB,UAAI,OAAQ,OAAM,IAAI,MAAM,kCAAkC;AAC9D,YAAM,QAAQ,QAAQ,IAAI,IAAI;AAC9B,UAAI,UAAU,OAAW,QAAO;AAChC,aAAO,MAAM,iBAAiB,SAAS,KAAK;AAAA,IAC9C;AAAA,EACF;AACF;AAEA,eAAe,iBACb,SACA,OACA,QACe;AACf,QAAM,SAAS,MAAM,OAAO,WAAW;AACvC,MAAI;AACF,UAAM,SAAS,MAAM,uBAAuB,SAAS,KAAK;AAC1D,UAAM,gBAAgB,QAAQ,MAAM;AACpC,UAAM,OAAO,OAAO;AAAA,EACtB,SAAS,OAAO;AACd,UAAM,OAAO,MAAM,EAAE,MAAM,MAAM,MAAS;AAC1C,UAAM;AAAA,EACR;AACF;AAEA,eAAe,iBACb,SACA,OACqB;AACrB,SAAO,MAAM,kBAAkB,MAAM,uBAAuB,SAAS,KAAK,CAAC;AAC7E;AAEA,eAAe,sBACb,SACA,OACA,QACA,QACqB;AACrB,kBAAgB,QAAQ,QAAQ,MAAM,gBAAgB;AACtD,MAAI,WAAW,EAAG,QAAO,IAAI,WAAW;AACxC,MAAI,MAAM,sBAAsB,GAAG;AACjC,UAAMC,WAAU,MAAM;AAAA,MACpB,MAAM,uBAAuB,SAAS,KAAK;AAAA,MAC3C;AAAA,MACA;AAAA,IACF;AACA,WAAO,IAAI;AAAA,MACTA,SAAQ;AAAA,MACRA,SAAQ;AAAA,MACRA,SAAQ;AAAA,IACV;AAAA,EACF;AACA,QAAM,UAAU,MAAM;AAAA,IACpB,MAAM,uBAAuB,SAAS,OAAO;AAAA,MAC3C,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,KAAK,SAAS;AAAA,MACd,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,SAAO,IAAI,WAAW,QAAQ,QAAQ,QAAQ,YAAY,QAAQ,UAAU;AAC9E;AAEA,eAAe,8BACb,OACA,QACA,QACiB;AACjB,QAAM,SAAmB,CAAC;AAC1B,QAAM,MAAM,SAAS;AACrB,MAAI,WAAW;AACf,MAAI,YAAY;AAChB,mBAAiB,SAAS,OAAO;AAC/B,UAAM,QAAQ,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK,KAAK;AAChE,UAAM,WAAW,WAAW,MAAM;AAClC,QAAI,WAAW,UAAU,WAAW,KAAK;AACvC,YAAM,WAAW,MAAM;AAAA,QACrB,KAAK,IAAI,GAAG,SAAS,QAAQ;AAAA,QAC7B,KAAK,IAAI,MAAM,YAAY,MAAM,QAAQ;AAAA,MAC3C;AACA,aAAO,KAAK,QAAQ;AACpB,mBAAa,SAAS;AAAA,IACxB;AACA,eAAW;AACX,QAAI,YAAY,IAAK;AAAA,EACvB;AACA,MAAI,cAAc,QAAQ;AACxB,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AACA,SAAO,OAAO,OAAO,QAAQ,SAAS;AACxC;AAEA,eAAe,uBACb,SACA,OACA,SACgC;AAChC,SAAO,MAAM,IAAI,QAA+B,CAACD,UAAS,WAAW;AACnE,UAAM,WAAW,CAAC,OAAqB,WAAqB;AAC1D,UAAI,SAAS,WAAW,QAAW;AACjC,eAAO,SAAS,IAAI,MAAM,0BAA0B,MAAM,QAAQ,EAAE,CAAC;AAAA,MACvE,OAAO;AACL,QAAAA,SAAQ,MAAM;AAAA,MAChB;AAAA,IACF;AACA,QAAI,YAAY,OAAW,SAAQ,eAAe,OAAO,QAAQ;AAAA,QAC5D,SAAQ,eAAe,OAAO,SAAS,QAAQ;AAAA,EACtD,CAAC;AACH;AAEA,eAAe,aACb,MACA,SACe;AACf,QAAM,UAAU,IAAS,aAAQ;AACjC,QAAM,SAAS,MAAM,KAAK,WAAW;AACrC,QAAM,eAAe,QAAQ;AAC7B,QAAM,aAAa,gBAAgB,cAAc,MAAM;AACvD,QAAM,aAAa,EAAE,WAAW,OAAO,UAAU,MAAM;AACvD,MAAI;AAKJ,MAAI;AACF,eAAW,wBAAwB,OAAO;AAC1C,UAAM,cAAc,kBAAkB,SAAS,UAAU,UAAU;AACnE,UAAM,QAAQ,KAAK,CAAC,aAAa,UAAU,CAAC;AAC5C,QAAI,CAAC,WAAW,UAAU;AACxB,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AACA,YAAQ,IAAI;AACZ,UAAM;AACN,UAAM,OAAO,OAAO;AAAA,EACtB,SAAS,OAAO;AACd,eAAW,YAAY;AACvB,QAAI,CAAC,WAAW,YAAY,aAAa,QAAW;AAClD,gCAA0B,QAAQ;AAAA,IACpC;AACA,QAAI,CAAC,aAAa,WAAW;AAC3B,mBAAa;AAAA,QACX,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,0BAA0B;AAAA,MACvE;AAAA,IACF;AACA,UAAM,WAAW,MAAM,MAAM,MAAS;AACtC,UAAM,OAAO,MAAM,EAAE,MAAM,MAAM,MAAS;AAC1C,UAAM;AAAA,EACR;AACF;AAEA,eAAe,kBACb,SACA,UACA,OACe;AACf,SAAO,CAAC,MAAM,WAAW;AACvB,UAAM,SAAS,MAAM,SAAS,KAAK;AACnC,QAAI,MAAM,UAAW;AACrB,QAAI,OAAO,MAAM;AACf,YAAM,WAAW;AACjB;AAAA,IACF;AACA,QAAI,UAAU,OAAO,OAAO;AAC1B,cAAQ;AAAA,QACN,yBAAyB,OAAO,MAAM,IAAI;AAAA,QAC1C,OAAO,MAAM;AAAA,QACb,EAAE,UAAU,MAAM;AAAA,MACpB;AAAA,IACF,WAAW,UAAU,OAAO,OAAO;AACjC,cAAQ,UAAU,OAAO,KAAK,OAAO,MAAM,IAAI,GAAG,OAAO,MAAM,MAAM;AAAA,QACnE,UAAU;AAAA,MACZ,CAAC;AAAA,IACH,OAAO;AACL,cAAQ;AAAA,QACN,0BAA0B,OAAO,KAAK;AAAA,QACtC,OAAO,MAAM;AAAA,QACb,EAAE,UAAU,OAAO,MAAM,OAAO,MAAM,KAAK;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,yBAAyB,MAA8B;AAC9D,SAAO,SAAS;AAAA,KACb,mBAAmB;AAClB,YAAM,SAAS,MAAM,KAAK,WAAW;AACrC,UAAI;AACF,iBAAS,SAAS,GAAG,SAAS,OAAO,QAAQ;AAC3C,gBAAM,QAAQ,MAAM,OAAO;AAAA,YACzB;AAAA,YACA,KAAK,IAAI,KAAK,MAAM,OAAO,OAAO,MAAM;AAAA,UAC1C;AACA,oBAAU,MAAM;AAChB,gBAAM;AAAA,QACR;AAAA,MACF,UAAE;AACA,cAAM,OAAO,MAAM;AAAA,MACrB;AAAA,IACF,GAAG;AAAA,EACL;AACF;AAEA,SAAS,2BACP,UACA,MACoB;AACpB,MAAI,OAAO,aAAa,YAAY,aAAa,KAAM,QAAO;AAC9D,QAAM,YAAY;AAIlB,SAAO,UAAU,kBAAkB,MAAM,QACvC,OAAO,UAAU,SAAS,WACxB,UAAU,OACV;AACN;AAEA,SAAS,0BACP,OACU;AACV,SAAO,SAAS;AAAA,KACb,mBAAmB;AAClB,eAAS,SAAS,GAAG,SAAS,MAAM,QAAQ;AAC1C,cAAM,QAAQ,MAAM,MAAM;AAAA,UACxB;AAAA,UACA,KAAK,IAAI,KAAK,MAAM,MAAM,OAAO,MAAM;AAAA,QACzC;AACA,kBAAU,MAAM;AAChB,cAAM;AAAA,MACR;AAAA,IACF,GAAG;AAAA,EACL;AACF;AAEA,SAAS,wBACP,SACgE;AAChE,QAAM,gBAAiB,QACrB,OAAO,aACT;AACA,SAAO,kBAAkB,SACpB,QAAwC,OAAO,QAAQ,EAAE,IAC1D,cAAc,KAAK,OAAO;AAChC;AAEA,SAAS,0BACP,UACM;AACN,MAAI,SAAS,WAAW,OAAW;AACnC,MAAI;AACF,SAAK,QAAQ,QAAQ,SAAS,OAAO,CAAC,EAAE,MAAM,MAAM,MAAS;AAAA,EAC/D,QAAQ;AAAA,EAER;AACF;AAEA,eAAe,gBACb,OACA,QACe;AACf,QAAM;AAAA,IACJ;AAAA,IACA,IAAI,SAAS;AAAA,MACX,OAAO,CAAC,OAAe,WAAW,aAAa;AAC7C,aAAK,OAAO,MAAM,KAAK,EAAE;AAAA,UACvB,MAAM,SAAS;AAAA,UACf,CAAC,UACC;AAAA,YACE,iBAAiB,QACb,QACA,IAAI,MAAM,2BAA2B;AAAA,UAC3C;AAAA,QACJ;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,eAAe,kBACb,OACiB;AACjB,SAAO,MAAM,IAAI,QAAQ,CAACA,UAAS,WAAW;AAC5C,UAAM,SAAmB,CAAC;AAC1B,UAAM,GAAG,QAAQ,CAAC,UAAkB,OAAO,KAAK,KAAK,CAAC;AACtD,UAAM,KAAK,SAAS,MAAM;AAC1B,UAAM,KAAK,OAAO,MAAMA,SAAQ,OAAO,OAAO,MAAM,CAAC,CAAC;AAAA,EACxD,CAAC;AACH;AAEO,IAAM,wBAA2C;AAAA,EACtD,cAAc;AAAA,IACZ,QAAQ,MAAS,IAAe,6BAAqB;AAAA,EACvD;AAAA,EACA,UAAU,EAAE,MAAM,iBAAiB;AAAA,EACnC,WAAW;AAAA,IACT,YAAY,gBAAgB,YAAY,GAAG;AAAA,IAC3C,iBAAiB,CAAC,eAAe;AAC/B,YAAM,QAAQ,wBAAwB,KAAK,UAAU;AACrD,UAAI,UAAU,KAAM,QAAO,QAAQ,QAAQ,MAAS;AACpD,UAAI;AACF,oBAAY,KAAK,OAAO,MAAM,CAAC,CAAC,GAAG,CAAC;AACpC,eAAO,QAAQ,QAAQ,IAAI;AAAA,MAC7B,SAAS,OAAO;AACd,YACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,SACf;AACA,iBAAO,QAAQ,QAAQ,KAAK;AAAA,QAC9B;AACA,eAAO,QAAQ,QAAQ,IAAI;AAAA,MAC7B;AAAA,IACF;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT,cAAc,CAAC,aAAa;AAC1B,YAAM,OAAO,2BAA2B,UAAU,WAAW;AAC7D,aAAO,QAAQ;AAAA,QACb,SAAS,SAAY,SAAY,IAAI,cAAc,IAAI;AAAA,MACzD;AAAA,IACF;AAAA,IACA,SAAS,CAAC,aAAa;AACrB,YAAM,OAAO,2BAA2B,UAAU,MAAM;AACxD,aAAO,QAAQ;AAAA,QACb,SAAS,SAAY,SAAY,IAAI,SAAS,IAAI;AAAA,MACpD;AAAA,IACF;AAAA,IACA,wBAAwB,CAAC,cAAc;AACrC,YAAM,OAAO,2BAA2B,WAAW,WAAW;AAC9D,aAAO,QAAQ;AAAA,QACb,SAAS,SAAY,SAAY,IAAI,cAAc,IAAI;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT,mBAAmB,CAAC,YAClB,IAAI,YAAY,IAAI,mBAAmB,GAAG,OAAO;AAAA,EACrD;AAAA,EACA,KAAK;AAAA,IACH,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AACF;AAEA,IAAM,qBAAN,cAAiC,OAAO;AAAA,EAC7B;AAAA,EAEF,YAAY,eAAwB;AACzC,UAAM;AACN,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEO,UAAU,cAAoC;AACnD,UAAM,OAAO,sBAAsB,YAAY;AAC/C,UAAM,WAAsB;AAAA,MAC1B,KAAK,kBAAkB,yBAAyB;AAAA,MAChD;AAAA,IACF;AACA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,MAAM;AAAA,MACN,KAAQ,gBAAa,UAAU,MAAM;AAAA,IACvC;AAAA,EACF;AACF;AAeA,SAAS,2BAAmC;AAC1C,QAAM,WAAY,WACf;AACH,MAAI,OAAO,aAAa,YAAY,aAAa,GAAI,QAAO;AAC5D,MAAI,YAAY,YAAY,IAAI;AAChC,SAAO,MAAM;AACX,eAAW,aAAa;AAAA,MACX,gBAAK,WAAW,MAAM;AAAA,MACtB,gBAAK,WAAW,YAAY,QAAQ,MAAM;AAAA,IACvD,GAAG;AACD,UAAI;AACF,YAAO,YAAS,SAAS,EAAE,YAAY,EAAG,QAAO;AAAA,MACnD,QAAQ;AAAA,MAER;AAAA,IACF;AACA,UAAM,SAAoB,mBAAQ,SAAS;AAC3C,QAAI,WAAW;AACb,YAAM,IAAI,MAAM,iCAAiC;AACnD,gBAAY;AAAA,EACd;AACF;;;AFl3BA,SAAS,QAAAE,aAAY;AACrB,SAAS,WAAAC,gBAAe;AAGjB,IAAM,wBAAwB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMA,IAAM,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQhC,eAAsB,uBACpB,SAC4B;AAC5B,SAAO,MAAM,wBAAwB,OAAO,aAAa;AACvD,WAAO,MAAM,iCAAiC,UAAU,OAAO;AAAA,EACjE,CAAC;AACH;AAEA,eAAsB,0BACpB,SACA,OAC4B;AAC5B,QAAM,aAAa,2BAA2B,SAAS,KAAK;AAE5D,SAAO,MAAM,wBAAwB,OAAO,aAAa;AACvD,UAAM,kCAAkC,UAAU,SAAS,UAAU;AACrE,WAAO;AAAA,EACT,CAAC;AACH;AAEA,eAAsB,oBACpB,SACA,KACA,OAC4B;AAC5B,SAAO,MAAM,wBAAwB,OAAO,aAAa;AACvD,UAAM,UAAU,MAAM,iCAAiC,UAAU,OAAO;AACxE,UAAM,OAAO,2BAA2B,SAAS;AAAA,MAC/C,GAAG;AAAA,MACH,CAAC,wBAAwB,SAAS,GAAG,CAAC,GAAG;AAAA,IAC3C,CAAC;AAED,UAAM,kCAAkC,UAAU,SAAS,IAAI;AAC/D,WAAO;AAAA,EACT,CAAC;AACH;AAEA,eAAsB,uBACpB,SACA,KAC4B;AAC5B,SAAO,MAAM,wBAAwB,OAAO,aAAa;AACvD,UAAM,UAAU,MAAM,iCAAiC,UAAU,OAAO;AACxE,UAAM,gBAAgB,wBAAwB,SAAS,GAAG;AAC1D,UAAM,EAAE,CAAC,aAAa,GAAG,UAAU,GAAG,UAAU,IAAI;AACpD,UAAM,OAAO,2BAA2B,SAAS,SAAS;AAE1D,UAAM,kCAAkC,UAAU,SAAS,IAAI;AAC/D,WAAO;AAAA,EACT,CAAC;AACH;AAEA,eAAsB,wBACpB,SAC4B;AAC5B,SAAO,MAAM,0BAA0B,SAAS,CAAC,CAAC;AACpD;AAEO,SAAS,wBACd,OACgC;AAChC,MAAI,UAAU,aAAa;AACzB,WAAO;AAAA,EACT;AAEA,SAAO,sBAAsB,KAAK,CAAC,YAAY,YAAY,KAAK;AAClE;AAEO,SAAS,uBACd,SACA,OACmB;AACnB,MACG,YAAY,SACX,YAAY,gBACZ,YAAY,eACZ,YAAY,eACb,MAAM,WAAW,UAAa,MAAM,UAAU,QAC/C;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAI,MAAM,WAAW,SAAY,CAAC,IAAI,EAAE,QAAQ,OAAO;AAAA,IACvD,GAAI,MAAM,UAAU,SAAY,CAAC,IAAI,EAAE,OAAO,OAAO;AAAA,EACvD;AACF;AAEO,SAAS,wBACd,SACA,KACQ;AACR,QAAM,aAAa,IAAI,KAAK;AAE5B,MAAI,eAAe,IAAI;AACrB,UAAM,IAAI,MAAM,6BAA6B;AAAA,EAC/C;AAEA,MAAI,YAAY,SAAS,YAAY,cAAc;AACjD,YAAQ,YAAY;AAAA,MAClB,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO;AAAA,IACX;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,2BACd,SACA,OACmB;AACnB,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO,yBAAyB,KAAK;AAAA,IACvC,KAAK;AACH,aAAO,kBAAkB,KAAK;AAAA,IAChC,KAAK;AACH,aAAO,yBAAyB,KAAK;AAAA,IACvC,KAAK;AACH,aAAO,wBAAwB,KAAK;AAAA,IACtC,KAAK;AACH,aAAO,wBAAwB,KAAK;AAAA,EACxC;AACF;AAEA,eAAe,wBACb,WACY;AACZ,QAAM,WAAW,MAAM;AAAA,IACrB,IAAI;AAAA,MACFD;AAAA,QACE,wBAAwB,KAAKA,MAAKC,SAAQ,GAAG,YAAY;AAAA,QACzD;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,EACF;AAEA,MAAI;AACF,WAAO,MAAM,UAAU,QAAQ;AAAA,EACjC,UAAE;AACA,UAAM,SAAS,MAAM;AAAA,EACvB;AACF;AAEA,eAAe,iCACb,UACA,SAC4B;AAC5B,QAAM,QAAQ,MAAM,SAAS;AAAA,IAC3B;AAAA,IACA,CAAC,OAAO;AAAA,IACR,CAAC,QAAQ,OAAO,IAAI,UAAU;AAAA,EAChC;AAEA,SAAO,UAAU,SAAY,CAAC,IAAI,iBAAiB,SAAS,KAAK;AACnE;AAEA,eAAe,kCACb,UACA,SACA,OACe;AACf,QAAM,SAAS;AAAA,IACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,CAAC,SAAS,KAAK,UAAU,KAAK,GAAG,KAAK,IAAI,CAAC;AAAA,EAC7C;AACF;AAEA,SAAS,iBACP,SACA,OACmB;AACnB,MAAI;AAEJ,MAAI;AACF,aAAS,KAAK,MAAM,KAAK;AAAA,EAC3B,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,iCAAiC,OAAO,KAAK,YAAY,KAAK,CAAC;AAAA,IACjE;AAAA,EACF;AAEA,MAAI,WAAW,QAAQ,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,GAAG;AAC1E,UAAM,IAAI;AAAA,MACR,gCAAgC,OAAO;AAAA,IACzC;AAAA,EACF;AAEA,SAAO,2BAA2B,SAAS,MAA2B;AACxE;AAEA,SAAS,yBAAyB,OAA6C;AAC7E,QAAM,cAAc,oBAAI,IAAI;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,mBAAmB,oBAAI,IAAI,CAAC,UAAU,mBAAmB,CAAC;AAChE,QAAM,OAAgC,CAAC;AAEvC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,CAAC,YAAY,IAAI,GAAG,GAAG;AACzB,YAAM,IAAI,MAAM,kCAAkC,GAAG,EAAE;AAAA,IACzD;AACA,QAAI,QAAQ,cAAc;AACxB,YAAM,SACJ,OAAO,UAAU,WACb,QACA,OAAO,UAAU,WACf,OAAO,KAAK,IACZ;AAER,UAAI,CAAC,OAAO,UAAU,MAAM,KAAK,UAAU,GAAG;AAC5C,cAAM,IAAI,MAAM,mDAAmD;AAAA,MACrE;AACA,WAAK,GAAG,IAAI;AACZ;AAAA,IACF;AACA,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,YAAM,IAAI,MAAM,cAAc,GAAG,8BAA8B;AAAA,IACjE;AACA,UAAM,aAAa,MAAM,KAAK;AAE9B,QAAI,QAAQ,cAAc,CAAC,iBAAiB,IAAI,UAAU,GAAG;AAC3D,YAAM,IAAI,MAAM,gCAAgC,UAAU,EAAE;AAAA,IAC9D;AAEA,SAAK,GAAG,IAAI;AAAA,EACd;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,OAA6C;AACtE,QAAM,cAAc,oBAAI,IAAI;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,mBAAmB,oBAAI,IAAI;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,OAAgC,CAAC;AAEvC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,CAAC,YAAY,IAAI,GAAG,GAAG;AACzB,YAAM,IAAI,MAAM,2BAA2B,GAAG,EAAE;AAAA,IAClD;AACA,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,YAAM,IAAI,MAAM,OAAO,GAAG,8BAA8B;AAAA,IAC1D;AACA,UAAM,aAAa,MAAM,KAAK;AAE9B,QAAI,QAAQ,cAAc,CAAC,iBAAiB,IAAI,UAAU,GAAG;AAC3D,YAAM,IAAI,MAAM,yBAAyB,UAAU,EAAE;AAAA,IACvD;AAEA,SAAK,GAAG,IAAI;AAAA,EACd;AAEA,SAAO;AACT;AAEA,SAAS,yBAAyB,OAA6C;AAC7E,QAAM,cAAc,oBAAI,IAAI,CAAC,OAAO,SAAS,CAAC;AAC9C,QAAM,OAAgC,CAAC;AAEvC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,CAAC,YAAY,IAAI,GAAG,GAAG;AACzB,YAAM,IAAI,MAAM,kCAAkC,GAAG,EAAE;AAAA,IACzD;AACA,UAAM,SACJ,OAAO,UAAU,WACb,QACA,OAAO,UAAU,WACf,OAAO,KAAK,IACZ;AAER,QAAI,CAAC,OAAO,UAAU,MAAM,KAAK,UAAU,GAAG;AAC5C,YAAM,IAAI,MAAM,cAAc,GAAG,8BAA8B;AAAA,IACjE;AACA,SAAK,GAAG,IAAI;AAAA,EACd;AAEA,SAAO;AACT;AAEA,SAAS,wBAAwB,OAA6C;AAC5E,QAAM,cAAc,oBAAI,IAAI,CAAC,YAAY,YAAY,OAAO,CAAC;AAC7D,QAAM,mBAAmB,oBAAI,IAAI,CAAC,OAAO,OAAO,CAAC;AACjD,QAAM,OAAgC,CAAC;AAEvC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,CAAC,YAAY,IAAI,GAAG,GAAG;AACzB,YAAM,IAAI,MAAM,iCAAiC,GAAG,EAAE;AAAA,IACxD;AACA,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,YAAM,IAAI,MAAM,aAAa,GAAG,8BAA8B;AAAA,IAChE;AACA,UAAM,aAAa,MAAM,KAAK;AAE9B,QAAI,QAAQ,cAAc,CAAC,iBAAiB,IAAI,UAAU,GAAG;AAC3D,YAAM,IAAI,MAAM,+BAA+B,UAAU,EAAE;AAAA,IAC7D;AAEA,SAAK,GAAG,IAAI;AAAA,EACd;AAEA,SAAO;AACT;AAEA,SAAS,wBAAwB,OAA6C;AAC5E,SAAO,uBAAuB,aAAa,KAAK;AAClD;AAEA,SAAS,uBACP,SACA,OACmB;AACnB,QAAM,cAAc,oBAAI,IAAI,CAAC,YAAY,OAAO,CAAC;AACjD,QAAM,OAAgC,CAAC;AAEvC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,CAAC,YAAY,IAAI,GAAG,GAAG;AACzB,YAAM,IAAI,MAAM,WAAW,OAAO,gBAAgB,GAAG,EAAE;AAAA,IACzD;AACA,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,YAAM,IAAI,MAAM,GAAG,OAAO,IAAI,GAAG,8BAA8B;AAAA,IACjE;AACA,SAAK,GAAG,IAAI,MAAM,KAAK;AAAA,EACzB;AAEA,SAAO;AACT;AAEA,SAAS,YAAY,OAAwB;AAC3C,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;","names":["process","resolve","content","join","homedir"]}
|
|
1
|
+
{"version":3,"sources":["../src/local-config.ts","../src/runtime-context.ts","../src/node-platform.ts"],"sourcesContent":["import { openSharedStateDatabase } from \"wiki-graph-core\";\nimport { getWikiGraphSDKStateDir } from \"./runtime-context.js\";\nimport { NodeFile } from \"./node-platform.js\";\nimport { join } from \"path\";\nimport { homedir } from \"os\";\nimport type { Database } from \"wiki-graph-core\";\n\nexport const LOCAL_CONFIG_SECTIONS = [\n \"concurrent\",\n \"embeddings\",\n \"llm\",\n \"wikimedia\",\n \"wikispine\",\n] as const;\n\nexport type LocalConfigSection = (typeof LOCAL_CONFIG_SECTIONS)[number];\n\nexport type LocalConfigObject = Readonly<Record<string, unknown>>;\n\nconst LOCAL_CONFIG_SCHEMA_SQL = `\nCREATE TABLE IF NOT EXISTS config_sections (\n section TEXT PRIMARY KEY,\n value_json TEXT NOT NULL,\n updated_at INTEGER NOT NULL\n);\n`;\n\nexport async function readLocalConfigSection(\n section: LocalConfigSection,\n): Promise<LocalConfigObject> {\n return await withLocalConfigDatabase(async (database) => {\n return await readLocalConfigSectionInDatabase(database, section);\n });\n}\n\nexport async function replaceLocalConfigSection(\n section: LocalConfigSection,\n value: LocalConfigObject,\n): Promise<LocalConfigObject> {\n const normalized = validateLocalConfigSection(section, value);\n\n return await withLocalConfigDatabase(async (database) => {\n await writeLocalConfigSectionInDatabase(database, section, normalized);\n return normalized;\n });\n}\n\nexport async function putLocalConfigValue(\n section: LocalConfigSection,\n key: string,\n value: unknown,\n): Promise<LocalConfigObject> {\n return await withLocalConfigDatabase(async (database) => {\n const current = await readLocalConfigSectionInDatabase(database, section);\n const next = validateLocalConfigSection(section, {\n ...current,\n [normalizeLocalConfigKey(section, key)]: value,\n });\n\n await writeLocalConfigSectionInDatabase(database, section, next);\n return next;\n });\n}\n\nexport async function deleteLocalConfigValue(\n section: LocalConfigSection,\n key: string,\n): Promise<LocalConfigObject> {\n return await withLocalConfigDatabase(async (database) => {\n const current = await readLocalConfigSectionInDatabase(database, section);\n const normalizedKey = normalizeLocalConfigKey(section, key);\n const { [normalizedKey]: _removed, ...nextInput } = current;\n const next = validateLocalConfigSection(section, nextInput);\n\n await writeLocalConfigSectionInDatabase(database, section, next);\n return next;\n });\n}\n\nexport async function clearLocalConfigSection(\n section: LocalConfigSection,\n): Promise<LocalConfigObject> {\n return await replaceLocalConfigSection(section, {});\n}\n\nexport function parseLocalConfigSection(\n value: string | undefined,\n): LocalConfigSection | undefined {\n if (value === \"embedding\") {\n return \"embeddings\";\n }\n\n return LOCAL_CONFIG_SECTIONS.find((section) => section === value);\n}\n\nexport function maskLocalConfigSection(\n section: LocalConfigSection,\n value: LocalConfigObject,\n): LocalConfigObject {\n if (\n (section !== \"llm\" &&\n section !== \"embeddings\" &&\n section !== \"wikimedia\" &&\n section !== \"wikispine\") ||\n (value.apiKey === undefined && value.token === undefined)\n ) {\n return value;\n }\n\n return {\n ...value,\n ...(value.apiKey === undefined ? {} : { apiKey: \"****\" }),\n ...(value.token === undefined ? {} : { token: \"****\" }),\n };\n}\n\nexport function normalizeLocalConfigKey(\n section: LocalConfigSection,\n key: string,\n): string {\n const normalized = key.trim();\n\n if (normalized === \"\") {\n throw new Error(\"Config key cannot be empty.\");\n }\n\n if (section === \"llm\" || section === \"embeddings\") {\n switch (normalized) {\n case \"api-key\":\n return \"apiKey\";\n case \"base-url\":\n return \"baseURL\";\n default:\n return normalized;\n }\n }\n return normalized;\n}\n\nexport function validateLocalConfigSection(\n section: LocalConfigSection,\n value: LocalConfigObject,\n): LocalConfigObject {\n switch (section) {\n case \"embeddings\":\n return validateEmbeddingsConfig(value);\n case \"llm\":\n return validateLLMConfig(value);\n case \"concurrent\":\n return validateConcurrentConfig(value);\n case \"wikimedia\":\n return validateWikimediaConfig(value);\n case \"wikispine\":\n return validateWikispineConfig(value);\n }\n}\n\nasync function withLocalConfigDatabase<T>(\n operation: (database: Database) => Promise<T>,\n): Promise<T> {\n const database = await openSharedStateDatabase(\n new NodeFile(\n join(\n getWikiGraphSDKStateDir() ?? join(homedir(), \".wikigraph\"),\n \"core.sqlite\",\n ),\n ),\n LOCAL_CONFIG_SCHEMA_SQL,\n );\n\n try {\n return await operation(database);\n } finally {\n await database.close();\n }\n}\n\nasync function readLocalConfigSectionInDatabase(\n database: Database,\n section: LocalConfigSection,\n): Promise<LocalConfigObject> {\n const value = await database.queryOne(\n \"SELECT value_json FROM config_sections WHERE section = ?\",\n [section],\n (row) => String(row.value_json),\n );\n\n return value === undefined ? {} : parseSectionJSON(section, value);\n}\n\nasync function writeLocalConfigSectionInDatabase(\n database: Database,\n section: LocalConfigSection,\n value: LocalConfigObject,\n): Promise<void> {\n await database.run(\n `\nINSERT INTO config_sections (section, value_json, updated_at)\nVALUES (?, ?, ?)\nON CONFLICT(section) DO UPDATE SET\n value_json = excluded.value_json,\n updated_at = excluded.updated_at\n`,\n [section, JSON.stringify(value), Date.now()],\n );\n}\n\nfunction parseSectionJSON(\n section: LocalConfigSection,\n value: string,\n): LocalConfigObject {\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(value);\n } catch (error) {\n throw new Error(\n `Invalid local config JSON for ${section}: ${formatError(error)}`,\n );\n }\n\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\n `Invalid local config section ${section}: expected object.`,\n );\n }\n\n return validateLocalConfigSection(section, parsed as LocalConfigObject);\n}\n\nfunction validateEmbeddingsConfig(value: LocalConfigObject): LocalConfigObject {\n const allowedKeys = new Set([\n \"apiKey\",\n \"baseURL\",\n \"dimensions\",\n \"model\",\n \"name\",\n \"provider\",\n ]);\n const allowedProviders = new Set([\"openai\", \"openai-compatible\"]);\n const next: Record<string, unknown> = {};\n\n for (const [key, entry] of Object.entries(value)) {\n if (!allowedKeys.has(key)) {\n throw new Error(`Unknown embeddings config key: ${key}`);\n }\n if (key === \"dimensions\") {\n const parsed =\n typeof entry === \"number\"\n ? entry\n : typeof entry === \"string\"\n ? Number(entry)\n : NaN;\n\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new Error(\"embeddings.dimensions must be a positive integer.\");\n }\n next[key] = parsed;\n continue;\n }\n if (typeof entry !== \"string\" || entry.trim() === \"\") {\n throw new Error(`embeddings.${key} must be a non-empty string.`);\n }\n const normalized = entry.trim();\n\n if (key === \"provider\" && !allowedProviders.has(normalized)) {\n throw new Error(`Unknown embeddings.provider: ${normalized}`);\n }\n\n next[key] = normalized;\n }\n\n return next;\n}\n\nfunction validateLLMConfig(value: LocalConfigObject): LocalConfigObject {\n const allowedKeys = new Set([\n \"apiKey\",\n \"baseURL\",\n \"model\",\n \"name\",\n \"provider\",\n ]);\n const allowedProviders = new Set([\n \"anthropic\",\n \"google\",\n \"openai\",\n \"openai-compatible\",\n ]);\n const next: Record<string, unknown> = {};\n\n for (const [key, entry] of Object.entries(value)) {\n if (!allowedKeys.has(key)) {\n throw new Error(`Unknown llm config key: ${key}`);\n }\n if (typeof entry !== \"string\" || entry.trim() === \"\") {\n throw new Error(`llm.${key} must be a non-empty string.`);\n }\n const normalized = entry.trim();\n\n if (key === \"provider\" && !allowedProviders.has(normalized)) {\n throw new Error(`Unknown llm.provider: ${normalized}`);\n }\n\n next[key] = normalized;\n }\n\n return next;\n}\n\nfunction validateConcurrentConfig(value: LocalConfigObject): LocalConfigObject {\n const allowedKeys = new Set([\"job\", \"request\"]);\n const next: Record<string, unknown> = {};\n\n for (const [key, entry] of Object.entries(value)) {\n if (!allowedKeys.has(key)) {\n throw new Error(`Unknown concurrent config key: ${key}`);\n }\n const parsed =\n typeof entry === \"number\"\n ? entry\n : typeof entry === \"string\"\n ? Number(entry)\n : NaN;\n\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new Error(`concurrent.${key} must be a positive integer.`);\n }\n next[key] = parsed;\n }\n\n return next;\n}\n\nfunction validateWikispineConfig(value: LocalConfigObject): LocalConfigObject {\n const allowedKeys = new Set([\"endpoint\", \"provider\", \"token\"]);\n const allowedProviders = new Set([\"cli\", \"fetch\"]);\n const next: Record<string, unknown> = {};\n\n for (const [key, entry] of Object.entries(value)) {\n if (!allowedKeys.has(key)) {\n throw new Error(`Unknown wikispine config key: ${key}`);\n }\n if (typeof entry !== \"string\" || entry.trim() === \"\") {\n throw new Error(`wikispine.${key} must be a non-empty string.`);\n }\n const normalized = entry.trim();\n\n if (key === \"provider\" && !allowedProviders.has(normalized)) {\n throw new Error(`Unknown wikispine.provider: ${normalized}`);\n }\n\n next[key] = normalized;\n }\n\n return next;\n}\n\nfunction validateWikimediaConfig(value: LocalConfigObject): LocalConfigObject {\n return validateEndpointConfig(\"wikimedia\", value);\n}\n\nfunction validateEndpointConfig(\n section: \"wikimedia\",\n value: LocalConfigObject,\n): LocalConfigObject {\n const allowedKeys = new Set([\"endpoint\", \"token\"]);\n const next: Record<string, unknown> = {};\n\n for (const [key, entry] of Object.entries(value)) {\n if (!allowedKeys.has(key)) {\n throw new Error(`Unknown ${section} config key: ${key}`);\n }\n if (typeof entry !== \"string\" || entry.trim() === \"\") {\n throw new Error(`${section}.${key} must be a non-empty string.`);\n }\n next[key] = entry.trim();\n }\n\n return next;\n}\n\nfunction formatError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import { AsyncLocalStorage } from \"async_hooks\";\n\nimport type { WikiGraphSDKProviders } from \"./providers.js\";\n\nexport type WikiGraphSDKEnvPolicy = \"development\" | \"production\";\n\nexport interface WikiGraphSDKRuntimeContext {\n readonly cwd: string;\n readonly env: NodeJS.ProcessEnv;\n readonly envPolicy: WikiGraphSDKEnvPolicy;\n readonly providers?: WikiGraphSDKProviders;\n readonly stateDir?: string | undefined;\n}\n\n/** Shared by independently bundled SDK entry points in the same process. */\nconst RUNTIME_CONTEXT_KEY = Symbol.for(\"wiki-graph-sdk.runtime-context.v1\");\nconst runtimeContext = getRuntimeContextStorage();\n\nfunction getRuntimeContextStorage(): AsyncLocalStorage<WikiGraphSDKRuntimeContext> {\n const runtimeGlobal = globalThis as unknown as Record<PropertyKey, unknown>;\n const existing = runtimeGlobal[RUNTIME_CONTEXT_KEY];\n if (existing !== undefined) {\n return existing as AsyncLocalStorage<WikiGraphSDKRuntimeContext>;\n }\n\n const storage = new AsyncLocalStorage<WikiGraphSDKRuntimeContext>();\n Object.defineProperty(runtimeGlobal, RUNTIME_CONTEXT_KEY, {\n configurable: false,\n enumerable: false,\n value: storage,\n writable: false,\n });\n return storage;\n}\n\nexport async function withWikiGraphSDKRuntimeContext<T>(\n context: WikiGraphSDKRuntimeContext,\n operation: () => Promise<T> | T,\n): Promise<T> {\n return await runtimeContext.run(context, operation);\n}\n\nexport function getWikiGraphSDKRuntimeContext(): WikiGraphSDKRuntimeContext {\n return (\n runtimeContext.getStore() ?? {\n cwd: process.cwd(),\n env: process.env,\n envPolicy: \"production\",\n providers: {},\n }\n );\n}\n\nexport function getWikiGraphSDKStateDir(): string | undefined {\n return getWikiGraphSDKRuntimeContext().stateDir;\n}\n\nexport function getWikiGraphSDKProviders(): WikiGraphSDKProviders {\n return getWikiGraphSDKRuntimeContext().providers ?? {};\n}\n","/* eslint-disable no-restricted-syntax, @typescript-eslint/parameter-properties */\nimport * as asyncHooks from \"node:async_hooks\";\nimport * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport * as fsPromises from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport * as pathModule from \"node:path\";\nimport * as process from \"node:process\";\nimport { Readable, Writable } from \"node:stream\";\nimport { pipeline } from \"node:stream/promises\";\nimport * as sqlite3 from \"sqlite3\";\nimport * as yauzl from \"yauzl\";\nimport * as yazl from \"yazl\";\nimport { Environment, Loader, type LoaderSource } from \"nunjucks\";\n\nconst nodeProcess =\n (process as unknown as { default?: typeof process }).default ?? process;\nconst nodeSqlite3 =\n (sqlite3 as unknown as { default?: typeof sqlite3 }).default ?? sqlite3;\n\nimport {\n getWikiGraphStorage,\n installWikiGraphPlatform,\n installWikiGraphStorage,\n withWikiGraphStorage,\n type Directory,\n type File,\n type FileReader,\n type ReadonlyFile,\n type FileWriter,\n type HostDatabaseConnection,\n type HostDatabaseOpenOptions,\n type HostDatabaseRow,\n type HostDatabaseValue,\n type HostZipWriteEntry,\n type HostZipReader,\n type WikiGraphPlatform,\n type WikiGraphStorage,\n normalizeTemplateName,\n} from \"wiki-graph-core/platform\";\n\n/** Stable across independently bundled SDK entry points. */\nconst NODE_RESOURCE_KIND = Symbol.for(\"wiki-graph-sdk.node-resource.v1\");\n\n/** Install the Node implementation used by the CLI and its workers. */\nexport class NodeFile implements File {\n public readonly kind = \"file\" as const;\n public readonly [NODE_RESOURCE_KIND] = \"file\" as const;\n public readonly identity: string;\n public readonly name: string;\n\n public constructor(\n public readonly path: string,\n name = pathModule.basename(path),\n ) {\n this.identity = encodeNodeResourceIdentity(\"file\", path);\n this.name = name;\n }\n\n public async openReader(): Promise<FileReader> {\n const handle = await fsPromises.open(this.path, \"r\");\n let closed = false;\n try {\n const stats = await handle.stat();\n if (!stats.isFile())\n throw new Error(\"File reader requires a regular file\");\n const { size } = stats;\n return {\n size,\n close: async () => {\n if (!closed) await handle.close();\n closed = true;\n },\n read: async (offset, length) => {\n if (closed) throw new Error(\"Cannot read from a closed FileReader\");\n assertFileRange(offset, length, size);\n const buffer = Buffer.allocUnsafe(length);\n let bytesRead = 0;\n while (bytesRead < length) {\n const result = await handle.read(\n buffer,\n bytesRead,\n length - bytesRead,\n offset + bytesRead,\n );\n if (result.bytesRead === 0) {\n throw new Error(\"File changed while reading its byte range\");\n }\n bytesRead += result.bytesRead;\n }\n return new Uint8Array(buffer.buffer, buffer.byteOffset, bytesRead);\n },\n };\n } catch (error) {\n await handle.close();\n throw error;\n }\n }\n\n public async getLastModified(): Promise<number | undefined> {\n try {\n return (await fsPromises.stat(this.path)).mtimeMs;\n } catch (error) {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return undefined;\n }\n throw error;\n }\n }\n\n public async openWriter(): Promise<FileWriter> {\n await fsPromises.mkdir(pathModule.dirname(this.path), { recursive: true });\n const temporary = `${this.path}.tmp-${crypto.randomUUID()}`;\n const handle = await fsPromises.open(temporary, \"wx\");\n let closed = false;\n return {\n write: async (data) => {\n if (closed) throw new Error(\"Cannot write to a closed FileWriter\");\n await writeNodeFileHandle(handle, data);\n },\n writeAt: async (offset, data) => {\n if (closed) throw new Error(\"Cannot write to a closed FileWriter\");\n assertFileOffset(offset);\n await writeNodeFileHandle(handle, data, offset);\n },\n commit: async () => {\n if (!closed) {\n await handle.close();\n await fsPromises.rename(temporary, this.path);\n }\n closed = true;\n },\n abort: async () => {\n if (!closed) {\n await handle.close();\n await fsPromises.rm(temporary, { force: true });\n }\n closed = true;\n },\n };\n }\n}\n\n/** @internal Completes writes even when the Node file handle reports a short write. */\nexport async function writeNodeFileHandle(\n handle: Pick<fsPromises.FileHandle, \"write\">,\n data: Uint8Array | string,\n position?: number,\n): Promise<void> {\n const buffer = Buffer.from(data);\n let written = 0;\n while (written < buffer.byteLength) {\n const result = await handle.write(\n buffer,\n written,\n buffer.byteLength - written,\n position === undefined ? null : position + written,\n );\n if (result.bytesWritten === 0) {\n throw new Error(\"File writer made no progress\");\n }\n written += result.bytesWritten;\n }\n}\n\nfunction assertFileRange(offset: number, length: number, size: number): void {\n assertFileOffset(offset);\n if (!Number.isSafeInteger(length) || length < 0) {\n throw new RangeError(\n \"File read length must be a non-negative safe integer\",\n );\n }\n if (offset > size || length > size - offset) {\n throw new RangeError(\"File read range exceeds the file size\");\n }\n}\n\nfunction assertFileOffset(offset: number): void {\n if (!Number.isSafeInteger(offset) || offset < 0) {\n throw new RangeError(\"File offset must be a non-negative safe integer\");\n }\n}\n\nexport class NodeDirectory implements Directory {\n public readonly kind = \"directory\" as const;\n public readonly [NODE_RESOURCE_KIND] = \"directory\" as const;\n public readonly identity: string;\n public readonly name: string;\n\n public constructor(public readonly path: string) {\n this.identity = encodeNodeResourceIdentity(\"directory\", path);\n this.name = pathModule.basename(path);\n }\n\n public async getFile(name: string): Promise<File | undefined> {\n assertChildName(name);\n const file = new NodeFile(pathModule.join(this.path, name));\n try {\n return (await fsPromises.stat(file.path)).isFile() ? file : undefined;\n } catch {\n return undefined;\n }\n }\n\n public async getLastModified(): Promise<number | undefined> {\n try {\n return (await fsPromises.stat(this.path)).mtimeMs;\n } catch (error) {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return undefined;\n }\n throw error;\n }\n }\n\n public async getDirectory(name: string): Promise<Directory | undefined> {\n assertChildName(name);\n const directory = new NodeDirectory(pathModule.join(this.path, name));\n try {\n return (await fsPromises.stat(directory.path)).isDirectory()\n ? directory\n : undefined;\n } catch {\n return undefined;\n }\n }\n\n public async list(): Promise<ReadonlyArray<File | Directory>> {\n const entries = await fsPromises.readdir(this.path, {\n withFileTypes: true,\n });\n return entries.map((entry) =>\n entry.isDirectory()\n ? new NodeDirectory(pathModule.join(this.path, entry.name))\n : new NodeFile(pathModule.join(this.path, entry.name), entry.name),\n );\n }\n\n public async createFile(name: string): Promise<File> {\n assertChildName(name);\n await fsPromises.mkdir(this.path, { recursive: true });\n const file = new NodeFile(pathModule.join(this.path, name));\n await fsPromises.writeFile(file.path, \"\", { flag: \"wx\" });\n return file;\n }\n\n public async createDirectory(name: string): Promise<Directory> {\n assertChildName(name);\n await fsPromises.mkdir(this.path, { recursive: true });\n const directory = new NodeDirectory(pathModule.join(this.path, name));\n await fsPromises.mkdir(directory.path);\n return directory;\n }\n\n public async remove(\n name: string,\n options?: { readonly recursive?: boolean },\n ): Promise<void> {\n assertChildName(name);\n await fsPromises.rm(pathModule.join(this.path, name), {\n force: true,\n recursive: options?.recursive === true,\n });\n }\n}\n\nfunction encodeNodeResourceIdentity(\n kind: \"directory\" | \"file\",\n path: string,\n): string {\n return `node-${kind}:${Buffer.from(pathModule.resolve(path), \"utf8\").toString(\"base64url\")}`;\n}\n\nfunction decodeNodeResourceIdentity(\n identity: string,\n kind: \"directory\" | \"file\",\n): string | undefined {\n const prefix = `node-${kind}:`;\n if (!identity.startsWith(prefix)) {\n // State created before opaque resource identities stored native paths.\n return pathModule.isAbsolute(identity) ? identity : undefined;\n }\n try {\n return Buffer.from(identity.slice(prefix.length), \"base64url\").toString(\n \"utf8\",\n );\n } catch {\n return undefined;\n }\n}\n\nexport function getNodeResourcePath(resource: File | Directory): string {\n const brandedPath = getBrandedNodeResourcePath(resource, resource.kind);\n if (brandedPath !== undefined) return brandedPath;\n if (\n typeof resource === \"object\" &&\n resource !== null &&\n \"path\" in resource &&\n typeof resource.path === \"string\"\n ) {\n return resource.path;\n }\n throw new TypeError(\"Expected a Node File or Directory resource\");\n}\n\nfunction assertChildName(name: string): void {\n if (\n name.length === 0 ||\n name === \".\" ||\n name === \"..\" ||\n pathModule.isAbsolute(name) ||\n name.includes(\"/\") ||\n name.includes(\"\\\\\")\n ) {\n throw new TypeError(`Directory child must be a relative name: ${name}`);\n }\n}\n\nclass NodeDatabaseConnection implements HostDatabaseConnection {\n public constructor(private readonly database: sqlite3.Database) {}\n\n public async close(): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n this.database.close((error) => {\n if (error) reject(error);\n else resolve();\n });\n });\n }\n\n public async execute(sql: string): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n this.database.exec(sql, (error) => {\n if (error) reject(error);\n else resolve();\n });\n });\n }\n\n public async queryAll(\n sql: string,\n params: readonly HostDatabaseValue[] = [],\n ): Promise<readonly HostDatabaseRow[]> {\n return await new Promise((resolve, reject) => {\n this.database.all(sql, [...params], (error, rows: HostDatabaseRow[]) => {\n if (error) reject(error);\n else resolve(rows);\n });\n });\n }\n\n public async queryOne(\n sql: string,\n params: readonly HostDatabaseValue[] = [],\n ): Promise<HostDatabaseRow | undefined> {\n return await new Promise((resolve, reject) => {\n this.database.get(sql, [...params], (error, row: HostDatabaseRow) => {\n if (error) reject(error);\n else resolve(row);\n });\n });\n }\n\n public async run(\n sql: string,\n params: readonly HostDatabaseValue[] = [],\n ): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n this.database.run(sql, [...params], (error) => {\n if (error) reject(error);\n else resolve();\n });\n });\n }\n}\n\nasync function openNodeDatabase(\n file: ReadonlyFile,\n options: HostDatabaseOpenOptions,\n): Promise<NodeDatabaseConnection> {\n const flags =\n (options.mode === \"readonly\"\n ? nodeSqlite3.OPEN_READONLY\n : nodeSqlite3.OPEN_READWRITE |\n (options.create ? nodeSqlite3.OPEN_CREATE : 0)) |\n nodeSqlite3.OPEN_FULLMUTEX;\n return new NodeDatabaseConnection(await openNativeNodeDatabase(file, flags));\n}\n\nasync function openNativeNodeDatabase(\n file: ReadonlyFile,\n flags: number,\n): Promise<sqlite3.Database> {\n const path = getBrandedNodeResourcePath(file, \"file\");\n if (path === undefined) {\n throw new TypeError(\"The Node database adapter requires a NodeFile\");\n }\n return await new Promise((resolve, reject) => {\n const database = new nodeSqlite3.Database(path, flags, (error) => {\n if (error) reject(error);\n else resolve(database);\n });\n });\n}\n\nasync function openNodeZip(file: ReadonlyFile): Promise<HostZipReader> {\n const path = getBrandedNodeResourcePath(file, \"file\");\n if (path === undefined) {\n throw new TypeError(\"The Node ZIP adapter requires a NodeFile\");\n }\n const zipFile = await new Promise<yauzl.ZipFile>((resolve, reject) => {\n yauzl.open(\n path,\n { autoClose: false, lazyEntries: true },\n (error, opened) => {\n if (error || opened === undefined)\n reject(error ?? new Error(\"Cannot open ZIP\"));\n else resolve(opened);\n },\n );\n });\n\n const entries = await new Promise<Map<string, yauzl.Entry>>(\n (resolve, reject) => {\n const discovered = new Map<string, yauzl.Entry>();\n const rejectAndClose = (error: unknown) => {\n zipFile.close();\n reject(\n error instanceof Error\n ? error\n : new Error(\"Cannot scan ZIP central directory\"),\n );\n };\n const resolveEntries = () => {\n zipFile.off(\"error\", rejectAndClose);\n resolve(discovered);\n };\n zipFile.on(\"entry\", (entry: yauzl.Entry) => {\n if (!entry.fileName.endsWith(\"/\")) {\n discovered.set(entry.fileName, entry);\n }\n zipFile.readEntry();\n });\n zipFile.once(\"error\", rejectAndClose);\n zipFile.once(\"end\", resolveEntries);\n zipFile.readEntry();\n },\n );\n\n let closed = false;\n return {\n close: () => {\n if (!closed) zipFile.close();\n closed = true;\n return Promise.resolve();\n },\n copyEntry: async (name, target) => {\n if (closed) throw new Error(\"Cannot read a closed ZIP archive\");\n const entry = entries.get(name);\n if (entry === undefined) return false;\n await copyNodeZipEntry(zipFile, entry, target);\n return true;\n },\n getEntrySize: (name) => {\n if (closed) throw new Error(\"Cannot read a closed ZIP archive\");\n return Promise.resolve(entries.get(name)?.uncompressedSize);\n },\n listEntries: () => Promise.resolve([...entries.keys()]),\n readEntryRange: async (name, offset, length) => {\n if (closed) throw new Error(\"Cannot read a closed ZIP archive\");\n const entry = entries.get(name);\n if (entry === undefined) return undefined;\n return await readNodeZipEntryRange(zipFile, entry, offset, length);\n },\n readEntry: async (name) => {\n if (closed) throw new Error(\"Cannot read a closed ZIP archive\");\n const entry = entries.get(name);\n if (entry === undefined) return undefined;\n return await readNodeZipEntry(zipFile, entry);\n },\n };\n}\n\nasync function copyNodeZipEntry(\n zipFile: yauzl.ZipFile,\n entry: yauzl.Entry,\n target: File,\n): Promise<void> {\n const writer = await target.openWriter();\n try {\n const stream = await openNodeZipEntryStream(zipFile, entry);\n await writeNodeStream(stream, writer);\n await writer.commit();\n } catch (error) {\n await writer.abort().catch(() => undefined);\n throw error;\n }\n}\n\nasync function readNodeZipEntry(\n zipFile: yauzl.ZipFile,\n entry: yauzl.Entry,\n): Promise<Uint8Array> {\n return await collectNodeStream(await openNodeZipEntryStream(zipFile, entry));\n}\n\nasync function readNodeZipEntryRange(\n zipFile: yauzl.ZipFile,\n entry: yauzl.Entry,\n offset: number,\n length: number,\n): Promise<Uint8Array> {\n assertFileRange(offset, length, entry.uncompressedSize);\n if (length === 0) return new Uint8Array();\n if (entry.compressionMethod !== 0) {\n const content = await collectDecodedNodeStreamRange(\n await openNodeZipEntryStream(zipFile, entry),\n offset,\n length,\n );\n return new Uint8Array(\n content.buffer,\n content.byteOffset,\n content.byteLength,\n );\n }\n const content = await collectNodeStream(\n await openNodeZipEntryStream(zipFile, entry, {\n decompress: null,\n decrypt: null,\n end: offset + length,\n start: offset,\n }),\n );\n return new Uint8Array(content.buffer, content.byteOffset, content.byteLength);\n}\n\nasync function collectDecodedNodeStreamRange(\n input: NodeJS.ReadableStream,\n offset: number,\n length: number,\n): Promise<Buffer> {\n const chunks: Buffer[] = [];\n const end = offset + length;\n let position = 0;\n let collected = 0;\n for await (const value of input) {\n const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value);\n const chunkEnd = position + chunk.byteLength;\n if (chunkEnd > offset && position < end) {\n const selected = chunk.subarray(\n Math.max(0, offset - position),\n Math.min(chunk.byteLength, end - position),\n );\n chunks.push(selected);\n collected += selected.byteLength;\n }\n position = chunkEnd;\n if (position >= end) break;\n }\n if (collected !== length) {\n throw new Error(\"ZIP entry changed while reading its byte range\");\n }\n return Buffer.concat(chunks, collected);\n}\n\nasync function openNodeZipEntryStream(\n zipFile: yauzl.ZipFile,\n entry: yauzl.Entry,\n options?: yauzl.ZipFileOptions,\n): Promise<NodeJS.ReadableStream> {\n return await new Promise<NodeJS.ReadableStream>((resolve, reject) => {\n const callback = (error: Error | null, opened: Readable) => {\n if (error || opened === undefined) {\n reject(error ?? new Error(`Cannot read ZIP entry: ${entry.fileName}`));\n } else {\n resolve(opened);\n }\n };\n if (options === undefined) zipFile.openReadStream(entry, callback);\n else zipFile.openReadStream(entry, options, callback);\n });\n}\n\nasync function writeNodeZip(\n file: File,\n entries: Iterable<HostZipWriteEntry> | AsyncIterable<HostZipWriteEntry>,\n): Promise<void> {\n const zipFile = new yazl.ZipFile();\n const writer = await file.openWriter();\n const outputStream = zipFile.outputStream as Readable;\n const outputDone = writeNodeStream(outputStream, writer);\n const entryState = { cancelled: false, complete: false };\n let iterator:\n | Iterator<HostZipWriteEntry>\n | AsyncIterator<HostZipWriteEntry>\n | undefined;\n\n try {\n iterator = getNodeZipEntryIterator(entries);\n const entriesDone = addNodeZipEntries(zipFile, iterator, entryState);\n await Promise.race([entriesDone, outputDone]);\n if (!entryState.complete) {\n throw new Error(\"ZIP output ended before entry production completed\");\n }\n zipFile.end();\n await outputDone;\n await writer.commit();\n } catch (error) {\n entryState.cancelled = true;\n if (!entryState.complete && iterator !== undefined) {\n closeNodeZipEntryIterator(iterator);\n }\n if (!outputStream.destroyed) {\n outputStream.destroy(\n error instanceof Error ? error : new Error(\"Cannot write ZIP archive\"),\n );\n }\n await outputDone.catch(() => undefined);\n await writer.abort().catch(() => undefined);\n throw error;\n }\n}\n\nasync function addNodeZipEntries(\n zipFile: yazl.ZipFile,\n iterator: Iterator<HostZipWriteEntry> | AsyncIterator<HostZipWriteEntry>,\n state: { cancelled: boolean; complete: boolean },\n): Promise<void> {\n while (!state.cancelled) {\n const result = await iterator.next();\n if (state.cancelled) return;\n if (result.done) {\n state.complete = true;\n return;\n }\n if (\"file\" in result.value) {\n zipFile.addReadStream(\n createNodeFileReadStream(result.value.file),\n result.value.name,\n { compress: false },\n );\n } else if (\"data\" in result.value) {\n zipFile.addBuffer(Buffer.from(result.value.data), result.value.name, {\n compress: false,\n });\n } else {\n zipFile.addReadStream(\n createNodeRangeReadStream(result.value),\n result.value.name,\n { compress: false, size: result.value.size },\n );\n }\n }\n}\n\nfunction createNodeFileReadStream(file: ReadonlyFile): Readable {\n return Readable.from(\n (async function* () {\n const reader = await file.openReader();\n try {\n for (let offset = 0; offset < reader.size; ) {\n const chunk = await reader.read(\n offset,\n Math.min(64 * 1024, reader.size - offset),\n );\n offset += chunk.byteLength;\n yield chunk;\n }\n } finally {\n await reader.close();\n }\n })(),\n );\n}\n\nfunction getBrandedNodeResourcePath(\n resource: unknown,\n kind: \"directory\" | \"file\",\n): string | undefined {\n if (typeof resource !== \"object\" || resource === null) return undefined;\n const candidate = resource as {\n readonly [NODE_RESOURCE_KIND]?: unknown;\n readonly path?: unknown;\n };\n return candidate[NODE_RESOURCE_KIND] === kind &&\n typeof candidate.path === \"string\"\n ? candidate.path\n : undefined;\n}\n\nfunction createNodeRangeReadStream(\n entry: Extract<HostZipWriteEntry, { readonly size: number }>,\n): Readable {\n return Readable.from(\n (async function* () {\n for (let offset = 0; offset < entry.size; ) {\n const chunk = await entry.read(\n offset,\n Math.min(64 * 1024, entry.size - offset),\n );\n offset += chunk.byteLength;\n yield chunk;\n }\n })(),\n );\n}\n\nfunction getNodeZipEntryIterator(\n entries: Iterable<HostZipWriteEntry> | AsyncIterable<HostZipWriteEntry>,\n): Iterator<HostZipWriteEntry> | AsyncIterator<HostZipWriteEntry> {\n const asyncIterator = (entries as AsyncIterable<HostZipWriteEntry>)[\n Symbol.asyncIterator\n ];\n return asyncIterator === undefined\n ? (entries as Iterable<HostZipWriteEntry>)[Symbol.iterator]()\n : asyncIterator.call(entries);\n}\n\nfunction closeNodeZipEntryIterator(\n iterator: Iterator<HostZipWriteEntry> | AsyncIterator<HostZipWriteEntry>,\n): void {\n if (iterator.return === undefined) return;\n try {\n void Promise.resolve(iterator.return()).catch(() => undefined);\n } catch {\n // Preserve the failure that caused iteration to stop.\n }\n}\n\nasync function writeNodeStream(\n input: NodeJS.ReadableStream,\n writer: FileWriter,\n): Promise<void> {\n await pipeline(\n input,\n new Writable({\n write: (chunk: Buffer, _encoding, callback) => {\n void writer.write(chunk).then(\n () => callback(),\n (error: unknown) =>\n callback(\n error instanceof Error\n ? error\n : new Error(\"Cannot stream ZIP archive\"),\n ),\n );\n },\n }),\n );\n}\n\nasync function collectNodeStream(\n input: NodeJS.ReadableStream,\n): Promise<Buffer> {\n return await new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n input.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n input.once(\"error\", reject);\n input.once(\"end\", () => resolve(Buffer.concat(chunks)));\n });\n}\n\nexport const nodeWikiGraphPlatform: WikiGraphPlatform = {\n asyncContext: {\n create: <T>() => new asyncHooks.AsyncLocalStorage<T>(),\n },\n database: { open: openNodeDatabase },\n lifecycle: {\n instanceId: `node-process:${nodeProcess.pid}`,\n isInstanceAlive: (instanceId) => {\n const match = /^node-process:(\\d+)$/u.exec(instanceId);\n if (match === null) return Promise.resolve(undefined);\n try {\n nodeProcess.kill(Number(match[1]), 0);\n return Promise.resolve(true);\n } catch (error) {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"ESRCH\"\n ) {\n return Promise.resolve(false);\n }\n return Promise.resolve(true);\n }\n },\n },\n resources: {\n getDirectory: (identity) => {\n const path = decodeNodeResourceIdentity(identity, \"directory\");\n return Promise.resolve(\n path === undefined ? undefined : new NodeDirectory(path),\n );\n },\n getFile: (identity) => {\n const path = decodeNodeResourceIdentity(identity, \"file\");\n return Promise.resolve(\n path === undefined ? undefined : new NodeFile(path),\n );\n },\n resolveLegacyDirectory: (reference) => {\n const path = decodeNodeResourceIdentity(reference, \"directory\");\n return Promise.resolve(\n path === undefined ? undefined : new NodeDirectory(path),\n );\n },\n },\n templates: {\n createEnvironment: (options) =>\n new Environment(new NodeTemplateLoader(), options),\n },\n zip: {\n open: openNodeZip,\n write: writeNodeZip,\n },\n};\n\nclass NodeTemplateLoader extends Loader {\n readonly #dataDirectory: string | undefined;\n\n public constructor(dataDirectory?: string) {\n super();\n this.#dataDirectory = dataDirectory;\n }\n\n public getSource(templateName: string): LoaderSource {\n const name = normalizeTemplateName(templateName);\n const filePath = pathModule.join(\n this.#dataDirectory ?? resolveNodeDataDirectory(),\n name,\n );\n return {\n noCache: false,\n path: name,\n src: fs.readFileSync(filePath, \"utf8\"),\n };\n }\n}\n\nexport function createNodeTemplateEnvironment(\n dataDirectory: string,\n options: {\n readonly autoescape?: boolean;\n readonly trimBlocks?: boolean;\n } = {},\n): Environment {\n return new Environment(new NodeTemplateLoader(dataDirectory), {\n autoescape: options.autoescape ?? true,\n trimBlocks: options.trimBlocks ?? true,\n });\n}\n\nfunction resolveNodeDataDirectory(): string {\n const injected = (globalThis as { __WIKIGRAPH_DATA_DIR__?: unknown })\n .__WIKIGRAPH_DATA_DIR__;\n if (typeof injected === \"string\" && injected !== \"\") return injected;\n let directory = nodeProcess.cwd();\n while (true) {\n for (const candidate of [\n pathModule.join(directory, \"data\"),\n pathModule.join(directory, \"packages\", \"core\", \"data\"),\n ]) {\n try {\n if (fs.statSync(candidate).isDirectory()) return candidate;\n } catch {\n // Keep looking toward the filesystem root.\n }\n }\n const parent = pathModule.dirname(directory);\n if (parent === directory)\n throw new Error(\"Could not locate data directory\");\n directory = parent;\n }\n}\n\nexport function createNodeWikiGraphStorage(\n stateRoot = pathModule.join(os.homedir(), \".wikigraph\"),\n): WikiGraphStorage {\n return {\n library: new NodeDirectory(stateRoot),\n documentStore: new NodeDirectory(pathModule.join(stateRoot, \"documents\")),\n };\n}\n\nexport function installNodeWikiGraphPlatform(stateRoot?: string): void {\n installWikiGraphPlatform(nodeWikiGraphPlatform);\n installWikiGraphStorage(createNodeWikiGraphStorage(stateRoot));\n}\n\nexport function ensureNodeWikiGraphPlatform(): void {\n installWikiGraphPlatform(nodeWikiGraphPlatform);\n try {\n getWikiGraphStorage();\n } catch {\n installWikiGraphStorage(createNodeWikiGraphStorage());\n }\n}\n\nexport async function withNodeWikiGraphStorage<T>(\n stateRoot: string | undefined,\n operation: () => Promise<T> | T,\n): Promise<T> {\n return await withWikiGraphStorage(\n stateRoot === undefined ? undefined : createNodeWikiGraphStorage(stateRoot),\n operation,\n );\n}\n"],"mappings":"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","names":["process","resolve","content","join","homedir"]}
|
package/dist/maintenance.cjs
CHANGED
|
@@ -34,8 +34,8 @@ __export(maintenance_exports, {
|
|
|
34
34
|
WikiGraphMaintenanceManager: () => WikiGraphMaintenanceManager
|
|
35
35
|
});
|
|
36
36
|
module.exports = __toCommonJS(maintenance_exports);
|
|
37
|
-
var
|
|
38
|
-
var
|
|
37
|
+
var import_wiki_graph_core2 = require("wiki-graph-core");
|
|
38
|
+
var import_path3 = require("path");
|
|
39
39
|
|
|
40
40
|
// src/node-platform.ts
|
|
41
41
|
var asyncHooks = __toESM(require("async_hooks"), 1);
|
|
@@ -264,6 +264,14 @@ function decodeNodeResourceIdentity(identity, kind) {
|
|
|
264
264
|
return void 0;
|
|
265
265
|
}
|
|
266
266
|
}
|
|
267
|
+
function getNodeResourcePath(resource) {
|
|
268
|
+
const brandedPath = getBrandedNodeResourcePath(resource, resource.kind);
|
|
269
|
+
if (brandedPath !== void 0) return brandedPath;
|
|
270
|
+
if (typeof resource === "object" && resource !== null && "path" in resource && typeof resource.path === "string") {
|
|
271
|
+
return resource.path;
|
|
272
|
+
}
|
|
273
|
+
throw new TypeError("Expected a Node File or Directory resource");
|
|
274
|
+
}
|
|
267
275
|
function assertChildName(name) {
|
|
268
276
|
if (name.length === 0 || name === "." || name === ".." || pathModule.isAbsolute(name) || name.includes("/") || name.includes("\\")) {
|
|
269
277
|
throw new TypeError(`Directory child must be a relative name: ${name}`);
|
|
@@ -275,42 +283,42 @@ var NodeDatabaseConnection = class {
|
|
|
275
283
|
}
|
|
276
284
|
database;
|
|
277
285
|
async close() {
|
|
278
|
-
await new Promise((
|
|
286
|
+
await new Promise((resolve4, reject) => {
|
|
279
287
|
this.database.close((error) => {
|
|
280
288
|
if (error) reject(error);
|
|
281
|
-
else
|
|
289
|
+
else resolve4();
|
|
282
290
|
});
|
|
283
291
|
});
|
|
284
292
|
}
|
|
285
293
|
async execute(sql) {
|
|
286
|
-
await new Promise((
|
|
294
|
+
await new Promise((resolve4, reject) => {
|
|
287
295
|
this.database.exec(sql, (error) => {
|
|
288
296
|
if (error) reject(error);
|
|
289
|
-
else
|
|
297
|
+
else resolve4();
|
|
290
298
|
});
|
|
291
299
|
});
|
|
292
300
|
}
|
|
293
301
|
async queryAll(sql, params = []) {
|
|
294
|
-
return await new Promise((
|
|
302
|
+
return await new Promise((resolve4, reject) => {
|
|
295
303
|
this.database.all(sql, [...params], (error, rows) => {
|
|
296
304
|
if (error) reject(error);
|
|
297
|
-
else
|
|
305
|
+
else resolve4(rows);
|
|
298
306
|
});
|
|
299
307
|
});
|
|
300
308
|
}
|
|
301
309
|
async queryOne(sql, params = []) {
|
|
302
|
-
return await new Promise((
|
|
310
|
+
return await new Promise((resolve4, reject) => {
|
|
303
311
|
this.database.get(sql, [...params], (error, row) => {
|
|
304
312
|
if (error) reject(error);
|
|
305
|
-
else
|
|
313
|
+
else resolve4(row);
|
|
306
314
|
});
|
|
307
315
|
});
|
|
308
316
|
}
|
|
309
317
|
async run(sql, params = []) {
|
|
310
|
-
await new Promise((
|
|
318
|
+
await new Promise((resolve4, reject) => {
|
|
311
319
|
this.database.run(sql, [...params], (error) => {
|
|
312
320
|
if (error) reject(error);
|
|
313
|
-
else
|
|
321
|
+
else resolve4();
|
|
314
322
|
});
|
|
315
323
|
});
|
|
316
324
|
}
|
|
@@ -324,10 +332,10 @@ async function openNativeNodeDatabase(file, flags) {
|
|
|
324
332
|
if (path === void 0) {
|
|
325
333
|
throw new TypeError("The Node database adapter requires a NodeFile");
|
|
326
334
|
}
|
|
327
|
-
return await new Promise((
|
|
335
|
+
return await new Promise((resolve4, reject) => {
|
|
328
336
|
const database = new nodeSqlite3.Database(path, flags, (error) => {
|
|
329
337
|
if (error) reject(error);
|
|
330
|
-
else
|
|
338
|
+
else resolve4(database);
|
|
331
339
|
});
|
|
332
340
|
});
|
|
333
341
|
}
|
|
@@ -336,19 +344,19 @@ async function openNodeZip(file) {
|
|
|
336
344
|
if (path === void 0) {
|
|
337
345
|
throw new TypeError("The Node ZIP adapter requires a NodeFile");
|
|
338
346
|
}
|
|
339
|
-
const zipFile = await new Promise((
|
|
347
|
+
const zipFile = await new Promise((resolve4, reject) => {
|
|
340
348
|
yauzl.open(
|
|
341
349
|
path,
|
|
342
350
|
{ autoClose: false, lazyEntries: true },
|
|
343
351
|
(error, opened) => {
|
|
344
352
|
if (error || opened === void 0)
|
|
345
353
|
reject(error ?? new Error("Cannot open ZIP"));
|
|
346
|
-
else
|
|
354
|
+
else resolve4(opened);
|
|
347
355
|
}
|
|
348
356
|
);
|
|
349
357
|
});
|
|
350
358
|
const entries = await new Promise(
|
|
351
|
-
(
|
|
359
|
+
(resolve4, reject) => {
|
|
352
360
|
const discovered = /* @__PURE__ */ new Map();
|
|
353
361
|
const rejectAndClose = (error) => {
|
|
354
362
|
zipFile.close();
|
|
@@ -358,7 +366,7 @@ async function openNodeZip(file) {
|
|
|
358
366
|
};
|
|
359
367
|
const resolveEntries = () => {
|
|
360
368
|
zipFile.off("error", rejectAndClose);
|
|
361
|
-
|
|
369
|
+
resolve4(discovered);
|
|
362
370
|
};
|
|
363
371
|
zipFile.on("entry", (entry) => {
|
|
364
372
|
if (!entry.fileName.endsWith("/")) {
|
|
@@ -468,12 +476,12 @@ async function collectDecodedNodeStreamRange(input, offset, length) {
|
|
|
468
476
|
return Buffer.concat(chunks, collected);
|
|
469
477
|
}
|
|
470
478
|
async function openNodeZipEntryStream(zipFile, entry, options) {
|
|
471
|
-
return await new Promise((
|
|
479
|
+
return await new Promise((resolve4, reject) => {
|
|
472
480
|
const callback = (error, opened) => {
|
|
473
481
|
if (error || opened === void 0) {
|
|
474
482
|
reject(error ?? new Error(`Cannot read ZIP entry: ${entry.fileName}`));
|
|
475
483
|
} else {
|
|
476
|
-
|
|
484
|
+
resolve4(opened);
|
|
477
485
|
}
|
|
478
486
|
};
|
|
479
487
|
if (options === void 0) zipFile.openReadStream(entry, callback);
|
|
@@ -604,11 +612,11 @@ async function writeNodeStream(input, writer) {
|
|
|
604
612
|
);
|
|
605
613
|
}
|
|
606
614
|
async function collectNodeStream(input) {
|
|
607
|
-
return await new Promise((
|
|
615
|
+
return await new Promise((resolve4, reject) => {
|
|
608
616
|
const chunks = [];
|
|
609
617
|
input.on("data", (chunk) => chunks.push(chunk));
|
|
610
618
|
input.once("error", reject);
|
|
611
|
-
input.once("end", () =>
|
|
619
|
+
input.once("end", () => resolve4(Buffer.concat(chunks)));
|
|
612
620
|
});
|
|
613
621
|
}
|
|
614
622
|
var nodeWikiGraphPlatform = {
|
|
@@ -727,7 +735,8 @@ function getWikiGraphSDKRuntimeContext() {
|
|
|
727
735
|
return runtimeContext.getStore() ?? {
|
|
728
736
|
cwd: process.cwd(),
|
|
729
737
|
env: process.env,
|
|
730
|
-
envPolicy: "production"
|
|
738
|
+
envPolicy: "production",
|
|
739
|
+
providers: {}
|
|
731
740
|
};
|
|
732
741
|
}
|
|
733
742
|
|
|
@@ -741,6 +750,107 @@ function resolveWikiGraphRuntimePath(path) {
|
|
|
741
750
|
return (0, import_path.isAbsolute)(path) ? path : (0, import_path.resolve)(context.cwd, path);
|
|
742
751
|
}
|
|
743
752
|
|
|
753
|
+
// src/archive/target.ts
|
|
754
|
+
var import_promises2 = require("fs/promises");
|
|
755
|
+
var import_path2 = require("path");
|
|
756
|
+
var import_wiki_graph_core = require("wiki-graph-core");
|
|
757
|
+
var WikiGraphArchiveOwnershipError = class extends Error {
|
|
758
|
+
code = "WIKI_GRAPH_ARCHIVE_OWNERSHIP_MISMATCH";
|
|
759
|
+
constructor(message) {
|
|
760
|
+
super(message);
|
|
761
|
+
this.name = "WikiGraphArchiveOwnershipError";
|
|
762
|
+
}
|
|
763
|
+
};
|
|
764
|
+
async function assertStandaloneWikiGraphArchivePath(inputPath) {
|
|
765
|
+
const path = resolveWikiGraphRuntimePath(inputPath);
|
|
766
|
+
const candidate = await canonicalPath(path);
|
|
767
|
+
const candidateIdentity = await readFileIdentity(path);
|
|
768
|
+
const libraries = await (0, import_wiki_graph_core.listWikiGraphLibraries)();
|
|
769
|
+
const matches = await findMatchingMembers(
|
|
770
|
+
libraries,
|
|
771
|
+
candidate,
|
|
772
|
+
candidateIdentity
|
|
773
|
+
);
|
|
774
|
+
if (matches.length > 0) {
|
|
775
|
+
const match = requireUnambiguousManagedMatch(path, matches);
|
|
776
|
+
throw new WikiGraphArchiveOwnershipError(
|
|
777
|
+
`Standalone archive path belongs to registered library ${(0, import_wiki_graph_core.formatWikiGraphLibraryUri)(
|
|
778
|
+
match.library.isDefault ? void 0 : match.library.publicId
|
|
779
|
+
)}: ${path}. Use the library UUID URI ${match.archive.uri} instead.`
|
|
780
|
+
);
|
|
781
|
+
}
|
|
782
|
+
for (const library of libraries) {
|
|
783
|
+
const rootPath = getNodeResourcePath(library.folder);
|
|
784
|
+
const root = await canonicalPath(rootPath);
|
|
785
|
+
if (!isWithin(root, candidate)) continue;
|
|
786
|
+
throw new WikiGraphArchiveOwnershipError(
|
|
787
|
+
`Standalone archive path belongs to registered library ${(0, import_wiki_graph_core.formatWikiGraphLibraryUri)(
|
|
788
|
+
library.isDefault ? void 0 : library.publicId
|
|
789
|
+
)}: ${path}. Scan the library, then address the archive by its library UUID URI.`
|
|
790
|
+
);
|
|
791
|
+
}
|
|
792
|
+
return path;
|
|
793
|
+
}
|
|
794
|
+
async function canonicalPath(path) {
|
|
795
|
+
try {
|
|
796
|
+
return await (0, import_promises2.realpath)(path);
|
|
797
|
+
} catch {
|
|
798
|
+
const absolute = (0, import_path2.resolve)(path);
|
|
799
|
+
const parent = (0, import_path2.dirname)(absolute);
|
|
800
|
+
return parent === absolute ? absolute : (0, import_path2.join)(await canonicalPath(parent), (0, import_path2.basename)(absolute));
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
function isWithin(root, candidate) {
|
|
804
|
+
const child = (0, import_path2.relative)(root, candidate);
|
|
805
|
+
return child === "" || !child.startsWith("..") && !(0, import_path2.isAbsolute)(child);
|
|
806
|
+
}
|
|
807
|
+
async function findMatchingMembers(libraries, candidate, candidateIdentity) {
|
|
808
|
+
const members = [];
|
|
809
|
+
for (const library of libraries) {
|
|
810
|
+
const archives = await (0, import_wiki_graph_core.listWikiGraphLibraryArchives)({
|
|
811
|
+
isDefault: library.isDefault,
|
|
812
|
+
kind: "scope",
|
|
813
|
+
...library.isDefault ? {} : { publicId: library.publicId }
|
|
814
|
+
});
|
|
815
|
+
for (const archive of archives) {
|
|
816
|
+
if (archive.file === void 0) continue;
|
|
817
|
+
members.push({
|
|
818
|
+
archive,
|
|
819
|
+
library,
|
|
820
|
+
memberPath: getNodeResourcePath(archive.file)
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
const exact = [];
|
|
825
|
+
for (const member of members) {
|
|
826
|
+
if (await canonicalPath(member.memberPath) === candidate) {
|
|
827
|
+
exact.push(member);
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
if (exact.length > 0 || candidateIdentity === void 0) return exact;
|
|
831
|
+
const identityMatches = [];
|
|
832
|
+
for (const member of members) {
|
|
833
|
+
if (await readFileIdentity(member.memberPath) === candidateIdentity) {
|
|
834
|
+
identityMatches.push(member);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
return identityMatches;
|
|
838
|
+
}
|
|
839
|
+
function requireUnambiguousManagedMatch(path, matches) {
|
|
840
|
+
if (matches.length === 1) return matches[0];
|
|
841
|
+
throw new WikiGraphArchiveOwnershipError(
|
|
842
|
+
`Archive file identity is ambiguous across managed archives: ${path}. Use an explicit library UUID URI (${matches.map((match) => match.archive.uri).join(", ")}).`
|
|
843
|
+
);
|
|
844
|
+
}
|
|
845
|
+
async function readFileIdentity(path) {
|
|
846
|
+
try {
|
|
847
|
+
const value = await (0, import_promises2.stat)(path);
|
|
848
|
+
return `${value.dev}:${value.ino}`;
|
|
849
|
+
} catch {
|
|
850
|
+
return void 0;
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
|
|
744
854
|
// src/maintenance.ts
|
|
745
855
|
var WikiGraphMaintenanceManager = class {
|
|
746
856
|
#runtime;
|
|
@@ -751,22 +861,22 @@ var WikiGraphMaintenanceManager = class {
|
|
|
751
861
|
return await this.#runtime.run(
|
|
752
862
|
async () => {
|
|
753
863
|
if (target.kind === "home") {
|
|
754
|
-
return await (0,
|
|
864
|
+
return await (0, import_wiki_graph_core2.upgradeWikiGraphMaintenanceTarget)({ kind: "home" });
|
|
755
865
|
}
|
|
756
866
|
if (target.kind === "library") {
|
|
757
|
-
const parsed = (0,
|
|
867
|
+
const parsed = (0, import_wiki_graph_core2.parseWikiGraphLibraryUri)(target.uri);
|
|
758
868
|
if (parsed === void 0 || parsed.kind === "archive") {
|
|
759
869
|
throw new Error(
|
|
760
870
|
`Invalid Wiki Graph library upgrade target: ${target.uri}`
|
|
761
871
|
);
|
|
762
872
|
}
|
|
763
|
-
return await (0,
|
|
873
|
+
return await (0, import_wiki_graph_core2.upgradeWikiGraphMaintenanceTarget)({
|
|
764
874
|
kind: "library",
|
|
765
875
|
target: parsed
|
|
766
876
|
});
|
|
767
877
|
}
|
|
768
|
-
const path =
|
|
769
|
-
return await (0,
|
|
878
|
+
const path = await assertStandaloneWikiGraphArchivePath(target.path);
|
|
879
|
+
return await (0, import_wiki_graph_core2.upgradeWikiGraphMaintenanceTarget)({
|
|
770
880
|
file: new NodeFile(path),
|
|
771
881
|
kind: "archive"
|
|
772
882
|
});
|
|
@@ -779,9 +889,9 @@ var WikiGraphMaintenanceManager = class {
|
|
|
779
889
|
return await this.#runtime.run(async () => {
|
|
780
890
|
const resolvedInputPath = resolveWikiGraphRuntimePath(inputPath);
|
|
781
891
|
const resolvedOutputPath = resolveWikiGraphRuntimePath(outputPath);
|
|
782
|
-
await (0,
|
|
892
|
+
await (0, import_wiki_graph_core2.migrateLegacySdpubToWikg)(
|
|
783
893
|
new NodeFile(resolvedInputPath),
|
|
784
|
-
new NodeFile(resolvedOutputPath, (0,
|
|
894
|
+
new NodeFile(resolvedOutputPath, (0, import_path3.basename)(resolvedOutputPath))
|
|
785
895
|
);
|
|
786
896
|
return {
|
|
787
897
|
inputPath: resolvedInputPath,
|