@utaba/deep-memory 0.5.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.
- package/dist/index.cjs +354 -362
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +352 -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.0" : "0.1.0";
|
|
3411
3098
|
var RepositoryExporter = class {
|
|
3412
3099
|
storage;
|
|
3413
3100
|
provenance;
|
|
@@ -4373,54 +4060,358 @@ var DeepMemory = class {
|
|
|
4373
4060
|
relationshipCount
|
|
4374
4061
|
});
|
|
4375
4062
|
}
|
|
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
|
-
});
|
|
4063
|
+
/**
|
|
4064
|
+
* Import a repository from a stream of chunks.
|
|
4065
|
+
* Use for large repositories to avoid loading everything into memory.
|
|
4066
|
+
*/
|
|
4067
|
+
async importRepositoryStream(header, chunks, options) {
|
|
4068
|
+
await this.ensureInitialized();
|
|
4069
|
+
const importer = new RepositoryImporter({
|
|
4070
|
+
storage: this.storage,
|
|
4071
|
+
actorId: this.provenance.getContext().actorId,
|
|
4072
|
+
onProgress: (progress) => this.globalEventBus.emit("import:progress", progress)
|
|
4073
|
+
});
|
|
4074
|
+
await this.globalEventBus.emit("import:started", { repositoryId: options.target.repositoryId });
|
|
4075
|
+
const result = await importer.importStream(header, chunks, options);
|
|
4076
|
+
if (result.success) {
|
|
4077
|
+
await this.globalEventBus.emit("import:completed", {
|
|
4078
|
+
repositoryId: result.repositoryId,
|
|
4079
|
+
entitiesImported: result.statistics.entitiesImported,
|
|
4080
|
+
relationshipsImported: result.statistics.relationshipsImported
|
|
4081
|
+
});
|
|
4082
|
+
} else {
|
|
4083
|
+
await this.globalEventBus.emit("import:failed", {
|
|
4084
|
+
repositoryId: result.repositoryId,
|
|
4085
|
+
error: result.warnings.map((w) => w.message).join("; ")
|
|
4086
|
+
});
|
|
4087
|
+
}
|
|
4088
|
+
return result;
|
|
4089
|
+
}
|
|
4090
|
+
/** Subscribe to global events */
|
|
4091
|
+
on(event, handler) {
|
|
4092
|
+
return this.globalEventBus.on(event, handler);
|
|
4093
|
+
}
|
|
4094
|
+
/** Update the provenance context (e.g., new conversation) */
|
|
4095
|
+
updateProvenance(context) {
|
|
4096
|
+
this.provenance.updateContext(context);
|
|
4097
|
+
this.globalEventBus.updateProvenance(this.provenance.getContext());
|
|
4098
|
+
}
|
|
4099
|
+
/** Dispose of all resources */
|
|
4100
|
+
async dispose() {
|
|
4101
|
+
this.globalEventBus.removeAllListeners();
|
|
4102
|
+
if (this.graphTraversalProvider?.dispose) {
|
|
4103
|
+
await this.graphTraversalProvider.dispose();
|
|
4104
|
+
}
|
|
4105
|
+
if (this.storage.dispose) {
|
|
4106
|
+
await this.storage.dispose();
|
|
4107
|
+
}
|
|
4108
|
+
this.initialized = false;
|
|
4109
|
+
}
|
|
4110
|
+
};
|
|
4111
|
+
|
|
4112
|
+
// src/relationships/compilers/GremlinCompiler.ts
|
|
4113
|
+
var DEFAULT_ESTIMATED_FANOUT_PER_HOP = 10;
|
|
4114
|
+
var GremlinCompiler = class {
|
|
4115
|
+
language = "gremlin";
|
|
4116
|
+
compile(spec, _vocabulary) {
|
|
4117
|
+
const parts = [];
|
|
4118
|
+
const params = {};
|
|
4119
|
+
let paramIndex = 0;
|
|
4120
|
+
let estimatedFanOut = 1;
|
|
4121
|
+
const nextParam = (value) => {
|
|
4122
|
+
const name = `p${paramIndex++}`;
|
|
4123
|
+
params[name] = value;
|
|
4124
|
+
return name;
|
|
4125
|
+
};
|
|
4126
|
+
parts.push("g.V()");
|
|
4127
|
+
if (spec.start.entityId) {
|
|
4128
|
+
const p = nextParam(spec.start.entityId);
|
|
4129
|
+
parts.push(`.has('id', ${p})`);
|
|
4130
|
+
} else if (spec.start.entityType) {
|
|
4131
|
+
const p = nextParam(spec.start.entityType);
|
|
4132
|
+
parts.push(`.has('entityType', ${p})`);
|
|
4133
|
+
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
4134
|
+
}
|
|
4135
|
+
if (spec.start.filter) {
|
|
4136
|
+
for (const f of spec.start.filter) {
|
|
4137
|
+
parts.push(compilePropertyFilter(f, nextParam));
|
|
4138
|
+
}
|
|
4139
|
+
}
|
|
4140
|
+
const steps = spec.steps ?? [];
|
|
4141
|
+
for (const step of steps) {
|
|
4142
|
+
if (step.repeat) {
|
|
4143
|
+
parts.push(compileRepeatStep(step, nextParam));
|
|
4144
|
+
estimatedFanOut *= step.repeat.maxDepth * DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
4145
|
+
} else if (step.relationshipFilter && step.relationshipFilter.length > 0) {
|
|
4146
|
+
parts.push(compileEdgeStep(step, nextParam));
|
|
4147
|
+
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
4148
|
+
} else {
|
|
4149
|
+
parts.push(compileSimpleStep(step, nextParam));
|
|
4150
|
+
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
4151
|
+
}
|
|
4152
|
+
if (step.entityTypes && step.entityTypes.length > 0) {
|
|
4153
|
+
const typeParams = step.entityTypes.map((t) => nextParam(t));
|
|
4154
|
+
parts.push(`.has('entityType', within(${typeParams.join(", ")}))`);
|
|
4155
|
+
}
|
|
4156
|
+
if (step.entityFilter) {
|
|
4157
|
+
for (const f of step.entityFilter) {
|
|
4158
|
+
parts.push(compilePropertyFilter(f, nextParam));
|
|
4159
|
+
}
|
|
4160
|
+
}
|
|
4161
|
+
}
|
|
4162
|
+
if (spec.returnMode === "all") {
|
|
4163
|
+
}
|
|
4164
|
+
if (spec.dedup !== false) {
|
|
4165
|
+
parts.push(".dedup()");
|
|
4166
|
+
}
|
|
4167
|
+
const limit = spec.limit ?? 50;
|
|
4168
|
+
const offset = spec.offset ?? 0;
|
|
4169
|
+
const pOffset = nextParam(offset);
|
|
4170
|
+
const pEnd = nextParam(offset + limit);
|
|
4171
|
+
parts.push(`.range(${pOffset}, ${pEnd})`);
|
|
4172
|
+
params["_limit"] = limit;
|
|
4173
|
+
params["_offset"] = offset;
|
|
4174
|
+
if (spec.returnMode === "path") {
|
|
4175
|
+
parts.push(".path()");
|
|
4176
|
+
}
|
|
4177
|
+
if (spec.returnMode !== "path") {
|
|
4178
|
+
parts.push(".valueMap(true)");
|
|
4179
|
+
}
|
|
4180
|
+
return {
|
|
4181
|
+
query: parts.join(""),
|
|
4182
|
+
params,
|
|
4183
|
+
estimatedFanOut: Math.min(estimatedFanOut, 1e4)
|
|
4184
|
+
};
|
|
4185
|
+
}
|
|
4186
|
+
};
|
|
4187
|
+
function compileSimpleStep(step, nextParam) {
|
|
4188
|
+
const types = step.relationshipTypes;
|
|
4189
|
+
const typeArgs = types ? types.map((t) => nextParam(t)).join(", ") : "";
|
|
4190
|
+
switch (step.direction) {
|
|
4191
|
+
case "out":
|
|
4192
|
+
return types ? `.out(${typeArgs})` : ".out()";
|
|
4193
|
+
case "in":
|
|
4194
|
+
return types ? `.in(${typeArgs})` : ".in()";
|
|
4195
|
+
case "both":
|
|
4196
|
+
return types ? `.both(${typeArgs})` : ".both()";
|
|
4197
|
+
}
|
|
4198
|
+
}
|
|
4199
|
+
function compileEdgeStep(step, nextParam) {
|
|
4200
|
+
const parts = [];
|
|
4201
|
+
const types = step.relationshipTypes;
|
|
4202
|
+
const typeArgs = types ? types.map((t) => nextParam(t)).join(", ") : "";
|
|
4203
|
+
switch (step.direction) {
|
|
4204
|
+
case "out":
|
|
4205
|
+
parts.push(types ? `.outE(${typeArgs})` : ".outE()");
|
|
4206
|
+
break;
|
|
4207
|
+
case "in":
|
|
4208
|
+
parts.push(types ? `.inE(${typeArgs})` : ".inE()");
|
|
4209
|
+
break;
|
|
4210
|
+
case "both":
|
|
4211
|
+
parts.push(types ? `.bothE(${typeArgs})` : ".bothE()");
|
|
4212
|
+
break;
|
|
4213
|
+
}
|
|
4214
|
+
if (step.relationshipFilter) {
|
|
4215
|
+
for (const f of step.relationshipFilter) {
|
|
4216
|
+
parts.push(compilePropertyFilter(f, nextParam));
|
|
4400
4217
|
}
|
|
4401
|
-
return result;
|
|
4402
4218
|
}
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4219
|
+
switch (step.direction) {
|
|
4220
|
+
case "out":
|
|
4221
|
+
parts.push(".inV()");
|
|
4222
|
+
break;
|
|
4223
|
+
case "in":
|
|
4224
|
+
parts.push(".outV()");
|
|
4225
|
+
break;
|
|
4226
|
+
case "both":
|
|
4227
|
+
parts.push(".otherV()");
|
|
4228
|
+
break;
|
|
4406
4229
|
}
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4230
|
+
return parts.join("");
|
|
4231
|
+
}
|
|
4232
|
+
function compileRepeatStep(step, nextParam) {
|
|
4233
|
+
const parts = [];
|
|
4234
|
+
const innerStep = step.relationshipFilter?.length ? compileEdgeStep({ ...step, repeat: void 0 }, nextParam) : compileSimpleStep(step, nextParam);
|
|
4235
|
+
if (step.repeat?.emitIntermediates !== false) {
|
|
4236
|
+
parts.push(".emit()");
|
|
4411
4237
|
}
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4238
|
+
parts.push(`.repeat(${innerStep.startsWith(".") ? `__${innerStep}` : innerStep})`);
|
|
4239
|
+
if (step.repeat?.until && step.repeat.until.length > 0) {
|
|
4240
|
+
const untilParts = step.repeat.until.map((f) => compilePropertyFilter(f, nextParam));
|
|
4241
|
+
parts.push(`.until(${untilParts.join("")})`);
|
|
4242
|
+
}
|
|
4243
|
+
if (step.repeat?.maxDepth) {
|
|
4244
|
+
const p = nextParam(step.repeat.maxDepth);
|
|
4245
|
+
parts.push(`.times(${p})`);
|
|
4246
|
+
}
|
|
4247
|
+
if (step.repeat?.emitIntermediates === false) {
|
|
4248
|
+
parts.push(".emit()");
|
|
4249
|
+
}
|
|
4250
|
+
return parts.join("");
|
|
4251
|
+
}
|
|
4252
|
+
function compilePropertyFilter(filter, nextParam) {
|
|
4253
|
+
const key = nextParam(filter.key);
|
|
4254
|
+
switch (filter.operator) {
|
|
4255
|
+
case "eq": {
|
|
4256
|
+
const val = nextParam(filter.value);
|
|
4257
|
+
return `.has(${key}, ${val})`;
|
|
4417
4258
|
}
|
|
4418
|
-
|
|
4419
|
-
|
|
4259
|
+
case "neq": {
|
|
4260
|
+
const val = nextParam(filter.value);
|
|
4261
|
+
return `.has(${key}, neq(${val}))`;
|
|
4420
4262
|
}
|
|
4421
|
-
|
|
4263
|
+
case "gt": {
|
|
4264
|
+
const val = nextParam(filter.value);
|
|
4265
|
+
return `.has(${key}, gt(${val}))`;
|
|
4266
|
+
}
|
|
4267
|
+
case "gte": {
|
|
4268
|
+
const val = nextParam(filter.value);
|
|
4269
|
+
return `.has(${key}, gte(${val}))`;
|
|
4270
|
+
}
|
|
4271
|
+
case "lt": {
|
|
4272
|
+
const val = nextParam(filter.value);
|
|
4273
|
+
return `.has(${key}, lt(${val}))`;
|
|
4274
|
+
}
|
|
4275
|
+
case "lte": {
|
|
4276
|
+
const val = nextParam(filter.value);
|
|
4277
|
+
return `.has(${key}, lte(${val}))`;
|
|
4278
|
+
}
|
|
4279
|
+
case "contains": {
|
|
4280
|
+
const val = nextParam(filter.value);
|
|
4281
|
+
return `.has(${key}, containing(${val}))`;
|
|
4282
|
+
}
|
|
4283
|
+
case "isNull":
|
|
4284
|
+
return `.hasNot(${key})`;
|
|
4285
|
+
case "isNotNull":
|
|
4286
|
+
return `.has(${key})`;
|
|
4287
|
+
}
|
|
4288
|
+
}
|
|
4289
|
+
|
|
4290
|
+
// src/relationships/compilers/CypherCompiler.ts
|
|
4291
|
+
var DEFAULT_ESTIMATED_FANOUT_PER_HOP2 = 10;
|
|
4292
|
+
var CypherCompiler = class {
|
|
4293
|
+
language = "cypher";
|
|
4294
|
+
compile(spec, _vocabulary) {
|
|
4295
|
+
const params = {};
|
|
4296
|
+
let paramIndex = 0;
|
|
4297
|
+
let estimatedFanOut = 1;
|
|
4298
|
+
const whereClauses = [];
|
|
4299
|
+
let nodeIndex = 0;
|
|
4300
|
+
const nextParam = (value) => {
|
|
4301
|
+
const name = `p${paramIndex++}`;
|
|
4302
|
+
params[name] = value;
|
|
4303
|
+
return `$${name}`;
|
|
4304
|
+
};
|
|
4305
|
+
const startNode = `n${nodeIndex++}`;
|
|
4306
|
+
let matchParts = [];
|
|
4307
|
+
if (spec.start.entityId) {
|
|
4308
|
+
matchParts.push(`(${startNode})`);
|
|
4309
|
+
whereClauses.push(`${startNode}.id = ${nextParam(spec.start.entityId)}`);
|
|
4310
|
+
} else if (spec.start.entityType) {
|
|
4311
|
+
matchParts.push(`(${startNode})`);
|
|
4312
|
+
whereClauses.push(`${startNode}.entityType = ${nextParam(spec.start.entityType)}`);
|
|
4313
|
+
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP2;
|
|
4314
|
+
} else {
|
|
4315
|
+
matchParts.push(`(${startNode})`);
|
|
4316
|
+
}
|
|
4317
|
+
if (spec.start.filter) {
|
|
4318
|
+
for (const f of spec.start.filter) {
|
|
4319
|
+
whereClauses.push(compilePropertyFilterCypher(startNode, f, nextParam));
|
|
4320
|
+
}
|
|
4321
|
+
}
|
|
4322
|
+
let lastNode = startNode;
|
|
4323
|
+
const steps = spec.steps ?? [];
|
|
4324
|
+
for (let i = 0; i < steps.length; i++) {
|
|
4325
|
+
const step = steps[i];
|
|
4326
|
+
const targetNode = `n${nodeIndex++}`;
|
|
4327
|
+
const relAlias = `r${i}`;
|
|
4328
|
+
const relTypes = step.relationshipTypes?.length ? step.relationshipTypes.join("|") : "";
|
|
4329
|
+
const relTypePattern = relTypes ? `:${relTypes}` : "";
|
|
4330
|
+
const depthPattern = step.repeat ? `*1..${step.repeat.maxDepth}` : "";
|
|
4331
|
+
let pattern;
|
|
4332
|
+
switch (step.direction) {
|
|
4333
|
+
case "out":
|
|
4334
|
+
pattern = `-[${relAlias}${relTypePattern}${depthPattern}]->(${targetNode})`;
|
|
4335
|
+
break;
|
|
4336
|
+
case "in":
|
|
4337
|
+
pattern = `<-[${relAlias}${relTypePattern}${depthPattern}]-(${targetNode})`;
|
|
4338
|
+
break;
|
|
4339
|
+
case "both":
|
|
4340
|
+
pattern = `-[${relAlias}${relTypePattern}${depthPattern}]-(${targetNode})`;
|
|
4341
|
+
break;
|
|
4342
|
+
}
|
|
4343
|
+
matchParts.push(pattern);
|
|
4344
|
+
estimatedFanOut *= step.repeat ? step.repeat.maxDepth * DEFAULT_ESTIMATED_FANOUT_PER_HOP2 : DEFAULT_ESTIMATED_FANOUT_PER_HOP2;
|
|
4345
|
+
if (step.entityTypes && step.entityTypes.length > 0) {
|
|
4346
|
+
const typeParam = nextParam(step.entityTypes);
|
|
4347
|
+
whereClauses.push(`${targetNode}.entityType IN ${typeParam}`);
|
|
4348
|
+
}
|
|
4349
|
+
if (step.entityFilter) {
|
|
4350
|
+
for (const f of step.entityFilter) {
|
|
4351
|
+
whereClauses.push(compilePropertyFilterCypher(targetNode, f, nextParam));
|
|
4352
|
+
}
|
|
4353
|
+
}
|
|
4354
|
+
if (step.relationshipFilter) {
|
|
4355
|
+
for (const f of step.relationshipFilter) {
|
|
4356
|
+
whereClauses.push(compilePropertyFilterCypher(relAlias, f, nextParam));
|
|
4357
|
+
}
|
|
4358
|
+
}
|
|
4359
|
+
lastNode = targetNode;
|
|
4360
|
+
}
|
|
4361
|
+
const matchClause = `MATCH ${matchParts[0]}${matchParts.slice(1).join("")}`;
|
|
4362
|
+
const whereClause = whereClauses.length > 0 ? `
|
|
4363
|
+
WHERE ${whereClauses.join(" AND ")}` : "";
|
|
4364
|
+
let returnClause;
|
|
4365
|
+
if (spec.returnMode === "path") {
|
|
4366
|
+
const allNodes = Array.from({ length: nodeIndex }, (_, i) => `n${i}`);
|
|
4367
|
+
const allRels = steps.map((_, i) => `r${i}`);
|
|
4368
|
+
returnClause = `RETURN ${[...allNodes, ...allRels].join(", ")}`;
|
|
4369
|
+
} else if (spec.returnMode === "all") {
|
|
4370
|
+
const allNodes = Array.from({ length: nodeIndex }, (_, i) => `n${i}`);
|
|
4371
|
+
returnClause = spec.dedup !== false ? `RETURN DISTINCT ${allNodes.join(", ")}` : `RETURN ${allNodes.join(", ")}`;
|
|
4372
|
+
} else {
|
|
4373
|
+
returnClause = spec.dedup !== false ? `RETURN DISTINCT ${lastNode}` : `RETURN ${lastNode}`;
|
|
4374
|
+
}
|
|
4375
|
+
const offset = spec.offset ?? 0;
|
|
4376
|
+
const limit = spec.limit ?? 50;
|
|
4377
|
+
const skipClause = offset > 0 ? `
|
|
4378
|
+
SKIP ${nextParam(offset)}` : "";
|
|
4379
|
+
const limitClause = `
|
|
4380
|
+
LIMIT ${nextParam(limit)}`;
|
|
4381
|
+
params["_limit"] = limit;
|
|
4382
|
+
params["_offset"] = offset;
|
|
4383
|
+
const query = `${matchClause}${whereClause}
|
|
4384
|
+
${returnClause}${skipClause}${limitClause}`;
|
|
4385
|
+
return {
|
|
4386
|
+
query,
|
|
4387
|
+
params,
|
|
4388
|
+
estimatedFanOut: Math.min(estimatedFanOut, 1e4)
|
|
4389
|
+
};
|
|
4422
4390
|
}
|
|
4423
4391
|
};
|
|
4392
|
+
function compilePropertyFilterCypher(nodeAlias, filter, nextParam) {
|
|
4393
|
+
const prop = `${nodeAlias}.${filter.key}`;
|
|
4394
|
+
switch (filter.operator) {
|
|
4395
|
+
case "eq":
|
|
4396
|
+
return `${prop} = ${nextParam(filter.value)}`;
|
|
4397
|
+
case "neq":
|
|
4398
|
+
return `${prop} <> ${nextParam(filter.value)}`;
|
|
4399
|
+
case "gt":
|
|
4400
|
+
return `${prop} > ${nextParam(filter.value)}`;
|
|
4401
|
+
case "gte":
|
|
4402
|
+
return `${prop} >= ${nextParam(filter.value)}`;
|
|
4403
|
+
case "lt":
|
|
4404
|
+
return `${prop} < ${nextParam(filter.value)}`;
|
|
4405
|
+
case "lte":
|
|
4406
|
+
return `${prop} <= ${nextParam(filter.value)}`;
|
|
4407
|
+
case "contains":
|
|
4408
|
+
return `${prop} CONTAINS ${nextParam(filter.value)}`;
|
|
4409
|
+
case "isNull":
|
|
4410
|
+
return `${prop} IS NULL`;
|
|
4411
|
+
case "isNotNull":
|
|
4412
|
+
return `${prop} IS NOT NULL`;
|
|
4413
|
+
}
|
|
4414
|
+
}
|
|
4424
4415
|
|
|
4425
4416
|
// src/providers-builtin/InMemoryStorageProvider.ts
|
|
4426
4417
|
var InMemoryStorageProvider = class {
|
|
@@ -5155,6 +5146,7 @@ var NoOpEmbeddingProvider = class {
|
|
|
5155
5146
|
VocabularyValidationError,
|
|
5156
5147
|
generateId,
|
|
5157
5148
|
isValidUuid,
|
|
5158
|
-
matchesPropertyFilters
|
|
5149
|
+
matchesPropertyFilters,
|
|
5150
|
+
projectEntity
|
|
5159
5151
|
});
|
|
5160
5152
|
//# sourceMappingURL=index.cjs.map
|