@splendidlabz/utils 1.8.1 → 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 +6 -0
- package/dist/cjs/dom/index.cjs +90 -0
- package/dist/cjs/dom/observers/index.cjs +92 -2
- package/dist/cjs/dom/observers/scroll-observer.cjs +170 -0
- package/dist/cjs/lib/functions/functional.cjs +20 -0
- package/dist/cjs/lib/functions/index.cjs +20 -0
- package/dist/cjs/lib/index.cjs +20 -0
- package/dist/esm/dom/index.js +89 -0
- package/dist/esm/dom/observers/index.js +90 -1
- package/dist/esm/dom/observers/scroll-observer.js +144 -0
- package/dist/esm/lib/functions/functional.js +18 -0
- package/dist/esm/lib/functions/index.js +18 -0
- package/dist/esm/lib/index.js +18 -0
- 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 +1 -1
- package/package.json +1 -1
- 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/functions/functional.js +82 -0
- package/src/lib/functions/functional.test.js +196 -0
|
@@ -121,8 +121,97 @@ function resizeObserver(target, options) {
|
|
|
121
121
|
destroy: (_) => observer.disconnect()
|
|
122
122
|
};
|
|
123
123
|
}
|
|
124
|
+
|
|
125
|
+
// src/dom/observers/scroll-observer.js
|
|
126
|
+
var defaultOptions2 = {
|
|
127
|
+
threshold: 0,
|
|
128
|
+
// Float between 0 to 1.
|
|
129
|
+
tolerance: 0.1,
|
|
130
|
+
// Float between 0 to 1. Tolerance for event firing
|
|
131
|
+
throttle: 16,
|
|
132
|
+
// Throttle interval in ms (default: ~60fps)
|
|
133
|
+
once: false
|
|
134
|
+
// Only fire threshold callback once
|
|
135
|
+
};
|
|
136
|
+
function scrollObserver(node, options = {}) {
|
|
137
|
+
const { callback, onScrollDown, onScrollUp, onEnterThreshold, ...userOpts } = options;
|
|
138
|
+
const opts = { ...defaultOptions2, ...userOpts };
|
|
139
|
+
const { threshold, tolerance, throttle, once } = opts;
|
|
140
|
+
const prevScrollDirection = null;
|
|
141
|
+
let prevScrollTop = 0;
|
|
142
|
+
let prevScrollPercent = 0;
|
|
143
|
+
let lastThrottleTime = 0;
|
|
144
|
+
let thresholdFired = false;
|
|
145
|
+
let rafId = null;
|
|
146
|
+
const isDocumentScroll = node === document || node === window;
|
|
147
|
+
const scrollElement = isDocumentScroll ? document.documentElement : node;
|
|
148
|
+
let cachedScrollHeight = 0;
|
|
149
|
+
let cachedClientHeight = 0;
|
|
150
|
+
updateCache();
|
|
151
|
+
const cacheObserver = resizeObserver(scrollElement, {
|
|
152
|
+
callback: updateCache
|
|
153
|
+
});
|
|
154
|
+
node.addEventListener("scroll", throttledObserve, { passive: true });
|
|
155
|
+
function updateCache() {
|
|
156
|
+
cachedScrollHeight = scrollElement.scrollHeight;
|
|
157
|
+
cachedClientHeight = scrollElement.clientHeight;
|
|
158
|
+
}
|
|
159
|
+
function throttledObserve() {
|
|
160
|
+
const now = Date.now();
|
|
161
|
+
if (now - lastThrottleTime < throttle) return;
|
|
162
|
+
lastThrottleTime = now;
|
|
163
|
+
rafId = requestAnimationFrame(observe);
|
|
164
|
+
}
|
|
165
|
+
function observe() {
|
|
166
|
+
const scrollTop = scrollElement.scrollTop;
|
|
167
|
+
if (Math.abs(scrollTop - prevScrollTop) < 1) return;
|
|
168
|
+
const scrollDirection = scrollTop > prevScrollTop ? "down" : "up";
|
|
169
|
+
const maxScroll = Math.max(1, cachedScrollHeight - cachedClientHeight);
|
|
170
|
+
const scrollPercent = Math.min(1, Math.max(0, scrollTop / maxScroll));
|
|
171
|
+
const thresholdMin = threshold - tolerance / 2;
|
|
172
|
+
const thresholdMax = threshold + tolerance / 2;
|
|
173
|
+
const wasInThreshold = prevScrollPercent >= thresholdMin && prevScrollPercent <= thresholdMax;
|
|
174
|
+
const isInThreshold = scrollPercent >= thresholdMin && scrollPercent <= thresholdMax;
|
|
175
|
+
const hasEnteredThreshold = !wasInThreshold && isInThreshold && (!once || !thresholdFired);
|
|
176
|
+
if (hasEnteredThreshold && once) {
|
|
177
|
+
thresholdFired = true;
|
|
178
|
+
}
|
|
179
|
+
const callbackData = {
|
|
180
|
+
scrollTop,
|
|
181
|
+
scrollDirection,
|
|
182
|
+
scrollPercent,
|
|
183
|
+
directionChanged: scrollDirection !== prevScrollDirection,
|
|
184
|
+
hasEnteredThreshold,
|
|
185
|
+
isInThreshold
|
|
186
|
+
};
|
|
187
|
+
if (typeof callback === "function") {
|
|
188
|
+
callback(callbackData);
|
|
189
|
+
}
|
|
190
|
+
if (scrollDirection !== prevScrollDirection) {
|
|
191
|
+
if (scrollDirection === "down" && typeof onScrollDown === "function") {
|
|
192
|
+
onScrollDown(callbackData);
|
|
193
|
+
}
|
|
194
|
+
if (scrollDirection === "up" && typeof onScrollUp === "function") {
|
|
195
|
+
onScrollUp(callbackData);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (hasEnteredThreshold && typeof onEnterThreshold === "function") {
|
|
199
|
+
onEnterThreshold(callbackData);
|
|
200
|
+
}
|
|
201
|
+
prevScrollTop = scrollTop;
|
|
202
|
+
prevScrollPercent = scrollPercent;
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
destroy() {
|
|
206
|
+
node.removeEventListener("scroll", throttledObserve);
|
|
207
|
+
if (rafId) cancelAnimationFrame(rafId);
|
|
208
|
+
cacheObserver.destroy();
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
}
|
|
124
212
|
export {
|
|
125
213
|
intersectionObserver,
|
|
126
214
|
mutationObserver,
|
|
127
|
-
resizeObserver
|
|
215
|
+
resizeObserver,
|
|
216
|
+
scrollObserver
|
|
128
217
|
};
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// src/dom/events.js
|
|
2
|
+
function dispatchEvent(node, eventName, detail, options = {}) {
|
|
3
|
+
node.dispatchEvent(
|
|
4
|
+
new CustomEvent(eventName, {
|
|
5
|
+
...options,
|
|
6
|
+
detail
|
|
7
|
+
})
|
|
8
|
+
);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// src/dom/get-element.js
|
|
12
|
+
function getNodeType(node) {
|
|
13
|
+
if (node instanceof Element) return "element";
|
|
14
|
+
if (node instanceof NodeList) return "nodelist";
|
|
15
|
+
if (Array.isArray(node)) return "array";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// src/dom/observers/observer.js
|
|
19
|
+
function useObserverMethodOnTarget(target, observer, method = "observe", options = void 0) {
|
|
20
|
+
const targetType = getNodeType(target);
|
|
21
|
+
if (targetType === "element") observer[method](target, options);
|
|
22
|
+
if (targetType === "nodelist") {
|
|
23
|
+
const elements = Array.from(target);
|
|
24
|
+
elements.forEach((element) => observer[method](element, options));
|
|
25
|
+
}
|
|
26
|
+
if (targetType === "array") {
|
|
27
|
+
target.forEach((element) => observer[method](element, options));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// src/dom/observers/resize-observer.js
|
|
32
|
+
function resizeObserver(target, options) {
|
|
33
|
+
const { callback, ...opts } = options;
|
|
34
|
+
const observer = new ResizeObserver(observerFn);
|
|
35
|
+
if (target === window) target = document.body;
|
|
36
|
+
useObserverMethodOnTarget(target, observer, "observe", opts);
|
|
37
|
+
function observerFn(entries) {
|
|
38
|
+
for (const entry of entries) {
|
|
39
|
+
if (callback) callback({ entry, entries, observer });
|
|
40
|
+
else dispatchEvent(target, "resize-obs", { entry, entries, observer });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
observe(target2) {
|
|
45
|
+
useObserverMethodOnTarget(target2, observer, "observe", options);
|
|
46
|
+
},
|
|
47
|
+
unobserve(target2) {
|
|
48
|
+
useObserverMethodOnTarget(target2, observer, "unobserve");
|
|
49
|
+
},
|
|
50
|
+
disconnect: (_) => observer.disconnect(),
|
|
51
|
+
destroy: (_) => observer.disconnect()
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// src/dom/observers/scroll-observer.js
|
|
56
|
+
var defaultOptions = {
|
|
57
|
+
threshold: 0,
|
|
58
|
+
// Float between 0 to 1.
|
|
59
|
+
tolerance: 0.1,
|
|
60
|
+
// Float between 0 to 1. Tolerance for event firing
|
|
61
|
+
throttle: 16,
|
|
62
|
+
// Throttle interval in ms (default: ~60fps)
|
|
63
|
+
once: false
|
|
64
|
+
// Only fire threshold callback once
|
|
65
|
+
};
|
|
66
|
+
function scrollObserver(node, options = {}) {
|
|
67
|
+
const { callback, onScrollDown, onScrollUp, onEnterThreshold, ...userOpts } = options;
|
|
68
|
+
const opts = { ...defaultOptions, ...userOpts };
|
|
69
|
+
const { threshold, tolerance, throttle, once } = opts;
|
|
70
|
+
const prevScrollDirection = null;
|
|
71
|
+
let prevScrollTop = 0;
|
|
72
|
+
let prevScrollPercent = 0;
|
|
73
|
+
let lastThrottleTime = 0;
|
|
74
|
+
let thresholdFired = false;
|
|
75
|
+
let rafId = null;
|
|
76
|
+
const isDocumentScroll = node === document || node === window;
|
|
77
|
+
const scrollElement = isDocumentScroll ? document.documentElement : node;
|
|
78
|
+
let cachedScrollHeight = 0;
|
|
79
|
+
let cachedClientHeight = 0;
|
|
80
|
+
updateCache();
|
|
81
|
+
const cacheObserver = resizeObserver(scrollElement, {
|
|
82
|
+
callback: updateCache
|
|
83
|
+
});
|
|
84
|
+
node.addEventListener("scroll", throttledObserve, { passive: true });
|
|
85
|
+
function updateCache() {
|
|
86
|
+
cachedScrollHeight = scrollElement.scrollHeight;
|
|
87
|
+
cachedClientHeight = scrollElement.clientHeight;
|
|
88
|
+
}
|
|
89
|
+
function throttledObserve() {
|
|
90
|
+
const now = Date.now();
|
|
91
|
+
if (now - lastThrottleTime < throttle) return;
|
|
92
|
+
lastThrottleTime = now;
|
|
93
|
+
rafId = requestAnimationFrame(observe);
|
|
94
|
+
}
|
|
95
|
+
function observe() {
|
|
96
|
+
const scrollTop = scrollElement.scrollTop;
|
|
97
|
+
if (Math.abs(scrollTop - prevScrollTop) < 1) return;
|
|
98
|
+
const scrollDirection = scrollTop > prevScrollTop ? "down" : "up";
|
|
99
|
+
const maxScroll = Math.max(1, cachedScrollHeight - cachedClientHeight);
|
|
100
|
+
const scrollPercent = Math.min(1, Math.max(0, scrollTop / maxScroll));
|
|
101
|
+
const thresholdMin = threshold - tolerance / 2;
|
|
102
|
+
const thresholdMax = threshold + tolerance / 2;
|
|
103
|
+
const wasInThreshold = prevScrollPercent >= thresholdMin && prevScrollPercent <= thresholdMax;
|
|
104
|
+
const isInThreshold = scrollPercent >= thresholdMin && scrollPercent <= thresholdMax;
|
|
105
|
+
const hasEnteredThreshold = !wasInThreshold && isInThreshold && (!once || !thresholdFired);
|
|
106
|
+
if (hasEnteredThreshold && once) {
|
|
107
|
+
thresholdFired = true;
|
|
108
|
+
}
|
|
109
|
+
const callbackData = {
|
|
110
|
+
scrollTop,
|
|
111
|
+
scrollDirection,
|
|
112
|
+
scrollPercent,
|
|
113
|
+
directionChanged: scrollDirection !== prevScrollDirection,
|
|
114
|
+
hasEnteredThreshold,
|
|
115
|
+
isInThreshold
|
|
116
|
+
};
|
|
117
|
+
if (typeof callback === "function") {
|
|
118
|
+
callback(callbackData);
|
|
119
|
+
}
|
|
120
|
+
if (scrollDirection !== prevScrollDirection) {
|
|
121
|
+
if (scrollDirection === "down" && typeof onScrollDown === "function") {
|
|
122
|
+
onScrollDown(callbackData);
|
|
123
|
+
}
|
|
124
|
+
if (scrollDirection === "up" && typeof onScrollUp === "function") {
|
|
125
|
+
onScrollUp(callbackData);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (hasEnteredThreshold && typeof onEnterThreshold === "function") {
|
|
129
|
+
onEnterThreshold(callbackData);
|
|
130
|
+
}
|
|
131
|
+
prevScrollTop = scrollTop;
|
|
132
|
+
prevScrollPercent = scrollPercent;
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
destroy() {
|
|
136
|
+
node.removeEventListener("scroll", throttledObserve);
|
|
137
|
+
if (rafId) cancelAnimationFrame(rafId);
|
|
138
|
+
cacheObserver.destroy();
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
export {
|
|
143
|
+
scrollObserver
|
|
144
|
+
};
|
|
@@ -15,11 +15,27 @@ function compose(...fns) {
|
|
|
15
15
|
return fns.reduceRight((acc, fn) => fn(acc), value);
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
+
function composeAsync(...fns) {
|
|
19
|
+
return async function(value) {
|
|
20
|
+
return fns.reduceRight(async (acc, fn) => {
|
|
21
|
+
const result = await acc;
|
|
22
|
+
return await fn(result);
|
|
23
|
+
}, value);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
18
26
|
function pipe(...fns) {
|
|
19
27
|
return function(value) {
|
|
20
28
|
return fns.reduce((acc, fn) => fn(acc), value);
|
|
21
29
|
};
|
|
22
30
|
}
|
|
31
|
+
function pipeAsync(...fns) {
|
|
32
|
+
return async function(value) {
|
|
33
|
+
return fns.reduce(async (acc, fn) => {
|
|
34
|
+
const result = await acc;
|
|
35
|
+
return await fn(result);
|
|
36
|
+
}, value);
|
|
37
|
+
};
|
|
38
|
+
}
|
|
23
39
|
function times(fn, n) {
|
|
24
40
|
const result = [];
|
|
25
41
|
for (let i = 0; i < n; i++) {
|
|
@@ -29,7 +45,9 @@ function times(fn, n) {
|
|
|
29
45
|
}
|
|
30
46
|
export {
|
|
31
47
|
compose,
|
|
48
|
+
composeAsync,
|
|
32
49
|
curry,
|
|
33
50
|
pipe,
|
|
51
|
+
pipeAsync,
|
|
34
52
|
times
|
|
35
53
|
};
|
|
@@ -38,11 +38,27 @@ function compose(...fns) {
|
|
|
38
38
|
return fns.reduceRight((acc, fn) => fn(acc), value);
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
|
+
function composeAsync(...fns) {
|
|
42
|
+
return async function(value) {
|
|
43
|
+
return fns.reduceRight(async (acc, fn) => {
|
|
44
|
+
const result = await acc;
|
|
45
|
+
return await fn(result);
|
|
46
|
+
}, value);
|
|
47
|
+
};
|
|
48
|
+
}
|
|
41
49
|
function pipe(...fns) {
|
|
42
50
|
return function(value) {
|
|
43
51
|
return fns.reduce((acc, fn) => fn(acc), value);
|
|
44
52
|
};
|
|
45
53
|
}
|
|
54
|
+
function pipeAsync(...fns) {
|
|
55
|
+
return async function(value) {
|
|
56
|
+
return fns.reduce(async (acc, fn) => {
|
|
57
|
+
const result = await acc;
|
|
58
|
+
return await fn(result);
|
|
59
|
+
}, value);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
46
62
|
function times(fn, n) {
|
|
47
63
|
const result = [];
|
|
48
64
|
for (let i = 0; i < n; i++) {
|
|
@@ -75,11 +91,13 @@ function wait(ms) {
|
|
|
75
91
|
}
|
|
76
92
|
export {
|
|
77
93
|
compose,
|
|
94
|
+
composeAsync,
|
|
78
95
|
curry,
|
|
79
96
|
debounce,
|
|
80
97
|
delay,
|
|
81
98
|
getEnv,
|
|
82
99
|
pipe,
|
|
100
|
+
pipeAsync,
|
|
83
101
|
throttle,
|
|
84
102
|
timeout,
|
|
85
103
|
times,
|
package/dist/esm/lib/index.js
CHANGED
|
@@ -450,11 +450,27 @@ function compose(...fns) {
|
|
|
450
450
|
return fns.reduceRight((acc, fn) => fn(acc), value);
|
|
451
451
|
};
|
|
452
452
|
}
|
|
453
|
+
function composeAsync(...fns) {
|
|
454
|
+
return async function(value) {
|
|
455
|
+
return fns.reduceRight(async (acc, fn) => {
|
|
456
|
+
const result = await acc;
|
|
457
|
+
return await fn(result);
|
|
458
|
+
}, value);
|
|
459
|
+
};
|
|
460
|
+
}
|
|
453
461
|
function pipe(...fns) {
|
|
454
462
|
return function(value) {
|
|
455
463
|
return fns.reduce((acc, fn) => fn(acc), value);
|
|
456
464
|
};
|
|
457
465
|
}
|
|
466
|
+
function pipeAsync(...fns) {
|
|
467
|
+
return async function(value) {
|
|
468
|
+
return fns.reduce(async (acc, fn) => {
|
|
469
|
+
const result = await acc;
|
|
470
|
+
return await fn(result);
|
|
471
|
+
}, value);
|
|
472
|
+
};
|
|
473
|
+
}
|
|
458
474
|
function times(fn, n) {
|
|
459
475
|
const result = [];
|
|
460
476
|
for (let i = 0; i < n; i++) {
|
|
@@ -946,6 +962,7 @@ export {
|
|
|
946
962
|
RouteManager,
|
|
947
963
|
camelCaseKeys,
|
|
948
964
|
compose,
|
|
965
|
+
composeAsync,
|
|
949
966
|
concatMix,
|
|
950
967
|
createMix,
|
|
951
968
|
createSSE,
|
|
@@ -987,6 +1004,7 @@ export {
|
|
|
987
1004
|
parseJSON,
|
|
988
1005
|
parseSSE,
|
|
989
1006
|
pipe,
|
|
1007
|
+
pipeAsync,
|
|
990
1008
|
plural,
|
|
991
1009
|
pluralize,
|
|
992
1010
|
reject,
|
|
@@ -17,6 +17,7 @@ export { imagesLoaded, mediaLoaded, videosLoaded } from './media.cjs';
|
|
|
17
17
|
export { intersectionObserver } from './observers/intersection-observer.cjs';
|
|
18
18
|
export { mutationObserver } from './observers/mutation-observer.cjs';
|
|
19
19
|
export { resizeObserver } from './observers/resize-observer.cjs';
|
|
20
|
+
export { scrollObserver } from './observers/scroll-observer.cjs';
|
|
20
21
|
export { PKCE } from './pkce.cjs';
|
|
21
22
|
export { queryParams } from './query-params.cjs';
|
|
22
23
|
export { randomString, uuid } from './random-string.cjs';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scroll Observer - Optimized for performance
|
|
3
|
+
* @param {Element} node - The element to observe scroll events on
|
|
4
|
+
* @param {Object} options - Configuration options
|
|
5
|
+
* @param {Number} options.threshold - Float between 0 to 1. When to trigger callback (0.75 = 75% down page)
|
|
6
|
+
* @param {Number} options.tolerance - Float between 0 to 1. Tolerance zone around threshold
|
|
7
|
+
* @param {Number} options.throttle - Throttle interval in ms (default: 16ms for ~60fps)
|
|
8
|
+
* @param {Boolean} options.once - Only fire threshold callback once (default: false)
|
|
9
|
+
* @param {Function} options.callback - Called on every scroll with scrollPercent
|
|
10
|
+
* @param {Function} options.onScrollDown - Called when scrolling down
|
|
11
|
+
* @param {Function} options.onScrollUp - Called when scrolling up
|
|
12
|
+
* @param {Function} options.onEnterThreshold - Called when entering threshold zone
|
|
13
|
+
*/
|
|
14
|
+
declare function scrollObserver(node: Element, options?: {
|
|
15
|
+
threshold: number;
|
|
16
|
+
tolerance: number;
|
|
17
|
+
throttle: number;
|
|
18
|
+
once: boolean;
|
|
19
|
+
callback: Function;
|
|
20
|
+
onScrollDown: Function;
|
|
21
|
+
onScrollUp: Function;
|
|
22
|
+
onEnterThreshold: Function;
|
|
23
|
+
}): {
|
|
24
|
+
destroy(): void;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export { scrollObserver };
|
|
@@ -1,6 +1,72 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Creates a curried version of a function that can be called with partial arguments
|
|
3
|
+
* @param {Function} fn - The function to curry
|
|
4
|
+
* @return {Function} The curried function
|
|
5
|
+
* @property {any} return - The result of calling the original function when all arguments are provided
|
|
6
|
+
* @example
|
|
7
|
+
* const add = (a, b, c) => a + b + c
|
|
8
|
+
* const curriedAdd = curry(add)
|
|
9
|
+
* curriedAdd(1)(2)(3) // 6
|
|
10
|
+
* curriedAdd(1, 2)(3) // 6
|
|
11
|
+
* curriedAdd(1)(2, 3) // 6
|
|
12
|
+
*/
|
|
13
|
+
declare function curry(fn: Function): Function;
|
|
14
|
+
/**
|
|
15
|
+
* Composes functions from right to left (synchronous)
|
|
16
|
+
* @param {...Function} fns - Functions to compose
|
|
17
|
+
* @return {Function} The composed function
|
|
18
|
+
* @property {any} return - The result of applying all functions in sequence
|
|
19
|
+
* @example
|
|
20
|
+
* const add1 = x => x + 1
|
|
21
|
+
* const multiply2 = x => x * 2
|
|
22
|
+
* const composed = compose(add1, multiply2)
|
|
23
|
+
* composed(3) // 7 (3 * 2 + 1)
|
|
24
|
+
*/
|
|
25
|
+
declare function compose(...fns: Function[]): Function;
|
|
26
|
+
/**
|
|
27
|
+
* Composes functions from right to left (asynchronous)
|
|
28
|
+
* @param {...Function} fns - Functions to compose (can be sync or async)
|
|
29
|
+
* @return {Function} The composed async function
|
|
30
|
+
* @property {Promise<any>} return - A Promise that resolves to the result of applying all functions
|
|
31
|
+
* @example
|
|
32
|
+
* const add1 = x => x + 1
|
|
33
|
+
* const multiplyAsync = async x => x * 2
|
|
34
|
+
* await composeAsync(add1, multiplyAsync)(3) // 7 (3 * 2 + 1)
|
|
35
|
+
*/
|
|
36
|
+
declare function composeAsync(...fns: Function[]): Function;
|
|
37
|
+
/**
|
|
38
|
+
* Pipes functions from left to right (synchronous)
|
|
39
|
+
* @param {...Function} fns - Functions to pipe
|
|
40
|
+
* @return {Function} The piped function
|
|
41
|
+
* @property {any} return - The result of applying all functions in sequence
|
|
42
|
+
* @example
|
|
43
|
+
* const add1 = x => x + 1
|
|
44
|
+
* const multiply2 = x => x * 2
|
|
45
|
+
* const piped = pipe(add1, multiply2)
|
|
46
|
+
* piped(3) // 8 (3 + 1) * 2
|
|
47
|
+
*/
|
|
48
|
+
declare function pipe(...fns: Function[]): Function;
|
|
49
|
+
/**
|
|
50
|
+
* Pipes functions from left to right (asynchronous)
|
|
51
|
+
* @param {...Function} fns - Functions to pipe (can be sync or async)
|
|
52
|
+
* @return {Function} The piped async function
|
|
53
|
+
* @property {Promise<any>} return - A Promise that resolves to the result of applying all functions
|
|
54
|
+
* @example
|
|
55
|
+
* const add1 = x => x + 1
|
|
56
|
+
* const multiplyAsync = async x => x * 2
|
|
57
|
+
* await pipeAsync(add1, multiplyAsync)(3) // 8 ((3 + 1) * 2)
|
|
58
|
+
*/
|
|
59
|
+
declare function pipeAsync(...fns: Function[]): Function;
|
|
60
|
+
/**
|
|
61
|
+
* Calls a function n times with the current index and returns an array of results
|
|
62
|
+
* @param {Function} fn - Function to call (receives index as argument)
|
|
63
|
+
* @param {number} n - Number of times to call the function
|
|
64
|
+
* @return {any[]} Array of results from calling the function
|
|
65
|
+
* @property {any[]} return - Array containing the results of each function call
|
|
66
|
+
* @example
|
|
67
|
+
* times(i => i * 2, 3) // [0, 2, 4]
|
|
68
|
+
* times(() => Math.random(), 2) // [0.123, 0.456] (random values)
|
|
69
|
+
*/
|
|
70
|
+
declare function times(fn: Function, n: number): any[];
|
|
5
71
|
|
|
6
|
-
export { compose, curry, pipe, times };
|
|
72
|
+
export { compose, composeAsync, curry, pipe, pipeAsync, times };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { debounce } from './debounce.cjs';
|
|
2
2
|
export { getEnv } from './env.cjs';
|
|
3
|
-
export { compose, curry, pipe, times } from './functional.cjs';
|
|
3
|
+
export { compose, composeAsync, curry, pipe, pipeAsync, times } from './functional.cjs';
|
|
4
4
|
export { throttle } from './throttle.cjs';
|
|
5
5
|
export { delay, timeout, wait } from './timeout.cjs';
|
|
@@ -13,7 +13,7 @@ export { flattenArrayFields, formDataToObject } from './form/form-data.cjs';
|
|
|
13
13
|
export { SanitizeOptions, sanitize, sanitizeArray, sanitizeObject } from './form/sanitize.cjs';
|
|
14
14
|
export { debounce } from './functions/debounce.cjs';
|
|
15
15
|
export { getEnv } from './functions/env.cjs';
|
|
16
|
-
export { compose, curry, pipe, times } from './functions/functional.cjs';
|
|
16
|
+
export { compose, composeAsync, curry, pipe, pipeAsync, times } from './functions/functional.cjs';
|
|
17
17
|
export { throttle } from './functions/throttle.cjs';
|
|
18
18
|
export { delay, timeout, wait } from './functions/timeout.cjs';
|
|
19
19
|
export { isHashedValue } from './hash.cjs';
|
package/package.json
CHANGED
|
@@ -4,8 +4,8 @@ import { useObserverMethodOnTarget } from './observer.js'
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Creates and manages a ResizeObserver instance to monitor size changes of a target element.
|
|
7
|
-
*
|
|
8
|
-
* @param {Element|Window|NodeList|Element[]} target - The element(s) to observe.
|
|
7
|
+
*
|
|
8
|
+
* @param {Element|Window|NodeList|Element[]} target - The element(s) to observe.
|
|
9
9
|
* - If window is provided, document.body will be observed instead.
|
|
10
10
|
* - If NodeList or Array of elements is provided, all elements will be observed.
|
|
11
11
|
* @param {Object} options - Configuration options for the resize observer
|
|
@@ -13,13 +13,13 @@ import { useObserverMethodOnTarget } from './observer.js'
|
|
|
13
13
|
* @param {Function} [options.callback] - Optional callback function that will be called when resize changes are detected.
|
|
14
14
|
* If not provided, a 'resize-obs' event will be dispatched on the target.
|
|
15
15
|
* @param {Object} [options.observerOptions] - Additional options to pass to ResizeObserver.observe()
|
|
16
|
-
*
|
|
16
|
+
*
|
|
17
17
|
* @returns {Object} An object with methods to control the observer:
|
|
18
18
|
* - observe(target, options): Start observing a new target element
|
|
19
19
|
* - unobserve(target): Stop observing a target element
|
|
20
20
|
* - disconnect(): Disconnect the observer and stop all observations
|
|
21
21
|
* - destroy(): Alias for disconnect()
|
|
22
|
-
*
|
|
22
|
+
*
|
|
23
23
|
* @example
|
|
24
24
|
* // Basic usage with callback
|
|
25
25
|
* resizeObserver(element, {
|
|
@@ -27,7 +27,7 @@ import { useObserverMethodOnTarget } from './observer.js'
|
|
|
27
27
|
* console.log('Element resized:', entry.contentRect);
|
|
28
28
|
* }
|
|
29
29
|
* });
|
|
30
|
-
*
|
|
30
|
+
*
|
|
31
31
|
* @example
|
|
32
32
|
* // Usage with event listener
|
|
33
33
|
* resizeObserver(element);
|