/** * (c) Facebook, Inc. and its affiliates. Confidential and proprietary. * * @emails oncall+recoil * @flow strict-local * @format */ 'use strict'; export type NodeCacheRoute = Array<[mixed, mixed]>; export type TreeCacheNode = TreeCacheLeaf | TreeCacheBranch; export type TreeCacheLeaf = { type: 'leaf', value: T, branchKey?: ?mixed, parent: ?TreeCacheBranch, }; export type TreeCacheBranch = { type: 'branch', nodeKey: mixed, branches: Map>, branchKey?: ?mixed, parent: ?TreeCacheBranch, }; export type NodeValueGet = (nodeKey: mixed) => mixed; type NodeVisitHandler = (node: TreeCacheNode) => void; export type GetHandlers = { onNodeVisit: NodeVisitHandler }; export type SetHandlers = { onNodeVisit: NodeVisitHandler }; /** * This is an opinionated tree cache that conforms to the requirements needed * by Recoil selectors. * * Unlike a conventional cache, the tree cache does not store key-value pairs, * but "routes" that point to values. In the context of selectors these routes * represent dependencies that a selector has to other atoms and selectors. * * In order to retrieve a value from the cache, a function is passed to the * cache's `get()` method, and the tree cache will use that function to traverse * itself, passing the provided function a "key" (the first part of the route tuple), * reconstructing the route to some value (or undefined). * * The handlers are necessary for the selector to be able to capture the * incremental nodes in the tree that are traversed while looking for a cache * hit as these incremental nodes represent dependencies to the selector, which * are used internally by the selector. */ export interface TreeCacheImplementation { +get: (NodeValueGet, handlers?: GetHandlers) => ?T, +set: (NodeCacheRoute, T, handlers?: SetHandlers) => void, +delete: (TreeCacheNode) => boolean, +clear: () => void, +root: () => ?TreeCacheNode, +size: () => number, }