or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration-api.mdcore-zone-api.mdindex.mdpatching-system.mdtask-system.mdtesting-utilities.mdzone-specifications.md

patching-system.mddocs/

0

# Patching System

1

2

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

3

4

## Capabilities

5

6

### Core Patching API

7

8

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

9

10

```typescript { .api }

11

/**

12

* Patch function type for extending Zone.js functionality

13

* @param global - Global object (window, global, etc.)

14

* @param Zone - Zone constructor

15

* @param api - ZonePrivate API for patch utilities

16

*/

17

type PatchFn = (global: Window, Zone: ZoneType, api: ZonePrivate) => void;

18

19

/**

20

* Load a patch for specified native module

21

* @param name - Unique name for the patch

22

* @param fn - Patch function to execute

23

* @param ignoreDuplicate - Whether to ignore duplicate patch names

24

*/

25

__load_patch(name: string, fn: PatchFn, ignoreDuplicate?: boolean): void;

26

```

27

28

**Usage Examples:**

29

30

```typescript

31

import 'zone.js';

32

33

// Load a custom patch

34

Zone.__load_patch('custom-api', (global, Zone, api) => {

35

// Patch some custom API

36

const originalMethod = global.customAPI?.someMethod;

37

if (originalMethod) {

38

global.customAPI.someMethod = api.wrapWithCurrentZone(

39

originalMethod,

40

'customAPI.someMethod'

41

);

42

}

43

});

44

45

// Load browser patches

46

Zone.__load_patch('browser', (global, Zone, api) => {

47

patchBrowser(Zone);

48

});

49

50

// Load Node.js patches

51

Zone.__load_patch('node', (global, Zone, api) => {

52

patchNode(Zone);

53

});

54

```

55

56

### ZonePrivate API

57

58

Internal API providing utilities for developing custom patches.

59

60

```typescript { .api }

61

/**

62

* Private API for patch development

63

*/

64

interface ZonePrivate {

65

/** Get current zone frame information */

66

currentZoneFrame(): ZoneFrame;

67

68

/** Generate zone symbol with prefix */

69

symbol(name: string): string;

70

71

/** Schedule a microtask */

72

scheduleMicroTask(task?: MicroTask): void;

73

74

/** Handle unhandled errors */

75

onUnhandledError(error: Error): void;

76

77

/** Notify that microtask queue is drained */

78

microtaskDrainDone(): void;

79

80

/** Check if uncaught errors should be shown */

81

showUncaughtError(): boolean;

82

83

/** Patch EventTarget APIs */

84

patchEventTarget(global: any, api: ZonePrivate, apis: any[], options?: any): boolean[];

85

86

/** Patch object properties for event handlers */

87

patchOnProperties(obj: any, properties: string[] | null, prototype?: any): void;

88

89

/** Patch Promise.then method */

90

patchThen(ctor: Function): void;

91

92

/** Patch a method with zone awareness */

93

patchMethod(

94

target: any,

95

name: string,

96

patchFn: (delegate: Function, delegateName: string, name: string) => Function

97

): Function | null;

98

99

/** Bind arguments with zone context */

100

bindArguments(args: any[], source: string): any[];

101

102

/** Patch macrotask APIs (setTimeout, etc.) */

103

patchMacroTask(obj: any, funcName: string, metaCreator: Function): void;

104

105

/** Patch event prototype methods */

106

patchEventPrototype(global: any, api: ZonePrivate): void;

107

108

/** Check if running in IE or Edge */

109

isIEOrEdge(): boolean;

110

111

/** Object.defineProperty reference */

112

ObjectDefineProperty: typeof Object.defineProperty;

113

114

/** Object.getOwnPropertyDescriptor reference */

115

ObjectGetOwnPropertyDescriptor: typeof Object.getOwnPropertyDescriptor;

116

117

/** Object.create reference */

118

ObjectCreate: typeof Object.create;

119

120

/** Array.prototype.slice reference */

121

ArraySlice: typeof Array.prototype.slice;

122

123

/** Patch constructor class */

124

patchClass(className: string): void;

125

126

/** Wrap callback with current zone */

127

wrapWithCurrentZone(callback: any, source: string): any;

128

129

/** Filter properties for patching */

130

filterProperties(target: any, onProperties: string[], ignoreProperties: any[]): string[];

131

132

/** Attach origin reference to patched function */

133

attachOriginToPatched(target: any, origin: any): void;

134

135

/** Redefine property with descriptor */

136

_redefineProperty(target: any, callback: string, desc: any): void;

137

138

/** Native microtask scheduler */

139

nativeScheduleMicroTask(func: Function): void;

140

141

/** Get global objects and utilities */

142

getGlobalObjects(): {

143

globalSources: any;

144

zoneSymbolEventNames: any;

145

eventNames: string[];

146

isBrowser: boolean;

147

isMix: boolean;

148

isNode: boolean;

149

TRUE_STR: string;

150

FALSE_STR: string;

151

ZONE_SYMBOL_PREFIX: string;

152

ADD_EVENT_LISTENER_STR: string;

153

REMOVE_EVENT_LISTENER_STR: string;

154

} | undefined;

155

}

156

```

