UNPKG

@tldraw/utils

Version:

tldraw infinite canvas SDK (private utilities).

8 lines (7 loc) 5.87 kB
{ "version": 3, "sources": ["../../src/lib/perf.ts"], "sourcesContent": ["/**\n * Color scheme for performance indicators.\n * Provides consistent colors for performance measurement displays.\n *\n * @public\n */\nexport const PERFORMANCE_COLORS = {\n\tGood: '#40C057',\n\tMid: '#FFC078',\n\tPoor: '#E03131',\n}\n\n/**\n * Default color for performance measurement log prefixes.\n * Uses the 'Good' performance color for console output styling.\n *\n * @public\n */\nexport const PERFORMANCE_PREFIX_COLOR = PERFORMANCE_COLORS.Good\n\n/**\n * Measures and logs the execution time of a callback function.\n * Executes the provided callback and logs the duration to the console with styled output.\n *\n * @param name - Descriptive name for the operation being measured\n * @param cb - Callback function to execute and measure\n * @returns The return value of the callback function\n *\n * @example\n * ```ts\n * const result = measureCbDuration('data processing', () => {\n * return processLargeDataSet(data)\n * })\n * // Console output: \"Perf data processing took 42.5ms\"\n * ```\n *\n * @internal\n */\nexport function measureCbDuration(name: string, cb: () => any) {\n\tconst start = performance.now()\n\tconst result = cb()\n\t// eslint-disable-next-line no-console\n\tconsole.debug(\n\t\t`%cPerf%c ${name} took ${performance.now() - start}ms`,\n\t\t`color: white; background: ${PERFORMANCE_PREFIX_COLOR};padding: 2px;border-radius: 3px;`,\n\t\t'font-weight: normal'\n\t)\n\treturn result\n}\n\n/**\n * Decorator that measures and logs the execution time of class methods.\n * Wraps the decorated method to automatically log its execution duration.\n *\n * @param _target - The class prototype (unused)\n * @param propertyKey - Name of the method being decorated\n * @param descriptor - Property descriptor of the method\n * @returns Modified property descriptor with timing measurement\n *\n * @example\n * ```ts\n * class DataProcessor {\n * @measureDuration\n * processData(data: unknown[]) {\n * return data.map(item => transform(item))\n * }\n * }\n * // When processData is called, logs: \"Perf processData took: 15.2ms\"\n * ```\n *\n * @internal\n */\nexport function measureDuration(_target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n\tconst originalMethod = descriptor.value\n\tdescriptor.value = function (...args: any[]) {\n\t\tconst start = performance.now()\n\t\tconst result = originalMethod.apply(this, args)\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.debug(\n\t\t\t`%cPerf%c ${propertyKey} took: ${performance.now() - start}ms`,\n\t\t\t`color: white; background: ${PERFORMANCE_PREFIX_COLOR};padding: 2px;border-radius: 3px;`,\n\t\t\t'font-weight: normal'\n\t\t)\n\t\treturn result\n\t}\n\treturn descriptor\n}\n\nconst averages = new Map<any, { total: number; count: number }>()\n\n/**\n * Decorator that measures method execution time and tracks running averages.\n * Wraps the decorated method to log both current execution time and running average.\n * Maintains a running total and count for each decorated method to calculate averages.\n *\n * @param _target - The class prototype (unused)\n * @param propertyKey - Name of the method being decorated\n * @param descriptor - Property descriptor of the method\n * @returns Modified property descriptor with timing measurement and averaging\n *\n * @example\n * ```ts\n * class RenderEngine {\n * @measureAverageDuration\n * renderFrame() {\n * // Rendering logic here\n * }\n * }\n * // After multiple calls, logs: \"Perf renderFrame took 16.67ms | average 15.83ms\"\n * ```\n *\n * @internal\n */\nexport function measureAverageDuration(\n\t_target: any,\n\tpropertyKey: string,\n\tdescriptor: PropertyDescriptor\n) {\n\tconst originalMethod = descriptor.value\n\tdescriptor.value = function (...args: any[]) {\n\t\tconst start = performance.now()\n\t\tconst result = originalMethod.apply(this, args)\n\t\tconst end = performance.now()\n\t\tconst length = end - start\n\t\tif (length !== 0) {\n\t\t\tconst value = averages.get(descriptor.value)!\n\t\t\tconst total = value.total + length\n\t\t\tconst count = value.count + 1\n\t\t\taverages.set(descriptor.value, { total, count })\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.debug(\n\t\t\t\t`%cPerf%c ${propertyKey} took ${(end - start).toFixed(2)}ms | average ${(total / count).toFixed(2)}ms`,\n\t\t\t\t`color: white; background: ${PERFORMANCE_PREFIX_COLOR};padding: 2px;border-radius: 3px;`,\n\t\t\t\t'font-weight: normal'\n\t\t\t)\n\t\t}\n\t\treturn result\n\t}\n\taverages.set(descriptor.value, { total: 0, count: 0 })\n\treturn descriptor\n}\n"], "mappings": "AAMO,MAAM,qBAAqB;AAAA,EACjC,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AACP;AAQO,MAAM,2BAA2B,mBAAmB;AAoBpD,SAAS,kBAAkB,MAAc,IAAe;AAC9D,QAAM,QAAQ,YAAY,IAAI;AAC9B,QAAM,SAAS,GAAG;AAElB,UAAQ;AAAA,IACP,YAAY,IAAI,SAAS,YAAY,IAAI,IAAI,KAAK;AAAA,IAClD,6BAA6B,wBAAwB;AAAA,IACrD;AAAA,EACD;AACA,SAAO;AACR;AAwBO,SAAS,gBAAgB,SAAc,aAAqB,YAAgC;AAClG,QAAM,iBAAiB,WAAW;AAClC,aAAW,QAAQ,YAAa,MAAa;AAC5C,UAAM,QAAQ,YAAY,IAAI;AAC9B,UAAM,SAAS,eAAe,MAAM,MAAM,IAAI;AAE9C,YAAQ;AAAA,MACP,YAAY,WAAW,UAAU,YAAY,IAAI,IAAI,KAAK;AAAA,MAC1D,6BAA6B,wBAAwB;AAAA,MACrD;AAAA,IACD;AACA,WAAO;AAAA,EACR;AACA,SAAO;AACR;AAEA,MAAM,WAAW,oBAAI,IAA2C;AAyBzD,SAAS,uBACf,SACA,aACA,YACC;AACD,QAAM,iBAAiB,WAAW;AAClC,aAAW,QAAQ,YAAa,MAAa;AAC5C,UAAM,QAAQ,YAAY,IAAI;AAC9B,UAAM,SAAS,eAAe,MAAM,MAAM,IAAI;AAC9C,UAAM,MAAM,YAAY,IAAI;AAC5B,UAAM,SAAS,MAAM;AACrB,QAAI,WAAW,GAAG;AACjB,YAAM,QAAQ,SAAS,IAAI,WAAW,KAAK;AAC3C,YAAM,QAAQ,MAAM,QAAQ;AAC5B,YAAM,QAAQ,MAAM,QAAQ;AAC5B,eAAS,IAAI,WAAW,OAAO,EAAE,OAAO,MAAM,CAAC;AAE/C,cAAQ;AAAA,QACP,YAAY,WAAW,UAAU,MAAM,OAAO,QAAQ,CAAC,CAAC,iBAAiB,QAAQ,OAAO,QAAQ,CAAC,CAAC;AAAA,QAClG,6BAA6B,wBAAwB;AAAA,QACrD;AAAA,MACD;AAAA,IACD;AACA,WAAO;AAAA,EACR;AACA,WAAS,IAAI,WAAW,OAAO,EAAE,OAAO,GAAG,OAAO,EAAE,CAAC;AACrD,SAAO;AACR;", "names": [] }