wakz-sdk 1.0.0

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.
Files changed (56) hide show
  1. package/README.md +264 -0
  2. package/dist/client.d.ts +124 -0
  3. package/dist/client.d.ts.map +1 -0
  4. package/dist/client.js +323 -0
  5. package/dist/client.js.map +1 -0
  6. package/dist/crypto.d.ts +26 -0
  7. package/dist/crypto.d.ts.map +1 -0
  8. package/dist/crypto.js +161 -0
  9. package/dist/crypto.js.map +1 -0
  10. package/dist/esm/client.js.map +1 -0
  11. package/dist/esm/client.mjs +319 -0
  12. package/dist/esm/crypto.js.map +1 -0
  13. package/dist/esm/crypto.mjs +123 -0
  14. package/dist/esm/events.js.map +1 -0
  15. package/dist/esm/events.mjs +100 -0
  16. package/dist/esm/http.js.map +1 -0
  17. package/dist/esm/http.mjs +159 -0
  18. package/dist/esm/index.js.map +1 -0
  19. package/dist/esm/index.mjs +32 -0
  20. package/dist/esm/session.js.map +1 -0
  21. package/dist/esm/session.mjs +186 -0
  22. package/dist/esm/types.js.map +1 -0
  23. package/dist/esm/types.mjs +5 -0
  24. package/dist/esm/utils.js.map +1 -0
  25. package/dist/esm/utils.mjs +139 -0
  26. package/dist/esm/websocket.js.map +1 -0
  27. package/dist/esm/websocket.mjs +363 -0
  28. package/dist/events.d.ts +38 -0
  29. package/dist/events.d.ts.map +1 -0
  30. package/dist/events.js +104 -0
  31. package/dist/events.js.map +1 -0
  32. package/dist/http.d.ts +37 -0
  33. package/dist/http.d.ts.map +1 -0
  34. package/dist/http.js +163 -0
  35. package/dist/http.js.map +1 -0
  36. package/dist/index.d.ts +27 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +49 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/session.d.ts +75 -0
  41. package/dist/session.d.ts.map +1 -0
  42. package/dist/session.js +190 -0
  43. package/dist/session.js.map +1 -0
  44. package/dist/types.d.ts +149 -0
  45. package/dist/types.d.ts.map +1 -0
  46. package/dist/types.js +6 -0
  47. package/dist/types.js.map +1 -0
  48. package/dist/utils.d.ts +56 -0
  49. package/dist/utils.d.ts.map +1 -0
  50. package/dist/utils.js +153 -0
  51. package/dist/utils.js.map +1 -0
  52. package/dist/websocket.d.ts +93 -0
  53. package/dist/websocket.d.ts.map +1 -0
  54. package/dist/websocket.js +367 -0
  55. package/dist/websocket.js.map +1 -0
  56. package/package.json +50 -0
