billy-herrington-utils 1.0.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 +34 -0
- package/biome.json +35 -0
- package/dist/billy-herrington-utils.es.js +242 -0
- package/dist/billy-herrington-utils.umd.js +1 -0
- package/index.html +24 -0
- package/package.json +34 -0
- package/src/index.ts +20 -0
- package/src/utils/arrays/index.ts +11 -0
- package/src/utils/async/index.ts +54 -0
- package/src/utils/device/index.ts +3 -0
- package/src/utils/dom/index.ts +92 -0
- package/src/utils/events/index.ts +37 -0
- package/src/utils/fetch/index.ts +22 -0
- package/src/utils/math/index.ts +3 -0
- package/src/utils/observers/index.ts +67 -0
- package/src/utils/parsers/index.ts +24 -0
- package/src/utils/strings/index.ts +7 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.json +23 -0
- package/vite.config.js +27 -0
package/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
### _daddy told us not to be ashamed of our utils_
|
|
2
|
+

|
|
3
|
+
|
|
4
|
+
* stringToWords
|
|
5
|
+
* sanitizeStr
|
|
6
|
+
* timeToSeconds
|
|
7
|
+
* parseCSSUrl
|
|
8
|
+
* parseDataParams
|
|
9
|
+
* parseIntegerOr
|
|
10
|
+
* Observer
|
|
11
|
+
* LazyImgLoader
|
|
12
|
+
* circularShift
|
|
13
|
+
* MOBILE_UA
|
|
14
|
+
* fetchHtml
|
|
15
|
+
* fetchText
|
|
16
|
+
* fetchWith
|
|
17
|
+
* objectToFormData
|
|
18
|
+
* Tick
|
|
19
|
+
* listenEvents
|
|
20
|
+
* parseDom
|
|
21
|
+
* copyAttributes
|
|
22
|
+
* downloader
|
|
23
|
+
* findNextSibling
|
|
24
|
+
* getAllUniqueParents
|
|
25
|
+
* replaceElementTag
|
|
26
|
+
* waitForElementExists
|
|
27
|
+
* watchDomChangesWithThrottle
|
|
28
|
+
* watchElementChildrenCount
|
|
29
|
+
* isMob
|
|
30
|
+
* computeAsyncOneAtTime
|
|
31
|
+
* SyncPull
|
|
32
|
+
* wait
|
|
33
|
+
* chunks
|
|
34
|
+
* range
|
package/biome.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/1.8.3/schema.json",
|
|
3
|
+
"organizeImports": {
|
|
4
|
+
"enabled": true
|
|
5
|
+
},
|
|
6
|
+
"formatter": {
|
|
7
|
+
"enabled": true,
|
|
8
|
+
"indentWidth": 2,
|
|
9
|
+
"indentStyle": "space",
|
|
10
|
+
"lineWidth": 100,
|
|
11
|
+
"lineEnding": "lf"
|
|
12
|
+
},
|
|
13
|
+
"javascript": {
|
|
14
|
+
"formatter": {
|
|
15
|
+
"quoteStyle": "single",
|
|
16
|
+
"semicolons": "always"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"linter": {
|
|
20
|
+
"enabled": true,
|
|
21
|
+
"rules": {
|
|
22
|
+
"recommended": true,
|
|
23
|
+
"style": {
|
|
24
|
+
"useNumberNamespace": "off"
|
|
25
|
+
},
|
|
26
|
+
"complexity": {
|
|
27
|
+
"noStaticOnlyClass": "off",
|
|
28
|
+
"noForEach": "off"
|
|
29
|
+
},
|
|
30
|
+
"suspicious": {
|
|
31
|
+
"noRedundantUseStrict": "off"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
var b = Object.defineProperty;
|
|
2
|
+
var d = (e, t, r) => t in e ? b(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r;
|
|
3
|
+
var o = (e, t, r) => d(e, typeof t != "symbol" ? t + "" : t, r);
|
|
4
|
+
function I(e) {
|
|
5
|
+
return e.split(",").map((t) => t.trim().toLowerCase()).filter((t) => t);
|
|
6
|
+
}
|
|
7
|
+
function A(e) {
|
|
8
|
+
return (e == null ? void 0 : e.replace(/\n|\t/, " ").replace(/ {2,}/, " ").trim().toLowerCase()) || "";
|
|
9
|
+
}
|
|
10
|
+
function E(e) {
|
|
11
|
+
return ((e == null ? void 0 : e.match(/\d+/gm)) || [0]).reverse().map((t, r) => parseInt(t) * 60 ** r).reduce((t, r) => t + r);
|
|
12
|
+
}
|
|
13
|
+
function T(e, t) {
|
|
14
|
+
return Number.isInteger(parseInt(e)) ? parseInt(e) : t;
|
|
15
|
+
}
|
|
16
|
+
function L(e) {
|
|
17
|
+
const t = e.split(";").flatMap((r) => {
|
|
18
|
+
const n = r.match(/([\+\w+]+):(\w+)?/), i = n == null ? void 0 : n[2];
|
|
19
|
+
if (i) return n[1].split("+").map((s) => ({ [s]: i }));
|
|
20
|
+
}).filter((r) => r);
|
|
21
|
+
return Object.assign({}, ...t);
|
|
22
|
+
}
|
|
23
|
+
function O(e) {
|
|
24
|
+
return e.replace(/url\("|\"\).*/g, "");
|
|
25
|
+
}
|
|
26
|
+
class l {
|
|
27
|
+
constructor(t) {
|
|
28
|
+
o(this, "observer");
|
|
29
|
+
this.callback = t, this.observer = new IntersectionObserver(this.handleIntersection.bind(this));
|
|
30
|
+
}
|
|
31
|
+
observe(t) {
|
|
32
|
+
this.observer.observe(t);
|
|
33
|
+
}
|
|
34
|
+
throttle(t, r) {
|
|
35
|
+
this.observer.unobserve(t), setTimeout(() => this.observer.observe(t), r);
|
|
36
|
+
}
|
|
37
|
+
handleIntersection(t) {
|
|
38
|
+
for (const r of t)
|
|
39
|
+
r.isIntersecting && this.callback(r.target);
|
|
40
|
+
}
|
|
41
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
42
|
+
static observeWhile(t, r, n) {
|
|
43
|
+
const i = new l(async (s) => {
|
|
44
|
+
await r() && i.throttle(s, n);
|
|
45
|
+
});
|
|
46
|
+
return i.observe(t), i;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
class u {
|
|
50
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
51
|
+
constructor(t, r = "data-lazy-load", n = !0) {
|
|
52
|
+
o(this, "lazyImgObserver");
|
|
53
|
+
o(this, "delazify", (t) => {
|
|
54
|
+
this.lazyImgObserver.observer.unobserve(t), t.src = t.getAttribute(this.attributeName), this.removeTagAfter && t.removeAttribute(this.attributeName);
|
|
55
|
+
});
|
|
56
|
+
this.attributeName = r, this.removeTagAfter = n, this.lazyImgObserver = new l((i) => {
|
|
57
|
+
t(i, this.delazify);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
lazify(t, r, n) {
|
|
61
|
+
!r || !n || (r.setAttribute(this.attributeName, n), r.src = "", this.lazyImgObserver.observe(r));
|
|
62
|
+
}
|
|
63
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
64
|
+
static create(t) {
|
|
65
|
+
return new u((n, i) => {
|
|
66
|
+
t(n) && i(n);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function M(e, t = 6, r = 1) {
|
|
71
|
+
return (e + r) % t || t;
|
|
72
|
+
}
|
|
73
|
+
function h(e) {
|
|
74
|
+
const t = new DOMParser().parseFromString(e, "text/html").body;
|
|
75
|
+
return t.children.length > 1 ? t : t.firstElementChild;
|
|
76
|
+
}
|
|
77
|
+
function m(e, t) {
|
|
78
|
+
for (const r of t.attributes)
|
|
79
|
+
r.nodeValue && e.setAttribute(r.nodeName, r.nodeValue);
|
|
80
|
+
}
|
|
81
|
+
function S(e, t) {
|
|
82
|
+
var n;
|
|
83
|
+
const r = document.createElement(t);
|
|
84
|
+
return m(r, e), r.innerHTML = e.innerHTML, (n = e.parentNode) == null || n.replaceChild(r, e), r;
|
|
85
|
+
}
|
|
86
|
+
function z(e) {
|
|
87
|
+
return Array.from(e).reduce((t, r) => (r.parentElement && t.includes(r.parentElement) && t.push(r.parentElement), t), []);
|
|
88
|
+
}
|
|
89
|
+
function p(e) {
|
|
90
|
+
return e.nextElementSibling ? e.nextElementSibling : e.parentElement ? p(e.parentElement) : null;
|
|
91
|
+
}
|
|
92
|
+
function v(e, t, r) {
|
|
93
|
+
const n = new MutationObserver((i) => {
|
|
94
|
+
const s = e.querySelector(t);
|
|
95
|
+
s && (n.disconnect(), r(s));
|
|
96
|
+
});
|
|
97
|
+
n.observe(document.body, { childList: !0, subtree: !0 });
|
|
98
|
+
}
|
|
99
|
+
function F(e, t) {
|
|
100
|
+
let r = e.children.length;
|
|
101
|
+
new MutationObserver((i, s) => {
|
|
102
|
+
for (const a of i)
|
|
103
|
+
a.type === "childList" && r !== e.children.length && (r = e.children.length, t(s, r));
|
|
104
|
+
}).observe(e, { childList: !0 });
|
|
105
|
+
}
|
|
106
|
+
function P(e, t, r = 1e3, n = { childList: !0, subtree: !0, attributes: !0 }) {
|
|
107
|
+
let i, s;
|
|
108
|
+
new MutationObserver((y, w) => {
|
|
109
|
+
const c = Date.now();
|
|
110
|
+
i && c - i < r && s && clearTimeout(s), s = setTimeout(t, r), i = c;
|
|
111
|
+
}).observe(e, n);
|
|
112
|
+
}
|
|
113
|
+
function x(e = { append: "", after: "", button: "", cbBefore: () => {
|
|
114
|
+
} }) {
|
|
115
|
+
var r, n;
|
|
116
|
+
const t = h(e.button);
|
|
117
|
+
e.append && ((r = document.querySelector(e.append)) == null || r.append(t)), e.after && ((n = document.querySelector(e.after)) == null || n.after(t)), t.addEventListener("click", (i) => {
|
|
118
|
+
i.preventDefault(), e.cbBefore && e.cbBefore(), v(document.body, "video", (s) => {
|
|
119
|
+
window.location.href = s.getAttribute("src");
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
const g = [
|
|
124
|
+
"Mozilla/5.0 (Linux; Android 10; K)",
|
|
125
|
+
"AppleWebKit/537.36 (KHTML, like Gecko)",
|
|
126
|
+
"Chrome/114.0.0.0 Mobile Safari/537.36"
|
|
127
|
+
].join(" ");
|
|
128
|
+
function f(e, t = { html: !1, mobile: !1 }) {
|
|
129
|
+
const r = {};
|
|
130
|
+
return t.mobile && Object.assign(r, { headers: new Headers({ "User-Agent": g }) }), fetch(e, r).then((n) => n.text()).then((n) => t.html ? h(n) : n);
|
|
131
|
+
}
|
|
132
|
+
const C = (e) => f(e, { html: !0 }), D = (e) => f(e);
|
|
133
|
+
function H(e) {
|
|
134
|
+
const t = new FormData();
|
|
135
|
+
return Object.entries(e).forEach(([r, n]) => t.append(r, n)), t;
|
|
136
|
+
}
|
|
137
|
+
function N(e, t, r) {
|
|
138
|
+
for (const n of t)
|
|
139
|
+
e.addEventListener(n, r, !0);
|
|
140
|
+
}
|
|
141
|
+
class j {
|
|
142
|
+
constructor(t, r = !0) {
|
|
143
|
+
o(this, "tick");
|
|
144
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
145
|
+
o(this, "callbackFinal");
|
|
146
|
+
this.delay = t, this.startImmediate = r, this.tick = null, this.delay = t, this.startImmediate = r;
|
|
147
|
+
}
|
|
148
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
149
|
+
start(t, r = null) {
|
|
150
|
+
this.stop(), this.callbackFinal = r, this.startImmediate && t(), this.tick = setInterval(t, this.delay);
|
|
151
|
+
}
|
|
152
|
+
stop() {
|
|
153
|
+
this.tick !== null && (clearInterval(this.tick), this.tick = null), this.callbackFinal && (this.callbackFinal(), this.callbackFinal = null);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function q() {
|
|
157
|
+
return /iPhone|Android/i.test(navigator.userAgent);
|
|
158
|
+
}
|
|
159
|
+
async function W(e) {
|
|
160
|
+
const t = [];
|
|
161
|
+
for await (const r of e)
|
|
162
|
+
t.push(await r());
|
|
163
|
+
return t;
|
|
164
|
+
}
|
|
165
|
+
function B(e) {
|
|
166
|
+
return new Promise((t) => setTimeout(t, e));
|
|
167
|
+
}
|
|
168
|
+
class U {
|
|
169
|
+
constructor() {
|
|
170
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
171
|
+
o(this, "pull", []);
|
|
172
|
+
o(this, "lock", !1);
|
|
173
|
+
}
|
|
174
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
175
|
+
getHighPriorityFirst(t = 0) {
|
|
176
|
+
if (t > 3 || this.pull.length === 0) return;
|
|
177
|
+
const r = this.pull.findIndex((n) => n.p === t);
|
|
178
|
+
if (r >= 0) {
|
|
179
|
+
const n = this.pull[r].v;
|
|
180
|
+
return this.pull = this.pull.slice(0, r).concat(this.pull.slice(r + 1)), n;
|
|
181
|
+
}
|
|
182
|
+
return this.getHighPriorityFirst(t + 1);
|
|
183
|
+
}
|
|
184
|
+
*pullGenerator() {
|
|
185
|
+
for (; this.pull.length > 0; )
|
|
186
|
+
yield this.getHighPriorityFirst();
|
|
187
|
+
}
|
|
188
|
+
async processPull() {
|
|
189
|
+
if (!this.lock) {
|
|
190
|
+
this.lock = !0;
|
|
191
|
+
for await (const t of this.pullGenerator())
|
|
192
|
+
await t();
|
|
193
|
+
this.lock = !1;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
197
|
+
push(t) {
|
|
198
|
+
this.pull.push(t), this.processPull();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function _(e, t) {
|
|
202
|
+
const r = [];
|
|
203
|
+
for (let n = 0; n < e.length; n += t)
|
|
204
|
+
r.push(e.slice(n, n + t));
|
|
205
|
+
return r;
|
|
206
|
+
}
|
|
207
|
+
function G(e, t = 1) {
|
|
208
|
+
return [...Array(e).keys()].map((r) => r + t);
|
|
209
|
+
}
|
|
210
|
+
export {
|
|
211
|
+
u as LazyImgLoader,
|
|
212
|
+
g as MOBILE_UA,
|
|
213
|
+
l as Observer,
|
|
214
|
+
U as SyncPull,
|
|
215
|
+
j as Tick,
|
|
216
|
+
_ as chunks,
|
|
217
|
+
M as circularShift,
|
|
218
|
+
W as computeAsyncOneAtTime,
|
|
219
|
+
m as copyAttributes,
|
|
220
|
+
x as downloader,
|
|
221
|
+
C as fetchHtml,
|
|
222
|
+
D as fetchText,
|
|
223
|
+
f as fetchWith,
|
|
224
|
+
p as findNextSibling,
|
|
225
|
+
z as getAllUniqueParents,
|
|
226
|
+
q as isMob,
|
|
227
|
+
N as listenEvents,
|
|
228
|
+
H as objectToFormData,
|
|
229
|
+
O as parseCSSUrl,
|
|
230
|
+
L as parseDataParams,
|
|
231
|
+
h as parseDom,
|
|
232
|
+
T as parseIntegerOr,
|
|
233
|
+
G as range,
|
|
234
|
+
S as replaceElementTag,
|
|
235
|
+
A as sanitizeStr,
|
|
236
|
+
I as stringToWords,
|
|
237
|
+
E as timeToSeconds,
|
|
238
|
+
B as wait,
|
|
239
|
+
v as waitForElementExists,
|
|
240
|
+
P as watchDomChangesWithThrottle,
|
|
241
|
+
F as watchElementChildrenCount
|
|
242
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(i,l){typeof exports=="object"&&typeof module<"u"?l(exports):typeof define=="function"&&define.amd?define(["exports"],l):(i=typeof globalThis<"u"?globalThis:i||self,l(i.bhutils={}))})(this,function(i){"use strict";var B=Object.defineProperty;var _=(i,l,c)=>l in i?B(i,l,{enumerable:!0,configurable:!0,writable:!0,value:c}):i[l]=c;var o=(i,l,c)=>_(i,typeof l!="symbol"?l+"":l,c);function l(n){return n.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e)}function c(n){return(n==null?void 0:n.replace(/\n|\t/," ").replace(/ {2,}/," ").trim().toLowerCase())||""}function w(n){return((n==null?void 0:n.match(/\d+/gm))||[0]).reverse().map((e,t)=>parseInt(e)*60**t).reduce((e,t)=>e+t)}function T(n,e){return Number.isInteger(parseInt(n))?parseInt(n):e}function E(n){const e=n.split(";").flatMap(t=>{const r=t.match(/([\+\w+]+):(\w+)?/),s=r==null?void 0:r[2];if(s)return r[1].split("+").map(a=>({[a]:s}))}).filter(t=>t);return Object.assign({},...e)}function k(n){return n.replace(/url\("|\"\).*/g,"")}class u{constructor(e){o(this,"observer");this.callback=e,this.observer=new IntersectionObserver(this.handleIntersection.bind(this))}observe(e){this.observer.observe(e)}throttle(e,t){this.observer.unobserve(e),setTimeout(()=>this.observer.observe(e),t)}handleIntersection(e){for(const t of e)t.isIntersecting&&this.callback(t.target)}static observeWhile(e,t,r){const s=new u(async a=>{await t()&&s.throttle(a,r)});return s.observe(e),s}}class h{constructor(e,t="data-lazy-load",r=!0){o(this,"lazyImgObserver");o(this,"delazify",e=>{this.lazyImgObserver.observer.unobserve(e),e.src=e.getAttribute(this.attributeName),this.removeTagAfter&&e.removeAttribute(this.attributeName)});this.attributeName=t,this.removeTagAfter=r,this.lazyImgObserver=new u(s=>{e(s,this.delazify)})}lazify(e,t,r){!t||!r||(t.setAttribute(this.attributeName,r),t.src="",this.lazyImgObserver.observe(t))}static create(e){return new h((r,s)=>{e(r)&&s(r)})}}function A(n,e=6,t=1){return(n+t)%e||e}function f(n){const e=new DOMParser().parseFromString(n,"text/html").body;return e.children.length>1?e:e.firstElementChild}function m(n,e){for(const t of e.attributes)t.nodeValue&&n.setAttribute(t.nodeName,t.nodeValue)}function I(n,e){var r;const t=document.createElement(e);return m(t,n),t.innerHTML=n.innerHTML,(r=n.parentNode)==null||r.replaceChild(t,n),t}function S(n){return Array.from(n).reduce((e,t)=>(t.parentElement&&e.includes(t.parentElement)&&e.push(t.parentElement),e),[])}function v(n){return n.nextElementSibling?n.nextElementSibling:n.parentElement?v(n.parentElement):null}function g(n,e,t){const r=new MutationObserver(s=>{const a=n.querySelector(e);a&&(r.disconnect(),t(a))});r.observe(document.body,{childList:!0,subtree:!0})}function O(n,e){let t=n.children.length;new MutationObserver((s,a)=>{for(const b of s)b.type==="childList"&&t!==n.children.length&&(t=n.children.length,e(a,t))}).observe(n,{childList:!0})}function L(n,e,t=1e3,r={childList:!0,subtree:!0,attributes:!0}){let s,a;new MutationObserver((G,K)=>{const y=Date.now();s&&y-s<t&&a&&clearTimeout(a),a=setTimeout(e,t),s=y}).observe(n,r)}function M(n={append:"",after:"",button:"",cbBefore:()=>{}}){var t,r;const e=f(n.button);n.append&&((t=document.querySelector(n.append))==null||t.append(e)),n.after&&((r=document.querySelector(n.after))==null||r.after(e)),e.addEventListener("click",s=>{s.preventDefault(),n.cbBefore&&n.cbBefore(),g(document.body,"video",a=>{window.location.href=a.getAttribute("src")})})}const p=["Mozilla/5.0 (Linux; Android 10; K)","AppleWebKit/537.36 (KHTML, like Gecko)","Chrome/114.0.0.0 Mobile Safari/537.36"].join(" ");function d(n,e={html:!1,mobile:!1}){const t={};return e.mobile&&Object.assign(t,{headers:new Headers({"User-Agent":p})}),fetch(n,t).then(r=>r.text()).then(r=>e.html?f(r):r)}const P=n=>d(n,{html:!0}),z=n=>d(n);function F(n){const e=new FormData;return Object.entries(n).forEach(([t,r])=>e.append(t,r)),e}function C(n,e,t){for(const r of e)n.addEventListener(r,t,!0)}class D{constructor(e,t=!0){o(this,"tick");o(this,"callbackFinal");this.delay=e,this.startImmediate=t,this.tick=null,this.delay=e,this.startImmediate=t}start(e,t=null){this.stop(),this.callbackFinal=t,this.startImmediate&&e(),this.tick=setInterval(e,this.delay)}stop(){this.tick!==null&&(clearInterval(this.tick),this.tick=null),this.callbackFinal&&(this.callbackFinal(),this.callbackFinal=null)}}function H(){return/iPhone|Android/i.test(navigator.userAgent)}async function N(n){const e=[];for await(const t of n)e.push(await t());return e}function j(n){return new Promise(e=>setTimeout(e,n))}class W{constructor(){o(this,"pull",[]);o(this,"lock",!1)}getHighPriorityFirst(e=0){if(e>3||this.pull.length===0)return;const t=this.pull.findIndex(r=>r.p===e);if(t>=0){const r=this.pull[t].v;return this.pull=this.pull.slice(0,t).concat(this.pull.slice(t+1)),r}return this.getHighPriorityFirst(e+1)}*pullGenerator(){for(;this.pull.length>0;)yield this.getHighPriorityFirst()}async processPull(){if(!this.lock){this.lock=!0;for await(const e of this.pullGenerator())await e();this.lock=!1}}push(e){this.pull.push(e),this.processPull()}}function U(n,e){const t=[];for(let r=0;r<n.length;r+=e)t.push(n.slice(r,r+e));return t}function q(n,e=1){return[...Array(n).keys()].map(t=>t+e)}i.LazyImgLoader=h,i.MOBILE_UA=p,i.Observer=u,i.SyncPull=W,i.Tick=D,i.chunks=U,i.circularShift=A,i.computeAsyncOneAtTime=N,i.copyAttributes=m,i.downloader=M,i.fetchHtml=P,i.fetchText=z,i.fetchWith=d,i.findNextSibling=v,i.getAllUniqueParents=S,i.isMob=H,i.listenEvents=C,i.objectToFormData=F,i.parseCSSUrl=k,i.parseDataParams=E,i.parseDom=f,i.parseIntegerOr=T,i.range=q,i.replaceElementTag=I,i.sanitizeStr=c,i.stringToWords=l,i.timeToSeconds=w,i.wait=j,i.waitForElementExists=g,i.watchDomChangesWithThrottle=L,i.watchElementChildrenCount=O,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})});
|
package/index.html
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Document</title>
|
|
8
|
+
<style>
|
|
9
|
+
body {
|
|
10
|
+
background: radial-gradient(red, green, blue);
|
|
11
|
+
height: 100vh;
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
margin: 0;
|
|
14
|
+
}
|
|
15
|
+
</style>
|
|
16
|
+
<script src="./dist/billy-herrington-utils.umd.js"></script>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<script>
|
|
21
|
+
</script>
|
|
22
|
+
</body>
|
|
23
|
+
|
|
24
|
+
</html>
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "billy-herrington-utils",
|
|
3
|
+
"description": "daddy told us not to be ashamed of our utils",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"keywords": ["utils", "observer", "dom", "fetch", "arrays"],
|
|
7
|
+
"author": "smartacephale atm.mormon@protonmail.com (https://github.com/smartacephale)",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"homepage": "https://github.com/smartacephale/billy-herrington-utils#readme",
|
|
10
|
+
"main": "./dist/billy-herrington-utils.umd.js",
|
|
11
|
+
"module": "./dist/billy-herrington-utils.es.js",
|
|
12
|
+
"repository": "github:smartacephale/billy-herrington-utils",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/smartacephale/billy-herrington-utils/issues",
|
|
15
|
+
"email": "atm.mormon@protonmail.com"
|
|
16
|
+
},
|
|
17
|
+
"browser": "./dist/billy-herrington-utils.es.js",
|
|
18
|
+
"unpkg": "./dist/billy-herrington-utils.es.js",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"import": "./dist/billy-herrington-utils.es.js",
|
|
22
|
+
"require": "./dist/billy-herrington-utils.umd.cjs"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"dev": "vite",
|
|
27
|
+
"build": "tsc && vite build",
|
|
28
|
+
"preview": "vite preview"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"typescript": "^5.5.3",
|
|
32
|
+
"vite": "^5.4.0"
|
|
33
|
+
}
|
|
34
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export { stringToWords, sanitizeStr } from "./utils/strings";
|
|
2
|
+
export { timeToSeconds, parseCSSUrl, parseDataParams, parseIntegerOr } from "./utils/parsers";
|
|
3
|
+
export { Observer, LazyImgLoader } from "./utils/observers";
|
|
4
|
+
export { circularShift } from "./utils/math";
|
|
5
|
+
export { MOBILE_UA, fetchHtml, fetchText, fetchWith, objectToFormData } from "./utils/fetch";
|
|
6
|
+
export { Tick, listenEvents } from "./utils/events";
|
|
7
|
+
export {
|
|
8
|
+
parseDom,
|
|
9
|
+
copyAttributes,
|
|
10
|
+
downloader,
|
|
11
|
+
findNextSibling,
|
|
12
|
+
getAllUniqueParents,
|
|
13
|
+
replaceElementTag,
|
|
14
|
+
waitForElementExists,
|
|
15
|
+
watchDomChangesWithThrottle,
|
|
16
|
+
watchElementChildrenCount
|
|
17
|
+
} from "./utils/dom";
|
|
18
|
+
export { isMob } from "./utils/device";
|
|
19
|
+
export { computeAsyncOneAtTime, SyncPull, wait } from "./utils/async";
|
|
20
|
+
export { chunks, range } from "./utils/arrays";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function chunks<T>(arr: Array<T>, n: number): Array<Array<T>> {
|
|
2
|
+
const res = [];
|
|
3
|
+
for (let i = 0; i < arr.length; i += n) {
|
|
4
|
+
res.push(arr.slice(i, i + n));
|
|
5
|
+
}
|
|
6
|
+
return res;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function range(size: number, startAt = 1): Array<number> {
|
|
10
|
+
return [...Array(size).keys()].map(i => i + startAt);
|
|
11
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// https://2ality.com/2016/10/asynchronous-iteration.html
|
|
2
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
3
|
+
export async function computeAsyncOneAtTime(iterable: Iterable<any>) {
|
|
4
|
+
const res = [];
|
|
5
|
+
for await (const f of iterable) {
|
|
6
|
+
res.push(await f());
|
|
7
|
+
}
|
|
8
|
+
return res;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function wait(milliseconds: number) {
|
|
12
|
+
return new Promise(resolve => setTimeout(resolve, milliseconds));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// do async one at time
|
|
16
|
+
export class SyncPull {
|
|
17
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
18
|
+
pull: Array<any> = [];
|
|
19
|
+
lock = false;
|
|
20
|
+
|
|
21
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
22
|
+
getHighPriorityFirst(p = 0): any {
|
|
23
|
+
if (p > 3 || this.pull.length === 0) return undefined;
|
|
24
|
+
const i = this.pull.findIndex(e => e.p === p);
|
|
25
|
+
if (i >= 0) {
|
|
26
|
+
const res = this.pull[i].v;
|
|
27
|
+
this.pull = this.pull.slice(0, i).concat(this.pull.slice(i + 1));
|
|
28
|
+
return res;
|
|
29
|
+
}
|
|
30
|
+
return this.getHighPriorityFirst(p + 1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
*pullGenerator() {
|
|
34
|
+
while (this.pull.length > 0) {
|
|
35
|
+
yield this.getHighPriorityFirst();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async processPull() {
|
|
40
|
+
if (!this.lock) {
|
|
41
|
+
this.lock = true;
|
|
42
|
+
for await (const f of this.pullGenerator()) {
|
|
43
|
+
await f();
|
|
44
|
+
}
|
|
45
|
+
this.lock = false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
50
|
+
push(x: any) {
|
|
51
|
+
this.pull.push(x);
|
|
52
|
+
this.processPull();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export function parseDom(html: string): HTMLElement {
|
|
2
|
+
const parsed = new DOMParser().parseFromString(html, 'text/html').body;
|
|
3
|
+
return parsed.children.length > 1 ? parsed : parsed.firstElementChild as HTMLElement;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export function copyAttributes(target: HTMLElement | Element, source: HTMLElement | Element) {
|
|
7
|
+
for (const attr of source.attributes) {
|
|
8
|
+
attr.nodeValue && target.setAttribute(attr.nodeName, attr.nodeValue);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function replaceElementTag(e: HTMLElement | Element, tagName: string) {
|
|
13
|
+
const newTagElement = document.createElement(tagName);
|
|
14
|
+
copyAttributes(newTagElement, e);
|
|
15
|
+
newTagElement.innerHTML = e.innerHTML;
|
|
16
|
+
e.parentNode?.replaceChild(newTagElement, e);
|
|
17
|
+
return newTagElement;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function getAllUniqueParents(elements: HTMLCollection): Array<HTMLElement | Element> {
|
|
21
|
+
return Array.from(elements).reduce((acc, v) => {
|
|
22
|
+
if (v.parentElement && acc.includes(v.parentElement as HTMLElement)) { acc.push(v.parentElement); }
|
|
23
|
+
return acc;
|
|
24
|
+
}, [] as Array<HTMLElement | Element>);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function findNextSibling(el: HTMLElement | Element) {
|
|
28
|
+
if (el.nextElementSibling) return el.nextElementSibling;
|
|
29
|
+
if (el.parentElement) return findNextSibling(el.parentElement);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
34
|
+
export function waitForElementExists(parent: HTMLElement | Element, selector: string, callback: any): void {
|
|
35
|
+
const observer = new MutationObserver((_mutations) => {
|
|
36
|
+
const el = parent.querySelector(selector);
|
|
37
|
+
if (el) {
|
|
38
|
+
observer.disconnect();
|
|
39
|
+
callback(el);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
46
|
+
export function watchElementChildrenCount(element: HTMLElement | Element, callback: any): void {
|
|
47
|
+
let count = element.children.length;
|
|
48
|
+
const observer = new MutationObserver((mutationList, observer) => {
|
|
49
|
+
for (const mutation of mutationList) {
|
|
50
|
+
if (mutation.type === "childList") {
|
|
51
|
+
if (count !== element.children.length) {
|
|
52
|
+
count = element.children.length;
|
|
53
|
+
callback(observer, count);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
observer.observe(element, { childList: true });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
62
|
+
export function watchDomChangesWithThrottle(element: HTMLElement | Element, callback: any,
|
|
63
|
+
throttle = 1000, options: Record<string, boolean> = { childList: true, subtree: true, attributes: true }) {
|
|
64
|
+
let lastMutationTime: number;
|
|
65
|
+
let timeout: number;
|
|
66
|
+
const observer = new MutationObserver((_mutationList, _observer) => {
|
|
67
|
+
const now = Date.now();
|
|
68
|
+
if (lastMutationTime && now - lastMutationTime < throttle) {
|
|
69
|
+
timeout && clearTimeout(timeout);
|
|
70
|
+
}
|
|
71
|
+
timeout = setTimeout(callback, throttle);
|
|
72
|
+
lastMutationTime = now;
|
|
73
|
+
});
|
|
74
|
+
observer.observe(element, options);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function downloader(options = { append: "", after: "", button: "", cbBefore: () => { } }) {
|
|
78
|
+
const btn = parseDom(options.button);
|
|
79
|
+
|
|
80
|
+
if (options.append) document.querySelector(options.append)?.append(btn);
|
|
81
|
+
if (options.after) document.querySelector(options.after)?.after(btn);
|
|
82
|
+
|
|
83
|
+
btn.addEventListener('click', (e) => {
|
|
84
|
+
e.preventDefault();
|
|
85
|
+
|
|
86
|
+
if (options.cbBefore) options.cbBefore();
|
|
87
|
+
|
|
88
|
+
waitForElementExists(document.body, 'video', (video: HTMLVideoElement) => {
|
|
89
|
+
window.location.href = video.getAttribute('src') as string;
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
2
|
+
export function listenEvents(dom: HTMLElement | Element, events: Array<string>, callback: any): void {
|
|
3
|
+
for (const e of events) {
|
|
4
|
+
dom.addEventListener(e, callback, true);
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class Tick {
|
|
9
|
+
private tick: null | number;
|
|
10
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
11
|
+
private callbackFinal: any;
|
|
12
|
+
|
|
13
|
+
constructor(private delay: number, private startImmediate = true) {
|
|
14
|
+
this.tick = null;
|
|
15
|
+
this.delay = delay;
|
|
16
|
+
this.startImmediate = startImmediate;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
20
|
+
start(callback: any, callbackFinal = null) {
|
|
21
|
+
this.stop();
|
|
22
|
+
this.callbackFinal = callbackFinal;
|
|
23
|
+
if (this.startImmediate) callback();
|
|
24
|
+
this.tick = setInterval(callback, this.delay);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
stop() {
|
|
28
|
+
if (this.tick !== null) {
|
|
29
|
+
clearInterval(this.tick);
|
|
30
|
+
this.tick = null;
|
|
31
|
+
}
|
|
32
|
+
if (this.callbackFinal) {
|
|
33
|
+
this.callbackFinal();
|
|
34
|
+
this.callbackFinal = null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { parseDom } from "../dom";
|
|
2
|
+
|
|
3
|
+
export const MOBILE_UA = [
|
|
4
|
+
'Mozilla/5.0 (Linux; Android 10; K)',
|
|
5
|
+
'AppleWebKit/537.36 (KHTML, like Gecko)',
|
|
6
|
+
'Chrome/114.0.0.0 Mobile Safari/537.36'].join(' ');
|
|
7
|
+
|
|
8
|
+
export function fetchWith(url: string, options: Record<string, boolean> = { html: false, mobile: false }) {
|
|
9
|
+
const reqOpts = {};
|
|
10
|
+
if (options.mobile) Object.assign(reqOpts, { headers: new Headers({ "User-Agent": MOBILE_UA }) });
|
|
11
|
+
return fetch(url, reqOpts).then((r) => r.text()).then(r => options.html ? parseDom(r) : r);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const fetchHtml = (url: string) => fetchWith(url, { html: true });
|
|
15
|
+
|
|
16
|
+
export const fetchText = (url: string) => fetchWith(url);
|
|
17
|
+
|
|
18
|
+
export function objectToFormData(object: Record<string, number | boolean | string>): FormData {
|
|
19
|
+
const formData = new FormData();
|
|
20
|
+
Object.entries(object).forEach(([k, v]) => formData.append(k, v as string));
|
|
21
|
+
return formData;
|
|
22
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export class Observer {
|
|
2
|
+
public observer: IntersectionObserver;
|
|
3
|
+
constructor(private callback: (entry: Element) => void) {
|
|
4
|
+
this.observer = new IntersectionObserver(this.handleIntersection.bind(this));
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
observe(target: Element) {
|
|
8
|
+
this.observer.observe(target);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
throttle(target: Element, throttleTime: number) {
|
|
12
|
+
this.observer.unobserve(target);
|
|
13
|
+
setTimeout(() => this.observer.observe(target), throttleTime);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
handleIntersection(entries: Iterable<IntersectionObserverEntry>) {
|
|
17
|
+
for (const entry of entries) {
|
|
18
|
+
if (entry.isIntersecting) {
|
|
19
|
+
this.callback(entry.target);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
25
|
+
static observeWhile(target: Element, callback: any, throttleTime: number) {
|
|
26
|
+
const observer_ = new Observer(async (target: Element) => {
|
|
27
|
+
const condition = await callback();
|
|
28
|
+
if (condition) observer_.throttle(target, throttleTime);
|
|
29
|
+
});
|
|
30
|
+
observer_.observe(target);
|
|
31
|
+
return observer_;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class LazyImgLoader {
|
|
36
|
+
public lazyImgObserver: Observer;
|
|
37
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
38
|
+
constructor(callback: any, private attributeName = 'data-lazy-load', private removeTagAfter = true) {
|
|
39
|
+
this.lazyImgObserver = new Observer((target: Element) => {
|
|
40
|
+
callback(target, this.delazify);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
lazify(_target: Element, img: HTMLImageElement, imgSrc: string) {
|
|
45
|
+
if (!img || !imgSrc) return;
|
|
46
|
+
img.setAttribute(this.attributeName, imgSrc);
|
|
47
|
+
img.src = '';
|
|
48
|
+
this.lazyImgObserver.observe(img);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
delazify = (target: HTMLImageElement) => {
|
|
52
|
+
this.lazyImgObserver.observer.unobserve(target);
|
|
53
|
+
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;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export function timeToSeconds(t: string): number {
|
|
2
|
+
return (t?.match(/\d+/gm) || [0])
|
|
3
|
+
.reverse()
|
|
4
|
+
.map((s, i) => parseInt(s as string) * 60 ** i)
|
|
5
|
+
.reduce((a, b) => a + b);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function parseIntegerOr(n: string | number, or: number): number {
|
|
9
|
+
return Number.isInteger(parseInt(n as string)) ? parseInt(n as string) : or;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// "data:02;body+head:async;void:;zero:;"
|
|
13
|
+
export function parseDataParams(str: string) {
|
|
14
|
+
const params = str.split(';').flatMap(s => {
|
|
15
|
+
const parsed = s.match(/([\+\w+]+):(\w+)?/);
|
|
16
|
+
const value = parsed?.[2];
|
|
17
|
+
if (value) return parsed[1].split('+').map(p => ({ [p]: value }));
|
|
18
|
+
}).filter(_ => _);
|
|
19
|
+
return Object.assign({}, ...params);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function parseCSSUrl(s: string) {
|
|
23
|
+
return s.replace(/url\("|\"\).*/g, '');
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
|
|
9
|
+
/* Bundler mode */
|
|
10
|
+
"moduleResolution": "bundler",
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
12
|
+
"isolatedModules": true,
|
|
13
|
+
"moduleDetection": "force",
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
|
|
16
|
+
/* Linting */
|
|
17
|
+
"strict": true,
|
|
18
|
+
"noUnusedLocals": true,
|
|
19
|
+
"noUnusedParameters": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": true
|
|
21
|
+
},
|
|
22
|
+
"include": ["src", "main.js"]
|
|
23
|
+
}
|
package/vite.config.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { defineConfig, loadEnv } from "vite";
|
|
3
|
+
|
|
4
|
+
export default ({ mode }) => {
|
|
5
|
+
return defineConfig({
|
|
6
|
+
define: {
|
|
7
|
+
"process.env": {},
|
|
8
|
+
},
|
|
9
|
+
run: {
|
|
10
|
+
entry: path.resolve(__dirname, "./src/index.html")
|
|
11
|
+
},
|
|
12
|
+
resolve: {
|
|
13
|
+
alias: {
|
|
14
|
+
vue: 'vue/dist/vue.esm-bundler.js',
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
build: {
|
|
18
|
+
watch: false,
|
|
19
|
+
lib: {
|
|
20
|
+
minify: true,
|
|
21
|
+
entry: path.resolve(__dirname, "./src/index.ts"),
|
|
22
|
+
name: "bhutils",
|
|
23
|
+
fileName: (format) => `billy-herrington-utils.${format}.js`,
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
};
|