@yuneta/gobj-ui 7.23.171 → 7.23.173
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/dist/gobj-ui.cjs.js +131 -347
- package/dist/gobj-ui.es.js +132 -348
- package/package.json +3 -3
- package/src/yui_dev.js +162 -363
- package/src/dev_machine_trace.js +0 -116
- package/src/dev_machine_trace.test.js +0 -123
package/src/yui_dev.js
CHANGED
|
@@ -13,6 +13,13 @@ import {
|
|
|
13
13
|
kw_get_local_storage_value,
|
|
14
14
|
kw_set_local_storage_value,
|
|
15
15
|
gobj_write_attr,
|
|
16
|
+
gobj_command,
|
|
17
|
+
gobj_global_trace_level,
|
|
18
|
+
gobj_global_trace_no_level,
|
|
19
|
+
gobj_get_gclass_trace_level2,
|
|
20
|
+
gclass_find_by_name,
|
|
21
|
+
trace_level_t,
|
|
22
|
+
log_error,
|
|
16
23
|
gobj_create_service,
|
|
17
24
|
gobj_find_service,
|
|
18
25
|
gobj_start,
|
|
@@ -21,16 +28,6 @@ import {
|
|
|
21
28
|
gobj_set_trace_machine_format,
|
|
22
29
|
} from "@yuneta/gobj-js";
|
|
23
30
|
|
|
24
|
-
/* A NAMESPACE import, deliberately, for one optional API.
|
|
25
|
-
*
|
|
26
|
-
* `set_console_log_filter` arrived in gobj-js 7.13.6, and a NAMED import of
|
|
27
|
-
* an export the installed copy does not have is a hard module-load error --
|
|
28
|
-
* it would take the whole app down instead of degrading. Read off the
|
|
29
|
-
* namespace, a missing export is plain `undefined` and can be tested for. */
|
|
30
|
-
import * as gobj_js from "@yuneta/gobj-js";
|
|
31
|
-
|
|
32
|
-
import {log_signature, log_is_periodic} from "./dev_machine_trace.js";
|
|
33
|
-
|
|
34
31
|
import i18next, {t} from 'i18next';
|
|
35
32
|
|
|
36
33
|
/***********************************************************************
|
|
@@ -41,11 +38,8 @@ import i18next, {t} from 'i18next';
|
|
|
41
38
|
* losing history. Reopening the window repaints the buffer.
|
|
42
39
|
***********************************************************************/
|
|
43
40
|
const TRAFFIC_MAX = 600; // capped history
|
|
44
|
-
const PERIODIC_THRESHOLD = 5; // a signature seen >= N times reads as recurring
|
|
45
|
-
const PERIODIC_RE = /PERIODIC|TIMEOUT|HEARTBEAT|PING/i;
|
|
46
41
|
|
|
47
|
-
let TRAFFIC_LOG = []; // [{title,event,command,
|
|
48
|
-
let TRAFFIC_COUNTS = new Map(); // signature -> occurrences (for periodic detection)
|
|
42
|
+
let TRAFFIC_LOG = []; // [{title,event,command,dir,size,ts,kw,jn,hay,$node}]
|
|
49
43
|
let SEARCH_TEXT = ""; // session-only free-text filter (not persisted)
|
|
50
44
|
|
|
51
45
|
/* Running totals of framework errors/warnings seen since page load (or the
|
|
@@ -61,8 +55,18 @@ const TRAFFIC_TS_FIELDS = {
|
|
|
61
55
|
"from_t": 1, "to_t": 1, "from_tm": 1, "to_tm": 1, "time": 1,
|
|
62
56
|
};
|
|
63
57
|
|
|
64
|
-
/* Trace toggles
|
|
65
|
-
|
|
58
|
+
/* Trace toggles.
|
|
59
|
+
*
|
|
60
|
+
* A chip does ONE thing: it turns trace bits of the runtime on or off
|
|
61
|
+
* through the yuno's trace commands -- the C kernel's, same names -- and
|
|
62
|
+
* the yuno persists them (`trace_levels` / `no_trace_levels`). Whether a
|
|
63
|
+
* message is traced is decided by the gobj that emits it, never by this
|
|
64
|
+
* window reading messages. The chip's state is READ from the runtime, so
|
|
65
|
+
* it cannot disagree with what is traced.
|
|
66
|
+
*
|
|
67
|
+
* [key, label i18n key, title i18n key, state(), toggle()]
|
|
68
|
+
*
|
|
69
|
+
* `data-label` carries the i18n KEY and not the text: the chips are
|
|
66
70
|
* repainted from it by `refresh_dev_chrome()` on every toggle, so a
|
|
67
71
|
* label translated once at build time would come back in English at
|
|
68
72
|
* the first click. */
|
|
@@ -70,36 +74,48 @@ const TRAFFIC_TS_FIELDS = {
|
|
|
70
74
|
* `validate-locales`: the table below and the `grp` / `mk_view` /
|
|
71
75
|
* `mk_expand` / `mk_dir` / `mk_out` helpers pass their key as a
|
|
72
76
|
* VARIABLE, and `OUT_TITLES` holds three more in a lookup table --
|
|
73
|
-
* so
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* consumer must define, kept here so it can be copied:
|
|
77
|
+
* so a scan of `t("…")` sees none of them and reports OK with the
|
|
78
|
+
* whole window in English. The full set a consumer must define,
|
|
79
|
+
* kept here so it can be copied:
|
|
77
80
|
*
|
|
78
81
|
* automata, both, browser console only, clear,
|
|
79
82
|
* clear captured traffic, compact, console, copied, copy,
|
|
80
83
|
* copy visible traffic to clipboard, creation, data, detailed,
|
|
81
84
|
* dev window and browser console, dev window only, developer,
|
|
82
|
-
* errors, expand, expanded, filter events / payload, find,
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* name only, no poll, outgoing, output, periodic, schema, show,
|
|
85
|
+
* errors, expand, expanded, filter events / payload, find, i18n,
|
|
86
|
+
* i18next debug output, incoming, log, machine trace shape,
|
|
87
|
+
* metadata, name only, outgoing, output, periodic, schema, show,
|
|
86
88
|
* show this section in the expanded view, simple mach,
|
|
87
|
-
* start / stop, subscriptions,
|
|
88
|
-
*
|
|
89
|
+
* start / stop, subscriptions,
|
|
90
|
+
* trace every event of every automaton,
|
|
91
|
+
* trace subscriptions and publications,
|
|
92
|
+
* trace the creation and destruction of gobjs,
|
|
93
|
+
* trace the messages to and from the backend,
|
|
94
|
+
* trace the periodic timer event,
|
|
95
|
+
* trace the start and stop of gobjs,
|
|
96
|
+
* traces, traffic, view, window, yuno monitor
|
|
89
97
|
*
|
|
90
98
|
* wattyzer and the yunovatios GUIs carry them; check a new consumer
|
|
91
99
|
* against this list, and confirm it by DUMPING the window. */
|
|
92
100
|
const TRACE_DEFS = [
|
|
93
|
-
["
|
|
94
|
-
|
|
95
|
-
["
|
|
96
|
-
|
|
97
|
-
["
|
|
98
|
-
|
|
99
|
-
["
|
|
101
|
+
["automata", "automata", "trace every event of every automaton",
|
|
102
|
+
automata_state, toggle_automata],
|
|
103
|
+
["creation", "creation", "trace the creation and destruction of gobjs",
|
|
104
|
+
() => global_bit(trace_level_t.TRACE_CREATE_DELETE), () => toggle_global("create_delete")],
|
|
105
|
+
["start_stop", "start / stop", "trace the start and stop of gobjs",
|
|
106
|
+
() => global_bit(trace_level_t.TRACE_START_STOP), () => toggle_global("start_stop")],
|
|
107
|
+
["subscriptions", "subscriptions", "trace subscriptions and publications",
|
|
108
|
+
() => global_bit(trace_level_t.TRACE_SUBSCRIPTIONS), () => toggle_global("subscriptions")],
|
|
109
|
+
["i18n", "i18n", "i18next debug output",
|
|
110
|
+
i18n_state, toggle_i18n],
|
|
111
|
+
["traffic", "traffic", "trace the messages to and from the backend",
|
|
112
|
+
traffic_state, toggle_traffic],
|
|
113
|
+
["periodic", "periodic", "trace the periodic timer event",
|
|
114
|
+
periodic_state, toggle_periodic],
|
|
100
115
|
];
|
|
101
116
|
|
|
102
117
|
|
|
118
|
+
|
|
103
119
|
/******************************
|
|
104
120
|
* Small helpers
|
|
105
121
|
******************************/
|
|
@@ -201,17 +217,6 @@ function dev_view()
|
|
|
201
217
|
return (v === "compact" || v === "name" || v === "full") ? v : "detailed";
|
|
202
218
|
}
|
|
203
219
|
|
|
204
|
-
/* ON by default. The machine trace is the reason this window
|
|
205
|
-
* exists, and a yuno with one timer emits two lines a second for
|
|
206
|
-
* ever: leaving the filter off meant the first thing anybody saw
|
|
207
|
-
* after enabling Automata was a wall of EV_TIMEOUT with their own
|
|
208
|
-
* transitions somewhere inside it. The chip turns it back off.
|
|
209
|
-
*
|
|
210
|
-
* A CONSTANT, and not the literal in two places: the reader and the
|
|
211
|
-
* toggle must agree on what "unset" means, or the first click on the
|
|
212
|
-
* chip writes the value it already had and appears to do nothing. */
|
|
213
|
-
const HIDE_PERIODIC_DEFAULT = 1;
|
|
214
|
-
|
|
215
220
|
/* Which SHAPE the machine trace is written in — the two the C kernel
|
|
216
221
|
* offers, and the chip that swaps them:
|
|
217
222
|
*
|
|
@@ -220,7 +225,7 @@ const HIDE_PERIODIC_DEFAULT = 1;
|
|
|
220
225
|
* change, and the `<- … ret: N` return
|
|
221
226
|
*
|
|
222
227
|
* 1 because that is what the C kernel defaults to, so a browser yuno and
|
|
223
|
-
* a node read alike.
|
|
228
|
+
* a node read alike. A CONSTANT and not a
|
|
224
229
|
* literal in each of the three places that read it (the chip, the chrome
|
|
225
230
|
* and start up): they have to agree on what "unset" means, or the chip
|
|
226
231
|
* is born showing the wrong state and its first click does nothing. */
|
|
@@ -241,11 +246,6 @@ function dev_simple_mach()
|
|
|
241
246
|
return dev_num(SIMPLE_MACH_KEY, SIMPLE_MACH_DEFAULT) ? 1 : 0;
|
|
242
247
|
}
|
|
243
248
|
|
|
244
|
-
function dev_hide_periodic()
|
|
245
|
-
{
|
|
246
|
-
return dev_num("dev_hide_periodic", HIDE_PERIODIC_DEFAULT) ? true : false;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
249
|
/* Where dev output (traffic + all logs + automata) is routed:
|
|
250
250
|
* "window" → dev window only (browser console silenced framework-wide)
|
|
251
251
|
* "console" → browser console only (nothing appended to the window)
|
|
@@ -259,46 +259,12 @@ function dev_route()
|
|
|
259
259
|
}
|
|
260
260
|
|
|
261
261
|
/* Push the current route's console decision down to gobj-js. Called from
|
|
262
|
-
* apply_dev_traces (startup)
|
|
263
|
-
* whenever a filter that the console also obeys is toggled. */
|
|
262
|
+
* apply_dev_traces (startup) and whenever the Output selector changes. */
|
|
264
263
|
function apply_console_route()
|
|
265
264
|
{
|
|
266
265
|
set_console_log_enabled(dev_route() !== "window");
|
|
267
|
-
|
|
268
|
-
/* ONE rule, TWO sinks.
|
|
269
|
-
*
|
|
270
|
-
* The window's Periodic filter used to end at the window, so with the
|
|
271
|
-
* Output on "Both" the timers were gone from the panel and still
|
|
272
|
-
* arriving in the browser console, two lines a second — the same flood,
|
|
273
|
-
* one pane over. It cannot be fixed from this side alone: gobj-js writes
|
|
274
|
-
* the console line BEFORE it calls the log sink, so nothing here can
|
|
275
|
-
* un-print it. It hands out a say instead (`set_console_log_filter`,
|
|
276
|
-
* gobj-js >= 7.13.6), and this is the same predicate `entry_hidden()`
|
|
277
|
-
* uses, so the two panes cannot disagree about what is noise.
|
|
278
|
-
*
|
|
279
|
-
* Feature-detected rather than required: against an older gobj-js the
|
|
280
|
-
* window still filters and the console still floods, exactly as before,
|
|
281
|
-
* and the reason is logged once instead of failing. */
|
|
282
|
-
if(typeof gobj_js.set_console_log_filter === "function") {
|
|
283
|
-
gobj_js.set_console_log_filter((level, msg) => {
|
|
284
|
-
if(!dev_hide_periodic()) {
|
|
285
|
-
return true;
|
|
286
|
-
}
|
|
287
|
-
return !log_is_periodic(level, is_string(msg) ? msg : String(msg));
|
|
288
|
-
});
|
|
289
|
-
} else if(!__console_filter_warned__) {
|
|
290
|
-
__console_filter_warned__ = true;
|
|
291
|
-
console.warn(
|
|
292
|
-
"yui_dev: gobj-js has no set_console_log_filter (needs >= 7.13.6): " +
|
|
293
|
-
"the Periodic filter applies to this window only, not to the console"
|
|
294
|
-
);
|
|
295
|
-
}
|
|
296
266
|
}
|
|
297
267
|
|
|
298
|
-
/* The warning above is worth saying, and worth saying ONCE: this runs on
|
|
299
|
-
* every Output change and every filter toggle. */
|
|
300
|
-
let __console_filter_warned__ = false;
|
|
301
|
-
|
|
302
268
|
/* Emit one inter-event traffic line to the browser console (routes
|
|
303
269
|
* "console" and "both"). gobj-js only knows about framework logs, not this
|
|
304
270
|
* traffic feed, so the console mirror is produced here. */
|
|
@@ -315,20 +281,6 @@ function console_traffic(title, jn, direction, size)
|
|
|
315
281
|
);
|
|
316
282
|
}
|
|
317
283
|
|
|
318
|
-
function dev_muted()
|
|
319
|
-
{
|
|
320
|
-
let a = kw_get_local_storage_value("dev_muted_events", [], false);
|
|
321
|
-
if(!Array.isArray(a)) {
|
|
322
|
-
a = [];
|
|
323
|
-
}
|
|
324
|
-
return new Set(a);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
function dev_set_muted(set)
|
|
328
|
-
{
|
|
329
|
-
kw_set_local_storage_value("dev_muted_events", Array.from(set));
|
|
330
|
-
}
|
|
331
|
-
|
|
332
284
|
function set_view(v)
|
|
333
285
|
{
|
|
334
286
|
kw_set_local_storage_value("dev_view_mode", v);
|
|
@@ -351,64 +303,21 @@ function toggle_pref(key, def)
|
|
|
351
303
|
{
|
|
352
304
|
let v = dev_num(key, def) ? 0 : 1;
|
|
353
305
|
kw_set_local_storage_value(key, v);
|
|
354
|
-
/* The console filter closes over dev_hide_periodic(), which reads the
|
|
355
|
-
* stored value on each call, so it follows this on its own. Re-pushed
|
|
356
|
-
* anyway: a filter installed before this module reached apply_dev_traces
|
|
357
|
-
* is the difference between the console obeying the chip and ignoring
|
|
358
|
-
* it, and one assignment is cheaper than that class of bug. */
|
|
359
|
-
apply_console_route();
|
|
360
306
|
rerender_all();
|
|
361
307
|
refresh_dev_chrome();
|
|
362
308
|
}
|
|
363
309
|
|
|
364
|
-
function mute_signature(sig)
|
|
365
|
-
{
|
|
366
|
-
let set = dev_muted();
|
|
367
|
-
set.add(sig);
|
|
368
|
-
dev_set_muted(set);
|
|
369
|
-
rerender_all();
|
|
370
|
-
refresh_dev_chrome();
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
function unmute_signature(sig)
|
|
374
|
-
{
|
|
375
|
-
let set = dev_muted();
|
|
376
|
-
set.delete(sig);
|
|
377
|
-
dev_set_muted(set);
|
|
378
|
-
rerender_all();
|
|
379
|
-
refresh_dev_chrome();
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
|
|
383
310
|
/******************************
|
|
384
311
|
* Filtering
|
|
385
312
|
******************************/
|
|
386
313
|
|
|
387
314
|
|
|
388
|
-
/* Signature identifies a "kind" of message. Command answers share
|
|
389
|
-
* the generic EV_MT_COMMAND event, so fold the command in to tell
|
|
390
|
-
* a get-stats poll apart from a user action. */
|
|
391
|
-
function traffic_signature(event, command)
|
|
392
|
-
{
|
|
393
|
-
return command ? (event + " · " + command) : event;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
function traffic_is_periodic(sig)
|
|
397
|
-
{
|
|
398
|
-
if(PERIODIC_RE.test(sig)) {
|
|
399
|
-
return true;
|
|
400
|
-
}
|
|
401
|
-
return (TRAFFIC_COUNTS.get(sig) || 0) >= PERIODIC_THRESHOLD;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
315
|
function build_filter_ctx()
|
|
405
316
|
{
|
|
406
317
|
return {
|
|
407
318
|
out: dev_num("dev_filter_out", 1),
|
|
408
319
|
inc: dev_num("dev_filter_in", 1),
|
|
409
320
|
err: dev_num("dev_filter_err", 1),
|
|
410
|
-
muted: dev_muted(),
|
|
411
|
-
hide_periodic: dev_hide_periodic(),
|
|
412
321
|
search: SEARCH_TEXT,
|
|
413
322
|
};
|
|
414
323
|
}
|
|
@@ -418,20 +327,9 @@ function entry_hidden(e, ctx)
|
|
|
418
327
|
if(e.kind === "log") {
|
|
419
328
|
/* Mirrored console logs respect the search box only — not the
|
|
420
329
|
* in/out/err traffic filters, which are about DIRECTION and a
|
|
421
|
-
* log has none.
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
* Automata is on, the machine trace is what floods this
|
|
425
|
-
* window, and every one of those lines arrives here as a log.
|
|
426
|
-
* It applies to a machine TRANSITION only, and never above
|
|
427
|
-
* debug level — see log_is_periodic(). By NAME and not by
|
|
428
|
-
* count, unlike the traffic half below: a busy FSM crosses
|
|
429
|
-
* the recurrence threshold on almost every event within
|
|
430
|
-
* seconds, so counting here would empty the window of the
|
|
431
|
-
* very transitions somebody turned Automata on to read. */
|
|
432
|
-
if(ctx.hide_periodic && e.periodic) {
|
|
433
|
-
return true;
|
|
434
|
-
}
|
|
330
|
+
* log has none. What is traced at all is the runtime's trace
|
|
331
|
+
* levels, set by the chips: this window never reads a message
|
|
332
|
+
* to decide whether to show it. */
|
|
435
333
|
return !!(ctx.search && e.hay.indexOf(ctx.search) < 0);
|
|
436
334
|
}
|
|
437
335
|
if(e.dir === 1 && !ctx.out) {
|
|
@@ -443,12 +341,6 @@ function entry_hidden(e, ctx)
|
|
|
443
341
|
if(e.dir === 3 && !ctx.err) {
|
|
444
342
|
return true;
|
|
445
343
|
}
|
|
446
|
-
if(ctx.muted.has(e.sig)) {
|
|
447
|
-
return true;
|
|
448
|
-
}
|
|
449
|
-
if(ctx.hide_periodic && traffic_is_periodic(e.sig)) {
|
|
450
|
-
return true;
|
|
451
|
-
}
|
|
452
344
|
if(ctx.search && e.hay.indexOf(ctx.search) < 0) {
|
|
453
345
|
return true;
|
|
454
346
|
}
|
|
@@ -481,11 +373,6 @@ function ensure_dev_style()
|
|
|
481
373
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
482
374
|
}
|
|
483
375
|
.YDEV_LOG { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 6px 10px; }
|
|
484
|
-
.YDEV_MUTED {
|
|
485
|
-
display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
|
|
486
|
-
padding: 4px 10px; border-bottom: 1px solid rgba(0,0,0,0.08); font-size: 12px;
|
|
487
|
-
}
|
|
488
|
-
.YDEV_MUTED:empty { display: none; }
|
|
489
376
|
.YDEV_STATS {
|
|
490
377
|
flex: 0 0 auto; display: flex; flex-wrap: wrap; gap: 14px;
|
|
491
378
|
padding: 6px 10px; border-top: 1px solid rgba(0,0,0,0.1);
|
|
@@ -517,7 +404,6 @@ function ensure_dev_style()
|
|
|
517
404
|
.YDEV_CHIP.s-in.is-active { background: rgba(5,150,105,0.16); border-color: #059669; color: #059669; }
|
|
518
405
|
.YDEV_CHIP.s-err.is-active { background: rgba(220,38,38,0.16); border-color: #dc2626; color: #dc2626; }
|
|
519
406
|
.YDEV_CHIP[data-dir]:not(.is-active) { opacity: 0.4; text-decoration: line-through; }
|
|
520
|
-
.YDEV_CHIP[data-toggle="periodic"].is-active { background: rgba(217,119,6,0.16); border-color: #d97706; color: #b45309; font-weight: 600; }
|
|
521
407
|
.YDEV_SEG { display: inline-flex; border: 1px solid rgba(0,0,0,0.18); border-radius: 7px; overflow: hidden; }
|
|
522
408
|
.YDEV_SEG_BTN {
|
|
523
409
|
font: inherit; font-size: 12px; padding: 4px 10px; border: 0;
|
|
@@ -531,12 +417,6 @@ function ensure_dev_style()
|
|
|
531
417
|
border: 1px solid rgba(0,0,0,0.18); border-radius: 7px;
|
|
532
418
|
background: transparent; color: inherit;
|
|
533
419
|
}
|
|
534
|
-
.YDEV_MUTED_CHIP {
|
|
535
|
-
font: inherit; font-family: "DejaVu Sans Mono", monospace; font-size: 12px;
|
|
536
|
-
display: inline-flex; align-items: center; gap: 6px; padding: 2px 8px;
|
|
537
|
-
border: 1px solid rgba(217,119,6,0.5); border-radius: 999px;
|
|
538
|
-
background: rgba(217,119,6,0.12); color: #b45309; cursor: pointer;
|
|
539
|
-
}
|
|
540
420
|
.YDEV_STAT.s-out { color: #2563eb; } .YDEV_STAT.s-in { color: #059669; } .YDEV_STAT.s-err { color: #dc2626; }
|
|
541
421
|
.YDEV_STAT.s-warn { color: #d97706; }
|
|
542
422
|
.YDEV_STAT.is-strong { font-weight: 700; }
|
|
@@ -564,10 +444,7 @@ function ensure_dev_style()
|
|
|
564
444
|
.dir-err .TRAFFIC_ARROW, .dir-err .TRAFFIC_EVENT { color: #dc2626; }
|
|
565
445
|
.TRAFFIC_SUMMARY { opacity: 0.6; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1 1 auto; min-width: 0; }
|
|
566
446
|
.TRAFFIC_META { margin-left: auto; opacity: 0.6; font-size: 11px; white-space: nowrap; }
|
|
567
|
-
.
|
|
568
|
-
.TRAFFIC_ENTRY:hover .TRAFFIC_MUTE, .TRAFFIC_LINE:hover .TRAFFIC_MUTE, .TRAFFIC_NAME:hover .TRAFFIC_MUTE { opacity: 0.5; }
|
|
569
|
-
.TRAFFIC_MUTE:hover { opacity: 1 !important; color: #d97706; }
|
|
570
|
-
.TRAFFIC_KW { margin: 2px 0 0 16px; }
|
|
447
|
+
.TRAFFIC_ENTRY:hover .TRAFFIC_KW { margin: 2px 0 0 16px; }
|
|
571
448
|
.TRAFFIC_FULL { margin: 4px 0 0 16px; padding: 6px 8px; font-family: monospace; font-size: 11px; line-height: 1.4; white-space: pre-wrap; word-break: break-word; background: rgba(0,0,0,0.04); border-radius: 4px; overflow-x: auto; }
|
|
572
449
|
.TRAFFIC_ROW { display: flex; gap: 6px; align-items: baseline; }
|
|
573
450
|
.TRAFFIC_BULLET { opacity: 0.45; flex: 0 0 auto; }
|
|
@@ -611,9 +488,7 @@ details.TRAFFIC_NEST > summary::-webkit-details-marker { display: none; }
|
|
|
611
488
|
:root[data-theme="dark"] .TRAFFIC_VAL.t-bool, :root[data-theme="dark"] .TRAFFIC_VAL.t-null { color: #c084fc; }
|
|
612
489
|
:root[data-theme="dark"] .YDEV_CHIP.is-active { background: rgba(96,165,250,0.2); border-color: #60a5fa; color: #93c5fd; }
|
|
613
490
|
:root[data-theme="dark"] .YDEV_SEG_BTN.is-active { background: #2563eb; color: #fff; }
|
|
614
|
-
:root[data-theme="dark"]
|
|
615
|
-
:root[data-theme="dark"] .YDEV_MUTED_CHIP { border-color: rgba(245,158,11,0.5); background: rgba(245,158,11,0.16); color: #fbbf24; }
|
|
616
|
-
`;
|
|
491
|
+
:root[data-theme="dark"] `;
|
|
617
492
|
let $style = document.createElement('style');
|
|
618
493
|
$style.id = 'yui-dev-style';
|
|
619
494
|
$style.textContent = css;
|
|
@@ -727,21 +602,6 @@ function traffic_bullets(obj)
|
|
|
727
602
|
******************************/
|
|
728
603
|
|
|
729
604
|
|
|
730
|
-
/* A small mute affordance that silences this signature (persistent). */
|
|
731
|
-
function mute_button(sig)
|
|
732
|
-
{
|
|
733
|
-
/* `t('mute this message')` and not `'Mute ' + sig`: a composed
|
|
734
|
-
* title is no i18n key, and the row already says which message. */
|
|
735
|
-
return ['button', {class: 'TRAFFIC_MUTE', type: 'button',
|
|
736
|
-
title: t('mute this message'), 'data-i18n-title': 'mute this message'}, '⊘', {
|
|
737
|
-
click: (ev) => {
|
|
738
|
-
ev.stopPropagation();
|
|
739
|
-
ev.preventDefault();
|
|
740
|
-
mute_signature(sig);
|
|
741
|
-
}
|
|
742
|
-
}];
|
|
743
|
-
}
|
|
744
|
-
|
|
745
605
|
function event_spans(e)
|
|
746
606
|
{
|
|
747
607
|
let spans = [['span', {class: 'TRAFFIC_ARROW'}, dir_arrow(e.dir)],
|
|
@@ -786,7 +646,6 @@ function compact_summary(kw)
|
|
|
786
646
|
function render_detailed(e)
|
|
787
647
|
{
|
|
788
648
|
let head = event_spans(e);
|
|
789
|
-
head.push(mute_button(e.sig));
|
|
790
649
|
head.push(['span', {class: 'TRAFFIC_META'}, `${traffic_size(e.size)} · ${e.ts}`]);
|
|
791
650
|
|
|
792
651
|
let children = [['div', {class: 'TRAFFIC_HEADER'}, head]];
|
|
@@ -843,7 +702,6 @@ function full_sections(payload)
|
|
|
843
702
|
function render_full(e)
|
|
844
703
|
{
|
|
845
704
|
let head = event_spans(e);
|
|
846
|
-
head.push(mute_button(e.sig));
|
|
847
705
|
head.push(['span', {class: 'TRAFFIC_META'}, `${traffic_size(e.size)} · ${e.ts}`]);
|
|
848
706
|
|
|
849
707
|
let payload = full_sections(e.kw ? e.kw : e.jn);
|
|
@@ -864,7 +722,6 @@ function render_compact(e)
|
|
|
864
722
|
{
|
|
865
723
|
let kids = event_spans(e);
|
|
866
724
|
kids.push(['span', {class: 'TRAFFIC_SUMMARY'}, compact_summary(e.kw)]);
|
|
867
|
-
kids.push(mute_button(e.sig));
|
|
868
725
|
kids.push(['span', {class: 'TRAFFIC_META'}, `${traffic_size(e.size)} · ${e.ts}`]);
|
|
869
726
|
return createElement2(['div', {class: 'TRAFFIC_LINE ' + dir_class(e.dir), title: e.title}, kids]);
|
|
870
727
|
}
|
|
@@ -872,7 +729,6 @@ function render_compact(e)
|
|
|
872
729
|
function render_name(e)
|
|
873
730
|
{
|
|
874
731
|
let kids = event_spans(e);
|
|
875
|
-
kids.push(mute_button(e.sig));
|
|
876
732
|
kids.push(['span', {class: 'TRAFFIC_META'}, e.ts]);
|
|
877
733
|
return createElement2(['div', {class: 'TRAFFIC_NAME ' + dir_class(e.dir), title: e.title}, kids]);
|
|
878
734
|
}
|
|
@@ -932,7 +788,6 @@ function render_entry(e)
|
|
|
932
788
|
function clear_traffic()
|
|
933
789
|
{
|
|
934
790
|
TRAFFIC_LOG.length = 0;
|
|
935
|
-
TRAFFIC_COUNTS.clear();
|
|
936
791
|
LOG_ERR_COUNT = 0;
|
|
937
792
|
LOG_WARN_COUNT = 0;
|
|
938
793
|
let logger = document.getElementById('developer-traffic-logger');
|
|
@@ -1116,7 +971,6 @@ function info_traffic(title, msg, direction, size)
|
|
|
1116
971
|
let event = (jn && jn.event) ? String(jn.event) : "(no event)";
|
|
1117
972
|
let kw = (jn && jn.kw && typeof jn.kw === "object") ? jn.kw : null;
|
|
1118
973
|
let command = (kw && typeof kw.command === "string") ? kw.command : "";
|
|
1119
|
-
let sig = traffic_signature(event, command);
|
|
1120
974
|
|
|
1121
975
|
let hay = "";
|
|
1122
976
|
try {
|
|
@@ -1126,35 +980,21 @@ function info_traffic(title, msg, direction, size)
|
|
|
1126
980
|
}
|
|
1127
981
|
|
|
1128
982
|
let entry = {
|
|
1129
|
-
title: title || "", event: event, command: command,
|
|
983
|
+
title: title || "", event: event, command: command,
|
|
1130
984
|
dir: direction, size: size, ts: traffic_now(),
|
|
1131
985
|
kw: kw, jn: jn, hay: hay, $node: null,
|
|
1132
986
|
};
|
|
1133
987
|
|
|
1134
988
|
TRAFFIC_LOG.push(entry);
|
|
1135
|
-
TRAFFIC_COUNTS.set(sig, (TRAFFIC_COUNTS.get(sig) || 0) + 1);
|
|
1136
|
-
|
|
1137
|
-
/* When a signature just crosses the "recurring" threshold and
|
|
1138
|
-
* the periodic filter is on, its earlier entries must disappear
|
|
1139
|
-
* too — a full repaint is the correct, simple answer. */
|
|
1140
|
-
let crossed = dev_hide_periodic() && (TRAFFIC_COUNTS.get(sig) === PERIODIC_THRESHOLD);
|
|
1141
989
|
|
|
1142
990
|
if(TRAFFIC_LOG.length > TRAFFIC_MAX) {
|
|
1143
991
|
let old = TRAFFIC_LOG.shift();
|
|
1144
|
-
let c = (TRAFFIC_COUNTS.get(old.sig) || 0) - 1;
|
|
1145
|
-
if(c <= 0) {
|
|
1146
|
-
TRAFFIC_COUNTS.delete(old.sig);
|
|
1147
|
-
} else {
|
|
1148
|
-
TRAFFIC_COUNTS.set(old.sig, c);
|
|
1149
|
-
}
|
|
1150
992
|
if(old.$node && old.$node.parentNode) {
|
|
1151
993
|
old.$node.parentNode.removeChild(old.$node);
|
|
1152
994
|
}
|
|
1153
995
|
}
|
|
1154
996
|
|
|
1155
|
-
if(
|
|
1156
|
-
rerender_all();
|
|
1157
|
-
} else if(!entry_hidden(entry, build_filter_ctx())) {
|
|
997
|
+
if(!entry_hidden(entry, build_filter_ctx())) {
|
|
1158
998
|
let node = render_entry(entry);
|
|
1159
999
|
entry.$node = node;
|
|
1160
1000
|
/* Drop the "no traffic yet" placeholder before the first row. */
|
|
@@ -1221,28 +1061,14 @@ function info_log(level, msg, hora)
|
|
|
1221
1061
|
} else {
|
|
1222
1062
|
text = is_string(msg) ? msg : String(msg);
|
|
1223
1063
|
}
|
|
1224
|
-
/* A machine line is signed by its EVENT, not by "log:debug":
|
|
1225
|
-
* that is what makes a hundred EV_TIMEOUTs ONE recurring
|
|
1226
|
-
* thing the filter and the counter can see, instead of a
|
|
1227
|
-
* hundred anonymous debug lines they cannot tell apart. */
|
|
1228
1064
|
let entry = {
|
|
1229
1065
|
kind: "log", level: lvl, text: text,
|
|
1230
1066
|
dir: 0, size: 0, ts: traffic_now(),
|
|
1231
|
-
sig: log_signature(lvl, text),
|
|
1232
|
-
periodic: log_is_periodic(lvl, text),
|
|
1233
1067
|
hay: (lvl + " " + text).toLowerCase(), $node: null,
|
|
1234
1068
|
};
|
|
1235
1069
|
TRAFFIC_LOG.push(entry);
|
|
1236
1070
|
if(TRAFFIC_LOG.length > TRAFFIC_MAX) {
|
|
1237
1071
|
let old = TRAFFIC_LOG.shift();
|
|
1238
|
-
if(old.kind !== "log") {
|
|
1239
|
-
let c = (TRAFFIC_COUNTS.get(old.sig) || 0) - 1;
|
|
1240
|
-
if(c <= 0) {
|
|
1241
|
-
TRAFFIC_COUNTS.delete(old.sig);
|
|
1242
|
-
} else {
|
|
1243
|
-
TRAFFIC_COUNTS.set(old.sig, c);
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
1072
|
if(old.$node && old.$node.parentNode) {
|
|
1247
1073
|
old.$node.parentNode.removeChild(old.$node);
|
|
1248
1074
|
}
|
|
@@ -1270,78 +1096,108 @@ function info_log(level, msg, hora)
|
|
|
1270
1096
|
******************************/
|
|
1271
1097
|
|
|
1272
1098
|
|
|
1273
|
-
|
|
1099
|
+
/* Send one of the yuno's trace commands; a refusal is said. */
|
|
1100
|
+
function yuno_trace_command(command, kw)
|
|
1274
1101
|
{
|
|
1275
|
-
let
|
|
1276
|
-
if(
|
|
1277
|
-
|
|
1278
|
-
v = 0;
|
|
1279
|
-
} else {
|
|
1280
|
-
gobj_write_attr(gobj_yuno(), "trace_inter_event", true);
|
|
1281
|
-
gobj_write_attr(gobj_yuno(), "trace_ievent_callback", info_traffic);
|
|
1282
|
-
v = 1;
|
|
1102
|
+
let r = gobj_command(gobj_yuno(), command, kw, gobj_yuno());
|
|
1103
|
+
if(!r || r.result < 0) {
|
|
1104
|
+
log_error(`yui_dev: ${command} ${JSON.stringify(kw)}: ${r ? r.comment : "no answer"}`);
|
|
1283
1105
|
}
|
|
1284
|
-
kw_set_local_storage_value("trace_traffic", v);
|
|
1285
1106
|
refresh_dev_chrome();
|
|
1286
1107
|
}
|
|
1287
1108
|
|
|
1288
|
-
function
|
|
1109
|
+
function global_bit(bit)
|
|
1110
|
+
{
|
|
1111
|
+
return (gobj_global_trace_level() & bit) ? 1 : 0;
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
const GLOBAL_TRACE_BITS = {
|
|
1115
|
+
"machine": trace_level_t.TRACE_MACHINE,
|
|
1116
|
+
"ev_kw": trace_level_t.TRACE_EV_KW,
|
|
1117
|
+
"create_delete": trace_level_t.TRACE_CREATE_DELETE,
|
|
1118
|
+
"start_stop": trace_level_t.TRACE_START_STOP,
|
|
1119
|
+
"subscriptions": trace_level_t.TRACE_SUBSCRIPTIONS,
|
|
1120
|
+
};
|
|
1121
|
+
|
|
1122
|
+
function toggle_global(level)
|
|
1123
|
+
{
|
|
1124
|
+
yuno_trace_command("set-global-trace",
|
|
1125
|
+
{level: level, set: global_bit(GLOBAL_TRACE_BITS[level]) ? 0 : 1});
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
/* Automata cycles 0 → 1 (machine) → 2 (machine + the kw of each event) → 0. */
|
|
1129
|
+
function automata_state()
|
|
1289
1130
|
{
|
|
1290
|
-
|
|
1131
|
+
if(!global_bit(trace_level_t.TRACE_MACHINE)) {
|
|
1132
|
+
return 0;
|
|
1133
|
+
}
|
|
1134
|
+
return global_bit(trace_level_t.TRACE_EV_KW) ? 2 : 1;
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
function toggle_automata()
|
|
1138
|
+
{
|
|
1139
|
+
let v = automata_state();
|
|
1291
1140
|
if(v === 0) {
|
|
1292
|
-
|
|
1141
|
+
yuno_trace_command("set-global-trace", {level: "machine", set: 1});
|
|
1293
1142
|
} else if(v === 1) {
|
|
1294
|
-
|
|
1143
|
+
yuno_trace_command("set-global-trace", {level: "ev_kw", set: 1});
|
|
1295
1144
|
} else {
|
|
1296
|
-
|
|
1145
|
+
yuno_trace_command("set-global-trace", {level: "ev_kw", set: 0});
|
|
1146
|
+
yuno_trace_command("set-global-trace", {level: "machine", set: 0});
|
|
1297
1147
|
}
|
|
1298
|
-
gobj_write_attr(gobj_yuno(), "tracing", v);
|
|
1299
|
-
kw_set_local_storage_value("trace_automata", v);
|
|
1300
|
-
refresh_dev_chrome();
|
|
1301
1148
|
}
|
|
1302
1149
|
|
|
1303
|
-
|
|
1150
|
+
/* Traffic is C_IEVENT_CLI's own level, as `set-gclass-trace
|
|
1151
|
+
* gclass=C_IEVENT_CLI level=ievents` on a node. */
|
|
1152
|
+
function traffic_state()
|
|
1304
1153
|
{
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1154
|
+
/* An app with no websocket registers no C_IEVENT_CLI: nothing to trace,
|
|
1155
|
+
* and nothing wrong with that, so ask before reading its levels. */
|
|
1156
|
+
if(!gclass_find_by_name("C_IEVENT_CLI")) {
|
|
1157
|
+
return 0;
|
|
1158
|
+
}
|
|
1159
|
+
return gobj_get_gclass_trace_level2("C_IEVENT_CLI").includes("ievents") ? 1 : 0;
|
|
1310
1160
|
}
|
|
1311
1161
|
|
|
1312
|
-
function
|
|
1162
|
+
function toggle_traffic()
|
|
1313
1163
|
{
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1164
|
+
if(!gclass_find_by_name("C_IEVENT_CLI")) {
|
|
1165
|
+
log_error("yui_dev: no C_IEVENT_CLI in this app, there is no traffic to trace");
|
|
1166
|
+
return;
|
|
1167
|
+
}
|
|
1168
|
+
yuno_trace_command("set-gclass-trace",
|
|
1169
|
+
{gclass_name: "C_IEVENT_CLI", level: "ievents", set: traffic_state() ? 0 : 1});
|
|
1319
1170
|
}
|
|
1320
1171
|
|
|
1321
|
-
|
|
1172
|
+
/* Periodic is EV_TIMEOUT_PERIODIC and nothing else: the global level
|
|
1173
|
+
* `timer_periodic`. main() silences it with the NO-trace of the same
|
|
1174
|
+
* level, which wins over the trace, so the chip moves both. */
|
|
1175
|
+
function periodic_state()
|
|
1322
1176
|
{
|
|
1323
|
-
let
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
kw_set_local_storage_value("trace_subscriptions", v);
|
|
1327
|
-
refresh_dev_chrome();
|
|
1177
|
+
let on = gobj_global_trace_level() & trace_level_t.TRACE_TIMER_PERIODIC;
|
|
1178
|
+
let off = gobj_global_trace_no_level() & trace_level_t.TRACE_TIMER_PERIODIC;
|
|
1179
|
+
return (on && !off) ? 1 : 0;
|
|
1328
1180
|
}
|
|
1329
1181
|
|
|
1330
|
-
function
|
|
1182
|
+
function toggle_periodic()
|
|
1331
1183
|
{
|
|
1332
|
-
let v =
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
kw_set_local_storage_value("trace_i18n", v);
|
|
1336
|
-
refresh_dev_chrome();
|
|
1184
|
+
let v = periodic_state() ? 0 : 1;
|
|
1185
|
+
yuno_trace_command("set-global-trace", {level: "timer_periodic", set: v});
|
|
1186
|
+
yuno_trace_command("set-global-no-trace", {level: "timer_periodic", set: v ? 0 : 1});
|
|
1337
1187
|
}
|
|
1338
1188
|
|
|
1339
|
-
|
|
1189
|
+
/* I18n is no trace of the runtime: i18next's own debug switch, kept in
|
|
1190
|
+
* the browser as it always was. */
|
|
1191
|
+
function i18n_state()
|
|
1340
1192
|
{
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1193
|
+
return Number(kw_get_local_storage_value("trace_i18n", 0, false)) ? 1 : 0;
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
function toggle_i18n()
|
|
1197
|
+
{
|
|
1198
|
+
let v = i18n_state() ? 0 : 1;
|
|
1199
|
+
i18next.options.debug = v ? true : false;
|
|
1200
|
+
kw_set_local_storage_value("trace_i18n", v);
|
|
1345
1201
|
refresh_dev_chrome();
|
|
1346
1202
|
}
|
|
1347
1203
|
|
|
@@ -1351,16 +1207,17 @@ function set_no_poll()
|
|
|
1351
1207
|
******************************/
|
|
1352
1208
|
|
|
1353
1209
|
|
|
1354
|
-
/* Sync every control's visual state
|
|
1355
|
-
*
|
|
1210
|
+
/* Sync every control's visual state -- the trace chips from the
|
|
1211
|
+
* runtime, the rest from persisted prefs -- plus the stats strip. Idempotent; null-guarded so
|
|
1356
1212
|
* it is safe to call whether or not the window is mounted. */
|
|
1357
1213
|
function refresh_dev_chrome()
|
|
1358
1214
|
{
|
|
1359
1215
|
document.querySelectorAll('.YDEV_CHIP[data-trace]').forEach(($b) => {
|
|
1360
1216
|
let key = $b.getAttribute('data-trace');
|
|
1217
|
+
let def = TRACE_DEFS.find((d) => d[0] === key);
|
|
1361
1218
|
let label = t($b.getAttribute('data-label') || '');
|
|
1362
|
-
let v =
|
|
1363
|
-
$b.textContent = (key === "
|
|
1219
|
+
let v = def ? def[3]() : 0;
|
|
1220
|
+
$b.textContent = (key === "automata" && v > 0) ? (label + " " + v) : label;
|
|
1364
1221
|
$b.classList.toggle('is-active', v > 0);
|
|
1365
1222
|
});
|
|
1366
1223
|
|
|
@@ -1388,39 +1245,10 @@ function refresh_dev_chrome()
|
|
|
1388
1245
|
$b.classList.toggle('is-active', !!dev_num($b.getAttribute('data-dir'), 1));
|
|
1389
1246
|
});
|
|
1390
1247
|
|
|
1391
|
-
document.querySelectorAll('.YDEV_CHIP[data-toggle="periodic"]').forEach(($b) => {
|
|
1392
|
-
$b.classList.toggle('is-active', dev_hide_periodic());
|
|
1393
|
-
});
|
|
1394
|
-
|
|
1395
1248
|
document.querySelectorAll('.YDEV_CHIP[data-toggle="automata-simple"]').forEach(($b) => {
|
|
1396
1249
|
$b.classList.toggle('is-active', !!dev_simple_mach());
|
|
1397
1250
|
});
|
|
1398
1251
|
|
|
1399
|
-
let $m = document.getElementById('ydev-muted');
|
|
1400
|
-
if($m) {
|
|
1401
|
-
$m.replaceChildren();
|
|
1402
|
-
let set = dev_muted();
|
|
1403
|
-
if(set.size) {
|
|
1404
|
-
let $lbl = document.createElement('span');
|
|
1405
|
-
$lbl.className = 'YDEV_LABEL';
|
|
1406
|
-
$lbl.textContent = t('muted');
|
|
1407
|
-
$lbl.setAttribute('data-i18n', 'muted');
|
|
1408
|
-
$m.appendChild($lbl);
|
|
1409
|
-
set.forEach((sig) => {
|
|
1410
|
-
$m.appendChild(createElement2(
|
|
1411
|
-
['button', {class: 'YDEV_MUTED_CHIP', type: 'button',
|
|
1412
|
-
title: t('unmute'), 'data-i18n-title': 'unmute'},
|
|
1413
|
-
'⊘ ' + sig + ' ✕', {
|
|
1414
|
-
click: (ev) => {
|
|
1415
|
-
ev.stopPropagation();
|
|
1416
|
-
unmute_signature(sig);
|
|
1417
|
-
}
|
|
1418
|
-
}]
|
|
1419
|
-
));
|
|
1420
|
-
});
|
|
1421
|
-
}
|
|
1422
|
-
}
|
|
1423
|
-
|
|
1424
1252
|
update_stats();
|
|
1425
1253
|
}
|
|
1426
1254
|
|
|
@@ -1485,17 +1313,19 @@ function dev_fallback_copy(text)
|
|
|
1485
1313
|
document.body.removeChild(ta);
|
|
1486
1314
|
}
|
|
1487
1315
|
|
|
1488
|
-
/* The control bar: trace toggles, view selector, direction
|
|
1489
|
-
*
|
|
1316
|
+
/* The control bar: trace toggles, view selector, direction
|
|
1317
|
+
* filters, free-text search, copy, clear. Returns an element. */
|
|
1490
1318
|
function build_control_bar()
|
|
1491
1319
|
{
|
|
1492
|
-
let trace_chips = TRACE_DEFS.map(([key, label_key,
|
|
1320
|
+
let trace_chips = TRACE_DEFS.map(([key, label_key, title_key, state, toggle]) => ['button', {
|
|
1493
1321
|
class: 'YDEV_CHIP', 'data-trace': key, 'data-label': label_key,
|
|
1494
1322
|
'data-i18n': label_key, type: 'button',
|
|
1323
|
+
title: t(title_key), 'data-i18n-title': title_key,
|
|
1324
|
+
'aria-label': t(label_key), 'data-i18n-aria-label': label_key,
|
|
1495
1325
|
}, t(label_key), {
|
|
1496
1326
|
click: (ev) => {
|
|
1497
1327
|
ev.stopPropagation();
|
|
1498
|
-
|
|
1328
|
+
toggle();
|
|
1499
1329
|
}
|
|
1500
1330
|
}]);
|
|
1501
1331
|
|
|
@@ -1594,24 +1424,6 @@ function build_control_bar()
|
|
|
1594
1424
|
mk_dir('err', '⚠', 'dev_filter_err', 'errors'),
|
|
1595
1425
|
];
|
|
1596
1426
|
|
|
1597
|
-
let periodic_chip = ['button', {
|
|
1598
|
-
class: 'YDEV_CHIP', 'data-toggle': 'periodic', type: 'button',
|
|
1599
|
-
title: t('hide the timers and the recurring traffic'),
|
|
1600
|
-
'data-i18n-title': 'hide the timers and the recurring traffic',
|
|
1601
|
-
}, [
|
|
1602
|
-
/* The glyph is its own element so the label beside it can carry
|
|
1603
|
-
* its key: `refresh_language()` replaces the FIRST text node of
|
|
1604
|
-
* the element that carries `data-i18n`, and that would have
|
|
1605
|
-
* eaten the glyph with the word. */
|
|
1606
|
-
['span', {class: 'YDEV_GLYPH'}, '⊘'],
|
|
1607
|
-
['span', {'data-i18n': 'periodic'}, t('periodic')]
|
|
1608
|
-
], {
|
|
1609
|
-
click: (ev) => {
|
|
1610
|
-
ev.stopPropagation();
|
|
1611
|
-
toggle_pref('dev_hide_periodic', HIDE_PERIODIC_DEFAULT);
|
|
1612
|
-
}
|
|
1613
|
-
}];
|
|
1614
|
-
|
|
1615
1427
|
let search = ['input', {
|
|
1616
1428
|
class: 'YDEV_SEARCH', type: 'search', 'data-role': 'search',
|
|
1617
1429
|
placeholder: t('filter events / payload'),
|
|
@@ -1656,7 +1468,7 @@ function build_control_bar()
|
|
|
1656
1468
|
grp('traces', [...trace_chips, simple_mach]), sep(),
|
|
1657
1469
|
grp('output', [output_seg]), sep(),
|
|
1658
1470
|
grp('view', [view_seg]), expand_grp, sep(),
|
|
1659
|
-
grp('show',
|
|
1471
|
+
grp('show', dir_chips), sep(),
|
|
1660
1472
|
grp('find', [search]), sep(),
|
|
1661
1473
|
grp('log', [copy, clear]),
|
|
1662
1474
|
]]);
|
|
@@ -1672,12 +1484,11 @@ function build_title_header()
|
|
|
1672
1484
|
]]);
|
|
1673
1485
|
}
|
|
1674
1486
|
|
|
1675
|
-
/* The monitor body: control bar +
|
|
1487
|
+
/* The monitor body: control bar + log + stats strip. */
|
|
1676
1488
|
function build_dev_body()
|
|
1677
1489
|
{
|
|
1678
1490
|
return createElement2(['div', {class: 'YDEV_BODY'}, [
|
|
1679
1491
|
build_control_bar(),
|
|
1680
|
-
['div', {class: 'YDEV_MUTED', id: 'ydev-muted'}, []],
|
|
1681
1492
|
['div', {class: 'YDEV_LOG', id: 'developer-traffic-logger'}, []],
|
|
1682
1493
|
['div', {class: 'YDEV_STATS', id: 'ydev-stats'}, []],
|
|
1683
1494
|
]]);
|
|
@@ -1702,32 +1513,19 @@ function dev_window_was_open()
|
|
|
1702
1513
|
}
|
|
1703
1514
|
|
|
1704
1515
|
/************************************************************
|
|
1705
|
-
*
|
|
1706
|
-
*
|
|
1707
|
-
*
|
|
1516
|
+
* Wire the developer window's sinks and the browser-side prefs.
|
|
1517
|
+
* Call it once at app startup.
|
|
1518
|
+
*
|
|
1519
|
+
* The TRACE LEVELS are not here: the yuno restores the ones the user
|
|
1520
|
+
* persisted in its own mt_create (`trace_levels` / `no_trace_levels`),
|
|
1521
|
+
* as a C yuno does. What is left is where the output goes.
|
|
1708
1522
|
************************************************************/
|
|
1709
1523
|
function apply_dev_traces()
|
|
1710
1524
|
{
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
let subscriptions = Number(kw_get_local_storage_value("trace_subscriptions", 0, false));
|
|
1716
|
-
let i18n = Number(kw_get_local_storage_value("trace_i18n", 0, false));
|
|
1717
|
-
let no_poll = Number(kw_get_local_storage_value("no_poll", 0, false));
|
|
1718
|
-
|
|
1719
|
-
if(traffic) {
|
|
1720
|
-
gobj_write_attr(gobj_yuno(), "trace_inter_event", true);
|
|
1721
|
-
gobj_write_attr(gobj_yuno(), "trace_ievent_callback", info_traffic);
|
|
1722
|
-
} else {
|
|
1723
|
-
gobj_write_attr(gobj_yuno(), "trace_inter_event", false);
|
|
1724
|
-
}
|
|
1725
|
-
gobj_write_attr(gobj_yuno(), "tracing", trace);
|
|
1726
|
-
gobj_write_attr(gobj_yuno(), "trace_creation", creation);
|
|
1727
|
-
gobj_write_attr(gobj_yuno(), "trace_start_stop", start_stop);
|
|
1728
|
-
gobj_write_attr(gobj_yuno(), "trace_subscriptions", subscriptions);
|
|
1729
|
-
gobj_write_attr(gobj_yuno(), "no_poll", no_poll);
|
|
1730
|
-
i18next.options.debug = i18n ? true : false;
|
|
1525
|
+
/* The traffic trace of C_IEVENT_CLI lands in this window. */
|
|
1526
|
+
gobj_write_attr(gobj_yuno(), "trace_ievent_callback", info_traffic);
|
|
1527
|
+
|
|
1528
|
+
i18next.options.debug = i18n_state() ? true : false;
|
|
1731
1529
|
|
|
1732
1530
|
/* Which shape the machine trace is written in (persisted). */
|
|
1733
1531
|
gobj_set_trace_machine_format(dev_simple_mach());
|
|
@@ -1812,8 +1610,8 @@ function setup_dev(self, show)
|
|
|
1812
1610
|
*
|
|
1813
1611
|
* Returns { $el, dispose }:
|
|
1814
1612
|
* - $el: the panel element (control bar + log + stats).
|
|
1815
|
-
* - dispose:
|
|
1816
|
-
* the
|
|
1613
|
+
* - dispose: call it from the modal's on_close (kept for the
|
|
1614
|
+
* contract; the traces outlive the panel).
|
|
1817
1615
|
************************************************************/
|
|
1818
1616
|
function build_dev_panel()
|
|
1819
1617
|
{
|
|
@@ -1844,8 +1642,9 @@ function build_dev_panel()
|
|
|
1844
1642
|
rerender_all();
|
|
1845
1643
|
}, 0);
|
|
1846
1644
|
|
|
1645
|
+
/* Nothing to undo: a trace level is the yuno's state, persisted,
|
|
1646
|
+
* and it is not tied to this panel being open. */
|
|
1847
1647
|
let dispose = function() {
|
|
1848
|
-
gobj_write_attr(gobj_yuno(), "trace_inter_event", false);
|
|
1849
1648
|
};
|
|
1850
1649
|
|
|
1851
1650
|
return {$el: $el, dispose: dispose};
|