mediasfu-shared 1.2.0 → 1.2.2
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/CHANGELOG.md +15 -0
- package/README.md +145 -131
- package/dist/consumers/connectIps.d.ts.map +1 -1
- package/dist/consumers/index.cjs +1 -1
- package/dist/consumers/index.js +1 -1
- package/dist/{getParticipantMedia-CdcYqcbD.cjs → getParticipantMedia-BH3d_-Q1.cjs} +4 -4
- package/dist/getParticipantMedia-BH3d_-Q1.cjs.map +1 -0
- package/dist/{getParticipantMedia-B0JS6d2b.js → getParticipantMedia-CGqnSb93.js} +4 -4
- package/dist/getParticipantMedia-CGqnSb93.js.map +1 -0
- package/dist/index.cjs +3 -3
- package/dist/index.js +4 -4
- package/dist/index.native.cjs +3 -3
- package/dist/index.native.js +3 -3
- package/dist/{joinLocalRoom-CvteNe4R.js → joinLocalRoom-7ibqv7zZ.js} +2 -2
- package/dist/{joinLocalRoom-CvteNe4R.js.map → joinLocalRoom-7ibqv7zZ.js.map} +1 -1
- package/dist/{joinLocalRoom-BdM1msQt.cjs → joinLocalRoom-BJBDvTYh.cjs} +2 -2
- package/dist/{joinLocalRoom-BdM1msQt.cjs.map → joinLocalRoom-BJBDvTYh.cjs.map} +1 -1
- package/dist/methods/recording/startRecording.d.ts.map +1 -1
- package/dist/types/index.cjs +2 -2
- package/dist/types/index.js +2 -2
- package/dist/{updateParticipantAudioDecibels-DLd8Y-Fh.js → updateParticipantAudioDecibels-C_MygF6q.js} +45 -5
- package/dist/updateParticipantAudioDecibels-C_MygF6q.js.map +1 -0
- package/dist/{updateParticipantAudioDecibels-DPmHiy3K.cjs → updateParticipantAudioDecibels-bZ6R8WHj.cjs} +45 -5
- package/dist/updateParticipantAudioDecibels-bZ6R8WHj.cjs.map +1 -0
- package/package.json +2 -1
- package/src/consumers/connectIps.ts +68 -8
- package/src/methods/recording/startRecording.ts +7 -1
- package/dist/getParticipantMedia-B0JS6d2b.js.map +0 -1
- package/dist/getParticipantMedia-CdcYqcbD.cjs.map +0 -1
- package/dist/updateParticipantAudioDecibels-DLd8Y-Fh.js.map +0 -1
- package/dist/updateParticipantAudioDecibels-DPmHiy3K.cjs.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mediasfu-shared",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "mediasfu-shared – framework-agnostic WebRTC runtime for MediaSFU. Room helpers, mediasoup signaling, socket management, media state, and TypeScript types for React, Vue, Angular, Svelte, and plain TS.",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"src",
|
|
38
38
|
"README.md",
|
|
39
39
|
"HEADLESS_GUIDE.md",
|
|
40
|
+
"CHANGELOG.md",
|
|
40
41
|
"LICENSE"
|
|
41
42
|
],
|
|
42
43
|
"scripts": {
|
|
@@ -36,6 +36,63 @@ export interface ConnectIpsOptions {
|
|
|
36
36
|
// Export the type definition for the function
|
|
37
37
|
export type ConnectIpsType = (options: ConnectIpsOptions) => Promise<[Record<string, any>[], string[]]>;
|
|
38
38
|
|
|
39
|
+
// Keep the reservation local to one room engine's socket collection. Separate
|
|
40
|
+
// rooms may legitimately consume from the same endpoint and must not share a
|
|
41
|
+
// socket, while overlapping updates for one room must serialize that endpoint.
|
|
42
|
+
const pendingConsumeConnections = new WeakMap<
|
|
43
|
+
object,
|
|
44
|
+
Map<string, Promise<boolean>>
|
|
45
|
+
>();
|
|
46
|
+
|
|
47
|
+
const normalizeConsumeEndpoint = (ip: string): string =>
|
|
48
|
+
ip.trim().toLowerCase().replace(/\.$/, "");
|
|
49
|
+
|
|
50
|
+
const hasConsumeEndpoint = (
|
|
51
|
+
consumeSockets: ConsumeSocket[],
|
|
52
|
+
endpoint: string
|
|
53
|
+
): boolean => consumeSockets.some((socketObj) => {
|
|
54
|
+
const ip = Object.keys(socketObj)[0];
|
|
55
|
+
return Boolean(ip) && normalizeConsumeEndpoint(ip) === endpoint;
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
async function reserveConsumeEndpoint(
|
|
59
|
+
consumeSockets: ConsumeSocket[],
|
|
60
|
+
ip: string,
|
|
61
|
+
reservationOwner: object = consumeSockets
|
|
62
|
+
): Promise<((connected?: boolean) => void) | null> {
|
|
63
|
+
const endpoint = normalizeConsumeEndpoint(ip);
|
|
64
|
+
if (!endpoint || endpoint === "none") return null;
|
|
65
|
+
|
|
66
|
+
let pendingForSockets = pendingConsumeConnections.get(reservationOwner);
|
|
67
|
+
if (!pendingForSockets) {
|
|
68
|
+
pendingForSockets = new Map<string, Promise<boolean>>();
|
|
69
|
+
pendingConsumeConnections.set(reservationOwner, pendingForSockets);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
while (true) {
|
|
73
|
+
if (hasConsumeEndpoint(consumeSockets, endpoint)) return null;
|
|
74
|
+
|
|
75
|
+
const pending = pendingForSockets.get(endpoint);
|
|
76
|
+
if (pending) {
|
|
77
|
+
if (await pending) return null;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let resolvePending!: (connected: boolean) => void;
|
|
82
|
+
const reservation = new Promise<boolean>((resolve) => {
|
|
83
|
+
resolvePending = resolve;
|
|
84
|
+
});
|
|
85
|
+
pendingForSockets.set(endpoint, reservation);
|
|
86
|
+
|
|
87
|
+
return (didConnect = false) => {
|
|
88
|
+
if (pendingForSockets?.get(endpoint) === reservation) {
|
|
89
|
+
pendingForSockets.delete(endpoint);
|
|
90
|
+
}
|
|
91
|
+
resolvePending(didConnect === true);
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
39
96
|
/**
|
|
40
97
|
* Connects to remote IPs and manages socket connections.
|
|
41
98
|
*
|
|
@@ -105,15 +162,15 @@ export const connectIps = async ({
|
|
|
105
162
|
}
|
|
106
163
|
|
|
107
164
|
for (const ip of remIP) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
continue;
|
|
115
|
-
}
|
|
165
|
+
const releaseReservation = await reserveConsumeEndpoint(
|
|
166
|
+
consume_sockets,
|
|
167
|
+
ip,
|
|
168
|
+
parameters?.socket || consume_sockets
|
|
169
|
+
);
|
|
170
|
+
if (!releaseReservation) continue;
|
|
116
171
|
|
|
172
|
+
let connected = false;
|
|
173
|
+
try {
|
|
117
174
|
// Connect to the remote socket using socket.io-client
|
|
118
175
|
const remote_sock = await connectSocket({ apiUserName, apiKey, apiToken, link: `https://${ip}.mediasfu.com` });
|
|
119
176
|
|
|
@@ -161,10 +218,13 @@ export const connectIps = async ({
|
|
|
161
218
|
// Add the remote socket to the consume_sockets array
|
|
162
219
|
consume_sockets.push({ [ip]: remote_sock });
|
|
163
220
|
updateConsume_sockets(consume_sockets);
|
|
221
|
+
connected = true;
|
|
164
222
|
}
|
|
165
223
|
} catch (error) {
|
|
166
224
|
// Handle the error
|
|
167
225
|
console.log("connectIps error", error);
|
|
226
|
+
} finally {
|
|
227
|
+
releaseReservation(connected);
|
|
168
228
|
}
|
|
169
229
|
}
|
|
170
230
|
|
|
@@ -222,7 +222,13 @@ export const startRecording: StartRecordingType = async ({
|
|
|
222
222
|
updateRecordPaused(recordPaused)
|
|
223
223
|
|
|
224
224
|
if (action === 'startRecord') {
|
|
225
|
-
|
|
225
|
+
// restart: force an immediate updateScreenClient. Without it,
|
|
226
|
+
// rePort only emits when activeNames or screenStates differ from
|
|
227
|
+
// their previous values — and nothing has changed at the moment a
|
|
228
|
+
// recording starts, so the recorder got no layout until something
|
|
229
|
+
// later did (a speaker change, a join, a share). Resume already
|
|
230
|
+
// forced it; start now matches.
|
|
231
|
+
await rePort({ restart: true, parameters: parameters.getUpdatedAllParams() })
|
|
226
232
|
await recordStartTimer({ parameters })
|
|
227
233
|
} else {
|
|
228
234
|
updateRecordResumed(true)
|