function atomFamily()

in packages/recoil/recoil_values/Recoil_atomFamily.js [103:172]


function atomFamily<T, P: Parameter>(
  options: AtomFamilyOptions<T, P>,
): P => RecoilState<T> {
  const atomCache = cacheFromPolicy<P, RecoilState<T>>({
    equality: options.cachePolicyForParams_UNSTABLE?.equality ?? 'value',
    eviction: 'keep-all',
  });

  // Simple atomFamily implementation to cache individual atoms based
  // on the parameter value equality.
  return (params: P) => {
    const cachedAtom = atomCache.get(params);
    if (cachedAtom != null) {
      return cachedAtom;
    }

    const {cachePolicyForParams_UNSTABLE, ...atomOptions} = options;
    const optionsDefault:
      | RecoilValue<T>
      | Promise<T>
      | Loadable<T>
      | WrappedValue<T>
      | T
      | (P => T | RecoilValue<T> | Promise<T> | Loadable<T> | WrappedValue<T>) =
      'default' in options
        ? // $FlowIssue[prop-missing] No way to refine in Flow that property is not defined
          // $FlowIssue[incompatible-type] No way to refine in Flow that property is not defined
          options.default
        : new Promise(() => {});

    const newAtom = atom<T>({
      ...atomOptions,
      key: `${options.key}__${stableStringify(params) ?? 'void'}`,
      default:
        typeof optionsDefault === 'function'
          ? // The default was parameterized
            // Flow doesn't know that T isn't a function, so we need to case to any
            // $FlowIssue[incompatible-use]
            optionsDefault(params)
          : // Default may be a static value, promise, or RecoilValue
            optionsDefault,

      retainedBy_UNSTABLE:
        typeof options.retainedBy_UNSTABLE === 'function'
          ? options.retainedBy_UNSTABLE(params)
          : options.retainedBy_UNSTABLE,

      effects:
        typeof options.effects === 'function'
          ? options.effects(params)
          : typeof options.effects_UNSTABLE === 'function'
          ? options.effects_UNSTABLE(params)
          : options.effects ?? options.effects_UNSTABLE,

      // prettier-ignore
      // @fb-only: scopeRules_APPEND_ONLY_READ_THE_DOCS: mapScopeRules(
      // @fb-only: options.scopeRules_APPEND_ONLY_READ_THE_DOCS,
      // @fb-only: params,
      // @fb-only: ),
    });

    atomCache.set(params, newAtom);

    setConfigDeletionHandler(newAtom.key, () => {
      atomCache.delete(params);
    });

    return newAtom;
  };
}