Skip to content

Commit 16c9c54

Browse files
committed
chore: bump version to 0.5.0 and improve DevTools connection handling
- Update version across package.json, manifest.json, and package-lock.json - Refactor background script to use per-tab connection tracking - Replace global devtoolsPort with tabConnections map for better isolation - Add DEVTOOLS_CONNECT message handling for inspected tab association
1 parent 22ad9bb commit 16c9c54

File tree

8 files changed

+137
-247
lines changed

8 files changed

+137
-247
lines changed

package-lock.json

Lines changed: 12 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "tanstack-query-chrome-devtools",
33
"private": true,
4-
"version": "0.4.0",
4+
"version": "0.5.0",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",
@@ -17,6 +17,7 @@
1717
"@tanstack/query-core": "^5.80.2",
1818
"class-variance-authority": "^0.7.1",
1919
"clsx": "^2.1.1",
20+
"highlight.js": "^11.11.1",
2021
"lucide-react": "^0.522.0",
2122
"react": "^19.1.0",
2223
"react-dom": "^19.1.0"

public/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"manifest_version": 3,
33
"name": "TanStack Query DevTools",
4-
"version": "0.4.0",
4+
"version": "0.5.0",
55
"description": "Chrome DevTools extension for debugging TanStack Query applications. Inspect queries, mutations, and cache state in real-time.",
66
"permissions": ["activeTab"],
77
"devtools_page": "devtools.html",

src/background/background.ts

Lines changed: 77 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@
33
// Track which tabs have TanStack Query detected
44
const tabsWithTanStackQuery = new Set<number>();
55

