
committed by
Kara Erickson

parent
7b3bcc23af
commit
5eb7426216
63
packages/zone.js/lib/node/events.ts
Normal file
63
packages/zone.js/lib/node/events.ts
Normal file
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {patchEventTarget} from '../common/events';
|
||||
|
||||
Zone.__load_patch('EventEmitter', (global: any) => {
|
||||
// For EventEmitter
|
||||
const EE_ADD_LISTENER = 'addListener';
|
||||
const EE_PREPEND_LISTENER = 'prependListener';
|
||||
const EE_REMOVE_LISTENER = 'removeListener';
|
||||
const EE_REMOVE_ALL_LISTENER = 'removeAllListeners';
|
||||
const EE_LISTENERS = 'listeners';
|
||||
const EE_ON = 'on';
|
||||
|
||||
const compareTaskCallbackVsDelegate = function(task: any, delegate: any) {
|
||||
// same callback, same capture, same event name, just return
|
||||
return task.callback === delegate || task.callback.listener === delegate;
|
||||
};
|
||||
|
||||
const eventNameToString = function(eventName: string|Symbol) {
|
||||
if (typeof eventName === 'string') {
|
||||
return eventName as string;
|
||||
}
|
||||
if (!eventName) {
|
||||
return '';
|
||||
}
|
||||
return eventName.toString().replace('(', '_').replace(')', '_');
|
||||
};
|
||||
|
||||
function patchEventEmitterMethods(obj: any) {
|
||||
const result = patchEventTarget(global, [obj], {
|
||||
useG: false,
|
||||
add: EE_ADD_LISTENER,
|
||||
rm: EE_REMOVE_LISTENER,
|
||||
prepend: EE_PREPEND_LISTENER,
|
||||
rmAll: EE_REMOVE_ALL_LISTENER,
|
||||
listeners: EE_LISTENERS,
|
||||
chkDup: false,
|
||||
rt: true,
|
||||
diff: compareTaskCallbackVsDelegate,
|
||||
eventNameToString: eventNameToString
|
||||
});
|
||||
if (result && result[0]) {
|
||||
obj[EE_ON] = obj[EE_ADD_LISTENER];
|
||||
}
|
||||
}
|
||||
|
||||
// EventEmitter
|
||||
let events;
|
||||
try {
|
||||
events = require('events');
|
||||
} catch (err) {
|
||||
}
|
||||
|
||||
if (events && events.EventEmitter) {
|
||||
patchEventEmitterMethods(events.EventEmitter.prototype);
|
||||
}
|
||||
});
|
41
packages/zone.js/lib/node/fs.ts
Normal file
41
packages/zone.js/lib/node/fs.ts
Normal file
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {patchMacroTask} from '../common/utils';
|
||||
|
||||
Zone.__load_patch('fs', () => {
|
||||
let fs: any;
|
||||
try {
|
||||
fs = require('fs');
|
||||
} catch (err) {
|
||||
}
|
||||
|
||||
// watch, watchFile, unwatchFile has been patched
|
||||
// because EventEmitter has been patched
|
||||
const TO_PATCH_MACROTASK_METHODS = [
|
||||
'access', 'appendFile', 'chmod', 'chown', 'close', 'exists', 'fchmod',
|
||||
'fchown', 'fdatasync', 'fstat', 'fsync', 'ftruncate', 'futimes', 'lchmod',
|
||||
'lchown', 'link', 'lstat', 'mkdir', 'mkdtemp', 'open', 'read',
|
||||
'readdir', 'readFile', 'readlink', 'realpath', 'rename', 'rmdir', 'stat',
|
||||
'symlink', 'truncate', 'unlink', 'utimes', 'write', 'writeFile',
|
||||
];
|
||||
|
||||
if (fs) {
|
||||
TO_PATCH_MACROTASK_METHODS.filter(name => !!fs[name] && typeof fs[name] === 'function')
|
||||
.forEach(name => {
|
||||
patchMacroTask(fs, name, (self: any, args: any[]) => {
|
||||
return {
|
||||
name: 'fs.' + name,
|
||||
args: args,
|
||||
cbIdx: args.length > 0 ? args.length - 1 : -1,
|
||||
target: self
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
154
packages/zone.js/lib/node/node.ts
Normal file
154
packages/zone.js/lib/node/node.ts
Normal file
@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import './node_util';
|
||||
import './events';
|
||||
import './fs';
|
||||
|
||||
import {findEventTasks} from '../common/events';
|
||||
import {patchTimer} from '../common/timers';
|
||||
import {ArraySlice, isMix, patchMacroTask, patchMicroTask} from '../common/utils';
|
||||
|
||||
const set = 'set';
|
||||
const clear = 'clear';
|
||||
|
||||
Zone.__load_patch('node_timers', (global: any, Zone: ZoneType) => {
|
||||
// Timers
|
||||
let globalUseTimeoutFromTimer = false;
|
||||
try {
|
||||
const timers = require('timers');
|
||||
let globalEqualTimersTimeout = global.setTimeout === timers.setTimeout;
|
||||
if (!globalEqualTimersTimeout && !isMix) {
|
||||
// 1. if isMix, then we are in mix environment such as Electron
|
||||
// we should only patch timers.setTimeout because global.setTimeout
|
||||
// have been patched
|
||||
// 2. if global.setTimeout not equal timers.setTimeout, check
|
||||
// whether global.setTimeout use timers.setTimeout or not
|
||||
const originSetTimeout = timers.setTimeout;
|
||||
timers.setTimeout = function() {
|
||||
globalUseTimeoutFromTimer = true;
|
||||
return originSetTimeout.apply(this, arguments);
|
||||
};
|
||||
const detectTimeout = global.setTimeout(() => {}, 100);
|
||||
clearTimeout(detectTimeout);
|
||||
timers.setTimeout = originSetTimeout;
|
||||
}
|
||||
patchTimer(timers, set, clear, 'Timeout');
|
||||
patchTimer(timers, set, clear, 'Interval');
|
||||
patchTimer(timers, set, clear, 'Immediate');
|
||||
} catch (error) {
|
||||
// timers module not exists, for example, when we using nativeScript
|
||||
// timers is not available
|
||||
}
|
||||
if (isMix) {
|
||||
// if we are in mix environment, such as Electron,
|
||||
// the global.setTimeout has already been patched,
|
||||
// so we just patch timers.setTimeout
|
||||
return;
|
||||
}
|
||||
if (!globalUseTimeoutFromTimer) {
|
||||
// 1. global setTimeout equals timers setTimeout
|
||||
// 2. or global don't use timers setTimeout(maybe some other library patch setTimeout)
|
||||
// 3. or load timers module error happens, we should patch global setTimeout
|
||||
patchTimer(global, set, clear, 'Timeout');
|
||||
patchTimer(global, set, clear, 'Interval');
|
||||
patchTimer(global, set, clear, 'Immediate');
|
||||
} else {
|
||||
// global use timers setTimeout, but not equals
|
||||
// this happens when use nodejs v0.10.x, global setTimeout will
|
||||
// use a lazy load version of timers setTimeout
|
||||
// we should not double patch timer's setTimeout
|
||||
// so we only store the __symbol__ for consistency
|
||||
global[Zone.__symbol__('setTimeout')] = global.setTimeout;
|
||||
global[Zone.__symbol__('setInterval')] = global.setInterval;
|
||||
global[Zone.__symbol__('setImmediate')] = global.setImmediate;
|
||||
}
|
||||
});
|
||||
|
||||
// patch process related methods
|
||||
Zone.__load_patch('nextTick', () => {
|
||||
// patch nextTick as microTask
|
||||
patchMicroTask(process, 'nextTick', (self: any, args: any[]) => {
|
||||
return {
|
||||
name: 'process.nextTick',
|
||||
args: args,
|
||||
cbIdx: (args.length > 0 && typeof args[0] === 'function') ? 0 : -1,
|
||||
target: process
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
Zone.__load_patch(
|
||||
'handleUnhandledPromiseRejection', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
|
||||
(Zone as any)[api.symbol('unhandledPromiseRejectionHandler')] =
|
||||
findProcessPromiseRejectionHandler('unhandledRejection');
|
||||
|
||||
(Zone as any)[api.symbol('rejectionHandledHandler')] =
|
||||
findProcessPromiseRejectionHandler('rejectionHandled');
|
||||
|
||||
// handle unhandled promise rejection
|
||||
function findProcessPromiseRejectionHandler(evtName: string) {
|
||||
return function(e: any) {
|
||||
const eventTasks = findEventTasks(process, evtName);
|
||||
eventTasks.forEach(eventTask => {
|
||||
// process has added unhandledrejection event listener
|
||||
// trigger the event listener
|
||||
if (evtName === 'unhandledRejection') {
|
||||
eventTask.invoke(e.rejection, e.promise);
|
||||
} else if (evtName === 'rejectionHandled') {
|
||||
eventTask.invoke(e.promise);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Crypto
|
||||
Zone.__load_patch('crypto', () => {
|
||||
let crypto: any;
|
||||
try {
|
||||
crypto = require('crypto');
|
||||
} catch (err) {
|
||||
}
|
||||
|
||||
// use the generic patchMacroTask to patch crypto
|
||||
if (crypto) {
|
||||
const methodNames = ['randomBytes', 'pbkdf2'];
|
||||
methodNames.forEach(name => {
|
||||
patchMacroTask(crypto, name, (self: any, args: any[]) => {
|
||||
return {
|
||||
name: 'crypto.' + name,
|
||||
args: args,
|
||||
cbIdx: (args.length > 0 && typeof args[args.length - 1] === 'function') ?
|
||||
args.length - 1 :
|
||||
-1,
|
||||
target: crypto
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Zone.__load_patch('console', (global: any, Zone: ZoneType) => {
|
||||
const consoleMethods =
|
||||
['dir', 'log', 'info', 'error', 'warn', 'assert', 'debug', 'timeEnd', 'trace'];
|
||||
consoleMethods.forEach((m: string) => {
|
||||
const originalMethod = (console as any)[Zone.__symbol__(m)] = (console as any)[m];
|
||||
if (originalMethod) {
|
||||
(console as any)[m] = function() {
|
||||
const args = ArraySlice.call(arguments);
|
||||
if (Zone.current === Zone.root) {
|
||||
return originalMethod.apply(this, args);
|
||||
} else {
|
||||
return Zone.root.run(originalMethod, this, args);
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
17
packages/zone.js/lib/node/node_util.ts
Normal file
17
packages/zone.js/lib/node/node_util.ts
Normal file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {bindArguments, patchMacroTask, patchMethod, patchOnProperties, setShouldCopySymbolProperties} from '../common/utils';
|
||||
|
||||
Zone.__load_patch('node_util', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
|
||||
api.patchOnProperties = patchOnProperties;
|
||||
api.patchMethod = patchMethod;
|
||||
api.bindArguments = bindArguments;
|
||||
api.patchMacroTask = patchMacroTask;
|
||||
setShouldCopySymbolProperties(true);
|
||||
});
|
12
packages/zone.js/lib/node/rollup-main.ts
Normal file
12
packages/zone.js/lib/node/rollup-main.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import '../zone';
|
||||
import '../common/promise';
|
||||
import '../common/to-string';
|
||||
import './node';
|
12
packages/zone.js/lib/node/rollup-test-main.ts
Normal file
12
packages/zone.js/lib/node/rollup-test-main.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import './rollup-main';
|
||||
|
||||
// load test related files into bundle
|
||||
import '../testing/zone-testing';
|
Reference in New Issue
Block a user