measure-fn 3.8.0 → 3.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -237,7 +237,7 @@ import { configure } from 'measure-fn';
237
237
  configure({
238
238
  silent: true, // suppress all output
239
239
  timestamps: true, // prepend [HH:MM:SS.mmm]
240
- maxResultLength: 200, // truncate results (default: 200, 0 = unlimited)
240
+ maxResultLength: 200, // truncate results (default: 0 = unlimited)
241
241
  dotEndLabel: false, // show full label on end lines (default: true = dots)
242
242
  dotChar: '.', // character for dot fill (default: '·')
243
243
  logger: (event) => { // custom event handler
package/index.test.ts CHANGED
@@ -385,6 +385,46 @@ describe("createMeasure (scoped)", () => {
385
385
  expect(out.logs[2]).toBe("[b:a] ... y");
386
386
  expect(out.logs[4]).toBe("[a:b] ... z");
387
387
  });
388
+
389
+ test("scoped maxResultLength truncates results", () => {
390
+ const s = createMeasure("s", { maxResultLength: 15 });
391
+ s.resetCounter();
392
+ const out = captureConsole();
393
+ s.measureSync("op", () => ({ data: "x".repeat(50) }));
394
+ out.restore();
395
+ expect(out.logs[0]).toContain("…");
396
+ });
397
+
398
+ test("scoped maxResultLength inherits to children", () => {
399
+ const s = createMeasure("s", { maxResultLength: 15 });
400
+ s.resetCounter();
401
+ const out = captureConsole();
402
+ s.measureSync("parent", (m) => {
403
+ m("child", () => ({ data: "x".repeat(50) }));
404
+ return 1;
405
+ });
406
+ out.restore();
407
+ const childLine = out.logs[1];
408
+ expect(childLine).toContain("…");
409
+ });
410
+
411
+ test("per-label maxResultLength overrides scoped", () => {
412
+ const s = createMeasure("s", { maxResultLength: 15 });
413
+ s.resetCounter();
414
+ const out = captureConsole();
415
+ s.measureSync({ label: "op", maxResultLength: 500 }, () => ({ data: "x".repeat(50) }));
416
+ out.restore();
417
+ expect(out.logs[0]).not.toContain("…");
418
+ });
419
+
420
+ test("scoped maxResultLength works with async measure", async () => {
421
+ const s = createMeasure("s", { maxResultLength: 15 });
422
+ s.resetCounter();
423
+ const out = captureConsole();
424
+ await s.measure("op", async () => ({ data: "x".repeat(50) }));
425
+ out.restore();
426
+ expect(out.logs[1]).toContain("…");
427
+ });
388
428
  });
389
429
 
390
430
  // ─── measure.retry ───────────────────────────────────────────────────
package/index.ts CHANGED
@@ -12,7 +12,7 @@ const toAlpha = (num: number): string => {
12
12
 
13
13
  // ─── Safe Stringify ──────────────────────────────────────────────────
14
14
 
15
- let maxResultLen = 200;
15
+ let maxResultLen = 0;
16
16
 
17
17
  export const safeStringify = (value: unknown, limit?: number): string => {
18
18
  const cap = limit ?? maxResultLen;
@@ -273,10 +273,13 @@ export const resetCounter = () => {
273
273
  globalRootCounter = 0;
274
274
  };
275
275
 
276
- // ─── Core Implementation ─────────────────────────────────────────────
276
+ export type ScopeOpts = {
277
+ maxResultLength?: number;
278
+ };
277
279
 
278
- const createMeasureImpl = (prefix?: string, counterRef?: { value: number }) => {
280
+ const createMeasureImpl = (prefix?: string, counterRef?: { value: number }, scopeOpts?: ScopeOpts) => {
279
281
  const counter = counterRef ?? { get value() { return globalRootCounter; }, set value(v) { globalRootCounter = v; } };
282
+ const scopeMaxLen = scopeOpts?.maxResultLength;
280
283
  let _lastError: unknown = null;
281
284
 
282
285
  const _measureInternal = async <U>(
@@ -394,7 +397,7 @@ const createMeasureImpl = (prefix?: string, counterRef?: { value: number }) => {
394
397
  arg3?: (error: unknown) => any
395
398
  ): Promise<T | null> => {
396
399
  if (typeof arg2 === 'function') {
397
- return _measureInternal(arg2 as any, arg1, [counter.value++], 0, arg3) as Promise<T | null>;
400
+ return _measureInternal(arg2 as any, arg1, [counter.value++], 0, arg3, scopeMaxLen) as Promise<T | null>;
398
401
  } else {
399
402
  const currentId = toAlpha(counter.value++);
400
403
  emit({
@@ -539,7 +542,7 @@ const createMeasureImpl = (prefix?: string, counterRef?: { value: number }) => {
539
542
  arg2?: ((measure: MeasureSyncFn) => T)
540
543
  ): T | null => {
541
544
  if (typeof arg2 === 'function') {
542
- return _measureInternalSync(arg2, arg1, [counter.value++], 0) as T | null;
545
+ return _measureInternalSync(arg2, arg1, [counter.value++], 0, undefined, scopeMaxLen) as T | null;
543
546
  } else {
544
547
  const currentId = toAlpha(counter.value++);
545
548
  emit({
@@ -595,9 +598,9 @@ export const measureSync = globalInstance.measureSync;
595
598
 
596
599
  // ─── Scoped instances ────────────────────────────────────────────────
597
600
 
598
- export const createMeasure = (scopePrefix: string) => {
601
+ export const createMeasure = (scopePrefix: string, opts?: ScopeOpts) => {
599
602
  const scopeCounter = { value: 0 };
600
- const scoped = createMeasureImpl(scopePrefix, scopeCounter);
603
+ const scoped = createMeasureImpl(scopePrefix, scopeCounter, opts);
601
604
  return {
602
605
  ...scoped,
603
606
  resetCounter: () => { scopeCounter.value = 0; },
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "module": "index.ts",
4
4
  "main": "./index.ts",
5
5
  "types": "./index.ts",
6
- "version": "3.8.0",
6
+ "version": "3.9.0",
7
7
  "type": "module",
8
8
  "private": false,
9
9
  "description": "Zero-dependency function performance measurement with hierarchical logging",