From 6cc40d7baf9d071dbaac55e7ee1ced28a67aadfa Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Wed, 24 Feb 2021 09:56:07 -0330 Subject: [PATCH] Add doc comments for all public functions and types Note that the metadata type was split up to make it easier to use the `@property` JSDoc directive. --- src/BaseControllerV2.ts | 67 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/src/BaseControllerV2.ts b/src/BaseControllerV2.ts index 7c55840f369..dce94b183b3 100644 --- a/src/BaseControllerV2.ts +++ b/src/BaseControllerV2.ts @@ -7,7 +7,15 @@ import type { Draft, Patch } from 'immer'; enablePatches(); /** - * State change callbacks + * A state change listener. + * + * This function will get called for each state change, and is given a copy of + * the new state along with a set of patches describing the changes since the + * last update. + * + * @param state - The new controller state + * @param patches - A list of patches describing any changes (see here for more + * information: https://immerjs.github.io/immer/docs/patches) */ export type Listener = (state: T, patches: Patch[]) => void; @@ -22,17 +30,46 @@ type RecursivePartial = { RecursivePartial; }; +/** + * An anonymizing function + * + * This function will accept one piece of the controller state (one property), + * and will return an anonymized representation of this state. By "anonymized", + * we mean that it should not contain any information that could be personally + * identifiable. + * + * @param value - A piece of controller state + * @returns An anonymized representation of the given state + */ export type Anonymizer = (value: T) => T extends Primitive ? T : RecursivePartial; +/** + * State metadata. + * + * This metadata describes which parts of state should be persisted, and how to + * get an anonymized representation of the state. + */ export type StateMetadata = { - [P in keyof T]: { - persist: boolean; - anonymous: boolean | Anonymizer; - }; + [P in keyof T]: StatePropertyMetadata }; /** - * Controller class that provides state management and subscriptions + * Metadata for a single state property + * + * @property persist - Indicates whether this property should be persisted + * (`true` for persistent, `false` for transient) + * @property anonymous - Indicates whether this property is already anonymous, + * (`true` for anonymous, `false` if it has potential to be personally + * identifiable), or is set to a function that returns an anonymized + * representation of this state. + */ +export interface StatePropertyMetadata

{ + persist: boolean; + anonymous: boolean | Anonymizer

; +} + +/** + * Controller class that provides state management, subscriptions, and state metadata */ export class BaseController> { private internalState: S; @@ -120,6 +157,17 @@ function isAnonymizingFunction(x: boolean | Anonymizer): x is Anonymizer>(state: S, metadata: StateMetadata): RecursivePartial { return Object.keys(state).reduce((anonymizedState, _key) => { const key: keyof S = _key; // https://stackoverflow.com/questions/63893394/string-cannot-be-used-to-index-type-t @@ -133,6 +181,13 @@ export function getAnonymizedState>(state: S, meta }, {} as RecursivePartial); } +/** + * Returns the subset of state that should be persisted + * + * @param state - The controller state + * @param metadata - The controller state metadata, which describes which pieces of state should be persisted + * @returns The subset of controller state that should be persisted + */ export function getPersistentState>(state: S, metadata: StateMetadata): RecursivePartial { return Object.keys(state).reduce((persistedState, _key) => { const key: keyof S = _key; // https://stackoverflow.com/questions/63893394/string-cannot-be-used-to-index-type-t