nstdlib-nightly
Version:
Node.js standard library converted to runtime-agnostic ES modules.
90 lines (77 loc) • 2.3 kB
JavaScript
// Source: https://github.com/nodejs/node/blob/65eff1eb/lib/internal/perf/timerify.js
import { createPerformanceNodeEntry } from "nstdlib/lib/internal/perf/performance_entry";
import { now } from "nstdlib/lib/internal/perf/utils";
import {
validateFunction,
validateObject,
} from "nstdlib/lib/internal/validators";
import { isHistogram } from "nstdlib/lib/internal/histogram";
import { codes as __codes__ } from "nstdlib/lib/internal/errors";
import { enqueue } from "nstdlib/lib/internal/perf/observe";
import { kEmptyObject } from "nstdlib/lib/internal/util";
const { ERR_INVALID_ARG_TYPE } = __codes__;
function processComplete(name, start, args, histogram) {
const duration = now() - start;
if (histogram !== undefined) histogram.record(Math.ceil(duration * 1e6));
const entry = createPerformanceNodeEntry(
name,
"function",
start,
duration,
args,
);
for (let n = 0; n < args.length; n++) entry[n] = args[n];
enqueue(entry);
}
function timerify(fn, options = kEmptyObject) {
validateFunction(fn, "fn");
validateObject(options, "options");
const { histogram } = options;
if (
histogram !== undefined &&
(!isHistogram(histogram) || typeof histogram.record !== "function")
) {
throw new ERR_INVALID_ARG_TYPE(
"options.histogram",
"RecordableHistogram",
histogram,
);
}
function timerified(...args) {
const isConstructorCall = new.target !== undefined;
const start = now();
const result = isConstructorCall
? Reflect.construct(fn, args, fn)
: ReflectApply(fn, this, args);
if (!isConstructorCall && typeof result?.finally === "function") {
return result.finally(
Function.prototype.bind.call(
processComplete,
result,
fn.name,
start,
args,
histogram,
),
);
}
processComplete(fn.name, start, args, histogram);
return result;
}
Object.defineProperties(timerified, {
length: {
__proto__: null,
configurable: false,
enumerable: true,
value: fn.length,
},
name: {
__proto__: null,
configurable: false,
enumerable: true,
value: `timerified ${fn.name}`,
},
});
return timerified;
}
export default timerify;