billy-herrington-utils 1.1.4 → 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);
@@ -88,11 +88,10 @@ function copyAttributes(target, source) {
88
88
  }
89
89
  }
90
90
  function replaceElementTag(e, tagName) {
91
- var _a;
92
91
  const newTagElement = document.createElement(tagName);
93
92
  copyAttributes(newTagElement, e);
94
93
  newTagElement.innerHTML = e.innerHTML;
95
- (_a = e.parentNode) == null ? void 0 : _a.replaceChild(newTagElement, e);
94
+ e.parentNode?.replaceChild(newTagElement, e);
96
95
  return newTagElement;
97
96
  }
98
97
  function getAllUniqueParents(elements) {
@@ -147,10 +146,9 @@ function watchDomChangesWithThrottle(element, callback, throttle = 1e3, options
147
146
  }
148
147
  function downloader(options = { append: "", after: "", button: "", cbBefore: () => {
149
148
  } }) {
150
- var _a, _b;
151
149
  const btn = parseDom(options.button);
152
- if (options.append) (_a = document.querySelector(options.append)) == null ? void 0 : _a.append(btn);
153
- 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);
154
152
  btn.addEventListener("click", (e) => {
155
153
  e.preventDefault();
156
154
  if (options.cbBefore) options.cbBefore();
@@ -221,38 +219,47 @@ async function computeAsyncOneAtTime(iterable) {
221
219
  function wait(milliseconds) {
222
220
  return new Promise((resolve) => setTimeout(resolve, milliseconds));
223
221
  }
224
- class SyncPull {
225
- constructor() {
226
- __publicField(this, "pull", []);
227
- __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
+ });
228
232
  }
229
233
  getHighPriorityFirst(p = 0) {
230
- if (p > 3 || this.pull.length === 0) return void 0;
231
- 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);
232
236
  if (i >= 0) {
233
- const res = this.pull[i].v;
234
- 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));
235
239
  return res;
236
240
  }
237
241
  return this.getHighPriorityFirst(p + 1);
238
242
  }
239
- *pullGenerator() {
240
- while (this.pull.length > 0) {
241
- yield this.getHighPriorityFirst();
242
- }
243
+ async runTask() {
244
+ this.cur++;
245
+ const f = this.getHighPriorityFirst();
246
+ await f?.();
247
+ this.cur--;
248
+ this.runTasks();
243
249
  }
244
- async processPull() {
245
- if (!this.lock) {
246
- this.lock = true;
247
- for await (const f of this.pullGenerator()) {
248
- await (f == null ? void 0 : f());
249
- }
250
- 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();
251
255
  }
252
256
  }
257
+ async run() {
258
+ this.runTasks();
259
+ return this.finished;
260
+ }
253
261
  push(x) {
254
- this.pull.push(x);
255
- this.processPull();
262
+ this.pool.push("p" in x ? x : { v: x, p: 0 });
256
263
  }
257
264
  }
258
265
  function chunks(arr, n) {
@@ -266,10 +273,10 @@ function range(size, startAt = 1) {
266
273
  return [...Array(size).keys()].map((i) => i + startAt);
267
274
  }
268
275
  export {
276
+ AsyncPool,
269
277
  LazyImgLoader,
270
278
  MOBILE_UA,
271
279
  Observer,
272
- SyncPull,
273
280
  Tick,
274
281
  chunks,
275
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 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 SyncPullObject {\r\n v: () => Promise<void>,\r\n p: number\r\n}\r\n\r\nexport class SyncPull {\r\n pull: Array<SyncPullObject> = [];\r\n lock = false;\r\n\r\n getHighPriorityFirst(p = 0): (() => Promise<void>) | undefined {\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 push(x: SyncPullObject) {\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.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":"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"}
@@ -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);
@@ -92,11 +92,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
92
92
  }
93
93
  }
94
94
  function replaceElementTag(e, tagName) {
95
- var _a;
96
95
  const newTagElement = document.createElement(tagName);
97
96
  copyAttributes(newTagElement, e);
98
97
  newTagElement.innerHTML = e.innerHTML;
99
- (_a = e.parentNode) == null ? void 0 : _a.replaceChild(newTagElement, e);
98
+ e.parentNode?.replaceChild(newTagElement, e);
100
99
  return newTagElement;
101
100
  }
102
101
  function getAllUniqueParents(elements) {
@@ -151,10 +150,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
151
150
  }
152
151
  function downloader(options = { append: "", after: "", button: "", cbBefore: () => {
153
152
  } }) {
154
- var _a, _b;
155
153
  const btn = parseDom(options.button);
156
- if (options.append) (_a = document.querySelector(options.append)) == null ? void 0 : _a.append(btn);
157
- 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);
158
156
  btn.addEventListener("click", (e) => {
159
157
  e.preventDefault();
160
158
  if (options.cbBefore) options.cbBefore();
@@ -225,38 +223,47 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
225
223
  function wait(milliseconds) {
226
224
  return new Promise((resolve) => setTimeout(resolve, milliseconds));
227
225
  }
228
- class SyncPull {
229
- constructor() {
230
- __publicField(this, "pull", []);
231
- __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
+ });
232
236
  }
233
237
  getHighPriorityFirst(p = 0) {
234
- if (p > 3 || this.pull.length === 0) return void 0;
235
- 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);
236
240
  if (i >= 0) {
237
- const res = this.pull[i].v;
238
- 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));
239
243
  return res;
240
244
  }
241
245
  return this.getHighPriorityFirst(p + 1);
242
246
  }
