lynx-console 0.0.0 → 0.1.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.
package/README.md ADDED
@@ -0,0 +1,132 @@
1
+ # lynx-console
2
+
3
+ An in-app developer console that can be embedded in Lynx apps. View console logs, network requests, and performance metrics in real time.
4
+
5
+ ## Features
6
+
7
+ - **Console Logs** — View output from `console.log`, `console.error`, and more in real time
8
+ - **Main Thread Console** — Capture logs from the main thread
9
+ - **Network Monitor** — Inspect method, headers, body, and response of `fetch` requests
10
+ - **Performance Monitor** — Track performance metrics such as FCP (First Contentful Paint)
11
+ - **Floating Button** — Open and close the console with a floating button that displays the FCP value
12
+ - **Light/Dark Theme** support
13
+ - **Seed Design** based UI
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ yarn add lynx-console
19
+ ```
20
+
21
+ ### Peer Dependencies
22
+
23
+ ```bash
24
+ yarn add @lynx-js/react @lynx-js/types
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ### 1. Initialize Monitors
30
+
31
+ Call the monitoring functions at your app's entry point. This setup must run **before** the `LynxConsole` component is rendered.
32
+
33
+ ```typescript
34
+ import {
35
+ initLogMonitor,
36
+ initMainThreadConsole,
37
+ initNetworkMonitor,
38
+ initPerformanceMonitor,
39
+ } from "lynx-console/setup";
40
+
41
+ initLogMonitor();
42
+ initMainThreadConsole();
43
+ initNetworkMonitor();
44
+ initPerformanceMonitor();
45
+ ```
46
+
47
+ ### 2. Render the Component
48
+
49
+ ```tsx
50
+ import LynxConsole from "lynx-console";
51
+
52
+ function App() {
53
+ return (
54
+ <view>
55
+ {/* Your app content */}
56
+ <LynxConsole theme="light" safeAreaInsetBottom="34px" />
57
+ </view>
58
+ );
59
+ }
60
+ ```
61
+
62
+ ```tsx
63
+ const LynxConsole = lazy(() => import("lynx-console"));
64
+
65
+ function App() {
66
+ return (
67
+ <view>
68
+ {/* Your app content */}
69
+ <Suspense>
70
+ <LynxConsole theme="light" safeAreaInsetBottom="34px" />
71
+ <Suspense>
72
+ </view>
73
+ );
74
+ }
75
+ ```
76
+
77
+ ### Controlling with ref
78
+
79
+ You can programmatically open and close the console using `LynxConsoleHandle`.
80
+
81
+ ```tsx
82
+ import { type LynxConsoleHandle } from "lynx-console";
83
+ import { useRef } from "@lynx-js/react";
84
+
85
+ const LynxConsole = lazy(() => import("lynx-console"));
86
+
87
+ function App() {
88
+ const consoleRef = useRef<LynxConsoleHandle>(null);
89
+
90
+ const toggleConsole = () => {
91
+ if (consoleRef.current?.isOpen()) {
92
+ consoleRef.current.close();
93
+ } else {
94
+ consoleRef.current?.open();
95
+ }
96
+ };
97
+
98
+ return (
99
+ <view>
100
+ <Suspense>
101
+ <LynxConsole ref={consoleRef} />
102
+ <Suspense>
103
+ </view>
104
+ );
105
+ }
106
+ ```
107
+
108
+ ## API
109
+
110
+ ### `LynxConsole` Props
111
+
112
+ | Prop | Type | Default | Description |
113
+ |------|------|---------|-------------|
114
+ | `theme` | `"light" \| "dark"` | `"light"` | Console UI theme |
115
+ | `safeAreaInsetBottom` | `string` | `"50px"` | Bottom safe area inset |
116
+
117
+ ### `LynxConsoleHandle`
118
+
119
+ | Method | Description |
120
+ |--------|-------------|
121
+ | `open()` | Opens the console |
122
+ | `close()` | Closes the console |
123
+ | `isOpen()` | Returns whether the console is open |
124
+
125
+ ### Monitor Initialization Functions
126
+
127
+ | Function | Description |
128
+ |----------|-------------|
129
+ | `initLogMonitor()` | Captures `console.log`, `console.error`, etc. |
130
+ | `initMainThreadConsole()` | Captures console output from the main thread |
131
+ | `initNetworkMonitor()` | Intercepts and records `fetch` requests |
132
+ | `initPerformanceMonitor()` | Collects performance metrics |
@@ -7,7 +7,7 @@
7
7
  display: flex;
