@js-toolkit/web-utils 1.49.0 → 1.50.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.
@@ -2,6 +2,7 @@ import { EventEmitterListener } from './EventEmitterListener';
2
2
  import type { EmitterTarget, GetEventMap } from './EventEmitterListener.utils';
3
3
  export declare class EventListeners {
4
4
  private readonly listeners;
5
+ getScopes(): IterableIterator<EmitterTarget>;
5
6
  scope<T extends EmitterTarget, M extends AnyObject = GetEventMap<T>>(target: T, scope?: string): EventEmitterListener<T, M>;
6
7
  removeAllListeners<T extends EmitterTarget>(target?: T | undefined, scope?: string): this;
7
8
  }
package/EventListeners.js CHANGED
@@ -1 +1 @@
1
- import{EventEmitterListener}from"./EventEmitterListener";export class EventListeners{constructor(){this.listeners=new Map}scope(e,s){var t,l;const r=null!=s?s:"",i=null!==(t=this.listeners.get(e))&&void 0!==t?t:new Map;!this.listeners.has(e)&&this.listeners.set(e,i);const n=null!==(l=i.get(r))&&void 0!==l?l:new EventEmitterListener(e);return!i.has(r)&&i.set(r,n),n}removeAllListeners(e,s){var t;if(e)if(s){const l=this.listeners.get(e);null===(t=null==l?void 0:l.get(s))||void 0===t||t.removeAllListeners(),null==l||l.delete(s),0===(null==l?void 0:l.size)&&this.listeners.delete(e)}else{const s=this.listeners.get(e);null==s||s.forEach((e=>e.removeAllListeners())),null==s||s.clear(),this.listeners.delete(e)}else this.listeners.forEach((e=>{e.forEach((e=>e.removeAllListeners())),e.clear()})),this.listeners.clear();return this}}
1
+ import{EventEmitterListener}from"./EventEmitterListener";export class EventListeners{constructor(){this.listeners=new Map}getScopes(){return this.listeners.keys()}scope(e,s){var t,l;const r=null!=s?s:"",i=null!==(t=this.listeners.get(e))&&void 0!==t?t:new Map;!this.listeners.has(e)&&this.listeners.set(e,i);const n=null!==(l=i.get(r))&&void 0!==l?l:new EventEmitterListener(e);return!i.has(r)&&i.set(r,n),n}removeAllListeners(e,s){var t;if(e)if(s){const l=this.listeners.get(e);null===(t=null==l?void 0:l.get(s))||void 0===t||t.removeAllListeners(),null==l||l.delete(s),0===(null==l?void 0:l.size)&&this.listeners.delete(e)}else{const s=this.listeners.get(e);null==s||s.forEach((e=>e.removeAllListeners())),null==s||s.clear(),this.listeners.delete(e)}else this.listeners.forEach((e=>{e.forEach((e=>e.removeAllListeners())),e.clear()})),this.listeners.clear();return this}}
@@ -15,8 +15,8 @@ export declare class PipController extends EventEmitter<PipController.EventMap>
15
15
  private readonly listener;
16
16
  constructor(video: HTMLVideoElement);
17
17
  destroy(): Promise<void>;
18
- get isPip(): boolean;
19
- get currentElement(): HTMLVideoElement | null;
18
+ isPip(): boolean;
19
+ getCurrentElement(): HTMLVideoElement | null;
20
20
  request(): Promise<void>;
21
21
  exit(): Promise<void>;
22
22
  }
@@ -26,7 +26,7 @@ export declare namespace PipController {
26
26
  }
27
27
  type EventMap = {
28
28
  [Events.Change]: [{
29
- isPip: boolean;
29
+ pip: boolean;
30
30
  }];
31
31
  };
32
32
  }
