CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vue--runtime-core

Vue.js 3 runtime core library providing foundational APIs for building custom renderers and managing reactive component systems

Pending
Overview
Eval results
Files

watch-effects.mddocs/

Watch & Effects

Vue's watch system enables reactive observation of data changes with flexible scheduling and deep/shallow watching options. Effects provide low-level reactive behavior for custom reactivity patterns.

Capabilities

Watch Functions

Watch reactive data sources and execute callbacks when they change.

/**
 * Watches a single reactive source
 * @param source - Reactive source to watch
 * @param callback - Callback executed when source changes
 * @param options - Watch configuration options
 * @returns Function to stop the watcher
 */
function watch<T, Immediate extends Readonly<boolean> = false>(
  source: WatchSource<T>,
  callback: WatchCallback<T, Immediate extends true ? T | undefined : T>,
  options?: WatchOptions<T, Immediate>
): WatchHandle;

/**
 * Watches multiple reactive sources
 * @param sources - Array of reactive sources to watch
 * @param callback - Callback executed when any source changes
 * @param options - Watch configuration options
 * @returns Function to stop the watcher
 */
function watch<T extends MultiWatchSources, Immediate extends Readonly<boolean> = false>(
  sources: [...T],
  callback: WatchCallback<MapSources<T>, Immediate extends true ? Partial<MapSources<T>> : MapSources<T>>,
  options?: WatchOptions<T, Immediate>
): WatchHandle;

/**
 * Watches an object and its properties
 * @param source - Object to watch
 * @param callback - Callback executed when object changes
 * @param options - Watch configuration options
 * @returns Function to stop the watcher
 */
function watch<T extends object, Immediate extends Readonly<boolean> = false>(
  source: T,
  callback: WatchCallback<T, Immediate extends true ? T | undefined : T>,
  options?: WatchOptions<T, Immediate>
): WatchHandle;

Usage Examples:

import { ref, reactive, watch } from "@vue/runtime-core";

const count = ref(0);
const state = reactive({ name: "Vue", version: 3 });

// Watch a ref
const stopWatchingCount = watch(count, (newValue, oldValue) => {
  console.log(`Count changed from ${oldValue} to ${newValue}`);
});

// Watch multiple sources
const stopWatchingMultiple = watch(
  [count, () => state.name],
  ([newCount, newName], [oldCount, oldName]) => {
    console.log(`Count: ${oldCount} -> ${newCount}`);
    console.log(`Name: ${oldName} -> ${newName}`);
  }
);

// Watch with immediate execution
watch(
  () => state.version,
  (version) => {
    console.log(`Version: ${version}`);
  },
  { immediate: true } // Runs immediately with current value
);

// Deep watch for objects
watch(
  state,
  (newState, oldState) => {
    console.log("State changed:", newState);
  },
  { deep: true } // Watches nested properties
);

// Cleanup
stopWatchingCount();
stopWatchingMultiple();

WatchEffect Functions

Automatically track dependencies and re-run when they change.

/**
 * Runs a function immediately and re-runs when dependencies change
 * @param effect - Function to run and track dependencies
 * @param options - Effect configuration options
 * @returns Function to stop the effect
 */
function watchEffect(
  effect: WatchEffect,
  options?: WatchEffectOptions
): WatchStopHandle;

/**
 * Like watchEffect but runs after component updates (post-flush)
 * @param effect - Function to run and track dependencies
 * @param options - Effect configuration options
 * @returns Function to stop the effect
 */
function watchPostEffect(
  effect: WatchEffect,
  options?: WatchEffectOptions
): WatchStopHandle;

/**
 * Like watchEffect but runs synchronously
 * @param effect - Function to run and track dependencies
 * @param options - Effect configuration options
 * @returns Function to stop the effect
 */
function watchSyncEffect(
  effect: WatchEffect,
  options?: WatchEffectOptions
): WatchStopHandle;

Usage Examples:

import { ref, watchEffect, watchPostEffect, watchSyncEffect } from "@vue/runtime-core";

const count = ref(0);
const name = ref("Vue");

// Basic watchEffect
const stopEffect = watchEffect(() => {
  console.log(`Count is ${count.value} and name is ${name.value}`);
});
// Runs immediately and when count or name changes

// watchEffect with cleanup
watchEffect((onInvalidate) => {
  const timer = setInterval(() => {
    console.log(`Timer: ${count.value}`);
  }, 1000);
  
  // Cleanup when effect is invalidated
  onInvalidate(() => {
    clearInterval(timer);
  });
});

