@nice-code/state 0.3.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.
Files changed (27) hide show
  1. package/README.md +1 -0
  2. package/build/devtools/browser/index.js +1653 -0
  3. package/build/index.js +241 -0
  4. package/build/react/index.js +315 -0
  5. package/build/types/core/Store.d.ts +135 -0
  6. package/build/types/core/index.d.ts +1 -0
  7. package/build/types/devtools/browser/NiceStateDevtools.d.ts +8 -0
  8. package/build/types/devtools/browser/components/ChangeDetailPanel.d.ts +5 -0
  9. package/build/types/devtools/browser/components/ChangeList.d.ts +9 -0
  10. package/build/types/devtools/browser/components/DiffView.d.ts +9 -0
  11. package/build/types/devtools/browser/components/JsonView.d.ts +7 -0
  12. package/build/types/devtools/browser/components/PanelChrome.d.ts +54 -0
  13. package/build/types/devtools/browser/components/SectionLabel.d.ts +4 -0
  14. package/build/types/devtools/browser/components/StateInspector.d.ts +16 -0
  15. package/build/types/devtools/browser/components/StoreTabs.d.ts +12 -0
  16. package/build/types/devtools/browser/components/utils.d.ts +29 -0
  17. package/build/types/devtools/browser/devtools_dock.d.ts +47 -0
  18. package/build/types/devtools/browser/index.d.ts +3 -0
  19. package/build/types/devtools/core/StateDevtools.types.d.ts +43 -0
  20. package/build/types/devtools/core/StateDevtoolsCore.d.ts +56 -0
  21. package/build/types/devtools/core/devtools_colors.d.ts +26 -0
  22. package/build/types/index.d.ts +1 -0
  23. package/build/types/react/InjectStoreState.d.ts +18 -0
  24. package/build/types/react/index.d.ts +3 -0
  25. package/build/types/react/useLocalStore.d.ts +8 -0
  26. package/build/types/react/useStoreState.d.ts +23 -0
  27. package/package.json +56 -0
