@semiont/sdk 0.5.0 → 0.5.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/README.md +52 -30
- package/dist/index.d.ts +237 -52
- package/dist/index.js +366 -174
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,13 +1,50 @@
|
|
|
1
|
-
import { annotationId, resourceId, email, googleCredential, refreshToken, EventBus,
|
|
2
|
-
|
|
3
|
-
import {
|
|
1
|
+
import { SemiontError, annotationId, resourceId, email, googleCredential, refreshToken, EventBus, baseUrl, accessToken, isHighlight, isComment, isAssessment, isReference, isTag, decodeWithCharset, getPrimaryMediaType, userDID, searchQuery } from '@semiont/core';
|
|
2
|
+
export { SemiontError, accessToken, annotationId, baseUrl, entityType, refreshToken, resourceId, userId } from '@semiont/core';
|
|
3
|
+
import { Observable, lastValueFrom, firstValueFrom, merge, TimeoutError, throwError, BehaviorSubject, map as map$1, distinctUntilChanged, Subject, Subscription, of, filter as filter$1, take as take$1, timeout as timeout$1 } from 'rxjs';
|
|
4
|
+
export { firstValueFrom, lastValueFrom } from 'rxjs';
|
|
5
|
+
import { filter, map, take, timeout, catchError, takeUntil, startWith, debounceTime, distinctUntilChanged as distinctUntilChanged$1, switchMap } from 'rxjs/operators';
|
|
4
6
|
import { HttpTransport, HttpContentTransport, createActorVM, APIError } from '@semiont/api-client';
|
|
5
7
|
export { APIError, DEGRADED_THRESHOLD_MS, HttpContentTransport, HttpTransport, createActorVM } from '@semiont/api-client';
|
|
6
8
|
|
|
7
9
|
// src/client.ts
|
|
8
|
-
var
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
var StreamObservable = class _StreamObservable extends Observable {
|
|
11
|
+
then(onfulfilled, onrejected) {
|
|
12
|
+
return lastValueFrom(this).then(onfulfilled, onrejected);
|
|
13
|
+
}
|
|
14
|
+
/** Wrap an existing Observable's subscribe behavior in a StreamObservable. */
|
|
15
|
+
static from(source) {
|
|
16
|
+
return new _StreamObservable((subscriber) => source.subscribe(subscriber));
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
var CacheObservable = class _CacheObservable extends Observable {
|
|
20
|
+
then(onfulfilled, onrejected) {
|
|
21
|
+
return firstValueFrom(this.pipe(filter((v) => v !== void 0))).then(onfulfilled, onrejected);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Wrap an existing Observable's subscribe behavior in a `CacheObservable`.
|
|
25
|
+
*
|
|
26
|
+
* Memoizes on source identity: passing the same `source` returns the same
|
|
27
|
+
* wrapper instance. The Browse cache primitive already returns a stable
|
|
28
|
+
* Observable per key (its B4 contract), so this preserves that contract
|
|
29
|
+
* through the awaitable wrapping. Without the memo, every public-method
|
|
30
|
+
* call would produce a fresh wrapper and break referential-equality
|
|
31
|
+
* guarantees that React-side consumers depend on.
|
|
32
|
+
*
|
|
33
|
+
* Backed by a `WeakMap`, so wrappers are GC'd when their source is.
|
|
34
|
+
*/
|
|
35
|
+
static from(source) {
|
|
36
|
+
let wrapper = wrapperCache.get(source);
|
|
37
|
+
if (!wrapper) {
|
|
38
|
+
wrapper = new _CacheObservable((subscriber) => source.subscribe(subscriber));
|
|
39
|
+
wrapperCache.set(source, wrapper);
|
|
40
|
+
}
|
|
41
|
+
return wrapper;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
var wrapperCache = /* @__PURE__ */ new WeakMap();
|
|
45
|
+
var BusRequestError = class extends SemiontError {
|
|
46
|
+
constructor(message, code, details) {
|
|
47
|
+
super(message, code, details);
|
|
11
48
|
this.name = "BusRequestError";
|
|
12
49
|
}
|
|
13
50
|
};
|
|
@@ -21,9 +58,31 @@ async function busRequest(bus, emitChannel, payload, resultChannel, failureChann
|
|
|
21
58
|
),
|
|
22
59
|
bus.stream(failureChannel).pipe(
|
|
23
60
|
filter((e) => e.correlationId === correlationId),
|
|
24
|
-
map((e) => ({
|
|
61
|
+
map((e) => ({
|
|
62
|
+
ok: false,
|
|
63
|
+
error: new BusRequestError(e.message ?? "Bus request rejected", "bus.rejected", {
|
|
64
|
+
channel: failureChannel,
|
|
65
|
+
correlationId,
|
|
66
|
+
payload: e
|
|
67
|
+
})
|
|
68
|
+
}))
|
|
25
69
|
)
|
|
26
|
-
).pipe(
|
|
70
|
+
).pipe(
|
|
71
|
+
take(1),
|
|
72
|
+
timeout(timeoutMs),
|
|
73
|
+
catchError((err) => {
|
|
74
|
+
if (err instanceof TimeoutError) {
|
|
75
|
+
return throwError(
|
|
76
|
+
() => new BusRequestError(
|
|
77
|
+
`Bus request timed out after ${timeoutMs}ms on ${resultChannel}`,
|
|
78
|
+
"bus.timeout",
|
|
79
|
+
{ channel: emitChannel, resultChannel, correlationId, timeoutMs }
|
|
80
|
+
)
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
return throwError(() => err);
|
|
84
|
+
})
|
|
85
|
+
);
|
|
27
86
|
const resultPromise = firstValueFrom(result$);
|
|
28
87
|
await bus.emit(emitChannel, fullPayload);
|
|
29
88
|
const result = await resultPromise;
|
|
@@ -106,11 +165,6 @@ var BrowseNamespace = class {
|
|
|
106
165
|
this.transport = transport;
|
|
107
166
|
this.bus = bus;
|
|
108
167
|
this.content = content;
|
|
109
|
-
const g = globalThis;
|
|
110
|
-
g.__SEMIONT_BROWSE_INSTANCES__ = (g.__SEMIONT_BROWSE_INSTANCES__ ?? 0) + 1;
|
|
111
|
-
const browseSerial = g.__SEMIONT_BROWSE_INSTANCES__;
|
|
112
|
-
this.__serial__ = browseSerial;
|
|
113
|
-
console.debug(`[diag] BrowseNamespace #${browseSerial} constructed`);
|
|
114
168
|
this.resourceCache = createCache(async (id) => {
|
|
115
169
|
const result = await busRequest(
|
|
116
170
|
this.transport,
|
|
@@ -133,32 +187,30 @@ var BrowseNamespace = class {
|
|
|
133
187
|
);
|
|
134
188
|
return result.resources;
|
|
135
189
|
});
|
|
136
|
-
this.annotationListCache = createCache(async (
|
|
190
|
+
this.annotationListCache = createCache(async (resourceId2) => {
|
|
137
191
|
return busRequest(
|
|
138
192
|
this.transport,
|
|
139
193
|
"browse:annotations-requested",
|
|
140
|
-
{ resourceId },
|
|
194
|
+
{ resourceId: resourceId2 },
|
|
141
195
|
"browse:annotations-result",
|
|
142
196
|
"browse:annotations-failed"
|
|
143
197
|
);
|
|
144
198
|
});
|
|
145
|
-
this.annotationDetailCache = createCache(async (
|
|
146
|
-
const
|
|
147
|
-
if (!
|
|
148
|
-
throw new Error(`Cannot fetch annotation ${
|
|
199
|
+
this.annotationDetailCache = createCache(async (annotationId2) => {
|
|
200
|
+
const resourceId2 = this.annotationResources.get(annotationId2);
|
|
201
|
+
if (!resourceId2) {
|
|
202
|
+
throw new Error(`Cannot fetch annotation ${annotationId2}: no resourceId known`);
|
|
149
203
|
}
|
|
150
204
|
const result = await busRequest(
|
|
151
205
|
this.transport,
|
|
152
206
|
"browse:annotation-requested",
|
|
153
|
-
{ resourceId, annotationId },
|
|
207
|
+
{ resourceId: resourceId2, annotationId: annotationId2 },
|
|
154
208
|
"browse:annotation-result",
|
|
155
209
|
"browse:annotation-failed"
|
|
156
210
|
);
|
|
157
211
|
return result.annotation;
|
|
158
212
|
});
|
|
159
213
|
this.entityTypesCache = createCache(async () => {
|
|
160
|
-
const serial = this.__serial__;
|
|
161
|
-
console.debug(`[diag] BrowseNamespace#${serial} entityTypes fetchFn START`);
|
|
162
214
|
const result = await busRequest(
|
|
163
215
|
this.transport,
|
|
164
216
|
"browse:entity-types-requested",
|
|
@@ -166,24 +218,23 @@ var BrowseNamespace = class {
|
|
|
166
218
|
"browse:entity-types-result",
|
|
167
219
|
"browse:entity-types-failed"
|
|
168
220
|
);
|
|
169
|
-
console.debug(`[diag] BrowseNamespace#${serial} entityTypes fetchFn RESOLVE`, JSON.stringify(result.entityTypes).slice(0, 200));
|
|
170
221
|
return result.entityTypes;
|
|
171
222
|
});
|
|
172
|
-
this.referencedByCache = createCache(async (
|
|
223
|
+
this.referencedByCache = createCache(async (resourceId2) => {
|
|
173
224
|
const result = await busRequest(
|
|
174
225
|
this.transport,
|
|
175
226
|
"browse:referenced-by-requested",
|
|
176
|
-
{ resourceId },
|
|
227
|
+
{ resourceId: resourceId2 },
|
|
177
228
|
"browse:referenced-by-result",
|
|
178
229
|
"browse:referenced-by-failed"
|
|
179
230
|
);
|
|
180
231
|
return result.referencedBy;
|
|
181
232
|
});
|
|
182
|
-
this.resourceEventsCache = createCache(async (
|
|
233
|
+
this.resourceEventsCache = createCache(async (resourceId2) => {
|
|
183
234
|
const result = await busRequest(
|
|
184
235
|
this.transport,
|
|
185
236
|
"browse:events-requested",
|
|
186
|
-
{ resourceId },
|
|
237
|
+
{ resourceId: resourceId2 },
|
|
187
238
|
"browse:events-result",
|
|
188
239
|
"browse:events-failed"
|
|
189
240
|
);
|
|
@@ -195,7 +246,7 @@ var BrowseNamespace = class {
|
|
|
195
246
|
//
|
|
196
247
|
// Each cache encapsulates the BehaviorSubject store, in-flight guard,
|
|
197
248
|
// and per-key observable memoization that was previously open-coded
|
|
198
|
-
// here. Behavioral contract: `packages/
|
|
249
|
+
// here. Behavioral contract: `packages/sdk/docs/CACHE-SEMANTICS.md`.
|
|
199
250
|
//
|
|
200
251
|
// Public surface (`resource()`, `annotations()`, etc.) is unchanged;
|
|
201
252
|
// the caches are an implementation detail of this namespace.
|
|
@@ -227,71 +278,66 @@ var BrowseNamespace = class {
|
|
|
227
278
|
*/
|
|
228
279
|
annotationListObs = /* @__PURE__ */ new Map();
|
|
229
280
|
// ── Live queries ────────────────────────────────────────────────────────
|
|
230
|
-
|
|
231
|
-
|
|
281
|
+
//
|
|
282
|
+
// These return `CacheObservable<T>`: subscribers see `T | undefined`
|
|
283
|
+
// (with `undefined` during initial load), and `await` resolves to the
|
|
284
|
+
// first non-undefined value.
|
|
285
|
+
resource(resourceId2) {
|
|
286
|
+
return CacheObservable.from(this.resourceCache.observe(resourceId2));
|
|
232
287
|
}
|
|
233
288
|
resources(filters) {
|
|
234
289
|
const key = JSON.stringify(filters ?? {});
|
|
235
290
|
this.resourceListFilters.set(key, filters ?? {});
|
|
236
|
-
return this.resourceListCache.observe(key);
|
|
291
|
+
return CacheObservable.from(this.resourceListCache.observe(key));
|
|
237
292
|
}
|
|
238
|
-
annotations(
|
|
239
|
-
let obs = this.annotationListObs.get(
|
|
293
|
+
annotations(resourceId2) {
|
|
294
|
+
let obs = this.annotationListObs.get(resourceId2);
|
|
240
295
|
if (!obs) {
|
|
241
|
-
obs = this.annotationListCache.observe(
|
|
242
|
-
this.annotationListObs.set(
|
|
296
|
+
obs = this.annotationListCache.observe(resourceId2).pipe(map$1((r) => r?.annotations));
|
|
297
|
+
this.annotationListObs.set(resourceId2, obs);
|
|
243
298
|
}
|
|
244
|
-
return obs;
|
|
299
|
+
return CacheObservable.from(obs);
|
|
245
300
|
}
|
|
246
|
-
annotation(
|
|
247
|
-
this.annotationResources.set(
|
|
248
|
-
return this.annotationDetailCache.observe(
|
|
301
|
+
annotation(resourceId2, annotationId2) {
|
|
302
|
+
this.annotationResources.set(annotationId2, resourceId2);
|
|
303
|
+
return CacheObservable.from(this.annotationDetailCache.observe(annotationId2));
|
|
249
304
|
}
|
|
250
305
|
entityTypes() {
|
|
251
|
-
|
|
252
|
-
console.debug(`[diag] BrowseNamespace#${serial} entityTypes() called`);
|
|
253
|
-
const self = this;
|
|
254
|
-
if (!self.__entityTypesDiag__) {
|
|
255
|
-
self.__entityTypesDiag__ = this.entityTypesCache.observe(ENTITY_TYPES_KEY).pipe(map$1((v) => {
|
|
256
|
-
console.debug(`[diag] BrowseNamespace#${serial} entityTypes$ EMIT`, v === void 0 ? "undefined" : JSON.stringify(v).slice(0, 200));
|
|
257
|
-
return v;
|
|
258
|
-
}));
|
|
259
|
-
}
|
|
260
|
-
return self.__entityTypesDiag__;
|
|
306
|
+
return CacheObservable.from(this.entityTypesCache.observe(ENTITY_TYPES_KEY));
|
|
261
307
|
}
|
|
262
|
-
referencedBy(
|
|
263
|
-
return this.referencedByCache.observe(
|
|
308
|
+
referencedBy(resourceId2) {
|
|
309
|
+
return CacheObservable.from(this.referencedByCache.observe(resourceId2));
|
|
264
310
|
}
|
|
265
|
-
events(
|
|
266
|
-
return this.resourceEventsCache.observe(
|
|
311
|
+
events(resourceId2) {
|
|
312
|
+
return CacheObservable.from(this.resourceEventsCache.observe(resourceId2));
|
|
267
313
|
}
|
|
268
314
|
// ── One-shot reads ──────────────────────────────────────────────────────
|
|
269
|
-
async resourceContent(
|
|
270
|
-
const result = await this.content.getBinary(
|
|
315
|
+
async resourceContent(resourceId2) {
|
|
316
|
+
const result = await this.content.getBinary(resourceId2, { accept: "text/plain" });
|
|
271
317
|
const decoder = new TextDecoder();
|
|
272
318
|
return decoder.decode(result.data);
|
|
273
319
|
}
|
|
274
|
-
async resourceRepresentation(
|
|
275
|
-
return this.content.getBinary(
|
|
320
|
+
async resourceRepresentation(resourceId2, options) {
|
|
321
|
+
return this.content.getBinary(resourceId2, options?.accept ? { accept: options.accept } : void 0);
|
|
276
322
|
}
|
|
277
|
-
async resourceRepresentationStream(
|
|
278
|
-
return this.content.getBinaryStream(
|
|
323
|
+
async resourceRepresentationStream(resourceId2, options) {
|
|
324
|
+
return this.content.getBinaryStream(resourceId2, options?.accept ? { accept: options.accept } : void 0);
|
|
279
325
|
}
|
|
280
|
-
async resourceEvents(
|
|
326
|
+
async resourceEvents(resourceId2) {
|
|
281
327
|
const result = await busRequest(
|
|
282
328
|
this.transport,
|
|
283
329
|
"browse:events-requested",
|
|
284
|
-
{ resourceId },
|
|
330
|
+
{ resourceId: resourceId2 },
|
|
285
331
|
"browse:events-result",
|
|
286
332
|
"browse:events-failed"
|
|
287
333
|
);
|
|
288
334
|
return result.events;
|
|
289
335
|
}
|
|
290
|
-
async annotationHistory(
|
|
336
|
+
async annotationHistory(resourceId2, annotationId2) {
|
|
291
337
|
return busRequest(
|
|
292
338
|
this.transport,
|
|
293
339
|
"browse:annotation-history-requested",
|
|
294
|
-
{ resourceId, annotationId },
|
|
340
|
+
{ resourceId: resourceId2, annotationId: annotationId2 },
|
|
295
341
|
"browse:annotation-history-result",
|
|
296
342
|
"browse:annotation-history-failed"
|
|
297
343
|
);
|
|
@@ -315,11 +361,11 @@ var BrowseNamespace = class {
|
|
|
315
361
|
);
|
|
316
362
|
}
|
|
317
363
|
// ── UI signals (local bus fan-out) ────────────────────────────────────
|
|
318
|
-
click(
|
|
319
|
-
this.bus.get("browse:click").next({ annotationId, motivation });
|
|
364
|
+
click(annotationId2, motivation) {
|
|
365
|
+
this.bus.get("browse:click").next({ annotationId: annotationId2, motivation });
|
|
320
366
|
}
|
|
321
|
-
navigateReference(
|
|
322
|
-
this.bus.get("browse:reference-navigate").next({ resourceId });
|
|
367
|
+
navigateReference(resourceId2) {
|
|
368
|
+
this.bus.get("browse:reference-navigate").next({ resourceId: resourceId2 });
|
|
323
369
|
}
|
|
324
370
|
// ── Cache-mutation API (used by the bus-event subscribers below and by
|
|
325
371
|
// other namespaces that know about specific updates) ─────────────────
|
|
@@ -327,12 +373,12 @@ var BrowseNamespace = class {
|
|
|
327
373
|
// - `invalidate*` — SWR refetch (B7). Keeps prior value visible.
|
|
328
374
|
// - `removeAnnotationDetail` — drops the entry (B13a: entity gone).
|
|
329
375
|
// - `updateAnnotationInPlace` — write-through (B13b: new value known).
|
|
330
|
-
invalidateAnnotationList(
|
|
331
|
-
this.annotationListCache.invalidate(
|
|
376
|
+
invalidateAnnotationList(resourceId2) {
|
|
377
|
+
this.annotationListCache.invalidate(resourceId2);
|
|
332
378
|
}
|
|
333
|
-
removeAnnotationDetail(
|
|
334
|
-
this.annotationDetailCache.remove(
|
|
335
|
-
this.annotationResources.delete(
|
|
379
|
+
removeAnnotationDetail(annotationId2) {
|
|
380
|
+
this.annotationDetailCache.remove(annotationId2);
|
|
381
|
+
this.annotationResources.delete(annotationId2);
|
|
336
382
|
}
|
|
337
383
|
invalidateResourceDetail(id) {
|
|
338
384
|
this.resourceCache.invalidate(id);
|
|
@@ -343,21 +389,21 @@ var BrowseNamespace = class {
|
|
|
343
389
|
invalidateEntityTypes() {
|
|
344
390
|
this.entityTypesCache.invalidate(ENTITY_TYPES_KEY);
|
|
345
391
|
}
|
|
346
|
-
invalidateReferencedBy(
|
|
347
|
-
this.referencedByCache.invalidate(
|
|
392
|
+
invalidateReferencedBy(resourceId2) {
|
|
393
|
+
this.referencedByCache.invalidate(resourceId2);
|
|
348
394
|
}
|
|
349
|
-
invalidateResourceEvents(
|
|
350
|
-
this.resourceEventsCache.invalidate(
|
|
395
|
+
invalidateResourceEvents(resourceId2) {
|
|
396
|
+
this.resourceEventsCache.invalidate(resourceId2);
|
|
351
397
|
}
|
|
352
|
-
updateAnnotationInPlace(
|
|
353
|
-
const currentList = this.annotationListCache.get(
|
|
398
|
+
updateAnnotationInPlace(resourceId2, annotation) {
|
|
399
|
+
const currentList = this.annotationListCache.get(resourceId2);
|
|
354
400
|
if (currentList) {
|
|
355
401
|
const idx = currentList.annotations.findIndex((a) => a.id === annotation.id);
|
|
356
402
|
const nextAnnotations = idx >= 0 ? currentList.annotations.map((a, i) => i === idx ? annotation : a) : [...currentList.annotations, annotation];
|
|
357
|
-
this.annotationListCache.set(
|
|
403
|
+
this.annotationListCache.set(resourceId2, { ...currentList, annotations: nextAnnotations });
|
|
358
404
|
}
|
|
359
405
|
const aId = annotationId(annotation.id);
|
|
360
|
-
this.annotationResources.set(aId,
|
|
406
|
+
this.annotationResources.set(aId, resourceId2);
|
|
361
407
|
this.annotationDetailCache.set(aId, annotation);
|
|
362
408
|
}
|
|
363
409
|
// ── EventBus subscriptions ──────────────────────────────────────────────
|
|
@@ -461,17 +507,18 @@ var MarkNamespace = class {
|
|
|
461
507
|
this.transport = transport;
|
|
462
508
|
this.bus = bus;
|
|
463
509
|
}
|
|
464
|
-
async annotation(
|
|
465
|
-
|
|
510
|
+
async annotation(resourceId2, input) {
|
|
511
|
+
const result = await busRequest(
|
|
466
512
|
this.transport,
|
|
467
513
|
"mark:create-request",
|
|
468
|
-
{ resourceId, request: input },
|
|
514
|
+
{ resourceId: resourceId2, request: input },
|
|
469
515
|
"mark:create-ok",
|
|
470
516
|
"mark:create-failed"
|
|
471
517
|
);
|
|
518
|
+
return { annotationId: annotationId(result.annotationId) };
|
|
472
519
|
}
|
|
473
|
-
async delete(
|
|
474
|
-
await this.transport.emit("mark:delete", { annotationId, resourceId });
|
|
520
|
+
async delete(resourceId2, annotationId2) {
|
|
521
|
+
await this.transport.emit("mark:delete", { annotationId: annotationId2, resourceId: resourceId2 });
|
|
475
522
|
}
|
|
476
523
|
async entityType(type) {
|
|
477
524
|
await this.transport.emit("mark:add-entity-type", { tag: type });
|
|
@@ -481,14 +528,14 @@ var MarkNamespace = class {
|
|
|
481
528
|
await this.transport.emit("mark:add-entity-type", { tag });
|
|
482
529
|
}
|
|
483
530
|
}
|
|
484
|
-
async archive(
|
|
485
|
-
await this.transport.emit("mark:archive", { resourceId });
|
|
531
|
+
async archive(resourceId2) {
|
|
532
|
+
await this.transport.emit("mark:archive", { resourceId: resourceId2 });
|
|
486
533
|
}
|
|
487
|
-
async unarchive(
|
|
488
|
-
await this.transport.emit("mark:unarchive", { resourceId });
|
|
534
|
+
async unarchive(resourceId2) {
|
|
535
|
+
await this.transport.emit("mark:unarchive", { resourceId: resourceId2 });
|
|
489
536
|
}
|
|
490
|
-
assist(
|
|
491
|
-
return new
|
|
537
|
+
assist(resourceId2, motivation, options) {
|
|
538
|
+
return new StreamObservable((subscriber) => {
|
|
492
539
|
let done = false;
|
|
493
540
|
let pollTimer = null;
|
|
494
541
|
let pollInterval = null;
|
|
@@ -528,7 +575,7 @@ var MarkNamespace = class {
|
|
|
528
575
|
data: {
|
|
529
576
|
jobId,
|
|
530
577
|
jobType: status.jobType ?? "annotation",
|
|
531
|
-
resourceId,
|
|
578
|
+
resourceId: resourceId2,
|
|
532
579
|
result: status.result
|
|
533
580
|
}
|
|
534
581
|
});
|
|
@@ -565,7 +612,7 @@ var MarkNamespace = class {
|
|
|
565
612
|
cleanup();
|
|
566
613
|
subscriber.error(new Error(e.error));
|
|
567
614
|
});
|
|
568
|
-
this.dispatchAssist(
|
|
615
|
+
this.dispatchAssist(resourceId2, motivation, options).then(({ jobId }) => {
|
|
569
616
|
if (jobId && !done) {
|
|
570
617
|
activeJobId = jobId;
|
|
571
618
|
resetPollTimer(jobId);
|
|
@@ -613,7 +660,7 @@ var MarkNamespace = class {
|
|
|
613
660
|
toggleMode() {
|
|
614
661
|
this.bus.get("mark:mode-toggled").next(void 0);
|
|
615
662
|
}
|
|
616
|
-
async dispatchAssist(
|
|
663
|
+
async dispatchAssist(resourceId2, motivation, options) {
|
|
617
664
|
const jobTypeMap = {
|
|
618
665
|
tagging: "tag-annotation",
|
|
619
666
|
linking: "reference-annotation",
|
|
@@ -640,7 +687,7 @@ var MarkNamespace = class {
|
|
|
640
687
|
return busRequest(
|
|
641
688
|
this.transport,
|
|
642
689
|
"job:create",
|
|
643
|
-
{ jobType, resourceId, params },
|
|
690
|
+
{ jobType, resourceId: resourceId2, params },
|
|
644
691
|
"job:created",
|
|
645
692
|
"job:create-failed"
|
|
646
693
|
);
|
|
@@ -653,11 +700,11 @@ var BindNamespace = class {
|
|
|
653
700
|
this.transport = transport;
|
|
654
701
|
this.bus = bus;
|
|
655
702
|
}
|
|
656
|
-
async body(
|
|
703
|
+
async body(resourceId2, annotationId2, operations) {
|
|
657
704
|
await this.transport.emit("bind:update-body", {
|
|
658
705
|
correlationId: crypto.randomUUID(),
|
|
659
|
-
annotationId,
|
|
660
|
-
resourceId,
|
|
706
|
+
annotationId: annotationId2,
|
|
707
|
+
resourceId: resourceId2,
|
|
661
708
|
operations
|
|
662
709
|
});
|
|
663
710
|
}
|
|
@@ -670,8 +717,8 @@ var GatherNamespace = class {
|
|
|
670
717
|
this.transport = transport;
|
|
671
718
|
this.bus = bus;
|
|
672
719
|
}
|
|
673
|
-
annotation(
|
|
674
|
-
return new
|
|
720
|
+
annotation(annotationId2, resourceId2, options) {
|
|
721
|
+
return new StreamObservable((subscriber) => {
|
|
675
722
|
const correlationId = crypto.randomUUID();
|
|
676
723
|
const complete$ = this.bus.get("gather:complete").pipe(
|
|
677
724
|
filter((e) => e.correlationId === correlationId)
|
|
@@ -681,7 +728,7 @@ var GatherNamespace = class {
|
|
|
681
728
|
);
|
|
682
729
|
const sub = merge(
|
|
683
730
|
this.bus.get("gather:annotation-progress").pipe(
|
|
684
|
-
filter((e) => e.annotationId ===
|
|
731
|
+
filter((e) => e.annotationId === annotationId2),
|
|
685
732
|
map((e) => e)
|
|
686
733
|
),
|
|
687
734
|
complete$.pipe(map((e) => e))
|
|
@@ -698,8 +745,8 @@ var GatherNamespace = class {
|
|
|
698
745
|
});
|
|
699
746
|
this.transport.emit("gather:requested", {
|
|
700
747
|
correlationId,
|
|
701
|
-
annotationId,
|
|
702
|
-
resourceId,
|
|
748
|
+
annotationId: annotationId2,
|
|
749
|
+
resourceId: resourceId2,
|
|
703
750
|
options: { contextWindow: options?.contextWindow ?? 2e3 }
|
|
704
751
|
}).catch((error) => {
|
|
705
752
|
subscriber.error(error);
|
|
@@ -723,8 +770,8 @@ var MatchNamespace = class {
|
|
|
723
770
|
requestSearch(input) {
|
|
724
771
|
this.bus.get("match:search-requested").next(input);
|
|
725
772
|
}
|
|
726
|
-
search(
|
|
727
|
-
return new
|
|
773
|
+
search(resourceId2, referenceId, context, options) {
|
|
774
|
+
return new StreamObservable((subscriber) => {
|
|
728
775
|
const correlationId = crypto.randomUUID();
|
|
729
776
|
const result$ = this.bus.get("match:search-results").pipe(
|
|
730
777
|
filter((e) => e.correlationId === correlationId)
|
|
@@ -741,7 +788,7 @@ var MatchNamespace = class {
|
|
|
741
788
|
});
|
|
742
789
|
this.transport.emit("match:search-requested", {
|
|
743
790
|
correlationId,
|
|
744
|
-
resourceId,
|
|
791
|
+
resourceId: resourceId2,
|
|
745
792
|
referenceId,
|
|
746
793
|
context,
|
|
747
794
|
limit: options?.limit ?? 10,
|
|
@@ -779,8 +826,8 @@ var YieldNamespace = class {
|
|
|
779
826
|
});
|
|
780
827
|
return { resourceId: result.resourceId };
|
|
781
828
|
}
|
|
782
|
-
fromAnnotation(
|
|
783
|
-
return new
|
|
829
|
+
fromAnnotation(resourceId2, annotationId2, options) {
|
|
830
|
+
return new StreamObservable((subscriber) => {
|
|
784
831
|
let done = false;
|
|
785
832
|
let pollTimer = null;
|
|
786
833
|
let pollInterval = null;
|
|
@@ -820,7 +867,7 @@ var YieldNamespace = class {
|
|
|
820
867
|
data: {
|
|
821
868
|
jobId: jid,
|
|
822
869
|
jobType: status.jobType ?? "generation",
|
|
823
|
-
resourceId,
|
|
870
|
+
resourceId: resourceId2,
|
|
824
871
|
result: status.result
|
|
825
872
|
}
|
|
826
873
|
});
|
|
@@ -862,9 +909,9 @@ var YieldNamespace = class {
|
|
|
862
909
|
"job:create",
|
|
863
910
|
{
|
|
864
911
|
jobType: "generation",
|
|
865
|
-
resourceId,
|
|
912
|
+
resourceId: resourceId2,
|
|
866
913
|
params: {
|
|
867
|
-
referenceId:
|
|
914
|
+
referenceId: annotationId2,
|
|
868
915
|
title: options.title,
|
|
869
916
|
prompt: options.prompt,
|
|
870
917
|
language: options.language,
|
|
@@ -893,11 +940,11 @@ var YieldNamespace = class {
|
|
|
893
940
|
};
|
|
894
941
|
});
|
|
895
942
|
}
|
|
896
|
-
async cloneToken(
|
|
943
|
+
async cloneToken(resourceId2) {
|
|
897
944
|
return busRequest(
|
|
898
945
|
this.transport,
|
|
899
946
|
"yield:clone-token-requested",
|
|
900
|
-
{ resourceId },
|
|
947
|
+
{ resourceId: resourceId2 },
|
|
901
948
|
"yield:clone-token-generated",
|
|
902
949
|
"yield:clone-token-failed"
|
|
903
950
|
);
|
|
@@ -932,14 +979,14 @@ var BeckonNamespace = class {
|
|
|
932
979
|
this.transport = transport;
|
|
933
980
|
this.bus = bus;
|
|
934
981
|
}
|
|
935
|
-
attention(
|
|
936
|
-
void this.transport.emit("beckon:focus", { annotationId, resourceId });
|
|
982
|
+
attention(annotationId2, resourceId2) {
|
|
983
|
+
void this.transport.emit("beckon:focus", { annotationId: annotationId2, resourceId: resourceId2 });
|
|
937
984
|
}
|
|
938
|
-
hover(
|
|
939
|
-
this.bus.get("beckon:hover").next({ annotationId });
|
|
985
|
+
hover(annotationId2) {
|
|
986
|
+
this.bus.get("beckon:hover").next({ annotationId: annotationId2 });
|
|
940
987
|
}
|
|
941
|
-
sparkle(
|
|
942
|
-
this.bus.get("beckon:sparkle").next({ annotationId });
|
|
988
|
+
sparkle(annotationId2) {
|
|
989
|
+
this.bus.get("beckon:sparkle").next({ annotationId: annotationId2 });
|
|
943
990
|
}
|
|
944
991
|
};
|
|
945
992
|
|
|
@@ -1028,8 +1075,8 @@ var AuthNamespace = class {
|
|
|
1028
1075
|
async mcpToken() {
|
|
1029
1076
|
return this.transport.generateMcpToken();
|
|
1030
1077
|
}
|
|
1031
|
-
async mediaToken(
|
|
1032
|
-
return this.transport.getMediaToken(
|
|
1078
|
+
async mediaToken(resourceId2) {
|
|
1079
|
+
return this.transport.getMediaToken(resourceId2);
|
|
1033
1080
|
}
|
|
1034
1081
|
};
|
|
1035
1082
|
|
|
@@ -1045,8 +1092,8 @@ var AdminNamespace = class {
|
|
|
1045
1092
|
async userStats() {
|
|
1046
1093
|
return this.transport.getUserStats();
|
|
1047
1094
|
}
|
|
1048
|
-
async updateUser(
|
|
1049
|
-
const result = await this.transport.updateUser(
|
|
1095
|
+
async updateUser(userId2, data) {
|
|
1096
|
+
const result = await this.transport.updateUser(userId2, data);
|
|
1050
1097
|
return result.user;
|
|
1051
1098
|
}
|
|
1052
1099
|
async oauthConfig() {
|
|
@@ -1071,7 +1118,7 @@ var AdminNamespace = class {
|
|
|
1071
1118
|
return this.transport.importKnowledgeBase(file, onProgress);
|
|
1072
1119
|
}
|
|
1073
1120
|
};
|
|
1074
|
-
var SemiontClient = class {
|
|
1121
|
+
var SemiontClient = class _SemiontClient {
|
|
1075
1122
|
/**
|
|
1076
1123
|
* The wire-facing transport. Owns bus actor, HTTP, auth, admin, exchange,
|
|
1077
1124
|
* system. Exposed for advanced consumers (workers, custom job adapters)
|
|
@@ -1134,13 +1181,74 @@ var SemiontClient = class {
|
|
|
1134
1181
|
get state$() {
|
|
1135
1182
|
return this.transport.state$;
|
|
1136
1183
|
}
|
|
1137
|
-
subscribeToResource(
|
|
1138
|
-
return this.transport.subscribeToResource(
|
|
1184
|
+
subscribeToResource(resourceId2) {
|
|
1185
|
+
return this.transport.subscribeToResource(resourceId2);
|
|
1139
1186
|
}
|
|
1140
1187
|
dispose() {
|
|
1141
1188
|
this.transport.dispose();
|
|
1142
1189
|
this.content.dispose();
|
|
1143
1190
|
}
|
|
1191
|
+
/**
|
|
1192
|
+
* Convenience factory for the default HTTP setup. Constructs a
|
|
1193
|
+
* `BehaviorSubject<AccessToken | null>` internally, plus an
|
|
1194
|
+
* `HttpTransport` and `HttpContentTransport`, and returns the wired
|
|
1195
|
+
* `SemiontClient`.
|
|
1196
|
+
*
|
|
1197
|
+
* Use this for one-shot scripts, CLI commands, or any consumer that
|
|
1198
|
+
* doesn't need to drive the token from outside (no manual refresh,
|
|
1199
|
+
* no cross-tab sync). For long-running scripts that need refresh,
|
|
1200
|
+
* use `SemiontSession.fromHttp(...)` instead — it owns the same
|
|
1201
|
+
* transport/client wiring plus the proactive-refresh + storage
|
|
1202
|
+
* machinery.
|
|
1203
|
+
*
|
|
1204
|
+
* Strings are accepted for `baseUrl` and `token`; they are branded
|
|
1205
|
+
* via `baseUrl()` / `accessToken()` from `@semiont/core` automatically.
|
|
1206
|
+
* Pass the already-branded values if you have them.
|
|
1207
|
+
*
|
|
1208
|
+
* Omit `token` for unauthenticated usage (public endpoints only).
|
|
1209
|
+
*/
|
|
1210
|
+
static fromHttp(opts) {
|
|
1211
|
+
const url = typeof opts.baseUrl === "string" ? baseUrl(opts.baseUrl) : opts.baseUrl;
|
|
1212
|
+
const tok = opts.token == null ? null : typeof opts.token === "string" ? accessToken(opts.token) : opts.token;
|
|
1213
|
+
const token$ = new BehaviorSubject(tok);
|
|
1214
|
+
const transport = new HttpTransport({ baseUrl: url, token$ });
|
|
1215
|
+
const content = new HttpContentTransport(transport);
|
|
1216
|
+
return new _SemiontClient(transport, content);
|
|
1217
|
+
}
|
|
1218
|
+
/**
|
|
1219
|
+
* Async factory for the credentials-first script case. Builds a
|
|
1220
|
+
* transient transport, calls `auth.password(email, password)` to
|
|
1221
|
+
* acquire an access token, and returns the wired client with the
|
|
1222
|
+
* token populated.
|
|
1223
|
+
*
|
|
1224
|
+
* This is the right entry point for skills, CLI scripts, and any
|
|
1225
|
+
* consumer that starts with email + password rather than a JWT
|
|
1226
|
+
* already on hand. For consumers that already hold a token (CLI
|
|
1227
|
+
* cached-token path, env-var token, embedded auth flow), use
|
|
1228
|
+
* `fromHttp({ baseUrl, token })` instead.
|
|
1229
|
+
*
|
|
1230
|
+
* For long-running scripts that need refresh, use
|
|
1231
|
+
* `SemiontSession.signIn(...)` — same credentials shape, plus the
|
|
1232
|
+
* session machinery for proactive refresh and persistence.
|
|
1233
|
+
*
|
|
1234
|
+
* Throws if authentication fails. The transient client is disposed
|
|
1235
|
+
* before the throw, so no resources leak on failure.
|
|
1236
|
+
*/
|
|
1237
|
+
static async signIn(opts) {
|
|
1238
|
+
const url = typeof opts.baseUrl === "string" ? baseUrl(opts.baseUrl) : opts.baseUrl;
|
|
1239
|
+
const token$ = new BehaviorSubject(null);
|
|
1240
|
+
const transport = new HttpTransport({ baseUrl: url, token$ });
|
|
1241
|
+
const content = new HttpContentTransport(transport);
|
|
1242
|
+
const client = new _SemiontClient(transport, content);
|
|
1243
|
+
try {
|
|
1244
|
+
const auth = await client.auth.password(opts.email, opts.password);
|
|
1245
|
+
token$.next(accessToken(auth.token));
|
|
1246
|
+
return client;
|
|
1247
|
+
} catch (err) {
|
|
1248
|
+
client.dispose();
|
|
1249
|
+
throw err;
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1144
1252
|
};
|
|
1145
1253
|
|
|
1146
1254
|
// src/session/storage.ts
|
|
@@ -1241,21 +1349,17 @@ function kbBackendUrl(kb) {
|
|
|
1241
1349
|
function generateKbId() {
|
|
1242
1350
|
return crypto.randomUUID();
|
|
1243
1351
|
}
|
|
1244
|
-
|
|
1245
|
-
// src/session/errors.ts
|
|
1246
|
-
var SemiontError = class extends Error {
|
|
1247
|
-
code;
|
|
1352
|
+
var SemiontSessionError = class extends SemiontError {
|
|
1248
1353
|
kbId;
|
|
1249
1354
|
constructor(code, message, kbId = null) {
|
|
1250
|
-
super(message);
|
|
1251
|
-
this.name = "
|
|
1252
|
-
this.code = code;
|
|
1355
|
+
super(message, code, { kbId });
|
|
1356
|
+
this.name = "SemiontSessionError";
|
|
1253
1357
|
this.kbId = kbId;
|
|
1254
1358
|
}
|
|
1255
1359
|
};
|
|
1256
1360
|
|
|
1257
1361
|
// src/session/semiont-session.ts
|
|
1258
|
-
var SemiontSession = class {
|
|
1362
|
+
var SemiontSession = class _SemiontSession {
|
|
1259
1363
|
kb;
|
|
1260
1364
|
client;
|
|
1261
1365
|
token$;
|
|
@@ -1344,7 +1448,7 @@ var SemiontSession = class {
|
|
|
1344
1448
|
this.onAuthFailed("Your session has expired. Please sign in again.");
|
|
1345
1449
|
} else {
|
|
1346
1450
|
this.onError(
|
|
1347
|
-
new
|
|
1451
|
+
new SemiontSessionError(
|
|
1348
1452
|
"session.auth-failed",
|
|
1349
1453
|
err instanceof Error ? err.message : String(err),
|
|
1350
1454
|
this.kb.id
|
|
@@ -1377,7 +1481,7 @@ var SemiontSession = class {
|
|
|
1377
1481
|
clearStoredSession(this.storage, this.kb.id);
|
|
1378
1482
|
this.onAuthFailed("Your session has expired. Please sign in again.");
|
|
1379
1483
|
this.onError(
|
|
1380
|
-
new
|
|
1484
|
+
new SemiontSessionError("session.refresh-exhausted", "Token refresh failed", this.kb.id)
|
|
1381
1485
|
);
|
|
1382
1486
|
return null;
|
|
1383
1487
|
}
|
|
@@ -1448,6 +1552,94 @@ var SemiontSession = class {
|
|
|
1448
1552
|
this.token$.complete();
|
|
1449
1553
|
this.user$.complete();
|
|
1450
1554
|
}
|
|
1555
|
+
/**
|
|
1556
|
+
* Convenience factory for the default HTTP setup. Constructs the
|
|
1557
|
+
* shared `BehaviorSubject<AccessToken | null>`, an `HttpTransport`,
|
|
1558
|
+
* an `HttpContentTransport`, and a `SemiontClient`, then wires
|
|
1559
|
+
* the session over them. Removes the load-bearing
|
|
1560
|
+
* "same-token$-instance" invariant from the caller's hands.
|
|
1561
|
+
*
|
|
1562
|
+
* Strings are accepted for `baseUrl` and `token`; they are branded
|
|
1563
|
+
* via `baseUrl()` / `accessToken()` from `@semiont/core` automatically.
|
|
1564
|
+
*
|
|
1565
|
+
* The remaining options (`refresh`, `validate`, `onAuthFailed`,
|
|
1566
|
+
* `onError`) match `SemiontSessionConfig` exactly.
|
|
1567
|
+
*/
|
|
1568
|
+
static fromHttp(opts) {
|
|
1569
|
+
const url = typeof opts.baseUrl === "string" ? baseUrl(opts.baseUrl) : opts.baseUrl;
|
|
1570
|
+
const tok = opts.token == null ? null : typeof opts.token === "string" ? accessToken(opts.token) : opts.token;
|
|
1571
|
+
const token$ = new BehaviorSubject(tok);
|
|
1572
|
+
const transport = new HttpTransport({ baseUrl: url, token$ });
|
|
1573
|
+
const content = new HttpContentTransport(transport);
|
|
1574
|
+
const client = new SemiontClient(transport, content);
|
|
1575
|
+
const config = { kb: opts.kb, storage: opts.storage, client, token$ };
|
|
1576
|
+
if (opts.refresh) config.refresh = opts.refresh;
|
|
1577
|
+
if (opts.validate) config.validate = opts.validate;
|
|
1578
|
+
if (opts.onAuthFailed) config.onAuthFailed = opts.onAuthFailed;
|
|
1579
|
+
if (opts.onError) config.onError = opts.onError;
|
|
1580
|
+
return new _SemiontSession(config);
|
|
1581
|
+
}
|
|
1582
|
+
/**
|
|
1583
|
+
* Async factory for the credentials-first long-running script case.
|
|
1584
|
+
* Builds the transport stack, calls `auth.password(email, password)`
|
|
1585
|
+
* to acquire access + refresh tokens, persists them via the storage
|
|
1586
|
+
* adapter, wires a default `refresh` callback that exchanges the
|
|
1587
|
+
* refresh token via `auth.refresh(...)`, and returns the ready
|
|
1588
|
+
* session.
|
|
1589
|
+
*
|
|
1590
|
+
* The consumer-supplied `refresh` callback becomes optional — only
|
|
1591
|
+
* needed for non-standard refresh flows (worker-pool shared secret,
|
|
1592
|
+
* OAuth refresh-token grant, interactive re-prompt). The default
|
|
1593
|
+
* uses the refresh token returned by `auth.password`.
|
|
1594
|
+
*
|
|
1595
|
+
* `kb` is required and must be a full `KnowledgeBase`. The `id` field
|
|
1596
|
+
* is the storage key for this session — distinct scripts sharing the
|
|
1597
|
+
* same `SessionStorage` instance must use distinct ids to avoid
|
|
1598
|
+
* trampling each other's tokens. The factory does not synthesize a
|
|
1599
|
+
* default; the consumer makes the choice.
|
|
1600
|
+
*
|
|
1601
|
+
* Throws on auth failure with no resources leaked. On success, the
|
|
1602
|
+
* returned session's `ready` promise has already resolved.
|
|
1603
|
+
*/
|
|
1604
|
+
static async signIn(opts) {
|
|
1605
|
+
const url = typeof opts.baseUrl === "string" ? baseUrl(opts.baseUrl) : opts.baseUrl;
|
|
1606
|
+
const token$ = new BehaviorSubject(null);
|
|
1607
|
+
const transport = new HttpTransport({ baseUrl: url, token$ });
|
|
1608
|
+
const content = new HttpContentTransport(transport);
|
|
1609
|
+
const client = new SemiontClient(transport, content);
|
|
1610
|
+
let auth;
|
|
1611
|
+
try {
|
|
1612
|
+
auth = await client.auth.password(opts.email, opts.password);
|
|
1613
|
+
} catch (err) {
|
|
1614
|
+
client.dispose();
|
|
1615
|
+
throw err;
|
|
1616
|
+
}
|
|
1617
|
+
setStoredSession(opts.storage, opts.kb.id, { access: auth.token, refresh: auth.refreshToken });
|
|
1618
|
+
token$.next(accessToken(auth.token));
|
|
1619
|
+
const defaultRefresh = async () => {
|
|
1620
|
+
const stored = getStoredSession(opts.storage, opts.kb.id);
|
|
1621
|
+
if (!stored) return null;
|
|
1622
|
+
try {
|
|
1623
|
+
const response = await client.auth.refresh(stored.refresh);
|
|
1624
|
+
return response.access_token;
|
|
1625
|
+
} catch {
|
|
1626
|
+
return null;
|
|
1627
|
+
}
|
|
1628
|
+
};
|
|
1629
|
+
const config = {
|
|
1630
|
+
kb: opts.kb,
|
|
1631
|
+
storage: opts.storage,
|
|
1632
|
+
client,
|
|
1633
|
+
token$,
|
|
1634
|
+
refresh: defaultRefresh
|
|
1635
|
+
};
|
|
1636
|
+
if (opts.validate) config.validate = opts.validate;
|
|
1637
|
+
if (opts.onAuthFailed) config.onAuthFailed = opts.onAuthFailed;
|
|
1638
|
+
if (opts.onError) config.onError = opts.onError;
|
|
1639
|
+
const session = new _SemiontSession(config);
|
|
1640
|
+
await session.ready;
|
|
1641
|
+
return session;
|
|
1642
|
+
}
|
|
1451
1643
|
};
|
|
1452
1644
|
|
|
1453
1645
|
// src/session/notify.ts
|
|
@@ -1728,7 +1920,7 @@ var SemiontBrowser = class {
|
|
|
1728
1920
|
await session.ready;
|
|
1729
1921
|
} catch (err) {
|
|
1730
1922
|
this.error$.next(
|
|
1731
|
-
new
|
|
1923
|
+
new SemiontSessionError(
|
|
1732
1924
|
"session.construct-failed",
|
|
1733
1925
|
err instanceof Error ? err.message : String(err),
|
|
1734
1926
|
id
|
|
@@ -1995,20 +2187,20 @@ function createSearchPipeline(fetch, options = {}) {
|
|
|
1995
2187
|
function createBeckonVM(client) {
|
|
1996
2188
|
const subs = [];
|
|
1997
2189
|
const hovered$ = new BehaviorSubject(null);
|
|
1998
|
-
subs.push(client.bus.get("beckon:hover").subscribe(({ annotationId }) => {
|
|
1999
|
-
hovered$.next(
|
|
2000
|
-
if (
|
|
2001
|
-
client.bus.get("beckon:sparkle").next({ annotationId });
|
|
2190
|
+
subs.push(client.bus.get("beckon:hover").subscribe(({ annotationId: annotationId2 }) => {
|
|
2191
|
+
hovered$.next(annotationId2);
|
|
2192
|
+
if (annotationId2) {
|
|
2193
|
+
client.bus.get("beckon:sparkle").next({ annotationId: annotationId2 });
|
|
2002
2194
|
}
|
|
2003
2195
|
}));
|
|
2004
|
-
subs.push(client.bus.get("browse:click").subscribe(({ annotationId }) => {
|
|
2005
|
-
client.bus.get("beckon:focus").next({ annotationId });
|
|
2196
|
+
subs.push(client.bus.get("browse:click").subscribe(({ annotationId: annotationId2 }) => {
|
|
2197
|
+
client.bus.get("beckon:focus").next({ annotationId: annotationId2 });
|
|
2006
2198
|
}));
|
|
2007
2199
|
return {
|
|
2008
2200
|
hoveredAnnotationId$: hovered$.asObservable(),
|
|
2009
|
-
hover: (
|
|
2010
|
-
focus: (
|
|
2011
|
-
sparkle: (
|
|
2201
|
+
hover: (annotationId2) => client.bus.get("beckon:hover").next({ annotationId: annotationId2 }),
|
|
2202
|
+
focus: (annotationId2) => client.bus.get("beckon:focus").next({ annotationId: annotationId2 }),
|
|
2203
|
+
sparkle: (annotationId2) => client.bus.get("beckon:sparkle").next({ annotationId: annotationId2 }),
|
|
2012
2204
|
dispose() {
|
|
2013
2205
|
subs.forEach((s) => s.unsubscribe());
|
|
2014
2206
|
hovered$.complete();
|
|
@@ -2025,13 +2217,13 @@ function createHoverHandlers(emit, delayMs) {
|
|
|
2025
2217
|
timer = null;
|
|
2026
2218
|
}
|
|
2027
2219
|
};
|
|
2028
|
-
const handleMouseEnter = (
|
|
2029
|
-
if (currentHover ===
|
|
2220
|
+
const handleMouseEnter = (annotationId2) => {
|
|
2221
|
+
if (currentHover === annotationId2) return;
|
|
2030
2222
|
cancelTimer();
|
|
2031
2223
|
timer = setTimeout(() => {
|
|
2032
2224
|
timer = null;
|
|
2033
|
-
currentHover =
|
|
2034
|
-
emit(
|
|
2225
|
+
currentHover = annotationId2;
|
|
2226
|
+
emit(annotationId2);
|
|
2035
2227
|
}, delayMs);
|
|
2036
2228
|
};
|
|
2037
2229
|
const handleMouseLeave = () => {
|
|
@@ -2095,7 +2287,7 @@ function createShellVM(browser, options) {
|
|
|
2095
2287
|
}
|
|
2096
2288
|
};
|
|
2097
2289
|
}
|
|
2098
|
-
function createGatherVM(client,
|
|
2290
|
+
function createGatherVM(client, resourceId2) {
|
|
2099
2291
|
const subs = [];
|
|
2100
2292
|
const context$ = new BehaviorSubject(null);
|
|
2101
2293
|
const loading$ = new BehaviorSubject(false);
|
|
@@ -2108,7 +2300,7 @@ function createGatherVM(client, resourceId) {
|
|
|
2108
2300
|
annotationId$.next(annotationId(event.annotationId));
|
|
2109
2301
|
const gatherSub = client.gather.annotation(
|
|
2110
2302
|
annotationId(event.annotationId),
|
|
2111
|
-
|
|
2303
|
+
resourceId2,
|
|
2112
2304
|
{ contextWindow: event.options?.contextWindow ?? 2e3 }
|
|
2113
2305
|
).pipe(
|
|
2114
2306
|
timeout(6e4)
|
|
@@ -2150,7 +2342,7 @@ function createMatchVM(client, _resourceId) {
|
|
|
2150
2342
|
subs.push(client.bus.get("match:search-requested").subscribe((event) => {
|
|
2151
2343
|
const searchSub = client.match.search(
|
|
2152
2344
|
resourceId(event.resourceId),
|
|
2153
|
-
event.referenceId,
|
|
2345
|
+
annotationId(event.referenceId),
|
|
2154
2346
|
event.context,
|
|
2155
2347
|
{ limit: event.limit, useSemanticScoring: event.useSemanticScoring }
|
|
2156
2348
|
).pipe(
|
|
@@ -2171,14 +2363,14 @@ function createMatchVM(client, _resourceId) {
|
|
|
2171
2363
|
}
|
|
2172
2364
|
};
|
|
2173
2365
|
}
|
|
2174
|
-
function createYieldVM(client,
|
|
2366
|
+
function createYieldVM(client, resourceId2, locale) {
|
|
2175
2367
|
const subs = [];
|
|
2176
2368
|
const isGenerating$ = new BehaviorSubject(false);
|
|
2177
2369
|
const progress$ = new BehaviorSubject(null);
|
|
2178
2370
|
let clearTimer = null;
|
|
2179
2371
|
const generate = (referenceId, options) => {
|
|
2180
2372
|
const genSub = client.yield.fromAnnotation(
|
|
2181
|
-
resourceId(
|
|
2373
|
+
resourceId(resourceId2),
|
|
2182
2374
|
annotationId(referenceId),
|
|
2183
2375
|
{ ...options, language: options.language || locale }
|
|
2184
2376
|
).pipe(
|
|
@@ -2226,7 +2418,7 @@ function selectionToSelector(selection) {
|
|
|
2226
2418
|
}
|
|
2227
2419
|
return { type: "TextQuoteSelector", exact: selection.exact, ...selection.prefix && { prefix: selection.prefix }, ...selection.suffix && { suffix: selection.suffix } };
|
|
2228
2420
|
}
|
|
2229
|
-
function createMarkVM(client,
|
|
2421
|
+
function createMarkVM(client, resourceId2) {
|
|
2230
2422
|
const subs = [];
|
|
2231
2423
|
const pendingAnnotation$ = new BehaviorSubject(null);
|
|
2232
2424
|
const assistingMotivation$ = new BehaviorSubject(null);
|
|
@@ -2250,9 +2442,9 @@ function createMarkVM(client, resourceId) {
|
|
|
2250
2442
|
subs.push(client.bus.get("mark:create-ok").subscribe(() => pendingAnnotation$.next(null)));
|
|
2251
2443
|
subs.push(client.bus.get("mark:submit").subscribe(async (event) => {
|
|
2252
2444
|
try {
|
|
2253
|
-
const result = await client.mark.annotation(
|
|
2445
|
+
const result = await client.mark.annotation(resourceId2, {
|
|
2254
2446
|
motivation: event.motivation,
|
|
2255
|
-
target: { source:
|
|
2447
|
+
target: { source: resourceId2, selector: event.selector },
|
|
2256
2448
|
body: event.body
|
|
2257
2449
|
});
|
|
2258
2450
|
client.bus.get("mark:create-ok").next({ annotationId: result.annotationId });
|
|
@@ -2262,7 +2454,7 @@ function createMarkVM(client, resourceId) {
|
|
|
2262
2454
|
}));
|
|
2263
2455
|
subs.push(client.bus.get("mark:delete").subscribe(async (event) => {
|
|
2264
2456
|
try {
|
|
2265
|
-
await client.mark.delete(
|
|
2457
|
+
await client.mark.delete(resourceId2, event.annotationId);
|
|
2266
2458
|
client.bus.get("mark:delete-ok").next({ annotationId: event.annotationId });
|
|
2267
2459
|
} catch (error) {
|
|
2268
2460
|
client.bus.get("mark:delete-failed").next({ message: error instanceof Error ? error.message : String(error) });
|
|
@@ -2272,7 +2464,7 @@ function createMarkVM(client, resourceId) {
|
|
|
2272
2464
|
clearProgressTimer();
|
|
2273
2465
|
assistingMotivation$.next(event.motivation);
|
|
2274
2466
|
progress$.next(null);
|
|
2275
|
-
const assistSub = client.mark.assist(
|
|
2467
|
+
const assistSub = client.mark.assist(resourceId2, event.motivation, event.options).pipe(
|
|
2276
2468
|
timeout({ each: 18e4 })
|
|
2277
2469
|
).subscribe({
|
|
2278
2470
|
next: (e) => {
|
|
@@ -2560,14 +2752,14 @@ function createWelcomeVM(client) {
|
|
|
2560
2752
|
}
|
|
2561
2753
|
};
|
|
2562
2754
|
}
|
|
2563
|
-
function createResourceLoaderVM(client,
|
|
2564
|
-
const raw$ = client.browse.resource(
|
|
2755
|
+
function createResourceLoaderVM(client, resourceId2) {
|
|
2756
|
+
const raw$ = client.browse.resource(resourceId2);
|
|
2565
2757
|
const resource$ = raw$;
|
|
2566
2758
|
const isLoading$ = raw$.pipe(map$1((r) => r === void 0));
|
|
2567
2759
|
return {
|
|
2568
2760
|
resource$,
|
|
2569
2761
|
isLoading$,
|
|
2570
|
-
invalidate: () => client.browse.invalidateResourceDetail(
|
|
2762
|
+
invalidate: () => client.browse.invalidateResourceDetail(resourceId2),
|
|
2571
2763
|
dispose: () => {
|
|
2572
2764
|
}
|
|
2573
2765
|
};
|
|
@@ -2815,20 +3007,20 @@ var WIZARD_CLOSED = {
|
|
|
2815
3007
|
defaultTitle: "",
|
|
2816
3008
|
entityTypes: []
|
|
2817
3009
|
};
|
|
2818
|
-
function createResourceViewerPageVM(client,
|
|
3010
|
+
function createResourceViewerPageVM(client, resourceId2, locale, browse, options) {
|
|
2819
3011
|
const disposer = createDisposer();
|
|
2820
3012
|
const beckon = createBeckonVM(client);
|
|
2821
|
-
const mark = createMarkVM(client,
|
|
2822
|
-
const gather = createGatherVM(client,
|
|
3013
|
+
const mark = createMarkVM(client, resourceId2);
|
|
3014
|
+
const gather = createGatherVM(client, resourceId2);
|
|
2823
3015
|
const matchVM = createMatchVM(client);
|
|
2824
|
-
const yieldVM = createYieldVM(client,
|
|
3016
|
+
const yieldVM = createYieldVM(client, resourceId2, locale);
|
|
2825
3017
|
disposer.add(beckon);
|
|
2826
3018
|
disposer.add(browse);
|
|
2827
3019
|
disposer.add(mark);
|
|
2828
3020
|
disposer.add(gather);
|
|
2829
3021
|
disposer.add(matchVM);
|
|
2830
3022
|
disposer.add(yieldVM);
|
|
2831
|
-
const annotations$ = client.browse.annotations(
|
|
3023
|
+
const annotations$ = client.browse.annotations(resourceId2).pipe(
|
|
2832
3024
|
map$1((a) => a ?? [])
|
|
2833
3025
|
);
|
|
2834
3026
|
const annotationGroups$ = annotations$.pipe(
|
|
@@ -2847,10 +3039,10 @@ function createResourceViewerPageVM(client, resourceId, locale, browse, options)
|
|
|
2847
3039
|
const entityTypes$ = client.browse.entityTypes().pipe(
|
|
2848
3040
|
map$1((e) => e ?? [])
|
|
2849
3041
|
);
|
|
2850
|
-
const events$ = client.browse.events(
|
|
3042
|
+
const events$ = client.browse.events(resourceId2).pipe(
|
|
2851
3043
|
map$1((e) => e ?? [])
|
|
2852
3044
|
);
|
|
2853
|
-
const referencedBy$ = client.browse.referencedBy(
|
|
3045
|
+
const referencedBy$ = client.browse.referencedBy(resourceId2).pipe(
|
|
2854
3046
|
map$1((r) => r ?? [])
|
|
2855
3047
|
);
|
|
2856
3048
|
const content$ = new BehaviorSubject("");
|
|
@@ -2860,7 +3052,7 @@ function createResourceViewerPageVM(client, resourceId, locale, browse, options)
|
|
|
2860
3052
|
const isBinaryType = mediaType.startsWith("image/") || mediaType === "application/pdf";
|
|
2861
3053
|
if (!isBinaryType && mediaType) {
|
|
2862
3054
|
contentLoading$.next(true);
|
|
2863
|
-
client.browse.resourceRepresentation(
|
|
3055
|
+
client.browse.resourceRepresentation(resourceId2, { accept: mediaType }).then(({ data }) => {
|
|
2864
3056
|
content$.next(decodeWithCharset(data, mediaType));
|
|
2865
3057
|
contentLoading$.next(false);
|
|
2866
3058
|
}).catch(() => {
|
|
@@ -2868,11 +3060,11 @@ function createResourceViewerPageVM(client, resourceId, locale, browse, options)
|
|
|
2868
3060
|
});
|
|
2869
3061
|
}
|
|
2870
3062
|
if (isBinaryType) {
|
|
2871
|
-
client.auth.mediaToken(
|
|
3063
|
+
client.auth.mediaToken(resourceId2).then(({ token }) => mediaToken$.next(token)).catch(() => {
|
|
2872
3064
|
});
|
|
2873
3065
|
}
|
|
2874
3066
|
const wizard$ = new BehaviorSubject(WIZARD_CLOSED);
|
|
2875
|
-
const unsubscribeResource = client.subscribeToResource(
|
|
3067
|
+
const unsubscribeResource = client.subscribeToResource(resourceId2);
|
|
2876
3068
|
disposer.add(unsubscribeResource);
|
|
2877
3069
|
const bindInitiateSub = client.bus.get("bind:initiate").subscribe((event) => {
|
|
2878
3070
|
wizard$.next({
|
|
@@ -3025,6 +3217,6 @@ function createComposePageVM(client, browse, params, auth) {
|
|
|
3025
3217
|
};
|
|
3026
3218
|
}
|
|
3027
3219
|
|
|
3028
|
-
export { AdminNamespace, AuthNamespace, BeckonNamespace, BindNamespace, BrowseNamespace, BusRequestError, COMMON_PANELS, FrontendSessionSignals, GatherNamespace, HOVER_DELAY_MS, InMemorySessionStorage, JobNamespace, MarkNamespace, MatchNamespace, RESOURCE_PANELS, SemiontBrowser, SemiontClient,
|
|
3220
|
+
export { AdminNamespace, AuthNamespace, BeckonNamespace, BindNamespace, BrowseNamespace, BusRequestError, COMMON_PANELS, CacheObservable, FrontendSessionSignals, GatherNamespace, HOVER_DELAY_MS, InMemorySessionStorage, JobNamespace, MarkNamespace, MatchNamespace, RESOURCE_PANELS, SemiontBrowser, SemiontClient, SemiontSession, SemiontSessionError, StreamObservable, YieldNamespace, busRequest, createAdminSecurityVM, createAdminUsersVM, createBeckonVM, createCache, createComposePageVM, createDiscoverVM, createDisposer, createEntityTagsVM, createExchangeVM, createGatherVM, createHoverHandlers, createJobClaimAdapter, createJobQueueVM, createMarkVM, createMatchVM, createResourceLoaderVM, createResourceViewerPageVM, createSearchPipeline, createSessionVM, createShellVM, createSmelterActorVM, createWelcomeVM, createYieldVM, defaultProtocol, getBrowser, isValidHostname, kbBackendUrl, notifyPermissionDenied, notifySessionExpired, setStoredSession };
|
|
3029
3221
|
//# sourceMappingURL=index.js.map
|
|
3030
3222
|
//# sourceMappingURL=index.js.map
|