@baasix/sdk 0.1.7 → 0.1.9

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/dist/index.d.cts CHANGED
@@ -1076,8 +1076,26 @@ interface RoomUserEvent {
1076
1076
  room: string;
1077
1077
  userId: string | number;
1078
1078
  socketId: string;
1079
+ metadata: Record<string, any>;
1079
1080
  timestamp: string;
1080
1081
  }
1082
+ interface RoomKickEvent {
1083
+ room: string;
1084
+ kickedBy: string | number;
1085
+ timestamp: string;
1086
+ }
1087
+ interface RoomCreatorChangedEvent {
1088
+ room: string;
1089
+ newCreatorSocketId: string;
1090
+ newCreatorUserId: string | number;
1091
+ timestamp: string;
1092
+ }
1093
+ interface RoomMember {
1094
+ socketId: string;
1095
+ userId: string | number;
1096
+ isCreator: boolean;
1097
+ metadata: Record<string, any>;
1098
+ }
1081
1099
  interface SubscriptionCallback<T = any> {
1082
1100
  (payload: SubscriptionPayload<T>): void;
1083
1101
  }
@@ -1119,6 +1137,8 @@ declare class RealtimeModule {
1119
1137
  private workflowCallbacks;
1120
1138
  private roomCallbacks;
1121
1139
  private roomUserCallbacks;
1140
+ private kickCallbacks;
1141
+ private creatorChangedCallbacks;
1122
1142
  private connectionCallbacks;
1123
1143
  private reconnecting;
1124
1144
  private connectionPromise;
@@ -1249,20 +1269,31 @@ declare class RealtimeModule {
1249
1269
  subscribeToExecution(executionId: string | number, callback: (data: WorkflowExecutionUpdate) => void): () => void;
1250
1270
  private handleWorkflowUpdate;
1251
1271
  /**
1252
- * Join a custom room for real-time communication
1272
+ * Join a custom room for real-time communication.
1273
+ *
1274
+ * You can optionally attach metadata (e.g. display name, avatar, team) that
1275
+ * will be visible to all other members via {@link getRoomMembers} and in
1276
+ * `room:user:joined` events.
1277
+ *
1278
+ * @param roomName - The room to join.
1279
+ * @param metadata - Optional key/value pairs stored alongside this member.
1253
1280
  *
1254
1281
  * @example
1255
1282
  * ```typescript
1256
- * // Join a room
1257
- * await baasix.realtime.joinRoom('game:lobby');
1283
+ * // Join a room with metadata
1284
+ * await baasix.realtime.joinRoom('game:lobby', {
1285
+ * username: 'Alice',
1286
+ * avatar: 'https://example.com/alice.png',
1287
+ * team: 'blue',
1288
+ * });
1258
1289
  *
1259
- * // Listen for messages
1260
- * baasix.realtime.onRoomMessage('game:lobby', 'chat', (data) => {
1261
- * console.log(`${data.sender.userId}: ${data.payload.text}`);
1290
+ * // Listen for other users joining (includes their metadata)
1291
+ * baasix.realtime.onUserJoined('game:lobby', (data) => {
1292
+ * console.log(data.metadata.username, 'joined');
1262
1293
  * });
1263
1294
  * ```
1264
1295
  */
1265
- joinRoom(roomName: string): Promise<void>;
1296
+ joinRoom(roomName: string, metadata?: Record<string, any>): Promise<void>;
1266
1297
  /**
1267
1298
  * Leave a custom room
1268
1299
  *
@@ -1272,6 +1303,55 @@ declare class RealtimeModule {
1272
1303
  * ```
1273
1304
  */
1274
1305
  leaveRoom(roomName: string): Promise<void>;
1306
+ /**
1307
+ * Get the list of users currently in a room.
1308
+ * You must already be a member of the room to call this.
1309
+ *
1310
+ * Each entry includes `userId`, `socketId`, `isCreator`, and `metadata`
1311
+ * (the custom object the member passed to {@link joinRoom}).
1312
+ *
1313
+ * @example
1314
+ * ```typescript
1315
+ * const members = await baasix.realtime.getRoomMembers('game:lobby');
1316
+ * members.forEach(m => {
1317
+ * console.log(m.metadata.username, m.isCreator ? '(owner)' : '');
1318
+ * });
1319
+ * ```
1320
+ */
1321
+ getRoomMembers(roomName: string): Promise<RoomMember[]>;
1322
+ /**
1323
+ * Kick a user from a custom room. Only the room creator may call this.
1324
+ *
1325
+ * @example
1326
+ * ```typescript
1327
+ * await baasix.realtime.kickFromRoom('game:lobby', 'user-id-123');
1328
+ * ```
1329
+ */
1330
+ kickFromRoom(roomName: string, targetUserId: string | number): Promise<void>;
1331
+ /**
1332
+ * Listen for being kicked from a room.
1333
+ * The callback fires when the current user is removed by the room creator.
1334
+ * Room listeners are automatically cleaned up after the kick.
1335
+ *
1336
+ * @example
1337
+ * ```typescript
1338
+ * baasix.realtime.onKicked('game:lobby', ({ kickedBy }) => {
1339
+ * console.log(`You were kicked by user ${kickedBy}`);
1340
+ * });
1341
+ * ```
1342
+ */
1343
+ onKicked(roomName: string, callback: (data: RoomKickEvent) => void): () => void;
1344
+ /**
1345
+ * Listen for room ownership changes (e.g. when the creator leaves).
1346
+ *
1347
+ * @example
1348
+ * ```typescript
1349
+ * baasix.realtime.onRoomCreatorChanged('game:lobby', ({ newCreatorUserId }) => {
1350
+ * console.log(`New room owner: ${newCreatorUserId}`);
1351
+ * });
1352
+ * ```
1353
+ */
1354
+ onRoomCreatorChanged(roomName: string, callback: (data: RoomCreatorChangedEvent) => void): () => void;
1275
1355
  /**
1276
1356
  * Send a message to a room
1277
1357
  *
package/dist/index.d.ts CHANGED
@@ -1076,8 +1076,26 @@ interface RoomUserEvent {
1076
1076
  room: string;
1077
1077
  userId: string | number;
1078
1078
  socketId: string;
1079
+ metadata: Record<string, any>;
1079
1080
  timestamp: string;
1080
1081
  }
1082
+ interface RoomKickEvent {
1083
+ room: string;
1084
+ kickedBy: string | number;
1085
+ timestamp: string;
1086
+ }
1087
+ interface RoomCreatorChangedEvent {
1088
+ room: string;
1089
+ newCreatorSocketId: string;
1090
+ newCreatorUserId: string | number;
1091
+ timestamp: string;
1092
+ }
1093
+ interface RoomMember {
1094
+ socketId: string;
1095
+ userId: string | number;
1096
+ isCreator: boolean;
1097
+ metadata: Record<string, any>;
1098
+ }
1081
1099
  interface SubscriptionCallback<T = any> {
1082
1100
  (payload: SubscriptionPayload<T>): void;
1083
1101
  }
@@ -1119,6 +1137,8 @@ declare class RealtimeModule {
1119
1137
  private workflowCallbacks;
1120
1138
  private roomCallbacks;
1121
1139
  private roomUserCallbacks;
1140
+ private kickCallbacks;
1141
+ private creatorChangedCallbacks;
1122
1142
  private connectionCallbacks;
1123
1143
  private reconnecting;
1124
1144
  private connectionPromise;
@@ -1249,20 +1269,31 @@ declare class RealtimeModule {
1249
1269
  subscribeToExecution(executionId: string | number, callback: (data: WorkflowExecutionUpdate) => void): () => void;
1250
1270
  private handleWorkflowUpdate;
1251
1271
  /**
1252
- * Join a custom room for real-time communication
1272
+ * Join a custom room for real-time communication.
1273
+ *
1274
+ * You can optionally attach metadata (e.g. display name, avatar, team) that
1275
+ * will be visible to all other members via {@link getRoomMembers} and in
1276
+ * `room:user:joined` events.
1277
+ *
1278
+ * @param roomName - The room to join.
1279
+ * @param metadata - Optional key/value pairs stored alongside this member.
1253
1280
  *
1254
1281
  * @example
1255
1282
  * ```typescript
1256
- * // Join a room
1257
- * await baasix.realtime.joinRoom('game:lobby');
1283
+ * // Join a room with metadata
1284
+ * await baasix.realtime.joinRoom('game:lobby', {
1285
+ * username: 'Alice',
1286
+ * avatar: 'https://example.com/alice.png',
1287
+ * team: 'blue',
1288
+ * });
1258
1289
  *
1259
- * // Listen for messages
1260
- * baasix.realtime.onRoomMessage('game:lobby', 'chat', (data) => {
1261
- * console.log(`${data.sender.userId}: ${data.payload.text}`);
1290
+ * // Listen for other users joining (includes their metadata)
1291
+ * baasix.realtime.onUserJoined('game:lobby', (data) => {
1292
+ * console.log(data.metadata.username, 'joined');
1262
1293
  * });
1263
1294
  * ```
1264
1295
  */
1265
- joinRoom(roomName: string): Promise<void>;
1296
+ joinRoom(roomName: string, metadata?: Record<string, any>): Promise<void>;
1266
1297
  /**
1267
1298
  * Leave a custom room
1268
1299
  *
@@ -1272,6 +1303,55 @@ declare class RealtimeModule {
1272
1303
  * ```
1273
1304
  */
1274
1305
  leaveRoom(roomName: string): Promise<void>;
1306
+ /**
1307
+ * Get the list of users currently in a room.
1308
+ * You must already be a member of the room to call this.
1309
+ *
1310
+ * Each entry includes `userId`, `socketId`, `isCreator`, and `metadata`
1311
+ * (the custom object the member passed to {@link joinRoom}).
1312
+ *
1313
+ * @example
1314
+ * ```typescript
1315
+ * const members = await baasix.realtime.getRoomMembers('game:lobby');
1316
+ * members.forEach(m => {
1317
+ * console.log(m.metadata.username, m.isCreator ? '(owner)' : '');
1318
+ * });
1319
+ * ```
1320
+ */
1321
+ getRoomMembers(roomName: string): Promise<RoomMember[]>;
1322
+ /**
1323
+ * Kick a user from a custom room. Only the room creator may call this.
1324
+ *
1325
+ * @example
1326
+ * ```typescript
1327
+ * await baasix.realtime.kickFromRoom('game:lobby', 'user-id-123');
1328
+ * ```
1329
+ */
1330
+ kickFromRoom(roomName: string, targetUserId: string | number): Promise<void>;
1331
+ /**
1332
+ * Listen for being kicked from a room.
1333
+ * The callback fires when the current user is removed by the room creator.
1334
+ * Room listeners are automatically cleaned up after the kick.
1335
+ *
1336
+ * @example
1337
+ * ```typescript
1338
+ * baasix.realtime.onKicked('game:lobby', ({ kickedBy }) => {
1339
+ * console.log(`You were kicked by user ${kickedBy}`);
1340
+ * });
1341
+ * ```
1342
+ */
1343
+ onKicked(roomName: string, callback: (data: RoomKickEvent) => void): () => void;
1344
+ /**
1345
+ * Listen for room ownership changes (e.g. when the creator leaves).
1346
+ *
1347
+ * @example
1348
+ * ```typescript
1349
+ * baasix.realtime.onRoomCreatorChanged('game:lobby', ({ newCreatorUserId }) => {
1350
+ * console.log(`New room owner: ${newCreatorUserId}`);
1351
+ * });
1352
+ * ```
1353
+ */
1354
+ onRoomCreatorChanged(roomName: string, callback: (data: RoomCreatorChangedEvent) => void): () => void;
1275
1355
  /**
1276
1356
  * Send a message to a room
1277
1357
  *
package/dist/index.js CHANGED
@@ -3291,6 +3291,8 @@ var RealtimeModule = class {
3291
3291
  roomCallbacks = /* @__PURE__ */ new Map();
3292
3292
  // room -> event -> callbacks
3293
3293
  roomUserCallbacks = /* @__PURE__ */ new Map();
3294
+ kickCallbacks = /* @__PURE__ */ new Map();
3295
+ creatorChangedCallbacks = /* @__PURE__ */ new Map();
3294
3296
  connectionCallbacks = /* @__PURE__ */ new Set();
3295
3297
  reconnecting = false;
3296
3298
  connectionPromise = null;
@@ -3420,6 +3422,27 @@ var RealtimeModule = class {
3420
3422
  }
3421
3423
  });
