@splendidlabz/utils 1.7.0 → 1.8.2
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/CHANGELOG.md +18 -0
- package/dist/cjs/dom/font-size.cjs +1 -1
- package/dist/cjs/dom/index.cjs +91 -1
- package/dist/cjs/dom/observers/index.cjs +92 -2
- package/dist/cjs/dom/observers/scroll-observer.cjs +170 -0
- package/dist/cjs/lib/date/index.cjs +3 -1
- package/dist/cjs/lib/date/time.cjs +3 -1
- package/dist/cjs/lib/functions/functional.cjs +20 -0
- package/dist/cjs/lib/functions/index.cjs +20 -0
- package/dist/cjs/lib/index.cjs +27 -2
- package/dist/cjs/lib/numbers/index.cjs +1 -1
- package/dist/cjs/lib/objects/extend.cjs +2 -1
- package/dist/cjs/lib/objects/index.cjs +4 -1
- package/dist/cjs/lib/objects/mix/mix.cjs +4 -1
- package/dist/cjs/node/file-cache.cjs +3 -3
- package/dist/cjs/node/index.cjs +3 -3
- package/dist/esm/dom/font-size.js +1 -1
- package/dist/esm/dom/index.js +90 -1
- package/dist/esm/dom/observers/index.js +90 -1
- package/dist/esm/dom/observers/scroll-observer.js +144 -0
- package/dist/esm/lib/date/index.js +3 -1
- package/dist/esm/lib/date/time.js +3 -1
- package/dist/esm/lib/functions/functional.js +18 -0
- package/dist/esm/lib/functions/index.js +18 -0
- package/dist/esm/lib/index.js +24 -2
- package/dist/esm/lib/numbers/index.js +1 -1
- package/dist/esm/lib/objects/extend.js +2 -1
- package/dist/esm/lib/objects/index.js +3 -1
- package/dist/esm/lib/objects/mix/mix.js +3 -1
- package/dist/esm/node/file-cache.js +1 -1
- package/dist/esm/node/index.js +1 -1
- package/dist/types/dom/index.d.cts +1 -0
- package/dist/types/dom/observers/index.d.cts +1 -0
- package/dist/types/dom/observers/scroll-observer.d.cts +27 -0
- package/dist/types/lib/functions/functional.d.cts +71 -5
- package/dist/types/lib/functions/index.d.cts +1 -1
- package/dist/types/lib/index.d.cts +2 -2
- package/dist/types/lib/objects/extend.d.cts +1 -1
- package/dist/types/lib/objects/index.d.cts +1 -1
- package/dist/types/lib/objects/mix/mix.d.cts +43 -3
- package/package.json +2 -3
- package/src/dom/observers/index.js +1 -0
- package/src/dom/observers/resize-observer.js +5 -5
- package/src/dom/observers/scroll-observer.js +132 -0
- package/src/lib/date/time.js +2 -0
- package/src/lib/functions/functional.js +82 -0
- package/src/lib/functions/functional.test.js +196 -0
- package/src/lib/numbers/index.js +1 -1
- package/src/lib/numbers/split-unit.test.js +45 -0
- package/src/lib/objects/mix/mix.js +74 -4
- package/src/lib/objects/mix/mix.test.js +51 -2
- package/src/node/file-cache.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @splendidlabz/utils
|
|
2
2
|
|
|
3
|
+
## 1.8.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- - abd0770c Add pipeAsync and composeAsync along with tests
|
|
8
|
+
|
|
9
|
+
## 1.8.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Build
|
|
14
|
+
|
|
15
|
+
## 1.8.0
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- Several updates
|
|
20
|
+
|
|
3
21
|
## 1.7.0
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
|
@@ -30,7 +30,7 @@ module.exports = __toCommonJS(font_size_exports);
|
|
|
30
30
|
// src/lib/numbers/index.js
|
|
31
31
|
function splitUnit(string) {
|
|
32
32
|
if (typeof string === "number") return [string, null];
|
|
33
|
-
const regex = /(-?\d*\.?\d+)([a-z]+)/i;
|
|
33
|
+
const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i;
|
|
34
34
|
const match = string.match(regex);
|
|
35
35
|
if (match) return [parseFloat(match[1]), match[2]];
|
|
36
36
|
return [parseFloat(string), null];
|
package/dist/cjs/dom/index.cjs
CHANGED
|
@@ -79,6 +79,7 @@ __export(dom_exports, {
|
|
|
79
79
|
removeListeners: () => removeListeners,
|
|
80
80
|
resizeObserver: () => resizeObserver,
|
|
81
81
|
sanitize: () => sanitize2,
|
|
82
|
+
scrollObserver: () => scrollObserver,
|
|
82
83
|
scrollToElement: () => scrollToElement,
|
|
83
84
|
sessionStore: () => sessionStore,
|
|
84
85
|
setCSSValue: () => setCSSValue,
|
|
@@ -338,7 +339,7 @@ function nativeMasonrySupport(node) {
|
|
|
338
339
|
// src/lib/numbers/index.js
|
|
339
340
|
function splitUnit(string) {
|
|
340
341
|
if (typeof string === "number") return [string, null];
|
|
341
|
-
const regex = /(-?\d*\.?\d+)([a-z]+)/i;
|
|
342
|
+
const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i;
|
|
342
343
|
const match = string.match(regex);
|
|
343
344
|
if (match) return [parseFloat(match[1]), match[2]];
|
|
344
345
|
return [parseFloat(string), null];
|
|
@@ -943,6 +944,94 @@ function mutationObserver(target, options) {
|
|
|
943
944
|
};
|
|
944
945
|
}
|
|
945
946
|
|
|
947
|
+
// src/dom/observers/scroll-observer.js
|
|
948
|
+
var defaultOptions2 = {
|
|
949
|
+
threshold: 0,
|
|
950
|
+
// Float between 0 to 1.
|
|
951
|
+
tolerance: 0.1,
|
|
952
|
+
// Float between 0 to 1. Tolerance for event firing
|
|
953
|
+
throttle: 16,
|
|
954
|
+
// Throttle interval in ms (default: ~60fps)
|
|
955
|
+
once: false
|
|
956
|
+
// Only fire threshold callback once
|
|
957
|
+
};
|
|
958
|
+
function scrollObserver(node, options = {}) {
|
|
959
|
+
const { callback, onScrollDown, onScrollUp, onEnterThreshold, ...userOpts } = options;
|
|
960
|
+
const opts = { ...defaultOptions2, ...userOpts };
|
|
961
|
+
const { threshold, tolerance, throttle, once } = opts;
|
|
962
|
+
const prevScrollDirection = null;
|
|
963
|
+
let prevScrollTop = 0;
|
|
964
|
+
let prevScrollPercent = 0;
|
|
965
|
+
let lastThrottleTime = 0;
|
|
966
|
+
let thresholdFired = false;
|
|
967
|
+
let rafId = null;
|
|
968
|
+
const isDocumentScroll = node === document || node === window;
|
|
969
|
+
const scrollElement = isDocumentScroll ? document.documentElement : node;
|
|
970
|
+
let cachedScrollHeight = 0;
|
|
971
|
+
let cachedClientHeight = 0;
|
|
972
|
+
updateCache();
|
|
973
|
+
const cacheObserver = resizeObserver(scrollElement, {
|
|
974
|
+
callback: updateCache
|
|
975
|
+
});
|
|
976
|
+
node.addEventListener("scroll", throttledObserve, { passive: true });
|
|
977
|
+
function updateCache() {
|
|
978
|
+
cachedScrollHeight = scrollElement.scrollHeight;
|
|
979
|
+
cachedClientHeight = scrollElement.clientHeight;
|
|
980
|
+
}
|
|
981
|
+
function throttledObserve() {
|
|
982
|
+
const now = Date.now();
|
|
983
|
+
if (now - lastThrottleTime < throttle) return;
|
|
984
|
+
lastThrottleTime = now;
|
|
985
|
+
rafId = requestAnimationFrame(observe);
|
|
986
|
+
}
|
|
987
|
+
function observe() {
|
|
988
|
+
const scrollTop = scrollElement.scrollTop;
|
|
989
|
+
if (Math.abs(scrollTop - prevScrollTop) < 1) return;
|
|
990
|
+
const scrollDirection = scrollTop > prevScrollTop ? "down" : "up";
|
|
991
|
+
const maxScroll = Math.max(1, cachedScrollHeight - cachedClientHeight);
|
|
992
|
+
const scrollPercent = Math.min(1, Math.max(0, scrollTop / maxScroll));
|
|
993
|
+
const thresholdMin = threshold - tolerance / 2;
|
|
994
|
+
const thresholdMax = threshold + tolerance / 2;
|
|
995
|
+
const wasInThreshold = prevScrollPercent >= thresholdMin && prevScrollPercent <= thresholdMax;
|
|
996
|
+
const isInThreshold = scrollPercent >= thresholdMin && scrollPercent <= thresholdMax;
|
|
997
|
+
const hasEnteredThreshold = !wasInThreshold && isInThreshold && (!once || !thresholdFired);
|
|
998
|
+
if (hasEnteredThreshold && once) {
|
|
999
|
+
thresholdFired = true;
|
|
1000
|
+
}
|
|
1001
|
+
const callbackData = {
|
|
1002
|
+
scrollTop,
|
|
1003
|
+
scrollDirection,
|
|
1004
|
+
scrollPercent,
|
|
1005
|
+
directionChanged: scrollDirection !== prevScrollDirection,
|
|
1006
|
+
hasEnteredThreshold,
|
|
1007
|
+
isInThreshold
|
|
1008
|
+
};
|
|
1009
|
+
if (typeof callback === "function") {
|
|
1010
|
+
callback(callbackData);
|
|
1011
|
+
}
|
|
1012
|
+
if (scrollDirection !== prevScrollDirection) {
|
|
1013
|
+
if (scrollDirection === "down" && typeof onScrollDown === "function") {
|
|
1014
|
+
onScrollDown(callbackData);
|
|
1015
|
+
}
|
|
1016
|
+
if (scrollDirection === "up" && typeof onScrollUp === "function") {
|
|
1017
|
+
onScrollUp(callbackData);
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
if (hasEnteredThreshold && typeof onEnterThreshold === "function") {
|
|
1021
|
+
onEnterThreshold(callbackData);
|
|
1022
|
+
}
|
|
1023
|
+
prevScrollTop = scrollTop;
|
|
1024
|
+
prevScrollPercent = scrollPercent;
|
|
1025
|
+
}
|
|
1026
|
+
return {
|
|
1027
|
+
destroy() {
|
|
1028
|
+
node.removeEventListener("scroll", throttledObserve);
|
|
1029
|
+
if (rafId) cancelAnimationFrame(rafId);
|
|
1030
|
+
cacheObserver.destroy();
|
|
1031
|
+
}
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
|
|
946
1035
|
// src/dom/random-string.js
|
|
947
1036
|
function randomString(length = 10) {
|
|
948
1037
|
const firstLetter = String.fromCharCode(65 + Math.floor(Math.random() * 26));
|
|
@@ -1182,6 +1271,7 @@ function scrambleText(text) {
|
|
|
1182
1271
|
removeListeners,
|
|
1183
1272
|
resizeObserver,
|
|
1184
1273
|
sanitize,
|
|
1274
|
+
scrollObserver,
|
|
1185
1275
|
scrollToElement,
|
|
1186
1276
|
sessionStore,
|
|
1187
1277
|
setCSSValue,
|
|
@@ -21,7 +21,8 @@ var observers_exports = {};
|
|
|
21
21
|
__export(observers_exports, {
|
|
22
22
|
intersectionObserver: () => intersectionObserver,
|
|
23
23
|
mutationObserver: () => mutationObserver,
|
|
24
|
-
resizeObserver: () => resizeObserver
|
|
24
|
+
resizeObserver: () => resizeObserver,
|
|
25
|
+
scrollObserver: () => scrollObserver
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(observers_exports);
|
|
27
28
|
|
|
@@ -148,9 +149,98 @@ function resizeObserver(target, options) {
|
|
|
148
149
|
destroy: (_) => observer.disconnect()
|
|
149
150
|
};
|
|
150
151
|
}
|
|
152
|
+
|
|
153
|
+
// src/dom/observers/scroll-observer.js
|
|
154
|
+
var defaultOptions2 = {
|
|
155
|
+
threshold: 0,
|
|
156
|
+
// Float between 0 to 1.
|
|
157
|
+
tolerance: 0.1,
|
|
158
|
+
// Float between 0 to 1. Tolerance for event firing
|
|
159
|
+
throttle: 16,
|
|
160
|
+
// Throttle interval in ms (default: ~60fps)
|
|
161
|
+
once: false
|
|
162
|
+
// Only fire threshold callback once
|
|
163
|
+
};
|
|
164
|
+
function scrollObserver(node, options = {}) {
|
|
165
|
+
const { callback, onScrollDown, onScrollUp, onEnterThreshold, ...userOpts } = options;
|
|
166
|
+
const opts = { ...defaultOptions2, ...userOpts };
|
|
167
|
+
const { threshold, tolerance, throttle, once } = opts;
|
|
168
|
+
const prevScrollDirection = null;
|
|
169
|
+
let prevScrollTop = 0;
|
|
170
|
+
let prevScrollPercent = 0;
|
|
171
|
+
let lastThrottleTime = 0;
|
|
172
|
+
let thresholdFired = false;
|
|
173
|
+
let rafId = null;
|
|
174
|
+
const isDocumentScroll = node === document || node === window;
|
|
175
|
+
const scrollElement = isDocumentScroll ? document.documentElement : node;
|
|
176
|
+
let cachedScrollHeight = 0;
|
|
177
|
+
let cachedClientHeight = 0;
|
|
178
|
+
updateCache();
|
|
179
|
+
const cacheObserver = resizeObserver(scrollElement, {
|
|
180
|
+
callback: updateCache
|
|
181
|
+
});
|
|
182
|
+
node.addEventListener("scroll", throttledObserve, { passive: true });
|
|
183
|
+
function updateCache() {
|
|
184
|
+
cachedScrollHeight = scrollElement.scrollHeight;
|
|
185
|
+
cachedClientHeight = scrollElement.clientHeight;
|
|
186
|
+
}
|
|
187
|
+
function throttledObserve() {
|
|
188
|
+
const now = Date.now();
|
|
189
|
+
if (now - lastThrottleTime < throttle) return;
|
|
190
|
+
lastThrottleTime = now;
|
|
191
|
+
rafId = requestAnimationFrame(observe);
|
|
192
|
+
}
|
|
193
|
+
function observe() {
|
|
194
|
+
const scrollTop = scrollElement.scrollTop;
|
|
195
|
+
if (Math.abs(scrollTop - prevScrollTop) < 1) return;
|
|
196
|
+
const scrollDirection = scrollTop > prevScrollTop ? "down" : "up";
|
|
197
|
+
const maxScroll = Math.max(1, cachedScrollHeight - cachedClientHeight);
|
|
198
|
+
const scrollPercent = Math.min(1, Math.max(0, scrollTop / maxScroll));
|
|
199
|
+
const thresholdMin = threshold - tolerance / 2;
|
|
200
|
+
const thresholdMax = threshold + tolerance / 2;
|
|
201
|
+
const wasInThreshold = prevScrollPercent >= thresholdMin && prevScrollPercent <= thresholdMax;
|
|
202
|
+
const isInThreshold = scrollPercent >= thresholdMin && scrollPercent <= thresholdMax;
|
|
203
|
+
const hasEnteredThreshold = !wasInThreshold && isInThreshold && (!once || !thresholdFired);
|
|
204
|
+
if (hasEnteredThreshold && once) {
|
|
205
|
+
thresholdFired = true;
|
|
206
|
+
}
|
|
207
|
+
const callbackData = {
|
|
208
|
+
scrollTop,
|
|
209
|
+
scrollDirection,
|
|
210
|
+
scrollPercent,
|
|
211
|
+
directionChanged: scrollDirection !== prevScrollDirection,
|
|
212
|
+
hasEnteredThreshold,
|
|
213
|
+
isInThreshold
|
|
214
|
+
};
|
|
215
|
+
if (typeof callback === "function") {
|
|
216
|
+
callback(callbackData);
|
|
217
|
+
}
|
|
218
|
+
if (scrollDirection !== prevScrollDirection) {
|
|
219
|
+
if (scrollDirection === "down" && typeof onScrollDown === "function") {
|
|
220
|
+
onScrollDown(callbackData);
|
|
221
|
+
}
|
|
222
|
+
if (scrollDirection === "up" && typeof onScrollUp === "function") {
|
|
223
|
+
onScrollUp(callbackData);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (hasEnteredThreshold && typeof onEnterThreshold === "function") {
|
|
227
|
+
onEnterThreshold(callbackData);
|
|
228
|
+
}
|
|
229
|
+
prevScrollTop = scrollTop;
|
|
230
|
+
prevScrollPercent = scrollPercent;
|
|
231
|
+
}
|
|
232
|
+
return {
|
|
233
|
+
destroy() {
|
|
234
|
+
node.removeEventListener("scroll", throttledObserve);
|
|
235
|
+
if (rafId) cancelAnimationFrame(rafId);
|
|
236
|
+
cacheObserver.destroy();
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
}
|
|
151
240
|
// Annotate the CommonJS export names for ESM import in node:
|
|
152
241
|
0 && (module.exports = {
|
|
153
242
|
intersectionObserver,
|
|
154
243
|
mutationObserver,
|
|
155
|
-
resizeObserver
|
|
244
|
+
resizeObserver,
|
|
245
|
+
scrollObserver
|
|
156
246
|
});
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// src/dom/observers/scroll-observer.js
|
|
20
|
+
var scroll_observer_exports = {};
|
|
21
|
+
__export(scroll_observer_exports, {
|
|
22
|
+
scrollObserver: () => scrollObserver
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(scroll_observer_exports);
|
|
25
|
+
|
|
26
|
+
// src/dom/events.js
|
|
27
|
+
function dispatchEvent(node, eventName, detail, options = {}) {
|
|
28
|
+
node.dispatchEvent(
|
|
29
|
+
new CustomEvent(eventName, {
|
|
30
|
+
...options,
|
|
31
|
+
detail
|
|
32
|
+
})
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// src/dom/get-element.js
|
|
37
|
+
function getNodeType(node) {
|
|
38
|
+
if (node instanceof Element) return "element";
|
|
39
|
+
if (node instanceof NodeList) return "nodelist";
|
|
40
|
+
if (Array.isArray(node)) return "array";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/dom/observers/observer.js
|
|
44
|
+
function useObserverMethodOnTarget(target, observer, method = "observe", options = void 0) {
|
|
45
|
+
const targetType = getNodeType(target);
|
|
46
|
+
if (targetType === "element") observer[method](target, options);
|
|
47
|
+
if (targetType === "nodelist") {
|
|
48
|
+
const elements = Array.from(target);
|
|
49
|
+
elements.forEach((element) => observer[method](element, options));
|
|
50
|
+
}
|
|
51
|
+
if (targetType === "array") {
|
|
52
|
+
target.forEach((element) => observer[method](element, options));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/dom/observers/resize-observer.js
|
|
57
|
+
function resizeObserver(target, options) {
|
|
58
|
+
const { callback, ...opts } = options;
|
|
59
|
+
const observer = new ResizeObserver(observerFn);
|
|
60
|
+
if (target === window) target = document.body;
|
|
61
|
+
useObserverMethodOnTarget(target, observer, "observe", opts);
|
|
62
|
+
function observerFn(entries) {
|
|
63
|
+
for (const entry of entries) {
|
|
64
|
+
if (callback) callback({ entry, entries, observer });
|
|
65
|
+
else dispatchEvent(target, "resize-obs", { entry, entries, observer });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
observe(target2) {
|
|
70
|
+
useObserverMethodOnTarget(target2, observer, "observe", options);
|
|
71
|
+
},
|
|
72
|
+
unobserve(target2) {
|
|
73
|
+
useObserverMethodOnTarget(target2, observer, "unobserve");
|
|
74
|
+
},
|
|
75
|
+
disconnect: (_) => observer.disconnect(),
|
|
76
|
+
destroy: (_) => observer.disconnect()
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// src/dom/observers/scroll-observer.js
|
|
81
|
+
var defaultOptions = {
|
|
82
|
+
threshold: 0,
|
|
83
|
+
// Float between 0 to 1.
|
|
84
|
+
tolerance: 0.1,
|
|
85
|
+
// Float between 0 to 1. Tolerance for event firing
|
|
86
|
+
throttle: 16,
|
|
87
|
+
// Throttle interval in ms (default: ~60fps)
|
|
88
|
+
once: false
|
|
89
|
+
// Only fire threshold callback once
|
|
90
|
+
};
|
|
91
|
+
function scrollObserver(node, options = {}) {
|
|
92
|
+
const { callback, onScrollDown, onScrollUp, onEnterThreshold, ...userOpts } = options;
|
|
93
|
+
const opts = { ...defaultOptions, ...userOpts };
|
|
94
|
+
const { threshold, tolerance, throttle, once } = opts;
|
|
95
|
+
const prevScrollDirection = null;
|
|
96
|
+
let prevScrollTop = 0;
|
|
97
|
+
let prevScrollPercent = 0;
|
|
98
|
+
let lastThrottleTime = 0;
|
|
99
|
+
let thresholdFired = false;
|
|
100
|
+
let rafId = null;
|
|
101
|
+
const isDocumentScroll = node === document || node === window;
|
|
102
|
+
const scrollElement = isDocumentScroll ? document.documentElement : node;
|
|
103
|
+
let cachedScrollHeight = 0;
|
|
104
|
+
let cachedClientHeight = 0;
|
|
105
|
+
updateCache();
|
|
106
|
+
const cacheObserver = resizeObserver(scrollElement, {
|
|
107
|
+
callback: updateCache
|
|
108
|
+
});
|
|
109
|
+
node.addEventListener("scroll", throttledObserve, { passive: true });
|
|
110
|
+
function updateCache() {
|
|
111
|
+
cachedScrollHeight = scrollElement.scrollHeight;
|
|
112
|
+
cachedClientHeight = scrollElement.clientHeight;
|
|
113
|
+
}
|
|
114
|
+
function throttledObserve() {
|
|
115
|
+
const now = Date.now();
|
|
116
|
+
if (now - lastThrottleTime < throttle) return;
|
|
117
|
+
lastThrottleTime = now;
|
|
118
|
+
rafId = requestAnimationFrame(observe);
|
|
119
|
+
}
|
|
120
|
+
function observe() {
|
|
121
|
+
const scrollTop = scrollElement.scrollTop;
|
|
122
|
+
if (Math.abs(scrollTop - prevScrollTop) < 1) return;
|
|
123
|
+
const scrollDirection = scrollTop > prevScrollTop ? "down" : "up";
|
|
124
|
+
const maxScroll = Math.max(1, cachedScrollHeight - cachedClientHeight);
|
|
125
|
+
const scrollPercent = Math.min(1, Math.max(0, scrollTop / maxScroll));
|
|
126
|
+
const thresholdMin = threshold - tolerance / 2;
|
|
127
|
+
const thresholdMax = threshold + tolerance / 2;
|
|
128
|
+
const wasInThreshold = prevScrollPercent >= thresholdMin && prevScrollPercent <= thresholdMax;
|
|
129
|
+
const isInThreshold = scrollPercent >= thresholdMin && scrollPercent <= thresholdMax;
|
|
130
|
+
const hasEnteredThreshold = !wasInThreshold && isInThreshold && (!once || !thresholdFired);
|
|
131
|
+
if (hasEnteredThreshold && once) {
|
|
132
|
+
thresholdFired = true;
|
|
133
|
+
}
|
|
134
|
+
const callbackData = {
|
|
135
|
+
scrollTop,
|
|
136
|
+
scrollDirection,
|
|
137
|
+
scrollPercent,
|
|
138
|
+
directionChanged: scrollDirection !== prevScrollDirection,
|
|
139
|
+
hasEnteredThreshold,
|
|
140
|
+
isInThreshold
|
|
141
|
+
};
|
|
142
|
+
if (typeof callback === "function") {
|
|
143
|
+
callback(callbackData);
|
|
144
|
+
}
|
|
145
|
+
if (scrollDirection !== prevScrollDirection) {
|
|
146
|
+
if (scrollDirection === "down" && typeof onScrollDown === "function") {
|
|
147
|
+
onScrollDown(callbackData);
|
|
148
|
+
}
|
|
149
|
+
if (scrollDirection === "up" && typeof onScrollUp === "function") {
|
|
150
|
+
onScrollUp(callbackData);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (hasEnteredThreshold && typeof onEnterThreshold === "function") {
|
|
154
|
+
onEnterThreshold(callbackData);
|
|
155
|
+
}
|
|
156
|
+
prevScrollTop = scrollTop;
|
|
157
|
+
prevScrollPercent = scrollPercent;
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
destroy() {
|
|
161
|
+
node.removeEventListener("scroll", throttledObserve);
|
|
162
|
+
if (rafId) cancelAnimationFrame(rafId);
|
|
163
|
+
cacheObserver.destroy();
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
168
|
+
0 && (module.exports = {
|
|
169
|
+
scrollObserver
|
|
170
|
+
});
|
|
@@ -122,7 +122,7 @@ var MONTHS = [
|
|
|
122
122
|
// src/lib/numbers/index.js
|
|
123
123
|
function splitUnit(string) {
|
|
124
124
|
if (typeof string === "number") return [string, null];
|
|
125
|
-
const regex = /(-?\d*\.?\d+)([a-z]+)/i;
|
|
125
|
+
const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i;
|
|
126
126
|
const match = string.match(regex);
|
|
127
127
|
if (match) return [parseFloat(match[1]), match[2]];
|
|
128
128
|
return [parseFloat(string), null];
|
|
@@ -140,10 +140,12 @@ function ms(arg) {
|
|
|
140
140
|
if (unit === "hours") return getTimeInMs(value, "hours");
|
|
141
141
|
if (unit === "m") return getTimeInMs(value, "minutes");
|
|
142
142
|
if (unit === "min") return getTimeInMs(value, "minutes");
|
|
143
|
+
if (unit === "mins") return getTimeInMs(value, "minutes");
|
|
143
144
|
if (unit === "minute") return getTimeInMs(value, "minutes");
|
|
144
145
|
if (unit === "minutes") return getTimeInMs(value, "minutes");
|
|
145
146
|
if (unit === "s") return getTimeInMs(value, "seconds");
|
|
146
147
|
if (unit === "sec") return getTimeInMs(value, "seconds");
|
|
148
|
+
if (unit === "secs") return getTimeInMs(value, "seconds");
|
|
147
149
|
if (unit === "second") return getTimeInMs(value, "seconds");
|
|
148
150
|
if (unit === "seconds") return getTimeInMs(value, "seconds");
|
|
149
151
|
return value;
|
|
@@ -33,7 +33,7 @@ module.exports = __toCommonJS(time_exports);
|
|
|
33
33
|
// src/lib/numbers/index.js
|
|
34
34
|
function splitUnit(string) {
|
|
35
35
|
if (typeof string === "number") return [string, null];
|
|
36
|
-
const regex = /(-?\d*\.?\d+)([a-z]+)/i;
|
|
36
|
+
const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i;
|
|
37
37
|
const match = string.match(regex);
|
|
38
38
|
if (match) return [parseFloat(match[1]), match[2]];
|
|
39
39
|
return [parseFloat(string), null];
|
|
@@ -51,10 +51,12 @@ function ms(arg) {
|
|
|
51
51
|
if (unit === "hours") return getTimeInMs(value, "hours");
|
|
52
52
|
if (unit === "m") return getTimeInMs(value, "minutes");
|
|
53
53
|
if (unit === "min") return getTimeInMs(value, "minutes");
|
|
54
|
+
if (unit === "mins") return getTimeInMs(value, "minutes");
|
|
54
55
|
if (unit === "minute") return getTimeInMs(value, "minutes");
|
|
55
56
|
if (unit === "minutes") return getTimeInMs(value, "minutes");
|
|
56
57
|
if (unit === "s") return getTimeInMs(value, "seconds");
|
|
57
58
|
if (unit === "sec") return getTimeInMs(value, "seconds");
|
|
59
|
+
if (unit === "secs") return getTimeInMs(value, "seconds");
|
|
58
60
|
if (unit === "second") return getTimeInMs(value, "seconds");
|
|
59
61
|
if (unit === "seconds") return getTimeInMs(value, "seconds");
|
|
60
62
|
return value;
|
|
@@ -20,8 +20,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
var functional_exports = {};
|
|
21
21
|
__export(functional_exports, {
|
|
22
22
|
compose: () => compose,
|
|
23
|
+
composeAsync: () => composeAsync,
|
|
23
24
|
curry: () => curry,
|
|
24
25
|
pipe: () => pipe,
|
|
26
|
+
pipeAsync: () => pipeAsync,
|
|
25
27
|
times: () => times
|
|
26
28
|
});
|
|
27
29
|
module.exports = __toCommonJS(functional_exports);
|
|
@@ -41,11 +43,27 @@ function compose(...fns) {
|
|
|
41
43
|
return fns.reduceRight((acc, fn) => fn(acc), value);
|
|
42
44
|
};
|
|
43
45
|
}
|
|
46
|
+
function composeAsync(...fns) {
|
|
47
|
+
return async function(value) {
|
|
48
|
+
return fns.reduceRight(async (acc, fn) => {
|
|
49
|
+
const result = await acc;
|
|
50
|
+
return await fn(result);
|
|
51
|
+
}, value);
|
|
52
|
+
};
|
|
53
|
+
}
|
|
44
54
|
function pipe(...fns) {
|
|
45
55
|
return function(value) {
|
|
46
56
|
return fns.reduce((acc, fn) => fn(acc), value);
|
|
47
57
|
};
|
|
48
58
|
}
|
|
59
|
+
function pipeAsync(...fns) {
|
|
60
|
+
return async function(value) {
|
|
61
|
+
return fns.reduce(async (acc, fn) => {
|
|
62
|
+
const result = await acc;
|
|
63
|
+
return await fn(result);
|
|
64
|
+
}, value);
|
|
65
|
+
};
|
|
66
|
+
}
|
|
49
67
|
function times(fn, n) {
|
|
50
68
|
const result = [];
|
|
51
69
|
for (let i = 0; i < n; i++) {
|
|
@@ -56,7 +74,9 @@ function times(fn, n) {
|
|
|
56
74
|
// Annotate the CommonJS export names for ESM import in node:
|
|
57
75
|
0 && (module.exports = {
|
|
58
76
|
compose,
|
|
77
|
+
composeAsync,
|
|
59
78
|
curry,
|
|
60
79
|
pipe,
|
|
80
|
+
pipeAsync,
|
|
61
81
|
times
|
|
62
82
|
});
|
|
@@ -20,11 +20,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
var functions_exports = {};
|
|
21
21
|
__export(functions_exports, {
|
|
22
22
|
compose: () => compose,
|
|
23
|
+
composeAsync: () => composeAsync,
|
|
23
24
|
curry: () => curry,
|
|
24
25
|
debounce: () => debounce,
|
|
25
26
|
delay: () => delay,
|
|
26
27
|
getEnv: () => getEnv,
|
|
27
28
|
pipe: () => pipe,
|
|
29
|
+
pipeAsync: () => pipeAsync,
|
|
28
30
|
throttle: () => throttle,
|
|
29
31
|
timeout: () => timeout,
|
|
30
32
|
times: () => times,
|
|
@@ -72,11 +74,27 @@ function compose(...fns) {
|
|
|
72
74
|
return fns.reduceRight((acc, fn) => fn(acc), value);
|
|
73
75
|
};
|
|
74
76
|
}
|
|
77
|
+
function composeAsync(...fns) {
|
|
78
|
+
return async function(value) {
|
|
79
|
+
return fns.reduceRight(async (acc, fn) => {
|
|
80
|
+
const result = await acc;
|
|
81
|
+
return await fn(result);
|
|
82
|
+
}, value);
|
|
83
|
+
};
|
|
84
|
+
}
|
|
75
85
|
function pipe(...fns) {
|
|
76
86
|
return function(value) {
|
|
77
87
|
return fns.reduce((acc, fn) => fn(acc), value);
|
|
78
88
|
};
|
|
79
89
|
}
|
|
90
|
+
function pipeAsync(...fns) {
|
|
91
|
+
return async function(value) {
|
|
92
|
+
return fns.reduce(async (acc, fn) => {
|
|
93
|
+
const result = await acc;
|
|
94
|
+
return await fn(result);
|
|
95
|
+
}, value);
|
|
96
|
+
};
|
|
97
|
+
}
|
|
80
98
|
function times(fn, n) {
|
|
81
99
|
const result = [];
|
|
82
100
|
for (let i = 0; i < n; i++) {
|
|
@@ -110,11 +128,13 @@ function wait(ms) {
|
|
|
110
128
|
// Annotate the CommonJS export names for ESM import in node:
|
|
111
129
|
0 && (module.exports = {
|
|
112
130
|
compose,
|
|
131
|
+
composeAsync,
|
|
113
132
|
curry,
|
|
114
133
|
debounce,
|
|
115
134
|
delay,
|
|
116
135
|
getEnv,
|
|
117
136
|
pipe,
|
|
137
|
+
pipeAsync,
|
|
118
138
|
throttle,
|
|
119
139
|
timeout,
|
|
120
140
|
times,
|
package/dist/cjs/lib/index.cjs
CHANGED
|
@@ -35,6 +35,8 @@ __export(lib_exports, {
|
|
|
35
35
|
RouteManager: () => RouteManager,
|
|
36
36
|
camelCaseKeys: () => camelCaseKeys,
|
|
37
37
|
compose: () => compose,
|
|
38
|
+
composeAsync: () => composeAsync,
|
|
39
|
+
concatMix: () => concatMix,
|
|
38
40
|
createMix: () => createMix,
|
|
39
41
|
createSSE: () => createSSE,
|
|
40
42
|
curry: () => curry,
|
|
@@ -75,6 +77,7 @@ __export(lib_exports, {
|
|
|
75
77
|
parseJSON: () => parseJSON,
|
|
76
78
|
parseSSE: () => parseSSE,
|
|
77
79
|
pipe: () => pipe,
|
|
80
|
+
pipeAsync: () => pipeAsync,
|
|
78
81
|
plural: () => plural,
|
|
79
82
|
pluralize: () => pluralize,
|
|
80
83
|
reject: () => reject,
|
|
@@ -369,7 +372,7 @@ function toRadians(angle) {
|
|
|
369
372
|
// src/lib/numbers/index.js
|
|
370
373
|
function splitUnit(string) {
|
|
371
374
|
if (typeof string === "number") return [string, null];
|
|
372
|
-
const regex = /(-?\d*\.?\d+)([a-z]+)/i;
|
|
375
|
+
const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i;
|
|
373
376
|
const match = string.match(regex);
|
|
374
377
|
if (match) return [parseFloat(match[1]), match[2]];
|
|
375
378
|
return [parseFloat(string), null];
|
|
@@ -387,10 +390,12 @@ function ms(arg) {
|
|
|
387
390
|
if (unit === "hours") return getTimeInMs(value, "hours");
|
|
388
391
|
if (unit === "m") return getTimeInMs(value, "minutes");
|
|
389
392
|
if (unit === "min") return getTimeInMs(value, "minutes");
|
|
393
|
+
if (unit === "mins") return getTimeInMs(value, "minutes");
|
|
390
394
|
if (unit === "minute") return getTimeInMs(value, "minutes");
|
|
391
395
|
if (unit === "minutes") return getTimeInMs(value, "minutes");
|
|
392
396
|
if (unit === "s") return getTimeInMs(value, "seconds");
|
|
393
397
|
if (unit === "sec") return getTimeInMs(value, "seconds");
|
|
398
|
+
if (unit === "secs") return getTimeInMs(value, "seconds");
|
|
394
399
|
if (unit === "second") return getTimeInMs(value, "seconds");
|
|
395
400
|
if (unit === "seconds") return getTimeInMs(value, "seconds");
|
|
396
401
|
return value;
|
|
@@ -565,11 +570,27 @@ function compose(...fns) {
|
|
|
565
570
|
return fns.reduceRight((acc, fn) => fn(acc), value);
|
|
566
571
|
};
|
|
567
572
|
}
|
|
573
|
+
function composeAsync(...fns) {
|
|
574
|
+
return async function(value) {
|
|
575
|
+
return fns.reduceRight(async (acc, fn) => {
|
|
576
|
+
const result = await acc;
|
|
577
|
+
return await fn(result);
|
|
578
|
+
}, value);
|
|
579
|
+
};
|
|
580
|
+
}
|
|
568
581
|
function pipe(...fns) {
|
|
569
582
|
return function(value) {
|
|
570
583
|
return fns.reduce((acc, fn) => fn(acc), value);
|
|
571
584
|
};
|
|
572
585
|
}
|
|
586
|
+
function pipeAsync(...fns) {
|
|
587
|
+
return async function(value) {
|
|
588
|
+
return fns.reduce(async (acc, fn) => {
|
|
589
|
+
const result = await acc;
|
|
590
|
+
return await fn(result);
|
|
591
|
+
}, value);
|
|
592
|
+
};
|
|
593
|
+
}
|
|
573
594
|
function times(fn, n) {
|
|
574
595
|
const result = [];
|
|
575
596
|
for (let i = 0; i < n; i++) {
|
|
@@ -720,8 +741,9 @@ function notEqual(a, b) {
|
|
|
720
741
|
}
|
|
721
742
|
|
|
722
743
|
// src/lib/objects/mix/mix.js
|
|
723
|
-
var DEFAULT_OPTIONS = { array: "
|
|
744
|
+
var DEFAULT_OPTIONS = { array: "replace" };
|
|
724
745
|
var mix = createMix();
|
|
746
|
+
var concatMix = createMix({ array: "concat" });
|
|
725
747
|
function createMix(userOptions = {}) {
|
|
726
748
|
const options = { ...DEFAULT_OPTIONS, ...userOptions };
|
|
727
749
|
function _mix(...sources) {
|
|
@@ -1061,6 +1083,8 @@ function getSymbolValue(object, description) {
|
|
|
1061
1083
|
RouteManager,
|
|
1062
1084
|
camelCaseKeys,
|
|
1063
1085
|
compose,
|
|
1086
|
+
composeAsync,
|
|
1087
|
+
concatMix,
|
|
1064
1088
|
createMix,
|
|
1065
1089
|
createSSE,
|
|
1066
1090
|
curry,
|
|
@@ -1101,6 +1125,7 @@ function getSymbolValue(object, description) {
|
|
|
1101
1125
|
parseJSON,
|
|
1102
1126
|
parseSSE,
|
|
1103
1127
|
pipe,
|
|
1128
|
+
pipeAsync,
|
|
1104
1129
|
plural,
|
|
1105
1130
|
pluralize,
|
|
1106
1131
|
reject,
|
|
@@ -36,7 +36,7 @@ function toRadians(angle) {
|
|
|
36
36
|
// src/lib/numbers/index.js
|
|
37
37
|
function splitUnit(string) {
|
|
38
38
|
if (typeof string === "number") return [string, null];
|
|
39
|
-
const regex = /(-?\d*\.?\d+)([a-z]+)/i;
|
|
39
|
+
const regex = /(-?\d*\.?\d+)\s*([a-z]+)/i;
|
|
40
40
|
const match = string.match(regex);
|
|
41
41
|
if (match) return [parseFloat(match[1]), match[2]];
|
|
42
42
|
return [parseFloat(string), null];
|