aboutsummaryrefslogtreecommitdiff
path: root/src/cdp/network-buffer.ts
diff options
context:
space:
mode:
authoramankumarsingh77 <amankumarsingh7702@gmail.com>2026-07-28 22:29:16 +0530
committerAman Kumar <145339995+amankumarsingh77@users.noreply.github.com>2026-08-02 19:12:46 +0530
commitb484c017807acb902eaaaa4e242f8b79f8e8eba6 (patch)
tree4bd58916c7642e8211b4b86ab6162aa5c7a202d2 /src/cdp/network-buffer.ts
parent1b5c4240a5e679a322f636098a4b370cac084875 (diff)
refactor: act on the fallow audit
Unused exports it found that my own sweep missed, because I had grepped by name and these names occur as local variables elsewhere: deadline and the Deadline type in util/time.ts were genuinely unreferenced and are gone; isWireMessage, resolveUserDataDir, CLEAR_SELECTION_LABEL and the ExpandableText type are used only inside their own file and no longer export. isWireMessage became internal when server.ts moved to the shared serialize/deserialize codec. Duplication: console-buffer and network-buffer were the same capacity-bounded map with an overflow flag, sharing eviction, the drain tail and clear() across three clone groups. That is now cdp/record-store.ts, with tests — neither buffer had any. The three Network follow-up events also repeated the same decode-and-find preamble; one `update` helper covers them, and drops the redundant optional chaining that survived a `!id` guard. formatBytes existed verbatim in js.ts and network.ts; it is now util/bytes.ts. Duplication overall: 2.7% to 2.0%, and none of the remainder is in src. .fallowrc.json records the two entry points the tool cannot infer — the pi extension (declared under pi.extensions) and the daemon (spawned by path) — without which five reachable files read as dead. sharp is ignored because it is loaded through a variable specifier in a dynamic import so it can stay optional. agentDir is exported solely for a test's dynamic import, so it is suppressed by name rather than globally enabling ignoreExportsUsedInFile, which would have hidden four of the five findings above. Not acted on: the "split high-impact file" suggestions for session.ts, client.ts and ref-resolve.ts (119 LOC) are size and fan-in heuristics with no defect behind them, and splitting them would add the indirection this refactor set out to remove. The claim that state.ts is 100% dead is an artifact of the missing entry point. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'src/cdp/network-buffer.ts')
-rw-r--r--src/cdp/network-buffer.ts85
1 files changed, 36 insertions, 49 deletions
diff --git a/src/cdp/network-buffer.ts b/src/cdp/network-buffer.ts
index 0366ed4..20ca0fe 100644
--- a/src/cdp/network-buffer.ts
+++ b/src/cdp/network-buffer.ts
@@ -1,4 +1,5 @@
-import { decodeEvent } from "./events";
+import { decodeEvent, type EventParamsOf } from "./events";
+import { createRecordStore } from "./record-store";
export type NetworkRecord = {
requestId: string;
@@ -51,17 +52,24 @@ const compileUrlMatcher = (pattern: string): ((url: string) => boolean) => {
return (url) => url.includes(pattern);
};
+type UpdateEvent = "Network.responseReceived" | "Network.loadingFinished" | "Network.loadingFailed";
+
export const createNetworkBuffer = (capacity = 500): NetworkBuffer => {
- const records = new Map<string, NetworkRecord>();
- let overflowed = false;
-
- const evictOldestIfFull = (): void => {
- while (records.size >= capacity) {
- const oldest = records.keys().next();
- if (oldest.done) return;
- records.delete(oldest.value);
- overflowed = true;
- }
+ const records = createRecordStore<string, NetworkRecord>(capacity);
+
+ // All three follow-up events say the same thing first: decode, find the request they belong to, give up quietly if it is gone.
+ const update = <E extends UpdateEvent>(
+ method: E,
+ p: unknown,
+ apply: (r: NetworkRecord, params: EventParamsOf<E>) => void,
+ ): void => {
+ const decoded = decodeEvent(method, p);
+ if (!decoded.success) return;
+ const id = decoded.data.requestId;
+ if (!id) return;
+ const r = records.get(id);
+ if (!r) return;
+ apply(r, decoded.data);
};
return {
@@ -73,7 +81,6 @@ export const createNetworkBuffer = (capacity = 500): NetworkBuffer => {
const method = params?.request.method;
if (!id || !url || !method) return;
records.delete(id);
- evictOldestIfFull();
const postData = params.request.postData;
records.set(id, {
requestId: id,
@@ -86,40 +93,28 @@ export const createNetworkBuffer = (capacity = 500): NetworkBuffer => {
},
ingestResponseReceived(p) {
- const decoded = decodeEvent("Network.responseReceived", p);
- const params = decoded.success ? decoded.data : undefined;
- const id = params?.requestId;
- if (!id) return;
- const r = records.get(id);
- if (!r) return;
- if (params?.response?.status !== undefined) r.status = params.response.status;
- if (params?.response?.statusText !== undefined && params.response.statusText !== "") r.statusText = params.response.statusText;
- if (params?.response?.mimeType !== undefined) r.mimeType = params.response.mimeType;
- // type is more accurate on responseReceived (CDP sometimes refines it)
- if (params?.type !== undefined) r.type = params.type;
+ update("Network.responseReceived", p, (r, params) => {
+ if (params.response?.status !== undefined) r.status = params.response.status;
+ if (params.response?.statusText !== undefined && params.response.statusText !== "") r.statusText = params.response.statusText;
+ if (params.response?.mimeType !== undefined) r.mimeType = params.response.mimeType;
+ // type is more accurate on responseReceived (CDP sometimes refines it)
+ if (params.type !== undefined) r.type = params.type;
+ });
},
ingestLoadingFinished(p) {
- const decoded = decodeEvent("Network.loadingFinished", p);
- const params = decoded.success ? decoded.data : undefined;
- const id = params?.requestId;
- if (!id) return;
- const r = records.get(id);
- if (!r) return;
- if (params?.encodedDataLength !== undefined) r.responseBodySize = params.encodedDataLength;
- r.durationMs = Date.now() - r.requestStartedMs;
+ update("Network.loadingFinished", p, (r, params) => {
+ if (params.encodedDataLength !== undefined) r.responseBodySize = params.encodedDataLength;
+ r.durationMs = Date.now() - r.requestStartedMs;
+ });
},
ingestLoadingFailed(p) {
- const decoded = decodeEvent("Network.loadingFailed", p);
- const params = decoded.success ? decoded.data : undefined;
- const id = params?.requestId;
- if (!id) return;
- const r = records.get(id);
- if (!r) return;
- r.failed = true;
- if (params?.errorText !== undefined) r.errorText = params.errorText;
- r.durationMs = Date.now() - r.requestStartedMs;
+ update("Network.loadingFailed", p, (r, params) => {
+ r.failed = true;
+ if (params.errorText !== undefined) r.errorText = params.errorText;
+ r.durationMs = Date.now() - r.requestStartedMs;
+ });
},
drain(filter) {
@@ -141,19 +136,11 @@ export const createNetworkBuffer = (capacity = 500): NetworkBuffer => {
matched.push({ ...r });
}
- const total = matched.length;
- const limit = Math.min(filter.limit ?? 50, 500);
- const limited = matched.slice(-limit);
-
- const bufferOverflowed = overflowed;
- overflowed = false;
-
- return { records: limited, total, bufferOverflowed };
+ return records.page(matched, filter.limit);
},
clear() {
records.clear();
- overflowed = false;
},
};
};