@js-toolkit/web-utils 1.62.2 → 1.64.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.
@@ -5,6 +5,7 @@ type GetOffOptions<T extends EmitterTarget> = T extends DomEventTarget ? boolean
5
5
  interface GetListenersOptions {
6
6
  event?: string | undefined;
7
7
  type?: 'normal' | 'capture' | undefined;
8
+ wrapper?: boolean | undefined;
8
9
  }
9
10
  export declare class EventEmitterListener<T extends EmitterTarget, M extends AnyObject = GetEventMap<T>> {
10
11
  readonly target: T;
@@ -14,8 +15,8 @@ export declare class EventEmitterListener<T extends EmitterTarget, M extends Any
14
15
  readonly passiveSupported: boolean;
15
16
  constructor(target: T, interceptor?: ((...args: any[]) => [...args: unknown[]] | undefined) | undefined);
16
17
  private createWrapper;
17
- getListenerList<L = unknown>({ event, type }?: GetListenersOptions): L[];
18
- getListeners<L = unknown>({ event, type }?: GetListenersOptions): Record<string, L[]>;
18
+ getListenerList<L = unknown>({ event, type, wrapper }?: GetListenersOptions): L[];
19
+ getListeners<L = unknown>({ event, type, wrapper }?: GetListenersOptions): Record<string, L[]>;
19
20
  has<K extends GetEventType<T>>(type: K, listener?: GetEventListener<T, K, M>, ...rest: [
20
21
  ...(T extends DomEventTarget ? [options?: GetOffOptions<T> | undefined] : []),
21
22
  ...unknown[]
@@ -1 +1 @@
1
- import{isPassiveSupported,isDomEventTarget,isEventTargetLike,normalizeOptions}from"./EventEmitterListener.utils";export class EventEmitterListener{target;interceptor;normalListeners={};captureListeners={};passiveSupported=isPassiveSupported();constructor(t,e){this.target=t,this.interceptor=e,this.target=t}createWrapper(t,e,s,...r){return(...i)=>{s&&this.off(t,e,...r);const n=this.interceptor&&this.interceptor(...i)||i;e(...n)}}getListenerList({event:t,type:e}={}){const s="normal"===e&&this.normalListeners||"capture"===e&&this.captureListeners||void 0;if(s){const e=t?s[t]&&{[t]:s[t]}:s;return e?Object.values(e).flatMap((t=>t?Array.from(t.keys()):[])):[]}return this.getListenerList({event:t,type:"normal"}).concat(this.getListenerList({event:t,type:"capture"}))}getListeners({event:t,type:e}={}){const s="normal"===e&&this.normalListeners||"capture"===e&&this.captureListeners||void 0;if(!s){const e=this.getListeners({event:t,type:"normal"}),s=this.getListeners({event:t,type:"capture"}),r={},i=([t,e])=>{const s=r[t];r[t]=s?s.concat(e):e};return Object.entries(e).forEach(i),Object.entries(s).forEach(i),r}const r=t?s[t]&&{[t]:s[t]}:s;return r?Object.entries(r).reduce(((t,[e,s])=>{const r=s?Array.from(s.keys()):[];return r.length>0&&(t[e]=r),t}),{}):{}}has(t,e,...s){if(!isDomEventTarget(this.target)){const s=this.normalListeners[t];return!!s&&(e?s.has(e):s.size>0)}const r=s[0],i=!0===r||r&&"object"==typeof r&&(r.capture??!1)?this.captureListeners[t]:this.normalListeners[t];return!!i&&(e?i.has(e):i.size>0)}on(t,e,...s){if(!isDomEventTarget(this.target)){const r=this.normalListeners[t]??new Map;this.normalListeners[t]=r;const i=r.get(e)??(this.interceptor?this.createWrapper(t,e,!1):e);return!r.has(e)&&r.set(e,i),isEventTargetLike(this.target)?this.target.addEventListener(t,i,...s):this.target.on(t,i,...s),this}const r=s[0],i=!0===r||r&&"object"==typeof r&&(r.capture??!1),n=(r&&"object"==typeof r&&r.once)??!1;if(i){const s=this.captureListeners[t]??new Map;this.captureListeners[t]=s;const i=s.get(e)??this.createWrapper(t,e,n,r);!s.has(e)&&s.set(e,i),this.target.addEventListener(t,i,normalizeOptions(r))}else{const s=this.normalListeners[t]??new Map;this.normalListeners[t]=s;const i=s.get(e)??this.createWrapper(t,e,n,r);!s.has(e)&&s.set(e,i),this.target.addEventListener(t,i,normalizeOptions(r))}return this}once(t,e,...s){if(!isDomEventTarget(this.target)){const r=this.normalListeners[t]??new Map;this.normalListeners[t]=r;const i=r.get(e)??this.createWrapper(t,e,!0,...s);return!r.has(e)&&r.set(e,i),isEventTargetLike(this.target)?this.target.addEventListener(t,i,...s):this.target.once?this.target.once(t,i,...s):this.target.on(t,i,...s),this}const r=s[0];return this.on(t,e,{..."object"==typeof r?r:null!=r&&{capture:r},once:!0})}off(t,e,...s){if(!isDomEventTarget(this.target)){const r=this.normalListeners[t],i=r?.get(e);return r&&i&&r.delete(e),0===r?.size&&delete this.normalListeners[t],isEventTargetLike(this.target)?this.target.removeEventListener(t,i??e,...s):this.target.off(t,i??e,...s),this}const r=s[0],i=!0===r||r&&"object"==typeof r&&(r.capture??!1),n=i?this.captureListeners[t]:this.normalListeners[t],o=n?.get(e);return n&&o&&n.delete(e),0===n?.size&&(i?delete this.captureListeners[t]:delete this.normalListeners[t]),this.target.removeEventListener(t,o??e,normalizeOptions(r)),this}removeAllListeners(t){if(t){const e=this.normalListeners[t];e&&e.forEach(((e,s)=>this.off(t,s)));const s=this.captureListeners[t];s&&s.forEach(((e,s)=>this.off(t,s,!0)))}else Object.keys(this.normalListeners).forEach((t=>this.removeAllListeners(t))),Object.keys(this.captureListeners).forEach((t=>this.removeAllListeners(t)));return this}removeAllListenersBut(...t){return 0===t.length?this.removeAllListeners():(Object.keys(this.normalListeners).forEach((e=>!t.includes(e)&&this.removeAllListeners(e))),Object.keys(this.captureListeners).forEach((e=>!t.includes(e)&&this.removeAllListeners(e))),this)}emit(t,...e){const[s,...r]=e;return this.getListenerList({event:t}).forEach((t=>{t(s,...r)})),this}}
1
+ import{isPassiveSupported,isDomEventTarget,isEventTargetLike,normalizeOptions}from"./EventEmitterListener.utils";function getEventTypeError(){return new Error("Event type can not be null.")}function getEventListenerError(){return new Error("Event listener can not be null.")}export class EventEmitterListener{target;interceptor;normalListeners={};captureListeners={};passiveSupported=isPassiveSupported();constructor(e,t){this.target=e,this.interceptor=t,this.target=e}createWrapper(e,t,r,...s){return(...n)=>{r&&this.off(e,t,...s);const i=this.interceptor&&this.interceptor(...n)||n;t(...i)}}getListenerList({event:e,type:t,wrapper:r}={}){const s="normal"===t&&this.normalListeners||"capture"===t&&this.captureListeners||void 0;if(s){const t=e?s[e]&&{[e]:s[e]}:s;return t?Object.values(t).flatMap((e=>e?Array.from(r?e.values():e.keys()):[])):[]}return this.getListenerList({event:e,type:"normal",wrapper:r}).concat(this.getListenerList({event:e,type:"capture",wrapper:r}))}getListeners({event:e,type:t,wrapper:r}={}){const s="normal"===t&&this.normalListeners||"capture"===t&&this.captureListeners||void 0;if(!s){const t=this.getListeners({event:e,type:"normal",wrapper:r}),s=this.getListeners({event:e,type:"capture",wrapper:r}),n={},i=([e,t])=>{const r=n[e];n[e]=r?r.concat(t):t};return Object.entries(t).forEach(i),Object.entries(s).forEach(i),n}const n=e?s[e]&&{[e]:s[e]}:s;return n?Object.entries(n).reduce(((e,[t,s])=>{const n=s?Array.from(r?s.values():s.keys()):[];return n.length>0&&(e[t]=n),e}),{}):{}}has(e,t,...r){if(!isDomEventTarget(this.target)){const r=this.normalListeners[e];return!!r&&(t?r.has(t):r.size>0)}const s=r[0],n=!0===s||s&&"object"==typeof s&&(s.capture??!1)?this.captureListeners[e]:this.normalListeners[e];return!!n&&(t?n.has(t):n.size>0)}on(e,t,...r){if(null==e)throw getEventTypeError();if(null==t)throw getEventListenerError();if(!isDomEventTarget(this.target)){const s=this.normalListeners[e]??new Map;this.normalListeners[e]=s;const n=s.get(t)??(this.interceptor?this.createWrapper(e,t,!1,...r):t);return!s.has(t)&&s.set(t,n),isEventTargetLike(this.target)?this.target.addEventListener(e,n,...r):this.target.on(e,n,...r),this}const s=r[0],n=!0===s||s&&"object"==typeof s&&(s.capture??!1),i=(s&&"object"==typeof s&&s.once)??!1;if(n){const n=this.captureListeners[e]??new Map;this.captureListeners[e]=n;const o=n.get(t)??this.createWrapper(e,t,i,...r);!n.has(t)&&n.set(t,o),this.target.addEventListener(e,o,normalizeOptions(s))}else{const n=this.normalListeners[e]??new Map;this.normalListeners[e]=n;const o=n.get(t)??this.createWrapper(e,t,i,...r);!n.has(t)&&n.set(t,o),this.target.addEventListener(e,o,normalizeOptions(s))}return this}once(e,t,...r){if(null==e)throw getEventTypeError();if(null==t)throw getEventListenerError();if(!isDomEventTarget(this.target)){const s=this.normalListeners[e]??new Map;this.normalListeners[e]=s;const n=s.get(t)??this.createWrapper(e,t,!0,...r);return!s.has(t)&&s.set(t,n),isEventTargetLike(this.target)?this.target.addEventListener(e,n,...r):this.target.once?this.target.once(e,n,...r):this.target.on(e,n,...r),this}const s=r[0];return this.on(e,t,{..."object"==typeof s?s:null!=s&&{capture:s},once:!0})}off(e,t,...r){if(!isDomEventTarget(this.target)){const s=this.normalListeners[e],n=s?.get(t);return s&&n&&s.delete(t),0===s?.size&&delete this.normalListeners[e],isEventTargetLike(this.target)?this.target.removeEventListener(e,n??t,...r):this.target.off(e,n??t,...r),this}const s=r[0],n=!0===s||s&&"object"==typeof s&&(s.capture??!1),i=n?this.captureListeners[e]:this.normalListeners[e],o=i?.get(t);return i&&o&&i.delete(t),0===i?.size&&(n?delete this.captureListeners[e]:delete this.normalListeners[e]),this.target.removeEventListener(e,o??t,normalizeOptions(s)),this}removeAllListeners(e){if(e){const t=this.normalListeners[e];t&&t.forEach(((t,r)=>this.off(e,r)));const r=this.captureListeners[e];r&&r.forEach(((t,r)=>this.off(e,r,!0)))}else Object.keys(this.normalListeners).forEach((e=>this.removeAllListeners(e))),Object.keys(this.captureListeners).forEach((e=>this.removeAllListeners(e)));return this}removeAllListenersBut(...e){return 0===e.length?this.removeAllListeners():(Object.keys(this.normalListeners).forEach((t=>!e.includes(t)&&this.removeAllListeners(t))),Object.keys(this.captureListeners).forEach((t=>!e.includes(t)&&this.removeAllListeners(t))),this)}emit(e,...t){if(null==e)throw getEventTypeError();const[r,...s]=t;return this.getListenerList({event:e,wrapper:!0}).forEach((e=>{e(r,...s)})),this}}
@@ -23,7 +23,7 @@ export type GetEventListener<T extends EmitterTarget, E, EM extends AnyObject =
23
23
  type ListenersMapToEventMap<T extends Record<string, AnyFunction[]>> = {
24
24
  [P in keyof T]: Parameters<T[P][number]>[0];
25
25
  };
26
- export type GetEventMap<T> = T extends Document ? DocumentEventMap : T extends HTMLBodyElement ? HTMLBodyElementEventMap : T extends HTMLVideoElement ? HTMLVideoElementEventMap : T extends HTMLMediaElement ? HTMLMediaElementEventMap : T extends TextTrackList ? TextTrackListEventMap : T extends HTMLElement ? HTMLElementEventMap : T extends Element ? ElementEventMap : T extends Animation ? AnimationEventMap : T extends AbortSignal ? AbortSignalEventMap : T extends BroadcastChannel ? BroadcastChannelEventMap : T extends WebSocket ? WebSocketEventMap : T extends MediaStreamTrack ? MediaStreamTrackEventMap : T extends MediaStream ? MediaStreamEventMap : T extends EventSource ? EventSourceEventMap : T extends SourceBuffer ? SourceBufferEventMap : T extends SourceBufferList ? SourceBufferListEventMap : T extends EventEmitter<any, any> ? ListenersMapToEventMap<ReturnType<T['getEventListeners']>> : EmptyObject;
26
+ export type GetEventMap<T> = T extends Window ? WindowEventMap : T extends ServiceWorker ? ServiceWorkerEventMap : T extends Worker ? WorkerEventMap : T extends ShadowRoot ? ShadowRootEventMap : T extends Document ? DocumentEventMap : T extends HTMLBodyElement ? HTMLBodyElementEventMap : T extends HTMLVideoElement ? HTMLVideoElementEventMap : T extends HTMLMediaElement ? HTMLMediaElementEventMap : T extends TextTrackList ? TextTrackListEventMap : T extends HTMLElement ? HTMLElementEventMap : T extends Element ? ElementEventMap : T extends TextTrackList ? TextTrackListEventMap : T extends TextTrackCue ? TextTrackCueEventMap : T extends Animation ? AnimationEventMap : T extends AbortSignal ? AbortSignalEventMap : T extends BroadcastChannel ? BroadcastChannelEventMap : T extends WebSocket ? WebSocketEventMap : T extends MediaStreamTrack ? MediaStreamTrackEventMap : T extends MediaStream ? MediaStreamEventMap : T extends EventSource ? EventSourceEventMap : T extends SourceBuffer ? SourceBufferEventMap : T extends SourceBufferList ? SourceBufferListEventMap : T extends RemotePlayback ? RemotePlaybackEventMap : T extends EventEmitter<any, any> ? ListenersMapToEventMap<ReturnType<T['getEventListeners']>> : EmptyObject;
27
27
  export declare function isEventTargetLike(target: EmitterTarget): target is EventTargetLike;
28
28
  export declare function isDomEventTarget(target: EmitterTarget): target is DomEventTarget;
29
29
  export declare function isEventEmitterLike(target: EmitterTarget): target is EventEmitterLike;
@@ -0,0 +1,9 @@
1
+ declare global {
2
+ interface PermissionDescriptorNew {
3
+ name: PermissionName | 'clipboard-write';
4
+ }
5
+ interface Permissions {
6
+ query(permissionDesc: PermissionDescriptorNew): Promise<PermissionStatus>;
7
+ }
8
+ }
9
+ export declare function checkPermission(name: PermissionDescriptorNew['name']): Promise<PermissionState | undefined>;
@@ -0,0 +1 @@
1
+ export async function checkPermission(t){try{return(await(navigator.permissions?.query?.({name:t}))).state}catch{}}
@@ -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,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}
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&&[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}
@@ -8,12 +8,13 @@ declare global {
8
8
  }
9
9
  }
10
10
  export declare class PipController extends EventEmitter<PipController.EventMap> implements AsyncDisposable {
11
+ private readonly options;
11
12
  private static isApiEnabled;
12
13
  private static isWebkitApiEnabled;
13
14
  static isAvailable(video: HTMLVideoElement): boolean;
14
15
  get Events(): typeof PipController.Events;
15
16
  private readonly listener;
16
- constructor(video: HTMLVideoElement);
17
+ constructor(video: HTMLVideoElement, options?: PipController.Options);
17
18
  isPip(): boolean;
18
19
  getCurrentElement(): HTMLVideoElement | null;
19
20
  request(): Promise<void>;
@@ -22,6 +23,9 @@ export declare class PipController extends EventEmitter<PipController.EventMap>
22
23
  [Symbol.asyncDispose](): PromiseLike<void>;
23
24
  }
24
25
  export declare namespace PipController {
26
+ interface Options {
27
+ readonly toggleNativeSubtitles?: boolean | undefined;
28
+ }
25
29
  enum Events {
26
30
  Change = "change"
27
31
  }
@@ -1 +1 @@
1
- import{EventEmitter}from"@js-toolkit/utils/EventEmitter";import{EventEmitterListener}from"../EventEmitterListener";const getPipUnavailableError=()=>new Error("PiP is not available");export class PipController extends EventEmitter{static isApiEnabled(){return!!HTMLVideoElement.prototype.requestPictureInPicture&&!!document.exitPictureInPicture&&!!document.pictureInPictureEnabled}static isWebkitApiEnabled(e){return!!e.webkitSupportsPresentationMode&&e.webkitSupportsPresentationMode("picture-in-picture")}static isAvailable(e){return this.isApiEnabled()&&!e.disablePictureInPicture||this.isWebkitApiEnabled(e)}get Events(){return PipController.Events}listener;constructor(e){if(super(),this.listener=new EventEmitterListener(e),PipController.isAvailable(e)){const e=()=>{this.emit(this.Events.Change,{pip:!0})},t=()=>{this.emit(this.Events.Change,{pip:!1})};PipController.isApiEnabled()?(this.listener.on("enterpictureinpicture",e),this.listener.on("leavepictureinpicture",t)):this.listener.on("webkitpresentationmodechanged",(()=>{let i=this.listener.target.webkitPresentationMode;return()=>{"picture-in-picture"===this.listener.target.webkitPresentationMode?e():"picture-in-picture"===i&&t(),i=this.listener.target.webkitPresentationMode}})(),!0)}}isPip(){return PipController.isApiEnabled()?document.pictureInPictureElement===this.listener.target:"picture-in-picture"===this.listener.target.webkitPresentationMode}getCurrentElement(){return this.isPip()?this.listener.target:null}request(){return new Promise(((e,t)=>{if(this.isPip())e();else{if(!PipController.isAvailable(this.listener.target))throw getPipUnavailableError();PipController.isApiEnabled()?this.listener.target.requestPictureInPicture().then((()=>e()),t):(this.listener.once("webkitpresentationmodechanged",(()=>{"picture-in-picture"===this.listener.target.webkitPresentationMode?e():t(new Error("Something went wrong."))}),!0),this.listener.target.webkitSetPresentationMode("picture-in-picture"))}}))}exit(){return new Promise(((e,t)=>{if(this.isPip()){if(!PipController.isAvailable(this.listener.target))throw getPipUnavailableError();PipController.isApiEnabled()?document.exitPictureInPicture().then(e,t):(this.listener.once("webkitpresentationmodechanged",(()=>{"picture-in-picture"!==this.listener.target.webkitPresentationMode?e():t(new Error("Something went wrong."))}),!0),this.listener.target.webkitSetPresentationMode("inline"))}else e()}))}destroy(){return this.exit().finally((()=>{this.removeAllListeners(),this.listener.removeAllListeners()}))}[Symbol.asyncDispose](){return this.destroy()}}!function(e){let t;!function(e){e.Change="change"}(t=e.Events||(e.Events={}))}(PipController||(PipController={}));
1
+ import{EventEmitter}from"@js-toolkit/utils/EventEmitter";import{EventEmitterListener}from"../EventEmitterListener";import{toggleNativeSubtitles}from"./toggleNativeSubtitles";const getPipUnavailableError=()=>new Error("PiP is not available");export class PipController extends EventEmitter{options;static isApiEnabled(){return!!HTMLVideoElement.prototype.requestPictureInPicture&&!!document.exitPictureInPicture&&!!document.pictureInPictureEnabled}static isWebkitApiEnabled(e){return!!e.webkitSupportsPresentationMode&&e.webkitSupportsPresentationMode("picture-in-picture")}static isAvailable(e){return this.isApiEnabled()&&!e.disablePictureInPicture||this.isWebkitApiEnabled(e)}get Events(){return PipController.Events}listener;constructor(e,t={}){if(super(),this.options=t,this.listener=new EventEmitterListener(e),PipController.isAvailable(e)){const e=(()=>{const e=()=>{e.nativeSubtitles=this.options.toggleNativeSubtitles&&this.listener.target.textTracks.length>0,e.nativeSubtitles&&toggleNativeSubtitles(!0,this.listener.target.textTracks),this.emit(this.Events.Change,{pip:!0})};return e.nativeSubtitles=void 0,e})(),t=()=>{e.nativeSubtitles&&toggleNativeSubtitles(!1,this.listener.target.textTracks),this.emit(this.Events.Change,{pip:!1})};PipController.isApiEnabled()?(this.listener.on("enterpictureinpicture",e),this.listener.on("leavepictureinpicture",t)):this.listener.on("webkitpresentationmodechanged",(()=>{let i=this.listener.target.webkitPresentationMode;return()=>{"picture-in-picture"===this.listener.target.webkitPresentationMode?e():"picture-in-picture"===i&&t(),i=this.listener.target.webkitPresentationMode}})(),!0)}}isPip(){return PipController.isApiEnabled()?document.pictureInPictureElement===this.listener.target:"picture-in-picture"===this.listener.target.webkitPresentationMode}getCurrentElement(){return this.isPip()?this.listener.target:null}request(){return new Promise(((e,t)=>{if(this.isPip())e();else{if(!PipController.isAvailable(this.listener.target))throw getPipUnavailableError();PipController.isApiEnabled()?this.listener.target.requestPictureInPicture().then((()=>e()),t):(this.listener.once("webkitpresentationmodechanged",(()=>{"picture-in-picture"===this.listener.target.webkitPresentationMode?e():t(new Error("Something went wrong."))}),!0),this.listener.target.webkitSetPresentationMode("picture-in-picture"))}}))}exit(){return new Promise(((e,t)=>{if(this.isPip()){if(!PipController.isAvailable(this.listener.target))throw getPipUnavailableError();PipController.isApiEnabled()?document.exitPictureInPicture().then(e,t):(this.listener.once("webkitpresentationmodechanged",(()=>{"picture-in-picture"!==this.listener.target.webkitPresentationMode?e():t(new Error("Something went wrong."))}),!0),this.listener.target.webkitSetPresentationMode("inline"))}else e()}))}destroy(){return this.exit().finally((()=>{this.removeAllListeners(),this.listener.removeAllListeners()}))}[Symbol.asyncDispose](){return this.destroy()}}!function(e){let t;!function(e){e.Change="change"}(t=e.Events||(e.Events={}))}(PipController||(PipController={}));
@@ -3,6 +3,12 @@ import { type ActivateTextTrackInfo, type TextTrackInfo, type TextTrackItem } fr
3
3
  declare global {
4
4
  interface HTMLMediaElementEventMap extends TextTracksEventMap {
5
5
  }
6
+ interface TextTrack {
7
+ native?: boolean | undefined;
8
+ }
9
+ interface TextTrackList {
10
+ [index: number]: TextTrack | undefined;
11
+ }
6
12
  }
7
13
  interface TextTracksEventMap {
8
14
  texttracklistchange: CustomEvent<TextTracksController.EventMap[TextTracksController.Events.TextTrackListChanged][0]>;
@@ -13,13 +19,16 @@ export interface Cue extends PartialBut<OmitStrict<VTTCue, keyof EventTarget | '
13
19
  readonly rows: string[];
14
20
  }
15
21
  export type { TextTrackInfo, ActivateTextTrackInfo, TextTrackItem };
22
+ export type ActiveTextTrackInfo = TextTrackInfo & Pick<TextTrack, 'mode'>;
16
23
  export declare class TextTracksController extends EventEmitter<TextTracksController.EventMap> implements Disposable {
17
24
  private readonly options;
18
25
  private readonly eventListeners;
19
26
  private addedTracks;
20
27
  private textTrackList;
21
28
  private media;
29
+ /** Already set. */
22
30
  private textTrack;
31
+ /** To be set. */
23
32
  private nextTextTrack;
24
33
  get Events(): typeof TextTracksController.Events;
25
34
  constructor(options?: TextTracksController.Options);
@@ -30,7 +39,7 @@ export declare class TextTracksController extends EventEmitter<TextTracksControl
30
39
  attach(media: HTMLMediaElement): void;
31
40
  getTextTracks(): readonly TextTrackInfo[];
32
41
  setTextTracks(textTrackList: readonly TextTrackItem[]): void;
33
- getActiveTextTrack(): TextTrackInfo | undefined;
42
+ getActiveTextTrack(): ActiveTextTrackInfo | undefined;
34
43
  setActiveTextTrack(tt: ActivateTextTrackInfo | undefined): boolean;
35
44
  destroy(): void;
36
45
  [Symbol.dispose](): void;
@@ -57,7 +66,7 @@ export declare namespace TextTracksController {
57
66
  ];
58
67
  [Events.CurrentTextTrackChanged]: [
59
68
  {
60
- readonly textTrack: TextTrackInfo | undefined;
69
+ readonly textTrack: ActiveTextTrackInfo | undefined;
61
70
  readonly index: number;
62
71
  }
63
72
  ];
@@ -1 +1 @@
1
- import{EventEmitter}from"@js-toolkit/utils/EventEmitter";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={}));
1
+ import{EventEmitter}from"@js-toolkit/utils/EventEmitter";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),s.rows=splitRows(s.text,this.options.preferCueRowLength),r[t]=s,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]&&{...this.textTrackList[i],mode:e[i].mode})??{id:e[i].id,kind:e[i].kind,language:e[i].language,label:e[i].label,mode:e[i].mode});this.textTrack?.language===a?.language&&this.textTrack?.kind===a?.kind&&this.textTrack?.mode===a?.mode||(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={}));
@@ -3,15 +3,15 @@ declare global {
3
3
  customGroupId?: string | undefined;
4
4
  }
