@semiont/api-client 0.4.19 → 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 +18 -6
- package/dist/index.d.ts +1211 -487
- package/dist/index.js +3097 -896
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,272 +1,57 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { BaseUrl, Logger, ResourceId, AccessToken, components, UserDID, paths, AnnotationId, GraphConnection, UpdateResourceInput, Motivation, MarkProgress, BodyOperation, GatheredContext, YieldProgress as YieldProgress$1, JobId, EventBus, Email, RefreshToken, GoogleCredential, ContentFormat, SearchQuery, CloneToken, EntityType } from '@semiont/core';
|
|
1
|
+
import { components, UserDID, paths, ResourceId, AnnotationId, GraphConnection, UpdateResourceInput, Motivation, BodyOperation, GatheredContext, JobId, EventBus, AccessToken, BaseUrl, Logger, EventMap, Email, RefreshToken, GoogleCredential, ContentFormat, SearchQuery, CloneToken, EntityType, Selector } from '@semiont/core';
|
|
3
2
|
export { Logger, Selector, getFragmentSelector, getSvgSelector, getTextPositionSelector, validateSvgMarkup } from '@semiont/core';
|
|
4
|
-
import { Observable } from 'rxjs';
|
|
3
|
+
import { Observable, BehaviorSubject, Subject } from 'rxjs';
|
|
5
4
|
export { BoundingBox, ContentCache, FragmentSelector, JWTTokenSchema, LOCALES, LocaleInfo, MatchQuality, Point, SvgSelector, TextPosition, TextPositionSelector, TextQuoteSelector, ValidatedAnnotation, ValidationFailure, ValidationResult, ValidationSuccess, buildContentCache, createCircleSvg, createPolygonSvg, createRectangleSvg, decodeRepresentation, decodeWithCharset, extractBoundingBox, extractCharset, extractContext, findBestTextMatch, findTextWithContext, formatLocaleDisplay, getAllLocaleCodes, getAnnotationExactText, getBodySource, getBodyType, getChecksum, getCommentText, getCreator, getDerivedFrom, getExactText, getLanguage, getLocaleEnglishName, getLocaleInfo, getLocaleNativeName, getNodeEncoding, getPrimaryMediaType, getPrimaryRepresentation, getPrimarySelector, getResourceEntityTypes, getResourceId, getStorageUri, getTargetSelector, getTargetSource, getTextQuoteSelector, hasTargetSelector, isArchived, isAssessment, isBodyResolved, isComment, isDraft, isHighlight, isReference, isResolvedReference, isStubReference, isTag, isValidEmail, normalizeCoordinates, normalizeText, parseSvgSelector, scaleSvgToNative, validateAndCorrectOffsets, validateData, verifyPosition } from './utils/index.js';
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
*
|
|
10
|
-
* Progress and result types for events delivered via the long-lived
|
|
11
|
-
* events-stream. These match the payloads emitted by job workers on
|
|
12
|
-
* the resource-scoped EventBus. Used by the MCP server for type-safe
|
|
13
|
-
* event handling.
|
|
14
|
-
*/
|
|
15
|
-
/**
|
|
16
|
-
* Progress event for reference/linking detection stream
|
|
17
|
-
*
|
|
18
|
-
* Sent by POST /resources/:id/annotate-references
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```typescript
|
|
22
|
-
* stream.onProgress((progress: ReferenceDetectionProgress) => {
|
|
23
|
-
* if (progress.status === 'scanning') {
|
|
24
|
-
* console.log(`Scanning for ${progress.currentEntityType}...`);
|
|
25
|
-
* console.log(`Progress: ${progress.processedEntityTypes}/${progress.totalEntityTypes}`);
|
|
26
|
-
* }
|
|
27
|
-
* });
|
|
28
|
-
* ```
|
|
29
|
-
*/
|
|
30
|
-
interface ReferenceDetectionProgress {
|
|
31
|
-
/** Current status of detection operation */
|
|
32
|
-
status: 'started' | 'scanning' | 'complete' | 'error';
|
|
33
|
-
/** Resource ID being scanned */
|
|
34
|
-
resourceId: string;
|
|
35
|
-
/** Currently scanning for this entity type (only present during 'scanning') */
|
|
36
|
-
currentEntityType?: string;
|
|
37
|
-
/** Total number of entity types to scan */
|
|
38
|
-
totalEntityTypes: number;
|
|
39
|
-
/** Number of entity types processed so far */
|
|
40
|
-
processedEntityTypes: number;
|
|
41
|
-
/** Human-readable status message */
|
|
42
|
-
message?: string;
|
|
43
|
-
/** Total entities found (only present in 'complete') */
|
|
44
|
-
foundCount?: number;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Progress event for resource generation stream
|
|
48
|
-
*
|
|
49
|
-
* Sent by POST /resources/:resourceId/annotations/:annotationId/yield-resource
|
|
50
|
-
*
|
|
51
|
-
* @example
|
|
52
|
-
* ```typescript
|
|
53
|
-
* stream.onProgress((progress: YieldProgress) => {
|
|
54
|
-
* console.log(`${progress.status}: ${progress.percentage}%`);
|
|
55
|
-
* console.log(progress.message);
|
|
56
|
-
* });
|
|
57
|
-
* ```
|
|
58
|
-
*/
|
|
59
|
-
interface YieldProgress {
|
|
60
|
-
/** Current stage of generation operation */
|
|
61
|
-
status: 'started' | 'fetching' | 'generating' | 'creating' | 'complete' | 'error';
|
|
62
|
-
/** Annotation ID being used as source */
|
|
63
|
-
referenceId: string;
|
|
64
|
-
/** Name of resource being generated */
|
|
65
|
-
resourceName?: string;
|
|
66
|
-
/** ID of generated resource (only present in 'complete') */
|
|
67
|
-
resourceId?: string;
|
|
68
|
-
/** ID of source resource */
|
|
69
|
-
sourceResourceId?: string;
|
|
70
|
-
/** Percentage complete (0-100) */
|
|
71
|
-
percentage: number;
|
|
72
|
-
/** Human-readable status message */
|
|
73
|
-
message?: string;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Resource event from real-time event stream
|
|
77
|
-
*
|
|
78
|
-
* Sent by GET /resources/:id/events/stream
|
|
79
|
-
*
|
|
80
|
-
* This represents a single event from the event store, broadcast in real-time
|
|
81
|
-
* as it occurs. Used for real-time collaboration - multiple users see each
|
|
82
|
-
* other's changes as they happen.
|
|
83
|
-
*
|
|
84
|
-
* Re-exported from @semiont/core (authoritative source).
|
|
85
|
-
* The discriminated union type provides type-safe event handling.
|
|
86
|
-
*
|
|
87
|
-
* @example
|
|
88
|
-
* ```typescript
|
|
89
|
-
* stream.onEvent((event) => {
|
|
90
|
-
* console.log(`Event: ${event.type}`);
|
|
91
|
-
* console.log(`User: ${event.userId}`);
|
|
92
|
-
* console.log(`Payload:`, event.payload);
|
|
93
|
-
* });
|
|
94
|
-
* ```
|
|
95
|
-
*/
|
|
96
|
-
/**
|
|
97
|
-
* SSE stream controller interface
|
|
98
|
-
*
|
|
99
|
-
* Returned by all SSE methods. Events auto-emit to EventBus (required).
|
|
100
|
-
*
|
|
101
|
-
* **Architecture Note**: All SSE methods require `eventBus` in options to enforce
|
|
102
|
-
* event-driven architecture. This is enforced at compile time via TypeScript.
|
|
103
|
-
*
|
|
104
|
-
* @example
|
|
105
|
-
* ```typescript
|
|
106
|
-
* const eventBus = new EventBus();
|
|
107
|
-
*
|
|
108
|
-
* // Subscribe to events
|
|
109
|
-
* eventBus.get('detection:progress').subscribe((p) => console.log(p.message));
|
|
110
|
-
* eventBus.get('detection:complete').subscribe(() => console.log('Done!'));
|
|
111
|
-
* eventBus.get('detection:failed').subscribe(({ error }) => console.error(error));
|
|
112
|
-
*
|
|
113
|
-
* // Start stream - eventBus is required (TypeScript enforced)
|
|
114
|
-
* const stream = client.sse.markReferences(resourceId, request, { auth, eventBus });
|
|
115
|
-
*
|
|
116
|
-
* // Cleanup when done
|
|
117
|
-
* stream.close();
|
|
118
|
-
* ```
|
|
119
|
-
*/
|
|
120
|
-
interface SSEStream {
|
|
121
|
-
/**
|
|
122
|
-
* Close the SSE stream and abort the connection
|
|
123
|
-
*
|
|
124
|
-
* Should be called to cleanup resources when stream is no longer needed.
|
|
125
|
-
* Safe to call multiple times.
|
|
126
|
-
*
|
|
127
|
-
* @example
|
|
128
|
-
* ```typescript
|
|
129
|
-
* // React cleanup
|
|
130
|
-
* useEffect(() => {
|
|
131
|
-
* const stream = client.sse.markReferences(..., { auth, eventBus });
|
|
132
|
-
* return () => stream.close();
|
|
133
|
-
* }, []);
|
|
134
|
-
* ```
|
|
135
|
-
*/
|
|
136
|
-
close(): void;
|
|
6
|
+
interface ViewModel {
|
|
7
|
+
dispose(): void;
|
|
137
8
|
}
|
|
9
|
+
declare function createDisposer(): {
|
|
10
|
+
add(vm: ViewModel | (() => void)): void;
|
|
11
|
+
dispose(): void;
|
|
12
|
+
};
|
|
138
13
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
declare const SSE_STREAM_CONNECTED: "stream-connected";
|
|
144
|
-
type SSEStreamConnected = typeof SSE_STREAM_CONNECTED;
|
|
145
|
-
/**
|
|
146
|
-
* SSE Client configuration
|
|
147
|
-
*/
|
|
148
|
-
interface SSEClientConfig {
|
|
149
|
-
baseUrl: BaseUrl;
|
|
150
|
-
logger?: Logger;
|
|
14
|
+
interface BusEvent {
|
|
15
|
+
channel: string;
|
|
16
|
+
payload: Record<string, unknown>;
|
|
17
|
+
scope?: string;
|
|
151
18
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
eventBus: _semiont_core.EventBus;
|
|
19
|
+
interface ActorVMOptions {
|
|
20
|
+
baseUrl: string;
|
|
21
|
+
token: string | (() => string);
|
|
22
|
+
channels: string[];
|
|
23
|
+
scope?: string;
|
|
24
|
+
reconnectMs?: number;
|
|
159
25
|
}
|
|
160
26
|
/**
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
* This client has three methods — one per long-lived broadcast stream.
|
|
164
|
-
* Per-operation SSE routes have been replaced by plain HTTP POSTs with
|
|
165
|
-
* results delivered via the events-stream.
|
|
166
|
-
*
|
|
167
|
-
* Uses native fetch() instead of ky for SSE support.
|
|
168
|
-
* Auth tokens are passed per-request via options.
|
|
169
|
-
*
|
|
170
|
-
* @example
|
|
171
|
-
* ```typescript
|
|
172
|
-
* const sseClient = new SSEClient({ baseUrl: 'http://localhost:4000' });
|
|
27
|
+
* Connection state exposed by the SSE bus actor.
|
|
173
28
|
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
29
|
+
* initial ─ before start() has been called
|
|
30
|
+
* connecting ─ fetch() in flight, no bytes yet
|
|
31
|
+
* open ─ SSE stream live, first byte seen
|
|
32
|
+
* reconnecting ─ open → dropped, retrying; may be transient
|
|
33
|
+
* degraded ─ has been reconnecting for > DEGRADED_THRESHOLD_MS;
|
|
34
|
+
* UI banner threshold; distinguishes brief mount-
|
|
35
|
+
* churn cycles from sustained disconnection
|
|
36
|
+
* closed ─ stop()/dispose() called; terminal
|
|
176
37
|
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
* // Close when done
|
|
181
|
-
* stream.close();
|
|
182
|
-
* ```
|
|
38
|
+
* Transition rules are enforced by a helper that throws on invalid
|
|
39
|
+
* transitions — catches bugs in the reconnect loop that would
|
|
40
|
+
* otherwise strand the observable in a lying value.
|
|
183
41
|
*/
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
* Opens a long-lived SSE connection to receive real-time events for a resource.
|
|
196
|
-
* Used for collaborative editing - see events from other users as they happen.
|
|
197
|
-
*
|
|
198
|
-
* This stream does NOT have a complete event - it stays open until explicitly closed.
|
|
199
|
-
*
|
|
200
|
-
* @param resourceId - Resource URI or ID to subscribe to
|
|
201
|
-
* @param options - Request options (auth token)
|
|
202
|
-
* @returns SSE stream controller with event callback
|
|
203
|
-
*
|
|
204
|
-
* @example
|
|
205
|
-
* ```typescript
|
|
206
|
-
* const stream = sseClient.resourceEvents(
|
|
207
|
-
* 'http://localhost:4000/resources/doc-123',
|
|
208
|
-
* { auth: 'your-token' }
|
|
209
|
-
* );
|
|
210
|
-
*
|
|
211
|
-
* stream.onProgress((event) => {
|
|
212
|
-
* console.log(`Event: ${event.type}`);
|
|
213
|
-
* console.log(`User: ${event.userId}`);
|
|
214
|
-
* console.log(`Sequence: ${event.metadata.sequenceNumber}`);
|
|
215
|
-
* console.log(`Payload:`, event.payload);
|
|
216
|
-
* });
|
|
217
|
-
*
|
|
218
|
-
* stream.onError((error) => {
|
|
219
|
-
* console.error('Stream error:', error.message);
|
|
220
|
-
* });
|
|
221
|
-
*
|
|
222
|
-
* // Close when no longer needed (e.g., component unmount)
|
|
223
|
-
* stream.close();
|
|
224
|
-
* ```
|
|
225
|
-
*/
|
|
226
|
-
resourceEvents(resourceId: ResourceId, options: SSERequestOptions & {
|
|
227
|
-
onConnected?: () => void;
|
|
228
|
-
}): SSEStream;
|
|
229
|
-
/**
|
|
230
|
-
* Subscribe to global system events (long-lived stream)
|
|
231
|
-
*
|
|
232
|
-
* Opens a long-lived SSE connection to receive system-level domain events
|
|
233
|
-
* (entity type additions, etc.) that are not scoped to a specific resource.
|
|
234
|
-
*
|
|
235
|
-
* @param options - Request options (auth token, eventBus)
|
|
236
|
-
* @returns SSE stream controller
|
|
237
|
-
*
|
|
238
|
-
* @example
|
|
239
|
-
* ```typescript
|
|
240
|
-
* const stream = sseClient.globalEvents({ auth: 'your-token', eventBus });
|
|
241
|
-
*
|
|
242
|
-
* // Events auto-emit to EventBus typed channels — subscribe there
|
|
243
|
-
* eventBus.get('mark:entity-type-added').subscribe((stored) => {
|
|
244
|
-
* // Invalidate entity types query
|
|
245
|
-
* });
|
|
246
|
-
*
|
|
247
|
-
* // Close when no longer needed
|
|
248
|
-
* stream.close();
|
|
249
|
-
* ```
|
|
250
|
-
*/
|
|
251
|
-
globalEvents(options: SSERequestOptions & {
|
|
252
|
-
onConnected?: () => void;
|
|
253
|
-
}): SSEStream;
|
|
254
|
-
/**
|
|
255
|
-
* Subscribe to participant attention stream (long-lived stream)
|
|
256
|
-
*
|
|
257
|
-
* Opens a participant-scoped SSE connection to receive cross-participant
|
|
258
|
-
* beckon signals. Signals are delivered as 'beckon:focus' events routed
|
|
259
|
-
* to the EventBus — the existing scroll/highlight machinery handles them.
|
|
260
|
-
*
|
|
261
|
-
* Signals are ephemeral — delivered if connected, dropped if not.
|
|
262
|
-
*
|
|
263
|
-
* @param options - Request options (auth token, eventBus)
|
|
264
|
-
* @returns SSE stream controller
|
|
265
|
-
*/
|
|
266
|
-
attentionStream(options: SSERequestOptions & {
|
|
267
|
-
onConnected?: () => void;
|
|
268
|
-
}): SSEStream;
|
|
42
|
+
type ConnectionState = 'initial' | 'connecting' | 'open' | 'reconnecting' | 'degraded' | 'closed';
|
|
43
|
+
/** Time in the `reconnecting` state before transitioning to `degraded`. */
|
|
44
|
+
declare const DEGRADED_THRESHOLD_MS = 3000;
|
|
45
|
+
interface ActorVM extends ViewModel {
|
|
46
|
+
on$<T = Record<string, unknown>>(channel: string): Observable<T>;
|
|
47
|
+
emit(channel: string, payload: Record<string, unknown>, emitScope?: string): Promise<void>;
|
|
48
|
+
state$: Observable<ConnectionState>;
|
|
49
|
+
addChannels(channels: string[], scope?: string): void;
|
|
50
|
+
removeChannels(channels: string[]): void;
|
|
51
|
+
start(): void;
|
|
52
|
+
stop(): void;
|
|
269
53
|
}
|
|
54
|
+
declare function createActorVM(options: ActorVMOptions): ActorVM;
|
|
270
55
|
|
|
271
56
|
/**
|
|
272
57
|
* Verb Namespace Interfaces
|
|
@@ -280,19 +65,20 @@ declare class SSEClient {
|
|
|
280
65
|
* proxy handles HTTP, auth, SSE, and caching internally.
|
|
281
66
|
*
|
|
282
67
|
* Return type conventions:
|
|
283
|
-
* - Browse live queries → Observable (
|
|
68
|
+
* - Browse live queries → Observable (bus gateway driven, cached)
|
|
284
69
|
* - Browse one-shot reads → Promise (fetch once, no cache)
|
|
285
70
|
* - Commands (mark, bind, yield.resource) → Promise (fire-and-forget)
|
|
286
71
|
* - Long-running ops (gather, match, yield.fromAnnotation, mark.assist) → Observable (progress + result)
|
|
287
72
|
* - Ephemeral signals (beckon) → void
|
|
288
73
|
*/
|
|
289
74
|
|
|
290
|
-
type Annotation$
|
|
291
|
-
type ResourceDescriptor$
|
|
292
|
-
type StoredEventResponse$
|
|
75
|
+
type Annotation$2 = components['schemas']['Annotation'];
|
|
76
|
+
type ResourceDescriptor$5 = components['schemas']['ResourceDescriptor'];
|
|
77
|
+
type StoredEventResponse$2 = components['schemas']['StoredEventResponse'];
|
|
293
78
|
type GatherProgress = components['schemas']['GatherProgress'];
|
|
294
79
|
type MatchSearchResult = components['schemas']['MatchSearchResult'];
|
|
295
|
-
type
|
|
80
|
+
type JobProgress$2 = components['schemas']['JobProgress'];
|
|
81
|
+
type YieldProgress$1 = JobProgress$2;
|
|
296
82
|
type GatherAnnotationComplete = components['schemas']['GatherAnnotationComplete'];
|
|
297
83
|
type JobStatusResponse$1 = components['schemas']['JobStatusResponse'];
|
|
298
84
|
type AuthResponse$1 = components['schemas']['AuthResponse'];
|
|
@@ -314,6 +100,14 @@ type ResponseContent$1<T> = T extends {
|
|
|
314
100
|
};
|
|
315
101
|
};
|
|
316
102
|
};
|
|
103
|
+
} ? R : T extends {
|
|
104
|
+
responses: {
|
|
105
|
+
202: {
|
|
106
|
+
content: {
|
|
107
|
+
'application/json': infer R;
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
};
|
|
317
111
|
} ? R : never;
|
|
318
112
|
type RequestContent$1<T> = T extends {
|
|
319
113
|
requestBody?: {
|
|
@@ -323,7 +117,7 @@ type RequestContent$1<T> = T extends {
|
|
|
323
117
|
};
|
|
324
118
|
} ? R : never;
|
|
325
119
|
/** Input for creating an annotation via mark.annotation() */
|
|
326
|
-
type CreateAnnotationInput =
|
|
120
|
+
type CreateAnnotationInput = components['schemas']['CreateAnnotationRequest'];
|
|
327
121
|
/** Input for creating a resource via yield.resource() */
|
|
328
122
|
interface CreateResourceInput {
|
|
329
123
|
name: string;
|
|
@@ -335,6 +129,11 @@ interface CreateResourceInput {
|
|
|
335
129
|
sourceAnnotationId?: string;
|
|
336
130
|
sourceResourceId?: string;
|
|
337
131
|
storageUri: string;
|
|
132
|
+
/** Prompt that drove AI generation (for AI-generated resources). */
|
|
133
|
+
generationPrompt?: string;
|
|
134
|
+
/** Agent(s) that generated the content (for AI-generated resources). */
|
|
135
|
+
generator?: components['schemas']['Agent'] | components['schemas']['Agent'][];
|
|
136
|
+
isDraft?: boolean;
|
|
338
137
|
}
|
|
339
138
|
/** Options for yield.fromAnnotation() */
|
|
340
139
|
interface GenerationOptions {
|
|
@@ -358,11 +157,16 @@ interface MarkAssistOptions {
|
|
|
358
157
|
categories?: string[];
|
|
359
158
|
}
|
|
360
159
|
/** Options for yield.createFromToken() */
|
|
361
|
-
type CreateFromTokenOptions =
|
|
160
|
+
type CreateFromTokenOptions = {
|
|
161
|
+
token: string;
|
|
162
|
+
name: string;
|
|
163
|
+
content: string;
|
|
164
|
+
archiveOriginal?: boolean;
|
|
165
|
+
};
|
|
362
166
|
/** Referenced-by entry from browse.referencedBy() */
|
|
363
|
-
type ReferencedByEntry =
|
|
167
|
+
type ReferencedByEntry = components['schemas']['GetReferencedByResponse']['referencedBy'][number];
|
|
364
168
|
/** Annotation history from browse.annotationHistory() */
|
|
365
|
-
type AnnotationHistoryResponse =
|
|
169
|
+
type AnnotationHistoryResponse = components['schemas']['GetAnnotationHistoryResponse'];
|
|
366
170
|
/** User object from auth/admin responses */
|
|
367
171
|
type User = AuthResponse$1['user'];
|
|
368
172
|
/**
|
|
@@ -377,30 +181,31 @@ type GatherAnnotationProgress = GatherProgress | GatherAnnotationComplete;
|
|
|
377
181
|
type MatchSearchProgress = MatchSearchResult;
|
|
378
182
|
/**
|
|
379
183
|
* Progress emitted by mark.assist() Observable.
|
|
380
|
-
*
|
|
381
|
-
*
|
|
184
|
+
* Each emission is a JobProgress snapshot (unified job lifecycle). The
|
|
185
|
+
* Observable completes on `job:complete`; errors on `job:fail`.
|
|
382
186
|
*/
|
|
383
|
-
type MarkAssistProgress =
|
|
187
|
+
type MarkAssistProgress = JobProgress$2;
|
|
384
188
|
/**
|
|
385
189
|
* Browse — reads from materialized views
|
|
386
190
|
*
|
|
387
191
|
* Live queries return Observables that emit initial state and re-emit
|
|
388
|
-
* on
|
|
192
|
+
* on bus gateway updates. One-shot reads return Promises.
|
|
389
193
|
*
|
|
390
194
|
* Backend actor: Browser (context classes)
|
|
391
195
|
* Event prefix: browse:*
|
|
392
196
|
*/
|
|
393
197
|
interface BrowseNamespace$1 {
|
|
394
|
-
resource(resourceId: ResourceId): Observable<ResourceDescriptor$
|
|
198
|
+
resource(resourceId: ResourceId): Observable<ResourceDescriptor$5 | undefined>;
|
|
395
199
|
resources(filters?: {
|
|
396
200
|
limit?: number;
|
|
397
201
|
archived?: boolean;
|
|
398
202
|
search?: string;
|
|
399
|
-
}): Observable<ResourceDescriptor$
|
|
400
|
-
annotations(resourceId: ResourceId): Observable<Annotation$
|
|
401
|
-
annotation(resourceId: ResourceId, annotationId: AnnotationId): Observable<Annotation$
|
|
203
|
+
}): Observable<ResourceDescriptor$5[] | undefined>;
|
|
204
|
+
annotations(resourceId: ResourceId): Observable<Annotation$2[] | undefined>;
|
|
205
|
+
annotation(resourceId: ResourceId, annotationId: AnnotationId): Observable<Annotation$2 | undefined>;
|
|
402
206
|
entityTypes(): Observable<string[] | undefined>;
|
|
403
207
|
referencedBy(resourceId: ResourceId): Observable<ReferencedByEntry[] | undefined>;
|
|
208
|
+
events(resourceId: ResourceId): Observable<StoredEventResponse$2[] | undefined>;
|
|
404
209
|
resourceContent(resourceId: ResourceId): Promise<string>;
|
|
405
210
|
resourceRepresentation(resourceId: ResourceId, options?: {
|
|
406
211
|
accept?: string;
|
|
@@ -414,18 +219,18 @@ interface BrowseNamespace$1 {
|
|
|
414
219
|
stream: ReadableStream<Uint8Array>;
|
|
415
220
|
contentType: string;
|
|
416
221
|
}>;
|
|
417
|
-
resourceEvents(resourceId: ResourceId): Promise<StoredEventResponse$
|
|
222
|
+
resourceEvents(resourceId: ResourceId): Promise<StoredEventResponse$2[]>;
|
|
418
223
|
annotationHistory(resourceId: ResourceId, annotationId: AnnotationId): Promise<AnnotationHistoryResponse>;
|
|
419
224
|
connections(resourceId: ResourceId): Promise<GraphConnection[]>;
|
|
420
|
-
backlinks(resourceId: ResourceId): Promise<Annotation$
|
|
421
|
-
resourcesByName(query: string, limit?: number): Promise<ResourceDescriptor$
|
|
422
|
-
files(dirPath?: string, sort?: 'name' | 'mtime' | 'annotationCount'): Promise<
|
|
225
|
+
backlinks(resourceId: ResourceId): Promise<Annotation$2[]>;
|
|
226
|
+
resourcesByName(query: string, limit?: number): Promise<ResourceDescriptor$5[]>;
|
|
227
|
+
files(dirPath?: string, sort?: 'name' | 'mtime' | 'annotationCount'): Promise<components['schemas']['BrowseFilesResponse']>;
|
|
423
228
|
}
|
|
424
229
|
/**
|
|
425
230
|
* Mark — annotation CRUD, entity types, AI assist
|
|
426
231
|
*
|
|
427
232
|
* Commands return Promises that resolve on HTTP acceptance (202).
|
|
428
|
-
* Results appear on browse Observables via
|
|
233
|
+
* Results appear on browse Observables via bus gateway.
|
|
429
234
|
* assist() returns an Observable for long-running progress.
|
|
430
235
|
*
|
|
431
236
|
* Backend actor: Stower
|
|
@@ -506,7 +311,7 @@ interface YieldNamespace$1 {
|
|
|
506
311
|
token: string;
|
|
507
312
|
expiresAt: string;
|
|
508
313
|
}>;
|
|
509
|
-
fromToken(token: string): Promise<ResourceDescriptor$
|
|
314
|
+
fromToken(token: string): Promise<ResourceDescriptor$5>;
|
|
510
315
|
createFromToken(options: CreateFromTokenOptions): Promise<{
|
|
511
316
|
resourceId: string;
|
|
512
317
|
}>;
|
|
@@ -586,53 +391,55 @@ interface AdminNamespace$1 {
|
|
|
586
391
|
}>;
|
|
587
392
|
}
|
|
588
393
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
*/
|
|
599
|
-
|
|
600
|
-
type Annotation = components['schemas']['Annotation'];
|
|
601
|
-
type ResourceDescriptor$1 = components['schemas']['ResourceDescriptor'];
|
|
602
|
-
type StoredEventResponse = components['schemas']['StoredEventResponse'];
|
|
603
|
-
type TokenGetter$9 = () => AccessToken | undefined;
|
|
394
|
+
type Annotation$1 = components['schemas']['Annotation'];
|
|
395
|
+
type ResourceDescriptor$4 = components['schemas']['ResourceDescriptor'];
|
|
396
|
+
type StoredEventResponse$1 = components['schemas']['StoredEventResponse'];
|
|
397
|
+
type TokenGetter$4 = () => AccessToken | undefined;
|
|
398
|
+
type ResourceListFilters = {
|
|
399
|
+
limit?: number;
|
|
400
|
+
archived?: boolean;
|
|
401
|
+
search?: string;
|
|
402
|
+
};
|
|
604
403
|
declare class BrowseNamespace implements BrowseNamespace$1 {
|
|
605
404
|
private readonly http;
|
|
606
405
|
private readonly eventBus;
|
|
607
|
-
private readonly
|
|
608
|
-
private readonly
|
|
609
|
-
private readonly
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
private readonly
|
|
618
|
-
private readonly
|
|
619
|
-
private readonly
|
|
620
|
-
private
|
|
621
|
-
private readonly
|
|
622
|
-
|
|
623
|
-
private readonly
|
|
406
|
+
private readonly resourceCache;
|
|
407
|
+
private readonly resourceListCache;
|
|
408
|
+
private readonly annotationListCache;
|
|
409
|
+
/**
|
|
410
|
+
* Annotation-detail cache keyed by `annotationId` only — the resourceId
|
|
411
|
+
* is a routing hint for the backend fetch, not an identity component.
|
|
412
|
+
* We track the most recent resourceId per annotationId in a side-map
|
|
413
|
+
* so `mark:delete-ok` (which carries only `annotationId`) can reach
|
|
414
|
+
* the right cache entry. Aligns with the pre-refactor semantics.
|
|
415
|
+
*/
|
|
416
|
+
private readonly annotationDetailCache;
|
|
417
|
+
private readonly annotationResources;
|
|
418
|
+
private readonly entityTypesCache;
|
|
419
|
+
private readonly referencedByCache;
|
|
420
|
+
private readonly resourceEventsCache;
|
|
421
|
+
/** Filter-blob memory so `invalidateResourceLists` can replay per-key. */
|
|
422
|
+
private readonly resourceListFilters;
|
|
423
|
+
/**
|
|
424
|
+
* Per-key memo for `annotations()` observables. The cache stores the
|
|
425
|
+
* full `AnnotationsListResponse`; the public shape is just the inner
|
|
426
|
+
* `Annotation[]`. Without this memo, every call to `annotations(rId)`
|
|
427
|
+
* would produce a fresh `.pipe(map(...))` observable, violating B4
|
|
428
|
+
* (per-key observable stability). Consumers that compare observable
|
|
429
|
+
* identity — React hooks depending on the observable reference,
|
|
430
|
+
* `distinctUntilChanged` at a higher level — would misbehave.
|
|
431
|
+
*/
|
|
432
|
+
private readonly annotationListObs;
|
|
624
433
|
private readonly getToken;
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
}): Observable<ResourceDescriptor$1[] | undefined>;
|
|
632
|
-
annotations(resourceId: ResourceId): Observable<Annotation[] | undefined>;
|
|
633
|
-
annotation(resourceId: ResourceId, annotationId: AnnotationId): Observable<Annotation | undefined>;
|
|
434
|
+
private readonly actor;
|
|
435
|
+
constructor(http: SemiontApiClient, eventBus: EventBus, getToken: TokenGetter$4, actor: ActorVM);
|
|
436
|
+
resource(resourceId: ResourceId): Observable<ResourceDescriptor$4 | undefined>;
|
|
437
|
+
resources(filters?: ResourceListFilters): Observable<ResourceDescriptor$4[] | undefined>;
|
|
438
|
+
annotations(resourceId: ResourceId): Observable<Annotation$1[] | undefined>;
|
|
439
|
+
annotation(resourceId: ResourceId, annotationId: AnnotationId): Observable<Annotation$1 | undefined>;
|
|
634
440
|
entityTypes(): Observable<string[] | undefined>;
|
|
635
441
|
referencedBy(resourceId: ResourceId): Observable<ReferencedByEntry[] | undefined>;
|
|
442
|
+
events(resourceId: ResourceId): Observable<StoredEventResponse$1[] | undefined>;
|
|
636
443
|
resourceContent(resourceId: ResourceId): Promise<string>;
|
|
637
444
|
resourceRepresentation(resourceId: ResourceId, options?: {
|
|
638
445
|
accept?: string;
|
|
@@ -646,45 +453,56 @@ declare class BrowseNamespace implements BrowseNamespace$1 {
|
|
|
646
453
|
stream: ReadableStream<Uint8Array>;
|
|
647
454
|
contentType: string;
|
|
648
455
|
}>;
|
|
649
|
-
resourceEvents(resourceId: ResourceId): Promise<StoredEventResponse[]>;
|
|
456
|
+
resourceEvents(resourceId: ResourceId): Promise<StoredEventResponse$1[]>;
|
|
650
457
|
annotationHistory(resourceId: ResourceId, annotationId: AnnotationId): Promise<AnnotationHistoryResponse>;
|
|
651
458
|
connections(_resourceId: ResourceId): Promise<GraphConnection[]>;
|
|
652
|
-
backlinks(_resourceId: ResourceId): Promise<Annotation[]>;
|
|
653
|
-
resourcesByName(_query: string, _limit?: number): Promise<ResourceDescriptor$
|
|
654
|
-
files(dirPath?: string, sort?: 'name' | 'mtime' | 'annotationCount'): Promise<
|
|
459
|
+
backlinks(_resourceId: ResourceId): Promise<Annotation$1[]>;
|
|
460
|
+
resourcesByName(_query: string, _limit?: number): Promise<ResourceDescriptor$4[]>;
|
|
461
|
+
files(dirPath?: string, sort?: 'name' | 'mtime' | 'annotationCount'): Promise<components['schemas']['BrowseFilesResponse']>;
|
|
655
462
|
invalidateAnnotationList(resourceId: ResourceId): void;
|
|
656
|
-
|
|
463
|
+
removeAnnotationDetail(annotationId: AnnotationId): void;
|
|
657
464
|
invalidateResourceDetail(id: ResourceId): void;
|
|
658
465
|
invalidateResourceLists(): void;
|
|
659
466
|
invalidateEntityTypes(): void;
|
|
660
467
|
invalidateReferencedBy(resourceId: ResourceId): void;
|
|
661
|
-
|
|
468
|
+
invalidateResourceEvents(resourceId: ResourceId): void;
|
|
469
|
+
updateAnnotationInPlace(resourceId: ResourceId, annotation: Annotation$1): void;
|
|
470
|
+
/**
|
|
471
|
+
* Typed shorthand for `eventBus.get(channel).subscribe(handler)`.
|
|
472
|
+
* Preserves per-channel payload typing so handlers read
|
|
473
|
+
* `EventMap[K]` without any casts.
|
|
474
|
+
*/
|
|
475
|
+
private on;
|
|
476
|
+
/**
|
|
477
|
+
* Handler shared by `mark:entity-tag-added` and `mark:entity-tag-removed`.
|
|
478
|
+
* Both events carry the same effect: the annotation list, the
|
|
479
|
+
* resource descriptor, and the event log for that resource all may
|
|
480
|
+
* now reflect different entity tagging, so invalidate all three.
|
|
481
|
+
*/
|
|
482
|
+
private onEntityTagChanged;
|
|
483
|
+
/**
|
|
484
|
+
* Handler shared by `mark:archived` and `mark:unarchived`. Both
|
|
485
|
+
* change a resource's archived flag, which is stored on the resource
|
|
486
|
+
* descriptor and affects the resource-list filter.
|
|
487
|
+
*/
|
|
488
|
+
private onArchiveToggled;
|
|
489
|
+
/**
|
|
490
|
+
* Handler shared by `yield:create-ok` and `yield:update-ok`. Both
|
|
491
|
+
* report a resource mutation with the resourceId as a string (not
|
|
492
|
+
* yet branded), so we brand and apply the same effect as
|
|
493
|
+
* `onArchiveToggled`.
|
|
494
|
+
*/
|
|
495
|
+
private onYieldResourceMutated;
|
|
662
496
|
private subscribeToEvents;
|
|
663
|
-
private fetchAnnotationList;
|
|
664
|
-
private fetchAnnotationDetail;
|
|
665
|
-
private fetchResourceDetail;
|
|
666
|
-
private fetchResourceList;
|
|
667
|
-
private fetchEntityTypes;
|
|
668
|
-
private fetchReferencedBy;
|
|
669
497
|
}
|
|
670
498
|
|
|
671
|
-
|
|
672
|
-
* MarkNamespace — annotation CRUD, entity types, AI assist
|
|
673
|
-
*
|
|
674
|
-
* Commands return Promises that resolve on HTTP acceptance.
|
|
675
|
-
* Results appear on browse Observables via events-stream.
|
|
676
|
-
* assist() returns an Observable for long-running progress.
|
|
677
|
-
*
|
|
678
|
-
* Backend actor: Stower
|
|
679
|
-
* Event prefix: mark:*
|
|
680
|
-
*/
|
|
681
|
-
|
|
682
|
-
type TokenGetter$8 = () => AccessToken | undefined;
|
|
499
|
+
type TokenGetter$3 = () => AccessToken | undefined;
|
|
683
500
|
declare class MarkNamespace implements MarkNamespace$1 {
|
|
684
501
|
private readonly http;
|
|
685
502
|
private readonly eventBus;
|
|
686
503
|
private readonly getToken;
|
|
687
|
-
|
|
504
|
+
private readonly actor;
|
|
505
|
+
constructor(http: SemiontApiClient, eventBus: EventBus, getToken: TokenGetter$3, actor: ActorVM);
|
|
688
506
|
annotation(resourceId: ResourceId, input: CreateAnnotationInput): Promise<{
|
|
689
507
|
annotationId: string;
|
|
690
508
|
}>;
|
|
@@ -698,41 +516,16 @@ declare class MarkNamespace implements MarkNamespace$1 {
|
|
|
698
516
|
private dispatchAssist;
|
|
699
517
|
}
|
|
700
518
|
|
|
701
|
-
/**
|
|
702
|
-
* BindNamespace — reference linking
|
|
703
|
-
*
|
|
704
|
-
* The simplest namespace. One method. The result (updated annotation
|
|
705
|
-
* with resolved reference) arrives on browse.annotations() via the
|
|
706
|
-
* enriched mark:body-updated event.
|
|
707
|
-
*
|
|
708
|
-
* Backend actor: Stower (via mark:update-body)
|
|
709
|
-
* Event prefix: mark:body-updated (shares mark event pipeline)
|
|
710
|
-
*/
|
|
711
|
-
|
|
712
|
-
type TokenGetter$7 = () => AccessToken | undefined;
|
|
713
519
|
declare class BindNamespace implements BindNamespace$1 {
|
|
714
|
-
private readonly
|
|
715
|
-
|
|
716
|
-
constructor(http: SemiontApiClient, getToken: TokenGetter$7);
|
|
520
|
+
private readonly actor;
|
|
521
|
+
constructor(actor: ActorVM);
|
|
717
522
|
body(resourceId: ResourceId, annotationId: AnnotationId, operations: BodyOperation[]): Promise<void>;
|
|
718
523
|
}
|
|
719
524
|
|
|
720
|
-
/**
|
|
721
|
-
* GatherNamespace — context assembly
|
|
722
|
-
*
|
|
723
|
-
* Long-running (LLM calls + graph traversal). Returns Observables
|
|
724
|
-
* that emit progress then the gathered context.
|
|
725
|
-
*
|
|
726
|
-
* Backend actor: Gatherer
|
|
727
|
-
* Event prefix: gather:*
|
|
728
|
-
*/
|
|
729
|
-
|
|
730
|
-
type TokenGetter$6 = () => AccessToken | undefined;
|
|
731
525
|
declare class GatherNamespace implements GatherNamespace$1 {
|
|
732
|
-
private readonly http;
|
|
733
526
|
private readonly eventBus;
|
|
734
|
-
private readonly
|
|
735
|
-
constructor(
|
|
527
|
+
private readonly actor;
|
|
528
|
+
constructor(eventBus: EventBus, actor: ActorVM);
|
|
736
529
|
annotation(annotationId: AnnotationId, resourceId: ResourceId, options?: {
|
|
737
530
|
contextWindow?: number;
|
|
738
531
|
}): Observable<GatherAnnotationProgress>;
|
|
@@ -741,87 +534,50 @@ declare class GatherNamespace implements GatherNamespace$1 {
|
|
|
741
534
|
}): Observable<GatherAnnotationProgress>;
|
|
742
535
|
}
|
|
743
536
|
|
|
744
|
-
/**
|
|
745
|
-
* MatchNamespace — search and ranking
|
|
746
|
-
*
|
|
747
|
-
* Long-running (semantic search, optional LLM scoring). Returns
|
|
748
|
-
* Observable with results.
|
|
749
|
-
*
|
|
750
|
-
* Backend actor: Matcher
|
|
751
|
-
* Event prefix: match:*
|
|
752
|
-
*/
|
|
753
|
-
|
|
754
|
-
type TokenGetter$5 = () => AccessToken | undefined;
|
|
755
537
|
declare class MatchNamespace implements MatchNamespace$1 {
|
|
756
|
-
private readonly http;
|
|
757
538
|
private readonly eventBus;
|
|
758
|
-
private readonly
|
|
759
|
-
constructor(
|
|
539
|
+
private readonly actor;
|
|
540
|
+
constructor(eventBus: EventBus, actor: ActorVM);
|
|
760
541
|
search(resourceId: ResourceId, referenceId: string, context: GatheredContext, options?: {
|
|
761
542
|
limit?: number;
|
|
762
543
|
useSemanticScoring?: boolean;
|
|
763
544
|
}): Observable<MatchSearchProgress>;
|
|
764
545
|
}
|
|
765
546
|
|
|
766
|
-
|
|
767
|
-
* YieldNamespace — resource creation
|
|
768
|
-
*
|
|
769
|
-
* resource() is synchronous file upload (Promise).
|
|
770
|
-
* fromAnnotation() is long-running LLM generation (Observable).
|
|
771
|
-
*
|
|
772
|
-
* Backend actor: Stower + generation worker
|
|
773
|
-
* Event prefix: yield:*
|
|
774
|
-
*/
|
|
547
|
+
type YieldProgress = components['schemas']['JobProgress'];
|
|
775
548
|
|
|
776
|
-
type ResourceDescriptor = components['schemas']['ResourceDescriptor'];
|
|
777
|
-
type TokenGetter$
|
|
549
|
+
type ResourceDescriptor$3 = components['schemas']['ResourceDescriptor'];
|
|
550
|
+
type TokenGetter$2 = () => AccessToken | undefined;
|
|
778
551
|
declare class YieldNamespace implements YieldNamespace$1 {
|
|
779
552
|
private readonly http;
|
|
780
553
|
private readonly eventBus;
|
|
781
554
|
private readonly getToken;
|
|
782
|
-
|
|
555
|
+
private readonly actor;
|
|
556
|
+
constructor(http: SemiontApiClient, eventBus: EventBus, getToken: TokenGetter$2, actor: ActorVM);
|
|
783
557
|
resource(data: CreateResourceInput): Promise<{
|
|
784
558
|
resourceId: string;
|
|
785
559
|
}>;
|
|
786
|
-
fromAnnotation(resourceId: ResourceId, annotationId: AnnotationId, options: GenerationOptions): Observable<YieldProgress
|
|
560
|
+
fromAnnotation(resourceId: ResourceId, annotationId: AnnotationId, options: GenerationOptions): Observable<YieldProgress>;
|
|
787
561
|
cloneToken(resourceId: ResourceId): Promise<{
|
|
788
562
|
token: string;
|
|
789
563
|
expiresAt: string;
|
|
790
564
|
}>;
|
|
791
|
-
fromToken(token: string): Promise<ResourceDescriptor>;
|
|
565
|
+
fromToken(token: string): Promise<ResourceDescriptor$3>;
|
|
792
566
|
createFromToken(options: CreateFromTokenOptions): Promise<{
|
|
793
567
|
resourceId: string;
|
|
794
568
|
}>;
|
|
795
569
|
}
|
|
796
570
|
|
|
797
|
-
/**
|
|
798
|
-
* BeckonNamespace — attention coordination
|
|
799
|
-
*
|
|
800
|
-
* Fire-and-forget. Ephemeral presence signal delivered via the
|
|
801
|
-
* attention-stream to other participants.
|
|
802
|
-
*
|
|
803
|
-
* Backend actor: (frontend relay via attention-stream)
|
|
804
|
-
* Event prefix: beckon:*
|
|
805
|
-
*/
|
|
806
|
-
|
|
807
|
-
type TokenGetter$3 = () => AccessToken | undefined;
|
|
808
571
|
declare class BeckonNamespace implements BeckonNamespace$1 {
|
|
809
|
-
private readonly
|
|
810
|
-
|
|
811
|
-
constructor(http: SemiontApiClient, getToken: TokenGetter$3);
|
|
572
|
+
private readonly actor;
|
|
573
|
+
constructor(actor: ActorVM);
|
|
812
574
|
attention(annotationId: AnnotationId, resourceId: ResourceId): void;
|
|
813
575
|
}
|
|
814
576
|
|
|
815
|
-
/**
|
|
816
|
-
* JobNamespace — worker lifecycle
|
|
817
|
-
*/
|
|
818
|
-
|
|
819
577
|
type JobStatusResponse = components['schemas']['JobStatusResponse'];
|
|
820
|
-
type TokenGetter$2 = () => AccessToken | undefined;
|
|
821
578
|
declare class JobNamespace implements JobNamespace$1 {
|
|
822
|
-
private readonly
|
|
823
|
-
|
|
824
|
-
constructor(http: SemiontApiClient, getToken: TokenGetter$2);
|
|
579
|
+
private readonly actor;
|
|
580
|
+
constructor(actor: ActorVM);
|
|
825
581
|
status(jobId: JobId): Promise<JobStatusResponse>;
|
|
826
582
|
pollUntilComplete(jobId: JobId, options?: {
|
|
827
583
|
interval?: number;
|
|
@@ -923,6 +679,14 @@ type ResponseContent<T> = T extends {
|
|
|
923
679
|
};
|
|
924
680
|
};
|
|
925
681
|
};
|
|
682
|
+
} ? R : T extends {
|
|
683
|
+
responses: {
|
|
684
|
+
202: {
|
|
685
|
+
content: {
|
|
686
|
+
'application/json': infer R;
|
|
687
|
+
};
|
|
688
|
+
};
|
|
689
|
+
};
|
|
926
690
|
} ? R : never;
|
|
927
691
|
type RequestContent<T> = T extends {
|
|
928
692
|
requestBody?: {
|
|
@@ -944,27 +708,24 @@ declare class APIError extends Error {
|
|
|
944
708
|
* 401 propagates as an APIError.
|
|
945
709
|
*
|
|
946
710
|
* Implementations must dedupe concurrent calls so that simultaneous 401s
|
|
947
|
-
* don't fire multiple parallel refresh requests.
|
|
948
|
-
*
|
|
949
|
-
* keyed by KB id.
|
|
711
|
+
* don't fire multiple parallel refresh requests. `SemiontSession.refresh()`
|
|
712
|
+
* satisfies this via an in-flight Promise map keyed by KB id.
|
|
950
713
|
*/
|
|
951
714
|
type TokenRefresher = () => Promise<string | null>;
|
|
952
715
|
interface SemiontApiClientConfig {
|
|
953
716
|
baseUrl: BaseUrl;
|
|
954
|
-
/**
|
|
955
|
-
|
|
717
|
+
/**
|
|
718
|
+
* Observable access token. All auth (HTTP + bus) reads the current value.
|
|
719
|
+
* Update by calling `.next(newToken)` on the BehaviorSubject. The bus actor
|
|
720
|
+
* auto-starts when the value transitions from null to a real token.
|
|
721
|
+
* If omitted, the client operates unauthenticated (public endpoints only).
|
|
722
|
+
*/
|
|
723
|
+
token$?: BehaviorSubject<AccessToken | null>;
|
|
956
724
|
timeout?: number;
|
|
957
725
|
retry?: number;
|
|
958
726
|
logger?: Logger;
|
|
959
727
|
/** Optional 401-recovery hook. See {@link TokenRefresher}. */
|
|
960
728
|
tokenRefresher?: TokenRefresher;
|
|
961
|
-
/**
|
|
962
|
-
* Token getter for the verb-namespace API (client.browse, client.mark, etc.).
|
|
963
|
-
* When provided, auth is managed internally — no per-call auth needed.
|
|
964
|
-
* The getter is called on each request to get the current token.
|
|
965
|
-
* If not provided, namespace methods use undefined auth (public endpoints only).
|
|
966
|
-
*/
|
|
967
|
-
getToken?: () => AccessToken | undefined;
|
|
968
729
|
}
|
|
969
730
|
/**
|
|
970
731
|
* Options for individual API requests
|
|
@@ -982,21 +743,18 @@ interface RequestOptions {
|
|
|
982
743
|
declare class SemiontApiClient {
|
|
983
744
|
private http;
|
|
984
745
|
readonly baseUrl: BaseUrl;
|
|
985
|
-
/** The workspace-scoped EventBus this client was constructed with. */
|
|
986
|
-
readonly eventBus: EventBus;
|
|
987
|
-
private logger?;
|
|
988
746
|
/**
|
|
989
|
-
*
|
|
990
|
-
*
|
|
747
|
+
* Workspace-scoped EventBus — owned by the client, constructed
|
|
748
|
+
* internally, never accepted from config. Private: all bus access
|
|
749
|
+
* goes through `client.emit` / `client.on` / `client.stream`.
|
|
991
750
|
*/
|
|
992
|
-
private
|
|
751
|
+
private readonly eventBus;
|
|
752
|
+
private logger?;
|
|
993
753
|
/**
|
|
994
|
-
*
|
|
995
|
-
*
|
|
996
|
-
* Separate from the main HTTP client to clearly mark streaming endpoints.
|
|
997
|
-
* Uses native fetch() instead of ky for SSE support.
|
|
754
|
+
* Observable token source. All auth reads from this.
|
|
998
755
|
*/
|
|
999
|
-
readonly
|
|
756
|
+
private readonly token$;
|
|
757
|
+
private _actor;
|
|
1000
758
|
readonly browse: BrowseNamespace;
|
|
1001
759
|
readonly mark: MarkNamespace;
|
|
1002
760
|
readonly bind: BindNamespace;
|
|
@@ -1008,12 +766,41 @@ declare class SemiontApiClient {
|
|
|
1008
766
|
readonly auth: AuthNamespace;
|
|
1009
767
|
readonly admin: AdminNamespace;
|
|
1010
768
|
constructor(config: SemiontApiClientConfig);
|
|
769
|
+
private _actorStarted;
|
|
770
|
+
get actor(): ActorVM;
|
|
771
|
+
private activeResource;
|
|
1011
772
|
/**
|
|
1012
|
-
*
|
|
1013
|
-
*
|
|
1014
|
-
*
|
|
773
|
+
* Subscribe the bus actor to the resource-scoped SSE stream for a single
|
|
774
|
+
* resource and bridge incoming scoped events into the workspace event bus.
|
|
775
|
+
*
|
|
776
|
+
* **One distinct scope at a time**: the client supports subscriptions
|
|
777
|
+
* to a single resource scope concurrently. Multiple calls with the
|
|
778
|
+
* **same** resourceId are ref-counted — each returns an independent
|
|
779
|
+
* unsubscribe; the underlying SSE scope is torn down only when the
|
|
780
|
+
* last unsubscribe fires. Calling with a **different** resourceId
|
|
781
|
+
* while a subscription is live throws. Widening this to multiple
|
|
782
|
+
* concurrent scopes is deferred until a product requirement (e.g.
|
|
783
|
+
* split-pane viewer, headless fleet-watcher) forces the design.
|
|
784
|
+
*
|
|
785
|
+
* @returns a disposer that decrements the ref count (and tears down
|
|
786
|
+
* the SSE scope + bridges when it reaches zero).
|
|
787
|
+
*/
|
|
788
|
+
subscribeToResource(resourceId: ResourceId): () => void;
|
|
789
|
+
private makeUnsubscriber;
|
|
790
|
+
dispose(): void;
|
|
791
|
+
/** Emit an event on the internal bus. */
|
|
792
|
+
emit<K extends keyof EventMap>(channel: K, payload: EventMap[K]): void;
|
|
793
|
+
/** Subscribe to an event on the internal bus; returns unsubscribe. */
|
|
794
|
+
on<K extends keyof EventMap>(channel: K, handler: (payload: EventMap[K]) => void): () => void;
|
|
795
|
+
/** Read-only observable for a bus channel. Consumers `.pipe(...)` over this. */
|
|
796
|
+
stream<K extends keyof EventMap>(channel: K): Observable<EventMap[K]>;
|
|
797
|
+
/**
|
|
798
|
+
* Build the `Authorization: Bearer <token>` header. If the caller passed
|
|
799
|
+
* an explicit `{ auth }` it wins (used by session-internal throwaway
|
|
800
|
+
* clients that need to run a validation request with a specific token).
|
|
801
|
+
* Otherwise the current value of `this.token$` is used, so external
|
|
802
|
+
* callers never have to plumb the token themselves.
|
|
1015
803
|
*/
|
|
1016
|
-
setTokenGetter(getter: () => AccessToken | undefined): void;
|
|
1017
804
|
private authHeaders;
|
|
1018
805
|
authenticatePassword(email: Email, password: string, options?: RequestOptions): Promise<ResponseContent<paths['/api/tokens/password']['post']>>;
|
|
1019
806
|
refreshToken(token: RefreshToken, options?: RequestOptions): Promise<ResponseContent<paths['/api/tokens/refresh']['post']>>;
|
|
@@ -1037,6 +824,8 @@ declare class SemiontApiClient {
|
|
|
1037
824
|
* @param data.creationMethod - Optional creation method
|
|
1038
825
|
* @param data.sourceAnnotationId - Optional source annotation ID
|
|
1039
826
|
* @param data.sourceResourceId - Optional source resource ID
|
|
827
|
+
* @param data.generationPrompt - Optional prompt that drove AI generation
|
|
828
|
+
* @param data.generator - Optional Agent(s) that generated the content
|
|
1040
829
|
* @param options - Request options including auth
|
|
1041
830
|
*/
|
|
1042
831
|
yieldResource(data: {
|
|
@@ -1049,10 +838,11 @@ declare class SemiontApiClient {
|
|
|
1049
838
|
sourceAnnotationId?: string;
|
|
1050
839
|
sourceResourceId?: string;
|
|
1051
840
|
storageUri: string;
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
841
|
+
generationPrompt?: string;
|
|
842
|
+
generator?: components['schemas']['Agent'] | components['schemas']['Agent'][];
|
|
843
|
+
isDraft?: boolean;
|
|
844
|
+
}, options?: RequestOptions): Promise<ResponseContent<paths['/resources']['post']>>;
|
|
845
|
+
browseResource(id: ResourceId, _options?: RequestOptions): Promise<components['schemas']['GetResourceResponse']>;
|
|
1056
846
|
/**
|
|
1057
847
|
* Get resource representation using W3C content negotiation
|
|
1058
848
|
* Returns raw binary content (images, PDFs, text, etc.) with content type
|
|
@@ -1125,39 +915,47 @@ declare class SemiontApiClient {
|
|
|
1125
915
|
stream: ReadableStream<Uint8Array>;
|
|
1126
916
|
contentType: string;
|
|
1127
917
|
}>;
|
|
1128
|
-
browseResources(limit?: number, archived?: boolean, query?: SearchQuery,
|
|
1129
|
-
updateResource(id: ResourceId, data:
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
918
|
+
browseResources(limit?: number, archived?: boolean, query?: SearchQuery, _options?: RequestOptions): Promise<components['schemas']['ListResourcesResponse']>;
|
|
919
|
+
updateResource(id: ResourceId, data: {
|
|
920
|
+
archived?: boolean;
|
|
921
|
+
entityTypes?: string[];
|
|
922
|
+
}, options?: RequestOptions): Promise<void>;
|
|
923
|
+
getResourceEvents(id: ResourceId, _options?: RequestOptions): Promise<components['schemas']['GetEventsResponse']>;
|
|
924
|
+
browseReferences(id: ResourceId, _options?: RequestOptions): Promise<components['schemas']['GetReferencedByResponse']>;
|
|
925
|
+
generateCloneToken(id: ResourceId, _options?: RequestOptions): Promise<components['schemas']['CloneResourceWithTokenResponse']>;
|
|
926
|
+
getResourceByToken(token: CloneToken, _options?: RequestOptions): Promise<components['schemas']['GetResourceByTokenResponse']>;
|
|
927
|
+
createResourceFromToken(data: {
|
|
928
|
+
token: string;
|
|
929
|
+
name: string;
|
|
930
|
+
content: string;
|
|
931
|
+
archiveOriginal?: boolean;
|
|
932
|
+
}, _options?: RequestOptions): Promise<{
|
|
1135
933
|
resourceId: string;
|
|
1136
934
|
}>;
|
|
1137
|
-
markAnnotation(id: ResourceId, data:
|
|
935
|
+
markAnnotation(id: ResourceId, data: components['schemas']['CreateAnnotationRequest'], _options?: RequestOptions): Promise<{
|
|
1138
936
|
annotationId: string;
|
|
1139
937
|
}>;
|
|
1140
|
-
getAnnotation(id: AnnotationId,
|
|
1141
|
-
browseAnnotation(resourceId: ResourceId, annotationId: AnnotationId,
|
|
1142
|
-
browseAnnotations(id: ResourceId,
|
|
1143
|
-
deleteAnnotation(resourceId: ResourceId, annotationId: AnnotationId,
|
|
938
|
+
getAnnotation(id: AnnotationId, _options?: RequestOptions): Promise<components['schemas']['GetAnnotationResponse']>;
|
|
939
|
+
browseAnnotation(resourceId: ResourceId, annotationId: AnnotationId, _options?: RequestOptions): Promise<components['schemas']['GetAnnotationResponse']>;
|
|
940
|
+
browseAnnotations(id: ResourceId, _motivation?: Motivation, _options?: RequestOptions): Promise<components['schemas']['GetAnnotationsResponse']>;
|
|
941
|
+
deleteAnnotation(resourceId: ResourceId, annotationId: AnnotationId, _options?: RequestOptions): Promise<void>;
|
|
1144
942
|
bindAnnotation(resourceId: ResourceId, annotationId: AnnotationId, data: {
|
|
1145
943
|
operations: BodyOperation[];
|
|
1146
|
-
},
|
|
944
|
+
}, _options?: RequestOptions): Promise<{
|
|
1147
945
|
correlationId: string;
|
|
1148
946
|
}>;
|
|
1149
|
-
getAnnotationHistory(resourceId: ResourceId, annotationId: AnnotationId,
|
|
947
|
+
getAnnotationHistory(resourceId: ResourceId, annotationId: AnnotationId, _options?: RequestOptions): Promise<components['schemas']['GetAnnotationHistoryResponse']>;
|
|
1150
948
|
annotateReferences(resourceId: ResourceId, data: {
|
|
1151
949
|
entityTypes: string[];
|
|
1152
950
|
includeDescriptiveReferences?: boolean;
|
|
1153
|
-
},
|
|
951
|
+
}, _options?: RequestOptions): Promise<{
|
|
1154
952
|
correlationId: string;
|
|
1155
953
|
jobId: string;
|
|
1156
954
|
}>;
|
|
1157
955
|
annotateHighlights(resourceId: ResourceId, data: {
|
|
1158
956
|
instructions?: string;
|
|
1159
957
|
density?: number;
|
|
1160
|
-
},
|
|
958
|
+
}, _options?: RequestOptions): Promise<{
|
|
1161
959
|
correlationId: string;
|
|
1162
960
|
jobId: string;
|
|
1163
961
|
}>;
|
|
@@ -1166,7 +964,7 @@ declare class SemiontApiClient {
|
|
|
1166
964
|
tone?: string;
|
|
1167
965
|
density?: number;
|
|
1168
966
|
language?: string;
|
|
1169
|
-
},
|
|
967
|
+
}, _options?: RequestOptions): Promise<{
|
|
1170
968
|
correlationId: string;
|
|
1171
969
|
jobId: string;
|
|
1172
970
|
}>;
|
|
@@ -1175,14 +973,14 @@ declare class SemiontApiClient {
|
|
|
1175
973
|
tone?: string;
|
|
1176
974
|
density?: number;
|
|
1177
975
|
language?: string;
|
|
1178
|
-
},
|
|
976
|
+
}, _options?: RequestOptions): Promise<{
|
|
1179
977
|
correlationId: string;
|
|
1180
978
|
jobId: string;
|
|
1181
979
|
}>;
|
|
1182
980
|
annotateTags(resourceId: ResourceId, data: {
|
|
1183
981
|
schemaId: string;
|
|
1184
982
|
categories: string[];
|
|
1185
|
-
},
|
|
983
|
+
}, _options?: RequestOptions): Promise<{
|
|
1186
984
|
correlationId: string;
|
|
1187
985
|
jobId: string;
|
|
1188
986
|
}>;
|
|
@@ -1194,14 +992,14 @@ declare class SemiontApiClient {
|
|
|
1194
992
|
language?: string;
|
|
1195
993
|
temperature?: number;
|
|
1196
994
|
maxTokens?: number;
|
|
1197
|
-
},
|
|
995
|
+
}, _options?: RequestOptions): Promise<{
|
|
1198
996
|
correlationId: string;
|
|
1199
997
|
jobId: string;
|
|
1200
998
|
}>;
|
|
1201
999
|
gatherAnnotationContext(resourceId: ResourceId, annotationId: AnnotationId, data: {
|
|
1202
1000
|
correlationId: string;
|
|
1203
1001
|
contextWindow?: number;
|
|
1204
|
-
},
|
|
1002
|
+
}, _options?: RequestOptions): Promise<{
|
|
1205
1003
|
correlationId: string;
|
|
1206
1004
|
}>;
|
|
1207
1005
|
matchSearch(resourceId: ResourceId, data: {
|
|
@@ -1210,13 +1008,17 @@ declare class SemiontApiClient {
|
|
|
1210
1008
|
context: unknown;
|
|
1211
1009
|
limit?: number;
|
|
1212
1010
|
useSemanticScoring?: boolean;
|
|
1213
|
-
},
|
|
1011
|
+
}, _options?: RequestOptions): Promise<{
|
|
1214
1012
|
correlationId: string;
|
|
1215
1013
|
}>;
|
|
1216
|
-
addEntityType(type: EntityType,
|
|
1217
|
-
addEntityTypesBulk(types: EntityType[],
|
|
1218
|
-
listEntityTypes(
|
|
1219
|
-
beckonAttention(
|
|
1014
|
+
addEntityType(type: EntityType, _options?: RequestOptions): Promise<void>;
|
|
1015
|
+
addEntityTypesBulk(types: EntityType[], _options?: RequestOptions): Promise<void>;
|
|
1016
|
+
listEntityTypes(_options?: RequestOptions): Promise<components['schemas']['GetEntityTypesResponse']>;
|
|
1017
|
+
beckonAttention(_participantId: string, data: {
|
|
1018
|
+
annotationId?: string;
|
|
1019
|
+
resourceId: string;
|
|
1020
|
+
message?: string;
|
|
1021
|
+
}, _options?: RequestOptions): Promise<components['schemas']['BeckonResponse']>;
|
|
1220
1022
|
listUsers(options?: RequestOptions): Promise<ResponseContent<paths['/api/admin/users']['get']>>;
|
|
1221
1023
|
getUserStats(options?: RequestOptions): Promise<ResponseContent<paths['/api/admin/users/stats']['get']>>;
|
|
1222
1024
|
/**
|
|
@@ -1268,7 +1070,7 @@ declare class SemiontApiClient {
|
|
|
1268
1070
|
result?: Record<string, unknown>;
|
|
1269
1071
|
}>;
|
|
1270
1072
|
private parseSSEStream;
|
|
1271
|
-
getJobStatus(id: JobId,
|
|
1073
|
+
getJobStatus(id: JobId, _options?: RequestOptions): Promise<components['schemas']['JobStatusResponse']>;
|
|
1272
1074
|
/**
|
|
1273
1075
|
* Poll a job until it completes or fails
|
|
1274
1076
|
* @param id - The job ID to poll
|
|
@@ -1278,13 +1080,935 @@ declare class SemiontApiClient {
|
|
|
1278
1080
|
pollJobUntilComplete(id: JobId, options?: {
|
|
1279
1081
|
interval?: number;
|
|
1280
1082
|
timeout?: number;
|
|
1281
|
-
onProgress?: (status:
|
|
1083
|
+
onProgress?: (status: components['schemas']['JobStatusResponse']) => void;
|
|
1282
1084
|
auth?: AccessToken;
|
|
1283
|
-
}): Promise<
|
|
1085
|
+
}): Promise<components['schemas']['JobStatusResponse']>;
|
|
1284
1086
|
healthCheck(options?: RequestOptions): Promise<ResponseContent<paths['/api/health']['get']>>;
|
|
1285
1087
|
getStatus(options?: RequestOptions): Promise<ResponseContent<paths['/api/status']['get']>>;
|
|
1286
|
-
browseFiles(dirPath?: string, sort?: 'name' | 'mtime' | 'annotationCount',
|
|
1088
|
+
browseFiles(dirPath?: string, sort?: 'name' | 'mtime' | 'annotationCount', _options?: RequestOptions): Promise<components['schemas']['BrowseFilesResponse']>;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
declare class BusRequestError extends Error {
|
|
1092
|
+
constructor(message: string);
|
|
1093
|
+
}
|
|
1094
|
+
declare function busRequest<TResult>(actor: ActorVM, emitChannel: string, payload: Record<string, unknown>, resultChannel: string, failureChannel: string, timeoutMs?: number): Promise<TResult>;
|
|
1095
|
+
|
|
1096
|
+
/**
|
|
1097
|
+
* RxJS-native read-through cache primitive.
|
|
1098
|
+
*
|
|
1099
|
+
* Behavioral contract: packages/api-client/docs/CACHE-SEMANTICS.md (B1–B13).
|
|
1100
|
+
*
|
|
1101
|
+
* Framework-agnostic: no React, no dependency on any namespace. Used by
|
|
1102
|
+
* `BrowseNamespace` to back its per-key stores, but equally usable from
|
|
1103
|
+
* CLI, MCP, or worker code.
|
|
1104
|
+
*
|
|
1105
|
+
* Shape:
|
|
1106
|
+
* - `observe(key)`: returns an Observable<V | undefined> that triggers
|
|
1107
|
+
* a fetch on first subscription for a missing key, dedup-joins any
|
|
1108
|
+
* concurrent fetch, and emits the stored value thereafter.
|
|
1109
|
+
* - `invalidate(key)`: stale-while-revalidate — keeps the current
|
|
1110
|
+
* value visible to observers, clears the in-flight guard, starts a
|
|
1111
|
+
* fresh fetch. If the previous fetch was orphaned (SSE torn down,
|
|
1112
|
+
* response lost), this is how the cache recovers.
|
|
1113
|
+
* - `remove(key)`: drops the cache entry entirely. Used for entity
|
|
1114
|
+
* deletions (B13a). No refetch.
|
|
1115
|
+
* - `set(key, value)`: writes through without a fetch. Used when a
|
|
1116
|
+
* bus event carries the new value inline (B13b).
|
|
1117
|
+
* - `invalidateAll()`: per-key SWR refetch of every currently-cached
|
|
1118
|
+
* entry. Used by gap-detection paths.
|
|
1119
|
+
* - `dispose()`: completes the store so observers unsubscribe.
|
|
1120
|
+
*
|
|
1121
|
+
* What's deliberately out:
|
|
1122
|
+
* - No subscriber ref-counting / GC of unobserved keys. The per-key
|
|
1123
|
+
* observable memo grows with the set of observed keys for the cache's
|
|
1124
|
+
* lifetime (B11). Acceptable given cache lifetime == client lifetime.
|
|
1125
|
+
* - No TTL / cacheTime. Entries are evicted only by explicit remove.
|
|
1126
|
+
* - No retry / backoff. A failing fetch leaves the cache unchanged
|
|
1127
|
+
* (B6); the caller drives retry via invalidate.
|
|
1128
|
+
*/
|
|
1129
|
+
|
|
1130
|
+
interface Cache<K, V> {
|
|
1131
|
+
/** Observable stream of the value at `key`. Triggers a fetch if not cached. */
|
|
1132
|
+
observe(key: K): Observable<V | undefined>;
|
|
1133
|
+
/** Synchronous snapshot of the current value, without triggering a fetch. */
|
|
1134
|
+
get(key: K): V | undefined;
|
|
1135
|
+
/** Iterator of currently-cached keys. For invalidateAll and diagnostics. */
|
|
1136
|
+
keys(): K[];
|
|
1137
|
+
/**
|
|
1138
|
+
* Mark the entry stale and refetch. Keeps the previous value visible
|
|
1139
|
+
* to observers during the refetch (stale-while-revalidate).
|
|
1140
|
+
*/
|
|
1141
|
+
invalidate(key: K): void;
|
|
1142
|
+
/** Drop the entry from the cache. No refetch. */
|
|
1143
|
+
remove(key: K): void;
|
|
1144
|
+
/** Write-through: set the value directly without a fetch. */
|
|
1145
|
+
set(key: K, value: V): void;
|
|
1146
|
+
/** Per-key SWR refetch of every currently-cached entry. */
|
|
1147
|
+
invalidateAll(): void;
|
|
1148
|
+
/** Release the underlying subject. Observers complete. */
|
|
1149
|
+
dispose(): void;
|
|
1150
|
+
}
|
|
1151
|
+
declare function createCache<K, V>(fetchFn: (key: K) => Promise<V>): Cache<K, V>;
|
|
1152
|
+
|
|
1153
|
+
/**
|
|
1154
|
+
* KnowledgeBase — a connection to a Semiont backend instance.
|
|
1155
|
+
*
|
|
1156
|
+
* Each KB has its own JWT, its own API base URL, and its own session.
|
|
1157
|
+
* The user is "authenticated against KB X" — never globally authenticated.
|
|
1158
|
+
*/
|
|
1159
|
+
interface KnowledgeBase {
|
|
1160
|
+
id: string;
|
|
1161
|
+
label: string;
|
|
1162
|
+
host: string;
|
|
1163
|
+
port: number;
|
|
1164
|
+
protocol: 'http' | 'https';
|
|
1165
|
+
email: string;
|
|
1166
|
+
gitBranch?: string;
|
|
1167
|
+
}
|
|
1168
|
+
/**
|
|
1169
|
+
* Input shape for adding a new KB. The id is generated by the provider.
|
|
1170
|
+
*/
|
|
1171
|
+
type NewKnowledgeBase = Omit<KnowledgeBase, 'id'>;
|
|
1172
|
+
/**
|
|
1173
|
+
* Status of the locally-stored credential for a KB. Derived from the
|
|
1174
|
+
* presence and validity of the JWT in session storage.
|
|
1175
|
+
*/
|
|
1176
|
+
type KbSessionStatus = 'authenticated' | 'expired' | 'signed-out' | 'unreachable';
|
|
1177
|
+
|
|
1178
|
+
/**
|
|
1179
|
+
* Session-level error surface. Emitted on `SemiontBrowser.error$` for
|
|
1180
|
+
* failures that make the session itself unusable (auth failed, actor
|
|
1181
|
+
* couldn't start, token refresh terminally exhausted). Per-request
|
|
1182
|
+
* errors stay with the caller as normal Promise rejections.
|
|
1183
|
+
*/
|
|
1184
|
+
type SemiontErrorCode = 'session.construct-failed' | 'session.auth-failed' | 'session.refresh-exhausted' | 'browser.sign-in-failed';
|
|
1185
|
+
declare class SemiontError extends Error {
|
|
1186
|
+
readonly code: SemiontErrorCode;
|
|
1187
|
+
readonly kbId: string | null;
|
|
1188
|
+
constructor(code: SemiontErrorCode, message: string, kbId?: string | null);
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
/**
|
|
1192
|
+
* SessionStorage — environment-agnostic persistence adapter for the
|
|
1193
|
+
* Semiont session layer. Decouples `SemiontSession` / `SemiontBrowser`
|
|
1194
|
+
* from `localStorage` / `window` so the same classes can run in a
|
|
1195
|
+
* browser, a CLI process, or tests without environment guards.
|
|
1196
|
+
*
|
|
1197
|
+
* Implementations shipped here:
|
|
1198
|
+
* - `InMemorySessionStorage` — map-backed, for tests.
|
|
1199
|
+
*
|
|
1200
|
+
* Browser-backed (`WebBrowserStorage`) lives in `@semiont/react-ui`
|
|
1201
|
+
* because it touches browser-only globals.
|
|
1202
|
+
*/
|
|
1203
|
+
/** String key/value store with optional cross-context change subscription. */
|
|
1204
|
+
interface SessionStorage {
|
|
1205
|
+
/** Read a string value; null if absent. */
|
|
1206
|
+
get(key: string): string | null;
|
|
1207
|
+
/** Write a string value. */
|
|
1208
|
+
set(key: string, value: string): void;
|
|
1209
|
+
/** Remove a key. No-op if absent. */
|
|
1210
|
+
delete(key: string): void;
|
|
1211
|
+
/**
|
|
1212
|
+
* Optional: subscribe to external changes (cross-tab, cross-process).
|
|
1213
|
+
* Browser implements via the `storage` event; filesystem would use
|
|
1214
|
+
* fs.watch; in-memory omits this method. Returns an unsubscribe
|
|
1215
|
+
* callback. If omitted, cross-context sync simply isn't available
|
|
1216
|
+
* in that environment — the session still works correctly within a
|
|
1217
|
+
* single process.
|
|
1218
|
+
*/
|
|
1219
|
+
subscribe?(handler: (key: string, newValue: string | null) => void): () => void;
|
|
1220
|
+
}
|
|
1221
|
+
/**
|
|
1222
|
+
* Map-backed `SessionStorage`. Cross-context sync is not implemented;
|
|
1223
|
+
* tests that need it can drive it manually.
|
|
1224
|
+
*/
|
|
1225
|
+
declare class InMemorySessionStorage implements SessionStorage {
|
|
1226
|
+
private readonly map;
|
|
1227
|
+
get(key: string): string | null;
|
|
1228
|
+
set(key: string, value: string): void;
|
|
1229
|
+
delete(key: string): void;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
/**
|
|
1233
|
+
* SemiontSession — per-backend session lifetime object. Owns the
|
|
1234
|
+
* SemiontApiClient, the access token BehaviorSubject, and optionally
|
|
1235
|
+
* an authenticated user. One SemiontSession exists per active backend
|
|
1236
|
+
* connection; lifetime is decoupled from React mount lifetime.
|
|
1237
|
+
*
|
|
1238
|
+
* Headless by design. Runs in browsers, CLIs, workers, and tests.
|
|
1239
|
+
* UI-specific state (session-expired/permission-denied modals) lives
|
|
1240
|
+
* in `FrontendSessionSignals`, which wraps a session — the session
|
|
1241
|
+
* itself has no modal observables, no user-facing notifications.
|
|
1242
|
+
*
|
|
1243
|
+
* Auth is parameterized via callbacks passed at construction:
|
|
1244
|
+
*
|
|
1245
|
+
* - `refresh()` — invoked on 401 / proactive re-auth. Returns the
|
|
1246
|
+
* new access token, or null on failure. The frontend passes a
|
|
1247
|
+
* closure that runs the refresh-token flow; the worker passes
|
|
1248
|
+
* one that exchanges the shared secret.
|
|
1249
|
+
*
|
|
1250
|
+
* - `validate(token)` — optional. If provided, the session calls
|
|
1251
|
+
* it once at startup with the stored token to confirm it's
|
|
1252
|
+
* still good and populate `user$`. Frontend passes `getMe`;
|
|
1253
|
+
* worker omits this (service principals have no user record).
|
|
1254
|
+
*
|
|
1255
|
+
* - `onAuthFailed(message)` — optional. Invoked when refresh
|
|
1256
|
+
* terminally fails (expired token, no recovery possible). The
|
|
1257
|
+
* frontend wires this to `FrontendSessionSignals.notifySessionExpired`
|
|
1258
|
+
* so the modal surfaces; headless consumers typically just log.
|
|
1259
|
+
*
|
|
1260
|
+
* Persistence goes through a `SessionStorage` adapter provided at
|
|
1261
|
+
* construction — the session never touches `localStorage` or `window`
|
|
1262
|
+
* directly.
|
|
1263
|
+
*/
|
|
1264
|
+
|
|
1265
|
+
type UserInfo = components['schemas']['UserResponse'];
|
|
1266
|
+
interface SemiontSessionConfig {
|
|
1267
|
+
kb: KnowledgeBase;
|
|
1268
|
+
/** Persistence adapter. Reads/writes tokens via this. */
|
|
1269
|
+
storage: SessionStorage;
|
|
1270
|
+
/**
|
|
1271
|
+
* Re-authenticate after expiry / 401. Returns a new access token
|
|
1272
|
+
* (no "Bearer " prefix) on success, or null if recovery is
|
|
1273
|
+
* impossible (user needs to sign in again, or the service secret
|
|
1274
|
+
* is missing). Callers must dedupe concurrent invocations if the
|
|
1275
|
+
* underlying auth call isn't itself idempotent.
|
|
1276
|
+
*/
|
|
1277
|
+
refresh: () => Promise<string | null>;
|
|
1278
|
+
/**
|
|
1279
|
+
* Validate the stored token at startup and populate `user$`. Omit
|
|
1280
|
+
* for service-principal sessions (worker, CLI tools) where there
|
|
1281
|
+
* is no user record to fetch.
|
|
1282
|
+
*/
|
|
1283
|
+
validate?: (token: AccessToken) => Promise<UserInfo | null>;
|
|
1284
|
+
/**
|
|
1285
|
+
* Invoked when refresh terminally fails. Frontend consumers wire
|
|
1286
|
+
* this to a UI signal that surfaces the session-expired modal.
|
|
1287
|
+
*/
|
|
1288
|
+
onAuthFailed?: (message: string | null) => void;
|
|
1289
|
+
/** Called for session-level failures (auth, refresh exhaustion). */
|
|
1290
|
+
onError?: (err: SemiontError) => void;
|
|
1291
|
+
}
|
|
1292
|
+
declare class SemiontSession {
|
|
1293
|
+
readonly kb: KnowledgeBase;
|
|
1294
|
+
readonly client: SemiontApiClient;
|
|
1295
|
+
readonly token$: BehaviorSubject<AccessToken | null>;
|
|
1296
|
+
readonly user$: BehaviorSubject<UserInfo | null>;
|
|
1297
|
+
readonly streamState$: Observable<ConnectionState>;
|
|
1298
|
+
/** Resolves after the initial validation round-trip completes (success or failure). */
|
|
1299
|
+
readonly ready: Promise<void>;
|
|
1300
|
+
private readonly storage;
|
|
1301
|
+
private readonly doRefresh;
|
|
1302
|
+
private readonly doValidate?;
|
|
1303
|
+
private readonly onAuthFailed;
|
|
1304
|
+
private readonly onError;
|
|
1305
|
+
private refreshTimer;
|
|
1306
|
+
private unsubscribeStorage;
|
|
1307
|
+
private disposed;
|
|
1308
|
+
constructor(config: SemiontSessionConfig);
|
|
1309
|
+
/**
|
|
1310
|
+
* Run the initial mount-time validation. If a stored access token is
|
|
1311
|
+
* present and unexpired, call the configured `validate` with it to
|
|
1312
|
+
* confirm it still works and populate `user$`. If expired, try
|
|
1313
|
+
* refresh first. On 401 from validate, try refresh once. Surfaces
|
|
1314
|
+
* auth-failed on terminal failure.
|
|
1315
|
+
*
|
|
1316
|
+
* When no `validate` callback is provided (service principals), this
|
|
1317
|
+
* still runs through the refresh-if-expired step so the stored
|
|
1318
|
+
* token is current — it just skips the user-validation round trip.
|
|
1319
|
+
*/
|
|
1320
|
+
private validate;
|
|
1321
|
+
/**
|
|
1322
|
+
* Refresh the access token via the configured `refresh` callback.
|
|
1323
|
+
* On success, pushes the new token into `token$` and schedules the
|
|
1324
|
+
* next proactive refresh. On failure, clears persisted state and
|
|
1325
|
+
* fires `onAuthFailed` — the frontend's wiring of that callback is
|
|
1326
|
+
* what surfaces the session-expired modal.
|
|
1327
|
+
*/
|
|
1328
|
+
refresh(): Promise<AccessToken | null>;
|
|
1329
|
+
private scheduleProactiveRefresh;
|
|
1330
|
+
private clearRefreshTimer;
|
|
1331
|
+
/**
|
|
1332
|
+
* Cross-context sync: another tab/process refreshed or signed out this
|
|
1333
|
+
* KB. Mirror the change into our in-memory state.
|
|
1334
|
+
*/
|
|
1335
|
+
private handleStorageChange;
|
|
1336
|
+
get expiresAt(): Date | null;
|
|
1337
|
+
dispose(): Promise<void>;
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
/**
|
|
1341
|
+
* OpenResource — a single entry in the open-resources list (tabs).
|
|
1342
|
+
*
|
|
1343
|
+
* The list itself lives on `SemiontBrowser.openResources$`. The CRUD
|
|
1344
|
+
* methods (`addOpenResource`, `removeOpenResource`, `updateOpenResourceName`,
|
|
1345
|
+
* `reorderOpenResources`) live on `SemiontBrowser` too.
|
|
1346
|
+
*/
|
|
1347
|
+
interface OpenResource {
|
|
1348
|
+
/** Unique identifier for the resource */
|
|
1349
|
+
id: string;
|
|
1350
|
+
/** Display name of the resource */
|
|
1351
|
+
name: string;
|
|
1352
|
+
/** Timestamp when the resource was opened */
|
|
1353
|
+
openedAt: number;
|
|
1354
|
+
/** Order/position for manual sorting (optional for backward compatibility) */
|
|
1355
|
+
order?: number;
|
|
1356
|
+
/** Media type for icon display (e.g., 'application/pdf', 'text/plain') */
|
|
1357
|
+
mediaType?: string;
|
|
1358
|
+
/** Working-tree URI (e.g. "file://docs/overview.md") — used as tooltip in navigation */
|
|
1359
|
+
storageUri?: string;
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
/**
|
|
1363
|
+
* FrontendSessionSignals — modal state that belongs to the UI, not
|
|
1364
|
+
* the session itself.
|
|
1365
|
+
*
|
|
1366
|
+
* `SemiontSession` is a headless per-backend client + token + user
|
|
1367
|
+
* holder. It can run in any process: browser, worker, CLI, test. But
|
|
1368
|
+
* the session-expired / permission-denied *modals* only make sense
|
|
1369
|
+
* in a UI context. Keeping those observables on `SemiontSession`
|
|
1370
|
+
* meant workers and CLIs carried four dead BehaviorSubjects that
|
|
1371
|
+
* nothing would ever fire.
|
|
1372
|
+
*
|
|
1373
|
+
* `FrontendSessionSignals` owns the modal state and has no hard
|
|
1374
|
+
* reference to a session. `SemiontBrowser` constructs one alongside
|
|
1375
|
+
* every frontend session and wires:
|
|
1376
|
+
*
|
|
1377
|
+
* - `session.onAuthFailed` → `signals.notifySessionExpired` so
|
|
1378
|
+
* proactive-refresh failures surface as modals
|
|
1379
|
+
* - `notify` module handlers → the active signals' methods so
|
|
1380
|
+
* external callers (e.g. React Query's QueryCache.onError) can
|
|
1381
|
+
* trigger the modals without touching the session
|
|
1382
|
+
*
|
|
1383
|
+
* React consumers that need modal state subscribe here; consumers
|
|
1384
|
+
* that need bus/HTTP access continue to subscribe to the session.
|
|
1385
|
+
*
|
|
1386
|
+
* Session auth-state cleanup (clearing token, clearing storage) is
|
|
1387
|
+
* the session's own responsibility inside `refresh()` — by the time
|
|
1388
|
+
* `notifySessionExpired` runs, the session has already torn down.
|
|
1389
|
+
* Signals only surfaces the modal.
|
|
1390
|
+
*/
|
|
1391
|
+
|
|
1392
|
+
declare class FrontendSessionSignals {
|
|
1393
|
+
readonly sessionExpiredAt$: BehaviorSubject<number | null>;
|
|
1394
|
+
readonly sessionExpiredMessage$: BehaviorSubject<string | null>;
|
|
1395
|
+
readonly permissionDeniedAt$: BehaviorSubject<number | null>;
|
|
1396
|
+
readonly permissionDeniedMessage$: BehaviorSubject<string | null>;
|
|
1397
|
+
constructor();
|
|
1398
|
+
notifySessionExpired(message: string | null): void;
|
|
1399
|
+
notifyPermissionDenied(message: string | null): void;
|
|
1400
|
+
acknowledgeSessionExpired(): void;
|
|
1401
|
+
acknowledgePermissionDenied(): void;
|
|
1402
|
+
dispose(): void;
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
/**
|
|
1406
|
+
* SemiontBrowser — top-level app-facing container for non-KB state.
|
|
1407
|
+
*
|
|
1408
|
+
* Holds the list of configured KBs, the active KB selection, the active
|
|
1409
|
+
* SemiontSession, the identity token, the open-resources list, and a
|
|
1410
|
+
* session-level error stream. Module-scoped singleton — survives every
|
|
1411
|
+
* React re-render, remount, and route change. `SemiontProvider` hands
|
|
1412
|
+
* the singleton to the React tree; `useSemiont()` returns it.
|
|
1413
|
+
*
|
|
1414
|
+
* Persistence goes through a `SessionStorage` adapter provided at
|
|
1415
|
+
* construction — the browser never touches `localStorage` or `window`
|
|
1416
|
+
* directly.
|
|
1417
|
+
*/
|
|
1418
|
+
|
|
1419
|
+
interface SemiontBrowserConfig {
|
|
1420
|
+
/** Persistence adapter. The browser reads/writes all persisted state via this. */
|
|
1421
|
+
storage: SessionStorage;
|
|
1422
|
+
}
|
|
1423
|
+
declare class SemiontBrowser {
|
|
1424
|
+
readonly kbs$: BehaviorSubject<KnowledgeBase[]>;
|
|
1425
|
+
readonly activeKbId$: BehaviorSubject<string | null>;
|
|
1426
|
+
readonly activeSession$: BehaviorSubject<SemiontSession | null>;
|
|
1427
|
+
/**
|
|
1428
|
+
* Modal signals (session-expired / permission-denied) for the
|
|
1429
|
+
* currently-active session. Parallels `activeSession$` — always
|
|
1430
|
+
* non-null when `activeSession$` is non-null, always null when it
|
|
1431
|
+
* is. Extracted from the session itself so headless sessions
|
|
1432
|
+
* (workers, CLIs, tests) don't carry dead modal observables.
|
|
1433
|
+
* See [FrontendSessionSignals](./frontend-session-signals.ts).
|
|
1434
|
+
*/
|
|
1435
|
+
readonly activeSignals$: BehaviorSubject<FrontendSessionSignals | null>;
|
|
1436
|
+
/**
|
|
1437
|
+
* True while a session is actively being constructed (setActiveKb /
|
|
1438
|
+
* signIn in flight, awaiting `session.ready`). Distinguishes the
|
|
1439
|
+
* "session about to arrive" intermediate state from "session
|
|
1440
|
+
* intentionally null" (after signOut, or when the active KB has no
|
|
1441
|
+
* stored credentials). UIs that want a loading spinner should gate
|
|
1442
|
+
* on this; otherwise they get stuck spinning after every signOut.
|
|
1443
|
+
*/
|
|
1444
|
+
readonly sessionActivating$: BehaviorSubject<boolean>;
|
|
1445
|
+
readonly openResources$: BehaviorSubject<OpenResource[]>;
|
|
1446
|
+
readonly error$: Subject<SemiontError>;
|
|
1447
|
+
readonly identityToken$: BehaviorSubject<string | null>;
|
|
1448
|
+
private readonly storage;
|
|
1449
|
+
/**
|
|
1450
|
+
* App-scoped EventBus. Hosts UI-shell events that must work regardless
|
|
1451
|
+
* of whether a KB session is active: panel toggles, sidebar state,
|
|
1452
|
+
* tab reorders, routing, settings, etc. Disjoint from the per-session
|
|
1453
|
+
* bus inside `SemiontApiClient`, which carries KB-content events
|
|
1454
|
+
* (mark:*, beckon:*, gather:*, match:*, bind:*, yield:*, browse:click).
|
|
1455
|
+
*/
|
|
1456
|
+
private readonly eventBus;
|
|
1457
|
+
private unregisterNotify;
|
|
1458
|
+
private unsubscribeStorage;
|
|
1459
|
+
private disposed;
|
|
1460
|
+
private activating;
|
|
1461
|
+
/**
|
|
1462
|
+
* Per-KB in-flight refresh dedup. Simultaneous 401s for the same
|
|
1463
|
+
* KB converge on a single `/api/tokens/refresh` network call.
|
|
1464
|
+
* Was previously module-scoped in `refresh.ts`; moved here when
|
|
1465
|
+
* that file was deleted — SemiontBrowser is a singleton so the
|
|
1466
|
+
* scoping is equivalent.
|
|
1467
|
+
*/
|
|
1468
|
+
private readonly inFlightRefreshes;
|
|
1469
|
+
constructor(config: SemiontBrowserConfig);
|
|
1470
|
+
/** Emit an event on the browser's app-scoped bus. */
|
|
1471
|
+
emit<K extends keyof EventMap>(channel: K, payload: EventMap[K]): void;
|
|
1472
|
+
/** Subscribe to an event; returns unsubscribe. */
|
|
1473
|
+
on<K extends keyof EventMap>(channel: K, handler: (payload: EventMap[K]) => void): () => void;
|
|
1474
|
+
/** Read-only observable for an app-scoped channel. */
|
|
1475
|
+
stream<K extends keyof EventMap>(channel: K): Observable<EventMap[K]>;
|
|
1476
|
+
/**
|
|
1477
|
+
* Set the app-level identity token (from NextAuth's useSession).
|
|
1478
|
+
* Called at the root layout via a single `useEffect`. No other site
|
|
1479
|
+
* in the codebase should call this.
|
|
1480
|
+
*/
|
|
1481
|
+
setIdentityToken(token: string | null): void;
|
|
1482
|
+
addKb(input: NewKnowledgeBase, access: string, refresh: string): KnowledgeBase;
|
|
1483
|
+
removeKb(id: string): void;
|
|
1484
|
+
updateKb(id: string, updates: Partial<KnowledgeBase>): void;
|
|
1485
|
+
/**
|
|
1486
|
+
* Read the locally-stored credential status for a KB. Pure / synchronous —
|
|
1487
|
+
* does not subscribe to context changes. Used by KB-list UI to color status
|
|
1488
|
+
* dots without requiring re-renders on every tick.
|
|
1489
|
+
*/
|
|
1490
|
+
getKbSessionStatus(kbId: string): KbSessionStatus;
|
|
1491
|
+
/**
|
|
1492
|
+
* Switch the active KB. Follows the D2 disposal contract:
|
|
1493
|
+
* 1. Synchronously announce the new id on `activeKbId$` and null out
|
|
1494
|
+
* `activeSession$` so views see a safe empty state first.
|
|
1495
|
+
* 2. Serialize overlapping calls — if an activation is in flight, wait
|
|
1496
|
+
* for it before proceeding.
|
|
1497
|
+
* 3. Dispose whatever session is currently live.
|
|
1498
|
+
* 4. Construct the next session and await `session.ready`.
|
|
1499
|
+
* 5. Before emitting, re-check `activeKbId$` — if a newer call superseded
|
|
1500
|
+
* us while we waited, dispose our session and skip the emit.
|
|
1501
|
+
* 6. Emit the new session.
|
|
1502
|
+
*/
|
|
1503
|
+
setActiveKb(id: string | null): Promise<void>;
|
|
1504
|
+
/**
|
|
1505
|
+
* Sign in to an existing KB: store the tokens and (re)activate the
|
|
1506
|
+
* session. If the KB is already active, the current session is disposed
|
|
1507
|
+
* and replaced so the new tokens take effect.
|
|
1508
|
+
*/
|
|
1509
|
+
signIn(id: string, access: string, refresh: string): Promise<void>;
|
|
1510
|
+
/**
|
|
1511
|
+
* Sign out of a KB: clear stored tokens. If the KB is active, dispose
|
|
1512
|
+
* its session + signals and emit null for both.
|
|
1513
|
+
*/
|
|
1514
|
+
signOut(id: string): Promise<void>;
|
|
1515
|
+
addOpenResource(id: string, name: string, mediaType?: string, storageUri?: string): void;
|
|
1516
|
+
removeOpenResource(id: string): void;
|
|
1517
|
+
updateOpenResourceName(id: string, name: string): void;
|
|
1518
|
+
reorderOpenResources(oldIndex: number, newIndex: number): void;
|
|
1519
|
+
/**
|
|
1520
|
+
* Refresh the active KB's access token. Returns the new token on
|
|
1521
|
+
* success, null on failure. Concurrent calls for the same KB
|
|
1522
|
+
* dedupe through `inFlightRefreshes`, so simultaneous 401s trigger
|
|
1523
|
+
* only one `/api/tokens/refresh` round trip.
|
|
1524
|
+
*
|
|
1525
|
+
* Uses a throwaway `SemiontApiClient` with no `tokenRefresher` —
|
|
1526
|
+
* a refresh call returning 401 would otherwise re-enter this
|
|
1527
|
+
* function infinitely.
|
|
1528
|
+
*/
|
|
1529
|
+
private performRefresh;
|
|
1530
|
+
/**
|
|
1531
|
+
* Validate an access token by calling `getMe` on a throwaway
|
|
1532
|
+
* client. The session uses this once at startup to populate
|
|
1533
|
+
* `user$`; 401 triggers a refresh-then-retry inside the session.
|
|
1534
|
+
*/
|
|
1535
|
+
private performValidate;
|
|
1536
|
+
dispose(): Promise<void>;
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
/**
|
|
1540
|
+
* Module-scoped singleton for SemiontBrowser. Constructed lazily on first
|
|
1541
|
+
* `getBrowser()` call, survives every React re-render, remount, and route
|
|
1542
|
+
* change.
|
|
1543
|
+
*
|
|
1544
|
+
* The caller provides a `SessionStorage` implementation — there is no
|
|
1545
|
+
* default here because storage-backend selection is environment-specific
|
|
1546
|
+
* (browsers use `WebBrowserStorage`, CLI uses a filesystem adapter,
|
|
1547
|
+
* tests use `InMemorySessionStorage`). The first call to `getBrowser`
|
|
1548
|
+
* wins; subsequent calls return the cached instance regardless of the
|
|
1549
|
+
* storage passed.
|
|
1550
|
+
*/
|
|
1551
|
+
|
|
1552
|
+
interface GetBrowserOptions {
|
|
1553
|
+
/** Persistence adapter used to construct the singleton on first call. */
|
|
1554
|
+
storage: SessionStorage;
|
|
1555
|
+
}
|
|
1556
|
+
declare function getBrowser(options: GetBrowserOptions): SemiontBrowser;
|
|
1557
|
+
|
|
1558
|
+
/**
|
|
1559
|
+
* Pure helpers and storage-adapter-driven loaders for the Semiont
|
|
1560
|
+
* session layer.
|
|
1561
|
+
*
|
|
1562
|
+
* Contains:
|
|
1563
|
+
* - Storage key shape (constants, `sessionKey(kbId)`)
|
|
1564
|
+
* - JWT expiry parsing and "is expired" check
|
|
1565
|
+
* - URL/protocol helpers for KB instances
|
|
1566
|
+
* - Loaders/savers that take a `SessionStorage` and operate over it
|
|
1567
|
+
* (no direct `localStorage` access)
|
|
1568
|
+
*
|
|
1569
|
+
* No React imports, no module-scoped state, no side effects beyond
|
|
1570
|
+
* whatever the passed-in `SessionStorage` does.
|
|
1571
|
+
*/
|
|
1572
|
+
|
|
1573
|
+
/** The shape persisted per KB. */
|
|
1574
|
+
interface StoredSession {
|
|
1575
|
+
access: string;
|
|
1576
|
+
refresh: string;
|
|
1577
|
+
}
|
|
1578
|
+
declare function setStoredSession(storage: SessionStorage, kbId: string, session: StoredSession): void;
|
|
1579
|
+
declare function defaultProtocol(host: string): 'http' | 'https';
|
|
1580
|
+
declare function isValidHostname(host: string): boolean;
|
|
1581
|
+
declare function kbBackendUrl(kb: KnowledgeBase): string;
|
|
1582
|
+
|
|
1583
|
+
declare function notifySessionExpired(message?: string): void;
|
|
1584
|
+
declare function notifyPermissionDenied(message?: string): void;
|
|
1585
|
+
|
|
1586
|
+
/**
|
|
1587
|
+
* createSearchPipeline
|
|
1588
|
+
*
|
|
1589
|
+
* A debounced-search RxJS pipeline factory. Combines an input Subject with a
|
|
1590
|
+
* downstream fetch function and emits typed `{ results, isSearching }` state.
|
|
1591
|
+
*
|
|
1592
|
+
* Designed to be created once per component instance via React's
|
|
1593
|
+
* `useState(() => createSearchPipeline(...))` lazy initializer, then consumed
|
|
1594
|
+
* via `useObservable(pipeline.state$)`. The pipeline holds no React state and
|
|
1595
|
+
* has no React imports — it's pure RxJS, unit-testable without a renderer.
|
|
1596
|
+
*
|
|
1597
|
+
* The fetch function is expected to return `Observable<T[] | undefined>`,
|
|
1598
|
+
* matching the cache-miss-then-data shape of `BrowseNamespace` Observables:
|
|
1599
|
+
* `undefined` means "fetch in flight, no value yet"; an array means "data
|
|
1600
|
+
* available (possibly empty)".
|
|
1601
|
+
*/
|
|
1602
|
+
|
|
1603
|
+
interface SearchState<T> {
|
|
1604
|
+
results: T[];
|
|
1605
|
+
isSearching: boolean;
|
|
1606
|
+
}
|
|
1607
|
+
interface SearchPipeline<T> {
|
|
1608
|
+
/** Latest query string. Bind to a controlled input via `useObservable`. */
|
|
1609
|
+
query$: Observable<string>;
|
|
1610
|
+
/** Latest search state — results plus a loading flag. */
|
|
1611
|
+
state$: Observable<SearchState<T>>;
|
|
1612
|
+
/** Push a new query value. Triggers the debounced fetch. */
|
|
1613
|
+
setQuery(value: string): void;
|
|
1614
|
+
/** Tear down the input Subject. Call from `useEffect` cleanup. */
|
|
1615
|
+
dispose(): void;
|
|
1616
|
+
}
|
|
1617
|
+
interface SearchPipelineOptions {
|
|
1618
|
+
/** Milliseconds to wait after the last keystroke before fetching. Default 250. */
|
|
1619
|
+
debounceMs?: number;
|
|
1620
|
+
/** Initial query value. Useful for modals that open with a pre-filled term. */
|
|
1621
|
+
initialQuery?: string;
|
|
1622
|
+
}
|
|
1623
|
+
declare function createSearchPipeline<T>(fetch: (query: string) => Observable<T[] | undefined>, options?: SearchPipelineOptions): SearchPipeline<T>;
|
|
1624
|
+
|
|
1625
|
+
interface BeckonVM extends ViewModel {
|
|
1626
|
+
hoveredAnnotationId$: Observable<string | null>;
|
|
1627
|
+
hover(annotationId: string | null): void;
|
|
1628
|
+
focus(annotationId: string): void;
|
|
1629
|
+
sparkle(annotationId: string): void;
|
|
1630
|
+
}
|
|
1631
|
+
declare function createBeckonVM(client: SemiontApiClient): BeckonVM;
|
|
1632
|
+
/** Default milliseconds the mouse must dwell before beckon:hover is emitted. */
|
|
1633
|
+
declare const HOVER_DELAY_MS = 150;
|
|
1634
|
+
type EmitHover = (annotationId: string | null) => void;
|
|
1635
|
+
interface HoverHandlers {
|
|
1636
|
+
handleMouseEnter: (annotationId: string) => void;
|
|
1637
|
+
handleMouseLeave: () => void;
|
|
1638
|
+
cleanup: () => void;
|
|
1639
|
+
}
|
|
1640
|
+
declare function createHoverHandlers(emit: EmitHover, delayMs: number): HoverHandlers;
|
|
1641
|
+
|
|
1642
|
+
/**
|
|
1643
|
+
* ShellVM — app-shell state: which toolbar panel is open, tab-bar
|
|
1644
|
+
* coordination helpers, scroll-to-annotation signals. Lives on
|
|
1645
|
+
* `SemiontBrowser`'s app-scoped bus (not the per-session client bus)
|
|
1646
|
+
* because panel toggles and shell chrome must work regardless of
|
|
1647
|
+
* whether a KB session is active.
|
|
1648
|
+
*
|
|
1649
|
+
* Channels: `panel:toggle`, `panel:open`, `panel:close`.
|
|
1650
|
+
*/
|
|
1651
|
+
|
|
1652
|
+
type ToolbarPanelType = 'history' | 'info' | 'annotations' | 'settings' | 'collaboration' | 'user' | 'jsonld' | 'knowledge-base';
|
|
1653
|
+
declare const COMMON_PANELS: readonly ToolbarPanelType[];
|
|
1654
|
+
declare const RESOURCE_PANELS: readonly ToolbarPanelType[];
|
|
1655
|
+
interface ShellVM extends ViewModel {
|
|
1656
|
+
activePanel$: Observable<ToolbarPanelType | null>;
|
|
1657
|
+
scrollToAnnotationId$: Observable<string | null>;
|
|
1658
|
+
panelInitialTab$: Observable<{
|
|
1659
|
+
tab: string;
|
|
1660
|
+
generation: number;
|
|
1661
|
+
} | null>;
|
|
1662
|
+
openPanel(panel: string): void;
|
|
1663
|
+
closePanel(): void;
|
|
1664
|
+
togglePanel(panel: string): void;
|
|
1665
|
+
onScrollCompleted(): void;
|
|
1666
|
+
}
|
|
1667
|
+
interface ShellVMOptions {
|
|
1668
|
+
initialPanel?: ToolbarPanelType | null;
|
|
1669
|
+
onPanelChange?: (panel: ToolbarPanelType | null) => void;
|
|
1670
|
+
}
|
|
1671
|
+
declare function createShellVM(browser: SemiontBrowser, options?: ShellVMOptions): ShellVM;
|
|
1672
|
+
|
|
1673
|
+
interface GatherVM extends ViewModel {
|
|
1674
|
+
context$: Observable<GatheredContext | null>;
|
|
1675
|
+
loading$: Observable<boolean>;
|
|
1676
|
+
error$: Observable<Error | null>;
|
|
1677
|
+
annotationId$: Observable<AnnotationId | null>;
|
|
1678
|
+
}
|
|
1679
|
+
declare function createGatherVM(client: SemiontApiClient, resourceId: ResourceId): GatherVM;
|
|
1680
|
+
|
|
1681
|
+
interface MatchVM extends ViewModel {
|
|
1682
|
+
}
|
|
1683
|
+
declare function createMatchVM(client: SemiontApiClient, _resourceId: ResourceId): MatchVM;
|
|
1684
|
+
|
|
1685
|
+
type JobProgress$1 = components['schemas']['JobProgress'];
|
|
1686
|
+
interface GenerateDocumentOptions {
|
|
1687
|
+
title: string;
|
|
1688
|
+
storageUri: string;
|
|
1689
|
+
prompt?: string;
|
|
1690
|
+
language?: string;
|
|
1691
|
+
temperature?: number;
|
|
1692
|
+
maxTokens?: number;
|
|
1693
|
+
context: GatheredContext;
|
|
1694
|
+
}
|
|
1695
|
+
interface YieldVM extends ViewModel {
|
|
1696
|
+
isGenerating$: Observable<boolean>;
|
|
1697
|
+
progress$: Observable<JobProgress$1 | null>;
|
|
1698
|
+
generate(referenceId: string, options: GenerateDocumentOptions): void;
|
|
1699
|
+
}
|
|
1700
|
+
declare function createYieldVM(client: SemiontApiClient, resourceId: ResourceId, locale: string): YieldVM;
|
|
1701
|
+
|
|
1702
|
+
type JobProgress = components['schemas']['JobProgress'];
|
|
1703
|
+
interface PendingAnnotation {
|
|
1704
|
+
selector: Selector | Selector[];
|
|
1705
|
+
motivation: Motivation;
|
|
1706
|
+
}
|
|
1707
|
+
interface MarkVM extends ViewModel {
|
|
1708
|
+
pendingAnnotation$: Observable<PendingAnnotation | null>;
|
|
1709
|
+
assistingMotivation$: Observable<Motivation | null>;
|
|
1710
|
+
progress$: Observable<JobProgress | null>;
|
|
1711
|
+
}
|
|
1712
|
+
declare function createMarkVM(client: SemiontApiClient, resourceId: ResourceId): MarkVM;
|
|
1713
|
+
|
|
1714
|
+
type ResourceDescriptor$2 = components['schemas']['ResourceDescriptor'];
|
|
1715
|
+
interface DiscoverVM extends ViewModel {
|
|
1716
|
+
browse: ShellVM;
|
|
1717
|
+
search: SearchPipeline<ResourceDescriptor$2>;
|
|
1718
|
+
recentResources$: Observable<ResourceDescriptor$2[]>;
|
|
1719
|
+
entityTypes$: Observable<string[]>;
|
|
1720
|
+
isLoadingRecent$: Observable<boolean>;
|
|
1721
|
+
}
|
|
1722
|
+
declare function createDiscoverVM(client: SemiontApiClient, browse: ShellVM): DiscoverVM;
|
|
1723
|
+
|
|
1724
|
+
interface EntityTagsVM extends ViewModel {
|
|
1725
|
+
browse: ShellVM;
|
|
1726
|
+
entityTypes$: Observable<string[]>;
|
|
1727
|
+
isLoading$: Observable<boolean>;
|
|
1728
|
+
newTag$: Observable<string>;
|
|
1729
|
+
error$: Observable<string>;
|
|
1730
|
+
isAdding$: Observable<boolean>;
|
|
1731
|
+
setNewTag(value: string): void;
|
|
1732
|
+
addTag(): Promise<void>;
|
|
1733
|
+
}
|
|
1734
|
+
declare function createEntityTagsVM(client: SemiontApiClient, browse: ShellVM): EntityTagsVM;
|
|
1735
|
+
|
|
1736
|
+
interface ImportPreview {
|
|
1737
|
+
format: string;
|
|
1738
|
+
version: number;
|
|
1739
|
+
sourceUrl: string;
|
|
1740
|
+
stats: Record<string, number>;
|
|
1741
|
+
}
|
|
1742
|
+
interface ExchangeVM extends ViewModel {
|
|
1743
|
+
browse: ShellVM;
|
|
1744
|
+
selectedFile$: Observable<File | null>;
|
|
1745
|
+
preview$: Observable<ImportPreview | null>;
|
|
1746
|
+
importPhase$: Observable<string | null>;
|
|
1747
|
+
importMessage$: Observable<string | undefined>;
|
|
1748
|
+
importResult$: Observable<Record<string, unknown> | undefined>;
|
|
1749
|
+
isExporting$: Observable<boolean>;
|
|
1750
|
+
isImporting$: Observable<boolean>;
|
|
1751
|
+
selectFile(file: File): void;
|
|
1752
|
+
cancelImport(): void;
|
|
1753
|
+
doExport(): Promise<{
|
|
1754
|
+
blob: Blob;
|
|
1755
|
+
filename: string;
|
|
1756
|
+
}>;
|
|
1757
|
+
doImport(): Promise<void>;
|
|
1758
|
+
}
|
|
1759
|
+
declare function createExchangeVM(browse: ShellVM, exportFn: (params?: {
|
|
1760
|
+
includeArchived?: boolean;
|
|
1761
|
+
}) => Promise<Response>, importFn: (file: File, options?: {
|
|
1762
|
+
onProgress?: (event: {
|
|
1763
|
+
phase: string;
|
|
1764
|
+
message?: string;
|
|
1765
|
+
result?: Record<string, unknown>;
|
|
1766
|
+
}) => void;
|
|
1767
|
+
}) => Promise<{
|
|
1768
|
+
phase: string;
|
|
1769
|
+
message?: string;
|
|
1770
|
+
result?: Record<string, unknown>;
|
|
1771
|
+
}>): ExchangeVM;
|
|
1772
|
+
|
|
1773
|
+
interface AdminUsersVM extends ViewModel {
|
|
1774
|
+
browse: ShellVM;
|
|
1775
|
+
users$: Observable<unknown[]>;
|
|
1776
|
+
stats$: Observable<unknown | null>;
|
|
1777
|
+
usersLoading$: Observable<boolean>;
|
|
1778
|
+
statsLoading$: Observable<boolean>;
|
|
1779
|
+
updateUser(id: string, data: {
|
|
1780
|
+
isAdmin?: boolean;
|
|
1781
|
+
isActive?: boolean;
|
|
1782
|
+
}): Promise<void>;
|
|
1783
|
+
}
|
|
1784
|
+
declare function createAdminUsersVM(client: SemiontApiClient, browse: ShellVM): AdminUsersVM;
|
|
1785
|
+
|
|
1786
|
+
interface AdminSecurityVM extends ViewModel {
|
|
1787
|
+
browse: ShellVM;
|
|
1788
|
+
providers$: Observable<unknown[]>;
|
|
1789
|
+
allowedDomains$: Observable<string[]>;
|
|
1790
|
+
isLoading$: Observable<boolean>;
|
|
1791
|
+
}
|
|
1792
|
+
declare function createAdminSecurityVM(client: SemiontApiClient, browse: ShellVM): AdminSecurityVM;
|
|
1793
|
+
|
|
1794
|
+
interface WelcomeVM extends ViewModel {
|
|
1795
|
+
userData$: Observable<{
|
|
1796
|
+
termsAcceptedAt?: string;
|
|
1797
|
+
} | null>;
|
|
1798
|
+
isProcessing$: Observable<boolean>;
|
|
1799
|
+
acceptTerms(): Promise<void>;
|
|
1800
|
+
}
|
|
1801
|
+
declare function createWelcomeVM(client: SemiontApiClient): WelcomeVM;
|
|
1802
|
+
|
|
1803
|
+
type ResourceDescriptor$1 = components['schemas']['ResourceDescriptor'];
|
|
1804
|
+
interface ResourceLoaderVM extends ViewModel {
|
|
1805
|
+
resource$: Observable<ResourceDescriptor$1 | undefined>;
|
|
1806
|
+
isLoading$: Observable<boolean>;
|
|
1807
|
+
invalidate(): void;
|
|
1808
|
+
}
|
|
1809
|
+
declare function createResourceLoaderVM(client: SemiontApiClient, resourceId: ResourceId): ResourceLoaderVM;
|
|
1810
|
+
|
|
1811
|
+
interface SessionVM extends ViewModel {
|
|
1812
|
+
isLoggingOut$: Observable<boolean>;
|
|
1813
|
+
logout(): Promise<void>;
|
|
1814
|
+
}
|
|
1815
|
+
declare function createSessionVM(client: SemiontApiClient): SessionVM;
|
|
1816
|
+
|
|
1817
|
+
interface SmelterEvent {
|
|
1818
|
+
type: string;
|
|
1819
|
+
resourceId?: string;
|
|
1820
|
+
payload: Record<string, unknown>;
|
|
1821
|
+
}
|
|
1822
|
+
interface SmelterActorVMOptions {
|
|
1823
|
+
baseUrl: string;
|
|
1824
|
+
token: string;
|
|
1825
|
+
reconnectMs?: number;
|
|
1826
|
+
}
|
|
1827
|
+
interface SmelterActorVM extends ViewModel {
|
|
1828
|
+
events$: Observable<SmelterEvent>;
|
|
1829
|
+
state$: Observable<ConnectionState>;
|
|
1830
|
+
emit(channel: string, payload: Record<string, unknown>): Promise<void>;
|
|
1831
|
+
start(): void;
|
|
1832
|
+
stop(): void;
|
|
1833
|
+
}
|
|
1834
|
+
declare function createSmelterActorVM(options: SmelterActorVMOptions): SmelterActorVM;
|
|
1835
|
+
|
|
1836
|
+
/**
|
|
1837
|
+
* Job Claim Adapter — worker-side job lifecycle glue on top of a
|
|
1838
|
+
* shared `ActorVM`.
|
|
1839
|
+
*
|
|
1840
|
+
* Replaces the old `WorkerVM`, which owned its own actor and
|
|
1841
|
+
* duplicated the SSE connection that `SemiontApiClient` already held.
|
|
1842
|
+
* Workers now construct a `SemiontSession` normally (one actor, one
|
|
1843
|
+
* SSE connection) and use this adapter to attach job-claim behaviour
|
|
1844
|
+
* on top of `session.client.actor`.
|
|
1845
|
+
*
|
|
1846
|
+
* The adapter is intentionally thin: it subscribes to `job:queued`
|
|
1847
|
+
* on the actor, claims jobs via the existing request-response
|
|
1848
|
+
* protocol (`job:claim` → `job:claimed` / `job:claim-failed`), and
|
|
1849
|
+
* exposes observables for job orchestration. It does **not** own
|
|
1850
|
+
* the actor, has no HTTP concerns, and has no modal state.
|
|
1851
|
+
*/
|
|
1852
|
+
|
|
1853
|
+
interface JobAssignment {
|
|
1854
|
+
jobId: string;
|
|
1855
|
+
type: string;
|
|
1856
|
+
resourceId: string;
|
|
1857
|
+
}
|
|
1858
|
+
interface ActiveJob {
|
|
1859
|
+
jobId: string;
|
|
1860
|
+
type: string;
|
|
1861
|
+
resourceId: string;
|
|
1862
|
+
userId: string;
|
|
1863
|
+
params: Record<string, unknown>;
|
|
1864
|
+
}
|
|
1865
|
+
interface JobClaimAdapterOptions {
|
|
1866
|
+
/** Shared actor (typically `session.client.actor`). */
|
|
1867
|
+
actor: ActorVM;
|
|
1868
|
+
/**
|
|
1869
|
+
* Job types this worker can process. Jobs of other types that
|
|
1870
|
+
* arrive on `job:queued` are ignored. Empty array = accept any.
|
|
1871
|
+
*/
|
|
1872
|
+
jobTypes: string[];
|
|
1873
|
+
}
|
|
1874
|
+
interface JobClaimAdapter {
|
|
1875
|
+
/** Currently-claimed job, or null when idle. */
|
|
1876
|
+
readonly activeJob$: Observable<ActiveJob | null>;
|
|
1877
|
+
/** True while a claim is in flight or a job is being processed. */
|
|
1878
|
+
readonly isProcessing$: Observable<boolean>;
|
|
1879
|
+
/** Monotonically-incrementing count of successfully-completed jobs. */
|
|
1880
|
+
readonly jobsCompleted$: Observable<number>;
|
|
1881
|
+
/** Stream of job failures (including claim-failed and processing errors). */
|
|
1882
|
+
readonly errors$: Observable<{
|
|
1883
|
+
jobId: string;
|
|
1884
|
+
error: string;
|
|
1885
|
+
}>;
|
|
1886
|
+
/**
|
|
1887
|
+
* Subscribe to `job:queued` events (adding the channel to the actor
|
|
1888
|
+
* if not already subscribed) and begin claiming matching jobs.
|
|
1889
|
+
* Idempotent — calling `start()` twice is a no-op.
|
|
1890
|
+
*/
|
|
1891
|
+
start(): void;
|
|
1892
|
+
/** Stop claiming new jobs. Does not cancel an in-flight job. */
|
|
1893
|
+
stop(): void;
|
|
1894
|
+
/** Signal successful completion of `activeJob$`. */
|
|
1895
|
+
completeJob(): void;
|
|
1896
|
+
/** Signal failure of `activeJob$`. Emits on `errors$`. */
|
|
1897
|
+
failJob(jobId: string, error: string): void;
|
|
1898
|
+
/** Release observables. Does not dispose the shared actor. */
|
|
1899
|
+
dispose(): void;
|
|
1900
|
+
}
|
|
1901
|
+
/**
|
|
1902
|
+
* Attach job-claim behaviour to a shared `ActorVM`.
|
|
1903
|
+
*/
|
|
1904
|
+
declare function createJobClaimAdapter(options: JobClaimAdapterOptions): JobClaimAdapter;
|
|
1905
|
+
|
|
1906
|
+
interface Job {
|
|
1907
|
+
jobId: string;
|
|
1908
|
+
type: string;
|
|
1909
|
+
status: string;
|
|
1910
|
+
resourceId: string;
|
|
1911
|
+
userId: string;
|
|
1912
|
+
created: string;
|
|
1913
|
+
startedAt?: string;
|
|
1914
|
+
completedAt?: string;
|
|
1915
|
+
error?: string;
|
|
1916
|
+
progress?: Record<string, unknown>;
|
|
1917
|
+
result?: Record<string, unknown>;
|
|
1918
|
+
}
|
|
1919
|
+
interface JobQueueVM extends ViewModel {
|
|
1920
|
+
jobs$: Observable<Job[]>;
|
|
1921
|
+
pendingByType$: Observable<Map<string, number>>;
|
|
1922
|
+
runningJobs$: Observable<Job[]>;
|
|
1923
|
+
jobCreated$: Observable<Job>;
|
|
1924
|
+
jobCompleted$: Observable<Job>;
|
|
1925
|
+
jobFailed$: Observable<Job>;
|
|
1926
|
+
}
|
|
1927
|
+
declare function createJobQueueVM(client: SemiontApiClient): JobQueueVM;
|
|
1928
|
+
|
|
1929
|
+
type Annotation = components['schemas']['Annotation'];
|
|
1930
|
+
interface AnnotationGroups {
|
|
1931
|
+
highlights: Annotation[];
|
|
1932
|
+
comments: Annotation[];
|
|
1933
|
+
assessments: Annotation[];
|
|
1934
|
+
references: Annotation[];
|
|
1935
|
+
tags: Annotation[];
|
|
1936
|
+
}
|
|
1937
|
+
type StoredEventResponse = components['schemas']['StoredEventResponse'];
|
|
1938
|
+
interface WizardState {
|
|
1939
|
+
open: boolean;
|
|
1940
|
+
annotationId: string | null;
|
|
1941
|
+
resourceId: string | null;
|
|
1942
|
+
defaultTitle: string;
|
|
1943
|
+
entityTypes: string[];
|
|
1944
|
+
}
|
|
1945
|
+
interface ResourceViewerPageVM extends ViewModel {
|
|
1946
|
+
beckon: BeckonVM;
|
|
1947
|
+
browse: ShellVM;
|
|
1948
|
+
mark: MarkVM;
|
|
1949
|
+
gather: GatherVM;
|
|
1950
|
+
yield: YieldVM;
|
|
1951
|
+
annotations$: Observable<Annotation[]>;
|
|
1952
|
+
annotationGroups$: Observable<AnnotationGroups>;
|
|
1953
|
+
entityTypes$: Observable<string[]>;
|
|
1954
|
+
events$: Observable<StoredEventResponse[]>;
|
|
1955
|
+
referencedBy$: Observable<ReferencedByEntry[]>;
|
|
1956
|
+
content$: Observable<string>;
|
|
1957
|
+
contentLoading$: Observable<boolean>;
|
|
1958
|
+
mediaToken$: Observable<string | null>;
|
|
1959
|
+
wizard$: Observable<WizardState>;
|
|
1960
|
+
closeWizard(): void;
|
|
1961
|
+
}
|
|
1962
|
+
declare function createResourceViewerPageVM(client: SemiontApiClient, resourceId: ResourceId, locale: string, browse: ShellVM, options?: {
|
|
1963
|
+
mediaType?: string;
|
|
1964
|
+
}): ResourceViewerPageVM;
|
|
1965
|
+
|
|
1966
|
+
type ResourceDescriptor = components['schemas']['ResourceDescriptor'];
|
|
1967
|
+
type ComposeMode = 'new' | 'clone' | 'reference';
|
|
1968
|
+
interface ComposeParams {
|
|
1969
|
+
mode?: string | undefined;
|
|
1970
|
+
token?: string | undefined;
|
|
1971
|
+
annotationUri?: string | undefined;
|
|
1972
|
+
sourceDocumentId?: string | undefined;
|
|
1973
|
+
name?: string | undefined;
|
|
1974
|
+
entityTypes?: string | undefined;
|
|
1975
|
+
storedContext?: string | undefined;
|
|
1976
|
+
}
|
|
1977
|
+
interface CloneData {
|
|
1978
|
+
sourceResource: ResourceDescriptor;
|
|
1979
|
+
sourceContent: string;
|
|
1980
|
+
}
|
|
1981
|
+
interface ReferenceData {
|
|
1982
|
+
annotationUri: string;
|
|
1983
|
+
sourceDocumentId: string;
|
|
1984
|
+
name: string;
|
|
1985
|
+
entityTypes: string[];
|
|
1986
|
+
}
|
|
1987
|
+
interface SaveResourceParams {
|
|
1988
|
+
mode: ComposeMode;
|
|
1989
|
+
name: string;
|
|
1990
|
+
storageUri: string;
|
|
1991
|
+
content?: string;
|
|
1992
|
+
file?: File;
|
|
1993
|
+
format?: string;
|
|
1994
|
+
charset?: string;
|
|
1995
|
+
entityTypes?: string[];
|
|
1996
|
+
language: string;
|
|
1997
|
+
archiveOriginal?: boolean;
|
|
1998
|
+
annotationUri?: string;
|
|
1999
|
+
sourceDocumentId?: string;
|
|
2000
|
+
}
|
|
2001
|
+
interface ComposePageVM extends ViewModel {
|
|
2002
|
+
browse: ShellVM;
|
|
2003
|
+
mode$: Observable<ComposeMode>;
|
|
2004
|
+
loading$: Observable<boolean>;
|
|
2005
|
+
cloneData$: Observable<CloneData | null>;
|
|
2006
|
+
referenceData$: Observable<ReferenceData | null>;
|
|
2007
|
+
gatheredContext$: Observable<GatheredContext | null>;
|
|
2008
|
+
entityTypes$: Observable<string[]>;
|
|
2009
|
+
save(params: SaveResourceParams): Promise<string>;
|
|
1287
2010
|
}
|
|
2011
|
+
declare function createComposePageVM(client: SemiontApiClient, browse: ShellVM, params: ComposeParams, auth?: AccessToken): ComposePageVM;
|
|
1288
2012
|
|
|
1289
2013
|
/**
|
|
1290
2014
|
* MIME type utilities for Semiont
|
|
@@ -1324,4 +2048,4 @@ declare function isPdfMimeType(mimeType: string): boolean;
|
|
|
1324
2048
|
type MimeCategory = 'text' | 'image' | 'unsupported';
|
|
1325
2049
|
declare function getMimeCategory(mimeType: string): MimeCategory;
|
|
1326
2050
|
|
|
1327
|
-
export { APIError, AdminNamespace, type AnnotationHistoryResponse, AuthNamespace, BeckonNamespace, BindNamespace, BrowseNamespace, type CreateAnnotationInput, type CreateFromTokenOptions, type CreateResourceInput, type GatherAnnotationProgress, GatherNamespace, type GenerationOptions, JobNamespace, type MarkAssistOptions, type MarkAssistProgress, MarkNamespace, MatchNamespace, type MatchSearchProgress, type MimeCategory, type
|
|
2051
|
+
export { APIError, type ActiveJob, type ActorVM, type ActorVMOptions, AdminNamespace, type AdminSecurityVM, type AdminUsersVM, type AnnotationGroups, type AnnotationHistoryResponse, AuthNamespace, BeckonNamespace, type BeckonVM, BindNamespace, BrowseNamespace, type BusEvent, BusRequestError, COMMON_PANELS, type Cache, type CloneData, type ComposeMode, type ComposePageVM, type ComposeParams, type ConnectionState, type CreateAnnotationInput, type CreateFromTokenOptions, type CreateResourceInput, DEGRADED_THRESHOLD_MS, 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 MarkAssistOptions, type MarkAssistProgress, MarkNamespace, type MarkVM, MatchNamespace, type MatchSearchProgress, type MatchVM, type MimeCategory, type NewKnowledgeBase, type OpenResource, type PendingAnnotation, RESOURCE_PANELS, type ReferenceData, type ReferencedByEntry, type RequestContent$1 as RequestContent, type RequestOptions, type ResourceLoaderVM, type ResourceViewerPageVM, type ResponseContent$1 as ResponseContent, type SaveResourceParams, type SearchPipeline, type SearchPipelineOptions, type SearchState, SemiontApiClient, type SemiontApiClientConfig, SemiontBrowser, type SemiontBrowserConfig, SemiontError, type SemiontErrorCode, SemiontSession, type SemiontSessionConfig, type SessionStorage, type SessionVM, type ShellVM, type ShellVMOptions, type SmelterActorVM, type SmelterActorVMOptions, type SmelterEvent, type StoredSession, type TokenRefresher, type ToolbarPanelType, type User, type UserInfo, type ViewModel, type WelcomeVM, type WizardState, YieldNamespace, type YieldVM, busRequest, createActorVM, 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, getExtensionForMimeType, getMimeCategory, isImageMimeType, isPdfMimeType, isTextMimeType, isValidHostname, kbBackendUrl, notifyPermissionDenied, notifySessionExpired, setStoredSession };
|