@nicia-ai/typegraph 0.24.1 → 0.25.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/dist/backend/postgres/index.cjs +178 -55
- package/dist/backend/postgres/index.cjs.map +1 -1
- package/dist/backend/postgres/index.d.cts +6 -7
- package/dist/backend/postgres/index.d.ts +6 -7
- package/dist/backend/postgres/index.js +151 -28
- package/dist/backend/postgres/index.js.map +1 -1
- package/dist/backend/sqlite/index.cjs +19 -17
- package/dist/backend/sqlite/index.d.cts +6 -7
- package/dist/backend/sqlite/index.d.ts +6 -7
- package/dist/backend/sqlite/index.js +9 -7
- package/dist/backend/sqlite/libsql.cjs +12 -10
- package/dist/backend/sqlite/libsql.cjs.map +1 -1
- package/dist/backend/sqlite/libsql.d.cts +4 -5
- package/dist/backend/sqlite/libsql.d.ts +4 -5
- package/dist/backend/sqlite/libsql.js +9 -7
- package/dist/backend/sqlite/libsql.js.map +1 -1
- package/dist/backend/sqlite/local.cjs +14 -12
- package/dist/backend/sqlite/local.cjs.map +1 -1
- package/dist/backend/sqlite/local.d.cts +4 -5
- package/dist/backend/sqlite/local.d.ts +4 -5
- package/dist/backend/sqlite/local.js +9 -7
- package/dist/backend/sqlite/local.js.map +1 -1
- package/dist/chunk-4BOWVUGQ.js +2029 -0
- package/dist/chunk-4BOWVUGQ.js.map +1 -0
- package/dist/{chunk-SUHW2UYL.cjs → chunk-7CDXX3QZ.cjs} +2 -2
- package/dist/chunk-7CDXX3QZ.cjs.map +1 -0
- package/dist/chunk-7V335GHG.cjs +112 -0
- package/dist/chunk-7V335GHG.cjs.map +1 -0
- package/dist/chunk-7W3KAMVQ.cjs +2678 -0
- package/dist/chunk-7W3KAMVQ.cjs.map +1 -0
- package/dist/chunk-CTHNVU6K.cjs +551 -0
- package/dist/chunk-CTHNVU6K.cjs.map +1 -0
- package/dist/chunk-D2GO3RBL.cjs +12 -0
- package/dist/chunk-D2GO3RBL.cjs.map +1 -0
- package/dist/{chunk-WFMTAEEN.js → chunk-DOTEN2FG.js} +81 -7
- package/dist/chunk-DOTEN2FG.js.map +1 -0
- package/dist/chunk-E5JZSEGJ.cjs +301 -0
- package/dist/chunk-E5JZSEGJ.cjs.map +1 -0
- package/dist/chunk-EG6TJ3I5.js +286 -0
- package/dist/chunk-EG6TJ3I5.js.map +1 -0
- package/dist/chunk-EJCDOA37.js +537 -0
- package/dist/chunk-EJCDOA37.js.map +1 -0
- package/dist/{chunk-UVZHTBZ5.cjs → chunk-EK6RJ373.cjs} +7 -150
- package/dist/chunk-EK6RJ373.cjs.map +1 -0
- package/dist/{chunk-GUTQTMOV.js → chunk-FPCOUJSL.js} +2 -2
- package/dist/chunk-FPCOUJSL.js.map +1 -0
- package/dist/{chunk-3JK66E3I.cjs → chunk-JTI5WT4P.cjs} +630 -59
- package/dist/chunk-JTI5WT4P.cjs.map +1 -0
- package/dist/chunk-LVCSL6A3.js +2626 -0
- package/dist/chunk-LVCSL6A3.js.map +1 -0
- package/dist/chunk-NHQWXSTS.js +10 -0
- package/dist/chunk-NHQWXSTS.js.map +1 -0
- package/dist/chunk-NZ5PMBTG.js +105 -0
- package/dist/chunk-NZ5PMBTG.js.map +1 -0
- package/dist/{chunk-5HVDOPZU.cjs → chunk-O2P3KAUT.cjs} +416 -93
- package/dist/chunk-O2P3KAUT.cjs.map +1 -0
- package/dist/{chunk-QOLTW7OZ.js → chunk-OJ6IQVZG.js} +151 -13
- package/dist/chunk-OJ6IQVZG.js.map +1 -0
- package/dist/{chunk-EYELZHKY.js → chunk-OOS2RKRH.js} +5 -140
- package/dist/chunk-OOS2RKRH.js.map +1 -0
- package/dist/chunk-RCAJZG67.cjs +2069 -0
- package/dist/chunk-RCAJZG67.cjs.map +1 -0
- package/dist/{chunk-O5PST6TB.cjs → chunk-W5MTHMTE.cjs} +83 -6
- package/dist/chunk-W5MTHMTE.cjs.map +1 -0
- package/dist/{chunk-EY4LBX3F.js → chunk-WI5VRP3X.js} +337 -26
- package/dist/chunk-WI5VRP3X.js.map +1 -0
- package/dist/chunk-WVQXAFP3.js +79 -0
- package/dist/chunk-WVQXAFP3.js.map +1 -0
- package/dist/chunk-X3244EKP.cjs +84 -0
- package/dist/chunk-X3244EKP.cjs.map +1 -0
- package/dist/{chunk-753F33CV.js → chunk-YZZBDCLV.js} +617 -44
- package/dist/chunk-YZZBDCLV.js.map +1 -0
- package/dist/{chunk-OVJ2BE5Q.cjs → chunk-ZEMNF3QK.cjs} +171 -33
- package/dist/chunk-ZEMNF3QK.cjs.map +1 -0
- package/dist/{ddl-B_H8JM-E.d.cts → ddl-B2jjLjpR.d.cts} +762 -99
- package/dist/{ddl-1tFIvt9V.d.ts → ddl-DpaeAKPp.d.ts} +762 -99
- package/dist/extension-types-D07e_NTw.d.cts +543 -0
- package/dist/extension-types-D07e_NTw.d.ts +543 -0
- package/dist/graph-extension/index.cjs +71 -0
- package/dist/graph-extension/index.cjs.map +1 -0
- package/dist/graph-extension/index.d.cts +278 -0
- package/dist/graph-extension/index.d.ts +278 -0
- package/dist/graph-extension/index.js +6 -0
- package/dist/graph-extension/index.js.map +1 -0
- package/dist/{index-DXkEXpNz.d.ts → index-CT6nvtxL.d.cts} +114 -5
- package/dist/{index-DXkEXpNz.d.cts → index-DQheiVQV.d.ts} +114 -5
- package/dist/index.cjs +2672 -901
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -10
- package/dist/index.d.ts +29 -10
- package/dist/index.js +2248 -598
- package/dist/index.js.map +1 -1
- package/dist/indexes/index.cjs +25 -23
- package/dist/indexes/index.d.cts +40 -22
- package/dist/indexes/index.d.ts +40 -22
- package/dist/indexes/index.js +5 -3
- package/dist/interchange/index.cjs +8 -7
- package/dist/interchange/index.cjs.map +1 -1
- package/dist/interchange/index.d.cts +5 -4
- package/dist/interchange/index.d.ts +5 -4
- package/dist/interchange/index.js +3 -2
- package/dist/interchange/index.js.map +1 -1
- package/dist/{manager-nIhmttD-.d.ts → manager-BKaPQbns.d.ts} +189 -6
- package/dist/{manager-Vkz28eAC.d.cts → manager-BpjBW1JK.d.cts} +189 -6
- package/dist/materialize-indexes-BB9N5uQl.d.cts +68 -0
- package/dist/materialize-indexes-BYpU2RKh.d.ts +68 -0
- package/dist/profiler/index.cjs +10 -8
- package/dist/profiler/index.cjs.map +1 -1
- package/dist/profiler/index.d.cts +8 -7
- package/dist/profiler/index.d.ts +8 -7
- package/dist/profiler/index.js +3 -1
- package/dist/profiler/index.js.map +1 -1
- package/dist/schema/index.cjs +43 -22
- package/dist/schema/index.cjs.map +1 -1
- package/dist/schema/index.d.cts +17 -8
- package/dist/schema/index.d.ts +17 -8
- package/dist/schema/index.js +9 -4
- package/dist/schema/index.js.map +1 -1
- package/dist/{sqlite-D0aceIe0.d.cts → sqlite-CU3j6rc7.d.ts} +837 -120
- package/dist/{sqlite-SUxbZqfy.d.ts → sqlite-Myo8e3Lr.d.cts} +837 -120
- package/dist/{store-U3i2tUch.d.ts → store-BAGuOHDh.d.cts} +659 -23
- package/dist/{store-CpvwTMxV.d.cts → store-De98Lod4.d.ts} +659 -23
- package/dist/types--0EslBx5.d.cts +2123 -0
- package/dist/{types-qYFZ9SqD.d.ts → types-BLmJq4wI.d.ts} +3 -2
- package/dist/types-BNWYZ-0-.d.ts +2123 -0
- package/dist/{types-yH4_p0XB.d.cts → types-CYga3lZp.d.cts} +3 -2
- package/dist/where-CluR73rs.d.ts +11 -0
- package/dist/where-m1uWsdua.d.cts +11 -0
- package/package.json +33 -73
- package/dist/ast-C8S37w1A.d.ts +0 -497
- package/dist/ast-dgLhLOg0.d.cts +0 -497
- package/dist/chunk-3JK66E3I.cjs.map +0 -1
- package/dist/chunk-3PPEHLGK.js +0 -1116
- package/dist/chunk-3PPEHLGK.js.map +0 -1
- package/dist/chunk-5HVDOPZU.cjs.map +0 -1
- package/dist/chunk-753F33CV.js.map +0 -1
- package/dist/chunk-EY4LBX3F.js.map +0 -1
- package/dist/chunk-EYELZHKY.js.map +0 -1
- package/dist/chunk-GFGVREHH.js +0 -1381
- package/dist/chunk-GFGVREHH.js.map +0 -1
- package/dist/chunk-GUTQTMOV.js.map +0 -1
- package/dist/chunk-LBORRUNJ.js +0 -135
- package/dist/chunk-LBORRUNJ.js.map +0 -1
- package/dist/chunk-O5PST6TB.cjs.map +0 -1
- package/dist/chunk-OLROXS2S.cjs +0 -147
- package/dist/chunk-OLROXS2S.cjs.map +0 -1
- package/dist/chunk-OVJ2BE5Q.cjs.map +0 -1
- package/dist/chunk-PAUN562Y.cjs +0 -1417
- package/dist/chunk-PAUN562Y.cjs.map +0 -1
- package/dist/chunk-PEE4EWXZ.cjs +0 -1131
- package/dist/chunk-PEE4EWXZ.cjs.map +0 -1
- package/dist/chunk-QOLTW7OZ.js.map +0 -1
- package/dist/chunk-SUHW2UYL.cjs.map +0 -1
- package/dist/chunk-UVZHTBZ5.cjs.map +0 -1
- package/dist/chunk-WFMTAEEN.js.map +0 -1
- package/dist/types-C-zfYDJB.d.ts +0 -159
- package/dist/types-CQx4iW5Y.d.cts +0 -159
- package/dist/types-Qk2l3IkQ.d.cts +0 -1254
- package/dist/types-Qk2l3IkQ.d.ts +0 -1254
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/profiler/ast-extractor.ts","../../src/profiler/collector.ts","../../src/profiler/constants.ts","../../src/profiler/recommendations.ts","../../src/profiler/query-profiler.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * AST Extractor - Extracts property access patterns from QueryAst.\n *\n * Walks the query AST to identify all property accesses and their\n * usage contexts (filter, sort, select, groupBy).\n */\n\nimport {\n type FieldRef,\n type NodePredicate,\n type OrderSpec,\n type PredicateExpression,\n type ProjectedField,\n type QueryAst,\n type SelectiveField,\n} from \"../query/ast\";\nimport { jsonPointer } from \"../query/json-pointer\";\nimport {\n type ProfileEntityType,\n type PropertyTarget,\n type UsageContext,\n} from \"./types\";\n\n// ============================================================\n// Extracted Access Type\n// ============================================================\n\n/**\n * A property access extracted from the AST.\n */\ntype ExtractedAccess = Readonly<{\n /** Whether the access targets nodes or edges */\n entityType: ProfileEntityType;\n /** Expanded kind names for the alias */\n kindNames: readonly string[];\n /** The accessed target (props pointer or system field) */\n target: PropertyTarget;\n /** How the property was used */\n context: UsageContext;\n /** Predicate type if used in a filter (eq, contains, gt, etc.) */\n predicateType?: string;\n}>;\n\n// ============================================================\n// Main Extraction Function\n// ============================================================\n\n/**\n * Extracts all property accesses from a QueryAst.\n *\n * Walks the AST to find all property references and categorizes\n * them by usage context (filter, sort, select, groupBy).\n *\n * @param ast - The query AST to analyze\n * @returns Array of extracted property accesses\n */\nexport function extractPropertyAccesses(\n ast: QueryAst,\n): readonly ExtractedAccess[] {\n const accesses: ExtractedAccess[] = [];\n\n // Extract from predicates (filters)\n for (const predicate of ast.predicates) {\n const extracted = extractFromNodePredicate(predicate, ast);\n accesses.push(...extracted);\n }\n\n // Extract from orderBy (sorts)\n if (ast.orderBy) {\n for (const order of ast.orderBy) {\n const extracted = extractFromOrderSpec(order, ast);\n if (extracted) {\n accesses.push(extracted);\n }\n }\n }\n\n // Extract from projection (selects)\n for (const field of ast.projection.fields) {\n const extracted = extractFromProjectedField(field, ast);\n if (extracted) {\n accesses.push(extracted);\n }\n }\n\n // Extract from groupBy\n if (ast.groupBy) {\n for (const field of ast.groupBy.fields) {\n const extracted = extractFromFieldRef(field, \"groupBy\", ast);\n if (extracted) {\n accesses.push(extracted);\n }\n }\n }\n\n // Extract from having (if it exists)\n if (ast.having) {\n const havingAccesses = extractFromExpression(ast.having, undefined, ast);\n accesses.push(...havingAccesses);\n }\n\n // Extract from selective fields (smart select optimization)\n if (ast.selectiveFields) {\n for (const field of ast.selectiveFields) {\n const extracted = extractFromSelectiveField(field, ast);\n if (extracted) {\n accesses.push(extracted);\n }\n }\n }\n\n return accesses;\n}\n\n// ============================================================\n// Predicate Extraction\n// ============================================================\n\nfunction extractFromNodePredicate(\n predicate: NodePredicate,\n ast: QueryAst,\n): ExtractedAccess[] {\n return extractFromExpression(\n predicate.expression,\n predicate.targetAlias,\n ast,\n );\n}\n\nfunction extractFromExpression(\n expr: PredicateExpression,\n alias: string | undefined,\n ast: QueryAst,\n): ExtractedAccess[] {\n const accesses: ExtractedAccess[] = [];\n\n switch (expr.__type) {\n case \"comparison\": {\n const extracted = extractFromFieldRef(expr.left, \"filter\", ast);\n if (extracted) {\n accesses.push({ ...extracted, predicateType: expr.op });\n }\n break;\n }\n\n case \"string_op\": {\n const extracted = extractFromFieldRef(expr.field, \"filter\", ast);\n if (extracted) {\n accesses.push({ ...extracted, predicateType: expr.op });\n }\n break;\n }\n\n case \"null_check\": {\n const extracted = extractFromFieldRef(expr.field, \"filter\", ast);\n if (extracted) {\n accesses.push({ ...extracted, predicateType: expr.op });\n }\n break;\n }\n\n case \"between\": {\n const extracted = extractFromFieldRef(expr.field, \"filter\", ast);\n if (extracted) {\n accesses.push({ ...extracted, predicateType: \"between\" });\n }\n break;\n }\n\n case \"array_op\": {\n const extracted = extractFromFieldRef(expr.field, \"filter\", ast);\n if (extracted) {\n accesses.push({ ...extracted, predicateType: expr.op });\n }\n break;\n }\n\n case \"object_op\": {\n const extracted = extractFromFieldRef(expr.field, \"filter\", ast);\n if (extracted) {\n accesses.push({ ...extracted, predicateType: expr.op });\n }\n break;\n }\n\n case \"and\":\n case \"or\": {\n for (const sub of expr.predicates) {\n accesses.push(...extractFromExpression(sub, alias, ast));\n }\n break;\n }\n\n case \"not\": {\n accesses.push(...extractFromExpression(expr.predicate, alias, ast));\n break;\n }\n\n case \"aggregate_comparison\": {\n // For aggregate comparisons, extract the field being aggregated\n const extracted = extractFromFieldRef(\n expr.aggregate.field,\n \"filter\",\n ast,\n );\n if (extracted) {\n accesses.push({\n ...extracted,\n predicateType: `${expr.aggregate.function}_${expr.op}`,\n });\n }\n break;\n }\n\n case \"exists\": {\n // Recursively extract from subquery\n const subAccesses = extractPropertyAccesses(expr.subquery);\n accesses.push(...subAccesses);\n break;\n }\n\n case \"in_subquery\": {\n // Extract from the field being checked\n const extracted = extractFromFieldRef(expr.field, \"filter\", ast);\n if (extracted) {\n accesses.push({ ...extracted, predicateType: \"in_subquery\" });\n }\n // Recursively extract from subquery\n const subAccesses = extractPropertyAccesses(expr.subquery);\n accesses.push(...subAccesses);\n break;\n }\n\n case \"vector_similarity\": {\n // Vector similarity is a special case - the field is an embedding\n // We track it but with a special predicate type\n const extracted = extractFromFieldRef(expr.field, \"filter\", ast);\n if (extracted) {\n accesses.push({ ...extracted, predicateType: \"vector_similarity\" });\n }\n break;\n }\n\n case \"fulltext_match\": {\n // Fulltext match targets a searchable string field. Track as an\n // index hint so the profiler reports its usage.\n const extracted = extractFromFieldRef(expr.field, \"filter\", ast);\n if (extracted) {\n accesses.push({ ...extracted, predicateType: \"fulltext_match\" });\n }\n break;\n }\n }\n\n return accesses;\n}\n\n// ============================================================\n// Order/Projection Extraction\n// ============================================================\n\nfunction extractFromOrderSpec(\n order: OrderSpec,\n ast: QueryAst,\n): ExtractedAccess | undefined {\n return extractFromFieldRef(order.field, \"sort\", ast);\n}\n\nfunction extractFromProjectedField(\n field: ProjectedField,\n ast: QueryAst,\n): ExtractedAccess | undefined {\n if (field.source.__type === \"aggregate\") {\n // For aggregates, extract the field being aggregated\n return extractFromFieldRef(field.source.field, \"select\", ast);\n }\n return extractFromFieldRef(field.source, \"select\", ast);\n}\n\n/**\n * Extracts property access from a SelectiveField.\n *\n * SelectiveFields are used by the smart select optimization to track\n * which specific fields were accessed in the select callback.\n */\nfunction extractFromSelectiveField(\n field: SelectiveField,\n ast: QueryAst,\n): ExtractedAccess | undefined {\n // Skip system fields (id, kind, etc.) - they're always indexed\n if (field.isSystemField) {\n return undefined;\n }\n\n const resolved = resolveAliasToKinds(field.alias, ast);\n if (!resolved) {\n return undefined;\n }\n\n return {\n entityType: resolved.entityType,\n kindNames: resolved.kindNames,\n target: {\n __type: \"prop\",\n pointer: jsonPointer(field.field.split(\".\")),\n },\n context: \"select\",\n };\n}\n\n// ============================================================\n// Field Reference Extraction\n// ============================================================\n\nfunction extractFromFieldRef(\n ref: FieldRef,\n context: UsageContext,\n ast: QueryAst,\n): ExtractedAccess | undefined {\n const resolved = resolveAliasToKinds(ref.alias, ast);\n if (!resolved) {\n return undefined;\n }\n\n const target = extractTargetFromFieldRef(ref);\n if (!target) {\n return undefined;\n }\n\n return {\n entityType: resolved.entityType,\n kindNames: resolved.kindNames,\n target,\n context,\n };\n}\n\n// ============================================================\n// Helper Functions\n// ============================================================\n\n/**\n * Resolves an alias to its expanded kind names.\n */\ntype ResolvedAliasKinds = Readonly<{\n entityType: ProfileEntityType;\n kindNames: readonly string[];\n}>;\n\nfunction resolveAliasToKinds(\n alias: string,\n ast: QueryAst,\n): ResolvedAliasKinds | undefined {\n if (ast.start.alias === alias) {\n return { entityType: \"node\", kindNames: ast.start.kinds };\n }\n\n // Check traversals\n for (const traversal of ast.traversals) {\n if (traversal.nodeAlias === alias) {\n return { entityType: \"node\", kindNames: traversal.nodeKinds };\n }\n // Also check edge alias\n if (traversal.edgeAlias === alias) {\n return { entityType: \"edge\", kindNames: traversal.edgeKinds };\n }\n }\n\n return undefined;\n}\n\n/**\n * Extracts the accessed target from a FieldRef.\n */\nfunction extractTargetFromFieldRef(ref: FieldRef): PropertyTarget | undefined {\n if (ref.jsonPointer) {\n return { __type: \"prop\", pointer: ref.jsonPointer };\n }\n\n // For props access without jsonPointer (shouldn't happen normally)\n if (ref.path.length > 1 && ref.path[0] === \"props\") {\n return { __type: \"prop\", pointer: jsonPointer(ref.path.slice(1)) };\n }\n\n if (ref.path.length === 1) {\n return { __type: \"system\", field: ref.path[0]! };\n }\n\n return undefined;\n}\n","/**\n * ProfileCollector - Aggregates property access patterns.\n *\n * Mutable collector that tracks property access patterns across queries\n * and provides immutable snapshots for reporting.\n */\n\nimport {\n type JsonPointerInput,\n normalizeJsonPointer,\n} from \"../query/json-pointer\";\nimport {\n type ProfileEntityType,\n type ProfileSummary,\n type PropertyAccessStats,\n type PropertyPath,\n type UsageContext,\n} from \"./types\";\n\n// ============================================================\n// Serialization Helpers\n// ============================================================\n\n/**\n * Converts a PropertyPath to a string key for Map storage.\n *\n * @example\n * ```typescript\n * pathToKey({\n * entityType: \"node\",\n * kind: \"Person\",\n * target: { __type: \"prop\", pointer: \"/email\" },\n * })\n * // => \"node:Person:/email\"\n * ```\n */\nexport function pathToKey(path: PropertyPath): string {\n const targetKey =\n path.target.__type === \"prop\" ?\n path.target.pointer\n : `$${path.target.field}`;\n return `${path.entityType}:${path.kind}:${targetKey}`;\n}\n\n/**\n * Parses a key back to a PropertyPath.\n *\n * @example\n * ```typescript\n * keyToPath(\"node:Person:/email\")\n * // => { entityType: \"node\", kind: \"Person\", target: { __type: \"prop\", pointer: \"/email\" } }\n * ```\n */\nexport function keyToPath(key: string): PropertyPath {\n const firstColonIndex = key.indexOf(\":\");\n const secondColonIndex =\n firstColonIndex === -1 ? -1 : key.indexOf(\":\", firstColonIndex + 1);\n if (firstColonIndex === -1 || secondColonIndex === -1) {\n throw new Error(\n `Invalid profile key: \"${key}\". Expected format \"{entityType}:{kind}:{target}\".`,\n );\n }\n\n const entityTypePart = key.slice(0, firstColonIndex);\n const kind = key.slice(firstColonIndex + 1, secondColonIndex);\n if (kind === \"\") {\n throw new Error(`Invalid profile key: \"${key}\". Kind must not be empty.`);\n }\n const targetPart = key.slice(secondColonIndex + 1);\n\n const entityType = parseEntityType(entityTypePart);\n\n if (targetPart.startsWith(\"$\")) {\n const systemField = targetPart.slice(1);\n if (systemField === \"\") {\n throw new Error(\n `Invalid profile key: \"${key}\". System field must not be empty.`,\n );\n }\n return {\n entityType,\n kind,\n target: { __type: \"system\", field: systemField },\n };\n }\n\n const pointer = normalizeJsonPointer(\n targetPart as JsonPointerInput<Record<string, unknown>>,\n );\n\n return {\n entityType,\n kind,\n target: { __type: \"prop\", pointer },\n };\n}\n\n// ============================================================\n// Mutable Stats Type\n// ============================================================\n\ninterface MutableStats {\n count: number;\n contexts: Set<UsageContext>;\n predicateTypes: Set<string>;\n firstSeenMs: number;\n lastSeenMs: number;\n}\n\nfunction parseEntityType(value: string): ProfileEntityType {\n if (value === \"node\" || value === \"edge\") {\n return value;\n }\n // This indicates a bug in pathToKey() or data corruption.\n // Throw rather than silently defaulting to avoid incorrect recommendations.\n throw new Error(\n `Invalid entity type in profile key: \"${value}\". Expected \"node\" or \"edge\".`,\n );\n}\n\n// ============================================================\n// ProfileCollector Class\n// ============================================================\n\n/**\n * Collects and aggregates property access patterns.\n *\n * This class is mutable internally but provides immutable snapshots\n * via `getPatterns()` and `getSummary()`.\n *\n * @example\n * ```typescript\n * const collector = new ProfileCollector();\n *\n * collector.record(\n * { nodeKind: \"Person\", fieldPath: [\"email\"] },\n * \"filter\",\n * \"eq\"\n * );\n * collector.recordQuery();\n *\n * const patterns = collector.getPatterns();\n * const summary = collector.getSummary();\n * ```\n */\nexport class ProfileCollector {\n readonly #patterns = new Map<string, MutableStats>();\n readonly #startedAt = new Date();\n #queryCount = 0;\n\n /**\n * Records a property access.\n *\n * @param path - The property path that was accessed\n * @param context - How the property was used (filter, sort, select, groupBy)\n * @param predicateType - Optional predicate type (eq, contains, gt, etc.)\n */\n record(\n path: PropertyPath,\n context: UsageContext,\n predicateType?: string,\n ): void {\n const key = pathToKey(path);\n const existing = this.#patterns.get(key);\n const nowMs = Date.now();\n\n if (existing) {\n existing.count++;\n existing.contexts.add(context);\n if (predicateType) {\n existing.predicateTypes.add(predicateType);\n }\n existing.lastSeenMs = nowMs;\n } else {\n this.#patterns.set(key, {\n count: 1,\n contexts: new Set([context]),\n predicateTypes: predicateType ? new Set([predicateType]) : new Set(),\n firstSeenMs: nowMs,\n lastSeenMs: nowMs,\n });\n }\n }\n\n /**\n * Increments the query count.\n * Call this once per query execution.\n */\n recordQuery(): void {\n this.#queryCount++;\n }\n\n /**\n * Gets all patterns as an immutable map.\n *\n * Returns a new Map with immutable stats objects.\n */\n getPatterns(): ReadonlyMap<string, PropertyAccessStats> {\n const result = new Map<string, PropertyAccessStats>();\n\n for (const [key, stats] of this.#patterns) {\n result.set(key, {\n count: stats.count,\n contexts: new Set(stats.contexts),\n predicateTypes: new Set(stats.predicateTypes),\n firstSeen: new Date(stats.firstSeenMs),\n lastSeen: new Date(stats.lastSeenMs),\n });\n }\n\n return result;\n }\n\n /**\n * Gets summary statistics.\n */\n getSummary(): ProfileSummary {\n return {\n totalQueries: this.#queryCount,\n uniquePatterns: this.#patterns.size,\n startedAt: this.#startedAt,\n durationMs: Date.now() - this.#startedAt.getTime(),\n };\n }\n\n /**\n * Resets all collected data.\n *\n * Note: This does not reset the startedAt timestamp.\n * Create a new ProfileCollector for a fresh session.\n */\n reset(): void {\n this.#patterns.clear();\n this.#queryCount = 0;\n }\n}\n","export const DEFAULT_MIN_FREQUENCY_FOR_RECOMMENDATION = 3 as const;\nexport const DEFAULT_HIGH_FREQUENCY_THRESHOLD = 10 as const;\nexport const DEFAULT_MEDIUM_FREQUENCY_THRESHOLD = 5 as const;\n","/**\n * Index Recommendations - Generates index suggestions from usage patterns.\n *\n * Analyzes collected property access patterns and generates prioritized\n * recommendations for missing indexes.\n */\n\nimport { keyToPath, pathToKey } from \"./collector\";\nimport {\n DEFAULT_HIGH_FREQUENCY_THRESHOLD,\n DEFAULT_MEDIUM_FREQUENCY_THRESHOLD,\n DEFAULT_MIN_FREQUENCY_FOR_RECOMMENDATION,\n} from \"./constants\";\nimport {\n type DeclaredIndex,\n type IndexRecommendation,\n type PropertyAccessStats,\n type PropertyPath,\n type RecommendationPriority,\n} from \"./types\";\n\n// ============================================================\n// Main Functions\n// ============================================================\n\ntype GenerateRecommendationsOptions = Readonly<{\n minFrequencyForRecommendation?: number;\n mediumFrequencyThreshold?: number;\n highFrequencyThreshold?: number;\n}>;\n\n/**\n * Generates index recommendations based on usage patterns.\n *\n * Analyzes property access patterns and returns prioritized recommendations\n * for properties that would benefit from indexing.\n *\n * @param patterns - Collected property access patterns\n * @param declaredIndexes - Indexes that already exist\n * @param options - Threshold configuration (or legacy `minFrequency` number)\n * @returns Sorted array of index recommendations\n */\nexport function generateRecommendations(\n patterns: ReadonlyMap<string, PropertyAccessStats>,\n declaredIndexes: readonly DeclaredIndex[],\n options: number | GenerateRecommendationsOptions = {},\n): readonly IndexRecommendation[] {\n const recommendations: IndexRecommendation[] = [];\n const indexedPaths = buildIndexedPathsSet(declaredIndexes);\n\n const config = normalizeRecommendationsOptions(options);\n\n for (const [key, stats] of patterns) {\n // Only recommend indexes for filter and sort contexts.\n // Select and groupBy contexts are collected for completeness (useful for debugging\n // and future features like covering index suggestions) but don't drive recommendations\n // since they don't benefit from B-tree indexes in the same way.\n const hasFilterOrSort =\n stats.contexts.has(\"filter\") || stats.contexts.has(\"sort\");\n\n if (!hasFilterOrSort) {\n continue;\n }\n\n if (stats.count < config.minFrequencyForRecommendation) {\n continue;\n }\n\n const path = keyToPath(key);\n\n // Skip system fields - they're indexed by TypeGraph and/or not indexable as props.\n if (isSystemField(path)) {\n continue;\n }\n\n // Check if already indexed\n if (isIndexed(path, indexedPaths)) {\n continue;\n }\n\n recommendations.push({\n entityType: path.entityType,\n kind: path.kind,\n fields: path.target.__type === \"prop\" ? [path.target.pointer] : [],\n reason: buildReasonString(stats),\n frequency: stats.count,\n priority: getPriority(stats.count, config),\n });\n }\n\n // Sort by priority (high first), then by frequency (descending)\n return recommendations.toSorted((a, b) => {\n const priorityOrder: Record<RecommendationPriority, number> = {\n high: 0,\n medium: 1,\n low: 2,\n };\n const priorityDiff = priorityOrder[a.priority] - priorityOrder[b.priority];\n if (priorityDiff !== 0) return priorityDiff;\n return b.frequency - a.frequency;\n });\n}\n\n/**\n * Gets properties used in filters that lack indexes.\n *\n * Useful for test assertions to ensure all filtered properties are indexed.\n *\n * @param patterns - Collected property access patterns\n * @param declaredIndexes - Indexes that already exist\n * @returns Array of unindexed property paths\n */\nexport function getUnindexedFilters(\n patterns: ReadonlyMap<string, PropertyAccessStats>,\n declaredIndexes: readonly DeclaredIndex[],\n): readonly PropertyPath[] {\n const indexedPaths = buildIndexedPathsSet(declaredIndexes);\n const unindexed: PropertyPath[] = [];\n\n for (const [key, stats] of patterns) {\n // Only check filter context\n if (!stats.contexts.has(\"filter\")) {\n continue;\n }\n\n const path = keyToPath(key);\n\n // Skip system fields\n if (isSystemField(path)) {\n continue;\n }\n\n if (!isIndexed(path, indexedPaths)) {\n unindexed.push(path);\n }\n }\n\n return unindexed;\n}\n\n// ============================================================\n// Helper Functions\n// ============================================================\n\n/**\n * Builds a set of indexed property paths for fast lookup.\n */\nfunction buildIndexedPathsSet(indexes: readonly DeclaredIndex[]): Set<string> {\n const set = new Set<string>();\n\n for (const index of indexes) {\n const firstField = index.fields[0];\n if (!firstField) continue;\n\n // Prefix matching:\n // A composite index on (a, b, c) can be used for predicates on (a).\n set.add(\n pathToKey({\n entityType: index.entityType,\n kind: index.kind,\n target: { __type: \"prop\", pointer: firstField },\n }),\n );\n }\n\n return set;\n}\n\n/**\n * Checks if a property path is covered by an index.\n */\nfunction isIndexed(path: PropertyPath, indexedPaths: Set<string>): boolean {\n return indexedPaths.has(pathToKey(path));\n}\n\n/**\n * Checks if a property path refers to a system field.\n */\nfunction isSystemField(path: PropertyPath): boolean {\n return path.target.__type === \"system\";\n}\n\n/**\n * Builds a human-readable reason string for a recommendation.\n */\nfunction buildReasonString(stats: PropertyAccessStats): string {\n const contexts = [...stats.contexts].join(\", \");\n const predicates = [...stats.predicateTypes];\n\n let reason = `Used in ${contexts}`;\n if (predicates.length > 0) {\n reason += ` with ${predicates.join(\", \")}`;\n }\n reason += ` (${stats.count} ${stats.count === 1 ? \"time\" : \"times\"})`;\n\n return reason;\n}\n\n/**\n * Determines recommendation priority based on access frequency.\n */\ntype NormalizedRecommendationsOptions = Readonly<{\n minFrequencyForRecommendation: number;\n mediumFrequencyThreshold: number;\n highFrequencyThreshold: number;\n}>;\n\nfunction normalizeRecommendationsOptions(\n options: number | GenerateRecommendationsOptions,\n): NormalizedRecommendationsOptions {\n if (typeof options === \"number\") {\n return {\n minFrequencyForRecommendation: options,\n mediumFrequencyThreshold: DEFAULT_MEDIUM_FREQUENCY_THRESHOLD,\n highFrequencyThreshold: DEFAULT_HIGH_FREQUENCY_THRESHOLD,\n };\n }\n\n return {\n minFrequencyForRecommendation:\n options.minFrequencyForRecommendation ??\n DEFAULT_MIN_FREQUENCY_FOR_RECOMMENDATION,\n mediumFrequencyThreshold:\n options.mediumFrequencyThreshold ?? DEFAULT_MEDIUM_FREQUENCY_THRESHOLD,\n highFrequencyThreshold:\n options.highFrequencyThreshold ?? DEFAULT_HIGH_FREQUENCY_THRESHOLD,\n };\n}\n\nfunction getPriority(\n frequency: number,\n options: NormalizedRecommendationsOptions,\n): RecommendationPriority {\n if (frequency >= options.highFrequencyThreshold) return \"high\";\n if (frequency >= options.mediumFrequencyThreshold) return \"medium\";\n return \"low\";\n}\n","/**\n * QueryProfiler - Main profiler class.\n *\n * Captures query patterns from the AST and generates index recommendations.\n * Uses Proxy to wrap Store and QueryBuilder for transparent interception.\n */\n\nimport { type z } from \"zod\";\n\nimport { type GraphDef } from \"../core/define-graph\";\nimport { type QueryAst } from \"../query/ast\";\nimport { resolveFieldTypeInfoAtJsonPointer } from \"../query/field-type-info\";\nimport {\n type JsonPointer,\n jsonPointer,\n parseJsonPointer,\n} from \"../query/json-pointer\";\nimport {\n createSchemaIntrospector,\n type SchemaIntrospector,\n} from \"../query/schema-introspector\";\nimport { type Store } from \"../store/store\";\nimport { extractPropertyAccesses } from \"./ast-extractor\";\nimport { ProfileCollector } from \"./collector\";\nimport {\n DEFAULT_HIGH_FREQUENCY_THRESHOLD,\n DEFAULT_MEDIUM_FREQUENCY_THRESHOLD,\n DEFAULT_MIN_FREQUENCY_FOR_RECOMMENDATION,\n} from \"./constants\";\nimport {\n generateRecommendations,\n getUnindexedFilters,\n} from \"./recommendations\";\nimport {\n type DeclaredIndex,\n type ProfileReport,\n type ProfilerOptions,\n type PropertyPath,\n} from \"./types\";\n\n// ============================================================\n// ProfiledStore Type\n// ============================================================\n\n/**\n * A Store with profiling capabilities.\n *\n * Behaves exactly like a regular Store but tracks all query executions.\n * Access the profiler via the `profiler` property.\n */\nexport type ProfiledStore<G extends GraphDef> = Store<G> & {\n /** The profiler instance attached to this store */\n readonly profiler: QueryProfiler;\n};\n\n// ============================================================\n// QueryProfiler Class\n// ============================================================\n\n/**\n * QueryProfiler captures and analyzes query patterns.\n *\n * Attach to a store to automatically track all query executions,\n * then generate reports with index recommendations.\n *\n * @example\n * ```typescript\n * import { QueryProfiler } from \"@nicia-ai/typegraph/profiler\";\n *\n * const profiler = new QueryProfiler({\n * declaredIndexes: [\n * { nodeKind: \"Person\", fields: [\"email\"], unique: true, name: \"idx_email\" },\n * ],\n * });\n *\n * const profiledStore = profiler.attachToStore(store);\n *\n * // Run queries...\n * await profiledStore.query()\n * .from(\"Person\", \"p\")\n * .whereNode(\"p\", (p) => p.email.eq(\"alice@example.com\"))\n * .select((ctx) => ctx.p)\n * .execute();\n *\n * // Get report\n * const report = profiler.getReport();\n * console.log(report.recommendations);\n * ```\n */\nexport class QueryProfiler {\n readonly #collector = new ProfileCollector();\n readonly #declaredIndexes: readonly DeclaredIndex[];\n readonly #minFrequencyForRecommendation: number;\n readonly #mediumFrequencyThreshold: number;\n readonly #highFrequencyThreshold: number;\n #schemaIntrospector: SchemaIntrospector | undefined;\n #attached = false;\n\n constructor(options?: ProfilerOptions) {\n this.#declaredIndexes = options?.declaredIndexes ?? [];\n this.#minFrequencyForRecommendation =\n options?.minFrequencyForRecommendation ??\n DEFAULT_MIN_FREQUENCY_FOR_RECOMMENDATION;\n this.#mediumFrequencyThreshold =\n options?.mediumFrequencyThreshold ?? DEFAULT_MEDIUM_FREQUENCY_THRESHOLD;\n this.#highFrequencyThreshold =\n options?.highFrequencyThreshold ?? DEFAULT_HIGH_FREQUENCY_THRESHOLD;\n }\n\n /**\n * Records a query execution from its AST.\n *\n * This is called automatically when attached to a store.\n * Can also be called manually for custom integrations.\n *\n * @param ast - The query AST to analyze\n */\n recordQuery(ast: QueryAst): void {\n this.#collector.recordQuery();\n\n const accesses = extractPropertyAccesses(ast);\n for (const access of accesses) {\n const paths = resolveAccessPaths(access, this.#schemaIntrospector);\n for (const path of paths) {\n this.#collector.record(path, access.context, access.predicateType);\n }\n }\n }\n\n /**\n * Attaches the profiler to a store.\n *\n * Returns a wrapped store that tracks all query executions.\n * The wrapped store behaves identically to the original.\n *\n * @param store - The store to attach to\n * @returns A profiled store with the `profiler` property\n * @throws Error if the profiler is already attached to another store\n */\n attachToStore<G extends GraphDef>(store: Store<G>): ProfiledStore<G> {\n if (this.#attached) {\n throw new Error(\n \"Profiler is already attached. Call detach() first or create a new profiler.\",\n );\n }\n this.#attached = true;\n this.#schemaIntrospector = createSchemaIntrospector(\n buildNodeSchemaMap(store.graph),\n buildEdgeSchemaMap(store.graph),\n );\n return createProfiledStore(store, this);\n }\n\n /**\n * Generates a complete profile report.\n *\n * The report includes:\n * - All property access patterns with frequency and context\n * - Index recommendations sorted by priority\n * - List of unindexed filter properties\n * - Summary statistics\n *\n * @returns The profile report\n */\n getReport(): ProfileReport {\n const patterns = this.#collector.getPatterns();\n const summary = this.#collector.getSummary();\n\n return {\n patterns,\n recommendations: generateRecommendations(\n patterns,\n this.#declaredIndexes,\n {\n minFrequencyForRecommendation: this.#minFrequencyForRecommendation,\n mediumFrequencyThreshold: this.#mediumFrequencyThreshold,\n highFrequencyThreshold: this.#highFrequencyThreshold,\n },\n ),\n summary,\n unindexedFilters: getUnindexedFilters(patterns, this.#declaredIndexes),\n };\n }\n\n /**\n * Checks if all filtered properties are covered by indexes.\n *\n * Throws an error if any filtered properties lack indexes.\n * Useful for test assertions to ensure query performance.\n *\n * @throws Error if unindexed filter properties are found\n *\n * @example\n * ```typescript\n * // In your test file\n * it(\"all filtered properties should be indexed\", () => {\n * profiler.assertIndexCoverage();\n * });\n * ```\n */\n assertIndexCoverage(): void {\n const report = this.getReport();\n if (report.unindexedFilters.length > 0) {\n const missing = report.unindexedFilters\n .map((p) => formatPropertyPath(p))\n .join(\", \");\n throw new Error(`Unindexed filter properties: ${missing}`);\n }\n }\n\n /**\n * Resets all collected data.\n *\n * Clears patterns and query count. Useful for starting a fresh\n * profiling session without creating a new profiler instance.\n */\n reset(): void {\n this.#collector.reset();\n }\n\n /**\n * Marks the profiler as detached.\n *\n * Call this when you're done profiling to allow reattachment\n * to the same or a different store.\n */\n detach(): void {\n this.#attached = false;\n this.#schemaIntrospector = undefined;\n }\n\n /**\n * Whether the profiler is currently attached to a store.\n */\n get isAttached(): boolean {\n return this.#attached;\n }\n}\n\nfunction buildNodeSchemaMap(\n graph: GraphDef,\n): ReadonlyMap<string, Readonly<{ schema: z.ZodType }>> {\n const entries = Object.values(graph.nodes).map(\n (n) => [n.type.kind, { schema: n.type.schema }] as const,\n );\n return new Map(entries);\n}\n\nfunction buildEdgeSchemaMap(\n graph: GraphDef,\n): ReadonlyMap<string, Readonly<{ schema: z.ZodType }>> {\n const entries = Object.values(graph.edges).map(\n (edgeRegistration) =>\n [\n edgeRegistration.type.kind,\n { schema: edgeRegistration.type.schema },\n ] as const,\n );\n return new Map(entries);\n}\n\nfunction resolveAccessPaths(\n access: ReturnType<typeof extractPropertyAccesses>[number],\n schemaIntrospector: SchemaIntrospector | undefined,\n): readonly PropertyPath[] {\n const kinds = access.kindNames;\n if (kinds.length === 0) {\n // This indicates a bug in the AST extractor - aliases should always resolve to kinds.\n // Log warning and skip rather than silently dropping data.\n warnInDevelopment(\n `[QueryProfiler] Access pattern has empty kindNames for context \"${access.context}\". ` +\n `This may indicate a bug in alias resolution.`,\n );\n return [];\n }\n\n if (!schemaIntrospector) {\n return [\n {\n entityType: access.entityType,\n kind: kinds[0]!,\n target: access.target,\n },\n ];\n }\n\n if (access.target.__type !== \"prop\") {\n return [\n {\n entityType: access.entityType,\n kind: kinds[0]!,\n target: access.target,\n },\n ];\n }\n\n const pointer = access.target.pointer;\n const matchingKinds = kinds.filter((kindName) =>\n hasPointerInSchema(\n schemaIntrospector,\n access.entityType,\n kindName,\n pointer,\n ),\n );\n\n const kindsToUse = matchingKinds.length > 0 ? matchingKinds : [kinds[0]!];\n\n return kindsToUse.map((kindName) => ({\n entityType: access.entityType,\n kind: kindName,\n target: access.target,\n }));\n}\n\nfunction warnInDevelopment(message: string, details?: unknown): void {\n if (!isDevelopmentEnvironment()) {\n return;\n }\n if (details !== undefined) {\n console.warn(message, details);\n return;\n }\n console.warn(message);\n}\n\nfunction isDevelopmentEnvironment(): boolean {\n return getNodeEnv() !== \"production\";\n}\n\nfunction getNodeEnv(): string | undefined {\n if (typeof process === \"undefined\") {\n return undefined;\n }\n return process.env.NODE_ENV;\n}\n\n/**\n * Checks whether a JSON pointer exists in the schema for the given kind.\n *\n * This is used to attribute multi-kind aliases (includeSubClasses) to the most\n * relevant concrete kinds by verifying that the accessed pointer exists.\n *\n * Returns false on missing fields or invalid pointers.\n */\nfunction hasPointerInSchema(\n schemaIntrospector: SchemaIntrospector,\n entityType: PropertyPath[\"entityType\"],\n kindName: string,\n pointer: JsonPointer,\n): boolean {\n const segments = parseJsonPointer(pointer);\n const [first, ...rest] = segments;\n if (!first) {\n return false;\n }\n\n const rootInfo =\n entityType === \"node\" ?\n schemaIntrospector.getFieldTypeInfo(kindName, first)\n : schemaIntrospector.getEdgeFieldTypeInfo(kindName, first);\n\n if (!rootInfo) {\n return false;\n }\n\n if (rest.length === 0) {\n return true;\n }\n\n try {\n const resolved = resolveFieldTypeInfoAtJsonPointer(\n rootInfo,\n jsonPointer(rest),\n );\n return resolved !== undefined;\n } catch (error) {\n warnInDevelopment(\n `[QueryProfiler] Failed to resolve pointer \"${pointer}\" for ${entityType} kind \"${kindName}\".`,\n error,\n );\n return false;\n }\n}\n\nfunction formatPropertyPath(path: PropertyPath): string {\n const target =\n path.target.__type === \"prop\" ?\n (path.target.pointer as string)\n : `$${path.target.field}`;\n return `${path.entityType}:${path.kind}:${target}`;\n}\n\n// ============================================================\n// Proxy Implementation\n// ============================================================\n\n/**\n * Creates a profiled store wrapper using Proxy.\n */\nfunction createProfiledStore<G extends GraphDef>(\n store: Store<G>,\n profiler: QueryProfiler,\n): ProfiledStore<G> {\n const storeProxyHandler: ProxyHandler<Store<G>> = {\n get(target, property, _receiver) {\n // Add profiler property\n if (property === \"profiler\") {\n return profiler;\n }\n\n // Wrap query() method\n if (property === \"query\") {\n return () => {\n const builder = target.query();\n return wrapQueryBuilder(builder, profiler);\n };\n }\n\n // IMPORTANT: Store is a class with private fields; accessors and methods\n // must be invoked with `this === target`, not the proxy receiver.\n const value: unknown = Reflect.get(target, property, target);\n\n // Bind functions to the target to preserve private field access.\n if (typeof value === \"function\") {\n return (value as (...args: unknown[]) => unknown).bind(target);\n }\n\n return value;\n },\n };\n\n return new Proxy(store, storeProxyHandler) as ProfiledStore<G>;\n}\n\n/**\n * Wraps a query builder to intercept method calls.\n *\n * The builder returns new builders for most methods, and returns\n * ExecutableQuery for select/aggregate. We need to recursively\n * wrap to ensure all paths lead to wrapped ExecutableQueries.\n */\nfunction wrapQueryBuilder<T extends object>(\n builder: T,\n profiler: QueryProfiler,\n): T {\n const builderProxyHandler: ProxyHandler<T> = {\n get(target, property, receiver) {\n const value: unknown = Reflect.get(target, property, receiver);\n\n // Not a function - return as-is\n if (typeof value !== \"function\") {\n return value;\n }\n\n // Wrap the method to intercept results\n return (...args: unknown[]): unknown => {\n const result: unknown = (\n value as (...args: unknown[]) => unknown\n ).apply(target, args);\n\n // If result is null/undefined or primitive, return as-is\n if (result === null || typeof result !== \"object\") {\n return result;\n }\n\n // Check if result is an ExecutableQuery (has toAst and execute)\n if (hasExecutableQueryShape(result)) {\n return wrapExecutableQuery(result, profiler);\n }\n\n // Check if result is a builder (has from, select, whereNode, etc.)\n if (hasQueryBuilderShape(result)) {\n return wrapQueryBuilder(result, profiler);\n }\n\n // Otherwise return as-is (e.g., compile() returns SQL)\n return result;\n };\n },\n };\n\n return new Proxy(builder, builderProxyHandler);\n}\n\n/**\n * Wraps an ExecutableQuery to intercept execute(), paginate(), stream().\n */\nfunction wrapExecutableQuery<T extends object>(\n query: T,\n profiler: QueryProfiler,\n): T {\n const executableQueryProxyHandler: ProxyHandler<T> = {\n get(target, property, receiver) {\n const value: unknown = Reflect.get(target, property, receiver);\n\n // Not a function - return as-is\n if (typeof value !== \"function\") {\n return value;\n }\n\n const fn = value as (...args: unknown[]) => unknown;\n\n // Always bind `this` to the original instance to preserve private fields.\n return (...args: unknown[]): unknown => {\n // Intercept execute, paginate, stream\n if (\n property === \"execute\" ||\n property === \"paginate\" ||\n property === \"stream\"\n ) {\n const toAst = Reflect.get(\n target,\n \"toAst\",\n receiver,\n ) as () => QueryAst;\n const ast = toAst.call(target);\n profiler.recordQuery(ast);\n }\n\n const result: unknown = fn.apply(target, args);\n\n // Any method that returns an ExecutableQuery-shaped object should remain wrapped.\n // Using duck-typing rather than a method whitelist ensures new chainable methods\n // (e.g., orderBy, limit, offset, pipe, union, intersect, etc.) are automatically handled.\n if (\n result &&\n typeof result === \"object\" &&\n hasExecutableQueryShape(result)\n ) {\n return wrapExecutableQuery(result, profiler);\n }\n\n return result;\n };\n },\n };\n\n return new Proxy(query, executableQueryProxyHandler);\n}\n\n// ============================================================\n// Type Guards\n// ============================================================\n\n/**\n * Checks if an object looks like an ExecutableQuery.\n */\nfunction hasExecutableQueryShape(object: object): boolean {\n return (\n \"toAst\" in object &&\n typeof object.toAst === \"function\" &&\n \"execute\" in object &&\n typeof object.execute === \"function\"\n );\n}\n\n/**\n * Checks if an object looks like a QueryBuilder or TraversalBuilder.\n * Covers both the main query builder and traversal/edge builder chains.\n */\nfunction hasQueryBuilderShape(object: object): boolean {\n return (\n (\"from\" in object && typeof object.from === \"function\") ||\n (\"select\" in object && typeof object.select === \"function\") ||\n (\"whereNode\" in object && typeof object.whereNode === \"function\") ||\n (\"traverse\" in object && typeof object.traverse === \"function\") ||\n // Traversal builder methods\n (\"whereEdge\" in object && typeof object.whereEdge === \"function\") ||\n (\"to\" in object && typeof object.to === \"function\")\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/profiler/ast-extractor.ts","../../src/profiler/collector.ts","../../src/profiler/constants.ts","../../src/profiler/recommendations.ts","../../src/profiler/query-profiler.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * AST Extractor - Extracts property access patterns from QueryAst.\n *\n * Walks the query AST to identify all property accesses and their\n * usage contexts (filter, sort, select, groupBy).\n */\n\nimport {\n type FieldRef,\n type NodePredicate,\n type OrderSpec,\n type PredicateExpression,\n type ProjectedField,\n type QueryAst,\n type SelectiveField,\n} from \"../query/ast\";\nimport { jsonPointer } from \"../query/json-pointer\";\nimport {\n type ProfileEntityType,\n type PropertyTarget,\n type UsageContext,\n} from \"./types\";\n\n// ============================================================\n// Extracted Access Type\n// ============================================================\n\n/**\n * A property access extracted from the AST.\n */\ntype ExtractedAccess = Readonly<{\n /** Whether the access targets nodes or edges */\n entityType: ProfileEntityType;\n /** Expanded kind names for the alias */\n kindNames: readonly string[];\n /** The accessed target (props pointer or system field) */\n target: PropertyTarget;\n /** How the property was used */\n context: UsageContext;\n /** Predicate type if used in a filter (eq, contains, gt, etc.) */\n predicateType?: string;\n}>;\n\n// ============================================================\n// Main Extraction Function\n// ============================================================\n\n/**\n * Extracts all property accesses from a QueryAst.\n *\n * Walks the AST to find all property references and categorizes\n * them by usage context (filter, sort, select, groupBy).\n *\n * @param ast - The query AST to analyze\n * @returns Array of extracted property accesses\n */\nexport function extractPropertyAccesses(\n ast: QueryAst,\n): readonly ExtractedAccess[] {\n const accesses: ExtractedAccess[] = [];\n\n // Extract from predicates (filters)\n for (const predicate of ast.predicates) {\n const extracted = extractFromNodePredicate(predicate, ast);\n accesses.push(...extracted);\n }\n\n // Extract from orderBy (sorts)\n if (ast.orderBy) {\n for (const order of ast.orderBy) {\n const extracted = extractFromOrderSpec(order, ast);\n if (extracted) {\n accesses.push(extracted);\n }\n }\n }\n\n // Extract from projection (selects)\n for (const field of ast.projection.fields) {\n const extracted = extractFromProjectedField(field, ast);\n if (extracted) {\n accesses.push(extracted);\n }\n }\n\n // Extract from groupBy\n if (ast.groupBy) {\n for (const field of ast.groupBy.fields) {\n const extracted = extractFromFieldRef(field, \"groupBy\", ast);\n if (extracted) {\n accesses.push(extracted);\n }\n }\n }\n\n // Extract from having (if it exists)\n if (ast.having) {\n const havingAccesses = extractFromExpression(ast.having, undefined, ast);\n accesses.push(...havingAccesses);\n }\n\n // Extract from selective fields (smart select optimization)\n if (ast.selectiveFields) {\n for (const field of ast.selectiveFields) {\n const extracted = extractFromSelectiveField(field, ast);\n if (extracted) {\n accesses.push(extracted);\n }\n }\n }\n\n return accesses;\n}\n\n// ============================================================\n// Predicate Extraction\n// ============================================================\n\nfunction extractFromNodePredicate(\n predicate: NodePredicate,\n ast: QueryAst,\n): ExtractedAccess[] {\n return extractFromExpression(\n predicate.expression,\n predicate.targetAlias,\n ast,\n );\n}\n\nfunction extractFromExpression(\n expr: PredicateExpression,\n alias: string | undefined,\n ast: QueryAst,\n): ExtractedAccess[] {\n const accesses: ExtractedAccess[] = [];\n\n switch (expr.__type) {\n case \"comparison\": {\n const extracted = extractFromFieldRef(expr.left, \"filter\", ast);\n if (extracted) {\n accesses.push({ ...extracted, predicateType: expr.op });\n }\n break;\n }\n\n case \"string_op\": {\n const extracted = extractFromFieldRef(expr.field, \"filter\", ast);\n if (extracted) {\n accesses.push({ ...extracted, predicateType: expr.op });\n }\n break;\n }\n\n case \"null_check\": {\n const extracted = extractFromFieldRef(expr.field, \"filter\", ast);\n if (extracted) {\n accesses.push({ ...extracted, predicateType: expr.op });\n }\n break;\n }\n\n case \"between\": {\n const extracted = extractFromFieldRef(expr.field, \"filter\", ast);\n if (extracted) {\n accesses.push({ ...extracted, predicateType: \"between\" });\n }\n break;\n }\n\n case \"array_op\": {\n const extracted = extractFromFieldRef(expr.field, \"filter\", ast);\n if (extracted) {\n accesses.push({ ...extracted, predicateType: expr.op });\n }\n break;\n }\n\n case \"object_op\": {\n const extracted = extractFromFieldRef(expr.field, \"filter\", ast);\n if (extracted) {\n accesses.push({ ...extracted, predicateType: expr.op });\n }\n break;\n }\n\n case \"and\":\n case \"or\": {\n for (const sub of expr.predicates) {\n accesses.push(...extractFromExpression(sub, alias, ast));\n }\n break;\n }\n\n case \"not\": {\n accesses.push(...extractFromExpression(expr.predicate, alias, ast));\n break;\n }\n\n case \"aggregate_comparison\": {\n // For aggregate comparisons, extract the field being aggregated\n const extracted = extractFromFieldRef(\n expr.aggregate.field,\n \"filter\",\n ast,\n );\n if (extracted) {\n accesses.push({\n ...extracted,\n predicateType: `${expr.aggregate.function}_${expr.op}`,\n });\n }\n break;\n }\n\n case \"exists\": {\n // Recursively extract from subquery\n const subAccesses = extractPropertyAccesses(expr.subquery);\n accesses.push(...subAccesses);\n break;\n }\n\n case \"in_subquery\": {\n // Extract from the field being checked\n const extracted = extractFromFieldRef(expr.field, \"filter\", ast);\n if (extracted) {\n accesses.push({ ...extracted, predicateType: \"in_subquery\" });\n }\n // Recursively extract from subquery\n const subAccesses = extractPropertyAccesses(expr.subquery);\n accesses.push(...subAccesses);\n break;\n }\n\n case \"vector_similarity\": {\n // Vector similarity is a special case - the field is an embedding\n // We track it but with a special predicate type\n const extracted = extractFromFieldRef(expr.field, \"filter\", ast);\n if (extracted) {\n accesses.push({ ...extracted, predicateType: \"vector_similarity\" });\n }\n break;\n }\n\n case \"fulltext_match\": {\n // Fulltext match targets a searchable string field. Track as an\n // index hint so the profiler reports its usage.\n const extracted = extractFromFieldRef(expr.field, \"filter\", ast);\n if (extracted) {\n accesses.push({ ...extracted, predicateType: \"fulltext_match\" });\n }\n break;\n }\n }\n\n return accesses;\n}\n\n// ============================================================\n// Order/Projection Extraction\n// ============================================================\n\nfunction extractFromOrderSpec(\n order: OrderSpec,\n ast: QueryAst,\n): ExtractedAccess | undefined {\n return extractFromFieldRef(order.field, \"sort\", ast);\n}\n\nfunction extractFromProjectedField(\n field: ProjectedField,\n ast: QueryAst,\n): ExtractedAccess | undefined {\n if (field.source.__type === \"aggregate\") {\n // For aggregates, extract the field being aggregated\n return extractFromFieldRef(field.source.field, \"select\", ast);\n }\n return extractFromFieldRef(field.source, \"select\", ast);\n}\n\n/**\n * Extracts property access from a SelectiveField.\n *\n * SelectiveFields are used by the smart select optimization to track\n * which specific fields were accessed in the select callback.\n */\nfunction extractFromSelectiveField(\n field: SelectiveField,\n ast: QueryAst,\n): ExtractedAccess | undefined {\n // Skip system fields (id, kind, etc.) - they're always indexed\n if (field.isSystemField) {\n return undefined;\n }\n\n const resolved = resolveAliasToKinds(field.alias, ast);\n if (!resolved) {\n return undefined;\n }\n\n return {\n entityType: resolved.entityType,\n kindNames: resolved.kindNames,\n target: {\n __type: \"prop\",\n pointer: jsonPointer(field.field.split(\".\")),\n },\n context: \"select\",\n };\n}\n\n// ============================================================\n// Field Reference Extraction\n// ============================================================\n\nfunction extractFromFieldRef(\n ref: FieldRef,\n context: UsageContext,\n ast: QueryAst,\n): ExtractedAccess | undefined {\n const resolved = resolveAliasToKinds(ref.alias, ast);\n if (!resolved) {\n return undefined;\n }\n\n const target = extractTargetFromFieldRef(ref);\n if (!target) {\n return undefined;\n }\n\n return {\n entityType: resolved.entityType,\n kindNames: resolved.kindNames,\n target,\n context,\n };\n}\n\n// ============================================================\n// Helper Functions\n// ============================================================\n\n/**\n * Resolves an alias to its expanded kind names.\n */\ntype ResolvedAliasKinds = Readonly<{\n entityType: ProfileEntityType;\n kindNames: readonly string[];\n}>;\n\nfunction resolveAliasToKinds(\n alias: string,\n ast: QueryAst,\n): ResolvedAliasKinds | undefined {\n if (ast.start.alias === alias) {\n return { entityType: \"node\", kindNames: ast.start.kinds };\n }\n\n // Check traversals\n for (const traversal of ast.traversals) {\n if (traversal.nodeAlias === alias) {\n return { entityType: \"node\", kindNames: traversal.nodeKinds };\n }\n // Also check edge alias\n if (traversal.edgeAlias === alias) {\n return { entityType: \"edge\", kindNames: traversal.edgeKinds };\n }\n }\n\n return undefined;\n}\n\n/**\n * Extracts the accessed target from a FieldRef.\n */\nfunction extractTargetFromFieldRef(ref: FieldRef): PropertyTarget | undefined {\n if (ref.jsonPointer) {\n return { __type: \"prop\", pointer: ref.jsonPointer };\n }\n\n // For props access without jsonPointer (shouldn't happen normally)\n if (ref.path.length > 1 && ref.path[0] === \"props\") {\n return { __type: \"prop\", pointer: jsonPointer(ref.path.slice(1)) };\n }\n\n if (ref.path.length === 1) {\n return { __type: \"system\", field: ref.path[0]! };\n }\n\n return undefined;\n}\n","/**\n * ProfileCollector - Aggregates property access patterns.\n *\n * Mutable collector that tracks property access patterns across queries\n * and provides immutable snapshots for reporting.\n */\n\nimport {\n type JsonPointerInput,\n normalizeJsonPointer,\n} from \"../query/json-pointer\";\nimport {\n type ProfileEntityType,\n type ProfileSummary,\n type PropertyAccessStats,\n type PropertyPath,\n type UsageContext,\n} from \"./types\";\n\n// ============================================================\n// Serialization Helpers\n// ============================================================\n\n/**\n * Converts a PropertyPath to a string key for Map storage.\n *\n * @example\n * ```typescript\n * pathToKey({\n * entityType: \"node\",\n * kind: \"Person\",\n * target: { __type: \"prop\", pointer: \"/email\" },\n * })\n * // => \"node:Person:/email\"\n * ```\n */\nexport function pathToKey(path: PropertyPath): string {\n const targetKey =\n path.target.__type === \"prop\" ?\n path.target.pointer\n : `$${path.target.field}`;\n return `${path.entityType}:${path.kind}:${targetKey}`;\n}\n\n/**\n * Parses a key back to a PropertyPath.\n *\n * @example\n * ```typescript\n * keyToPath(\"node:Person:/email\")\n * // => { entityType: \"node\", kind: \"Person\", target: { __type: \"prop\", pointer: \"/email\" } }\n * ```\n */\nexport function keyToPath(key: string): PropertyPath {\n const firstColonIndex = key.indexOf(\":\");\n const secondColonIndex =\n firstColonIndex === -1 ? -1 : key.indexOf(\":\", firstColonIndex + 1);\n if (firstColonIndex === -1 || secondColonIndex === -1) {\n throw new Error(\n `Invalid profile key: \"${key}\". Expected format \"{entityType}:{kind}:{target}\".`,\n );\n }\n\n const entityTypePart = key.slice(0, firstColonIndex);\n const kind = key.slice(firstColonIndex + 1, secondColonIndex);\n if (kind === \"\") {\n throw new Error(`Invalid profile key: \"${key}\". Kind must not be empty.`);\n }\n const targetPart = key.slice(secondColonIndex + 1);\n\n const entityType = parseEntityType(entityTypePart);\n\n if (targetPart.startsWith(\"$\")) {\n const systemField = targetPart.slice(1);\n if (systemField === \"\") {\n throw new Error(\n `Invalid profile key: \"${key}\". System field must not be empty.`,\n );\n }\n return {\n entityType,\n kind,\n target: { __type: \"system\", field: systemField },\n };\n }\n\n const pointer = normalizeJsonPointer(\n targetPart as JsonPointerInput<Record<string, unknown>>,\n );\n\n return {\n entityType,\n kind,\n target: { __type: \"prop\", pointer },\n };\n}\n\n// ============================================================\n// Mutable Stats Type\n// ============================================================\n\ninterface MutableStats {\n count: number;\n contexts: Set<UsageContext>;\n predicateTypes: Set<string>;\n firstSeenMs: number;\n lastSeenMs: number;\n}\n\nfunction parseEntityType(value: string): ProfileEntityType {\n if (value === \"node\" || value === \"edge\") {\n return value;\n }\n // This indicates a bug in pathToKey() or data corruption.\n // Throw rather than silently defaulting to avoid incorrect recommendations.\n throw new Error(\n `Invalid entity type in profile key: \"${value}\". Expected \"node\" or \"edge\".`,\n );\n}\n\n// ============================================================\n// ProfileCollector Class\n// ============================================================\n\n/**\n * Collects and aggregates property access patterns.\n *\n * This class is mutable internally but provides immutable snapshots\n * via `getPatterns()` and `getSummary()`.\n *\n * @example\n * ```typescript\n * const collector = new ProfileCollector();\n *\n * collector.record(\n * { nodeKind: \"Person\", fieldPath: [\"email\"] },\n * \"filter\",\n * \"eq\"\n * );\n * collector.recordQuery();\n *\n * const patterns = collector.getPatterns();\n * const summary = collector.getSummary();\n * ```\n */\nexport class ProfileCollector {\n readonly #patterns = new Map<string, MutableStats>();\n readonly #startedAt = new Date();\n #queryCount = 0;\n\n /**\n * Records a property access.\n *\n * @param path - The property path that was accessed\n * @param context - How the property was used (filter, sort, select, groupBy)\n * @param predicateType - Optional predicate type (eq, contains, gt, etc.)\n */\n record(\n path: PropertyPath,\n context: UsageContext,\n predicateType?: string,\n ): void {\n const key = pathToKey(path);\n const existing = this.#patterns.get(key);\n const nowMs = Date.now();\n\n if (existing) {\n existing.count++;\n existing.contexts.add(context);\n if (predicateType) {\n existing.predicateTypes.add(predicateType);\n }\n existing.lastSeenMs = nowMs;\n } else {\n this.#patterns.set(key, {\n count: 1,\n contexts: new Set([context]),\n predicateTypes: predicateType ? new Set([predicateType]) : new Set(),\n firstSeenMs: nowMs,\n lastSeenMs: nowMs,\n });\n }\n }\n\n /**\n * Increments the query count.\n * Call this once per query execution.\n */\n recordQuery(): void {\n this.#queryCount++;\n }\n\n /**\n * Gets all patterns as an immutable map.\n *\n * Returns a new Map with immutable stats objects.\n */\n getPatterns(): ReadonlyMap<string, PropertyAccessStats> {\n const result = new Map<string, PropertyAccessStats>();\n\n for (const [key, stats] of this.#patterns) {\n result.set(key, {\n count: stats.count,\n contexts: new Set(stats.contexts),\n predicateTypes: new Set(stats.predicateTypes),\n firstSeen: new Date(stats.firstSeenMs),\n lastSeen: new Date(stats.lastSeenMs),\n });\n }\n\n return result;\n }\n\n /**\n * Gets summary statistics.\n */\n getSummary(): ProfileSummary {\n return {\n totalQueries: this.#queryCount,\n uniquePatterns: this.#patterns.size,\n startedAt: this.#startedAt,\n durationMs: Date.now() - this.#startedAt.getTime(),\n };\n }\n\n /**\n * Resets all collected data.\n *\n * Note: This does not reset the startedAt timestamp.\n * Create a new ProfileCollector for a fresh session.\n */\n reset(): void {\n this.#patterns.clear();\n this.#queryCount = 0;\n }\n}\n","export const DEFAULT_MIN_FREQUENCY_FOR_RECOMMENDATION = 3 as const;\nexport const DEFAULT_HIGH_FREQUENCY_THRESHOLD = 10 as const;\nexport const DEFAULT_MEDIUM_FREQUENCY_THRESHOLD = 5 as const;\n","/**\n * Index Recommendations - Generates index suggestions from usage patterns.\n *\n * Analyzes collected property access patterns and generates prioritized\n * recommendations for missing indexes.\n */\n\nimport { keyToPath, pathToKey } from \"./collector\";\nimport {\n DEFAULT_HIGH_FREQUENCY_THRESHOLD,\n DEFAULT_MEDIUM_FREQUENCY_THRESHOLD,\n DEFAULT_MIN_FREQUENCY_FOR_RECOMMENDATION,\n} from \"./constants\";\nimport {\n type DeclaredIndex,\n type IndexRecommendation,\n type PropertyAccessStats,\n type PropertyPath,\n type RecommendationPriority,\n} from \"./types\";\n\n// ============================================================\n// Main Functions\n// ============================================================\n\ntype GenerateRecommendationsOptions = Readonly<{\n minFrequencyForRecommendation?: number;\n mediumFrequencyThreshold?: number;\n highFrequencyThreshold?: number;\n}>;\n\n/**\n * Generates index recommendations based on usage patterns.\n *\n * Analyzes property access patterns and returns prioritized recommendations\n * for properties that would benefit from indexing.\n *\n * @param patterns - Collected property access patterns\n * @param declaredIndexes - Indexes that already exist\n * @param options - Threshold configuration (or legacy `minFrequency` number)\n * @returns Sorted array of index recommendations\n */\nexport function generateRecommendations(\n patterns: ReadonlyMap<string, PropertyAccessStats>,\n declaredIndexes: readonly DeclaredIndex[],\n options: number | GenerateRecommendationsOptions = {},\n): readonly IndexRecommendation[] {\n const recommendations: IndexRecommendation[] = [];\n const indexedPaths = buildIndexedPathsSet(declaredIndexes);\n\n const config = normalizeRecommendationsOptions(options);\n\n for (const [key, stats] of patterns) {\n // Only recommend indexes for filter and sort contexts.\n // Select and groupBy contexts are collected for completeness (useful for debugging\n // and future features like covering index suggestions) but don't drive recommendations\n // since they don't benefit from B-tree indexes in the same way.\n const hasFilterOrSort =\n stats.contexts.has(\"filter\") || stats.contexts.has(\"sort\");\n\n if (!hasFilterOrSort) {\n continue;\n }\n\n if (stats.count < config.minFrequencyForRecommendation) {\n continue;\n }\n\n const path = keyToPath(key);\n\n // Skip system fields - they're indexed by TypeGraph and/or not indexable as props.\n if (isSystemField(path)) {\n continue;\n }\n\n // Check if already indexed\n if (isIndexed(path, indexedPaths)) {\n continue;\n }\n\n recommendations.push({\n entityType: path.entityType,\n kind: path.kind,\n fields: path.target.__type === \"prop\" ? [path.target.pointer] : [],\n reason: buildReasonString(stats),\n frequency: stats.count,\n priority: getPriority(stats.count, config),\n });\n }\n\n // Sort by priority (high first), then by frequency (descending)\n return recommendations.toSorted((a, b) => {\n const priorityOrder: Record<RecommendationPriority, number> = {\n high: 0,\n medium: 1,\n low: 2,\n };\n const priorityDiff = priorityOrder[a.priority] - priorityOrder[b.priority];\n if (priorityDiff !== 0) return priorityDiff;\n return b.frequency - a.frequency;\n });\n}\n\n/**\n * Gets properties used in filters that lack indexes.\n *\n * Useful for test assertions to ensure all filtered properties are indexed.\n *\n * @param patterns - Collected property access patterns\n * @param declaredIndexes - Indexes that already exist\n * @returns Array of unindexed property paths\n */\nexport function getUnindexedFilters(\n patterns: ReadonlyMap<string, PropertyAccessStats>,\n declaredIndexes: readonly DeclaredIndex[],\n): readonly PropertyPath[] {\n const indexedPaths = buildIndexedPathsSet(declaredIndexes);\n const unindexed: PropertyPath[] = [];\n\n for (const [key, stats] of patterns) {\n // Only check filter context\n if (!stats.contexts.has(\"filter\")) {\n continue;\n }\n\n const path = keyToPath(key);\n\n // Skip system fields\n if (isSystemField(path)) {\n continue;\n }\n\n if (!isIndexed(path, indexedPaths)) {\n unindexed.push(path);\n }\n }\n\n return unindexed;\n}\n\n// ============================================================\n// Helper Functions\n// ============================================================\n\n/**\n * Builds a set of indexed property paths for fast lookup.\n */\nfunction buildIndexedPathsSet(indexes: readonly DeclaredIndex[]): Set<string> {\n const set = new Set<string>();\n\n for (const index of indexes) {\n const firstField = index.fields[0];\n if (!firstField) continue;\n\n // Prefix matching:\n // A composite index on (a, b, c) can be used for predicates on (a).\n set.add(\n pathToKey({\n entityType: index.entityType,\n kind: index.kind,\n target: { __type: \"prop\", pointer: firstField },\n }),\n );\n }\n\n return set;\n}\n\n/**\n * Checks if a property path is covered by an index.\n */\nfunction isIndexed(path: PropertyPath, indexedPaths: Set<string>): boolean {\n return indexedPaths.has(pathToKey(path));\n}\n\n/**\n * Checks if a property path refers to a system field.\n */\nfunction isSystemField(path: PropertyPath): boolean {\n return path.target.__type === \"system\";\n}\n\n/**\n * Builds a human-readable reason string for a recommendation.\n */\nfunction buildReasonString(stats: PropertyAccessStats): string {\n const contexts = [...stats.contexts].join(\", \");\n const predicates = [...stats.predicateTypes];\n\n let reason = `Used in ${contexts}`;\n if (predicates.length > 0) {\n reason += ` with ${predicates.join(\", \")}`;\n }\n reason += ` (${stats.count} ${stats.count === 1 ? \"time\" : \"times\"})`;\n\n return reason;\n}\n\n/**\n * Determines recommendation priority based on access frequency.\n */\ntype NormalizedRecommendationsOptions = Readonly<{\n minFrequencyForRecommendation: number;\n mediumFrequencyThreshold: number;\n highFrequencyThreshold: number;\n}>;\n\nfunction normalizeRecommendationsOptions(\n options: number | GenerateRecommendationsOptions,\n): NormalizedRecommendationsOptions {\n if (typeof options === \"number\") {\n return {\n minFrequencyForRecommendation: options,\n mediumFrequencyThreshold: DEFAULT_MEDIUM_FREQUENCY_THRESHOLD,\n highFrequencyThreshold: DEFAULT_HIGH_FREQUENCY_THRESHOLD,\n };\n }\n\n return {\n minFrequencyForRecommendation:\n options.minFrequencyForRecommendation ??\n DEFAULT_MIN_FREQUENCY_FOR_RECOMMENDATION,\n mediumFrequencyThreshold:\n options.mediumFrequencyThreshold ?? DEFAULT_MEDIUM_FREQUENCY_THRESHOLD,\n highFrequencyThreshold:\n options.highFrequencyThreshold ?? DEFAULT_HIGH_FREQUENCY_THRESHOLD,\n };\n}\n\nfunction getPriority(\n frequency: number,\n options: NormalizedRecommendationsOptions,\n): RecommendationPriority {\n if (frequency >= options.highFrequencyThreshold) return \"high\";\n if (frequency >= options.mediumFrequencyThreshold) return \"medium\";\n return \"low\";\n}\n","/**\n * QueryProfiler - Main profiler class.\n *\n * Captures query patterns from the AST and generates index recommendations.\n * Uses Proxy to wrap Store and QueryBuilder for transparent interception.\n */\n\nimport { type z } from \"zod\";\n\nimport { type GraphDef } from \"../core/define-graph\";\nimport { type QueryAst } from \"../query/ast\";\nimport { resolveFieldTypeInfoAtJsonPointer } from \"../query/field-type-info\";\nimport {\n type JsonPointer,\n jsonPointer,\n parseJsonPointer,\n} from \"../query/json-pointer\";\nimport {\n createSchemaIntrospector,\n type SchemaIntrospector,\n} from \"../query/schema-introspector\";\nimport { type Store } from \"../store/store\";\nimport { extractPropertyAccesses } from \"./ast-extractor\";\nimport { ProfileCollector } from \"./collector\";\nimport {\n DEFAULT_HIGH_FREQUENCY_THRESHOLD,\n DEFAULT_MEDIUM_FREQUENCY_THRESHOLD,\n DEFAULT_MIN_FREQUENCY_FOR_RECOMMENDATION,\n} from \"./constants\";\nimport {\n generateRecommendations,\n getUnindexedFilters,\n} from \"./recommendations\";\nimport {\n type DeclaredIndex,\n type ProfileReport,\n type ProfilerOptions,\n type PropertyPath,\n} from \"./types\";\n\n// ============================================================\n// ProfiledStore Type\n// ============================================================\n\n/**\n * A Store with profiling capabilities.\n *\n * Behaves exactly like a regular Store but tracks all query executions.\n * Access the profiler via the `profiler` property.\n */\nexport type ProfiledStore<G extends GraphDef> = Store<G> & {\n /** The profiler instance attached to this store */\n readonly profiler: QueryProfiler;\n};\n\n// ============================================================\n// QueryProfiler Class\n// ============================================================\n\n/**\n * QueryProfiler captures and analyzes query patterns.\n *\n * Attach to a store to automatically track all query executions,\n * then generate reports with index recommendations.\n *\n * @example\n * ```typescript\n * import { QueryProfiler } from \"@nicia-ai/typegraph/profiler\";\n *\n * const profiler = new QueryProfiler({\n * declaredIndexes: [\n * { nodeKind: \"Person\", fields: [\"email\"], unique: true, name: \"idx_email\" },\n * ],\n * });\n *\n * const profiledStore = profiler.attachToStore(store);\n *\n * // Run queries...\n * await profiledStore.query()\n * .from(\"Person\", \"p\")\n * .whereNode(\"p\", (p) => p.email.eq(\"alice@example.com\"))\n * .select((ctx) => ctx.p)\n * .execute();\n *\n * // Get report\n * const report = profiler.getReport();\n * console.log(report.recommendations);\n * ```\n */\nexport class QueryProfiler {\n readonly #collector = new ProfileCollector();\n readonly #declaredIndexes: readonly DeclaredIndex[];\n readonly #minFrequencyForRecommendation: number;\n readonly #mediumFrequencyThreshold: number;\n readonly #highFrequencyThreshold: number;\n #schemaIntrospector: SchemaIntrospector | undefined;\n #attached = false;\n\n constructor(options?: ProfilerOptions) {\n this.#declaredIndexes = options?.declaredIndexes ?? [];\n this.#minFrequencyForRecommendation =\n options?.minFrequencyForRecommendation ??\n DEFAULT_MIN_FREQUENCY_FOR_RECOMMENDATION;\n this.#mediumFrequencyThreshold =\n options?.mediumFrequencyThreshold ?? DEFAULT_MEDIUM_FREQUENCY_THRESHOLD;\n this.#highFrequencyThreshold =\n options?.highFrequencyThreshold ?? DEFAULT_HIGH_FREQUENCY_THRESHOLD;\n }\n\n /**\n * Records a query execution from its AST.\n *\n * This is called automatically when attached to a store.\n * Can also be called manually for custom integrations.\n *\n * @param ast - The query AST to analyze\n */\n recordQuery(ast: QueryAst): void {\n this.#collector.recordQuery();\n\n const accesses = extractPropertyAccesses(ast);\n for (const access of accesses) {\n const paths = resolveAccessPaths(access, this.#schemaIntrospector);\n for (const path of paths) {\n this.#collector.record(path, access.context, access.predicateType);\n }\n }\n }\n\n /**\n * Attaches the profiler to a store.\n *\n * Returns a wrapped store that tracks all query executions.\n * The wrapped store behaves identically to the original.\n *\n * @param store - The store to attach to\n * @returns A profiled store with the `profiler` property\n * @throws Error if the profiler is already attached to another store\n */\n attachToStore<G extends GraphDef>(store: Store<G>): ProfiledStore<G> {\n if (this.#attached) {\n throw new Error(\n \"Profiler is already attached. Call detach() first or create a new profiler.\",\n );\n }\n this.#attached = true;\n this.#schemaIntrospector = createSchemaIntrospector(\n buildNodeSchemaMap(store.graph),\n buildEdgeSchemaMap(store.graph),\n );\n return createProfiledStore(store, this);\n }\n\n /**\n * Generates a complete profile report.\n *\n * The report includes:\n * - All property access patterns with frequency and context\n * - Index recommendations sorted by priority\n * - List of unindexed filter properties\n * - Summary statistics\n *\n * @returns The profile report\n */\n getReport(): ProfileReport {\n const patterns = this.#collector.getPatterns();\n const summary = this.#collector.getSummary();\n\n return {\n patterns,\n recommendations: generateRecommendations(\n patterns,\n this.#declaredIndexes,\n {\n minFrequencyForRecommendation: this.#minFrequencyForRecommendation,\n mediumFrequencyThreshold: this.#mediumFrequencyThreshold,\n highFrequencyThreshold: this.#highFrequencyThreshold,\n },\n ),\n summary,\n unindexedFilters: getUnindexedFilters(patterns, this.#declaredIndexes),\n };\n }\n\n /**\n * Checks if all filtered properties are covered by indexes.\n *\n * Throws an error if any filtered properties lack indexes.\n * Useful for test assertions to ensure query performance.\n *\n * @throws Error if unindexed filter properties are found\n *\n * @example\n * ```typescript\n * // In your test file\n * it(\"all filtered properties should be indexed\", () => {\n * profiler.assertIndexCoverage();\n * });\n * ```\n */\n assertIndexCoverage(): void {\n const report = this.getReport();\n if (report.unindexedFilters.length > 0) {\n const missing = report.unindexedFilters\n .map((p) => formatPropertyPath(p))\n .join(\", \");\n throw new Error(`Unindexed filter properties: ${missing}`);\n }\n }\n\n /**\n * Resets all collected data.\n *\n * Clears patterns and query count. Useful for starting a fresh\n * profiling session without creating a new profiler instance.\n */\n reset(): void {\n this.#collector.reset();\n }\n\n /**\n * Marks the profiler as detached.\n *\n * Call this when you're done profiling to allow reattachment\n * to the same or a different store.\n */\n detach(): void {\n this.#attached = false;\n this.#schemaIntrospector = undefined;\n }\n\n /**\n * Whether the profiler is currently attached to a store.\n */\n get isAttached(): boolean {\n return this.#attached;\n }\n}\n\nfunction buildNodeSchemaMap(\n graph: GraphDef,\n): ReadonlyMap<string, Readonly<{ schema: z.ZodType }>> {\n const entries = Object.values(graph.nodes).map(\n (n) => [n.type.kind, { schema: n.type.schema }] as const,\n );\n return new Map(entries);\n}\n\nfunction buildEdgeSchemaMap(\n graph: GraphDef,\n): ReadonlyMap<string, Readonly<{ schema: z.ZodType }>> {\n const entries = Object.values(graph.edges).map(\n (edgeRegistration) =>\n [\n edgeRegistration.type.kind,\n { schema: edgeRegistration.type.schema },\n ] as const,\n );\n return new Map(entries);\n}\n\nfunction resolveAccessPaths(\n access: ReturnType<typeof extractPropertyAccesses>[number],\n schemaIntrospector: SchemaIntrospector | undefined,\n): readonly PropertyPath[] {\n const kinds = access.kindNames;\n if (kinds.length === 0) {\n // This indicates a bug in the AST extractor - aliases should always resolve to kinds.\n // Log warning and skip rather than silently dropping data.\n warnInDevelopment(\n `[QueryProfiler] Access pattern has empty kindNames for context \"${access.context}\". ` +\n `This may indicate a bug in alias resolution.`,\n );\n return [];\n }\n\n if (!schemaIntrospector) {\n return [\n {\n entityType: access.entityType,\n kind: kinds[0]!,\n target: access.target,\n },\n ];\n }\n\n if (access.target.__type !== \"prop\") {\n return [\n {\n entityType: access.entityType,\n kind: kinds[0]!,\n target: access.target,\n },\n ];\n }\n\n const pointer = access.target.pointer;\n const matchingKinds = kinds.filter((kindName) =>\n hasPointerInSchema(\n schemaIntrospector,\n access.entityType,\n kindName,\n pointer,\n ),\n );\n\n const kindsToUse = matchingKinds.length > 0 ? matchingKinds : [kinds[0]!];\n\n return kindsToUse.map((kindName) => ({\n entityType: access.entityType,\n kind: kindName,\n target: access.target,\n }));\n}\n\nfunction warnInDevelopment(message: string, details?: unknown): void {\n if (!isDevelopmentEnvironment()) {\n return;\n }\n if (details !== undefined) {\n console.warn(message, details);\n return;\n }\n console.warn(message);\n}\n\nfunction isDevelopmentEnvironment(): boolean {\n return getNodeEnv() !== \"production\";\n}\n\nfunction getNodeEnv(): string | undefined {\n if (typeof process === \"undefined\") {\n return undefined;\n }\n return process.env.NODE_ENV;\n}\n\n/**\n * Checks whether a JSON pointer exists in the schema for the given kind.\n *\n * This is used to attribute multi-kind aliases (includeSubClasses) to the most\n * relevant concrete kinds by verifying that the accessed pointer exists.\n *\n * Returns false on missing fields or invalid pointers.\n */\nfunction hasPointerInSchema(\n schemaIntrospector: SchemaIntrospector,\n entityType: PropertyPath[\"entityType\"],\n kindName: string,\n pointer: JsonPointer,\n): boolean {\n const segments = parseJsonPointer(pointer);\n const [first, ...rest] = segments;\n if (!first) {\n return false;\n }\n\n const rootInfo =\n entityType === \"node\" ?\n schemaIntrospector.getFieldTypeInfo(kindName, first)\n : schemaIntrospector.getEdgeFieldTypeInfo(kindName, first);\n\n if (!rootInfo) {\n return false;\n }\n\n if (rest.length === 0) {\n return true;\n }\n\n try {\n const resolved = resolveFieldTypeInfoAtJsonPointer(\n rootInfo,\n jsonPointer(rest),\n );\n return resolved !== undefined;\n } catch (error) {\n warnInDevelopment(\n `[QueryProfiler] Failed to resolve pointer \"${pointer}\" for ${entityType} kind \"${kindName}\".`,\n error,\n );\n return false;\n }\n}\n\nfunction formatPropertyPath(path: PropertyPath): string {\n const target =\n path.target.__type === \"prop\" ?\n (path.target.pointer as string)\n : `$${path.target.field}`;\n return `${path.entityType}:${path.kind}:${target}`;\n}\n\n// ============================================================\n// Proxy Implementation\n// ============================================================\n\n/**\n * Creates a profiled store wrapper using Proxy.\n */\nfunction createProfiledStore<G extends GraphDef>(\n store: Store<G>,\n profiler: QueryProfiler,\n): ProfiledStore<G> {\n const storeProxyHandler: ProxyHandler<Store<G>> = {\n get(target, property, _receiver) {\n // Add profiler property\n if (property === \"profiler\") {\n return profiler;\n }\n\n // Wrap query() method\n if (property === \"query\") {\n return () => {\n const builder = target.query();\n return wrapQueryBuilder(builder, profiler);\n };\n }\n\n // IMPORTANT: Store is a class with private fields; accessors and methods\n // must be invoked with `this === target`, not the proxy receiver.\n const value: unknown = Reflect.get(target, property, target);\n\n // Bind functions to the target to preserve private field access.\n if (typeof value === \"function\") {\n return (value as (...args: unknown[]) => unknown).bind(target);\n }\n\n return value;\n },\n };\n\n return new Proxy(store, storeProxyHandler) as ProfiledStore<G>;\n}\n\n/**\n * Wraps a query builder to intercept method calls.\n *\n * The builder returns new builders for most methods, and returns\n * ExecutableQuery for select/aggregate. We need to recursively\n * wrap to ensure all paths lead to wrapped ExecutableQueries.\n */\nfunction wrapQueryBuilder<T extends object>(\n builder: T,\n profiler: QueryProfiler,\n): T {\n const builderProxyHandler: ProxyHandler<T> = {\n get(target, property, receiver) {\n const value: unknown = Reflect.get(target, property, receiver);\n\n // Not a function - return as-is\n if (typeof value !== \"function\") {\n return value;\n }\n\n // Wrap the method to intercept results\n return (...args: unknown[]): unknown => {\n const result: unknown = (\n value as (...args: unknown[]) => unknown\n ).apply(target, args);\n\n // If result is null/undefined or primitive, return as-is\n if (result === null || typeof result !== \"object\") {\n return result;\n }\n\n // Check if result is an ExecutableQuery (has toAst and execute)\n if (hasExecutableQueryShape(result)) {\n return wrapExecutableQuery(result, profiler);\n }\n\n // Check if result is a builder (has from, select, whereNode, etc.)\n if (hasQueryBuilderShape(result)) {\n return wrapQueryBuilder(result, profiler);\n }\n\n // Otherwise return as-is (e.g., compile() returns SQL)\n return result;\n };\n },\n };\n\n return new Proxy(builder, builderProxyHandler);\n}\n\n/**\n * Wraps an ExecutableQuery to intercept execute(), paginate(), stream().\n */\nfunction wrapExecutableQuery<T extends object>(\n query: T,\n profiler: QueryProfiler,\n): T {\n const executableQueryProxyHandler: ProxyHandler<T> = {\n get(target, property, receiver) {\n const value: unknown = Reflect.get(target, property, receiver);\n\n // Not a function - return as-is\n if (typeof value !== \"function\") {\n return value;\n }\n\n const fn = value as (...args: unknown[]) => unknown;\n\n // Always bind `this` to the original instance to preserve private fields.\n return (...args: unknown[]): unknown => {\n // Intercept execute, paginate, stream\n if (\n property === \"execute\" ||\n property === \"paginate\" ||\n property === \"stream\"\n ) {\n const toAst = Reflect.get(\n target,\n \"toAst\",\n receiver,\n ) as () => QueryAst;\n const ast = toAst.call(target);\n profiler.recordQuery(ast);\n }\n\n const result: unknown = fn.apply(target, args);\n\n // Any method that returns an ExecutableQuery-shaped object should remain wrapped.\n // Using duck-typing rather than a method whitelist ensures new chainable methods\n // (e.g., orderBy, limit, offset, pipe, union, intersect, etc.) are automatically handled.\n if (\n result &&\n typeof result === \"object\" &&\n hasExecutableQueryShape(result)\n ) {\n return wrapExecutableQuery(result, profiler);\n }\n\n return result;\n };\n },\n };\n\n return new Proxy(query, executableQueryProxyHandler);\n}\n\n// ============================================================\n// Type Guards\n// ============================================================\n\n/**\n * Checks if an object looks like an ExecutableQuery.\n */\nfunction hasExecutableQueryShape(object: object): boolean {\n return (\n \"toAst\" in object &&\n typeof object.toAst === \"function\" &&\n \"execute\" in object &&\n typeof object.execute === \"function\"\n );\n}\n\n/**\n * Checks if an object looks like a QueryBuilder or TraversalBuilder.\n * Covers both the main query builder and traversal/edge builder chains.\n */\nfunction hasQueryBuilderShape(object: object): boolean {\n return (\n (\"from\" in object && typeof object.from === \"function\") ||\n (\"select\" in object && typeof object.select === \"function\") ||\n (\"whereNode\" in object && typeof object.whereNode === \"function\") ||\n (\"traverse\" in object && typeof object.traverse === \"function\") ||\n // Traversal builder methods\n (\"whereEdge\" in object && typeof object.whereEdge === \"function\") ||\n (\"to\" in object && typeof object.to === \"function\")\n );\n}\n"]}
|
package/dist/schema/index.cjs
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('../chunk-
|
|
5
|
-
require('../chunk-
|
|
3
|
+
var chunk7W3KAMVQ_cjs = require('../chunk-7W3KAMVQ.cjs');
|
|
4
|
+
require('../chunk-E5JZSEGJ.cjs');
|
|
5
|
+
require('../chunk-RCAJZG67.cjs');
|
|
6
|
+
require('../chunk-CTHNVU6K.cjs');
|
|
7
|
+
require('../chunk-EK6RJ373.cjs');
|
|
8
|
+
require('../chunk-X3244EKP.cjs');
|
|
9
|
+
require('../chunk-W5MTHMTE.cjs');
|
|
10
|
+
require('../chunk-7V335GHG.cjs');
|
|
6
11
|
|
|
7
12
|
// src/schema/deserializer.ts
|
|
8
13
|
function deserializeSchema(schema) {
|
|
@@ -42,7 +47,7 @@ function buildRegistryFromClosures(schema) {
|
|
|
42
47
|
const edgeImplyingClosure = recordToMap(closures.edgeImplyingClosure);
|
|
43
48
|
const nodeKinds = /* @__PURE__ */ new Map();
|
|
44
49
|
const edgeKinds = /* @__PURE__ */ new Map();
|
|
45
|
-
return new
|
|
50
|
+
return new chunk7W3KAMVQ_cjs.KindRegistry(nodeKinds, edgeKinds, {
|
|
46
51
|
subClassAncestors,
|
|
47
52
|
subClassDescendants,
|
|
48
53
|
broaderClosure,
|
|
@@ -68,77 +73,93 @@ function simpleRecordToMap(record) {
|
|
|
68
73
|
return new Map(Object.entries(record));
|
|
69
74
|
}
|
|
70
75
|
|
|
76
|
+
Object.defineProperty(exports, "applyDeprecatedKinds", {
|
|
77
|
+
enumerable: true,
|
|
78
|
+
get: function () { return chunk7W3KAMVQ_cjs.applyDeprecatedKinds; }
|
|
79
|
+
});
|
|
71
80
|
Object.defineProperty(exports, "computeSchemaDiff", {
|
|
72
81
|
enumerable: true,
|
|
73
|
-
get: function () { return
|
|
82
|
+
get: function () { return chunk7W3KAMVQ_cjs.computeSchemaDiff; }
|
|
74
83
|
});
|
|
75
84
|
Object.defineProperty(exports, "computeSchemaHash", {
|
|
76
85
|
enumerable: true,
|
|
77
|
-
get: function () { return
|
|
86
|
+
get: function () { return chunk7W3KAMVQ_cjs.computeSchemaHash; }
|
|
78
87
|
});
|
|
79
88
|
Object.defineProperty(exports, "createValidationError", {
|
|
80
89
|
enumerable: true,
|
|
81
|
-
get: function () { return
|
|
90
|
+
get: function () { return chunk7W3KAMVQ_cjs.createValidationError; }
|
|
82
91
|
});
|
|
83
92
|
Object.defineProperty(exports, "deserializeWherePredicate", {
|
|
84
93
|
enumerable: true,
|
|
85
|
-
get: function () { return
|
|
94
|
+
get: function () { return chunk7W3KAMVQ_cjs.deserializeWherePredicate; }
|
|
86
95
|
});
|
|
87
96
|
Object.defineProperty(exports, "ensureSchema", {
|
|
88
97
|
enumerable: true,
|
|
89
|
-
get: function () { return
|
|
98
|
+
get: function () { return chunk7W3KAMVQ_cjs.ensureSchema; }
|
|
90
99
|
});
|
|
91
100
|
Object.defineProperty(exports, "getActiveSchema", {
|
|
92
101
|
enumerable: true,
|
|
93
|
-
get: function () { return
|
|
102
|
+
get: function () { return chunk7W3KAMVQ_cjs.getActiveSchema; }
|
|
94
103
|
});
|
|
95
104
|
Object.defineProperty(exports, "getMigrationActions", {
|
|
96
105
|
enumerable: true,
|
|
97
|
-
get: function () { return
|
|
106
|
+
get: function () { return chunk7W3KAMVQ_cjs.getMigrationActions; }
|
|
98
107
|
});
|
|
99
108
|
Object.defineProperty(exports, "getSchemaChanges", {
|
|
100
109
|
enumerable: true,
|
|
101
|
-
get: function () { return
|
|
110
|
+
get: function () { return chunk7W3KAMVQ_cjs.getSchemaChanges; }
|
|
102
111
|
});
|
|
103
112
|
Object.defineProperty(exports, "initializeSchema", {
|
|
104
113
|
enumerable: true,
|
|
105
|
-
get: function () { return
|
|
114
|
+
get: function () { return chunk7W3KAMVQ_cjs.initializeSchema; }
|
|
106
115
|
});
|
|
107
116
|
Object.defineProperty(exports, "isBackwardsCompatible", {
|
|
108
117
|
enumerable: true,
|
|
109
|
-
get: function () { return
|
|
118
|
+
get: function () { return chunk7W3KAMVQ_cjs.isBackwardsCompatible; }
|
|
110
119
|
});
|
|
111
120
|
Object.defineProperty(exports, "isSchemaInitialized", {
|
|
112
121
|
enumerable: true,
|
|
113
|
-
get: function () { return
|
|
122
|
+
get: function () { return chunk7W3KAMVQ_cjs.isSchemaInitialized; }
|
|
123
|
+
});
|
|
124
|
+
Object.defineProperty(exports, "loadActiveSchemaWithBootstrap", {
|
|
125
|
+
enumerable: true,
|
|
126
|
+
get: function () { return chunk7W3KAMVQ_cjs.loadActiveSchemaWithBootstrap; }
|
|
127
|
+
});
|
|
128
|
+
Object.defineProperty(exports, "loadAndMergeGraphExtensionDocument", {
|
|
129
|
+
enumerable: true,
|
|
130
|
+
get: function () { return chunk7W3KAMVQ_cjs.loadAndMergeGraphExtensionDocument; }
|
|
114
131
|
});
|
|
115
132
|
Object.defineProperty(exports, "migrateSchema", {
|
|
116
133
|
enumerable: true,
|
|
117
|
-
get: function () { return
|
|
134
|
+
get: function () { return chunk7W3KAMVQ_cjs.migrateSchema; }
|
|
135
|
+
});
|
|
136
|
+
Object.defineProperty(exports, "parseSerializedSchema", {
|
|
137
|
+
enumerable: true,
|
|
138
|
+
get: function () { return chunk7W3KAMVQ_cjs.parseSerializedSchema; }
|
|
118
139
|
});
|
|
119
140
|
Object.defineProperty(exports, "rollbackSchema", {
|
|
120
141
|
enumerable: true,
|
|
121
|
-
get: function () { return
|
|
142
|
+
get: function () { return chunk7W3KAMVQ_cjs.rollbackSchema; }
|
|
122
143
|
});
|
|
123
144
|
Object.defineProperty(exports, "serializeSchema", {
|
|
124
145
|
enumerable: true,
|
|
125
|
-
get: function () { return
|
|
146
|
+
get: function () { return chunk7W3KAMVQ_cjs.serializeSchema; }
|
|
126
147
|
});
|
|
127
148
|
Object.defineProperty(exports, "validateEdgeProps", {
|
|
128
149
|
enumerable: true,
|
|
129
|
-
get: function () { return
|
|
150
|
+
get: function () { return chunk7W3KAMVQ_cjs.validateEdgeProps; }
|
|
130
151
|
});
|
|
131
152
|
Object.defineProperty(exports, "validateNodeProps", {
|
|
132
153
|
enumerable: true,
|
|
133
|
-
get: function () { return
|
|
154
|
+
get: function () { return chunk7W3KAMVQ_cjs.validateNodeProps; }
|
|
134
155
|
});
|
|
135
156
|
Object.defineProperty(exports, "validateProps", {
|
|
136
157
|
enumerable: true,
|
|
137
|
-
get: function () { return
|
|
158
|
+
get: function () { return chunk7W3KAMVQ_cjs.validateProps; }
|
|
138
159
|
});
|
|
139
160
|
Object.defineProperty(exports, "wrapZodError", {
|
|
140
161
|
enumerable: true,
|
|
141
|
-
get: function () { return
|
|
162
|
+
get: function () { return chunk7W3KAMVQ_cjs.wrapZodError; }
|
|
142
163
|
});
|
|
143
164
|
exports.deserializeSchema = deserializeSchema;
|
|
144
165
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/schema/deserializer.ts"],"names":["KindRegistry"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/schema/deserializer.ts"],"names":["KindRegistry"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Schema deserializer for loading stored schemas.\n *\n * Reconstructs runtime objects from SerializedSchema.\n * Note: Zod schemas cannot be fully reconstructed from JSON Schema,\n * so this provides access to the serialized data for introspection.\n */\nimport { KindRegistry } from \"../registry/kind-registry\";\nimport {\n type SerializedClosures,\n type SerializedEdgeDef,\n type SerializedMetaEdge,\n type SerializedNodeDef,\n type SerializedOntologyRelation,\n type SerializedSchema,\n} from \"./types\";\n\n// ============================================================\n// Deserialized Schema\n// ============================================================\n\n/**\n * A deserialized schema provides read-only access to schema metadata.\n *\n * Note: Unlike the original GraphDef, this does not include Zod schemas\n * since those cannot be reconstructed from JSON Schema. Use this for\n * introspection and metadata access only.\n */\nexport type DeserializedSchema = Readonly<{\n graphId: string;\n version: number;\n generatedAt: string;\n\n /** Get node definition by name */\n getNode: (name: string) => SerializedNodeDef | undefined;\n\n /** Get all node names */\n getNodeNames: () => readonly string[];\n\n /** Get edge definition by name */\n getEdge: (name: string) => SerializedEdgeDef | undefined;\n\n /** Get all edge names */\n getEdgeNames: () => readonly string[];\n\n /** Get meta-edge definition by name */\n getMetaEdge: (name: string) => SerializedMetaEdge | undefined;\n\n /** Get all meta-edge names */\n getMetaEdgeNames: () => readonly string[];\n\n /** Get all ontology relations */\n getRelations: () => readonly SerializedOntologyRelation[];\n\n /** Get precomputed closures */\n getClosures: () => SerializedClosures;\n\n /** Get graph defaults */\n getDefaults: () => SerializedSchema[\"defaults\"];\n\n /** Get the raw serialized schema */\n getRaw: () => SerializedSchema;\n\n /** Build a KindRegistry from the closures */\n buildRegistry: () => KindRegistry;\n}>;\n\n// ============================================================\n// Deserialization\n// ============================================================\n\n/**\n * Deserializes a SerializedSchema into a DeserializedSchema.\n *\n * @param schema - The serialized schema to deserialize\n * @returns A deserialized schema with accessor methods\n */\nexport function deserializeSchema(\n schema: SerializedSchema,\n): DeserializedSchema {\n const nodeNames = Object.keys(schema.nodes);\n const edgeNames = Object.keys(schema.edges);\n const metaEdgeNames = Object.keys(schema.ontology.metaEdges);\n\n return {\n graphId: schema.graphId,\n version: schema.version,\n generatedAt: schema.generatedAt,\n\n getNode: (name) => schema.nodes[name],\n getNodeNames: () => nodeNames,\n\n getEdge: (name) => schema.edges[name],\n getEdgeNames: () => edgeNames,\n\n getMetaEdge: (name) => schema.ontology.metaEdges[name],\n getMetaEdgeNames: () => metaEdgeNames,\n\n getRelations: () => schema.ontology.relations,\n getClosures: () => schema.ontology.closures,\n\n getDefaults: () => schema.defaults,\n getRaw: () => schema,\n\n buildRegistry: () => buildRegistryFromClosures(schema),\n };\n}\n\n// ============================================================\n// Registry Building\n// ============================================================\n\n/**\n * Builds a KindRegistry from serialized closures.\n *\n * This allows query execution without recomputing closures.\n */\nfunction buildRegistryFromClosures(schema: SerializedSchema): KindRegistry {\n const { closures } = schema.ontology;\n\n // Convert Record<string, string[]> back to Map<string, Set<string>>\n const subClassAncestors = recordToMap(closures.subClassAncestors);\n const subClassDescendants = recordToMap(closures.subClassDescendants);\n const broaderClosure = recordToMap(closures.broaderClosure);\n const narrowerClosure = recordToMap(closures.narrowerClosure);\n const equivalenceSets = recordToMap(closures.equivalenceSets);\n const partOfClosure = recordToMap(closures.partOfClosure);\n const hasPartClosure = recordToMap(closures.hasPartClosure);\n const iriToKind = simpleRecordToMap(closures.iriToKind);\n const disjointPairs = new Set(closures.disjointPairs);\n const edgeInverses = simpleRecordToMap(closures.edgeInverses);\n const edgeImplicationsClosure = recordToMap(closures.edgeImplicationsClosure);\n const edgeImplyingClosure = recordToMap(closures.edgeImplyingClosure);\n\n // Build empty node/edge kind maps (we don't have the actual Zod schemas)\n const nodeKinds = new Map();\n const edgeKinds = new Map();\n\n return new KindRegistry(nodeKinds, edgeKinds, {\n subClassAncestors,\n subClassDescendants,\n broaderClosure,\n narrowerClosure,\n equivalenceSets,\n iriToKind,\n disjointPairs,\n partOfClosure,\n hasPartClosure,\n edgeInverses,\n edgeImplicationsClosure,\n edgeImplyingClosure,\n });\n}\n\n/**\n * Converts Record<string, string[]> to Map<string, Set<string>>.\n */\nfunction recordToMap(\n record: Record<string, readonly string[]>,\n): ReadonlyMap<string, ReadonlySet<string>> {\n const result = new Map<string, Set<string>>();\n for (const [key, values] of Object.entries(record)) {\n result.set(key, new Set(values));\n }\n return result;\n}\n\n/**\n * Converts Record<string, string> to Map<string, string>.\n */\nfunction simpleRecordToMap(\n record: Record<string, string>,\n): ReadonlyMap<string, string> {\n return new Map(Object.entries(record));\n}\n"]}
|
package/dist/schema/index.d.cts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { K as KindRegistry, G as GraphDef } from '../manager-
|
|
2
|
-
export { C as ChangeSeverity,
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
1
|
+
import { K as KindRegistry, G as GraphDef } from '../manager-BpjBW1JK.cjs';
|
|
2
|
+
export { C as ChangeSeverity, a as ChangeType, D as DeprecatedKindsChange, E as EdgeChange, b as ExtensionChange, I as IndexChange, M as MigrationHookContext, N as NodeChange, O as OntologyChange, S as SchemaDiff, c as SchemaManagerOptions, d as SchemaValidationResult, e as applyDeprecatedKinds, f as computeSchemaDiff, g as ensureSchema, h as getActiveSchema, i as getMigrationActions, j as getSchemaChanges, k as initializeSchema, l as isBackwardsCompatible, m as isSchemaInitialized, n as loadActiveSchemaWithBootstrap, o as loadAndMergeGraphExtensionDocument, p as migrateSchema, q as parseSerializedSchema, r as rollbackSchema } from '../manager-BpjBW1JK.cjs';
|
|
3
|
+
import { S as SerializedNodeDef, d as SerializedEdgeDef, e as SerializedMetaEdge, f as SerializedOntologyRelation, g as SerializedClosures, h as SerializedSchema, i as SchemaHash } from '../types--0EslBx5.cjs';
|
|
4
|
+
export { j as JsonSchema, k as SerializedOntology, l as SerializedUniqueConstraint } from '../types--0EslBx5.cjs';
|
|
5
|
+
import { a as NullCheckOp, K as KindEntity } from '../extension-types-D07e_NTw.cjs';
|
|
5
6
|
import { ZodType, ZodError } from 'zod';
|
|
6
|
-
import {
|
|
7
|
+
import { V as ValidationIssue, a as ValidationError } from '../index-CT6nvtxL.cjs';
|
|
7
8
|
import 'drizzle-orm';
|
|
9
|
+
import '../materialize-indexes-BB9N5uQl.cjs';
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* Schema deserializer for loading stored schemas.
|
|
@@ -56,6 +58,13 @@ type DeserializedSchema = Readonly<{
|
|
|
56
58
|
*/
|
|
57
59
|
declare function deserializeSchema(schema: SerializedSchema): DeserializedSchema;
|
|
58
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Schema serializer for homoiconic storage.
|
|
63
|
+
*
|
|
64
|
+
* Converts a GraphDef to a SerializedSchema for database storage.
|
|
65
|
+
* Uses Zod's toJSONSchema() for property schema serialization.
|
|
66
|
+
*/
|
|
67
|
+
|
|
59
68
|
/**
|
|
60
69
|
* Serializes a GraphDef to a SerializedSchema.
|
|
61
70
|
*
|
|
@@ -70,7 +79,7 @@ declare function serializeSchema<G extends GraphDef>(graph: G, version: number):
|
|
|
70
79
|
type SerializedPredicate = Readonly<{
|
|
71
80
|
__type: "unique_predicate";
|
|
72
81
|
field: string;
|
|
73
|
-
op:
|
|
82
|
+
op: NullCheckOp;
|
|
74
83
|
}>;
|
|
75
84
|
/**
|
|
76
85
|
* Field builder returned by the predicate proxy.
|
|
@@ -98,7 +107,7 @@ type PredicateBuilder = Readonly<Record<string, FieldPredicateBuilder>>;
|
|
|
98
107
|
type UniquePredicate = Readonly<{
|
|
99
108
|
__type: "unique_predicate";
|
|
100
109
|
field: string;
|
|
101
|
-
op:
|
|
110
|
+
op: NullCheckOp;
|
|
102
111
|
}>;
|
|
103
112
|
declare function deserializeWherePredicate(serialized: string): (builder: PredicateBuilder) => UniquePredicate;
|
|
104
113
|
/**
|
|
@@ -128,7 +137,7 @@ declare function computeSchemaHash(schema: SerializedSchema): Promise<SchemaHash
|
|
|
128
137
|
*/
|
|
129
138
|
type ValidationContext = Readonly<{
|
|
130
139
|
/** Type of entity being validated */
|
|
131
|
-
entityType:
|
|
140
|
+
entityType: KindEntity;
|
|
132
141
|
/** Kind/type name of the entity */
|
|
133
142
|
kind: string;
|
|
134
143
|
/** Operation being performed */
|
package/dist/schema/index.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { K as KindRegistry, G as GraphDef } from '../manager-
|
|
2
|
-
export { C as ChangeSeverity,
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
1
|
+
import { K as KindRegistry, G as GraphDef } from '../manager-BKaPQbns.js';
|
|
2
|
+
export { C as ChangeSeverity, a as ChangeType, D as DeprecatedKindsChange, E as EdgeChange, b as ExtensionChange, I as IndexChange, M as MigrationHookContext, N as NodeChange, O as OntologyChange, S as SchemaDiff, c as SchemaManagerOptions, d as SchemaValidationResult, e as applyDeprecatedKinds, f as computeSchemaDiff, g as ensureSchema, h as getActiveSchema, i as getMigrationActions, j as getSchemaChanges, k as initializeSchema, l as isBackwardsCompatible, m as isSchemaInitialized, n as loadActiveSchemaWithBootstrap, o as loadAndMergeGraphExtensionDocument, p as migrateSchema, q as parseSerializedSchema, r as rollbackSchema } from '../manager-BKaPQbns.js';
|
|
3
|
+
import { S as SerializedNodeDef, d as SerializedEdgeDef, e as SerializedMetaEdge, f as SerializedOntologyRelation, g as SerializedClosures, h as SerializedSchema, i as SchemaHash } from '../types-BNWYZ-0-.js';
|
|
4
|
+
export { j as JsonSchema, k as SerializedOntology, l as SerializedUniqueConstraint } from '../types-BNWYZ-0-.js';
|
|
5
|
+
import { a as NullCheckOp, K as KindEntity } from '../extension-types-D07e_NTw.js';
|
|
5
6
|
import { ZodType, ZodError } from 'zod';
|
|
6
|
-
import {
|
|
7
|
+
import { V as ValidationIssue, a as ValidationError } from '../index-DQheiVQV.js';
|
|
7
8
|
import 'drizzle-orm';
|
|
9
|
+
import '../materialize-indexes-BYpU2RKh.js';
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* Schema deserializer for loading stored schemas.
|
|
@@ -56,6 +58,13 @@ type DeserializedSchema = Readonly<{
|
|
|
56
58
|
*/
|
|
57
59
|
declare function deserializeSchema(schema: SerializedSchema): DeserializedSchema;
|
|
58
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Schema serializer for homoiconic storage.
|
|
63
|
+
*
|
|
64
|
+
* Converts a GraphDef to a SerializedSchema for database storage.
|
|
65
|
+
* Uses Zod's toJSONSchema() for property schema serialization.
|
|
66
|
+
*/
|
|
67
|
+
|
|
59
68
|
/**
|
|
60
69
|
* Serializes a GraphDef to a SerializedSchema.
|
|
61
70
|
*
|
|
@@ -70,7 +79,7 @@ declare function serializeSchema<G extends GraphDef>(graph: G, version: number):
|
|
|
70
79
|
type SerializedPredicate = Readonly<{
|
|
71
80
|
__type: "unique_predicate";
|
|
72
81
|
field: string;
|
|
73
|
-
op:
|
|
82
|
+
op: NullCheckOp;
|
|
74
83
|
}>;
|
|
75
84
|
/**
|
|
76
85
|
* Field builder returned by the predicate proxy.
|
|
@@ -98,7 +107,7 @@ type PredicateBuilder = Readonly<Record<string, FieldPredicateBuilder>>;
|
|
|
98
107
|
type UniquePredicate = Readonly<{
|
|
99
108
|
__type: "unique_predicate";
|
|
100
109
|
field: string;
|
|
101
|
-
op:
|
|
110
|
+
op: NullCheckOp;
|
|
102
111
|
}>;
|
|
103
112
|
declare function deserializeWherePredicate(serialized: string): (builder: PredicateBuilder) => UniquePredicate;
|
|
104
113
|
/**
|
|
@@ -128,7 +137,7 @@ declare function computeSchemaHash(schema: SerializedSchema): Promise<SchemaHash
|
|
|
128
137
|
*/
|
|
129
138
|
type ValidationContext = Readonly<{
|
|
130
139
|
/** Type of entity being validated */
|
|
131
|
-
entityType:
|
|
140
|
+
entityType: KindEntity;
|
|
132
141
|
/** Kind/type name of the entity */
|
|
133
142
|
kind: string;
|
|
134
143
|
/** Operation being performed */
|