@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 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ontology/types.ts","../src/errors/validation.ts","../src/schema/migration.ts","../src/ontology/closures.ts","../src/ontology/constants.ts","../src/registry/kind-registry.ts","../src/schema/serializer.ts","../src/schema/types.ts","../src/schema/manager.ts"],"names":["index","z"],"mappings":"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","file":"chunk-GFGVREHH.js","sourcesContent":["import { type EdgeType, type NodeType } from \"../core/types\";\n\n// ============================================================\n// Brand Key\n// ============================================================\n\n/** Brand key for MetaEdge */\nexport const META_EDGE_BRAND = \"__metaEdge\" as const;\n\n// ============================================================\n// Inference Types\n// ============================================================\n\n/**\n * How a meta-edge affects queries and validation.\n */\nexport type InferenceType =\n | \"subsumption\" // Query for X includes instances of subclasses\n | \"hierarchy\" // Enables broader/narrower traversal\n | \"substitution\" // Can substitute equivalent types\n | \"constraint\" // Validation rules\n | \"composition\" // Part-whole navigation\n | \"association\" // Discovery/recommendation\n | \"none\"; // No automatic inference\n\n// ============================================================\n// Meta-Edge Properties\n// ============================================================\n\n/**\n * Properties of a meta-edge.\n */\nexport type MetaEdgeProperties = Readonly<{\n transitive: boolean; // A→B, B→C implies A→C\n symmetric: boolean; // A→B implies B→A\n reflexive: boolean; // A→A is always true\n inverse: string | undefined; // Name of inverse meta-edge\n inference: InferenceType; // How this affects queries\n description: string | undefined;\n}>;\n\n// ============================================================\n// Meta-Edge Type\n// ============================================================\n\n/**\n * A meta-edge definition.\n *\n * Meta-edges represent type-level relationships (between kinds),\n * not instance-level relationships (between nodes).\n */\nexport type MetaEdge<K extends string = string> = Readonly<{\n [META_EDGE_BRAND]: true;\n name: K;\n properties: MetaEdgeProperties;\n}>;\n\n// ============================================================\n// Ontology Relation\n// ============================================================\n\n/**\n * A relation in the ontology (instance of meta-edge between types).\n *\n * @example\n * ```typescript\n * // Podcast subClassOf Media\n * subClassOf(Podcast, Media)\n *\n * // Person equivalentTo schema:Person\n * equivalentTo(Person, \"https://schema.org/Person\")\n * ```\n */\nexport type OntologyRelation = Readonly<{\n metaEdge: MetaEdge;\n from: NodeType | EdgeType | string; // string for external IRIs\n to: NodeType | EdgeType | string;\n}>;\n\n// ============================================================\n// Type Guards\n// ============================================================\n\n/**\n * Checks if a value is a MetaEdge.\n */\nexport function isMetaEdge(value: unknown): value is MetaEdge {\n return (\n typeof value === \"object\" &&\n value !== null &&\n META_EDGE_BRAND in value &&\n (value as Record<string, unknown>)[META_EDGE_BRAND] === true\n );\n}\n\n/**\n * Gets the type name from a NodeType, EdgeType, or IRI string.\n */\nexport function getTypeName(typeOrIri: NodeType | EdgeType | string): string {\n if (typeof typeOrIri === \"string\") {\n return typeOrIri;\n }\n return typeOrIri.kind;\n}\n","/**\n * Contextual Validation Utilities\n *\n * Provides Zod validation wrappers that include full context about\n * which entity (node/edge) and operation (create/update) failed.\n *\n * @example\n * ```typescript\n * const props = validateNodeProps(schema, input, {\n * kind: \"Person\",\n * operation: \"create\",\n * });\n * ```\n */\n\nimport { type ZodError, type ZodType } from \"zod\";\n\nimport { ValidationError, type ValidationIssue } from \"./index\";\n\n// ============================================================\n// Types\n// ============================================================\n\n/**\n * Context for validation operations.\n */\nexport type ValidationContext = Readonly<{\n /** Type of entity being validated */\n entityType: \"node\" | \"edge\";\n /** Kind/type name of the entity */\n kind: string;\n /** Operation being performed */\n operation: \"create\" | \"update\";\n /** Entity ID (for updates) */\n id?: string;\n}>;\n\n// ============================================================\n// Validation Functions\n// ============================================================\n\n/**\n * Converts Zod issues to ValidationIssue format.\n */\nfunction zodIssuesToValidationIssues(error: ZodError): ValidationIssue[] {\n return error.issues.map((issue) => ({\n path: issue.path.join(\".\"),\n message: issue.message,\n code: issue.code,\n }));\n}\n\n/**\n * Builds a descriptive location string for error messages.\n */\nfunction buildLocationString(context: ValidationContext): string {\n if (context.id) {\n return `${context.kind}/${context.id}`;\n }\n return `new ${context.kind}`;\n}\n\n/**\n * Validates props with full context for error messages.\n *\n * @param schema - Zod schema to validate against\n * @param props - Properties to validate\n * @param context - Context about the entity and operation\n * @returns Validated and transformed props\n * @throws ValidationError with full context if validation fails\n *\n * @example\n * ```typescript\n * const validatedProps = validateProps(personSchema, input, {\n * entityType: \"node\",\n * kind: \"Person\",\n * operation: \"create\",\n * });\n * ```\n */\nexport function validateProps<T>(\n schema: ZodType<T>,\n props: unknown,\n context: ValidationContext,\n): T {\n const result = schema.safeParse(props);\n\n if (result.success) {\n return result.data;\n }\n\n const issues = zodIssuesToValidationIssues(result.error);\n const location = buildLocationString(context);\n\n throw new ValidationError(\n `Invalid ${context.entityType} props for ${location}: ${result.error.message}`,\n {\n entityType: context.entityType,\n kind: context.kind,\n operation: context.operation,\n ...(context.id !== undefined && { id: context.id }),\n issues,\n },\n { cause: result.error },\n );\n}\n\n/**\n * Validates node props with full context.\n *\n * Convenience wrapper around validateProps for node operations.\n *\n * @example\n * ```typescript\n * const props = validateNodeProps(schema, input, {\n * kind: \"Person\",\n * operation: \"create\",\n * });\n * ```\n */\nexport function validateNodeProps<T>(\n schema: ZodType<T>,\n props: unknown,\n context: Readonly<{\n kind: string;\n operation: \"create\" | \"update\";\n id?: string;\n }>,\n): T {\n return validateProps(schema, props, {\n entityType: \"node\",\n ...context,\n });\n}\n\n/**\n * Validates edge props with full context.\n *\n * Convenience wrapper around validateProps for edge operations.\n *\n * @example\n * ```typescript\n * const props = validateEdgeProps(schema, input, {\n * kind: \"worksAt\",\n * operation: \"create\",\n * });\n * ```\n */\nexport function validateEdgeProps<T>(\n schema: ZodType<T>,\n props: unknown,\n context: Readonly<{\n kind: string;\n operation: \"create\" | \"update\";\n id?: string;\n }>,\n): T {\n return validateProps(schema, props, {\n entityType: \"edge\",\n ...context,\n });\n}\n\n/**\n * Wraps a Zod error with TypeGraph context.\n *\n * Use this when you've already caught a ZodError and want to\n * convert it to a ValidationError with context.\n *\n * @example\n * ```typescript\n * try {\n * schema.parse(input);\n * } catch (error) {\n * if (error instanceof ZodError) {\n * throw wrapZodError(error, {\n * entityType: \"node\",\n * kind: \"Person\",\n * operation: \"create\",\n * });\n * }\n * throw error;\n * }\n * ```\n */\nexport function wrapZodError(\n error: ZodError,\n context: ValidationContext,\n): ValidationError {\n const issues = zodIssuesToValidationIssues(error);\n const location = buildLocationString(context);\n\n return new ValidationError(\n `Validation failed for ${context.entityType} ${location}: ${error.message}`,\n {\n entityType: context.entityType,\n kind: context.kind,\n operation: context.operation,\n ...(context.id !== undefined && { id: context.id }),\n issues,\n },\n { cause: error },\n );\n}\n\n/**\n * Creates a simple ValidationError without Zod context.\n *\n * Use this for custom validation rules that aren't part of a Zod schema.\n *\n * @example\n * ```typescript\n * if (startDate > endDate) {\n * throw createValidationError(\n * \"Start date must be before end date\",\n * [{ path: \"startDate\", message: \"Must be before endDate\" }],\n * { entityType: \"edge\", kind: \"employment\", operation: \"create\" }\n * );\n * }\n * ```\n */\nexport function createValidationError(\n message: string,\n issues: ValidationIssue[],\n context?: Partial<ValidationContext>,\n): ValidationError {\n return new ValidationError(message, {\n ...(context?.entityType !== undefined && {\n entityType: context.entityType,\n }),\n ...(context?.kind !== undefined && { kind: context.kind }),\n ...(context?.operation !== undefined && { operation: context.operation }),\n ...(context?.id !== undefined && { id: context.id }),\n issues,\n });\n}\n","/**\n * Schema migration utilities.\n *\n * Provides diff detection between schema versions to identify\n * what has changed and what migrations might be needed.\n */\nimport {\n type SerializedEdgeDef,\n type SerializedNodeDef,\n type SerializedOntology,\n type SerializedSchema,\n} from \"./types\";\n\n// ============================================================\n// Change Types\n// ============================================================\n\n/**\n * Types of changes that can occur in a schema.\n */\nexport type ChangeType = \"added\" | \"removed\" | \"modified\" | \"renamed\";\n\n/**\n * Severity of a change for migration purposes.\n */\nexport type ChangeSeverity =\n | \"safe\" // No data migration needed\n | \"warning\" // Might need attention\n | \"breaking\"; // Requires data migration\n\n// ============================================================\n// Node Changes\n// ============================================================\n\n/**\n * A change to a node definition.\n */\nexport type NodeChange = Readonly<{\n type: ChangeType;\n kind: string;\n severity: ChangeSeverity;\n details: string;\n before?: SerializedNodeDef | undefined;\n after?: SerializedNodeDef | undefined;\n}>;\n\n// ============================================================\n// Edge Changes\n// ============================================================\n\n/**\n * A change to an edge definition.\n */\nexport type EdgeChange = Readonly<{\n type: ChangeType;\n kind: string;\n severity: ChangeSeverity;\n details: string;\n before?: SerializedEdgeDef | undefined;\n after?: SerializedEdgeDef | undefined;\n}>;\n\n// ============================================================\n// Ontology Changes\n// ============================================================\n\n/**\n * A change to the ontology.\n */\nexport type OntologyChange = Readonly<{\n type: ChangeType;\n entity: \"metaEdge\" | \"relation\";\n name: string;\n severity: ChangeSeverity;\n details: string;\n}>;\n\n// ============================================================\n// Schema Diff\n// ============================================================\n\n/**\n * A complete diff between two schema versions.\n */\nexport type SchemaDiff = Readonly<{\n fromVersion: number;\n toVersion: number;\n\n /** Changes to node definitions */\n nodes: readonly NodeChange[];\n\n /** Changes to edge definitions */\n edges: readonly EdgeChange[];\n\n /** Changes to ontology */\n ontology: readonly OntologyChange[];\n\n /** Whether any breaking changes exist */\n hasBreakingChanges: boolean;\n\n /** Whether the change is backwards compatible (no breaking changes) */\n isBackwardsCompatible: boolean;\n\n /** Whether any changes exist at all */\n hasChanges: boolean;\n\n /** Summary of changes */\n summary: string;\n}>;\n\n// ============================================================\n// Diff Computation\n// ============================================================\n\n/**\n * Computes the diff between two schema versions.\n *\n * @param before - The previous schema version\n * @param after - The new schema version\n * @returns A diff describing all changes\n */\nexport function computeSchemaDiff(\n before: SerializedSchema,\n after: SerializedSchema,\n): SchemaDiff {\n const nodeChanges = diffNodes(before.nodes, after.nodes);\n const edgeChanges = diffEdges(before.edges, after.edges);\n const ontologyChanges = diffOntology(before.ontology, after.ontology);\n\n const allChanges = [...nodeChanges, ...edgeChanges, ...ontologyChanges];\n const hasBreakingChanges = allChanges.some(\n (change) => change.severity === \"breaking\",\n );\n const hasChanges = allChanges.length > 0;\n\n const summary = generateSummary(nodeChanges, edgeChanges, ontologyChanges);\n\n return {\n fromVersion: before.version,\n toVersion: after.version,\n nodes: nodeChanges,\n edges: edgeChanges,\n ontology: ontologyChanges,\n hasBreakingChanges,\n isBackwardsCompatible: !hasBreakingChanges,\n hasChanges,\n summary,\n };\n}\n\n// ============================================================\n// Node Diff\n// ============================================================\n\n/**\n * Computes changes between node definitions.\n */\nfunction diffNodes(\n before: Record<string, SerializedNodeDef>,\n after: Record<string, SerializedNodeDef>,\n): readonly NodeChange[] {\n const changes: NodeChange[] = [];\n const beforeNames = new Set(Object.keys(before));\n const afterNames = new Set(Object.keys(after));\n\n // Find removed nodes\n for (const name of beforeNames) {\n if (!afterNames.has(name)) {\n changes.push({\n type: \"removed\",\n kind: name,\n severity: \"breaking\",\n details: `Node kind \"${name}\" was removed`,\n before: before[name],\n });\n }\n }\n\n // Find added nodes\n for (const name of afterNames) {\n if (!beforeNames.has(name)) {\n changes.push({\n type: \"added\",\n kind: name,\n severity: \"safe\",\n details: `Node kind \"${name}\" was added`,\n after: after[name],\n });\n }\n }\n\n // Find modified nodes\n for (const name of beforeNames) {\n if (afterNames.has(name)) {\n const nodeBefore = before[name]!;\n const nodeAfter = after[name]!;\n const nodeChanges = diffNodeDef(name, nodeBefore, nodeAfter);\n changes.push(...nodeChanges);\n }\n }\n\n return changes;\n}\n\n/**\n * Computes changes to a single node definition.\n */\nfunction diffNodeDef(\n name: string,\n before: SerializedNodeDef,\n after: SerializedNodeDef,\n): readonly NodeChange[] {\n const changes: NodeChange[] = [];\n\n // Check property schema changes\n const propsBefore = JSON.stringify(before.properties);\n const propsAfter = JSON.stringify(after.properties);\n if (propsBefore !== propsAfter) {\n // Determine if properties were added or removed\n const beforeProps = before.properties.properties ?? {};\n const afterProps = after.properties.properties ?? {};\n const beforeRequired = new Set(before.properties.required);\n const afterRequired = new Set(after.properties.required);\n\n const addedProps = Object.keys(afterProps).filter(\n (p) => !(p in beforeProps),\n );\n const removedProps = Object.keys(beforeProps).filter(\n (p) => !(p in afterProps),\n );\n const newRequired = [...afterRequired].filter(\n (p) => !beforeRequired.has(p),\n );\n\n const { severity, details } = computePropertyChangeSeverity(\n name,\n removedProps,\n addedProps,\n newRequired,\n );\n\n changes.push({\n type: \"modified\",\n kind: name,\n severity,\n details,\n before,\n after,\n });\n }\n\n // Check onDelete behavior\n if (before.onDelete !== after.onDelete) {\n changes.push({\n type: \"modified\",\n kind: name,\n severity: \"warning\",\n details: `onDelete changed from \"${before.onDelete}\" to \"${after.onDelete}\" for \"${name}\"`,\n before,\n after,\n });\n }\n\n // Check unique constraints\n const constraintsBefore = JSON.stringify(before.uniqueConstraints);\n const constraintsAfter = JSON.stringify(after.uniqueConstraints);\n if (constraintsBefore !== constraintsAfter) {\n changes.push({\n type: \"modified\",\n kind: name,\n severity: \"warning\",\n details: `Unique constraints changed for \"${name}\"`,\n before,\n after,\n });\n }\n\n return changes;\n}\n\n/**\n * Computes the severity and details message for property changes.\n */\nfunction computePropertyChangeSeverity(\n name: string,\n removedProps: readonly string[],\n addedProps: readonly string[],\n newRequired: readonly string[],\n): { severity: ChangeSeverity; details: string } {\n if (removedProps.length > 0) {\n return {\n severity: \"breaking\",\n details: `Properties removed from \"${name}\": ${removedProps.join(\", \")}`,\n };\n }\n if (newRequired.length > 0) {\n return {\n severity: \"breaking\",\n details: `New required properties in \"${name}\": ${newRequired.join(\", \")}`,\n };\n }\n if (addedProps.length > 0) {\n return {\n severity: \"safe\",\n details: `Properties added to \"${name}\": ${addedProps.join(\", \")}`,\n };\n }\n return {\n severity: \"safe\",\n details: `Properties changed in \"${name}\"`,\n };\n}\n\n// ============================================================\n// Edge Diff\n// ============================================================\n\n/**\n * Computes changes between edge definitions.\n */\nfunction diffEdges(\n before: Record<string, SerializedEdgeDef>,\n after: Record<string, SerializedEdgeDef>,\n): readonly EdgeChange[] {\n const changes: EdgeChange[] = [];\n const beforeNames = new Set(Object.keys(before));\n const afterNames = new Set(Object.keys(after));\n\n // Find removed edges\n for (const name of beforeNames) {\n if (!afterNames.has(name)) {\n changes.push({\n type: \"removed\",\n kind: name,\n severity: \"breaking\",\n details: `Edge kind \"${name}\" was removed`,\n before: before[name],\n });\n }\n }\n\n // Find added edges\n for (const name of afterNames) {\n if (!beforeNames.has(name)) {\n changes.push({\n type: \"added\",\n kind: name,\n severity: \"safe\",\n details: `Edge kind \"${name}\" was added`,\n after: after[name],\n });\n }\n }\n\n // Find modified edges\n for (const name of beforeNames) {\n if (afterNames.has(name)) {\n const edgeBefore = before[name]!;\n const edgeAfter = after[name]!;\n const edgeChanges = diffEdgeDef(name, edgeBefore, edgeAfter);\n changes.push(...edgeChanges);\n }\n }\n\n return changes;\n}\n\n/**\n * Computes changes to a single edge definition.\n */\nfunction diffEdgeDef(\n name: string,\n before: SerializedEdgeDef,\n after: SerializedEdgeDef,\n): readonly EdgeChange[] {\n const changes: EdgeChange[] = [];\n\n // Check endpoint kinds\n const fromBefore = JSON.stringify(before.fromKinds);\n const fromAfter = JSON.stringify(after.fromKinds);\n if (fromBefore !== fromAfter) {\n changes.push({\n type: \"modified\",\n kind: name,\n severity: \"warning\",\n details: `fromKinds changed for \"${name}\"`,\n before,\n after,\n });\n }\n\n const toBefore = JSON.stringify(before.toKinds);\n const toAfter = JSON.stringify(after.toKinds);\n if (toBefore !== toAfter) {\n changes.push({\n type: \"modified\",\n kind: name,\n severity: \"warning\",\n details: `toKinds changed for \"${name}\"`,\n before,\n after,\n });\n }\n\n // Check cardinality\n if (before.cardinality !== after.cardinality) {\n changes.push({\n type: \"modified\",\n kind: name,\n severity: \"warning\",\n details: `Cardinality changed from \"${before.cardinality}\" to \"${after.cardinality}\" for \"${name}\"`,\n before,\n after,\n });\n }\n\n // Check properties\n const propsBefore = JSON.stringify(before.properties);\n const propsAfter = JSON.stringify(after.properties);\n if (propsBefore !== propsAfter) {\n changes.push({\n type: \"modified\",\n kind: name,\n severity: \"safe\",\n details: `Properties changed for \"${name}\"`,\n before,\n after,\n });\n }\n\n return changes;\n}\n\n// ============================================================\n// Ontology Diff\n// ============================================================\n\n/**\n * Computes changes to the ontology.\n */\nfunction diffOntology(\n before: SerializedOntology,\n after: SerializedOntology,\n): readonly OntologyChange[] {\n const changes: OntologyChange[] = [];\n\n // Diff meta-edges\n const metaEdgesBefore = new Set(Object.keys(before.metaEdges));\n const metaEdgesAfter = new Set(Object.keys(after.metaEdges));\n\n for (const name of metaEdgesBefore) {\n if (!metaEdgesAfter.has(name)) {\n changes.push({\n type: \"removed\",\n entity: \"metaEdge\",\n name,\n severity: \"breaking\",\n details: `Meta-edge \"${name}\" was removed`,\n });\n }\n }\n\n for (const name of metaEdgesAfter) {\n if (!metaEdgesBefore.has(name)) {\n changes.push({\n type: \"added\",\n entity: \"metaEdge\",\n name,\n severity: \"safe\",\n details: `Meta-edge \"${name}\" was added`,\n });\n }\n }\n\n // Diff relations (simplified - just detect additions/removals)\n const relationsBefore = new Set(\n before.relations.map((r) => `${r.metaEdge}:${r.from}:${r.to}`),\n );\n const relationsAfter = new Set(\n after.relations.map((r) => `${r.metaEdge}:${r.from}:${r.to}`),\n );\n\n for (const relationKey of relationsBefore) {\n if (!relationsAfter.has(relationKey)) {\n const [metaEdge, from, to] = relationKey.split(\":\");\n changes.push({\n type: \"removed\",\n entity: \"relation\",\n name: relationKey,\n severity: \"warning\",\n details: `Relation ${metaEdge}(${from}, ${to}) was removed`,\n });\n }\n }\n\n for (const relationKey of relationsAfter) {\n if (!relationsBefore.has(relationKey)) {\n const [metaEdge, from, to] = relationKey.split(\":\");\n changes.push({\n type: \"added\",\n entity: \"relation\",\n name: relationKey,\n severity: \"safe\",\n details: `Relation ${metaEdge}(${from}, ${to}) was added`,\n });\n }\n }\n\n return changes;\n}\n\n// ============================================================\n// Summary Generation\n// ============================================================\n\n/**\n * Generates a human-readable summary of changes.\n */\nfunction generateSummary(\n nodeChanges: readonly NodeChange[],\n edgeChanges: readonly EdgeChange[],\n ontologyChanges: readonly OntologyChange[],\n): string {\n const parts: string[] = [];\n\n const nodeAdded = nodeChanges.filter((c) => c.type === \"added\").length;\n const nodeRemoved = nodeChanges.filter((c) => c.type === \"removed\").length;\n const nodeModified = nodeChanges.filter((c) => c.type === \"modified\").length;\n\n if (nodeAdded > 0 || nodeRemoved > 0 || nodeModified > 0) {\n parts.push(\n `Nodes: ${nodeAdded} added, ${nodeRemoved} removed, ${nodeModified} modified`,\n );\n }\n\n const edgeAdded = edgeChanges.filter((c) => c.type === \"added\").length;\n const edgeRemoved = edgeChanges.filter((c) => c.type === \"removed\").length;\n const edgeModified = edgeChanges.filter((c) => c.type === \"modified\").length;\n\n if (edgeAdded > 0 || edgeRemoved > 0 || edgeModified > 0) {\n parts.push(\n `Edges: ${edgeAdded} added, ${edgeRemoved} removed, ${edgeModified} modified`,\n );\n }\n\n const ontologyAdded = ontologyChanges.filter(\n (c) => c.type === \"added\",\n ).length;\n const ontologyRemoved = ontologyChanges.filter(\n (c) => c.type === \"removed\",\n ).length;\n\n if (ontologyAdded > 0 || ontologyRemoved > 0) {\n parts.push(`Ontology: ${ontologyAdded} added, ${ontologyRemoved} removed`);\n }\n\n if (parts.length === 0) {\n return \"No changes\";\n }\n\n return parts.join(\"; \");\n}\n\n// ============================================================\n// Migration Helpers\n// ============================================================\n\n/**\n * Checks if a schema change is backwards compatible.\n *\n * A change is backwards compatible if:\n * - No nodes or edges were removed\n * - No required properties were added\n * - No existing properties were removed\n */\nexport function isBackwardsCompatible(diff: SchemaDiff): boolean {\n return !diff.hasBreakingChanges;\n}\n\n/**\n * Gets a list of actions needed for migration.\n */\nexport function getMigrationActions(diff: SchemaDiff): readonly string[] {\n const actions: string[] = [];\n\n for (const change of diff.nodes) {\n if (change.type === \"removed\") {\n actions.push(`DELETE data for removed node kind \"${change.kind}\"`);\n }\n if (change.severity === \"breaking\" && change.type === \"modified\") {\n actions.push(\n `MIGRATE data for node kind \"${change.kind}\": ${change.details}`,\n );\n }\n }\n\n for (const change of diff.edges) {\n if (change.type === \"removed\") {\n actions.push(`DELETE data for removed edge kind \"${change.kind}\"`);\n }\n }\n\n return actions;\n}\n","/**\n * Transitive closure computation for ontology relationships.\n *\n * Uses Warshall's algorithm for efficient closure computation.\n */\n\n/**\n * Computes the transitive closure of a set of directed relations.\n *\n * Given relations like [A→B, B→C], computes all transitive paths [A→B, A→C, B→C].\n *\n * @param relations - Array of [from, to] pairs representing direct relationships\n * @returns Map from each 'from' to the set of all reachable 'to' values\n */\nexport function computeTransitiveClosure(\n relations: readonly (readonly [string, string])[],\n): ReadonlyMap<string, ReadonlySet<string>> {\n // Build mutable map for computation\n const closure = new Map<string, Set<string>>();\n\n // Collect all nodes\n const allNodes = new Set<string>();\n for (const [from, to] of relations) {\n allNodes.add(from);\n allNodes.add(to);\n }\n\n // Initialize empty sets for all nodes\n for (const node of allNodes) {\n closure.set(node, new Set());\n }\n\n // Add direct relationships\n for (const [from, to] of relations) {\n closure.get(from)?.add(to);\n }\n\n // Warshall's algorithm for transitive closure\n // For each intermediate node k, check if i→k and k→j implies i→j\n for (const k of allNodes) {\n for (const index of allNodes) {\n const indexReaches = closure.get(index);\n if (!indexReaches?.has(k)) continue;\n\n const kReaches = closure.get(k);\n if (!kReaches) continue;\n\n for (const index of kReaches) {\n indexReaches.add(index);\n }\n }\n }\n\n return closure;\n}\n\n/**\n * Computes the inverse of a transitive closure map.\n *\n * Given A→{B, C}, returns B→{A}, C→{A}.\n */\nexport function invertClosure(\n closure: ReadonlyMap<string, ReadonlySet<string>>,\n): ReadonlyMap<string, ReadonlySet<string>> {\n const result = new Map<string, Set<string>>();\n\n for (const [from, tos] of closure) {\n for (const to of tos) {\n const existing = result.get(to) ?? new Set();\n existing.add(from);\n result.set(to, existing);\n }\n }\n\n return result;\n}\n\n/**\n * Checks if there's a path from source to target in the closure.\n */\nexport function isReachable(\n closure: ReadonlyMap<string, ReadonlySet<string>>,\n source: string,\n target: string,\n): boolean {\n return closure.get(source)?.has(target) ?? false;\n}\n","/**\n * Named constants for ontology meta-edge names.\n *\n * Use these constants instead of string literals for type safety\n * and IDE support.\n */\n\n// ============================================================\n// Meta-Edge Names\n// ============================================================\n\n/** Type inheritance (Podcast subClassOf Media) */\nexport const META_EDGE_SUB_CLASS_OF = \"subClassOf\" as const;\n\n/** Broader concept (ML broader AI) */\nexport const META_EDGE_BROADER = \"broader\" as const;\n\n/** Narrower concept (AI narrower ML) */\nexport const META_EDGE_NARROWER = \"narrower\" as const;\n\n/** Non-hierarchical association */\nexport const META_EDGE_RELATED_TO = \"relatedTo\" as const;\n\n/** Same class, different representation */\nexport const META_EDGE_EQUIVALENT_TO = \"equivalentTo\" as const;\n\n/** Same individual (for deduplication) */\nexport const META_EDGE_SAME_AS = \"sameAs\" as const;\n\n/** Explicitly different individuals */\nexport const META_EDGE_DIFFERENT_FROM = \"differentFrom\" as const;\n\n/** Mutually exclusive types */\nexport const META_EDGE_DISJOINT_WITH = \"disjointWith\" as const;\n\n/** X is part of Y */\nexport const META_EDGE_PART_OF = \"partOf\" as const;\n\n/** Y has part X */\nexport const META_EDGE_HAS_PART = \"hasPart\" as const;\n\n/** Edge A is inverse of edge B */\nexport const META_EDGE_INVERSE_OF = \"inverseOf\" as const;\n\n/** Edge A implies edge B exists */\nexport const META_EDGE_IMPLIES = \"implies\" as const;\n\n// ============================================================\n// All Meta-Edge Names (for validation)\n// ============================================================\n\nexport const ALL_META_EDGE_NAMES = [\n META_EDGE_SUB_CLASS_OF,\n META_EDGE_BROADER,\n META_EDGE_NARROWER,\n META_EDGE_RELATED_TO,\n META_EDGE_EQUIVALENT_TO,\n META_EDGE_SAME_AS,\n META_EDGE_DIFFERENT_FROM,\n META_EDGE_DISJOINT_WITH,\n META_EDGE_PART_OF,\n META_EDGE_HAS_PART,\n META_EDGE_INVERSE_OF,\n META_EDGE_IMPLIES,\n] as const;\n\nexport type MetaEdgeName = (typeof ALL_META_EDGE_NAMES)[number];\n","import { type AnyEdgeType, type NodeType } from \"../core/types\";\nimport {\n computeTransitiveClosure,\n invertClosure,\n isReachable,\n} from \"../ontology/closures\";\nimport {\n META_EDGE_BROADER,\n META_EDGE_DISJOINT_WITH,\n META_EDGE_EQUIVALENT_TO,\n META_EDGE_HAS_PART,\n META_EDGE_IMPLIES,\n META_EDGE_INVERSE_OF,\n META_EDGE_NARROWER,\n META_EDGE_PART_OF,\n META_EDGE_SAME_AS,\n META_EDGE_SUB_CLASS_OF,\n} from \"../ontology/constants\";\nimport { type OntologyRelation } from \"../ontology/types\";\n\n/**\n * KindRegistry holds precomputed closures for ontological reasoning.\n *\n * Computed at store initialization and cached for fast query-time lookups.\n */\nexport class KindRegistry {\n // === Node & Edge Kinds ===\n readonly nodeKinds: ReadonlyMap<string, NodeType>;\n readonly edgeKinds: ReadonlyMap<string, AnyEdgeType>;\n\n // === Subsumption (subClassOf) ===\n // Transitive closure for inheritance\n readonly subClassAncestors: ReadonlyMap<string, ReadonlySet<string>>;\n readonly subClassDescendants: ReadonlyMap<string, ReadonlySet<string>>;\n\n // === Hierarchy (broader/narrower) ===\n // Transitive closure for concept hierarchy (separate from subClassOf!)\n readonly broaderClosure: ReadonlyMap<string, ReadonlySet<string>>;\n readonly narrowerClosure: ReadonlyMap<string, ReadonlySet<string>>;\n\n // === Equivalence ===\n readonly equivalenceSets: ReadonlyMap<string, ReadonlySet<string>>;\n readonly iriToKind: ReadonlyMap<string, string>;\n\n // === Constraints ===\n readonly disjointPairs: ReadonlySet<string>; // Normalized pairs: \"Organization|Person\"\n\n // === Composition ===\n readonly partOfClosure: ReadonlyMap<string, ReadonlySet<string>>;\n readonly hasPartClosure: ReadonlyMap<string, ReadonlySet<string>>;\n\n // === Edge Relationships ===\n readonly edgeInverses: ReadonlyMap<string, string>;\n readonly edgeImplicationsClosure: ReadonlyMap<string, ReadonlySet<string>>;\n readonly edgeImplyingClosure: ReadonlyMap<string, ReadonlySet<string>>;\n\n constructor(\n nodeKinds: ReadonlyMap<string, NodeType>,\n edgeKinds: ReadonlyMap<string, AnyEdgeType>,\n closures: {\n subClassAncestors: ReadonlyMap<string, ReadonlySet<string>>;\n subClassDescendants: ReadonlyMap<string, ReadonlySet<string>>;\n broaderClosure: ReadonlyMap<string, ReadonlySet<string>>;\n narrowerClosure: ReadonlyMap<string, ReadonlySet<string>>;\n equivalenceSets: ReadonlyMap<string, ReadonlySet<string>>;\n iriToKind: ReadonlyMap<string, string>;\n disjointPairs: ReadonlySet<string>;\n partOfClosure: ReadonlyMap<string, ReadonlySet<string>>;\n hasPartClosure: ReadonlyMap<string, ReadonlySet<string>>;\n edgeInverses: ReadonlyMap<string, string>;\n edgeImplicationsClosure: ReadonlyMap<string, ReadonlySet<string>>;\n edgeImplyingClosure: ReadonlyMap<string, ReadonlySet<string>>;\n },\n ) {\n this.nodeKinds = nodeKinds;\n this.edgeKinds = edgeKinds;\n this.subClassAncestors = closures.subClassAncestors;\n this.subClassDescendants = closures.subClassDescendants;\n this.broaderClosure = closures.broaderClosure;\n this.narrowerClosure = closures.narrowerClosure;\n this.equivalenceSets = closures.equivalenceSets;\n this.iriToKind = closures.iriToKind;\n this.disjointPairs = closures.disjointPairs;\n this.partOfClosure = closures.partOfClosure;\n this.hasPartClosure = closures.hasPartClosure;\n this.edgeInverses = closures.edgeInverses;\n this.edgeImplicationsClosure = closures.edgeImplicationsClosure;\n this.edgeImplyingClosure = closures.edgeImplyingClosure;\n }\n\n // === Subsumption Methods ===\n\n /**\n * Checks if child is a subclass of parent (directly or transitively).\n */\n isSubClassOf(child: string, parent: string): boolean {\n return isReachable(this.subClassAncestors, child, parent);\n }\n\n /**\n * Expands a kind to include all its subclasses.\n * Returns [kind, ...subclasses].\n */\n expandSubClasses(kind: string): readonly string[] {\n const descendants = this.subClassDescendants.get(kind) ?? new Set();\n return [kind, ...descendants];\n }\n\n /**\n * Gets all ancestors of a kind (via subClassOf).\n */\n getAncestors(kind: string): ReadonlySet<string> {\n return this.subClassAncestors.get(kind) ?? new Set();\n }\n\n /**\n * Gets all descendants of a kind (via subClassOf).\n */\n getDescendants(kind: string): ReadonlySet<string> {\n return this.subClassDescendants.get(kind) ?? new Set();\n }\n\n // === Hierarchy Methods ===\n\n /**\n * Checks if narrowerConcept is narrower than broaderConcept.\n */\n isNarrowerThan(narrowerConcept: string, broaderConcept: string): boolean {\n return isReachable(this.broaderClosure, narrowerConcept, broaderConcept);\n }\n\n /**\n * Checks if broaderConcept is broader than narrowerConcept.\n */\n isBroaderThan(broaderConcept: string, narrowerConcept: string): boolean {\n return isReachable(this.narrowerClosure, broaderConcept, narrowerConcept);\n }\n\n /**\n * Expands to include all narrower concepts.\n */\n expandNarrower(kind: string): readonly string[] {\n const narrower = this.narrowerClosure.get(kind) ?? new Set();\n return [kind, ...narrower];\n }\n\n /**\n * Expands to include all broader concepts.\n */\n expandBroader(kind: string): readonly string[] {\n const broader = this.broaderClosure.get(kind) ?? new Set();\n return [kind, ...broader];\n }\n\n // === Equivalence Methods ===\n\n /**\n * Checks if two kinds are equivalent.\n */\n areEquivalent(a: string, b: string): boolean {\n const equivalents = this.equivalenceSets.get(a);\n return equivalents?.has(b) ?? false;\n }\n\n /**\n * Gets all equivalents of a kind (including external IRIs).\n */\n getEquivalents(kind: string): readonly string[] {\n const equivalents = this.equivalenceSets.get(kind);\n return equivalents ? [...equivalents] : [];\n }\n\n /**\n * Resolves an external IRI to an internal kind name.\n */\n resolveIri(iri: string): string | undefined {\n return this.iriToKind.get(iri);\n }\n\n // === Constraint Methods ===\n\n /**\n * Checks if two kinds are disjoint.\n */\n areDisjoint(a: string, b: string): boolean {\n const normalizedPair = a < b ? `${a}|${b}` : `${b}|${a}`;\n return this.disjointPairs.has(normalizedPair);\n }\n\n /**\n * Gets all kinds that are disjoint with the given kind.\n */\n getDisjointKinds(kind: string): readonly string[] {\n const result: string[] = [];\n for (const pair of this.disjointPairs) {\n const parts = pair.split(\"|\");\n const firstKind = parts[0]!;\n const secondKind = parts[1]!;\n if (firstKind === kind) result.push(secondKind);\n else if (secondKind === kind) result.push(firstKind);\n }\n return result;\n }\n\n // === Composition Methods ===\n\n /**\n * Checks if part is part of whole (directly or transitively).\n */\n isPartOf(part: string, whole: string): boolean {\n return isReachable(this.partOfClosure, part, whole);\n }\n\n /**\n * Gets all wholes that contain this part.\n */\n getWholes(part: string): readonly string[] {\n const wholes = this.partOfClosure.get(part);\n return wholes ? [...wholes] : [];\n }\n\n /**\n * Gets all parts of this whole.\n */\n getParts(whole: string): readonly string[] {\n const parts = this.hasPartClosure.get(whole);\n return parts ? [...parts] : [];\n }\n\n // === Edge Relationship Methods ===\n\n /**\n * Gets the inverse edge kind for a given edge kind.\n * If edgeA inverseOf edgeB, then getInverseEdge(\"edgeA\") returns \"edgeB\".\n */\n getInverseEdge(edgeKind: string): string | undefined {\n return this.edgeInverses.get(edgeKind);\n }\n\n /**\n * Gets all edges implied by a given edge (transitively).\n * If A implies B and B implies C, then getImpliedEdges(\"A\") returns [\"B\", \"C\"].\n */\n getImpliedEdges(edgeKind: string): readonly string[] {\n const implied = this.edgeImplicationsClosure.get(edgeKind);\n return implied ? [...implied] : [];\n }\n\n /**\n * Gets all edges that imply a given edge (transitively).\n * If A implies B and B implies C, then getImplyingEdges(\"C\") returns [\"A\", \"B\"].\n * Used for query-time expansion: when querying for C, also include A and B edges.\n */\n getImplyingEdges(edgeKind: string): readonly string[] {\n const implying = this.edgeImplyingClosure.get(edgeKind);\n return implying ? [...implying] : [];\n }\n\n /**\n * Expands an edge kind to include all edges that imply it.\n * Returns [edgeKind, ...implyingEdges].\n */\n expandImplyingEdges(edgeKind: string): readonly string[] {\n const implying = this.edgeImplyingClosure.get(edgeKind) ?? new Set();\n return [edgeKind, ...implying];\n }\n\n // === Edge Endpoint Validation ===\n\n /**\n * Checks if a concrete kind is assignable to a target kind.\n * Uses subsumption: Company is assignable to Organization if Company subClassOf Organization.\n */\n isAssignableTo(concreteKind: string, targetKind: string): boolean {\n if (concreteKind === targetKind) return true;\n return this.isSubClassOf(concreteKind, targetKind);\n }\n\n /**\n * Validates that a kind exists in the registry.\n */\n hasNodeType(name: string): boolean {\n return this.nodeKinds.has(name);\n }\n\n /**\n * Validates that an edge kind exists in the registry.\n */\n hasEdgeType(name: string): boolean {\n return this.edgeKinds.has(name);\n }\n\n /**\n * Gets a node kind by name.\n */\n getNodeType(name: string): NodeType | undefined {\n return this.nodeKinds.get(name);\n }\n\n /**\n * Gets an edge kind by name.\n */\n getEdgeType(name: string): AnyEdgeType | undefined {\n return this.edgeKinds.get(name);\n }\n}\n\n/**\n * Builder function to create empty closures.\n */\nexport function createEmptyClosures(): {\n subClassAncestors: ReadonlyMap<string, ReadonlySet<string>>;\n subClassDescendants: ReadonlyMap<string, ReadonlySet<string>>;\n broaderClosure: ReadonlyMap<string, ReadonlySet<string>>;\n narrowerClosure: ReadonlyMap<string, ReadonlySet<string>>;\n equivalenceSets: ReadonlyMap<string, ReadonlySet<string>>;\n iriToKind: ReadonlyMap<string, string>;\n disjointPairs: ReadonlySet<string>;\n partOfClosure: ReadonlyMap<string, ReadonlySet<string>>;\n hasPartClosure: ReadonlyMap<string, ReadonlySet<string>>;\n edgeInverses: ReadonlyMap<string, string>;\n edgeImplicationsClosure: ReadonlyMap<string, ReadonlySet<string>>;\n edgeImplyingClosure: ReadonlyMap<string, ReadonlySet<string>>;\n} {\n return {\n subClassAncestors: new Map(),\n subClassDescendants: new Map(),\n broaderClosure: new Map(),\n narrowerClosure: new Map(),\n equivalenceSets: new Map(),\n iriToKind: new Map(),\n disjointPairs: new Set(),\n partOfClosure: new Map(),\n hasPartClosure: new Map(),\n edgeInverses: new Map(),\n edgeImplicationsClosure: new Map(),\n edgeImplyingClosure: new Map(),\n };\n}\n\n/**\n * Computes all closures from an ontology.\n */\nexport function computeClosuresFromOntology(\n ontology: readonly OntologyRelation[],\n): {\n subClassAncestors: ReadonlyMap<string, ReadonlySet<string>>;\n subClassDescendants: ReadonlyMap<string, ReadonlySet<string>>;\n broaderClosure: ReadonlyMap<string, ReadonlySet<string>>;\n narrowerClosure: ReadonlyMap<string, ReadonlySet<string>>;\n equivalenceSets: ReadonlyMap<string, ReadonlySet<string>>;\n iriToKind: ReadonlyMap<string, string>;\n disjointPairs: ReadonlySet<string>;\n partOfClosure: ReadonlyMap<string, ReadonlySet<string>>;\n hasPartClosure: ReadonlyMap<string, ReadonlySet<string>>;\n edgeInverses: ReadonlyMap<string, string>;\n edgeImplicationsClosure: ReadonlyMap<string, ReadonlySet<string>>;\n edgeImplyingClosure: ReadonlyMap<string, ReadonlySet<string>>;\n} {\n // Collect relations by type\n const subClassRelations: [string, string][] = [];\n const broaderRelations: [string, string][] = [];\n const equivalentRelations: [string, string][] = [];\n const disjointRelations: [string, string][] = [];\n const partOfRelations: [string, string][] = [];\n const inverseOfRelations: [string, string][] = [];\n const impliesRelations: [string, string][] = [];\n\n for (const relation of ontology) {\n const fromName = getKindName(relation.from);\n const toName = getKindName(relation.to);\n\n switch (relation.metaEdge.name) {\n case META_EDGE_SUB_CLASS_OF: {\n subClassRelations.push([fromName, toName]);\n break;\n }\n case META_EDGE_BROADER: {\n broaderRelations.push([fromName, toName]);\n break;\n }\n case META_EDGE_NARROWER: {\n // narrower is inverse of broader\n broaderRelations.push([toName, fromName]);\n break;\n }\n case META_EDGE_EQUIVALENT_TO:\n case META_EDGE_SAME_AS: {\n equivalentRelations.push([fromName, toName]);\n break;\n }\n case META_EDGE_DISJOINT_WITH: {\n disjointRelations.push([fromName, toName]);\n break;\n }\n case META_EDGE_PART_OF: {\n partOfRelations.push([fromName, toName]);\n break;\n }\n case META_EDGE_HAS_PART: {\n // hasPart is inverse of partOf\n partOfRelations.push([toName, fromName]);\n break;\n }\n case META_EDGE_INVERSE_OF: {\n // inverseOf is symmetric: if A inverseOf B, then B inverseOf A\n inverseOfRelations.push([fromName, toName]);\n break;\n }\n case META_EDGE_IMPLIES: {\n impliesRelations.push([fromName, toName]);\n break;\n }\n }\n }\n\n // Compute subClassOf closures\n const subClassAncestors = computeTransitiveClosure(subClassRelations);\n const subClassDescendants = invertClosure(subClassAncestors);\n\n // Compute broader/narrower closures\n const broaderClosure = computeTransitiveClosure(broaderRelations);\n const narrowerClosure = invertClosure(broaderClosure);\n\n // Compute equivalence sets and IRI mappings\n const equivalenceSets = computeEquivalenceSets(equivalentRelations);\n const iriToKind = computeIriMapping(equivalentRelations);\n\n // Compute disjoint pairs (normalize for symmetric lookup)\n const disjointPairs = computeDisjointPairs(disjointRelations);\n\n // Compute partOf closures\n const partOfClosure = computeTransitiveClosure(partOfRelations);\n const hasPartClosure = invertClosure(partOfClosure);\n\n // Compute edge inverses (symmetric: store both directions)\n const edgeInverses = computeEdgeInverses(inverseOfRelations);\n\n // Compute edge implications closure (transitive)\n // edgeImplicationsClosure: A -> [B, C] means A implies B and C\n // edgeImplyingClosure: C -> [A, B] means A and B imply C (inverse direction)\n const edgeImplicationsClosure = computeTransitiveClosure(impliesRelations);\n const edgeImplyingClosure = invertClosure(edgeImplicationsClosure);\n\n return {\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 * Gets the name from a NodeType, EdgeType, or string.\n */\nfunction getKindName(kindOrIri: NodeType | AnyEdgeType | string): string {\n if (typeof kindOrIri === \"string\") {\n return kindOrIri;\n }\n return kindOrIri.kind;\n}\n\n/**\n * Checks if a string is an external IRI (not a local kind name).\n */\nfunction isExternalIri(value: string): boolean {\n return value.startsWith(\"http://\") || value.startsWith(\"https://\");\n}\n\n/**\n * Computes equivalence sets (symmetric + transitive closure).\n */\nfunction computeEquivalenceSets(\n relations: readonly (readonly [string, string])[],\n): ReadonlyMap<string, ReadonlySet<string>> {\n // Use union-find to compute equivalence classes\n const parent = new Map<string, string>();\n\n function find(x: string): string {\n if (!parent.has(x)) {\n parent.set(x, x);\n return x;\n }\n // Safe: has() check above guarantees key exists\n const parentNode = parent.get(x)!;\n if (parentNode === x) return x;\n const root = find(parentNode);\n parent.set(x, root); // Path compression\n return root;\n }\n\n function union(a: string, b: string): void {\n const rootA = find(a);\n const rootB = find(b);\n if (rootA !== rootB) {\n parent.set(rootA, rootB);\n }\n }\n\n // Build equivalence classes\n for (const [a, b] of relations) {\n union(a, b);\n }\n\n // Collect all members of each equivalence class\n const classes = new Map<string, Set<string>>();\n for (const key of parent.keys()) {\n const root = find(key);\n const existing = classes.get(root) ?? new Set();\n existing.add(key);\n classes.set(root, existing);\n }\n\n // Build result: each node maps to its equivalence set\n const result = new Map<string, ReadonlySet<string>>();\n for (const members of classes.values()) {\n for (const member of members) {\n // Exclude self from equivalence set\n const others = new Set(members);\n others.delete(member);\n result.set(member, others);\n }\n }\n\n return result;\n}\n\n/**\n * Computes mapping from external IRIs to internal kind names.\n */\nfunction computeIriMapping(\n relations: readonly (readonly [string, string])[],\n): ReadonlyMap<string, string> {\n const result = new Map<string, string>();\n\n for (const [a, b] of relations) {\n // If one is an IRI and other is a kind name, map IRI → kind\n if (isExternalIri(a) && !isExternalIri(b)) {\n result.set(a, b);\n } else if (isExternalIri(b) && !isExternalIri(a)) {\n result.set(b, a);\n }\n }\n\n return result;\n}\n\n/**\n * Computes normalized disjoint pairs.\n */\nfunction computeDisjointPairs(\n relations: readonly (readonly [string, string])[],\n): ReadonlySet<string> {\n const result = new Set<string>();\n\n for (const [a, b] of relations) {\n // Normalize pair for consistent lookup\n const normalized = a < b ? `${a}|${b}` : `${b}|${a}`;\n result.add(normalized);\n }\n\n return result;\n}\n\n/**\n * Computes edge inverse mapping (symmetric: stores both directions).\n */\nfunction computeEdgeInverses(\n relations: readonly (readonly [string, string])[],\n): ReadonlyMap<string, string> {\n const result = new Map<string, string>();\n\n for (const [a, b] of relations) {\n // inverseOf is symmetric: A inverseOf B means B inverseOf A too\n result.set(a, b);\n result.set(b, a);\n }\n\n return result;\n}\n","/**\n * Schema serializer for homoiconic storage.\n *\n * Converts a GraphDef to a SerializedSchema for database storage.\n * Uses Zod's toJSONSchema() for property schema serialization.\n */\nimport { z } from \"zod\";\n\nimport {\n getEdgeKinds,\n getNodeKinds,\n type GraphDef,\n} from \"../core/define-graph\";\nimport {\n type EdgeRegistration,\n type NodeRegistration,\n type UniqueConstraint,\n} from \"../core/types\";\nimport {\n getTypeName,\n type MetaEdge,\n type OntologyRelation,\n} from \"../ontology/types\";\nimport { computeClosuresFromOntology } from \"../registry/kind-registry\";\nimport { nowIso } from \"../utils/date\";\nimport {\n type JsonSchema,\n type SchemaHash,\n type SerializedClosures,\n type SerializedEdgeDef,\n type SerializedMetaEdge,\n type SerializedNodeDef,\n type SerializedOntology,\n type SerializedOntologyRelation,\n type SerializedSchema,\n type SerializedUniqueConstraint,\n} from \"./types\";\n\n// ============================================================\n// Main Serialization\n// ============================================================\n\n/**\n * Serializes a GraphDef to a SerializedSchema.\n *\n * @param graph - The graph definition to serialize\n * @param version - The schema version number\n * @returns The serialized schema\n */\nexport function serializeSchema<G extends GraphDef>(\n graph: G,\n version: number,\n): SerializedSchema {\n const nodes = serializeNodes(graph);\n const edges = serializeEdges(graph);\n const ontology = serializeOntology(graph.ontology);\n\n return {\n graphId: graph.id,\n version,\n generatedAt: nowIso(),\n nodes,\n edges,\n ontology,\n defaults: {\n onNodeDelete: graph.defaults.onNodeDelete,\n temporalMode: graph.defaults.temporalMode,\n },\n };\n}\n\n// ============================================================\n// Node Serialization\n// ============================================================\n\n/**\n * Serializes all node definitions.\n */\nfunction serializeNodes<G extends GraphDef>(\n graph: G,\n): Record<string, SerializedNodeDef> {\n const result: Record<string, SerializedNodeDef> = {};\n\n for (const kindName of getNodeKinds(graph)) {\n const registration = graph.nodes[kindName];\n if (registration === undefined) continue;\n result[kindName] = serializeNodeDef(registration);\n }\n\n return result;\n}\n\n/**\n * Serializes a single node registration.\n */\nfunction serializeNodeDef(registration: NodeRegistration): SerializedNodeDef {\n const node = registration.type;\n\n return {\n kind: node.kind,\n properties: serializeZodSchema(node.schema),\n uniqueConstraints: serializeUniqueConstraints(registration.unique ?? []),\n onDelete: registration.onDelete ?? \"restrict\",\n description: node.description,\n };\n}\n\n/**\n * Serializes unique constraints.\n */\nfunction serializeUniqueConstraints(\n constraints: readonly UniqueConstraint[],\n): readonly SerializedUniqueConstraint[] {\n return constraints.map((constraint) => ({\n name: constraint.name,\n fields: [...constraint.fields],\n where:\n constraint.where ? serializeWherePredicate(constraint.where) : undefined,\n scope: constraint.scope,\n collation: constraint.collation,\n }));\n}\n\n/**\n * A serialized predicate structure (matches UniqueConstraintPredicate from core/types).\n */\ntype SerializedPredicate = Readonly<{\n __type: \"unique_predicate\";\n field: string;\n op: \"isNull\" | \"isNotNull\";\n}>;\n\n/**\n * Field builder returned by the predicate proxy.\n */\ntype FieldPredicateBuilder = Readonly<{\n isNull: () => SerializedPredicate;\n isNotNull: () => SerializedPredicate;\n}>;\n\n/**\n * Predicate builder type for where clause serialization.\n */\ntype PredicateBuilder = Readonly<Record<string, FieldPredicateBuilder>>;\n\n/**\n * Serializes a where predicate function to a JSON-serializable structure.\n *\n * The where function is called with a proxy builder that captures the\n * field and operation, which can then be serialized and later deserialized.\n */\nfunction serializeWherePredicate(\n whereFunction: (builder: PredicateBuilder) => SerializedPredicate,\n): string {\n // Create a proxy builder that captures the predicate structure\n const builder = new Proxy(\n {},\n {\n get(_target, field: string): FieldPredicateBuilder {\n return {\n isNull: (): SerializedPredicate => ({\n __type: \"unique_predicate\",\n field,\n op: \"isNull\" as const,\n }),\n isNotNull: (): SerializedPredicate => ({\n __type: \"unique_predicate\",\n field,\n op: \"isNotNull\" as const,\n }),\n };\n },\n },\n );\n\n // Call the where function to get the predicate\n const predicate = whereFunction(builder);\n\n // Serialize the predicate structure as JSON\n return JSON.stringify({ field: predicate.field, op: predicate.op });\n}\n\n/**\n * Deserializes a where predicate JSON back to a predicate function.\n *\n * This can be used to reconstruct a UniqueConstraint's where clause\n * from a serialized schema.\n *\n * @param serialized - The JSON string from serialization\n * @returns A where function that returns the predicate structure\n */\n/**\n * Unique predicate result type.\n */\ntype UniquePredicate = Readonly<{\n __type: \"unique_predicate\";\n field: string;\n op: \"isNull\" | \"isNotNull\";\n}>;\n\nexport function deserializeWherePredicate(\n serialized: string,\n): (builder: PredicateBuilder) => UniquePredicate {\n const parsed = JSON.parse(serialized) as {\n field: string;\n op: \"isNull\" | \"isNotNull\";\n };\n\n return (builder: PredicateBuilder): UniquePredicate => {\n const fieldBuilder = builder[parsed.field];\n if (!fieldBuilder) {\n throw new Error(`Unknown field in where predicate: ${parsed.field}`);\n }\n\n const result =\n parsed.op === \"isNull\" ? fieldBuilder.isNull() : fieldBuilder.isNotNull();\n return {\n __type: \"unique_predicate\",\n field: result.field,\n op: result.op,\n };\n };\n}\n\n// ============================================================\n// Edge Serialization\n// ============================================================\n\n/**\n * Serializes all edge definitions.\n */\nfunction serializeEdges<G extends GraphDef>(\n graph: G,\n): Record<string, SerializedEdgeDef> {\n const result: Record<string, SerializedEdgeDef> = {};\n\n for (const kindName of getEdgeKinds(graph)) {\n const registration = graph.edges[kindName];\n if (registration === undefined) continue;\n result[kindName] = serializeEdgeDef(registration);\n }\n\n return result;\n}\n\n/**\n * Serializes a single edge registration.\n */\nfunction serializeEdgeDef(registration: EdgeRegistration): SerializedEdgeDef {\n const edge = registration.type;\n\n return {\n kind: edge.kind,\n fromKinds: registration.from.map((node) => node.kind),\n toKinds: registration.to.map((node) => node.kind),\n properties: serializeZodSchema(edge.schema),\n cardinality: registration.cardinality ?? \"many\",\n endpointExistence: registration.endpointExistence ?? \"notDeleted\",\n description: edge.description,\n };\n}\n\n// ============================================================\n// Ontology Serialization\n// ============================================================\n\n/**\n * Serializes the complete ontology.\n */\nfunction serializeOntology(\n relations: readonly OntologyRelation[],\n): SerializedOntology {\n // Collect unique meta-edges\n const metaEdgeMap = new Map<string, MetaEdge>();\n for (const relation of relations) {\n const metaEdge = relation.metaEdge;\n if (!metaEdgeMap.has(metaEdge.name)) {\n metaEdgeMap.set(metaEdge.name, metaEdge);\n }\n }\n\n // Serialize meta-edges\n const metaEdges: Record<string, SerializedMetaEdge> = {};\n for (const [name, metaEdge] of metaEdgeMap) {\n metaEdges[name] = serializeMetaEdge(metaEdge);\n }\n\n // Serialize relations\n const serializedRelations = relations.map((relation) =>\n serializeOntologyRelation(relation),\n );\n\n // Compute and serialize closures\n const closures = serializeClosures(relations);\n\n return {\n metaEdges,\n relations: serializedRelations,\n closures,\n };\n}\n\n/**\n * Serializes a meta-edge.\n */\nfunction serializeMetaEdge(metaEdge: MetaEdge): SerializedMetaEdge {\n return {\n name: metaEdge.name,\n transitive: metaEdge.properties.transitive,\n symmetric: metaEdge.properties.symmetric,\n reflexive: metaEdge.properties.reflexive,\n inverse: metaEdge.properties.inverse,\n inference: metaEdge.properties.inference,\n description: metaEdge.properties.description,\n };\n}\n\n/**\n * Serializes an ontology relation.\n */\nfunction serializeOntologyRelation(\n relation: OntologyRelation,\n): SerializedOntologyRelation {\n return {\n metaEdge: relation.metaEdge.name,\n from: getTypeName(relation.from),\n to: getTypeName(relation.to),\n };\n}\n\n/**\n * Serializes precomputed closures.\n */\nfunction serializeClosures(\n relations: readonly OntologyRelation[],\n): SerializedClosures {\n if (relations.length === 0) {\n return {\n subClassAncestors: {},\n subClassDescendants: {},\n broaderClosure: {},\n narrowerClosure: {},\n equivalenceSets: {},\n disjointPairs: [],\n partOfClosure: {},\n hasPartClosure: {},\n iriToKind: {},\n edgeInverses: {},\n edgeImplicationsClosure: {},\n edgeImplyingClosure: {},\n };\n }\n\n const computed = computeClosuresFromOntology(relations);\n\n return {\n subClassAncestors: mapToRecord(computed.subClassAncestors),\n subClassDescendants: mapToRecord(computed.subClassDescendants),\n broaderClosure: mapToRecord(computed.broaderClosure),\n narrowerClosure: mapToRecord(computed.narrowerClosure),\n equivalenceSets: mapToRecord(computed.equivalenceSets),\n disjointPairs: [...computed.disjointPairs],\n partOfClosure: mapToRecord(computed.partOfClosure),\n hasPartClosure: mapToRecord(computed.hasPartClosure),\n iriToKind: mapToSimpleRecord(computed.iriToKind),\n edgeInverses: mapToSimpleRecord(computed.edgeInverses),\n edgeImplicationsClosure: mapToRecord(computed.edgeImplicationsClosure),\n edgeImplyingClosure: mapToRecord(computed.edgeImplyingClosure),\n };\n}\n\n/**\n * Converts a Map<string, Set<string>> to Record<string, string[]>.\n */\nfunction mapToRecord(\n map: ReadonlyMap<string, ReadonlySet<string>>,\n): Record<string, readonly string[]> {\n const result: Record<string, readonly string[]> = {};\n for (const [key, values] of map) {\n result[key] = [...values];\n }\n return result;\n}\n\n/**\n * Converts a Map<string, string> to Record<string, string>.\n */\nfunction mapToSimpleRecord(\n map: ReadonlyMap<string, string>,\n): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [key, value] of map) {\n result[key] = value;\n }\n return result;\n}\n\n// ============================================================\n// Zod Schema Serialization\n// ============================================================\n\n/**\n * Serializes a Zod schema to JSON Schema.\n *\n * Uses Zod 4's toJSONSchema() method for conversion.\n */\nfunction serializeZodSchema(schema: z.ZodType): JsonSchema {\n try {\n // Zod 4 has toJSONSchema as a standard export\n const jsonSchema = z.toJSONSchema(schema);\n return jsonSchema as JsonSchema;\n } catch {\n // Fallback for schemas that can't be converted\n return { type: \"object\" };\n }\n}\n\n// ============================================================\n// Schema Hashing\n// ============================================================\n\n/**\n * Computes a hash of the schema content for change detection.\n *\n * Excludes version and generatedAt since those change on every save.\n */\nexport async function computeSchemaHash(\n schema: SerializedSchema,\n): Promise<SchemaHash> {\n // Create a hashable representation excluding dynamic fields\n const hashable = {\n graphId: schema.graphId,\n nodes: schema.nodes,\n edges: schema.edges,\n ontology: schema.ontology,\n defaults: schema.defaults,\n };\n\n // Serialize with sorted keys for deterministic output\n const json = JSON.stringify(hashable, sortedReplacer);\n return sha256Hash(json);\n}\n\n/**\n * JSON replacer that sorts object keys for deterministic serialization.\n */\nfunction sortedReplacer(_key: string, value: unknown): unknown {\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n const sorted: Record<string, unknown> = {};\n for (const key of Object.keys(value).toSorted()) {\n sorted[key] = (value as Record<string, unknown>)[key];\n }\n return sorted;\n }\n return value;\n}\n\n/**\n * Computes SHA-256 hash of a string using the Web Crypto API.\n *\n * Works in Node.js 16+, Cloudflare Workers, Deno, and browsers.\n * Returns first 16 hex characters (64 bits) for a compact but collision-resistant hash.\n */\nasync function sha256Hash(input: string): Promise<string> {\n const encoded = new TextEncoder().encode(input);\n const digest = await globalThis.crypto.subtle.digest(\"SHA-256\", encoded);\n const bytes = new Uint8Array(digest);\n // Only need 8 bytes (16 hex chars) — avoid converting the full 32-byte digest\n let hex = \"\";\n for (let index = 0; index < 8; index++) {\n const byte = bytes[index];\n if (byte === undefined) break;\n hex += byte.toString(16).padStart(2, \"0\");\n }\n return hex;\n}\n","/**\n * Types for serialized schema storage.\n *\n * These types represent the JSON-serializable format used for\n * homoiconic schema storage in the database.\n *\n * The Zod schema (serializedSchemaZod) is the single source of truth.\n * The TypeScript type (SerializedSchema) is inferred from it.\n */\nimport { z } from \"zod\";\n\nimport {\n type Cardinality,\n type Collation,\n type DeleteBehavior,\n type EndpointExistence,\n type TemporalMode,\n type UniquenessScope,\n} from \"../core/types\";\nimport { type InferenceType } from \"../ontology/types\";\n\n// ============================================================\n// Enum Zod Schemas\n//\n// These mirror the literal union types from core/types.ts and\n// ontology/types.ts. The Zod schema validates that stored values\n// are members of the known set — unknown enum values from newer\n// schema versions are rejected at the parse boundary rather than\n// silently cast to narrow union types.\n// ============================================================\n\nconst deleteBehaviorZod = z.enum([\"restrict\", \"cascade\", \"disconnect\"]);\n\nconst cardinalityZod = z.enum([\"many\", \"one\", \"unique\", \"oneActive\"]);\n\nconst endpointExistenceZod = z.enum([\"notDeleted\", \"currentlyValid\", \"ever\"]);\n\nconst temporalModeZod = z.enum([\n \"current\",\n \"asOf\",\n \"includeEnded\",\n \"includeTombstones\",\n]);\n\nconst uniquenessScopeZod = z.enum([\"kind\", \"kindWithSubClasses\"]);\n\nconst collationZod = z.enum([\"binary\", \"caseInsensitive\"]);\n\nconst inferenceTypeZod = z.enum([\n \"subsumption\",\n \"hierarchy\",\n \"substitution\",\n \"constraint\",\n \"composition\",\n \"association\",\n \"none\",\n]);\n\n// ============================================================\n// JSON Schema Types (from Zod)\n// ============================================================\n\n/**\n * JSON Schema type (subset used by Zod toJSONSchema).\n *\n * This is a simplified version - the actual JSON Schema has many more properties.\n */\nexport type JsonSchema = Readonly<{\n $schema?: string;\n type?: string | readonly string[];\n properties?: Record<string, JsonSchema>;\n required?: readonly string[];\n items?: JsonSchema;\n additionalProperties?: boolean | JsonSchema;\n enum?: readonly unknown[];\n const?: unknown;\n anyOf?: readonly JsonSchema[];\n oneOf?: readonly JsonSchema[];\n allOf?: readonly JsonSchema[];\n not?: JsonSchema;\n description?: string;\n default?: unknown;\n minimum?: number;\n maximum?: number;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n format?: string;\n [key: string]: unknown;\n}>;\n\n// ============================================================\n// Serialized Meta-Edge\n// ============================================================\n\n/**\n * Serialized representation of a meta-edge.\n */\nexport type SerializedMetaEdge = Readonly<{\n name: string;\n transitive: boolean;\n symmetric: boolean;\n reflexive: boolean;\n inverse: string | undefined;\n inference: InferenceType;\n description: string | undefined;\n}>;\n\n// ============================================================\n// Serialized Ontology Relation\n// ============================================================\n\n/**\n * Serialized representation of an ontology relation.\n */\nexport type SerializedOntologyRelation = Readonly<{\n metaEdge: string; // Meta-edge name\n from: string; // Node kind name or external IRI\n to: string; // Node kind name or external IRI\n}>;\n\n// ============================================================\n// Serialized Closures\n// ============================================================\n\n/**\n * Precomputed closures stored in the schema for fast runtime lookup.\n */\nexport type SerializedClosures = Readonly<{\n subClassAncestors: Record<string, readonly string[]>;\n subClassDescendants: Record<string, readonly string[]>;\n broaderClosure: Record<string, readonly string[]>;\n narrowerClosure: Record<string, readonly string[]>;\n equivalenceSets: Record<string, readonly string[]>;\n disjointPairs: readonly string[]; // [\"Organization|Person\", ...]\n partOfClosure: Record<string, readonly string[]>;\n hasPartClosure: Record<string, readonly string[]>;\n iriToKind: Record<string, string>;\n edgeInverses: Record<string, string>; // {\"likes\": \"likedBy\", ...}\n edgeImplicationsClosure: Record<string, readonly string[]>;\n edgeImplyingClosure: Record<string, readonly string[]>;\n}>;\n\n// ============================================================\n// Serialized Ontology\n// ============================================================\n\n/**\n * Complete serialized ontology section.\n */\nexport type SerializedOntology = Readonly<{\n metaEdges: Record<string, SerializedMetaEdge>;\n relations: readonly SerializedOntologyRelation[];\n closures: SerializedClosures;\n}>;\n\n// ============================================================\n// Serialized Uniqueness Constraint\n// ============================================================\n\n/**\n * Serialized representation of a uniqueness constraint.\n */\nexport type SerializedUniqueConstraint = Readonly<{\n name: string;\n fields: readonly string[];\n where: string | undefined; // Serialized predicate or undefined\n scope: UniquenessScope;\n collation: Collation;\n}>;\n\n// ============================================================\n// Serialized Node Definition\n// ============================================================\n\n/**\n * Serialized representation of a node kind.\n */\nexport type SerializedNodeDef = Readonly<{\n kind: string;\n properties: JsonSchema;\n uniqueConstraints: readonly SerializedUniqueConstraint[];\n onDelete: DeleteBehavior;\n description: string | undefined;\n}>;\n\n// ============================================================\n// Serialized Edge Definition\n// ============================================================\n\n/**\n * Serialized representation of an edge kind.\n */\nexport type SerializedEdgeDef = Readonly<{\n kind: string;\n fromKinds: readonly string[];\n toKinds: readonly string[];\n properties: JsonSchema;\n cardinality: Cardinality;\n endpointExistence: EndpointExistence;\n description: string | undefined;\n}>;\n\n// ============================================================\n// Serialized Schema\n// ============================================================\n\n/**\n * Validates that each record key matches the identifier field inside its value.\n * Catches corruption like `nodes.Person.kind = \"Company\"`.\n */\nfunction checkRecordKeyMatchesField(\n field: string,\n section: string,\n): (\n record: Record<string, Record<string, unknown>>,\n ctx: z.RefinementCtx,\n) => void {\n return (record, ctx) => {\n for (const [key, value] of Object.entries(record)) {\n const embedded = value[field];\n if (typeof embedded === \"string\" && embedded !== key) {\n ctx.addIssue({\n code: \"custom\",\n path: [key, field],\n message: `Record key \"${key}\" does not match ${field} \"${embedded}\" in ${section}`,\n });\n }\n }\n };\n}\n\n/**\n * Zod schema for validating serialized schema documents read from the database.\n *\n * Enum fields (temporalMode, cardinality, deleteBehavior, etc.) are validated\n * against the real literal unions — unknown enum values from newer schema\n * versions are rejected at the parse boundary.\n *\n * Nested objects use .loose() so that extra structural fields added by newer\n * versions are accepted without failing validation (forward compatibility for\n * shape, strict for semantics).\n */\nexport const serializedSchemaZod = z.object({\n graphId: z.string(),\n version: z.number(),\n generatedAt: z.string(),\n nodes: z\n .record(\n z.string(),\n z\n .object({\n kind: z.string(),\n properties: z.record(z.string(), z.unknown()),\n uniqueConstraints: z.array(\n z\n .object({\n name: z.string(),\n fields: z.array(z.string()),\n where: z.string().optional(),\n scope: uniquenessScopeZod,\n collation: collationZod,\n })\n .loose(),\n ),\n onDelete: deleteBehaviorZod,\n description: z.string().optional(),\n })\n .loose(),\n )\n .superRefine(checkRecordKeyMatchesField(\"kind\", \"nodes\")),\n edges: z\n .record(\n z.string(),\n z\n .object({\n kind: z.string(),\n fromKinds: z.array(z.string()),\n toKinds: z.array(z.string()),\n properties: z.record(z.string(), z.unknown()),\n cardinality: cardinalityZod,\n endpointExistence: endpointExistenceZod,\n description: z.string().optional(),\n })\n .loose(),\n )\n .superRefine(checkRecordKeyMatchesField(\"kind\", \"edges\")),\n ontology: z\n .object({\n metaEdges: z\n .record(\n z.string(),\n z\n .object({\n name: z.string(),\n transitive: z.boolean(),\n symmetric: z.boolean(),\n reflexive: z.boolean(),\n inference: inferenceTypeZod,\n inverse: z.string().optional(),\n description: z.string().optional(),\n })\n .loose(),\n )\n .superRefine(checkRecordKeyMatchesField(\"name\", \"ontology.metaEdges\")),\n relations: z.array(\n z\n .object({\n metaEdge: z.string(),\n from: z.string(),\n to: z.string(),\n })\n .loose(),\n ),\n closures: z\n .object({\n subClassAncestors: z.record(z.string(), z.array(z.string())),\n subClassDescendants: z.record(z.string(), z.array(z.string())),\n broaderClosure: z.record(z.string(), z.array(z.string())),\n narrowerClosure: z.record(z.string(), z.array(z.string())),\n equivalenceSets: z.record(z.string(), z.array(z.string())),\n disjointPairs: z.array(z.string()),\n partOfClosure: z.record(z.string(), z.array(z.string())),\n hasPartClosure: z.record(z.string(), z.array(z.string())),\n iriToKind: z.record(z.string(), z.string()),\n edgeInverses: z.record(z.string(), z.string()),\n edgeImplicationsClosure: z.record(z.string(), z.array(z.string())),\n edgeImplyingClosure: z.record(z.string(), z.array(z.string())),\n })\n .loose(),\n })\n .loose(),\n defaults: z\n .object({\n onNodeDelete: deleteBehaviorZod,\n temporalMode: temporalModeZod,\n })\n .loose(),\n});\n\n/**\n * Complete serialized schema document.\n *\n * This is the format stored in the schema_doc column of\n * typegraph_schema_versions. The type is kept explicit rather than\n * inferred from the Zod schema so that downstream code sees the\n * precise literal union types (DeleteBehavior, TemporalMode, etc.)\n * instead of the broader `string` type that Zod's passthrough schema uses.\n */\nexport type SerializedSchema = Readonly<{\n graphId: string;\n version: number;\n generatedAt: string;\n nodes: Record<string, SerializedNodeDef>;\n edges: Record<string, SerializedEdgeDef>;\n ontology: SerializedOntology;\n defaults: Readonly<{\n onNodeDelete: DeleteBehavior;\n temporalMode: TemporalMode;\n }>;\n}>;\n\n// ============================================================\n// Schema Hash\n// ============================================================\n\n/**\n * A schema hash for detecting changes.\n *\n * We hash the schema content (excluding version and generatedAt)\n * to detect if the schema has actually changed.\n */\nexport type SchemaHash = string;\n","/**\n * Schema manager for TypeGraph.\n *\n * Provides schema lifecycle management:\n * - Initialization on first store creation\n * - Validation on store open\n * - Auto-migration for safe changes\n * - Error reporting for breaking changes\n */\nimport { type GraphBackend, type SchemaVersionRow } from \"../backend/types\";\nimport { type GraphDef } from \"../core/define-graph\";\nimport { DatabaseOperationError, MigrationError } from \"../errors\";\nimport {\n computeSchemaDiff,\n getMigrationActions,\n isBackwardsCompatible,\n type SchemaDiff,\n} from \"./migration\";\nimport { computeSchemaHash, serializeSchema } from \"./serializer\";\nimport { type SerializedSchema, serializedSchemaZod } from \"./types\";\n\n/**\n * Parses and validates a serialized schema document from the database.\n *\n * Uses the Zod schema to validate the full nested structure, catching\n * corruption, incompatible schema versions, or truncated JSON at the\n * parse boundary rather than letting invalid data propagate silently.\n */\nfunction parseSerializedSchema(json: string): SerializedSchema {\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch {\n throw new DatabaseOperationError(\n \"Stored schema document is not valid JSON\",\n { operation: \"select\", entity: \"schema\" },\n );\n }\n\n const result = serializedSchemaZod.safeParse(parsed);\n if (!result.success) {\n const issues = result.error.issues\n .map((issue) => `${issue.path.join(\".\")}: ${issue.message}`)\n .join(\"; \");\n throw new DatabaseOperationError(\n `Stored schema document is malformed: ${issues}`,\n { operation: \"select\", entity: \"schema\" },\n );\n }\n\n // The Zod schema validates enum fields (temporalMode, cardinality, etc.)\n // against the real literal unions. The cast is sound — the only broadening\n // is .loose() on objects (extra fields), not on enum values.\n return result.data as SerializedSchema;\n}\n\n// ============================================================\n// Helpers\n// ============================================================\n\nconst MISSING_TABLE_PATTERNS = [\n \"no such table\", // SQLite\n \"does not exist\", // PostgreSQL (\"relation ... does not exist\")\n \"SQLITE_ERROR\", // D1 / Durable Objects error code\n];\n\nfunction isMissingTableError(error: unknown): boolean {\n const message = error instanceof Error ? error.message : String(error);\n return MISSING_TABLE_PATTERNS.some((pattern) => message.includes(pattern));\n}\n\n// ============================================================\n// Types\n// ============================================================\n\n/**\n * Result of schema validation.\n */\nexport type SchemaValidationResult =\n | { status: \"initialized\"; version: number }\n | { status: \"unchanged\"; version: number }\n | {\n status: \"migrated\";\n fromVersion: number;\n toVersion: number;\n diff: SchemaDiff;\n }\n | { status: \"pending\"; version: number; diff: SchemaDiff }\n | { status: \"breaking\"; diff: SchemaDiff; actions: readonly string[] };\n\n/**\n * Context passed to migration lifecycle hooks.\n *\n * Hooks are intended for observability (logging, metrics, alerts),\n * not for data transformations. Use an explicit migration runner\n * for backfill scripts — see the schema evolution guide.\n */\nexport type MigrationHookContext = Readonly<{\n graphId: string;\n fromVersion: number;\n toVersion: number;\n diff: SchemaDiff;\n}>;\n\n/**\n * Options for schema management.\n */\nexport type SchemaManagerOptions = Readonly<{\n /** If true, auto-migrate safe changes. Default: true */\n autoMigrate?: boolean;\n /** If true, throw on breaking changes. Default: true */\n throwOnBreaking?: boolean;\n /** Called before a safe auto-migration is applied. For observability only. */\n onBeforeMigrate?: (context: MigrationHookContext) => void | Promise<void>;\n /** Called after a safe auto-migration is applied. For observability only. */\n onAfterMigrate?: (context: MigrationHookContext) => void | Promise<void>;\n}>;\n\n// ============================================================\n// Schema Manager\n// ============================================================\n\n/**\n * Ensures the schema is initialized and up-to-date.\n *\n * This is the main entry point for schema management. It:\n * 1. Initializes the schema if this is the first run (version 1)\n * 2. Returns \"unchanged\" if the schema matches the current graph\n * 3. Auto-migrates safe changes if autoMigrate is true\n * 4. Throws MigrationError for breaking changes if throwOnBreaking is true\n *\n * @param backend - The database backend\n * @param graph - The current graph definition\n * @param options - Schema management options\n * @returns The result of schema validation\n * @throws MigrationError if breaking changes detected and throwOnBreaking is true\n */\nexport async function ensureSchema<G extends GraphDef>(\n backend: GraphBackend,\n graph: G,\n options?: SchemaManagerOptions,\n): Promise<SchemaValidationResult> {\n const autoMigrate = options?.autoMigrate ?? true;\n const throwOnBreaking = options?.throwOnBreaking ?? true;\n\n // Get the active schema from the database.\n // On a fresh database the base tables may not exist yet. If\n // bootstrapTables is available, create them and retry.\n let activeSchema: SchemaVersionRow | undefined;\n try {\n activeSchema = await backend.getActiveSchema(graph.id);\n } catch (error) {\n if (backend.bootstrapTables && isMissingTableError(error)) {\n await backend.bootstrapTables();\n activeSchema = await backend.getActiveSchema(graph.id);\n } else {\n throw error;\n }\n }\n\n if (!activeSchema) {\n // No schema exists - initialize with version 1\n const result = await initializeSchema(backend, graph);\n return { status: \"initialized\", version: result.version };\n }\n\n // Parse the stored schema\n const storedSchema = parseSerializedSchema(activeSchema.schema_doc);\n\n // Serialize the current graph for comparison\n const currentSchema = serializeSchema(graph, activeSchema.version + 1);\n\n // Quick hash check - if hashes match, schemas are identical\n const storedHash = activeSchema.schema_hash;\n const currentHash = await computeSchemaHash(currentSchema);\n\n if (storedHash === currentHash) {\n return { status: \"unchanged\", version: activeSchema.version };\n }\n\n // Hashes differ - compute the diff\n const diff = computeSchemaDiff(storedSchema, currentSchema);\n\n if (!diff.hasChanges) {\n // Hash changed but no semantic changes (shouldn't happen, but handle it)\n return { status: \"unchanged\", version: activeSchema.version };\n }\n\n // Check if changes are backwards compatible\n if (isBackwardsCompatible(diff)) {\n if (autoMigrate) {\n // Safe changes - auto-migrate\n const hookContext: MigrationHookContext = {\n graphId: graph.id,\n fromVersion: activeSchema.version,\n toVersion: activeSchema.version + 1,\n diff,\n };\n await options?.onBeforeMigrate?.(hookContext);\n const newVersion = await migrateSchema(\n backend,\n graph,\n activeSchema.version,\n );\n await options?.onAfterMigrate?.(hookContext);\n return {\n status: \"migrated\",\n fromVersion: activeSchema.version,\n toVersion: newVersion,\n diff,\n };\n }\n // Auto-migrate disabled but changes are safe\n return {\n status: \"pending\",\n version: activeSchema.version,\n diff,\n };\n }\n\n // Breaking changes detected\n const actions = getMigrationActions(diff);\n\n if (throwOnBreaking) {\n throw new MigrationError(\n `Schema migration required: ${diff.summary}. ` +\n `${actions.length} migration action(s) needed. ` +\n `Use getSchemaChanges() to review, then migrateSchema() to apply.`,\n {\n graphId: graph.id,\n fromVersion: activeSchema.version,\n toVersion: activeSchema.version + 1,\n },\n );\n }\n\n return { status: \"breaking\", diff, actions };\n}\n\n/**\n * Initializes the schema for a new graph.\n *\n * Creates version 1 of the schema and marks it as active.\n *\n * @param backend - The database backend\n * @param graph - The graph definition\n * @returns The created schema version row\n */\nexport async function initializeSchema<G extends GraphDef>(\n backend: GraphBackend,\n graph: G,\n): Promise<SchemaVersionRow> {\n const schema = serializeSchema(graph, 1);\n const hash = await computeSchemaHash(schema);\n\n return backend.insertSchema({\n graphId: graph.id,\n version: 1,\n schemaHash: hash,\n schemaDoc: schema,\n isActive: true,\n });\n}\n\n/**\n * Migrates the schema to match the current graph definition.\n *\n * This creates a new schema version and marks it as active.\n * The old version is preserved for history/rollback.\n *\n * @param backend - The database backend\n * @param graph - The current graph definition\n * @param currentVersion - The current active schema version\n * @returns The new version number\n */\nexport async function migrateSchema<G extends GraphDef>(\n backend: GraphBackend,\n graph: G,\n currentVersion: number,\n): Promise<number> {\n const newVersion = currentVersion + 1;\n const schema = serializeSchema(graph, newVersion);\n const hash = await computeSchemaHash(schema);\n\n // Insert new version (not active yet)\n await backend.insertSchema({\n graphId: graph.id,\n version: newVersion,\n schemaHash: hash,\n schemaDoc: schema,\n isActive: false,\n });\n\n // Atomically switch to the new version\n await backend.setActiveSchema(graph.id, newVersion);\n\n return newVersion;\n}\n\n/**\n * Rolls back the active schema to a previous version.\n *\n * The target version must already exist in the version history.\n * This does not delete newer versions — it simply switches the active pointer.\n *\n * @param backend - The database backend\n * @param graphId - The graph ID\n * @param targetVersion - The version to roll back to\n * @throws MigrationError if the target version does not exist\n */\nexport async function rollbackSchema(\n backend: GraphBackend,\n graphId: string,\n targetVersion: number,\n): Promise<void> {\n const row = await backend.getSchemaVersion(graphId, targetVersion);\n if (!row) {\n throw new MigrationError(\n `Cannot rollback to version ${targetVersion}: version does not exist.`,\n { graphId, fromVersion: targetVersion, toVersion: targetVersion },\n );\n }\n await backend.setActiveSchema(graphId, targetVersion);\n}\n\n/**\n * Gets the current active schema for a graph.\n *\n * @param backend - The database backend\n * @param graphId - The graph ID\n * @returns The active schema or undefined if not initialized\n */\nexport async function getActiveSchema(\n backend: GraphBackend,\n graphId: string,\n): Promise<SerializedSchema | undefined> {\n const row = await backend.getActiveSchema(graphId);\n if (!row) return undefined;\n return parseSerializedSchema(row.schema_doc);\n}\n\n/**\n * Checks if a graph's schema has been initialized.\n *\n * @param backend - The database backend\n * @param graphId - The graph ID\n * @returns True if the schema has been initialized\n */\nexport async function isSchemaInitialized(\n backend: GraphBackend,\n graphId: string,\n): Promise<boolean> {\n const row = await backend.getActiveSchema(graphId);\n return row !== undefined;\n}\n\n/**\n * Gets the schema diff between the stored schema and current graph.\n *\n * @param backend - The database backend\n * @param graph - The current graph definition\n * @returns The diff, or undefined if schema not initialized\n */\nexport async function getSchemaChanges<G extends GraphDef>(\n backend: GraphBackend,\n graph: G,\n): Promise<SchemaDiff | undefined> {\n const activeSchema = await backend.getActiveSchema(graph.id);\n if (!activeSchema) return undefined;\n\n const storedSchema = parseSerializedSchema(activeSchema.schema_doc);\n const currentSchema = serializeSchema(graph, activeSchema.version + 1);\n\n return computeSchemaDiff(storedSchema, currentSchema);\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/backend/types.ts"],"names":[],"mappings":";AAqsBO,SAAS,oBAAA,CACd,SACA,QAAA,EACc;AACd,EAAA,IAAI,QAAA,GAAW,KAAA;AACf,EAAA,OAAO;AAAA,IACL,GAAG,OAAA;AAAA,IACH,MAAM,KAAA,GAAuB;AAC3B,MAAA,IAAI,QAAA,EAAU;AACd,MAAA,QAAA,GAAW,IAAA;AACX,MAAA,MAAM,QAAQ,KAAA,EAAM;AACpB,MAAA,MAAM,QAAA,EAAS;AAAA,IACjB;AAAA,GACF;AACF;AAeA,eAAsB,0BAAA,CACpB,OAAA,EACA,EAAA,EACA,QAAA,EACY;AACZ,EAAA,IAAI,CAAC,OAAA,CAAQ,YAAA,CAAa,YAAA,EAAc;AACtC,IAAA,OAAO,EAAA,CAAG,YAAY,OAAO,CAAA;AAAA,EAC/B;AACA,EAAA,OAAO,QAAQ,WAAA,CAAY,CAAC,EAAA,KAAO,EAAA,CAAG,EAAE,CAAC,CAAA;AAC3C;AAyLO,IAAM,mBAAA,GAA2C;AAAA,EACtD,KAAA,EAAO,KAAA;AAAA;AAAA,EACP,cAAA,EAAgB,IAAA;AAAA;AAAA,EAChB,UAAA,EAAY,KAAA;AAAA;AAAA,EACZ,GAAA,EAAK,IAAA;AAAA;AAAA,EACL,SAAA,EAAW,IAAA;AAAA;AAAA,EACX,YAAA,EAAc;AAAA;AAChB;AAKO,IAAM,qBAAA,GAA6C;AAAA,EACxD,KAAA,EAAO,IAAA;AAAA;AAAA,EACP,cAAA,EAAgB,IAAA;AAAA,EAChB,UAAA,EAAY,IAAA;AAAA,EACZ,GAAA,EAAK,IAAA;AAAA,EACL,SAAA,EAAW,IAAA;AAAA,EACX,YAAA,EAAc;AAAA;AAChB","file":"chunk-GUTQTMOV.js","sourcesContent":["/**\n * Backend interface types for TypeGraph storage.\n *\n * The backend abstracts database operations, allowing different\n * SQL implementations (SQLite, PostgreSQL) behind a common interface.\n */\nimport { type SQL } from \"drizzle-orm\";\n\nimport { type TemporalMode } from \"../core/types\";\nimport { type SqlTableNames } from \"../query/compiler/schema\";\nimport { type FulltextStrategy } from \"../query/dialect/fulltext-strategy\";\nimport { type SerializedSchema } from \"../schema/types\";\n\n// ============================================================\n// Vector Search Types\n// ============================================================\n\n/**\n * Supported vector similarity metrics.\n */\nexport type VectorMetric = \"cosine\" | \"l2\" | \"inner_product\";\n\n/**\n * Supported vector index types.\n */\nexport type VectorIndexType = \"hnsw\" | \"ivfflat\" | \"none\";\n\n/**\n * Vector search capabilities.\n */\nexport type VectorCapabilities = Readonly<{\n /** Whether the backend supports vector operations */\n supported: boolean;\n /** Supported similarity metrics */\n metrics: readonly VectorMetric[];\n /** Supported index types */\n indexTypes: readonly VectorIndexType[];\n /** Maximum dimensions supported */\n maxDimensions: number;\n}>;\n\n// ============================================================\n// Fulltext Search Types\n// ============================================================\n\n/**\n * Query modes for fulltext search.\n *\n * - \"websearch\": Google-style syntax (quoted phrases, +required, -excluded).\n * Postgres: `websearch_to_tsquery`. SQLite: translated to FTS5 MATCH.\n * - \"phrase\": treats the whole query as a phrase.\n * Postgres: `phraseto_tsquery`. SQLite: FTS5 `\"...\"` phrase.\n * - \"plain\": splits on whitespace and ANDs terms.\n * Postgres: `plainto_tsquery`. SQLite: default FTS5 AND.\n * - \"raw\": dialect-native syntax passed through unchanged.\n */\nexport type FulltextQueryMode = \"websearch\" | \"phrase\" | \"plain\" | \"raw\";\n\n/**\n * Fulltext search capabilities declared by a backend.\n */\nexport type FulltextCapabilities = Readonly<{\n /** Whether the backend supports fulltext operations */\n supported: boolean;\n /**\n * Language / tokenizer names understood by this backend.\n * Postgres: installed regconfigs (english, simple, ...).\n * SQLite FTS5: tokenizer names (unicode61, porter, trigram).\n */\n languages: readonly string[];\n /** Whether phrase queries are supported. */\n phraseQueries: boolean;\n /** Whether prefix (`foo*`) queries are supported. */\n prefixQueries: boolean;\n /** Whether highlighting / snippets are supported. */\n highlighting: boolean;\n}>;\n\n// ============================================================\n// SQL Dialect & Capabilities\n// ============================================================\n\nimport { type SqlDialect } from \"../query/dialect/types\";\n\nexport type { SqlDialect } from \"../query/dialect/types\";\n\n/**\n * Backend capabilities that vary by dialect.\n */\nexport type BackendCapabilities = Readonly<{\n /** Whether the backend supports JSONB type (vs TEXT for JSON) */\n jsonb: boolean;\n /** Whether the backend supports partial indexes */\n partialIndexes: boolean;\n /** Whether the backend supports GIN indexes for JSON */\n ginIndexes: boolean;\n /** Whether the backend supports CTE (WITH) queries */\n cte: boolean;\n /** Whether the backend supports RETURNING clause */\n returning: boolean;\n /** Whether the backend supports atomic transactions (D1 does not) */\n transactions: boolean;\n /** Vector search capabilities (undefined if not configured) */\n vector?: VectorCapabilities | undefined;\n /** Fulltext search capabilities (undefined if not configured) */\n fulltext?: FulltextCapabilities | undefined;\n}>;\n\n// ============================================================\n// Row Types (Database Records)\n// ============================================================\n\n/**\n * A row from the typegraph_nodes table.\n */\nexport type NodeRow = Readonly<{\n graph_id: string;\n kind: string;\n id: string;\n props: string; // JSON string\n version: number;\n valid_from: string | undefined;\n valid_to: string | undefined;\n created_at: string;\n updated_at: string;\n deleted_at: string | undefined;\n}>;\n\n/**\n * A row from the typegraph_edges table.\n */\nexport type EdgeRow = Readonly<{\n graph_id: string;\n id: string;\n kind: string;\n from_kind: string;\n from_id: string;\n to_kind: string;\n to_id: string;\n props: string; // JSON string\n valid_from: string | undefined;\n valid_to: string | undefined;\n created_at: string;\n updated_at: string;\n deleted_at: string | undefined;\n}>;\n\n/**\n * A row from the typegraph_node_uniques table.\n */\nexport type UniqueRow = Readonly<{\n graph_id: string;\n node_kind: string;\n constraint_name: string;\n key: string;\n node_id: string;\n concrete_kind: string;\n deleted_at: string | undefined;\n}>;\n\n/**\n * A row from the typegraph_schema_versions table.\n */\nexport type SchemaVersionRow = Readonly<{\n graph_id: string;\n version: number;\n schema_hash: string;\n schema_doc: string; // JSON string\n created_at: string;\n is_active: boolean;\n}>;\n\n/**\n * A row from the typegraph_node_embeddings table.\n */\nexport type EmbeddingRow = Readonly<{\n graph_id: string;\n node_kind: string;\n node_id: string;\n field_path: string;\n embedding: readonly number[];\n dimensions: number;\n created_at: string;\n updated_at: string;\n}>;\n\n// ============================================================\n// Insert Parameters\n// ============================================================\n\n/**\n * Parameters for inserting a node.\n */\nexport type InsertNodeParams = Readonly<{\n graphId: string;\n kind: string;\n id: string;\n props: Readonly<Record<string, unknown>>;\n validFrom?: string;\n validTo?: string;\n}>;\n\n/**\n * Parameters for updating a node.\n */\nexport type UpdateNodeParams = Readonly<{\n graphId: string;\n kind: string;\n id: string;\n props: Readonly<Record<string, unknown>>;\n validTo?: string;\n incrementVersion?: boolean;\n /** If true, clears deleted_at (un-deletes the node). Used by upsert. */\n clearDeleted?: boolean;\n}>;\n\n/**\n * Parameters for deleting a node (soft delete).\n */\nexport type DeleteNodeParams = Readonly<{\n graphId: string;\n kind: string;\n id: string;\n}>;\n\n/**\n * Parameters for inserting an edge.\n */\nexport type InsertEdgeParams = Readonly<{\n graphId: string;\n id: string;\n kind: string;\n fromKind: string;\n fromId: string;\n toKind: string;\n toId: string;\n props: Readonly<Record<string, unknown>>;\n validFrom?: string;\n validTo?: string;\n}>;\n\n/**\n * Parameters for updating an edge.\n */\nexport type UpdateEdgeParams = Readonly<{\n graphId: string;\n id: string;\n props: Readonly<Record<string, unknown>>;\n validTo?: string;\n clearDeleted?: boolean;\n}>;\n\n/**\n * Parameters for deleting an edge (soft delete).\n */\nexport type DeleteEdgeParams = Readonly<{\n graphId: string;\n id: string;\n}>;\n\n/**\n * Parameters for hard deleting a node (permanent removal).\n */\nexport type HardDeleteNodeParams = Readonly<{\n graphId: string;\n kind: string;\n id: string;\n}>;\n\n/**\n * Parameters for hard deleting an edge (permanent removal).\n */\nexport type HardDeleteEdgeParams = Readonly<{\n graphId: string;\n id: string;\n}>;\n\n// ============================================================\n// Embedding Parameters\n// ============================================================\n\n/**\n * Parameters for inserting or updating an embedding.\n */\nexport type UpsertEmbeddingParams = Readonly<{\n graphId: string;\n nodeKind: string;\n nodeId: string;\n fieldPath: string;\n embedding: readonly number[];\n dimensions: number;\n}>;\n\n/**\n * Parameters for deleting an embedding.\n */\nexport type DeleteEmbeddingParams = Readonly<{\n graphId: string;\n nodeKind: string;\n nodeId: string;\n fieldPath: string;\n}>;\n\n/**\n * Parameters for vector similarity search.\n */\nexport type VectorSearchParams = Readonly<{\n graphId: string;\n nodeKind: string;\n fieldPath: string;\n queryEmbedding: readonly number[];\n metric: VectorMetric;\n limit: number;\n minScore?: number;\n}>;\n\n/**\n * Result from a vector similarity search.\n */\nexport type VectorSearchResult = Readonly<{\n nodeId: string;\n /**\n * Cosine metric returns similarity score (higher is better).\n * L2 and inner_product return raw distance (lower is better).\n */\n score: number;\n}>;\n\n/**\n * Parameters for creating a vector index.\n */\nexport type CreateVectorIndexParams = Readonly<{\n graphId: string;\n nodeKind: string;\n fieldPath: string;\n dimensions: number;\n metric: VectorMetric;\n indexType: VectorIndexType;\n /** Index-specific parameters */\n indexParams?: Readonly<{\n /** HNSW: max connections per layer */\n m?: number;\n /** HNSW: construction search depth */\n efConstruction?: number;\n /** IVFFlat: number of lists */\n lists?: number;\n }>;\n}>;\n\n/**\n * Parameters for dropping a vector index.\n */\nexport type DropVectorIndexParams = Readonly<{\n graphId: string;\n nodeKind: string;\n fieldPath: string;\n}>;\n\n// ============================================================\n// Fulltext Parameters\n// ============================================================\n\n/**\n * Parameters for inserting or updating a fulltext entry.\n *\n * One row per node. Callers concatenate the searchable fields into\n * `content` so a single MATCH query can find terms spread across fields.\n */\nexport type UpsertFulltextParams = Readonly<{\n graphId: string;\n nodeKind: string;\n nodeId: string;\n content: string;\n language: string;\n}>;\n\n/**\n * Parameters for deleting a single fulltext entry.\n */\nexport type DeleteFulltextParams = Readonly<{\n graphId: string;\n nodeKind: string;\n nodeId: string;\n}>;\n\n/**\n * A single row in a fulltext batch upsert.\n */\nexport type FulltextBatchRow = Readonly<{\n nodeId: string;\n content: string;\n language: string;\n}>;\n\n/**\n * Parameters for a batched fulltext upsert.\n *\n * Homogeneous: one graph, one node kind, many nodes. Duplicate `nodeId`\n * values within a single batch are deduplicated last-write-wins by the\n * builders before SQL generation — Postgres `ON CONFLICT` errors on\n * repeated conflict keys in one statement, and SQLite `DELETE + INSERT`\n * would create duplicate virtual-table rows otherwise.\n */\nexport type UpsertFulltextBatchParams = Readonly<{\n graphId: string;\n nodeKind: string;\n rows: readonly FulltextBatchRow[];\n}>;\n\n/**\n * Parameters for a batched fulltext delete.\n */\nexport type DeleteFulltextBatchParams = Readonly<{\n graphId: string;\n nodeKind: string;\n nodeIds: readonly string[];\n}>;\n\n/**\n * Parameters for fulltext search.\n */\nexport type FulltextSearchParams = Readonly<{\n graphId: string;\n nodeKind: string;\n /** The user-supplied query string. */\n query: string;\n /** How to parse `query`. Default: \"websearch\". */\n mode?: FulltextQueryMode;\n /**\n * Language override. Default: per-row language (as stored at insert time).\n * Postgres: passed as the regconfig to `to_tsquery` / `websearch_to_tsquery`.\n * SQLite: informational only (FTS5 tokenizer is fixed at table-create time).\n */\n language?: string;\n /** Max rows to return. */\n limit: number;\n /** Minimum rank to include (backend-dependent units). */\n minScore?: number;\n /** Whether to return a highlighted snippet per match. */\n includeSnippets?: boolean;\n}>;\n\n/**\n * Result from a fulltext search.\n *\n * Score semantics differ by backend; prefer `rank` (1-based) when fusing\n * with another source via RRF.\n */\nexport type FulltextSearchResult = Readonly<{\n nodeId: string;\n /**\n * Backend-native relevance score.\n * Postgres: `ts_rank_cd` (higher is better).\n * SQLite FTS5: negated `bm25()` (higher is better; FTS5 returns lower-is-better).\n */\n score: number;\n /** 1-based rank within the result set, suitable for RRF. */\n rank: number;\n /** Highlighted snippet of the content (if `includeSnippets` was set). */\n snippet?: string;\n}>;\n\n/**\n * Parameters for creating a fulltext index.\n *\n * The canonical index (Postgres GIN on `tsv`, SQLite FTS5 virtual table)\n * is created when the fulltext table itself is created. This is reserved\n * for advanced per-kind specializations.\n */\ntype CreateFulltextIndexParams = Readonly<{\n graphId: string;\n nodeKind: string;\n language: string;\n}>;\n\n/**\n * Parameters for dropping a fulltext index created via createFulltextIndex.\n */\ntype DropFulltextIndexParams = Readonly<{\n graphId: string;\n nodeKind: string;\n}>;\n\n// ============================================================\n// Query Types\n// ============================================================\n\n/**\n * Transaction options.\n */\nexport type TransactionOptions = Readonly<{\n /** Transaction isolation level (if supported) */\n isolationLevel?:\n | \"read_uncommitted\"\n | \"read_committed\"\n | \"repeatable_read\"\n | \"serializable\";\n}>;\n\n// ============================================================\n// Backend Interface\n// ============================================================\n\n/**\n * Transaction backend - a backend scoped to a transaction.\n */\nexport type TransactionBackend = Omit<\n GraphBackend,\n \"transaction\" | \"close\" | \"refreshStatistics\"\n>;\n\n/**\n * The GraphBackend interface abstracts database operations.\n *\n * Implementations should provide:\n * - SQLite backend via better-sqlite3 or libsql\n * - PostgreSQL backend via pg or postgres\n */\nexport type GraphBackend = Readonly<{\n /** The SQL dialect */\n dialect: SqlDialect;\n /** Backend capabilities */\n capabilities: BackendCapabilities;\n /** Table names used by this backend (for query schema auto-derivation) */\n tableNames?: SqlTableNames | undefined;\n /**\n * Optional fulltext strategy override. When present, both the compiler\n * (for `$fulltext.matches()` in query builder) and backend-direct\n * search paths use this instead of the dialect's default strategy —\n * allowing a Postgres backend to ship pg_trgm, ParadeDB, pgroonga etc.\n * When absent, the dialect's default strategy is used.\n */\n fulltextStrategy?: FulltextStrategy | undefined;\n\n // === Node Operations ===\n insertNode: (params: InsertNodeParams) => Promise<NodeRow>;\n insertNodeNoReturn?: (params: InsertNodeParams) => Promise<void>;\n insertNodesBatch?: (params: readonly InsertNodeParams[]) => Promise<void>;\n insertNodesBatchReturning?: (\n params: readonly InsertNodeParams[],\n ) => Promise<readonly NodeRow[]>;\n updateNode: (params: UpdateNodeParams) => Promise<NodeRow>;\n deleteNode: (params: DeleteNodeParams) => Promise<void>;\n hardDeleteNode: (params: HardDeleteNodeParams) => Promise<void>;\n getNode: (\n graphId: string,\n kind: string,\n id: string,\n ) => Promise<NodeRow | undefined>;\n getNodes?: (\n graphId: string,\n kind: string,\n ids: readonly string[],\n ) => Promise<readonly NodeRow[]>;\n\n // === Edge Operations ===\n insertEdge: (params: InsertEdgeParams) => Promise<EdgeRow>;\n insertEdgeNoReturn?: (params: InsertEdgeParams) => Promise<void>;\n insertEdgesBatch?: (params: readonly InsertEdgeParams[]) => Promise<void>;\n insertEdgesBatchReturning?: (\n params: readonly InsertEdgeParams[],\n ) => Promise<readonly EdgeRow[]>;\n updateEdge: (params: UpdateEdgeParams) => Promise<EdgeRow>;\n deleteEdge: (params: DeleteEdgeParams) => Promise<void>;\n hardDeleteEdge: (params: HardDeleteEdgeParams) => Promise<void>;\n getEdge: (graphId: string, id: string) => Promise<EdgeRow | undefined>;\n getEdges?: (\n graphId: string,\n ids: readonly string[],\n ) => Promise<readonly EdgeRow[]>;\n\n // === Edge Cardinality Operations ===\n countEdgesFrom: (params: CountEdgesFromParams) => Promise<number>;\n edgeExistsBetween: (params: EdgeExistsBetweenParams) => Promise<boolean>;\n\n // === Edge Query Operations ===\n findEdgesConnectedTo: (\n params: FindEdgesConnectedToParams,\n ) => Promise<readonly EdgeRow[]>;\n\n // === Collection Query Operations ===\n findNodesByKind: (\n params: FindNodesByKindParams,\n ) => Promise<readonly NodeRow[]>;\n countNodesByKind: (params: CountNodesByKindParams) => Promise<number>;\n findEdgesByKind: (\n params: FindEdgesByKindParams,\n ) => Promise<readonly EdgeRow[]>;\n countEdgesByKind: (params: CountEdgesByKindParams) => Promise<number>;\n\n // === Unique Constraint Operations ===\n insertUnique: (params: InsertUniqueParams) => Promise<void>;\n deleteUnique: (params: DeleteUniqueParams) => Promise<void>;\n checkUnique: (params: CheckUniqueParams) => Promise<UniqueRow | undefined>;\n checkUniqueBatch?: (\n params: CheckUniqueBatchParams,\n ) => Promise<readonly UniqueRow[]>;\n\n // === Schema Operations ===\n getActiveSchema: (graphId: string) => Promise<SchemaVersionRow | undefined>;\n getSchemaVersion: (\n graphId: string,\n version: number,\n ) => Promise<SchemaVersionRow | undefined>;\n insertSchema: (params: InsertSchemaParams) => Promise<SchemaVersionRow>;\n setActiveSchema: (graphId: string, version: number) => Promise<void>;\n\n // === Embedding Operations (optional - depends on vector capabilities) ===\n upsertEmbedding?: (params: UpsertEmbeddingParams) => Promise<void>;\n deleteEmbedding?: (params: DeleteEmbeddingParams) => Promise<void>;\n getEmbedding?: (\n graphId: string,\n nodeKind: string,\n nodeId: string,\n fieldPath: string,\n ) => Promise<EmbeddingRow | undefined>;\n vectorSearch?: (\n params: VectorSearchParams,\n ) => Promise<readonly VectorSearchResult[]>;\n createVectorIndex?: (params: CreateVectorIndexParams) => Promise<void>;\n dropVectorIndex?: (params: DropVectorIndexParams) => Promise<void>;\n\n // === Fulltext Operations (optional - depends on fulltext capabilities) ===\n upsertFulltext?: (params: UpsertFulltextParams) => Promise<void>;\n deleteFulltext?: (params: DeleteFulltextParams) => Promise<void>;\n /**\n * Batched variant of `upsertFulltext`. Optional — callers fall back to\n * per-row `upsertFulltext` when unset.\n */\n upsertFulltextBatch?: (params: UpsertFulltextBatchParams) => Promise<void>;\n /**\n * Batched variant of `deleteFulltext`. Optional — callers fall back to\n * per-row `deleteFulltext` when unset.\n */\n deleteFulltextBatch?: (params: DeleteFulltextBatchParams) => Promise<void>;\n fulltextSearch?: (\n params: FulltextSearchParams,\n ) => Promise<readonly FulltextSearchResult[]>;\n createFulltextIndex?: (params: CreateFulltextIndexParams) => Promise<void>;\n dropFulltextIndex?: (params: DropFulltextIndexParams) => Promise<void>;\n\n // === Graph Lifecycle ===\n /**\n * Hard-deletes all data for a graph (nodes, edges, uniques, embeddings, schema versions).\n * Intended for import-replacement workflows. No hooks, no per-row logic.\n */\n clearGraph: (graphId: string) => Promise<void>;\n\n /**\n * Creates the base TypeGraph tables if they don't already exist.\n *\n * Called automatically by `createStoreWithSchema()` when a fresh database\n * is detected. Users who manage DDL themselves via `createStore()` never\n * hit this path.\n */\n bootstrapTables?: () => Promise<void>;\n\n /**\n * Refreshes the backend's query-planner statistics.\n *\n * Call this once after a large initial import or bulk backfill. Without\n * up-to-date statistics, the planner can pick suboptimal execution plans\n * — on PostgreSQL this is the difference between a 0.5ms and a 5ms\n * forward traversal; on SQLite it's the difference between 0.9ms and\n * 23ms fulltext search. Autovacuum / background statistics collection\n * will catch up eventually, but calling this explicitly after a bulk\n * load gives you correct latencies immediately.\n *\n * Implementations:\n * - SQLite runs `ANALYZE`, which populates `sqlite_stat1`\n * - PostgreSQL runs `ANALYZE` on the TypeGraph-managed tables\n *\n * Safe to call at any time; costs a few tens of milliseconds on the\n * sizes this library is designed for.\n */\n refreshStatistics: () => Promise<void>;\n\n // === Query Execution ===\n execute: <T>(query: SQL) => Promise<readonly T[]>;\n\n /** Execute pre-compiled SQL text with bound parameters. Available on sync SQLite and pg backends. */\n executeRaw?: <T>(\n sqlText: string,\n params: readonly unknown[],\n ) => Promise<readonly T[]>;\n\n /** Compile a Drizzle SQL object to { sql, params } without executing. */\n compileSql?: (\n query: SQL,\n ) => Readonly<{ sql: string; params: readonly unknown[] }>;\n\n // === Transaction ===\n transaction: <T>(\n fn: (tx: TransactionBackend) => Promise<T>,\n options?: TransactionOptions,\n ) => Promise<T>;\n\n // === Lifecycle ===\n close: () => Promise<void>;\n}>;\n\n// ============================================================\n// Managed Backend Helper\n// ============================================================\n\n/**\n * Wraps a GraphBackend with idempotent close that also runs a teardown\n * callback (e.g. closing the underlying database connection).\n */\nexport function wrapWithManagedClose(\n backend: GraphBackend,\n teardown: () => void | Promise<void>,\n): GraphBackend {\n let isClosed = false;\n return {\n ...backend,\n async close(): Promise<void> {\n if (isClosed) return;\n isClosed = true;\n await backend.close();\n await teardown();\n },\n };\n}\n\n/**\n * Runs `fn` inside a transaction when the backend supports one, falling\n * through to a direct invocation otherwise. Lets call sites benefit from\n * atomicity on backends that have transactions while staying functional\n * on backends that don't (Cloudflare D1, `drizzle-orm/neon-http` over\n * HTTP). The single-statement race window is already implicit on any\n * backend that reports `transactions: false`; callers that cannot\n * tolerate it must branch on the capability themselves.\n *\n * Pass `fallback` only when the toplevel backend method would recurse\n * — for example, when implementing `backend.setActiveSchema` itself,\n * pass the operation-level backend so the no-tx path doesn't loop.\n */\nexport async function runOptionallyInTransaction<T>(\n backend: GraphBackend,\n fn: (target: GraphBackend | TransactionBackend) => Promise<T>,\n fallback?: GraphBackend | TransactionBackend,\n): Promise<T> {\n if (!backend.capabilities.transactions) {\n return fn(fallback ?? backend);\n }\n return backend.transaction((tx) => fn(tx));\n}\n\n// ============================================================\n// Additional Parameter Types\n// ============================================================\n\n/**\n * Parameters for inserting a unique constraint entry.\n */\nexport type InsertUniqueParams = Readonly<{\n graphId: string;\n nodeKind: string;\n constraintName: string;\n key: string;\n nodeId: string;\n concreteKind: string;\n}>;\n\n/**\n * Parameters for deleting a unique constraint entry.\n */\nexport type DeleteUniqueParams = Readonly<{\n graphId: string;\n nodeKind: string;\n constraintName: string;\n key: string;\n}>;\n\n/**\n * Parameters for checking a unique constraint.\n */\nexport type CheckUniqueParams = Readonly<{\n graphId: string;\n nodeKind: string;\n constraintName: string;\n key: string;\n /** If true, also returns soft-deleted entries. Used by get-or-create operations. */\n includeDeleted?: boolean;\n}>;\n\n/**\n * Parameters for batch-checking unique constraints.\n */\nexport type CheckUniqueBatchParams = Readonly<{\n graphId: string;\n nodeKind: string;\n constraintName: string;\n keys: readonly string[];\n /** If true, also returns soft-deleted entries. Used by get-or-create operations. */\n includeDeleted?: boolean;\n}>;\n\n/**\n * Parameters for inserting a schema version.\n */\nexport type InsertSchemaParams = Readonly<{\n graphId: string;\n version: number;\n schemaHash: string;\n schemaDoc: SerializedSchema;\n isActive: boolean;\n}>;\n\n/**\n * Parameters for counting edges from a source node.\n */\nexport type CountEdgesFromParams = Readonly<{\n graphId: string;\n edgeKind: string;\n fromKind: string;\n fromId: string;\n /** If true, only count edges where valid_to IS NULL */\n activeOnly?: boolean;\n}>;\n\n/**\n * Parameters for checking if an edge exists between two nodes.\n */\nexport type EdgeExistsBetweenParams = Readonly<{\n graphId: string;\n edgeKind: string;\n fromKind: string;\n fromId: string;\n toKind: string;\n toId: string;\n}>;\n\n/**\n * Parameters for finding edges connected to a node.\n */\nexport type FindEdgesConnectedToParams = Readonly<{\n graphId: string;\n nodeKind: string;\n nodeId: string;\n}>;\n\n/**\n * Parameters for finding nodes by kind.\n */\nexport type FindNodesByKindParams = Readonly<{\n graphId: string;\n kind: string;\n /** Max rows to return. */\n limit?: number;\n /** Offset. Present for backward compat; rebuild uses `after` instead. */\n offset?: number;\n /** If true, exclude deleted nodes. Default true. */\n excludeDeleted?: boolean;\n /** Temporal mode for filtering by validity period. */\n temporalMode?: TemporalMode;\n /** Timestamp for \"current\" and \"asOf\" temporal modes. */\n asOf?: string;\n /**\n * Stable ordering for keyset pagination. Default: \"created_at\" (existing\n * behavior). Rebuild should use \"id\" for iteration that is stable under\n * concurrent writes and shared timestamps.\n */\n orderBy?: \"id\" | \"created_at\";\n /**\n * Keyset cursor. Returns rows strictly greater (by `orderBy`) than this\n * value. When `orderBy: \"id\"`, compared lexicographically. Mutually\n * exclusive with `offset` — callers pick one.\n */\n after?: string;\n}>;\n\n/**\n * Parameters for counting nodes by kind.\n */\nexport type CountNodesByKindParams = Readonly<{\n graphId: string;\n kind: string;\n /** If true, exclude deleted nodes. Default true. */\n excludeDeleted?: boolean;\n /** Temporal mode for filtering by validity period. */\n temporalMode?: TemporalMode;\n /** Timestamp for \"current\" and \"asOf\" temporal modes. */\n asOf?: string;\n}>;\n\n/**\n * Parameters for finding edges by kind.\n */\nexport type FindEdgesByKindParams = Readonly<{\n graphId: string;\n kind: string;\n fromKind?: string;\n fromId?: string;\n toKind?: string;\n toId?: string;\n limit?: number;\n offset?: number;\n /** If true, exclude deleted edges. Default true. */\n excludeDeleted?: boolean;\n /** Temporal mode for filtering by validity period. */\n temporalMode?: TemporalMode;\n /** Timestamp for \"current\" and \"asOf\" temporal modes. */\n asOf?: string;\n}>;\n\n/**\n * Parameters for counting edges by kind.\n */\nexport type CountEdgesByKindParams = Readonly<{\n graphId: string;\n kind: string;\n fromKind?: string;\n fromId?: string;\n toKind?: string;\n toId?: string;\n /** If true, exclude deleted edges. Default true. */\n excludeDeleted?: boolean;\n /** Temporal mode for filtering by validity period. */\n temporalMode?: TemporalMode;\n /** Timestamp for \"current\" and \"asOf\" temporal modes. */\n asOf?: string;\n}>;\n\n// ============================================================\n// Default Capabilities\n// ============================================================\n\n/**\n * Default capabilities for SQLite.\n */\nexport const SQLITE_CAPABILITIES: BackendCapabilities = {\n jsonb: false, // SQLite uses TEXT with json functions\n partialIndexes: true, // SQLite supports WHERE in CREATE INDEX\n ginIndexes: false, // SQLite doesn't have GIN\n cte: true, // SQLite supports WITH\n returning: true, // SQLite 3.35+ supports RETURNING\n transactions: true, // SQLite supports transactions\n};\n\n/**\n * Default capabilities for PostgreSQL.\n */\nexport const POSTGRES_CAPABILITIES: BackendCapabilities = {\n jsonb: true, // PostgreSQL has native JSONB\n partialIndexes: true,\n ginIndexes: true,\n cte: true,\n returning: true,\n transactions: true, // PostgreSQL supports transactions\n};\n"]}
|
package/dist/chunk-LBORRUNJ.js
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { ValidationError, ConfigurationError } from './chunk-WFMTAEEN.js';
|
|
2
|
-
|
|
3
|
-
// src/core/types.ts
|
|
4
|
-
var NODE_TYPE_BRAND = "__nodeType";
|
|
5
|
-
var EDGE_TYPE_BRAND = "__edgeType";
|
|
6
|
-
function isNodeType(value) {
|
|
7
|
-
return typeof value === "object" && value !== null && NODE_TYPE_BRAND in value && value[NODE_TYPE_BRAND] === true;
|
|
8
|
-
}
|
|
9
|
-
function isEdgeType(value) {
|
|
10
|
-
return typeof value === "object" && value !== null && EDGE_TYPE_BRAND in value && value[EDGE_TYPE_BRAND] === true;
|
|
11
|
-
}
|
|
12
|
-
function isEdgeTypeWithEndpoints(value) {
|
|
13
|
-
return isEdgeType(value) && Array.isArray(value.from) && value.from.length > 0 && Array.isArray(value.to) && value.to.length > 0;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// src/core/define-graph.ts
|
|
17
|
-
var GRAPH_DEF_BRAND = "__graphDef";
|
|
18
|
-
function validateConstraintNarrowing(name, edgeType, registration) {
|
|
19
|
-
const builtInFromNames = new Set(edgeType.from.map((n) => n.kind));
|
|
20
|
-
for (const fromNode of registration.from) {
|
|
21
|
-
if (!builtInFromNames.has(fromNode.kind)) {
|
|
22
|
-
throw new ConfigurationError(
|
|
23
|
-
`Edge "${name}" registration has 'from' kind "${fromNode.kind}" not in edge's built-in domain: [${[...builtInFromNames].join(", ")}]`,
|
|
24
|
-
{
|
|
25
|
-
edgeName: name,
|
|
26
|
-
invalidFrom: fromNode.kind,
|
|
27
|
-
allowedFrom: [...builtInFromNames]
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
suggestion: `Edge registration can only narrow, not widen, the edge type's built-in constraints.`
|
|
31
|
-
}
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
const builtInToNames = new Set(edgeType.to.map((n) => n.kind));
|
|
36
|
-
for (const toNode of registration.to) {
|
|
37
|
-
if (!builtInToNames.has(toNode.kind)) {
|
|
38
|
-
throw new ConfigurationError(
|
|
39
|
-
`Edge "${name}" registration has 'to' kind "${toNode.kind}" not in edge's built-in range: [${[...builtInToNames].join(", ")}]`,
|
|
40
|
-
{
|
|
41
|
-
edgeName: name,
|
|
42
|
-
invalidTo: toNode.kind,
|
|
43
|
-
allowedTo: [...builtInToNames]
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
suggestion: `Edge registration can only narrow, not widen, the edge type's built-in constraints.`
|
|
47
|
-
}
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
function normalizeEdgeEntry(name, entry, allNodeTypes) {
|
|
53
|
-
if (isEdgeType(entry)) {
|
|
54
|
-
if (isEdgeTypeWithEndpoints(entry)) {
|
|
55
|
-
return { type: entry, from: entry.from, to: entry.to };
|
|
56
|
-
}
|
|
57
|
-
return { type: entry, from: allNodeTypes, to: allNodeTypes };
|
|
58
|
-
}
|
|
59
|
-
if (isEdgeTypeWithEndpoints(entry.type)) {
|
|
60
|
-
validateConstraintNarrowing(name, entry.type, entry);
|
|
61
|
-
}
|
|
62
|
-
return entry;
|
|
63
|
-
}
|
|
64
|
-
function normalizeEdges(edges, allNodeTypes) {
|
|
65
|
-
const result = {};
|
|
66
|
-
for (const [name, entry] of Object.entries(edges)) {
|
|
67
|
-
result[name] = normalizeEdgeEntry(name, entry, allNodeTypes);
|
|
68
|
-
}
|
|
69
|
-
return result;
|
|
70
|
-
}
|
|
71
|
-
function defineGraph(config) {
|
|
72
|
-
const defaults = {
|
|
73
|
-
onNodeDelete: config.defaults?.onNodeDelete ?? "restrict",
|
|
74
|
-
temporalMode: config.defaults?.temporalMode ?? "current"
|
|
75
|
-
};
|
|
76
|
-
const allNodeTypes = Object.values(config.nodes).map((reg) => reg.type);
|
|
77
|
-
const normalizedEdges = normalizeEdges(config.edges, allNodeTypes);
|
|
78
|
-
return Object.freeze({
|
|
79
|
-
[GRAPH_DEF_BRAND]: true,
|
|
80
|
-
id: config.id,
|
|
81
|
-
nodes: config.nodes,
|
|
82
|
-
edges: normalizedEdges,
|
|
83
|
-
ontology: config.ontology ?? [],
|
|
84
|
-
defaults
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
function isGraphDef(value) {
|
|
88
|
-
return typeof value === "object" && value !== null && GRAPH_DEF_BRAND in value && value[GRAPH_DEF_BRAND] === true;
|
|
89
|
-
}
|
|
90
|
-
function getNodeKinds(graph) {
|
|
91
|
-
return Object.keys(graph.nodes);
|
|
92
|
-
}
|
|
93
|
-
function getEdgeKinds(graph) {
|
|
94
|
-
return Object.keys(graph.edges);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// src/utils/date.ts
|
|
98
|
-
var ISO_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?Z$/;
|
|
99
|
-
function isValidIsoDate(value) {
|
|
100
|
-
if (!ISO_DATE_PATTERN.test(value)) {
|
|
101
|
-
return false;
|
|
102
|
-
}
|
|
103
|
-
const date = new Date(value);
|
|
104
|
-
return !Number.isNaN(date.getTime());
|
|
105
|
-
}
|
|
106
|
-
function validateIsoDate(value, fieldName) {
|
|
107
|
-
if (!isValidIsoDate(value)) {
|
|
108
|
-
throw new ValidationError(
|
|
109
|
-
`Invalid ISO 8601 datetime for "${fieldName}": "${value}". Expected format: YYYY-MM-DDTHH:mm:ss.sssZ`,
|
|
110
|
-
{
|
|
111
|
-
issues: [
|
|
112
|
-
{
|
|
113
|
-
path: fieldName,
|
|
114
|
-
message: `Invalid ISO 8601 datetime format. Expected: YYYY-MM-DDTHH:mm:ss.sssZ, got: "${value}"`
|
|
115
|
-
}
|
|
116
|
-
]
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
suggestion: `Use a valid ISO 8601 UTC datetime like "2024-01-15T10:30:00.000Z"`
|
|
120
|
-
}
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
return value;
|
|
124
|
-
}
|
|
125
|
-
function validateOptionalIsoDate(value, fieldName) {
|
|
126
|
-
if (value === void 0) return void 0;
|
|
127
|
-
return validateIsoDate(value, fieldName);
|
|
128
|
-
}
|
|
129
|
-
function nowIso() {
|
|
130
|
-
return (/* @__PURE__ */ new Date()).toISOString();
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export { EDGE_TYPE_BRAND, NODE_TYPE_BRAND, defineGraph, getEdgeKinds, getNodeKinds, isEdgeType, isEdgeTypeWithEndpoints, isGraphDef, isNodeType, nowIso, validateOptionalIsoDate };
|
|
134
|
-
//# sourceMappingURL=chunk-LBORRUNJ.js.map
|
|
135
|
-
//# sourceMappingURL=chunk-LBORRUNJ.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/types.ts","../src/core/define-graph.ts","../src/utils/date.ts"],"names":[],"mappings":"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","file":"chunk-LBORRUNJ.js","sourcesContent":["import { type z } from \"zod\";\n\n// ============================================================\n// Brand Keys for Nominal Typing\n// ============================================================\n\n/** Brand key for NodeType */\nexport const NODE_TYPE_BRAND = \"__nodeType\" as const;\n\n/** Brand key for EdgeType */\nexport const EDGE_TYPE_BRAND = \"__edgeType\" as const;\n\n/** Brand symbol for NodeId */\ndeclare const __nodeId: unique symbol;\n\n/** Brand symbol for EdgeId */\ndeclare const __edgeId: unique symbol;\n\n// ============================================================\n// Node Type\n// ============================================================\n\n/**\n * A node type definition.\n *\n * Created via `defineNode()`. Represents a type of node in the graph\n * with an associated Zod schema for properties.\n */\nexport type NodeType<\n K extends string = string,\n S extends z.ZodObject<z.ZodRawShape> = z.ZodObject<z.ZodRawShape>,\n> = Readonly<{\n [NODE_TYPE_BRAND]: true;\n kind: K;\n schema: S;\n description: string | undefined;\n}>;\n\n/**\n * Branded node ID type.\n *\n * Prevents mixing IDs from different node types at compile time.\n */\nexport type NodeId<N extends NodeType> = string &\n Readonly<{\n [__nodeId]: N;\n }>;\n\n/**\n * Infer the props type from a NodeType.\n */\nexport type NodeProps<N extends NodeType> = z.infer<N[\"schema\"]>;\n\n// ============================================================\n// Edge Type\n// ============================================================\n\n/**\n * An edge type definition.\n *\n * Created via `defineEdge()`. Represents a type of edge in the graph\n * with an optional Zod schema for properties.\n *\n * Optionally includes `from` and `to` arrays that define the allowed\n * source and target node types (domain and range constraints).\n */\nexport type EdgeType<\n K extends string = string,\n S extends z.ZodObject<z.ZodRawShape> = z.ZodObject<z.ZodRawShape>,\n From extends readonly NodeType[] | undefined = undefined,\n To extends readonly NodeType[] | undefined = undefined,\n> = Readonly<{\n [EDGE_TYPE_BRAND]: true;\n kind: K;\n schema: S;\n description: string | undefined;\n from: From;\n to: To;\n}>;\n\n/**\n * Base edge type for use in constraints - accepts any from/to configuration.\n */\nexport type AnyEdgeType = EdgeType<\n string,\n z.ZodObject<z.ZodRawShape>,\n readonly NodeType[] | undefined,\n readonly NodeType[] | undefined\n>;\n\n/**\n * An edge type that has both from and to constraints defined.\n * Can be used directly in defineGraph without an EdgeRegistration wrapper.\n */\nexport type EdgeTypeWithEndpoints = EdgeType<\n string,\n z.ZodObject<z.ZodRawShape>,\n readonly NodeType[],\n readonly NodeType[]\n>;\n\n/**\n * Branded edge ID type.\n *\n * Prevents mixing IDs from different edge types at compile time.\n */\nexport type EdgeId<E extends AnyEdgeType = AnyEdgeType> = string &\n Readonly<{\n [__edgeId]: E;\n }>;\n\n/**\n * Infer the props type from an EdgeType.\n */\nexport type EdgeProps<E extends AnyEdgeType> = z.infer<E[\"schema\"]>;\n\n// ============================================================\n// Configuration Types\n// ============================================================\n\n/**\n * Delete behaviors for nodes.\n */\nexport type DeleteBehavior = \"restrict\" | \"cascade\" | \"disconnect\";\n\n/**\n * Edge cardinality constraints.\n */\nexport type Cardinality =\n | \"many\" // No constraint (default)\n | \"one\" // At most one edge of this kind from any source node\n | \"unique\" // At most one edge of this kind between any (source, target) pair\n | \"oneActive\"; // At most one edge with valid_to IS NULL from any source\n\n/**\n * Endpoint existence modes for edge validation.\n */\nexport type EndpointExistence =\n | \"notDeleted\" // Endpoint deleted_at IS NULL (default)\n | \"currentlyValid\" // Endpoint not deleted AND temporally valid\n | \"ever\"; // Endpoint exists in any state\n\n/**\n * Temporal query modes.\n */\nexport type TemporalMode =\n | \"current\" // Valid now AND not deleted\n | \"asOf\" // Valid at specific date AND not deleted\n | \"includeEnded\" // All validity periods AND not deleted\n | \"includeTombstones\"; // Everything including soft-deleted\n\n/**\n * Uniqueness constraint scope.\n */\nexport type UniquenessScope =\n | \"kind\" // Unique within this exact kind only\n | \"kindWithSubClasses\"; // Unique across this kind and all subclasses\n\n/**\n * Collation for uniqueness constraints.\n */\nexport type Collation = \"binary\" | \"caseInsensitive\";\n\n// ============================================================\n// Uniqueness Constraint\n// ============================================================\n\n/**\n * Uniqueness constraint definition.\n */\nexport type UniqueConstraint<\n S extends z.ZodObject<z.ZodRawShape> = z.ZodObject<z.ZodRawShape>,\n> = Readonly<{\n name: string;\n fields: readonly (keyof z.infer<S> & string)[];\n where?: (\n props: UniqueConstraintPredicateBuilder<S>,\n ) => UniqueConstraintPredicate;\n scope: UniquenessScope;\n collation: Collation;\n}>;\n\n/**\n * Predicate builder for uniqueness constraint where clause.\n * Uses -? to make all fields required in the builder, even if optional in the schema.\n */\ntype UniqueConstraintPredicateBuilder<S extends z.ZodObject<z.ZodRawShape>> =\n Readonly<{\n [K in keyof z.infer<S>]-?: UniqueConstraintField;\n }>;\n\n/**\n * Field operations for uniqueness constraint predicates.\n */\ntype UniqueConstraintField = Readonly<{\n isNull: () => UniqueConstraintPredicate;\n isNotNull: () => UniqueConstraintPredicate;\n}>;\n\n/**\n * A uniqueness constraint predicate (internal representation).\n */\ntype UniqueConstraintPredicate = Readonly<{\n __type: \"unique_predicate\";\n field: string;\n op: \"isNull\" | \"isNotNull\";\n}>;\n\n// ============================================================\n// Node Registration\n// ============================================================\n\n/**\n * Node registration in a graph definition.\n */\nexport type NodeRegistration<N extends NodeType = NodeType> = Readonly<{\n type: N;\n unique?: readonly UniqueConstraint<N[\"schema\"]>[];\n onDelete?: DeleteBehavior;\n}>;\n\n// ============================================================\n// Edge Registration\n// ============================================================\n\n/**\n * Edge registration in a graph definition.\n */\nexport type EdgeRegistration<\n E extends AnyEdgeType = AnyEdgeType,\n FromTypes extends NodeType = NodeType,\n ToTypes extends NodeType = NodeType,\n> = Readonly<{\n type: E;\n from: readonly FromTypes[];\n to: readonly ToTypes[];\n cardinality?: Cardinality;\n endpointExistence?: EndpointExistence;\n}>;\n\n// ============================================================\n// Graph Defaults\n// ============================================================\n\n/**\n * Default settings for a graph.\n */\nexport type GraphDefaults = Readonly<{\n onNodeDelete?: DeleteBehavior;\n temporalMode?: TemporalMode;\n}>;\n\n// ============================================================\n// Type Helpers\n// ============================================================\n\n/**\n * Checks if a value is a NodeType.\n */\nexport function isNodeType(value: unknown): value is NodeType {\n return (\n typeof value === \"object\" &&\n value !== null &&\n NODE_TYPE_BRAND in value &&\n (value as Record<string, unknown>)[NODE_TYPE_BRAND] === true\n );\n}\n\n/**\n * Checks if a value is an EdgeType.\n */\nexport function isEdgeType(value: unknown): value is AnyEdgeType {\n return (\n typeof value === \"object\" &&\n value !== null &&\n EDGE_TYPE_BRAND in value &&\n (value as Record<string, unknown>)[EDGE_TYPE_BRAND] === true\n );\n}\n\n/**\n * Checks if a value is an EdgeType with both from and to constraints defined.\n * Such edges can be used directly in defineGraph without an EdgeRegistration wrapper.\n */\nexport function isEdgeTypeWithEndpoints(\n value: unknown,\n): value is EdgeTypeWithEndpoints {\n return (\n isEdgeType(value) &&\n Array.isArray(value.from) &&\n value.from.length > 0 &&\n Array.isArray(value.to) &&\n value.to.length > 0\n );\n}\n","import { ConfigurationError } from \"../errors/index\";\nimport { type OntologyRelation } from \"../ontology/types\";\nimport {\n type AnyEdgeType,\n type DeleteBehavior,\n type EdgeRegistration,\n type EdgeTypeWithEndpoints,\n type GraphDefaults,\n isEdgeType,\n isEdgeTypeWithEndpoints,\n type NodeRegistration,\n type NodeType,\n type TemporalMode,\n} from \"./types\";\n\n// ============================================================\n// Graph Definition Brand Symbol\n// ============================================================\n\n/** Brand key for GraphDef */\nconst GRAPH_DEF_BRAND = \"__graphDef\" as const;\n\n// ============================================================\n// Edge Entry Types\n// ============================================================\n\n/**\n * An edge entry in the graph definition.\n * Can be:\n * - EdgeType directly (constrained or unconstrained)\n * - EdgeRegistration object (always works, can override/narrow defaults)\n */\ntype EdgeEntry = EdgeRegistration | AnyEdgeType;\n\n/**\n * Normalized edge map type - all entries become EdgeRegistration.\n * For bare EdgeTypes, constrained endpoints are extracted from the type;\n * unconstrained edges fall back to all node types in the graph.\n */\ntype NormalizedEdges<\n TNodes extends Record<string, NodeRegistration>,\n TEdges extends Record<string, EdgeEntry>,\n> = {\n [K in keyof TEdges]: TEdges[K] extends EdgeRegistration ? TEdges[K]\n : TEdges[K] extends AnyEdgeType ?\n EdgeRegistration<\n TEdges[K],\n TEdges[K][\"from\"] extends readonly (infer N extends NodeType)[] ? N\n : TNodes[keyof TNodes][\"type\"],\n TEdges[K][\"to\"] extends readonly (infer N extends NodeType)[] ? N\n : TNodes[keyof TNodes][\"type\"]\n >\n : never;\n};\n\n// ============================================================\n// Edge Normalization Functions\n// ============================================================\n\n/**\n * Validates that an EdgeRegistration's constraints don't widen beyond\n * the edge type's built-in domain/range constraints.\n */\nfunction validateConstraintNarrowing(\n name: string,\n edgeType: EdgeTypeWithEndpoints,\n registration: EdgeRegistration,\n): void {\n const builtInFromNames = new Set(edgeType.from.map((n) => n.kind));\n for (const fromNode of registration.from) {\n if (!builtInFromNames.has(fromNode.kind)) {\n throw new ConfigurationError(\n `Edge \"${name}\" registration has 'from' kind \"${fromNode.kind}\" ` +\n `not in edge's built-in domain: [${[...builtInFromNames].join(\", \")}]`,\n {\n edgeName: name,\n invalidFrom: fromNode.kind,\n allowedFrom: [...builtInFromNames],\n },\n {\n suggestion: `Edge registration can only narrow, not widen, the edge type's built-in constraints.`,\n },\n );\n }\n }\n\n const builtInToNames = new Set(edgeType.to.map((n) => n.kind));\n for (const toNode of registration.to) {\n if (!builtInToNames.has(toNode.kind)) {\n throw new ConfigurationError(\n `Edge \"${name}\" registration has 'to' kind \"${toNode.kind}\" ` +\n `not in edge's built-in range: [${[...builtInToNames].join(\", \")}]`,\n {\n edgeName: name,\n invalidTo: toNode.kind,\n allowedTo: [...builtInToNames],\n },\n {\n suggestion: `Edge registration can only narrow, not widen, the edge type's built-in constraints.`,\n },\n );\n }\n }\n}\n\n/**\n * Normalizes a single edge entry to EdgeRegistration.\n */\nfunction normalizeEdgeEntry(\n name: string,\n entry: EdgeEntry,\n allNodeTypes: readonly NodeType[],\n): EdgeRegistration {\n if (isEdgeType(entry)) {\n if (isEdgeTypeWithEndpoints(entry)) {\n // EdgeType with from/to — convert to EdgeRegistration\n return { type: entry, from: entry.from, to: entry.to };\n }\n // Unconstrained EdgeType — allow any→any\n return { type: entry, from: allNodeTypes, to: allNodeTypes };\n }\n\n // Already EdgeRegistration — validate narrowing if edge has built-in constraints\n if (isEdgeTypeWithEndpoints(entry.type)) {\n validateConstraintNarrowing(name, entry.type, entry);\n }\n\n return entry;\n}\n\n/**\n * Normalizes all edge entries to EdgeRegistration.\n */\nfunction normalizeEdges(\n edges: Record<string, EdgeEntry>,\n allNodeTypes: readonly NodeType[],\n): Record<string, EdgeRegistration> {\n const result: Record<string, EdgeRegistration> = {};\n for (const [name, entry] of Object.entries(edges)) {\n result[name] = normalizeEdgeEntry(name, entry, allNodeTypes);\n }\n return result;\n}\n\n// ============================================================\n// Graph Definition Configuration\n// ============================================================\n\n/**\n * Configuration for defineGraph.\n */\ntype GraphDefConfig<\n TNodes extends Record<string, NodeRegistration>,\n TEdges extends Record<string, EdgeEntry>,\n TOntology extends readonly OntologyRelation[],\n> = Readonly<{\n /** Unique identifier for this graph */\n id: string;\n /** Node registrations */\n nodes: TNodes;\n /** Edge registrations or EdgeTypes with built-in domain/range */\n edges: TEdges;\n /** Ontology relations */\n ontology?: TOntology;\n /** Graph-wide defaults */\n defaults?: GraphDefaults;\n}>;\n\n// ============================================================\n// Graph Definition Type\n// ============================================================\n\n/**\n * A graph definition.\n *\n * This is a compile-time artifact that describes the structure of a graph.\n * Use `createStore()` to create a runtime store from this definition.\n */\nexport type GraphDef<\n TNodes extends Record<string, NodeRegistration> = Record<\n string,\n NodeRegistration\n >,\n TEdges extends Record<string, EdgeRegistration> = Record<\n string,\n EdgeRegistration\n >,\n TOntology extends readonly OntologyRelation[] = readonly OntologyRelation[],\n> = Readonly<{\n [GRAPH_DEF_BRAND]: true;\n id: string;\n nodes: TNodes;\n edges: TEdges;\n ontology: TOntology;\n defaults: Readonly<{\n onNodeDelete: DeleteBehavior;\n temporalMode: TemporalMode;\n }>;\n}>;\n\n// ============================================================\n// Type Helpers\n// ============================================================\n\n/**\n * Extract node kind names from a GraphDef.\n */\nexport type NodeKinds<G extends GraphDef> = keyof G[\"nodes\"] & string;\n\n/**\n * Extract edge kind names from a GraphDef.\n */\nexport type EdgeKinds<G extends GraphDef> = keyof G[\"edges\"] & string;\n\n/**\n * Get a NodeType from a GraphDef by kind name.\n */\nexport type GetNodeType<\n G extends GraphDef,\n K extends NodeKinds<G>,\n> = G[\"nodes\"][K][\"type\"];\n\n/**\n * Get an EdgeType from a GraphDef by kind name.\n */\nexport type GetEdgeType<\n G extends GraphDef,\n K extends EdgeKinds<G>,\n> = G[\"edges\"][K][\"type\"];\n\n/**\n * Get all NodeTypes from a GraphDef.\n */\nexport type AllNodeTypes<G extends GraphDef> = {\n [K in NodeKinds<G>]: G[\"nodes\"][K][\"type\"];\n}[NodeKinds<G>];\n\n/**\n * Get all EdgeTypes from a GraphDef.\n */\nexport type AllEdgeTypes<G extends GraphDef> = {\n [K in EdgeKinds<G>]: G[\"edges\"][K][\"type\"];\n}[EdgeKinds<G>];\n\n// ============================================================\n// Define Graph Function\n// ============================================================\n\n/**\n * Creates a graph definition.\n *\n * @example\n * ```typescript\n * const graph = defineGraph({\n * id: \"my_graph\",\n * nodes: {\n * Person: { type: Person },\n * Company: { type: Company },\n * },\n * edges: {\n * // Traditional EdgeRegistration syntax\n * worksAt: {\n * type: worksAt,\n * from: [Person],\n * to: [Company],\n * cardinality: \"many\",\n * },\n * // Or use EdgeType directly if it has from/to defined\n * knows, // EdgeType with built-in domain/range\n * },\n * ontology: [\n * subClassOf(Company, Organization),\n * disjointWith(Person, Organization),\n * ],\n * defaults: {\n * onNodeDelete: \"restrict\",\n * temporalMode: \"current\",\n * },\n * });\n * ```\n */\nexport function defineGraph<\n const TNodes extends Record<string, NodeRegistration<NodeType>>,\n const TEdges extends Record<string, EdgeEntry>,\n const TOntology extends readonly OntologyRelation[],\n>(\n config: GraphDefConfig<TNodes, TEdges, TOntology>,\n): GraphDef<TNodes, NormalizedEdges<TNodes, TEdges>, TOntology> {\n const defaults = {\n onNodeDelete: config.defaults?.onNodeDelete ?? \"restrict\",\n temporalMode: config.defaults?.temporalMode ?? \"current\",\n } as const;\n\n const allNodeTypes = Object.values(config.nodes).map((reg) => reg.type);\n const normalizedEdges = normalizeEdges(config.edges, allNodeTypes);\n\n return Object.freeze({\n [GRAPH_DEF_BRAND]: true as const,\n id: config.id,\n nodes: config.nodes,\n edges: normalizedEdges,\n ontology: config.ontology ?? ([] as unknown as TOntology),\n defaults,\n }) as GraphDef<TNodes, NormalizedEdges<TNodes, TEdges>, TOntology>;\n}\n\n// ============================================================\n// Graph Definition Utilities\n// ============================================================\n\n/**\n * Checks if a value is a GraphDef.\n */\nexport function isGraphDef(value: unknown): value is GraphDef {\n return (\n typeof value === \"object\" &&\n value !== null &&\n GRAPH_DEF_BRAND in value &&\n (value as Record<string, unknown>)[GRAPH_DEF_BRAND] === true\n );\n}\n\n/**\n * Gets all node kind names from a GraphDef.\n */\nexport function getNodeKinds<G extends GraphDef>(\n graph: G,\n): readonly (keyof G[\"nodes\"] & string)[] {\n return Object.keys(graph.nodes);\n}\n\n/**\n * Gets all edge kind names from a GraphDef.\n */\nexport function getEdgeKinds<G extends GraphDef>(\n graph: G,\n): readonly (keyof G[\"edges\"] & string)[] {\n return Object.keys(graph.edges);\n}\n","/**\n * Date encoding utilities for consistent storage.\n *\n * Contract: All dates are stored as ISO 8601 strings in UTC.\n * - Always includes milliseconds\n * - Always UTC (Z suffix)\n * - Sorts correctly as strings\n */\n\nimport { ValidationError } from \"../errors\";\n\n/**\n * ISO 8601 datetime pattern.\n * Matches formats like:\n * - 2024-01-15T10:30:00.000Z\n * - 2024-01-15T10:30:00Z\n * - 2024-01-15T10:30:00.123Z\n */\nconst ISO_DATE_PATTERN = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,3})?Z$/;\n\n/**\n * Checks if a string is a valid ISO 8601 datetime.\n *\n * @param value - String to validate\n * @returns True if valid ISO 8601 datetime\n */\nexport function isValidIsoDate(value: string): boolean {\n if (!ISO_DATE_PATTERN.test(value)) {\n return false;\n }\n // Also check that Date parsing produces a valid date\n const date = new Date(value);\n return !Number.isNaN(date.getTime());\n}\n\n/**\n * Validates that a string is a valid ISO 8601 datetime.\n * Throws ValidationError if invalid.\n *\n * @param value - String to validate\n * @param fieldName - Name of field for error message\n * @returns The validated string\n * @throws ValidationError if not a valid ISO datetime\n */\nexport function validateIsoDate(value: string, fieldName: string): string {\n if (!isValidIsoDate(value)) {\n throw new ValidationError(\n `Invalid ISO 8601 datetime for \"${fieldName}\": \"${value}\". ` +\n `Expected format: YYYY-MM-DDTHH:mm:ss.sssZ`,\n {\n issues: [\n {\n path: fieldName,\n message: `Invalid ISO 8601 datetime format. Expected: YYYY-MM-DDTHH:mm:ss.sssZ, got: \"${value}\"`,\n },\n ],\n },\n {\n suggestion: `Use a valid ISO 8601 UTC datetime like \"2024-01-15T10:30:00.000Z\"`,\n },\n );\n }\n return value;\n}\n\n/**\n * Validates an optional ISO date string.\n * Returns undefined if value is undefined, otherwise validates.\n */\nexport function validateOptionalIsoDate(\n value: string | undefined,\n fieldName: string,\n): string | undefined {\n if (value === undefined) return undefined;\n return validateIsoDate(value, fieldName);\n}\n\n/**\n * Encodes a Date to an ISO 8601 string for storage.\n */\nexport function encodeDate(date: Date): string {\n return date.toISOString();\n}\n\n/**\n * Decodes an ISO 8601 string to a Date.\n * Validates the string format first.\n *\n * @throws ValidationError if not a valid ISO datetime\n */\nexport function decodeDate(isoString: string): Date {\n validateIsoDate(isoString, \"date\");\n return new Date(isoString);\n}\n\n/**\n * Returns the current timestamp as an ISO string.\n */\nexport function nowIso(): string {\n return new Date().toISOString();\n}\n"]}
|