mediasfu-shared 1.3.0 → 1.3.1

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/consumers/connectSendTransportAudio.d.ts.map +1 -1
  3. package/dist/consumers/connectSendTransportScreen.d.ts.map +1 -1
  4. package/dist/consumers/connectSendTransportVideo.d.ts.map +1 -1
  5. package/dist/consumers/createSendTransport.d.ts +4 -48
  6. package/dist/consumers/createSendTransport.d.ts.map +1 -1
  7. package/dist/consumers/index.cjs +1 -1
  8. package/dist/consumers/index.js +1 -1
  9. package/dist/consumers/sendTransportGuard.d.ts +30 -0
  10. package/dist/consumers/sendTransportGuard.d.ts.map +1 -0
  11. package/dist/{getParticipantMedia-DEJwXXhU.js → getParticipantMedia-CZbsFBth.js} +3 -3
  12. package/dist/{getParticipantMedia-DEJwXXhU.js.map → getParticipantMedia-CZbsFBth.js.map} +1 -1
  13. package/dist/{getParticipantMedia-1okyF4H7.cjs → getParticipantMedia-Dli4dOLp.cjs} +3 -3
  14. package/dist/{getParticipantMedia-1okyF4H7.cjs.map → getParticipantMedia-Dli4dOLp.cjs.map} +1 -1
  15. package/dist/index.cjs +4 -3
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.js +9 -8
  18. package/dist/index.native.cjs +4 -3
  19. package/dist/index.native.cjs.map +1 -1
  20. package/dist/index.native.js +8 -7
  21. package/dist/{joinLocalRoom-DS6_6lJL.js → joinLocalRoom-BWoS-8wt.js} +2 -2
  22. package/dist/{joinLocalRoom-DS6_6lJL.js.map → joinLocalRoom-BWoS-8wt.js.map} +1 -1
  23. package/dist/{joinLocalRoom-Dsn39SwS.cjs → joinLocalRoom-DQvud99t.cjs} +2 -2
  24. package/dist/{joinLocalRoom-Dsn39SwS.cjs.map → joinLocalRoom-DQvud99t.cjs.map} +1 -1
  25. package/dist/sockets/SocketManager.d.ts +7 -0
  26. package/dist/sockets/SocketManager.d.ts.map +1 -1
  27. package/dist/types/index.cjs +2 -2
  28. package/dist/types/index.js +2 -2
  29. package/dist/{updateParticipantAudioDecibels-Dni8i6AY.cjs → updateParticipantAudioDecibels-CbCP1PDs.cjs} +162 -67
  30. package/dist/updateParticipantAudioDecibels-CbCP1PDs.cjs.map +1 -0
  31. package/dist/{updateParticipantAudioDecibels-BBfdHWQ0.js → updateParticipantAudioDecibels-xKKq7Zp5.js} +166 -71
  32. package/dist/updateParticipantAudioDecibels-xKKq7Zp5.js.map +1 -0
  33. package/package.json +1 -1
  34. package/src/consumers/connectSendTransportAudio.ts +7 -4
  35. package/src/consumers/connectSendTransportScreen.ts +6 -4
  36. package/src/consumers/connectSendTransportVideo.ts +4 -2
  37. package/src/consumers/createSendTransport.ts +62 -4
  38. package/src/consumers/sendTransportGuard.ts +65 -0
  39. package/src/sockets/SocketManager.ts +31 -1
  40. package/dist/updateParticipantAudioDecibels-BBfdHWQ0.js.map +0 -1
  41. package/dist/updateParticipantAudioDecibels-Dni8i6AY.cjs.map +0 -1
@@ -766,6 +766,24 @@ async function compareScreenStates({
766
766
  console.log("compareScreenStates error", error);
767
767
  }
768
768
  }