5
5
  }
6
- export type TextTrackItem = Readonly<PartialSome<RequiredStrict<Pick<HTMLTrackElement, 'src'> & Pick<TextTrack, 'kind' | 'label' | 'language'>>, 'kind'>>;
7
- export interface TextTrackInfo extends Pick<TextTrackItem, 'kind' | 'language' | 'label'> {
8
- readonly id: string;
6
+ export type TextTrackItem = Readonly<OptionalToUndefined<PartialSome<RequiredStrict<Pick<HTMLTrackElement, 'src'> & Pick<TextTrack, 'kind' | 'label' | 'language'>>, 'kind'>>>;
7
+ export interface TextTrackInfo extends Pick<TextTrackItem, 'kind' | 'language' | 'label'>, Pick<TextTrack, 'id'> {
9
8
  }
10
9
  export type ActivateTextTrackInfo = OptionalToUndefined<PartialBut<Pick<TextTrackInfo, 'kind' | 'language'>, 'language'>>;
11
10
  /** Hack: MSE can't remove texttracks on detaching because of no browser api for that. */
12
11
  export declare function fakeDetachTextTracks(media: HTMLMediaElement): void;
13
12
  export declare function parseTextTracks(media: HTMLMediaElement): TextTrackInfo[];
14
13
  export declare function isIOSFullscreen(media: HTMLMediaElement): boolean;
14
+ export declare function findTextTrack(media: Pick<HTMLMediaElement, 'textTracks'>, conditions: OptionalToUndefined<Partial<Pick<TextTrack, 'mode' | 'language'>>>[]): TextTrack | undefined;
15
15
  export declare function setActiveTextTrack(media: HTMLMediaElement, tt: ActivateTextTrackInfo | undefined, hideActiveTrack: boolean): boolean;
16
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;
@@ -1 +1 @@
1
- import{isIOS}from"../../platform/isIOS";const DETACHED_GROUP_ID="__detached__";export function fakeDetachTextTracks(t){Array.prototype.forEach.call(t.textTracks,(t=>{const e=t;e.customGroupId&&(e.customGroupId="__detached__")}))}export function parseTextTracks(t){return 0===t.textTracks.length?[]:Array.prototype.reduce.call(t.textTracks,((t,{customGroupId:e,id:n,kind:r,language:l,label:a})=>("__detached__"!==e&&l&&t.push({id:n,kind:r,language:l,label:a??""}),t)),[])}export function isIOSFullscreen(t){return isIOS()&&!!t.webkitDisplayingFullscreen}export function setActiveTextTrack(t,e,n){const{textTracks:r}=t;if(0===r.length)return!1;let l=!1,a=!1;for(let t=0;t<r.length;t+=1){const c=r[t];if(a||c.language!==e?.language||e.kind&&c.kind!==e.kind)"disabled"!==c.mode&&(c.mode="disabled",l=!0);else{const t=n?"hidden":"showing";c.mode=t,a=!0,l=!0}}return l}export function addTextTracks(t,e,n){const r=Array.prototype.reduce.call(t.textTracks,((t,e)=>(e.language&&(t[e.language]=e),t)),{});e.forEach((e=>{if(!r[e.language]){const r=document.createElement("track");r.src=e.src,r.srclang=e.language,r.label=e.label,r.kind=e.kind??"captions",r.default=!1,n(t.appendChild(r))}}))}export function buildCueId(t,e){return`${t.startTime}-${e}`}export function splitRows(t,e){if(e<=0)return t.split(/\r?\n/);const n=[];let r=0,l=r,a="";for(let c=0;c<=t.length;c+=1){const i=t[c];a.length>0&&r<l&&(n[l]=null==i?a.trim():a.trimStart(),a=""),r=l;let o=n[r]??"";if("\n"===i||"\r\n"===i)a.length>0&&o.length+a.length<=e&&(o+=o.length>0?a:a.trimStart(),a=""),l+=1;else if(" "===i){if(a.length>0){o.length+a.length>e&&o.length>0?(l+=1,o=o.trimEnd()):(o+=0===o.length?a.trimStart():a,a="")}a+=i}else if(null==i&&a.length>0){o.length+a.length>e&&0!==o.length?(r+=1,o=a.trim()):o+=a}else i&&(a+=i);n[r]=o}return n}
1
+ import{isIOS}from"../../platform/isIOS";const DETACHED_GROUP_ID="__detached__";export function fakeDetachTextTracks(t){Array.prototype.forEach.call(t.textTracks,(t=>{const e=t;e.customGroupId&&(e.customGroupId="__detached__")}))}export function parseTextTracks(t){return 0===t.textTracks.length?[]:Array.prototype.reduce.call(t.textTracks,((t,{customGroupId:e,id:n,kind:r,language:l,label:a})=>("__detached__"!==e&&l&&t.push({id:n,kind:r,language:l,label:a??""}),t)),[])}export function isIOSFullscreen(t){return isIOS()&&!!t.webkitDisplayingFullscreen}export function findTextTrack(t,e){return Array.prototype.find.call(t.textTracks,(({mode:t,language:n})=>e.some((e=>!(null!=e.mode&&e.mode!==t||null!=e.language&&e.language!==n)))))}export function setActiveTextTrack(t,e,n){const{textTracks:r}=t;if(0===r.length)return!1;let l=!1,a=!1;for(let t=0;t<r.length;t+=1){const o=r[t];if(a||o.language!==e?.language||e.kind&&o.kind!==e.kind)"disabled"!==o.mode&&(o.mode="disabled",l=!0);else{const t=n?"hidden":"showing";o.mode=t,a=!0,l=!0}}return l}export function addTextTracks(t,e,n){const r=new Set;for(const{language:e,kind:n}of t.textTracks)r.add(`${e} ${n}`);e.forEach((e=>{const l=e.kind??"subtitles";if(!r.has(`${e.language} ${l}`)){const r=document.createElement("track");r.src=e.src,r.srclang=e.language,r.label=e.label,r.kind=l,r.default=!1,n(t.appendChild(r))}}))}export function buildCueId(t,e){return`${t.startTime}-${e}`}export function splitRows(t,e){if(e<=0)return t.split(/\r?\n/);const n=[];let r=0,l=r,a="";for(let o=0;o<=t.length;o+=1){const i=t[o];a.length>0&&r<l&&(n[l]=null==i?a.trim():a.trimStart(),a=""),r=l;let c=n[r]??"";if("\n"===i||"\r\n"===i)a.length>0&&c.length+a.length<=e&&(c+=c.length>0?a:a.trimStart(),a=""),l+=1;else if(" "===i){if(a.length>0){c.length+a.length>e&&c.length>0?(l+=1,c=c.trimEnd()):(c+=0===c.length?a.trimStart():a,a="")}a+=i}else if(null==i&&a.length>0){c.length+a.length>e&&0!==c.length?(r+=1,c=a.trim()):c+=a}else i&&(a+=i);n[r]=c}return n}
@@ -1 +1 @@
1
- export function resetMedia(e){if(e.src||e.srcObject||e.childElementCount>0){if(URL.revokeObjectURL(e.src),e.removeAttribute("src"),e.srcObject=null,e.childElementCount>0)for(const t of e.children)t instanceof HTMLSourceElement&&e.removeChild(t);e.load()}}
1
+ export function resetMedia(e){(e.src||e.srcObject||e.childElementCount>0)&&(URL.revokeObjectURL(e.src),e.removeAttribute("src"),e.srcObject=null,e.childElementCount>0&&Array.prototype.filter.call(e.children,(e=>e instanceof HTMLSourceElement)).forEach((r=>e.removeChild(r))),e.load())}
@@ -1,6 +1 @@
1
- declare global {
2
- interface TextTrack {
3
- native?: boolean | undefined;
4
- }
5
- }
6
1
  export declare function toggleNativeSubtitles(native: boolean, textTracks: TextTrackList): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@js-toolkit/web-utils",
3
- "version": "1.62.2",
3
+ "version": "1.64.0",
4
4
  "description": "Web utils",
5
5
  "author": "VZH",
6
6
  "license": "MIT",
@@ -20,31 +20,30 @@
20
20
  "@js-toolkit/node-utils": "^1.2.1"
21
21
  },