6-
// Connection health tracking
7-
interface ConnectionInfo {
8-
port: chrome.runtime.Port;
9-
tabId: number | null;
6+
// Tab-specific connection tracking
7+
interface TabConnection {
8+
devtoolsPort: chrome.runtime.Port | null;
9+
inspectedTabId: number;
10+
connectionId: string;
1011
connectedAt: number;
1112
lastPing: number;
1213
}
1314

14-
const activeConnections = new Map<string, ConnectionInfo>();
15+
// Track DevTools connections per inspected tab
16+
const tabConnections = new Map<number, TabConnection>();
1517

1618
// Message types
1719
interface TanStackQueryMessage {
@@ -34,71 +36,63 @@ interface QueryActionResult {
3436
error?: string;
3537
}
3638

37-
// Store DevTools port connection
38-
let devtoolsPort: chrome.runtime.Port | null = null;
39-
4039
// Handle DevTools connections
41-
chrome.runtime.onConnect.addListener(async (port) => {
40+
chrome.runtime.onConnect.addListener((port) => {
4241
if (port.name === "devtools") {
4342
const connectionId = `devtools-${Date.now()}`;
44-
devtoolsPort = port;
43+
let inspectedTabId: number | null = null;
4544

46-
// Get current tab ID asynchronously
47-
const currentTabId = await getCurrentTabId();
45+
port.onMessage.addListener(async (message) => {
46+
// Handle DevTools connection with inspected tab ID
47+
if (message.type === "DEVTOOLS_CONNECT") {
48+
inspectedTabId = message.inspectedTabId;
49+
50+
// Validate that we have a valid tab ID
51+
if (!inspectedTabId) {
52+
console.error("Invalid inspected tab ID received");
53+
return;
54+
}
4855

49-
if (currentTabId) {
50-
chrome.tabs
51-
.sendMessage(currentTabId, {
52-
type: "REQUEST_IMMEDIATE_UPDATE",
53-
})
54-
.catch((error: unknown) => {
55-
console.warn("Failed to request immediate update:", error);
56+
// Store this connection for the inspected tab
57+
const connection: TabConnection = {
58+
devtoolsPort: port,
59+
inspectedTabId,
60+
connectionId,
61+
connectedAt: Date.now(),
62+
lastPing: Date.now(),
63+
};
64+
65+
tabConnections.set(inspectedTabId, connection);
66+
67+
// Send initial state for this specific tab
68+
port.postMessage({
69+
type: "INITIAL_STATE",
70+
hasTanStackQuery: tabsWithTanStackQuery.has(inspectedTabId),
5671
});
57-
}
58-
59-
// Track this connection
60-
activeConnections.set(connectionId, {
61-
port,
62-
tabId: currentTabId,
63-
connectedAt: Date.now(),
64-
lastPing: Date.now(),
65-
});
66-
67-
// Send initial state to DevTools
68-
if (currentTabId) {
69-
port.postMessage({
70-
type: "INITIAL_STATE",
71-
hasTanStackQuery: tabsWithTanStackQuery.has(currentTabId),
72-
});
7372

74-
// If TanStack Query is already detected, request immediate data update
75-
if (tabsWithTanStackQuery.has(currentTabId)) {
76-
chrome.tabs
77-
.sendMessage(currentTabId, {
73+
// Request immediate update from the inspected tab
74+
try {
75+
await chrome.tabs.sendMessage(inspectedTabId, {
7876
type: "REQUEST_IMMEDIATE_UPDATE",
79-
})
80-
.catch((error: unknown) => {
81-
console.warn("Failed to request immediate update:", error);
8277
});
83-
}
84-
}
78+
} catch (error: unknown) {
79+
console.warn("Failed to request immediate update:", error);
80+
}
8581

86-
// Send connection health info
87-
port.postMessage({
88-
type: "CONNECTION_ESTABLISHED",
89-
connectionId,
90-
timestamp: Date.now(),
91-
});
82+
// Send connection confirmation
83+
port.postMessage({
84+
type: "CONNECTION_ESTABLISHED",
85+
connectionId,
86+
inspectedTabId,
87+
timestamp: Date.now(),
88+
});
9289

93-
port.onDisconnect.addListener(() => {
94-
devtoolsPort = null;
95-
activeConnections.delete(connectionId);
96-
});
90+
return;
91+
}
9792

98-
port.onMessage.addListener(async (message) => {
9993
// Handle ping messages for connection health
100-
if (message.type === "PING") {
101-
const connection = activeConnections.get(connectionId);
94+
if (message.type === "PING" && inspectedTabId) {
95+
const connection = tabConnections.get(inspectedTabId);
10296
if (connection) {
10397
connection.lastPing = Date.now();
10498
port.postMessage({
@@ -109,16 +103,22 @@ chrome.runtime.onConnect.addListener(async (port) => {
109103
return;
110104
}
111105

112-
// Forward messages to content script if needed
113-
const currentTabId = await getCurrentTabId();
114-
if (currentTabId && message.type) {
106+
// Forward other messages to the inspected tab's content script
107+
if (inspectedTabId && message.type) {
115108
chrome.tabs
116-
.sendMessage(currentTabId, message)
109+
.sendMessage(inspectedTabId, message)
117110
.catch((error: unknown) => {
118111
console.warn("Failed to send message to content script:", error);
119112
});
120113
}
121114
});
115+
116+
port.onDisconnect.addListener(() => {
117+
// Clean up this connection
118+
if (inspectedTabId) {
119+
tabConnections.delete(inspectedTabId);
120+
}
121+
});
122122
}
123123
});
124124

@@ -128,13 +128,16 @@ chrome.runtime.onMessage.addListener(
128128
const tabId = sender.tab?.id;
129129
if (!tabId) return;
130130

131+
// Get the DevTools connection for this specific tab
132+
const connection = tabConnections.get(tabId);
133+
131134
if (message.type === "QEVENT") {
132135
switch (message.subtype) {
133136
case "QUERY_CLIENT_DETECTED":
134137
tabsWithTanStackQuery.add(tabId);
135138

136-
// Forward to DevTools panel
137-
devtoolsPort?.postMessage({
139+
// Forward to DevTools panel for this specific tab only
140+
connection?.devtoolsPort?.postMessage({
138141
type: "QEVENT",
139142
subtype: "QUERY_CLIENT_DETECTED",
140143
tabId: tabId,
@@ -145,8 +148,8 @@ chrome.runtime.onMessage.addListener(
145148
case "QUERY_CLIENT_NOT_FOUND":
146149
tabsWithTanStackQuery.delete(tabId);
147150

148-
// Forward to DevTools panel
149-
devtoolsPort?.postMessage({
151+
// Forward to DevTools panel for this specific tab only
152+
connection?.devtoolsPort?.postMessage({
150153
type: "QEVENT",
151154
subtype: "QUERY_CLIENT_NOT_FOUND",
152155
tabId: tabId,
@@ -155,8 +158,8 @@ chrome.runtime.onMessage.addListener(
155158
break;
156159

157160
case "QUERY_STATE_UPDATE":
158-
// Forward to DevTools panel
159-
devtoolsPort?.postMessage({
161+
// Forward to DevTools panel for this specific tab only
162+
connection?.devtoolsPort?.postMessage({
160163
type: "QEVENT",
161164
subtype: "QUERY_STATE_UPDATE",
162165
tabId: tabId,
@@ -165,8 +168,8 @@ chrome.runtime.onMessage.addListener(
165168
break;
166169

167170
case "QUERY_DATA_UPDATE":
168-
// Forward to DevTools panel
169-
devtoolsPort?.postMessage({
171+
// Forward to DevTools panel for this specific tab only
172+
connection?.devtoolsPort?.postMessage({
170173
type: "QEVENT",
171174
subtype: "QUERY_DATA_UPDATE",
172175
tabId: tabId,
@@ -175,8 +178,8 @@ chrome.runtime.onMessage.addListener(
175178
break;
176179

177180
case "MUTATION_DATA_UPDATE":
178-
// Forward to DevTools panel
179-
devtoolsPort?.postMessage({
181+
// Forward to DevTools panel for this specific tab only
182+
connection?.devtoolsPort?.postMessage({
180183
type: "QEVENT",
181184
subtype: "MUTATION_DATA_UPDATE",
182185
tabId: tabId,
@@ -188,8 +191,8 @@ chrome.runtime.onMessage.addListener(
188191

189192
// Handle query action results from content script
190193
if (message.type === "QUERY_ACTION_RESULT") {
191-
// Forward to DevTools panel
192-
devtoolsPort?.postMessage({
194+
// Forward to DevTools panel for this specific tab only
195+
connection?.devtoolsPort?.postMessage({
193196
...message,
194197
tabId: tabId,
195198
});
@@ -199,23 +202,10 @@ chrome.runtime.onMessage.addListener(
199202
},
200203
);
201204

202-
// Helper function to get current active tab ID
203-
async function getCurrentTabId(): Promise<number | null> {
204-
try {
205-
const [tab] = await chrome.tabs.query({
206-
active: true,
207-
currentWindow: true,
208-
});
209-
return tab?.id || null;
210-
} catch (error) {
211-
console.warn("Failed to get current tab ID:", error);
212-
return null;
213-
}
214-
}
215-
216205
// Clean up when tabs are closed
217206
chrome.tabs.onRemoved.addListener((tabId) => {
218207
tabsWithTanStackQuery.delete(tabId);
208+
tabConnections.delete(tabId);
219209
});
220210

221211
// Extension lifecycle

0 commit comments

Comments
 (0)