@semiont/sdk 0.5.0 → 0.5.2
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 +136 -44
- package/dist/index.d.ts +663 -609
- package/dist/index.js +672 -1147
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,31 +1,142 @@
|
|
|
1
1
|
import * as rxjs from 'rxjs';
|
|
2
2
|
import { Observable, BehaviorSubject, Subject } from 'rxjs';
|
|
3
|
+
export { firstValueFrom, lastValueFrom } from 'rxjs';
|
|
3
4
|
import * as _semiont_core from '@semiont/core';
|
|
4
|
-
import { components, UserDID, paths,
|
|
5
|
-
export { ConnectionState, Logger } from '@semiont/core';
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
import { ResourceId, components, UserDID, paths, BackendDownload, ProgressEvent, AnnotationId, BodyOperation, EventMap, ResourceDescriptor, Annotation, GraphConnection, Motivation, GatheredContext, JobId, ITransport, EventBus, IContentTransport, IBackendOperations, BaseUrl, AccessToken, SemiontError, ConnectionState, Selector } from '@semiont/core';
|
|
6
|
+
export { AccessToken, Annotation, AnnotationId, BaseUrl, BodyItem, BodyOperation, ConnectionState, EntityType, EventMap, GatheredContext, IContentTransport, ITransport, Logger, Motivation, RefreshToken, ResourceDescriptor, ResourceId, SemiontError, UserId, accessToken, annotationId, baseUrl, entityType, refreshToken, resourceId, userId } from '@semiont/core';
|
|
7
|
+
export { APIError, HttpContentTransport, HttpTransport, HttpTransportConfig, TokenRefresher } from '@semiont/api-client';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Thenable Observable subclasses.
|
|
11
|
+
*
|
|
12
|
+
* Two thin Observable subclasses that also implement `PromiseLike<T>`. Used as
|
|
13
|
+
* the public return type of namespace methods that emit streams (job
|
|
14
|
+
* lifecycle, generation progress) and cache reads (Browse live queries).
|
|
15
|
+
*
|
|
16
|
+
* The point: scripts can `await` the call directly without `lastValueFrom` /
|
|
17
|
+
* `firstValueFrom` wrappers; reactive consumers keep using `.subscribe(...)`
|
|
18
|
+
* and `.pipe(...)` exactly as before.
|
|
19
|
+
*
|
|
20
|
+
* The asymmetric `.then()` semantics — last-value-on-completion for streams,
|
|
21
|
+
* first-non-undefined-value for caches — is encoded by the subclass name. The
|
|
22
|
+
* docstring on the namespace method tells the consumer which one applies.
|
|
23
|
+
*
|
|
24
|
+
* `.pipe(...)` returns a plain `Observable<T>` (RxJS doesn't propagate
|
|
25
|
+
* subclasses through `pipe`). Once you compose, you've explicitly entered
|
|
26
|
+
* RxJS land; `lastValueFrom` from `rxjs` is the right bridge there.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Bounded Observable stream — emits zero-or-more progress values, then a
|
|
31
|
+
* final value on completion. Used by job-lifecycle methods like
|
|
32
|
+
* `mark.assist`, `gather.annotation`, `match.search`, `yield.fromAnnotation`.
|
|
33
|
+
*
|
|
34
|
+
* Awaiting resolves to the **last** emitted value (via `lastValueFrom`).
|
|
35
|
+
* Subscribing yields every emission, ending in `complete`.
|
|
36
|
+
*/
|
|
37
|
+
declare class StreamObservable<T> extends Observable<T> implements PromiseLike<T> {
|
|
38
|
+
then<R1 = T, R2 = never>(onfulfilled?: ((v: T) => R1 | PromiseLike<R1>) | null, onrejected?: ((e: unknown) => R2 | PromiseLike<R2>) | null): PromiseLike<R1 | R2>;
|
|
39
|
+
/** Wrap an existing Observable's subscribe behavior in a StreamObservable. */
|
|
40
|
+
static from<T>(source: Observable<T>): StreamObservable<T>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Multicast cache observable — emits `undefined` while the underlying value
|
|
44
|
+
* is loading, then the value, then re-emits when bus events invalidate the
|
|
45
|
+
* cache entry. Used by Browse live-query methods (`browse.resource`,
|
|
46
|
+
* `browse.annotations`, etc.).
|
|
47
|
+
*
|
|
48
|
+
* Awaiting resolves to the **first non-undefined** value (waits past the
|
|
49
|
+
* loading state). Subscribing yields the full sequence including the
|
|
50
|
+
* initial `undefined`, so reactive consumers can render a loading state.
|
|
51
|
+
*
|
|
52
|
+
* The class is parameterized as `CacheObservable<T>` even though the
|
|
53
|
+
* stream's element type is `T | undefined` — `T` is what the consumer
|
|
54
|
+
* gets from `await`, and that's the contract we want to advertise. The
|
|
55
|
+
* `Observable<T | undefined>` shape leaks through `.subscribe` and
|
|
56
|
+
* `.pipe` in the natural way.
|
|
57
|
+
*/
|
|
58
|
+
declare class CacheObservable<T> extends Observable<T | undefined> implements PromiseLike<T> {
|
|
59
|
+
then<R1 = T, R2 = never>(onfulfilled?: ((v: T) => R1 | PromiseLike<R1>) | null, onrejected?: ((e: unknown) => R2 | PromiseLike<R2>) | null): PromiseLike<R1 | R2>;
|
|
60
|
+
/**
|
|
61
|
+
* Wrap an existing Observable's subscribe behavior in a `CacheObservable`.
|
|
62
|
+
*
|
|
63
|
+
* Memoizes on source identity: passing the same `source` returns the same
|
|
64
|
+
* wrapper instance. The Browse cache primitive already returns a stable
|
|
65
|
+
* Observable per key (its B4 contract), so this preserves that contract
|
|
66
|
+
* through the awaitable wrapping. Without the memo, every public-method
|
|
67
|
+
* call would produce a fresh wrapper and break referential-equality
|
|
68
|
+
* guarantees that hook-style reactive consumers depend on.
|
|
69
|
+
*
|
|
70
|
+
* Backed by a `WeakMap`, so wrappers are GC'd when their source is.
|
|
71
|
+
*/
|
|
72
|
+
static from<T>(source: Observable<T | undefined>): CacheObservable<T>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Discriminated phases of an upload's lifecycle.
|
|
76
|
+
*
|
|
77
|
+
* - `started` — emitted immediately on `yield.resource(...)` invocation, before any bytes flow.
|
|
78
|
+
* - `progress` — emitted as bytes flow over the wire. Wired by `HttpContentTransport`'s XHR path when a caller passes `onProgress` (or, transitively, when `yield.resource` is the caller — it always wires the hook so subscribers see byte counts). `bytesUploaded` and `totalBytes` carry the running counts; `totalBytes` may be 0 when the transport can't determine the total (rare, e.g. chunked encoding) — UI consumers should render an indeterminate state in that case.
|
|
79
|
+
* - `finished` — emitted on backend acknowledgement, carries the assigned `resourceId`.
|
|
80
|
+
*
|
|
81
|
+
* Failures surface as `Observable.error(...)` (typically an `APIError` from the transport's `errors$` Subject), not as a `phase: 'failed'` event — `subscribe`'s error callback handles them. Cancellation is honored: unsubscribing before `finished` aborts the in-flight HTTP request on the XHR path.
|
|
82
|
+
*/
|
|
83
|
+
type UploadProgress = {
|
|
84
|
+
phase: 'started';
|
|
85
|
+
totalBytes: number;
|
|
86
|
+
} | {
|
|
87
|
+
phase: 'progress';
|
|
88
|
+
bytesUploaded: number;
|
|
89
|
+
totalBytes: number;
|
|
90
|
+
} | {
|
|
91
|
+
phase: 'finished';
|
|
92
|
+
resourceId: ResourceId;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Specialized `StreamObservable` for `yield.resource`. Subscribers see the
|
|
96
|
+
* full `UploadProgress` event sequence (started → optional progress → finished).
|
|
97
|
+
* Awaiting resolves specifically to `{ resourceId }` extracted from the
|
|
98
|
+
* `'finished'` event — preserving the pre-Phase-18 awaited shape so existing
|
|
99
|
+
* `await client.yield.resource(...)` callers don't need to narrow the union.
|
|
100
|
+
*/
|
|
101
|
+
declare class UploadObservable extends Observable<UploadProgress> implements PromiseLike<{
|
|
102
|
+
resourceId: ResourceId;
|
|
103
|
+
}> {
|
|
104
|
+
then<R1 = {
|
|
105
|
+
resourceId: ResourceId;
|
|
106
|
+
}, R2 = never>(onfulfilled?: ((v: {
|
|
107
|
+
resourceId: ResourceId;
|
|
108
|
+
}) => R1 | PromiseLike<R1>) | null, onrejected?: ((e: unknown) => R2 | PromiseLike<R2>) | null): PromiseLike<R1 | R2>;
|
|
109
|
+
}
|
|
8
110
|
|
|
9
111
|
/**
|
|
10
112
|
* Verb Namespace Interfaces
|
|
11
113
|
*
|
|
12
|
-
* These interfaces define the public API of
|
|
13
|
-
*
|
|
14
|
-
*
|
|
114
|
+
* These interfaces define the public API of `@semiont/sdk`, organized by
|
|
115
|
+
* the 7 domain flows (Browse, Mark, Bind, Gather, Match, Yield, Beckon)
|
|
116
|
+
* plus infrastructure namespaces (Job, Auth, Admin).
|
|
15
117
|
*
|
|
16
|
-
* Each namespace maps 1:1 to a flow. Each flow maps to a clear actor
|
|
17
|
-
*
|
|
18
|
-
*
|
|
118
|
+
* Each namespace maps 1:1 to a flow. Each flow maps to a clear actor on
|
|
119
|
+
* the backend. The frontend calls `client.mark.annotation()` and the
|
|
120
|
+
* client handles HTTP, auth, SSE, and caching internally.
|
|
19
121
|
*
|
|
20
122
|
* Return type conventions:
|
|
21
|
-
* - Browse live queries →
|
|
22
|
-
*
|
|
23
|
-
* -
|
|
24
|
-
* -
|
|
25
|
-
* -
|
|
123
|
+
* - Browse live queries → `CacheObservable<T>` (bus-driven, cached;
|
|
124
|
+
* subscribe yields `T | undefined`, await yields `T` after first load)
|
|
125
|
+
* - Browse one-shot reads → `Promise<T>` (fetch once, no cache)
|
|
126
|
+
* - Commands (mark, bind, yield.resource) → `Promise<T>` (atomic ops)
|
|
127
|
+
* - Long-running ops (gather, match, yield.fromAnnotation, mark.assist)
|
|
128
|
+
* → `StreamObservable<T>` (progress + result; subscribe yields every
|
|
129
|
+
* emit, await yields the last one)
|
|
130
|
+
* - Ephemeral signals (beckon) → `void`
|
|
131
|
+
*
|
|
132
|
+
* `StreamObservable` and `CacheObservable` are `Observable` subclasses
|
|
133
|
+
* that also implement `PromiseLike<T>` — `await client.X.Y(...)` works
|
|
134
|
+
* directly without `lastValueFrom`/`firstValueFrom` wrappers.
|
|
135
|
+
* `.pipe(...)` returns a plain `Observable<T>` (the thenable subclass
|
|
136
|
+
* does not propagate through pipe — by design).
|
|
26
137
|
*/
|
|
27
138
|
|
|
28
|
-
type StoredEventResponse$
|
|
139
|
+
type StoredEventResponse$1 = components['schemas']['StoredEventResponse'];
|
|
29
140
|
type GatherProgress = components['schemas']['GatherProgress'];
|
|
30
141
|
type MatchSearchResult = components['schemas']['MatchSearchResult'];
|
|
31
142
|
type JobProgress$2 = components['schemas']['JobProgress'];
|
|
@@ -92,7 +203,10 @@ interface GenerationOptions {
|
|
|
92
203
|
storageUri: string;
|
|
93
204
|
context: GatheredContext;
|
|
94
205
|
prompt?: string;
|
|
206
|
+
/** Annotation/resource body locale — language the generated resource is written in (typically the user's UI locale). */
|
|
95
207
|
language?: string;
|
|
208
|
+
/** Source-resource locale — language of the resource the annotation lives on, used in the prompt so the LLM understands embedded source-context snippets. BCP-47. */
|
|
209
|
+
sourceLanguage?: string;
|
|
96
210
|
temperature?: number;
|
|
97
211
|
maxTokens?: number;
|
|
98
212
|
}
|
|
@@ -103,7 +217,10 @@ interface MarkAssistOptions {
|
|
|
103
217
|
instructions?: string;
|
|
104
218
|
density?: number;
|
|
105
219
|
tone?: string;
|
|
220
|
+
/** Annotation body locale — language the LLM should write generated body text in (comment text, assessment text, tag/reference body language stamp). BCP-47. */
|
|
106
221
|
language?: string;
|
|
222
|
+
/** Source-resource locale — language of the content being analyzed, used in the prompt so the LLM analyzes non-English source correctly. BCP-47. */
|
|
223
|
+
sourceLanguage?: string;
|
|
107
224
|
schemaId?: string;
|
|
108
225
|
categories?: string[];
|
|
109
226
|
}
|
|
@@ -171,17 +288,17 @@ type YieldGenerationEvent = {
|
|
|
171
288
|
* Event prefix: browse:*
|
|
172
289
|
*/
|
|
173
290
|
interface BrowseNamespace$1 {
|
|
174
|
-
resource(resourceId: ResourceId):
|
|
291
|
+
resource(resourceId: ResourceId): CacheObservable<ResourceDescriptor>;
|
|
175
292
|
resources(filters?: {
|
|
176
293
|
limit?: number;
|
|
177
294
|
archived?: boolean;
|
|
178
295
|
search?: string;
|
|
179
|
-
}):
|
|
180
|
-
annotations(resourceId: ResourceId):
|
|
181
|
-
annotation(resourceId: ResourceId, annotationId: AnnotationId):
|
|
182
|
-
entityTypes():
|
|
183
|
-
referencedBy(resourceId: ResourceId):
|
|
184
|
-
events(resourceId: ResourceId):
|
|
296
|
+
}): CacheObservable<ResourceDescriptor[]>;
|
|
297
|
+
annotations(resourceId: ResourceId): CacheObservable<Annotation[]>;
|
|
298
|
+
annotation(resourceId: ResourceId, annotationId: AnnotationId): CacheObservable<Annotation>;
|
|
299
|
+
entityTypes(): CacheObservable<string[]>;
|
|
300
|
+
referencedBy(resourceId: ResourceId): CacheObservable<ReferencedByEntry[]>;
|
|
301
|
+
events(resourceId: ResourceId): CacheObservable<StoredEventResponse$1[]>;
|
|
185
302
|
resourceContent(resourceId: ResourceId): Promise<string>;
|
|
186
303
|
resourceRepresentation(resourceId: ResourceId, options?: {
|
|
187
304
|
accept?: string;
|
|
@@ -195,7 +312,7 @@ interface BrowseNamespace$1 {
|
|
|
195
312
|
stream: ReadableStream<Uint8Array>;
|
|
196
313
|
contentType: string;
|
|
197
314
|
}>;
|
|
198
|
-
resourceEvents(resourceId: ResourceId): Promise<StoredEventResponse$
|
|
315
|
+
resourceEvents(resourceId: ResourceId): Promise<StoredEventResponse$1[]>;
|
|
199
316
|
annotationHistory(resourceId: ResourceId, annotationId: AnnotationId): Promise<AnnotationHistoryResponse>;
|
|
200
317
|
connections(resourceId: ResourceId): Promise<GraphConnection[]>;
|
|
201
318
|
backlinks(resourceId: ResourceId): Promise<Annotation[]>;
|
|
@@ -205,7 +322,33 @@ interface BrowseNamespace$1 {
|
|
|
205
322
|
navigateReference(resourceId: ResourceId): void;
|
|
206
323
|
}
|
|
207
324
|
/**
|
|
208
|
-
*
|
|
325
|
+
* Frame — schema-layer flow (the eighth flow).
|
|
326
|
+
*
|
|
327
|
+
* Frame operates on the KB's conceptual vocabulary — what *kinds* of
|
|
328
|
+
* things exist (entity types) and, in the future, what taxonomies are
|
|
329
|
+
* recognized (tag schemas), what relations are typed (predicate types),
|
|
330
|
+
* and how schemas are imported (ontology I/O). The other seven flows
|
|
331
|
+
* (yield, mark, match, bind, gather, browse, beckon) operate on
|
|
332
|
+
* content; Frame operates on the schema layer that content is expressed
|
|
333
|
+
* in.
|
|
334
|
+
*
|
|
335
|
+
* MVP scope is small: entity-type vocabulary writes only. Live reads of
|
|
336
|
+
* the entity-type vocabulary stay on Browse (`browse.entityTypes()` is
|
|
337
|
+
* a `CacheObservable<string[]>` consumed by 8+ call sites). Frame owns
|
|
338
|
+
* writes; Browse owns reads — the same asymmetry that already holds for
|
|
339
|
+
* resources and annotations.
|
|
340
|
+
*
|
|
341
|
+
* Backend actor: Stower
|
|
342
|
+
* Event prefix: frame:*
|
|
343
|
+
*/
|
|
344
|
+
interface FrameNamespace$1 {
|
|
345
|
+
/** Add a single entity type to the KB's vocabulary. Idempotent — adding an existing type is a no-op. */
|
|
346
|
+
addEntityType(type: string): Promise<void>;
|
|
347
|
+
/** Add multiple entity types in one call. Convenience over a loop of `addEntityType`. */
|
|
348
|
+
addEntityTypes(types: string[]): Promise<void>;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Mark — annotation CRUD, AI assist, resource lifecycle
|
|
209
352
|
*
|
|
210
353
|
* Commands return Promises that resolve on HTTP acceptance (202).
|
|
211
354
|
* Results appear on browse Observables via bus gateway.
|
|
@@ -215,17 +358,15 @@ interface BrowseNamespace$1 {
|
|
|
215
358
|
* Event prefix: mark:*
|
|
216
359
|
*/
|
|
217
360
|
interface MarkNamespace$1 {
|
|
218
|
-
annotation(
|
|
219
|
-
annotationId:
|
|
361
|
+
annotation(input: CreateAnnotationInput): Promise<{
|
|
362
|
+
annotationId: AnnotationId;
|
|
220
363
|
}>;
|
|
221
364
|
delete(resourceId: ResourceId, annotationId: AnnotationId): Promise<void>;
|
|
222
|
-
entityType(type: string): Promise<void>;
|
|
223
|
-
entityTypes(types: string[]): Promise<void>;
|
|
224
365
|
archive(resourceId: ResourceId): Promise<void>;
|
|
225
366
|
unarchive(resourceId: ResourceId): Promise<void>;
|
|
226
|
-
assist(resourceId: ResourceId, motivation: Motivation, options: MarkAssistOptions):
|
|
367
|
+
assist(resourceId: ResourceId, motivation: Motivation, options: MarkAssistOptions): StreamObservable<MarkAssistEvent>;
|
|
227
368
|
request(selector: components['schemas']['MarkRequestedEvent']['selector'], motivation: Motivation): void;
|
|
228
|
-
/** Fire-and-forget variant of `assist` — mark-
|
|
369
|
+
/** Fire-and-forget variant of `assist` — mark-state-unit orchestrates the call and its progress Observable. */
|
|
229
370
|
requestAssist(motivation: Motivation, options: MarkAssistOptions, correlationId?: string): void;
|
|
230
371
|
/** Submit the currently pending annotation with its selector and optional body. */
|
|
231
372
|
submit(input: components['schemas']['MarkSubmitEvent']): void;
|
|
@@ -263,12 +404,12 @@ interface BindNamespace$1 {
|
|
|
263
404
|
* Event prefix: gather:*
|
|
264
405
|
*/
|
|
265
406
|
interface GatherNamespace$1 {
|
|
266
|
-
annotation(
|
|
407
|
+
annotation(resourceId: ResourceId, annotationId: AnnotationId, options?: {
|
|
267
408
|
contextWindow?: number;
|
|
268
|
-
}):
|
|
409
|
+
}): StreamObservable<GatherAnnotationProgress>;
|
|
269
410
|
resource(resourceId: ResourceId, options?: {
|
|
270
411
|
contextWindow?: number;
|
|
271
|
-
}):
|
|
412
|
+
}): StreamObservable<GatherAnnotationProgress>;
|
|
272
413
|
}
|
|
273
414
|
/**
|
|
274
415
|
* Match — search and ranking
|
|
@@ -280,11 +421,11 @@ interface GatherNamespace$1 {
|
|
|
280
421
|
* Event prefix: match:*
|
|
281
422
|
*/
|
|
282
423
|
interface MatchNamespace$1 {
|
|
283
|
-
search(resourceId: ResourceId, referenceId:
|
|
424
|
+
search(resourceId: ResourceId, referenceId: AnnotationId, context: GatheredContext, options?: {
|
|
284
425
|
limit?: number;
|
|
285
426
|
useSemanticScoring?: boolean;
|
|
286
|
-
}):
|
|
287
|
-
/** Fire-and-forget variant: match-
|
|
427
|
+
}): StreamObservable<MatchSearchProgress>;
|
|
428
|
+
/** Fire-and-forget variant: match-state-unit orchestrates the call and its result Observable. */
|
|
288
429
|
requestSearch(input: components['schemas']['MatchSearchRequest']): void;
|
|
289
430
|
}
|
|
290
431
|
/**
|
|
@@ -297,17 +438,15 @@ interface MatchNamespace$1 {
|
|
|
297
438
|
* Event prefix: yield:*
|
|
298
439
|
*/
|
|
299
440
|
interface YieldNamespace$1 {
|
|
300
|
-
resource(data: CreateResourceInput):
|
|
301
|
-
|
|
302
|
-
}>;
|
|
303
|
-
fromAnnotation(resourceId: ResourceId, annotationId: AnnotationId, options: GenerationOptions): Observable<YieldGenerationEvent>;
|
|
441
|
+
resource(data: CreateResourceInput): UploadObservable;
|
|
442
|
+
fromAnnotation(resourceId: ResourceId, annotationId: AnnotationId, options: GenerationOptions): StreamObservable<YieldGenerationEvent>;
|
|
304
443
|
cloneToken(resourceId: ResourceId): Promise<{
|
|
305
444
|
token: string;
|
|
306
445
|
expiresAt: string;
|
|
307
446
|
}>;
|
|
308
447
|
fromToken(token: string): Promise<ResourceDescriptor>;
|
|
309
448
|
createFromToken(options: CreateFromTokenOptions): Promise<{
|
|
310
|
-
resourceId:
|
|
449
|
+
resourceId: ResourceId;
|
|
311
450
|
}>;
|
|
312
451
|
/** UI signal: user invoked the clone action from the resource-info panel. */
|
|
313
452
|
clone(): void;
|
|
@@ -322,7 +461,7 @@ interface YieldNamespace$1 {
|
|
|
322
461
|
* Event prefix: beckon:*
|
|
323
462
|
*/
|
|
324
463
|
interface BeckonNamespace$1 {
|
|
325
|
-
attention(
|
|
464
|
+
attention(resourceId: ResourceId, annotationId: AnnotationId): void;
|
|
326
465
|
hover(annotationId: AnnotationId | null): void;
|
|
327
466
|
sparkle(annotationId: AnnotationId): void;
|
|
328
467
|
}
|
|
@@ -344,7 +483,7 @@ interface JobNamespace$1 {
|
|
|
344
483
|
timeout?: number;
|
|
345
484
|
onProgress?: (status: JobStatusResponse$1) => void;
|
|
346
485
|
}): Promise<JobStatusResponse$1>;
|
|
347
|
-
|
|
486
|
+
cancelByType(jobType: 'annotation' | 'generation'): Promise<void>;
|
|
348
487
|
/** UI signal: cancel all active jobs of a given type (e.g. "annotation"). */
|
|
349
488
|
cancelRequest(jobType: 'annotation' | 'generation'): void;
|
|
350
489
|
}
|
|
@@ -375,31 +514,21 @@ interface AdminNamespace$1 {
|
|
|
375
514
|
oauthConfig(): Promise<OAuthConfigResponse$1>;
|
|
376
515
|
healthCheck(): Promise<ResponseContent<paths['/api/health']['get']>>;
|
|
377
516
|
status(): Promise<ResponseContent<paths['/api/status']['get']>>;
|
|
378
|
-
backup(): Promise<
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
result?: Record<string, unknown>;
|
|
387
|
-
}>;
|
|
517
|
+
backup(): Promise<BackendDownload>;
|
|
518
|
+
/**
|
|
519
|
+
* Restore from a backup archive. Returns a `StreamObservable` that
|
|
520
|
+
* emits each `ProgressEvent` as the operation runs (`'started'`,
|
|
521
|
+
* `'parsing'`, `'importing'`, ..., `'complete'`). Subscribers see
|
|
522
|
+
* every step; awaiters get the final event via the PromiseLike sugar.
|
|
523
|
+
*/
|
|
524
|
+
restore(file: File): StreamObservable<ProgressEvent>;
|
|
388
525
|
exportKnowledgeBase(params?: {
|
|
389
526
|
includeArchived?: boolean;
|
|
390
|
-
}): Promise<
|
|
391
|
-
importKnowledgeBase(file: File
|
|
392
|
-
phase: string;
|
|
393
|
-
message?: string;
|
|
394
|
-
result?: Record<string, unknown>;
|
|
395
|
-
}) => void): Promise<{
|
|
396
|
-
phase: string;
|
|
397
|
-
message?: string;
|
|
398
|
-
result?: Record<string, unknown>;
|
|
399
|
-
}>;
|
|
527
|
+
}): Promise<BackendDownload>;
|
|
528
|
+
importKnowledgeBase(file: File): StreamObservable<ProgressEvent>;
|
|
400
529
|
}
|
|
401
530
|
|
|
402
|
-
type StoredEventResponse
|
|
531
|
+
type StoredEventResponse = components['schemas']['StoredEventResponse'];
|
|
403
532
|
type ResourceListFilters = {
|
|
404
533
|
limit?: number;
|
|
405
534
|
archived?: boolean;
|
|
@@ -437,13 +566,13 @@ declare class BrowseNamespace implements BrowseNamespace$1 {
|
|
|
437
566
|
*/
|
|
438
567
|
private readonly annotationListObs;
|
|
439
568
|
constructor(transport: ITransport, bus: EventBus, content: IContentTransport);
|
|
440
|
-
resource(resourceId: ResourceId):
|
|
441
|
-
resources(filters?: ResourceListFilters):
|
|
442
|
-
annotations(resourceId: ResourceId):
|
|
443
|
-
annotation(resourceId: ResourceId, annotationId: AnnotationId):
|
|
444
|
-
entityTypes():
|
|
445
|
-
referencedBy(resourceId: ResourceId):
|
|
446
|
-
events(resourceId: ResourceId):
|
|
569
|
+
resource(resourceId: ResourceId): CacheObservable<ResourceDescriptor>;
|
|
570
|
+
resources(filters?: ResourceListFilters): CacheObservable<ResourceDescriptor[]>;
|
|
571
|
+
annotations(resourceId: ResourceId): CacheObservable<Annotation[]>;
|
|
572
|
+
annotation(resourceId: ResourceId, annotationId: AnnotationId): CacheObservable<Annotation>;
|
|
573
|
+
entityTypes(): CacheObservable<string[]>;
|
|
574
|
+
referencedBy(resourceId: ResourceId): CacheObservable<ReferencedByEntry[]>;
|
|
575
|
+
events(resourceId: ResourceId): CacheObservable<StoredEventResponse[]>;
|
|
447
576
|
resourceContent(resourceId: ResourceId): Promise<string>;
|
|
448
577
|
resourceRepresentation(resourceId: ResourceId, options?: {
|
|
449
578
|
accept?: string;
|
|
@@ -457,7 +586,7 @@ declare class BrowseNamespace implements BrowseNamespace$1 {
|
|
|
457
586
|
stream: ReadableStream<Uint8Array>;
|
|
458
587
|
contentType: string;
|
|
459
588
|
}>;
|
|
460
|
-
resourceEvents(resourceId: ResourceId): Promise<StoredEventResponse
|
|
589
|
+
resourceEvents(resourceId: ResourceId): Promise<StoredEventResponse[]>;
|
|
461
590
|
annotationHistory(resourceId: ResourceId, annotationId: AnnotationId): Promise<AnnotationHistoryResponse>;
|
|
462
591
|
connections(_resourceId: ResourceId): Promise<GraphConnection[]>;
|
|
463
592
|
backlinks(_resourceId: ResourceId): Promise<Annotation[]>;
|
|
@@ -506,15 +635,13 @@ declare class MarkNamespace implements MarkNamespace$1 {
|
|
|
506
635
|
private readonly transport;
|
|
507
636
|
private readonly bus;
|
|
508
637
|
constructor(transport: ITransport, bus: EventBus);
|
|
509
|
-
annotation(
|
|
510
|
-
annotationId:
|
|
638
|
+
annotation(input: CreateAnnotationInput): Promise<{
|
|
639
|
+
annotationId: AnnotationId;
|
|
511
640
|
}>;
|
|
512
641
|
delete(resourceId: ResourceId, annotationId: AnnotationId): Promise<void>;
|
|
513
|
-
entityType(type: string): Promise<void>;
|
|
514
|
-
entityTypes(types: string[]): Promise<void>;
|
|
515
642
|
archive(resourceId: ResourceId): Promise<void>;
|
|
516
643
|
unarchive(resourceId: ResourceId): Promise<void>;
|
|
517
|
-
assist(resourceId: ResourceId, motivation: Motivation, options: MarkAssistOptions):
|
|
644
|
+
assist(resourceId: ResourceId, motivation: Motivation, options: MarkAssistOptions): StreamObservable<MarkAssistEvent>;
|
|
518
645
|
request(selector: components['schemas']['MarkRequestedEvent']['selector'], motivation: Motivation): void;
|
|
519
646
|
requestAssist(motivation: Motivation, options: MarkAssistOptions, correlationId?: string): void;
|
|
520
647
|
submit(input: components['schemas']['MarkSubmitEvent']): void;
|
|
@@ -539,12 +666,12 @@ declare class GatherNamespace implements GatherNamespace$1 {
|
|
|
539
666
|
private readonly transport;
|
|
540
667
|
private readonly bus;
|
|
541
668
|
constructor(transport: ITransport, bus: EventBus);
|
|
542
|
-
annotation(
|
|
669
|
+
annotation(resourceId: ResourceId, annotationId: AnnotationId, options?: {
|
|
543
670
|
contextWindow?: number;
|
|
544
|
-
}):
|
|
671
|
+
}): StreamObservable<GatherAnnotationProgress>;
|
|
545
672
|
resource(_resourceId: ResourceId, _options?: {
|
|
546
673
|
contextWindow?: number;
|
|
547
|
-
}):
|
|
674
|
+
}): StreamObservable<GatherAnnotationProgress>;
|
|
548
675
|
}
|
|
549
676
|
|
|
550
677
|
declare class MatchNamespace implements MatchNamespace$1 {
|
|
@@ -552,10 +679,10 @@ declare class MatchNamespace implements MatchNamespace$1 {
|
|
|
552
679
|
private readonly bus;
|
|
553
680
|
constructor(transport: ITransport, bus: EventBus);
|
|
554
681
|
requestSearch(input: components['schemas']['MatchSearchRequest']): void;
|
|
555
|
-
search(resourceId: ResourceId, referenceId:
|
|
682
|
+
search(resourceId: ResourceId, referenceId: AnnotationId, context: GatheredContext, options?: {
|
|
556
683
|
limit?: number;
|
|
557
684
|
useSemanticScoring?: boolean;
|
|
558
|
-
}):
|
|
685
|
+
}): StreamObservable<MatchSearchProgress>;
|
|
559
686
|
}
|
|
560
687
|
|
|
561
688
|
declare class YieldNamespace implements YieldNamespace$1 {
|
|
@@ -563,17 +690,15 @@ declare class YieldNamespace implements YieldNamespace$1 {
|
|
|
563
690
|
private readonly bus;
|
|
564
691
|
private readonly content;
|
|
565
692
|
constructor(transport: ITransport, bus: EventBus, content: IContentTransport);
|
|
566
|
-
resource(data: CreateResourceInput):
|
|
567
|
-
|
|
568
|
-
}>;
|
|
569
|
-
fromAnnotation(resourceId: ResourceId, annotationId: AnnotationId, options: GenerationOptions): Observable<YieldGenerationEvent>;
|
|
693
|
+
resource(data: CreateResourceInput): UploadObservable;
|
|
694
|
+
fromAnnotation(resourceId: ResourceId, annotationId: AnnotationId, options: GenerationOptions): StreamObservable<YieldGenerationEvent>;
|
|
570
695
|
cloneToken(resourceId: ResourceId): Promise<{
|
|
571
696
|
token: string;
|
|
572
697
|
expiresAt: string;
|
|
573
698
|
}>;
|
|
574
699
|
fromToken(token: string): Promise<ResourceDescriptor>;
|
|
575
700
|
createFromToken(options: CreateFromTokenOptions): Promise<{
|
|
576
|
-
resourceId:
|
|
701
|
+
resourceId: ResourceId;
|
|
577
702
|
}>;
|
|
578
703
|
clone(): void;
|
|
579
704
|
}
|
|
@@ -582,11 +707,38 @@ declare class BeckonNamespace implements BeckonNamespace$1 {
|
|
|
582
707
|
private readonly transport;
|
|
583
708
|
private readonly bus;
|
|
584
709
|
constructor(transport: ITransport, bus: EventBus);
|
|
585
|
-
attention(
|
|
710
|
+
attention(resourceId: ResourceId, annotationId: AnnotationId): void;
|
|
586
711
|
hover(annotationId: AnnotationId | null): void;
|
|
587
712
|
sparkle(annotationId: AnnotationId): void;
|
|
588
713
|
}
|
|
589
714
|
|
|
715
|
+
/**
|
|
716
|
+
* FrameNamespace — the eighth flow's surface.
|
|
717
|
+
*
|
|
718
|
+
* Frame operates on the KB's **schema layer** — the conceptual vocabulary
|
|
719
|
+
* the other seven flows are expressed in. Where yield/mark/match/bind/
|
|
720
|
+
* gather/browse/beckon act on content (resources, annotations, references,
|
|
721
|
+
* attention), Frame acts on what *kinds* of things exist: entity types,
|
|
722
|
+
* eventually tag schemas, relation/predicate types, ontology imports.
|
|
723
|
+
*
|
|
724
|
+
* The MVP owns a single primitive — entity-type vocabulary writes on the
|
|
725
|
+
* `frame:add-entity-type` channel. See `docs/protocol/flows/FRAME.md`
|
|
726
|
+
* for the per-flow contract.
|
|
727
|
+
*
|
|
728
|
+
* Live reads of the entity-type vocabulary stay on Browse
|
|
729
|
+
* (`browse.entityTypes()` is a `CacheObservable<string[]>`). Frame owns
|
|
730
|
+
* writes; Browse owns reads. The asymmetry is intentional — re-implementing
|
|
731
|
+
* Browse's cache primitives on Frame for a single read would duplicate
|
|
732
|
+
* machinery without benefit.
|
|
733
|
+
*/
|
|
734
|
+
|
|
735
|
+
declare class FrameNamespace implements FrameNamespace$1 {
|
|
736
|
+
private readonly transport;
|
|
737
|
+
constructor(transport: ITransport);
|
|
738
|
+
addEntityType(type: string): Promise<void>;
|
|
739
|
+
addEntityTypes(types: string[]): Promise<void>;
|
|
740
|
+
}
|
|
741
|
+
|
|
590
742
|
type JobStatusResponse = components['schemas']['JobStatusResponse'];
|
|
591
743
|
declare class JobNamespace implements JobNamespace$1 {
|
|
592
744
|
private readonly transport;
|
|
@@ -610,19 +762,19 @@ declare class JobNamespace implements JobNamespace$1 {
|
|
|
610
762
|
timeout?: number;
|
|
611
763
|
onProgress?: (status: JobStatusResponse) => void;
|
|
612
764
|
}): Promise<JobStatusResponse>;
|
|
613
|
-
|
|
765
|
+
cancelByType(jobType: 'annotation' | 'generation'): Promise<void>;
|
|
614
766
|
cancelRequest(jobType: 'annotation' | 'generation'): void;
|
|
615
767
|
}
|
|
616
768
|
|
|
617
769
|
/**
|
|
618
|
-
* AuthNamespace — authentication.
|
|
770
|
+
* AuthNamespace — authentication. Backend ops only; no bus.
|
|
619
771
|
*/
|
|
620
772
|
|
|
621
773
|
type AuthResponse = components['schemas']['AuthResponse'];
|
|
622
774
|
type TokenRefreshResponse = components['schemas']['TokenRefreshResponse'];
|
|
623
775
|
declare class AuthNamespace implements AuthNamespace$1 {
|
|
624
|
-
private readonly
|
|
625
|
-
constructor(
|
|
776
|
+
private readonly backend;
|
|
777
|
+
constructor(backend: IBackendOperations);
|
|
626
778
|
password(emailStr: string, passwordStr: string): Promise<AuthResponse>;
|
|
627
779
|
google(credential: string): Promise<AuthResponse>;
|
|
628
780
|
refresh(token: string): Promise<TokenRefreshResponse>;
|
|
@@ -638,42 +790,26 @@ declare class AuthNamespace implements AuthNamespace$1 {
|
|
|
638
790
|
}
|
|
639
791
|
|
|
640
792
|
/**
|
|
641
|
-
* AdminNamespace — administration.
|
|
793
|
+
* AdminNamespace — administration. Backend ops only; no bus.
|
|
642
794
|
*/
|
|
643
795
|
|
|
644
796
|
type AdminUserStatsResponse = components['schemas']['AdminUserStatsResponse'];
|
|
645
797
|
type OAuthConfigResponse = components['schemas']['OAuthConfigResponse'];
|
|
646
798
|
declare class AdminNamespace implements AdminNamespace$1 {
|
|
647
|
-
private readonly
|
|
648
|
-
constructor(
|
|
799
|
+
private readonly backend;
|
|
800
|
+
constructor(backend: IBackendOperations);
|
|
649
801
|
users(): Promise<User[]>;
|
|
650
802
|
userStats(): Promise<AdminUserStatsResponse>;
|
|
651
803
|
updateUser(userId: UserDID, data: RequestContent<paths['/api/admin/users/{id}']['patch']>): Promise<User>;
|
|
652
804
|
oauthConfig(): Promise<OAuthConfigResponse>;
|
|
653
805
|
healthCheck(): Promise<ResponseContent<paths['/api/health']['get']>>;
|
|
654
806
|
status(): Promise<ResponseContent<paths['/api/status']['get']>>;
|
|
655
|
-
backup(): Promise<
|
|
656
|
-
restore(file: File
|
|
657
|
-
phase: string;
|
|
658
|
-
message?: string;
|
|
659
|
-
result?: Record<string, unknown>;
|
|
660
|
-
}) => void): Promise<{
|
|
661
|
-
phase: string;
|
|
662
|
-
message?: string;
|
|
663
|
-
result?: Record<string, unknown>;
|
|
664
|
-
}>;
|
|
807
|
+
backup(): Promise<BackendDownload>;
|
|
808
|
+
restore(file: File): StreamObservable<ProgressEvent>;
|
|
665
809
|
exportKnowledgeBase(params?: {
|
|
666
810
|
includeArchived?: boolean;
|
|
667
|
-
}): Promise<
|
|
668
|
-
importKnowledgeBase(file: File
|
|
669
|
-
phase: string;
|
|
670
|
-
message?: string;
|
|
671
|
-
result?: Record<string, unknown>;
|
|
672
|
-
}) => void): Promise<{
|
|
673
|
-
phase: string;
|
|
674
|
-
message?: string;
|
|
675
|
-
result?: Record<string, unknown>;
|
|
676
|
-
}>;
|
|
811
|
+
}): Promise<BackendDownload>;
|
|
812
|
+
importKnowledgeBase(file: File): StreamObservable<ProgressEvent>;
|
|
677
813
|
}
|
|
678
814
|
|
|
679
815
|
declare class SemiontClient {
|
|
@@ -694,6 +830,7 @@ declare class SemiontClient {
|
|
|
694
830
|
*/
|
|
695
831
|
readonly bus: EventBus;
|
|
696
832
|
readonly baseUrl: BaseUrl;
|
|
833
|
+
readonly frame: FrameNamespace;
|
|
697
834
|
readonly browse: BrowseNamespace;
|
|
698
835
|
readonly mark: MarkNamespace;
|
|
699
836
|
readonly bind: BindNamespace;
|
|
@@ -702,8 +839,8 @@ declare class SemiontClient {
|
|
|
702
839
|
readonly yield: YieldNamespace;
|
|
703
840
|
readonly beckon: BeckonNamespace;
|
|
704
841
|
readonly job: JobNamespace;
|
|
705
|
-
readonly auth: AuthNamespace;
|
|
706
|
-
readonly admin: AdminNamespace;
|
|
842
|
+
readonly auth: AuthNamespace | undefined;
|
|
843
|
+
readonly admin: AdminNamespace | undefined;
|
|
707
844
|
/**
|
|
708
845
|
* The client *owns* its bus. The constructor creates a fresh `EventBus`
|
|
709
846
|
* and hands it to the transport via `transport.bridgeInto(this.bus)`.
|
|
@@ -716,16 +853,78 @@ declare class SemiontClient {
|
|
|
716
853
|
* Callers do not pass a bus in. If they need to interact with the bus
|
|
717
854
|
* (e.g. for tests or to subscribe to arbitrary channels), they read it
|
|
718
855
|
* back via `client.bus`.
|
|
856
|
+
*
|
|
857
|
+
* `backend` is optional. When provided, the `auth` and `admin`
|
|
858
|
+
* namespaces are constructed against it; when omitted, they're
|
|
859
|
+
* `undefined`. For HTTP setups this is conventionally the same
|
|
860
|
+
* `HttpTransport` instance that's also passed as `transport` (HTTP
|
|
861
|
+
* implements both `ITransport` and `IBackendOperations`).
|
|
719
862
|
*/
|
|
720
|
-
constructor(transport: ITransport, content: IContentTransport);
|
|
863
|
+
constructor(transport: ITransport, content: IContentTransport, backend?: IBackendOperations);
|
|
721
864
|
/** Transport-level connection state. HTTP reflects SSE health; local is always 'connected'. */
|
|
722
865
|
get state$(): rxjs.Observable<_semiont_core.ConnectionState>;
|
|
723
866
|
subscribeToResource(resourceId: ResourceId): () => void;
|
|
724
867
|
dispose(): void;
|
|
868
|
+
/**
|
|
869
|
+
* Convenience factory for the default HTTP setup. Constructs a
|
|
870
|
+
* `BehaviorSubject<AccessToken | null>` internally, plus an
|
|
871
|
+
* `HttpTransport` and `HttpContentTransport`, and returns the wired
|
|
872
|
+
* `SemiontClient`.
|
|
873
|
+
*
|
|
874
|
+
* Use this for one-shot scripts, CLI commands, or any consumer that
|
|
875
|
+
* doesn't need to drive the token from outside (no manual refresh,
|
|
876
|
+
* no cross-tab sync). For long-running scripts that need refresh,
|
|
877
|
+
* use `SemiontSession.fromHttp(...)` (with a token already on hand)
|
|
878
|
+
* or `SemiontSession.signInHttp(...)` (credentials-first) instead —
|
|
879
|
+
* either owns the same transport/client wiring plus the
|
|
880
|
+
* proactive-refresh + storage machinery.
|
|
881
|
+
*
|
|
882
|
+
* Strings are accepted for `baseUrl` and `token`; they are branded
|
|
883
|
+
* via `baseUrl()` / `accessToken()` from `@semiont/core` automatically.
|
|
884
|
+
* Pass the already-branded values if you have them.
|
|
885
|
+
*
|
|
886
|
+
* Omit `token` for unauthenticated usage (public endpoints only).
|
|
887
|
+
*/
|
|
888
|
+
static fromHttp(opts: {
|
|
889
|
+
baseUrl: BaseUrl | string;
|
|
890
|
+
token?: AccessToken | string | null;
|
|
891
|
+
}): SemiontClient;
|
|
892
|
+
/**
|
|
893
|
+
* Async factory for the credentials-first script case. Builds a
|
|
894
|
+
* transient HTTP transport, calls `auth.password(email, password)`
|
|
895
|
+
* to acquire an access token, and returns the wired client with
|
|
896
|
+
* the token populated.
|
|
897
|
+
*
|
|
898
|
+
* This is the right entry point for skills, CLI scripts, and any
|
|
899
|
+
* consumer that starts with email + password rather than a JWT
|
|
900
|
+
* already on hand. For consumers that already hold a token (CLI
|
|
901
|
+
* cached-token path, env-var token, embedded auth flow), use
|
|
902
|
+
* `fromHttp({ baseUrl, token })` instead.
|
|
903
|
+
*
|
|
904
|
+
* For long-running scripts that need refresh, use
|
|
905
|
+
* `SemiontSession.signInHttp(...)` — same credentials shape, plus
|
|
906
|
+
* the session machinery for proactive refresh and persistence.
|
|
907
|
+
*
|
|
908
|
+
* Named `signInHttp` because email+password authentication is
|
|
909
|
+
* inherently an HTTP-shaped operation in the current backend; an
|
|
910
|
+
* in-process `LocalTransport` doesn't have a credentials login
|
|
911
|
+
* path. Non-HTTP transports construct the client directly from
|
|
912
|
+
* their package's transport instance.
|
|
913
|
+
*
|
|
914
|
+
* Throws if authentication fails. The transient client is disposed
|
|
915
|
+
* before the throw, so no resources leak on failure.
|
|
916
|
+
*/
|
|
917
|
+
static signInHttp(opts: {
|
|
918
|
+
baseUrl: BaseUrl | string;
|
|
919
|
+
email: string;
|
|
920
|
+
password: string;
|
|
921
|
+
}): Promise<SemiontClient>;
|
|
725
922
|
}
|
|
726
923
|
|
|
727
|
-
|
|
728
|
-
|
|
924
|
+
type BusRequestErrorCode = 'bus.timeout' | 'bus.rejected' | 'bus.bad-payload' | 'bus.unauthorized' | 'bus.forbidden' | 'bus.not-found';
|
|
925
|
+
declare class BusRequestError extends SemiontError {
|
|
926
|
+
code: BusRequestErrorCode;
|
|
927
|
+
constructor(message: string, code: BusRequestErrorCode, details?: Record<string, unknown>);
|
|
729
928
|
}
|
|
730
929
|
/**
|
|
731
930
|
* Subset of ITransport that `busRequest` needs: a way to send a command and
|
|
@@ -739,76 +938,49 @@ interface BusRequestPrimitive {
|
|
|
739
938
|
declare function busRequest<TResult>(bus: BusRequestPrimitive, emitChannel: string, payload: Record<string, unknown>, resultChannel: string, failureChannel: string, timeoutMs?: number): Promise<TResult>;
|
|
740
939
|
|
|
741
940
|
/**
|
|
742
|
-
*
|
|
743
|
-
*
|
|
744
|
-
*
|
|
745
|
-
*
|
|
746
|
-
*
|
|
747
|
-
* `
|
|
748
|
-
*
|
|
749
|
-
*
|
|
750
|
-
*
|
|
751
|
-
*
|
|
752
|
-
*
|
|
753
|
-
*
|
|
754
|
-
* - `invalidate(key)`: stale-while-revalidate — keeps the current
|
|
755
|
-
* value visible to observers, clears the in-flight guard, starts a
|
|
756
|
-
* fresh fetch. If the previous fetch was orphaned (SSE torn down,
|
|
757
|
-
* response lost), this is how the cache recovers.
|
|
758
|
-
* - `remove(key)`: drops the cache entry entirely. Used for entity
|
|
759
|
-
* deletions (B13a). No refetch.
|
|
760
|
-
* - `set(key, value)`: writes through without a fetch. Used when a
|
|
761
|
-
* bus event carries the new value inline (B13b).
|
|
762
|
-
* - `invalidateAll()`: per-key SWR refetch of every currently-cached
|
|
763
|
-
* entry. Used by gap-detection paths.
|
|
764
|
-
* - `dispose()`: completes the store so observers unsubscribe.
|
|
765
|
-
*
|
|
766
|
-
* What's deliberately out:
|
|
767
|
-
* - No subscriber ref-counting / GC of unobserved keys. The per-key
|
|
768
|
-
* observable memo grows with the set of observed keys for the cache's
|
|
769
|
-
* lifetime (B11). Acceptable given cache lifetime == client lifetime.
|
|
770
|
-
* - No TTL / cacheTime. Entries are evicted only by explicit remove.
|
|
771
|
-
* - No retry / backoff. A failing fetch leaves the cache unchanged
|
|
772
|
-
* (B6); the caller drives retry via invalidate.
|
|
773
|
-
*/
|
|
774
|
-
|
|
775
|
-
interface Cache<K, V> {
|
|
776
|
-
/** Observable stream of the value at `key`. Triggers a fetch if not cached. */
|
|
777
|
-
observe(key: K): Observable<V | undefined>;
|
|
778
|
-
/** Synchronous snapshot of the current value, without triggering a fetch. */
|
|
779
|
-
get(key: K): V | undefined;
|
|
780
|
-
/** Iterator of currently-cached keys. For invalidateAll and diagnostics. */
|
|
781
|
-
keys(): K[];
|
|
782
|
-
/**
|
|
783
|
-
* Mark the entry stale and refetch. Keeps the previous value visible
|
|
784
|
-
* to observers during the refetch (stale-while-revalidate).
|
|
785
|
-
*/
|
|
786
|
-
invalidate(key: K): void;
|
|
787
|
-
/** Drop the entry from the cache. No refetch. */
|
|
788
|
-
remove(key: K): void;
|
|
789
|
-
/** Write-through: set the value directly without a fetch. */
|
|
790
|
-
set(key: K, value: V): void;
|
|
791
|
-
/** Per-key SWR refetch of every currently-cached entry. */
|
|
792
|
-
invalidateAll(): void;
|
|
793
|
-
/** Release the underlying subject. Observers complete. */
|
|
794
|
-
dispose(): void;
|
|
795
|
-
}
|
|
796
|
-
declare function createCache<K, V>(fetchFn: (key: K) => Promise<V>): Cache<K, V>;
|
|
797
|
-
|
|
798
|
-
/**
|
|
799
|
-
* KnowledgeBase — a connection to a Semiont backend instance.
|
|
941
|
+
* KnowledgeBase — a connection to a Semiont knowledge system.
|
|
942
|
+
*
|
|
943
|
+
* The KB type itself is uniform. The transport-shape variation lives in
|
|
944
|
+
* the nested `endpoint` field, which is a discriminated union:
|
|
945
|
+
*
|
|
946
|
+
* - `endpoint.kind === 'http'` — a remote backend reached over HTTP+SSE.
|
|
947
|
+
* Carries `host`/`port`/`protocol`.
|
|
948
|
+
* - `endpoint.kind === 'local'` — an in-process knowledge system reached
|
|
949
|
+
* via `LocalTransport` from
|
|
950
|
+
* `@semiont/make-meaning`. Carries an
|
|
951
|
+
* opaque `kbId` identifying the local
|
|
952
|
+
* instance to the host process.
|
|
800
953
|
*
|
|
801
|
-
*
|
|
802
|
-
*
|
|
954
|
+
* Code that doesn't know how to make a transport (`SemiontSession`,
|
|
955
|
+
* `SemiontBrowser`, the frontend KB list UI) treats `KnowledgeBase` as
|
|
956
|
+
* uniform and never inspects `endpoint`. Code that *does* construct
|
|
957
|
+
* transports (the transport-factory passed to `SemiontBrowser`,
|
|
958
|
+
* `kbBackendUrl` for HTTP URL construction) inspects `endpoint.kind`
|
|
959
|
+
* and dispatches.
|
|
960
|
+
*
|
|
961
|
+
* Each KB has its own session, its own credentials (where applicable),
|
|
962
|
+
* and its own JWT (HTTP only). The user is "authenticated against KB X" —
|
|
963
|
+
* never globally authenticated.
|
|
803
964
|
*/
|
|
965
|
+
/** Fields shared by every KB regardless of endpoint kind. */
|
|
804
966
|
interface KnowledgeBase {
|
|
805
967
|
id: string;
|
|
806
968
|
label: string;
|
|
969
|
+
email: string;
|
|
970
|
+
gitBranch?: string;
|
|
971
|
+
endpoint: KbEndpoint;
|
|
972
|
+
}
|
|
973
|
+
type KbEndpoint = HttpEndpoint | LocalEndpoint;
|
|
974
|
+
interface HttpEndpoint {
|
|
975
|
+
kind: 'http';
|
|
807
976
|
host: string;
|
|
808
977
|
port: number;
|
|
809
978
|
protocol: 'http' | 'https';
|
|
810
|
-
|
|
811
|
-
|
|
979
|
+
}
|
|
980
|
+
interface LocalEndpoint {
|
|
981
|
+
kind: 'local';
|
|
982
|
+
/** Opaque identifier for the in-process KB instance the host has loaded. */
|
|
983
|
+
kbId: string;
|
|
812
984
|
}
|
|
813
985
|
/**
|
|
814
986
|
* Input shape for adding a new KB. The id is generated by the provider.
|
|
@@ -819,18 +991,63 @@ type NewKnowledgeBase = Omit<KnowledgeBase, 'id'>;
|
|
|
819
991
|
* presence and validity of the JWT in session storage.
|
|
820
992
|
*/
|
|
821
993
|
type KbSessionStatus = 'authenticated' | 'expired' | 'signed-out' | 'unreachable';
|
|
994
|
+
/**
|
|
995
|
+
* Construct a `KnowledgeBase` for an HTTP-backed Semiont backend without
|
|
996
|
+
* spelling out the nested `endpoint` literal. Convenience for tests,
|
|
997
|
+
* worker bootstraps, and one-off scripts.
|
|
998
|
+
*
|
|
999
|
+
* ```ts
|
|
1000
|
+
* const kb = httpKb({
|
|
1001
|
+
* id: 'my-watcher',
|
|
1002
|
+
* label: 'My Watcher',
|
|
1003
|
+
* email: 'me@example.com',
|
|
1004
|
+
* host: 'localhost',
|
|
1005
|
+
* port: 4000,
|
|
1006
|
+
* protocol: 'http',
|
|
1007
|
+
* });
|
|
1008
|
+
* ```
|
|
1009
|
+
*
|
|
1010
|
+
* Equivalent to:
|
|
1011
|
+
*
|
|
1012
|
+
* ```ts
|
|
1013
|
+
* const kb: KnowledgeBase = {
|
|
1014
|
+
* id, label, email,
|
|
1015
|
+
* endpoint: { kind: 'http', host, port, protocol },
|
|
1016
|
+
* };
|
|
1017
|
+
* ```
|
|
1018
|
+
*
|
|
1019
|
+
* UI hosts that have a structured form (host / port / protocol pickers)
|
|
1020
|
+
* already construct the literal directly — they don't need this helper.
|
|
1021
|
+
* Local-endpoint KBs construct the literal directly too; the local
|
|
1022
|
+
* endpoint shape (`{ kind: 'local', kbId }`) is one line and doesn't
|
|
1023
|
+
* earn a helper.
|
|
1024
|
+
*/
|
|
1025
|
+
declare function httpKb(opts: {
|
|
1026
|
+
id: string;
|
|
1027
|
+
label: string;
|
|
1028
|
+
email: string;
|
|
1029
|
+
host: string;
|
|
1030
|
+
port: number;
|
|
1031
|
+
protocol: 'http' | 'https';
|
|
1032
|
+
gitBranch?: string;
|
|
1033
|
+
}): KnowledgeBase;
|
|
822
1034
|
|
|
823
1035
|
/**
|
|
824
1036
|
* Session-level error surface. Emitted on `SemiontBrowser.error$` for
|
|
825
1037
|
* failures that make the session itself unusable (auth failed, actor
|
|
826
1038
|
* couldn't start, token refresh terminally exhausted). Per-request
|
|
827
1039
|
* errors stay with the caller as normal Promise rejections.
|
|
1040
|
+
*
|
|
1041
|
+
* `SemiontSessionError` extends `SemiontError` (the unified Semiont base)
|
|
1042
|
+
* so consumers can catch with `instanceof SemiontError` for any error
|
|
1043
|
+
* surfaced through the SDK.
|
|
828
1044
|
*/
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
1045
|
+
|
|
1046
|
+
type SemiontSessionErrorCode = 'session.construct-failed' | 'session.auth-failed' | 'session.refresh-exhausted' | 'browser.sign-in-failed';
|
|
1047
|
+
declare class SemiontSessionError extends SemiontError {
|
|
1048
|
+
code: SemiontSessionErrorCode;
|
|
832
1049
|
readonly kbId: string | null;
|
|
833
|
-
constructor(code:
|
|
1050
|
+
constructor(code: SemiontSessionErrorCode, message: string, kbId?: string | null);
|
|
834
1051
|
}
|
|
835
1052
|
|
|
836
1053
|
/**
|
|
@@ -882,7 +1099,7 @@ declare class InMemorySessionStorage implements SessionStorage {
|
|
|
882
1099
|
*
|
|
883
1100
|
* Headless by design. Runs in browsers, CLIs, workers, and tests.
|
|
884
1101
|
* UI-specific state (session-expired/permission-denied modals) lives
|
|
885
|
-
* in `
|
|
1102
|
+
* in `SessionSignals`, which wraps a session — the session
|
|
886
1103
|
* itself has no modal observables, no user-facing notifications.
|
|
887
1104
|
*
|
|
888
1105
|
* Auth is parameterized via callbacks passed at construction:
|
|
@@ -898,9 +1115,9 @@ declare class InMemorySessionStorage implements SessionStorage {
|
|
|
898
1115
|
* worker omits this (service principals have no user record).
|
|
899
1116
|
*
|
|
900
1117
|
* - `onAuthFailed(message)` — optional. Invoked when refresh
|
|
901
|
-
* terminally fails (expired token, no recovery possible).
|
|
902
|
-
*
|
|
903
|
-
*
|
|
1118
|
+
* terminally fails (expired token, no recovery possible). UI hosts
|
|
1119
|
+
* typically wire this to `SessionSignals.notifySessionExpired` so a
|
|
1120
|
+
* modal surfaces; headless consumers typically just log.
|
|
904
1121
|
*
|
|
905
1122
|
* Persistence goes through a `SessionStorage` adapter provided at
|
|
906
1123
|
* construction — the session never touches `localStorage` or `window`
|
|
@@ -944,7 +1161,7 @@ interface SemiontSessionConfig {
|
|
|
944
1161
|
*/
|
|
945
1162
|
onAuthFailed?: (message: string | null) => void;
|
|
946
1163
|
/** Called for session-level failures (auth, refresh exhaustion). */
|
|
947
|
-
onError?: (err:
|
|
1164
|
+
onError?: (err: SemiontSessionError) => void;
|
|
948
1165
|
}
|
|
949
1166
|
declare class SemiontSession {
|
|
950
1167
|
readonly kb: KnowledgeBase;
|
|
@@ -952,6 +1169,18 @@ declare class SemiontSession {
|
|
|
952
1169
|
readonly token$: BehaviorSubject<AccessToken | null>;
|
|
953
1170
|
readonly user$: BehaviorSubject<UserInfo | null>;
|
|
954
1171
|
readonly streamState$: Observable<ConnectionState>;
|
|
1172
|
+
/**
|
|
1173
|
+
* Stream of `SemiontError` instances surfaced by the underlying transport
|
|
1174
|
+
* just before they're thrown to the caller. For `HttpTransport` this is
|
|
1175
|
+
* an `APIError` (status-coded); other transports emit their own subclass.
|
|
1176
|
+
* Surfaced here so a host layer (e.g. `SemiontBrowser`) can route by
|
|
1177
|
+
* `err.code` to global notifications without every call site handling
|
|
1178
|
+
* errors itself. Headless consumers can subscribe for logging.
|
|
1179
|
+
*
|
|
1180
|
+
* Re-published from `client.transport.errors$` per the `ITransport`
|
|
1181
|
+
* contract — the session is purely a passthrough.
|
|
1182
|
+
*/
|
|
1183
|
+
readonly errors$: Observable<SemiontError>;
|
|
955
1184
|
/** Resolves after the initial validation round-trip completes (success or failure). */
|
|
956
1185
|
readonly ready: Promise<void>;
|
|
957
1186
|
private readonly storage;
|
|
@@ -1001,6 +1230,67 @@ declare class SemiontSession {
|
|
|
1001
1230
|
*/
|
|
1002
1231
|
subscribe<K extends keyof EventMap>(channel: K, handler: (payload: EventMap[K]) => void): () => void;
|
|
1003
1232
|
dispose(): Promise<void>;
|
|
1233
|
+
/**
|
|
1234
|
+
* Convenience factory for the default HTTP setup. Constructs the
|
|
1235
|
+
* shared `BehaviorSubject<AccessToken | null>`, an `HttpTransport`,
|
|
1236
|
+
* an `HttpContentTransport`, and a `SemiontClient`, then wires
|
|
1237
|
+
* the session over them. Removes the load-bearing
|
|
1238
|
+
* "same-token$-instance" invariant from the caller's hands.
|
|
1239
|
+
*
|
|
1240
|
+
* Strings are accepted for `baseUrl` and `token`; they are branded
|
|
1241
|
+
* via `baseUrl()` / `accessToken()` from `@semiont/core` automatically.
|
|
1242
|
+
*
|
|
1243
|
+
* The remaining options (`refresh`, `validate`, `onAuthFailed`,
|
|
1244
|
+
* `onError`) match `SemiontSessionConfig` exactly.
|
|
1245
|
+
*/
|
|
1246
|
+
static fromHttp(opts: {
|
|
1247
|
+
kb: KnowledgeBase;
|
|
1248
|
+
storage: SessionStorage;
|
|
1249
|
+
baseUrl: BaseUrl | string;
|
|
1250
|
+
token?: AccessToken | string | null;
|
|
1251
|
+
refresh?: () => Promise<string | null>;
|
|
1252
|
+
validate?: (token: AccessToken) => Promise<UserInfo | null>;
|
|
1253
|
+
onAuthFailed?: (message: string | null) => void;
|
|
1254
|
+
onError?: (err: SemiontSessionError) => void;
|
|
1255
|
+
}): SemiontSession;
|
|
1256
|
+
/**
|
|
1257
|
+
* Async factory for the credentials-first long-running script case.
|
|
1258
|
+
* Builds the HTTP transport stack, calls `auth.password(email,
|
|
1259
|
+
* password)` to acquire access + refresh tokens, persists them via
|
|
1260
|
+
* the storage adapter, wires a default `refresh` callback that
|
|
1261
|
+
* exchanges the refresh token via `auth.refresh(...)`, and returns
|
|
1262
|
+
* the ready session.
|
|
1263
|
+
*
|
|
1264
|
+
* The consumer-supplied `refresh` callback becomes optional — only
|
|
1265
|
+
* needed for non-standard refresh flows (worker-pool shared secret,
|
|
1266
|
+
* OAuth refresh-token grant, interactive re-prompt). The default
|
|
1267
|
+
* uses the refresh token returned by `auth.password`.
|
|
1268
|
+
*
|
|
1269
|
+
* `kb` is required and must be a full `KnowledgeBase`. The `id` field
|
|
1270
|
+
* is the storage key for this session — distinct scripts sharing the
|
|
1271
|
+
* same `SessionStorage` instance must use distinct ids to avoid
|
|
1272
|
+
* trampling each other's tokens. The factory does not synthesize a
|
|
1273
|
+
* default; the consumer makes the choice.
|
|
1274
|
+
*
|
|
1275
|
+
* Named `signInHttp` because email+password authentication is
|
|
1276
|
+
* inherently an HTTP-shaped operation in the current backend; an
|
|
1277
|
+
* in-process `LocalTransport` doesn't have a credentials login
|
|
1278
|
+
* path. Non-HTTP transports construct the session directly from
|
|
1279
|
+
* their package's transport instance.
|
|
1280
|
+
*
|
|
1281
|
+
* Throws on auth failure with no resources leaked. On success, the
|
|
1282
|
+
* returned session's `ready` promise has already resolved.
|
|
1283
|
+
*/
|
|
1284
|
+
static signInHttp(opts: {
|
|
1285
|
+
kb: KnowledgeBase;
|
|
1286
|
+
storage: SessionStorage;
|
|
1287
|
+
baseUrl: BaseUrl | string;
|
|
1288
|
+
email: string;
|
|
1289
|
+
password: string;
|
|
1290
|
+
validate?: (token: AccessToken) => Promise<UserInfo | null>;
|
|
1291
|
+
onAuthFailed?: (message: string | null) => void;
|
|
1292
|
+
onError?: (err: SemiontSessionError) => void;
|
|
1293
|
+
}): Promise<SemiontSession>;
|
|
1004
1294
|
}
|
|
1005
1295
|
|
|
1006
1296
|
/**
|
|
@@ -1026,36 +1316,33 @@ interface OpenResource {
|
|
|
1026
1316
|
}
|
|
1027
1317
|
|
|
1028
1318
|
/**
|
|
1029
|
-
*
|
|
1030
|
-
* the session itself.
|
|
1319
|
+
* SessionSignals — UI-facing notification state that belongs to the host
|
|
1320
|
+
* surface, not to the session itself.
|
|
1031
1321
|
*
|
|
1032
1322
|
* `SemiontSession` is a headless per-backend client + token + user
|
|
1033
1323
|
* holder. It can run in any process: browser, worker, CLI, test. But
|
|
1034
|
-
* the session-expired / permission-denied *
|
|
1035
|
-
*
|
|
1036
|
-
*
|
|
1037
|
-
*
|
|
1324
|
+
* the session-expired / permission-denied *notifications* are inherently
|
|
1325
|
+
* a UI-host concern. Keeping those observables on `SemiontSession` meant
|
|
1326
|
+
* workers and CLIs carried four dead BehaviorSubjects that nothing would
|
|
1327
|
+
* ever fire.
|
|
1038
1328
|
*
|
|
1039
|
-
* `
|
|
1040
|
-
*
|
|
1041
|
-
* every
|
|
1329
|
+
* `SessionSignals` owns the notification state and has no hard reference
|
|
1330
|
+
* to a session. A UI host (e.g. `SemiontBrowser`) constructs one alongside
|
|
1331
|
+
* every active session and wires:
|
|
1042
1332
|
*
|
|
1043
1333
|
* - `session.onAuthFailed` → `signals.notifySessionExpired` so
|
|
1044
|
-
* proactive-refresh failures surface as
|
|
1045
|
-
* - `notify` module handlers → the active signals' methods so
|
|
1046
|
-
* external callers (e.g. React Query's QueryCache.onError) can
|
|
1047
|
-
* trigger the modals without touching the session
|
|
1334
|
+
* proactive-refresh failures surface as a notification
|
|
1048
1335
|
*
|
|
1049
|
-
*
|
|
1050
|
-
* that need bus/HTTP access continue to subscribe to the session.
|
|
1336
|
+
* UI consumers that need to render modal/banner state subscribe here;
|
|
1337
|
+
* consumers that need bus/HTTP access continue to subscribe to the session.
|
|
1051
1338
|
*
|
|
1052
1339
|
* Session auth-state cleanup (clearing token, clearing storage) is
|
|
1053
1340
|
* the session's own responsibility inside `refresh()` — by the time
|
|
1054
1341
|
* `notifySessionExpired` runs, the session has already torn down.
|
|
1055
|
-
* Signals only surfaces the
|
|
1342
|
+
* Signals only surfaces the notification.
|
|
1056
1343
|
*/
|
|
1057
1344
|
|
|
1058
|
-
declare class
|
|
1345
|
+
declare class SessionSignals {
|
|
1059
1346
|
readonly sessionExpiredAt$: BehaviorSubject<number | null>;
|
|
1060
1347
|
readonly sessionExpiredMessage$: BehaviorSubject<string | null>;
|
|
1061
1348
|
readonly permissionDeniedAt$: BehaviorSubject<number | null>;
|
|
@@ -1068,14 +1355,46 @@ declare class FrontendSessionSignals {
|
|
|
1068
1355
|
dispose(): void;
|
|
1069
1356
|
}
|
|
1070
1357
|
|
|
1358
|
+
/**
|
|
1359
|
+
* SessionFactory — the injection point that lets `SemiontBrowser` stay
|
|
1360
|
+
* transport-agnostic.
|
|
1361
|
+
*
|
|
1362
|
+
* The browser knows how to manage the *lifecycle* of an active session
|
|
1363
|
+
* (track it in `activeSession$`, dispose on KB switch, serialize
|
|
1364
|
+
* overlapping activations) but does not know how to *construct* one —
|
|
1365
|
+
* because that's where transport choice lives. The construction step
|
|
1366
|
+
* is parameterized via this factory.
|
|
1367
|
+
*
|
|
1368
|
+
* The HTTP factory is provided by `createHttpSessionFactory`. A
|
|
1369
|
+
* future in-process variant from `@semiont/make-meaning` would expose
|
|
1370
|
+
* its own factory.
|
|
1371
|
+
*/
|
|
1372
|
+
|
|
1373
|
+
interface SessionFactoryOptions {
|
|
1374
|
+
/** The KB the session is being constructed for. */
|
|
1375
|
+
kb: KnowledgeBase;
|
|
1376
|
+
/** Persistence adapter — same one the browser uses. */
|
|
1377
|
+
storage: SessionStorage;
|
|
1378
|
+
/** Modal-signal sink for auth-failed / permission-denied notifications. */
|
|
1379
|
+
signals: SessionSignals;
|
|
1380
|
+
/** Receives session-level errors (auth-failed, refresh-exhausted, ...). */
|
|
1381
|
+
onError: (err: SemiontSessionError) => void;
|
|
1382
|
+
}
|
|
1383
|
+
type SessionFactory = (opts: SessionFactoryOptions) => SemiontSession;
|
|
1384
|
+
|
|
1071
1385
|
/**
|
|
1072
1386
|
* SemiontBrowser — top-level app-facing container for non-KB state.
|
|
1073
1387
|
*
|
|
1074
1388
|
* Holds the list of configured KBs, the active KB selection, the active
|
|
1075
1389
|
* SemiontSession, the identity token, the open-resources list, and a
|
|
1076
|
-
* session-level error stream.
|
|
1077
|
-
*
|
|
1078
|
-
*
|
|
1390
|
+
* session-level error stream. Held as a process-wide instance for the
|
|
1391
|
+
* host's lifetime — see `getBrowser()` in `registry.ts` for the canonical
|
|
1392
|
+
* accessor.
|
|
1393
|
+
*
|
|
1394
|
+
* Transport-agnostic: the browser orchestrates session *lifecycle* but
|
|
1395
|
+
* delegates session *construction* to a `SessionFactory` injected at
|
|
1396
|
+
* construction. HTTP-backed apps pass `createHttpSessionFactory()` from
|
|
1397
|
+
* `@semiont/sdk`; in-process apps pass their own factory.
|
|
1079
1398
|
*
|
|
1080
1399
|
* Persistence goes through a `SessionStorage` adapter provided at
|
|
1081
1400
|
* construction — the browser never touches `localStorage` or `window`
|
|
@@ -1085,6 +1404,14 @@ declare class FrontendSessionSignals {
|
|
|
1085
1404
|
interface SemiontBrowserConfig {
|
|
1086
1405
|
/** Persistence adapter. The browser reads/writes all persisted state via this. */
|
|
1087
1406
|
storage: SessionStorage;
|
|
1407
|
+
/**
|
|
1408
|
+
* Builds a `SemiontSession` for a KB. The browser is transport-
|
|
1409
|
+
* agnostic — every HTTP-vs-local construction concern lives in the
|
|
1410
|
+
* factory. HTTP-backed apps pass `createHttpSessionFactory()` from
|
|
1411
|
+
* `@semiont/sdk`; a future in-process variant from `@semiont/make-meaning`
|
|
1412
|
+
* would expose its own factory.
|
|
1413
|
+
*/
|
|
1414
|
+
sessionFactory: SessionFactory;
|
|
1088
1415
|
}
|
|
1089
1416
|
declare class SemiontBrowser {
|
|
1090
1417
|
readonly kbs$: BehaviorSubject<KnowledgeBase[]>;
|
|
@@ -1096,9 +1423,9 @@ declare class SemiontBrowser {
|
|
|
1096
1423
|
* non-null when `activeSession$` is non-null, always null when it
|
|
1097
1424
|
* is. Extracted from the session itself so headless sessions
|
|
1098
1425
|
* (workers, CLIs, tests) don't carry dead modal observables.
|
|
1099
|
-
* See [
|
|
1426
|
+
* See [SessionSignals](./session-signals.ts).
|
|
1100
1427
|
*/
|
|
1101
|
-
readonly activeSignals$: BehaviorSubject<
|
|
1428
|
+
readonly activeSignals$: BehaviorSubject<SessionSignals | null>;
|
|
1102
1429
|
/**
|
|
1103
1430
|
* True while a session is actively being constructed (setActiveKb /
|
|
1104
1431
|
* signIn in flight, awaiting `session.ready`). Distinguishes the
|
|
@@ -1109,9 +1436,10 @@ declare class SemiontBrowser {
|
|
|
1109
1436
|
*/
|
|
1110
1437
|
readonly sessionActivating$: BehaviorSubject<boolean>;
|
|
1111
1438
|
readonly openResources$: BehaviorSubject<OpenResource[]>;
|
|
1112
|
-
readonly error$: Subject<
|
|
1439
|
+
readonly error$: Subject<SemiontSessionError>;
|
|
1113
1440
|
readonly identityToken$: BehaviorSubject<string | null>;
|
|
1114
1441
|
private readonly storage;
|
|
1442
|
+
private readonly sessionFactory;
|
|
1115
1443
|
/**
|
|
1116
1444
|
* App-scoped EventBus. Hosts UI-shell events that must work regardless
|
|
1117
1445
|
* of whether a KB session is active: panel toggles, sidebar state,
|
|
@@ -1120,18 +1448,9 @@ declare class SemiontBrowser {
|
|
|
1120
1448
|
* (mark:*, beckon:*, gather:*, match:*, bind:*, yield:*, browse:click).
|
|
1121
1449
|
*/
|
|
1122
1450
|
private readonly eventBus;
|
|
1123
|
-
private unregisterNotify;
|
|
1124
1451
|
private unsubscribeStorage;
|
|
1125
1452
|
private disposed;
|
|
1126
1453
|
private activating;
|
|
1127
|
-
/**
|
|
1128
|
-
* Per-KB in-flight refresh dedup. Simultaneous 401s for the same
|
|
1129
|
-
* KB converge on a single `/api/tokens/refresh` network call.
|
|
1130
|
-
* Was previously module-scoped in `refresh.ts`; moved here when
|
|
1131
|
-
* that file was deleted — SemiontBrowser is a singleton so the
|
|
1132
|
-
* scoping is equivalent.
|
|
1133
|
-
*/
|
|
1134
|
-
private readonly inFlightRefreshes;
|
|
1135
1454
|
constructor(config: SemiontBrowserConfig);
|
|
1136
1455
|
/** Emit an event on the browser's app-scoped bus. */
|
|
1137
1456
|
emit<K extends keyof EventMap>(channel: K, payload: EventMap[K]): void;
|
|
@@ -1140,14 +1459,25 @@ declare class SemiontBrowser {
|
|
|
1140
1459
|
/** Read-only observable for an app-scoped channel. */
|
|
1141
1460
|
stream<K extends keyof EventMap>(channel: K): Observable<EventMap[K]>;
|
|
1142
1461
|
/**
|
|
1143
|
-
* Set the app-level identity token
|
|
1144
|
-
*
|
|
1145
|
-
*
|
|
1462
|
+
* Set the app-level identity token. Sourced from whatever the host
|
|
1463
|
+
* environment uses for OAuth sessions (e.g. NextAuth in a browser app).
|
|
1464
|
+
* Should be called once from the host's startup-and-on-change site;
|
|
1465
|
+
* no other code should write to this slot.
|
|
1146
1466
|
*/
|
|
1147
1467
|
setIdentityToken(token: string | null): void;
|
|
1148
1468
|
addKb(input: NewKnowledgeBase, access: string, refresh: string): KnowledgeBase;
|
|
1149
1469
|
removeKb(id: string): void;
|
|
1150
|
-
|
|
1470
|
+
/**
|
|
1471
|
+
* Patch a KB in the list. Restricted to the common, endpoint-agnostic
|
|
1472
|
+
* fields (`label`, `email`, `gitBranch`) — the `endpoint` shape isn't
|
|
1473
|
+
* editable in place; remove and re-add to change the connection
|
|
1474
|
+
* target.
|
|
1475
|
+
*/
|
|
1476
|
+
updateKb(id: string, updates: {
|
|
1477
|
+
label?: string;
|
|
1478
|
+
email?: string;
|
|
1479
|
+
gitBranch?: string;
|
|
1480
|
+
}): void;
|
|
1151
1481
|
/**
|
|
1152
1482
|
* Read the locally-stored credential status for a KB. Pure / synchronous —
|
|
1153
1483
|
* does not subscribe to context changes. Used by KB-list UI to color status
|
|
@@ -1182,46 +1512,45 @@ declare class SemiontBrowser {
|
|
|
1182
1512
|
removeOpenResource(id: string): void;
|
|
1183
1513
|
updateOpenResourceName(id: string, name: string): void;
|
|
1184
1514
|
reorderOpenResources(oldIndex: number, newIndex: number): void;
|
|
1185
|
-
/**
|
|
1186
|
-
* Refresh the active KB's access token. Returns the new token on
|
|
1187
|
-
* success, null on failure. Concurrent calls for the same KB
|
|
1188
|
-
* dedupe through `inFlightRefreshes`, so simultaneous 401s trigger
|
|
1189
|
-
* only one `/api/tokens/refresh` round trip.
|
|
1190
|
-
*
|
|
1191
|
-
* Uses a throwaway `SemiontClient` with no `tokenRefresher` —
|
|
1192
|
-
* a refresh call returning 401 would otherwise re-enter this
|
|
1193
|
-
* function infinitely.
|
|
1194
|
-
*/
|
|
1195
|
-
private performRefresh;
|
|
1196
|
-
/**
|
|
1197
|
-
* Validate an access token by calling `auth.me` on a throwaway
|
|
1198
|
-
* client. The session uses this once at startup to populate
|
|
1199
|
-
* `user$`; 401 triggers a refresh-then-retry inside the session.
|
|
1200
|
-
*
|
|
1201
|
-
* The throwaway transport is seeded with the specific token to
|
|
1202
|
-
* validate so the request actually carries it (HttpTransport
|
|
1203
|
-
* sources `Authorization` from its `token$`).
|
|
1204
|
-
*/
|
|
1205
|
-
private performValidate;
|
|
1206
1515
|
dispose(): Promise<void>;
|
|
1207
1516
|
}
|
|
1208
1517
|
|
|
1209
1518
|
/**
|
|
1210
|
-
*
|
|
1211
|
-
*
|
|
1212
|
-
*
|
|
1213
|
-
*
|
|
1214
|
-
*
|
|
1215
|
-
*
|
|
1216
|
-
*
|
|
1217
|
-
*
|
|
1218
|
-
*
|
|
1219
|
-
*
|
|
1519
|
+
* createHttpSessionFactory — the default `SessionFactory` for HTTP-backed
|
|
1520
|
+
* KBs. Owns every HTTP-specific construction concern that used to live in
|
|
1521
|
+
* `SemiontBrowser`: building `HttpTransport`/`HttpContentTransport`,
|
|
1522
|
+
* wiring the `tokenRefresher` callback, deduplicating concurrent 401
|
|
1523
|
+
* refresh round trips, and invoking the auth endpoints for token refresh
|
|
1524
|
+
* and user-validate.
|
|
1525
|
+
*
|
|
1526
|
+
* Returned as a closure so a single `inFlightRefreshes` map is shared
|
|
1527
|
+
* across every session this factory builds — the dedup is meaningful
|
|
1528
|
+
* across concurrent session reactivations for the same KB id.
|
|
1529
|
+
*/
|
|
1530
|
+
|
|
1531
|
+
declare function createHttpSessionFactory(): SessionFactory;
|
|
1532
|
+
|
|
1533
|
+
/**
|
|
1534
|
+
* Process-wide accessor for `SemiontBrowser`. Constructed lazily on the
|
|
1535
|
+
* first `getBrowser()` call and held for the host's lifetime — a single
|
|
1536
|
+
* instance owns the KB list, identity token, and active-session state,
|
|
1537
|
+
* so callers throughout the host get the same view of "which KB am I
|
|
1538
|
+
* talking to right now" regardless of where they pick it up.
|
|
1539
|
+
*
|
|
1540
|
+
* The caller provides a `SessionStorage` implementation and a
|
|
1541
|
+
* `SessionFactory` — both are environment-specific (browsers use
|
|
1542
|
+
* `WebBrowserStorage` + `createHttpSessionFactory()`, CLI/embedded
|
|
1543
|
+
* hosts use a filesystem adapter and possibly a local-process
|
|
1544
|
+
* factory, tests use `InMemorySessionStorage` and stubs). The first
|
|
1545
|
+
* call to `getBrowser` wins; subsequent calls return the cached
|
|
1546
|
+
* instance regardless of the options passed.
|
|
1220
1547
|
*/
|
|
1221
1548
|
|
|
1222
1549
|
interface GetBrowserOptions {
|
|
1223
1550
|
/** Persistence adapter used to construct the singleton on first call. */
|
|
1224
1551
|
storage: SessionStorage;
|
|
1552
|
+
/** Session factory used to build a `SemiontSession` per active KB. */
|
|
1553
|
+
sessionFactory: SessionFactory;
|
|
1225
1554
|
}
|
|
1226
1555
|
declare function getBrowser(options: GetBrowserOptions): SemiontBrowser;
|
|
1227
1556
|
|
|
@@ -1248,16 +1577,45 @@ interface StoredSession {
|
|
|
1248
1577
|
declare function setStoredSession(storage: SessionStorage, kbId: string, session: StoredSession): void;
|
|
1249
1578
|
declare function defaultProtocol(host: string): 'http' | 'https';
|
|
1250
1579
|
declare function isValidHostname(host: string): boolean;
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1580
|
+
/**
|
|
1581
|
+
* Build the wire URL for an HTTP KB endpoint. HTTP-shaped helper —
|
|
1582
|
+
* lives next to the KB list machinery because the frontend Panel needs
|
|
1583
|
+
* it for the auth round-trip when adding a KB. Code that holds a
|
|
1584
|
+
* uniform `KnowledgeBase` should not call this; it should hand the KB
|
|
1585
|
+
* to a transport factory and let the factory inspect `endpoint.kind`.
|
|
1586
|
+
*/
|
|
1587
|
+
declare function kbBackendUrl(endpoint: HttpEndpoint): string;
|
|
1255
1588
|
|
|
1256
|
-
|
|
1589
|
+
/**
|
|
1590
|
+
* Marker for the state-unit pattern: a stateful, lifecycled object with an
|
|
1591
|
+
* RxJS-shaped public surface, constructed by a factory function
|
|
1592
|
+
* (`createFooStateUnit`), with internal state held in a closure.
|
|
1593
|
+
*
|
|
1594
|
+
* The structural contract is `dispose()` — the rest of the pattern
|
|
1595
|
+
* (closure-based identity, Observable public surface, internal Subjects
|
|
1596
|
+
* exposed as `.asObservable()` views, no leaked subscriptions, composition
|
|
1597
|
+
* by parameter rather than ownership) is convention enforced by review,
|
|
1598
|
+
* not the type system.
|
|
1599
|
+
*
|
|
1600
|
+
* See `packages/sdk/docs/STATE-UNITS.md` for the full axioms and rationale.
|
|
1601
|
+
*/
|
|
1602
|
+
interface StateUnit {
|
|
1603
|
+
/**
|
|
1604
|
+
* Idempotent, total teardown. Completes every Subject the unit owns,
|
|
1605
|
+
* unsubscribes every internal subscription, releases timers / abort
|
|
1606
|
+
* controllers / network handles. Safe to call multiple times — the
|
|
1607
|
+
* second call is a no-op.
|
|
1608
|
+
*/
|
|
1257
1609
|
dispose(): void;
|
|
1258
1610
|
}
|
|
1611
|
+
/**
|
|
1612
|
+
* Compose multiple disposers into a single `dispose()` call. Accepts either
|
|
1613
|
+
* a `StateUnit` (whose `dispose()` will be invoked) or a plain teardown
|
|
1614
|
+
* function. The returned object is itself disposable; call its `dispose()`
|
|
1615
|
+
* once to tear down everything that was added.
|
|
1616
|
+
*/
|
|
1259
1617
|
declare function createDisposer(): {
|
|
1260
|
-
add(
|
|
1618
|
+
add(item: StateUnit | (() => void)): void;
|
|
1261
1619
|
dispose(): void;
|
|
1262
1620
|
};
|
|
1263
1621
|
|
|
@@ -1267,10 +1625,9 @@ declare function createDisposer(): {
|
|
|
1267
1625
|
* A debounced-search RxJS pipeline factory. Combines an input Subject with a
|
|
1268
1626
|
* downstream fetch function and emits typed `{ results, isSearching }` state.
|
|
1269
1627
|
*
|
|
1270
|
-
* Designed to be created once per
|
|
1271
|
-
*
|
|
1272
|
-
*
|
|
1273
|
-
* has no React imports — it's pure RxJS, unit-testable without a renderer.
|
|
1628
|
+
* Designed to be created once per consumer instance and held for its lifetime
|
|
1629
|
+
* (e.g. by a view layer's lazy initializer), then observed via `state$`. The
|
|
1630
|
+
* pipeline is pure RxJS — unit-testable without any view-layer dependency.
|
|
1274
1631
|
*
|
|
1275
1632
|
* The fetch function is expected to return `Observable<T[] | undefined>`,
|
|
1276
1633
|
* matching the cache-miss-then-data shape of `BrowseNamespace` Observables:
|
|
@@ -1283,13 +1640,13 @@ interface SearchState<T> {
|
|
|
1283
1640
|
isSearching: boolean;
|
|
1284
1641
|
}
|
|
1285
1642
|
interface SearchPipeline<T> {
|
|
1286
|
-
/** Latest query string. Bind to a controlled input
|
|
1643
|
+
/** Latest query string. Bind to a controlled input. */
|
|
1287
1644
|
query$: Observable<string>;
|
|
1288
1645
|
/** Latest search state — results plus a loading flag. */
|
|
1289
1646
|
state$: Observable<SearchState<T>>;
|
|
1290
1647
|
/** Push a new query value. Triggers the debounced fetch. */
|
|
1291
1648
|
setQuery(value: string): void;
|
|
1292
|
-
/** Tear down the input Subject. Call from
|
|
1649
|
+
/** Tear down the input Subject. Call from the consumer's cleanup hook. */
|
|
1293
1650
|
dispose(): void;
|
|
1294
1651
|
}
|
|
1295
1652
|
interface SearchPipelineOptions {
|
|
@@ -1300,13 +1657,34 @@ interface SearchPipelineOptions {
|
|
|
1300
1657
|
}
|
|
1301
1658
|
declare function createSearchPipeline<T>(fetch: (query: string) => Observable<T[] | undefined>, options?: SearchPipelineOptions): SearchPipeline<T>;
|
|
1302
1659
|
|
|
1303
|
-
|
|
1660
|
+
/**
|
|
1661
|
+
* WorkerBus — minimal channel-bus surface that worker-side adapters
|
|
1662
|
+
* (e.g. `JobClaimAdapter` in `@semiont/jobs`, `SmelterActorStateUnit` in
|
|
1663
|
+
* `@semiont/make-meaning`) need.
|
|
1664
|
+
*
|
|
1665
|
+
* Transport-neutral by design. HTTP `ActorStateUnit` (from `@semiont/api-client`)
|
|
1666
|
+
* satisfies it directly; an in-process worker can pass a small shim around
|
|
1667
|
+
* an `EventBus` with a `() => Promise<void>` `emit` that calls into the
|
|
1668
|
+
* actor system.
|
|
1669
|
+
*
|
|
1670
|
+
* `addChannels` is optional because in-process buses receive every emit
|
|
1671
|
+
* implicitly — only HTTP needs to widen its SSE subscription set to
|
|
1672
|
+
* include worker-only channels (`job:queued`, `yield:created`, etc.).
|
|
1673
|
+
*/
|
|
1674
|
+
|
|
1675
|
+
interface WorkerBus {
|
|
1676
|
+
on$<T = Record<string, unknown>>(channel: string): Observable<T>;
|
|
1677
|
+
emit(channel: string, payload: Record<string, unknown>): Promise<void>;
|
|
1678
|
+
addChannels?(channels: readonly string[]): void;
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
interface BeckonStateUnit extends StateUnit {
|
|
1304
1682
|
hoveredAnnotationId$: Observable<AnnotationId | null>;
|
|
1305
1683
|
hover(annotationId: AnnotationId | null): void;
|
|
1306
1684
|
focus(annotationId: AnnotationId): void;
|
|
1307
1685
|
sparkle(annotationId: AnnotationId): void;
|
|
1308
1686
|
}
|
|
1309
|
-
declare function
|
|
1687
|
+
declare function createBeckonStateUnit(client: SemiontClient): BeckonStateUnit;
|
|
1310
1688
|
/** Default milliseconds the mouse must dwell before beckon:hover is emitted. */
|
|
1311
1689
|
declare const HOVER_DELAY_MS = 150;
|
|
1312
1690
|
type EmitHover = (annotationId: AnnotationId | null) => void;
|
|
@@ -1317,372 +1695,48 @@ interface HoverHandlers {
|
|
|
1317
1695
|
}
|
|
1318
1696
|
declare function createHoverHandlers(emit: EmitHover, delayMs: number): HoverHandlers;
|
|
1319
1697
|
|
|
1320
|
-
|
|
1321
|
-
* ShellVM — app-shell state: which toolbar panel is open, tab-bar
|
|
1322
|
-
* coordination helpers, scroll-to-annotation signals. Lives on
|
|
1323
|
-
* `SemiontBrowser`'s app-scoped bus (not the per-session client bus)
|
|
1324
|
-
* because panel toggles and shell chrome must work regardless of
|
|
1325
|
-
* whether a KB session is active.
|
|
1326
|
-
*
|
|
1327
|
-
* Channels: `panel:toggle`, `panel:open`, `panel:close`.
|
|
1328
|
-
*/
|
|
1329
|
-
|
|
1330
|
-
type ToolbarPanelType = 'history' | 'info' | 'annotations' | 'settings' | 'collaboration' | 'user' | 'jsonld' | 'knowledge-base';
|
|
1331
|
-
declare const COMMON_PANELS: readonly ToolbarPanelType[];
|
|
1332
|
-
declare const RESOURCE_PANELS: readonly ToolbarPanelType[];
|
|
1333
|
-
interface ShellVM extends ViewModel {
|
|
1334
|
-
activePanel$: Observable<ToolbarPanelType | null>;
|
|
1335
|
-
scrollToAnnotationId$: Observable<string | null>;
|
|
1336
|
-
panelInitialTab$: Observable<{
|
|
1337
|
-
tab: string;
|
|
1338
|
-
generation: number;
|
|
1339
|
-
} | null>;
|
|
1340
|
-
openPanel(panel: string): void;
|
|
1341
|
-
closePanel(): void;
|
|
1342
|
-
togglePanel(panel: string): void;
|
|
1343
|
-
onScrollCompleted(): void;
|
|
1344
|
-
}
|
|
1345
|
-
interface ShellVMOptions {
|
|
1346
|
-
initialPanel?: ToolbarPanelType | null;
|
|
1347
|
-
onPanelChange?: (panel: ToolbarPanelType | null) => void;
|
|
1348
|
-
}
|
|
1349
|
-
declare function createShellVM(browser: SemiontBrowser, options?: ShellVMOptions): ShellVM;
|
|
1350
|
-
|
|
1351
|
-
interface GatherVM extends ViewModel {
|
|
1698
|
+
interface GatherStateUnit extends StateUnit {
|
|
1352
1699
|
context$: Observable<GatheredContext | null>;
|
|
1353
1700
|
loading$: Observable<boolean>;
|
|
1354
1701
|
error$: Observable<Error | null>;
|
|
1355
1702
|
annotationId$: Observable<AnnotationId | null>;
|
|
1356
1703
|
}
|
|
1357
|
-
declare function
|
|
1704
|
+
declare function createGatherStateUnit(client: SemiontClient, resourceId: ResourceId): GatherStateUnit;
|
|
1358
1705
|
|
|
1359
|
-
interface
|
|
1706
|
+
interface MatchStateUnit extends StateUnit {
|
|
1360
1707
|
}
|
|
1361
|
-
declare function
|
|
1708
|
+
declare function createMatchStateUnit(client: SemiontClient, _resourceId: ResourceId): MatchStateUnit;
|
|
1362
1709
|
|
|
1363
1710
|
type JobProgress$1 = components['schemas']['JobProgress'];
|
|
1364
1711
|
interface GenerateDocumentOptions {
|
|
1365
1712
|
title: string;
|
|
1366
1713
|
storageUri: string;
|
|
1367
1714
|
prompt?: string;
|
|
1715
|
+
/** Body locale — language the generated resource is written in. Falls back to the state unit's UI locale when unset. */
|
|
1368
1716
|
language?: string;
|
|
1717
|
+
/** Source-resource locale — language of the resource the annotation lives on. Forwarded to the prompt for context-snippet awareness. BCP-47. */
|
|
1718
|
+
sourceLanguage?: string;
|
|
1369
1719
|
temperature?: number;
|
|
1370
1720
|
maxTokens?: number;
|
|
1371
1721
|
context: GatheredContext;
|
|
1372
1722
|
}
|
|
1373
|
-
interface
|
|
1723
|
+
interface YieldStateUnit extends StateUnit {
|
|
1374
1724
|
isGenerating$: Observable<boolean>;
|
|
1375
1725
|
progress$: Observable<JobProgress$1 | null>;
|
|
1376
1726
|
generate(referenceId: string, options: GenerateDocumentOptions): void;
|
|
1377
1727
|
}
|
|
1378
|
-
declare function
|
|
1728
|
+
declare function createYieldStateUnit(client: SemiontClient, resourceId: ResourceId, locale: string): YieldStateUnit;
|
|
1379
1729
|
|
|
1380
1730
|
type JobProgress = components['schemas']['JobProgress'];
|
|
1381
1731
|
interface PendingAnnotation {
|
|
1382
1732
|
selector: Selector | Selector[];
|
|
1383
1733
|
motivation: Motivation;
|
|
1384
1734
|
}
|
|
1385
|
-
interface
|
|
1735
|
+
interface MarkStateUnit extends StateUnit {
|
|
1386
1736
|
pendingAnnotation$: Observable<PendingAnnotation | null>;
|
|
1387
1737
|
assistingMotivation$: Observable<Motivation | null>;
|
|
1388
1738
|
progress$: Observable<JobProgress | null>;
|
|
1389
1739
|
}
|
|
1390
|
-
declare function
|
|
1391
|
-
|
|
1392
|
-
interface DiscoverVM extends ViewModel {
|
|
1393
|
-
browse: ShellVM;
|
|
1394
|
-
search: SearchPipeline<ResourceDescriptor>;
|
|
1395
|
-
recentResources$: Observable<ResourceDescriptor[]>;
|
|
1396
|
-
entityTypes$: Observable<string[]>;
|
|
1397
|
-
isLoadingRecent$: Observable<boolean>;
|
|
1398
|
-
}
|
|
1399
|
-
declare function createDiscoverVM(client: SemiontClient, browse: ShellVM): DiscoverVM;
|
|
1400
|
-
|
|
1401
|
-
interface EntityTagsVM extends ViewModel {
|
|
1402
|
-
browse: ShellVM;
|
|
1403
|
-
entityTypes$: Observable<string[]>;
|
|
1404
|
-
isLoading$: Observable<boolean>;
|
|
1405
|
-
newTag$: Observable<string>;
|
|
1406
|
-
error$: Observable<string>;
|
|
1407
|
-
isAdding$: Observable<boolean>;
|
|
1408
|
-
setNewTag(value: string): void;
|
|
1409
|
-
addTag(): Promise<void>;
|
|
1410
|
-
}
|
|
1411
|
-
declare function createEntityTagsVM(client: SemiontClient, browse: ShellVM): EntityTagsVM;
|
|
1412
|
-
|
|
1413
|
-
interface ImportPreview {
|
|
1414
|
-
format: string;
|
|
1415
|
-
version: number;
|
|
1416
|
-
sourceUrl: string;
|
|
1417
|
-
stats: Record<string, number>;
|
|
1418
|
-
}
|
|
1419
|
-
interface ExchangeVM extends ViewModel {
|
|
1420
|
-
browse: ShellVM;
|
|
1421
|
-
selectedFile$: Observable<File | null>;
|
|
1422
|
-
preview$: Observable<ImportPreview | null>;
|
|
1423
|
-
importPhase$: Observable<string | null>;
|
|
1424
|
-
importMessage$: Observable<string | undefined>;
|
|
1425
|
-
importResult$: Observable<Record<string, unknown> | undefined>;
|
|
1426
|
-
isExporting$: Observable<boolean>;
|
|
1427
|
-
isImporting$: Observable<boolean>;
|
|
1428
|
-
selectFile(file: File): void;
|
|
1429
|
-
cancelImport(): void;
|
|
1430
|
-
doExport(): Promise<{
|
|
1431
|
-
blob: Blob;
|
|
1432
|
-
filename: string;
|
|
1433
|
-
}>;
|
|
1434
|
-
doImport(): Promise<void>;
|
|
1435
|
-
}
|
|
1436
|
-
declare function createExchangeVM(browse: ShellVM, exportFn: (params?: {
|
|
1437
|
-
includeArchived?: boolean;
|
|
1438
|
-
}) => Promise<Response>, importFn: (file: File, options?: {
|
|
1439
|
-
onProgress?: (event: {
|
|
1440
|
-
phase: string;
|
|
1441
|
-
message?: string;
|
|
1442
|
-
result?: Record<string, unknown>;
|
|
1443
|
-
}) => void;
|
|
1444
|
-
}) => Promise<{
|
|
1445
|
-
phase: string;
|
|
1446
|
-
message?: string;
|
|
1447
|
-
result?: Record<string, unknown>;
|
|
1448
|
-
}>): ExchangeVM;
|
|
1449
|
-
|
|
1450
|
-
interface AdminUsersVM extends ViewModel {
|
|
1451
|
-
browse: ShellVM;
|
|
1452
|
-
users$: Observable<unknown[]>;
|
|
1453
|
-
stats$: Observable<unknown | null>;
|
|
1454
|
-
usersLoading$: Observable<boolean>;
|
|
1455
|
-
statsLoading$: Observable<boolean>;
|
|
1456
|
-
updateUser(id: string, data: {
|
|
1457
|
-
isAdmin?: boolean;
|
|
1458
|
-
isActive?: boolean;
|
|
1459
|
-
}): Promise<void>;
|
|
1460
|
-
}
|
|
1461
|
-
declare function createAdminUsersVM(client: SemiontClient, browse: ShellVM): AdminUsersVM;
|
|
1462
|
-
|
|
1463
|
-
interface AdminSecurityVM extends ViewModel {
|
|
1464
|
-
browse: ShellVM;
|
|
1465
|
-
providers$: Observable<unknown[]>;
|
|
1466
|
-
allowedDomains$: Observable<string[]>;
|
|
1467
|
-
isLoading$: Observable<boolean>;
|
|
1468
|
-
}
|
|
1469
|
-
declare function createAdminSecurityVM(client: SemiontClient, browse: ShellVM): AdminSecurityVM;
|
|
1470
|
-
|
|
1471
|
-
interface WelcomeVM extends ViewModel {
|
|
1472
|
-
userData$: Observable<{
|
|
1473
|
-
termsAcceptedAt?: string;
|
|
1474
|
-
} | null>;
|
|
1475
|
-
isProcessing$: Observable<boolean>;
|
|
1476
|
-
acceptTerms(): Promise<void>;
|
|
1477
|
-
}
|
|
1478
|
-
declare function createWelcomeVM(client: SemiontClient): WelcomeVM;
|
|
1479
|
-
|
|
1480
|
-
interface ResourceLoaderVM extends ViewModel {
|
|
1481
|
-
resource$: Observable<ResourceDescriptor | undefined>;
|
|
1482
|
-
isLoading$: Observable<boolean>;
|
|
1483
|
-
invalidate(): void;
|
|
1484
|
-
}
|
|
1485
|
-
declare function createResourceLoaderVM(client: SemiontClient, resourceId: ResourceId): ResourceLoaderVM;
|
|
1486
|
-
|
|
1487
|
-
interface SessionVM extends ViewModel {
|
|
1488
|
-
isLoggingOut$: Observable<boolean>;
|
|
1489
|
-
logout(): Promise<void>;
|
|
1490
|
-
}
|
|
1491
|
-
declare function createSessionVM(client: SemiontClient): SessionVM;
|
|
1492
|
-
|
|
1493
|
-
interface SmelterEvent {
|
|
1494
|
-
type: string;
|
|
1495
|
-
resourceId?: string;
|
|
1496
|
-
payload: Record<string, unknown>;
|
|
1497
|
-
}
|
|
1498
|
-
interface SmelterActorVMOptions {
|
|
1499
|
-
baseUrl: string;
|
|
1500
|
-
token: string;
|
|
1501
|
-
reconnectMs?: number;
|
|
1502
|
-
}
|
|
1503
|
-
interface SmelterActorVM extends ViewModel {
|
|
1504
|
-
events$: Observable<SmelterEvent>;
|
|
1505
|
-
state$: Observable<ConnectionState>;
|
|
1506
|
-
emit(channel: string, payload: Record<string, unknown>): Promise<void>;
|
|
1507
|
-
start(): void;
|
|
1508
|
-
stop(): void;
|
|
1509
|
-
}
|
|
1510
|
-
declare function createSmelterActorVM(options: SmelterActorVMOptions): SmelterActorVM;
|
|
1511
|
-
|
|
1512
|
-
/**
|
|
1513
|
-
* Job Claim Adapter — worker-side job lifecycle glue on top of a
|
|
1514
|
-
* shared `ActorVM`.
|
|
1515
|
-
*
|
|
1516
|
-
* Replaces the old `WorkerVM`, which owned its own actor and
|
|
1517
|
-
* duplicated the SSE connection that `SemiontClient` already held.
|
|
1518
|
-
* Workers now construct a `SemiontSession` normally (one actor, one
|
|
1519
|
-
* SSE connection) and use this adapter to attach job-claim behaviour
|
|
1520
|
-
* on top of `session.client.actor`.
|
|
1521
|
-
*
|
|
1522
|
-
* The adapter is intentionally thin: it subscribes to `job:queued`
|
|
1523
|
-
* on the actor, claims jobs via the existing request-response
|
|
1524
|
-
* protocol (`job:claim` → `job:claimed` / `job:claim-failed`), and
|
|
1525
|
-
* exposes observables for job orchestration. It does **not** own
|
|
1526
|
-
* the actor, has no HTTP concerns, and has no modal state.
|
|
1527
|
-
*/
|
|
1528
|
-
|
|
1529
|
-
interface JobAssignment {
|
|
1530
|
-
jobId: string;
|
|
1531
|
-
type: string;
|
|
1532
|
-
resourceId: string;
|
|
1533
|
-
}
|
|
1534
|
-
interface ActiveJob {
|
|
1535
|
-
jobId: string;
|
|
1536
|
-
type: string;
|
|
1537
|
-
resourceId: string;
|
|
1538
|
-
userId: string;
|
|
1539
|
-
params: Record<string, unknown>;
|
|
1540
|
-
}
|
|
1541
|
-
interface JobClaimAdapterOptions {
|
|
1542
|
-
/** Shared actor (typically `session.client.actor`). */
|
|
1543
|
-
actor: ActorVM;
|
|
1544
|
-
/**
|
|
1545
|
-
* Job types this worker can process. Jobs of other types that
|
|
1546
|
-
* arrive on `job:queued` are ignored. Empty array = accept any.
|
|
1547
|
-
*/
|
|
1548
|
-
jobTypes: string[];
|
|
1549
|
-
}
|
|
1550
|
-
interface JobClaimAdapter {
|
|
1551
|
-
/** Currently-claimed job, or null when idle. */
|
|
1552
|
-
readonly activeJob$: Observable<ActiveJob | null>;
|
|
1553
|
-
/** True while a claim is in flight or a job is being processed. */
|
|
1554
|
-
readonly isProcessing$: Observable<boolean>;
|
|
1555
|
-
/** Monotonically-incrementing count of successfully-completed jobs. */
|
|
1556
|
-
readonly jobsCompleted$: Observable<number>;
|
|
1557
|
-
/** Stream of job failures (including claim-failed and processing errors). */
|
|
1558
|
-
readonly errors$: Observable<{
|
|
1559
|
-
jobId: string;
|
|
1560
|
-
error: string;
|
|
1561
|
-
}>;
|
|
1562
|
-
/**
|
|
1563
|
-
* Subscribe to `job:queued` events (adding the channel to the actor
|
|
1564
|
-
* if not already subscribed) and begin claiming matching jobs.
|
|
1565
|
-
* Idempotent — calling `start()` twice is a no-op.
|
|
1566
|
-
*/
|
|
1567
|
-
start(): void;
|
|
1568
|
-
/** Stop claiming new jobs. Does not cancel an in-flight job. */
|
|
1569
|
-
stop(): void;
|
|
1570
|
-
/** Signal successful completion of `activeJob$`. */
|
|
1571
|
-
completeJob(): void;
|
|
1572
|
-
/** Signal failure of `activeJob$`. Emits on `errors$`. */
|
|
1573
|
-
failJob(jobId: string, error: string): void;
|
|
1574
|
-
/** Release observables. Does not dispose the shared actor. */
|
|
1575
|
-
dispose(): void;
|
|
1576
|
-
}
|
|
1577
|
-
/**
|
|
1578
|
-
* Attach job-claim behaviour to a shared `ActorVM`.
|
|
1579
|
-
*/
|
|
1580
|
-
declare function createJobClaimAdapter(options: JobClaimAdapterOptions): JobClaimAdapter;
|
|
1581
|
-
|
|
1582
|
-
interface Job {
|
|
1583
|
-
jobId: string;
|
|
1584
|
-
type: string;
|
|
1585
|
-
status: string;
|
|
1586
|
-
resourceId: string;
|
|
1587
|
-
/** DID of the user who initiated the job (audit). */
|
|
1588
|
-
userId: string;
|
|
1589
|
-
created: string;
|
|
1590
|
-
startedAt?: string;
|
|
1591
|
-
completedAt?: string;
|
|
1592
|
-
error?: string;
|
|
1593
|
-
progress?: Record<string, unknown>;
|
|
1594
|
-
result?: Record<string, unknown>;
|
|
1595
|
-
}
|
|
1596
|
-
interface JobQueueVM extends ViewModel {
|
|
1597
|
-
jobs$: Observable<Job[]>;
|
|
1598
|
-
pendingByType$: Observable<Map<string, number>>;
|
|
1599
|
-
runningJobs$: Observable<Job[]>;
|
|
1600
|
-
jobCreated$: Observable<Job>;
|
|
1601
|
-
jobCompleted$: Observable<Job>;
|
|
1602
|
-
jobFailed$: Observable<Job>;
|
|
1603
|
-
}
|
|
1604
|
-
declare function createJobQueueVM(client: SemiontClient): JobQueueVM;
|
|
1605
|
-
|
|
1606
|
-
interface AnnotationGroups {
|
|
1607
|
-
highlights: Annotation[];
|
|
1608
|
-
comments: Annotation[];
|
|
1609
|
-
assessments: Annotation[];
|
|
1610
|
-
references: Annotation[];
|
|
1611
|
-
tags: Annotation[];
|
|
1612
|
-
}
|
|
1613
|
-
type StoredEventResponse = components['schemas']['StoredEventResponse'];
|
|
1614
|
-
interface WizardState {
|
|
1615
|
-
open: boolean;
|
|
1616
|
-
annotationId: string | null;
|
|
1617
|
-
resourceId: string | null;
|
|
1618
|
-
defaultTitle: string;
|
|
1619
|
-
entityTypes: string[];
|
|
1620
|
-
}
|
|
1621
|
-
interface ResourceViewerPageVM extends ViewModel {
|
|
1622
|
-
beckon: BeckonVM;
|
|
1623
|
-
browse: ShellVM;
|
|
1624
|
-
mark: MarkVM;
|
|
1625
|
-
gather: GatherVM;
|
|
1626
|
-
yield: YieldVM;
|
|
1627
|
-
annotations$: Observable<Annotation[]>;
|
|
1628
|
-
annotationGroups$: Observable<AnnotationGroups>;
|
|
1629
|
-
entityTypes$: Observable<string[]>;
|
|
1630
|
-
events$: Observable<StoredEventResponse[]>;
|
|
1631
|
-
referencedBy$: Observable<ReferencedByEntry[]>;
|
|
1632
|
-
content$: Observable<string>;
|
|
1633
|
-
contentLoading$: Observable<boolean>;
|
|
1634
|
-
mediaToken$: Observable<string | null>;
|
|
1635
|
-
wizard$: Observable<WizardState>;
|
|
1636
|
-
closeWizard(): void;
|
|
1637
|
-
}
|
|
1638
|
-
declare function createResourceViewerPageVM(client: SemiontClient, resourceId: ResourceId, locale: string, browse: ShellVM, options?: {
|
|
1639
|
-
mediaType?: string;
|
|
1640
|
-
}): ResourceViewerPageVM;
|
|
1641
|
-
|
|
1642
|
-
type ComposeMode = 'new' | 'clone' | 'reference';
|
|
1643
|
-
interface ComposeParams {
|
|
1644
|
-
mode?: string | undefined;
|
|
1645
|
-
token?: string | undefined;
|
|
1646
|
-
annotationUri?: string | undefined;
|
|
1647
|
-
sourceDocumentId?: string | undefined;
|
|
1648
|
-
name?: string | undefined;
|
|
1649
|
-
entityTypes?: string | undefined;
|
|
1650
|
-
storedContext?: string | undefined;
|
|
1651
|
-
}
|
|
1652
|
-
interface CloneData {
|
|
1653
|
-
sourceResource: ResourceDescriptor;
|
|
1654
|
-
sourceContent: string;
|
|
1655
|
-
}
|
|
1656
|
-
interface ReferenceData {
|
|
1657
|
-
annotationUri: string;
|
|
1658
|
-
sourceDocumentId: string;
|
|
1659
|
-
name: string;
|
|
1660
|
-
entityTypes: string[];
|
|
1661
|
-
}
|
|
1662
|
-
interface SaveResourceParams {
|
|
1663
|
-
mode: ComposeMode;
|
|
1664
|
-
name: string;
|
|
1665
|
-
storageUri: string;
|
|
1666
|
-
content?: string;
|
|
1667
|
-
file?: File;
|
|
1668
|
-
format?: string;
|
|
1669
|
-
charset?: string;
|
|
1670
|
-
entityTypes?: string[];
|
|
1671
|
-
language: string;
|
|
1672
|
-
archiveOriginal?: boolean;
|
|
1673
|
-
annotationUri?: string;
|
|
1674
|
-
sourceDocumentId?: string;
|
|
1675
|
-
}
|
|
1676
|
-
interface ComposePageVM extends ViewModel {
|
|
1677
|
-
browse: ShellVM;
|
|
1678
|
-
mode$: Observable<ComposeMode>;
|
|
1679
|
-
loading$: Observable<boolean>;
|
|
1680
|
-
cloneData$: Observable<CloneData | null>;
|
|
1681
|
-
referenceData$: Observable<ReferenceData | null>;
|
|
1682
|
-
gatheredContext$: Observable<GatheredContext | null>;
|
|
1683
|
-
entityTypes$: Observable<string[]>;
|
|
1684
|
-
save(params: SaveResourceParams): Promise<string>;
|
|
1685
|
-
}
|
|
1686
|
-
declare function createComposePageVM(client: SemiontClient, browse: ShellVM, params: ComposeParams, auth?: AccessToken): ComposePageVM;
|
|
1740
|
+
declare function createMarkStateUnit(client: SemiontClient, resourceId: ResourceId): MarkStateUnit;
|
|
1687
1741
|
|
|
1688
|
-
export {
|
|
1742
|
+
export { AdminNamespace, type AnnotationHistoryResponse, AuthNamespace, BeckonNamespace, type BeckonStateUnit, BindNamespace, BrowseNamespace, BusRequestError, type BusRequestErrorCode, type BusRequestPrimitive, CacheObservable, type CreateAnnotationInput, type CreateFromTokenOptions, type CreateResourceInput, FrameNamespace, type GatherAnnotationProgress, GatherNamespace, type GatherStateUnit, type GenerateDocumentOptions, type GenerationOptions, type GetBrowserOptions, HOVER_DELAY_MS, type HoverHandlers, type HttpEndpoint, InMemorySessionStorage, JobNamespace, type KbEndpoint, type KbSessionStatus, type KnowledgeBase, type LocalEndpoint, type MarkAssistEvent, type MarkAssistOptions, type MarkAssistProgress, MarkNamespace, type MarkStateUnit, MatchNamespace, type MatchSearchProgress, type MatchStateUnit, type NewKnowledgeBase, type OpenResource, type PendingAnnotation, type ReferencedByEntry, type RequestContent, type ResponseContent, type SearchPipeline, type SearchPipelineOptions, type SearchState, SemiontBrowser, type SemiontBrowserConfig, SemiontClient, SemiontSession, type SemiontSessionConfig, SemiontSessionError, type SemiontSessionErrorCode, type SessionFactory, type SessionFactoryOptions, SessionSignals, type SessionStorage, type StateUnit, type StoredSession, StreamObservable, UploadObservable, type UploadProgress, type User, type UserInfo, type WorkerBus, type YieldGenerationEvent, YieldNamespace, type YieldStateUnit, busRequest, createBeckonStateUnit, createDisposer, createGatherStateUnit, createHoverHandlers, createHttpSessionFactory, createMarkStateUnit, createMatchStateUnit, createSearchPipeline, createYieldStateUnit, defaultProtocol, getBrowser, httpKb, isValidHostname, kbBackendUrl, setStoredSession };
|