157

158

### Browser Patches

159

160

Zone.js provides comprehensive patches for browser APIs.

161

162

```typescript { .api }

163

/**

164

* Patch core browser APIs

165

* @param Zone - Zone constructor

166

*/

167

function patchBrowser(Zone: ZoneType): void;

168

169

/**

170

* Patch common browser APIs (timers, RAF, etc.)

171

* @param Zone - Zone constructor

172

*/

173

function patchCommon(Zone: ZoneType): void;

174

175

/**

176

* Patch EventTarget API

177

* @param global - Global object

178

* @param api - ZonePrivate API

179

*/

180

function eventTargetPatch(global: any, api: ZonePrivate): void;

181

182

/**

183

* Patch timer APIs (setTimeout, setInterval)

184

* @param window - Window object

185

* @param setName - Setter function name

186

* @param cancelName - Canceller function name

187

* @param nameSuffix - Name suffix for debugging

188

*/

189

function patchTimer(window: any, setName: string, cancelName: string, nameSuffix: string): void;

190

191

/**

192

* Patch Promise API

193

* @param Zone - Zone constructor

194

*/

195

function patchPromise(Zone: ZoneType): void;

196

197

/**

198

* Patch Fetch API

199

* @param Zone - Zone constructor

200

*/

201

function patchFetch(Zone: ZoneType): void;

202

```

203

204

**Usage Examples:**

205

206

```typescript

207

// Browser patches are typically loaded automatically

208

import 'zone.js'; // Loads browser patches

209

210

// Manual browser patching

211

Zone.__load_patch('browser', (global, Zone, api) => {

212

patchBrowser(Zone);

213

});

214

215

// Patch specific APIs

216

Zone.__load_patch('timers', (global, Zone, api) => {

217

patchTimer(global, 'setTimeout', 'clearTimeout', 'Timeout');

218

patchTimer(global, 'setInterval', 'clearInterval', 'Interval');

219

});

220

221

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

222

patchPromise(Zone);

223

});

224

```

225

226

### Node.js Patches

227

228

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

229

230

```typescript { .api }

231

/**

232

* Patch core Node.js APIs

233

* @param Zone - Zone constructor

234

*/

235

function patchNode(Zone: ZoneType): void;

236

237

/**

238

* Patch EventEmitter API

239

* @param Zone - Zone constructor

240

*/

241

function patchEvents(Zone: ZoneType): void;

242

243

/**

244

* Patch File System API

245

* @param Zone - Zone constructor

246

*/

247

function patchFs(Zone: ZoneType): void;

248

249

/**

250

* Patch Node.js utilities

251

* @param Zone - Zone constructor

252

*/

253

function patchNodeUtil(Zone: ZoneType): void;

254

```

255

256

**Usage Examples:**

257

258

```typescript

259

// Node.js patches

260

import 'zone.js/node';

261

262

// Or load manually

263

Zone.__load_patch('node', (global, Zone, api) => {

264

patchNode(Zone);

265

});

266

267

// Patch specific Node.js APIs

268

Zone.__load_patch('events', (global, Zone, api) => {

269

patchEvents(Zone);

270

});

271

272

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

273

patchFs(Zone);

274

});

275

```

276

277

### Web API Patches

278

279

Extended patches for modern web APIs.

280

281

