@yuneta/gobj-js 7.7.3 → 7.8.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 +76 -2
- package/dist/gobj-js.cjs.js +87 -21
- package/dist/gobj-js.cjs.js.map +1 -1
- package/dist/gobj-js.cjs.min.js +745 -727
- package/dist/gobj-js.cjs.min.js.map +1 -1
- package/dist/gobj-js.es.js +87 -22
- package/dist/gobj-js.es.js.map +1 -1
- package/dist/gobj-js.es.min.js +804 -785
- package/dist/gobj-js.es.min.js.map +1 -1
- package/dist/gobj-js.iife.js +87 -21
- package/dist/gobj-js.iife.js.map +1 -1
- package/dist/gobj-js.iife.min.js +796 -778
- package/dist/gobj-js.iife.min.js.map +1 -1
- package/dist/gobj-js.umd.js +87 -21
- package/dist/gobj-js.umd.js.map +1 -1
- package/dist/gobj-js.umd.min.js +1124 -1106
- package/dist/gobj-js.umd.min.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -477,6 +477,16 @@ gobj_list_persistent_attrs(gobj, keys)
|
|
|
477
477
|
|
|
478
478
|
Attributes marked `SDF_PERSIST` are automatically saved/loaded.
|
|
479
479
|
|
|
480
|
+
**Always name what you save**: `gobj_save_persistent_attrs(gobj, "attr_name")`
|
|
481
|
+
(a string, or a list/dict of names). The bare call saves every `SDF_PERSIST`
|
|
482
|
+
attr, which is wasteful and can clobber attrs the caller never touched.
|
|
483
|
+
|
|
484
|
+
**Check the result.** `db_save_persistent_attrs()` / `gobj_save_persistent_attrs()`
|
|
485
|
+
return **`0` on success, `-1` on failure**, and a failure is logged through
|
|
486
|
+
`log_error`. `localStorage` can *refuse* a write (quota exceeded, private mode,
|
|
487
|
+
storage blocked): treating that as saved leaves the in-memory attr and the UI
|
|
488
|
+
showing a value the store rejected, which the next reload silently loses.
|
|
489
|
+
|
|
480
490
|
### Helpers & Utilities
|
|
481
491
|
|
|
482
492
|
```javascript
|
|
@@ -572,10 +582,54 @@ trace_msg(format, ...args) // cyan, prefixed "MSG"
|
|
|
572
582
|
trace_json(json, msg) // dir-dump a JSON object
|
|
573
583
|
|
|
574
584
|
// Redirect error/warning output to a single remote handler
|
|
575
|
-
// (info/debug always go to the browser console)
|
|
576
585
|
set_remote_log_functions(remote_log_fn) // fn(message) — single function
|
|
586
|
+
|
|
587
|
+
// Receive every log record (any level) in your own sink
|
|
588
|
+
set_log_callback(fn) // fn(level, message)
|
|
589
|
+
|
|
590
|
+
// Gate the DIRECT browser-console writes of all the functions above
|
|
591
|
+
set_console_log_enabled(enabled) // default: true (unchanged behaviour)
|
|
577
592
|
```
|
|
578
593
|
|
|
594
|
+
**Three independent output paths.** `set_console_log_enabled(false)` silences
|
|
595
|
+
only the `console.*` writes: the log-sink callback (`set_log_callback`) and the
|
|
596
|
+
remote log functions (`set_remote_log_functions`) still fire. That is what lets
|
|
597
|
+
a GUI route framework output — **including the automata/FSM trace, which arrives
|
|
598
|
+
as `debug`** — into its own monitor window while keeping the browser console
|
|
599
|
+
clean (gobj-ui's dev-window "Output" selector does exactly this).
|
|
600
|
+
|
|
601
|
+
### i18n: `refresh_language` and the `data-i18n-*` family
|
|
602
|
+
|
|
603
|
+
The runtime does not translate anything itself — the **app** owns the
|
|
604
|
+
translator (i18next, typically) and passes it in as `t`. What the runtime
|
|
605
|
+
provides is the mechanism to **re-translate live DOM** when the language
|
|
606
|
+
changes:
|
|
607
|
+
|
|
608
|
+
```javascript
|
|
609
|
+
refresh_language(element, t) // element defaults to `document`
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
It only re-translates a node that **carries its key**, so passing a string
|
|
613
|
+
through `t()` once at build time is not enough — that text is frozen in the
|
|
614
|
+
mount-time language for the life of the view. Tag the DOM instead:
|
|
615
|
+
|
|
616
|
+
| Attribute | Re-translates |
|
|
617
|
+
|---|---|
|
|
618
|
+
| `data-i18n` | the element's first text node |
|
|
619
|
+
| `data-i18n-title` | the `title` attribute (hover tooltip) |
|
|
620
|
+
| `data-i18n-aria-label` | the `aria-label` (assistive-tech name) |
|
|
621
|
+
| `data-i18n-placeholder` | the `placeholder` of an input/textarea |
|
|
622
|
+
|
|
623
|
+
The three attribute variants exist because `data-i18n` walks **text nodes**,
|
|
624
|
+
which cannot reach an attribute. Anything a third-party **widget** draws is
|
|
625
|
+
reachable by none of them — re-render it from the language-change handler
|
|
626
|
+
instead.
|
|
627
|
+
|
|
628
|
+
**A missing key is invisible**: i18next answers an unknown key with the key
|
|
629
|
+
itself, so it renders as lower-case English and never changes language. Do not
|
|
630
|
+
compose data into a key either (`` `${key} · ${t(mode)}` ``) — split it so each
|
|
631
|
+
translatable half carries its own key.
|
|
632
|
+
|
|
579
633
|
### String Formatting
|
|
580
634
|
|
|
581
635
|
```javascript
|
|
@@ -600,6 +654,10 @@ register_c_yuno();
|
|
|
600
654
|
|
|
601
655
|
Key attributes: `yuno_name`, `yuno_role`, `yuno_id`, `yuno_version`, `yuno_release`, `yuneta_version`, `required_services`, `tracing`, `start_date`, `node_uuid`, `__username__`
|
|
602
656
|
|
|
657
|
+
The yuno's `required_services` is the **fallback** for links that declare none
|
|
658
|
+
of their own. A multi-link yuno should set the list on each `C_IEVENT_CLI`
|
|
659
|
+
instead — see [C_IEVENT_CLI](#c_ievent_cli) below.
|
|
660
|
+
|
|
603
661
|
### C_TIMER
|
|
604
662
|
|
|
605
663
|
Manages timeouts and periodic timers.
|
|
@@ -638,7 +696,23 @@ let remote = gobj_create_service("backend", "C_IEVENT_CLI", {
|
|
|
638
696
|
}, gobj_yuno());
|
|
639
697
|
```
|
|
640
698
|
|
|
641
|
-
Key attributes: `url`, `jwt`, `wanted_yuno_role`, `wanted_yuno_name`, `wanted_yuno_service`, `remote_yuno_role`, `remote_yuno_name`, `remote_yuno_service`
|
|
699
|
+
Key attributes: `url`, `jwt`, `wanted_yuno_role`, `wanted_yuno_name`, `wanted_yuno_service`, `remote_yuno_role`, `remote_yuno_name`, `remote_yuno_service`, `required_services`, `timeout_retry`, `timeout_retry_max`
|
|
700
|
+
|
|
701
|
+
**`required_services`** (default `[]`) is the list this link advertises in its
|
|
702
|
+
identity_card, which the remote's `C_AUTHZ` uses to authorize commands. It is
|
|
703
|
+
**per link**: empty falls back to the yuno's own `required_services`, so a
|
|
704
|
+
single-link yuno needs nothing. A **multi-link** yuno must set it per link — a
|
|
705
|
+
yuno-wide list can only be the union of every backend's services, so each
|
|
706
|
+
backend would be handed the service names of all the others, and get a card
|
|
707
|
+
naming services it does not host.
|
|
708
|
+
|
|
709
|
+
**Reconnect backoff.** A dropped link retries after `timeout_retry` (5s), then
|
|
710
|
+
**doubles** up to `timeout_retry_max` (60s), with ±20% jitter. The jitter is
|
|
711
|
+
what breaks lockstep, so N links that dropped together do not stampede a backend
|
|
712
|
+
that is just coming back. The backoff resets when a session is actually reached,
|
|
713
|
+
and on `mt_start` — a deliberate reconnect never inherits a previous run's
|
|
714
|
+
penalty. For the old fixed-interval behaviour set `timeout_retry_max` equal to
|
|
715
|
+
`timeout_retry`.
|
|
642
716
|
|
|
643
717
|
---
|
|
644
718
|
|
package/dist/gobj-js.cjs.js
CHANGED
|
@@ -2630,6 +2630,10 @@ var __log_callback__ = null;
|
|
|
2630
2630
|
function set_log_callback(fn) {
|
|
2631
2631
|
__log_callback__ = typeof fn === "function" ? fn : null;
|
|
2632
2632
|
}
|
|
2633
|
+
var __console_output_enabled__ = true;
|
|
2634
|
+
function set_console_log_enabled(enabled) {
|
|
2635
|
+
__console_output_enabled__ = enabled ? true : false;
|
|
2636
|
+
}
|
|
2633
2637
|
var __in_log_callback__ = false;
|
|
2634
2638
|
function emit_log_callback(level, msg, hora) {
|
|
2635
2639
|
if (__log_callback__ && !__in_log_callback__) {
|
|
@@ -2675,9 +2679,10 @@ function format_log(format) {
|
|
|
2675
2679
|
function log_error(format) {
|
|
2676
2680
|
let msg = format_log(format);
|
|
2677
2681
|
let hora = current_timestamp();
|
|
2678
|
-
if (f_error) if (f_error === window.console.error)
|
|
2679
|
-
|
|
2680
|
-
|
|
2682
|
+
if (f_error) if (f_error === window.console.error) {
|
|
2683
|
+
if (__console_output_enabled__) f_error("%c" + hora + " ERROR: " + String(msg), "color:red");
|
|
2684
|
+
} else {
|
|
2685
|
+
if (__console_output_enabled__) window.console.error("%c" + hora + " ERROR: " + String(msg), "color:red");
|
|
2681
2686
|
f_error(`${hora} ERROR: ${String(msg)}`);
|
|
2682
2687
|
}
|
|
2683
2688
|
emit_log_callback("error", msg, hora);
|
|
@@ -2685,9 +2690,10 @@ function log_error(format) {
|
|
|
2685
2690
|
function log_warning(format) {
|
|
2686
2691
|
let msg = format_log(format);
|
|
2687
2692
|
let hora = current_timestamp();
|
|
2688
|
-
if (f_warning) if (f_warning === window.console.warn)
|
|
2689
|
-
|
|
2690
|
-
|
|
2693
|
+
if (f_warning) if (f_warning === window.console.warn) {
|
|
2694
|
+
if (__console_output_enabled__) f_warning("%c" + hora + " WARNING: " + String(msg), "color:yellow");
|
|
2695
|
+
} else {
|
|
2696
|
+
if (__console_output_enabled__) window.console.warn("%c" + hora + " WARNING: " + String(msg), "color:yellow");
|
|
2691
2697
|
f_warning(`${hora} WARNING: ${String(msg)}`);
|
|
2692
2698
|
}
|
|
2693
2699
|
emit_log_callback("warning", msg, hora);
|
|
@@ -2695,24 +2701,32 @@ function log_warning(format) {
|
|
|
2695
2701
|
function log_info(format) {
|
|
2696
2702
|
let msg = format_log(format);
|
|
2697
2703
|
let hora = current_timestamp();
|
|
2698
|
-
if (f_info)
|
|
2704
|
+
if (f_info) {
|
|
2705
|
+
if (__console_output_enabled__) f_info("%c" + hora + " INFO: " + String(msg), "color:cyan");
|
|
2706
|
+
}
|
|
2699
2707
|
emit_log_callback("info", msg, hora);
|
|
2700
2708
|
}
|
|
2701
2709
|
function log_debug(format) {
|
|
2702
2710
|
let msg = format_log(format);
|
|
2703
2711
|
let hora = current_timestamp();
|
|
2704
|
-
if (f_debug)
|
|
2712
|
+
if (f_debug) {
|
|
2713
|
+
if (__console_output_enabled__) f_debug("%c" + hora + " DEBUG: " + String(msg), "color:silver");
|
|
2714
|
+
}
|
|
2705
2715
|
emit_log_callback("debug", msg, hora);
|
|
2706
2716
|
}
|
|
2707
2717
|
function trace_msg(format) {
|
|
2708
2718
|
let msg = format_log(format);
|
|
2709
2719
|
let hora = current_timestamp();
|
|
2710
|
-
if (f_debug)
|
|
2720
|
+
if (f_debug) {
|
|
2721
|
+
if (__console_output_enabled__) f_debug("%c" + hora + " MSG: " + String(msg), "color:cyan");
|
|
2722
|
+
}
|
|
2711
2723
|
emit_log_callback("msg", msg, hora);
|
|
2712
2724
|
}
|
|
2713
2725
|
function trace_json(jn, msg) {
|
|
2714
|
-
if (
|
|
2715
|
-
|
|
2726
|
+
if (__console_output_enabled__) {
|
|
2727
|
+
if (msg) window.console.warn("=====> " + msg);
|
|
2728
|
+
window.console.dir(jn);
|
|
2729
|
+
}
|
|
2716
2730
|
emit_log_callback("json", jn, current_timestamp());
|
|
2717
2731
|
}
|
|
2718
2732
|
/************************************************************
|
|
@@ -3525,17 +3539,26 @@ function kw_get_local_storage_value(key, default_value, create = false) {
|
|
|
3525
3539
|
}
|
|
3526
3540
|
/********************************************
|
|
3527
3541
|
* Save a local attribute
|
|
3542
|
+
*
|
|
3543
|
+
* Returns 0 on success, -1 when the value did NOT reach the store.
|
|
3544
|
+
* It used to return nothing and only console.warn, so every caller up the
|
|
3545
|
+
* chain (db_save_persistent_attrs -> gobj_save_persistent_attrs -> the app)
|
|
3546
|
+
* reported success on a store that had rejected the write: a full or blocked
|
|
3547
|
+
* localStorage (quota, private mode) silently discarded the change while the
|
|
3548
|
+
* UI showed it as saved.
|
|
3528
3549
|
********************************************/
|
|
3529
3550
|
function kw_set_local_storage_value(key, value) {
|
|
3530
|
-
if (typeof window === "undefined" || !window.localStorage) return;
|
|
3551
|
+
if (typeof window === "undefined" || !window.localStorage) return 0;
|
|
3531
3552
|
if (!key || value === void 0) {
|
|
3532
|
-
|
|
3533
|
-
return;
|
|
3553
|
+
log_error(`kw_set_local_storage_value(): invalid key or value: key=${key}`);
|
|
3554
|
+
return -1;
|
|
3534
3555
|
}
|
|
3535
3556
|
try {
|
|
3536
3557
|
window.localStorage.setItem(key, JSON.stringify(value));
|
|
3558
|
+
return 0;
|
|
3537
3559
|
} catch (e) {
|
|
3538
|
-
|
|
3560
|
+
log_error(`kw_set_local_storage_value(): cannot save "${key}" (storage full or blocked?): ${e && e.message ? e.message : e}`);
|
|
3561
|
+
return -1;
|
|
3539
3562
|
}
|
|
3540
3563
|
}
|
|
3541
3564
|
/********************************************
|
|
@@ -4510,6 +4533,10 @@ function refresh_language(element, t) {
|
|
|
4510
4533
|
let value = elem.getAttribute("data-i18n-aria-label");
|
|
4511
4534
|
if (value) elem.setAttribute("aria-label", t(value));
|
|
4512
4535
|
});
|
|
4536
|
+
element.querySelectorAll("[data-i18n-placeholder]").forEach(function(elem) {
|
|
4537
|
+
let value = elem.getAttribute("data-i18n-placeholder");
|
|
4538
|
+
if (value) elem.setAttribute("placeholder", t(value));
|
|
4539
|
+
});
|
|
4513
4540
|
}
|
|
4514
4541
|
/************************************************************
|
|
4515
4542
|
* Example Usage
|
|
@@ -4691,13 +4718,16 @@ function db_load_persistent_attrs(gobj, keys) {
|
|
|
4691
4718
|
}
|
|
4692
4719
|
}
|
|
4693
4720
|
/************************************************************
|
|
4694
|
-
*
|
|
4721
|
+
* Returns 0 on success, -1 when the attrs did NOT reach the store
|
|
4722
|
+
* (quota exceeded, private mode, storage disabled). Callers must check
|
|
4723
|
+
* it: a discarded write with a UI that shows the value as saved is the
|
|
4724
|
+
* worst of both worlds.
|
|
4695
4725
|
************************************************************/
|
|
4696
4726
|
function db_save_persistent_attrs(gobj, keys) {
|
|
4697
4727
|
let attrs = kw_clone_by_keys(gobj, gobj_read_attrs(gobj, sdata_flag_t.SDF_PERSIST, 0), keys, false);
|
|
4698
4728
|
let jn_file = kw_get_local_storage_value(_get_persistent_path(gobj), null, false);
|
|
4699
4729
|
if (jn_file && is_object(jn_file)) json_object_update_missing(attrs, jn_file);
|
|
4700
|
-
kw_set_local_storage_value(_get_persistent_path(gobj), attrs);
|
|
4730
|
+
return kw_set_local_storage_value(_get_persistent_path(gobj), attrs);
|
|
4701
4731
|
}
|
|
4702
4732
|
/************************************************************
|
|
4703
4733
|
*
|
|
@@ -5446,7 +5476,9 @@ var attrs_table = [
|
|
|
5446
5476
|
SDATA(data_type_t.DTP_STRING, "jwt", sdata_flag_t.SDF_PERSIST, "", "JWT"),
|
|
5447
5477
|
SDATA(data_type_t.DTP_STRING, "cert_pem", sdata_flag_t.SDF_PERSIST, "", "SSL server certification, PEM str format"),
|
|
5448
5478
|
SDATA(data_type_t.DTP_JSON, "extra_info", sdata_flag_t.SDF_RD, "{}", "dict data set by user, added to the identity card msg."),
|
|
5449
|
-
SDATA(data_type_t.
|
|
5479
|
+
SDATA(data_type_t.DTP_LIST, "required_services", sdata_flag_t.SDF_RD, "[]", "Services this LINK requires (identity card). Empty = the yuno's `required_services`, as before. A yuno with several links to DIFFERENT backends must set it per link: the yuno-wide list is the union, so every backend is told the service names of all the others."),
|
|
5480
|
+
SDATA(data_type_t.DTP_INTEGER, "timeout_retry", sdata_flag_t.SDF_RD, "5000", "First reconnect delay (ms). It BACKS OFF from here, doubling up to timeout_retry_max, and resets when a session is reached"),
|
|
5481
|
+
SDATA(data_type_t.DTP_INTEGER, "timeout_retry_max", sdata_flag_t.SDF_RD, "60000", "Cap of the reconnect backoff (ms). Set it equal to timeout_retry for the old fixed-interval behaviour"),
|
|
5450
5482
|
SDATA(data_type_t.DTP_INTEGER, "timeout_idack", sdata_flag_t.SDF_RD, "5000", "timeout waiting idAck"),
|
|
5451
5483
|
SDATA(data_type_t.DTP_POINTER, "subscriber", 0, 0, "subscriber of output-events. If null then subscriber is the parent"),
|
|
5452
5484
|
SDATA_END()
|
|
@@ -5459,7 +5491,8 @@ var PRIVATE_DATA = {
|
|
|
5459
5491
|
gobj_timer: null,
|
|
5460
5492
|
inform_on_close: false,
|
|
5461
5493
|
websocket: null,
|
|
5462
|
-
inside_on_open: false
|
|
5494
|
+
inside_on_open: false,
|
|
5495
|
+
retry_ms: 0
|
|
5463
5496
|
};
|
|
5464
5497
|
var __gclass__ = null;
|
|
5465
5498
|
/******************************
|
|
@@ -5507,6 +5540,7 @@ function mt_writing(gobj, path) {
|
|
|
5507
5540
|
function mt_start(gobj) {
|
|
5508
5541
|
let priv = gobj.priv;
|
|
5509
5542
|
gobj_start(priv.gobj_timer);
|
|
5543
|
+
priv.retry_ms = 0;
|
|
5510
5544
|
priv.websocket = setup_websocket(gobj);
|
|
5511
5545
|
return 0;
|
|
5512
5546
|
}
|
|
@@ -5765,6 +5799,8 @@ function send_identity_card(gobj) {
|
|
|
5765
5799
|
let yuno_version = gobj_read_str_attr(gobj_yuno(), "yuno_version");
|
|
5766
5800
|
let yuno_release = gobj_read_str_attr(gobj_yuno(), "yuno_release");
|
|
5767
5801
|
let yuno_tag = gobj_read_str_attr(gobj_yuno(), "yuno_tag");
|
|
5802
|
+
let required_services = gobj_read_attr(gobj, "required_services");
|
|
5803
|
+
if (!required_services || !required_services.length) required_services = gobj_read_attr(gobj_yuno(), "required_services");
|
|
5768
5804
|
let kw = {
|
|
5769
5805
|
"yuno_role": gobj_yuno_role(),
|
|
5770
5806
|
"yuno_id": gobj_yuno_id(),
|
|
@@ -5783,7 +5819,7 @@ function send_identity_card(gobj) {
|
|
|
5783
5819
|
"id": node_uuid(),
|
|
5784
5820
|
"user_agent": typeof window !== "undefined" ? window.navigator.userAgent : "",
|
|
5785
5821
|
"language": typeof window !== "undefined" ? window.navigator.language : "",
|
|
5786
|
-
"required_services":
|
|
5822
|
+
"required_services": required_services
|
|
5787
5823
|
};
|
|
5788
5824
|
msg_iev_push_stack(gobj, kw, IEVENT_STACK_ID, build_cli_ievent_request(gobj, gobj_name(gobj_parent(gobj)), null));
|
|
5789
5825
|
msg_iev_set_msg_type(gobj, kw, "__identity__");
|
|
@@ -5912,9 +5948,37 @@ function ac_on_close(gobj, event, kw, src) {
|
|
|
5912
5948
|
was_clean: e.wasClean
|
|
5913
5949
|
});
|
|
5914
5950
|
}
|
|
5915
|
-
if (gobj_is_running(gobj)) set_timeout(priv.gobj_timer,
|
|
5951
|
+
if (gobj_is_running(gobj)) set_timeout(priv.gobj_timer, next_retry(gobj));
|
|
5916
5952
|
return 0;
|
|
5917
5953
|
}
|
|
5954
|
+
/***************************************************************
|
|
5955
|
+
* How long to wait before the next reconnect attempt.
|
|
5956
|
+
*
|
|
5957
|
+
* The delay used to be a constant (`timeout_retry`, 5s), for ever. A
|
|
5958
|
+
* backend that is down — or a URL with a typo, which never comes back —
|
|
5959
|
+
* was therefore hit every 5 seconds for the whole life of the tab, by
|
|
5960
|
+
* EVERY link pointed at it, all in lockstep. It backs off now: from
|
|
5961
|
+
* `timeout_retry`, doubling, capped at `timeout_retry_max`.
|
|
5962
|
+
*
|
|
5963
|
+
* The jitter (±20%) is what breaks the lockstep. Without it, N links that
|
|
5964
|
+
* went down together retry together for ever — a thundering herd against a
|
|
5965
|
+
* backend that is just coming back up. It is the one place a random number
|
|
5966
|
+
* earns its keep.
|
|
5967
|
+
*
|
|
5968
|
+
* Reset to zero when a session is actually reached
|
|
5969
|
+
* (ac_identity_card_ack), so a link that flaps once does not carry a
|
|
5970
|
+
* minute-long penalty into its next real drop.
|
|
5971
|
+
***************************************************************/
|
|
5972
|
+
function next_retry(gobj) {
|
|
5973
|
+
let priv = gobj.priv;
|
|
5974
|
+
let base = gobj_read_integer_attr(gobj, "timeout_retry");
|
|
5975
|
+
let max = gobj_read_integer_attr(gobj, "timeout_retry_max");
|
|
5976
|
+
if (max < base) max = base;
|
|
5977
|
+
priv.retry_ms = priv.retry_ms ? Math.min(priv.retry_ms * 2, max) : base;
|
|
5978
|
+
let jitter = priv.retry_ms * .2;
|
|
5979
|
+
let ms = priv.retry_ms - jitter + Math.random() * 2 * jitter;
|
|
5980
|
+
return Math.max(1, Math.round(ms));
|
|
5981
|
+
}
|
|
5918
5982
|
/********************************************
|
|
5919
5983
|
*
|
|
5920
5984
|
********************************************/
|
|
@@ -5955,6 +6019,7 @@ function ac_identity_card_ack(gobj, event, kw, src) {
|
|
|
5955
6019
|
} else {
|
|
5956
6020
|
gobj_change_state(gobj, "ST_SESSION");
|
|
5957
6021
|
priv.inside_on_open = true;
|
|
6022
|
+
priv.retry_ms = 0;
|
|
5958
6023
|
if (!priv.inform_on_close) {
|
|
5959
6024
|
priv.inform_on_close = true;
|
|
5960
6025
|
let kw_on_open = {
|
|
@@ -6378,6 +6443,7 @@ exports.register_c_yuno = register_c_yuno;
|
|
|
6378
6443
|
exports.safeSrc = safeSrc;
|
|
6379
6444
|
exports.sdata_flag_t = sdata_flag_t;
|
|
6380
6445
|
exports.send_http_json_post = send_http_json_post;
|
|
6446
|
+
exports.set_console_log_enabled = set_console_log_enabled;
|
|
6381
6447
|
exports.set_log_callback = set_log_callback;
|
|
6382
6448
|
exports.set_remote_log_functions = set_remote_log_functions;
|
|
6383
6449
|
exports.set_timeout = set_timeout;
|