CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-zone-js

Execution context library that persists across asynchronous operations for JavaScript applications

Overview
Eval results
Files

patching-system.mddocs/

Patching System

Monkey patching infrastructure for browser and Node.js APIs, enabling zone context preservation across various asynchronous operations.

Capabilities

Core Patching API

Zone.js provides a comprehensive patching system to integrate with native APIs.

/**
 * Patch function type for extending Zone.js functionality
 * @param global - Global object (window, global, etc.)
 * @param Zone - Zone constructor
 * @param api - ZonePrivate API for patch utilities
 */
type PatchFn = (global: Window, Zone: ZoneType, api: ZonePrivate) => void;

/**
 * Load a patch for specified native module
 * @param name - Unique name for the patch
 * @param fn - Patch function to execute
 * @param ignoreDuplicate - Whether to ignore duplicate patch names
 */
__load_patch(name: string, fn: PatchFn, ignoreDuplicate?: boolean): void;

Usage Examples:

import 'zone.js';

// Load a custom patch
Zone.__load_patch('custom-api', (global, Zone, api) => {
  // Patch some custom API
  const originalMethod = global.customAPI?.someMethod;
  if (originalMethod) {
    global.customAPI.someMethod = api.wrapWithCurrentZone(
      originalMethod, 
      'customAPI.someMethod'
    );
  }
});

// Load browser patches
Zone.__load_patch('browser', (global, Zone, api) => {
  patchBrowser(Zone);
});

// Load Node.js patches
Zone.__load_patch('node', (global, Zone, api) => {
  patchNode(Zone);
});

ZonePrivate API

Internal API providing utilities for developing custom patches.

/**
 * Private API for patch development
 */
interface ZonePrivate {
  /** Get current zone frame information */
  currentZoneFrame(): ZoneFrame;
  
  /** Generate zone symbol with prefix */
  symbol(name: string): string;
  
  /** Schedule a microtask */
  scheduleMicroTask(task?: MicroTask): void;
  
  /** Handle unhandled errors */
  onUnhandledError(error: Error): void;
  
  /** Notify that microtask queue is drained */
  microtaskDrainDone(): void;
  
  /** Check if uncaught errors should be shown */
  showUncaughtError(): boolean;
  
  /** Patch EventTarget APIs */
  patchEventTarget(global: any, api: ZonePrivate, apis: any[], options?: any): boolean[];
  
  /** Patch object properties for event handlers */
  patchOnProperties(obj: any, properties: string[] | null, prototype?: any): void;
  
  /** Patch Promise.then method */
  patchThen(ctor: Function): void;
  
  /** Patch a method with zone awareness */
  patchMethod(
    target: any,
    name: string,
    patchFn: (delegate: Function, delegateName: string, name: string) => Function
  ): Function | null;
  
  /** Bind arguments with zone context */
  bindArguments(args: any[], source: string): any[];
  
  /** Patch macrotask APIs (setTimeout, etc.) */
  patchMacroTask(obj: any, funcName: string, metaCreator: Function): void;
  
  /** Patch event prototype methods */
  patchEventPrototype(global: any, api: ZonePrivate): void;
  
  /** Check if running in IE or Edge */
  isIEOrEdge(): boolean;
  
  /** Object.defineProperty reference */
  ObjectDefineProperty: typeof Object.defineProperty;
  
  /** Object.getOwnPropertyDescriptor reference */
  ObjectGetOwnPropertyDescriptor: typeof Object.getOwnPropertyDescriptor;
  
  /** Object.create reference */
  ObjectCreate: typeof Object.create;
  
  /** Array.prototype.slice reference */
  ArraySlice: typeof Array.prototype.slice;
  
  /** Patch constructor class */
  patchClass(className: string): void;
  
  /** Wrap callback with current zone */
  wrapWithCurrentZone(callback: any, source: string): any;
  
  /** Filter properties for patching */
  filterProperties(target: any, onProperties: string[], ignoreProperties: any[]): string[];
  
  /** Attach origin reference to patched function */
  attachOriginToPatched(target: any, origin: any): void;
  
  /** Redefine property with descriptor */
  _redefineProperty(target: any, callback: string, desc: any): void;
  
  /** Native microtask scheduler */
  nativeScheduleMicroTask(func: Function): void;
  
  /** Get global objects and utilities */
  getGlobalObjects(): {
    globalSources: any;
    zoneSymbolEventNames: any;
    eventNames: string[];
    isBrowser: boolean;
    isMix: boolean;
    isNode: boolean;
    TRUE_STR: string;
    FALSE_STR: string;
    ZONE_SYMBOL_PREFIX: string;
    ADD_EVENT_LISTENER_STR: string;
    REMOVE_EVENT_LISTENER_STR: string;
  } | undefined;
}

Browser Patches

Zone.js provides comprehensive patches for browser APIs.

/**
 * Patch core browser APIs
 * @param Zone - Zone constructor
 */
function patchBrowser(Zone: ZoneType): void;

/**
 * Patch common browser APIs (timers, RAF, etc.)
 * @param Zone - Zone constructor
 */
