diff --git a/.gitignore b/.gitignore index 893239e..1294e7a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ log.txt node_modules log-app.txt coverage -junit.xml \ No newline at end of file +junit.xml +.vscode/launch.json \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a11b191..009e515 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,7 @@ "requires": true, "packages": { "": { - "name": "js-event-loop-demo-server", + "name": "node-visualizer-server", "version": "1.0.0", "license": "MIT", "dependencies": { @@ -28,7 +28,7 @@ "jest-junit": "^12.0.0" }, "engines": { - "node": "11.x" + "node": ">=16.x" } }, "node_modules/@babel/code-frame": { @@ -2337,7 +2337,7 @@ "version": "2.6.3", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.3.tgz", "integrity": "sha512-l00tmFFZOBHtYhN4Cz7k32VM7vTn3rE2ANjQDxdEN6zmXZ/xq1jQuutnmHvMG1ZJ7xd72+TA5YpUK8wz3rWsfQ==", - "deprecated": "core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3." + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js." }, "node_modules/core-util-is": { "version": "1.0.2", @@ -4509,6 +4509,7 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "dev": true, "bin": { "uuid": "bin/uuid" @@ -6912,6 +6913,7 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "dev": true, "bin": { "uuid": "bin/uuid" @@ -7030,6 +7032,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "deprecated": "some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added", "dev": true, "dependencies": { "@cnakazawa/watch": "^1.0.3", @@ -7614,6 +7617,7 @@ "version": "0.5.3", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", "dev": true, "dependencies": { "atob": "^2.1.2", @@ -7635,6 +7639,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated", "dev": true }, "node_modules/spdx-correct": { diff --git a/package.json b/package.json index 8e805a6..36a00e8 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,10 @@ "main": "index.js", "license": "MIT", "engines": { - "node": "11.x" + "node": ">=16.x" }, "scripts": { - "start": "node --experimental-worker index.js", + "start": "node index.js", "test": "jest" }, "dependencies": { diff --git a/src/main/eventsReducer.js b/src/main/eventsReducer.js index 6ceb78d..2da3a12 100644 --- a/src/main/eventsReducer.js +++ b/src/main/eventsReducer.js @@ -57,10 +57,12 @@ const eventsReducer = (state, evt) => { ({ asyncID }) => asyncID === payload.asyncID ); - if (microtaskInfo) { + if ( + (microtaskInfo) || + (state.prevEvt.type==='EnterFunction' && state.prevEvt.payload.name==='queueMicrotask')) { state.events.push({ type: 'EnqueueMicrotask', - payload: { name: microtaskInfo.name }, + payload: { name: microtaskInfo?.name || 'microtask' }, // TODO: Get callback name for q'd µtasks }); } } @@ -198,12 +200,15 @@ const reduceEvents = (events) => { }) ); - // console.log({ - // resolvedPromiseIds, - // promisesWithInvokedCallbacksInfo, - // parentsIdsOfPromisesWithInvokedCallbacks, - // parentsIdsOfMicrotasks, - // }); + console.log({ + resolvedPromiseIds, + promisesWithInvokedCallbacksInfo, + parentsIdsOfPromisesWithInvokedCallbacks, + promiseChildIdToParentId, + microtasksWithInvokedCallbacksInfo, + microtaskChildIdToParentId, + parentsIdsOfMicrotasks, + }); return events.reduce(eventsReducer, { events: [], diff --git a/src/worker/asyncHook.js b/src/worker/asyncHook.js index 6a6730b..1743d71 100644 --- a/src/worker/asyncHook.js +++ b/src/worker/asyncHook.js @@ -6,6 +6,7 @@ function debug(...args) { } const asyncIdToResource = {}; const init = (asyncId, type, triggerAsyncId, resource) => { + debug(`asyncId:${asyncId}, type:${type}, taid:${triggerAsyncId}, resource:`,resource); asyncIdToResource[asyncId] = resource; if (type === 'PROMISE') { postEvent(Events.InitPromise(asyncId, triggerAsyncId)); @@ -19,11 +20,11 @@ const init = (asyncId, type, triggerAsyncId, resource) => { const callbackName = resource._onImmediate.name || 'anonymous'; postEvent(Events.InitImmediate(asyncId, callbackName)); } - // if (type === 'Microtask') { - // const callbackName = resource.callback.name || 'anonymous'; - // debug(resource); - // postEvent(Events.InitMicrotask(asyncId, triggerAsyncId, callbackName)); - // } + if (type === 'Microtask') { + const callbackName = resource.callback?.name || 'anonymous'; + debug('Microtask: ', resource); + postEvent(Events.InitMicrotask(asyncId, triggerAsyncId, callbackName)); + } if ( type === 'TickObject' && resource.callback.name !== 'maybeReadMore_' && @@ -36,7 +37,7 @@ const init = (asyncId, type, triggerAsyncId, resource) => { resource.callback.name !== 'finish' && resource.callback.name !== 'resume_' ) { - const callbackName = resource.callback.name || 'anonymous'; + const callbackName = resource?.callback?.name || 'microtask'; debug(callbackName); postEvent(Events.InitMicrotask(asyncId, triggerAsyncId, callbackName)); } @@ -45,7 +46,7 @@ const init = (asyncId, type, triggerAsyncId, resource) => { const before = (asyncId) => { const resource = asyncIdToResource[asyncId] || {}; const resourceName = resource.constructor.name; - if (resourceName === 'PromiseWrap') { + if (resourceName === 'Promise') { postEvent(Events.BeforePromise(asyncId)); } if (resourceName === 'Timeout') { @@ -56,36 +57,36 @@ const before = (asyncId) => { const callbackName = resource._onImmediate.name || 'anonymous'; postEvent(Events.BeforeImmediate(asyncId, callbackName)); } - if ( - resourceName === 'Object' && - resource.callback && - resource.callback.name !== 'maybeReadMore_' && - resource.callback.name !== 'afterWriteTick' && - resource.callback.name !== 'onSocketNT' && - resource.callback.name !== 'initRead' && - resource.callback.name !== 'emitReadable_' && - resource.callback.name !== 'emitCloseNT' && - resource.callback.name !== 'endReadableNT' && - resource.callback.name !== 'finish' && - resource.callback.name !== 'resume_' - ) { - const callbackName = resource.callback.name || 'anonymous'; - postEvent(Events.BeforeMicrotask(asyncId, callbackName)); - } - // if (resourceName === 'AsyncResource') { - // postEvent(Events.BeforeMicrotask(asyncId)); + // if ( + // resourceName === 'Object' && + // resource.callback && + // resource.callback.name !== 'maybeReadMore_' && + // resource.callback.name !== 'afterWriteTick' && + // resource.callback.name !== 'onSocketNT' && + // resource.callback.name !== 'initRead' && + // resource.callback.name !== 'emitReadable_' && + // resource.callback.name !== 'emitCloseNT' && + // resource.callback.name !== 'endReadableNT' && + // resource.callback.name !== 'finish' && + // resource.callback.name !== 'resume_' + // ) { + // const callbackName = resource.callback.name || 'anonymous'; + // postEvent(Events.BeforeMicrotask(asyncId, callbackName)); // } + if (resourceName === 'AsyncResource') { + postEvent(Events.BeforeMicrotask(asyncId)); + } }; const after = (asyncId) => { const resource = asyncIdToResource[asyncId] || {}; const resourceName = resource.constructor.name; - if (resourceName === 'PromiseWrap') { + if (resourceName === 'Promise') { postEvent(Events.AfterPromise(asyncId)); } - // if (resourceName === 'AsyncResource') { - // postEvent(Events.AfterMicrotask(asyncId)); - // } + if (resourceName === 'AsyncResource') { + postEvent(Events.AfterMicrotask(asyncId)); + } }; const destroy = (asyncId) => {