@nicia-ai/typegraph 0.1.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.
Files changed (131) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +47 -0
  3. package/dist/ast-BVyihVbP.d.cts +564 -0
  4. package/dist/ast-BVyihVbP.d.ts +564 -0
  5. package/dist/backend/drizzle/index.cjs +41 -0
  6. package/dist/backend/drizzle/index.cjs.map +1 -0
  7. package/dist/backend/drizzle/index.d.cts +12 -0
  8. package/dist/backend/drizzle/index.d.ts +12 -0
  9. package/dist/backend/drizzle/index.js +12 -0
  10. package/dist/backend/drizzle/index.js.map +1 -0
  11. package/dist/backend/drizzle/postgres.cjs +27 -0
  12. package/dist/backend/drizzle/postgres.cjs.map +1 -0
  13. package/dist/backend/drizzle/postgres.d.cts +37 -0
  14. package/dist/backend/drizzle/postgres.d.ts +37 -0
  15. package/dist/backend/drizzle/postgres.js +10 -0
  16. package/dist/backend/drizzle/postgres.js.map +1 -0
  17. package/dist/backend/drizzle/schema/postgres.cjs +40 -0
  18. package/dist/backend/drizzle/schema/postgres.cjs.map +1 -0
  19. package/dist/backend/drizzle/schema/postgres.d.cts +2419 -0
  20. package/dist/backend/drizzle/schema/postgres.d.ts +2419 -0
  21. package/dist/backend/drizzle/schema/postgres.js +7 -0
  22. package/dist/backend/drizzle/schema/postgres.js.map +1 -0
  23. package/dist/backend/drizzle/schema/sqlite.cjs +40 -0
  24. package/dist/backend/drizzle/schema/sqlite.cjs.map +1 -0
  25. package/dist/backend/drizzle/schema/sqlite.d.cts +2647 -0
  26. package/dist/backend/drizzle/schema/sqlite.d.ts +2647 -0
  27. package/dist/backend/drizzle/schema/sqlite.js +7 -0
  28. package/dist/backend/drizzle/schema/sqlite.js.map +1 -0
  29. package/dist/backend/drizzle/sqlite.cjs +27 -0
  30. package/dist/backend/drizzle/sqlite.cjs.map +1 -0
  31. package/dist/backend/drizzle/sqlite.d.cts +36 -0
  32. package/dist/backend/drizzle/sqlite.d.ts +36 -0
  33. package/dist/backend/drizzle/sqlite.js +10 -0
  34. package/dist/backend/drizzle/sqlite.js.map +1 -0
  35. package/dist/backend/postgres/index.cjs +53 -0
  36. package/dist/backend/postgres/index.cjs.map +1 -0
  37. package/dist/backend/postgres/index.d.cts +12 -0
  38. package/dist/backend/postgres/index.d.ts +12 -0
  39. package/dist/backend/postgres/index.js +12 -0
  40. package/dist/backend/postgres/index.js.map +1 -0
  41. package/dist/backend/sqlite/index.cjs +117 -0
  42. package/dist/backend/sqlite/index.cjs.map +1 -0
  43. package/dist/backend/sqlite/index.d.cts +71 -0
  44. package/dist/backend/sqlite/index.d.ts +71 -0
  45. package/dist/backend/sqlite/index.js +78 -0
  46. package/dist/backend/sqlite/index.js.map +1 -0
  47. package/dist/chunk-2QHQ2C4P.js +146 -0
  48. package/dist/chunk-2QHQ2C4P.js.map +1 -0
  49. package/dist/chunk-3A5TKOEJ.js +306 -0
  50. package/dist/chunk-3A5TKOEJ.js.map +1 -0
  51. package/dist/chunk-4PIEL2VO.js +162 -0
  52. package/dist/chunk-4PIEL2VO.js.map +1 -0
  53. package/dist/chunk-536PH5FT.js +342 -0
  54. package/dist/chunk-536PH5FT.js.map +1 -0
  55. package/dist/chunk-DBFCKELK.cjs +156 -0
  56. package/dist/chunk-DBFCKELK.cjs.map +1 -0
  57. package/dist/chunk-DDM2FZRJ.cjs +1143 -0
  58. package/dist/chunk-DDM2FZRJ.cjs.map +1 -0
  59. package/dist/chunk-DGUM43GV.js +10 -0
  60. package/dist/chunk-DGUM43GV.js.map +1 -0
  61. package/dist/chunk-F32HCHYA.cjs +680 -0
  62. package/dist/chunk-F32HCHYA.cjs.map +1 -0
  63. package/dist/chunk-IIAT36MI.js +353 -0
  64. package/dist/chunk-IIAT36MI.js.map +1 -0
  65. package/dist/chunk-JDAET5LO.js +236 -0
  66. package/dist/chunk-JDAET5LO.js.map +1 -0
  67. package/dist/chunk-JEQ2X3Z6.cjs +12 -0
  68. package/dist/chunk-JEQ2X3Z6.cjs.map +1 -0
  69. package/dist/chunk-JKTO7TW3.js +299 -0
  70. package/dist/chunk-JKTO7TW3.js.map +1 -0
  71. package/dist/chunk-K7SQ3SWP.js +497 -0
  72. package/dist/chunk-K7SQ3SWP.js.map +1 -0
  73. package/dist/chunk-L642L24T.js +142 -0
  74. package/dist/chunk-L642L24T.js.map +1 -0
  75. package/dist/chunk-MFVCSNIY.cjs +308 -0
  76. package/dist/chunk-MFVCSNIY.cjs.map +1 -0
  77. package/dist/chunk-MNO33ASC.cjs +240 -0
  78. package/dist/chunk-MNO33ASC.cjs.map +1 -0
  79. package/dist/chunk-N4AOJ3VF.cjs +154 -0
  80. package/dist/chunk-N4AOJ3VF.cjs.map +1 -0
  81. package/dist/chunk-P5CNM325.cjs +508 -0
  82. package/dist/chunk-P5CNM325.cjs.map +1 -0
  83. package/dist/chunk-RYT4H46I.js +646 -0
  84. package/dist/chunk-RYT4H46I.js.map +1 -0
  85. package/dist/chunk-SV5H3XM5.cjs +321 -0
  86. package/dist/chunk-SV5H3XM5.cjs.map +1 -0
  87. package/dist/chunk-TXHKFLWX.cjs +344 -0
  88. package/dist/chunk-TXHKFLWX.cjs.map +1 -0
  89. package/dist/chunk-UJAGXJDG.cjs +170 -0
  90. package/dist/chunk-UJAGXJDG.cjs.map +1 -0
  91. package/dist/chunk-VXRVGFCI.js +1128 -0
  92. package/dist/chunk-VXRVGFCI.js.map +1 -0
  93. package/dist/chunk-YM5AL65Y.cjs +357 -0
  94. package/dist/chunk-YM5AL65Y.cjs.map +1 -0
  95. package/dist/index.cjs +8334 -0
  96. package/dist/index.cjs.map +1 -0
  97. package/dist/index.d.cts +1365 -0
  98. package/dist/index.d.ts +1365 -0
  99. package/dist/index.js +8105 -0
  100. package/dist/index.js.map +1 -0
  101. package/dist/indexes/index.cjs +67 -0
  102. package/dist/indexes/index.cjs.map +1 -0
  103. package/dist/indexes/index.d.cts +62 -0
  104. package/dist/indexes/index.d.ts +62 -0
  105. package/dist/indexes/index.js +6 -0
  106. package/dist/indexes/index.js.map +1 -0
  107. package/dist/interchange/index.cjs +612 -0
  108. package/dist/interchange/index.cjs.map +1 -0
  109. package/dist/interchange/index.d.cts +288 -0
  110. package/dist/interchange/index.d.ts +288 -0
  111. package/dist/interchange/index.js +598 -0
  112. package/dist/interchange/index.js.map +1 -0
  113. package/dist/profiler/index.cjs +793 -0
  114. package/dist/profiler/index.cjs.map +1 -0
  115. package/dist/profiler/index.d.cts +283 -0
  116. package/dist/profiler/index.d.ts +283 -0
  117. package/dist/profiler/index.js +785 -0
  118. package/dist/profiler/index.js.map +1 -0
  119. package/dist/store-60Lcfi0w.d.ts +2263 -0
  120. package/dist/store-Bifii8MZ.d.cts +2263 -0
  121. package/dist/test-helpers-BjyRYJZX.d.ts +22 -0
  122. package/dist/test-helpers-NoQXhleQ.d.cts +22 -0
  123. package/dist/types-BRzHlhKC.d.cts +14 -0
  124. package/dist/types-BRzHlhKC.d.ts +14 -0
  125. package/dist/types-BrSfFSpW.d.cts +158 -0
  126. package/dist/types-CX4cLd7M.d.ts +152 -0
  127. package/dist/types-CjZ7g_7v.d.ts +442 -0
  128. package/dist/types-DDOSfrih.d.cts +442 -0
  129. package/dist/types-D_3mEv2y.d.ts +158 -0
  130. package/dist/types-a5rAxC92.d.cts +152 -0
  131. package/package.json +201 -0
