@tanstack/pacer-devtools 1.1.3 → 1.1.4

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 (37) hide show
  1. package/README.md +7 -7
  2. package/dist/PacerDevtools-C_K6wJJQ.js +1315 -0
  3. package/dist/PacerDevtools-DMClGMZE.js +1147 -0
  4. package/dist/index.d.ts +6 -8
  5. package/dist/index.js +5 -6
  6. package/dist/production/index.d.ts +19 -0
  7. package/dist/{core.js → production/index.js} +3 -6
  8. package/dist/production/server.js +6 -0
  9. package/dist/server.js +9 -0
  10. package/package.json +38 -5
  11. package/src/PacerDevtools.tsx +13 -4
  12. package/src/core.tsx +3 -4
  13. package/dist/PacerContextProvider.js +0 -142
  14. package/dist/PacerContextProvider.js.map +0 -1
  15. package/dist/PacerDevtools.js +0 -14
  16. package/dist/PacerDevtools.js.map +0 -1
  17. package/dist/components/ActionButtons.js +0 -154
  18. package/dist/components/ActionButtons.js.map +0 -1
  19. package/dist/components/DetailsPanel.js +0 -76
  20. package/dist/components/DetailsPanel.js.map +0 -1
  21. package/dist/components/Shell.js +0 -107
  22. package/dist/components/Shell.js.map +0 -1
  23. package/dist/components/StateHeader.js +0 -85
  24. package/dist/components/StateHeader.js.map +0 -1
  25. package/dist/components/UtilList.js +0 -72
  26. package/dist/components/UtilList.js.map +0 -1
  27. package/dist/components/util-groups.js +0 -57
  28. package/dist/components/util-groups.js.map +0 -1
  29. package/dist/core.d.ts +0 -24
  30. package/dist/core.js.map +0 -1
  31. package/dist/index.js.map +0 -1
  32. package/dist/production.d.ts +0 -2
  33. package/dist/production.js +0 -5
  34. package/dist/styles/tokens.js +0 -301
  35. package/dist/styles/tokens.js.map +0 -1
  36. package/dist/styles/use-styles.js +0 -364
  37. package/dist/styles/use-styles.js.map +0 -1