function patchCommon(Zone: ZoneType): void;

/**
 * Patch EventTarget API
 * @param global - Global object
 * @param api - ZonePrivate API
 */
function eventTargetPatch(global: any, api: ZonePrivate): void;

/**
 * Patch timer APIs (setTimeout, setInterval)
 * @param window - Window object
 * @param setName - Setter function name
 * @param cancelName - Canceller function name
 * @param nameSuffix - Name suffix for debugging
 */
function patchTimer(window: any, setName: string, cancelName: string, nameSuffix: string): void;

/**
 * Patch Promise API
 * @param Zone - Zone constructor
 */
function patchPromise(Zone: ZoneType): void;

/**
 * Patch Fetch API
 * @param Zone - Zone constructor
 */
function patchFetch(Zone: ZoneType): void;

Usage Examples:

// Browser patches are typically loaded automatically
import 'zone.js'; // Loads browser patches

// Manual browser patching
Zone.__load_patch('browser', (global, Zone, api) => {
  patchBrowser(Zone);
});

// Patch specific APIs
Zone.__load_patch('timers', (global, Zone, api) => {
  patchTimer(global, 'setTimeout', 'clearTimeout', 'Timeout');
  patchTimer(global, 'setInterval', 'clearInterval', 'Interval');
});

Zone.__load_patch('promise', (global, Zone, api) => {
  patchPromise(Zone);
});

Node.js Patches

Zone.js provides patches for Node.js APIs to enable zone context in server environments.

/**
 * Patch core Node.js APIs
 * @param Zone - Zone constructor
 */
function patchNode(Zone: ZoneType): void;

/**
 * Patch EventEmitter API
 * @param Zone - Zone constructor
 */
function patchEvents(Zone: ZoneType): void;

/**
 * Patch File System API
 * @param Zone - Zone constructor
 */
function patchFs(Zone: ZoneType): void;

/**
 * Patch Node.js utilities
 * @param Zone - Zone constructor
 */
function patchNodeUtil(Zone: ZoneType): void;

Usage Examples:

// Node.js patches
import 'zone.js/node';

// Or load manually
Zone.__load_patch('node', (global, Zone, api) => {
  patchNode(Zone);
});

// Patch specific Node.js APIs
Zone.__load_patch('events', (global, Zone, api) => {
  patchEvents(Zone);
});

Zone.__load_patch('fs', (global, Zone, api) => {
  patchFs(Zone);
});

Web API Patches

Extended patches for modern web APIs.

/**
 * Patch Canvas API
 * @param Zone - Zone constructor
 */
function patchCanvas(Zone: ZoneType): void;

/**
 * Patch MessagePort API
 * @param Zone - Zone constructor
 */
function patchMessagePort(Zone: ZoneType): void;

/**
 * Patch MediaQuery API
 * @param Zone - Zone constructor
 */
function patchMediaQuery(Zone: ZoneType): void;

/**
 * Patch Notification API
 * @param Zone - Zone constructor
 */
function patchNotifications(Zone: ZoneType): void;

/**
 * Patch ResizeObserver API
 * @param Zone - Zone constructor
 */
function patchResizeObserver(Zone: ZoneType): void;

/**
 * Patch WebRTC PeerConnection API
 * @param Zone - Zone constructor
 */
function patchRtcPeerConnection(Zone: ZoneType): void;

/**
 * Patch getUserMedia API
 * @param Zone - Zone constructor
 */
function patchUserMedia(Zone: ZoneType): void;

/**
 * Patch WebSocket API
 * @param global - Global object
 * @param api - ZonePrivate API
 */
function apply(api: ZonePrivate, global: any): void;

Usage Examples:

import 'zone.js';

// Load specific web API patches
Zone.__load_patch('canvas', (global, Zone, api) => {
  patchCanvas(Zone);
});

Zone.__load_patch('webapis-notification', (global, Zone, api) => {
  patchNotifications(Zone);
});

Zone.__load_patch('webapis-resize-observer', (global, Zone, api) => {
  patchResizeObserver(Zone);
});

// Use patched APIs - zone context is preserved
const myZone = Zone.current.fork({ name: 'web-api-zone' });

myZone.run(() => {
  // Notification API preserves zone context
  new Notification('Test', {
    body: 'Zone context preserved'
  });
  
  // ResizeObserver preserves zone context
  const observer = new ResizeObserver((entries) => {
    console.log('ResizeObserver in:', Zone.current.name); // 'web-api-zone'
  });
  
  observer.observe(document.body);
});

Framework Integration Patches

Patches for test frameworks and libraries.

/**
 * Patch Jasmine testing framework
 * @param Zone - Zone constructor
 */
function patchJasmine(Zone: ZoneType): void;

/**
 * Patch Jest testing framework
 * @param Zone - Zone constructor
 */
function patchJest(Zone: ZoneType): void;

/**
 * Patch Mocha testing framework
 * @param Zone - Zone constructor
 */
function patchMocha(Zone: ZoneType): void;

/**
 * Patch RxJS library
 * @param Zone - Zone constructor
 */
function patchRxJs(Zone: ZoneType): void;

