@@ -12,24 +12,65 @@ let activeTab;
12
12
const tabsObj = { } ;
13
13
// Will store Chrome web vital metrics and their corresponding values.
14
14
const metrics = { } ;
15
+
16
+ // Helper function to check if a URL is localhost
17
+ function isLocalhost ( url ) {
18
+ return url ?. startsWith ( 'http://localhost:' ) || url ?. startsWith ( 'https://localhost:' ) ;
19
+ }
20
+
21
+ // Helper function to find localhost tab
22
+ async function findLocalhostTab ( ) {
23
+ const tabs = await chrome . tabs . query ( { currentWindow : true } ) ;
24
+ return tabs . find ( ( tab ) => tab . url && isLocalhost ( tab . url ) ) ;
25
+ }
26
+
27
+ //keep alive functionality to address port disconnection issues
15
28
function setupKeepAlive ( ) {
16
- //ellie
17
- // Create an alarm that triggers every 4.9 minutes (under the 5-minute limit)
29
+ // Clear any existing keep-alive alarms to prevent duplicates
30
+ chrome . alarms . clear ( 'keepAlive' , ( wasCleared ) => {
31
+ if ( wasCleared ) {
32
+ console . log ( 'Cleared existing keep-alive alarm.' ) ;
33
+ }
34
+ } ) ;
35
+
36
+ // Create a new keep-alive alarm, we found .5 min to resolve the idle time port disconnection
18
37
chrome . alarms . create ( 'keepAlive' , { periodInMinutes : 0.5 } ) ;
19
38
39
+ // Log active alarms for debugging
40
+ chrome . alarms . getAll ( ( alarms ) => {
41
+ console . log (
42
+ 'Active alarms:' ,
43
+ alarms . map ( ( alarm ) => alarm . name ) ,
44
+ ) ;
45
+ } ) ;
46
+
47
+ // Listen for the keep-alive alarm
20
48
chrome . alarms . onAlarm . addListener ( ( alarm ) => {
21
49
if ( alarm . name === 'keepAlive' ) {
22
50
console . log ( 'Keep-alive alarm triggered.' ) ;
23
51
pingServiceWorker ( ) ;
24
52
}
25
53
} ) ;
26
54
}
55
+
27
56
// Ping the service worker to keep it alive
28
57
function pingServiceWorker ( ) {
29
- // Use a lightweight API call to keep the service worker active
30
- chrome . runtime . getPlatformInfo ( ( ) => {
31
- console . log ( 'Service worker pinged successfully' ) ;
32
- } ) ;
58
+ try {
59
+ chrome . runtime . getPlatformInfo ( ( ) => {
60
+ console . log ( 'Service worker pinged successfully.' ) ;
61
+ } ) ;
62
+ } catch ( error ) {
63
+ console . error ( 'Failed to ping service worker:' , error ) ;
64
+
65
+ // Fallback: Trigger an empty event to wake up the service worker
66
+ chrome . runtime . sendMessage ( { type : 'ping' } , ( response ) => {
67
+ if ( chrome . runtime . lastError ) {
68
+ console . error ( 'Fallback message failed:' , chrome . runtime . lastError . message ) ;
69
+ } else {
70
+ console . log ( 'Fallback message sent successfully:' , response ) ;
71
+ }
72
+ } ) ;
73
+ }
33
74
}
34
75
35
76
// function pruning the chrome ax tree and pulling the relevant properties
@@ -281,15 +322,24 @@ function changeCurrLocation(tabObj, rootNode, index, name) {
281
322
}
282
323
283
324
async function getActiveTab ( ) {
284
- return new Promise ( ( resolve , reject ) => {
285
- chrome . tabs . query ( { active : true , currentWindow : true } , function ( tabs ) {
286
- if ( tabs . length > 0 ) {
287
- resolve ( tabs [ 0 ] . id ) ;
288
- } else {
289
- reject ( new Error ( 'No active tab' ) ) ;
290
- }
291
- } ) ;
292
- } ) ;
325
+ try {
326
+ // First try to find a localhost tab
327
+ const localhostTab = await findLocalhostTab ( ) ;
328
+ if ( localhostTab ) {
329
+ return localhostTab . id ;
330
+ }
331
+
332
+ // Fallback to current active tab
333
+ const tabs = await chrome . tabs . query ( { active : true , currentWindow : true } ) ;
334
+ if ( tabs . length > 0 ) {
335
+ return tabs [ 0 ] . id ;
336
+ }
337
+
338
+ throw new Error ( 'No active tab' ) ;
339
+ } catch ( error ) {
340
+ console . error ( 'Error in getActiveTab:' , error ) ;
341
+ throw error ;
342
+ }
293
343
}
294
344
295
345
/*
@@ -366,7 +416,7 @@ chrome.runtime.onConnect.addListener(async (port) => {
366
416
} ) ;
367
417
}
368
418
369
- // Handles port disconnection by removing the disconnected port -ellie
419
+ // Handles port disconnection by removing the disconnected port
370
420
port . onDisconnect . addListener ( ( ) => {
371
421
const index = portsArr . indexOf ( port ) ;
372
422
if ( index !== - 1 ) {
@@ -656,7 +706,7 @@ chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
656
706
break ;
657
707
}
658
708
659
- // DUPLICATE SNAPSHOT CHECK -ellie
709
+ // DUPLICATE SNAPSHOT CHECK
660
710
const isDuplicateSnapshot = ( previous , incoming ) => {
661
711
if ( ! previous || ! incoming ) return false ;
662
712
const prevData = previous ?. componentData ;
@@ -772,26 +822,62 @@ chrome.tabs.onUpdated.addListener((tabId, changeInfo) => {
772
822
} ) ;
773
823
774
824
// When tab view is changed, put the tabId as the current tab
775
- chrome . tabs . onActivated . addListener ( ( info ) => {
825
+ chrome . tabs . onActivated . addListener ( async ( info ) => {
776
826
// Get info about the tab information from tabId
777
- chrome . tabs . get ( info . tabId , ( tab ) => {
778
- // Never set a reactime instance to the active tab
779
- if ( ! tab . pendingUrl ?. match ( '^chrome-extension' ) ) {
780
- activeTab = tab ;
781
-
782
- // Send messages to active ports about the tab change
783
- if ( portsArr . length > 0 ) {
784
- portsArr . forEach ( ( bg ) =>
785
- bg . postMessage ( {
786
- action : 'changeTab' ,
787
- payload : { tabId : tab . id , title : tab . title } ,
788
- } ) ,
789
- ) ;
827
+ try {
828
+ const tab = await chrome . tabs . get ( info . tabId ) ;
829
+
830
+ // Only update activeTab if:
831
+ // 1. It's not a Reactime extension tab
832
+ // 2. We don't already have a localhost tab being tracked
833
+ // 3. Or if it is a localhost tab (prioritize localhost)
834
+ if ( ! tab . url ?. match ( '^chrome-extension' ) ) {
835
+ if ( isLocalhost ( tab . url ) ) {
836
+ // Always prioritize localhost tabs
837
+ activeTab = tab ;
838
+ if ( portsArr . length > 0 ) {
839
+ portsArr . forEach ( ( bg ) =>
840
+ bg . postMessage ( {
841
+ action : 'changeTab' ,
842
+ payload : { tabId : tab . id , title : tab . title } ,
843
+ } ) ,
844
+ ) ;
845
+ }
846
+ } else if ( ! activeTab || ! isLocalhost ( activeTab . url ) ) {
847
+ // Only set non-localhost tab as active if we don't have a localhost tab
848
+ activeTab = tab ;
849
+ if ( portsArr . length > 0 ) {
850
+ portsArr . forEach ( ( bg ) =>
851
+ bg . postMessage ( {
852
+ action : 'changeTab' ,
853
+ payload : { tabId : tab . id , title : tab . title } ,
854
+ } ) ,
855
+ ) ;
856
+ }
790
857
}
791
858
}
792
- } ) ;
859
+ } catch ( error ) {
860
+ console . error ( 'Error in tab activation handler:' , error ) ;
861
+ }
862
+ } ) ;
863
+
864
+ // Ensure keep-alive is set up when the extension is installed
865
+ chrome . runtime . onInstalled . addListener ( ( ) => {
866
+ console . log ( 'Extension installed. Setting up keep-alive...' ) ;
867
+ setupKeepAlive ( ) ;
793
868
} ) ;
794
869
870
+ // Ensure keep-alive is set up when the browser starts
795
871
chrome . runtime . onStartup . addListener ( ( ) => {
872
+ console . log ( 'Browser started. Setting up keep-alive...' ) ;
796
873
setupKeepAlive ( ) ;
797
874
} ) ;
875
+
876
+ // Optional: Reset keep-alive when a message is received (to cover edge cases)
877
+ chrome . runtime . onMessage . addListener ( ( message , sender , sendResponse ) => {
878
+ if ( message === 'resetKeepAlive' ) {
879
+ console . log ( 'Resetting keep-alive as requested.' ) ;
880
+ setupKeepAlive ( ) ;
881
+ sendResponse ( { success : true } ) ;
882
+ }
883
+ } ) ;
0 commit comments