patronum
Version:
☄️ Effector utility library delivering modularity and convenience
144 lines (143 loc) • 3.63 kB
JavaScript
import { createEvent, createStore, is, sample, attach, merge } from 'effector';
export function debounce() {
var _ref;
var argsShape = arguments.length === 2 ? {
source: arguments.length <= 0 ? undefined : arguments[0],
timeout: arguments.length <= 1 ? undefined : arguments[1]
} : arguments.length <= 0 ? undefined : arguments[0];
var {
source,
timeout,
target,
name
} = argsShape;
if (!is.unit(source)) throw new TypeError('source must be unit from effector');
if (is.domain(source, {
sid: "jsc7s2"
})) throw new TypeError('source cannot be domain');
var $timeout = toStoreNumber(timeout);
var saveCancel = createEvent({
name: "saveCancel",
sid: "-kec0n3"
});
var $canceller = createStore([], {
and: {
serialize: 'ignore'
},
name: "$canceller",
sid: "-tfm9fg"
}).on(saveCancel, (_, payload) => payload);
var tick = (_ref = target) !== null && _ref !== void 0 ? _ref : createEvent({
name: "tick",
sid: "-50e2rn"
});
var timerFx = attach({
and: {
name: name || "debounce(".concat((source === null || source === void 0 ? void 0 : source.shortName) || source.kind, ") effect"),
source: $canceller,
effect(_ref2, timeout) {
var [timeoutId, rejectPromise] = _ref2;
if (timeoutId) clearTimeout(timeoutId);
if (rejectPromise) rejectPromise();
return new Promise((resolve, reject) => {
saveCancel([setTimeout(resolve, timeout), reject]);
});
}
},
or: {
name: "timerFx",
sid: "-jwso4j"
}
});
$canceller.reset(timerFx.done);
// It's ok - nothing will ever start unless source is triggered
var $payload = createStore([], {
and: {
serialize: 'ignore',
skipVoid: false
},
name: "$payload",
sid: "-x9cllg"
}).on(source, (_, payload) => [payload]);
var $canTick = createStore(true, {
and: {
serialize: 'ignore'
},
name: "$canTick",
sid: "8r2952"
});
var triggerTick = createEvent({
name: "triggerTick",
sid: "-781myl"
});
$canTick.on(triggerTick, () => false).on([tick,
// debounce timeout should be restarted on timeout change
$timeout,
// debounce timeout can be restarted in later ticks
timerFx], () => true);
var requestTick = merge([source,
// debounce timeout is restarted on timeout change
sample({
and: [{
clock: $timeout,
filter: timerFx.pending
}],
or: {
name: "requestTick",
sid: "-khrpxp"
}
})], {
name: "requestTick",
sid: "2k0852"
});
sample({
and: [{
clock: requestTick,
filter: $canTick,
target: triggerTick
}],
or: {
sid: "-31h8q8"
}
});
sample({
and: [{
source: $timeout,
clock: triggerTick,
target: timerFx
}],
or: {
sid: "-2y6h62"
}
});
sample({
and: [{
source: $payload,
clock: timerFx.done,
fn: _ref3 => {
var [payload] = _ref3;
return payload;
},
target: tick
}],
or: {
sid: "-2jc15b"
}
});
return tick;
}
function toStoreNumber(value) {
if (is.store(value, {
sid: "-21qm2b"
})) return value;
if (typeof value === 'number') {
if (value < 0 || !Number.isFinite(value)) throw new Error("timeout must be positive number or zero. Received: \"".concat(value, "\""));
return createStore(value, {
and: {
name: '$timeout'
},
sid: "kbepy4"
});
}
throw new TypeError("timeout parameter in interval method should be number or Store. \"".concat(typeof value, "\" was passed"));
}