hunk.code_window:     requestFrame,
     }: {
       update?: FrameUpdater
       onFrame?: FrameListener
       requestFrame?: typeof requestAnimationFrame
     } = {}) {
  
hunk.labels: keep keep keep keep replace keep
hunk.after_edit:     requestFrame?: RequestFrameFn
  
hunk.file_path: packages/core/src/FrameLoop.ts
hunk.type: replace
file: import { useCallback, useState, useEffect, useRef } from 'react'
  import { Indexable } from './types'
  
  export * from './types'
  export * from './createInterpolator'
  
  import * as Globals from './globals'
  export { Globals }
  
  interface IsArray {
    <T>(a: T): a is T & ReadonlyArray<any>
  }
  
  type PlainObject<T> = Exclude<T & Indexable, Function | ReadonlyArray<any>>
  
  export const is = {
    arr: Array.isArray as IsArray,
    obj: <T extends any>(a: T): a is PlainObject<T> =>
      !!a && a.constructor.name === 'Object',
    fun: (a: unknown): a is Function => typeof a === 'function',
    str: (a: unknown): a is string => typeof a === 'string',
    num: (a: unknown): a is number => typeof a === 'number',
    und: (a: unknown): a is undefined => a === void 0,
    boo: (a: unknown): a is boolean => typeof a === 'boolean',
  }
  
  export function useOnce(effect: React.EffectCallback) {
    useEffect(effect, [])
  }
  
  export function useForceUpdate() {
    const [, f] = useState(false)
    const forceUpdate = useCallback(() => f(v => !v), [])
    return forceUpdate
  }
  
  /** Use a value from the previous render */
  export function usePrev<T>(value: T): T | undefined {
    const prevRef = useRef<any>(undefined)
    const prev = prevRef.current
    prevRef.current = value
    return prev
  }
  