@nicia-ai/typegraph 0.3.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/backend/drizzle/index.cjs +6 -6
  2. package/dist/backend/drizzle/index.d.cts +1 -1
  3. package/dist/backend/drizzle/index.d.ts +1 -1
  4. package/dist/backend/drizzle/index.js +4 -4
  5. package/dist/backend/drizzle/postgres.cjs +4 -4
  6. package/dist/backend/drizzle/postgres.d.cts +1 -1
  7. package/dist/backend/drizzle/postgres.d.ts +1 -1
  8. package/dist/backend/drizzle/postgres.js +3 -3
  9. package/dist/backend/drizzle/sqlite.cjs +4 -4
  10. package/dist/backend/drizzle/sqlite.d.cts +1 -1
  11. package/dist/backend/drizzle/sqlite.d.ts +1 -1
  12. package/dist/backend/drizzle/sqlite.js +3 -3
  13. package/dist/backend/postgres/index.cjs +4 -4
  14. package/dist/backend/postgres/index.d.cts +1 -1
  15. package/dist/backend/postgres/index.d.ts +1 -1
  16. package/dist/backend/postgres/index.js +3 -3
  17. package/dist/backend/sqlite/index.cjs +6 -6
  18. package/dist/backend/sqlite/index.d.cts +1 -1
  19. package/dist/backend/sqlite/index.d.ts +1 -1
  20. package/dist/backend/sqlite/index.js +4 -4
  21. package/dist/{chunk-OYL2SGBD.cjs → chunk-44SXEVF4.cjs} +18 -2
  22. package/dist/chunk-44SXEVF4.cjs.map +1 -0
  23. package/dist/{chunk-F2BZSEFE.js → chunk-4MTYE6CF.js} +4 -4
  24. package/dist/{chunk-F2BZSEFE.js.map → chunk-4MTYE6CF.js.map} +1 -1
  25. package/dist/{chunk-4HARSV2G.js → chunk-6HFWKZU5.js} +61 -3
  26. package/dist/chunk-6HFWKZU5.js.map +1 -0
  27. package/dist/{chunk-F23W4W3A.cjs → chunk-ENXM4W4M.cjs} +18 -18
  28. package/dist/{chunk-F23W4W3A.cjs.map → chunk-ENXM4W4M.cjs.map} +1 -1
  29. package/dist/{chunk-ZJHQZZT2.cjs → chunk-K2ROKOK3.cjs} +6 -6
  30. package/dist/{chunk-ZJHQZZT2.cjs.map → chunk-K2ROKOK3.cjs.map} +1 -1
  31. package/dist/{chunk-46YY2FRV.js → chunk-KKFJJYCP.js} +3 -3
  32. package/dist/{chunk-46YY2FRV.js.map → chunk-KKFJJYCP.js.map} +1 -1
  33. package/dist/{chunk-CMHFS34N.cjs → chunk-KPU6TLUV.cjs} +16 -16
  34. package/dist/{chunk-CMHFS34N.cjs.map → chunk-KPU6TLUV.cjs.map} +1 -1
  35. package/dist/{chunk-DD6ONEBN.cjs → chunk-LDM2AFKZ.cjs} +12 -12
  36. package/dist/{chunk-DD6ONEBN.cjs.map → chunk-LDM2AFKZ.cjs.map} +1 -1
  37. package/dist/{chunk-NP4G4ZKM.js → chunk-M5SOQ7UV.js} +4 -4
  38. package/dist/{chunk-NP4G4ZKM.js.map → chunk-M5SOQ7UV.js.map} +1 -1
  39. package/dist/{chunk-SFY2PPOY.cjs → chunk-PW5BSBZV.cjs} +68 -10
  40. package/dist/chunk-PW5BSBZV.cjs.map +1 -0
  41. package/dist/{chunk-O5XPCJLF.js → chunk-SJ2QMDXY.js} +18 -3
  42. package/dist/chunk-SJ2QMDXY.js.map +1 -0
  43. package/dist/{chunk-XDTYTNYL.js → chunk-TGDFBLGS.js} +3 -3
  44. package/dist/{chunk-XDTYTNYL.js.map → chunk-TGDFBLGS.js.map} +1 -1
  45. package/dist/{index-Dkicw49A.d.ts → index-DyrR_d-H.d.cts} +9 -1
  46. package/dist/{index-Dkicw49A.d.cts → index-DyrR_d-H.d.ts} +9 -1
  47. package/dist/index.cjs +1130 -218
  48. package/dist/index.cjs.map +1 -1
  49. package/dist/index.d.cts +7 -7
  50. package/dist/index.d.ts +7 -7
  51. package/dist/index.js +924 -16
  52. package/dist/index.js.map +1 -1
  53. package/dist/interchange/index.cjs +7 -7
  54. package/dist/interchange/index.d.cts +3 -3
  55. package/dist/interchange/index.d.ts +3 -3
  56. package/dist/interchange/index.js +2 -2
  57. package/dist/{manager-e9LXthrx.d.ts → manager-DXC7CqKG.d.ts} +1 -1
  58. package/dist/{manager-Jc5Btay9.d.cts → manager-DiPf-0GG.d.cts} +1 -1
  59. package/dist/profiler/index.d.cts +3 -3
  60. package/dist/profiler/index.d.ts +3 -3
  61. package/dist/schema/index.cjs +22 -22
  62. package/dist/schema/index.d.cts +5 -5
  63. package/dist/schema/index.d.ts +5 -5
  64. package/dist/schema/index.js +4 -4
  65. package/dist/{store-DM3Tk3Pw.d.ts → store-DODIWZxC.d.ts} +145 -7
  66. package/dist/{store-nbBybLWP.d.cts → store-nDW3GOFb.d.cts} +145 -7
  67. package/dist/{types-Cdbi4hcx.d.ts → types-DpIoePMI.d.ts} +19 -0
  68. package/dist/{types-DDP0MGBF.d.cts → types-WX8V9dqn.d.cts} +19 -0
  69. package/package.json +2 -2
  70. package/dist/chunk-4HARSV2G.js.map +0 -1
  71. package/dist/chunk-O5XPCJLF.js.map +0 -1
  72. package/dist/chunk-OYL2SGBD.cjs.map +0 -1
  73. package/dist/chunk-SFY2PPOY.cjs.map +0 -1
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
- import { META_EDGE_BRAND, META_EDGE_SUB_CLASS_OF, META_EDGE_NARROWER, META_EDGE_BROADER, META_EDGE_RELATED_TO, META_EDGE_EQUIVALENT_TO, META_EDGE_SAME_AS, META_EDGE_DIFFERENT_FROM, META_EDGE_DISJOINT_WITH, META_EDGE_HAS_PART, META_EDGE_PART_OF, META_EDGE_INVERSE_OF, META_EDGE_IMPLIES, ensureSchema, computeClosuresFromOntology, createEmptyClosures, KindRegistry, validateNodeProps, validateEdgeProps } from './chunk-NP4G4ZKM.js';
2
- export { isMetaEdge } from './chunk-NP4G4ZKM.js';
3
- import { NODE_TYPE_BRAND, EDGE_TYPE_BRAND, nowIso, validateOptionalIsoDate, getNodeKinds, getEdgeKinds } from './chunk-XDTYTNYL.js';
4
- export { defineGraph, getEdgeKinds, getNodeKinds, isEdgeType, isEdgeTypeWithEndpoints, isGraphDef, isNodeType } from './chunk-XDTYTNYL.js';
5
- import { ConfigurationError, UnsupportedPredicateError, ValidationError, CompilerInvariantError, KindNotFoundError, RestrictedDeleteError, NodeNotFoundError, DatabaseOperationError, EdgeNotFoundError, UniquenessError, EndpointNotFoundError, EndpointError, DisjointError, CardinalityError } from './chunk-O5XPCJLF.js';
6
- export { CardinalityError, CompilerInvariantError, ConfigurationError, DatabaseOperationError, DisjointError, EdgeNotFoundError, EndpointError, EndpointNotFoundError, KindNotFoundError, MigrationError, NodeNotFoundError, RestrictedDeleteError, SchemaMismatchError, TypeGraphError, UniquenessError, UnsupportedPredicateError, ValidationError, VersionConflictError, getErrorSuggestion, isConstraintError, isSystemError, isTypeGraphError, isUserRecoverable } from './chunk-O5XPCJLF.js';
1
+ import { META_EDGE_BRAND, META_EDGE_SUB_CLASS_OF, META_EDGE_NARROWER, META_EDGE_BROADER, META_EDGE_RELATED_TO, META_EDGE_EQUIVALENT_TO, META_EDGE_SAME_AS, META_EDGE_DIFFERENT_FROM, META_EDGE_DISJOINT_WITH, META_EDGE_HAS_PART, META_EDGE_PART_OF, META_EDGE_INVERSE_OF, META_EDGE_IMPLIES, ensureSchema, computeClosuresFromOntology, createEmptyClosures, KindRegistry, validateNodeProps, validateEdgeProps } from './chunk-M5SOQ7UV.js';
2
+ export { isMetaEdge } from './chunk-M5SOQ7UV.js';
3
+ import { NODE_TYPE_BRAND, EDGE_TYPE_BRAND, nowIso, validateOptionalIsoDate, getNodeKinds, getEdgeKinds } from './chunk-TGDFBLGS.js';
4
+ export { defineGraph, getEdgeKinds, getNodeKinds, isEdgeType, isEdgeTypeWithEndpoints, isGraphDef, isNodeType } from './chunk-TGDFBLGS.js';
5
+ import { ConfigurationError, UnsupportedPredicateError, ValidationError, CompilerInvariantError, KindNotFoundError, RestrictedDeleteError, NodeNotFoundError, DatabaseOperationError, EdgeNotFoundError, NodeConstraintNotFoundError, UniquenessError, EndpointNotFoundError, CardinalityError, EndpointError, DisjointError } from './chunk-SJ2QMDXY.js';
6
+ export { CardinalityError, CompilerInvariantError, ConfigurationError, DatabaseOperationError, DisjointError, EdgeNotFoundError, EndpointError, EndpointNotFoundError, KindNotFoundError, MigrationError, NodeConstraintNotFoundError, NodeNotFoundError, RestrictedDeleteError, SchemaMismatchError, TypeGraphError, UniquenessError, UnsupportedPredicateError, ValidationError, VersionConflictError, getErrorSuggestion, isConstraintError, isSystemError, isTypeGraphError, isUserRecoverable } from './chunk-SJ2QMDXY.js';
7
7
  import { getDialect, NODE_META_KEYS, EDGE_META_KEYS } from './chunk-54WJF3DW.js';
