@typicalday/firegraph 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -90
- package/bin/firegraph.mjs +21 -7
- package/dist/backend-U-MLShlg.d.ts +97 -0
- package/dist/backend-np4gEVhB.d.cts +97 -0
- package/dist/backend.cjs.map +1 -1
- package/dist/backend.d.cts +7 -6
- package/dist/backend.d.ts +7 -6
- package/dist/backend.js +1 -1
- package/dist/backend.js.map +1 -1
- package/dist/{chunk-EVUM6ORB.js → chunk-6SB34IPQ.js} +76 -8
- package/dist/chunk-6SB34IPQ.js.map +1 -0
- package/dist/{chunk-SU4FNLC3.js → chunk-EEKWRX5E.js} +1 -1
- package/dist/{chunk-SU4FNLC3.js.map → chunk-EEKWRX5E.js.map} +1 -1
- package/dist/{chunk-YLGXLEUE.js → chunk-GJVVRTQT.js} +5 -14
- package/dist/chunk-GJVVRTQT.js.map +1 -0
- package/dist/{chunk-GLOVWKQH.js → chunk-R7CRGYY4.js} +1 -1
- package/dist/{chunk-GLOVWKQH.js.map → chunk-R7CRGYY4.js.map} +1 -1
- package/dist/{do-sqlite.cjs → cloudflare/index.cjs} +1659 -1422
- package/dist/cloudflare/index.cjs.map +1 -0
- package/dist/cloudflare/index.d.cts +529 -0
- package/dist/cloudflare/index.d.ts +529 -0
- package/dist/cloudflare/index.js +934 -0
- package/dist/cloudflare/index.js.map +1 -0
- package/dist/codegen/index.cjs +4 -13
- package/dist/codegen/index.cjs.map +1 -1
- package/dist/codegen/index.d.cts +1 -1
- package/dist/codegen/index.d.ts +1 -1
- package/dist/codegen/index.js +1 -1
- package/dist/index.cjs +144 -132
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +116 -27
- package/dist/index.d.ts +116 -27
- package/dist/index.js +77 -123
- package/dist/index.js.map +1 -1
- package/dist/query-client/index.cjs.map +1 -1
- package/dist/query-client/index.js +1 -1
- package/dist/{scope-path-BtajqNK5.d.ts → scope-path-B1G3YiA7.d.cts} +5 -100
- package/dist/{scope-path-D2mNENJ-.d.cts → scope-path-B1G3YiA7.d.ts} +5 -100
- package/dist/{types-DfWVTsMn.d.ts → types-BGWxcpI_.d.cts} +92 -1
- package/dist/{types-DfWVTsMn.d.cts → types-BGWxcpI_.d.ts} +92 -1
- package/package.json +13 -17
- package/dist/chunk-EVUM6ORB.js.map +0 -1
- package/dist/chunk-SZ6W4VAS.js +0 -701
- package/dist/chunk-SZ6W4VAS.js.map +0 -1
- package/dist/chunk-YLGXLEUE.js.map +0 -1
- package/dist/d1.cjs +0 -2421
- package/dist/d1.cjs.map +0 -1
- package/dist/d1.d.cts +0 -54
- package/dist/d1.d.ts +0 -54
- package/dist/d1.js +0 -76
- package/dist/d1.js.map +0 -1
- package/dist/do-sqlite.cjs.map +0 -1
- package/dist/do-sqlite.d.cts +0 -41
- package/dist/do-sqlite.d.ts +0 -41
- package/dist/do-sqlite.js +0 -79
- package/dist/do-sqlite.js.map +0 -1
- package/dist/editor/client/assets/index-Bq2bfzeY.js +0 -411
- package/dist/editor/client/assets/index-CJ4m_EOL.css +0 -1
- package/dist/editor/client/index.html +0 -16
- package/dist/editor/server/index.mjs +0 -51511
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/query-client/index.ts","../../src/query-client/client.ts","../../src/query-client/config.ts","../../src/query-client/shaping.ts","../../src/query-client/cli.ts"],"sourcesContent":["export { runQueryCli } from './cli.js';\nexport type { QueryClientErrorCode } from './client.js';\nexport { QueryClient, QueryClientError } from './client.js';\nexport { readEditorPort } from './config.js';\nexport { summarizeEdge, summarizeRecord } from './shaping.js';\nexport type {\n GetEdgesInput,\n GetEdgesResult,\n GetNodeDetailInput,\n GetNodesInput,\n GetNodesResult,\n NodeDetailResult,\n QueryClientOptions,\n SchemaResult,\n SearchInput,\n SearchResult,\n SummarizedEdge,\n SummarizedRecord,\n TraverseHop,\n TraverseHopResult,\n TraverseInput,\n TraverseResult,\n WhereClause,\n} from './types.js';\n","import http from 'node:http';\n\nimport { readEditorPort } from './config.js';\nimport { summarizeEdge, summarizeRecord } from './shaping.js';\nimport type {\n GetEdgesInput,\n GetEdgesResult,\n GetNodeDetailInput,\n GetNodesInput,\n GetNodesResult,\n NodeDetailResult,\n QueryClientOptions,\n SchemaResult,\n SearchInput,\n SearchResult,\n SummarizedEdge,\n SummarizedRecord,\n TraverseHopResult,\n TraverseInput,\n TraverseResult,\n} from './types.js';\n\n// --- Error ---\n\nexport type QueryClientErrorCode = 'VALIDATION_ERROR' | 'CONNECTION_FAILED' | 'SERVER_ERROR';\n\nexport class QueryClientError extends Error {\n constructor(\n message: string,\n public readonly code: QueryClientErrorCode,\n ) {\n super(message);\n this.name = 'QueryClientError';\n }\n}\n\n// --- Validation helpers ---\n\nfunction requireString(value: unknown, name: string): asserts value is string {\n if (typeof value !== 'string' || value.length === 0) {\n throw new QueryClientError(`${name} must be a non-empty string`, 'VALIDATION_ERROR');\n }\n}\n\nfunction clampInt(value: number | undefined, min: number, max: number, fallback: number): number {\n if (value == null) return fallback;\n if (!Number.isInteger(value)) {\n throw new QueryClientError(`limit must be an integer`, 'VALIDATION_ERROR');\n }\n return Math.max(min, Math.min(max, value));\n}\n\nfunction validateSortDir(dir: string | undefined): void {\n if (dir != null && dir !== 'asc' && dir !== 'desc') {\n throw new QueryClientError(`sortDir must be 'asc' or 'desc'`, 'VALIDATION_ERROR');\n }\n}\n\n// --- HTTP helpers ---\n\nfunction httpGet(url: string): Promise<string> {\n return new Promise((resolve, reject) => {\n http\n .get(url, (res) => {\n let body = '';\n res.on('data', (c: string) => (body += c));\n res.on('end', () => resolve(body));\n })\n .on('error', (err) => {\n reject(new QueryClientError(`Connection failed: ${err.message}`, 'CONNECTION_FAILED'));\n });\n });\n}\n\nfunction httpPost(url: string, payload: string): Promise<string> {\n const parsed = new URL(url);\n return new Promise((resolve, reject) => {\n const req = http.request(\n {\n hostname: parsed.hostname,\n port: parsed.port,\n path: parsed.pathname,\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Content-Length': Buffer.byteLength(payload),\n },\n },\n (res) => {\n let body = '';\n res.on('data', (c: string) => (body += c));\n res.on('end', () => resolve(body));\n },\n );\n req.on('error', (err) => {\n reject(new QueryClientError(`Connection failed: ${err.message}`, 'CONNECTION_FAILED'));\n });\n req.write(payload);\n req.end();\n });\n}\n\nfunction parseTrpcResponse(raw: string, procedure: string): unknown {\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new QueryClientError(\n `Invalid JSON from ${procedure}: ${raw.slice(0, 200)}`,\n 'SERVER_ERROR',\n );\n }\n if (parsed.error) {\n const msg =\n typeof parsed.error === 'object' && parsed.error !== null\n ? ((parsed.error as Record<string, unknown>).message ?? JSON.stringify(parsed.error))\n : String(parsed.error);\n throw new QueryClientError(`Server error from ${procedure}: ${msg}`, 'SERVER_ERROR');\n }\n return (parsed.result as Record<string, unknown>)?.data ?? parsed;\n}\n\n// --- Client ---\n\nexport class QueryClient {\n private readonly baseUrl: string;\n\n constructor(options?: QueryClientOptions) {\n const host = options?.host ?? 'localhost';\n const port = options?.port ?? readEditorPort();\n this.baseUrl = `http://${host}:${port}/api/trpc`;\n }\n\n private async query(procedure: string, input?: unknown): Promise<unknown> {\n const qs = input != null ? `?input=${encodeURIComponent(JSON.stringify(input))}` : '';\n const url = `${this.baseUrl}/${procedure}${qs}`;\n const raw = await httpGet(url);\n return parseTrpcResponse(raw, procedure);\n }\n\n private async mutate(procedure: string, input: unknown): Promise<unknown> {\n const url = `${this.baseUrl}/${procedure}`;\n const raw = await httpPost(url, JSON.stringify(input));\n return parseTrpcResponse(raw, procedure);\n }\n\n // --- Public API ---\n\n async getSchema(): Promise<SchemaResult> {\n const data = (await this.query('getSchema')) as Record<string, unknown>;\n return {\n nodeTypes: ((data.nodeTypes as unknown[]) ?? []).map(\n (t) =>\n (typeof t === 'object' && t !== null ? (t as Record<string, unknown>).type : t) as string,\n ),\n edgeTypes: ((data.edgeTypes as unknown[]) ?? []).map((t) => {\n const e = t as Record<string, unknown>;\n return {\n relation: e.axbType as string,\n from: e.aType as string,\n to: e.bType as string,\n inverseLabel: (e.inverseLabel as string) ?? null,\n };\n }),\n };\n }\n\n async getNodeDetail(input: GetNodeDetailInput): Promise<NodeDetailResult> {\n requireString(input.uid, 'uid');\n const data = (await this.query('getNodeDetail', { uid: input.uid })) as Record<string, unknown>;\n return {\n node: summarizeRecord(data.node as Record<string, unknown> | null),\n outEdges: ((data.outEdges as Record<string, unknown>[]) ?? [])\n .map(summarizeEdge)\n .filter(Boolean) as SummarizedEdge[],\n inEdges: ((data.inEdges as Record<string, unknown>[]) ?? [])\n .map(summarizeEdge)\n .filter(Boolean) as SummarizedEdge[],\n };\n }\n\n async getNodes(input: GetNodesInput): Promise<GetNodesResult> {\n const limit = clampInt(input.limit, 1, 200, 25);\n validateSortDir(input.sortDir);\n const data = (await this.query('getNodes', {\n type: input.type,\n limit,\n startAfter: input.startAfter,\n sortBy: input.sortBy,\n sortDir: input.sortDir,\n where: input.where,\n })) as Record<string, unknown>;\n return {\n nodes: ((data.nodes as Record<string, unknown>[]) ?? [])\n .map(summarizeRecord)\n .filter(Boolean) as SummarizedRecord[],\n hasMore: (data.hasMore as boolean) ?? false,\n nextCursor: data.nextCursor as string | null | undefined,\n };\n }\n\n async getEdges(input: GetEdgesInput): Promise<GetEdgesResult> {\n const hasFilter =\n input.aType ||\n input.aUid ||\n input.axbType ||\n input.bType ||\n input.bUid ||\n (input.where && input.where.length > 0);\n if (!hasFilter) {\n throw new QueryClientError(\n 'getEdges requires at least one filter field (aType, aUid, axbType, bType, bUid, or where)',\n 'VALIDATION_ERROR',\n );\n }\n const limit = clampInt(input.limit, 1, 200, 25);\n validateSortDir(input.sortDir);\n const data = (await this.query('getEdges', {\n aType: input.aType,\n aUid: input.aUid,\n axbType: input.axbType,\n bType: input.bType,\n bUid: input.bUid,\n limit,\n startAfter: input.startAfter,\n sortBy: input.sortBy,\n sortDir: input.sortDir,\n where: input.where,\n })) as Record<string, unknown>;\n return {\n edges: ((data.edges as Record<string, unknown>[]) ?? [])\n .map(summarizeEdge)\n .filter(Boolean) as SummarizedEdge[],\n hasMore: (data.hasMore as boolean) ?? false,\n nextCursor: data.nextCursor as string | null | undefined,\n };\n }\n\n async traverse(input: TraverseInput): Promise<TraverseResult> {\n requireString(input.startUid, 'startUid');\n if (!input.hops || input.hops.length === 0) {\n throw new QueryClientError('traverse requires at least one hop', 'VALIDATION_ERROR');\n }\n for (let i = 0; i < input.hops.length; i++) {\n const hop = input.hops[i];\n requireString(hop.axbType, `hops[${i}].axbType`);\n if (hop.direction != null && hop.direction !== 'forward' && hop.direction !== 'reverse') {\n throw new QueryClientError(\n `hops[${i}].direction must be 'forward' or 'reverse'`,\n 'VALIDATION_ERROR',\n );\n }\n if (hop.limit != null && (!Number.isInteger(hop.limit) || hop.limit < 1)) {\n throw new QueryClientError(\n `hops[${i}].limit must be a positive integer`,\n 'VALIDATION_ERROR',\n );\n }\n }\n if (input.maxReads != null && (!Number.isInteger(input.maxReads) || input.maxReads < 1)) {\n throw new QueryClientError('maxReads must be a positive integer', 'VALIDATION_ERROR');\n }\n if (\n input.concurrency != null &&\n (!Number.isInteger(input.concurrency) || input.concurrency < 1)\n ) {\n throw new QueryClientError('concurrency must be a positive integer', 'VALIDATION_ERROR');\n }\n\n const data = (await this.mutate('traverse', input)) as Record<string, unknown>;\n return {\n hops: ((data.hops as Record<string, unknown>[]) ?? []).map(\n (h): TraverseHopResult => ({\n relation: h.axbType as string,\n direction: h.direction as string,\n depth: h.depth as number,\n edgeCount: ((h.edges as unknown[]) ?? []).length,\n edges: ((h.edges as Record<string, unknown>[]) ?? [])\n .map(summarizeEdge)\n .filter(Boolean) as SummarizedEdge[],\n truncated: (h.truncated as boolean) ?? false,\n }),\n ),\n totalReads: (data.totalReads as number) ?? 0,\n truncated: (data.truncated as boolean) ?? false,\n };\n }\n\n async search(input: SearchInput): Promise<SearchResult> {\n requireString(input.q, 'q');\n const limit = clampInt(input.limit, 1, 50, 20);\n const data = (await this.query('search', { q: input.q, limit })) as Record<string, unknown>;\n return {\n results: ((data.results as Record<string, unknown>[]) ?? [])\n .map((r) => {\n const base = summarizeRecord(r);\n if (!base) return null;\n return {\n ...base,\n matchType: (r._matchType as string) ?? null,\n };\n })\n .filter(Boolean) as (SummarizedRecord & { matchType: string | null })[],\n };\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nconst CONFIG_FILES = ['firegraph.config.ts', 'firegraph.config.js', 'firegraph.config.mjs'];\nconst DEFAULT_PORT = 3884;\n\n/**\n * Read the editor port from firegraph config files using regex.\n * Zero-dependency — no jiti needed.\n */\nexport function readEditorPort(cwd?: string): number {\n const dir = cwd ?? process.cwd();\n for (const name of CONFIG_FILES) {\n try {\n const content = readFileSync(join(dir, name), 'utf8');\n const editorBlock = content.match(/editor\\s*:\\s*\\{[^}]*\\}/s)?.[0] ?? '';\n const portMatch = editorBlock.match(/port\\s*:\\s*(\\d+)/);\n if (portMatch) return parseInt(portMatch[1], 10);\n } catch {\n continue;\n }\n }\n return DEFAULT_PORT;\n}\n","import type { SummarizedEdge, SummarizedRecord } from './types.js';\n\nexport function summarizeRecord(r: Record<string, unknown> | null): SummarizedRecord | null {\n if (!r) return null;\n const out: SummarizedRecord = { type: r.aType as string, uid: r.aUid as string };\n const data = r.data as Record<string, unknown> | undefined;\n if (data && typeof data === 'object' && Object.keys(data).length > 0) {\n out.data = data;\n }\n return out;\n}\n\nexport function summarizeEdge(r: Record<string, unknown> | null): SummarizedEdge | null {\n if (!r) return null;\n const out: SummarizedEdge = {\n fromType: r.aType as string,\n fromUid: r.aUid as string,\n relation: r.axbType as string,\n toType: r.bType as string,\n toUid: r.bUid as string,\n };\n const data = r.data as Record<string, unknown> | undefined;\n if (data && typeof data === 'object' && Object.keys(data).length > 0) {\n out.data = data;\n }\n return out;\n}\n","import { QueryClient, QueryClientError } from './client.js';\nimport type { TraverseInput } from './types.js';\n\n// --- Argument parsing ---\n\ninterface ParsedArgs {\n flags: Record<string, string>;\n positional: string[];\n}\n\nfunction parseFlags(args: string[]): ParsedArgs {\n const flags: Record<string, string> = {};\n const positional: string[] = [];\n for (let i = 0; i < args.length; i++) {\n if (args[i].startsWith('--')) {\n const key = args[i].slice(2);\n const next = args[i + 1];\n if (next && !next.startsWith('--')) {\n flags[key] = next;\n i++;\n } else {\n flags[key] = 'true';\n }\n } else {\n positional.push(args[i]);\n }\n }\n return { flags, positional };\n}\n\n// --- CLI runner ---\n\nexport async function runQueryCli(argv: string[]): Promise<void> {\n const command = argv[0];\n const rest = argv.slice(1);\n const { flags, positional } = parseFlags(rest);\n\n const port = flags.port ? parseInt(flags.port, 10) : undefined;\n const host = flags.host ?? undefined;\n const client = new QueryClient({ port, host });\n\n try {\n let result: unknown;\n\n switch (command) {\n case 'schema':\n result = await client.getSchema();\n break;\n\n case 'get':\n if (!positional[0]) {\n die('Usage: firegraph query get <uid>');\n }\n result = await client.getNodeDetail({ uid: positional[0] });\n break;\n\n case 'find-nodes': {\n if (!positional[0]) {\n die('Usage: firegraph query find-nodes <type> [--limit N]');\n }\n result = await client.getNodes({\n type: positional[0],\n limit: flags.limit ? parseInt(flags.limit, 10) : undefined,\n });\n break;\n }\n\n case 'find-edges': {\n result = await client.getEdges({\n aType: flags.aType,\n aUid: flags.aUid,\n axbType: flags.axbType,\n bType: flags.bType,\n bUid: flags.bUid,\n limit: flags.limit ? parseInt(flags.limit, 10) : undefined,\n });\n break;\n }\n\n case 'traverse': {\n const jsonStr = positional.join(' ');\n if (!jsonStr) {\n die(\n 'Usage: firegraph query traverse \\'<JSON>\\'\\n\\n' +\n 'JSON shape:\\n' +\n '{\\n' +\n ' \"startUid\": \"nodeUid\",\\n' +\n ' \"hops\": [\\n' +\n ' {\\n' +\n ' \"axbType\": \"relationName\",\\n' +\n ' \"direction\": \"forward\" | \"reverse\",\\n' +\n ' \"limit\": 10,\\n' +\n ' \"aType\": \"filterSourceType\",\\n' +\n ' \"bType\": \"filterTargetType\",\\n' +\n ' \"orderBy\": { \"field\": \"data.name\", \"direction\": \"asc\" },\\n' +\n ' \"where\": [{ \"field\": \"data.status\", \"op\": \"==\", \"value\": \"active\" }]\\n' +\n ' }\\n' +\n ' ],\\n' +\n ' \"maxReads\": 100,\\n' +\n ' \"concurrency\": 5\\n' +\n '}',\n );\n }\n let input: TraverseInput;\n try {\n input = JSON.parse(jsonStr) as TraverseInput;\n } catch {\n die(`Invalid JSON: ${jsonStr.slice(0, 200)}`);\n }\n result = await client.traverse(input!);\n break;\n }\n\n case 'search':\n if (!positional[0]) {\n die('Usage: firegraph query search <query>');\n }\n result = await client.search({ q: positional.join(' ') });\n break;\n\n case '--help':\n case '-h':\n case undefined:\n printHelp();\n return;\n\n default:\n die(\n `Unknown query command: ${command}\\n` +\n 'Commands: schema, get, find-nodes, find-edges, traverse, search',\n );\n }\n\n console.log(JSON.stringify(result, null, 2));\n } catch (err) {\n if (err instanceof QueryClientError) {\n console.error(JSON.stringify({ error: err.message, code: err.code }));\n } else {\n console.error(JSON.stringify({ error: (err as Error).message }));\n }\n process.exit(1);\n }\n}\n\nfunction printHelp(): void {\n console.log('');\n console.log(' Usage: firegraph query <command> [options]');\n console.log('');\n console.log(' Commands:');\n console.log(' schema Get graph schema (node types + edge types)');\n console.log(' get <uid> Get node detail with edges');\n console.log(' find-nodes <type> [--limit N] List nodes of a type');\n console.log(' find-edges [filters] List edges matching filters');\n console.log(' traverse \\'<JSON>\\' Multi-hop graph traversal');\n console.log(' search <query> Search nodes by text');\n console.log('');\n console.log(' Global options:');\n console.log(' --port <number> Editor server port (default: auto-detect from config)');\n console.log(' --host <string> Editor server host (default: localhost)');\n console.log('');\n console.log(' find-edges filters:');\n console.log(' --aType <type> Filter by source type');\n console.log(' --aUid <uid> Filter by source UID');\n console.log(' --axbType <rel> Filter by relation type');\n console.log(' --bType <type> Filter by target type');\n console.log(' --bUid <uid> Filter by target UID');\n console.log(' --limit <N> Max results (1-200, default 25)');\n console.log('');\n console.log(' Examples:');\n console.log(' npx firegraph query schema');\n console.log(' npx firegraph query get Kj7vNq2mP9xR4wL1tY8s3');\n console.log(' npx firegraph query find-nodes task --limit 10');\n console.log(' npx firegraph query find-edges --aUid Kj7vNq2mP9xR4wL1tY8s3 --axbType hasTask');\n console.log(' npx firegraph query search \"John Doe\"');\n console.log('');\n}\n\nfunction die(msg: string): never {\n console.error(msg);\n process.exit(1);\n}\n"],"mappings":"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","names":["http"]}
|
|
1
|
+
{"version":3,"sources":["../../src/query-client/index.ts","../../src/query-client/client.ts","../../src/query-client/config.ts","../../src/query-client/shaping.ts","../../src/query-client/cli.ts"],"sourcesContent":["export { runQueryCli } from './cli.js';\nexport type { QueryClientErrorCode } from './client.js';\nexport { QueryClient, QueryClientError } from './client.js';\nexport { readEditorPort } from './config.js';\nexport { summarizeEdge, summarizeRecord } from './shaping.js';\nexport type {\n GetEdgesInput,\n GetEdgesResult,\n GetNodeDetailInput,\n GetNodesInput,\n GetNodesResult,\n NodeDetailResult,\n QueryClientOptions,\n SchemaResult,\n SearchInput,\n SearchResult,\n SummarizedEdge,\n SummarizedRecord,\n TraverseHop,\n TraverseHopResult,\n TraverseInput,\n TraverseResult,\n WhereClause,\n} from './types.js';\n","import http from 'node:http';\n\nimport { readEditorPort } from './config.js';\nimport { summarizeEdge, summarizeRecord } from './shaping.js';\nimport type {\n GetEdgesInput,\n GetEdgesResult,\n GetNodeDetailInput,\n GetNodesInput,\n GetNodesResult,\n NodeDetailResult,\n QueryClientOptions,\n SchemaResult,\n SearchInput,\n SearchResult,\n SummarizedEdge,\n SummarizedRecord,\n TraverseHopResult,\n TraverseInput,\n TraverseResult,\n} from './types.js';\n\n// --- Error ---\n\nexport type QueryClientErrorCode = 'VALIDATION_ERROR' | 'CONNECTION_FAILED' | 'SERVER_ERROR';\n\nexport class QueryClientError extends Error {\n constructor(\n message: string,\n public readonly code: QueryClientErrorCode,\n ) {\n super(message);\n this.name = 'QueryClientError';\n }\n}\n\n// --- Validation helpers ---\n\nfunction requireString(value: unknown, name: string): asserts value is string {\n if (typeof value !== 'string' || value.length === 0) {\n throw new QueryClientError(`${name} must be a non-empty string`, 'VALIDATION_ERROR');\n }\n}\n\nfunction clampInt(value: number | undefined, min: number, max: number, fallback: number): number {\n if (value == null) return fallback;\n if (!Number.isInteger(value)) {\n throw new QueryClientError(`limit must be an integer`, 'VALIDATION_ERROR');\n }\n return Math.max(min, Math.min(max, value));\n}\n\nfunction validateSortDir(dir: string | undefined): void {\n if (dir != null && dir !== 'asc' && dir !== 'desc') {\n throw new QueryClientError(`sortDir must be 'asc' or 'desc'`, 'VALIDATION_ERROR');\n }\n}\n\n// --- HTTP helpers ---\n\nfunction httpGet(url: string): Promise<string> {\n return new Promise((resolve, reject) => {\n http\n .get(url, (res) => {\n let body = '';\n res.on('data', (c: string) => (body += c));\n res.on('end', () => resolve(body));\n })\n .on('error', (err) => {\n reject(new QueryClientError(`Connection failed: ${err.message}`, 'CONNECTION_FAILED'));\n });\n });\n}\n\nfunction httpPost(url: string, payload: string): Promise<string> {\n const parsed = new URL(url);\n return new Promise((resolve, reject) => {\n const req = http.request(\n {\n hostname: parsed.hostname,\n port: parsed.port,\n path: parsed.pathname,\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Content-Length': Buffer.byteLength(payload),\n },\n },\n (res) => {\n let body = '';\n res.on('data', (c: string) => (body += c));\n res.on('end', () => resolve(body));\n },\n );\n req.on('error', (err) => {\n reject(new QueryClientError(`Connection failed: ${err.message}`, 'CONNECTION_FAILED'));\n });\n req.write(payload);\n req.end();\n });\n}\n\nfunction parseTrpcResponse(raw: string, procedure: string): unknown {\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new QueryClientError(\n `Invalid JSON from ${procedure}: ${raw.slice(0, 200)}`,\n 'SERVER_ERROR',\n );\n }\n if (parsed.error) {\n const msg =\n typeof parsed.error === 'object' && parsed.error !== null\n ? ((parsed.error as Record<string, unknown>).message ?? JSON.stringify(parsed.error))\n : String(parsed.error);\n throw new QueryClientError(`Server error from ${procedure}: ${msg}`, 'SERVER_ERROR');\n }\n return (parsed.result as Record<string, unknown>)?.data ?? parsed;\n}\n\n// --- Client ---\n\nexport class QueryClient {\n private readonly baseUrl: string;\n\n constructor(options?: QueryClientOptions) {\n const host = options?.host ?? 'localhost';\n const port = options?.port ?? readEditorPort();\n this.baseUrl = `http://${host}:${port}/api/trpc`;\n }\n\n private async query(procedure: string, input?: unknown): Promise<unknown> {\n const qs = input != null ? `?input=${encodeURIComponent(JSON.stringify(input))}` : '';\n const url = `${this.baseUrl}/${procedure}${qs}`;\n const raw = await httpGet(url);\n return parseTrpcResponse(raw, procedure);\n }\n\n private async mutate(procedure: string, input: unknown): Promise<unknown> {\n const url = `${this.baseUrl}/${procedure}`;\n const raw = await httpPost(url, JSON.stringify(input));\n return parseTrpcResponse(raw, procedure);\n }\n\n // --- Public API ---\n\n async getSchema(): Promise<SchemaResult> {\n const data = (await this.query('getSchema')) as Record<string, unknown>;\n return {\n nodeTypes: ((data.nodeTypes as unknown[]) ?? []).map(\n (t) =>\n (typeof t === 'object' && t !== null ? (t as Record<string, unknown>).type : t) as string,\n ),\n edgeTypes: ((data.edgeTypes as unknown[]) ?? []).map((t) => {\n const e = t as Record<string, unknown>;\n return {\n relation: e.axbType as string,\n from: e.aType as string,\n to: e.bType as string,\n inverseLabel: (e.inverseLabel as string) ?? null,\n };\n }),\n };\n }\n\n async getNodeDetail(input: GetNodeDetailInput): Promise<NodeDetailResult> {\n requireString(input.uid, 'uid');\n const data = (await this.query('getNodeDetail', { uid: input.uid })) as Record<string, unknown>;\n return {\n node: summarizeRecord(data.node as Record<string, unknown> | null),\n outEdges: ((data.outEdges as Record<string, unknown>[]) ?? [])\n .map(summarizeEdge)\n .filter(Boolean) as SummarizedEdge[],\n inEdges: ((data.inEdges as Record<string, unknown>[]) ?? [])\n .map(summarizeEdge)\n .filter(Boolean) as SummarizedEdge[],\n };\n }\n\n async getNodes(input: GetNodesInput): Promise<GetNodesResult> {\n const limit = clampInt(input.limit, 1, 200, 25);\n validateSortDir(input.sortDir);\n const data = (await this.query('getNodes', {\n type: input.type,\n limit,\n startAfter: input.startAfter,\n sortBy: input.sortBy,\n sortDir: input.sortDir,\n where: input.where,\n })) as Record<string, unknown>;\n return {\n nodes: ((data.nodes as Record<string, unknown>[]) ?? [])\n .map(summarizeRecord)\n .filter(Boolean) as SummarizedRecord[],\n hasMore: (data.hasMore as boolean) ?? false,\n nextCursor: data.nextCursor as string | null | undefined,\n };\n }\n\n async getEdges(input: GetEdgesInput): Promise<GetEdgesResult> {\n const hasFilter =\n input.aType ||\n input.aUid ||\n input.axbType ||\n input.bType ||\n input.bUid ||\n (input.where && input.where.length > 0);\n if (!hasFilter) {\n throw new QueryClientError(\n 'getEdges requires at least one filter field (aType, aUid, axbType, bType, bUid, or where)',\n 'VALIDATION_ERROR',\n );\n }\n const limit = clampInt(input.limit, 1, 200, 25);\n validateSortDir(input.sortDir);\n const data = (await this.query('getEdges', {\n aType: input.aType,\n aUid: input.aUid,\n axbType: input.axbType,\n bType: input.bType,\n bUid: input.bUid,\n limit,\n startAfter: input.startAfter,\n sortBy: input.sortBy,\n sortDir: input.sortDir,\n where: input.where,\n })) as Record<string, unknown>;\n return {\n edges: ((data.edges as Record<string, unknown>[]) ?? [])\n .map(summarizeEdge)\n .filter(Boolean) as SummarizedEdge[],\n hasMore: (data.hasMore as boolean) ?? false,\n nextCursor: data.nextCursor as string | null | undefined,\n };\n }\n\n async traverse(input: TraverseInput): Promise<TraverseResult> {\n requireString(input.startUid, 'startUid');\n if (!input.hops || input.hops.length === 0) {\n throw new QueryClientError('traverse requires at least one hop', 'VALIDATION_ERROR');\n }\n for (let i = 0; i < input.hops.length; i++) {\n const hop = input.hops[i];\n requireString(hop.axbType, `hops[${i}].axbType`);\n if (hop.direction != null && hop.direction !== 'forward' && hop.direction !== 'reverse') {\n throw new QueryClientError(\n `hops[${i}].direction must be 'forward' or 'reverse'`,\n 'VALIDATION_ERROR',\n );\n }\n if (hop.limit != null && (!Number.isInteger(hop.limit) || hop.limit < 1)) {\n throw new QueryClientError(\n `hops[${i}].limit must be a positive integer`,\n 'VALIDATION_ERROR',\n );\n }\n }\n if (input.maxReads != null && (!Number.isInteger(input.maxReads) || input.maxReads < 1)) {\n throw new QueryClientError('maxReads must be a positive integer', 'VALIDATION_ERROR');\n }\n if (\n input.concurrency != null &&\n (!Number.isInteger(input.concurrency) || input.concurrency < 1)\n ) {\n throw new QueryClientError('concurrency must be a positive integer', 'VALIDATION_ERROR');\n }\n\n const data = (await this.mutate('traverse', input)) as Record<string, unknown>;\n return {\n hops: ((data.hops as Record<string, unknown>[]) ?? []).map(\n (h): TraverseHopResult => ({\n relation: h.axbType as string,\n direction: h.direction as string,\n depth: h.depth as number,\n edgeCount: ((h.edges as unknown[]) ?? []).length,\n edges: ((h.edges as Record<string, unknown>[]) ?? [])\n .map(summarizeEdge)\n .filter(Boolean) as SummarizedEdge[],\n truncated: (h.truncated as boolean) ?? false,\n }),\n ),\n totalReads: (data.totalReads as number) ?? 0,\n truncated: (data.truncated as boolean) ?? false,\n };\n }\n\n async search(input: SearchInput): Promise<SearchResult> {\n requireString(input.q, 'q');\n const limit = clampInt(input.limit, 1, 50, 20);\n const data = (await this.query('search', { q: input.q, limit })) as Record<string, unknown>;\n return {\n results: ((data.results as Record<string, unknown>[]) ?? [])\n .map((r) => {\n const base = summarizeRecord(r);\n if (!base) return null;\n return {\n ...base,\n matchType: (r._matchType as string) ?? null,\n };\n })\n .filter(Boolean) as (SummarizedRecord & { matchType: string | null })[],\n };\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nconst CONFIG_FILES = ['firegraph.config.ts', 'firegraph.config.js', 'firegraph.config.mjs'];\nconst DEFAULT_PORT = 3884;\n\n/**\n * Read the editor port from firegraph config files using regex.\n * Zero-dependency — no jiti needed.\n */\nexport function readEditorPort(cwd?: string): number {\n const dir = cwd ?? process.cwd();\n for (const name of CONFIG_FILES) {\n try {\n const content = readFileSync(join(dir, name), 'utf8');\n const editorBlock = content.match(/editor\\s*:\\s*\\{[^}]*\\}/s)?.[0] ?? '';\n const portMatch = editorBlock.match(/port\\s*:\\s*(\\d+)/);\n if (portMatch) return parseInt(portMatch[1], 10);\n } catch {\n continue;\n }\n }\n return DEFAULT_PORT;\n}\n","import type { SummarizedEdge, SummarizedRecord } from './types.js';\n\nexport function summarizeRecord(r: Record<string, unknown> | null): SummarizedRecord | null {\n if (!r) return null;\n const out: SummarizedRecord = { type: r.aType as string, uid: r.aUid as string };\n const data = r.data as Record<string, unknown> | undefined;\n if (data && typeof data === 'object' && Object.keys(data).length > 0) {\n out.data = data;\n }\n return out;\n}\n\nexport function summarizeEdge(r: Record<string, unknown> | null): SummarizedEdge | null {\n if (!r) return null;\n const out: SummarizedEdge = {\n fromType: r.aType as string,\n fromUid: r.aUid as string,\n relation: r.axbType as string,\n toType: r.bType as string,\n toUid: r.bUid as string,\n };\n const data = r.data as Record<string, unknown> | undefined;\n if (data && typeof data === 'object' && Object.keys(data).length > 0) {\n out.data = data;\n }\n return out;\n}\n","import { QueryClient, QueryClientError } from './client.js';\nimport type { TraverseInput } from './types.js';\n\n// --- Argument parsing ---\n\ninterface ParsedArgs {\n flags: Record<string, string>;\n positional: string[];\n}\n\nfunction parseFlags(args: string[]): ParsedArgs {\n const flags: Record<string, string> = {};\n const positional: string[] = [];\n for (let i = 0; i < args.length; i++) {\n if (args[i].startsWith('--')) {\n const key = args[i].slice(2);\n const next = args[i + 1];\n if (next && !next.startsWith('--')) {\n flags[key] = next;\n i++;\n } else {\n flags[key] = 'true';\n }\n } else {\n positional.push(args[i]);\n }\n }\n return { flags, positional };\n}\n\n// --- CLI runner ---\n\nexport async function runQueryCli(argv: string[]): Promise<void> {\n const command = argv[0];\n const rest = argv.slice(1);\n const { flags, positional } = parseFlags(rest);\n\n const port = flags.port ? parseInt(flags.port, 10) : undefined;\n const host = flags.host ?? undefined;\n const client = new QueryClient({ port, host });\n\n try {\n let result: unknown;\n\n switch (command) {\n case 'schema':\n result = await client.getSchema();\n break;\n\n case 'get':\n if (!positional[0]) {\n die('Usage: firegraph query get <uid>');\n }\n result = await client.getNodeDetail({ uid: positional[0] });\n break;\n\n case 'find-nodes': {\n if (!positional[0]) {\n die('Usage: firegraph query find-nodes <type> [--limit N]');\n }\n result = await client.getNodes({\n type: positional[0],\n limit: flags.limit ? parseInt(flags.limit, 10) : undefined,\n });\n break;\n }\n\n case 'find-edges': {\n result = await client.getEdges({\n aType: flags.aType,\n aUid: flags.aUid,\n axbType: flags.axbType,\n bType: flags.bType,\n bUid: flags.bUid,\n limit: flags.limit ? parseInt(flags.limit, 10) : undefined,\n });\n break;\n }\n\n case 'traverse': {\n const jsonStr = positional.join(' ');\n if (!jsonStr) {\n die(\n \"Usage: firegraph query traverse '<JSON>'\\n\\n\" +\n 'JSON shape:\\n' +\n '{\\n' +\n ' \"startUid\": \"nodeUid\",\\n' +\n ' \"hops\": [\\n' +\n ' {\\n' +\n ' \"axbType\": \"relationName\",\\n' +\n ' \"direction\": \"forward\" | \"reverse\",\\n' +\n ' \"limit\": 10,\\n' +\n ' \"aType\": \"filterSourceType\",\\n' +\n ' \"bType\": \"filterTargetType\",\\n' +\n ' \"orderBy\": { \"field\": \"data.name\", \"direction\": \"asc\" },\\n' +\n ' \"where\": [{ \"field\": \"data.status\", \"op\": \"==\", \"value\": \"active\" }]\\n' +\n ' }\\n' +\n ' ],\\n' +\n ' \"maxReads\": 100,\\n' +\n ' \"concurrency\": 5\\n' +\n '}',\n );\n }\n let input: TraverseInput;\n try {\n input = JSON.parse(jsonStr) as TraverseInput;\n } catch {\n die(`Invalid JSON: ${jsonStr.slice(0, 200)}`);\n }\n result = await client.traverse(input!);\n break;\n }\n\n case 'search':\n if (!positional[0]) {\n die('Usage: firegraph query search <query>');\n }\n result = await client.search({ q: positional.join(' ') });\n break;\n\n case '--help':\n case '-h':\n case undefined:\n printHelp();\n return;\n\n default:\n die(\n `Unknown query command: ${command}\\n` +\n 'Commands: schema, get, find-nodes, find-edges, traverse, search',\n );\n }\n\n console.log(JSON.stringify(result, null, 2));\n } catch (err) {\n if (err instanceof QueryClientError) {\n console.error(JSON.stringify({ error: err.message, code: err.code }));\n } else {\n console.error(JSON.stringify({ error: (err as Error).message }));\n }\n process.exit(1);\n }\n}\n\nfunction printHelp(): void {\n console.log('');\n console.log(' Usage: firegraph query <command> [options]');\n console.log('');\n console.log(' Commands:');\n console.log(' schema Get graph schema (node types + edge types)');\n console.log(' get <uid> Get node detail with edges');\n console.log(' find-nodes <type> [--limit N] List nodes of a type');\n console.log(' find-edges [filters] List edges matching filters');\n console.log(\" traverse '<JSON>' Multi-hop graph traversal\");\n console.log(' search <query> Search nodes by text');\n console.log('');\n console.log(' Global options:');\n console.log(' --port <number> Editor server port (default: auto-detect from config)');\n console.log(' --host <string> Editor server host (default: localhost)');\n console.log('');\n console.log(' find-edges filters:');\n console.log(' --aType <type> Filter by source type');\n console.log(' --aUid <uid> Filter by source UID');\n console.log(' --axbType <rel> Filter by relation type');\n console.log(' --bType <type> Filter by target type');\n console.log(' --bUid <uid> Filter by target UID');\n console.log(' --limit <N> Max results (1-200, default 25)');\n console.log('');\n console.log(' Examples:');\n console.log(' npx firegraph query schema');\n console.log(' npx firegraph query get Kj7vNq2mP9xR4wL1tY8s3');\n console.log(' npx firegraph query find-nodes task --limit 10');\n console.log(' npx firegraph query find-edges --aUid Kj7vNq2mP9xR4wL1tY8s3 --axbType hasTask');\n console.log(' npx firegraph query search \"John Doe\"');\n console.log('');\n}\n\nfunction die(msg: string): never {\n console.error(msg);\n process.exit(1);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,uBAAiB;;;ACAjB,qBAA6B;AAC7B,uBAAqB;AAErB,IAAM,eAAe,CAAC,uBAAuB,uBAAuB,sBAAsB;AAC1F,IAAM,eAAe;AAMd,SAAS,eAAe,KAAsB;AACnD,QAAM,MAAM,OAAO,QAAQ,IAAI;AAC/B,aAAW,QAAQ,cAAc;AAC/B,QAAI;AACF,YAAM,cAAU,iCAAa,uBAAK,KAAK,IAAI,GAAG,MAAM;AACpD,YAAM,cAAc,QAAQ,MAAM,yBAAyB,IAAI,CAAC,KAAK;AACrE,YAAM,YAAY,YAAY,MAAM,kBAAkB;AACtD,UAAI,UAAW,QAAO,SAAS,UAAU,CAAC,GAAG,EAAE;AAAA,IACjD,QAAQ;AACN;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;ACrBO,SAAS,gBAAgB,GAA4D;AAC1F,MAAI,CAAC,EAAG,QAAO;AACf,QAAM,MAAwB,EAAE,MAAM,EAAE,OAAiB,KAAK,EAAE,KAAe;AAC/E,QAAM,OAAO,EAAE;AACf,MAAI,QAAQ,OAAO,SAAS,YAAY,OAAO,KAAK,IAAI,EAAE,SAAS,GAAG;AACpE,QAAI,OAAO;AAAA,EACb;AACA,SAAO;AACT;AAEO,SAAS,cAAc,GAA0D;AACtF,MAAI,CAAC,EAAG,QAAO;AACf,QAAM,MAAsB;AAAA,IAC1B,UAAU,EAAE;AAAA,IACZ,SAAS,EAAE;AAAA,IACX,UAAU,EAAE;AAAA,IACZ,QAAQ,EAAE;AAAA,IACV,OAAO,EAAE;AAAA,EACX;AACA,QAAM,OAAO,EAAE;AACf,MAAI,QAAQ,OAAO,SAAS,YAAY,OAAO,KAAK,IAAI,EAAE,SAAS,GAAG;AACpE,QAAI,OAAO;AAAA,EACb;AACA,SAAO;AACT;;;AFAO,IAAM,mBAAN,cAA+B,MAAM;AAAA,EAC1C,YACE,SACgB,MAChB;AACA,UAAM,OAAO;AAFG;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;AAIA,SAAS,cAAc,OAAgB,MAAuC;AAC5E,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAAG;AACnD,UAAM,IAAI,iBAAiB,GAAG,IAAI,+BAA+B,kBAAkB;AAAA,EACrF;AACF;AAEA,SAAS,SAAS,OAA2B,KAAa,KAAa,UAA0B;AAC/F,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,CAAC,OAAO,UAAU,KAAK,GAAG;AAC5B,UAAM,IAAI,iBAAiB,4BAA4B,kBAAkB;AAAA,EAC3E;AACA,SAAO,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,CAAC;AAC3C;AAEA,SAAS,gBAAgB,KAA+B;AACtD,MAAI,OAAO,QAAQ,QAAQ,SAAS,QAAQ,QAAQ;AAClD,UAAM,IAAI,iBAAiB,mCAAmC,kBAAkB;AAAA,EAClF;AACF;AAIA,SAAS,QAAQ,KAA8B;AAC7C,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,qBAAAA,QACG,IAAI,KAAK,CAAC,QAAQ;AACjB,UAAI,OAAO;AACX,UAAI,GAAG,QAAQ,CAAC,MAAe,QAAQ,CAAE;AACzC,UAAI,GAAG,OAAO,MAAM,QAAQ,IAAI,CAAC;AAAA,IACnC,CAAC,EACA,GAAG,SAAS,CAAC,QAAQ;AACpB,aAAO,IAAI,iBAAiB,sBAAsB,IAAI,OAAO,IAAI,mBAAmB,CAAC;AAAA,IACvF,CAAC;AAAA,EACL,CAAC;AACH;AAEA,SAAS,SAAS,KAAa,SAAkC;AAC/D,QAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,MAAM,iBAAAA,QAAK;AAAA,MACf;AAAA,QACE,UAAU,OAAO;AAAA,QACjB,MAAM,OAAO;AAAA,QACb,MAAM,OAAO;AAAA,QACb,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,kBAAkB,OAAO,WAAW,OAAO;AAAA,QAC7C;AAAA,MACF;AAAA,MACA,CAAC,QAAQ;AACP,YAAI,OAAO;AACX,YAAI,GAAG,QAAQ,CAAC,MAAe,QAAQ,CAAE;AACzC,YAAI,GAAG,OAAO,MAAM,QAAQ,IAAI,CAAC;AAAA,MACnC;AAAA,IACF;AACA,QAAI,GAAG,SAAS,CAAC,QAAQ;AACvB,aAAO,IAAI,iBAAiB,sBAAsB,IAAI,OAAO,IAAI,mBAAmB,CAAC;AAAA,IACvF,CAAC;AACD,QAAI,MAAM,OAAO;AACjB,QAAI,IAAI;AAAA,EACV,CAAC;AACH;AAEA,SAAS,kBAAkB,KAAa,WAA4B;AAClE,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,GAAG;AAAA,EACzB,QAAQ;AACN,UAAM,IAAI;AAAA,MACR,qBAAqB,SAAS,KAAK,IAAI,MAAM,GAAG,GAAG,CAAC;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AACA,MAAI,OAAO,OAAO;AAChB,UAAM,MACJ,OAAO,OAAO,UAAU,YAAY,OAAO,UAAU,OAC/C,OAAO,MAAkC,WAAW,KAAK,UAAU,OAAO,KAAK,IACjF,OAAO,OAAO,KAAK;AACzB,UAAM,IAAI,iBAAiB,qBAAqB,SAAS,KAAK,GAAG,IAAI,cAAc;AAAA,EACrF;AACA,SAAQ,OAAO,QAAoC,QAAQ;AAC7D;AAIO,IAAM,cAAN,MAAkB;AAAA,EACN;AAAA,EAEjB,YAAY,SAA8B;AACxC,UAAM,OAAO,SAAS,QAAQ;AAC9B,UAAM,OAAO,SAAS,QAAQ,eAAe;AAC7C,SAAK,UAAU,UAAU,IAAI,IAAI,IAAI;AAAA,EACvC;AAAA,EAEA,MAAc,MAAM,WAAmB,OAAmC;AACxE,UAAM,KAAK,SAAS,OAAO,UAAU,mBAAmB,KAAK,UAAU,KAAK,CAAC,CAAC,KAAK;AACnF,UAAM,MAAM,GAAG,KAAK,OAAO,IAAI,SAAS,GAAG,EAAE;AAC7C,UAAM,MAAM,MAAM,QAAQ,GAAG;AAC7B,WAAO,kBAAkB,KAAK,SAAS;AAAA,EACzC;AAAA,EAEA,MAAc,OAAO,WAAmB,OAAkC;AACxE,UAAM,MAAM,GAAG,KAAK,OAAO,IAAI,SAAS;AACxC,UAAM,MAAM,MAAM,SAAS,KAAK,KAAK,UAAU,KAAK,CAAC;AACrD,WAAO,kBAAkB,KAAK,SAAS;AAAA,EACzC;AAAA;AAAA,EAIA,MAAM,YAAmC;AACvC,UAAM,OAAQ,MAAM,KAAK,MAAM,WAAW;AAC1C,WAAO;AAAA,MACL,YAAa,KAAK,aAA2B,CAAC,GAAG;AAAA,QAC/C,CAAC,MACE,OAAO,MAAM,YAAY,MAAM,OAAQ,EAA8B,OAAO;AAAA,MACjF;AAAA,MACA,YAAa,KAAK,aAA2B,CAAC,GAAG,IAAI,CAAC,MAAM;AAC1D,cAAM,IAAI;AACV,eAAO;AAAA,UACL,UAAU,EAAE;AAAA,UACZ,MAAM,EAAE;AAAA,UACR,IAAI,EAAE;AAAA,UACN,cAAe,EAAE,gBAA2B;AAAA,QAC9C;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,OAAsD;AACxE,kBAAc,MAAM,KAAK,KAAK;AAC9B,UAAM,OAAQ,MAAM,KAAK,MAAM,iBAAiB,EAAE,KAAK,MAAM,IAAI,CAAC;AAClE,WAAO;AAAA,MACL,MAAM,gBAAgB,KAAK,IAAsC;AAAA,MACjE,WAAY,KAAK,YAA0C,CAAC,GACzD,IAAI,aAAa,EACjB,OAAO,OAAO;AAAA,MACjB,UAAW,KAAK,WAAyC,CAAC,GACvD,IAAI,aAAa,EACjB,OAAO,OAAO;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,OAA+C;AAC5D,UAAM,QAAQ,SAAS,MAAM,OAAO,GAAG,KAAK,EAAE;AAC9C,oBAAgB,MAAM,OAAO;AAC7B,UAAM,OAAQ,MAAM,KAAK,MAAM,YAAY;AAAA,MACzC,MAAM,MAAM;AAAA,MACZ;AAAA,MACA,YAAY,MAAM;AAAA,MAClB,QAAQ,MAAM;AAAA,MACd,SAAS,MAAM;AAAA,MACf,OAAO,MAAM;AAAA,IACf,CAAC;AACD,WAAO;AAAA,MACL,QAAS,KAAK,SAAuC,CAAC,GACnD,IAAI,eAAe,EACnB,OAAO,OAAO;AAAA,MACjB,SAAU,KAAK,WAAuB;AAAA,MACtC,YAAY,KAAK;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,OAA+C;AAC5D,UAAM,YACJ,MAAM,SACN,MAAM,QACN,MAAM,WACN,MAAM,SACN,MAAM,QACL,MAAM,SAAS,MAAM,MAAM,SAAS;AACvC,QAAI,CAAC,WAAW;AACd,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,UAAM,QAAQ,SAAS,MAAM,OAAO,GAAG,KAAK,EAAE;AAC9C,oBAAgB,MAAM,OAAO;AAC7B,UAAM,OAAQ,MAAM,KAAK,MAAM,YAAY;AAAA,MACzC,OAAO,MAAM;AAAA,MACb,MAAM,MAAM;AAAA,MACZ,SAAS,MAAM;AAAA,MACf,OAAO,MAAM;AAAA,MACb,MAAM,MAAM;AAAA,MACZ;AAAA,MACA,YAAY,MAAM;AAAA,MAClB,QAAQ,MAAM;AAAA,MACd,SAAS,MAAM;AAAA,MACf,OAAO,MAAM;AAAA,IACf,CAAC;AACD,WAAO;AAAA,MACL,QAAS,KAAK,SAAuC,CAAC,GACnD,IAAI,aAAa,EACjB,OAAO,OAAO;AAAA,MACjB,SAAU,KAAK,WAAuB;AAAA,MACtC,YAAY,KAAK;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,OAA+C;AAC5D,kBAAc,MAAM,UAAU,UAAU;AACxC,QAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,WAAW,GAAG;AAC1C,YAAM,IAAI,iBAAiB,sCAAsC,kBAAkB;AAAA,IACrF;AACA,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK,QAAQ,KAAK;AAC1C,YAAM,MAAM,MAAM,KAAK,CAAC;AACxB,oBAAc,IAAI,SAAS,QAAQ,CAAC,WAAW;AAC/C,UAAI,IAAI,aAAa,QAAQ,IAAI,cAAc,aAAa,IAAI,cAAc,WAAW;AACvF,cAAM,IAAI;AAAA,UACR,QAAQ,CAAC;AAAA,UACT;AAAA,QACF;AAAA,MACF;AACA,UAAI,IAAI,SAAS,SAAS,CAAC,OAAO,UAAU,IAAI,KAAK,KAAK,IAAI,QAAQ,IAAI;AACxE,cAAM,IAAI;AAAA,UACR,QAAQ,CAAC;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,QAAI,MAAM,YAAY,SAAS,CAAC,OAAO,UAAU,MAAM,QAAQ,KAAK,MAAM,WAAW,IAAI;AACvF,YAAM,IAAI,iBAAiB,uCAAuC,kBAAkB;AAAA,IACtF;AACA,QACE,MAAM,eAAe,SACpB,CAAC,OAAO,UAAU,MAAM,WAAW,KAAK,MAAM,cAAc,IAC7D;AACA,YAAM,IAAI,iBAAiB,0CAA0C,kBAAkB;AAAA,IACzF;AAEA,UAAM,OAAQ,MAAM,KAAK,OAAO,YAAY,KAAK;AACjD,WAAO;AAAA,MACL,OAAQ,KAAK,QAAsC,CAAC,GAAG;AAAA,QACrD,CAAC,OAA0B;AAAA,UACzB,UAAU,EAAE;AAAA,UACZ,WAAW,EAAE;AAAA,UACb,OAAO,EAAE;AAAA,UACT,YAAa,EAAE,SAAuB,CAAC,GAAG;AAAA,UAC1C,QAAS,EAAE,SAAuC,CAAC,GAChD,IAAI,aAAa,EACjB,OAAO,OAAO;AAAA,UACjB,WAAY,EAAE,aAAyB;AAAA,QACzC;AAAA,MACF;AAAA,MACA,YAAa,KAAK,cAAyB;AAAA,MAC3C,WAAY,KAAK,aAAyB;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,OAA2C;AACtD,kBAAc,MAAM,GAAG,GAAG;AAC1B,UAAM,QAAQ,SAAS,MAAM,OAAO,GAAG,IAAI,EAAE;AAC7C,UAAM,OAAQ,MAAM,KAAK,MAAM,UAAU,EAAE,GAAG,MAAM,GAAG,MAAM,CAAC;AAC9D,WAAO;AAAA,MACL,UAAW,KAAK,WAAyC,CAAC,GACvD,IAAI,CAAC,MAAM;AACV,cAAM,OAAO,gBAAgB,CAAC;AAC9B,YAAI,CAAC,KAAM,QAAO;AAClB,eAAO;AAAA,UACL,GAAG;AAAA,UACH,WAAY,EAAE,cAAyB;AAAA,QACzC;AAAA,MACF,CAAC,EACA,OAAO,OAAO;AAAA,IACnB;AAAA,EACF;AACF;;;AGvSA,SAAS,WAAW,MAA4B;AAC9C,QAAM,QAAgC,CAAC;AACvC,QAAM,aAAuB,CAAC;AAC9B,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,KAAK,CAAC,EAAE,WAAW,IAAI,GAAG;AAC5B,YAAM,MAAM,KAAK,CAAC,EAAE,MAAM,CAAC;AAC3B,YAAM,OAAO,KAAK,IAAI,CAAC;AACvB,UAAI,QAAQ,CAAC,KAAK,WAAW,IAAI,GAAG;AAClC,cAAM,GAAG,IAAI;AACb;AAAA,MACF,OAAO;AACL,cAAM,GAAG,IAAI;AAAA,MACf;AAAA,IACF,OAAO;AACL,iBAAW,KAAK,KAAK,CAAC,CAAC;AAAA,IACzB;AAAA,EACF;AACA,SAAO,EAAE,OAAO,WAAW;AAC7B;AAIA,eAAsB,YAAY,MAA+B;AAC/D,QAAM,UAAU,KAAK,CAAC;AACtB,QAAM,OAAO,KAAK,MAAM,CAAC;AACzB,QAAM,EAAE,OAAO,WAAW,IAAI,WAAW,IAAI;AAE7C,QAAM,OAAO,MAAM,OAAO,SAAS,MAAM,MAAM,EAAE,IAAI;AACrD,QAAM,OAAO,MAAM,QAAQ;AAC3B,QAAM,SAAS,IAAI,YAAY,EAAE,MAAM,KAAK,CAAC;AAE7C,MAAI;AACF,QAAI;AAEJ,YAAQ,SAAS;AAAA,MACf,KAAK;AACH,iBAAS,MAAM,OAAO,UAAU;AAChC;AAAA,MAEF,KAAK;AACH,YAAI,CAAC,WAAW,CAAC,GAAG;AAClB,cAAI,kCAAkC;AAAA,QACxC;AACA,iBAAS,MAAM,OAAO,cAAc,EAAE,KAAK,WAAW,CAAC,EAAE,CAAC;AAC1D;AAAA,MAEF,KAAK,cAAc;AACjB,YAAI,CAAC,WAAW,CAAC,GAAG;AAClB,cAAI,sDAAsD;AAAA,QAC5D;AACA,iBAAS,MAAM,OAAO,SAAS;AAAA,UAC7B,MAAM,WAAW,CAAC;AAAA,UAClB,OAAO,MAAM,QAAQ,SAAS,MAAM,OAAO,EAAE,IAAI;AAAA,QACnD,CAAC;AACD;AAAA,MACF;AAAA,MAEA,KAAK,cAAc;AACjB,iBAAS,MAAM,OAAO,SAAS;AAAA,UAC7B,OAAO,MAAM;AAAA,UACb,MAAM,MAAM;AAAA,UACZ,SAAS,MAAM;AAAA,UACf,OAAO,MAAM;AAAA,UACb,MAAM,MAAM;AAAA,UACZ,OAAO,MAAM,QAAQ,SAAS,MAAM,OAAO,EAAE,IAAI;AAAA,QACnD,CAAC;AACD;AAAA,MACF;AAAA,MAEA,KAAK,YAAY;AACf,cAAM,UAAU,WAAW,KAAK,GAAG;AACnC,YAAI,CAAC,SAAS;AACZ;AAAA,YACE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAkBF;AAAA,QACF;AACA,YAAI;AACJ,YAAI;AACF,kBAAQ,KAAK,MAAM,OAAO;AAAA,QAC5B,QAAQ;AACN,cAAI,iBAAiB,QAAQ,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,QAC9C;AACA,iBAAS,MAAM,OAAO,SAAS,KAAM;AACrC;AAAA,MACF;AAAA,MAEA,KAAK;AACH,YAAI,CAAC,WAAW,CAAC,GAAG;AAClB,cAAI,uCAAuC;AAAA,QAC7C;AACA,iBAAS,MAAM,OAAO,OAAO,EAAE,GAAG,WAAW,KAAK,GAAG,EAAE,CAAC;AACxD;AAAA,MAEF,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,kBAAU;AACV;AAAA,MAEF;AACE;AAAA,UACE,0BAA0B,OAAO;AAAA;AAAA,QAEnC;AAAA,IACJ;AAEA,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C,SAAS,KAAK;AACZ,QAAI,eAAe,kBAAkB;AACnC,cAAQ,MAAM,KAAK,UAAU,EAAE,OAAO,IAAI,SAAS,MAAM,IAAI,KAAK,CAAC,CAAC;AAAA,IACtE,OAAO;AACL,cAAQ,MAAM,KAAK,UAAU,EAAE,OAAQ,IAAc,QAAQ,CAAC,CAAC;AAAA,IACjE;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEA,SAAS,YAAkB;AACzB,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,8CAA8C;AAC1D,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,aAAa;AACzB,UAAQ,IAAI,gFAAgF;AAC5F,UAAQ,IAAI,gEAAgE;AAC5E,UAAQ,IAAI,0DAA0D;AACtE,UAAQ,IAAI,iEAAiE;AAC7E,UAAQ,IAAI,+DAA+D;AAC3E,UAAQ,IAAI,0DAA0D;AACtE,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,mBAAmB;AAC/B,UAAQ,IAAI,6EAA6E;AACzF,UAAQ,IAAI,+DAA+D;AAC3E,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,uBAAuB;AACnC,UAAQ,IAAI,6CAA6C;AACzD,UAAQ,IAAI,4CAA4C;AACxD,UAAQ,IAAI,+CAA+C;AAC3D,UAAQ,IAAI,6CAA6C;AACzD,UAAQ,IAAI,4CAA4C;AACxD,UAAQ,IAAI,uDAAuD;AACnE,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,aAAa;AACzB,UAAQ,IAAI,gCAAgC;AAC5C,UAAQ,IAAI,mDAAmD;AAC/D,UAAQ,IAAI,oDAAoD;AAChE,UAAQ,IAAI,mFAAmF;AAC/F,UAAQ,IAAI,2CAA2C;AACvD,UAAQ,IAAI,EAAE;AAChB;AAEA,SAAS,IAAI,KAAoB;AAC/B,UAAQ,MAAM,GAAG;AACjB,UAAQ,KAAK,CAAC;AAChB;","names":["http"]}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { S as StoredGraphRecord, i as QueryFilter, y as QueryOptions, e as GraphReader, m as BulkOptions, C as CascadeResult, F as FindEdgesParams, o as BulkResult } from './types-DfWVTsMn.js';
|
|
2
|
-
|
|
3
1
|
declare class FiregraphError extends Error {
|
|
4
2
|
readonly code: string;
|
|
5
3
|
constructor(message: string, code: string);
|
|
@@ -39,9 +37,10 @@ declare class MigrationError extends FiregraphError {
|
|
|
39
37
|
* Thrown when a caller tries to perform an operation that would require
|
|
40
38
|
* atomicity across two physical storage backends — e.g. opening a routed
|
|
41
39
|
* subgraph client from inside a transaction callback. Cross-backend
|
|
42
|
-
* atomicity cannot be honoured by
|
|
43
|
-
* SQLite,
|
|
44
|
-
* of silently confining the write to the
|
|
40
|
+
* atomicity cannot be honoured by real-world storage engines (Firestore,
|
|
41
|
+
* SQLite drivers over D1/DO/better-sqlite3, etc.), so firegraph surfaces
|
|
42
|
+
* this as a typed error instead of silently confining the write to the
|
|
43
|
+
* base backend.
|
|
45
44
|
*
|
|
46
45
|
* Normally `TransactionBackend` and `BatchBackend` don't expose `subgraph()`
|
|
47
46
|
* at the type level, so this error is unreachable through well-typed code.
|
|
@@ -54,100 +53,6 @@ declare class CrossBackendTransactionError extends FiregraphError {
|
|
|
54
53
|
constructor(message: string);
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
/**
|
|
58
|
-
* Backend abstraction for firegraph.
|
|
59
|
-
*
|
|
60
|
-
* `StorageBackend` is the single interface every storage driver implements.
|
|
61
|
-
* The Firestore backend wraps `@google-cloud/firestore`; the SQLite backend
|
|
62
|
-
* (shared by D1 and Durable Object SQLite) uses a parameterized SQL executor.
|
|
63
|
-
*
|
|
64
|
-
* `GraphClientImpl` and friends depend only on this interface — they have
|
|
65
|
-
* no direct knowledge of Firestore or SQLite.
|
|
66
|
-
*/
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Per-record write payload — backend-agnostic. Timestamps are not present;
|
|
70
|
-
* the backend supplies them via `serverTimestamp()` placeholders that it
|
|
71
|
-
* itself resolves at commit time.
|
|
72
|
-
*/
|
|
73
|
-
interface WritableRecord {
|
|
74
|
-
aType: string;
|
|
75
|
-
aUid: string;
|
|
76
|
-
axbType: string;
|
|
77
|
-
bType: string;
|
|
78
|
-
bUid: string;
|
|
79
|
-
data: Record<string, unknown>;
|
|
80
|
-
/** Schema version (set by the writer when registry has migrations). */
|
|
81
|
-
v?: number;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Patch shape for `updateDoc`. Captures the two patterns that exist today:
|
|
85
|
-
* - `dataFields`: shallow merge under `data` (used by `updateNode`)
|
|
86
|
-
* - `replaceData`: full data replacement (used by migration write-back)
|
|
87
|
-
* - `v`: optional schema-version stamp
|
|
88
|
-
*
|
|
89
|
-
* `updatedAt` is always set by the backend.
|
|
90
|
-
*/
|
|
91
|
-
interface UpdatePayload {
|
|
92
|
-
dataFields?: Record<string, unknown>;
|
|
93
|
-
replaceData?: Record<string, unknown>;
|
|
94
|
-
v?: number;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Read/write transaction adapter. Mirrors Firestore's transaction semantics:
|
|
98
|
-
* reads are snapshot-consistent; writes are issued inside the transaction
|
|
99
|
-
* and a rejection from any write aborts the surrounding `runTransaction`.
|
|
100
|
-
*
|
|
101
|
-
* Writes return `Promise<void>` so SQL drivers can surface row-level errors
|
|
102
|
-
* (constraint violations, malformed JSON paths) rather than swallowing them.
|
|
103
|
-
* Firestore implementations can resolve synchronously since the underlying
|
|
104
|
-
* `Transaction.set/update/delete` calls are themselves synchronous buffers.
|
|
105
|
-
*/
|
|
106
|
-
interface TransactionBackend {
|
|
107
|
-
getDoc(docId: string): Promise<StoredGraphRecord | null>;
|
|
108
|
-
query(filters: QueryFilter[], options?: QueryOptions): Promise<StoredGraphRecord[]>;
|
|
109
|
-
setDoc(docId: string, record: WritableRecord): Promise<void>;
|
|
110
|
-
updateDoc(docId: string, update: UpdatePayload): Promise<void>;
|
|
111
|
-
deleteDoc(docId: string): Promise<void>;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Atomic multi-write batch.
|
|
115
|
-
*/
|
|
116
|
-
interface BatchBackend {
|
|
117
|
-
setDoc(docId: string, record: WritableRecord): void;
|
|
118
|
-
updateDoc(docId: string, update: UpdatePayload): void;
|
|
119
|
-
deleteDoc(docId: string): void;
|
|
120
|
-
commit(): Promise<void>;
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* The single storage abstraction.
|
|
124
|
-
*
|
|
125
|
-
* Each backend instance is scoped to a "graph location" — for Firestore
|
|
126
|
-
* that's a collection path; for SQLite it's a (table, scopePath) pair.
|
|
127
|
-
* `subgraph()` returns a child backend bound to a nested location.
|
|
128
|
-
*/
|
|
129
|
-
interface StorageBackend {
|
|
130
|
-
/** Backend-internal location identifier (collection path or table name). */
|
|
131
|
-
readonly collectionPath: string;
|
|
132
|
-
/** Subgraph scope (empty string for root). */
|
|
133
|
-
readonly scopePath: string;
|
|
134
|
-
getDoc(docId: string): Promise<StoredGraphRecord | null>;
|
|
135
|
-
query(filters: QueryFilter[], options?: QueryOptions): Promise<StoredGraphRecord[]>;
|
|
136
|
-
setDoc(docId: string, record: WritableRecord): Promise<void>;
|
|
137
|
-
updateDoc(docId: string, update: UpdatePayload): Promise<void>;
|
|
138
|
-
deleteDoc(docId: string): Promise<void>;
|
|
139
|
-
runTransaction<T>(fn: (tx: TransactionBackend) => Promise<T>): Promise<T>;
|
|
140
|
-
createBatch(): BatchBackend;
|
|
141
|
-
subgraph(parentNodeUid: string, name: string): StorageBackend;
|
|
142
|
-
removeNodeCascade(uid: string, reader: GraphReader, options?: BulkOptions): Promise<CascadeResult>;
|
|
143
|
-
bulkRemoveEdges(params: FindEdgesParams, reader: GraphReader, options?: BulkOptions): Promise<BulkResult>;
|
|
144
|
-
/**
|
|
145
|
-
* Find edges across all subgraphs sharing a given collection name.
|
|
146
|
-
* Optional — backends that can't support this should throw a clear error.
|
|
147
|
-
*/
|
|
148
|
-
findEdgesGlobal?(params: FindEdgesParams, collectionName?: string): Promise<StoredGraphRecord[]>;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
56
|
/**
|
|
152
57
|
* Storage-scope path utilities — materialized-path parsing helpers for the
|
|
153
58
|
* SQLite backend's `storageScope` string and for any custom backend that
|
|
@@ -231,4 +136,4 @@ declare function isAncestorScopeUid(storageScope: string, uid: string): boolean;
|
|
|
231
136
|
*/
|
|
232
137
|
declare function appendStorageScope(parentScope: string, uid: string, name: string): string;
|
|
233
138
|
|
|
234
|
-
export {
|
|
139
|
+
export { CrossBackendTransactionError as C, DynamicRegistryError as D, EdgeNotFoundError as E, FiregraphError as F, InvalidQueryError as I, MigrationError as M, NodeNotFoundError as N, QuerySafetyError as Q, RegistryScopeError as R, type StorageScopeSegment as S, TraversalError as T, ValidationError as V, appendStorageScope as a, RegistryViolationError as b, isAncestorScopeUid as i, parseStorageScope as p, resolveAncestorScope as r };
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { S as StoredGraphRecord, i as QueryFilter, y as QueryOptions, e as GraphReader, m as BulkOptions, C as CascadeResult, F as FindEdgesParams, o as BulkResult } from './types-DfWVTsMn.cjs';
|
|
2
|
-
|
|
3
1
|
declare class FiregraphError extends Error {
|
|
4
2
|
readonly code: string;
|
|
5
3
|
constructor(message: string, code: string);
|
|
@@ -39,9 +37,10 @@ declare class MigrationError extends FiregraphError {
|
|
|
39
37
|
* Thrown when a caller tries to perform an operation that would require
|
|
40
38
|
* atomicity across two physical storage backends — e.g. opening a routed
|
|
41
39
|
* subgraph client from inside a transaction callback. Cross-backend
|
|
42
|
-
* atomicity cannot be honoured by
|
|
43
|
-
* SQLite,
|
|
44
|
-
* of silently confining the write to the
|
|
40
|
+
* atomicity cannot be honoured by real-world storage engines (Firestore,
|
|
41
|
+
* SQLite drivers over D1/DO/better-sqlite3, etc.), so firegraph surfaces
|
|
42
|
+
* this as a typed error instead of silently confining the write to the
|
|
43
|
+
* base backend.
|
|
45
44
|
*
|
|
46
45
|
* Normally `TransactionBackend` and `BatchBackend` don't expose `subgraph()`
|
|
47
46
|
* at the type level, so this error is unreachable through well-typed code.
|
|
@@ -54,100 +53,6 @@ declare class CrossBackendTransactionError extends FiregraphError {
|
|
|
54
53
|
constructor(message: string);
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
/**
|
|
58
|
-
* Backend abstraction for firegraph.
|
|
59
|
-
*
|
|
60
|
-
* `StorageBackend` is the single interface every storage driver implements.
|
|
61
|
-
* The Firestore backend wraps `@google-cloud/firestore`; the SQLite backend
|
|
62
|
-
* (shared by D1 and Durable Object SQLite) uses a parameterized SQL executor.
|
|
63
|
-
*
|
|
64
|
-
* `GraphClientImpl` and friends depend only on this interface — they have
|
|
65
|
-
* no direct knowledge of Firestore or SQLite.
|
|
66
|
-
*/
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Per-record write payload — backend-agnostic. Timestamps are not present;
|
|
70
|
-
* the backend supplies them via `serverTimestamp()` placeholders that it
|
|
71
|
-
* itself resolves at commit time.
|
|
72
|
-
*/
|
|
73
|
-
interface WritableRecord {
|
|
74
|
-
aType: string;
|
|
75
|
-
aUid: string;
|
|
76
|
-
axbType: string;
|
|
77
|
-
bType: string;
|
|
78
|
-
bUid: string;
|
|
79
|
-
data: Record<string, unknown>;
|
|
80
|
-
/** Schema version (set by the writer when registry has migrations). */
|
|
81
|
-
v?: number;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Patch shape for `updateDoc`. Captures the two patterns that exist today:
|
|
85
|
-
* - `dataFields`: shallow merge under `data` (used by `updateNode`)
|
|
86
|
-
* - `replaceData`: full data replacement (used by migration write-back)
|
|
87
|
-
* - `v`: optional schema-version stamp
|
|
88
|
-
*
|
|
89
|
-
* `updatedAt` is always set by the backend.
|
|
90
|
-
*/
|
|
91
|
-
interface UpdatePayload {
|
|
92
|
-
dataFields?: Record<string, unknown>;
|
|
93
|
-
replaceData?: Record<string, unknown>;
|
|
94
|
-
v?: number;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Read/write transaction adapter. Mirrors Firestore's transaction semantics:
|
|
98
|
-
* reads are snapshot-consistent; writes are issued inside the transaction
|
|
99
|
-
* and a rejection from any write aborts the surrounding `runTransaction`.
|
|
100
|
-
*
|
|
101
|
-
* Writes return `Promise<void>` so SQL drivers can surface row-level errors
|
|
102
|
-
* (constraint violations, malformed JSON paths) rather than swallowing them.
|
|
103
|
-
* Firestore implementations can resolve synchronously since the underlying
|
|
104
|
-
* `Transaction.set/update/delete` calls are themselves synchronous buffers.
|
|
105
|
-
*/
|
|
106
|
-
interface TransactionBackend {
|
|
107
|
-
getDoc(docId: string): Promise<StoredGraphRecord | null>;
|
|
108
|
-
query(filters: QueryFilter[], options?: QueryOptions): Promise<StoredGraphRecord[]>;
|
|
109
|
-
setDoc(docId: string, record: WritableRecord): Promise<void>;
|
|
110
|
-
updateDoc(docId: string, update: UpdatePayload): Promise<void>;
|
|
111
|
-
deleteDoc(docId: string): Promise<void>;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Atomic multi-write batch.
|
|
115
|
-
*/
|
|
116
|
-
interface BatchBackend {
|
|
117
|
-
setDoc(docId: string, record: WritableRecord): void;
|
|
118
|
-
updateDoc(docId: string, update: UpdatePayload): void;
|
|
119
|
-
deleteDoc(docId: string): void;
|
|
120
|
-
commit(): Promise<void>;
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* The single storage abstraction.
|
|
124
|
-
*
|
|
125
|
-
* Each backend instance is scoped to a "graph location" — for Firestore
|
|
126
|
-
* that's a collection path; for SQLite it's a (table, scopePath) pair.
|
|
127
|
-
* `subgraph()` returns a child backend bound to a nested location.
|
|
128
|
-
*/
|
|
129
|
-
interface StorageBackend {
|
|
130
|
-
/** Backend-internal location identifier (collection path or table name). */
|
|
131
|
-
readonly collectionPath: string;
|
|
132
|
-
/** Subgraph scope (empty string for root). */
|
|
133
|
-
readonly scopePath: string;
|
|
134
|
-
getDoc(docId: string): Promise<StoredGraphRecord | null>;
|
|
135
|
-
query(filters: QueryFilter[], options?: QueryOptions): Promise<StoredGraphRecord[]>;
|
|
136
|
-
setDoc(docId: string, record: WritableRecord): Promise<void>;
|
|
137
|
-
updateDoc(docId: string, update: UpdatePayload): Promise<void>;
|
|
138
|
-
deleteDoc(docId: string): Promise<void>;
|
|
139
|
-
runTransaction<T>(fn: (tx: TransactionBackend) => Promise<T>): Promise<T>;
|
|
140
|
-
createBatch(): BatchBackend;
|
|
141
|
-
subgraph(parentNodeUid: string, name: string): StorageBackend;
|
|
142
|
-
removeNodeCascade(uid: string, reader: GraphReader, options?: BulkOptions): Promise<CascadeResult>;
|
|
143
|
-
bulkRemoveEdges(params: FindEdgesParams, reader: GraphReader, options?: BulkOptions): Promise<BulkResult>;
|
|
144
|
-
/**
|
|
145
|
-
* Find edges across all subgraphs sharing a given collection name.
|
|
146
|
-
* Optional — backends that can't support this should throw a clear error.
|
|
147
|
-
*/
|
|
148
|
-
findEdgesGlobal?(params: FindEdgesParams, collectionName?: string): Promise<StoredGraphRecord[]>;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
56
|
/**
|
|
152
57
|
* Storage-scope path utilities — materialized-path parsing helpers for the
|
|
153
58
|
* SQLite backend's `storageScope` string and for any custom backend that
|
|
@@ -231,4 +136,4 @@ declare function isAncestorScopeUid(storageScope: string, uid: string): boolean;
|
|
|
231
136
|
*/
|
|
232
137
|
declare function appendStorageScope(parentScope: string, uid: string, name: string): string;
|
|
233
138
|
|
|
234
|
-
export {
|
|
139
|
+
export { CrossBackendTransactionError as C, DynamicRegistryError as D, EdgeNotFoundError as E, FiregraphError as F, InvalidQueryError as I, MigrationError as M, NodeNotFoundError as N, QuerySafetyError as Q, RegistryScopeError as R, type StorageScopeSegment as S, TraversalError as T, ValidationError as V, appendStorageScope as a, RegistryViolationError as b, isAncestorScopeUid as i, parseStorageScope as p, resolveAncestorScope as r };
|
|
@@ -242,6 +242,66 @@ interface StoredMigrationStep {
|
|
|
242
242
|
type MigrationExecutor = (source: string) => MigrationFn;
|
|
243
243
|
/** Write-back mode for auto-migrated records. */
|
|
244
244
|
type MigrationWriteBack = 'off' | 'eager' | 'background';
|
|
245
|
+
/**
|
|
246
|
+
* One field in a composite index. The string shorthand form defaults to
|
|
247
|
+
* ascending order; use the object form when a field needs to be indexed
|
|
248
|
+
* descending (e.g., pagination by `{ path: 'updatedAt', desc: true }`).
|
|
249
|
+
*/
|
|
250
|
+
interface IndexFieldSpec {
|
|
251
|
+
/**
|
|
252
|
+
* Field path. Top-level firegraph fields (`aType`, `aUid`, `axbType`,
|
|
253
|
+
* `bType`, `bUid`, `createdAt`, `updatedAt`, `v`) resolve to their
|
|
254
|
+
* underlying columns. Dotted paths like `'data.status'` or
|
|
255
|
+
* `'data.author.name'` index into the JSON data payload.
|
|
256
|
+
*
|
|
257
|
+
* Each dotted component must match `/^[A-Za-z_][A-Za-z0-9_-]*$/` — keys
|
|
258
|
+
* with dots, quotes, brackets, spaces, or other syntax characters are
|
|
259
|
+
* rejected at DDL build time. Indexes on exotic keys are not supported
|
|
260
|
+
* because SQLite expression indexes must match the query compiler's
|
|
261
|
+
* output verbatim, and inlining quoted path components into DDL would
|
|
262
|
+
* desynchronize the two compilers. If you need to filter by an exotic
|
|
263
|
+
* key, use `replaceData` writes rather than an indexed field.
|
|
264
|
+
*/
|
|
265
|
+
path: string;
|
|
266
|
+
/** Descending order; defaults to ascending. */
|
|
267
|
+
desc?: boolean;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Declarative secondary index. Translators emit a `CREATE INDEX` statement
|
|
271
|
+
* (SQLite) or a `FirestoreIndex` composite (Firestore) per spec.
|
|
272
|
+
*
|
|
273
|
+
* Composite indexes support the prefix of their `fields` list — a spec
|
|
274
|
+
* `{ fields: ['aType', 'axbType'] }` also covers queries filtering on
|
|
275
|
+
* `aType` alone.
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* ```ts
|
|
279
|
+
* // Plain composite on top-level fields
|
|
280
|
+
* { fields: ['aType', 'axbType'] }
|
|
281
|
+
*
|
|
282
|
+
* // Mixed string + object form; `updatedAt` descending
|
|
283
|
+
* { fields: ['aType', 'aUid', 'axbType', { path: 'updatedAt', desc: true }] }
|
|
284
|
+
*
|
|
285
|
+
* // JSON data-field index (SQLite: expression index on json_extract)
|
|
286
|
+
* { fields: ['aType', 'axbType', 'data.status'] }
|
|
287
|
+
*
|
|
288
|
+
* // Partial index (SQLite only — Firestore ignores the `where` clause)
|
|
289
|
+
* { fields: ['aType'], where: "json_extract(data, '$.archived') = 0" }
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
interface IndexSpec {
|
|
293
|
+
/**
|
|
294
|
+
* Ordered field list. String shorthand = ascending. Use `IndexFieldSpec`
|
|
295
|
+
* form to mark individual fields descending.
|
|
296
|
+
*/
|
|
297
|
+
fields: Array<string | IndexFieldSpec>;
|
|
298
|
+
/**
|
|
299
|
+
* Partial-index predicate. Applied verbatim after `WHERE` in the emitted
|
|
300
|
+
* SQLite DDL. Ignored (with a one-time warning) by the Firestore
|
|
301
|
+
* generator — Firestore composite indexes do not support predicates.
|
|
302
|
+
*/
|
|
303
|
+
where?: string;
|
|
304
|
+
}
|
|
245
305
|
interface RegistryEntry {
|
|
246
306
|
aType: string;
|
|
247
307
|
axbType: string;
|
|
@@ -305,6 +365,18 @@ interface RegistryEntry {
|
|
|
305
365
|
* Omit to inherit the global setting.
|
|
306
366
|
*/
|
|
307
367
|
migrationWriteBack?: MigrationWriteBack;
|
|
368
|
+
/**
|
|
369
|
+
* Secondary indexes tied to this triple. Each spec becomes a single
|
|
370
|
+
* backend-native composite index scoped to rows matching
|
|
371
|
+
* `(aType, axbType, bType)` — though the DDL does not currently restrict
|
|
372
|
+
* by triple, so authors should think of these as globally-applied indexes
|
|
373
|
+
* declared on the triple's behalf.
|
|
374
|
+
*
|
|
375
|
+
* Use this to accelerate `findNodes` / `findEdges` queries that filter
|
|
376
|
+
* on `data.*` fields or compose with firegraph's top-level fields in ways
|
|
377
|
+
* the default preset doesn't cover.
|
|
378
|
+
*/
|
|
379
|
+
indexes?: IndexSpec[];
|
|
308
380
|
}
|
|
309
381
|
/** Topology declaration for an edge (from edge.json). */
|
|
310
382
|
interface EdgeTopology {
|
|
@@ -344,6 +416,8 @@ interface DiscoveredEntity {
|
|
|
344
416
|
migrations?: MigrationStep[];
|
|
345
417
|
/** Per-entity write-back override from meta.json. */
|
|
346
418
|
migrationWriteBack?: MigrationWriteBack;
|
|
419
|
+
/** Secondary indexes loaded from meta.json (`indexes` field). */
|
|
420
|
+
indexes?: IndexSpec[];
|
|
347
421
|
}
|
|
348
422
|
/** Result of scanning an entities directory. */
|
|
349
423
|
interface DiscoveryResult {
|
|
@@ -482,6 +556,23 @@ interface GraphRegistry {
|
|
|
482
556
|
lookup(aType: string, axbType: string, bType: string): RegistryEntry | undefined;
|
|
483
557
|
/** Return all entries matching the given axbType (edge relation name). */
|
|
484
558
|
lookupByAxbType(axbType: string): ReadonlyArray<RegistryEntry>;
|
|
559
|
+
/**
|
|
560
|
+
* Return every edge entry originating from `aType` that has `targetGraph`
|
|
561
|
+
* set — i.e. the direct subgraph children of nodes of this type.
|
|
562
|
+
*
|
|
563
|
+
* Used by backends that need to enumerate a node's subgraph DOs without
|
|
564
|
+
* walking the graph. Each returned entry carries both `axbType` (the edge
|
|
565
|
+
* label that introduces the subgraph) and `targetGraph` (the subgraph
|
|
566
|
+
* segment name).
|
|
567
|
+
*
|
|
568
|
+
* Entries are deduplicated by `targetGraph` alone — the physical subgraph
|
|
569
|
+
* store is addressed by `(parentUid, targetGraph)`, so multiple edge
|
|
570
|
+
* relations (distinct `axbType` or `bType`) pointing into the same segment
|
|
571
|
+
* collapse to a single representative entry. The first-declared entry
|
|
572
|
+
* wins the collision. Callers only care about the subgraph name, not the
|
|
573
|
+
* originating relation or target node type.
|
|
574
|
+
*/
|
|
575
|
+
getSubgraphTopology(aType: string): ReadonlyArray<RegistryEntry>;
|
|
485
576
|
entries(): ReadonlyArray<RegistryEntry>;
|
|
486
577
|
}
|
|
487
578
|
interface GraphReader {
|
|
@@ -642,4 +733,4 @@ interface CascadeResult extends BulkResult {
|
|
|
642
733
|
nodeDeleted: boolean;
|
|
643
734
|
}
|
|
644
735
|
|
|
645
|
-
export { type
|
|
736
|
+
export { type ScanProtection as A, type BulkBatchError as B, type CascadeResult as C, type DynamicGraphClient as D, type EdgeTopology as E, type FindEdgesParams as F, type GraphClientOptions as G, type HopDefinition as H, type IndexSpec as I, type TraversalOptions as J, type TraversalResult as K, type ViewDefaultsConfig as L, type MigrationExecutor as M, type NodeTypeData as N, type ViewResolverConfig as O, defineConfig as P, type QueryPlan as Q, type RegistryEntry as R, type StoredGraphRecord as S, type TraversalBuilder as T, resolveView as U, type ViewContext as V, type WhereClause as W, type GraphClient as a, type DiscoveryResult as b, type GraphRegistry as c, type GraphReader as d, type DynamicRegistryConfig as e, type MigrationWriteBack as f, type MigrationStep as g, type FindNodesParams as h, type QueryFilter as i, type GraphRecord as j, type MigrationFn as k, type StoredMigrationStep as l, type BulkOptions as m, type BulkProgress as n, type BulkResult as o, type DefineTypeOptions as p, type DiscoveredEntity as q, type EdgeTypeData as r, type FiregraphConfig as s, type GraphBatch as t, type GraphTransaction as u, type GraphWriter as v, type HopResult as w, type IndexFieldSpec as x, type QueryMode as y, type QueryOptions as z };
|