@yuneta/gobj-js 7.25.8 → 7.26.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.
@@ -25,8 +25,8 @@ var gobjJs = (function(exports) {
25
25
  return sprintf.apply(null, [fmt].concat(argv || []));
26
26
  }
27
27
  function sprintf_format(parse_tree, argv) {
28
- var cursor = 1, tree_length = parse_tree.length, arg, output = "", i, k, ph, pad, pad_character, pad_length, is_positive, sign;
29
- for (i = 0; i < tree_length; i++) if (typeof parse_tree[i] === "string") output += parse_tree[i];
28
+ var cursor = 1, tree_length = parse_tree.length, arg, output = "", i = 0, k, ph, pad, pad_character, pad_length, is_positive, sign;
29
+ for (; i < tree_length; i++) if (typeof parse_tree[i] === "string") output += parse_tree[i];
30
30
  else if (typeof parse_tree[i] === "object") {
31
31
  ph = parse_tree[i];
32
32
  if (ph.keys) {
@@ -159,7 +159,7 @@ var gobjJs = (function(exports) {
159
159
  function build_command_response(gobj, result, comment, schema, data) {
160
160
  return {
161
161
  result,
162
- comment: comment || {},
162
+ comment: comment || "",
163
163
  schema: schema || {},
164
164
  data: data || []
165
165
  };
@@ -213,7 +213,7 @@ var gobjJs = (function(exports) {
213
213
  var __global_stats_parser_fn__ = null;
214
214
  var dl_global_event_types = [];
215
215
  var _gclass_register = Object.create(null);
216
- var __jn_services__ = {};
216
+ var __jn_services__ = Object.create(null);
217
217
  var __yuno__ = null;
218
218
  var __default_service__ = null;
219
219
  var __inside__ = 0;
@@ -822,7 +822,8 @@ var gobjJs = (function(exports) {
822
822
  if (!is_object(jn_value)) jn_value = {};
823
823
  break;
824
824
  case data_type_t.DTP_JSON:
825
- if (is_string(svalue)) try {
825
+ if (svalue === "" || svalue === void 0) jn_value = null;
826
+ else if (is_string(svalue)) try {
826
827
  jn_value = JSON.parse(svalue);
827
828
  } catch (error) {
828
829
  log_error(`JSON parse error: ${error.message}`);
@@ -857,11 +858,17 @@ var gobjJs = (function(exports) {
857
858
  break;
858
859
  case data_type_t.DTP_INTEGER:
859
860
  jn_value2 = parseInt(jn_value_);
860
- if (isNaN(jn_value2)) log_error(`${gobj_short_name(gobj)}: attr NaN: ${it.name}`);
861
+ if (isNaN(jn_value2)) {
862
+ log_error(`${gobj_short_name(gobj)}: attr NaN: ${it.name}`);
863
+ return -1;
864
+ }
861
865
  break;
862
866
  case data_type_t.DTP_REAL:
863
867
  jn_value2 = Number(jn_value_);
864
- if (isNaN(jn_value2)) log_error(`${gobj_short_name(gobj)}: attr NaN: ${it.name}`);
868
+ if (isNaN(jn_value2)) {
869
+ log_error(`${gobj_short_name(gobj)}: attr NaN: ${it.name}`);
870
+ return -1;
871
+ }
865
872
  break;
866
873
  case data_type_t.DTP_LIST:
867
874
  if (is_string(jn_value_)) try {
@@ -888,15 +895,11 @@ var gobjJs = (function(exports) {
888
895
  }
889
896
  break;
890
897
  case data_type_t.DTP_JSON:
898
+ jn_value2 = jn_value_;
891
899
  if (is_string(jn_value_)) try {
892
900
  jn_value2 = JSON.parse(jn_value_);
893
901
  } catch (error) {
894
- log_error(`JSON parse error: ${error.message}`);
895
- }
896
- else jn_value2 = jn_value_;
897
- if (!is_array(jn_value2) && !is_object(jn_value2)) {
898
- log_error(`attr must be a json dict/list: ${it.name}`);
899
- return -1;
902
+ jn_value2 = jn_value_;
900
903
  }
901
904
  break;
902
905
  case data_type_t.DTP_POINTER: jn_value2 = jn_value_;
@@ -1201,6 +1204,10 @@ var gobjJs = (function(exports) {
1201
1204
  * find a service
1202
1205
  ************************************************************/
1203
1206
  function gobj_find_service(service_name, verbose) {
1207
+ if (!is_string(service_name)) {
1208
+ log_error(`gobj_find_service(): service name must be a string: ${service_name}`);
1209
+ return null;
1210
+ }
1204
1211
  service_name = service_name.toLowerCase();
1205
1212
  let service_gobj = __jn_services__[service_name];
1206
1213
  if (!service_gobj) {
@@ -1335,7 +1342,7 @@ var gobjJs = (function(exports) {
1335
1342
  let new_kw = kw;
1336
1343
  if (json2sdata(hs, new_kw, -1, gobj.gclass.gclass_flag & gclass_flag_t.gcflag_ignore_unknown_attrs ? 0 : print_attr_not_found, gobj) < 0) {
1337
1344
  log_error(`${gobj_short_name(gobj)} json2data() FAILED`);
1338
- trace_json(new_kw);
1345
+ trace_json_masked(new_kw);
1339
1346
  }
1340
1347
  }
1341
1348
  /************************************************************
@@ -1358,9 +1365,10 @@ var gobjJs = (function(exports) {
1358
1365
  return null;
1359
1366
  }
1360
1367
  if (is_string(parent)) {
1361
- parent = gobj_find_service(parent);
1368
+ const parent_name = parent;
1369
+ parent = gobj_find_service(parent_name);
1362
1370
  if (!parent) {
1363
- log_warning(`parent service not found: ${parent}`);
1371
+ log_warning(`parent service not found: ${parent_name}`);
1364
1372
  return null;
1365
1373
  }
1366
1374
  }
@@ -1473,6 +1481,7 @@ var gobjJs = (function(exports) {
1473
1481
  parent.gclass.gmt.mt_child_removed(parent, gobj);
1474
1482
  }
1475
1483
  if (gobj.gobj_flag & gobj_flag_t.gobj_flag_service) _deregister_service(gobj);
1484
+ if (gobj === __default_service__) __default_service__ = null;
1476
1485
  gobj_unsubscribe_list(gobj, gobj.dl_subscriptions, true);
1477
1486
  gobj_unsubscribe_list(gobj, gobj.dl_subscribings, true);
1478
1487
  if (parent) {
@@ -1818,7 +1827,7 @@ var gobjJs = (function(exports) {
1818
1827
  log_error(`gobj NULL of bad type`);
1819
1828
  return null;
1820
1829
  }
1821
- if (gobj.bottom_gobj) log_warning(`${gobj_short_name(gobj)}: bottom_gobj already set`);
1830
+ if (gobj.bottom_gobj && bottom_gobj) log_warning(`${gobj_short_name(gobj)}: bottom_gobj already set`);
1822
1831
  gobj.bottom_gobj = bottom_gobj;
1823
1832
  }
1824
1833
  /***************************************************************************
@@ -2233,7 +2242,7 @@ var gobjJs = (function(exports) {
2233
2242
  jn_attrs[key] = value;
2234
2243
  if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(key)) gobj.priv[key] = value;
2235
2244
  if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
2236
- if (gobj.mt_writing) gobj.mt_writing(gobj, key);
2245
+ if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, key);
2237
2246
  }
2238
2247
  return 0;
2239
2248
  }
@@ -2257,8 +2266,8 @@ var gobjJs = (function(exports) {
2257
2266
  if (!it.name) continue;
2258
2267
  if (exclude_flag && it.flag & exclude_flag) continue;
2259
2268
  if (include_flag === -1 || it.flag & include_flag) {
2260
- const value = set_default(gobj, gobj.jn_attrs, it);
2261
- if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(it.name)) gobj.priv[it.name] = value;
2269
+ set_default(gobj, gobj.jn_attrs, it);
2270
+ if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(it.name)) gobj.priv[it.name] = gobj.jn_attrs[it.name];
2262
2271
  if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, it.name);
2263
2272
  }
2264
2273
  }
@@ -2292,7 +2301,7 @@ var gobjJs = (function(exports) {
2292
2301
  let hs = gobj_hsdata2(gobj, name, false);
2293
2302
  if (hs) {
2294
2303
  hs[name] = parseBoolean(value);
2295
- if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] = value;
2304
+ if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] = hs[name];
2296
2305
  if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
2297
2306
  if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, name);
2298
2307
  }
@@ -2308,7 +2317,7 @@ var gobjJs = (function(exports) {
2308
2317
  let hs = gobj_hsdata2(gobj, name, false);
2309
2318
  if (hs) {
2310
2319
  hs[name] = parseInt(value);
2311
- if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] = value;
2320
+ if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] = hs[name];
2312
2321
  if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
2313
2322
  if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, name);
2314
2323
  }
@@ -2324,7 +2333,7 @@ var gobjJs = (function(exports) {
2324
2333
  let hs = gobj_hsdata2(gobj, name, false);
2325
2334
  if (hs) {
2326
2335
  hs[name] = String(value);
2327
- if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] = value;
2336
+ if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] = hs[name];
2328
2337
  if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
2329
2338
  if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, name);
2330
2339
  }
@@ -2378,15 +2387,15 @@ var gobjJs = (function(exports) {
2378
2387
  log_error(`${gobj_short_name(gobj)}: gobj_change_parent() BAD TYPE of parent`);
2379
2388
  return -1;
2380
2389
  }
2381
- if (gobj.parent && gobj.parent.mt_child_removed) gobj.parent.mt_child_removed(gobj.parent, gobj);
2390
+ if (gobj.parent && gobj.parent.gclass.gmt.mt_child_removed) gobj.parent.gclass.gmt.mt_child_removed(gobj.parent, gobj);
2382
2391
  if (gobj.parent) {
2383
2392
  _remove_child(gobj.parent, gobj);
2384
2393
  gobj.parent = null;
2385
2394
  }
2386
2395
  _add_child(parent, gobj);
2387
- if (parent.mt_child_added) {
2396
+ if (parent.gclass.gmt.mt_child_added) {
2388
2397
  if (__trace_gobj_create_delete__(gobj)) log_debug(sprintf("👦👦🔵 child_added(%s): %s", gobj_full_name(parent), gobj_short_name(gobj)));
2389
- parent.mt_child_added(parent, gobj);
2398
+ parent.gclass.gmt.mt_child_added(parent, gobj);
2390
2399
  }
2391
2400
  return 0;
2392
2401
  }
@@ -2498,9 +2507,19 @@ var gobjJs = (function(exports) {
2498
2507
  let snapshot = __dl_posted_events__;
2499
2508
  __dl_posted_events__ = [];
2500
2509
  let delivered = 0;
2501
- for (let msg of snapshot) {
2510
+ for (let i = 0; i < snapshot.length; i++) {
2511
+ const msg = snapshot[i];
2502
2512
  if (msg.dst.obflag & (obflag_t.obflag_destroyed | obflag_t.obflag_destroying)) continue;
2503
- gobj_send_event(msg.dst, msg.event, msg.kw, msg.src);
2513
+ try {
2514
+ gobj_send_event(msg.dst, msg.event, msg.kw, msg.src);
2515
+ } catch (e) {
2516
+ __dl_posted_events__ = snapshot.slice(i + 1).concat(__dl_posted_events__);
2517
+ if (__dl_posted_events__.length > 0 && !__posted_events_scheduled__) {
2518
+ __posted_events_scheduled__ = true;
2519
+ setTimeout(gobj_deliver_posted_events, 0);
2520
+ }
2521
+ throw e;
2522
+ }
2504
2523
  delivered++;
2505
2524
  }
2506
2525
  if (__dl_posted_events__.length > 0 && !__posted_events_scheduled__) {
@@ -2550,7 +2569,7 @@ var gobjJs = (function(exports) {
2550
2569
  else trace_machine(sprintf("🔃 mach(%s%s), st: %s, ev: %s, from(%s%s)", !dst.running ? "!!" : "", gobj_short_name(dst), state.state_name, event ? event : "", src && !src.running ? "!!" : "", gobj_short_name(src)));
2551
2570
  if (kw) {
2552
2571
  if (__trace_gobj_ev_kw__(dst)) {
2553
- if (json_object_size(kw)) trace_json(kw);
2572
+ if (json_object_size(kw)) trace_json_masked(kw);
2554
2573
  }
2555
2574
  }
2556
2575
  }
@@ -2570,7 +2589,7 @@ var gobjJs = (function(exports) {
2570
2589
  }
2571
2590
  if (kw) {
2572
2591
  if (__trace_gobj_ev_kw__(dst)) {
2573
- if (json_object_size(kw)) trace_json(kw);
2592
+ if (json_object_size(kw)) trace_json_masked(kw);
2574
2593
  }
2575
2594
  }
2576
2595
  }
@@ -2578,15 +2597,40 @@ var gobjJs = (function(exports) {
2578
2597
  let ret = -1;
2579
2598
  try {
2580
2599
  if (event_action.action) ret = event_action.action(dst, event, kw, src);
2581
- } finally {}
2600
+ } catch (e) {
2601
+ __inside__--;
2602
+ if (!(e && e.__gobj_logged__)) {
2603
+ log_error(`${gobj_short_name(dst)}: action of ${event} in ${dst.current_state.state_name} THREW: ${e && e.stack ? e.stack : e}`);
2604
+ try {
2605
+ e.__gobj_logged__ = true;
2606
+ } catch (e2) {}
2607
+ }
2608
+ throw e;
2609
+ }
2582
2610
  if (tracea && __trace_machine_format__ !== 1 && !(dst.obflag & obflag_t.obflag_destroyed)) trace_machine(sprintf("<- mach(%s%s^%s), st: %s, ev: %s, ret: %d", !dst.running ? "!!" : "", gobj_gclass_name(dst), gobj_name(dst), dst.current_state.state_name, event ? event : "", is_number(ret) ? ret : 0));
2583
2611
  __inside__--;
2584
2612
  return ret;
2585
2613
  }
2586
2614
  var subs_flag_t = Object.freeze({
2587
- __hard_subscription__: 1,
2588
- __own_event__: 2
2615
+ __rename_event_name__: 1,
2616
+ __hard_subscription__: 2,
2617
+ __own_event__: 4
2589
2618
  });
2619
+ /***************************************************************************
2620
+ * The event type of `event_name` in any registered gclass, null if none.
2621
+ * The C kernel's gobj_find_event_type(): any case, gclasses only.
2622
+ ***************************************************************************/
2623
+ function _find_event_type_in_gclasses(event_name) {
2624
+ let lower = String(event_name).toLowerCase();
2625
+ for (let gclass_name in _gclass_register) {
2626
+ let dl = _gclass_register[gclass_name].dl_events;
2627
+ for (let i = 0; i < dl.length; i++) {
2628
+ let event_type = dl[i];
2629
+ if (event_type.event_name && event_type.event_name.toLowerCase() === lower) return event_type;
2630
+ }
2631
+ }
2632
+ return null;
2633
+ }
2590
2634
  var subscription_desc = [
2591
2635
  SDATA(data_type_t.DTP_POINTER, "publisher", 0, null, "publisher gobj"),
2592
2636
  SDATA(data_type_t.DTP_POINTER, "subscriber", 0, null, "subscriber gobj"),
@@ -2619,6 +2663,21 @@ var gobjJs = (function(exports) {
2619
2663
  if (json_size(__config__) > 0) {
2620
2664
  let kw_clone = json_deep_copy(__config__);
2621
2665
  json_object_set_new(subs, "__config__", kw_clone);
2666
+ let renamed_event = kw_get_str(publisher, kw_clone, "__rename_event_name__", "");
2667
+ if (!empty_string(renamed_event)) {
2668
+ let event_type = _find_event_type_in_gclasses(renamed_event);
2669
+ if (event_type) {
2670
+ json_object_set_new(subs, "renamed_event", event_type.event_name);
2671
+ delete kw_clone.__rename_event_name__;
2672
+ subs_flag |= subs_flag_t.__rename_event_name__;
2673
+ let kw_global = kw_get_dict(publisher, subs, "__global__", null);
2674
+ if (!is_object(kw_global)) {
2675
+ kw_global = {};
2676
+ json_object_set_new(subs, "__global__", kw_global);
2677
+ }
2678
+ kw_global.__original_event_name__ = event;
2679
+ } else log_error(`${gobj_short_name(publisher)}: EVENT NOT FOUND (__rename_event_name__: ${renamed_event})`);
2680
+ }
2622
2681
  if (kw_has_key(kw_clone, "__hard_subscription__")) {
2623
2682
  let hard_subscription = kw_get_bool(publisher, kw_clone, "__hard_subscription__", false);
2624
2683
  json_object_del(kw_clone, "__hard_subscription__");
@@ -2638,9 +2697,52 @@ var gobjJs = (function(exports) {
2638
2697
  return subs;
2639
2698
  }
2640
2699
  /***************************************************************************
2700
+ * The kw to find the subscriptions a (un)subscription `kw` names: `kw` as
2701
+ * _create_subscription() stores it, as the C kernel's
2702
+ * _subscription_match_kw(). The three `__config__` keys the framework
2703
+ * reads (__hard_subscription__, __own_event__, __rename_event_name__)
2704
+ * become the subs_flag and are taken out of the stored `__config__`, and
2705
+ * a renamed event adds `__original_event_name__` to the stored
2706
+ * `__global__`: with `kw` as it came, the same kw matched no subscription,
2707
+ * a repeat of it was made twice (the subscriber got each event twice) and
2708
+ * its withdrawal found nothing. A known renamed event is returned in
2709
+ * `renamed_event`, which _match_subscription() compares: a plain and a
2710
+ * renamed subscription, or two renames of one event, are two. A rename
2711
+ * that no gclass declares stays in the stored `__config__`, and in this
2712
+ * one. Up to gobj-js 7.25.8 the kw was compared as it came, and
2713
+ * `__rename_event_name__` always stayed in the stored `__config__`: a
2714
+ * plain kw with the rest of that __config__ found no repeat (two
2715
+ * subscriptions where C has one).
2716
+ * Return {kw, renamed_event}; renamed_event is "" when kw does not rename.
2717
+ ***************************************************************************/
2718
+ function _subscription_match_kw(kw, event) {
2719
+ let __config__ = kw ? kw.__config__ : null;
2720
+ if (!is_object(__config__) || !kw_has_key(__config__, "__hard_subscription__") && !kw_has_key(__config__, "__own_event__") && !kw_has_key(__config__, "__rename_event_name__")) return {
2721
+ kw,
2722
+ renamed_event: ""
2723
+ };
2724
+ let kw_match = Object.assign({}, kw);
2725
+ let config_match = Object.assign({}, __config__);
2726
+ kw_match.__config__ = config_match;
2727
+ let renamed_event = "";
2728
+ let rename = config_match.__rename_event_name__;
2729
+ let event_type = typeof rename === "string" && !empty_string(rename) ? _find_event_type_in_gclasses(rename) : null;
2730
+ if (event_type) {
2731
+ renamed_event = event_type.event_name;
2732
+ delete config_match.__rename_event_name__;
2733
+ if (event && json_size(kw_match.__global__) > 0) kw_match.__global__ = Object.assign({}, kw_match.__global__, { __original_event_name__: event });
2734
+ }
2735
+ delete config_match.__hard_subscription__;
2736
+ delete config_match.__own_event__;
2737
+ return {
2738
+ kw: kw_match,
2739
+ renamed_event
2740
+ };
2741
+ }
2742
+ /***************************************************************************
2641
2743
  * Match subscription
2642
2744
  ***************************************************************************/
2643
- function _match_subscription(subs, publisher, event, kw, subscriber) {
2745
+ function _match_subscription(subs, publisher, event, renamed_event, kw, subscriber) {
2644
2746
  let __config__ = kw_get_dict(publisher, kw, "__config__", null);
2645
2747
  let __global__ = kw_get_dict(publisher, kw, "__global__", null);
2646
2748
  let __local__ = kw_get_dict(publisher, kw, "__local__", null);
@@ -2655,6 +2757,9 @@ var gobjJs = (function(exports) {
2655
2757
  if (event) {
2656
2758
  if (event !== kw_get_str(null, subs, "event", "")) match = false;
2657
2759
  }
2760
+ if (renamed_event) {
2761
+ if (renamed_event !== kw_get_str(null, subs, "renamed_event", "")) match = false;
2762
+ }
2658
2763
  if (json_size(__config__) > 0) {
2659
2764
  let kw_config = kw_get_dict(null, subs, "__config__", null);
2660
2765
  if (json_size(kw_config) > 0) {
@@ -2689,26 +2794,29 @@ var gobjJs = (function(exports) {
2689
2794
  * kw (__config__, __global__, __local__, __filter__),
2690
2795
  * subscriber
2691
2796
  ***************************************************************************/
2692
- function _find_subscriptions(dl_subs, publisher, event, kw, subscriber) {
2797
+ function _find_subscriptions(dl_subs, publisher, event, renamed_event, kw, subscriber) {
2693
2798
  let iter = [];
2694
2799
  for (let i = 0; i < dl_subs.length; i++) {
2695
2800
  let subs = dl_subs[i];
2696
- if (_match_subscription(subs, publisher, event, kw, subscriber)) json_array_append(iter, subs);
2801
+ if (_match_subscription(subs, publisher, event, renamed_event, kw, subscriber)) json_array_append(iter, subs);
2697
2802
  }
2698
2803
  return iter;
2699
2804
  }
2700
2805
  /***************************************************************************
2701
- * Find idx of subscription in dl_subs, -1 not found
2806
+ * Find idx of the subscription `subs` itself in dl_subs, -1 not found.
2807
+ * Up to gobj-js 7.25.8 it was the first entry whose fields matched `subs`:
2808
+ * a subscription already removed took a live one that matched it (a plain
2809
+ * one matches every other of its event and subscriber).
2702
2810
  ***************************************************************************/
2703
- function _get_subs_idx(dl_subs, publisher, event, kw, subscriber) {
2704
- for (let i = 0; i < dl_subs.length; i++) {
2705
- let subs = dl_subs[i];
2706
- if (_match_subscription(subs, publisher, event, kw, subscriber)) return i;
2707
- }
2708
- return -1;
2811
+ function _get_subs_idx(dl_subs, subs) {
2812
+ return dl_subs.indexOf(subs);
2709
2813
  }
2710
2814
  /***************************************************************************
2711
- * Delete subscription in publisher and subscriber
2815
+ * Delete subscription in publisher and subscriber.
2816
+ * Return 0 removed, -1 a hard one kept (only `force` removes it), 1 it
2817
+ * was not there any more: already removed, as a stale reference is, or by
2818
+ * the mt_subscription_deleted() of an earlier entry of the same list. The
2819
+ * caller says which is an error. As in C.
2712
2820
  ***************************************************************************/
2713
2821
  function _delete_subscription(gobj, subs, force, not_inform) {
2714
2822
  let publisher = kw_get_pointer(gobj, subs, "publisher", null, kw_flag_t.KW_REQUIRED);
@@ -2717,7 +2825,12 @@ var gobjJs = (function(exports) {
2717
2825
  if (kw_get_int(gobj, subs, "subs_flag", null, kw_flag_t.KW_REQUIRED) & subs_flag_t.__hard_subscription__ ? 1 : 0) {
2718
2826
  if (!force) return -1;
2719
2827
  }
2720
- if (__trace_gobj_subscriptions__(subscriber) || __trace_gobj_subscriptions__(publisher)) {
2828
+ let tracea = __trace_gobj_subscriptions__(subscriber) || __trace_gobj_subscriptions__(publisher);
2829
+ if (_get_subs_idx(publisher.dl_subscriptions, subs) < 0) {
2830
+ if (tracea) trace_machine(sprintf("💜💜👎 unsubscribing event '%s': publisher %s, subscriber'%s', ALREADY REMOVED", event ? event : "", gobj_short_name(publisher), gobj_short_name(subscriber)));
2831
+ return 1;
2832
+ }
2833
+ if (tracea) {
2721
2834
  trace_machine(sprintf("💜💜👎 unsubscribing event '%s': publisher %s, subscriber'%s'", event ? event : "", gobj_short_name(publisher), gobj_short_name(subscriber)));
2722
2835
  trace_json(subs);
2723
2836
  }
@@ -2726,13 +2839,13 @@ var gobjJs = (function(exports) {
2726
2839
  if (publisher.gclass.gmt.mt_subscription_deleted) publisher.gclass.gmt.mt_subscription_deleted(publisher, subs);
2727
2840
  }
2728
2841
  }
2729
- let idx = _get_subs_idx(publisher.dl_subscriptions, publisher, event, subs, subscriber);
2842
+ let idx = _get_subs_idx(publisher.dl_subscriptions, subs);
2730
2843
  if (idx >= 0) json_array_remove(publisher.dl_subscriptions, idx);
2731
2844
  else {
2732
2845
  log_error(`${gobj_short_name(gobj)}: subscription in publisher not found`);
2733
2846
  trace_json(subs);
2734
2847
  }
2735
- idx = _get_subs_idx(subscriber.dl_subscribings, publisher, event, subs, subscriber);
2848
+ idx = _get_subs_idx(subscriber.dl_subscribings, subs);
2736
2849
  if (idx >= 0) json_array_remove(subscriber.dl_subscribings, idx);
2737
2850
  else {
2738
2851
  log_error(`${gobj_short_name(gobj)}: subscription in subscriber not found`);
@@ -2775,7 +2888,17 @@ var gobjJs = (function(exports) {
2775
2888
  }
2776
2889
  }
2777
2890
  } else event = "";
2778
- let dl_subs = _find_subscriptions(publisher.dl_subscriptions, publisher, event, kw, subscriber);
2891
+ let match = _subscription_match_kw(kw, event);
2892
+ let dl_subs = _find_subscriptions(publisher.dl_subscriptions, publisher, event, match.renamed_event, match.kw, subscriber);
2893
+ let subs_hard = null;
2894
+ for (let i = 0; i < dl_subs.length; i++) if (kw_get_int(publisher, dl_subs[i], "subs_flag", 0, kw_flag_t.KW_REQUIRED) & subs_flag_t.__hard_subscription__) {
2895
+ subs_hard = dl_subs[i];
2896
+ break;
2897
+ }
2898
+ if (subs_hard) {
2899
+ log_warning(`${gobj_short_name(publisher)}: Hard subscription REPEATED, the one there is kept and returned (event: ${event}, subscriber: ${gobj_short_name(subscriber)})`);
2900
+ return subs_hard;
2901
+ }
2779
2902
  if (json_array_size(dl_subs) > 0) {
2780
2903
  log_error(`${gobj_short_name(publisher)}: ${json_array_size(dl_subs)} subscription(s) REPEATED, will be deleted and override`);
2781
2904
  trace_json(dl_subs, "subscription REPEATED");
@@ -2790,7 +2913,7 @@ var gobjJs = (function(exports) {
2790
2913
  json_array_append(subscriber.dl_subscribings, subs);
2791
2914
  if (__trace_gobj_subscriptions__(subscriber) || __trace_gobj_subscriptions__(publisher)) {
2792
2915
  trace_machine(sprintf("💜💜👍 subscribing event '%s', publisher '%s', subscriber %s", event ? event : "", gobj_short_name(publisher), gobj_short_name(subscriber)));
2793
- if (kw && (__trace_gobj_ev_kw__(subscriber) || __trace_gobj_ev_kw__(publisher))) trace_json(kw);
2916
+ if (kw && (__trace_gobj_ev_kw__(subscriber) || __trace_gobj_ev_kw__(publisher))) trace_json_masked(kw);
2794
2917
  }
2795
2918
  if (publisher.gclass.gmt.mt_subscription_added) {
2796
2919
  let result = publisher.gclass.gmt.mt_subscription_added(publisher, subs);
@@ -2832,16 +2955,22 @@ var gobjJs = (function(exports) {
2832
2955
  }
2833
2956
  }
2834
2957
  } else event = "";
2835
- let dl_subs = _find_subscriptions(publisher.dl_subscriptions, publisher, event, kw, subscriber);
2958
+ let match = _subscription_match_kw(kw, event);
2959
+ let dl_subs = _find_subscriptions(publisher.dl_subscriptions, publisher, event, match.renamed_event, match.kw, subscriber);
2836
2960
  let deleted = 0;
2961
+ let kept_hard = 0;
2962
+ let already_removed = 0;
2837
2963
  for (let i = 0; i < dl_subs.length; i++) {
2838
2964
  let subs = dl_subs[i];
2839
- _delete_subscription(publisher, subs, false, false);
2840
- deleted++;
2965
+ let ret = _delete_subscription(publisher, subs, false, false);
2966
+ if (ret === 0) deleted++;
2967
+ else if (ret < 0) kept_hard++;
2968
+ else already_removed++;
2841
2969
  }
2842
- if (!deleted) {
2970
+ if (kept_hard) log_warning(`${gobj_short_name(publisher)}: Hard subscription not removed, only gobj_unsubscribe_list() with force removes it (event: ${event}, hard: ${kept_hard})`);
2971
+ else if (!deleted && !already_removed) {
2843
2972
  log_warning(`${gobj_short_name(publisher)}: No subscription found`);
2844
- trace_json(kw, "No subscription found");
2973
+ trace_json_masked(kw, "No subscription found");
2845
2974
  }
2846
2975
  return 0;
2847
2976
  }
@@ -2850,10 +2979,12 @@ var gobjJs = (function(exports) {
2850
2979
  ***************************************************************************/
2851
2980
  function gobj_unsubscribe_list(gobj, dl_subs, force) {
2852
2981
  let dl = [...dl_subs];
2982
+ let already_removed = 0;
2853
2983
  for (let i = 0; i < dl.length; i++) {
2854
2984
  let subs = dl[i];
2855
- _delete_subscription(gobj, subs, force, false);
2985
+ if (_delete_subscription(gobj, subs, force, false) > 0) already_removed++;
2856
2986
  }
2987
+ if (already_removed) log_warning(`${gobj_short_name(gobj)}: Subscription(s) already removed, nothing to remove (count: ${already_removed})`);
2857
2988
  return 0;
2858
2989
  }
2859
2990
  /***************************************************************************
@@ -2865,7 +2996,7 @@ var gobjJs = (function(exports) {
2865
2996
  ***************************************************************************/
2866
2997
  function gobj_find_subscriptions(publisher, event, kw, subscriber) {
2867
2998
  if (kw == null) kw = {};
2868
- return _find_subscriptions(publisher.dl_subscriptions, publisher, event, kw, subscriber);
2999
+ return _find_subscriptions(publisher.dl_subscriptions, publisher, event, null, kw, subscriber);
2869
3000
  }
2870
3001
  /***************************************************************************
2871
3002
  *
@@ -2904,7 +3035,7 @@ var gobjJs = (function(exports) {
2904
3035
  * subscriber
2905
3036
  ***************************************************************************/
2906
3037
  function gobj_find_subscribings(subscriber, event, kw, publisher) {
2907
- return _find_subscriptions(subscriber.dl_subscribings, publisher, event, kw, subscriber);
3038
+ return _find_subscriptions(subscriber.dl_subscribings, publisher, event, null, kw, subscriber);
2908
3039
  }
2909
3040
  /***************************************************************************
2910
3041
  * Return the sum of returns of gobj_send_event
@@ -2930,7 +3061,7 @@ var gobjJs = (function(exports) {
2930
3061
  if (tracea) {
2931
3062
  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));
2932
3063
  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 : "", ""));
2933
- if (__trace_gobj_ev_kw__(publisher) && json_object_size(kw)) trace_json(kw);
3064
+ if (__trace_gobj_ev_kw__(publisher) && json_object_size(kw)) trace_json_masked(kw);
2934
3065
  }
2935
3066
  if (publisher.gclass.gmt.mt_publish_event) {
2936
3067
  let topublish = publisher.gclass.gmt.mt_publish_event(publisher, event, kw);
@@ -2955,6 +3086,8 @@ var gobjJs = (function(exports) {
2955
3086
  let __global__ = kw_get_dict(publisher, subs, "__global__", null, 0);
2956
3087
  let __local__ = kw_get_dict(publisher, subs, "__local__", null, 0);
2957
3088
  let __filter__ = kw_get_dict_value(publisher, subs, "__filter__", null, 0);
3089
+ let event_name = subs.renamed_event;
3090
+ if (empty_string(event_name)) event_name = event;
2958
3091
  let topublish = 1;
2959
3092
  if (publisher.gclass.gmt.mt_publication_filter) topublish = publisher.gclass.gmt.mt_publication_filter(publisher, event, kw, subscriber);
2960
3093
  else if (json_size(__filter__) > 0) {
@@ -2978,11 +3111,11 @@ var gobjJs = (function(exports) {
2978
3111
  if (__config__) {}
2979
3112
  if (json_size(__global__) > 0) json_object_update(kw2publish, json_deep_copy(__global__));
2980
3113
  if (tracea) {
2981
- if (__trace_machine_format__ === 1) trace_machine(sprintf("🔝🔄 %s (%s) %s%s", event ? event : "", event ? event : "", !subscriber.running ? "!!" : "", gobj_short_name(subscriber)));
2982
- else trace_machine(sprintf("🔝🔄 mach(%s%s), st: %s, ev: %s, from(%s%s)", !subscriber.running ? "!!" : "", gobj_short_name(subscriber), gobj_current_state(subscriber), event ? event : "", publisher && !publisher.running ? "!!" : "", gobj_short_name(publisher)));
2983
- if (__trace_gobj_ev_kw__(publisher) && json_object_size(kw2publish)) trace_json(kw2publish);
3114
+ if (__trace_machine_format__ === 1) trace_machine(sprintf("🔝🔄 %s (%s) %s%s", event ? event : "", event_name ? event_name : "", !subscriber.running ? "!!" : "", gobj_short_name(subscriber)));
3115
+ else trace_machine(sprintf("🔝🔄 mach(%s%s), st: %s, ev: %s (%s), from(%s%s)", !subscriber.running ? "!!" : "", gobj_short_name(subscriber), gobj_current_state(subscriber), event ? event : "", event_name ? event_name : "", publisher && !publisher.running ? "!!" : "", gobj_short_name(publisher)));
3116
+ if (__trace_gobj_ev_kw__(publisher) && json_object_size(kw2publish)) trace_json_masked(kw2publish);
2984
3117
  }
2985
- let ret_ = gobj_send_event(subscriber, event, kw2publish, publisher);
3118
+ let ret_ = gobj_send_event(subscriber, event_name, kw2publish, publisher);
2986
3119
  if (ret_ < 0 && subs_flag & subs_flag_t.__own_event__) {
2987
3120
  sent_count = -1;
2988
3121
  break;
@@ -3006,8 +3139,9 @@ var gobjJs = (function(exports) {
3006
3139
  return -1;
3007
3140
  }
3008
3141
  if (is_commands_tracing(gobj) || is_machine_tracing(gobj, null) && !is_machine_not_tracing(src, null)) {
3009
- trace_machine(sprintf("🌀🌀 mach(%s%s), cmd: %s, src: %s", !gobj_is_running(gobj) ? "!!" : "", gobj_short_name(gobj), command, gobj_short_name(src)));
3010
- if (__trace_gobj_ev_kw__(gobj)) trace_json(kw);
3142
+ let command_shown = mask_secrets_inline(command);
3143
+ trace_machine(sprintf("🌀🌀 mach(%s%s), cmd: %s, src: %s", !gobj_is_running(gobj) ? "!!" : "", gobj_short_name(gobj), command_shown !== null ? command_shown : command, gobj_short_name(src)));
3144
+ if (__trace_gobj_ev_kw__(gobj)) trace_json_masked(kw);
3011
3145
  }
3012
3146
  if (gobj.gclass.gmt.mt_command_parser) return gobj.gclass.gmt.mt_command_parser(gobj, command, kw, src);
3013
3147
  if (gobj.gclass.command_table) {
@@ -3143,10 +3277,22 @@ var gobjJs = (function(exports) {
3143
3277
  f_warning = _console.warn;
3144
3278
  }
3145
3279
  }
3280
+ /************************************************************
3281
+ * JSON.stringify for a log line: a circular object (a gobj,
3282
+ * a DOM node) must not make the log call itself throw.
3283
+ ************************************************************/
3284
+ function log_stringify(v) {
3285
+ try {
3286
+ return JSON.stringify(v);
3287
+ } catch (e) {
3288
+ return String(v);
3289
+ }
3290
+ }
3146
3291
  function format_log(format) {
3147
3292
  const args = Array.prototype.slice.call(arguments);
3148
3293
  let output = "";
3149
3294
  if (typeof format === "string") {
3295
+ if (args.length === 1) return format;
3150
3296
  let i = 1;
3151
3297
  output = format.replace(/%[sdifoO]/g, (match) => {
3152
3298
  const val = args[i++];
@@ -3156,17 +3302,17 @@ var gobjJs = (function(exports) {
3156
3302
  case "%i": return parseInt(val);
3157
3303
  case "%f": return parseFloat(val);
3158
3304
  case "%o":
3159
- case "%O": return typeof val === "object" ? JSON.stringify(val) : String(val);
3305
+ case "%O": return typeof val === "object" ? log_stringify(val) : String(val);
3160
3306
  default: return match;
3161
3307
  }
3162
3308
  });
3163
- const rest = args.slice(i).map((arg) => typeof arg === "object" ? JSON.stringify(arg) : String(arg));
3309
+ const rest = args.slice(i).map((arg) => typeof arg === "object" ? log_stringify(arg) : String(arg));
3164
3310
  if (rest.length > 0) output += " " + rest.join(" ");
3165
- } else output = args.map((arg) => typeof arg === "object" ? JSON.stringify(arg) : String(arg)).join(" ");
3311
+ } else output = args.map((arg) => typeof arg === "object" ? log_stringify(arg) : String(arg)).join(" ");
3166
3312
  return output;
3167
3313
  }
3168
- function log_error(format) {
3169
- let msg = format_log(format);
3314
+ function log_error(format, ...args) {
3315
+ let msg = format_log(format, ...args);
3170
3316
  let hora = current_timestamp();
3171
3317
  if (f_error) {
3172
3318
  if (f_error === _console.error) {
@@ -3178,8 +3324,8 @@ var gobjJs = (function(exports) {
3178
3324
  }
3179
3325
  emit_log_callback("error", msg, hora);
3180
3326
  }
3181
- function log_warning(format) {
3182
- let msg = format_log(format);
3327
+ function log_warning(format, ...args) {
3328
+ let msg = format_log(format, ...args);
3183
3329
  let hora = current_timestamp();
3184
3330
  if (f_warning) {
3185
3331
  if (f_warning === _console.warn) {
@@ -3191,24 +3337,24 @@ var gobjJs = (function(exports) {
3191
3337
  }
3192
3338
  emit_log_callback("warning", msg, hora);
3193
3339
  }
3194
- function log_info(format) {
3195
- let msg = format_log(format);
3340
+ function log_info(format, ...args) {
3341
+ let msg = format_log(format, ...args);
3196
3342
  let hora = current_timestamp();
3197
3343
  if (f_info) {
3198
3344
  if (console_wants("info", msg)) f_info("%c" + hora + " INFO: " + String(msg), "color:cyan");
3199
3345
  }
3200
3346
  emit_log_callback("info", msg, hora);
3201
3347
  }
3202
- function log_debug(format) {
3203
- let msg = format_log(format);
3348
+ function log_debug(format, ...args) {
3349
+ let msg = format_log(format, ...args);
3204
3350
  let hora = current_timestamp();
3205
3351
  if (f_debug) {
3206
3352
  if (console_wants("debug", msg)) f_debug("%c" + hora + " DEBUG: " + String(msg), "color:silver");
3207
3353
  }
3208
3354
  emit_log_callback("debug", msg, hora);
3209
3355
  }
3210
- function trace_msg(format) {
3211
- let msg = format_log(format);
3356
+ function trace_msg(format, ...args) {
3357
+ let msg = format_log(format, ...args);
3212
3358
  let hora = current_timestamp();
3213
3359
  if (f_debug) {
3214
3360
  if (console_wants("msg", msg)) f_debug("%c" + hora + " MSG: " + String(msg), "color:cyan");
@@ -3223,6 +3369,268 @@ var gobjJs = (function(exports) {
3223
3369
  emit_log_callback("json", jn, current_timestamp());
3224
3370
  }
3225
3371
  /************************************************************
3372
+ * The names of the secrets (is_secret_name()). The same lists
3373
+ * as the C kernel's helpers.c: a name that holds one of these
3374
+ * (any case) is a secret.
3375
+ ************************************************************/
3376
+ var SECRET_NAME_PARTS = [
3377
+ "passw",
3378
+ "pwd",
3379
+ "passphrase",
3380
+ "secret",
3381
+ "token",
3382
+ "jwt",
3383
+ "bearer",
3384
+ "authorization",
3385
+ "cookie",
3386
+ "credential",
3387
+ "salt"
3388
+ ];
3389
+ var SECRET_NAME_JOINED = [
3390
+ "apikey",
3391
+ "sessionid",
3392
+ "sessionkey",
3393
+ "authdata"
3394
+ ];
3395
+ var NOT_SECRET_SEGMENTS = /* @__PURE__ */ new Set([
3396
+ "endpoint",
3397
+ "url",
3398
+ "uri",
3399
+ "domain",
3400
+ "path",
3401
+ "file",
3402
+ "public",
3403
+ "pub",
3404
+ "count",
3405
+ "counts",
3406
+ "type",
3407
+ "name",
3408
+ "len",
3409
+ "length",
3410
+ "size",
3411
+ "max",
3412
+ "min",
3413
+ "ttl",
3414
+ "timeout",
3415
+ "expiry",
3416
+ "expires",
3417
+ "mode"
3418
+ ]);
3419
+ /************************************************************
3420
+ * TRUE if `name` is the name of a secret: a password, a token,
3421
+ * a key... Any case. As the C kernel's is_secret_name().
3422
+ ************************************************************/
3423
+ function is_secret_name(name) {
3424
+ if (typeof name !== "string" || name.length < 3) return false;
3425
+ let lower = name.toLowerCase();
3426
+ let hit = false;
3427
+ for (const part of SECRET_NAME_PARTS) if (lower.indexOf(part) >= 0) {
3428
+ hit = true;
3429
+ break;
3430
+ }
3431
+ if (!hit) {
3432
+ let joined = lower.replace(/[_\-. \t]/g, "");
3433
+ for (const part of SECRET_NAME_JOINED) if (joined.indexOf(part) >= 0) {
3434
+ hit = true;
3435
+ break;
3436
+ }
3437
+ }
3438
+ if (!hit) hit = lower.indexOf("priv") >= 0 && lower.indexOf("key") >= 0;
3439
+ if (!hit) return false;
3440
+ for (const segment of lower.split(/[_\-. \t]/)) if (NOT_SECRET_SEGMENTS.has(segment)) return false;
3441
+ return true;
3442
+ }
3443
+ /************************************************************
3444
+ * Where an unquoted secret value that begins at `p` ends: at
3445
+ * the end, at the quote that closes an outer quoted value, or
3446
+ * before the next "word=" -- a plain word after a blank is still
3447
+ * part of it ("password=correct horse battery", "password=
3448
+ * hunter2"). As the C kernel's inline_secret_value_end().
3449
+ ************************************************************/
3450
+ function inline_secret_value_end(str, p, outer) {
3451
+ const blank = (c) => c === " " || c === " ";
3452
+ const closes_outer = (i) => outer && str[i] === outer && (i + 1 >= str.length || blank(str[i + 1]));
3453
+ let end = p;
3454
+ while (true) {
3455
+ while (end < str.length && !blank(str[end])) {
3456
+ if (closes_outer(end)) return end;
3457
+ end++;
3458
+ }
3459
+ if (end >= str.length) return end;
3460
+ let w = end;
3461
+ while (w < str.length && blank(str[w])) w++;
3462
+ if (w >= str.length || closes_outer(w)) return end;
3463
+ for (let e = w; e < str.length && !blank(str[e]) && !closes_outer(e); e++) if (str[e] === "=" && e > w) return end;
3464
+ end = w;
3465
+ }
3466
+ }
3467
+ /************************************************************
3468
+ * A text (a command line) with the value of every "name=value"
3469
+ * whose name is a secret's written as "********", quoted or not
3470
+ * (and the "value" of a write-attr whose attribute names a
3471
+ * secret). The rest as it is. Return null when there was nothing
3472
+ * to mask. As the C kernel's mask_secrets_inline().
3473
+ ************************************************************/
3474
+ var MASK_MAX_NAME = 128;
3475
+ var MASK_MAX_BYTES = 4194304;
3476
+ var MASK_TOO_LARGE = "<not shown: too large to mask>";
3477
+ function mask_secrets_inline(str) {
3478
+ if (typeof str !== "string" || str.indexOf("=") < 0) return null;
3479
+ if (str.length > MASK_MAX_BYTES) return MASK_TOO_LARGE;
3480
+ let value_is_secret = false;
3481
+ let re_attr = /(^|[ \t])attribute=["']?([^ \t"']*)/g;
3482
+ let m;
3483
+ while ((m = re_attr.exec(str)) !== null) if (is_secret_name(m[2].slice(-128))) value_is_secret = true;
3484
+ let parts = [];
3485
+ let copied = 0;
3486
+ let changed = false;
3487
+ let outer = "";
3488
+ let word = 0;
3489
+ let p = 0;
3490
+ const is_blank_or_end = (i) => i >= str.length || str[i] === " " || str[i] === " ";
3491
+ while (p < str.length) {
3492
+ let c = str[p];
3493
+ if (c === " " || c === " ") {
3494
+ p++;
3495
+ word = p;
3496
+ continue;
3497
+ }
3498
+ if (c === "\"" || c === "'") {
3499
+ if (!outer && (p === 0 || str[p - 1] === " " || str[p - 1] === " " || str[p - 1] === "=")) outer = c;
3500
+ else if (c === outer && is_blank_or_end(p + 1)) outer = "";
3501
+ }
3502
+ if (c !== "=") {
3503
+ p++;
3504
+ continue;
3505
+ }
3506
+ let name = str.substring(Math.max(word, p - MASK_MAX_NAME), p);
3507
+ word = p + 1;
3508
+ if (!(is_secret_name(name) || value_is_secret && name.toLowerCase() === "value")) {
3509
+ p++;
3510
+ continue;
3511
+ }
3512
+ p++;
3513
+ let quote = str[p] === "\"" || str[p] === "'" ? str[p] : "";
3514
+ let end;
3515
+ if (quote) {
3516
+ end = p + 1;
3517
+ while (end < str.length && str[end] !== quote) end++;
3518
+ if (str[end] === quote) end++;
3519
+ } else end = inline_secret_value_end(str, p, outer);
3520
+ if (end > p) {
3521
+ parts.push(str.substring(copied, p));
3522
+ parts.push("********");
3523
+ copied = end;
3524
+ changed = true;
3525
+ }
3526
+ p = end;
3527
+ word = p;
3528
+ }
3529
+ if (!changed) return null;
3530
+ parts.push(str.substring(copied));
3531
+ return parts.join("");
3532
+ }
3533
+ /************************************************************
3534
+ * A json as a log or a trace may show it: at any depth, the
3535
+ * value of a key with a secret's name is "********", whatever
3536
+ * its type (not an absent one, a null or an empty string); so is
3537
+ * the "value" of a dict whose "attribute" names a secret; and a
3538
+ * string is masked as mask_secrets_inline(). Return a masked
3539
+ * copy, or `jn` itself when there was nothing to mask. As the C
3540
+ * kernel's json_mask_secrets().
3541
+ *
3542
+ * Only JSON is walked: plain objects (their prototype is
3543
+ * Object.prototype or null) and arrays. Anything else -- a gobj,
3544
+ * a DOM node, a class instance, a typed array, a function -- is
3545
+ * passed as it is, never walked, as trace_json() always showed it
3546
+ * (a kw may carry a gobj: its parent and children make a cycle).
3547
+ * A plain object met twice is masked once, the same everywhere; a
3548
+ * cycle back to one is "<cycle>"; below MASK_MAX_DEPTH levels
3549
+ * (64, as in C) nothing is shown.
3550
+ * It never throws: a failure is the placeholder below.
3551
+ ************************************************************/
3552
+ var MASK_MAX_DEPTH = 64;
3553
+ var MASK_FAILED = "<not shown: the masking failed>";
3554
+ function is_plain_object(value) {
3555
+ if (value === null || typeof value !== "object") return false;
3556
+ let proto = Object.getPrototypeOf(value);
3557
+ return proto === Object.prototype || proto === null;
3558
+ }
3559
+ var MASK_IN_PROGRESS = Symbol("mask-in-progress");
3560
+ function _json_mask_secrets(jn, memo, depth, budget) {
3561
+ if (typeof jn === "string") {
3562
+ if (jn.length > budget.left) {
3563
+ budget.left = 0;
3564
+ return MASK_TOO_LARGE;
3565
+ }
3566
+ budget.left -= jn.length;
3567
+ let masked = mask_secrets_inline(jn);
3568
+ return masked !== null ? masked : jn;
3569
+ }
3570
+ let is_array = Array.isArray(jn);
3571
+ if (!is_array && !is_plain_object(jn)) return jn;
3572
+ if (budget.left <= 0) return MASK_TOO_LARGE;
3573
+ if (memo.has(jn)) {
3574
+ let seen = memo.get(jn);
3575
+ return seen === MASK_IN_PROGRESS ? "<cycle>" : seen;
3576
+ }
3577
+ if (depth >= MASK_MAX_DEPTH) return "<deeper not shown>";
3578
+ budget.left -= 1;
3579
+ memo.set(jn, MASK_IN_PROGRESS);
3580
+ let changed = false;
3581
+ let truncated = false;
3582
+ let result;
3583
+ if (is_array) {
3584
+ result = [];
3585
+ for (let i = 0; i < jn.length; i++) {
3586
+ if (budget.left <= 0) {
3587
+ truncated = true;
3588
+ break;
3589
+ }
3590
+ budget.left -= 1;
3591
+ let shown = _json_mask_secrets(jn[i], memo, depth + 1, budget);
3592
+ if (shown !== jn[i]) changed = true;
3593
+ result.push(shown);
3594
+ }
3595
+ if (truncated) result.push(MASK_TOO_LARGE);
3596
+ } else {
3597
+ result = Object.create(Object.getPrototypeOf(jn));
3598
+ let value_is_secret = typeof jn.attribute === "string" && is_secret_name(jn.attribute.slice(-128));
3599
+ for (const key in jn) {
3600
+ if (!Object.prototype.hasOwnProperty.call(jn, key)) continue;
3601
+ if (budget.left <= 0) {
3602
+ truncated = true;
3603
+ break;
3604
+ }
3605
+ budget.left -= 1 + key.length;
3606
+ let value = jn[key];
3607
+ let shown;
3608
+ if ((is_secret_name(key.slice(-128)) || value_is_secret && key === "value") && value !== void 0 && value !== null && value !== "") shown = "********";
3609
+ else shown = _json_mask_secrets(value, memo, depth + 1, budget);
3610
+ if (shown !== value) changed = true;
3611
+ result[key] = shown;
3612
+ }
3613
+ if (truncated) result["<more>"] = MASK_TOO_LARGE;
3614
+ }
3615
+ if (!changed && !truncated) result = jn;
3616
+ memo.set(jn, result);
3617
+ return result;
3618
+ }
3619
+ function json_mask_secrets(jn) {
3620
+ try {
3621
+ return _json_mask_secrets(jn, /* @__PURE__ */ new WeakMap(), 0, { left: MASK_MAX_BYTES });
3622
+ } catch (e) {
3623
+ return MASK_FAILED;
3624
+ }
3625
+ }
3626
+ /************************************************************
3627
+ * trace_json() of a json that can hold a credential: what
3628
+ * json_mask_secrets() masks is shown masked
3629
+ ************************************************************/
3630
+ function trace_json_masked(jn, msg) {
3631
+ trace_json(json_mask_secrets(jn), msg);
3632
+ }
3633
+ /************************************************************
3226
3634
  * Duplicate an object (new references)
3227
3635
  * using the modern structuredClone (Deep copy of a single object)
3228
3636
  ************************************************************/
@@ -3495,6 +3903,8 @@ var gobjJs = (function(exports) {
3495
3903
  if (is_number(jn_var1) || is_number(jn_var2)) {
3496
3904
  let val1 = Number(jn_var1);
3497
3905
  let val2 = Number(jn_var2);
3906
+ if (Number.isNaN(val1)) val1 = 0;
3907
+ if (Number.isNaN(val2)) val2 = 0;
3498
3908
  if (val1 > val2) return 1;
3499
3909
  else if (val1 < val2) return -1;
3500
3910
  else return 0;
@@ -3524,8 +3934,8 @@ var gobjJs = (function(exports) {
3524
3934
  ***************************************************************************/
3525
3935
  function is_metadata_key(key) {
3526
3936
  if (!is_string(key)) return false;
3527
- let i;
3528
- for (i = 0; i < key.length; i++) {
3937
+ let i = 0;
3938
+ for (; i < key.length; i++) {
3529
3939
  if (key[i] !== "_") break;
3530
3940
  if (i > 2) break;
3531
3941
  }
@@ -3536,8 +3946,8 @@ var gobjJs = (function(exports) {
3536
3946
  ***************************************************************************/
3537
3947
  function is_private_key(key) {
3538
3948
  if (!is_string(key)) return false;
3539
- let i;
3540
- for (i = 0; i < key.length; i++) {
3949
+ let i = 0;
3950
+ for (; i < key.length; i++) {
3541
3951
  if (key[i] !== "_") break;
3542
3952
  if (i > 2) break;
3543
3953
  }
@@ -3562,6 +3972,28 @@ var gobjJs = (function(exports) {
3562
3972
  return false;
3563
3973
  }
3564
3974
  /************************************************************
3975
+ * A key that reaches the prototype chain instead of the data:
3976
+ * "__proto__", "constructor" or "prototype" when the object
3977
+ * does not hold it as its OWN key. A walk through one of them
3978
+ * read, or WROTE, Object.prototype: the flat id
3979
+ * "__proto__`polluted" set a key on every object of the page.
3980
+ * In C they are keys like any other, so here too: read them
3981
+ * only as own keys, and write "__proto__" as an own key.
3982
+ ************************************************************/
3983
+ function is_prototype_segment(obj, key) {
3984
+ if (key === "__proto__" || key === "constructor" || key === "prototype") return !Object.prototype.hasOwnProperty.call(obj, key);
3985
+ return false;
3986
+ }
3987
+ function set_own_key(obj, key, value) {
3988
+ if (key === "__proto__") Object.defineProperty(obj, key, {
3989
+ value,
3990
+ writable: true,
3991
+ enumerable: true,
3992
+ configurable: true
3993
+ });
3994
+ else obj[key] = value;
3995
+ }
3996
+ /************************************************************
3565
3997
  * The value at `path` (keys joined by a backtick), as the C
3566
3998
  * kw_find_path() finds it: undefined when it is not there.
3567
3999
  * A kw that is not a dict or a list is LOGGED ("kw must be list
@@ -3588,7 +4020,12 @@ var gobjJs = (function(exports) {
3588
4020
  }
3589
4021
  let ss = path.split("`");
3590
4022
  let len = ss.length;
3591
- for (let i = 0; i < len - 1; i++) {
4023
+ for (let i = 0; i < len; i++) {
4024
+ if (is_prototype_segment(kw, ss[i])) {
4025
+ if (verbose) log_error(`${prefix}path not found: '${path}'`);
4026
+ return;
4027
+ }
4028
+ if (i === len - 1) break;
3592
4029
  kw = kw[ss[i]];
3593
4030
  if (kw === void 0 || kw === null) {
3594
4031
  if (verbose) log_error(`${prefix}path not found: '${path}'`);
@@ -3648,7 +4085,7 @@ var gobjJs = (function(exports) {
3648
4085
  return v;
3649
4086
  } else if (required) {
3650
4087
  log_error(`path not found: '${path}'`);
3651
- trace_json(kw);
4088
+ trace_json_masked(kw);
3652
4089
  }
3653
4090
  return Boolean(default_value);
3654
4091
  }
@@ -3662,11 +4099,11 @@ var gobjJs = (function(exports) {
3662
4099
  } else if (wild && b === null) value = false;
3663
4100
  else if (wild) {
3664
4101
  log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a simple json element: '${path}'`);
3665
- trace_json(kw);
4102
+ trace_json_masked(kw);
3666
4103
  return false;
3667
4104
  } else {
3668
4105
  log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a json boolean: '${path}'`);
3669
- trace_json(kw);
4106
+ trace_json_masked(kw);
3670
4107
  return Boolean(default_value);
3671
4108
  }
3672
4109
  if (extract) kw_delete(gobj, kw, path);
@@ -3716,7 +4153,7 @@ var gobjJs = (function(exports) {
3716
4153
  return v;
3717
4154
  } else if (required) {
3718
4155
  log_error(`path not found: '${path}'`);
3719
- trace_json(kw);
4156
+ trace_json_masked(kw);
3720
4157
  }
3721
4158
  return parseInt(default_value);
3722
4159
  }
@@ -3724,14 +4161,14 @@ var gobjJs = (function(exports) {
3724
4161
  if (is_number(v)) value = Math.trunc(v);
3725
4162
  else if (!wild) {
3726
4163
  log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a json integer: '${path}'`);
3727
- trace_json(kw);
4164
+ trace_json_masked(kw);
3728
4165
  return parseInt(default_value);
3729
4166
  } else if (is_boolean(v)) value = v ? 1 : 0;
3730
4167
  else if (is_string(v)) value = strtoll_base0(v);
3731
4168
  else if (v === null) value = 0;
3732
4169
  else {
3733
4170
  log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a simple json element: '${path}'`);
3734
- trace_json(kw);
4171
+ trace_json_masked(kw);
3735
4172
  return 0;
3736
4173
  }
3737
4174
  if (extract) kw_delete(gobj, kw, path);
@@ -3763,7 +4200,7 @@ var gobjJs = (function(exports) {
3763
4200
  return v;
3764
4201
  } else if (required) {
3765
4202
  log_error(`path not found: '${path}'`);
3766
- trace_json(kw);
4203
+ trace_json_masked(kw);
3767
4204
  }
3768
4205
  return Number(default_value);
3769
4206
  }
@@ -3771,7 +4208,7 @@ var gobjJs = (function(exports) {
3771
4208
  if (is_number(v)) value = v;
3772
4209
  else if (!wild) {
3773
4210
  log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a json real: '${path}'`);
3774
- trace_json(kw);
4211
+ trace_json_masked(kw);
3775
4212
  return Number(default_value);
3776
4213
  } else if (is_boolean(v)) value = v ? 1 : 0;
3777
4214
  else if (is_string(v)) {
@@ -3780,7 +4217,7 @@ var gobjJs = (function(exports) {
3780
4217
  } else if (v === null) value = 0;
3781
4218
  else {
3782
4219
  log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a simple json element: '${path}'`);
3783
- trace_json(kw);
4220
+ trace_json_masked(kw);
3784
4221
  return 0;
3785
4222
  }
3786
4223
  if (extract) kw_delete(gobj, kw, path);
@@ -3832,14 +4269,14 @@ var gobjJs = (function(exports) {
3832
4269
  return default_value;
3833
4270
  } else if (required && !kw_path_holds_key(kw, path)) {
3834
4271
  log_error(`path not found: '${path}'`);
3835
- trace_json(kw);
4272
+ trace_json_masked(kw);
3836
4273
  }
3837
4274
  return default_value;
3838
4275
  }
3839
4276
  if (!is_string(v)) {
3840
4277
  if (v !== null) {
3841
4278
  log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a json str: '${path}'`);
3842
- trace_json(kw);
4279
+ trace_json_masked(kw);
3843
4280
  }
3844
4281
  return default_value;
3845
4282
  }
@@ -3862,7 +4299,7 @@ var gobjJs = (function(exports) {
3862
4299
  return v;
3863
4300
  } else if (required) {
3864
4301
  log_error(`path not found: '${path}'`);
3865
- trace_json(kw);
4302
+ trace_json_masked(kw);
3866
4303
  }
3867
4304
  return default_value;
3868
4305
  }
@@ -3889,14 +4326,14 @@ var gobjJs = (function(exports) {
3889
4326
  }
3890
4327
  if (required) {
3891
4328
  log_error(`path not found: '${path}'`);
3892
- trace_json(kw);
4329
+ trace_json_masked(kw);
3893
4330
  }
3894
4331
  return default_value;
3895
4332
  }
3896
4333
  if (!is_object(v)) {
3897
4334
  if (required) {
3898
4335
  log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a json dict: '${path}'`);
3899
- trace_json(kw);
4336
+ trace_json_masked(kw);
3900
4337
  }
3901
4338
  return default_value;
3902
4339
  }
@@ -3919,7 +4356,7 @@ var gobjJs = (function(exports) {
3919
4356
  return v;
3920
4357
  } else if (required) {
3921
4358
  log_error(`path not found: '${path}'`);
3922
- trace_json(kw);
4359
+ trace_json_masked(kw);
3923
4360
  }
3924
4361
  return default_value;
3925
4362
  }
@@ -3947,14 +4384,14 @@ var gobjJs = (function(exports) {
3947
4384
  }
3948
4385
  if (required) {
3949
4386
  log_error(`path not found: '${path}'`);
3950
- trace_json(kw);
4387
+ trace_json_masked(kw);
3951
4388
  }
3952
4389
  return default_value;
3953
4390
  }
3954
4391
  if (!is_array(v)) {
3955
4392
  if (required) {
3956
4393
  log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}path MUST BE a json list: '${path}'`);
3957
- trace_json(kw);
4394
+ trace_json_masked(kw);
3958
4395
  }
3959
4396
  return default_value;
3960
4397
  }
@@ -3971,17 +4408,13 @@ var gobjJs = (function(exports) {
3971
4408
  return -1;
3972
4409
  }
3973
4410
  let ss = path.split("`");
3974
- if (ss.length <= 1) {
3975
- kw[path] = value;
3976
- return 0;
3977
- }
3978
4411
  let len = ss.length;
3979
4412
  for (let i = 0; i < len; i++) {
3980
4413
  let key = ss[i];
3981
- if (i === len - 1) kw[key] = value;
4414
+ if (i === len - 1) set_own_key(kw, key, value);
3982
4415
  else {
3983
- let seg = kw[key];
3984
- if (seg === void 0) kw[key] = {};
4416
+ let seg = is_prototype_segment(kw, key) ? void 0 : kw[key];
4417
+ if (seg === void 0) set_own_key(kw, key, {});
3985
4418
  else if (!is_object(seg) && !is_array(seg)) {
3986
4419
  log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}kw_set_dict_value(): segment '${key}' is not a dict or a list: '${path}'`);
3987
4420
  return -1;
@@ -4036,9 +4469,9 @@ var gobjJs = (function(exports) {
4036
4469
  if (!matched) break;
4037
4470
  continue;
4038
4471
  }
4039
- let jn_record_value = kw_get_dict_value(0, kw, path, 0, 0);
4040
- if (!jn_record_value) jn_record_value = json_object_get(kw, path);
4041
- if (!jn_record_value) {
4472
+ let jn_record_value = kw_get_dict_value(0, kw, path, void 0, 0);
4473
+ if (jn_record_value === void 0) jn_record_value = json_object_get(kw, path);
4474
+ if (jn_record_value === void 0) {
4042
4475
  matched = false;
4043
4476
  break;
4044
4477
  }
@@ -4157,10 +4590,11 @@ var gobjJs = (function(exports) {
4157
4590
  ***************************************************************************/
4158
4591
  function kw_clone_by_not_keys(gobj, kw, keys, verbose) {
4159
4592
  let kw_clone = {};
4593
+ if (!is_object(kw)) return kw_clone;
4160
4594
  json_object_update(kw_clone, kw);
4161
4595
  if (is_string(keys) && !empty_string(keys)) {
4162
4596
  let key = keys;
4163
- if (kw_get_dict_value(gobj, kw, key, 0, 0)) json_object_del(kw_clone, key);
4597
+ if (kw.hasOwnProperty(key)) json_object_del(kw_clone, key);
4164
4598
  else if (verbose) log_error(`${gobj_short_name(gobj)}: key not found: ${key}`);
4165
4599
  } else if (is_object(keys) && json_object_size(keys) > 0) {
4166
4600
  for (let key of Object.keys(keys)) if (kw.hasOwnProperty(key)) json_object_del(kw_clone, key);
@@ -5120,9 +5554,15 @@ var gobjJs = (function(exports) {
5120
5554
  * will be 'data-i18n' attr
5121
5555
  *
5122
5556
  * content -> string | [createElement2() or parameters of createElement2]
5557
+ * | HTMLElement | SVGElement | Text
5123
5558
  * if string begins with '<' then
5124
5559
  * it will be converted to HTMLElement
5125
5560
  * content = createOneHtml(string)
5561
+ * ⚠️ So a string is MARKUP when it starts with '<': never
5562
+ * pass DATA (a value from a backend, a name a user typed)
5563
+ * as a bare string, or "<img src=x onerror=...>" runs.
5564
+ * Pass it as a Text node, which is always text:
5565
+ * ['span', {}, document.createTextNode(value)]
5126
5566
  * if attrs['i18n'] is not empty then (or 'data-i18n' or 'data_i18next')
5127
5567
  * it will be overridden with the translation
5128
5568
  * content = translate(attrs['i18n']));
@@ -5561,7 +6001,7 @@ var gobjJs = (function(exports) {
5561
6001
  current[seg] = flat[key];
5562
6002
  } else {
5563
6003
  if (Object.prototype.hasOwnProperty.call(current, seg)) throw new Error(`flat2json: '${key}' is written twice, or once as a value and once as a container`);
5564
- current[seg] = flat[key];
6004
+ set_own_key(current, seg, flat[key]);
5565
6005
  }
5566
6006
  break;
5567
6007
  }
@@ -5574,10 +6014,10 @@ var gobjJs = (function(exports) {
5574
6014
  current[seg] = child;
5575
6015
  }
5576
6016
  } else {
5577
- child = current[seg];
6017
+ child = is_prototype_segment(current, seg) ? void 0 : current[seg];
5578
6018
  if (child === void 0) {
5579
6019
  child = next_is_index ? [] : {};
5580
- current[seg] = child;
6020
+ set_own_key(current, seg, child);
5581
6021
  }
5582
6022
  }
5583
6023
  if (child === null || typeof child !== "object") throw new Error(`flat2json: '${key}' walks through a value: the same id is a leaf and a container at once`);
@@ -6340,6 +6780,7 @@ var gobjJs = (function(exports) {
6340
6780
  ***************************************************************/
6341
6781
  function mt_play(gobj) {
6342
6782
  let default_service = gobj_default_service();
6783
+ if (!default_service) return 0;
6343
6784
  if (!gobj_is_running(default_service)) gobj_start(default_service);
6344
6785
  if (!gobj_is_playing(default_service)) gobj_play(default_service);
6345
6786
  return 0;
@@ -6348,7 +6789,8 @@ var gobjJs = (function(exports) {
6348
6789
  * Framework Method: Pause
6349
6790
  ***************************************************************/
6350
6791
  function mt_pause(gobj) {
6351
- gobj_pause(gobj_default_service());
6792
+ let default_service = gobj_default_service();
6793
+ if (default_service && gobj_is_playing(default_service)) gobj_pause(default_service);
6352
6794
  return 0;
6353
6795
  }
6354
6796
  /***************************************************************
@@ -6604,6 +7046,7 @@ var gobjJs = (function(exports) {
6604
7046
  function mt_create(gobj) {
6605
7047
  let priv = gobj.priv;
6606
7048
  priv.gobj_timer = gobj_create_pure_child(gobj_name(gobj), "C_TIMER", {}, gobj);
7049
+ priv.ws_seq = 0;
6607
7050
  priv.url = gobj_read_str_attr(gobj, "url");
6608
7051
  priv.remote_yuno_name = gobj_read_str_attr(gobj, "remote_yuno_name");
6609
7052
  priv.remote_yuno_role = gobj_read_str_attr(gobj, "remote_yuno_role");
@@ -6638,6 +7081,16 @@ var gobjJs = (function(exports) {
6638
7081
  function mt_start(gobj) {
6639
7082
  let priv = gobj.priv;
6640
7083
  priv.retry_ms = 0;
7084
+ if (gobj_current_state(gobj) !== "ST_DISCONNECTED") {
7085
+ gobj_send_event(gobj, "EV_ON_CLOSE", {
7086
+ url: priv.url,
7087
+ ws_seq: priv.ws_seq,
7088
+ code: 1e3,
7089
+ reason: "restarted",
7090
+ was_clean: true
7091
+ }, gobj);
7092
+ clear_timeout(priv.gobj_timer);
7093
+ }
6641
7094
  priv.websocket = setup_websocket(gobj);
6642
7095
  return 0;
6643
7096
  }
@@ -6772,10 +7225,16 @@ var gobjJs = (function(exports) {
6772
7225
  log_error(`${gobj_short_name(gobj)}: Failed to initialize WebSocket.`);
6773
7226
  return null;
6774
7227
  }
7228
+ const ws_seq = ++gobj.priv.ws_seq;
6775
7229
  websocket.onopen = () => {
6776
- gobj_send_event(gobj, "EV_ON_OPEN", { url }, gobj);
7230
+ if (ws_seq !== gobj.priv.ws_seq || gobj_is_destroying(gobj)) return;
7231
+ gobj_send_event(gobj, "EV_ON_OPEN", {
7232
+ url,
7233
+ ws_seq
7234
+ }, gobj);
6777
7235
  };
6778
7236
  websocket.onmessage = (e) => {
7237
+ if (ws_seq !== gobj.priv.ws_seq || gobj_is_destroying(gobj)) return;
6779
7238
  gobj_send_event(gobj, "EV_ON_MESSAGE", {
6780
7239
  url,
6781
7240
  data: e.data
@@ -6783,9 +7242,13 @@ var gobjJs = (function(exports) {
6783
7242
  };
6784
7243
  websocket.onclose = (e) => {
6785
7244
  if (gobj_is_destroying(gobj)) return;
7245
+ if (ws_seq !== gobj.priv.ws_seq) return;
6786
7246
  if (!gobj_read_bool_attr(gobj_yuno(), "browser_beforeunload")) gobj_send_event(gobj, "EV_ON_CLOSE", {
6787
7247
  url,
6788
- e
7248
+ ws_seq,
7249
+ code: e.code,
7250
+ reason: e.reason,
7251
+ was_clean: e.wasClean
6789
7252
  }, gobj);
6790
7253
  else log_warning("Close websocket by unload page");
6791
7254
  };
@@ -6806,7 +7269,7 @@ var gobjJs = (function(exports) {
6806
7269
  try {
6807
7270
  websocket.close(code, reason);
6808
7271
  } catch (e) {
6809
- log_error("Error closing WebSocket:", e.message);
7272
+ log_error(`${gobj_short_name(gobj)}: Error closing WebSocket: ${e.message}`);
6810
7273
  }
6811
7274
  }
6812
7275
  /***************************************************************
@@ -6816,7 +7279,7 @@ var gobjJs = (function(exports) {
6816
7279
  let hora = current_timestamp();
6817
7280
  try {
6818
7281
  log_debug("\n" + hora + " " + prefix + "\n");
6819
- trace_json(iev);
7282
+ trace_json_masked(iev);
6820
7283
  } catch (e) {
6821
7284
  log_debug("ERROR in trace_inter_event: " + e);
6822
7285
  }
@@ -6932,29 +7395,29 @@ var gobjJs = (function(exports) {
6932
7395
  try {
6933
7396
  x = JSON.parse(data);
6934
7397
  } catch (e) {
6935
- log_error("parsing inter_event json: " + e);
7398
+ log_warning(`${gobj_short_name(gobj)}: parsing inter_event json: ${e}`);
6936
7399
  return null;
6937
7400
  }
6938
7401
  if (!(x instanceof Object)) {
6939
- log_error("parsing inter_event: websocket data not a json object");
7402
+ log_warning(`${gobj_short_name(gobj)}: parsing inter_event: websocket data not a json object`);
6940
7403
  return null;
6941
7404
  }
6942
7405
  let event = x["event"];
6943
7406
  if (!event) {
6944
- log_error("parsing inter_event: no event");
7407
+ log_warning(`${gobj_short_name(gobj)}: parsing inter_event: no event`);
6945
7408
  return null;
6946
7409
  }
6947
7410
  if (typeof event !== "string") {
6948
- log_error("parsing inter_event: event not a string");
7411
+ log_warning(`${gobj_short_name(gobj)}: parsing inter_event: event not a string`);
6949
7412
  return null;
6950
7413
  }
6951
7414
  let kw = x["kw"];
6952
7415
  if (!kw) {
6953
- log_error("parsing inter_kw: no kw");
7416
+ log_warning(`${gobj_short_name(gobj)}: parsing inter_kw: no kw`);
6954
7417
  return null;
6955
7418
  }
6956
7419
  if (!(kw instanceof Object)) {
6957
- log_error("parsing inter_event: kw not a json object");
7420
+ log_warning(`${gobj_short_name(gobj)}: parsing inter_event: kw not a json object`);
6958
7421
  return null;
6959
7422
  }
6960
7423
  return {
@@ -7014,10 +7477,9 @@ var gobjJs = (function(exports) {
7014
7477
  ***************************************************************/
7015
7478
  function ac_on_close(gobj, event, kw, src) {
7016
7479
  let priv = gobj.priv;
7017
- let e = kw.e;
7018
7480
  let url = kw.url;
7019
7481
  set_remote_log_functions();
7020
- log_warning(`${gobj_short_name(gobj)}: WebSocket closed ${url} (Code: ${e.code}, Reason: "${e.reason}", Clean: ${e.wasClean})`);
7482
+ log_warning(`${gobj_short_name(gobj)}: WebSocket closed ${url} (Code: ${kw.code}, Reason: "${kw.reason}", Clean: ${kw.was_clean})`);
7021
7483
  if (priv.websocket) {
7022
7484
  priv.websocket.onopen = null;
7023
7485
  priv.websocket.onmessage = null;
@@ -7034,15 +7496,15 @@ var gobjJs = (function(exports) {
7034
7496
  remote_yuno_service: priv.remote_yuno_service
7035
7497
  });
7036
7498
  } else {
7037
- log_warning(`${gobj_short_name(gobj)}: EV_ON_OPEN_ERROR cannot open ${url} (Code: ${e.code}, Reason: "${e.reason}", Clean: ${e.wasClean})`);
7499
+ log_warning(`${gobj_short_name(gobj)}: EV_ON_OPEN_ERROR cannot open ${url} (Code: ${kw.code}, Reason: "${kw.reason}", Clean: ${kw.was_clean})`);
7038
7500
  gobj_publish_event(gobj, "EV_ON_OPEN_ERROR", {
7039
7501
  url,
7040
7502
  remote_yuno_name: priv.remote_yuno_name,
7041
7503
  remote_yuno_role: priv.remote_yuno_role,
7042
7504
  remote_yuno_service: priv.remote_yuno_service,
7043
- code: e.code,
7044
- reason: e.reason,
7045
- was_clean: e.wasClean
7505
+ code: kw.code,
7506
+ reason: kw.reason,
7507
+ was_clean: kw.was_clean
7046
7508
  });
7047
7509
  }
7048
7510
  if (gobj_is_running(gobj)) set_timeout(priv.gobj_timer, next_retry(gobj));
@@ -7140,6 +7602,10 @@ var gobjJs = (function(exports) {
7140
7602
  function ac_on_message(gobj, event, kw, src) {
7141
7603
  let url = gobj.priv.url;
7142
7604
  let iev_msg = iev_create_from_json(gobj, kw.data);
7605
+ if (!iev_msg) {
7606
+ log_warning(`${gobj_short_name(gobj)}: frame dropped from ${url}: ${String(kw.data).substring(0, 256)}`);
7607
+ return -1;
7608
+ }
7143
7609
  if (is_traffic_tracing(gobj)) {
7144
7610
  let prefix = gobj_name(gobj_yuno()) + " <== " + url;
7145
7611
  let size = kw.data.length;
@@ -7165,8 +7631,14 @@ var gobjJs = (function(exports) {
7165
7631
  return 0;
7166
7632
  }
7167
7633
  let iev_dst_service = kw_get_str(gobj, event_id, "dst_service", "");
7168
- if (msg_type === "__subscribing__") return -1;
7169
- if (msg_type === "__unsubscribing__") return -1;
7634
+ if (msg_type === "__subscribing__") {
7635
+ log_warning(`${gobj_short_name(gobj)}: subscription event ignored, I'm client (service: ${iev_dst_service}, event: ${iev_event})`);
7636
+ return -1;
7637
+ }
7638
+ if (msg_type === "__unsubscribing__") {
7639
+ log_warning(`${gobj_short_name(gobj)}: unsubscription event ignored, I'm client (service: ${iev_dst_service}, event: ${iev_event})`);
7640
+ return -1;
7641
+ }
7170
7642
  if (gobj_has_event(gobj, iev_event, event_flag_t.EVF_PUBLIC_EVENT)) {
7171
7643
  gobj_send_event(gobj, iev_event, iev_kw, gobj);
7172
7644
  return 0;
@@ -7498,6 +7970,7 @@ var gobjJs = (function(exports) {
7498
7970
  exports.is_object = is_object;
7499
7971
  exports.is_private_key = is_private_key;
7500
7972
  exports.is_pure_number = is_pure_number;
7973
+ exports.is_secret_name = is_secret_name;
7501
7974
  exports.is_string = is_string;
7502
7975
  exports.jdb_delete = jdb_delete;
7503
7976
  exports.jdb_get = jdb_get;
@@ -7513,6 +7986,7 @@ var gobjJs = (function(exports) {
7513
7986
  exports.json_array_size = json_array_size;
7514
7987
  exports.json_deep_copy = json_deep_copy;
7515
7988
  exports.json_is_identical = json_is_identical;
7989
+ exports.json_mask_secrets = json_mask_secrets;
7516
7990
  exports.json_object_del = json_object_del;
7517
7991
  exports.json_object_get = json_object_get;
7518
7992
  exports.json_object_set = json_object_set;
@@ -7560,6 +8034,7 @@ var gobjJs = (function(exports) {
7560
8034
  exports.log_error = log_error;
7561
8035
  exports.log_info = log_info;
7562
8036
  exports.log_warning = log_warning;
8037
+ exports.mask_secrets_inline = mask_secrets_inline;
7563
8038
  exports.msg_iev_get_msg_type = msg_iev_get_msg_type;
7564
8039
  exports.msg_iev_get_stack = msg_iev_get_stack;
7565
8040
  exports.msg_iev_push_stack = msg_iev_push_stack;
@@ -7593,6 +8068,7 @@ var gobjJs = (function(exports) {
7593
8068
  exports.template_get_field_desc = template_get_field_desc;
7594
8069
  exports.timeTracker = timeTracker;
7595
8070
  exports.trace_json = trace_json;
8071
+ exports.trace_json_masked = trace_json_masked;
7596
8072
  exports.trace_level_t = trace_level_t;
7597
8073
  exports.trace_msg = trace_msg;
7598
8074
  exports.treedb_decoder_fkey = treedb_decoder_fkey;