@debros/network-ts-sdk 0.3.4 → 0.4.3

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 CHANGED
@@ -215,6 +215,55 @@ const topics = await client.pubsub.topics();
215
215
  console.log("Active topics:", topics);
216
216
  ```
217
217
 
218
+ ### Presence Support
219
+
220
+ The SDK supports real-time presence tracking, allowing you to see who is currently subscribed to a topic.
221
+
222
+ #### Subscribe with Presence
223
+
224
+ Enable presence by providing `presence` options in `subscribe`:
225
+
226
+ ```typescript
227
+ const subscription = await client.pubsub.subscribe("room.123", {
228
+ onMessage: (msg) => console.log("Message:", msg.data),
229
+ presence: {
230
+ enabled: true,
231
+ memberId: "user-alice",
232
+ meta: { displayName: "Alice", avatar: "URL" },
233
+ onJoin: (member) => {
234
+ console.log(`${member.memberId} joined at ${new Date(member.joinedAt)}`);
235
+ console.log("Meta:", member.meta);
236
+ },
237
+ onLeave: (member) => {
238
+ console.log(`${member.memberId} left`);
239
+ },
240
+ },
241
+ });
242
+ ```
243
+
244
+ #### Get Presence for a Topic
245
+
246
+ Query current members without subscribing:
247
+
248
+ ```typescript
249
+ const presence = await client.pubsub.getPresence("room.123");
250
+ console.log(`Total members: ${presence.count}`);
251
+ presence.members.forEach((member) => {
252
+ console.log(`- ${member.memberId} (joined: ${new Date(member.joinedAt)})`);
253
+ });
254
+ ```
255
+
256
+ #### Subscription Helpers
257
+
258
+ Get presence information from an active subscription:
259
+
260
+ ```typescript
261
+ if (subscription.hasPresence()) {
262
+ const members = await subscription.getPresence();
263
+ console.log("Current members:", members);
264
+ }
265
+ ```
266
+
218
267
  ### Authentication
219
268
 
220
269
  #### Switch API Key
package/dist/index.d.ts CHANGED
@@ -1,11 +1,45 @@
1
1
  import WebSocket from 'isomorphic-ws';
2
2
 
3
+ declare class SDKError extends Error {
4
+ readonly httpStatus: number;
5
+ readonly code: string;
6
+ readonly details: Record<string, any>;
7
+ constructor(message: string, httpStatus?: number, code?: string, details?: Record<string, any>);
8
+ static fromResponse(status: number, body: any, message?: string): SDKError;
9
+ toJSON(): {
10
+ name: string;
11
+ message: string;
12
+ httpStatus: number;
13
+ code: string;
14
+ details: Record<string, any>;
15
+ };
16
+ }
17
+
18
+ /**
19
+ * Context provided to the onNetworkError callback
20
+ */
21
+ interface NetworkErrorContext {
22
+ method: "GET" | "POST" | "PUT" | "DELETE" | "WS";
23
+ path: string;
24
+ isRetry: boolean;
25
+ attempt: number;
26
+ }
27
+ /**
28
+ * Callback invoked when a network error occurs.
29
+ * Use this to trigger gateway failover or other error handling.
30
+ */
31
+ type NetworkErrorCallback = (error: SDKError, context: NetworkErrorContext) => void;
3
32
  interface HttpClientConfig {
4
33
  baseURL: string;
5
34
  timeout?: number;
6
35
  maxRetries?: number;
7
36
  retryDelayMs?: number;
8
37
  fetch?: typeof fetch;
38
+ /**
39
+ * Callback invoked on network errors (after all retries exhausted).
40
+ * Use this to trigger gateway failover at the application layer.
41
+ */
42
+ onNetworkError?: NetworkErrorCallback;
9
43
  }
10
44
  declare class HttpClient {
11
45
  private baseURL;
@@ -15,12 +49,21 @@ declare class HttpClient {
15
49
  private fetch;
16
50
  private apiKey?;
17
51
  private jwt?;
52
+ private onNetworkError?;
18
53
  constructor(config: HttpClientConfig);
54
+ /**
55
+ * Set the network error callback
56
+ */
57
+ setOnNetworkError(callback: NetworkErrorCallback | undefined): void;
19
58
  setApiKey(apiKey?: string): void;
20
59
  setJwt(jwt?: string): void;
21
60
  private getAuthHeaders;
22
61
  private getAuthToken;
23
62
  getApiKey(): string | undefined;
63
+ /**
64
+ * Get the base URL
65
+ */
66
+ getBaseURL(): string;
24
67
  request<T = any>(method: "GET" | "POST" | "PUT" | "DELETE", path: string, options?: {
25
68
  body?: any;
26
69
  headers?: Record<string, string>;
@@ -283,6 +326,11 @@ interface WSClientConfig {
283
326
  timeout?: number;
284
327
  authToken?: string;
285
328
  WebSocket?: typeof WebSocket;
329
+ /**
330
+ * Callback invoked on WebSocket errors.
331
+ * Use this to trigger gateway failover at the application layer.
332
+ */
333
+ onNetworkError?: NetworkErrorCallback;
286
334
  }
287
335
  type WSMessageHandler = (data: string) => void;
288
336
  type WSErrorHandler = (error: Error) => void;
@@ -290,13 +338,15 @@ type WSCloseHandler = () => void;
290
338
  type WSOpenHandler = () => void;
291
339
  /**
292
340
  * Simple WebSocket client with minimal abstractions
293
- * No complex reconnection, no heartbeats - keep it simple
341
+ * No complex reconnection, no failover - keep it simple
342
+ * Gateway failover is handled at the application layer
294
343
  */
295
344
  declare class WSClient {
296
- private url;
345
+ private wsURL;
297
346
  private timeout;
298
347
  private authToken?;
299
348
  private WebSocketClass;
349
+ private onNetworkError?;
300
350
  private ws?;
301
351
  private messageHandlers;
302
352
  private errorHandlers;
@@ -304,6 +354,14 @@ declare class WSClient {
304
354
  private openHandlers;
305
355
  private isClosed;
306
356
  constructor(config: WSClientConfig);
357
+ /**
358
+ * Set the network error callback
359
+ */
360
+ setOnNetworkError(callback: NetworkErrorCallback | undefined): void;
361
+ /**
362
+ * Get the current WebSocket URL
363
+ */
364
+ get url(): string;
307
365
  /**
308
366
  * Connect to WebSocket server
309
367
  */
@@ -358,17 +416,41 @@ declare class WSClient {
358
416
  setAuthToken(token?: string): void;
359
417
  }
360
418
 
361
- interface Message {
419
+ interface PubSubMessage {
362
420
  data: string;
363
421
  topic: string;
364
422
  timestamp: number;
365
423
  }
366
- type MessageHandler = (message: Message) => void;
424
+ interface PresenceMember {
425
+ memberId: string;
426
+ joinedAt: number;
427
+ meta?: Record<string, unknown>;
428
+ }
429
+ interface PresenceResponse {
430
+ topic: string;
431
+ members: PresenceMember[];
432
+ count: number;
433
+ }
434
+ interface PresenceOptions {
435
+ enabled: boolean;
436
+ memberId: string;
437
+ meta?: Record<string, unknown>;
438
+ onJoin?: (member: PresenceMember) => void;
439
+ onLeave?: (member: PresenceMember) => void;
440
+ }
441
+ interface SubscribeOptions {
442
+ onMessage?: MessageHandler;
443
+ onError?: ErrorHandler;
444
+ onClose?: CloseHandler;
445
+ presence?: PresenceOptions;
446
+ }
447
+ type MessageHandler = (message: PubSubMessage) => void;
367
448
  type ErrorHandler = (error: Error) => void;
368
449
  type CloseHandler = () => void;
450
+
369
451
  /**
370
452
  * Simple PubSub client - one WebSocket connection per topic
371
- * No connection pooling, no reference counting - keep it simple
453
+ * Gateway failover is handled at the application layer
372
454
  */
373
455
  declare class PubSubClient {
374
456
  private httpClient;
@@ -382,15 +464,15 @@ declare class PubSubClient {
382
464
  * List active topics in the current namespace
383
465
  */
384
466
  topics(): Promise<string[]>;
467
+ /**
468
+ * Get current presence for a topic without subscribing
469
+ */
470
+ getPresence(topic: string): Promise<PresenceResponse>;
385
471
  /**
386
472
  * Subscribe to a topic via WebSocket
387
473
  * Creates one WebSocket connection per topic
388
474
  */
389
- subscribe(topic: string, handlers?: {
390
- onMessage?: MessageHandler;
391
- onError?: ErrorHandler;
392
- onClose?: CloseHandler;
393
- }): Promise<Subscription>;
475
+ subscribe(topic: string, options?: SubscribeOptions): Promise<Subscription>;
394
476
  }
395
477
  /**
396
478
  * Subscription represents an active WebSocket subscription to a topic
@@ -398,6 +480,7 @@ declare class PubSubClient {
398
480
  declare class Subscription {
399
481
  private wsClient;
400
482
  private topic;
483
+ private presenceOptions?;
401
484
  private messageHandlers;
402
485
  private errorHandlers;
403
486
  private closeHandlers;
@@ -405,7 +488,16 @@ declare class Subscription {
405
488
  private wsMessageHandler;
406
489
  private wsErrorHandler;
407
490
  private wsCloseHandler;
408
- constructor(wsClient: WSClient, topic: string);
491
+ private getPresenceFn;
492
+ constructor(wsClient: WSClient, topic: string, presenceOptions: PresenceOptions | undefined, getPresenceFn: () => Promise<PresenceResponse>);
493
+ /**
494
+ * Get current presence (requires presence.enabled on subscribe)
495
+ */
496
+ getPresence(): Promise<PresenceMember[]>;
497
+ /**
498
+ * Check if presence is enabled for this subscription
499
+ */
500
+ hasPresence(): boolean;
409
501
  /**
410
502
  * Register message handler
411
503
  */
@@ -695,27 +787,69 @@ declare class StorageClient {
695
787
  unpin(cid: string): Promise<void>;
696
788
  }
697
789
 
698
- declare class SDKError extends Error {
699
- readonly httpStatus: number;
700
- readonly code: string;
701
- readonly details: Record<string, any>;
702
- constructor(message: string, httpStatus?: number, code?: string, details?: Record<string, any>);
703
- static fromResponse(status: number, body: any, message?: string): SDKError;
704
- toJSON(): {
705
- name: string;
706
- message: string;
707
- httpStatus: number;
708
- code: string;
709
- details: Record<string, any>;
710
- };
790
+ /**
791
+ * Functions Client
792
+ * Client for calling serverless functions on the Orama Network
793
+ */
794
+
795
+ interface FunctionsClientConfig {
796
+ /**
797
+ * Base URL for the functions gateway
798
+ * Defaults to using the same baseURL as the HTTP client
799
+ */
800
+ gatewayURL?: string;
801
+ /**
802
+ * Namespace for the functions
803
+ */
804
+ namespace: string;
805
+ }
806
+ declare class FunctionsClient {
807
+ private httpClient;
808
+ private gatewayURL?;
809
+ private namespace;
810
+ constructor(httpClient: HttpClient, config?: FunctionsClientConfig);
811
+ /**
812
+ * Invoke a serverless function by name
813
+ *
814
+ * @param functionName - Name of the function to invoke
815
+ * @param input - Input payload for the function
816
+ * @returns The function response
817
+ */
818
+ invoke<TInput = any, TOutput = any>(functionName: string, input: TInput): Promise<TOutput>;
819
+ }
820
+
821
+ /**
822
+ * Serverless Functions Types
823
+ * Type definitions for calling serverless functions on the Orama Network
824
+ */
825
+ /**
826
+ * Generic response from a serverless function
827
+ */
828
+ interface FunctionResponse<T = unknown> {
829
+ success: boolean;
830
+ error?: string;
831
+ data?: T;
832
+ }
833
+ /**
834
+ * Standard success/error response used by many functions
835
+ */
836
+ interface SuccessResponse {
837
+ success: boolean;
838
+ error?: string;
711
839
  }
712
840
 
713
841
  interface ClientConfig extends Omit<HttpClientConfig, "fetch"> {
714
842
  apiKey?: string;
715
843
  jwt?: string;
716
844
  storage?: StorageAdapter;
717
- wsConfig?: Partial<WSClientConfig>;
845
+ wsConfig?: Partial<Omit<WSClientConfig, "wsURL">>;
846
+ functionsConfig?: FunctionsClientConfig;
718
847
  fetch?: typeof fetch;
848
+ /**
849
+ * Callback invoked on network errors (HTTP and WebSocket).
850
+ * Use this to trigger gateway failover at the application layer.
851
+ */
852
+ onNetworkError?: NetworkErrorCallback;
719
853
  }
720
854
  interface Client {
721
855
  auth: AuthClient;
@@ -724,7 +858,8 @@ interface Client {
724
858
  network: NetworkClient;
725
859
  cache: CacheClient;
726
860
  storage: StorageClient;
861
+ functions: FunctionsClient;
727
862
  }
728
863
  declare function createClient(config: ClientConfig): Client;
729
864
 
730
- export { AuthClient, type AuthConfig, CacheClient, type CacheDeleteRequest, type CacheDeleteResponse, type CacheGetRequest, type CacheGetResponse, type CacheHealthResponse, type CacheMultiGetRequest, type CacheMultiGetResponse, type CachePutRequest, type CachePutResponse, type CacheScanRequest, type CacheScanResponse, type Client, type ClientConfig, type CloseHandler, type ColumnDefinition, DBClient, type Entity, type ErrorHandler, type FindOptions, HttpClient, LocalStorageAdapter, MemoryStorage, type Message, type MessageHandler, NetworkClient, type NetworkStatus, type PeerInfo, type ProxyRequest, type ProxyResponse, PubSubClient, QueryBuilder, type QueryResponse, Repository, SDKError, type SelectOptions, type StorageAdapter, StorageClient, type StoragePinRequest, type StoragePinResponse, type StorageStatus, type StorageUploadResponse, Subscription, type TransactionOp, type TransactionRequest, WSClient, type WhoAmI, createClient, extractPrimaryKey, extractTableName };
865
+ export { AuthClient, type AuthConfig, CacheClient, type CacheDeleteRequest, type CacheDeleteResponse, type CacheGetRequest, type CacheGetResponse, type CacheHealthResponse, type CacheMultiGetRequest, type CacheMultiGetResponse, type CachePutRequest, type CachePutResponse, type CacheScanRequest, type CacheScanResponse, type Client, type ClientConfig, type CloseHandler, type ColumnDefinition, DBClient, type Entity, type ErrorHandler, type FindOptions, type FunctionResponse, FunctionsClient, type FunctionsClientConfig, HttpClient, LocalStorageAdapter, MemoryStorage, type MessageHandler, NetworkClient, type NetworkErrorCallback, type NetworkErrorContext, type NetworkStatus, type PeerInfo, type PresenceMember, type PresenceOptions, type PresenceResponse, type ProxyRequest, type ProxyResponse, PubSubClient, type PubSubMessage, QueryBuilder, type QueryResponse, Repository, SDKError, type SelectOptions, type StorageAdapter, StorageClient, type StoragePinRequest, type StoragePinResponse, type StorageStatus, type StorageUploadResponse, type SubscribeOptions, Subscription, type SuccessResponse, type TransactionOp, type TransactionRequest, WSClient, type WhoAmI, createClient, extractPrimaryKey, extractTableName };