22
22
  "devDependencies": {
23
- "@eslint/compat": "^1.2.6",
24
- "@eslint/eslintrc": "^3.2.0",
25
- "@eslint/js": "^9.20.0",
26
- "@js-toolkit/configs": "^3.94.0",
27
- "@js-toolkit/utils": "^1.59.1",
23
+ "@eslint/compat": "^1.2.8",
24
+ "@eslint/eslintrc": "^3.3.1",
25
+ "@eslint/js": "^9.25.0",
26
+ "@js-toolkit/configs": "^3.94.2",
27
+ "@js-toolkit/utils": "^1.59.2",
28
28
  "@types/eslint": "^9.6.1",
29
- "@types/eslint__eslintrc": "^2.1.2",
30
- "@types/eslint__js": "^8.42.3",
31
29
  "@types/lodash.throttle": "^4.1.9",
32
30
  "@types/uuid": "^10.0.0",
33
31
  "copyfiles": "^2.4.1",
34
- "eslint": "^9.20.1",
35
- "eslint-config-prettier": "^10.0.1",
32
+ "eslint": "^9.25.0",
33
+ "eslint-config-prettier": "^10.1.2",
34
+ "eslint-import-resolver-typescript": "^4.3.3",
36
35
  "eslint-plugin-import": "^2.31.0",
37
- "eslint-plugin-prettier": "^5.2.3",
36
+ "eslint-plugin-prettier": "^5.2.6",
38
37
  "lodash.throttle": "^4.1.1",
39
- "prettier": "^3.5.1",
38
+ "prettier": "^3.5.3",
40
39
  "reconnecting-websocket": "^4.4.0",
41
40
  "rimraf": "^6.0.1",
42
41
  "terser": "^5.39.0",
43
- "typescript": "^5.7.3",
44
- "typescript-eslint": "^8.24.1",
45
- "ua-parser-js": "^2.0.2",
42
+ "typescript": "^5.8.3",
43
+ "typescript-eslint": "^8.30.1",
44
+ "ua-parser-js": "^2.0.3",
46
45
  "uuid": "^11.1.0",
47
- "webpack": "^5.98.0",
46
+ "webpack": "^5.99.6",
48
47
  "yargs": "^17.7.2"
49
48
  }
