billy-herrington-utils 2.0.7 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +360 -62
- package/dist/billy-herrington-utils.es.js +275 -6251
- package/dist/billy-herrington-utils.es.js.map +1 -1
- package/dist/billy-herrington-utils.umd.js +321 -6253
- package/dist/billy-herrington-utils.umd.js.map +1 -1
- package/dist/index.d.ts +69 -190
- package/package.json +18 -7
- package/src/index.ts +1 -44
- package/src/types/index.ts +7 -0
- package/src/utils/arrays/index.ts +11 -5
- package/src/utils/async/index.ts +0 -88
- package/src/utils/dom/{observers.ts → dom-observers.ts} +3 -3
- package/src/utils/dom/index.ts +97 -16
- package/src/utils/events/index.ts +2 -37
- package/src/utils/events/on-hover.ts +42 -0
- package/src/utils/events/tick.ts +27 -0
- package/src/utils/fetch/index.ts +30 -28
- package/src/utils/index.ts +39 -0
- package/src/utils/objects/index.ts +19 -18
- package/src/utils/objects/memoize.ts +25 -0
- package/src/utils/observers/index.ts +4 -28
- package/src/utils/observers/lazy-image-loader.ts +27 -0
- package/src/utils/parsers/index.ts +2 -20
- package/src/utils/parsers/time-parser.ts +28 -0
- package/src/utils/strings/regexes.ts +12 -8
- package/src/types/globals.d.ts +0 -0
- package/src/userscripts/data-manager/data-filter.ts +0 -110
- package/src/userscripts/data-manager/index.ts +0 -141
- package/src/userscripts/infinite-scroll/index.ts +0 -106
- package/src/userscripts/pagination-parsing/index.ts +0 -55
- package/src/userscripts/pagination-parsing/pagination-strategies/PaginationStrategy.ts +0 -42
- package/src/userscripts/pagination-parsing/pagination-strategies/PaginationStrategyDataParams.ts +0 -66
- package/src/userscripts/pagination-parsing/pagination-strategies/PaginationStrategyPathnameParams.ts +0 -77
- package/src/userscripts/pagination-parsing/pagination-strategies/PaginationStrategySearchParams.ts +0 -56
- package/src/userscripts/pagination-parsing/pagination-strategies/PaginationStrategyTrash.ts +0 -33
- package/src/userscripts/pagination-parsing/pagination-strategies/index.ts +0 -5
- package/src/userscripts/pagination-parsing/pagination-utils/index.ts +0 -69
- package/src/userscripts/router/router.ts +0 -71
- package/src/userscripts/rules/index.ts +0 -241
- package/src/userscripts/types/index.ts +0 -19
- package/src/utils/device/index.ts +0 -3
- package/src/utils/userscript/index.ts +0 -10
package/README.md
CHANGED
|
@@ -1,90 +1,388 @@
|
|
|
1
1
|
### _daddy told us not to be ashamed of our utils_
|
|
2
2
|

