@defcomm/meetingsdk 0.4.3 → 0.4.5
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.mts +46 -11
- package/dist/index.d.ts +46 -11
- package/dist/index.js +120 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +131 -18
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -59,6 +59,34 @@ type ChatMessage = {
|
|
|
59
59
|
} | null;
|
|
60
60
|
target?: string | null;
|
|
61
61
|
};
|
|
62
|
+
type PubSubMessage<T = unknown> = {
|
|
63
|
+
id: string;
|
|
64
|
+
topic: PubSubTopic;
|
|
65
|
+
sender_id: string;
|
|
66
|
+
sender_name?: string | null;
|
|
67
|
+
timestamp: number;
|
|
68
|
+
data: T;
|
|
69
|
+
};
|
|
70
|
+
type PubSubTopicConfig = {
|
|
71
|
+
SECURE_CHAT: {
|
|
72
|
+
publish: ChatInput;
|
|
73
|
+
message: ChatMessage;
|
|
74
|
+
};
|
|
75
|
+
REACTION: {
|
|
76
|
+
publish: {
|
|
77
|
+
emoji: string;
|
|
78
|
+
};
|
|
79
|
+
message: {
|
|
80
|
+
emoji: string;
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
type PubSubTopic = keyof PubSubTopicConfig;
|
|
85
|
+
type PubSubHandle<TPublish = unknown, TMessage = TPublish> = {
|
|
86
|
+
messages: PubSubMessage<TMessage>[];
|
|
87
|
+
publish: (data: TPublish) => void;
|
|
88
|
+
};
|
|
89
|
+
type PubSubHandleForTopic<T extends PubSubTopic> = PubSubHandle<PubSubTopicConfig[T]["publish"], PubSubTopicConfig[T]["message"]>;
|
|
62
90
|
type Participant = {
|
|
63
91
|
id: string;
|
|
64
92
|
name?: string;
|
|
@@ -97,7 +125,6 @@ type MeetingConfig = {
|
|
|
97
125
|
videoMuted?: boolean;
|
|
98
126
|
token?: string;
|
|
99
127
|
};
|
|
100
|
-
type PubSubTopic = "SECURE_CHAT" | "REACTION";
|
|
101
128
|
type RecordingInfo = {
|
|
102
129
|
recording_id: string;
|
|
103
130
|
started_at?: string;
|
|
@@ -241,6 +268,15 @@ declare class VideoSDKCore {
|
|
|
241
268
|
}>;
|
|
242
269
|
sendChatMessage(payload: ChatInput): void;
|
|
243
270
|
sendReaction(reaction: string): void;
|
|
271
|
+
/**
|
|
272
|
+
* Generic PubSub publishing entry point.
|
|
273
|
+
*
|
|
274
|
+
* The public SDK exposes one PubSub API for all topics. The current SFU
|
|
275
|
+
* protocol still has dedicated wire messages for chat and reactions, so
|
|
276
|
+
* this method is the compatibility bridge. The application does not need
|
|
277
|
+
* to know about those wire-level message types.
|
|
278
|
+
*/
|
|
279
|
+
publishPubSub<T extends PubSubTopic>(topic: T, data: PubSubTopicConfig[T]["publish"]): void;
|
|
244
280
|
private cleanupRemoteParticipant;
|
|
245
281
|
disconnect(): Promise<void>;
|
|
246
282
|
private performDisconnect;
|
|
@@ -263,10 +299,6 @@ interface ParticipantInfo {
|
|
|
263
299
|
[key: string]: any;
|
|
264
300
|
}
|
|
265
301
|
|
|
266
|
-
type PubSubHandle = {
|
|
267
|
-
messages: ChatMessage[];
|
|
268
|
-
publish: (input: ChatInput) => void;
|
|
269
|
-
};
|
|
270
302
|
type MeetingContextValue = {
|
|
271
303
|
sdk: VideoSDKCore;
|
|
272
304
|
join: (config?: Omit<MeetingConfig, "participantId">) => Promise<void>;
|
|
@@ -296,7 +328,8 @@ type MeetingContextValue = {
|
|
|
296
328
|
presenterId: string | null;
|
|
297
329
|
activeSpeakerIds: string[];
|
|
298
330
|
recording: RecordingInfo | null;
|
|
299
|
-
usePubSub: (topic:
|
|
331
|
+
usePubSub: <T extends PubSubTopic>(topic: T) => PubSubHandleForTopic<T>;
|
|
332
|
+
onPubSubMessage: <T extends PubSubTopic>(topic: T, cb: (message: PubSubMessage<PubSubTopicConfig[T]["message"]>) => void) => () => void;
|
|
300
333
|
approveJoinRequest: (requestId: string) => void;
|
|
301
334
|
rejectJoinRequest: (requestId: string) => void;
|
|
302
335
|
startRecording: () => Promise<void>;
|
|
@@ -358,10 +391,8 @@ declare const useMeeting: (handlers?: {
|
|
|
358
391
|
presenterId: string | null;
|
|
359
392
|
activeSpeakerIds: string[];
|
|
360
393
|
recording: RecordingInfo | null;
|
|
361
|
-
usePubSub: (topic:
|
|
362
|
-
|
|
363
|
-
publish: (input: ChatInput) => void;
|
|
364
|
-
};
|
|
394
|
+
usePubSub: <T extends PubSubTopic>(topic: T) => PubSubHandleForTopic<T>;
|
|
395
|
+
onPubSubMessage: <T extends PubSubTopic>(topic: T, cb: (message: PubSubMessage<PubSubTopicConfig[T]["message"]>) => void) => () => void;
|
|
365
396
|
approveJoinRequest: (requestId: string) => void;
|
|
366
397
|
rejectJoinRequest: (requestId: string) => void;
|
|
367
398
|
startRecording: () => Promise<void>;
|
|
@@ -456,4 +487,8 @@ declare class ActiveSpeakerDetector {
|
|
|
456
487
|
destroy(): Promise<void>;
|
|
457
488
|
}
|
|
458
489
|
|
|
459
|
-
|
|
490
|
+
declare function usePubSub<T extends PubSubTopic>(topic: T, options?: {
|
|
491
|
+
onMessageReceived?: (message: PubSubMessage<PubSubTopicConfig[T]["message"]>) => void;
|
|
492
|
+
}): PubSubHandleForTopic<T>;
|
|
493
|
+
|
|
494
|
+
export { ActiveSpeakerDetector, type ChatInput, type MeetingConfig, MeetingProvider, MeetingState, type Participant, type ParticipantInfo, type PubSubHandle, type PubSubHandleForTopic, type PubSubMessage, type PubSubTopic, type PubSubTopicConfig, type Reaction, type RecordingInfo, type SFUConnectionState, type TrackInfo, VideoSDKCore, useLocalParticipant, useMeeting, useMeetingContext, useMeetingPreview, useParticipants, usePubSub, useRemoteMedia };
|
package/dist/index.d.ts
CHANGED
|
@@ -59,6 +59,34 @@ type ChatMessage = {
|
|
|
59
59
|
} | null;
|
|
60
60
|
target?: string | null;
|
|
61
61
|
};
|
|
62
|
+
type PubSubMessage<T = unknown> = {
|
|
63
|
+
id: string;
|
|
64
|
+
topic: PubSubTopic;
|
|
65
|
+
sender_id: string;
|
|
66
|
+
sender_name?: string | null;
|
|
67
|
+
timestamp: number;
|
|
68
|
+
data: T;
|
|
69
|
+
};
|
|
70
|
+
type PubSubTopicConfig = {
|
|
71
|
+
SECURE_CHAT: {
|
|
72
|
+
publish: ChatInput;
|
|
73
|
+
message: ChatMessage;
|
|
74
|
+
};
|
|
75
|
+
REACTION: {
|
|
76
|
+
publish: {
|
|
77
|
+
emoji: string;
|
|
78
|
+
};
|
|
79
|
+
message: {
|
|
80
|
+
emoji: string;
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
type PubSubTopic = keyof PubSubTopicConfig;
|
|
85
|
+
type PubSubHandle<TPublish = unknown, TMessage = TPublish> = {
|
|
86
|
+
messages: PubSubMessage<TMessage>[];
|
|
87
|
+
publish: (data: TPublish) => void;
|
|
88
|
+
};
|
|
89
|
+
type PubSubHandleForTopic<T extends PubSubTopic> = PubSubHandle<PubSubTopicConfig[T]["publish"], PubSubTopicConfig[T]["message"]>;
|
|
62
90
|
type Participant = {
|
|
63
91
|
id: string;
|
|
64
92
|
name?: string;
|
|
@@ -97,7 +125,6 @@ type MeetingConfig = {
|
|
|
97
125
|
videoMuted?: boolean;
|
|
98
126
|
token?: string;
|
|
99
127
|
};
|
|
100
|
-
type PubSubTopic = "SECURE_CHAT" | "REACTION";
|
|
101
128
|
type RecordingInfo = {
|
|
102
129
|
recording_id: string;
|
|
103
130
|
started_at?: string;
|
|
@@ -241,6 +268,15 @@ declare class VideoSDKCore {
|
|
|
241
268
|
}>;
|
|
242
269
|
sendChatMessage(payload: ChatInput): void;
|
|
243
270
|
sendReaction(reaction: string): void;
|
|
271
|
+
/**
|
|
272
|
+
* Generic PubSub publishing entry point.
|
|
273
|
+
*
|
|
274
|
+
* The public SDK exposes one PubSub API for all topics. The current SFU
|
|
275
|
+
* protocol still has dedicated wire messages for chat and reactions, so
|
|
276
|
+
* this method is the compatibility bridge. The application does not need
|
|
277
|
+
* to know about those wire-level message types.
|
|
278
|
+
*/
|
|
279
|
+
publishPubSub<T extends PubSubTopic>(topic: T, data: PubSubTopicConfig[T]["publish"]): void;
|
|
244
280
|
private cleanupRemoteParticipant;
|
|
245
281
|
disconnect(): Promise<void>;
|
|
246
282
|
private performDisconnect;
|
|
@@ -263,10 +299,6 @@ interface ParticipantInfo {
|
|
|
263
299
|
[key: string]: any;
|
|
264
300
|
}
|
|
265
301
|
|
|
266
|
-
type PubSubHandle = {
|
|
267
|
-
messages: ChatMessage[];
|
|
268
|
-
publish: (input: ChatInput) => void;
|
|
269
|
-
};
|
|
270
302
|
type MeetingContextValue = {
|
|
271
303
|
sdk: VideoSDKCore;
|
|
272
304
|
join: (config?: Omit<MeetingConfig, "participantId">) => Promise<void>;
|
|
@@ -296,7 +328,8 @@ type MeetingContextValue = {
|
|
|
296
328
|
presenterId: string | null;
|
|
297
329
|
activeSpeakerIds: string[];
|
|
298
330
|
recording: RecordingInfo | null;
|
|
299
|
-
usePubSub: (topic:
|
|
331
|
+
usePubSub: <T extends PubSubTopic>(topic: T) => PubSubHandleForTopic<T>;
|
|
332
|
+
onPubSubMessage: <T extends PubSubTopic>(topic: T, cb: (message: PubSubMessage<PubSubTopicConfig[T]["message"]>) => void) => () => void;
|
|
300
333
|
approveJoinRequest: (requestId: string) => void;
|
|
301
334
|
rejectJoinRequest: (requestId: string) => void;
|
|
302
335
|
startRecording: () => Promise<void>;
|
|
@@ -358,10 +391,8 @@ declare const useMeeting: (handlers?: {
|
|
|
358
391
|
presenterId: string | null;
|
|
359
392
|
activeSpeakerIds: string[];
|
|
360
393
|
recording: RecordingInfo | null;
|
|
361
|
-
usePubSub: (topic:
|
|
362
|
-
|
|
363
|
-
publish: (input: ChatInput) => void;
|
|
364
|
-
};
|
|
394
|
+
usePubSub: <T extends PubSubTopic>(topic: T) => PubSubHandleForTopic<T>;
|
|
395
|
+
onPubSubMessage: <T extends PubSubTopic>(topic: T, cb: (message: PubSubMessage<PubSubTopicConfig[T]["message"]>) => void) => () => void;
|
|
365
396
|
approveJoinRequest: (requestId: string) => void;
|
|
366
397
|
rejectJoinRequest: (requestId: string) => void;
|
|
367
398
|
startRecording: () => Promise<void>;
|
|
@@ -456,4 +487,8 @@ declare class ActiveSpeakerDetector {
|
|
|
456
487
|
destroy(): Promise<void>;
|
|
457
488
|
}
|
|
458
489
|
|
|
459
|
-
|
|
490
|
+
declare function usePubSub<T extends PubSubTopic>(topic: T, options?: {
|
|
491
|
+
onMessageReceived?: (message: PubSubMessage<PubSubTopicConfig[T]["message"]>) => void;
|
|
492
|
+
}): PubSubHandleForTopic<T>;
|
|
493
|
+
|
|
494
|
+
export { ActiveSpeakerDetector, type ChatInput, type MeetingConfig, MeetingProvider, MeetingState, type Participant, type ParticipantInfo, type PubSubHandle, type PubSubHandleForTopic, type PubSubMessage, type PubSubTopic, type PubSubTopicConfig, type Reaction, type RecordingInfo, type SFUConnectionState, type TrackInfo, VideoSDKCore, useLocalParticipant, useMeeting, useMeetingContext, useMeetingPreview, useParticipants, usePubSub, useRemoteMedia };
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,7 @@ __export(index_exports, {
|
|
|
29
29
|
useMeetingContext: () => useMeetingContext,
|
|
30
30
|
useMeetingPreview: () => useMeetingPreview,
|
|
31
31
|
useParticipants: () => useParticipants,
|
|
32
|
+
usePubSub: () => usePubSub,
|
|
32
33
|
useRemoteMedia: () => useRemoteMedia
|
|
33
34
|
});
|
|
34
35
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -2738,6 +2739,28 @@ var VideoSDKCore = class {
|
|
|
2738
2739
|
}
|
|
2739
2740
|
this.sfuClient.sendReaction(reaction);
|
|
2740
2741
|
}
|
|
2742
|
+
/**
|
|
2743
|
+
* Generic PubSub publishing entry point.
|
|
2744
|
+
*
|
|
2745
|
+
* The public SDK exposes one PubSub API for all topics. The current SFU
|
|
2746
|
+
* protocol still has dedicated wire messages for chat and reactions, so
|
|
2747
|
+
* this method is the compatibility bridge. The application does not need
|
|
2748
|
+
* to know about those wire-level message types.
|
|
2749
|
+
*/
|
|
2750
|
+
publishPubSub(topic, data) {
|
|
2751
|
+
switch (topic) {
|
|
2752
|
+
case "SECURE_CHAT":
|
|
2753
|
+
this.sendChatMessage(data);
|
|
2754
|
+
return;
|
|
2755
|
+
case "REACTION":
|
|
2756
|
+
this.sendReaction(data.emoji);
|
|
2757
|
+
return;
|
|
2758
|
+
default: {
|
|
2759
|
+
const exhaustive = topic;
|
|
2760
|
+
throw new Error(`Unsupported PubSub topic: ${exhaustive}`);
|
|
2761
|
+
}
|
|
2762
|
+
}
|
|
2763
|
+
}
|
|
2741
2764
|
// CLEANUP
|
|
2742
2765
|
cleanupRemoteParticipant(participantId) {
|
|
2743
2766
|
this.activeSpeakerDetector.removeParticipant(participantId);
|
|
@@ -2825,6 +2848,10 @@ var MeetingProvider = ({
|
|
|
2825
2848
|
const recordingStartedListeners = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
2826
2849
|
const recordingStoppedListeners = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
2827
2850
|
const reactionListeners = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
2851
|
+
const pubSubListeners = (0, import_react2.useRef)(
|
|
2852
|
+
/* @__PURE__ */ new Map()
|
|
2853
|
+
);
|
|
2854
|
+
const [reactionPubSubMessages, setReactionPubSubMessages] = (0, import_react2.useState)([]);
|
|
2828
2855
|
const activeSpeakerListeners = (0, import_react2.useRef)(
|
|
2829
2856
|
/* @__PURE__ */ new Set()
|
|
2830
2857
|
);
|
|
@@ -2858,8 +2885,43 @@ var MeetingProvider = ({
|
|
|
2858
2885
|
onRecordingStopped: (recording2) => {
|
|
2859
2886
|
recordingStoppedListeners.current.forEach((fn) => fn(recording2));
|
|
2860
2887
|
},
|
|
2888
|
+
onChatMessage: (message) => {
|
|
2889
|
+
const msg = {
|
|
2890
|
+
id: message.id,
|
|
2891
|
+
text: message.text,
|
|
2892
|
+
sender_id: message.sender_id,
|
|
2893
|
+
sender_name: message.sender_name,
|
|
2894
|
+
timestamp: Number(message.timestamp),
|
|
2895
|
+
reply_to: message.reply_to ?? null,
|
|
2896
|
+
target: message.target ?? null
|
|
2897
|
+
};
|
|
2898
|
+
const pubSubMessage = {
|
|
2899
|
+
id: msg.id,
|
|
2900
|
+
topic: "SECURE_CHAT",
|
|
2901
|
+
sender_id: msg.sender_id,
|
|
2902
|
+
sender_name: msg.sender_name,
|
|
2903
|
+
timestamp: msg.timestamp,
|
|
2904
|
+
data: msg
|
|
2905
|
+
};
|
|
2906
|
+
pubSubListeners.current.get("SECURE_CHAT")?.forEach((fn) => fn(pubSubMessage));
|
|
2907
|
+
},
|
|
2861
2908
|
onReaction: (reaction) => {
|
|
2862
2909
|
reactionListeners.current.forEach((fn) => fn(reaction));
|
|
2910
|
+
const timestamp = typeof reaction.timestamp === "number" ? reaction.timestamp : Date.parse(reaction.timestamp);
|
|
2911
|
+
const message = {
|
|
2912
|
+
id: reaction.id,
|
|
2913
|
+
topic: "REACTION",
|
|
2914
|
+
sender_id: reaction.participant_id,
|
|
2915
|
+
sender_name: reaction.sender_name,
|
|
2916
|
+
timestamp,
|
|
2917
|
+
data: {
|
|
2918
|
+
emoji: reaction.emoji
|
|
2919
|
+
}
|
|
2920
|
+
};
|
|
2921
|
+
setReactionPubSubMessages(
|
|
2922
|
+
(previous) => [...previous, message].slice(-50)
|
|
2923
|
+
);
|
|
2924
|
+
pubSubListeners.current.get("REACTION")?.forEach((fn) => fn(message));
|
|
2863
2925
|
},
|
|
2864
2926
|
onConnectionStateChanged: (state) => {
|
|
2865
2927
|
connectionStateListeners.current.forEach(
|
|
@@ -2922,12 +2984,48 @@ var MeetingProvider = ({
|
|
|
2922
2984
|
activeSpeakerIds,
|
|
2923
2985
|
recording,
|
|
2924
2986
|
usePubSub: (topic) => {
|
|
2925
|
-
if (topic
|
|
2926
|
-
|
|
2987
|
+
if (topic === "SECURE_CHAT") {
|
|
2988
|
+
const chatMessages = messages.map((message) => ({
|
|
2989
|
+
id: message.id,
|
|
2990
|
+
topic: "SECURE_CHAT",
|
|
2991
|
+
sender_id: message.sender_id,
|
|
2992
|
+
sender_name: message.sender_name,
|
|
2993
|
+
timestamp: message.timestamp,
|
|
2994
|
+
data: message
|
|
2995
|
+
}));
|
|
2996
|
+
return {
|
|
2997
|
+
messages: chatMessages,
|
|
2998
|
+
publish: ((data) => {
|
|
2999
|
+
sdk.publishPubSub("SECURE_CHAT", data);
|
|
3000
|
+
})
|
|
3001
|
+
};
|
|
2927
3002
|
}
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
3003
|
+
if (topic === "REACTION") {
|
|
3004
|
+
return {
|
|
3005
|
+
messages: reactionPubSubMessages,
|
|
3006
|
+
publish: ((data) => {
|
|
3007
|
+
if (!data?.emoji) {
|
|
3008
|
+
console.warn("[PubSub] REACTION requires an emoji");
|
|
3009
|
+
return;
|
|
3010
|
+
}
|
|
3011
|
+
sdk.publishPubSub("REACTION", data);
|
|
3012
|
+
})
|
|
3013
|
+
};
|
|
3014
|
+
}
|
|
3015
|
+
throw new Error(`Unsupported PubSub topic: "${topic}"`);
|
|
3016
|
+
},
|
|
3017
|
+
onPubSubMessage: (topic, cb) => {
|
|
3018
|
+
let listeners = pubSubListeners.current.get(topic);
|
|
3019
|
+
if (!listeners) {
|
|
3020
|
+
listeners = /* @__PURE__ */ new Set();
|
|
3021
|
+
pubSubListeners.current.set(topic, listeners);
|
|
3022
|
+
}
|
|
3023
|
+
listeners.add(cb);
|
|
3024
|
+
return () => {
|
|
3025
|
+
listeners?.delete(cb);
|
|
3026
|
+
if (listeners?.size === 0) {
|
|
3027
|
+
pubSubListeners.current.delete(topic);
|
|
3028
|
+
}
|
|
2931
3029
|
};
|
|
2932
3030
|
},
|
|
2933
3031
|
approveJoinRequest: sdk.approveJoinRequest.bind(sdk),
|
|
@@ -2996,7 +3094,8 @@ var MeetingProvider = ({
|
|
|
2996
3094
|
messages,
|
|
2997
3095
|
presenterId,
|
|
2998
3096
|
recording,
|
|
2999
|
-
activeSpeakerIds
|
|
3097
|
+
activeSpeakerIds,
|
|
3098
|
+
reactionPubSubMessages
|
|
3000
3099
|
]);
|
|
3001
3100
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MeetingContext.Provider, { value, children });
|
|
3002
3101
|
};
|
|
@@ -3226,6 +3325,20 @@ function useMeetingPreview(roomId, participantId) {
|
|
|
3226
3325
|
error
|
|
3227
3326
|
};
|
|
3228
3327
|
}
|
|
3328
|
+
|
|
3329
|
+
// src/react/usePubSub.ts
|
|
3330
|
+
var import_react8 = require("react");
|
|
3331
|
+
function usePubSub(topic, options) {
|
|
3332
|
+
const ctx = useMeetingContext();
|
|
3333
|
+
(0, import_react8.useEffect)(() => {
|
|
3334
|
+
if (!options?.onMessageReceived) return;
|
|
3335
|
+
return ctx.onPubSubMessage(
|
|
3336
|
+
topic,
|
|
3337
|
+
options.onMessageReceived
|
|
3338
|
+
);
|
|
3339
|
+
}, [ctx, topic, options?.onMessageReceived]);
|
|
3340
|
+
return ctx.usePubSub(topic);
|
|
3341
|
+
}
|
|
3229
3342
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3230
3343
|
0 && (module.exports = {
|
|
3231
3344
|
ActiveSpeakerDetector,
|
|
@@ -3237,6 +3350,7 @@ function useMeetingPreview(roomId, participantId) {
|
|
|
3237
3350
|
useMeetingContext,
|
|
3238
3351
|
useMeetingPreview,
|
|
3239
3352
|
useParticipants,
|
|
3353
|
+
usePubSub,
|
|
3240
3354
|
useRemoteMedia
|
|
3241
3355
|
});
|
|
3242
3356
|
//# sourceMappingURL=index.js.map
|