50
49
  }
@@ -0,0 +1,8 @@
1
+ export declare class Semver {
2
+ readonly major: number;
3
+ readonly minor: number;
4
+ readonly patch: number;
5
+ static parse(version: string): Semver | undefined;
6
+ constructor(major: number, minor: number, patch: number);
7
+ toString(): string;
8
+ }
@@ -0,0 +1 @@
1
+ export class Semver{major;minor;patch;static parse(t){const r=/(\d+)\.(\d+)(?:\.(\d+))?/.exec(t);if(!r)return;const s=parseInt(r[1],10)||0,e=parseInt(r[2],10)||0,n=parseInt(r[3],10)||0;return new Semver(s,e,n)}constructor(t,r,s){this.major=t,this.minor=r,this.patch=s}toString(){return`${this.major}_${this.minor}_${this.patch}`}}
@@ -1,8 +1,2 @@
1
- interface Semver {
2
- readonly major: number;
3
- readonly minor: number;
4
- readonly patch: number;
5
- toString(): string;
6
- }
1
+ import { Semver } from './Semver';
7
2
  export declare function getIOSVersion(): Semver | undefined;
8
- export {};
@@ -1 +1 @@
1
- import{getCachedPlatformInfo}from"./getPlatformInfo";import{isIOS}from"./isIOS";let memo;export function getIOSVersion(){if(void 0===memo){const o=getCachedPlatformInfo();if(!o)return;const{os:t}=o,r=isIOS()&&t.version&&/(\d+)\.(\d+)(?:\.(\d+))?/.exec(t.version);memo=r?{major:parseInt(r[1],10)||0,minor:parseInt(r[2],10)||0,patch:parseInt(r[3],10)||0,toString(){return`${this.major}_${this.minor}_${this.patch}`}}:null}return memo??void 0}
1
+ import{getCachedPlatformInfo}from"./getPlatformInfo";import{isIOS}from"./isIOS";import{Semver}from"./Semver";let memo;export function getIOSVersion(){if(void 0===memo){const o=getCachedPlatformInfo();if(!o)return;const{os:e}=o;memo=isIOS()&&e.version?Semver.parse(e.version):null}return memo??void 0}
@@ -1,8 +1,7 @@
1
1
  /// <reference types="ua-parser-js" preserve="true" />
2
- type PlatformInfo = DeepReadonly<OmitStrict<UAParser.IResult, 'withClientHints' | 'withFeatureCheck'>> & {
2
+ export type PlatformInfo = DeepReadonly<DeepExcludeKeysOfType<UAParser.IResult, AnyFunction>> & {
3
3
  toStringObject(): Record<Keys<ExcludeKeysOfType<UAParser.IResult, AnyFunction>>, string>;
4
4
  };
5
5
  export declare function getPlatformInfoSync(): PlatformInfo;
6
6
  export declare function getPlatformInfo(): Promise<PlatformInfo>;
7
7
  export declare function getCachedPlatformInfo(): PlatformInfo | undefined;
8
- export {};