@@ -0,0 +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":["jsonPointer","normalizeJsonPointer","createSchemaIntrospector","parseJsonPointer","resolveFieldTypeInfoAtJsonPointer"],"mappings":"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","file":"index.cjs","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 */\nexport type 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\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.name, { 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.name,\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 handler: 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, handler) 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/selectAggregate. 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 handler: 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, handler);\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 handler: 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, handler);\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"]}
@@ -0,0 +1,283 @@
1
+ import { G as GraphDef, S as Store } from '../store-Bifii8MZ.cjs';
2
+ import { Q as QueryAst } from '../ast-BVyihVbP.cjs';
3
+ import { P as ProfilerOptions, a as ProfileReport, b as ProfileEntityType, c as PropertyTarget, U as UsageContext, d as PropertyPath, e as PropertyAccessStats, f as ProfileSummary, D as DeclaredIndex, I as IndexRecommendation } from '../types-BrSfFSpW.cjs';
4
+ export { R as RecommendationPriority } from '../types-BrSfFSpW.cjs';
5
+ import '../types-DDOSfrih.cjs';
6
+ import 'drizzle-orm';
7
+ import '../types-BRzHlhKC.cjs';
8
+ import 'zod';
9
+
10
+ /**
11
+ * QueryProfiler - Main profiler class.
12
+ *
13
+ * Captures query patterns from the AST and generates index recommendations.
14
+ * Uses Proxy to wrap Store and QueryBuilder for transparent interception.
15
+ */
16
+
17
+ /**
18
+ * A Store with profiling capabilities.
19
+ *
20
+ * Behaves exactly like a regular Store but tracks all query executions.
21
+ * Access the profiler via the `profiler` property.
22
+ */
23
+ type ProfiledStore<G extends GraphDef> = Store<G> & {
24
+ /** The profiler instance attached to this store */
25
+ readonly profiler: QueryProfiler;
26
+ };
27
+ /**
28
+ * QueryProfiler captures and analyzes query patterns.
29
+ *
30
+ * Attach to a store to automatically track all query executions,
31
+ * then generate reports with index recommendations.
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * import { QueryProfiler } from "@nicia-ai/typegraph/profiler";
36
+ *
37
+ * const profiler = new QueryProfiler({
38
+ * declaredIndexes: [
39
+ * { nodeKind: "Person", fields: ["email"], unique: true, name: "idx_email" },
40
+ * ],
41
+ * });
42
+ *
43
+ * const profiledStore = profiler.attachToStore(store);
44
+ *
45
+ * // Run queries...
46
+ * await profiledStore.query()
47
+ * .from("Person", "p")
48
+ * .whereNode("p", (p) => p.email.eq("alice@example.com"))
49
+ * .select((ctx) => ctx.p)
50
+ * .execute();
51
+ *
52
+ * // Get report
53
+ * const report = profiler.getReport();
54
+ * console.log(report.recommendations);
55
+ * ```
56
+ */
57
+ declare class QueryProfiler {
58
+ #private;
59
+ constructor(options?: ProfilerOptions);
60
+ /**
61
+ * Records a query execution from its AST.
62
+ *
63
+ * This is called automatically when attached to a store.
64
+ * Can also be called manually for custom integrations.
65
+ *
66
+ * @param ast - The query AST to analyze
67
+ */
68
+ recordQuery(ast: QueryAst): void;
69
+ /**
70
+ * Attaches the profiler to a store.
71
+ *
72
+ * Returns a wrapped store that tracks all query executions.
73
+ * The wrapped store behaves identically to the original.
74
+ *
75
+ * @param store - The store to attach to
76
+ * @returns A profiled store with the `profiler` property
77
+ * @throws Error if the profiler is already attached to another store
78
+ */
79
+ attachToStore<G extends GraphDef>(store: Store<G>): ProfiledStore<G>;
80
+ /**
81
+ * Generates a complete profile report.
82
+ *
83
+ * The report includes:
84
+ * - All property access patterns with frequency and context
85
+ * - Index recommendations sorted by priority
86
+ * - List of unindexed filter properties
87
+ * - Summary statistics
88
+ *
89
+ * @returns The profile report
90
+ */
91
+ getReport(): ProfileReport;
92
+ /**
93
+ * Checks if all filtered properties are covered by indexes.
94
+ *
95
+ * Throws an error if any filtered properties lack indexes.
96
+ * Useful for test assertions to ensure query performance.
97
+ *
98
+ * @throws Error if unindexed filter properties are found
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * // In your test file
103
+ * it("all filtered properties should be indexed", () => {
104
+ * profiler.assertIndexCoverage();
105
+ * });
106
+ * ```
107
+ */
108
+ assertIndexCoverage(): void;
109
+ /**
110
+ * Resets all collected data.
111
+ *
112
+ * Clears patterns and query count. Useful for starting a fresh
113
+ * profiling session without creating a new profiler instance.
114
+ */
115
+ reset(): void;
116
+ /**
117
+ * Marks the profiler as detached.
118
+ *
119
+ * Call this when you're done profiling to allow reattachment
120
+ * to the same or a different store.
121
+ */
122
+ detach(): void;
123
+ /**
124
+ * Whether the profiler is currently attached to a store.
125
+ */
126
+ get isAttached(): boolean;
127
+ }
128
+
129
+ /**
130
+ * AST Extractor - Extracts property access patterns from QueryAst.
131
+ *
132
+ * Walks the query AST to identify all property accesses and their
133
+ * usage contexts (filter, sort, select, groupBy).
134
+ */
135
+
136
+ /**
137
+ * A property access extracted from the AST.
138
+ */
139
+ type ExtractedAccess = Readonly<{
140
+ /** Whether the access targets nodes or edges */
141
+ entityType: ProfileEntityType;
142
+ /** Expanded kind names for the alias */
143
+ kindNames: readonly string[];
144
+ /** The accessed target (props pointer or system field) */
145
+ target: PropertyTarget;
146
+ /** How the property was used */
147
+ context: UsageContext;
148
+ /** Predicate type if used in a filter (eq, contains, gt, etc.) */
149
+ predicateType?: string;
150
+ }>;
151
+ /**
152
+ * Extracts all property accesses from a QueryAst.
153
+ *
154
+ * Walks the AST to find all property references and categorizes
155
+ * them by usage context (filter, sort, select, groupBy).
156
+ *
157
+ * @param ast - The query AST to analyze
158
+ * @returns Array of extracted property accesses
159
+ */
160
+ declare function extractPropertyAccesses(ast: QueryAst): readonly ExtractedAccess[];
161
+
162
+ /**
163
+ * ProfileCollector - Aggregates property access patterns.
164
+ *
165
+ * Mutable collector that tracks property access patterns across queries
166
+ * and provides immutable snapshots for reporting.
167
+ */
168
+
169
+ /**
170
+ * Converts a PropertyPath to a string key for Map storage.
171
+ *
172
+ * @example
173
+ * ```typescript
174
+ * pathToKey({
175
+ * entityType: "node",
176
+ * kind: "Person",
177
+ * target: { __type: "prop", pointer: "/email" },
178
+ * })
179
+ * // => "node:Person:/email"
180
+ * ```
181
+ */
182
+ declare function pathToKey(path: PropertyPath): string;
183
+ /**
184
+ * Parses a key back to a PropertyPath.
185
+ *
186
+ * @example
187
+ * ```typescript
188
+ * keyToPath("node:Person:/email")
189
+ * // => { entityType: "node", kind: "Person", target: { __type: "prop", pointer: "/email" } }
190
+ * ```
191
+ */
192
+ declare function keyToPath(key: string): PropertyPath;
193
+ /**
194
+ * Collects and aggregates property access patterns.
195
+ *
196
+ * This class is mutable internally but provides immutable snapshots
197
+ * via `getPatterns()` and `getSummary()`.
198
+ *
199
+ * @example
200
+ * ```typescript
201
+ * const collector = new ProfileCollector();
202
+ *
203
+ * collector.record(
204
+ * { nodeKind: "Person", fieldPath: ["email"] },
205
+ * "filter",
206
+ * "eq"
207
+ * );
208
+ * collector.recordQuery();
209
+ *
210
+ * const patterns = collector.getPatterns();
211
+ * const summary = collector.getSummary();
212
+ * ```
213
+ */
214
+ declare class ProfileCollector {
215
+ #private;
216
+ /**
217
+ * Records a property access.
218
+ *
219
+ * @param path - The property path that was accessed
220
+ * @param context - How the property was used (filter, sort, select, groupBy)
221
+ * @param predicateType - Optional predicate type (eq, contains, gt, etc.)
222
+ */
223
+ record(path: PropertyPath, context: UsageContext, predicateType?: string): void;
224
+ /**
225
+ * Increments the query count.
226
+ * Call this once per query execution.
227
+ */
228
+ recordQuery(): void;
229
+ /**
230
+ * Gets all patterns as an immutable map.
231
+ *
232
+ * Returns a new Map with immutable stats objects.
233
+ */
234
+ getPatterns(): ReadonlyMap<string, PropertyAccessStats>;
235
+ /**
236
+ * Gets summary statistics.
237
+ */
238
+ getSummary(): ProfileSummary;
239
+ /**
240
+ * Resets all collected data.
241
+ *
242
+ * Note: This does not reset the startedAt timestamp.
243
+ * Create a new ProfileCollector for a fresh session.
244
+ */
245
+ reset(): void;
246
+ }
247
+
248
+ /**
249
+ * Index Recommendations - Generates index suggestions from usage patterns.
250
+ *
251
+ * Analyzes collected property access patterns and generates prioritized
252
+ * recommendations for missing indexes.
253
+ */
254
+
255
+ type GenerateRecommendationsOptions = Readonly<{
256
+ minFrequencyForRecommendation?: number;
257
+ mediumFrequencyThreshold?: number;
258
+ highFrequencyThreshold?: number;
259
+ }>;
260
+ /**
261
+ * Generates index recommendations based on usage patterns.
262
+ *
263
+ * Analyzes property access patterns and returns prioritized recommendations
264
+ * for properties that would benefit from indexing.
265
+ *
266
+ * @param patterns - Collected property access patterns
267
+ * @param declaredIndexes - Indexes that already exist
268
+ * @param options - Threshold configuration (or legacy `minFrequency` number)
269
+ * @returns Sorted array of index recommendations
270
+ */
271
+ declare function generateRecommendations(patterns: ReadonlyMap<string, PropertyAccessStats>, declaredIndexes: readonly DeclaredIndex[], options?: number | GenerateRecommendationsOptions): readonly IndexRecommendation[];
272
+ /**
273
+ * Gets properties used in filters that lack indexes.
274
+ *
275
+ * Useful for test assertions to ensure all filtered properties are indexed.
276
+ *
277
+ * @param patterns - Collected property access patterns
278
+ * @param declaredIndexes - Indexes that already exist
279
+ * @returns Array of unindexed property paths
280
+ */
281
+ declare function getUnindexedFilters(patterns: ReadonlyMap<string, PropertyAccessStats>, declaredIndexes: readonly DeclaredIndex[]): readonly PropertyPath[];
282
+
283
+ export { DeclaredIndex, type ExtractedAccess, IndexRecommendation, ProfileCollector, ProfileReport, ProfileSummary, type ProfiledStore, ProfilerOptions, PropertyAccessStats, PropertyPath, QueryProfiler, UsageContext, extractPropertyAccesses, generateRecommendations, getUnindexedFilters, keyToPath, pathToKey };