Skip to content

Instantly share code, notes, and snippets.

@NazariiShvets
Last active October 10, 2023 17:00
Show Gist options
  • Save NazariiShvets/4daa17991c0a1c878270810ef2ba1478 to your computer and use it in GitHub Desktop.
Save NazariiShvets/4daa17991c0a1c878270810ef2ba1478 to your computer and use it in GitHub Desktop.
chainRoute with feature flags?
import type { RouteInstance, RouteParams } from 'atomic-router';
import type { Store } from 'effector';
import { combine } from 'effector';
import {
mergeChained,
prepareConditionalRouteForChain
} from '@acme/atomic-router';
import { $$cacheSessionFeatureFlag } from '@acme/shared/feature-flags/features';
import type { CreateAuthorizedRouteConfig as CreateCachedAuthorizedRouteConfig } from './authorized.factory.cached';
import { createAuthorizedRoute as createCachedAuthorizedRoute } from './authorized.factory.cached';
import { createAuthorizedRoute as createLegacyAuthorizedRoute } from './authorized.factory.legacy';
const createAuthorizedRoute = <TRouteParams extends RouteParams = {}>(
route: RouteInstance<TRouteParams>,
config: CreateCachedAuthorizedRouteConfig<TRouteParams> = {}
): RouteInstance<TRouteParams> & { $pending: Store<boolean> } => {
// Has side-effects on failed chain
const cachedChainedRoute = createCachedAuthorizedRoute(
prepareConditionalRouteForChain($$cacheSessionFeatureFlag.$enabled, route),
config
);
// Has different side-effects on failed chain
const legacyChainedRoute = createLegacyAuthorizedRoute(
prepareConditionalRouteForChain($$cacheSessionFeatureFlag.$disabled, route)
);
const chainedRoute = mergeChained(
$$cacheSessionFeatureFlag.$enabled,
cachedChainedRoute,
legacyChainedRoute
);
return Object.assign(chainedRoute, {
$pending: combine(
$$cacheSessionFeatureFlag.$enabled,
cachedChainedRoute.$pending,
legacyChainedRoute.$pending,
(useCached, cachedPending, legacyPending) =>
useCached ? cachedPending : legacyPending
)
});
};
export { createAuthorizedRoute };
import { Kind, RouteInstance, RouteParams } from 'atomic-router';
import { attach, combine, merge, sample, Store } from 'effector';
import { not } from 'patronum';
function mergeChained<TRouteParams extends RouteParams = {}>(
$condition: Store<boolean>,
route1: RouteInstance<TRouteParams>,
route2: RouteInstance<TRouteParams>
) {
const resultRoute: RouteInstance<TRouteParams> = {
open: attach({
source: $condition,
effect: (condition, params) =>
condition ? route1.open(params) : route2.open(params)
}),
navigate: attach({
source: $condition,
effect: (condition, params) =>
condition ? route1.navigate(params) : route2.navigate(params)
}),
$isOpened: combine(
$condition,
route1.$isOpened,
route2.$isOpened,
(condition, left, right) => (condition ? left : right)
),
$params: combine(
$condition,
route1.$params,
route2.$params,
(condition, left, right) => (condition ? left : right)
),
$query: combine(
$condition,
route1.$query,
route2.$query,
(condition, left, right) => (condition ? left : right)
),
opened: merge([
sample({ clock: route1.opened, filter: $condition }),
sample({ clock: route2.opened, filter: not($condition) })
]),
updated: merge([
sample({ clock: route1.updated, filter: $condition }),
sample({ clock: route2.updated, filter: not($condition) })
]),
closed: merge([
sample({ clock: route1.closed, filter: $condition }),
sample({ clock: route2.closed, filter: not($condition) })
]),
kind: Kind.ROUTE,
//@ts-expect-error https://github.com/atomic-router/atomic-router/blob/a0c4b2a254297b889ba1e16fada0a3bd5de2b4d3/src/methods/create-route.ts#L94
settings: {
derived: true
}
};
return resultRoute;
}
export { mergeChained };
import { Kind, RouteInstance, RouteParams } from 'atomic-router';
import { attach, combine, sample, Store } from 'effector';
function prepareConditionalRouteForChain<TRouteParams extends RouteParams = {}>(
$condition: Store<boolean>,
route: RouteInstance<TRouteParams>
) {
const stableEmptyObjectReference = {} as TRouteParams;
const conditionedRoute: RouteInstance<TRouteParams> = {
open: attach({
source: $condition,
effect: (condition, params) => {
if (!condition) throw new Error('Condition for this route is disabled');
return route.open(params);
}
}),
navigate: attach({
source: $condition,
effect: (condition, params) => {
if (!condition) throw new Error('Condition for this route is disabled');
return route.navigate(params);
}
}),
$isOpened: combine($condition, route.$isOpened, (condition, isOpened) =>
condition ? isOpened : false
),
$params: combine($condition, route.$params, (condition, params) =>
condition ? params : stableEmptyObjectReference
),
$query: combine($condition, route.$params, (condition, params) =>
condition ? params : stableEmptyObjectReference
),
opened: sample({ clock: route.opened, filter: $condition }),
updated: sample({ clock: route.updated, filter: $condition }),
closed: sample({ clock: route.closed, filter: $condition }),
kind: Kind.ROUTE,
//@ts-expect-error https://github.com/atomic-router/atomic-router/blob/a0c4b2a254297b889ba1e16fada0a3bd5de2b4d3/src/methods/create-route.ts#L94
settings: {
derived: true
}
};
return conditionedRoute;
}
export { prepareConditionalRouteForChain };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment