tabctl 0.6.0-rc.10 → 0.6.0-rc.12

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.
@@ -783,7 +783,12 @@
783
783
  var RECONNECT_ALARM = "tabctl-reconnect";
784
784
  var KEEPALIVE_INTERVAL_MINUTES = 1;
785
785
  var BROWSER_STATE_SYNC_DEBOUNCE_MS = 750;
786
- var ACTIVE_PAGE_CACHE_DEBOUNCE_MS = 1e3;
786
+ var ACTIVE_PAGE_CACHE_LOADING_RETRY_MS = 100;
787
+ var ACTIVE_PAGE_CACHE_SETTLING_RETRY_MS = 150;
788
+ var ACTIVE_PAGE_CACHE_FIRST_QUIESCENT_TIMEOUT_MS = 750;
789
+ var ACTIVE_PAGE_CACHE_FIRST_QUIESCENT_SAMPLE_MS = 75;
790
+ var ACTIVE_PAGE_CACHE_FIRST_LOADING_MAX_ATTEMPTS = 300;
791
+ var ACTIVE_PAGE_CACHE_FIRST_SETTLING_MAX_ATTEMPTS = 200;
787
792
  var ACTIVE_PAGE_CACHE_TIMEOUT_MS = 5e3;
788
793
  var MAX_PAGE_HTML_CHARS = 10 * 1024 * 1024;
789
794
  var ACTIVE_PAGE_CACHE_MAX_HTML_CHARS = MAX_PAGE_HTML_CHARS;
@@ -795,6 +800,10 @@
795
800
  var ACTIVE_PAGE_CACHE_STATUS_TIMEOUT_MS = 3e4;
796
801
  var CACHE_AVAILABLE_BADGE_TEXT = "C";
797
802
  var CACHE_AVAILABLE_BADGE_COLOR = "#2da44e";
803
+ var CACHE_WAITING_BADGE_TEXT = "W";
804
+ var CACHE_WAITING_BADGE_COLOR = "#bf8700";
805
+ var CACHE_ERROR_BADGE_TEXT = "E";
806
+ var CACHE_ERROR_BADGE_COLOR = "#cf222e";
798
807
  var RECONNECT_INITIAL_DELAY_MS = 250;
799
808
  var RECONNECT_MAX_DELAY_MS = 3e4;
800
809
  var RECONNECT_ALARM_MIN_DELAY_MS = 3e4;
@@ -832,7 +841,16 @@
832
841
  lastCapturedKey: null,
833
842
  lastQuiescentCapturedKey: null,
834
843
  lastQuiescentCapturedAt: 0,
835
- statusRequests: /* @__PURE__ */ new Map()
844
+ statusRequests: /* @__PURE__ */ new Map(),
845
+ states: /* @__PURE__ */ new Map()
846
+ };
847
+ var ACTIVE_PAGE_CACHE_STATE_DETAILS = {
848
+ checking: "checking status",
849
+ loading: "page still loading",
850
+ settling: "waiting for page settle",
851
+ capturing: "capture pending",
852
+ cached: "page cache available",
853
+ error: "capture failed"
836
854
  };
837
855
  function log(...args) {
838
856
  console.log("[tabctl]", ...args);
@@ -969,6 +987,9 @@
969
987
  function activePageCacheKey(tab, url) {
970
988
  return `${tab.id}:${url}`;
971
989
  }
990
+ function activePageCacheKeyForTabId(tabId, url) {
991
+ return `${tabId}:${url}`;
992
+ }
972
993
  function activePageCacheUrl(tab) {
973
994
  return tab.url || tab.pendingUrl || "";
974
995
  }
@@ -987,19 +1008,84 @@
987
1008
  log("clear cache indicator failed", { tabId, error });
988
1009
  }
989
1010
  }
990
- async function setCacheAvailableIndicator(tabId, expectedUrl) {
1011
+ async function setCacheBadgeIndicator(tabId, expectedUrl, text, color, title) {
991
1012
  try {
992
1013
  const tab = await chrome.tabs.get(tabId);
993
1014
  if (!isEligibleActivePageCacheTab(tab) || activePageCacheUrl(tab) !== expectedUrl) {
994
1015
  await clearCacheAvailableIndicator(tabId);
995
1016
  return;
996
1017
  }
997
- await chrome.action?.setBadgeBackgroundColor?.({ tabId, color: CACHE_AVAILABLE_BADGE_COLOR });
998
- await chrome.action?.setBadgeText?.({ tabId, text: CACHE_AVAILABLE_BADGE_TEXT });
999
- await chrome.action?.setTitle?.({ tabId, title: "Tab Control - page cache available" });
1018
+ await chrome.action?.setBadgeBackgroundColor?.({ tabId, color });
1019
+ await chrome.action?.setBadgeText?.({ tabId, text });
1020
+ await chrome.action?.setTitle?.({ tabId, title });
1000
1021
  } catch (error) {
1001
- log("set cache indicator failed", { tabId, error });
1022
+ log("set cache indicator failed", { tabId, text, error });
1023
+ }
1024
+ }
1025
+ async function setCacheAvailableIndicator(tabId, expectedUrl) {
1026
+ await setCacheBadgeIndicator(
1027
+ tabId,
1028
+ expectedUrl,
1029
+ CACHE_AVAILABLE_BADGE_TEXT,
1030
+ CACHE_AVAILABLE_BADGE_COLOR,
1031
+ "Tab Control - page cache available"
1032
+ );
1033
+ }
1034
+ async function setCacheWaitingIndicator(tabId, expectedUrl, detail) {
1035
+ await setCacheBadgeIndicator(
1036
+ tabId,
1037
+ expectedUrl,
1038
+ CACHE_WAITING_BADGE_TEXT,
1039
+ CACHE_WAITING_BADGE_COLOR,
1040
+ `Tab Control - waiting for page cache (${detail})`
1041
+ );
1042
+ }
1043
+ async function setCacheErrorIndicator(tabId, expectedUrl, detail) {
1044
+ await setCacheBadgeIndicator(
1045
+ tabId,
1046
+ expectedUrl,
1047
+ CACHE_ERROR_BADGE_TEXT,
1048
+ CACHE_ERROR_BADGE_COLOR,
1049
+ `Tab Control - page cache error (${detail})`
1050
+ );
1051
+ }
1052
+ function hasPendingActivePageCacheWork(tabId, url) {
1053
+ const key = activePageCacheKeyForTabId(tabId, url);
1054
+ return activePageCache.inFlightKeys.has(key) || activePageCache.pending?.key === key || activePageCache.quiescentPending?.key === key;
1055
+ }
1056
+ function setActivePageCacheState(tabId, url, kind, detail = ACTIVE_PAGE_CACHE_STATE_DETAILS[kind]) {
1057
+ activePageCache.states.set(activePageCacheKeyForTabId(tabId, url), { kind, detail });
1058
+ }
1059
+ function activePageCacheState(tabId, url) {
1060
+ return activePageCache.states.get(activePageCacheKeyForTabId(tabId, url));
1061
+ }
1062
+ function clearActivePageCacheState(tabId, url) {
1063
+ activePageCache.states.delete(activePageCacheKeyForTabId(tabId, url));
1064
+ }
1065
+ function clearActivePageCacheStatesForTab(tabId) {
1066
+ const prefix = `${tabId}:`;
1067
+ for (const key of activePageCache.states.keys()) {
1068
+ if (key.startsWith(prefix)) {
1069
+ activePageCache.states.delete(key);
1070
+ }
1071
+ }
1072
+ }
1073
+ function clearPendingFirstActivePageCacheCapture(key) {
1074
+ if (activePageCache.pending?.key === key) {
1075
+ activePageCache.pending = null;
1076
+ }
1077
+ }
1078
+ function failFirstActivePageCacheCapture(pending, tab, url, detail) {
1079
+ clearPendingFirstActivePageCacheCapture(pending.key);
1080
+ setActivePageCacheState(tab.id, url, "error", detail);
1081
+ void setCacheErrorIndicator(tab.id, url, detail);
1082
+ void requestPageCacheStatusForTab(tab.id, `first-capture:${detail.replace(/\s+/g, "-")}`);
1083
+ }
1084
+ function waitingDetailForActivePageCacheState(state2) {
1085
+ if (state2?.kind === "checking" || state2?.kind === "loading" || state2?.kind === "settling" || state2?.kind === "capturing") {
1086
+ return state2.detail;
1002
1087
  }
1088
+ return null;
1003
1089
  }
1004
1090
  async function applyPageCacheStatus(tabId, expectedUrl, available) {
1005
1091
  try {
@@ -1007,10 +1093,31 @@
1007
1093
  if (activePageCacheUrl(tab) !== expectedUrl) {
1008
1094
  return;
1009
1095
  }
1010
- if (!isEligibleActivePageCacheTab(tab) || !available) {
1096
+ if (!isEligibleActivePageCacheTab(tab)) {
1011
1097
  await clearCacheAvailableIndicator(tabId);
1012
1098
  return;
1013
1099
  }
1100
+ if (!available) {
1101
+ const cacheState = activePageCacheState(tabId, expectedUrl);
1102
+ const waitingDetail = waitingDetailForActivePageCacheState(cacheState);
1103
+ if (waitingDetail) {
1104
+ await setCacheWaitingIndicator(tabId, expectedUrl, waitingDetail);
1105
+ return;
1106
+ }
1107
+ if (cacheState?.kind === "error") {
1108
+ await setCacheErrorIndicator(tabId, expectedUrl, cacheState.detail);
1109
+ return;
1110
+ }
1111
+ if (hasPendingActivePageCacheWork(tabId, expectedUrl)) {
1112
+ setActivePageCacheState(tabId, expectedUrl, "capturing");
1113
+ await setCacheWaitingIndicator(tabId, expectedUrl, ACTIVE_PAGE_CACHE_STATE_DETAILS.capturing);
1114
+ return;
1115
+ }
1116
+ clearActivePageCacheState(tabId, expectedUrl);
1117
+ await clearCacheAvailableIndicator(tabId);
1118
+ return;
1119
+ }
1120
+ setActivePageCacheState(tabId, expectedUrl, "cached");
1014
1121
  await setCacheAvailableIndicator(tabId, expectedUrl);
1015
1122
  } catch {
1016
1123
  await clearCacheAvailableIndicator(tabId);
@@ -1044,7 +1151,8 @@
1044
1151
  const port = state.port;
1045
1152
  if (!port) {
1046
1153
  connectNative();
1047
- void clearCacheAvailableIndicator(tab.id);
1154
+ setActivePageCacheState(tab.id, url, "checking", "native host reconnecting");
1155
+ void setCacheWaitingIndicator(tab.id, url, "native host reconnecting");
1048
1156
  return;
1049
1157
  }
1050
1158
  const id = nextActivePageCacheStatusId();
@@ -1096,7 +1204,7 @@
1096
1204
  }
1097
1205
  function isEligibleActivePageCacheTab(tab) {
1098
1206
  const url = activePageCacheUrl(tab);
1099
- return typeof tab.id === "number" && Boolean(url) && tab.incognito !== true && !browserState.incognitoTabIds.has(tab.id) && (typeof tab.windowId !== "number" || !browserState.incognitoWindowIds.has(tab.windowId)) && tab.discarded !== true && tab.status !== "loading" && isScriptableUrl(url);
1207
+ return typeof tab.id === "number" && Boolean(url) && tab.incognito !== true && !browserState.incognitoTabIds.has(tab.id) && (typeof tab.windowId !== "number" || !browserState.incognitoWindowIds.has(tab.windowId)) && tab.discarded !== true && isScriptableUrl(url);
1100
1208
  }
1101
1209
  function clearPendingActivePageCacheCapture() {
1102
1210
  if (activePageCache.timer) {
@@ -1135,6 +1243,17 @@
1135
1243
  }
1136
1244
  }, ACTIVE_PAGE_CACHE_QUIESCENT_DELAY_MS);
1137
1245
  }
1246
+ function scheduleFirstActivePageCacheRetry(pending, delayMs) {
1247
+ clearPendingActivePageCacheCapture();
1248
+ activePageCache.pending = pending;
1249
+ activePageCache.timer = setTimeout(() => {
1250
+ activePageCache.timer = null;
1251
+ const retry = activePageCache.pending;
1252
+ if (retry) {
1253
+ void captureFirstSettledActivePageCache(retry);
1254
+ }
1255
+ }, delayMs);
1256
+ }
1138
1257
  function scheduleActivePageCacheCapture(tab, reason) {
1139
1258
  if (!isEligibleActivePageCacheTab(tab)) {
1140
1259
  if (typeof tab.id === "number") {
@@ -1144,23 +1263,27 @@
1144
1263
  clearPendingQuiescentActivePageCacheCapture();
1145
1264
  return;
1146
1265
  }
1147
- requestPageCacheStatus(tab, reason);
1148
1266
  const url = activePageCacheUrl(tab);
1149
1267
  const key = activePageCacheKey(tab, url);
1268
+ if (tab.status === "loading") {
1269
+ setActivePageCacheState(tab.id, url, "loading");
1270
+ void setCacheWaitingIndicator(tab.id, url, ACTIVE_PAGE_CACHE_STATE_DETAILS.loading);
1271
+ if (activePageCache.pending?.key !== key) {
1272
+ scheduleFirstActivePageCacheRetry({ tabId: tab.id, reason, key, attempts: 0 }, ACTIVE_PAGE_CACHE_LOADING_RETRY_MS);
1273
+ }
1274
+ return;
1275
+ }
1276
+ setActivePageCacheState(tab.id, url, "checking");
1277
+ void setCacheWaitingIndicator(tab.id, url, ACTIVE_PAGE_CACHE_STATE_DETAILS.checking);
1278
+ requestPageCacheStatus(tab, reason);
1150
1279
  scheduleQuiescentActivePageCacheCapture(tab, reason, key);
1151
1280
  if (activePageCache.inFlightKeys.has(key) || activePageCache.lastCapturedKey === key) {
1152
1281
  return;
1153
1282
  }
1154
- clearPendingActivePageCacheCapture();
1155
- activePageCache.pending = { tab, reason, key };
1156
- activePageCache.timer = setTimeout(() => {
1157
- activePageCache.timer = null;
1158
- const pending = activePageCache.pending;
1159
- activePageCache.pending = null;
1160
- if (pending) {
1161
- void captureActivePageCache(pending.tab, pending.reason, pending.key);
1162
- }
1163
- }, ACTIVE_PAGE_CACHE_DEBOUNCE_MS);
1283
+ if (activePageCache.pending?.key === key) {
1284
+ return;
1285
+ }
1286
+ scheduleFirstActivePageCacheRetry({ tabId: tab.id, reason, key, attempts: 0 }, 0);
1164
1287
  }
1165
1288
  async function scheduleActivePageCacheCaptureForTab(tabId, reason) {
1166
1289
  try {
@@ -1195,6 +1318,83 @@
1195
1318
  return null;
1196
1319
  }
1197
1320
  }
1321
+ async function getPageCacheOpenTabs() {
1322
+ const tabs = await chrome.tabs.query({});
1323
+ return tabs.filter((tab) => typeof tab.id === "number").filter((tab) => tab.incognito !== true).map((tab) => ({ tabId: tab.id, url: activePageCacheUrl(tab) })).filter((tab) => tab.url.length > 0 && isScriptableUrl(tab.url));
1324
+ }
1325
+ async function captureFirstSettledActivePageCache(pending) {
1326
+ if (activePageCache.inFlightKeys.has(pending.key) || activePageCache.lastCapturedKey === pending.key) {
1327
+ if (activePageCache.pending?.key === pending.key) {
1328
+ activePageCache.pending = null;
1329
+ }
1330
+ return;
1331
+ }
1332
+ const tab = await currentActivePageCacheTab(pending.tabId, pending.key);
1333
+ if (!tab) {
1334
+ if (activePageCache.pending?.key === pending.key) {
1335
+ activePageCache.pending = null;
1336
+ }
1337
+ return;
1338
+ }
1339
+ const tabUrl = activePageCacheUrl(tab);
1340
+ if (tab.status === "loading") {
1341
+ setActivePageCacheState(tab.id, tabUrl, "loading");
1342
+ void setCacheWaitingIndicator(tab.id, tabUrl, ACTIVE_PAGE_CACHE_STATE_DETAILS.loading);
1343
+ if (pending.attempts < ACTIVE_PAGE_CACHE_FIRST_LOADING_MAX_ATTEMPTS) {
1344
+ scheduleFirstActivePageCacheRetry(
1345
+ { ...pending, attempts: pending.attempts + 1 },
1346
+ ACTIVE_PAGE_CACHE_LOADING_RETRY_MS
1347
+ );
1348
+ } else {
1349
+ failFirstActivePageCacheCapture(pending, tab, tabUrl, "loading attempts exhausted");
1350
+ }
1351
+ return;
1352
+ }
1353
+ setActivePageCacheState(tab.id, tabUrl, "settling");
1354
+ void setCacheWaitingIndicator(tab.id, tabUrl, ACTIVE_PAGE_CACHE_STATE_DETAILS.settling);
1355
+ const probe = await content.probePageQuiescence(
1356
+ tab.id,
1357
+ ACTIVE_PAGE_CACHE_FIRST_QUIESCENT_TIMEOUT_MS,
1358
+ ACTIVE_PAGE_CACHE_FIRST_QUIESCENT_SAMPLE_MS
1359
+ );
1360
+ if (activePageCache.pending?.key !== pending.key) {
1361
+ return;
1362
+ }
1363
+ if (!probe.quiet) {
1364
+ if (probe.error || probe.documentReadyState === null) {
1365
+ failFirstActivePageCacheCapture(
1366
+ pending,
1367
+ tab,
1368
+ tabUrl,
1369
+ probe.reason || "page settle probe failed"
1370
+ );
1371
+ return;
1372
+ }
1373
+ const loading = probe.documentReadyState !== "interactive" && probe.documentReadyState !== "complete";
1374
+ setActivePageCacheState(tab.id, tabUrl, loading ? "loading" : "settling");
1375
+ void setCacheWaitingIndicator(
1376
+ tab.id,
1377
+ tabUrl,
1378
+ loading ? ACTIVE_PAGE_CACHE_STATE_DETAILS.loading : ACTIVE_PAGE_CACHE_STATE_DETAILS.settling
1379
+ );
1380
+ if (pending.attempts < ACTIVE_PAGE_CACHE_FIRST_SETTLING_MAX_ATTEMPTS) {
1381
+ scheduleFirstActivePageCacheRetry(
1382
+ { ...pending, attempts: pending.attempts + 1 },
1383
+ loading ? ACTIVE_PAGE_CACHE_LOADING_RETRY_MS : ACTIVE_PAGE_CACHE_SETTLING_RETRY_MS
1384
+ );
1385
+ } else {
1386
+ failFirstActivePageCacheCapture(
1387
+ pending,
1388
+ tab,
1389
+ tabUrl,
1390
+ loading ? "loading attempts exhausted" : "settling attempts exhausted"
1391
+ );
1392
+ }
1393
+ return;
1394
+ }
1395
+ clearPendingFirstActivePageCacheCapture(pending.key);
1396
+ await captureActivePageCache(tab, pending.reason, pending.key);
1397
+ }
1198
1398
  async function rescheduleQuiescentActivePageCacheCapture(pending) {
1199
1399
  if (pending.attempts >= 2 || isQuiescentCaptureCoolingDown(pending.key)) {
1200
1400
  return;
@@ -1221,6 +1421,9 @@
1221
1421
  if (!tab) {
1222
1422
  return;
1223
1423
  }
1424
+ const tabUrl = activePageCacheUrl(tab);
1425
+ setActivePageCacheState(tab.id, tabUrl, "settling");
1426
+ void setCacheWaitingIndicator(tab.id, tabUrl, ACTIVE_PAGE_CACHE_STATE_DETAILS.settling);
1224
1427
  const probe = await content.probePageQuiescence(
1225
1428
  tab.id,
1226
1429
  ACTIVE_PAGE_CACHE_QUIESCENT_TIMEOUT_MS,
@@ -1241,7 +1444,7 @@
1241
1444
  connectNative();
1242
1445
  return false;
1243
1446
  }
1244
- if (!isEligibleActivePageCacheTab(tab) || activePageCache.inFlightKeys.has(key)) {
1447
+ if (!isEligibleActivePageCacheTab(tab) || tab.status === "loading" || activePageCache.inFlightKeys.has(key)) {
1245
1448
  return false;
1246
1449
  }
1247
1450
  activePageCache.inFlightKeys.add(key);
@@ -1250,8 +1453,42 @@
1250
1453
  if (!captureTab) {
1251
1454
  return false;
1252
1455
  }
1456
+ const captureUrl = activePageCacheUrl(captureTab);
1457
+ if (captureTab.status === "loading") {
1458
+ setActivePageCacheState(captureTab.id, captureUrl, "loading");
1459
+ void setCacheWaitingIndicator(captureTab.id, captureUrl, ACTIVE_PAGE_CACHE_STATE_DETAILS.loading);
1460
+ scheduleFirstActivePageCacheRetry({ tabId: captureTab.id, reason, key, attempts: 0 }, ACTIVE_PAGE_CACHE_LOADING_RETRY_MS);
1461
+ return false;
1462
+ }
1463
+ setActivePageCacheState(captureTab.id, captureUrl, "capturing");
1464
+ void setCacheWaitingIndicator(captureTab.id, captureUrl, ACTIVE_PAGE_CACHE_STATE_DETAILS.capturing);
1253
1465
  const extraction = await content.extractPageHtml(captureTab.id, ACTIVE_PAGE_CACHE_TIMEOUT_MS, ACTIVE_PAGE_CACHE_MAX_HTML_CHARS);
1254
1466
  if (extraction.status !== "READ" || typeof extraction.html !== "string" || extraction.html.length === 0) {
1467
+ log("active page cache extraction not readable", {
1468
+ tabId: captureTab.id,
1469
+ reason,
1470
+ key,
1471
+ status: extraction.status,
1472
+ error: extraction.error,
1473
+ sourceHtmlChars: extraction.sourceHtmlChars,
1474
+ sourceTextChars: extraction.sourceTextChars,
1475
+ documentReadyState: extraction.documentReadyState,
1476
+ truncatedHtml: extraction.truncatedHtml
1477
+ });
1478
+ if (extraction.status === "NOT_LOADED") {
1479
+ const url = activePageCacheUrl(captureTab);
1480
+ setActivePageCacheState(captureTab.id, url, "loading");
1481
+ void setCacheWaitingIndicator(captureTab.id, url, ACTIVE_PAGE_CACHE_STATE_DETAILS.loading);
1482
+ scheduleFirstActivePageCacheRetry(
1483
+ { tabId: captureTab.id, reason, key, attempts: 0 },
1484
+ ACTIVE_PAGE_CACHE_LOADING_RETRY_MS
1485
+ );
1486
+ } else {
1487
+ const detail = typeof extraction.status === "string" ? extraction.status.toLowerCase().replace(/_/g, " ") : "capture failed";
1488
+ const url = activePageCacheUrl(captureTab);
1489
+ setActivePageCacheState(captureTab.id, url, "error", detail);
1490
+ void setCacheErrorIndicator(captureTab.id, url, detail);
1491
+ }
1255
1492
  void requestPageCacheStatusForTab(captureTab.id, `${reason}:capture-failed`);
1256
1493
  return false;
1257
1494
  }
@@ -1263,6 +1500,7 @@
1263
1500
  if (!port) {
1264
1501
  return false;
1265
1502
  }
1503
+ const openTabs = await getPageCacheOpenTabs();
1266
1504
  const id = nextActivePageCacheId();
1267
1505
  trackPageCacheStatusRequest(id, verifiedTab.id, activePageCacheUrl(verifiedTab));
1268
1506
  port.postMessage({
@@ -1272,6 +1510,7 @@
1272
1510
  data: {
1273
1511
  reason,
1274
1512
  capturedAt: Date.now(),
1513
+ openTabs,
1275
1514
  tab: {
1276
1515
  tabId: verifiedTab.id,
1277
1516
  windowId: verifiedTab.windowId,
@@ -1294,6 +1533,9 @@
1294
1533
  return true;
1295
1534
  } catch (error) {
1296
1535
  log("active page cache capture failed", { tabId: tab.id, reason, error });
1536
+ const url = activePageCacheUrl(tab);
1537
+ setActivePageCacheState(tab.id, url, "error", "capture exception");
1538
+ void setCacheErrorIndicator(tab.id, url, "capture exception");
1297
1539
  void requestPageCacheStatusForTab(tab.id, `${reason}:capture-error`);
1298
1540
  return false;
1299
1541
  } finally {
@@ -1417,6 +1659,7 @@
1417
1659
  changeInfo
1418
1660
  });
1419
1661
  if ("url" in changeInfo || "status" in changeInfo || "discarded" in changeInfo) {
1662
+ clearActivePageCacheStatesForTab(tabId);
1420
1663
  void clearCacheAvailableIndicator(tabId);
1421
1664
  }
1422
1665
  if (tab.active && ("url" in changeInfo || "status" in changeInfo || "discarded" in changeInfo)) {
@@ -1456,6 +1699,7 @@
1456
1699
  activePageCache.statusRequests.delete(requestId);
1457
1700
  }
1458
1701
  });
1702
+ clearActivePageCacheStatesForTab(tabId);
1459
1703
  void clearCacheAvailableIndicator(tabId);
1460
1704
  });
1461
1705
  chrome.tabs?.onActivated?.addListener((activeInfo) => {
@@ -22,5 +22,5 @@
22
22
  "action": {
23
23
  "default_title": "Tab Control"
24
24
  },
25
- "version_name": "0.6.0-rc.10"
25
+ "version_name": "0.6.0-rc.12"
26
26
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tabctl",
3
- "version": "0.6.0-rc.10",
3
+ "version": "0.6.0-rc.12",
4
4
  "description": "CLI tool to manage and analyze browser tabs",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -53,7 +53,7 @@
53
53
  "typescript": "^5.4.5"
54
54
  },
55
55
  "optionalDependencies": {
56
- "tabctl-win32-x64": "0.6.0-rc.10"
56
+ "tabctl-win32-x64": "0.6.0-rc.12"
57
57
  },
58
58
  "dependencies": {
59
59
  "normalize-url": "^8.1.1"