diff --git a/src/skip/index.ts b/src/skip/index.ts new file mode 100644 index 00000000..9471d9d2 --- /dev/null +++ b/src/skip/index.ts @@ -0,0 +1,55 @@ +import { + Event, + Store, + Unit, + combine, + createEvent, + createStore, + is, + sample, +} from 'effector'; + +export function skip({ + clock, + count, + reset, +}: { + clock?: Unit; + count: Store | number; + reset?: Unit; +}): Event { + const $count = is.store(count) ? count : createStore(count); + + const $skipped = createStore(0); + + const $canTrigger = combine( + [$skipped, $count], + ([skipped, count]) => skipped >= count, + ); + + clock = is.unit(clock) ? clock : createEvent(); + + reset = is.unit(reset) ? reset : createEvent(); + + const event = sample({ + clock, + source: $skipped, + filter: $canTrigger, + fn: (_, params) => params, + }); + + sample({ + clock, + source: $skipped, + filter: $canTrigger.map((canTrigger) => !canTrigger), + fn: (skipped) => skipped + 1, + target: $skipped, + }); + + sample({ + clock: [$count, reset], + target: $skipped.reinit, + }); + + return event; +} diff --git a/src/take/index.ts b/src/take/index.ts new file mode 100644 index 00000000..e3a6b0e6 --- /dev/null +++ b/src/take/index.ts @@ -0,0 +1,52 @@ +import { + Event, + Store, + Unit, + combine, + createEvent, + createStore, + is, + sample, +} from 'effector'; + +export function skip({ + clock, + count, + reset, +}: { + clock: Unit; + count: Store | number; + reset?: Unit; +}): Event { + const $count = is.store(count) ? count : createStore(count); + + const $taken = createStore(0); + + const $canTrigger = combine([$taken, $count], ([taken, count]) => taken >= count); + + clock = is.unit(clock) ? clock : createEvent(); + + reset = is.unit(reset) ? reset : createEvent(); + + const event = sample({ + clock, + source: $taken, + filter: $canTrigger, + fn: (_, params) => params, + }); + + sample({ + clock, + source: $taken, + filter: $canTrigger.map((canTrigger) => !canTrigger), + fn: (taken) => taken + 1, + target: $taken, + }); + + sample({ + clock: [$count, reset], + target: $taken.reinit, + }); + + return event; +}