@hello-pangea/dnd
Version:
Beautiful and accessible drag and drop for lists with React
53 lines (43 loc) • 1.13 kB
text/typescript
import { invariant } from '../../../invariant';
interface Entry {
timerId: TimeoutID;
callback: () => void;
}
export interface AsyncMarshal {
add: (fn: () => void) => void;
flush: () => void;
}
export default () => {
const entries: Entry[] = [];
const execute = (timerId: TimeoutID) => {
const index: number = entries.findIndex(
(item): boolean => item.timerId === timerId,
);
invariant(index !== -1, 'Could not find timer');
// delete in place
const [entry] = entries.splice(index, 1);
entry.callback();
};
const add = (fn: () => void) => {
const timerId: TimeoutID = setTimeout(() => execute(timerId));
const entry: Entry = {
timerId,
callback: fn,
};
entries.push(entry);
};
const flush = () => {
// nothing to flush
if (!entries.length) {
return;
}
const shallow: Entry[] = [...entries];
// clearing entries in case a callback adds some more callbacks
entries.length = 0;
shallow.forEach((entry: Entry) => {
clearTimeout(entry.timerId);
entry.callback();
});
};
return { add, flush };
};