hiperf_txt_parser 1.0.2 → 1.0.4

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.
@@ -0,0 +1,13 @@
1
+ import type { PerfData, RecordSample } from "./types.js";
2
+ /**
3
+ * 将 RecordSample 原始栈中符合 pattern 的帧转为 hstack 可解析的栈格式。
4
+ *
5
+ * 输出示例:
6
+ * #26 at triggerBinder (entry|entry|1.0.0|src/main/ets/myabilitystage/PreloadHook.ts:4:21)
7
+ */
8
+ export declare function toBackTraceStack(sample: RecordSample): string;
9
+ /**
10
+ * 批量将 PerfData 中所有 RecordSample 转为 hstack 可解析栈。
11
+ * 返回数组长度与 recordSamples 一致,元素顺序一一对应。
12
+ */
13
+ export declare function toBackTraceStacks(data: PerfData): string[];
@@ -0,0 +1,33 @@
1
+ // 例: 26:0x0000005ab8b4beee : triggerBinder:[url:entry|entry|1.0.0|src/main/ets/x.ts:4:21][...]
2
+ const RAW_STACK_PATTERN = /^\s*(\d+):0x[0-9A-Za-z]+\s*:\s*([^\[]+?)\s*:\[url:([^\]]+)\].*$/;
3
+ /**
4
+ * 将 RecordSample 原始栈中符合 pattern 的帧转为 hstack 可解析的栈格式。
5
+ *
6
+ * 输出示例:
7
+ * #26 at triggerBinder (entry|entry|1.0.0|src/main/ets/myabilitystage/PreloadHook.ts:4:21)
8
+ */
9
+ export function toBackTraceStack(sample) {
10
+ const frames = sample.callchainFrames?.frames ?? [];
11
+ const out = [];
12
+ for (const frame of frames) {
13
+ const m = frame.match(RAW_STACK_PATTERN);
14
+ if (!m)
15
+ continue;
16
+ const index = m[1];
17
+ const funcName = m[2].trim();
18
+ const urlInfo = m[3].trim();
19
+ out.push(`#${index} at ${funcName} (${urlInfo})`);
20
+ }
21
+ console.info(`[hiperf_txt_parser] toBackTraceStack user stacks: ${out.length}/${frames.length}`);
22
+ return out.join("\n");
23
+ }
24
+ /**
25
+ * 批量将 PerfData 中所有 RecordSample 转为 hstack 可解析栈。
26
+ * 返回数组长度与 recordSamples 一致,元素顺序一一对应。
27
+ */
28
+ export function toBackTraceStacks(data) {
29
+ const stacks = data.recordSamples.map((sample) => toBackTraceStack(sample));
30
+ const nonEmpty = stacks.filter((s) => s.length > 0).length;
31
+ console.info(`[hiperf_txt_parser] toBackTraceStacks processed recordSamples: ${data.recordSamples.length}, non-empty user stacks: ${nonEmpty}`);
32
+ return stacks;
33
+ }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { parsePerfData, filterByTgid } from "./parser.js";
2
2
  export { formatPerfDataToText, formatPerfDataToJson } from "./serializer.js";
3
+ export { toBackTraceStack, toBackTraceStacks } from "./backtrace.js";
3
4
  export type { PerfData, RecordSample } from "./types.js";
4
5
  export type { RecordSampleJsonExportItem } from "./serializer.js";
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export { parsePerfData, filterByTgid } from "./parser.js";
2
2
  export { formatPerfDataToText, formatPerfDataToJson } from "./serializer.js";
3
+ export { toBackTraceStack, toBackTraceStacks } from "./backtrace.js";
package/dist/parser.js CHANGED
@@ -255,13 +255,16 @@ export function parsePerfData(text) {
255
255
  // 跳过无法解析的块
256
256
  }
257
257
  }
258
+ console.info(`[hiperf_txt_parser] parsePerfData parsed recordSamples: ${recordSamples.length}`);
258
259
  return { recordSamples };
259
260
  }
260
261
  /**
261
262
  * 按 tgid 过滤 RecordSample(当前以 pid 字段作为 tgid)
262
263
  */
263
264
  export function filterByTgid(data, tgid) {
264
- return {
265
- recordSamples: data.recordSamples.filter((sample) => sample.pid === tgid),
266
- };
265
+ const before = data.recordSamples.length;
266
+ const afterSamples = data.recordSamples.filter((sample) => sample.pid === tgid);
267
+ const after = afterSamples.length;
268
+ console.info(`[hiperf_txt_parser] filterByTgid tgid=${tgid}, recordSamples: ${before} -> ${after}`);
269
+ return { recordSamples: afterSamples };
267
270
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hiperf_txt_parser",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Parse perf data.txt and output structured TypeScript data",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",