@reactra/devtools 0.1.0-alpha.0

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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +78 -0
  3. package/dist/ValueTree.d.ts +38 -0
  4. package/dist/ValueTree.d.ts.map +1 -0
  5. package/dist/ValueTree.js +178 -0
  6. package/dist/ValueTree.js.map +1 -0
  7. package/dist/helpers.d.ts +59 -0
  8. package/dist/helpers.d.ts.map +1 -0
  9. package/dist/helpers.js +110 -0
  10. package/dist/helpers.js.map +1 -0
  11. package/dist/hookRecorder.d.ts +72 -0
  12. package/dist/hookRecorder.d.ts.map +1 -0
  13. package/dist/hookRecorder.js +142 -0
  14. package/dist/hookRecorder.js.map +1 -0
  15. package/dist/index.d.ts +10 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +16 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/invoke.d.ts +35 -0
  20. package/dist/invoke.d.ts.map +1 -0
  21. package/dist/invoke.js +67 -0
  22. package/dist/invoke.js.map +1 -0
  23. package/dist/model.d.ts +99 -0
  24. package/dist/model.d.ts.map +1 -0
  25. package/dist/model.js +160 -0
  26. package/dist/model.js.map +1 -0
  27. package/dist/panel.d.ts +17 -0
  28. package/dist/panel.d.ts.map +1 -0
  29. package/dist/panel.js +438 -0
  30. package/dist/panel.js.map +1 -0
  31. package/dist/routerWatcher.d.ts +47 -0
  32. package/dist/routerWatcher.d.ts.map +1 -0
  33. package/dist/routerWatcher.js +51 -0
  34. package/dist/routerWatcher.js.map +1 -0
  35. package/dist/serialize.d.ts +38 -0
  36. package/dist/serialize.d.ts.map +1 -0
  37. package/dist/serialize.js +217 -0
  38. package/dist/serialize.js.map +1 -0
  39. package/dist/storeRecorder.d.ts +25 -0
  40. package/dist/storeRecorder.d.ts.map +1 -0
  41. package/dist/storeRecorder.js +94 -0
  42. package/dist/storeRecorder.js.map +1 -0
  43. package/dist/storeWatcher.d.ts +26 -0
  44. package/dist/storeWatcher.d.ts.map +1 -0
  45. package/dist/storeWatcher.js +24 -0
  46. package/dist/storeWatcher.js.map +1 -0
  47. package/dist/styles.d.ts +5 -0
  48. package/dist/styles.d.ts.map +1 -0
  49. package/dist/styles.js +288 -0
  50. package/dist/styles.js.map +1 -0
  51. package/dist/tabs/router.d.ts +10 -0
  52. package/dist/tabs/router.d.ts.map +1 -0
  53. package/dist/tabs/router.js +48 -0
  54. package/dist/tabs/router.js.map +1 -0
  55. package/dist/tabs/stores.d.ts +14 -0
  56. package/dist/tabs/stores.d.ts.map +1 -0
  57. package/dist/tabs/stores.js +167 -0
  58. package/dist/tabs/stores.js.map +1 -0
  59. package/dist/tabs/timeTravel.d.ts +46 -0
  60. package/dist/tabs/timeTravel.d.ts.map +1 -0
  61. package/dist/tabs/timeTravel.js +322 -0
  62. package/dist/tabs/timeTravel.js.map +1 -0
  63. package/package.json +43 -0
