@baasix/sdk 0.1.7 → 0.1.8
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 +46 -0
- package/dist/index.cjs +131 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +64 -0
- package/dist/index.d.ts +64 -0
- package/dist/index.js +131 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1053,6 +1053,52 @@ const channel = baasix.realtime
|
|
|
1053
1053
|
channel.unsubscribe();
|
|
1054
1054
|
```
|
|
1055
1055
|
|
|
1056
|
+
### Custom Rooms
|
|
1057
|
+
|
|
1058
|
+
Custom rooms enable real-time communication between users for chat, games, or collaborative features. The **first user to join** a room becomes its creator. If the creator leaves temporarily, ownership transfers to the next member — but the **original creator automatically reclaims ownership** when they rejoin. If the room empties and is recreated, the next joiner becomes the new owner.
|
|
1059
|
+
|
|
1060
|
+
```typescript
|
|
1061
|
+
// Join a room
|
|
1062
|
+
await baasix.realtime.joinRoom('game:lobby');
|
|
1063
|
+
|
|
1064
|
+
// Get current members (you must be in the room)
|
|
1065
|
+
const members = await baasix.realtime.getRoomMembers('game:lobby');
|
|
1066
|
+
// [{ socketId: string, userId: string|number, isCreator: boolean }, ...]
|
|
1067
|
+
|
|
1068
|
+
// Send a message to all room members
|
|
1069
|
+
await baasix.realtime.sendToRoom('game:lobby', 'chat', { text: 'Hello!' });
|
|
1070
|
+
|
|
1071
|
+
// Listen for room messages
|
|
1072
|
+
const unsubscribe = baasix.realtime.onRoomMessage('game:lobby', 'chat', (data) => {
|
|
1073
|
+
console.log(`${data.sender.userId}: ${data.payload.text}`);
|
|
1074
|
+
});
|
|
1075
|
+
|
|
1076
|
+
// Listen for users joining / leaving
|
|
1077
|
+
baasix.realtime.onRoomUserJoined('game:lobby', (data) => {
|
|
1078
|
+
console.log(`${data.userId} joined`);
|
|
1079
|
+
});
|
|
1080
|
+
baasix.realtime.onRoomUserLeft('game:lobby', (data) => {
|
|
1081
|
+
console.log(`${data.userId} left`);
|
|
1082
|
+
});
|
|
1083
|
+
|
|
1084
|
+
// Kick a user — only the room creator can do this
|
|
1085
|
+
await baasix.realtime.kickFromRoom('game:lobby', 'target-user-id');
|
|
1086
|
+
|
|
1087
|
+
// Listen for being kicked out (fires only on the kicked user's socket)
|
|
1088
|
+
baasix.realtime.onKicked('game:lobby', ({ kickedBy }) => {
|
|
1089
|
+
console.log(`You were kicked by user ${kickedBy}`);
|
|
1090
|
+
// Room listeners are automatically cleaned up after a kick
|
|
1091
|
+
});
|
|
1092
|
+
|
|
1093
|
+
// Listen for ownership changes (fires for all members when creator changes)
|
|
1094
|
+
baasix.realtime.onRoomCreatorChanged('game:lobby', ({ newCreatorUserId }) => {
|
|
1095
|
+
console.log(`New room owner: ${newCreatorUserId}`);
|
|
1096
|
+
});
|
|
1097
|
+
|
|
1098
|
+
// Leave the room
|
|
1099
|
+
await baasix.realtime.leaveRoom('game:lobby');
|
|
1100
|
+
```
|
|
1101
|
+
|
|
1056
1102
|
### Connection Management
|
|
1057
1103
|
|
|
1058
1104
|
```typescript
|
package/dist/index.cjs
CHANGED
|
@@ -3293,6 +3293,8 @@ var RealtimeModule = class {
|
|
|
3293
3293
|
roomCallbacks = /* @__PURE__ */ new Map();
|
|
3294
3294
|
// room -> event -> callbacks
|
|
3295
3295
|
roomUserCallbacks = /* @__PURE__ */ new Map();
|
|
3296
|
+
kickCallbacks = /* @__PURE__ */ new Map();
|
|
3297
|
+
creatorChangedCallbacks = /* @__PURE__ */ new Map();
|
|
3296
3298
|
connectionCallbacks = /* @__PURE__ */ new Set();
|
|
3297
3299
|
reconnecting = false;
|
|
3298
3300
|
connectionPromise = null;
|
|
@@ -3422,6 +3424,27 @@ var RealtimeModule = class {
|
|
|
3422
3424
|
}
|
|
3423
3425
|
});
|
|
3424
3426
|
});
|
|
3427
|
+
this.socket.on("room:kicked", (data) => {
|
|
3428
|
+
const callbacks = this.kickCallbacks.get(data.room);
|
|
3429
|
+
callbacks?.forEach((cb) => {
|
|
3430
|
+
try {
|
|
3431
|
+
cb(data);
|
|
3432
|
+
} catch (e) {
|
|
3433
|
+
console.error("[Baasix Realtime] Error in room kicked callback:", e);
|
|
3434
|
+
}
|
|
3435
|
+
});
|
|
3436
|
+
this.cleanupRoomListeners(data.room);
|
|
3437
|
+
});
|
|
3438
|
+
this.socket.on("room:creator:changed", (data) => {
|
|
3439
|
+
const callbacks = this.creatorChangedCallbacks.get(data.room);
|
|
3440
|
+
callbacks?.forEach((cb) => {
|
|
3441
|
+
try {
|
|
3442
|
+
cb(data);
|
|
3443
|
+
} catch (e) {
|
|
3444
|
+
console.error("[Baasix Realtime] Error in room creator changed callback:", e);
|
|
3445
|
+
}
|
|
3446
|
+
});
|
|
3447
|
+
});
|
|
3425
3448
|
this.socket.connect();
|
|
3426
3449
|
} catch (error) {
|
|
3427
3450
|
this.connectionPromise = null;
|
|
@@ -3451,6 +3474,8 @@ var RealtimeModule = class {
|
|
|
3451
3474
|
this.workflowCallbacks.clear();
|
|
3452
3475
|
this.roomCallbacks.clear();
|
|
3453
3476
|
this.roomUserCallbacks.clear();
|
|
3477
|
+
this.kickCallbacks.clear();
|
|
3478
|
+
this.creatorChangedCallbacks.clear();
|
|
3454
3479
|
}
|
|
3455
3480
|
/**
|
|
3456
3481
|
* Check if connected to the realtime server
|
|
@@ -3721,6 +3746,110 @@ var RealtimeModule = class {
|
|
|
3721
3746
|
});
|
|
3722
3747
|
});
|
|
3723
3748
|
}
|
|
3749
|
+
/**
|
|
3750
|
+
* Get the list of users currently in a room.
|
|
3751
|
+
* You must already be a member of the room to call this.
|
|
3752
|
+
*
|
|
3753
|
+
* @example
|
|
3754
|
+
* ```typescript
|
|
3755
|
+
* const members = await baasix.realtime.getRoomMembers('game:lobby');
|
|
3756
|
+
* members.forEach(m => {
|
|
3757
|
+
* console.log(m.userId, m.isCreator ? '(owner)' : '');
|
|
3758
|
+
* });
|
|
3759
|
+
* ```
|
|
3760
|
+
*/
|
|
3761
|
+
async getRoomMembers(roomName) {
|
|
3762
|
+
if (!this.socket?.connected) {
|
|
3763
|
+
throw new Error("Not connected. Call connect() first.");
|
|
3764
|
+
}
|
|
3765
|
+
return new Promise((resolve, reject) => {
|
|
3766
|
+
this.socket.emit("room:members", { room: roomName }, (response) => {
|
|
3767
|
+
if (response.status === "success") {
|
|
3768
|
+
resolve(response.members);
|
|
3769
|
+
} else {
|
|
3770
|
+
reject(new Error(response.message || "Failed to get room members"));
|
|
3771
|
+
}
|
|
3772
|
+
});
|
|
3773
|
+
});
|
|
3774
|
+
}
|
|
3775
|
+
/**
|
|
3776
|
+
* Kick a user from a custom room. Only the room creator may call this.
|
|
3777
|
+
*
|
|
3778
|
+
* @example
|
|
3779
|
+
* ```typescript
|
|
3780
|
+
* await baasix.realtime.kickFromRoom('game:lobby', 'user-id-123');
|
|
3781
|
+
* ```
|
|
3782
|
+
*/
|
|
3783
|
+
async kickFromRoom(roomName, targetUserId) {
|
|
3784
|
+
if (!this.socket?.connected) {
|
|
3785
|
+
throw new Error("Not connected. Call connect() first.");
|
|
3786
|
+
}
|
|
3787
|
+
return new Promise((resolve, reject) => {
|
|
3788
|
+
this.socket.emit(
|
|
3789
|
+
"room:kick",
|
|
3790
|
+
{ room: roomName, userId: targetUserId },
|
|
3791
|
+
(response) => {
|
|
3792
|
+
if (response.status === "success") {
|
|
3793
|
+
resolve();
|
|
3794
|
+
} else {
|
|
3795
|
+
reject(new Error(response.message || "Failed to kick user"));
|
|
3796
|
+
}
|
|
3797
|
+
}
|
|
3798
|
+
);
|
|
3799
|
+
});
|
|
3800
|
+
}
|
|
3801
|
+
/**
|
|
3802
|
+
* Listen for being kicked from a room.
|
|
3803
|
+
* The callback fires when the current user is removed by the room creator.
|
|
3804
|
+
* Room listeners are automatically cleaned up after the kick.
|
|
3805
|
+
*
|
|
3806
|
+
* @example
|
|
3807
|
+
* ```typescript
|
|
3808
|
+
* baasix.realtime.onKicked('game:lobby', ({ kickedBy }) => {
|
|
3809
|
+
* console.log(`You were kicked by user ${kickedBy}`);
|
|
3810
|
+
* });
|
|
3811
|
+
* ```
|
|
3812
|
+
*/
|
|
3813
|
+
onKicked(roomName, callback) {
|
|
3814
|
+
if (!this.kickCallbacks.has(roomName)) {
|
|
3815
|
+
this.kickCallbacks.set(roomName, /* @__PURE__ */ new Set());
|
|
3816
|
+
}
|
|
3817
|
+
this.kickCallbacks.get(roomName).add(callback);
|
|
3818
|
+
return () => {
|
|
3819
|
+
const callbacks = this.kickCallbacks.get(roomName);
|
|
3820
|
+
if (callbacks) {
|
|
3821
|
+
callbacks.delete(callback);
|
|
3822
|
+
if (callbacks.size === 0) {
|
|
3823
|
+
this.kickCallbacks.delete(roomName);
|
|
3824
|
+
}
|
|
3825
|
+
}
|
|
3826
|
+
};
|
|
3827
|
+
}
|
|
3828
|
+
/**
|
|
3829
|
+
* Listen for room ownership changes (e.g. when the creator leaves).
|
|
3830
|
+
*
|
|
3831
|
+
* @example
|
|
3832
|
+
* ```typescript
|
|
3833
|
+
* baasix.realtime.onRoomCreatorChanged('game:lobby', ({ newCreatorUserId }) => {
|
|
3834
|
+
* console.log(`New room owner: ${newCreatorUserId}`);
|
|
3835
|
+
* });
|
|
3836
|
+
* ```
|
|
3837
|
+
*/
|
|
3838
|
+
onRoomCreatorChanged(roomName, callback) {
|
|
3839
|
+
if (!this.creatorChangedCallbacks.has(roomName)) {
|
|
3840
|
+
this.creatorChangedCallbacks.set(roomName, /* @__PURE__ */ new Set());
|
|
3841
|
+
}
|
|
3842
|
+
this.creatorChangedCallbacks.get(roomName).add(callback);
|
|
3843
|
+
return () => {
|
|
3844
|
+
const callbacks = this.creatorChangedCallbacks.get(roomName);
|
|
3845
|
+
if (callbacks) {
|
|
3846
|
+
callbacks.delete(callback);
|
|
3847
|
+
if (callbacks.size === 0) {
|
|
3848
|
+
this.creatorChangedCallbacks.delete(roomName);
|
|
3849
|
+
}
|
|
3850
|
+
}
|
|
3851
|
+
};
|
|
3852
|
+
}
|
|
3724
3853
|
/**
|
|
3725
3854
|
* Send a message to a room
|
|
3726
3855
|
*
|
|
@@ -3873,6 +4002,8 @@ var RealtimeModule = class {
|
|
|
3873
4002
|
cleanupRoomListeners(roomName) {
|
|
3874
4003
|
this.roomCallbacks.delete(roomName);
|
|
3875
4004
|
this.roomUserCallbacks.delete(roomName);
|
|
4005
|
+
this.kickCallbacks.delete(roomName);
|
|
4006
|
+
this.creatorChangedCallbacks.delete(roomName);
|
|
3876
4007
|
}
|
|
3877
4008
|
// ===================
|
|
3878
4009
|
// Channel (Room) API - Supabase-style
|