2g 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,287 +0,0 @@
1
- var e = require("node:fs/promises");
2
-
3
- var n = require("node:path");
4
-
5
- var t = require("node:net");
6
-
7
- var o = require("node:readline");
8
-
9
- var r = require("./sessionSockets-chunk.js");
10
-
11
- async function listSessions(t = {}) {
12
- r.cleanStaleSessionsSync();
13
- const o = r.getSessionBaseDir();
14
- const i = await e.readdir(o, {
15
- withFileTypes: !0
16
- }).catch(() => []);
17
- const s = [];
18
- for (const e of i) {
19
- if (!e.isDirectory()) {
20
- continue;
21
- }
22
- const t = n.join(o, e.name);
23
- const i = r.readMetaSync(t);
24
- if (!i) {
25
- continue;
26
- }
27
- s.push({
28
- id: e.name,
29
- pid: i.pid,
30
- formatVersion: i.formatVersion,
31
- alive: !1,
32
- startedAt: i.startedAt,
33
- command: i.command,
34
- cwd: i.cwd,
35
- version: i.version,
36
- origin: i.origin,
37
- sessionDir: t
38
- });
39
- }
40
- const c = r.newestSessionIds(s);
41
- for (const e of s) {
42
- e.alive = r.isPidAlive(e.pid) && c.has(e.id);
43
- }
44
- return function filterSessions(e, n) {
45
- const t = n?.trim();
46
- if (!t) {
47
- return e;
48
- }
49
- const o = e.filter(e => function matchesSessionExactly(e, n) {
50
- return sessionSearchValues(e).some(e => e === n);
51
- }(e, t));
52
- if (o.length) {
53
- return o;
54
- }
55
- const r = t.toLowerCase();
56
- return e.filter(e => sessionSearchValues(e).some(e => e.toLowerCase().includes(r)));
57
- }(s, t.selector).sort((e, n) => n.startedAt - e.startedAt);
58
- }
59
-
60
- async function* readLines(e) {
61
- let n = "";
62
- for await (const t of e.createReadStream({
63
- encoding: "utf8"
64
- })) {
65
- n += t;
66
- let e = -1;
67
- while ((e = n.indexOf("\n")) >= 0) {
68
- const t = n.slice(0, e);
69
- n = n.slice(e + 1);
70
- if (t) {
71
- yield t;
72
- }
73
- }
74
- }
75
- if (n) {
76
- yield n;
77
- }
78
- }
79
-
80
- function formatSessionSelector(e) {
81
- return `${e.pid} (${e.command})`;
82
- }
83
-
84
- function readLiveLine(e, n) {
85
- if (!n) {
86
- return e.next();
87
- }
88
- if (n.aborted) {
89
- return Promise.resolve(null);
90
- }
91
- return new Promise(t => {
92
- const onAbort = () => t(null);
93
- n.addEventListener("abort", onAbort, {
94
- once: !0
95
- });
96
- e.next().then(e => {
97
- n.removeEventListener("abort", onAbort);
98
- t(n.aborted ? null : e);
99
- });
100
- });
101
- }
102
-
103
- function resetAbortTimer(e, n, t) {
104
- clearTimeout(e);
105
- return setAbortTimer(n, t);
106
- }
107
-
108
- function setAbortTimer(e, n) {
109
- const t = setTimeout(() => e.abort(), n);
110
- t.unref?.();
111
- return t;
112
- }
113
-
114
- function sessionSearchValues(e) {
115
- 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);
116
- }
117
-
118
- function tryConnect(e, n) {
119
- return new Promise(o => {
120
- const r = t.connect(e);
121
- const cleanup = () => {
122
- r.off("connect", onConnect);
123
- r.off("error", onError);
124
- n?.removeEventListener("abort", onAbort);
125
- };
126
- const onConnect = () => {
127
- cleanup();
128
- o(r);
129
- };
130
- const onError = () => {
131
- cleanup();
132
- r.destroy();
133
- o(null);
134
- };
135
- const onAbort = () => {
136
- cleanup();
137
- r.destroy();
138
- o(null);
139
- };
140
- r.once("connect", onConnect);
141
- r.once("error", onError);
142
- n?.addEventListener("abort", onAbort, {
143
- once: !0
144
- });
145
- });
146
- }
147
-
148
- exports.listSessions = listSessions;
149
-
150
- exports.resolveSession = async function resolveSession(e) {
151
- const n = await listSessions({
152
- selector: e
153
- });
154
- const t = n.filter(e => e.alive);
155
- const o = 1 === n.length ? n[0] : 1 === t.length ? t[0] : null;
156
- if (!o) {
157
- throw new Error(null != e ? n.length ? `Ambiguous 2g session "${e}"; specify one of: ${n.map(formatSessionSelector).join(", ")}` : `No 2g session matching "${e}"` : n.length ? `Ambiguous 2g session; specify one of: ${n.map(formatSessionSelector).join(", ")}` : "No 2g sessions found");
158
- }
159
- return o;
160
- };
161
-
162
- exports.tap = async function* tap(t, i = {}) {
163
- const s = !0 === i.follow;
164
- const c = r.parseSince(i.since);
165
- const a = r.compileEventFilter(i.filter);
166
- const l = function createTapAbortController(e, n) {
167
- if (!n || null == e.timeout && null == e.idleTimeout) {
168
- return;
169
- }
170
- const t = new AbortController;
171
- e.signal?.addEventListener("abort", () => t.abort(), {
172
- once: !0
173
- });
174
- if (null != e.timeout) {
175
- setAbortTimer(t, e.timeout);
176
- }
177
- return t;
178
- }(i, s);
179
- const u = l?.signal ?? i.signal;
180
- const f = r.readMetaSync(t);
181
- const d = s ? await async function connectLive(e, n, t) {
182
- const i = r.resolveSocketPath(e, n?.socket ?? r.SESSION_FILES.liveSocket);
183
- const s = await async function connectWithRetry(e, n) {
184
- for (let t = 0; t < 20 && !n?.aborted; t++) {
185
- const t = await tryConnect(e, n);
186
- if (t) {
187
- return t;
188
- }
189
- await new Promise(e => setTimeout(e, 50));
190
- }
191
- return null;
192
- }(i, t);
193
- if (!s) {
194
- return;
195
- }
196
- const c = o.createInterface({
197
- input: s
198
- });
199
- const a = [];
200
- const l = [];
201
- let u = !1;
202
- const push = e => {
203
- const n = l.shift();
204
- if (n) {
205
- n(e);
206
- } else if (null != e) {
207
- a.push(e);
208
- }
209
- };
210
- c.on("line", e => push(e));
211
- c.on("close", () => {
212
- u = !0;
213
- push(null);
214
- });
215
- s.on("error", () => {
216
- u = !0;
217
- push(null);
218
- });
219
- t?.addEventListener("abort", () => s.destroy(), {
220
- once: !0
221
- });
222
- return {
223
- buffer: a,
224
- next() {
225
- if (a.length) {
226
- return Promise.resolve(a.shift());
227
- }
228
- if (u) {
229
- return Promise.resolve(null);
230
- }
231
- return new Promise(e => l.push(e));
232
- }
233
- };
234
- }(t, f, u) : void 0;
235
- const m = await async function openHistoryFiles(t, o) {
236
- const i = o?.maxSegments ?? r.DEFAULT_SEGMENTS;
237
- const s = await Promise.all(Array.from({
238
- length: i
239
- }, (o, r) => e.open(n.join(t, `${r}.jsonl`), "r").catch(() => null)));
240
- return s.filter(e => null != e).reverse();
241
- }(t, f);
242
- let v;
243
- try {
244
- for (const e of m) {
245
- for await (const n of readLines(e)) {
246
- const e = r.parseEventLine(n, i, a, c);
247
- if (e) {
248
- yield e;
249
- }
250
- }
251
- }
252
- } finally {
253
- await Promise.all(m.map(e => e.close().catch(() => {})));
254
- }
255
- if (!d) {
256
- return;
257
- }
258
- if (null != i.idleTimeout && l) {
259
- v = setAbortTimer(l, i.idleTimeout);
260
- }
261
- for (const e of d.buffer.splice(0)) {
262
- const n = r.parseEventLine(e, i, a, c);
263
- if (n) {
264
- if (v) {
265
- v = resetAbortTimer(v, l, i.idleTimeout);
266
- }
267
- yield n;
268
- }
269
- }
270
- while (!u?.aborted) {
271
- const e = await readLiveLine(d, u);
272
- if (null == e) {
273
- break;
274
- }
275
- if (v) {
276
- v = resetAbortTimer(v, l, i.idleTimeout);
277
- }
278
- const n = r.parseEventLine(e, i, a, c);
279
- if (n) {
280
- yield n;
281
- }
282
- }
283
- if (v) {
284
- clearTimeout(v);
285
- }
286
- };
287
- //# sourceMappingURL=tap-chunk.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tap-chunk.js","sources":["../../src/tap.ts"],"sourcesContent":["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 newestSessionIds,\n readMetaSync,\n} from './clean';\nimport { type SessionMeta } from './session';\nimport type { ParsedEvent } from './types';\nimport {\n compileEventFilter,\n parseEventLine,\n parseSince,\n type EventFilterOptions,\n} from './utils/eventFilter';\nimport { resolveSocketPath } from './utils/sessionSockets';\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 extends EventFilterOptions {\n follow?: boolean;\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: false,\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 const newest = newestSessionIds(sessions);\n for (const session of sessions) {\n session.alive = isPidAlive(session.pid) && newest.has(session.id);\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 activeSessions = sessions.filter(session => session.alive);\n const session =\n sessions.length === 1\n ? sessions[0]\n : activeSessions.length === 1\n ? activeSessions[0]\n : null;\n if (!session)\n throw new Error(\n selector != null\n ? sessions.length\n ? `Ambiguous 2g session \"${selector}\"; specify one of: ${sessions\n .map(formatSessionSelector)\n .join(', ')}`\n : `No 2g session matching \"${selector}\"`\n : sessions.length\n ? `Ambiguous 2g session; specify one of: ${sessions\n .map(formatSessionSelector)\n .join(', ')}`\n : 'No 2g 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 meta = readMetaSync(sessionDir);\n const live = follow ? await connectLive(sessionDir, meta, signal) : undefined;\n const history = await openHistoryFiles(sessionDir, meta);\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, meta: SessionMeta | null) {\n const maxSegments = meta?.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\nfunction 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\nfunction formatSessionSelector(session: ListedSession) {\n return `${session.pid} (${session.command})`;\n}\n\nasync function connectLive(\n sessionDir: string,\n meta: SessionMeta | null,\n signal?: AbortSignal\n) {\n const socketPath = resolveSocketPath(\n sessionDir,\n meta?.socket ?? SESSION_FILES.liveSocket\n );\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":["async","listSessions","options","cleanStaleSessionsSync","baseDir","getSessionBaseDir","entries","fs","readdir","withFileTypes","catch","sessions","entry","isDirectory","sessionDir","path","join","name","meta","readMetaSync","push","id","pid","formatVersion","alive","startedAt","command","cwd","version","origin","newest","newestSessionIds","session","isPidAlive","has","filterSessions","selector","input","trim","exact","filter","matchesSessionExactly","sessionSearchValues","some","value","length","normalized","toLowerCase","includes","sort","a","b","readLines","handle","pending","chunk","createReadStream","encoding","index","indexOf","line","slice","formatSessionSelector","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","resolveSession","activeSessions","Error","map","tap","follow","since","parseSince","eventFilter","compileEventFilter","createTapAbortController","idleTimeout","AbortController","connectLive","resolveSocketPath","SESSION_FILES","liveSocket","connectWithRetry","attempt","rl","createInterface","buffer","waiters","closed","waiter","shift","on","undefined","history","openHistoryFiles","maxSegments","DEFAULT_SEGMENTS","handles","all","Array","from","_","open","reverse","idleTimer","event","parseEventLine","close","splice"],"mappings":"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"}
@@ -1,287 +0,0 @@
1
- import e from "node:fs/promises";
2
-
3
- import n from "node:path";
4
-
5
- import t from "node:net";
6
-
7
- import { createInterface as o } from "node:readline";
8
-
9
- import { d as i, c as r, r as s, p as c, b as a, n as l, i as f, f as u, S as m, D as d, g as p } from "./sessionSockets-chunk.mjs";
10
-
11
- async function listSessions(t = {}) {
12
- a();
13
- const o = p();
14
- const i = await e.readdir(o, {
15
- withFileTypes: !0
16
- }).catch(() => []);
17
- const r = [];
18
- for (const e of i) {
19
- if (!e.isDirectory()) {
20
- continue;
21
- }
22
- const t = n.join(o, e.name);
23
- const i = s(t);
24
- if (!i) {
25
- continue;
26
- }
27
- r.push({
28
- id: e.name,
29
- pid: i.pid,
30
- formatVersion: i.formatVersion,
31
- alive: !1,
32
- startedAt: i.startedAt,
33
- command: i.command,
34
- cwd: i.cwd,
35
- version: i.version,
36
- origin: i.origin,
37
- sessionDir: t
38
- });
39
- }
40
- const c = l(r);
41
- for (const e of r) {
42
- e.alive = f(e.pid) && c.has(e.id);
43
- }
44
- return function filterSessions(e, n) {
45
- const t = n?.trim();
46
- if (!t) {
47
- return e;
48
- }
49
- const o = e.filter(e => function matchesSessionExactly(e, n) {
50
- return sessionSearchValues(e).some(e => e === n);
51
- }(e, t));
52
- if (o.length) {
53
- return o;
54
- }
55
- const i = t.toLowerCase();
56
- return e.filter(e => sessionSearchValues(e).some(e => e.toLowerCase().includes(i)));
57
- }(r, t.selector).sort((e, n) => n.startedAt - e.startedAt);
58
- }
59
-
60
- async function resolveSession(e) {
61
- const n = await listSessions({
62
- selector: e
63
- });
64
- const t = n.filter(e => e.alive);
65
- const o = 1 === n.length ? n[0] : 1 === t.length ? t[0] : null;
66
- if (!o) {
67
- throw new Error(null != e ? n.length ? `Ambiguous 2g session "${e}"; specify one of: ${n.map(formatSessionSelector).join(", ")}` : `No 2g session matching "${e}"` : n.length ? `Ambiguous 2g session; specify one of: ${n.map(formatSessionSelector).join(", ")}` : "No 2g sessions found");
68
- }
69
- return o;
70
- }
71
-
72
- async function* tap(t, a = {}) {
73
- const l = !0 === a.follow;
74
- const f = i(a.since);
75
- const p = r(a.filter);
76
- const g = function createTapAbortController(e, n) {
77
- if (!n || null == e.timeout && null == e.idleTimeout) {
78
- return;
79
- }
80
- const t = new AbortController;
81
- e.signal?.addEventListener("abort", () => t.abort(), {
82
- once: !0
83
- });
84
- if (null != e.timeout) {
85
- setAbortTimer(t, e.timeout);
86
- }
87
- return t;
88
- }(a, l);
89
- const h = g?.signal ?? a.signal;
90
- const w = s(t);
91
- const v = l ? await async function connectLive(e, n, t) {
92
- const i = u(e, n?.socket ?? m.liveSocket);
93
- const r = await async function connectWithRetry(e, n) {
94
- for (let t = 0; t < 20 && !n?.aborted; t++) {
95
- const t = await tryConnect(e, n);
96
- if (t) {
97
- return t;
98
- }
99
- await new Promise(e => setTimeout(e, 50));
100
- }
101
- return null;
102
- }(i, t);
103
- if (!r) {
104
- return;
105
- }
106
- const s = o({
107
- input: r
108
- });
109
- const c = [];
110
- const a = [];
111
- let l = !1;
112
- const push = e => {
113
- const n = a.shift();
114
- if (n) {
115
- n(e);
116
- } else if (null != e) {
117
- c.push(e);
118
- }
119
- };
120
- s.on("line", e => push(e));
121
- s.on("close", () => {
122
- l = !0;
123
- push(null);
124
- });
125
- r.on("error", () => {
126
- l = !0;
127
- push(null);
128
- });
129
- t?.addEventListener("abort", () => r.destroy(), {
130
- once: !0
131
- });
132
- return {
133
- buffer: c,
134
- next() {
135
- if (c.length) {
136
- return Promise.resolve(c.shift());
137
- }
138
- if (l) {
139
- return Promise.resolve(null);
140
- }
141
- return new Promise(e => a.push(e));
142
- }
143
- };
144
- }(t, w, h) : void 0;
145
- const y = await async function openHistoryFiles(t, o) {
146
- const i = o?.maxSegments ?? d;
147
- const r = await Promise.all(Array.from({
148
- length: i
149
- }, (o, i) => e.open(n.join(t, `${i}.jsonl`), "r").catch(() => null)));
150
- return r.filter(e => null != e).reverse();
151
- }(t, w);
152
- let b;
153
- try {
154
- for (const e of y) {
155
- for await (const n of readLines(e)) {
156
- const e = c(n, a, p, f);
157
- if (e) {
158
- yield e;
159
- }
160
- }
161
- }
162
- } finally {
163
- await Promise.all(y.map(e => e.close().catch(() => {})));
164
- }
165
- if (!v) {
166
- return;
167
- }
168
- if (null != a.idleTimeout && g) {
169
- b = setAbortTimer(g, a.idleTimeout);
170
- }
171
- for (const e of v.buffer.splice(0)) {
172
- const n = c(e, a, p, f);
173
- if (n) {
174
- if (b) {
175
- b = resetAbortTimer(b, g, a.idleTimeout);
176
- }
177
- yield n;
178
- }
179
- }
180
- while (!h?.aborted) {
181
- const e = await readLiveLine(v, h);
182
- if (null == e) {
183
- break;
184
- }
185
- if (b) {
186
- b = resetAbortTimer(b, g, a.idleTimeout);
187
- }
188
- const n = c(e, a, p, f);
189
- if (n) {
190
- yield n;
191
- }
192
- }
193
- if (b) {
194
- clearTimeout(b);
195
- }
196
- }
197
-
198
- async function* readLines(e) {
199
- let n = "";
200
- for await (const t of e.createReadStream({
201
- encoding: "utf8"
202
- })) {
203
- n += t;
204
- let e = -1;
205
- while ((e = n.indexOf("\n")) >= 0) {
206
- const t = n.slice(0, e);
207
- n = n.slice(e + 1);
208
- if (t) {
209
- yield t;
210
- }
211
- }
212
- }
213
- if (n) {
214
- yield n;
215
- }
216
- }
217
-
218
- function formatSessionSelector(e) {
219
- return `${e.pid} (${e.command})`;
220
- }
221
-
222
- function readLiveLine(e, n) {
223
- if (!n) {
224
- return e.next();
225
- }
226
- if (n.aborted) {
227
- return Promise.resolve(null);
228
- }
229
- return new Promise(t => {
230
- const onAbort = () => t(null);
231
- n.addEventListener("abort", onAbort, {
232
- once: !0
233
- });
234
- e.next().then(e => {
235
- n.removeEventListener("abort", onAbort);
236
- t(n.aborted ? null : e);
237
- });
238
- });
239
- }
240
-
241
- function resetAbortTimer(e, n, t) {
242
- clearTimeout(e);
243
- return setAbortTimer(n, t);
244
- }
245
-
246
- function setAbortTimer(e, n) {
247
- const t = setTimeout(() => e.abort(), n);
248
- t.unref?.();
249
- return t;
250
- }
251
-
252
- function sessionSearchValues(e) {
253
- 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);
254
- }
255
-
256
- function tryConnect(e, n) {
257
- return new Promise(o => {
258
- const i = t.connect(e);
259
- const cleanup = () => {
260
- i.off("connect", onConnect);
261
- i.off("error", onError);
262
- n?.removeEventListener("abort", onAbort);
263
- };
264
- const onConnect = () => {
265
- cleanup();
266
- o(i);
267
- };
268
- const onError = () => {
269
- cleanup();
270
- i.destroy();
271
- o(null);
272
- };
273
- const onAbort = () => {
274
- cleanup();
275
- i.destroy();
276
- o(null);
277
- };
278
- i.once("connect", onConnect);
279
- i.once("error", onError);
280
- n?.addEventListener("abort", onAbort, {
281
- once: !0
282
- });
283
- });
284
- }
285
-
286
- export { listSessions as l, resolveSession as r, tap as t };
287
- //# sourceMappingURL=tap-chunk.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tap-chunk.mjs","sources":["../../src/tap.ts"],"sourcesContent":["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 newestSessionIds,\n readMetaSync,\n} from './clean';\nimport { type SessionMeta } from './session';\nimport type { ParsedEvent } from './types';\nimport {\n compileEventFilter,\n parseEventLine,\n parseSince,\n type EventFilterOptions,\n} from './utils/eventFilter';\nimport { resolveSocketPath } from './utils/sessionSockets';\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 extends EventFilterOptions {\n follow?: boolean;\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: false,\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 const newest = newestSessionIds(sessions);\n for (const session of sessions) {\n session.alive = isPidAlive(session.pid) && newest.has(session.id);\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 activeSessions = sessions.filter(session => session.alive);\n const session =\n sessions.length === 1\n ? sessions[0]\n : activeSessions.length === 1\n ? activeSessions[0]\n : null;\n if (!session)\n throw new Error(\n selector != null\n ? sessions.length\n ? `Ambiguous 2g session \"${selector}\"; specify one of: ${sessions\n .map(formatSessionSelector)\n .join(', ')}`\n : `No 2g session matching \"${selector}\"`\n : sessions.length\n ? `Ambiguous 2g session; specify one of: ${sessions\n .map(formatSessionSelector)\n .join(', ')}`\n : 'No 2g 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 meta = readMetaSync(sessionDir);\n const live = follow ? await connectLive(sessionDir, meta, signal) : undefined;\n const history = await openHistoryFiles(sessionDir, meta);\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, meta: SessionMeta | null) {\n const maxSegments = meta?.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\nfunction 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\nfunction formatSessionSelector(session: ListedSession) {\n return `${session.pid} (${session.command})`;\n}\n\nasync function connectLive(\n sessionDir: string,\n meta: SessionMeta | null,\n signal?: AbortSignal\n) {\n const socketPath = resolveSocketPath(\n sessionDir,\n meta?.socket ?? SESSION_FILES.liveSocket\n );\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":["async","listSessions","options","cleanStaleSessionsSync","baseDir","getSessionBaseDir","entries","fs","readdir","withFileTypes","catch","sessions","entry","isDirectory","sessionDir","path","join","name","meta","readMetaSync","push","id","pid","formatVersion","alive","startedAt","command","cwd","version","origin","newest","newestSessionIds","session","isPidAlive","has","filterSessions","selector","input","trim","exact","filter","matchesSessionExactly","sessionSearchValues","some","value","length","normalized","toLowerCase","includes","sort","a","b","resolveSession","activeSessions","Error","map","formatSessionSelector","tap","follow","since","parseSince","eventFilter","compileEventFilter","abort","createTapAbortController","timeout","idleTimeout","AbortController","signal","addEventListener","once","setAbortTimer","live","connectLive","socketPath","resolveSocketPath","socket","SESSION_FILES","liveSocket","connectWithRetry","attempt","aborted","tryConnect","Promise","resolve","setTimeout","rl","createInterface","buffer","waiters","closed","line","waiter","shift","on","destroy","next","undefined","history","openHistoryFiles","maxSegments","DEFAULT_SEGMENTS","handles","all","Array","from","_","index","open","handle","reverse","idleTimer","readLines","event","parseEventLine","close","splice","resetAbortTimer","readLiveLine","clearTimeout","pending","chunk","createReadStream","encoding","indexOf","slice","onAbort","then","removeEventListener","timer","unref","String","argv","execPath","env","npmLifecycleEvent","npmPackageName","net","connect","cleanup","off","onConnect","onError"],"mappings":"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"}