@expo/event-log 0.0.1-init
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/CHANGELOG.md +5 -0
- package/LICENSE.md +22 -0
- package/README.md +74 -0
- package/bin/cli.js +19 -0
- package/cli/package.json +17 -0
- package/dist/chunks/tap-chunk.js +536 -0
- package/dist/chunks/tap-chunk.js.map +1 -0
- package/dist/chunks/tap-chunk.mjs +522 -0
- package/dist/chunks/tap-chunk.mjs.map +1 -0
- package/dist/event-log.d.ts +142 -0
- package/dist/event-log.js +983 -0
- package/dist/event-log.js.map +1 -0
- package/dist/event-log.mjs +977 -0
- package/dist/event-log.mjs.map +1 -0
- package/dist/expo-event-log-cli.d.ts +4 -0
- package/dist/expo-event-log-cli.js +1412 -0
- package/dist/expo-event-log-cli.js.map +1 -0
- package/dist/expo-event-log-cli.mjs +1406 -0
- package/dist/expo-event-log-cli.mjs.map +1 -0
- package/package.json +95 -0
|
@@ -0,0 +1,1406 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { fileURLToPath as e } from "node:url";
|
|
3
|
+
|
|
4
|
+
import { c as t, p as n, a as s, m as o, r, b as i, d as a, t as c, L as l, l as p } from "./chunks/tap-chunk.mjs";
|
|
5
|
+
|
|
6
|
+
import u from "node:fs";
|
|
7
|
+
|
|
8
|
+
import { createInterface as f } from "node:readline";
|
|
9
|
+
|
|
10
|
+
import { parseArgs as d } from "node:util";
|
|
11
|
+
|
|
12
|
+
import m from "node:crypto";
|
|
13
|
+
|
|
14
|
+
import h from "node:path";
|
|
15
|
+
|
|
16
|
+
import g from "typescript";
|
|
17
|
+
|
|
18
|
+
import { spawn as v } from "node:child_process";
|
|
19
|
+
|
|
20
|
+
import y from "node:http";
|
|
21
|
+
|
|
22
|
+
const w = {
|
|
23
|
+
since: {
|
|
24
|
+
type: "string"
|
|
25
|
+
},
|
|
26
|
+
filter: {
|
|
27
|
+
type: "string",
|
|
28
|
+
multiple: !0
|
|
29
|
+
},
|
|
30
|
+
tail: {
|
|
31
|
+
type: "boolean"
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
async function* readJsonlStream(e) {
|
|
36
|
+
const t = f({
|
|
37
|
+
input: e
|
|
38
|
+
});
|
|
39
|
+
for await (const e of t) {
|
|
40
|
+
if (!e) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const t = s(e);
|
|
44
|
+
if (t) {
|
|
45
|
+
yield t;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function parseSharedTapOptions(e) {
|
|
51
|
+
return {
|
|
52
|
+
since: e.since,
|
|
53
|
+
filter: e.filter?.flatMap(e => e.split(",")).map(e => e.trim()).filter(Boolean),
|
|
54
|
+
follow: !0 === e.tail
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function parseHelp(e) {
|
|
59
|
+
return !0 === d({
|
|
60
|
+
args: e,
|
|
61
|
+
allowPositionals: !0,
|
|
62
|
+
strict: !1,
|
|
63
|
+
options: {
|
|
64
|
+
help: {
|
|
65
|
+
type: "boolean",
|
|
66
|
+
short: "h"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}).values.help;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function parsePort(e) {
|
|
73
|
+
if (null == e) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const t = function parseInteger(e, t) {
|
|
77
|
+
if (!/^\d+$/.test(e)) {
|
|
78
|
+
throw new Error(`Invalid ${t}: ${e}`);
|
|
79
|
+
}
|
|
80
|
+
const n = Number(e);
|
|
81
|
+
if (!Number.isSafeInteger(n)) {
|
|
82
|
+
throw new Error(`Invalid ${t}: ${e}`);
|
|
83
|
+
}
|
|
84
|
+
return n;
|
|
85
|
+
}(e, "port");
|
|
86
|
+
if (t < 0 || t > 65535) {
|
|
87
|
+
throw new Error(`Invalid port: ${e}`);
|
|
88
|
+
}
|
|
89
|
+
return t;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function parseNonNegativeNumber(e, t) {
|
|
93
|
+
if (null == e) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const n = Number(e);
|
|
97
|
+
if (!Number.isFinite(n) || n < 0) {
|
|
98
|
+
throw new Error(`Invalid ${t}: ${e}`);
|
|
99
|
+
}
|
|
100
|
+
return n;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function matchesTapOptions(e, t, n) {
|
|
104
|
+
if (null != t && e._t < t) {
|
|
105
|
+
return !1;
|
|
106
|
+
}
|
|
107
|
+
return o(e._e, n);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function durationUnitToMs(e) {
|
|
111
|
+
if ("ms" === e || "msec" === e || "msecs" === e || "millisecond" === e || "milliseconds" === e) {
|
|
112
|
+
return 1;
|
|
113
|
+
}
|
|
114
|
+
if ("s" === e || "sec" === e || "secs" === e || "second" === e || "seconds" === e) {
|
|
115
|
+
return 1e3;
|
|
116
|
+
}
|
|
117
|
+
if ("m" === e || "min" === e || "mins" === e || "minute" === e || "minutes" === e) {
|
|
118
|
+
return 6e4;
|
|
119
|
+
}
|
|
120
|
+
if ("h" === e || "hr" === e || "hrs" === e || "hour" === e || "hours" === e) {
|
|
121
|
+
return 36e5;
|
|
122
|
+
}
|
|
123
|
+
throw new Error(`Invalid duration unit: ${e}`);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function runCleanCli(e = []) {
|
|
127
|
+
const t = function parseJsonFlag(e) {
|
|
128
|
+
return d({
|
|
129
|
+
args: e,
|
|
130
|
+
allowPositionals: !0,
|
|
131
|
+
options: {
|
|
132
|
+
json: {
|
|
133
|
+
type: "boolean"
|
|
134
|
+
},
|
|
135
|
+
help: {
|
|
136
|
+
type: "boolean",
|
|
137
|
+
short: "h"
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}).values;
|
|
141
|
+
}(e);
|
|
142
|
+
if (t.json) {
|
|
143
|
+
r();
|
|
144
|
+
}
|
|
145
|
+
const n = i();
|
|
146
|
+
process.stdout.write(t.json ? `${JSON.stringify({
|
|
147
|
+
removed: n
|
|
148
|
+
})}\n` : `Removed ${n} stale sessions.\n`);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const b = [ ":started", ":done", ":failed" ];
|
|
152
|
+
|
|
153
|
+
async function convertToChromeTrace(e, t = {}) {
|
|
154
|
+
const n = new TraceConverter(t);
|
|
155
|
+
for await (const t of async function* toAsyncIterable$1(e) {
|
|
156
|
+
if (Symbol.asyncIterator in e) {
|
|
157
|
+
yield* e;
|
|
158
|
+
} else {
|
|
159
|
+
yield* e;
|
|
160
|
+
}
|
|
161
|
+
}(e)) {
|
|
162
|
+
n.add(t);
|
|
163
|
+
}
|
|
164
|
+
return n.toTraceFile();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
class TraceConverter {
|
|
168
|
+
traceEvents=[];
|
|
169
|
+
#e=new Map;
|
|
170
|
+
#t=1;
|
|
171
|
+
#n;
|
|
172
|
+
#s;
|
|
173
|
+
#o="0.1.0";
|
|
174
|
+
constructor(e = {}) {
|
|
175
|
+
this.#n = e.pid ?? 1;
|
|
176
|
+
this.#s = e.processName ?? "event log";
|
|
177
|
+
this.traceEvents.push({
|
|
178
|
+
ph: "M",
|
|
179
|
+
name: "process_name",
|
|
180
|
+
pid: this.#n,
|
|
181
|
+
args: {
|
|
182
|
+
name: this.#s
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
add(e) {
|
|
187
|
+
if ("root:init" === e._e) {
|
|
188
|
+
if ("string" == typeof e.version) {
|
|
189
|
+
this.#o = e.version;
|
|
190
|
+
}
|
|
191
|
+
if ("event log" === this.#s && "string" == typeof e.version) {
|
|
192
|
+
this.#s = `event log (v${e.version})`;
|
|
193
|
+
}
|
|
194
|
+
this.traceEvents.push({
|
|
195
|
+
ph: "M",
|
|
196
|
+
name: "process_name",
|
|
197
|
+
pid: this.#n,
|
|
198
|
+
args: {
|
|
199
|
+
name: this.#s
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const t = function splitEventName$2(e) {
|
|
205
|
+
const t = e.indexOf(":");
|
|
206
|
+
if (t < 1) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
category: e.slice(0, t),
|
|
211
|
+
name: e.slice(t + 1)
|
|
212
|
+
};
|
|
213
|
+
}(e._e);
|
|
214
|
+
if (!t) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const n = this.#r(t.category, "string" == typeof e._w ? e._w : void 0);
|
|
218
|
+
const s = function extractArgs$1(e) {
|
|
219
|
+
const t = {};
|
|
220
|
+
for (const n of Object.keys(e)) {
|
|
221
|
+
if ("_e" === n || "_t" === n || "_d" === n) {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
t[n] = e[n];
|
|
225
|
+
}
|
|
226
|
+
return Object.keys(t).length ? t : void 0;
|
|
227
|
+
}(e);
|
|
228
|
+
if ("number" == typeof e._d) {
|
|
229
|
+
this.traceEvents.push({
|
|
230
|
+
ph: "X",
|
|
231
|
+
name: stripSuffix$2(t.name),
|
|
232
|
+
cat: t.category,
|
|
233
|
+
pid: this.#n,
|
|
234
|
+
tid: n,
|
|
235
|
+
ts: Math.round(1e3 * (e._t - e._d)),
|
|
236
|
+
dur: Math.round(1e3 * e._d),
|
|
237
|
+
args: s
|
|
238
|
+
});
|
|
239
|
+
} else {
|
|
240
|
+
this.traceEvents.push({
|
|
241
|
+
ph: "i",
|
|
242
|
+
name: stripSuffix$2(t.name),
|
|
243
|
+
cat: t.category,
|
|
244
|
+
pid: this.#n,
|
|
245
|
+
tid: n,
|
|
246
|
+
ts: Math.round(1e3 * e._t),
|
|
247
|
+
s: e._e.endsWith(":progress") ? "t" : "g",
|
|
248
|
+
args: s
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
toTraceFile() {
|
|
253
|
+
return {
|
|
254
|
+
traceEvents: this.traceEvents,
|
|
255
|
+
metadata: {
|
|
256
|
+
source: "expo-event-log",
|
|
257
|
+
version: this.#o,
|
|
258
|
+
convertedAt: (new Date).toISOString()
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
#r(e, t) {
|
|
263
|
+
const n = t ? `${e}:${t}` : e;
|
|
264
|
+
let s = this.#e.get(n);
|
|
265
|
+
if (null == s) {
|
|
266
|
+
s = this.#t++;
|
|
267
|
+
this.#e.set(n, s);
|
|
268
|
+
this.traceEvents.push({
|
|
269
|
+
ph: "M",
|
|
270
|
+
name: "thread_name",
|
|
271
|
+
pid: this.#n,
|
|
272
|
+
tid: s,
|
|
273
|
+
args: {
|
|
274
|
+
name: t ? `${e} ${t}` : e
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
return s;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function stripSuffix$2(e) {
|
|
283
|
+
for (const t of b) {
|
|
284
|
+
if (e.endsWith(t)) {
|
|
285
|
+
return e.slice(0, -t.length);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return e;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const S = [ ":started", ":done", ":failed" ];
|
|
292
|
+
|
|
293
|
+
async function convertToOpenTelemetry(e, t = {}) {
|
|
294
|
+
const n = new OpenTelemetryConverter(t);
|
|
295
|
+
for await (const t of async function* toAsyncIterable(e) {
|
|
296
|
+
if (Symbol.asyncIterator in e) {
|
|
297
|
+
yield* e;
|
|
298
|
+
} else {
|
|
299
|
+
yield* e;
|
|
300
|
+
}
|
|
301
|
+
}(e)) {
|
|
302
|
+
n.add(t);
|
|
303
|
+
}
|
|
304
|
+
return n.toFile();
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
class OpenTelemetryConverter {
|
|
308
|
+
#i=m.randomBytes(16).toString("hex");
|
|
309
|
+
#a=createSpanId();
|
|
310
|
+
#c=[];
|
|
311
|
+
#l=[];
|
|
312
|
+
#s;
|
|
313
|
+
#o="0.1.0";
|
|
314
|
+
#p;
|
|
315
|
+
#u;
|
|
316
|
+
constructor(e) {
|
|
317
|
+
this.options = e;
|
|
318
|
+
this.#s = e.processName ?? "event log";
|
|
319
|
+
}
|
|
320
|
+
add(e) {
|
|
321
|
+
const t = unixNano(e._t);
|
|
322
|
+
this.#p = null == this.#p || BigInt(t) < BigInt(this.#p) ? t : this.#p;
|
|
323
|
+
this.#u = null == this.#u || BigInt(t) > BigInt(this.#u) ? t : this.#u;
|
|
324
|
+
if ("root:init" === e._e) {
|
|
325
|
+
if ("string" == typeof e.version) {
|
|
326
|
+
this.#o = e.version;
|
|
327
|
+
}
|
|
328
|
+
if ("event log" === this.#s && "string" == typeof e.version) {
|
|
329
|
+
this.#s = `event log (v${e.version})`;
|
|
330
|
+
}
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
if ("number" == typeof e._d) {
|
|
334
|
+
this.#c.push(this.#f(e));
|
|
335
|
+
} else {
|
|
336
|
+
this.#l.push(this.#d(e));
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
toFile() {
|
|
340
|
+
const e = this.#p ?? unixNano(Date.now());
|
|
341
|
+
const t = this.#u ?? e;
|
|
342
|
+
return {
|
|
343
|
+
resourceSpans: [ {
|
|
344
|
+
resource: {
|
|
345
|
+
attributes: attributes({
|
|
346
|
+
"service.name": this.#s,
|
|
347
|
+
"service.version": this.#o,
|
|
348
|
+
"process.pid": this.options.pid,
|
|
349
|
+
"telemetry.sdk.name": "@expo/event-log",
|
|
350
|
+
"telemetry.sdk.language": "nodejs"
|
|
351
|
+
})
|
|
352
|
+
},
|
|
353
|
+
scopeSpans: [ {
|
|
354
|
+
scope: {
|
|
355
|
+
name: "@expo/event-log"
|
|
356
|
+
},
|
|
357
|
+
spans: [ {
|
|
358
|
+
traceId: this.#i,
|
|
359
|
+
spanId: this.#a,
|
|
360
|
+
name: this.#s,
|
|
361
|
+
startTimeUnixNano: e,
|
|
362
|
+
endTimeUnixNano: t,
|
|
363
|
+
attributes: attributes({
|
|
364
|
+
"event_log.kind": "session"
|
|
365
|
+
}),
|
|
366
|
+
events: this.#l.length ? this.#l : void 0
|
|
367
|
+
}, ...this.#c ]
|
|
368
|
+
} ]
|
|
369
|
+
} ]
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
#f(e) {
|
|
373
|
+
const t = splitEventName$1(e._e);
|
|
374
|
+
const n = unixNano(e._t - e._d);
|
|
375
|
+
const s = unixNano(e._t);
|
|
376
|
+
return {
|
|
377
|
+
traceId: this.#i,
|
|
378
|
+
spanId: createSpanId(),
|
|
379
|
+
parentSpanId: this.#a,
|
|
380
|
+
name: t ? stripSuffix$1(t.name) : e._e,
|
|
381
|
+
startTimeUnixNano: n,
|
|
382
|
+
endTimeUnixNano: s,
|
|
383
|
+
attributes: eventAttributes(e, t)
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
#d(e) {
|
|
387
|
+
const t = splitEventName$1(e._e);
|
|
388
|
+
return {
|
|
389
|
+
timeUnixNano: unixNano(e._t),
|
|
390
|
+
name: t ? stripSuffix$1(t.name) : e._e,
|
|
391
|
+
attributes: eventAttributes(e, t)
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
function eventAttributes(e, t) {
|
|
397
|
+
const n = {
|
|
398
|
+
"event.name": e._e
|
|
399
|
+
};
|
|
400
|
+
if (t) {
|
|
401
|
+
n["event.category"] = t.category;
|
|
402
|
+
n["event.action"] = t.name;
|
|
403
|
+
}
|
|
404
|
+
if ("string" == typeof e._w) {
|
|
405
|
+
n["event.worker.id"] = e._w;
|
|
406
|
+
}
|
|
407
|
+
for (const t of Object.keys(e)) {
|
|
408
|
+
if ("_e" === t || "_t" === t || "_d" === t || "_w" === t) {
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
411
|
+
n[`event_log.${t}`] = e[t];
|
|
412
|
+
}
|
|
413
|
+
return attributes(n);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function attributes(e) {
|
|
417
|
+
const t = [];
|
|
418
|
+
for (const [n, s] of Object.entries(e)) {
|
|
419
|
+
const e = anyValue(s);
|
|
420
|
+
if (e) {
|
|
421
|
+
t.push({
|
|
422
|
+
key: n,
|
|
423
|
+
value: e
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return t;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
function anyValue(e) {
|
|
431
|
+
if ("string" == typeof e) {
|
|
432
|
+
return {
|
|
433
|
+
stringValue: e
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
if ("boolean" == typeof e) {
|
|
437
|
+
return {
|
|
438
|
+
boolValue: e
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
if ("number" == typeof e) {
|
|
442
|
+
if (!Number.isFinite(e)) {
|
|
443
|
+
return null;
|
|
444
|
+
}
|
|
445
|
+
return Number.isInteger(e) ? {
|
|
446
|
+
intValue: String(e)
|
|
447
|
+
} : {
|
|
448
|
+
doubleValue: e
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
if (Array.isArray(e)) {
|
|
452
|
+
return {
|
|
453
|
+
arrayValue: {
|
|
454
|
+
values: e.flatMap(e => {
|
|
455
|
+
const t = anyValue(e);
|
|
456
|
+
return t ? [ t ] : [];
|
|
457
|
+
})
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
if (e && "object" == typeof e) {
|
|
462
|
+
return {
|
|
463
|
+
kvlistValue: {
|
|
464
|
+
values: attributes(e)
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
return null;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
function createSpanId() {
|
|
472
|
+
return m.randomBytes(8).toString("hex");
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
function unixNano(e) {
|
|
476
|
+
return String(BigInt(Math.round(1e6 * e)));
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
function splitEventName$1(e) {
|
|
480
|
+
const t = e.indexOf(":");
|
|
481
|
+
if (t < 1) {
|
|
482
|
+
return null;
|
|
483
|
+
}
|
|
484
|
+
return {
|
|
485
|
+
category: e.slice(0, t),
|
|
486
|
+
name: e.slice(t + 1)
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
function stripSuffix$1(e) {
|
|
491
|
+
for (const t of S) {
|
|
492
|
+
if (e.endsWith(t)) {
|
|
493
|
+
return e.slice(0, -t.length);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
return e;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
async function runExportCli(e) {
|
|
500
|
+
if (parseHelp(e)) {
|
|
501
|
+
!function printExportHelp() {
|
|
502
|
+
process.stdout.write([ "Usage: event-log export [selector]", "", "Options:", " selector Match by PID, command, or cwd", " --input <file> Read JSONL events from a file", " -o, --output <file> Write output to a file", " --format <format> chrome-trace or opentelemetry", " --json Print JSON output", " --since <time> Duration, Unix time, or ISO date", " --filter <pattern> category[:kind], wildcards allowed", " --tail Follow live events after replaying history", " --timeout <duration> Stop tailing after an absolute duration", " Tail also stops after 30s without new events", "" ].join("\n"));
|
|
503
|
+
}();
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
const s = function parseExportOptions(e) {
|
|
507
|
+
const t = d({
|
|
508
|
+
args: e,
|
|
509
|
+
allowPositionals: !0,
|
|
510
|
+
options: {
|
|
511
|
+
...w,
|
|
512
|
+
input: {
|
|
513
|
+
type: "string"
|
|
514
|
+
},
|
|
515
|
+
output: {
|
|
516
|
+
type: "string",
|
|
517
|
+
short: "o"
|
|
518
|
+
},
|
|
519
|
+
format: {
|
|
520
|
+
type: "string"
|
|
521
|
+
},
|
|
522
|
+
json: {
|
|
523
|
+
type: "boolean"
|
|
524
|
+
},
|
|
525
|
+
timeout: {
|
|
526
|
+
type: "string"
|
|
527
|
+
},
|
|
528
|
+
help: {
|
|
529
|
+
type: "boolean",
|
|
530
|
+
short: "h"
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
});
|
|
534
|
+
const n = parseSharedTapOptions(t.values);
|
|
535
|
+
const s = function parseDuration(e) {
|
|
536
|
+
if (null == e || "" === e) {
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
const t = e.trim().toLowerCase();
|
|
540
|
+
if (!t) {
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
let n = 0;
|
|
544
|
+
let s = 0;
|
|
545
|
+
const o = /(\d+(?:\.\d+)?)\s*(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h)?/gy;
|
|
546
|
+
while (s < t.length) {
|
|
547
|
+
o.lastIndex = s;
|
|
548
|
+
const r = o.exec(t);
|
|
549
|
+
if (!r) {
|
|
550
|
+
throw new Error(`Invalid duration: ${e}`);
|
|
551
|
+
}
|
|
552
|
+
const i = Number(r[1]);
|
|
553
|
+
if (!Number.isFinite(i)) {
|
|
554
|
+
throw new Error(`Invalid duration: ${e}`);
|
|
555
|
+
}
|
|
556
|
+
n += i * durationUnitToMs(r[2] ?? "ms");
|
|
557
|
+
s = o.lastIndex;
|
|
558
|
+
while (" " === t[s] || "," === t[s]) {
|
|
559
|
+
s++;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return n;
|
|
563
|
+
}(t.values.timeout);
|
|
564
|
+
const o = t.values.format ?? "chrome-trace";
|
|
565
|
+
if (!function isExportFormat(e) {
|
|
566
|
+
return "chrome-trace" === e || "opentelemetry" === e;
|
|
567
|
+
}(o)) {
|
|
568
|
+
throw new Error(`Unsupported format: ${o}`);
|
|
569
|
+
}
|
|
570
|
+
if (t.positionals[0] && t.values.input) {
|
|
571
|
+
throw new Error("Use either a session selector or --input, not both");
|
|
572
|
+
}
|
|
573
|
+
if (null != s && !n.follow) {
|
|
574
|
+
throw new Error("Use --timeout only with --tail");
|
|
575
|
+
}
|
|
576
|
+
return {
|
|
577
|
+
selector: t.positionals[0],
|
|
578
|
+
inputFile: t.values.input,
|
|
579
|
+
output: t.values.output,
|
|
580
|
+
format: o,
|
|
581
|
+
since: n.since,
|
|
582
|
+
filter: n.filter,
|
|
583
|
+
follow: n.follow,
|
|
584
|
+
timeout: s,
|
|
585
|
+
idleTimeout: 3e4,
|
|
586
|
+
json: t.values.json ?? !1
|
|
587
|
+
};
|
|
588
|
+
}(e);
|
|
589
|
+
if (s.json) {
|
|
590
|
+
r();
|
|
591
|
+
}
|
|
592
|
+
let o;
|
|
593
|
+
let i;
|
|
594
|
+
let l;
|
|
595
|
+
if (s.selector) {
|
|
596
|
+
const e = await a(s.selector);
|
|
597
|
+
i = function formatSessionProcessName(e) {
|
|
598
|
+
return e.version ? `${e.command} (v${e.version}, PID ${e.pid})` : `${e.command} (PID ${e.pid})`;
|
|
599
|
+
}(e);
|
|
600
|
+
l = e.pid;
|
|
601
|
+
o = c(e.sessionDir, {
|
|
602
|
+
follow: s.follow,
|
|
603
|
+
timeout: s.timeout,
|
|
604
|
+
idleTimeout: s.follow ? s.idleTimeout : void 0
|
|
605
|
+
});
|
|
606
|
+
} else if (s.inputFile) {
|
|
607
|
+
o = async function* readJsonlFile(e) {
|
|
608
|
+
yield* readJsonlStream(u.createReadStream(e, {
|
|
609
|
+
encoding: "utf8"
|
|
610
|
+
}));
|
|
611
|
+
}(s.inputFile);
|
|
612
|
+
} else {
|
|
613
|
+
o = async function* readJsonlStdin() {
|
|
614
|
+
yield* readJsonlStream(process.stdin);
|
|
615
|
+
}();
|
|
616
|
+
}
|
|
617
|
+
const p = async function* filterEvents(e, s) {
|
|
618
|
+
const o = t(s.filter);
|
|
619
|
+
const r = n(s.since);
|
|
620
|
+
for await (const t of e) {
|
|
621
|
+
if (matchesTapOptions(t, r, o)) {
|
|
622
|
+
yield t;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}(o, s);
|
|
626
|
+
const f = "opentelemetry" === s.format ? await convertToOpenTelemetry(p, {
|
|
627
|
+
pid: l,
|
|
628
|
+
processName: i
|
|
629
|
+
}) : await convertToChromeTrace(p, {
|
|
630
|
+
pid: l,
|
|
631
|
+
processName: i
|
|
632
|
+
});
|
|
633
|
+
const m = JSON.stringify(f, null, 2);
|
|
634
|
+
if (s.output) {
|
|
635
|
+
u.writeFileSync(s.output, `${m}\n`);
|
|
636
|
+
} else {
|
|
637
|
+
process.stdout.write(`${m}\n`);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
function extractEventRegistry(e = {}) {
|
|
642
|
+
const t = e.project ?? function findTsconfig(e) {
|
|
643
|
+
let t = e;
|
|
644
|
+
while (1) {
|
|
645
|
+
const e = h.join(t, "tsconfig.json");
|
|
646
|
+
if (u.existsSync(e)) {
|
|
647
|
+
return e;
|
|
648
|
+
}
|
|
649
|
+
const n = h.dirname(t);
|
|
650
|
+
if (n === t) {
|
|
651
|
+
return null;
|
|
652
|
+
}
|
|
653
|
+
t = n;
|
|
654
|
+
}
|
|
655
|
+
}(process.cwd());
|
|
656
|
+
if (!t) {
|
|
657
|
+
throw new Error("Could not find tsconfig.json");
|
|
658
|
+
}
|
|
659
|
+
const n = g.readConfigFile(t, g.sys.readFile);
|
|
660
|
+
if (n.error) {
|
|
661
|
+
throw new Error(function formatDiagnostic(e) {
|
|
662
|
+
return g.flattenDiagnosticMessageText(e.messageText, "\n");
|
|
663
|
+
}(n.error));
|
|
664
|
+
}
|
|
665
|
+
const s = g.parseJsonConfigFileContent(n.config, g.sys, h.dirname(t));
|
|
666
|
+
const o = g.createProgram(s.fileNames, s.options);
|
|
667
|
+
const r = o.getTypeChecker();
|
|
668
|
+
const i = function findEventRegistry(e, t) {
|
|
669
|
+
const n = t.getAmbientModules().find(e => '"@expo/event-log"' === e.getName());
|
|
670
|
+
const s = n?.exports?.get("EventRegistry");
|
|
671
|
+
if (s) {
|
|
672
|
+
return t.getDeclaredTypeOfSymbol(s);
|
|
673
|
+
}
|
|
674
|
+
for (const n of e.getSourceFiles()) {
|
|
675
|
+
if (isEventLogEntrypoint(n.fileName)) {
|
|
676
|
+
const e = t.getSymbolAtLocation(n);
|
|
677
|
+
const s = e?.exports?.get("EventRegistry");
|
|
678
|
+
if (s) {
|
|
679
|
+
return t.getDeclaredTypeOfSymbol(s);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
for (const n of e.getSourceFiles()) {
|
|
684
|
+
if (!/[\\/](@expo[\\/]event-log|event-log)[\\/]/.test(n.fileName)) {
|
|
685
|
+
continue;
|
|
686
|
+
}
|
|
687
|
+
let e;
|
|
688
|
+
n.forEachChild(function visit(t) {
|
|
689
|
+
if (g.isInterfaceDeclaration(t) && "EventRegistry" === t.name.text) {
|
|
690
|
+
e = t;
|
|
691
|
+
}
|
|
692
|
+
t.forEachChild(visit);
|
|
693
|
+
});
|
|
694
|
+
if (e) {
|
|
695
|
+
const n = t.getSymbolAtLocation(e.name);
|
|
696
|
+
if (n) {
|
|
697
|
+
return t.getDeclaredTypeOfSymbol(n);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
return null;
|
|
702
|
+
}(o, r);
|
|
703
|
+
if (!i) {
|
|
704
|
+
throw new Error("Could not resolve EventRegistry");
|
|
705
|
+
}
|
|
706
|
+
const a = i.getProperties().map(e => function serializeRegistryEntry(e, t) {
|
|
707
|
+
const n = e.getName().replace(/^"|"$/g, "");
|
|
708
|
+
const s = e.valueDeclaration ?? e.declarations?.[0];
|
|
709
|
+
const o = s ? t.getTypeOfSymbolAtLocation(e, s) : void 0;
|
|
710
|
+
const r = {};
|
|
711
|
+
const i = [];
|
|
712
|
+
for (const e of o?.getProperties() ?? []) {
|
|
713
|
+
const n = e.valueDeclaration ?? e.declarations?.[0];
|
|
714
|
+
if (!n) {
|
|
715
|
+
continue;
|
|
716
|
+
}
|
|
717
|
+
if (0 !== (e.flags & g.SymbolFlags.Optional)) {
|
|
718
|
+
i.push(e.getName());
|
|
719
|
+
}
|
|
720
|
+
r[e.getName()] = t.typeToString(t.getTypeOfSymbolAtLocation(e, n));
|
|
721
|
+
}
|
|
722
|
+
const a = n.indexOf(":");
|
|
723
|
+
return {
|
|
724
|
+
key: n,
|
|
725
|
+
category: a > -1 ? n.slice(0, a) : "",
|
|
726
|
+
name: a > -1 ? n.slice(a + 1) : n,
|
|
727
|
+
fields: r,
|
|
728
|
+
optionalFields: i
|
|
729
|
+
};
|
|
730
|
+
}(e, r)).sort((e, t) => e.key.localeCompare(t.key));
|
|
731
|
+
return "json" === e.format ? JSON.stringify(a, null, 2) : function formatDts(e) {
|
|
732
|
+
const t = [ "// Auto-generated by @expo/event-log extract", "// Do not edit manually.", "", "declare module '@expo/event-log' {", " interface EventRegistry {" ];
|
|
733
|
+
for (const n of e) {
|
|
734
|
+
t.push(` '${n.key}': {`);
|
|
735
|
+
for (const [e, s] of Object.entries(n.fields)) {
|
|
736
|
+
const o = n.optionalFields.includes(e) ? "?" : "";
|
|
737
|
+
t.push(` ${e}${o}: ${s};`);
|
|
738
|
+
}
|
|
739
|
+
t.push(" };");
|
|
740
|
+
}
|
|
741
|
+
t.push(" }", "}");
|
|
742
|
+
return t.join("\n");
|
|
743
|
+
}(a);
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
function runExtractCli(e) {
|
|
747
|
+
if (parseHelp(e)) {
|
|
748
|
+
!function printExtractHelp() {
|
|
749
|
+
process.stdout.write([ "Usage: event-log extract", "", "Options:", " -p, --project <file> tsconfig.json path", " -o, --output <file> Write output to a file", " --format <format> dts or json", " --json Print JSON schema", "" ].join("\n"));
|
|
750
|
+
}();
|
|
751
|
+
return;
|
|
752
|
+
}
|
|
753
|
+
const t = d({
|
|
754
|
+
args: e,
|
|
755
|
+
options: {
|
|
756
|
+
format: {
|
|
757
|
+
type: "string"
|
|
758
|
+
},
|
|
759
|
+
json: {
|
|
760
|
+
type: "boolean"
|
|
761
|
+
},
|
|
762
|
+
output: {
|
|
763
|
+
type: "string",
|
|
764
|
+
short: "o"
|
|
765
|
+
},
|
|
766
|
+
project: {
|
|
767
|
+
type: "string",
|
|
768
|
+
short: "p"
|
|
769
|
+
},
|
|
770
|
+
help: {
|
|
771
|
+
type: "boolean",
|
|
772
|
+
short: "h"
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
});
|
|
776
|
+
if (t.values.json && "dts" === t.values.format) {
|
|
777
|
+
throw new Error("Use either --json or --format dts, not both");
|
|
778
|
+
}
|
|
779
|
+
if (t.values.json) {
|
|
780
|
+
r();
|
|
781
|
+
}
|
|
782
|
+
const n = t.values.json ? "json" : t.values.format ?? "dts";
|
|
783
|
+
if ("dts" !== n && "json" !== n) {
|
|
784
|
+
throw new Error(`Unsupported format: ${n}`);
|
|
785
|
+
}
|
|
786
|
+
const s = {
|
|
787
|
+
format: n,
|
|
788
|
+
output: t.values.output,
|
|
789
|
+
project: t.values.project
|
|
790
|
+
};
|
|
791
|
+
const o = extractEventRegistry(s);
|
|
792
|
+
if (s.output) {
|
|
793
|
+
u.writeFileSync(s.output, `${o}\n`);
|
|
794
|
+
} else {
|
|
795
|
+
process.stdout.write(`${o}\n`);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
function isEventLogEntrypoint(e) {
|
|
800
|
+
return /(?:^|[\\/])(?:src[\\/]index\.ts|dist[\\/]event-log\.d\.ts)$/.test(e);
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
const T = [ ":started", ":done", ":failed" ];
|
|
804
|
+
|
|
805
|
+
class InspectTrace {
|
|
806
|
+
events=[];
|
|
807
|
+
#e=new Map;
|
|
808
|
+
#t=1;
|
|
809
|
+
#n;
|
|
810
|
+
#s;
|
|
811
|
+
constructor(e) {
|
|
812
|
+
this.#n = e.pid ?? 1;
|
|
813
|
+
this.#s = e.processName;
|
|
814
|
+
this.#m({
|
|
815
|
+
ph: "M",
|
|
816
|
+
name: "process_name",
|
|
817
|
+
pid: this.#n,
|
|
818
|
+
args: {
|
|
819
|
+
name: this.#s
|
|
820
|
+
}
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
add(e) {
|
|
824
|
+
const t = this.events.length;
|
|
825
|
+
if ("root:init" === e._e) {
|
|
826
|
+
this.#m({
|
|
827
|
+
ph: "M",
|
|
828
|
+
name: "process_name",
|
|
829
|
+
pid: this.#n,
|
|
830
|
+
args: {
|
|
831
|
+
name: this.#s
|
|
832
|
+
}
|
|
833
|
+
});
|
|
834
|
+
return this.events.slice(t);
|
|
835
|
+
}
|
|
836
|
+
const n = function splitEventName(e) {
|
|
837
|
+
const t = e.indexOf(":");
|
|
838
|
+
if (t < 1) {
|
|
839
|
+
return null;
|
|
840
|
+
}
|
|
841
|
+
return {
|
|
842
|
+
category: e.slice(0, t),
|
|
843
|
+
name: e.slice(t + 1)
|
|
844
|
+
};
|
|
845
|
+
}(e._e);
|
|
846
|
+
if (!n) {
|
|
847
|
+
return [];
|
|
848
|
+
}
|
|
849
|
+
const s = this.#r(n.category, "string" == typeof e._w ? e._w : void 0);
|
|
850
|
+
const o = function extractArgs(e) {
|
|
851
|
+
const t = {};
|
|
852
|
+
for (const n of Object.keys(e)) {
|
|
853
|
+
if ("_e" === n || "_t" === n || "_d" === n) {
|
|
854
|
+
continue;
|
|
855
|
+
}
|
|
856
|
+
t[n] = e[n];
|
|
857
|
+
}
|
|
858
|
+
return Object.keys(t).length ? t : void 0;
|
|
859
|
+
}(e);
|
|
860
|
+
if ("number" == typeof e._d) {
|
|
861
|
+
this.#m({
|
|
862
|
+
ph: "X",
|
|
863
|
+
name: stripSuffix(n.name),
|
|
864
|
+
cat: n.category,
|
|
865
|
+
pid: this.#n,
|
|
866
|
+
tid: s,
|
|
867
|
+
ts: Math.round(1e3 * (e._t - e._d)),
|
|
868
|
+
dur: Math.round(1e3 * e._d),
|
|
869
|
+
args: o
|
|
870
|
+
});
|
|
871
|
+
} else {
|
|
872
|
+
this.#m({
|
|
873
|
+
ph: "i",
|
|
874
|
+
name: stripSuffix(n.name),
|
|
875
|
+
cat: n.category,
|
|
876
|
+
pid: this.#n,
|
|
877
|
+
tid: s,
|
|
878
|
+
ts: Math.round(1e3 * e._t),
|
|
879
|
+
s: e._e.endsWith(":progress") ? "t" : "g",
|
|
880
|
+
args: o
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
return this.events.slice(t);
|
|
884
|
+
}
|
|
885
|
+
#r(e, t) {
|
|
886
|
+
const n = t ? `${e}:${t}` : e;
|
|
887
|
+
let s = this.#e.get(n);
|
|
888
|
+
if (null == s) {
|
|
889
|
+
s = this.#t++;
|
|
890
|
+
this.#e.set(n, s);
|
|
891
|
+
this.#m({
|
|
892
|
+
ph: "M",
|
|
893
|
+
name: "thread_name",
|
|
894
|
+
pid: this.#n,
|
|
895
|
+
tid: s,
|
|
896
|
+
args: {
|
|
897
|
+
name: t ? `${e} ${t}` : e
|
|
898
|
+
}
|
|
899
|
+
});
|
|
900
|
+
}
|
|
901
|
+
return s;
|
|
902
|
+
}
|
|
903
|
+
#m(e) {
|
|
904
|
+
this.events.push(e);
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
function stripSuffix(e) {
|
|
909
|
+
for (const t of T) {
|
|
910
|
+
if (e.endsWith(t)) {
|
|
911
|
+
return e.slice(0, -t.length);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
return e;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
function runInspectCli(e) {
|
|
918
|
+
if (parseHelp(function argsBeforeSeparator(e) {
|
|
919
|
+
const t = e.indexOf("--");
|
|
920
|
+
return t >= 0 ? e.slice(0, t) : e;
|
|
921
|
+
}(e))) {
|
|
922
|
+
!function printInspectHelp() {
|
|
923
|
+
process.stdout.write([ "Usage: event-log inspect [options] -- <command> [args...]", "", "Options:", " --port <port> Inspector port, defaults to 9229", " --host <host> Inspector host, defaults to 127.0.0.1", " --wait Wait for a DevTools client before spawning", " --linger <seconds> Keep inspector open after child exits", " --no-banner Do not print inspector connection info", "" ].join("\n"));
|
|
924
|
+
}();
|
|
925
|
+
return Promise.resolve(0);
|
|
926
|
+
}
|
|
927
|
+
return async function runInspectSidecar(e) {
|
|
928
|
+
const t = e.port ?? 9229;
|
|
929
|
+
const n = e.host ?? "127.0.0.1";
|
|
930
|
+
const s = e.linger ?? 5;
|
|
931
|
+
const o = new InspectTrace({
|
|
932
|
+
processName: e.command
|
|
933
|
+
});
|
|
934
|
+
const r = await CdpTraceServer.listen({
|
|
935
|
+
host: n,
|
|
936
|
+
port: t,
|
|
937
|
+
command: e.command
|
|
938
|
+
});
|
|
939
|
+
if (!1 !== e.banner) {
|
|
940
|
+
process.stderr.write(`Debugger listening on ${r.url}\nOpen chrome://inspect to connect.\n`);
|
|
941
|
+
}
|
|
942
|
+
if (e.wait) {
|
|
943
|
+
await r.waitForClient();
|
|
944
|
+
}
|
|
945
|
+
const i = function spawnInspectedProcess(e, t) {
|
|
946
|
+
const n = v(e, t, {
|
|
947
|
+
stdio: [ "inherit", "inherit", "inherit", "pipe" ],
|
|
948
|
+
env: {
|
|
949
|
+
...process.env,
|
|
950
|
+
[l]: "3"
|
|
951
|
+
}
|
|
952
|
+
});
|
|
953
|
+
return {
|
|
954
|
+
process: n,
|
|
955
|
+
eventStream: n.stdio[3]
|
|
956
|
+
};
|
|
957
|
+
}(e.command, e.args);
|
|
958
|
+
const forward = e => i.process.kill(e);
|
|
959
|
+
process.once("SIGINT", () => forward("SIGINT"));
|
|
960
|
+
process.once("SIGTERM", () => forward("SIGTERM"));
|
|
961
|
+
process.once("SIGHUP", () => forward("SIGHUP"));
|
|
962
|
+
const a = function readEvents(e, t) {
|
|
963
|
+
const n = f({
|
|
964
|
+
input: e
|
|
965
|
+
});
|
|
966
|
+
n.on("line", e => {
|
|
967
|
+
try {
|
|
968
|
+
t(JSON.parse(e));
|
|
969
|
+
} catch {}
|
|
970
|
+
});
|
|
971
|
+
return new Promise(e => n.on("close", e));
|
|
972
|
+
}(i.eventStream, e => {
|
|
973
|
+
r.add(o.add(e));
|
|
974
|
+
});
|
|
975
|
+
const c = await function waitForChild(e) {
|
|
976
|
+
return new Promise(t => {
|
|
977
|
+
e.on("exit", (e, n) => {
|
|
978
|
+
if ("number" == typeof e) {
|
|
979
|
+
t(e);
|
|
980
|
+
} else {
|
|
981
|
+
t(n ? 128 : 1);
|
|
982
|
+
}
|
|
983
|
+
});
|
|
984
|
+
});
|
|
985
|
+
}(i.process);
|
|
986
|
+
await a;
|
|
987
|
+
r.add(o.events);
|
|
988
|
+
if (s > 0) {
|
|
989
|
+
await new Promise(e => setTimeout(e, 1e3 * s));
|
|
990
|
+
}
|
|
991
|
+
await r.close();
|
|
992
|
+
return c;
|
|
993
|
+
}(function parseInspectOptions(e) {
|
|
994
|
+
const t = e.indexOf("--");
|
|
995
|
+
const n = t >= 0 ? e.slice(0, t) : [];
|
|
996
|
+
const s = t >= 0 ? e.slice(t + 1) : e;
|
|
997
|
+
const o = d({
|
|
998
|
+
args: n,
|
|
999
|
+
options: {
|
|
1000
|
+
port: {
|
|
1001
|
+
type: "string"
|
|
1002
|
+
},
|
|
1003
|
+
host: {
|
|
1004
|
+
type: "string"
|
|
1005
|
+
},
|
|
1006
|
+
wait: {
|
|
1007
|
+
type: "boolean"
|
|
1008
|
+
},
|
|
1009
|
+
linger: {
|
|
1010
|
+
type: "string"
|
|
1011
|
+
},
|
|
1012
|
+
help: {
|
|
1013
|
+
type: "boolean",
|
|
1014
|
+
short: "h"
|
|
1015
|
+
},
|
|
1016
|
+
"no-banner": {
|
|
1017
|
+
type: "boolean"
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
});
|
|
1021
|
+
if (!s.length) {
|
|
1022
|
+
throw new Error("inspect requires -- <command> [args...]");
|
|
1023
|
+
}
|
|
1024
|
+
return {
|
|
1025
|
+
port: parsePort(o.values.port) ?? 9229,
|
|
1026
|
+
host: o.values.host ?? "127.0.0.1",
|
|
1027
|
+
wait: o.values.wait ?? !1,
|
|
1028
|
+
linger: parseNonNegativeNumber(o.values.linger, "linger") ?? 5,
|
|
1029
|
+
banner: o.values["no-banner"] ? !1 : !0,
|
|
1030
|
+
command: s[0],
|
|
1031
|
+
args: s.slice(1)
|
|
1032
|
+
};
|
|
1033
|
+
}(e));
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
class CdpTraceServer {
|
|
1037
|
+
id=m.randomUUID();
|
|
1038
|
+
#h;
|
|
1039
|
+
#g=new Set;
|
|
1040
|
+
#v=new Map;
|
|
1041
|
+
#y=[];
|
|
1042
|
+
#w=[];
|
|
1043
|
+
#b=!1;
|
|
1044
|
+
constructor(e, t, n, s) {
|
|
1045
|
+
this.host = t;
|
|
1046
|
+
this.port = n;
|
|
1047
|
+
this.command = s;
|
|
1048
|
+
this.#h = e;
|
|
1049
|
+
}
|
|
1050
|
+
static listen(e) {
|
|
1051
|
+
const t = y.createServer();
|
|
1052
|
+
const n = new CdpTraceServer(t, e.host, e.port, e.command);
|
|
1053
|
+
t.on("request", (e, t) => n.#S(e, t));
|
|
1054
|
+
t.on("upgrade", (e, t) => n.#T(e, t));
|
|
1055
|
+
return new Promise((s, o) => {
|
|
1056
|
+
t.once("error", o);
|
|
1057
|
+
t.listen(e.port, e.host, () => {
|
|
1058
|
+
t.off("error", o);
|
|
1059
|
+
const e = t.address();
|
|
1060
|
+
if (e && "object" == typeof e) {
|
|
1061
|
+
n.port = e.port;
|
|
1062
|
+
}
|
|
1063
|
+
s(n);
|
|
1064
|
+
});
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
get url() {
|
|
1068
|
+
return `ws://${this.host}:${this.port}/${this.id}`;
|
|
1069
|
+
}
|
|
1070
|
+
add(e) {
|
|
1071
|
+
if (!e.length) {
|
|
1072
|
+
return;
|
|
1073
|
+
}
|
|
1074
|
+
if (!this.#b || !this.#g.size) {
|
|
1075
|
+
this.#y.push(...e);
|
|
1076
|
+
if (this.#y.length > 1e4) {
|
|
1077
|
+
this.#y.splice(0, this.#y.length - 1e4);
|
|
1078
|
+
}
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
this.#N("Tracing.dataCollected", {
|
|
1082
|
+
value: e
|
|
1083
|
+
});
|
|
1084
|
+
}
|
|
1085
|
+
waitForClient() {
|
|
1086
|
+
if (this.#g.size) {
|
|
1087
|
+
return Promise.resolve();
|
|
1088
|
+
}
|
|
1089
|
+
return new Promise(e => this.#w.push(e));
|
|
1090
|
+
}
|
|
1091
|
+
close() {
|
|
1092
|
+
for (const e of this.#g) {
|
|
1093
|
+
e.destroy();
|
|
1094
|
+
}
|
|
1095
|
+
return new Promise(e => this.#h.close(() => e()));
|
|
1096
|
+
}
|
|
1097
|
+
#S(e, t) {
|
|
1098
|
+
const n = {
|
|
1099
|
+
id: this.id,
|
|
1100
|
+
type: "node",
|
|
1101
|
+
title: this.command,
|
|
1102
|
+
description: "@expo/event-log inspect",
|
|
1103
|
+
webSocketDebuggerUrl: this.url,
|
|
1104
|
+
devtoolsFrontendUrl: `/devtools/inspector.html?ws=${this.host}:${this.port}/${this.id}`
|
|
1105
|
+
};
|
|
1106
|
+
t.setHeader("content-type", "application/json");
|
|
1107
|
+
t.end(JSON.stringify([ n ]));
|
|
1108
|
+
}
|
|
1109
|
+
#T(e, t) {
|
|
1110
|
+
const n = e.headers["sec-websocket-key"];
|
|
1111
|
+
if ("string" != typeof n) {
|
|
1112
|
+
t.destroy();
|
|
1113
|
+
return;
|
|
1114
|
+
}
|
|
1115
|
+
const s = m.createHash("sha1").update(`${n}258EAFA5-E914-47DA-95CA-C5AB0DC85B11`).digest("base64");
|
|
1116
|
+
t.write([ "HTTP/1.1 101 Switching Protocols", "Upgrade: websocket", "Connection: Upgrade", `Sec-WebSocket-Accept: ${s}`, "", "" ].join("\r\n"));
|
|
1117
|
+
this.#g.add(t);
|
|
1118
|
+
for (const e of this.#w.splice(0)) {
|
|
1119
|
+
e();
|
|
1120
|
+
}
|
|
1121
|
+
t.on("data", e => this.#x(t, Buffer.from(e)));
|
|
1122
|
+
t.on("close", () => {
|
|
1123
|
+
this.#g.delete(t);
|
|
1124
|
+
this.#v.delete(t);
|
|
1125
|
+
});
|
|
1126
|
+
t.on("error", () => {
|
|
1127
|
+
this.#g.delete(t);
|
|
1128
|
+
this.#v.delete(t);
|
|
1129
|
+
});
|
|
1130
|
+
}
|
|
1131
|
+
#x(e, t) {
|
|
1132
|
+
const n = this.#v.get(e);
|
|
1133
|
+
const s = n ? Buffer.concat([ n, t ]) : t;
|
|
1134
|
+
let o = 0;
|
|
1135
|
+
while (o < s.length) {
|
|
1136
|
+
const t = readFrame(s, o);
|
|
1137
|
+
if (!t) {
|
|
1138
|
+
this.#v.set(e, s.subarray(o));
|
|
1139
|
+
return;
|
|
1140
|
+
}
|
|
1141
|
+
o = t.nextOffset;
|
|
1142
|
+
if (8 === t.opcode) {
|
|
1143
|
+
e.end();
|
|
1144
|
+
} else if (1 === t.opcode) {
|
|
1145
|
+
this.#E(e, t.payload.toString("utf8"));
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
this.#v.delete(e);
|
|
1149
|
+
}
|
|
1150
|
+
#E(e, t) {
|
|
1151
|
+
let n;
|
|
1152
|
+
try {
|
|
1153
|
+
n = JSON.parse(t);
|
|
1154
|
+
} catch {
|
|
1155
|
+
return;
|
|
1156
|
+
}
|
|
1157
|
+
if ("Tracing.start" === n.method) {
|
|
1158
|
+
this.#b = !0;
|
|
1159
|
+
this.#I(e, n.id);
|
|
1160
|
+
if (this.#y.length) {
|
|
1161
|
+
this.#N("Tracing.dataCollected", {
|
|
1162
|
+
value: this.#y.splice(0)
|
|
1163
|
+
});
|
|
1164
|
+
}
|
|
1165
|
+
} else if ("Tracing.end" === n.method) {
|
|
1166
|
+
this.#b = !1;
|
|
1167
|
+
this.#I(e, n.id);
|
|
1168
|
+
this.#N("Tracing.tracingComplete", {});
|
|
1169
|
+
} else {
|
|
1170
|
+
this.#I(e, n.id);
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
#I(e, t) {
|
|
1174
|
+
if (null != t) {
|
|
1175
|
+
writeFrame(e, JSON.stringify({
|
|
1176
|
+
id: t,
|
|
1177
|
+
result: {}
|
|
1178
|
+
}));
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
#N(e, t) {
|
|
1182
|
+
const n = JSON.stringify({
|
|
1183
|
+
method: e,
|
|
1184
|
+
params: t
|
|
1185
|
+
});
|
|
1186
|
+
for (const e of this.#g) {
|
|
1187
|
+
writeFrame(e, n);
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
function readFrame(e, t) {
|
|
1193
|
+
if (t + 2 > e.length) {
|
|
1194
|
+
return null;
|
|
1195
|
+
}
|
|
1196
|
+
const n = e[t + 1];
|
|
1197
|
+
const s = 15 & e[t];
|
|
1198
|
+
const o = !!(128 & n);
|
|
1199
|
+
let r = 127 & n;
|
|
1200
|
+
let i = t + 2;
|
|
1201
|
+
if (126 === r) {
|
|
1202
|
+
if (i + 2 > e.length) {
|
|
1203
|
+
return null;
|
|
1204
|
+
}
|
|
1205
|
+
r = e.readUInt16BE(i);
|
|
1206
|
+
i += 2;
|
|
1207
|
+
} else if (127 === r) {
|
|
1208
|
+
if (i + 8 > e.length) {
|
|
1209
|
+
return null;
|
|
1210
|
+
}
|
|
1211
|
+
const t = e.readBigUInt64BE(i);
|
|
1212
|
+
if (t > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
1213
|
+
return null;
|
|
1214
|
+
}
|
|
1215
|
+
r = Number(t);
|
|
1216
|
+
i += 8;
|
|
1217
|
+
}
|
|
1218
|
+
const a = i;
|
|
1219
|
+
if (o) {
|
|
1220
|
+
i += 4;
|
|
1221
|
+
}
|
|
1222
|
+
if (i + r > e.length) {
|
|
1223
|
+
return null;
|
|
1224
|
+
}
|
|
1225
|
+
const c = Buffer.from(e.subarray(i, i + r));
|
|
1226
|
+
if (o) {
|
|
1227
|
+
const t = e.subarray(a, a + 4);
|
|
1228
|
+
for (let e = 0; e < c.length; e++) {
|
|
1229
|
+
c[e] ^= t[e % 4];
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
return {
|
|
1233
|
+
opcode: s,
|
|
1234
|
+
payload: c,
|
|
1235
|
+
nextOffset: i + r
|
|
1236
|
+
};
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
function writeFrame(e, t) {
|
|
1240
|
+
const n = Buffer.from(t);
|
|
1241
|
+
let s;
|
|
1242
|
+
if (n.length < 126) {
|
|
1243
|
+
s = Buffer.from([ 129, n.length ]);
|
|
1244
|
+
} else if (n.length < 65536) {
|
|
1245
|
+
s = Buffer.allocUnsafe(4);
|
|
1246
|
+
s[0] = 129;
|
|
1247
|
+
s[1] = 126;
|
|
1248
|
+
s.writeUInt16BE(n.length, 2);
|
|
1249
|
+
} else {
|
|
1250
|
+
s = Buffer.allocUnsafe(10);
|
|
1251
|
+
s[0] = 129;
|
|
1252
|
+
s[1] = 127;
|
|
1253
|
+
s.writeBigUInt64BE(BigInt(n.length), 2);
|
|
1254
|
+
}
|
|
1255
|
+
e.write(Buffer.concat([ s, n ]));
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
function escapeTsv(e) {
|
|
1259
|
+
return String(e).replace(/\\/g, "\\\\").replace(/\t/g, "\\t").replace(/\r/g, "\\r").replace(/\n/g, "\\n");
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
async function runTapCli(e) {
|
|
1263
|
+
if (parseHelp(e)) {
|
|
1264
|
+
!function printTapHelp() {
|
|
1265
|
+
process.stdout.write([ "Usage: event-log tap [selector]", "", "Options:", " selector Match by PID, command, or cwd", " --since <time> Duration, Unix time, or ISO date", " --filter <pattern> category[:kind], wildcards allowed", " --format pretty Print a readable line per event", " --tail Follow live events after replaying history", "" ].join("\n"));
|
|
1266
|
+
}();
|
|
1267
|
+
return;
|
|
1268
|
+
}
|
|
1269
|
+
const t = function parseTapOptions(e) {
|
|
1270
|
+
const t = d({
|
|
1271
|
+
args: e,
|
|
1272
|
+
allowPositionals: !0,
|
|
1273
|
+
options: {
|
|
1274
|
+
...w,
|
|
1275
|
+
format: {
|
|
1276
|
+
type: "string"
|
|
1277
|
+
},
|
|
1278
|
+
json: {
|
|
1279
|
+
type: "boolean"
|
|
1280
|
+
},
|
|
1281
|
+
help: {
|
|
1282
|
+
type: "boolean",
|
|
1283
|
+
short: "h"
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
});
|
|
1287
|
+
const n = parseSharedTapOptions(t.values);
|
|
1288
|
+
if (t.values.json && "pretty" === t.values.format) {
|
|
1289
|
+
throw new Error("Use either --json or --format pretty, not both");
|
|
1290
|
+
}
|
|
1291
|
+
return {
|
|
1292
|
+
selector: t.positionals[0],
|
|
1293
|
+
since: n.since,
|
|
1294
|
+
follow: n.follow,
|
|
1295
|
+
filter: n.filter,
|
|
1296
|
+
json: t.values.json ?? !1,
|
|
1297
|
+
pretty: t.values.json ? !1 : "pretty" === t.values.format
|
|
1298
|
+
};
|
|
1299
|
+
}(e);
|
|
1300
|
+
if (t.json) {
|
|
1301
|
+
r();
|
|
1302
|
+
}
|
|
1303
|
+
const n = await a(t.selector);
|
|
1304
|
+
for await (const e of c(n.sessionDir, t)) {
|
|
1305
|
+
if (t.pretty) {
|
|
1306
|
+
process.stdout.write(`${new Date(e._t).toISOString()} ${e._e} ${JSON.stringify(e)}\n`);
|
|
1307
|
+
} else {
|
|
1308
|
+
process.stdout.write(`${JSON.stringify(e)}\n`);
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
async function main(e = process.argv.slice(2)) {
|
|
1314
|
+
const [t, ...n] = e;
|
|
1315
|
+
if (!t || "--help" === t || "-h" === t) {
|
|
1316
|
+
!function printHelp() {
|
|
1317
|
+
process.stdout.write([ "Usage: event-log <command>", "", "Commands:", " ps [selector] List sessions; selector matches PID, command, or cwd", " --json", "", " tap [selector] Replay session events as JSONL", " --since <time> --filter <category[:kind]> --tail --format pretty", "", " export [selector] Export events to Chrome Trace or OTLP JSON", " --input <file> -o <file> --format <format> --filter <category[:kind]> --tail", "", " inspect [options] -- <cmd> Run a command with inspector sidecar", " --port <port> --host <host> --wait --linger <seconds> --no-banner", "", " extract Extract merged EventRegistry schema", " --project <file> --output <file> --format dts|json --json", "", " clean Remove stale sessions", " --json", "", "Run event-log <command> --help for full command help.", "" ].join("\n"));
|
|
1318
|
+
}();
|
|
1319
|
+
return 0;
|
|
1320
|
+
}
|
|
1321
|
+
switch (t) {
|
|
1322
|
+
case "extract":
|
|
1323
|
+
runExtractCli(n);
|
|
1324
|
+
return 0;
|
|
1325
|
+
|
|
1326
|
+
case "ps":
|
|
1327
|
+
if (parseHelp(n)) {
|
|
1328
|
+
!function printPsHelp() {
|
|
1329
|
+
process.stdout.write([ "Usage: event-log ps [selector]", "", "Options:", " selector Match by PID, command, or cwd", " --json Print sessions as JSON", "" ].join("\n"));
|
|
1330
|
+
}();
|
|
1331
|
+
return 0;
|
|
1332
|
+
}
|
|
1333
|
+
await async function runPsCli(e = []) {
|
|
1334
|
+
const t = d({
|
|
1335
|
+
args: e,
|
|
1336
|
+
allowPositionals: !0,
|
|
1337
|
+
options: {
|
|
1338
|
+
json: {
|
|
1339
|
+
type: "boolean"
|
|
1340
|
+
},
|
|
1341
|
+
help: {
|
|
1342
|
+
type: "boolean",
|
|
1343
|
+
short: "h"
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
});
|
|
1347
|
+
if (t.values.json) {
|
|
1348
|
+
r();
|
|
1349
|
+
}
|
|
1350
|
+
const n = await p({
|
|
1351
|
+
selector: t.positionals[0]
|
|
1352
|
+
});
|
|
1353
|
+
if (t.values.json) {
|
|
1354
|
+
process.stdout.write(`${JSON.stringify(n, null, 2)}\n`);
|
|
1355
|
+
return;
|
|
1356
|
+
}
|
|
1357
|
+
process.stdout.write("PID\tSTATUS\tSTARTED\tCOMMAND\tCWD\n");
|
|
1358
|
+
for (const e of n) {
|
|
1359
|
+
process.stdout.write(`${escapeTsv(e.pid)}\t${escapeTsv(e.alive ? "alive" : "exited")}\t${escapeTsv(new Date(e.startedAt).toISOString())}\t${escapeTsv(e.command)}\t${escapeTsv(e.cwd)}\n`);
|
|
1360
|
+
}
|
|
1361
|
+
}(n);
|
|
1362
|
+
return 0;
|
|
1363
|
+
|
|
1364
|
+
case "tap":
|
|
1365
|
+
await runTapCli(n);
|
|
1366
|
+
return 0;
|
|
1367
|
+
|
|
1368
|
+
case "clean":
|
|
1369
|
+
if (parseHelp(n)) {
|
|
1370
|
+
!function printCleanHelp() {
|
|
1371
|
+
process.stdout.write([ "Usage: event-log clean", "", "Options:", " --json", "" ].join("\n"));
|
|
1372
|
+
}();
|
|
1373
|
+
return 0;
|
|
1374
|
+
}
|
|
1375
|
+
runCleanCli(n);
|
|
1376
|
+
return 0;
|
|
1377
|
+
|
|
1378
|
+
case "export":
|
|
1379
|
+
await runExportCli(n);
|
|
1380
|
+
return 0;
|
|
1381
|
+
|
|
1382
|
+
case "inspect":
|
|
1383
|
+
return runInspectCli(n);
|
|
1384
|
+
|
|
1385
|
+
default:
|
|
1386
|
+
throw new Error(`Unknown command: ${t}`);
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
if (function isCliEntrypoint() {
|
|
1391
|
+
try {
|
|
1392
|
+
return process.argv[1] === e(import.meta.url);
|
|
1393
|
+
} catch {
|
|
1394
|
+
return !1;
|
|
1395
|
+
}
|
|
1396
|
+
}()) {
|
|
1397
|
+
main().then(e => {
|
|
1398
|
+
process.exitCode = e;
|
|
1399
|
+
}).catch(e => {
|
|
1400
|
+
process.stderr.write(`${e instanceof Error ? e.message : String(e)}\n`);
|
|
1401
|
+
process.exitCode = 1;
|
|
1402
|
+
});
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
export { main };
|
|
1406
|
+
//# sourceMappingURL=expo-event-log-cli.mjs.map
|