/** * 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 { CachePolicy, CachePolicyWithoutEviction } from '../caches/Recoil_CachePolicy'; import type { DefaultValue } from '../core/Recoil_Node'; import type { RecoilState, RecoilValue, RecoilValueReadOnly } from '../core/Recoil_RecoilValue'; import type { RetainedBy } from '../core/Recoil_RetainedBy'; import type { GetCallback } from '../recoil_values/Recoil_selector'; import type { GetRecoilValue, ResetRecoilState, SetRecoilState } from './Recoil_callbackTypes'; const cacheFromPolicy = require('../caches/Recoil_cacheFromPolicy'); const { setConfigDeletionHandler } = require('../core/Recoil_Node'); 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 type Primitive = void | null | boolean | number | string; export type Parameter = Primitive | { toJSON: () => string, ... } | $ReadOnlyArray | $ReadOnly<{...}>; // | $ReadOnly<{[string]: Parameter}>; // TODO Better enforce object is serializable type ReadOnlySelectorFamilyOptions = $ReadOnly<{ key: string, get: (P) => ({ get: GetRecoilValue, getCallback: GetCallback, }) => Promise | RecoilValue | T, cachePolicyForParams_UNSTABLE?: CachePolicyWithoutEviction, cachePolicy_UNSTABLE?: CachePolicy, dangerouslyAllowMutability?: boolean, retainedBy_UNSTABLE?: RetainedBy | ((P) => RetainedBy), }>; 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;