igorkamyshev / farfetched

The advanced data fetching tool for web applications
https://ff.effector.dev
MIT License
190 stars 34 forks source link

Barrier: Add a way to check if it's active asynchronously #457

Open optislav opened 7 months ago

optislav commented 7 months ago

In the docs, we have this example:

import { createBarrier } from '@farfetched/core';

const $authToken = createStore(/* ... */);

const authBarrier = createBarrier({
  active: combine($authToken, (token) => isTokenInvalid(token)),
});

However, there is no way to check if the token is valid synchronously in Firebase, as getIdToken() always returns a promise. https://firebase.google.com/docs/reference/js/v8/firebase.User#getidtoken

Maybe active should also accept an effect that returns a boolean?

optislav commented 7 months ago

We can use an external library (e.g., jwt-decode) to validate the Firebase token. So even though we can't get the token from the Firebase SDK synchronously, this barrier will get it asynchronously if the token is undefined.

const FIVE_MINUTES_MS = 5 * 60 * 1000 // Firebase default behavior to fetch new token if 5 minutes left
const isTokenAlmostExpired = (jwt: string | null) => {
  if (!jwt) return true
  const { exp } = jwtDecode(jwt)
  if (!exp) return true
  return Date.now() + FIVE_MINUTES_MS > exp * 1000
}

export const authBarrier = createBarrier({
  active: combine($authToken, (token) => isTokenAlmostExpired(token)),
  perform: [getTokenMutation],
})