reactoradar 1.6.4 → 1.6.6

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.
@@ -1,134 +0,0 @@
1
- 'use strict';
2
-
3
- const state = window.RNDebug.state;
4
- const $ = window.RNDebug.$;
5
- const esc = window.RNDebug.esc;
6
- const highlight = window.RNDebug.highlight;
7
- const formatSize = window.RNDebug.formatSize;
8
- const renderJSON = window.RNDebug.renderJSON;
9
-
10
- // ─────────────────────────────────────────────────────────────────────────────
11
- // ASYNC STORAGE PANEL
12
- // ─────────────────────────────────────────────────────────────────────────────
13
- function initStoragePanel() {
14
- const panel = $('panel-storage');
15
- panel.innerHTML = `
16
- <div class="panel-toolbar">
17
- <span class="panel-label">AsyncStorage</span>
18
- <span class="badge" id="sBadge">0</span>
19
- </div>
20
- <div class="storage-layout">
21
- <div class="storage-keys">
22
- <div class="panel-toolbar" style="height:32px">
23
- <span style="font-size:10px;color:var(--text-dim);text-transform:uppercase;letter-spacing:1px">Keys</span>
24
- </div>
25
- <div class="scroll-area storage-keys-list" id="storageKeyList">
26
- <div class="empty-state" id="storageEmpty">
27
- <div class="icon">💾</div>
28
- <div class="label">No storage data</div>
29
- <div class="hint">Add storage plugin to RNDebugPlugin</div>
30
- </div>
31
- </div>
32
- </div>
33
- <div class="storage-value-view">
34
- <div class="storage-value-toolbar">
35
- <span style="font-size:10px;color:var(--text-dim);text-transform:uppercase;letter-spacing:1px">Value</span>
36
- <span id="storageSelectedKey" style="font-size:11px;color:var(--accent);margin-left:8px"></span>
37
- </div>
38
- <div class="storage-value-body" id="storageValueBody">
39
- <span style="color:var(--text-dim)">Select a key to view its value</span>
40
- </div>
41
- </div>
42
- </div>`;
43
- }
44
-
45
- let _storageRAF = null;
46
- let _storageChanged = false;
47
-
48
- function handleStorageEvent(event) {
49
- if (event.type !== 'storage') return;
50
- const { key, value, action } = event;
51
- if (action === 'set' || action === 'snapshot') {
52
- if (action === 'snapshot' && typeof key === 'object') {
53
- // Skip if data hasn't changed
54
- const newKeys = Object.keys(key).sort().join(',');
55
- const oldKeys = state.storage.keys.sort().join(',');
56
- if (newKeys === oldKeys) {
57
- // Check if values changed
58
- let same = true;
59
- for (const [k, v] of Object.entries(key)) {
60
- if (state.storage.entries[k] !== v) { same = false; break; }
61
- }
62
- if (same) return; // No changes, skip re-render
63
- }
64
- Object.entries(key).forEach(([k, v]) => {
65
- state.storage.entries[k] = v;
66
- if (!state.storage.keys.includes(k)) state.storage.keys.push(k);
67
- });
68
- } else {
69
- if (state.storage.entries[key] === value) return; // No change
70
- state.storage.entries[key] = value;
71
- if (!state.storage.keys.includes(key)) state.storage.keys.push(key);
72
- }
73
- } else if (action === 'remove') {
74
- if (!(key in state.storage.entries)) return; // Already removed
75
- delete state.storage.entries[key];
76
- state.storage.keys = state.storage.keys.filter(k => k !== key);
77
- if (state.storage.selected === key) state.storage.selected = null;
78
- }
79
- $('sBadge').textContent = state.storage.keys.length;
80
- // Debounce render via rAF
81
- if (!_storageRAF) {
82
- _storageRAF = requestAnimationFrame(() => {
83
- _storageRAF = null;
84
- renderStorage();
85
- });
86
- }
87
- }
88
-
89
- function renderStorage() {
90
- const list = $('storageKeyList');
91
- const empty = $('storageEmpty');
92
- if (!list) return;
93
-
94
- const visible = state.storage.keys.filter(k =>
95
- !state.filter || k.toLowerCase().includes(state.filter)
96
- );
97
-
98
- empty.style.display = visible.length ? 'none' : 'flex';
99
- list.querySelectorAll('.storage-key-row').forEach(e => e.remove());
100
-
101
- const frag = document.createDocumentFragment();
102
- visible.forEach(k => {
103
- const div = document.createElement('div');
104
- const val = state.storage.entries[k] || '';
105
- div.className = 'storage-key-row entry' + (k === state.storage.selected ? ' selected' : '');
106
- div.innerHTML = `
107
- <span class="key-name">${highlight(esc(k), state.filter)}</span>
108
- <span class="key-size">${formatSize(val.length)}</span>`;
109
- div.onclick = () => { state.storage.selected = k; renderStorage(); renderStorageValue(); };
110
- frag.appendChild(div);
111
- });
112
- list.appendChild(frag);
113
- renderStorageValue();
114
- }
115
-
116
- function renderStorageValue() {
117
- const body = $('storageValueBody');
118
- const keyLabel = $('storageSelectedKey');
119
- if (!body) return;
120
- const { selected, entries } = state.storage;
121
- if (!selected) {
122
- body.innerHTML = '<span style="color:var(--text-dim)">Select a key</span>';
123
- if (keyLabel) keyLabel.textContent = '';
124
- return;
125
- }
126
- if (keyLabel) keyLabel.textContent = selected;
127
- body.innerHTML = renderJSON(entries[selected]);
128
- }
129
-
130
- // ─── Export via window.RNDebug ────────────────────────────────────────────────
131
- window.RNDebug.initStoragePanel = initStoragePanel;
132
- window.RNDebug.handleStorageEvent = handleStorageEvent;
133
- window.RNDebug.renderStorage = renderStorage;
134
- window.RNDebug.renderStorageValue = renderStorageValue;
@@ -1,132 +0,0 @@
1
- 'use strict';
2
-
3
- // ─── Shared namespace ─────────────────────────────────────────────────────────
4
- window.RNDebug = window.RNDebug || {};
5
-
6
- // ─── State ────────────────────────────────────────────────────────────────────
7
- window.RNDebug.state = {
8
- filter: '',
9
- activePanel: 'console',
10
- ports: {},
11
-
12
- console: { logs: [], levelFilter: 'all' },
13
-
14
- network: {
15
- requests: {},
16
- order: [],
17
- statusFilter: 'all',
18
- typeFilter: 'all',
19
- searchFilter: '',
20
- throttle: 'none',
21
- enabled: true,
22
- selectedId: null,
23
- sortCol: 'time',
24
- sortDir: 'desc',
25
- },
26
-
27
- redux: {
28
- actions: [], // { type, payload, index, ts }
29
- states: [], // full state snapshot after each action
30
- selected: -1,
31
- stateTab: 'state', // 'state' | 'diff' | 'action'
32
- travelIndex: -1,
33
- },
34
-
35
- storage: {
36
- entries: {}, // key → value string
37
- keys: [], // ordered keys
38
- selected: null,
39
- },
40
-
41
- // Device connection tracking
42
- connections: { redux: false, network: false, storage: false, reactDT: false },
43
- };
44
-
45
- // ─── Helpers ──────────────────────────────────────────────────────────────────
46
- const $ = id => document.getElementById(id);
47
- const esc = s => s == null ? '' : String(s)
48
- .replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
49
- const ts = ms => new Date(ms).toLocaleTimeString('en',{hour12:false,hour:'2-digit',minute:'2-digit',second:'2-digit'});
50
- const cls = (el, ...classes) => { el.className = classes.filter(Boolean).join(' '); return el; };
51
-
52
- function pretty(val) {
53
- if (val == null) return '';
54
- if (typeof val === 'string') { try { return JSON.stringify(JSON.parse(val),null,2); } catch{} return val; }
55
- return JSON.stringify(val, null, 2);
56
- }
57
-
58
- function syntaxHighlight(json) {
59
- return json
60
- .replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)/g, m => {
61
- if (/^"/.test(m)) return /:$/.test(m) ? `<span class="json-key">${m}</span>` : `<span class="json-str">${m}</span>`;
62
- if (/true|false/.test(m)) return `<span class="json-bool">${m}</span>`;
63
- if (/null/.test(m)) return `<span class="json-null">${m}</span>`;
64
- return `<span class="json-num">${m}</span>`;
65
- });
66
- }
67
-
68
- function renderJSON(val) {
69
- try {
70
- const str = typeof val === 'string' ? val : JSON.stringify(val, null, 2);
71
- return syntaxHighlight(esc(str));
72
- } catch { return esc(String(val)); }
73
- }
74
-
75
- function tryURL(url) { try { return new URL(url); } catch { return null; } }
76
-
77
- // Extract short "filename:line" from a stack frame like "at Component (/path/to/file.js:42:10)"
78
- function extractCallerShort(caller) {
79
- if (!caller) return '';
80
- // Match patterns like "filename.js:123" or "filename.tsx:123"
81
- const m = caller.match(/([^/\\\s]+\.[jt]sx?):(\d+)/);
82
- if (m) return `${m[1]}:${m[2]}`;
83
- // Fallback: just trim and shorten
84
- const trimmed = caller.replace(/^\s*at\s+/, '').trim();
85
- return trimmed.length > 40 ? trimmed.slice(-40) : trimmed;
86
- }
87
-
88
- function highlight(html, term) {
89
- if (!term) return html;
90
- const re = new RegExp(`(${term.replace(/[.*+?^${}()|[\]\\]/g,'\\$&')})`, 'gi');
91
- return html.replace(re, '<mark>$1</mark>');
92
- }
93
-
94
- function formatSize(bytes) {
95
- if (bytes < 1024) return `${bytes}b`;
96
- return `${(bytes/1024).toFixed(1)}kb`;
97
- }
98
-
99
- // ─── Shared context menu helper ──────────────────────────────────────────────
100
- function showContextMenu(e, items) {
101
- document.querySelectorAll('.ctx-menu').forEach(el => el.remove());
102
- const menu = document.createElement('div');
103
- menu.className = 'ctx-menu';
104
- items.forEach(({ label, action }) => {
105
- const item = document.createElement('div');
106
- item.className = 'ctx-item';
107
- item.textContent = label;
108
- item.addEventListener('click', () => { action(); menu.remove(); });
109
- menu.appendChild(item);
110
- });
111
- menu.style.left = Math.min(e.clientX, window.innerWidth - 200) + 'px';
112
- menu.style.top = Math.min(e.clientY, window.innerHeight - items.length * 32 - 10) + 'px';
113
- document.body.appendChild(menu);
114
- setTimeout(() => {
115
- const close = (ev) => { if (!menu.contains(ev.target)) { menu.remove(); document.removeEventListener('click', close); } };
116
- document.addEventListener('click', close);
117
- }, 0);
118
- }
119
-
120
- // ─── Export all via window.RNDebug ────────────────────────────────────────────
121
- window.RNDebug.$ = $;
122
- window.RNDebug.esc = esc;
123
- window.RNDebug.ts = ts;
124
- window.RNDebug.cls = cls;
125
- window.RNDebug.pretty = pretty;
126
- window.RNDebug.syntaxHighlight = syntaxHighlight;
127
- window.RNDebug.renderJSON = renderJSON;
128
- window.RNDebug.tryURL = tryURL;
129
- window.RNDebug.extractCallerShort = extractCallerShort;
130
- window.RNDebug.highlight = highlight;
131
- window.RNDebug.formatSize = formatSize;
132
- window.RNDebug.showContextMenu = showContextMenu;
@@ -1,145 +0,0 @@
1
- /* ── Object Inspector Tree (Chrome DevTools-like) ────────────────────────── */
2
- .ov-node { margin: 0; }
3
- .ov-header {
4
- display: inline-flex;
5
- align-items: baseline;
6
- gap: 2px;
7
- cursor: pointer;
8
- padding: 1px 0;
9
- border-radius: 2px;
10
- }
11
- .ov-arrow { user-select: none; -webkit-user-select: none; }
12
- .ov-header:hover { background: var(--bg3); }
13
- .ov-arrow {
14
- display: inline-block;
15
- width: 12px;
16
- font-size: 8px;
17
- color: var(--text-dim);
18
- text-align: center;
19
- flex-shrink: 0;
20
- transition: transform 0.1s;
21
- }
22
- .ov-key { color: var(--accent); }
23
- .ov-preview { color: var(--text-dim); font-style: italic; }
24
- .ov-children { padding-left: 16px; border-left: 1px solid var(--border); margin-left: 5px; }
25
- .ov-leaf { padding: 1px 0 1px 14px; line-height: 1.55; }
26
- .ov-meta { color: var(--text-dim); font-style: italic; font-size: 10px; }
27
-
28
- /* Value type colors */
29
- .ov-str { color: var(--green); }
30
- .ov-num { color: var(--orange); }
31
- .ov-bool { color: var(--accent2); }
32
- .ov-null { color: var(--text-dim); font-style: italic; }
33
- .ov-undef { color: var(--text-dim); font-style: italic; }
34
-
35
- /* JSON syntax highlighting */
36
- .json-key { color: var(--accent); }
37
- .json-str { color: var(--green); }
38
- .json-num { color: var(--orange); }
39
- .json-bool { color: var(--accent2); }
40
- .json-null { color: var(--text-dim); }
41
-
42
- /* highlight */
43
- mark { background: rgba(79,172,255,.2); color: var(--accent); border-radius: 2px; padding: 0 1px; }
44
-
45
- /* ── Toggle Switch ──────────────────────────────────────────────────────────── */
46
- .toggle-label {
47
- display: flex;
48
- align-items: center;
49
- gap: 6px;
50
- cursor: pointer;
51
- -webkit-app-region: no-drag;
52
- }
53
- .toggle-text {
54
- font-size: 10px;
55
- font-weight: 500;
56
- color: var(--text-dim);
57
- text-transform: uppercase;
58
- letter-spacing: 0.5px;
59
- }
60
- .toggle-input { display: none; }
61
- .toggle-slider {
62
- position: relative;
63
- width: 28px;
64
- height: 16px;
65
- border-radius: 8px;
66
- background: var(--bg4);
67
- border: 1px solid var(--border2);
68
- transition: background 0.2s;
69
- }
70
- .toggle-slider::after {
71
- content: '';
72
- position: absolute;
73
- top: 2px;
74
- left: 2px;
75
- width: 10px;
76
- height: 10px;
77
- border-radius: 50%;
78
- background: var(--text-dim);
79
- transition: transform 0.2s, background 0.2s;
80
- }
81
- .toggle-input:checked + .toggle-slider {
82
- background: var(--green);
83
- border-color: var(--green);
84
- }
85
- .toggle-input:checked + .toggle-slider::after {
86
- transform: translateX(12px);
87
- background: #fff;
88
- }
89
-
90
- /* Context menu */
91
- .ctx-menu {
92
- position: fixed;
93
- background: var(--bg2);
94
- border: 1px solid var(--border2);
95
- border-radius: 6px;
96
- padding: 4px 0;
97
- min-width: 180px;
98
- box-shadow: 0 4px 16px rgba(0,0,0,.3);
99
- z-index: 1000;
100
- font-size: 11px;
101
- }
102
- .ctx-item {
103
- padding: 6px 14px;
104
- cursor: pointer;
105
- color: var(--text);
106
- transition: background 0.1s;
107
- }
108
- .ctx-item:hover { background: var(--bg4); color: var(--accent); }
109
-
110
- /* ─────────────────────────────────────────────────────────────────────────────
111
- REACT TREE PANEL (iframe wrapper)
112
- ───────────────────────────────────────────────────────────────────────────── */
113
- .react-panel-inner {
114
- display: flex;
115
- flex-direction: column;
116
- height: 100%;
117
- }
118
- .react-devtools-iframe {
119
- flex: 1;
120
- border: none;
121
- background: #1a1d24;
122
- width: 100%;
123
- }
124
- .react-connect-hint {
125
- display: flex;
126
- flex-direction: column;
127
- align-items: center;
128
- justify-content: center;
129
- height: 100%;
130
- gap: 14px;
131
- color: var(--text-dim);
132
- }
133
- .react-connect-hint code { background: var(--bg3); padding: 3px 8px; border-radius: 4px; color: var(--accent); font-size: 11px; }
134
- .btn-launch {
135
- padding: 8px 20px;
136
- border-radius: 6px;
137
- border: 1px solid var(--accent);
138
- background: rgba(79,172,255,.1);
139
- color: var(--accent);
140
- font-family: inherit;
141
- font-size: 12px;
142
- cursor: pointer;
143
- transition: all 0.15s;
144
- }
145
- .btn-launch:hover { background: rgba(79,172,255,.2); }
@@ -1,73 +0,0 @@
1
- /* ─────────────────────────────────────────────────────────────────────────────
2
- CONSOLE PANEL
3
- ───────────────────────────────────────────────────────────────────────────── */
4
- .log-row {
5
- display: grid;
6
- grid-template-columns: 58px 44px 1fr;
7
- gap: 8px;
8
- align-items: baseline;
9
- padding: 4px 14px;
10
- border-bottom: 1px solid transparent;
11
- transition: background 0.08s;
12
- cursor: default;
13
- }
14
- .log-row:hover { background: var(--bg3); }
15
- .log-row.warn { background: rgba(245,200,66,.03); border-bottom-color: rgba(245,200,66,.06); }
16
- .log-row.error { background: rgba(255,94,114,.04); border-bottom-color: rgba(255,94,114,.07); }
17
-
18
- .log-time { color: var(--text-dim); font-size: 10px; white-space: nowrap; }
19
-
20
- .lvl-badge { display: inline-block; font-size: 9px; font-weight: 700; padding: 1px 5px; border-radius: 3px; text-transform: uppercase; letter-spacing: 0.5px; }
21
- .lvl-log { background: rgba(200,210,230,.07); color: var(--text-dim); }
22
- .lvl-info { background: rgba(79,172,255,.12); color: var(--accent); }
23
- .lvl-warn { background: rgba(245,200,66,.12); color: var(--yellow); }
24
- .lvl-error { background: rgba(255,94,114,.15); color: var(--red); }
25
- .lvl-debug { background: rgba(155,127,255,.12); color: var(--accent2); }
26
-
27
- .log-body-wrap {
28
- display: flex;
29
- flex-direction: column;
30
- cursor: pointer;
31
- min-width: 0;
32
- }
33
- .log-arrow {
34
- display: inline-block;
35
- width: 14px;
36
- font-size: 8px;
37
- color: var(--text-dim);
38
- flex-shrink: 0;
39
- user-select: none;
40
- -webkit-user-select: none;
41
- margin-bottom: 1px;
42
- }
43
- .log-arrow.expanded { color: var(--accent); }
44
- .log-preview {
45
- display: flex;
46
- align-items: baseline;
47
- gap: 8px;
48
- color: var(--text);
49
- font-size: 11px;
50
- line-height: 1.5;
51
- overflow: hidden;
52
- white-space: nowrap;
53
- user-select: text;
54
- -webkit-user-select: text;
55
- }
56
- .log-preview > span:first-child {
57
- overflow: hidden;
58
- text-overflow: ellipsis;
59
- flex: 1;
60
- min-width: 0;
61
- }
62
- .log-caller-inline {
63
- flex-shrink: 0;
64
- font-size: 10px;
65
- color: var(--text-dim);
66
- opacity: 0.7;
67
- }
68
- .log-full {
69
- padding-top: 4px;
70
- }
71
- .log-body { color: var(--text); white-space: pre-wrap; word-break: break-word; line-height: 1.55; user-select: text; -webkit-user-select: text; cursor: text; }
72
- .log-text { color: var(--text); }
73
- .log-caller { display: block; color: var(--text-dim); font-size: 10px; margin-top: 3px; }