769
+ function stopReconnectingWhenRefused(socket) {
770
+ const onRejected = (payload) => {
771
+ const refusal = new MediaSocketConnectError({
772
+ phase: "rejected",
773
+ reason: normalizeRejectionReason(payload?.reason),
774
+ stage: typeof payload?.stage === "string" ? payload.stage : void 0,
775
+ elapsedMs: 0
776
+ });
777
+ if (refusal.retryable) return;
778
+ socket.off("connection-rejected", onRejected);
779
+ console.warn(`MediaSFU media socket: reconnect refused (${refusal.reason}); not retrying.`);
780
+ try {
781
+ socket.disconnect();
782
+ } catch {
783
+ }
784
+ };
785
+ socket.on("connection-rejected", onRejected);
786
+ }
769
787
  async function validateApiKeyToken(value) {
770
788
  if (!/^[a-z0-9]{64}$/i.test(value)) {
771
789
  throw new Error("Invalid API key or token.");
@@ -853,7 +871,10 @@ async function connectSocket({ apiUserName, apiKey, apiToken, link }) {
853
871
  } catch {
854
872
  }
855
873
  console.log(`Connected to ${conn} socket with ID: ${socketId}`);
856
- settle(() => resolve(socket));
874
+ settle(() => {
875
+ stopReconnectingWhenRefused(socket);
876
+ resolve(socket);
877
+ });
857
878
  };
858
879
  const handleConnectError = (error) => {
859
880
  settle(() => {
@@ -1914,6 +1935,36 @@ const connectSendTransport = async ({ option, targetOption = "all", parameters }
1914
1935
  console.log("connectSendTransport error", error);
1915
1936
  }
1916
1937
  };
1938
+ const pendingCreations = /* @__PURE__ */ new WeakMap();
1939
+ const pendingSendTransportCreation = (socket) => socket ? pendingCreations.get(socket) : void 0;
1940
+ const trackSendTransportCreation = (socket, create) => {
1941
+ if (!socket) return create();
1942
+ const running = create();
1943
+ pendingCreations.set(socket, running);
1944
+ const release = () => {
1945
+ if (pendingCreations.get(socket) === running) pendingCreations.delete(socket);
1946
+ };
1947
+ running.then(release, release);
1948
+ return running;
1949
+ };
1950
+ const isOpen = (item) => Boolean(item && !item.closed);
1951
+ const pendingProduces = /* @__PURE__ */ new WeakMap();
1952
+ const produceOnce$1 = async (transport, key, produce) => {
1953
+ let byKey = pendingProduces.get(transport);
1954
+ if (!byKey) {
1955
+ byKey = /* @__PURE__ */ new Map();
1956
+ pendingProduces.set(transport, byKey);
1957
+ }
1958
+ const inFlight = byKey.get(key);
1959
+ if (inFlight) return { producer: await inFlight, joined: true };
1960
+ const running = produce();
1961
+ byKey.set(key, running);
1962
+ try {
1963
+ return { producer: await running, joined: false };
1964
+ } finally {
1965
+ if (byKey.get(key) === running) byKey.delete(key);
1966
+ }
1967
+ };
1917
1968
  const connectLocalSendTransportAudio = async ({
1918
1969
  parameters,
1919
1970
  audioParams
@@ -1926,7 +1977,7 @@ const connectLocalSendTransportAudio = async ({
1926
1977
  updateLocalProducerTransport
1927
1978
  } = parameters;
1928
1979
  if (localProducerTransport) {
1929
- localAudioProducer = await localProducerTransport.produce(audioParams);
1980
+ localAudioProducer = (await produceOnce$1(localProducerTransport, "audio", () => localProducerTransport.produce(audioParams))).producer;
1930
1981
  updateLocalAudioProducer?.(localAudioProducer);
1931
1982
  updateLocalProducerTransport?.(localProducerTransport);
1932
1983
  }
@@ -1964,8 +2015,9 @@ const connectSendTransportAudio = async ({
1964
2015
  updateProducerTransport
1965
2016
  } = parameters;
1966
2017
  if (targetOption === "all" || targetOption === "remote") {
1967
- audioProducer = await producerTransport.produce(audioParams);
1968
- updateMicLevel(audioProducer, parameters.updateAudioLevel);
2018
+ const produced = await produceOnce$1(producerTransport, "audio", () => producerTransport.produce(audioParams));
2019
+ audioProducer = produced.producer;
2020
+ if (!produced.joined) updateMicLevel(audioProducer, parameters.updateAudioLevel);
1969
2021
  updateAudioProducer(audioProducer);
1970
2022
  updateProducerTransport(producerTransport);
1971
2023
  }
@@ -2003,11 +2055,11 @@ const connectLocalSendTransportScreen = async ({
2003
2055
  (codec2) => codec2.mimeType.toLowerCase() === "video/vp9"
2004
2056
  );
2005
2057
  if (localProducerTransport) {
2006
- localScreenProducer = await localProducerTransport.produce({
2058
+ localScreenProducer = (await produceOnce$1(localProducerTransport, "screen", () => localProducerTransport.produce({
2007
2059
  track: stream.getVideoTracks()[0],
2008
2060
  codec,
2009
2061
  appData: { mediaTag: "screen-video" }
2010
- });
2062
+ }))).producer;
2011
2063
  updateLocalScreenProducer?.(localScreenProducer);
2012
2064
  updateLocalProducerTransport?.(localProducerTransport);
2013
2065
  }
@@ -2037,12 +2089,12 @@ const connectSendTransportScreen = async ({
2037
2089
  (codec2) => codec2.mimeType.toLowerCase() === "video/vp9"
2038
2090
  );
2039
2091
  if (targetOption === "remote" || targetOption === "all") {
2040
- screenProducer = await producerTransport.produce({
2092
+ screenProducer = (await produceOnce$1(producerTransport, "screen", () => producerTransport.produce({
2041
2093
  track: stream.getVideoTracks()[0],
2042
2094
  ...params,
2043
2095
  codec,
2044
2096
  appData: { mediaTag: "screen-video" }
2045
- });
2097
+ }))).producer;
2046
2098
  updateScreenProducer(screenProducer);
2047
2099
  updateProducerTransport(producerTransport);
2048
2100
  }
@@ -2070,7 +2122,7 @@ const connectLocalSendTransportVideo = async ({
2070
2122
  updateLocalProducerTransport
2071
2123
  } = parameters;
2072
2124
  if (localProducerTransport) {
2073
- localVideoProducer = await localProducerTransport.produce(videoParams);
2125
+ localVideoProducer = (await produceOnce$1(localProducerTransport, "video", () => localProducerTransport.produce(videoParams))).producer;
2074
2126
  updateLocalVideoProducer?.(localVideoProducer);
2075
2127
  updateLocalProducerTransport?.(localProducerTransport);
2076
2128
  }
@@ -2095,7 +2147,7 @@ const connectSendTransportVideo = async ({
2095
2147
  updateUpdateMainWindow
2096
2148
  } = parameters;
2097
2149
  if (targetOption === "all" || targetOption === "remote") {
2098
- videoProducer = await producerTransport.produce(videoParams);
2150
+ videoProducer = (await produceOnce$1(producerTransport, "video", () => producerTransport.produce(videoParams))).producer;
2099
2151
  if (islevel === "2") {
2100
2152
  updateMainWindow = true;
2101
2153
  }
@@ -2215,7 +2267,7 @@ const createLocalSendTransport = async ({
2215
2267
  console.error("Error creating local send transport:", error);
2216
2268
  }
2217
2269
  };
2218
- const createSendTransport = async ({
2270
+ const createSendTransportNow = async ({
2219
2271
  option,
2220
2272
  parameters
2221
2273
  }) => {
@@ -2245,67 +2297,109 @@ const createSendTransport = async ({
2245
2297
  } catch (error) {
2246
2298
  console.log("Error creating local send transport:", error);
2247
2299
  }
2248
- socket.emit(
2300
+ await new Promise((resolve, reject) => socket.emit(
2249
2301
  "createWebRtcTransport",
2250
2302
  { consumer: false, islevel },
2251
2303
  async ({ params }) => {
2252
- if (params && params.error) {
2253
- console.error("Error in createWebRtcTransport:", params.error);
2254
- return;
2255
- }
2256
- const resolvedDevice = parameters.getCurrentParams ? parameters.getCurrentParams().device : device ?? null;
2257
- if (!resolvedDevice) {
2258
- return;
2259
- }
2260
- const createdProducerTransport = await resolvedDevice.createSendTransport(params);
2261
- updateProducerTransport(createdProducerTransport);
2262
- createdProducerTransport.on(
2263
- "connect",
2264
- async ({ dtlsParameters }, callback, errback) => {
2265
- try {
2266
- socket.emit("transport-connect", { dtlsParameters });
2267
- callback();
2268
- } catch (error) {
2269
- errback(error);
2270
- }
2271
- }
2272
- );
2273
- createdProducerTransport.on(
2274
- "produce",
2275
- async (parameters2, callback, errback) => {
2276
- try {
2277
- socket.emit(
2278
- "transport-produce",
2279
- {
2280
- kind: parameters2.kind,
2281
- rtpParameters: parameters2.rtpParameters,
2282
- appData: parameters2.appData,
2283
- islevel,
2284
- name: member
2285
- },
2286
- async ({ id }) => {
2287
- callback({ id });
2288
- }
2289
- );
2290
- } catch (error) {
2291
- errback(error);
2292
- }
2304
+ try {
2305
+ if (params && params.error) {
2306
+ console.error("Error in createWebRtcTransport:", params.error);
2307
+ reject(new Error(String(params.error)));
2308
+ return;
2293
2309
  }
2294
- );
2295
- attachTransportRecovery(createdProducerTransport, socket, () => clearFailedSendState(parameters, createdProducerTransport));
2296
- transportCreated = true;
2297
- parameters = parameters.getCurrentParams?.() ?? parameters;
2298
- await connectSendTransport2({
2299
- targetOption: "remote",
2300
- option,
2301
- parameters: {
2302
- ...parameters,
2303
- producerTransport: createdProducerTransport
2310
+ const resolvedDevice = parameters.getCurrentParams ? parameters.getCurrentParams().device : device ?? null;
2311
+ if (!resolvedDevice) {
2312
+ resolve();
2313
+ return;
2304
2314
  }
2305
- });
2306
- updateTransportCreated(transportCreated);
2315
+ const createdProducerTransport = await resolvedDevice.createSendTransport(params);
2316
+ updateProducerTransport(createdProducerTransport);
2317
+ createdProducerTransport.on(
2318
+ "connect",
2319
+ async ({ dtlsParameters }, callback, errback) => {
2320
+ try {
2321
+ socket.emit("transport-connect", { dtlsParameters });
2322
+ callback();
2323
+ } catch (error) {
2324
+ errback(error);
2325
+ }
2326
+ }
2327
+ );
2328
+ createdProducerTransport.on(
2329
+ "produce",
2330
+ async (parameters2, callback, errback) => {
2331
+ try {
2332
+ socket.emit(
2333
+ "transport-produce",
2334
+ {
2335
+ kind: parameters2.kind,
2336
+ rtpParameters: parameters2.rtpParameters,
2337
+ appData: parameters2.appData,
2338
+ islevel,
2339
+ name: member
2340
+ },
2341
+ async ({ id }) => {
2342
+ callback({ id });
2343
+ }
2344
+ );
2345
+ } catch (error) {
2346
+ errback(error);
2347
+ }
2348
+ }
2349
+ );
2350
+ attachTransportRecovery(createdProducerTransport, socket, () => clearFailedSendState(parameters, createdProducerTransport));
2351
+ transportCreated = true;
2352
+ parameters = parameters.getCurrentParams?.() ?? parameters;
2353
+ await connectSendTransport2({
2354
+ targetOption: "remote",
2355
+ option,
2356
+ parameters: {
2357
+ ...parameters,
2358
+ producerTransport: createdProducerTransport
2359
+ }
2360
+ });
2361
+ updateTransportCreated(transportCreated);
2362
+ resolve();
2363
+ } catch (error) {
2364
+ reject(error);
2365
+ }
2307
2366
  }
2308
- );
2367
+ ));
2368
+ } catch (error) {
2369
+ console.log("Error creating send transport:", error);
2370
+ }
2371
+ };
2372
+ const producerFor = (params, option) => {
2373
+ if (option === "audio") return isOpen(params.audioProducer);
2374
+ if (option === "video") return isOpen(params.videoProducer);
2375
+ if (option === "screen") return isOpen(params.screenProducer);
2376
+ return isOpen(params.audioProducer) && isOpen(params.videoProducer);
2377
+ };
2378
+ const createSendTransport = async ({
2379
+ option,
2380
+ parameters
2381
+ }) => {
2382
+ try {
2383
+ const current = parameters.getCurrentParams?.() ?? parameters.getUpdatedAllParams?.() ?? parameters;
2384
+ const socket = current.socket;
2385
+ const pending = pendingSendTransportCreation(socket);
2386
+ if (!pending && !(current.transportCreated && isOpen(current.producerTransport))) {
2387
+ await trackSendTransportCreation(socket, () => createSendTransportNow({ option, parameters }));
2388
+ return;
2389
+ }
2390
+ if (pending) await pending.catch(() => void 0);
2391
+ const latest = parameters.getCurrentParams?.() ?? parameters.getUpdatedAllParams?.() ?? parameters;
2392
+ if (!isOpen(latest.producerTransport)) {
2393
+ await createSendTransport({ option, parameters });
2394
+ return;
2395
+ }
2396
+ if (producerFor(latest, option)) return;
2397
+ const connectSendTransport2 = latest.connectSendTransport ?? parameters.connectSendTransport;
2398
+ await connectSendTransport2({
2399
+ targetOption: "all",
2400
+ option,
2401
+ parameters: { ...latest, producerTransport: latest.producerTransport }
2402
+ });
2309
2403
  } catch (error) {
2310
2404
  console.log("Error creating send transport:", error);
2311
2405
  }
@@ -5911,10 +6005,11 @@ export {
5911
6005
  rememberScreenAudioProducer as al,
5912
6006
  recallScreenAudioProducer as am,
5913
6007
  setScreenAudioVolume as an,
5914
- connectSocket as ao,
5915
- disconnectSocket as ap,
5916
- connectLocalSocket as aq,
5917
- createFrameworkConsumerContractError as ar,
6008
+ stopReconnectingWhenRefused as ao,
6009
+ connectSocket as ap,
6010
+ disconnectSocket as aq,
6011
+ connectLocalSocket as ar,
6012
+ createFrameworkConsumerContractError as as,
5918
6013
  checkScreenShare as b,
5919
6014
  consumerResume as c,
5920
6015
  closeAndResize as d,
@@ -5941,4 +6036,4 @@ export {
5941
6036
  processConsumerTransportsAudio as y,
5942
6037
  readjust as z
5943
6038
  };
5944
- //# sourceMappingURL=updateParticipantAudioDecibels-BBfdHWQ0.js.map
6039
+ //# sourceMappingURL=updateParticipantAudioDecibels-xKKq7Zp5.js.map