8
8
  import { jsonPointer, parseJsonPointer, createSchemaIntrospector, normalizeJsonPointer, joinJsonPointers, resolveFieldTypeInfoAtJsonPointer, getEmbeddingDimensions, isEmbeddingSchema } from './chunk-K7SQ3SWP.js';
9
9
  export { MAX_JSON_POINTER_DEPTH, embedding, getEmbeddingDimensions, isEmbeddingSchema, joinJsonPointers, jsonPointer, normalizeJsonPointer, parseJsonPointer } from './chunk-K7SQ3SWP.js';
@@ -8452,7 +8452,7 @@ function createEdgeCollection(config) {
8452
8452
  const results = await executeEdgeCreateBatch2(batchInputs, backend);
8453
8453
  return narrowEdges(results);
8454
8454
  },
8455
- async bulkUpsert(items) {
8455
+ async bulkUpsertById(items) {
8456
8456
  if (items.length === 0) return [];
8457
8457
  const upsertAll = async (target) => {
8458
8458
  const ids = items.map((item) => item.id);
@@ -8478,7 +8478,7 @@ function createEdgeCollection(config) {
8478
8478
  if (existing) {
8479
8479
  const input = {
8480
8480
  id: item.id,
8481
- props: item.props ?? {}
8481
+ props: item.props
8482
8482
  };
8483
8483
  if (item.validTo !== void 0) input.validTo = item.validTo;
8484
8484
  toUpdate.push({
@@ -8494,7 +8494,7 @@ function createEdgeCollection(config) {
8494
8494
  fromId: item.from.id,
8495
8495
  toKind: item.to.kind,
8496
8496
  toId: item.to.id,
8497
- props: item.props ?? {}
8497
+ props: item.props
8498
8498
  };
8499
8499
  if (item.validFrom !== void 0) input.validFrom = item.validFrom;
8500
8500
  if (item.validTo !== void 0) input.validTo = item.validTo;
@@ -8548,6 +8548,74 @@ function createEdgeCollection(config) {
8548
8548
  return;
8549
8549
  }
8550
8550
  await deleteAll(backend);
8551
+ },
8552
+ async findByEndpoints(from, to, options) {
8553
+ const findOptions = {};
8554
+ if (options?.matchOn !== void 0)
8555
+ findOptions.matchOn = options.matchOn;
8556
+ if (options?.props !== void 0)
8557
+ findOptions.props = options.props;
8558
+ const result = await config.executeFindByEndpoints(
8559
+ kind,
8560
+ from.kind,
8561
+ from.id,
8562
+ to.kind,
8563
+ to.id,
8564
+ backend,
8565
+ findOptions
8566
+ );
8567
+ return result === void 0 ? void 0 : narrowEdge(result);
8568
+ },
8569
+ async getOrCreateByEndpoints(from, to, props, options) {
8570
+ const getOrCreateOptions = {};
8571
+ if (options?.matchOn !== void 0)
8572
+ getOrCreateOptions.matchOn = options.matchOn;
8573
+ if (options?.ifExists !== void 0)
8574
+ getOrCreateOptions.ifExists = options.ifExists;
8575
+ const result = await config.executeGetOrCreateByEndpoints(
8576
+ kind,
8577
+ from.kind,
8578
+ from.id,
8579
+ to.kind,
8580
+ to.id,
8581
+ props,
8582
+ backend,
8583
+ getOrCreateOptions
8584
+ );
8585
+ return { edge: narrowEdge(result.edge), action: result.action };
8586
+ },
8587
+ async bulkGetOrCreateByEndpoints(items, options) {
8588
+ if (items.length === 0) return [];
8589
+ const mappedItems = items.map((item) => ({
8590
+ fromKind: item.from.kind,
8591
+ fromId: item.from.id,
8592
+ toKind: item.to.kind,
8593
+ toId: item.to.id,
8594
+ props: item.props
8595
+ }));
8596
+ const getOrCreateOptions = {};
8597
+ if (options?.matchOn !== void 0)
8598
+ getOrCreateOptions.matchOn = options.matchOn;
8599
+ if (options?.ifExists !== void 0)
8600
+ getOrCreateOptions.ifExists = options.ifExists;
8601
+ const getOrCreateAll = async (target) => {
8602
+ const results = await config.executeBulkGetOrCreateByEndpoints(
8603
+ kind,
8604
+ mappedItems,
8605
+ target,
8606
+ getOrCreateOptions
8607
+ );
8608
+ return results.map((result) => ({
8609
+ edge: narrowEdge(result.edge),
8610
+ action: result.action
8611
+ }));
8612
+ };
8613
+ if (backend.capabilities.transactions && "transaction" in backend) {
8614
+ return backend.transaction(
8615
+ async (txBackend) => getOrCreateAll(txBackend)
8616
+ );
8617
+ }
8618
+ return getOrCreateAll(backend);
8551
8619
  }
8552
8620
  };
8553
8621
  }
@@ -8586,7 +8654,11 @@ function createNodeCollection(config) {
8586
8654
  executeDelete: executeNodeDelete2,
8587
8655
  executeHardDelete: executeNodeHardDelete2,
8588
8656
  matchesTemporalMode,
8589
- createQuery
8657
+ createQuery,
8658
+ executeGetOrCreateByConstraint,
8659
+ executeBulkGetOrCreateByConstraint,
8660
+ executeFindByConstraint,
8661
+ executeBulkFindByConstraint
8590
8662
  } = config;
8591
8663
  return {
8592
8664
  async create(props, options) {
@@ -8696,7 +8768,7 @@ function createNodeCollection(config) {
8696
8768
  }
8697
8769
  return backend.countNodesByKind(params);
8698
8770
  },
8699
- async upsert(id, props, options) {
8771
+ async upsertById(id, props, options) {
8700
8772
  const existing = await backend.getNode(graphId, kind, id);
8701
8773
  if (existing) {
8702
8774
  const input = {
@@ -8737,7 +8809,7 @@ function createNodeCollection(config) {
8737
8809
  const results = await executeNodeCreateBatch2(batchInputs, backend);
8738
8810
  return narrowNodes(results);
8739
8811
  },
8740
- async bulkUpsert(items) {
8812
+ async bulkUpsertById(items) {
8741
8813
  if (items.length === 0) return [];
8742
8814
  const upsertAll = async (target) => {
8743
8815
  const ids = items.map((item) => item.id);
@@ -8834,6 +8906,68 @@ function createNodeCollection(config) {
8834
8906
  return;
8835
8907
  }
8836
8908
  await deleteAll(backend);
8909
+ },
8910
+ async findByConstraint(constraintName, props) {
8911
+ const result = await executeFindByConstraint(
8912
+ kind,
8913
+ constraintName,
8914
+ props,
8915
+ backend
8916
+ );
8917
+ return result === void 0 ? void 0 : narrowNode(result);
8918
+ },
8919
+ async bulkFindByConstraint(constraintName, items) {
8920
+ if (items.length === 0) return [];
8921
+ const mappedItems = items.map((item) => ({
8922
+ props: item.props
8923
+ }));
8924
+ const results = await executeBulkFindByConstraint(
8925
+ kind,
8926
+ constraintName,
8927
+ mappedItems,
8928
+ backend
8929
+ );
8930
+ return results.map(
8931
+ (result) => result === void 0 ? void 0 : narrowNode(result)
8932
+ );
8933
+ },
8934
+ async getOrCreateByConstraint(constraintName, props, options) {
8935
+ const execute = async (target) => {
8936
+ const result = await executeGetOrCreateByConstraint(
8937
+ kind,
8938
+ constraintName,
8939
+ props,
8940
+ target,
8941
+ options
8942
+ );
8943
+ return result;
8944
+ };
8945
+ if (backend.capabilities.transactions && "transaction" in backend) {
8946
+ return backend.transaction(async (txBackend) => execute(txBackend));
8947
+ }
8948
+ return execute(backend);
8949
+ },
8950
+ async bulkGetOrCreateByConstraint(constraintName, items, options) {
8951
+ if (items.length === 0) return [];
8952
+ const mappedItems = items.map((item) => ({
8953
+ props: item.props
8954
+ }));
8955
+ const getOrCreateAll = async (target) => {
8956
+ const results = await executeBulkGetOrCreateByConstraint(
8957
+ kind,
8958
+ constraintName,
8959
+ mappedItems,
8960
+ target,
8961
+ options
8962
+ );
8963
+ return results;
8964
+ };
8965
+ if (backend.capabilities.transactions && "transaction" in backend) {
8966
+ return backend.transaction(
8967
+ async (txBackend) => getOrCreateAll(txBackend)
8968
+ );
8969
+ }
8970
+ return getOrCreateAll(backend);
8837
8971
  }
8838
8972
  };
8839
8973
  }
@@ -8891,16 +9025,18 @@ function createEdgeCollectionsProxy(graph, graphId, registry, backend, operation
8891
9025
  }
8892
9026
 
8893
9027
  // src/constraints/index.ts
9028
+ var UNIQUE_KEY_SEPARATOR = "";
9029
+ var UNIQUE_KEY_NULL_MARKER = "";
8894
9030
  function computeUniqueKey(props, fields, collation) {
8895
9031
  const values = fields.map((field2) => {
8896
9032
  const value = props[field2];
8897
9033
  if (value === void 0 || value === null) {
8898
- return "\0";
9034
+ return UNIQUE_KEY_NULL_MARKER;
8899
9035
  }
8900
9036
  const stringValue = typeof value === "string" ? value : typeof value === "number" || typeof value === "boolean" ? value.toString() : JSON.stringify(value);
8901
9037
  return collation === "caseInsensitive" ? stringValue.toLowerCase() : stringValue;
8902
9038
  });
8903
- return values.join("\0");
9039
+ return values.join(UNIQUE_KEY_SEPARATOR);
8904
9040
  }
8905
9041
  function checkWherePredicate(constraint, props) {
8906
9042
  if (!constraint.where) {
@@ -9577,6 +9713,343 @@ async function executeEdgeHardDelete(ctx, id, backend) {
9577
9713
  });
9578
9714
  });
9579
9715
  }
9716
+ var RECORD_SEP = "";
9717
+ var UNIT_SEP = "";
9718
+ var UNDEFINED_SENTINEL = "";
9719
+ function validateMatchOnFields(schema, matchOn, edgeKind) {
9720
+ if (matchOn.length === 0) return;
9721
+ const shape = schema.shape;
9722
+ if (shape === void 0) {
9723
+ throw new ValidationError(
9724
+ `Edge kind "${edgeKind}" has no schema shape to validate matchOn fields against`,
9725
+ {
9726
+ kind: edgeKind,
9727
+ operation: "create",
9728
+ issues: matchOn.map((field2) => ({
9729
+ path: field2,
9730
+ message: `Field "${field2}" does not exist in edge schema`
9731
+ }))
9732
+ }
9733
+ );
9734
+ }
9735
+ const invalidFields = matchOn.filter((field2) => !(field2 in shape));
9736
+ if (invalidFields.length > 0) {
9737
+ throw new ValidationError(
9738
+ `Invalid matchOn fields for edge kind "${edgeKind}": ${invalidFields.join(", ")}`,
9739
+ {
9740
+ kind: edgeKind,
9741
+ operation: "create",
9742
+ issues: invalidFields.map((field2) => ({
9743
+ path: field2,
9744
+ message: `Field "${field2}" does not exist in edge schema`
9745
+ }))
9746
+ }
9747
+ );
9748
+ }
9749
+ }
9750
+ function stableStringify(value) {
9751
+ if (value === void 0) return UNDEFINED_SENTINEL;
9752
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
9753
+ if (Array.isArray(value)) {
9754
+ return `[${value.map((item) => stableStringify(item)).join(",")}]`;
9755
+ }
9756
+ const sorted = Object.keys(value).toSorted();
9757
+ const entries = sorted.map(
9758
+ (key) => `${JSON.stringify(key)}:${stableStringify(value[key])}`
9759
+ );
9760
+ return `{${entries.join(",")}}`;
9761
+ }
9762
+ function buildEdgeCompositeKey(fromKind, fromId, toKind, toId, props, matchOn) {
9763
+ const endpointPart = `${fromKind}${RECORD_SEP}${fromId}${RECORD_SEP}${toKind}${RECORD_SEP}${toId}`;
9764
+ if (matchOn.length === 0) return endpointPart;
9765
+ const sortedFields = [...matchOn].toSorted();
9766
+ const propertyParts = sortedFields.map(
9767
+ (field2) => `${RECORD_SEP}${field2}${UNIT_SEP}${stableStringify(props[field2])}`
9768
+ );
9769
+ return endpointPart + propertyParts.join("");
9770
+ }
9771
+ function buildEndpointPairKey(fromKind, fromId, toKind, toId) {
9772
+ return `${fromKind}${RECORD_SEP}${fromId}${RECORD_SEP}${toKind}${RECORD_SEP}${toId}`;
9773
+ }
9774
+ function findMatchingEdge(rows, matchOn, inputProps) {
9775
+ let liveRow;
9776
+ let deletedRow;
9777
+ for (const row of rows) {
9778
+ if (matchOn.length > 0) {
9779
+ const rowProps = JSON.parse(row.props);
9780
+ const matches = matchOn.every(
9781
+ (field2) => stableStringify(rowProps[field2]) === stableStringify(inputProps[field2])
9782
+ );
9783
+ if (!matches) continue;
9784
+ }
9785
+ if (row.deleted_at === void 0) {
9786
+ liveRow ??= row;
9787
+ } else {
9788
+ deletedRow ??= row;
9789
+ }
9790
+ if (liveRow !== void 0) break;
9791
+ }
9792
+ return { liveRow, deletedRow };
9793
+ }
9794
+ async function executeEdgeFindByEndpoints(ctx, kind, fromKind, fromId, toKind, toId, backend, options) {
9795
+ const matchOn = options?.matchOn ?? [];
9796
+ const props = options?.props ?? {};
9797
+ const registration = getEdgeRegistration(ctx.graph, kind);
9798
+ const edgeKind = registration.type;
9799
+ if (matchOn.length > 0) {
9800
+ validateMatchOnFields(edgeKind.schema, matchOn, kind);
9801
+ }
9802
+ const candidateRows = await backend.findEdgesByKind({
9803
+ graphId: ctx.graphId,
9804
+ kind,
9805
+ fromKind,
9806
+ fromId,
9807
+ toKind,
9808
+ toId,
9809
+ excludeDeleted: true
9810
+ });
9811
+ if (candidateRows.length === 0) return void 0;
9812
+ if (matchOn.length === 0) return rowToEdge(candidateRows[0]);
9813
+ const { liveRow } = findMatchingEdge(candidateRows, matchOn, props);
9814
+ return liveRow === void 0 ? void 0 : rowToEdge(liveRow);
9815
+ }
9816
+ async function executeEdgeGetOrCreateByEndpoints(ctx, kind, fromKind, fromId, toKind, toId, props, backend, options) {
9817
+ const ifExists = options?.ifExists ?? "return";
9818
+ const matchOn = options?.matchOn ?? [];
9819
+ const registration = getEdgeRegistration(ctx.graph, kind);
9820
+ const edgeKind = registration.type;
9821
+ const validatedProps = validateEdgeProps(edgeKind.schema, props, {
9822
+ kind,
9823
+ operation: "create"
9824
+ });
9825
+ validateMatchOnFields(edgeKind.schema, matchOn, kind);
9826
+ const candidateRows = await backend.findEdgesByKind({
9827
+ graphId: ctx.graphId,
9828
+ kind,
9829
+ fromKind,
9830
+ fromId,
9831
+ toKind,
9832
+ toId,
9833
+ excludeDeleted: false,
9834
+ temporalMode: "includeTombstones"
9835
+ });
9836
+ const { liveRow, deletedRow } = findMatchingEdge(
9837
+ candidateRows,
9838
+ matchOn,
9839
+ validatedProps
9840
+ );
9841
+ if (liveRow === void 0 && deletedRow === void 0) {
9842
+ const input = {
9843
+ kind,
9844
+ fromKind,
9845
+ fromId,
9846
+ toKind,
9847
+ toId,
9848
+ props: validatedProps
9849
+ };
9850
+ const edge2 = await executeEdgeCreate(ctx, input, backend);
9851
+ return { edge: edge2, action: "created" };
9852
+ }
9853
+ if (liveRow !== void 0) {
9854
+ if (ifExists === "return") {
9855
+ return { edge: rowToEdge(liveRow), action: "found" };
9856
+ }
9857
+ const edge2 = await executeEdgeUpsertUpdate(
9858
+ ctx,
9859
+ { id: liveRow.id, props: validatedProps },
9860
+ backend
9861
+ );
9862
+ return { edge: edge2, action: "updated" };
9863
+ }
9864
+ const cardinality = registration.cardinality ?? "many";
9865
+ const matchedDeletedRow = deletedRow;
9866
+ const effectiveValidTo = matchedDeletedRow.valid_to;
9867
+ const constraintContext = {
9868
+ graphId: ctx.graphId,
9869
+ registry: ctx.registry,
9870
+ backend
9871
+ };
9872
+ await checkCardinalityConstraint(
9873
+ constraintContext,
9874
+ kind,
9875
+ cardinality,
9876
+ fromKind,
9877
+ fromId,
9878
+ toKind,
9879
+ toId,
9880
+ effectiveValidTo
9881
+ );
9882
+ const edge = await executeEdgeUpsertUpdate(
9883
+ ctx,
9884
+ { id: matchedDeletedRow.id, props: validatedProps },
9885
+ backend,
9886
+ { clearDeleted: true }
9887
+ );
9888
+ return { edge, action: "resurrected" };
9889
+ }
9890
+ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend, options) {
9891
+ if (items.length === 0) return [];
9892
+ const ifExists = options?.ifExists ?? "return";
9893
+ const matchOn = options?.matchOn ?? [];
9894
+ const registration = getEdgeRegistration(ctx.graph, kind);
9895
+ const edgeKind = registration.type;
9896
+ const cardinality = registration.cardinality ?? "many";
9897
+ validateMatchOnFields(edgeKind.schema, matchOn, kind);
9898
+ const validated = [];
9899
+ for (const item of items) {
9900
+ const validatedProps = validateEdgeProps(edgeKind.schema, item.props, {
9901
+ kind,
9902
+ operation: "create"
9903
+ });
9904
+ const compositeKey = buildEdgeCompositeKey(
9905
+ item.fromKind,
9906
+ item.fromId,
9907
+ item.toKind,
9908
+ item.toId,
9909
+ validatedProps,
9910
+ matchOn
9911
+ );
9912
+ const endpointKey = buildEndpointPairKey(
9913
+ item.fromKind,
9914
+ item.fromId,
9915
+ item.toKind,
9916
+ item.toId
9917
+ );
9918
+ validated.push({
9919
+ fromKind: item.fromKind,
9920
+ fromId: item.fromId,
9921
+ toKind: item.toKind,
9922
+ toId: item.toId,
9923
+ validatedProps,
9924
+ compositeKey,
9925
+ endpointKey
9926
+ });
9927
+ }
9928
+ const uniqueEndpoints = /* @__PURE__ */ new Map();
9929
+ for (const entry of validated) {
9930
+ if (!uniqueEndpoints.has(entry.endpointKey)) {
9931
+ uniqueEndpoints.set(entry.endpointKey, {
9932
+ fromKind: entry.fromKind,
9933
+ fromId: entry.fromId,
9934
+ toKind: entry.toKind,
9935
+ toId: entry.toId
9936
+ });
9937
+ }
9938
+ }
9939
+ const rowsByEndpoint = /* @__PURE__ */ new Map();
9940
+ for (const [endpointKey, endpoint] of uniqueEndpoints) {
9941
+ const rows = await backend.findEdgesByKind({
9942
+ graphId: ctx.graphId,
9943
+ kind,
9944
+ fromKind: endpoint.fromKind,
9945
+ fromId: endpoint.fromId,
9946
+ toKind: endpoint.toKind,
9947
+ toId: endpoint.toId,
9948
+ excludeDeleted: false,
9949
+ temporalMode: "includeTombstones"
9950
+ });
9951
+ rowsByEndpoint.set(endpointKey, rows);
9952
+ }
9953
+ const toCreate = [];
9954
+ const toFetch = [];
9955
+ const duplicateOf = [];
9956
+ const seenKeys = /* @__PURE__ */ new Map();
9957
+ for (const [index, entry] of validated.entries()) {
9958
+ const previousIndex = seenKeys.get(entry.compositeKey);
9959
+ if (previousIndex !== void 0) {
9960
+ duplicateOf.push({ index, sourceIndex: previousIndex });
9961
+ continue;
9962
+ }
9963
+ seenKeys.set(entry.compositeKey, index);
9964
+ const candidateRows = rowsByEndpoint.get(entry.endpointKey) ?? [];
9965
+ const { liveRow, deletedRow } = findMatchingEdge(
9966
+ candidateRows,
9967
+ matchOn,
9968
+ entry.validatedProps
9969
+ );
9970
+ if (liveRow === void 0 && deletedRow === void 0) {
9971
+ toCreate.push({
9972
+ index,
9973
+ input: {
9974
+ kind,
9975
+ fromKind: entry.fromKind,
9976
+ fromId: entry.fromId,
9977
+ toKind: entry.toKind,
9978
+ toId: entry.toId,
9979
+ props: entry.validatedProps
9980
+ }
9981
+ });
9982
+ } else {
9983
+ const bestRow = liveRow ?? deletedRow;
9984
+ toFetch.push({
9985
+ index,
9986
+ row: bestRow,
9987
+ isDeleted: liveRow === void 0,
9988
+ validatedProps: entry.validatedProps,
9989
+ fromKind: entry.fromKind,
9990
+ fromId: entry.fromId,
9991
+ toKind: entry.toKind,
9992
+ toId: entry.toId
9993
+ });
9994
+ }
9995
+ }
9996
+ const results = Array.from({ length: items.length });
9997
+ if (toCreate.length > 0) {
9998
+ const createInputs = toCreate.map((entry) => entry.input);
9999
+ const createdEdges = await executeEdgeCreateBatch(
10000
+ ctx,
10001
+ createInputs,
10002
+ backend
10003
+ );
10004
+ for (const [batchIndex, entry] of toCreate.entries()) {
10005
+ results[entry.index] = {
10006
+ edge: createdEdges[batchIndex],
10007
+ action: "created"
10008
+ };
10009
+ }
10010
+ }
10011
+ for (const entry of toFetch) {
10012
+ if (entry.isDeleted) {
10013
+ const effectiveValidTo = entry.row.valid_to;
10014
+ const constraintContext = {
10015
+ graphId: ctx.graphId,
10016
+ registry: ctx.registry,
10017
+ backend
10018
+ };
10019
+ await checkCardinalityConstraint(
10020
+ constraintContext,
10021
+ kind,
10022
+ cardinality,
10023
+ entry.fromKind,
10024
+ entry.fromId,
10025
+ entry.toKind,
10026
+ entry.toId,
10027
+ effectiveValidTo
10028
+ );
10029
+ const edge = await executeEdgeUpsertUpdate(
10030
+ ctx,
10031
+ { id: entry.row.id, props: entry.validatedProps },
10032
+ backend,
10033
+ { clearDeleted: true }
10034
+ );
10035
+ results[entry.index] = { edge, action: "resurrected" };
10036
+ } else if (ifExists === "update") {
10037
+ const edge = await executeEdgeUpsertUpdate(
10038
+ ctx,
10039
+ { id: entry.row.id, props: entry.validatedProps },
10040
+ backend
10041
+ );
10042
+ results[entry.index] = { edge, action: "updated" };
10043
+ } else {
10044
+ results[entry.index] = { edge: rowToEdge(entry.row), action: "found" };
10045
+ }
10046
+ }
10047
+ for (const { index, sourceIndex } of duplicateOf) {
10048
+ const sourceResult = results[sourceIndex];
10049
+ results[index] = { edge: sourceResult.edge, action: "found" };
10050
+ }
10051
+ return results;
10052
+ }
9580
10053
 
9581
10054
  // src/store/embedding-sync.ts
9582
10055
  function getEmbeddingFields(schema) {
@@ -10359,6 +10832,371 @@ async function executeNodeHardDelete(ctx, kind, id, backend) {
10359
10832
  await ("transaction" in backend && backend.capabilities.transactions ? backend.transaction(async (tx) => hardDelete(tx)) : hardDelete(backend));
10360
10833
  });
10361
10834
  }
10835
+ function resolveConstraint(graph, kind, constraintName) {
10836
+ const registration = getNodeRegistration(graph, kind);
10837
+ const constraints = registration.unique ?? [];
10838
+ const constraint = constraints.find((c) => c.name === constraintName);
10839
+ if (constraint === void 0) {
10840
+ throw new NodeConstraintNotFoundError(constraintName, kind);
10841
+ }
10842
+ return constraint;
10843
+ }
10844
+ async function executeNodeGetOrCreateByConstraint(ctx, kind, constraintName, props, backend, options) {
10845
+ const ifExists = options?.ifExists ?? "return";
10846
+ const registration = getNodeRegistration(ctx.graph, kind);
10847
+ const nodeKind = registration.type;
10848
+ const validatedProps = validateNodeProps(nodeKind.schema, props, {
10849
+ kind,
10850
+ operation: "create"
10851
+ });
10852
+ const constraint = resolveConstraint(ctx.graph, kind, constraintName);
10853
+ if (!checkWherePredicate(constraint, validatedProps)) {
10854
+ const input = { kind, props: validatedProps };
10855
+ const node = await executeNodeCreate(ctx, input, backend);
10856
+ return { node, action: "created" };
10857
+ }
10858
+ const key = computeUniqueKey(
10859
+ validatedProps,
10860
+ constraint.fields,
10861
+ constraint.collation
10862
+ );
10863
+ const kindsToCheck = getKindsForUniquenessCheck(
10864
+ kind,
10865
+ constraint.scope,
10866
+ ctx.registry
10867
+ );
10868
+ let existingUniqueRow;
10869
+ for (const kindToCheck of kindsToCheck) {
10870
+ const row = await backend.checkUnique({
10871
+ graphId: ctx.graphId,
10872
+ nodeKind: kindToCheck,
10873
+ constraintName: constraint.name,
10874
+ key,
10875
+ includeDeleted: true
10876
+ });
10877
+ if (row !== void 0) {
10878
+ existingUniqueRow = row;
10879
+ break;
10880
+ }
10881
+ }
10882
+ if (existingUniqueRow === void 0) {
10883
+ const input = { kind, props: validatedProps };
10884
+ const node = await executeNodeCreate(ctx, input, backend);
10885
+ return { node, action: "created" };
10886
+ }
10887
+ const existingRow = await backend.getNode(
10888
+ ctx.graphId,
10889
+ existingUniqueRow.concrete_kind,
10890
+ existingUniqueRow.node_id
10891
+ );
10892
+ if (existingRow === void 0) {
10893
+ const input = { kind, props: validatedProps };
10894
+ const node = await executeNodeCreate(ctx, input, backend);
10895
+ return { node, action: "created" };
10896
+ }
10897
+ const isSoftDeleted = existingRow.deleted_at !== void 0;
10898
+ if (isSoftDeleted || ifExists === "update") {
10899
+ const concreteKind = existingUniqueRow.concrete_kind;
10900
+ const node = await executeNodeUpsertUpdate(
10901
+ ctx,
10902
+ {
10903
+ kind: concreteKind,
10904
+ id: existingRow.id,
10905
+ props: validatedProps
10906
+ },
10907
+ backend,
10908
+ { clearDeleted: isSoftDeleted }
10909
+ );
10910
+ return { node, action: isSoftDeleted ? "resurrected" : "updated" };
10911
+ }
10912
+ return { node: rowToNode(existingRow), action: "found" };
10913
+ }
10914
+ async function executeNodeFindByConstraint(ctx, kind, constraintName, props, backend) {
10915
+ const registration = getNodeRegistration(ctx.graph, kind);
10916
+ const nodeKind = registration.type;
10917
+ const validatedProps = validateNodeProps(nodeKind.schema, props, {
10918
+ kind,
10919
+ operation: "create"
10920
+ });
10921
+ const constraint = resolveConstraint(ctx.graph, kind, constraintName);
10922
+ if (!checkWherePredicate(constraint, validatedProps)) return void 0;
10923
+ const key = computeUniqueKey(
10924
+ validatedProps,
10925
+ constraint.fields,
10926
+ constraint.collation
10927
+ );
10928
+ const kindsToCheck = getKindsForUniquenessCheck(
10929
+ kind,
10930
+ constraint.scope,
10931
+ ctx.registry
10932
+ );
10933
+ let existingUniqueRow;
10934
+ for (const kindToCheck of kindsToCheck) {
10935
+ const row = await backend.checkUnique({
10936
+ graphId: ctx.graphId,
10937
+ nodeKind: kindToCheck,
10938
+ constraintName: constraint.name,
10939
+ key,
10940
+ includeDeleted: false
10941
+ });
10942
+ if (row !== void 0) {
10943
+ existingUniqueRow = row;
10944
+ break;
10945
+ }
10946
+ }
10947
+ if (existingUniqueRow === void 0) return void 0;
10948
+ const existingRow = await backend.getNode(
10949
+ ctx.graphId,
10950
+ existingUniqueRow.concrete_kind,
10951
+ existingUniqueRow.node_id
10952
+ );
10953
+ if (existingRow === void 0 || existingRow.deleted_at !== void 0)
10954
+ return void 0;
10955
+ return rowToNode(existingRow);
10956
+ }
10957
+ async function executeNodeBulkFindByConstraint(ctx, kind, constraintName, items, backend) {
10958
+ if (items.length === 0) return [];
10959
+ const registration = getNodeRegistration(ctx.graph, kind);
10960
+ const nodeKind = registration.type;
10961
+ const constraint = resolveConstraint(ctx.graph, kind, constraintName);
10962
+ const validated = [];
10963
+ for (const item of items) {
10964
+ const validatedProps = validateNodeProps(nodeKind.schema, item.props, {
10965
+ kind,
10966
+ operation: "create"
10967
+ });
10968
+ const applies = checkWherePredicate(constraint, validatedProps);
10969
+ const key = applies ? computeUniqueKey(
10970
+ validatedProps,
10971
+ constraint.fields,
10972
+ constraint.collation
10973
+ ) : void 0;
10974
+ validated.push({ validatedProps, key });
10975
+ }
10976
+ const uniqueKeys = [
10977
+ ...new Set(
10978
+ validated.map((v) => v.key).filter((k) => k !== void 0)
10979
+ )
10980
+ ];
10981
+ const kindsToCheck = getKindsForUniquenessCheck(
10982
+ kind,
10983
+ constraint.scope,
10984
+ ctx.registry
10985
+ );
10986
+ const existingByKey = /* @__PURE__ */ new Map();
10987
+ if (uniqueKeys.length > 0) {
10988
+ for (const kindToCheck of kindsToCheck) {
10989
+ if (backend.checkUniqueBatch === void 0) {
10990
+ for (const key of uniqueKeys) {
10991
+ if (existingByKey.has(key)) continue;
10992
+ const row = await backend.checkUnique({
10993
+ graphId: ctx.graphId,
10994
+ nodeKind: kindToCheck,
10995
+ constraintName: constraint.name,
10996
+ key,
10997
+ includeDeleted: false
10998
+ });
10999
+ if (row !== void 0) {
11000
+ existingByKey.set(row.key, row);
11001
+ }
11002
+ }
11003
+ } else {
11004
+ const rows = await backend.checkUniqueBatch({
11005
+ graphId: ctx.graphId,
11006
+ nodeKind: kindToCheck,
11007
+ constraintName: constraint.name,
11008
+ keys: uniqueKeys,
11009
+ includeDeleted: false
11010
+ });
11011
+ for (const row of rows) {
11012
+ if (!existingByKey.has(row.key)) {
11013
+ existingByKey.set(row.key, row);
11014
+ }
11015
+ }
11016
+ }
11017
+ }
11018
+ }
11019
+ const results = Array.from({ length: items.length });
11020
+ const seenKeys = /* @__PURE__ */ new Map();
11021
+ for (const [index, { key }] of validated.entries()) {
11022
+ if (key === void 0) {
11023
+ results[index] = void 0;
11024
+ continue;
11025
+ }
11026
+ const previousIndex = seenKeys.get(key);
11027
+ if (previousIndex !== void 0) {
11028
+ results[index] = results[previousIndex];
11029
+ continue;
11030
+ }
11031
+ seenKeys.set(key, index);
11032
+ const existing = existingByKey.get(key);
11033
+ if (existing === void 0) {
11034
+ results[index] = void 0;
11035
+ continue;
11036
+ }
11037
+ const existingRow = await backend.getNode(
11038
+ ctx.graphId,
11039
+ existing.concrete_kind,
11040
+ existing.node_id
11041
+ );
11042
+ if (existingRow === void 0 || existingRow.deleted_at !== void 0) {
11043
+ results[index] = void 0;
11044
+ continue;
11045
+ }
11046
+ results[index] = rowToNode(existingRow);
11047
+ }
11048
+ return results;
11049
+ }
11050
+ async function executeNodeBulkGetOrCreateByConstraint(ctx, kind, constraintName, items, backend, options) {
11051
+ if (items.length === 0) return [];
11052
+ const ifExists = options?.ifExists ?? "return";
11053
+ const registration = getNodeRegistration(ctx.graph, kind);
11054
+ const nodeKind = registration.type;
11055
+ const constraint = resolveConstraint(ctx.graph, kind, constraintName);
11056
+ const validated = [];
11057
+ for (const item of items) {
11058
+ const validatedProps = validateNodeProps(nodeKind.schema, item.props, {
11059
+ kind,
11060
+ operation: "create"
11061
+ });
11062
+ const applies = checkWherePredicate(constraint, validatedProps);
11063
+ const key = applies ? computeUniqueKey(
11064
+ validatedProps,
11065
+ constraint.fields,
11066
+ constraint.collation
11067
+ ) : void 0;
11068
+ validated.push({ validatedProps, key });
11069
+ }
11070
+ const uniqueKeys = [
11071
+ ...new Set(
11072
+ validated.map((v) => v.key).filter((k) => k !== void 0)
11073
+ )
11074
+ ];
11075
+ const kindsToCheck = getKindsForUniquenessCheck(
11076
+ kind,
11077
+ constraint.scope,
11078
+ ctx.registry
11079
+ );
11080
+ const existingByKey = /* @__PURE__ */ new Map();
11081
+ if (uniqueKeys.length > 0) {
11082
+ for (const kindToCheck of kindsToCheck) {
11083
+ if (backend.checkUniqueBatch === void 0) {
11084
+ for (const key of uniqueKeys) {
11085
+ if (existingByKey.has(key)) continue;
11086
+ const row = await backend.checkUnique({
11087
+ graphId: ctx.graphId,
11088
+ nodeKind: kindToCheck,
11089
+ constraintName: constraint.name,
11090
+ key,
11091
+ includeDeleted: true
11092
+ });
11093
+ if (row !== void 0) {
11094
+ existingByKey.set(row.key, row);
11095
+ }
11096
+ }
11097
+ } else {
11098
+ const rows = await backend.checkUniqueBatch({
11099
+ graphId: ctx.graphId,
11100
+ nodeKind: kindToCheck,
11101
+ constraintName: constraint.name,
11102
+ keys: uniqueKeys,
11103
+ includeDeleted: true
11104
+ });
11105
+ for (const row of rows) {
11106
+ if (!existingByKey.has(row.key)) {
11107
+ existingByKey.set(row.key, row);
11108
+ }
11109
+ }
11110
+ }
11111
+ }
11112
+ }
11113
+ const toCreate = [];
11114
+ const toFetch = [];
11115
+ const duplicateOf = [];
11116
+ const seenKeys = /* @__PURE__ */ new Map();
11117
+ for (const [index, { validatedProps, key }] of validated.entries()) {
11118
+ if (key === void 0) {
11119
+ toCreate.push({
11120
+ index,
11121
+ input: { kind, props: validatedProps }
11122
+ });
11123
+ continue;
11124
+ }
11125
+ const previousIndex = seenKeys.get(key);
11126
+ if (previousIndex !== void 0) {
11127
+ duplicateOf.push({ index, sourceIndex: previousIndex });
11128
+ continue;
11129
+ }
11130
+ seenKeys.set(key, index);
11131
+ const existing = existingByKey.get(key);
11132
+ if (existing === void 0) {
11133
+ toCreate.push({
11134
+ index,
11135
+ input: { kind, props: validatedProps }
11136
+ });
11137
+ } else {
11138
+ toFetch.push({
11139
+ index,
11140
+ nodeId: existing.node_id,
11141
+ concreteKind: existing.concrete_kind,
11142
+ validatedProps,
11143
+ isSoftDeleted: existing.deleted_at !== void 0
11144
+ });
11145
+ }
11146
+ }
11147
+ const results = Array.from({ length: items.length });
11148
+ if (toCreate.length > 0) {
11149
+ const createInputs = toCreate.map((entry) => entry.input);
11150
+ const createdNodes = await executeNodeCreateBatch(
11151
+ ctx,
11152
+ createInputs,
11153
+ backend
11154
+ );
11155
+ for (const [batchIndex, entry] of toCreate.entries()) {
11156
+ results[entry.index] = {
11157
+ node: createdNodes[batchIndex],
11158
+ action: "created"
11159
+ };
11160
+ }
11161
+ }
11162
+ for (const entry of toFetch) {
11163
+ const { index, concreteKind, validatedProps, isSoftDeleted, nodeId } = entry;
11164
+ const existingRow = await backend.getNode(
11165
+ ctx.graphId,
11166
+ concreteKind,
11167
+ nodeId
11168
+ );
11169
+ if (existingRow === void 0) {
11170
+ const input = { kind, props: validatedProps };
11171
+ const node = await executeNodeCreate(ctx, input, backend);
11172
+ results[index] = { node, action: "created" };
11173
+ continue;
11174
+ }
11175
+ if (isSoftDeleted || ifExists === "update") {
11176
+ const node = await executeNodeUpsertUpdate(
11177
+ ctx,
11178
+ {
11179
+ kind: concreteKind,
11180
+ id: existingRow.id,
11181
+ props: validatedProps
11182
+ },
11183
+ backend,
11184
+ { clearDeleted: isSoftDeleted }
11185
+ );
11186
+ results[index] = {
11187
+ node,
11188
+ action: isSoftDeleted ? "resurrected" : "updated"
11189
+ };
11190
+ } else {
11191
+ results[index] = { node: rowToNode(existingRow), action: "found" };
11192
+ }
11193
+ }
11194
+ for (const { index, sourceIndex } of duplicateOf) {
11195
+ const sourceResult = results[sourceIndex];
11196
+ results[index] = { node: sourceResult.node, action: "found" };
11197
+ }
11198
+ return results;
11199
+ }
10362
11200
 
10363
11201
  // src/store/store.ts
10364
11202
  var Store = class {
@@ -10472,7 +11310,31 @@ var Store = class {
10472
11310
  executeDelete: (kind, id, backend) => executeNodeDelete(ctx, kind, id, backend),
10473
11311
  executeHardDelete: (kind, id, backend) => executeNodeHardDelete(ctx, kind, id, backend),
10474
11312
  matchesTemporalMode: (row, options) => this.#matchesTemporalMode(row, options),
10475
- createQuery: () => this.query()
11313
+ createQuery: () => this.query(),
11314
+ executeGetOrCreateByConstraint: (kind, constraintName, props, backend, options) => executeNodeGetOrCreateByConstraint(
11315
+ ctx,
11316
+ kind,
11317
+ constraintName,
11318
+ props,
11319
+ backend,
11320
+ options
11321
+ ),
11322
+ executeBulkGetOrCreateByConstraint: (kind, constraintName, items, backend, options) => executeNodeBulkGetOrCreateByConstraint(
11323
+ ctx,
11324
+ kind,
11325
+ constraintName,
11326
+ items,
11327
+ backend,
11328
+ options
11329
+ ),
11330
+ executeFindByConstraint: (kind, constraintName, props, backend) => executeNodeFindByConstraint(ctx, kind, constraintName, props, backend),
11331
+ executeBulkFindByConstraint: (kind, constraintName, items, backend) => executeNodeBulkFindByConstraint(
11332
+ ctx,
11333
+ kind,
11334
+ constraintName,
11335
+ items,
11336
+ backend
11337
+ )
10476
11338
  };
10477
11339
  }
10478
11340
  /**
@@ -10491,7 +11353,35 @@ var Store = class {
10491
11353
  executeDelete: (id, backend) => executeEdgeDelete(ctx, id, backend),
10492
11354
  executeHardDelete: (id, backend) => executeEdgeHardDelete(ctx, id, backend),
10493
11355
  matchesTemporalMode: (row, options) => this.#matchesTemporalMode(row, options),
10494
- createQuery: () => this.query()
11356
+ createQuery: () => this.query(),
11357
+ executeGetOrCreateByEndpoints: (kind, fromKind, fromId, toKind, toId, props, backend, options) => executeEdgeGetOrCreateByEndpoints(
11358
+ ctx,
11359
+ kind,
11360
+ fromKind,
11361
+ fromId,
11362
+ toKind,
11363
+ toId,
11364
+ props,
11365
+ backend,
11366
+ options
11367
+ ),
11368
+ executeBulkGetOrCreateByEndpoints: (kind, items, backend, options) => executeEdgeBulkGetOrCreateByEndpoints(
11369
+ ctx,
11370
+ kind,
11371
+ items,
11372
+ backend,
11373
+ options
11374
+ ),
11375
+ executeFindByEndpoints: (kind, fromKind, fromId, toKind, toId, backend, options) => executeEdgeFindByEndpoints(
11376
+ ctx,
11377
+ kind,
11378
+ fromKind,
11379
+ fromId,
11380
+ toKind,
11381
+ toId,
11382
+ backend,
11383
+ options
11384
+ )
10495
11385
  };
10496
11386
  }
10497
11387
  // === Query Builder ===
@@ -10558,6 +11448,24 @@ var Store = class {
10558
11448
  return fn({ nodes, edges });
10559
11449
  });
10560
11450
  }
11451
+ // === Graph Lifecycle ===
11452
+ /**
11453
+ * Hard-deletes all data for this graph from the database.
11454
+ *
11455
+ * Removes all nodes, edges, uniqueness entries, embeddings, and schema versions
11456
+ * for this graph's ID. No hooks, no per-row logic. Wrapped in a transaction
11457
+ * when the backend supports it.
11458
+ *
11459
+ * The store is usable after clearing — new data can be created immediately.
11460
+ */
11461
+ async clear() {
11462
+ const doClear = async (target) => {
11463
+ await target.clearGraph(this.graphId);
11464
+ };
11465
+ await (this.#backend.capabilities.transactions ? this.#backend.transaction(async (tx) => doClear(tx)) : doClear(this.#backend));
11466
+ this.#nodeCollections = void 0;
11467
+ this.#edgeCollections = void 0;
11468
+ }
10561
11469
  // === Lifecycle ===
10562
11470
  /**
10563
11471
  * Closes the store and releases underlying resources.