3422
3424
  });
3425
+ this.socket.on("room:kicked", (data) => {
3426
+ const callbacks = this.kickCallbacks.get(data.room);
3427
+ callbacks?.forEach((cb) => {
3428
+ try {
3429
+ cb(data);
3430
+ } catch (e) {
3431
+ console.error("[Baasix Realtime] Error in room kicked callback:", e);
3432
+ }
3433
+ });
3434
+ this.cleanupRoomListeners(data.room);
3435
+ });
3436
+ this.socket.on("room:creator:changed", (data) => {
3437
+ const callbacks = this.creatorChangedCallbacks.get(data.room);
3438
+ callbacks?.forEach((cb) => {
3439
+ try {
3440
+ cb(data);
3441
+ } catch (e) {
3442
+ console.error("[Baasix Realtime] Error in room creator changed callback:", e);
3443
+ }
3444
+ });
3445
+ });
3423
3446
  this.socket.connect();
3424
3447
  } catch (error) {
3425
3448
  this.connectionPromise = null;
@@ -3449,6 +3472,8 @@ var RealtimeModule = class {
3449
3472
  this.workflowCallbacks.clear();
3450
3473
  this.roomCallbacks.clear();
3451
3474
  this.roomUserCallbacks.clear();
3475
+ this.kickCallbacks.clear();
3476
+ this.creatorChangedCallbacks.clear();
3452
3477
  }
3453
3478
  /**
3454
3479
  * Check if connected to the realtime server
@@ -3668,25 +3693,36 @@ var RealtimeModule = class {
3668
3693
  // Custom Rooms API
3669
3694
  // ===================
3670
3695
  /**
3671
- * Join a custom room for real-time communication
3672
- *
3696
+ * Join a custom room for real-time communication.
3697
+ *
3698
+ * You can optionally attach metadata (e.g. display name, avatar, team) that
3699
+ * will be visible to all other members via {@link getRoomMembers} and in
3700
+ * `room:user:joined` events.
3701
+ *
3702
+ * @param roomName - The room to join.
3703
+ * @param metadata - Optional key/value pairs stored alongside this member.
3704
+ *
3673
3705
  * @example
3674
3706
  * ```typescript
3675
- * // Join a room
3676
- * await baasix.realtime.joinRoom('game:lobby');
3677
- *
3678
- * // Listen for messages
3679
- * baasix.realtime.onRoomMessage('game:lobby', 'chat', (data) => {
3680
- * console.log(`${data.sender.userId}: ${data.payload.text}`);
3707
+ * // Join a room with metadata
3708
+ * await baasix.realtime.joinRoom('game:lobby', {
3709
+ * username: 'Alice',
3710
+ * avatar: 'https://example.com/alice.png',
3711
+ * team: 'blue',
3712
+ * });
3713
+ *
3714
+ * // Listen for other users joining (includes their metadata)
3715
+ * baasix.realtime.onUserJoined('game:lobby', (data) => {
3716
+ * console.log(data.metadata.username, 'joined');
3681
3717
  * });
3682
3718
  * ```
3683
3719
  */
3684
- async joinRoom(roomName) {
3720
+ async joinRoom(roomName, metadata = {}) {
3685
3721
  if (!this.socket?.connected) {
3686
3722
  throw new Error("Not connected. Call connect() first.");
3687
3723
  }
3688
3724
  return new Promise((resolve, reject) => {
3689
- this.socket.emit("room:join", { room: roomName }, (response) => {
3725
+ this.socket.emit("room:join", { room: roomName, metadata }, (response) => {
3690
3726
  if (response.status === "success") {
3691
3727
  this.setupRoomListeners(roomName);
3692
3728
  resolve();
@@ -3719,6 +3755,113 @@ var RealtimeModule = class {
3719
3755
  });
3720
3756
  });
3721
3757
  }
3758
+ /**
3759
+ * Get the list of users currently in a room.
3760
+ * You must already be a member of the room to call this.
3761
+ *
3762
+ * Each entry includes `userId`, `socketId`, `isCreator`, and `metadata`
3763
+ * (the custom object the member passed to {@link joinRoom}).
3764
+ *
3765
+ * @example
3766
+ * ```typescript
3767
+ * const members = await baasix.realtime.getRoomMembers('game:lobby');
3768
+ * members.forEach(m => {
3769
+ * console.log(m.metadata.username, m.isCreator ? '(owner)' : '');
3770
+ * });
3771
+ * ```
3772
+ */
3773
+ async getRoomMembers(roomName) {
3774
+ if (!this.socket?.connected) {
3775
+ throw new Error("Not connected. Call connect() first.");
3776
+ }
3777
+ return new Promise((resolve, reject) => {
3778
+ this.socket.emit("room:members", { room: roomName }, (response) => {
3779
+ if (response.status === "success") {
3780
+ resolve(response.members);
3781
+ } else {
3782
+ reject(new Error(response.message || "Failed to get room members"));
3783
+ }
3784
+ });
3785
+ });
3786
+ }
3787
+ /**
3788
+ * Kick a user from a custom room. Only the room creator may call this.
3789
+ *
3790
+ * @example
3791
+ * ```typescript
3792
+ * await baasix.realtime.kickFromRoom('game:lobby', 'user-id-123');
3793
+ * ```
3794
+ */
3795
+ async kickFromRoom(roomName, targetUserId) {
3796
+ if (!this.socket?.connected) {
3797
+ throw new Error("Not connected. Call connect() first.");
3798
+ }
3799
+ return new Promise((resolve, reject) => {
3800
+ this.socket.emit(
3801
+ "room:kick",
3802
+ { room: roomName, userId: targetUserId },
3803
+ (response) => {
3804
+ if (response.status === "success") {
3805
+ resolve();
3806
+ } else {
3807
+ reject(new Error(response.message || "Failed to kick user"));
3808
+ }
3809
+ }
3810
+ );
3811
+ });
3812
+ }
3813
+ /**
3814
+ * Listen for being kicked from a room.
3815
+ * The callback fires when the current user is removed by the room creator.
3816
+ * Room listeners are automatically cleaned up after the kick.
3817
+ *
3818
+ * @example
3819
+ * ```typescript
3820
+ * baasix.realtime.onKicked('game:lobby', ({ kickedBy }) => {
3821
+ * console.log(`You were kicked by user ${kickedBy}`);
3822
+ * });
3823
+ * ```
3824
+ */
3825
+ onKicked(roomName, callback) {
3826
+ if (!this.kickCallbacks.has(roomName)) {
3827
+ this.kickCallbacks.set(roomName, /* @__PURE__ */ new Set());
3828
+ }
3829
+ this.kickCallbacks.get(roomName).add(callback);
3830
+ return () => {
3831
+ const callbacks = this.kickCallbacks.get(roomName);
3832
+ if (callbacks) {
3833
+ callbacks.delete(callback);
3834
+ if (callbacks.size === 0) {
3835
+ this.kickCallbacks.delete(roomName);
3836
+ }
3837
+ }
3838
+ };
3839
+ }
3840
+ /**
3841
+ * Listen for room ownership changes (e.g. when the creator leaves).
3842
+ *
3843
+ * @example
3844
+ * ```typescript
3845
+ * baasix.realtime.onRoomCreatorChanged('game:lobby', ({ newCreatorUserId }) => {
3846
+ * console.log(`New room owner: ${newCreatorUserId}`);
3847
+ * });
3848
+ * ```
3849
+ */
3850
+ onRoomCreatorChanged(roomName, callback) {
3851
+ if (!this.creatorChangedCallbacks.has(roomName)) {
3852
+ this.creatorChangedCallbacks.set(roomName, /* @__PURE__ */ new Set());
3853
+ }
3854
+ this.creatorChangedCallbacks.get(roomName).add(callback);
3855
+ return () => {
3856
+ const callbacks = this.creatorChangedCallbacks.get(roomName);
3857
+ if (callbacks) {
3858
+ callbacks.delete(callback);
3859
+ if (callbacks.size === 0) {
3860
+ this.creatorChangedCallbacks.delete(roomName);
3861
+ }
3862
+ }
3863
+ };
3864
+ }
3722
3865
  /**
3723
3866
  * Send a message to a room
3724
3867
  *
@@ -3871,6 +4014,8 @@ var RealtimeModule = class {
3871
4014
  cleanupRoomListeners(roomName) {
3872
4015
  this.roomCallbacks.delete(roomName);
3873
4016
  this.roomUserCallbacks.delete(roomName);
4017
+ this.kickCallbacks.delete(roomName);
4018
+ this.creatorChangedCallbacks.delete(roomName);
3874
4019
  }
3875
4020
  // ===================
3876
4021
  // Channel (Room) API - Supabase-style