@@ -0,0 +1,1147 @@
1
+ import { createComponent, escape, ssr, ssrAttribute, ssrStyleProperty } from "solid-js/web";
2
+ import { Header, HeaderLogo, JsonTree, MainPanel, ThemeContextProvider, useTheme } from "@tanstack/devtools-ui";
3
+ import { createStore } from "solid-js/store";
4
+ import { For, createContext, createEffect, createMemo, createSignal, onCleanup, onMount, useContext } from "solid-js";
5
+ import { pacerEventClient } from "@tanstack/pacer/event-client";
6
+ import * as goober from "goober";
7
+ import { useStore } from "@tanstack/solid-store";
8
+ import clsx from "clsx";
9
+ import dayjs from "dayjs";
10
+ import relativeTime from "dayjs/plugin/relativeTime.js";
11
+ //#region src/PacerContextProvider.tsx
12
+ const initialPacerDevtoolsStore = {
13
+ asyncBatchers: [],
14
+ asyncDebouncers: [],
15
+ asyncQueuers: [],
16
+ asyncRateLimiters: [],
17
+ asyncThrottlers: [],
18
+ batchers: [],
19
+ debouncers: [],
20
+ queuers: [],
21
+ rateLimiters: [],
22
+ throttlers: [],
23
+ lastUpdatedByKey: {}
24
+ };
25
+ const PacerDevtoolsContext = createContext([initialPacerDevtoolsStore, () => {}]);
26
+ const updateOrAddToArray = (oldArray, newItem) => {
27
+ const index = oldArray.findIndex((item) => item.key === newItem.key);
28
+ if (index !== -1) return oldArray.map((item, i) => i === index ? newItem : item);
29
+ return [...oldArray, newItem];
30
+ };
31
+ function PacerContextProvider(props) {
32
+ const [store, setStore] = createStore(initialPacerDevtoolsStore);
33
+ createEffect(() => {
34
+ onCleanup(pacerEventClient.onAllPluginEvents((_e) => {
35
+ const e = _e;
36
+ switch (e.type) {
37
+ case "pacer:AsyncBatcher":
38
+ setStore({
39
+ asyncBatchers: updateOrAddToArray(store.asyncBatchers, e.payload),
40
+ lastUpdatedByKey: {
41
+ ...store.lastUpdatedByKey,
42
+ [e.payload.key]: Date.now()
43
+ }
44
+ });
45
+ break;
46
+ case "pacer:AsyncDebouncer":
47
+ setStore({
48
+ asyncDebouncers: updateOrAddToArray(store.asyncDebouncers, e.payload),
49
+ lastUpdatedByKey: {
50
+ ...store.lastUpdatedByKey,
51
+ [e.payload.key]: Date.now()
52
+ }
53
+ });
54
+ break;
55
+ case "pacer:AsyncQueuer":
56
+ setStore({
57
+ asyncQueuers: updateOrAddToArray(store.asyncQueuers, e.payload),
58
+ lastUpdatedByKey: {
59
+ ...store.lastUpdatedByKey,
60
+ [e.payload.key]: Date.now()
61
+ }
62
+ });
63
+ break;
64
+ case "pacer:AsyncRateLimiter":
65
+ setStore({
66
+ asyncRateLimiters: updateOrAddToArray(store.asyncRateLimiters, e.payload),
67
+ lastUpdatedByKey: {
68
+ ...store.lastUpdatedByKey,
69
+ [e.payload.key]: Date.now()
70
+ }
71
+ });
72
+ break;
73
+ case "pacer:AsyncThrottler":
74
+ setStore({
75
+ asyncThrottlers: updateOrAddToArray(store.asyncThrottlers, e.payload),
76
+ lastUpdatedByKey: {
77
+ ...store.lastUpdatedByKey,
78
+ [e.payload.key]: Date.now()
79
+ }
80
+ });
81
+ break;
82
+ case "pacer:Batcher":
83
+ setStore({
84
+ batchers: updateOrAddToArray(store.batchers, e.payload),
85
+ lastUpdatedByKey: {
86
+ ...store.lastUpdatedByKey,
87
+ [e.payload.key]: Date.now()
88
+ }
89
+ });
90
+ break;
91
+ case "pacer:Debouncer":
92
+ setStore({
93
+ debouncers: updateOrAddToArray(store.debouncers, e.payload),
94
+ lastUpdatedByKey: {
95
+ ...store.lastUpdatedByKey,
96
+ [e.payload.key]: Date.now()
97
+ }
98
+ });
99
+ break;
100
+ case "pacer:Queuer":
101
+ setStore({
102
+ queuers: updateOrAddToArray(store.queuers, e.payload),
103
+ lastUpdatedByKey: {
104
+ ...store.lastUpdatedByKey,
105
+ [e.payload.key]: Date.now()
106
+ }
107
+ });
108
+ break;
109
+ case "pacer:RateLimiter":
110
+ setStore({
111
+ rateLimiters: updateOrAddToArray(store.rateLimiters, e.payload),
112
+ lastUpdatedByKey: {
113
+ ...store.lastUpdatedByKey,
114
+ [e.payload.key]: Date.now()
115
+ }
116
+ });
117
+ break;
118
+ case "pacer:Throttler":
119
+ setStore({
120
+ throttlers: updateOrAddToArray(store.throttlers, e.payload),
121
+ lastUpdatedByKey: {
122
+ ...store.lastUpdatedByKey,
123
+ [e.payload.key]: Date.now()
124
+ }
125
+ });
126
+ break;
127
+ }
128
+ }));
129
+ });
130
+ return createComponent(PacerDevtoolsContext.Provider, {
131
+ value: [store, setStore],
132
+ get children() {
133
+ return props.children;
134
+ }
135
+ });
136
+ }
137
+ const usePacerDevtoolsContext = () => {
138
+ return useContext(PacerDevtoolsContext);
139
+ };
140
+ const usePacerDevtoolsState = () => {
141
+ const [state] = usePacerDevtoolsContext();
142
+ return state;
143
+ };
144
+ //#endregion
145
+ //#region src/styles/tokens.ts
146
+ const tokens = {
147
+ colors: {
148
+ inherit: "inherit",
149
+ current: "currentColor",
150
+ transparent: "transparent",
151
+ black: "#000000",
152
+ white: "#ffffff",
153
+ neutral: {
154
+ 50: "#f9fafb",
155
+ 100: "#f2f4f7",
156
+ 200: "#eaecf0",
157
+ 300: "#d0d5dd",
158
+ 400: "#98a2b3",
159
+ 500: "#667085",
160
+ 600: "#475467",
161
+ 700: "#344054",
162
+ 800: "#1d2939",
163
+ 900: "#101828"
164
+ },
165
+ darkGray: {
166
+ 50: "#525c7a",
167
+ 100: "#49536e",
168
+ 200: "#414962",
169
+ 300: "#394056",
170
+ 400: "#313749",
171
+ 500: "#292e3d",
172
+ 600: "#212530",
173
+ 700: "#191c24",
174
+ 800: "#111318",
175
+ 900: "#0b0d10"
176
+ },
177
+ gray: {
178
+ 50: "#f9fafb",
179
+ 100: "#f2f4f7",
180
+ 200: "#eaecf0",
181
+ 300: "#d0d5dd",
182
+ 400: "#98a2b3",
183
+ 500: "#667085",
184
+ 600: "#475467",
185
+ 700: "#344054",
186
+ 800: "#1d2939",
187
+ 900: "#101828"
188
+ },
189
+ blue: {
190
+ 25: "#F5FAFF",
191
+ 50: "#EFF8FF",
192
+ 100: "#D1E9FF",
193
+ 200: "#B2DDFF",
194
+ 300: "#84CAFF",
195
+ 400: "#53B1FD",
196
+ 500: "#2E90FA",
197
+ 600: "#1570EF",
198
+ 700: "#175CD3",
199
+ 800: "#1849A9",
200
+ 900: "#194185"
201
+ },
202
+ green: {
203
+ 25: "#F6FEF9",
204
+ 50: "#ECFDF3",
205
+ 100: "#D1FADF",
206
+ 200: "#A6F4C5",
207
+ 300: "#6CE9A6",
208
+ 400: "#32D583",
209
+ 500: "#12B76A",
210
+ 600: "#039855",
211
+ 700: "#027A48",
212
+ 800: "#05603A",
213
+ 900: "#054F31"
214
+ },
215
+ red: {
216
+ 50: "#fef2f2",
217
+ 100: "#fee2e2",
218
+ 200: "#fecaca",
219
+ 300: "#fca5a5",
220
+ 400: "#f87171",
221
+ 500: "#ef4444",
222
+ 600: "#dc2626",
223
+ 700: "#b91c1c",
224
+ 800: "#991b1b",
225
+ 900: "#7f1d1d",
226
+ 950: "#450a0a"
227
+ },
228
+ yellow: {
229
+ 25: "#FFFCF5",
230
+ 50: "#FFFAEB",
231
+ 100: "#FEF0C7",
232
+ 200: "#FEDF89",
233
+ 300: "#FEC84B",
234
+ 400: "#FDB022",
235
+ 500: "#F79009",
236
+ 600: "#DC6803",
237
+ 700: "#B54708",
238
+ 800: "#93370D",
239
+ 900: "#7A2E0E"
240
+ },
241
+ purple: {
242
+ 25: "#FAFAFF",
243
+ 50: "#F4F3FF",
244
+ 100: "#EBE9FE",
245
+ 200: "#D9D6FE",
246
+ 300: "#BDB4FE",
247
+ 400: "#9B8AFB",
248
+ 500: "#7A5AF8",
249
+ 600: "#6938EF",
250
+ 700: "#5925DC",
251
+ 800: "#4A1FB8",
252
+ 900: "#3E1C96"
253
+ },
254
+ teal: {
255
+ 25: "#F6FEFC",
256
+ 50: "#F0FDF9",
257
+ 100: "#CCFBEF",
258
+ 200: "#99F6E0",
259
+ 300: "#5FE9D0",
260
+ 400: "#2ED3B7",
261
+ 500: "#15B79E",
262
+ 600: "#0E9384",
263
+ 700: "#107569",
264
+ 800: "#125D56",
265
+ 900: "#134E48"
266
+ },
267
+ pink: {
268
+ 25: "#fdf2f8",
269
+ 50: "#fce7f3",
270
+ 100: "#fbcfe8",
271
+ 200: "#f9a8d4",
272
+ 300: "#f472b6",
273
+ 400: "#ec4899",
274
+ 500: "#db2777",
275
+ 600: "#be185d",
276
+ 700: "#9d174d",
277
+ 800: "#831843",
278
+ 900: "#500724"
279
+ },
280
+ cyan: {
281
+ 25: "#ecfeff",
282
+ 50: "#cffafe",
283
+ 100: "#a5f3fc",
284
+ 200: "#67e8f9",
285
+ 300: "#22d3ee",
286
+ 400: "#06b6d4",
287
+ 500: "#0891b2",
288
+ 600: "#0e7490",
289
+ 700: "#155e75",
290
+ 800: "#164e63",
291
+ 900: "#083344"
292
+ }
293
+ },
294
+ alpha: {
295
+ 100: "ff",
296
+ 90: "e5",
297
+ 80: "cc",
298
+ 70: "b3",
299
+ 60: "99",
300
+ 50: "80",
301
+ 40: "66",
302
+ 30: "4d",
303
+ 20: "33",
304
+ 10: "1a",
305
+ 0: "00"
306
+ },
307
+ font: {
308
+ size: {
309
+ "2xs": "calc(var(--tsrd-font-size) * 0.625)",
310
+ xs: "calc(var(--tsrd-font-size) * 0.75)",
311
+ sm: "calc(var(--tsrd-font-size) * 0.875)",
312
+ md: "var(--tsrd-font-size)",
313
+ lg: "calc(var(--tsrd-font-size) * 1.125)",
314
+ xl: "calc(var(--tsrd-font-size) * 1.25)",
315
+ "2xl": "calc(var(--tsrd-font-size) * 1.5)",
316
+ "3xl": "calc(var(--tsrd-font-size) * 1.875)",
317
+ "4xl": "calc(var(--tsrd-font-size) * 2.25)",
318
+ "5xl": "calc(var(--tsrd-font-size) * 3)",
319
+ "6xl": "calc(var(--tsrd-font-size) * 3.75)",
320
+ "7xl": "calc(var(--tsrd-font-size) * 4.5)",
321
+ "8xl": "calc(var(--tsrd-font-size) * 6)",
322
+ "9xl": "calc(var(--tsrd-font-size) * 8)"
323
+ },
324
+ lineHeight: {
325
+ "3xs": "calc(var(--tsrd-font-size) * 0.75)",
326
+ "2xs": "calc(var(--tsrd-font-size) * 0.875)",
327
+ xs: "calc(var(--tsrd-font-size) * 1)",
328
+ sm: "calc(var(--tsrd-font-size) * 1.25)",
329
+ md: "calc(var(--tsrd-font-size) * 1.5)",
330
+ lg: "calc(var(--tsrd-font-size) * 1.75)",
331
+ xl: "calc(var(--tsrd-font-size) * 2)",
332
+ "2xl": "calc(var(--tsrd-font-size) * 2.25)",
333
+ "3xl": "calc(var(--tsrd-font-size) * 2.5)",
334
+ "4xl": "calc(var(--tsrd-font-size) * 2.75)",
335
+ "5xl": "calc(var(--tsrd-font-size) * 3)",
336
+ "6xl": "calc(var(--tsrd-font-size) * 3.25)",
337
+ "7xl": "calc(var(--tsrd-font-size) * 3.5)",
338
+ "8xl": "calc(var(--tsrd-font-size) * 3.75)",
339
+ "9xl": "calc(var(--tsrd-font-size) * 4)"
340
+ },
341
+ weight: {
342
+ thin: "100",
343
+ extralight: "200",
344
+ light: "300",
345
+ normal: "400",
346
+ medium: "500",
347
+ semibold: "600",
348
+ bold: "700",
349
+ extrabold: "800",
350
+ black: "900"
351
+ },
352
+ fontFamily: {
353
+ sans: "ui-sans-serif, Inter, system-ui, sans-serif, sans-serif",
354
+ mono: `ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace`
355
+ }
356
+ },
357
+ breakpoints: {
358
+ xs: "320px",
359
+ sm: "640px",
360
+ md: "768px",
361
+ lg: "1024px",
362
+ xl: "1280px",
363
+ "2xl": "1536px"
364
+ },
365
+ border: { radius: {
366
+ none: "0px",
367
+ xs: "calc(var(--tsrd-font-size) * 0.125)",
368
+ sm: "calc(var(--tsrd-font-size) * 0.25)",
369
+ md: "calc(var(--tsrd-font-size) * 0.375)",
370
+ lg: "calc(var(--tsrd-font-size) * 0.5)",
371
+ xl: "calc(var(--tsrd-font-size) * 0.75)",
372
+ "2xl": "calc(var(--tsrd-font-size) * 1)",
373
+ "3xl": "calc(var(--tsrd-font-size) * 1.5)",
374
+ full: "9999px"
375
+ } },
376
+ size: {
377
+ 0: "0px",
378
+ .25: "calc(var(--tsrd-font-size) * 0.0625)",
379
+ .5: "calc(var(--tsrd-font-size) * 0.125)",
380
+ 1: "calc(var(--tsrd-font-size) * 0.25)",
381
+ 1.5: "calc(var(--tsrd-font-size) * 0.375)",
382
+ 2: "calc(var(--tsrd-font-size) * 0.5)",
383
+ 2.5: "calc(var(--tsrd-font-size) * 0.625)",
384
+ 3: "calc(var(--tsrd-font-size) * 0.75)",
385
+ 3.5: "calc(var(--tsrd-font-size) * 0.875)",
386
+ 4: "calc(var(--tsrd-font-size) * 1)",
387
+ 4.5: "calc(var(--tsrd-font-size) * 1.125)",
388
+ 5: "calc(var(--tsrd-font-size) * 1.25)",
389
+ 5.5: "calc(var(--tsrd-font-size) * 1.375)",
390
+ 6: "calc(var(--tsrd-font-size) * 1.5)",
391
+ 6.5: "calc(var(--tsrd-font-size) * 1.625)",
392
+ 7: "calc(var(--tsrd-font-size) * 1.75)",
393
+ 8: "calc(var(--tsrd-font-size) * 2)",
394
+ 9: "calc(var(--tsrd-font-size) * 2.25)",
395
+ 10: "calc(var(--tsrd-font-size) * 2.5)",
396
+ 11: "calc(var(--tsrd-font-size) * 2.75)",
397
+ 12: "calc(var(--tsrd-font-size) * 3)",
398
+ 14: "calc(var(--tsrd-font-size) * 3.5)",
399
+ 16: "calc(var(--tsrd-font-size) * 4)",
400
+ 20: "calc(var(--tsrd-font-size) * 5)",
401
+ 24: "calc(var(--tsrd-font-size) * 6)",
402
+ 28: "calc(var(--tsrd-font-size) * 7)",
403
+ 32: "calc(var(--tsrd-font-size) * 8)",
404
+ 36: "calc(var(--tsrd-font-size) * 9)",
405
+ 40: "calc(var(--tsrd-font-size) * 10)",
406
+ 44: "calc(var(--tsrd-font-size) * 11)",
407
+ 48: "calc(var(--tsrd-font-size) * 12)",
408
+ 52: "calc(var(--tsrd-font-size) * 13)",
409
+ 56: "calc(var(--tsrd-font-size) * 14)",
410
+ 60: "calc(var(--tsrd-font-size) * 15)",
411
+ 64: "calc(var(--tsrd-font-size) * 16)",
412
+ 72: "calc(var(--tsrd-font-size) * 18)",
413
+ 80: "calc(var(--tsrd-font-size) * 20)",
414
+ 96: "calc(var(--tsrd-font-size) * 24)"
415
+ },
416
+ shadow: {
417
+ xs: (_ = "rgb(0 0 0 / 0.1)") => `0 1px 2px 0 rgb(0 0 0 / 0.05)`,
418
+ sm: (color = "rgb(0 0 0 / 0.1)") => `0 1px 3px 0 ${color}, 0 1px 2px -1px ${color}`,
419
+ md: (color = "rgb(0 0 0 / 0.1)") => `0 4px 6px -1px ${color}, 0 2px 4px -2px ${color}`,
420
+ lg: (color = "rgb(0 0 0 / 0.1)") => `0 10px 15px -3px ${color}, 0 4px 6px -4px ${color}`,
421
+ xl: (color = "rgb(0 0 0 / 0.1)") => `0 20px 25px -5px ${color}, 0 8px 10px -6px ${color}`,
422
+ "2xl": (color = "rgb(0 0 0 / 0.25)") => `0 25px 50px -12px ${color}`,
423
+ inner: (color = "rgb(0 0 0 / 0.05)") => `inset 0 2px 4px 0 ${color}`,
424
+ none: () => `none`
425
+ },
426
+ zIndices: {
427
+ hide: -1,
428
+ auto: "auto",
429
+ base: 0,
430
+ docked: 10,
431
+ dropdown: 1e3,
432
+ sticky: 1100,
433
+ banner: 1200,
434
+ overlay: 1300,
435
+ modal: 1400,
436
+ popover: 1500,
437
+ skipLink: 1600,
438
+ toast: 1700,
439
+ tooltip: 1800
440
+ }
441
+ };
442
+ //#endregion
443
+ //#region src/styles/use-styles.ts
444
+ const stylesFactory = (theme) => {
445
+ const { colors, font, size, alpha, border } = tokens;
446
+ const { fontFamily, size: fontSize } = font;
447
+ const css = goober.css;
448
+ const t = (light, dark) => theme === "light" ? light : dark;
449
+ return {
450
+ mainContainer: css`
451
+ display: flex;
452
+ flex: 1;
453
+ min-height: 0;
454
+ overflow: hidden;
455
+ padding: ${size[2]};
456
+ padding-top: 0;
457
+ margin-top: ${size[2]};
458
+ `,
459
+ dragHandle: css`
460
+ width: 8px;
461
+ background: ${t(colors.gray[300], colors.darkGray[600])};
462
+ cursor: col-resize;
463
+ position: relative;
464
+ transition: all 0.2s ease;
465
+ user-select: none;
466
+ pointer-events: all;
467
+ margin: 0 ${size[1]};
468
+ border-radius: 2px;
469
+
470
+ &:hover {
471
+ background: ${t(colors.blue[600], colors.blue[500])};
472
+ margin: 0 ${size[1]};
473
+ }
474
+
475
+ &.dragging {
476
+ background: ${t(colors.blue[700], colors.blue[600])};
477
+ margin: 0 ${size[1]};
478
+ }
479
+
480
+ &::after {
481
+ content: '';
482
+ position: absolute;
483
+ top: 50%;
484
+ left: 50%;
485
+ transform: translate(-50%, -50%);
486
+ width: 2px;
487
+ height: 20px;
488
+ background: ${t(colors.gray[400], colors.darkGray[400])};
489
+ border-radius: 1px;
490
+ pointer-events: none;
491
+ }
492
+
493
+ &:hover::after,
494
+ &.dragging::after {
495
+ background: ${t(colors.blue[500], colors.blue[300])};
496
+ }
497
+ `,
498
+ leftPanel: css`
499
+ background: ${t(colors.gray[100], colors.darkGray[800])};
500
+ border-radius: ${border.radius.lg};
501
+ border: 1px solid ${t(colors.gray[200], colors.darkGray[700])};
502
+ display: flex;
503
+ flex-direction: column;
504
+ overflow: hidden;
505
+ min-height: 0;
506
+ flex-shrink: 0;
507
+ `,
508
+ rightPanel: css`
509
+ background: ${t(colors.gray[100], colors.darkGray[800])};
510
+ border-radius: ${border.radius.lg};
511
+ border: 1px solid ${t(colors.gray[200], colors.darkGray[700])};
512
+ display: flex;
513
+ flex-direction: column;
514
+ overflow: hidden;
515
+ min-height: 0;
516
+ flex: 1;
517
+ `,
518
+ panelHeader: css`
519
+ font-size: ${fontSize.md};
520
+ font-weight: ${font.weight.bold};
521
+ color: ${t(colors.blue[700], colors.blue[400])};
522
+ padding: ${size[2]};
523
+ border-bottom: 1px solid ${t(colors.gray[200], colors.darkGray[700])};
524
+ background: ${t(colors.gray[100], colors.darkGray[800])};
525
+ flex-shrink: 0;
526
+ `,
527
+ utilList: css`
528
+ flex: 1;
529
+ overflow-y: auto;
530
+ padding: ${size[1]};
531
+ min-height: 0;
532
+ `,
533
+ utilGroup: css`
534
+ margin-bottom: ${size[2]};
535
+ `,
536
+ utilGroupHeader: css`
537
+ font-size: ${fontSize.xs};
538
+ font-weight: ${font.weight.semibold};
539
+ color: ${t(colors.gray[600], colors.gray[400])};
540
+ text-transform: uppercase;
541
+ letter-spacing: 0.05em;
542
+ margin-bottom: ${size[1]};
543
+ padding: ${size[1]} ${size[2]};
544
+ background: ${t(colors.gray[200], colors.darkGray[700])};
545
+ border-radius: ${border.radius.md};
546
+ `,
547
+ utilRow: css`
548
+ display: flex;
549
+ justify-content: space-between;
550
+ align-items: center;
551
+ padding: ${size[2]};
552
+ margin-bottom: ${size[1]};
553
+ background: ${t(colors.gray[200], colors.darkGray[700])};
554
+ border-radius: ${border.radius.md};
555
+ cursor: pointer;
556
+ transition: all 0.2s ease;
557
+ border: 1px solid transparent;
558
+
559
+ &:hover {
560
+ background: ${t(colors.gray[300], colors.darkGray[600])};
561
+ border-color: ${t(colors.gray[400], colors.darkGray[500])};
562
+ }
563
+ `,
564
+ utilRowSelected: css`
565
+ background: ${t(colors.blue[100], colors.blue[900] + alpha[20])};
566
+ border-color: ${t(colors.blue[600], colors.blue[500])};
567
+ box-shadow: 0 0 0 1px
568
+ ${t(colors.blue[600] + alpha[30], colors.blue[500] + alpha[30])};
569
+ `,
570
+ utilKey: css`
571
+ font-family: ${fontFamily.mono};
572
+ font-size: ${fontSize.xs};
573
+ color: ${t(colors.gray[900], colors.gray[100])};
574
+ flex: 1;
575
+ overflow: hidden;
576
+ text-overflow: ellipsis;
577
+ white-space: nowrap;
578
+ `,
579
+ utilStatus: css`
580
+ font-size: ${fontSize.xs};
581
+ color: ${t(colors.gray[600], colors.gray[400])};
582
+ text-transform: uppercase;
583
+ letter-spacing: 0.05em;
584
+ padding: ${size[1]} ${size[1]};
585
+ background: ${t(colors.gray[300], colors.darkGray[600])};
586
+ border-radius: ${border.radius.sm};
587
+ margin-left: ${size[1]};
588
+ `,
589
+ stateDetails: css`
590
+ flex: 1;
591
+ overflow-y: auto;
592
+ padding: ${size[2]};
593
+ min-height: 0;
594
+ `,
595
+ stateHeader: css`
596
+ margin-bottom: ${size[2]};
597
+ padding-bottom: ${size[2]};
598
+ border-bottom: 1px solid ${t(colors.gray[200], colors.darkGray[700])};
599
+ `,
600
+ stateTitle: css`
601
+ font-size: ${fontSize.md};
602
+ font-weight: ${font.weight.bold};
603
+ color: ${t(colors.blue[700], colors.blue[400])};
604
+ margin-bottom: ${size[1]};
605
+ `,
606
+ stateKey: css`
607
+ font-family: ${fontFamily.mono};
608
+ font-size: ${fontSize.xs};
609
+ color: ${t(colors.gray[600], colors.gray[400])};
610
+ word-break: break-all;
611
+ `,
612
+ stateContent: css`
613
+ background: ${t(colors.gray[100], colors.darkGray[700])};
614
+ border-radius: ${border.radius.md};
615
+ padding: ${size[2]};
616
+ border: 1px solid ${t(colors.gray[300], colors.darkGray[600])};
617
+ `,
618
+ detailsGrid: css`
619
+ display: grid;
620
+ grid-template-columns: 1fr;
621
+ gap: ${size[2]};
622
+ align-items: start;
623
+ `,
624
+ detailSection: css`
625
+ background: ${t(colors.white, colors.darkGray[700])};
626
+ border: 1px solid ${t(colors.gray[300], colors.darkGray[600])};
627
+ border-radius: ${border.radius.md};
628
+ padding: ${size[2]};
629
+ `,
630
+ detailSectionHeader: css`
631
+ font-size: ${fontSize.sm};
632
+ font-weight: ${font.weight.bold};
633
+ color: ${t(colors.gray[800], colors.gray[200])};
634
+ margin-bottom: ${size[1]};
635
+ text-transform: uppercase;
636
+ letter-spacing: 0.04em;
637
+ `,
638
+ actionsRow: css`
639
+ display: flex;
640
+ flex-wrap: wrap;
641
+ gap: ${size[2]};
642
+ `,
643
+ actionButton: css`
644
+ display: inline-flex;
645
+ align-items: center;
646
+ gap: ${size[1]};
647
+ padding: ${size[1]} ${size[2]};
648
+ border-radius: ${border.radius.md};
649
+ border: 1px solid ${t(colors.gray[300], colors.darkGray[500])};
650
+ background: ${t(colors.gray[200], colors.darkGray[600])};
651
+ color: ${t(colors.gray[900], colors.gray[100])};
652
+ font-size: ${fontSize.xs};
653
+ cursor: pointer;
654
+ user-select: none;
655
+ transition:
656
+ background 0.15s,
657
+ border-color 0.15s;
658
+ &:hover {
659
+ background: ${t(colors.gray[300], colors.darkGray[500])};
660
+ border-color: ${t(colors.gray[400], colors.darkGray[400])};
661
+ }
662
+ &:disabled {
663
+ opacity: 0.5;
664
+ cursor: not-allowed;
665
+ &:hover {
666
+ background: ${t(colors.gray[200], colors.darkGray[600])};
667
+ border-color: ${t(colors.gray[300], colors.darkGray[500])};
668
+ }
669
+ }
670
+ `,
671
+ actionDotBlue: css`
672
+ width: 6px;
673
+ height: 6px;
674
+ border-radius: 9999px;
675
+ background: ${colors.blue[400]};
676
+ `,
677
+ actionDotGreen: css`
678
+ width: 6px;
679
+ height: 6px;
680
+ border-radius: 9999px;
681
+ background: ${colors.green[400]};
682
+ `,
683
+ actionDotRed: css`
684
+ width: 6px;
685
+ height: 6px;
686
+ border-radius: 9999px;
687
+ background: ${colors.red[400]};
688
+ `,
689
+ actionDotYellow: css`
690
+ width: 6px;
691
+ height: 6px;
692
+ border-radius: 9999px;
693
+ background: ${colors.yellow[400]};
694
+ `,
695
+ actionDotOrange: css`
696
+ width: 6px;
697
+ height: 6px;
698
+ border-radius: 9999px;
699
+ background: ${colors.pink[400]};
700
+ `,
701
+ actionDotPurple: css`
702
+ width: 6px;
703
+ height: 6px;
704
+ border-radius: 9999px;
705
+ background: ${colors.purple[400]};
706
+ `,
707
+ infoGrid: css`
708
+ display: grid;
709
+ grid-template-columns: auto 1fr;
710
+ gap: ${size[1]};
711
+ row-gap: ${size[1]};
712
+ align-items: center;
713
+ `,
714
+ infoLabel: css`
715
+ color: ${t(colors.gray[600], colors.gray[400])};
716
+ font-size: ${fontSize.xs};
717
+ text-transform: uppercase;
718
+ letter-spacing: 0.05em;
719
+ `,
720
+ infoValueMono: css`
721
+ font-family: ${fontFamily.mono};
722
+ font-size: ${fontSize.xs};
723
+ color: ${t(colors.gray[900], colors.gray[100])};
724
+ word-break: break-all;
725
+ `,
726
+ noSelection: css`
727
+ flex: 1;
728
+ display: flex;
729
+ align-items: center;
730
+ justify-content: center;
731
+ color: ${t(colors.gray[500], colors.gray[500])};
732
+ font-style: italic;
733
+ text-align: center;
734
+ padding: ${size[4]};
735
+ `,
736
+ sectionContainer: css`
737
+ display: flex;
738
+ flex-wrap: wrap;
739
+ gap: ${size[4]};
740
+ `,
741
+ section: css`
742
+ background: ${t(colors.gray[100], colors.darkGray[800])};
743
+ border-radius: ${border.radius.lg};
744
+ box-shadow: ${tokens.shadow.md(t(colors.gray[400] + alpha[80], colors.black + alpha[80]))};
745
+ padding: ${size[4]};
746
+ margin-bottom: ${size[4]};
747
+ border: 1px solid ${t(colors.gray[200], colors.darkGray[700])};
748
+ min-width: 0;
749
+ max-width: 33%;
750
+ max-height: fit-content;
751
+ `,
752
+ sectionHeader: css`
753
+ font-size: ${fontSize.lg};
754
+ font-weight: ${font.weight.bold};
755
+ margin-bottom: ${size[2]};
756
+ color: ${t(colors.blue[600], colors.blue[400])};
757
+ letter-spacing: 0.01em;
758
+ display: flex;
759
+ align-items: center;
760
+ gap: ${size[2]};
761
+ `,
762
+ sectionEmpty: css`
763
+ color: ${t(colors.gray[500], colors.gray[500])};
764
+ font-size: ${fontSize.sm};
765
+ font-style: italic;
766
+ margin: ${size[2]} 0;
767
+ `,
768
+ instanceList: css`
769
+ display: flex;
770
+ flex-direction: column;
771
+ gap: ${size[2]};
772
+ background: ${t(colors.gray[200], colors.darkGray[700])};
773
+ border: 1px solid ${t(colors.gray[300], colors.darkGray[600])};
774
+ `,
775
+ instanceCard: css`
776
+ background: ${t(colors.gray[200], colors.darkGray[700])};
777
+ border-radius: ${border.radius.md};
778
+ padding: ${size[3]};
779
+ border: 1px solid ${t(colors.gray[300], colors.darkGray[600])};
780
+ font-size: ${fontSize.sm};
781
+ color: ${t(colors.gray[900], colors.gray[100])};
782
+ font-family: ${fontFamily.mono};
783
+ overflow-x: auto;
784
+ transition:
785
+ box-shadow 0.3s,
786
+ background 0.3s;
787
+ `
788
+ };
789
+ };
790
+ function useStyles() {
791
+ const { theme } = useTheme();
792
+ const [styles, setStyles] = createSignal(stylesFactory(theme()));
793
+ createEffect(() => {
794
+ setStyles(stylesFactory(theme()));
795
+ });
796
+ return styles;
797
+ }
798
+ //#endregion
799
+ //#region src/components/util-groups.ts
800
+ const UTIL_GROUPS = [
801
+ {
802
+ key: "debouncers",
803
+ label: "Debouncers",
804
+ displayName: "Debouncer"
805
+ },
806
+ {
807
+ key: "throttlers",
808
+ label: "Throttlers",
809
+ displayName: "Throttler"
810
+ },
811
+ {
812
+ key: "batchers",
813
+ label: "Batchers",
814
+ displayName: "Batcher"
815
+ },
816
+ {
817
+ key: "queuers",
818
+ label: "Queuers",
819
+ displayName: "Queuer"
820
+ },
821
+ {
822
+ key: "rateLimiters",
823
+ label: "Rate Limiters",
824
+ displayName: "Rate Limiter"
825
+ },
826
+ {
827
+ key: "asyncDebouncers",
828
+ label: "Async Debouncers",
829
+ displayName: "Async Debouncer"
830
+ },
831
+ {
832
+ key: "asyncThrottlers",
833
+ label: "Async Throttlers",
834
+ displayName: "Async Throttler"
835
+ },
836
+ {
837
+ key: "asyncBatchers",
838
+ label: "Async Batchers",
839
+ displayName: "Async Batcher"
840
+ },
841
+ {
842
+ key: "asyncQueuers",
843
+ label: "Async Queuers",
844
+ displayName: "Async Queuer"
845
+ },
846
+ {
847
+ key: "asyncRateLimiters",
848
+ label: "Async Rate Limiters",
849
+ displayName: "Async Rate Limiter"
850
+ }
851
+ ];
852
+ //#endregion
853
+ //#region src/components/UtilList.tsx
854
+ var _tmpl$$4 = [
855
+ "<div",
856
+ ">",
857
+ "</div>"
858
+ ], _tmpl$2$2 = [
859
+ "<div",
860
+ "><div",
861
+ ">",
862
+ "</div>",
863
+ "</div>"
864
+ ], _tmpl$3$2 = [
865
+ "<div",
866
+ "><div",
867
+ ">",
868
+ "</div><div",
869
+ ">",
870
+ "</div></div>"
871
+ ];
872
+ function UtilList(props) {
873
+ const styles = useStyles();
874
+ return ssr(_tmpl$$4, ssrAttribute("class", escape(styles().utilList, true), false), escape(createComponent(For, {
875
+ each: UTIL_GROUPS,
876
+ children: (group) => props.utilState()[group.key].length > 0 && ssr(_tmpl$2$2, ssrAttribute("class", escape(styles().utilGroup, true), false), ssrAttribute("class", escape(styles().utilGroupHeader, true), false), escape(group.label), escape(createComponent(For, {
877
+ get each() {
878
+ return props.utilState()[group.key];
879
+ },
880
+ children: (instance) => {
881
+ const status = (() => {
882
+ try {
883
+ const statusAccessor = useStore(instance.store, (s) => s.status);
884
+ return () => statusAccessor() ?? "unknown";
885
+ } catch {
886
+ return () => "unknown";
887
+ }
888
+ })();
889
+ return ssr(_tmpl$3$2, ssrAttribute("class", escape(clsx(styles().utilRow, props.selectedKey() === instance.key && styles().utilRowSelected), true), false), ssrAttribute("class", escape(styles().utilKey, true), false), escape(instance.key), ssrAttribute("class", escape(styles().utilStatus, true), false), escape(status()));
890
+ }
891
+ })))
892
+ })));
893
+ }
894
+ //#endregion
895
+ //#region src/components/ActionButtons.tsx
896
+ var _tmpl$$3 = ["<div", ">No actions available for this util</div>"], _tmpl$2$1 = [
897
+ "<div",
898
+ ">",
899
+ "",
900
+ "",
901
+ "",
902
+ "",
903
+ "",
904
+ "</div>"
905
+ ], _tmpl$3$1 = [
906
+ "<button",
907
+ "><span",
908
+ "></span>",
909
+ "</button>"
910
+ ], _tmpl$4 = [
911
+ "<button",
912
+ "",
913
+ "><span",
914
+ "></span>Flush</button>"
915
+ ], _tmpl$5 = [
916
+ "<button",
917
+ "",
918
+ "><span",
919
+ "></span>Cancel</button>"
920
+ ], _tmpl$6 = [
921
+ "<button",
922
+ "><span",
923
+ "></span>Reset</button>"
924
+ ], _tmpl$7 = [
925
+ "<button",
926
+ "",
927
+ "><span",
928
+ "></span>Clear</button>"
929
+ ];
930
+ function ActionButtons(props) {
931
+ const styles = useStyles();
932
+ const utilInstance = props.instance;
933
+ const utilState = utilInstance?.store?.state;
934
+ const hasPending = utilState && "isPending" in utilState;
935
+ const hasEmpty = utilState && "isEmpty" in utilState;
936
+ const isPending = hasPending ? !!utilState.isPending : false;
937
+ const isEmpty = hasEmpty ? utilState.isEmpty : void 0;
938
+ const hasFlush = typeof utilInstance.flush === "function";
939
+ const hasCancel = typeof utilInstance.cancel === "function";
940
+ const hasReset = typeof utilInstance.reset === "function";
941
+ const hasClear = typeof utilInstance.clear === "function";
942
+ const hasStart = typeof utilInstance.start === "function";
943
+ const hasStop = typeof utilInstance.stop === "function";
944
+ const hasStartStop = hasStart && hasStop;
945
+ const isRunning = utilState?.isRunning ?? true;
946
+ if (!hasPending && !hasFlush && !hasCancel && !hasReset && !hasClear) return ssr(_tmpl$$3, ssrAttribute("class", escape(styles().sectionEmpty, true), false));
947
+ `${props.utilName}`;
948
+ return ssr(_tmpl$2$1, ssrAttribute("class", escape(styles().actionsRow, true), false), hasPending && ssr(_tmpl$3$1, ssrAttribute("class", escape(styles().actionButton, true), false), ssrAttribute("class", escape(styles().actionDotBlue, true), false), isPending ? "Restore Pending" : "Trigger Pending"), hasFlush && ssr(_tmpl$4, ssrAttribute("class", escape(styles().actionButton, true), false), ssrAttribute("disabled", props.utilName.toLowerCase().includes("debouncer") && !isPending || props.utilName.toLowerCase().includes("throttler") && !isPending || props.utilName.toLowerCase().includes("batcher") && isEmpty || props.utilName.toLowerCase().includes("queuer") && isEmpty, true), ssrAttribute("class", escape(styles().actionDotGreen, true), false)), hasCancel && ssr(_tmpl$5, ssrAttribute("class", escape(styles().actionButton, true), false), ssrAttribute("disabled", props.utilName.toLowerCase().includes("debouncer") && !isPending || props.utilName.toLowerCase().includes("throttler") && !isPending || props.utilName.toLowerCase().includes("batcher") && isEmpty || props.utilName.toLowerCase().includes("queuer") && isEmpty, true), ssrAttribute("class", escape(styles().actionDotRed, true), false)), hasReset && ssr(_tmpl$6, ssrAttribute("class", escape(styles().actionButton, true), false), ssrAttribute("class", escape(styles().actionDotYellow, true), false)), hasClear && ssr(_tmpl$7, ssrAttribute("class", escape(styles().actionButton, true), false), ssrAttribute("disabled", props.utilName.toLowerCase().includes("batcher") && isEmpty || props.utilName.toLowerCase().includes("queuer") && isEmpty, true), ssrAttribute("class", escape(styles().actionDotOrange, true), false)), hasStartStop && ssr(_tmpl$3$1, ssrAttribute("class", escape(styles().actionButton, true), false), ssrAttribute("class", escape(styles().actionDotPurple, true), false), isRunning ? "Stop" : "Start"));
949
+ }
950
+ //#endregion
951
+ //#region src/components/StateHeader.tsx
952
+ var _tmpl$$2 = [
953
+ "<div",
954
+ "><div",
955
+ ">",
956
+ "</div><div style=\"",
957
+ "\"><div",
958
+ "><div",
959
+ ">Key</div><div",
960
+ ">",
961
+ "</div><div",
962
+ ">Last Updated</div><div",
963
+ ">",
964
+ " (",
965
+ ")</div></div><div",
966
+ " style=\"",
967
+ "\">",
968
+ "% reduction</div></div></div>"
969
+ ];
970
+ dayjs.extend(relativeTime);
971
+ function StateHeader(props) {
972
+ const styles = useStyles();
973
+ const [now, setNow] = createSignal(Date.now());
974
+ onMount(() => {
975
+ const interval = setInterval(() => {
976
+ setNow(Date.now());
977
+ }, 1e3);
978
+ onCleanup(() => {
979
+ clearInterval(interval);
980
+ });
981
+ });
982
+ const entry = props.selectedInstance();
983
+ if (!entry) return null;
984
+ const key = entry.instance.key;
985
+ const updatedAt = props.utilState().lastUpdatedByKey[key] ?? Date.now();
986
+ const getRelativeTime = () => {
987
+ const diffMs = now() - updatedAt;
988
+ const diffSeconds = Math.floor(diffMs / 1e3);
989
+ if (diffSeconds < 60) return `${diffSeconds} second${diffSeconds !== 1 ? "s" : ""} ago`;
990
+ return dayjs(updatedAt).fromNow();
991
+ };
992
+ const getReductionPercentage = () => {
993
+ const state = entry.instance.store?.state || entry.instance.state;
994
+ if (!state) return 0;
995
+ const completedExecutions = entry.type.toLowerCase().includes("async") ? state.settleCount || 0 : state.executionCount || 0;
996
+ if (entry.type.toLowerCase().includes("batcher")) {
997
+ const totalItemsProcessed = state.totalItemsProcessed || 0;
998
+ if (totalItemsProcessed === 0) return 0;
999
+ return Math.round((totalItemsProcessed - completedExecutions) / totalItemsProcessed * 100);
1000
+ }
1001
+ let requestCount = 0;
1002
+ if (state.maybeExecuteCount !== void 0) requestCount = state.maybeExecuteCount;
1003
+ else if (state.addItemCount !== void 0) requestCount = state.addItemCount;
1004
+ else return 0;
1005
+ if (requestCount === 0) return 0;
1006
+ const reduction = requestCount - completedExecutions;
1007
+ return Math.round(reduction / requestCount * 100);
1008
+ };
1009
+ const reductionPercentage = getReductionPercentage();
1010
+ return ssr(_tmpl$$2, ssrAttribute("class", escape(styles().stateHeader, true), false), ssrAttribute("class", escape(styles().stateTitle, true), false), escape(entry.type), ssrStyleProperty("display:", "flex") + ssrStyleProperty(";align-items:", "center") + ssrStyleProperty(";gap:", "16px"), ssrAttribute("class", escape(styles().infoGrid, true), false), ssrAttribute("class", escape(styles().infoLabel, true), false), ssrAttribute("class", escape(styles().infoValueMono, true), false), escape(key), ssrAttribute("class", escape(styles().infoLabel, true), false), ssrAttribute("class", escape(styles().infoValueMono, true), false), escape(new Date(updatedAt).toLocaleTimeString()), escape(getRelativeTime()), ssrAttribute("class", escape(styles().infoValueMono, true), false), ssrStyleProperty("margin-left:", "auto") + ssrStyleProperty(";font-weight:", "bold"), escape(reductionPercentage));
1011
+ }
1012
+ //#endregion
1013
+ //#region src/components/DetailsPanel.tsx
1014
+ var _tmpl$$1 = [
1015
+ "<div",
1016
+ ">",
1017
+ "</div>"
1018
+ ], _tmpl$2 = ["<div", ">Select a util from the left panel to view its state</div>"], _tmpl$3 = [
1019
+ "<div",
1020
+ "><div",
1021
+ "><div",
1022
+ ">Actions</div>",
1023
+ "</div><div",
1024
+ "><div",
1025
+ ">State</div><div",
1026
+ ">",
1027
+ "</div></div><div",
1028
+ "><div",
1029
+ ">Options</div><div",
1030
+ ">",
1031
+ "</div></div></div>"
1032
+ ];
1033
+ function DetailsPanel(props) {
1034
+ const styles = useStyles();
1035
+ return ssr(_tmpl$$1, ssrAttribute("class", escape(styles().stateDetails, true), false), (() => {
1036
+ const entry = props.selectedInstance();
1037
+ if (!entry) return ssr(_tmpl$2, ssrAttribute("class", escape(styles().noSelection, true), false));
1038
+ return escape([createComponent(StateHeader, {
1039
+ get selectedInstance() {
1040
+ return props.selectedInstance;
1041
+ },
1042
+ get utilState() {
1043
+ return props.utilState;
1044
+ }
1045
+ }), ssr(_tmpl$3, ssrAttribute("class", escape(styles().detailsGrid, true), false), ssrAttribute("class", escape(styles().detailSection, true), false), ssrAttribute("class", escape(styles().detailSectionHeader, true), false), escape(createComponent(ActionButtons, {
1046
+ get instance() {
1047
+ return entry.instance;
1048
+ },
1049
+ get utilName() {
1050
+ return entry.type;
1051
+ }
1052
+ })), ssrAttribute("class", escape(styles().detailSection, true), false), ssrAttribute("class", escape(styles().detailSectionHeader, true), false), ssrAttribute("class", escape(styles().stateContent, true), false), escape(createComponent(JsonTree, { get value() {
1053
+ return entry.instance.store?.state;
1054
+ } })), ssrAttribute("class", escape(styles().detailSection, true), false), ssrAttribute("class", escape(styles().detailSectionHeader, true), false), ssrAttribute("class", escape(styles().stateContent, true), false), escape(createComponent(JsonTree, { get value() {
1055
+ return entry.instance.options;
1056
+ } })))]);
1057
+ })());
1058
+ }
1059
+ //#endregion
1060
+ //#region src/components/Shell.tsx
1061
+ var _tmpl$ = [
1062
+ "<div",
1063
+ "><div",
1064
+ " style=\"",
1065
+ "\">",
1066
+ "</div><div class=\"",
1067
+ "\"></div><div",
1068
+ " style=\"",
1069
+ "\"><div",
1070
+ ">Details</div>",
1071
+ "</div></div>"
1072
+ ];
1073
+ function Shell() {
1074
+ const styles = useStyles();
1075
+ const state = usePacerDevtoolsState();
1076
+ const utilState = () => state;
1077
+ const [selectedKey, setSelectedKey] = createSignal(null);
1078
+ const [leftPanelWidth, setLeftPanelWidth] = createSignal(300);
1079
+ const [isDragging, setIsDragging] = createSignal(false);
1080
+ const selectedInstance = createMemo(() => {
1081
+ const key = selectedKey();
1082
+ if (!key) return null;
1083
+ for (const group of UTIL_GROUPS) {
1084
+ const instance = utilState()[group.key].find((inst) => inst.key === key);
1085
+ if (instance) return {
1086
+ instance,
1087
+ type: group.displayName
1088
+ };
1089
+ }
1090
+ return null;
1091
+ });
1092
+ let dragStartX = 0;
1093
+ let dragStartWidth = 0;
1094
+ const handleMouseMove = (e) => {
1095
+ if (!isDragging()) return;
1096
+ e.preventDefault();
1097
+ const deltaX = e.clientX - dragStartX;
1098
+ setLeftPanelWidth(Math.max(150, Math.min(800, dragStartWidth + deltaX)));
1099
+ };
1100
+ const handleMouseUp = () => {
1101
+ setIsDragging(false);
1102
+ document.body.style.cursor = "";
1103
+ document.body.style.userSelect = "";
1104
+ };
1105
+ onMount(() => {
1106
+ document.addEventListener("mousemove", handleMouseMove);
1107
+ document.addEventListener("mouseup", handleMouseUp);
1108
+ });
1109
+ onCleanup(() => {
1110
+ document.removeEventListener("mousemove", handleMouseMove);
1111
+ document.removeEventListener("mouseup", handleMouseUp);
1112
+ });
1113
+ return createComponent(MainPanel, { get children() {
1114
+ return [createComponent(Header, { get children() {
1115
+ return createComponent(HeaderLogo, {
1116
+ flavor: {
1117
+ light: "#84cc16",
1118
+ dark: "#84cc16"
1119
+ },
1120
+ children: "TanStack Pacer"
1121
+ });
1122
+ } }), ssr(_tmpl$, ssrAttribute("class", escape(styles().mainContainer, true), false), ssrAttribute("class", escape(styles().leftPanel, true), false), ssrStyleProperty("width:", `${escape(leftPanelWidth(), true)}px`) + ssrStyleProperty(";min-width:", "150px") + ssrStyleProperty(";max-width:", "800px"), escape(createComponent(UtilList, {
1123
+ selectedKey,
1124
+ setSelectedKey,
1125
+ utilState
1126
+ })), `${escape(styles().dragHandle, true)} ${isDragging() ? "dragging" : ""}`, ssrAttribute("class", escape(styles().rightPanel, true), false), ssrStyleProperty("flex:", 1), ssrAttribute("class", escape(styles().panelHeader, true), false), escape(createComponent(DetailsPanel, {
1127
+ selectedInstance,
1128
+ utilState
1129
+ })))];
1130
+ } });
1131
+ }
1132
+ //#endregion
1133
+ //#region src/PacerDevtools.tsx
1134
+ function PacerDevtools(props) {
1135
+ return createComponent(ThemeContextProvider, {
1136
+ get theme() {
1137
+ return props.theme;
1138
+ },
1139
+ get children() {
1140
+ return createComponent(PacerContextProvider, { get children() {
1141
+ return createComponent(Shell, {});
1142
+ } });
1143
+ }
1144
+ });
1145
+ }
1146
+ //#endregion
1147
+ export { PacerDevtools as default };