bsprof-cli 1.0.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.
@@ -0,0 +1,202 @@
1
+ export interface BsprofHeader {
2
+ majorVersion: number;
3
+ minorVersion: number;
4
+ patchLevel: number;
5
+ headerSize: number;
6
+ requestedSampleRatio: number;
7
+ actualSampleRatio: number;
8
+ lineSpecificData: boolean;
9
+ memoryOperations: boolean;
10
+ timestampStart: bigint;
11
+ targetName: string;
12
+ supplementalInfo: string;
13
+ targetVersion: string;
14
+ deviceVendor: string;
15
+ deviceModel: string;
16
+ deviceFirmware: string;
17
+ }
18
+ export interface PathElement {
19
+ callingId: number;
20
+ modId?: number;
21
+ fileStrId: number;
22
+ funcStrId: number;
23
+ lineNumber: number;
24
+ lineOff?: number;
25
+ root: boolean;
26
+ }
27
+ export interface ModuleEntry {
28
+ nameStrId: number;
29
+ }
30
+ export interface MemoryRecord {
31
+ allocCount: number;
32
+ freeCount: number;
33
+ allocBytes: number;
34
+ freeBytes: number;
35
+ }
36
+ export interface CpuRecord {
37
+ cpuSelf: number;
38
+ wallSelf: number;
39
+ callCount?: number;
40
+ }
41
+ export interface ParseResult {
42
+ count: number;
43
+ errors: number;
44
+ memoryByPE: Map<number, MemoryRecord>;
45
+ cpuByPE: Map<number, CpuRecord>;
46
+ }
47
+ export interface ParsedProfile {
48
+ header: BsprofHeader;
49
+ strings: Map<number, string>;
50
+ modules: Map<number, ModuleEntry>;
51
+ pathElements: Map<number, PathElement>;
52
+ parseResult: ParseResult;
53
+ timestampEnd?: bigint;
54
+ fileSize: number;
55
+ }
56
+ export type MemorySortField = 'retained' | 'allocated' | 'allocCount';
57
+ export type CpuSortField = 'cpuSelf' | 'wallSelf' | 'callCount';
58
+ export interface AnalysisOptions {
59
+ top: number;
60
+ sortBy?: string;
61
+ filterModule?: string;
62
+ excludeModule?: string;
63
+ filterFile?: string;
64
+ threshold: number;
65
+ }
66
+ export interface ModuleStats {
67
+ module: string;
68
+ allocBytes: number;
69
+ freeBytes: number;
70
+ retainedBytes: number;
71
+ allocCount: number;
72
+ freeCount: number;
73
+ }
74
+ export interface FileStats {
75
+ file: string;
76
+ module: string;
77
+ allocBytes: number;
78
+ freeBytes: number;
79
+ retainedBytes: number;
80
+ allocCount: number;
81
+ freeCount: number;
82
+ }
83
+ export interface FunctionStats {
84
+ function: string;
85
+ file: string;
86
+ module: string;
87
+ allocBytes: number;
88
+ freeBytes: number;
89
+ retainedBytes: number;
90
+ allocCount: number;
91
+ freeCount: number;
92
+ cpuSelf: number;
93
+ wallSelf: number;
94
+ callCount: number;
95
+ callStack?: string[];
96
+ }
97
+ export interface HeaderInfo {
98
+ targetName: string;
99
+ targetVersion: string;
100
+ device: string;
101
+ firmware: string;
102
+ duration: number;
103
+ fileSize: number;
104
+ formatVersion: string;
105
+ features: string[];
106
+ }
107
+ export interface ParseStats {
108
+ entries: number;
109
+ errors: number;
110
+ strings: number;
111
+ modules: number;
112
+ pathElements: number;
113
+ }
114
+ export interface MemorySummary {
115
+ totalAllocBytes: number;
116
+ totalFreeBytes: number;
117
+ totalRetainedBytes: number;
118
+ totalAllocCount: number;
119
+ totalFreeCount: number;
120
+ parseStats: ParseStats;
121
+ }
122
+ export interface MemoryReport {
123
+ header: HeaderInfo;
124
+ summary: MemorySummary;
125
+ byModule: ModuleStats[];
126
+ byFile: FileStats[];
127
+ byFunction: FunctionStats[];
128
+ }
129
+ export interface CpuSummary {
130
+ totalCpuTime: number;
131
+ totalWallTime: number;
132
+ totalCallCount: number;
133
+ parseStats: ParseStats;
134
+ }
135
+ export interface CpuReport {
136
+ header: HeaderInfo;
137
+ summary: CpuSummary;
138
+ byFunction: FunctionStats[];
139
+ }
140
+ export interface FullReport {
141
+ header: HeaderInfo;
142
+ memory: MemoryReport;
143
+ cpu: CpuReport;
144
+ }
145
+ export interface SummaryReport {
146
+ header: HeaderInfo;
147
+ parseStats: ParseStats;
148
+ topMemoryLeaks: FunctionStats[];
149
+ topCpuConsumers: FunctionStats[];
150
+ moduleOverview: ModuleStats[];
151
+ }
152
+ export interface FunctionDelta {
153
+ function: string;
154
+ file: string;
155
+ module: string;
156
+ retainedBefore: number;
157
+ retainedAfter: number;
158
+ delta: number;
159
+ cpuBefore?: number;
160
+ cpuAfter?: number;
161
+ cpuDelta?: number;
162
+ }
163
+ export interface DiffReport {
164
+ before: {
165
+ file: string;
166
+ targetVersion: string;
167
+ };
168
+ after: {
169
+ file: string;
170
+ targetVersion: string;
171
+ };
172
+ memoryDelta: {
173
+ totalRetainedBefore: number;
174
+ totalRetainedAfter: number;
175
+ totalRetainedDelta: number;
176
+ regressions: FunctionDelta[];
177
+ improvements: FunctionDelta[];
178
+ newLeaks: string[];
179
+ resolvedLeaks: string[];
180
+ };
181
+ cpuDelta?: {
182
+ totalCpuBefore: number;
183
+ totalCpuAfter: number;
184
+ totalCpuDelta: number;
185
+ regressions: FunctionDelta[];
186
+ improvements: FunctionDelta[];
187
+ };
188
+ }
189
+ export interface ChromeTraceEvent {
190
+ name: string;
191
+ cat: string;
192
+ ph: string;
193
+ ts: number;
194
+ dur?: number;
195
+ pid: number;
196
+ tid: number;
197
+ args?: Record<string, unknown>;
198
+ }
199
+ export type OutputFormat = 'text' | 'json' | 'markdown';
200
+ export type ExportFormat = 'chrome-trace' | 'csv' | 'json';
201
+ export type AnalysisMode = 'memory' | 'cpu' | 'full' | 'summary';
202
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Buffer reader with varint (LEB128) decoding support for the .bsprof binary format.
3
+ * Varints use unsigned LEB128 encoding with up to 70-bit shift.
4
+ */
5
+ export declare class BufferReader {
6
+ pos: number;
7
+ private buf;
8
+ constructor(buffer: Buffer, offset?: number);
9
+ get length(): number;
10
+ get remaining(): number;
11
+ readVarint(): bigint;
12
+ /** Read varint and return as Number (safe for uint32 values) */
13
+ vi(): number;
14
+ /** Read varint and return as BigInt (for uint64 values) */
15
+ vi64(): bigint;
16
+ readFloat32LE(): number;
17
+ /** Read a null-terminated UTF-8 string */
18
+ readUtf8z(): string;
19
+ readAscii(length: number): string;
20
+ }
21
+ //# sourceMappingURL=varint.d.ts.map
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Buffer reader with varint (LEB128) decoding support for the .bsprof binary format.
3
+ * Varints use unsigned LEB128 encoding with up to 70-bit shift.
4
+ */
5
+ export class BufferReader {
6
+ pos;
7
+ buf;
8
+ constructor(buffer, offset = 0) {
9
+ this.buf = buffer;
10
+ this.pos = offset;
11
+ }
12
+ get length() {
13
+ return this.buf.length;
14
+ }
15
+ get remaining() {
16
+ return this.buf.length - this.pos;
17
+ }
18
+ readVarint() {
19
+ let result = 0n;
20
+ let shift = 0n;
21
+ while (this.pos < this.buf.length) {
22
+ const byte = this.buf[this.pos++];
23
+ result |= BigInt(byte & 0x7f) << shift;
24
+ if ((byte & 0x80) === 0)
25
+ break;
26
+ shift += 7n;
27
+ if (shift > 70n)
28
+ throw new Error(`Varint overflow at position ${this.pos}`);
29
+ }
30
+ return result;
31
+ }
32
+ /** Read varint and return as Number (safe for uint32 values) */
33
+ vi() {
34
+ return Number(this.readVarint());
35
+ }
36
+ /** Read varint and return as BigInt (for uint64 values) */
37
+ vi64() {
38
+ return this.readVarint();
39
+ }
40
+ readFloat32LE() {
41
+ const val = this.buf.readFloatLE(this.pos);
42
+ this.pos += 4;
43
+ return val;
44
+ }
45
+ /** Read a null-terminated UTF-8 string */
46
+ readUtf8z() {
47
+ const start = this.pos;
48
+ while (this.pos < this.buf.length && this.buf[this.pos] !== 0)
49
+ this.pos++;
50
+ const str = this.buf.toString('utf8', start, this.pos);
51
+ this.pos++;
52
+ return str;
53
+ }
54
+ readAscii(length) {
55
+ const str = this.buf.toString('ascii', this.pos, this.pos + length);
56
+ this.pos += length;
57
+ return str;
58
+ }
59
+ }
60
+ //# sourceMappingURL=varint.js.map
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "bsprof-cli",
3
+ "version": "1.0.0",
4
+ "description": "CLI tool for parsing and analyzing BrightScript Profiler (.bsprof) files",
5
+ "type": "module",
6
+ "main": "./dist/lib.js",
7
+ "types": "./dist/lib.d.ts",
8
+ "bin": {
9
+ "bsprof": "./dist/index.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/lib.js",
14
+ "types": "./dist/lib.d.ts"
15
+ }
16
+ },
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "start": "node dist/index.js",
20
+ "prepublishOnly": "npm run build"
21
+ },
22
+ "keywords": [
23
+ "roku",
24
+ "brightscript",
25
+ "profiler",
26
+ "bsprof",
27
+ "performance",
28
+ "memory",
29
+ "cpu"
30
+ ],
31
+ "author": "Juan Carlos Joya Carvajal",
32
+ "license": "MIT",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/jack1590/roku-bsprof-cli.git"
36
+ },
37
+ "homepage": "https://github.com/jack1590/roku-bsprof-cli#readme",
38
+ "bugs": {
39
+ "url": "https://github.com/jack1590/roku-bsprof-cli/issues"
40
+ },
41
+ "engines": {
42
+ "node": ">=18.0.0"
43
+ },
44
+ "files": [
45
+ "dist/**/*.js",
46
+ "dist/**/*.d.ts",
47
+ "README.md",
48
+ "LICENSE"
49
+ ],
50
+ "dependencies": {
51
+ "chalk": "^5.6.2",
52
+ "commander": "^14.0.3",
53
+ "minimatch": "^10.2.5"
54
+ },
55
+ "devDependencies": {
56
+ "@types/node": "^25.6.0",
57
+ "typescript": "^6.0.2"
58
+ }
59
+ }