@nicia-ai/typegraph 0.4.0 → 0.6.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 (114) hide show
  1. package/README.md +2 -2
  2. package/dist/{ast-CXFx6bF6.d.ts → ast-CG87Zr6p.d.ts} +2 -2
  3. package/dist/{ast-D-3bOanX.d.cts → ast-Cq9qrnNP.d.cts} +2 -2
  4. package/dist/backend/postgres/index.cjs +295 -23
  5. package/dist/backend/postgres/index.cjs.map +1 -1
  6. package/dist/backend/postgres/index.d.cts +33 -10
  7. package/dist/backend/postgres/index.d.ts +33 -10
  8. package/dist/backend/postgres/index.js +285 -5
  9. package/dist/backend/postgres/index.js.map +1 -1
  10. package/dist/backend/sqlite/index.cjs +21 -90
  11. package/dist/backend/sqlite/index.cjs.map +1 -1
  12. package/dist/backend/sqlite/index.d.cts +22 -58
  13. package/dist/backend/sqlite/index.d.ts +22 -58
  14. package/dist/backend/sqlite/index.js +3 -78
  15. package/dist/backend/sqlite/index.js.map +1 -1
  16. package/dist/backend/sqlite/local.cjs +83 -0
  17. package/dist/backend/sqlite/local.cjs.map +1 -0
  18. package/dist/backend/sqlite/local.d.cts +66 -0
  19. package/dist/backend/sqlite/local.d.ts +66 -0
  20. package/dist/backend/sqlite/local.js +77 -0
  21. package/dist/backend/sqlite/local.js.map +1 -0
  22. package/dist/chunk-23NGZHUN.cjs +2132 -0
  23. package/dist/chunk-23NGZHUN.cjs.map +1 -0
  24. package/dist/{chunk-ZO2FRJ2U.js → chunk-2DKSQNPW.js} +3 -4
  25. package/dist/chunk-2DKSQNPW.js.map +1 -0
  26. package/dist/chunk-JPO7W262.js +2093 -0
  27. package/dist/chunk-JPO7W262.js.map +1 -0
  28. package/dist/{chunk-NYDXJGA3.cjs → chunk-K5O7TOJO.cjs} +15 -16
  29. package/dist/chunk-K5O7TOJO.cjs.map +1 -0
  30. package/dist/{backend/drizzle/schema/postgres.d.ts → ddl-Bcyb4DW1.d.cts} +17 -17
  31. package/dist/{backend/drizzle/schema/postgres.d.cts → ddl-D7DQx8w8.d.ts} +17 -17
  32. package/dist/{index-DyrR_d-H.d.cts → index-QTnQwakS.d.cts} +1 -1
  33. package/dist/{index-DyrR_d-H.d.ts → index-QTnQwakS.d.ts} +1 -1
  34. package/dist/index.cjs +238 -1
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.cts +11 -12
  37. package/dist/index.d.ts +11 -12
  38. package/dist/index.js +238 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/indexes/index.d.cts +5 -6
  41. package/dist/indexes/index.d.ts +5 -6
  42. package/dist/interchange/index.d.cts +5 -6
  43. package/dist/interchange/index.d.ts +5 -6
  44. package/dist/{manager-0NysX4s6.d.cts → manager-BImRiYwz.d.cts} +3 -3
  45. package/dist/{manager-DFKe7ql3.d.ts → manager-DGQ9UF18.d.ts} +3 -3
  46. package/dist/profiler/index.d.cts +7 -8
  47. package/dist/profiler/index.d.ts +7 -8
  48. package/dist/schema/index.d.cts +6 -7
  49. package/dist/schema/index.d.ts +6 -7
  50. package/dist/{backend/drizzle/schema/sqlite.d.ts → sqlite-CSJ-fgIm.d.ts} +2 -25
  51. package/dist/{backend/drizzle/schema/sqlite.d.cts → sqlite-FWGZLwDd.d.cts} +2 -25
  52. package/dist/{store-SiovWEYA.d.ts → store-CscQUG-S.d.ts} +57 -6
  53. package/dist/{store-DhoA5uRc.d.cts → store-DNv1yd3n.d.cts} +57 -6
  54. package/dist/{types-DHRsi6j9.d.cts → types-BbMn2Ycv.d.cts} +2 -2
  55. package/dist/{types-ZT5mlism.d.ts → types-C2rhqkg7.d.ts} +2 -2
  56. package/dist/{types-6EKrWTs9.d.ts → types-D5ggX07j.d.ts} +7 -3
  57. package/dist/{types-BL1GyVku.d.cts → types-DEMAqkA1.d.cts} +1 -1
  58. package/dist/{types-DCGa53O2.d.ts → types-DJZoHy5R.d.ts} +1 -1
  59. package/dist/{types-DTJEu_-h.d.ts → types-DolHw9pJ.d.cts} +14 -1
  60. package/dist/{types-DTJEu_-h.d.cts → types-DolHw9pJ.d.ts} +14 -1
  61. package/dist/{types-BUy-pHKH.d.cts → types-SVDEKnU6.d.cts} +7 -3
  62. package/package.json +6 -46
  63. package/dist/backend/drizzle/index.cjs +0 -40
  64. package/dist/backend/drizzle/index.cjs.map +0 -1
  65. package/dist/backend/drizzle/index.d.cts +0 -13
  66. package/dist/backend/drizzle/index.d.ts +0 -13
  67. package/dist/backend/drizzle/index.js +0 -11
  68. package/dist/backend/drizzle/index.js.map +0 -1
  69. package/dist/backend/drizzle/postgres.cjs +0 -26
  70. package/dist/backend/drizzle/postgres.cjs.map +0 -1
  71. package/dist/backend/drizzle/postgres.d.cts +0 -35
  72. package/dist/backend/drizzle/postgres.d.ts +0 -35
  73. package/dist/backend/drizzle/postgres.js +0 -9
  74. package/dist/backend/drizzle/postgres.js.map +0 -1
  75. package/dist/backend/drizzle/schema/postgres.cjs +0 -39
  76. package/dist/backend/drizzle/schema/postgres.cjs.map +0 -1
  77. package/dist/backend/drizzle/schema/postgres.js +0 -6
  78. package/dist/backend/drizzle/schema/postgres.js.map +0 -1
  79. package/dist/backend/drizzle/schema/sqlite.cjs +0 -39
  80. package/dist/backend/drizzle/schema/sqlite.cjs.map +0 -1
  81. package/dist/backend/drizzle/schema/sqlite.js +0 -6
  82. package/dist/backend/drizzle/schema/sqlite.js.map +0 -1
  83. package/dist/backend/drizzle/sqlite.cjs +0 -26
  84. package/dist/backend/drizzle/sqlite.cjs.map +0 -1
  85. package/dist/backend/drizzle/sqlite.d.cts +0 -35
  86. package/dist/backend/drizzle/sqlite.d.ts +0 -35
  87. package/dist/backend/drizzle/sqlite.js +0 -9
  88. package/dist/backend/drizzle/sqlite.js.map +0 -1
  89. package/dist/chunk-3PURVEA4.js +0 -193
  90. package/dist/chunk-3PURVEA4.js.map +0 -1
  91. package/dist/chunk-7RVSDXT3.cjs +0 -1509
  92. package/dist/chunk-7RVSDXT3.cjs.map +0 -1
  93. package/dist/chunk-LUARLSYT.cjs +0 -289
  94. package/dist/chunk-LUARLSYT.cjs.map +0 -1
  95. package/dist/chunk-NU2XNMVI.cjs +0 -201
  96. package/dist/chunk-NU2XNMVI.cjs.map +0 -1
  97. package/dist/chunk-NYDXJGA3.cjs.map +0 -1
  98. package/dist/chunk-OGGLFYFA.js +0 -177
  99. package/dist/chunk-OGGLFYFA.js.map +0 -1
  100. package/dist/chunk-Q6PXIKRQ.js +0 -287
  101. package/dist/chunk-Q6PXIKRQ.js.map +0 -1
  102. package/dist/chunk-SMLIWLS7.js +0 -236
  103. package/dist/chunk-SMLIWLS7.js.map +0 -1
  104. package/dist/chunk-UYMT4LO2.cjs +0 -241
  105. package/dist/chunk-UYMT4LO2.cjs.map +0 -1
  106. package/dist/chunk-XZL6MCZJ.cjs +0 -185
  107. package/dist/chunk-XZL6MCZJ.cjs.map +0 -1
  108. package/dist/chunk-ZO2FRJ2U.js.map +0 -1
  109. package/dist/chunk-ZQGOBVXZ.js +0 -1488
  110. package/dist/chunk-ZQGOBVXZ.js.map +0 -1
  111. package/dist/test-helpers-CIq1Hhj1.d.ts +0 -26
  112. package/dist/test-helpers-DPRFVky4.d.cts +0 -26
  113. package/dist/types-BRzHlhKC.d.cts +0 -14
  114. package/dist/types-BRzHlhKC.d.ts +0 -14