Usage Examples:

// Framework patches are typically loaded with testing bundle
import 'zone.js/testing'; // Includes Jasmine patches

// Manual framework patching
Zone.__load_patch('jasmine', (global, Zone, api) => {
  patchJasmine(Zone);
});

Zone.__load_patch('rxjs', (global, Zone, api) => {
  patchRxJs(Zone);
});

Custom Patch Development

Utilities for developing custom patches.

/**
 * Patch object properties for event handlers
 * @param obj - Object to patch
 * @param properties - Properties to patch
 * @param prototype - Prototype to patch (optional)
 */
function patchOnProperties(obj: any, properties: string[] | null, prototype?: any): void;

/**
 * Patch a single property
 * @param obj - Object to patch
 * @param prop - Property name to patch
 * @param prototype - Prototype to patch (optional)
 */
function patchProperty(obj: any, prop: string, prototype?: any): void;

/**
 * Patch method with zone awareness
 * @param target - Object containing the method
 * @param name - Method name
 * @param patchFn - Function that returns the patched method
 */
function patchMethod(target: any, name: string, patchFn: Function): Function | null;

/**
 * Patch microtask method
 * @param obj - Object to patch
 * @param funcName - Function name
 * @param metaCreator - Function to create task metadata
 */
function patchMicroTask(obj: any, funcName: string, metaCreator: Function): void;

/**
 * Patch macrotask method
 * @param obj - Object to patch
 * @param funcName - Function name
 * @param metaCreator - Function to create task metadata
 */
function patchMacroTask(obj: any, funcName: string, metaCreator: Function): void;

Usage Examples:

// Custom patch for a third-party library
Zone.__load_patch('custom-library', (global, Zone, api) => {
  const CustomLib = global.CustomLib;
  if (!CustomLib) return;
  
  // Patch event properties
  api.patchOnProperties(CustomLib.prototype, ['ondata', 'onerror', 'onend']);
  
  // Patch async method
  api.patchMethod(CustomLib.prototype, 'asyncMethod', (delegate, delegateName, name) => {
    return function(this: any, ...args: any[]) {
      const callback = args[args.length - 1];
      if (typeof callback === 'function') {
        args[args.length - 1] = api.wrapWithCurrentZone(callback, `${name}_callback`);
      }
      return delegate.apply(this, args);
    };
  });
  
  // Patch timer-like method
  api.patchMacroTask(CustomLib.prototype, 'delayedCall', (self: any, args: any[]) => {
    return {
      source: 'CustomLib.delayedCall',
      delay: args[1] || 0,
      callback: args[0],
      args: []
    };
  });
});

// Use the patched library
const myZone = Zone.current.fork({ name: 'custom-lib-zone' });

myZone.run(() => {
  const lib = new CustomLib();
  
  // Event handlers preserve zone context
  lib.ondata = (data) => {
    console.log('Data received in:', Zone.current.name); // 'custom-lib-zone'
  };
  
  // Async methods preserve zone context
  lib.asyncMethod((result) => {
    console.log('Async result in:', Zone.current.name); // 'custom-lib-zone'
  });
});

Patch Utilities

Common utilities used in patch development.

/**
 * Wrap callback with current zone context
 * @param callback - Function to wrap
 * @param source - Debug identifier
 * @returns Wrapped function
 */
function wrapWithCurrentZone<T extends Function>(callback: T, source: string): T;

/**
 * Generate zone symbol with prefix
 * @param name - Symbol name
 * @returns Prefixed symbol string
 */
function zoneSymbol(name: string): string;

/**
 * Check if property is writable
 * @param propertyDesc - Property descriptor
 * @returns true if property is writable
 */
function isPropertyWritable(propertyDesc: any): boolean;

/**
 * Copy symbol properties from source to destination
 * @param src - Source object
 * @param dest - Destination object
 */
function copySymbolProperties(src: any, dest: any): void;

/**
 * Attach origin reference to patched function
 * @param patched - Patched function
 * @param original - Original function
 */
function attachOriginToPatched(patched: Function, original: any): void;

Usage Examples:

// Utility usage in custom patches
Zone.__load_patch('utilities-example', (global, Zone, api) => {
  const originalSetTimeout = global.setTimeout;
  const timeoutSymbol = api.symbol('setTimeout');
  
  // Store original function
  global[timeoutSymbol] = originalSetTimeout;
  
  // Create wrapped version
  global.setTimeout = function(callback: Function, delay: number, ...args: any[]) {
    const wrappedCallback = api.wrapWithCurrentZone(callback, 'setTimeout');
    return originalSetTimeout.call(this, wrappedCallback, delay, ...args);
  };
  
  // Attach origin reference
  api.attachOriginToPatched(global.setTimeout, originalSetTimeout);
  
  // Copy any symbol properties
  api.copySymbolProperties(originalSetTimeout, global.setTimeout);
});

Install with Tessl CLI

npx tessl i tessl/npm-zone-js

docs

configuration-api.md

core-zone-api.md

index.md

patching-system.md

task-system.md

testing-utilities.md

zone-specifications.md

tile.json