hunk.code_window:     }
       // Ensure the initial value can be accessed by animated components.
       const range = this._prepareNode(props)
       return scheduleProps<T>(++this._lastCallId, {
         key: this.key,
  
hunk.labels: keep add keep keep keep keep keep
hunk.after_edit:     // These props are coerced into booleans by the `scheduleProps` function,
       // so they need their default values processed before then.
       mergeDefaultProp('cancel')
       mergeDefaultProp('pause')
  
hunk.file_path: packages/core/src/SpringValue.ts
hunk.type: add
file: import { useMemoOne } from 'use-memo-one'
  import {
    is,
    each,
    toArray,
    getFluidConfig,
    isAnimatedString,
    AnyFn,
    OneOrMore,
    FluidValue,
    Lookup,
  } from 'shared'
  import * as G from 'shared/globals'
  import { ReservedProps, ForwardProps, InferTo } from './types'
  
  // @see https://github.com/alexreardon/use-memo-one/pull/10
  export const useMemo: typeof useMemoOne = (create, deps) =>
    useMemoOne(create, deps || [{}])
  
  export function callProp<T>(
    value: T,
    ...args: T extends AnyFn ? Parameters<T> : unknown[]
  ): T extends AnyFn<any, infer U> ? U : T {
    return is.fun(value) ? value(...args) : value
  }
  
  /** Try to coerce the given value into a boolean using the given key */
  export const matchProp = (
    value: boolean | OneOrMore<string> | ((key: any) => boolean) | undefined,
    key: string | undefined
  ) =>
    value === true ||
    !!(
      key &&
      value &&
      (is.fun(value) ? value(key) : toArray(value).includes(key))
    )
  
  export const concatFn = <T extends AnyFn>(first: T | undefined, last: T) =>
    first ? (...args: Parameters<T>) => (first(...args), last(...args)) : last
  
  type AnyProps<T, Arg = never> = OneOrMore<T> | ((i: number, arg: Arg) => T)
  
  export const getProps = <T, Arg = never>(
    props: AnyProps<T, Arg> | null | undefined,
    i: number,
    arg: Arg
  ) =>
    props &&
    (is.fun(props) ? props(i, arg) : is.arr(props) ? props[i] : { ...props })
  
  /** Returns `true` if the given prop is having its default value set. */
  export const isDefaultProp = <T extends Lookup>(props: T, key: keyof T) =>
    !is.und(
      props.default === true ? props[key] : props.default && props.default[key]
    )
  
  export const mergeDefaultProps = (
    defaultProps: Lookup,
    props: Lookup & { default?: boolean | Lookup }
  ) => {
    if (props.default === true) {
      each(DEFAULT_PROPS, key => {
        const value = props[key]
        if (!is.und(value)) {
          defaultProps[key] = value as any
        }
      })
    } else if (props.default) {
      each(props.default, (value, key) => {
        if (!is.und(value)) {
          defaultProps[key] = value as any
        }
      })
    }
  }
  
  /** These props can have default values */
  export const DEFAULT_PROPS = [
    'pause',
    'cancel',
    'config',
    'immediate',
    'onDelayEnd',
    'onProps',
    'onStart',
    'onChange',
    'onRest',
  ] as const
  
  const RESERVED_PROPS: Required<ReservedProps> = {
    children: 1,
    config: 1,
    from: 1,
    to: 1,
    ref: 1,
    loop: 1,
    reset: 1,
    pause: 1,
    cancel: 1,
    reverse: 1,
    immediate: 1,
    default: 1,
    delay: 1,
    keys: 1,
    items: 1,
    trail: 1,
    sort: 1,
    expires: 1,
    initial: 1,
    enter: 1,
    leave: 1,
    update: 1,
    onDelayEnd: 1,
    onProps: 1,
    onStart: 1,
    onChange: 1,
    onRest: 1,
  }
  
  /**
   * Extract any properties whose keys are *not* reserved for customizing your
   * animations. All hooks use this function, which means `useTransition` props
   * are reserved for `useSpring` calls, etc.
   */
  function getForwardProps<Props extends ReservedProps>(
    props: Props
  ): ForwardProps<Props> | undefined {
    const forward: any = {}
  
    let count = 0
    each(props, (value, prop) => {
      if (!RESERVED_PROPS[prop]) {
        forward[prop] = value
        count++
      }
    })
  
    if (count) {
      return forward
    }
  }
  
  /**
   * Clone the given `props` and move all non-reserved props
   * into the `to` prop.
   */
  export function inferTo<T extends object>(props: T): InferTo<T> {
    const to = getForwardProps(props)
    if (to) {
      const out: any = { to }
      each(props, (val, key) => key in to || (out[key] = val))
      return out
    }
    return { ...props } as any
  }
  
  // Compute the goal value, converting "red" to "rgba(255, 0, 0, 1)" in the process
  export function computeGoal<T>(value: T | FluidValue<T>): T {
    const config = getFluidConfig(value)
    return config
      ? computeGoal(config.get())
      : is.arr(value)
      ? value.map(computeGoal)
      : isAnimatedString(value)
      ? (G.createStringInterpolator({
          range: [0, 1],
          output: [value, value] as any,
        })(1) as any)
      : value
  }
  
  /** Basic helper for clearing a queue after processing it */
  export function flush<P, T>(
    queue: Map<P, T>,
    iterator: (entry: [P, T]) => void
  ): void
  export function flush<T>(queue: Set<T>, iterator: (value: T) => void): void
  export function flush(queue: any, iterator: any) {
    if (queue.size) {
      const items = Array.from(queue)
      queue.clear()
      each(items, iterator)
    }
  }
  