@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.js
CHANGED
|
@@ -901,310 +901,6 @@ function validateTraversalSpec(spec, vocabulary, capabilities) {
|
|
|
901
901
|
};
|
|
902
902
|
}
|
|
903
903
|
|
|
904
|
-
// src/relationships/compilers/GremlinCompiler.ts
|
|
905
|
-
var DEFAULT_ESTIMATED_FANOUT_PER_HOP = 10;
|
|
906
|
-
var GremlinCompiler = class {
|
|
907
|
-
language = "gremlin";
|
|
908
|
-
compile(spec, _vocabulary) {
|
|
909
|
-
const parts = [];
|
|
910
|
-
const params = {};
|
|
911
|
-
let paramIndex = 0;
|
|
912
|
-
let estimatedFanOut = 1;
|
|
913
|
-
const nextParam = (value) => {
|
|
914
|
-
const name = `p${paramIndex++}`;
|
|
915
|
-
params[name] = value;
|
|
916
|
-
return name;
|
|
917
|
-
};
|
|
918
|
-
parts.push("g.V()");
|
|
919
|
-
if (spec.start.entityId) {
|
|
920
|
-
const p = nextParam(spec.start.entityId);
|
|
921
|
-
parts.push(`.has('id', ${p})`);
|
|
922
|
-
} else if (spec.start.entityType) {
|
|
923
|
-
const p = nextParam(spec.start.entityType);
|
|
924
|
-
parts.push(`.has('entityType', ${p})`);
|
|
925
|
-
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
926
|
-
}
|
|
927
|
-
if (spec.start.filter) {
|
|
928
|
-
for (const f of spec.start.filter) {
|
|
929
|
-
parts.push(compilePropertyFilter(f, nextParam));
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
const steps = spec.steps ?? [];
|
|
933
|
-
for (const step of steps) {
|
|
934
|
-
if (step.repeat) {
|
|
935
|
-
parts.push(compileRepeatStep(step, nextParam));
|
|
936
|
-
estimatedFanOut *= step.repeat.maxDepth * DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
937
|
-
} else if (step.relationshipFilter && step.relationshipFilter.length > 0) {
|
|
938
|
-
parts.push(compileEdgeStep(step, nextParam));
|
|
939
|
-
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
940
|
-
} else {
|
|
941
|
-
parts.push(compileSimpleStep(step, nextParam));
|
|
942
|
-
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
943
|
-
}
|
|
944
|
-
if (step.entityTypes && step.entityTypes.length > 0) {
|
|
945
|
-
const typeParams = step.entityTypes.map((t) => nextParam(t));
|
|
946
|
-
parts.push(`.has('entityType', within(${typeParams.join(", ")}))`);
|
|
947
|
-
}
|
|
948
|
-
if (step.entityFilter) {
|
|
949
|
-
for (const f of step.entityFilter) {
|
|
950
|
-
parts.push(compilePropertyFilter(f, nextParam));
|
|
951
|
-
}
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
if (spec.returnMode === "all") {
|
|
955
|
-
}
|
|
956
|
-
if (spec.dedup !== false) {
|
|
957
|
-
parts.push(".dedup()");
|
|
958
|
-
}
|
|
959
|
-
const limit = spec.limit ?? 50;
|
|
960
|
-
const offset = spec.offset ?? 0;
|
|
961
|
-
const pOffset = nextParam(offset);
|
|
962
|
-
const pEnd = nextParam(offset + limit);
|
|
963
|
-
parts.push(`.range(${pOffset}, ${pEnd})`);
|
|
964
|
-
params["_limit"] = limit;
|
|
965
|
-
params["_offset"] = offset;
|
|
966
|
-
if (spec.returnMode === "path") {
|
|
967
|
-
parts.push(".path()");
|
|
968
|
-
}
|
|
969
|
-
if (spec.returnMode !== "path") {
|
|
970
|
-
parts.push(".valueMap(true)");
|
|
971
|
-
}
|
|
972
|
-
return {
|
|
973
|
-
query: parts.join(""),
|
|
974
|
-
params,
|
|
975
|
-
estimatedFanOut: Math.min(estimatedFanOut, 1e4)
|
|
976
|
-
};
|
|
977
|
-
}
|
|
978
|
-
};
|
|
979
|
-
function compileSimpleStep(step, nextParam) {
|
|
980
|
-
const types = step.relationshipTypes;
|
|
981
|
-
const typeArgs = types ? types.map((t) => nextParam(t)).join(", ") : "";
|
|
982
|
-
switch (step.direction) {
|
|
983
|
-
case "out":
|
|
984
|
-
return types ? `.out(${typeArgs})` : ".out()";
|
|
985
|
-
case "in":
|
|
986
|
-
return types ? `.in(${typeArgs})` : ".in()";
|
|
987
|
-
case "both":
|
|
988
|
-
return types ? `.both(${typeArgs})` : ".both()";
|
|
989
|
-
}
|
|
990
|
-
}
|
|
991
|
-
function compileEdgeStep(step, nextParam) {
|
|
992
|
-
const parts = [];
|
|
993
|
-
const types = step.relationshipTypes;
|
|
994
|
-
const typeArgs = types ? types.map((t) => nextParam(t)).join(", ") : "";
|
|
995
|
-
switch (step.direction) {
|
|
996
|
-
case "out":
|
|
997
|
-
parts.push(types ? `.outE(${typeArgs})` : ".outE()");
|
|
998
|
-
break;
|
|
999
|
-
case "in":
|
|
1000
|
-
parts.push(types ? `.inE(${typeArgs})` : ".inE()");
|
|
1001
|
-
break;
|
|
1002
|
-
case "both":
|
|
1003
|
-
parts.push(types ? `.bothE(${typeArgs})` : ".bothE()");
|
|
1004
|
-
break;
|
|
1005
|
-
}
|
|
1006
|
-
if (step.relationshipFilter) {
|
|
1007
|
-
for (const f of step.relationshipFilter) {
|
|
1008
|
-
parts.push(compilePropertyFilter(f, nextParam));
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
switch (step.direction) {
|
|
1012
|
-
case "out":
|
|
1013
|
-
parts.push(".inV()");
|
|
1014
|
-
break;
|
|
1015
|
-
case "in":
|
|
1016
|
-
parts.push(".outV()");
|
|
1017
|
-
break;
|
|
1018
|
-
case "both":
|
|
1019
|
-
parts.push(".otherV()");
|
|
1020
|
-
break;
|
|
1021
|
-
}
|
|
1022
|
-
return parts.join("");
|
|
1023
|
-
}
|
|
1024
|
-
function compileRepeatStep(step, nextParam) {
|
|
1025
|
-
const parts = [];
|
|
1026
|
-
const innerStep = step.relationshipFilter?.length ? compileEdgeStep({ ...step, repeat: void 0 }, nextParam) : compileSimpleStep(step, nextParam);
|
|
1027
|
-
if (step.repeat?.emitIntermediates !== false) {
|
|
1028
|
-
parts.push(".emit()");
|
|
1029
|
-
}
|
|
1030
|
-
parts.push(`.repeat(${innerStep.startsWith(".") ? `__${innerStep}` : innerStep})`);
|
|
1031
|
-
if (step.repeat?.until && step.repeat.until.length > 0) {
|
|
1032
|
-
const untilParts = step.repeat.until.map((f) => compilePropertyFilter(f, nextParam));
|
|
1033
|
-
parts.push(`.until(${untilParts.join("")})`);
|
|
1034
|
-
}
|
|
1035
|
-
if (step.repeat?.maxDepth) {
|
|
1036
|
-
const p = nextParam(step.repeat.maxDepth);
|
|
1037
|
-
parts.push(`.times(${p})`);
|
|
1038
|
-
}
|
|
1039
|
-
if (step.repeat?.emitIntermediates === false) {
|
|
1040
|
-
parts.push(".emit()");
|
|
1041
|
-
}
|
|
1042
|
-
return parts.join("");
|
|
1043
|
-
}
|
|
1044
|
-
function compilePropertyFilter(filter, nextParam) {
|
|
1045
|
-
const key = nextParam(filter.key);
|
|
1046
|
-
switch (filter.operator) {
|
|
1047
|
-
case "eq": {
|
|
1048
|
-
const val = nextParam(filter.value);
|
|
1049
|
-
return `.has(${key}, ${val})`;
|
|
1050
|
-
}
|
|
1051
|
-
case "neq": {
|
|
1052
|
-
const val = nextParam(filter.value);
|
|
1053
|
-
return `.has(${key}, neq(${val}))`;
|
|
1054
|
-
}
|
|
1055
|
-
case "gt": {
|
|
1056
|
-
const val = nextParam(filter.value);
|
|
1057
|
-
return `.has(${key}, gt(${val}))`;
|
|
1058
|
-
}
|
|
1059
|
-
case "gte": {
|
|
1060
|
-
const val = nextParam(filter.value);
|
|
1061
|
-
return `.has(${key}, gte(${val}))`;
|
|
1062
|
-
}
|
|
1063
|
-
case "lt": {
|
|
1064
|
-
const val = nextParam(filter.value);
|
|
1065
|
-
return `.has(${key}, lt(${val}))`;
|
|
1066
|
-
}
|
|
1067
|
-
case "lte": {
|
|
1068
|
-
const val = nextParam(filter.value);
|
|
1069
|
-
return `.has(${key}, lte(${val}))`;
|
|
1070
|
-
}
|
|
1071
|
-
case "contains": {
|
|
1072
|
-
const val = nextParam(filter.value);
|
|
1073
|
-
return `.has(${key}, containing(${val}))`;
|
|
1074
|
-
}
|
|
1075
|
-
case "isNull":
|
|
1076
|
-
return `.hasNot(${key})`;
|
|
1077
|
-
case "isNotNull":
|
|
1078
|
-
return `.has(${key})`;
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
// src/relationships/compilers/CypherCompiler.ts
|
|
1083
|
-
var DEFAULT_ESTIMATED_FANOUT_PER_HOP2 = 10;
|
|
1084
|
-
var CypherCompiler = class {
|
|
1085
|
-
language = "cypher";
|
|
1086
|
-
compile(spec, _vocabulary) {
|
|
1087
|
-
const params = {};
|
|
1088
|
-
let paramIndex = 0;
|
|
1089
|
-
let estimatedFanOut = 1;
|
|
1090
|
-
const whereClauses = [];
|
|
1091
|
-
let nodeIndex = 0;
|
|
1092
|
-
const nextParam = (value) => {
|
|
1093
|
-
const name = `p${paramIndex++}`;
|
|
1094
|
-
params[name] = value;
|
|
1095
|
-
return `$${name}`;
|
|
1096
|
-
};
|
|
1097
|
-
const startNode = `n${nodeIndex++}`;
|
|
1098
|
-
let matchParts = [];
|
|
1099
|
-
if (spec.start.entityId) {
|
|
1100
|
-
matchParts.push(`(${startNode})`);
|
|
1101
|
-
whereClauses.push(`${startNode}.id = ${nextParam(spec.start.entityId)}`);
|
|
1102
|
-
} else if (spec.start.entityType) {
|
|
1103
|
-
matchParts.push(`(${startNode})`);
|
|
1104
|
-
whereClauses.push(`${startNode}.entityType = ${nextParam(spec.start.entityType)}`);
|
|
1105
|
-
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP2;
|
|
1106
|
-
} else {
|
|
1107
|
-
matchParts.push(`(${startNode})`);
|
|
1108
|
-
}
|
|
1109
|
-
if (spec.start.filter) {
|
|
1110
|
-
for (const f of spec.start.filter) {
|
|
1111
|
-
whereClauses.push(compilePropertyFilterCypher(startNode, f, nextParam));
|
|
1112
|
-
}
|
|
1113
|
-
}
|
|
1114
|
-
let lastNode = startNode;
|
|
1115
|
-
const steps = spec.steps ?? [];
|
|
1116
|
-
for (let i = 0; i < steps.length; i++) {
|
|
1117
|
-
const step = steps[i];
|
|
1118
|
-
const targetNode = `n${nodeIndex++}`;
|
|
1119
|
-
const relAlias = `r${i}`;
|
|
1120
|
-
const relTypes = step.relationshipTypes?.length ? step.relationshipTypes.join("|") : "";
|
|
1121
|
-
const relTypePattern = relTypes ? `:${relTypes}` : "";
|
|
1122
|
-
const depthPattern = step.repeat ? `*1..${step.repeat.maxDepth}` : "";
|
|
1123
|
-
let pattern;
|
|
1124
|
-
switch (step.direction) {
|
|
1125
|
-
case "out":
|
|
1126
|
-
pattern = `-[${relAlias}${relTypePattern}${depthPattern}]->(${targetNode})`;
|
|
1127
|
-
break;
|
|
1128
|
-
case "in":
|
|
1129
|
-
pattern = `<-[${relAlias}${relTypePattern}${depthPattern}]-(${targetNode})`;
|
|
1130
|
-
break;
|
|
1131
|
-
case "both":
|
|
1132
|
-
pattern = `-[${relAlias}${relTypePattern}${depthPattern}]-(${targetNode})`;
|
|
1133
|
-
break;
|
|
1134
|
-
}
|
|
1135
|
-
matchParts.push(pattern);
|
|
1136
|
-
estimatedFanOut *= step.repeat ? step.repeat.maxDepth * DEFAULT_ESTIMATED_FANOUT_PER_HOP2 : DEFAULT_ESTIMATED_FANOUT_PER_HOP2;
|
|
1137
|
-
if (step.entityTypes && step.entityTypes.length > 0) {
|
|
1138
|
-
const typeParam = nextParam(step.entityTypes);
|
|
1139
|
-
whereClauses.push(`${targetNode}.entityType IN ${typeParam}`);
|
|
1140
|
-
}
|
|
1141
|
-
if (step.entityFilter) {
|
|
1142
|
-
for (const f of step.entityFilter) {
|
|
1143
|
-
whereClauses.push(compilePropertyFilterCypher(targetNode, f, nextParam));
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
|
-
if (step.relationshipFilter) {
|
|
1147
|
-
for (const f of step.relationshipFilter) {
|
|
1148
|
-
whereClauses.push(compilePropertyFilterCypher(relAlias, f, nextParam));
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1151
|
-
lastNode = targetNode;
|
|
1152
|
-
}
|
|
1153
|
-
const matchClause = `MATCH ${matchParts[0]}${matchParts.slice(1).join("")}`;
|
|
1154
|
-
const whereClause = whereClauses.length > 0 ? `
|
|
1155
|
-
WHERE ${whereClauses.join(" AND ")}` : "";
|
|
1156
|
-
let returnClause;
|
|
1157
|
-
if (spec.returnMode === "path") {
|
|
1158
|
-
const allNodes = Array.from({ length: nodeIndex }, (_, i) => `n${i}`);
|
|
1159
|
-
const allRels = steps.map((_, i) => `r${i}`);
|
|
1160
|
-
returnClause = `RETURN ${[...allNodes, ...allRels].join(", ")}`;
|
|
1161
|
-
} else if (spec.returnMode === "all") {
|
|
1162
|
-
const allNodes = Array.from({ length: nodeIndex }, (_, i) => `n${i}`);
|
|
1163
|
-
returnClause = spec.dedup !== false ? `RETURN DISTINCT ${allNodes.join(", ")}` : `RETURN ${allNodes.join(", ")}`;
|
|
1164
|
-
} else {
|
|
1165
|
-
returnClause = spec.dedup !== false ? `RETURN DISTINCT ${lastNode}` : `RETURN ${lastNode}`;
|
|
1166
|
-
}
|
|
1167
|
-
const offset = spec.offset ?? 0;
|
|
1168
|
-
const limit = spec.limit ?? 50;
|
|
1169
|
-
const skipClause = offset > 0 ? `
|
|
1170
|
-
SKIP ${nextParam(offset)}` : "";
|
|
1171
|
-
const limitClause = `
|
|
1172
|
-
LIMIT ${nextParam(limit)}`;
|
|
1173
|
-
params["_limit"] = limit;
|
|
1174
|
-
params["_offset"] = offset;
|
|
1175
|
-
const query = `${matchClause}${whereClause}
|
|
1176
|
-
${returnClause}${skipClause}${limitClause}`;
|
|
1177
|
-
return {
|
|
1178
|
-
query,
|
|
1179
|
-
params,
|
|
1180
|
-
estimatedFanOut: Math.min(estimatedFanOut, 1e4)
|
|
1181
|
-
};
|
|
1182
|
-
}
|
|
1183
|
-
};
|
|
1184
|
-
function compilePropertyFilterCypher(nodeAlias, filter, nextParam) {
|
|
1185
|
-
const prop = `${nodeAlias}.${filter.key}`;
|
|
1186
|
-
switch (filter.operator) {
|
|
1187
|
-
case "eq":
|
|
1188
|
-
return `${prop} = ${nextParam(filter.value)}`;
|
|
1189
|
-
case "neq":
|
|
1190
|
-
return `${prop} <> ${nextParam(filter.value)}`;
|
|
1191
|
-
case "gt":
|
|
1192
|
-
return `${prop} > ${nextParam(filter.value)}`;
|
|
1193
|
-
case "gte":
|
|
1194
|
-
return `${prop} >= ${nextParam(filter.value)}`;
|
|
1195
|
-
case "lt":
|
|
1196
|
-
return `${prop} < ${nextParam(filter.value)}`;
|
|
1197
|
-
case "lte":
|
|
1198
|
-
return `${prop} <= ${nextParam(filter.value)}`;
|
|
1199
|
-
case "contains":
|
|
1200
|
-
return `${prop} CONTAINS ${nextParam(filter.value)}`;
|
|
1201
|
-
case "isNull":
|
|
1202
|
-
return `${prop} IS NULL`;
|
|
1203
|
-
case "isNotNull":
|
|
1204
|
-
return `${prop} IS NOT NULL`;
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
1207
|
-
|
|
1208
904
|
// src/relationships/PropertyFilterMatcher.ts
|
|
1209
905
|
function matchesPropertyFilters(properties, filters) {
|
|
1210
906
|
return filters.every((filter) => matchesSingleFilter(properties, filter));
|
|
@@ -1737,8 +1433,9 @@ var GraphTraversal = class {
|
|
|
1737
1433
|
}
|
|
1738
1434
|
/**
|
|
1739
1435
|
* Execute a structured traversal.
|
|
1740
|
-
* Validates the spec,
|
|
1741
|
-
* falls back to
|
|
1436
|
+
* Validates the spec, delegates to the GraphTraversalProvider if one is
|
|
1437
|
+
* registered (the provider owns native compilation), or falls back to
|
|
1438
|
+
* application-level BFS over StorageProvider.
|
|
1742
1439
|
*/
|
|
1743
1440
|
async traverse(spec) {
|
|
1744
1441
|
const capabilities = this.graphTraversalProvider?.getCapabilities();
|
|
@@ -1753,19 +1450,8 @@ var GraphTraversal = class {
|
|
|
1753
1450
|
}
|
|
1754
1451
|
throw new TraversalValidationError(structErrors.length > 0 ? structErrors : validation.errors);
|
|
1755
1452
|
}
|
|
1756
|
-
if (this.graphTraversalProvider
|
|
1757
|
-
|
|
1758
|
-
let compiledQuery;
|
|
1759
|
-
if (language === "gremlin") {
|
|
1760
|
-
const compiler = new GremlinCompiler();
|
|
1761
|
-
const compiled = compiler.compile(spec, vocabulary);
|
|
1762
|
-
compiledQuery = compiled.query;
|
|
1763
|
-
} else if (language === "cypher") {
|
|
1764
|
-
const compiler = new CypherCompiler();
|
|
1765
|
-
const compiled = compiler.compile(spec, vocabulary);
|
|
1766
|
-
compiledQuery = compiled.query;
|
|
1767
|
-
}
|
|
1768
|
-
return this.graphTraversalProvider.traverse(this.repositoryId, spec, compiledQuery);
|
|
1453
|
+
if (this.graphTraversalProvider) {
|
|
1454
|
+
return this.graphTraversalProvider.traverse(this.repositoryId, spec);
|
|
1769
1455
|
}
|
|
1770
1456
|
return executeFallbackTraversal(this.repositoryId, this.storage, spec);
|
|
1771
1457
|
}
|
|
@@ -3352,7 +3038,7 @@ var EventBus = class {
|
|
|
3352
3038
|
};
|
|
3353
3039
|
|
|
3354
3040
|
// src/portability/RepositoryExporter.ts
|
|
3355
|
-
var LIBRARY_VERSION = true ? "0.
|
|
3041
|
+
var LIBRARY_VERSION = true ? "0.6.1" : "0.1.0";
|
|
3356
3042
|
var RepositoryExporter = class {
|
|
3357
3043
|
storage;
|
|
3358
3044
|
provenance;
|
|
@@ -4146,6 +3832,16 @@ var DeepMemory = class {
|
|
|
4146
3832
|
await this.globalEventBus.emit("repository:opened", { repositoryId });
|
|
4147
3833
|
return repo;
|
|
4148
3834
|
}
|
|
3835
|
+
/** Get the full stored record for a single repository (including legal, owner, metadata, governance) */
|
|
3836
|
+
async getRepository(repositoryId) {
|
|
3837
|
+
await this.ensureInitialized();
|
|
3838
|
+
this.validateRepositoryId(repositoryId);
|
|
3839
|
+
const storedRepo = await this.storage.getRepository(repositoryId);
|
|
3840
|
+
if (!storedRepo) {
|
|
3841
|
+
throw new RepositoryNotFoundError(repositoryId);
|
|
3842
|
+
}
|
|
3843
|
+
return storedRepo;
|
|
3844
|
+
}
|
|
4149
3845
|
/** List all repositories */
|
|
4150
3846
|
async listRepositories(filter) {
|
|
4151
3847
|
await this.ensureInitialized();
|
|
@@ -4318,54 +4014,358 @@ var DeepMemory = class {
|
|
|
4318
4014
|
relationshipCount
|
|
4319
4015
|
});
|
|
4320
4016
|
}
|
|
4321
|
-
/**
|
|
4322
|
-
* Import a repository from a stream of chunks.
|
|
4323
|
-
* Use for large repositories to avoid loading everything into memory.
|
|
4324
|
-
*/
|
|
4325
|
-
async importRepositoryStream(header, chunks, options) {
|
|
4326
|
-
await this.ensureInitialized();
|
|
4327
|
-
const importer = new RepositoryImporter({
|
|
4328
|
-
storage: this.storage,
|
|
4329
|
-
actorId: this.provenance.getContext().actorId,
|
|
4330
|
-
onProgress: (progress) => this.globalEventBus.emit("import:progress", progress)
|
|
4331
|
-
});
|
|
4332
|
-
await this.globalEventBus.emit("import:started", { repositoryId: options.target.repositoryId });
|
|
4333
|
-
const result = await importer.importStream(header, chunks, options);
|
|
4334
|
-
if (result.success) {
|
|
4335
|
-
await this.globalEventBus.emit("import:completed", {
|
|
4336
|
-
repositoryId: result.repositoryId,
|
|
4337
|
-
entitiesImported: result.statistics.entitiesImported,
|
|
4338
|
-
relationshipsImported: result.statistics.relationshipsImported
|
|
4339
|
-
});
|
|
4340
|
-
} else {
|
|
4341
|
-
await this.globalEventBus.emit("import:failed", {
|
|
4342
|
-
repositoryId: result.repositoryId,
|
|
4343
|
-
error: result.warnings.map((w) => w.message).join("; ")
|
|
4344
|
-
});
|
|
4017
|
+
/**
|
|
4018
|
+
* Import a repository from a stream of chunks.
|
|
4019
|
+
* Use for large repositories to avoid loading everything into memory.
|
|
4020
|
+
*/
|
|
4021
|
+
async importRepositoryStream(header, chunks, options) {
|
|
4022
|
+
await this.ensureInitialized();
|
|
4023
|
+
const importer = new RepositoryImporter({
|
|
4024
|
+
storage: this.storage,
|
|
4025
|
+
actorId: this.provenance.getContext().actorId,
|
|
4026
|
+
onProgress: (progress) => this.globalEventBus.emit("import:progress", progress)
|
|
4027
|
+
});
|
|
4028
|
+
await this.globalEventBus.emit("import:started", { repositoryId: options.target.repositoryId });
|
|
4029
|
+
const result = await importer.importStream(header, chunks, options);
|
|
4030
|
+
if (result.success) {
|
|
4031
|
+
await this.globalEventBus.emit("import:completed", {
|
|
4032
|
+
repositoryId: result.repositoryId,
|
|
4033
|
+
entitiesImported: result.statistics.entitiesImported,
|
|
4034
|
+
relationshipsImported: result.statistics.relationshipsImported
|
|
4035
|
+
});
|
|
4036
|
+
} else {
|
|
4037
|
+
await this.globalEventBus.emit("import:failed", {
|
|
4038
|
+
repositoryId: result.repositoryId,
|
|
4039
|
+
error: result.warnings.map((w) => w.message).join("; ")
|
|
4040
|
+
});
|
|
4041
|
+
}
|
|
4042
|
+
return result;
|
|
4043
|
+
}
|
|
4044
|
+
/** Subscribe to global events */
|
|
4045
|
+
on(event, handler) {
|
|
4046
|
+
return this.globalEventBus.on(event, handler);
|
|
4047
|
+
}
|
|
4048
|
+
/** Update the provenance context (e.g., new conversation) */
|
|
4049
|
+
updateProvenance(context) {
|
|
4050
|
+
this.provenance.updateContext(context);
|
|
4051
|
+
this.globalEventBus.updateProvenance(this.provenance.getContext());
|
|
4052
|
+
}
|
|
4053
|
+
/** Dispose of all resources */
|
|
4054
|
+
async dispose() {
|
|
4055
|
+
this.globalEventBus.removeAllListeners();
|
|
4056
|
+
if (this.graphTraversalProvider?.dispose) {
|
|
4057
|
+
await this.graphTraversalProvider.dispose();
|
|
4058
|
+
}
|
|
4059
|
+
if (this.storage.dispose) {
|
|
4060
|
+
await this.storage.dispose();
|
|
4061
|
+
}
|
|
4062
|
+
this.initialized = false;
|
|
4063
|
+
}
|
|
4064
|
+
};
|
|
4065
|
+
|
|
4066
|
+
// src/relationships/compilers/GremlinCompiler.ts
|
|
4067
|
+
var DEFAULT_ESTIMATED_FANOUT_PER_HOP = 10;
|
|
4068
|
+
var GremlinCompiler = class {
|
|
4069
|
+
language = "gremlin";
|
|
4070
|
+
compile(spec, _vocabulary) {
|
|
4071
|
+
const parts = [];
|
|
4072
|
+
const params = {};
|
|
4073
|
+
let paramIndex = 0;
|
|
4074
|
+
let estimatedFanOut = 1;
|
|
4075
|
+
const nextParam = (value) => {
|
|
4076
|
+
const name = `p${paramIndex++}`;
|
|
4077
|
+
params[name] = value;
|
|
4078
|
+
return name;
|
|
4079
|
+
};
|
|
4080
|
+
parts.push("g.V()");
|
|
4081
|
+
if (spec.start.entityId) {
|
|
4082
|
+
const p = nextParam(spec.start.entityId);
|
|
4083
|
+
parts.push(`.has('id', ${p})`);
|
|
4084
|
+
} else if (spec.start.entityType) {
|
|
4085
|
+
const p = nextParam(spec.start.entityType);
|
|
4086
|
+
parts.push(`.has('entityType', ${p})`);
|
|
4087
|
+
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
4088
|
+
}
|
|
4089
|
+
if (spec.start.filter) {
|
|
4090
|
+
for (const f of spec.start.filter) {
|
|
4091
|
+
parts.push(compilePropertyFilter(f, nextParam));
|
|
4092
|
+
}
|
|
4093
|
+
}
|
|
4094
|
+
const steps = spec.steps ?? [];
|
|
4095
|
+
for (const step of steps) {
|
|
4096
|
+
if (step.repeat) {
|
|
4097
|
+
parts.push(compileRepeatStep(step, nextParam));
|
|
4098
|
+
estimatedFanOut *= step.repeat.maxDepth * DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
4099
|
+
} else if (step.relationshipFilter && step.relationshipFilter.length > 0) {
|
|
4100
|
+
parts.push(compileEdgeStep(step, nextParam));
|
|
4101
|
+
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
4102
|
+
} else {
|
|
4103
|
+
parts.push(compileSimpleStep(step, nextParam));
|
|
4104
|
+
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;
|
|
4105
|
+
}
|
|
4106
|
+
if (step.entityTypes && step.entityTypes.length > 0) {
|
|
4107
|
+
const typeParams = step.entityTypes.map((t) => nextParam(t));
|
|
4108
|
+
parts.push(`.has('entityType', within(${typeParams.join(", ")}))`);
|
|
4109
|
+
}
|
|
4110
|
+
if (step.entityFilter) {
|
|
4111
|
+
for (const f of step.entityFilter) {
|
|
4112
|
+
parts.push(compilePropertyFilter(f, nextParam));
|
|
4113
|
+
}
|
|
4114
|
+
}
|
|
4115
|
+
}
|
|
4116
|
+
if (spec.returnMode === "all") {
|
|
4117
|
+
}
|
|
4118
|
+
if (spec.dedup !== false) {
|
|
4119
|
+
parts.push(".dedup()");
|
|
4120
|
+
}
|
|
4121
|
+
const limit = spec.limit ?? 50;
|
|
4122
|
+
const offset = spec.offset ?? 0;
|
|
4123
|
+
const pOffset = nextParam(offset);
|
|
4124
|
+
const pEnd = nextParam(offset + limit);
|
|
4125
|
+
parts.push(`.range(${pOffset}, ${pEnd})`);
|
|
4126
|
+
params["_limit"] = limit;
|
|
4127
|
+
params["_offset"] = offset;
|
|
4128
|
+
if (spec.returnMode === "path") {
|
|
4129
|
+
parts.push(".path()");
|
|
4130
|
+
}
|
|
4131
|
+
if (spec.returnMode !== "path") {
|
|
4132
|
+
parts.push(".valueMap(true)");
|
|
4133
|
+
}
|
|
4134
|
+
return {
|
|
4135
|
+
query: parts.join(""),
|
|
4136
|
+
params,
|
|
4137
|
+
estimatedFanOut: Math.min(estimatedFanOut, 1e4)
|
|
4138
|
+
};
|
|
4139
|
+
}
|
|
4140
|
+
};
|
|
4141
|
+
function compileSimpleStep(step, nextParam) {
|
|
4142
|
+
const types = step.relationshipTypes;
|
|
4143
|
+
const typeArgs = types ? types.map((t) => nextParam(t)).join(", ") : "";
|
|
4144
|
+
switch (step.direction) {
|
|
4145
|
+
case "out":
|
|
4146
|
+
return types ? `.out(${typeArgs})` : ".out()";
|
|
4147
|
+
case "in":
|
|
4148
|
+
return types ? `.in(${typeArgs})` : ".in()";
|
|
4149
|
+
case "both":
|
|
4150
|
+
return types ? `.both(${typeArgs})` : ".both()";
|
|
4151
|
+
}
|
|
4152
|
+
}
|
|
4153
|
+
function compileEdgeStep(step, nextParam) {
|
|
4154
|
+
const parts = [];
|
|
4155
|
+
const types = step.relationshipTypes;
|
|
4156
|
+
const typeArgs = types ? types.map((t) => nextParam(t)).join(", ") : "";
|
|
4157
|
+
switch (step.direction) {
|
|
4158
|
+
case "out":
|
|
4159
|
+
parts.push(types ? `.outE(${typeArgs})` : ".outE()");
|
|
4160
|
+
break;
|
|
4161
|
+
case "in":
|
|
4162
|
+
parts.push(types ? `.inE(${typeArgs})` : ".inE()");
|
|
4163
|
+
break;
|
|
4164
|
+
case "both":
|
|
4165
|
+
parts.push(types ? `.bothE(${typeArgs})` : ".bothE()");
|
|
4166
|
+
break;
|
|
4167
|
+
}
|
|
4168
|
+
if (step.relationshipFilter) {
|
|
4169
|
+
for (const f of step.relationshipFilter) {
|
|
4170
|
+
parts.push(compilePropertyFilter(f, nextParam));
|
|
4345
4171
|
}
|
|
4346
|
-
return result;
|
|
4347
4172
|
}
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4173
|
+
switch (step.direction) {
|
|
4174
|
+
case "out":
|
|
4175
|
+
parts.push(".inV()");
|
|
4176
|
+
break;
|
|
4177
|
+
case "in":
|
|
4178
|
+
parts.push(".outV()");
|
|
4179
|
+
break;
|
|
4180
|
+
case "both":
|
|
4181
|
+
parts.push(".otherV()");
|
|
4182
|
+
break;
|
|
4351
4183
|
}
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4184
|
+
return parts.join("");
|
|
4185
|
+
}
|
|
4186
|
+
function compileRepeatStep(step, nextParam) {
|
|
4187
|
+
const parts = [];
|
|
4188
|
+
const innerStep = step.relationshipFilter?.length ? compileEdgeStep({ ...step, repeat: void 0 }, nextParam) : compileSimpleStep(step, nextParam);
|
|
4189
|
+
if (step.repeat?.emitIntermediates !== false) {
|
|
4190
|
+
parts.push(".emit()");
|
|
4356
4191
|
}
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4192
|
+
parts.push(`.repeat(${innerStep.startsWith(".") ? `__${innerStep}` : innerStep})`);
|
|
4193
|
+
if (step.repeat?.until && step.repeat.until.length > 0) {
|
|
4194
|
+
const untilParts = step.repeat.until.map((f) => compilePropertyFilter(f, nextParam));
|
|
4195
|
+
parts.push(`.until(${untilParts.join("")})`);
|
|
4196
|
+
}
|
|
4197
|
+
if (step.repeat?.maxDepth) {
|
|
4198
|
+
const p = nextParam(step.repeat.maxDepth);
|
|
4199
|
+
parts.push(`.times(${p})`);
|
|
4200
|
+
}
|
|
4201
|
+
if (step.repeat?.emitIntermediates === false) {
|
|
4202
|
+
parts.push(".emit()");
|
|
4203
|
+
}
|
|
4204
|
+
return parts.join("");
|
|
4205
|
+
}
|
|
4206
|
+
function compilePropertyFilter(filter, nextParam) {
|
|
4207
|
+
const key = nextParam(filter.key);
|
|
4208
|
+
switch (filter.operator) {
|
|
4209
|
+
case "eq": {
|
|
4210
|
+
const val = nextParam(filter.value);
|
|
4211
|
+
return `.has(${key}, ${val})`;
|
|
4362
4212
|
}
|
|
4363
|
-
|
|
4364
|
-
|
|
4213
|
+
case "neq": {
|
|
4214
|
+
const val = nextParam(filter.value);
|
|
4215
|
+
return `.has(${key}, neq(${val}))`;
|
|
4365
4216
|
}
|
|
4366
|
-
|
|
4217
|
+
case "gt": {
|
|
4218
|
+
const val = nextParam(filter.value);
|
|
4219
|
+
return `.has(${key}, gt(${val}))`;
|
|
4220
|
+
}
|
|
4221
|
+
case "gte": {
|
|
4222
|
+
const val = nextParam(filter.value);
|
|
4223
|
+
return `.has(${key}, gte(${val}))`;
|
|
4224
|
+
}
|
|
4225
|
+
case "lt": {
|
|
4226
|
+
const val = nextParam(filter.value);
|
|
4227
|
+
return `.has(${key}, lt(${val}))`;
|
|
4228
|
+
}
|
|
4229
|
+
case "lte": {
|
|
4230
|
+
const val = nextParam(filter.value);
|
|
4231
|
+
return `.has(${key}, lte(${val}))`;
|
|
4232
|
+
}
|
|
4233
|
+
case "contains": {
|
|
4234
|
+
const val = nextParam(filter.value);
|
|
4235
|
+
return `.has(${key}, containing(${val}))`;
|
|
4236
|
+
}
|
|
4237
|
+
case "isNull":
|
|
4238
|
+
return `.hasNot(${key})`;
|
|
4239
|
+
case "isNotNull":
|
|
4240
|
+
return `.has(${key})`;
|
|
4241
|
+
}
|
|
4242
|
+
}
|
|
4243
|
+
|
|
4244
|
+
// src/relationships/compilers/CypherCompiler.ts
|
|
4245
|
+
var DEFAULT_ESTIMATED_FANOUT_PER_HOP2 = 10;
|
|
4246
|
+
var CypherCompiler = class {
|
|
4247
|
+
language = "cypher";
|
|
4248
|
+
compile(spec, _vocabulary) {
|
|
4249
|
+
const params = {};
|
|
4250
|
+
let paramIndex = 0;
|
|
4251
|
+
let estimatedFanOut = 1;
|
|
4252
|
+
const whereClauses = [];
|
|
4253
|
+
let nodeIndex = 0;
|
|
4254
|
+
const nextParam = (value) => {
|
|
4255
|
+
const name = `p${paramIndex++}`;
|
|
4256
|
+
params[name] = value;
|
|
4257
|
+
return `$${name}`;
|
|
4258
|
+
};
|
|
4259
|
+
const startNode = `n${nodeIndex++}`;
|
|
4260
|
+
let matchParts = [];
|
|
4261
|
+
if (spec.start.entityId) {
|
|
4262
|
+
matchParts.push(`(${startNode})`);
|
|
4263
|
+
whereClauses.push(`${startNode}.id = ${nextParam(spec.start.entityId)}`);
|
|
4264
|
+
} else if (spec.start.entityType) {
|
|
4265
|
+
matchParts.push(`(${startNode})`);
|
|
4266
|
+
whereClauses.push(`${startNode}.entityType = ${nextParam(spec.start.entityType)}`);
|
|
4267
|
+
estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP2;
|
|
4268
|
+
} else {
|
|
4269
|
+
matchParts.push(`(${startNode})`);
|
|
4270
|
+
}
|
|
4271
|
+
if (spec.start.filter) {
|
|
4272
|
+
for (const f of spec.start.filter) {
|
|
4273
|
+
whereClauses.push(compilePropertyFilterCypher(startNode, f, nextParam));
|
|
4274
|
+
}
|
|
4275
|
+
}
|
|
4276
|
+
let lastNode = startNode;
|
|
4277
|
+
const steps = spec.steps ?? [];
|
|
4278
|
+
for (let i = 0; i < steps.length; i++) {
|
|
4279
|
+
const step = steps[i];
|
|
4280
|
+
const targetNode = `n${nodeIndex++}`;
|
|
4281
|
+
const relAlias = `r${i}`;
|
|
4282
|
+
const relTypes = step.relationshipTypes?.length ? step.relationshipTypes.join("|") : "";
|
|
4283
|
+
const relTypePattern = relTypes ? `:${relTypes}` : "";
|
|
4284
|
+
const depthPattern = step.repeat ? `*1..${step.repeat.maxDepth}` : "";
|
|
4285
|
+
let pattern;
|
|
4286
|
+
switch (step.direction) {
|
|
4287
|
+
case "out":
|
|
4288
|
+
pattern = `-[${relAlias}${relTypePattern}${depthPattern}]->(${targetNode})`;
|
|
4289
|
+
break;
|
|
4290
|
+
case "in":
|
|
4291
|
+
pattern = `<-[${relAlias}${relTypePattern}${depthPattern}]-(${targetNode})`;
|
|
4292
|
+
break;
|
|
4293
|
+
case "both":
|
|
4294
|
+
pattern = `-[${relAlias}${relTypePattern}${depthPattern}]-(${targetNode})`;
|
|
4295
|
+
break;
|
|
4296
|
+
}
|
|
4297
|
+
matchParts.push(pattern);
|
|
4298
|
+
estimatedFanOut *= step.repeat ? step.repeat.maxDepth * DEFAULT_ESTIMATED_FANOUT_PER_HOP2 : DEFAULT_ESTIMATED_FANOUT_PER_HOP2;
|
|
4299
|
+
if (step.entityTypes && step.entityTypes.length > 0) {
|
|
4300
|
+
const typeParam = nextParam(step.entityTypes);
|
|
4301
|
+
whereClauses.push(`${targetNode}.entityType IN ${typeParam}`);
|
|
4302
|
+
}
|
|
4303
|
+
if (step.entityFilter) {
|
|
4304
|
+
for (const f of step.entityFilter) {
|
|
4305
|
+
whereClauses.push(compilePropertyFilterCypher(targetNode, f, nextParam));
|
|
4306
|
+
}
|
|
4307
|
+
}
|
|
4308
|
+
if (step.relationshipFilter) {
|
|
4309
|
+
for (const f of step.relationshipFilter) {
|
|
4310
|
+
whereClauses.push(compilePropertyFilterCypher(relAlias, f, nextParam));
|
|
4311
|
+
}
|
|
4312
|
+
}
|
|
4313
|
+
lastNode = targetNode;
|
|
4314
|
+
}
|
|
4315
|
+
const matchClause = `MATCH ${matchParts[0]}${matchParts.slice(1).join("")}`;
|
|
4316
|
+
const whereClause = whereClauses.length > 0 ? `
|
|
4317
|
+
WHERE ${whereClauses.join(" AND ")}` : "";
|
|
4318
|
+
let returnClause;
|
|
4319
|
+
if (spec.returnMode === "path") {
|
|
4320
|
+
const allNodes = Array.from({ length: nodeIndex }, (_, i) => `n${i}`);
|
|
4321
|
+
const allRels = steps.map((_, i) => `r${i}`);
|
|
4322
|
+
returnClause = `RETURN ${[...allNodes, ...allRels].join(", ")}`;
|
|
4323
|
+
} else if (spec.returnMode === "all") {
|
|
4324
|
+
const allNodes = Array.from({ length: nodeIndex }, (_, i) => `n${i}`);
|
|
4325
|
+
returnClause = spec.dedup !== false ? `RETURN DISTINCT ${allNodes.join(", ")}` : `RETURN ${allNodes.join(", ")}`;
|
|
4326
|
+
} else {
|
|
4327
|
+
returnClause = spec.dedup !== false ? `RETURN DISTINCT ${lastNode}` : `RETURN ${lastNode}`;
|
|
4328
|
+
}
|
|
4329
|
+
const offset = spec.offset ?? 0;
|
|
4330
|
+
const limit = spec.limit ?? 50;
|
|
4331
|
+
const skipClause = offset > 0 ? `
|
|
4332
|
+
SKIP ${nextParam(offset)}` : "";
|
|
4333
|
+
const limitClause = `
|
|
4334
|
+
LIMIT ${nextParam(limit)}`;
|
|
4335
|
+
params["_limit"] = limit;
|
|
4336
|
+
params["_offset"] = offset;
|
|
4337
|
+
const query = `${matchClause}${whereClause}
|
|
4338
|
+
${returnClause}${skipClause}${limitClause}`;
|
|
4339
|
+
return {
|
|
4340
|
+
query,
|
|
4341
|
+
params,
|
|
4342
|
+
estimatedFanOut: Math.min(estimatedFanOut, 1e4)
|
|
4343
|
+
};
|
|
4367
4344
|
}
|
|
4368
4345
|
};
|
|
4346
|
+
function compilePropertyFilterCypher(nodeAlias, filter, nextParam) {
|
|
4347
|
+
const prop = `${nodeAlias}.${filter.key}`;
|
|
4348
|
+
switch (filter.operator) {
|
|
4349
|
+
case "eq":
|
|
4350
|
+
return `${prop} = ${nextParam(filter.value)}`;
|
|
4351
|
+
case "neq":
|
|
4352
|
+
return `${prop} <> ${nextParam(filter.value)}`;
|
|
4353
|
+
case "gt":
|
|
4354
|
+
return `${prop} > ${nextParam(filter.value)}`;
|
|
4355
|
+
case "gte":
|
|
4356
|
+
return `${prop} >= ${nextParam(filter.value)}`;
|
|
4357
|
+
case "lt":
|
|
4358
|
+
return `${prop} < ${nextParam(filter.value)}`;
|
|
4359
|
+
case "lte":
|
|
4360
|
+
return `${prop} <= ${nextParam(filter.value)}`;
|
|
4361
|
+
case "contains":
|
|
4362
|
+
return `${prop} CONTAINS ${nextParam(filter.value)}`;
|
|
4363
|
+
case "isNull":
|
|
4364
|
+
return `${prop} IS NULL`;
|
|
4365
|
+
case "isNotNull":
|
|
4366
|
+
return `${prop} IS NOT NULL`;
|
|
4367
|
+
}
|
|
4368
|
+
}
|
|
4369
4369
|
|
|
4370
4370
|
// src/providers-builtin/InMemoryStorageProvider.ts
|
|
4371
4371
|
var InMemoryStorageProvider = class {
|
|
@@ -5099,6 +5099,7 @@ export {
|
|
|
5099
5099
|
VocabularyValidationError,
|
|
5100
5100
|
generateId,
|
|
5101
5101
|
isValidUuid,
|
|
5102
|
-
matchesPropertyFilters
|
|
5102
|
+
matchesPropertyFilters,
|
|
5103
|
+
projectEntity
|
|
5103
5104
|
};
|
|
5104
5105
|
//# sourceMappingURL=index.js.map
|