@@ -0,0 +1,2093 @@
1
+ import { DatabaseOperationError, UniquenessError } from './chunk-SJ2QMDXY.js';
2
+ import { buildSqliteNodeIndexBuilders, buildSqliteEdgeIndexBuilders, buildPostgresNodeIndexBuilders, buildPostgresEdgeIndexBuilders } from './chunk-U3452TEU.js';
3
+ import { sqliteTable, text, integer, primaryKey, index, blob, getTableConfig } from 'drizzle-orm/sqlite-core';
4
+ import { customType, pgTable, timestamp, integer as integer$1, jsonb, text as text$1, primaryKey as primaryKey$1, index as index$1, boolean, getTableConfig as getTableConfig$1 } from 'drizzle-orm/pg-core';
5
+ import { sql, getTableName } from 'drizzle-orm';
6
+
7
+ var DEFAULT_TABLE_NAMES = {
8
+ nodes: "typegraph_nodes",
9
+ edges: "typegraph_edges",
10
+ uniques: "typegraph_node_uniques",
11
+ schemaVersions: "typegraph_schema_versions",
12
+ embeddings: "typegraph_node_embeddings"
13
+ };
14
+ function createSqliteTables(names = {}, options = {}) {
15
+ const n = { ...DEFAULT_TABLE_NAMES, ...names };
16
+ const indexes = options.indexes ?? [];
17
+ const nodes3 = sqliteTable(
18
+ n.nodes,
19
+ {
20
+ graphId: text("graph_id").notNull(),
21
+ kind: text("kind").notNull(),
22
+ id: text("id").notNull(),
23
+ props: text("props").notNull(),
24
+ version: integer("version").notNull().default(1),
25
+ validFrom: text("valid_from"),
26
+ validTo: text("valid_to"),
27
+ createdAt: text("created_at").notNull(),
28
+ updatedAt: text("updated_at").notNull(),
29
+ deletedAt: text("deleted_at")
30
+ },
31
+ (t) => [
32
+ primaryKey({ columns: [t.graphId, t.kind, t.id] }),
33
+ index(`${n.nodes}_kind_idx`).on(t.graphId, t.kind),
34
+ index(`${n.nodes}_kind_created_idx`).on(
35
+ t.graphId,
36
+ t.kind,
37
+ t.deletedAt,
38
+ t.createdAt
39
+ ),
40
+ index(`${n.nodes}_deleted_idx`).on(t.graphId, t.deletedAt),
41
+ index(`${n.nodes}_valid_idx`).on(t.graphId, t.validFrom, t.validTo),
42
+ ...buildSqliteNodeIndexBuilders(t, indexes)
43
+ ]
44
+ );
45
+ const edges3 = sqliteTable(
46
+ n.edges,
47
+ {
48
+ graphId: text("graph_id").notNull(),
49
+ id: text("id").notNull(),
50
+ kind: text("kind").notNull(),
51
+ fromKind: text("from_kind").notNull(),
52
+ fromId: text("from_id").notNull(),
53
+ toKind: text("to_kind").notNull(),
54
+ toId: text("to_id").notNull(),
55
+ props: text("props").notNull(),
56
+ validFrom: text("valid_from"),
57
+ validTo: text("valid_to"),
58
+ createdAt: text("created_at").notNull(),
59
+ updatedAt: text("updated_at").notNull(),
60
+ deletedAt: text("deleted_at")
61
+ },
62
+ (t) => [
63
+ primaryKey({ columns: [t.graphId, t.id] }),
64
+ index(`${n.edges}_kind_idx`).on(t.graphId, t.kind),
65
+ // Directional traversal index (outgoing): supports endpoint lookups
66
+ // and extra filtering by edge kind / target kind.
67
+ index(`${n.edges}_from_idx`).on(
68
+ t.graphId,
69
+ t.fromKind,
70
+ t.fromId,
71
+ t.kind,
72
+ t.toKind,
73
+ t.deletedAt,
74
+ t.validTo
75
+ ),
76
+ // Directional traversal index (incoming): mirrors from_idx for reverse traversals.
77
+ index(`${n.edges}_to_idx`).on(
78
+ t.graphId,
79
+ t.toKind,
80
+ t.toId,
81
+ t.kind,
82
+ t.fromKind,
83
+ t.deletedAt,
84
+ t.validTo
85
+ ),
86
+ index(`${n.edges}_kind_created_idx`).on(
87
+ t.graphId,
88
+ t.kind,
89
+ t.deletedAt,
90
+ t.createdAt
91
+ ),
92
+ index(`${n.edges}_deleted_idx`).on(t.graphId, t.deletedAt),
93
+ index(`${n.edges}_valid_idx`).on(t.graphId, t.validFrom, t.validTo),
94
+ index(`${n.edges}_cardinality_idx`).on(
95
+ t.graphId,
96
+ t.kind,
97
+ t.fromKind,
98
+ t.fromId,
99
+ t.validTo
100
+ ),
101
+ ...buildSqliteEdgeIndexBuilders(t, indexes)
102
+ ]
103
+ );
104
+ const uniques3 = sqliteTable(
105
+ n.uniques,
106
+ {
107
+ graphId: text("graph_id").notNull(),
108
+ nodeKind: text("node_kind").notNull(),
109
+ constraintName: text("constraint_name").notNull(),
110
+ key: text("key").notNull(),
111
+ nodeId: text("node_id").notNull(),
112
+ concreteKind: text("concrete_kind").notNull(),
113
+ deletedAt: text("deleted_at")
114
+ },
115
+ (t) => [
116
+ primaryKey({
117
+ columns: [t.graphId, t.nodeKind, t.constraintName, t.key]
118
+ }),
119
+ index(`${n.uniques}_node_idx`).on(t.graphId, t.concreteKind, t.nodeId)
120
+ ]
121
+ );
122
+ const schemaVersions3 = sqliteTable(
123
+ n.schemaVersions,
124
+ {
125
+ graphId: text("graph_id").notNull(),
126
+ version: integer("version").notNull(),
127
+ schemaHash: text("schema_hash").notNull(),
128
+ schemaDoc: text("schema_doc").notNull(),
129
+ createdAt: text("created_at").notNull(),
130
+ isActive: integer("is_active", { mode: "boolean" }).notNull().default(false)
131
+ },
132
+ (t) => [
133
+ primaryKey({ columns: [t.graphId, t.version] }),
134
+ index(`${n.schemaVersions}_active_idx`).on(t.graphId, t.isActive)
135
+ ]
136
+ );
137
+ const embeddings3 = sqliteTable(
138
+ n.embeddings,
139
+ {
140
+ graphId: text("graph_id").notNull(),
141
+ nodeKind: text("node_kind").notNull(),
142
+ nodeId: text("node_id").notNull(),
143
+ fieldPath: text("field_path").notNull(),
144
+ /**
145
+ * Embedding vector.
146
+ * Stored as BLOB for sqlite-vec binary format, or JSON text for fallback.
147
+ * For sqlite-vec: use vec_f32() to convert JSON array to binary.
148
+ */
149
+ embedding: blob("embedding", { mode: "buffer" }).notNull(),
150
+ /** Number of dimensions (for validation) */
151
+ dimensions: integer("dimensions").notNull(),
152
+ createdAt: text("created_at").notNull(),
153
+ updatedAt: text("updated_at").notNull()
154
+ },
155
+ (t) => [
156
+ primaryKey({
157
+ columns: [t.graphId, t.nodeKind, t.nodeId, t.fieldPath]
158
+ }),
159
+ // Index for looking up embeddings by node
160
+ index(`${n.embeddings}_node_idx`).on(
161
+ t.graphId,
162
+ t.nodeKind,
163
+ t.nodeId
164
+ ),
165
+ // Index for filtering by kind and field (used in vector search)
166
+ index(`${n.embeddings}_kind_field_idx`).on(
167
+ t.graphId,
168
+ t.nodeKind,
169
+ t.fieldPath
170
+ )
171
+ ]
172
+ );
173
+ return { nodes: nodes3, edges: edges3, uniques: uniques3, schemaVersions: schemaVersions3, embeddings: embeddings3 };
174
+ }
175
+ var tables = createSqliteTables();
176
+ var { nodes, edges, uniques, schemaVersions, embeddings } = tables;
177
+ var vector = customType({
178
+ dataType(config) {
179
+ return config?.dimensions ? `vector(${config.dimensions})` : "vector";
180
+ },
181
+ toDriver(value) {
182
+ return `[${value.join(",")}]`;
183
+ },
184
+ fromDriver(value) {
185
+ if (Array.isArray(value)) {
186
+ return value;
187
+ }
188
+ const content = value.slice(1, -1);
189
+ if (content === "") {
190
+ return [];
191
+ }
192
+ return content.split(",").map((s) => Number.parseFloat(s.trim()));
193
+ }
194
+ });
195
+
196
+ // src/backend/drizzle/schema/postgres.ts
197
+ var DEFAULT_TABLE_NAMES2 = {
198
+ nodes: "typegraph_nodes",
199
+ edges: "typegraph_edges",
200
+ uniques: "typegraph_node_uniques",
201
+ schemaVersions: "typegraph_schema_versions",
202
+ embeddings: "typegraph_node_embeddings"
203
+ };
204
+ function createPostgresTables(names = {}, options = {}) {
205
+ const n = { ...DEFAULT_TABLE_NAMES2, ...names };
206
+ const indexes = options.indexes ?? [];
207
+ const nodes3 = pgTable(
208
+ n.nodes,
209
+ {
210
+ graphId: text$1("graph_id").notNull(),
211
+ kind: text$1("kind").notNull(),
212
+ id: text$1("id").notNull(),
213
+ props: jsonb("props").notNull(),
214
+ version: integer$1("version").notNull().default(1),
215
+ validFrom: timestamp("valid_from", { withTimezone: true }),
216
+ validTo: timestamp("valid_to", { withTimezone: true }),
217
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull(),
218
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull(),
219
+ deletedAt: timestamp("deleted_at", { withTimezone: true })
220
+ },
221
+ (t) => [
222
+ primaryKey$1({ columns: [t.graphId, t.kind, t.id] }),
223
+ index$1(`${n.nodes}_kind_idx`).on(t.graphId, t.kind),
224
+ index$1(`${n.nodes}_kind_created_idx`).on(
225
+ t.graphId,
226
+ t.kind,
227
+ t.deletedAt,
228
+ t.createdAt
229
+ ),
230
+ index$1(`${n.nodes}_deleted_idx`).on(t.graphId, t.deletedAt),
231
+ index$1(`${n.nodes}_valid_idx`).on(t.graphId, t.validFrom, t.validTo),
232
+ ...buildPostgresNodeIndexBuilders(t, indexes)
233
+ ]
234
+ );
235
+ const edges3 = pgTable(
236
+ n.edges,
237
+ {
238
+ graphId: text$1("graph_id").notNull(),
239
+ id: text$1("id").notNull(),
240
+ kind: text$1("kind").notNull(),
241
+ fromKind: text$1("from_kind").notNull(),
242
+ fromId: text$1("from_id").notNull(),
243
+ toKind: text$1("to_kind").notNull(),
244
+ toId: text$1("to_id").notNull(),
245
+ props: jsonb("props").notNull(),
246
+ validFrom: timestamp("valid_from", { withTimezone: true }),
247
+ validTo: timestamp("valid_to", { withTimezone: true }),
248
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull(),
249
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull(),
250
+ deletedAt: timestamp("deleted_at", { withTimezone: true })
251
+ },
252
+ (t) => [
253
+ primaryKey$1({ columns: [t.graphId, t.id] }),
254
+ index$1(`${n.edges}_kind_idx`).on(t.graphId, t.kind),
255
+ // Directional traversal index (outgoing): supports endpoint lookups
256
+ // and extra filtering by edge kind / target kind.
257
+ index$1(`${n.edges}_from_idx`).on(
258
+ t.graphId,
259
+ t.fromKind,
260
+ t.fromId,
261
+ t.kind,
262
+ t.toKind,
263
+ t.deletedAt,
264
+ t.validTo
265
+ ),
266
+ // Directional traversal index (incoming): mirrors from_idx for reverse traversals.
267
+ index$1(`${n.edges}_to_idx`).on(
268
+ t.graphId,
269
+ t.toKind,
270
+ t.toId,
271
+ t.kind,
272
+ t.fromKind,
273
+ t.deletedAt,
274
+ t.validTo
275
+ ),
276
+ index$1(`${n.edges}_kind_created_idx`).on(
277
+ t.graphId,
278
+ t.kind,
279
+ t.deletedAt,
280
+ t.createdAt
281
+ ),
282
+ index$1(`${n.edges}_deleted_idx`).on(t.graphId, t.deletedAt),
283
+ index$1(`${n.edges}_valid_idx`).on(t.graphId, t.validFrom, t.validTo),
284
+ index$1(`${n.edges}_cardinality_idx`).on(
285
+ t.graphId,
286
+ t.kind,
287
+ t.fromKind,
288
+ t.fromId,
289
+ t.validTo
290
+ ),
291
+ ...buildPostgresEdgeIndexBuilders(t, indexes)
292
+ ]
293
+ );
294
+ const uniques3 = pgTable(
295
+ n.uniques,
296
+ {
297
+ graphId: text$1("graph_id").notNull(),
298
+ nodeKind: text$1("node_kind").notNull(),
299
+ constraintName: text$1("constraint_name").notNull(),
300
+ key: text$1("key").notNull(),
301
+ nodeId: text$1("node_id").notNull(),
302
+ concreteKind: text$1("concrete_kind").notNull(),
303
+ deletedAt: timestamp("deleted_at", { withTimezone: true })
304
+ },
305
+ (t) => [
306
+ primaryKey$1({
307
+ columns: [t.graphId, t.nodeKind, t.constraintName, t.key]
308
+ }),
309
+ index$1(`${n.uniques}_node_idx`).on(t.graphId, t.concreteKind, t.nodeId)
310
+ ]
311
+ );
312
+ const schemaVersions3 = pgTable(
313
+ n.schemaVersions,
314
+ {
315
+ graphId: text$1("graph_id").notNull(),
316
+ version: integer$1("version").notNull(),
317
+ schemaHash: text$1("schema_hash").notNull(),
318
+ schemaDoc: jsonb("schema_doc").notNull(),
319
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull(),
320
+ isActive: boolean("is_active").notNull().default(false)
321
+ },
322
+ (t) => [
323
+ primaryKey$1({ columns: [t.graphId, t.version] }),
324
+ index$1(`${n.schemaVersions}_active_idx`).on(t.graphId, t.isActive)
325
+ ]
326
+ );
327
+ const embeddings3 = pgTable(
328
+ n.embeddings,
329
+ {
330
+ graphId: text$1("graph_id").notNull(),
331
+ nodeKind: text$1("node_kind").notNull(),
332
+ nodeId: text$1("node_id").notNull(),
333
+ fieldPath: text$1("field_path").notNull(),
334
+ /** Embedding vector stored as native pgvector type */
335
+ embedding: vector("embedding").notNull(),
336
+ /** Number of dimensions (for validation) */
337
+ dimensions: integer$1("dimensions").notNull(),
338
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull(),
339
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull()
340
+ },
341
+ (t) => [
342
+ primaryKey$1({
343
+ columns: [t.graphId, t.nodeKind, t.nodeId, t.fieldPath]
344
+ }),
345
+ // Index for looking up embeddings by node
346
+ index$1(`${n.embeddings}_node_idx`).on(
347
+ t.graphId,
348
+ t.nodeKind,
349
+ t.nodeId
350
+ ),
351
+ // Index for filtering by kind and field (used in vector search)
352
+ index$1(`${n.embeddings}_kind_field_idx`).on(
353
+ t.graphId,
354
+ t.nodeKind,
355
+ t.fieldPath
356
+ )
357
+ ]
358
+ );
359
+ return { nodes: nodes3, edges: edges3, uniques: uniques3, schemaVersions: schemaVersions3, embeddings: embeddings3 };
360
+ }
361
+ var tables2 = createPostgresTables();
362
+ var { nodes: nodes2, edges: edges2, uniques: uniques2, schemaVersions: schemaVersions2, embeddings: embeddings2 } = tables2;
363
+ function getSqliteColumnType(column) {
364
+ switch (column.columnType) {
365
+ case "SQLiteText": {
366
+ return "TEXT";
367
+ }
368
+ case "SQLiteInteger": {
369
+ return "INTEGER";
370
+ }
371
+ case "SQLiteReal": {
372
+ return "REAL";
373
+ }
374
+ case "SQLiteBlob": {
375
+ return "BLOB";
376
+ }
377
+ default: {
378
+ return "TEXT";
379
+ }
380
+ }
381
+ }
382
+ function formatDefaultValue(value) {
383
+ if (value === null) return "NULL";
384
+ if (typeof value === "string") return `'${value}'`;
385
+ if (typeof value === "number") return String(value);
386
+ if (typeof value === "boolean") return value ? "1" : "0";
387
+ return JSON.stringify(value);
388
+ }
389
+ function generateSqliteCreateTableSQL(table) {
390
+ const config = getTableConfig(table);
391
+ const columnDefs = [];
392
+ for (const column of config.columns) {
393
+ const parts = [
394
+ `"${column.name}"`,
395
+ getSqliteColumnType(column)
396
+ ];
397
+ if (column.notNull) {
398
+ parts.push("NOT NULL");
399
+ }
400
+ if (column.hasDefault && column.default !== void 0) {
401
+ parts.push(`DEFAULT ${formatDefaultValue(column.default)}`);
402
+ }
403
+ columnDefs.push(parts.join(" "));
404
+ }
405
+ const pk = config.primaryKeys[0];
406
+ if (pk) {
407
+ const pkColumns = pk.columns.map((c) => `"${c.name}"`).join(", ");
408
+ columnDefs.push(`PRIMARY KEY (${pkColumns})`);
409
+ }
410
+ return `CREATE TABLE IF NOT EXISTS "${config.name}" (
411
+ ${columnDefs.join(",\n ")}
412
+ );`;
413
+ }
414
+ function renderIndexColumn(col) {
415
+ if (col && typeof col === "object" && "name" in col) {
416
+ return `"${col.name}"`;
417
+ }
418
+ const sql10 = tryInlineSql(col);
419
+ if (sql10 !== void 0) {
420
+ return sql10;
421
+ }
422
+ return "unknown";
423
+ }
424
+ function tryInlineSql(value) {
425
+ if (value && typeof value === "object" && "getSQL" in value) {
426
+ const maybe = value;
427
+ if (typeof maybe.getSQL === "function") {
428
+ return inlineSql(maybe.getSQL());
429
+ }
430
+ }
431
+ return inlineSql(value);
432
+ }
433
+ function flattenSqlChunk(chunk) {
434
+ if (typeof chunk === "string") {
435
+ return chunk;
436
+ }
437
+ if (typeof chunk === "object" && chunk !== null) {
438
+ if ("value" in chunk && Array.isArray(chunk.value)) {
439
+ return chunk.value.map((part) => flattenSqlChunk(part)).join("");
440
+ }
441
+ if ("queryChunks" in chunk && Array.isArray(chunk.queryChunks)) {
442
+ return chunk.queryChunks.map((part) => flattenSqlChunk(part)).join("");
443
+ }
444
+ if ("getSQL" in chunk) {
445
+ const maybe = chunk;
446
+ if (typeof maybe.getSQL === "function") {
447
+ return flattenSqlChunk(maybe.getSQL());
448
+ }
449
+ }
450
+ }
451
+ throw new Error(`Unable to inline SQL chunk: ${String(chunk)}`);
452
+ }
453
+ function inlineSql(value) {
454
+ try {
455
+ return flattenSqlChunk(value);
456
+ } catch {
457
+ return void 0;
458
+ }
459
+ }
460
+ function inlineSqlOrThrow(value, context) {
461
+ const inlined = inlineSql(value);
462
+ if (inlined === void 0) {
463
+ throw new Error(`Unable to inline SQL for ${context}`);
464
+ }
465
+ return inlined;
466
+ }
467
+ function generateSqliteCreateIndexSQL(table) {
468
+ const config = getTableConfig(table);
469
+ const statements = [];
470
+ for (const index3 of config.indexes) {
471
+ const indexConfig = index3.config;
472
+ const columns = indexConfig.columns.map((c) => renderIndexColumn(c)).join(", ");
473
+ const unique = indexConfig.unique ? "UNIQUE " : "";
474
+ const where = indexConfig.where ? ` WHERE ${inlineSqlOrThrow(indexConfig.where, `SQLite index "${indexConfig.name}" WHERE clause`)}` : "";
475
+ statements.push(
476
+ `CREATE ${unique}INDEX IF NOT EXISTS "${indexConfig.name}" ON "${config.name}" (${columns})${where};`
477
+ );
478
+ }
479
+ return statements;
480
+ }
481
+ function generateSqliteDDL(tables3 = tables) {
482
+ const statements = [];
483
+ for (const table of Object.values(tables3)) {
484
+ statements.push(generateSqliteCreateTableSQL(table));
485
+ }
486
+ for (const table of Object.values(tables3)) {
487
+ statements.push(...generateSqliteCreateIndexSQL(table));
488
+ }
489
+ return statements;
490
+ }
491
+ function generateSqliteMigrationSQL(tables3 = tables) {
492
+ return generateSqliteDDL(tables3).join("\n\n");
493
+ }
494
+ function getPgColumnType(column) {
495
+ switch (column.columnType) {
496
+ case "PgText": {
497
+ return "TEXT";
498
+ }
499
+ case "PgInteger": {
500
+ return "INTEGER";
501
+ }
502
+ case "PgBoolean": {
503
+ return "BOOLEAN";
504
+ }
505
+ case "PgJsonb": {
506
+ return "JSONB";
507
+ }
508
+ case "PgTimestamp": {
509
+ return column.config?.withTimezone ? "TIMESTAMPTZ" : "TIMESTAMP";
510
+ }
511
+ case "PgReal": {
512
+ return "REAL";
513
+ }
514
+ case "PgDoublePrecision": {
515
+ return "DOUBLE PRECISION";
516
+ }
517
+ case "PgCustomColumn": {
518
+ const dataType = column.getSQLType?.();
519
+ return dataType ?? "TEXT";
520
+ }
521
+ default: {
522
+ return "TEXT";
523
+ }
524
+ }
525
+ }
526
+ function formatPgDefaultValue(value) {
527
+ if (value === null) return "NULL";
528
+ if (typeof value === "string") return `'${value}'`;
529
+ if (typeof value === "number") return String(value);
530
+ if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
531
+ return JSON.stringify(value);
532
+ }
533
+ function generatePgCreateTableSQL(table) {
534
+ const config = getTableConfig$1(table);
535
+ const columnDefs = [];
536
+ for (const column of config.columns) {
537
+ const parts = [
538
+ `"${column.name}"`,
539
+ getPgColumnType(column)
540
+ ];
541
+ if (column.notNull) {
542
+ parts.push("NOT NULL");
543
+ }
544
+ if (column.hasDefault && column.default !== void 0) {
545
+ parts.push(`DEFAULT ${formatPgDefaultValue(column.default)}`);
546
+ }
547
+ columnDefs.push(parts.join(" "));
548
+ }
549
+ const pk = config.primaryKeys[0];
550
+ if (pk) {
551
+ const pkColumns = pk.columns.map((c) => `"${c.name}"`).join(", ");
552
+ columnDefs.push(`PRIMARY KEY (${pkColumns})`);
553
+ }
554
+ return `CREATE TABLE IF NOT EXISTS "${config.name}" (
555
+ ${columnDefs.join(",\n ")}
556
+ );`;
557
+ }
558
+ function generatePgCreateIndexSQL(table) {
559
+ const config = getTableConfig$1(table);
560
+ const statements = [];
561
+ for (const index3 of config.indexes) {
562
+ const indexConfig = index3.config;
563
+ const columns = indexConfig.columns.map((c) => renderIndexColumn(c)).join(", ");
564
+ const unique = indexConfig.unique ? "UNIQUE " : "";
565
+ const method = indexConfig.method && indexConfig.method !== "btree" ? ` USING ${indexConfig.method}` : "";
566
+ const where = indexConfig.where ? ` WHERE ${inlineSqlOrThrow(indexConfig.where, `PostgreSQL index "${indexConfig.name}" WHERE clause`)}` : "";
567
+ statements.push(
568
+ `CREATE ${unique}INDEX IF NOT EXISTS "${indexConfig.name}" ON "${config.name}"${method} (${columns})${where};`
569
+ );
570
+ }
571
+ return statements;
572
+ }
573
+ function generatePostgresDDL(tables3 = tables2) {
574
+ const statements = [];
575
+ for (const table of Object.values(tables3)) {
576
+ statements.push(generatePgCreateTableSQL(table));
577
+ }
578
+ for (const table of Object.values(tables3)) {
579
+ statements.push(...generatePgCreateIndexSQL(table));
580
+ }
581
+ return statements;
582
+ }
583
+ function generatePostgresMigrationSQL(tables3 = tables2) {
584
+ const extensionSql = "-- Enable pgvector extension for vector similarity search\nCREATE EXTENSION IF NOT EXISTS vector;";
585
+ const ddlSql = generatePostgresDDL(tables3).join("\n\n");
586
+ return `${extensionSql}
587
+
588
+ ${ddlSql}`;
589
+ }
590
+
591
+ // src/backend/types.ts
592
+ var SQLITE_CAPABILITIES = {
593
+ jsonb: false,
594
+ // SQLite uses TEXT with json functions
595
+ partialIndexes: true,
596
+ // SQLite supports WHERE in CREATE INDEX
597
+ ginIndexes: false,
598
+ // SQLite doesn't have GIN
599
+ cte: true,
600
+ // SQLite supports WITH
601
+ returning: true,
602
+ // SQLite 3.35+ supports RETURNING
603
+ transactions: true
604
+ // SQLite supports transactions
605
+ };
606
+ var POSTGRES_CAPABILITIES = {
607
+ jsonb: true,
608
+ // PostgreSQL has native JSONB
609
+ partialIndexes: true,
610
+ ginIndexes: true,
611
+ cte: true,
612
+ returning: true,
613
+ transactions: true
614
+ // PostgreSQL supports transactions
615
+ };
616
+ var D1_CAPABILITIES = {
617
+ jsonb: false,
618
+ // D1 uses TEXT with json functions
619
+ partialIndexes: true,
620
+ ginIndexes: false,
621
+ cte: true,
622
+ returning: true,
623
+ transactions: false
624
+ // D1 does NOT support atomic transactions
625
+ };
626
+
627
+ // src/backend/drizzle/row-mappers.ts
628
+ function requireTimestamp(value, field) {
629
+ if (value === void 0) {
630
+ throw new DatabaseOperationError(
631
+ `Expected non-null ${field} timestamp`,
632
+ { operation: "select", entity: "row" }
633
+ );
634
+ }
635
+ return value;
636
+ }
637
+ function nowIso() {
638
+ return (/* @__PURE__ */ new Date()).toISOString();
639
+ }
640
+ function nullToUndefined(value) {
641
+ return value ?? void 0;
642
+ }
643
+ function formatPostgresTimestamp(value) {
644
+ if (value === null || value === void 0) return void 0;
645
+ if (value instanceof Date) return value.toISOString();
646
+ if (typeof value === "string") {
647
+ if (value.includes("T")) return value;
648
+ const date = new Date(value);
649
+ if (!Number.isNaN(date.getTime())) return date.toISOString();
650
+ return value;
651
+ }
652
+ return void 0;
653
+ }
654
+ function normalizeJsonColumn(value) {
655
+ return typeof value === "string" ? value : JSON.stringify(value ?? {});
656
+ }
657
+ var SQLITE_ROW_MAPPER_CONFIG = {
658
+ formatTimestamp: (value) => nullToUndefined(value),
659
+ normalizeJson: (value) => value
660
+ };
661
+ var POSTGRES_ROW_MAPPER_CONFIG = {
662
+ formatTimestamp: formatPostgresTimestamp,
663
+ normalizeJson: normalizeJsonColumn
664
+ };
665
+ function createNodeRowMapper(config) {
666
+ return (row) => ({
667
+ graph_id: row.graph_id,
668
+ kind: row.kind,
669
+ id: row.id,
670
+ props: config.normalizeJson(row.props),
671
+ version: row.version,
672
+ valid_from: nullToUndefined(config.formatTimestamp(row.valid_from)),
673
+ valid_to: nullToUndefined(config.formatTimestamp(row.valid_to)),
674
+ created_at: requireTimestamp(config.formatTimestamp(row.created_at), "created_at"),
675
+ updated_at: requireTimestamp(config.formatTimestamp(row.updated_at), "updated_at"),
676
+ deleted_at: nullToUndefined(config.formatTimestamp(row.deleted_at))
677
+ });
678
+ }
679
+ function createEdgeRowMapper(config) {
680
+ return (row) => ({
681
+ graph_id: row.graph_id,
682
+ id: row.id,
683
+ kind: row.kind,
684
+ from_kind: row.from_kind,
685
+ from_id: row.from_id,
686
+ to_kind: row.to_kind,
687
+ to_id: row.to_id,
688
+ props: config.normalizeJson(row.props),
689
+ valid_from: nullToUndefined(config.formatTimestamp(row.valid_from)),
690
+ valid_to: nullToUndefined(config.formatTimestamp(row.valid_to)),
691
+ created_at: requireTimestamp(config.formatTimestamp(row.created_at), "created_at"),
692
+ updated_at: requireTimestamp(config.formatTimestamp(row.updated_at), "updated_at"),
693
+ deleted_at: nullToUndefined(config.formatTimestamp(row.deleted_at))
694
+ });
695
+ }
696
+ function createUniqueRowMapper(config) {
697
+ return (row) => ({
698
+ graph_id: row.graph_id,
699
+ node_kind: row.node_kind,
700
+ constraint_name: row.constraint_name,
701
+ key: row.key,
702
+ node_id: row.node_id,
703
+ concrete_kind: row.concrete_kind,
704
+ deleted_at: nullToUndefined(config.formatTimestamp(row.deleted_at))
705
+ });
706
+ }
707
+ function createSchemaVersionRowMapper(config) {
708
+ return (row) => {
709
+ const isActiveValue = row.is_active;
710
+ const isActive = isActiveValue === true || isActiveValue === 1 || isActiveValue === "1";
711
+ return {
712
+ graph_id: row.graph_id,
713
+ version: row.version,
714
+ schema_hash: row.schema_hash,
715
+ schema_doc: config.normalizeJson(row.schema_doc),
716
+ created_at: requireTimestamp(config.formatTimestamp(row.created_at), "created_at"),
717
+ is_active: isActive
718
+ };
719
+ };
720
+ }
721
+
722
+ // src/backend/drizzle/operation-backend-core.ts
723
+ function chunkArray(values, size) {
724
+ if (values.length <= size) {
725
+ return [values];
726
+ }
727
+ const chunks = [];
728
+ for (let index3 = 0; index3 < values.length; index3 += size) {
729
+ chunks.push(values.slice(index3, index3 + size));
730
+ }
731
+ return chunks;
732
+ }
733
+ function createCommonOperationBackend(options) {
734
+ const { batchConfig, execution, operationStrategy, rowMappers } = options;
735
+ const nowIso2 = options.nowIso ?? nowIso;
736
+ return {
737
+ async insertNode(params) {
738
+ const timestamp2 = nowIso2();
739
+ const query = operationStrategy.buildInsertNode(params, timestamp2);
740
+ const row = await execution.execGet(query);
741
+ if (!row) throw new DatabaseOperationError("Insert node failed: no row returned", { operation: "insert", entity: "node" });
742
+ return rowMappers.toNodeRow(row);
743
+ },
744
+ async insertNodeNoReturn(params) {
745
+ const timestamp2 = nowIso2();
746
+ const query = operationStrategy.buildInsertNodeNoReturn(params, timestamp2);
747
+ await execution.execRun(query);
748
+ },
749
+ async insertNodesBatch(params) {
750
+ if (params.length === 0) {
751
+ return;
752
+ }
753
+ const timestamp2 = nowIso2();
754
+ for (const chunk of chunkArray(params, batchConfig.nodeInsertBatchSize)) {
755
+ const query = operationStrategy.buildInsertNodesBatch(chunk, timestamp2);
756
+ await execution.execRun(query);
757
+ }
758
+ },
759
+ async insertNodesBatchReturning(params) {
760
+ if (params.length === 0) {
761
+ return [];
762
+ }
763
+ const timestamp2 = nowIso2();
764
+ const allRows = [];
765
+ for (const chunk of chunkArray(params, batchConfig.nodeInsertBatchSize)) {
766
+ const query = operationStrategy.buildInsertNodesBatchReturning(chunk, timestamp2);
767
+ const rows = await execution.execAll(query);
768
+ allRows.push(...rows.map((row) => rowMappers.toNodeRow(row)));
769
+ }
770
+ return allRows;
771
+ },
772
+ async getNode(graphId, kind, id) {
773
+ const query = operationStrategy.buildGetNode(graphId, kind, id);
774
+ const row = await execution.execGet(query);
775
+ return row ? rowMappers.toNodeRow(row) : void 0;
776
+ },
777
+ async getNodes(graphId, kind, ids) {
778
+ if (ids.length === 0) return [];
779
+ const allRows = [];
780
+ for (const chunk of chunkArray(ids, batchConfig.getNodesChunkSize)) {
781
+ const query = operationStrategy.buildGetNodes(graphId, kind, chunk);
782
+ const rows = await execution.execAll(query);
783
+ allRows.push(...rows.map((row) => rowMappers.toNodeRow(row)));
784
+ }
785
+ return allRows;
786
+ },
787
+ async updateNode(params) {
788
+ const timestamp2 = nowIso2();
789
+ const query = operationStrategy.buildUpdateNode(params, timestamp2);
790
+ const row = await execution.execGet(query);
791
+ if (!row) throw new DatabaseOperationError("Update node failed: no row returned", { operation: "update", entity: "node" });
792
+ return rowMappers.toNodeRow(row);
793
+ },
794
+ async deleteNode(params) {
795
+ const timestamp2 = nowIso2();
796
+ const query = operationStrategy.buildDeleteNode(params, timestamp2);
797
+ await execution.execRun(query);
798
+ },
799
+ // IMPORTANT: This cascade is not atomic. Callers must ensure this runs
800
+ // within a transaction to prevent partial deletion on intermediate failure.
801
+ async hardDeleteNode(params) {
802
+ const deleteUniquesQuery = operationStrategy.buildHardDeleteUniquesByNode(
803
+ params.graphId,
804
+ params.id
805
+ );
806
+ await execution.execRun(deleteUniquesQuery);
807
+ const deleteEmbeddingsQuery = operationStrategy.buildHardDeleteEmbeddingsByNode(
808
+ params.graphId,
809
+ params.kind,
810
+ params.id
811
+ );
812
+ await execution.execRun(deleteEmbeddingsQuery);
813
+ const deleteEdgesQuery = operationStrategy.buildHardDeleteEdgesByNode(
814
+ params.graphId,
815
+ params.kind,
816
+ params.id
817
+ );
818
+ await execution.execRun(deleteEdgesQuery);
819
+ const query = operationStrategy.buildHardDeleteNode(params);
820
+ await execution.execRun(query);
821
+ },
822
+ async insertEdge(params) {
823
+ const timestamp2 = nowIso2();
824
+ const query = operationStrategy.buildInsertEdge(params, timestamp2);
825
+ const row = await execution.execGet(query);
826
+ if (!row) throw new DatabaseOperationError("Insert edge failed: no row returned", { operation: "insert", entity: "edge" });
827
+ return rowMappers.toEdgeRow(row);
828
+ },
829
+ async insertEdgeNoReturn(params) {
830
+ const timestamp2 = nowIso2();
831
+ const query = operationStrategy.buildInsertEdgeNoReturn(params, timestamp2);
832
+ await execution.execRun(query);
833
+ },
834
+ async insertEdgesBatch(params) {
835
+ if (params.length === 0) {
836
+ return;
837
+ }
838
+ const timestamp2 = nowIso2();
839
+ for (const chunk of chunkArray(params, batchConfig.edgeInsertBatchSize)) {
840
+ const query = operationStrategy.buildInsertEdgesBatch(chunk, timestamp2);
841
+ await execution.execRun(query);
842
+ }
843
+ },
844
+ async insertEdgesBatchReturning(params) {
845
+ if (params.length === 0) {
846
+ return [];
847
+ }
848
+ const timestamp2 = nowIso2();
849
+ const allRows = [];
850
+ for (const chunk of chunkArray(params, batchConfig.edgeInsertBatchSize)) {
851
+ const query = operationStrategy.buildInsertEdgesBatchReturning(chunk, timestamp2);
852
+ const rows = await execution.execAll(query);
853
+ allRows.push(...rows.map((row) => rowMappers.toEdgeRow(row)));
854
+ }
855
+ return allRows;
856
+ },
857
+ async getEdge(graphId, id) {
858
+ const query = operationStrategy.buildGetEdge(graphId, id);
859
+ const row = await execution.execGet(query);
860
+ return row ? rowMappers.toEdgeRow(row) : void 0;
861
+ },
862
+ async getEdges(graphId, ids) {
863
+ if (ids.length === 0) return [];
864
+ const allRows = [];
865
+ for (const chunk of chunkArray(ids, batchConfig.getEdgesChunkSize)) {
866
+ const query = operationStrategy.buildGetEdges(graphId, chunk);
867
+ const rows = await execution.execAll(query);
868
+ allRows.push(...rows.map((row) => rowMappers.toEdgeRow(row)));
869
+ }
870
+ return allRows;
871
+ },
872
+ async updateEdge(params) {
873
+ const timestamp2 = nowIso2();
874
+ const query = operationStrategy.buildUpdateEdge(params, timestamp2);
875
+ const row = await execution.execGet(query);
876
+ if (!row) throw new DatabaseOperationError("Update edge failed: no row returned", { operation: "update", entity: "edge" });
877
+ return rowMappers.toEdgeRow(row);
878
+ },
879
+ async deleteEdge(params) {
880
+ const timestamp2 = nowIso2();
881
+ const query = operationStrategy.buildDeleteEdge(params, timestamp2);
882
+ await execution.execRun(query);
883
+ },
884
+ async hardDeleteEdge(params) {
885
+ const query = operationStrategy.buildHardDeleteEdge(params);
886
+ await execution.execRun(query);
887
+ },
888
+ async countEdgesFrom(params) {
889
+ const query = operationStrategy.buildCountEdgesFrom(params);
890
+ const row = await execution.execGet(query);
891
+ return Number(row?.count ?? 0);
892
+ },
893
+ async edgeExistsBetween(params) {
894
+ const query = operationStrategy.buildEdgeExistsBetween(params);
895
+ const row = await execution.execGet(query);
896
+ return row !== void 0;
897
+ },
898
+ async findEdgesConnectedTo(params) {
899
+ const query = operationStrategy.buildFindEdgesConnectedTo(params);
900
+ const rows = await execution.execAll(query);
901
+ return rows.map((row) => rowMappers.toEdgeRow(row));
902
+ },
903
+ async findNodesByKind(params) {
904
+ const query = operationStrategy.buildFindNodesByKind(params);
905
+ const rows = await execution.execAll(query);
906
+ return rows.map((row) => rowMappers.toNodeRow(row));
907
+ },
908
+ async countNodesByKind(params) {
909
+ const query = operationStrategy.buildCountNodesByKind(params);
910
+ const row = await execution.execGet(query);
911
+ return Number(row?.count ?? 0);
912
+ },
913
+ async findEdgesByKind(params) {
914
+ const query = operationStrategy.buildFindEdgesByKind(params);
915
+ const rows = await execution.execAll(query);
916
+ return rows.map((row) => rowMappers.toEdgeRow(row));
917
+ },
918
+ async countEdgesByKind(params) {
919
+ const query = operationStrategy.buildCountEdgesByKind(params);
920
+ const row = await execution.execGet(query);
921
+ return Number(row?.count ?? 0);
922
+ },
923
+ async insertUnique(params) {
924
+ const query = operationStrategy.buildInsertUnique(params);
925
+ const result = await execution.execGet(query);
926
+ if (result && result.node_id !== params.nodeId) {
927
+ throw new UniquenessError({
928
+ constraintName: params.constraintName,
929
+ kind: params.nodeKind,
930
+ existingId: result.node_id,
931
+ newId: params.nodeId,
932
+ fields: []
933
+ });
934
+ }
935
+ },
936
+ async deleteUnique(params) {
937
+ const timestamp2 = nowIso2();
938
+ const query = operationStrategy.buildDeleteUnique(params, timestamp2);
939
+ await execution.execRun(query);
940
+ },
941
+ async checkUnique(params) {
942
+ const query = operationStrategy.buildCheckUnique(params);
943
+ const row = await execution.execGet(query);
944
+ return row ? rowMappers.toUniqueRow(row) : void 0;
945
+ },
946
+ async checkUniqueBatch(params) {
947
+ if (params.keys.length === 0) return [];
948
+ const query = operationStrategy.buildCheckUniqueBatch(params);
949
+ const rows = await execution.execAll(query);
950
+ return rows.map((row) => rowMappers.toUniqueRow(row));
951
+ },
952
+ async getActiveSchema(graphId) {
953
+ const query = operationStrategy.buildGetActiveSchema(graphId);
954
+ const row = await execution.execGet(query);
955
+ return row ? rowMappers.toSchemaVersionRow(row) : void 0;
956
+ },
957
+ async insertSchema(params) {
958
+ const timestamp2 = nowIso2();
959
+ const query = operationStrategy.buildInsertSchema(params, timestamp2);
960
+ const row = await execution.execGet(query);
961
+ if (!row) throw new DatabaseOperationError("Insert schema failed: no row returned", { operation: "insert", entity: "schema" });
962
+ return rowMappers.toSchemaVersionRow(row);
963
+ },
964
+ async getSchemaVersion(graphId, version) {
965
+ const query = operationStrategy.buildGetSchemaVersion(graphId, version);
966
+ const row = await execution.execGet(query);
967
+ return row ? rowMappers.toSchemaVersionRow(row) : void 0;
968
+ },
969
+ async setActiveSchema(graphId, version) {
970
+ const queries = operationStrategy.buildSetActiveSchema(graphId, version);
971
+ await execution.execRun(queries.deactivateAll);
972
+ await execution.execRun(queries.activateVersion);
973
+ },
974
+ async clearGraph(graphId) {
975
+ const statements = operationStrategy.buildClearGraph(graphId);
976
+ for (const statement of statements) {
977
+ await execution.execRun(statement);
978
+ }
979
+ }
980
+ };
981
+ }
982
+ function buildClearGraph(tables3, graphId) {
983
+ return [
984
+ sql`DELETE FROM ${tables3.embeddings} WHERE ${tables3.embeddings.graphId} = ${graphId}`,
985
+ sql`DELETE FROM ${tables3.uniques} WHERE ${tables3.uniques.graphId} = ${graphId}`,
986
+ sql`DELETE FROM ${tables3.edges} WHERE ${tables3.edges.graphId} = ${graphId}`,
987
+ sql`DELETE FROM ${tables3.nodes} WHERE ${tables3.nodes.graphId} = ${graphId}`,
988
+ sql`DELETE FROM ${tables3.schemaVersions} WHERE ${tables3.schemaVersions.graphId} = ${graphId}`
989
+ ];
990
+ }
991
+ function buildTemporalConditions(table, params) {
992
+ const conditions = [];
993
+ const mode = params.temporalMode;
994
+ if (mode === "includeTombstones") return conditions;
995
+ if (params.excludeDeleted !== false) {
996
+ conditions.push(sql`${table.deletedAt} IS NULL`);
997
+ }
998
+ if (mode === "current" || mode === "asOf") {
999
+ const asOf = params.asOf;
1000
+ conditions.push(
1001
+ sql`(${table.validFrom} IS NULL OR ${table.validFrom} <= ${asOf})`,
1002
+ sql`(${table.validTo} IS NULL OR ${table.validTo} > ${asOf})`
1003
+ );
1004
+ }
1005
+ return conditions;
1006
+ }
1007
+ function buildFindNodesByKind(tables3, params) {
1008
+ const { nodes: nodes3 } = tables3;
1009
+ const conditions = [
1010
+ sql`${nodes3.graphId} = ${params.graphId}`,
1011
+ sql`${nodes3.kind} = ${params.kind}`,
1012
+ ...buildTemporalConditions(nodes3, params)
1013
+ ];
1014
+ const whereClause = sql.join(conditions, sql` AND `);
1015
+ if (params.limit !== void 0 && params.offset !== void 0) {
1016
+ return sql`
1017
+ SELECT * FROM ${nodes3}
1018
+ WHERE ${whereClause}
1019
+ ORDER BY ${nodes3.createdAt} DESC
1020
+ LIMIT ${params.limit} OFFSET ${params.offset}
1021
+ `;
1022
+ }
1023
+ if (params.limit !== void 0) {
1024
+ return sql`
1025
+ SELECT * FROM ${nodes3}
1026
+ WHERE ${whereClause}
1027
+ ORDER BY ${nodes3.createdAt} DESC
1028
+ LIMIT ${params.limit}
1029
+ `;
1030
+ }
1031
+ return sql`
1032
+ SELECT * FROM ${nodes3}
1033
+ WHERE ${whereClause}
1034
+ ORDER BY ${nodes3.createdAt} DESC
1035
+ `;
1036
+ }
1037
+ function buildCountNodesByKind(tables3, params) {
1038
+ const { nodes: nodes3 } = tables3;
1039
+ const conditions = [
1040
+ sql`${nodes3.graphId} = ${params.graphId}`,
1041
+ sql`${nodes3.kind} = ${params.kind}`,
1042
+ ...buildTemporalConditions(nodes3, params)
1043
+ ];
1044
+ const whereClause = sql.join(conditions, sql` AND `);
1045
+ return sql`
1046
+ SELECT COUNT(*) as count FROM ${nodes3}
1047
+ WHERE ${whereClause}
1048
+ `;
1049
+ }
1050
+ function buildFindEdgesByKind(tables3, params) {
1051
+ const { edges: edges3 } = tables3;
1052
+ const conditions = [
1053
+ sql`${edges3.graphId} = ${params.graphId}`,
1054
+ sql`${edges3.kind} = ${params.kind}`,
1055
+ ...buildTemporalConditions(edges3, params)
1056
+ ];
1057
+ if (params.fromKind !== void 0) {
1058
+ conditions.push(sql`${edges3.fromKind} = ${params.fromKind}`);
1059
+ }
1060
+ if (params.fromId !== void 0) {
1061
+ conditions.push(sql`${edges3.fromId} = ${params.fromId}`);
1062
+ }
1063
+ if (params.toKind !== void 0) {
1064
+ conditions.push(sql`${edges3.toKind} = ${params.toKind}`);
1065
+ }
1066
+ if (params.toId !== void 0) {
1067
+ conditions.push(sql`${edges3.toId} = ${params.toId}`);
1068
+ }
1069
+ const whereClause = sql.join(conditions, sql` AND `);
1070
+ if (params.limit !== void 0 && params.offset !== void 0) {
1071
+ return sql`
1072
+ SELECT * FROM ${edges3}
1073
+ WHERE ${whereClause}
1074
+ ORDER BY ${edges3.createdAt} DESC
1075
+ LIMIT ${params.limit} OFFSET ${params.offset}
1076
+ `;
1077
+ }
1078
+ if (params.limit !== void 0) {
1079
+ return sql`
1080
+ SELECT * FROM ${edges3}
1081
+ WHERE ${whereClause}
1082
+ ORDER BY ${edges3.createdAt} DESC
1083
+ LIMIT ${params.limit}
1084
+ `;
1085
+ }
1086
+ return sql`
1087
+ SELECT * FROM ${edges3}
1088
+ WHERE ${whereClause}
1089
+ ORDER BY ${edges3.createdAt} DESC
1090
+ `;
1091
+ }
1092
+ function buildCountEdgesByKind(tables3, params) {
1093
+ const { edges: edges3 } = tables3;
1094
+ const conditions = [
1095
+ sql`${edges3.graphId} = ${params.graphId}`,
1096
+ sql`${edges3.kind} = ${params.kind}`,
1097
+ ...buildTemporalConditions(edges3, params)
1098
+ ];
1099
+ if (params.fromKind !== void 0) {
1100
+ conditions.push(sql`${edges3.fromKind} = ${params.fromKind}`);
1101
+ }
1102
+ if (params.fromId !== void 0) {
1103
+ conditions.push(sql`${edges3.fromId} = ${params.fromId}`);
1104
+ }
1105
+ if (params.toKind !== void 0) {
1106
+ conditions.push(sql`${edges3.toKind} = ${params.toKind}`);
1107
+ }
1108
+ if (params.toId !== void 0) {
1109
+ conditions.push(sql`${edges3.toId} = ${params.toId}`);
1110
+ }
1111
+ const whereClause = sql.join(conditions, sql` AND `);
1112
+ return sql`
1113
+ SELECT COUNT(*) as count FROM ${edges3}
1114
+ WHERE ${whereClause}
1115
+ `;
1116
+ }
1117
+ function sqlNull(value) {
1118
+ return value ?? sql.raw("NULL");
1119
+ }
1120
+ function quotedColumn(column) {
1121
+ return sql.raw(`"${column.name.replaceAll('"', '""')}"`);
1122
+ }
1123
+ function nodeColumnList(nodes3) {
1124
+ return sql.raw(`"${nodes3.graphId.name}", "${nodes3.kind.name}", "${nodes3.id.name}", "${nodes3.props.name}", "${nodes3.version.name}", "${nodes3.validFrom.name}", "${nodes3.validTo.name}", "${nodes3.createdAt.name}", "${nodes3.updatedAt.name}"`);
1125
+ }
1126
+ function edgeColumnList(edges3) {
1127
+ return sql.raw(`"${edges3.graphId.name}", "${edges3.id.name}", "${edges3.kind.name}", "${edges3.fromKind.name}", "${edges3.fromId.name}", "${edges3.toKind.name}", "${edges3.toId.name}", "${edges3.props.name}", "${edges3.validFrom.name}", "${edges3.validTo.name}", "${edges3.createdAt.name}", "${edges3.updatedAt.name}"`);
1128
+ }
1129
+
1130
+ // src/backend/drizzle/operations/edges.ts
1131
+ function buildInsertEdge(tables3, params, timestamp2) {
1132
+ const { edges: edges3 } = tables3;
1133
+ const propsJson = JSON.stringify(params.props);
1134
+ const columns = edgeColumnList(edges3);
1135
+ return sql`
1136
+ INSERT INTO ${edges3} (${columns})
1137
+ VALUES (
1138
+ ${params.graphId}, ${params.id}, ${params.kind},
1139
+ ${params.fromKind}, ${params.fromId}, ${params.toKind}, ${params.toId},
1140
+ ${propsJson}, ${sqlNull(params.validFrom)}, ${sqlNull(params.validTo)},
1141
+ ${timestamp2}, ${timestamp2}
1142
+ )
1143
+ RETURNING *
1144
+ `;
1145
+ }
1146
+ function buildInsertEdgeNoReturn(tables3, params, timestamp2) {
1147
+ const { edges: edges3 } = tables3;
1148
+ const propsJson = JSON.stringify(params.props);
1149
+ const columns = edgeColumnList(edges3);
1150
+ return sql`
1151
+ INSERT INTO ${edges3} (${columns})
1152
+ VALUES (
1153
+ ${params.graphId}, ${params.id}, ${params.kind},
1154
+ ${params.fromKind}, ${params.fromId}, ${params.toKind}, ${params.toId},
1155
+ ${propsJson}, ${sqlNull(params.validFrom)}, ${sqlNull(params.validTo)},
1156
+ ${timestamp2}, ${timestamp2}
1157
+ )
1158
+ `;
1159
+ }
1160
+ function buildInsertEdgesBatch(tables3, params, timestamp2) {
1161
+ const { edges: edges3 } = tables3;
1162
+ const columns = edgeColumnList(edges3);
1163
+ const values = params.map((edgeParams) => {
1164
+ const propsJson = JSON.stringify(edgeParams.props);
1165
+ return sql`(${edgeParams.graphId}, ${edgeParams.id}, ${edgeParams.kind}, ${edgeParams.fromKind}, ${edgeParams.fromId}, ${edgeParams.toKind}, ${edgeParams.toId}, ${propsJson}, ${sqlNull(edgeParams.validFrom)}, ${sqlNull(edgeParams.validTo)}, ${timestamp2}, ${timestamp2})`;
1166
+ });
1167
+ return sql`
1168
+ INSERT INTO ${edges3} (${columns})
1169
+ VALUES ${sql.join(values, sql`, `)}
1170
+ `;
1171
+ }
1172
+ function buildInsertEdgesBatchReturning(tables3, params, timestamp2) {
1173
+ const { edges: edges3 } = tables3;
1174
+ const columns = edgeColumnList(edges3);
1175
+ const values = params.map((edgeParams) => {
1176
+ const propsJson = JSON.stringify(edgeParams.props);
1177
+ return sql`(${edgeParams.graphId}, ${edgeParams.id}, ${edgeParams.kind}, ${edgeParams.fromKind}, ${edgeParams.fromId}, ${edgeParams.toKind}, ${edgeParams.toId}, ${propsJson}, ${sqlNull(edgeParams.validFrom)}, ${sqlNull(edgeParams.validTo)}, ${timestamp2}, ${timestamp2})`;
1178
+ });
1179
+ return sql`
1180
+ INSERT INTO ${edges3} (${columns})
1181
+ VALUES ${sql.join(values, sql`, `)}
1182
+ RETURNING *
1183
+ `;
1184
+ }
1185
+ function buildGetEdge(tables3, graphId, id) {
1186
+ const { edges: edges3 } = tables3;
1187
+ return sql`
1188
+ SELECT * FROM ${edges3}
1189
+ WHERE ${edges3.graphId} = ${graphId}
1190
+ AND ${edges3.id} = ${id}
1191
+ `;
1192
+ }
1193
+ function buildGetEdges(tables3, graphId, ids) {
1194
+ const { edges: edges3 } = tables3;
1195
+ const idPlaceholders = sql.join(
1196
+ ids.map((edgeId) => sql`${edgeId}`),
1197
+ sql`, `
1198
+ );
1199
+ return sql`
1200
+ SELECT * FROM ${edges3}
1201
+ WHERE ${edges3.graphId} = ${graphId}
1202
+ AND ${edges3.id} IN (${idPlaceholders})
1203
+ `;
1204
+ }
1205
+ function buildUpdateEdge(tables3, params, timestamp2) {
1206
+ const { edges: edges3 } = tables3;
1207
+ const propsJson = JSON.stringify(params.props);
1208
+ const setParts = [
1209
+ sql`${quotedColumn(edges3.props)} = ${propsJson}`,
1210
+ sql`${quotedColumn(edges3.updatedAt)} = ${timestamp2}`
1211
+ ];
1212
+ if (params.validTo !== void 0) {
1213
+ setParts.push(sql`${quotedColumn(edges3.validTo)} = ${params.validTo}`);
1214
+ }
1215
+ if (params.clearDeleted) {
1216
+ setParts.push(sql`${quotedColumn(edges3.deletedAt)} = NULL`);
1217
+ }
1218
+ const setClause = sql.join(setParts, sql`, `);
1219
+ if (params.clearDeleted) {
1220
+ return sql`
1221
+ UPDATE ${edges3}
1222
+ SET ${setClause}
1223
+ WHERE ${edges3.graphId} = ${params.graphId}
1224
+ AND ${edges3.id} = ${params.id}
1225
+ RETURNING *
1226
+ `;
1227
+ }
1228
+ return sql`
1229
+ UPDATE ${edges3}
1230
+ SET ${setClause}
1231
+ WHERE ${edges3.graphId} = ${params.graphId}
1232
+ AND ${edges3.id} = ${params.id}
1233
+ AND ${edges3.deletedAt} IS NULL
1234
+ RETURNING *
1235
+ `;
1236
+ }
1237
+ function buildDeleteEdge(tables3, params, timestamp2) {
1238
+ const { edges: edges3 } = tables3;
1239
+ return sql`
1240
+ UPDATE ${edges3}
1241
+ SET ${quotedColumn(edges3.deletedAt)} = ${timestamp2}
1242
+ WHERE ${edges3.graphId} = ${params.graphId}
1243
+ AND ${edges3.id} = ${params.id}
1244
+ AND ${edges3.deletedAt} IS NULL
1245
+ `;
1246
+ }
1247
+ function buildHardDeleteEdge(tables3, params) {
1248
+ const { edges: edges3 } = tables3;
1249
+ return sql`
1250
+ DELETE FROM ${edges3}
1251
+ WHERE ${edges3.graphId} = ${params.graphId}
1252
+ AND ${edges3.id} = ${params.id}
1253
+ `;
1254
+ }
1255
+ function buildHardDeleteEdgesByNode(tables3, graphId, nodeKind, nodeId) {
1256
+ const { edges: edges3 } = tables3;
1257
+ return sql`
1258
+ DELETE FROM ${edges3}
1259
+ WHERE ${edges3.graphId} = ${graphId}
1260
+ AND (
1261
+ (${edges3.fromKind} = ${nodeKind} AND ${edges3.fromId} = ${nodeId})
1262
+ OR (${edges3.toKind} = ${nodeKind} AND ${edges3.toId} = ${nodeId})
1263
+ )
1264
+ `;
1265
+ }
1266
+ function buildCountEdgesFrom(tables3, params) {
1267
+ const { edges: edges3 } = tables3;
1268
+ if (params.activeOnly) {
1269
+ return sql`
1270
+ SELECT COUNT(*) as count FROM ${edges3}
1271
+ WHERE ${edges3.graphId} = ${params.graphId}
1272
+ AND ${edges3.kind} = ${params.edgeKind}
1273
+ AND ${edges3.fromKind} = ${params.fromKind}
1274
+ AND ${edges3.fromId} = ${params.fromId}
1275
+ AND ${edges3.deletedAt} IS NULL
1276
+ AND ${edges3.validTo} IS NULL
1277
+ `;
1278
+ }
1279
+ return sql`
1280
+ SELECT COUNT(*) as count FROM ${edges3}
1281
+ WHERE ${edges3.graphId} = ${params.graphId}
1282
+ AND ${edges3.kind} = ${params.edgeKind}
1283
+ AND ${edges3.fromKind} = ${params.fromKind}
1284
+ AND ${edges3.fromId} = ${params.fromId}
1285
+ AND ${edges3.deletedAt} IS NULL
1286
+ `;
1287
+ }
1288
+ function buildEdgeExistsBetween(tables3, params) {
1289
+ const { edges: edges3 } = tables3;
1290
+ return sql`
1291
+ SELECT 1 FROM ${edges3}
1292
+ WHERE ${edges3.graphId} = ${params.graphId}
1293
+ AND ${edges3.kind} = ${params.edgeKind}
1294
+ AND ${edges3.fromKind} = ${params.fromKind}
1295
+ AND ${edges3.fromId} = ${params.fromId}
1296
+ AND ${edges3.toKind} = ${params.toKind}
1297
+ AND ${edges3.toId} = ${params.toId}
1298
+ AND ${edges3.deletedAt} IS NULL
1299
+ LIMIT 1
1300
+ `;
1301
+ }
1302
+ function buildFindEdgesConnectedTo(tables3, params) {
1303
+ const { edges: edges3 } = tables3;
1304
+ return sql`
1305
+ SELECT * FROM ${edges3}
1306
+ WHERE ${edges3.graphId} = ${params.graphId}
1307
+ AND ${edges3.deletedAt} IS NULL
1308
+ AND ${edges3.fromKind} = ${params.nodeKind}
1309
+ AND ${edges3.fromId} = ${params.nodeId}
1310
+ UNION ALL
1311
+ SELECT * FROM ${edges3}
1312
+ WHERE ${edges3.graphId} = ${params.graphId}
1313
+ AND ${edges3.deletedAt} IS NULL
1314
+ AND ${edges3.toKind} = ${params.nodeKind}
1315
+ AND ${edges3.toId} = ${params.nodeId}
1316
+ AND NOT (
1317
+ ${edges3.fromKind} = ${params.nodeKind}
1318
+ AND ${edges3.fromId} = ${params.nodeId}
1319
+ )
1320
+ `;
1321
+ }
1322
+ function buildInsertNode(tables3, params, timestamp2) {
1323
+ const { nodes: nodes3 } = tables3;
1324
+ const propsJson = JSON.stringify(params.props);
1325
+ const columns = nodeColumnList(nodes3);
1326
+ return sql`
1327
+ INSERT INTO ${nodes3} (${columns})
1328
+ VALUES (
1329
+ ${params.graphId}, ${params.kind}, ${params.id}, ${propsJson},
1330
+ 1, ${sqlNull(params.validFrom)}, ${sqlNull(params.validTo)},
1331
+ ${timestamp2}, ${timestamp2}
1332
+ )
1333
+ RETURNING *
1334
+ `;
1335
+ }
1336
+ function buildInsertNodeNoReturn(tables3, params, timestamp2) {
1337
+ const { nodes: nodes3 } = tables3;
1338
+ const propsJson = JSON.stringify(params.props);
1339
+ const columns = nodeColumnList(nodes3);
1340
+ return sql`
1341
+ INSERT INTO ${nodes3} (${columns})
1342
+ VALUES (
1343
+ ${params.graphId}, ${params.kind}, ${params.id}, ${propsJson},
1344
+ 1, ${sqlNull(params.validFrom)}, ${sqlNull(params.validTo)},
1345
+ ${timestamp2}, ${timestamp2}
1346
+ )
1347
+ `;
1348
+ }
1349
+ function buildInsertNodesBatch(tables3, params, timestamp2) {
1350
+ const { nodes: nodes3 } = tables3;
1351
+ const columns = nodeColumnList(nodes3);
1352
+ const values = params.map((nodeParams) => {
1353
+ const propsJson = JSON.stringify(nodeParams.props);
1354
+ return sql`(${nodeParams.graphId}, ${nodeParams.kind}, ${nodeParams.id}, ${propsJson}, 1, ${sqlNull(nodeParams.validFrom)}, ${sqlNull(nodeParams.validTo)}, ${timestamp2}, ${timestamp2})`;
1355
+ });
1356
+ return sql`
1357
+ INSERT INTO ${nodes3} (${columns})
1358
+ VALUES ${sql.join(values, sql`, `)}
1359
+ `;
1360
+ }
1361
+ function buildInsertNodesBatchReturning(tables3, params, timestamp2) {
1362
+ const { nodes: nodes3 } = tables3;
1363
+ const columns = nodeColumnList(nodes3);
1364
+ const values = params.map((nodeParams) => {
1365
+ const propsJson = JSON.stringify(nodeParams.props);
1366
+ return sql`(${nodeParams.graphId}, ${nodeParams.kind}, ${nodeParams.id}, ${propsJson}, 1, ${sqlNull(nodeParams.validFrom)}, ${sqlNull(nodeParams.validTo)}, ${timestamp2}, ${timestamp2})`;
1367
+ });
1368
+ return sql`
1369
+ INSERT INTO ${nodes3} (${columns})
1370
+ VALUES ${sql.join(values, sql`, `)}
1371
+ RETURNING *
1372
+ `;
1373
+ }
1374
+ function buildGetNode(tables3, graphId, kind, id) {
1375
+ const { nodes: nodes3 } = tables3;
1376
+ return sql`
1377
+ SELECT * FROM ${nodes3}
1378
+ WHERE ${nodes3.graphId} = ${graphId}
1379
+ AND ${nodes3.kind} = ${kind}
1380
+ AND ${nodes3.id} = ${id}
1381
+ `;
1382
+ }
1383
+ function buildGetNodes(tables3, graphId, kind, ids) {
1384
+ const { nodes: nodes3 } = tables3;
1385
+ const idPlaceholders = sql.join(
1386
+ ids.map((nodeId) => sql`${nodeId}`),
1387
+ sql`, `
1388
+ );
1389
+ return sql`
1390
+ SELECT * FROM ${nodes3}
1391
+ WHERE ${nodes3.graphId} = ${graphId}
1392
+ AND ${nodes3.kind} = ${kind}
1393
+ AND ${nodes3.id} IN (${idPlaceholders})
1394
+ `;
1395
+ }
1396
+ function buildUpdateNode(tables3, params, timestamp2) {
1397
+ const { nodes: nodes3 } = tables3;
1398
+ const propsJson = JSON.stringify(params.props);
1399
+ const setParts = [
1400
+ sql`${quotedColumn(nodes3.props)} = ${propsJson}`,
1401
+ sql`${quotedColumn(nodes3.updatedAt)} = ${timestamp2}`
1402
+ ];
1403
+ if (params.incrementVersion) {
1404
+ setParts.push(
1405
+ sql`${quotedColumn(nodes3.version)} = ${quotedColumn(nodes3.version)} + 1`
1406
+ );
1407
+ }
1408
+ if (params.validTo !== void 0) {
1409
+ setParts.push(sql`${quotedColumn(nodes3.validTo)} = ${params.validTo}`);
1410
+ }
1411
+ if (params.clearDeleted) {
1412
+ setParts.push(sql`${quotedColumn(nodes3.deletedAt)} = NULL`);
1413
+ }
1414
+ const setClause = sql.join(setParts, sql`, `);
1415
+ if (params.clearDeleted) {
1416
+ return sql`
1417
+ UPDATE ${nodes3}
1418
+ SET ${setClause}
1419
+ WHERE ${nodes3.graphId} = ${params.graphId}
1420
+ AND ${nodes3.kind} = ${params.kind}
1421
+ AND ${nodes3.id} = ${params.id}
1422
+ RETURNING *
1423
+ `;
1424
+ }
1425
+ return sql`
1426
+ UPDATE ${nodes3}
1427
+ SET ${setClause}
1428
+ WHERE ${nodes3.graphId} = ${params.graphId}
1429
+ AND ${nodes3.kind} = ${params.kind}
1430
+ AND ${nodes3.id} = ${params.id}
1431
+ AND ${nodes3.deletedAt} IS NULL
1432
+ RETURNING *
1433
+ `;
1434
+ }
1435
+ function buildDeleteNode(tables3, params, timestamp2) {
1436
+ const { nodes: nodes3 } = tables3;
1437
+ return sql`
1438
+ UPDATE ${nodes3}
1439
+ SET ${quotedColumn(nodes3.deletedAt)} = ${timestamp2}
1440
+ WHERE ${nodes3.graphId} = ${params.graphId}
1441
+ AND ${nodes3.kind} = ${params.kind}
1442
+ AND ${nodes3.id} = ${params.id}
1443
+ AND ${nodes3.deletedAt} IS NULL
1444
+ `;
1445
+ }
1446
+ function buildHardDeleteNode(tables3, params) {
1447
+ const { nodes: nodes3 } = tables3;
1448
+ return sql`
1449
+ DELETE FROM ${nodes3}
1450
+ WHERE ${nodes3.graphId} = ${params.graphId}
1451
+ AND ${nodes3.kind} = ${params.kind}
1452
+ AND ${nodes3.id} = ${params.id}
1453
+ `;
1454
+ }
1455
+ function createSchemaDialectStrategy(dialect) {
1456
+ const trueLiteral = dialect === "sqlite" ? sql.raw("1") : sql.raw("TRUE");
1457
+ const falseLiteral = dialect === "sqlite" ? sql.raw("0") : sql.raw("FALSE");
1458
+ return {
1459
+ booleanLiteral(value) {
1460
+ return value ? trueLiteral : falseLiteral;
1461
+ }
1462
+ };
1463
+ }
1464
+ var SCHEMA_DIALECT_STRATEGIES = {
1465
+ postgres: createSchemaDialectStrategy("postgres"),
1466
+ sqlite: createSchemaDialectStrategy("sqlite")
1467
+ };
1468
+ function buildInsertSchema(tables3, params, timestamp2, dialect = "sqlite") {
1469
+ const { schemaVersions: schemaVersions3 } = tables3;
1470
+ const strategy = SCHEMA_DIALECT_STRATEGIES[dialect];
1471
+ const schemaDocumentJson = JSON.stringify(params.schemaDoc);
1472
+ const isActiveValue = strategy.booleanLiteral(params.isActive);
1473
+ const columns = sql.raw(`"${schemaVersions3.graphId.name}", "${schemaVersions3.version.name}", "${schemaVersions3.schemaHash.name}", "${schemaVersions3.schemaDoc.name}", "${schemaVersions3.createdAt.name}", "${schemaVersions3.isActive.name}"`);
1474
+ return sql`
1475
+ INSERT INTO ${schemaVersions3} (${columns})
1476
+ VALUES (
1477
+ ${params.graphId}, ${params.version},
1478
+ ${params.schemaHash}, ${schemaDocumentJson},
1479
+ ${timestamp2}, ${isActiveValue}
1480
+ )
1481
+ RETURNING *
1482
+ `;
1483
+ }
1484
+ function buildGetActiveSchema(tables3, graphId, dialect = "sqlite") {
1485
+ const { schemaVersions: schemaVersions3 } = tables3;
1486
+ const strategy = SCHEMA_DIALECT_STRATEGIES[dialect];
1487
+ return sql`
1488
+ SELECT * FROM ${schemaVersions3}
1489
+ WHERE ${schemaVersions3.graphId} = ${graphId}
1490
+ AND ${schemaVersions3.isActive} = ${strategy.booleanLiteral(true)}
1491
+ `;
1492
+ }
1493
+ function buildGetSchemaVersion(tables3, graphId, version) {
1494
+ const { schemaVersions: schemaVersions3 } = tables3;
1495
+ return sql`
1496
+ SELECT * FROM ${schemaVersions3}
1497
+ WHERE ${schemaVersions3.graphId} = ${graphId}
1498
+ AND ${schemaVersions3.version} = ${version}
1499
+ `;
1500
+ }
1501
+ function buildSetActiveSchema(tables3, graphId, version, dialect = "sqlite") {
1502
+ const { schemaVersions: schemaVersions3 } = tables3;
1503
+ const strategy = SCHEMA_DIALECT_STRATEGIES[dialect];
1504
+ const deactivateAll = sql`
1505
+ UPDATE ${schemaVersions3}
1506
+ SET ${quotedColumn(schemaVersions3.isActive)} = ${strategy.booleanLiteral(false)}
1507
+ WHERE ${schemaVersions3.graphId} = ${graphId}
1508
+ `;
1509
+ const activateVersion = sql`
1510
+ UPDATE ${schemaVersions3}
1511
+ SET ${quotedColumn(schemaVersions3.isActive)} = ${strategy.booleanLiteral(true)}
1512
+ WHERE ${schemaVersions3.graphId} = ${graphId}
1513
+ AND ${schemaVersions3.version} = ${version}
1514
+ `;
1515
+ return { deactivateAll, activateVersion };
1516
+ }
1517
+ function buildInsertUniqueSqlite(tables3, params) {
1518
+ const { uniques: uniques3 } = tables3;
1519
+ const columns = sql.raw(`"${uniques3.graphId.name}", "${uniques3.nodeKind.name}", "${uniques3.constraintName.name}", "${uniques3.key.name}", "${uniques3.nodeId.name}", "${uniques3.concreteKind.name}", "${uniques3.deletedAt.name}"`);
1520
+ const conflictColumns = sql.raw(`"${uniques3.graphId.name}", "${uniques3.nodeKind.name}", "${uniques3.constraintName.name}", "${uniques3.key.name}"`);
1521
+ return sql`
1522
+ INSERT INTO ${uniques3} (${columns})
1523
+ VALUES (
1524
+ ${params.graphId}, ${params.nodeKind}, ${params.constraintName},
1525
+ ${params.key}, ${params.nodeId}, ${params.concreteKind}, ${sql.raw("NULL")}
1526
+ )
1527
+ ON CONFLICT (${conflictColumns})
1528
+ DO UPDATE SET
1529
+ ${quotedColumn(uniques3.nodeId)} = CASE
1530
+ WHEN ${quotedColumn(uniques3.nodeId)} = ${params.nodeId} THEN ${params.nodeId}
1531
+ WHEN ${quotedColumn(uniques3.deletedAt)} IS NOT NULL THEN ${params.nodeId}
1532
+ ELSE ${quotedColumn(uniques3.nodeId)}
1533
+ END,
1534
+ ${quotedColumn(uniques3.concreteKind)} = CASE
1535
+ WHEN ${quotedColumn(uniques3.nodeId)} = ${params.nodeId} THEN ${params.concreteKind}
1536
+ WHEN ${quotedColumn(uniques3.deletedAt)} IS NOT NULL THEN ${params.concreteKind}
1537
+ ELSE ${quotedColumn(uniques3.concreteKind)}
1538
+ END,
1539
+ ${quotedColumn(uniques3.deletedAt)} = CASE
1540
+ WHEN ${quotedColumn(uniques3.nodeId)} = ${params.nodeId} THEN NULL
1541
+ WHEN ${quotedColumn(uniques3.deletedAt)} IS NOT NULL THEN NULL
1542
+ ELSE ${quotedColumn(uniques3.deletedAt)}
1543
+ END
1544
+ RETURNING ${quotedColumn(uniques3.nodeId)} as node_id
1545
+ `;
1546
+ }
1547
+ function buildInsertUniquePostgres(tables3, params) {
1548
+ const { uniques: uniques3 } = tables3;
1549
+ const columns = sql.raw(`"${uniques3.graphId.name}", "${uniques3.nodeKind.name}", "${uniques3.constraintName.name}", "${uniques3.key.name}", "${uniques3.nodeId.name}", "${uniques3.concreteKind.name}", "${uniques3.deletedAt.name}"`);
1550
+ const conflictColumns = sql.raw(`"${uniques3.graphId.name}", "${uniques3.nodeKind.name}", "${uniques3.constraintName.name}", "${uniques3.key.name}"`);
1551
+ const tableName = getTableName(uniques3);
1552
+ const existingColumn = (column) => sql.raw(`"${tableName}"."${column.name}"`);
1553
+ return sql`
1554
+ INSERT INTO ${uniques3} (${columns})
1555
+ VALUES (
1556
+ ${params.graphId}, ${params.nodeKind}, ${params.constraintName},
1557
+ ${params.key}, ${params.nodeId}, ${params.concreteKind}, ${sql.raw("NULL")}
1558
+ )
1559
+ ON CONFLICT (${conflictColumns})
1560
+ DO UPDATE SET
1561
+ ${quotedColumn(uniques3.nodeId)} = CASE
1562
+ WHEN ${existingColumn(uniques3.nodeId)} = ${params.nodeId} THEN ${params.nodeId}
1563
+ WHEN ${existingColumn(uniques3.deletedAt)} IS NOT NULL THEN ${params.nodeId}
1564
+ ELSE ${existingColumn(uniques3.nodeId)}
1565
+ END,
1566
+ ${quotedColumn(uniques3.concreteKind)} = CASE
1567
+ WHEN ${existingColumn(uniques3.nodeId)} = ${params.nodeId} THEN ${params.concreteKind}
1568
+ WHEN ${existingColumn(uniques3.deletedAt)} IS NOT NULL THEN ${params.concreteKind}
1569
+ ELSE ${existingColumn(uniques3.concreteKind)}
1570
+ END,
1571
+ ${quotedColumn(uniques3.deletedAt)} = CASE
1572
+ WHEN ${existingColumn(uniques3.nodeId)} = ${params.nodeId} THEN NULL
1573
+ WHEN ${existingColumn(uniques3.deletedAt)} IS NOT NULL THEN NULL
1574
+ ELSE ${existingColumn(uniques3.deletedAt)}
1575
+ END
1576
+ RETURNING ${quotedColumn(uniques3.nodeId)} as node_id
1577
+ `;
1578
+ }
1579
+ var UNIQUE_INSERT_BUILDERS = {
1580
+ postgres: buildInsertUniquePostgres,
1581
+ sqlite: buildInsertUniqueSqlite
1582
+ };
1583
+ function buildInsertUnique(tables3, dialect, params) {
1584
+ const builder = UNIQUE_INSERT_BUILDERS[dialect];
1585
+ return builder(tables3, params);
1586
+ }
1587
+ function buildDeleteUnique(tables3, params, timestamp2) {
1588
+ const { uniques: uniques3 } = tables3;
1589
+ return sql`
1590
+ UPDATE ${uniques3}
1591
+ SET ${quotedColumn(uniques3.deletedAt)} = ${timestamp2}
1592
+ WHERE ${uniques3.graphId} = ${params.graphId}
1593
+ AND ${uniques3.nodeKind} = ${params.nodeKind}
1594
+ AND ${uniques3.constraintName} = ${params.constraintName}
1595
+ AND ${uniques3.key} = ${params.key}
1596
+ AND ${uniques3.deletedAt} IS NULL
1597
+ `;
1598
+ }
1599
+ function buildHardDeleteUniquesByNode(tables3, graphId, nodeId) {
1600
+ const { uniques: uniques3 } = tables3;
1601
+ return sql`
1602
+ DELETE FROM ${uniques3}
1603
+ WHERE ${uniques3.graphId} = ${graphId}
1604
+ AND ${uniques3.nodeId} = ${nodeId}
1605
+ `;
1606
+ }
1607
+ function buildHardDeleteEmbeddingsByNode(tables3, graphId, nodeKind, nodeId) {
1608
+ const { embeddings: embeddings3 } = tables3;
1609
+ return sql`
1610
+ DELETE FROM ${embeddings3}
1611
+ WHERE ${embeddings3.graphId} = ${graphId}
1612
+ AND ${embeddings3.nodeKind} = ${nodeKind}
1613
+ AND ${embeddings3.nodeId} = ${nodeId}
1614
+ `;
1615
+ }
1616
+ function buildCheckUnique(tables3, params) {
1617
+ const { uniques: uniques3 } = tables3;
1618
+ if (params.includeDeleted) {
1619
+ return sql`
1620
+ SELECT * FROM ${uniques3}
1621
+ WHERE ${uniques3.graphId} = ${params.graphId}
1622
+ AND ${uniques3.nodeKind} = ${params.nodeKind}
1623
+ AND ${uniques3.constraintName} = ${params.constraintName}
1624
+ AND ${uniques3.key} = ${params.key}
1625
+ `;
1626
+ }
1627
+ return sql`
1628
+ SELECT * FROM ${uniques3}
1629
+ WHERE ${uniques3.graphId} = ${params.graphId}
1630
+ AND ${uniques3.nodeKind} = ${params.nodeKind}
1631
+ AND ${uniques3.constraintName} = ${params.constraintName}
1632
+ AND ${uniques3.key} = ${params.key}
1633
+ AND ${uniques3.deletedAt} IS NULL
1634
+ `;
1635
+ }
1636
+ function buildCheckUniqueBatch(tables3, params) {
1637
+ const { uniques: uniques3 } = tables3;
1638
+ const keyPlaceholders = sql.join(
1639
+ params.keys.map((key) => sql`${key}`),
1640
+ sql`, `
1641
+ );
1642
+ if (params.includeDeleted) {
1643
+ return sql`
1644
+ SELECT * FROM ${uniques3}
1645
+ WHERE ${uniques3.graphId} = ${params.graphId}
1646
+ AND ${uniques3.nodeKind} = ${params.nodeKind}
1647
+ AND ${uniques3.constraintName} = ${params.constraintName}
1648
+ AND ${uniques3.key} IN (${keyPlaceholders})
1649
+ `;
1650
+ }
1651
+ return sql`
1652
+ SELECT * FROM ${uniques3}
1653
+ WHERE ${uniques3.graphId} = ${params.graphId}
1654
+ AND ${uniques3.nodeKind} = ${params.nodeKind}
1655
+ AND ${uniques3.constraintName} = ${params.constraintName}
1656
+ AND ${uniques3.key} IN (${keyPlaceholders})
1657
+ AND ${uniques3.deletedAt} IS NULL
1658
+ `;
1659
+ }
1660
+ function assertFiniteNumberArray(array, name) {
1661
+ for (const [index3, value] of array.entries()) {
1662
+ if (typeof value !== "number" || !Number.isFinite(value)) {
1663
+ throw new TypeError(
1664
+ `${name}[${index3}] must be a finite number, got: ${value}`
1665
+ );
1666
+ }
1667
+ }
1668
+ }
1669
+ function formatEmbeddingLiteral(embedding) {
1670
+ assertFiniteNumberArray(embedding, "embedding");
1671
+ return `[${embedding.join(",")}]`;
1672
+ }
1673
+ function buildUpsertEmbeddingPostgres(tables3, params, timestamp2) {
1674
+ const { embeddings: embeddings3 } = tables3;
1675
+ const embeddingLiteral = formatEmbeddingLiteral(params.embedding);
1676
+ const columns = sql.raw(
1677
+ `"${embeddings3.graphId.name}", "${embeddings3.nodeKind.name}", "${embeddings3.nodeId.name}", "${embeddings3.fieldPath.name}", "${embeddings3.embedding.name}", "${embeddings3.dimensions.name}", "${embeddings3.createdAt.name}", "${embeddings3.updatedAt.name}"`
1678
+ );
1679
+ const conflictColumns = sql.raw(
1680
+ `"${embeddings3.graphId.name}", "${embeddings3.nodeKind.name}", "${embeddings3.nodeId.name}", "${embeddings3.fieldPath.name}"`
1681
+ );
1682
+ const column = (target) => sql.raw(`"${target.name}"`);
1683
+ return sql`
1684
+ INSERT INTO ${embeddings3} (${columns})
1685
+ VALUES (
1686
+ ${params.graphId}, ${params.nodeKind}, ${params.nodeId}, ${params.fieldPath},
1687
+ ${embeddingLiteral}::vector, ${params.dimensions}, ${timestamp2}, ${timestamp2}
1688
+ )
1689
+ ON CONFLICT (${conflictColumns})
1690
+ DO UPDATE SET
1691
+ ${column(embeddings3.embedding)} = ${embeddingLiteral}::vector,
1692
+ ${column(embeddings3.dimensions)} = ${params.dimensions},
1693
+ ${column(embeddings3.updatedAt)} = ${timestamp2}
1694
+ `;
1695
+ }
1696
+ function buildDeleteEmbedding(tables3, params) {
1697
+ const { embeddings: embeddings3 } = tables3;
1698
+ return sql`
1699
+ DELETE FROM ${embeddings3}
1700
+ WHERE ${embeddings3.graphId} = ${params.graphId}
1701
+ AND ${embeddings3.nodeKind} = ${params.nodeKind}
1702
+ AND ${embeddings3.nodeId} = ${params.nodeId}
1703
+ AND ${embeddings3.fieldPath} = ${params.fieldPath}
1704
+ `;
1705
+ }
1706
+ function buildGetEmbedding(tables3, graphId, nodeKind, nodeId, fieldPath) {
1707
+ const { embeddings: embeddings3 } = tables3;
1708
+ return sql`
1709
+ SELECT * FROM ${embeddings3}
1710
+ WHERE ${embeddings3.graphId} = ${graphId}
1711
+ AND ${embeddings3.nodeKind} = ${nodeKind}
1712
+ AND ${embeddings3.nodeId} = ${nodeId}
1713
+ AND ${embeddings3.fieldPath} = ${fieldPath}
1714
+ `;
1715
+ }
1716
+ function buildDistanceExpression(embeddingColumn, queryLiteral, metric) {
1717
+ const vectorParameter = sql`${queryLiteral}::vector`;
1718
+ switch (metric) {
1719
+ case "cosine": {
1720
+ return sql`(${embeddingColumn} <=> ${vectorParameter})`;
1721
+ }
1722
+ case "l2": {
1723
+ return sql`(${embeddingColumn} <-> ${vectorParameter})`;
1724
+ }
1725
+ case "inner_product": {
1726
+ return sql`(${embeddingColumn} <#> ${vectorParameter})`;
1727
+ }
1728
+ default: {
1729
+ const _exhaustive = metric;
1730
+ throw new Error(`Unsupported vector metric: ${String(_exhaustive)}`);
1731
+ }
1732
+ }
1733
+ }
1734
+ function buildVectorSearchScoreExpression(distanceExpression, metric) {
1735
+ switch (metric) {
1736
+ case "cosine": {
1737
+ return sql`(1 - (${distanceExpression}))`;
1738
+ }
1739
+ case "l2":
1740
+ case "inner_product": {
1741
+ return distanceExpression;
1742
+ }
1743
+ default: {
1744
+ const _exhaustive = metric;
1745
+ throw new Error(`Unsupported vector metric: ${String(_exhaustive)}`);
1746
+ }
1747
+ }
1748
+ }
1749
+ function buildVectorSearchMinScoreCondition(distanceExpression, metric, minScore) {
1750
+ switch (metric) {
1751
+ case "cosine": {
1752
+ const threshold = 1 - minScore;
1753
+ return sql`${distanceExpression} <= ${threshold}`;
1754
+ }
1755
+ case "l2": {
1756
+ return sql`${distanceExpression} <= ${minScore}`;
1757
+ }
1758
+ case "inner_product": {
1759
+ const negativeThreshold = -minScore;
1760
+ return sql`${distanceExpression} <= ${negativeThreshold}`;
1761
+ }
1762
+ default: {
1763
+ const _exhaustive = metric;
1764
+ throw new Error(`Unsupported vector metric: ${String(_exhaustive)}`);
1765
+ }
1766
+ }
1767
+ }
1768
+ function buildVectorSearchPostgres(tables3, params) {
1769
+ const { embeddings: embeddings3 } = tables3;
1770
+ const queryLiteral = formatEmbeddingLiteral(params.queryEmbedding);
1771
+ if (params.minScore !== void 0 && !Number.isFinite(params.minScore)) {
1772
+ throw new TypeError(
1773
+ `minScore must be a finite number, got: ${params.minScore}`
1774
+ );
1775
+ }
1776
+ if (!Number.isInteger(params.limit) || params.limit <= 0) {
1777
+ throw new Error(`limit must be a positive integer, got: ${params.limit}`);
1778
+ }
1779
+ const embeddingColumn = sql`${embeddings3.embedding}`;
1780
+ const distanceExpression = buildDistanceExpression(
1781
+ embeddingColumn,
1782
+ queryLiteral,
1783
+ params.metric
1784
+ );
1785
+ const conditions = [
1786
+ sql`${embeddings3.graphId} = ${params.graphId}`,
1787
+ sql`${embeddings3.nodeKind} = ${params.nodeKind}`,
1788
+ sql`${embeddings3.fieldPath} = ${params.fieldPath}`
1789
+ ];
1790
+ if (params.minScore !== void 0) {
1791
+ conditions.push(
1792
+ buildVectorSearchMinScoreCondition(
1793
+ distanceExpression,
1794
+ params.metric,
1795
+ params.minScore
1796
+ )
1797
+ );
1798
+ }
1799
+ const whereClause = sql.join(conditions, sql` AND `);
1800
+ const scoreExpression = buildVectorSearchScoreExpression(
1801
+ distanceExpression,
1802
+ params.metric
1803
+ );
1804
+ return sql`
1805
+ SELECT
1806
+ ${embeddings3.nodeId} as node_id,
1807
+ ${scoreExpression} as score
1808
+ FROM ${embeddings3}
1809
+ WHERE ${whereClause}
1810
+ ORDER BY ${distanceExpression} ASC
1811
+ LIMIT ${params.limit}
1812
+ `;
1813
+ }
1814
+
1815
+ // src/backend/drizzle/operations/strategy.ts
1816
+ function bindTableOperationBuilders(tables3, builders) {
1817
+ const boundEntries = Object.entries(builders).map(([name, builder]) => {
1818
+ function boundBuilder(...args) {
1819
+ return builder(tables3, ...args);
1820
+ }
1821
+ return [name, boundBuilder];
1822
+ });
1823
+ return Object.fromEntries(boundEntries);
1824
+ }
1825
+ var COMMON_TABLE_OPERATION_BUILDERS = {
1826
+ buildInsertNode,
1827
+ buildInsertNodeNoReturn,
1828
+ buildInsertNodesBatch,
1829
+ buildInsertNodesBatchReturning,
1830
+ buildGetNode,
1831
+ buildGetNodes,
1832
+ buildUpdateNode,
1833
+ buildDeleteNode,
1834
+ buildHardDeleteNode,
1835
+ buildInsertEdge,
1836
+ buildInsertEdgeNoReturn,
1837
+ buildInsertEdgesBatch,
1838
+ buildInsertEdgesBatchReturning,
1839
+ buildGetEdge,
1840
+ buildGetEdges,
1841
+ buildUpdateEdge,
1842
+ buildDeleteEdge,
1843
+ buildHardDeleteEdge,
1844
+ buildHardDeleteEdgesByNode,
1845
+ buildCountEdgesFrom,
1846
+ buildEdgeExistsBetween,
1847
+ buildFindEdgesConnectedTo,
1848
+ buildFindNodesByKind,
1849
+ buildCountNodesByKind,
1850
+ buildFindEdgesByKind,
1851
+ buildCountEdgesByKind,
1852
+ buildDeleteUnique,
1853
+ buildHardDeleteUniquesByNode,
1854
+ buildHardDeleteEmbeddingsByNode,
1855
+ buildCheckUnique,
1856
+ buildCheckUniqueBatch,
1857
+ buildGetSchemaVersion
1858
+ };
1859
+ function createCommonOperationStrategy(tables3, dialect) {
1860
+ const tableOperations = bindTableOperationBuilders(
1861
+ tables3,
1862
+ COMMON_TABLE_OPERATION_BUILDERS
1863
+ );
1864
+ return {
1865
+ ...tableOperations,
1866
+ buildInsertUnique(params) {
1867
+ return buildInsertUnique(tables3, dialect, params);
1868
+ },
1869
+ buildGetActiveSchema(graphId) {
1870
+ return buildGetActiveSchema(tables3, graphId, dialect);
1871
+ },
1872
+ buildInsertSchema(params, timestamp2) {
1873
+ return buildInsertSchema(tables3, params, timestamp2, dialect);
1874
+ },
1875
+ buildSetActiveSchema(graphId, version) {
1876
+ return buildSetActiveSchema(tables3, graphId, version, dialect);
1877
+ },
1878
+ buildClearGraph(graphId) {
1879
+ return buildClearGraph(tables3, graphId);
1880
+ }
1881
+ };
1882
+ }
1883
+ function createSqliteOperationStrategy(tables3) {
1884
+ return createCommonOperationStrategy(tables3, "sqlite");
1885
+ }
1886
+ function createPostgresOperationStrategy(tables3) {
1887
+ const common = createCommonOperationStrategy(tables3, "postgres");
1888
+ return {
1889
+ ...common,
1890
+ buildUpsertEmbedding(params, timestamp2) {
1891
+ return buildUpsertEmbeddingPostgres(tables3, params, timestamp2);
1892
+ },
1893
+ buildDeleteEmbedding(params) {
1894
+ return buildDeleteEmbedding(tables3, params);
1895
+ },
1896
+ buildGetEmbedding(graphId, nodeKind, nodeId, fieldPath) {
1897
+ return buildGetEmbedding(tables3, graphId, nodeKind, nodeId, fieldPath);
1898
+ },
1899
+ buildVectorSearch(params) {
1900
+ return buildVectorSearchPostgres(tables3, params);
1901
+ }
1902
+ };
1903
+ }
1904
+ function assertPositiveInteger(value, name) {
1905
+ if (!Number.isInteger(value) || value <= 0) {
1906
+ throw new Error(`${name} must be a positive integer, got: ${value}`);
1907
+ }
1908
+ }
1909
+ function assertSafeIdentifier(value, name) {
1910
+ if (!/^[a-z0-9_]+$/i.test(value)) {
1911
+ throw new Error(
1912
+ `${name} must contain only alphanumeric characters and underscores, got: ${value}`
1913
+ );
1914
+ }
1915
+ }
1916
+ var MAX_IDENTIFIER_LENGTH = 63;
1917
+ function sanitizeIdentifier(s) {
1918
+ return s.toLowerCase().replaceAll(/[^a-z0-9_]/g, "_");
1919
+ }
1920
+ function quoteIdentifier(value) {
1921
+ return `"${value.replaceAll('"', '""')}"`;
1922
+ }
1923
+ function shortHash(input) {
1924
+ let h1 = 3735928559;
1925
+ let h2 = 1103547991;
1926
+ for (let index3 = 0; index3 < input.length; index3++) {
1927
+ const ch = input.codePointAt(index3);
1928
+ h1 = Math.imul(h1 ^ ch, 2654435761);
1929
+ h2 = Math.imul(h2 ^ ch, 1597334677);
1930
+ }
1931
+ h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
1932
+ h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
1933
+ const hi = (h2 >>> 0).toString(16).padStart(8, "0");
1934
+ const lo = (h1 >>> 0).toString(16).padStart(8, "0");
1935
+ return `${hi}${lo}`.slice(0, 8);
1936
+ }
1937
+ function generateVectorIndexName(graphId, nodeKind, fieldPath, metric = "cosine") {
1938
+ const parts = [
1939
+ "idx_emb",
1940
+ sanitizeIdentifier(graphId),
1941
+ sanitizeIdentifier(nodeKind),
1942
+ sanitizeIdentifier(fieldPath),
1943
+ metric
1944
+ ];
1945
+ const name = parts.join("_");
1946
+ if (name.length <= MAX_IDENTIFIER_LENGTH) {
1947
+ return name;
1948
+ }
1949
+ const hash = shortHash(name);
1950
+ const truncated = name.slice(0, MAX_IDENTIFIER_LENGTH - 1 - hash.length);
1951
+ return `${truncated}_${hash}`;
1952
+ }
1953
+ function getOperatorClass(metric) {
1954
+ switch (metric) {
1955
+ case "cosine": {
1956
+ return "vector_cosine_ops";
1957
+ }
1958
+ case "l2": {
1959
+ return "vector_l2_ops";
1960
+ }
1961
+ case "inner_product": {
1962
+ return "vector_ip_ops";
1963
+ }
1964
+ default: {
1965
+ const _exhaustive = metric;
1966
+ throw new Error("Unsupported vector metric: " + String(_exhaustive));
1967
+ }
1968
+ }
1969
+ }
1970
+ function escapeSqlString(value) {
1971
+ const tag = `tg${crypto.randomUUID().replaceAll("-", "").slice(0, 8)}`;
1972
+ return `$${tag}$${value}$${tag}$`;
1973
+ }
1974
+ async function createPostgresVectorIndex(db, options) {
1975
+ const {
1976
+ graphId,
1977
+ nodeKind,
1978
+ fieldPath,
1979
+ dimensions,
1980
+ embeddingsTableName = "typegraph_node_embeddings",
1981
+ indexType = "hnsw",
1982
+ metric = "cosine",
1983
+ hnswM = 16,
1984
+ hnswEfConstruction = 64,
1985
+ ivfflatLists = 100
1986
+ } = options;
1987
+ assertPositiveInteger(dimensions, "dimensions");
1988
+ assertPositiveInteger(hnswM, "hnswM");
1989
+ assertPositiveInteger(hnswEfConstruction, "hnswEfConstruction");
1990
+ assertPositiveInteger(ivfflatLists, "ivfflatLists");
1991
+ const indexName = generateVectorIndexName(graphId, nodeKind, fieldPath, metric);
1992
+ const operatorClass = getOperatorClass(metric);
1993
+ const quotedEmbeddingsTableName = quoteIdentifier(embeddingsTableName);
1994
+ assertSafeIdentifier(indexName, "indexName");
1995
+ const safeGraphId = escapeSqlString(graphId);
1996
+ const safeNodeKind = escapeSqlString(nodeKind);
1997
+ const safeFieldPath = escapeSqlString(fieldPath);
1998
+ let indexSql;
1999
+ if (indexType === "hnsw") {
2000
+ indexSql = sql.raw(`
2001
+ CREATE INDEX IF NOT EXISTS ${indexName}
2002
+ ON ${quotedEmbeddingsTableName}
2003
+ USING hnsw ((embedding::vector(${dimensions})) ${operatorClass})
2004
+ WITH (m = ${hnswM}, ef_construction = ${hnswEfConstruction})
2005
+ WHERE graph_id = ${safeGraphId}
2006
+ AND node_kind = ${safeNodeKind}
2007
+ AND field_path = ${safeFieldPath}
2008
+ `);
2009
+ } else if (indexType === "ivfflat") {
2010
+ indexSql = sql.raw(`
2011
+ CREATE INDEX IF NOT EXISTS ${indexName}
2012
+ ON ${quotedEmbeddingsTableName}
2013
+ USING ivfflat ((embedding::vector(${dimensions})) ${operatorClass})
2014
+ WITH (lists = ${ivfflatLists})
2015
+ WHERE graph_id = ${safeGraphId}
2016
+ AND node_kind = ${safeNodeKind}
2017
+ AND field_path = ${safeFieldPath}
2018
+ `);
2019
+ } else {
2020
+ return {
2021
+ indexName,
2022
+ success: true,
2023
+ message: `Index type "${indexType}" not supported, skipping index creation`
2024
+ };
2025
+ }
2026
+ try {
2027
+ await db.execute(indexSql);
2028
+ return {
2029
+ indexName,
2030
+ success: true,
2031
+ message: `Created ${indexType.toUpperCase()} index "${indexName}" for ${nodeKind}.${fieldPath}`
2032
+ };
2033
+ } catch (error) {
2034
+ return {
2035
+ indexName,
2036
+ success: false,
2037
+ message: `Failed to create index: ${error instanceof Error ? error.message : String(error)}`
2038
+ };
2039
+ }
2040
+ }
2041
+ async function dropPostgresVectorIndex(db, indexName) {
2042
+ assertSafeIdentifier(indexName, "indexName");
2043
+ try {
2044
+ const dropSql = sql.raw(`DROP INDEX IF EXISTS ${indexName}`);
2045
+ await db.execute(dropSql);
2046
+ return {
2047
+ indexName,
2048
+ success: true,
2049
+ message: `Dropped index "${indexName}"`
2050
+ };
2051
+ } catch (error) {
2052
+ return {
2053
+ indexName,
2054
+ success: false,
2055
+ message: `Failed to drop index: ${error instanceof Error ? error.message : String(error)}`
2056
+ };
2057
+ }
2058
+ }
2059
+ function createSqliteVectorIndex(_options) {
2060
+ const indexName = generateVectorIndexName(
2061
+ _options.graphId,
2062
+ _options.nodeKind,
2063
+ _options.fieldPath,
2064
+ _options.metric
2065
+ );
2066
+ return {
2067
+ indexName,
2068
+ success: true,
2069
+ message: "SQLite/sqlite-vec uses optimized internal indexing, no explicit index needed"
2070
+ };
2071
+ }
2072
+ function dropSqliteVectorIndex(graphId, nodeKind, fieldPath, metric = "cosine") {
2073
+ const indexName = generateVectorIndexName(graphId, nodeKind, fieldPath, metric);
2074
+ return {
2075
+ indexName,
2076
+ success: true,
2077
+ message: "SQLite/sqlite-vec does not use explicit indexes"
2078
+ };
2079
+ }
2080
+
2081
+ // src/backend/drizzle/execution/types.ts
2082
+ function compileQueryWithDialect(db, query, backendName) {
2083
+ const databaseWithCompiler = db;
2084
+ const compiler = databaseWithCompiler.dialect;
2085
+ if (compiler === void 0) {
2086
+ throw new Error(`${backendName} backend is missing a SQL compiler`);
2087
+ }
2088
+ return compiler.sqlToQuery(query);
2089
+ }
2090
+
2091
+ export { D1_CAPABILITIES, POSTGRES_CAPABILITIES, POSTGRES_ROW_MAPPER_CONFIG, SQLITE_CAPABILITIES, SQLITE_ROW_MAPPER_CONFIG, compileQueryWithDialect, createCommonOperationBackend, createEdgeRowMapper, createNodeRowMapper, createPostgresOperationStrategy, createPostgresTables, createPostgresVectorIndex, createSchemaVersionRowMapper, createSqliteOperationStrategy, createSqliteTables, createSqliteVectorIndex, createUniqueRowMapper, dropPostgresVectorIndex, dropSqliteVectorIndex, edges, edges2, embeddings, embeddings2, formatPostgresTimestamp, generatePostgresDDL, generatePostgresMigrationSQL, generateSqliteDDL, generateSqliteMigrationSQL, generateVectorIndexName, nodes, nodes2, nowIso, schemaVersions, schemaVersions2, tables, tables2, uniques, uniques2 };
2092
+ //# sourceMappingURL=chunk-JPO7W262.js.map
2093
+ //# sourceMappingURL=chunk-JPO7W262.js.map