@jobshimo/browser-link 0.27.1 → 0.28.1

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 (52) hide show
  1. package/dist/activity/db.d.ts +27 -0
  2. package/dist/activity/db.js +98 -0
  3. package/dist/activity/db.js.map +1 -0
  4. package/dist/activity/extract.d.ts +32 -0
  5. package/dist/activity/extract.js +126 -0
  6. package/dist/activity/extract.js.map +1 -0
  7. package/dist/activity/paths.d.ts +16 -0
  8. package/dist/activity/paths.js +24 -0
  9. package/dist/activity/paths.js.map +1 -0
  10. package/dist/activity/queries.d.ts +100 -0
  11. package/dist/activity/queries.js +286 -0
  12. package/dist/activity/queries.js.map +1 -0
  13. package/dist/activity/types.d.ts +119 -0
  14. package/dist/activity/types.js +41 -0
  15. package/dist/activity/types.js.map +1 -0
  16. package/dist/bridge/ws-bridge.d.ts +18 -1
  17. package/dist/bridge/ws-bridge.js +107 -0
  18. package/dist/bridge/ws-bridge.js.map +1 -1
  19. package/dist/cdp/inpage/deep-query.d.ts +1 -1
  20. package/dist/cdp/inpage/deep-query.js +1 -1
  21. package/dist/cdp/inpage/dom-helpers.d.ts +1 -1
  22. package/dist/cdp/inpage/dom-helpers.js +1 -1
  23. package/dist/cli.js +24 -0
  24. package/dist/cli.js.map +1 -1
  25. package/dist/commands/activity.d.ts +11 -0
  26. package/dist/commands/activity.js +347 -0
  27. package/dist/commands/activity.js.map +1 -0
  28. package/dist/config.d.ts +26 -0
  29. package/dist/config.js.map +1 -1
  30. package/dist/extension/activity.d.ts +201 -0
  31. package/dist/extension/activity.html +662 -0
  32. package/dist/extension/activity.js +555 -0
  33. package/dist/extension/activity.js.map +1 -0
  34. package/dist/extension/background.js +146 -0
  35. package/dist/extension/background.js.map +1 -1
  36. package/dist/extension/inpage/deep-query.d.ts +1 -1
  37. package/dist/extension/inpage/deep-query.js +1 -1
  38. package/dist/extension/inpage/dom-helpers.d.ts +1 -1
  39. package/dist/extension/inpage/dom-helpers.js +1 -1
  40. package/dist/extension/manifest.json +3 -2
  41. package/dist/extension/popup.html +58 -0
  42. package/dist/extension/popup.js +11 -0
  43. package/dist/extension/popup.js.map +1 -1
  44. package/dist/messages.d.ts +80 -2
  45. package/dist/server.js +30 -0
  46. package/dist/server.js.map +1 -1
  47. package/dist/tools/browser-definitions.js +50 -2
  48. package/dist/tools/browser-definitions.js.map +1 -1
  49. package/dist/tools/browser-dispatch.d.ts +34 -7
  50. package/dist/tools/browser-dispatch.js +107 -1
  51. package/dist/tools/browser-dispatch.js.map +1 -1
  52. package/package.json +2 -2
