@vforsh/argus-watcher 0.1.7 → 0.1.8

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.
Files changed (45) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/cdp/text-filter.js.map +1 -1
  3. package/dist/http/routes/domSelectorRoute.d.ts +16 -0
  4. package/dist/http/routes/domSelectorRoute.d.ts.map +1 -0
  5. package/dist/http/routes/domSelectorRoute.js +31 -0
  6. package/dist/http/routes/domSelectorRoute.js.map +1 -0
  7. package/dist/http/routes/postDomClick.d.ts.map +1 -1
  8. package/dist/http/routes/postDomClick.js +2 -7
  9. package/dist/http/routes/postDomClick.js.map +1 -1
  10. package/dist/http/routes/postDomFocus.d.ts.map +1 -1
  11. package/dist/http/routes/postDomFocus.js +6 -17
  12. package/dist/http/routes/postDomFocus.js.map +1 -1
  13. package/dist/http/routes/postDomHover.d.ts.map +1 -1
  14. package/dist/http/routes/postDomHover.js +6 -17
  15. package/dist/http/routes/postDomHover.js.map +1 -1
  16. package/dist/http/routes/postDomInfo.d.ts.map +1 -1
  17. package/dist/http/routes/postDomInfo.js +6 -18
  18. package/dist/http/routes/postDomInfo.js.map +1 -1
  19. package/dist/http/routes/postDomRemove.d.ts.map +1 -1
  20. package/dist/http/routes/postDomRemove.js +6 -17
  21. package/dist/http/routes/postDomRemove.js.map +1 -1
  22. package/dist/http/routes/postDomTree.d.ts.map +1 -1
  23. package/dist/http/routes/postDomTree.js +6 -18
  24. package/dist/http/routes/postDomTree.js.map +1 -1
  25. package/dist/index.d.ts +1 -1
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +3 -396
  28. package/dist/index.js.map +1 -1
  29. package/dist/sources/extension-delegating-session.d.ts +21 -0
  30. package/dist/sources/extension-delegating-session.d.ts.map +1 -0
  31. package/dist/sources/extension-delegating-session.js +62 -0
  32. package/dist/sources/extension-delegating-session.js.map +1 -0
  33. package/dist/sources/extension-session-events.d.ts +21 -0
  34. package/dist/sources/extension-session-events.d.ts.map +1 -0
  35. package/dist/sources/extension-session-events.js +103 -0
  36. package/dist/sources/extension-session-events.js.map +1 -0
  37. package/dist/sources/extension-source.d.ts +0 -4
  38. package/dist/sources/extension-source.d.ts.map +1 -1
  39. package/dist/sources/extension-source.js +28 -169
  40. package/dist/sources/extension-source.js.map +1 -1
  41. package/dist/startWatcherRuntime.d.ts +6 -0
  42. package/dist/startWatcherRuntime.d.ts.map +1 -0
  43. package/dist/startWatcherRuntime.js +414 -0
  44. package/dist/startWatcherRuntime.js.map +1 -0
  45. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,22 +1,6 @@
1
- import os from 'node:os';
2
- import path from 'node:path';
3
1
  import Emittery from 'emittery';