package/PipController.js CHANGED
@@ -1 +1 @@
1
- import{EventEmitter}from"eventemitter3";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(){return!!HTMLVideoElement.prototype.webkitSupportsPresentationMode&&HTMLVideoElement.prototype.webkitSupportsPresentationMode("picture-in-picture")}static isAvailable(e){return this.isApiEnabled()&&!e.disablePictureInPicture||this.isWebkitApiEnabled()}get Events(){return PipController.Events}constructor(e){if(super(),this.listener=new EventEmitterListener(e),PipController.isAvailable(e)){const e=()=>{this.emit(this.Events.Change,{isPip:!0})},t=()=>{this.emit(this.Events.Change,{isPip:!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)}}destroy(){return this.exit().finally((()=>{this.removeAllListeners(),this.listener.removeAllListeners()}))}get isPip(){return PipController.isApiEnabled()?document.pictureInPictureElement===this.listener.target:"picture-in-picture"===this.listener.target.webkitPresentationMode}get currentElement(){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()}))}}!function(e){let t;!function(e){e.Change="change"}(t=e.Events||(e.Events={}))}(PipController||(PipController={}));
1
+ import{EventEmitter}from"eventemitter3";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}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)}}destroy(){return this.exit().finally((()=>{this.removeAllListeners(),this.listener.removeAllListeners()}))}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()}))}}!function(e){let t;!function(e){e.Change="change"}(t=e.Events||(e.Events={}))}(PipController||(PipController={}));
package/loadScript.js CHANGED
@@ -1 +1 @@
1
- import{onDOMReady}from"./onDOMReady";function isScriptAdded(e){const r=e.startsWith("//")?window.location.protocol+e:e;for(let e=0;e<document.scripts.length;e+=1)if(document.scripts[e].src===r)return!0;return!1}export function loadScript(e,{keepScript:r,id:t,async:n=!0,defer:o=!1}={}){return new Promise(((d,i)=>{onDOMReady((()=>{try{if(t){if(document.scripts.namedItem(t))return void d()}else if(isScriptAdded(e))return void d();const c=document.createElement("script"),s=()=>{c.removeEventListener("load",a),c.removeEventListener("error",p),r||c.remove()},a=()=>{s(),d()},p=e=>{s();const r=e instanceof ErrorEvent?e:new Error("Script load error. See previous log messages.");i(r)};t&&(c.id=t),c.async=n,c.defer=o,c.src=e,c.addEventListener("load",a,{once:!0}),c.addEventListener("error",p,{once:!0}),document.head.appendChild(c)}catch(e){i(e)}}))}))}
1
+ import{onDOMReady}from"./onDOMReady";function isScriptAdded(e){const r=e.startsWith("//")?window.location.protocol+e:e;for(let e=0;e<document.scripts.length;e+=1)if(document.scripts[e].src===r)return!0;return!1}export function loadScript(e,{keepScript:r,id:t,async:n=!0,defer:o=!1}={}){return new Promise(((d,i)=>{onDOMReady((()=>{try{if(t){if(document.scripts.namedItem(t))return void d()}else if(isScriptAdded(e))return void d();const c=document.createElement("script"),s=()=>{c.removeEventListener("load",a),c.removeEventListener("error",p),r||c.remove()},a=()=>{s(),d()},p=r=>{s();const t=r instanceof ErrorEvent?r:new Error(`Unable to load script by url ${e}. See previous log messages.`,{cause:r});i(t)};t&&(c.id=t),c.async=n,c.defer=o,c.src=e,c.addEventListener("load",a,{once:!0}),c.addEventListener("error",p,{once:!0}),document.head.appendChild(c)}catch(e){i(e)}}))}))}
@@ -0,0 +1,5 @@
1
+ export interface BaseMediaController<T extends HTMLMediaElement = HTMLMediaElement> {
2
+ attach(media: T, ...args: unknown[]): void;
3
+ detach(): void;
4
+ destroy(): void;
5
+ }
@@ -0,0 +1 @@
1
+ export{};
@@ -1,12 +1,13 @@
1
+ import type { BaseMediaController } from './BaseMediaController';
1
2
  export declare function attachMediaStream(media: HTMLMediaElement, stream: MediaStream | undefined): void;