```typescript { .api }

282

/**

283

* Patch Canvas API

284

* @param Zone - Zone constructor

285

*/

286

function patchCanvas(Zone: ZoneType): void;

287

288

/**

289

* Patch MessagePort API

290

* @param Zone - Zone constructor

291

*/

292

function patchMessagePort(Zone: ZoneType): void;

293

294

/**

295

* Patch MediaQuery API

296

* @param Zone - Zone constructor

297

*/

298

function patchMediaQuery(Zone: ZoneType): void;

299

300

/**

301

* Patch Notification API

302

* @param Zone - Zone constructor

303

*/

304

function patchNotifications(Zone: ZoneType): void;

305

306

/**

307

* Patch ResizeObserver API

308

* @param Zone - Zone constructor

309

*/

310

function patchResizeObserver(Zone: ZoneType): void;

311

312

/**

313

* Patch WebRTC PeerConnection API

314

* @param Zone - Zone constructor

315

*/

316

function patchRtcPeerConnection(Zone: ZoneType): void;

317

318

/**

319

* Patch getUserMedia API

320

* @param Zone - Zone constructor

321

*/

322

function patchUserMedia(Zone: ZoneType): void;

323

324

/**

325

* Patch WebSocket API

326

* @param global - Global object

327

* @param api - ZonePrivate API

328

*/

329

function apply(api: ZonePrivate, global: any): void;

330

```

331

332

**Usage Examples:**

333

334

```typescript

335

import 'zone.js';

336

337

// Load specific web API patches

338

Zone.__load_patch('canvas', (global, Zone, api) => {

339

patchCanvas(Zone);

340

});

341

342

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

343

patchNotifications(Zone);

344

});

345

346

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

347

patchResizeObserver(Zone);

348

});

349

350

// Use patched APIs - zone context is preserved

351

const myZone = Zone.current.fork({ name: 'web-api-zone' });

352

353

myZone.run(() => {

354

// Notification API preserves zone context

355

new Notification('Test', {

356

body: 'Zone context preserved'

357

});

358

359

// ResizeObserver preserves zone context

360

const observer = new ResizeObserver((entries) => {

361

console.log('ResizeObserver in:', Zone.current.name); // 'web-api-zone'

362

});

363

364

observer.observe(document.body);

365

});

366

```

367

368

### Framework Integration Patches

369

370

Patches for test frameworks and libraries.

371

372

```typescript { .api }

373

/**

374

* Patch Jasmine testing framework

375

* @param Zone - Zone constructor

376

*/

377

function patchJasmine(Zone: ZoneType): void;

378

379

/**

380

* Patch Jest testing framework

381

* @param Zone - Zone constructor

382

*/

383

function patchJest(Zone: ZoneType): void;

384

385

/**

386

* Patch Mocha testing framework

387

* @param Zone - Zone constructor

388

*/

389

function patchMocha(Zone: ZoneType): void;

390

391

/**

392

* Patch RxJS library

393

* @param Zone - Zone constructor

394

*/

395

function patchRxJs(Zone: ZoneType): void;

396

```

397

398

**Usage Examples:**

399

400

```typescript

401

// Framework patches are typically loaded with testing bundle

402

import 'zone.js/testing'; // Includes Jasmine patches

403

404

// Manual framework patching

405

Zone.__load_patch('jasmine', (global, Zone, api) => {

406

patchJasmine(Zone);

407

});

408

409

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

410

patchRxJs(Zone);

411

});

412

```

413

414

### Custom Patch Development

415

416

Utilities for developing custom patches.

417

418

```typescript { .api }

419

/**

420

* Patch object properties for event handlers

421

* @param obj - Object to patch

422

* @param properties - Properties to patch

423

* @param prototype - Prototype to patch (optional)

424

*/

425

function patchOnProperties(obj: any, properties: string[] | null, prototype?: any): void;

426

427

/**

428

* Patch a single property

429

* @param obj - Object to patch

430

* @param prop - Property name to patch

431

* @param prototype - Prototype to patch (optional)

432

*/

433

function patchProperty(obj: any, prop: string, prototype?: any): void;

434

435

/**

436

* Patch method with zone awareness

437

* @param target - Object containing the method

438

* @param name - Method name

439

* @param patchFn - Function that returns the patched method

440

*/

441

function patchMethod(target: any, name: string, patchFn: Function): Function | null;

442

443

/**

444

* Patch microtask method

445

* @param obj - Object to patch

446

* @param funcName - Function name

447

* @param metaCreator - Function to create task metadata

448

*/

449

function patchMicroTask(obj: any, funcName: string, metaCreator: Function): void;

450

451

/**

452

* Patch macrotask method

453

* @param obj - Object to patch

454

* @param funcName - Function name

455

* @param metaCreator - Function to create task metadata

456

*/

457

function patchMacroTask(obj: any, funcName: string, metaCreator: Function): void;

458

```

