@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/README.md +51 -0
- package/dist/index.cjs +155 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +87 -7
- package/dist/index.d.ts +87 -7
- package/dist/index.js +155 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1053,6 +1053,57 @@ 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 — pass optional metadata stored alongside your membership
|
|
1062
|
+
await baasix.realtime.joinRoom('game:lobby', {
|
|
1063
|
+
username: 'Alice',
|
|
1064
|
+
avatar: 'https://example.com/alice.png',
|
|
1065
|
+
team: 'blue',
|
|
1066
|
+
});
|
|
1067
|
+
|
|
1068
|
+
// Get current members (you must be in the room)
|
|
1069
|
+
// Each entry includes userId, socketId, isCreator, and metadata
|
|
1070
|
+
const members = await baasix.realtime.getRoomMembers('game:lobby');
|
|
1071
|
+
// [{ socketId: string, userId: string|number, isCreator: boolean, metadata: Record<string,any> }, ...]
|
|
1072
|
+
|
|
1073
|
+
// Send a message to all room members
|
|
1074
|
+
await baasix.realtime.sendToRoom('game:lobby', 'chat', { text: 'Hello!' });
|
|
1075
|
+
|
|
1076
|
+
// Listen for room messages
|
|
1077
|
+
const unsubscribe = baasix.realtime.onRoomMessage('game:lobby', 'chat', (data) => {
|
|
1078
|
+
console.log(`${data.sender.userId}: ${data.payload.text}`);
|
|
1079
|
+
});
|
|
1080
|
+
|
|
1081
|
+
// Listen for users joining / leaving (joined event includes their metadata)
|
|
1082
|
+
baasix.realtime.onRoomUserJoined('game:lobby', (data) => {
|
|
1083
|
+
console.log(`${data.metadata.username} joined`);
|
|
1084
|
+
});
|
|
1085
|
+
baasix.realtime.onRoomUserLeft('game:lobby', (data) => {
|
|
1086
|
+
console.log(`${data.userId} left`);
|
|
1087
|
+
});
|
|
1088
|
+
|
|
1089
|
+
// Kick a user — only the room creator can do this
|
|
1090
|
+
await baasix.realtime.kickFromRoom('game:lobby', 'target-user-id');
|
|
1091
|
+
|
|
1092
|
+
// Listen for being kicked out (fires only on the kicked user's socket)
|
|
1093
|
+
baasix.realtime.onKicked('game:lobby', ({ kickedBy }) => {
|
|
1094
|
+
console.log(`You were kicked by user ${kickedBy}`);
|
|
1095
|
+
// Room listeners are automatically cleaned up after a kick
|
|
1096
|
+
});
|
|
1097
|
+
|
|
1098
|
+
// Listen for ownership changes (fires for all members when creator changes)
|
|
1099
|
+
baasix.realtime.onRoomCreatorChanged('game:lobby', ({ newCreatorUserId }) => {
|
|
1100
|
+
console.log(`New room owner: ${newCreatorUserId}`);
|
|
1101
|
+
});
|
|
1102
|
+
|
|
1103
|
+
// Leave the room
|
|
1104
|
+
await baasix.realtime.leaveRoom('game:lobby');
|
|
1105
|
+
```
|
|
1106
|
+
|
|
1056
1107
|
### Connection Management
|
|
1057
1108
|
|
|
1058
1109
|
```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
|
|
@@ -3670,25 +3695,36 @@ var RealtimeModule = class {
|
|
|
3670
3695
|
// Custom Rooms API
|
|
3671
3696
|
// ===================
|
|
3672
3697
|
/**
|
|
3673
|
-
* Join a custom room for real-time communication
|
|
3674
|
-
*
|
|
3698
|
+
* Join a custom room for real-time communication.
|
|
3699
|
+
*
|
|
3700
|
+
* You can optionally attach metadata (e.g. display name, avatar, team) that
|
|
3701
|
+
* will be visible to all other members via {@link getRoomMembers} and in
|
|
3702
|
+
* `room:user:joined` events.
|
|
3703
|
+
*
|
|
3704
|
+
* @param roomName - The room to join.
|
|
3705
|
+
* @param metadata - Optional key/value pairs stored alongside this member.
|
|
3706
|
+
*
|
|
3675
3707
|
* @example
|
|
3676
3708
|
* ```typescript
|
|
3677
|
-
* // Join a room
|
|
3678
|
-
* await baasix.realtime.joinRoom('game:lobby'
|
|
3679
|
-
*
|
|
3680
|
-
*
|
|
3681
|
-
*
|
|
3682
|
-
*
|
|
3709
|
+
* // Join a room with metadata
|
|
3710
|
+
* await baasix.realtime.joinRoom('game:lobby', {
|
|
3711
|
+
* username: 'Alice',
|
|
3712
|
+
* avatar: 'https://example.com/alice.png',
|
|
3713
|
+
* team: 'blue',
|
|
3714
|
+
* });
|
|
3715
|
+
*
|
|
3716
|
+
* // Listen for other users joining (includes their metadata)
|
|
3717
|
+
* baasix.realtime.onUserJoined('game:lobby', (data) => {
|
|
3718
|
+
* console.log(data.metadata.username, 'joined');
|
|
3683
3719
|
* });
|
|
3684
3720
|
* ```
|
|
3685
3721
|
*/
|
|
3686
|
-
async joinRoom(roomName) {
|
|
3722
|
+
async joinRoom(roomName, metadata = {}) {
|
|
3687
3723
|
if (!this.socket?.connected) {
|
|
3688
3724
|
throw new Error("Not connected. Call connect() first.");
|
|
3689
3725
|
}
|
|
3690
3726
|
return new Promise((resolve, reject) => {
|
|
3691
|
-
this.socket.emit("room:join", { room: roomName }, (response) => {
|
|
3727
|
+
this.socket.emit("room:join", { room: roomName, metadata }, (response) => {
|
|
3692
3728
|
if (response.status === "success") {
|
|
3693
3729
|
this.setupRoomListeners(roomName);
|
|
3694
3730
|
resolve();
|
|
@@ -3721,6 +3757,113 @@ var RealtimeModule = class {
|
|
|
3721
3757
|
});
|
|
3722
3758
|
});
|
|
3723
3759
|
}
|
|
3760
|
+
/**
|
|
3761
|
+
* Get the list of users currently in a room.
|
|
3762
|
+
* You must already be a member of the room to call this.
|
|
3763
|
+
*
|
|
3764
|
+
* Each entry includes `userId`, `socketId`, `isCreator`, and `metadata`
|
|
3765
|
+
* (the custom object the member passed to {@link joinRoom}).
|
|
3766
|
+
*
|
|
3767
|
+
* @example
|
|
3768
|
+
* ```typescript
|
|
3769
|
+
* const members = await baasix.realtime.getRoomMembers('game:lobby');
|
|
3770
|
+
* members.forEach(m => {
|
|
3771
|
+
* console.log(m.metadata.username, m.isCreator ? '(owner)' : '');
|
|
3772
|
+
* });
|
|
3773
|
+
* ```
|
|
3774
|
+
*/
|
|
3775
|
+
async getRoomMembers(roomName) {
|
|
3776
|
+
if (!this.socket?.connected) {
|
|
3777
|
+
throw new Error("Not connected. Call connect() first.");
|
|
3778
|
+
}
|
|
3779
|
+
return new Promise((resolve, reject) => {
|
|
3780
|
+
this.socket.emit("room:members", { room: roomName }, (response) => {
|
|
3781
|
+
if (response.status === "success") {
|
|
3782
|
+
resolve(response.members);
|
|
3783
|
+
} else {
|
|
3784
|
+
reject(new Error(response.message || "Failed to get room members"));
|
|
3785
|
+
}
|
|
3786
|
+
});
|
|
3787
|
+
});
|
|
3788
|
+
}
|
|
3789
|
+
/**
|
|
3790
|
+
* Kick a user from a custom room. Only the room creator may call this.
|
|
3791
|
+
*
|
|
3792
|
+
* @example
|
|
3793
|
+
* ```typescript
|
|
3794
|
+
* await baasix.realtime.kickFromRoom('game:lobby', 'user-id-123');
|
|
3795
|
+
* ```
|
|
3796
|
+
*/
|
|
3797
|
+
async kickFromRoom(roomName, targetUserId) {
|
|
3798
|
+
if (!this.socket?.connected) {
|
|
3799
|
+
throw new Error("Not connected. Call connect() first.");
|
|
3800
|
+
}
|
|
3801
|
+
return new Promise((resolve, reject) => {
|
|
3802
|
+
this.socket.emit(
|
|
3803
|
+
"room:kick",
|
|
3804
|
+
{ room: roomName, userId: targetUserId },
|
|
3805
|
+
(response) => {
|
|
3806
|
+
if (response.status === "success") {
|
|
3807
|
+
resolve();
|
|
3808
|
+
} else {
|
|
3809
|
+
reject(new Error(response.message || "Failed to kick user"));
|
|
3810
|
+
}
|
|
3811
|
+
}
|
|
3812
|
+
);
|
|
3813
|
+
});
|
|
3814
|
+
}
|
|
3815
|
+
/**
|
|
3816
|
+
* Listen for being kicked from a room.
|
|
3817
|
+
* The callback fires when the current user is removed by the room creator.
|
|
3818
|
+
* Room listeners are automatically cleaned up after the kick.
|
|
3819
|
+
*
|
|
3820
|
+
* @example
|
|
3821
|
+
* ```typescript
|
|
3822
|
+
* baasix.realtime.onKicked('game:lobby', ({ kickedBy }) => {
|
|
3823
|
+
* console.log(`You were kicked by user ${kickedBy}`);
|
|
3824
|
+
* });
|
|
3825
|
+
* ```
|
|
3826
|
+
*/
|
|
3827
|
+
onKicked(roomName, callback) {
|
|
3828
|
+
if (!this.kickCallbacks.has(roomName)) {
|
|
3829
|
+
this.kickCallbacks.set(roomName, /* @__PURE__ */ new Set());
|
|
3830
|
+
}
|
|
3831
|
+
this.kickCallbacks.get(roomName).add(callback);
|
|
3832
|
+
return () => {
|
|
3833
|
+
const callbacks = this.kickCallbacks.get(roomName);
|
|
3834
|
+
if (callbacks) {
|
|
3835
|
+
callbacks.delete(callback);
|
|
3836
|
+
if (callbacks.size === 0) {
|
|
3837
|
+
this.kickCallbacks.delete(roomName);
|
|
3838
|
+
}
|
|
3839
|
+
}
|
|
3840
|
+
};
|
|
3841
|
+
}
|
|
3842
|
+
/**
|
|
3843
|
+
* Listen for room ownership changes (e.g. when the creator leaves).
|
|
3844
|
+
*
|
|
3845
|
+
* @example
|
|
3846
|
+
* ```typescript
|
|
3847
|
+
* baasix.realtime.onRoomCreatorChanged('game:lobby', ({ newCreatorUserId }) => {
|
|
3848
|
+
* console.log(`New room owner: ${newCreatorUserId}`);
|
|
3849
|
+
* });
|
|
3850
|
+
* ```
|
|
3851
|
+
*/
|
|
3852
|
+
onRoomCreatorChanged(roomName, callback) {
|
|
3853
|
+
if (!this.creatorChangedCallbacks.has(roomName)) {
|
|
3854
|
+
this.creatorChangedCallbacks.set(roomName, /* @__PURE__ */ new Set());
|
|
3855
|
+
}
|
|
3856
|
+
this.creatorChangedCallbacks.get(roomName).add(callback);
|
|
3857
|
+
return () => {
|
|
3858
|
+
const callbacks = this.creatorChangedCallbacks.get(roomName);
|
|
3859
|
+
if (callbacks) {
|
|
3860
|
+
callbacks.delete(callback);
|
|
3861
|
+
if (callbacks.size === 0) {
|
|
3862
|
+
this.creatorChangedCallbacks.delete(roomName);
|
|
3863
|
+
}
|
|
3864
|
+
}
|
|
3865
|
+
};
|
|
3866
|
+
}
|
|
3724
3867
|
/**
|
|
3725
3868
|
* Send a message to a room
|
|
3726
3869
|
*
|
|
@@ -3873,6 +4016,8 @@ var RealtimeModule = class {
|
|
|
3873
4016
|
cleanupRoomListeners(roomName) {
|
|
3874
4017
|
this.roomCallbacks.delete(roomName);
|
|
3875
4018
|
this.roomUserCallbacks.delete(roomName);
|
|
4019
|
+
this.kickCallbacks.delete(roomName);
|
|
4020
|
+
this.creatorChangedCallbacks.delete(roomName);
|
|
3876
4021
|
}
|
|
3877
4022
|
// ===================
|
|
3878
4023
|
// Channel (Room) API - Supabase-style
|