/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @emails oncall+recoil * @flow strict-local * @format */ 'use strict'; import type { Loadable } from '../adt/Recoil_Loadable'; import type { CacheImplementation } from '../caches/Recoil_Cache'; import type { DefaultValue } from '../core/Recoil_Node'; import type { RecoilState, RecoilValue, RecoilValueReadOnly } from '../core/Recoil_RecoilValue'; import type { GetRecoilValue, ResetRecoilState, SetRecoilState } from './Recoil_selector'; const cacheWithValueEquality = require('../caches/Recoil_cacheWithValueEquality'); const stableStringify = require('../util/Recoil_stableStringify'); const selector = require('./Recoil_selector'); // Keep in mind the parameter needs to be serializable as a cahche key // using Recoil_stableStringify export type Parameter = void | null | boolean | number | string | $ReadOnly<{...}> | $ReadOnlyArray; type ReadOnlySelectorFamilyOptions = $ReadOnly<{ key: string, get: (P) => ({ get: GetRecoilValue }) => Promise | RecoilValue | T, cacheImplementation_UNSTABLE?: () => CacheImplementation>, cacheImplementationForParams_UNSTABLE?: () => CacheImplementation>, dangerouslyAllowMutability?: boolean, }>; export type ReadWriteSelectorFamilyOptions = $ReadOnly<{ ...ReadOnlySelectorFamilyOptions, set: (P) => ({ set: SetRecoilState, get: GetRecoilValue, reset: ResetRecoilState, }, newValue: T | DefaultValue) => void, }>; export type SelectorFamilyOptions = ReadOnlySelectorFamilyOptions | ReadWriteSelectorFamilyOptions; // Add a unique index to each selector in case the cache implementation allows // duplicate keys based on equivalent stringified parameters let nextIndex = 0; /* eslint-disable no-redeclare */ declare function selectorFamily(options: ReadOnlySelectorFamilyOptions): (Params) => RecoilValueReadOnly; declare function selectorFamily(options: ReadWriteSelectorFamilyOptions): (Params) => RecoilState; // Return a function that returns members of a family of selectors of the same type // E.g., // // const s = selectorFamily(...); // s({a: 1}) => a selector // s({a: 2}) => a different selector // // By default, the selectors are distinguished by distinct values of the // parameter based on value equality, not reference equality. This allows using // object literals or other equivalent objects at callsites to not create // duplicate cache entries. This behavior may be overridden with the // cacheImplementationForParams option. declare function selectorFamily(options: ReadOnlySelectorFamilyOptions | ReadWriteSelectorFamilyOptions): (Params) => RecoilValue; /* eslint-enable no-redeclare */ module.exports = selectorFamily;