@nicia-ai/typegraph 0.12.0 → 0.14.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 (67) hide show
  1. package/dist/backend/postgres/index.cjs +28 -28
  2. package/dist/backend/postgres/index.d.cts +1 -1
  3. package/dist/backend/postgres/index.d.ts +1 -1
  4. package/dist/backend/postgres/index.js +4 -4
  5. package/dist/backend/sqlite/index.cjs +14 -14
  6. package/dist/backend/sqlite/index.d.cts +1 -1
  7. package/dist/backend/sqlite/index.d.ts +1 -1
  8. package/dist/backend/sqlite/index.js +4 -4
  9. package/dist/backend/sqlite/local.cjs +7 -7
  10. package/dist/backend/sqlite/local.d.cts +1 -1
  11. package/dist/backend/sqlite/local.d.ts +1 -1
  12. package/dist/backend/sqlite/local.js +4 -4
  13. package/dist/{chunk-U3452TEU.js → chunk-6GWJH6AR.js} +15 -27
  14. package/dist/chunk-6GWJH6AR.js.map +1 -0
  15. package/dist/{chunk-52WSY6G5.js → chunk-BNIBR5U2.js} +70 -31
  16. package/dist/chunk-BNIBR5U2.js.map +1 -0
  17. package/dist/{chunk-54WJF3DW.js → chunk-GNIYZKBI.js} +29 -3
  18. package/dist/chunk-GNIYZKBI.js.map +1 -0
  19. package/dist/{chunk-2XPKLHHH.cjs → chunk-KE2BL3JZ.cjs} +74 -35
  20. package/dist/chunk-KE2BL3JZ.cjs.map +1 -0
  21. package/dist/{chunk-PYV4ADC6.js → chunk-KLOSTZDQ.js} +141 -13
  22. package/dist/chunk-KLOSTZDQ.js.map +1 -0
  23. package/dist/{chunk-JQDWEX6V.cjs → chunk-LELLOHJK.cjs} +22 -34
  24. package/dist/chunk-LELLOHJK.cjs.map +1 -0
  25. package/dist/{chunk-2WVFEIHR.cjs → chunk-MME3H4ZF.cjs} +40 -2
  26. package/dist/chunk-MME3H4ZF.cjs.map +1 -0
  27. package/dist/{chunk-NZMKJHE2.cjs → chunk-OEKH5PWL.cjs} +15 -15
  28. package/dist/{chunk-NZMKJHE2.cjs.map → chunk-OEKH5PWL.cjs.map} +1 -1
  29. package/dist/{chunk-7VITUTRA.cjs → chunk-QFZ5QB2J.cjs} +140 -12
  30. package/dist/chunk-QFZ5QB2J.cjs.map +1 -0
  31. package/dist/{chunk-J4SICP3X.js → chunk-RVUEBUBH.js} +3 -3
  32. package/dist/{chunk-J4SICP3X.js.map → chunk-RVUEBUBH.js.map} +1 -1
  33. package/dist/index.cjs +483 -597
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +12 -9
  36. package/dist/index.d.ts +12 -9
  37. package/dist/index.js +445 -559
  38. package/dist/index.js.map +1 -1
  39. package/dist/indexes/index.cjs +16 -16
  40. package/dist/indexes/index.js +2 -2
  41. package/dist/interchange/index.d.cts +3 -3
  42. package/dist/interchange/index.d.ts +3 -3
  43. package/dist/{manager-DGSnJa1v.d.cts → manager-oh2mTMvy.d.cts} +1 -1
  44. package/dist/{manager-BCLhWysp.d.ts → manager-qRSdnKEO.d.ts} +1 -1
  45. package/dist/profiler/index.cjs +6 -6
  46. package/dist/profiler/index.cjs.map +1 -1
  47. package/dist/profiler/index.d.cts +3 -3
  48. package/dist/profiler/index.d.ts +3 -3
  49. package/dist/profiler/index.js +6 -6
  50. package/dist/profiler/index.js.map +1 -1
  51. package/dist/schema/index.cjs +20 -20
  52. package/dist/schema/index.d.cts +4 -4
  53. package/dist/schema/index.d.ts +4 -4
  54. package/dist/schema/index.js +2 -2
  55. package/dist/{store-BcnA11lH.d.ts → store-B9ItxA-Q.d.ts} +56 -17
  56. package/dist/{store-NEa4EFFD.d.cts → store-BJPIoe8u.d.cts} +56 -17
  57. package/dist/{types-1YJKodRv.d.ts → types-5t_MIcvv.d.ts} +12 -6
  58. package/dist/{types-GLkwvQvS.d.cts → types-Ckfwgv9l.d.cts} +12 -6
  59. package/package.json +1 -1
  60. package/dist/chunk-2WVFEIHR.cjs.map +0 -1
  61. package/dist/chunk-2XPKLHHH.cjs.map +0 -1
  62. package/dist/chunk-52WSY6G5.js.map +0 -1
  63. package/dist/chunk-54WJF3DW.js.map +0 -1
  64. package/dist/chunk-7VITUTRA.cjs.map +0 -1
  65. package/dist/chunk-JQDWEX6V.cjs.map +0 -1
  66. package/dist/chunk-PYV4ADC6.js.map +0 -1
  67. package/dist/chunk-U3452TEU.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,16 +1,66 @@
1
1
  'use strict';
2
2
 
3
- var chunk7VITUTRA_cjs = require('./chunk-7VITUTRA.cjs');
3
+ var chunkQFZ5QB2J_cjs = require('./chunk-QFZ5QB2J.cjs');
4
4
  var chunkNI2GV74U_cjs = require('./chunk-NI2GV74U.cjs');
5
5
  var chunk44SXEVF4_cjs = require('./chunk-44SXEVF4.cjs');
6
- var chunk2WVFEIHR_cjs = require('./chunk-2WVFEIHR.cjs');
6
+ var chunkMME3H4ZF_cjs = require('./chunk-MME3H4ZF.cjs');
7
7
  var chunkP5CNM325_cjs = require('./chunk-P5CNM325.cjs');
8
8
  var zod = require('zod');
9
9
  var drizzleOrm = require('drizzle-orm');
10
10
  var nanoid = require('nanoid');
11
11
 
12
+ // src/store/reserved-keys.ts
13
+ var RESERVED_NODE_KEYS = /* @__PURE__ */ new Set([
14
+ "id",
15
+ "kind",
16
+ "meta"
17
+ ]);
18
+ var RESERVED_EDGE_KEYS = /* @__PURE__ */ new Set([
19
+ "id",
20
+ "kind",
21
+ "meta",
22
+ "fromKind",
23
+ "fromId",
24
+ "toKind",
25
+ "toId"
26
+ ]);
27
+ var PROTOTYPE_POLLUTION_KEYS = /* @__PURE__ */ new Set([
28
+ "__proto__",
29
+ "constructor",
30
+ "prototype"
31
+ ]);
32
+ function validateProjectionField(field2, entityType, kind) {
33
+ const reserved = entityType === "node" ? RESERVED_NODE_KEYS : RESERVED_EDGE_KEYS;
34
+ if (reserved.has(field2)) {
35
+ throw new chunk44SXEVF4_cjs.ConfigurationError(
36
+ `Projection field "${field2}" on ${entityType} kind "${kind}" conflicts with a reserved structural key`,
37
+ { field: field2, kind, entityType, reservedKeys: [...reserved] },
38
+ {
39
+ suggestion: `Remove "${field2}" from the projection. Structural fields (${[...reserved].join(", ")}) are included automatically when relevant.`
40
+ }
41
+ );
42
+ }
43
+ if (PROTOTYPE_POLLUTION_KEYS.has(field2)) {
44
+ throw new chunk44SXEVF4_cjs.ConfigurationError(
45
+ `Projection field "${field2}" on ${entityType} kind "${kind}" is not allowed`,
46
+ { field: field2, kind, entityType },
47
+ {
48
+ suggestion: `"${field2}" cannot be used as a projection field name.`
49
+ }
50
+ );
51
+ }
52
+ }
53
+ function filterReservedKeys(props, reservedKeys) {
54
+ const filtered = {};
55
+ for (const [key, value] of Object.entries(props)) {
56
+ if (!reservedKeys.has(key)) {
57
+ filtered[key] = value;
58
+ }
59
+ }
60
+ return filtered;
61
+ }
62
+
12
63
  // src/core/node.ts
13
- var RESERVED_NODE_KEYS = /* @__PURE__ */ new Set(["id", "kind", "meta"]);
14
64
  function validateSchemaKeys(schema, name) {
15
65
  const shape = schema.shape;
16
66
  const conflicts = Object.keys(shape).filter(
@@ -35,15 +85,6 @@ function defineNode(name, options) {
35
85
  description: options.description
36
86
  });
37
87
  }
38
- var RESERVED_EDGE_KEYS = /* @__PURE__ */ new Set([
39
- "id",
40
- "kind",
41
- "meta",
42
- "fromKind",
43
- "fromId",
44
- "toKind",
45
- "toId"
46
- ]);
47
88
  var EMPTY_SCHEMA = zod.z.object({});
