@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.mjs
CHANGED
|
@@ -74,7 +74,6 @@ var HttpClient = class {
|
|
|
74
74
|
method,
|
|
75
75
|
headers: requestHeaders,
|
|
76
76
|
body: processedBody,
|
|
77
|
-
credentials: "include",
|
|
78
77
|
...fetchOptions
|
|
79
78
|
});
|
|
80
79
|
if (response.status === 204) {
|
|
@@ -139,29 +138,8 @@ var HttpClient = class {
|
|
|
139
138
|
// src/lib/token-manager.ts
|
|
140
139
|
var TOKEN_KEY = "insforge-auth-token";
|
|
141
140
|
var USER_KEY = "insforge-auth-user";
|
|
142
|
-
var AUTH_FLAG_COOKIE = "isAuthenticated";
|
|
143
|
-
function hasAuthCookie() {
|
|
144
|
-
if (typeof document === "undefined") return false;
|
|
145
|
-
return document.cookie.split(";").some(
|
|
146
|
-
(c) => c.trim().startsWith(`${AUTH_FLAG_COOKIE}=`)
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
function setAuthCookie() {
|
|
150
|
-
if (typeof document === "undefined") return;
|
|
151
|
-
const maxAge = 7 * 24 * 60 * 60;
|
|
152
|
-
document.cookie = `${AUTH_FLAG_COOKIE}=true; path=/; max-age=${maxAge}; SameSite=Lax`;
|
|
153
|
-
}
|
|
154
|
-
function clearAuthCookie() {
|
|
155
|
-
if (typeof document === "undefined") return;
|
|
156
|
-
document.cookie = `${AUTH_FLAG_COOKIE}=; path=/; max-age=0; SameSite=Lax`;
|
|
157
|
-
}
|
|
158
141
|
var TokenManager = class {
|
|
159
142
|
constructor(storage) {
|
|
160
|
-
// In-memory storage
|
|
161
|
-
this.accessToken = null;
|
|
162
|
-
this.user = null;
|
|
163
|
-
// Mode: 'memory' (new backend) or 'storage' (legacy backend, default)
|
|
164
|
-
this._mode = "storage";
|
|
165
143
|
if (storage) {
|
|
166
144
|
this.storage = storage;
|
|
167
145
|
} else if (typeof window !== "undefined" && window.localStorage) {
|
|
@@ -179,112 +157,32 @@ var TokenManager = class {
|
|
|
179
157
|
};
|
|
180
158
|
}
|
|
181
159
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
get mode() {
|
|
186
|
-
return this._mode;
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Set mode to memory (new backend with cookies + memory)
|
|
190
|
-
*/
|
|
191
|
-
setMemoryMode() {
|
|
192
|
-
if (this._mode === "storage") {
|
|
193
|
-
this.storage.removeItem(TOKEN_KEY);
|
|
194
|
-
this.storage.removeItem(USER_KEY);
|
|
195
|
-
}
|
|
196
|
-
this._mode = "memory";
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Set mode to storage (legacy backend with localStorage)
|
|
200
|
-
* Also loads existing session from localStorage
|
|
201
|
-
*/
|
|
202
|
-
setStorageMode() {
|
|
203
|
-
this._mode = "storage";
|
|
204
|
-
this.loadFromStorage();
|
|
160
|
+
saveSession(session) {
|
|
161
|
+
this.storage.setItem(TOKEN_KEY, session.accessToken);
|
|
162
|
+
this.storage.setItem(USER_KEY, JSON.stringify(session.user));
|
|
205
163
|
}
|
|
206
|
-
|
|
207
|
-
* Load session from localStorage
|
|
208
|
-
*/
|
|
209
|
-
loadFromStorage() {
|
|
164
|
+
getSession() {
|
|
210
165
|
const token = this.storage.getItem(TOKEN_KEY);
|
|
211
166
|
const userStr = this.storage.getItem(USER_KEY);
|
|
212
|
-
if (token
|
|
213
|
-
|
|
214
|
-
this.accessToken = token;
|
|
215
|
-
this.user = JSON.parse(userStr);
|
|
216
|
-
} catch {
|
|
217
|
-
this.clearSession();
|
|
218
|
-
}
|
|
167
|
+
if (!token || !userStr) {
|
|
168
|
+
return null;
|
|
219
169
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
this.user = session.user;
|
|
227
|
-
if (this._mode === "storage") {
|
|
228
|
-
this.storage.setItem(TOKEN_KEY, session.accessToken);
|
|
229
|
-
this.storage.setItem(USER_KEY, JSON.stringify(session.user));
|
|
170
|
+
try {
|
|
171
|
+
const user = JSON.parse(userStr);
|
|
172
|
+
return { accessToken: token, user };
|
|
173
|
+
} catch {
|
|
174
|
+
this.clearSession();
|
|
175
|
+
return null;
|
|
230
176
|
}
|
|
231
177
|
}
|
|
232
|
-
/**
|
|
233
|
-
* Get current session
|
|
234
|
-
*/
|
|
235
|
-
getSession() {
|
|
236
|
-
if (!this.accessToken || !this.user) return null;
|
|
237
|
-
return {
|
|
238
|
-
accessToken: this.accessToken,
|
|
239
|
-
user: this.user
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
/**
|
|
243
|
-
* Get access token
|
|
244
|
-
*/
|
|
245
178
|
getAccessToken() {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Set access token
|
|
250
|
-
*/
|
|
251
|
-
setAccessToken(token) {
|
|
252
|
-
this.accessToken = token;
|
|
253
|
-
if (this._mode === "storage") {
|
|
254
|
-
this.storage.setItem(TOKEN_KEY, token);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* Get user
|
|
259
|
-
*/
|
|
260
|
-
getUser() {
|
|
261
|
-
return this.user;
|
|
262
|
-
}
|
|
263
|
-
/**
|
|
264
|
-
* Set user
|
|
265
|
-
*/
|
|
266
|
-
setUser(user) {
|
|
267
|
-
this.user = user;
|
|
268
|
-
if (this._mode === "storage") {
|
|
269
|
-
this.storage.setItem(USER_KEY, JSON.stringify(user));
|
|
270
|
-
}
|
|
179
|
+
const token = this.storage.getItem(TOKEN_KEY);
|
|
180
|
+
return typeof token === "string" ? token : null;
|
|
271
181
|
}
|
|
272
|
-
/**
|
|
273
|
-
* Clear session (both memory and localStorage)
|
|
274
|
-
*/
|
|
275
182
|
clearSession() {
|
|
276
|
-
this.accessToken = null;
|
|
277
|
-
this.user = null;
|
|
278
183
|
this.storage.removeItem(TOKEN_KEY);
|
|
279
184
|
this.storage.removeItem(USER_KEY);
|
|
280
185
|
}
|
|
281
|
-
/**
|
|
282
|
-
* Check if there's a session in localStorage (for legacy detection)
|
|
283
|
-
*/
|
|
284
|
-
hasStoredSession() {
|
|
285
|
-
const token = this.storage.getItem(TOKEN_KEY);
|
|
286
|
-
return !!token;
|
|
287
|
-
}
|
|
288
186
|
};
|
|
289
187
|
|
|
290
188
|
// src/modules/database-postgrest.ts
|
|
@@ -399,71 +297,6 @@ var Auth = class {
|
|
|
399
297
|
this.database = new Database(http, tokenManager);
|
|
400
298
|
this.detectAuthCallback();
|
|
401
299
|
}
|
|
402
|
-
/**
|
|
403
|
-
* Restore session on app initialization
|
|
404
|
-
*
|
|
405
|
-
* @returns Object with isLoggedIn status
|
|
406
|
-
*
|
|
407
|
-
* @example
|
|
408
|
-
* ```typescript
|
|
409
|
-
* const client = new InsForgeClient({ baseUrl: '...' });
|
|
410
|
-
* const { isLoggedIn } = await client.auth.restoreSession();
|
|
411
|
-
*
|
|
412
|
-
* if (isLoggedIn) {
|
|
413
|
-
* const { data } = await client.auth.getCurrentUser();
|
|
414
|
-
* }
|
|
415
|
-
* ```
|
|
416
|
-
*/
|
|
417
|
-
async restoreSession() {
|
|
418
|
-
if (typeof window === "undefined") {
|
|
419
|
-
return { isLoggedIn: false };
|
|
420
|
-
}
|
|
421
|
-
if (this.tokenManager.getAccessToken()) {
|
|
422
|
-
return { isLoggedIn: true };
|
|
423
|
-
}
|
|
424
|
-
if (hasAuthCookie()) {
|
|
425
|
-
try {
|
|
426
|
-
const response = await this.http.post(
|
|
427
|
-
"/api/auth/refresh"
|
|
428
|
-
);
|
|
429
|
-
if (response.accessToken) {
|
|
430
|
-
this.tokenManager.setMemoryMode();
|
|
431
|
-
this.tokenManager.setAccessToken(response.accessToken);
|
|
432
|
-
this.http.setAuthToken(response.accessToken);
|
|
433
|
-
if (response.user) {
|
|
434
|
-
this.tokenManager.setUser(response.user);
|
|
435
|
-
}
|
|
436
|
-
return { isLoggedIn: true };
|
|
437
|
-
}
|
|
438
|
-
} catch (error) {
|
|
439
|
-
if (error instanceof InsForgeError) {
|
|
440
|
-
if (error.statusCode === 404) {
|
|
441
|
-
this.tokenManager.setStorageMode();
|
|
442
|
-
const token = this.tokenManager.getAccessToken();
|
|
443
|
-
if (token) {
|
|
444
|
-
this.http.setAuthToken(token);
|
|
445
|
-
return { isLoggedIn: true };
|
|
446
|
-
}
|
|
447
|
-
return { isLoggedIn: false };
|
|
448
|
-
}
|
|
449
|
-
if (error.statusCode === 401 || error.statusCode === 403) {
|
|
450
|
-
clearAuthCookie();
|
|
451
|
-
return { isLoggedIn: false };
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
return { isLoggedIn: false };
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
if (this.tokenManager.hasStoredSession()) {
|
|
458
|
-
this.tokenManager.setStorageMode();
|
|
459
|
-
const token = this.tokenManager.getAccessToken();
|
|
460
|
-
if (token) {
|
|
461
|
-
this.http.setAuthToken(token);
|
|
462
|
-
return { isLoggedIn: true };
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
return { isLoggedIn: false };
|
|
466
|
-
}
|
|
467
300
|
/**
|
|
468
301
|
* Automatically detect and handle OAuth callback parameters in the URL
|
|
469
302
|
* This runs on initialization to seamlessly complete the OAuth flow
|
|
@@ -491,9 +324,8 @@ var Auth = class {
|
|
|
491
324
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
492
325
|
}
|
|
493
326
|
};
|
|
494
|
-
this.http.setAuthToken(accessToken);
|
|
495
327
|
this.tokenManager.saveSession(session);
|
|
496
|
-
|
|
328
|
+
this.http.setAuthToken(accessToken);
|
|
497
329
|
const url = new URL(window.location.href);
|
|
498
330
|
url.searchParams.delete("access_token");
|
|
499
331
|
url.searchParams.delete("user_id");
|
|
@@ -514,13 +346,14 @@ var Auth = class {
|
|
|
514
346
|
async signUp(request) {
|
|
515
347
|
try {
|
|
516
348
|
const response = await this.http.post("/api/auth/users", request);
|
|
517
|
-
if (response.accessToken && response.user
|
|
349
|
+
if (response.accessToken && response.user) {
|
|
518
350
|
const session = {
|
|
519
351
|
accessToken: response.accessToken,
|
|
520
352
|
user: response.user
|
|
521
353
|
};
|
|
522
|
-
|
|
523
|
-
|
|
354
|
+
if (!isHostedAuthEnvironment()) {
|
|
355
|
+
this.tokenManager.saveSession(session);
|
|
356
|
+
}
|
|
524
357
|
this.http.setAuthToken(response.accessToken);
|
|
525
358
|
}
|
|
526
359
|
return {
|
|
@@ -547,15 +380,21 @@ var Auth = class {
|
|
|
547
380
|
async signInWithPassword(request) {
|
|
548
381
|
try {
|
|
549
382
|
const response = await this.http.post("/api/auth/sessions", request);
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
383
|
+
const session = {
|
|
384
|
+
accessToken: response.accessToken || "",
|
|
385
|
+
user: response.user || {
|
|
386
|
+
id: "",
|
|
387
|
+
email: "",
|
|
388
|
+
name: "",
|
|
389
|
+
emailVerified: false,
|
|
390
|
+
createdAt: "",
|
|
391
|
+
updatedAt: ""
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
if (!isHostedAuthEnvironment()) {
|
|
555
395
|
this.tokenManager.saveSession(session);
|
|
556
|
-
setAuthCookie();
|
|
557
|
-
this.http.setAuthToken(response.accessToken);
|
|
558
396
|
}
|
|
397
|
+
this.http.setAuthToken(response.accessToken || "");
|
|
559
398
|
return {
|
|
560
399
|
data: response,
|
|
561
400
|
error: null
|
|
@@ -613,13 +452,8 @@ var Auth = class {
|
|
|
613
452
|
*/
|
|
614
453
|
async signOut() {
|
|
615
454
|
try {
|
|
616
|
-
try {
|
|
617
|
-
await this.http.post("/api/auth/logout");
|
|
618
|
-
} catch {
|
|
619
|
-
}
|
|
620
455
|
this.tokenManager.clearSession();
|
|
621
456
|
this.http.setAuthToken(null);
|
|
622
|
-
clearAuthCookie();
|
|
623
457
|
return { error: null };
|
|
624
458
|
} catch (error) {
|
|
625
459
|
return {
|
|
@@ -941,14 +775,13 @@ var Auth = class {
|
|
|
941
775
|
"/api/auth/email/verify",
|
|
942
776
|
request
|
|
943
777
|
);
|
|
944
|
-
if (response.accessToken
|
|
778
|
+
if (response.accessToken) {
|
|
945
779
|
const session = {
|
|
946
780
|
accessToken: response.accessToken,
|
|
947
781
|
user: response.user || {}
|
|
948
782
|
};
|
|
949
783
|
this.tokenManager.saveSession(session);
|
|
950
784
|
this.http.setAuthToken(response.accessToken);
|
|
951
|
-
setAuthCookie();
|
|
952
785
|
}
|
|
953
786
|
return {
|
|
954
787
|
data: response,
|
|
@@ -1491,6 +1324,239 @@ var Functions = class {
|
|
|
1491
1324
|
}
|
|
1492
1325
|
};
|
|
1493
1326
|
|
|
1327
|
+
// src/modules/realtime.ts
|
|
1328
|
+
import { io } from "socket.io-client";
|
|
1329
|
+
var CONNECT_TIMEOUT = 1e4;
|
|
1330
|
+
var Realtime = class {
|
|
1331
|
+
constructor(baseUrl, tokenManager) {
|
|
1332
|
+
this.socket = null;
|
|
1333
|
+
this.connectPromise = null;
|
|
1334
|
+
this.subscribedChannels = /* @__PURE__ */ new Set();
|
|
1335
|
+
this.eventListeners = /* @__PURE__ */ new Map();
|
|
1336
|
+
this.baseUrl = baseUrl;
|
|
1337
|
+
this.tokenManager = tokenManager;
|
|
1338
|
+
}
|
|
1339
|
+
notifyListeners(event, payload) {
|
|
1340
|
+
const listeners = this.eventListeners.get(event);
|
|
1341
|
+
if (!listeners) return;
|
|
1342
|
+
for (const cb of listeners) {
|
|
1343
|
+
try {
|
|
1344
|
+
cb(payload);
|
|
1345
|
+
} catch (err) {
|
|
1346
|
+
console.error(`Error in ${event} callback:`, err);
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
/**
|
|
1351
|
+
* Connect to the realtime server
|
|
1352
|
+
* @returns Promise that resolves when connected
|
|
1353
|
+
*/
|
|
1354
|
+
connect() {
|
|
1355
|
+
if (this.socket?.connected) {
|
|
1356
|
+
return Promise.resolve();
|
|
1357
|
+
}
|
|
1358
|
+
if (this.connectPromise) {
|
|
1359
|
+
return this.connectPromise;
|
|
1360
|
+
}
|
|
1361
|
+
this.connectPromise = new Promise((resolve, reject) => {
|
|
1362
|
+
const session = this.tokenManager.getSession();
|
|
1363
|
+
const token = session?.accessToken;
|
|
1364
|
+
this.socket = io(this.baseUrl, {
|
|
1365
|
+
transports: ["websocket"],
|
|
1366
|
+
auth: token ? { token } : void 0
|
|
1367
|
+
});
|
|
1368
|
+
let initialConnection = true;
|
|
1369
|
+
let timeoutId = null;
|
|
1370
|
+
const cleanup = () => {
|
|
1371
|
+
if (timeoutId) {
|
|
1372
|
+
clearTimeout(timeoutId);
|
|
1373
|
+
timeoutId = null;
|
|
1374
|
+
}
|
|
1375
|
+
};
|
|
1376
|
+
timeoutId = setTimeout(() => {
|
|
1377
|
+
if (initialConnection) {
|
|
1378
|
+
initialConnection = false;
|
|
1379
|
+
this.connectPromise = null;
|
|
1380
|
+
this.socket?.disconnect();
|
|
1381
|
+
this.socket = null;
|
|
1382
|
+
reject(new Error(`Connection timeout after ${CONNECT_TIMEOUT}ms`));
|
|
1383
|
+
}
|
|
1384
|
+
}, CONNECT_TIMEOUT);
|
|
1385
|
+
this.socket.on("connect", () => {
|
|
1386
|
+
cleanup();
|
|
1387
|
+
for (const channel of this.subscribedChannels) {
|
|
1388
|
+
this.socket.emit("realtime:subscribe", { channel });
|
|
1389
|
+
}
|
|
1390
|
+
this.notifyListeners("connect");
|
|
1391
|
+
if (initialConnection) {
|
|
1392
|
+
initialConnection = false;
|
|
1393
|
+
this.connectPromise = null;
|
|
1394
|
+
resolve();
|
|
1395
|
+
}
|
|
1396
|
+
});
|
|
1397
|
+
this.socket.on("connect_error", (error) => {
|
|
1398
|
+
cleanup();
|
|
1399
|
+
this.notifyListeners("connect_error", error);
|
|
1400
|
+
if (initialConnection) {
|
|
1401
|
+
initialConnection = false;
|
|
1402
|
+
this.connectPromise = null;
|
|
1403
|
+
reject(error);
|
|
1404
|
+
}
|
|
1405
|
+
});
|
|
1406
|
+
this.socket.on("disconnect", (reason) => {
|
|
1407
|
+
this.notifyListeners("disconnect", reason);
|
|
1408
|
+
});
|
|
1409
|
+
this.socket.on("realtime:error", (error) => {
|
|
1410
|
+
this.notifyListeners("error", error);
|
|
1411
|
+
});
|
|
1412
|
+
this.socket.onAny((event, message) => {
|
|
1413
|
+
if (event === "realtime:error") return;
|
|
1414
|
+
this.notifyListeners(event, message);
|
|
1415
|
+
});
|
|
1416
|
+
});
|
|
1417
|
+
return this.connectPromise;
|
|
1418
|
+
}
|
|
1419
|
+
/**
|
|
1420
|
+
* Disconnect from the realtime server
|
|
1421
|
+
*/
|
|
1422
|
+
disconnect() {
|
|
1423
|
+
if (this.socket) {
|
|
1424
|
+
this.socket.disconnect();
|
|
1425
|
+
this.socket = null;
|
|
1426
|
+
}
|
|
1427
|
+
this.subscribedChannels.clear();
|
|
1428
|
+
}
|
|
1429
|
+
/**
|
|
1430
|
+
* Check if connected to the realtime server
|
|
1431
|
+
*/
|
|
1432
|
+
get isConnected() {
|
|
1433
|
+
return this.socket?.connected ?? false;
|
|
1434
|
+
}
|
|
1435
|
+
/**
|
|
1436
|
+
* Get the current connection state
|
|
1437
|
+
*/
|
|
1438
|
+
get connectionState() {
|
|
1439
|
+
if (!this.socket) return "disconnected";
|
|
1440
|
+
if (this.socket.connected) return "connected";
|
|
1441
|
+
return "connecting";
|
|
1442
|
+
}
|
|
1443
|
+
/**
|
|
1444
|
+
* Get the socket ID (if connected)
|
|
1445
|
+
*/
|
|
1446
|
+
get socketId() {
|
|
1447
|
+
return this.socket?.id;
|
|
1448
|
+
}
|
|
1449
|
+
/**
|
|
1450
|
+
* Subscribe to a channel
|
|
1451
|
+
*
|
|
1452
|
+
* Automatically connects if not already connected.
|
|
1453
|
+
*
|
|
1454
|
+
* @param channel - Channel name (e.g., 'orders:123', 'broadcast')
|
|
1455
|
+
* @returns Promise with the subscription response
|
|
1456
|
+
*/
|
|
1457
|
+
async subscribe(channel) {
|
|
1458
|
+
if (this.subscribedChannels.has(channel)) {
|
|
1459
|
+
return { ok: true, channel };
|
|
1460
|
+
}
|
|
1461
|
+
if (!this.socket?.connected) {
|
|
1462
|
+
try {
|
|
1463
|
+
await this.connect();
|
|
1464
|
+
} catch (error) {
|
|
1465
|
+
const message = error instanceof Error ? error.message : "Connection failed";
|
|
1466
|
+
return { ok: false, channel, error: { code: "CONNECTION_FAILED", message } };
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
return new Promise((resolve) => {
|
|
1470
|
+
this.socket.emit("realtime:subscribe", { channel }, (response) => {
|
|
1471
|
+
if (response.ok) {
|
|
1472
|
+
this.subscribedChannels.add(channel);
|
|
1473
|
+
}
|
|
1474
|
+
resolve(response);
|
|
1475
|
+
});
|
|
1476
|
+
});
|
|
1477
|
+
}
|
|
1478
|
+
/**
|
|
1479
|
+
* Unsubscribe from a channel (fire-and-forget)
|
|
1480
|
+
*
|
|
1481
|
+
* @param channel - Channel name to unsubscribe from
|
|
1482
|
+
*/
|
|
1483
|
+
unsubscribe(channel) {
|
|
1484
|
+
this.subscribedChannels.delete(channel);
|
|
1485
|
+
if (this.socket?.connected) {
|
|
1486
|
+
this.socket.emit("realtime:unsubscribe", { channel });
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
/**
|
|
1490
|
+
* Publish a message to a channel
|
|
1491
|
+
*
|
|
1492
|
+
* @param channel - Channel name
|
|
1493
|
+
* @param event - Event name
|
|
1494
|
+
* @param payload - Message payload
|
|
1495
|
+
*/
|
|
1496
|
+
async publish(channel, event, payload) {
|
|
1497
|
+
if (!this.socket?.connected) {
|
|
1498
|
+
throw new Error("Not connected to realtime server. Call connect() first.");
|
|
1499
|
+
}
|
|
1500
|
+
this.socket.emit("realtime:publish", { channel, event, payload });
|
|
1501
|
+
}
|
|
1502
|
+
/**
|
|
1503
|
+
* Listen for events
|
|
1504
|
+
*
|
|
1505
|
+
* Reserved event names:
|
|
1506
|
+
* - 'connect' - Fired when connected to the server
|
|
1507
|
+
* - 'connect_error' - Fired when connection fails (payload: Error)
|
|
1508
|
+
* - 'disconnect' - Fired when disconnected (payload: reason string)
|
|
1509
|
+
* - 'error' - Fired when a realtime error occurs (payload: RealtimeErrorPayload)
|
|
1510
|
+
*
|
|
1511
|
+
* All other events receive a `SocketMessage` payload with metadata.
|
|
1512
|
+
*
|
|
1513
|
+
* @param event - Event name to listen for
|
|
1514
|
+
* @param callback - Callback function when event is received
|
|
1515
|
+
*/
|
|
1516
|
+
on(event, callback) {
|
|
1517
|
+
if (!this.eventListeners.has(event)) {
|
|
1518
|
+
this.eventListeners.set(event, /* @__PURE__ */ new Set());
|
|
1519
|
+
}
|
|
1520
|
+
this.eventListeners.get(event).add(callback);
|
|
1521
|
+
}
|
|
1522
|
+
/**
|
|
1523
|
+
* Remove a listener for a specific event
|
|
1524
|
+
*
|
|
1525
|
+
* @param event - Event name
|
|
1526
|
+
* @param callback - The callback function to remove
|
|
1527
|
+
*/
|
|
1528
|
+
off(event, callback) {
|
|
1529
|
+
const listeners = this.eventListeners.get(event);
|
|
1530
|
+
if (listeners) {
|
|
1531
|
+
listeners.delete(callback);
|
|
1532
|
+
if (listeners.size === 0) {
|
|
1533
|
+
this.eventListeners.delete(event);
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
/**
|
|
1538
|
+
* Listen for an event only once, then automatically remove the listener
|
|
1539
|
+
*
|
|
1540
|
+
* @param event - Event name to listen for
|
|
1541
|
+
* @param callback - Callback function when event is received
|
|
1542
|
+
*/
|
|
1543
|
+
once(event, callback) {
|
|
1544
|
+
const wrapper = (payload) => {
|
|
1545
|
+
this.off(event, wrapper);
|
|
1546
|
+
callback(payload);
|
|
1547
|
+
};
|
|
1548
|
+
this.on(event, wrapper);
|
|
1549
|
+
}
|
|
1550
|
+
/**
|
|
1551
|
+
* Get all currently subscribed channels
|
|
1552
|
+
*
|
|
1553
|
+
* @returns Array of channel names
|
|
1554
|
+
*/
|
|
1555
|
+
getSubscribedChannels() {
|
|
1556
|
+
return Array.from(this.subscribedChannels);
|
|
1557
|
+
}
|
|
1558
|
+
};
|
|
1559
|
+
|
|
1494
1560
|
// src/client.ts
|
|
1495
1561
|
var InsForgeClient = class {
|
|
1496
1562
|
constructor(config = {}) {
|
|
@@ -1508,11 +1574,15 @@ var InsForgeClient = class {
|
|
|
1508
1574
|
if (existingSession?.accessToken) {
|
|
1509
1575
|
this.http.setAuthToken(existingSession.accessToken);
|
|
1510
1576
|
}
|
|
1511
|
-
this.auth = new Auth(
|
|
1577
|
+
this.auth = new Auth(
|
|
1578
|
+
this.http,
|
|
1579
|
+
this.tokenManager
|
|
1580
|
+
);
|
|
1512
1581
|
this.database = new Database(this.http, this.tokenManager);
|
|
1513
1582
|
this.storage = new Storage(this.http);
|
|
1514
1583
|
this.ai = new AI(this.http);
|
|
1515
1584
|
this.functions = new Functions(this.http);
|
|
1585
|
+
this.realtime = new Realtime(this.http.baseUrl, this.tokenManager);
|
|
1516
1586
|
}
|
|
1517
1587
|
/**
|
|
1518
1588
|
* Get the underlying HTTP client for custom requests
|
|
@@ -1549,6 +1619,7 @@ export {
|
|
|
1549
1619
|
HttpClient,
|
|
1550
1620
|
InsForgeClient,
|
|
1551
1621
|
InsForgeError,
|
|
1622
|
+
Realtime,
|
|
1552
1623
|
Storage,
|
|
1553
1624
|
StorageBucket,
|
|
1554
1625
|
TokenManager,
|