Execution context library that persists across asynchronous operations for JavaScript applications
Zone configuration system for customizing zone behavior through lifecycle hooks, error handling, and task interception.
Configuration object that defines zone behavior through lifecycle hooks and properties.
/**
* Configuration object for customizing zone behavior
*/
interface ZoneSpec {
/** Required: zone name for debugging and identification */
name: string;
/** Optional: key-value properties attached to the zone */
properties?: {[key: string]: any};
/** Hook called when this zone is forked to create child zones */
onFork?: (
parentZoneDelegate: ZoneDelegate,
currentZone: Zone,
targetZone: Zone,
zoneSpec: ZoneSpec
) => Zone;
/** Hook called when callbacks are wrapped for zone context */
onIntercept?: (
parentZoneDelegate: ZoneDelegate,
currentZone: Zone,
targetZone: Zone,
delegate: Function,
source: string
) => Function;
/** Hook called when functions are executed in the zone */
onInvoke?: (
parentZoneDelegate: ZoneDelegate,
currentZone: Zone,
targetZone: Zone,
delegate: Function,
applyThis: any,
applyArgs?: any[],
source?: string
) => any;
/** Hook called when errors occur in the zone */
onHandleError?: (
parentZoneDelegate: ZoneDelegate,
currentZone: Zone,
targetZone: Zone,
error: any
) => boolean;
/** Hook called when tasks are scheduled in the zone */
onScheduleTask?: (
parentZoneDelegate: ZoneDelegate,
currentZone: Zone,
targetZone: Zone,
task: Task
) => Task;
/** Hook called when tasks are executed in the zone */
onInvokeTask?: (
parentZoneDelegate: ZoneDelegate,
currentZone: Zone,
targetZone: Zone,
task: Task,
applyThis: any,
applyArgs?: any[]
) => any;
/** Hook called when tasks are cancelled in the zone */
onCancelTask?: (
parentZoneDelegate: ZoneDelegate,
currentZone: Zone,
targetZone: Zone,
task: Task
) => any;
/** Hook called when zone task state changes */
onHasTask?: (
parentZoneDelegate: ZoneDelegate,
currentZone: Zone,
targetZone: Zone,
hasTaskState: HasTaskState
) => void;
}Usage Examples:
import 'zone.js';
// Basic zone with properties
const userZone = Zone.current.fork({
name: 'user-zone',
properties: {
userId: 123,
theme: 'dark'
}
});
// Zone with error handling
const errorHandlingZone = Zone.current.fork({
name: 'error-handler',
onHandleError: (delegate, current, target, error) => {
console.error('Zone error:', error);
// Return true to prevent error propagation
return true;
}
});
// Zone with task tracking
const taskTrackingZone = Zone.current.fork({
name: 'task-tracker',
onScheduleTask: (delegate, current, target, task) => {
console.log('Task scheduled:', task.type, task.source);
return delegate.scheduleTask(target, task);
},
onHasTask: (delegate, current, target, hasTaskState) => {
console.log('Task state changed:', hasTaskState);
}
});Delegate object that provides access to parent zone operations within lifecycle hooks.
/**
* Delegate interface for accessing parent zone operations
*/
interface ZoneDelegate {
/** Zone associated with this delegate */
readonly zone: Zone;
/** Delegate zone forking to parent */
fork(targetZone: Zone, zoneSpec: ZoneSpec): Zone;
/** Delegate callback interception to parent */
intercept(targetZone: Zone, callback: Function, source: string): Function;
/** Delegate function invocation to parent */
invoke(
targetZone: Zone,
callback: Function,
applyThis?: any,
applyArgs?: any[],
source?: string
): any;
/** Delegate error handling to parent */
handleError(targetZone: Zone, error: any): boolean;
/** Delegate task scheduling to parent */
scheduleTask(targetZone: Zone, task: Task): Task;
/** Delegate task invocation to parent */
invokeTask(targetZone: Zone, task: Task, applyThis?: any, applyArgs?: any[]): any;
/** Delegate task cancellation to parent */
cancelTask(targetZone: Zone, task: Task): any;
/** Delegate task state notification to parent */
hasTask(targetZone: Zone, isEmpty: HasTaskState): void;
}Zone specifications enable powerful customization through lifecycle hooks.
/**
* Hook called when this zone is forked to create child zones
* @param parentZoneDelegate - Delegate for parent zone operations
* @param currentZone - Zone where the fork hook is declared
* @param targetZone - Zone that will be the parent of the new zone
* @param zoneSpec - Specification for the new child zone
* @returns The newly created zone
*/
onFork?: (
parentZoneDelegate: ZoneDelegate,
currentZone: Zone,
targetZone: Zone,
zoneSpec: ZoneSpec
) => Zone;
/**
* Hook called when callbacks are wrapped for zone context
* @param parentZoneDelegate - Delegate for parent zone operations
* @param currentZone - Zone where the intercept hook is declared
* @param targetZone - Zone where the callback will execute
* @param delegate - Original callback function
* @param source - Debug identifier for the operation
* @returns Modified callback function
*/
onIntercept?: (
parentZoneDelegate: ZoneDelegate,
currentZone: Zone,
targetZone: Zone,
delegate: Function,
source: string
) => Function;
/**
* Hook called when functions are executed in the zone
* @param parentZoneDelegate - Delegate for parent zone operations
* @param currentZone - Zone where the invoke hook is declared
* @param targetZone - Zone where the function will execute
* @param delegate - Function to execute
* @param applyThis - 'this' context for the function
* @param applyArgs - Arguments to pass to the function
* @param source - Debug identifier for the operation
* @returns Return value from the function
*/
onInvoke?: (
parentZoneDelegate: ZoneDelegate,
currentZone: Zone,
targetZone: Zone,
delegate: Function,
applyThis: any,
applyArgs?: any[],
source?: string
) => any;Usage Examples:
// Profiling zone that measures execution time
const profilingZone = Zone.current.fork({
name: 'profiler',
onInvoke: (delegate, current, target, fn, thisArg, args, source) => {
const start = performance.now();
const result = delegate.invoke(target, fn, thisArg, args, source);
const duration = performance.now() - start;
console.log(`${source || 'unknown'} took ${duration}ms`);
return result;
}
});
// Logging zone that tracks all operations
const loggingZone = Zone.current.fork({
name: 'logger',
onIntercept: (delegate, current, target, callback, source) => {
console.log('Intercepting:', source);
return delegate.intercept(target, callback, source);
},
onScheduleTask: (delegate, current, target, task) => {
console.log('Scheduling task:', task.type, task.source);
return delegate.scheduleTask(target, task);
}
});Zone.js provides several built-in zone specifications for common use cases.
/**
* Fake async test zone for controlling time in tests
*/
class FakeAsyncTestZoneSpec implements ZoneSpec {
name: 'fakeAsync';
tick(millis?: number, doTick?: (elapsed: number) => void): void;
flush(maxTurns?: number): number;
flushMicrotasks(): void;
}
/**
* Async test zone that waits for all async operations to complete
*/
class AsyncTestZoneSpec implements ZoneSpec {
name: 'async-test';
whenStable(): Promise<any>;
}
/**
* Proxy zone for test isolation
*/
class ProxyZoneSpec implements ZoneSpec {
name: 'proxy';
setDelegate(delegateSpec: ZoneSpec): void;
getDelegate(): ZoneSpec;
resetDelegate(): void;
}
/**
* Task tracking zone for monitoring task execution
*/
class TaskTrackingZoneSpec implements ZoneSpec {
name: 'task-tracking';
readonly microTasks: Task[];
readonly macroTasks: Task[];
readonly eventTasks: Task[];
clear(): void;
}Zone specifications enable sophisticated error handling strategies.
/**
* Hook called when errors occur in the zone
* @param parentZoneDelegate - Delegate for parent zone operations
* @param currentZone - Zone where the error hook is declared
* @param targetZone - Zone where the error occurred
* @param error - The error that occurred
* @returns true to handle the error, false to propagate to parent
*/
onHandleError?: (
parentZoneDelegate: ZoneDelegate,
currentZone: Zone,
targetZone: Zone,
error: any
) => boolean;Usage Examples:
// Error reporting zone
const errorReportingZone = Zone.current.fork({
name: 'error-reporter',
onHandleError: (delegate, current, target, error) => {
// Send error to monitoring service
console.error('Zone error in', target.name, ':', error);
// Could send to external service
// errorService.report(error, { zone: target.name });
// Return false to allow error to propagate
return false;
}
});
// Error isolation zone
const isolatedZone = Zone.current.fork({
name: 'isolated',
onHandleError: (delegate, current, target, error) => {
console.log('Isolated error:', error.message);
// Return true to prevent error propagation
return true;
}
});
isolatedZone.run(() => {
setTimeout(() => {
throw new Error('This error is isolated');
}, 100);
// Error won't propagate beyond this zone
});Install with Tessl CLI
npx tessl i tessl/npm-zone-js