@@ -0,0 +1,363 @@
1
+ // ═══════════════════════════════════════════════════════════════
2
+ // WAKZ SDK — WebSocket Transport Manager
3
+ // ═══════════════════════════════════════════════════════════════
4
+ import { WAKZEventEmitter } from './events';
5
+ import { calculateBackoff, sleep, nowISO, generateId, Logger } from './utils';
6
+ /**
7
+ * WebSocket transport manager with automatic reconnection.
8
+ * Handles connection lifecycle, message framing, and keep-alive.
9
+ */
10
+ export class WebSocketTransport extends WAKZEventEmitter {
11
+ // Re-export connected state
12
+ get isConnected() {
13
+ return this._isConnected && this.ws?.readyState === WebSocket.OPEN;
14
+ }
15
+ constructor(apiKey, wsUrl, options = {}) {
16
+ super();
17
+ this.ws = null;
18
+ this._isConnected = false;
19
+ this._isConnecting = false;
20
+ this._retryCount = 0;
21
+ this._isDestroyed = false;
22
+ this._reconnectTimer = null;
23
+ this._pingInterval = null;
24
+ this._messageQueue = [];
25
+ this._pendingRequests = new Map();
26
+ /**
27
+ * Handle WebSocket open event.
28
+ */
29
+ this.handleOpen = () => {
30
+ this._isConnecting = false;
31
+ this._isConnected = true;
32
+ this._retryCount = 0;
33
+ this.logger.debug('[WS] Connected');
34
+ this.emit('connected', undefined);
35
+ // Flush queued messages
36
+ this.flushMessageQueue();
37
+ // Start ping interval (every 30s)
38
+ this._pingInterval = setInterval(() => {
39
+ this.send({ type: 'ping', timestamp: nowISO() });
40
+ }, 30000);
41
+ };
42
+ /**
43
+ * Handle WebSocket close event.
44
+ */
45
+ this.handleClose = (event) => {
46
+ this._isConnected = false;
47
+ this._isConnecting = false;
48
+ this.clearPingInterval();
49
+ this.logger.debug('[WS] Closed:', event.code, event.reason);
50
+ this.emit('disconnected', { code: event.code, reason: event.reason });
51
+ // Auto-reconnect if enabled
52
+ if (this.autoReconnect && !this._isDestroyed) {
53
+ this.attemptReconnect();
54
+ }
55
+ };
56
+ /**
57
+ * Handle WebSocket error event.
58
+ */
59
+ this.handleError = (event) => {
60
+ this.logger.error('[WS] Error:', event);
61
+ this.emit('error', new Error('WebSocket error occurred'));
62
+ };
63
+ /**
64
+ * Handle incoming WebSocket message.
65
+ */
66
+ this.handleMessage = (event) => {
67
+ try {
68
+ const data = JSON.parse(String(event.data));
69
+ // Handle pong (keep-alive response)
70
+ if (data.type === 'pong')
71
+ return;
72
+ // Handle errors
73
+ if (data.type === 'error') {
74
+ this.emit('error', new Error(String(data.payload ?? 'Server error')));
75
+ // Resolve pending request with error
76
+ if (data.id && this._pendingRequests.has(data.id)) {
77
+ const pending = this._pendingRequests.get(data.id);
78
+ clearTimeout(pending.timer);
79
+ this._pendingRequests.delete(data.id);
80
+ pending.reject(new Error(String(data.payload ?? 'Server error')));
81
+ }
82
+ return;
83
+ }
84
+ // Handle message response
85
+ if (data.type === 'message' && data.id && this._pendingRequests.has(data.id)) {
86
+ const pending = this._pendingRequests.get(data.id);
87
+ clearTimeout(pending.timer);
88
+ this._pendingRequests.delete(data.id);
89
+ const msg = {
90
+ id: data.id,
91
+ role: 'assistant',
92
+ content: data.payload?.content
93
+ || String(data.payload ?? ''),
94
+ timestamp: data.timestamp || nowISO(),
95
+ };
96
+ pending.resolve(msg);
97
+ this.emit('message', msg);
98
+ return;
99
+ }
100
+ // Handle session events
101
+ if (data.type === 'session') {
102
+ this.logger.debug('[WS] Session event:', data.payload);
103
+ return;
104
+ }
105
+ // Handle unsolicited messages (server push)
106
+ if (data.type === 'message') {
107
+ const msg = {
108
+ id: data.id || generateId('msg'),
109
+ role: data.payload?.role || 'assistant',
110
+ content: data.payload?.content || String(data.payload ?? ''),
111
+ timestamp: data.timestamp || nowISO(),
112
+ };
113
+ this.emit('message', msg);
114
+ }
115
+ }
116
+ catch (err) {
117
+ this.logger.error('[WS] Failed to parse message:', err);
118
+ }
119
+ };
120
+ this.apiKey = apiKey;
121
+ this.wsUrl = wsUrl;
122
+ this.autoReconnect = options.autoReconnect ?? true;
123
+ this.maxRetries = options.maxRetries ?? 5;
124
+ this.initialRetryDelay = options.initialRetryDelay ?? 1000;
125
+ this.maxRetryDelay = options.maxRetryDelay ?? 30000;
126
+ this.logger = new Logger(options.debug ?? false);
127
+ }
128
+ /**
129
+ * Connect to the WebSocket server.
130
+ */
131
+ async connect() {
132
+ if (this._isConnecting || this.isConnected)
133
+ return;
134
+ if (this._isDestroyed)
135
+ throw new Error('Transport is destroyed');
136
+ this._isConnecting = true;
137
+ this.logger.debug('[WS] Connecting to:', this.wsUrl);
138
+ try {
139
+ this.ws = this.createWebSocket();
140
+ await this.waitForConnection();
141
+ }
142
+ catch (err) {
143
+ this._isConnecting = false;
144
+ this.logger.error('[WS] Connection failed:', err);
145
+ throw err;
146
+ }
147
+ }
148
+ /**
149
+ * Send a message through the WebSocket.
150
+ */
151
+ async sendMessage(content, sessionId, visitorId) {
152
+ const envelope = {
153
+ type: 'message',
154
+ id: generateId('req'),
155
+ timestamp: nowISO(),
156
+ payload: {
157
+ content,
158
+ role: 'user',
159
+ session_id: sessionId,
160
+ visitor_id: visitorId,
161
+ },
162
+ };
163
+ return new Promise((resolve, reject) => {
164
+ // If not connected, queue the message
165
+ if (!this.isConnected) {
166
+ this._messageQueue.push(envelope);
167
+ reject(new Error('WebSocket not connected. Message queued.'));
168
+ return;
169
+ }
170
+ // Set up response timeout (30s)
171
+ const timer = setTimeout(() => {
172
+ this._pendingRequests.delete(envelope.id);
173
+ reject(new Error('Response timeout'));
174
+ }, 30000);
175
+ this._pendingRequests.set(envelope.id, {
176
+ resolve: resolve,
177
+ reject,
178
+ timer,
179
+ });
180
+ this.send(envelope);
181
+ });
182
+ }
183
+ /**
184
+ * Disconnect from the WebSocket server.
185
+ */
186
+ disconnect(code = 1000, reason = 'Client disconnect') {
187
+ this._isDestroyed = true;
188
+ this._isConnecting = false;
189
+ this.clearTimers();
190
+ if (this.ws) {
191
+ try {
192
+ this.ws.close(code, reason);
193
+ }
194
+ catch {
195
+ // Already closed
196
+ }
197
+ this.ws = null;
198
+ }
199
+ this._isConnected = false;
200
+ this.logger.debug('[WS] Disconnected');
201
+ this.emit('disconnected', { code, reason });
202
+ }
203
+ /**
204
+ * Create a WebSocket instance (handles browser vs Node.js).
205
+ */
206
+ createWebSocket() {
207
+ // Build authenticated URL
208
+ const url = new URL(this.wsUrl);
209
+ url.searchParams.set('api_key', this.apiKey);
210
+ let ws;
211
+ if (typeof WebSocket !== 'undefined') {
212
+ // Browser WebSocket
213
+ ws = new WebSocket(url.toString());
214
+ }
215
+ else {
216
+ // Node.js — try to use ws package
217
+ try {
218
+ const WS = require('ws');
219
+ ws = new WS(url.toString());
220
+ }
221
+ catch {
222
+ throw new Error('[WAKZ SDK] WebSocket not available. Install "ws" package for Node.js, or use HTTP transport.');
223
+ }
224
+ }
225
+ ws.onopen = this.handleOpen;
226
+ ws.onclose = this.handleClose;
227
+ ws.onerror = this.handleError;
228
+ ws.onmessage = this.handleMessage;
229
+ return ws;
230
+ }
231
+ /**
232
+ * Wait for the WebSocket to open.
233
+ */
234
+ waitForConnection() {
235
+ return new Promise((resolve, reject) => {
236
+ const timeout = setTimeout(() => {
237
+ reject(new Error('WebSocket connection timeout'));
238
+ }, 15000);
239
+ const ws = this.ws;
240
+ const onOpen = () => {
241
+ clearTimeout(timeout);
242
+ ws.removeEventListener('open', onOpen);
243
+ ws.removeEventListener('error', onError);
244
+ resolve();
245
+ };
246
+ const onError = (event) => {
247
+ clearTimeout(timeout);
248
+ ws.removeEventListener('open', onOpen);
249
+ ws.removeEventListener('error', onError);
250
+ reject(new Error('WebSocket connection error'));
251
+ };
252
+ ws.addEventListener('open', onOpen);
253
+ ws.addEventListener('error', onError);
254
+ });
255
+ }
256
+ /**
257
+ * Attempt to reconnect with exponential backoff.
258
+ */
259
+ async attemptReconnect() {
260
+ if (this._retryCount >= this.maxRetries) {
261
+ this.logger.error('[WS] Max retries reached, giving up');
262
+ this.emit('reconnect_failed', { reason: 'Max retries exceeded' });
263
+ return;
264
+ }
265
+ const delay = calculateBackoff(this._retryCount, this.initialRetryDelay, this.maxRetryDelay);
266
+ this._retryCount++;
267
+ this.logger.debug(`[WS] Reconnecting in ${Math.round(delay)}ms (attempt ${this._retryCount}/${this.maxRetries})`);
268
+ this.emit('reconnecting', { attempt: this._retryCount, delay });
269
+ await sleep(delay);
270
+ if (this._isDestroyed)
271
+ return;
272
+ try {
273
+ this._isConnecting = true;
274
+ this.ws = this.createWebSocket();
275
+ await this.waitForConnection();
276
+ }
277
+ catch (err) {
278
+ this.logger.error('[WS] Reconnect attempt failed:', err);
279
+ this.attemptReconnect(); // Recursive retry
280
+ }
281
+ }
282
+ /**
283
+ * Flush queued messages after reconnection.
284
+ */
285
+ flushMessageQueue() {
286
+ while (this._messageQueue.length > 0 && this.isConnected) {
287
+ const envelope = this._messageQueue.shift();
288
+ this.send(envelope);
289
+ }
290
+ }
291
+ /**
292
+ * Send a raw envelope through the WebSocket.
293
+ */
294
+ send(envelope) {
295
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
296
+ this._messageQueue.push(envelope);
297
+ return;
298
+ }
299
+ try {
300
+ this.ws.send(JSON.stringify(envelope));
301
+ }
302
+ catch (err) {
303
+ this.logger.error('[WS] Send error:', err);
304
+ this._messageQueue.push(envelope);
305
+ }
306
+ }
307
+ /**
308
+ * Perform a health check via WebSocket.
309
+ */
310
+ async healthCheck() {
311
+ const startTime = Date.now();
312
+ try {
313
+ if (!this.isConnected) {
314
+ return { healthy: false, latency: 0 };
315
+ }
316
+ return new Promise((resolve) => {
317
+ const envelope = {
318
+ type: 'ping',
319
+ id: generateId('hc'),
320
+ timestamp: nowISO(),
321
+ };
322
+ const timer = setTimeout(() => {
323
+ resolve({ healthy: false, latency: Date.now() - startTime });
324
+ }, 5000);
325
+ const handler = () => {
326
+ clearTimeout(timer);
327
+ this.off('message', handler);
328
+ resolve({ healthy: true, latency: Date.now() - startTime });
329
+ };
330
+ this.on('message', handler);
331
+ this.send(envelope);
332
+ });
333
+ }
334
+ catch {
335
+ return { healthy: false, latency: Date.now() - startTime };
336
+ }
337
+ }
338
+ /**
339
+ * Clear all timers.
340
+ */
341
+ clearTimers() {
342
+ this.clearPingInterval();
343
+ if (this._reconnectTimer) {
344
+ clearTimeout(this._reconnectTimer);
345
+ this._reconnectTimer = null;
346
+ }
347
+ // Clear pending request timeouts
348
+ for (const [, pending] of this._pendingRequests) {
349
+ clearTimeout(pending.timer);
350
+ }
351
+ this._pendingRequests.clear();
352
+ }
353
+ /**
354
+ * Clear the ping interval.
355
+ */
356
+ clearPingInterval() {
357
+ if (this._pingInterval) {
358
+ clearInterval(this._pingInterval);
359
+ this._pingInterval = null;
360
+ }
361
+ }
362
+ }
363
+ //# sourceMappingURL=websocket.js.map
@@ -0,0 +1,38 @@
1
+ import type { WAKZEventType, WAKZEventMap, WAKZEventCallback } from './types';
2
+ /**
3
+ * Lightweight typed event emitter for the WAKZ SDK.
4
+ * Zero external dependencies.
5
+ */
6
+ export declare class WAKZEventEmitter {
7
+ private listeners;
8
+ private onceListeners;
9
+ /**
10
+ * Register an event listener.
11
+ */
12
+ on<K extends WAKZEventType>(event: K, callback: WAKZEventCallback<WAKZEventMap[K]>): this;
13
+ /**
14
+ * Register a one-time event listener (auto-removes after first call).
15
+ */
16
+ once<K extends WAKZEventType>(event: K, callback: WAKZEventCallback<WAKZEventMap[K]>): this;
17
+ /**
18
+ * Remove a specific event listener.
19
+ */
20
+ off<K extends WAKZEventType>(event: K, callback: WAKZEventCallback<WAKZEventMap[K]>): this;
21
+ /**
22
+ * Remove all listeners for a specific event, or all events if no event specified.
23
+ */
24
+ removeAllListeners(event?: WAKZEventType): this;
25
+ /**
26
+ * Emit an event to all registered listeners.
27
+ */
28
+ protected emit<K extends WAKZEventType>(event: K, data: WAKZEventMap[K]): void;
29
+ /**
30
+ * Get the count of listeners for a specific event.
31
+ */
32
+ listenerCount(event: WAKZEventType): number;
33
+ /**
34
+ * Destroy the emitter — remove all listeners.
35
+ */
36
+ destroy(): void;
37
+ }
38
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAI9E;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,aAAa,CAA0B;IAE/C;;OAEG;IACH,EAAE,CAAC,CAAC,SAAS,aAAa,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAQzF;;OAEG;IACH,IAAI,CAAC,CAAC,SAAS,aAAa,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAQ3F;;OAEG;IACH,GAAG,CAAC,CAAC,SAAS,aAAa,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAM1F;;OAEG;IACH,kBAAkB,CAAC,KAAK,CAAC,EAAE,aAAa,GAAG,IAAI;IAW/C;;OAEG;IACH,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,aAAa,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI;IA4B9E;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM;IAI3C;;OAEG;IACH,OAAO,IAAI,IAAI;CAIhB"}
package/dist/events.js ADDED
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ // ═══════════════════════════════════════════════════════════════
3
+ // WAKZ SDK — Event Emitter System
4
+ // ═══════════════════════════════════════════════════════════════
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.WAKZEventEmitter = void 0;
7
+ /**
8
+ * Lightweight typed event emitter for the WAKZ SDK.
9
+ * Zero external dependencies.
10
+ */
11
+ class WAKZEventEmitter {
12
+ constructor() {
13
+ this.listeners = new Map();
14
+ this.onceListeners = new Map();
15
+ }
16
+ /**
17
+ * Register an event listener.
18
+ */
19
+ on(event, callback) {
20
+ if (!this.listeners.has(event)) {
21
+ this.listeners.set(event, new Set());
22
+ }
23
+ this.listeners.get(event).add(callback);
24
+ return this;
25
+ }
26
+ /**
27
+ * Register a one-time event listener (auto-removes after first call).
28
+ */
29
+ once(event, callback) {
30
+ if (!this.onceListeners.has(event)) {
31
+ this.onceListeners.set(event, new Set());
32
+ }
33
+ this.onceListeners.get(event).add(callback);
34
+ return this;
35
+ }
36
+ /**
37
+ * Remove a specific event listener.
38
+ */
39
+ off(event, callback) {
40
+ this.listeners.get(event)?.delete(callback);
41
+ this.onceListeners.get(event)?.delete(callback);
42
+ return this;
43
+ }
44
+ /**
45
+ * Remove all listeners for a specific event, or all events if no event specified.
46
+ */
47
+ removeAllListeners(event) {
48
+ if (event) {
49
+ this.listeners.delete(event);
50
+ this.onceListeners.delete(event);
51
+ }
52
+ else {
53
+ this.listeners.clear();
54
+ this.onceListeners.clear();
55
+ }
56
+ return this;
57
+ }
58
+ /**
59
+ * Emit an event to all registered listeners.
60
+ */
61
+ emit(event, data) {
62
+ // Fire persistent listeners
63
+ const persistent = this.listeners.get(event);
64
+ if (persistent) {
65
+ for (const cb of persistent) {
66
+ try {
67
+ cb(data);
68
+ }
69
+ catch (err) {
70
+ // Prevent listener errors from breaking the emitter
71
+ console.error(`[WAKZ SDK] Error in "${event}" listener:`, err);
72
+ }
73
+ }
74
+ }
75
+ // Fire and consume once-listeners
76
+ const once = this.onceListeners.get(event);
77
+ if (once) {
78
+ for (const cb of once) {
79
+ try {
80
+ cb(data);
81
+ }
82
+ catch (err) {
83
+ console.error(`[WAKZ SDK] Error in "${event}" once-listener:`, err);
84
+ }
85
+ }
86
+ this.onceListeners.delete(event);
87
+ }
88
+ }
89
+ /**
90
+ * Get the count of listeners for a specific event.
91
+ */
92
+ listenerCount(event) {
93
+ return (this.listeners.get(event)?.size ?? 0) + (this.onceListeners.get(event)?.size ?? 0);
94
+ }
95
+ /**
96
+ * Destroy the emitter — remove all listeners.
97
+ */
98
+ destroy() {
99
+ this.listeners.clear();
100
+ this.onceListeners.clear();
101
+ }
102
+ }
103
+ exports.WAKZEventEmitter = WAKZEventEmitter;
104
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}
package/dist/http.d.ts ADDED
@@ -0,0 +1,37 @@
1
+ import type { SendMessageResponse, WidgetConfig, HealthCheckResult } from './types';
2
+ /**
3
+ * HTTP/REST fallback transport for environments where WebSocket is unavailable.
4
+ * All requests are signed with HMAC-SHA256 for secure authentication.
5
+ */
6
+ export declare class HttpTransport {
7
+ private baseUrl;
8
+ private apiKey;
9
+ private timeout;
10
+ private logger;
11
+ constructor(apiKey: string, baseUrl: string, timeout?: number, debug?: boolean);
12
+ /**
13
+ * Send a chat message via REST API.
14
+ */
15
+ sendMessage(content: string, sessionId?: string, visitorId?: string): Promise<SendMessageResponse>;
16
+ /**
17
+ * Fetch widget configuration.
18
+ */
19
+ fetchWidgetConfig(): Promise<WidgetConfig | null>;
20
+ /**
21
+ * Perform a health check against the API.
22
+ */
23
+ healthCheck(): Promise<HealthCheckResult>;
24
+ /**
25
+ * Get the current session from the server.
26
+ */
27
+ getSession(visitorId: string): Promise<{
28
+ id: string;
29
+ messageCount: number;
30
+ isActive: boolean;
31
+ } | null>;
32
+ /**
33
+ * Fetch with timeout support.
34
+ */
35
+ private fetchWithTimeout;
36
+ }
37
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,mBAAmB,EAEnB,YAAY,EACZ,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAIjB;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;gBAGrB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,MAAc,EACvB,KAAK,GAAE,OAAe;IAQxB;;OAEG;IACG,WAAW,CACf,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,mBAAmB,CAAC;IAiD/B;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAuBvD;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,iBAAiB,CAAC;IA2B/C;;OAEG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAC3C,EAAE,EAAE,MAAM,CAAC;QACX,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,OAAO,CAAC;KACnB,GAAG,IAAI,CAAC;IAkBT;;OAEG;YACW,gBAAgB;CAyB/B"}