// Post-flush effect (runs after DOM updates)
watchPostEffect(() => {
  // This runs after component DOM updates
  console.log("DOM updated, count is:", count.value);
});

// Sync effect (runs synchronously)
watchSyncEffect(() => {
  console.log("Sync effect, count:", count.value);
});

// Stop effects
stopEffect();

Watch Options & Configuration

Configure watch behavior with various options.

interface WatchOptions<T = any, Immediate extends boolean = boolean> {
  /**
   * Run the callback immediately with current value
   */
  immediate?: Immediate;
  
  /**
   * Watch nested properties in objects and arrays
   */
  deep?: boolean;
  
  /**
   * Flush timing: 'pre' (before updates), 'post' (after updates), 'sync' (synchronous)
   */
  flush?: 'pre' | 'post' | 'sync';
  
  /**
   * Debug hook called when watcher triggers
   */
  onTrack?: (event: DebuggerEvent) => void;
  
  /**
   * Debug hook called when watcher triggers
   */
  onTrigger?: (event: DebuggerEvent) => void;
  
  /**
   * Indicates whether the job is allowed to recursively trigger itself
   */
  allowRecurse?: boolean;
}

interface WatchEffectOptions {
  /**
   * Flush timing for the effect
   */
  flush?: 'pre' | 'post' | 'sync';
  
  /**
   * Debug hook called when effect is tracked
   */
  onTrack?: (event: DebuggerEvent) => void;
  
  /**
   * Debug hook called when effect is triggered
   */
  onTrigger?: (event: DebuggerEvent) => void;
  
  /**
   * Indicates whether the job is allowed to recursively trigger itself
   */
  allowRecurse?: boolean;
}

Usage Examples:

import { ref, reactive, watch, watchEffect } from "@vue/runtime-core";

const user = reactive({
  profile: {
    name: "Alice",
    settings: {
      theme: "dark"
    }
  }
});

// Deep watching
watch(
  user,
  (newUser, oldUser) => {
    console.log("User changed:", newUser);
  },
  {
    deep: true, // Watch nested properties
    immediate: true, // Run immediately
    flush: 'post' // Run after DOM updates
  }
);

// Flush timing examples
const count = ref(0);

// Pre-flush (default) - runs before DOM updates
watch(count, () => console.log("Pre-flush"), { flush: 'pre' });

// Post-flush - runs after DOM updates
watch(count, () => console.log("Post-flush"), { flush: 'post' });

// Sync - runs synchronously
watch(count, () => console.log("Sync"), { flush: 'sync' });

// Debug hooks
watchEffect(
  () => {
    console.log("Count:", count.value);
  },
  {
    onTrack(e) {
      console.log("Tracked:", e);
    },
    onTrigger(e) {
      console.log("Triggered:", e);
    }
  }
);

Types

type WatchSource<T = any> = Ref<T> | ComputedRef<T> | (() => T);

type MultiWatchSources = (WatchSource<unknown> | object)[];

type MapSources<T> = {
  [K in keyof T]: T[K] extends WatchSource<infer V>
    ? V
    : T[K] extends object
    ? T[K]
    : never;
};

type WatchCallback<V = any, OV = any> = (
  value: V,
  oldValue: OV,
  onCleanup: OnCleanup
) => any;

type WatchStopHandle = () => void;

type WatchHandle = WatchStopHandle;

interface WatchEffect {
  (onCleanup: OnCleanup): void;
}

type OnCleanup = (cleanupFn: () => void) => void;

interface DebuggerEvent {
  effect: ReactiveEffect;
  target: object;
  type: TrackOpTypes | TriggerOpTypes;
  key: any;
  newValue?: any;
  oldValue?: any;
  oldTarget?: Map<any, any> | Set<any>;
}

enum TrackOpTypes {
  GET = 'get',
  HAS = 'has',
  ITERATE = 'iterate'
}

enum TriggerOpTypes {
  SET = 'set',
  ADD = 'add',
  DELETE = 'delete',
  CLEAR = 'clear'
}

Install with Tessl CLI

npx tessl i tessl/npm-vue--runtime-core

docs

asset-resolution.md

builtin-components.md

components.md

composition-helpers.md

dependency-injection.md

error-handling.md

hydration.md

index.md

internal-render-helpers.md

lifecycle.md

reactivity.md

scheduler-timing.md

ssr-context.md

vdom-rendering.md

watch-effects.md

tile.json