@couch-kit/devtools 3.0.2 → 3.0.3
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.
- package/CHANGELOG.md +8 -0
- package/dist/index.js +369 -0
- package/lib/index.d.ts +1 -2
- package/lib/index.d.ts.map +1 -1
- package/package.json +6 -4
- package/src/index.ts +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @couch-kit/devtools
|
|
2
2
|
|
|
3
|
+
## 3.0.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#206](https://github.com/faluciano/react-native-couch-kit/pull/206) [`cfe5bbb`](https://github.com/faluciano/react-native-couch-kit/commit/cfe5bbb1ac46eca0cb006b07473fbfab32e0182b) Thanks [@faluciano](https://github.com/faluciano)! - Publish a bundle that actually contains `DebugOverlay`.
|
|
8
|
+
|
|
9
|
+
Every previous release shipped a 27-byte `dist/index.js` that exported `DebugOverlay` without defining it: with `sideEffects: false`, the bundler tree-shook the named re-export of the package's only value. The build also targeted React's development JSX runtime, which does not work in a production build. The entry point now uses `export *`, the bundle is built against `react/jsx-runtime`, and the build fails if either regresses.
|
|
10
|
+
|
|
3
11
|
## 3.0.2
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,372 @@
|
|
|
1
|
+
// src/DebugOverlay.tsx
|
|
2
|
+
import { useState, useCallback, useRef } from "react";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
var STATUS_COLORS = {
|
|
5
|
+
connected: "#4ade80",
|
|
6
|
+
connecting: "#facc15",
|
|
7
|
+
reconnecting: "#facc15",
|
|
8
|
+
disconnected: "#f87171",
|
|
9
|
+
error: "#f87171"
|
|
10
|
+
};
|
|
11
|
+
function formatTimestamp(ts) {
|
|
12
|
+
const date = new Date(ts);
|
|
13
|
+
return date.toLocaleTimeString("en-US", {
|
|
14
|
+
hour12: false,
|
|
15
|
+
hour: "2-digit",
|
|
16
|
+
minute: "2-digit",
|
|
17
|
+
second: "2-digit"
|
|
18
|
+
}) + "." + String(date.getMilliseconds()).padStart(3, "0");
|
|
19
|
+
}
|
|
20
|
+
function JsonTree({ data, depth = 0 }) {
|
|
21
|
+
if (data === null || data === undefined) {
|
|
22
|
+
return /* @__PURE__ */ jsx("span", {
|
|
23
|
+
style: { color: "#9ca3af" },
|
|
24
|
+
children: String(data)
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
if (typeof data === "boolean") {
|
|
28
|
+
return /* @__PURE__ */ jsx("span", {
|
|
29
|
+
style: { color: "#c084fc" },
|
|
30
|
+
children: String(data)
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
if (typeof data === "number") {
|
|
34
|
+
return /* @__PURE__ */ jsx("span", {
|
|
35
|
+
style: { color: "#60a5fa" },
|
|
36
|
+
children: data
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
if (typeof data === "string") {
|
|
40
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
41
|
+
style: { color: "#4ade80" },
|
|
42
|
+
children: [
|
|
43
|
+
'"',
|
|
44
|
+
data,
|
|
45
|
+
'"'
|
|
46
|
+
]
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (Array.isArray(data)) {
|
|
50
|
+
if (data.length === 0)
|
|
51
|
+
return /* @__PURE__ */ jsx("span", {
|
|
52
|
+
children: "[]"
|
|
53
|
+
});
|
|
54
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
55
|
+
children: [
|
|
56
|
+
`[
|
|
57
|
+
`,
|
|
58
|
+
data.map((item, i) => /* @__PURE__ */ jsxs("span", {
|
|
59
|
+
children: [
|
|
60
|
+
" ".repeat(depth + 1),
|
|
61
|
+
/* @__PURE__ */ jsx(JsonTree, {
|
|
62
|
+
data: item,
|
|
63
|
+
depth: depth + 1
|
|
64
|
+
}),
|
|
65
|
+
i < data.length - 1 ? "," : "",
|
|
66
|
+
`
|
|
67
|
+
`
|
|
68
|
+
]
|
|
69
|
+
}, i)),
|
|
70
|
+
" ".repeat(depth),
|
|
71
|
+
"]"
|
|
72
|
+
]
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (typeof data === "object") {
|
|
76
|
+
const entries = Object.entries(data);
|
|
77
|
+
if (entries.length === 0)
|
|
78
|
+
return /* @__PURE__ */ jsx("span", {
|
|
79
|
+
children: "{}"
|
|
80
|
+
});
|
|
81
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
82
|
+
children: [
|
|
83
|
+
`{
|
|
84
|
+
`,
|
|
85
|
+
entries.map(([key, value], i) => /* @__PURE__ */ jsxs("span", {
|
|
86
|
+
children: [
|
|
87
|
+
" ".repeat(depth + 1),
|
|
88
|
+
/* @__PURE__ */ jsx("span", {
|
|
89
|
+
style: { color: "#93c5fd" },
|
|
90
|
+
children: key
|
|
91
|
+
}),
|
|
92
|
+
": ",
|
|
93
|
+
/* @__PURE__ */ jsx(JsonTree, {
|
|
94
|
+
data: value,
|
|
95
|
+
depth: depth + 1
|
|
96
|
+
}),
|
|
97
|
+
i < entries.length - 1 ? "," : "",
|
|
98
|
+
`
|
|
99
|
+
`
|
|
100
|
+
]
|
|
101
|
+
}, key)),
|
|
102
|
+
" ".repeat(depth),
|
|
103
|
+
"}"
|
|
104
|
+
]
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return /* @__PURE__ */ jsx("span", {
|
|
108
|
+
children: String(data)
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
function DebugOverlay({
|
|
112
|
+
data,
|
|
113
|
+
defaultCollapsed = true,
|
|
114
|
+
position = "bottom-right",
|
|
115
|
+
maxHeight = 400
|
|
116
|
+
}) {
|
|
117
|
+
const [collapsed, setCollapsed] = useState(defaultCollapsed);
|
|
118
|
+
const [activeTab, setActiveTab] = useState("actions");
|
|
119
|
+
const tapCountRef = useRef(0);
|
|
120
|
+
const tapTimerRef = useRef(null);
|
|
121
|
+
const handleToggle = useCallback(() => {
|
|
122
|
+
tapCountRef.current++;
|
|
123
|
+
if (tapTimerRef.current) {
|
|
124
|
+
clearTimeout(tapTimerRef.current);
|
|
125
|
+
}
|
|
126
|
+
tapTimerRef.current = setTimeout(() => {
|
|
127
|
+
tapCountRef.current = 0;
|
|
128
|
+
}, 300);
|
|
129
|
+
setCollapsed((prev) => !prev);
|
|
130
|
+
}, []);
|
|
131
|
+
if (!data.enabled)
|
|
132
|
+
return null;
|
|
133
|
+
const positionStyles = {
|
|
134
|
+
position: "fixed",
|
|
135
|
+
zIndex: 99999,
|
|
136
|
+
...position.includes("top") ? { top: 8 } : { bottom: 8 },
|
|
137
|
+
...position.includes("left") ? { left: 8 } : { right: 8 }
|
|
138
|
+
};
|
|
139
|
+
const statusColor = STATUS_COLORS[data.connectionStatus] ?? "#9ca3af";
|
|
140
|
+
const panelStyle = {
|
|
141
|
+
...positionStyles,
|
|
142
|
+
fontFamily: "'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, monospace",
|
|
143
|
+
fontSize: 11,
|
|
144
|
+
lineHeight: 1.4,
|
|
145
|
+
color: "#e5e7eb",
|
|
146
|
+
backgroundColor: "rgba(17, 24, 39, 0.95)",
|
|
147
|
+
border: "1px solid rgba(75, 85, 99, 0.6)",
|
|
148
|
+
borderRadius: 8,
|
|
149
|
+
overflow: "hidden",
|
|
150
|
+
width: collapsed ? "auto" : 360,
|
|
151
|
+
backdropFilter: "blur(8px)",
|
|
152
|
+
boxShadow: "0 4px 24px rgba(0, 0, 0, 0.4)"
|
|
153
|
+
};
|
|
154
|
+
const buttonStyle = {
|
|
155
|
+
background: "none",
|
|
156
|
+
border: "none",
|
|
157
|
+
color: "#e5e7eb",
|
|
158
|
+
cursor: "pointer",
|
|
159
|
+
padding: "6px 10px",
|
|
160
|
+
fontSize: 11,
|
|
161
|
+
fontFamily: "inherit"
|
|
162
|
+
};
|
|
163
|
+
const tabStyle = (isActive) => ({
|
|
164
|
+
...buttonStyle,
|
|
165
|
+
borderBottom: isActive ? "2px solid #60a5fa" : "2px solid transparent",
|
|
166
|
+
color: isActive ? "#60a5fa" : "#9ca3af",
|
|
167
|
+
paddingBottom: 4
|
|
168
|
+
});
|
|
169
|
+
if (collapsed) {
|
|
170
|
+
return /* @__PURE__ */ jsx("div", {
|
|
171
|
+
style: positionStyles,
|
|
172
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
173
|
+
onClick: handleToggle,
|
|
174
|
+
style: {
|
|
175
|
+
...buttonStyle,
|
|
176
|
+
backgroundColor: "rgba(17, 24, 39, 0.95)",
|
|
177
|
+
border: "1px solid rgba(75, 85, 99, 0.6)",
|
|
178
|
+
borderRadius: 8,
|
|
179
|
+
display: "flex",
|
|
180
|
+
alignItems: "center",
|
|
181
|
+
gap: 6,
|
|
182
|
+
padding: "6px 12px",
|
|
183
|
+
backdropFilter: "blur(8px)",
|
|
184
|
+
boxShadow: "0 2px 12px rgba(0, 0, 0, 0.3)"
|
|
185
|
+
},
|
|
186
|
+
children: [
|
|
187
|
+
/* @__PURE__ */ jsx("span", {
|
|
188
|
+
style: {
|
|
189
|
+
width: 8,
|
|
190
|
+
height: 8,
|
|
191
|
+
borderRadius: "50%",
|
|
192
|
+
backgroundColor: statusColor,
|
|
193
|
+
display: "inline-block"
|
|
194
|
+
}
|
|
195
|
+
}),
|
|
196
|
+
/* @__PURE__ */ jsx("span", {
|
|
197
|
+
children: "Debug"
|
|
198
|
+
}),
|
|
199
|
+
data.rtt !== null && /* @__PURE__ */ jsxs("span", {
|
|
200
|
+
style: { color: "#9ca3af" },
|
|
201
|
+
children: [
|
|
202
|
+
data.rtt,
|
|
203
|
+
"ms"
|
|
204
|
+
]
|
|
205
|
+
})
|
|
206
|
+
]
|
|
207
|
+
})
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
const latestState = data.stateHistory.length > 0 ? data.stateHistory[data.stateHistory.length - 1]?.state : null;
|
|
211
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
212
|
+
style: panelStyle,
|
|
213
|
+
children: [
|
|
214
|
+
/* @__PURE__ */ jsxs("div", {
|
|
215
|
+
style: {
|
|
216
|
+
display: "flex",
|
|
217
|
+
alignItems: "center",
|
|
218
|
+
justifyContent: "space-between",
|
|
219
|
+
padding: "6px 10px",
|
|
220
|
+
borderBottom: "1px solid rgba(75, 85, 99, 0.4)"
|
|
221
|
+
},
|
|
222
|
+
children: [
|
|
223
|
+
/* @__PURE__ */ jsxs("div", {
|
|
224
|
+
style: { display: "flex", alignItems: "center", gap: 6 },
|
|
225
|
+
children: [
|
|
226
|
+
/* @__PURE__ */ jsx("span", {
|
|
227
|
+
style: {
|
|
228
|
+
width: 8,
|
|
229
|
+
height: 8,
|
|
230
|
+
borderRadius: "50%",
|
|
231
|
+
backgroundColor: statusColor,
|
|
232
|
+
display: "inline-block"
|
|
233
|
+
}
|
|
234
|
+
}),
|
|
235
|
+
/* @__PURE__ */ jsx("span", {
|
|
236
|
+
style: { fontWeight: 600 },
|
|
237
|
+
children: "Debug"
|
|
238
|
+
}),
|
|
239
|
+
/* @__PURE__ */ jsxs("span", {
|
|
240
|
+
style: { color: "#9ca3af" },
|
|
241
|
+
children: [
|
|
242
|
+
data.connectionStatus,
|
|
243
|
+
data.rtt !== null ? ` · ${data.rtt}ms` : ""
|
|
244
|
+
]
|
|
245
|
+
})
|
|
246
|
+
]
|
|
247
|
+
}),
|
|
248
|
+
/* @__PURE__ */ jsxs("div", {
|
|
249
|
+
style: { display: "flex", gap: 4 },
|
|
250
|
+
children: [
|
|
251
|
+
/* @__PURE__ */ jsx("button", {
|
|
252
|
+
onClick: data.clearHistory,
|
|
253
|
+
style: buttonStyle,
|
|
254
|
+
title: "Clear",
|
|
255
|
+
children: "✕"
|
|
256
|
+
}),
|
|
257
|
+
/* @__PURE__ */ jsx("button", {
|
|
258
|
+
onClick: handleToggle,
|
|
259
|
+
style: buttonStyle,
|
|
260
|
+
title: "Collapse",
|
|
261
|
+
children: "▾"
|
|
262
|
+
})
|
|
263
|
+
]
|
|
264
|
+
})
|
|
265
|
+
]
|
|
266
|
+
}),
|
|
267
|
+
/* @__PURE__ */ jsxs("div", {
|
|
268
|
+
style: {
|
|
269
|
+
display: "flex",
|
|
270
|
+
gap: 0,
|
|
271
|
+
borderBottom: "1px solid rgba(75, 85, 99, 0.4)",
|
|
272
|
+
padding: "0 6px"
|
|
273
|
+
},
|
|
274
|
+
children: [
|
|
275
|
+
/* @__PURE__ */ jsxs("button", {
|
|
276
|
+
onClick: () => setActiveTab("actions"),
|
|
277
|
+
style: tabStyle(activeTab === "actions"),
|
|
278
|
+
children: [
|
|
279
|
+
"Actions (",
|
|
280
|
+
data.actionLog.length,
|
|
281
|
+
")"
|
|
282
|
+
]
|
|
283
|
+
}),
|
|
284
|
+
/* @__PURE__ */ jsx("button", {
|
|
285
|
+
onClick: () => setActiveTab("state"),
|
|
286
|
+
style: tabStyle(activeTab === "state"),
|
|
287
|
+
children: "State"
|
|
288
|
+
})
|
|
289
|
+
]
|
|
290
|
+
}),
|
|
291
|
+
/* @__PURE__ */ jsxs("div", {
|
|
292
|
+
style: {
|
|
293
|
+
maxHeight,
|
|
294
|
+
overflowY: "auto",
|
|
295
|
+
padding: 8
|
|
296
|
+
},
|
|
297
|
+
children: [
|
|
298
|
+
activeTab === "actions" && /* @__PURE__ */ jsx("div", {
|
|
299
|
+
children: data.actionLog.length === 0 ? /* @__PURE__ */ jsx("div", {
|
|
300
|
+
style: {
|
|
301
|
+
color: "#6b7280",
|
|
302
|
+
textAlign: "center",
|
|
303
|
+
padding: 16
|
|
304
|
+
},
|
|
305
|
+
children: "No actions recorded"
|
|
306
|
+
}) : data.actionLog.slice().reverse().map((entry) => /* @__PURE__ */ jsxs("div", {
|
|
307
|
+
style: {
|
|
308
|
+
padding: "4px 6px",
|
|
309
|
+
borderBottom: "1px solid rgba(75, 85, 99, 0.2)",
|
|
310
|
+
display: "flex",
|
|
311
|
+
flexDirection: "column",
|
|
312
|
+
gap: 2
|
|
313
|
+
},
|
|
314
|
+
children: [
|
|
315
|
+
/* @__PURE__ */ jsxs("div", {
|
|
316
|
+
style: {
|
|
317
|
+
display: "flex",
|
|
318
|
+
justifyContent: "space-between",
|
|
319
|
+
alignItems: "center"
|
|
320
|
+
},
|
|
321
|
+
children: [
|
|
322
|
+
/* @__PURE__ */ jsx("span", {
|
|
323
|
+
style: {
|
|
324
|
+
color: entry.source === "local" ? "#60a5fa" : "#4ade80",
|
|
325
|
+
fontSize: 10,
|
|
326
|
+
textTransform: "uppercase"
|
|
327
|
+
},
|
|
328
|
+
children: entry.source
|
|
329
|
+
}),
|
|
330
|
+
/* @__PURE__ */ jsx("span", {
|
|
331
|
+
style: { color: "#6b7280", fontSize: 10 },
|
|
332
|
+
children: formatTimestamp(entry.timestamp)
|
|
333
|
+
})
|
|
334
|
+
]
|
|
335
|
+
}),
|
|
336
|
+
/* @__PURE__ */ jsx("pre", {
|
|
337
|
+
style: {
|
|
338
|
+
margin: 0,
|
|
339
|
+
fontSize: 10,
|
|
340
|
+
color: "#d1d5db",
|
|
341
|
+
whiteSpace: "pre-wrap",
|
|
342
|
+
wordBreak: "break-all"
|
|
343
|
+
},
|
|
344
|
+
children: /* @__PURE__ */ jsx(JsonTree, {
|
|
345
|
+
data: entry.action
|
|
346
|
+
})
|
|
347
|
+
})
|
|
348
|
+
]
|
|
349
|
+
}, entry.id))
|
|
350
|
+
}),
|
|
351
|
+
activeTab === "state" && /* @__PURE__ */ jsx("pre", {
|
|
352
|
+
style: {
|
|
353
|
+
margin: 0,
|
|
354
|
+
fontSize: 10,
|
|
355
|
+
whiteSpace: "pre-wrap",
|
|
356
|
+
wordBreak: "break-all"
|
|
357
|
+
},
|
|
358
|
+
children: latestState !== null ? /* @__PURE__ */ jsx(JsonTree, {
|
|
359
|
+
data: latestState
|
|
360
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
361
|
+
style: { color: "#6b7280" },
|
|
362
|
+
children: "No state captured"
|
|
363
|
+
})
|
|
364
|
+
})
|
|
365
|
+
]
|
|
366
|
+
})
|
|
367
|
+
]
|
|
368
|
+
});
|
|
369
|
+
}
|
|
1
370
|
export {
|
|
2
371
|
DebugOverlay
|
|
3
372
|
};
|
package/lib/index.d.ts
CHANGED
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,gBAAgB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@couch-kit/devtools",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.3",
|
|
4
4
|
"description": "Developer tooling and debug overlay for Couch Kit games",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
},
|
|
14
14
|
"sideEffects": false,
|
|
15
15
|
"scripts": {
|
|
16
|
-
"build": "bun build ./src/index.ts --outdir ./dist --target browser --external react --external @couch-kit/client --external @couch-kit/core && tsc -p tsconfig.build.json",
|
|
16
|
+
"build": "NODE_ENV=production bun build ./src/index.ts --outdir ./dist --target browser --external react --external @couch-kit/client --external @couch-kit/core && tsc -p tsconfig.build.json && bun run verify-build",
|
|
17
|
+
"verify-build": "node -e \"const s=require('fs').readFileSync('./dist/index.js','utf8');if(!s.includes('function DebugOverlay'))throw new Error('dist/index.js is missing DebugOverlay — empty bundle');if(s.includes('jsx-dev-runtime'))throw new Error('dist/index.js uses react/jsx-dev-runtime — build with NODE_ENV=production');\"",
|
|
18
|
+
"prepublishOnly": "bun run build",
|
|
17
19
|
"test": "bun test",
|
|
18
20
|
"typecheck": "tsc --noEmit",
|
|
19
21
|
"clean": "rm -rf dist lib"
|
|
@@ -27,8 +29,8 @@
|
|
|
27
29
|
],
|
|
28
30
|
"dependencies": {},
|
|
29
31
|
"devDependencies": {
|
|
30
|
-
"@couch-kit/client": "0.
|
|
31
|
-
"@couch-kit/core": "0.
|
|
32
|
+
"@couch-kit/client": "0.15.0",
|
|
33
|
+
"@couch-kit/core": "0.10.0",
|
|
32
34
|
"@happy-dom/global-registrator": "^20.10.6",
|
|
33
35
|
"@testing-library/dom": "^10.4.1",
|
|
34
36
|
"@testing-library/react": "^16.3.2",
|
package/src/index.ts
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
export { DebugOverlay } from
|
|
2
|
-
export
|
|
1
|
+
// `export *`, not `export { DebugOverlay } from`: with `sideEffects: false`,
|
|
2
|
+
// bun tree-shakes a named re-export of the package's only value out of the
|
|
3
|
+
// bundle, publishing a `dist/index.js` that exports a binding it never defines.
|
|
4
|
+
// The build's `verify-build` step fails if that ever happens again.
|
|
5
|
+
export * from "./DebugOverlay";
|