@semiont/sdk 0.4.21
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 +115 -0
- package/dist/index.d.ts +1688 -0
- package/dist/index.js +3030 -0
- package/dist/index.js.map +1 -0
- package/package.json +60 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1688 @@
|
|
|
1
|
+
import * as rxjs from 'rxjs';
|
|
2
|
+
import { Observable, BehaviorSubject, Subject } from 'rxjs';
|
|
3
|
+
import * as _semiont_core from '@semiont/core';
|
|
4
|
+
import { components, UserDID, paths, ResourceId, AnnotationId, BodyOperation, EventMap, ResourceDescriptor, Annotation, GraphConnection, Motivation, GatheredContext, JobId, ITransport, EventBus, IContentTransport, BaseUrl, AccessToken, ConnectionState, Selector } from '@semiont/core';
|
|
5
|
+
export { ConnectionState, Logger } from '@semiont/core';
|
|
6
|
+
import { ActorVM } from '@semiont/api-client';
|
|
7
|
+
export { APIError, ActorVM, ActorVMOptions, BusEvent, DEGRADED_THRESHOLD_MS, HttpContentTransport, HttpTransport, HttpTransportConfig, TokenRefresher, createActorVM } from '@semiont/api-client';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Verb Namespace Interfaces
|
|
11
|
+
*
|
|
12
|
+
* These interfaces define the public API of the Semiont api-client,
|
|
13
|
+
* organized by the 7 domain flows (Browse, Mark, Bind, Gather, Match,
|
|
14
|
+
* Yield, Beckon) plus infrastructure namespaces (Job, Auth, Admin).
|
|
15
|
+
*
|
|
16
|
+
* Each namespace maps 1:1 to a flow. Each flow maps to a clear actor
|
|
17
|
+
* on the backend. The frontend calls `client.mark.annotation()` and the
|
|
18
|
+
* proxy handles HTTP, auth, SSE, and caching internally.
|
|
19
|
+
*
|
|
20
|
+
* Return type conventions:
|
|
21
|
+
* - Browse live queries → Observable (bus gateway driven, cached)
|
|
22
|
+
* - Browse one-shot reads → Promise (fetch once, no cache)
|
|
23
|
+
* - Commands (mark, bind, yield.resource) → Promise (fire-and-forget)
|
|
24
|
+
* - Long-running ops (gather, match, yield.fromAnnotation, mark.assist) → Observable (progress + result)
|
|
25
|
+
* - Ephemeral signals (beckon) → void
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
type StoredEventResponse$2 = components['schemas']['StoredEventResponse'];
|
|
29
|
+
type GatherProgress = components['schemas']['GatherProgress'];
|
|
30
|
+
type MatchSearchResult = components['schemas']['MatchSearchResult'];
|
|
31
|
+
type JobProgress$2 = components['schemas']['JobProgress'];
|
|
32
|
+
type GatherAnnotationComplete = components['schemas']['GatherAnnotationComplete'];
|
|
33
|
+
type JobStatusResponse$1 = components['schemas']['JobStatusResponse'];
|
|
34
|
+
type AuthResponse$1 = components['schemas']['AuthResponse'];
|
|
35
|
+
type TokenRefreshResponse$1 = components['schemas']['TokenRefreshResponse'];
|
|
36
|
+
type OAuthConfigResponse$1 = components['schemas']['OAuthConfigResponse'];
|
|
37
|
+
type AdminUserStatsResponse$1 = components['schemas']['AdminUserStatsResponse'];
|
|
38
|
+
type ResponseContent<T> = T extends {
|
|
39
|
+
responses: {
|
|
40
|
+
200: {
|
|
41
|
+
content: {
|
|
42
|
+
'application/json': infer R;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
} ? R : T extends {
|
|
47
|
+
responses: {
|
|
48
|
+
201: {
|
|
49
|
+
content: {
|
|
50
|
+
'application/json': infer R;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
} ? R : T extends {
|
|
55
|
+
responses: {
|
|
56
|
+
202: {
|
|
57
|
+
content: {
|
|
58
|
+
'application/json': infer R;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
} ? R : never;
|
|
63
|
+
type RequestContent<T> = T extends {
|
|
64
|
+
requestBody?: {
|
|
65
|
+
content: {
|
|
66
|
+
'application/json': infer R;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
} ? R : never;
|
|
70
|
+
/** Input for creating an annotation via mark.annotation() */
|
|
71
|
+
type CreateAnnotationInput = components['schemas']['CreateAnnotationRequest'];
|
|
72
|
+
/** Input for creating a resource via yield.resource() */
|
|
73
|
+
interface CreateResourceInput {
|
|
74
|
+
name: string;
|
|
75
|
+
file: File | Buffer;
|
|
76
|
+
format: string;
|
|
77
|
+
entityTypes?: string[];
|
|
78
|
+
language?: string;
|
|
79
|
+
creationMethod?: string;
|
|
80
|
+
sourceAnnotationId?: string;
|
|
81
|
+
sourceResourceId?: string;
|
|
82
|
+
storageUri: string;
|
|
83
|
+
/** Prompt that drove AI generation (for AI-generated resources). */
|
|
84
|
+
generationPrompt?: string;
|
|
85
|
+
/** Agent(s) that generated the content (for AI-generated resources). */
|
|
86
|
+
generator?: components['schemas']['Agent'] | components['schemas']['Agent'][];
|
|
87
|
+
isDraft?: boolean;
|
|
88
|
+
}
|
|
89
|
+
/** Options for yield.fromAnnotation() */
|
|
90
|
+
interface GenerationOptions {
|
|
91
|
+
title: string;
|
|
92
|
+
storageUri: string;
|
|
93
|
+
context: GatheredContext;
|
|
94
|
+
prompt?: string;
|
|
95
|
+
language?: string;
|
|
96
|
+
temperature?: number;
|
|
97
|
+
maxTokens?: number;
|
|
98
|
+
}
|
|
99
|
+
/** Options for mark.assist() */
|
|
100
|
+
interface MarkAssistOptions {
|
|
101
|
+
entityTypes?: string[];
|
|
102
|
+
includeDescriptiveReferences?: boolean;
|
|
103
|
+
instructions?: string;
|
|
104
|
+
density?: number;
|
|
105
|
+
tone?: string;
|
|
106
|
+
language?: string;
|
|
107
|
+
schemaId?: string;
|
|
108
|
+
categories?: string[];
|
|
109
|
+
}
|
|
110
|
+
/** Options for yield.createFromToken() */
|
|
111
|
+
type CreateFromTokenOptions = {
|
|
112
|
+
token: string;
|
|
113
|
+
name: string;
|
|
114
|
+
content: string;
|
|
115
|
+
archiveOriginal?: boolean;
|
|
116
|
+
};
|
|
117
|
+
/** Referenced-by entry from browse.referencedBy() */
|
|
118
|
+
type ReferencedByEntry = components['schemas']['GetReferencedByResponse']['referencedBy'][number];
|
|
119
|
+
/** Annotation history from browse.annotationHistory() */
|
|
120
|
+
type AnnotationHistoryResponse = components['schemas']['GetAnnotationHistoryResponse'];
|
|
121
|
+
/** User object from auth/admin responses */
|
|
122
|
+
type User = AuthResponse$1['user'];
|
|
123
|
+
/**
|
|
124
|
+
* Progress emitted by gather.annotation() Observable.
|
|
125
|
+
* Emits GatherProgress during assembly, then GatherAnnotationComplete on finish.
|
|
126
|
+
*/
|
|
127
|
+
type GatherAnnotationProgress = GatherProgress | GatherAnnotationComplete;
|
|
128
|
+
/**
|
|
129
|
+
* Progress emitted by match.search() Observable.
|
|
130
|
+
* Emits the final MatchSearchResult (no intermediate progress events currently).
|
|
131
|
+
*/
|
|
132
|
+
type MatchSearchProgress = MatchSearchResult;
|
|
133
|
+
/**
|
|
134
|
+
* Progress payload emitted by mark.assist() and yield.fromAnnotation()
|
|
135
|
+
* Observables. Each progress emission carries a JobProgress snapshot
|
|
136
|
+
* (unified job lifecycle).
|
|
137
|
+
*/
|
|
138
|
+
type MarkAssistProgress = JobProgress$2;
|
|
139
|
+
/**
|
|
140
|
+
* Discriminated event yielded by the `mark.assist()` Observable. Progress
|
|
141
|
+
* events stream while the worker runs; the final value before the
|
|
142
|
+
* Observable completes is a `complete` event carrying the `JobCompleteCommand`
|
|
143
|
+
* payload (with `result`, `jobId`, `jobType`, etc.). The Observable errors
|
|
144
|
+
* on `job:fail`.
|
|
145
|
+
*/
|
|
146
|
+
type MarkAssistEvent = {
|
|
147
|
+
kind: 'progress';
|
|
148
|
+
data: MarkAssistProgress;
|
|
149
|
+
} | {
|
|
150
|
+
kind: 'complete';
|
|
151
|
+
data: components['schemas']['JobCompleteCommand'];
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Discriminated event yielded by the `yield.fromAnnotation()` Observable.
|
|
155
|
+
* Same shape and semantics as `MarkAssistEvent`.
|
|
156
|
+
*/
|
|
157
|
+
type YieldGenerationEvent = {
|
|
158
|
+
kind: 'progress';
|
|
159
|
+
data: JobProgress$2;
|
|
160
|
+
} | {
|
|
161
|
+
kind: 'complete';
|
|
162
|
+
data: components['schemas']['JobCompleteCommand'];
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* Browse — reads from materialized views
|
|
166
|
+
*
|
|
167
|
+
* Live queries return Observables that emit initial state and re-emit
|
|
168
|
+
* on bus gateway updates. One-shot reads return Promises.
|
|
169
|
+
*
|
|
170
|
+
* Backend actor: Browser (context classes)
|
|
171
|
+
* Event prefix: browse:*
|
|
172
|
+
*/
|
|
173
|
+
interface BrowseNamespace$1 {
|
|
174
|
+
resource(resourceId: ResourceId): Observable<ResourceDescriptor | undefined>;
|
|
175
|
+
resources(filters?: {
|
|
176
|
+
limit?: number;
|
|
177
|
+
archived?: boolean;
|
|
178
|
+
search?: string;
|
|
179
|
+
}): Observable<ResourceDescriptor[] | undefined>;
|
|
180
|
+
annotations(resourceId: ResourceId): Observable<Annotation[] | undefined>;
|
|
181
|
+
annotation(resourceId: ResourceId, annotationId: AnnotationId): Observable<Annotation | undefined>;
|
|
182
|
+
entityTypes(): Observable<string[] | undefined>;
|
|
183
|
+
referencedBy(resourceId: ResourceId): Observable<ReferencedByEntry[] | undefined>;
|
|
184
|
+
events(resourceId: ResourceId): Observable<StoredEventResponse$2[] | undefined>;
|
|
185
|
+
resourceContent(resourceId: ResourceId): Promise<string>;
|
|
186
|
+
resourceRepresentation(resourceId: ResourceId, options?: {
|
|
187
|
+
accept?: string;
|
|
188
|
+
}): Promise<{
|
|
189
|
+
data: ArrayBuffer;
|
|
190
|
+
contentType: string;
|
|
191
|
+
}>;
|
|
192
|
+
resourceRepresentationStream(resourceId: ResourceId, options?: {
|
|
193
|
+
accept?: string;
|
|
194
|
+
}): Promise<{
|
|
195
|
+
stream: ReadableStream<Uint8Array>;
|
|
196
|
+
contentType: string;
|
|
197
|
+
}>;
|
|
198
|
+
resourceEvents(resourceId: ResourceId): Promise<StoredEventResponse$2[]>;
|
|
199
|
+
annotationHistory(resourceId: ResourceId, annotationId: AnnotationId): Promise<AnnotationHistoryResponse>;
|
|
200
|
+
connections(resourceId: ResourceId): Promise<GraphConnection[]>;
|
|
201
|
+
backlinks(resourceId: ResourceId): Promise<Annotation[]>;
|
|
202
|
+
resourcesByName(query: string, limit?: number): Promise<ResourceDescriptor[]>;
|
|
203
|
+
files(dirPath?: string, sort?: 'name' | 'mtime' | 'annotationCount'): Promise<components['schemas']['BrowseFilesResponse']>;
|
|
204
|
+
click(annotationId: AnnotationId, motivation: Motivation): void;
|
|
205
|
+
navigateReference(resourceId: ResourceId): void;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Mark — annotation CRUD, entity types, AI assist
|
|
209
|
+
*
|
|
210
|
+
* Commands return Promises that resolve on HTTP acceptance (202).
|
|
211
|
+
* Results appear on browse Observables via bus gateway.
|
|
212
|
+
* assist() returns an Observable for long-running progress.
|
|
213
|
+
*
|
|
214
|
+
* Backend actor: Stower
|
|
215
|
+
* Event prefix: mark:*
|
|
216
|
+
*/
|
|
217
|
+
interface MarkNamespace$1 {
|
|
218
|
+
annotation(resourceId: ResourceId, input: CreateAnnotationInput): Promise<{
|
|
219
|
+
annotationId: string;
|
|
220
|
+
}>;
|
|
221
|
+
delete(resourceId: ResourceId, annotationId: AnnotationId): Promise<void>;
|
|
222
|
+
entityType(type: string): Promise<void>;
|
|
223
|
+
entityTypes(types: string[]): Promise<void>;
|
|
224
|
+
archive(resourceId: ResourceId): Promise<void>;
|
|
225
|
+
unarchive(resourceId: ResourceId): Promise<void>;
|
|
226
|
+
assist(resourceId: ResourceId, motivation: Motivation, options: MarkAssistOptions): Observable<MarkAssistEvent>;
|
|
227
|
+
request(selector: components['schemas']['MarkRequestedEvent']['selector'], motivation: Motivation): void;
|
|
228
|
+
/** Fire-and-forget variant of `assist` — mark-vm orchestrates the call and its progress Observable. */
|
|
229
|
+
requestAssist(motivation: Motivation, options: MarkAssistOptions, correlationId?: string): void;
|
|
230
|
+
/** Submit the currently pending annotation with its selector and optional body. */
|
|
231
|
+
submit(input: components['schemas']['MarkSubmitEvent']): void;
|
|
232
|
+
/** Cancel the currently pending annotation (if any). */
|
|
233
|
+
cancelPending(): void;
|
|
234
|
+
/** Dismiss the in-progress AI-assist widget. */
|
|
235
|
+
dismissProgress(): void;
|
|
236
|
+
changeSelection(motivation: Motivation | null): void;
|
|
237
|
+
changeClick(action: string): void;
|
|
238
|
+
changeShape(shape: string): void;
|
|
239
|
+
toggleMode(): void;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Bind — reference linking
|
|
243
|
+
*
|
|
244
|
+
* The simplest namespace. One method. The result (updated annotation
|
|
245
|
+
* with resolved reference) arrives on browse.annotations() via the
|
|
246
|
+
* enriched mark:body-updated event.
|
|
247
|
+
*
|
|
248
|
+
* Backend actor: Stower (via mark:update-body)
|
|
249
|
+
* Event prefix: mark:body-updated (shares mark event pipeline)
|
|
250
|
+
*/
|
|
251
|
+
interface BindNamespace$1 {
|
|
252
|
+
body(resourceId: ResourceId, annotationId: AnnotationId, operations: BodyOperation[]): Promise<void>;
|
|
253
|
+
/** UI signal: a reference-binding flow is requested for an annotation. */
|
|
254
|
+
initiate(input: EventMap['bind:initiate']): void;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Gather — context assembly
|
|
258
|
+
*
|
|
259
|
+
* Long-running (LLM calls + graph traversal). Returns Observables
|
|
260
|
+
* that emit progress then the gathered context.
|
|
261
|
+
*
|
|
262
|
+
* Backend actor: Gatherer
|
|
263
|
+
* Event prefix: gather:*
|
|
264
|
+
*/
|
|
265
|
+
interface GatherNamespace$1 {
|
|
266
|
+
annotation(annotationId: AnnotationId, resourceId: ResourceId, options?: {
|
|
267
|
+
contextWindow?: number;
|
|
268
|
+
}): Observable<GatherAnnotationProgress>;
|
|
269
|
+
resource(resourceId: ResourceId, options?: {
|
|
270
|
+
contextWindow?: number;
|
|
271
|
+
}): Observable<GatherAnnotationProgress>;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Match — search and ranking
|
|
275
|
+
*
|
|
276
|
+
* Long-running (semantic search, optional LLM scoring). Returns
|
|
277
|
+
* Observable with progress then results.
|
|
278
|
+
*
|
|
279
|
+
* Backend actor: Matcher
|
|
280
|
+
* Event prefix: match:*
|
|
281
|
+
*/
|
|
282
|
+
interface MatchNamespace$1 {
|
|
283
|
+
search(resourceId: ResourceId, referenceId: string, context: GatheredContext, options?: {
|
|
284
|
+
limit?: number;
|
|
285
|
+
useSemanticScoring?: boolean;
|
|
286
|
+
}): Observable<MatchSearchProgress>;
|
|
287
|
+
/** Fire-and-forget variant: match-vm orchestrates the call and its result Observable. */
|
|
288
|
+
requestSearch(input: components['schemas']['MatchSearchRequest']): void;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Yield — resource creation
|
|
292
|
+
*
|
|
293
|
+
* resource() is synchronous file upload (Promise).
|
|
294
|
+
* fromAnnotation() is long-running LLM generation (Observable).
|
|
295
|
+
*
|
|
296
|
+
* Backend actor: Stower + generation worker
|
|
297
|
+
* Event prefix: yield:*
|
|
298
|
+
*/
|
|
299
|
+
interface YieldNamespace$1 {
|
|
300
|
+
resource(data: CreateResourceInput): Promise<{
|
|
301
|
+
resourceId: string;
|
|
302
|
+
}>;
|
|
303
|
+
fromAnnotation(resourceId: ResourceId, annotationId: AnnotationId, options: GenerationOptions): Observable<YieldGenerationEvent>;
|
|
304
|
+
cloneToken(resourceId: ResourceId): Promise<{
|
|
305
|
+
token: string;
|
|
306
|
+
expiresAt: string;
|
|
307
|
+
}>;
|
|
308
|
+
fromToken(token: string): Promise<ResourceDescriptor>;
|
|
309
|
+
createFromToken(options: CreateFromTokenOptions): Promise<{
|
|
310
|
+
resourceId: string;
|
|
311
|
+
}>;
|
|
312
|
+
/** UI signal: user invoked the clone action from the resource-info panel. */
|
|
313
|
+
clone(): void;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Beckon — attention coordination
|
|
317
|
+
*
|
|
318
|
+
* Fire-and-forget. Ephemeral presence signal delivered via the
|
|
319
|
+
* attention-stream to other participants.
|
|
320
|
+
*
|
|
321
|
+
* Backend actor: (frontend relay via attention-stream)
|
|
322
|
+
* Event prefix: beckon:*
|
|
323
|
+
*/
|
|
324
|
+
interface BeckonNamespace$1 {
|
|
325
|
+
attention(annotationId: AnnotationId, resourceId: ResourceId): void;
|
|
326
|
+
hover(annotationId: AnnotationId | null): void;
|
|
327
|
+
sparkle(annotationId: AnnotationId): void;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Job — worker lifecycle
|
|
331
|
+
*/
|
|
332
|
+
interface JobNamespace$1 {
|
|
333
|
+
/** Live stream of `job:queued` events from the bus. */
|
|
334
|
+
readonly queued$: Observable<EventMap['job:queued']>;
|
|
335
|
+
/** Live stream of `job:report-progress` events from the bus. */
|
|
336
|
+
readonly progress$: Observable<EventMap['job:report-progress']>;
|
|
337
|
+
/** Live stream of `job:complete` events from the bus. */
|
|
338
|
+
readonly complete$: Observable<EventMap['job:complete']>;
|
|
339
|
+
/** Live stream of `job:fail` events from the bus. */
|
|
340
|
+
readonly fail$: Observable<EventMap['job:fail']>;
|
|
341
|
+
status(jobId: JobId): Promise<JobStatusResponse$1>;
|
|
342
|
+
pollUntilComplete(jobId: JobId, options?: {
|
|
343
|
+
interval?: number;
|
|
344
|
+
timeout?: number;
|
|
345
|
+
onProgress?: (status: JobStatusResponse$1) => void;
|
|
346
|
+
}): Promise<JobStatusResponse$1>;
|
|
347
|
+
cancel(jobId: JobId, type: string): Promise<void>;
|
|
348
|
+
/** UI signal: cancel all active jobs of a given type (e.g. "annotation"). */
|
|
349
|
+
cancelRequest(jobType: 'annotation' | 'generation'): void;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Auth — authentication
|
|
353
|
+
*/
|
|
354
|
+
interface AuthNamespace$1 {
|
|
355
|
+
password(email: string, password: string): Promise<AuthResponse$1>;
|
|
356
|
+
google(credential: string): Promise<AuthResponse$1>;
|
|
357
|
+
refresh(token: string): Promise<TokenRefreshResponse$1>;
|
|
358
|
+
logout(): Promise<void>;
|
|
359
|
+
me(): Promise<User>;
|
|
360
|
+
acceptTerms(): Promise<void>;
|
|
361
|
+
mcpToken(): Promise<{
|
|
362
|
+
token: string;
|
|
363
|
+
}>;
|
|
364
|
+
mediaToken(resourceId: ResourceId): Promise<{
|
|
365
|
+
token: string;
|
|
366
|
+
}>;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Admin — administration
|
|
370
|
+
*/
|
|
371
|
+
interface AdminNamespace$1 {
|
|
372
|
+
users(): Promise<User[]>;
|
|
373
|
+
userStats(): Promise<AdminUserStatsResponse$1>;
|
|
374
|
+
updateUser(userId: UserDID, data: RequestContent<paths['/api/admin/users/{id}']['patch']>): Promise<User>;
|
|
375
|
+
oauthConfig(): Promise<OAuthConfigResponse$1>;
|
|
376
|
+
healthCheck(): Promise<ResponseContent<paths['/api/health']['get']>>;
|
|
377
|
+
status(): Promise<ResponseContent<paths['/api/status']['get']>>;
|
|
378
|
+
backup(): Promise<Response>;
|
|
379
|
+
restore(file: File, onProgress?: (event: {
|
|
380
|
+
phase: string;
|
|
381
|
+
message?: string;
|
|
382
|
+
result?: Record<string, unknown>;
|
|
383
|
+
}) => void): Promise<{
|
|
384
|
+
phase: string;
|
|
385
|
+
message?: string;
|
|
386
|
+
result?: Record<string, unknown>;
|
|
387
|
+
}>;
|
|
388
|
+
exportKnowledgeBase(params?: {
|
|
389
|
+
includeArchived?: boolean;
|
|
390
|
+
}): Promise<Response>;
|
|
391
|
+
importKnowledgeBase(file: File, onProgress?: (event: {
|
|
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
|
+
}>;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
type StoredEventResponse$1 = components['schemas']['StoredEventResponse'];
|
|
403
|
+
type ResourceListFilters = {
|
|
404
|
+
limit?: number;
|
|
405
|
+
archived?: boolean;
|
|
406
|
+
search?: string;
|
|
407
|
+
};
|
|
408
|
+
declare class BrowseNamespace implements BrowseNamespace$1 {
|
|
409
|
+
private readonly transport;
|
|
410
|
+
private readonly bus;
|
|
411
|
+
private readonly content;
|
|
412
|
+
private readonly resourceCache;
|
|
413
|
+
private readonly resourceListCache;
|
|
414
|
+
private readonly annotationListCache;
|
|
415
|
+
/**
|
|
416
|
+
* Annotation-detail cache keyed by `annotationId` only — the resourceId
|
|
417
|
+
* is a routing hint for the backend fetch, not an identity component.
|
|
418
|
+
* We track the most recent resourceId per annotationId in a side-map
|
|
419
|
+
* so `mark:delete-ok` (which carries only `annotationId`) can reach
|
|
420
|
+
* the right cache entry. Aligns with the pre-refactor semantics.
|
|
421
|
+
*/
|
|
422
|
+
private readonly annotationDetailCache;
|
|
423
|
+
private readonly annotationResources;
|
|
424
|
+
private readonly entityTypesCache;
|
|
425
|
+
private readonly referencedByCache;
|
|
426
|
+
private readonly resourceEventsCache;
|
|
427
|
+
/** Filter-blob memory so `invalidateResourceLists` can replay per-key. */
|
|
428
|
+
private readonly resourceListFilters;
|
|
429
|
+
/**
|
|
430
|
+
* Per-key memo for `annotations()` observables. The cache stores the
|
|
431
|
+
* full `AnnotationsListResponse`; the public shape is just the inner
|
|
432
|
+
* `Annotation[]`. Without this memo, every call to `annotations(rId)`
|
|
433
|
+
* would produce a fresh `.pipe(map(...))` observable, violating B4
|
|
434
|
+
* (per-key observable stability). Consumers that compare observable
|
|
435
|
+
* identity — React hooks depending on the observable reference,
|
|
436
|
+
* `distinctUntilChanged` at a higher level — would misbehave.
|
|
437
|
+
*/
|
|
438
|
+
private readonly annotationListObs;
|
|
439
|
+
constructor(transport: ITransport, bus: EventBus, content: IContentTransport);
|
|
440
|
+
resource(resourceId: ResourceId): Observable<ResourceDescriptor | undefined>;
|
|
441
|
+
resources(filters?: ResourceListFilters): Observable<ResourceDescriptor[] | undefined>;
|
|
442
|
+
annotations(resourceId: ResourceId): Observable<Annotation[] | undefined>;
|
|
443
|
+
annotation(resourceId: ResourceId, annotationId: AnnotationId): Observable<Annotation | undefined>;
|
|
444
|
+
entityTypes(): Observable<string[] | undefined>;
|
|
445
|
+
referencedBy(resourceId: ResourceId): Observable<ReferencedByEntry[] | undefined>;
|
|
446
|
+
events(resourceId: ResourceId): Observable<StoredEventResponse$1[] | undefined>;
|
|
447
|
+
resourceContent(resourceId: ResourceId): Promise<string>;
|
|
448
|
+
resourceRepresentation(resourceId: ResourceId, options?: {
|
|
449
|
+
accept?: string;
|
|
450
|
+
}): Promise<{
|
|
451
|
+
data: ArrayBuffer;
|
|
452
|
+
contentType: string;
|
|
453
|
+
}>;
|
|
454
|
+
resourceRepresentationStream(resourceId: ResourceId, options?: {
|
|
455
|
+
accept?: string;
|
|
456
|
+
}): Promise<{
|
|
457
|
+
stream: ReadableStream<Uint8Array>;
|
|
458
|
+
contentType: string;
|
|
459
|
+
}>;
|
|
460
|
+
resourceEvents(resourceId: ResourceId): Promise<StoredEventResponse$1[]>;
|
|
461
|
+
annotationHistory(resourceId: ResourceId, annotationId: AnnotationId): Promise<AnnotationHistoryResponse>;
|
|
462
|
+
connections(_resourceId: ResourceId): Promise<GraphConnection[]>;
|
|
463
|
+
backlinks(_resourceId: ResourceId): Promise<Annotation[]>;
|
|
464
|
+
resourcesByName(_query: string, _limit?: number): Promise<ResourceDescriptor[]>;
|
|
465
|
+
files(dirPath?: string, sort?: 'name' | 'mtime' | 'annotationCount'): Promise<components['schemas']['BrowseFilesResponse']>;
|
|
466
|
+
click(annotationId: AnnotationId, motivation: Motivation): void;
|
|
467
|
+
navigateReference(resourceId: ResourceId): void;
|
|
468
|
+
invalidateAnnotationList(resourceId: ResourceId): void;
|
|
469
|
+
removeAnnotationDetail(annotationId: AnnotationId): void;
|
|
470
|
+
invalidateResourceDetail(id: ResourceId): void;
|
|
471
|
+
invalidateResourceLists(): void;
|
|
472
|
+
invalidateEntityTypes(): void;
|
|
473
|
+
invalidateReferencedBy(resourceId: ResourceId): void;
|
|
474
|
+
invalidateResourceEvents(resourceId: ResourceId): void;
|
|
475
|
+
updateAnnotationInPlace(resourceId: ResourceId, annotation: Annotation): void;
|
|
476
|
+
/**
|
|
477
|
+
* Typed shorthand for `eventBus.get(channel).subscribe(handler)`.
|
|
478
|
+
* Preserves per-channel payload typing so handlers read
|
|
479
|
+
* `EventMap[K]` without any casts.
|
|
480
|
+
*/
|
|
481
|
+
private on;
|
|
482
|
+
/**
|
|
483
|
+
* Handler shared by `mark:entity-tag-added` and `mark:entity-tag-removed`.
|
|
484
|
+
* Both events carry the same effect: the annotation list, the
|
|
485
|
+
* resource descriptor, and the event log for that resource all may
|
|
486
|
+
* now reflect different entity tagging, so invalidate all three.
|
|
487
|
+
*/
|
|
488
|
+
private onEntityTagChanged;
|
|
489
|
+
/**
|
|
490
|
+
* Handler shared by `mark:archived` and `mark:unarchived`. Both
|
|
491
|
+
* change a resource's archived flag, which is stored on the resource
|
|
492
|
+
* descriptor and affects the resource-list filter.
|
|
493
|
+
*/
|
|
494
|
+
private onArchiveToggled;
|
|
495
|
+
/**
|
|
496
|
+
* Handler shared by `yield:create-ok` and `yield:update-ok`. Both
|
|
497
|
+
* report a resource mutation with the resourceId as a string (not
|
|
498
|
+
* yet branded), so we brand and apply the same effect as
|
|
499
|
+
* `onArchiveToggled`.
|
|
500
|
+
*/
|
|
501
|
+
private onYieldResourceMutated;
|
|
502
|
+
private subscribeToEvents;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
declare class MarkNamespace implements MarkNamespace$1 {
|
|
506
|
+
private readonly transport;
|
|
507
|
+
private readonly bus;
|
|
508
|
+
constructor(transport: ITransport, bus: EventBus);
|
|
509
|
+
annotation(resourceId: ResourceId, input: CreateAnnotationInput): Promise<{
|
|
510
|
+
annotationId: string;
|
|
511
|
+
}>;
|
|
512
|
+
delete(resourceId: ResourceId, annotationId: AnnotationId): Promise<void>;
|
|
513
|
+
entityType(type: string): Promise<void>;
|
|
514
|
+
entityTypes(types: string[]): Promise<void>;
|
|
515
|
+
archive(resourceId: ResourceId): Promise<void>;
|
|
516
|
+
unarchive(resourceId: ResourceId): Promise<void>;
|
|
517
|
+
assist(resourceId: ResourceId, motivation: Motivation, options: MarkAssistOptions): Observable<MarkAssistEvent>;
|
|
518
|
+
request(selector: components['schemas']['MarkRequestedEvent']['selector'], motivation: Motivation): void;
|
|
519
|
+
requestAssist(motivation: Motivation, options: MarkAssistOptions, correlationId?: string): void;
|
|
520
|
+
submit(input: components['schemas']['MarkSubmitEvent']): void;
|
|
521
|
+
cancelPending(): void;
|
|
522
|
+
dismissProgress(): void;
|
|
523
|
+
changeSelection(motivation: Motivation | null): void;
|
|
524
|
+
changeClick(action: string): void;
|
|
525
|
+
changeShape(shape: string): void;
|
|
526
|
+
toggleMode(): void;
|
|
527
|
+
private dispatchAssist;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
declare class BindNamespace implements BindNamespace$1 {
|
|
531
|
+
private readonly transport;
|
|
532
|
+
private readonly bus;
|
|
533
|
+
constructor(transport: ITransport, bus: EventBus);
|
|
534
|
+
body(resourceId: ResourceId, annotationId: AnnotationId, operations: BodyOperation[]): Promise<void>;
|
|
535
|
+
initiate(input: EventMap['bind:initiate']): void;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
declare class GatherNamespace implements GatherNamespace$1 {
|
|
539
|
+
private readonly transport;
|
|
540
|
+
private readonly bus;
|
|
541
|
+
constructor(transport: ITransport, bus: EventBus);
|
|
542
|
+
annotation(annotationId: AnnotationId, resourceId: ResourceId, options?: {
|
|
543
|
+
contextWindow?: number;
|
|
544
|
+
}): Observable<GatherAnnotationProgress>;
|
|
545
|
+
resource(_resourceId: ResourceId, _options?: {
|
|
546
|
+
contextWindow?: number;
|
|
547
|
+
}): Observable<GatherAnnotationProgress>;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
declare class MatchNamespace implements MatchNamespace$1 {
|
|
551
|
+
private readonly transport;
|
|
552
|
+
private readonly bus;
|
|
553
|
+
constructor(transport: ITransport, bus: EventBus);
|
|
554
|
+
requestSearch(input: components['schemas']['MatchSearchRequest']): void;
|
|
555
|
+
search(resourceId: ResourceId, referenceId: string, context: GatheredContext, options?: {
|
|
556
|
+
limit?: number;
|
|
557
|
+
useSemanticScoring?: boolean;
|
|
558
|
+
}): Observable<MatchSearchProgress>;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
declare class YieldNamespace implements YieldNamespace$1 {
|
|
562
|
+
private readonly transport;
|
|
563
|
+
private readonly bus;
|
|
564
|
+
private readonly content;
|
|
565
|
+
constructor(transport: ITransport, bus: EventBus, content: IContentTransport);
|
|
566
|
+
resource(data: CreateResourceInput): Promise<{
|
|
567
|
+
resourceId: string;
|
|
568
|
+
}>;
|
|
569
|
+
fromAnnotation(resourceId: ResourceId, annotationId: AnnotationId, options: GenerationOptions): Observable<YieldGenerationEvent>;
|
|
570
|
+
cloneToken(resourceId: ResourceId): Promise<{
|
|
571
|
+
token: string;
|
|
572
|
+
expiresAt: string;
|
|
573
|
+
}>;
|
|
574
|
+
fromToken(token: string): Promise<ResourceDescriptor>;
|
|
575
|
+
createFromToken(options: CreateFromTokenOptions): Promise<{
|
|
576
|
+
resourceId: string;
|
|
577
|
+
}>;
|
|
578
|
+
clone(): void;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
declare class BeckonNamespace implements BeckonNamespace$1 {
|
|
582
|
+
private readonly transport;
|
|
583
|
+
private readonly bus;
|
|
584
|
+
constructor(transport: ITransport, bus: EventBus);
|
|
585
|
+
attention(annotationId: AnnotationId, resourceId: ResourceId): void;
|
|
586
|
+
hover(annotationId: AnnotationId | null): void;
|
|
587
|
+
sparkle(annotationId: AnnotationId): void;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
type JobStatusResponse = components['schemas']['JobStatusResponse'];
|
|
591
|
+
declare class JobNamespace implements JobNamespace$1 {
|
|
592
|
+
private readonly transport;
|
|
593
|
+
private readonly bus;
|
|
594
|
+
constructor(transport: ITransport, bus: EventBus);
|
|
595
|
+
/**
|
|
596
|
+
* Live stream of `job:queued` events. Surfaces a typed view onto the
|
|
597
|
+
* underlying bus channel for consumers (CLIs, MCP handlers, widgets)
|
|
598
|
+
* that orchestrate jobs and need to react to lifecycle transitions.
|
|
599
|
+
*/
|
|
600
|
+
get queued$(): Observable<EventMap['job:queued']>;
|
|
601
|
+
/** Live stream of `job:report-progress` events. */
|
|
602
|
+
get progress$(): Observable<EventMap['job:report-progress']>;
|
|
603
|
+
/** Live stream of `job:complete` events. */
|
|
604
|
+
get complete$(): Observable<EventMap['job:complete']>;
|
|
605
|
+
/** Live stream of `job:fail` events. */
|
|
606
|
+
get fail$(): Observable<EventMap['job:fail']>;
|
|
607
|
+
status(jobId: JobId): Promise<JobStatusResponse>;
|
|
608
|
+
pollUntilComplete(jobId: JobId, options?: {
|
|
609
|
+
interval?: number;
|
|
610
|
+
timeout?: number;
|
|
611
|
+
onProgress?: (status: JobStatusResponse) => void;
|
|
612
|
+
}): Promise<JobStatusResponse>;
|
|
613
|
+
cancel(_jobId: JobId, type: string): Promise<void>;
|
|
614
|
+
cancelRequest(jobType: 'annotation' | 'generation'): void;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* AuthNamespace — authentication. Pure wire, no bus.
|
|
619
|
+
*/
|
|
620
|
+
|
|
621
|
+
type AuthResponse = components['schemas']['AuthResponse'];
|
|
622
|
+
type TokenRefreshResponse = components['schemas']['TokenRefreshResponse'];
|
|
623
|
+
declare class AuthNamespace implements AuthNamespace$1 {
|
|
624
|
+
private readonly transport;
|
|
625
|
+
constructor(transport: ITransport);
|
|
626
|
+
password(emailStr: string, passwordStr: string): Promise<AuthResponse>;
|
|
627
|
+
google(credential: string): Promise<AuthResponse>;
|
|
628
|
+
refresh(token: string): Promise<TokenRefreshResponse>;
|
|
629
|
+
logout(): Promise<void>;
|
|
630
|
+
me(): Promise<User>;
|
|
631
|
+
acceptTerms(): Promise<void>;
|
|
632
|
+
mcpToken(): Promise<{
|
|
633
|
+
token: string;
|
|
634
|
+
}>;
|
|
635
|
+
mediaToken(resourceId: ResourceId): Promise<{
|
|
636
|
+
token: string;
|
|
637
|
+
}>;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/**
|
|
641
|
+
* AdminNamespace — administration. Pure wire, no bus.
|
|
642
|
+
*/
|
|
643
|
+
|
|
644
|
+
type AdminUserStatsResponse = components['schemas']['AdminUserStatsResponse'];
|
|
645
|
+
type OAuthConfigResponse = components['schemas']['OAuthConfigResponse'];
|
|
646
|
+
declare class AdminNamespace implements AdminNamespace$1 {
|
|
647
|
+
private readonly transport;
|
|
648
|
+
constructor(transport: ITransport);
|
|
649
|
+
users(): Promise<User[]>;
|
|
650
|
+
userStats(): Promise<AdminUserStatsResponse>;
|
|
651
|
+
updateUser(userId: UserDID, data: RequestContent<paths['/api/admin/users/{id}']['patch']>): Promise<User>;
|
|
652
|
+
oauthConfig(): Promise<OAuthConfigResponse>;
|
|
653
|
+
healthCheck(): Promise<ResponseContent<paths['/api/health']['get']>>;
|
|
654
|
+
status(): Promise<ResponseContent<paths['/api/status']['get']>>;
|
|
655
|
+
backup(): Promise<Response>;
|
|
656
|
+
restore(file: File, onProgress?: (event: {
|
|
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
|
+
}>;
|
|
665
|
+
exportKnowledgeBase(params?: {
|
|
666
|
+
includeArchived?: boolean;
|
|
667
|
+
}): Promise<Response>;
|
|
668
|
+
importKnowledgeBase(file: File, onProgress?: (event: {
|
|
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
|
+
}>;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
declare class SemiontClient {
|
|
680
|
+
/**
|
|
681
|
+
* The wire-facing transport. Owns bus actor, HTTP, auth, admin, exchange,
|
|
682
|
+
* system. Exposed for advanced consumers (workers, custom job adapters)
|
|
683
|
+
* that need raw `transport.emit(channel, payload, scope)` access. Ordinary
|
|
684
|
+
* consumers go through typed namespace methods.
|
|
685
|
+
*/
|
|
686
|
+
readonly transport: ITransport;
|
|
687
|
+
/** Binary I/O transport. */
|
|
688
|
+
private readonly content;
|
|
689
|
+
/**
|
|
690
|
+
* Per-client local EventBus. Wire events flow in via the transport
|
|
691
|
+
* bridge. Read-only public so `SemiontSession.subscribe(channel, …)`
|
|
692
|
+
* can wire arbitrary-channel subscriptions; everything else uses
|
|
693
|
+
* typed namespace methods.
|
|
694
|
+
*/
|
|
695
|
+
readonly bus: EventBus;
|
|
696
|
+
readonly baseUrl: BaseUrl;
|
|
697
|
+
readonly browse: BrowseNamespace;
|
|
698
|
+
readonly mark: MarkNamespace;
|
|
699
|
+
readonly bind: BindNamespace;
|
|
700
|
+
readonly gather: GatherNamespace;
|
|
701
|
+
readonly match: MatchNamespace;
|
|
702
|
+
readonly yield: YieldNamespace;
|
|
703
|
+
readonly beckon: BeckonNamespace;
|
|
704
|
+
readonly job: JobNamespace;
|
|
705
|
+
readonly auth: AuthNamespace;
|
|
706
|
+
readonly admin: AdminNamespace;
|
|
707
|
+
/**
|
|
708
|
+
* The client *owns* its bus. The constructor creates a fresh `EventBus`
|
|
709
|
+
* and hands it to the transport via `transport.bridgeInto(this.bus)`.
|
|
710
|
+
* The reference flows client → transport, never the other way:
|
|
711
|
+
* the transport stores the reference and publishes the events it
|
|
712
|
+
* receives onto that bus. `HttpTransport` does so for every channel
|
|
713
|
+
* delivered on its SSE wire; in-process transports adapt their
|
|
714
|
+
* internal source.
|
|
715
|
+
*
|
|
716
|
+
* Callers do not pass a bus in. If they need to interact with the bus
|
|
717
|
+
* (e.g. for tests or to subscribe to arbitrary channels), they read it
|
|
718
|
+
* back via `client.bus`.
|
|
719
|
+
*/
|
|
720
|
+
constructor(transport: ITransport, content: IContentTransport);
|
|
721
|
+
/** Transport-level connection state. HTTP reflects SSE health; local is always 'connected'. */
|
|
722
|
+
get state$(): rxjs.Observable<_semiont_core.ConnectionState>;
|
|
723
|
+
subscribeToResource(resourceId: ResourceId): () => void;
|
|
724
|
+
dispose(): void;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
declare class BusRequestError extends Error {
|
|
728
|
+
constructor(message: string);
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* Subset of ITransport that `busRequest` needs: a way to send a command and
|
|
732
|
+
* a way to observe channels. Generic enough that an in-process transport
|
|
733
|
+
* can satisfy it without round-tripping through HTTP.
|
|
734
|
+
*/
|
|
735
|
+
interface BusRequestPrimitive {
|
|
736
|
+
emit<K extends keyof EventMap>(channel: K, payload: EventMap[K]): Promise<void>;
|
|
737
|
+
stream<K extends keyof EventMap>(channel: K): Observable<EventMap[K]>;
|
|
738
|
+
}
|
|
739
|
+
declare function busRequest<TResult>(bus: BusRequestPrimitive, emitChannel: string, payload: Record<string, unknown>, resultChannel: string, failureChannel: string, timeoutMs?: number): Promise<TResult>;
|
|
740
|
+
|
|
741
|
+
/**
|
|
742
|
+
* RxJS-native read-through cache primitive.
|
|
743
|
+
*
|
|
744
|
+
* Behavioral contract: packages/api-client/docs/CACHE-SEMANTICS.md (B1–B13).
|
|
745
|
+
*
|
|
746
|
+
* Framework-agnostic: no React, no dependency on any namespace. Used by
|
|
747
|
+
* `BrowseNamespace` to back its per-key stores, but equally usable from
|
|
748
|
+
* CLI, MCP, or worker code.
|
|
749
|
+
*
|
|
750
|
+
* Shape:
|
|
751
|
+
* - `observe(key)`: returns an Observable<V | undefined> that triggers
|
|
752
|
+
* a fetch on first subscription for a missing key, dedup-joins any
|
|
753
|
+
* concurrent fetch, and emits the stored value thereafter.
|
|
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.
|
|
800
|
+
*
|
|
801
|
+
* Each KB has its own JWT, its own API base URL, and its own session.
|
|
802
|
+
* The user is "authenticated against KB X" — never globally authenticated.
|
|
803
|
+
*/
|
|
804
|
+
interface KnowledgeBase {
|
|
805
|
+
id: string;
|
|
806
|
+
label: string;
|
|
807
|
+
host: string;
|
|
808
|
+
port: number;
|
|
809
|
+
protocol: 'http' | 'https';
|
|
810
|
+
email: string;
|
|
811
|
+
gitBranch?: string;
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* Input shape for adding a new KB. The id is generated by the provider.
|
|
815
|
+
*/
|
|
816
|
+
type NewKnowledgeBase = Omit<KnowledgeBase, 'id'>;
|
|
817
|
+
/**
|
|
818
|
+
* Status of the locally-stored credential for a KB. Derived from the
|
|
819
|
+
* presence and validity of the JWT in session storage.
|
|
820
|
+
*/
|
|
821
|
+
type KbSessionStatus = 'authenticated' | 'expired' | 'signed-out' | 'unreachable';
|
|
822
|
+
|
|
823
|
+
/**
|
|
824
|
+
* Session-level error surface. Emitted on `SemiontBrowser.error$` for
|
|
825
|
+
* failures that make the session itself unusable (auth failed, actor
|
|
826
|
+
* couldn't start, token refresh terminally exhausted). Per-request
|
|
827
|
+
* errors stay with the caller as normal Promise rejections.
|
|
828
|
+
*/
|
|
829
|
+
type SemiontErrorCode = 'session.construct-failed' | 'session.auth-failed' | 'session.refresh-exhausted' | 'browser.sign-in-failed';
|
|
830
|
+
declare class SemiontError extends Error {
|
|
831
|
+
readonly code: SemiontErrorCode;
|
|
832
|
+
readonly kbId: string | null;
|
|
833
|
+
constructor(code: SemiontErrorCode, message: string, kbId?: string | null);
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
/**
|
|
837
|
+
* SessionStorage — environment-agnostic persistence adapter for the
|
|
838
|
+
* Semiont session layer. Decouples `SemiontSession` / `SemiontBrowser`
|
|
839
|
+
* from `localStorage` / `window` so the same classes can run in a
|
|
840
|
+
* browser, a CLI process, or tests without environment guards.
|
|
841
|
+
*
|
|
842
|
+
* Implementations shipped here:
|
|
843
|
+
* - `InMemorySessionStorage` — map-backed, for tests.
|
|
844
|
+
*
|
|
845
|
+
* Browser-backed (`WebBrowserStorage`) lives in `@semiont/react-ui`
|
|
846
|
+
* because it touches browser-only globals.
|
|
847
|
+
*/
|
|
848
|
+
/** String key/value store with optional cross-context change subscription. */
|
|
849
|
+
interface SessionStorage {
|
|
850
|
+
/** Read a string value; null if absent. */
|
|
851
|
+
get(key: string): string | null;
|
|
852
|
+
/** Write a string value. */
|
|
853
|
+
set(key: string, value: string): void;
|
|
854
|
+
/** Remove a key. No-op if absent. */
|
|
855
|
+
delete(key: string): void;
|
|
856
|
+
/**
|
|
857
|
+
* Optional: subscribe to external changes (cross-tab, cross-process).
|
|
858
|
+
* Browser implements via the `storage` event; filesystem would use
|
|
859
|
+
* fs.watch; in-memory omits this method. Returns an unsubscribe
|
|
860
|
+
* callback. If omitted, cross-context sync simply isn't available
|
|
861
|
+
* in that environment — the session still works correctly within a
|
|
862
|
+
* single process.
|
|
863
|
+
*/
|
|
864
|
+
subscribe?(handler: (key: string, newValue: string | null) => void): () => void;
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Map-backed `SessionStorage`. Cross-context sync is not implemented;
|
|
868
|
+
* tests that need it can drive it manually.
|
|
869
|
+
*/
|
|
870
|
+
declare class InMemorySessionStorage implements SessionStorage {
|
|
871
|
+
private readonly map;
|
|
872
|
+
get(key: string): string | null;
|
|
873
|
+
set(key: string, value: string): void;
|
|
874
|
+
delete(key: string): void;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
/**
|
|
878
|
+
* SemiontSession — per-backend session lifetime object. Owns the
|
|
879
|
+
* SemiontClient, the access token BehaviorSubject, and optionally
|
|
880
|
+
* an authenticated user. One SemiontSession exists per active backend
|
|
881
|
+
* connection; lifetime is decoupled from React mount lifetime.
|
|
882
|
+
*
|
|
883
|
+
* Headless by design. Runs in browsers, CLIs, workers, and tests.
|
|
884
|
+
* UI-specific state (session-expired/permission-denied modals) lives
|
|
885
|
+
* in `FrontendSessionSignals`, which wraps a session — the session
|
|
886
|
+
* itself has no modal observables, no user-facing notifications.
|
|
887
|
+
*
|
|
888
|
+
* Auth is parameterized via callbacks passed at construction:
|
|
889
|
+
*
|
|
890
|
+
* - `refresh()` — invoked on 401 / proactive re-auth. Returns the
|
|
891
|
+
* new access token, or null on failure. The frontend passes a
|
|
892
|
+
* closure that runs the refresh-token flow; the worker passes
|
|
893
|
+
* one that exchanges the shared secret.
|
|
894
|
+
*
|
|
895
|
+
* - `validate(token)` — optional. If provided, the session calls
|
|
896
|
+
* it once at startup with the stored token to confirm it's
|
|
897
|
+
* still good and populate `user$`. Frontend passes `getMe`;
|
|
898
|
+
* worker omits this (service principals have no user record).
|
|
899
|
+
*
|
|
900
|
+
* - `onAuthFailed(message)` — optional. Invoked when refresh
|
|
901
|
+
* terminally fails (expired token, no recovery possible). The
|
|
902
|
+
* frontend wires this to `FrontendSessionSignals.notifySessionExpired`
|
|
903
|
+
* so the modal surfaces; headless consumers typically just log.
|
|
904
|
+
*
|
|
905
|
+
* Persistence goes through a `SessionStorage` adapter provided at
|
|
906
|
+
* construction — the session never touches `localStorage` or `window`
|
|
907
|
+
* directly.
|
|
908
|
+
*/
|
|
909
|
+
|
|
910
|
+
type UserInfo = components['schemas']['UserResponse'];
|
|
911
|
+
interface SemiontSessionConfig {
|
|
912
|
+
kb: KnowledgeBase;
|
|
913
|
+
/** Persistence adapter. Reads/writes tokens via this. */
|
|
914
|
+
storage: SessionStorage;
|
|
915
|
+
/**
|
|
916
|
+
* Pre-built api client. The session does not construct it — caller
|
|
917
|
+
* builds the transport stack and passes the client in. This is the
|
|
918
|
+
* seam where consumers swap one `ITransport` implementation for
|
|
919
|
+
* another (HTTP, in-process, etc.).
|
|
920
|
+
*/
|
|
921
|
+
client: SemiontClient;
|
|
922
|
+
/**
|
|
923
|
+
* Token observable shared with the transport. Caller must pass the
|
|
924
|
+
* SAME instance to both the transport (via `HttpTransport` config)
|
|
925
|
+
* and the session. The session writes refreshed tokens here; the
|
|
926
|
+
* transport reads from here.
|
|
927
|
+
*/
|
|
928
|
+
token$: BehaviorSubject<AccessToken | null>;
|
|
929
|
+
/**
|
|
930
|
+
* Re-authenticate after expiry / 401. Returns a new access token
|
|
931
|
+
* (no "Bearer " prefix) on success, or null if recovery is
|
|
932
|
+
* impossible. Omit for transports where tokens don't apply.
|
|
933
|
+
*/
|
|
934
|
+
refresh?: () => Promise<string | null>;
|
|
935
|
+
/**
|
|
936
|
+
* Validate the stored token at startup and populate `user$`. Omit
|
|
937
|
+
* for service-principal sessions (worker, CLI tools) where there
|
|
938
|
+
* is no user record to fetch.
|
|
939
|
+
*/
|
|
940
|
+
validate?: (token: AccessToken) => Promise<UserInfo | null>;
|
|
941
|
+
/**
|
|
942
|
+
* Invoked when refresh terminally fails. Frontend consumers wire
|
|
943
|
+
* this to a UI signal that surfaces the session-expired modal.
|
|
944
|
+
*/
|
|
945
|
+
onAuthFailed?: (message: string | null) => void;
|
|
946
|
+
/** Called for session-level failures (auth, refresh exhaustion). */
|
|
947
|
+
onError?: (err: SemiontError) => void;
|
|
948
|
+
}
|
|
949
|
+
declare class SemiontSession {
|
|
950
|
+
readonly kb: KnowledgeBase;
|
|
951
|
+
readonly client: SemiontClient;
|
|
952
|
+
readonly token$: BehaviorSubject<AccessToken | null>;
|
|
953
|
+
readonly user$: BehaviorSubject<UserInfo | null>;
|
|
954
|
+
readonly streamState$: Observable<ConnectionState>;
|
|
955
|
+
/** Resolves after the initial validation round-trip completes (success or failure). */
|
|
956
|
+
readonly ready: Promise<void>;
|
|
957
|
+
private readonly storage;
|
|
958
|
+
private readonly doRefresh?;
|
|
959
|
+
private readonly doValidate?;
|
|
960
|
+
private readonly onAuthFailed;
|
|
961
|
+
private readonly onError;
|
|
962
|
+
private refreshTimer;
|
|
963
|
+
private unsubscribeStorage;
|
|
964
|
+
private disposed;
|
|
965
|
+
constructor(config: SemiontSessionConfig);
|
|
966
|
+
/**
|
|
967
|
+
* Run the initial mount-time validation. If a stored access token is
|
|
968
|
+
* present and unexpired, call the configured `validate` with it to
|
|
969
|
+
* confirm it still works and populate `user$`. If expired, try
|
|
970
|
+
* refresh first. On 401 from validate, try refresh once. Surfaces
|
|
971
|
+
* auth-failed on terminal failure.
|
|
972
|
+
*
|
|
973
|
+
* When no `validate` callback is provided (service principals), this
|
|
974
|
+
* still runs through the refresh-if-expired step so the stored
|
|
975
|
+
* token is current — it just skips the user-validation round trip.
|
|
976
|
+
*/
|
|
977
|
+
private validate;
|
|
978
|
+
/**
|
|
979
|
+
* Refresh the access token via the configured `refresh` callback.
|
|
980
|
+
* On success, pushes the new token into `token$` and schedules the
|
|
981
|
+
* next proactive refresh. On failure, clears persisted state and
|
|
982
|
+
* fires `onAuthFailed` — the frontend's wiring of that callback is
|
|
983
|
+
* what surfaces the session-expired modal.
|
|
984
|
+
*/
|
|
985
|
+
refresh(): Promise<AccessToken | null>;
|
|
986
|
+
private scheduleProactiveRefresh;
|
|
987
|
+
private clearRefreshTimer;
|
|
988
|
+
/**
|
|
989
|
+
* Cross-context sync: another tab/process refreshed or signed out this
|
|
990
|
+
* KB. Mirror the change into our in-memory state.
|
|
991
|
+
*/
|
|
992
|
+
private handleStorageChange;
|
|
993
|
+
get expiresAt(): Date | null;
|
|
994
|
+
/**
|
|
995
|
+
* Subscribe to a session-bus channel. The single sanctioned escape hatch
|
|
996
|
+
* for generic-channel subscription (the case `useEventSubscription` needs
|
|
997
|
+
* — channel name is a hook parameter, not known statically). All other
|
|
998
|
+
* consumers must call typed namespace methods (e.g. `session.client.mark.archive(...)`).
|
|
999
|
+
*
|
|
1000
|
+
* @returns disposer that unsubscribes the handler.
|
|
1001
|
+
*/
|
|
1002
|
+
subscribe<K extends keyof EventMap>(channel: K, handler: (payload: EventMap[K]) => void): () => void;
|
|
1003
|
+
dispose(): Promise<void>;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
/**
|
|
1007
|
+
* OpenResource — a single entry in the open-resources list (tabs).
|
|
1008
|
+
*
|
|
1009
|
+
* The list itself lives on `SemiontBrowser.openResources$`. The CRUD
|
|
1010
|
+
* methods (`addOpenResource`, `removeOpenResource`, `updateOpenResourceName`,
|
|
1011
|
+
* `reorderOpenResources`) live on `SemiontBrowser` too.
|
|
1012
|
+
*/
|
|
1013
|
+
interface OpenResource {
|
|
1014
|
+
/** Unique identifier for the resource */
|
|
1015
|
+
id: string;
|
|
1016
|
+
/** Display name of the resource */
|
|
1017
|
+
name: string;
|
|
1018
|
+
/** Timestamp when the resource was opened */
|
|
1019
|
+
openedAt: number;
|
|
1020
|
+
/** Order/position for manual sorting (optional for backward compatibility) */
|
|
1021
|
+
order?: number;
|
|
1022
|
+
/** Media type for icon display (e.g., 'application/pdf', 'text/plain') */
|
|
1023
|
+
mediaType?: string;
|
|
1024
|
+
/** Working-tree URI (e.g. "file://docs/overview.md") — used as tooltip in navigation */
|
|
1025
|
+
storageUri?: string;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
/**
|
|
1029
|
+
* FrontendSessionSignals — modal state that belongs to the UI, not
|
|
1030
|
+
* the session itself.
|
|
1031
|
+
*
|
|
1032
|
+
* `SemiontSession` is a headless per-backend client + token + user
|
|
1033
|
+
* holder. It can run in any process: browser, worker, CLI, test. But
|
|
1034
|
+
* the session-expired / permission-denied *modals* only make sense
|
|
1035
|
+
* in a UI context. Keeping those observables on `SemiontSession`
|
|
1036
|
+
* meant workers and CLIs carried four dead BehaviorSubjects that
|
|
1037
|
+
* nothing would ever fire.
|
|
1038
|
+
*
|
|
1039
|
+
* `FrontendSessionSignals` owns the modal state and has no hard
|
|
1040
|
+
* reference to a session. `SemiontBrowser` constructs one alongside
|
|
1041
|
+
* every frontend session and wires:
|
|
1042
|
+
*
|
|
1043
|
+
* - `session.onAuthFailed` → `signals.notifySessionExpired` so
|
|
1044
|
+
* proactive-refresh failures surface as modals
|
|
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
|
|
1048
|
+
*
|
|
1049
|
+
* React consumers that need modal state subscribe here; consumers
|
|
1050
|
+
* that need bus/HTTP access continue to subscribe to the session.
|
|
1051
|
+
*
|
|
1052
|
+
* Session auth-state cleanup (clearing token, clearing storage) is
|
|
1053
|
+
* the session's own responsibility inside `refresh()` — by the time
|
|
1054
|
+
* `notifySessionExpired` runs, the session has already torn down.
|
|
1055
|
+
* Signals only surfaces the modal.
|
|
1056
|
+
*/
|
|
1057
|
+
|
|
1058
|
+
declare class FrontendSessionSignals {
|
|
1059
|
+
readonly sessionExpiredAt$: BehaviorSubject<number | null>;
|
|
1060
|
+
readonly sessionExpiredMessage$: BehaviorSubject<string | null>;
|
|
1061
|
+
readonly permissionDeniedAt$: BehaviorSubject<number | null>;
|
|
1062
|
+
readonly permissionDeniedMessage$: BehaviorSubject<string | null>;
|
|
1063
|
+
constructor();
|
|
1064
|
+
notifySessionExpired(message: string | null): void;
|
|
1065
|
+
notifyPermissionDenied(message: string | null): void;
|
|
1066
|
+
acknowledgeSessionExpired(): void;
|
|
1067
|
+
acknowledgePermissionDenied(): void;
|
|
1068
|
+
dispose(): void;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
/**
|
|
1072
|
+
* SemiontBrowser — top-level app-facing container for non-KB state.
|
|
1073
|
+
*
|
|
1074
|
+
* Holds the list of configured KBs, the active KB selection, the active
|
|
1075
|
+
* SemiontSession, the identity token, the open-resources list, and a
|
|
1076
|
+
* session-level error stream. Module-scoped singleton — survives every
|
|
1077
|
+
* React re-render, remount, and route change. `SemiontProvider` hands
|
|
1078
|
+
* the singleton to the React tree; `useSemiont()` returns it.
|
|
1079
|
+
*
|
|
1080
|
+
* Persistence goes through a `SessionStorage` adapter provided at
|
|
1081
|
+
* construction — the browser never touches `localStorage` or `window`
|
|
1082
|
+
* directly.
|
|
1083
|
+
*/
|
|
1084
|
+
|
|
1085
|
+
interface SemiontBrowserConfig {
|
|
1086
|
+
/** Persistence adapter. The browser reads/writes all persisted state via this. */
|
|
1087
|
+
storage: SessionStorage;
|
|
1088
|
+
}
|
|
1089
|
+
declare class SemiontBrowser {
|
|
1090
|
+
readonly kbs$: BehaviorSubject<KnowledgeBase[]>;
|
|
1091
|
+
readonly activeKbId$: BehaviorSubject<string | null>;
|
|
1092
|
+
readonly activeSession$: BehaviorSubject<SemiontSession | null>;
|
|
1093
|
+
/**
|
|
1094
|
+
* Modal signals (session-expired / permission-denied) for the
|
|
1095
|
+
* currently-active session. Parallels `activeSession$` — always
|
|
1096
|
+
* non-null when `activeSession$` is non-null, always null when it
|
|
1097
|
+
* is. Extracted from the session itself so headless sessions
|
|
1098
|
+
* (workers, CLIs, tests) don't carry dead modal observables.
|
|
1099
|
+
* See [FrontendSessionSignals](./frontend-session-signals.ts).
|
|
1100
|
+
*/
|
|
1101
|
+
readonly activeSignals$: BehaviorSubject<FrontendSessionSignals | null>;
|
|
1102
|
+
/**
|
|
1103
|
+
* True while a session is actively being constructed (setActiveKb /
|
|
1104
|
+
* signIn in flight, awaiting `session.ready`). Distinguishes the
|
|
1105
|
+
* "session about to arrive" intermediate state from "session
|
|
1106
|
+
* intentionally null" (after signOut, or when the active KB has no
|
|
1107
|
+
* stored credentials). UIs that want a loading spinner should gate
|
|
1108
|
+
* on this; otherwise they get stuck spinning after every signOut.
|
|
1109
|
+
*/
|
|
1110
|
+
readonly sessionActivating$: BehaviorSubject<boolean>;
|
|
1111
|
+
readonly openResources$: BehaviorSubject<OpenResource[]>;
|
|
1112
|
+
readonly error$: Subject<SemiontError>;
|
|
1113
|
+
readonly identityToken$: BehaviorSubject<string | null>;
|
|
1114
|
+
private readonly storage;
|
|
1115
|
+
/**
|
|
1116
|
+
* App-scoped EventBus. Hosts UI-shell events that must work regardless
|
|
1117
|
+
* of whether a KB session is active: panel toggles, sidebar state,
|
|
1118
|
+
* tab reorders, routing, settings, etc. Disjoint from the per-session
|
|
1119
|
+
* bus inside `SemiontClient`, which carries KB-content events
|
|
1120
|
+
* (mark:*, beckon:*, gather:*, match:*, bind:*, yield:*, browse:click).
|
|
1121
|
+
*/
|
|
1122
|
+
private readonly eventBus;
|
|
1123
|
+
private unregisterNotify;
|
|
1124
|
+
private unsubscribeStorage;
|
|
1125
|
+
private disposed;
|
|
1126
|
+
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
|
+
constructor(config: SemiontBrowserConfig);
|
|
1136
|
+
/** Emit an event on the browser's app-scoped bus. */
|
|
1137
|
+
emit<K extends keyof EventMap>(channel: K, payload: EventMap[K]): void;
|
|
1138
|
+
/** Subscribe to an event; returns unsubscribe. */
|
|
1139
|
+
on<K extends keyof EventMap>(channel: K, handler: (payload: EventMap[K]) => void): () => void;
|
|
1140
|
+
/** Read-only observable for an app-scoped channel. */
|
|
1141
|
+
stream<K extends keyof EventMap>(channel: K): Observable<EventMap[K]>;
|
|
1142
|
+
/**
|
|
1143
|
+
* Set the app-level identity token (from NextAuth's useSession).
|
|
1144
|
+
* Called at the root layout via a single `useEffect`. No other site
|
|
1145
|
+
* in the codebase should call this.
|
|
1146
|
+
*/
|
|
1147
|
+
setIdentityToken(token: string | null): void;
|
|
1148
|
+
addKb(input: NewKnowledgeBase, access: string, refresh: string): KnowledgeBase;
|
|
1149
|
+
removeKb(id: string): void;
|
|
1150
|
+
updateKb(id: string, updates: Partial<KnowledgeBase>): void;
|
|
1151
|
+
/**
|
|
1152
|
+
* Read the locally-stored credential status for a KB. Pure / synchronous —
|
|
1153
|
+
* does not subscribe to context changes. Used by KB-list UI to color status
|
|
1154
|
+
* dots without requiring re-renders on every tick.
|
|
1155
|
+
*/
|
|
1156
|
+
getKbSessionStatus(kbId: string): KbSessionStatus;
|
|
1157
|
+
/**
|
|
1158
|
+
* Switch the active KB. Follows the D2 disposal contract:
|
|
1159
|
+
* 1. Synchronously announce the new id on `activeKbId$` and null out
|
|
1160
|
+
* `activeSession$` so views see a safe empty state first.
|
|
1161
|
+
* 2. Serialize overlapping calls — if an activation is in flight, wait
|
|
1162
|
+
* for it before proceeding.
|
|
1163
|
+
* 3. Dispose whatever session is currently live.
|
|
1164
|
+
* 4. Construct the next session and await `session.ready`.
|
|
1165
|
+
* 5. Before emitting, re-check `activeKbId$` — if a newer call superseded
|
|
1166
|
+
* us while we waited, dispose our session and skip the emit.
|
|
1167
|
+
* 6. Emit the new session.
|
|
1168
|
+
*/
|
|
1169
|
+
setActiveKb(id: string | null): Promise<void>;
|
|
1170
|
+
/**
|
|
1171
|
+
* Sign in to an existing KB: store the tokens and (re)activate the
|
|
1172
|
+
* session. If the KB is already active, the current session is disposed
|
|
1173
|
+
* and replaced so the new tokens take effect.
|
|
1174
|
+
*/
|
|
1175
|
+
signIn(id: string, access: string, refresh: string): Promise<void>;
|
|
1176
|
+
/**
|
|
1177
|
+
* Sign out of a KB: clear stored tokens. If the KB is active, dispose
|
|
1178
|
+
* its session + signals and emit null for both.
|
|
1179
|
+
*/
|
|
1180
|
+
signOut(id: string): Promise<void>;
|
|
1181
|
+
addOpenResource(id: string, name: string, mediaType?: string, storageUri?: string): void;
|
|
1182
|
+
removeOpenResource(id: string): void;
|
|
1183
|
+
updateOpenResourceName(id: string, name: string): void;
|
|
1184
|
+
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
|
+
dispose(): Promise<void>;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
/**
|
|
1210
|
+
* Module-scoped singleton for SemiontBrowser. Constructed lazily on first
|
|
1211
|
+
* `getBrowser()` call, survives every React re-render, remount, and route
|
|
1212
|
+
* change.
|
|
1213
|
+
*
|
|
1214
|
+
* The caller provides a `SessionStorage` implementation — there is no
|
|
1215
|
+
* default here because storage-backend selection is environment-specific
|
|
1216
|
+
* (browsers use `WebBrowserStorage`, CLI uses a filesystem adapter,
|
|
1217
|
+
* tests use `InMemorySessionStorage`). The first call to `getBrowser`
|
|
1218
|
+
* wins; subsequent calls return the cached instance regardless of the
|
|
1219
|
+
* storage passed.
|
|
1220
|
+
*/
|
|
1221
|
+
|
|
1222
|
+
interface GetBrowserOptions {
|
|
1223
|
+
/** Persistence adapter used to construct the singleton on first call. */
|
|
1224
|
+
storage: SessionStorage;
|
|
1225
|
+
}
|
|
1226
|
+
declare function getBrowser(options: GetBrowserOptions): SemiontBrowser;
|
|
1227
|
+
|
|
1228
|
+
/**
|
|
1229
|
+
* Pure helpers and storage-adapter-driven loaders for the Semiont
|
|
1230
|
+
* session layer.
|
|
1231
|
+
*
|
|
1232
|
+
* Contains:
|
|
1233
|
+
* - Storage key shape (constants, `sessionKey(kbId)`)
|
|
1234
|
+
* - JWT expiry parsing and "is expired" check
|
|
1235
|
+
* - URL/protocol helpers for KB instances
|
|
1236
|
+
* - Loaders/savers that take a `SessionStorage` and operate over it
|
|
1237
|
+
* (no direct `localStorage` access)
|
|
1238
|
+
*
|
|
1239
|
+
* No React imports, no module-scoped state, no side effects beyond
|
|
1240
|
+
* whatever the passed-in `SessionStorage` does.
|
|
1241
|
+
*/
|
|
1242
|
+
|
|
1243
|
+
/** The shape persisted per KB. */
|
|
1244
|
+
interface StoredSession {
|
|
1245
|
+
access: string;
|
|
1246
|
+
refresh: string;
|
|
1247
|
+
}
|
|
1248
|
+
declare function setStoredSession(storage: SessionStorage, kbId: string, session: StoredSession): void;
|
|
1249
|
+
declare function defaultProtocol(host: string): 'http' | 'https';
|
|
1250
|
+
declare function isValidHostname(host: string): boolean;
|
|
1251
|
+
declare function kbBackendUrl(kb: KnowledgeBase): string;
|
|
1252
|
+
|
|
1253
|
+
declare function notifySessionExpired(message?: string): void;
|
|
1254
|
+
declare function notifyPermissionDenied(message?: string): void;
|
|
1255
|
+
|
|
1256
|
+
interface ViewModel {
|
|
1257
|
+
dispose(): void;
|
|
1258
|
+
}
|
|
1259
|
+
declare function createDisposer(): {
|
|
1260
|
+
add(vm: ViewModel | (() => void)): void;
|
|
1261
|
+
dispose(): void;
|
|
1262
|
+
};
|
|
1263
|
+
|
|
1264
|
+
/**
|
|
1265
|
+
* createSearchPipeline
|
|
1266
|
+
*
|
|
1267
|
+
* A debounced-search RxJS pipeline factory. Combines an input Subject with a
|
|
1268
|
+
* downstream fetch function and emits typed `{ results, isSearching }` state.
|
|
1269
|
+
*
|
|
1270
|
+
* Designed to be created once per component instance via React's
|
|
1271
|
+
* `useState(() => createSearchPipeline(...))` lazy initializer, then consumed
|
|
1272
|
+
* via `useObservable(pipeline.state$)`. The pipeline holds no React state and
|
|
1273
|
+
* has no React imports — it's pure RxJS, unit-testable without a renderer.
|
|
1274
|
+
*
|
|
1275
|
+
* The fetch function is expected to return `Observable<T[] | undefined>`,
|
|
1276
|
+
* matching the cache-miss-then-data shape of `BrowseNamespace` Observables:
|
|
1277
|
+
* `undefined` means "fetch in flight, no value yet"; an array means "data
|
|
1278
|
+
* available (possibly empty)".
|
|
1279
|
+
*/
|
|
1280
|
+
|
|
1281
|
+
interface SearchState<T> {
|
|
1282
|
+
results: T[];
|
|
1283
|
+
isSearching: boolean;
|
|
1284
|
+
}
|
|
1285
|
+
interface SearchPipeline<T> {
|
|
1286
|
+
/** Latest query string. Bind to a controlled input via `useObservable`. */
|
|
1287
|
+
query$: Observable<string>;
|
|
1288
|
+
/** Latest search state — results plus a loading flag. */
|
|
1289
|
+
state$: Observable<SearchState<T>>;
|
|
1290
|
+
/** Push a new query value. Triggers the debounced fetch. */
|
|
1291
|
+
setQuery(value: string): void;
|
|
1292
|
+
/** Tear down the input Subject. Call from `useEffect` cleanup. */
|
|
1293
|
+
dispose(): void;
|
|
1294
|
+
}
|
|
1295
|
+
interface SearchPipelineOptions {
|
|
1296
|
+
/** Milliseconds to wait after the last keystroke before fetching. Default 250. */
|
|
1297
|
+
debounceMs?: number;
|
|
1298
|
+
/** Initial query value. Useful for modals that open with a pre-filled term. */
|
|
1299
|
+
initialQuery?: string;
|
|
1300
|
+
}
|
|
1301
|
+
declare function createSearchPipeline<T>(fetch: (query: string) => Observable<T[] | undefined>, options?: SearchPipelineOptions): SearchPipeline<T>;
|
|
1302
|
+
|
|
1303
|
+
interface BeckonVM extends ViewModel {
|
|
1304
|
+
hoveredAnnotationId$: Observable<AnnotationId | null>;
|
|
1305
|
+
hover(annotationId: AnnotationId | null): void;
|
|
1306
|
+
focus(annotationId: AnnotationId): void;
|
|
1307
|
+
sparkle(annotationId: AnnotationId): void;
|
|
1308
|
+
}
|
|
1309
|
+
declare function createBeckonVM(client: SemiontClient): BeckonVM;
|
|
1310
|
+
/** Default milliseconds the mouse must dwell before beckon:hover is emitted. */
|
|
1311
|
+
declare const HOVER_DELAY_MS = 150;
|
|
1312
|
+
type EmitHover = (annotationId: AnnotationId | null) => void;
|
|
1313
|
+
interface HoverHandlers {
|
|
1314
|
+
handleMouseEnter: (annotationId: AnnotationId) => void;
|
|
1315
|
+
handleMouseLeave: () => void;
|
|
1316
|
+
cleanup: () => void;
|
|
1317
|
+
}
|
|
1318
|
+
declare function createHoverHandlers(emit: EmitHover, delayMs: number): HoverHandlers;
|
|
1319
|
+
|
|
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 {
|
|
1352
|
+
context$: Observable<GatheredContext | null>;
|
|
1353
|
+
loading$: Observable<boolean>;
|
|
1354
|
+
error$: Observable<Error | null>;
|
|
1355
|
+
annotationId$: Observable<AnnotationId | null>;
|
|
1356
|
+
}
|
|
1357
|
+
declare function createGatherVM(client: SemiontClient, resourceId: ResourceId): GatherVM;
|
|
1358
|
+
|
|
1359
|
+
interface MatchVM extends ViewModel {
|
|
1360
|
+
}
|
|
1361
|
+
declare function createMatchVM(client: SemiontClient, _resourceId: ResourceId): MatchVM;
|
|
1362
|
+
|
|
1363
|
+
type JobProgress$1 = components['schemas']['JobProgress'];
|
|
1364
|
+
interface GenerateDocumentOptions {
|
|
1365
|
+
title: string;
|
|
1366
|
+
storageUri: string;
|
|
1367
|
+
prompt?: string;
|
|
1368
|
+
language?: string;
|
|
1369
|
+
temperature?: number;
|
|
1370
|
+
maxTokens?: number;
|
|
1371
|
+
context: GatheredContext;
|
|
1372
|
+
}
|
|
1373
|
+
interface YieldVM extends ViewModel {
|
|
1374
|
+
isGenerating$: Observable<boolean>;
|
|
1375
|
+
progress$: Observable<JobProgress$1 | null>;
|
|
1376
|
+
generate(referenceId: string, options: GenerateDocumentOptions): void;
|
|
1377
|
+
}
|
|
1378
|
+
declare function createYieldVM(client: SemiontClient, resourceId: ResourceId, locale: string): YieldVM;
|
|
1379
|
+
|
|
1380
|
+
type JobProgress = components['schemas']['JobProgress'];
|
|
1381
|
+
interface PendingAnnotation {
|
|
1382
|
+
selector: Selector | Selector[];
|
|
1383
|
+
motivation: Motivation;
|
|
1384
|
+
}
|
|
1385
|
+
interface MarkVM extends ViewModel {
|
|
1386
|
+
pendingAnnotation$: Observable<PendingAnnotation | null>;
|
|
1387
|
+
assistingMotivation$: Observable<Motivation | null>;
|
|
1388
|
+
progress$: Observable<JobProgress | null>;
|
|
1389
|
+
}
|
|
1390
|
+
declare function createMarkVM(client: SemiontClient, resourceId: ResourceId): MarkVM;
|
|
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;
|
|
1687
|
+
|
|
1688
|
+
export { type ActiveJob, AdminNamespace, type AdminSecurityVM, type AdminUsersVM, type AnnotationGroups, type AnnotationHistoryResponse, AuthNamespace, BeckonNamespace, type BeckonVM, BindNamespace, BrowseNamespace, BusRequestError, type BusRequestPrimitive, COMMON_PANELS, type Cache, type CloneData, type ComposeMode, type ComposePageVM, type ComposeParams, type CreateAnnotationInput, type CreateFromTokenOptions, type CreateResourceInput, type DiscoverVM, type EntityTagsVM, type ExchangeVM, FrontendSessionSignals, type GatherAnnotationProgress, GatherNamespace, type GatherVM, type GenerateDocumentOptions, type GenerationOptions, type GetBrowserOptions, HOVER_DELAY_MS, type HoverHandlers, type ImportPreview, InMemorySessionStorage, type Job, type JobAssignment, type JobClaimAdapter, type JobClaimAdapterOptions, JobNamespace, type JobQueueVM, type KbSessionStatus, type KnowledgeBase, type MarkAssistEvent, type MarkAssistOptions, type MarkAssistProgress, MarkNamespace, type MarkVM, MatchNamespace, type MatchSearchProgress, type MatchVM, type NewKnowledgeBase, type OpenResource, type PendingAnnotation, RESOURCE_PANELS, type ReferenceData, type ReferencedByEntry, type RequestContent, type ResourceLoaderVM, type ResourceViewerPageVM, type ResponseContent, type SaveResourceParams, type SearchPipeline, type SearchPipelineOptions, type SearchState, SemiontBrowser, type SemiontBrowserConfig, SemiontClient, SemiontError, type SemiontErrorCode, SemiontSession, type SemiontSessionConfig, type SessionStorage, type SessionVM, type ShellVM, type ShellVMOptions, type SmelterActorVM, type SmelterActorVMOptions, type SmelterEvent, type StoredSession, type ToolbarPanelType, type User, type UserInfo, type ViewModel, type WelcomeVM, type WizardState, type YieldGenerationEvent, YieldNamespace, type YieldVM, busRequest, createAdminSecurityVM, createAdminUsersVM, createBeckonVM, createCache, createComposePageVM, createDiscoverVM, createDisposer, createEntityTagsVM, createExchangeVM, createGatherVM, createHoverHandlers, createJobClaimAdapter, createJobQueueVM, createMarkVM, createMatchVM, createResourceLoaderVM, createResourceViewerPageVM, createSearchPipeline, createSessionVM, createShellVM, createSmelterActorVM, createWelcomeVM, createYieldVM, defaultProtocol, getBrowser, isValidHostname, kbBackendUrl, notifyPermissionDenied, notifySessionExpired, setStoredSession };
|