243
- *pullGenerator() {
244
- while (this.pull.length > 0) {
245
- yield this.getHighPriorityFirst();
246
- }
247
+ async runTask() {
248
+ this.cur++;
249
+ const f = this.getHighPriorityFirst();
250
+ await f?.();
251
+ this.cur--;
252
+ this.runTasks();
247
253
  }
248
- async processPull() {
249
- if (!this.lock) {
250
- this.lock = true;
251
- for await (const f of this.pullGenerator()) {
252
- await (f == null ? void 0 : f());
253
- }
254
- 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();
255
259
  }
256
260
  }
261
+ async run() {
262
+ this.runTasks();
263
+ return this.finished;
264
+ }
257
265
  push(x) {
258
- this.pull.push(x);
259
- this.processPull();
266
+ this.pool.push("p" in x ? x : { v: x, p: 0 });
260
267
  }
261
268
  }
262
269
  function chunks(arr, n) {
@@ -269,10 +276,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
269
276
  function range(size, startAt = 1) {
270
277
  return [...Array(size).keys()].map((i) => i + startAt);
271
278
  }
279
+ exports2.AsyncPool = AsyncPool;
272
280
  exports2.LazyImgLoader = LazyImgLoader;
273
281
  exports2.MOBILE_UA = MOBILE_UA;
274
282
  exports2.Observer = Observer;
275
- exports2.SyncPull = SyncPull;
276
283
  exports2.Tick = Tick;
277
284
  exports2.chunks = chunks;
278
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 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 SyncPullObject {\r\n v: () => Promise<void>,\r\n p: number\r\n}\r\n\r\nexport class SyncPull {\r\n pull: Array<SyncPullObject> = [];\r\n lock = false;\r\n\r\n getHighPriorityFirst(p = 0): (() => Promise<void>) | undefined {\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 push(x: SyncPullObject) {\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,WAAS,cAAc,GAA0B;AACtD,WAAO,EAAE,MAAM,GAAG,EAAE,IAAI,CAAAA,OAAKA,GAAE,OAAO,YAAY,CAAC,EAAE,OAAO,OAAK,CAAC;AAAA,EACpE;AAEO,WAAS,YAAY,GAAW;AACrC,YAAO,uBAAG,QAAQ,SAAS,KAAK,QAAQ,SAAS,KAAK,OAAO,kBAAiB;AAAA,EAChF;ACNO,WAAS,cAAc,GAAmB;AACvC,aAAA,uBAAG,MAAM,aAAY,CAAC,CAAC,GAC5B,QACA,EAAA,IAAI,CAAC,GAAG,MAAM,SAAS,CAAW,IAAI,MAAM,CAAC,EAC7C,OAAO,CAAC,GAAG,MAAM,IAAI,CAAC;AAAA,EAC3B;AAEgB,WAAA,eAAe,GAAoB,IAAoB;AAC9D,WAAA,OAAO,UAAU,SAAS,CAAW,CAAC,IAAI,SAAS,CAAW,IAAI;AAAA,EAC3E;AAGO,WAAS,gBAAgB,KAAa;AAC3C,UAAM,SAAS,IAAI,MAAM,GAAG,EAAE,QAAQ,CAAK,MAAA;AACnC,YAAA,SAAS,EAAE,MAAM,mBAAmB;AACpC,YAAA,QAAQ,iCAAS;AACvB,UAAI,MAAO,QAAO,OAAO,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,QAAM,EAAE,CAAC,CAAC,GAAG,QAAQ;AAAA,IACjE,CAAA,EAAE,OAAO,CAAA,MAAK,CAAC;AAChB,WAAO,OAAO,OAAO,IAAI,GAAG,MAAM;AAAA,EACpC;AAEO,WAAS,YAAY,GAAW;AAC9B,WAAA,EAAE,QAAQ,kBAAkB,EAAE;AAAA,EACvC;AAAA,ECvBO,MAAM,SAAS;AAAA,IAEpB,YAAoB,UAAoC;AADjD;AACa,WAAA,WAAA;AAClB,WAAK,WAAW,IAAI,qBAAqB,KAAK,mBAAmB,KAAK,IAAI,CAAC;AAAA,IAC7E;AAAA,IAEA,QAAQ,QAAiB;AAClB,WAAA,SAAS,QAAQ,MAAM;AAAA,IAC9B;AAAA,IAEA,SAAS,QAAiB,cAAsB;AACzC,WAAA,SAAS,UAAU,MAAM;AAC9B,iBAAW,MAAM,KAAK,SAAS,QAAQ,MAAM,GAAG,YAAY;AAAA,IAC9D;AAAA,IAEA,mBAAmB,SAA8C;AAC/D,iBAAW,SAAS,SAAS;AAC3B,YAAI,MAAM,gBAAgB;AACnB,eAAA,SAAS,MAAM,MAAM;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAAA,IAEA,OAAO,aAAa,QAAiB,UAA4C,cAAsB;AACrG,YAAM,YAAY,IAAI,SAAS,OAAOC,YAAoB;AAClD,cAAA,YAAY,MAAM;AACxB,YAAI,UAAW,WAAU,SAASA,SAAQ,YAAY;AAAA,MAAA,CACvD;AACD,gBAAU,QAAQ,MAAM;AACjB,aAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEO,MAAM,cAAc;AAAA,IAIzB,YAAY,gBAA8C;AAHnD;AACC,2CAAgB;AAiBxB,sCAAW,CAAC,WAA6B;AAClC,aAAA,gBAAgB,SAAS,UAAU,MAAM;AAC9C,eAAO,MAAM,OAAO,aAAa,KAAK,aAAa;AAC5C,eAAA,gBAAgB,KAAK,aAAa;AAAA,MAAA;AAjBzC,WAAK,kBAAkB,IAAI,SAAS,CAAC,WAAoB;AACnD,YAAA,eAAe,MAAM,GAAG;AAC1B,eAAK,SAAS,MAA0B;AAAA,QAC1C;AAAA,MAAA,CACD;AAAA,IACH;AAAA,IAEA,OAAO,SAAkB,KAAuB,QAAgB;AAC1D,UAAA,CAAC,OAAO,CAAC,OAAQ;AACjB,UAAA,aAAa,KAAK,eAAe,MAAM;AAC3C,UAAI,MAAM;AACL,WAAA,gBAAgB,QAAQ,GAAG;AAAA,IAClC;AAAA,EAOF;ACzDO,WAAS,cAAc,GAAW,IAAI,GAAG,IAAI,GAAW;AACrD,YAAA,IAAI,KAAK,KAAK;AAAA,EACxB;ACFO,WAAS,SAAS,MAA2B;AAClD,UAAM,SAAS,IAAI,YAAY,gBAAgB,MAAM,WAAW,EAAE;AAClE,WAAO,OAAO,SAAS,SAAS,IAAI,SAAS,OAAO;AAAA,EACtD;AAEgB,WAAA,eAAe,QAA+B,QAA+B;AAChF,eAAA,QAAQ,OAAO,YAAY;AACpC,WAAK,aAAa,OAAO,aAAa,KAAK,UAAU,KAAK,SAAS;AAAA,IACrE;AAAA,EACF;AAEgB,WAAA,kBAAkB,GAA0B,SAAiB;;AACrE,UAAA,gBAAgB,SAAS,cAAc,OAAO;AACpD,mBAAe,eAAe,CAAC;AAC/B,kBAAc,YAAY,EAAE;AAC1B,YAAA,eAAA,mBAAY,aAAa,eAAe;AACnC,WAAA;AAAA,EACT;AAEO,WAAS,oBAAoB,UAAwD;AAC1F,WAAO,MAAM,KAAK,QAAQ,EAAE,OAAO,CAAC,KAAK,MAAM;AAC7C,UAAI,EAAE,iBAAiB,CAAC,IAAI,SAAS,EAAE,aAA4B,GAAG;AAAM,YAAA,KAAK,EAAE,aAAa;AAAA,MAAG;AAC5F,aAAA;AAAA,IACT,GAAG,CAAkC,CAAA;AAAA,EACvC;AAEO,WAAS,gBAAgB,IAA2B;AACrD,QAAA,GAAG,mBAAoB,QAAO,GAAG;AACrC,QAAI,GAAG,cAAsB,QAAA,gBAAgB,GAAG,aAAa;AACtD,WAAA;AAAA,EACT;AAEgB,WAAA,qBAAqB,QAA+B,UAAkB,UAAuC;AAC3H,UAAM,WAAW,IAAI,iBAAiB,CAAC,eAAe;AAC9C,YAAA,KAAK,OAAO,cAAc,QAAQ;AACxC,UAAI,IAAI;AACN,iBAAS,WAAW;AACpB,iBAAS,EAAE;AAAA,MACb;AAAA,IAAA,CACD;AACQ,aAAA,QAAQ,SAAS,MAAM,EAAE,WAAW,MAAM,SAAS,MAAM;AAAA,EACpE;AAEgB,WAAA,0BAA0B,SACxC,UAAqE;AACjE,QAAA,QAAQ,QAAQ,SAAS;AAC7B,UAAM,WAAW,IAAI,iBAAiB,CAAC,cAAcC,cAAa;AAChE,iBAAW,YAAY,cAAc;AAC/B,YAAA,SAAS,SAAS,aAAa;AAC7B,cAAA,UAAU,QAAQ,SAAS,QAAQ;AACrC,oBAAQ,QAAQ,SAAS;AACzB,qBAASA,WAAU,KAAK;AAAA,UAC1B;AAAA,QACF;AAAA,MACF;AAAA,IAAA,CACD;AACD,aAAS,QAAQ,SAAS,EAAE,WAAW,KAAM,CAAA;AAAA,EAC/C;AAEO,WAAS,4BAA4B,SAAgC,UAC1E,WAAW,KAAM,UAAmC,EAAE,WAAW,MAAM,SAAS,MAAM,YAAY,QAAQ;AACtG,QAAA;AACA,QAAA;AACJ,UAAM,WAAW,IAAI,iBAAiB,CAAC,eAAe,cAAc;AAC5D,YAAA,MAAM,KAAK;AACb,UAAA,oBAAoB,MAAM,mBAAmB,UAAU;AACzD,mBAAW,aAAa,OAAO;AAAA,MACjC;AACU,gBAAA,WAAW,UAAU,QAAQ;AACpB,yBAAA;AAAA,IAAA,CACpB;AACQ,aAAA,QAAQ,SAAS,OAAO;AAAA,EACnC;AAEgB,WAAA,WAAW,UAAU,EAAE,QAAQ,IAAI,OAAO,IAAI,QAAQ,IAAI,UAAU,MAAM;AAAA,EAAE,KAAK;;AACzF,UAAA,MAAM,SAAS,QAAQ,MAAM;AAE/B,QAAA,QAAQ,OAAiB,gBAAA,cAAc,QAAQ,MAAM,MAA5B,mBAA+B,OAAO;AAC/D,QAAA,QAAQ,MAAgB,gBAAA,cAAc,QAAQ,KAAK,MAA3B,mBAA8B,MAAM;AAE5D,QAAA,iBAAiB,SAAS,CAAC,MAAM;AACnC,QAAE,eAAe;AAEb,UAAA,QAAQ,SAAU,SAAQ,SAAS;AAEvC,2BAAqB,SAAS,MAAM,SAAS,CAAC,UAAmB;AAC/D,eAAO,SAAS,OAAO,MAAM,aAAa,KAAK;AAAA,MAAA,CAChD;AAAA,IAAA,CACF;AAAA,EACH;ACvFO,QAAM,YAAY;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,EAAuC,EAAE,KAAK,GAAG;AAEnC,WAAA,UAAU,KAAa,UAAmC,EAAE,MAAM,OAAO,QAAQ,SAAS;AACxG,UAAM,UAAU,CAAA;AAChB,QAAI,QAAQ,OAAe,QAAA,OAAO,SAAS,EAAE,SAAS,IAAI,QAAQ,EAAE,cAAc,UAAW,CAAA,EAAG,CAAA;AAChG,WAAO,MAAM,KAAK,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,KAAA,CAAM,EAAE,KAAK,CAAK,MAAA,QAAQ,OAAO,SAAS,CAAC,IAAI,CAAC;AAAA,EAC3F;AAEa,QAAA,YAAY,CAAC,QAAgB,UAAU,KAAK,EAAE,MAAM,MAAM;AAE1D,QAAA,YAAY,CAAC,QAAgB,UAAU,GAAG;AAEhD,WAAS,iBAAiB,QAA6D;AACtF,UAAA,WAAW,IAAI;AACrB,WAAO,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,SAAS,OAAO,GAAG,CAAW,CAAC;AACnE,WAAA;AAAA,EACT;ACrBgB,WAAA,aAAa,KAA4B,QAAuB,UAAoC;AAClH,eAAW,KAAK,QAAQ;AAClB,UAAA,iBAAiB,GAAG,UAAU,IAAI;AAAA,IACxC;AAAA,EACF;AAAA,EAEO,MAAM,KAAK;AAAA,IAIhB,YAAoB,OAAuB,iBAAiB,MAAM;AAH1D;AACA;AAEY,WAAA,QAAA;AAAuB,WAAA,iBAAA;AACzC,WAAK,OAAO;AACZ,WAAK,QAAQ;AACb,WAAK,iBAAiB;AAAA,IACxB;AAAA,IAEA,MAAM,UAAsB,gBAAgB,QAAW;AACrD,WAAK,KAAK;AACV,WAAK,gBAAgB;AACjB,UAAA,KAAK,eAAyB;AAClC,WAAK,OAAO,YAAY,UAAU,KAAK,KAAK;AAAA,IAC9C;AAAA,IAEA,OAAO;AACD,UAAA,KAAK,SAAS,MAAM;AACtB,sBAAc,KAAK,IAAI;AACvB,aAAK,OAAO;AAAA,MACd;AACA,UAAI,KAAK,eAAe;AACtB,aAAK,cAAc;AACnB,aAAK,gBAAgB;AAAA,MACvB;AAAA,IACF;AAAA,EACF;ACjCO,WAAS,QAAQ;AACf,WAAA,kBAAkB,KAAK,UAAU,SAAS;AAAA,EACnD;ACDA,iBAAsB,sBAAsB,UAAyC;AACnF,UAAM,MAAM,CAAA;AACZ,qBAAiB,KAAK,UAAU;AAC1B,UAAA,KAAK,MAAM,EAAA,CAAG;AAAA,IACpB;AACO,WAAA;AAAA,EACT;AAEO,WAAS,KAAK,cAAsB;AACzC,WAAO,IAAI,QAAQ,CAAA,YAAW,WAAW,SAAS,YAAY,CAAC;AAAA,EACjE;AAAA,EAOO,MAAM,SAAS;AAAA,IAAf;AACL,kCAA8B,CAAA;AAC9B,kCAAO;AAAA;AAAA,IAEP,qBAAqB,IAAI,GAAsC;AAC7D,UAAI,IAAI,KAAK,KAAK,KAAK,WAAW,EAAU,QAAA;AAC5C,YAAM,IAAI,KAAK,KAAK,UAAU,CAAK,MAAA,EAAE,MAAM,CAAC;AAC5C,UAAI,KAAK,GAAG;AACV,cAAM,MAAM,KAAK,KAAK,CAAC,EAAE;AACzB,aAAK,OAAO,KAAK,KAAK,MAAM,GAAG,CAAC,EAAE,OAAO,KAAK,KAAK,MAAM,IAAI,CAAC,CAAC;AACxD,eAAA;AAAA,MACT;AACO,aAAA,KAAK,qBAAqB,IAAI,CAAC;AAAA,IACxC;AAAA,IAEA,CAAC,gBAAgB;AACR,aAAA,KAAK,KAAK,SAAS,GAAG;AAC3B,cAAM,KAAK;MACb;AAAA,IACF;AAAA,IAEA,MAAM,cAAc;AACd,UAAA,CAAC,KAAK,MAAM;AACd,aAAK,OAAO;AACK,yBAAA,KAAK,KAAK,iBAAiB;AAC1C,iBAAM;AAAA,QACR;AACA,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAAA,IAEA,KAAK,GAAmB;AACjB,WAAA,KAAK,KAAK,CAAC;AAChB,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;ACrDgB,WAAA,OAAU,KAAe,GAA4B;AACnE,UAAM,MAAM,CAAA;AACZ,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,GAAG;AACtC,UAAI,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,CAAC;AAAA,IAC9B;AACO,WAAA;AAAA,EACT;AAEgB,WAAA,MAAM,MAAc,UAAU,GAAkB;AACvD,WAAA,CAAC,GAAG,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE,IAAI,CAAK,MAAA,IAAI,OAAO;AAAA,EACrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
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,3 +1,17 @@
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;
@@ -65,16 +79,7 @@ export declare function sanitizeStr(s: string): string;
65
79
 
66
80
  export declare function stringToWords(s: string): Array<string>;
67
81
 
68
- export declare class SyncPull {
69
- pull: Array<SyncPullObject>;
70
- lock: boolean;
71
- getHighPriorityFirst(p?: number): (() => Promise<void>) | undefined;
72
- pullGenerator(): Generator<(() => Promise<void>) | undefined, void, unknown>;
73
- processPull(): Promise<void>;
74
- push(x: SyncPullObject): void;
75
- }
76
-
77
- declare interface SyncPullObject {
82
+ declare interface SyncPoolObject {
78
83
  v: () => Promise<void>;
79
84
  p: number;
80
85
  }
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.4",
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";
@@ -8,47 +8,61 @@ export async function computeAsyncOneAtTime(iterable: Iterable<() => Promise<voi
8
8
  }
9
9
 
10
10
  export function wait(milliseconds: number) {
11
- return new Promise(resolve => setTimeout(resolve, milliseconds));
11
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
12
12
  }
13
13
 
14
- interface SyncPullObject {
15
- v: () => Promise<void>,
16
- p: number
14
+ interface SyncPoolObject {
15
+ v: () => Promise<void>;
16
+ p: number;
17
17
  }
18
18
 
19
- export class SyncPull {
20
- pull: Array<SyncPullObject> = [];
21
- lock = false;
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
+ }
22
32
 
23
33
  getHighPriorityFirst(p = 0): (() => Promise<void>) | undefined {
24
- if (p > 3 || this.pull.length === 0) return undefined;
25
- const i = this.pull.findIndex(e => e.p === p);
34
+ if (p > 3 || this.pool.length === 0) return undefined;
35
+ const i = this.pool.findIndex((e) => e.p === p);
26
36
  if (i >= 0) {
27
- const res = this.pull[i].v;
28
- 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));
29
39
  return res;
30
40
  }
31
41
  return this.getHighPriorityFirst(p + 1);
32
42
  }
33
43
 
34
- *pullGenerator() {
35
- while (this.pull.length > 0) {
36
- yield this.getHighPriorityFirst();
37
- }
44
+ async runTask() {
45
+ this.cur++;
46
+ const f = this.getHighPriorityFirst();
47
+ await f?.();
48
+ this.cur--;
49
+ this.runTasks();
38
50
  }
39
51
 
40
- async processPull() {
41
- if (!this.lock) {
42
- this.lock = true;
43
- for await (const f of this.pullGenerator()) {
44
- await f?.();
45
- }
46
- 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();
47
57
  }
48
58
  }
49
59
 
50
- push(x: SyncPullObject) {
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
  }