@yuneta/gobj-js 7.16.6 → 7.22.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 +21 -3
- package/dist/gobj-js.cjs.js +302 -57
- package/dist/gobj-js.cjs.js.map +1 -1
- package/dist/gobj-js.cjs.min.js +1269 -1154
- package/dist/gobj-js.cjs.min.js.map +1 -1
- package/dist/gobj-js.es.js +294 -58
- package/dist/gobj-js.es.js.map +1 -1
- package/dist/gobj-js.es.min.js +1231 -1120
- package/dist/gobj-js.es.min.js.map +1 -1
- package/dist/gobj-js.iife.js +302 -57
- package/dist/gobj-js.iife.js.map +1 -1
- package/dist/gobj-js.iife.min.js +1658 -1543
- package/dist/gobj-js.iife.min.js.map +1 -1
- package/dist/gobj-js.umd.js +302 -57
- package/dist/gobj-js.umd.js.map +1 -1
- package/dist/gobj-js.umd.min.js +1656 -1541
- package/dist/gobj-js.umd.min.js.map +1 -1
- package/package.json +1 -1
package/dist/gobj-js.umd.js
CHANGED
|
@@ -197,7 +197,7 @@
|
|
|
197
197
|
*
|
|
198
198
|
* Licence: MIT (http://www.opensource.org/licenses/mit-license)
|
|
199
199
|
* Copyright (c) 2014,2024 Niyamaka.
|
|
200
|
-
* Copyright (c) 2025, ArtGins.
|
|
200
|
+
* Copyright (c) 2025-2026, ArtGins.
|
|
201
201
|
*********************************************************************************/
|
|
202
202
|
/**************************************************************************
|
|
203
203
|
* Constants
|
|
@@ -432,6 +432,7 @@
|
|
|
432
432
|
TRACE_URING_TIME: 536870912,
|
|
433
433
|
TRACE_COMMANDS: 1073741824
|
|
434
434
|
});
|
|
435
|
+
var TRACE_USER_LEVEL = 65535;
|
|
435
436
|
var TRACE_GLOBAL_LEVEL1 = 268369920;
|
|
436
437
|
var s_global_trace_level = [
|
|
437
438
|
[
|
|
@@ -513,17 +514,28 @@
|
|
|
513
514
|
var __global_trace_level__ = 0;
|
|
514
515
|
var __global_trace_no_level__ = 0;
|
|
515
516
|
var __deep_trace__ = 0;
|
|
516
|
-
function level2bit(level) {
|
|
517
|
+
function level2bit(level, s_user_trace_level) {
|
|
517
518
|
for (const [name, bit] of s_global_trace_level) if (name === level) return bit;
|
|
519
|
+
if (Array.isArray(s_user_trace_level)) {
|
|
520
|
+
for (let i = 0; i < s_user_trace_level.length && i < 16; i++) if (s_user_trace_level[i] && s_user_trace_level[i][0] === level) return 1 << i;
|
|
521
|
+
}
|
|
518
522
|
return 0;
|
|
519
523
|
}
|
|
520
|
-
function
|
|
521
|
-
|
|
524
|
+
function bit2level(bitmask, s_user_trace_level) {
|
|
525
|
+
let levels = [];
|
|
526
|
+
for (const [name, bit] of s_global_trace_level) if (bitmask & bit) levels.push(name);
|
|
527
|
+
if (Array.isArray(s_user_trace_level)) {
|
|
528
|
+
for (let i = 0; i < s_user_trace_level.length && i < 16; i++) if (s_user_trace_level[i] && bitmask & 1 << i) levels.push(s_user_trace_level[i][0]);
|
|
529
|
+
}
|
|
530
|
+
return levels;
|
|
531
|
+
}
|
|
532
|
+
function trace_bitmask(level, who, s_user_trace_level) {
|
|
533
|
+
if (empty_string(level)) return s_user_trace_level === void 0 ? TRACE_GLOBAL_LEVEL1 : TRACE_USER_LEVEL;
|
|
522
534
|
if (/^[0-9]+$/.test(String(level))) {
|
|
523
535
|
const n = Number(level);
|
|
524
536
|
if (n) return n;
|
|
525
537
|
}
|
|
526
|
-
const bit = level2bit(String(level));
|
|
538
|
+
const bit = level2bit(String(level), s_user_trace_level);
|
|
527
539
|
if (!bit) {
|
|
528
540
|
log_error(`${who}: trace level NOT FOUND: ${level}`);
|
|
529
541
|
return 0;
|
|
@@ -552,32 +564,30 @@
|
|
|
552
564
|
}
|
|
553
565
|
return bitmask;
|
|
554
566
|
}
|
|
555
|
-
function legacy_yuno_trace_bits() {
|
|
556
|
-
if (!__yuno__ || !__yuno__.jn_attrs) return 0;
|
|
557
|
-
let bits = 0;
|
|
558
|
-
if (gobj_has_attr(__yuno__, "tracing")) {
|
|
559
|
-
const tracing = Number(gobj_read_attr(__yuno__, "tracing")) || 0;
|
|
560
|
-
if (tracing >= 1) bits |= trace_level_t.TRACE_MACHINE;
|
|
561
|
-
if (tracing >= 2) bits |= trace_level_t.TRACE_EV_KW;
|
|
562
|
-
}
|
|
563
|
-
if (gobj_has_attr(__yuno__, "trace_timer") && gobj_read_attr(__yuno__, "trace_timer")) bits |= trace_level_t.TRACE_TIMER;
|
|
564
|
-
if (gobj_has_attr(__yuno__, "trace_creation") && gobj_read_attr(__yuno__, "trace_creation")) bits |= trace_level_t.TRACE_CREATE_DELETE;
|
|
565
|
-
if (gobj_has_attr(__yuno__, "trace_start_stop") && gobj_read_attr(__yuno__, "trace_start_stop")) bits |= trace_level_t.TRACE_START_STOP;
|
|
566
|
-
return bits;
|
|
567
|
-
}
|
|
568
567
|
function __trace_gobj_create_delete__(gobj) {
|
|
569
|
-
return
|
|
568
|
+
return gobj_trace_level(gobj) & trace_level_t.TRACE_CREATE_DELETE;
|
|
569
|
+
}
|
|
570
|
+
function __trace_gobj_subscriptions__(gobj) {
|
|
571
|
+
return gobj_trace_level(gobj) & trace_level_t.TRACE_SUBSCRIPTIONS;
|
|
570
572
|
}
|
|
571
573
|
function __trace_gobj_start_stop__(gobj) {
|
|
572
|
-
return
|
|
574
|
+
return gobj_trace_level(gobj) & trace_level_t.TRACE_START_STOP;
|
|
573
575
|
}
|
|
574
576
|
function __trace_gobj_ev_kw__(gobj) {
|
|
575
|
-
return
|
|
577
|
+
return gobj_trace_level(gobj) & trace_level_t.TRACE_EV_KW;
|
|
576
578
|
}
|
|
577
579
|
function __trace_gobj_states__(gobj) {
|
|
578
580
|
return gobj_trace_level(gobj) & trace_level_t.TRACE_STATES;
|
|
579
581
|
}
|
|
580
582
|
/************************************************************
|
|
583
|
+
* Must trace a command? — the C kernel's is_commands_tracing()
|
|
584
|
+
************************************************************/
|
|
585
|
+
function is_commands_tracing(gobj) {
|
|
586
|
+
if (__deep_trace__ > 1) return true;
|
|
587
|
+
if (!gobj) return false;
|
|
588
|
+
return gobj_trace_level(gobj) & trace_level_t.TRACE_COMMANDS ? true : false;
|
|
589
|
+
}
|
|
590
|
+
/************************************************************
|
|
581
591
|
* Must trace? — the C kernel's is_machine_tracing(), including
|
|
582
592
|
* the two event-specific levels: `timer` and `timer_periodic`
|
|
583
593
|
* light up only for their own event.
|
|
@@ -585,7 +595,7 @@
|
|
|
585
595
|
function is_machine_tracing(gobj, event) {
|
|
586
596
|
if (__deep_trace__ > 1) return true;
|
|
587
597
|
if (!gobj) return false;
|
|
588
|
-
const level = gobj_trace_level(gobj)
|
|
598
|
+
const level = gobj_trace_level(gobj);
|
|
589
599
|
return level & trace_level_t.TRACE_MACHINE || level & trace_level_t.TRACE_TIMER_PERIODIC && event === "EV_TIMEOUT_PERIODIC" || level & trace_level_t.TRACE_TIMER && event === "EV_TIMEOUT" ? true : false;
|
|
590
600
|
}
|
|
591
601
|
/************************************************************
|
|
@@ -618,6 +628,49 @@
|
|
|
618
628
|
function gobj_global_trace_level() {
|
|
619
629
|
return __global_trace_level__;
|
|
620
630
|
}
|
|
631
|
+
function gobj_global_trace_no_level() {
|
|
632
|
+
return __global_trace_no_level__;
|
|
633
|
+
}
|
|
634
|
+
function gobj_set_global_trace2(bitmask, set) {
|
|
635
|
+
if (set) __global_trace_level__ = (__global_trace_level__ | bitmask) >>> 0;
|
|
636
|
+
else __global_trace_level__ = (__global_trace_level__ & ~bitmask) >>> 0;
|
|
637
|
+
return 0;
|
|
638
|
+
}
|
|
639
|
+
function gobj_set_global_no_trace2(bitmask, set) {
|
|
640
|
+
if (set) __global_trace_no_level__ = (__global_trace_no_level__ | bitmask) >>> 0;
|
|
641
|
+
else __global_trace_no_level__ = (__global_trace_no_level__ & ~bitmask) >>> 0;
|
|
642
|
+
return 0;
|
|
643
|
+
}
|
|
644
|
+
function gobj_get_global_trace_level() {
|
|
645
|
+
return bit2level(__global_trace_level__, null);
|
|
646
|
+
}
|
|
647
|
+
function gobj_get_global_trace_no_level() {
|
|
648
|
+
return bit2level(__global_trace_no_level__, null);
|
|
649
|
+
}
|
|
650
|
+
function gobj_get_gclass_trace_level(gclass) {
|
|
651
|
+
const gclass_ = is_string(gclass) ? gclass_find_by_name(gclass) : gclass;
|
|
652
|
+
if (!gclass_) {
|
|
653
|
+
log_error(`gobj_get_gclass_trace_level: gclass NOT FOUND: ${gclass}`);
|
|
654
|
+
return [];
|
|
655
|
+
}
|
|
656
|
+
return bit2level(gclass_.trace_level | __global_trace_level__, gclass_.s_user_trace_level);
|
|
657
|
+
}
|
|
658
|
+
function gobj_get_gclass_trace_level2(gclass) {
|
|
659
|
+
const gclass_ = is_string(gclass) ? gclass_find_by_name(gclass) : gclass;
|
|
660
|
+
if (!gclass_) {
|
|
661
|
+
log_error(`gobj_get_gclass_trace_level2: gclass NOT FOUND: ${gclass}`);
|
|
662
|
+
return [];
|
|
663
|
+
}
|
|
664
|
+
return bit2level(gclass_.trace_level, gclass_.s_user_trace_level);
|
|
665
|
+
}
|
|
666
|
+
function gobj_get_gclass_trace_no_level(gclass) {
|
|
667
|
+
const gclass_ = is_string(gclass) ? gclass_find_by_name(gclass) : gclass;
|
|
668
|
+
if (!gclass_) {
|
|
669
|
+
log_error(`gobj_get_gclass_trace_no_level: gclass NOT FOUND: ${gclass}`);
|
|
670
|
+
return [];
|
|
671
|
+
}
|
|
672
|
+
return bit2level(gclass_.no_trace_level, gclass_.s_user_trace_level);
|
|
673
|
+
}
|
|
621
674
|
function gobj_set_deep_trace(value) {
|
|
622
675
|
__deep_trace__ = Number(value) || 0;
|
|
623
676
|
return 0;
|
|
@@ -628,7 +681,7 @@
|
|
|
628
681
|
log_error(`gobj_set_gclass_trace: gclass NOT FOUND: ${gclass}`);
|
|
629
682
|
return -1;
|
|
630
683
|
}
|
|
631
|
-
const bitmask = trace_bitmask(level, "gobj_set_gclass_trace");
|
|
684
|
+
const bitmask = level === null ? 4294967295 : trace_bitmask(level, "gobj_set_gclass_trace", gclass_.s_user_trace_level || null);
|
|
632
685
|
if (!bitmask) return -1;
|
|
633
686
|
if (set) gclass_.trace_level |= bitmask;
|
|
634
687
|
else gclass_.trace_level &= ~bitmask;
|
|
@@ -639,7 +692,7 @@
|
|
|
639
692
|
log_error(`gobj_set_gobj_trace: gobj NULL`);
|
|
640
693
|
return -1;
|
|
641
694
|
}
|
|
642
|
-
const bitmask = trace_bitmask(level, "gobj_set_gobj_trace");
|
|
695
|
+
const bitmask = trace_bitmask(level, "gobj_set_gobj_trace", gobj.gclass && gobj.gclass.s_user_trace_level || null);
|
|
643
696
|
if (!bitmask) return -1;
|
|
644
697
|
if (set) gobj.trace_level |= bitmask;
|
|
645
698
|
else gobj.trace_level &= ~bitmask;
|
|
@@ -651,7 +704,7 @@
|
|
|
651
704
|
log_error(`gobj_set_gclass_no_trace: gclass NOT FOUND: ${gclass}`);
|
|
652
705
|
return -1;
|
|
653
706
|
}
|
|
654
|
-
const bitmask = trace_bitmask(level, "gobj_set_gclass_no_trace");
|
|
707
|
+
const bitmask = level === null ? 4294967295 : trace_bitmask(level, "gobj_set_gclass_no_trace", gclass_.s_user_trace_level || null);
|
|
655
708
|
if (!bitmask) return -1;
|
|
656
709
|
if (set) gclass_.no_trace_level |= bitmask;
|
|
657
710
|
else gclass_.no_trace_level &= ~bitmask;
|
|
@@ -662,7 +715,7 @@
|
|
|
662
715
|
log_error(`gobj_set_gobj_no_trace: gobj NULL`);
|
|
663
716
|
return -1;
|
|
664
717
|
}
|
|
665
|
-
const bitmask = trace_bitmask(level, "gobj_set_gobj_no_trace");
|
|
718
|
+
const bitmask = trace_bitmask(level, "gobj_set_gobj_no_trace", gobj.gclass && gobj.gclass.s_user_trace_level || null);
|
|
666
719
|
if (!bitmask) return -1;
|
|
667
720
|
if (set) gobj.no_trace_level |= bitmask;
|
|
668
721
|
else gobj.no_trace_level &= ~bitmask;
|
|
@@ -2666,7 +2719,7 @@
|
|
|
2666
2719
|
if (kw_get_int(gobj, subs, "subs_flag", null, kw_flag_t.KW_REQUIRED) & subs_flag_t.__hard_subscription__ ? 1 : 0) {
|
|
2667
2720
|
if (!force) return -1;
|
|
2668
2721
|
}
|
|
2669
|
-
if (
|
|
2722
|
+
if (__trace_gobj_subscriptions__(subscriber) || __trace_gobj_subscriptions__(publisher)) {
|
|
2670
2723
|
trace_machine(sprintf("💜💜👎 unsubscribing event '%s': publisher %s, subscriber'%s'", event ? event : "", gobj_short_name(publisher), gobj_short_name(subscriber)));
|
|
2671
2724
|
trace_json(subs);
|
|
2672
2725
|
}
|
|
@@ -2737,7 +2790,7 @@
|
|
|
2737
2790
|
}
|
|
2738
2791
|
json_array_append(publisher.dl_subscriptions, subs);
|
|
2739
2792
|
json_array_append(subscriber.dl_subscribings, subs);
|
|
2740
|
-
if (
|
|
2793
|
+
if (__trace_gobj_subscriptions__(subscriber) || __trace_gobj_subscriptions__(publisher)) {
|
|
2741
2794
|
trace_machine(sprintf("💜💜👍 subscribing event '%s', publisher '%s', subscriber %s", event ? event : "", gobj_short_name(publisher), gobj_short_name(subscriber)));
|
|
2742
2795
|
if (kw) trace_json(kw);
|
|
2743
2796
|
}
|
|
@@ -2875,7 +2928,7 @@
|
|
|
2875
2928
|
return -1;
|
|
2876
2929
|
}
|
|
2877
2930
|
}
|
|
2878
|
-
let tracea =
|
|
2931
|
+
let tracea = (__trace_gobj_subscriptions__(publisher) || is_machine_tracing(publisher, event)) && !is_machine_not_tracing(publisher, event);
|
|
2879
2932
|
if (tracea) {
|
|
2880
2933
|
if (__trace_machine_format__ === 1) trace_machine(sprintf("🔝🔝 %s %s%s %s", event ? event : "", !publisher.running ? "!!" : "", gobj_short_name(publisher), publisher.current_state.state_name));
|
|
2881
2934
|
else trace_machine(sprintf("🔝🔝 mach(%s%s^%s), st: %s, ev: %s%s%s", !publisher.running ? "!!" : "", gobj_gclass_name(publisher), gobj_name(publisher), publisher.current_state.state_name, "", event ? event : "", ""));
|
|
@@ -2953,10 +3006,9 @@
|
|
|
2953
3006
|
log_error("gobj NULL or DESTROYED");
|
|
2954
3007
|
return -1;
|
|
2955
3008
|
}
|
|
2956
|
-
|
|
2957
|
-
if (tracea) {
|
|
3009
|
+
if (is_commands_tracing(gobj) || is_machine_tracing(gobj, null) && !is_machine_not_tracing(src, null)) {
|
|
2958
3010
|
trace_machine(sprintf("🌀🌀 mach(%s%s), cmd: %s, src: %s", !gobj_is_running(gobj) ? "!!" : "", gobj_short_name(gobj), command, gobj_short_name(src)));
|
|
2959
|
-
if (
|
|
3011
|
+
if (__trace_gobj_ev_kw__(gobj)) trace_json(kw);
|
|
2960
3012
|
}
|
|
2961
3013
|
if (gobj.gclass.gmt.mt_command_parser) return gobj.gclass.gmt.mt_command_parser(gobj, command, kw, src);
|
|
2962
3014
|
if (gobj.gclass.command_table) {
|
|
@@ -4024,10 +4076,18 @@
|
|
|
4024
4076
|
- list of strings [s,...]
|
|
4025
4077
|
- list of dicts [{},...]
|
|
4026
4078
|
- dict of dicts {id:{},...}
|
|
4027
|
-
return a
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4079
|
+
return a NEW list holding the rows that match `ids` and the
|
|
4080
|
+
`jn_filter` (where). If match_fn is 0 then kw_match_simple is used.
|
|
4081
|
+
|
|
4082
|
+
WARNING the LIST is new; its elements are THE SAME objects, not
|
|
4083
|
+
copies. The C twin increfs each one and says "clone", which this
|
|
4084
|
+
comment repeated for years: javascript has no refcount, so a write
|
|
4085
|
+
through a collected row writes into `kw`. Copy what you mean to
|
|
4086
|
+
modify.
|
|
4087
|
+
|
|
4088
|
+
Returns null -- not an empty list -- for a `kw` that is neither a
|
|
4089
|
+
list nor a dict, so a caller that reads `.length` off the answer
|
|
4090
|
+
must check it first (kwid_find_one_record does).
|
|
4031
4091
|
*************************************************************/
|
|
4032
4092
|
function kwid_collect(gobj, kw, ids, jn_filter, match_fn) {
|
|
4033
4093
|
if (gobj && !is_gobj(gobj)) log_error(`GObj bad instanceof`);
|
|
@@ -4056,12 +4116,17 @@
|
|
|
4056
4116
|
}
|
|
4057
4117
|
/*************************************************************
|
|
4058
4118
|
Utility for databases.
|
|
4059
|
-
Return a
|
|
4060
|
-
WARNING the "id" of a dict's record is
|
|
4119
|
+
Return a dict from a "dict of records" or "list of records".
|
|
4120
|
+
WARNING the "id" of a dict's record is hardcoded to its key.
|
|
4061
4121
|
Convention:
|
|
4062
|
-
- all arrays are
|
|
4122
|
+
- all arrays are lists of records (dicts) with "id" as primary key
|
|
4063
4123
|
- delimiter is '`' and '.'
|
|
4064
4124
|
If path is empty then use kw
|
|
4125
|
+
|
|
4126
|
+
WARNING "new" is the C twin's word, where it means a new REFERENCE:
|
|
4127
|
+
handed a dict, both return THAT dict and not a copy of it. Only the
|
|
4128
|
+
list case builds something new, and even then the records inside it
|
|
4129
|
+
are the same objects.
|
|
4065
4130
|
*************************************************************/
|
|
4066
4131
|
function kwid_new_dict(gobj, kw, path) {
|
|
4067
4132
|
if (gobj && !is_gobj(gobj)) log_error(`GObj bad instanceof`);
|
|
@@ -4070,20 +4135,59 @@
|
|
|
4070
4135
|
if (is_object(kw)) new_dict = kw;
|
|
4071
4136
|
else if (is_array(kw)) for (let i = 0; i < kw.length; i++) {
|
|
4072
4137
|
let kv = kw[i];
|
|
4073
|
-
let id = kw_get_str(gobj, kv, "id", "",
|
|
4138
|
+
let id = kw_get_str(gobj, kv, "id", "", kw_flag_t.KW_REQUIRED);
|
|
4074
4139
|
if (!empty_string(id)) new_dict[id] = kv;
|
|
4075
4140
|
}
|
|
4076
4141
|
else log_error(`${gobj_short_name(gobj)} kwid_new_dict: data type unknown`);
|
|
4077
4142
|
return new_dict;
|
|
4078
4143
|
}
|
|
4079
4144
|
/*************************************************************
|
|
4145
|
+
Utility for databases.
|
|
4146
|
+
Return a list from a "dict of records" or "list of records".
|
|
4147
|
+
The NORMALIZING function of this family: whatever shape the data
|
|
4148
|
+
arrives in, what comes back is the shape a table indexed and
|
|
4149
|
+
sorted by `id` wants.
|
|
4150
|
+
Convention:
|
|
4151
|
+
- all arrays are lists of records (dicts) with "id" as primary key
|
|
4152
|
+
- delimiter is '`' and '.'
|
|
4153
|
+
If path is empty then use kw
|
|
4154
|
+
|
|
4155
|
+
WARNING handed a DICT it writes each record's key into the record
|
|
4156
|
+
as its `id`, OVERWRITING one that differs -- in the source records,
|
|
4157
|
+
which it does not copy. That is the C twin's behaviour
|
|
4158
|
+
(`json_object_set_new(v, "id", ...)` in kwid.c) and it is the point:
|
|
4159
|
+
a dict keyed by id whose records disagree with their own key is
|
|
4160
|
+
exactly what this is for. Handed a LIST it returns that same list,
|
|
4161
|
+
untouched, as C returns a new reference to it.
|
|
4162
|
+
*************************************************************/
|
|
4163
|
+
function kwid_new_list(gobj, kw, path) {
|
|
4164
|
+
if (gobj && !is_gobj(gobj)) log_error(`GObj bad instanceof`);
|
|
4165
|
+
if (!empty_string(path)) kw = kw_find_path(gobj, kw, path);
|
|
4166
|
+
if (is_array(kw)) return kw;
|
|
4167
|
+
if (is_object(kw)) {
|
|
4168
|
+
let new_list = [];
|
|
4169
|
+
for (let id of Object.keys(kw)) {
|
|
4170
|
+
let record = kw[id];
|
|
4171
|
+
if (!is_object(record)) {
|
|
4172
|
+
log_error(`${gobj_short_name(gobj)} kwid_new_list: not a record: '${id}'`);
|
|
4173
|
+
continue;
|
|
4174
|
+
}
|
|
4175
|
+
record["id"] = id;
|
|
4176
|
+
new_list.push(record);
|
|
4177
|
+
}
|
|
4178
|
+
return new_list;
|
|
4179
|
+
}
|
|
4180
|
+
log_error(`${gobj_short_name(gobj)} kwid_new_list: wrong type for list`);
|
|
4181
|
+
return [];
|
|
4182
|
+
}
|
|
4183
|
+
/*************************************************************
|
|
4080
4184
|
* Utility for databases. See kwid_collect parameters
|
|
4081
4185
|
*************************************************************/
|
|
4082
4186
|
function kwid_find_one_record(gobj, kw, ids, jn_filter, match_fn) {
|
|
4083
4187
|
if (gobj && !is_gobj(gobj)) log_error(`GObj bad instanceof`);
|
|
4084
4188
|
let list = kwid_collect(gobj, kw, ids, jn_filter, match_fn);
|
|
4085
|
-
if (list.length
|
|
4086
|
-
|
|
4189
|
+
if (!list || list.length === 0) return null;
|
|
4190
|
+
return list[0];
|
|
4087
4191
|
}
|
|
4088
4192
|
/*************************************************************
|
|
4089
4193
|
Utility for databases.
|
|
@@ -5988,7 +6092,7 @@
|
|
|
5988
6092
|
*
|
|
5989
6093
|
* The default yuno in js
|
|
5990
6094
|
*
|
|
5991
|
-
* Copyright (c) 2025, ArtGins.
|
|
6095
|
+
* Copyright (c) 2025-2026, ArtGins.
|
|
5992
6096
|
* All Rights Reserved. ****************************************************************************/
|
|
5993
6097
|
/***************************************************************
|
|
5994
6098
|
* Constants
|
|
@@ -6011,15 +6115,9 @@
|
|
|
6011
6115
|
SDATA(data_type_t.DTP_STRING, "yuno_version", 0, "", "Yuno version (APP_VERSION)"),
|
|
6012
6116
|
SDATA(data_type_t.DTP_STRING, "yuneta_version", 0, YUNETA_VERSION, "Yuneta version"),
|
|
6013
6117
|
SDATA(data_type_t.DTP_LIST, "required_services", 0, "[]", "Required services"),
|
|
6014
|
-
SDATA(data_type_t.
|
|
6015
|
-
SDATA(data_type_t.
|
|
6016
|
-
SDATA(data_type_t.
|
|
6017
|
-
SDATA(data_type_t.DTP_POINTER, "trace_ievent_callback", 0, null, "Trace traffic callback"),
|
|
6018
|
-
SDATA(data_type_t.DTP_BOOLEAN, "trace_creation", 0, 0, "Trace creation"),
|
|
6019
|
-
SDATA(data_type_t.DTP_BOOLEAN, "trace_start_stop", 0, 0, "Trace start/stop"),
|
|
6020
|
-
SDATA(data_type_t.DTP_BOOLEAN, "trace_subscriptions", 0, 0, "Trace subscription"),
|
|
6021
|
-
SDATA(data_type_t.DTP_BOOLEAN, "trace_i18n", 0, 0, "Trace i18n"),
|
|
6022
|
-
SDATA(data_type_t.DTP_BOOLEAN, "no_poll", 0, 0, "no poll"),
|
|
6118
|
+
SDATA(data_type_t.DTP_DICT, "trace_levels", sdata_flag_t.SDF_PERSIST, "{}", "Trace levels"),
|
|
6119
|
+
SDATA(data_type_t.DTP_DICT, "no_trace_levels", sdata_flag_t.SDF_PERSIST, "{}", "No trace levels"),
|
|
6120
|
+
SDATA(data_type_t.DTP_POINTER, "trace_ievent_callback", 0, null, "Where the traffic trace goes (C_IEVENT_CLI levels ievents/ievents2); console when null"),
|
|
6023
6121
|
SDATA(data_type_t.DTP_BOOLEAN, "developer", 0, false, "Developer mode enabled"),
|
|
6024
6122
|
SDATA(data_type_t.DTP_INTEGER, "periodic_timeout", 0, "1000", "Timeout periodic, in miliseconds."),
|
|
6025
6123
|
SDATA_END()
|
|
@@ -6038,6 +6136,8 @@
|
|
|
6038
6136
|
gobj_write_str_attr(gobj, "node_uuid", node_uuid());
|
|
6039
6137
|
gobj.priv.gobj_timer = gobj_create_pure_child(gobj_name(gobj), "C_TIMER", {}, gobj);
|
|
6040
6138
|
priv.periodic_timeout = gobj_read_attr(gobj, "periodic_timeout");
|
|
6139
|
+
set_user_gclass_traces(gobj);
|
|
6140
|
+
set_user_gclass_no_traces(gobj);
|
|
6041
6141
|
}
|
|
6042
6142
|
/***************************************************************
|
|
6043
6143
|
* Framework Method: Writing
|
|
@@ -6082,8 +6182,135 @@
|
|
|
6082
6182
|
* Local Methods
|
|
6083
6183
|
***************************/
|
|
6084
6184
|
/***************************************************************
|
|
6185
|
+
* Restore the trace levels the user persisted.
|
|
6085
6186
|
*
|
|
6187
|
+
* A saved scope REPLACES what is in force: main() sets its defaults
|
|
6188
|
+
* (gobj_set_global_no_trace("timer_periodic"), a gclass it wants quiet)
|
|
6189
|
+
* before the yuno is created, and a default the user turned off must
|
|
6190
|
+
* stay off. A scope is saved whole, empty included (save_global_trace());
|
|
6191
|
+
* a scope never saved keeps main()'s. The C kernel's C_YUNO does the same.
|
|
6192
|
+
***************************************************************/
|
|
6193
|
+
function set_user_gclass_traces(gobj) {
|
|
6194
|
+
let jn_trace_levels = gobj_read_attr(gobj, "trace_levels");
|
|
6195
|
+
if (!is_object(jn_trace_levels)) return 0;
|
|
6196
|
+
let jn_global = jn_trace_levels["__global_trace__"];
|
|
6197
|
+
if (is_array(jn_global)) {
|
|
6198
|
+
gobj_set_global_trace2(4294967295, false);
|
|
6199
|
+
for (let level of jn_global) gobj_set_global_trace(level, true);
|
|
6200
|
+
}
|
|
6201
|
+
for (const [name, jn_levels] of Object.entries(jn_trace_levels)) {
|
|
6202
|
+
let gclass = gclass_find_by_name(name);
|
|
6203
|
+
if (!gclass) continue;
|
|
6204
|
+
if (!is_array(jn_levels)) {
|
|
6205
|
+
log_error(`${gobj_name(gobj)}: trace_levels of ${name} MUST be a list`);
|
|
6206
|
+
continue;
|
|
6207
|
+
}
|
|
6208
|
+
gobj_set_gclass_trace(gclass, null, false);
|
|
6209
|
+
for (let level of jn_levels) gobj_set_gclass_trace(gclass, level, true);
|
|
6210
|
+
}
|
|
6211
|
+
return 0;
|
|
6212
|
+
}
|
|
6213
|
+
/***************************************************************
|
|
6214
|
+
* Restore the no-trace levels, see set_user_gclass_traces()
|
|
6215
|
+
***************************************************************/
|
|
6216
|
+
function set_user_gclass_no_traces(gobj) {
|
|
6217
|
+
let jn_no_trace_levels = gobj_read_attr(gobj, "no_trace_levels");
|
|
6218
|
+
if (!is_object(jn_no_trace_levels)) return 0;
|
|
6219
|
+
let jn_global = jn_no_trace_levels["__global_no_trace__"];
|
|
6220
|
+
if (is_array(jn_global)) {
|
|
6221
|
+
gobj_set_global_no_trace2(4294967295, false);
|
|
6222
|
+
for (let level of jn_global) gobj_set_global_no_trace(level, true);
|
|
6223
|
+
}
|
|
6224
|
+
for (const [name, jn_levels] of Object.entries(jn_no_trace_levels)) {
|
|
6225
|
+
let gclass = gclass_find_by_name(name);
|
|
6226
|
+
if (!gclass) continue;
|
|
6227
|
+
if (!is_array(jn_levels)) {
|
|
6228
|
+
log_error(`${gobj_name(gobj)}: no_trace_levels of ${name} MUST be a list`);
|
|
6229
|
+
continue;
|
|
6230
|
+
}
|
|
6231
|
+
gobj_set_gclass_no_trace(gclass, null, false);
|
|
6232
|
+
for (let level of jn_levels) gobj_set_gclass_no_trace(gclass, level, true);
|
|
6233
|
+
}
|
|
6234
|
+
return 0;
|
|
6235
|
+
}
|
|
6236
|
+
/***************************************************************
|
|
6237
|
+
* Save a scope WHOLE, from the levels in force (see
|
|
6238
|
+
* set_user_gclass_traces()): a saved scope replaces main()'s, so it
|
|
6239
|
+
* has to carry everything that must be in force.
|
|
6240
|
+
***************************************************************/
|
|
6241
|
+
function save_trace_scope(gobj, attr, scope, levels) {
|
|
6242
|
+
let jn_levels = gobj_read_attr(gobj, attr);
|
|
6243
|
+
if (!is_object(jn_levels)) jn_levels = {};
|
|
6244
|
+
jn_levels[scope] = levels;
|
|
6245
|
+
gobj_write_attr(gobj, attr, jn_levels);
|
|
6246
|
+
return gobj_save_persistent_attrs(gobj, attr);
|
|
6247
|
+
}
|
|
6248
|
+
/***************************************************************
|
|
6249
|
+
* "set" as the C command reads it: TRUE / set / 1, FALSE / reset / 0
|
|
6086
6250
|
***************************************************************/
|
|
6251
|
+
function parse_set(value) {
|
|
6252
|
+
if (value === true || value === false) return value;
|
|
6253
|
+
let v = String(value === void 0 || value === null ? "" : value).toLowerCase();
|
|
6254
|
+
if (v === "true" || v === "set") return true;
|
|
6255
|
+
if (v === "false" || v === "reset") return false;
|
|
6256
|
+
if (v === "" || isNaN(Number(v))) return null;
|
|
6257
|
+
return Number(v) ? true : false;
|
|
6258
|
+
}
|
|
6259
|
+
function yuno_prefix() {
|
|
6260
|
+
return `${gobj_yuno_role()}^${gobj_yuno_name()}`;
|
|
6261
|
+
}
|
|
6262
|
+
/***************************
|
|
6263
|
+
* Commands
|
|
6264
|
+
***************************/
|
|
6265
|
+
/***************************************************************
|
|
6266
|
+
* The trace commands of the C kernel's C_YUNO, same names and same
|
|
6267
|
+
* parameters (`level`, `set`, `gclass_name` / `gclass`). Setting a
|
|
6268
|
+
* level saves its scope.
|
|
6269
|
+
***************************************************************/
|
|
6270
|
+
function mt_command_parser(gobj, command, kw, src) {
|
|
6271
|
+
kw = kw || {};
|
|
6272
|
+
switch (command) {
|
|
6273
|
+
case "get-global-trace": return build_command_response(gobj, 0, null, null, gobj_get_global_trace_level());
|
|
6274
|
+
case "get-global-no-trace": return build_command_response(gobj, 0, null, null, gobj_get_global_trace_no_level());
|
|
6275
|
+
case "set-global-trace":
|
|
6276
|
+
case "set-global-no-trace": {
|
|
6277
|
+
let no = command === "set-global-no-trace";
|
|
6278
|
+
let level = kw.level;
|
|
6279
|
+
let set = parse_set(kw.set);
|
|
6280
|
+
if (!level) return build_command_response(gobj, -1, `${yuno_prefix()}: what level?`, null, null);
|
|
6281
|
+
if (set === null) return build_command_response(gobj, -1, `${yuno_prefix()}: bitmask set or re-set?`, null, null);
|
|
6282
|
+
if ((no ? gobj_set_global_no_trace(level, set) : gobj_set_global_trace(level, set)) < 0) return build_command_response(gobj, -1, `${yuno_prefix()}: global trace level not found: ${level}`, null, null);
|
|
6283
|
+
if (no) {
|
|
6284
|
+
save_trace_scope(gobj, "no_trace_levels", "__global_no_trace__", gobj_get_global_trace_no_level());
|
|
6285
|
+
return build_command_response(gobj, 0, null, null, gobj_get_global_trace_no_level());
|
|
6286
|
+
}
|
|
6287
|
+
save_trace_scope(gobj, "trace_levels", "__global_trace__", gobj_get_global_trace_level());
|
|
6288
|
+
return build_command_response(gobj, 0, null, null, gobj_get_global_trace_level());
|
|
6289
|
+
}
|
|
6290
|
+
case "get-gclass-trace":
|
|
6291
|
+
case "get-gclass-no-trace":
|
|
6292
|
+
case "set-gclass-trace":
|
|
6293
|
+
case "set-gclass-no-trace": {
|
|
6294
|
+
let no = command.indexOf("no-trace") >= 0;
|
|
6295
|
+
let gclass_name = kw.gclass_name || kw.gclass || "";
|
|
6296
|
+
let gclass = gclass_find_by_name(gclass_name);
|
|
6297
|
+
if (!gclass) return build_command_response(gobj, -1, `${yuno_prefix()}: what gclass is '${gclass_name}'?`, null, null);
|
|
6298
|
+
if (command.indexOf("get-") === 0) return build_command_response(gobj, 0, null, null, no ? gobj_get_gclass_trace_no_level(gclass) : gobj_get_gclass_trace_level(gclass));
|
|
6299
|
+
let level = kw.level;
|
|
6300
|
+
let set = parse_set(kw.set);
|
|
6301
|
+
if (!level) return build_command_response(gobj, -1, `${yuno_prefix()}: what level?`, null, null);
|
|
6302
|
+
if (set === null) return build_command_response(gobj, -1, `${yuno_prefix()}: bitmask set or re-set?`, null, null);
|
|
6303
|
+
if ((no ? gobj_set_gclass_no_trace(gclass, level, set) : gobj_set_gclass_trace(gclass, level, set)) < 0) return build_command_response(gobj, -1, `${yuno_prefix()}: trace level of ${gclass_name} not found: ${level}`, null, null);
|
|
6304
|
+
if (no) {
|
|
6305
|
+
save_trace_scope(gobj, "no_trace_levels", gclass_name, gobj_get_gclass_trace_no_level(gclass));
|
|
6306
|
+
return build_command_response(gobj, 0, null, null, gobj_get_gclass_trace_no_level(gclass));
|
|
6307
|
+
}
|
|
6308
|
+
save_trace_scope(gobj, "trace_levels", gclass_name, gobj_get_gclass_trace_level2(gclass));
|
|
6309
|
+
return build_command_response(gobj, 0, null, null, gobj_get_gclass_trace_level(gclass));
|
|
6310
|
+
}
|
|
6311
|
+
default: return build_command_response(gobj, -1, `${yuno_prefix()}: command not available: ${command}`, null, null);
|
|
6312
|
+
}
|
|
6313
|
+
}
|
|
6087
6314
|
/***************************
|
|
6088
6315
|
* Actions
|
|
6089
6316
|
***************************/
|
|
@@ -6104,7 +6331,8 @@
|
|
|
6104
6331
|
mt_stop: mt_stop$1,
|
|
6105
6332
|
mt_destroy: mt_destroy$1,
|
|
6106
6333
|
mt_play,
|
|
6107
|
-
mt_pause
|
|
6334
|
+
mt_pause,
|
|
6335
|
+
mt_command_parser
|
|
6108
6336
|
};
|
|
6109
6337
|
/***************************************************************
|
|
6110
6338
|
* Create the GClass
|
|
@@ -6140,7 +6368,7 @@
|
|
|
6140
6368
|
*
|
|
6141
6369
|
* Licence: MIT (http://www.opensource.org/licenses/mit-license)
|
|
6142
6370
|
* Copyright (c) 2014,2024 Niyamaka.
|
|
6143
|
-
* Copyright (c) 2025, ArtGins.
|
|
6371
|
+
* Copyright (c) 2025-2026, ArtGins.
|
|
6144
6372
|
**************************************************************************/
|
|
6145
6373
|
/***************************************************************
|
|
6146
6374
|
* Constants
|
|
@@ -6170,6 +6398,14 @@
|
|
|
6170
6398
|
SDATA(data_type_t.DTP_POINTER, "subscriber", 0, 0, "subscriber of output-events. If null then subscriber is the parent"),
|
|
6171
6399
|
SDATA_END()
|
|
6172
6400
|
];
|
|
6401
|
+
var s_user_trace_level = [
|
|
6402
|
+
["ievents", "Trace inter-events with metadata of kw"],
|
|
6403
|
+
["ievents2", "Trace inter-events with full kw"],
|
|
6404
|
+
["identity-card", "Trace identity_card messages"]
|
|
6405
|
+
];
|
|
6406
|
+
function is_traffic_tracing(gobj) {
|
|
6407
|
+
return gobj_trace_level(gobj) & 3 ? true : false;
|
|
6408
|
+
}
|
|
6173
6409
|
var PRIVATE_DATA = {
|
|
6174
6410
|
url: null,
|
|
6175
6411
|
remote_yuno_name: null,
|
|
@@ -6432,7 +6668,7 @@
|
|
|
6432
6668
|
function send_iev(gobj, iev) {
|
|
6433
6669
|
let priv = gobj.priv;
|
|
6434
6670
|
let msg = JSON.stringify(iev);
|
|
6435
|
-
if (
|
|
6671
|
+
if (is_traffic_tracing(gobj)) {
|
|
6436
6672
|
let url = gobj_read_str_attr(gobj, "url");
|
|
6437
6673
|
let prefix = gobj_name(gobj_yuno()) + " ==> " + url;
|
|
6438
6674
|
let trace_ievent_callback = gobj_read_attr(gobj_yuno(), "trace_ievent_callback");
|
|
@@ -6726,7 +6962,7 @@
|
|
|
6726
6962
|
function ac_on_message(gobj, event, kw, src) {
|
|
6727
6963
|
let url = gobj.priv.url;
|
|
6728
6964
|
let iev_msg = iev_create_from_json(gobj, kw.data);
|
|
6729
|
-
if (
|
|
6965
|
+
if (is_traffic_tracing(gobj)) {
|
|
6730
6966
|
let prefix = gobj_name(gobj_yuno()) + " <== " + url;
|
|
6731
6967
|
let size = kw.data.length;
|
|
6732
6968
|
let trace_ievent_callback = gobj_read_attr(gobj_yuno(), "trace_ievent_callback");
|
|
@@ -6899,7 +7135,7 @@
|
|
|
6899
7135
|
["EV_ON_OPEN_ERROR", event_flag_t.EVF_OUTPUT_EVENT | event_flag_t.EVF_NO_WARN_SUBS],
|
|
6900
7136
|
["EV_TIMEOUT", 0],
|
|
6901
7137
|
[null, 0]
|
|
6902
|
-
], states, gmt, 0, attrs_table, PRIVATE_DATA, 0, 0,
|
|
7138
|
+
], states, gmt, 0, attrs_table, PRIVATE_DATA, 0, 0, s_user_trace_level, gclass_flag_t.gcflag_no_check_output_events);
|
|
6903
7139
|
if (!__gclass__) return -1;
|
|
6904
7140
|
return 0;
|
|
6905
7141
|
}
|
|
@@ -6991,7 +7227,13 @@
|
|
|
6991
7227
|
exports.gobj_flag_t = gobj_flag_t;
|
|
6992
7228
|
exports.gobj_full_name = gobj_full_name;
|
|
6993
7229
|
exports.gobj_gclass_name = gobj_gclass_name;
|
|
7230
|
+
exports.gobj_get_gclass_trace_level = gobj_get_gclass_trace_level;
|
|
7231
|
+
exports.gobj_get_gclass_trace_level2 = gobj_get_gclass_trace_level2;
|
|
7232
|
+
exports.gobj_get_gclass_trace_no_level = gobj_get_gclass_trace_no_level;
|
|
7233
|
+
exports.gobj_get_global_trace_level = gobj_get_global_trace_level;
|
|
7234
|
+
exports.gobj_get_global_trace_no_level = gobj_get_global_trace_no_level;
|
|
6994
7235
|
exports.gobj_global_trace_level = gobj_global_trace_level;
|
|
7236
|
+
exports.gobj_global_trace_no_level = gobj_global_trace_no_level;
|
|
6995
7237
|
exports.gobj_has_attr = gobj_has_attr;
|
|
6996
7238
|
exports.gobj_has_event = gobj_has_event;
|
|
6997
7239
|
exports.gobj_has_output_event = gobj_has_output_event;
|
|
@@ -7033,7 +7275,9 @@
|
|
|
7033
7275
|
exports.gobj_set_gclass_no_trace = gobj_set_gclass_no_trace;
|
|
7034
7276
|
exports.gobj_set_gclass_trace = gobj_set_gclass_trace;
|
|
7035
7277
|
exports.gobj_set_global_no_trace = gobj_set_global_no_trace;
|
|
7278
|
+
exports.gobj_set_global_no_trace2 = gobj_set_global_no_trace2;
|
|
7036
7279
|
exports.gobj_set_global_trace = gobj_set_global_trace;
|
|
7280
|
+
exports.gobj_set_global_trace2 = gobj_set_global_trace2;
|
|
7037
7281
|
exports.gobj_set_gobj_no_trace = gobj_set_gobj_no_trace;
|
|
7038
7282
|
exports.gobj_set_gobj_trace = gobj_set_gobj_trace;
|
|
7039
7283
|
exports.gobj_set_trace_machine_format = gobj_set_trace_machine_format;
|
|
@@ -7131,6 +7375,7 @@
|
|
|
7131
7375
|
exports.kwid_get_ids = kwid_get_ids;
|
|
7132
7376
|
exports.kwid_match_id = kwid_match_id;
|
|
7133
7377
|
exports.kwid_new_dict = kwid_new_dict;
|
|
7378
|
+
exports.kwid_new_list = kwid_new_list;
|
|
7134
7379
|
exports.list2options = list2options;
|
|
7135
7380
|
exports.load_json_file = load_json_file;
|
|
7136
7381
|
exports.log_debug = log_debug;
|