@@ -0,0 +1,555 @@
1
+ "use strict";
2
+ /**
3
+ * The Activity window.
4
+ *
5
+ * A dedicated extension page rather than a section of the 320px popup, for one
6
+ * reason that is not cosmetic: a Chrome action popup closes the moment it loses
7
+ * focus, so it physically cannot be watched while an agent works. This window
8
+ * stays open, and can be parked on a second monitor while the agent runs.
9
+ *
10
+ * It owns no data. Every row comes from the server's `activity.db` through the
11
+ * background service worker (`activityQuery` → WS `activity.query`), so what
12
+ * this page shows survives closing the browser, and closing this page loses
13
+ * nothing.
14
+ */
15
+ /** How often the live tail asks for new rows. Two seconds reads as immediate
16
+ * to a human watching an agent work, and costs one small indexed SELECT — far
17
+ * cheaper than the render it usually skips because nothing changed. */
18
+ const TAIL_INTERVAL_MS = 2_000;
19
+ /** Rows held in the page. Beyond this the oldest are dropped from the DOM (not
20
+ * from the trail — they are still on disk and in any export). A table that
21
+ * grows without bound is how a panel left open overnight eats a gigabyte. */
22
+ const MAX_ROWS_IN_VIEW = 1_000;
23
+ /** Resolve a required element, failing loudly at load rather than producing a
24
+ * page that silently does nothing when the template and this script drift. */
25
+ const el = (id) => {
26
+ const node = document.getElementById(id);
27
+ if (!node)
28
+ throw new Error(`activity: missing #${id}`);
29
+ return node;
30
+ };
31
+ const ui = {
32
+ live: el('live'),
33
+ refresh: el('refresh'),
34
+ exportBtn: el('export'),
35
+ agent: el('filter-agent'),
36
+ tool: el('filter-tool'),
37
+ failed: el('filter-failed'),
38
+ text: el('filter-text'),
39
+ reset: el('filter-reset'),
40
+ count: el('count'),
41
+ table: el('table'),
42
+ rows: el('rows'),
43
+ state: el('state'),
44
+ stateTitle: el('state-title'),
45
+ stateDetail: el('state-detail'),
46
+ status: el('status'),
47
+ usageRows: el('usage-rows'),
48
+ usageSize: el('usage-size'),
49
+ usageSpan: el('usage-span'),
50
+ usageMeter: el('usage-fill').parentElement,
51
+ usageFill: el('usage-fill'),
52
+ usageCap: el('usage-cap'),
53
+ purgeToggle: el('purge-toggle'),
54
+ purgePanel: el('purge-panel'),
55
+ purgeFrom: el('purge-from'),
56
+ purgeTo: el('purge-to'),
57
+ purgeSummary: el('purge-summary'),
58
+ purgeCheck: el('purge-check'),
59
+ purgeRun: el('purge-run'),
60
+ purgeCancel: el('purge-cancel'),
61
+ preset30d: el('purge-preset-30d'),
62
+ preset7d: el('purge-preset-7d'),
63
+ presetAll: el('purge-preset-all'),
64
+ };
65
+ let records = [];
66
+ let lastStats = null;
67
+ /** Rows the last dry run said the current range would delete. Cleared whenever
68
+ * the range changes, so the red button can never act on a stale count — the
69
+ * user must always be shown a number for the range they are actually about to
70
+ * purge. */
71
+ let pendingPurgeCount = null;
72
+ let live = true;
73
+ let tailTimer = null;
74
+ /** Tools seen so far, so the filter offers exactly what exists rather than a
75
+ * hardcoded list that goes stale when a tool is added. */
76
+ const knownTools = new Set();
77
+ function ask(query) {
78
+ return new Promise((resolve) => {
79
+ chrome.runtime.sendMessage({ action: 'activityQuery', query }, (reply) => {
80
+ if (chrome.runtime.lastError) {
81
+ resolve({ ok: false, error: chrome.runtime.lastError.message ?? 'unreachable' });
82
+ return;
83
+ }
84
+ resolve(reply);
85
+ });
86
+ });
87
+ }
88
+ /** Server-side filters. The free-text box is deliberately NOT one of them: it
89
+ * filters what is already loaded, so typing feels instant and never costs a
90
+ * round trip. The dropdowns are, because they change which rows exist. */
91
+ function serverFilters() {
92
+ const filters = { limit: 300 };
93
+ if (ui.agent.value)
94
+ filters.agent = ui.agent.value;
95
+ if (ui.tool.value)
96
+ filters.tool = ui.tool.value;
97
+ if (ui.failed.getAttribute('aria-pressed') === 'true')
98
+ filters.outcome = 'error';
99
+ return filters;
100
+ }
101
+ /* ------------------------------------------------------------- time ------
102
+ *
103
+ * ONE RULE, no exceptions:
104
+ *
105
+ * The trail stores UTC. The user only ever sees, and only ever types,
106
+ * their own local time.
107
+ *
108
+ * Everything the user reads goes through `toLocale*`. Everything the user
109
+ * types is a local calendar day and is converted to a UTC instant here, at
110
+ * this boundary, before it reaches the server. Nothing downstream of this
111
+ * file thinks about timezones at all.
112
+ *
113
+ * Exports are the one deliberate exception and are NOT a display surface:
114
+ * they keep raw UTC, because a file handed to another machine or another
115
+ * agent must not carry this browser's timezone baked into it.
116
+ */
117
+ /** A local calendar day (`2026-07-31` from an `<input type="date">`) widened
118
+ * to the UTC instant at that day's local start or local end.
119
+ *
120
+ * Widening matters: without it, a purge "to Jul 31" would resolve to midnight
121
+ * and silently spare everything that happened during Jul 31. */
122
+ function localDayToUtc(day, edge) {
123
+ // No `Z` and no offset — the runtime parses this as LOCAL time, which is
124
+ // exactly what the date picker meant.
125
+ const suffix = edge === 'start' ? 'T00:00:00.000' : 'T23:59:59.999';
126
+ return new Date(`${day}${suffix}`).toISOString();
127
+ }
128
+ /** A Date as the local calendar day the picker expects (`YYYY-MM-DD`).
129
+ * NOT `toISOString().slice(0, 10)` — that is the UTC day, which is the wrong
130
+ * one for anybody whose offset has already rolled the date over. */
131
+ function toLocalDay(date) {
132
+ const pad = (n) => String(n).padStart(2, '0');
133
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
134
+ }
135
+ /** Full local timestamp, for the hover on a relative time. */
136
+ function formatExact(iso) {
137
+ return new Date(iso).toLocaleString();
138
+ }
139
+ /** Bytes as a human reads them. Binary units because that is what a file
140
+ * manager will show for the same file, and two numbers that disagree about the
141
+ * same thing are worse than either alone. */
142
+ function formatBytes(bytes) {
143
+ if (bytes < 1024)
144
+ return `${bytes} B`;
145
+ const units = ['KB', 'MB', 'GB'];
146
+ let value = bytes / 1024;
147
+ let unit = 0;
148
+ while (value >= 1024 && unit < units.length - 1) {
149
+ value /= 1024;
150
+ unit += 1;
151
+ }
152
+ return `${value < 10 ? value.toFixed(1) : Math.round(value)} ${units[unit]}`;
153
+ }
154
+ function formatDay(iso) {
155
+ if (iso === null)
156
+ return '—';
157
+ return new Date(iso).toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
158
+ }
159
+ /**
160
+ * Repaint the always-visible usage strip.
161
+ *
162
+ * Called from every reply — reads and purges alike — so the numbers can never
163
+ * be stale relative to what is on screen beneath them.
164
+ */
165
+ function renderStats(stats) {
166
+ lastStats = stats;
167
+ ui.usageRows.textContent = stats.rows.toLocaleString();
168
+ ui.usageSize.textContent = formatBytes(stats.bytes);
169
+ ui.usageSpan.textContent = formatDay(stats.oldest_at);
170
+ const ratio = stats.max_rows > 0 ? stats.rows / stats.max_rows : 0;
171
+ ui.usageFill.style.width = `${Math.min(100, Math.round(ratio * 100))}%`;
172
+ ui.usageCap.textContent = `${stats.rows.toLocaleString()} / ${stats.max_rows.toLocaleString()}`;
173
+ // Amber past 80%: the trail is close to dropping its oldest entries, which
174
+ // is the one moment the user genuinely needs to decide between purging and
175
+ // exporting first.
176
+ ui.usageMeter.classList.toggle('warn', ratio >= 0.8);
177
+ }
178
+ function formatTime(iso) {
179
+ const then = new Date(iso).getTime();
180
+ const secondsAgo = Math.round((Date.now() - then) / 1000);
181
+ if (secondsAgo < 5)
182
+ return 'just now';
183
+ if (secondsAgo < 60)
184
+ return `${secondsAgo}s ago`;
185
+ if (secondsAgo < 3600)
186
+ return `${Math.floor(secondsAgo / 60)}m ago`;
187
+ return new Date(iso).toLocaleTimeString();
188
+ }
189
+ /** What the action acted on, in priority order. A selector says the most; a
190
+ * payload is next; the URL is the fallback for tools that take neither. */
191
+ function targetOf(record) {
192
+ return record.selector ?? record.payload ?? record.url ?? '—';
193
+ }
194
+ function matchesText(record, needle) {
195
+ if (needle === '')
196
+ return true;
197
+ const hay = [record.tool, record.selector, record.url, record.payload, record.error, record.agent]
198
+ .filter((v) => typeof v === 'string')
199
+ .join(' ')
200
+ .toLowerCase();
201
+ return hay.includes(needle);
202
+ }
203
+ function buildRow(record) {
204
+ const tr = document.createElement('tr');
205
+ if (record.outcome === 'error')
206
+ tr.className = 'failed';
207
+ const when = document.createElement('td');
208
+ when.className = 'when';
209
+ when.textContent = formatTime(record.at);
210
+ when.title = formatExact(record.at);
211
+ const agent = document.createElement('td');
212
+ if (record.agent) {
213
+ const badge = document.createElement('span');
214
+ badge.className = 'agent';
215
+ badge.textContent = record.agent;
216
+ if (record.agentPid !== null)
217
+ badge.title = `pid ${record.agentPid}`;
218
+ agent.append(badge);
219
+ }
220
+ else {
221
+ agent.textContent = '—';
222
+ }
223
+ const tool = document.createElement('td');
224
+ tool.className = 'tool';
225
+ tool.textContent = record.tool;
226
+ if (record.flowId) {
227
+ const tag = document.createElement('span');
228
+ tag.className = 'flow-tag';
229
+ tag.textContent = 'flow';
230
+ tag.title = record.flowId;
231
+ tool.append(tag);
232
+ }
233
+ const target = document.createElement('td');
234
+ const main = document.createElement('span');
235
+ main.className = 'target';
236
+ main.textContent = targetOf(record);
237
+ target.append(main);
238
+ // Show the payload as a second line only when it is not already the target,
239
+ // so a `type` row reads "#search / hunter2" without repeating itself.
240
+ if (record.payload !== null && record.payload !== targetOf(record)) {
241
+ const payload = document.createElement('span');
242
+ payload.className = 'payload';
243
+ payload.textContent = record.payload;
244
+ target.append(payload);
245
+ }
246
+ if (record.url !== null && record.url !== targetOf(record)) {
247
+ const url = document.createElement('span');
248
+ url.className = 'url';
249
+ url.textContent = record.url;
250
+ target.append(url);
251
+ }
252
+ const outcome = document.createElement('td');
253
+ outcome.className = `outcome ${record.outcome}`;
254
+ outcome.textContent =
255
+ record.outcome === 'ok' ? `ok · ${record.durationMs}ms` : (record.error ?? 'error');
256
+ if (record.outcome === 'error' && record.error)
257
+ outcome.title = record.error;
258
+ tr.append(when, agent, tool, target, outcome);
259
+ return tr;
260
+ }
261
+ function showState(title, detail = '') {
262
+ ui.stateTitle.textContent = title;
263
+ ui.stateDetail.textContent = detail;
264
+ ui.state.classList.remove('hidden');
265
+ ui.table.classList.add('hidden');
266
+ }
267
+ function render() {
268
+ const needle = ui.text.value.trim().toLowerCase();
269
+ const visible = records.filter((r) => matchesText(r, needle));
270
+ if (visible.length === 0) {
271
+ showState(records.length === 0 ? 'No activity yet' : 'Nothing matches this filter', records.length === 0
272
+ ? 'Actions appear here the moment an agent touches a connected tab.'
273
+ : 'Try clearing the search box or the dropdowns.');
274
+ ui.count.textContent = records.length === 0 ? '' : `0 of ${records.length} shown`;
275
+ return;
276
+ }
277
+ ui.state.classList.add('hidden');
278
+ ui.table.classList.remove('hidden');
279
+ const fragment = document.createDocumentFragment();
280
+ for (const record of visible)
281
+ fragment.append(buildRow(record));
282
+ ui.rows.replaceChildren(fragment);
283
+ ui.count.textContent =
284
+ visible.length === records.length
285
+ ? `${visible.length} actions`
286
+ : `${visible.length} of ${records.length} shown`;
287
+ }
288
+ function refreshAgentOptions(agents) {
289
+ const current = ui.agent.value;
290
+ const options = ['<option value="">All agents</option>'];
291
+ for (const { agent, count } of agents) {
292
+ options.push(`<option value="${escapeAttr(agent)}">${escapeHtml(agent)} (${count})</option>`);
293
+ }
294
+ ui.agent.innerHTML = options.join('');
295
+ ui.agent.value = current;
296
+ }
297
+ function refreshToolOptions() {
298
+ const current = ui.tool.value;
299
+ const options = ['<option value="">All tools</option>'];
300
+ for (const tool of [...knownTools].sort()) {
301
+ options.push(`<option value="${escapeAttr(tool)}">${escapeHtml(tool)}</option>`);
302
+ }
303
+ ui.tool.innerHTML = options.join('');
304
+ ui.tool.value = current;
305
+ }
306
+ /** The two option lists are the only place this page builds markup from a
307
+ * string, and both values are server-owned. Escaped anyway: an agent label is
308
+ * self-declared text, and "it cannot contain a quote today" is not a security
309
+ * boundary. */
310
+ function escapeHtml(value) {
311
+ return value.replace(/[&<>]/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;' })[c] ?? c);
312
+ }
313
+ function escapeAttr(value) {
314
+ return escapeHtml(value).replace(/"/g, '&quot;');
315
+ }
316
+ async function load() {
317
+ const reply = await ask(serverFilters());
318
+ if (!reply.ok) {
319
+ if (reply.error === 'not-connected') {
320
+ showState('No connected tab', 'The trail lives in the browser-link server. Connect a tab from the popup to read it.');
321
+ }
322
+ else {
323
+ showState('Could not read the trail', reply.error);
324
+ }
325
+ ui.status.textContent = `error: ${reply.error}`;
326
+ return;
327
+ }
328
+ records = reply.records;
329
+ renderStats(reply.stats);
330
+ for (const record of records)
331
+ knownTools.add(record.tool);
332
+ refreshAgentOptions(reply.agents);
333
+ refreshToolOptions();
334
+ ui.status.textContent = `${reply.total} actions recorded`;
335
+ render();
336
+ }
337
+ /** Tail: ask only for what is newer than the newest row we hold, then prepend.
338
+ * Cheaper than reloading the page of 300 on every tick, and it keeps the
339
+ * user's scroll position where they left it. */
340
+ async function tail() {
341
+ const newest = records.at(0)?.id;
342
+ if (newest === undefined) {
343
+ await load();
344
+ return;
345
+ }
346
+ const reply = await ask({ ...serverFilters(), since_id: newest });
347
+ if (!reply.ok)
348
+ return;
349
+ renderStats(reply.stats);
350
+ if (reply.records.length === 0)
351
+ return;
352
+ for (const record of reply.records)
353
+ knownTools.add(record.tool);
354
+ records = [...reply.records, ...records].slice(0, MAX_ROWS_IN_VIEW);
355
+ refreshAgentOptions(reply.agents);
356
+ refreshToolOptions();
357
+ ui.status.textContent = `${reply.total} actions recorded`;
358
+ render();
359
+ }
360
+ function setLive(next) {
361
+ live = next;
362
+ ui.live.setAttribute('aria-pressed', String(live));
363
+ if (tailTimer !== null)
364
+ clearInterval(tailTimer);
365
+ tailTimer = live ? setInterval(() => void tail(), TAIL_INTERVAL_MS) : null;
366
+ }
367
+ /**
368
+ * Download what is on screen as NDJSON.
369
+ *
370
+ * NDJSON rather than JSON because a trail is append-only and line-oriented:
371
+ * it greps, it tails, it diffs, and another agent can stream it without
372
+ * parsing the whole file. Exports exactly the filtered view, because the
373
+ * filter is how the user said what they wanted.
374
+ *
375
+ * Note this is the VISIBLE page. `browser-link activity export` is the tool
376
+ * for the complete trail — and the one with `--redact`.
377
+ */
378
+ function exportVisible() {
379
+ const needle = ui.text.value.trim().toLowerCase();
380
+ const visible = records.filter((r) => matchesText(r, needle));
381
+ const body = visible.map((r) => JSON.stringify(r)).join('\n');
382
+ const blob = new Blob([`${body}\n`], { type: 'application/x-ndjson' });
383
+ const url = URL.createObjectURL(blob);
384
+ const stamp = new Date().toISOString().replace(/[:.]/g, '-');
385
+ chrome.downloads.download({ url, filename: `browser-link-activity-${stamp}.ndjson` }, () => {
386
+ // Revoke once Chrome has taken the bytes; leaking the object URL would
387
+ // pin the whole export in memory for the life of the window.
388
+ URL.revokeObjectURL(url);
389
+ });
390
+ }
391
+ /* ---------------------------------------------------------------- purge --
392
+ *
393
+ * Two-step by construction: the red button stays disabled until a dry run has
394
+ * put a real number in front of the user for the exact range they picked.
395
+ * Changing either date wipes that number and disables it again.
396
+ */
397
+ function purgeAsk(input) {
398
+ return new Promise((resolve) => {
399
+ chrome.runtime.sendMessage({ action: 'activityPurge', ...input }, (reply) => {
400
+ if (chrome.runtime.lastError) {
401
+ resolve({ ok: false, error: chrome.runtime.lastError.message ?? 'unreachable' });
402
+ return;
403
+ }
404
+ resolve(reply);
405
+ });
406
+ });
407
+ }
408
+ /** A `<input type="date">` gives a local calendar day; the trail stores UTC
409
+ * instants. Widen each end to cover the whole day the user pointed at, or a
410
+ * purge "to Aug 14" would silently spare everything that happened on Aug 14. */
411
+ function rangeFromInputs() {
412
+ const from = ui.purgeFrom.value;
413
+ const to = ui.purgeTo.value;
414
+ return {
415
+ ...(from ? { from: localDayToUtc(from, 'start') } : {}),
416
+ ...(to ? { to: localDayToUtc(to, 'end') } : {}),
417
+ };
418
+ }
419
+ function describeRange() {
420
+ const from = ui.purgeFrom.value;
421
+ const to = ui.purgeTo.value;
422
+ if (!from && !to)
423
+ return 'the entire trail';
424
+ if (from && to)
425
+ return `${from} → ${to}`;
426
+ if (from)
427
+ return `everything from ${from} onwards`;
428
+ return `everything up to ${to}`;
429
+ }
430
+ /** Invalidate any resolved count. Called on every change to the range. */
431
+ function resetPurgeConfirmation() {
432
+ pendingPurgeCount = null;
433
+ ui.purgeRun.disabled = true;
434
+ ui.purgeRun.textContent = 'Delete permanently';
435
+ // Restate what is currently stored next to the range being chosen — deciding
436
+ // what to delete is much easier with the total in the same sentence.
437
+ const current = lastStats === null
438
+ ? ''
439
+ : ` Currently ${lastStats.rows.toLocaleString()} actions, ${formatBytes(lastStats.bytes)}.`;
440
+ ui.purgeSummary.textContent = `Ready to check: ${describeRange()}.${current}`;
441
+ }
442
+ function setDaysAgo(days) {
443
+ const cutoff = new Date(Date.now() - days * 86_400_000);
444
+ ui.purgeFrom.value = '';
445
+ // Purging "older than N days" is an open-ended range with only an upper
446
+ // bound — the oldest row is wherever the trail happens to start.
447
+ ui.purgeTo.value = toLocalDay(cutoff);
448
+ resetPurgeConfirmation();
449
+ }
450
+ ui.purgeToggle.addEventListener('click', () => {
451
+ const opening = ui.purgePanel.hasAttribute('hidden');
452
+ if (opening)
453
+ ui.purgePanel.removeAttribute('hidden');
454
+ else
455
+ ui.purgePanel.setAttribute('hidden', '');
456
+ resetPurgeConfirmation();
457
+ });
458
+ ui.purgeCancel.addEventListener('click', () => {
459
+ ui.purgePanel.setAttribute('hidden', '');
460
+ });
461
+ ui.preset30d.addEventListener('click', () => {
462
+ setDaysAgo(30);
463
+ });
464
+ ui.preset7d.addEventListener('click', () => {
465
+ setDaysAgo(7);
466
+ });
467
+ ui.presetAll.addEventListener('click', () => {
468
+ ui.purgeFrom.value = '';
469
+ ui.purgeTo.value = '';
470
+ resetPurgeConfirmation();
471
+ });
472
+ ui.purgeFrom.addEventListener('change', resetPurgeConfirmation);
473
+ ui.purgeTo.addEventListener('change', resetPurgeConfirmation);
474
+ ui.purgeCheck.addEventListener('click', () => {
475
+ ui.purgeCheck.disabled = true;
476
+ ui.purgeSummary.textContent = 'Counting…';
477
+ void purgeAsk({ ...rangeFromInputs(), dryRun: true }).then((reply) => {
478
+ ui.purgeCheck.disabled = false;
479
+ if (!reply.ok) {
480
+ ui.purgeSummary.textContent = `Could not check: ${reply.error}`;
481
+ return;
482
+ }
483
+ renderStats(reply.stats);
484
+ pendingPurgeCount = reply.removed;
485
+ if (reply.removed === 0) {
486
+ ui.purgeSummary.textContent = `Nothing to delete in ${describeRange()}.`;
487
+ ui.purgeRun.disabled = true;
488
+ return;
489
+ }
490
+ ui.purgeSummary.textContent = `This will permanently delete ${reply.removed.toLocaleString()} of ${reply.stats.rows.toLocaleString()} actions (${describeRange()}).`;
491
+ ui.purgeRun.disabled = false;
492
+ ui.purgeRun.textContent = `Delete ${reply.removed.toLocaleString()} permanently`;
493
+ });
494
+ });
495
+ ui.purgeRun.addEventListener('click', () => {
496
+ if (pendingPurgeCount === null || pendingPurgeCount === 0)
497
+ return;
498
+ // Native confirm on purpose: it is modal, it cannot be missed, and this is
499
+ // the last moment before rows stop existing.
500
+ const ok = window.confirm(`Permanently delete ${pendingPurgeCount.toLocaleString()} actions (${describeRange()})?\n\nThis cannot be undone.`);
501
+ if (!ok)
502
+ return;
503
+ ui.purgeRun.disabled = true;
504
+ ui.purgeRun.textContent = 'Deleting…';
505
+ ui.purgeSummary.textContent = 'Deleting and reclaiming disk space…';
506
+ void purgeAsk(rangeFromInputs()).then((reply) => {
507
+ ui.purgeRun.textContent = 'Delete permanently';
508
+ if (!reply.ok) {
509
+ ui.purgeSummary.textContent = `Purge failed: ${reply.error}`;
510
+ return;
511
+ }
512
+ renderStats(reply.stats);
513
+ ui.purgeSummary.textContent = `Deleted ${reply.removed.toLocaleString()} actions. ${reply.stats.rows.toLocaleString()} left, ${formatBytes(reply.stats.bytes)} on disk.`;
514
+ resetPurgeConfirmation();
515
+ // The rows on screen may no longer exist — reload rather than leave the
516
+ // table showing what was just deleted.
517
+ records = [];
518
+ void load();
519
+ });
520
+ });
521
+ ui.live.addEventListener('click', () => {
522
+ setLive(ui.live.getAttribute('aria-pressed') !== 'true');
523
+ });
524
+ ui.refresh.addEventListener('click', () => void load());
525
+ ui.exportBtn.addEventListener('click', exportVisible);
526
+ ui.failed.addEventListener('click', () => {
527
+ ui.failed.setAttribute('aria-pressed', String(ui.failed.getAttribute('aria-pressed') !== 'true'));
528
+ void load();
529
+ });
530
+ ui.agent.addEventListener('change', () => void load());
531
+ ui.tool.addEventListener('change', () => void load());
532
+ ui.text.addEventListener('input', render);
533
+ ui.reset.addEventListener('click', () => {
534
+ ui.agent.value = '';
535
+ ui.tool.value = '';
536
+ ui.text.value = '';
537
+ ui.failed.setAttribute('aria-pressed', 'false');
538
+ void load();
539
+ });
540
+ // Stop tailing while the window is hidden. A background window polling every
541
+ // two seconds forever is a battery cost with no reader.
542
+ document.addEventListener('visibilitychange', () => {
543
+ if (document.hidden) {
544
+ if (tailTimer !== null)
545
+ clearInterval(tailTimer);
546
+ tailTimer = null;
547
+ }
548
+ else if (live) {
549
+ setLive(true);
550
+ void tail();
551
+ }
552
+ });
553
+ setLive(true);
554
+ void load();
555
+ //# sourceMappingURL=activity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.js","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"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"}