@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 @@
|
|
|
1
|
+
{"version":3,"file":"tap-chunk.js","sources":["../../src/constants.ts","../../src/clean.ts","../../src/tap.ts","../../src/utils/redirectConsole.ts"],"sourcesContent":["import os from 'node:os';\nimport path from 'node:path';\n\nexport const EVENT_LOG_TMP_DIR = path.join(os.tmpdir(), 'expo-event-log');\nexport const EVENT_LOG_FORMAT_VERSION = 1;\nexport const EVENT_LOG_STATE_VERSION = 1;\nexport const LOG_EVENTS_ENV = 'LOG_EVENTS';\nexport const INTERNAL_IPC_ENV = '__eventLogIpc';\nexport const INTERNAL_PROCESS_ORIGIN_ENV = '__eventLogProcessOrigin';\n\nexport const SESSION_FILES = {\n meta: 'meta.json',\n liveSocket: 'live.sock',\n ipcSocket: 'ipc.sock',\n} as const;\n\nexport const DEFAULT_SEGMENTS = 3;\nexport const DEFAULT_SEGMENT_SIZE = 512 * 1024;\nexport const DEFAULT_RETAIN_MS = 7 * 24 * 60 * 60 * 1000;\nexport const DEFAULT_MAX_SESSIONS = 100;\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nimport {\n DEFAULT_MAX_SESSIONS,\n DEFAULT_RETAIN_MS,\n EVENT_LOG_TMP_DIR,\n EVENT_LOG_FORMAT_VERSION,\n SESSION_FILES,\n} from './constants';\nimport type { SessionMeta } from './install';\n\ninterface SessionEntry {\n dir: string;\n meta: SessionMeta;\n alive: boolean;\n}\n\nconst SESSION_BASE_DIR_OVERRIDE = Symbol.for(\n '@expo/event-log/session-base-dir-override'\n);\n\ninterface EventLogGlobal {\n [SESSION_BASE_DIR_OVERRIDE]?: string;\n}\n\nexport function cleanStaleSessionsSync() {\n const entries = getSessionEntries();\n const now = Date.now();\n let removed = 0;\n\n for (const entry of entries) {\n if (!entry.alive && now - entry.meta.startedAt > DEFAULT_RETAIN_MS) {\n fs.rmSync(entry.dir, { recursive: true, force: true });\n removed++;\n }\n }\n\n const retained = entries\n .filter(entry => fs.existsSync(entry.dir))\n .sort((a, b) => b.meta.startedAt - a.meta.startedAt);\n\n for (const entry of retained\n .filter(entry => !entry.alive)\n .slice(DEFAULT_MAX_SESSIONS)) {\n fs.rmSync(entry.dir, { recursive: true, force: true });\n removed++;\n }\n\n return removed;\n}\n\nexport function readMetaSync(sessionDir: string): SessionMeta | null {\n try {\n const meta = JSON.parse(\n fs.readFileSync(path.join(sessionDir, SESSION_FILES.meta), 'utf8')\n );\n return isCompatibleSessionMeta(meta) ? meta : null;\n } catch {\n return null;\n }\n}\n\nexport function getSessionBaseDir() {\n return (\n (globalThis as EventLogGlobal)[SESSION_BASE_DIR_OVERRIDE] ||\n EVENT_LOG_TMP_DIR\n );\n}\n\nexport function _setSessionBaseDir(dir: string | undefined) {\n const globalScope = globalThis as EventLogGlobal;\n if (dir) globalScope[SESSION_BASE_DIR_OVERRIDE] = dir;\n else delete globalScope[SESSION_BASE_DIR_OVERRIDE];\n}\n\nexport function isPidAlive(pid: number) {\n if (!pid || pid === process.pid) return true;\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction getSessionEntries() {\n try {\n const baseDir = getSessionBaseDir();\n return fs\n .readdirSync(baseDir, { withFileTypes: true })\n .filter(entry => entry.isDirectory())\n .map(entry => {\n const dir = path.join(baseDir, entry.name);\n return { dir, meta: readMetaSync(dir), alive: false };\n })\n .filter(\n (entry): entry is SessionEntry =>\n !!entry.meta && isCompatibleSessionMeta(entry.meta)\n )\n .map(entry => ({ ...entry, alive: isPidAlive(entry.meta.pid) }));\n } catch {\n return [];\n }\n}\n\nfunction isCompatibleSessionMeta(meta: unknown): meta is SessionMeta {\n return (\n !!meta &&\n typeof meta === 'object' &&\n (meta as SessionMeta).formatVersion === EVENT_LOG_FORMAT_VERSION\n );\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport net from 'node:net';\nimport { createInterface } from 'node:readline';\n\nimport { DEFAULT_SEGMENTS, SESSION_FILES } from './constants';\nimport {\n cleanStaleSessionsSync,\n getSessionBaseDir,\n isPidAlive,\n readMetaSync,\n} from './clean';\nimport { type SessionMeta } from './install';\nimport type { ParsedEvent } from './types';\n\nexport interface ListedSession {\n id: string;\n pid: number;\n formatVersion: number;\n alive: boolean;\n startedAt: number;\n command: string;\n cwd: string;\n version?: string;\n origin?: SessionMeta['origin'];\n sessionDir: string;\n}\n\nexport interface ListSessionsOptions {\n selector?: string;\n}\n\nexport interface TapOptions {\n since?: number | string | Date;\n follow?: boolean;\n filter?: string | string[];\n signal?: AbortSignal;\n timeout?: number;\n idleTimeout?: number;\n}\n\nexport async function listSessions(\n options: ListSessionsOptions = {}\n): Promise<ListedSession[]> {\n cleanStaleSessionsSync();\n const baseDir = getSessionBaseDir();\n const entries = await fs\n .readdir(baseDir, { withFileTypes: true })\n .catch(() => []);\n const sessions: ListedSession[] = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const sessionDir = path.join(baseDir, entry.name);\n const meta = readMetaSync(sessionDir);\n if (!meta) continue;\n sessions.push({\n id: entry.name,\n pid: meta.pid,\n formatVersion: meta.formatVersion,\n alive: isPidAlive(meta.pid),\n startedAt: meta.startedAt,\n command: meta.command,\n cwd: meta.cwd,\n version: meta.version,\n origin: meta.origin,\n sessionDir,\n });\n }\n\n return filterSessions(sessions, options.selector).sort(\n (a, b) => b.startedAt - a.startedAt\n );\n}\n\nexport async function resolveSession(selector?: string) {\n const sessions = await listSessions({ selector });\n const session = sessions.length === 1 ? sessions[0] : null;\n if (!session)\n throw new Error(\n selector != null\n ? sessions.length\n ? `Ambiguous event-log session \"${selector}\"; specify one of: ${sessions\n .map(formatSessionSelector)\n .join(', ')}`\n : `No event-log session matching \"${selector}\"`\n : sessions.length\n ? `Ambiguous event-log session; specify one of: ${sessions\n .map(formatSessionSelector)\n .join(', ')}`\n : 'No event-log sessions found'\n );\n return session;\n}\n\nexport async function* tap(\n sessionDir: string,\n options: TapOptions = {}\n): AsyncIterable<ParsedEvent> {\n const follow = options.follow === true;\n const since = parseSince(options.since);\n const eventFilter = compileEventFilter(options.filter);\n const abort = createTapAbortController(options, follow);\n const signal = abort?.signal ?? options.signal;\n const live = follow ? await connectLive(sessionDir, signal) : undefined;\n const history = await openHistoryFiles(sessionDir);\n let idleTimer: NodeJS.Timeout | undefined;\n\n try {\n for (const handle of history) {\n for await (const line of readLines(handle)) {\n const event = parseEventLine(line, options, eventFilter, since);\n if (event) yield event;\n }\n }\n } finally {\n await Promise.all(history.map(handle => handle.close().catch(() => {})));\n }\n\n if (!live) return;\n if (options.idleTimeout != null && abort) {\n idleTimer = setAbortTimer(abort, options.idleTimeout);\n }\n\n for (const line of live.buffer.splice(0)) {\n const event = parseEventLine(line, options, eventFilter, since);\n if (event) {\n if (idleTimer)\n idleTimer = resetAbortTimer(idleTimer, abort!, options.idleTimeout!);\n yield event;\n }\n }\n\n while (!signal?.aborted) {\n const line = await readLiveLine(live, signal);\n if (line == null) break;\n if (idleTimer)\n idleTimer = resetAbortTimer(idleTimer, abort!, options.idleTimeout!);\n const event = parseEventLine(line, options, eventFilter, since);\n if (event) yield event;\n }\n\n if (idleTimer) clearTimeout(idleTimer);\n}\n\nasync function openHistoryFiles(sessionDir: string) {\n const maxSegments = readMetaSync(sessionDir)?.maxSegments ?? DEFAULT_SEGMENTS;\n const handles = await Promise.all(\n Array.from({ length: maxSegments }, (_, index) =>\n fs.open(path.join(sessionDir, `${index}.jsonl`), 'r').catch(() => null)\n )\n );\n return handles.filter(handle => handle != null).reverse();\n}\n\nasync function* readLines(handle: fs.FileHandle) {\n let pending = '';\n for await (const chunk of handle.createReadStream({ encoding: 'utf8' })) {\n pending += chunk;\n let index = -1;\n while ((index = pending.indexOf('\\n')) >= 0) {\n const line = pending.slice(0, index);\n pending = pending.slice(index + 1);\n if (line) yield line;\n }\n }\n if (pending) yield pending;\n}\n\nexport function parseEventLine(\n line: string,\n options: TapOptions = {},\n eventFilter = compileEventFilter(options.filter),\n since = parseSince(options.since)\n): ParsedEvent | null {\n try {\n const event = JSON.parse(line) as ParsedEvent;\n if (!event || typeof event._e !== 'string' || typeof event._t !== 'number')\n return null;\n if (since != null && event._t < since) return null;\n if (!matchesEventFilter(event._e, eventFilter)) return null;\n return event;\n } catch {\n return null;\n }\n}\n\nexport function parseSince(value: TapOptions['since']) {\n if (value == null) return undefined;\n if (value instanceof Date) {\n const timestamp = value.getTime();\n if (Number.isFinite(timestamp)) return timestamp;\n throw new Error(`Invalid since: ${value.toString()}`);\n }\n if (typeof value === 'number') {\n if (!Number.isFinite(value) || value < 0)\n throw new Error(`Invalid since: ${value}`);\n return normalizeUnixTimestamp(value);\n }\n\n const input = value.trim();\n if (!input) return undefined;\n if (/^\\d+(?:\\.\\d+)?$/.test(input))\n return normalizeUnixTimestamp(Number(input));\n\n const duration = parseDuration(input);\n if (duration != null) return Date.now() - duration;\n\n const timestamp = Date.parse(input);\n if (Number.isFinite(timestamp)) return timestamp;\n throw new Error(`Invalid since: ${value}`);\n}\n\nexport function compileEventFilter(filter: string | string[] | undefined) {\n const patterns = normalizeEventFilter(filter);\n if (!patterns.length) return null;\n return new RegExp(`^(?:${patterns.map(eventPatternToRegex).join('|')})$`);\n}\n\nexport function matchesEventFilter(eventName: string, filter: RegExp | null) {\n return !filter || filter.test(eventName);\n}\n\nexport function filterSessions(\n sessions: ListedSession[],\n selector: string | undefined\n) {\n const input = selector?.trim();\n if (!input) return sessions;\n\n const exact = sessions.filter(session =>\n matchesSessionExactly(session, input)\n );\n if (exact.length) return exact;\n\n const normalized = input.toLowerCase();\n return sessions.filter(session =>\n sessionSearchValues(session).some(value =>\n value.toLowerCase().includes(normalized)\n )\n );\n}\n\nexport function formatSessionSelector(session: ListedSession) {\n return `${session.pid} (${session.command})`;\n}\n\nfunction normalizeEventFilter(filter: string | string[] | undefined) {\n const values = Array.isArray(filter) ? filter : filter ? [filter] : [];\n return values\n .flatMap(value => value.split(','))\n .map(value => value.trim())\n .filter(Boolean);\n}\n\nfunction eventPatternToRegex(pattern: string) {\n const source =\n pattern.includes(':') || pattern.includes('*') ? pattern : `${pattern}:*`;\n return source.split('*').map(escapeRegex).join('.*');\n}\n\nfunction escapeRegex(value: string) {\n return value.replace(/[|\\\\{}()[\\]^$+?.]/g, '\\\\$&');\n}\n\nfunction parseDuration(value: string) {\n const input = value.trim().toLowerCase();\n if (!input) return undefined;\n\n let total = 0;\n let index = 0;\n const pattern =\n /(\\d+(?:\\.\\d+)?)\\s*(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h)/gy;\n\n while (index < input.length) {\n pattern.lastIndex = index;\n const match = pattern.exec(input);\n if (!match) return undefined;\n const amount = Number(match[1]);\n if (!Number.isFinite(amount)) return undefined;\n total += amount * durationUnitToMs(match[2]);\n index = pattern.lastIndex;\n while (input[index] === ' ' || input[index] === ',') index++;\n }\n\n return total;\n}\n\nfunction normalizeUnixTimestamp(value: number) {\n return value < 10_000_000_000 ? value * 1000 : value;\n}\n\nfunction durationUnitToMs(unit: string) {\n if (\n unit === 'ms' ||\n unit === 'msec' ||\n unit === 'msecs' ||\n unit === 'millisecond' ||\n unit === 'milliseconds'\n )\n return 1;\n if (\n unit === 's' ||\n unit === 'sec' ||\n unit === 'secs' ||\n unit === 'second' ||\n unit === 'seconds'\n )\n return 1000;\n if (\n unit === 'm' ||\n unit === 'min' ||\n unit === 'mins' ||\n unit === 'minute' ||\n unit === 'minutes'\n )\n return 60_000;\n if (\n unit === 'h' ||\n unit === 'hr' ||\n unit === 'hrs' ||\n unit === 'hour' ||\n unit === 'hours'\n )\n return 3_600_000;\n return 1;\n}\n\nasync function connectLive(sessionDir: string, signal?: AbortSignal) {\n const socketPath = path.join(sessionDir, SESSION_FILES.liveSocket);\n const socket = await connectWithRetry(socketPath, signal);\n if (!socket) return undefined;\n const rl = createInterface({ input: socket });\n const buffer: string[] = [];\n const waiters: Array<(line: string | null) => void> = [];\n let closed = false;\n\n const push = (line: string | null) => {\n const waiter = waiters.shift();\n if (waiter) waiter(line);\n else if (line != null) buffer.push(line);\n };\n\n rl.on('line', line => push(line));\n rl.on('close', () => {\n closed = true;\n push(null);\n });\n socket.on('error', () => {\n closed = true;\n push(null);\n });\n signal?.addEventListener('abort', () => socket.destroy(), { once: true });\n\n return {\n buffer,\n next() {\n if (buffer.length) return Promise.resolve(buffer.shift()!);\n if (closed) return Promise.resolve(null);\n return new Promise<string | null>(resolve => waiters.push(resolve));\n },\n };\n}\n\nfunction readLiveLine(\n live: { next(): Promise<string | null> },\n signal?: AbortSignal\n) {\n if (!signal) return live.next();\n if (signal.aborted) return Promise.resolve(null);\n\n return new Promise<string | null>(resolve => {\n const onAbort = () => resolve(null);\n signal.addEventListener('abort', onAbort, { once: true });\n live.next().then(line => {\n signal.removeEventListener('abort', onAbort);\n resolve(signal.aborted ? null : line);\n });\n });\n}\n\nfunction createTapAbortController(options: TapOptions, follow: boolean) {\n if (!follow || (options.timeout == null && options.idleTimeout == null))\n return undefined;\n\n const abort = new AbortController();\n options.signal?.addEventListener('abort', () => abort.abort(), {\n once: true,\n });\n if (options.timeout != null) setAbortTimer(abort, options.timeout);\n return abort;\n}\n\nfunction resetAbortTimer(\n timer: NodeJS.Timeout,\n abort: AbortController,\n timeout: number\n) {\n clearTimeout(timer);\n return setAbortTimer(abort, timeout);\n}\n\nfunction setAbortTimer(abort: AbortController, timeout: number) {\n const timer = setTimeout(() => abort.abort(), timeout);\n timer.unref?.();\n return timer;\n}\n\nfunction matchesSessionExactly(session: ListedSession, selector: string) {\n return sessionSearchValues(session).some(value => value === selector);\n}\n\nfunction sessionSearchValues(session: ListedSession) {\n return [\n session.id,\n String(session.pid),\n session.sessionDir,\n session.cwd,\n session.command,\n session.origin?.cwd,\n session.origin?.argv.join(' '),\n session.origin?.execPath,\n session.origin?.env?.npmLifecycleEvent,\n session.origin?.env?.npmPackageName,\n ].filter((value): value is string => !!value);\n}\n\nasync function connectWithRetry(socketPath: string, signal?: AbortSignal) {\n for (let attempt = 0; attempt < 20 && !signal?.aborted; attempt++) {\n const socket = await tryConnect(socketPath, signal);\n if (socket) return socket;\n await new Promise(resolve => setTimeout(resolve, 50));\n }\n return null;\n}\n\nfunction tryConnect(socketPath: string, signal?: AbortSignal) {\n return new Promise<net.Socket | null>(resolve => {\n const socket = net.connect(socketPath);\n const cleanup = () => {\n socket.off('connect', onConnect);\n socket.off('error', onError);\n signal?.removeEventListener('abort', onAbort);\n };\n const onConnect = () => {\n cleanup();\n resolve(socket);\n };\n const onError = () => {\n cleanup();\n socket.destroy();\n resolve(null);\n };\n const onAbort = () => {\n cleanup();\n socket.destroy();\n resolve(null);\n };\n socket.once('connect', onConnect);\n socket.once('error', onError);\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n","import { Console } from 'node:console';\n\nexport function redirectConsoleToStderr() {\n globalThis.console = new Console(process.stderr, process.stderr);\n}\n\nexport function redirectConsoleForFd(fd: number) {\n if (fd === 1) {\n const output = process.stderr;\n Object.defineProperty(process, 'stdout', { get: () => output });\n globalThis.console = new Console(output, output);\n } else if (fd === 2) {\n const output = process.stdout;\n Object.defineProperty(process, 'stderr', { get: () => output });\n globalThis.console = new Console(output, output);\n }\n}\n"],"names":["EVENT_LOG_TMP_DIR","path","join","os","tmpdir","SESSION_FILES","meta","liveSocket","ipcSocket","SESSION_BASE_DIR_OVERRIDE","Symbol","for","cleanStaleSessionsSync","entries","getSessionEntries","baseDir","getSessionBaseDir","fs","readdirSync","withFileTypes","filter","entry","isDirectory","map","dir","name","readMetaSync","alive","isCompatibleSessionMeta","isPidAlive","pid","now","Date","removed","startedAt","rmSync","recursive","force","retained","existsSync","sort","a","b","slice","sessionDir","JSON","parse","readFileSync","globalThis","process","kill","formatVersion","async","listSessions","options","readdir","catch","sessions","push","id","command","cwd","version","origin","filterSessions","selector","input","trim","exact","session","matchesSessionExactly","sessionSearchValues","some","value","length","normalized","toLowerCase","includes","readLines","handle","pending","chunk","createReadStream","encoding","index","indexOf","line","parseEventLine","eventFilter","compileEventFilter","since","parseSince","event","_e","_t","matchesEventFilter","timestamp","getTime","Number","isFinite","Error","toString","normalizeUnixTimestamp","test","duration","parseDuration","total","pattern","lastIndex","match","exec","amount","durationUnitToMs","patterns","normalizeEventFilter","values","Array","isArray","flatMap","split","Boolean","RegExp","eventPatternToRegex","eventName","formatSessionSelector","escapeRegex","replace","unit","readLiveLine","live","signal","next","aborted","Promise","resolve","onAbort","addEventListener","once","then","removeEventListener","resetAbortTimer","timer","abort","timeout","clearTimeout","setAbortTimer","setTimeout","unref","String","argv","execPath","env","npmLifecycleEvent","npmPackageName","tryConnect","socketPath","socket","net","connect","cleanup","off","onConnect","onError","destroy","redirectConsoleForFd","fd","output","stderr","Object","defineProperty","get","console","Console","stdout","redirectConsoleToStderr","resolveSession","tap","follow","createTapAbortController","idleTimeout","AbortController","connectLive","connectWithRetry","attempt","rl","createInterface","buffer","waiters","closed","waiter","shift","on","undefined","history","openHistoryFiles","maxSegments","handles","all","from","_","open","reverse","idleTimer","close","splice"],"mappings":"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"}
|
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
import { Console as e } from "node:console";
|
|
2
|
+
|
|
3
|
+
import n from "node:fs/promises";
|
|
4
|
+
|
|
5
|
+
import t from "node:path";
|
|
6
|
+
|
|
7
|
+
import r from "node:net";
|
|
8
|
+
|
|
9
|
+
import { createInterface as o } from "node:readline";
|
|
10
|
+
|
|
11
|
+
import i from "node:os";
|
|
12
|
+
|
|
13
|
+
import s from "node:fs";
|
|
14
|
+
|
|
15
|
+
const c = t.join(i.tmpdir(), "expo-event-log");
|
|
16
|
+
|
|
17
|
+
const a = 1;
|
|
18
|
+
|
|
19
|
+
const l = 1;
|
|
20
|
+
|
|
21
|
+
const u = "LOG_EVENTS";
|
|
22
|
+
|
|
23
|
+
const f = "__eventLogIpc";
|
|
24
|
+
|
|
25
|
+
const m = "__eventLogProcessOrigin";
|
|
26
|
+
|
|
27
|
+
const d = {
|
|
28
|
+
meta: "meta.json",
|
|
29
|
+
liveSocket: "live.sock",
|
|
30
|
+
ipcSocket: "ipc.sock"
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const p = 3;
|
|
34
|
+
|
|
35
|
+
const v = 524288;
|
|
36
|
+
|
|
37
|
+
const S = Symbol.for("@expo/event-log/session-base-dir-override");
|
|
38
|
+
|
|
39
|
+
function cleanStaleSessionsSync() {
|
|
40
|
+
const e = function getSessionEntries() {
|
|
41
|
+
try {
|
|
42
|
+
const e = getSessionBaseDir();
|
|
43
|
+
return s.readdirSync(e, {
|
|
44
|
+
withFileTypes: !0
|
|
45
|
+
}).filter(e => e.isDirectory()).map(n => {
|
|
46
|
+
const r = t.join(e, n.name);
|
|
47
|
+
return {
|
|
48
|
+
dir: r,
|
|
49
|
+
meta: readMetaSync(r),
|
|
50
|
+
alive: !1
|
|
51
|
+
};
|
|
52
|
+
}).filter(e => !!e.meta && isCompatibleSessionMeta(e.meta)).map(e => ({
|
|
53
|
+
...e,
|
|
54
|
+
alive: isPidAlive(e.meta.pid)
|
|
55
|
+
}));
|
|
56
|
+
} catch {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
}();
|
|
60
|
+
const n = Date.now();
|
|
61
|
+
let r = 0;
|
|
62
|
+
for (const t of e) {
|
|
63
|
+
if (!t.alive && n - t.meta.startedAt > 6048e5) {
|
|
64
|
+
s.rmSync(t.dir, {
|
|
65
|
+
recursive: !0,
|
|
66
|
+
force: !0
|
|
67
|
+
});
|
|
68
|
+
r++;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const o = e.filter(e => s.existsSync(e.dir)).sort((e, n) => n.meta.startedAt - e.meta.startedAt);
|
|
72
|
+
for (const e of o.filter(e => !e.alive).slice(100)) {
|
|
73
|
+
s.rmSync(e.dir, {
|
|
74
|
+
recursive: !0,
|
|
75
|
+
force: !0
|
|
76
|
+
});
|
|
77
|
+
r++;
|
|
78
|
+
}
|
|
79
|
+
return r;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function readMetaSync(e) {
|
|
83
|
+
try {
|
|
84
|
+
const n = JSON.parse(s.readFileSync(t.join(e, d.meta), "utf8"));
|
|
85
|
+
return isCompatibleSessionMeta(n) ? n : null;
|
|
86
|
+
} catch {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function getSessionBaseDir() {
|
|
92
|
+
return globalThis[S] || c;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function isPidAlive(e) {
|
|
96
|
+
if (!e || e === process.pid) {
|
|
97
|
+
return !0;
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
process.kill(e, 0);
|
|
101
|
+
return !0;
|
|
102
|
+
} catch {
|
|
103
|
+
return !1;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function isCompatibleSessionMeta(e) {
|
|
108
|
+
return !!e && "object" == typeof e && 1 === e.formatVersion;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function redirectConsoleToStderr() {
|
|
112
|
+
globalThis.console = new e(process.stderr, process.stderr);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function redirectConsoleForFd(n) {
|
|
116
|
+
if (1 === n) {
|
|
117
|
+
const n = process.stderr;
|
|
118
|
+
Object.defineProperty(process, "stdout", {
|
|
119
|
+
get: () => n
|
|
120
|
+
});
|
|
121
|
+
globalThis.console = new e(n, n);
|
|
122
|
+
} else if (2 === n) {
|
|
123
|
+
const n = process.stdout;
|
|
124
|
+
Object.defineProperty(process, "stderr", {
|
|
125
|
+
get: () => n
|
|
126
|
+
});
|
|
127
|
+
globalThis.console = new e(n, n);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async function listSessions(e = {}) {
|
|
132
|
+
cleanStaleSessionsSync();
|
|
133
|
+
const r = getSessionBaseDir();
|
|
134
|
+
const o = await n.readdir(r, {
|
|
135
|
+
withFileTypes: !0
|
|
136
|
+
}).catch(() => []);
|
|
137
|
+
const i = [];
|
|
138
|
+
for (const e of o) {
|
|
139
|
+
if (!e.isDirectory()) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const n = t.join(r, e.name);
|
|
143
|
+
const o = readMetaSync(n);
|
|
144
|
+
if (!o) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
i.push({
|
|
148
|
+
id: e.name,
|
|
149
|
+
pid: o.pid,
|
|
150
|
+
formatVersion: o.formatVersion,
|
|
151
|
+
alive: isPidAlive(o.pid),
|
|
152
|
+
startedAt: o.startedAt,
|
|
153
|
+
command: o.command,
|
|
154
|
+
cwd: o.cwd,
|
|
155
|
+
version: o.version,
|
|
156
|
+
origin: o.origin,
|
|
157
|
+
sessionDir: n
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
return function filterSessions(e, n) {
|
|
161
|
+
const t = n?.trim();
|
|
162
|
+
if (!t) {
|
|
163
|
+
return e;
|
|
164
|
+
}
|
|
165
|
+
const r = e.filter(e => function matchesSessionExactly(e, n) {
|
|
166
|
+
return sessionSearchValues(e).some(e => e === n);
|
|
167
|
+
}(e, t));
|
|
168
|
+
if (r.length) {
|
|
169
|
+
return r;
|
|
170
|
+
}
|
|
171
|
+
const o = t.toLowerCase();
|
|
172
|
+
return e.filter(e => sessionSearchValues(e).some(e => e.toLowerCase().includes(o)));
|
|
173
|
+
}(i, e.selector).sort((e, n) => n.startedAt - e.startedAt);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async function resolveSession(e) {
|
|
177
|
+
const n = await listSessions({
|
|
178
|
+
selector: e
|
|
179
|
+
});
|
|
180
|
+
const t = 1 === n.length ? n[0] : null;
|
|
181
|
+
if (!t) {
|
|
182
|
+
throw new Error(null != e ? n.length ? `Ambiguous event-log session "${e}"; specify one of: ${n.map(formatSessionSelector).join(", ")}` : `No event-log session matching "${e}"` : n.length ? `Ambiguous event-log session; specify one of: ${n.map(formatSessionSelector).join(", ")}` : "No event-log sessions found");
|
|
183
|
+
}
|
|
184
|
+
return t;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
async function* tap(e, r = {}) {
|
|
188
|
+
const i = !0 === r.follow;
|
|
189
|
+
const s = parseSince(r.since);
|
|
190
|
+
const c = compileEventFilter(r.filter);
|
|
191
|
+
const a = function createTapAbortController(e, n) {
|
|
192
|
+
if (!n || null == e.timeout && null == e.idleTimeout) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
const t = new AbortController;
|
|
196
|
+
e.signal?.addEventListener("abort", () => t.abort(), {
|
|
197
|
+
once: !0
|
|
198
|
+
});
|
|
199
|
+
if (null != e.timeout) {
|
|
200
|
+
setAbortTimer(t, e.timeout);
|
|
201
|
+
}
|
|
202
|
+
return t;
|
|
203
|
+
}(r, i);
|
|
204
|
+
const l = a?.signal ?? r.signal;
|
|
205
|
+
const u = i ? await async function connectLive(e, n) {
|
|
206
|
+
const r = t.join(e, d.liveSocket);
|
|
207
|
+
const i = await async function connectWithRetry(e, n) {
|
|
208
|
+
for (let t = 0; t < 20 && !n?.aborted; t++) {
|
|
209
|
+
const t = await tryConnect(e, n);
|
|
210
|
+
if (t) {
|
|
211
|
+
return t;
|
|
212
|
+
}
|
|
213
|
+
await new Promise(e => setTimeout(e, 50));
|
|
214
|
+
}
|
|
215
|
+
return null;
|
|
216
|
+
}(r, n);
|
|
217
|
+
if (!i) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const s = o({
|
|
221
|
+
input: i
|
|
222
|
+
});
|
|
223
|
+
const c = [];
|
|
224
|
+
const a = [];
|
|
225
|
+
let l = !1;
|
|
226
|
+
const push = e => {
|
|
227
|
+
const n = a.shift();
|
|
228
|
+
if (n) {
|
|
229
|
+
n(e);
|
|
230
|
+
} else if (null != e) {
|
|
231
|
+
c.push(e);
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
s.on("line", e => push(e));
|
|
235
|
+
s.on("close", () => {
|
|
236
|
+
l = !0;
|
|
237
|
+
push(null);
|
|
238
|
+
});
|
|
239
|
+
i.on("error", () => {
|
|
240
|
+
l = !0;
|
|
241
|
+
push(null);
|
|
242
|
+
});
|
|
243
|
+
n?.addEventListener("abort", () => i.destroy(), {
|
|
244
|
+
once: !0
|
|
245
|
+
});
|
|
246
|
+
return {
|
|
247
|
+
buffer: c,
|
|
248
|
+
next() {
|
|
249
|
+
if (c.length) {
|
|
250
|
+
return Promise.resolve(c.shift());
|
|
251
|
+
}
|
|
252
|
+
if (l) {
|
|
253
|
+
return Promise.resolve(null);
|
|
254
|
+
}
|
|
255
|
+
return new Promise(e => a.push(e));
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
}(e, l) : void 0;
|
|
259
|
+
const f = await async function openHistoryFiles(e) {
|
|
260
|
+
const r = readMetaSync(e)?.maxSegments ?? 3;
|
|
261
|
+
const o = await Promise.all(Array.from({
|
|
262
|
+
length: r
|
|
263
|
+
}, (r, o) => n.open(t.join(e, `${o}.jsonl`), "r").catch(() => null)));
|
|
264
|
+
return o.filter(e => null != e).reverse();
|
|
265
|
+
}(e);
|
|
266
|
+
let m;
|
|
267
|
+
try {
|
|
268
|
+
for (const e of f) {
|
|
269
|
+
for await (const n of readLines(e)) {
|
|
270
|
+
const e = parseEventLine(n, r, c, s);
|
|
271
|
+
if (e) {
|
|
272
|
+
yield e;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
} finally {
|
|
277
|
+
await Promise.all(f.map(e => e.close().catch(() => {})));
|
|
278
|
+
}
|
|
279
|
+
if (!u) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
if (null != r.idleTimeout && a) {
|
|
283
|
+
m = setAbortTimer(a, r.idleTimeout);
|
|
284
|
+
}
|
|
285
|
+
for (const e of u.buffer.splice(0)) {
|
|
286
|
+
const n = parseEventLine(e, r, c, s);
|
|
287
|
+
if (n) {
|
|
288
|
+
if (m) {
|
|
289
|
+
m = resetAbortTimer(m, a, r.idleTimeout);
|
|
290
|
+
}
|
|
291
|
+
yield n;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
while (!l?.aborted) {
|
|
295
|
+
const e = await readLiveLine(u, l);
|
|
296
|
+
if (null == e) {
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
if (m) {
|
|
300
|
+
m = resetAbortTimer(m, a, r.idleTimeout);
|
|
301
|
+
}
|
|
302
|
+
const n = parseEventLine(e, r, c, s);
|
|
303
|
+
if (n) {
|
|
304
|
+
yield n;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
if (m) {
|
|
308
|
+
clearTimeout(m);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
async function* readLines(e) {
|
|
313
|
+
let n = "";
|
|
314
|
+
for await (const t of e.createReadStream({
|
|
315
|
+
encoding: "utf8"
|
|
316
|
+
})) {
|
|
317
|
+
n += t;
|
|
318
|
+
let e = -1;
|
|
319
|
+
while ((e = n.indexOf("\n")) >= 0) {
|
|
320
|
+
const t = n.slice(0, e);
|
|
321
|
+
n = n.slice(e + 1);
|
|
322
|
+
if (t) {
|
|
323
|
+
yield t;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
if (n) {
|
|
328
|
+
yield n;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function parseEventLine(e, n = {}, t = compileEventFilter(n.filter), r = parseSince(n.since)) {
|
|
333
|
+
try {
|
|
334
|
+
const n = JSON.parse(e);
|
|
335
|
+
if (!n || "string" != typeof n._e || "number" != typeof n._t) {
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
if (null != r && n._t < r) {
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
if (!matchesEventFilter(n._e, t)) {
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
return n;
|
|
345
|
+
} catch {
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function parseSince(e) {
|
|
351
|
+
if (null == e) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
if (e instanceof Date) {
|
|
355
|
+
const n = e.getTime();
|
|
356
|
+
if (Number.isFinite(n)) {
|
|
357
|
+
return n;
|
|
358
|
+
}
|
|
359
|
+
throw new Error(`Invalid since: ${e.toString()}`);
|
|
360
|
+
}
|
|
361
|
+
if ("number" == typeof e) {
|
|
362
|
+
if (!Number.isFinite(e) || e < 0) {
|
|
363
|
+
throw new Error(`Invalid since: ${e}`);
|
|
364
|
+
}
|
|
365
|
+
return normalizeUnixTimestamp(e);
|
|
366
|
+
}
|
|
367
|
+
const n = e.trim();
|
|
368
|
+
if (!n) {
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
if (/^\d+(?:\.\d+)?$/.test(n)) {
|
|
372
|
+
return normalizeUnixTimestamp(Number(n));
|
|
373
|
+
}
|
|
374
|
+
const t = function parseDuration(e) {
|
|
375
|
+
const n = e.trim().toLowerCase();
|
|
376
|
+
if (!n) {
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
let t = 0;
|
|
380
|
+
let r = 0;
|
|
381
|
+
const o = /(\d+(?:\.\d+)?)\s*(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h)/gy;
|
|
382
|
+
while (r < n.length) {
|
|
383
|
+
o.lastIndex = r;
|
|
384
|
+
const e = o.exec(n);
|
|
385
|
+
if (!e) {
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
const i = Number(e[1]);
|
|
389
|
+
if (!Number.isFinite(i)) {
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
t += i * durationUnitToMs(e[2]);
|
|
393
|
+
r = o.lastIndex;
|
|
394
|
+
while (" " === n[r] || "," === n[r]) {
|
|
395
|
+
r++;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
return t;
|
|
399
|
+
}(n);
|
|
400
|
+
if (null != t) {
|
|
401
|
+
return Date.now() - t;
|
|
402
|
+
}
|
|
403
|
+
const r = Date.parse(n);
|
|
404
|
+
if (Number.isFinite(r)) {
|
|
405
|
+
return r;
|
|
406
|
+
}
|
|
407
|
+
throw new Error(`Invalid since: ${e}`);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
function compileEventFilter(e) {
|
|
411
|
+
const n = function normalizeEventFilter(e) {
|
|
412
|
+
const n = Array.isArray(e) ? e : e ? [ e ] : [];
|
|
413
|
+
return n.flatMap(e => e.split(",")).map(e => e.trim()).filter(Boolean);
|
|
414
|
+
}(e);
|
|
415
|
+
if (!n.length) {
|
|
416
|
+
return null;
|
|
417
|
+
}
|
|
418
|
+
return new RegExp(`^(?:${n.map(eventPatternToRegex).join("|")})$`);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function matchesEventFilter(e, n) {
|
|
422
|
+
return !n || n.test(e);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function formatSessionSelector(e) {
|
|
426
|
+
return `${e.pid} (${e.command})`;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
function eventPatternToRegex(e) {
|
|
430
|
+
return (e.includes(":") || e.includes("*") ? e : `${e}:*`).split("*").map(escapeRegex).join(".*");
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
function escapeRegex(e) {
|
|
434
|
+
return e.replace(/[|\\{}()[\]^$+?.]/g, "\\$&");
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
function normalizeUnixTimestamp(e) {
|
|
438
|
+
return e < 1e10 ? 1e3 * e : e;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
function durationUnitToMs(e) {
|
|
442
|
+
if ("ms" === e || "msec" === e || "msecs" === e || "millisecond" === e || "milliseconds" === e) {
|
|
443
|
+
return 1;
|
|
444
|
+
}
|
|
445
|
+
if ("s" === e || "sec" === e || "secs" === e || "second" === e || "seconds" === e) {
|
|
446
|
+
return 1e3;
|
|
447
|
+
}
|
|
448
|
+
if ("m" === e || "min" === e || "mins" === e || "minute" === e || "minutes" === e) {
|
|
449
|
+
return 6e4;
|
|
450
|
+
}
|
|
451
|
+
if ("h" === e || "hr" === e || "hrs" === e || "hour" === e || "hours" === e) {
|
|
452
|
+
return 36e5;
|
|
453
|
+
}
|
|
454
|
+
return 1;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
function readLiveLine(e, n) {
|
|
458
|
+
if (!n) {
|
|
459
|
+
return e.next();
|
|
460
|
+
}
|
|
461
|
+
if (n.aborted) {
|
|
462
|
+
return Promise.resolve(null);
|
|
463
|
+
}
|
|
464
|
+
return new Promise(t => {
|
|
465
|
+
const onAbort = () => t(null);
|
|
466
|
+
n.addEventListener("abort", onAbort, {
|
|
467
|
+
once: !0
|
|
468
|
+
});
|
|
469
|
+
e.next().then(e => {
|
|
470
|
+
n.removeEventListener("abort", onAbort);
|
|
471
|
+
t(n.aborted ? null : e);
|
|
472
|
+
});
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function resetAbortTimer(e, n, t) {
|
|
477
|
+
clearTimeout(e);
|
|
478
|
+
return setAbortTimer(n, t);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
function setAbortTimer(e, n) {
|
|
482
|
+
const t = setTimeout(() => e.abort(), n);
|
|
483
|
+
t.unref?.();
|
|
484
|
+
return t;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
function sessionSearchValues(e) {
|
|
488
|
+
return [ e.id, String(e.pid), e.sessionDir, e.cwd, e.command, e.origin?.cwd, e.origin?.argv.join(" "), e.origin?.execPath, e.origin?.env?.npmLifecycleEvent, e.origin?.env?.npmPackageName ].filter(e => !!e);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
function tryConnect(e, n) {
|
|
492
|
+
return new Promise(t => {
|
|
493
|
+
const o = r.connect(e);
|
|
494
|
+
const cleanup = () => {
|
|
495
|
+
o.off("connect", onConnect);
|
|
496
|
+
o.off("error", onError);
|
|
497
|
+
n?.removeEventListener("abort", onAbort);
|
|
498
|
+
};
|
|
499
|
+
const onConnect = () => {
|
|
500
|
+
cleanup();
|
|
501
|
+
t(o);
|
|
502
|
+
};
|
|
503
|
+
const onError = () => {
|
|
504
|
+
cleanup();
|
|
505
|
+
o.destroy();
|
|
506
|
+
t(null);
|
|
507
|
+
};
|
|
508
|
+
const onAbort = () => {
|
|
509
|
+
cleanup();
|
|
510
|
+
o.destroy();
|
|
511
|
+
t(null);
|
|
512
|
+
};
|
|
513
|
+
o.once("connect", onConnect);
|
|
514
|
+
o.once("error", onError);
|
|
515
|
+
n?.addEventListener("abort", onAbort, {
|
|
516
|
+
once: !0
|
|
517
|
+
});
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
export { p as D, l as E, m as I, u as L, d as S, parseEventLine as a, cleanStaleSessionsSync as b, compileEventFilter as c, resolveSession as d, redirectConsoleForFd as e, f, a as g, getSessionBaseDir as h, v as i, listSessions as l, matchesEventFilter as m, parseSince as p, redirectConsoleToStderr as r, tap as t };
|
|
522
|
+
//# sourceMappingURL=tap-chunk.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tap-chunk.mjs","sources":["../../src/constants.ts","../../src/clean.ts","../../src/utils/redirectConsole.ts","../../src/tap.ts"],"sourcesContent":["import os from 'node:os';\nimport path from 'node:path';\n\nexport const EVENT_LOG_TMP_DIR = path.join(os.tmpdir(), 'expo-event-log');\nexport const EVENT_LOG_FORMAT_VERSION = 1;\nexport const EVENT_LOG_STATE_VERSION = 1;\nexport const LOG_EVENTS_ENV = 'LOG_EVENTS';\nexport const INTERNAL_IPC_ENV = '__eventLogIpc';\nexport const INTERNAL_PROCESS_ORIGIN_ENV = '__eventLogProcessOrigin';\n\nexport const SESSION_FILES = {\n meta: 'meta.json',\n liveSocket: 'live.sock',\n ipcSocket: 'ipc.sock',\n} as const;\n\nexport const DEFAULT_SEGMENTS = 3;\nexport const DEFAULT_SEGMENT_SIZE = 512 * 1024;\nexport const DEFAULT_RETAIN_MS = 7 * 24 * 60 * 60 * 1000;\nexport const DEFAULT_MAX_SESSIONS = 100;\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nimport {\n DEFAULT_MAX_SESSIONS,\n DEFAULT_RETAIN_MS,\n EVENT_LOG_TMP_DIR,\n EVENT_LOG_FORMAT_VERSION,\n SESSION_FILES,\n} from './constants';\nimport type { SessionMeta } from './install';\n\ninterface SessionEntry {\n dir: string;\n meta: SessionMeta;\n alive: boolean;\n}\n\nconst SESSION_BASE_DIR_OVERRIDE = Symbol.for(\n '@expo/event-log/session-base-dir-override'\n);\n\ninterface EventLogGlobal {\n [SESSION_BASE_DIR_OVERRIDE]?: string;\n}\n\nexport function cleanStaleSessionsSync() {\n const entries = getSessionEntries();\n const now = Date.now();\n let removed = 0;\n\n for (const entry of entries) {\n if (!entry.alive && now - entry.meta.startedAt > DEFAULT_RETAIN_MS) {\n fs.rmSync(entry.dir, { recursive: true, force: true });\n removed++;\n }\n }\n\n const retained = entries\n .filter(entry => fs.existsSync(entry.dir))\n .sort((a, b) => b.meta.startedAt - a.meta.startedAt);\n\n for (const entry of retained\n .filter(entry => !entry.alive)\n .slice(DEFAULT_MAX_SESSIONS)) {\n fs.rmSync(entry.dir, { recursive: true, force: true });\n removed++;\n }\n\n return removed;\n}\n\nexport function readMetaSync(sessionDir: string): SessionMeta | null {\n try {\n const meta = JSON.parse(\n fs.readFileSync(path.join(sessionDir, SESSION_FILES.meta), 'utf8')\n );\n return isCompatibleSessionMeta(meta) ? meta : null;\n } catch {\n return null;\n }\n}\n\nexport function getSessionBaseDir() {\n return (\n (globalThis as EventLogGlobal)[SESSION_BASE_DIR_OVERRIDE] ||\n EVENT_LOG_TMP_DIR\n );\n}\n\nexport function _setSessionBaseDir(dir: string | undefined) {\n const globalScope = globalThis as EventLogGlobal;\n if (dir) globalScope[SESSION_BASE_DIR_OVERRIDE] = dir;\n else delete globalScope[SESSION_BASE_DIR_OVERRIDE];\n}\n\nexport function isPidAlive(pid: number) {\n if (!pid || pid === process.pid) return true;\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction getSessionEntries() {\n try {\n const baseDir = getSessionBaseDir();\n return fs\n .readdirSync(baseDir, { withFileTypes: true })\n .filter(entry => entry.isDirectory())\n .map(entry => {\n const dir = path.join(baseDir, entry.name);\n return { dir, meta: readMetaSync(dir), alive: false };\n })\n .filter(\n (entry): entry is SessionEntry =>\n !!entry.meta && isCompatibleSessionMeta(entry.meta)\n )\n .map(entry => ({ ...entry, alive: isPidAlive(entry.meta.pid) }));\n } catch {\n return [];\n }\n}\n\nfunction isCompatibleSessionMeta(meta: unknown): meta is SessionMeta {\n return (\n !!meta &&\n typeof meta === 'object' &&\n (meta as SessionMeta).formatVersion === EVENT_LOG_FORMAT_VERSION\n );\n}\n","import { Console } from 'node:console';\n\nexport function redirectConsoleToStderr() {\n globalThis.console = new Console(process.stderr, process.stderr);\n}\n\nexport function redirectConsoleForFd(fd: number) {\n if (fd === 1) {\n const output = process.stderr;\n Object.defineProperty(process, 'stdout', { get: () => output });\n globalThis.console = new Console(output, output);\n } else if (fd === 2) {\n const output = process.stdout;\n Object.defineProperty(process, 'stderr', { get: () => output });\n globalThis.console = new Console(output, output);\n }\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport net from 'node:net';\nimport { createInterface } from 'node:readline';\n\nimport { DEFAULT_SEGMENTS, SESSION_FILES } from './constants';\nimport {\n cleanStaleSessionsSync,\n getSessionBaseDir,\n isPidAlive,\n readMetaSync,\n} from './clean';\nimport { type SessionMeta } from './install';\nimport type { ParsedEvent } from './types';\n\nexport interface ListedSession {\n id: string;\n pid: number;\n formatVersion: number;\n alive: boolean;\n startedAt: number;\n command: string;\n cwd: string;\n version?: string;\n origin?: SessionMeta['origin'];\n sessionDir: string;\n}\n\nexport interface ListSessionsOptions {\n selector?: string;\n}\n\nexport interface TapOptions {\n since?: number | string | Date;\n follow?: boolean;\n filter?: string | string[];\n signal?: AbortSignal;\n timeout?: number;\n idleTimeout?: number;\n}\n\nexport async function listSessions(\n options: ListSessionsOptions = {}\n): Promise<ListedSession[]> {\n cleanStaleSessionsSync();\n const baseDir = getSessionBaseDir();\n const entries = await fs\n .readdir(baseDir, { withFileTypes: true })\n .catch(() => []);\n const sessions: ListedSession[] = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const sessionDir = path.join(baseDir, entry.name);\n const meta = readMetaSync(sessionDir);\n if (!meta) continue;\n sessions.push({\n id: entry.name,\n pid: meta.pid,\n formatVersion: meta.formatVersion,\n alive: isPidAlive(meta.pid),\n startedAt: meta.startedAt,\n command: meta.command,\n cwd: meta.cwd,\n version: meta.version,\n origin: meta.origin,\n sessionDir,\n });\n }\n\n return filterSessions(sessions, options.selector).sort(\n (a, b) => b.startedAt - a.startedAt\n );\n}\n\nexport async function resolveSession(selector?: string) {\n const sessions = await listSessions({ selector });\n const session = sessions.length === 1 ? sessions[0] : null;\n if (!session)\n throw new Error(\n selector != null\n ? sessions.length\n ? `Ambiguous event-log session \"${selector}\"; specify one of: ${sessions\n .map(formatSessionSelector)\n .join(', ')}`\n : `No event-log session matching \"${selector}\"`\n : sessions.length\n ? `Ambiguous event-log session; specify one of: ${sessions\n .map(formatSessionSelector)\n .join(', ')}`\n : 'No event-log sessions found'\n );\n return session;\n}\n\nexport async function* tap(\n sessionDir: string,\n options: TapOptions = {}\n): AsyncIterable<ParsedEvent> {\n const follow = options.follow === true;\n const since = parseSince(options.since);\n const eventFilter = compileEventFilter(options.filter);\n const abort = createTapAbortController(options, follow);\n const signal = abort?.signal ?? options.signal;\n const live = follow ? await connectLive(sessionDir, signal) : undefined;\n const history = await openHistoryFiles(sessionDir);\n let idleTimer: NodeJS.Timeout | undefined;\n\n try {\n for (const handle of history) {\n for await (const line of readLines(handle)) {\n const event = parseEventLine(line, options, eventFilter, since);\n if (event) yield event;\n }\n }\n } finally {\n await Promise.all(history.map(handle => handle.close().catch(() => {})));\n }\n\n if (!live) return;\n if (options.idleTimeout != null && abort) {\n idleTimer = setAbortTimer(abort, options.idleTimeout);\n }\n\n for (const line of live.buffer.splice(0)) {\n const event = parseEventLine(line, options, eventFilter, since);\n if (event) {\n if (idleTimer)\n idleTimer = resetAbortTimer(idleTimer, abort!, options.idleTimeout!);\n yield event;\n }\n }\n\n while (!signal?.aborted) {\n const line = await readLiveLine(live, signal);\n if (line == null) break;\n if (idleTimer)\n idleTimer = resetAbortTimer(idleTimer, abort!, options.idleTimeout!);\n const event = parseEventLine(line, options, eventFilter, since);\n if (event) yield event;\n }\n\n if (idleTimer) clearTimeout(idleTimer);\n}\n\nasync function openHistoryFiles(sessionDir: string) {\n const maxSegments = readMetaSync(sessionDir)?.maxSegments ?? DEFAULT_SEGMENTS;\n const handles = await Promise.all(\n Array.from({ length: maxSegments }, (_, index) =>\n fs.open(path.join(sessionDir, `${index}.jsonl`), 'r').catch(() => null)\n )\n );\n return handles.filter(handle => handle != null).reverse();\n}\n\nasync function* readLines(handle: fs.FileHandle) {\n let pending = '';\n for await (const chunk of handle.createReadStream({ encoding: 'utf8' })) {\n pending += chunk;\n let index = -1;\n while ((index = pending.indexOf('\\n')) >= 0) {\n const line = pending.slice(0, index);\n pending = pending.slice(index + 1);\n if (line) yield line;\n }\n }\n if (pending) yield pending;\n}\n\nexport function parseEventLine(\n line: string,\n options: TapOptions = {},\n eventFilter = compileEventFilter(options.filter),\n since = parseSince(options.since)\n): ParsedEvent | null {\n try {\n const event = JSON.parse(line) as ParsedEvent;\n if (!event || typeof event._e !== 'string' || typeof event._t !== 'number')\n return null;\n if (since != null && event._t < since) return null;\n if (!matchesEventFilter(event._e, eventFilter)) return null;\n return event;\n } catch {\n return null;\n }\n}\n\nexport function parseSince(value: TapOptions['since']) {\n if (value == null) return undefined;\n if (value instanceof Date) {\n const timestamp = value.getTime();\n if (Number.isFinite(timestamp)) return timestamp;\n throw new Error(`Invalid since: ${value.toString()}`);\n }\n if (typeof value === 'number') {\n if (!Number.isFinite(value) || value < 0)\n throw new Error(`Invalid since: ${value}`);\n return normalizeUnixTimestamp(value);\n }\n\n const input = value.trim();\n if (!input) return undefined;\n if (/^\\d+(?:\\.\\d+)?$/.test(input))\n return normalizeUnixTimestamp(Number(input));\n\n const duration = parseDuration(input);\n if (duration != null) return Date.now() - duration;\n\n const timestamp = Date.parse(input);\n if (Number.isFinite(timestamp)) return timestamp;\n throw new Error(`Invalid since: ${value}`);\n}\n\nexport function compileEventFilter(filter: string | string[] | undefined) {\n const patterns = normalizeEventFilter(filter);\n if (!patterns.length) return null;\n return new RegExp(`^(?:${patterns.map(eventPatternToRegex).join('|')})$`);\n}\n\nexport function matchesEventFilter(eventName: string, filter: RegExp | null) {\n return !filter || filter.test(eventName);\n}\n\nexport function filterSessions(\n sessions: ListedSession[],\n selector: string | undefined\n) {\n const input = selector?.trim();\n if (!input) return sessions;\n\n const exact = sessions.filter(session =>\n matchesSessionExactly(session, input)\n );\n if (exact.length) return exact;\n\n const normalized = input.toLowerCase();\n return sessions.filter(session =>\n sessionSearchValues(session).some(value =>\n value.toLowerCase().includes(normalized)\n )\n );\n}\n\nexport function formatSessionSelector(session: ListedSession) {\n return `${session.pid} (${session.command})`;\n}\n\nfunction normalizeEventFilter(filter: string | string[] | undefined) {\n const values = Array.isArray(filter) ? filter : filter ? [filter] : [];\n return values\n .flatMap(value => value.split(','))\n .map(value => value.trim())\n .filter(Boolean);\n}\n\nfunction eventPatternToRegex(pattern: string) {\n const source =\n pattern.includes(':') || pattern.includes('*') ? pattern : `${pattern}:*`;\n return source.split('*').map(escapeRegex).join('.*');\n}\n\nfunction escapeRegex(value: string) {\n return value.replace(/[|\\\\{}()[\\]^$+?.]/g, '\\\\$&');\n}\n\nfunction parseDuration(value: string) {\n const input = value.trim().toLowerCase();\n if (!input) return undefined;\n\n let total = 0;\n let index = 0;\n const pattern =\n /(\\d+(?:\\.\\d+)?)\\s*(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h)/gy;\n\n while (index < input.length) {\n pattern.lastIndex = index;\n const match = pattern.exec(input);\n if (!match) return undefined;\n const amount = Number(match[1]);\n if (!Number.isFinite(amount)) return undefined;\n total += amount * durationUnitToMs(match[2]);\n index = pattern.lastIndex;\n while (input[index] === ' ' || input[index] === ',') index++;\n }\n\n return total;\n}\n\nfunction normalizeUnixTimestamp(value: number) {\n return value < 10_000_000_000 ? value * 1000 : value;\n}\n\nfunction durationUnitToMs(unit: string) {\n if (\n unit === 'ms' ||\n unit === 'msec' ||\n unit === 'msecs' ||\n unit === 'millisecond' ||\n unit === 'milliseconds'\n )\n return 1;\n if (\n unit === 's' ||\n unit === 'sec' ||\n unit === 'secs' ||\n unit === 'second' ||\n unit === 'seconds'\n )\n return 1000;\n if (\n unit === 'm' ||\n unit === 'min' ||\n unit === 'mins' ||\n unit === 'minute' ||\n unit === 'minutes'\n )\n return 60_000;\n if (\n unit === 'h' ||\n unit === 'hr' ||\n unit === 'hrs' ||\n unit === 'hour' ||\n unit === 'hours'\n )\n return 3_600_000;\n return 1;\n}\n\nasync function connectLive(sessionDir: string, signal?: AbortSignal) {\n const socketPath = path.join(sessionDir, SESSION_FILES.liveSocket);\n const socket = await connectWithRetry(socketPath, signal);\n if (!socket) return undefined;\n const rl = createInterface({ input: socket });\n const buffer: string[] = [];\n const waiters: Array<(line: string | null) => void> = [];\n let closed = false;\n\n const push = (line: string | null) => {\n const waiter = waiters.shift();\n if (waiter) waiter(line);\n else if (line != null) buffer.push(line);\n };\n\n rl.on('line', line => push(line));\n rl.on('close', () => {\n closed = true;\n push(null);\n });\n socket.on('error', () => {\n closed = true;\n push(null);\n });\n signal?.addEventListener('abort', () => socket.destroy(), { once: true });\n\n return {\n buffer,\n next() {\n if (buffer.length) return Promise.resolve(buffer.shift()!);\n if (closed) return Promise.resolve(null);\n return new Promise<string | null>(resolve => waiters.push(resolve));\n },\n };\n}\n\nfunction readLiveLine(\n live: { next(): Promise<string | null> },\n signal?: AbortSignal\n) {\n if (!signal) return live.next();\n if (signal.aborted) return Promise.resolve(null);\n\n return new Promise<string | null>(resolve => {\n const onAbort = () => resolve(null);\n signal.addEventListener('abort', onAbort, { once: true });\n live.next().then(line => {\n signal.removeEventListener('abort', onAbort);\n resolve(signal.aborted ? null : line);\n });\n });\n}\n\nfunction createTapAbortController(options: TapOptions, follow: boolean) {\n if (!follow || (options.timeout == null && options.idleTimeout == null))\n return undefined;\n\n const abort = new AbortController();\n options.signal?.addEventListener('abort', () => abort.abort(), {\n once: true,\n });\n if (options.timeout != null) setAbortTimer(abort, options.timeout);\n return abort;\n}\n\nfunction resetAbortTimer(\n timer: NodeJS.Timeout,\n abort: AbortController,\n timeout: number\n) {\n clearTimeout(timer);\n return setAbortTimer(abort, timeout);\n}\n\nfunction setAbortTimer(abort: AbortController, timeout: number) {\n const timer = setTimeout(() => abort.abort(), timeout);\n timer.unref?.();\n return timer;\n}\n\nfunction matchesSessionExactly(session: ListedSession, selector: string) {\n return sessionSearchValues(session).some(value => value === selector);\n}\n\nfunction sessionSearchValues(session: ListedSession) {\n return [\n session.id,\n String(session.pid),\n session.sessionDir,\n session.cwd,\n session.command,\n session.origin?.cwd,\n session.origin?.argv.join(' '),\n session.origin?.execPath,\n session.origin?.env?.npmLifecycleEvent,\n session.origin?.env?.npmPackageName,\n ].filter((value): value is string => !!value);\n}\n\nasync function connectWithRetry(socketPath: string, signal?: AbortSignal) {\n for (let attempt = 0; attempt < 20 && !signal?.aborted; attempt++) {\n const socket = await tryConnect(socketPath, signal);\n if (socket) return socket;\n await new Promise(resolve => setTimeout(resolve, 50));\n }\n return null;\n}\n\nfunction tryConnect(socketPath: string, signal?: AbortSignal) {\n return new Promise<net.Socket | null>(resolve => {\n const socket = net.connect(socketPath);\n const cleanup = () => {\n socket.off('connect', onConnect);\n socket.off('error', onError);\n signal?.removeEventListener('abort', onAbort);\n };\n const onConnect = () => {\n cleanup();\n resolve(socket);\n };\n const onError = () => {\n cleanup();\n socket.destroy();\n resolve(null);\n };\n const onAbort = () => {\n cleanup();\n socket.destroy();\n resolve(null);\n };\n socket.once('connect', onConnect);\n socket.once('error', onError);\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n"],"names":["EVENT_LOG_TMP_DIR","path","join","os","tmpdir","EVENT_LOG_FORMAT_VERSION","EVENT_LOG_STATE_VERSION","LOG_EVENTS_ENV","INTERNAL_IPC_ENV","INTERNAL_PROCESS_ORIGIN_ENV","SESSION_FILES","meta","liveSocket","ipcSocket","DEFAULT_SEGMENTS","DEFAULT_SEGMENT_SIZE","SESSION_BASE_DIR_OVERRIDE","Symbol","for","cleanStaleSessionsSync","entries","getSessionEntries","baseDir","getSessionBaseDir","fs","readdirSync","withFileTypes","filter","entry","isDirectory","map","dir","name","readMetaSync","alive","isCompatibleSessionMeta","isPidAlive","pid","now","Date","removed","startedAt","rmSync","recursive","force","retained","existsSync","sort","a","b","slice","sessionDir","JSON","parse","readFileSync","globalThis","process","kill","formatVersion","redirectConsoleToStderr","console","Console","stderr","redirectConsoleForFd","fd","output","Object","defineProperty","get","stdout","async","listSessions","options","readdir","catch","sessions","push","id","command","cwd","version","origin","filterSessions","selector","input","trim","exact","session","matchesSessionExactly","sessionSearchValues","some","value","length","normalized","toLowerCase","includes","resolveSession","Error","formatSessionSelector","tap","follow","since","parseSince","eventFilter","compileEventFilter","abort","createTapAbortController","timeout","idleTimeout","AbortController","signal","addEventListener","once","setAbortTimer","live","connectLive","socketPath","socket","connectWithRetry","attempt","aborted","tryConnect","Promise","resolve","setTimeout","rl","createInterface","buffer","waiters","closed","line","waiter","shift","on","destroy","next","undefined","history","openHistoryFiles","maxSegments","handles","all","Array","from","_","index","open","handle","reverse","idleTimer","readLines","event","parseEventLine","close","splice","resetAbortTimer","readLiveLine","clearTimeout","pending","chunk","createReadStream","encoding","indexOf","_e","_t","matchesEventFilter","timestamp","getTime","Number","isFinite","toString","normalizeUnixTimestamp","test","duration","parseDuration","total","pattern","lastIndex","match","exec","amount","durationUnitToMs","patterns","normalizeEventFilter","values","isArray","flatMap","split","Boolean","RegExp","eventPatternToRegex","eventName","escapeRegex","replace","unit","onAbort","then","removeEventListener","timer","unref","String","argv","execPath","env","npmLifecycleEvent","npmPackageName","net","connect","cleanup","off","onConnect","onError"],"mappings":"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"}
|