package/dist/styles.js ADDED
@@ -0,0 +1,288 @@
1
+ // @reactra/devtools — injected stylesheet.
2
+ //
3
+ // Owner: reactra-devtools-spec.md §2 + reactra-runtime-spec.md §2
4
+ // (UI-companion tier): no `.css` imports in package source, so the panel
5
+ // ships its styles as a string and injects ONE <style> tag per document
6
+ // (the popup-out window gets its own — Devtools §2), behind a
7
+ // `typeof document` guard. All selectors are prefixed `.rdt-`; the
8
+ // timeline's `.rrd-*` sheet is injected separately via
9
+ // `@reactra/replay-devtools/timeline`'s `ensureStyles` — never duplicated.
10
+ //
11
+ // The `--rdt-*` token block is shared with `@reactra/replay-devtools` via the
12
+ // `/tokens` subpath (C7 — reactra-runtime-spec.md §3 /tokens row).
13
+ // `ensureStyles` calls `ensureTokens` so the popup window also gets tokens.
14
+ import { ensureTokens } from "@reactra/replay-devtools/tokens";
15
+ let injected = new WeakSet();
16
+ /** Append the devtools stylesheet once per document. No-op outside a browser. */
17
+ export const ensureStyles = (target) => {
18
+ const doc = target ?? (typeof document === "undefined" ? undefined : document);
19
+ if (!doc || injected.has(doc))
20
+ return;
21
+ injected.add(doc);
22
+ // Tokens first — the devtools CSS references `var(--rdt-*)`.
23
+ ensureTokens(doc);
24
+ const tag = doc.createElement("style");
25
+ tag.setAttribute("data-reactra-devtools", "");
26
+ tag.textContent = CSS;
27
+ doc.head.appendChild(tag);
28
+ };
29
+ /** Test hook: lets unit tests assert single-injection semantics. */
30
+ export const __resetStylesForTest = () => {
31
+ injected = new WeakSet();
32
+ };
33
+ // Devtools-specific CSS. The `--rdt-*` variables are declared by the
34
+ // shared token block (injected above); this sheet only defines layout,
35
+ // components, and animations that are unique to the devtools panel.
36
+ const CSS = `
37
+ /* ---- Pill ---- */
38
+ .rdt-pill {
39
+ position: fixed; right: 16px; bottom: 16px; z-index: 2147483000;
40
+ display: inline-flex; align-items: center; gap: 6px;
41
+ background: var(--rdt-bg-raised); color: var(--rdt-text);
42
+ border: 1px solid var(--rdt-border-med);
43
+ border-radius: 999px; padding: 6px 14px; cursor: pointer;
44
+ font: 600 var(--rdt-sz-base)/1.2 var(--rdt-font);
45
+ box-shadow: 0 4px 14px rgba(0,0,0,.35);
46
+ }
47
+ .rdt-pill:hover { border-color: var(--rdt-border-focus); }
48
+ .rdt-logo { color: var(--rdt-accent-soft); }
49
+
50
+ /* ---- Panel shell ---- */
51
+ .rdt-panel {
52
+ position: fixed; left: 0; right: 0; bottom: 0; z-index: 2147483001;
53
+ height: 400px; display: flex; flex-direction: column;
54
+ background: var(--rdt-bg-base); color: var(--rdt-text);
55
+ border-top: 1px solid var(--rdt-border-med);
56
+ font: var(--rdt-sz-base)/1.45 var(--rdt-font);
57
+ box-shadow: 0 -6px 24px rgba(0,0,0,.4); outline: none;
58
+ }
59
+ .rdt-panel--popup {
60
+ position: static; height: 100vh; border-top: none; box-shadow: none;
61
+ }
62
+ /* Minimized: collapse to the header bar only (the body is not rendered). */
63
+ .rdt-panel--min { height: auto; }
64
+
65
+ /* Drag-resize handle (T2.4) — sits on top of the panel at its top edge. */
66
+ .rdt-resize-handle {
67
+ position: absolute; top: 0; left: 0; right: 0; height: 4px;
68
+ cursor: ns-resize; z-index: 1;
69
+ }
70
+ .rdt-resize-handle:hover { background: var(--rdt-border-focus); opacity: .5; }
71
+
72
+ .rdt-head {
73
+ display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
74
+ padding: 7px 12px; background: var(--rdt-bg-raised);
75
+ border-bottom: 1px solid var(--rdt-border);
76
+ }
77
+ .rdt-title { font-weight: 700; color: var(--rdt-text-bright); }
78
+ .rdt-spacer { flex: 1; }
79
+ .rdt-btn {
80
+ background: var(--rdt-btn-bg); color: var(--rdt-text);
81
+ border: 1px solid var(--rdt-btn-border);
82
+ border-radius: 6px; padding: 3px 10px; cursor: pointer; font: inherit;
83
+ }
84
+ .rdt-btn:hover:not(:disabled) { border-color: var(--rdt-border-focus); color: var(--rdt-text-bright); }
85
+ .rdt-btn:disabled { opacity: .4; cursor: default; }
86
+ .rdt-btn:focus-visible { outline: 2px solid var(--rdt-focus-ring); outline-offset: 2px; }
87
+ .rdt-btn--accent { background: #33285e; border-color: var(--rdt-accent); }
88
+ .rdt-mini { font-size: var(--rdt-sz-xs); padding: 1px 7px; }
89
+
90
+ /* ---- Tabs ---- */
91
+ .rdt-tabs { display: flex; gap: 4px; }
92
+ .rdt-tab {
93
+ background: transparent; color: var(--rdt-text-dim);
94
+ border: 1px solid transparent; border-bottom: 2px solid transparent;
95
+ border-radius: 6px 6px 0 0; padding: 3px 12px; cursor: pointer; font: inherit;
96
+ }
97
+ .rdt-tab:hover { color: var(--rdt-text-bright); }
98
+ .rdt-tab:focus-visible { outline: 2px solid var(--rdt-focus-ring); outline-offset: 2px; }
99
+ /* Active tab: bottom-border accent strip (UX#10) */
100
+ .rdt-tab--on {
101
+ background: var(--rdt-btn-bg); color: var(--rdt-text-bright);
102
+ border-color: var(--rdt-btn-border); border-bottom-color: var(--rdt-accent);
103
+ }
104
+
105
+ /* ---- Messages ---- */
106
+ .rdt-warn {
107
+ background: var(--rdt-warn-bg); color: var(--rdt-warn-fg); border-radius: 6px;
108
+ padding: 2px 8px; font-size: var(--rdt-sz-sm);
109
+ }
110
+ .rdt-err { color: var(--rdt-err); }
111
+ .rdt-hint { color: var(--rdt-text-faint); }
112
+
113
+ /* ---- Body layout ---- */
114
+ .rdt-body { display: flex; flex: 1; min-height: 0; }
115
+ .rdt-rail {
116
+ width: 240px; flex: none; overflow-y: auto;
117
+ border-right: 1px solid var(--rdt-border); padding: 8px 10px;
118
+ }
119
+ .rdt-rail h4 {
120
+ margin: 0 0 6px; font-size: var(--rdt-sz-sm); color: var(--rdt-text-dim);
121
+ text-transform: uppercase; letter-spacing: .06em;
122
+ }
123
+
124
+ /* Rail search input (T2.3) */
125
+ .rdt-search {
126
+ width: 100%; box-sizing: border-box;
127
+ background: var(--rdt-bg-deep); color: var(--rdt-text);
128
+ border: 1px solid var(--rdt-btn-border);
129
+ border-radius: 6px; padding: 3px 8px; font: inherit;
130
+ font-size: var(--rdt-sz-sm); margin-bottom: 6px;
131
+ }
132
+ .rdt-search:focus { outline: 2px solid var(--rdt-focus-ring); border-color: var(--rdt-border-focus); }
133
+ .rdt-search::placeholder { color: var(--rdt-text-faint); }
134
+
135
+ .rdt-item {
136
+ display: flex; align-items: center; gap: 6px; width: 100%; text-align: left;
137
+ background: transparent; color: var(--rdt-text);
138
+ border: 1px solid transparent;
139
+ border-radius: 6px; padding: 5px 8px; margin-bottom: 3px;
140
+ cursor: pointer; font: inherit;
141
+ }
142
+ .rdt-item:hover { background: var(--rdt-bg-hover); border-color: var(--rdt-border); }
143
+ .rdt-item:focus-visible { outline: 2px solid var(--rdt-focus-ring); }
144
+ .rdt-item--on { background: var(--rdt-btn-bg); border-color: var(--rdt-btn-border); }
145
+ .rdt-item--stale { opacity: .45; }
146
+ .rdt-item code { color: var(--rdt-accent-soft); }
147
+ .rdt-count { margin-left: auto; color: var(--rdt-text-faint); font-size: var(--rdt-sz-xs); }
148
+
149
+ /* Rail header row: title + optional rail-level actions (T2.2 "Clear stale") */
150
+ .rdt-rail-header {
151
+ display: flex; align-items: baseline; justify-content: space-between;
152
+ margin-bottom: 6px;
153
+ }
154
+ .rdt-rail-header h4 { margin: 0; }
155
+
156
+ /* "Clear stale" rail button (T2.2) */
157
+ .rdt-rail-action {
158
+ font-size: var(--rdt-sz-xs); color: var(--rdt-text-faint);
159
+ background: none; border: none; cursor: pointer; padding: 0; margin: 4px 0 6px;
160
+ text-decoration: underline;
161
+ }
162
+ .rdt-rail-action:hover { color: var(--rdt-text-dim); }
163
+
164
+ .rdt-main { flex: 1; min-width: 0; overflow-y: auto; padding: 10px 14px; }
165
+ .rdt-card {
166
+ background: var(--rdt-bg-raised); border: 1px solid var(--rdt-border);
167
+ border-radius: 8px; padding: 8px 12px; margin-bottom: 8px;
168
+ }
169
+ .rdt-card-id {
170
+ color: var(--rdt-accent-soft); font-weight: 700; margin-bottom: 6px;
171
+ display: flex; gap: 8px; align-items: center;
172
+ }
173
+
174
+ /* ---- Grouped sections (T1.3) ---- */
175
+ .rdt-group {
176
+ margin-bottom: 12px;
177
+ }
178
+ .rdt-group-label {
179
+ font-size: var(--rdt-sz-xs); color: var(--rdt-text-faint); text-transform: uppercase;
180
+ letter-spacing: .08em; margin-bottom: 4px; padding-bottom: 2px;
181
+ border-bottom: 1px solid var(--rdt-border);
182
+ }
183
+
184
+ /* ---- Badges ---- */
185
+ .rdt-badge { border-radius: 5px; padding: 0 6px; font-size: var(--rdt-sz-xs); font-weight: 700; }
186
+ .rdt-badge--live { background: var(--rdt-ok-bg); color: var(--rdt-ok); }
187
+ .rdt-badge--view { background: var(--rdt-view-bg); color: var(--rdt-view-fg); }
188
+ .rdt-badge--kind { background: var(--rdt-kind-bg); color: var(--rdt-kind-fg); }
189
+ .rdt-badge--stale { background: var(--rdt-stale-bg); color: var(--rdt-stale-fg); }
190
+ .rdt-badge--idle { background: var(--rdt-idle-bg); color: var(--rdt-idle-fg); }
191
+
192
+ /* ---- Sections / lists ---- */
193
+ .rdt-section {
194
+ margin: 14px 0 6px; font-size: var(--rdt-sz-sm); color: var(--rdt-text-dim);
195
+ text-transform: uppercase; letter-spacing: .06em;
196
+ }
197
+ .rdt-list { display: flex; flex-direction: column; gap: 2px; }
198
+ .rdt-row {
199
+ display: flex; align-items: center; gap: 10px; padding: 4px 8px;
200
+ border: 1px solid transparent; border-radius: 6px;
201
+ }
202
+ .rdt-row--on { background: var(--rdt-btn-bg); border-color: var(--rdt-btn-border); }
203
+ .rdt-path { color: var(--rdt-path); }
204
+ .rdt-sub { color: var(--rdt-text-faint); font-size: var(--rdt-sz-xs); }
205
+ .rdt-time { margin-left: auto; color: var(--rdt-text-faint); font-size: var(--rdt-sz-xs); }
206
+ .rdt-pair { display: inline-flex; gap: 5px; margin-right: 12px; }
207
+ .rdt-pair .rdt-k { min-width: 0; }
208
+
209
+ /* ---- Key-value rows ---- */
210
+ .rdt-kv { display: flex; gap: 8px; align-items: baseline; padding: 2px 0; }
211
+ .rdt-k { color: var(--rdt-text-dim); flex: none; min-width: 110px; }
212
+ .rdt-v { color: var(--rdt-text); word-break: break-all; white-space: pre-wrap; }
213
+ /* Timed fade: changed-key color fades out over 1.2s (UX#12).
214
+ The class is removed after the timer fires in the component. */
215
+ .rdt-v--changed {
216
+ color: var(--rdt-changed);
217
+ animation: rdt-fade-changed 1.2s ease-out forwards;
218
+ }
219
+ @keyframes rdt-fade-changed {
220
+ 0% { color: var(--rdt-changed); }
221
+ 80% { color: var(--rdt-changed); }
222
+ 100% { color: var(--rdt-text); }
223
+ }
224
+
225
+ /* ---- Value tree (T1.2) ---- */
226
+ .rdt-tree { font-size: var(--rdt-sz-sm); }
227
+ .rdt-tree-node { padding: 1px 0; }
228
+ .rdt-tree-toggle {
229
+ background: none; border: none; cursor: pointer; padding: 0 4px 0 0;
230
+ color: var(--rdt-text-dim); font: inherit; font-size: var(--rdt-sz-xs);
231
+ }
232
+ .rdt-tree-toggle:hover { color: var(--rdt-accent-soft); }
233
+ .rdt-tree-key { color: var(--rdt-text-dim); }
234
+ .rdt-tree-val { color: var(--rdt-text); }
235
+ .rdt-tree-val--str { color: #8ec07c; }
236
+ .rdt-tree-val--num { color: #b8bb26; }
237
+ .rdt-tree-val--bool { color: var(--rdt-accent-soft); }
238
+ .rdt-tree-val--null { color: var(--rdt-text-faint); }
239
+ .rdt-tree-val--sentinel { color: var(--rdt-warn-fg); }
240
+ .rdt-tree-val--resource { color: var(--rdt-kind-fg); }
241
+ .rdt-tree-children { margin-left: 14px; border-left: 1px solid var(--rdt-border); padding-left: 6px; }
242
+ /* Copy-to-clipboard affordance (T2.5) */
243
+ .rdt-copy {
244
+ background: none; border: none; cursor: pointer; padding: 0 0 0 6px;
245
+ color: var(--rdt-text-faint); font: inherit; font-size: var(--rdt-sz-xs);
246
+ opacity: 0;
247
+ transition: opacity .15s;
248
+ }
249
+ .rdt-tree-node:hover .rdt-copy { opacity: 1; }
250
+ .rdt-copy:hover { color: var(--rdt-accent-soft); }
251
+
252
+ /* ---- Invoke ---- */
253
+ .rdt-args {
254
+ background: var(--rdt-bg-deep); color: var(--rdt-text);
255
+ border: 1px solid var(--rdt-btn-border);
256
+ border-radius: 6px; padding: 2px 8px; font: inherit;
257
+ font-size: var(--rdt-sz-sm); width: 160px;
258
+ }
259
+ .rdt-run { margin-left: 6px; }
260
+ .rdt-invoke-err { color: var(--rdt-err); font-size: var(--rdt-sz-sm); margin-left: 116px; }
261
+
262
+ /* ---- Time Travel ---- */
263
+ .rdt-transport {
264
+ display: flex; align-items: center; gap: 6px; padding: 8px 0 4px; flex-wrap: wrap;
265
+ }
266
+ .rdt-pos { color: var(--rdt-text-dim); font-size: var(--rdt-sz-sm); margin-left: 4px; }
267
+ .rdt-select {
268
+ background: var(--rdt-bg-deep); color: var(--rdt-text);
269
+ border: 1px solid var(--rdt-btn-border);
270
+ border-radius: 6px; padding: 2px 6px; font: inherit; font-size: var(--rdt-sz-sm);
271
+ }
272
+ /* Full-width REPLAYING banner (UX#5 / T3.3) */
273
+ .rdt-banner {
274
+ display: block; width: 100%; box-sizing: border-box;
275
+ background: var(--rdt-banner-bg); color: var(--rdt-banner-fg);
276
+ border-radius: 0; padding: 5px 14px;
277
+ font-size: var(--rdt-sz-sm); font-weight: 700;
278
+ text-align: center; letter-spacing: .06em;
279
+ margin: 0 -14px 0; /* bleed to main edges */
280
+ }
281
+ /* Panel-level replaying state class (T3.3) */
282
+ .rdt-panel--replaying .rdt-head {
283
+ border-bottom-color: var(--rdt-banner-bg);
284
+ }
285
+ .rdt-states { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
286
+ .rdt-rec { color: var(--rdt-rec); }
287
+ `;
288
+ //# sourceMappingURL=styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,EAAE;AACF,kEAAkE;AAClE,yEAAyE;AACzE,wEAAwE;AACxE,8DAA8D;AAC9D,mEAAmE;AACnE,uDAAuD;AACvD,2EAA2E;AAC3E,EAAE;AACF,8EAA8E;AAC9E,mEAAmE;AACnE,4EAA4E;AAE5E,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AAE9D,IAAI,QAAQ,GAAG,IAAI,OAAO,EAAY,CAAA;AAEtC,iFAAiF;AACjF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAiB,EAAQ,EAAE;IACtD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;IAC9E,IAAI,CAAC,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAM;IACrC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACjB,6DAA6D;IAC7D,YAAY,CAAC,GAAG,CAAC,CAAA;IACjB,MAAM,GAAG,GAAG,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;IACtC,GAAG,CAAC,YAAY,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAA;IAC7C,GAAG,CAAC,WAAW,GAAG,GAAG,CAAA;IACrB,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;AAC3B,CAAC,CAAA;AAED,oEAAoE;AACpE,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAS,EAAE;IAC7C,QAAQ,GAAG,IAAI,OAAO,EAAY,CAAA;AACpC,CAAC,CAAA;AAED,qEAAqE;AACrE,uEAAuE;AACvE,oEAAoE;AACpE,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2PX,CAAA"}
@@ -0,0 +1,10 @@
1
+ import { type ReactNode } from "react";
2
+ import type { NavLog } from "../routerWatcher.ts";
3
+ /** Props of the Router tab. */
4
+ export interface RouterTabProps {
5
+ /** Panel-owned navigation log (records while the panel is mounted — §6). */
6
+ navLog: NavLog;
7
+ }
8
+ /** Router tab — current route, manifest, recent navigations (§6). */
9
+ export declare const RouterTab: (props: RouterTabProps) => ReactNode;
10
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/tabs/router.ts"],"names":[],"mappings":"AASA,OAAO,EAA2C,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAG/E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAEjD,+BAA+B;AAC/B,MAAM,WAAW,cAAc;IAC7B,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAA;CACf;AAgBD,qEAAqE;AACrE,eAAO,MAAM,SAAS,GAAI,OAAO,cAAc,KAAG,SA0FjD,CAAA"}
@@ -0,0 +1,48 @@
1
+ // @reactra/devtools — the Router tab (Devtools spec §6, read-only v1).
2
+ //
3
+ // Reads `@reactra/router`'s registry via the §2 data layer (routerWatcher):
4
+ // the current route (id/pattern/pathname/params/coerced query), the full
5
+ // manifest with the current route highlighted, and the recent-navigation log.
6
+ // The nav log is owned by the panel (records for the panel's whole lifetime,
7
+ // not just while this tab is visible) and passed in. Read-only in v1;
8
+ // middleware-run visualization is deferred to v1.1 (§6). createElement (no JSX).
9
+ import { createElement as h, useEffect, useState } from "react";
10
+ import { serialize } from "../serialize.js";
11
+ import { currentRoute, listRoutes, subscribeRouter } from "../routerWatcher.js";
12
+ /** Render a params/query object as `key: value` rows, or an em dash if empty. */
13
+ const objectRows = (obj) => {
14
+ const keys = Object.keys(obj);
15
+ if (keys.length === 0)
16
+ return h("span", { className: "rdt-hint" }, "—");
17
+ return keys.map((k) => h("span", { key: k, className: "rdt-pair" }, h("span", { className: "rdt-k" }, k), h("span", { className: "rdt-v" }, JSON.stringify(serialize(obj[k])))));
18
+ };
19
+ /** Router tab — current route, manifest, recent navigations (§6). */
20
+ export const RouterTab = (props) => {
21
+ const [, force] = useState(0);
22
+ useEffect(() => {
23
+ // Re-render this tab on transitions; the nav LOG itself is recorded at the
24
+ // panel level (props.navLog) so navigations off this tab still land.
25
+ const off = subscribeRouter(() => force((n) => n + 1));
26
+ return off;
27
+ }, []);
28
+ const route = currentRoute();
29
+ const routes = listRoutes();
30
+ const navs = props.navLog.entries();
31
+ return h("div", { className: "rdt-main" },
32
+ // ---- Current route ------------------------------------------------------
33
+ h("div", { className: "rdt-card" }, h("div", { className: "rdt-card-id" }, route.route ? route.route.id : "(no match)", route.route && h("span", { className: "rdt-badge rdt-badge--kind" }, route.route.path)), h("div", { className: "rdt-kv" }, h("span", { className: "rdt-k" }, "pathname"), h("span", { className: "rdt-v rdt-path" }, route.pathname)), h("div", { className: "rdt-kv" }, h("span", { className: "rdt-k" }, "params"), h("span", { className: "rdt-v" }, objectRows(route.params))), h("div", { className: "rdt-kv" }, h("span", { className: "rdt-k" }, "query"), h("span", { className: "rdt-v" }, objectRows(route.query)))),
34
+ // ---- Manifest -----------------------------------------------------------
35
+ h("h4", { className: "rdt-section" }, `Manifest (${routes.length})`), routes.length === 0
36
+ ? h("div", { className: "rdt-hint" }, "No routes registered.")
37
+ : h("div", { className: "rdt-list" }, ...routes.map((r) => h("div", {
38
+ key: r.id,
39
+ className: route.route && r.id === route.route.id ? "rdt-row rdt-row--on" : "rdt-row",
40
+ }, h("span", { className: "rdt-path" }, r.path), h("span", { className: "rdt-sub" }, r.id), route.route && r.id === route.route.id &&
41
+ h("span", { className: "rdt-badge rdt-badge--live" }, "current")))),
42
+ // ---- Recent navigations -------------------------------------------------
43
+ h("h4", { className: "rdt-section" }, `Recent navigations (${navs.length})`), navs.length === 0
44
+ ? h("div", { className: "rdt-hint" }, "No navigations yet — they're recorded while the panel is mounted.")
45
+ : h("div", { className: "rdt-list" }, ...navs.map((n, i) => h("div", { key: `${n.timestamp}.${i}`, className: "rdt-row" }, h("span", { className: "rdt-path" }, n.pathname), Object.keys(n.params).length > 0 &&
46
+ h("span", { className: "rdt-sub" }, JSON.stringify(n.params)), h("span", { className: "rdt-time" }, new Date(n.timestamp).toLocaleTimeString())))));
47
+ };
48
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/tabs/router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type ReactNode } from "react";
2
+ import type { DevtoolsModel } from "../model.ts";
3
+ /** Props of the Stores tab. */
4
+ export interface StoresTabProps {
5
+ /**
6
+ * The DevtoolsModel facade — its subscribe() provides the consolidated
7
+ * ticker (T2.1 / arch#2a). When omitted, the tab falls back to its own
8
+ * 700ms poll (backward-compat for isolated unit tests).
9
+ */
10
+ model?: DevtoolsModel;
11
+ }
12
+ /** Stores tab — registered bindings, kind chips, live snapshots (§5). */
13
+ export declare const StoresTab: (props: StoresTabProps) => ReactNode;
14
+ //# sourceMappingURL=stores.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stores.d.ts","sourceRoot":"","sources":["../../src/tabs/stores.ts"],"names":[],"mappings":"AAQA,OAAO,EAAmD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAIvF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAShD,+BAA+B;AAC/B,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,KAAK,CAAC,EAAE,aAAa,CAAA;CACtB;AAED,yEAAyE;AACzE,eAAO,MAAM,SAAS,GAAI,OAAO,cAAc,KAAG,SA2NjD,CAAA"}
@@ -0,0 +1,167 @@
1
+ // @reactra/devtools — the Stores tab (Devtools spec §5).
2
+ //
3
+ // Reads `@reactra/store`'s registry via the §2 data layer (storeWatcher):
4
+ // every registered binding with its kind chip + instantiation state, and a
5
+ // live diffed snapshot for instantiated stores (store actions get the §4
6
+ // `▶ run` treatment, DVT004). Read-only otherwise — no store time travel
7
+ // (§10). createElement (no JSX); browser globals only in effects.
8
+ import { createElement as h, useEffect, useRef, useState } from "react";
9
+ import { diffKeys } from "@reactra/replay-devtools/timeline";
10
+ import { callableNames, groupBindings } from "../helpers.js";
11
+ import { runInvoke } from "../invoke.js";
12
+ import { serializeBindings } from "../serialize.js";
13
+ import { ValueTree } from "../ValueTree.js";
14
+ import { listStores, storeSnapshot, subscribeStore } from "../storeWatcher.js";
15
+ /** The kind chip text — `route+subtree` when the binding carries a subtree path (§5). */
16
+ const kindLabel = (r) => (r.subtreePath ? "route+subtree" : r.kind);
17
+ /** Stores tab — registered bindings, kind chips, live snapshots (§5). */
18
+ export const StoresTab = (props) => {
19
+ const { model } = props;
20
+ const [, force] = useState(0);
21
+ const [sel, setSel] = useState(null);
22
+ const [argText, setArgText] = useState({});
23
+ const [invokeErr, setInvokeErr] = useState({});
24
+ // T2.3: search filter for the stores rail — case-insensitive substring.
25
+ const [search, setSearch] = useState("");
26
+ // Previous data snapshot per store — drives the changed-key flash.
27
+ const prevRef = useRef(new Map());
28
+ const rows = listStores();
29
+ // T2.3: apply search filter before rendering.
30
+ const searchLower = search.toLowerCase();
31
+ const filteredRows = searchLower
32
+ ? rows.filter((r) => r.name.toLowerCase().includes(searchLower))
33
+ : rows;
34
+ // The set of LIVE stores; the effect re-subscribes whenever it changes
35
+ // (a route store instantiating on entry).
36
+ const liveKey = rows.map((r) => (r.instantiated ? r.name : "")).join("|");
37
+ useEffect(() => {
38
+ const bump = () => force((n) => n + 1);
39
+ // Subscribe to live store changes for instant delivery on value changes.
40
+ const offs = rows.filter((r) => r.instantiated).map((r) => subscribeStore(r.name, bump));
41
+ // Use the consolidated ticker from the model (T2.1) when available;
42
+ // fall back to a standalone 700ms interval for backward compat.
43
+ let tickerOff = null;
44
+ if (model) {
45
+ // The model's subscribe includes the ticker — no extra setInterval.
46
+ tickerOff = model.subscribe(bump);
47
+ }
48
+ else {
49
+ const id = setInterval(bump, 700);
50
+ tickerOff = () => clearInterval(id);
51
+ }
52
+ return () => {
53
+ for (const off of offs)
54
+ off();
55
+ tickerOff?.();
56
+ };
57
+ // rows is recomputed every render; liveKey is its stable identity.
58
+ // eslint-disable-next-line react-hooks/exhaustive-deps
59
+ }, [liveKey, model]);
60
+ const selected = sel !== null && rows.some((r) => r.name === sel) ? sel : (rows[0]?.name ?? null);
61
+ const selRow = rows.find((r) => r.name === selected);
62
+ const snap = selected ? storeSnapshot(selected) : undefined;
63
+ // Split store snapshot into data vs action members (T1.3 grouping).
64
+ const { data: rawData, actions: rawActions } = snap ? groupBindings(snap) : { data: {}, actions: {} };
65
+ const data = serializeBindings(rawData);
66
+ const callables = Object.keys(rawActions);
67
+ const changed = new Set(selected && snap ? diffKeys(prevRef.current.get(selected), data) : []);
68
+ const preserved = new Set(selRow?.preservedFields ?? []);
69
+ const invoke = (store, member, fn) => {
70
+ const key = `${store}.${member}`;
71
+ // Fix 6b: pass onAsyncError so a rejected async action surfaces inline.
72
+ const result = runInvoke(fn, argText[key], (msg) => setInvokeErr((c) => ({ ...c, [key]: msg })));
73
+ if (!result.ok) {
74
+ setInvokeErr((c) => ({ ...c, [key]: result.error }));
75
+ }
76
+ else {
77
+ setInvokeErr((c) => ({ ...c, [key]: "" }));
78
+ }
79
+ };
80
+ // Remember the rendered snapshot after paint so the next change's diff
81
+ // highlights exactly what moved.
82
+ useEffect(() => {
83
+ if (selected) {
84
+ const s = storeSnapshot(selected);
85
+ if (s)
86
+ prevRef.current.set(selected, serializeBindings(s));
87
+ }
88
+ });
89
+ return h("div", { className: "rdt-body" }, h("div", {
90
+ className: "rdt-rail",
91
+ // T3.1: ARIA listbox — the rail is a listbox of selectable stores.
92
+ role: "listbox",
93
+ "aria-label": "Stores",
94
+ "aria-orientation": "vertical",
95
+ // T3.1: arrow-key navigation in the rail listbox.
96
+ onKeyDown: (e) => {
97
+ const visIdx = filteredRows.findIndex((r) => r.name === selected);
98
+ if (e.key === "ArrowDown" && visIdx < filteredRows.length - 1) {
99
+ setSel(filteredRows[visIdx + 1].name);
100
+ e.preventDefault();
101
+ }
102
+ else if (e.key === "ArrowUp" && visIdx > 0) {
103
+ setSel(filteredRows[visIdx - 1].name);
104
+ e.preventDefault();
105
+ }
106
+ },
107
+ }, h("h4", null, "Stores"),
108
+ // T2.3: search input — shown when there are stores to filter.
109
+ rows.length > 0 &&
110
+ h("input", {
111
+ className: "rdt-search",
112
+ type: "search",
113
+ placeholder: "Filter stores…",
114
+ value: search,
115
+ onChange: (e) => setSearch(e.target.value),
116
+ "aria-label": "Filter stores by name",
117
+ }), rows.length === 0 &&
118
+ h("div", { className: "rdt-hint" }, "No stores registered."), filteredRows.length === 0 &&
119
+ rows.length > 0 &&
120
+ h("div", { className: "rdt-hint" }, `No stores match "${search}".`), ...filteredRows.map((r) => {
121
+ const isSelected = r.name === selected;
122
+ return h("button", {
123
+ key: r.name,
124
+ className: `rdt-item${isSelected ? " rdt-item--on" : ""}${r.instantiated ? "" : " rdt-item--stale"}`,
125
+ // T3.1: option role + aria-selected.
126
+ role: "option",
127
+ "aria-selected": isSelected,
128
+ tabIndex: isSelected ? 0 : -1,
129
+ onClick: () => setSel(r.name),
130
+ title: r.instantiated ? "live" : "not instantiated (enter its route)",
131
+ }, h("code", null, r.name), h("span", { className: "rdt-badge rdt-badge--kind" }, kindLabel(r)), !r.instantiated &&
132
+ h("span", { className: "rdt-badge rdt-badge--idle" }, "idle"));
133
+ })), h("div", { className: "rdt-main" }, selected === null
134
+ ? h("div", { className: "rdt-hint" }, "No store selected.")
135
+ : selRow && !selRow.instantiated
136
+ ? h("div", { className: "rdt-card" }, h("div", { className: "rdt-card-id" }, selected), h("div", { className: "rdt-hint" }, "not instantiated — enter its route to inspect live state."))
137
+ : h("div", { className: "rdt-card" }, h("div", { className: "rdt-card-id" }, selected),
138
+ // State / data section (T1.3).
139
+ Object.keys(data).length > 0 &&
140
+ h("div", { className: "rdt-group" }, h("div", { className: "rdt-group-label" }, "State"), h(ValueTree, { data, changed }),
141
+ // Preserved-state badges (Store §6) sit in the data group.
142
+ preserved.size > 0 &&
143
+ h("div", { className: "rdt-kv" }, h("span", { className: "rdt-k" }, "preserved"), h("span", { className: "rdt-v" }, ...[...preserved].map((f) => h("span", { key: f, className: "rdt-badge rdt-badge--kind", title: "preserved state (Store §6)", style: { marginRight: 4 } }, f))))),
144
+ // Actions section (T1.3) — the §4 invoke rows (DVT004).
145
+ callables.length > 0 &&
146
+ h("div", { className: "rdt-group" }, h("div", { className: "rdt-group-label" }, "Actions"), ...callables.flatMap((k) => {
147
+ const key = `${selected}.${k}`;
148
+ return [
149
+ h("div", { key, className: "rdt-kv" }, h("span", { className: "rdt-k" }, `${k}()`), h("input", {
150
+ className: "rdt-args",
151
+ placeholder: 'args: ["x", 1]',
152
+ value: argText[key] ?? "",
153
+ onChange: (e) => setArgText((cur) => ({ ...cur, [key]: e.target.value })),
154
+ }), h("button", {
155
+ className: "rdt-btn rdt-mini rdt-run",
156
+ onClick: () => invoke(selected, k, snap[k]),
157
+ title: "Invoke — the exact action the store exposes",
158
+ }, "▶ run")),
159
+ invokeErr[key]
160
+ ? h("div", { key: `${key}.err`, className: "rdt-invoke-err" }, invokeErr[key])
161
+ : null,
162
+ ];
163
+ })), Object.keys(data).length === 0 &&
164
+ callables.length === 0 &&
165
+ h("div", { className: "rdt-hint" }, "Empty snapshot."))));
166
+ };
167
+ //# sourceMappingURL=stores.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stores.js","sourceRoot":"","sources":["../../src/tabs/stores.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import { type ReactNode } from "react";
2
+ import type { HookRecorder } from "../hookRecorder.ts";
3
+ /** Props of the Time Travel tab. */
4
+ export interface TimeTravelTabProps {
5
+ recorder: HookRecorder;
6
+ hookState: "pending" | "installed" | "occupied";
7
+ /**
8
+ * T3.3: called when the replaying state changes so the parent panel can
9
+ * apply `rdt-panel--replaying` to the shell.
10
+ */
11
+ onReplayingChange?: (replaying: boolean) => void;
12
+ }
13
+ /** Which component names re-drove the running UI vs rendered panel-only (§7). */
14
+ interface DriveResult {
15
+ live: string[];
16
+ view: string[];
17
+ }
18
+ /** Side-effect deps for {@link driveEntriesRouteFirst} — injected so the routing /
19
+ * store / component re-drive can be exercised in a unit test without a real router. */
20
+ export interface DriveEntryDeps {
21
+ /** Raw (lossless) store snapshot folded under `componentId` at/before `absT`. */
22
+ rawStoreStateAt: (componentId: string, absT: number) => Record<string, unknown> | undefined;
23
+ /** Re-drive the URL (router navigate). */
24
+ navigate: (path: string) => void;
25
+ /** Current `pathname + search`, or undefined under SSR/Node. */
26
+ currentLocation: () => string | undefined;
27
+ /** Drive a store to a snapshot; returns the count of fields written. */
28
+ replayStoreState: (name: string, state: Record<string, unknown>) => number;
29
+ /** Drive a replayable component to a snapshot; returns the setter count. */
30
+ applyReplayState: (state: Record<string, unknown>, name: string) => number;
31
+ }
32
+ /**
33
+ * Drive folded `statesAt` entries back into the live app, **route-first** (architect
34
+ * C2). Pass A re-drives every `Route` navigation — which fires the router's `onEnter`
35
+ * synchronously → `StoreRegistry.instantiate` for the target route's stores. Pass B
36
+ * then restores stores (incl. the route stores Pass A just instantiated) + replayable
37
+ * components. A route store on a middleware-gated / not-yet-loaded route instantiates
38
+ * asynchronously, so it's still absent in Pass B → `replayStoreState` returns 0 →
39
+ * `view` (clean degrade, no settle-tick — C1). Pure but for the injected side effects,
40
+ * so the ordering invariant is unit-testable.
41
+ */
42
+ export declare const driveEntriesRouteFirst: (entries: ReadonlyArray<readonly [string, unknown]>, absT: number, deps: DriveEntryDeps) => DriveResult;
43
+ /** Time Travel tab — passive history + replayable live re-drive (§7). */
44
+ export declare const TimeTravelTab: (props: TimeTravelTabProps) => ReactNode;
45
+ export {};
46
+ //# sourceMappingURL=timeTravel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeTravel.d.ts","sourceRoot":"","sources":["../../src/tabs/timeTravel.ts"],"names":[],"mappings":"AAWA,OAAO,EAA4D,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAoBhG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAYtD,oCAAoC;AACpC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,YAAY,CAAA;IACtB,SAAS,EAAE,SAAS,GAAG,WAAW,GAAG,UAAU,CAAA;IAC/C;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAA;CACjD;AAED,iFAAiF;AACjF,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,IAAI,EAAE,MAAM,EAAE,CAAA;CACf;AAED;uFACuF;AACvF,MAAM,WAAW,cAAc;IAC7B,iFAAiF;IACjF,eAAe,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAA;IAC3F,0CAA0C;IAC1C,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,gEAAgE;IAChE,eAAe,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;IACzC,wEAAwE;IACxE,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAA;IAC1E,4EAA4E;IAC5E,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;CAC3E;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,GACjC,SAAS,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAClD,MAAM,MAAM,EACZ,MAAM,cAAc,KACnB,WAoCF,CAAA;AAED,yEAAyE;AACzE,eAAO,MAAM,aAAa,GAAI,OAAO,kBAAkB,KAAG,SAmWzD,CAAA"}