Skip to content

⬅️ Back to Table of Contents

📄 useRefHistory

📊 Analysis Summary

Metric Count
🔧 Functions 7
📦 Imports 9
📐 Interfaces 2

📚 Table of Contents

🛠️ File Location:

📂 packages/core/useRefHistory/index.ts

📦 Imports

Name Source
ConfigurableEventFilter @vueuse/shared
ConfigurableFlush @vueuse/shared
Fn @vueuse/shared
Ref vue
CloneFn ../useCloned
UseManualRefHistoryReturn ../useManualRefHistory
pausableFilter @vueuse/shared
watchIgnorable @vueuse/shared
useManualRefHistory ../useManualRefHistory

Functions

useRefHistory(source: Ref<Raw>, options: UseRefHistoryOptions<Raw, Serialized>): UseRefHistoryReturn<Raw, Serialized>

Track the change history of a ref, also provides undo and redo functionality.

Parameters:

  • source any: No description
  • options any: No description

See: https://vueuse.org/useRefHistory

Raw JSDoc
/**
 * Track the change history of a ref, also provides undo and redo functionality.
 *
 * @see https://vueuse.org/useRefHistory
 * @param source
 * @param options
 */

Calls:

  • pausableFilter (from @vueuse/shared)
  • watchIgnorable (from @vueuse/shared)
  • ignorePrevAsyncUpdates
  • ignoreUpdates
  • useManualRefHistory (from ../useManualRefHistory)
  • shouldCommit
  • manualCommit
  • resumeTracking
  • commit
  • fn
  • stop
  • clear

Internal Comments:

// Track the last raw value for shouldCommit comparison (x2)
// Support changes that are done after the last history operation (x3)
// examples: (x6)
//   undo, modify (x3)
//   undo, undo, modify (x3)
// If there were already changes in the state, they will be ignored (x3)
//   modify, undo (x3)
//   undo, modify, undo (x3)
// This guard only applies for flush 'pre' and 'post' (x3)
// If the user triggers a commit manually, then reset the watcher (x3)
// so we do not trigger an extra commit in the async watcher (x3)

Code
export function useRefHistory<Raw, Serialized = Raw>(
  source: Ref<Raw>,
  options: UseRefHistoryOptions<Raw, Serialized> = {},
): UseRefHistoryReturn<Raw, Serialized> {
  const {
    deep = false,
    flush = 'pre',
    eventFilter,
    shouldCommit = () => true,
  } = options

  const {
    eventFilter: composedFilter,
    pause,
    resume: resumeTracking,
    isActive: isTracking,
  } = pausableFilter(eventFilter)

  // Track the last raw value for shouldCommit comparison
  let lastRawValue: Raw | undefined = source.value

  const {
    ignoreUpdates,
    ignorePrevAsyncUpdates,
    stop,
  } = watchIgnorable(
    source,
    commit,
    { deep, flush, eventFilter: composedFilter },
  )

  function setSource(source: Ref<Raw>, value: Raw) {
    // Support changes that are done after the last history operation
    // examples:
    //   undo, modify
    //   undo, undo, modify
    // If there were already changes in the state, they will be ignored
    // examples:
    //   modify, undo
    //   undo, modify, undo
    ignorePrevAsyncUpdates()

    ignoreUpdates(() => {
      source.value = value
      lastRawValue = value
    })
  }

  const manualHistory = useManualRefHistory(source, { ...options, clone: options.clone || deep, setSource })

  const { clear, commit: manualCommit } = manualHistory

  function commit() {
    // This guard only applies for flush 'pre' and 'post'
    // If the user triggers a commit manually, then reset the watcher
    // so we do not trigger an extra commit in the async watcher
    ignorePrevAsyncUpdates()

    if (!shouldCommit(lastRawValue, source.value))
      return

    lastRawValue = source.value
    manualCommit()
  }

  function resume(commitNow?: boolean) {
    resumeTracking()
    if (commitNow)
      commit()
  }

  function batch(fn: (cancel: Fn) => void) {
    let canceled = false

    const cancel = () => canceled = true

    ignoreUpdates(() => {
      fn(cancel)
    })

    if (!canceled)
      commit()
  }

  function dispose() {
    stop()
    clear()
  }
  return {
    ...manualHistory,
    isTracking,
    pause,
    resume,
    commit,
    batch,
    dispose,
  }
}

Internal helpers

Declared inside another function in this file.

setSource(source: Ref<Raw>, value: Raw): void

Parameters:

  • source Ref<Raw>
  • value Raw

Returns: void

Calls:

  • ignorePrevAsyncUpdates
  • ignoreUpdates

Internal Comments:

