@js-toolkit/web-utils 1.59.0 → 1.60.0
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/EventListeners.js +1 -1
- package/FullscreenController.d.ts +0 -1
- package/FullscreenController.js +1 -1
- package/createRafLoop.d.ts +2 -2
- package/createRafLoop.js +1 -1
- package/fullscreen.js +1 -1
- package/fullscreenUtils.d.ts +1 -0
- package/fullscreenUtils.js +1 -0
- package/getAspectRatio.d.ts +3 -3
- package/getEventAwaiter.d.ts +4 -4
- package/getEventAwaiter.js +1 -1
- package/getGeoLocality.js +1 -1
- package/iframe/getAutoConnector.d.ts +2 -1
- package/iframe/getAutoConnector.js +1 -1
- package/imageToBlob.js +1 -1
- package/media/TextTracksController/TextTracksController.js +1 -1
- package/media/TextTracksController/utils.d.ts +1 -1
- package/media/getMediaSource.d.ts +1 -1
- package/media/parseCueText.js +1 -1
- package/package.json +15 -15
- package/platform/isTelegramWebView.d.ts +4 -0
- package/platform/isTelegramWebView.js +1 -0
- package/webrtc/PeerConnection.d.ts +3 -2
- package/webrtc/PeerConnection.js +1 -1
package/EventListeners.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{EventEmitterListener}from"./EventEmitterListener";export class EventListeners{listeners=new Map;getScopes(){return this.listeners.keys()}scope(e,s){const t=s??"",r=this.listeners.get(e)??new Map;!this.listeners.has(e)&&this.listeners.set(e,r);const i=r.get(t)??new EventEmitterListener(e);return!r.has(t)&&r.set(t,i),i}removeAllListeners(e,s){if(e)
|
|
1
|
+
import{EventEmitterListener}from"./EventEmitterListener";export class EventListeners{listeners=new Map;getScopes(){return this.listeners.keys()}scope(e,s){const t=s??"",r=this.listeners.get(e)??new Map;!this.listeners.has(e)&&this.listeners.set(e,r);const i=r.get(t)??new EventEmitterListener(e);return!r.has(t)&&r.set(t,i),i}removeAllListeners(e,s){if(e){const t=this.listeners.get(e);s?(t?.get(s)?.removeAllListeners(),t?.delete(s),0===t?.size&&this.listeners.delete(e)):(t?.forEach((e=>e.removeAllListeners())),t?.clear(),this.listeners.delete(e))}else this.listeners.forEach((e=>{e.forEach((e=>e.removeAllListeners())),e.clear()})),this.listeners.clear();return this}}
|
|
@@ -7,7 +7,6 @@ declare global {
|
|
|
7
7
|
webkitSupportsFullscreen?: boolean | undefined;
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
|
-
export declare function enterPseudoFullscreen(element: Element & ElementCSSInlineStyle): VoidFunction;
|
|
11
10
|
export declare class FullscreenController extends EventEmitter<FullscreenController.EventMap> implements AsyncDisposable {
|
|
12
11
|
private readonly element;
|
|
13
12
|
private options;
|
package/FullscreenController.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{EventEmitter}from"eventemitter3";import{hasIn}from"@js-toolkit/utils/hasIn";import{
|
|
1
|
+
import{EventEmitter}from"eventemitter3";import{hasIn}from"@js-toolkit/utils/hasIn";import{toggleNativeSubtitles}from"./media/toggleNativeSubtitles";import{fullscreen}from"./fullscreen";import{enterPseudoFullscreen}from"./fullscreenUtils";export class FullscreenController extends EventEmitter{element;options;static isApiAvailable(){return fullscreen.isApiEnabled()}get Events(){return FullscreenController.Events}fallback;exitPseudoFullscreen;constructor(e,t={}){super(),this.element=e,this.options=t,this.setOptions(t)}unbind(){if(fullscreen.names){const{names:e}=fullscreen;this.element.removeEventListener(e.changeEventName,this.nativeChangeHandler),this.element.removeEventListener(e.errorEventName,this.nativeErrorHandler)}this.fallback instanceof HTMLVideoElement&&(this.fallback.removeEventListener("webkitbeginfullscreen",this.videoBeginFullscreenHandler),this.fallback.removeEventListener("webkitendfullscreen",this.videoEndFullscreenHandler),this.fallback=void 0)}setOptions(e){if(this.unbind(),this.options=e??{},this.fallback=this.options.fallback,fullscreen.names&&fullscreen.isApiEnabled()){const{names:e}=fullscreen;this.element.addEventListener(e.changeEventName,this.nativeChangeHandler),this.element.addEventListener(e.errorEventName,this.nativeErrorHandler)}else this.fallback instanceof HTMLVideoElement&&(this.fallback.addEventListener("webkitbeginfullscreen",this.videoBeginFullscreenHandler),this.fallback.addEventListener("webkitendfullscreen",this.videoEndFullscreenHandler))}isAvailable(){return fullscreen.isApiEnabled()||"pseudo"===this.fallback||this.fallback instanceof HTMLVideoElement&&!!this.fallback.webkitEnterFullscreen&&!!this.fallback.webkitSupportsFullscreen}isFullscreen(){return!!this.getCurrentElement()}isPseudoFullscreen(){return this.isFullscreen()&&!!this.exitPseudoFullscreen}getCurrentElement(){if(fullscreen.isApiEnabled()){if(fullscreen.getElement()===this.element)return this.element}else{if(this.exitPseudoFullscreen)return this.element;if(this.fallback instanceof HTMLVideoElement&&this.fallback.webkitDisplayingFullscreen)return this.fallback}return null}nativeChangeHandler=()=>{this.emit(this.Events.Change,{fullscreen:this.isFullscreen(),type:"native"})};nativeErrorHandler=e=>{this.emit(this.Events.Error,{error:e,type:"native"})};videoBeginFullscreenHandler=(()=>{const e=()=>{const t=this.fallback;e.controls=t.controls,e.nativeSubtitles=hasIn(this.options,"toggleNativeSubtitles")&&this.options.toggleNativeSubtitles&&t.textTracks.length>0,e.nativeSubtitles&&toggleNativeSubtitles(!0,t.textTracks),this.emit(this.Events.Change,{fullscreen:!0,type:"video"})};return e.nativeSubtitles=void 0,e.controls=void 0,e})();videoEndFullscreenHandler=()=>{const e=this.fallback;null!=this.videoBeginFullscreenHandler.controls&&(e.controls=this.videoBeginFullscreenHandler.controls),this.videoBeginFullscreenHandler.nativeSubtitles&&toggleNativeSubtitles(!1,e.textTracks),this.emit(this.Events.Change,{fullscreen:!1,type:"video"})};request(e={}){return new Promise(((t,n)=>{if(this.isFullscreen())return void t();if(fullscreen.isApiEnabled())return void fullscreen.request(this.element,e).then(t).catch(n);if("pseudo"===this.fallback)return this.exitPseudoFullscreen=enterPseudoFullscreen(this.element),this.emit(this.Events.Change,{fullscreen:!0,type:"pseudo"}),void t();const l=this.fallback instanceof HTMLVideoElement&&this.fallback||void 0;if(l?.webkitEnterFullscreen&&l.webkitSupportsFullscreen){const e=()=>{l.removeEventListener("webkitbeginfullscreen",e),t()};return l.addEventListener("webkitbeginfullscreen",e),void l.webkitEnterFullscreen()}n(new fullscreen.UnavailableError)}))}exit(){return new Promise(((e,t)=>{if(!this.isFullscreen())return void e();if(fullscreen.isApiEnabled())return void fullscreen.exit().then(e).catch(t);if(this.exitPseudoFullscreen)return this.exitPseudoFullscreen(),this.exitPseudoFullscreen=void 0,this.emit(this.Events.Change,{fullscreen:!1,type:"pseudo"}),void e();const n=this.fallback instanceof HTMLVideoElement&&this.fallback||void 0;if(n?.webkitExitFullscreen&&n.webkitSupportsFullscreen){const t=()=>{n.removeEventListener("webkitendfullscreen",t),e()};return n.addEventListener("webkitendfullscreen",t),void n.webkitExitFullscreen()}t(new fullscreen.UnavailableError)}))}destroy(){return this.exit().then((()=>new Promise((e=>{requestAnimationFrame((()=>{this.removeAllListeners(),this.unbind(),e()}))}))))}[Symbol.asyncDispose](){return this.destroy()}}!function(e){let t;!function(e){e.Change="change",e.Error="error"}(t=e.Events||(e.Events={}))}(FullscreenController||(FullscreenController={}));
|
package/createRafLoop.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export interface RafLoopStartOptions {
|
|
2
2
|
readonly suspendTimeout?: number | undefined;
|
|
3
|
-
readonly scope?: AnimationFrameProvider | undefined;
|
|
3
|
+
readonly scope?: (AnimationFrameProvider & WindowOrWorkerGlobalScope) | undefined;
|
|
4
4
|
}
|
|
5
5
|
export interface RafLoop {
|
|
6
6
|
start: (callback: FrameRequestCallback, options?: RafLoopStartOptions) => void;
|
|
7
|
-
stop:
|
|
7
|
+
stop: (waitLast?: boolean) => void;
|
|
8
8
|
isActive: () => boolean;
|
|
9
9
|
}
|
|
10
10
|
export declare function createRafLoop(): RafLoop;
|
package/createRafLoop.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export function createRafLoop(){let e,o,
|
|
1
|
+
export function createRafLoop(){let e,t,o,i=!1,n=0,a=window;const r=()=>{a.clearTimeout(e),t&&a.cancelAnimationFrame(t),t=void 0,n=0,e=void 0},s=()=>{t=a.requestAnimationFrame(u)},u=u=>{o&&(i?(o(u),n>0?e=a.setTimeout(s,n):s()):null==t&&null==e||(r(),o(u)))};return{start:(e,{suspendTimeout:t=0,scope:r=window}={})=>{o=e,n=t,a=r,i||(i=!0,s())},stop:e=>{i&&(i=!1,e||r())},isActive:()=>i}}
|
package/fullscreen.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{es5ErrorCompat}from"@js-toolkit/utils/es5ErrorCompat";import{promisify}from"@js-toolkit/utils/promisify";export class FullscreenUnavailableError extends Error{constructor(){super("Fullscreen is not available"),es5ErrorCompat(this,FullscreenUnavailableError)}}export var fullscreen;!function(e){e.names=[{requestFullscreenName:"requestFullscreen",exitFullscreenName:"exitFullscreen",fullscreenElementName:"fullscreenElement",fullscreenEnabledName:"fullscreenEnabled",changeEventName:"fullscreenchange",errorEventName:"fullscreenerror"},{requestFullscreenName:"webkitRequestFullscreen",exitFullscreenName:"webkitExitFullscreen",fullscreenElementName:"webkitFullscreenElement",fullscreenEnabledName:"webkitFullscreenEnabled",changeEventName:"webkitfullscreenchange",errorEventName:"webkitfullscreenerror"},{requestFullscreenName:"webkitRequestFullScreen",exitFullscreenName:"webkitCancelFullScreen",fullscreenElementName:"webkitCurrentFullScreenElement",fullscreenEnabledName:"webkitCancelFullScreen",changeEventName:"webkitfullscreenchange",errorEventName:"webkitfullscreenerror"},{requestFullscreenName:"mozRequestFullScreen",exitFullscreenName:"mozCancelFullScreen",fullscreenElementName:"mozFullScreenElement",fullscreenEnabledName:"mozFullScreenEnabled",changeEventName:"mozfullscreenchange",errorEventName:"mozfullscreenerror"},{requestFullscreenName:"msRequestFullscreen",exitFullscreenName:"msExitFullscreen",fullscreenElementName:"msFullscreenElement",fullscreenEnabledName:"msFullscreenEnabled",changeEventName:"MSFullscreenChange",errorEventName:"MSFullscreenError"}].find((({exitFullscreenName:e})=>e in document));const n={change:e.names?.changeEventName,error:e.names?.errorEventName};function r(){if(!e.names)throw new e.UnavailableError;return Boolean(document[e.names.fullscreenElementName])}function l(e,r,l){const
|
|
1
|
+
import{es5ErrorCompat}from"@js-toolkit/utils/es5ErrorCompat";import{promisify}from"@js-toolkit/utils/promisify";export class FullscreenUnavailableError extends Error{constructor(){super("Fullscreen is not available"),es5ErrorCompat(this,FullscreenUnavailableError)}}export var fullscreen;!function(e){e.names=[{requestFullscreenName:"requestFullscreen",exitFullscreenName:"exitFullscreen",fullscreenElementName:"fullscreenElement",fullscreenEnabledName:"fullscreenEnabled",changeEventName:"fullscreenchange",errorEventName:"fullscreenerror"},{requestFullscreenName:"webkitRequestFullscreen",exitFullscreenName:"webkitExitFullscreen",fullscreenElementName:"webkitFullscreenElement",fullscreenEnabledName:"webkitFullscreenEnabled",changeEventName:"webkitfullscreenchange",errorEventName:"webkitfullscreenerror"},{requestFullscreenName:"webkitRequestFullScreen",exitFullscreenName:"webkitCancelFullScreen",fullscreenElementName:"webkitCurrentFullScreenElement",fullscreenEnabledName:"webkitCancelFullScreen",changeEventName:"webkitfullscreenchange",errorEventName:"webkitfullscreenerror"},{requestFullscreenName:"mozRequestFullScreen",exitFullscreenName:"mozCancelFullScreen",fullscreenElementName:"mozFullScreenElement",fullscreenEnabledName:"mozFullScreenEnabled",changeEventName:"mozfullscreenchange",errorEventName:"mozfullscreenerror"},{requestFullscreenName:"msRequestFullscreen",exitFullscreenName:"msExitFullscreen",fullscreenElementName:"msFullscreenElement",fullscreenEnabledName:"msFullscreenEnabled",changeEventName:"MSFullscreenChange",errorEventName:"MSFullscreenError"}].find((({exitFullscreenName:e})=>e in document));const n={change:e.names?.changeEventName,error:e.names?.errorEventName};function r(){if(!e.names)throw new e.UnavailableError;return Boolean(document[e.names.fullscreenElementName])}function l(e,r,l){const a=n[e];a&&document.addEventListener(a,r,l)}function a(e,r,l){const a=n[e];a&&document.removeEventListener(a,r,l)}function t(n,r){return new Promise(((t,s)=>{if(!e.names)throw new e.UnavailableError;const c=()=>{a("change",c),a("error",u),t()},u=e=>{a("change",c),a("error",u),s(e)};l("change",c),l("error",u),n[e.names.requestFullscreenName](r)}))}function s(){return new Promise(((n,t)=>{if(!e.names)throw new e.UnavailableError;if(!r())return void n();const s=()=>{a("change",s),a("error",c),n()},c=e=>{a("change",s),a("error",c),t(e)};l("change",s),l("error",c),document[e.names.exitFullscreenName]()}))}e.UnavailableError=FullscreenUnavailableError,e.isApiAvailable=function(){return!!e.names},e.isApiEnabled=function(){return!!e.names&&Boolean(document[e.names.fullscreenEnabledName])},e.isFullscreen=r,e.getElement=function(){if(!e.names)throw new e.UnavailableError;return document[e.names.fullscreenElementName]},e.on=l,e.off=a,e.request=t,e.exit=s,e.toggle=function(e){return promisify((()=>r()?s():t(e)))},e.onChange=function(e){l("change",e)},e.onError=function(e){l("error",e)}}(fullscreen||(fullscreen={}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function enterPseudoFullscreen(element: Element & ElementCSSInlineStyle): VoidFunction;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function enterPseudoFullscreen(t){let e,i;return e={position:t.style.position,left:t.style.left,top:t.style.top,width:t.style.width,height:t.style.height,maxWidth:t.style.maxWidth,maxHeight:t.style.maxHeight,zIndex:t.style.zIndex},i=t,i.style.position="fixed",i.style.left="0px",i.style.top="0px",i.style.width="100%",i.style.height="100%",i.style.maxWidth="100%",i.style.maxHeight="100%",i.style.zIndex="99999",()=>{e&&i&&(i.style.position=e.position,i.style.left=e.left,i.style.top=e.top,i.style.width=e.width,i.style.height=e.height,i.style.maxWidth=e.maxWidth,i.style.maxHeight=e.maxHeight,i.style.zIndex=e.zIndex),e=void 0,i=void 0}}
|
package/getAspectRatio.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export interface AspectRatio {
|
|
2
|
-
/** Approximate width
|
|
2
|
+
/** Approximate ratio of the width. Eg. 16 of 16/9. */
|
|
3
3
|
width: number;
|
|
4
|
-
/** Approximate height
|
|
4
|
+
/** Approximate ratio of the height. Eg. 9 of 16/9. */
|
|
5
5
|
height: number;
|
|
6
|
-
/** Actual ratio value */
|
|
6
|
+
/** Actual ratio value. */
|
|
7
7
|
ratio: number;
|
|
8
8
|
}
|
|
9
9
|
/** Approximate aspect ratio */
|
package/getEventAwaiter.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { type Awaiter } from '@js-toolkit/utils/getAwaiter';
|
|
1
|
+
import { type Awaiter, type AwaiterOptions } from '@js-toolkit/utils/getAwaiter';
|
|
2
2
|
import { type EmitterTarget, type EventTargetLike, type GetEventType, type GetEventTypeFromFn } from './EventEmitterListener.utils';
|
|
3
|
-
export type EventAwaiter = Awaiter<
|
|
4
|
-
interface Options {
|
|
3
|
+
export type EventAwaiter = Awaiter<any>;
|
|
4
|
+
interface Options extends AwaiterOptions {
|
|
5
5
|
/** If it returns true then resolve is ignored. */
|
|
6
6
|
readonly ignoreResolve?: (event: any) => boolean;
|
|
7
7
|
/** If it returns null or undefined then reject is ignored. */
|
|
8
8
|
readonly eventToError?: (event: any) => unknown;
|
|
9
9
|
}
|
|
10
|
-
export declare function getEventAwaiter<T extends EmitterTarget, E extends T extends EventTargetLike ? GetEventTypeFromFn<OverloadToUnion<T['addEventListener']>> : GetEventType<T>>(target: T, resolveEvent: E | E[], rejectEvent?: E | E[], { ignoreResolve, eventToError }?: Options): EventAwaiter;
|
|
10
|
+
export declare function getEventAwaiter<T extends EmitterTarget, E extends T extends EventTargetLike ? GetEventTypeFromFn<OverloadToUnion<T['addEventListener']>> : GetEventType<T>>(target: T, resolveEvent: E | E[], rejectEvent?: E | E[], { ignoreResolve, eventToError, lazy, ...rest }?: Options): EventAwaiter;
|
|
11
11
|
export {};
|
package/getEventAwaiter.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getAwaiter}from"@js-toolkit/utils/getAwaiter";import{EventEmitterListener}from"./EventEmitterListener";import{isEventEmitterLike}from"./EventEmitterListener.utils";export function getEventAwaiter(e,t,r,{ignoreResolve:i,eventToError:o}={}){const
|
|
1
|
+
import{getAwaiter}from"@js-toolkit/utils/getAwaiter";import{EventEmitterListener}from"./EventEmitterListener";import{isEventEmitterLike}from"./EventEmitterListener.utils";export function getEventAwaiter(e,t,r,{ignoreResolve:i,eventToError:o,lazy:n=!0,...s}={}){const E=getAwaiter({lazy:n,...s}),a=Array.isArray(t)?t:[t],f=Array.isArray(r)?r:[r],m=isEventEmitterLike(e)?e:new EventEmitterListener(e),v=e=>{!(!!i&&i(e))&&E.resolve(e)},c=e=>{const t=o?o(e):e;null!=t&&E.reject(t)},l=()=>{a.forEach((e=>m.off(e,v))),f.forEach((e=>m.off(e,c)))},A=E.resolve;E.resolve=(...e)=>(l(),A(...e));const y=E.reject;return E.reject=(...e)=>{y(...e),l()},a.forEach((e=>m.on(e,v))),f.forEach((e=>m.on(e,c))),E}
|
package/getGeoLocality.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export function getGeoLocality({longitude:e,latitude:r,lang:o}){const s=new URL("https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode");return s.searchParams.set("f","json"),s.searchParams.set("featureTypes","Locality"),s.searchParams.set("location",`{ x: ${e}, y: ${r} }`),o&&s.searchParams.set("langCode",o),window.fetch(s.toString()).then((e=>e.json())).then((e=>{const{address:r,error:o}=e;if(o)throw new Error(o
|
|
1
|
+
import{getErrorMessage}from"@js-toolkit/utils/getErrorMessage";export function getGeoLocality({longitude:e,latitude:r,lang:o}){const s=new URL("https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode");return s.searchParams.set("f","json"),s.searchParams.set("featureTypes","Locality"),s.searchParams.set("location",`{ x: ${e}, y: ${r} }`),o&&s.searchParams.set("langCode",o),window.fetch(s.toString()).then((e=>e.json())).then((e=>{const{address:r,error:o}=e;if(o)throw new Error(getErrorMessage(o),{cause:o});return r.PlaceName||r.LongLabel||r.ShortLabel||""}))}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import log from '@js-toolkit/utils/log';
|
|
1
2
|
import { type MessagesTypes } from './messages';
|
|
2
3
|
import { type Target } from './utils';
|
|
3
4
|
export { getClientMessages, getHostMessages } from './messages';
|
|
@@ -27,7 +28,7 @@ export type AutoConnectorOptions<SendData = AnyObject, ReceiveData = unknown> =
|
|
|
27
28
|
readonly messagesTypes: MessagesTypes;
|
|
28
29
|
/** Process messages only from targets passed to `start` method. Default `true`. */
|
|
29
30
|
readonly strictTargets?: boolean;
|
|
30
|
-
readonly logger?: Pick<
|
|
31
|
+
readonly logger?: Pick<log.Logger, 'v1' | 'warn'> | undefined;
|
|
31
32
|
} & ({
|
|
32
33
|
readonly channel: 'open' | 'use';
|
|
33
34
|
readonly onConnect: (info: ConnectTargetInfo<ReceiveData>, port: MessagePort) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{v4 as uuid}from"uuid";import{onDOMReady}from"../onDOMReady";import{isPingMessage,isTargetReadyMessage}from"./messages";import{isWindowProxy,readTargets}from"./utils";import{getOriginFromMessage}from"./getOriginFromMessage";export{getClientMessages,getHostMessages}from"./messages";export function getAutoConnector({id:e,label:t,strictTargets:
|
|
1
|
+
import{v4 as uuid}from"uuid";import log from"@js-toolkit/utils/log";import{onDOMReady}from"../onDOMReady";import{isPingMessage,isTargetReadyMessage}from"./messages";import{isWindowProxy,readTargets}from"./utils";import{getOriginFromMessage}from"./getOriginFromMessage";export{getClientMessages,getHostMessages}from"./messages";export function getAutoConnector({id:e,label:t,strictTargets:o=!0,messagesTypes:s,channel:n,logger:i=log.getLogger("AutoConnector"),onSendData:r,onConnect:a}){const d=e||uuid(),g=t||d,c=new Map,f="open"===n?new Map:void 0;let u,l;const p=(e,t,o,s,n)=>{if(window!==t)if(isWindowProxy(t)){t.postMessage(e,o,n);const r=t===window.parent?"iframe parent":"iframe";i.v1(`${g}: Post message to ${r} (uid=${s},self.uid=${d},origin=${o}):`,e)}else t.postMessage(e,n&&{transfer:n}),i.v1(`${g}: Post message to MessageEventSource (uid=${s},self.uid=${d}):`,e)},m=(e,t,o)=>{p({uid:d,type:s.Ping},e,t,o)},h=e=>{if(!e.source||e.source===window)return;if(!isPingMessage(e.data,s)&&!isTargetReadyMessage(e.data,s))return;if(e.data.uid===d)return;const t=e.source,l=e.data.uid;if(i.v1(`${g}: Receive message from iframe (uid=${l},self.uid=${d},origin=${e.origin}):`,e.data),o&&u&&!u.has(t))return void i.v1(`${g}: Could not find target (uid=${l},self.uid=${d}) by message.source.`);const h=getOriginFromMessage(e);if(isPingMessage(e.data,s)&&!c.get(l)?.Ping)return c.set(l,{...c.get(l),Ping:!0}),void m(t,h,l);let w=!1;if(c.get(l)?.Ping&&!c.get(l)?.SelfReady){c.set(l,{...c.get(l),SelfReady:!0});const e={target:t,origin:h},o=f?(()=>{const t=f.get(l)?.[0]??new MessageChannel;return f.set(l,[t,e]),t.port2})():void 0;((e,t,o,n,i)=>{p({uid:d,type:s.SelfReady,data:e},t,o,n,i?[i]:void 0)})(r?r(e):void 0,t,h,l,o),w=!1}if(isTargetReadyMessage(e.data,s)&&c.get(l)?.SelfReady){c.delete(l),u?.delete(t);const o=(()=>{if("open"===n){const e=f?.get(l)?.[0].port1;if(!e)throw new Error("Something went wrong: MessageChannel is not created despite the fact that the `channel` option is `open`.");return e}if("use"===n){const t=e.ports[0];if(!t)throw new Error("MessagePort is not received despite the fact that the `channel` option is `use`. The `channel` option of connector on another side must be equals `open`.");return t}})(),{data:s}=e.data,r=()=>{i.v1(`${g}: Connection established (self.uid=${d} + uid=${l}).`),a({data:s,target:t,origin:h},o)};w?setTimeout(r,0):r()}},w=()=>{l&&(l(),l=void 0)};return{start:(e,t={})=>{if(l&&!t.append)return void i.warn(`${g}: Already started. You should first call \`stop\`.`);if(t.append){const e=u;w(),u=e}const o=()=>{const o=(()=>{const t="function"==typeof e?e():e;return t.length>0?t:void 0})(),s=o&&readTargets(o);if(!s)return;const n=new Set(s);t.append?(u||(u=new Set),n.forEach((e=>u.add(e)))):u=n,window.addEventListener("message",h);(t.append?n:u).forEach((e=>{e!==window&&m(e,"*","")}))},s="function"==typeof e?onDOMReady(o):o();l=()=>{s&&s(),window.removeEventListener("message",h),u=void 0}},stop:w,isStarted:()=>!!l,close:e=>{const t=e instanceof Set?e:new Set(readTargets(e));if(0!==t.size&&(f&&f.forEach((([e,o],s)=>{t.has(o.target)&&(e.port1.close(),e.port2.close(),f.delete(s))})),u)){const e=u;t.forEach((t=>e.delete(t)))}},destroy:()=>{w(),c.clear(),f&&(f.forEach((([e])=>{e.port1.close(),e.port2.close()})),f.clear())},[Symbol.dispose](){this.destroy()}}}
|
package/imageToBlob.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export function imageToBlob(
|
|
1
|
+
import{get2dContextError}from"./takeSnapshot";export function imageToBlob(t){return new Promise(((e,o)=>{const r=document.createElement("canvas");r.width=t.width,r.height=t.height;const n=r.getContext("2d");if(!n)throw get2dContextError();n.drawImage(t,0,0),r.toBlob((t=>{t?e(t):o(new Error("Unable to get blob from image."))}))}))}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{EventEmitter}from"eventemitter3";import{EventListeners}from"../../EventListeners";import{MediaNotAttachedError}from"../MediaNotAttachedError";import{parseTextTracks,setActiveTextTrack,addTextTracks,isIOSFullscreen,splitRows,buildCueId}from"./utils";function dispatchNativeEvent(t,e,s){t.dispatchEvent(new CustomEvent(e,{detail:s}))}export class TextTracksController extends EventEmitter{options;eventListeners=new EventListeners;addedTracks=[];textTrackList=[];media;textTrack;nextTextTrack;get Events(){return TextTracksController.Events}constructor(t){super(),this.options={emitNativeEvents:!1,hideActiveTrack:!0,preferCueRowLength:0},t&&this.setOptions(t)}setOptions(t){Object.assign(this.options,{...t,emitNativeEvents:t.emitNativeEvents??this.options.emitNativeEvents,hideActiveTrack:t.hideActiveTrack??this.options.hideActiveTrack,preferCueRowLength:t.preferCueRowLength??this.options.preferCueRowLength})}isAttached(){return!!this.media}getMediaElement(){if(!this.media)throw new MediaNotAttachedError;return this.media}detach(){this.eventListeners.removeAllListeners(),this.media=void 0,this.addedTracks=[],this.textTrackList=[],this.textTrack=void 0,this.nextTextTrack=void 0}attach(t){this.detach();const e=(()=>{const e=[];return s=>{const{activeCues:i}=s.target;if(!i)return;let a=e.length!==i.length;const r=new Array(i.length);for(let t=0;t<r.length;t+=1){const s=i[t];s.id=s.id||buildCueId(s,t),r[t]=s,r[t].rows=splitRows(s.text,this.options.preferCueRowLength),a||e[t]?.id===s.id||(a=!0),e[t]=s}e.length>r.length&&e.splice(r.length-e.length),a&&(this.emit(this.Events.TextTrackCueChanged,{textTrack:s.target,cues:r}),this.options.emitNativeEvents&&dispatchNativeEvent(t,"texttrackcuechange",{textTrack:s.target,cues:r}))}})(),s=()=>{this.textTrackList=parseTextTracks(t),this.emit(this.Events.TextTrackListChanged,{textTracks:this.textTrackList}),this.options.emitNativeEvents&&dispatchNativeEvent(t,"texttracklistchange",{textTracks:this.textTrackList}),setActiveTextTrack(t,this.textTrack??this.nextTextTrack,this.options.hideActiveTrack&&!isIOSFullscreen(t))};this.media=t
|
|
1
|
+
import{EventEmitter}from"eventemitter3";import{EventListeners}from"../../EventListeners";import{MediaNotAttachedError}from"../MediaNotAttachedError";import{parseTextTracks,setActiveTextTrack,addTextTracks,isIOSFullscreen,splitRows,buildCueId}from"./utils";function dispatchNativeEvent(t,e,s){t.dispatchEvent(new CustomEvent(e,{detail:s}))}export class TextTracksController extends EventEmitter{options;eventListeners=new EventListeners;addedTracks=[];textTrackList=[];media;textTrack;nextTextTrack;get Events(){return TextTracksController.Events}constructor(t){super(),this.options={emitNativeEvents:!1,hideActiveTrack:!0,preferCueRowLength:0},t&&this.setOptions(t)}setOptions(t){Object.assign(this.options,{...t,emitNativeEvents:t.emitNativeEvents??this.options.emitNativeEvents,hideActiveTrack:t.hideActiveTrack??this.options.hideActiveTrack,preferCueRowLength:t.preferCueRowLength??this.options.preferCueRowLength})}isAttached(){return!!this.media}getMediaElement(){if(!this.media)throw new MediaNotAttachedError;return this.media}detach(){this.eventListeners.removeAllListeners(),this.media=void 0,this.addedTracks=[],this.textTrackList=[],this.textTrack=void 0,this.nextTextTrack=void 0}attach(t){this.detach();const e=(()=>{const e=[];return s=>{const{activeCues:i}=s.target;if(!i)return;let a=e.length!==i.length;const r=new Array(i.length);for(let t=0;t<r.length;t+=1){const s=i[t];s.id=s.id||buildCueId(s,t),r[t]=s,r[t].rows=splitRows(s.text,this.options.preferCueRowLength),a||e[t]?.id===s.id||(a=!0),e[t]=s}e.length>r.length&&e.splice(r.length-e.length),a&&(this.emit(this.Events.TextTrackCueChanged,{textTrack:s.target,cues:r}),this.options.emitNativeEvents&&dispatchNativeEvent(t,"texttrackcuechange",{textTrack:s.target,cues:r}))}})(),s=()=>{this.textTrackList=parseTextTracks(t),this.emit(this.Events.TextTrackListChanged,{textTracks:this.textTrackList}),this.options.emitNativeEvents&&dispatchNativeEvent(t,"texttracklistchange",{textTracks:this.textTrackList}),setActiveTextTrack(t,this.textTrack??this.nextTextTrack,this.options.hideActiveTrack&&!isIOSFullscreen(t))};this.media=t;let i=!1;const a=t=>{i||s(),this.eventListeners.scope(t).on("cuechange",e)},r=t=>{s(),this.eventListeners.scope(t).off("cuechange",e)};if(this.eventListeners.scope(this.media.textTracks).on("change",(()=>{const{textTracks:e}=t,{nextTextTrack:s}=this;let i=-1;for(let a=0;a<e.length;a+=1){const r=e[a];if(r.language===s?.language&&r.kind===s?.kind||isIOSFullscreen(t)||(r.mode="disabled"),"disabled"!==r.mode&&i>=0&&(r.mode="disabled"),"disabled"!==r.mode){if(i=a,!r.native&&!isIOSFullscreen(t)){const t=this.options.hideActiveTrack?"hidden":"showing";r.mode!==t&&(r.mode=t)}r.native&&r.language===s?.language&&r.kind===s.kind&&(r.mode="showing")}}const a=e[i]&&(this.textTrackList[i]??{id:e[i].id,kind:e[i].kind,language:e[i].language,label:e[i].label});this.textTrack?.language===a?.language&&this.textTrack?.kind===a?.kind||(this.textTrack=a,this.nextTextTrack=this.textTrack,this.emit(this.Events.CurrentTextTrackChanged,{textTrack:this.textTrack,index:i}),this.options.emitNativeEvents&&dispatchNativeEvent(t,"texttrackchange",{textTrack:this.textTrack,index:i}))})).on("addtrack",(({track:t})=>t&&a(t))).on("removetrack",(({track:t})=>t&&r(t))),this.media.textTracks.length>0){this.textTrackList=parseTextTracks(t),i=!0;try{Array.prototype.forEach.call(this.media.textTracks,a),s()}finally{i=!1}}}getTextTracks(){return this.textTrackList}setTextTracks(t){const e=this.getMediaElement();if(this.eventListeners.scope(e,"@@setTextTracks").removeAllListeners(),this.addedTracks.forEach((t=>t.remove())),0===t.length)return;const s=()=>{addTextTracks(e,t,(t=>this.addedTracks.push(t))),this.textTrackList=parseTextTracks(e)};e.readyState>=e.HAVE_CURRENT_DATA?s():this.eventListeners.scope(e,"@@setTextTracks").once("loadeddata",s)}getActiveTextTrack(){return this.textTrack}setActiveTextTrack(t){const e=this.getMediaElement();return this.nextTextTrack=t&&this.textTrackList.find((e=>e.language===t.language&&(!t.kind||e.kind===t.kind))),setActiveTextTrack(e,this.nextTextTrack,this.options.hideActiveTrack&&!isIOSFullscreen(e))}destroy(){this.detach(),this.removeAllListeners()}[Symbol.dispose](){this.destroy()}}!function(t){let e;!function(t){t.TextTrackListChanged="TrackListChanged",t.CurrentTextTrackChanged="CurrentTextTrackChanged",t.TextTrackCueChanged="TextTrackCueChanged"}(e=t.Events||(t.Events={}))}(TextTracksController||(TextTracksController={}));
|
|
@@ -13,7 +13,7 @@ export declare function fakeDetachTextTracks(media: HTMLMediaElement): void;
|
|
|
13
13
|
export declare function parseTextTracks(media: HTMLMediaElement): TextTrackInfo[];
|
|
14
14
|
export declare function isIOSFullscreen(media: HTMLMediaElement): boolean;
|
|
15
15
|
export declare function setActiveTextTrack(media: HTMLMediaElement, tt: ActivateTextTrackInfo | undefined, hideActiveTrack: boolean): boolean;
|
|
16
|
-
/** Dynamically add text tracks */
|
|
16
|
+
/** Dynamically add text tracks if they not exist. */
|
|
17
17
|
export declare function addTextTracks(media: HTMLMediaElement, textTrackList: readonly TextTrackItem[], onAdd: (el: HTMLTrackElement) => void): void;
|
|
18
18
|
export declare function buildCueId(cue: Pick<TextTrackCue, 'startTime'>, index: number): string;
|
|
19
19
|
export declare function splitRows(text: string, preferLineLength: number): string[];
|
|
@@ -14,4 +14,4 @@ declare global {
|
|
|
14
14
|
ManagedMediaSource?: ManagedMediaSource & typeof MediaSource;
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
export declare function getMediaSource(managedMediaSource?: 'prefer' | 'maybe'
|
|
17
|
+
export declare function getMediaSource(managedMediaSource?: 'prefer' | 'maybe'): typeof MediaSource | undefined;
|
package/media/parseCueText.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{splitRows}from"./TextTracksController/utils";const ESCAPE={"&":"&","<":"<",">":">","‎":"","‏":""," ":" "},TAG_NAME={c:"span",i:"i",b:"b",u:"u",ruby:"ruby",rt:"rt",lang:"span"},TAG_ANNOTATION={v:"title",lang:"lang"},NEEDS_PARENT={rt:"ruby"};function computeSeconds(e,t,n,o){return 3600*(+e||0)+60*(+t||0)+(+n||0)+(+o||0)/1e3}function parseTimeStamp(e){const t=e.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/);if(!t)return;const[,n,o,r,
|
|
1
|
+
import{splitRows}from"./TextTracksController/utils";const ESCAPE={"&":"&","<":"<",">":">","‎":"","‏":""," ":" "},TAG_NAME={c:"span",i:"i",b:"b",u:"u",ruby:"ruby",rt:"rt",lang:"span"},TAG_ANNOTATION={v:"title",lang:"lang"},NEEDS_PARENT={rt:"ruby"};function computeSeconds(e,t,n,o){return 3600*(+e||0)+60*(+t||0)+(+n||0)+(+o||0)/1e3}function parseTimeStamp(e){const t=e.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/);if(!t)return;const[,n,o,r,l]=t;return l?computeSeconds(n,o,r.replace(":",""),l):+n>59?computeSeconds(n,o,"",l):computeSeconds("",n,o,l)}function unescape(e){let t,n=e;for(;t=n.match(/&(amp|lt|gt|lrm|rlm|nbsp);/);)n=n.replace(t[0],(e=>ESCAPE[e]));return n}function nextToken(e){if(!e)return[e,void 0];const t=e.match(/^([^<]*)(<[^>]*>?)?/);if(!t)return[e,void 0];const n=t[1]?t[1]:t[2];return null==n?[e,n]:[e.substring(n.length),n]}function shouldAdd(e,t){return!NEEDS_PARENT[t.localName]||NEEDS_PARENT[t.localName]===e.localName}function createHtmlNode(e,t){const n=TAG_NAME[e];if(!n)return;const o=window.document.createElement(n),r=TAG_ANNOTATION[e];return r&&t&&(o[r]=t.trim()),o}export function parseCueText(e,t,{preferLength:n=0}={}){let o,r,l=e,s=-1;const c=[],a=[],u=[],i=e=>{0===a.length&&a.push([]),a.at(-1).push(t?t(e,(a.at(-1)??a.at(-2))?.at(-1)):e)},p=e=>{const t=c.pop()??"",n=o;if(o=n.parentElement||void 0,null==o){i({id:e,startTime:s>=0?s:void 0,tag:t,node:n})}},d=()=>`${a.length}-${(a.at(-1)?.length??0)+1}`,m=(e,t)=>{t?u.push(e):u[u.length-1]+=e,t&&a.push([]),null==o?(e=>{const t=createHtmlNode("c","");t.appendChild(window.document.createTextNode(unescape(e)));const n={id:d(),node:t,tag:"c",startTime:s>=0?s:void 0};i(n)})(e):o.appendChild(window.document.createTextNode(unescape(e)))};for(;null!=([l,r]=nextToken(l),r);)if("<"===r[0])if("/"===r[1])c.at(-1)===r.substring(2).replace(">","")&&p(d());else{const e=parseTimeStamp(r.substring(1,r.length-1));if(e)s=e;else{const e=r.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/),t=e&&createHtmlNode(e[1],e[3]);!t||o&&!shouldAdd(o,t)||(e[2]&&(t.className=e[2].substring(1).replace("."," ")),c.push(e[1]),o?.appendChild(t),o=t)}}else if(0===u.length||n>0&&u.at(-1).length+r.length>n){const e=splitRows(r,n);for(let t=0;t<e.length;t+=1)m(e[t],!0)}else m(r,!1);return{segments:a,rawText:u}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@js-toolkit/web-utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.60.0",
|
|
4
4
|
"description": "Web utils",
|
|
5
5
|
"author": "VZH",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,32 +20,32 @@
|
|
|
20
20
|
"@js-toolkit/node-utils": "^1.2.1"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@eslint/compat": "^1.2.
|
|
23
|
+
"@eslint/compat": "^1.2.6",
|
|
24
24
|
"@eslint/eslintrc": "^3.2.0",
|
|
25
|
-
"@eslint/js": "^9.
|
|
26
|
-
"@js-toolkit/configs": "^3.
|
|
27
|
-
"@js-toolkit/utils": "^1.
|
|
25
|
+
"@eslint/js": "^9.20.0",
|
|
26
|
+
"@js-toolkit/configs": "^3.94.0",
|
|
27
|
+
"@js-toolkit/utils": "^1.58.0",
|
|
28
28
|
"@types/eslint": "^9.6.1",
|
|
29
29
|
"@types/eslint__eslintrc": "^2.1.2",
|
|
30
30
|
"@types/eslint__js": "^8.42.3",
|
|
31
31
|
"@types/lodash.throttle": "^4.1.9",
|
|
32
32
|
"@types/uuid": "^10.0.0",
|
|
33
33
|
"copyfiles": "^2.4.1",
|
|
34
|
-
"eslint": "^9.
|
|
35
|
-
"eslint-config-prettier": "^
|
|
34
|
+
"eslint": "^9.20.0",
|
|
35
|
+
"eslint-config-prettier": "^10.0.1",
|
|
36
36
|
"eslint-plugin-import": "^2.31.0",
|
|
37
|
-
"eslint-plugin-prettier": "^5.2.
|
|
37
|
+
"eslint-plugin-prettier": "^5.2.3",
|
|
38
38
|
"eventemitter3": "^5.0.1",
|
|
39
39
|
"lodash.throttle": "^4.1.1",
|
|
40
|
-
"prettier": "^3.
|
|
40
|
+
"prettier": "^3.5.0",
|
|
41
41
|
"reconnecting-websocket": "^4.4.0",
|
|
42
42
|
"rimraf": "^6.0.1",
|
|
43
|
-
"terser": "^5.
|
|
44
|
-
"typescript": "^5.
|
|
45
|
-
"typescript-eslint": "^8.
|
|
46
|
-
"ua-parser-js": "^2.0.
|
|
47
|
-
"uuid": "^11.0.
|
|
48
|
-
"webpack": "^5.
|
|
43
|
+
"terser": "^5.38.1",
|
|
44
|
+
"typescript": "^5.7.3",
|
|
45
|
+
"typescript-eslint": "^8.24.0",
|
|
46
|
+
"ua-parser-js": "^2.0.2",
|
|
47
|
+
"uuid": "^11.0.5",
|
|
48
|
+
"webpack": "^5.97.1",
|
|
49
49
|
"yargs": "^17.7.2"
|
|
50
50
|
}
|
|
51
51
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function isTelegramWebView(){return!!window.TelegramWebviewProxy}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { DataEventEmitter, type DataEventListener, type DataEventMap } from '@js-toolkit/utils/DataEventEmitter';
|
|
2
|
+
import log from '@js-toolkit/utils/log';
|
|
2
3
|
import * as sdpUtils from './sdputils';
|
|
3
4
|
export declare class PeerConnection extends DataEventEmitter<PeerConnection.EventMap, PeerConnection> implements Disposable {
|
|
4
5
|
readonly options: PeerConnection.Options;
|
|
5
6
|
get Events(): typeof PeerConnection.Events;
|
|
6
|
-
readonly logger: Pick<
|
|
7
|
+
readonly logger: Pick<log.Logger, "warn" | "debug">;
|
|
7
8
|
private pc;
|
|
8
9
|
constructor(options?: PeerConnection.Options);
|
|
9
10
|
private clear;
|
|
@@ -38,7 +39,7 @@ export declare namespace PeerConnection {
|
|
|
38
39
|
readonly offerOptions?: RTCOfferOptions;
|
|
39
40
|
readonly rtc?: RTCConfiguration;
|
|
40
41
|
readonly codecs?: sdpUtils.PreferCodecs;
|
|
41
|
-
readonly logger?: Pick<
|
|
42
|
+
readonly logger?: Pick<log.Logger, 'debug' | 'warn'> | undefined;
|
|
42
43
|
readonly id?: string;
|
|
43
44
|
}
|
|
44
45
|
enum Events {
|
package/webrtc/PeerConnection.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DataEventEmitter}from"@js-toolkit/utils/DataEventEmitter";import{getErrorMessage}from"@js-toolkit/utils/getErrorMessage";import{hasIn}from"@js-toolkit/utils/hasIn";import*as sdpUtils from"./sdputils";export class PeerConnection extends DataEventEmitter{options;get Events(){return PeerConnection.Events}logger;pc;constructor(e={}){super(),this.options=e,this.logger=e.logger??
|
|
1
|
+
import{DataEventEmitter}from"@js-toolkit/utils/DataEventEmitter";import{getErrorMessage}from"@js-toolkit/utils/getErrorMessage";import{hasIn}from"@js-toolkit/utils/hasIn";import log from"@js-toolkit/utils/log";import*as sdpUtils from"./sdputils";export class PeerConnection extends DataEventEmitter{options;get Events(){return PeerConnection.Events}logger;pc;constructor(e={}){super(),this.options=e,this.logger=e.logger??log.getLogger("PeerConnection"),this.pc=this.createPC()}clear(){this.pc.onsignalingstatechange=null,this.pc.onconnectionstatechange=null,this.pc.oniceconnectionstatechange=null,this.pc.ontrack=null,this.pc.onnegotiationneeded=null,this.pc.onicecandidate=null,this.pc.onicecandidateerror=null}createPC(){const e=new RTCPeerConnection(this.options.rtc);return e.onsignalingstatechange=()=>{this.logger.debug(`Signaling state changed to: ${e.signalingState}`),"closed"===e.signalingState&&(this.emit(this.Events.Closed),this.clear())},hasIn(RTCPeerConnection.prototype,"onconnectionstatechange")?e.onconnectionstatechange=()=>{this.logger.debug(`Connection state changed to: ${e.connectionState}`),"connected"===e.connectionState?this.emit(this.Events.Connected):"disconnected"===e.connectionState&&this.emit(this.Events.Disconnected)}:e.oniceconnectionstatechange=()=>{this.logger.debug(`ICE connection state changed to: ${e.iceConnectionState}`),"connected"===e.iceConnectionState?this.emit(this.Events.Connected):"disconnected"===e.iceConnectionState&&this.emit(this.Events.Disconnected)},e.ontrack=({streams:e,track:t})=>{if(this.logger.debug("Remote stream received.",e.length,t.kind),0===e.length)return;const[n]=e;n.onremovetrack=()=>{this.logger.debug("onremovetrack"),this.emit(this.Events.RemoteStreamChanged,n)},n.onaddtrack=()=>{this.logger.debug("onaddtrack"),this.emit(this.Events.RemoteStreamChanged,n)},this.emit(this.Events.RemoteStreamChanged,n)},e.onnegotiationneeded=()=>{const{iceConnectionState:t}=e;"connected"!==t&&"completed"!==t||(this.logger.debug("Reinitializing connection..."),this.emit(this.Events.ReinitializingConnectionRequired))},e.onicecandidate=({candidate:e})=>{e?sdpUtils.isValidIceCandidate(e)&&this.emit(this.Events.LocalIceCandidate,e):this.emit(this.Events.EndOfIceCandidates)},e.onicecandidateerror=e=>{if(e instanceof RTCPeerConnectionIceErrorEvent){const{errorCode:t,errorText:n,hostCandidate:i,url:o}=e;this.logger.warn(`ICE candidate error: errorCode=${t}, errorText=${n}, hostCandidate=${i}, url=${o}`)}else this.logger.warn(`ICE candidate error: ${getErrorMessage(e)}`)},e}async setLocalDescription(e,t){const n=sdpUtils.prepareLocalDescription(t,this.options.codecs);return await e.setLocalDescription(n),n}async setRemoteDescription(e,t){const n=sdpUtils.prepareRemoteDescription(t,this.options.codecs);return await e.setRemoteDescription(n),n}isConnected(){return"connected"===this.pc.iceConnectionState||"completed"===this.pc.iceConnectionState}isClosed(){return"closed"===this.pc.signalingState}addIceCandidate(e){return this.pc.addIceCandidate(e)}attachStream(e){const t=this.pc.getSenders(),n=t.length?e.getTracks().filter((e=>!t.find((({track:t})=>!!t&&t.id===e.id)))):e.getTracks();n.length?(n.forEach((t=>this.pc.addTrack(t,e))),this.logger.debug(`Attached ${n.length} track(s) to a peer connection.`)):this.logger.debug("No tracks to attach to a peer connection.")}reattachStream(e){const t=this.pc.iceConnectionState;if("new"!==t&&"connected"!==t&&"completed"!==t)return;const n=e?e.getTracks():[];this.pc.getSenders().forEach((e=>{const{track:t}=e;!t||"ended"!==t.readyState&&n.find((e=>e.id===t.id))||(this.pc.removeTrack(e),this.logger.debug(`'${t&&t.kind}' track is removed from a peer connection.`))})),e&&this.attachStream(e)}async createOffer(){const e=await this.pc.createOffer(this.options.offerOptions);return this.setLocalDescription(this.pc,e)}async createAnswer(e){await this.setRemoteDescription(this.pc,e);const t=await this.pc.createAnswer(this.options.offerOptions);return this.setLocalDescription(this.pc,t)}applyAnswer(e){return this.setRemoteDescription(this.pc,e)}reconnect(){this.close(),this.pc=this.createPC()}close(){this.pc.close(),this.pc.onsignalingstatechange&&(this.emit(this.Events.Closed),this.clear())}destroy(){this.close(),this.removeAllListeners()}[Symbol.dispose](){this.destroy()}}!function(e){let t;!function(e){e.LocalIceCandidate="LocalIceCandidate",e.EndOfIceCandidates="EndOfIceCandidates",e.Connected="Connected",e.Disconnected="Disconnected",e.RemoteStreamChanged="RemoteStreamChanged",e.ReinitializingConnectionRequired="ReinitializingConnectionRequired",e.Closed="Closed"}(t=e.Events||(e.Events={}))}(PeerConnection||(PeerConnection={}));
|