@@ -0,0 +1,1653 @@
1
+ // src/devtools/core/StateDevtoolsCore.ts
2
+ class StateDevtoolsCore {
3
+ _stores = new Map;
4
+ _changes = [];
5
+ _listeners = new Set;
6
+ _maxChanges;
7
+ _paused = false;
8
+ _cuidCounter = 0;
9
+ _sourceOverride = null;
10
+ constructor(options = {}) {
11
+ this._maxChanges = options.maxChanges ?? 250;
12
+ }
13
+ registerStore(label, store) {
14
+ const id = this._uniqueId(label);
15
+ let lastSnapshot = store.getRawState();
16
+ let pendingPatches = [];
17
+ let pendingInverse = [];
18
+ const unsubPatches = store.listenToPatches((patches, inverse) => {
19
+ for (const p of patches)
20
+ pendingPatches.push(p);
21
+ for (const p of inverse)
22
+ pendingInverse.push(p);
23
+ });
24
+ const unsubUpdate = store.subscribe(() => {
25
+ const snapshot = store.getRawState();
26
+ const patches = pendingPatches;
27
+ const inverse = pendingInverse;
28
+ pendingPatches = [];
29
+ pendingInverse = [];
30
+ const reg = this._stores.get(id);
31
+ if (reg != null)
32
+ reg.currentState = snapshot;
33
+ const source = this._sourceOverride ?? (patches.length > 0 ? "update" : "replace");
34
+ const prevSnapshot = lastSnapshot;
35
+ lastSnapshot = snapshot;
36
+ if (this._paused) {
37
+ this._notify();
38
+ return;
39
+ }
40
+ this._recordChange(id, {
41
+ cuid: `chg_${++this._cuidCounter}`,
42
+ storeId: id,
43
+ storeLabel: label,
44
+ timestamp: Date.now(),
45
+ patches,
46
+ inversePatches: inverse,
47
+ prevSnapshot,
48
+ snapshot,
49
+ source
50
+ });
51
+ });
52
+ this._stores.set(id, {
53
+ id,
54
+ label,
55
+ store,
56
+ currentState: lastSnapshot,
57
+ changeCount: 0,
58
+ unsubscribe: () => {
59
+ unsubPatches();
60
+ unsubUpdate();
61
+ }
62
+ });
63
+ this._notify();
64
+ return () => this.unregisterStore(id);
65
+ }
66
+ unregisterStore(id) {
67
+ const reg = this._stores.get(id);
68
+ if (reg == null)
69
+ return;
70
+ reg.unsubscribe();
71
+ this._stores.delete(id);
72
+ this._changes = this._changes.filter((c) => c.storeId !== id);
73
+ this._notify();
74
+ }
75
+ applyEdit(storeId, newState) {
76
+ const reg = this._stores.get(storeId);
77
+ if (reg == null)
78
+ return;
79
+ this._sourceOverride = "devtools-edit";
80
+ try {
81
+ reg.store.replace(newState);
82
+ } finally {
83
+ this._sourceOverride = null;
84
+ }
85
+ }
86
+ revertChange(change) {
87
+ const reg = this._stores.get(change.storeId);
88
+ if (reg == null || change.inversePatches.length === 0)
89
+ return;
90
+ this._sourceOverride = "devtools-revert";
91
+ try {
92
+ reg.store.applyPatches(change.inversePatches);
93
+ } finally {
94
+ this._sourceOverride = null;
95
+ }
96
+ }
97
+ setPaused(paused) {
98
+ if (this._paused === paused)
99
+ return;
100
+ this._paused = paused;
101
+ this._notify();
102
+ }
103
+ togglePaused() {
104
+ this.setPaused(!this._paused);
105
+ }
106
+ clear() {
107
+ this._changes = [];
108
+ for (const reg of this._stores.values()) {
109
+ reg.changeCount = 0;
110
+ reg.lastChangeTime = undefined;
111
+ }
112
+ this._notify();
113
+ }
114
+ getSnapshot() {
115
+ return this._buildSnapshot();
116
+ }
117
+ subscribe(listener) {
118
+ this._listeners.add(listener);
119
+ listener(this._buildSnapshot());
120
+ return () => {
121
+ this._listeners.delete(listener);
122
+ };
123
+ }
124
+ _recordChange(id, change) {
125
+ const reg = this._stores.get(id);
126
+ if (reg != null) {
127
+ reg.changeCount += 1;
128
+ reg.lastChangeTime = change.timestamp;
129
+ }
130
+ this._changes = [change, ...this._changes];
131
+ if (this._changes.length > this._maxChanges) {
132
+ this._changes.length = this._maxChanges;
133
+ }
134
+ this._notify();
135
+ }
136
+ _uniqueId(label) {
137
+ if (!this._stores.has(label))
138
+ return label;
139
+ let n = 2;
140
+ while (this._stores.has(`${label} (${n})`))
141
+ n += 1;
142
+ return `${label} (${n})`;
143
+ }
144
+ _buildSnapshot() {
145
+ const stores = [];
146
+ for (const reg of this._stores.values()) {
147
+ stores.push({
148
+ id: reg.id,
149
+ label: reg.label,
150
+ currentState: reg.currentState,
151
+ changeCount: reg.changeCount,
152
+ lastChangeTime: reg.lastChangeTime
153
+ });
154
+ }
155
+ return { stores, changes: this._changes, paused: this._paused };
156
+ }
157
+ _notify() {
158
+ const snapshot = this._buildSnapshot();
159
+ for (const listener of this._listeners)
160
+ listener(snapshot);
161
+ }
162
+ }
163
+ // src/devtools/browser/NiceStateDevtools.tsx
164
+ import { useEffect as useEffect2, useId, useMemo, useReducer, useState as useState4 } from "react";
165
+
166
+ // src/devtools/core/devtools_colors.ts
167
+ var DEVTOOL_COLOR_SEMANTIC_ERROR = "#FF5C5C";
168
+ var DEVTOOL_COLOR_SEMANTIC_SUCCESS = "#A3E635";
169
+ var DEVTOOL_COLOR_SEMANTIC_SYSTEM = "#38BDF8";
170
+ var DEVTOOL_COLOR_SEMANTIC_WARNING = "#FB923C";
171
+ var DEVTOOL_COLOR_SEMANTIC_METADATA = "#A1A1AA";
172
+ var DEVTOOL_COLOR_TEXT_EMPHASIS = "#f1f5f9";
173
+ var DEVTOOL_COLOR_TEXT_SECONDARY = "#cbd5e1";
174
+ var DEVTOOL_COLOR_TEXT_MUTED = "#64748b";
175
+ var DEVTOOL_COLOR_TEXT_FAINT = "#334155";
176
+ var DEVTOOL_LIST_BASE_BACKGROUND = "#0f172a";
177
+ var DEVTOOL_LIST_SELECTED_BACKGROUND = "#1d2942";
178
+ var DEVTOOL_DETAIL_BASE_BACKGROUND = "#0d1729";
179
+ var DEVTOOL_DETAIL_HEADER_BACKGROUND = "#131f35";
180
+ var DEVTOOL_SECTION_BACKGROUND = "#1e293b";
181
+ var DEVTOOL_SECTION_STRING_BACKGROUND = "#0d131f";
182
+ var DEVTOOL_PANEL_BORDER = "#1e293b";
183
+ var DEVTOOL_PANEL_DIVIDER_BORDER = "#1d3352";
184
+ var DEVTOOL_EDITOR_BACKGROUND = "#08101f";
185
+ var DEVTOOL_ERROR_BACKGROUND = "#1e0a0a";
186
+ var DEVTOOL_JSON_KEY = "#a5b4fc";
187
+ var DEVTOOL_JSON_STRING = "#fbbf24";
188
+ var DEVTOOL_JSON_NUMBER = "#34d399";
189
+ var DEVTOOL_JSON_KEYWORD = "#a78bfa";
190
+ var DEVTOOL_JSON_PUNCTUATION = "#475569";
191
+ var MONO_FONT = "ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace";
192
+ var SANS_FONT = "ui-sans-serif, system-ui, sans-serif";
193
+
194
+ // src/devtools/browser/devtools_dock.ts
195
+ var GLOBAL_KEY = "__NICE_DEVTOOLS_DOCK__";
196
+ var VERSION = 2;
197
+ function createCoordinator() {
198
+ const panels = new Map;
199
+ const listeners = new Set;
200
+ function toRef(panel) {
201
+ return {
202
+ id: panel.id,
203
+ label: panel.label,
204
+ icon: panel.icon,
205
+ badge: panel.badge,
206
+ onOpen: panel.onOpen
207
+ };
208
+ }
209
+ function applyBodyMargins() {
210
+ if (typeof document === "undefined")
211
+ return;
212
+ const margins = { top: 0, bottom: 0, left: 0, right: 0 };
213
+ for (const panel of panels.values()) {
214
+ if (panel.open)
215
+ margins[panel.side] += panel.size;
216
+ }
217
+ const sides = ["top", "bottom", "left", "right"];
218
+ for (const side of sides) {
219
+ if (margins[side] > 0) {
220
+ document.body.style.setProperty(`margin-${side}`, `${margins[side]}px`);
221
+ } else {
222
+ document.body.style.removeProperty(`margin-${side}`);
223
+ }
224
+ }
225
+ }
226
+ function notify() {
227
+ applyBodyMargins();
228
+ for (const listener of listeners)
229
+ listener();
230
+ }
231
+ return {
232
+ version: VERSION,
233
+ register(panel) {
234
+ panels.set(panel.id, { ...panel });
235
+ notify();
236
+ return () => {
237
+ panels.delete(panel.id);
238
+ notify();
239
+ };
240
+ },
241
+ update(id, next) {
242
+ const existing = panels.get(id);
243
+ if (existing == null)
244
+ return;
245
+ if (existing.side === next.side && existing.size === next.size && existing.open === next.open && existing.badge === next.badge) {
246
+ return;
247
+ }
248
+ panels.set(id, { ...existing, ...next });
249
+ notify();
250
+ },
251
+ getView(id) {
252
+ const list = [...panels.values()];
253
+ const anyOpen = list.some((p) => p.open);
254
+ const firstId = list.length > 0 ? list[0].id : null;
255
+ let dockOffset = 0;
256
+ const self = panels.get(id);
257
+ if (self != null && self.open) {
258
+ for (const panel of list) {
259
+ if (panel.id === id)
260
+ break;
261
+ if (panel.open && panel.side === self.side)
262
+ dockOffset += panel.size;
263
+ }
264
+ }
265
+ return {
266
+ dockOffset,
267
+ anyOpen,
268
+ isPrimary: id === firstId,
269
+ devtools: list.map(toRef),
270
+ otherClosed: list.filter((p) => !p.open && p.id !== id).map(toRef)
271
+ };
272
+ },
273
+ subscribe(listener) {
274
+ listeners.add(listener);
275
+ return () => {
276
+ listeners.delete(listener);
277
+ };
278
+ }
279
+ };
280
+ }
281
+ function getDevtoolsDockCoordinator() {
282
+ if (typeof window === "undefined")
283
+ return createCoordinator();
284
+ const host = window;
285
+ const existing = host[GLOBAL_KEY];
286
+ if (existing != null && existing.version === VERSION)
287
+ return existing;
288
+ const created = createCoordinator();
289
+ host[GLOBAL_KEY] = created;
290
+ return created;
291
+ }
292
+
293
+ // src/devtools/browser/components/ChangeDetailPanel.tsx
294
+ import { useState as useState2 } from "react";
295
+
296
+ // src/devtools/browser/components/utils.ts
297
+ function safeStringify(value, indent = 2) {
298
+ if (value === undefined)
299
+ return "undefined";
300
+ if (value === null)
301
+ return "null";
302
+ try {
303
+ return JSON.stringify(value, null, indent);
304
+ } catch {
305
+ return String(value);
306
+ }
307
+ }
308
+ function formatTimestamp(ms) {
309
+ return new Date(ms).toLocaleTimeString([], {
310
+ hour: "2-digit",
311
+ minute: "2-digit",
312
+ second: "2-digit",
313
+ hour12: false
314
+ });
315
+ }
316
+ var SOURCE_LABEL = {
317
+ update: "UPDATE",
318
+ replace: "REPLACE",
319
+ "devtools-edit": "EDIT",
320
+ "devtools-revert": "REVERT"
321
+ };
322
+ var SOURCE_COLOR = {
323
+ update: DEVTOOL_COLOR_SEMANTIC_SYSTEM,
324
+ replace: DEVTOOL_COLOR_SEMANTIC_METADATA,
325
+ "devtools-edit": DEVTOOL_COLOR_SEMANTIC_WARNING,
326
+ "devtools-revert": DEVTOOL_COLOR_SEMANTIC_WARNING
327
+ };
328
+ function patchPathToString(path) {
329
+ if (path.length === 0)
330
+ return "(root)";
331
+ return path.map((seg) => String(seg)).join(".");
332
+ }
333
+ function summarizeChange(change) {
334
+ const { patches } = change;
335
+ if (patches.length === 0) {
336
+ return change.source === "replace" || change.source === "devtools-edit" ? "whole state replaced" : "no patches";
337
+ }
338
+ if (patches.length === 1) {
339
+ const p = patches[0];
340
+ const path = patchPathToString(p.path);
341
+ if (p.op === "replace" && isScalar(p.value)) {
342
+ return `${path} → ${formatScalar(p.value)}`;
343
+ }
344
+ if (p.op === "add")
345
+ return `+ ${path}`;
346
+ if (p.op === "remove")
347
+ return `− ${path}`;
348
+ return path;
349
+ }
350
+ const paths = patches.map((p) => topLevel(p.path)).filter((s) => s.length > 0);
351
+ const unique = [...new Set(paths)];
352
+ const shown = unique.slice(0, 3).join(", ");
353
+ return unique.length > 3 ? `${shown} +${unique.length - 3}` : shown;
354
+ }
355
+ function topLevel(path) {
356
+ return path.length > 0 ? String(path[0]) : "(root)";
357
+ }
358
+ function computeDiff(before, after) {
359
+ const out = [];
360
+ walkDiff([], before, after, out);
361
+ return out;
362
+ }
363
+ function isPlainObjectOrArray(value) {
364
+ return value != null && typeof value === "object";
365
+ }
366
+ function walkDiff(path, before, after, out) {
367
+ if (Object.is(before, after))
368
+ return;
369
+ const bothContainers = isPlainObjectOrArray(before) && isPlainObjectOrArray(after);
370
+ const sameShape = bothContainers && Array.isArray(before) === Array.isArray(after);
371
+ if (sameShape) {
372
+ const b = before;
373
+ const a = after;
374
+ const keys = new Set([...Object.keys(b), ...Object.keys(a)]);
375
+ for (const key of keys) {
376
+ const inB = key in b;
377
+ const inA = key in a;
378
+ const next = [...path, key];
379
+ if (inB && !inA) {
380
+ out.push({ path: formatDiffPath(next), kind: "removed", before: b[key] });
381
+ } else if (!inB && inA) {
382
+ out.push({ path: formatDiffPath(next), kind: "added", after: a[key] });
383
+ } else {
384
+ walkDiff(next, b[key], a[key], out);
385
+ }
386
+ }
387
+ return;
388
+ }
389
+ out.push({ path: formatDiffPath(path), kind: "changed", before, after });
390
+ }
391
+ function formatDiffPath(path) {
392
+ return path.length === 0 ? "(root)" : path.map((seg) => String(seg)).join(".");
393
+ }
394
+ function isScalar(value) {
395
+ return value == null || typeof value !== "object";
396
+ }
397
+ function formatScalar(value) {
398
+ if (typeof value === "string")
399
+ return `"${value.length > 24 ? `${value.slice(0, 24)}…` : value}"`;
400
+ return String(value);
401
+ }
402
+
403
+ // src/devtools/browser/components/JsonView.tsx
404
+ import { jsxDEV } from "react/jsx-dev-runtime";
405
+ var JSON_TOKEN_RE = /("(?:\\.|[^"\\])*")(\s*:)?|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)|(\btrue\b|\bfalse\b|\bnull\b|\bundefined\b)|([{}[\],])/g;
406
+ function renderColoredJson(text) {
407
+ const nodes = [];
408
+ let last = 0;
409
+ let i = 0;
410
+ JSON_TOKEN_RE.lastIndex = 0;
411
+ for (let m = JSON_TOKEN_RE.exec(text);m !== null; m = JSON_TOKEN_RE.exec(text)) {
412
+ if (m.index > last)
413
+ nodes.push(text.slice(last, m.index));
414
+ const [, str, colon, num, kw, punct] = m;
415
+ if (str != null) {
416
+ if (colon != null) {
417
+ nodes.push(/* @__PURE__ */ jsxDEV("span", {
418
+ style: { color: DEVTOOL_JSON_KEY },
419
+ children: str
420
+ }, i++, false, undefined, this));
421
+ nodes.push(/* @__PURE__ */ jsxDEV("span", {
422
+ style: { color: DEVTOOL_JSON_PUNCTUATION },
423
+ children: colon
424
+ }, i++, false, undefined, this));
425
+ } else {
426
+ nodes.push(/* @__PURE__ */ jsxDEV("span", {
427
+ style: { color: DEVTOOL_JSON_STRING },
428
+ children: str
429
+ }, i++, false, undefined, this));
430
+ }
431
+ } else if (num != null) {
432
+ nodes.push(/* @__PURE__ */ jsxDEV("span", {
433
+ style: { color: DEVTOOL_JSON_NUMBER },
434
+ children: num
435
+ }, i++, false, undefined, this));
436
+ } else if (kw != null) {
437
+ nodes.push(/* @__PURE__ */ jsxDEV("span", {
438
+ style: { color: DEVTOOL_JSON_KEYWORD },
439
+ children: kw
440
+ }, i++, false, undefined, this));
441
+ } else if (punct != null) {
442
+ nodes.push(/* @__PURE__ */ jsxDEV("span", {
443
+ style: { color: DEVTOOL_JSON_PUNCTUATION },
444
+ children: punct
445
+ }, i++, false, undefined, this));
446
+ }
447
+ last = JSON_TOKEN_RE.lastIndex;
448
+ }
449
+ if (last < text.length)
450
+ nodes.push(text.slice(last));
451
+ return nodes;
452
+ }
453
+ function JsonView({
454
+ value,
455
+ indent = 2,
456
+ style
457
+ }) {
458
+ const text = safeStringify(value, indent);
459
+ return /* @__PURE__ */ jsxDEV("pre", {
460
+ style: {
461
+ margin: 0,
462
+ padding: "8px 10px",
463
+ borderRadius: "4px",
464
+ fontSize: "11px",
465
+ lineHeight: 1.5,
466
+ fontFamily: MONO_FONT,
467
+ background: DEVTOOL_SECTION_STRING_BACKGROUND,
468
+ overflowX: "auto",
469
+ whiteSpace: "pre-wrap",
470
+ wordBreak: "break-word",
471
+ ...style
472
+ },
473
+ children: renderColoredJson(text)
474
+ }, undefined, false, undefined, this);
475
+ }
476
+
477
+ // src/devtools/browser/components/DiffView.tsx
478
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
479
+ var ADDED_BG = "rgba(163, 230, 53, 0.08)";
480
+ var REMOVED_BG = "rgba(255, 92, 92, 0.08)";
481
+ function DiffView({ before, after }) {
482
+ const entries = computeDiff(before, after);
483
+ if (entries.length === 0) {
484
+ return /* @__PURE__ */ jsxDEV2("div", {
485
+ style: {
486
+ padding: "10px",
487
+ borderRadius: "4px",
488
+ background: DEVTOOL_SECTION_STRING_BACKGROUND,
489
+ color: DEVTOOL_COLOR_TEXT_MUTED,
490
+ fontSize: "11px",
491
+ fontStyle: "italic"
492
+ },
493
+ children: "No differences — before and after are structurally equal."
494
+ }, undefined, false, undefined, this);
495
+ }
496
+ return /* @__PURE__ */ jsxDEV2("div", {
497
+ style: { display: "flex", flexDirection: "column", gap: "6px" },
498
+ children: entries.map((entry) => /* @__PURE__ */ jsxDEV2(DiffRow, {
499
+ entry
500
+ }, `${entry.kind}:${entry.path}`, false, undefined, this))
501
+ }, undefined, false, undefined, this);
502
+ }
503
+ function DiffRow({ entry }) {
504
+ const showRemoved = entry.kind === "removed" || entry.kind === "changed";
505
+ const showAdded = entry.kind === "added" || entry.kind === "changed";
506
+ return /* @__PURE__ */ jsxDEV2("div", {
507
+ style: {
508
+ borderRadius: "4px",
509
+ overflow: "hidden",
510
+ border: `1px solid ${DEVTOOL_SECTION_STRING_BACKGROUND}`
511
+ },
512
+ children: [
513
+ /* @__PURE__ */ jsxDEV2("div", {
514
+ style: {
515
+ padding: "3px 8px",
516
+ background: DEVTOOL_SECTION_STRING_BACKGROUND,
517
+ color: DEVTOOL_COLOR_TEXT_SECONDARY,
518
+ fontFamily: MONO_FONT,
519
+ fontSize: "10px"
520
+ },
521
+ children: entry.path
522
+ }, undefined, false, undefined, this),
523
+ showRemoved && /* @__PURE__ */ jsxDEV2(DiffLine, {
524
+ sign: "−",
525
+ color: DEVTOOL_COLOR_SEMANTIC_ERROR,
526
+ background: REMOVED_BG,
527
+ value: entry.before
528
+ }, undefined, false, undefined, this),
529
+ showAdded && /* @__PURE__ */ jsxDEV2(DiffLine, {
530
+ sign: "+",
531
+ color: DEVTOOL_COLOR_SEMANTIC_SUCCESS,
532
+ background: ADDED_BG,
533
+ value: entry.after
534
+ }, undefined, false, undefined, this)
535
+ ]
536
+ }, undefined, true, undefined, this);
537
+ }
538
+ function DiffLine({
539
+ sign,
540
+ color,
541
+ background,
542
+ value
543
+ }) {
544
+ return /* @__PURE__ */ jsxDEV2("div", {
545
+ style: { display: "flex", gap: "6px", padding: "3px 8px", background },
546
+ children: [
547
+ /* @__PURE__ */ jsxDEV2("span", {
548
+ style: { color, fontWeight: 700, flexShrink: 0, userSelect: "none" },
549
+ children: sign
550
+ }, undefined, false, undefined, this),
551
+ /* @__PURE__ */ jsxDEV2("span", {
552
+ style: {
553
+ flex: 1,
554
+ minWidth: 0,
555
+ fontFamily: MONO_FONT,
556
+ fontSize: "11px",
557
+ lineHeight: 1.5,
558
+ whiteSpace: "pre-wrap",
559
+ wordBreak: "break-word"
560
+ },
561
+ children: renderColoredJson(safeStringify(value, 2))
562
+ }, undefined, false, undefined, this)
563
+ ]
564
+ }, undefined, true, undefined, this);
565
+ }
566
+
567
+ // src/devtools/browser/components/PanelChrome.tsx
568
+ import {
569
+ useState
570
+ } from "react";
571
+ import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
572
+ var DOCKED_SIZE_MIN = 160;
573
+ var POSITION_GRID = [
574
+ [null, "dock-top", null],
575
+ ["dock-left", null, "dock-right"],
576
+ [null, "dock-bottom", null]
577
+ ];
578
+ function getDockSide(pos) {
579
+ switch (pos) {
580
+ case "dock-top":
581
+ return "top";
582
+ case "dock-left":
583
+ return "left";
584
+ case "dock-right":
585
+ return "right";
586
+ default:
587
+ return "bottom";
588
+ }
589
+ }
590
+ function PanelHeader({
591
+ position,
592
+ onPositionChange,
593
+ onClose,
594
+ onClear,
595
+ paused,
596
+ onTogglePause,
597
+ openOthers,
598
+ children
599
+ }) {
600
+ return /* @__PURE__ */ jsxDEV3("div", {
601
+ style: {
602
+ display: "flex",
603
+ alignItems: "center",
604
+ justifyContent: "space-between",
605
+ padding: "8px 12px",
606
+ gap: "10px",
607
+ background: DEVTOOL_SECTION_BACKGROUND,
608
+ borderBottom: `1px solid ${DEVTOOL_LIST_BASE_BACKGROUND}`,
609
+ flexShrink: 0
610
+ },
611
+ children: [
612
+ /* @__PURE__ */ jsxDEV3("div", {
613
+ style: { display: "flex", alignItems: "center", gap: "8px", minWidth: 0 },
614
+ children: [
615
+ /* @__PURE__ */ jsxDEV3("span", {
616
+ style: {
617
+ color: DEVTOOL_COLOR_SEMANTIC_SYSTEM,
618
+ fontWeight: "bold",
619
+ fontSize: "11px",
620
+ whiteSpace: "nowrap"
621
+ },
622
+ children: "\uD83E\uDDE9 state"
623
+ }, undefined, false, undefined, this),
624
+ openOthers?.map((item) => /* @__PURE__ */ jsxDEV3("button", {
625
+ onClick: item.onOpen,
626
+ title: `Open ${item.label} devtools`,
627
+ style: {
628
+ display: "flex",
629
+ alignItems: "center",
630
+ gap: "4px",
631
+ background: DEVTOOL_LIST_BASE_BACKGROUND,
632
+ border: `1px solid ${DEVTOOL_COLOR_TEXT_FAINT}`,
633
+ borderRadius: "999px",
634
+ color: DEVTOOL_COLOR_TEXT_MUTED,
635
+ cursor: "pointer",
636
+ fontSize: "10px",
637
+ padding: "1px 7px 1px 6px",
638
+ fontFamily: SANS_FONT,
639
+ whiteSpace: "nowrap"
640
+ },
641
+ children: [
642
+ /* @__PURE__ */ jsxDEV3("span", {
643
+ children: item.icon
644
+ }, undefined, false, undefined, this),
645
+ /* @__PURE__ */ jsxDEV3("span", {
646
+ children: item.label
647
+ }, undefined, false, undefined, this),
648
+ item.badge != null && /* @__PURE__ */ jsxDEV3("span", {
649
+ style: { color: DEVTOOL_COLOR_SEMANTIC_SYSTEM },
650
+ children: item.badge
651
+ }, undefined, false, undefined, this)
652
+ ]
653
+ }, item.id, true, undefined, this))
654
+ ]
655
+ }, undefined, true, undefined, this),
656
+ /* @__PURE__ */ jsxDEV3("div", {
657
+ style: { display: "flex", gap: "10px", alignItems: "center" },
658
+ children: [
659
+ children,
660
+ /* @__PURE__ */ jsxDEV3("button", {
661
+ onClick: onTogglePause,
662
+ title: paused ? "Resume recording" : "Pause recording",
663
+ style: chromeButtonStyle(paused ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : DEVTOOL_COLOR_TEXT_MUTED),
664
+ children: paused ? "▶ resume" : "⏸ pause"
665
+ }, undefined, false, undefined, this),
666
+ onClear != null && /* @__PURE__ */ jsxDEV3("button", {
667
+ onClick: onClear,
668
+ style: chromeButtonStyle(DEVTOOL_COLOR_TEXT_MUTED),
669
+ children: "clear"
670
+ }, undefined, false, undefined, this),
671
+ /* @__PURE__ */ jsxDEV3(PositionPicker, {
672
+ position,
673
+ onChange: onPositionChange
674
+ }, undefined, false, undefined, this),
675
+ /* @__PURE__ */ jsxDEV3("button", {
676
+ onClick: onClose,
677
+ style: {
678
+ ...chromeButtonStyle(DEVTOOL_COLOR_TEXT_MUTED),
679
+ fontSize: "16px",
680
+ lineHeight: "1"
681
+ },
682
+ children: "×"
683
+ }, undefined, false, undefined, this)
684
+ ]
685
+ }, undefined, true, undefined, this)
686
+ ]
687
+ }, undefined, true, undefined, this);
688
+ }
689
+ function chromeButtonStyle(color) {
690
+ return {
691
+ background: "none",
692
+ border: "none",
693
+ color,
694
+ cursor: "pointer",
695
+ fontSize: "11px",
696
+ padding: 0,
697
+ fontFamily: SANS_FONT,
698
+ whiteSpace: "nowrap"
699
+ };
700
+ }
701
+ function PositionPicker({
702
+ position,
703
+ onChange
704
+ }) {
705
+ return /* @__PURE__ */ jsxDEV3("div", {
706
+ title: "Move / dock panel",
707
+ style: { display: "grid", gridTemplateColumns: "repeat(3, 9px)", gap: "2px", padding: "2px" },
708
+ children: POSITION_GRID.flat().map((pos) => {
709
+ if (pos == null)
710
+ return /* @__PURE__ */ jsxDEV3("div", {
711
+ style: { width: "9px", height: "9px" }
712
+ }, "center-empty", false, undefined, this);
713
+ const isDock = pos.startsWith("dock-");
714
+ const isTopBottom = pos === "dock-top" || pos === "dock-bottom";
715
+ const isActive = pos === position;
716
+ return /* @__PURE__ */ jsxDEV3("div", {
717
+ title: pos,
718
+ onClick: () => onChange(pos),
719
+ style: {
720
+ width: "9px",
721
+ height: "9px",
722
+ display: "flex",
723
+ alignItems: "center",
724
+ justifyContent: "center",
725
+ cursor: "pointer"
726
+ },
727
+ children: /* @__PURE__ */ jsxDEV3("div", {
728
+ style: {
729
+ width: isDock ? isTopBottom ? "9px" : "3px" : "7px",
730
+ height: isDock ? isTopBottom ? "3px" : "9px" : "7px",
731
+ borderRadius: isDock ? "1px" : "50%",
732
+ background: isActive ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : DEVTOOL_COLOR_TEXT_FAINT
733
+ }
734
+ }, undefined, false, undefined, this)
735
+ }, pos, false, undefined, this);
736
+ })
737
+ }, undefined, false, undefined, this);
738
+ }
739
+ function ResizeHandle({
740
+ dockSide,
741
+ dockedSize,
742
+ onChange
743
+ }) {
744
+ const isHoriz = dockSide === "left" || dockSide === "right";
745
+ const onMouseDown = (e) => {
746
+ e.preventDefault();
747
+ const startCoord = isHoriz ? e.clientX : e.clientY;
748
+ const startSize = dockedSize;
749
+ const maxSize = isHoriz ? window.innerWidth * 0.85 : window.innerHeight * 0.85;
750
+ const sign = dockSide === "bottom" || dockSide === "right" ? -1 : 1;
751
+ const onMove = (me) => {
752
+ const delta = (isHoriz ? me.clientX : me.clientY) - startCoord;
753
+ onChange(Math.max(DOCKED_SIZE_MIN, Math.min(maxSize, startSize + sign * delta)));
754
+ };
755
+ const onUp = () => {
756
+ window.removeEventListener("mousemove", onMove);
757
+ window.removeEventListener("mouseup", onUp);
758
+ };
759
+ window.addEventListener("mousemove", onMove);
760
+ window.addEventListener("mouseup", onUp);
761
+ };
762
+ const edgeStyle = dockSide === "bottom" ? { top: 0, left: 0, right: 0, height: "5px", cursor: "ns-resize" } : dockSide === "top" ? { bottom: 0, left: 0, right: 0, height: "5px", cursor: "ns-resize" } : dockSide === "right" ? { top: 0, bottom: 0, left: 0, width: "5px", cursor: "ew-resize" } : { top: 0, bottom: 0, right: 0, width: "5px", cursor: "ew-resize" };
763
+ return /* @__PURE__ */ jsxDEV3("div", {
764
+ onMouseDown,
765
+ style: { position: "absolute", zIndex: 10, background: "transparent", ...edgeStyle }
766
+ }, undefined, false, undefined, this);
767
+ }
768
+ var SPLIT_RATIO_MIN = 0.15;
769
+ var SPLIT_RATIO_MAX = 0.85;
770
+ function SplitHandle({
771
+ horizontal,
772
+ onRatioChange
773
+ }) {
774
+ const [hovered, setHovered] = useState(false);
775
+ const onMouseDown = (e) => {
776
+ e.preventDefault();
777
+ const container = e.currentTarget.parentElement;
778
+ if (container == null)
779
+ return;
780
+ const onMove = (me) => {
781
+ const rect = container.getBoundingClientRect();
782
+ const ratio = horizontal ? (rect.right - me.clientX) / rect.width : (rect.bottom - me.clientY) / rect.height;
783
+ onRatioChange(Math.max(SPLIT_RATIO_MIN, Math.min(SPLIT_RATIO_MAX, ratio)));
784
+ };
785
+ const onUp = () => {
786
+ window.removeEventListener("mousemove", onMove);
787
+ window.removeEventListener("mouseup", onUp);
788
+ };
789
+ window.addEventListener("mousemove", onMove);
790
+ window.addEventListener("mouseup", onUp);
791
+ };
792
+ return /* @__PURE__ */ jsxDEV3("div", {
793
+ onMouseDown,
794
+ onMouseEnter: () => setHovered(true),
795
+ onMouseLeave: () => setHovered(false),
796
+ style: {
797
+ flex: "0 0 5px",
798
+ alignSelf: "stretch",
799
+ cursor: horizontal ? "ew-resize" : "ns-resize",
800
+ background: hovered ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : "transparent",
801
+ opacity: hovered ? 0.6 : 1,
802
+ zIndex: 5
803
+ }
804
+ }, undefined, false, undefined, this);
805
+ }
806
+ function SegmentedControl({
807
+ options,
808
+ value,
809
+ onChange
810
+ }) {
811
+ return /* @__PURE__ */ jsxDEV3("div", {
812
+ style: {
813
+ display: "flex",
814
+ border: `1px solid ${DEVTOOL_COLOR_TEXT_FAINT}`,
815
+ borderRadius: "5px",
816
+ overflow: "hidden"
817
+ },
818
+ children: options.map((opt) => {
819
+ const active = opt.value === value;
820
+ return /* @__PURE__ */ jsxDEV3("button", {
821
+ onClick: () => onChange(opt.value),
822
+ style: {
823
+ background: active ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : "transparent",
824
+ color: active ? "#0f172a" : DEVTOOL_COLOR_TEXT_MUTED,
825
+ border: "none",
826
+ cursor: "pointer",
827
+ fontSize: "10px",
828
+ fontWeight: active ? 700 : 500,
829
+ padding: "3px 9px",
830
+ fontFamily: SANS_FONT
831
+ },
832
+ children: opt.label
833
+ }, opt.value, false, undefined, this);
834
+ })
835
+ }, undefined, false, undefined, this);
836
+ }
837
+ function DevtoolsLauncher({ items }) {
838
+ return /* @__PURE__ */ jsxDEV3("div", {
839
+ style: {
840
+ position: "fixed",
841
+ bottom: "16px",
842
+ right: "16px",
843
+ zIndex: 2147483646,
844
+ display: "flex",
845
+ fontFamily: MONO_FONT,
846
+ fontSize: "12px"
847
+ },
848
+ children: /* @__PURE__ */ jsxDEV3("div", {
849
+ style: {
850
+ display: "flex",
851
+ background: DEVTOOL_SECTION_BACKGROUND,
852
+ border: `1px solid ${DEVTOOL_COLOR_TEXT_FAINT}`,
853
+ borderRadius: "6px",
854
+ overflow: "hidden",
855
+ boxShadow: "0 8px 24px rgba(0,0,0,0.35)"
856
+ },
857
+ children: items.map((item, i) => /* @__PURE__ */ jsxDEV3("button", {
858
+ onClick: item.onOpen,
859
+ style: {
860
+ display: "flex",
861
+ alignItems: "center",
862
+ gap: "5px",
863
+ background: "transparent",
864
+ color: DEVTOOL_COLOR_TEXT_SECONDARY,
865
+ border: "none",
866
+ borderLeft: i > 0 ? `1px solid ${DEVTOOL_COLOR_TEXT_FAINT}` : "none",
867
+ cursor: "pointer",
868
+ padding: "6px 11px",
869
+ fontFamily: MONO_FONT,
870
+ fontSize: "12px",
871
+ lineHeight: "1.5"
872
+ },
873
+ children: [
874
+ /* @__PURE__ */ jsxDEV3("span", {
875
+ children: item.icon
876
+ }, undefined, false, undefined, this),
877
+ /* @__PURE__ */ jsxDEV3("span", {
878
+ children: item.label
879
+ }, undefined, false, undefined, this),
880
+ item.badge != null && /* @__PURE__ */ jsxDEV3("span", {
881
+ style: { color: DEVTOOL_COLOR_SEMANTIC_SYSTEM },
882
+ children: item.badge
883
+ }, undefined, false, undefined, this)
884
+ ]
885
+ }, item.id, true, undefined, this))
886
+ }, undefined, false, undefined, this)
887
+ }, undefined, false, undefined, this);
888
+ }
889
+
890
+ // src/devtools/browser/components/ChangeDetailPanel.tsx
891
+ import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
892
+ function ChangeDetailPanel({
893
+ change,
894
+ onRevert
895
+ }) {
896
+ const [view, setView] = useState2("diff");
897
+ const canRevert = change.inversePatches.length > 0;
898
+ return /* @__PURE__ */ jsxDEV4("div", {
899
+ style: {
900
+ flex: 1,
901
+ display: "flex",
902
+ flexDirection: "column",
903
+ overflow: "hidden",
904
+ minHeight: 0,
905
+ background: DEVTOOL_DETAIL_BASE_BACKGROUND
906
+ },
907
+ children: [
908
+ /* @__PURE__ */ jsxDEV4("div", {
909
+ style: {
910
+ padding: "8px 12px",
911
+ background: DEVTOOL_DETAIL_HEADER_BACKGROUND,
912
+ borderBottom: `1px solid ${DEVTOOL_LIST_BASE_BACKGROUND}`,
913
+ display: "flex",
914
+ alignItems: "center",
915
+ gap: "8px",
916
+ flexShrink: 0
917
+ },
918
+ children: [
919
+ /* @__PURE__ */ jsxDEV4("span", {
920
+ style: {
921
+ color: DEVTOOL_COLOR_TEXT_EMPHASIS,
922
+ fontWeight: 600,
923
+ fontFamily: MONO_FONT,
924
+ fontSize: "12px",
925
+ overflow: "hidden",
926
+ textOverflow: "ellipsis",
927
+ whiteSpace: "nowrap"
928
+ },
929
+ children: change.storeLabel
930
+ }, undefined, false, undefined, this),
931
+ /* @__PURE__ */ jsxDEV4("span", {
932
+ style: {
933
+ padding: "1px 7px",
934
+ borderRadius: "999px",
935
+ background: SOURCE_COLOR[change.source],
936
+ color: "#0f172a",
937
+ fontSize: "8px",
938
+ fontWeight: 700,
939
+ letterSpacing: "0.08em",
940
+ fontFamily: SANS_FONT
941
+ },
942
+ children: SOURCE_LABEL[change.source]
943
+ }, undefined, false, undefined, this),
944
+ /* @__PURE__ */ jsxDEV4("span", {
945
+ style: { flex: 1 }
946
+ }, undefined, false, undefined, this),
947
+ /* @__PURE__ */ jsxDEV4("span", {
948
+ style: { color: DEVTOOL_COLOR_TEXT_MUTED, fontSize: "10px", fontFamily: MONO_FONT },
949
+ children: formatTimestamp(change.timestamp)
950
+ }, undefined, false, undefined, this),
951
+ /* @__PURE__ */ jsxDEV4("button", {
952
+ onClick: () => onRevert(change),
953
+ disabled: !canRevert,
954
+ title: canRevert ? "Apply this change's inverse patches to undo it" : "No inverse patches available to revert",
955
+ style: {
956
+ background: "transparent",
957
+ border: `1px solid ${canRevert ? DEVTOOL_COLOR_SEMANTIC_WARNING : DEVTOOL_SECTION_BACKGROUND}`,
958
+ color: canRevert ? DEVTOOL_COLOR_SEMANTIC_WARNING : DEVTOOL_COLOR_TEXT_MUTED,
959
+ borderRadius: "4px",
960
+ cursor: canRevert ? "pointer" : "not-allowed",
961
+ fontSize: "10px",
962
+ padding: "2px 8px",
963
+ fontFamily: SANS_FONT,
964
+ flexShrink: 0
965
+ },
966
+ children: "⟲ revert"
967
+ }, undefined, false, undefined, this)
968
+ ]
969
+ }, undefined, true, undefined, this),
970
+ /* @__PURE__ */ jsxDEV4("div", {
971
+ style: {
972
+ padding: "6px 12px",
973
+ borderBottom: `1px solid ${DEVTOOL_LIST_BASE_BACKGROUND}`,
974
+ flexShrink: 0
975
+ },
976
+ children: /* @__PURE__ */ jsxDEV4(SegmentedControl, {
977
+ options: [
978
+ { value: "diff", label: "Diff View" },
979
+ { value: "before", label: "Before" },
980
+ { value: "after", label: "After" }
981
+ ],
982
+ value: view,
983
+ onChange: setView
984
+ }, undefined, false, undefined, this)
985
+ }, undefined, false, undefined, this),
986
+ /* @__PURE__ */ jsxDEV4("div", {
987
+ style: {
988
+ flex: 1,
989
+ overflowY: "auto",
990
+ minHeight: 0,
991
+ padding: "10px 12px"
992
+ },
993
+ children: [
994
+ view === "diff" && /* @__PURE__ */ jsxDEV4(DiffView, {
995
+ before: change.prevSnapshot,
996
+ after: change.snapshot
997
+ }, undefined, false, undefined, this),
998
+ view === "before" && /* @__PURE__ */ jsxDEV4(JsonView, {
999
+ value: change.prevSnapshot
1000
+ }, undefined, false, undefined, this),
1001
+ view === "after" && /* @__PURE__ */ jsxDEV4(JsonView, {
1002
+ value: change.snapshot
1003
+ }, undefined, false, undefined, this)
1004
+ ]
1005
+ }, undefined, true, undefined, this)
1006
+ ]
1007
+ }, undefined, true, undefined, this);
1008
+ }
1009
+
1010
+ // src/devtools/browser/components/ChangeList.tsx
1011
+ import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
1012
+ function ChangeList({
1013
+ changes,
1014
+ selectedCuid,
1015
+ onSelect,
1016
+ showStore,
1017
+ style
1018
+ }) {
1019
+ if (changes.length === 0) {
1020
+ return /* @__PURE__ */ jsxDEV5("div", {
1021
+ style: {
1022
+ padding: "24px",
1023
+ textAlign: "center",
1024
+ color: DEVTOOL_COLOR_TEXT_MUTED,
1025
+ fontSize: "11px",
1026
+ ...style
1027
+ },
1028
+ children: "No changes recorded yet. Mutate a store to see it here."
1029
+ }, undefined, false, undefined, this);
1030
+ }
1031
+ return /* @__PURE__ */ jsxDEV5("div", {
1032
+ style,
1033
+ children: changes.map((change) => /* @__PURE__ */ jsxDEV5(ChangeRow, {
1034
+ change,
1035
+ selected: change.cuid === selectedCuid,
1036
+ onClick: () => onSelect(change.cuid),
1037
+ showStore
1038
+ }, change.cuid, false, undefined, this))
1039
+ }, undefined, false, undefined, this);
1040
+ }
1041
+ function ChangeRow({
1042
+ change,
1043
+ selected,
1044
+ onClick,
1045
+ showStore
1046
+ }) {
1047
+ const sourceColor = SOURCE_COLOR[change.source];
1048
+ return /* @__PURE__ */ jsxDEV5("div", {
1049
+ onClick,
1050
+ style: {
1051
+ display: "flex",
1052
+ flexDirection: "column",
1053
+ gap: "3px",
1054
+ padding: "6px 10px",
1055
+ cursor: "pointer",
1056
+ borderBottom: `1px solid ${DEVTOOL_SECTION_BACKGROUND}`,
1057
+ borderLeft: `2px solid ${selected ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : "transparent"}`,
1058
+ background: selected ? DEVTOOL_LIST_SELECTED_BACKGROUND : DEVTOOL_LIST_BASE_BACKGROUND
1059
+ },
1060
+ children: [
1061
+ /* @__PURE__ */ jsxDEV5("div", {
1062
+ style: { display: "flex", alignItems: "center", gap: "6px" },
1063
+ children: [
1064
+ /* @__PURE__ */ jsxDEV5("span", {
1065
+ style: {
1066
+ color: DEVTOOL_COLOR_TEXT_MUTED,
1067
+ fontSize: "10px",
1068
+ fontFamily: MONO_FONT,
1069
+ flexShrink: 0
1070
+ },
1071
+ children: formatTimestamp(change.timestamp)
1072
+ }, undefined, false, undefined, this),
1073
+ /* @__PURE__ */ jsxDEV5(Badge, {
1074
+ color: sourceColor,
1075
+ children: SOURCE_LABEL[change.source]
1076
+ }, undefined, false, undefined, this),
1077
+ showStore && /* @__PURE__ */ jsxDEV5("span", {
1078
+ style: {
1079
+ color: DEVTOOL_COLOR_SEMANTIC_SYSTEM,
1080
+ fontSize: "10px",
1081
+ fontFamily: MONO_FONT,
1082
+ overflow: "hidden",
1083
+ textOverflow: "ellipsis",
1084
+ whiteSpace: "nowrap"
1085
+ },
1086
+ children: change.storeLabel
1087
+ }, undefined, false, undefined, this),
1088
+ /* @__PURE__ */ jsxDEV5("span", {
1089
+ style: { flex: 1 }
1090
+ }, undefined, false, undefined, this),
1091
+ change.patches.length > 0 && /* @__PURE__ */ jsxDEV5("span", {
1092
+ style: { color: DEVTOOL_COLOR_TEXT_FAINT, fontSize: "10px", flexShrink: 0 },
1093
+ children: [
1094
+ change.patches.length,
1095
+ " patch",
1096
+ change.patches.length === 1 ? "" : "es"
1097
+ ]
1098
+ }, undefined, true, undefined, this)
1099
+ ]
1100
+ }, undefined, true, undefined, this),
1101
+ /* @__PURE__ */ jsxDEV5("div", {
1102
+ style: {
1103
+ color: DEVTOOL_COLOR_TEXT_SECONDARY,
1104
+ fontSize: "11px",
1105
+ fontFamily: MONO_FONT,
1106
+ overflow: "hidden",
1107
+ textOverflow: "ellipsis",
1108
+ whiteSpace: "nowrap"
1109
+ },
1110
+ children: summarizeChange(change)
1111
+ }, undefined, false, undefined, this)
1112
+ ]
1113
+ }, undefined, true, undefined, this);
1114
+ }
1115
+ function Badge({ color, children }) {
1116
+ return /* @__PURE__ */ jsxDEV5("span", {
1117
+ style: {
1118
+ flexShrink: 0,
1119
+ padding: "1px 6px",
1120
+ borderRadius: "999px",
1121
+ background: color,
1122
+ color: "#0f172a",
1123
+ fontSize: "8px",
1124
+ fontWeight: 700,
1125
+ letterSpacing: "0.08em",
1126
+ fontFamily: SANS_FONT
1127
+ },
1128
+ children
1129
+ }, undefined, false, undefined, this);
1130
+ }
1131
+
1132
+ // src/devtools/browser/components/StateInspector.tsx
1133
+ import { useEffect, useState as useState3 } from "react";
1134
+
1135
+ // src/devtools/browser/components/SectionLabel.tsx
1136
+ import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
1137
+ function SectionLabel({
1138
+ label,
1139
+ color = DEVTOOL_COLOR_SEMANTIC_SYSTEM
1140
+ }) {
1141
+ return /* @__PURE__ */ jsxDEV6("div", {
1142
+ style: {
1143
+ color,
1144
+ fontSize: "0.85em",
1145
+ marginBottom: "3px",
1146
+ textTransform: "uppercase",
1147
+ letterSpacing: "0.05em",
1148
+ fontWeight: 500,
1149
+ textAlign: "left"
1150
+ },
1151
+ children: label
1152
+ }, undefined, false, undefined, this);
1153
+ }
1154
+
1155
+ // src/devtools/browser/components/StateInspector.tsx
1156
+ import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
1157
+ function StateInspector({
1158
+ store,
1159
+ onApply
1160
+ }) {
1161
+ const liveText = safeStringify(store.currentState, 2);
1162
+ const [draft, setDraft] = useState3(liveText);
1163
+ const [dirty, setDirty] = useState3(false);
1164
+ const [error, setError] = useState3(null);
1165
+ useEffect(() => {
1166
+ setDraft(liveText);
1167
+ setDirty(false);
1168
+ setError(null);
1169
+ }, [store.id]);
1170
+ useEffect(() => {
1171
+ if (!dirty)
1172
+ setDraft(liveText);
1173
+ }, [liveText]);
1174
+ const onEdit = (value) => {
1175
+ setDraft(value);
1176
+ setDirty(true);
1177
+ setError(null);
1178
+ };
1179
+ const reload = () => {
1180
+ setDraft(liveText);
1181
+ setDirty(false);
1182
+ setError(null);
1183
+ };
1184
+ const apply = () => {
1185
+ let parsed;
1186
+ try {
1187
+ parsed = JSON.parse(draft);
1188
+ } catch (e) {
1189
+ setError(e instanceof Error ? e.message : "Invalid JSON");
1190
+ return;
1191
+ }
1192
+ onApply(store.id, parsed);
1193
+ setDirty(false);
1194
+ setError(null);
1195
+ };
1196
+ return /* @__PURE__ */ jsxDEV7("div", {
1197
+ style: {
1198
+ flex: 1,
1199
+ display: "flex",
1200
+ flexDirection: "column",
1201
+ overflow: "hidden",
1202
+ minHeight: 0,
1203
+ background: DEVTOOL_DETAIL_BASE_BACKGROUND
1204
+ },
1205
+ children: [
1206
+ /* @__PURE__ */ jsxDEV7("div", {
1207
+ style: {
1208
+ flex: 1,
1209
+ minHeight: 0,
1210
+ display: "flex",
1211
+ flexDirection: "column",
1212
+ padding: "10px 12px 8px"
1213
+ },
1214
+ children: [
1215
+ /* @__PURE__ */ jsxDEV7(SectionLabel, {
1216
+ label: "Current state"
1217
+ }, undefined, false, undefined, this),
1218
+ /* @__PURE__ */ jsxDEV7("div", {
1219
+ style: { flex: 1, minHeight: 0, overflow: "auto" },
1220
+ children: /* @__PURE__ */ jsxDEV7(JsonView, {
1221
+ value: store.currentState,
1222
+ style: { minHeight: "100%" }
1223
+ }, undefined, false, undefined, this)
1224
+ }, undefined, false, undefined, this)
1225
+ ]
1226
+ }, undefined, true, undefined, this),
1227
+ /* @__PURE__ */ jsxDEV7("div", {
1228
+ style: {
1229
+ flex: 1,
1230
+ minHeight: 0,
1231
+ display: "flex",
1232
+ flexDirection: "column",
1233
+ padding: "8px 12px 10px",
1234
+ borderTop: `1px solid ${DEVTOOL_PANEL_DIVIDER_BORDER}`
1235
+ },
1236
+ children: [
1237
+ /* @__PURE__ */ jsxDEV7("div", {
1238
+ style: {
1239
+ display: "flex",
1240
+ alignItems: "center",
1241
+ justifyContent: "space-between",
1242
+ marginBottom: "3px"
1243
+ },
1244
+ children: [
1245
+ /* @__PURE__ */ jsxDEV7(SectionLabel, {
1246
+ label: "Edit & apply",
1247
+ color: DEVTOOL_COLOR_SEMANTIC_WARNING
1248
+ }, undefined, false, undefined, this),
1249
+ dirty && /* @__PURE__ */ jsxDEV7("button", {
1250
+ onClick: reload,
1251
+ style: linkButtonStyle(DEVTOOL_COLOR_TEXT_MUTED),
1252
+ children: "reload from store"
1253
+ }, undefined, false, undefined, this)
1254
+ ]
1255
+ }, undefined, true, undefined, this),
1256
+ /* @__PURE__ */ jsxDEV7("textarea", {
1257
+ value: draft,
1258
+ spellCheck: false,
1259
+ onChange: (e) => onEdit(e.target.value),
1260
+ style: {
1261
+ flex: 1,
1262
+ minHeight: 0,
1263
+ width: "100%",
1264
+ resize: "none",
1265
+ boxSizing: "border-box",
1266
+ background: DEVTOOL_EDITOR_BACKGROUND,
1267
+ color: DEVTOOL_COLOR_TEXT_SECONDARY,
1268
+ border: `1px solid ${error != null ? DEVTOOL_COLOR_SEMANTIC_ERROR : DEVTOOL_SECTION_BACKGROUND}`,
1269
+ borderRadius: "4px",
1270
+ padding: "8px 10px",
1271
+ fontFamily: MONO_FONT,
1272
+ fontSize: "11px",
1273
+ lineHeight: 1.5
1274
+ }
1275
+ }, undefined, false, undefined, this),
1276
+ error != null && /* @__PURE__ */ jsxDEV7("div", {
1277
+ style: {
1278
+ marginTop: "6px",
1279
+ padding: "6px 8px",
1280
+ borderRadius: "4px",
1281
+ background: DEVTOOL_ERROR_BACKGROUND,
1282
+ color: DEVTOOL_COLOR_SEMANTIC_ERROR,
1283
+ fontFamily: MONO_FONT,
1284
+ fontSize: "10px",
1285
+ flexShrink: 0
1286
+ },
1287
+ children: error
1288
+ }, undefined, false, undefined, this),
1289
+ /* @__PURE__ */ jsxDEV7("div", {
1290
+ style: { display: "flex", gap: "8px", marginTop: "8px", flexShrink: 0 },
1291
+ children: /* @__PURE__ */ jsxDEV7("button", {
1292
+ onClick: apply,
1293
+ disabled: !dirty,
1294
+ style: {
1295
+ background: dirty ? DEVTOOL_COLOR_SEMANTIC_SUCCESS : DEVTOOL_SECTION_BACKGROUND,
1296
+ color: dirty ? "#0f172a" : DEVTOOL_COLOR_TEXT_MUTED,
1297
+ border: "none",
1298
+ borderRadius: "4px",
1299
+ cursor: dirty ? "pointer" : "not-allowed",
1300
+ fontSize: "11px",
1301
+ fontWeight: 600,
1302
+ padding: "5px 14px",
1303
+ fontFamily: SANS_FONT
1304
+ },
1305
+ children: "Apply to store"
1306
+ }, undefined, false, undefined, this)
1307
+ }, undefined, false, undefined, this)
1308
+ ]
1309
+ }, undefined, true, undefined, this)
1310
+ ]
1311
+ }, undefined, true, undefined, this);
1312
+ }
1313
+ function linkButtonStyle(color) {
1314
+ return {
1315
+ background: "none",
1316
+ border: "none",
1317
+ color,
1318
+ cursor: "pointer",
1319
+ fontSize: "10px",
1320
+ padding: 0,
1321
+ fontFamily: SANS_FONT
1322
+ };
1323
+ }
1324
+
1325
+ // src/devtools/browser/components/StoreTabs.tsx
1326
+ import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
1327
+ function StoreTabs({
1328
+ stores,
1329
+ selectedStoreId,
1330
+ onSelect,
1331
+ includeAll = true
1332
+ }) {
1333
+ return /* @__PURE__ */ jsxDEV8("div", {
1334
+ style: {
1335
+ display: "flex",
1336
+ gap: "6px",
1337
+ padding: "6px 10px",
1338
+ overflowX: "auto",
1339
+ background: DEVTOOL_LIST_BASE_BACKGROUND,
1340
+ borderBottom: `1px solid ${DEVTOOL_SECTION_BACKGROUND}`,
1341
+ flexShrink: 0
1342
+ },
1343
+ children: [
1344
+ includeAll && /* @__PURE__ */ jsxDEV8(Pill, {
1345
+ active: selectedStoreId == null,
1346
+ onClick: () => onSelect(null),
1347
+ label: "all"
1348
+ }, undefined, false, undefined, this),
1349
+ stores.length === 0 && /* @__PURE__ */ jsxDEV8("span", {
1350
+ style: { color: DEVTOOL_COLOR_TEXT_MUTED, fontSize: "11px", padding: "2px 0" },
1351
+ children: "no stores registered"
1352
+ }, undefined, false, undefined, this),
1353
+ stores.map((store) => /* @__PURE__ */ jsxDEV8(Pill, {
1354
+ active: selectedStoreId === store.id,
1355
+ onClick: () => onSelect(store.id),
1356
+ label: store.label,
1357
+ count: store.changeCount
1358
+ }, store.id, false, undefined, this))
1359
+ ]
1360
+ }, undefined, true, undefined, this);
1361
+ }
1362
+ function Pill({
1363
+ active,
1364
+ onClick,
1365
+ label,
1366
+ count
1367
+ }) {
1368
+ return /* @__PURE__ */ jsxDEV8("button", {
1369
+ onClick,
1370
+ style: {
1371
+ display: "flex",
1372
+ alignItems: "center",
1373
+ gap: "5px",
1374
+ background: active ? DEVTOOL_SECTION_BACKGROUND : "transparent",
1375
+ color: active ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : DEVTOOL_COLOR_TEXT_MUTED,
1376
+ border: `1px solid ${active ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : DEVTOOL_COLOR_TEXT_FAINT}`,
1377
+ borderRadius: "5px",
1378
+ cursor: "pointer",
1379
+ fontSize: "11px",
1380
+ fontFamily: MONO_FONT,
1381
+ padding: "2px 8px",
1382
+ whiteSpace: "nowrap",
1383
+ flexShrink: 0
1384
+ },
1385
+ children: [
1386
+ label,
1387
+ count != null && count > 0 && /* @__PURE__ */ jsxDEV8("span", {
1388
+ style: {
1389
+ color: active ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : DEVTOOL_COLOR_TEXT_FAINT,
1390
+ fontSize: "10px"
1391
+ },
1392
+ children: count
1393
+ }, undefined, false, undefined, this)
1394
+ ]
1395
+ }, undefined, true, undefined, this);
1396
+ }
1397
+
1398
+ // src/devtools/browser/NiceStateDevtools.tsx
1399
+ import { jsxDEV as jsxDEV9, Fragment } from "react/jsx-dev-runtime";
1400
+ if (typeof document !== "undefined" && !document.getElementById("__nice-state-devtools-styles")) {
1401
+ const style = document.createElement("style");
1402
+ style.id = "__nice-state-devtools-styles";
1403
+ style.textContent = `
1404
+ @keyframes __nice-state-pulse {
1405
+ 0%, 100% { opacity: 1; }
1406
+ 50% { opacity: 0.35; }
1407
+ }
1408
+ #__nice-state-devtools-panel ::-webkit-scrollbar { width: 4px; height: 4px; }
1409
+ #__nice-state-devtools-panel ::-webkit-scrollbar-track { background: transparent; }
1410
+ #__nice-state-devtools-panel ::-webkit-scrollbar-thumb { background: #334155; border-radius: 2px; }
1411
+ #__nice-state-devtools-panel ::-webkit-scrollbar-thumb:hover { background: #475569; }
1412
+ #__nice-state-devtools-panel ::-webkit-scrollbar-corner { background: transparent; }
1413
+ `;
1414
+ document.head?.appendChild(style);
1415
+ }
1416
+ var PREFS_KEY = "__nice-state-devtools-prefs";
1417
+ var DOCKED_HEIGHT_DEFAULT = 340;
1418
+ var DOCKED_WIDTH_DEFAULT = 460;
1419
+ var DETAIL_RATIO_DEFAULT = 0.5;
1420
+ var DOCK_POSITIONS = ["dock-bottom", "dock-top", "dock-left", "dock-right"];
1421
+ function isDockPosition(value) {
1422
+ return typeof value === "string" && DOCK_POSITIONS.includes(value);
1423
+ }
1424
+ function readPrefs(defaultPosition, initialOpen) {
1425
+ const fallback = {
1426
+ position: defaultPosition,
1427
+ isOpen: initialOpen,
1428
+ dockedHeight: DOCKED_HEIGHT_DEFAULT,
1429
+ dockedWidth: DOCKED_WIDTH_DEFAULT,
1430
+ detailRatio: DETAIL_RATIO_DEFAULT
1431
+ };
1432
+ try {
1433
+ if (typeof localStorage === "undefined")
1434
+ return fallback;
1435
+ const stored = localStorage.getItem(PREFS_KEY);
1436
+ const merged = stored != null ? { ...fallback, ...JSON.parse(stored) } : fallback;
1437
+ if (!isDockPosition(merged.position))
1438
+ merged.position = defaultPosition;
1439
+ return merged;
1440
+ } catch {
1441
+ return fallback;
1442
+ }
1443
+ }
1444
+ function writePrefs(prefs) {
1445
+ try {
1446
+ localStorage.setItem(PREFS_KEY, JSON.stringify(prefs));
1447
+ } catch {
1448
+ return;
1449
+ }
1450
+ }
1451
+ var EMPTY_SNAPSHOT = { stores: [], changes: [], paused: false };
1452
+ function NiceStateDevtools(props) {
1453
+ if (false) {}
1454
+ return /* @__PURE__ */ jsxDEV9(NiceStateDevtools_Panel, {
1455
+ ...props
1456
+ }, undefined, false, undefined, this);
1457
+ }
1458
+ function NiceStateDevtools_Panel({
1459
+ core,
1460
+ position: defaultPosition = "dock-bottom",
1461
+ initialOpen = false
1462
+ }) {
1463
+ const [prefs, setPrefsRaw] = useState4(() => readPrefs(defaultPosition, initialOpen));
1464
+ const [snapshot, setSnapshot] = useState4(EMPTY_SNAPSHOT);
1465
+ const [mode, setMode] = useState4("timeline");
1466
+ const [storeFilter, setStoreFilter] = useState4(null);
1467
+ const [selectedChangeCuid, setSelectedChangeCuid] = useState4(null);
1468
+ useEffect2(() => core.subscribe(setSnapshot), [core]);
1469
+ const setPrefs = (update) => {
1470
+ setPrefsRaw((prev) => {
1471
+ const next = { ...prev, ...update };
1472
+ writePrefs(next);
1473
+ return next;
1474
+ });
1475
+ };
1476
+ const { stores, changes, paused } = snapshot;
1477
+ const { position, isOpen, dockedHeight, dockedWidth, detailRatio } = prefs;
1478
+ const dockSide = getDockSide(position);
1479
+ const isHorizDock = dockSide === "top" || dockSide === "bottom";
1480
+ const dockedSize = isHorizDock ? dockedHeight : dockedWidth;
1481
+ const filteredChanges = useMemo(() => storeFilter == null ? changes : changes.filter((c) => c.storeId === storeFilter), [changes, storeFilter]);
1482
+ const selectedChange = selectedChangeCuid != null ? changes.find((c) => c.cuid === selectedChangeCuid) ?? null : null;
1483
+ const activeStore = stores.find((s) => s.id === storeFilter) ?? (stores.length > 0 ? stores[0] : null);
1484
+ const dock = useMemo(() => getDevtoolsDockCoordinator(), []);
1485
+ const panelId = useId();
1486
+ const [, bumpView] = useReducer((n) => n + 1, 0);
1487
+ const badge = changes.length > 0 ? String(changes.length) : undefined;
1488
+ useEffect2(() => {
1489
+ const unregister = dock.register({
1490
+ id: panelId,
1491
+ label: "state",
1492
+ icon: "\uD83E\uDDE9",
1493
+ side: dockSide,
1494
+ size: dockedSize,
1495
+ open: isOpen,
1496
+ badge,
1497
+ onOpen: () => setPrefs({ isOpen: true })
1498
+ });
1499
+ const unsubscribe = dock.subscribe(bumpView);
1500
+ return () => {
1501
+ unregister();
1502
+ unsubscribe();
1503
+ };
1504
+ }, [dock, panelId]);
1505
+ useEffect2(() => {
1506
+ dock.update(panelId, { side: dockSide, size: dockedSize, open: isOpen, badge });
1507
+ }, [dock, panelId, dockSide, dockedSize, isOpen, badge]);
1508
+ const view = dock.getView(panelId);
1509
+ const baseStyle = {
1510
+ position: "fixed",
1511
+ zIndex: 2147483646,
1512
+ fontFamily: "ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace",
1513
+ fontSize: "12px"
1514
+ };
1515
+ if (!isOpen) {
1516
+ if (view.isPrimary && !view.anyOpen) {
1517
+ return /* @__PURE__ */ jsxDEV9(DevtoolsLauncher, {
1518
+ items: view.devtools
1519
+ }, undefined, false, undefined, this);
1520
+ }
1521
+ return null;
1522
+ }
1523
+ const panelStyle = {
1524
+ ...baseStyle,
1525
+ background: DEVTOOL_LIST_BASE_BACKGROUND,
1526
+ border: `1px solid ${DEVTOOL_PANEL_BORDER}`,
1527
+ color: DEVTOOL_COLOR_TEXT_SECONDARY,
1528
+ display: "flex",
1529
+ flexDirection: "column",
1530
+ boxShadow: "0 -4px 24px rgba(0,0,0,0.4)",
1531
+ overflow: "hidden",
1532
+ ...dockSide === "bottom" ? { bottom: view.dockOffset, left: 0, right: 0, height: `${dockedSize}px`, borderRadius: "8px 8px 0 0" } : dockSide === "top" ? { top: view.dockOffset, left: 0, right: 0, height: `${dockedSize}px`, borderRadius: "0 0 8px 8px" } : dockSide === "left" ? { top: 0, left: view.dockOffset, bottom: 0, width: `${dockedSize}px`, borderRadius: "0 8px 8px 0" } : { top: 0, right: view.dockOffset, bottom: 0, width: `${dockedSize}px`, borderRadius: "8px 0 0 8px" }
1533
+ };
1534
+ return /* @__PURE__ */ jsxDEV9("div", {
1535
+ id: "__nice-state-devtools-panel",
1536
+ style: panelStyle,
1537
+ children: [
1538
+ /* @__PURE__ */ jsxDEV9(ResizeHandle, {
1539
+ dockSide,
1540
+ dockedSize,
1541
+ onChange: (size) => setPrefs(isHorizDock ? { dockedHeight: size } : { dockedWidth: size })
1542
+ }, undefined, false, undefined, this),
1543
+ /* @__PURE__ */ jsxDEV9(PanelHeader, {
1544
+ position,
1545
+ onPositionChange: (p) => setPrefs({ position: p }),
1546
+ onClose: () => setPrefs({ isOpen: false }),
1547
+ onClear: changes.length > 0 ? () => {
1548
+ core.clear();
1549
+ setSelectedChangeCuid(null);
1550
+ } : undefined,
1551
+ paused,
1552
+ onTogglePause: () => core.togglePaused(),
1553
+ openOthers: view.otherClosed,
1554
+ children: /* @__PURE__ */ jsxDEV9(SegmentedControl, {
1555
+ options: [
1556
+ { value: "timeline", label: "Timeline" },
1557
+ { value: "state", label: "State" }
1558
+ ],
1559
+ value: mode,
1560
+ onChange: setMode
1561
+ }, undefined, false, undefined, this)
1562
+ }, undefined, false, undefined, this),
1563
+ /* @__PURE__ */ jsxDEV9(StoreTabs, {
1564
+ stores,
1565
+ selectedStoreId: mode === "state" ? activeStore?.id ?? null : storeFilter,
1566
+ onSelect: setStoreFilter,
1567
+ includeAll: mode === "timeline"
1568
+ }, undefined, false, undefined, this),
1569
+ mode === "state" ? activeStore != null ? /* @__PURE__ */ jsxDEV9(StateInspector, {
1570
+ store: activeStore,
1571
+ onApply: (id, next) => core.applyEdit(id, next)
1572
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV9(EmptyMessage, {
1573
+ children: "No stores registered. Call core.registerStore(...)."
1574
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV9("div", {
1575
+ style: {
1576
+ flex: 1,
1577
+ display: "flex",
1578
+ flexDirection: isHorizDock ? "row" : "column",
1579
+ overflow: "hidden",
1580
+ minHeight: 0
1581
+ },
1582
+ children: [
1583
+ /* @__PURE__ */ jsxDEV9("div", {
1584
+ style: {
1585
+ flexGrow: selectedChange != null ? 1 - detailRatio : 1,
1586
+ flexShrink: 1,
1587
+ flexBasis: 0,
1588
+ minWidth: 0,
1589
+ minHeight: 0,
1590
+ overflowY: "auto"
1591
+ },
1592
+ children: /* @__PURE__ */ jsxDEV9(ChangeList, {
1593
+ changes: filteredChanges,
1594
+ selectedCuid: selectedChangeCuid,
1595
+ onSelect: (cuid) => setSelectedChangeCuid((prev) => prev === cuid ? null : cuid),
1596
+ showStore: storeFilter == null
1597
+ }, undefined, false, undefined, this)
1598
+ }, undefined, false, undefined, this),
1599
+ selectedChange != null && /* @__PURE__ */ jsxDEV9(Fragment, {
1600
+ children: [
1601
+ /* @__PURE__ */ jsxDEV9(SplitHandle, {
1602
+ horizontal: isHorizDock,
1603
+ onRatioChange: (ratio) => setPrefs({ detailRatio: ratio })
1604
+ }, undefined, false, undefined, this),
1605
+ /* @__PURE__ */ jsxDEV9("div", {
1606
+ style: {
1607
+ flexGrow: detailRatio,
1608
+ flexShrink: 1,
1609
+ flexBasis: 0,
1610
+ minWidth: 0,
1611
+ minHeight: 0,
1612
+ display: "flex",
1613
+ flexDirection: "column",
1614
+ overflow: "hidden",
1615
+ ...isHorizDock ? {
1616
+ borderLeft: `1px solid ${DEVTOOL_PANEL_DIVIDER_BORDER}`,
1617
+ boxShadow: "inset 18px 0 36px -14px rgba(0,0,0,0.8)"
1618
+ } : {
1619
+ borderTop: `1px solid ${DEVTOOL_PANEL_DIVIDER_BORDER}`,
1620
+ boxShadow: "inset 0 18px 36px -14px rgba(0,0,0,0.8)"
1621
+ }
1622
+ },
1623
+ children: /* @__PURE__ */ jsxDEV9(ChangeDetailPanel, {
1624
+ change: selectedChange,
1625
+ onRevert: (c) => core.revertChange(c)
1626
+ }, selectedChange.cuid, false, undefined, this)
1627
+ }, undefined, false, undefined, this)
1628
+ ]
1629
+ }, undefined, true, undefined, this)
1630
+ ]
1631
+ }, undefined, true, undefined, this)
1632
+ ]
1633
+ }, undefined, true, undefined, this);
1634
+ }
1635
+ function EmptyMessage({ children }) {
1636
+ return /* @__PURE__ */ jsxDEV9("div", {
1637
+ style: {
1638
+ flex: 1,
1639
+ display: "flex",
1640
+ alignItems: "center",
1641
+ justifyContent: "center",
1642
+ padding: "24px",
1643
+ textAlign: "center",
1644
+ color: DEVTOOL_COLOR_TEXT_MUTED,
1645
+ fontSize: "11px"
1646
+ },
1647
+ children
1648
+ }, undefined, false, undefined, this);
1649
+ }
1650
+ export {
1651
+ StateDevtoolsCore,
1652
+ NiceStateDevtools
1653
+ };