@semiont/api-client 0.2.45 → 0.3.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/README.md +44 -6
- package/dist/index.d.ts +199 -40
- package/dist/index.js +516 -125
- package/dist/index.js.map +1 -1
- package/dist/utils/index.d.ts +6 -40
- package/dist/utils/index.js +7 -50
- package/dist/utils/index.js.map +1 -1
- package/package.json +9 -7
package/dist/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import ky from 'ky';
|
|
2
|
-
import {
|
|
2
|
+
import { merge, firstValueFrom } from 'rxjs';
|
|
3
|
+
import { filter, map, take, timeout } from 'rxjs/operators';
|
|
4
|
+
export { getFragmentSelector, getSvgSelector, getTextPositionSelector, validateSvgMarkup } from '@semiont/core';
|
|
3
5
|
|
|
4
6
|
// src/client.ts
|
|
5
7
|
|
|
@@ -165,17 +167,6 @@ var SSEClient = class {
|
|
|
165
167
|
}
|
|
166
168
|
return headers;
|
|
167
169
|
}
|
|
168
|
-
/**
|
|
169
|
-
* Extract resource ID from URI
|
|
170
|
-
*
|
|
171
|
-
* Handles both full URIs and plain IDs:
|
|
172
|
-
* - 'http://localhost:4000/resources/doc-123' -> 'doc-123'
|
|
173
|
-
* - 'doc-123' -> 'doc-123'
|
|
174
|
-
*/
|
|
175
|
-
extractId(uri) {
|
|
176
|
-
const parts = uri.split("/");
|
|
177
|
-
return parts[parts.length - 1];
|
|
178
|
-
}
|
|
179
170
|
/**
|
|
180
171
|
* Detect annotations in a resource (streaming)
|
|
181
172
|
*
|
|
@@ -212,8 +203,7 @@ var SSEClient = class {
|
|
|
212
203
|
* ```
|
|
213
204
|
*/
|
|
214
205
|
annotateReferences(resourceId, request, options) {
|
|
215
|
-
const
|
|
216
|
-
const url = `${this.baseUrl}/resources/${id}/annotate-references-stream`;
|
|
206
|
+
const url = `${this.baseUrl}/resources/${resourceId}/annotate-references-stream`;
|
|
217
207
|
return createSSEStream(
|
|
218
208
|
url,
|
|
219
209
|
{
|
|
@@ -269,9 +259,7 @@ var SSEClient = class {
|
|
|
269
259
|
* ```
|
|
270
260
|
*/
|
|
271
261
|
yieldResourceFromAnnotation(resourceId, annotationId, request, options) {
|
|
272
|
-
const
|
|
273
|
-
const annId = this.extractId(annotationId);
|
|
274
|
-
const url = `${this.baseUrl}/resources/${resId}/annotations/${annId}/yield-resource-stream`;
|
|
262
|
+
const url = `${this.baseUrl}/resources/${resourceId}/annotations/${annotationId}/yield-resource-stream`;
|
|
275
263
|
return createSSEStream(
|
|
276
264
|
url,
|
|
277
265
|
{
|
|
@@ -325,8 +313,7 @@ var SSEClient = class {
|
|
|
325
313
|
* ```
|
|
326
314
|
*/
|
|
327
315
|
annotateHighlights(resourceId, request = {}, options) {
|
|
328
|
-
const
|
|
329
|
-
const url = `${this.baseUrl}/resources/${id}/annotate-highlights-stream`;
|
|
316
|
+
const url = `${this.baseUrl}/resources/${resourceId}/annotate-highlights-stream`;
|
|
330
317
|
return createSSEStream(
|
|
331
318
|
url,
|
|
332
319
|
{
|
|
@@ -380,8 +367,7 @@ var SSEClient = class {
|
|
|
380
367
|
* ```
|
|
381
368
|
*/
|
|
382
369
|
annotateAssessments(resourceId, request = {}, options) {
|
|
383
|
-
const
|
|
384
|
-
const url = `${this.baseUrl}/resources/${id}/annotate-assessments-stream`;
|
|
370
|
+
const url = `${this.baseUrl}/resources/${resourceId}/annotate-assessments-stream`;
|
|
385
371
|
return createSSEStream(
|
|
386
372
|
url,
|
|
387
373
|
{
|
|
@@ -439,8 +425,7 @@ var SSEClient = class {
|
|
|
439
425
|
* ```
|
|
440
426
|
*/
|
|
441
427
|
annotateComments(resourceId, request = {}, options) {
|
|
442
|
-
const
|
|
443
|
-
const url = `${this.baseUrl}/resources/${id}/annotate-comments-stream`;
|
|
428
|
+
const url = `${this.baseUrl}/resources/${resourceId}/annotate-comments-stream`;
|
|
444
429
|
return createSSEStream(
|
|
445
430
|
url,
|
|
446
431
|
{
|
|
@@ -499,8 +484,7 @@ var SSEClient = class {
|
|
|
499
484
|
* ```
|
|
500
485
|
*/
|
|
501
486
|
annotateTags(resourceId, request, options) {
|
|
502
|
-
const
|
|
503
|
-
const url = `${this.baseUrl}/resources/${id}/annotate-tags-stream`;
|
|
487
|
+
const url = `${this.baseUrl}/resources/${resourceId}/annotate-tags-stream`;
|
|
504
488
|
return createSSEStream(
|
|
505
489
|
url,
|
|
506
490
|
{
|
|
@@ -518,6 +502,35 @@ var SSEClient = class {
|
|
|
518
502
|
this.logger
|
|
519
503
|
);
|
|
520
504
|
}
|
|
505
|
+
/**
|
|
506
|
+
* Search for binding candidates (streaming)
|
|
507
|
+
*
|
|
508
|
+
* Bridges bind:search-requested to the backend Binder actor via SSE.
|
|
509
|
+
* Results emit as bind:search-results on the browser EventBus.
|
|
510
|
+
*
|
|
511
|
+
* @param resourceId - Resource the annotation belongs to
|
|
512
|
+
* @param request - Search configuration (referenceId, context, limit)
|
|
513
|
+
* @param options - Request options (auth token, eventBus)
|
|
514
|
+
* @returns SSE stream controller
|
|
515
|
+
*/
|
|
516
|
+
bindSearch(resourceId, request, options) {
|
|
517
|
+
const url = `${this.baseUrl}/resources/${resourceId}/bind-search-stream`;
|
|
518
|
+
return createSSEStream(
|
|
519
|
+
url,
|
|
520
|
+
{
|
|
521
|
+
method: "POST",
|
|
522
|
+
headers: this.getHeaders(options.auth),
|
|
523
|
+
body: JSON.stringify(request)
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
progressEvents: [],
|
|
527
|
+
completeEvent: "bind:search-results",
|
|
528
|
+
errorEvent: "bind:search-failed",
|
|
529
|
+
eventBus: options.eventBus
|
|
530
|
+
},
|
|
531
|
+
this.logger
|
|
532
|
+
);
|
|
533
|
+
}
|
|
521
534
|
/**
|
|
522
535
|
* Subscribe to resource events (long-lived stream)
|
|
523
536
|
*
|
|
@@ -553,8 +566,7 @@ var SSEClient = class {
|
|
|
553
566
|
* ```
|
|
554
567
|
*/
|
|
555
568
|
resourceEvents(resourceId, options) {
|
|
556
|
-
const
|
|
557
|
-
const url = `${this.baseUrl}/resources/${id}/events/stream`;
|
|
569
|
+
const url = `${this.baseUrl}/resources/${resourceId}/events/stream`;
|
|
558
570
|
const stream = createSSEStream(
|
|
559
571
|
url,
|
|
560
572
|
{
|
|
@@ -580,6 +592,54 @@ var SSEClient = class {
|
|
|
580
592
|
}
|
|
581
593
|
return stream;
|
|
582
594
|
}
|
|
595
|
+
/**
|
|
596
|
+
* Subscribe to global system events (long-lived stream)
|
|
597
|
+
*
|
|
598
|
+
* Opens a long-lived SSE connection to receive system-level domain events
|
|
599
|
+
* (entity type additions, etc.) that are not scoped to a specific resource.
|
|
600
|
+
*
|
|
601
|
+
* @param options - Request options (auth token, eventBus)
|
|
602
|
+
* @returns SSE stream controller
|
|
603
|
+
*
|
|
604
|
+
* @example
|
|
605
|
+
* ```typescript
|
|
606
|
+
* const stream = sseClient.globalEvents({ auth: 'your-token', eventBus });
|
|
607
|
+
*
|
|
608
|
+
* // Events auto-emit to EventBus — subscribe there
|
|
609
|
+
* eventBus.get('make-meaning:event').subscribe((event) => {
|
|
610
|
+
* if (event.type === 'entitytype.added') {
|
|
611
|
+
* // Invalidate entity types query
|
|
612
|
+
* }
|
|
613
|
+
* });
|
|
614
|
+
*
|
|
615
|
+
* // Close when no longer needed
|
|
616
|
+
* stream.close();
|
|
617
|
+
* ```
|
|
618
|
+
*/
|
|
619
|
+
globalEvents(options) {
|
|
620
|
+
const url = `${this.baseUrl}/api/events/stream`;
|
|
621
|
+
const stream = createSSEStream(
|
|
622
|
+
url,
|
|
623
|
+
{
|
|
624
|
+
method: "GET",
|
|
625
|
+
headers: this.getHeaders(options.auth)
|
|
626
|
+
},
|
|
627
|
+
{
|
|
628
|
+
progressEvents: ["*"],
|
|
629
|
+
completeEvent: null,
|
|
630
|
+
errorEvent: null,
|
|
631
|
+
eventBus: options.eventBus
|
|
632
|
+
},
|
|
633
|
+
this.logger
|
|
634
|
+
);
|
|
635
|
+
if (options.onConnected) {
|
|
636
|
+
const sub = options.eventBus.get(SSE_STREAM_CONNECTED).subscribe(() => {
|
|
637
|
+
options.onConnected();
|
|
638
|
+
sub.unsubscribe();
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
return stream;
|
|
642
|
+
}
|
|
583
643
|
};
|
|
584
644
|
|
|
585
645
|
// src/client.ts
|
|
@@ -617,11 +677,11 @@ var SemiontApiClient = class {
|
|
|
617
677
|
*/
|
|
618
678
|
sse;
|
|
619
679
|
constructor(config) {
|
|
620
|
-
const { baseUrl, timeout = 3e4, retry = 2, logger } = config;
|
|
680
|
+
const { baseUrl, timeout: timeout2 = 3e4, retry = 2, logger } = config;
|
|
621
681
|
this.logger = logger;
|
|
622
682
|
this.baseUrl = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
|
|
623
683
|
this.http = ky.create({
|
|
624
|
-
timeout,
|
|
684
|
+
timeout: timeout2,
|
|
625
685
|
retry,
|
|
626
686
|
hooks: {
|
|
627
687
|
beforeRequest: [
|
|
@@ -788,8 +848,8 @@ var SemiontApiClient = class {
|
|
|
788
848
|
auth: options?.auth
|
|
789
849
|
}).json();
|
|
790
850
|
}
|
|
791
|
-
async getResource(
|
|
792
|
-
return this.http.get(
|
|
851
|
+
async getResource(id, options) {
|
|
852
|
+
return this.http.get(`${this.baseUrl}/resources/${id}`, {
|
|
793
853
|
...options,
|
|
794
854
|
auth: options?.auth
|
|
795
855
|
}).json();
|
|
@@ -816,8 +876,8 @@ var SemiontApiClient = class {
|
|
|
816
876
|
* const { data, contentType } = await client.getResourceRepresentation(rUri, { accept: 'application/pdf', auth: token });
|
|
817
877
|
* ```
|
|
818
878
|
*/
|
|
819
|
-
async getResourceRepresentation(
|
|
820
|
-
const response = await this.http.get(
|
|
879
|
+
async getResourceRepresentation(id, options) {
|
|
880
|
+
const response = await this.http.get(`${this.baseUrl}/resources/${id}`, {
|
|
821
881
|
headers: {
|
|
822
882
|
Accept: options?.accept || "text/plain"
|
|
823
883
|
},
|
|
@@ -863,8 +923,8 @@ var SemiontApiClient = class {
|
|
|
863
923
|
* }
|
|
864
924
|
* ```
|
|
865
925
|
*/
|
|
866
|
-
async getResourceRepresentationStream(
|
|
867
|
-
const response = await this.http.get(
|
|
926
|
+
async getResourceRepresentationStream(id, options) {
|
|
927
|
+
const response = await this.http.get(`${this.baseUrl}/resources/${id}`, {
|
|
868
928
|
headers: {
|
|
869
929
|
Accept: options?.accept || "text/plain"
|
|
870
930
|
},
|
|
@@ -887,46 +947,45 @@ var SemiontApiClient = class {
|
|
|
887
947
|
auth: options?.auth
|
|
888
948
|
}).json();
|
|
889
949
|
}
|
|
890
|
-
async updateResource(
|
|
891
|
-
|
|
950
|
+
async updateResource(id, data, options) {
|
|
951
|
+
await this.http.patch(`${this.baseUrl}/resources/${id}`, {
|
|
892
952
|
json: data,
|
|
893
953
|
...options,
|
|
894
954
|
auth: options?.auth
|
|
895
|
-
}).
|
|
955
|
+
}).text();
|
|
896
956
|
}
|
|
897
|
-
async getResourceEvents(
|
|
898
|
-
return this.http.get(`${
|
|
957
|
+
async getResourceEvents(id, options) {
|
|
958
|
+
return this.http.get(`${this.baseUrl}/resources/${id}/events`, {
|
|
899
959
|
...options,
|
|
900
960
|
auth: options?.auth
|
|
901
961
|
}).json();
|
|
902
962
|
}
|
|
903
|
-
async getResourceAnnotations(
|
|
904
|
-
return this.http.get(`${
|
|
963
|
+
async getResourceAnnotations(id, options) {
|
|
964
|
+
return this.http.get(`${this.baseUrl}/resources/${id}/annotations`, {
|
|
905
965
|
...options,
|
|
906
966
|
auth: options?.auth
|
|
907
967
|
}).json();
|
|
908
968
|
}
|
|
909
|
-
async getAnnotationLLMContext(
|
|
969
|
+
async getAnnotationLLMContext(resourceId, annotationId, options) {
|
|
910
970
|
const searchParams = new URLSearchParams();
|
|
911
971
|
if (options?.contextWindow) {
|
|
912
972
|
searchParams.append("contextWindow", options.contextWindow.toString());
|
|
913
973
|
}
|
|
914
974
|
return this.http.get(
|
|
915
|
-
`${
|
|
975
|
+
`${this.baseUrl}/resources/${resourceId}/annotations/${annotationId}/llm-context`,
|
|
916
976
|
{
|
|
917
977
|
searchParams,
|
|
918
978
|
auth: options?.auth
|
|
919
979
|
}
|
|
920
980
|
).json();
|
|
921
981
|
}
|
|
922
|
-
async getResourceReferencedBy(
|
|
923
|
-
return this.http.get(`${
|
|
982
|
+
async getResourceReferencedBy(id, options) {
|
|
983
|
+
return this.http.get(`${this.baseUrl}/resources/${id}/referenced-by`, {
|
|
924
984
|
...options,
|
|
925
985
|
auth: options?.auth
|
|
926
986
|
}).json();
|
|
927
987
|
}
|
|
928
|
-
async generateCloneToken(
|
|
929
|
-
const id = resourceUri2.split("/").pop();
|
|
988
|
+
async generateCloneToken(id, options) {
|
|
930
989
|
return this.http.post(`${this.baseUrl}/resources/${id}/clone-with-token`, {
|
|
931
990
|
...options,
|
|
932
991
|
auth: options?.auth
|
|
@@ -948,69 +1007,70 @@ var SemiontApiClient = class {
|
|
|
948
1007
|
// ============================================================================
|
|
949
1008
|
// ANNOTATIONS
|
|
950
1009
|
// ============================================================================
|
|
951
|
-
async createAnnotation(
|
|
952
|
-
return this.http.post(`${
|
|
1010
|
+
async createAnnotation(id, data, options) {
|
|
1011
|
+
return this.http.post(`${this.baseUrl}/resources/${id}/annotations`, {
|
|
953
1012
|
json: data,
|
|
954
1013
|
...options,
|
|
955
1014
|
auth: options?.auth
|
|
956
1015
|
}).json();
|
|
957
1016
|
}
|
|
958
|
-
async getAnnotation(
|
|
959
|
-
return this.http.get(
|
|
1017
|
+
async getAnnotation(id, options) {
|
|
1018
|
+
return this.http.get(`${this.baseUrl}/annotations/${id}`, {
|
|
960
1019
|
...options,
|
|
961
1020
|
auth: options?.auth
|
|
962
1021
|
}).json();
|
|
963
1022
|
}
|
|
964
|
-
async getResourceAnnotation(
|
|
965
|
-
return this.http.get(
|
|
1023
|
+
async getResourceAnnotation(resourceId, annotationId, options) {
|
|
1024
|
+
return this.http.get(`${this.baseUrl}/resources/${resourceId}/annotations/${annotationId}`, {
|
|
966
1025
|
...options,
|
|
967
1026
|
auth: options?.auth
|
|
968
1027
|
}).json();
|
|
969
1028
|
}
|
|
970
|
-
async listAnnotations(
|
|
1029
|
+
async listAnnotations(id, motivation, options) {
|
|
971
1030
|
const searchParams = new URLSearchParams();
|
|
972
1031
|
if (motivation) searchParams.append("motivation", motivation);
|
|
973
|
-
return this.http.get(`${
|
|
1032
|
+
return this.http.get(`${this.baseUrl}/resources/${id}/annotations`, {
|
|
974
1033
|
searchParams,
|
|
975
1034
|
...options,
|
|
976
1035
|
auth: options?.auth
|
|
977
1036
|
}).json();
|
|
978
1037
|
}
|
|
979
|
-
async deleteAnnotation(
|
|
980
|
-
await this.http.delete(
|
|
1038
|
+
async deleteAnnotation(resourceId, annotationId, options) {
|
|
1039
|
+
await this.http.delete(`${this.baseUrl}/resources/${resourceId}/annotations/${annotationId}`, {
|
|
981
1040
|
...options,
|
|
982
1041
|
auth: options?.auth
|
|
983
1042
|
});
|
|
984
1043
|
}
|
|
985
|
-
async updateAnnotationBody(
|
|
986
|
-
|
|
1044
|
+
async updateAnnotationBody(resourceId, annotationId, data, options) {
|
|
1045
|
+
await this.http.put(`${this.baseUrl}/resources/${resourceId}/annotations/${annotationId}/body`, {
|
|
987
1046
|
json: data,
|
|
988
1047
|
...options,
|
|
989
1048
|
auth: options?.auth
|
|
990
|
-
})
|
|
1049
|
+
});
|
|
991
1050
|
}
|
|
992
|
-
async getAnnotationHistory(
|
|
1051
|
+
async getAnnotationHistory(resourceId, annotationId, options) {
|
|
1052
|
+
const url = `${this.baseUrl}/resources/${resourceId}/annotations/${annotationId}/history`;
|
|
993
1053
|
if (options) {
|
|
994
|
-
return this.http.get(
|
|
1054
|
+
return this.http.get(url, options).json();
|
|
995
1055
|
}
|
|
996
|
-
return this.http.get(
|
|
1056
|
+
return this.http.get(url).json();
|
|
997
1057
|
}
|
|
998
1058
|
// ============================================================================
|
|
999
1059
|
// ENTITY TYPES
|
|
1000
1060
|
// ============================================================================
|
|
1001
1061
|
async addEntityType(type, options) {
|
|
1002
|
-
|
|
1003
|
-
json: { type },
|
|
1062
|
+
await this.http.post(`${this.baseUrl}/api/entity-types`, {
|
|
1063
|
+
json: { tag: type },
|
|
1004
1064
|
...options,
|
|
1005
1065
|
auth: options?.auth
|
|
1006
|
-
})
|
|
1066
|
+
});
|
|
1007
1067
|
}
|
|
1008
1068
|
async addEntityTypesBulk(types, options) {
|
|
1009
|
-
|
|
1069
|
+
await this.http.post(`${this.baseUrl}/api/entity-types/bulk`, {
|
|
1010
1070
|
json: { tags: types },
|
|
1011
1071
|
...options,
|
|
1012
1072
|
auth: options?.auth
|
|
1013
|
-
})
|
|
1073
|
+
});
|
|
1014
1074
|
}
|
|
1015
1075
|
async listEntityTypes(options) {
|
|
1016
1076
|
return this.http.get(`${this.baseUrl}/api/entity-types`, {
|
|
@@ -1051,6 +1111,113 @@ var SemiontApiClient = class {
|
|
|
1051
1111
|
}).json();
|
|
1052
1112
|
}
|
|
1053
1113
|
// ============================================================================
|
|
1114
|
+
// ADMIN — EXCHANGE (Backup/Restore)
|
|
1115
|
+
// ============================================================================
|
|
1116
|
+
/**
|
|
1117
|
+
* Create a backup of the knowledge base. Returns raw Response for streaming download.
|
|
1118
|
+
* Caller should use response.blob() to trigger a file download.
|
|
1119
|
+
*/
|
|
1120
|
+
async backupKnowledgeBase(options) {
|
|
1121
|
+
return fetch(`${this.baseUrl}/api/admin/exchange/backup`, {
|
|
1122
|
+
method: "POST",
|
|
1123
|
+
headers: {
|
|
1124
|
+
"Content-Type": "application/json",
|
|
1125
|
+
...options?.auth ? { Authorization: `Bearer ${options.auth}` } : {}
|
|
1126
|
+
}
|
|
1127
|
+
});
|
|
1128
|
+
}
|
|
1129
|
+
/**
|
|
1130
|
+
* Restore knowledge base from a backup file. Parses SSE progress events and calls onProgress.
|
|
1131
|
+
* Returns the final SSE event (phase: 'complete' or 'error').
|
|
1132
|
+
*/
|
|
1133
|
+
async restoreKnowledgeBase(file, options) {
|
|
1134
|
+
const formData = new FormData();
|
|
1135
|
+
formData.append("file", file);
|
|
1136
|
+
const response = await fetch(`${this.baseUrl}/api/admin/exchange/restore`, {
|
|
1137
|
+
method: "POST",
|
|
1138
|
+
headers: {
|
|
1139
|
+
...options?.auth ? { Authorization: `Bearer ${options.auth}` } : {}
|
|
1140
|
+
},
|
|
1141
|
+
body: formData
|
|
1142
|
+
});
|
|
1143
|
+
if (!response.ok) {
|
|
1144
|
+
throw new Error(`Restore failed: ${response.status} ${response.statusText}`);
|
|
1145
|
+
}
|
|
1146
|
+
const reader = response.body.getReader();
|
|
1147
|
+
const decoder = new TextDecoder();
|
|
1148
|
+
let buffer = "";
|
|
1149
|
+
let finalResult = { phase: "unknown" };
|
|
1150
|
+
while (true) {
|
|
1151
|
+
const { done, value } = await reader.read();
|
|
1152
|
+
if (done) break;
|
|
1153
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1154
|
+
const lines = buffer.split("\n");
|
|
1155
|
+
buffer = lines.pop();
|
|
1156
|
+
for (const line of lines) {
|
|
1157
|
+
if (line.startsWith("data: ")) {
|
|
1158
|
+
const event = JSON.parse(line.slice(6));
|
|
1159
|
+
options?.onProgress?.(event);
|
|
1160
|
+
finalResult = event;
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
return finalResult;
|
|
1165
|
+
}
|
|
1166
|
+
// ============================================================================
|
|
1167
|
+
// ADMIN — EXCHANGE (Linked Data Export/Import)
|
|
1168
|
+
// ============================================================================
|
|
1169
|
+
/**
|
|
1170
|
+
* Export the knowledge base as a JSON-LD Linked Data archive. Returns raw Response for streaming download.
|
|
1171
|
+
* Caller should use response.blob() to trigger a file download.
|
|
1172
|
+
*/
|
|
1173
|
+
async exportKnowledgeBase(params, options) {
|
|
1174
|
+
const query = params?.includeArchived ? "?includeArchived=true" : "";
|
|
1175
|
+
return fetch(`${this.baseUrl}/api/moderate/exchange/export${query}`, {
|
|
1176
|
+
method: "POST",
|
|
1177
|
+
headers: {
|
|
1178
|
+
"Content-Type": "application/json",
|
|
1179
|
+
...options?.auth ? { Authorization: `Bearer ${options.auth}` } : {}
|
|
1180
|
+
}
|
|
1181
|
+
});
|
|
1182
|
+
}
|
|
1183
|
+
/**
|
|
1184
|
+
* Import a JSON-LD Linked Data archive into the knowledge base. Parses SSE progress events and calls onProgress.
|
|
1185
|
+
* Returns the final SSE event (phase: 'complete' or 'error').
|
|
1186
|
+
*/
|
|
1187
|
+
async importKnowledgeBase(file, options) {
|
|
1188
|
+
const formData = new FormData();
|
|
1189
|
+
formData.append("file", file);
|
|
1190
|
+
const response = await fetch(`${this.baseUrl}/api/moderate/exchange/import`, {
|
|
1191
|
+
method: "POST",
|
|
1192
|
+
headers: {
|
|
1193
|
+
...options?.auth ? { Authorization: `Bearer ${options.auth}` } : {}
|
|
1194
|
+
},
|
|
1195
|
+
body: formData
|
|
1196
|
+
});
|
|
1197
|
+
if (!response.ok) {
|
|
1198
|
+
throw new Error(`Import failed: ${response.status} ${response.statusText}`);
|
|
1199
|
+
}
|
|
1200
|
+
const reader = response.body.getReader();
|
|
1201
|
+
const decoder = new TextDecoder();
|
|
1202
|
+
let buffer = "";
|
|
1203
|
+
let finalResult = { phase: "unknown" };
|
|
1204
|
+
while (true) {
|
|
1205
|
+
const { done, value } = await reader.read();
|
|
1206
|
+
if (done) break;
|
|
1207
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1208
|
+
const lines = buffer.split("\n");
|
|
1209
|
+
buffer = lines.pop();
|
|
1210
|
+
for (const line of lines) {
|
|
1211
|
+
if (line.startsWith("data: ")) {
|
|
1212
|
+
const event = JSON.parse(line.slice(6));
|
|
1213
|
+
options?.onProgress?.(event);
|
|
1214
|
+
finalResult = event;
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
return finalResult;
|
|
1219
|
+
}
|
|
1220
|
+
// ============================================================================
|
|
1054
1221
|
// JOB STATUS
|
|
1055
1222
|
// ============================================================================
|
|
1056
1223
|
async getJobStatus(id, options) {
|
|
@@ -1067,7 +1234,7 @@ var SemiontApiClient = class {
|
|
|
1067
1234
|
*/
|
|
1068
1235
|
async pollJobUntilComplete(id, options) {
|
|
1069
1236
|
const interval = options?.interval ?? 1e3;
|
|
1070
|
-
const
|
|
1237
|
+
const timeout2 = options?.timeout ?? 6e4;
|
|
1071
1238
|
const startTime = Date.now();
|
|
1072
1239
|
while (true) {
|
|
1073
1240
|
const status = await this.getJobStatus(id, { auth: options?.auth });
|
|
@@ -1077,8 +1244,8 @@ var SemiontApiClient = class {
|
|
|
1077
1244
|
if (status.status === "complete" || status.status === "failed" || status.status === "cancelled") {
|
|
1078
1245
|
return status;
|
|
1079
1246
|
}
|
|
1080
|
-
if (Date.now() - startTime >
|
|
1081
|
-
throw new Error(`Job polling timeout after ${
|
|
1247
|
+
if (Date.now() - startTime > timeout2) {
|
|
1248
|
+
throw new Error(`Job polling timeout after ${timeout2}ms`);
|
|
1082
1249
|
}
|
|
1083
1250
|
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
1084
1251
|
}
|
|
@@ -1086,13 +1253,13 @@ var SemiontApiClient = class {
|
|
|
1086
1253
|
// ============================================================================
|
|
1087
1254
|
// LLM CONTEXT
|
|
1088
1255
|
// ============================================================================
|
|
1089
|
-
async getResourceLLMContext(
|
|
1256
|
+
async getResourceLLMContext(id, options) {
|
|
1090
1257
|
const searchParams = new URLSearchParams();
|
|
1091
1258
|
if (options?.depth !== void 0) searchParams.append("depth", options.depth.toString());
|
|
1092
1259
|
if (options?.maxResources !== void 0) searchParams.append("maxResources", options.maxResources.toString());
|
|
1093
1260
|
if (options?.includeContent !== void 0) searchParams.append("includeContent", options.includeContent.toString());
|
|
1094
1261
|
if (options?.includeSummary !== void 0) searchParams.append("includeSummary", options.includeSummary.toString());
|
|
1095
|
-
return this.http.get(`${
|
|
1262
|
+
return this.http.get(`${this.baseUrl}/resources/${id}/llm-context`, {
|
|
1096
1263
|
searchParams,
|
|
1097
1264
|
auth: options?.auth
|
|
1098
1265
|
}).json();
|
|
@@ -1113,6 +1280,273 @@ var SemiontApiClient = class {
|
|
|
1113
1280
|
return this.http.get(`${this.baseUrl}/api/status`).json();
|
|
1114
1281
|
}
|
|
1115
1282
|
};
|
|
1283
|
+
async function eventBusRequest(eventBus, requestEvent, payload, successEvent, failureEvent, timeoutMs = 3e4) {
|
|
1284
|
+
const correlationId = payload.correlationId;
|
|
1285
|
+
const result$ = merge(
|
|
1286
|
+
eventBus.get(successEvent).pipe(
|
|
1287
|
+
filter((e) => e.correlationId === correlationId),
|
|
1288
|
+
map((e) => ({ ok: true, response: e.response }))
|
|
1289
|
+
),
|
|
1290
|
+
eventBus.get(failureEvent).pipe(
|
|
1291
|
+
filter((e) => e.correlationId === correlationId),
|
|
1292
|
+
map((e) => ({ ok: false, error: e.error }))
|
|
1293
|
+
)
|
|
1294
|
+
).pipe(take(1), timeout(timeoutMs));
|
|
1295
|
+
const resultPromise = firstValueFrom(result$);
|
|
1296
|
+
eventBus.get(requestEvent).next(payload);
|
|
1297
|
+
const result = await resultPromise;
|
|
1298
|
+
if (!result.ok) {
|
|
1299
|
+
throw result.error;
|
|
1300
|
+
}
|
|
1301
|
+
return result.response;
|
|
1302
|
+
}
|
|
1303
|
+
var EventBusClient = class {
|
|
1304
|
+
constructor(eventBus, timeoutMs = 3e4) {
|
|
1305
|
+
this.eventBus = eventBus;
|
|
1306
|
+
this.timeoutMs = timeoutMs;
|
|
1307
|
+
}
|
|
1308
|
+
// ========================================================================
|
|
1309
|
+
// Browse Flow — Resource reads
|
|
1310
|
+
// ========================================================================
|
|
1311
|
+
async getResource(resourceId) {
|
|
1312
|
+
return eventBusRequest(
|
|
1313
|
+
this.eventBus,
|
|
1314
|
+
"browse:resource-requested",
|
|
1315
|
+
{ correlationId: crypto.randomUUID(), resourceId },
|
|
1316
|
+
"browse:resource-result",
|
|
1317
|
+
"browse:resource-failed",
|
|
1318
|
+
this.timeoutMs
|
|
1319
|
+
);
|
|
1320
|
+
}
|
|
1321
|
+
async listResources(options) {
|
|
1322
|
+
return eventBusRequest(
|
|
1323
|
+
this.eventBus,
|
|
1324
|
+
"browse:resources-requested",
|
|
1325
|
+
{ correlationId: crypto.randomUUID(), ...options },
|
|
1326
|
+
"browse:resources-result",
|
|
1327
|
+
"browse:resources-failed",
|
|
1328
|
+
this.timeoutMs
|
|
1329
|
+
);
|
|
1330
|
+
}
|
|
1331
|
+
// ========================================================================
|
|
1332
|
+
// Browse Flow — Annotation reads
|
|
1333
|
+
// ========================================================================
|
|
1334
|
+
async getAnnotations(resourceId) {
|
|
1335
|
+
return eventBusRequest(
|
|
1336
|
+
this.eventBus,
|
|
1337
|
+
"browse:annotations-requested",
|
|
1338
|
+
{ correlationId: crypto.randomUUID(), resourceId },
|
|
1339
|
+
"browse:annotations-result",
|
|
1340
|
+
"browse:annotations-failed",
|
|
1341
|
+
this.timeoutMs
|
|
1342
|
+
);
|
|
1343
|
+
}
|
|
1344
|
+
async getAnnotation(resourceId, annotationId) {
|
|
1345
|
+
return eventBusRequest(
|
|
1346
|
+
this.eventBus,
|
|
1347
|
+
"browse:annotation-requested",
|
|
1348
|
+
{ correlationId: crypto.randomUUID(), resourceId, annotationId },
|
|
1349
|
+
"browse:annotation-result",
|
|
1350
|
+
"browse:annotation-failed",
|
|
1351
|
+
this.timeoutMs
|
|
1352
|
+
);
|
|
1353
|
+
}
|
|
1354
|
+
// ========================================================================
|
|
1355
|
+
// Browse Flow — Event history
|
|
1356
|
+
// ========================================================================
|
|
1357
|
+
async getEvents(resourceId, options) {
|
|
1358
|
+
return eventBusRequest(
|
|
1359
|
+
this.eventBus,
|
|
1360
|
+
"browse:events-requested",
|
|
1361
|
+
{ correlationId: crypto.randomUUID(), resourceId, ...options },
|
|
1362
|
+
"browse:events-result",
|
|
1363
|
+
"browse:events-failed",
|
|
1364
|
+
this.timeoutMs
|
|
1365
|
+
);
|
|
1366
|
+
}
|
|
1367
|
+
async getAnnotationHistory(resourceId, annotationId) {
|
|
1368
|
+
return eventBusRequest(
|
|
1369
|
+
this.eventBus,
|
|
1370
|
+
"browse:annotation-history-requested",
|
|
1371
|
+
{ correlationId: crypto.randomUUID(), resourceId, annotationId },
|
|
1372
|
+
"browse:annotation-history-result",
|
|
1373
|
+
"browse:annotation-history-failed",
|
|
1374
|
+
this.timeoutMs
|
|
1375
|
+
);
|
|
1376
|
+
}
|
|
1377
|
+
// ========================================================================
|
|
1378
|
+
// Bind Flow — Graph queries
|
|
1379
|
+
// ========================================================================
|
|
1380
|
+
async getReferencedBy(resourceId, motivation) {
|
|
1381
|
+
return eventBusRequest(
|
|
1382
|
+
this.eventBus,
|
|
1383
|
+
"bind:referenced-by-requested",
|
|
1384
|
+
{ correlationId: crypto.randomUUID(), resourceId, motivation },
|
|
1385
|
+
"bind:referenced-by-result",
|
|
1386
|
+
"bind:referenced-by-failed",
|
|
1387
|
+
this.timeoutMs
|
|
1388
|
+
);
|
|
1389
|
+
}
|
|
1390
|
+
// ========================================================================
|
|
1391
|
+
// Mark Flow — Entity types
|
|
1392
|
+
// ========================================================================
|
|
1393
|
+
async listEntityTypes() {
|
|
1394
|
+
return eventBusRequest(
|
|
1395
|
+
this.eventBus,
|
|
1396
|
+
"mark:entity-types-requested",
|
|
1397
|
+
{ correlationId: crypto.randomUUID() },
|
|
1398
|
+
"mark:entity-types-result",
|
|
1399
|
+
"mark:entity-types-failed",
|
|
1400
|
+
this.timeoutMs
|
|
1401
|
+
);
|
|
1402
|
+
}
|
|
1403
|
+
addEntityType(tag, userId) {
|
|
1404
|
+
this.eventBus.get("mark:add-entity-type").next({ tag, userId });
|
|
1405
|
+
}
|
|
1406
|
+
// ========================================================================
|
|
1407
|
+
// Yield Flow — Clone tokens
|
|
1408
|
+
// ========================================================================
|
|
1409
|
+
async generateCloneToken(resourceId) {
|
|
1410
|
+
return eventBusRequest(
|
|
1411
|
+
this.eventBus,
|
|
1412
|
+
"yield:clone-token-requested",
|
|
1413
|
+
{ correlationId: crypto.randomUUID(), resourceId },
|
|
1414
|
+
"yield:clone-token-generated",
|
|
1415
|
+
"yield:clone-token-failed",
|
|
1416
|
+
this.timeoutMs
|
|
1417
|
+
);
|
|
1418
|
+
}
|
|
1419
|
+
async getResourceByToken(token) {
|
|
1420
|
+
return eventBusRequest(
|
|
1421
|
+
this.eventBus,
|
|
1422
|
+
"yield:clone-resource-requested",
|
|
1423
|
+
{ correlationId: crypto.randomUUID(), token },
|
|
1424
|
+
"yield:clone-resource-result",
|
|
1425
|
+
"yield:clone-resource-failed",
|
|
1426
|
+
this.timeoutMs
|
|
1427
|
+
);
|
|
1428
|
+
}
|
|
1429
|
+
async createResourceFromToken(options) {
|
|
1430
|
+
return eventBusRequest(
|
|
1431
|
+
this.eventBus,
|
|
1432
|
+
"yield:clone-create",
|
|
1433
|
+
{ correlationId: crypto.randomUUID(), ...options },
|
|
1434
|
+
"yield:clone-created",
|
|
1435
|
+
"yield:clone-create-failed",
|
|
1436
|
+
this.timeoutMs
|
|
1437
|
+
);
|
|
1438
|
+
}
|
|
1439
|
+
// ========================================================================
|
|
1440
|
+
// Job Control
|
|
1441
|
+
// ========================================================================
|
|
1442
|
+
async getJobStatus(jobId) {
|
|
1443
|
+
return eventBusRequest(
|
|
1444
|
+
this.eventBus,
|
|
1445
|
+
"job:status-requested",
|
|
1446
|
+
{ correlationId: crypto.randomUUID(), jobId },
|
|
1447
|
+
"job:status-result",
|
|
1448
|
+
"job:status-failed",
|
|
1449
|
+
this.timeoutMs
|
|
1450
|
+
);
|
|
1451
|
+
}
|
|
1452
|
+
// ========================================================================
|
|
1453
|
+
// Gather Flow — LLM context
|
|
1454
|
+
// ========================================================================
|
|
1455
|
+
async getAnnotationLLMContext(annotationId, resourceId, options) {
|
|
1456
|
+
const correlationId = crypto.randomUUID();
|
|
1457
|
+
const result$ = merge(
|
|
1458
|
+
this.eventBus.get("gather:complete").pipe(
|
|
1459
|
+
filter((e) => e.correlationId === correlationId),
|
|
1460
|
+
map((e) => ({ ok: true, response: e.response }))
|
|
1461
|
+
),
|
|
1462
|
+
this.eventBus.get("gather:failed").pipe(
|
|
1463
|
+
filter((e) => e.correlationId === correlationId),
|
|
1464
|
+
map((e) => ({ ok: false, error: e.error }))
|
|
1465
|
+
)
|
|
1466
|
+
).pipe(take(1), timeout(this.timeoutMs));
|
|
1467
|
+
const resultPromise = firstValueFrom(result$);
|
|
1468
|
+
this.eventBus.get("gather:requested").next({
|
|
1469
|
+
correlationId,
|
|
1470
|
+
annotationId,
|
|
1471
|
+
resourceId,
|
|
1472
|
+
options
|
|
1473
|
+
});
|
|
1474
|
+
const result = await resultPromise;
|
|
1475
|
+
if (!result.ok) {
|
|
1476
|
+
throw result.error;
|
|
1477
|
+
}
|
|
1478
|
+
return result.response;
|
|
1479
|
+
}
|
|
1480
|
+
async getResourceLLMContext(resourceId, options) {
|
|
1481
|
+
const correlationId = crypto.randomUUID();
|
|
1482
|
+
const result$ = merge(
|
|
1483
|
+
this.eventBus.get("gather:resource-complete").pipe(
|
|
1484
|
+
filter((e) => e.correlationId === correlationId),
|
|
1485
|
+
map((e) => ({ ok: true, response: e.context }))
|
|
1486
|
+
),
|
|
1487
|
+
this.eventBus.get("gather:resource-failed").pipe(
|
|
1488
|
+
filter((e) => e.correlationId === correlationId),
|
|
1489
|
+
map((e) => ({ ok: false, error: e.error }))
|
|
1490
|
+
)
|
|
1491
|
+
).pipe(take(1), timeout(this.timeoutMs));
|
|
1492
|
+
const resultPromise = firstValueFrom(result$);
|
|
1493
|
+
this.eventBus.get("gather:resource-requested").next({
|
|
1494
|
+
correlationId,
|
|
1495
|
+
resourceId,
|
|
1496
|
+
options
|
|
1497
|
+
});
|
|
1498
|
+
const result = await resultPromise;
|
|
1499
|
+
if (!result.ok) {
|
|
1500
|
+
throw result.error;
|
|
1501
|
+
}
|
|
1502
|
+
return result.response;
|
|
1503
|
+
}
|
|
1504
|
+
// ========================================================================
|
|
1505
|
+
// Bind Flow — Search
|
|
1506
|
+
// ========================================================================
|
|
1507
|
+
async searchResources(searchTerm) {
|
|
1508
|
+
const correlationId = crypto.randomUUID();
|
|
1509
|
+
const referenceId = correlationId;
|
|
1510
|
+
const result$ = merge(
|
|
1511
|
+
this.eventBus.get("bind:search-results").pipe(
|
|
1512
|
+
filter((e) => e.correlationId === correlationId),
|
|
1513
|
+
map((e) => ({ ok: true, results: e.results }))
|
|
1514
|
+
),
|
|
1515
|
+
this.eventBus.get("bind:search-failed").pipe(
|
|
1516
|
+
filter((e) => e.correlationId === correlationId),
|
|
1517
|
+
map((e) => ({ ok: false, error: e.error }))
|
|
1518
|
+
)
|
|
1519
|
+
).pipe(take(1), timeout(this.timeoutMs));
|
|
1520
|
+
const resultPromise = firstValueFrom(result$);
|
|
1521
|
+
this.eventBus.get("bind:search-requested").next({
|
|
1522
|
+
correlationId,
|
|
1523
|
+
referenceId,
|
|
1524
|
+
context: {
|
|
1525
|
+
annotation: {
|
|
1526
|
+
"@context": "http://www.w3.org/ns/anno.jsonld",
|
|
1527
|
+
type: "Annotation",
|
|
1528
|
+
id: referenceId,
|
|
1529
|
+
motivation: "linking",
|
|
1530
|
+
target: referenceId,
|
|
1531
|
+
body: []
|
|
1532
|
+
},
|
|
1533
|
+
sourceResource: {
|
|
1534
|
+
"@context": "https://schema.org",
|
|
1535
|
+
"@id": referenceId,
|
|
1536
|
+
name: searchTerm,
|
|
1537
|
+
format: "text/plain",
|
|
1538
|
+
representations: []
|
|
1539
|
+
},
|
|
1540
|
+
sourceContext: { selected: searchTerm }
|
|
1541
|
+
}
|
|
1542
|
+
});
|
|
1543
|
+
const result = await resultPromise;
|
|
1544
|
+
if (!result.ok) {
|
|
1545
|
+
throw result.error;
|
|
1546
|
+
}
|
|
1547
|
+
return result.results;
|
|
1548
|
+
}
|
|
1549
|
+
};
|
|
1116
1550
|
function getBodySource(body) {
|
|
1117
1551
|
if (Array.isArray(body)) {
|
|
1118
1552
|
for (const item of body) {
|
|
@@ -1120,7 +1554,7 @@ function getBodySource(body) {
|
|
|
1120
1554
|
const itemType = item.type;
|
|
1121
1555
|
const itemSource = item.source;
|
|
1122
1556
|
if (itemType === "SpecificResource" && typeof itemSource === "string") {
|
|
1123
|
-
return
|
|
1557
|
+
return itemSource;
|
|
1124
1558
|
}
|
|
1125
1559
|
}
|
|
1126
1560
|
}
|
|
@@ -1130,7 +1564,7 @@ function getBodySource(body) {
|
|
|
1130
1564
|
const bodyType = body.type;
|
|
1131
1565
|
const bodySource = body.source;
|
|
1132
1566
|
if (bodyType === "SpecificResource" && typeof bodySource === "string") {
|
|
1133
|
-
return
|
|
1567
|
+
return bodySource;
|
|
1134
1568
|
}
|
|
1135
1569
|
}
|
|
1136
1570
|
return null;
|
|
@@ -1161,9 +1595,9 @@ function isBodyResolved(body) {
|
|
|
1161
1595
|
}
|
|
1162
1596
|
function getTargetSource(target) {
|
|
1163
1597
|
if (typeof target === "string") {
|
|
1164
|
-
return
|
|
1598
|
+
return target;
|
|
1165
1599
|
}
|
|
1166
|
-
return
|
|
1600
|
+
return target.source;
|
|
1167
1601
|
}
|
|
1168
1602
|
function getTargetSelector(target) {
|
|
1169
1603
|
if (typeof target === "string") {
|
|
@@ -1231,49 +1665,12 @@ function getPrimarySelector(selector) {
|
|
|
1231
1665
|
}
|
|
1232
1666
|
return selector;
|
|
1233
1667
|
}
|
|
1234
|
-
function getTextPositionSelector(selector) {
|
|
1235
|
-
if (!selector) return null;
|
|
1236
|
-
const selectors = Array.isArray(selector) ? selector : [selector];
|
|
1237
|
-
const found = selectors.find((s) => s.type === "TextPositionSelector");
|
|
1238
|
-
if (!found) return null;
|
|
1239
|
-
return found.type === "TextPositionSelector" ? found : null;
|
|
1240
|
-
}
|
|
1241
1668
|
function getTextQuoteSelector(selector) {
|
|
1242
1669
|
const selectors = Array.isArray(selector) ? selector : [selector];
|
|
1243
1670
|
const found = selectors.find((s) => s.type === "TextQuoteSelector");
|
|
1244
1671
|
if (!found) return null;
|
|
1245
1672
|
return found.type === "TextQuoteSelector" ? found : null;
|
|
1246
1673
|
}
|
|
1247
|
-
function getSvgSelector(selector) {
|
|
1248
|
-
if (!selector) return null;
|
|
1249
|
-
const selectors = Array.isArray(selector) ? selector : [selector];
|
|
1250
|
-
const found = selectors.find((s) => s.type === "SvgSelector");
|
|
1251
|
-
if (!found) return null;
|
|
1252
|
-
return found.type === "SvgSelector" ? found : null;
|
|
1253
|
-
}
|
|
1254
|
-
function getFragmentSelector(selector) {
|
|
1255
|
-
if (!selector) return null;
|
|
1256
|
-
const selectors = Array.isArray(selector) ? selector : [selector];
|
|
1257
|
-
const found = selectors.find((s) => s.type === "FragmentSelector");
|
|
1258
|
-
if (!found) return null;
|
|
1259
|
-
return found.type === "FragmentSelector" ? found : null;
|
|
1260
|
-
}
|
|
1261
|
-
function validateSvgMarkup(svg) {
|
|
1262
|
-
if (!svg.includes('xmlns="http://www.w3.org/2000/svg"')) {
|
|
1263
|
-
return 'SVG must include xmlns="http://www.w3.org/2000/svg" attribute';
|
|
1264
|
-
}
|
|
1265
|
-
if (!svg.includes("<svg") || !svg.includes("</svg>")) {
|
|
1266
|
-
return "SVG must have opening and closing tags";
|
|
1267
|
-
}
|
|
1268
|
-
const shapeElements = ["rect", "circle", "ellipse", "polygon", "polyline", "path", "line"];
|
|
1269
|
-
const hasShape = shapeElements.some(
|
|
1270
|
-
(shape) => svg.includes(`<${shape}`) || svg.includes(`<${shape} `)
|
|
1271
|
-
);
|
|
1272
|
-
if (!hasShape) {
|
|
1273
|
-
return "SVG must contain at least one shape element (rect, circle, ellipse, polygon, polyline, path, or line)";
|
|
1274
|
-
}
|
|
1275
|
-
return null;
|
|
1276
|
-
}
|
|
1277
1674
|
function extractBoundingBox(svg) {
|
|
1278
1675
|
const viewBoxMatch = svg.match(/<svg[^>]*viewBox="([^"]+)"/);
|
|
1279
1676
|
if (viewBoxMatch) {
|
|
@@ -1507,13 +1904,7 @@ function getAllLocaleCodes() {
|
|
|
1507
1904
|
// src/utils/resources.ts
|
|
1508
1905
|
function getResourceId(resource) {
|
|
1509
1906
|
if (!resource) return void 0;
|
|
1510
|
-
|
|
1511
|
-
if (fullId.includes("/resources/")) {
|
|
1512
|
-
const parts = fullId.split("/resources/");
|
|
1513
|
-
const lastPart = parts[parts.length - 1];
|
|
1514
|
-
return lastPart || void 0;
|
|
1515
|
-
}
|
|
1516
|
-
return void 0;
|
|
1907
|
+
return resource["@id"] || void 0;
|
|
1517
1908
|
}
|
|
1518
1909
|
function getPrimaryRepresentation(resource) {
|
|
1519
1910
|
if (!resource?.representations) return void 0;
|
|
@@ -1798,14 +2189,14 @@ function isValidEmail(email) {
|
|
|
1798
2189
|
|
|
1799
2190
|
// src/mime-utils.ts
|
|
1800
2191
|
function getExtensionForMimeType(mimeType) {
|
|
1801
|
-
const
|
|
2192
|
+
const map2 = {
|
|
1802
2193
|
"text/plain": "txt",
|
|
1803
2194
|
"text/markdown": "md",
|
|
1804
2195
|
"image/png": "png",
|
|
1805
2196
|
"image/jpeg": "jpg",
|
|
1806
2197
|
"application/pdf": "pdf"
|
|
1807
2198
|
};
|
|
1808
|
-
return
|
|
2199
|
+
return map2[mimeType] || "dat";
|
|
1809
2200
|
}
|
|
1810
2201
|
function isImageMimeType(mimeType) {
|
|
1811
2202
|
return mimeType === "image/png" || mimeType === "image/jpeg";
|
|
@@ -1826,6 +2217,6 @@ function getMimeCategory(mimeType) {
|
|
|
1826
2217
|
return "unsupported";
|
|
1827
2218
|
}
|
|
1828
2219
|
|
|
1829
|
-
export { APIError, JWTTokenSchema, LOCALES, SSEClient, SSE_STREAM_CONNECTED, SemiontApiClient, buildContentCache, createCircleSvg, createPolygonSvg, createRectangleSvg, decodeRepresentation, decodeWithCharset, extractBoundingBox, extractCharset, extractContext, findBestTextMatch, findTextWithContext, formatLocaleDisplay, getAllLocaleCodes, getAnnotationExactText, getBodySource, getBodyType, getChecksum, getCommentText, getCreator, getDerivedFrom, getExactText, getExtensionForMimeType,
|
|
2220
|
+
export { APIError, EventBusClient, JWTTokenSchema, LOCALES, SSEClient, SSE_STREAM_CONNECTED, SemiontApiClient, buildContentCache, createCircleSvg, createPolygonSvg, createRectangleSvg, decodeRepresentation, decodeWithCharset, extractBoundingBox, extractCharset, extractContext, findBestTextMatch, findTextWithContext, formatLocaleDisplay, getAllLocaleCodes, getAnnotationExactText, getBodySource, getBodyType, getChecksum, getCommentText, getCreator, getDerivedFrom, getExactText, getExtensionForMimeType, getLanguage, getLocaleEnglishName, getLocaleInfo, getLocaleNativeName, getMimeCategory, getNodeEncoding, getPrimaryMediaType, getPrimaryRepresentation, getPrimarySelector, getResourceEntityTypes, getResourceId, getStorageUri, getTargetSelector, getTargetSource, getTextQuoteSelector, hasTargetSelector, isArchived, isAssessment, isBodyResolved, isComment, isDraft, isHighlight, isImageMimeType, isPdfMimeType, isReference, isResolvedReference, isStubReference, isTag, isTextMimeType, isValidEmail, normalizeCoordinates, normalizeText, parseSvgSelector, scaleSvgToNative, validateAndCorrectOffsets, validateData, verifyPosition };
|
|
1830
2221
|
//# sourceMappingURL=index.js.map
|
|
1831
2222
|
//# sourceMappingURL=index.js.map
|