2
3
  export declare function removeTrack(mediaStream: MediaStream, track: MediaStreamTrack): void;
3
4
  export declare function addTrack(mediaStream: MediaStream, track: MediaStreamTrack, onEnded?: VoidFunction | undefined): void;
4
- export declare class MediaStreamController {
5
+ export declare class MediaStreamController implements BaseMediaController {
5
6
  private mediaStream;
6
7
  private media;
7
8
  constructor(mediaStream: MediaStream);
8
- attachMedia(media: HTMLMediaElement): void;
9
- detachMedia(): void;
9
+ attach(media: HTMLMediaElement): void;
10
+ detach(): void;
10
11
  updateStream(stream: MediaStream): void;
11
12
  removeTrack(track: MediaStreamTrack): void;
12
13
  addTrack(track: MediaStreamTrack, onEnded?: VoidFunction | undefined): void;
@@ -1 +1 @@
1
- import{resetMedia}from"./resetMedia";export function attachMediaStream(e,t){t&&t.active&&e.muted&&0===t.getVideoTracks().filter((e=>!e.getSettings().displaySurface)).length?e.srcObject=null:e.srcObject=t&&t.active?t:null}export function removeTrack(e,t){e.removeTrack(t),e.dispatchEvent(new MediaStreamTrackEvent("removetrack",{track:t}))}export function addTrack(e,t,a){e.addTrack(t),e.dispatchEvent(new MediaStreamTrackEvent("addtrack",{track:t})),t.addEventListener("ended",(()=>{removeTrack(e,t),a&&a()}),{once:!0})}export class MediaStreamController{constructor(e){this.mediaStream=e}attachMedia(e){this.media=e,attachMediaStream(e,this.mediaStream)}detachMedia(){if(this.media){const{media:e}=this;this.media=void 0,resetMedia(e)}}updateStream(e){if(this.mediaStream===e)return;const{media:t}=this;this.mediaStream=e,t&&this.attachMedia(t)}removeTrack(e){removeTrack(this.mediaStream,e)}addTrack(e,t){addTrack(this.mediaStream,e,(()=>{this.removeTrack(e),t&&t()}))}reset(){this.mediaStream.getTracks().forEach((e=>{e.stop(),this.removeTrack(e)}))}destroy(){this.detachMedia(),this.reset()}}
1
+ import{resetMedia}from"./resetMedia";export function attachMediaStream(e,t){t&&t.active&&e.muted&&0===t.getVideoTracks().filter((e=>!e.getSettings().displaySurface)).length?e.srcObject=null:e.srcObject=t&&t.active?t:null}export function removeTrack(e,t){e.removeTrack(t),e.dispatchEvent(new MediaStreamTrackEvent("removetrack",{track:t}))}export function addTrack(e,t,a){e.addTrack(t),e.dispatchEvent(new MediaStreamTrackEvent("addtrack",{track:t})),t.addEventListener("ended",(()=>{removeTrack(e,t),a&&a()}),{once:!0})}export class MediaStreamController{constructor(e){this.mediaStream=e}attach(e){this.media=e,attachMediaStream(e,this.mediaStream)}detach(){if(this.media){const{media:e}=this;this.media=void 0,resetMedia(e)}}updateStream(e){if(this.mediaStream===e)return;const{media:t}=this;this.mediaStream=e,t&&this.attach(t)}removeTrack(e){removeTrack(this.mediaStream,e)}addTrack(e,t){addTrack(this.mediaStream,e,(()=>{this.removeTrack(e),t&&t()}))}reset(){this.mediaStream.getTracks().forEach((e=>{e.stop(),this.removeTrack(e)}))}destroy(){this.detach(),this.reset()}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@js-toolkit/web-utils",
3
- "version": "1.49.0",
3
+ "version": "1.50.0",
4
4
  "description": "Web utils",
5
5
  "author": "VZH",
6
6
  "license": "MIT",
@@ -17,22 +17,22 @@
17
17
  "minor-publish": "npm run build && npm version minor --force --no-workspaces-update -m 'v%s' && npm run copy:configs && cd ./dist && npm publish --access public && git push --follow-tags"
18
18
  },
19
19
  "optionalDependencies": {
20
- "@js-toolkit/node-utils": "^1.1.7"
20
+ "@js-toolkit/node-utils": "^1.2.0"
21
21
  },
22
22
  "devDependencies": {
23
- "@js-toolkit/configs": "^3.88.2",
23
+ "@js-toolkit/configs": "^3.89.1",
24
24
  "@js-toolkit/utils": "^1.50.0",
25
25
  "@types/uuid": "^9.0.7",
26
- "@typescript-eslint/eslint-plugin": "^6.14.0",
27
- "@typescript-eslint/parser": "^6.14.0",
26
+ "@typescript-eslint/eslint-plugin": "^6.18.1",
27
+ "@typescript-eslint/parser": "^6.18.1",
28
28
  "copyfiles": "^2.4.1",
29
- "eslint": "^8.55.0",
29
+ "eslint": "^8.56.0",
30
30
  "eslint-config-airbnb-base": "^15.0.0",
31
31
  "eslint-config-prettier": "^9.1.0",
32
- "eslint-plugin-import": "^2.29.0",
33
- "eslint-plugin-prettier": "^5.0.1",
32
+ "eslint-plugin-import": "^2.29.1",
33
+ "eslint-plugin-prettier": "^5.1.3",
34
34
  "eventemitter3": "^5.0.1",
35
- "prettier": "^3.1.1",
35
+ "prettier": "^3.2.2",
36
36
  "reconnecting-websocket": "^4.4.0",
37
37
  "rimraf": "^5.0.5",
38
38
  "terser": "^5.26.0",
package/platform/ua.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- type UAInfo = DeepReadonly<OmitStrict<UAParser.IResult, 'withClientHints'>>;
1
+ type UAInfo = DeepReadonly<OmitStrict<UAParser.IResult, 'withClientHints' | 'withFeatureCheck'>> & {
2
+ toStringObject(): Record<Keys<ExcludeKeysOfType<UAParser.IResult, AnyFunction>>, string>;
3
+ };
2
4
  export declare function getUAInfo(): Promise<UAInfo>;
3
5
  export declare function getCachedUAInfo(): UAInfo | undefined;
4
6
  export {};
package/platform/ua.js CHANGED
@@ -1 +1 @@
1
- import{__awaiter}from"tslib";import{UAParser}from"ua-parser-js";let result,promise;export function getUAInfo(){return __awaiter(this,void 0,void 0,(function*(){return null==result&&(promise=null!=promise?promise:Promise.resolve(new UAParser(navigator.userAgent).getResult().withClientHints()),result=yield promise,promise=void 0),result}))}export function getCachedUAInfo(){return result}
1
+ import{__awaiter}from"tslib";import{UAParser}from"ua-parser-js";let result,promise;export function getUAInfo(){return __awaiter(this,void 0,void 0,(function*(){return null==result&&(promise=null!=promise?promise:Promise.resolve(new UAParser(navigator.userAgent).getResult().withFeatureCheck().withClientHints()),result=Object.assign(Object.assign({},yield promise),{toStringObject(){return Object.getOwnPropertyNames(this).reduce(((e,t)=>{const r=t;return null!=this[r]&&"function"!=typeof this[r]&&(e[r]=this[r].toString()),e}),{})}}),promise=void 0),result}))}export function getCachedUAInfo(){return null==result&&(console.warn("UAInfo is not ready yet."),getUAInfo()),result}