8
8
  justify-content: center;
9
9
  align-items: flex-end;
10
- z-index: 3;
10
+ z-index: 9999;
11
11
  }
12
12
  .BottomSheet_backdrop__5pjw6y1 {
13
13
  position: fixed;
@@ -15,7 +15,7 @@
15
15
  right: 0;
16
16
  bottom: 0;
17
17
  left: 0;
18
- z-index: 2;
18
+ z-index: 9998;
19
19
  background: var(--seed-color-bg-overlay);
20
20
  transition: opacity var(--seed-duration-d6) cubic-bezier(0.4, 0, 0.2, 1);
21
21
  }
@@ -0,0 +1,340 @@
1
+ .ConsolePanel_container__db6kuu0 {
2
+ display: flex;
3
+ flex-direction: column;
4
+ height: 100%;
5
+ }
6
+ .ConsolePanel_placeholder__db6kuu1 {
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+ height: 100%;
11
+ }
12
+ .ConsolePanel_placeholderText__db6kuu2 {
13
+ font-size: 0.875rem;
14
+ line-height: 1.1875rem;
15
+ font-weight: var(--seed-font-weight-regular);
16
+ color: var(--seed-color-fg-disabled);
17
+ }
18
+ .ConsolePanel_logContainer__db6kuu3 {
19
+ display: flex;
20
+ flex-direction: column;
21
+ flex: 1;
22
+ padding-top: 4px;
23
+ }
24
+ .ConsolePanel_logHeader__db6kuu4 {
25
+ display: flex;
26
+ flex-direction: row;
27
+ align-items: center;
28
+ justify-content: space-between;
29
+ padding-bottom: 3px;
30
+ }
31
+ .ConsolePanel_fadeTop__db6kuu5 {
32
+ height: 20px;
33
+ margin-bottom: -20px;
34
+ z-index: 1;
35
+ background: linear-gradient(to bottom, var(--seed-color-bg-layer-default), #ffffff00);
36
+ }
37
+ .ConsolePanel_filterWrapper__db6kuu6 {
38
+ position: relative;
39
+ }
40
+ .ConsolePanel_filterButton__db6kuu7 {
41
+ display: flex;
42
+ flex-direction: row;
43
+ align-items: center;
44
+ padding: 3px 6px;
45
+ background-color: var(--seed-color-bg-neutral-weak);
46
+ border-radius: 4px;
47
+ }
48
+ .ConsolePanel_filterButtonText__db6kuu8 {
49
+ font-size: 0.8125rem;
50
+ line-height: 1.125rem;
51
+ font-weight: var(--seed-font-weight-medium);
52
+ color: var(--seed-color-fg-neutral);
53
+ }
54
+ .ConsolePanel_filterDropdown__db6kuu9 {
55
+ position: absolute;
56
+ top: 100%;
57
+ left: 0;
58
+ margin-top: 4px;
59
+ background-color: var(--seed-color-bg-layer-default);
60
+ border-width: 1px;
61
+ border-color: var(--seed-color-stroke-neutral-subtle);
62
+ border-style: solid;
63
+ border-radius: 8px;
64
+ padding: 4px 0;
65
+ z-index: 100;
66
+ min-width: 90px;
67
+ }
68
+ .ConsolePanel_filterOption__db6kuua {
69
+ display: flex;
70
+ flex-direction: row;
71
+ align-items: center;
72
+ gap: 4px;
73
+ padding: 8px 12px;
74
+ }
75
+ .ConsolePanel_filterCheckbox__db6kuub {
76
+ font-size: 0.8125rem;
77
+ line-height: 1.125rem;
78
+ font-weight: var(--seed-font-weight-medium);
79
+ width: 16px;
80
+ }
81
+ .ConsolePanel_filterCheckbox_level_log__db6kuuc {
82
+ color: var(--seed-color-palette-green-600);
83
+ }
84
+ .ConsolePanel_filterCheckbox_level_info__db6kuud {
85
+ color: var(--seed-color-palette-blue-600);
86
+ }
87
+ .ConsolePanel_filterCheckbox_level_warn__db6kuue {
88
+ color: var(--seed-color-palette-yellow-600);
89
+ }
90
+ .ConsolePanel_filterCheckbox_level_error__db6kuuf {
91
+ color: var(--seed-color-palette-red-600);
92
+ }
93
+ .ConsolePanel_filterLabel__db6kuug {
94
+ font-size: 0.8125rem;
95
+ line-height: 1.125rem;
96
+ font-weight: var(--seed-font-weight-medium);
97
+ }
98
+ .ConsolePanel_filterLabel_level_log__db6kuuh {
99
+ color: var(--seed-color-palette-green-600);
100
+ }
101
+ .ConsolePanel_filterLabel_level_info__db6kuui {
102
+ color: var(--seed-color-palette-blue-600);
103
+ }
104
+ .ConsolePanel_filterLabel_level_warn__db6kuuj {
105
+ color: var(--seed-color-palette-yellow-600);
106
+ }
107
+ .ConsolePanel_filterLabel_level_error__db6kuuk {
108
+ color: var(--seed-color-palette-red-600);
109
+ }
110
+ .ConsolePanel_searchWrapper__db6kuul {
111
+ display: flex;
112
+ flex-direction: row;
113
+ align-items: center;
114
+ flex: 1;
115
+ margin-left: 8px;
116
+ margin-right: 8px;
117
+ border-bottom-width: 1px;
118
+ border-bottom-color: var(--seed-color-stroke-neutral-subtle);
119
+ border-bottom-style: solid;
120
+ gap: 8px;
121
+ }
122
+ .ConsolePanel_searchPrompt__db6kuum {
123
+ font-size: 1.125rem;
124
+ line-height: 1.5rem;
125
+ font-weight: var(--seed-font-weight-medium);
126
+ color: var(--seed-color-fg-placeholder);
127
+ }
128
+ .ConsolePanel_searchInput__db6kuun {
129
+ flex: 1;
130
+ font-size: 0.8125rem;
131
+ line-height: 1.125rem;
132
+ font-weight: var(--seed-font-weight-regular);
133
+ color: var(--seed-color-fg-neutral);
134
+ caret-color: var(--seed-color-palette-green-600);
135
+ }
136
+ .ConsolePanel_clearButton__db6kuuo {
137
+ padding: 3px 6px;
138
+ background-color: var(--seed-color-bg-neutral-weak);
139
+ border-radius: 4px;
140
+ }
141
+ .ConsolePanel_clearButtonText__db6kuup {
142
+ font-size: 0.8125rem;
143
+ line-height: 1.125rem;
144
+ font-weight: var(--seed-font-weight-medium);
145
+ color: var(--seed-color-fg-neutral);
146
+ }
147
+ .ConsolePanel_logList__db6kuuq {
148
+ flex: 1;
149
+ padding-top: 0;
150
+ padding-bottom: 0;
151
+ }
152
+ .ConsolePanel_logItem__db6kuur {
153
+ padding: 8px;
154
+ border-bottom-width: 1px;
155
+ border-bottom-color: var(--seed-color-stroke-neutral-weak);
156
+ border-bottom-style: solid;
157
+ }
158
+ .ConsolePanel_logItem_level_warn__db6kuuu {
159
+ background-color: var(--seed-color-palette-yellow-100);
160
+ }
161
+ .ConsolePanel_logItem_level_error__db6kuuv {
162
+ background-color: var(--seed-color-palette-red-100);
163
+ }
164
+ .ConsolePanel_logItemHeader__db6kuuw {
165
+ display: flex;
166
+ flex-direction: row;
167
+ align-items: center;
168
+ margin-bottom: 4px;
169
+ }
170
+ .ConsolePanel_logLevel__db6kuux {
171
+ font-size: 0.75rem;
172
+ line-height: 1rem;
173
+ font-weight: var(--seed-font-weight-bold);
174
+ margin-right: 8px;
175
+ }
176
+ .ConsolePanel_logLevel_level_log__db6kuuy {
177
+ color: var(--seed-color-palette-green-600);
178
+ }
179
+ .ConsolePanel_logLevel_level_info__db6kuuz {
180
+ color: var(--seed-color-palette-blue-600);
181
+ }
182
+ .ConsolePanel_logLevel_level_warn__db6kuu10 {
183
+ color: var(--seed-color-palette-yellow-600);
184
+ }
185
+ .ConsolePanel_logLevel_level_error__db6kuu11 {
186
+ color: var(--seed-color-palette-red-600);
187
+ }
188
+ .ConsolePanel_logTime__db6kuu12 {
189
+ font-size: 0.75rem;
190
+ line-height: 1rem;
191
+ font-weight: var(--seed-font-weight-regular);
192
+ color: var(--seed-color-fg-neutral-subtle);
193
+ }
194
+ .ConsolePanel_toggleIndicator__db6kuu13 {
195
+ font-size: 0.75rem;
196
+ line-height: 1rem;
197
+ font-weight: var(--seed-font-weight-regular);
198
+ color: var(--seed-color-fg-neutral-subtle);
199
+ margin-left: 4px;
200
+ align-self: flex-start;
201
+ }
202
+ .ConsolePanel_logMessage__db6kuu14 {
203
+ font-size: 0.8125rem;
204
+ line-height: 1.125rem;
205
+ font-weight: var(--seed-font-weight-regular);
206
+ color: var(--seed-color-fg-neutral);
207
+ word-break: break-all;
208
+ }
209
+ .ConsolePanel_logArgsContainer__db6kuu15 {
210
+ display: flex;
211
+ flex-direction: row;
212
+ flex-wrap: wrap;
213
+ gap: 8px;
214
+ }
215
+ .ConsolePanel_logArgItem__db6kuu16 {
216
+ font-size: 0.8125rem;
217
+ line-height: 1.125rem;
218
+ font-weight: var(--seed-font-weight-regular);
219
+ }
220
+ .ConsolePanel_argNull__db6kuu17 {
221
+ color: var(--seed-color-fg-neutral-subtle);
222
+ }
223
+ .ConsolePanel_argUndefined__db6kuu18 {
224
+ color: var(--seed-color-fg-neutral-subtle);
225
+ }
226
+ .ConsolePanel_argString__db6kuu19 {
227
+ font-size: 0.8125rem;
228
+ line-height: 1.125rem;
229
+ font-weight: var(--seed-font-weight-regular);
230
+ }
231
+ .ConsolePanel_argString_level_log__db6kuu1a {
232
+ color: var(--seed-color-fg-neutral);
233
+ }
234
+ .ConsolePanel_argString_level_info__db6kuu1b {
235
+ color: var(--seed-color-fg-neutral);
236
+ }
237
+ .ConsolePanel_argString_level_warn__db6kuu1c {
238
+ color: var(--seed-color-palette-yellow-900);
239
+ }
240
+ .ConsolePanel_argString_level_error__db6kuu1d {
241
+ color: var(--seed-color-palette-red-900);
242
+ }
243
+ .ConsolePanel_argPrimitive__db6kuu1e {
244
+ font-size: 0.8125rem;
245
+ line-height: 1.125rem;
246
+ font-weight: var(--seed-font-weight-regular);
247
+ }
248
+ .ConsolePanel_argPrimitive_level_log__db6kuu1f {
249
+ color: var(--seed-color-palette-blue-600);
250
+ }
251
+ .ConsolePanel_argPrimitive_level_info__db6kuu1g {
252
+ color: var(--seed-color-palette-blue-600);
253
+ }
254
+ .ConsolePanel_argPrimitive_level_warn__db6kuu1h {
255
+ color: var(--seed-color-palette-yellow-900);
256
+ }
257
+ .ConsolePanel_argPrimitive_level_error__db6kuu1i {
258
+ color: var(--seed-color-palette-red-900);
259
+ }
260
+ .ConsolePanel_argObject__db6kuu1j {
261
+ display: flex;
262
+ flex-direction: column;
263
+ }
264
+ .ConsolePanel_argObjectHeader__db6kuu1k {
265
+ display: flex;
266
+ flex-direction: row;
267
+ align-items: center;
268
+ gap: 4px;
269
+ }
270
+ .ConsolePanel_argObjectPreview__db6kuu1l {
271
+ font-size: 0.8125rem;
272
+ line-height: 1.125rem;
273
+ font-weight: var(--seed-font-weight-medium);
274
+ color: var(--seed-color-fg-neutral);
275
+ }
276
+ .ConsolePanel_argObjectContent__db6kuu1m {
277
+ margin-top: 4px;
278
+ display: flex;
279
+ flex-direction: column;
280
+ gap: 4px;
281
+ }
282
+ .ConsolePanel_argObjectProperty__db6kuu1n {
283
+ display: flex;
284
+ flex-direction: row;
285
+ align-items: flex-start;
286
+ }
287
+ .ConsolePanel_argObjectKey__db6kuu1o {
288
+ font-size: 0.8125rem;
289
+ line-height: 1.125rem;
290
+ font-weight: var(--seed-font-weight-medium);
291
+ color: var(--seed-color-palette-purple-600);
292
+ }
293
+ .ConsolePanel_argObjectJson__db6kuu1p {
294
+ font-size: 0.8125rem;
295
+ line-height: 1.125rem;
296
+ font-weight: var(--seed-font-weight-regular);
297
+ color: var(--seed-color-fg-neutral);
298
+ }
299
+ .ConsolePanel_fadeBottom__db6kuu1q {
300
+ height: 20px;
301
+ margin-top: -20px;
302
+ z-index: 1;
303
+ background: linear-gradient(to top, var(--seed-color-bg-layer-default), #ffffff00);
304
+ }
305
+ .ConsolePanel_replInputRow__db6kuu1r {
306
+ display: flex;
307
+ flex-direction: row;
308
+ align-items: center;
309
+ gap: 8px;
310
+ padding-top: 0;
311
+ padding-bottom: 8px;
312
+ }
313
+ .ConsolePanel_replPrompt__db6kuu1s {
314
+ font-size: 1.625rem;
315
+ line-height: 2.1875rem;
316
+ font-weight: var(--seed-font-weight-medium);
317
+ color: var(--seed-color-fg-placeholder);
318
+ padding-bottom: 8px;
319
+ }
320
+ .ConsolePanel_replInput__db6kuu1t {
321
+ flex: 1;
322
+ font-size: 1rem;
323
+ line-height: 1.375rem;
324
+ font-weight: var(--seed-font-weight-regular);
325
+ color: var(--seed-color-fg-neutral);
326
+ caret-color: var(--seed-color-palette-green-600);
327
+ padding-bottom: 8px;
328
+ }
329
+ .ConsolePanel_replRunButton__db6kuu1u {
330
+ padding: 4px 10px;
331
+ background-color: var(--seed-color-palette-green-100);
332
+ border-radius: 4px;
333
+ margin-bottom: 8px;
334
+ }
335
+ .ConsolePanel_replRunButtonText__db6kuu1v {
336
+ font-size: 0.8125rem;
337
+ line-height: 1.125rem;
338
+ font-weight: var(--seed-font-weight-medium);
339
+ color: var(--seed-color-palette-green-600);
340
+ }
@@ -1,14 +1,16 @@
1
1
  .FloatingButton_wrapper__1homwpu0 {
2
2
  position: fixed;
3
- right: 16px;
4
- bottom: 84px;
5
3
  z-index: 9999;
6
4
  display: flex;
7
5
  flex-direction: row;
8
6
  align-items: center;
9
7
  gap: 8px;
8
+ overflow: visible;
9
+ transition: transform var(--seed-duration-d4) cubic-bezier(0.4, 0, 0.2, 1);
10
10
  }
11
- .FloatingButton_button__1homwpu2 {
11
+ .FloatingButton_button__1homwpu1 {
12
+ position: relative;
13
+ overflow: hidden;
12
14
  padding-left: 8px;
13
15
  padding-right: 8px;
14
16
  padding-top: 4px;
@@ -22,6 +24,15 @@
22
24
  gap: 2px;
23
25
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
24
26
  }
27
+ .FloatingButton_shineOverlay__1homwpu2 {
28
+ position: absolute;
29
+ top: -50%;
30
+ left: -25%;
31
+ width: 150%;
32
+ height: 200%;
33
+ background-color: rgba(255, 255, 255, 0.2);
34
+ border-radius: 9999px;
35
+ }
25
36
  .FloatingButton_title__1homwpu3 {
26
37
  font-size: 0.875rem;
27
38
  line-height: 1.1875rem;
@@ -37,6 +48,7 @@
37
48
  text-align: center;
38
49
  }
39
50
  .FloatingButton_reloadButton__1homwpu5 {
51
+ overflow: visible;
40
52
  width: 32px;
41
53
  height: 32px;
42
54
  border-radius: 16px;