patronum
Version:
☄️ Effector utility library delivering modularity and convenience
91 lines (90 loc) • 2.28 kB
JavaScript
import { createEffect, createEvent, createStore, is, sample } from 'effector';
export function throttle() {
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 = createEvent({
name: "target",
sid: "-gyhb56"
})
} = argsShape;
if (!is.unit(source)) throw new TypeError('source must be unit from effector');
var $timeout = toStoreNumber(timeout);
var timerFx = createEffect({
name: "throttle(".concat(source.shortName || source.kind, ") effect"),
handler: timeout => new Promise(resolve => setTimeout(resolve, timeout))
}, {
name: "timerFx",
sid: "-lp5bot"
});
// It's ok - nothing will ever start unless source is triggered
var $payload = createStore(null, {
and: {
serialize: 'ignore',
skipVoid: false
},
name: "$payload",
sid: "w71tnu"
}).on(source, (_, payload) => payload);
var triggerTick = createEvent({
name: "triggerTick",
sid: "-dquigt"
});
var $canTick = createStore(true, {
and: {
serialize: 'ignore'
},
name: "$canTick",
sid: "e2dxhp"
}).on(triggerTick, () => false).on(target, () => true);
sample({
and: [{
clock: source,
filter: $canTick,
target: triggerTick
}],
or: {
sid: "-hifwv4"
}
});
sample({
and: [{
source: $timeout,
clock: triggerTick,
target: timerFx
}],
or: {
sid: "-h3lgud"
}
});
sample({
and: [{
source: $payload,
clock: timerFx.done,
target
}],
or: {
sid: "-h0apa7"
}
});
return target;
}
function toStoreNumber(value) {
if (is.store(value, {
sid: "-gj92sk"
})) 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: "-2ktcsz"
});
}
throw new TypeError("timeout parameter should be number or Store. \"".concat(typeof value, "\" was passed"));
}