@insforge/sdk 1.0.1-refresh.8 → 1.0.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/LICENSE +201 -201
- package/README.md +249 -249
- package/dist/index.d.mts +132 -78
- package/dist/index.d.ts +132 -78
- package/dist/index.js +273 -201
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +272 -201
- package/dist/index.mjs.map +1 -1
- package/package.json +68 -67
package/dist/index.js
CHANGED
|
@@ -27,6 +27,7 @@ __export(index_exports, {
|
|
|
27
27
|
HttpClient: () => HttpClient,
|
|
28
28
|
InsForgeClient: () => InsForgeClient,
|
|
29
29
|
InsForgeError: () => InsForgeError,
|
|
30
|
+
Realtime: () => Realtime,
|
|
30
31
|
Storage: () => Storage,
|
|
31
32
|
StorageBucket: () => StorageBucket,
|
|
32
33
|
TokenManager: () => TokenManager,
|
|
@@ -111,7 +112,6 @@ var HttpClient = class {
|
|
|
111
112
|
method,
|
|
112
113
|
headers: requestHeaders,
|
|
113
114
|
body: processedBody,
|
|
114
|
-
credentials: "include",
|
|
115
115
|
...fetchOptions
|
|
116
116
|
});
|
|
117
117
|
if (response.status === 204) {
|
|
@@ -176,29 +176,8 @@ var HttpClient = class {
|
|
|
176
176
|
// src/lib/token-manager.ts
|
|
177
177
|
var TOKEN_KEY = "insforge-auth-token";
|
|
178
178
|
var USER_KEY = "insforge-auth-user";
|
|
179
|
-
var AUTH_FLAG_COOKIE = "isAuthenticated";
|
|
180
|
-
function hasAuthCookie() {
|
|
181
|
-
if (typeof document === "undefined") return false;
|
|
182
|
-
return document.cookie.split(";").some(
|
|
183
|
-
(c) => c.trim().startsWith(`${AUTH_FLAG_COOKIE}=`)
|
|
184
|
-
);
|
|
185
|
-
}
|
|
186
|
-
function setAuthCookie() {
|
|
187
|
-
if (typeof document === "undefined") return;
|
|
188
|
-
const maxAge = 7 * 24 * 60 * 60;
|
|
189
|
-
document.cookie = `${AUTH_FLAG_COOKIE}=true; path=/; max-age=${maxAge}; SameSite=Lax`;
|
|
190
|
-
}
|
|
191
|
-
function clearAuthCookie() {
|
|
192
|
-
if (typeof document === "undefined") return;
|
|
193
|
-
document.cookie = `${AUTH_FLAG_COOKIE}=; path=/; max-age=0; SameSite=Lax`;
|
|
194
|
-
}
|
|
195
179
|
var TokenManager = class {
|
|
196
180
|
constructor(storage) {
|
|
197
|
-
// In-memory storage
|
|
198
|
-
this.accessToken = null;
|
|
199
|
-
this.user = null;
|
|
200
|
-
// Mode: 'memory' (new backend) or 'storage' (legacy backend, default)
|
|
201
|
-
this._mode = "storage";
|
|
202
181
|
if (storage) {
|
|
203
182
|
this.storage = storage;
|
|
204
183
|
} else if (typeof window !== "undefined" && window.localStorage) {
|
|
@@ -216,112 +195,32 @@ var TokenManager = class {
|
|
|
216
195
|
};
|
|
217
196
|
}
|
|
218
197
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
get mode() {
|
|
223
|
-
return this._mode;
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Set mode to memory (new backend with cookies + memory)
|
|
227
|
-
*/
|
|
228
|
-
setMemoryMode() {
|
|
229
|
-
if (this._mode === "storage") {
|
|
230
|
-
this.storage.removeItem(TOKEN_KEY);
|
|
231
|
-
this.storage.removeItem(USER_KEY);
|
|
232
|
-
}
|
|
233
|
-
this._mode = "memory";
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Set mode to storage (legacy backend with localStorage)
|
|
237
|
-
* Also loads existing session from localStorage
|
|
238
|
-
*/
|
|
239
|
-
setStorageMode() {
|
|
240
|
-
this._mode = "storage";
|
|
241
|
-
this.loadFromStorage();
|
|
198
|
+
saveSession(session) {
|
|
199
|
+
this.storage.setItem(TOKEN_KEY, session.accessToken);
|
|
200
|
+
this.storage.setItem(USER_KEY, JSON.stringify(session.user));
|
|
242
201
|
}
|
|
243
|
-
|
|
244
|
-
* Load session from localStorage
|
|
245
|
-
*/
|
|
246
|
-
loadFromStorage() {
|
|
202
|
+
getSession() {
|
|
247
203
|
const token = this.storage.getItem(TOKEN_KEY);
|
|
248
204
|
const userStr = this.storage.getItem(USER_KEY);
|
|
249
|
-
if (token
|
|
250
|
-
|
|
251
|
-
this.accessToken = token;
|
|
252
|
-
this.user = JSON.parse(userStr);
|
|
253
|
-
} catch {
|
|
254
|
-
this.clearSession();
|
|
255
|
-
}
|
|
205
|
+
if (!token || !userStr) {
|
|
206
|
+
return null;
|
|
256
207
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
this.user = session.user;
|
|
264
|
-
if (this._mode === "storage") {
|
|
265
|
-
this.storage.setItem(TOKEN_KEY, session.accessToken);
|
|
266
|
-
this.storage.setItem(USER_KEY, JSON.stringify(session.user));
|
|
208
|
+
try {
|
|
209
|
+
const user = JSON.parse(userStr);
|
|
210
|
+
return { accessToken: token, user };
|
|
211
|
+
} catch {
|
|
212
|
+
this.clearSession();
|
|
213
|
+
return null;
|
|
267
214
|
}
|
|
268
215
|
}
|
|
269
|
-
/**
|
|
270
|
-
* Get current session
|
|
271
|
-
*/
|
|
272
|
-
getSession() {
|
|
273
|
-
if (!this.accessToken || !this.user) return null;
|
|
274
|
-
return {
|
|
275
|
-
accessToken: this.accessToken,
|
|
276
|
-
user: this.user
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
/**
|
|
280
|
-
* Get access token
|
|
281
|
-
*/
|
|
282
216
|
getAccessToken() {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* Set access token
|
|
287
|
-
*/
|
|
288
|
-
setAccessToken(token) {
|
|
289
|
-
this.accessToken = token;
|
|
290
|
-
if (this._mode === "storage") {
|
|
291
|
-
this.storage.setItem(TOKEN_KEY, token);
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
/**
|
|
295
|
-
* Get user
|
|
296
|
-
*/
|
|
297
|
-
getUser() {
|
|
298
|
-
return this.user;
|
|
299
|
-
}
|
|
300
|
-
/**
|
|
301
|
-
* Set user
|
|
302
|
-
*/
|
|
303
|
-
setUser(user) {
|
|
304
|
-
this.user = user;
|
|
305
|
-
if (this._mode === "storage") {
|
|
306
|
-
this.storage.setItem(USER_KEY, JSON.stringify(user));
|
|
307
|
-
}
|
|
217
|
+
const token = this.storage.getItem(TOKEN_KEY);
|
|
218
|
+
return typeof token === "string" ? token : null;
|
|
308
219
|
}
|
|
309
|
-
/**
|
|
310
|
-
* Clear session (both memory and localStorage)
|
|
311
|
-
*/
|
|
312
220
|
clearSession() {
|
|
313
|
-
this.accessToken = null;
|
|
314
|
-
this.user = null;
|
|
315
221
|
this.storage.removeItem(TOKEN_KEY);
|
|
316
222
|
this.storage.removeItem(USER_KEY);
|
|
317
223
|
}
|
|
318
|
-
/**
|
|
319
|
-
* Check if there's a session in localStorage (for legacy detection)
|
|
320
|
-
*/
|
|
321
|
-
hasStoredSession() {
|
|
322
|
-
const token = this.storage.getItem(TOKEN_KEY);
|
|
323
|
-
return !!token;
|
|
324
|
-
}
|
|
325
224
|
};
|
|
326
225
|
|
|
327
226
|
// src/modules/database-postgrest.ts
|
|
@@ -436,71 +335,6 @@ var Auth = class {
|
|
|
436
335
|
this.database = new Database(http, tokenManager);
|
|
437
336
|
this.detectAuthCallback();
|
|
438
337
|
}
|
|
439
|
-
/**
|
|
440
|
-
* Restore session on app initialization
|
|
441
|
-
*
|
|
442
|
-
* @returns Object with isLoggedIn status
|
|
443
|
-
*
|
|
444
|
-
* @example
|
|
445
|
-
* ```typescript
|
|
446
|
-
* const client = new InsForgeClient({ baseUrl: '...' });
|
|
447
|
-
* const { isLoggedIn } = await client.auth.restoreSession();
|
|
448
|
-
*
|
|
449
|
-
* if (isLoggedIn) {
|
|
450
|
-
* const { data } = await client.auth.getCurrentUser();
|
|
451
|
-
* }
|
|
452
|
-
* ```
|
|
453
|
-
*/
|
|
454
|
-
async restoreSession() {
|
|
455
|
-
if (typeof window === "undefined") {
|
|
456
|
-
return { isLoggedIn: false };
|
|
457
|
-
}
|
|
458
|
-
if (this.tokenManager.getAccessToken()) {
|
|
459
|
-
return { isLoggedIn: true };
|
|
460
|
-
}
|
|
461
|
-
if (hasAuthCookie()) {
|
|
462
|
-
try {
|
|
463
|
-
const response = await this.http.post(
|
|
464
|
-
"/api/auth/refresh"
|
|
465
|
-
);
|
|
466
|
-
if (response.accessToken) {
|
|
467
|
-
this.tokenManager.setMemoryMode();
|
|
468
|
-
this.tokenManager.setAccessToken(response.accessToken);
|
|
469
|
-
this.http.setAuthToken(response.accessToken);
|
|
470
|
-
if (response.user) {
|
|
471
|
-
this.tokenManager.setUser(response.user);
|
|
472
|
-
}
|
|
473
|
-
return { isLoggedIn: true };
|
|
474
|
-
}
|
|
475
|
-
} catch (error) {
|
|
476
|
-
if (error instanceof InsForgeError) {
|
|
477
|
-
if (error.statusCode === 404) {
|
|
478
|
-
this.tokenManager.setStorageMode();
|
|
479
|
-
const token = this.tokenManager.getAccessToken();
|
|
480
|
-
if (token) {
|
|
481
|
-
this.http.setAuthToken(token);
|
|
482
|
-
return { isLoggedIn: true };
|
|
483
|
-
}
|
|
484
|
-
return { isLoggedIn: false };
|
|
485
|
-
}
|
|
486
|
-
if (error.statusCode === 401 || error.statusCode === 403) {
|
|
487
|
-
clearAuthCookie();
|
|
488
|
-
return { isLoggedIn: false };
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
return { isLoggedIn: false };
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
if (this.tokenManager.hasStoredSession()) {
|
|
495
|
-
this.tokenManager.setStorageMode();
|
|
496
|
-
const token = this.tokenManager.getAccessToken();
|
|
497
|
-
if (token) {
|
|
498
|
-
this.http.setAuthToken(token);
|
|
499
|
-
return { isLoggedIn: true };
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
return { isLoggedIn: false };
|
|
503
|
-
}
|
|
504
338
|
/**
|
|
505
339
|
* Automatically detect and handle OAuth callback parameters in the URL
|
|
506
340
|
* This runs on initialization to seamlessly complete the OAuth flow
|
|
@@ -528,9 +362,8 @@ var Auth = class {
|
|
|
528
362
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
529
363
|
}
|
|
530
364
|
};
|
|
531
|
-
this.http.setAuthToken(accessToken);
|
|
532
365
|
this.tokenManager.saveSession(session);
|
|
533
|
-
|
|
366
|
+
this.http.setAuthToken(accessToken);
|
|
534
367
|
const url = new URL(window.location.href);
|
|
535
368
|
url.searchParams.delete("access_token");
|
|
536
369
|
url.searchParams.delete("user_id");
|
|
@@ -551,13 +384,14 @@ var Auth = class {
|
|
|
551
384
|
async signUp(request) {
|
|
552
385
|
try {
|
|
553
386
|
const response = await this.http.post("/api/auth/users", request);
|
|
554
|
-
if (response.accessToken && response.user
|
|
387
|
+
if (response.accessToken && response.user) {
|
|
555
388
|
const session = {
|
|
556
389
|
accessToken: response.accessToken,
|
|
557
390
|
user: response.user
|
|
558
391
|
};
|
|
559
|
-
|
|
560
|
-
|
|
392
|
+
if (!isHostedAuthEnvironment()) {
|
|
393
|
+
this.tokenManager.saveSession(session);
|
|
394
|
+
}
|
|
561
395
|
this.http.setAuthToken(response.accessToken);
|
|
562
396
|
}
|
|
563
397
|
return {
|
|
@@ -584,15 +418,21 @@ var Auth = class {
|
|
|
584
418
|
async signInWithPassword(request) {
|
|
585
419
|
try {
|
|
586
420
|
const response = await this.http.post("/api/auth/sessions", request);
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
421
|
+
const session = {
|
|
422
|
+
accessToken: response.accessToken || "",
|
|
423
|
+
user: response.user || {
|
|
424
|
+
id: "",
|
|
425
|
+
email: "",
|
|
426
|
+
name: "",
|
|
427
|
+
emailVerified: false,
|
|
428
|
+
createdAt: "",
|
|
429
|
+
updatedAt: ""
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
if (!isHostedAuthEnvironment()) {
|
|
592
433
|
this.tokenManager.saveSession(session);
|
|
593
|
-
setAuthCookie();
|
|
594
|
-
this.http.setAuthToken(response.accessToken);
|
|
595
434
|
}
|
|
435
|
+
this.http.setAuthToken(response.accessToken || "");
|
|
596
436
|
return {
|
|
597
437
|
data: response,
|
|
598
438
|
error: null
|
|
@@ -650,13 +490,8 @@ var Auth = class {
|
|
|
650
490
|
*/
|
|
651
491
|
async signOut() {
|
|
652
492
|
try {
|
|
653
|
-
try {
|
|
654
|
-
await this.http.post("/api/auth/logout");
|
|
655
|
-
} catch {
|
|
656
|
-
}
|
|
657
493
|
this.tokenManager.clearSession();
|
|
658
494
|
this.http.setAuthToken(null);
|
|
659
|
-
clearAuthCookie();
|
|
660
495
|
return { error: null };
|
|
661
496
|
} catch (error) {
|
|
662
497
|
return {
|
|
@@ -978,14 +813,13 @@ var Auth = class {
|
|
|
978
813
|
"/api/auth/email/verify",
|
|
979
814
|
request
|
|
980
815
|
);
|
|
981
|
-
if (response.accessToken
|
|
816
|
+
if (response.accessToken) {
|
|
982
817
|
const session = {
|
|
983
818
|
accessToken: response.accessToken,
|
|
984
819
|
user: response.user || {}
|
|
985
820
|
};
|
|
986
821
|
this.tokenManager.saveSession(session);
|
|
987
822
|
this.http.setAuthToken(response.accessToken);
|
|
988
|
-
setAuthCookie();
|
|
989
823
|
}
|
|
990
824
|
return {
|
|
991
825
|
data: response,
|
|
@@ -1528,6 +1362,239 @@ var Functions = class {
|
|
|
1528
1362
|
}
|
|
1529
1363
|
};
|
|
1530
1364
|
|
|
1365
|
+
// src/modules/realtime.ts
|
|
1366
|
+
var import_socket = require("socket.io-client");
|
|
1367
|
+
var CONNECT_TIMEOUT = 1e4;
|
|
1368
|
+
var Realtime = class {
|
|
1369
|
+
constructor(baseUrl, tokenManager) {
|
|
1370
|
+
this.socket = null;
|
|
1371
|
+
this.connectPromise = null;
|
|
1372
|
+
this.subscribedChannels = /* @__PURE__ */ new Set();
|
|
1373
|
+
this.eventListeners = /* @__PURE__ */ new Map();
|
|
1374
|
+
this.baseUrl = baseUrl;
|
|
1375
|
+
this.tokenManager = tokenManager;
|
|
1376
|
+
}
|
|
1377
|
+
notifyListeners(event, payload) {
|
|
1378
|
+
const listeners = this.eventListeners.get(event);
|
|
1379
|
+
if (!listeners) return;
|
|
1380
|
+
for (const cb of listeners) {
|
|
1381
|
+
try {
|
|
1382
|
+
cb(payload);
|
|
1383
|
+
} catch (err) {
|
|
1384
|
+
console.error(`Error in ${event} callback:`, err);
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
/**
|
|
1389
|
+
* Connect to the realtime server
|
|
1390
|
+
* @returns Promise that resolves when connected
|
|
1391
|
+
*/
|
|
1392
|
+
connect() {
|
|
1393
|
+
if (this.socket?.connected) {
|
|
1394
|
+
return Promise.resolve();
|
|
1395
|
+
}
|
|
1396
|
+
if (this.connectPromise) {
|
|
1397
|
+
return this.connectPromise;
|
|
1398
|
+
}
|
|
1399
|
+
this.connectPromise = new Promise((resolve, reject) => {
|
|
1400
|
+
const session = this.tokenManager.getSession();
|
|
1401
|
+
const token = session?.accessToken;
|
|
1402
|
+
this.socket = (0, import_socket.io)(this.baseUrl, {
|
|
1403
|
+
transports: ["websocket"],
|
|
1404
|
+
auth: token ? { token } : void 0
|
|
1405
|
+
});
|
|
1406
|
+
let initialConnection = true;
|
|
1407
|
+
let timeoutId = null;
|
|
1408
|
+
const cleanup = () => {
|
|
1409
|
+
if (timeoutId) {
|
|
1410
|
+
clearTimeout(timeoutId);
|
|
1411
|
+
timeoutId = null;
|
|
1412
|
+
}
|
|
1413
|
+
};
|
|
1414
|
+
timeoutId = setTimeout(() => {
|
|
1415
|
+
if (initialConnection) {
|
|
1416
|
+
initialConnection = false;
|
|
1417
|
+
this.connectPromise = null;
|
|
1418
|
+
this.socket?.disconnect();
|
|
1419
|
+
this.socket = null;
|
|
1420
|
+
reject(new Error(`Connection timeout after ${CONNECT_TIMEOUT}ms`));
|
|
1421
|
+
}
|
|
1422
|
+
}, CONNECT_TIMEOUT);
|
|
1423
|
+
this.socket.on("connect", () => {
|
|
1424
|
+
cleanup();
|
|
1425
|
+
for (const channel of this.subscribedChannels) {
|
|
1426
|
+
this.socket.emit("realtime:subscribe", { channel });
|
|
1427
|
+
}
|
|
1428
|
+
this.notifyListeners("connect");
|
|
1429
|
+
if (initialConnection) {
|
|
1430
|
+
initialConnection = false;
|
|
1431
|
+
this.connectPromise = null;
|
|
1432
|
+
resolve();
|
|
1433
|
+
}
|
|
1434
|
+
});
|
|
1435
|
+
this.socket.on("connect_error", (error) => {
|
|
1436
|
+
cleanup();
|
|
1437
|
+
this.notifyListeners("connect_error", error);
|
|
1438
|
+
if (initialConnection) {
|
|
1439
|
+
initialConnection = false;
|
|
1440
|
+
this.connectPromise = null;
|
|
1441
|
+
reject(error);
|
|
1442
|
+
}
|
|
1443
|
+
});
|
|
1444
|
+
this.socket.on("disconnect", (reason) => {
|
|
1445
|
+
this.notifyListeners("disconnect", reason);
|
|
1446
|
+
});
|
|
1447
|
+
this.socket.on("realtime:error", (error) => {
|
|
1448
|
+
this.notifyListeners("error", error);
|
|
1449
|
+
});
|
|
1450
|
+
this.socket.onAny((event, message) => {
|
|
1451
|
+
if (event === "realtime:error") return;
|
|
1452
|
+
this.notifyListeners(event, message);
|
|
1453
|
+
});
|
|
1454
|
+
});
|
|
1455
|
+
return this.connectPromise;
|
|
1456
|
+
}
|
|
1457
|
+
/**
|
|
1458
|
+
* Disconnect from the realtime server
|
|
1459
|
+
*/
|
|
1460
|
+
disconnect() {
|
|
1461
|
+
if (this.socket) {
|
|
1462
|
+
this.socket.disconnect();
|
|
1463
|
+
this.socket = null;
|
|
1464
|
+
}
|
|
1465
|
+
this.subscribedChannels.clear();
|
|
1466
|
+
}
|
|
1467
|
+
/**
|
|
1468
|
+
* Check if connected to the realtime server
|
|
1469
|
+
*/
|
|
1470
|
+
get isConnected() {
|
|
1471
|
+
return this.socket?.connected ?? false;
|
|
1472
|
+
}
|
|
1473
|
+
/**
|
|
1474
|
+
* Get the current connection state
|
|
1475
|
+
*/
|
|
1476
|
+
get connectionState() {
|
|
1477
|
+
if (!this.socket) return "disconnected";
|
|
1478
|
+
if (this.socket.connected) return "connected";
|
|
1479
|
+
return "connecting";
|
|
1480
|
+
}
|
|
1481
|
+
/**
|
|
1482
|
+
* Get the socket ID (if connected)
|
|
1483
|
+
*/
|
|
1484
|
+
get socketId() {
|
|
1485
|
+
return this.socket?.id;
|
|
1486
|
+
}
|
|
1487
|
+
/**
|
|
1488
|
+
* Subscribe to a channel
|
|
1489
|
+
*
|
|
1490
|
+
* Automatically connects if not already connected.
|
|
1491
|
+
*
|
|
1492
|
+
* @param channel - Channel name (e.g., 'orders:123', 'broadcast')
|
|
1493
|
+
* @returns Promise with the subscription response
|
|
1494
|
+
*/
|
|
1495
|
+
async subscribe(channel) {
|
|
1496
|
+
if (this.subscribedChannels.has(channel)) {
|
|
1497
|
+
return { ok: true, channel };
|
|
1498
|
+
}
|
|
1499
|
+
if (!this.socket?.connected) {
|
|
1500
|
+
try {
|
|
1501
|
+
await this.connect();
|
|
1502
|
+
} catch (error) {
|
|
1503
|
+
const message = error instanceof Error ? error.message : "Connection failed";
|
|
1504
|
+
return { ok: false, channel, error: { code: "CONNECTION_FAILED", message } };
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
return new Promise((resolve) => {
|
|
1508
|
+
this.socket.emit("realtime:subscribe", { channel }, (response) => {
|
|
1509
|
+
if (response.ok) {
|
|
1510
|
+
this.subscribedChannels.add(channel);
|
|
1511
|
+
}
|
|
1512
|
+
resolve(response);
|
|
1513
|
+
});
|
|
1514
|
+
});
|
|
1515
|
+
}
|
|
1516
|
+
/**
|
|
1517
|
+
* Unsubscribe from a channel (fire-and-forget)
|
|
1518
|
+
*
|
|
1519
|
+
* @param channel - Channel name to unsubscribe from
|
|
1520
|
+
*/
|
|
1521
|
+
unsubscribe(channel) {
|
|
1522
|
+
this.subscribedChannels.delete(channel);
|
|
1523
|
+
if (this.socket?.connected) {
|
|
1524
|
+
this.socket.emit("realtime:unsubscribe", { channel });
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
/**
|
|
1528
|
+
* Publish a message to a channel
|
|
1529
|
+
*
|
|
1530
|
+
* @param channel - Channel name
|
|
1531
|
+
* @param event - Event name
|
|
1532
|
+
* @param payload - Message payload
|
|
1533
|
+
*/
|
|
1534
|
+
async publish(channel, event, payload) {
|
|
1535
|
+
if (!this.socket?.connected) {
|
|
1536
|
+
throw new Error("Not connected to realtime server. Call connect() first.");
|
|
1537
|
+
}
|
|
1538
|
+
this.socket.emit("realtime:publish", { channel, event, payload });
|
|
1539
|
+
}
|
|
1540
|
+
/**
|
|
1541
|
+
* Listen for events
|
|
1542
|
+
*
|
|
1543
|
+
* Reserved event names:
|
|
1544
|
+
* - 'connect' - Fired when connected to the server
|
|
1545
|
+
* - 'connect_error' - Fired when connection fails (payload: Error)
|
|
1546
|
+
* - 'disconnect' - Fired when disconnected (payload: reason string)
|
|
1547
|
+
* - 'error' - Fired when a realtime error occurs (payload: RealtimeErrorPayload)
|
|
1548
|
+
*
|
|
1549
|
+
* All other events receive a `SocketMessage` payload with metadata.
|
|
1550
|
+
*
|
|
1551
|
+
* @param event - Event name to listen for
|
|
1552
|
+
* @param callback - Callback function when event is received
|
|
1553
|
+
*/
|
|
1554
|
+
on(event, callback) {
|
|
1555
|
+
if (!this.eventListeners.has(event)) {
|
|
1556
|
+
this.eventListeners.set(event, /* @__PURE__ */ new Set());
|
|
1557
|
+
}
|
|
1558
|
+
this.eventListeners.get(event).add(callback);
|
|
1559
|
+
}
|
|
1560
|
+
/**
|
|
1561
|
+
* Remove a listener for a specific event
|
|
1562
|
+
*
|
|
1563
|
+
* @param event - Event name
|
|
1564
|
+
* @param callback - The callback function to remove
|
|
1565
|
+
*/
|
|
1566
|
+
off(event, callback) {
|
|
1567
|
+
const listeners = this.eventListeners.get(event);
|
|
1568
|
+
if (listeners) {
|
|
1569
|
+
listeners.delete(callback);
|
|
1570
|
+
if (listeners.size === 0) {
|
|
1571
|
+
this.eventListeners.delete(event);
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
/**
|
|
1576
|
+
* Listen for an event only once, then automatically remove the listener
|
|
1577
|
+
*
|
|
1578
|
+
* @param event - Event name to listen for
|
|
1579
|
+
* @param callback - Callback function when event is received
|
|
1580
|
+
*/
|
|
1581
|
+
once(event, callback) {
|
|
1582
|
+
const wrapper = (payload) => {
|
|
1583
|
+
this.off(event, wrapper);
|
|
1584
|
+
callback(payload);
|
|
1585
|
+
};
|
|
1586
|
+
this.on(event, wrapper);
|
|
1587
|
+
}
|
|
1588
|
+
/**
|
|
1589
|
+
* Get all currently subscribed channels
|
|
1590
|
+
*
|
|
1591
|
+
* @returns Array of channel names
|
|
1592
|
+
*/
|
|
1593
|
+
getSubscribedChannels() {
|
|
1594
|
+
return Array.from(this.subscribedChannels);
|
|
1595
|
+
}
|
|
1596
|
+
};
|
|
1597
|
+
|
|
1531
1598
|
// src/client.ts
|
|
1532
1599
|
var InsForgeClient = class {
|
|
1533
1600
|
constructor(config = {}) {
|
|
@@ -1545,11 +1612,15 @@ var InsForgeClient = class {
|
|
|
1545
1612
|
if (existingSession?.accessToken) {
|
|
1546
1613
|
this.http.setAuthToken(existingSession.accessToken);
|
|
1547
1614
|
}
|
|
1548
|
-
this.auth = new Auth(
|
|
1615
|
+
this.auth = new Auth(
|
|
1616
|
+
this.http,
|
|
1617
|
+
this.tokenManager
|
|
1618
|
+
);
|
|
1549
1619
|
this.database = new Database(this.http, this.tokenManager);
|
|
1550
1620
|
this.storage = new Storage(this.http);
|
|
1551
1621
|
this.ai = new AI(this.http);
|
|
1552
1622
|
this.functions = new Functions(this.http);
|
|
1623
|
+
this.realtime = new Realtime(this.http.baseUrl, this.tokenManager);
|
|
1553
1624
|
}
|
|
1554
1625
|
/**
|
|
1555
1626
|
* Get the underlying HTTP client for custom requests
|
|
@@ -1587,6 +1658,7 @@ var index_default = InsForgeClient;
|
|
|
1587
1658
|
HttpClient,
|
|
1588
1659
|
InsForgeClient,
|
|
1589
1660
|
InsForgeError,
|
|
1661
|
+
Realtime,
|
|
1590
1662
|
Storage,
|
|
1591
1663
|
StorageBucket,
|
|
1592
1664
|
TokenManager,
|