Comparing version 4.11.0 to 5.0.0
@@ -9,3 +9,3 @@ # 0x kernel tracing | ||
Capturing these stacks requires kernel level tracing, which `0x` supports | ||
on Linux and macOS. | ||
on Linux. | ||
@@ -37,3 +37,3 @@ ## Requirements | ||
as bytecode handlers. In order to resolve this, the kernel tracing software | ||
(perf and DTrace) has to be able to jump to another memory address where the name | ||
(perf) has to be able to jump to another memory address where the name | ||
of the JavaScript function is held, however the memory address that it the kernel | ||
@@ -40,0 +40,0 @@ profiler should jump to is not exposed by the V8 engine to the kernel profiler. |
10
index.js
'use strict' | ||
const { sun, linux, windows, v8 } = require('./platform') | ||
const { linux, v8 } = require('./platform') | ||
const debug = require('debug')('0x') | ||
@@ -46,3 +46,3 @@ const { join, isAbsolute, relative, dirname } = require('path') | ||
args.title = args.title || `node ${args.argv.join(' ')}` | ||
var { ticks, pid, folder, inlined } = await startProcessAndCollectTraceData(args) | ||
const { ticks, pid, folder, inlined } = await startProcessAndCollectTraceData(args) | ||
@@ -104,4 +104,4 @@ if (treeDebug === true) { | ||
case 'linux': return linux(args, await isSudo()) | ||
case 'win32': return windows() | ||
default: return sun(args, await isSudo()) | ||
default: | ||
throw Error(`0x: ${platform} kernel tracing is not currently supported`) | ||
} | ||
@@ -139,3 +139,3 @@ } | ||
var meta | ||
let meta | ||
try { | ||
@@ -142,0 +142,0 @@ meta = JSON.parse(fs.readFileSync(join(folder, 'meta.json'))) |
@@ -52,3 +52,3 @@ 'use strict' | ||
if (name === '-') return '-' | ||
var htmlPath = (outputHtml || ( | ||
let htmlPath = (outputHtml || ( | ||
`{outputDir}${path.sep}{name}.html` | ||
@@ -55,0 +55,0 @@ )).replace('{pid}', pid || 'UNKNOWN_PID') |
@@ -9,4 +9,5 @@ 'use strict' | ||
const preloadDirRx = RegExp(join(escape(__dirname), 'preload')) | ||
// TODO(@rafaelgss): it looks like not working with v16 when node prefix was added | ||
const internalModuleRegExp = /^.?(?:\(anonymous\)|internalBinding|NativeModule[^ ]*) [^/\\][a-zA-Z0-9_/\\-]+\.js:\d+:\d+$/ | ||
const nodeBootstrapRegExp = / internal\/bootstrap.+\.js:\d+:\d+$/ | ||
const nodeBootstrapRegExp = / (node:)?internal\/bootstrap.+(\.js)?:\d+(:?\d+)$/ | ||
@@ -16,3 +17,4 @@ module.exports = ticksToTree | ||
function hasFileLocation (jsFrameName) { | ||
return /:\d+:\d+$/.test(jsFrameName) | ||
// perf samples doesn't contains the column number | ||
return /:\d+(:\d+)?$/.test(jsFrameName) | ||
} | ||
@@ -63,8 +65,9 @@ | ||
// 4 inlinable optimized | ||
var S = 0 | ||
let S = 0 | ||
if (type === 'JS') { | ||
if (name[0] === ' ') name = '(anonymous)' + name | ||
// TODO(@rafaelgss): adjust it for v16 + perf stacks | ||
if (inlineInfo === true) { | ||
const [ key ] = name.split(':') | ||
const [key] = name.split(':') | ||
const info = inlined[key] | ||
@@ -91,3 +94,3 @@ if (info !== undefined) { | ||
} else { | ||
const [ lookup ] = stack[ix - 1] ? (stack[ix - 1].name.split(':')) : [] | ||
const [lookup] = stack[ix - 1] ? (stack[ix - 1].name.split(':')) : [] | ||
const callerMatch = inlined[key].find(({ caller }) => caller.key === lookup) | ||
@@ -119,3 +122,3 @@ if (callerMatch) S += 2 | ||
function addToMergedTree (stack) { | ||
var lastFrame = null | ||
let lastFrame = null | ||
stack.forEach((frame, ix) => { | ||
@@ -142,3 +145,3 @@ // TODO need an elegant way to place inlined frames into *other* stacks | ||
function addToUnmergedTree (stack) { | ||
var lastFrame = null | ||
let lastFrame = null | ||
stack.forEach((frame, ix) => { | ||
@@ -177,3 +180,3 @@ // TODO need an elegant way to place inlined frames into *other* stacks | ||
let foundNodeModule = false | ||
for (var i = frames.length - 1; i >= 0; i--) { | ||
for (let i = frames.length - 1; i >= 0; i--) { | ||
const frame = frames[i] | ||
@@ -180,0 +183,0 @@ if (foundNodeModule) { |
@@ -9,3 +9,3 @@ 'use strict' | ||
const splitChar = '\n' | ||
let lines = [] | ||
const lines = [] | ||
let searchStart = 0 | ||
@@ -35,3 +35,4 @@ let newlineIx | ||
stacks[n].unshift({ name: line.trim().replace(/^LazyCompile:|Function:|Script:/, '') }) | ||
const name = cleanupStackLine(line) | ||
stacks[n].unshift({ name, type: getStackType(name) }) | ||
return stacks | ||
@@ -42,1 +43,31 @@ }, []) | ||
} | ||
function cleanupStackLine (line) { | ||
// match linux perf stack trace | ||
// eg: 7f587bf53533 Function:^emit node:events:340+0xa13 (/tmp/perf-132082.map) | ||
const regexCallStack = line.match(/^\s*(\w+)\s*(.+) \((\S*)\)/) | ||
if (regexCallStack) { | ||
const rawfunc = regexCallStack[2] | ||
// Linux 4.8 included symbol offsets in perf script output by default, eg: | ||
// 7fffb84c9afc cpu_startup_entry+0x800047c022ec ([kernel.kallsyms]) | ||
// strip these off: | ||
return rawfunc.replace(/\+0x[\da-f]+$/, '').replace(/^LazyCompile:|Function:|Script:/, '') | ||
} | ||
return line | ||
} | ||
function getStackType (name) { | ||
if (name.match(/^RegExp:/)) { | ||
return 'CODE:RegExp' | ||
} | ||
if (name.match(/::/)) { | ||
return 'CPP' | ||
} | ||
if (name.match(/.*\.js:/) || name.match(/:/)) { | ||
return 'JS' | ||
} | ||
// TODO(@rafaelgss): add native and kernel types | ||
return 'SHARED_LIB' | ||
} |
@@ -70,3 +70,3 @@ 'use strict' | ||
function isSudo () { | ||
var check = spawn('sudo', ['-n', 'true']) | ||
const check = spawn('sudo', ['-n', 'true']) | ||
return new Promise((resolve, reject) => { | ||
@@ -73,0 +73,0 @@ check.on('error', reject) |
@@ -10,2 +10,4 @@ 'use strict' | ||
const pump = require('pump') | ||
const debug = require('debug')('0x') | ||
const { Writable } = require('stream') | ||
@@ -79,2 +81,4 @@ const readFile = promisify(fs.readFile) | ||
debug(`v8LogToTicks isJson ${isJson}`) | ||
debug(`v8LogToTicks isolateLogPath ${isolateLogPath}`) | ||
const close = isJson ? () => {} : () => sp.kill() | ||
@@ -94,4 +98,11 @@ const srcStream = isJson ? fs.createReadStream(isolateLogPath) : sp.stdout | ||
} | ||
}), process.stderr) | ||
}), new Writable({ | ||
objectMode: true, | ||
write (chunk, enc, cb) { | ||
debug(`--prof-process --preprocces stderr: ${chunk.toString()}`) | ||
cb() | ||
} | ||
})) | ||
} | ||
return new Promise((resolve, reject) => { | ||
@@ -101,9 +112,6 @@ const ticks = [] | ||
const codeStream = parse('code.*', (code) => { | ||
codes.push(code) | ||
}) | ||
if (isJson === false) { | ||
const v8Json = isolateLogPath.replace(extname(isolateLogPath), '.json') | ||
pump(srcStream, fs.createWriteStream(v8Json), (err) => { | ||
debug('v8LogToTicks pump srcStream -> fs.createWriteStream v8Json err', err) | ||
if (err) { | ||
@@ -116,3 +124,13 @@ reject(err) | ||
pump(srcStream, codeStream, (err) => { | ||
const codeStream = parse('code.*') | ||
const codeDest = new Writable({ | ||
objectMode: true, | ||
write (chunk, _, cb) { | ||
codes.push(chunk) | ||
cb() | ||
} | ||
}) | ||
pump(srcStream, codeStream, codeDest, (err) => { | ||
debug('codeStream finished') | ||
if (!err) return | ||
@@ -129,15 +147,22 @@ if (/^Unexpected/.test(err.message)) { | ||
const delayMs = options.collectDelay * 1000 | ||
const tickStream = parse('ticks.*', (tick) => { | ||
const addr = tick.s.filter((n, i) => i % 2 === 0) | ||
var stack = addr.map((n) => codes[n]).filter(Boolean) | ||
if (firstTick.length === 0) { | ||
firstTick.push(tick.tm) | ||
const tickStream = parse('ticks.*') | ||
const dest = new Writable({ | ||
objectMode: true, | ||
write (tick, _, cb) { | ||
const addr = tick.s.filter((n, i) => i % 2 === 0) | ||
const stack = addr.map((n) => codes[n]).filter(Boolean) | ||
if (firstTick.length === 0) { | ||
firstTick.push(tick.tm) | ||
} | ||
// Compare ticks to first for collectDelay | ||
if (tick.tm > (firstTick[0] + delayMs)) { | ||
ticks.push(stack.reverse()) | ||
} | ||
cb() | ||
} | ||
// Compare ticks to first for collectDelay | ||
if (tick.tm > (firstTick[0] + delayMs)) { | ||
ticks.push(stack.reverse()) | ||
} | ||
}) | ||
pump(srcStream, tickStream, (err) => { | ||
pump(srcStream, tickStream, dest, (err) => { | ||
debug('tickStream finished') | ||
if (err) { | ||
@@ -152,2 +177,3 @@ close() | ||
sp.on('exit', (code) => { | ||
debug('v8LogToTicks sp.on exit code', code) | ||
if (code !== 0) return reject(Error('v8 log conversion failed')) | ||
@@ -154,0 +180,0 @@ }) |
'use strict' | ||
const ajv = require('ajv')() | ||
const Ajv = require('ajv') | ||
const ajv = new Ajv() | ||
@@ -5,0 +6,0 @@ module.exports = (schema) => { |
{ | ||
"name": "0x", | ||
"version": "4.11.0", | ||
"version": "5.0.0", | ||
"description": "🔥 single-command flamegraph profiling 🔥", | ||
@@ -27,5 +27,5 @@ "main": "index.js", | ||
"dependencies": { | ||
"ajv": "^6.9.2", | ||
"browserify": "^16.2.3", | ||
"concat-stream": "^1.5.2", | ||
"ajv": "^8.8.2", | ||
"browserify": "^17.0.0", | ||
"concat-stream": "^2.0.0", | ||
"d3-fg": "^6.14.0", | ||
@@ -36,8 +36,8 @@ "debounce": "^1.2.0", | ||
"env-string": "^1.0.0", | ||
"escape-string-regexp": "^1.0.5", | ||
"escape-string-regexp": "^4.0.0", | ||
"execspawn": "^1.0.1", | ||
"has-unicode": "^2.0.1", | ||
"hsl-to-rgb-for-reals": "^1.1.0", | ||
"jsonstream2": "^1.1.2", | ||
"make-dir": "^1.3.0", | ||
"jsonstream2": "^3.0.0", | ||
"make-dir": "^3.1.0", | ||
"minimist": "^1.2.0", | ||
@@ -48,20 +48,18 @@ "morphdom": "^2.3.3", | ||
"opn": "^5.4.0", | ||
"perf-sym": "^2.0.3", | ||
"pump": "^3.0.0", | ||
"pumpify": "^1.4.0", | ||
"semver": "^5.5.1", | ||
"pumpify": "^2.0.1", | ||
"semver": "^7.3.5", | ||
"single-line-log": "^1.0.1", | ||
"split2": "^3.1.0", | ||
"split2": "^4.0.0", | ||
"tachyons": "^4.9.1", | ||
"through2": "^2.0.5", | ||
"which": "^1.2.4" | ||
"through2": "^4.0.0", | ||
"which": "^2.0.2" | ||
}, | ||
"devDependencies": { | ||
"esprima": "^4.0.1", | ||
"rimraf": "^2.6.3", | ||
"snazzy": "^8.0.0", | ||
"standard": "^12.0.1", | ||
"tap": "^12.5.3" | ||
"rimraf": "^3.0.2", | ||
"snazzy": "^9.0.0", | ||
"standard": "^16.0.0", | ||
"tap": "^15.0.0" | ||
}, | ||
"browserify-shim": {} | ||
} |
'use strict' | ||
const linux = require('./linux') | ||
const sun = require('./sun') | ||
const windows = require('./windows') | ||
const v8 = require('./v8') | ||
module.exports = { linux, sun, windows, v8 } | ||
module.exports = { linux, v8 } |
@@ -21,4 +21,7 @@ 'use strict' | ||
const { status, outputDir, workingDir, name, onPort, pathToNodeBinary } = args | ||
var perf = pathTo('perf') | ||
if (!perf) return void cb(Error('Unable to locate perf - make sure it\'s in your PATH')) | ||
const perf = pathTo('perf') | ||
if (!perf) { | ||
cb(Error('Unable to locate perf - make sure it\'s in your PATH')) | ||
return | ||
} | ||
if (!sudo) { | ||
@@ -30,7 +33,7 @@ status('Stacks are captured using perf(1), which requires sudo access\n') | ||
var uid = parseInt(Math.random() * 1e9, 10).toString(36) | ||
var perfdat = '/tmp/perf-' + uid + '.data' | ||
var kernelTracingDebug = args.kernelTracingDebug | ||
const uid = parseInt(Math.random() * 1e9, 10).toString(36) | ||
const perfdat = '/tmp/perf-' + uid + '.data' | ||
const kernelTracingDebug = args.kernelTracingDebug | ||
var proc = spawn('sudo', [ | ||
const proc = spawn('sudo', [ | ||
'-E', | ||
@@ -40,5 +43,3 @@ 'perf', | ||
!kernelTracingDebug ? '-q' : '', | ||
'-e', | ||
'cpu-clock', | ||
'-F 1000', // 1000 samples per sec === 1ms profiling like dtrace | ||
'-F 99', | ||
'-g', | ||
@@ -61,6 +62,6 @@ '-o', | ||
} | ||
analyze(true) | ||
filterInternalFunctions(perfdat) | ||
}) | ||
var folder = getTargetFolder({ outputDir, workingDir, name, pid: proc.pid }) | ||
const folder = getTargetFolder({ outputDir, workingDir, name, pid: proc.pid }) | ||
@@ -81,3 +82,7 @@ if (onPort) status('Profiling\n') | ||
process.once('SIGINT', analyze) | ||
process.once('SIGINT', () => { | ||
spawn('sudo', ['kill', '-SIGINT', '' + proc.pid], { | ||
stdio: 'inherit' | ||
}) | ||
}) | ||
@@ -99,3 +104,3 @@ function analyze (manual) { | ||
function generate () { | ||
var stacks = spawn('sudo', ['perf', 'script', '-i', perfdat], { | ||
const stacks = spawn('sudo', ['perf', 'script', '-i', perfdat], { | ||
stdio: [ | ||
@@ -112,11 +117,31 @@ 'ignore', | ||
pid: proc.pid, | ||
folder: folder | ||
folder: folder, | ||
inlined: [] | ||
}) | ||
}) | ||
} | ||
} | ||
spawn('sudo', ['kill', '-SIGINT', '' + proc.pid], { | ||
stdio: 'inherit' | ||
function filterInternalFunctions (perfFile) { | ||
// Filtering out Node.js internal functions | ||
const sed = spawn('sudo', [ | ||
'sed', | ||
'-i', | ||
'-e', | ||
'/( __libc_start| LazyCompile | v8::internal::| Builtin:| Stub:| LoadIC:|[unknown]| LoadPolymorphicIC:)/d', | ||
'-e', | ||
's/ LazyCompile:[*~]?/ /', | ||
perfFile | ||
], { | ||
stdio: ['ignore', 'inherit', 'inherit', 'ignore', 'ignore', 'pipe'] | ||
}) | ||
sed.on('exit', function (code) { | ||
if (code !== null && code !== 0) { | ||
console.error('`sed` subprocess error, code: ' + code) | ||
return | ||
} | ||
analyze(true) | ||
}) | ||
} | ||
} |
@@ -26,3 +26,3 @@ 'use strict' | ||
let proc = spawn(pathToNodeBinary, [ | ||
const proc = spawn(pathToNodeBinary, [ | ||
'--prof', | ||
@@ -147,3 +147,3 @@ `--logfile=${workingDir ? `${args.workingDir}/` : ''}%p-v8.log`, | ||
let lastOptimizedFrame = null | ||
let inlined = {} | ||
const inlined = {} | ||
@@ -159,3 +159,3 @@ // Try to parse an INLINE() item from the optimization log, | ||
// would contain everything up to the ) in FUNCTION SOURCE () | ||
const [ match, inlinedFn ] = /INLINE \((.*?)\) id\{/.exec(s) || [ false ] | ||
const [match, inlinedFn] = /INLINE \((.*?)\) id\{/.exec(s) || [false] | ||
// shouldn't not match though.. | ||
@@ -162,0 +162,0 @@ if (match === false) return -1 |
@@ -16,3 +16,3 @@ # 0x | ||
* Node v8.5.0 and above | ||
* Node v12.x and above | ||
* Default usage supports any Operating System that Node runs on! | ||
@@ -22,12 +22,2 @@ * Chrome | ||
## Legacy | ||
Older versions of Node are supported via previous 0x versions: | ||
| 0x | Node | macOS/SmartOS | Linux | Windows | | ||
|----|------------|-------|-------|---------| | ||
| v4 | v8.5.0+ | ☑️ | ☑️ | ☑️ | | ||
| v3 | v6 – v8.4.0| ☑️ | ☑️ | ⤬ | | ||
| v2 | v4 | ☑️ | ☑️ | ⤬ | | ||
## Demo | ||
@@ -202,6 +192,5 @@ | ||
Use an OS kernel tracing tool (perf on Linux or | ||
dtrace on macOS and SmartOS). This will capture | ||
Use an OS kernel tracing tool (perf on Linux). This will capture | ||
native stack frames (C++ modules and Libuv I/O), | ||
but may result in missing stacks on Node 8. | ||
but may result in missing stacks from Node.js due to the optimizing compiler. | ||
@@ -255,3 +244,3 @@ See [docs/kernel-tracing.md](docs/kernel-tracing.md) for more information. | ||
Show output from DTrace or perf(1) tools. | ||
Show output from perf(1) tools. | ||
@@ -258,0 +247,0 @@ Default: false |
@@ -81,3 +81,3 @@ 'use strict' | ||
if (!state.control.optimized) return flamegraph.clear('yellow') | ||
flamegraph.search(RegExp('^\\*'), 'yellow') | ||
flamegraph.search(/^\\*/, 'yellow') | ||
return | ||
@@ -96,3 +96,3 @@ case 'not-optimized': | ||
function zoom () { | ||
var zoomLevel = 1 | ||
let zoomLevel = 1 | ||
return ({ type }) => { | ||
@@ -99,0 +99,0 @@ switch (type) { |
@@ -19,17 +19,23 @@ 'use strict' | ||
const tiers = button(render)({ label: 'Tiers', pressed: state.tiers }, () => action({ type: 'tiers' })) | ||
const view = state.renderMergedBtn && !state.visualizeCpuProfile ? button(render)({ | ||
label: state.merged ? 'Unmerge' : 'Merge', | ||
width: '6.85em', | ||
pressed: state.merged | ||
}, () => action({ type: 'view' })) : '' | ||
const optimized = state.visualizeCpuProfile ? '' : button(render)({ | ||
label: 'Optimized', | ||
pressed: !state.merged && state.optimized, | ||
disabled: state.merged | ||
}, () => action({ type: 'optimized' })) | ||
const unoptimized = state.visualizeCpuProfile ? '' : button(render)({ | ||
label: 'Unoptimized', | ||
pressed: !state.merged && state.unoptimized, | ||
disabled: state.merged | ||
}, () => action({ type: 'not-optimized' })) | ||
const view = state.renderMergedBtn && !state.visualizeCpuProfile | ||
? button(render)({ | ||
label: state.merged ? 'Unmerge' : 'Merge', | ||
width: '6.85em', | ||
pressed: state.merged | ||
}, () => action({ type: 'view' })) | ||
: '' | ||
const optimized = state.visualizeCpuProfile | ||
? '' | ||
: button(render)({ | ||
label: 'Optimized', | ||
pressed: !state.merged && state.optimized, | ||
disabled: state.merged | ||
}, () => action({ type: 'optimized' })) | ||
const unoptimized = state.visualizeCpuProfile | ||
? '' | ||
: button(render)({ | ||
label: 'Unoptimized', | ||
pressed: !state.merged && state.unoptimized, | ||
disabled: state.merged | ||
}, () => action({ type: 'not-optimized' })) | ||
@@ -36,0 +42,0 @@ return render` |
@@ -27,3 +27,3 @@ 'use strict' | ||
function v8cats (child) { | ||
var name = child.name | ||
const name = child.name | ||
if (child.type) return { type: child.type } | ||
@@ -30,0 +30,0 @@ // RegExp and Eval can contain anything (a method name defined in eval could be any string) |
@@ -33,3 +33,3 @@ 'use strict' | ||
} | ||
const inlinable = renderInlinable ? hoc({ bg: bgs['inlinable'], exclude, name: 'inlinable', disabled: !enableInlinable }, action) : '' | ||
const inlinable = renderInlinable ? hoc({ bg: bgs.inlinable, exclude, name: 'inlinable', disabled: !enableInlinable }, action) : '' | ||
const native = hoc({ bg: bgs.native, exclude, name: 'native' }, action) | ||
@@ -36,0 +36,0 @@ const regexp = hoc({ bg: bgs.regexp, exclude, name: 'regexp', lbl: 'rx' }, action) |
@@ -45,5 +45,5 @@ 'use strict' | ||
inlinable: `rgb(${hsl( | ||
colors['inlinable'].h, | ||
colors['inlinable'].s / 100 * 1.2, | ||
colors['inlinable'].l / 100 * 1.2 | ||
colors.inlinable.h, | ||
colors.inlinable.s / 100 * 1.2, | ||
colors.inlinable.l / 100 * 1.2 | ||
)})`, | ||
@@ -50,0 +50,0 @@ app: `rgb(${hsl( |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
617365
27
4
142
12
7
1962
323
+ Addedajv@8.17.1(transitive)
+ Addedavailable-typed-arrays@1.0.7(transitive)
+ Addedbrowserify@17.0.0(transitive)
+ Addedconcat-stream@2.0.0(transitive)
+ Addedduplexify@4.1.3(transitive)
+ Addedescape-string-regexp@4.0.0(transitive)
+ Addedevents@3.3.0(transitive)
+ Addedfast-uri@3.0.1(transitive)
+ Addedfor-each@0.3.3(transitive)
+ Addedhas-tostringtag@1.0.2(transitive)
+ Addedis-arguments@1.1.1(transitive)
+ Addedis-callable@1.2.7(transitive)
+ Addedis-generator-function@1.0.10(transitive)
+ Addedis-typed-array@1.1.13(transitive)
+ Addedjson-schema-traverse@1.0.0(transitive)
+ Addedjsonstream2@3.0.0(transitive)
+ Addedmake-dir@3.1.0(transitive)
+ Addedpath-browserify@1.0.1(transitive)
+ Addedpossible-typed-array-names@1.0.0(transitive)
+ Addedpumpify@2.0.1(transitive)
+ Addedrequire-from-string@2.0.2(transitive)
+ Addedsemver@6.3.17.6.3(transitive)
+ Addedsplit2@4.2.0(transitive)
+ Addedstream-browserify@3.0.0(transitive)
+ Addedthrough2@3.0.24.0.2(transitive)
+ Addedutil@0.12.5(transitive)
+ Addedwhich@2.0.2(transitive)
+ Addedwhich-typed-array@1.1.15(transitive)
- Removedperf-sym@^2.0.3
- Removedajv@6.12.6(transitive)
- Removedansicolors@0.2.1(transitive)
- Removedbrowserify@16.5.2(transitive)
- Removedduplexify@3.7.1(transitive)
- Removedevents@2.1.0(transitive)
- Removedfast-json-stable-stringify@2.1.0(transitive)
- Removedisarray@0.0.1(transitive)
- Removedjson-schema-traverse@0.4.1(transitive)
- Removedjson-stable-stringify@0.0.1(transitive)
- Removedjsonify@0.0.1(transitive)
- Removedjsonparse@0.0.6(transitive)
- Removedjsonstream2@1.1.2(transitive)
- Removedmake-dir@1.3.0(transitive)
- Removedpath-browserify@0.0.1(transitive)
- Removedperf-sym@2.0.3(transitive)
- Removedpify@3.0.0(transitive)
- Removedpretty-trace@0.3.1(transitive)
- Removedpump@1.0.32.0.1(transitive)
- Removedpumpify@1.5.1(transitive)
- Removedpunycode@2.3.1(transitive)
- Removedreadable-stream@1.0.34(transitive)
- Removedresolve-jit-symbols@0.5.0(transitive)
- Removedsemver@5.7.2(transitive)
- Removedshasum@1.0.2(transitive)
- Removedsplit2@0.2.12.2.03.2.2(transitive)
- Removedstream-browserify@2.0.2(transitive)
- Removedstring_decoder@0.10.31(transitive)
- Removedthrough2@0.6.5(transitive)
- Removeduri-js@4.4.1(transitive)
- Removedwhich@1.3.1(transitive)
Updatedajv@^8.8.2
Updatedbrowserify@^17.0.0
Updatedconcat-stream@^2.0.0
Updatedescape-string-regexp@^4.0.0
Updatedjsonstream2@^3.0.0
Updatedmake-dir@^3.1.0
Updatedpumpify@^2.0.1
Updatedsemver@^7.3.5
Updatedsplit2@^4.0.0
Updatedthrough2@^4.0.0
Updatedwhich@^2.0.2