@debros/network-ts-sdk 0.3.4 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -0
- package/dist/index.d.ts +109 -13
- package/dist/index.js +127 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/http.ts +21 -5
- package/src/core/ws.ts +14 -5
- package/src/functions/client.ts +62 -0
- package/src/functions/types.ts +21 -0
- package/src/index.ts +17 -7
- package/src/pubsub/client.ts +104 -31
- package/src/pubsub/types.ts +46 -0
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
|
@@ -21,6 +21,10 @@ declare class HttpClient {
|
|
|
21
21
|
private getAuthHeaders;
|
|
22
22
|
private getAuthToken;
|
|
23
23
|
getApiKey(): string | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Get the base URL
|
|
26
|
+
*/
|
|
27
|
+
getBaseURL(): string;
|
|
24
28
|
request<T = any>(method: "GET" | "POST" | "PUT" | "DELETE", path: string, options?: {
|
|
25
29
|
body?: any;
|
|
26
30
|
headers?: Record<string, string>;
|
|
@@ -290,10 +294,11 @@ type WSCloseHandler = () => void;
|
|
|
290
294
|
type WSOpenHandler = () => void;
|
|
291
295
|
/**
|
|
292
296
|
* Simple WebSocket client with minimal abstractions
|
|
293
|
-
* No complex reconnection, no
|
|
297
|
+
* No complex reconnection, no failover - keep it simple
|
|
298
|
+
* Gateway failover is handled at the application layer
|
|
294
299
|
*/
|
|
295
300
|
declare class WSClient {
|
|
296
|
-
private
|
|
301
|
+
private wsURL;
|
|
297
302
|
private timeout;
|
|
298
303
|
private authToken?;
|
|
299
304
|
private WebSocketClass;
|
|
@@ -304,6 +309,10 @@ declare class WSClient {
|
|
|
304
309
|
private openHandlers;
|
|
305
310
|
private isClosed;
|
|
306
311
|
constructor(config: WSClientConfig);
|
|
312
|
+
/**
|
|
313
|
+
* Get the current WebSocket URL
|
|
314
|
+
*/
|
|
315
|
+
get url(): string;
|
|
307
316
|
/**
|
|
308
317
|
* Connect to WebSocket server
|
|
309
318
|
*/
|
|
@@ -358,17 +367,41 @@ declare class WSClient {
|
|
|
358
367
|
setAuthToken(token?: string): void;
|
|
359
368
|
}
|
|
360
369
|
|
|
361
|
-
interface
|
|
370
|
+
interface PubSubMessage {
|
|
362
371
|
data: string;
|
|
363
372
|
topic: string;
|
|
364
373
|
timestamp: number;
|
|
365
374
|
}
|
|
366
|
-
|
|
375
|
+
interface PresenceMember {
|
|
376
|
+
memberId: string;
|
|
377
|
+
joinedAt: number;
|
|
378
|
+
meta?: Record<string, unknown>;
|
|
379
|
+
}
|
|
380
|
+
interface PresenceResponse {
|
|
381
|
+
topic: string;
|
|
382
|
+
members: PresenceMember[];
|
|
383
|
+
count: number;
|
|
384
|
+
}
|
|
385
|
+
interface PresenceOptions {
|
|
386
|
+
enabled: boolean;
|
|
387
|
+
memberId: string;
|
|
388
|
+
meta?: Record<string, unknown>;
|
|
389
|
+
onJoin?: (member: PresenceMember) => void;
|
|
390
|
+
onLeave?: (member: PresenceMember) => void;
|
|
391
|
+
}
|
|
392
|
+
interface SubscribeOptions {
|
|
393
|
+
onMessage?: MessageHandler;
|
|
394
|
+
onError?: ErrorHandler;
|
|
395
|
+
onClose?: CloseHandler;
|
|
396
|
+
presence?: PresenceOptions;
|
|
397
|
+
}
|
|
398
|
+
type MessageHandler = (message: PubSubMessage) => void;
|
|
367
399
|
type ErrorHandler = (error: Error) => void;
|
|
368
400
|
type CloseHandler = () => void;
|
|
401
|
+
|
|
369
402
|
/**
|
|
370
403
|
* Simple PubSub client - one WebSocket connection per topic
|
|
371
|
-
*
|
|
404
|
+
* Gateway failover is handled at the application layer
|
|
372
405
|
*/
|
|
373
406
|
declare class PubSubClient {
|
|
374
407
|
private httpClient;
|
|
@@ -382,15 +415,15 @@ declare class PubSubClient {
|
|
|
382
415
|
* List active topics in the current namespace
|
|
383
416
|
*/
|
|
384
417
|
topics(): Promise<string[]>;
|
|
418
|
+
/**
|
|
419
|
+
* Get current presence for a topic without subscribing
|
|
420
|
+
*/
|
|
421
|
+
getPresence(topic: string): Promise<PresenceResponse>;
|
|
385
422
|
/**
|
|
386
423
|
* Subscribe to a topic via WebSocket
|
|
387
424
|
* Creates one WebSocket connection per topic
|
|
388
425
|
*/
|
|
389
|
-
subscribe(topic: string,
|
|
390
|
-
onMessage?: MessageHandler;
|
|
391
|
-
onError?: ErrorHandler;
|
|
392
|
-
onClose?: CloseHandler;
|
|
393
|
-
}): Promise<Subscription>;
|
|
426
|
+
subscribe(topic: string, options?: SubscribeOptions): Promise<Subscription>;
|
|
394
427
|
}
|
|
395
428
|
/**
|
|
396
429
|
* Subscription represents an active WebSocket subscription to a topic
|
|
@@ -398,6 +431,7 @@ declare class PubSubClient {
|
|
|
398
431
|
declare class Subscription {
|
|
399
432
|
private wsClient;
|
|
400
433
|
private topic;
|
|
434
|
+
private presenceOptions?;
|
|
401
435
|
private messageHandlers;
|
|
402
436
|
private errorHandlers;
|
|
403
437
|
private closeHandlers;
|
|
@@ -405,7 +439,16 @@ declare class Subscription {
|
|
|
405
439
|
private wsMessageHandler;
|
|
406
440
|
private wsErrorHandler;
|
|
407
441
|
private wsCloseHandler;
|
|
408
|
-
|
|
442
|
+
private getPresenceFn;
|
|
443
|
+
constructor(wsClient: WSClient, topic: string, presenceOptions: PresenceOptions | undefined, getPresenceFn: () => Promise<PresenceResponse>);
|
|
444
|
+
/**
|
|
445
|
+
* Get current presence (requires presence.enabled on subscribe)
|
|
446
|
+
*/
|
|
447
|
+
getPresence(): Promise<PresenceMember[]>;
|
|
448
|
+
/**
|
|
449
|
+
* Check if presence is enabled for this subscription
|
|
450
|
+
*/
|
|
451
|
+
hasPresence(): boolean;
|
|
409
452
|
/**
|
|
410
453
|
* Register message handler
|
|
411
454
|
*/
|
|
@@ -695,6 +738,37 @@ declare class StorageClient {
|
|
|
695
738
|
unpin(cid: string): Promise<void>;
|
|
696
739
|
}
|
|
697
740
|
|
|
741
|
+
/**
|
|
742
|
+
* Functions Client
|
|
743
|
+
* Client for calling serverless functions on the Orama Network
|
|
744
|
+
*/
|
|
745
|
+
|
|
746
|
+
interface FunctionsClientConfig {
|
|
747
|
+
/**
|
|
748
|
+
* Base URL for the functions gateway
|
|
749
|
+
* Defaults to using the same baseURL as the HTTP client
|
|
750
|
+
*/
|
|
751
|
+
gatewayURL?: string;
|
|
752
|
+
/**
|
|
753
|
+
* Namespace for the functions
|
|
754
|
+
*/
|
|
755
|
+
namespace: string;
|
|
756
|
+
}
|
|
757
|
+
declare class FunctionsClient {
|
|
758
|
+
private httpClient;
|
|
759
|
+
private gatewayURL?;
|
|
760
|
+
private namespace;
|
|
761
|
+
constructor(httpClient: HttpClient, config?: FunctionsClientConfig);
|
|
762
|
+
/**
|
|
763
|
+
* Invoke a serverless function by name
|
|
764
|
+
*
|
|
765
|
+
* @param functionName - Name of the function to invoke
|
|
766
|
+
* @param input - Input payload for the function
|
|
767
|
+
* @returns The function response
|
|
768
|
+
*/
|
|
769
|
+
invoke<TInput = any, TOutput = any>(functionName: string, input: TInput): Promise<TOutput>;
|
|
770
|
+
}
|
|
771
|
+
|
|
698
772
|
declare class SDKError extends Error {
|
|
699
773
|
readonly httpStatus: number;
|
|
700
774
|
readonly code: string;
|
|
@@ -710,11 +784,32 @@ declare class SDKError extends Error {
|
|
|
710
784
|
};
|
|
711
785
|
}
|
|
712
786
|
|
|
787
|
+
/**
|
|
788
|
+
* Serverless Functions Types
|
|
789
|
+
* Type definitions for calling serverless functions on the Orama Network
|
|
790
|
+
*/
|
|
791
|
+
/**
|
|
792
|
+
* Generic response from a serverless function
|
|
793
|
+
*/
|
|
794
|
+
interface FunctionResponse<T = unknown> {
|
|
795
|
+
success: boolean;
|
|
796
|
+
error?: string;
|
|
797
|
+
data?: T;
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* Standard success/error response used by many functions
|
|
801
|
+
*/
|
|
802
|
+
interface SuccessResponse {
|
|
803
|
+
success: boolean;
|
|
804
|
+
error?: string;
|
|
805
|
+
}
|
|
806
|
+
|
|
713
807
|
interface ClientConfig extends Omit<HttpClientConfig, "fetch"> {
|
|
714
808
|
apiKey?: string;
|
|
715
809
|
jwt?: string;
|
|
716
810
|
storage?: StorageAdapter;
|
|
717
|
-
wsConfig?: Partial<WSClientConfig
|
|
811
|
+
wsConfig?: Partial<Omit<WSClientConfig, "wsURL">>;
|
|
812
|
+
functionsConfig?: FunctionsClientConfig;
|
|
718
813
|
fetch?: typeof fetch;
|
|
719
814
|
}
|
|
720
815
|
interface Client {
|
|
@@ -724,7 +819,8 @@ interface Client {
|
|
|
724
819
|
network: NetworkClient;
|
|
725
820
|
cache: CacheClient;
|
|
726
821
|
storage: StorageClient;
|
|
822
|
+
functions: FunctionsClient;
|
|
727
823
|
}
|
|
728
824
|
declare function createClient(config: ClientConfig): Client;
|
|
729
825
|
|
|
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
|
|
826
|
+
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 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 };
|
package/dist/index.js
CHANGED
|
@@ -91,6 +91,12 @@ var HttpClient = class {
|
|
|
91
91
|
getApiKey() {
|
|
92
92
|
return this.apiKey;
|
|
93
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Get the base URL
|
|
96
|
+
*/
|
|
97
|
+
getBaseURL() {
|
|
98
|
+
return this.baseURL;
|
|
99
|
+
}
|
|
94
100
|
async request(method, path, options = {}) {
|
|
95
101
|
const startTime = performance.now();
|
|
96
102
|
const url = new URL(this.baseURL + path);
|
|
@@ -212,7 +218,13 @@ var HttpClient = class {
|
|
|
212
218
|
}
|
|
213
219
|
return response.text();
|
|
214
220
|
} catch (error) {
|
|
215
|
-
|
|
221
|
+
const isRetryableError = error instanceof SDKError && [408, 429, 500, 502, 503, 504].includes(error.httpStatus);
|
|
222
|
+
if (isRetryableError && attempt < this.maxRetries) {
|
|
223
|
+
if (typeof console !== "undefined") {
|
|
224
|
+
console.warn(
|
|
225
|
+
`[HttpClient] Retrying request (attempt ${attempt + 1}/${this.maxRetries})`
|
|
226
|
+
);
|
|
227
|
+
}
|
|
216
228
|
await new Promise(
|
|
217
229
|
(resolve) => setTimeout(resolve, this.retryDelayMs * (attempt + 1))
|
|
218
230
|
);
|
|
@@ -798,11 +810,17 @@ var WSClient = class {
|
|
|
798
810
|
this.closeHandlers = /* @__PURE__ */ new Set();
|
|
799
811
|
this.openHandlers = /* @__PURE__ */ new Set();
|
|
800
812
|
this.isClosed = false;
|
|
801
|
-
this.
|
|
813
|
+
this.wsURL = config.wsURL;
|
|
802
814
|
this.timeout = config.timeout ?? 3e4;
|
|
803
815
|
this.authToken = config.authToken;
|
|
804
816
|
this.WebSocketClass = config.WebSocket ?? WebSocket;
|
|
805
817
|
}
|
|
818
|
+
/**
|
|
819
|
+
* Get the current WebSocket URL
|
|
820
|
+
*/
|
|
821
|
+
get url() {
|
|
822
|
+
return this.wsURL;
|
|
823
|
+
}
|
|
806
824
|
/**
|
|
807
825
|
* Connect to WebSocket server
|
|
808
826
|
*/
|
|
@@ -820,7 +838,7 @@ var WSClient = class {
|
|
|
820
838
|
}, this.timeout);
|
|
821
839
|
this.ws.addEventListener("open", () => {
|
|
822
840
|
clearTimeout(timeout);
|
|
823
|
-
console.log("[WSClient] Connected to", this.
|
|
841
|
+
console.log("[WSClient] Connected to", this.wsURL);
|
|
824
842
|
this.openHandlers.forEach((handler) => handler());
|
|
825
843
|
resolve();
|
|
826
844
|
});
|
|
@@ -833,6 +851,7 @@ var WSClient = class {
|
|
|
833
851
|
clearTimeout(timeout);
|
|
834
852
|
const error = new SDKError("WebSocket error", 500, "WS_ERROR", event);
|
|
835
853
|
this.errorHandlers.forEach((handler) => handler(error));
|
|
854
|
+
reject(error);
|
|
836
855
|
});
|
|
837
856
|
this.ws.addEventListener("close", () => {
|
|
838
857
|
clearTimeout(timeout);
|
|
@@ -848,7 +867,7 @@ var WSClient = class {
|
|
|
848
867
|
* Build WebSocket URL with auth token
|
|
849
868
|
*/
|
|
850
869
|
buildWSUrl() {
|
|
851
|
-
let url = this.
|
|
870
|
+
let url = this.wsURL;
|
|
852
871
|
if (this.authToken) {
|
|
853
872
|
const separator = url.includes("?") ? "&" : "?";
|
|
854
873
|
const paramName = this.authToken.startsWith("ak_") ? "api_key" : "token";
|
|
@@ -1009,14 +1028,32 @@ var PubSubClient = class {
|
|
|
1009
1028
|
);
|
|
1010
1029
|
return response.topics || [];
|
|
1011
1030
|
}
|
|
1031
|
+
/**
|
|
1032
|
+
* Get current presence for a topic without subscribing
|
|
1033
|
+
*/
|
|
1034
|
+
async getPresence(topic) {
|
|
1035
|
+
const response = await this.httpClient.get(
|
|
1036
|
+
`/v1/pubsub/presence?topic=${encodeURIComponent(topic)}`
|
|
1037
|
+
);
|
|
1038
|
+
return response;
|
|
1039
|
+
}
|
|
1012
1040
|
/**
|
|
1013
1041
|
* Subscribe to a topic via WebSocket
|
|
1014
1042
|
* Creates one WebSocket connection per topic
|
|
1015
1043
|
*/
|
|
1016
|
-
async subscribe(topic,
|
|
1044
|
+
async subscribe(topic, options = {}) {
|
|
1017
1045
|
const wsUrl = new URL(this.wsConfig.wsURL || "ws://127.0.0.1:6001");
|
|
1018
1046
|
wsUrl.pathname = "/v1/pubsub/ws";
|
|
1019
1047
|
wsUrl.searchParams.set("topic", topic);
|
|
1048
|
+
let presence;
|
|
1049
|
+
if (options.presence?.enabled) {
|
|
1050
|
+
presence = options.presence;
|
|
1051
|
+
wsUrl.searchParams.set("presence", "true");
|
|
1052
|
+
wsUrl.searchParams.set("member_id", presence.memberId);
|
|
1053
|
+
if (presence.meta) {
|
|
1054
|
+
wsUrl.searchParams.set("member_meta", JSON.stringify(presence.meta));
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1020
1057
|
const authToken = this.httpClient.getApiKey() ?? this.httpClient.getToken();
|
|
1021
1058
|
const wsClient = new WSClient({
|
|
1022
1059
|
...this.wsConfig,
|
|
@@ -1024,21 +1061,26 @@ var PubSubClient = class {
|
|
|
1024
1061
|
authToken
|
|
1025
1062
|
});
|
|
1026
1063
|
await wsClient.connect();
|
|
1027
|
-
const subscription = new Subscription(
|
|
1028
|
-
|
|
1029
|
-
|
|
1064
|
+
const subscription = new Subscription(
|
|
1065
|
+
wsClient,
|
|
1066
|
+
topic,
|
|
1067
|
+
presence,
|
|
1068
|
+
() => this.getPresence(topic)
|
|
1069
|
+
);
|
|
1070
|
+
if (options.onMessage) {
|
|
1071
|
+
subscription.onMessage(options.onMessage);
|
|
1030
1072
|
}
|
|
1031
|
-
if (
|
|
1032
|
-
subscription.onError(
|
|
1073
|
+
if (options.onError) {
|
|
1074
|
+
subscription.onError(options.onError);
|
|
1033
1075
|
}
|
|
1034
|
-
if (
|
|
1035
|
-
subscription.onClose(
|
|
1076
|
+
if (options.onClose) {
|
|
1077
|
+
subscription.onClose(options.onClose);
|
|
1036
1078
|
}
|
|
1037
1079
|
return subscription;
|
|
1038
1080
|
}
|
|
1039
1081
|
};
|
|
1040
1082
|
var Subscription = class {
|
|
1041
|
-
constructor(wsClient, topic) {
|
|
1083
|
+
constructor(wsClient, topic, presenceOptions, getPresenceFn) {
|
|
1042
1084
|
this.messageHandlers = /* @__PURE__ */ new Set();
|
|
1043
1085
|
this.errorHandlers = /* @__PURE__ */ new Set();
|
|
1044
1086
|
this.closeHandlers = /* @__PURE__ */ new Set();
|
|
@@ -1048,12 +1090,31 @@ var Subscription = class {
|
|
|
1048
1090
|
this.wsCloseHandler = null;
|
|
1049
1091
|
this.wsClient = wsClient;
|
|
1050
1092
|
this.topic = topic;
|
|
1093
|
+
this.presenceOptions = presenceOptions;
|
|
1094
|
+
this.getPresenceFn = getPresenceFn;
|
|
1051
1095
|
this.wsMessageHandler = (data) => {
|
|
1052
1096
|
try {
|
|
1053
1097
|
const envelope = JSON.parse(data);
|
|
1054
1098
|
if (!envelope || typeof envelope !== "object") {
|
|
1055
1099
|
throw new Error("Invalid envelope: not an object");
|
|
1056
1100
|
}
|
|
1101
|
+
if (envelope.type === "presence.join" || envelope.type === "presence.leave") {
|
|
1102
|
+
if (!envelope.member_id) {
|
|
1103
|
+
console.warn("[Subscription] Presence event missing member_id");
|
|
1104
|
+
return;
|
|
1105
|
+
}
|
|
1106
|
+
const presenceMember = {
|
|
1107
|
+
memberId: envelope.member_id,
|
|
1108
|
+
joinedAt: envelope.timestamp,
|
|
1109
|
+
meta: envelope.meta
|
|
1110
|
+
};
|
|
1111
|
+
if (envelope.type === "presence.join" && this.presenceOptions?.onJoin) {
|
|
1112
|
+
this.presenceOptions.onJoin(presenceMember);
|
|
1113
|
+
} else if (envelope.type === "presence.leave" && this.presenceOptions?.onLeave) {
|
|
1114
|
+
this.presenceOptions.onLeave(presenceMember);
|
|
1115
|
+
}
|
|
1116
|
+
return;
|
|
1117
|
+
}
|
|
1057
1118
|
if (!envelope.data || typeof envelope.data !== "string") {
|
|
1058
1119
|
throw new Error("Invalid envelope: missing or invalid data field");
|
|
1059
1120
|
}
|
|
@@ -1090,6 +1151,22 @@ var Subscription = class {
|
|
|
1090
1151
|
};
|
|
1091
1152
|
this.wsClient.onClose(this.wsCloseHandler);
|
|
1092
1153
|
}
|
|
1154
|
+
/**
|
|
1155
|
+
* Get current presence (requires presence.enabled on subscribe)
|
|
1156
|
+
*/
|
|
1157
|
+
async getPresence() {
|
|
1158
|
+
if (!this.presenceOptions?.enabled) {
|
|
1159
|
+
throw new Error("Presence is not enabled for this subscription");
|
|
1160
|
+
}
|
|
1161
|
+
const response = await this.getPresenceFn();
|
|
1162
|
+
return response.members;
|
|
1163
|
+
}
|
|
1164
|
+
/**
|
|
1165
|
+
* Check if presence is enabled for this subscription
|
|
1166
|
+
*/
|
|
1167
|
+
hasPresence() {
|
|
1168
|
+
return !!this.presenceOptions?.enabled;
|
|
1169
|
+
}
|
|
1093
1170
|
/**
|
|
1094
1171
|
* Register message handler
|
|
1095
1172
|
*/
|
|
@@ -1511,6 +1588,38 @@ var StorageClient = class {
|
|
|
1511
1588
|
}
|
|
1512
1589
|
};
|
|
1513
1590
|
|
|
1591
|
+
// src/functions/client.ts
|
|
1592
|
+
var FunctionsClient = class {
|
|
1593
|
+
constructor(httpClient, config) {
|
|
1594
|
+
this.httpClient = httpClient;
|
|
1595
|
+
this.gatewayURL = config?.gatewayURL;
|
|
1596
|
+
this.namespace = config?.namespace ?? "default";
|
|
1597
|
+
}
|
|
1598
|
+
/**
|
|
1599
|
+
* Invoke a serverless function by name
|
|
1600
|
+
*
|
|
1601
|
+
* @param functionName - Name of the function to invoke
|
|
1602
|
+
* @param input - Input payload for the function
|
|
1603
|
+
* @returns The function response
|
|
1604
|
+
*/
|
|
1605
|
+
async invoke(functionName, input) {
|
|
1606
|
+
const url = this.gatewayURL ? `${this.gatewayURL}/v1/invoke/${this.namespace}/${functionName}` : `/v1/invoke/${this.namespace}/${functionName}`;
|
|
1607
|
+
try {
|
|
1608
|
+
const response = await this.httpClient.post(url, input);
|
|
1609
|
+
return response;
|
|
1610
|
+
} catch (error) {
|
|
1611
|
+
if (error instanceof SDKError) {
|
|
1612
|
+
throw error;
|
|
1613
|
+
}
|
|
1614
|
+
throw new SDKError(
|
|
1615
|
+
`Function ${functionName} failed`,
|
|
1616
|
+
500,
|
|
1617
|
+
error instanceof Error ? error.message : String(error)
|
|
1618
|
+
);
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
};
|
|
1622
|
+
|
|
1514
1623
|
// src/index.ts
|
|
1515
1624
|
function createClient(config) {
|
|
1516
1625
|
const httpClient = new HttpClient({
|
|
@@ -1526,7 +1635,7 @@ function createClient(config) {
|
|
|
1526
1635
|
apiKey: config.apiKey,
|
|
1527
1636
|
jwt: config.jwt
|
|
1528
1637
|
});
|
|
1529
|
-
const wsURL = config.
|
|
1638
|
+
const wsURL = config.baseURL.replace(/^http/, "ws").replace(/\/$/, "");
|
|
1530
1639
|
const db = new DBClient(httpClient);
|
|
1531
1640
|
const pubsub = new PubSubClient(httpClient, {
|
|
1532
1641
|
...config.wsConfig,
|
|
@@ -1535,19 +1644,22 @@ function createClient(config) {
|
|
|
1535
1644
|
const network = new NetworkClient(httpClient);
|
|
1536
1645
|
const cache = new CacheClient(httpClient);
|
|
1537
1646
|
const storage = new StorageClient(httpClient);
|
|
1647
|
+
const functions = new FunctionsClient(httpClient, config.functionsConfig);
|
|
1538
1648
|
return {
|
|
1539
1649
|
auth,
|
|
1540
1650
|
db,
|
|
1541
1651
|
pubsub,
|
|
1542
1652
|
network,
|
|
1543
1653
|
cache,
|
|
1544
|
-
storage
|
|
1654
|
+
storage,
|
|
1655
|
+
functions
|
|
1545
1656
|
};
|
|
1546
1657
|
}
|
|
1547
1658
|
export {
|
|
1548
1659
|
AuthClient,
|
|
1549
1660
|
CacheClient,
|
|
1550
1661
|
DBClient,
|
|
1662
|
+
FunctionsClient,
|
|
1551
1663
|
HttpClient,
|
|
1552
1664
|
LocalStorageAdapter,
|
|
1553
1665
|
MemoryStorage,
|