48
89
  function validateSchemaKeys2(schema, name) {
49
90
  const shape = schema.shape;
@@ -84,7 +125,7 @@ function metaEdge(name, options = {}) {
84
125
  description: options.description
85
126
  };
86
127
  return Object.freeze({
87
- [chunk7VITUTRA_cjs.META_EDGE_BRAND]: true,
128
+ [chunkQFZ5QB2J_cjs.META_EDGE_BRAND]: true,
88
129
  name,
89
130
  properties
90
131
  });
@@ -120,7 +161,7 @@ function createExternalRef(table) {
120
161
  // src/ontology/core-meta-edges.ts
121
162
  function createMetaEdge(name, properties) {
122
163
  return Object.freeze({
123
- [chunk7VITUTRA_cjs.META_EDGE_BRAND]: true,
164
+ [chunkQFZ5QB2J_cjs.META_EDGE_BRAND]: true,
124
165
  name,
125
166
  properties: {
126
167
  transitive: properties.transitive ?? false,
@@ -132,7 +173,7 @@ function createMetaEdge(name, properties) {
132
173
  }
133
174
  });
134
175
  }
135
- var subClassOfMetaEdge = createMetaEdge(chunk7VITUTRA_cjs.META_EDGE_SUB_CLASS_OF, {
176
+ var subClassOfMetaEdge = createMetaEdge(chunkQFZ5QB2J_cjs.META_EDGE_SUB_CLASS_OF, {
136
177
  transitive: true,
137
178
  inference: "subsumption",
138
179
  description: "Type inheritance (Podcast subClassOf Media)"
@@ -144,9 +185,9 @@ function subClassOf(child, parent) {
144
185
  to: parent
145
186
  };
146
187
  }
147
- var broaderMetaEdge = createMetaEdge(chunk7VITUTRA_cjs.META_EDGE_BROADER, {
188
+ var broaderMetaEdge = createMetaEdge(chunkQFZ5QB2J_cjs.META_EDGE_BROADER, {
148
189
  transitive: true,
149
- inverse: chunk7VITUTRA_cjs.META_EDGE_NARROWER,
190
+ inverse: chunkQFZ5QB2J_cjs.META_EDGE_NARROWER,
150
191
  inference: "hierarchy",
151
192
  description: "Broader concept (ML broader AI)"
152
193
  });
@@ -157,9 +198,9 @@ function broader(narrowerConcept, broaderConcept) {
157
198
  to: broaderConcept
158
199
  };
159
200
  }
160
- var narrowerMetaEdge = createMetaEdge(chunk7VITUTRA_cjs.META_EDGE_NARROWER, {
201
+ var narrowerMetaEdge = createMetaEdge(chunkQFZ5QB2J_cjs.META_EDGE_NARROWER, {
161
202
  transitive: true,
162
- inverse: chunk7VITUTRA_cjs.META_EDGE_BROADER,
203
+ inverse: chunkQFZ5QB2J_cjs.META_EDGE_BROADER,
163
204
  inference: "hierarchy",
164
205
  description: "Narrower concept (AI narrower ML)"
165
206
  });
@@ -170,7 +211,7 @@ function narrower(broaderConcept, narrowerConcept) {
170
211
  to: narrowerConcept
171
212
  };
172
213
  }
173
- var relatedToMetaEdge = createMetaEdge(chunk7VITUTRA_cjs.META_EDGE_RELATED_TO, {
214
+ var relatedToMetaEdge = createMetaEdge(chunkQFZ5QB2J_cjs.META_EDGE_RELATED_TO, {
174
215
  symmetric: true,
175
216
  inference: "association",
176
217
  description: "Non-hierarchical association"
@@ -182,7 +223,7 @@ function relatedTo(conceptA, conceptB) {
182
223
  to: conceptB
183
224
  };
184
225
  }
185
- var equivalentToMetaEdge = createMetaEdge(chunk7VITUTRA_cjs.META_EDGE_EQUIVALENT_TO, {
226
+ var equivalentToMetaEdge = createMetaEdge(chunkQFZ5QB2J_cjs.META_EDGE_EQUIVALENT_TO, {
186
227
  symmetric: true,
187
228
  transitive: true,
188
229
  inference: "substitution",
@@ -195,7 +236,7 @@ function equivalentTo(kindA, kindBOrIri) {
195
236
  to: kindBOrIri
196
237
  };
197
238
  }
198
- var sameAsMetaEdge = createMetaEdge(chunk7VITUTRA_cjs.META_EDGE_SAME_AS, {
239
+ var sameAsMetaEdge = createMetaEdge(chunkQFZ5QB2J_cjs.META_EDGE_SAME_AS, {
199
240
  symmetric: true,
200
241
  transitive: true,
201
242
  inference: "substitution",
@@ -208,7 +249,7 @@ function sameAs(kindA, kindBOrIri) {
208
249
  to: kindBOrIri
209
250
  };
210
251
  }
211
- var differentFromMetaEdge = createMetaEdge(chunk7VITUTRA_cjs.META_EDGE_DIFFERENT_FROM, {
252
+ var differentFromMetaEdge = createMetaEdge(chunkQFZ5QB2J_cjs.META_EDGE_DIFFERENT_FROM, {
212
253
  symmetric: true,
213
254
  inference: "constraint",
214
255
  description: "Explicitly different individuals"
@@ -220,7 +261,7 @@ function differentFrom(kindA, kindB) {
220
261
  to: kindB
221
262
  };
222
263
  }
223
- var disjointWithMetaEdge = createMetaEdge(chunk7VITUTRA_cjs.META_EDGE_DISJOINT_WITH, {
264
+ var disjointWithMetaEdge = createMetaEdge(chunkQFZ5QB2J_cjs.META_EDGE_DISJOINT_WITH, {
224
265
  symmetric: true,
225
266
  inference: "constraint",
226
267
  description: "Mutually exclusive types"
@@ -232,9 +273,9 @@ function disjointWith(kindA, kindB) {
232
273
  to: kindB
233
274
  };
234
275
  }
235
- var partOfMetaEdge = createMetaEdge(chunk7VITUTRA_cjs.META_EDGE_PART_OF, {
276
+ var partOfMetaEdge = createMetaEdge(chunkQFZ5QB2J_cjs.META_EDGE_PART_OF, {
236
277
  transitive: true,
237
- inverse: chunk7VITUTRA_cjs.META_EDGE_HAS_PART,
278
+ inverse: chunkQFZ5QB2J_cjs.META_EDGE_HAS_PART,
238
279
  inference: "composition",
239
280
  description: "X is part of Y"
240
281
  });
@@ -245,9 +286,9 @@ function partOf(part, whole) {
245
286
  to: whole
246
287
  };
247
288
  }
248
- var hasPartMetaEdge = createMetaEdge(chunk7VITUTRA_cjs.META_EDGE_HAS_PART, {
289
+ var hasPartMetaEdge = createMetaEdge(chunkQFZ5QB2J_cjs.META_EDGE_HAS_PART, {
249
290
  transitive: true,
250
- inverse: chunk7VITUTRA_cjs.META_EDGE_PART_OF,
291
+ inverse: chunkQFZ5QB2J_cjs.META_EDGE_PART_OF,
251
292
  inference: "composition",
252
293
  description: "Y has part X"
253
294
  });
@@ -258,12 +299,12 @@ function hasPart(whole, part) {
258
299
  to: part
259
300
  };
260
301
  }
261
- var inverseOfMetaEdge = createMetaEdge(chunk7VITUTRA_cjs.META_EDGE_INVERSE_OF, {
302
+ var inverseOfMetaEdge = createMetaEdge(chunkQFZ5QB2J_cjs.META_EDGE_INVERSE_OF, {
262
303
  symmetric: true,
263
304
  inference: "none",
264
305
  description: "Edge A is inverse of edge B"
265
306
  });
266
- var impliesMetaEdge = createMetaEdge(chunk7VITUTRA_cjs.META_EDGE_IMPLIES, {
307
+ var impliesMetaEdge = createMetaEdge(chunkQFZ5QB2J_cjs.META_EDGE_IMPLIES, {
267
308
  transitive: true,
268
309
  inference: "none",
269
310
  description: "Edge A implies edge B exists"
@@ -1374,14 +1415,14 @@ function extractVectorSimilarityPredicates(predicates) {
1374
1415
  break;
1375
1416
  }
1376
1417
  case "and": {
1377
- for (const p of expr.predicates) {
1378
- visit(p, inDisallowedBranch);
1418
+ for (const predicate2 of expr.predicates) {
1419
+ visit(predicate2, inDisallowedBranch);
1379
1420
  }
1380
1421
  break;
1381
1422
  }
1382
1423
  case "or": {
1383
- for (const p of expr.predicates) {
1384
- visit(p, true);
1424
+ for (const predicate2 of expr.predicates) {
1425
+ visit(predicate2, true);
1385
1426
  }
1386
1427
  break;
1387
1428
  }
@@ -2404,6 +2445,9 @@ function compileTemporalFilter(options) {
2404
2445
  return drizzleOrm.sql`${deletedAt} IS NULL AND (${validFrom} IS NULL OR ${validFrom} <= ${now}) AND (${validTo} IS NULL OR ${validTo} > ${now})`;
2405
2446
  }
2406
2447
  case "asOf": {
2448
+ if (asOf === void 0) {
2449
+ throw new Error(`asOf timestamp is required for temporal mode "asOf"`);
2450
+ }
2407
2451
  const timestamp = asOf;
2408
2452
  return drizzleOrm.sql`${deletedAt} IS NULL AND (${validFrom} IS NULL OR ${validFrom} <= ${timestamp}) AND (${validTo} IS NULL OR ${validTo} > ${timestamp})`;
2409
2453
  }
@@ -2714,7 +2758,7 @@ function lowerComposableQueryToLogicalPlanNode(query, dialect, graphId, nextPlan
2714
2758
  }
2715
2759
  const vectorPredicate = runVectorPredicatePass(
2716
2760
  query,
2717
- chunk2WVFEIHR_cjs.getDialect(dialect)
2761
+ chunkMME3H4ZF_cjs.getDialect(dialect)
2718
2762
  ).vectorPredicate;
2719
2763
  const effectiveLimit = resolveVectorAwareLimit(query.limit, vectorPredicate);
2720
2764
  const loweringInput = {
@@ -2811,7 +2855,7 @@ function lowerSetOperationToLogicalPlan(input) {
2811
2855
  }
2812
2856
 
2813
2857
  // src/query/compiler/recursive.ts
2814
- var MAX_RECURSIVE_DEPTH = 100;
2858
+ var MAX_RECURSIVE_DEPTH = 10;
2815
2859
  var MAX_EXPLICIT_RECURSIVE_DEPTH = 1e3;
2816
2860
  var NO_ALWAYS_REQUIRED_COLUMNS = /* @__PURE__ */ new Set();
2817
2861
  function runRecursiveQueryPassPipeline(ast, graphId, ctx) {
@@ -3304,15 +3348,14 @@ var DEFAULT_TABLE_NAMES = {
3304
3348
  edges: "typegraph_edges",
3305
3349
  embeddings: "typegraph_node_embeddings"
3306
3350
  };
3307
- var MAX_IDENTIFIER_LENGTH = 63;
3308
3351
  var VALID_IDENTIFIER_PATTERN = /^[a-z_][a-z0-9_$]*$/i;
3309
3352
  function validateTableName(name, label) {
3310
3353
  if (!name || name.length === 0) {
3311
3354
  throw new chunk44SXEVF4_cjs.ConfigurationError(`${label} table name cannot be empty`);
3312
3355
  }
3313
- if (name.length > MAX_IDENTIFIER_LENGTH) {
3356
+ if (name.length > chunkMME3H4ZF_cjs.MAX_PG_IDENTIFIER_LENGTH) {
3314
3357
  throw new chunk44SXEVF4_cjs.ConfigurationError(
3315
- `${label} table name exceeds maximum length of ${MAX_IDENTIFIER_LENGTH} characters`
3358
+ `${label} table name exceeds maximum length of ${chunkMME3H4ZF_cjs.MAX_PG_IDENTIFIER_LENGTH} characters`
3316
3359
  );
3317
3360
  }
3318
3361
  if (!VALID_IDENTIFIER_PATTERN.test(name)) {
@@ -3395,64 +3438,13 @@ function decodeByValueType(value, valueType) {
3395
3438
  }
3396
3439
  }
3397
3440
 
3398
- // src/store/reserved-keys.ts
3399
- var RESERVED_NODE_KEYS2 = /* @__PURE__ */ new Set([
3400
- "id",
3401
- "kind",
3402
- "meta"
3403
- ]);
3404
- var RESERVED_EDGE_KEYS2 = /* @__PURE__ */ new Set([
3405
- "id",
3406
- "kind",
3407
- "meta",
3408
- "fromKind",
3409
- "fromId",
3410
- "toKind",
3411
- "toId"
3412
- ]);
3413
- var PROTOTYPE_POLLUTION_KEYS = /* @__PURE__ */ new Set([
3414
- "__proto__",
3415
- "constructor",
3416
- "prototype"
3417
- ]);
3418
- function validateProjectionField(field2, entityType, kind) {
3419
- const reserved = entityType === "node" ? RESERVED_NODE_KEYS2 : RESERVED_EDGE_KEYS2;
3420
- if (reserved.has(field2)) {
3421
- throw new chunk44SXEVF4_cjs.ConfigurationError(
3422
- `Projection field "${field2}" on ${entityType} kind "${kind}" conflicts with a reserved structural key`,
3423
- { field: field2, kind, entityType, reservedKeys: [...reserved] },
3424
- {
3425
- suggestion: `Remove "${field2}" from the projection. Structural fields (${[...reserved].join(", ")}) are included automatically when relevant.`
3426
- }
3427
- );
3428
- }
3429
- if (PROTOTYPE_POLLUTION_KEYS.has(field2)) {
3430
- throw new chunk44SXEVF4_cjs.ConfigurationError(
3431
- `Projection field "${field2}" on ${entityType} kind "${kind}" is not allowed`,
3432
- { field: field2, kind, entityType },
3433
- {
3434
- suggestion: `"${field2}" cannot be used as a projection field name.`
3435
- }
3436
- );
3437
- }
3438
- }
3439
- function filterReservedKeys(props, reservedKeys) {
3440
- const filtered = {};
3441
- for (const [key, value] of Object.entries(props)) {
3442
- if (!reservedKeys.has(key)) {
3443
- filtered[key] = value;
3444
- }
3445
- }
3446
- return filtered;
3447
- }
3448
-
3449
3441
  // src/store/row-mappers.ts
3450
3442
  function nullToUndefined2(value) {
3451
3443
  return value === null ? void 0 : value;
3452
3444
  }
3453
3445
  function rowToNode(row) {
3454
3446
  const rawProps = JSON.parse(row.props);
3455
- const props = filterReservedKeys(rawProps, RESERVED_NODE_KEYS2);
3447
+ const props = filterReservedKeys(rawProps, RESERVED_NODE_KEYS);
3456
3448
  return {
3457
3449
  kind: row.kind,
3458
3450
  id: row.id,
@@ -3472,7 +3464,7 @@ function rowToNodeMeta(row) {
3472
3464
  }
3473
3465
  function rowToEdge(row) {
3474
3466
  const rawProps = JSON.parse(row.props);
3475
- const props = filterReservedKeys(rawProps, RESERVED_EDGE_KEYS2);
3467
+ const props = filterReservedKeys(rawProps, RESERVED_EDGE_KEYS);
3476
3468
  return {
3477
3469
  id: row.id,
3478
3470
  kind: row.kind,
@@ -3496,17 +3488,6 @@ function rowToEdgeMeta(row) {
3496
3488
 
3497
3489
  // src/store/subgraph.ts
3498
3490
  var DEFAULT_SUBGRAPH_MAX_DEPTH = 10;
3499
- var MAX_PG_IDENTIFIER_LENGTH = 63;
3500
- function fnv1aBase36(input) {
3501
- let hash = 2166136261;
3502
- for (const character of input) {
3503
- const codePoint = character.codePointAt(0);
3504
- if (codePoint === void 0) continue;
3505
- hash ^= codePoint;
3506
- hash = Math.imul(hash, 16777619);
3507
- }
3508
- return (hash >>> 0).toString(36);
3509
- }
3510
3491
  var TEXT_ENCODER = new TextEncoder();
3511
3492
  function truncateToBytes(value, maxBytes) {
3512
3493
  const encoded = TEXT_ENCODER.encode(value);
@@ -3519,9 +3500,9 @@ function truncateToBytes(value, maxBytes) {
3519
3500
  }
3520
3501
  function projectionAlias(entityPrefix, kind, field2) {
3521
3502
  const prefix = entityPrefix === "node" ? "sg_n" : "sg_e";
3522
- const hash = fnv1aBase36(`${kind}\0${field2}`);
3503
+ const hash = chunkMME3H4ZF_cjs.fnv1aBase36(`${kind}\0${field2}`);
3523
3504
  const fixedBytes = prefix.length + 1 + 1 + hash.length;
3524
- const maxKindBytes = MAX_PG_IDENTIFIER_LENGTH - fixedBytes;
3505
+ const maxKindBytes = chunkMME3H4ZF_cjs.MAX_PG_IDENTIFIER_LENGTH - fixedBytes;
3525
3506
  const truncatedKind = truncateToBytes(kind, maxKindBytes);
3526
3507
  return `${prefix}_${truncatedKind}_${hash}`;
3527
3508
  }
@@ -3538,7 +3519,7 @@ async function executeSubgraph(params) {
3538
3519
  }
3539
3520
  const maxDepth = Math.min(
3540
3521
  options.maxDepth ?? DEFAULT_SUBGRAPH_MAX_DEPTH,
3541
- MAX_RECURSIVE_DEPTH
3522
+ MAX_EXPLICIT_RECURSIVE_DEPTH
3542
3523
  );
3543
3524
  const ctx = {
3544
3525
  graphId: params.graphId,
@@ -4222,6 +4203,7 @@ function compileFieldColumnForSetOp(field2, prefix, dialect) {
4222
4203
  updated_at: "_updated_at",
4223
4204
  deleted_at: "_deleted_at"
4224
4205
  };
4206
+ if (columnName === void 0) return drizzleOrm.sql.raw(`${cteName}.${alias}_props`);
4225
4207
  const suffix = columnMap[columnName];
4226
4208
  if (suffix) {
4227
4209
  return drizzleOrm.sql.raw(`${cteName}.${alias}${suffix}`);
@@ -4300,18 +4282,18 @@ function buildSetOperationSuffixClauses(op, dialect) {
4300
4282
  );
4301
4283
  }
4302
4284
  const orderParts = [];
4303
- for (const o of op.orderBy) {
4304
- const projected = matchFieldToProjection(o.field, projection);
4285
+ for (const orderSpec of op.orderBy) {
4286
+ const projected = matchFieldToProjection(orderSpec.field, projection);
4305
4287
  if (!projected) {
4306
- const fieldDesc = o.field.jsonPointer ? `${o.field.alias}.props${o.field.jsonPointer}` : `${o.field.alias}.${o.field.path.join(".")}`;
4288
+ const fieldDesc = orderSpec.field.jsonPointer ? `${orderSpec.field.alias}.props${orderSpec.field.jsonPointer}` : `${orderSpec.field.alias}.${orderSpec.field.path.join(".")}`;
4307
4289
  const availableFields = projection.fields.map((f) => f.outputName).join(", ");
4308
4290
  throw new chunk44SXEVF4_cjs.UnsupportedPredicateError(
4309
4291
  `Set operation ORDER BY field "${fieldDesc}" is not in the projection. ORDER BY for UNION/INTERSECT/EXCEPT must reference projected columns. Available columns: ${availableFields}`
4310
4292
  );
4311
4293
  }
4312
4294
  const columnRef = drizzleOrm.sql.raw(dialect.quoteIdentifier(projected.outputName));
4313
- const dir = drizzleOrm.sql.raw(o.direction.toUpperCase());
4314
- const nulls = o.nulls ?? (o.direction === "asc" ? "last" : "first");
4295
+ const dir = drizzleOrm.sql.raw(orderSpec.direction.toUpperCase());
4296
+ const nulls = orderSpec.nulls ?? (orderSpec.direction === "asc" ? "last" : "first");
4315
4297
  const nullsDir = drizzleOrm.sql.raw(nulls === "first" ? "DESC" : "ASC");
4316
4298
  orderParts.push(
4317
4299
  drizzleOrm.sql`(${columnRef} IS NULL) ${nullsDir}`,
@@ -4663,7 +4645,7 @@ function compileQuery(ast, graphId, options = "sqlite") {
4663
4645
  const options_ = typeof options === "string" ? { dialect: options } : options;
4664
4646
  const dialect = options_.dialect ?? "sqlite";
4665
4647
  const schema = options_.schema ?? DEFAULT_SQL_SCHEMA;
4666
- const adapter = chunk2WVFEIHR_cjs.getDialect(dialect);
4648
+ const adapter = chunkMME3H4ZF_cjs.getDialect(dialect);
4667
4649
  const ctx = {
4668
4650
  dialect: adapter,
4669
4651
  schema,
@@ -4703,7 +4685,7 @@ function compileSetOperation2(op, graphId, options = "sqlite") {
4703
4685
  const options_ = typeof options === "string" ? { dialect: options } : options;
4704
4686
  const dialect = options_.dialect ?? "sqlite";
4705
4687
  const schema = options_.schema ?? DEFAULT_SQL_SCHEMA;
4706
- const adapter = chunk2WVFEIHR_cjs.getDialect(dialect);
4688
+ const adapter = chunkMME3H4ZF_cjs.getDialect(dialect);
4707
4689
  return compileSetOperation(
4708
4690
  op,
4709
4691
  graphId,
@@ -5178,13 +5160,14 @@ function generateId() {
5178
5160
 
5179
5161
  // src/utils/path.ts
5180
5162
  function parseSqlitePath(path) {
5181
- if (!path || path === "||") return [];
5163
+ const emptyPath = `${chunkMME3H4ZF_cjs.SQLITE_PATH_DELIMITER}${chunkMME3H4ZF_cjs.SQLITE_PATH_DELIMITER}`;
5164
+ if (!path || path === emptyPath) return [];
5182
5165
  const trimmed = path.slice(1, -1);
5183
5166
  if (trimmed === "") return [];
5184
- return trimmed.split("|");
5167
+ return trimmed.split(chunkMME3H4ZF_cjs.SQLITE_PATH_DELIMITER);
5185
5168
  }
5186
5169
  function isSqlitePath(value) {
5187
- return typeof value === "string" && value.startsWith("|") && value.endsWith("|");
5170
+ return typeof value === "string" && value.startsWith(chunkMME3H4ZF_cjs.SQLITE_PATH_DELIMITER) && value.endsWith(chunkMME3H4ZF_cjs.SQLITE_PATH_DELIMITER);
5188
5171
  }
5189
5172
  function normalizePath(value) {
5190
5173
  if (Array.isArray(value)) {
@@ -5199,20 +5182,20 @@ function normalizePath(value) {
5199
5182
  return [];
5200
5183
  }
5201
5184
  function isPostgresTextArray(value) {
5202
- return typeof value === "string" && value.startsWith("{") && value.endsWith("}");
5185
+ return typeof value === "string" && value.startsWith(chunkMME3H4ZF_cjs.PG_ARRAY_START) && value.endsWith(chunkMME3H4ZF_cjs.PG_ARRAY_END);
5203
5186
  }
5204
5187
  function parsePostgresTextArray(value) {
5205
5188
  const inner = value.slice(1, -1);
5206
5189
  if (inner === "") return [];
5207
- return inner.split(",");
5190
+ return inner.split(chunkMME3H4ZF_cjs.PG_PATH_ELEMENT_SEPARATOR);
5208
5191
  }
5209
5192
 
5210
5193
  // src/query/execution/result-mapper.ts
5211
5194
  function transformPathColumns(rows, state, _dialect) {
5212
5195
  const pathAliases = [];
5213
- for (const t of state.traversals) {
5214
- if (t.variableLength?.pathAlias !== void 0) {
5215
- pathAliases.push(t.variableLength.pathAlias);
5196
+ for (const traversal of state.traversals) {
5197
+ if (traversal.variableLength?.pathAlias !== void 0) {
5198
+ pathAliases.push(traversal.variableLength.pathAlias);
5216
5199
  }
5217
5200
  }
5218
5201
  if (pathAliases.length === 0) return rows;
@@ -5236,8 +5219,8 @@ function transformPathColumns(rows, state, _dialect) {
5236
5219
  }
5237
5220
  return changed ? result : rows;
5238
5221
  }
5239
- var RESERVED_NODE_KEYS3 = /* @__PURE__ */ new Set(["id", "kind", "meta"]);
5240
- var RESERVED_EDGE_KEYS3 = /* @__PURE__ */ new Set(["id", "kind", "fromId", "toId", "meta"]);
5222
+ var RESERVED_NODE_KEYS2 = /* @__PURE__ */ new Set(["id", "kind", "meta"]);
5223
+ var RESERVED_EDGE_KEYS2 = /* @__PURE__ */ new Set(["id", "kind", "fromId", "toId", "meta"]);
5241
5224
  function nullToUndefined3(value) {
5242
5225
  return value === null ? void 0 : value;
5243
5226
  }
@@ -5275,7 +5258,7 @@ function buildSelectableNode(row, alias) {
5275
5258
  deletedAt
5276
5259
  }
5277
5260
  };
5278
- assignPropsExcludingReserved(result, rawProps, RESERVED_NODE_KEYS3);
5261
+ assignPropsExcludingReserved(result, rawProps, RESERVED_NODE_KEYS2);
5279
5262
  return result;
5280
5263
  }
5281
5264
  function buildSelectableNodeOrUndefined(row, alias) {
@@ -5317,7 +5300,7 @@ function buildSelectableEdge(row, alias) {
5317
5300
  deletedAt
5318
5301
  }
5319
5302
  };
5320
- assignPropsExcludingReserved(result, rawProps, RESERVED_EDGE_KEYS3);
5303
+ assignPropsExcludingReserved(result, rawProps, RESERVED_EDGE_KEYS2);
5321
5304
  return result;
5322
5305
  }
5323
5306
  function buildSelectContext(row, startAlias, traversals) {
@@ -5445,7 +5428,7 @@ async function* createStreamIterable(batchSize, paginate) {
5445
5428
  }
5446
5429
  }
5447
5430
  function getStreamBatchSize(options) {
5448
- return options?.batchSize ?? 1e3;
5431
+ return options?.batchSize ?? chunkMME3H4ZF_cjs.DEFAULT_STREAM_BATCH_SIZE;
5449
5432
  }
5450
5433
 
5451
5434
  // src/query/ast.ts
@@ -5537,7 +5520,7 @@ function createNodeTrackingProxy(alias, kindNames, tracker, options) {
5537
5520
  return getPlaceholderForSystemField(property, options.mode);
5538
5521
  }
5539
5522
  if (property === "meta") {
5540
- for (const key of chunk2WVFEIHR_cjs.NODE_META_KEYS) {
5523
+ for (const key of chunkMME3H4ZF_cjs.NODE_META_KEYS) {
5541
5524
  tracker.record(alias, `meta.${key}`, true);
5542
5525
  }
5543
5526
  return buildNodeMetaPlaceholder(options.mode);
@@ -5570,7 +5553,7 @@ function createEdgeTrackingProxy(alias, edgeKindNames, tracker, options) {
5570
5553
  return getPlaceholderForSystemField(property, options.mode);
5571
5554
  }
5572
5555
  if (property === "meta") {
5573
- for (const key of chunk2WVFEIHR_cjs.EDGE_META_KEYS) {
5556
+ for (const key of chunkMME3H4ZF_cjs.EDGE_META_KEYS) {
5574
5557
  tracker.record(alias, `meta.${key}`, true);
5575
5558
  }
5576
5559
  return buildEdgeMetaPlaceholder(options.mode);
@@ -5857,6 +5840,9 @@ function buildSelectiveContext(row, plans, traversals) {
5857
5840
  return context;
5858
5841
  }
5859
5842
  function buildOptionalAliasValue(row, plan) {
5843
+ if (plan.idOutputName === void 0) {
5844
+ return void 0;
5845
+ }
5860
5846
  const idValue = row[plan.idOutputName];
5861
5847
  if (idValue === null || idValue === void 0) {
5862
5848
  return void 0;
@@ -6258,7 +6244,7 @@ function substituteParameters(ast, bindings) {
6258
6244
  };
6259
6245
  }
6260
6246
  function fillPlaceholders(params, bindings, dialect) {
6261
- const adapter = chunk2WVFEIHR_cjs.getDialect(dialect);
6247
+ const adapter = chunkMME3H4ZF_cjs.getDialect(dialect);
6262
6248
  return params.map((parameter) => {
6263
6249
  if (parameter instanceof drizzleOrm.Placeholder) {
6264
6250
  const name = parameter.name;
@@ -7333,7 +7319,7 @@ var ExecutableQuery = class _ExecutableQuery {
7333
7319
  );
7334
7320
  }
7335
7321
  const isBackward = options.last !== void 0 || options.before !== void 0;
7336
- const limit = options.first ?? options.last ?? 20;
7322
+ const limit = options.first ?? options.last ?? chunkMME3H4ZF_cjs.DEFAULT_PAGINATION_LIMIT;
7337
7323
  const cursor = options.after ?? options.before;
7338
7324
  let cursorData;
7339
7325
  if (cursor) {
@@ -7656,7 +7642,8 @@ var TraversalBuilder = class _TraversalBuilder {
7656
7642
  }
7657
7643
  /**
7658
7644
  * Enables variable-length (recursive) traversal.
7659
- * By default, traverses unlimited depth with cycle prevention.
7645
+ * Defaults to MAX_RECURSIVE_DEPTH (10) hops with cycle prevention.
7646
+ * Use `maxHops` to override (up to MAX_EXPLICIT_RECURSIVE_DEPTH).
7660
7647
  */
7661
7648
  recursive(options) {
7662
7649
  const minDepth = options?.minHops ?? this.#variableLength.minDepth;
@@ -8850,8 +8837,8 @@ function createQueryBuilder(graphId, registry, options) {
8850
8837
  function buildKindRegistry(graph) {
8851
8838
  const nodeTypes = extractNodeTypes(graph);
8852
8839
  const edgeTypes = extractEdgeTypes(graph);
8853
- const closures = graph.ontology.length > 0 ? chunk7VITUTRA_cjs.computeClosuresFromOntology(graph.ontology) : chunk7VITUTRA_cjs.createEmptyClosures();
8854
- return new chunk7VITUTRA_cjs.KindRegistry(nodeTypes, edgeTypes, closures);
8840
+ const closures = graph.ontology.length > 0 ? chunkQFZ5QB2J_cjs.computeClosuresFromOntology(graph.ontology) : chunkQFZ5QB2J_cjs.createEmptyClosures();
8841
+ return new chunkQFZ5QB2J_cjs.KindRegistry(nodeTypes, edgeTypes, closures);
8855
8842
  }
8856
8843
  function extractNodeTypes(graph) {
8857
8844
  const result = /* @__PURE__ */ new Map();
@@ -8917,6 +8904,35 @@ function createEdgeCollection(config) {
8917
8904
  executeHardDelete: executeEdgeHardDelete2,
8918
8905
  matchesTemporalMode
8919
8906
  } = config;
8907
+ const mapRows = (rows) => rows.map((row) => narrowEdge(rowToEdge2(row)));
8908
+ async function findEdgesFrom(from, target) {
8909
+ const rows = await target.findEdgesByKind({
8910
+ graphId,
8911
+ kind,
8912
+ fromKind: from.kind,
8913
+ fromId: from.id,
8914
+ excludeDeleted: true
8915
+ });
8916
+ return mapRows(rows);
8917
+ }
8918
+ async function findEdgesTo(to, target) {
8919
+ const rows = await target.findEdgesByKind({
8920
+ graphId,
8921
+ kind,
8922
+ toKind: to.kind,
8923
+ toId: to.id,
8924
+ excludeDeleted: true
8925
+ });
8926
+ return mapRows(rows);
8927
+ }
8928
+ function buildFindByEndpointsOptions(options) {
8929
+ const result = {};
8930
+ if (options?.matchOn !== void 0)
8931
+ result.matchOn = options.matchOn;
8932
+ if (options?.props !== void 0)
8933
+ result.props = options.props;
8934
+ return result;
8935
+ }
8920
8936
  return {
8921
8937
  async create(from, to, props, options) {
8922
8938
  const result = await executeEdgeCreate2(
@@ -8972,24 +8988,32 @@ function createEdgeCollection(config) {
8972
8988
  return narrowEdge(result);
8973
8989
  },
8974
8990
  async findFrom(from) {
8975
- const rows = await backend.findEdgesByKind({
8976
- graphId,
8977
- kind,
8978
- fromKind: from.kind,
8979
- fromId: from.id,
8980
- excludeDeleted: true
8981
- });
8982
- return rows.map((row) => narrowEdge(rowToEdge2(row)));
8991
+ return findEdgesFrom(from, backend);
8983
8992
  },
8984
8993
  async findTo(to) {
8985
- const rows = await backend.findEdgesByKind({
8986
- graphId,
8987
- kind,
8988
- toKind: to.kind,
8989
- toId: to.id,
8990
- excludeDeleted: true
8991
- });
8992
- return rows.map((row) => narrowEdge(rowToEdge2(row)));
8994
+ return findEdgesTo(to, backend);
8995
+ },
8996
+ batchFindFrom(from) {
8997
+ return { executeOn: (target) => findEdgesFrom(from, target) };
8998
+ },
8999
+ batchFindTo(to) {
9000
+ return { executeOn: (target) => findEdgesTo(to, target) };
9001
+ },
9002
+ batchFindByEndpoints(from, to, options) {
9003
+ return {
9004
+ executeOn: async (target) => {
9005
+ const result = await config.executeFindByEndpoints(
9006
+ kind,
9007
+ from.kind,
9008
+ from.id,
9009
+ to.kind,
9010
+ to.id,
9011
+ target,
9012
+ buildFindByEndpointsOptions(options)
9013
+ );
9014
+ return result === void 0 ? [] : [narrowEdge(result)];
9015
+ }
9016
+ };
8993
9017
  },
8994
9018
  async delete(id) {
8995
9019
  await executeEdgeDelete2(id, backend);
@@ -9023,7 +9047,7 @@ function createEdgeCollection(config) {
9023
9047
  if (options?.limit !== void 0) params.limit = options.limit;
9024
9048
  if (options?.offset !== void 0) params.offset = options.offset;
9025
9049
  const rows = await backend.findEdgesByKind(params);
9026
- return rows.map((row) => narrowEdge(rowToEdge2(row)));
9050
+ return mapRows(rows);
9027
9051
  },
9028
9052
  async count(options) {
9029
9053
  const mode = options?.temporalMode ?? defaultTemporalMode;
@@ -9152,11 +9176,6 @@ function createEdgeCollection(config) {
9152
9176
  await deleteAll(backend);
9153
9177
  },
9154
9178
  async findByEndpoints(from, to, options) {
9155
- const findOptions = {};
9156
- if (options?.matchOn !== void 0)
9157
- findOptions.matchOn = options.matchOn;
9158
- if (options?.props !== void 0)
9159
- findOptions.props = options.props;
9160
9179
  const result = await config.executeFindByEndpoints(
9161
9180
  kind,
9162
9181
  from.kind,
@@ -9164,7 +9183,7 @@ function createEdgeCollection(config) {
9164
9183
  to.kind,
9165
9184
  to.id,
9166
9185
  backend,
9167
- findOptions
9186
+ buildFindByEndpointsOptions(options)
9168
9187
  );
9169
9188
  return result === void 0 ? void 0 : narrowEdge(result);
9170
9189
  },
@@ -10021,7 +10040,7 @@ async function validateAndPrepareEdgeCreate(ctx, input, id, backend) {
10021
10040
  nodeId: input.toId
10022
10041
  });
10023
10042
  }
10024
- const validatedProps = chunk7VITUTRA_cjs.validateEdgeProps(edgeKind.schema, input.props, {
10043
+ const validatedProps = chunkQFZ5QB2J_cjs.validateEdgeProps(edgeKind.schema, input.props, {
10025
10044
  kind,
10026
10045
  operation: "create"
10027
10046
  });
@@ -10171,7 +10190,7 @@ async function executeEdgeUpdate(ctx, input, backend) {
10171
10190
  const edgeKind = registration.type;
10172
10191
  const existingProps = JSON.parse(existing.props);
10173
10192
  const mergedProps = { ...existingProps, ...input.props };
10174
- const validatedProps = chunk7VITUTRA_cjs.validateEdgeProps(edgeKind.schema, mergedProps, {
10193
+ const validatedProps = chunkQFZ5QB2J_cjs.validateEdgeProps(edgeKind.schema, mergedProps, {
10175
10194
  kind: existing.kind,
10176
10195
  operation: "update",
10177
10196
  id
@@ -10197,7 +10216,7 @@ async function executeEdgeUpsertUpdate(ctx, input, backend, options) {
10197
10216
  const edgeKind = registration.type;
10198
10217
  const existingProps = JSON.parse(existing.props);
10199
10218
  const mergedProps = { ...existingProps, ...input.props };
10200
- const validatedProps = chunk7VITUTRA_cjs.validateEdgeProps(edgeKind.schema, mergedProps, {
10219
+ const validatedProps = chunkQFZ5QB2J_cjs.validateEdgeProps(edgeKind.schema, mergedProps, {
10201
10220
  kind: existing.kind,
10202
10221
  operation: "update",
10203
10222
  id
@@ -10354,7 +10373,7 @@ async function executeEdgeGetOrCreateByEndpoints(ctx, kind, fromKind, fromId, to
10354
10373
  const matchOn = options?.matchOn ?? [];
10355
10374
  const registration = getEdgeRegistration(ctx.graph, kind);
10356
10375
  const edgeKind = registration.type;
10357
- const validatedProps = chunk7VITUTRA_cjs.validateEdgeProps(edgeKind.schema, props, {
10376
+ const validatedProps = chunkQFZ5QB2J_cjs.validateEdgeProps(edgeKind.schema, props, {
10358
10377
  kind,
10359
10378
  operation: "create"
10360
10379
  });
@@ -10398,6 +10417,9 @@ async function executeEdgeGetOrCreateByEndpoints(ctx, kind, fromKind, fromId, to
10398
10417
  return { edge: edge2, action: "updated" };
10399
10418
  }
10400
10419
  const cardinality = registration.cardinality ?? "many";
10420
+ if (deletedRow === void 0) {
10421
+ throw new Error("Expected deletedRow to be defined");
10422
+ }
10401
10423
  const matchedDeletedRow = deletedRow;
10402
10424
  const effectiveValidTo = matchedDeletedRow.valid_to;
10403
10425
  const constraintContext = {
@@ -10433,7 +10455,7 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
10433
10455
  validateMatchOnFields(edgeKind.schema, matchOn, kind);
10434
10456
  const validated = [];
10435
10457
  for (const item of items) {
10436
- const validatedProps = chunk7VITUTRA_cjs.validateEdgeProps(edgeKind.schema, item.props, {
10458
+ const validatedProps = chunkQFZ5QB2J_cjs.validateEdgeProps(edgeKind.schema, item.props, {
10437
10459
  kind,
10438
10460
  operation: "create"
10439
10461
  });
@@ -10517,6 +10539,9 @@ async function executeEdgeBulkGetOrCreateByEndpoints(ctx, kind, items, backend,
10517
10539
  });
10518
10540
  } else {
10519
10541
  const bestRow = liveRow ?? deletedRow;
10542
+ if (bestRow === void 0) {
10543
+ throw new Error("Expected at least one of liveRow or deletedRow");
10544
+ }
10520
10545
  toFetch.push({
10521
10546
  index,
10522
10547
  row: bestRow,
@@ -10817,11 +10842,12 @@ function getNodeRegistration(graph, kind) {
10817
10842
  if (registration === void 0) throw new chunk44SXEVF4_cjs.KindNotFoundError(kind, "node");
10818
10843
  return registration;
10819
10844
  }
10845
+ var CACHE_KEY_SEPARATOR = "\0";
10820
10846
  function buildNodeCacheKey(graphId, kind, id) {
10821
- return `${graphId}\0${kind}\0${id}`;
10847
+ return `${graphId}${CACHE_KEY_SEPARATOR}${kind}${CACHE_KEY_SEPARATOR}${id}`;
10822
10848
  }
10823
10849
  function buildUniqueCacheKey(graphId, nodeKind, constraintName, key) {
10824
- return `${graphId}\0${nodeKind}\0${constraintName}\0${key}`;
10850
+ return `${graphId}${CACHE_KEY_SEPARATOR}${nodeKind}${CACHE_KEY_SEPARATOR}${constraintName}${CACHE_KEY_SEPARATOR}${key}`;
10825
10851
  }
10826
10852
  function createNodeAlreadyExistsError(kind, id) {
10827
10853
  return new chunk44SXEVF4_cjs.ValidationError(
@@ -10858,6 +10884,23 @@ function createPendingUniqueRow(graphId, nodeKind, constraintName, key, nodeId)
10858
10884
  deleted_at: void 0
10859
10885
  };
10860
10886
  }
10887
+ function resolveConstraint(graph, kind, constraintName) {
10888
+ const registration = getNodeRegistration(graph, kind);
10889
+ const constraints = registration.unique ?? [];
10890
+ const constraint = constraints.find(
10891
+ (candidate) => candidate.name === constraintName
10892
+ );
10893
+ if (constraint === void 0) {
10894
+ throw new chunk44SXEVF4_cjs.NodeConstraintNotFoundError(constraintName, kind);
10895
+ }
10896
+ return constraint;
10897
+ }
10898
+ function createUniquenessContext(graphId, registry, backend) {
10899
+ return { graphId, registry, backend };
10900
+ }
10901
+ function createEmbeddingSyncContext(graphId, nodeKind, nodeId, backend) {
10902
+ return { graphId, nodeKind, nodeId, backend };
10903
+ }
10861
10904
  function createNodeBatchValidationBackend(graphId, registry, backend) {
10862
10905
  const nodeCache = /* @__PURE__ */ new Map();
10863
10906
  const pendingNodes = /* @__PURE__ */ new Map();
@@ -10866,12 +10909,8 @@ function createNodeBatchValidationBackend(graphId, registry, backend) {
10866
10909
  async function getNodeCached(lookupGraphId, kind, id) {
10867
10910
  const cacheKey = buildNodeCacheKey(lookupGraphId, kind, id);
10868
10911
  const pendingNode = pendingNodes.get(cacheKey);
10869
- if (pendingNode !== void 0) {
10870
- return pendingNode;
10871
- }
10872
- if (nodeCache.has(cacheKey)) {
10873
- return nodeCache.get(cacheKey);
10874
- }
10912
+ if (pendingNode !== void 0) return pendingNode;
10913
+ if (nodeCache.has(cacheKey)) return nodeCache.get(cacheKey);
10875
10914
  const existing = await backend.getNode(lookupGraphId, kind, id);
10876
10915
  nodeCache.set(cacheKey, existing);
10877
10916
  return existing;
@@ -10893,16 +10932,14 @@ function createNodeBatchValidationBackend(graphId, registry, backend) {
10893
10932
  pendingOwner
10894
10933
  );
10895
10934
  }
10896
- if (uniqueCache.has(cacheKey)) {
10897
- return uniqueCache.get(cacheKey);
10898
- }
10935
+ if (uniqueCache.has(cacheKey)) return uniqueCache.get(cacheKey);
10899
10936
  const existing = await backend.checkUnique(params);
10900
10937
  uniqueCache.set(cacheKey, existing);
10901
10938
  return existing;
10902
10939
  }
10903
10940
  function registerPendingNode(params) {
10904
10941
  const cacheKey = buildNodeCacheKey(params.graphId, params.kind, params.id);
10905
- const pendingNode = {
10942
+ pendingNodes.set(cacheKey, {
10906
10943
  graph_id: params.graphId,
10907
10944
  kind: params.kind,
10908
10945
  id: params.id,
@@ -10913,14 +10950,11 @@ function createNodeBatchValidationBackend(graphId, registry, backend) {
10913
10950
  created_at: "",
10914
10951
  updated_at: "",
10915
10952
  deleted_at: void 0
10916
- };
10917
- pendingNodes.set(cacheKey, pendingNode);
10953
+ });
10918
10954
  }
10919
10955
  function registerPendingUniqueEntries(kind, id, props, constraints) {
10920
10956
  for (const constraint of constraints) {
10921
- if (!checkWherePredicate(constraint, props)) {
10922
- continue;
10923
- }
10957
+ if (!checkWherePredicate(constraint, props)) continue;
10924
10958
  const key = computeUniqueKey(
10925
10959
  props,
10926
10960
  constraint.fields,
@@ -10966,7 +11000,7 @@ async function validateAndPrepareNodeCreate(ctx, input, id, backend) {
10966
11000
  const kind = input.kind;
10967
11001
  const registration = getNodeRegistration(ctx.graph, kind);
10968
11002
  const nodeKind = registration.type;
10969
- const validatedProps = chunk7VITUTRA_cjs.validateNodeProps(nodeKind.schema, input.props, {
11003
+ const validatedProps = chunkQFZ5QB2J_cjs.validateNodeProps(nodeKind.schema, input.props, {
10970
11004
  kind,
10971
11005
  operation: "create"
10972
11006
  });
@@ -10982,14 +11016,9 @@ async function validateAndPrepareNodeCreate(ctx, input, id, backend) {
10982
11016
  backend
10983
11017
  };
10984
11018
  await checkDisjointnessConstraint(constraintContext, kind, id);
10985
- const uniquenessContext = {
10986
- graphId: ctx.graphId,
10987
- registry: ctx.registry,
10988
- backend
10989
- };
10990
11019
  const uniqueConstraints = registration.unique ?? [];
10991
11020
  await checkUniquenessConstraints(
10992
- uniquenessContext,
11021
+ createUniquenessContext(ctx.graphId, ctx.registry, backend),
10993
11022
  kind,
10994
11023
  id,
10995
11024
  validatedProps,
@@ -11012,64 +11041,99 @@ async function validateAndPrepareNodeCreate(ctx, input, id, backend) {
11012
11041
  };
11013
11042
  }
11014
11043
  async function finalizeNodeCreate(ctx, prepared, backend) {
11015
- const uniquenessContext = {
11016
- graphId: ctx.graphId,
11017
- registry: ctx.registry,
11018
- backend
11019
- };
11020
11044
  await insertUniquenessEntries(
11021
- uniquenessContext,
11045
+ createUniquenessContext(ctx.graphId, ctx.registry, backend),
11022
11046
  prepared.kind,
11023
11047
  prepared.id,
11024
11048
  prepared.validatedProps,
11025
11049
  prepared.uniqueConstraints
11026
11050
  );
11027
- const embeddingSyncContext = {
11028
- graphId: ctx.graphId,
11029
- nodeKind: prepared.kind,
11030
- nodeId: prepared.id,
11031
- backend
11032
- };
11033
11051
  await syncEmbeddings(
11034
- embeddingSyncContext,
11052
+ createEmbeddingSyncContext(
11053
+ ctx.graphId,
11054
+ prepared.kind,
11055
+ prepared.id,
11056
+ backend
11057
+ ),
11035
11058
  prepared.nodeKind.schema,
11036
11059
  prepared.validatedProps
11037
11060
  );
11038
11061
  }
11039
- async function executeNodeCreateInternal(ctx, input, backend, options) {
11040
- const kind = input.kind;
11041
- const id = input.id ?? generateId();
11042
- const opContext = ctx.createOperationContext("create", "node", kind, id);
11043
- return ctx.withOperationHooks(opContext, async () => {
11044
- const prepared = await validateAndPrepareNodeCreate(
11045
- ctx,
11046
- input,
11047
- id,
11048
- backend
11049
- );
11050
- let row;
11051
- {
11052
- row = await backend.insertNode(prepared.insertParams);
11053
- }
11054
- await finalizeNodeCreate(ctx, prepared, backend);
11055
- if (row === void 0) return;
11056
- return rowToNode(row);
11062
+ async function performNodeUpdate(ctx, input, backend, options) {
11063
+ const { kind, id } = input;
11064
+ const registration = getNodeRegistration(ctx.graph, kind);
11065
+ const existing = await backend.getNode(ctx.graphId, kind, id);
11066
+ if (!existing || existing.deleted_at && !options?.clearDeleted) {
11067
+ throw new chunk44SXEVF4_cjs.NodeNotFoundError(kind, id);
11068
+ }
11069
+ const existingProps = JSON.parse(existing.props);
11070
+ const mergedProps = { ...existingProps, ...input.props };
11071
+ const nodeKind = registration.type;
11072
+ const validatedProps = chunkQFZ5QB2J_cjs.validateNodeProps(nodeKind.schema, mergedProps, {
11073
+ kind,
11074
+ operation: "update",
11075
+ id
11057
11076
  });
11077
+ const validTo = chunkNI2GV74U_cjs.validateOptionalIsoDate(input.validTo, "validTo");
11078
+ await updateUniquenessEntries(
11079
+ createUniquenessContext(ctx.graphId, ctx.registry, backend),
11080
+ kind,
11081
+ id,
11082
+ existingProps,
11083
+ validatedProps,
11084
+ registration.unique ?? []
11085
+ );
11086
+ const updateParams = {
11087
+ graphId: ctx.graphId,
11088
+ kind,
11089
+ id,
11090
+ props: validatedProps,
11091
+ incrementVersion: true
11092
+ };
11093
+ if (validTo !== void 0) updateParams.validTo = validTo;
11094
+ if (options?.clearDeleted) updateParams.clearDeleted = true;
11095
+ const row = await backend.updateNode(updateParams);
11096
+ await syncEmbeddings(
11097
+ createEmbeddingSyncContext(ctx.graphId, kind, id, backend),
11098
+ nodeKind.schema,
11099
+ validatedProps
11100
+ );
11101
+ return rowToNode(row);
11058
11102
  }
11059
- async function executeNodeCreate(ctx, input, backend) {
11060
- const result = await executeNodeCreateInternal(ctx, input, backend);
11061
- if (!result) {
11062
- throw new chunk44SXEVF4_cjs.DatabaseOperationError(
11063
- "Node create failed: expected created node row",
11064
- { operation: "insert", entity: "node" }
11065
- );
11103
+ async function enforceDeleteBehavior(ctx, kind, id, mode, backend, registration) {
11104
+ const deleteBehavior = registration.onDelete ?? "restrict";
11105
+ const connectedEdges = await backend.findEdgesConnectedTo({
11106
+ graphId: ctx.graphId,
11107
+ nodeKind: kind,
11108
+ nodeId: id
11109
+ });
11110
+ if (connectedEdges.length === 0) return;
11111
+ switch (deleteBehavior) {
11112
+ case "restrict": {
11113
+ const edgeKinds = [...new Set(connectedEdges.map((edge) => edge.kind))];
11114
+ throw new chunk44SXEVF4_cjs.RestrictedDeleteError({
11115
+ nodeKind: kind,
11116
+ nodeId: id,
11117
+ edgeCount: connectedEdges.length,
11118
+ edgeKinds
11119
+ });
11120
+ }
11121
+ case "cascade":
11122
+ case "disconnect": {
11123
+ for (const edge of connectedEdges) {
11124
+ await (mode === "hard" ? backend.hardDeleteEdge({
11125
+ graphId: ctx.graphId,
11126
+ id: edge.id
11127
+ }) : backend.deleteEdge({
11128
+ graphId: ctx.graphId,
11129
+ id: edge.id
11130
+ }));
11131
+ }
11132
+ break;
11133
+ }
11066
11134
  }
11067
- return result;
11068
11135
  }
11069
- async function executeNodeCreateNoReturnBatch(ctx, inputs, backend) {
11070
- if (inputs.length === 0) {
11071
- return;
11072
- }
11136
+ async function prepareBatchCreates(ctx, inputs, backend) {
11073
11137
  const {
11074
11138
  backend: validationBackend,
11075
11139
  registerPendingNode,
@@ -11096,46 +11160,109 @@ async function executeNodeCreateNoReturnBatch(ctx, inputs, backend) {
11096
11160
  const batchInsertParams = preparedCreates.map(
11097
11161
  (prepared) => prepared.insertParams
11098
11162
  );
11099
- if (backend.insertNodesBatch === void 0) {
11100
- for (const insertParams of batchInsertParams) {
11101
- await (backend.insertNodeNoReturn?.(insertParams) ?? backend.insertNode(insertParams));
11102
- }
11103
- } else {
11104
- await backend.insertNodesBatch(batchInsertParams);
11105
- }
11106
- for (const prepared of preparedCreates) {
11107
- await finalizeNodeCreate(ctx, prepared, backend);
11163
+ return { preparedCreates, batchInsertParams };
11164
+ }
11165
+ async function findUniqueRowAcrossKinds(backend, graphId, constraintName, key, kindsToCheck, includeDeleted) {
11166
+ for (const kindToCheck of kindsToCheck) {
11167
+ const row = await backend.checkUnique({
11168
+ graphId,
11169
+ nodeKind: kindToCheck,
11170
+ constraintName,
11171
+ key,
11172
+ includeDeleted
11173
+ });
11174
+ if (row !== void 0) return row;
11108
11175
  }
11176
+ return void 0;
11109
11177
  }
11110
- async function executeNodeCreateBatch(ctx, inputs, backend) {
11111
- if (inputs.length === 0) {
11112
- return [];
11178
+ async function batchCheckUniqueAcrossKinds(backend, graphId, constraintName, uniqueKeys, kindsToCheck, includeDeleted) {
11179
+ const existingByKey = /* @__PURE__ */ new Map();
11180
+ for (const kindToCheck of kindsToCheck) {
11181
+ if (backend.checkUniqueBatch === void 0) {
11182
+ for (const key of uniqueKeys) {
11183
+ if (existingByKey.has(key)) continue;
11184
+ const row = await backend.checkUnique({
11185
+ graphId,
11186
+ nodeKind: kindToCheck,
11187
+ constraintName,
11188
+ key,
11189
+ includeDeleted
11190
+ });
11191
+ if (row !== void 0) {
11192
+ existingByKey.set(row.key, row);
11193
+ }
11194
+ }
11195
+ } else {
11196
+ const rows = await backend.checkUniqueBatch({
11197
+ graphId,
11198
+ nodeKind: kindToCheck,
11199
+ constraintName,
11200
+ keys: uniqueKeys,
11201
+ includeDeleted
11202
+ });
11203
+ for (const row of rows) {
11204
+ if (!existingByKey.has(row.key)) {
11205
+ existingByKey.set(row.key, row);
11206
+ }
11207
+ }
11208
+ }
11113
11209
  }
11114
- const {
11115
- backend: validationBackend,
11116
- registerPendingNode,
11117
- registerPendingUniqueEntries
11118
- } = createNodeBatchValidationBackend(ctx.graphId, ctx.registry, backend);
11119
- const preparedCreates = [];
11120
- for (const input of inputs) {
11121
- const id = input.id ?? generateId();
11210
+ return existingByKey;
11211
+ }
11212
+ async function executeNodeCreateInternal(ctx, input, backend, options) {
11213
+ const kind = input.kind;
11214
+ const id = input.id ?? generateId();
11215
+ const opContext = ctx.createOperationContext("create", "node", kind, id);
11216
+ return ctx.withOperationHooks(opContext, async () => {
11122
11217
  const prepared = await validateAndPrepareNodeCreate(
11123
11218
  ctx,
11124
11219
  input,
11125
11220
  id,
11126
- validationBackend
11221
+ backend
11127
11222
  );
11128
- preparedCreates.push(prepared);
11129
- registerPendingNode(prepared.insertParams);
11130
- registerPendingUniqueEntries(
11131
- prepared.kind,
11132
- prepared.id,
11133
- prepared.validatedProps,
11134
- prepared.uniqueConstraints
11223
+ let row;
11224
+ {
11225
+ row = await backend.insertNode(prepared.insertParams);
11226
+ }
11227
+ await finalizeNodeCreate(ctx, prepared, backend);
11228
+ if (row === void 0) return;
11229
+ return rowToNode(row);
11230
+ });
11231
+ }
11232
+ async function executeNodeCreate(ctx, input, backend) {
11233
+ const result = await executeNodeCreateInternal(ctx, input, backend);
11234
+ if (!result) {
11235
+ throw new chunk44SXEVF4_cjs.DatabaseOperationError(
11236
+ "Node create failed: expected created node row",
11237
+ { operation: "insert", entity: "node" }
11135
11238
  );
11136
11239
  }
11137
- const batchInsertParams = preparedCreates.map(
11138
- (prepared) => prepared.insertParams
11240
+ return result;
11241
+ }
11242
+ async function executeNodeCreateNoReturnBatch(ctx, inputs, backend) {
11243
+ if (inputs.length === 0) return;
11244
+ const { preparedCreates, batchInsertParams } = await prepareBatchCreates(
11245
+ ctx,
11246
+ inputs,
11247
+ backend
11248
+ );
11249
+ if (backend.insertNodesBatch === void 0) {
11250
+ for (const insertParams of batchInsertParams) {
11251
+ await (backend.insertNodeNoReturn?.(insertParams) ?? backend.insertNode(insertParams));
11252
+ }
11253
+ } else {
11254
+ await backend.insertNodesBatch(batchInsertParams);
11255
+ }
11256
+ for (const prepared of preparedCreates) {
11257
+ await finalizeNodeCreate(ctx, prepared, backend);
11258
+ }
11259
+ }
11260
+ async function executeNodeCreateBatch(ctx, inputs, backend) {
11261
+ if (inputs.length === 0) return [];
11262
+ const { preparedCreates, batchInsertParams } = await prepareBatchCreates(
11263
+ ctx,
11264
+ inputs,
11265
+ backend
11139
11266
  );
11140
11267
  let rows;
11141
11268
  if (backend.insertNodesBatchReturning === void 0) {
@@ -11153,170 +11280,40 @@ async function executeNodeCreateBatch(ctx, inputs, backend) {
11153
11280
  return rows.map((row) => rowToNode(row));
11154
11281
  }
11155
11282
  async function executeNodeUpdate(ctx, input, backend, options) {
11156
- const kind = input.kind;
11157
- const id = input.id;
11158
- const opContext = ctx.createOperationContext("update", "node", kind, id);
11159
- return ctx.withOperationHooks(opContext, async () => {
11160
- const registration = getNodeRegistration(ctx.graph, kind);
11161
- const existing = await backend.getNode(ctx.graphId, kind, id);
11162
- if (!existing || existing.deleted_at && !options?.clearDeleted) {
11163
- throw new chunk44SXEVF4_cjs.NodeNotFoundError(kind, id);
11164
- }
11165
- const existingProps = JSON.parse(existing.props);
11166
- const mergedProps = { ...existingProps, ...input.props };
11167
- const nodeKind = registration.type;
11168
- const validatedProps = chunk7VITUTRA_cjs.validateNodeProps(nodeKind.schema, mergedProps, {
11169
- kind,
11170
- operation: "update",
11171
- id
11172
- });
11173
- const validTo = chunkNI2GV74U_cjs.validateOptionalIsoDate(input.validTo, "validTo");
11174
- const uniquenessContext = {
11175
- graphId: ctx.graphId,
11176
- registry: ctx.registry,
11177
- backend
11178
- };
11179
- await updateUniquenessEntries(
11180
- uniquenessContext,
11181
- kind,
11182
- id,
11183
- existingProps,
11184
- validatedProps,
11185
- registration.unique ?? []
11186
- );
11187
- const updateParams = {
11188
- graphId: ctx.graphId,
11189
- kind,
11190
- id,
11191
- props: validatedProps,
11192
- incrementVersion: true
11193
- };
11194
- if (validTo !== void 0) updateParams.validTo = validTo;
11195
- if (options?.clearDeleted) updateParams.clearDeleted = true;
11196
- const row = await backend.updateNode(updateParams);
11197
- const embeddingSyncContext = {
11198
- graphId: ctx.graphId,
11199
- nodeKind: kind,
11200
- nodeId: id,
11201
- backend
11202
- };
11203
- await syncEmbeddings(embeddingSyncContext, nodeKind.schema, validatedProps);
11204
- return rowToNode(row);
11205
- });
11283
+ const opContext = ctx.createOperationContext(
11284
+ "update",
11285
+ "node",
11286
+ input.kind,
11287
+ input.id
11288
+ );
11289
+ return ctx.withOperationHooks(
11290
+ opContext,
11291
+ () => performNodeUpdate(ctx, input, backend, options)
11292
+ );
11206
11293
  }
11207
11294
  async function executeNodeUpsertUpdate(ctx, input, backend, options) {
11208
- const kind = input.kind;
11209
- const id = input.id;
11210
- const registration = getNodeRegistration(ctx.graph, kind);
11211
- const existing = await backend.getNode(ctx.graphId, kind, id);
11212
- if (!existing || existing.deleted_at && !options?.clearDeleted) {
11213
- throw new chunk44SXEVF4_cjs.NodeNotFoundError(kind, id);
11214
- }
11215
- const existingProps = JSON.parse(existing.props);
11216
- const mergedProps = { ...existingProps, ...input.props };
11217
- const nodeKind = registration.type;
11218
- const validatedProps = chunk7VITUTRA_cjs.validateNodeProps(nodeKind.schema, mergedProps, {
11219
- kind,
11220
- operation: "update",
11221
- id
11222
- });
11223
- const validTo = chunkNI2GV74U_cjs.validateOptionalIsoDate(input.validTo, "validTo");
11224
- const uniquenessContext = {
11225
- graphId: ctx.graphId,
11226
- registry: ctx.registry,
11227
- backend
11228
- };
11229
- await updateUniquenessEntries(
11230
- uniquenessContext,
11231
- kind,
11232
- id,
11233
- existingProps,
11234
- validatedProps,
11235
- registration.unique ?? []
11236
- );
11237
- const updateParams = {
11238
- graphId: ctx.graphId,
11239
- kind,
11240
- id,
11241
- props: validatedProps,
11242
- incrementVersion: true
11243
- };
11244
- if (validTo !== void 0) updateParams.validTo = validTo;
11245
- if (options?.clearDeleted) updateParams.clearDeleted = true;
11246
- const row = await backend.updateNode(updateParams);
11247
- const embeddingSyncContext = {
11248
- graphId: ctx.graphId,
11249
- nodeKind: kind,
11250
- nodeId: id,
11251
- backend
11252
- };
11253
- await syncEmbeddings(embeddingSyncContext, nodeKind.schema, validatedProps);
11254
- return rowToNode(row);
11295
+ return performNodeUpdate(ctx, input, backend, options);
11255
11296
  }
11256
11297
  async function executeNodeDelete(ctx, kind, id, backend) {
11257
11298
  const opContext = ctx.createOperationContext("delete", "node", kind, id);
11258
11299
  return ctx.withOperationHooks(opContext, async () => {
11259
11300
  const registration = getNodeRegistration(ctx.graph, kind);
11260
11301
  const existing = await backend.getNode(ctx.graphId, kind, id);
11261
- if (!existing || existing.deleted_at) {
11262
- return;
11263
- }
11302
+ if (!existing || existing.deleted_at) return;
11264
11303
  const existingProps = JSON.parse(existing.props);
11265
- const deleteBehavior = registration.onDelete ?? "restrict";
11266
- const connectedEdges = await backend.findEdgesConnectedTo({
11267
- graphId: ctx.graphId,
11268
- nodeKind: kind,
11269
- nodeId: id
11270
- });
11271
- if (connectedEdges.length > 0) {
11272
- switch (deleteBehavior) {
11273
- case "restrict": {
11274
- const edgeKinds = [
11275
- ...new Set(connectedEdges.map((edge) => edge.kind))
11276
- ];
11277
- throw new chunk44SXEVF4_cjs.RestrictedDeleteError({
11278
- nodeKind: kind,
11279
- nodeId: id,
11280
- edgeCount: connectedEdges.length,
11281
- edgeKinds
11282
- });
11283
- }
11284
- case "cascade":
11285
- case "disconnect": {
11286
- for (const edge of connectedEdges) {
11287
- await backend.deleteEdge({
11288
- graphId: ctx.graphId,
11289
- id: edge.id
11290
- });
11291
- }
11292
- break;
11293
- }
11294
- }
11295
- }
11296
- await backend.deleteNode({
11297
- graphId: ctx.graphId,
11298
- kind,
11299
- id
11300
- });
11301
- const uniquenessContext = {
11302
- graphId: ctx.graphId,
11303
- registry: ctx.registry,
11304
- backend
11305
- };
11304
+ await enforceDeleteBehavior(ctx, kind, id, "soft", backend, registration);
11305
+ await backend.deleteNode({ graphId: ctx.graphId, kind, id });
11306
11306
  await deleteUniquenessEntries(
11307
- uniquenessContext,
11307
+ createUniquenessContext(ctx.graphId, ctx.registry, backend),
11308
11308
  kind,
11309
11309
  existingProps,
11310
11310
  registration.unique ?? []
11311
11311
  );
11312
11312
  const nodeKind = registration.type;
11313
- const embeddingSyncContext = {
11314
- graphId: ctx.graphId,
11315
- nodeKind: kind,
11316
- nodeId: id,
11317
- backend
11318
- };
11319
- await deleteNodeEmbeddings(embeddingSyncContext, nodeKind.schema);
11313
+ await deleteNodeEmbeddings(
11314
+ createEmbeddingSyncContext(ctx.graphId, kind, id, backend),
11315
+ nodeKind.schema
11316
+ );
11320
11317
  });
11321
11318
  }
11322
11319
  async function executeNodeHardDelete(ctx, kind, id, backend) {
@@ -11324,71 +11321,29 @@ async function executeNodeHardDelete(ctx, kind, id, backend) {
11324
11321
  return ctx.withOperationHooks(opContext, async () => {
11325
11322
  const registration = getNodeRegistration(ctx.graph, kind);
11326
11323
  const existing = await backend.getNode(ctx.graphId, kind, id);
11327
- if (!existing) {
11328
- return;
11329
- }
11330
- const deleteBehavior = registration.onDelete ?? "restrict";
11331
- const connectedEdges = await backend.findEdgesConnectedTo({
11332
- graphId: ctx.graphId,
11333
- nodeKind: kind,
11334
- nodeId: id
11335
- });
11336
- if (connectedEdges.length > 0) {
11337
- switch (deleteBehavior) {
11338
- case "restrict": {
11339
- const edgeKinds = [
11340
- ...new Set(connectedEdges.map((edge) => edge.kind))
11341
- ];
11342
- throw new chunk44SXEVF4_cjs.RestrictedDeleteError({
11343
- nodeKind: kind,
11344
- nodeId: id,
11345
- edgeCount: connectedEdges.length,
11346
- edgeKinds
11347
- });
11348
- }
11349
- case "cascade":
11350
- case "disconnect": {
11351
- for (const edge of connectedEdges) {
11352
- await backend.hardDeleteEdge({
11353
- graphId: ctx.graphId,
11354
- id: edge.id
11355
- });
11356
- }
11357
- break;
11358
- }
11359
- }
11360
- }
11324
+ if (!existing) return;
11325
+ await enforceDeleteBehavior(ctx, kind, id, "hard", backend, registration);
11361
11326
  const hardDelete = async (target) => {
11362
- await target.hardDeleteNode({
11363
- graphId: ctx.graphId,
11364
- kind,
11365
- id
11366
- });
11327
+ await target.hardDeleteNode({ graphId: ctx.graphId, kind, id });
11367
11328
  };
11368
11329
  await ("transaction" in backend && backend.capabilities.transactions ? backend.transaction(async (tx) => hardDelete(tx)) : hardDelete(backend));
11369
11330
  });
11370
11331
  }
11371
- function resolveConstraint(graph, kind, constraintName) {
11372
- const registration = getNodeRegistration(graph, kind);
11373
- const constraints = registration.unique ?? [];
11374
- const constraint = constraints.find((c) => c.name === constraintName);
11375
- if (constraint === void 0) {
11376
- throw new chunk44SXEVF4_cjs.NodeConstraintNotFoundError(constraintName, kind);
11377
- }
11378
- return constraint;
11379
- }
11380
11332
  async function executeNodeGetOrCreateByConstraint(ctx, kind, constraintName, props, backend, options) {
11381
11333
  const ifExists = options?.ifExists ?? "return";
11382
11334
  const registration = getNodeRegistration(ctx.graph, kind);
11383
11335
  const nodeKind = registration.type;
11384
- const validatedProps = chunk7VITUTRA_cjs.validateNodeProps(nodeKind.schema, props, {
11336
+ const validatedProps = chunkQFZ5QB2J_cjs.validateNodeProps(nodeKind.schema, props, {
11385
11337
  kind,
11386
11338
  operation: "create"
11387
11339
  });
11388
11340
  const constraint = resolveConstraint(ctx.graph, kind, constraintName);
11389
11341
  if (!checkWherePredicate(constraint, validatedProps)) {
11390
- const input = { kind, props: validatedProps };
11391
- const node = await executeNodeCreate(ctx, input, backend);
11342
+ const node = await executeNodeCreate(
11343
+ ctx,
11344
+ { kind, props: validatedProps },
11345
+ backend
11346
+ );
11392
11347
  return { node, action: "created" };
11393
11348
  }
11394
11349
  const key = computeUniqueKey(
@@ -11401,23 +11356,20 @@ async function executeNodeGetOrCreateByConstraint(ctx, kind, constraintName, pro
11401
11356
  constraint.scope,
11402
11357
  ctx.registry
11403
11358
  );
11404
- let existingUniqueRow;
11405
- for (const kindToCheck of kindsToCheck) {
11406
- const row = await backend.checkUnique({
11407
- graphId: ctx.graphId,
11408
- nodeKind: kindToCheck,
11409
- constraintName: constraint.name,
11410
- key,
11411
- includeDeleted: true
11412
- });
11413
- if (row !== void 0) {
11414
- existingUniqueRow = row;
11415
- break;
11416
- }
11417
- }
11359
+ const existingUniqueRow = await findUniqueRowAcrossKinds(
11360
+ backend,
11361
+ ctx.graphId,
11362
+ constraint.name,
11363
+ key,
11364
+ kindsToCheck,
11365
+ true
11366
+ );
11418
11367
  if (existingUniqueRow === void 0) {
11419
- const input = { kind, props: validatedProps };
11420
- const node = await executeNodeCreate(ctx, input, backend);
11368
+ const node = await executeNodeCreate(
11369
+ ctx,
11370
+ { kind, props: validatedProps },
11371
+ backend
11372
+ );
11421
11373
  return { node, action: "created" };
11422
11374
  }
11423
11375
  const existingRow = await backend.getNode(
@@ -11426,8 +11378,11 @@ async function executeNodeGetOrCreateByConstraint(ctx, kind, constraintName, pro
11426
11378
  existingUniqueRow.node_id
11427
11379
  );
11428
11380
  if (existingRow === void 0) {
11429
- const input = { kind, props: validatedProps };
11430
- const node = await executeNodeCreate(ctx, input, backend);
11381
+ const node = await executeNodeCreate(
11382
+ ctx,
11383
+ { kind, props: validatedProps },
11384
+ backend
11385
+ );
11431
11386
  return { node, action: "created" };
11432
11387
  }
11433
11388
  const isSoftDeleted = existingRow.deleted_at !== void 0;
@@ -11450,7 +11405,7 @@ async function executeNodeGetOrCreateByConstraint(ctx, kind, constraintName, pro
11450
11405
  async function executeNodeFindByConstraint(ctx, kind, constraintName, props, backend) {
11451
11406
  const registration = getNodeRegistration(ctx.graph, kind);
11452
11407
  const nodeKind = registration.type;
11453
- const validatedProps = chunk7VITUTRA_cjs.validateNodeProps(nodeKind.schema, props, {
11408
+ const validatedProps = chunkQFZ5QB2J_cjs.validateNodeProps(nodeKind.schema, props, {
11454
11409
  kind,
11455
11410
  operation: "create"
11456
11411
  });
@@ -11466,20 +11421,14 @@ async function executeNodeFindByConstraint(ctx, kind, constraintName, props, bac
11466
11421
  constraint.scope,
11467
11422
  ctx.registry
11468
11423
  );
11469
- let existingUniqueRow;
11470
- for (const kindToCheck of kindsToCheck) {
11471
- const row = await backend.checkUnique({
11472
- graphId: ctx.graphId,
11473
- nodeKind: kindToCheck,
11474
- constraintName: constraint.name,
11475
- key,
11476
- includeDeleted: false
11477
- });
11478
- if (row !== void 0) {
11479
- existingUniqueRow = row;
11480
- break;
11481
- }
11482
- }
11424
+ const existingUniqueRow = await findUniqueRowAcrossKinds(
11425
+ backend,
11426
+ ctx.graphId,
11427
+ constraint.name,
11428
+ key,
11429
+ kindsToCheck,
11430
+ false
11431
+ );
11483
11432
  if (existingUniqueRow === void 0) return void 0;
11484
11433
  const existingRow = await backend.getNode(
11485
11434
  ctx.graphId,
@@ -11490,14 +11439,10 @@ async function executeNodeFindByConstraint(ctx, kind, constraintName, props, bac
11490
11439
  return void 0;
11491
11440
  return rowToNode(existingRow);
11492
11441
  }
11493
- async function executeNodeBulkFindByConstraint(ctx, kind, constraintName, items, backend) {
11494
- if (items.length === 0) return [];
11495
- const registration = getNodeRegistration(ctx.graph, kind);
11496
- const nodeKind = registration.type;
11497
- const constraint = resolveConstraint(ctx.graph, kind, constraintName);
11442
+ function validateAndComputeKeys(nodeKind, kind, constraint, items) {
11498
11443
  const validated = [];
11499
11444
  for (const item of items) {
11500
- const validatedProps = chunk7VITUTRA_cjs.validateNodeProps(nodeKind.schema, item.props, {
11445
+ const validatedProps = chunkQFZ5QB2J_cjs.validateNodeProps(nodeKind.schema, item.props, {
11501
11446
  kind,
11502
11447
  operation: "create"
11503
11448
  });
@@ -11509,49 +11454,35 @@ async function executeNodeBulkFindByConstraint(ctx, kind, constraintName, items,
11509
11454
  ) : void 0;
11510
11455
  validated.push({ validatedProps, key });
11511
11456
  }
11512
- const uniqueKeys = [
11457
+ return validated;
11458
+ }
11459
+ function collectUniqueKeys(validated) {
11460
+ return [
11513
11461
  ...new Set(
11514
- validated.map((v) => v.key).filter((k) => k !== void 0)
11462
+ validated.map((entry) => entry.key).filter((key) => key !== void 0)
11515
11463
  )
11516
11464
  ];
11465
+ }
11466
+ async function executeNodeBulkFindByConstraint(ctx, kind, constraintName, items, backend) {
11467
+ if (items.length === 0) return [];
11468
+ const registration = getNodeRegistration(ctx.graph, kind);
11469
+ const nodeKind = registration.type;
11470
+ const constraint = resolveConstraint(ctx.graph, kind, constraintName);
11471
+ const validated = validateAndComputeKeys(nodeKind, kind, constraint, items);
11472
+ const uniqueKeys = collectUniqueKeys(validated);
11517
11473
  const kindsToCheck = getKindsForUniquenessCheck(
11518
11474
  kind,
11519
11475
  constraint.scope,
11520
11476
  ctx.registry
11521
11477
  );
11522
- const existingByKey = /* @__PURE__ */ new Map();
11523
- if (uniqueKeys.length > 0) {
11524
- for (const kindToCheck of kindsToCheck) {
11525
- if (backend.checkUniqueBatch === void 0) {
11526
- for (const key of uniqueKeys) {
11527
- if (existingByKey.has(key)) continue;
11528
- const row = await backend.checkUnique({
11529
- graphId: ctx.graphId,
11530
- nodeKind: kindToCheck,
11531
- constraintName: constraint.name,
11532
- key,
11533
- includeDeleted: false
11534
- });
11535
- if (row !== void 0) {
11536
- existingByKey.set(row.key, row);
11537
- }
11538
- }
11539
- } else {
11540
- const rows = await backend.checkUniqueBatch({
11541
- graphId: ctx.graphId,
11542
- nodeKind: kindToCheck,
11543
- constraintName: constraint.name,
11544
- keys: uniqueKeys,
11545
- includeDeleted: false
11546
- });
11547
- for (const row of rows) {
11548
- if (!existingByKey.has(row.key)) {
11549
- existingByKey.set(row.key, row);
11550
- }
11551
- }
11552
- }
11553
- }
11554
- }
11478
+ const existingByKey = uniqueKeys.length > 0 ? await batchCheckUniqueAcrossKinds(
11479
+ backend,
11480
+ ctx.graphId,
11481
+ constraint.name,
11482
+ uniqueKeys,
11483
+ kindsToCheck,
11484
+ false
11485
+ ) : /* @__PURE__ */ new Map();
11555
11486
  const results = Array.from({ length: items.length });
11556
11487
  const seenKeys = /* @__PURE__ */ new Map();
11557
11488
  for (const [index, { key }] of validated.entries()) {
@@ -11589,73 +11520,28 @@ async function executeNodeBulkGetOrCreateByConstraint(ctx, kind, constraintName,
11589
11520
  const registration = getNodeRegistration(ctx.graph, kind);
11590
11521
  const nodeKind = registration.type;
11591
11522
  const constraint = resolveConstraint(ctx.graph, kind, constraintName);
11592
- const validated = [];
11593
- for (const item of items) {
11594
- const validatedProps = chunk7VITUTRA_cjs.validateNodeProps(nodeKind.schema, item.props, {
11595
- kind,
11596
- operation: "create"
11597
- });
11598
- const applies = checkWherePredicate(constraint, validatedProps);
11599
- const key = applies ? computeUniqueKey(
11600
- validatedProps,
11601
- constraint.fields,
11602
- constraint.collation
11603
- ) : void 0;
11604
- validated.push({ validatedProps, key });
11605
- }
11606
- const uniqueKeys = [
11607
- ...new Set(
11608
- validated.map((v) => v.key).filter((k) => k !== void 0)
11609
- )
11610
- ];
11523
+ const validated = validateAndComputeKeys(nodeKind, kind, constraint, items);
11524
+ const uniqueKeys = collectUniqueKeys(validated);
11611
11525
  const kindsToCheck = getKindsForUniquenessCheck(
11612
11526
  kind,
11613
11527
  constraint.scope,
11614
11528
  ctx.registry
11615
11529
  );
11616
- const existingByKey = /* @__PURE__ */ new Map();
11617
- if (uniqueKeys.length > 0) {
11618
- for (const kindToCheck of kindsToCheck) {
11619
- if (backend.checkUniqueBatch === void 0) {
11620
- for (const key of uniqueKeys) {
11621
- if (existingByKey.has(key)) continue;
11622
- const row = await backend.checkUnique({
11623
- graphId: ctx.graphId,
11624
- nodeKind: kindToCheck,
11625
- constraintName: constraint.name,
11626
- key,
11627
- includeDeleted: true
11628
- });
11629
- if (row !== void 0) {
11630
- existingByKey.set(row.key, row);
11631
- }
11632
- }
11633
- } else {
11634
- const rows = await backend.checkUniqueBatch({
11635
- graphId: ctx.graphId,
11636
- nodeKind: kindToCheck,
11637
- constraintName: constraint.name,
11638
- keys: uniqueKeys,
11639
- includeDeleted: true
11640
- });
11641
- for (const row of rows) {
11642
- if (!existingByKey.has(row.key)) {
11643
- existingByKey.set(row.key, row);
11644
- }
11645
- }
11646
- }
11647
- }
11648
- }
11530
+ const existingByKey = uniqueKeys.length > 0 ? await batchCheckUniqueAcrossKinds(
11531
+ backend,
11532
+ ctx.graphId,
11533
+ constraint.name,
11534
+ uniqueKeys,
11535
+ kindsToCheck,
11536
+ true
11537
+ ) : /* @__PURE__ */ new Map();
11649
11538
  const toCreate = [];
11650
11539
  const toFetch = [];
11651
11540
  const duplicateOf = [];
11652
11541
  const seenKeys = /* @__PURE__ */ new Map();
11653
11542
  for (const [index, { validatedProps, key }] of validated.entries()) {
11654
11543
  if (key === void 0) {
11655
- toCreate.push({
11656
- index,
11657
- input: { kind, props: validatedProps }
11658
- });
11544
+ toCreate.push({ index, input: { kind, props: validatedProps } });
11659
11545
  continue;
11660
11546
  }
11661
11547
  const previousIndex = seenKeys.get(key);
@@ -11666,10 +11552,7 @@ async function executeNodeBulkGetOrCreateByConstraint(ctx, kind, constraintName,
11666
11552
  seenKeys.set(key, index);
11667
11553
  const existing = existingByKey.get(key);
11668
11554
  if (existing === void 0) {
11669
- toCreate.push({
11670
- index,
11671
- input: { kind, props: validatedProps }
11672
- });
11555
+ toCreate.push({ index, input: { kind, props: validatedProps } });
11673
11556
  } else {
11674
11557
  toFetch.push({
11675
11558
  index,
@@ -11703,8 +11586,11 @@ async function executeNodeBulkGetOrCreateByConstraint(ctx, kind, constraintName,
11703
11586
  nodeId
11704
11587
  );
11705
11588
  if (existingRow === void 0) {
11706
- const input = { kind, props: validatedProps };
11707
- const node = await executeNodeCreate(ctx, input, backend);
11589
+ const node = await executeNodeCreate(
11590
+ ctx,
11591
+ { kind, props: validatedProps },
11592
+ backend
11593
+ );
11708
11594
  results[index] = { node, action: "created" };
11709
11595
  continue;
11710
11596
  }
@@ -12005,7 +11891,7 @@ var Store = class {
12005
11891
  graphId: this.graphId,
12006
11892
  rootId,
12007
11893
  backend: this.#backend,
12008
- dialect: chunk2WVFEIHR_cjs.getDialect(this.#backend.dialect),
11894
+ dialect: chunkMME3H4ZF_cjs.getDialect(this.#backend.dialect),
12009
11895
  schema: this.#schema,
12010
11896
  options
12011
11897
  });
@@ -12177,13 +12063,13 @@ function createStore(graph, backend, options) {
12177
12063
  }
12178
12064
  async function createStoreWithSchema(graph, backend, options) {
12179
12065
  const store = createStore(graph, backend, options);
12180
- const result = await chunk7VITUTRA_cjs.ensureSchema(backend, graph, options);
12066
+ const result = await chunkQFZ5QB2J_cjs.ensureSchema(backend, graph, options);
12181
12067
  return [store, result];
12182
12068
  }
12183
12069
 
12184
12070
  Object.defineProperty(exports, "isMetaEdge", {
12185
12071
  enumerable: true,
12186
- get: function () { return chunk7VITUTRA_cjs.isMetaEdge; }
12072
+ get: function () { return chunkQFZ5QB2J_cjs.isMetaEdge; }
12187
12073
  });
12188
12074
  Object.defineProperty(exports, "defineGraph", {
12189
12075
  enumerable: true,