billy-herrington-utils 1.1.3 → 1.1.5

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/README.md CHANGED
@@ -56,6 +56,6 @@ npm i billy-herrington-utils
56
56
  | `isMob()` | Checks if the current device is a mobile device. | N/A | `if (isMob()) { ... }` |
57
57
  | `computeAsyncOneAtTime(iterable)` | Executes asynchronous functions one at a time. | `iterable: Iterable<() => Promise<any>>` | `computeAsyncOneAtTime(asyncFunctions).then((results) => { ... });` |
58
58
  | `wait(milliseconds)` | Waits for a given number of milliseconds. | `milliseconds: number` | `await wait(1000);` |
59
- | `SyncPull` | A class for managing asynchronous tasks with priorities. | N/A | `const syncPull = new SyncPull(); syncPull.push(() => { ... });` |
59
+ | `AsyncPool` | A class for managing asynchronous tasks with priorities. | N/A | `const spool = new AsyncPool(); spool.push(() => { v: () => fetch(...), p: 1 });` |
60
60
  | `chunks(arr, n)` | Splits an array into chunks of a given size. | `arr: Array<any>`, `n: number` | `const chunks = chunks([1, 2, 3, 4, 5], 2);` -> `[[1, 2], [3, 4], [5]]` |
61
61
  | `range(start, end)` | Creates a range of numbers from `start` to `end` (inclusive). | `start: number`, `end: number` | `const numbers = range(1, 5);` -> `[1, 2, 3, 4, 5]` |
@@ -5,10 +5,10 @@ function stringToWords(s) {
5
5
  return s.split(",").map((s2) => s2.trim().toLowerCase()).filter((_) => _);
6
6
  }
7
7
  function sanitizeStr(s) {
8
- return (s == null ? void 0 : s.replace(/\n|\t/, " ").replace(/ {2,}/, " ").trim().toLowerCase()) || "";
8
+ return s?.replace(/\n|\t/, " ").replace(/ {2,}/, " ").trim().toLowerCase() || "";
9
9
  }
10
10
  function timeToSeconds(t) {
11
- return ((t == null ? void 0 : t.match(/\d+/gm)) || [0]).reverse().map((s, i) => parseInt(s) * 60 ** i).reduce((a, b) => a + b);
11
+ return (t?.match(/\d+/gm) || [0]).reverse().map((s, i) => parseInt(s) * 60 ** i).reduce((a, b) => a + b);
12
12
  }