|
|
3
3
|
|
|
4
|
+
## Installation
|
|
5
|
+
|
|
6
|
+
```shell
|
|
7
|
+
npm i billy-herrington-utils
|
|
4
8
|
```
|
|
5
|
-
|
|
6
|
-
```
|
|
7
|
-
```
|
|
9
|
+
```html
|
|
8
10
|
<script src="https://unpkg.com/billy-herrington-utils/dist/billy-herrington-utils.umd.js"></script>
|
|
9
11
|
<script>
|
|
10
12
|
const { Tick } = window.bhutils;
|
|
11
13
|
</script>
|
|
12
14
|
```
|
|
15
|
+
|
|
16
|
+
## 📦 Arrays & Iterables
|
|
17
|
+
|
|
18
|
+
### chunks
|
|
19
|
+
|
|
20
|
+
Splits an array into smaller arrays of a specified size.
|
|
21
|
+
|
|
22
|
+
* **Input**: `arr: T[]`, `size: number`
|
|
23
|
+
* **Output**: `T[][]`
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
const data = [1, 2, 3, 4, 5]
|
|
27
|
+
const result = chunks(data, 2)
|
|
28
|
+
console.log(result)
|
|
29
|
+
|
|
13
30
|
```
|
|
14
|
-
|
|
31
|
+
|
|
32
|
+
### range
|
|
33
|
+
|
|
34
|
+
Generates an array of numbers starting from a specific value.
|
|
35
|
+
|
|
36
|
+
* **Input**: `size: number`, `start?: number` (default 1), `step?: number` (default 1)
|
|
37
|
+
* **Output**: `number[]`
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
const numbers = range(5, 0, 10)
|
|
41
|
+
console.log(numbers)
|
|
42
|
+
|
|
15
43
|
```
|
|
16
44
|
|
|
17
|
-
|
|
45
|
+
### circularShift
|
|
46
|
+
|
|
47
|
+
Performs a circular shift on a number within a specific capacity.
|
|
18
48
|
|
|
19
|
-
**
|
|
49
|
+
* **Input**: `n: number` (current index), `c?: number` (capacity, default 6), `s?: number` (shift step, default 1)
|
|
50
|
+
* **Output**: `number`
|
|
20
51
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
* **Networking:** Make HTTP requests and handle data with ease.
|
|
25
|
-
* **Miscellaneous:** A variety of other useful functions for common tasks.
|
|
52
|
+
```typescript
|
|
53
|
+
const nextIndex = circularShift(5, 6, 1)
|
|
54
|
+
console.log(nextIndex)
|
|
26
55
|
|
|
27
|
-
|
|
56
|
+
```
|
|
28
57
|
|
|
29
58
|
---
|
|
30
59
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
60
|
+
## ⏱️ Async & Timing
|
|
61
|
+
|
|
62
|
+
### wait
|
|
63
|
+
|
|
64
|
+
Returns a Promise that resolves after a specified duration.
|
|
65
|
+
|
|
66
|
+
* **Input**: `milliseconds: number`
|
|
67
|
+
* **Output**: `Promise<void>`
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
await wait(1000)
|
|
71
|
+
console.log("Done waiting")
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Tick
|
|
76
|
+
|
|
77
|
+
A class for creating repeating intervals with start/stop control and final callbacks.
|
|
78
|
+
|
|
79
|
+
* **Methods**: `start(callback, callbackFinal?)`, `stop()`
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
const ticker = new Tick(1000)
|
|
83
|
+
ticker.start(
|
|
84
|
+
() => console.log("Tick"),
|
|
85
|
+
() => console.log("Stopped")
|
|
86
|
+
)
|
|
87
|
+
await wait(3000)
|
|
88
|
+
ticker.stop()
|
|
89
|
+
|
|
90
|
+
```
|
|
49
91
|
|
|
50
92
|
---
|
|
51
93
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
94
|
+
## 📝 String & Formatting
|
|
95
|
+
|
|
96
|
+
### splitWith
|
|
97
|
+
|
|
98
|
+
Splits a string by a delimiter, trims whitespace, and filters out empty strings.
|
|
99
|
+
|
|
100
|
+
* **Input**: `s: string`, `c?: string` (delimiter, default ",")
|
|
101
|
+
* **Output**: `string[]`
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
const tags = splitWith(" apple, banana , , orange ")
|
|
105
|
+
console.log(tags)
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### sanitizeStr
|
|
110
|
+
|
|
111
|
+
Removes newlines, tabs, and excessive whitespace from a string.
|
|
112
|
+
|
|
113
|
+
* **Input**: `s: string`
|
|
114
|
+
* **Output**: `string`
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
const raw = " Hello \n\t World "
|
|
118
|
+
const clean = sanitizeStr(raw)
|
|
119
|
+
console.log(clean)
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### timeToSeconds
|
|
124
|
+
|
|
125
|
+
Converts a time string (e.g., "1h 30min" or "01:30:00") into total seconds.
|
|
126
|
+
|
|
127
|
+
* **Input**: `timeStr: string`
|
|
128
|
+
* **Output**: `number`
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
const totalSeconds = timeToSeconds("1h 2min 30sec")
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### formatTimeToHHMMSS
|
|
136
|
+
|
|
137
|
+
Formats a descriptive time string into a standard HH:MM:SS format.
|
|
138
|
+
|
|
139
|
+
* **Input**: `timeStr: string`
|
|
140
|
+
* **Output**: `string`
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
const stamp = formatTimeToHHMMSS("1h 5min")
|
|
144
|
+
console.log(stamp)
|
|
145
|
+
|
|
146
|
+
```
|
|
67
147
|
|
|
68
148
|
---
|
|
69
149
|
|
|
70
|
-
|
|
150
|
+
## 🕸️ Network
|
|
151
|
+
|
|
152
|
+
### fetchWith
|
|
153
|
+
|
|
154
|
+
A wrapper around the native `fetch` API that supports a mobile User-Agent spoofing and automatic response parsing.
|
|
155
|
+
|
|
156
|
+
* **Input**: `input: string`, `options: { type?: 'json' | 'html' | 'text', mobile?: boolean, init?: RequestInit }`
|
|
157
|
+
* **Output**: `Promise<any>`
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
const data = await fetchWith("https://api.example.com/data", {
|
|
161
|
+
type: "json",
|
|
162
|
+
mobile: true
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
```
|
|
71
166
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
167
|
+
### fetchHtml / fetchJson / fetchText
|
|
168
|
+
|
|
169
|
+
Shorthand functions for `fetchWith` with specific return types.
|
|
170
|
+
|
|
171
|
+
* **Input**: `input: string`
|
|
172
|
+
* **Output**: `Promise<HTMLElement | object | string>`
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
const doc = await fetchHtml("https://example.com")
|
|
176
|
+
const json = await fetchJson("https://api.example.com")
|
|
177
|
+
|
|
178
|
+
```
|
|
77
179
|
|
|
78
180
|
---
|
|
79
181
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
182
|
+
## 🌲 DOM Manipulation
|
|
183
|
+
|
|
184
|
+
### parseHtml
|
|
185
|
+
|
|
186
|
+
Parses a raw HTML string and returns a DOM element (or body if multiple children exist).
|
|
187
|
+
|
|
188
|
+
* **Input**: `html: string`
|
|
189
|
+
* **Output**: `HTMLElement`
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
const element = parseHtml("<div><span>Hello</span></div>")
|
|
193
|
+
document.body.append(element)
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### querySelectorLast
|
|
198
|
+
|
|
199
|
+
Selects the last element matching a selector within a root.
|
|
200
|
+
|
|
201
|
+
* **Input**: `root?: ParentNode`, `selector: string`
|
|
202
|
+
* **Output**: `Element | undefined`
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
const lastItem = querySelectorLast(document, ".list-item")
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### querySelectorText
|
|
210
|
+
|
|
211
|
+
Safely extracts and sanitizes the inner text of an element matching the selector.
|
|
212
|
+
|
|
213
|
+
* **Input**: `e: Element`, `selector: string`
|
|
214
|
+
* **Output**: `string`
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
const title = querySelectorText(document.body, "h1.main-title")
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### replaceElementTag
|
|
222
|
+
|
|
223
|
+
Replaces an existing DOM element with a new element of a different tag name, preserving attributes and content.
|
|
224
|
+
|
|
225
|
+
* **Input**: `e: Element`, `tagName: string`
|
|
226
|
+
* **Output**: `Element` (the new element)
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
const oldDiv = document.querySelector("#container")
|
|
230
|
+
const newSection = replaceElementTag(oldDiv, "section")
|
|
231
|
+
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### instantiateTemplate
|
|
235
|
+
|
|
236
|
+
Creates a DOM element from a selector, updating specific attributes and text content during cloning.
|
|
237
|
+
|
|
238
|
+
* **Input**: `sourceSelector: string`, `attributeUpdates: object`, `contentUpdates: object`
|
|
239
|
+
* **Output**: `string` (innerHTML of the wrapper)
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
const html = instantiateTemplate(
|
|
243
|
+
"#card-template",
|
|
244
|
+
{ "data-id": "123" },
|
|
245
|
+
{ ".card-title": "New Item" }
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## 👁️ DOM Observers
|
|
253
|
+
|
|
254
|
+
### waitForElementToAppear
|
|
255
|
+
|
|
256
|
+
Watches the DOM until an element matching the selector appears, then executes a callback.
|
|
257
|
+
|
|
258
|
+
* **Input**: `parent: Node`, `selector: string`, `callback: (el: Element) => void`
|
|
259
|
+
* **Output**: `MutationObserver`
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
waitForElementToAppear(document.body, ".modal-popup", (modal) => {
|
|
263
|
+
console.log("Modal is ready", modal)
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### waitForElementToDisappear
|
|
269
|
+
|
|
270
|
+
Watches an element and triggers a callback when it is removed from the DOM.
|
|
271
|
+
|
|
272
|
+
* **Input**: `observable: Element`, `callback: () => void`
|
|
273
|
+
* **Output**: `MutationObserver`
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
const loadingSpinner = document.querySelector("#spinner")
|
|
277
|
+
waitForElementToDisappear(loadingSpinner, () => {
|
|
278
|
+
console.log("Loading finished")
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### watchDomChangesWithThrottle
|
|
284
|
+
|
|
285
|
+
Observes DOM changes and executes a callback with a throttle (rate limit).
|
|
286
|
+
|
|
287
|
+
* **Input**: `element: Node`, `callback: () => void`, `throttle?: number`
|
|
288
|
+
* **Output**: `MutationObserver`
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
watchDomChangesWithThrottle(document.body, () => {
|
|
292
|
+
console.log("DOM changed")
|
|
293
|
+
}, 500)
|
|
294
|
+
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## 🧬 Objects & Logic
|
|
300
|
+
|
|
301
|
+
### memoize
|
|
302
|
+
|
|
303
|
+
Creates a function that caches the result of calls with identical arguments.
|
|
304
|
+
|
|
305
|
+
* **Input**: `fn: Function`
|
|
306
|
+
* **Output**: `Function`
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
const heavyCalc = (x) => x * x
|
|
310
|
+
const cachedCalc = memoize(heavyCalc)
|
|
311
|
+
cachedCalc(5)
|
|
312
|
+
cachedCalc(5)
|
|
313
|
+
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### propsDifference
|
|
317
|
+
|
|
318
|
+
Compares two objects and returns the property names that are unique to each.
|
|
319
|
+
|
|
320
|
+
* **Input**: `obj1: object`, `obj2: object`
|
|
321
|
+
* **Output**: `{ d1: string[], d2: string[] }`
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
const diff = propsDifference({ a: 1, b: 2 }, { b: 3, c: 4 })
|
|
325
|
+
console.log(diff)
|
|
326
|
+
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### objectToFormData
|
|
330
|
+
|
|
331
|
+
Converts a plain JavaScript object into a `FormData` object.
|
|
332
|
+
|
|
333
|
+
* **Input**: `obj: Record<string, any>`
|
|
334
|
+
* **Output**: `FormData`
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
const form = objectToFormData({ username: "admin", file: blob })
|
|
338
|
+
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## 🛠️ Specialized Classes
|
|
344
|
+
|
|
345
|
+
### RegexFilter
|
|
346
|
+
|
|
347
|
+
A utility to compile and test strings against complex filter queries (supports OR logic, full-word search, and regex prefixes).
|
|
348
|
+
|
|
349
|
+
* **Usage**: Create with a query string, then use `hasEvery` or `hasNone`.
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
const filter = new RegexFilter("dog, cat, f:bird")
|
|
353
|
+
const isMatch = filter.hasEvery("I have a dog and a bird")
|
|
354
|
+
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### OnHover
|
|
358
|
+
|
|
359
|
+
Handles complex hover interactions, including tracking when the pointer leaves a specific subject.
|
|
360
|
+
|
|
361
|
+
* **Usage**: Instantiate with a container and a subject selector.
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
OnHover.create(
|
|
365
|
+
document.body,
|
|
366
|
+
(el) => el.classList.contains("tooltip-target"),
|
|
367
|
+
(target) => {
|
|
368
|
+
console.log("Hovering", target)
|
|
369
|
+
return {
|
|
370
|
+
onOverCallback: () => console.log("Finally block")
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
)
|
|
374
|
+
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### LazyImgLoader
|
|
378
|
+
|
|
379
|
+
Manages lazy loading of images by observing intersection and swapping data attributes for source URLs.
|
|
380
|
+
|
|
381
|
+
* **Usage**: Use `lazify` to setup an image and `delazify` to load it immediately.
|
|
382
|
+
|
|
383
|
+
```typescript
|
|
384
|
+
const loader = new LazyImgLoader((target) => true)
|
|
385
|
+
const img = document.querySelector("img")
|
|
386
|
+
loader.lazify(img, "https://example.com/image.jpg")
|
|
387
|
+
|
|
388
|
+
```
|