@fatagnus/dink-sdk 2.23.1 → 2.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/center/client.d.ts +15 -4
- package/dist/center/client.js +52 -2
- package/dist/center/client.js.map +1 -1
- package/dist/center/index.d.ts +578 -2
- package/dist/edge/client.d.ts +0 -1
- package/dist/edge/client.js +61 -4
- package/dist/edge/client.js.map +1 -1
- package/dist/edge/index.d.ts +501 -4
- package/dist/edge/service-builder.d.ts +0 -1
- package/dist/edge/worker.d.ts +0 -1
- package/dist/env/index.d.ts +12 -9
- package/dist/errors.d.ts +0 -1
- package/dist/index.d.ts +1069 -9
- package/dist/introspect-utils.d.ts +0 -1
- package/dist/introspect.d.ts +0 -1
- package/dist/types.d.ts +229 -214
- package/dist/types.js.map +1 -1
- package/package.json +3 -2
- package/dist/center/client.d.ts.map +0 -1
- package/dist/center/index.d.ts.map +0 -1
- package/dist/edge/client.d.ts.map +0 -1
- package/dist/edge/index.d.ts.map +0 -1
- package/dist/edge/service-builder.d.ts.map +0 -1
- package/dist/edge/worker.d.ts.map +0 -1
- package/dist/env/index.d.ts.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/introspect-utils.d.ts.map +0 -1
- package/dist/introspect.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
package/dist/center/index.d.ts
CHANGED
|
@@ -1,2 +1,578 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// Generated by dts-bundle-generator v9.5.1
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Service definition metadata
|
|
5
|
+
*/
|
|
6
|
+
export interface ServiceDefinition {
|
|
7
|
+
name: string;
|
|
8
|
+
version: string;
|
|
9
|
+
methods: string[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Interface for implementing a service handler on the edge
|
|
13
|
+
*/
|
|
14
|
+
/** Bidirectional raw byte channel on the edge side. */
|
|
15
|
+
export interface EdgeChannel {
|
|
16
|
+
/** Unique channel identifier (e.g., "ch_abc123") */
|
|
17
|
+
readonly id: string;
|
|
18
|
+
/** Send raw bytes to the browser. Returns false if backpressure is active. */
|
|
19
|
+
write(data: Uint8Array): boolean;
|
|
20
|
+
/** Register handler for incoming raw bytes from browser */
|
|
21
|
+
onData(handler: (data: Uint8Array) => void): void;
|
|
22
|
+
/** Close the channel, optionally with a reason */
|
|
23
|
+
close(reason?: string): void;
|
|
24
|
+
/** Called when the channel closes (by either side). Supports multiple handlers. */
|
|
25
|
+
onClose(handler: (reason?: string) => void): void;
|
|
26
|
+
/** Send a JSON-serializable control message out-of-band */
|
|
27
|
+
sendControl(msg: unknown): void;
|
|
28
|
+
/** Register handler for incoming control messages */
|
|
29
|
+
onControl(handler: (msg: unknown) => void): void;
|
|
30
|
+
/** True if channel is open */
|
|
31
|
+
readonly isOpen: boolean;
|
|
32
|
+
/** Promise that resolves when the channel closes */
|
|
33
|
+
readonly closed: Promise<void>;
|
|
34
|
+
/** Number of bytes queued for sending */
|
|
35
|
+
readonly bufferedAmount: number;
|
|
36
|
+
/** Register handler called when buffered data has been flushed */
|
|
37
|
+
onDrain(handler: () => void): void;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
*/
|
|
41
|
+
export interface ServiceHandler {
|
|
42
|
+
definition(): ServiceDefinition;
|
|
43
|
+
handleRequest(method: string, data: Uint8Array): Promise<Uint8Array>;
|
|
44
|
+
handleStream?(method: string, data: Uint8Array, emit: (data: Uint8Array) => Promise<void>, signal?: AbortSignal): Promise<void>;
|
|
45
|
+
handleChannel?(method: string, channel: EdgeChannel, request: unknown): Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Interface for making RPC calls to edge services
|
|
49
|
+
*/
|
|
50
|
+
export interface ServiceCaller {
|
|
51
|
+
call<Req, Resp>(edgeId: string, service: string, method: string, req: Req): Promise<Resp>;
|
|
52
|
+
subscribe<Req, Resp>(edgeId: string, service: string, method: string, req: Req, handler: (resp: Resp) => void): Promise<Subscription>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Interface for streaming subscriptions
|
|
56
|
+
*/
|
|
57
|
+
export interface Subscription {
|
|
58
|
+
unsubscribe(): void;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Connection quality level
|
|
62
|
+
*/
|
|
63
|
+
export type ConnectionQualityLevel = "excellent" | "good" | "fair" | "poor" | "unknown";
|
|
64
|
+
/**
|
|
65
|
+
* Connection state
|
|
66
|
+
*/
|
|
67
|
+
export type ConnectionState = "connecting" | "connected" | "reconnecting" | "disconnected";
|
|
68
|
+
/**
|
|
69
|
+
* Connection quality metrics
|
|
70
|
+
*/
|
|
71
|
+
export interface ConnectionQuality {
|
|
72
|
+
state: ConnectionState;
|
|
73
|
+
latencyMs: number | null;
|
|
74
|
+
avgLatencyMs: number | null;
|
|
75
|
+
messagesSentPerSecond: number;
|
|
76
|
+
messagesReceivedPerSecond: number;
|
|
77
|
+
totalMessagesSent: number;
|
|
78
|
+
totalMessagesReceived: number;
|
|
79
|
+
lastPingAt: number | null;
|
|
80
|
+
qualityLevel: ConnectionQualityLevel;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Configuration for connection quality monitoring
|
|
84
|
+
*/
|
|
85
|
+
export interface ConnectionQualityConfig {
|
|
86
|
+
/** Latency threshold for "excellent" quality in ms (default: 50) */
|
|
87
|
+
excellentLatencyMs?: number;
|
|
88
|
+
/** Latency threshold for "good" quality in ms (default: 150) */
|
|
89
|
+
goodLatencyMs?: number;
|
|
90
|
+
/** Latency threshold for "fair" quality in ms (default: 300) */
|
|
91
|
+
fairLatencyMs?: number;
|
|
92
|
+
/** Ping interval in milliseconds (default: 30000) */
|
|
93
|
+
pingIntervalMs?: number;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Configuration for CenterClient
|
|
97
|
+
*/
|
|
98
|
+
export interface CenterConfig {
|
|
99
|
+
/** dinkd server URL (e.g., "nats://localhost:4222") */
|
|
100
|
+
serverUrl: string;
|
|
101
|
+
/** App API key for authentication */
|
|
102
|
+
apiKey?: string;
|
|
103
|
+
/** App ID (optional, defaults to 'platform') */
|
|
104
|
+
appId?: string;
|
|
105
|
+
/** Request timeout in ms (default: 30000) */
|
|
106
|
+
timeout?: number;
|
|
107
|
+
/** Reconnect wait time in ms (default: 2000) */
|
|
108
|
+
reconnectWait?: number;
|
|
109
|
+
/** Max reconnect attempts, -1 for infinite (default: -1) */
|
|
110
|
+
maxReconnects?: number;
|
|
111
|
+
/** Connection quality configuration */
|
|
112
|
+
qualityConfig?: ConnectionQualityConfig;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Information about a discovered edge
|
|
116
|
+
*/
|
|
117
|
+
export interface EdgeInfo {
|
|
118
|
+
/** Unique edge identifier */
|
|
119
|
+
id: string;
|
|
120
|
+
/** Display name of the edge */
|
|
121
|
+
name: string;
|
|
122
|
+
/** Online status */
|
|
123
|
+
status: "online" | "offline";
|
|
124
|
+
/** Labels attached to the edge */
|
|
125
|
+
labels: Record<string, string>;
|
|
126
|
+
/** Services exposed by this edge */
|
|
127
|
+
services: string[];
|
|
128
|
+
/** Groups this edge belongs to */
|
|
129
|
+
groups?: string[];
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Options for discovering edges
|
|
133
|
+
*/
|
|
134
|
+
export interface DiscoverOptions {
|
|
135
|
+
/** Filter by service name */
|
|
136
|
+
serviceName?: string;
|
|
137
|
+
/** Filter by labels */
|
|
138
|
+
labels?: Record<string, string>;
|
|
139
|
+
/** Only return online edges (default: true) */
|
|
140
|
+
onlineOnly?: boolean;
|
|
141
|
+
/** Filter by method name (requires serviceName) */
|
|
142
|
+
methodName?: string;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Options for RPC calls
|
|
146
|
+
*/
|
|
147
|
+
export interface CallOptions {
|
|
148
|
+
/** Request timeout in ms */
|
|
149
|
+
timeout?: number;
|
|
150
|
+
/** Number of retries on failure (default: 0) */
|
|
151
|
+
retries?: number;
|
|
152
|
+
/** Delay between retries in ms (default: 1000) */
|
|
153
|
+
retryDelay?: number;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Type of API key
|
|
157
|
+
*/
|
|
158
|
+
export type KeyType = "edge" | "center" | "client" | "admin" | "app_master" | "sync_key";
|
|
159
|
+
/**
|
|
160
|
+
* Status of an API key
|
|
161
|
+
*/
|
|
162
|
+
export type KeyStatus = "active" | "expired" | "revoked" | "disabled";
|
|
163
|
+
/**
|
|
164
|
+
* Metadata about an API key
|
|
165
|
+
*/
|
|
166
|
+
export interface KeyMetadata {
|
|
167
|
+
/** Unique key identifier */
|
|
168
|
+
id: string;
|
|
169
|
+
/** App ID this key belongs to */
|
|
170
|
+
appId: string;
|
|
171
|
+
/** Display name of the key */
|
|
172
|
+
name: string;
|
|
173
|
+
/** Type of the key */
|
|
174
|
+
type: KeyType;
|
|
175
|
+
/** Edge ID (for edge keys) */
|
|
176
|
+
edgeId?: string;
|
|
177
|
+
/** Scopes granted to this key */
|
|
178
|
+
scopes: string[];
|
|
179
|
+
/** Resource restrictions */
|
|
180
|
+
resources?: {
|
|
181
|
+
services?: string[];
|
|
182
|
+
streams?: string[];
|
|
183
|
+
kvBuckets?: string[];
|
|
184
|
+
events?: string[];
|
|
185
|
+
};
|
|
186
|
+
/** Labels attached to the key */
|
|
187
|
+
labels?: Record<string, string>;
|
|
188
|
+
/** Current status of the key */
|
|
189
|
+
status: KeyStatus;
|
|
190
|
+
/** When the key was created */
|
|
191
|
+
createdAt: Date;
|
|
192
|
+
/** When the key expires (if set) */
|
|
193
|
+
expiresAt?: Date;
|
|
194
|
+
/** When the key was last used */
|
|
195
|
+
lastUsedAt?: Date;
|
|
196
|
+
/** When the key was revoked (if revoked) */
|
|
197
|
+
revokedAt?: Date;
|
|
198
|
+
/** Reason for revocation (if revoked) */
|
|
199
|
+
revokeReason?: string;
|
|
200
|
+
/** Groups for peer communication */
|
|
201
|
+
groups?: string[];
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Options for creating an API key
|
|
205
|
+
*/
|
|
206
|
+
export interface CreateKeyOptions {
|
|
207
|
+
/** Display name for the key */
|
|
208
|
+
name: string;
|
|
209
|
+
/** Type of key to create */
|
|
210
|
+
type: KeyType;
|
|
211
|
+
/** Edge ID (optional for edge keys, auto-generated if not provided) */
|
|
212
|
+
edgeId?: string;
|
|
213
|
+
/** Scopes to grant (optional, defaults based on type) */
|
|
214
|
+
scopes?: string[];
|
|
215
|
+
/** Scope bundle to use (e.g., 'bundle:edge') */
|
|
216
|
+
scopeBundle?: string;
|
|
217
|
+
/** Expiration time (e.g., '24h', '7d', '30d') */
|
|
218
|
+
expiresIn?: string;
|
|
219
|
+
/** Labels to attach to the key */
|
|
220
|
+
labels?: Record<string, string>;
|
|
221
|
+
/** Groups for peer-to-peer communication */
|
|
222
|
+
groups?: string[];
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Result from creating an API key
|
|
226
|
+
*/
|
|
227
|
+
export interface CreateKeyResult {
|
|
228
|
+
/** Key metadata */
|
|
229
|
+
key: KeyMetadata;
|
|
230
|
+
/** The actual API key (only shown once!) */
|
|
231
|
+
apiKey: string;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Options for listing keys
|
|
235
|
+
*/
|
|
236
|
+
export interface ListKeysOptions {
|
|
237
|
+
/** Filter by key type */
|
|
238
|
+
type?: KeyType;
|
|
239
|
+
/** Filter by labels */
|
|
240
|
+
labels?: Record<string, string>;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Service introspection types for AI agent support.
|
|
244
|
+
* These types match the Go struct definitions in pkg/types/introspect.go
|
|
245
|
+
* Property names use snake_case to match Go JSON tags for wire compatibility.
|
|
246
|
+
*/
|
|
247
|
+
/**
|
|
248
|
+
* MethodAIContext provides AI-specific guidance for understanding and using a method.
|
|
249
|
+
*/
|
|
250
|
+
export interface MethodAIContext {
|
|
251
|
+
/** When this method should be called */
|
|
252
|
+
when_to_use?: string;
|
|
253
|
+
/** Why to use this method over alternatives */
|
|
254
|
+
why_to_use?: string;
|
|
255
|
+
/** Instructions on how to use this method correctly */
|
|
256
|
+
how_to_use?: string;
|
|
257
|
+
/** Conditions that must be true before calling this method */
|
|
258
|
+
preconditions?: string[];
|
|
259
|
+
/** Side effects that occur when calling this method */
|
|
260
|
+
side_effects?: string[];
|
|
261
|
+
/** Names of related methods that may be useful */
|
|
262
|
+
related_methods?: string[];
|
|
263
|
+
/** Scenarios describing when to use this method */
|
|
264
|
+
scenarios?: string[];
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* ServiceAIContext provides AI-specific guidance for understanding a service.
|
|
268
|
+
*/
|
|
269
|
+
export interface ServiceAIContext {
|
|
270
|
+
/** High-level description of what this service does */
|
|
271
|
+
overview?: string;
|
|
272
|
+
/** List of capabilities this service provides */
|
|
273
|
+
capabilities?: string[];
|
|
274
|
+
/** Known limitations of this service */
|
|
275
|
+
limitations?: string[];
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* MethodDescriptor provides complete metadata about a service method for introspection
|
|
279
|
+
* and AI agent consumption.
|
|
280
|
+
*/
|
|
281
|
+
export interface MethodDescriptor {
|
|
282
|
+
/** Method name */
|
|
283
|
+
name: string;
|
|
284
|
+
/** Human-readable description of what this method does */
|
|
285
|
+
description?: string;
|
|
286
|
+
/** JSON Schema describing the input parameters */
|
|
287
|
+
input_schema?: Record<string, unknown>;
|
|
288
|
+
/** JSON Schema describing the output */
|
|
289
|
+
output_schema?: Record<string, unknown>;
|
|
290
|
+
/** Tags for categorization and filtering */
|
|
291
|
+
tags?: string[];
|
|
292
|
+
/** AI-specific context for this method */
|
|
293
|
+
ai_context?: MethodAIContext;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* ServiceDescriptor provides complete metadata about a service for introspection
|
|
297
|
+
* and AI agent consumption.
|
|
298
|
+
*/
|
|
299
|
+
export interface ServiceDescriptor {
|
|
300
|
+
/** Service name */
|
|
301
|
+
name: string;
|
|
302
|
+
/** Service version (semver recommended) */
|
|
303
|
+
version: string;
|
|
304
|
+
/** Human-readable description of this service */
|
|
305
|
+
description?: string;
|
|
306
|
+
/** Methods provided by this service */
|
|
307
|
+
methods?: MethodDescriptor[];
|
|
308
|
+
/** AI-specific context for this service */
|
|
309
|
+
ai_context?: ServiceAIContext;
|
|
310
|
+
/** Names of related services */
|
|
311
|
+
related_services?: string[];
|
|
312
|
+
}
|
|
313
|
+
/** Bidirectional raw byte channel (center-to-edge). */
|
|
314
|
+
export interface CenterChannel {
|
|
315
|
+
/** Unique channel identifier */
|
|
316
|
+
readonly id: string;
|
|
317
|
+
/** Send raw bytes to the edge. Returns false if backpressure is active. */
|
|
318
|
+
write(data: Uint8Array): boolean;
|
|
319
|
+
/** Register handler for incoming raw bytes from edge */
|
|
320
|
+
onData(handler: (data: Uint8Array) => void): void;
|
|
321
|
+
/** Close the channel */
|
|
322
|
+
close(): void;
|
|
323
|
+
/** Called when the channel closes. Supports multiple handlers. */
|
|
324
|
+
onClose(handler: (reason?: string) => void): void;
|
|
325
|
+
/** Send a JSON-serializable control message out-of-band */
|
|
326
|
+
sendControl(msg: unknown): void;
|
|
327
|
+
/** Register handler for incoming control messages */
|
|
328
|
+
onControl(handler: (msg: unknown) => void): void;
|
|
329
|
+
/** True if channel is open */
|
|
330
|
+
readonly isOpen: boolean;
|
|
331
|
+
/** Promise that resolves when the channel closes */
|
|
332
|
+
readonly closed: Promise<void>;
|
|
333
|
+
/** Number of bytes queued for sending */
|
|
334
|
+
readonly bufferedAmount: number;
|
|
335
|
+
/** Register handler called when buffered data has been flushed */
|
|
336
|
+
onDrain(handler: () => void): void;
|
|
337
|
+
}
|
|
338
|
+
export declare class CenterClient implements ServiceCaller {
|
|
339
|
+
private config;
|
|
340
|
+
private nc;
|
|
341
|
+
private appId;
|
|
342
|
+
private connectionState;
|
|
343
|
+
private lastLatencyMs;
|
|
344
|
+
private lastPingAt;
|
|
345
|
+
private latencyHistory;
|
|
346
|
+
private messagesSent;
|
|
347
|
+
private messagesReceived;
|
|
348
|
+
private statsStartedAt;
|
|
349
|
+
private qualityCallbacks;
|
|
350
|
+
private qualityConfig;
|
|
351
|
+
private pingTimer;
|
|
352
|
+
constructor(config: CenterConfig);
|
|
353
|
+
connect(): Promise<void>;
|
|
354
|
+
close(): Promise<void>;
|
|
355
|
+
isConnected(): boolean;
|
|
356
|
+
/**
|
|
357
|
+
* Get current connection quality metrics.
|
|
358
|
+
*/
|
|
359
|
+
getConnectionQuality(): ConnectionQuality;
|
|
360
|
+
/**
|
|
361
|
+
* Subscribe to connection quality changes.
|
|
362
|
+
* @param callback - Function called with updated quality metrics
|
|
363
|
+
* @returns Unsubscribe function
|
|
364
|
+
*/
|
|
365
|
+
onConnectionQualityChange(callback: (quality: ConnectionQuality) => void): () => void;
|
|
366
|
+
/**
|
|
367
|
+
* Ping the server and return round-trip latency in milliseconds.
|
|
368
|
+
*/
|
|
369
|
+
ping(): Promise<number>;
|
|
370
|
+
private setConnectionState;
|
|
371
|
+
private calculateQualityLevel;
|
|
372
|
+
private calculateAvgLatency;
|
|
373
|
+
private buildQualitySnapshot;
|
|
374
|
+
private emitQualityChange;
|
|
375
|
+
private setupConnectionHandlers;
|
|
376
|
+
private startPingTimer;
|
|
377
|
+
private stopPingTimer;
|
|
378
|
+
discoverEdges(opts?: DiscoverOptions): Promise<EdgeInfo[]>;
|
|
379
|
+
listEdges(): Promise<EdgeInfo[]>;
|
|
380
|
+
call<Req, Resp>(edgeId: string, service: string, method: string, req: Req, opts?: CallOptions): Promise<Resp>;
|
|
381
|
+
subscribe<Req, Resp>(edgeId: string, service: string, method: string, req: Req, handler: (resp: Resp) => void): Promise<Subscription>;
|
|
382
|
+
/**
|
|
383
|
+
* Open a bidirectional raw byte channel to an edge service.
|
|
384
|
+
*/
|
|
385
|
+
openChannel(edgeId: string, service: string, method: string, request?: unknown): Promise<CenterChannel>;
|
|
386
|
+
/**
|
|
387
|
+
* Call an edge RPC method and receive a streaming response.
|
|
388
|
+
* Returns an async iterable that yields response chunks.
|
|
389
|
+
*/
|
|
390
|
+
callEdgeRpcStream<Req>(edgeId: string, service: string, method: string, req: Req, opts?: CallOptions): AsyncGenerator<Uint8Array, void, undefined>;
|
|
391
|
+
private delay;
|
|
392
|
+
private getAuthHeaders;
|
|
393
|
+
/**
|
|
394
|
+
* Register a webhook endpoint for an edge service.
|
|
395
|
+
*/
|
|
396
|
+
registerWebhook(opts: {
|
|
397
|
+
edgeId: string;
|
|
398
|
+
service: string;
|
|
399
|
+
method: string;
|
|
400
|
+
secret?: string;
|
|
401
|
+
secretMode?: string;
|
|
402
|
+
description?: string;
|
|
403
|
+
}): Promise<Record<string, unknown>>;
|
|
404
|
+
/**
|
|
405
|
+
* List webhook registrations.
|
|
406
|
+
* @param filter - Optional filter by edgeId
|
|
407
|
+
*/
|
|
408
|
+
listWebhooks(filter?: {
|
|
409
|
+
edgeId?: string;
|
|
410
|
+
}): Promise<Array<Record<string, unknown>>>;
|
|
411
|
+
/**
|
|
412
|
+
* Delete a webhook registration.
|
|
413
|
+
* @param webhookId - The webhook ID to delete
|
|
414
|
+
*/
|
|
415
|
+
deleteWebhook(webhookId: string): Promise<void>;
|
|
416
|
+
/**
|
|
417
|
+
* Get a specific webhook by ID.
|
|
418
|
+
* @param webhookId - The webhook ID
|
|
419
|
+
*/
|
|
420
|
+
getWebhook(webhookId: string): Promise<Record<string, unknown>>;
|
|
421
|
+
/**
|
|
422
|
+
* Describe a service by name, returning its ServiceDescriptor.
|
|
423
|
+
* @param serviceName - The name or ID of the service to describe
|
|
424
|
+
* @returns Promise resolving to the ServiceDescriptor
|
|
425
|
+
*/
|
|
426
|
+
describeService(serviceName: string): Promise<ServiceDescriptor>;
|
|
427
|
+
/**
|
|
428
|
+
* Describe a specific method of a service, returning its MethodDescriptor.
|
|
429
|
+
* @param serviceName - The name or ID of the service
|
|
430
|
+
* @param methodName - The name of the method to describe
|
|
431
|
+
* @returns Promise resolving to the MethodDescriptor
|
|
432
|
+
*/
|
|
433
|
+
describeMethod(serviceName: string, methodName: string): Promise<MethodDescriptor>;
|
|
434
|
+
/**
|
|
435
|
+
* Get LLM-friendly context (llm.txt format) for specified services.
|
|
436
|
+
* @param serviceNames - A single service name or array of service names
|
|
437
|
+
* @returns Promise resolving to llm.txt formatted string
|
|
438
|
+
*/
|
|
439
|
+
getLLMContext(serviceNames: string | string[]): Promise<string>;
|
|
440
|
+
/**
|
|
441
|
+
* Get LLM-friendly context (llm.txt format) for all registered services.
|
|
442
|
+
* @returns Promise resolving to llm.txt formatted string
|
|
443
|
+
*/
|
|
444
|
+
getAllLLMContext(): Promise<string>;
|
|
445
|
+
/**
|
|
446
|
+
* List all services with their full ServiceDescriptors.
|
|
447
|
+
* @returns Promise resolving to array of ServiceDescriptors
|
|
448
|
+
*/
|
|
449
|
+
listServicesWithDescriptions(): Promise<ServiceDescriptor[]>;
|
|
450
|
+
/**
|
|
451
|
+
* Internal helper to list services from the API.
|
|
452
|
+
*/
|
|
453
|
+
private listServicesInternal;
|
|
454
|
+
/**
|
|
455
|
+
* Internal helper to get descriptors for a list of services.
|
|
456
|
+
*/
|
|
457
|
+
private getDescriptorsForServices;
|
|
458
|
+
/**
|
|
459
|
+
* Create a new API key.
|
|
460
|
+
* @param options - Key creation options
|
|
461
|
+
* @returns Promise resolving to the created key metadata and API key string
|
|
462
|
+
* @throws Error if key creation fails
|
|
463
|
+
*
|
|
464
|
+
* @example
|
|
465
|
+
* ```typescript
|
|
466
|
+
* const result = await client.createKey({
|
|
467
|
+
* name: 'my-edge-agent',
|
|
468
|
+
* type: 'edge',
|
|
469
|
+
* });
|
|
470
|
+
* console.log('API Key (save this!):', result.apiKey);
|
|
471
|
+
* console.log('Edge ID:', result.key.edgeId);
|
|
472
|
+
* ```
|
|
473
|
+
*/
|
|
474
|
+
createKey(options: CreateKeyOptions): Promise<CreateKeyResult>;
|
|
475
|
+
/**
|
|
476
|
+
* List API keys with optional filtering.
|
|
477
|
+
* @param options - Optional filter options
|
|
478
|
+
* @returns Promise resolving to array of key metadata
|
|
479
|
+
*
|
|
480
|
+
* @example
|
|
481
|
+
* ```typescript
|
|
482
|
+
* // List all edge keys
|
|
483
|
+
* const keys = await client.listKeys({ type: 'edge' });
|
|
484
|
+
* for (const key of keys) {
|
|
485
|
+
* console.log(`${key.name}: ${key.status}`);
|
|
486
|
+
* }
|
|
487
|
+
* ```
|
|
488
|
+
*/
|
|
489
|
+
listKeys(options?: ListKeysOptions): Promise<KeyMetadata[]>;
|
|
490
|
+
/**
|
|
491
|
+
* Get details of a specific key.
|
|
492
|
+
* @param keyId - The key ID to retrieve
|
|
493
|
+
* @returns Promise resolving to key metadata
|
|
494
|
+
*
|
|
495
|
+
* @example
|
|
496
|
+
* ```typescript
|
|
497
|
+
* const key = await client.getKey('key-123');
|
|
498
|
+
* console.log(`Key status: ${key.status}`);
|
|
499
|
+
* ```
|
|
500
|
+
*/
|
|
501
|
+
getKey(keyId: string): Promise<KeyMetadata>;
|
|
502
|
+
/**
|
|
503
|
+
* Revoke an API key.
|
|
504
|
+
* @param keyId - The key ID to revoke
|
|
505
|
+
* @param reason - Optional reason for revocation
|
|
506
|
+
*
|
|
507
|
+
* @example
|
|
508
|
+
* ```typescript
|
|
509
|
+
* await client.revokeKey('key-123', 'No longer needed');
|
|
510
|
+
* ```
|
|
511
|
+
*/
|
|
512
|
+
revokeKey(keyId: string, reason?: string): Promise<void>;
|
|
513
|
+
/**
|
|
514
|
+
* Delete a revoked API key permanently.
|
|
515
|
+
* Only revoked keys can be deleted - active keys must be revoked first.
|
|
516
|
+
* @param keyId - The key ID to delete
|
|
517
|
+
*
|
|
518
|
+
* @example
|
|
519
|
+
* ```typescript
|
|
520
|
+
* await client.deleteKey('key-123');
|
|
521
|
+
* ```
|
|
522
|
+
*/
|
|
523
|
+
deleteKey(keyId: string): Promise<void>;
|
|
524
|
+
/**
|
|
525
|
+
* Rotate an API key (revokes old key and creates new one).
|
|
526
|
+
* @param keyId - The key ID to rotate
|
|
527
|
+
* @returns Promise resolving to the new key metadata and API key string
|
|
528
|
+
*
|
|
529
|
+
* @example
|
|
530
|
+
* ```typescript
|
|
531
|
+
* const result = await client.rotateKey('key-123');
|
|
532
|
+
* console.log('New API Key:', result.apiKey);
|
|
533
|
+
* ```
|
|
534
|
+
*/
|
|
535
|
+
rotateKey(keyId: string): Promise<CreateKeyResult>;
|
|
536
|
+
/**
|
|
537
|
+
* Expose a center service into a group namespace.
|
|
538
|
+
* Edges in the group can call this service.
|
|
539
|
+
* Subscribes on: center.{appId}.group.{groupId}.services.{name}.>
|
|
540
|
+
*/
|
|
541
|
+
exposeToGroup(groupId: string, handler: ServiceHandler): Promise<Subscription>;
|
|
542
|
+
/**
|
|
543
|
+
* Call a specific edge's service within a group.
|
|
544
|
+
* Publishes to: edge.{appId}.group.{groupId}.{edgeId}.services.{service}.{method}
|
|
545
|
+
*/
|
|
546
|
+
callGroup<Req, Resp>(groupId: string, edgeId: string, service: string, method: string, req: Req, opts?: CallOptions): Promise<Resp>;
|
|
547
|
+
/**
|
|
548
|
+
* Scatter call to all edges in a group.
|
|
549
|
+
* Discovers edges in the group, then calls each via directed subject in parallel.
|
|
550
|
+
* Returns a map of edgeID → response data.
|
|
551
|
+
*/
|
|
552
|
+
scatterGroup<Req, Resp>(groupId: string, service: string, method: string, req: Req, opts?: CallOptions): Promise<Record<string, Resp>>;
|
|
553
|
+
/**
|
|
554
|
+
* Helper to parse key metadata from API response.
|
|
555
|
+
*/
|
|
556
|
+
private parseKeyMetadata;
|
|
557
|
+
/**
|
|
558
|
+
* Internal helper to format ServiceDescriptors as llm.txt.
|
|
559
|
+
*/
|
|
560
|
+
private formatAsLLMTxt;
|
|
561
|
+
/**
|
|
562
|
+
* Call an RPC method on any edge exposing the given service.
|
|
563
|
+
* Discovers an available edge first, then routes the call.
|
|
564
|
+
*/
|
|
565
|
+
callServiceRpc<Req, Resp>(service: string, method: string, req: Req, opts?: CallOptions & {
|
|
566
|
+
labels?: Record<string, string>;
|
|
567
|
+
}): Promise<Resp>;
|
|
568
|
+
/**
|
|
569
|
+
* List all services available in the mesh.
|
|
570
|
+
*/
|
|
571
|
+
listServices(): Promise<Array<{
|
|
572
|
+
name: string;
|
|
573
|
+
version?: string;
|
|
574
|
+
edgeCount: number;
|
|
575
|
+
}>>;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
export {};
|
package/dist/edge/client.d.ts
CHANGED
package/dist/edge/client.js
CHANGED
|
@@ -413,6 +413,7 @@ export class EdgeClient {
|
|
|
413
413
|
const nc = this.nc;
|
|
414
414
|
let inputSub = null;
|
|
415
415
|
let cancelSub = null;
|
|
416
|
+
let ctrlSub = null;
|
|
416
417
|
let open = true;
|
|
417
418
|
try {
|
|
418
419
|
// Parse the channel initiation message
|
|
@@ -424,6 +425,16 @@ export class EdgeClient {
|
|
|
424
425
|
if (channelPayload && typeof channelPayload === 'object' && 'payload' in channelPayload) {
|
|
425
426
|
channelPayload = channelPayload.payload || {};
|
|
426
427
|
}
|
|
428
|
+
// Generate channel ID from output subject
|
|
429
|
+
const channelId = 'ch_' + (outputSubject.split('.').pop() || outputSubject);
|
|
430
|
+
// Control message handlers
|
|
431
|
+
const controlHandlers = [];
|
|
432
|
+
// Backpressure tracking
|
|
433
|
+
let _bufferedAmount = 0;
|
|
434
|
+
const drainHandlers = [];
|
|
435
|
+
// Closed promise
|
|
436
|
+
let resolveClosed;
|
|
437
|
+
const closedPromise = new Promise((resolve) => { resolveClosed = resolve; });
|
|
427
438
|
const dataHandlers = [];
|
|
428
439
|
const closeHandlers = [];
|
|
429
440
|
const cleanup = (reason) => {
|
|
@@ -432,6 +443,8 @@ export class EdgeClient {
|
|
|
432
443
|
open = false;
|
|
433
444
|
inputSub?.unsubscribe();
|
|
434
445
|
cancelSub?.unsubscribe();
|
|
446
|
+
ctrlSub?.unsubscribe();
|
|
447
|
+
resolveClosed();
|
|
435
448
|
for (const h of closeHandlers) {
|
|
436
449
|
try {
|
|
437
450
|
h(reason);
|
|
@@ -460,16 +473,50 @@ export class EdgeClient {
|
|
|
460
473
|
cleanup('cancelled by client');
|
|
461
474
|
},
|
|
462
475
|
});
|
|
476
|
+
// Subscribe to control messages from browser
|
|
477
|
+
try {
|
|
478
|
+
ctrlSub = nc.subscribe(inputSubject + '.ctrl', {
|
|
479
|
+
callback: (_err, msg) => {
|
|
480
|
+
if (!open)
|
|
481
|
+
return;
|
|
482
|
+
try {
|
|
483
|
+
const parsed = JSON.parse(sc.decode(msg.data));
|
|
484
|
+
for (const h of controlHandlers) {
|
|
485
|
+
try {
|
|
486
|
+
h(parsed);
|
|
487
|
+
}
|
|
488
|
+
catch { /* ignore */ }
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
catch { /* ignore parse errors */ }
|
|
492
|
+
},
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
catch { /* ctrl subscription is optional */ }
|
|
463
496
|
// ACK the channel request
|
|
464
497
|
if (msg.reply) {
|
|
465
|
-
msg.respond(sc.encode(JSON.stringify({ status: 'channel', cancelSubject })));
|
|
498
|
+
msg.respond(sc.encode(JSON.stringify({ status: 'channel', cancelSubject, channelId })));
|
|
466
499
|
}
|
|
467
500
|
// Build the EdgeChannel object
|
|
468
501
|
const channel = {
|
|
502
|
+
get id() { return channelId; },
|
|
469
503
|
write(data) {
|
|
470
504
|
if (!open)
|
|
471
|
-
return;
|
|
505
|
+
return false;
|
|
472
506
|
nc.publish(outputSubject, data);
|
|
507
|
+
_bufferedAmount += data.byteLength;
|
|
508
|
+
queueMicrotask(() => {
|
|
509
|
+
_bufferedAmount = Math.max(0, _bufferedAmount - data.byteLength);
|
|
510
|
+
if (_bufferedAmount === 0) {
|
|
511
|
+
for (const h of drainHandlers) {
|
|
512
|
+
try {
|
|
513
|
+
h();
|
|
514
|
+
}
|
|
515
|
+
catch { /* ignore */ }
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
return true;
|
|
473
520
|
},
|
|
474
521
|
onData(handler) {
|
|
475
522
|
dataHandlers.push(handler);
|
|
@@ -483,9 +530,18 @@ export class EdgeClient {
|
|
|
483
530
|
onClose(handler) {
|
|
484
531
|
closeHandlers.push(handler);
|
|
485
532
|
},
|
|
486
|
-
|
|
487
|
-
|
|
533
|
+
sendControl(msg) {
|
|
534
|
+
if (!open)
|
|
535
|
+
return;
|
|
536
|
+
nc.publish(outputSubject + '.ctrl', sc.encode(JSON.stringify(msg)));
|
|
537
|
+
},
|
|
538
|
+
onControl(handler) {
|
|
539
|
+
controlHandlers.push(handler);
|
|
488
540
|
},
|
|
541
|
+
get isOpen() { return open; },
|
|
542
|
+
get closed() { return closedPromise; },
|
|
543
|
+
get bufferedAmount() { return _bufferedAmount; },
|
|
544
|
+
onDrain(handler) { drainHandlers.push(handler); },
|
|
489
545
|
};
|
|
490
546
|
// Call the handler — it may hold the channel open as long as it needs
|
|
491
547
|
await handler.handleChannel(method, channel, channelPayload);
|
|
@@ -503,6 +559,7 @@ export class EdgeClient {
|
|
|
503
559
|
finally {
|
|
504
560
|
inputSub?.unsubscribe();
|
|
505
561
|
cancelSub?.unsubscribe();
|
|
562
|
+
ctrlSub?.unsubscribe();
|
|
506
563
|
}
|
|
507
564
|
}
|
|
508
565
|
async unexposeService(name) {
|