13
13
  function parseIntegerOr(n, or) {
14
14
  return Number.isInteger(parseInt(n)) ? parseInt(n) : or;
@@ -16,7 +16,7 @@ function parseIntegerOr(n, or) {
16
16
  function parseDataParams(str) {
17
17
  const params = str.split(";").flatMap((s) => {
18
18
  const parsed = s.match(/([\+\w+]+):(\w+)?/);
19
- const value = parsed == null ? void 0 : parsed[2];
19
+ const value = parsed?.[2];
20
20
  if (value) return parsed[1].split("+").map((p) => ({ [p]: value }));
21
21
  }).filter((_) => _);
22
22
  return Object.assign({}, ...params);
@@ -44,7 +44,6 @@ class Observer {
44
44
  }
45
45
  }
46
46
  }
47
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
48
47
  static observeWhile(target, callback, throttleTime) {
49
48
  const observer_ = new Observer(async (target2) => {
50
49
  const condition = await callback();
@@ -55,18 +54,18 @@ class Observer {
55
54
  }
56
55
  }
57
56
  class LazyImgLoader {
58
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
59
- constructor(callback, attributeName = "data-lazy-load", removeTagAfter = true) {
57
+ constructor(shouldDelazify) {
60
58
  __publicField(this, "lazyImgObserver");
59
+ __publicField(this, "attributeName", "data-lazy-load");
61
60
  __publicField(this, "delazify", (target) => {
62
61
  this.lazyImgObserver.observer.unobserve(target);
63
62
  target.src = target.getAttribute(this.attributeName);
64
- if (this.removeTagAfter) target.removeAttribute(this.attributeName);
63
+ target.removeAttribute(this.attributeName);
65
64
  });
66
- this.attributeName = attributeName;
67
- this.removeTagAfter = removeTagAfter;
68
65
  this.lazyImgObserver = new Observer((target) => {
69
- callback(target, this.delazify);
66
+ if (shouldDelazify(target)) {
67
+ this.delazify(target);
68
+ }
70
69
  });
71
70
  }
72
71
  lazify(_target, img, imgSrc) {
@@ -75,15 +74,6 @@ class LazyImgLoader {
75
74
  img.src = "";
76
75
  this.lazyImgObserver.observe(img);
77
76
  }
78
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
79
- static create(callback) {
80
- const lazyImgLoader = new LazyImgLoader((target, delazify) => {
81
- if (callback(target)) {
82
- delazify(target);
83
- }
84
- });
85
- return lazyImgLoader;
86
- }
87
77
  }
88
78
  function circularShift(n, c = 6, s = 1) {
89
79
  return (n + s) % c || c;
@@ -98,11 +88,10 @@ function copyAttributes(target, source) {
98
88
  }
99
89
  }
100
90
  function replaceElementTag(e, tagName) {
101
- var _a;
102
91
  const newTagElement = document.createElement(tagName);
103
92
  copyAttributes(newTagElement, e);
104
93
  newTagElement.innerHTML = e.innerHTML;
105
- (_a = e.parentNode) == null ? void 0 : _a.replaceChild(newTagElement, e);
94
+ e.parentNode?.replaceChild(newTagElement, e);
106
95
  return newTagElement;
107
96
  }
108
97
  function getAllUniqueParents(elements) {
@@ -157,10 +146,9 @@ function watchDomChangesWithThrottle(element, callback, throttle = 1e3, options
157
146
  }
158
147
  function downloader(options = { append: "", after: "", button: "", cbBefore: () => {
159
148
  } }) {
160
- var _a, _b;
161
149
  const btn = parseDom(options.button);
162
- if (options.append) (_a = document.querySelector(options.append)) == null ? void 0 : _a.append(btn);
163
- if (options.after) (_b = document.querySelector(options.after)) == null ? void 0 : _b.after(btn);
150
+ if (options.append) document.querySelector(options.append)?.append(btn);
151
+ if (options.after) document.querySelector(options.after)?.after(btn);
164
152
  btn.addEventListener("click", (e) => {
165
153
  e.preventDefault();
166
154
  if (options.cbBefore) options.cbBefore();
@@ -194,7 +182,6 @@ function listenEvents(dom, events, callback) {
194
182
  class Tick {
195
183
  constructor(delay, startImmediate = true) {
196
184
  __publicField(this, "tick");
197
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
198
185
  __publicField(this, "callbackFinal");
199
186
  this.delay = delay;
200
187
  this.startImmediate = startImmediate;
@@ -202,8 +189,7 @@ class Tick {
202
189
  this.delay = delay;
203
190
  this.startImmediate = startImmediate;
204
191
  }
205
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
206
- start(callback, callbackFinal = null) {
192
+ start(callback, callbackFinal = void 0) {
207
193
  this.stop();
208
194
  this.callbackFinal = callbackFinal;
209
195
  if (this.startImmediate) callback();
@@ -216,7 +202,7 @@ class Tick {
216
202
  }
217
203
  if (this.callbackFinal) {
218
204
  this.callbackFinal();
219
- this.callbackFinal = null;
205
+ this.callbackFinal = void 0;
220
206
  }
221
207
  }
222
208
  }
@@ -233,41 +219,47 @@ async function computeAsyncOneAtTime(iterable) {
233
219
  function wait(milliseconds) {
234
220
  return new Promise((resolve) => setTimeout(resolve, milliseconds));
235
221
  }
236
- class SyncPull {
237
- constructor() {
238
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
239
- __publicField(this, "pull", []);
240
- __publicField(this, "lock", false);
222
+ class AsyncPool {
223
+ constructor(max = 1, pool = []) {
224
+ __publicField(this, "cur", 0);
225
+ __publicField(this, "finished");
226
+ __publicField(this, "_resolve");
227
+ this.max = max;
228
+ this.pool = pool;
229
+ this.finished = new Promise((resolve) => {
230
+ this._resolve = resolve;
231
+ });
241
232
  }
242
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
243
233
  getHighPriorityFirst(p = 0) {
244
- if (p > 3 || this.pull.length === 0) return void 0;
245
- const i = this.pull.findIndex((e) => e.p === p);
234
+ if (p > 3 || this.pool.length === 0) return void 0;
235
+ const i = this.pool.findIndex((e) => e.p === p);
246
236
  if (i >= 0) {
247
- const res = this.pull[i].v;
248
- this.pull = this.pull.slice(0, i).concat(this.pull.slice(i + 1));
237
+ const res = this.pool[i].v;
238
+ this.pool = this.pool.slice(0, i).concat(this.pool.slice(i + 1));
249
239
  return res;
250
240
  }
251
241
  return this.getHighPriorityFirst(p + 1);
252
242
  }
253
- *pullGenerator() {
254
- while (this.pull.length > 0) {
255
- yield this.getHighPriorityFirst();
256
- }
243
+ async runTask() {
244
+ this.cur++;
245
+ const f = this.getHighPriorityFirst();
246
+ await f?.();
247
+ this.cur--;
248
+ this.runTasks();
257
249
  }
258
- async processPull() {
259
- if (!this.lock) {
260
- this.lock = true;
261
- for await (const f of this.pullGenerator()) {
262
- await f();
263
- }
264
- this.lock = false;
250
+ runTasks() {
251
+ if (!this.pool.length) this._resolve?.(true);
252
+ if (this.cur < this.max) {
253
+ this.runTask();
254
+ this.runTasks();
265
255
  }
266
256
  }
267
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
257
+ async run() {
258
+ this.runTasks();
259
+ return this.finished;
260
+ }
268
261
  push(x) {
269
- this.pull.push(x);
270
- this.processPull();
262
+ this.pool.push("p" in x ? x : { v: x, p: 0 });
271
263
  }
272
264
  }
273
265
  function chunks(arr, n) {
@@ -281,10 +273,10 @@ function range(size, startAt = 1) {
281
273
  return [...Array(size).keys()].map((i) => i + startAt);
282
274
  }
283
275
  export {
276
+ AsyncPool,
284
277
  LazyImgLoader,
285
278
  MOBILE_UA,
286
279
  Observer,
287
- SyncPull,
288
280
  Tick,
289
281
  chunks,
290
282
  circularShift,
@@ -1 +1 @@
1
- {"version":3,"file":"billy-herrington-utils.es.js","sources":["../src/utils/strings/index.ts","../src/utils/parsers/index.ts","../src/utils/observers/index.ts","../src/utils/math/index.ts","../src/utils/dom/index.ts","../src/utils/fetch/index.ts","../src/utils/events/index.ts","../src/utils/device/index.ts","../src/utils/async/index.ts","../src/utils/arrays/index.ts"],"sourcesContent":["export function stringToWords(s: string): Array<string> {\r\n return s.split(\",\").map(s => s.trim().toLowerCase()).filter(_ => _);\r\n}\r\n\r\nexport function sanitizeStr(s: string) {\r\n return s?.replace(/\\n|\\t/, ' ').replace(/ {2,}/, ' ').trim().toLowerCase() || \"\";\r\n}\r\n","export function timeToSeconds(t: string): number {\r\n return (t?.match(/\\d+/gm) || [0])\r\n .reverse()\r\n .map((s, i) => parseInt(s as string) * 60 ** i)\r\n .reduce((a, b) => a + b);\r\n}\r\n\r\nexport function parseIntegerOr(n: string | number, or: number): number {\r\n return Number.isInteger(parseInt(n as string)) ? parseInt(n as string) : or;\r\n}\r\n\r\n// \"data:02;body+head:async;void:;zero:;\"\r\nexport function parseDataParams(str: string) {\r\n const params = str.split(';').flatMap(s => {\r\n const parsed = s.match(/([\\+\\w+]+):(\\w+)?/);\r\n const value = parsed?.[2];\r\n if (value) return parsed[1].split('+').map(p => ({ [p]: value }));\r\n }).filter(_ => _);\r\n return Object.assign({}, ...params);\r\n}\r\n\r\nexport function parseCSSUrl(s: string) {\r\n return s.replace(/url\\(\"|\\\"\\).*/g, '');\r\n}","export class Observer {\r\n public observer: IntersectionObserver;\r\n constructor(private callback: (entry: Element) => void) {\r\n this.observer = new IntersectionObserver(this.handleIntersection.bind(this));\r\n }\r\n\r\n observe(target: Element) {\r\n this.observer.observe(target);\r\n }\r\n\r\n throttle(target: Element, throttleTime: number) {\r\n this.observer.unobserve(target);\r\n setTimeout(() => this.observer.observe(target), throttleTime);\r\n }\r\n\r\n handleIntersection(entries: Iterable<IntersectionObserverEntry>) {\r\n for (const entry of entries) {\r\n if (entry.isIntersecting) {\r\n this.callback(entry.target);\r\n }\r\n }\r\n }\r\n\r\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\n static observeWhile(target: Element, callback: any, throttleTime: number) {\r\n const observer_ = new Observer(async (target: Element) => {\r\n const condition = await callback();\r\n if (condition) observer_.throttle(target, throttleTime);\r\n });\r\n observer_.observe(target);\r\n return observer_;\r\n }\r\n}\r\n\r\nexport class LazyImgLoader {\r\n public lazyImgObserver: Observer;\r\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\n constructor(callback: any, private attributeName = 'data-lazy-load', private removeTagAfter = true) {\r\n this.lazyImgObserver = new Observer((target: Element) => {\r\n callback(target, this.delazify);\r\n });\r\n }\r\n\r\n lazify(_target: Element, img: HTMLImageElement, imgSrc: string) {\r\n if (!img || !imgSrc) return;\r\n img.setAttribute(this.attributeName, imgSrc);\r\n img.src = '';\r\n this.lazyImgObserver.observe(img);\r\n }\r\n\r\n delazify = (target: HTMLImageElement) => {\r\n this.lazyImgObserver.observer.unobserve(target);\r\n target.src = target.getAttribute(this.attributeName) as string;\r\n if (this.removeTagAfter) target.removeAttribute(this.attributeName);\r\n }\r\n\r\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\n static create(callback: any) {\r\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\n const lazyImgLoader = new LazyImgLoader((target: Element, delazify: any) => {\r\n if (callback(target)) {\r\n delazify(target);\r\n }\r\n });\r\n return lazyImgLoader;\r\n }\r\n}\r\n","export function circularShift(n: number, c = 6, s = 1): number {\r\n return (n + s) % c || c;\r\n}\r\n","export function parseDom(html: string): HTMLElement {\r\n const parsed = new DOMParser().parseFromString(html, 'text/html').body;\r\n return parsed.children.length > 1 ? parsed : parsed.firstElementChild as HTMLElement;\r\n}\r\n\r\nexport function copyAttributes(target: HTMLElement | Element, source: HTMLElement | Element) {\r\n for (const attr of source.attributes) {\r\n attr.nodeValue && target.setAttribute(attr.nodeName, attr.nodeValue);\r\n }\r\n}\r\n\r\nexport function replaceElementTag(e: HTMLElement | Element, tagName: string) {\r\n const newTagElement = document.createElement(tagName);\r\n copyAttributes(newTagElement, e);\r\n newTagElement.innerHTML = e.innerHTML;\r\n e.parentNode?.replaceChild(newTagElement, e);\r\n return newTagElement;\r\n}\r\n\r\nexport function getAllUniqueParents(elements: HTMLCollection): Array<HTMLElement | Element> {\r\n return Array.from(elements).reduce((acc, v) => {\r\n if (v.parentElement && !acc.includes(v.parentElement as HTMLElement)) { acc.push(v.parentElement); }\r\n return acc;\r\n }, [] as Array<HTMLElement | Element>);\r\n}\r\n\r\nexport function findNextSibling(el: HTMLElement | Element) {\r\n if (el.nextElementSibling) return el.nextElementSibling;\r\n if (el.parentElement) return findNextSibling(el.parentElement);\r\n return null;\r\n}\r\n\r\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\nexport function waitForElementExists(parent: HTMLElement | Element, selector: string, callback: any): void {\r\n const observer = new MutationObserver((_mutations) => {\r\n const el = parent.querySelector(selector);\r\n if (el) {\r\n observer.disconnect();\r\n callback(el);\r\n }\r\n });\r\n observer.observe(document.body, { childList: true, subtree: true });\r\n}\r\n\r\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\nexport function watchElementChildrenCount(element: HTMLElement | Element, callback: any): void {\r\n let count = element.children.length;\r\n const observer = new MutationObserver((mutationList, observer) => {\r\n for (const mutation of mutationList) {\r\n if (mutation.type === \"childList\") {\r\n if (count !== element.children.length) {\r\n count = element.children.length;\r\n callback(observer, count);\r\n }\r\n }\r\n }\r\n });\r\n observer.observe(element, { childList: true });\r\n}\r\n\r\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\nexport function watchDomChangesWithThrottle(element: HTMLElement | Element, callback: any,\r\n throttle = 1000, options: Record<string, boolean> = { childList: true, subtree: true, attributes: true }) {\r\n let lastMutationTime: number;\r\n let timeout: number;\r\n const observer = new MutationObserver((_mutationList, _observer) => {\r\n const now = Date.now();\r\n if (lastMutationTime && now - lastMutationTime < throttle) {\r\n timeout && clearTimeout(timeout);\r\n }\r\n timeout = setTimeout(callback, throttle);\r\n lastMutationTime = now;\r\n });\r\n observer.observe(element, options);\r\n}\r\n\r\nexport function downloader(options = { append: \"\", after: \"\", button: \"\", cbBefore: () => { } }) {\r\n const btn = parseDom(options.button);\r\n\r\n if (options.append) document.querySelector(options.append)?.append(btn);\r\n if (options.after) document.querySelector(options.after)?.after(btn);\r\n\r\n btn.addEventListener('click', (e) => {\r\n e.preventDefault();\r\n\r\n if (options.cbBefore) options.cbBefore();\r\n\r\n waitForElementExists(document.body, 'video', (video: HTMLVideoElement) => {\r\n window.location.href = video.getAttribute('src') as string;\r\n });\r\n });\r\n}","import { parseDom } from \"../dom\";\r\n\r\nexport const MOBILE_UA = [\r\n 'Mozilla/5.0 (Linux; Android 10; K)',\r\n 'AppleWebKit/537.36 (KHTML, like Gecko)',\r\n 'Chrome/114.0.0.0 Mobile Safari/537.36'].join(' ');\r\n\r\nexport function fetchWith(url: string, options: Record<string, boolean> = { html: false, mobile: false }) {\r\n const reqOpts = {};\r\n if (options.mobile) Object.assign(reqOpts, { headers: new Headers({ \"User-Agent\": MOBILE_UA }) });\r\n return fetch(url, reqOpts).then((r) => r.text()).then(r => options.html ? parseDom(r) : r);\r\n}\r\n\r\nexport const fetchHtml = (url: string) => fetchWith(url, { html: true });\r\n\r\nexport const fetchText = (url: string) => fetchWith(url);\r\n\r\nexport function objectToFormData(object: Record<string, number | boolean | string>): FormData {\r\n const formData = new FormData();\r\n Object.entries(object).forEach(([k, v]) => formData.append(k, v as string));\r\n return formData;\r\n}\r\n","// biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\nexport function listenEvents(dom: HTMLElement | Element, events: Array<string>, callback: any): void {\r\n for (const e of events) {\r\n dom.addEventListener(e, callback, true);\r\n }\r\n}\r\n\r\nexport class Tick {\r\n private tick: null | number;\r\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\n private callbackFinal: any;\r\n\r\n constructor(private delay: number, private startImmediate = true) {\r\n this.tick = null;\r\n this.delay = delay;\r\n this.startImmediate = startImmediate;\r\n }\r\n\r\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\n start(callback: any, callbackFinal = null) {\r\n this.stop();\r\n this.callbackFinal = callbackFinal;\r\n if (this.startImmediate) callback();\r\n this.tick = setInterval(callback, this.delay);\r\n }\r\n\r\n stop() {\r\n if (this.tick !== null) {\r\n clearInterval(this.tick);\r\n this.tick = null;\r\n }\r\n if (this.callbackFinal) {\r\n this.callbackFinal();\r\n this.callbackFinal = null;\r\n }\r\n }\r\n}","export function isMob() {\r\n return /iPhone|Android/i.test(navigator.userAgent);\r\n}","// https://2ality.com/2016/10/asynchronous-iteration.html\r\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\nexport async function computeAsyncOneAtTime(iterable: Iterable<any>) {\r\n const res = [];\r\n for await (const f of iterable) {\r\n res.push(await f());\r\n }\r\n return res;\r\n}\r\n\r\nexport function wait(milliseconds: number) {\r\n return new Promise(resolve => setTimeout(resolve, milliseconds));\r\n}\r\n\r\n// do async one at time\r\nexport class SyncPull {\r\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\n pull: Array<any> = [];\r\n lock = false;\r\n\r\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\n getHighPriorityFirst(p = 0): any {\r\n if (p > 3 || this.pull.length === 0) return undefined;\r\n const i = this.pull.findIndex(e => e.p === p);\r\n if (i >= 0) {\r\n const res = this.pull[i].v;\r\n this.pull = this.pull.slice(0, i).concat(this.pull.slice(i + 1));\r\n return res;\r\n }\r\n return this.getHighPriorityFirst(p + 1);\r\n }\r\n\r\n *pullGenerator() {\r\n while (this.pull.length > 0) {\r\n yield this.getHighPriorityFirst();\r\n }\r\n }\r\n\r\n async processPull() {\r\n if (!this.lock) {\r\n this.lock = true;\r\n for await (const f of this.pullGenerator()) {\r\n await f();\r\n }\r\n this.lock = false;\r\n }\r\n }\r\n\r\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\n push(x: any) {\r\n this.pull.push(x);\r\n this.processPull();\r\n }\r\n}\r\n","export function chunks<T>(arr: Array<T>, n: number): Array<Array<T>> {\r\n const res = [];\r\n for (let i = 0; i < arr.length; i += n) {\r\n res.push(arr.slice(i, i + n));\r\n }\r\n return res;\r\n}\r\n\r\nexport function range(size: number, startAt = 1): Array<number> {\r\n return [...Array(size).keys()].map(i => i + startAt);\r\n}"],"names":["s","target","observer"],"mappings":";;;AAAO,SAAS,cAAc,GAA0B;AACtD,SAAO,EAAE,MAAM,GAAG,EAAE,IAAI,CAAAA,OAAKA,GAAE,OAAO,YAAY,CAAC,EAAE,OAAO,OAAK,CAAC;AACpE;AAEO,SAAS,YAAY,GAAW;AACrC,UAAO,uBAAG,QAAQ,SAAS,KAAK,QAAQ,SAAS,KAAK,OAAO,kBAAiB;AAChF;ACNO,SAAS,cAAc,GAAmB;AACvC,WAAA,uBAAG,MAAM,aAAY,CAAC,CAAC,GAC5B,QACA,EAAA,IAAI,CAAC,GAAG,MAAM,SAAS,CAAW,IAAI,MAAM,CAAC,EAC7C,OAAO,CAAC,GAAG,MAAM,IAAI,CAAC;AAC3B;AAEgB,SAAA,eAAe,GAAoB,IAAoB;AAC9D,SAAA,OAAO,UAAU,SAAS,CAAW,CAAC,IAAI,SAAS,CAAW,IAAI;AAC3E;AAGO,SAAS,gBAAgB,KAAa;AAC3C,QAAM,SAAS,IAAI,MAAM,GAAG,EAAE,QAAQ,CAAK,MAAA;AACnC,UAAA,SAAS,EAAE,MAAM,mBAAmB;AACpC,UAAA,QAAQ,iCAAS;AACvB,QAAI,MAAO,QAAO,OAAO,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,QAAM,EAAE,CAAC,CAAC,GAAG,QAAQ;AAAA,EACjE,CAAA,EAAE,OAAO,CAAA,MAAK,CAAC;AAChB,SAAO,OAAO,OAAO,IAAI,GAAG,MAAM;AACpC;AAEO,SAAS,YAAY,GAAW;AAC9B,SAAA,EAAE,QAAQ,kBAAkB,EAAE;AACvC;ACvBO,MAAM,SAAS;AAAA,EAEpB,YAAoB,UAAoC;AADjD;AACa,SAAA,WAAA;AAClB,SAAK,WAAW,IAAI,qBAAqB,KAAK,mBAAmB,KAAK,IAAI,CAAC;AAAA,EAC7E;AAAA,EAEA,QAAQ,QAAiB;AAClB,SAAA,SAAS,QAAQ,MAAM;AAAA,EAC9B;AAAA,EAEA,SAAS,QAAiB,cAAsB;AACzC,SAAA,SAAS,UAAU,MAAM;AAC9B,eAAW,MAAM,KAAK,SAAS,QAAQ,MAAM,GAAG,YAAY;AAAA,EAC9D;AAAA,EAEA,mBAAmB,SAA8C;AAC/D,eAAW,SAAS,SAAS;AAC3B,UAAI,MAAM,gBAAgB;AACnB,aAAA,SAAS,MAAM,MAAM;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,OAAO,aAAa,QAAiB,UAAe,cAAsB;AACxE,UAAM,YAAY,IAAI,SAAS,OAAOC,YAAoB;AAClD,YAAA,YAAY,MAAM;AACxB,UAAI,UAAW,WAAU,SAASA,SAAQ,YAAY;AAAA,IAAA,CACvD;AACD,cAAU,QAAQ,MAAM;AACjB,WAAA;AAAA,EACT;AACF;AAEO,MAAM,cAAc;AAAA;AAAA,EAGzB,YAAY,UAAuB,gBAAgB,kBAA0B,iBAAiB,MAAM;AAF7F;AAeP,oCAAW,CAAC,WAA6B;AAClC,WAAA,gBAAgB,SAAS,UAAU,MAAM;AAC9C,aAAO,MAAM,OAAO,aAAa,KAAK,aAAa;AACnD,UAAI,KAAK,eAAuB,QAAA,gBAAgB,KAAK,aAAa;AAAA,IAAA;AAhBjC,SAAA,gBAAA;AAA0C,SAAA,iBAAA;AAC3E,SAAK,kBAAkB,IAAI,SAAS,CAAC,WAAoB;AAC9C,eAAA,QAAQ,KAAK,QAAQ;AAAA,IAAA,CAC/B;AAAA,EACH;AAAA,EAEA,OAAO,SAAkB,KAAuB,QAAgB;AAC1D,QAAA,CAAC,OAAO,CAAC,OAAQ;AACjB,QAAA,aAAa,KAAK,eAAe,MAAM;AAC3C,QAAI,MAAM;AACL,SAAA,gBAAgB,QAAQ,GAAG;AAAA,EAClC;AAAA;AAAA,EASA,OAAO,OAAO,UAAe;AAE3B,UAAM,gBAAgB,IAAI,cAAc,CAAC,QAAiB,aAAkB;AACtE,UAAA,SAAS,MAAM,GAAG;AACpB,iBAAS,MAAM;AAAA,MACjB;AAAA,IAAA,CACD;AACM,WAAA;AAAA,EACT;AACF;AClEO,SAAS,cAAc,GAAW,IAAI,GAAG,IAAI,GAAW;AACrD,UAAA,IAAI,KAAK,KAAK;AACxB;ACFO,SAAS,SAAS,MAA2B;AAClD,QAAM,SAAS,IAAI,YAAY,gBAAgB,MAAM,WAAW,EAAE;AAClE,SAAO,OAAO,SAAS,SAAS,IAAI,SAAS,OAAO;AACtD;AAEgB,SAAA,eAAe,QAA+B,QAA+B;AAChF,aAAA,QAAQ,OAAO,YAAY;AACpC,SAAK,aAAa,OAAO,aAAa,KAAK,UAAU,KAAK,SAAS;AAAA,EACrE;AACF;AAEgB,SAAA,kBAAkB,GAA0B,SAAiB;AJXtE;AIYC,QAAA,gBAAgB,SAAS,cAAc,OAAO;AACpD,iBAAe,eAAe,CAAC;AAC/B,gBAAc,YAAY,EAAE;AAC1B,UAAA,eAAA,mBAAY,aAAa,eAAe;AACnC,SAAA;AACT;AAEO,SAAS,oBAAoB,UAAwD;AAC1F,SAAO,MAAM,KAAK,QAAQ,EAAE,OAAO,CAAC,KAAK,MAAM;AAC7C,QAAI,EAAE,iBAAiB,CAAC,IAAI,SAAS,EAAE,aAA4B,GAAG;AAAM,UAAA,KAAK,EAAE,aAAa;AAAA,IAAG;AAC5F,WAAA;AAAA,EACT,GAAG,CAAkC,CAAA;AACvC;AAEO,SAAS,gBAAgB,IAA2B;AACrD,MAAA,GAAG,mBAAoB,QAAO,GAAG;AACrC,MAAI,GAAG,cAAsB,QAAA,gBAAgB,GAAG,aAAa;AACtD,SAAA;AACT;AAGgB,SAAA,qBAAqB,QAA+B,UAAkB,UAAqB;AACzG,QAAM,WAAW,IAAI,iBAAiB,CAAC,eAAe;AAC9C,UAAA,KAAK,OAAO,cAAc,QAAQ;AACxC,QAAI,IAAI;AACN,eAAS,WAAW;AACpB,eAAS,EAAE;AAAA,IACb;AAAA,EAAA,CACD;AACQ,WAAA,QAAQ,SAAS,MAAM,EAAE,WAAW,MAAM,SAAS,MAAM;AACpE;AAGgB,SAAA,0BAA0B,SAAgC,UAAqB;AACzF,MAAA,QAAQ,QAAQ,SAAS;AAC7B,QAAM,WAAW,IAAI,iBAAiB,CAAC,cAAcC,cAAa;AAChE,eAAW,YAAY,cAAc;AAC/B,UAAA,SAAS,SAAS,aAAa;AAC7B,YAAA,UAAU,QAAQ,SAAS,QAAQ;AACrC,kBAAQ,QAAQ,SAAS;AACzB,mBAASA,WAAU,KAAK;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AAAA,EAAA,CACD;AACD,WAAS,QAAQ,SAAS,EAAE,WAAW,KAAM,CAAA;AAC/C;AAGO,SAAS,4BAA4B,SAAgC,UAC1E,WAAW,KAAM,UAAmC,EAAE,WAAW,MAAM,SAAS,MAAM,YAAY,QAAQ;AACtG,MAAA;AACA,MAAA;AACJ,QAAM,WAAW,IAAI,iBAAiB,CAAC,eAAe,cAAc;AAC5D,UAAA,MAAM,KAAK;AACb,QAAA,oBAAoB,MAAM,mBAAmB,UAAU;AACzD,iBAAW,aAAa,OAAO;AAAA,IACjC;AACU,cAAA,WAAW,UAAU,QAAQ;AACpB,uBAAA;AAAA,EAAA,CACpB;AACQ,WAAA,QAAQ,SAAS,OAAO;AACnC;AAEgB,SAAA,WAAW,UAAU,EAAE,QAAQ,IAAI,OAAO,IAAI,QAAQ,IAAI,UAAU,MAAM;AAAE,KAAK;AJ5E1F;AI6EC,QAAA,MAAM,SAAS,QAAQ,MAAM;AAE/B,MAAA,QAAQ,OAAiB,gBAAA,cAAc,QAAQ,MAAM,MAA5B,mBAA+B,OAAO;AAC/D,MAAA,QAAQ,MAAgB,gBAAA,cAAc,QAAQ,KAAK,MAA3B,mBAA8B,MAAM;AAE5D,MAAA,iBAAiB,SAAS,CAAC,MAAM;AACnC,MAAE,eAAe;AAEb,QAAA,QAAQ,SAAU,SAAQ,SAAS;AAEvC,yBAAqB,SAAS,MAAM,SAAS,CAAC,UAA4B;AACxE,aAAO,SAAS,OAAO,MAAM,aAAa,KAAK;AAAA,IAAA,CAChD;AAAA,EAAA,CACF;AACH;ACzFO,MAAM,YAAY;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAuC,EAAE,KAAK,GAAG;AAEnC,SAAA,UAAU,KAAa,UAAmC,EAAE,MAAM,OAAO,QAAQ,SAAS;AACxG,QAAM,UAAU,CAAA;AAChB,MAAI,QAAQ,OAAe,QAAA,OAAO,SAAS,EAAE,SAAS,IAAI,QAAQ,EAAE,cAAc,UAAW,CAAA,EAAG,CAAA;AAChG,SAAO,MAAM,KAAK,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,KAAA,CAAM,EAAE,KAAK,CAAK,MAAA,QAAQ,OAAO,SAAS,CAAC,IAAI,CAAC;AAC3F;AAEa,MAAA,YAAY,CAAC,QAAgB,UAAU,KAAK,EAAE,MAAM,MAAM;AAEhE,MAAM,YAAY,CAAC,QAAgB,UAAU,GAAG;AAEhD,SAAS,iBAAiB,QAA6D;AACtF,QAAA,WAAW,IAAI;AACrB,SAAO,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,SAAS,OAAO,GAAG,CAAW,CAAC;AACnE,SAAA;AACT;ACpBgB,SAAA,aAAa,KAA4B,QAAuB,UAAqB;AACnG,aAAW,KAAK,QAAQ;AAClB,QAAA,iBAAiB,GAAG,UAAU,IAAI;AAAA,EACxC;AACF;AAEO,MAAM,KAAK;AAAA,EAKhB,YAAoB,OAAuB,iBAAiB,MAAM;AAJ1D;AAEA;AAAA;AAEY,SAAA,QAAA;AAAuB,SAAA,iBAAA;AACzC,SAAK,OAAO;AACZ,SAAK,QAAQ;AACb,SAAK,iBAAiB;AAAA,EACxB;AAAA;AAAA,EAGA,MAAM,UAAe,gBAAgB,MAAM;AACzC,SAAK,KAAK;AACV,SAAK,gBAAgB;AACjB,QAAA,KAAK,eAAyB;AAClC,SAAK,OAAO,YAAY,UAAU,KAAK,KAAK;AAAA,EAC9C;AAAA,EAEA,OAAO;AACD,QAAA,KAAK,SAAS,MAAM;AACtB,oBAAc,KAAK,IAAI;AACvB,WAAK,OAAO;AAAA,IACd;AACA,QAAI,KAAK,eAAe;AACtB,WAAK,cAAc;AACnB,WAAK,gBAAgB;AAAA,IACvB;AAAA,EACF;AACF;ACpCO,SAAS,QAAQ;AACf,SAAA,kBAAkB,KAAK,UAAU,SAAS;AACnD;ACAA,eAAsB,sBAAsB,UAAyB;AACnE,QAAM,MAAM,CAAA;AACZ,mBAAiB,KAAK,UAAU;AAC1B,QAAA,KAAK,MAAM,EAAA,CAAG;AAAA,EACpB;AACO,SAAA;AACT;AAEO,SAAS,KAAK,cAAsB;AACzC,SAAO,IAAI,QAAQ,CAAA,YAAW,WAAW,SAAS,YAAY,CAAC;AACjE;AAGO,MAAM,SAAS;AAAA,EAAf;AAEL;AAAA,gCAAmB,CAAA;AACnB,gCAAO;AAAA;AAAA;AAAA,EAGP,qBAAqB,IAAI,GAAQ;AAC/B,QAAI,IAAI,KAAK,KAAK,KAAK,WAAW,EAAU,QAAA;AAC5C,UAAM,IAAI,KAAK,KAAK,UAAU,CAAK,MAAA,EAAE,MAAM,CAAC;AAC5C,QAAI,KAAK,GAAG;AACV,YAAM,MAAM,KAAK,KAAK,CAAC,EAAE;AACzB,WAAK,OAAO,KAAK,KAAK,MAAM,GAAG,CAAC,EAAE,OAAO,KAAK,KAAK,MAAM,IAAI,CAAC,CAAC;AACxD,aAAA;AAAA,IACT;AACO,WAAA,KAAK,qBAAqB,IAAI,CAAC;AAAA,EACxC;AAAA,EAEA,CAAC,gBAAgB;AACR,WAAA,KAAK,KAAK,SAAS,GAAG;AAC3B,YAAM,KAAK;IACb;AAAA,EACF;AAAA,EAEA,MAAM,cAAc;AACd,QAAA,CAAC,KAAK,MAAM;AACd,WAAK,OAAO;AACK,uBAAA,KAAK,KAAK,iBAAiB;AAC1C,cAAM,EAAE;AAAA,MACV;AACA,WAAK,OAAO;AAAA,IACd;AAAA,EACF;AAAA;AAAA,EAGA,KAAK,GAAQ;AACN,SAAA,KAAK,KAAK,CAAC;AAChB,SAAK,YAAY;AAAA,EACnB;AACF;ACrDgB,SAAA,OAAU,KAAe,GAA4B;AACnE,QAAM,MAAM,CAAA;AACZ,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,GAAG;AACtC,QAAI,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,CAAC;AAAA,EAC9B;AACO,SAAA;AACT;AAEgB,SAAA,MAAM,MAAc,UAAU,GAAkB;AACvD,SAAA,CAAC,GAAG,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE,IAAI,CAAK,MAAA,IAAI,OAAO;AACrD;"}
1
+ {"version":3,"file":"billy-herrington-utils.es.js","sources":["../src/utils/strings/index.ts","../src/utils/parsers/index.ts","../src/utils/observers/index.ts","../src/utils/math/index.ts","../src/utils/dom/index.ts","../src/utils/fetch/index.ts","../src/utils/events/index.ts","../src/utils/device/index.ts","../src/utils/async/index.ts","../src/utils/arrays/index.ts"],"sourcesContent":["export function stringToWords(s: string): Array<string> {\r\n return s.split(\",\").map(s => s.trim().toLowerCase()).filter(_ => _);\r\n}\r\n\r\nexport function sanitizeStr(s: string) {\r\n return s?.replace(/\\n|\\t/, ' ').replace(/ {2,}/, ' ').trim().toLowerCase() || \"\";\r\n}\r\n","export function timeToSeconds(t: string): number {\r\n return (t?.match(/\\d+/gm) || [0])\r\n .reverse()\r\n .map((s, i) => parseInt(s as string) * 60 ** i)\r\n .reduce((a, b) => a + b);\r\n}\r\n\r\nexport function parseIntegerOr(n: string | number, or: number): number {\r\n return Number.isInteger(parseInt(n as string)) ? parseInt(n as string) : or;\r\n}\r\n\r\n// \"data:02;body+head:async;void:;zero:;\"\r\nexport function parseDataParams(str: string) {\r\n const params = str.split(';').flatMap(s => {\r\n const parsed = s.match(/([\\+\\w+]+):(\\w+)?/);\r\n const value = parsed?.[2];\r\n if (value) return parsed[1].split('+').map(p => ({ [p]: value }));\r\n }).filter(_ => _);\r\n return Object.assign({}, ...params);\r\n}\r\n\r\nexport function parseCSSUrl(s: string) {\r\n return s.replace(/url\\(\"|\\\"\\).*/g, '');\r\n}","export class Observer {\r\n public observer: IntersectionObserver;\r\n constructor(private callback: (entry: Element) => void) {\r\n this.observer = new IntersectionObserver(this.handleIntersection.bind(this));\r\n }\r\n\r\n observe(target: Element) {\r\n this.observer.observe(target);\r\n }\r\n\r\n throttle(target: Element, throttleTime: number) {\r\n this.observer.unobserve(target);\r\n setTimeout(() => this.observer.observe(target), throttleTime);\r\n }\r\n\r\n handleIntersection(entries: Iterable<IntersectionObserverEntry>) {\r\n for (const entry of entries) {\r\n if (entry.isIntersecting) {\r\n this.callback(entry.target);\r\n }\r\n }\r\n }\r\n\r\n static observeWhile(target: Element, callback: () => Promise<boolean> | boolean, throttleTime: number) {\r\n const observer_ = new Observer(async (target: Element) => {\r\n const condition = await callback();\r\n if (condition) observer_.throttle(target, throttleTime);\r\n });\r\n observer_.observe(target);\r\n return observer_;\r\n }\r\n}\r\n\r\nexport class LazyImgLoader {\r\n public lazyImgObserver: Observer;\r\n private attributeName = 'data-lazy-load';\r\n\r\n constructor(shouldDelazify: (target: Element) => boolean) {\r\n this.lazyImgObserver = new Observer((target: Element) => {\r\n if (shouldDelazify(target)) {\r\n this.delazify(target as HTMLImageElement);\r\n }\r\n });\r\n }\r\n\r\n lazify(_target: Element, img: HTMLImageElement, imgSrc: string) {\r\n if (!img || !imgSrc) return;\r\n img.setAttribute(this.attributeName, imgSrc);\r\n img.src = '';\r\n this.lazyImgObserver.observe(img);\r\n }\r\n\r\n delazify = (target: HTMLImageElement) => {\r\n this.lazyImgObserver.observer.unobserve(target);\r\n target.src = target.getAttribute(this.attributeName) as string;\r\n target.removeAttribute(this.attributeName);\r\n }\r\n}\r\n","export function circularShift(n: number, c = 6, s = 1): number {\r\n return (n + s) % c || c;\r\n}\r\n","export function parseDom(html: string): HTMLElement {\r\n const parsed = new DOMParser().parseFromString(html, 'text/html').body;\r\n return parsed.children.length > 1 ? parsed : parsed.firstElementChild as HTMLElement;\r\n}\r\n\r\nexport function copyAttributes(target: HTMLElement | Element, source: HTMLElement | Element) {\r\n for (const attr of source.attributes) {\r\n attr.nodeValue && target.setAttribute(attr.nodeName, attr.nodeValue);\r\n }\r\n}\r\n\r\nexport function replaceElementTag(e: HTMLElement | Element, tagName: string) {\r\n const newTagElement = document.createElement(tagName);\r\n copyAttributes(newTagElement, e);\r\n newTagElement.innerHTML = e.innerHTML;\r\n e.parentNode?.replaceChild(newTagElement, e);\r\n return newTagElement;\r\n}\r\n\r\nexport function getAllUniqueParents(elements: HTMLCollection): Array<HTMLElement | Element> {\r\n return Array.from(elements).reduce((acc, v) => {\r\n if (v.parentElement && !acc.includes(v.parentElement as HTMLElement)) { acc.push(v.parentElement); }\r\n return acc;\r\n }, [] as Array<HTMLElement | Element>);\r\n}\r\n\r\nexport function findNextSibling(el: HTMLElement | Element) {\r\n if (el.nextElementSibling) return el.nextElementSibling;\r\n if (el.parentElement) return findNextSibling(el.parentElement);\r\n return null;\r\n}\r\n\r\nexport function waitForElementExists(parent: HTMLElement | Element, selector: string, callback: (el: Element) => void): void {\r\n const observer = new MutationObserver((_mutations) => {\r\n const el = parent.querySelector(selector);\r\n if (el) {\r\n observer.disconnect();\r\n callback(el);\r\n }\r\n });\r\n observer.observe(document.body, { childList: true, subtree: true });\r\n}\r\n\r\nexport function watchElementChildrenCount(element: HTMLElement | Element,\r\n callback: (observer: MutationObserver, count: number) => void): void {\r\n let count = element.children.length;\r\n const observer = new MutationObserver((mutationList, observer) => {\r\n for (const mutation of mutationList) {\r\n if (mutation.type === \"childList\") {\r\n if (count !== element.children.length) {\r\n count = element.children.length;\r\n callback(observer, count);\r\n }\r\n }\r\n }\r\n });\r\n observer.observe(element, { childList: true });\r\n}\r\n\r\nexport function watchDomChangesWithThrottle(element: HTMLElement | Element, callback: () => void,\r\n throttle = 1000, options: Record<string, boolean> = { childList: true, subtree: true, attributes: true }) {\r\n let lastMutationTime: number;\r\n let timeout: number;\r\n const observer = new MutationObserver((_mutationList, _observer) => {\r\n const now = Date.now();\r\n if (lastMutationTime && now - lastMutationTime < throttle) {\r\n timeout && clearTimeout(timeout);\r\n }\r\n timeout = setTimeout(callback, throttle);\r\n lastMutationTime = now;\r\n });\r\n observer.observe(element, options);\r\n}\r\n\r\nexport function downloader(options = { append: \"\", after: \"\", button: \"\", cbBefore: () => { } }) {\r\n const btn = parseDom(options.button);\r\n\r\n if (options.append) document.querySelector(options.append)?.append(btn);\r\n if (options.after) document.querySelector(options.after)?.after(btn);\r\n\r\n btn.addEventListener('click', (e) => {\r\n e.preventDefault();\r\n\r\n if (options.cbBefore) options.cbBefore();\r\n\r\n waitForElementExists(document.body, 'video', (video: Element) => {\r\n window.location.href = video.getAttribute('src') as string;\r\n });\r\n });\r\n}","import { parseDom } from \"../dom\";\r\n\r\nexport const MOBILE_UA = [\r\n 'Mozilla/5.0 (Linux; Android 10; K)',\r\n 'AppleWebKit/537.36 (KHTML, like Gecko)',\r\n 'Chrome/114.0.0.0 Mobile Safari/537.36'].join(' ');\r\n\r\nexport function fetchWith(url: string, options: Record<string, boolean> = { html: false, mobile: false }) {\r\n const reqOpts = {};\r\n if (options.mobile) Object.assign(reqOpts, { headers: new Headers({ \"User-Agent\": MOBILE_UA }) });\r\n return fetch(url, reqOpts).then((r) => r.text()).then(r => options.html ? parseDom(r) : r);\r\n}\r\n\r\nexport const fetchHtml = (url: string) => fetchWith(url, { html: true });\r\n\r\nexport const fetchText = (url: string) => fetchWith(url);\r\n\r\nexport function objectToFormData(object: Record<string, number | boolean | string>): FormData {\r\n const formData = new FormData();\r\n Object.entries(object).forEach(([k, v]) => formData.append(k, v as string));\r\n return formData;\r\n}\r\n","export function listenEvents(dom: HTMLElement | Element, events: Array<string>, callback: (e: Event) => void): void {\r\n for (const e of events) {\r\n dom.addEventListener(e, callback, true);\r\n }\r\n}\r\n\r\nexport class Tick {\r\n private tick: null | number;\r\n private callbackFinal: (() => void) | undefined;\r\n\r\n constructor(private delay: number, private startImmediate = true) {\r\n this.tick = null;\r\n this.delay = delay;\r\n this.startImmediate = startImmediate;\r\n }\r\n\r\n start(callback: () => void, callbackFinal = undefined) {\r\n this.stop();\r\n this.callbackFinal = callbackFinal;\r\n if (this.startImmediate) callback();\r\n this.tick = setInterval(callback, this.delay);\r\n }\r\n\r\n stop() {\r\n if (this.tick !== null) {\r\n clearInterval(this.tick);\r\n this.tick = null;\r\n }\r\n if (this.callbackFinal) {\r\n this.callbackFinal();\r\n this.callbackFinal = undefined;\r\n }\r\n }\r\n}","export function isMob() {\r\n return /iPhone|Android/i.test(navigator.userAgent);\r\n}","// https://2ality.com/2016/10/asynchronous-iteration.html\r\nexport async function computeAsyncOneAtTime(iterable: Iterable<() => Promise<void>>) {\r\n const res = [];\r\n for await (const f of iterable) {\r\n res.push(await f());\r\n }\r\n return res;\r\n}\r\n\r\nexport function wait(milliseconds: number) {\r\n return new Promise(resolve => setTimeout(resolve, milliseconds));\r\n}\r\n\r\ninterface SyncPoolObject {\r\n v: () => Promise<void>,\r\n p: number\r\n}\r\n\r\nexport class AsyncPool {\r\n cur = 0;\r\n private finished: Promise<boolean>;\r\n private _resolve?: (value: boolean | PromiseLike<boolean>) => void;\r\n\r\n constructor(private max = 1, private pool: Array<SyncPoolObject> = []) {\r\n this.finished = new Promise((resolve) => {\r\n this._resolve = resolve;\r\n });\r\n }\r\n\r\n getHighPriorityFirst(p = 0): (() => Promise<void>) | undefined {\r\n if (p > 3 || this.pool.length === 0) return undefined;\r\n const i = this.pool.findIndex(e => e.p === p);\r\n if (i >= 0) {\r\n const res = this.pool[i].v;\r\n this.pool = this.pool.slice(0, i).concat(this.pool.slice(i + 1));\r\n return res;\r\n }\r\n return this.getHighPriorityFirst(p + 1);\r\n }\r\n\r\n async runTask() {\r\n this.cur++;\r\n const f = this.getHighPriorityFirst();\r\n await f?.();\r\n this.cur--;\r\n this.runTasks();\r\n }\r\n\r\n runTasks() {\r\n if (!this.pool.length) this._resolve?.(true);\r\n if (this.cur < this.max) {\r\n this.runTask();\r\n this.runTasks();\r\n }\r\n }\r\n\r\n async run() {\r\n this.runTasks();\r\n return this.finished;\r\n }\r\n\r\n push(x: SyncPoolObject | (() => Promise<void>)) {\r\n this.pool.push('p' in x ? x : ({ v: x, p: 0 }));\r\n }\r\n}","export function chunks<T>(arr: Array<T>, n: number): Array<Array<T>> {\r\n const res = [];\r\n for (let i = 0; i < arr.length; i += n) {\r\n res.push(arr.slice(i, i + n));\r\n }\r\n return res;\r\n}\r\n\r\nexport function range(size: number, startAt = 1): Array<number> {\r\n return [...Array(size).keys()].map(i => i + startAt);\r\n}"],"names":["s","target","observer"],"mappings":";;;AAAO,SAAS,cAAc,GAA0B;AACtD,SAAO,EAAE,MAAM,GAAG,EAAE,IAAI,CAAAA,OAAKA,GAAE,OAAO,YAAY,CAAC,EAAE,OAAO,OAAK,CAAC;AACpE;AAEO,SAAS,YAAY,GAAW;AACrC,SAAO,GAAG,QAAQ,SAAS,GAAG,EAAE,QAAQ,SAAS,GAAG,EAAE,KAAA,EAAO,YAAA,KAAiB;AAChF;ACNO,SAAS,cAAc,GAAmB;AACvC,UAAA,GAAG,MAAM,OAAO,KAAK,CAAC,CAAC,GAC5B,QACA,EAAA,IAAI,CAAC,GAAG,MAAM,SAAS,CAAW,IAAI,MAAM,CAAC,EAC7C,OAAO,CAAC,GAAG,MAAM,IAAI,CAAC;AAC3B;AAEgB,SAAA,eAAe,GAAoB,IAAoB;AAC9D,SAAA,OAAO,UAAU,SAAS,CAAW,CAAC,IAAI,SAAS,CAAW,IAAI;AAC3E;AAGO,SAAS,gBAAgB,KAAa;AAC3C,QAAM,SAAS,IAAI,MAAM,GAAG,EAAE,QAAQ,CAAK,MAAA;AACnC,UAAA,SAAS,EAAE,MAAM,mBAAmB;AACpC,UAAA,QAAQ,SAAS,CAAC;AACxB,QAAI,MAAO,QAAO,OAAO,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,QAAM,EAAE,CAAC,CAAC,GAAG,QAAQ;AAAA,EACjE,CAAA,EAAE,OAAO,CAAA,MAAK,CAAC;AAChB,SAAO,OAAO,OAAO,IAAI,GAAG,MAAM;AACpC;AAEO,SAAS,YAAY,GAAW;AAC9B,SAAA,EAAE,QAAQ,kBAAkB,EAAE;AACvC;ACvBO,MAAM,SAAS;AAAA,EAEpB,YAAoB,UAAoC;AADjD;AACa,SAAA,WAAA;AAClB,SAAK,WAAW,IAAI,qBAAqB,KAAK,mBAAmB,KAAK,IAAI,CAAC;AAAA,EAC7E;AAAA,EAEA,QAAQ,QAAiB;AAClB,SAAA,SAAS,QAAQ,MAAM;AAAA,EAC9B;AAAA,EAEA,SAAS,QAAiB,cAAsB;AACzC,SAAA,SAAS,UAAU,MAAM;AAC9B,eAAW,MAAM,KAAK,SAAS,QAAQ,MAAM,GAAG,YAAY;AAAA,EAC9D;AAAA,EAEA,mBAAmB,SAA8C;AAC/D,eAAW,SAAS,SAAS;AAC3B,UAAI,MAAM,gBAAgB;AACnB,aAAA,SAAS,MAAM,MAAM;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,aAAa,QAAiB,UAA4C,cAAsB;AACrG,UAAM,YAAY,IAAI,SAAS,OAAOC,YAAoB;AAClD,YAAA,YAAY,MAAM;AACxB,UAAI,UAAW,WAAU,SAASA,SAAQ,YAAY;AAAA,IAAA,CACvD;AACD,cAAU,QAAQ,MAAM;AACjB,WAAA;AAAA,EACT;AACF;AAEO,MAAM,cAAc;AAAA,EAIzB,YAAY,gBAA8C;AAHnD;AACC,yCAAgB;AAiBxB,oCAAW,CAAC,WAA6B;AAClC,WAAA,gBAAgB,SAAS,UAAU,MAAM;AAC9C,aAAO,MAAM,OAAO,aAAa,KAAK,aAAa;AAC5C,aAAA,gBAAgB,KAAK,aAAa;AAAA,IAAA;AAjBzC,SAAK,kBAAkB,IAAI,SAAS,CAAC,WAAoB;AACnD,UAAA,eAAe,MAAM,GAAG;AAC1B,aAAK,SAAS,MAA0B;AAAA,MAC1C;AAAA,IAAA,CACD;AAAA,EACH;AAAA,EAEA,OAAO,SAAkB,KAAuB,QAAgB;AAC1D,QAAA,CAAC,OAAO,CAAC,OAAQ;AACjB,QAAA,aAAa,KAAK,eAAe,MAAM;AAC3C,QAAI,MAAM;AACL,SAAA,gBAAgB,QAAQ,GAAG;AAAA,EAClC;AAOF;ACzDO,SAAS,cAAc,GAAW,IAAI,GAAG,IAAI,GAAW;AACrD,UAAA,IAAI,KAAK,KAAK;AACxB;ACFO,SAAS,SAAS,MAA2B;AAClD,QAAM,SAAS,IAAI,YAAY,gBAAgB,MAAM,WAAW,EAAE;AAClE,SAAO,OAAO,SAAS,SAAS,IAAI,SAAS,OAAO;AACtD;AAEgB,SAAA,eAAe,QAA+B,QAA+B;AAChF,aAAA,QAAQ,OAAO,YAAY;AACpC,SAAK,aAAa,OAAO,aAAa,KAAK,UAAU,KAAK,SAAS;AAAA,EACrE;AACF;AAEgB,SAAA,kBAAkB,GAA0B,SAAiB;AACrE,QAAA,gBAAgB,SAAS,cAAc,OAAO;AACpD,iBAAe,eAAe,CAAC;AAC/B,gBAAc,YAAY,EAAE;AAC1B,IAAA,YAAY,aAAa,eAAe,CAAC;AACpC,SAAA;AACT;AAEO,SAAS,oBAAoB,UAAwD;AAC1F,SAAO,MAAM,KAAK,QAAQ,EAAE,OAAO,CAAC,KAAK,MAAM;AAC7C,QAAI,EAAE,iBAAiB,CAAC,IAAI,SAAS,EAAE,aAA4B,GAAG;AAAM,UAAA,KAAK,EAAE,aAAa;AAAA,IAAG;AAC5F,WAAA;AAAA,EACT,GAAG,CAAkC,CAAA;AACvC;AAEO,SAAS,gBAAgB,IAA2B;AACrD,MAAA,GAAG,mBAAoB,QAAO,GAAG;AACrC,MAAI,GAAG,cAAsB,QAAA,gBAAgB,GAAG,aAAa;AACtD,SAAA;AACT;AAEgB,SAAA,qBAAqB,QAA+B,UAAkB,UAAuC;AAC3H,QAAM,WAAW,IAAI,iBAAiB,CAAC,eAAe;AAC9C,UAAA,KAAK,OAAO,cAAc,QAAQ;AACxC,QAAI,IAAI;AACN,eAAS,WAAW;AACpB,eAAS,EAAE;AAAA,IACb;AAAA,EAAA,CACD;AACQ,WAAA,QAAQ,SAAS,MAAM,EAAE,WAAW,MAAM,SAAS,MAAM;AACpE;AAEgB,SAAA,0BAA0B,SACxC,UAAqE;AACjE,MAAA,QAAQ,QAAQ,SAAS;AAC7B,QAAM,WAAW,IAAI,iBAAiB,CAAC,cAAcC,cAAa;AAChE,eAAW,YAAY,cAAc;AAC/B,UAAA,SAAS,SAAS,aAAa;AAC7B,YAAA,UAAU,QAAQ,SAAS,QAAQ;AACrC,kBAAQ,QAAQ,SAAS;AACzB,mBAASA,WAAU,KAAK;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AAAA,EAAA,CACD;AACD,WAAS,QAAQ,SAAS,EAAE,WAAW,KAAM,CAAA;AAC/C;AAEO,SAAS,4BAA4B,SAAgC,UAC1E,WAAW,KAAM,UAAmC,EAAE,WAAW,MAAM,SAAS,MAAM,YAAY,QAAQ;AACtG,MAAA;AACA,MAAA;AACJ,QAAM,WAAW,IAAI,iBAAiB,CAAC,eAAe,cAAc;AAC5D,UAAA,MAAM,KAAK;AACb,QAAA,oBAAoB,MAAM,mBAAmB,UAAU;AACzD,iBAAW,aAAa,OAAO;AAAA,IACjC;AACU,cAAA,WAAW,UAAU,QAAQ;AACpB,uBAAA;AAAA,EAAA,CACpB;AACQ,WAAA,QAAQ,SAAS,OAAO;AACnC;AAEgB,SAAA,WAAW,UAAU,EAAE,QAAQ,IAAI,OAAO,IAAI,QAAQ,IAAI,UAAU,MAAM;AAAE,KAAK;AACzF,QAAA,MAAM,SAAS,QAAQ,MAAM;AAE/B,MAAA,QAAQ,OAAiB,UAAA,cAAc,QAAQ,MAAM,GAAG,OAAO,GAAG;AAClE,MAAA,QAAQ,MAAgB,UAAA,cAAc,QAAQ,KAAK,GAAG,MAAM,GAAG;AAE/D,MAAA,iBAAiB,SAAS,CAAC,MAAM;AACnC,MAAE,eAAe;AAEb,QAAA,QAAQ,SAAU,SAAQ,SAAS;AAEvC,yBAAqB,SAAS,MAAM,SAAS,CAAC,UAAmB;AAC/D,aAAO,SAAS,OAAO,MAAM,aAAa,KAAK;AAAA,IAAA,CAChD;AAAA,EAAA,CACF;AACH;ACvFO,MAAM,YAAY;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAuC,EAAE,KAAK,GAAG;AAEnC,SAAA,UAAU,KAAa,UAAmC,EAAE,MAAM,OAAO,QAAQ,SAAS;AACxG,QAAM,UAAU,CAAA;AAChB,MAAI,QAAQ,OAAe,QAAA,OAAO,SAAS,EAAE,SAAS,IAAI,QAAQ,EAAE,cAAc,UAAW,CAAA,EAAG,CAAA;AAChG,SAAO,MAAM,KAAK,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,KAAA,CAAM,EAAE,KAAK,CAAK,MAAA,QAAQ,OAAO,SAAS,CAAC,IAAI,CAAC;AAC3F;AAEa,MAAA,YAAY,CAAC,QAAgB,UAAU,KAAK,EAAE,MAAM,MAAM;AAEhE,MAAM,YAAY,CAAC,QAAgB,UAAU,GAAG;AAEhD,SAAS,iBAAiB,QAA6D;AACtF,QAAA,WAAW,IAAI;AACrB,SAAO,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,SAAS,OAAO,GAAG,CAAW,CAAC;AACnE,SAAA;AACT;ACrBgB,SAAA,aAAa,KAA4B,QAAuB,UAAoC;AAClH,aAAW,KAAK,QAAQ;AAClB,QAAA,iBAAiB,GAAG,UAAU,IAAI;AAAA,EACxC;AACF;AAEO,MAAM,KAAK;AAAA,EAIhB,YAAoB,OAAuB,iBAAiB,MAAM;AAH1D;AACA;AAEY,SAAA,QAAA;AAAuB,SAAA,iBAAA;AACzC,SAAK,OAAO;AACZ,SAAK,QAAQ;AACb,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,MAAM,UAAsB,gBAAgB,QAAW;AACrD,SAAK,KAAK;AACV,SAAK,gBAAgB;AACjB,QAAA,KAAK,eAAyB;AAClC,SAAK,OAAO,YAAY,UAAU,KAAK,KAAK;AAAA,EAC9C;AAAA,EAEA,OAAO;AACD,QAAA,KAAK,SAAS,MAAM;AACtB,oBAAc,KAAK,IAAI;AACvB,WAAK,OAAO;AAAA,IACd;AACA,QAAI,KAAK,eAAe;AACtB,WAAK,cAAc;AACnB,WAAK,gBAAgB;AAAA,IACvB;AAAA,EACF;AACF;ACjCO,SAAS,QAAQ;AACf,SAAA,kBAAkB,KAAK,UAAU,SAAS;AACnD;ACDA,eAAsB,sBAAsB,UAAyC;AACnF,QAAM,MAAM,CAAA;AACZ,mBAAiB,KAAK,UAAU;AAC1B,QAAA,KAAK,MAAM,EAAA,CAAG;AAAA,EACpB;AACO,SAAA;AACT;AAEO,SAAS,KAAK,cAAsB;AACzC,SAAO,IAAI,QAAQ,CAAA,YAAW,WAAW,SAAS,YAAY,CAAC;AACjE;AAOO,MAAM,UAAU;AAAA,EAKrB,YAAoB,MAAM,GAAW,OAA8B,CAAA,GAAI;AAJvE,+BAAM;AACE;AACA;AAEY,SAAA,MAAA;AAAiB,SAAA,OAAA;AACnC,SAAK,WAAW,IAAI,QAAQ,CAAC,YAAY;AACvC,WAAK,WAAW;AAAA,IAAA,CACjB;AAAA,EACH;AAAA,EAEA,qBAAqB,IAAI,GAAsC;AAC7D,QAAI,IAAI,KAAK,KAAK,KAAK,WAAW,EAAU,QAAA;AAC5C,UAAM,IAAI,KAAK,KAAK,UAAU,CAAK,MAAA,EAAE,MAAM,CAAC;AAC5C,QAAI,KAAK,GAAG;AACV,YAAM,MAAM,KAAK,KAAK,CAAC,EAAE;AACzB,WAAK,OAAO,KAAK,KAAK,MAAM,GAAG,CAAC,EAAE,OAAO,KAAK,KAAK,MAAM,IAAI,CAAC,CAAC;AACxD,aAAA;AAAA,IACT;AACO,WAAA,KAAK,qBAAqB,IAAI,CAAC;AAAA,EACxC;AAAA,EAEA,MAAM,UAAU;AACT,SAAA;AACC,UAAA,IAAI,KAAK;AACf,UAAM,IAAI;AACL,SAAA;AACL,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,WAAW;AACT,QAAI,CAAC,KAAK,KAAK,OAAQ,MAAK,WAAW,IAAI;AACvC,QAAA,KAAK,MAAM,KAAK,KAAK;AACvB,WAAK,QAAQ;AACb,WAAK,SAAS;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAM,MAAM;AACV,SAAK,SAAS;AACd,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,KAAK,GAA2C;AACzC,SAAA,KAAK,KAAK,OAAO,IAAI,IAAK,EAAE,GAAG,GAAG,GAAG,EAAI,CAAA;AAAA,EAChD;AACF;AChEgB,SAAA,OAAU,KAAe,GAA4B;AACnE,QAAM,MAAM,CAAA;AACZ,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,GAAG;AACtC,QAAI,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,CAAC;AAAA,EAC9B;AACO,SAAA;AACT;AAEgB,SAAA,MAAM,MAAc,UAAU,GAAkB;AACvD,SAAA,CAAC,GAAG,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE,IAAI,CAAK,MAAA,IAAI,OAAO;AACrD;"}
@@ -9,10 +9,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
9
9
  return s.split(",").map((s2) => s2.trim().toLowerCase()).filter((_) => _);
10
10
  }
11
11
  function sanitizeStr(s) {
12
- return (s == null ? void 0 : s.replace(/\n|\t/, " ").replace(/ {2,}/, " ").trim().toLowerCase()) || "";
12
+ return s?.replace(/\n|\t/, " ").replace(/ {2,}/, " ").trim().toLowerCase() || "";
13
13
  }
14
14
  function timeToSeconds(t) {
15
- return ((t == null ? void 0 : t.match(/\d+/gm)) || [0]).reverse().map((s, i) => parseInt(s) * 60 ** i).reduce((a, b) => a + b);
15
+ return (t?.match(/\d+/gm) || [0]).reverse().map((s, i) => parseInt(s) * 60 ** i).reduce((a, b) => a + b);
16
16
  }
17
17
  function parseIntegerOr(n, or) {
18
18
  return Number.isInteger(parseInt(n)) ? parseInt(n) : or;
@@ -20,7 +20,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
20
20
  function parseDataParams(str) {
21
21
  const params = str.split(";").flatMap((s) => {
22
22
  const parsed = s.match(/([\+\w+]+):(\w+)?/);
23
- const value = parsed == null ? void 0 : parsed[2];
23
+ const value = parsed?.[2];
24
24
  if (value) return parsed[1].split("+").map((p) => ({ [p]: value }));
25
25
  }).filter((_) => _);
26
26
  return Object.assign({}, ...params);
@@ -48,7 +48,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
48
48
  }
49
49
  }
50
50
  }
51
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
52
51
  static observeWhile(target, callback, throttleTime) {
53
52
  const observer_ = new Observer(async (target2) => {
54
53
  const condition = await callback();
@@ -59,18 +58,18 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
59
58
  }
60
59
  }
61
60
  class LazyImgLoader {
62
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
63
- constructor(callback, attributeName = "data-lazy-load", removeTagAfter = true) {
61
+ constructor(shouldDelazify) {
64
62
  __publicField(this, "lazyImgObserver");
63
+ __publicField(this, "attributeName", "data-lazy-load");
65
64
  __publicField(this, "delazify", (target) => {
66
65
  this.lazyImgObserver.observer.unobserve(target);
67
66
  target.src = target.getAttribute(this.attributeName);
68
- if (this.removeTagAfter) target.removeAttribute(this.attributeName);
67
+ target.removeAttribute(this.attributeName);
69
68
  });
70
- this.attributeName = attributeName;
71
- this.removeTagAfter = removeTagAfter;
72
69
  this.lazyImgObserver = new Observer((target) => {
73
- callback(target, this.delazify);
70
+ if (shouldDelazify(target)) {
71
+ this.delazify(target);
72
+ }
74
73
  });
75
74
  }
76
75
  lazify(_target, img, imgSrc) {
@@ -79,15 +78,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
79
78
  img.src = "";
80
79
  this.lazyImgObserver.observe(img);
81
80
  }
82
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
83
- static create(callback) {
84
- const lazyImgLoader = new LazyImgLoader((target, delazify) => {
85
- if (callback(target)) {
86
- delazify(target);
87
- }
88
- });
89
- return lazyImgLoader;
90
- }
91
81
  }
92
82
  function circularShift(n, c = 6, s = 1) {
93
83
  return (n + s) % c || c;
@@ -102,11 +92,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
102
92
  }
103
93
  }
104
94
  function replaceElementTag(e, tagName) {
105
- var _a;
106
95
  const newTagElement = document.createElement(tagName);
107
96
  copyAttributes(newTagElement, e);
108
97
  newTagElement.innerHTML = e.innerHTML;
109
- (_a = e.parentNode) == null ? void 0 : _a.replaceChild(newTagElement, e);
98
+ e.parentNode?.replaceChild(newTagElement, e);
110
99
  return newTagElement;
111
100
  }
112
101
  function getAllUniqueParents(elements) {
@@ -161,10 +150,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
161
150
  }
162
151
  function downloader(options = { append: "", after: "", button: "", cbBefore: () => {
163
152
  } }) {
164
- var _a, _b;
165
153
  const btn = parseDom(options.button);
166
- if (options.append) (_a = document.querySelector(options.append)) == null ? void 0 : _a.append(btn);
167
- if (options.after) (_b = document.querySelector(options.after)) == null ? void 0 : _b.after(btn);
154
+ if (options.append) document.querySelector(options.append)?.append(btn);
155
+ if (options.after) document.querySelector(options.after)?.after(btn);
168
156
  btn.addEventListener("click", (e) => {
169
157
  e.preventDefault();
170
158
  if (options.cbBefore) options.cbBefore();
@@ -198,7 +186,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
198
186
  class Tick {
199
187
  constructor(delay, startImmediate = true) {
200
188
  __publicField(this, "tick");
201
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
202
189
  __publicField(this, "callbackFinal");
203
190
  this.delay = delay;
204
191
  this.startImmediate = startImmediate;
@@ -206,8 +193,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
206
193
  this.delay = delay;
207
194
  this.startImmediate = startImmediate;
208
195
  }
209
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
210
- start(callback, callbackFinal = null) {
196
+ start(callback, callbackFinal = void 0) {
211
197
  this.stop();
212
198
  this.callbackFinal = callbackFinal;
213
199
  if (this.startImmediate) callback();
@@ -220,7 +206,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
220
206
  }
221
207
  if (this.callbackFinal) {
222
208
  this.callbackFinal();
223
- this.callbackFinal = null;
209
+ this.callbackFinal = void 0;
224
210
  }
225
211
  }
226
212
  }
@@ -237,41 +223,47 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
237
223
  function wait(milliseconds) {
238
224
  return new Promise((resolve) => setTimeout(resolve, milliseconds));
239
225
  }
240
- class SyncPull {
241
- constructor() {
242
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
243
- __publicField(this, "pull", []);
244
- __publicField(this, "lock", false);
226
+ class AsyncPool {
227
+ constructor(max = 1, pool = []) {
228
+ __publicField(this, "cur", 0);
229
+ __publicField(this, "finished");
230
+ __publicField(this, "_resolve");
231
+ this.max = max;
232
+ this.pool = pool;
233
+ this.finished = new Promise((resolve) => {
234
+ this._resolve = resolve;
235
+ });
245
236
  }
246
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
247
237
  getHighPriorityFirst(p = 0) {
248
- if (p > 3 || this.pull.length === 0) return void 0;
249
- const i = this.pull.findIndex((e) => e.p === p);
238
+ if (p > 3 || this.pool.length === 0) return void 0;
239
+ const i = this.pool.findIndex((e) => e.p === p);
250
240
  if (i >= 0) {
251
- const res = this.pull[i].v;
252
- this.pull = this.pull.slice(0, i).concat(this.pull.slice(i + 1));
241
+ const res = this.pool[i].v;
242
+ this.pool = this.pool.slice(0, i).concat(this.pool.slice(i + 1));
253
243
  return res;
254
244
  }
255
245
  return this.getHighPriorityFirst(p + 1);
256
246
  }
257
- *pullGenerator() {
258
- while (this.pull.length > 0) {
259
- yield this.getHighPriorityFirst();
260
- }
247
+ async runTask() {
248
+ this.cur++;
249
+ const f = this.getHighPriorityFirst();
250
+ await f?.();
251
+ this.cur--;
252
+ this.runTasks();
261
253
  }
262
- async processPull() {
263
- if (!this.lock) {
264
- this.lock = true;
265
- for await (const f of this.pullGenerator()) {
266
- await f();
267
- }
268
- this.lock = false;
254
+ runTasks() {
255
+ if (!this.pool.length) this._resolve?.(true);
256
+ if (this.cur < this.max) {
257
+ this.runTask();
258
+ this.runTasks();
269
259
  }
270
260
  }
271
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
261
+ async run() {
262
+ this.runTasks();
263
+ return this.finished;
264
+ }
272
265
  push(x) {
273
- this.pull.push(x);
274
- this.processPull();
266
+ this.pool.push("p" in x ? x : { v: x, p: 0 });
275
267
  }
276
268
  }
277
269
  function chunks(arr, n) {
@@ -284,10 +276,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
284
276
  function range(size, startAt = 1) {
285
277
  return [...Array(size).keys()].map((i) => i + startAt);
286
278
  }
279
+ exports2.AsyncPool = AsyncPool;
287
280
  exports2.LazyImgLoader = LazyImgLoader;
288
281
  exports2.MOBILE_UA = MOBILE_UA;
289
282
  exports2.Observer = Observer;
290
- exports2.SyncPull = SyncPull;
291
283
  exports2.Tick = Tick;
292
284
  exports2.chunks = chunks;
293
285
  exports2.circularShift = circularShift;
@@ -1 +1 @@
1
- {"version":3,"file":"billy-herrington-utils.umd.js","sources":["../src/utils/strings/index.ts","../src/utils/parsers/index.ts","../src/utils/observers/index.ts","../src/utils/math/index.ts","../src/utils/dom/index.ts","../src/utils/fetch/index.ts","../src/utils/events/index.ts","../src/utils/device/index.ts","../src/utils/async/index.ts","../src/utils/arrays/index.ts"],"sourcesContent":["export function stringToWords(s: string): Array<string> {\r\n return s.split(\",\").map(s => s.trim().toLowerCase()).filter(_ => _);\r\n}\r\n\r\nexport function sanitizeStr(s: string) {\r\n return s?.replace(/\\n|\\t/, ' ').replace(/ {2,}/, ' ').trim().toLowerCase() || \"\";\r\n}\r\n","export function timeToSeconds(t: string): number {\r\n return (t?.match(/\\d+/gm) || [0])\r\n .reverse()\r\n .map((s, i) => parseInt(s as string) * 60 ** i)\r\n .reduce((a, b) => a + b);\r\n}\r\n\r\nexport function parseIntegerOr(n: string | number, or: number): number {\r\n return Number.isInteger(parseInt(n as string)) ? parseInt(n as string) : or;\r\n}\r\n\r\n// \"data:02;body+head:async;void:;zero:;\"\r\nexport function parseDataParams(str: string) {\r\n const params = str.split(';').flatMap(s => {\r\n const parsed = s.match(/([\\+\\w+]+):(\\w+)?/);\r\n const value = parsed?.[2];\r\n if (value) return parsed[1].split('+').map(p => ({ [p]: value }));\r\n }).filter(_ => _);\r\n return Object.assign({}, ...params);\r\n}\r\n\r\nexport function parseCSSUrl(s: string) {\r\n return s.replace(/url\\(\"|\\\"\\).*/g, '');\r\n}","export class Observer {\r\n public observer: IntersectionObserver;\r\n constructor(private callback: (entry: Element) => void) {\r\n this.observer = new IntersectionObserver(this.handleIntersection.bind(this));\r\n }\r\n\r\n observe(target: Element) {\r\n this.observer.observe(target);\r\n }\r\n\r\n throttle(target: Element, throttleTime: number) {\r\n this.observer.unobserve(target);\r\n setTimeout(() => this.observer.observe(target), throttleTime);\r\n }\r\n\r\n handleIntersection(entries: Iterable<IntersectionObserverEntry>) {\r\n for (const entry of entries) {\r\n if (entry.isIntersecting) {\r\n this.callback(entry.target);\r\n }\r\n }\r\n }\r\n\r\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\n static observeWhile(target: Element, callback: any, throttleTime: number) {\r\n const observer_ = new Observer(async (target: Element) => {\r\n const condition = await callback();\r\n if (condition) observer_.throttle(target, throttleTime);\r\n });\r\n observer_.observe(target);\r\n return observer_;\r\n }\r\n}\r\n\r\nexport class LazyImgLoader {\r\n public lazyImgObserver: Observer;\r\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\n constructor(callback: any, private attributeName = 'data-lazy-load', private removeTagAfter = true) {\r\n this.lazyImgObserver = new Observer((target: Element) => {\r\n callback(target, this.delazify);\r\n });\r\n }\r\n\r\n lazify(_target: Element, img: HTMLImageElement, imgSrc: string) {\r\n if (!img || !imgSrc) return;\r\n img.setAttribute(this.attributeName, imgSrc);\r\n img.src = '';\r\n this.lazyImgObserver.observe(img);\r\n }\r\n\r\n delazify = (target: HTMLImageElement) => {\r\n this.lazyImgObserver.observer.unobserve(target);\r\n target.src = target.getAttribute(this.attributeName) as string;\r\n if (this.removeTagAfter) target.removeAttribute(this.attributeName);\r\n }\r\n\r\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\n static create(callback: any) {\r\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\n const lazyImgLoader = new LazyImgLoader((target: Element, delazify: any) => {\r\n if (callback(target)) {\r\n delazify(target);\r\n }\r\n });\r\n return lazyImgLoader;\r\n }\r\n}\r\n","export function circularShift(n: number, c = 6, s = 1): number {\r\n return (n + s) % c || c;\r\n}\r\n","export function parseDom(html: string): HTMLElement {\r\n const parsed = new DOMParser().parseFromString(html, 'text/html').body;\r\n return parsed.children.length > 1 ? parsed : parsed.firstElementChild as HTMLElement;\r\n}\r\n\r\nexport function copyAttributes(target: HTMLElement | Element, source: HTMLElement | Element) {\r\n for (const attr of source.attributes) {\r\n attr.nodeValue && target.setAttribute(attr.nodeName, attr.nodeValue);\r\n }\r\n}\r\n\r\nexport function replaceElementTag(e: HTMLElement | Element, tagName: string) {\r\n const newTagElement = document.createElement(tagName);\r\n copyAttributes(newTagElement, e);\r\n newTagElement.innerHTML = e.innerHTML;\r\n e.parentNode?.replaceChild(newTagElement, e);\r\n return newTagElement;\r\n}\r\n\r\nexport function getAllUniqueParents(elements: HTMLCollection): Array<HTMLElement | Element> {\r\n return Array.from(elements).reduce((acc, v) => {\r\n if (v.parentElement && !acc.includes(v.parentElement as HTMLElement)) { acc.push(v.parentElement); }\r\n return acc;\r\n }, [] as Array<HTMLElement | Element>);\r\n}\r\n\r\nexport function findNextSibling(el: HTMLElement | Element) {\r\n if (el.nextElementSibling) return el.nextElementSibling;\r\n if (el.parentElement) return findNextSibling(el.parentElement);\r\n return null;\r\n}\r\n\r\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\nexport function waitForElementExists(parent: HTMLElement | Element, selector: string, callback: any): void {\r\n const observer = new MutationObserver((_mutations) => {\r\n const el = parent.querySelector(selector);\r\n if (el) {\r\n observer.disconnect();\r\n callback(el);\r\n }\r\n });\r\n observer.observe(document.body, { childList: true, subtree: true });\r\n}\r\n\r\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\nexport function watchElementChildrenCount(element: HTMLElement | Element, callback: any): void {\r\n let count = element.children.length;\r\n const observer = new MutationObserver((mutationList, observer) => {\r\n for (const mutation of mutationList) {\r\n if (mutation.type === \"childList\") {\r\n if (count !== element.children.length) {\r\n count = element.children.length;\r\n callback(observer, count);\r\n }\r\n }\r\n }\r\n });\r\n observer.observe(element, { childList: true });\r\n}\r\n\r\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\nexport function watchDomChangesWithThrottle(element: HTMLElement | Element, callback: any,\r\n throttle = 1000, options: Record<string, boolean> = { childList: true, subtree: true, attributes: true }) {\r\n let lastMutationTime: number;\r\n let timeout: number;\r\n const observer = new MutationObserver((_mutationList, _observer) => {\r\n const now = Date.now();\r\n if (lastMutationTime && now - lastMutationTime < throttle) {\r\n timeout && clearTimeout(timeout);\r\n }\r\n timeout = setTimeout(callback, throttle);\r\n lastMutationTime = now;\r\n });\r\n observer.observe(element, options);\r\n}\r\n\r\nexport function downloader(options = { append: \"\", after: \"\", button: \"\", cbBefore: () => { } }) {\r\n const btn = parseDom(options.button);\r\n\r\n if (options.append) document.querySelector(options.append)?.append(btn);\r\n if (options.after) document.querySelector(options.after)?.after(btn);\r\n\r\n btn.addEventListener('click', (e) => {\r\n e.preventDefault();\r\n\r\n if (options.cbBefore) options.cbBefore();\r\n\r\n waitForElementExists(document.body, 'video', (video: HTMLVideoElement) => {\r\n window.location.href = video.getAttribute('src') as string;\r\n });\r\n });\r\n}","import { parseDom } from \"../dom\";\r\n\r\nexport const MOBILE_UA = [\r\n 'Mozilla/5.0 (Linux; Android 10; K)',\r\n 'AppleWebKit/537.36 (KHTML, like Gecko)',\r\n 'Chrome/114.0.0.0 Mobile Safari/537.36'].join(' ');\r\n\r\nexport function fetchWith(url: string, options: Record<string, boolean> = { html: false, mobile: false }) {\r\n const reqOpts = {};\r\n if (options.mobile) Object.assign(reqOpts, { headers: new Headers({ \"User-Agent\": MOBILE_UA }) });\r\n return fetch(url, reqOpts).then((r) => r.text()).then(r => options.html ? parseDom(r) : r);\r\n}\r\n\r\nexport const fetchHtml = (url: string) => fetchWith(url, { html: true });\r\n\r\nexport const fetchText = (url: string) => fetchWith(url);\r\n\r\nexport function objectToFormData(object: Record<string, number | boolean | string>): FormData {\r\n const formData = new FormData();\r\n Object.entries(object).forEach(([k, v]) => formData.append(k, v as string));\r\n return formData;\r\n}\r\n","// biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\nexport function listenEvents(dom: HTMLElement | Element, events: Array<string>, callback: any): void {\r\n for (const e of events) {\r\n dom.addEventListener(e, callback, true);\r\n }\r\n}\r\n\r\nexport class Tick {\r\n private tick: null | number;\r\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\n private callbackFinal: any;\r\n\r\n constructor(private delay: number, private startImmediate = true) {\r\n this.tick = null;\r\n this.delay = delay;\r\n this.startImmediate = startImmediate;\r\n }\r\n\r\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\n start(callback: any, callbackFinal = null) {\r\n this.stop();\r\n this.callbackFinal = callbackFinal;\r\n if (this.startImmediate) callback();\r\n this.tick = setInterval(callback, this.delay);\r\n }\r\n\r\n stop() {\r\n if (this.tick !== null) {\r\n clearInterval(this.tick);\r\n this.tick = null;\r\n }\r\n if (this.callbackFinal) {\r\n this.callbackFinal();\r\n this.callbackFinal = null;\r\n }\r\n }\r\n}","export function isMob() {\r\n return /iPhone|Android/i.test(navigator.userAgent);\r\n}","// https://2ality.com/2016/10/asynchronous-iteration.html\r\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\nexport async function computeAsyncOneAtTime(iterable: Iterable<any>) {\r\n const res = [];\r\n for await (const f of iterable) {\r\n res.push(await f());\r\n }\r\n return res;\r\n}\r\n\r\nexport function wait(milliseconds: number) {\r\n return new Promise(resolve => setTimeout(resolve, milliseconds));\r\n}\r\n\r\n// do async one at time\r\nexport class SyncPull {\r\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\n pull: Array<any> = [];\r\n lock = false;\r\n\r\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\n getHighPriorityFirst(p = 0): any {\r\n if (p > 3 || this.pull.length === 0) return undefined;\r\n const i = this.pull.findIndex(e => e.p === p);\r\n if (i >= 0) {\r\n const res = this.pull[i].v;\r\n this.pull = this.pull.slice(0, i).concat(this.pull.slice(i + 1));\r\n return res;\r\n }\r\n return this.getHighPriorityFirst(p + 1);\r\n }\r\n\r\n *pullGenerator() {\r\n while (this.pull.length > 0) {\r\n yield this.getHighPriorityFirst();\r\n }\r\n }\r\n\r\n async processPull() {\r\n if (!this.lock) {\r\n this.lock = true;\r\n for await (const f of this.pullGenerator()) {\r\n await f();\r\n }\r\n this.lock = false;\r\n }\r\n }\r\n\r\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\r\n push(x: any) {\r\n this.pull.push(x);\r\n this.processPull();\r\n }\r\n}\r\n","export function chunks<T>(arr: Array<T>, n: number): Array<Array<T>> {\r\n const res = [];\r\n for (let i = 0; i < arr.length; i += n) {\r\n res.push(arr.slice(i, i + n));\r\n }\r\n return res;\r\n}\r\n\r\nexport function range(size: number, startAt = 1): Array<number> {\r\n return [...Array(size).keys()].map(i => i + startAt);\r\n}"],"names":["s","target","observer"],"mappings":"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"}
1
+ {"version":3,"file":"billy-herrington-utils.umd.js","sources":["../src/utils/strings/index.ts","../src/utils/parsers/index.ts","../src/utils/observers/index.ts","../src/utils/math/index.ts","../src/utils/dom/index.ts","../src/utils/fetch/index.ts","../src/utils/events/index.ts","../src/utils/device/index.ts","../src/utils/async/index.ts","../src/utils/arrays/index.ts"],"sourcesContent":["export function stringToWords(s: string): Array<string> {\r\n return s.split(\",\").map(s => s.trim().toLowerCase()).filter(_ => _);\r\n}\r\n\r\nexport function sanitizeStr(s: string) {\r\n return s?.replace(/\\n|\\t/, ' ').replace(/ {2,}/, ' ').trim().toLowerCase() || \"\";\r\n}\r\n","export function timeToSeconds(t: string): number {\r\n return (t?.match(/\\d+/gm) || [0])\r\n .reverse()\r\n .map((s, i) => parseInt(s as string) * 60 ** i)\r\n .reduce((a, b) => a + b);\r\n}\r\n\r\nexport function parseIntegerOr(n: string | number, or: number): number {\r\n return Number.isInteger(parseInt(n as string)) ? parseInt(n as string) : or;\r\n}\r\n\r\n// \"data:02;body+head:async;void:;zero:;\"\r\nexport function parseDataParams(str: string) {\r\n const params = str.split(';').flatMap(s => {\r\n const parsed = s.match(/([\\+\\w+]+):(\\w+)?/);\r\n const value = parsed?.[2];\r\n if (value) return parsed[1].split('+').map(p => ({ [p]: value }));\r\n }).filter(_ => _);\r\n return Object.assign({}, ...params);\r\n}\r\n\r\nexport function parseCSSUrl(s: string) {\r\n return s.replace(/url\\(\"|\\\"\\).*/g, '');\r\n}","export class Observer {\r\n public observer: IntersectionObserver;\r\n constructor(private callback: (entry: Element) => void) {\r\n this.observer = new IntersectionObserver(this.handleIntersection.bind(this));\r\n }\r\n\r\n observe(target: Element) {\r\n this.observer.observe(target);\r\n }\r\n\r\n throttle(target: Element, throttleTime: number) {\r\n this.observer.unobserve(target);\r\n setTimeout(() => this.observer.observe(target), throttleTime);\r\n }\r\n\r\n handleIntersection(entries: Iterable<IntersectionObserverEntry>) {\r\n for (const entry of entries) {\r\n if (entry.isIntersecting) {\r\n this.callback(entry.target);\r\n }\r\n }\r\n }\r\n\r\n static observeWhile(target: Element, callback: () => Promise<boolean> | boolean, throttleTime: number) {\r\n const observer_ = new Observer(async (target: Element) => {\r\n const condition = await callback();\r\n if (condition) observer_.throttle(target, throttleTime);\r\n });\r\n observer_.observe(target);\r\n return observer_;\r\n }\r\n}\r\n\r\nexport class LazyImgLoader {\r\n public lazyImgObserver: Observer;\r\n private attributeName = 'data-lazy-load';\r\n\r\n constructor(shouldDelazify: (target: Element) => boolean) {\r\n this.lazyImgObserver = new Observer((target: Element) => {\r\n if (shouldDelazify(target)) {\r\n this.delazify(target as HTMLImageElement);\r\n }\r\n });\r\n }\r\n\r\n lazify(_target: Element, img: HTMLImageElement, imgSrc: string) {\r\n if (!img || !imgSrc) return;\r\n img.setAttribute(this.attributeName, imgSrc);\r\n img.src = '';\r\n this.lazyImgObserver.observe(img);\r\n }\r\n\r\n delazify = (target: HTMLImageElement) => {\r\n this.lazyImgObserver.observer.unobserve(target);\r\n target.src = target.getAttribute(this.attributeName) as string;\r\n target.removeAttribute(this.attributeName);\r\n }\r\n}\r\n","export function circularShift(n: number, c = 6, s = 1): number {\r\n return (n + s) % c || c;\r\n}\r\n","export function parseDom(html: string): HTMLElement {\r\n const parsed = new DOMParser().parseFromString(html, 'text/html').body;\r\n return parsed.children.length > 1 ? parsed : parsed.firstElementChild as HTMLElement;\r\n}\r\n\r\nexport function copyAttributes(target: HTMLElement | Element, source: HTMLElement | Element) {\r\n for (const attr of source.attributes) {\r\n attr.nodeValue && target.setAttribute(attr.nodeName, attr.nodeValue);\r\n }\r\n}\r\n\r\nexport function replaceElementTag(e: HTMLElement | Element, tagName: string) {\r\n const newTagElement = document.createElement(tagName);\r\n copyAttributes(newTagElement, e);\r\n newTagElement.innerHTML = e.innerHTML;\r\n e.parentNode?.replaceChild(newTagElement, e);\r\n return newTagElement;\r\n}\r\n\r\nexport function getAllUniqueParents(elements: HTMLCollection): Array<HTMLElement | Element> {\r\n return Array.from(elements).reduce((acc, v) => {\r\n if (v.parentElement && !acc.includes(v.parentElement as HTMLElement)) { acc.push(v.parentElement); }\r\n return acc;\r\n }, [] as Array<HTMLElement | Element>);\r\n}\r\n\r\nexport function findNextSibling(el: HTMLElement | Element) {\r\n if (el.nextElementSibling) return el.nextElementSibling;\r\n if (el.parentElement) return findNextSibling(el.parentElement);\r\n return null;\r\n}\r\n\r\nexport function waitForElementExists(parent: HTMLElement | Element, selector: string, callback: (el: Element) => void): void {\r\n const observer = new MutationObserver((_mutations) => {\r\n const el = parent.querySelector(selector);\r\n if (el) {\r\n observer.disconnect();\r\n callback(el);\r\n }\r\n });\r\n observer.observe(document.body, { childList: true, subtree: true });\r\n}\r\n\r\nexport function watchElementChildrenCount(element: HTMLElement | Element,\r\n callback: (observer: MutationObserver, count: number) => void): void {\r\n let count = element.children.length;\r\n const observer = new MutationObserver((mutationList, observer) => {\r\n for (const mutation of mutationList) {\r\n if (mutation.type === \"childList\") {\r\n if (count !== element.children.length) {\r\n count = element.children.length;\r\n callback(observer, count);\r\n }\r\n }\r\n }\r\n });\r\n observer.observe(element, { childList: true });\r\n}\r\n\r\nexport function watchDomChangesWithThrottle(element: HTMLElement | Element, callback: () => void,\r\n throttle = 1000, options: Record<string, boolean> = { childList: true, subtree: true, attributes: true }) {\r\n let lastMutationTime: number;\r\n let timeout: number;\r\n const observer = new MutationObserver((_mutationList, _observer) => {\r\n const now = Date.now();\r\n if (lastMutationTime && now - lastMutationTime < throttle) {\r\n timeout && clearTimeout(timeout);\r\n }\r\n timeout = setTimeout(callback, throttle);\r\n lastMutationTime = now;\r\n });\r\n observer.observe(element, options);\r\n}\r\n\r\nexport function downloader(options = { append: \"\", after: \"\", button: \"\", cbBefore: () => { } }) {\r\n const btn = parseDom(options.button);\r\n\r\n if (options.append) document.querySelector(options.append)?.append(btn);\r\n if (options.after) document.querySelector(options.after)?.after(btn);\r\n\r\n btn.addEventListener('click', (e) => {\r\n e.preventDefault();\r\n\r\n if (options.cbBefore) options.cbBefore();\r\n\r\n waitForElementExists(document.body, 'video', (video: Element) => {\r\n window.location.href = video.getAttribute('src') as string;\r\n });\r\n });\r\n}","import { parseDom } from \"../dom\";\r\n\r\nexport const MOBILE_UA = [\r\n 'Mozilla/5.0 (Linux; Android 10; K)',\r\n 'AppleWebKit/537.36 (KHTML, like Gecko)',\r\n 'Chrome/114.0.0.0 Mobile Safari/537.36'].join(' ');\r\n\r\nexport function fetchWith(url: string, options: Record<string, boolean> = { html: false, mobile: false }) {\r\n const reqOpts = {};\r\n if (options.mobile) Object.assign(reqOpts, { headers: new Headers({ \"User-Agent\": MOBILE_UA }) });\r\n return fetch(url, reqOpts).then((r) => r.text()).then(r => options.html ? parseDom(r) : r);\r\n}\r\n\r\nexport const fetchHtml = (url: string) => fetchWith(url, { html: true });\r\n\r\nexport const fetchText = (url: string) => fetchWith(url);\r\n\r\nexport function objectToFormData(object: Record<string, number | boolean | string>): FormData {\r\n const formData = new FormData();\r\n Object.entries(object).forEach(([k, v]) => formData.append(k, v as string));\r\n return formData;\r\n}\r\n","export function listenEvents(dom: HTMLElement | Element, events: Array<string>, callback: (e: Event) => void): void {\r\n for (const e of events) {\r\n dom.addEventListener(e, callback, true);\r\n }\r\n}\r\n\r\nexport class Tick {\r\n private tick: null | number;\r\n private callbackFinal: (() => void) | undefined;\r\n\r\n constructor(private delay: number, private startImmediate = true) {\r\n this.tick = null;\r\n this.delay = delay;\r\n this.startImmediate = startImmediate;\r\n }\r\n\r\n start(callback: () => void, callbackFinal = undefined) {\r\n this.stop();\r\n this.callbackFinal = callbackFinal;\r\n if (this.startImmediate) callback();\r\n this.tick = setInterval(callback, this.delay);\r\n }\r\n\r\n stop() {\r\n if (this.tick !== null) {\r\n clearInterval(this.tick);\r\n this.tick = null;\r\n }\r\n if (this.callbackFinal) {\r\n this.callbackFinal();\r\n this.callbackFinal = undefined;\r\n }\r\n }\r\n}","export function isMob() {\r\n return /iPhone|Android/i.test(navigator.userAgent);\r\n}","// https://2ality.com/2016/10/asynchronous-iteration.html\r\nexport async function computeAsyncOneAtTime(iterable: Iterable<() => Promise<void>>) {\r\n const res = [];\r\n for await (const f of iterable) {\r\n res.push(await f());\r\n }\r\n return res;\r\n}\r\n\r\nexport function wait(milliseconds: number) {\r\n return new Promise(resolve => setTimeout(resolve, milliseconds));\r\n}\r\n\r\ninterface SyncPoolObject {\r\n v: () => Promise<void>,\r\n p: number\r\n}\r\n\r\nexport class AsyncPool {\r\n cur = 0;\r\n private finished: Promise<boolean>;\r\n private _resolve?: (value: boolean | PromiseLike<boolean>) => void;\r\n\r\n constructor(private max = 1, private pool: Array<SyncPoolObject> = []) {\r\n this.finished = new Promise((resolve) => {\r\n this._resolve = resolve;\r\n });\r\n }\r\n\r\n getHighPriorityFirst(p = 0): (() => Promise<void>) | undefined {\r\n if (p > 3 || this.pool.length === 0) return undefined;\r\n const i = this.pool.findIndex(e => e.p === p);\r\n if (i >= 0) {\r\n const res = this.pool[i].v;\r\n this.pool = this.pool.slice(0, i).concat(this.pool.slice(i + 1));\r\n return res;\r\n }\r\n return this.getHighPriorityFirst(p + 1);\r\n }\r\n\r\n async runTask() {\r\n this.cur++;\r\n const f = this.getHighPriorityFirst();\r\n await f?.();\r\n this.cur--;\r\n this.runTasks();\r\n }\r\n\r\n runTasks() {\r\n if (!this.pool.length) this._resolve?.(true);\r\n if (this.cur < this.max) {\r\n this.runTask();\r\n this.runTasks();\r\n }\r\n }\r\n\r\n async run() {\r\n this.runTasks();\r\n return this.finished;\r\n }\r\n\r\n push(x: SyncPoolObject | (() => Promise<void>)) {\r\n this.pool.push('p' in x ? x : ({ v: x, p: 0 }));\r\n }\r\n}","export function chunks<T>(arr: Array<T>, n: number): Array<Array<T>> {\r\n const res = [];\r\n for (let i = 0; i < arr.length; i += n) {\r\n res.push(arr.slice(i, i + n));\r\n }\r\n return res;\r\n}\r\n\r\nexport function range(size: number, startAt = 1): Array<number> {\r\n return [...Array(size).keys()].map(i => i + startAt);\r\n}"],"names":["s","target","observer"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,22 @@
1
+ export declare class AsyncPool {
2
+ private max;
3
+ private pool;
4
+ cur: number;
5
+ private finished;
6
+ private _resolve?;
7
+ constructor(max?: number, pool?: Array<SyncPoolObject>);
8
+ getHighPriorityFirst(p?: number): (() => Promise<void>) | undefined;
9
+ runTask(): Promise<void>;
10
+ runTasks(): void;
11
+ run(): Promise<boolean>;
12
+ push(x: SyncPoolObject | (() => Promise<void>)): void;
13
+ }
14
+
1
15
  export declare function chunks<T>(arr: Array<T>, n: number): Array<Array<T>>;
2
16
 
3
17
  export declare function circularShift(n: number, c?: number, s?: number): number;
4
18
 
5
- export declare function computeAsyncOneAtTime(iterable: Iterable<any>): Promise<any[]>;
19
+ export declare function computeAsyncOneAtTime(iterable: Iterable<() => Promise<void>>): Promise<void[]>;
6
20
 
7
21
  export declare function copyAttributes(target: HTMLElement | Element, source: HTMLElement | Element): void;
8
22
 
@@ -26,16 +40,14 @@ export declare function getAllUniqueParents(elements: HTMLCollection): Array<HTM
26
40
  export declare function isMob(): boolean;
27
41
 
28
42
  export declare class LazyImgLoader {
29
- private attributeName;
30
- private removeTagAfter;
31
43
  lazyImgObserver: Observer;
32
- constructor(callback: any, attributeName?: string, removeTagAfter?: boolean);
44
+ private attributeName;
45
+ constructor(shouldDelazify: (target: Element) => boolean);
33
46
  lazify(_target: Element, img: HTMLImageElement, imgSrc: string): void;
34
47
  delazify: (target: HTMLImageElement) => void;
35
- static create(callback: any): LazyImgLoader;
36
48
  }
37
49
 
38
- export declare function listenEvents(dom: HTMLElement | Element, events: Array<string>, callback: any): void;
50
+ export declare function listenEvents(dom: HTMLElement | Element, events: Array<string>, callback: (e: Event) => void): void;
39
51
 
40
52
  export declare const MOBILE_UA: string;
41
53
 
@@ -48,7 +60,7 @@ export declare class Observer {
48
60
  observe(target: Element): void;
49
61
  throttle(target: Element, throttleTime: number): void;
50
62
  handleIntersection(entries: Iterable<IntersectionObserverEntry>): void;
51
- static observeWhile(target: Element, callback: any, throttleTime: number): Observer;
63
+ static observeWhile(target: Element, callback: () => Promise<boolean> | boolean, throttleTime: number): Observer;
52
64
  }
53
65
 
54
66
  export declare function parseCSSUrl(s: string): string;
@@ -67,13 +79,9 @@ export declare function sanitizeStr(s: string): string;
67
79
 
68
80
  export declare function stringToWords(s: string): Array<string>;
69
81
 
70
- export declare class SyncPull {
71
- pull: Array<any>;
72
- lock: boolean;
73
- getHighPriorityFirst(p?: number): any;
74
- pullGenerator(): Generator<any, void, unknown>;
75
- processPull(): Promise<void>;
76
- push(x: any): void;
82
+ declare interface SyncPoolObject {
83
+ v: () => Promise<void>;
84
+ p: number;
77
85
  }
78
86
 
79
87
  export declare class Tick {
@@ -82,7 +90,7 @@ export declare class Tick {
82
90
  private tick;
83
91
  private callbackFinal;
84
92
  constructor(delay: number, startImmediate?: boolean);
85
- start(callback: any, callbackFinal?: null): void;
93
+ start(callback: () => void, callbackFinal?: undefined): void;
86
94
  stop(): void;
87
95
  }
88
96
 
@@ -90,10 +98,10 @@ export declare function timeToSeconds(t: string): number;
90
98
 
91
99
  export declare function wait(milliseconds: number): Promise<unknown>;
92
100
 
93
- export declare function waitForElementExists(parent: HTMLElement | Element, selector: string, callback: any): void;
101
+ export declare function waitForElementExists(parent: HTMLElement | Element, selector: string, callback: (el: Element) => void): void;
94
102
 
95
- export declare function watchDomChangesWithThrottle(element: HTMLElement | Element, callback: any, throttle?: number, options?: Record<string, boolean>): void;
103
+ export declare function watchDomChangesWithThrottle(element: HTMLElement | Element, callback: () => void, throttle?: number, options?: Record<string, boolean>): void;
96
104
 
97
- export declare function watchElementChildrenCount(element: HTMLElement | Element, callback: any): void;
105
+ export declare function watchElementChildrenCount(element: HTMLElement | Element, callback: (observer: MutationObserver, count: number) => void): void;
98
106
 
99
107
  export { }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "billy-herrington-utils",
3
3
  "description": "daddy told us not to be ashamed of our utils",
4
- "version": "1.1.3",
4
+ "version": "1.1.5",
5
5
  "license": "MIT",
6
6
  "keywords": ["utils", "observer", "dom", "fetch", "arrays", "typescript"],
7
7
  "author": "smartacephale atm.mormon@protonmail.com (https://github.com/smartacephale)",
package/src/index.ts CHANGED
@@ -16,5 +16,5 @@ export {
16
16
  watchElementChildrenCount
17
17
  } from "./utils/dom";
18
18
  export { isMob } from "./utils/device";
19
- export { computeAsyncOneAtTime, SyncPull, wait } from "./utils/async";
19
+ export { computeAsyncOneAtTime, AsyncPool, wait } from "./utils/async";
20
20
  export { chunks, range } from "./utils/arrays";
@@ -1,6 +1,5 @@
1
1
  // https://2ality.com/2016/10/asynchronous-iteration.html
2
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
3
- export async function computeAsyncOneAtTime(iterable: Iterable<any>) {
2
+ export async function computeAsyncOneAtTime(iterable: Iterable<() => Promise<void>>) {
4
3
  const res = [];
5
4
  for await (const f of iterable) {
6
5
  res.push(await f());
@@ -9,46 +8,61 @@ export async function computeAsyncOneAtTime(iterable: Iterable<any>) {
9
8
  }
10
9
 
11
10
  export function wait(milliseconds: number) {
12
- return new Promise(resolve => setTimeout(resolve, milliseconds));
11
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
13
12
  }
14
13
 
15
- // do async one at time
16
- export class SyncPull {
17
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
18
- pull: Array<any> = [];
19
- lock = false;
14
+ interface SyncPoolObject {
15
+ v: () => Promise<void>;
16
+ p: number;
17
+ }
18
+
19
+ export class AsyncPool {
20
+ cur = 0;
21
+ private finished: Promise<boolean>;
22
+ private _resolve?: (value: boolean | PromiseLike<boolean>) => void;
23
+
24
+ constructor(
25
+ private max = 1,
26
+ private pool: Array<SyncPoolObject> = [],
27
+ ) {
28
+ this.finished = new Promise((resolve) => {
29
+ this._resolve = resolve;
30
+ });
31
+ }
20
32
 
21
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
22
- getHighPriorityFirst(p = 0): any {
23
- if (p > 3 || this.pull.length === 0) return undefined;
24
- const i = this.pull.findIndex(e => e.p === p);
33
+ getHighPriorityFirst(p = 0): (() => Promise<void>) | undefined {
34
+ if (p > 3 || this.pool.length === 0) return undefined;
35
+ const i = this.pool.findIndex((e) => e.p === p);
25
36
  if (i >= 0) {
26
- const res = this.pull[i].v;
27
- this.pull = this.pull.slice(0, i).concat(this.pull.slice(i + 1));
37
+ const res = this.pool[i].v;
38
+ this.pool = this.pool.slice(0, i).concat(this.pool.slice(i + 1));
28
39
  return res;
29
40
  }
30
41
  return this.getHighPriorityFirst(p + 1);
31
42
  }
32
43
 
33
- *pullGenerator() {
34
- while (this.pull.length > 0) {
35
- yield this.getHighPriorityFirst();
36
- }
44
+ async runTask() {
45
+ this.cur++;
46
+ const f = this.getHighPriorityFirst();
47
+ await f?.();
48
+ this.cur--;
49
+ this.runTasks();
37
50
  }
38
51
 
39
- async processPull() {
40
- if (!this.lock) {
41
- this.lock = true;
42
- for await (const f of this.pullGenerator()) {
43
- await f();
44
- }
45
- this.lock = false;
52
+ runTasks() {
53
+ if (!this.pool.length) this._resolve?.(true);
54
+ if (this.cur < this.max) {
55
+ this.runTask();
56
+ this.runTasks();
46
57
  }
47
58
  }
48
59
 
49
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
50
- push(x: any) {
51
- this.pull.push(x);
52
- this.processPull();
60
+ async run() {
61
+ this.runTasks();
62
+ return this.finished;
63
+ }
64
+
65
+ push(x: SyncPoolObject | (() => Promise<void>)) {
66
+ this.pool.push('p' in x ? x : { v: x, p: 0 });
53
67
  }
54
68
  }
@@ -30,8 +30,7 @@ export function findNextSibling(el: HTMLElement | Element) {
30
30
  return null;
31
31
  }
32
32
 
33
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
34
- export function waitForElementExists(parent: HTMLElement | Element, selector: string, callback: any): void {
33
+ export function waitForElementExists(parent: HTMLElement | Element, selector: string, callback: (el: Element) => void): void {
35
34
  const observer = new MutationObserver((_mutations) => {
36
35
  const el = parent.querySelector(selector);
37
36
  if (el) {
@@ -42,8 +41,8 @@ export function waitForElementExists(parent: HTMLElement | Element, selector: st
42
41
  observer.observe(document.body, { childList: true, subtree: true });
43
42
  }
44
43
 
45
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
46
- export function watchElementChildrenCount(element: HTMLElement | Element, callback: any): void {
44
+ export function watchElementChildrenCount(element: HTMLElement | Element,
45
+ callback: (observer: MutationObserver, count: number) => void): void {
47
46
  let count = element.children.length;
48
47
  const observer = new MutationObserver((mutationList, observer) => {
49
48
  for (const mutation of mutationList) {
@@ -58,8 +57,7 @@ export function watchElementChildrenCount(element: HTMLElement | Element, callba
58
57
  observer.observe(element, { childList: true });
59
58
  }
60
59
 
61
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
62
- export function watchDomChangesWithThrottle(element: HTMLElement | Element, callback: any,
60
+ export function watchDomChangesWithThrottle(element: HTMLElement | Element, callback: () => void,
63
61
  throttle = 1000, options: Record<string, boolean> = { childList: true, subtree: true, attributes: true }) {
64
62
  let lastMutationTime: number;
65
63
  let timeout: number;
@@ -85,7 +83,7 @@ export function downloader(options = { append: "", after: "", button: "", cbBefo
85
83
 
86
84
  if (options.cbBefore) options.cbBefore();
87
85
 
88
- waitForElementExists(document.body, 'video', (video: HTMLVideoElement) => {
86
+ waitForElementExists(document.body, 'video', (video: Element) => {
89
87
  window.location.href = video.getAttribute('src') as string;
90
88
  });
91
89
  });
@@ -1,5 +1,4 @@
1
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
2
- export function listenEvents(dom: HTMLElement | Element, events: Array<string>, callback: any): void {
1
+ export function listenEvents(dom: HTMLElement | Element, events: Array<string>, callback: (e: Event) => void): void {
3
2
  for (const e of events) {
4
3
  dom.addEventListener(e, callback, true);
5
4
  }
@@ -7,8 +6,7 @@ export function listenEvents(dom: HTMLElement | Element, events: Array<string>,
7
6
 
8
7
  export class Tick {
9
8
  private tick: null | number;
10
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
11
- private callbackFinal: any;
9
+ private callbackFinal: (() => void) | undefined;
12
10
 
13
11
  constructor(private delay: number, private startImmediate = true) {
14
12
  this.tick = null;
@@ -16,8 +14,7 @@ export class Tick {
16
14
  this.startImmediate = startImmediate;
17
15
  }
18
16
 
19
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
20
- start(callback: any, callbackFinal = null) {
17
+ start(callback: () => void, callbackFinal = undefined) {
21
18
  this.stop();
22
19
  this.callbackFinal = callbackFinal;
23
20
  if (this.startImmediate) callback();
@@ -31,7 +28,7 @@ export class Tick {
31
28
  }
32
29
  if (this.callbackFinal) {
33
30
  this.callbackFinal();
34
- this.callbackFinal = null;
31
+ this.callbackFinal = undefined;
35
32
  }
36
33
  }
37
34
  }
@@ -21,8 +21,7 @@ export class Observer {
21
21
  }
22
22
  }
23
23
 
24
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
25
- static observeWhile(target: Element, callback: any, throttleTime: number) {
24
+ static observeWhile(target: Element, callback: () => Promise<boolean> | boolean, throttleTime: number) {
26
25
  const observer_ = new Observer(async (target: Element) => {
27
26
  const condition = await callback();
28
27
  if (condition) observer_.throttle(target, throttleTime);
@@ -34,10 +33,13 @@ export class Observer {
34
33
 
35
34
  export class LazyImgLoader {
36
35
  public lazyImgObserver: Observer;
37
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
38
- constructor(callback: any, private attributeName = 'data-lazy-load', private removeTagAfter = true) {
36
+ private attributeName = 'data-lazy-load';
37
+
38
+ constructor(shouldDelazify: (target: Element) => boolean) {
39
39
  this.lazyImgObserver = new Observer((target: Element) => {
40
- callback(target, this.delazify);
40
+ if (shouldDelazify(target)) {
41
+ this.delazify(target as HTMLImageElement);
42
+ }
41
43
  });
42
44
  }
43
45
 
@@ -51,17 +53,6 @@ export class LazyImgLoader {
51
53
  delazify = (target: HTMLImageElement) => {
52
54
  this.lazyImgObserver.observer.unobserve(target);
53
55
  target.src = target.getAttribute(this.attributeName) as string;
54
- if (this.removeTagAfter) target.removeAttribute(this.attributeName);
55
- }
56
-
57
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
58
- static create(callback: any) {
59
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
60
- const lazyImgLoader = new LazyImgLoader((target: Element, delazify: any) => {
61
- if (callback(target)) {
62
- delazify(target);
63
- }
64
- });
65
- return lazyImgLoader;
56
+ target.removeAttribute(this.attributeName);
66
57
  }
67
58
  }