@nicia-ai/typegraph 0.9.2 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +279 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +279 -114
- package/dist/index.js.map +1 -1
- package/dist/interchange/index.d.cts +1 -1
- package/dist/interchange/index.d.ts +1 -1
- package/dist/profiler/index.d.cts +1 -1
- package/dist/profiler/index.d.ts +1 -1
- package/dist/{store-DgzIgrmn.d.cts → store-DyGdpDFr.d.cts} +103 -3
- package/dist/{store-wqOO3GSy.d.ts → store-nQ1ATBlN.d.ts} +103 -3
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -3033,7 +3033,7 @@ function compileRecursiveCte(ast, traversal, graphId, ctx, requiredColumnsByAlia
|
|
|
3033
3033
|
recursiveBaseWhereClauses.push(cycleCheck);
|
|
3034
3034
|
}
|
|
3035
3035
|
recursiveBaseWhereClauses.push(...edgePredicates, ...targetNodePredicates);
|
|
3036
|
-
function
|
|
3036
|
+
function compileRecursiveBranch2(branch) {
|
|
3037
3037
|
const recursiveFilterClauses = [
|
|
3038
3038
|
...recursiveBaseWhereClauses,
|
|
3039
3039
|
compileKindFilter2(branch.edgeKinds, "e.kind"),
|
|
@@ -3088,7 +3088,7 @@ function compileRecursiveCte(ast, traversal, graphId, ctx, requiredColumnsByAlia
|
|
|
3088
3088
|
const directTargetField = direction === "out" ? "to_id" : "from_id";
|
|
3089
3089
|
const directJoinKindField = direction === "out" ? "from_kind" : "to_kind";
|
|
3090
3090
|
const directTargetKindField = direction === "out" ? "to_kind" : "from_kind";
|
|
3091
|
-
const directBranch =
|
|
3091
|
+
const directBranch = compileRecursiveBranch2({
|
|
3092
3092
|
joinField: directJoinField,
|
|
3093
3093
|
targetField: directTargetField,
|
|
3094
3094
|
joinKindField: directJoinKindField,
|
|
@@ -3104,7 +3104,7 @@ function compileRecursiveCte(ast, traversal, graphId, ctx, requiredColumnsByAlia
|
|
|
3104
3104
|
(kind) => directEdgeKinds.includes(kind)
|
|
3105
3105
|
);
|
|
3106
3106
|
const duplicateGuard = overlappingKinds.length > 0 ? drizzleOrm.sql`NOT (e.from_id = e.to_id AND ${compileKindFilter2(overlappingKinds, "e.kind")})` : void 0;
|
|
3107
|
-
const inverseBranch =
|
|
3107
|
+
const inverseBranch = compileRecursiveBranch2({
|
|
3108
3108
|
joinField: inverseJoinField,
|
|
3109
3109
|
targetField: inverseTargetField,
|
|
3110
3110
|
joinKindField: inverseJoinKindField,
|
|
@@ -8267,21 +8267,29 @@ function narrowEdge(edge) {
|
|
|
8267
8267
|
function narrowEdges(edges) {
|
|
8268
8268
|
return edges;
|
|
8269
8269
|
}
|
|
8270
|
+
function buildCreateEdgeInput(kind, from, to, props, options) {
|
|
8271
|
+
const input = {
|
|
8272
|
+
kind,
|
|
8273
|
+
fromKind: from.kind,
|
|
8274
|
+
fromId: from.id,
|
|
8275
|
+
toKind: to.kind,
|
|
8276
|
+
toId: to.id,
|
|
8277
|
+
props
|
|
8278
|
+
};
|
|
8279
|
+
if (options?.id !== void 0) input.id = options.id;
|
|
8280
|
+
if (options?.validFrom !== void 0) input.validFrom = options.validFrom;
|
|
8281
|
+
if (options?.validTo !== void 0) input.validTo = options.validTo;
|
|
8282
|
+
return input;
|
|
8283
|
+
}
|
|
8284
|
+
function buildUpdateEdgeInput(id, props, options) {
|
|
8285
|
+
const input = { id, props };
|
|
8286
|
+
if (options?.validTo !== void 0) input.validTo = options.validTo;
|
|
8287
|
+
return input;
|
|
8288
|
+
}
|
|
8270
8289
|
function mapBulkEdgeInputs(kind, items) {
|
|
8271
|
-
return items.map(
|
|
8272
|
-
|
|
8273
|
-
|
|
8274
|
-
fromKind: item.from.kind,
|
|
8275
|
-
fromId: item.from.id,
|
|
8276
|
-
toKind: item.to.kind,
|
|
8277
|
-
toId: item.to.id,
|
|
8278
|
-
props: item.props ?? {}
|
|
8279
|
-
};
|
|
8280
|
-
if (item.id !== void 0) input.id = item.id;
|
|
8281
|
-
if (item.validFrom !== void 0) input.validFrom = item.validFrom;
|
|
8282
|
-
if (item.validTo !== void 0) input.validTo = item.validTo;
|
|
8283
|
-
return input;
|
|
8284
|
-
});
|
|
8290
|
+
return items.map(
|
|
8291
|
+
(item) => buildCreateEdgeInput(kind, item.from, item.to, item.props ?? {}, item)
|
|
8292
|
+
);
|
|
8285
8293
|
}
|
|
8286
8294
|
function createEdgeCollection(config) {
|
|
8287
8295
|
const {
|
|
@@ -8301,18 +8309,16 @@ function createEdgeCollection(config) {
|
|
|
8301
8309
|
} = config;
|
|
8302
8310
|
return {
|
|
8303
8311
|
async create(from, to, props, options) {
|
|
8304
|
-
const
|
|
8305
|
-
|
|
8306
|
-
|
|
8307
|
-
|
|
8308
|
-
|
|
8309
|
-
|
|
8310
|
-
|
|
8311
|
-
|
|
8312
|
-
|
|
8313
|
-
|
|
8314
|
-
if (options?.validTo !== void 0) input.validTo = options.validTo;
|
|
8315
|
-
const result = await executeEdgeCreate2(input, backend);
|
|
8312
|
+
const result = await executeEdgeCreate2(
|
|
8313
|
+
buildCreateEdgeInput(
|
|
8314
|
+
kind,
|
|
8315
|
+
from,
|
|
8316
|
+
to,
|
|
8317
|
+
props ?? {},
|
|
8318
|
+
options
|
|
8319
|
+
),
|
|
8320
|
+
backend
|
|
8321
|
+
);
|
|
8316
8322
|
return narrowEdge(result);
|
|
8317
8323
|
},
|
|
8318
8324
|
async getById(id, options) {
|
|
@@ -8349,12 +8355,10 @@ function createEdgeCollection(config) {
|
|
|
8349
8355
|
);
|
|
8350
8356
|
},
|
|
8351
8357
|
async update(id, props, options) {
|
|
8352
|
-
const
|
|
8353
|
-
id,
|
|
8354
|
-
|
|
8355
|
-
|
|
8356
|
-
if (options?.validTo !== void 0) input.validTo = options.validTo;
|
|
8357
|
-
const result = await executeEdgeUpdate2(input, backend);
|
|
8358
|
+
const result = await executeEdgeUpdate2(
|
|
8359
|
+
buildUpdateEdgeInput(id, props, options),
|
|
8360
|
+
backend
|
|
8361
|
+
);
|
|
8358
8362
|
return narrowEdge(result);
|
|
8359
8363
|
},
|
|
8360
8364
|
async findFrom(from) {
|
|
@@ -8467,29 +8471,26 @@ function createEdgeCollection(config) {
|
|
|
8467
8471
|
for (const item of items) {
|
|
8468
8472
|
const existing = existingMap.get(item.id);
|
|
8469
8473
|
if (existing) {
|
|
8470
|
-
const input = {
|
|
8471
|
-
id: item.id,
|
|
8472
|
-
props: item.props
|
|
8473
|
-
};
|
|
8474
|
-
if (item.validTo !== void 0) input.validTo = item.validTo;
|
|
8475
8474
|
toUpdate.push({
|
|
8476
8475
|
index: itemIndex,
|
|
8477
|
-
input
|
|
8476
|
+
input: buildUpdateEdgeInput(
|
|
8477
|
+
item.id,
|
|
8478
|
+
item.props ?? {},
|
|
8479
|
+
item
|
|
8480
|
+
),
|
|
8478
8481
|
clearDeleted: existing.deleted_at !== void 0
|
|
8479
8482
|
});
|
|
8480
8483
|
} else {
|
|
8481
|
-
|
|
8482
|
-
|
|
8483
|
-
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
|
|
8491
|
-
if (item.validTo !== void 0) input.validTo = item.validTo;
|
|
8492
|
-
toCreate.push({ index: itemIndex, input });
|
|
8484
|
+
toCreate.push({
|
|
8485
|
+
index: itemIndex,
|
|
8486
|
+
input: buildCreateEdgeInput(
|
|
8487
|
+
kind,
|
|
8488
|
+
item.from,
|
|
8489
|
+
item.to,
|
|
8490
|
+
item.props ?? {},
|
|
8491
|
+
item
|
|
8492
|
+
)
|
|
8493
|
+
});
|
|
8493
8494
|
}
|
|
8494
8495
|
itemIndex++;
|
|
8495
8496
|
}
|
|
@@ -8618,17 +8619,20 @@ function narrowNode(node) {
|
|
|
8618
8619
|
function narrowNodes(nodes) {
|
|
8619
8620
|
return nodes;
|
|
8620
8621
|
}
|
|
8622
|
+
function buildCreateInput(kind, props, options) {
|
|
8623
|
+
const input = { kind, props };
|
|
8624
|
+
if (options?.id !== void 0) input.id = options.id;
|
|
8625
|
+
if (options?.validFrom !== void 0) input.validFrom = options.validFrom;
|
|
8626
|
+
if (options?.validTo !== void 0) input.validTo = options.validTo;
|
|
8627
|
+
return input;
|
|
8628
|
+
}
|
|
8629
|
+
function buildUpdateInput(kind, id, props, options) {
|
|
8630
|
+
const input = { kind, id, props };
|
|
8631
|
+
if (options?.validTo !== void 0) input.validTo = options.validTo;
|
|
8632
|
+
return input;
|
|
8633
|
+
}
|
|
8621
8634
|
function mapBulkNodeInputs(kind, items) {
|
|
8622
|
-
return items.map((item) =>
|
|
8623
|
-
const input = {
|
|
8624
|
-
kind,
|
|
8625
|
-
props: item.props
|
|
8626
|
-
};
|
|
8627
|
-
if (item.id !== void 0) input.id = item.id;
|
|
8628
|
-
if (item.validFrom !== void 0) input.validFrom = item.validFrom;
|
|
8629
|
-
if (item.validTo !== void 0) input.validTo = item.validTo;
|
|
8630
|
-
return input;
|
|
8631
|
-
});
|
|
8635
|
+
return items.map((item) => buildCreateInput(kind, item.props, item));
|
|
8632
8636
|
}
|
|
8633
8637
|
function createNodeCollection(config) {
|
|
8634
8638
|
const {
|
|
@@ -8653,14 +8657,13 @@ function createNodeCollection(config) {
|
|
|
8653
8657
|
} = config;
|
|
8654
8658
|
return {
|
|
8655
8659
|
async create(props, options) {
|
|
8656
|
-
|
|
8657
|
-
|
|
8658
|
-
|
|
8659
|
-
|
|
8660
|
-
|
|
8661
|
-
|
|
8662
|
-
|
|
8663
|
-
const result = await executeNodeCreate2(input, backend);
|
|
8660
|
+
return this.createFromRecord(props, options);
|
|
8661
|
+
},
|
|
8662
|
+
async createFromRecord(data, options) {
|
|
8663
|
+
const result = await executeNodeCreate2(
|
|
8664
|
+
buildCreateInput(kind, data, options),
|
|
8665
|
+
backend
|
|
8666
|
+
);
|
|
8664
8667
|
return narrowNode(result);
|
|
8665
8668
|
},
|
|
8666
8669
|
async getById(id, options) {
|
|
@@ -8698,13 +8701,10 @@ function createNodeCollection(config) {
|
|
|
8698
8701
|
);
|
|
8699
8702
|
},
|
|
8700
8703
|
async update(id, props, options) {
|
|
8701
|
-
const
|
|
8702
|
-
kind,
|
|
8703
|
-
|
|
8704
|
-
|
|
8705
|
-
};
|
|
8706
|
-
if (options?.validTo !== void 0) input.validTo = options.validTo;
|
|
8707
|
-
const result = await executeNodeUpdate2(input, backend);
|
|
8704
|
+
const result = await executeNodeUpdate2(
|
|
8705
|
+
buildUpdateInput(kind, id, props, options),
|
|
8706
|
+
backend
|
|
8707
|
+
);
|
|
8708
8708
|
return narrowNode(result);
|
|
8709
8709
|
},
|
|
8710
8710
|
async delete(id) {
|
|
@@ -8760,31 +8760,28 @@ function createNodeCollection(config) {
|
|
|
8760
8760
|
return backend.countNodesByKind(params);
|
|
8761
8761
|
},
|
|
8762
8762
|
async upsertById(id, props, options) {
|
|
8763
|
+
return this.upsertByIdFromRecord(
|
|
8764
|
+
id,
|
|
8765
|
+
props,
|
|
8766
|
+
options
|
|
8767
|
+
);
|
|
8768
|
+
},
|
|
8769
|
+
async upsertByIdFromRecord(id, data, options) {
|
|
8763
8770
|
const existing = await backend.getNode(graphId, kind, id);
|
|
8764
8771
|
if (existing) {
|
|
8765
|
-
const input = {
|
|
8766
|
-
kind,
|
|
8767
|
-
id,
|
|
8768
|
-
props
|
|
8769
|
-
};
|
|
8770
|
-
if (options?.validTo !== void 0) input.validTo = options.validTo;
|
|
8771
8772
|
const clearDeleted = existing.deleted_at !== void 0;
|
|
8772
|
-
const
|
|
8773
|
-
|
|
8774
|
-
|
|
8775
|
-
|
|
8776
|
-
|
|
8777
|
-
|
|
8778
|
-
kind,
|
|
8779
|
-
id,
|
|
8780
|
-
props
|
|
8781
|
-
};
|
|
8782
|
-
if (options?.validFrom !== void 0)
|
|
8783
|
-
input.validFrom = options.validFrom;
|
|
8784
|
-
if (options?.validTo !== void 0) input.validTo = options.validTo;
|
|
8785
|
-
const result = await executeNodeCreate2(input, backend);
|
|
8786
|
-
return narrowNode(result);
|
|
8773
|
+
const result2 = await executeNodeUpdate2(
|
|
8774
|
+
buildUpdateInput(kind, id, data, options),
|
|
8775
|
+
backend,
|
|
8776
|
+
{ clearDeleted }
|
|
8777
|
+
);
|
|
8778
|
+
return narrowNode(result2);
|
|
8787
8779
|
}
|
|
8780
|
+
const result = await executeNodeCreate2(
|
|
8781
|
+
buildCreateInput(kind, data, { ...options, id }),
|
|
8782
|
+
backend
|
|
8783
|
+
);
|
|
8784
|
+
return narrowNode(result);
|
|
8788
8785
|
},
|
|
8789
8786
|
async bulkCreate(items) {
|
|
8790
8787
|
const batchInputs = mapBulkNodeInputs(
|
|
@@ -8828,26 +8825,25 @@ function createNodeCollection(config) {
|
|
|
8828
8825
|
for (const item of items) {
|
|
8829
8826
|
const existing = existingMap.get(item.id);
|
|
8830
8827
|
if (existing) {
|
|
8831
|
-
const input = {
|
|
8832
|
-
kind,
|
|
8833
|
-
id: item.id,
|
|
8834
|
-
props: item.props
|
|
8835
|
-
};
|
|
8836
|
-
if (item.validTo !== void 0) input.validTo = item.validTo;
|
|
8837
8828
|
toUpdate.push({
|
|
8838
8829
|
index: itemIndex,
|
|
8839
|
-
input
|
|
8830
|
+
input: buildUpdateInput(
|
|
8831
|
+
kind,
|
|
8832
|
+
item.id,
|
|
8833
|
+
item.props,
|
|
8834
|
+
item
|
|
8835
|
+
),
|
|
8840
8836
|
clearDeleted: existing.deleted_at !== void 0
|
|
8841
8837
|
});
|
|
8842
8838
|
} else {
|
|
8843
|
-
|
|
8844
|
-
|
|
8845
|
-
|
|
8846
|
-
|
|
8847
|
-
|
|
8848
|
-
|
|
8849
|
-
|
|
8850
|
-
|
|
8839
|
+
toCreate.push({
|
|
8840
|
+
index: itemIndex,
|
|
8841
|
+
input: buildCreateInput(
|
|
8842
|
+
kind,
|
|
8843
|
+
item.props,
|
|
8844
|
+
item
|
|
8845
|
+
)
|
|
8846
|
+
});
|
|
8851
8847
|
}
|
|
8852
8848
|
itemIndex++;
|
|
8853
8849
|
}
|
|
@@ -11188,6 +11184,142 @@ async function executeNodeBulkGetOrCreateByConstraint(ctx, kind, constraintName,
|
|
|
11188
11184
|
}
|
|
11189
11185
|
return results;
|
|
11190
11186
|
}
|
|
11187
|
+
var DEFAULT_SUBGRAPH_MAX_DEPTH = 10;
|
|
11188
|
+
function normalizeProps(value) {
|
|
11189
|
+
return typeof value === "string" ? value : JSON.stringify(value ?? {});
|
|
11190
|
+
}
|
|
11191
|
+
async function executeSubgraph(params) {
|
|
11192
|
+
const { options } = params;
|
|
11193
|
+
if (options.edges.length === 0) {
|
|
11194
|
+
return { nodes: [], edges: [] };
|
|
11195
|
+
}
|
|
11196
|
+
const maxDepth = Math.min(
|
|
11197
|
+
options.maxDepth ?? DEFAULT_SUBGRAPH_MAX_DEPTH,
|
|
11198
|
+
MAX_RECURSIVE_DEPTH
|
|
11199
|
+
);
|
|
11200
|
+
const ctx = {
|
|
11201
|
+
graphId: params.graphId,
|
|
11202
|
+
rootId: params.rootId,
|
|
11203
|
+
edgeKinds: options.edges,
|
|
11204
|
+
maxDepth,
|
|
11205
|
+
includeKinds: options.includeKinds,
|
|
11206
|
+
excludeRoot: options.excludeRoot ?? false,
|
|
11207
|
+
direction: options.direction ?? "out",
|
|
11208
|
+
cyclePolicy: options.cyclePolicy ?? "prevent",
|
|
11209
|
+
dialect: params.dialect,
|
|
11210
|
+
schema: params.schema ?? DEFAULT_SQL_SCHEMA,
|
|
11211
|
+
backend: params.backend
|
|
11212
|
+
};
|
|
11213
|
+
const reachableCte = buildReachableCte(ctx);
|
|
11214
|
+
const includedIdsCte = buildIncludedIdsCte(ctx);
|
|
11215
|
+
const [nodeRows, edgeRows] = await Promise.all([
|
|
11216
|
+
fetchSubgraphNodes(ctx, reachableCte, includedIdsCte),
|
|
11217
|
+
fetchSubgraphEdges(ctx, reachableCte, includedIdsCte)
|
|
11218
|
+
]);
|
|
11219
|
+
const nodes = nodeRows.map(
|
|
11220
|
+
(row) => rowToNode({ ...row, props: normalizeProps(row.props) })
|
|
11221
|
+
);
|
|
11222
|
+
const edges = edgeRows.map(
|
|
11223
|
+
(row) => rowToEdge({ ...row, props: normalizeProps(row.props) })
|
|
11224
|
+
);
|
|
11225
|
+
return {
|
|
11226
|
+
nodes,
|
|
11227
|
+
edges
|
|
11228
|
+
};
|
|
11229
|
+
}
|
|
11230
|
+
function buildReachableCte(ctx) {
|
|
11231
|
+
const shouldTrackPath = ctx.cyclePolicy === "prevent";
|
|
11232
|
+
const edgeKindFilter = compileKindFilter(drizzleOrm.sql.raw("e.kind"), ctx.edgeKinds);
|
|
11233
|
+
const initialPath = shouldTrackPath ? ctx.dialect.initializePath(drizzleOrm.sql.raw("n.id")) : void 0;
|
|
11234
|
+
const pathExtension = shouldTrackPath ? ctx.dialect.extendPath(drizzleOrm.sql.raw("r.path"), drizzleOrm.sql.raw("n.id")) : void 0;
|
|
11235
|
+
const cycleCheck = shouldTrackPath ? ctx.dialect.cycleCheck(drizzleOrm.sql.raw("n.id"), drizzleOrm.sql.raw("r.path")) : void 0;
|
|
11236
|
+
const baseColumns = [drizzleOrm.sql`n.id`, drizzleOrm.sql`n.kind`, drizzleOrm.sql`0 AS depth`];
|
|
11237
|
+
if (initialPath !== void 0) {
|
|
11238
|
+
baseColumns.push(drizzleOrm.sql`${initialPath} AS path`);
|
|
11239
|
+
}
|
|
11240
|
+
const baseCase = drizzleOrm.sql`SELECT ${drizzleOrm.sql.join(baseColumns, drizzleOrm.sql`, `)} FROM ${ctx.schema.nodesTable} n WHERE n.graph_id = ${ctx.graphId} AND n.id = ${ctx.rootId} AND n.deleted_at IS NULL`;
|
|
11241
|
+
const recursiveColumns = [
|
|
11242
|
+
drizzleOrm.sql`n.id`,
|
|
11243
|
+
drizzleOrm.sql`n.kind`,
|
|
11244
|
+
drizzleOrm.sql`r.depth + 1 AS depth`
|
|
11245
|
+
];
|
|
11246
|
+
if (pathExtension !== void 0) {
|
|
11247
|
+
recursiveColumns.push(drizzleOrm.sql`${pathExtension} AS path`);
|
|
11248
|
+
}
|
|
11249
|
+
const recursiveWhereClauses = [
|
|
11250
|
+
drizzleOrm.sql`e.graph_id = ${ctx.graphId}`,
|
|
11251
|
+
edgeKindFilter,
|
|
11252
|
+
drizzleOrm.sql`e.deleted_at IS NULL`,
|
|
11253
|
+
drizzleOrm.sql`n.deleted_at IS NULL`,
|
|
11254
|
+
drizzleOrm.sql`r.depth < ${ctx.maxDepth}`
|
|
11255
|
+
];
|
|
11256
|
+
if (cycleCheck !== void 0) {
|
|
11257
|
+
recursiveWhereClauses.push(cycleCheck);
|
|
11258
|
+
}
|
|
11259
|
+
const forceWorktableOuterJoinOrder = ctx.dialect.capabilities.forceRecursiveWorktableOuterJoinOrder;
|
|
11260
|
+
const recursiveCase = ctx.direction === "both" ? compileBidirectionalBranch({
|
|
11261
|
+
recursiveColumns,
|
|
11262
|
+
whereClauses: recursiveWhereClauses,
|
|
11263
|
+
forceWorktableOuterJoinOrder,
|
|
11264
|
+
schema: ctx.schema
|
|
11265
|
+
}) : compileRecursiveBranch({
|
|
11266
|
+
recursiveColumns,
|
|
11267
|
+
whereClauses: recursiveWhereClauses,
|
|
11268
|
+
joinField: "from_id",
|
|
11269
|
+
targetField: "to_id",
|
|
11270
|
+
targetKindField: "to_kind",
|
|
11271
|
+
forceWorktableOuterJoinOrder,
|
|
11272
|
+
schema: ctx.schema
|
|
11273
|
+
});
|
|
11274
|
+
return drizzleOrm.sql`WITH RECURSIVE reachable AS (${baseCase} UNION ALL ${recursiveCase})`;
|
|
11275
|
+
}
|
|
11276
|
+
function compileRecursiveBranch(params) {
|
|
11277
|
+
const columns = [...params.recursiveColumns];
|
|
11278
|
+
const selectClause = drizzleOrm.sql`SELECT ${drizzleOrm.sql.join(columns, drizzleOrm.sql`, `)}`;
|
|
11279
|
+
const nodeJoin = drizzleOrm.sql`JOIN ${params.schema.nodesTable} n ON n.graph_id = e.graph_id AND n.id = e.${drizzleOrm.sql.raw(params.targetField)} AND n.kind = e.${drizzleOrm.sql.raw(params.targetKindField)}`;
|
|
11280
|
+
if (params.forceWorktableOuterJoinOrder) {
|
|
11281
|
+
const allWhere = [
|
|
11282
|
+
...params.whereClauses,
|
|
11283
|
+
drizzleOrm.sql`e.${drizzleOrm.sql.raw(params.joinField)} = r.id`
|
|
11284
|
+
];
|
|
11285
|
+
return drizzleOrm.sql`${selectClause} FROM reachable r CROSS JOIN ${params.schema.edgesTable} e ${nodeJoin} WHERE ${drizzleOrm.sql.join(allWhere, drizzleOrm.sql` AND `)}`;
|
|
11286
|
+
}
|
|
11287
|
+
const where = [...params.whereClauses];
|
|
11288
|
+
return drizzleOrm.sql`${selectClause} FROM reachable r JOIN ${params.schema.edgesTable} e ON e.${drizzleOrm.sql.raw(params.joinField)} = r.id ${nodeJoin} WHERE ${drizzleOrm.sql.join(where, drizzleOrm.sql` AND `)}`;
|
|
11289
|
+
}
|
|
11290
|
+
function compileBidirectionalBranch(params) {
|
|
11291
|
+
const columns = [...params.recursiveColumns];
|
|
11292
|
+
const selectClause = drizzleOrm.sql`SELECT ${drizzleOrm.sql.join(columns, drizzleOrm.sql`, `)}`;
|
|
11293
|
+
const nodeJoin = drizzleOrm.sql`JOIN ${params.schema.nodesTable} n ON n.graph_id = e.graph_id AND ((e.to_id = r.id AND n.id = e.from_id AND n.kind = e.from_kind) OR (e.from_id = r.id AND n.id = e.to_id AND n.kind = e.to_kind))`;
|
|
11294
|
+
if (params.forceWorktableOuterJoinOrder) {
|
|
11295
|
+
const allWhere = [
|
|
11296
|
+
...params.whereClauses,
|
|
11297
|
+
drizzleOrm.sql`(e.from_id = r.id OR e.to_id = r.id)`
|
|
11298
|
+
];
|
|
11299
|
+
return drizzleOrm.sql`${selectClause} FROM reachable r CROSS JOIN ${params.schema.edgesTable} e ${nodeJoin} WHERE ${drizzleOrm.sql.join(allWhere, drizzleOrm.sql` AND `)}`;
|
|
11300
|
+
}
|
|
11301
|
+
return drizzleOrm.sql`${selectClause} FROM reachable r JOIN ${params.schema.edgesTable} e ON (e.from_id = r.id OR e.to_id = r.id) ${nodeJoin} WHERE ${drizzleOrm.sql.join([...params.whereClauses], drizzleOrm.sql` AND `)}`;
|
|
11302
|
+
}
|
|
11303
|
+
function buildIncludedIdsCte(ctx) {
|
|
11304
|
+
const filters = [];
|
|
11305
|
+
if (ctx.includeKinds !== void 0 && ctx.includeKinds.length > 0) {
|
|
11306
|
+
filters.push(compileKindFilter(drizzleOrm.sql.raw("kind"), ctx.includeKinds));
|
|
11307
|
+
}
|
|
11308
|
+
if (ctx.excludeRoot) {
|
|
11309
|
+
filters.push(drizzleOrm.sql`id != ${ctx.rootId}`);
|
|
11310
|
+
}
|
|
11311
|
+
const whereClause = filters.length > 0 ? drizzleOrm.sql` WHERE ${drizzleOrm.sql.join(filters, drizzleOrm.sql` AND `)}` : drizzleOrm.sql``;
|
|
11312
|
+
return drizzleOrm.sql`, included_ids AS (SELECT DISTINCT id FROM reachable${whereClause})`;
|
|
11313
|
+
}
|
|
11314
|
+
async function fetchSubgraphNodes(ctx, reachableCte, includedIdsCte) {
|
|
11315
|
+
const query = drizzleOrm.sql`${reachableCte}${includedIdsCte} SELECT n.kind, n.id, n.props, n.version, n.valid_from, n.valid_to, n.created_at, n.updated_at, n.deleted_at FROM ${ctx.schema.nodesTable} n WHERE n.graph_id = ${ctx.graphId} AND n.id IN (SELECT id FROM included_ids)`;
|
|
11316
|
+
return ctx.backend.execute(query);
|
|
11317
|
+
}
|
|
11318
|
+
async function fetchSubgraphEdges(ctx, reachableCte, includedIdsCte) {
|
|
11319
|
+
const edgeKindFilter = compileKindFilter(drizzleOrm.sql.raw("e.kind"), ctx.edgeKinds);
|
|
11320
|
+
const query = drizzleOrm.sql`${reachableCte}${includedIdsCte} SELECT e.id, e.kind, e.from_kind, e.from_id, e.to_kind, e.to_id, e.props, e.valid_from, e.valid_to, e.created_at, e.updated_at, e.deleted_at FROM ${ctx.schema.edgesTable} e WHERE e.graph_id = ${ctx.graphId} AND ${edgeKindFilter} AND e.deleted_at IS NULL AND e.from_id IN (SELECT id FROM included_ids) AND e.to_id IN (SELECT id FROM included_ids)`;
|
|
11321
|
+
return ctx.backend.execute(query);
|
|
11322
|
+
}
|
|
11191
11323
|
|
|
11192
11324
|
// src/store/store.ts
|
|
11193
11325
|
var Store = class {
|
|
@@ -11391,6 +11523,39 @@ var Store = class {
|
|
|
11391
11523
|
query() {
|
|
11392
11524
|
return this.#createQueryForBackend(this.#backend);
|
|
11393
11525
|
}
|
|
11526
|
+
// === Subgraph Extraction ===
|
|
11527
|
+
/**
|
|
11528
|
+
* Extracts a typed subgraph by traversing from a root node.
|
|
11529
|
+
*
|
|
11530
|
+
* Performs a BFS traversal from `rootId` following the specified edge kinds,
|
|
11531
|
+
* then returns all reachable nodes and the edges connecting them.
|
|
11532
|
+
*
|
|
11533
|
+
* @example
|
|
11534
|
+
* ```typescript
|
|
11535
|
+
* const result = await store.subgraph(run.id, {
|
|
11536
|
+
* edges: ["has_task", "runs_agent", "uses_skill"],
|
|
11537
|
+
* maxDepth: 4,
|
|
11538
|
+
* includeKinds: ["Run", "Task", "Agent", "Skill"],
|
|
11539
|
+
* });
|
|
11540
|
+
*
|
|
11541
|
+
* for (const node of result.nodes) {
|
|
11542
|
+
* switch (node.kind) {
|
|
11543
|
+
* case "Task": console.log(node.name); break;
|
|
11544
|
+
* case "Agent": console.log(node.model); break;
|
|
11545
|
+
* }
|
|
11546
|
+
* }
|
|
11547
|
+
* ```
|
|
11548
|
+
*/
|
|
11549
|
+
async subgraph(rootId, options) {
|
|
11550
|
+
return executeSubgraph({
|
|
11551
|
+
graphId: this.graphId,
|
|
11552
|
+
rootId,
|
|
11553
|
+
backend: this.#backend,
|
|
11554
|
+
dialect: chunk2WVFEIHR_cjs.getDialect(this.#backend.dialect),
|
|
11555
|
+
schema: this.#schema,
|
|
11556
|
+
options
|
|
11557
|
+
});
|
|
11558
|
+
}
|
|
11394
11559
|
// === Transactions ===
|
|
11395
11560
|
/**
|
|
11396
11561
|
* Executes a function within a transaction.
|