billy-herrington-utils 1.1.2 → 1.1.4

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
@@ -14,35 +14,48 @@
14
14
  npm i billy-herrington-utils
15
15
  ```
16
16
 
17
- ## utils:
18
- * stringToWords
19
- * sanitizeStr
20
- * timeToSeconds
21
- * parseCSSUrl
22
- * parseDataParams
23
- * parseIntegerOr
24
- * Observer
25
- * LazyImgLoader
26
- * circularShift
27
- * MOBILE_UA
28
- * fetchHtml
29
- * fetchText
30
- * fetchWith
31
- * objectToFormData
32
- * Tick
33
- * listenEvents
34
- * parseDom
35
- * copyAttributes
36
- * downloader
37
- * findNextSibling
38
- * getAllUniqueParents
39
- * replaceElementTag
40
- * waitForElementExists
41
- * watchDomChangesWithThrottle
42
- * watchElementChildrenCount
43
- * isMob
44
- * computeAsyncOneAtTime
45
- * SyncPull
46
- * wait
47
- * chunks
48
- * range
17
+ **A comprehensive collection of utility 🛠️ functions to make dungeon life easier.**
18
+
19
+ **Key features:**
20
+
21
+ * **String manipulation:** Easily parse, sanitize, and convert strings.
22
+ * **Time and date:** Work with time and date values effortlessly.
23
+ * **DOM manipulation:** Interact with DOM elements like a pro.
24
+ * **Networking:** Make HTTP requests and handle data with ease.
25
+ * **Miscellaneous:** A variety of other useful functions for common tasks.
26
+
27
+ ## **Documentation**
28
+
29
+ | Function | Short Explanation | Input Parameters | Example Input/Output or Usage |
30
+ |---|---|---|---|
31
+ | `stringToWords(s)` | Splits a string into an array of words. | `s: string` | `stringToWords("Hello, world!")` -> `["hello", "world"]` |
32
+ | `sanitizeStr(s)` | Sanitizes a string by removing newlines, tabs, and extra spaces. | `s: string` | `sanitizeStr("Hello\nWorld\t")` -> `hello world` |
33
+ | `timeToSeconds(timeStr)` | Converts a time string to seconds. | `timeStr: string` | `timeToSeconds("1h30m")` -> `5400` |
34
+ | `parseIntegerOr(value, defaultValue)` | Parses a string as an integer. | `value: string`, `defaultValue: number` | `parseIntegerOr("10", 0)` -> `10`, `parseIntegerOr("abc", 0)` -> `0` |
35
+ | `parseDataParams(str)` | Parses a string containing data parameters into an object. | `str: string` | `parseDataParams("param1:value1;param2:value2")` -> `{ param1: "value1", param2: "value2" }` |
36
+ | `parseCSSUrl(cssUrl)` | Extracts the URL from a CSS `url()` declaration. | `cssUrl: string` | `parseCSSUrl("url('https://example.com/image.jpg')")` -> `https://example.com/image.jpg` |
37
+ | `Observer` | A class for observing elements and triggering callbacks when they intersect with the viewport. | N/A | `const observer = new Observer((target) => { console.log(target); }); observer.observe(element);` |
38
+ | `LazyImgLoader` | A class for lazy loading images. | N/A | `const lazyLoader = new LazyImgLoader(); lazyLoader.lazify(element, image, imageSrc);` |
39
+ | `circularShift(value, max, shift)` | Performs a circular shift on a number. | `value: number`, `max: number = 6`, `shift: number = 1` | `circularShift(5, 10, 2)` -> `7` |
40
+ | `parseDom(html)` | Parses HTML into a DOM element. | `html: string` | `const element = parseDom("<div>Hello</div>");` |
41
+ | `copyAttributes(target, source)` | Copies attributes from one DOM element to another. | `target: HTMLElement`, `source: HTMLElement` | `copyAttributes(targetElement, sourceElement);` |
42
+ | `replaceElementTag(element, tagName)` | Replaces a DOM element with a new element of a different tag. | `element: HTMLElement`, `tagName: string` | `replaceElementTag(element, "span");` |
43
+ | `getAllUniqueParents(elements)` | Gets all unique parent elements of a list of elements. | `elements: HTMLElement[]` | `const parents = getAllUniqueParents(elements);` |
44
+ | `findNextSibling(element)` | Finds the next sibling element of a given element. | `element: HTMLElement` | `const nextSibling = findNextSibling(element);` |
45
+ | `waitForElementExists(parent, selector, callback)` | Waits for an element to exist within a parent element and then calls a callback. | `parent: HTMLElement`, `selector: string`, `callback: (element: HTMLElement) => void` | `waitForElementExists(container, ".target-element", (element) => { ... });` |
46
+ | `watchElementChildrenCount(element, callback)` | Watches for changes in the number of children of an element and calls a callback. | `element: HTMLElement`, `callback: (observer: MutationObserver, count: number) => void` | `watchElementChildrenCount(element, (observer, count) => { ... });` |
47
+ | `watchDomChangesWithThrottle(element, callback, throttle = 1e3, options = { childList: true, subtree: true, attributes: true })` | Watches for DOM changes within an element and calls a callback with throttling. | `element: HTMLElement`, `callback: (mutationList: MutationRecord[]) => void`, `throttle?: number`, `options?: MutationObserverInit` | `watchDomChangesWithThrottle(element, (mutationList) => { ... });` |
48
+ | `downloader(options)` | Creates a download button for a video element. | `options: { button: string, append?: string, after?: string, cbBefore?: () => void }` | `downloader({ button: "#download-button" });` |
49
+ | `MOBILE_UA` | A constant containing a mobile user agent string. | N/A | `console.log(MOBILE_UA);` |
50
+ | `fetchWith(url, options)` | Fetches data from a URL. | `url: string`, `options: { html?: boolean, mobile?: boolean }` | `fetchWith("https://api.example.com/data", { html: true }).then((html) => { ... });` |
51
+ | `fetchHtml(url)` | Fetches HTML from a URL. | `url: string` | `fetchHtml("https://example.com/page.html").then((html) => { ... });` |
52
+ | `fetchText(url)` | Fetches text from a URL. | `url: string` | `fetchText("https://example.com/data.txt").then((text) => { ... });` |
53
+ | `objectToFormData(object)` | Converts an object to FormData. | `object: object` | `const formData = objectToFormData({ name: "John", age: 30 });` |
54
+ | `listenEvents(element, events, callback)` | Adds event listeners to a DOM element. | `element: HTMLElement`, `events: string[]`, `callback: (event: Event) => void` | `listenEvents(element, ["click", "mouseover"], (event) => { ... });` |
55
+ | `Tick(delay, startImmediate = true)` | A class for creating interval timers. | `delay: number`, `startImmediate?: boolean` | `const tick = new Tick(1000, false); tick.start(() => { ... });` |
56
+ | `isMob()` | Checks if the current device is a mobile device. | N/A | `if (isMob()) { ... }` |
57
+ | `computeAsyncOneAtTime(iterable)` | Executes asynchronous functions one at a time. | `iterable: Iterable<() => Promise<any>>` | `computeAsyncOneAtTime(asyncFunctions).then((results) => { ... });` |
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(() => { ... });` |
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
+ | `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]` |
@@ -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;
@@ -194,7 +184,6 @@ function listenEvents(dom, events, callback) {
194
184
  class Tick {
195
185
  constructor(delay, startImmediate = true) {
196
186
  __publicField(this, "tick");
197
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
198
187
  __publicField(this, "callbackFinal");
199
188
  this.delay = delay;
200
189
  this.startImmediate = startImmediate;
@@ -202,8 +191,7 @@ class Tick {
202
191
  this.delay = delay;
203
192
  this.startImmediate = startImmediate;
204
193
  }
205
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
206
- start(callback, callbackFinal = null) {
194
+ start(callback, callbackFinal = void 0) {
207
195
  this.stop();
208
196
  this.callbackFinal = callbackFinal;
209
197
  if (this.startImmediate) callback();
@@ -216,7 +204,7 @@ class Tick {
216
204
  }
217
205
  if (this.callbackFinal) {
218
206
  this.callbackFinal();
219
- this.callbackFinal = null;
207
+ this.callbackFinal = void 0;
220
208
  }
221
209
  }
222
210
  }
@@ -235,11 +223,9 @@ function wait(milliseconds) {
235
223
  }
236
224
  class SyncPull {
237
225
  constructor() {
238
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
239
226
  __publicField(this, "pull", []);
240
227
  __publicField(this, "lock", false);
241
228
  }
242
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
243
229
  getHighPriorityFirst(p = 0) {
244
230
  if (p > 3 || this.pull.length === 0) return void 0;
245
231
  const i = this.pull.findIndex((e) => e.p === p);
@@ -259,12 +245,11 @@ class SyncPull {
259
245
  if (!this.lock) {
260
246
  this.lock = true;
261
247
  for await (const f of this.pullGenerator()) {
262
- await f();
248
+ await (f == null ? void 0 : f());
263
249
  }
264
250
  this.lock = false;
265
251
  }
266
252
  }
267
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
268
253
  push(x) {
269
254
  this.pull.push(x);
270
255
  this.processPull();
@@ -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":"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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 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,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,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;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;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;AJ1E1F;AI2EC,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,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,SAAS;AAAA,EAAf;AACL,gCAA8B,CAAA;AAC9B,gCAAO;AAAA;AAAA,EAEP,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,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,eAAM;AAAA,MACR;AACA,WAAK,OAAO;AAAA,IACd;AAAA,EACF;AAAA,EAEA,KAAK,GAAmB;AACjB,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;"}
@@ -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;
@@ -198,7 +188,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
198
188
  class Tick {
199
189
  constructor(delay, startImmediate = true) {
200
190
  __publicField(this, "tick");
201
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
202
191
  __publicField(this, "callbackFinal");
203
192
  this.delay = delay;
204
193
  this.startImmediate = startImmediate;
@@ -206,8 +195,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
206
195
  this.delay = delay;
207
196
  this.startImmediate = startImmediate;
208
197
  }
209
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
210
- start(callback, callbackFinal = null) {
198
+ start(callback, callbackFinal = void 0) {
211
199
  this.stop();
212
200
  this.callbackFinal = callbackFinal;
213
201
  if (this.startImmediate) callback();
@@ -220,7 +208,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
220
208
  }
221
209
  if (this.callbackFinal) {
222
210
  this.callbackFinal();
223
- this.callbackFinal = null;
211
+ this.callbackFinal = void 0;
224
212
  }
225
213
  }
226
214
  }
@@ -239,11 +227,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
239
227
  }
240
228
  class SyncPull {
241
229
  constructor() {
242
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
243
230
  __publicField(this, "pull", []);
244
231
  __publicField(this, "lock", false);
245
232
  }
246
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
247
233
  getHighPriorityFirst(p = 0) {
248
234
  if (p > 3 || this.pull.length === 0) return void 0;
249
235
  const i = this.pull.findIndex((e) => e.p === p);
@@ -263,12 +249,11 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
263
249
  if (!this.lock) {
264
250
  this.lock = true;
265
251
  for await (const f of this.pullGenerator()) {
266
- await f();
252
+ await (f == null ? void 0 : f());
267
253
  }
268
254
  this.lock = false;
269
255
  }
270
256
  }
271
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
272
257
  push(x) {
273
258
  this.pull.push(x);
274
259
  this.processPull();
@@ -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":";;;;;;;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;AAAA,IAGA,OAAO,aAAa,QAAiB,UAAe,cAAsB;AACxE,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;AAAA,IAGzB,YAAY,UAAuB,gBAAgB,kBAA0B,iBAAiB,MAAM;AAF7F;AAeP,sCAAW,CAAC,WAA6B;AAClC,aAAA,gBAAgB,SAAS,UAAU,MAAM;AAC9C,eAAO,MAAM,OAAO,aAAa,KAAK,aAAa;AACnD,YAAI,KAAK,eAAuB,QAAA,gBAAgB,KAAK,aAAa;AAAA,MAAA;AAhBjC,WAAA,gBAAA;AAA0C,WAAA,iBAAA;AAC3E,WAAK,kBAAkB,IAAI,SAAS,CAAC,WAAoB;AAC9C,iBAAA,QAAQ,KAAK,QAAQ;AAAA,MAAA,CAC/B;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;AAAA,IASA,OAAO,OAAO,UAAe;AAE3B,YAAM,gBAAgB,IAAI,cAAc,CAAC,QAAiB,aAAkB;AACtE,YAAA,SAAS,MAAM,GAAG;AACpB,mBAAS,MAAM;AAAA,QACjB;AAAA,MAAA,CACD;AACM,aAAA;AAAA,IACT;AAAA,EACF;AClEO,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;AAGgB,WAAA,qBAAqB,QAA+B,UAAkB,UAAqB;AACzG,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;AAGgB,WAAA,0BAA0B,SAAgC,UAAqB;AACzF,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;AAGO,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,UAA4B;AACxE,eAAO,SAAS,OAAO,MAAM,aAAa,KAAK;AAAA,MAAA,CAChD;AAAA,IAAA,CACF;AAAA,EACH;ACzFO,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;ACpBgB,WAAA,aAAa,KAA4B,QAAuB,UAAqB;AACnG,eAAW,KAAK,QAAQ;AAClB,UAAA,iBAAiB,GAAG,UAAU,IAAI;AAAA,IACxC;AAAA,EACF;AAAA,EAEO,MAAM,KAAK;AAAA,IAKhB,YAAoB,OAAuB,iBAAiB,MAAM;AAJ1D;AAEA;AAAA;AAEY,WAAA,QAAA;AAAuB,WAAA,iBAAA;AACzC,WAAK,OAAO;AACZ,WAAK,QAAQ;AACb,WAAK,iBAAiB;AAAA,IACxB;AAAA;AAAA,IAGA,MAAM,UAAe,gBAAgB,MAAM;AACzC,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;ACpCO,WAAS,QAAQ;AACf,WAAA,kBAAkB,KAAK,UAAU,SAAS;AAAA,EACnD;ACAA,iBAAsB,sBAAsB,UAAyB;AACnE,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,EAGO,MAAM,SAAS;AAAA,IAAf;AAEL;AAAA,kCAAmB,CAAA;AACnB,kCAAO;AAAA;AAAA;AAAA,IAGP,qBAAqB,IAAI,GAAQ;AAC/B,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,gBAAM,EAAE;AAAA,QACV;AACA,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAAA;AAAA,IAGA,KAAK,GAAQ;AACN,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 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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"}
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export declare function chunks<T>(arr: Array<T>, n: number): Array<Array<T>>;
2
2
 
3
3
  export declare function circularShift(n: number, c?: number, s?: number): number;
4
4
 
5
- export declare function computeAsyncOneAtTime(iterable: Iterable<any>): Promise<any[]>;
5
+ export declare function computeAsyncOneAtTime(iterable: Iterable<() => Promise<void>>): Promise<void[]>;
6
6
 
7
7
  export declare function copyAttributes(target: HTMLElement | Element, source: HTMLElement | Element): void;
8
8
 
@@ -26,16 +26,14 @@ export declare function getAllUniqueParents(elements: HTMLCollection): Array<HTM
26
26
  export declare function isMob(): boolean;
27
27
 
28
28
  export declare class LazyImgLoader {
29
- private attributeName;
30
- private removeTagAfter;
31
29
  lazyImgObserver: Observer;
32
- constructor(callback: any, attributeName?: string, removeTagAfter?: boolean);
30
+ private attributeName;
31
+ constructor(shouldDelazify: (target: Element) => boolean);
33
32
  lazify(_target: Element, img: HTMLImageElement, imgSrc: string): void;
34
33
  delazify: (target: HTMLImageElement) => void;
35
- static create(callback: any): LazyImgLoader;
36
34
  }
37
35
 
38
- export declare function listenEvents(dom: HTMLElement | Element, events: Array<string>, callback: any): void;
36
+ export declare function listenEvents(dom: HTMLElement | Element, events: Array<string>, callback: (e: Event) => void): void;
39
37
 
40
38
  export declare const MOBILE_UA: string;
41
39
 
@@ -48,7 +46,7 @@ export declare class Observer {
48
46
  observe(target: Element): void;
49
47
  throttle(target: Element, throttleTime: number): void;
50
48
  handleIntersection(entries: Iterable<IntersectionObserverEntry>): void;
51
- static observeWhile(target: Element, callback: any, throttleTime: number): Observer;
49
+ static observeWhile(target: Element, callback: () => Promise<boolean> | boolean, throttleTime: number): Observer;
52
50
  }
53
51
 
54
52
  export declare function parseCSSUrl(s: string): string;
@@ -68,12 +66,17 @@ export declare function sanitizeStr(s: string): string;
68
66
  export declare function stringToWords(s: string): Array<string>;
69
67
 
70
68
  export declare class SyncPull {
71
- pull: Array<any>;
69
+ pull: Array<SyncPullObject>;
72
70
  lock: boolean;
73
- getHighPriorityFirst(p?: number): any;
74
- pullGenerator(): Generator<any, void, unknown>;
71
+ getHighPriorityFirst(p?: number): (() => Promise<void>) | undefined;
72
+ pullGenerator(): Generator<(() => Promise<void>) | undefined, void, unknown>;
75
73
  processPull(): Promise<void>;
76
- push(x: any): void;
74
+ push(x: SyncPullObject): void;
75
+ }
76
+
77
+ declare interface SyncPullObject {
78
+ v: () => Promise<void>;
79
+ p: number;
77
80
  }
78
81
 
79
82
  export declare class Tick {
@@ -82,7 +85,7 @@ export declare class Tick {
82
85
  private tick;
83
86
  private callbackFinal;
84
87
  constructor(delay: number, startImmediate?: boolean);
85
- start(callback: any, callbackFinal?: null): void;
88
+ start(callback: () => void, callbackFinal?: undefined): void;
86
89
  stop(): void;
87
90
  }
88
91
 
@@ -90,10 +93,10 @@ export declare function timeToSeconds(t: string): number;
90
93
 
91
94
  export declare function wait(milliseconds: number): Promise<unknown>;
92
95
 
93
- export declare function waitForElementExists(parent: HTMLElement | Element, selector: string, callback: any): void;
96
+ export declare function waitForElementExists(parent: HTMLElement | Element, selector: string, callback: (el: Element) => void): void;
94
97
 
95
- export declare function watchDomChangesWithThrottle(element: HTMLElement | Element, callback: any, throttle?: number, options?: Record<string, boolean>): void;
98
+ export declare function watchDomChangesWithThrottle(element: HTMLElement | Element, callback: () => void, throttle?: number, options?: Record<string, boolean>): void;
96
99
 
97
- export declare function watchElementChildrenCount(element: HTMLElement | Element, callback: any): void;
100
+ export declare function watchElementChildrenCount(element: HTMLElement | Element, callback: (observer: MutationObserver, count: number) => void): void;
98
101
 
99
102
  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.2",
4
+ "version": "1.1.4",
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)",
@@ -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());
@@ -12,14 +11,16 @@ export function wait(milliseconds: number) {
12
11
  return new Promise(resolve => setTimeout(resolve, milliseconds));
13
12
  }
14
13
 
15
- // do async one at time
14
+ interface SyncPullObject {
15
+ v: () => Promise<void>,
16
+ p: number
17
+ }
18
+
16
19
  export class SyncPull {
17
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
18
- pull: Array<any> = [];
20
+ pull: Array<SyncPullObject> = [];
19
21
  lock = false;
20
22
 
21
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
22
- getHighPriorityFirst(p = 0): any {
23
+ getHighPriorityFirst(p = 0): (() => Promise<void>) | undefined {
23
24
  if (p > 3 || this.pull.length === 0) return undefined;
24
25
  const i = this.pull.findIndex(e => e.p === p);
25
26
  if (i >= 0) {
@@ -40,14 +41,13 @@ export class SyncPull {
40
41
  if (!this.lock) {
41
42
  this.lock = true;
42
43
  for await (const f of this.pullGenerator()) {
43
- await f();
44
+ await f?.();
44
45
  }
45
46
  this.lock = false;
46
47
  }
47
48
  }
48
49
 
49
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
50
- push(x: any) {
50
+ push(x: SyncPullObject) {
51
51
  this.pull.push(x);
52
52
  this.processPull();
53
53
  }
@@ -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
  }