4
- import { LogBuffer } from './buffer/LogBuffer.js';
5
- import { NetBuffer } from './buffer/NetBuffer.js';
6
- import { startHttpServer } from './http/server.js';
7
- import { announceWatcher, removeWatcher, startRegistryHeartbeat, resolveUniqueWatcherId } from './registry/registry.js';
8
- import { WatcherFileLogger } from './fileLogs/WatcherFileLogger.js';
9
- import { buildIgnoreMatcher } from './cdp/ignoreList.js';
10
- import { createNetworkCapture } from './cdp/networkCapture.js';
11
- import { createTraceRecorder } from './cdp/tracing.js';
12
- import { createScreenshotter } from './cdp/screenshot.js';
13
- import { createRuntimeEditor } from './cdp/editor.js';
14
- import { createCdpSessionHandle } from './cdp/connection.js';
15
- import { createPageIndicatorController, validatePageIndicatorOptions, } from './cdp/pageIndicator.js';
16
- import { createEmulationController } from './emulation/EmulationController.js';
17
- import { createThrottleController } from './throttle/ThrottleController.js';
18
- import { createCdpSource } from './sources/cdp-source.js';
19
- import { createExtensionSource } from './sources/extension-source.js';
2
+ import { resolveUniqueWatcherId } from './registry/registry.js';
3
+ import { createWatcherHandle } from './startWatcherRuntime.js';
20
4
  /**
21
5
  * Start a watcher that connects to Chrome (via CDP or extension), buffers console logs, and exposes the HTTP API.
22
6
  * @param options - Configuration for binding, source mode, and buffering.
@@ -27,383 +11,6 @@ export const startWatcher = async (options) => {
27
11
  throw new Error('Watcher id is required');
28
12
  }
29
13
  const watcherId = await resolveUniqueWatcherId(options.id);
30
- const sourceMode = options.source ?? 'cdp';
31
- const host = options.host ?? '127.0.0.1';
32
- const port = options.port ?? 0;
33
- const chrome = options.chrome ?? { host: '127.0.0.1', port: 9222 };
34
- const bufferSize = options.bufferSize ?? 50_000;
35
- const netBufferSize = options.bufferSize ?? 50_000;
36
- const startedAt = Date.now();
37
- const ignoreMatcher = buildIgnoreMatcher(options.ignoreList);
38
- const stripUrlPrefixes = options.location?.stripUrlPrefixes;
39
- // Resolve artifacts configuration
40
- const artifactsBaseDir = resolveArtifactsBaseDir(options.artifacts?.base, watcherId);
41
- const logsEnabled = options.artifacts?.logs?.enabled === true;
42
- const logsDir = path.join(artifactsBaseDir, 'logs');
43
- const includeTimestamps = options.artifacts?.logs?.includeTimestamps ?? false;
44
- const maxFiles = resolveMaxFiles(options.artifacts?.logs?.maxFiles);
45
- // Network capture is opt-in (disabled by default) and supported in both direct CDP and extension mode.
46
- const netEnabled = options.net?.enabled === true;
47
- // Page console logging (default: minimal)
48
- const pageConsoleLogging = options.pageConsoleLogging ?? 'minimal';
49
- const events = new Emittery();
50
- const buffer = new LogBuffer(bufferSize);
51
- const netBuffer = netEnabled ? new NetBuffer(netBufferSize) : null;
52
- let closing = false;
53
- let readyForShutdown = false;
54
- let shutdownRequested = false;
55
- let closeOnce = null;
56
- let cdpStatus = { attached: false, target: null };
57
- const fileLogger = logsEnabled
58
- ? new WatcherFileLogger({
59
- watcherId,
60
- startedAt,
61
- logsDir,
62
- chrome: sourceMode === 'cdp' ? chrome : undefined,
63
- match: options.match,
64
- maxFiles,
65
- includeTimestamps,
66
- buildFilename: options.artifacts?.logs?.buildFilename,
67
- })
68
- : null;
69
- const record = {
70
- id: watcherId,
71
- host,
72
- port,
73
- pid: process.pid,
74
- cwd: process.cwd(),
75
- startedAt,
76
- updatedAt: Date.now(),
77
- match: sourceMode === 'cdp' ? options.match : undefined,
78
- chrome: sourceMode === 'cdp' ? chrome : undefined,
79
- includeTimestamps,
80
- source: sourceMode,
81
- };
82
- // Create session handle for CDP mode (used by network capture, tracing, etc.)
83
- const sessionHandle = createCdpSessionHandle();
84
- // Emulation controller (shared across CDP and extension modes)
85
- const emulationController = createEmulationController();
86
- // Throttle controller (CPU, network, cache — shared across CDP and extension modes)
87
- const throttleController = createThrottleController();
88
- const logToPageConsole = (message) => {
89
- if (pageConsoleLogging === 'none') {
90
- return;
91
- }
92
- if (!sourceHandle?.session.isAttached()) {
93
- return;
94
- }
95
- const fullMessage = `[ARGUS] ${watcherId} :: ${message}`;
96
- queueMicrotask(() => {
97
- sourceHandle?.session
98
- .sendAndWait('Runtime.evaluate', {
99
- expression: `console.log(${JSON.stringify(fullMessage)})`,
100
- silent: true,
101
- })
102
- .catch(() => { });
103
- });
104
- };
105
- validatePageIndicatorOptions(options.pageIndicator);
106
- const indicatorEnabled = options.pageIndicator?.enabled === true;
107
- let indicatorController = null;
108
- let indicatorAttachedAt = null;
109
- if (indicatorEnabled) {
110
- indicatorController = createPageIndicatorController(options.pageIndicator);
111
- }
112
- const updateCdpStatus = (status) => {
113
- const prevAttached = cdpStatus.attached;
114
- cdpStatus = status;
115
- if (status.attached && !prevAttached) {
116
- const url = status.target?.url ?? 'unknown';
117
- logToPageConsole(`attached (url=${url})`);
118
- void events.emit('cdpAttached', {
119
- ts: Date.now(),
120
- watcherId,
121
- target: status.target,
122
- });
123
- return;
124
- }
125
- if (!status.attached && prevAttached) {
126
- void events.emit('cdpDetached', {
127
- ts: Date.now(),
128
- watcherId,
129
- target: status.target,
130
- reason: status.reason ?? 'unknown',
131
- });
132
- }
133
- };
134
- const buildIndicatorInfo = (target) => ({
135
- watcherId,
136
- watcherHost: host,
137
- watcherPort: record.port,
138
- watcherPid: process.pid,
139
- targetTitle: target?.title ?? null,
140
- targetUrl: target?.url ?? null,
141
- attachedAt: indicatorAttachedAt ?? Date.now(),
142
- });
143
- const onIndicatorNavigation = (session, info) => {
144
- if (!indicatorController) {
145
- return;
146
- }
147
- indicatorController.onNavigation(session, buildIndicatorInfo({ title: null, url: info.url }));
148
- };
149
- const onIndicatorLoad = () => {
150
- indicatorController?.reinstall();
151
- };
152
- const getIndicatorSession = () => sourceHandle.pageSession ?? sourceHandle.session;
153
- const onIndicatorAttach = (session, target) => {
154
- if (!indicatorController) {
155
- return;
156
- }
157
- indicatorAttachedAt = Date.now();
158
- indicatorController.onAttach(session, {
159
- id: target.id,
160
- title: target.title,
161
- url: target.url,
162
- type: target.type ?? 'page',
163
- parentId: target.parentId ?? null,
164
- webSocketDebuggerUrl: '',
165
- }, buildIndicatorInfo({ title: target.title, url: target.url }));
166
- };
167
- const maybeInjectOnAttach = async (session, target) => {
168
- if (!options.inject?.script) {
169
- return;
170
- }
171
- if (!session.isAttached()) {
172
- return;
173
- }
174
- const trimmedScript = options.inject.script.trim();
175
- if (trimmedScript === '') {
176
- console.warn(`[Watcher] Inject script is empty for watcher ${record.id}. Skipping.`);
177
- return;
178
- }
179
- const attachedAt = Date.now();
180
- const exposeArgus = options.inject.exposeArgus ?? true;
181
- const argusPayload = exposeArgus
182
- ? {
183
- watcherId: record.id,
184
- watcherHost: record.host,
185
- watcherPort: record.port,
186
- watcherPid: record.pid,
187
- attachedAt,
188
- target: {
189
- title: target.title ?? null,
190
- url: target.url ?? null,
191
- type: target.type ?? 'page',
192
- parentId: target.parentId ?? null,
193
- },
194
- }
195
- : null;
196
- const expression = buildInjectExpression(trimmedScript, argusPayload);
197
- try {
198
- await session.sendAndWait('Page.addScriptToEvaluateOnNewDocument', { source: expression });
199
- }
200
- catch (error) {
201
- console.warn(`[Watcher] Failed to register inject script for watcher ${record.id}: ${formatError(error)}`);
202
- }
203
- try {
204
- await session.sendAndWait('Runtime.evaluate', { expression, silent: true });
205
- }
206
- catch (error) {
207
- console.warn(`[Watcher] Failed to run inject script for watcher ${record.id}: ${formatError(error)}`);
208
- }
209
- };
210
- const handleSourceLog = (event) => {
211
- buffer.add(event);
212
- fileLogger?.writeEvent(event);
213
- };
214
- const handlePageNavigation = (info) => {
215
- fileLogger?.rotate(info);
216
- onIndicatorNavigation(getIndicatorSession(), info);
217
- runtimeEditor?.reset();
218
- };
219
- const handlePageIntl = (info) => {
220
- fileLogger?.setPageIntl(info);
221
- };
222
- const handleSourceAttach = async (session, target) => {
223
- runtimeEditor?.rebind();
224
- await emulationController.onAttach(session);
225
- await throttleController.onAttach(session);
226
- await networkCapture?.onAttached();
227
- onIndicatorAttach(session, target);
228
- await maybeInjectOnAttach(session, target);
229
- };
230
- const handleTargetChanged = (session, target) => {
231
- onIndicatorAttach(session, target);
232
- };
233
- const handleSourceDetach = (reason) => {
234
- runtimeEditor?.rebind();
235
- networkCapture?.onDetached();
236
- indicatorController?.onDetach();
237
- if (reason != null) {
238
- traceRecorder.onDetached(reason);
239
- }
240
- };
241
- // Create the appropriate source based on mode
242
- let sourceHandle;
243
- let networkCapture = null;
244
- let traceRecorder;
245
- let screenshotter;
246
- let runtimeEditor;
247
- if (sourceMode === 'extension') {
248
- // Extension mode
249
- sourceHandle = createExtensionSource({
250
- events: {
251
- onLog: handleSourceLog,
252
- onStatus: updateCdpStatus,
253
- onPageNavigation: handlePageNavigation,
254
- onPageLoad: onIndicatorLoad,
255
- onPageIntl: handlePageIntl,
256
- onAttach: handleSourceAttach,
257
- onTargetChanged: handleTargetChanged,
258
- onDetach: () => {
259
- handleSourceDetach();
260
- },
261
- },
262
- watcherId,
263
- watcherHost: host,
264
- watcherPort: record.port,
265
- ignoreMatcher: ignoreMatcher ? (url) => ignoreMatcher.matches(url) : null,
266
- stripUrlPrefixes,
267
- });
268
- networkCapture = netBuffer ? createNetworkCapture({ session: sourceHandle.pageSession ?? sourceHandle.session, buffer: netBuffer }) : null;
269
- // Create trace/screenshot with proxy session
270
- traceRecorder = createTraceRecorder({ session: sourceHandle.session, artifactsDir: artifactsBaseDir });
271
- screenshotter = createScreenshotter({ session: sourceHandle.session, artifactsDir: artifactsBaseDir });
272
- runtimeEditor = createRuntimeEditor(sourceHandle.session);
273
- }
274
- else {
275
- // CDP mode
276
- networkCapture = netBuffer ? createNetworkCapture({ session: sessionHandle.session, buffer: netBuffer }) : null;
277
- traceRecorder = createTraceRecorder({ session: sessionHandle.session, artifactsDir: artifactsBaseDir });
278
- screenshotter = createScreenshotter({ session: sessionHandle.session, artifactsDir: artifactsBaseDir });
279
- runtimeEditor = createRuntimeEditor(sessionHandle.session);
280
- sourceHandle = createCdpSource({
281
- chrome,
282
- match: options.match,
283
- sessionHandle,
284
- events: {
285
- onLog: handleSourceLog,
286
- onStatus: updateCdpStatus,
287
- onPageNavigation: handlePageNavigation,
288
- onPageLoad: onIndicatorLoad,
289
- onPageIntl: handlePageIntl,
290
- onAttach: handleSourceAttach,
291
- onDetach: (reason) => {
292
- handleSourceDetach(reason);
293
- },
294
- },
295
- watcherId,
296
- ignoreMatcher: ignoreMatcher ? (url) => ignoreMatcher.matches(url) : null,
297
- stripUrlPrefixes,
298
- });
299
- }
300
- const server = await startHttpServer({
301
- host,
302
- port,
303
- buffer,
304
- netBuffer,
305
- getWatcher: () => record,
306
- getCdpStatus: () => cdpStatus,
307
- pageCdpSession: sourceHandle.pageSession ?? sourceHandle.session,
308
- cdpSession: sourceHandle.session,
309
- traceRecorder,
310
- screenshotter,
311
- runtimeEditor,
312
- emulationController,
313
- throttleController,
314
- // Extension mode endpoints
315
- sourceHandle: sourceMode === 'extension' ? sourceHandle : undefined,
316
- onRequest: (event) => {
317
- if (pageConsoleLogging === 'full') {
318
- logToPageConsole(`http ${event.endpoint}`);
319
- }
320
- void events.emit('httpRequested', {
321
- ...event,
322
- watcherId,
323
- });
324
- },
325
- onShutdown: () => {
326
- if (!readyForShutdown || !closeOnce) {
327
- shutdownRequested = true;
328
- return;
329
- }
330
- void closeOnce();
331
- },
332
- });
333
- record.port = server.port;
334
- sourceHandle.syncWatcherInfo?.({
335
- watcherId,
336
- watcherHost: host,
337
- watcherPort: record.port,
338
- watcherPid: process.pid,
339
- });
340
- await announceWatcher(record);
341
- const heartbeat = startRegistryHeartbeat(() => record, options.heartbeatMs ?? 15_000);
342
- closeOnce = async () => {
343
- if (closing) {
344
- return;
345
- }
346
- closing = true;
347
- heartbeat.stop();
348
- indicatorController?.stop();
349
- if (cdpStatus.attached) {
350
- logToPageConsole('detached (reason=watcher_stopped)');
351
- }
352
- await sourceHandle.stop();
353
- await fileLogger?.close();
354
- traceRecorder.onDetached('watcher_stopped');
355
- await server.close();
356
- await removeWatcher(record.id);
357
- events.clearListeners();
358
- };
359
- readyForShutdown = true;
360
- if (shutdownRequested) {
361
- void closeOnce();
362
- }
363
- return {
364
- watcher: record,
365
- events,
366
- close: async () => {
367
- await closeOnce?.();
368
- },
369
- };
370
- };
371
- const resolveArtifactsBaseDir = (base, watcherId) => {
372
- if (base !== undefined && base !== null) {
373
- if (typeof base !== 'string' || base.trim() === '') {
374
- throw new Error('artifacts.base must be a non-empty string when provided');
375
- }
376
- return path.resolve(base);
377
- }
378
- return path.join(os.tmpdir(), 'argus', watcherId);
379
- };
380
- const resolveMaxFiles = (maxFiles) => {
381
- if (maxFiles === undefined) {
382
- return 5;
383
- }
384
- if (!Number.isInteger(maxFiles) || maxFiles < 1) {
385
- throw new Error('artifacts.logs.maxFiles must be an integer >= 1');
386
- }
387
- return maxFiles;
388
- };
389
- const buildInjectExpression = (script, argusPayload) => {
390
- const lines = ['(() => {'];
391
- if (argusPayload) {
392
- lines.push(`window.__ARGUS__ = ${JSON.stringify(argusPayload)};`);
393
- }
394
- lines.push(`const __argusScript = ${JSON.stringify(script)};`);
395
- lines.push('const __argusFn = new Function(__argusScript);');
396
- lines.push('__argusFn();');
397
- lines.push('})();');
398
- return lines.join('\n');
399
- };
400
- const formatError = (error) => {
401
- if (!error) {
402
- return 'Unknown error';
403
- }
404
- if (error instanceof Error) {
405
- return error.message;
406
- }
407
- return String(error);
14
+ return createWatcherHandle(options, watcherId);
408
15
  };
409
16
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,QAAQ,MAAM,UAAU,CAAA;AAC/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AA6J9D;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,OAA4B,EAA0B,EAAE;IAC1F,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAA;IAC1C,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,sBAAsB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAC1D,OAAO,mBAAmB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;AAC/C,CAAC,CAAA"}
@@ -0,0 +1,21 @@
1
+ import type { ExtensionSession } from '../native-messaging/session-manager.js';
2
+ import type { CdpSessionHandle, CdpTargetContext } from '../cdp/connection.js';
3
+ export type DelegatingSessionController = {
4
+ rebind: () => void;
5
+ dispose: () => void;
6
+ };
7
+ type CreateDelegatingSessionOptions = {
8
+ getCurrentSession: () => ExtensionSession | null;
9
+ requireCurrentSession: () => ExtensionSession;
10
+ getTargetContext: () => CdpTargetContext;
11
+ mapParams?: (method: string, params?: Record<string, unknown>) => Record<string, unknown> | undefined;
12
+ };
13
+ /**
14
+ * Keep a stable session handle while the underlying extension tab attachment changes over time.
15
+ */
16
+ export declare const createDelegatingSession: (options: CreateDelegatingSessionOptions) => {
17
+ session: CdpSessionHandle;
18
+ controller: DelegatingSessionController;
19
+ };
20
+ export {};
21
+ //# sourceMappingURL=extension-delegating-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-delegating-session.d.ts","sourceRoot":"","sources":["../../src/sources/extension-delegating-session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAA;AAC9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAS9E,MAAM,MAAM,2BAA2B,GAAG;IACzC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,OAAO,EAAE,MAAM,IAAI,CAAA;CACnB,CAAA;AAED,KAAK,8BAA8B,GAAG;IACrC,iBAAiB,EAAE,MAAM,gBAAgB,GAAG,IAAI,CAAA;IAChD,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;IAC7C,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;IACxC,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAA;CACrG,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,uBAAuB,GACnC,SAAS,8BAA8B,KACrC;IAAE,OAAO,EAAE,gBAAgB,CAAC;IAAC,UAAU,EAAE,2BAA2B,CAAA;CAsDtE,CAAA"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Keep a stable session handle while the underlying extension tab attachment changes over time.
3
+ */
4
+ export const createDelegatingSession = (options) => {
5
+ const subscriptions = new Set();
6
+ const rebindSubscriptions = () => {
7
+ // Delegating sessions are created before a tab may be attached, so event listeners
8
+ // must follow the active extension session instead of binding once and going stale.
9
+ for (const subscription of subscriptions) {
10
+ subscription.unbind();
11
+ const currentSession = options.getCurrentSession();
12
+ if (!currentSession) {
13
+ continue;
14
+ }
15
+ subscription.off = currentSession.handle.onEvent(subscription.method, subscription.handler);
16
+ }
17
+ };
18
+ const disposeSubscriptions = () => {
19
+ for (const subscription of subscriptions) {
20
+ subscription.unbind();
21
+ }
22
+ subscriptions.clear();
23
+ };
24
+ const controller = {
25
+ rebind: rebindSubscriptions,
26
+ dispose: disposeSubscriptions,
27
+ };
28
+ const session = {
29
+ isAttached: () => options.getCurrentSession()?.handle.isAttached() ?? false,
30
+ sendAndWait: async (method, params, commandOptions) => {
31
+ const currentSession = options.requireCurrentSession();
32
+ const targetContext = options.getTargetContext();
33
+ const nextParams = options.mapParams ? options.mapParams(method, params) : params;
34
+ const nextOptions = targetContext.kind === 'frame' && targetContext.sessionId
35
+ ? { ...(commandOptions ?? {}), sessionId: targetContext.sessionId }
36
+ : commandOptions;
37
+ return currentSession.handle.sendAndWait(method, nextParams, nextOptions);
38
+ },
39
+ onEvent: (method, handler) => {
40
+ const subscription = createDelegatingEventSubscription(method, handler);
41
+ subscriptions.add(subscription);
42
+ controller.rebind();
43
+ return () => {
44
+ subscription.unbind();
45
+ subscriptions.delete(subscription);
46
+ };
47
+ },
48
+ getTargetContext: options.getTargetContext,
49
+ };
50
+ controller.rebind();
51
+ return { session, controller };
52
+ };
53
+ const createDelegatingEventSubscription = (method, handler) => ({
54
+ method,
55
+ handler,
56
+ off: null,
57
+ unbind() {
58
+ this.off?.();
59
+ this.off = null;
60
+ },
61
+ });
62
+ //# sourceMappingURL=extension-delegating-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-delegating-session.js","sourceRoot":"","sources":["../../src/sources/extension-delegating-session.ts"],"names":[],"mappings":"AAsBA;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACtC,OAAuC,EACkC,EAAE;IAC3E,MAAM,aAAa,GAAG,IAAI,GAAG,EAA+B,CAAA;IAC5D,MAAM,mBAAmB,GAAG,GAAS,EAAE;QACtC,mFAAmF;QACnF,oFAAoF;QACpF,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;YAC1C,YAAY,CAAC,MAAM,EAAE,CAAA;YACrB,MAAM,cAAc,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAA;YAClD,IAAI,CAAC,cAAc,EAAE,CAAC;gBACrB,SAAQ;YACT,CAAC;YACD,YAAY,CAAC,GAAG,GAAG,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,CAAA;QAC5F,CAAC;IACF,CAAC,CAAA;IAED,MAAM,oBAAoB,GAAG,GAAS,EAAE;QACvC,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;YAC1C,YAAY,CAAC,MAAM,EAAE,CAAA;QACtB,CAAC;QACD,aAAa,CAAC,KAAK,EAAE,CAAA;IACtB,CAAC,CAAA;IAED,MAAM,UAAU,GAAgC;QAC/C,MAAM,EAAE,mBAAmB;QAC3B,OAAO,EAAE,oBAAoB;KAC7B,CAAA;IAED,MAAM,OAAO,GAAqB;QACjC,UAAU,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE,IAAI,KAAK;QAC3E,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,EAAE;YACrD,MAAM,cAAc,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAA;YACtD,MAAM,aAAa,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAA;YAChD,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;YACjF,MAAM,WAAW,GAChB,aAAa,CAAC,IAAI,KAAK,OAAO,IAAI,aAAa,CAAC,SAAS;gBACxD,CAAC,CAAC,EAAE,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,aAAa,CAAC,SAAS,EAAE;gBACnE,CAAC,CAAC,cAAc,CAAA;YAClB,OAAO,cAAc,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,CAAA;QAC1E,CAAC;QACD,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;YAC5B,MAAM,YAAY,GAAG,iCAAiC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;YACvE,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;YAC/B,UAAU,CAAC,MAAM,EAAE,CAAA;YAEnB,OAAO,GAAG,EAAE;gBACX,YAAY,CAAC,MAAM,EAAE,CAAA;gBACrB,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;YACnC,CAAC,CAAA;QACF,CAAC;QACD,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;KAC1C,CAAA;IAED,UAAU,CAAC,MAAM,EAAE,CAAA;IACnB,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAA;AAC/B,CAAC,CAAA;AAED,MAAM,iCAAiC,GAAG,CAAC,MAAc,EAAE,OAAmD,EAA+B,EAAE,CAAC,CAAC;IAChJ,MAAM;IACN,OAAO;IACP,GAAG,EAAE,IAAI;IACT,MAAM;QACL,IAAI,CAAC,GAAG,EAAE,EAAE,CAAA;QACZ,IAAI,CAAC,GAAG,GAAG,IAAI,CAAA;IAChB,CAAC;CACD,CAAC,CAAA"}
@@ -0,0 +1,21 @@
1
+ import type { ExtensionSession } from '../native-messaging/session-manager.js';
2
+ import type { CdpSourceEvents } from './types.js';
3
+ import { type ExtensionFrameState } from './extension-frame-state.js';
4
+ type RegisterExtensionSessionEventsOptions = {
5
+ session: ExtensionSession;
6
+ events: CdpSourceEvents;
7
+ ignoreMatcher?: ((url: string) => boolean) | null;
8
+ stripUrlPrefixes?: string[];
9
+ getOrCreateFrameState: (tabId: number) => ExtensionFrameState;
10
+ reconcileTargetSelection: (session: ExtensionSession) => boolean;
11
+ removeFrame: (tabId: number, frameId: string) => void;
12
+ refreshFrameTitle: (session: ExtensionSession, frameId: string, contextId?: number) => Promise<void>;
13
+ emitTargetChanged: (session: ExtensionSession) => void;
14
+ setCurrentSession: (session: ExtensionSession) => void;
15
+ };
16
+ /**
17
+ * Subscribe to extension-backed CDP events and funnel them back through the shared frame-state helpers.
18
+ */
19
+ export declare const registerExtensionSessionEventHandlers: ({ session, events, ignoreMatcher, stripUrlPrefixes, getOrCreateFrameState, reconcileTargetSelection, removeFrame, refreshFrameTitle, emitTargetChanged, setCurrentSession, }: RegisterExtensionSessionEventsOptions) => void;
20
+ export {};
21
+ //# sourceMappingURL=extension-session-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-session-events.d.ts","sourceRoot":"","sources":["../../src/sources/extension-session-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAA;AAC9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAqC,KAAK,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAGxG,KAAK,qCAAqC,GAAG;IAC5C,OAAO,EAAE,gBAAgB,CAAA;IACzB,MAAM,EAAE,eAAe,CAAA;IACvB,aAAa,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,IAAI,CAAA;IACjD,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,qBAAqB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,mBAAmB,CAAA;IAC7D,wBAAwB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAA;IAChE,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACrD,iBAAiB,EAAE,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACpG,iBAAiB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAA;IACtD,iBAAiB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAA;CACtD,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,qCAAqC,GAAI,8KAWnD,qCAAqC,KAAG,IA2G1C,CAAA"}
@@ -0,0 +1,103 @@
1
+ import { parseExecutionContext, parseFrame } from './extension-frame-state.js';
2
+ import { toConsoleEvent, toExceptionEvent } from './extension-log-events.js';
3
+ /**
4
+ * Subscribe to extension-backed CDP events and funnel them back through the shared frame-state helpers.
5
+ */
6
+ export const registerExtensionSessionEventHandlers = ({ session, events, ignoreMatcher, stripUrlPrefixes, getOrCreateFrameState, reconcileTargetSelection, removeFrame, refreshFrameTitle, emitTargetChanged, setCurrentSession, }) => {
7
+ session.handle.onEvent('Runtime.executionContextCreated', (params, meta) => {
8
+ const context = parseExecutionContext(params);
9
+ if (!context?.isDefault || !context.frameId) {
10
+ return;
11
+ }
12
+ const state = getOrCreateFrameState(session.tabId);
13
+ state.executionContexts.set(context.frameId, context.id);
14
+ const frame = state.frames.get(context.frameId);
15
+ if (frame) {
16
+ frame.sessionId = meta.sessionId ?? null;
17
+ }
18
+ void refreshFrameTitle(session, context.frameId, context.id);
19
+ reconcileTargetSelection(session);
20
+ });
21
+ session.handle.onEvent('Runtime.executionContextsCleared', () => {
22
+ const state = getOrCreateFrameState(session.tabId);
23
+ state.executionContexts.clear();
24
+ state.pendingTitleLoads.clear();
25
+ });
26
+ session.handle.onEvent('Runtime.executionContextDestroyed', (params) => {
27
+ const record = params;
28
+ if (record.executionContextId == null) {
29
+ return;
30
+ }
31
+ const state = getOrCreateFrameState(session.tabId);
32
+ for (const [frameId, contextId] of state.executionContexts.entries()) {
33
+ if (contextId === record.executionContextId) {
34
+ state.executionContexts.delete(frameId);
35
+ state.pendingTitleLoads.delete(frameId);
36
+ }
37
+ }
38
+ });
39
+ session.handle.onEvent('Page.frameNavigated', (params, meta) => {
40
+ const frame = parseFrame(params);
41
+ if (!frame) {
42
+ return;
43
+ }
44
+ const state = getOrCreateFrameState(session.tabId);
45
+ state.frames.set(frame.frameId, frame);
46
+ frame.sessionId = meta.sessionId ?? null;
47
+ if (!frame.parentFrameId) {
48
+ if (!meta.sessionId) {
49
+ state.topFrameId = frame.frameId;
50
+ session.url = frame.url;
51
+ }
52
+ else if (state.topFrameId == null) {
53
+ state.topFrameId = frame.parentFrameId;
54
+ }
55
+ }
56
+ else if (state.executionContexts.has(frame.frameId)) {
57
+ void refreshFrameTitle(session, frame.frameId);
58
+ }
59
+ setCurrentSession(session);
60
+ if (!frame.parentFrameId && !meta.sessionId) {
61
+ events.onPageNavigation?.({ url: frame.url, title: session.title ?? null });
62
+ }
63
+ if (reconcileTargetSelection(session)) {
64
+ return;
65
+ }
66
+ if ((!frame.parentFrameId && state.activeFrameId == null) || state.activeFrameId === frame.frameId) {
67
+ emitTargetChanged(session);
68
+ }
69
+ });
70
+ session.handle.onEvent('Page.frameAttached', (params, meta) => {
71
+ const record = params;
72
+ if (!record.frameId) {
73
+ return;
74
+ }
75
+ const state = getOrCreateFrameState(session.tabId);
76
+ state.frames.set(record.frameId, {
77
+ frameId: record.frameId,
78
+ parentFrameId: record.parentFrameId ?? state.topFrameId ?? null,
79
+ url: '',
80
+ title: null,
81
+ sessionId: meta.sessionId ?? null,
82
+ });
83
+ reconcileTargetSelection(session);
84
+ });
85
+ session.handle.onEvent('Page.frameDetached', (params) => {
86
+ const record = params;
87
+ if (!record.frameId) {
88
+ return;
89
+ }
90
+ removeFrame(session.tabId, record.frameId);
91
+ reconcileTargetSelection(session);
92
+ });
93
+ session.handle.onEvent('Page.domContentEventFired', () => {
94
+ events.onPageLoad?.();
95
+ });
96
+ session.handle.onEvent('Runtime.consoleAPICalled', (params) => {
97
+ events.onLog(toConsoleEvent(params, session, { ignoreMatcher, stripUrlPrefixes }));
98
+ });
99
+ session.handle.onEvent('Runtime.exceptionThrown', (params) => {
100
+ events.onLog(toExceptionEvent(params, session, { ignoreMatcher, stripUrlPrefixes }));
101
+ });
102
+ };
103
+ //# sourceMappingURL=extension-session-events.js.map