@semiont/graph 0.5.27 → 0.5.28
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/{chunk-GPJBZ6EG.js → chunk-2FPUYYXX.js} +9 -1
- package/dist/chunk-2FPUYYXX.js.map +1 -0
- package/dist/{chunk-Y62BMZ25.js → chunk-52FQCX5M.js} +18 -6
- package/dist/chunk-52FQCX5M.js.map +1 -0
- package/dist/{chunk-NYHKKGBV.js → chunk-MO34K2LQ.js} +32 -19
- package/dist/chunk-MO34K2LQ.js.map +1 -0
- package/dist/{chunk-7BYJ5YHD.js → chunk-RUKYB5L4.js} +6 -6
- package/dist/{chunk-7BYJ5YHD.js.map → chunk-RUKYB5L4.js.map} +1 -1
- package/dist/{chunk-YYVVWLB2.js → chunk-TKWHSSPF.js} +35 -16
- package/dist/chunk-TKWHSSPF.js.map +1 -0
- package/dist/{chunk-RRZDPP7Z.js → chunk-X77CPJUJ.js} +2 -2
- package/dist/{chunk-UKT6IXAM.js → chunk-XTHXGGIJ.js} +3 -3
- package/dist/{chunk-RBRHTAJN.js → chunk-ZPM4D2XD.js} +14 -5
- package/dist/chunk-ZPM4D2XD.js.map +1 -0
- package/dist/{dist-es-2ZN6SLSG.js → dist-es-AET2QNVA.js} +21 -21
- package/dist/dist-es-AET2QNVA.js.map +1 -0
- package/dist/{dist-es-RZ3HNVJG.js → dist-es-BSJRQ6XP.js} +7 -7
- package/dist/{dist-es-7CR3IHJD.js → dist-es-C2VXNLLU.js} +13 -13
- package/dist/{dist-es-M72B762W.js → dist-es-FTEZAK7G.js} +5 -5
- package/dist/{dist-es-NGG7JHEH.js → dist-es-FV5JDCUX.js} +4 -4
- package/dist/{dist-es-V3UQXKNJ.js → dist-es-IS4IC3TZ.js} +5 -5
- package/dist/{dist-es-ILOZ33QI.js → dist-es-ISXX5KU4.js} +5 -5
- package/dist/{dist-es-J63OY2RR.js → dist-es-RR4OU64S.js} +5 -5
- package/dist/{dist-es-LN4LZWKV.js → dist-es-V7467ELV.js} +3 -3
- package/dist/{event-streams-2HBIXE6X.js → event-streams-UU2VASBU.js} +36 -27
- package/dist/event-streams-UU2VASBU.js.map +1 -0
- package/dist/index.d.ts +0 -3
- package/dist/index.js +233 -342
- package/dist/index.js.map +1 -1
- package/dist/{loadSso-JTXSMWFI.js → loadSso-SCNBGUAS.js} +8 -8
- package/dist/{signin-BM6IHIKX.js → signin-6CO4ELBM.js} +8 -8
- package/dist/{sso-oidc-IBGZ52NP.js → sso-oidc-NYPIZEZ2.js} +8 -8
- package/dist/{sts-44HZWQDH.js → sts-7LYERIMP.js} +8 -8
- package/package.json +6 -6
- package/dist/chunk-GPJBZ6EG.js.map +0 -1
- package/dist/chunk-NYHKKGBV.js.map +0 -1
- package/dist/chunk-RBRHTAJN.js.map +0 -1
- package/dist/chunk-Y62BMZ25.js.map +0 -1
- package/dist/chunk-YYVVWLB2.js.map +0 -1
- package/dist/dist-es-2ZN6SLSG.js.map +0 -1
- package/dist/event-streams-2HBIXE6X.js.map +0 -1
- /package/dist/{chunk-RRZDPP7Z.js.map → chunk-X77CPJUJ.js.map} +0 -0
- /package/dist/{chunk-UKT6IXAM.js.map → chunk-XTHXGGIJ.js.map} +0 -0
- /package/dist/{dist-es-RZ3HNVJG.js.map → dist-es-BSJRQ6XP.js.map} +0 -0
- /package/dist/{dist-es-7CR3IHJD.js.map → dist-es-C2VXNLLU.js.map} +0 -0
- /package/dist/{dist-es-M72B762W.js.map → dist-es-FTEZAK7G.js.map} +0 -0
- /package/dist/{dist-es-NGG7JHEH.js.map → dist-es-FV5JDCUX.js.map} +0 -0
- /package/dist/{dist-es-V3UQXKNJ.js.map → dist-es-IS4IC3TZ.js.map} +0 -0
- /package/dist/{dist-es-ILOZ33QI.js.map → dist-es-ISXX5KU4.js.map} +0 -0
- /package/dist/{dist-es-J63OY2RR.js.map → dist-es-RR4OU64S.js.map} +0 -0
- /package/dist/{dist-es-LN4LZWKV.js.map → dist-es-V7467ELV.js.map} +0 -0
- /package/dist/{loadSso-JTXSMWFI.js.map → loadSso-SCNBGUAS.js.map} +0 -0
- /package/dist/{signin-BM6IHIKX.js.map → signin-6CO4ELBM.js.map} +0 -0
- /package/dist/{sso-oidc-IBGZ52NP.js.map → sso-oidc-NYPIZEZ2.js.map} +0 -0
- /package/dist/{sts-44HZWQDH.js.map → sts-7LYERIMP.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -57,9 +57,107 @@ function queryResources(all, filter) {
|
|
|
57
57
|
|
|
58
58
|
// src/implementations/neptune.ts
|
|
59
59
|
import { getEntityTypes } from "@semiont/ontology";
|
|
60
|
+
|
|
61
|
+
// src/annotation-codec.ts
|
|
60
62
|
import { annotationId as makeAnnotationId } from "@semiont/core";
|
|
63
|
+
import { getBodySource, getExactText, getTargetSelector, getTargetSource } from "@semiont/core";
|
|
64
|
+
function storedAnnotationType(motivation) {
|
|
65
|
+
return motivation === "highlighting" ? "TextualBody" : "SpecificResource";
|
|
66
|
+
}
|
|
67
|
+
function motivationForCategory(category) {
|
|
68
|
+
return category === "highlight" ? "highlighting" : "linking";
|
|
69
|
+
}
|
|
70
|
+
function buildAnnotation(input, created) {
|
|
71
|
+
const annotation = {
|
|
72
|
+
"@context": "http://www.w3.org/ns/anno.jsonld",
|
|
73
|
+
type: "Annotation",
|
|
74
|
+
id: makeAnnotationId(input.id),
|
|
75
|
+
motivation: input.motivation,
|
|
76
|
+
target: input.target,
|
|
77
|
+
creator: input.creator,
|
|
78
|
+
created
|
|
79
|
+
};
|
|
80
|
+
if (input.body && (!Array.isArray(input.body) || input.body.length > 0)) {
|
|
81
|
+
annotation.body = input.body;
|
|
82
|
+
}
|
|
83
|
+
return annotation;
|
|
84
|
+
}
|
|
85
|
+
function encodeAnnotation(annotation) {
|
|
86
|
+
const selector = getTargetSelector(annotation.target);
|
|
87
|
+
const bodySource = getBodySource(annotation.body);
|
|
88
|
+
const resourceId = getTargetSource(annotation.target);
|
|
89
|
+
if (!resourceId) throw new Error(`Annotation ${annotation.id} has no target source`);
|
|
90
|
+
if (!annotation.created) throw new Error(`Annotation ${annotation.id} has no created timestamp`);
|
|
91
|
+
const props = {
|
|
92
|
+
id: annotation.id,
|
|
93
|
+
resourceId,
|
|
94
|
+
type: storedAnnotationType(annotation.motivation),
|
|
95
|
+
motivation: annotation.motivation,
|
|
96
|
+
creator: JSON.stringify(annotation.creator),
|
|
97
|
+
created: annotation.created
|
|
98
|
+
};
|
|
99
|
+
if (selector) Object.assign(props, encodeSelector(selector));
|
|
100
|
+
if (bodySource) props.source = bodySource;
|
|
101
|
+
if (annotation.modified) props.modified = annotation.modified;
|
|
102
|
+
if (annotation.generator) props.generator = JSON.stringify(annotation.generator);
|
|
103
|
+
return props;
|
|
104
|
+
}
|
|
105
|
+
function encodeSelector(selector) {
|
|
106
|
+
const props = { selector: JSON.stringify(selector) };
|
|
107
|
+
const exact = getExactText(selector);
|
|
108
|
+
if (exact) props.exact = exact;
|
|
109
|
+
return props;
|
|
110
|
+
}
|
|
111
|
+
function decodeAnnotation(props, entityTypes = []) {
|
|
112
|
+
const id = props.id;
|
|
113
|
+
if (!id) throw new Error("Annotation missing required field: id");
|
|
114
|
+
const required = (key) => {
|
|
115
|
+
const value = props[key];
|
|
116
|
+
if (!value) throw new Error(`Annotation ${id} missing required field: ${key}`);
|
|
117
|
+
return value;
|
|
118
|
+
};
|
|
119
|
+
const resourceId = required("resourceId");
|
|
120
|
+
const creator = JSON.parse(required("creator"));
|
|
121
|
+
const motivation = required("motivation");
|
|
122
|
+
const created = required("created");
|
|
123
|
+
const body = [];
|
|
124
|
+
for (const entityType of entityTypes) {
|
|
125
|
+
if (entityType) body.push({ type: "TextualBody", value: entityType, purpose: "tagging" });
|
|
126
|
+
}
|
|
127
|
+
if (props.source) {
|
|
128
|
+
body.push({ type: "SpecificResource", source: props.source, purpose: "linking" });
|
|
129
|
+
}
|
|
130
|
+
const selector = decodeSelector(props.selector);
|
|
131
|
+
const target = selector ? { source: resourceId, selector } : { source: resourceId };
|
|
132
|
+
const annotation = {
|
|
133
|
+
"@context": "http://www.w3.org/ns/anno.jsonld",
|
|
134
|
+
type: "Annotation",
|
|
135
|
+
id: makeAnnotationId(id),
|
|
136
|
+
motivation,
|
|
137
|
+
target,
|
|
138
|
+
creator,
|
|
139
|
+
created
|
|
140
|
+
};
|
|
141
|
+
if (body.length > 0) annotation.body = body;
|
|
142
|
+
if (props.modified) annotation.modified = props.modified;
|
|
143
|
+
if (props.generator) {
|
|
144
|
+
try {
|
|
145
|
+
annotation.generator = JSON.parse(props.generator);
|
|
146
|
+
} catch {
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return annotation;
|
|
150
|
+
}
|
|
151
|
+
function decodeSelector(raw) {
|
|
152
|
+
if (!raw) return void 0;
|
|
153
|
+
const parsed = JSON.parse(raw);
|
|
154
|
+
if (!parsed || Object.keys(parsed).length === 0) return void 0;
|
|
155
|
+
return parsed;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// src/implementations/neptune.ts
|
|
61
159
|
import { v4 as uuidv4 } from "uuid";
|
|
62
|
-
import { getBodySource
|
|
160
|
+
import { getBodySource as getBodySource2, getTargetSource as getTargetSource2, getPrimaryRepresentation, getResourceId } from "@semiont/core";
|
|
63
161
|
var NeptuneClient;
|
|
64
162
|
var DescribeDBClustersCommand;
|
|
65
163
|
var gremlin;
|
|
@@ -69,7 +167,7 @@ var cardinality;
|
|
|
69
167
|
var __;
|
|
70
168
|
async function loadDependencies() {
|
|
71
169
|
if (!NeptuneClient) {
|
|
72
|
-
const neptuneModule = await import("./dist-es-
|
|
170
|
+
const neptuneModule = await import("./dist-es-AET2QNVA.js");
|
|
73
171
|
NeptuneClient = neptuneModule.NeptuneClient;
|
|
74
172
|
DescribeDBClustersCommand = neptuneModule.DescribeDBClustersCommand;
|
|
75
173
|
}
|
|
@@ -125,70 +223,22 @@ function vertexToResource(vertex) {
|
|
|
125
223
|
return resource;
|
|
126
224
|
}
|
|
127
225
|
function vertexToAnnotation(vertex, entityTypes = []) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const resourceId = getValue("resourceId", true);
|
|
145
|
-
const selectorRaw = getValue("selector", true);
|
|
146
|
-
const creatorRaw = getValue("creator", true);
|
|
147
|
-
const createdRaw = getValue("created", true);
|
|
148
|
-
const motivation = getValue("motivation") || "linking";
|
|
149
|
-
const creator = JSON.parse(creatorRaw);
|
|
150
|
-
const bodyArray = [];
|
|
151
|
-
for (const entityType of entityTypes) {
|
|
152
|
-
if (entityType) {
|
|
153
|
-
bodyArray.push({
|
|
154
|
-
type: "TextualBody",
|
|
155
|
-
value: entityType,
|
|
156
|
-
purpose: "tagging"
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
const bodySource = getValue("source");
|
|
161
|
-
if (bodySource) {
|
|
162
|
-
bodyArray.push({
|
|
163
|
-
type: "SpecificResource",
|
|
164
|
-
source: bodySource,
|
|
165
|
-
purpose: "linking"
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
const annotation = {
|
|
169
|
-
"@context": "http://www.w3.org/ns/anno.jsonld",
|
|
170
|
-
"type": "Annotation",
|
|
171
|
-
id,
|
|
172
|
-
motivation,
|
|
173
|
-
target: {
|
|
174
|
-
source: resourceId,
|
|
175
|
-
selector: JSON.parse(selectorRaw)
|
|
176
|
-
},
|
|
177
|
-
body: bodyArray,
|
|
178
|
-
creator,
|
|
179
|
-
created: createdRaw
|
|
180
|
-
// ISO string from DB
|
|
181
|
-
};
|
|
182
|
-
const modified = getValue("modified");
|
|
183
|
-
if (modified) annotation.modified = modified;
|
|
184
|
-
const generatorJson = getValue("generator");
|
|
185
|
-
if (generatorJson) {
|
|
186
|
-
try {
|
|
187
|
-
annotation.generator = JSON.parse(generatorJson);
|
|
188
|
-
} catch (e) {
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
return annotation;
|
|
226
|
+
return decodeAnnotation(normalizeProperties(vertex.properties || vertex), entityTypes);
|
|
227
|
+
}
|
|
228
|
+
function normalizeProperties(props) {
|
|
229
|
+
const normalized = {};
|
|
230
|
+
for (const [key, raw] of Object.entries(props ?? {})) {
|
|
231
|
+
const value = unwrap(raw);
|
|
232
|
+
if (value === void 0 || value === null) continue;
|
|
233
|
+
normalized[key] = typeof value === "string" ? value : String(value);
|
|
234
|
+
}
|
|
235
|
+
return normalized;
|
|
236
|
+
}
|
|
237
|
+
function unwrap(prop) {
|
|
238
|
+
if (prop === void 0 || prop === null) return void 0;
|
|
239
|
+
if (Array.isArray(prop)) return prop.length > 0 ? unwrap(prop[0]) : void 0;
|
|
240
|
+
if (typeof prop === "object" && "value" in prop) return prop.value;
|
|
241
|
+
return prop;
|
|
192
242
|
}
|
|
193
243
|
var NeptuneGraphDatabase = class {
|
|
194
244
|
connected = false;
|
|
@@ -385,25 +435,15 @@ var NeptuneGraphDatabase = class {
|
|
|
385
435
|
}
|
|
386
436
|
}
|
|
387
437
|
async createAnnotation(input) {
|
|
388
|
-
const
|
|
389
|
-
const
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
id: makeAnnotationId(id),
|
|
393
|
-
motivation: input.motivation,
|
|
394
|
-
target: input.target,
|
|
395
|
-
body: input.body,
|
|
396
|
-
creator: input.creator,
|
|
397
|
-
created: (/* @__PURE__ */ new Date()).toISOString()
|
|
398
|
-
};
|
|
399
|
-
const targetSource = getTargetSource(input.target);
|
|
400
|
-
const targetSelector = getTargetSelector(input.target);
|
|
401
|
-
const bodySource = getBodySource(input.body);
|
|
438
|
+
const annotation = buildAnnotation(input, (/* @__PURE__ */ new Date()).toISOString());
|
|
439
|
+
const props = encodeAnnotation(annotation);
|
|
440
|
+
const targetSource = props.resourceId;
|
|
441
|
+
const bodySource = props.source;
|
|
402
442
|
const entityTypes = getEntityTypes(input);
|
|
403
443
|
try {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
vertex.property(
|
|
444
|
+
let vertex = this.g.addV("Annotation");
|
|
445
|
+
for (const [key, value] of Object.entries(props)) {
|
|
446
|
+
vertex = vertex.property(key, value);
|
|
407
447
|
}
|
|
408
448
|
const newVertex = await vertex.next();
|
|
409
449
|
await this.g.V(newVertex.value).addE("BELONGS_TO").to(this.g.V().hasLabel("Resource").has("id", targetSource)).next();
|
|
@@ -443,11 +483,13 @@ var NeptuneGraphDatabase = class {
|
|
|
443
483
|
let traversal = this.g.V().hasLabel("Annotation").has("id", id);
|
|
444
484
|
if (updates.target !== void 0 && typeof updates.target !== "string") {
|
|
445
485
|
if (updates.target.selector !== void 0) {
|
|
446
|
-
|
|
486
|
+
for (const [key, value] of Object.entries(encodeSelector(updates.target.selector))) {
|
|
487
|
+
traversal = traversal.property(key, value);
|
|
488
|
+
}
|
|
447
489
|
}
|
|
448
490
|
}
|
|
449
491
|
if (updates.body !== void 0) {
|
|
450
|
-
const bodySource =
|
|
492
|
+
const bodySource = getBodySource2(updates.body);
|
|
451
493
|
const entityTypes2 = getEntityTypes({ body: updates.body });
|
|
452
494
|
if (bodySource) {
|
|
453
495
|
traversal = traversal.property("source", bodySource);
|
|
@@ -497,8 +539,7 @@ var NeptuneGraphDatabase = class {
|
|
|
497
539
|
traversal = traversal.has("resourceId", filter.resourceId);
|
|
498
540
|
}
|
|
499
541
|
if (filter.type) {
|
|
500
|
-
|
|
501
|
-
traversal = traversal.has("type", w3cType);
|
|
542
|
+
traversal = traversal.has("type", storedAnnotationType(motivationForCategory(filter.type)));
|
|
502
543
|
}
|
|
503
544
|
const results = await traversal.elementMap().toList();
|
|
504
545
|
const annotations = await this.fetchAnnotationsWithEntityTypes(results);
|
|
@@ -592,7 +633,7 @@ var NeptuneGraphDatabase = class {
|
|
|
592
633
|
const entityTypesResult = await this.g.V().hasLabel("Annotation").has("id", id).out("TAGGED_AS").hasLabel("EntityType").values("name").toList();
|
|
593
634
|
const entityTypes = entityTypesResult || [];
|
|
594
635
|
const annotation = vertexToAnnotation(annVertex, entityTypes);
|
|
595
|
-
const targetDocId =
|
|
636
|
+
const targetDocId = getBodySource2(annotation.body);
|
|
596
637
|
if (!targetDocId) continue;
|
|
597
638
|
const targetDocResult = await this.g.V().hasLabel("Resource").has("id", targetDocId).elementMap().next();
|
|
598
639
|
if (targetDocResult.value) {
|
|
@@ -616,7 +657,7 @@ var NeptuneGraphDatabase = class {
|
|
|
616
657
|
const entityTypesResult = await this.g.V().hasLabel("Annotation").has("id", id).out("TAGGED_AS").hasLabel("EntityType").values("name").toList();
|
|
617
658
|
const entityTypes = entityTypesResult || [];
|
|
618
659
|
const annotation = vertexToAnnotation(annVertex, entityTypes);
|
|
619
|
-
const sourceDocId =
|
|
660
|
+
const sourceDocId = getTargetSource2(annotation.target);
|
|
620
661
|
const existing = connectionsMap.get(sourceDocId);
|
|
621
662
|
if (existing) {
|
|
622
663
|
existing.bidirectional = true;
|
|
@@ -820,9 +861,8 @@ var NeptuneGraphDatabase = class {
|
|
|
820
861
|
};
|
|
821
862
|
|
|
822
863
|
// src/implementations/neo4j.ts
|
|
823
|
-
import { annotationId as makeAnnotationId2 } from "@semiont/core";
|
|
824
864
|
import { v4 as uuidv42 } from "uuid";
|
|
825
|
-
import {
|
|
865
|
+
import { getPrimaryRepresentation as getPrimaryRepresentation2 } from "@semiont/core";
|
|
826
866
|
import { getEntityTypes as getEntityTypes2 } from "@semiont/ontology";
|
|
827
867
|
function motivationToLabel(motivation) {
|
|
828
868
|
return motivation.charAt(0).toUpperCase() + motivation.slice(1);
|
|
@@ -1089,85 +1129,42 @@ var Neo4jGraphDatabase = class {
|
|
|
1089
1129
|
async createAnnotation(input) {
|
|
1090
1130
|
const session = this.getSession();
|
|
1091
1131
|
try {
|
|
1092
|
-
const
|
|
1093
|
-
const
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
id: makeAnnotationId2(id),
|
|
1097
|
-
motivation: input.motivation,
|
|
1098
|
-
target: input.target,
|
|
1099
|
-
body: input.body,
|
|
1100
|
-
creator: input.creator,
|
|
1101
|
-
created: (/* @__PURE__ */ new Date()).toISOString()
|
|
1102
|
-
};
|
|
1103
|
-
const targetSource = getTargetSource2(input.target);
|
|
1104
|
-
const targetSelector = getTargetSelector2(input.target);
|
|
1105
|
-
const bodySource = getBodySource2(input.body);
|
|
1132
|
+
const annotation = buildAnnotation(input, (/* @__PURE__ */ new Date()).toISOString());
|
|
1133
|
+
const props = encodeAnnotation(annotation);
|
|
1134
|
+
const targetSource = props.resourceId;
|
|
1135
|
+
const bodySource = props.source;
|
|
1106
1136
|
const entityTypes = getEntityTypes2(input);
|
|
1107
1137
|
const motivationLabel = motivationToLabel(annotation.motivation);
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
CREATE (a:Annotation:${motivationLabel} {
|
|
1113
|
-
id: $id,
|
|
1114
|
-
resourceId: $resourceId,
|
|
1115
|
-
exact: $exact,
|
|
1116
|
-
selector: $selector,
|
|
1117
|
-
type: $type,
|
|
1118
|
-
motivation: $motivation,
|
|
1119
|
-
creator: $creator,
|
|
1120
|
-
created: datetime($created),
|
|
1121
|
-
source: $source
|
|
1122
|
-
})
|
|
1138
|
+
const cypher = bodySource ? `MATCH (from:Resource {id: $targetSource})
|
|
1139
|
+
MATCH (to:Resource {id: $bodySource})
|
|
1140
|
+
CREATE (a:Annotation:${motivationLabel})
|
|
1141
|
+
SET a = $props, a.created = datetime($created)
|
|
1123
1142
|
CREATE (a)-[:BELONGS_TO]->(from)
|
|
1124
1143
|
CREATE (a)-[:REFERENCES]->(to)
|
|
1125
1144
|
FOREACH (entityType IN $entityTypes |
|
|
1126
1145
|
MERGE (et:EntityType {name: entityType})
|
|
1127
1146
|
CREATE (a)-[:TAGGED_AS]->(et)
|
|
1128
1147
|
)
|
|
1129
|
-
RETURN a
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
CREATE (a:Annotation:${motivationLabel} {
|
|
1133
|
-
id: $id,
|
|
1134
|
-
resourceId: $resourceId,
|
|
1135
|
-
exact: $exact,
|
|
1136
|
-
selector: $selector,
|
|
1137
|
-
type: $type,
|
|
1138
|
-
motivation: $motivation,
|
|
1139
|
-
creator: $creator,
|
|
1140
|
-
created: datetime($created)
|
|
1141
|
-
})
|
|
1148
|
+
RETURN a` : `MATCH (d:Resource {id: $targetSource})
|
|
1149
|
+
CREATE (a:Annotation:${motivationLabel})
|
|
1150
|
+
SET a = $props, a.created = datetime($created)
|
|
1142
1151
|
CREATE (a)-[:BELONGS_TO]->(d)
|
|
1143
1152
|
FOREACH (entityType IN $entityTypes |
|
|
1144
1153
|
MERGE (et:EntityType {name: entityType})
|
|
1145
1154
|
CREATE (a)-[:TAGGED_AS]->(et)
|
|
1146
1155
|
)
|
|
1147
1156
|
RETURN a`;
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
id,
|
|
1151
|
-
resourceId: targetSource,
|
|
1152
|
-
// Store full URI
|
|
1153
|
-
fromId: targetSource,
|
|
1154
|
-
// Store full URI
|
|
1155
|
-
toId: bodySource || null,
|
|
1156
|
-
// Store full URI
|
|
1157
|
-
exact: targetSelector ? getExactText2(targetSelector) : "",
|
|
1158
|
-
selector: JSON.stringify(targetSelector || {}),
|
|
1159
|
-
type: "SpecificResource",
|
|
1160
|
-
motivation: annotation.motivation,
|
|
1161
|
-
creator: JSON.stringify(annotation.creator),
|
|
1157
|
+
const result = await session.run(cypher, {
|
|
1158
|
+
props,
|
|
1162
1159
|
created: annotation.created,
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1160
|
+
targetSource,
|
|
1161
|
+
bodySource: bodySource ?? null,
|
|
1162
|
+
entityTypes
|
|
1163
|
+
});
|
|
1167
1164
|
if (result.records.length === 0) {
|
|
1168
1165
|
throw new Error(`Failed to create annotation: Resource ${targetSource} not found in graph database`);
|
|
1169
1166
|
}
|
|
1170
|
-
return
|
|
1167
|
+
return parseAnnotationNode(result.records[0].get("a"), entityTypes);
|
|
1171
1168
|
} finally {
|
|
1172
1169
|
await session.close();
|
|
1173
1170
|
}
|
|
@@ -1187,7 +1184,7 @@ var Neo4jGraphDatabase = class {
|
|
|
1187
1184
|
return null;
|
|
1188
1185
|
}
|
|
1189
1186
|
this.logger?.debug("Annotation found", { id });
|
|
1190
|
-
return
|
|
1187
|
+
return parseAnnotationNode(
|
|
1191
1188
|
result.records[0].get("a"),
|
|
1192
1189
|
result.records[0].get("entityTypes")
|
|
1193
1190
|
);
|
|
@@ -1203,9 +1200,9 @@ var Neo4jGraphDatabase = class {
|
|
|
1203
1200
|
Object.entries(updates).forEach(([key, value]) => {
|
|
1204
1201
|
if (key !== "id" && key !== "updatedAt") {
|
|
1205
1202
|
setClauses.push(`a.${key} = $${key}`);
|
|
1206
|
-
if (key === "
|
|
1203
|
+
if (key === "body") {
|
|
1207
1204
|
params[key] = JSON.stringify(value);
|
|
1208
|
-
} else if (key === "created"
|
|
1205
|
+
} else if (key === "created") {
|
|
1209
1206
|
params[key] = value ? new Date(value).toISOString() : null;
|
|
1210
1207
|
} else {
|
|
1211
1208
|
params[key] = value;
|
|
@@ -1283,7 +1280,7 @@ var Neo4jGraphDatabase = class {
|
|
|
1283
1280
|
} else {
|
|
1284
1281
|
this.logger?.debug("No body update for annotation", { id });
|
|
1285
1282
|
}
|
|
1286
|
-
return
|
|
1283
|
+
return parseAnnotationNode(
|
|
1287
1284
|
result.records[0].get("a"),
|
|
1288
1285
|
result.records[0].get("entityTypes")
|
|
1289
1286
|
);
|
|
@@ -1312,9 +1309,8 @@ var Neo4jGraphDatabase = class {
|
|
|
1312
1309
|
params.resourceId = filter.resourceId;
|
|
1313
1310
|
}
|
|
1314
1311
|
if (filter.type) {
|
|
1315
|
-
const w3cType = filter.type === "highlight" ? "TextualBody" : "SpecificResource";
|
|
1316
1312
|
conditions.push("a.type = $type");
|
|
1317
|
-
params.type =
|
|
1313
|
+
params.type = storedAnnotationType(motivationForCategory(filter.type));
|
|
1318
1314
|
}
|
|
1319
1315
|
const whereClause = conditions.length > 0 ? "WHERE " + conditions.join(" AND ") : "";
|
|
1320
1316
|
const result = await session.run(
|
|
@@ -1324,7 +1320,7 @@ var Neo4jGraphDatabase = class {
|
|
|
1324
1320
|
params
|
|
1325
1321
|
);
|
|
1326
1322
|
const annotations = result.records.map(
|
|
1327
|
-
(record) =>
|
|
1323
|
+
(record) => parseAnnotationNode(record.get("a"), record.get("entityTypes"))
|
|
1328
1324
|
);
|
|
1329
1325
|
return { annotations, total: annotations.length };
|
|
1330
1326
|
} finally {
|
|
@@ -1343,7 +1339,7 @@ var Neo4jGraphDatabase = class {
|
|
|
1343
1339
|
{ resourceId }
|
|
1344
1340
|
);
|
|
1345
1341
|
return result.records.map(
|
|
1346
|
-
(record) =>
|
|
1342
|
+
(record) => parseAnnotationNode(record.get("a"), record.get("entityTypes"))
|
|
1347
1343
|
);
|
|
1348
1344
|
} finally {
|
|
1349
1345
|
await session.close();
|
|
@@ -1371,7 +1367,7 @@ var Neo4jGraphDatabase = class {
|
|
|
1371
1367
|
if (result.records.length === 0) {
|
|
1372
1368
|
throw new Error("Annotation not found");
|
|
1373
1369
|
}
|
|
1374
|
-
return
|
|
1370
|
+
return parseAnnotationNode(
|
|
1375
1371
|
result.records[0].get("a"),
|
|
1376
1372
|
result.records[0].get("entityTypes")
|
|
1377
1373
|
);
|
|
@@ -1391,7 +1387,7 @@ var Neo4jGraphDatabase = class {
|
|
|
1391
1387
|
{ resourceId }
|
|
1392
1388
|
);
|
|
1393
1389
|
return result.records.map(
|
|
1394
|
-
(record) =>
|
|
1390
|
+
(record) => parseAnnotationNode(record.get("a"), record.get("entityTypes"))
|
|
1395
1391
|
);
|
|
1396
1392
|
} finally {
|
|
1397
1393
|
await session.close();
|
|
@@ -1415,7 +1411,7 @@ var Neo4jGraphDatabase = class {
|
|
|
1415
1411
|
ORDER BY a.created DESC`;
|
|
1416
1412
|
const result = await session.run(cypher, params);
|
|
1417
1413
|
return result.records.map(
|
|
1418
|
-
(record) =>
|
|
1414
|
+
(record) => parseAnnotationNode(record.get("a"), record.get("entityTypes"))
|
|
1419
1415
|
);
|
|
1420
1416
|
} finally {
|
|
1421
1417
|
await session.close();
|
|
@@ -1432,7 +1428,7 @@ var Neo4jGraphDatabase = class {
|
|
|
1432
1428
|
{ resourceId }
|
|
1433
1429
|
);
|
|
1434
1430
|
return result.records.map(
|
|
1435
|
-
(record) =>
|
|
1431
|
+
(record) => parseAnnotationNode(record.get("a"), record.get("entityTypes"))
|
|
1436
1432
|
);
|
|
1437
1433
|
} finally {
|
|
1438
1434
|
await session.close();
|
|
@@ -1450,7 +1446,7 @@ var Neo4jGraphDatabase = class {
|
|
|
1450
1446
|
const result = await session.run(cypher, { resourceId });
|
|
1451
1447
|
this.logger?.debug("Found annotations", { count: result.records.length });
|
|
1452
1448
|
return result.records.map(
|
|
1453
|
-
(record) =>
|
|
1449
|
+
(record) => parseAnnotationNode(record.get("a"), record.get("entityTypes"))
|
|
1454
1450
|
);
|
|
1455
1451
|
} finally {
|
|
1456
1452
|
await session.close();
|
|
@@ -1482,7 +1478,7 @@ var Neo4jGraphDatabase = class {
|
|
|
1482
1478
|
{ id: annId }
|
|
1483
1479
|
);
|
|
1484
1480
|
if (annResult.records.length > 0) {
|
|
1485
|
-
outgoing.push(
|
|
1481
|
+
outgoing.push(parseAnnotationNode(
|
|
1486
1482
|
annResult.records[0].get("a"),
|
|
1487
1483
|
annResult.records[0].get("entityTypes")
|
|
1488
1484
|
));
|
|
@@ -1499,7 +1495,7 @@ var Neo4jGraphDatabase = class {
|
|
|
1499
1495
|
{ id: annId }
|
|
1500
1496
|
);
|
|
1501
1497
|
if (annResult.records.length > 0) {
|
|
1502
|
-
incoming.push(
|
|
1498
|
+
incoming.push(parseAnnotationNode(
|
|
1503
1499
|
annResult.records[0].get("a"),
|
|
1504
1500
|
annResult.records[0].get("entityTypes")
|
|
1505
1501
|
));
|
|
@@ -1540,7 +1536,7 @@ var Neo4jGraphDatabase = class {
|
|
|
1540
1536
|
{ ids: annotationIds }
|
|
1541
1537
|
);
|
|
1542
1538
|
selResult.records.forEach((rec) => {
|
|
1543
|
-
annotations.push(
|
|
1539
|
+
annotations.push(parseAnnotationNode(
|
|
1544
1540
|
rec.get("a"),
|
|
1545
1541
|
rec.get("entityTypes")
|
|
1546
1542
|
));
|
|
@@ -1777,62 +1773,39 @@ var Neo4jGraphDatabase = class {
|
|
|
1777
1773
|
if (props.storageUri) resource.storageUri = props.storageUri;
|
|
1778
1774
|
return resource;
|
|
1779
1775
|
}
|
|
1780
|
-
parseAnnotationNode(node, entityTypes = []) {
|
|
1781
|
-
const props = node.properties;
|
|
1782
|
-
if (!props.id) throw new Error("Annotation missing required field: id");
|
|
1783
|
-
if (!props.resourceId) throw new Error(`Annotation ${props.id} missing required field: resourceId`);
|
|
1784
|
-
if (!props.type) throw new Error(`Annotation ${props.id} missing required field: type`);
|
|
1785
|
-
if (!props.selector) throw new Error(`Annotation ${props.id} missing required field: selector`);
|
|
1786
|
-
if (!props.creator) throw new Error(`Annotation ${props.id} missing required field: creator`);
|
|
1787
|
-
if (!props.motivation) throw new Error(`Annotation ${props.id} missing required field: motivation`);
|
|
1788
|
-
const creator = JSON.parse(props.creator);
|
|
1789
|
-
const bodyArray = [];
|
|
1790
|
-
for (const entityType of entityTypes) {
|
|
1791
|
-
if (entityType) {
|
|
1792
|
-
bodyArray.push({
|
|
1793
|
-
type: "TextualBody",
|
|
1794
|
-
value: entityType,
|
|
1795
|
-
purpose: "tagging"
|
|
1796
|
-
});
|
|
1797
|
-
}
|
|
1798
|
-
}
|
|
1799
|
-
if (props.source) {
|
|
1800
|
-
bodyArray.push({
|
|
1801
|
-
type: "SpecificResource",
|
|
1802
|
-
source: props.source,
|
|
1803
|
-
purpose: "linking"
|
|
1804
|
-
});
|
|
1805
|
-
}
|
|
1806
|
-
const annotation = {
|
|
1807
|
-
"@context": "http://www.w3.org/ns/anno.jsonld",
|
|
1808
|
-
"type": "Annotation",
|
|
1809
|
-
id: props.id,
|
|
1810
|
-
motivation: props.motivation,
|
|
1811
|
-
target: {
|
|
1812
|
-
source: props.resourceId,
|
|
1813
|
-
selector: JSON.parse(props.selector)
|
|
1814
|
-
},
|
|
1815
|
-
body: bodyArray,
|
|
1816
|
-
creator,
|
|
1817
|
-
created: props.created
|
|
1818
|
-
// ISO string from DB
|
|
1819
|
-
};
|
|
1820
|
-
if (props.modified) annotation.modified = props.modified.toString();
|
|
1821
|
-
if (props.generator) {
|
|
1822
|
-
try {
|
|
1823
|
-
annotation.generator = JSON.parse(props.generator);
|
|
1824
|
-
} catch (e) {
|
|
1825
|
-
}
|
|
1826
|
-
}
|
|
1827
|
-
return annotation;
|
|
1828
|
-
}
|
|
1829
1776
|
};
|
|
1777
|
+
function parseAnnotationNode(node, entityTypes = []) {
|
|
1778
|
+
return decodeAnnotation(normalizeProperties2(node.properties), entityTypes);
|
|
1779
|
+
}
|
|
1780
|
+
function normalizeProperties2(props) {
|
|
1781
|
+
const normalized = {};
|
|
1782
|
+
for (const [key, value] of Object.entries(props ?? {})) {
|
|
1783
|
+
if (value === null || value === void 0) continue;
|
|
1784
|
+
normalized[key] = typeof value === "string" ? value : String(value);
|
|
1785
|
+
}
|
|
1786
|
+
return normalized;
|
|
1787
|
+
}
|
|
1830
1788
|
|
|
1831
1789
|
// src/implementations/janusgraph.ts
|
|
1832
|
-
import { resourceId as makeResourceId
|
|
1833
|
-
import { getBodySource as getBodySource3, getPrimaryRepresentation as getPrimaryRepresentation3, getResourceId as getResourceId2
|
|
1790
|
+
import { resourceId as makeResourceId } from "@semiont/core";
|
|
1791
|
+
import { getBodySource as getBodySource3, getPrimaryRepresentation as getPrimaryRepresentation3, getResourceId as getResourceId2 } from "@semiont/core";
|
|
1834
1792
|
import { getEntityTypes as getEntityTypes3 } from "@semiont/ontology";
|
|
1835
1793
|
import { v4 as uuidv43 } from "uuid";
|
|
1794
|
+
function getPropertyValue(props, key) {
|
|
1795
|
+
if (!props[key]) return void 0;
|
|
1796
|
+
const prop = Array.isArray(props[key]) ? props[key][0] : props[key];
|
|
1797
|
+
return prop?.value || prop;
|
|
1798
|
+
}
|
|
1799
|
+
function vertexToAnnotation2(vertex, entityTypes = []) {
|
|
1800
|
+
const props = vertex.properties || {};
|
|
1801
|
+
const normalized = {};
|
|
1802
|
+
for (const key of Object.keys(props)) {
|
|
1803
|
+
const value = getPropertyValue(props, key);
|
|
1804
|
+
if (value === void 0 || value === null) continue;
|
|
1805
|
+
normalized[key] = typeof value === "string" ? value : String(value);
|
|
1806
|
+
}
|
|
1807
|
+
return decodeAnnotation(normalized, entityTypes);
|
|
1808
|
+
}
|
|
1836
1809
|
var JanusGraphDatabase = class {
|
|
1837
1810
|
constructor(graphConfig) {
|
|
1838
1811
|
this.graphConfig = graphConfig;
|
|
@@ -1883,10 +1856,10 @@ var JanusGraphDatabase = class {
|
|
|
1883
1856
|
// Helper function to convert vertex to Resource
|
|
1884
1857
|
vertexToResource(vertex) {
|
|
1885
1858
|
const props = vertex.properties || {};
|
|
1886
|
-
const id =
|
|
1887
|
-
const creatorRaw =
|
|
1888
|
-
const contentChecksum =
|
|
1889
|
-
const mediaType =
|
|
1859
|
+
const id = getPropertyValue(props, "id");
|
|
1860
|
+
const creatorRaw = getPropertyValue(props, "creator");
|
|
1861
|
+
const contentChecksum = getPropertyValue(props, "contentChecksum");
|
|
1862
|
+
const mediaType = getPropertyValue(props, "contentType");
|
|
1890
1863
|
if (!creatorRaw) throw new Error(`Resource ${id} missing required field: creator`);
|
|
1891
1864
|
if (!contentChecksum) throw new Error(`Resource ${id} missing required field: contentChecksum`);
|
|
1892
1865
|
if (!mediaType) throw new Error(`Resource ${id} missing required field: contentType`);
|
|
@@ -1894,95 +1867,38 @@ var JanusGraphDatabase = class {
|
|
|
1894
1867
|
const resource = {
|
|
1895
1868
|
"@context": "https://schema.org/",
|
|
1896
1869
|
"@id": id,
|
|
1897
|
-
name:
|
|
1898
|
-
entityTypes: JSON.parse(
|
|
1870
|
+
name: getPropertyValue(props, "name"),
|
|
1871
|
+
entityTypes: JSON.parse(getPropertyValue(props, "entityTypes") || "[]"),
|
|
1899
1872
|
representations: [{
|
|
1900
1873
|
mediaType,
|
|
1901
1874
|
checksum: contentChecksum,
|
|
1902
1875
|
rel: "original"
|
|
1903
1876
|
}],
|
|
1904
|
-
archived:
|
|
1905
|
-
dateCreated:
|
|
1877
|
+
archived: getPropertyValue(props, "archived") === "true",
|
|
1878
|
+
dateCreated: getPropertyValue(props, "created"),
|
|
1906
1879
|
wasAttributedTo: creator
|
|
1907
1880
|
};
|
|
1908
|
-
const sourceAnnotationId =
|
|
1909
|
-
const sourceResourceId =
|
|
1910
|
-
const storageUri =
|
|
1881
|
+
const sourceAnnotationId = getPropertyValue(props, "sourceAnnotationId");
|
|
1882
|
+
const sourceResourceId = getPropertyValue(props, "sourceResourceId");
|
|
1883
|
+
const storageUri = getPropertyValue(props, "storageUri");
|
|
1911
1884
|
if (sourceAnnotationId) resource.sourceAnnotationId = sourceAnnotationId;
|
|
1912
1885
|
if (sourceResourceId) resource.sourceResourceId = sourceResourceId;
|
|
1913
1886
|
if (storageUri) resource.storageUri = storageUri;
|
|
1914
1887
|
return resource;
|
|
1915
1888
|
}
|
|
1916
|
-
// Helper to get property value from Gremlin vertex properties
|
|
1917
|
-
getPropertyValue(props, key) {
|
|
1918
|
-
if (!props[key]) return void 0;
|
|
1919
|
-
const prop = Array.isArray(props[key]) ? props[key][0] : props[key];
|
|
1920
|
-
return prop?.value || prop;
|
|
1921
|
-
}
|
|
1922
1889
|
// Helper method to fetch annotations with their entity types
|
|
1923
1890
|
async fetchAnnotationsWithEntityTypes(annotationVertices) {
|
|
1924
1891
|
const annotations = [];
|
|
1925
1892
|
for (const vertex of annotationVertices) {
|
|
1926
|
-
const id =
|
|
1893
|
+
const id = getPropertyValue(vertex.properties || {}, "id");
|
|
1927
1894
|
const entityTypeVertices = await this.g.V().has("Annotation", "id", id).out("TAGGED_AS").has("EntityType").toList();
|
|
1928
1895
|
const entityTypes = entityTypeVertices.map(
|
|
1929
|
-
(v) =>
|
|
1896
|
+
(v) => getPropertyValue(v.properties || {}, "name")
|
|
1930
1897
|
).filter(Boolean);
|
|
1931
|
-
annotations.push(
|
|
1898
|
+
annotations.push(vertexToAnnotation2(vertex, entityTypes));
|
|
1932
1899
|
}
|
|
1933
1900
|
return annotations;
|
|
1934
1901
|
}
|
|
1935
|
-
// Helper function to convert vertex to Annotation
|
|
1936
|
-
vertexToAnnotation(vertex, entityTypes = []) {
|
|
1937
|
-
const props = vertex.properties || {};
|
|
1938
|
-
const motivation = this.getPropertyValue(props, "motivation") || "linking";
|
|
1939
|
-
const creatorJson = this.getPropertyValue(props, "creator");
|
|
1940
|
-
const creator = JSON.parse(creatorJson);
|
|
1941
|
-
const bodyArray = [];
|
|
1942
|
-
for (const entityType of entityTypes) {
|
|
1943
|
-
if (entityType) {
|
|
1944
|
-
bodyArray.push({
|
|
1945
|
-
type: "TextualBody",
|
|
1946
|
-
value: entityType,
|
|
1947
|
-
purpose: "tagging"
|
|
1948
|
-
});
|
|
1949
|
-
}
|
|
1950
|
-
}
|
|
1951
|
-
const bodySource = this.getPropertyValue(props, "source");
|
|
1952
|
-
if (bodySource) {
|
|
1953
|
-
bodyArray.push({
|
|
1954
|
-
type: "SpecificResource",
|
|
1955
|
-
source: bodySource,
|
|
1956
|
-
purpose: "linking"
|
|
1957
|
-
});
|
|
1958
|
-
}
|
|
1959
|
-
const annotation = {
|
|
1960
|
-
"@context": "http://www.w3.org/ns/anno.jsonld",
|
|
1961
|
-
"type": "Annotation",
|
|
1962
|
-
id: this.getPropertyValue(props, "id"),
|
|
1963
|
-
motivation,
|
|
1964
|
-
target: {
|
|
1965
|
-
source: this.getPropertyValue(props, "resourceId"),
|
|
1966
|
-
selector: JSON.parse(this.getPropertyValue(props, "selector") || "{}")
|
|
1967
|
-
},
|
|
1968
|
-
body: bodyArray,
|
|
1969
|
-
creator,
|
|
1970
|
-
created: this.getPropertyValue(props, "created")
|
|
1971
|
-
// ISO string from DB
|
|
1972
|
-
};
|
|
1973
|
-
const modified = this.getPropertyValue(props, "modified");
|
|
1974
|
-
if (modified) {
|
|
1975
|
-
annotation.modified = modified;
|
|
1976
|
-
}
|
|
1977
|
-
const generatorJson = this.getPropertyValue(props, "generator");
|
|
1978
|
-
if (generatorJson) {
|
|
1979
|
-
try {
|
|
1980
|
-
annotation.generator = JSON.parse(generatorJson);
|
|
1981
|
-
} catch (e) {
|
|
1982
|
-
}
|
|
1983
|
-
}
|
|
1984
|
-
return annotation;
|
|
1985
|
-
}
|
|
1986
1902
|
async createResource(resource) {
|
|
1987
1903
|
const id = getResourceId2(resource);
|
|
1988
1904
|
const primaryRep = getPrimaryRepresentation3(resource);
|
|
@@ -2035,26 +1951,14 @@ var JanusGraphDatabase = class {
|
|
|
2035
1951
|
return queryResources(docs.map((v) => this.vertexToResource(v)), filter);
|
|
2036
1952
|
}
|
|
2037
1953
|
async createAnnotation(input) {
|
|
2038
|
-
const
|
|
2039
|
-
const
|
|
2040
|
-
const
|
|
2041
|
-
|
|
2042
|
-
"type": "Annotation",
|
|
2043
|
-
id: makeAnnotationId3(id),
|
|
2044
|
-
motivation,
|
|
2045
|
-
target: input.target,
|
|
2046
|
-
body: input.body,
|
|
2047
|
-
creator: input.creator,
|
|
2048
|
-
created: (/* @__PURE__ */ new Date()).toISOString()
|
|
2049
|
-
};
|
|
2050
|
-
const bodySource = getBodySource3(input.body);
|
|
1954
|
+
const annotation = buildAnnotation(input, (/* @__PURE__ */ new Date()).toISOString());
|
|
1955
|
+
const props = encodeAnnotation(annotation);
|
|
1956
|
+
const targetSource = props.resourceId;
|
|
1957
|
+
const bodySource = props.source;
|
|
2051
1958
|
const entityTypes = getEntityTypes3(input);
|
|
2052
|
-
|
|
2053
|
-
const
|
|
2054
|
-
|
|
2055
|
-
const vertex = this.g.addV("Annotation").property("id", id).property("resourceId", targetSource).property("text", targetSelector ? getExactText3(targetSelector) : "").property("selector", JSON.stringify(targetSelector || {})).property("type", bodyType).property("motivation", motivation).property("creator", JSON.stringify(input.creator)).property("created", annotation.created);
|
|
2056
|
-
if (bodySource) {
|
|
2057
|
-
vertex.property("source", bodySource);
|
|
1959
|
+
let vertex = this.g.addV("Annotation");
|
|
1960
|
+
for (const [key, value] of Object.entries(props)) {
|
|
1961
|
+
vertex = vertex.property(key, value);
|
|
2058
1962
|
}
|
|
2059
1963
|
const annVertex = await vertex.next();
|
|
2060
1964
|
await this.g.V(annVertex.value).addE("BELONGS_TO").to(this.g.V().has("Resource", "id", targetSource)).next();
|
|
@@ -2071,7 +1975,7 @@ var JanusGraphDatabase = class {
|
|
|
2071
1975
|
}
|
|
2072
1976
|
await this.g.V(annVertex.value).addE("TAGGED_AS").to(this.g.V(etVertex.value)).next();
|
|
2073
1977
|
}
|
|
2074
|
-
this.logger?.info("Created annotation in JanusGraph", { id });
|
|
1978
|
+
this.logger?.info("Created annotation in JanusGraph", { id: annotation.id });
|
|
2075
1979
|
return annotation;
|
|
2076
1980
|
}
|
|
2077
1981
|
async getAnnotation(id) {
|
|
@@ -2081,16 +1985,17 @@ var JanusGraphDatabase = class {
|
|
|
2081
1985
|
}
|
|
2082
1986
|
const entityTypeVertices = await this.g.V().has("Annotation", "id", id).out("TAGGED_AS").has("EntityType").toList();
|
|
2083
1987
|
const entityTypes = entityTypeVertices.map(
|
|
2084
|
-
(v) =>
|
|
1988
|
+
(v) => getPropertyValue(v.properties || {}, "name")
|
|
2085
1989
|
).filter(Boolean);
|
|
2086
|
-
return
|
|
1990
|
+
return vertexToAnnotation2(vertices[0], entityTypes);
|
|
2087
1991
|
}
|
|
2088
1992
|
async updateAnnotation(id, updates) {
|
|
2089
1993
|
const traversalQuery = this.g.V().has("Annotation", "id", id);
|
|
2090
1994
|
if (updates.target !== void 0 && typeof updates.target !== "string") {
|
|
2091
1995
|
if (updates.target.selector !== void 0) {
|
|
2092
|
-
|
|
2093
|
-
|
|
1996
|
+
for (const [key, value] of Object.entries(encodeSelector(updates.target.selector))) {
|
|
1997
|
+
await traversalQuery.property(key, value).next();
|
|
1998
|
+
}
|
|
2094
1999
|
}
|
|
2095
2000
|
}
|
|
2096
2001
|
if (updates.body !== void 0) {
|
|
@@ -2138,8 +2043,7 @@ var JanusGraphDatabase = class {
|
|
|
2138
2043
|
traversalQuery = traversalQuery.has("resourceId", filter.resourceId);
|
|
2139
2044
|
}
|
|
2140
2045
|
if (filter.type) {
|
|
2141
|
-
|
|
2142
|
-
traversalQuery = traversalQuery.has("type", w3cType);
|
|
2046
|
+
traversalQuery = traversalQuery.has("type", storedAnnotationType(motivationForCategory(filter.type)));
|
|
2143
2047
|
}
|
|
2144
2048
|
const vertices = await traversalQuery.toList();
|
|
2145
2049
|
const annotations = await this.fetchAnnotationsWithEntityTypes(vertices);
|
|
@@ -2338,8 +2242,8 @@ var JanusGraphDatabase = class {
|
|
|
2338
2242
|
let entityTypesFromDb = [];
|
|
2339
2243
|
for (const vertex of collections) {
|
|
2340
2244
|
const props = vertex.properties || {};
|
|
2341
|
-
const type =
|
|
2342
|
-
const tagsJson =
|
|
2245
|
+
const type = getPropertyValue(props, "type");
|
|
2246
|
+
const tagsJson = getPropertyValue(props, "tags");
|
|
2343
2247
|
const tags = tagsJson ? JSON.parse(tagsJson) : [];
|
|
2344
2248
|
if (type === "entity-types") {
|
|
2345
2249
|
entityTypesFromDb = tags;
|
|
@@ -2362,9 +2266,10 @@ var JanusGraphDatabase = class {
|
|
|
2362
2266
|
};
|
|
2363
2267
|
|
|
2364
2268
|
// src/implementations/memorygraph.ts
|
|
2365
|
-
import { resourceId as makeResourceId2
|
|
2269
|
+
import { resourceId as makeResourceId2 } from "@semiont/core";
|
|
2366
2270
|
import { v4 as uuidv44 } from "uuid";
|
|
2367
2271
|
import { getBodySource as getBodySource4, getTargetSource as getTargetSource3, getResourceId as getResourceId3, getPrimaryRepresentation as getPrimaryRepresentation4, getResourceEntityTypes as getResourceEntityTypes2 } from "@semiont/core";
|
|
2272
|
+
import { getEntityTypes as getEntityTypes4 } from "@semiont/ontology";
|
|
2368
2273
|
var MemoryGraphDatabase = class {
|
|
2369
2274
|
connected = false;
|
|
2370
2275
|
logger;
|
|
@@ -2417,16 +2322,10 @@ var MemoryGraphDatabase = class {
|
|
|
2417
2322
|
}
|
|
2418
2323
|
async createAnnotation(input) {
|
|
2419
2324
|
const id = input.id;
|
|
2420
|
-
const annotation =
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
motivation: input.motivation,
|
|
2425
|
-
target: input.target,
|
|
2426
|
-
body: input.body,
|
|
2427
|
-
creator: input.creator,
|
|
2428
|
-
created: (/* @__PURE__ */ new Date()).toISOString()
|
|
2429
|
-
};
|
|
2325
|
+
const annotation = decodeAnnotation(
|
|
2326
|
+
encodeAnnotation(buildAnnotation(input, (/* @__PURE__ */ new Date()).toISOString())),
|
|
2327
|
+
getEntityTypes4(input)
|
|
2328
|
+
);
|
|
2430
2329
|
this.annotations.set(id, annotation);
|
|
2431
2330
|
this.logger?.debug("Created annotation", {
|
|
2432
2331
|
id,
|
|
@@ -2492,16 +2391,9 @@ var MemoryGraphDatabase = class {
|
|
|
2492
2391
|
}
|
|
2493
2392
|
async getEntityReferences(resourceId, entityTypes) {
|
|
2494
2393
|
const resourceIdStr = String(resourceId);
|
|
2495
|
-
let refs = Array.from(this.annotations.values()).filter((sel) =>
|
|
2496
|
-
if (getTargetSource3(sel.target) !== resourceIdStr) return false;
|
|
2497
|
-
const bodyEntityTypes = sel.body?.entityTypes;
|
|
2498
|
-
return Array.isArray(bodyEntityTypes) && bodyEntityTypes.length > 0;
|
|
2499
|
-
});
|
|
2394
|
+
let refs = Array.from(this.annotations.values()).filter((sel) => getTargetSource3(sel.target) === resourceIdStr && getEntityTypes4(sel).length > 0);
|
|
2500
2395
|
if (entityTypes && entityTypes.length > 0) {
|
|
2501
|
-
refs = refs.filter((sel) =>
|
|
2502
|
-
const bodyEntityTypes = sel.body?.entityTypes || [];
|
|
2503
|
-
return bodyEntityTypes.some((type) => entityTypes.includes(type));
|
|
2504
|
-
});
|
|
2396
|
+
refs = refs.filter((sel) => getEntityTypes4(sel).some((type) => entityTypes.includes(type)));
|
|
2505
2397
|
}
|
|
2506
2398
|
return refs;
|
|
2507
2399
|
}
|
|
@@ -2591,10 +2483,9 @@ var MemoryGraphDatabase = class {
|
|
|
2591
2483
|
const annotations = Array.from(this.annotations.values());
|
|
2592
2484
|
const highlightCount = annotations.filter((a) => a.motivation === "highlighting").length;
|
|
2593
2485
|
const referenceCount = annotations.filter((a) => a.motivation === "linking").length;
|
|
2594
|
-
const entityReferenceCount = annotations.filter(
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
}).length;
|
|
2486
|
+
const entityReferenceCount = annotations.filter(
|
|
2487
|
+
(a) => a.motivation === "linking" && getEntityTypes4(a).length > 0
|
|
2488
|
+
).length;
|
|
2598
2489
|
return {
|
|
2599
2490
|
resourceCount: this.resources.size,
|
|
2600
2491
|
annotationCount: this.annotations.size,
|