459

460

**Usage Examples:**

461

462

```typescript

463

// Custom patch for a third-party library

464

Zone.__load_patch('custom-library', (global, Zone, api) => {

465

const CustomLib = global.CustomLib;

466

if (!CustomLib) return;

467

468

// Patch event properties

469

api.patchOnProperties(CustomLib.prototype, ['ondata', 'onerror', 'onend']);

470

471

// Patch async method

472

api.patchMethod(CustomLib.prototype, 'asyncMethod', (delegate, delegateName, name) => {

473

return function(this: any, ...args: any[]) {

474

const callback = args[args.length - 1];

475

if (typeof callback === 'function') {

476

args[args.length - 1] = api.wrapWithCurrentZone(callback, `${name}_callback`);

477

}

478

return delegate.apply(this, args);

479

};

480

});

481

482

// Patch timer-like method

483

api.patchMacroTask(CustomLib.prototype, 'delayedCall', (self: any, args: any[]) => {

484

return {

485

source: 'CustomLib.delayedCall',

486

delay: args[1] || 0,

487

callback: args[0],

488

args: []

489

};

490

});

491

});

492

493

// Use the patched library

494

const myZone = Zone.current.fork({ name: 'custom-lib-zone' });

495

496

myZone.run(() => {

497

const lib = new CustomLib();

498

499

// Event handlers preserve zone context

500

lib.ondata = (data) => {

501

console.log('Data received in:', Zone.current.name); // 'custom-lib-zone'

502

};

503

504

// Async methods preserve zone context

505

lib.asyncMethod((result) => {

506

console.log('Async result in:', Zone.current.name); // 'custom-lib-zone'

507

});

508

});

509

```

510

511

### Patch Utilities

512

513

Common utilities used in patch development.

514

515

```typescript { .api }

516

/**

517

* Wrap callback with current zone context

518

* @param callback - Function to wrap

519

* @param source - Debug identifier

520

* @returns Wrapped function

521

*/

522

function wrapWithCurrentZone<T extends Function>(callback: T, source: string): T;

523

524

/**

525

* Generate zone symbol with prefix

526

* @param name - Symbol name

527

* @returns Prefixed symbol string

528

*/

529

function zoneSymbol(name: string): string;

530

531

/**

532

* Check if property is writable

533

* @param propertyDesc - Property descriptor

534

* @returns true if property is writable

535

*/

536

function isPropertyWritable(propertyDesc: any): boolean;

537

538

/**

539

* Copy symbol properties from source to destination

540

* @param src - Source object

541

* @param dest - Destination object

542

*/

543

function copySymbolProperties(src: any, dest: any): void;

544

545

/**

546

* Attach origin reference to patched function

547

* @param patched - Patched function

548

* @param original - Original function

549

*/

550

function attachOriginToPatched(patched: Function, original: any): void;

551

```

552

553

**Usage Examples:**

554

555

```typescript

556

// Utility usage in custom patches

557

Zone.__load_patch('utilities-example', (global, Zone, api) => {

558

const originalSetTimeout = global.setTimeout;

559

const timeoutSymbol = api.symbol('setTimeout');

560

561

// Store original function

562

global[timeoutSymbol] = originalSetTimeout;

563

564

// Create wrapped version

565

global.setTimeout = function(callback: Function, delay: number, ...args: any[]) {

566

const wrappedCallback = api.wrapWithCurrentZone(callback, 'setTimeout');

567

return originalSetTimeout.call(this, wrappedCallback, delay, ...args);

568

};

569

570

// Attach origin reference

571

api.attachOriginToPatched(global.setTimeout, originalSetTimeout);

572

573

// Copy any symbol properties

574

api.copySymbolProperties(originalSetTimeout, global.setTimeout);

575

});

576

```