Skip to content

Instantly share code, notes, and snippets.

@sergeysova
Created February 6, 2020 12:21
Show Gist options
  • Save sergeysova/73eb4afa33466c6b53ae249e109535da to your computer and use it in GitHub Desktop.
Save sergeysova/73eb4afa33466c6b53ae249e109535da to your computer and use it in GitHub Desktop.
// eslint-disable-next-line no-magic-numbers
const TOKEN_UPDATE_TIME_MS = 5 * 60 * 1e3;
const abortTimerToRefreshToken = createEvent();
const timerToRefreshToken = createEffect();
const $canRequestToken = combine(
refreshToken.pending,
timerToRefreshToken.pending,
$isAuthenticated,
(requestPending, refreshPending, isAuth) =>
!requestPending && !refreshPending && isAuth,
);
forward({
from: userLoggedOut,
to: abortTimerToRefreshToken,
});
forward({
from: userIsAuthNow,
to: refreshToken,
});
guard({
source: refreshToken.done,
filter: $canRequestToken,
target: timerToRefreshToken,
});
guard({
source: timerToRefreshToken.done,
filter: $canRequestToken,
target: refreshToken.prepend(empty),
});
timerToRefreshToken.use(() => {
let unsub;
return new Promise((resolve, reject) => {
const id = setTimeout(resolve, TOKEN_UPDATE_TIME_MS);
unsub = abortTimerToRefreshToken.watch(() => {
clearTimeout(id);
reject();
});
}).finally(unsub);
});
function createTimeout(
timeoutMs: number,
abort: Event<void>,
name = 'timeout',
): Effect<void, void> {
const fx = createEffect<void, void>({ name: `${name}Effect` });
fx.use(() => {
let unsub;
return new Promise<void>((resolve, reject) => {
const id = setTimeout(resolve, timeoutMs);
unsub = abort.watch(() => {
clearTimeout(id);
reject();
});
}).finally(unsub);
});
return fx;
}
function empty() {
return undefined;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment