@utaba/deep-memory 0.5.0 → 0.6.1
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 +364 -362
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +362 -361
- package/dist/index.js.map +1 -1
- package/dist/providers/index.d.cts +18 -10
- package/dist/providers/index.d.ts +18 -10
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -49,7 +49,8 @@ __export(src_exports, {
|
|
|
49
49
|
VocabularyValidationError: () => VocabularyValidationError,
|
|
50
50
|
generateId: () => generateId,
|
|
51
51
|
isValidUuid: () => isValidUuid,
|
|
52
|
-
matchesPropertyFilters: () => matchesPropertyFilters
|
|
52
|
+
matchesPropertyFilters: () => matchesPropertyFilters,
|
|
53
|
+
projectEntity: () => projectEntity
|
|
53
54
|
});
|
|
54
55
|
module.exports = __toCommonJS(src_exports);
|
|
55
56
|
|
|
@@ -956,310 +957,6 @@ function validateTraversalSpec(spec, vocabulary, capabilities) {
|
|
|
956
957
|
};
|
|
957
958
|
}
|
|
958
959
|
|
|
959
|
-
// src/relationships/compilers/GremlinCompiler.ts
|
|
960
|
-
var DEFAULT_ESTIMATED_FANOUT_PER_HOP = 10;
|
|
961
|
-
var GremlinCompiler = class {
|
|
962
|
-
language = "gremlin";
|
|
963
|
-
compile(spec, _vocabulary) {
|
|
964
|
-
const parts = [];
|
|
965
|
-
const params = {};
|
|
966
|
-
let paramIndex = 0;
|
|
967
|
-
let estimatedFanOut = 1;
|
|
968
|
-
const nextParam = (value) => {
|
|
969
|
-
const name = `p${paramIndex++}`;
|
|
970
|
-
params[name] = value;
|
|
971
|
-
return name;
|
|
972
|
-
};
|
|
973
|
-
parts.push("g.V()");
|
|
974
|
-
if (spec.start.entityId) {
|
|
975
|
-
const p = nextParam(spec.start.entityId);
|
|
976
|
-
parts.push(`.has('id', ${p})`);
|
|
977
|
-
} else if (spec.start.entityType) {
|
|
978
|
-
const p = nextParam(spec.start.entityType);
|
|
979
|
-
parts.push(`.has('entityType', ${p})`);
|
|
980
|
-
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
981
|
-
}
|
|
982
|
-
if (spec.start.filter) {
|
|
983
|
-
for (const f of spec.start.filter) {
|
|
984
|
-
parts.push(compilePropertyFilter(f, nextParam));
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
const steps = spec.steps ?? [];
|
|
988
|
-
for (const step of steps) {
|
|
989
|
-
if (step.repeat) {
|
|
990
|
-
parts.push(compileRepeatStep(step, nextParam));
|
|
991
|
-
estimatedFanOut *= step.repeat.maxDepth * DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
992
|
-
} else if (step.relationshipFilter && step.relationshipFilter.length > 0) {
|
|
993
|
-
parts.push(compileEdgeStep(step, nextParam));
|
|
994
|
-
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
995
|
-
} else {
|
|
996
|
-
parts.push(compileSimpleStep(step, nextParam));
|
|
997
|
-
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
998
|
-
}
|
|
999
|
-
if (step.entityTypes && step.entityTypes.length > 0) {
|
|
1000
|
-
const typeParams = step.entityTypes.map((t) => nextParam(t));
|
|
1001
|
-
parts.push(`.has('entityType', within(${typeParams.join(", ")}))`);
|
|
1002
|
-
}
|
|
1003
|
-
if (step.entityFilter) {
|
|
1004
|
-
for (const f of step.entityFilter) {
|
|
1005
|
-
parts.push(compilePropertyFilter(f, nextParam));
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
if (spec.returnMode === "all") {
|
|
1010
|
-
}
|
|
1011
|
-
if (spec.dedup !== false) {
|
|
1012
|
-
parts.push(".dedup()");
|
|
1013
|
-
}
|
|
1014
|
-
const limit = spec.limit ?? 50;
|
|
1015
|
-
const offset = spec.offset ?? 0;
|
|
1016
|
-
const pOffset = nextParam(offset);
|
|
1017
|
-
const pEnd = nextParam(offset + limit);
|
|
1018
|
-
parts.push(`.range(${pOffset}, ${pEnd})`);
|
|
1019
|
-
params["_limit"] = limit;
|
|
1020
|
-
params["_offset"] = offset;
|
|
1021
|
-
if (spec.returnMode === "path") {
|
|
1022
|
-
parts.push(".path()");
|
|
1023
|
-
}
|
|
1024
|
-
if (spec.returnMode !== "path") {
|
|
1025
|
-
parts.push(".valueMap(true)");
|
|
1026
|
-
}
|
|
1027
|
-
return {
|
|
1028
|
-
query: parts.join(""),
|
|
1029
|
-
params,
|
|
1030
|
-
estimatedFanOut: Math.min(estimatedFanOut, 1e4)
|
|
1031
|
-
};
|
|
1032
|
-
}
|
|
1033
|
-
};
|
|
1034
|
-
function compileSimpleStep(step, nextParam) {
|
|
1035
|
-
const types = step.relationshipTypes;
|
|
1036
|
-
const typeArgs = types ? types.map((t) => nextParam(t)).join(", ") : "";
|
|
1037
|
-
switch (step.direction) {
|
|
1038
|
-
case "out":
|
|
1039
|
-
return types ? `.out(${typeArgs})` : ".out()";
|
|
1040
|
-
case "in":
|
|
1041
|
-
return types ? `.in(${typeArgs})` : ".in()";
|
|
1042
|
-
case "both":
|
|
1043
|
-
return types ? `.both(${typeArgs})` : ".both()";
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
function compileEdgeStep(step, nextParam) {
|
|
1047
|
-
const parts = [];
|
|
1048
|
-
const types = step.relationshipTypes;
|
|
1049
|
-
const typeArgs = types ? types.map((t) => nextParam(t)).join(", ") : "";
|
|
1050
|
-
switch (step.direction) {
|
|
1051
|
-
case "out":
|
|
1052
|
-
parts.push(types ? `.outE(${typeArgs})` : ".outE()");
|
|
1053
|
-
break;
|
|
1054
|
-
case "in":
|
|
1055
|
-
parts.push(types ? `.inE(${typeArgs})` : ".inE()");
|
|
1056
|
-
break;
|
|
1057
|
-
case "both":
|
|
1058
|
-
parts.push(types ? `.bothE(${typeArgs})` : ".bothE()");
|
|
1059
|
-
break;
|
|
1060
|
-
}
|
|
1061
|
-
if (step.relationshipFilter) {
|
|
1062
|
-
for (const f of step.relationshipFilter) {
|
|
1063
|
-
parts.push(compilePropertyFilter(f, nextParam));
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
switch (step.direction) {
|
|
1067
|
-
case "out":
|
|
1068
|
-
parts.push(".inV()");
|
|
1069
|
-
break;
|
|
1070
|
-
case "in":
|
|
1071
|
-
parts.push(".outV()");
|
|
1072
|
-
break;
|
|
1073
|
-
case "both":
|
|
1074
|
-
parts.push(".otherV()");
|
|
1075
|
-
break;
|
|
1076
|
-
}
|
|
1077
|
-
return parts.join("");
|
|
1078
|
-
}
|
|
1079
|
-
function compileRepeatStep(step, nextParam) {
|
|
1080
|
-
const parts = [];
|
|
1081
|
-
const innerStep = step.relationshipFilter?.length ? compileEdgeStep({ ...step, repeat: void 0 }, nextParam) : compileSimpleStep(step, nextParam);
|
|
1082
|
-
if (step.repeat?.emitIntermediates !== false) {
|
|
1083
|
-
parts.push(".emit()");
|
|
1084
|
-
}
|
|
1085
|
-
parts.push(`.repeat(${innerStep.startsWith(".") ? `__${innerStep}` : innerStep})`);
|
|
1086
|
-
if (step.repeat?.until && step.repeat.until.length > 0) {
|
|
1087
|
-
const untilParts = step.repeat.until.map((f) => compilePropertyFilter(f, nextParam));
|
|
1088
|
-
parts.push(`.until(${untilParts.join("")})`);
|
|
1089
|
-
}
|
|
1090
|
-
if (step.repeat?.maxDepth) {
|
|
1091
|
-
const p = nextParam(step.repeat.maxDepth);
|
|
1092
|
-
parts.push(`.times(${p})`);
|
|
1093
|
-
}
|
|
1094
|
-
if (step.repeat?.emitIntermediates === false) {
|
|
1095
|
-
parts.push(".emit()");
|
|
1096
|
-
}
|
|
1097
|
-
return parts.join("");
|
|
1098
|
-
}
|
|
1099
|
-
function compilePropertyFilter(filter, nextParam) {
|
|
1100
|
-
const key = nextParam(filter.key);
|
|
1101
|
-
switch (filter.operator) {
|
|
1102
|
-
case "eq": {
|
|
1103
|
-
const val = nextParam(filter.value);
|
|
1104
|
-
return `.has(${key}, ${val})`;
|
|
1105
|
-
}
|
|
1106
|
-
case "neq": {
|
|
1107
|
-
const val = nextParam(filter.value);
|
|
1108
|
-
return `.has(${key}, neq(${val}))`;
|
|
1109
|
-
}
|
|
1110
|
-
case "gt": {
|
|
1111
|
-
const val = nextParam(filter.value);
|
|
1112
|
-
return `.has(${key}, gt(${val}))`;
|
|
1113
|
-
}
|
|
1114
|
-
case "gte": {
|
|
1115
|
-
const val = nextParam(filter.value);
|
|
1116
|
-
return `.has(${key}, gte(${val}))`;
|
|
1117
|
-
}
|
|
1118
|
-
case "lt": {
|
|
1119
|
-
const val = nextParam(filter.value);
|
|
1120
|
-
return `.has(${key}, lt(${val}))`;
|
|
1121
|
-
}
|
|
1122
|
-
case "lte": {
|
|
1123
|
-
const val = nextParam(filter.value);
|
|
1124
|
-
return `.has(${key}, lte(${val}))`;
|
|
1125
|
-
}
|
|
1126
|
-
case "contains": {
|
|
1127
|
-
const val = nextParam(filter.value);
|
|
1128
|
-
return `.has(${key}, containing(${val}))`;
|
|
1129
|
-
}
|
|
1130
|
-
case "isNull":
|
|
1131
|
-
return `.hasNot(${key})`;
|
|
1132
|
-
case "isNotNull":
|
|
1133
|
-
return `.has(${key})`;
|
|
1134
|
-
}
|
|
1135
|
-
}
|
|
1136
|
-
|
|
1137
|
-
// src/relationships/compilers/CypherCompiler.ts
|
|
1138
|
-
var DEFAULT_ESTIMATED_FANOUT_PER_HOP2 = 10;
|
|
1139
|
-
var CypherCompiler = class {
|
|
1140
|
-
language = "cypher";
|
|
1141
|
-
compile(spec, _vocabulary) {
|
|
1142
|
-
const params = {};
|
|
1143
|
-
let paramIndex = 0;
|
|
1144
|
-
let estimatedFanOut = 1;
|
|
1145
|
-
const whereClauses = [];
|
|
1146
|
-
let nodeIndex = 0;
|
|
1147
|
-
const nextParam = (value) => {
|
|
1148
|
-
const name = `p${paramIndex++}`;
|
|
1149
|
-
params[name] = value;
|
|
1150
|
-
return `$${name}`;
|
|
1151
|
-
};
|
|
1152
|
-
const startNode = `n${nodeIndex++}`;
|
|
1153
|
-
let matchParts = [];
|
|
1154
|
-
if (spec.start.entityId) {
|
|
1155
|
-
matchParts.push(`(${startNode})`);
|
|
1156
|
-
whereClauses.push(`${startNode}.id = ${nextParam(spec.start.entityId)}`);
|
|
1157
|
-
} else if (spec.start.entityType) {
|
|
1158
|
-
matchParts.push(`(${startNode})`);
|
|
1159
|
-
whereClauses.push(`${startNode}.entityType = ${nextParam(spec.start.entityType)}`);
|
|
1160
|
-
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP2;
|
|
1161
|
-
} else {
|
|
1162
|
-
matchParts.push(`(${startNode})`);
|
|
1163
|
-
}
|
|
1164
|
-
if (spec.start.filter) {
|
|
1165
|
-
for (const f of spec.start.filter) {
|
|
1166
|
-
whereClauses.push(compilePropertyFilterCypher(startNode, f, nextParam));
|
|
1167
|
-
}
|
|
1168
|
-
}
|
|
1169
|
-
let lastNode = startNode;
|
|
1170
|
-
const steps = spec.steps ?? [];
|
|
1171
|
-
for (let i = 0; i < steps.length; i++) {
|
|
1172
|
-
const step = steps[i];
|
|
1173
|
-
const targetNode = `n${nodeIndex++}`;
|
|
1174
|
-
const relAlias = `r${i}`;
|
|
1175
|
-
const relTypes = step.relationshipTypes?.length ? step.relationshipTypes.join("|") : "";
|
|
1176
|
-
const relTypePattern = relTypes ? `:${relTypes}` : "";
|
|
1177
|
-
const depthPattern = step.repeat ? `*1..${step.repeat.maxDepth}` : "";
|
|
1178
|
-
let pattern;
|
|
1179
|
-
switch (step.direction) {
|
|
1180
|
-
case "out":
|
|
1181
|
-
pattern = `-[${relAlias}${relTypePattern}${depthPattern}]->(${targetNode})`;
|
|
1182
|
-
break;
|
|
1183
|
-
case "in":
|
|
1184
|
-
pattern = `<-[${relAlias}${relTypePattern}${depthPattern}]-(${targetNode})`;
|
|
1185
|
-
break;
|
|
1186
|
-
case "both":
|
|
1187
|
-
pattern = `-[${relAlias}${relTypePattern}${depthPattern}]-(${targetNode})`;
|
|
1188
|
-
break;
|
|
1189
|
-
}
|
|
1190
|
-
matchParts.push(pattern);
|
|
1191
|
-
estimatedFanOut *= step.repeat ? step.repeat.maxDepth * DEFAULT_ESTIMATED_FANOUT_PER_HOP2 : DEFAULT_ESTIMATED_FANOUT_PER_HOP2;
|
|
1192
|
-
if (step.entityTypes && step.entityTypes.length > 0) {
|
|
1193
|
-
const typeParam = nextParam(step.entityTypes);
|
|
1194
|
-
whereClauses.push(`${targetNode}.entityType IN ${typeParam}`);
|
|
1195
|
-
}
|
|
1196
|
-
if (step.entityFilter) {
|
|
1197
|
-
for (const f of step.entityFilter) {
|
|
1198
|
-
whereClauses.push(compilePropertyFilterCypher(targetNode, f, nextParam));
|
|
1199
|
-
}
|
|
1200
|
-
}
|
|
1201
|
-
if (step.relationshipFilter) {
|
|
1202
|
-
for (const f of step.relationshipFilter) {
|
|
1203
|
-
whereClauses.push(compilePropertyFilterCypher(relAlias, f, nextParam));
|
|
1204
|
-
}
|
|
1205
|
-
}
|
|
1206
|
-
lastNode = targetNode;
|
|
1207
|
-
}
|
|
1208
|
-
const matchClause = `MATCH ${matchParts[0]}${matchParts.slice(1).join("")}`;
|
|
1209
|
-
const whereClause = whereClauses.length > 0 ? `
|
|
1210
|
-
WHERE ${whereClauses.join(" AND ")}` : "";
|
|
1211
|
-
let returnClause;
|
|
1212
|
-
if (spec.returnMode === "path") {
|
|
1213
|
-
const allNodes = Array.from({ length: nodeIndex }, (_, i) => `n${i}`);
|
|
1214
|
-
const allRels = steps.map((_, i) => `r${i}`);
|
|
1215
|
-
returnClause = `RETURN ${[...allNodes, ...allRels].join(", ")}`;
|
|
1216
|
-
} else if (spec.returnMode === "all") {
|
|
1217
|
-
const allNodes = Array.from({ length: nodeIndex }, (_, i) => `n${i}`);
|
|
1218
|
-
returnClause = spec.dedup !== false ? `RETURN DISTINCT ${allNodes.join(", ")}` : `RETURN ${allNodes.join(", ")}`;
|
|
1219
|
-
} else {
|
|
1220
|
-
returnClause = spec.dedup !== false ? `RETURN DISTINCT ${lastNode}` : `RETURN ${lastNode}`;
|
|
1221
|
-
}
|
|
1222
|
-
const offset = spec.offset ?? 0;
|
|
1223
|
-
const limit = spec.limit ?? 50;
|
|
1224
|
-
const skipClause = offset > 0 ? `
|
|
1225
|
-
SKIP ${nextParam(offset)}` : "";
|
|
1226
|
-
const limitClause = `
|
|
1227
|
-
LIMIT ${nextParam(limit)}`;
|
|
1228
|
-
params["_limit"] = limit;
|
|
1229
|
-
params["_offset"] = offset;
|
|
1230
|
-
const query = `${matchClause}${whereClause}
|
|
1231
|
-
${returnClause}${skipClause}${limitClause}`;
|
|
1232
|
-
return {
|
|
1233
|
-
query,
|
|
1234
|
-
params,
|
|
1235
|
-
estimatedFanOut: Math.min(estimatedFanOut, 1e4)
|
|
1236
|
-
};
|
|
1237
|
-
}
|
|
1238
|
-
};
|
|
1239
|
-
function compilePropertyFilterCypher(nodeAlias, filter, nextParam) {
|
|
1240
|
-
const prop = `${nodeAlias}.${filter.key}`;
|
|
1241
|
-
switch (filter.operator) {
|
|
1242
|
-
case "eq":
|
|
1243
|
-
return `${prop} = ${nextParam(filter.value)}`;
|
|
1244
|
-
case "neq":
|
|
1245
|
-
return `${prop} <> ${nextParam(filter.value)}`;
|
|
1246
|
-
case "gt":
|
|
1247
|
-
return `${prop} > ${nextParam(filter.value)}`;
|
|
1248
|
-
case "gte":
|
|
1249
|
-
return `${prop} >= ${nextParam(filter.value)}`;
|
|
1250
|
-
case "lt":
|
|
1251
|
-
return `${prop} < ${nextParam(filter.value)}`;
|
|
1252
|
-
case "lte":
|
|
1253
|
-
return `${prop} <= ${nextParam(filter.value)}`;
|
|
1254
|
-
case "contains":
|
|
1255
|
-
return `${prop} CONTAINS ${nextParam(filter.value)}`;
|
|
1256
|
-
case "isNull":
|
|
1257
|
-
return `${prop} IS NULL`;
|
|
1258
|
-
case "isNotNull":
|
|
1259
|
-
return `${prop} IS NOT NULL`;
|
|
1260
|
-
}
|
|
1261
|
-
}
|
|
1262
|
-
|
|
1263
960
|
// src/relationships/PropertyFilterMatcher.ts
|
|
1264
961
|
function matchesPropertyFilters(properties, filters) {
|
|
1265
962
|
return filters.every((filter) => matchesSingleFilter(properties, filter));
|
|
@@ -1792,8 +1489,9 @@ var GraphTraversal = class {
|
|
|
1792
1489
|
}
|
|
1793
1490
|
/**
|
|
1794
1491
|
* Execute a structured traversal.
|
|
1795
|
-
* Validates the spec,
|
|
1796
|
-
* falls back to
|
|
1492
|
+
* Validates the spec, delegates to the GraphTraversalProvider if one is
|
|
1493
|
+
* registered (the provider owns native compilation), or falls back to
|
|
1494
|
+
* application-level BFS over StorageProvider.
|
|
1797
1495
|
*/
|
|
1798
1496
|
async traverse(spec) {
|
|
1799
1497
|
const capabilities = this.graphTraversalProvider?.getCapabilities();
|
|
@@ -1808,19 +1506,8 @@ var GraphTraversal = class {
|
|
|
1808
1506
|
}
|
|
1809
1507
|
throw new TraversalValidationError(structErrors.length > 0 ? structErrors : validation.errors);
|
|
1810
1508
|
}
|
|
1811
|
-
if (this.graphTraversalProvider
|
|
1812
|
-
|
|
1813
|
-
let compiledQuery;
|
|
1814
|
-
if (language === "gremlin") {
|
|
1815
|
-
const compiler = new GremlinCompiler();
|
|
1816
|
-
const compiled = compiler.compile(spec, vocabulary);
|
|
1817
|
-
compiledQuery = compiled.query;
|
|
1818
|
-
} else if (language === "cypher") {
|
|
1819
|
-
const compiler = new CypherCompiler();
|
|
1820
|
-
const compiled = compiler.compile(spec, vocabulary);
|
|
1821
|
-
compiledQuery = compiled.query;
|
|
1822
|
-
}
|
|
1823
|
-
return this.graphTraversalProvider.traverse(this.repositoryId, spec, compiledQuery);
|
|
1509
|
+
if (this.graphTraversalProvider) {
|
|
1510
|
+
return this.graphTraversalProvider.traverse(this.repositoryId, spec);
|
|
1824
1511
|
}
|
|
1825
1512
|
return executeFallbackTraversal(this.repositoryId, this.storage, spec);
|
|
1826
1513
|
}
|
|
@@ -3407,7 +3094,7 @@ var EventBus = class {
|
|
|
3407
3094
|
};
|
|
3408
3095
|
|
|
3409
3096
|
// src/portability/RepositoryExporter.ts
|
|
3410
|
-
var LIBRARY_VERSION = true ? "0.
|
|
3097
|
+
var LIBRARY_VERSION = true ? "0.6.1" : "0.1.0";
|
|
3411
3098
|
var RepositoryExporter = class {
|
|
3412
3099
|
storage;
|
|
3413
3100
|
provenance;
|
|
@@ -4201,6 +3888,16 @@ var DeepMemory = class {
|
|
|
4201
3888
|
await this.globalEventBus.emit("repository:opened", { repositoryId });
|
|
4202
3889
|
return repo;
|
|
4203
3890
|
}
|
|
3891
|
+
/** Get the full stored record for a single repository (including legal, owner, metadata, governance) */
|
|
3892
|
+
async getRepository(repositoryId) {
|
|
3893
|
+
await this.ensureInitialized();
|
|
3894
|
+
this.validateRepositoryId(repositoryId);
|
|
3895
|
+
const storedRepo = await this.storage.getRepository(repositoryId);
|
|
3896
|
+
if (!storedRepo) {
|
|
3897
|
+
throw new RepositoryNotFoundError(repositoryId);
|
|
3898
|
+
}
|
|
3899
|
+
return storedRepo;
|
|
3900
|
+
}
|
|
4204
3901
|
/** List all repositories */
|
|
4205
3902
|
async listRepositories(filter) {
|
|
4206
3903
|
await this.ensureInitialized();
|
|
@@ -4373,54 +4070,358 @@ var DeepMemory = class {
|
|
|
4373
4070
|
relationshipCount
|
|
4374
4071
|
});
|
|
4375
4072
|
}
|
|
4376
|
-
/**
|
|
4377
|
-
* Import a repository from a stream of chunks.
|
|
4378
|
-
* Use for large repositories to avoid loading everything into memory.
|
|
4379
|
-
*/
|
|
4380
|
-
async importRepositoryStream(header, chunks, options) {
|
|
4381
|
-
await this.ensureInitialized();
|
|
4382
|
-
const importer = new RepositoryImporter({
|
|
4383
|
-
storage: this.storage,
|
|
4384
|
-
actorId: this.provenance.getContext().actorId,
|
|
4385
|
-
onProgress: (progress) => this.globalEventBus.emit("import:progress", progress)
|
|
4386
|
-
});
|
|
4387
|
-
await this.globalEventBus.emit("import:started", { repositoryId: options.target.repositoryId });
|
|
4388
|
-
const result = await importer.importStream(header, chunks, options);
|
|
4389
|
-
if (result.success) {
|
|
4390
|
-
await this.globalEventBus.emit("import:completed", {
|
|
4391
|
-
repositoryId: result.repositoryId,
|
|
4392
|
-
entitiesImported: result.statistics.entitiesImported,
|
|
4393
|
-
relationshipsImported: result.statistics.relationshipsImported
|
|
4394
|
-
});
|
|
4395
|
-
} else {
|
|
4396
|
-
await this.globalEventBus.emit("import:failed", {
|
|
4397
|
-
repositoryId: result.repositoryId,
|
|
4398
|
-
error: result.warnings.map((w) => w.message).join("; ")
|
|
4399
|
-
});
|
|
4073
|
+
/**
|
|
4074
|
+
* Import a repository from a stream of chunks.
|
|
4075
|
+
* Use for large repositories to avoid loading everything into memory.
|
|
4076
|
+
*/
|
|
4077
|
+
async importRepositoryStream(header, chunks, options) {
|
|
4078
|
+
await this.ensureInitialized();
|
|
4079
|
+
const importer = new RepositoryImporter({
|
|
4080
|
+
storage: this.storage,
|
|
4081
|
+
actorId: this.provenance.getContext().actorId,
|
|
4082
|
+
onProgress: (progress) => this.globalEventBus.emit("import:progress", progress)
|
|
4083
|
+
});
|
|
4084
|
+
await this.globalEventBus.emit("import:started", { repositoryId: options.target.repositoryId });
|
|
4085
|
+
const result = await importer.importStream(header, chunks, options);
|
|
4086
|
+
if (result.success) {
|
|
4087
|
+
await this.globalEventBus.emit("import:completed", {
|
|
4088
|
+
repositoryId: result.repositoryId,
|
|
4089
|
+
entitiesImported: result.statistics.entitiesImported,
|
|
4090
|
+
relationshipsImported: result.statistics.relationshipsImported
|
|
4091
|
+
});
|
|
4092
|
+
} else {
|
|
4093
|
+
await this.globalEventBus.emit("import:failed", {
|
|
4094
|
+
repositoryId: result.repositoryId,
|
|
4095
|
+
error: result.warnings.map((w) => w.message).join("; ")
|
|
4096
|
+
});
|
|
4097
|
+
}
|
|
4098
|
+
return result;
|
|
4099
|
+
}
|
|
4100
|
+
/** Subscribe to global events */
|
|
4101
|
+
on(event, handler) {
|
|
4102
|
+
return this.globalEventBus.on(event, handler);
|
|
4103
|
+
}
|
|
4104
|
+
/** Update the provenance context (e.g., new conversation) */
|
|
4105
|
+
updateProvenance(context) {
|
|
4106
|
+
this.provenance.updateContext(context);
|
|
4107
|
+
this.globalEventBus.updateProvenance(this.provenance.getContext());
|
|
4108
|
+
}
|
|
4109
|
+
/** Dispose of all resources */
|
|
4110
|
+
async dispose() {
|
|
4111
|
+
this.globalEventBus.removeAllListeners();
|
|
4112
|
+
if (this.graphTraversalProvider?.dispose) {
|
|
4113
|
+
await this.graphTraversalProvider.dispose();
|
|
4114
|
+
}
|
|
4115
|
+
if (this.storage.dispose) {
|
|
4116
|
+
await this.storage.dispose();
|
|
4117
|
+
}
|
|
4118
|
+
this.initialized = false;
|
|
4119
|
+
}
|
|
4120
|
+
};
|
|
4121
|
+
|
|
4122
|
+
// src/relationships/compilers/GremlinCompiler.ts
|
|
4123
|
+
var DEFAULT_ESTIMATED_FANOUT_PER_HOP = 10;
|
|
4124
|
+
var GremlinCompiler = class {
|
|
4125
|
+
language = "gremlin";
|
|
4126
|
+
compile(spec, _vocabulary) {
|
|
4127
|
+
const parts = [];
|
|
4128
|
+
const params = {};
|
|
4129
|
+
let paramIndex = 0;
|
|
4130
|
+
let estimatedFanOut = 1;
|
|
4131
|
+
const nextParam = (value) => {
|
|
4132
|
+
const name = `p${paramIndex++}`;
|
|
4133
|
+
params[name] = value;
|
|
4134
|
+
return name;
|
|
4135
|
+
};
|
|
4136
|
+
parts.push("g.V()");
|
|
4137
|
+
if (spec.start.entityId) {
|
|
4138
|
+
const p = nextParam(spec.start.entityId);
|
|
4139
|
+
parts.push(`.has('id', ${p})`);
|
|
4140
|
+
} else if (spec.start.entityType) {
|
|
4141
|
+
const p = nextParam(spec.start.entityType);
|
|
4142
|
+
parts.push(`.has('entityType', ${p})`);
|
|
4143
|
+
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
4144
|
+
}
|
|
4145
|
+
if (spec.start.filter) {
|
|
4146
|
+
for (const f of spec.start.filter) {
|
|
4147
|
+
parts.push(compilePropertyFilter(f, nextParam));
|
|
4148
|
+
}
|
|
4149
|
+
}
|
|
4150
|
+
const steps = spec.steps ?? [];
|
|
4151
|
+
for (const step of steps) {
|
|
4152
|
+
if (step.repeat) {
|
|
4153
|
+
parts.push(compileRepeatStep(step, nextParam));
|
|
4154
|
+
estimatedFanOut *= step.repeat.maxDepth * DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
4155
|
+
} else if (step.relationshipFilter && step.relationshipFilter.length > 0) {
|
|
4156
|
+
parts.push(compileEdgeStep(step, nextParam));
|
|
4157
|
+
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
4158
|
+
} else {
|
|
4159
|
+
parts.push(compileSimpleStep(step, nextParam));
|
|
4160
|
+
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
4161
|
+
}
|
|
4162
|
+
if (step.entityTypes && step.entityTypes.length > 0) {
|
|
4163
|
+
const typeParams = step.entityTypes.map((t) => nextParam(t));
|
|
4164
|
+
parts.push(`.has('entityType', within(${typeParams.join(", ")}))`);
|
|
4165
|
+
}
|
|
4166
|
+
if (step.entityFilter) {
|
|
4167
|
+
for (const f of step.entityFilter) {
|
|
4168
|
+
parts.push(compilePropertyFilter(f, nextParam));
|
|
4169
|
+
}
|
|
4170
|
+
}
|
|
4171
|
+
}
|
|
4172
|
+
if (spec.returnMode === "all") {
|
|
4173
|
+
}
|
|
4174
|
+
if (spec.dedup !== false) {
|
|
4175
|
+
parts.push(".dedup()");
|
|
4176
|
+
}
|
|
4177
|
+
const limit = spec.limit ?? 50;
|
|
4178
|
+
const offset = spec.offset ?? 0;
|
|
4179
|
+
const pOffset = nextParam(offset);
|
|
4180
|
+
const pEnd = nextParam(offset + limit);
|
|
4181
|
+
parts.push(`.range(${pOffset}, ${pEnd})`);
|
|
4182
|
+
params["_limit"] = limit;
|
|
4183
|
+
params["_offset"] = offset;
|
|
4184
|
+
if (spec.returnMode === "path") {
|
|
4185
|
+
parts.push(".path()");
|
|
4186
|
+
}
|
|
4187
|
+
if (spec.returnMode !== "path") {
|
|
4188
|
+
parts.push(".valueMap(true)");
|
|
4189
|
+
}
|
|
4190
|
+
return {
|
|
4191
|
+
query: parts.join(""),
|
|
4192
|
+
params,
|
|
4193
|
+
estimatedFanOut: Math.min(estimatedFanOut, 1e4)
|
|
4194
|
+
};
|
|
4195
|
+
}
|
|
4196
|
+
};
|
|
4197
|
+
function compileSimpleStep(step, nextParam) {
|
|
4198
|
+
const types = step.relationshipTypes;
|
|
4199
|
+
const typeArgs = types ? types.map((t) => nextParam(t)).join(", ") : "";
|
|
4200
|
+
switch (step.direction) {
|
|
4201
|
+
case "out":
|
|
4202
|
+
return types ? `.out(${typeArgs})` : ".out()";
|
|
4203
|
+
case "in":
|
|
4204
|
+
return types ? `.in(${typeArgs})` : ".in()";
|
|
4205
|
+
case "both":
|
|
4206
|
+
return types ? `.both(${typeArgs})` : ".both()";
|
|
4207
|
+
}
|
|
4208
|
+
}
|
|
4209
|
+
function compileEdgeStep(step, nextParam) {
|
|
4210
|
+
const parts = [];
|
|
4211
|
+
const types = step.relationshipTypes;
|
|
4212
|
+
const typeArgs = types ? types.map((t) => nextParam(t)).join(", ") : "";
|
|
4213
|
+
switch (step.direction) {
|
|
4214
|
+
case "out":
|
|
4215
|
+
parts.push(types ? `.outE(${typeArgs})` : ".outE()");
|
|
4216
|
+
break;
|
|
4217
|
+
case "in":
|
|
4218
|
+
parts.push(types ? `.inE(${typeArgs})` : ".inE()");
|
|
4219
|
+
break;
|
|
4220
|
+
case "both":
|
|
4221
|
+
parts.push(types ? `.bothE(${typeArgs})` : ".bothE()");
|
|
4222
|
+
break;
|
|
4223
|
+
}
|
|
4224
|
+
if (step.relationshipFilter) {
|
|
4225
|
+
for (const f of step.relationshipFilter) {
|
|
4226
|
+
parts.push(compilePropertyFilter(f, nextParam));
|
|
4400
4227
|
}
|
|
4401
|
-
return result;
|
|
4402
4228
|
}
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4229
|
+
switch (step.direction) {
|
|
4230
|
+
case "out":
|
|
4231
|
+
parts.push(".inV()");
|
|
4232
|
+
break;
|
|
4233
|
+
case "in":
|
|
4234
|
+
parts.push(".outV()");
|
|
4235
|
+
break;
|
|
4236
|
+
case "both":
|
|
4237
|
+
parts.push(".otherV()");
|
|
4238
|
+
break;
|
|
4406
4239
|
}
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4240
|
+
return parts.join("");
|
|
4241
|
+
}
|
|
4242
|
+
function compileRepeatStep(step, nextParam) {
|
|
4243
|
+
const parts = [];
|
|
4244
|
+
const innerStep = step.relationshipFilter?.length ? compileEdgeStep({ ...step, repeat: void 0 }, nextParam) : compileSimpleStep(step, nextParam);
|
|
4245
|
+
if (step.repeat?.emitIntermediates !== false) {
|
|
4246
|
+
parts.push(".emit()");
|
|
4411
4247
|
}
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4248
|
+
parts.push(`.repeat(${innerStep.startsWith(".") ? `__${innerStep}` : innerStep})`);
|
|
4249
|
+
if (step.repeat?.until && step.repeat.until.length > 0) {
|
|
4250
|
+
const untilParts = step.repeat.until.map((f) => compilePropertyFilter(f, nextParam));
|
|
4251
|
+
parts.push(`.until(${untilParts.join("")})`);
|
|
4252
|
+
}
|
|
4253
|
+
if (step.repeat?.maxDepth) {
|
|
4254
|
+
const p = nextParam(step.repeat.maxDepth);
|
|
4255
|
+
parts.push(`.times(${p})`);
|
|
4256
|
+
}
|
|
4257
|
+
if (step.repeat?.emitIntermediates === false) {
|
|
4258
|
+
parts.push(".emit()");
|
|
4259
|
+
}
|
|
4260
|
+
return parts.join("");
|
|
4261
|
+
}
|
|
4262
|
+
function compilePropertyFilter(filter, nextParam) {
|
|
4263
|
+
const key = nextParam(filter.key);
|
|
4264
|
+
switch (filter.operator) {
|
|
4265
|
+
case "eq": {
|
|
4266
|
+
const val = nextParam(filter.value);
|
|
4267
|
+
return `.has(${key}, ${val})`;
|
|
4417
4268
|
}
|
|
4418
|
-
|
|
4419
|
-
|
|
4269
|
+
case "neq": {
|
|
4270
|
+
const val = nextParam(filter.value);
|
|
4271
|
+
return `.has(${key}, neq(${val}))`;
|
|
4420
4272
|
}
|
|
4421
|
-
|
|
4273
|
+
case "gt": {
|
|
4274
|
+
const val = nextParam(filter.value);
|
|
4275
|
+
return `.has(${key}, gt(${val}))`;
|
|
4276
|
+
}
|
|
4277
|
+
case "gte": {
|
|
4278
|
+
const val = nextParam(filter.value);
|
|
4279
|
+
return `.has(${key}, gte(${val}))`;
|
|
4280
|
+
}
|
|
4281
|
+
case "lt": {
|
|
4282
|
+
const val = nextParam(filter.value);
|
|
4283
|
+
return `.has(${key}, lt(${val}))`;
|
|
4284
|
+
}
|
|
4285
|
+
case "lte": {
|
|
4286
|
+
const val = nextParam(filter.value);
|
|
4287
|
+
return `.has(${key}, lte(${val}))`;
|
|
4288
|
+
}
|
|
4289
|
+
case "contains": {
|
|
4290
|
+
const val = nextParam(filter.value);
|
|
4291
|
+
return `.has(${key}, containing(${val}))`;
|
|
4292
|
+
}
|
|
4293
|
+
case "isNull":
|
|
4294
|
+
return `.hasNot(${key})`;
|
|
4295
|
+
case "isNotNull":
|
|
4296
|
+
return `.has(${key})`;
|
|
4297
|
+
}
|
|
4298
|
+
}
|
|
4299
|
+
|
|
4300
|
+
// src/relationships/compilers/CypherCompiler.ts
|
|
4301
|
+
var DEFAULT_ESTIMATED_FANOUT_PER_HOP2 = 10;
|
|
4302
|
+
var CypherCompiler = class {
|
|
4303
|
+
language = "cypher";
|
|
4304
|
+
compile(spec, _vocabulary) {
|
|
4305
|
+
const params = {};
|
|
4306
|
+
let paramIndex = 0;
|
|
4307
|
+
let estimatedFanOut = 1;
|
|
4308
|
+
const whereClauses = [];
|
|
4309
|
+
let nodeIndex = 0;
|
|
4310
|
+
const nextParam = (value) => {
|
|
4311
|
+
const name = `p${paramIndex++}`;
|
|
4312
|
+
params[name] = value;
|
|
4313
|
+
return `$${name}`;
|
|
4314
|
+
};
|
|
4315
|
+
const startNode = `n${nodeIndex++}`;
|
|
4316
|
+
let matchParts = [];
|
|
4317
|
+
if (spec.start.entityId) {
|
|
4318
|
+
matchParts.push(`(${startNode})`);
|
|
4319
|
+
whereClauses.push(`${startNode}.id = ${nextParam(spec.start.entityId)}`);
|
|
4320
|
+
} else if (spec.start.entityType) {
|
|
4321
|
+
matchParts.push(`(${startNode})`);
|
|
4322
|
+
whereClauses.push(`${startNode}.entityType = ${nextParam(spec.start.entityType)}`);
|
|
4323
|
+
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP2;
|
|
4324
|
+
} else {
|
|
4325
|
+
matchParts.push(`(${startNode})`);
|
|
4326
|
+
}
|
|
4327
|
+
if (spec.start.filter) {
|
|
4328
|
+
for (const f of spec.start.filter) {
|
|
4329
|
+
whereClauses.push(compilePropertyFilterCypher(startNode, f, nextParam));
|
|
4330
|
+
}
|
|
4331
|
+
}
|
|
4332
|
+
let lastNode = startNode;
|
|
4333
|
+
const steps = spec.steps ?? [];
|
|
4334
|
+
for (let i = 0; i < steps.length; i++) {
|
|
4335
|
+
const step = steps[i];
|
|
4336
|
+
const targetNode = `n${nodeIndex++}`;
|
|
4337
|
+
const relAlias = `r${i}`;
|
|
4338
|
+
const relTypes = step.relationshipTypes?.length ? step.relationshipTypes.join("|") : "";
|
|
4339
|
+
const relTypePattern = relTypes ? `:${relTypes}` : "";
|
|
4340
|
+
const depthPattern = step.repeat ? `*1..${step.repeat.maxDepth}` : "";
|
|
4341
|
+
let pattern;
|
|
4342
|
+
switch (step.direction) {
|
|
4343
|
+
case "out":
|
|
4344
|
+
pattern = `-[${relAlias}${relTypePattern}${depthPattern}]->(${targetNode})`;
|
|
4345
|
+
break;
|
|
4346
|
+
case "in":
|
|
4347
|
+
pattern = `<-[${relAlias}${relTypePattern}${depthPattern}]-(${targetNode})`;
|
|
4348
|
+
break;
|
|
4349
|
+
case "both":
|
|
4350
|
+
pattern = `-[${relAlias}${relTypePattern}${depthPattern}]-(${targetNode})`;
|
|
4351
|
+
break;
|
|
4352
|
+
}
|
|
4353
|
+
matchParts.push(pattern);
|
|
4354
|
+
estimatedFanOut *= step.repeat ? step.repeat.maxDepth * DEFAULT_ESTIMATED_FANOUT_PER_HOP2 : DEFAULT_ESTIMATED_FANOUT_PER_HOP2;
|
|
4355
|
+
if (step.entityTypes && step.entityTypes.length > 0) {
|
|
4356
|
+
const typeParam = nextParam(step.entityTypes);
|
|
4357
|
+
whereClauses.push(`${targetNode}.entityType IN ${typeParam}`);
|
|
4358
|
+
}
|
|
4359
|
+
if (step.entityFilter) {
|
|
4360
|
+
for (const f of step.entityFilter) {
|
|
4361
|
+
whereClauses.push(compilePropertyFilterCypher(targetNode, f, nextParam));
|
|
4362
|
+
}
|
|
4363
|
+
}
|
|
4364
|
+
if (step.relationshipFilter) {
|
|
4365
|
+
for (const f of step.relationshipFilter) {
|
|
4366
|
+
whereClauses.push(compilePropertyFilterCypher(relAlias, f, nextParam));
|
|
4367
|
+
}
|
|
4368
|
+
}
|
|
4369
|
+
lastNode = targetNode;
|
|
4370
|
+
}
|
|
4371
|
+
const matchClause = `MATCH ${matchParts[0]}${matchParts.slice(1).join("")}`;
|
|
4372
|
+
const whereClause = whereClauses.length > 0 ? `
|
|
4373
|
+
WHERE ${whereClauses.join(" AND ")}` : "";
|
|
4374
|
+
let returnClause;
|
|
4375
|
+
if (spec.returnMode === "path") {
|
|
4376
|
+
const allNodes = Array.from({ length: nodeIndex }, (_, i) => `n${i}`);
|
|
4377
|
+
const allRels = steps.map((_, i) => `r${i}`);
|
|
4378
|
+
returnClause = `RETURN ${[...allNodes, ...allRels].join(", ")}`;
|
|
4379
|
+
} else if (spec.returnMode === "all") {
|
|
4380
|
+
const allNodes = Array.from({ length: nodeIndex }, (_, i) => `n${i}`);
|
|
4381
|
+
returnClause = spec.dedup !== false ? `RETURN DISTINCT ${allNodes.join(", ")}` : `RETURN ${allNodes.join(", ")}`;
|
|
4382
|
+
} else {
|
|
4383
|
+
returnClause = spec.dedup !== false ? `RETURN DISTINCT ${lastNode}` : `RETURN ${lastNode}`;
|
|
4384
|
+
}
|
|
4385
|
+
const offset = spec.offset ?? 0;
|
|
4386
|
+
const limit = spec.limit ?? 50;
|
|
4387
|
+
const skipClause = offset > 0 ? `
|
|
4388
|
+
SKIP ${nextParam(offset)}` : "";
|
|
4389
|
+
const limitClause = `
|
|
4390
|
+
LIMIT ${nextParam(limit)}`;
|
|
4391
|
+
params["_limit"] = limit;
|
|
4392
|
+
params["_offset"] = offset;
|
|
4393
|
+
const query = `${matchClause}${whereClause}
|
|
4394
|
+
${returnClause}${skipClause}${limitClause}`;
|
|
4395
|
+
return {
|
|
4396
|
+
query,
|
|
4397
|
+
params,
|
|
4398
|
+
estimatedFanOut: Math.min(estimatedFanOut, 1e4)
|
|
4399
|
+
};
|
|
4422
4400
|
}
|
|
4423
4401
|
};
|
|
4402
|
+
function compilePropertyFilterCypher(nodeAlias, filter, nextParam) {
|
|
4403
|
+
const prop = `${nodeAlias}.${filter.key}`;
|
|
4404
|
+
switch (filter.operator) {
|
|
4405
|
+
case "eq":
|
|
4406
|
+
return `${prop} = ${nextParam(filter.value)}`;
|
|
4407
|
+
case "neq":
|
|
4408
|
+
return `${prop} <> ${nextParam(filter.value)}`;
|
|
4409
|
+
case "gt":
|
|
4410
|
+
return `${prop} > ${nextParam(filter.value)}`;
|
|
4411
|
+
case "gte":
|
|
4412
|
+
return `${prop} >= ${nextParam(filter.value)}`;
|
|
4413
|
+
case "lt":
|
|
4414
|
+
return `${prop} < ${nextParam(filter.value)}`;
|
|
4415
|
+
case "lte":
|
|
4416
|
+
return `${prop} <= ${nextParam(filter.value)}`;
|
|
4417
|
+
case "contains":
|
|
4418
|
+
return `${prop} CONTAINS ${nextParam(filter.value)}`;
|
|
4419
|
+
case "isNull":
|
|
4420
|
+
return `${prop} IS NULL`;
|
|
4421
|
+
case "isNotNull":
|
|
4422
|
+
return `${prop} IS NOT NULL`;
|
|
4423
|
+
}
|
|
4424
|
+
}
|
|
4424
4425
|
|
|
4425
4426
|
// src/providers-builtin/InMemoryStorageProvider.ts
|
|
4426
4427
|
var InMemoryStorageProvider = class {
|
|
@@ -5155,6 +5156,7 @@ var NoOpEmbeddingProvider = class {
|
|
|
5155
5156
|
VocabularyValidationError,
|
|
5156
5157
|
generateId,
|
|
5157
5158
|
isValidUuid,
|
|
5158
|
-
matchesPropertyFilters
|
|
5159
|
+
matchesPropertyFilters,
|
|
5160
|
+
projectEntity
|
|
5159
5161
|
});
|
|
5160
5162
|
//# sourceMappingURL=index.cjs.map
|