// Support changes that are done after the last history operation (x3)
// examples: (x6)
//   undo, modify (x3)
//   undo, undo, modify (x3)
// If there were already changes in the state, they will be ignored (x3)
//   modify, undo (x3)
//   undo, modify, undo (x3)

Code
function setSource(source: Ref<Raw>, value: Raw) {
    // Support changes that are done after the last history operation
    // examples:
    //   undo, modify
    //   undo, undo, modify
    // If there were already changes in the state, they will be ignored
    // examples:
    //   modify, undo
    //   undo, modify, undo
    ignorePrevAsyncUpdates()

    ignoreUpdates(() => {
      source.value = value
      lastRawValue = value
    })
  }

commit(): void

Returns: void

Calls:

  • ignorePrevAsyncUpdates
  • shouldCommit
  • manualCommit

Internal Comments:

// This guard only applies for flush 'pre' and 'post' (x3)
// If the user triggers a commit manually, then reset the watcher (x3)
// so we do not trigger an extra commit in the async watcher (x3)

Code
function commit() {
    // This guard only applies for flush 'pre' and 'post'
    // If the user triggers a commit manually, then reset the watcher
    // so we do not trigger an extra commit in the async watcher
    ignorePrevAsyncUpdates()

    if (!shouldCommit(lastRawValue, source.value))
      return

    lastRawValue = source.value
    manualCommit()
  }

resume(commitNow: boolean): void

Parameters:

  • commitNow boolean

Returns: void

Calls:

  • resumeTracking
  • commit
Code
function resume(commitNow?: boolean) {
    resumeTracking()
    if (commitNow)
      commit()
  }

batch(fn: (cancel: Fn) => void): void

Parameters:

  • fn (cancel: Fn) => void

Returns: void

Calls:

  • ignoreUpdates
  • fn
  • commit
Code
function batch(fn: (cancel: Fn) => void) {
    let canceled = false

    const cancel = () => canceled = true

    ignoreUpdates(() => {
      fn(cancel)
    })

    if (!canceled)
      commit()
  }

cancel(): boolean

Returns: boolean

Code
() => canceled = true

dispose(): void

Returns: void

Calls:

  • stop
  • clear
Code
function dispose() {
    stop()
    clear()
  }

Interfaces

UseRefHistoryOptions<Raw, Serialized = Raw>

Interface Code
export interface UseRefHistoryOptions<Raw, Serialized = Raw> extends ConfigurableEventFilter, ConfigurableFlush {
  /**
   * Watch for deep changes, default to false
   *
   * When set to true, it will also create clones for values store in the history
   *
   * @default false
   */
  deep?: boolean

  /**
   * Maximum number of history to be kept. Default to unlimited.
   */
  capacity?: number

  /**
   * Clone when taking a snapshot, shortcut for dump: JSON.parse(JSON.stringify(value)).
   * Default to false
   *
   * @default false
   */
  clone?: boolean | CloneFn<Raw>
  /**
   * Serialize data into the history
   */
  dump?: (v: Raw) => Serialized
  /**
   * Deserialize data from the history
   */
  parse?: (v: Serialized) => Raw
  /**
   * Function to determine if the commit should proceed
   * @param oldValue Previous value
   * @param newValue New value
   * @returns boolean indicating if commit should proceed
   */
  shouldCommit?: (oldValue: Raw | undefined, newValue: Raw) => boolean
}

Properties

Name Type Optional Description
deep boolean not shown
capacity number not shown
clone boolean \| CloneFn<Raw> not shown
dump (v: Raw) => Serialized not shown
parse (v: Serialized) => Raw not shown
shouldCommit (oldValue: Raw \| undefined, newValue: Raw) => boolean not shown

UseRefHistoryReturn<Raw, Serialized>

Interface Code
export interface UseRefHistoryReturn<Raw, Serialized> extends UseManualRefHistoryReturn<Raw, Serialized> {
  /**
   * A ref representing if the tracking is enabled
   */
  isTracking: Ref<boolean>

  /**
   * Pause change tracking
   */
  pause: () => void

  /**
   * Resume change tracking
   *
   * @param [commit] if true, a history record will be create after resuming
   */
  resume: (commit?: boolean) => void

  /**
   * A sugar for auto pause and auto resuming within a function scope
   *
   * @param fn
   */
  batch: (fn: (cancel: Fn) => void) => void

  /**
   * Clear the data and stop the watch
   */
  dispose: () => void
}

Properties

Name Type Optional Description
isTracking Ref<boolean> not shown
pause () => void not shown
resume (commit?: boolean) => void not shown
batch (fn: (cancel: Fn) => void) => void not shown
dispose () => void not shown

Generated by Syntax Scribe