@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/dist/gobj-js.umd.js
CHANGED
|
@@ -2633,6 +2633,10 @@
|
|
|
2633
2633
|
function set_log_callback(fn) {
|
|
2634
2634
|
__log_callback__ = typeof fn === "function" ? fn : null;
|
|
2635
2635
|
}
|
|
2636
|
+
var __console_output_enabled__ = true;
|
|
2637
|
+
function set_console_log_enabled(enabled) {
|
|
2638
|
+
__console_output_enabled__ = enabled ? true : false;
|
|
2639
|
+
}
|
|
2636
2640
|
var __in_log_callback__ = false;
|
|
2637
2641
|
function emit_log_callback(level, msg, hora) {
|
|
2638
2642
|
if (__log_callback__ && !__in_log_callback__) {
|
|
@@ -2678,9 +2682,10 @@
|
|
|
2678
2682
|
function log_error(format) {
|
|
2679
2683
|
let msg = format_log(format);
|
|
2680
2684
|
let hora = current_timestamp();
|
|
2681
|
-
if (f_error) if (f_error === window.console.error)
|
|
2682
|
-
|
|
2683
|
-
|
|
2685
|
+
if (f_error) if (f_error === window.console.error) {
|
|
2686
|
+
if (__console_output_enabled__) f_error("%c" + hora + " ERROR: " + String(msg), "color:red");
|
|
2687
|
+
} else {
|
|
2688
|
+
if (__console_output_enabled__) window.console.error("%c" + hora + " ERROR: " + String(msg), "color:red");
|
|
2684
2689
|
f_error(`${hora} ERROR: ${String(msg)}`);
|
|
2685
2690
|
}
|
|
2686
2691
|
emit_log_callback("error", msg, hora);
|
|
@@ -2688,9 +2693,10 @@
|
|
|
2688
2693
|
function log_warning(format) {
|
|
2689
2694
|
let msg = format_log(format);
|
|
2690
2695
|
let hora = current_timestamp();
|
|
2691
|
-
if (f_warning) if (f_warning === window.console.warn)
|
|
2692
|
-
|
|
2693
|
-
|
|
2696
|
+
if (f_warning) if (f_warning === window.console.warn) {
|
|
2697
|
+
if (__console_output_enabled__) f_warning("%c" + hora + " WARNING: " + String(msg), "color:yellow");
|
|
2698
|
+
} else {
|
|
2699
|
+
if (__console_output_enabled__) window.console.warn("%c" + hora + " WARNING: " + String(msg), "color:yellow");
|
|
2694
2700
|
f_warning(`${hora} WARNING: ${String(msg)}`);
|
|
2695
2701
|
}
|
|
2696
2702
|
emit_log_callback("warning", msg, hora);
|
|
@@ -2698,24 +2704,32 @@
|
|
|
2698
2704
|
function log_info(format) {
|
|
2699
2705
|
let msg = format_log(format);
|
|
2700
2706
|
let hora = current_timestamp();
|
|
2701
|
-
if (f_info)
|
|
2707
|
+
if (f_info) {
|
|
2708
|
+
if (__console_output_enabled__) f_info("%c" + hora + " INFO: " + String(msg), "color:cyan");
|
|
2709
|
+
}
|
|
2702
2710
|
emit_log_callback("info", msg, hora);
|
|
2703
2711
|
}
|
|
2704
2712
|
function log_debug(format) {
|
|
2705
2713
|
let msg = format_log(format);
|
|
2706
2714
|
let hora = current_timestamp();
|
|
2707
|
-
if (f_debug)
|
|
2715
|
+
if (f_debug) {
|
|
2716
|
+
if (__console_output_enabled__) f_debug("%c" + hora + " DEBUG: " + String(msg), "color:silver");
|
|
2717
|
+
}
|
|
2708
2718
|
emit_log_callback("debug", msg, hora);
|
|
2709
2719
|
}
|
|
2710
2720
|
function trace_msg(format) {
|
|
2711
2721
|
let msg = format_log(format);
|
|
2712
2722
|
let hora = current_timestamp();
|
|
2713
|
-
if (f_debug)
|
|
2723
|
+
if (f_debug) {
|
|
2724
|
+
if (__console_output_enabled__) f_debug("%c" + hora + " MSG: " + String(msg), "color:cyan");
|
|
2725
|
+
}
|
|
2714
2726
|
emit_log_callback("msg", msg, hora);
|
|
2715
2727
|
}
|
|
2716
2728
|
function trace_json(jn, msg) {
|
|
2717
|
-
if (
|
|
2718
|
-
|
|
2729
|
+
if (__console_output_enabled__) {
|
|
2730
|
+
if (msg) window.console.warn("=====> " + msg);
|
|
2731
|
+
window.console.dir(jn);
|
|
2732
|
+
}
|
|
2719
2733
|
emit_log_callback("json", jn, current_timestamp());
|
|
2720
2734
|
}
|
|
2721
2735
|
/************************************************************
|
|
@@ -3528,17 +3542,26 @@
|
|
|
3528
3542
|
}
|
|
3529
3543
|
/********************************************
|
|
3530
3544
|
* Save a local attribute
|
|
3545
|
+
*
|
|
3546
|
+
* Returns 0 on success, -1 when the value did NOT reach the store.
|
|
3547
|
+
* It used to return nothing and only console.warn, so every caller up the
|
|
3548
|
+
* chain (db_save_persistent_attrs -> gobj_save_persistent_attrs -> the app)
|
|
3549
|
+
* reported success on a store that had rejected the write: a full or blocked
|
|
3550
|
+
* localStorage (quota, private mode) silently discarded the change while the
|
|
3551
|
+
* UI showed it as saved.
|
|
3531
3552
|
********************************************/
|
|
3532
3553
|
function kw_set_local_storage_value(key, value) {
|
|
3533
|
-
if (typeof window === "undefined" || !window.localStorage) return;
|
|
3554
|
+
if (typeof window === "undefined" || !window.localStorage) return 0;
|
|
3534
3555
|
if (!key || value === void 0) {
|
|
3535
|
-
|
|
3536
|
-
return;
|
|
3556
|
+
log_error(`kw_set_local_storage_value(): invalid key or value: key=${key}`);
|
|
3557
|
+
return -1;
|
|
3537
3558
|
}
|
|
3538
3559
|
try {
|
|
3539
3560
|
window.localStorage.setItem(key, JSON.stringify(value));
|
|
3561
|
+
return 0;
|
|
3540
3562
|
} catch (e) {
|
|
3541
|
-
|
|
3563
|
+
log_error(`kw_set_local_storage_value(): cannot save "${key}" (storage full or blocked?): ${e && e.message ? e.message : e}`);
|
|
3564
|
+
return -1;
|
|
3542
3565
|
}
|
|
3543
3566
|
}
|
|
3544
3567
|
/********************************************
|
|
@@ -4513,6 +4536,10 @@
|
|
|
4513
4536
|
let value = elem.getAttribute("data-i18n-aria-label");
|
|
4514
4537
|
if (value) elem.setAttribute("aria-label", t(value));
|
|
4515
4538
|
});
|
|
4539
|
+
element.querySelectorAll("[data-i18n-placeholder]").forEach(function(elem) {
|
|
4540
|
+
let value = elem.getAttribute("data-i18n-placeholder");
|
|
4541
|
+
if (value) elem.setAttribute("placeholder", t(value));
|
|
4542
|
+
});
|
|
4516
4543
|
}
|
|
4517
4544
|
/************************************************************
|
|
4518
4545
|
* Example Usage
|
|
@@ -4694,13 +4721,16 @@
|
|
|
4694
4721
|
}
|
|
4695
4722
|
}
|
|
4696
4723
|
/************************************************************
|
|
4697
|
-
*
|
|
4724
|
+
* Returns 0 on success, -1 when the attrs did NOT reach the store
|
|
4725
|
+
* (quota exceeded, private mode, storage disabled). Callers must check
|
|
4726
|
+
* it: a discarded write with a UI that shows the value as saved is the
|
|
4727
|
+
* worst of both worlds.
|
|
4698
4728
|
************************************************************/
|
|
4699
4729
|
function db_save_persistent_attrs(gobj, keys) {
|
|
4700
4730
|
let attrs = kw_clone_by_keys(gobj, gobj_read_attrs(gobj, sdata_flag_t.SDF_PERSIST, 0), keys, false);
|
|
4701
4731
|
let jn_file = kw_get_local_storage_value(_get_persistent_path(gobj), null, false);
|
|
4702
4732
|
if (jn_file && is_object(jn_file)) json_object_update_missing(attrs, jn_file);
|
|
4703
|
-
kw_set_local_storage_value(_get_persistent_path(gobj), attrs);
|
|
4733
|
+
return kw_set_local_storage_value(_get_persistent_path(gobj), attrs);
|
|
4704
4734
|
}
|
|
4705
4735
|
/************************************************************
|
|
4706
4736
|
*
|
|
@@ -5449,7 +5479,9 @@
|
|
|
5449
5479
|
SDATA(data_type_t.DTP_STRING, "jwt", sdata_flag_t.SDF_PERSIST, "", "JWT"),
|
|
5450
5480
|
SDATA(data_type_t.DTP_STRING, "cert_pem", sdata_flag_t.SDF_PERSIST, "", "SSL server certification, PEM str format"),
|
|
5451
5481
|
SDATA(data_type_t.DTP_JSON, "extra_info", sdata_flag_t.SDF_RD, "{}", "dict data set by user, added to the identity card msg."),
|
|
5452
|
-
SDATA(data_type_t.
|
|
5482
|
+
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."),
|
|
5483
|
+
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"),
|
|
5484
|
+
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"),
|
|
5453
5485
|
SDATA(data_type_t.DTP_INTEGER, "timeout_idack", sdata_flag_t.SDF_RD, "5000", "timeout waiting idAck"),
|
|
5454
5486
|
SDATA(data_type_t.DTP_POINTER, "subscriber", 0, 0, "subscriber of output-events. If null then subscriber is the parent"),
|
|
5455
5487
|
SDATA_END()
|
|
@@ -5462,7 +5494,8 @@
|
|
|
5462
5494
|
gobj_timer: null,
|
|
5463
5495
|
inform_on_close: false,
|
|
5464
5496
|
websocket: null,
|
|
5465
|
-
inside_on_open: false
|
|
5497
|
+
inside_on_open: false,
|
|
5498
|
+
retry_ms: 0
|
|
5466
5499
|
};
|
|
5467
5500
|
var __gclass__ = null;
|
|
5468
5501
|
/******************************
|
|
@@ -5510,6 +5543,7 @@
|
|
|
5510
5543
|
function mt_start(gobj) {
|
|
5511
5544
|
let priv = gobj.priv;
|
|
5512
5545
|
gobj_start(priv.gobj_timer);
|
|
5546
|
+
priv.retry_ms = 0;
|
|
5513
5547
|
priv.websocket = setup_websocket(gobj);
|
|
5514
5548
|
return 0;
|
|
5515
5549
|
}
|
|
@@ -5768,6 +5802,8 @@
|
|
|
5768
5802
|
let yuno_version = gobj_read_str_attr(gobj_yuno(), "yuno_version");
|
|
5769
5803
|
let yuno_release = gobj_read_str_attr(gobj_yuno(), "yuno_release");
|
|
5770
5804
|
let yuno_tag = gobj_read_str_attr(gobj_yuno(), "yuno_tag");
|
|
5805
|
+
let required_services = gobj_read_attr(gobj, "required_services");
|
|
5806
|
+
if (!required_services || !required_services.length) required_services = gobj_read_attr(gobj_yuno(), "required_services");
|
|
5771
5807
|
let kw = {
|
|
5772
5808
|
"yuno_role": gobj_yuno_role(),
|
|
5773
5809
|
"yuno_id": gobj_yuno_id(),
|
|
@@ -5786,7 +5822,7 @@
|
|
|
5786
5822
|
"id": node_uuid(),
|
|
5787
5823
|
"user_agent": typeof window !== "undefined" ? window.navigator.userAgent : "",
|
|
5788
5824
|
"language": typeof window !== "undefined" ? window.navigator.language : "",
|
|
5789
|
-
"required_services":
|
|
5825
|
+
"required_services": required_services
|
|
5790
5826
|
};
|
|
5791
5827
|
msg_iev_push_stack(gobj, kw, IEVENT_STACK_ID, build_cli_ievent_request(gobj, gobj_name(gobj_parent(gobj)), null));
|
|
5792
5828
|
msg_iev_set_msg_type(gobj, kw, "__identity__");
|
|
@@ -5915,9 +5951,37 @@
|
|
|
5915
5951
|
was_clean: e.wasClean
|
|
5916
5952
|
});
|
|
5917
5953
|
}
|
|
5918
|
-
if (gobj_is_running(gobj)) set_timeout(priv.gobj_timer,
|
|
5954
|
+
if (gobj_is_running(gobj)) set_timeout(priv.gobj_timer, next_retry(gobj));
|
|
5919
5955
|
return 0;
|
|
5920
5956
|
}
|
|
5957
|
+
/***************************************************************
|
|
5958
|
+
* How long to wait before the next reconnect attempt.
|
|
5959
|
+
*
|
|
5960
|
+
* The delay used to be a constant (`timeout_retry`, 5s), for ever. A
|
|
5961
|
+
* backend that is down — or a URL with a typo, which never comes back —
|
|
5962
|
+
* was therefore hit every 5 seconds for the whole life of the tab, by
|
|
5963
|
+
* EVERY link pointed at it, all in lockstep. It backs off now: from
|
|
5964
|
+
* `timeout_retry`, doubling, capped at `timeout_retry_max`.
|
|
5965
|
+
*
|
|
5966
|
+
* The jitter (±20%) is what breaks the lockstep. Without it, N links that
|
|
5967
|
+
* went down together retry together for ever — a thundering herd against a
|
|
5968
|
+
* backend that is just coming back up. It is the one place a random number
|
|
5969
|
+
* earns its keep.
|
|
5970
|
+
*
|
|
5971
|
+
* Reset to zero when a session is actually reached
|
|
5972
|
+
* (ac_identity_card_ack), so a link that flaps once does not carry a
|
|
5973
|
+
* minute-long penalty into its next real drop.
|
|
5974
|
+
***************************************************************/
|
|
5975
|
+
function next_retry(gobj) {
|
|
5976
|
+
let priv = gobj.priv;
|
|
5977
|
+
let base = gobj_read_integer_attr(gobj, "timeout_retry");
|
|
5978
|
+
let max = gobj_read_integer_attr(gobj, "timeout_retry_max");
|
|
5979
|
+
if (max < base) max = base;
|
|
5980
|
+
priv.retry_ms = priv.retry_ms ? Math.min(priv.retry_ms * 2, max) : base;
|
|
5981
|
+
let jitter = priv.retry_ms * .2;
|
|
5982
|
+
let ms = priv.retry_ms - jitter + Math.random() * 2 * jitter;
|
|
5983
|
+
return Math.max(1, Math.round(ms));
|
|
5984
|
+
}
|
|
5921
5985
|
/********************************************
|
|
5922
5986
|
*
|
|
5923
5987
|
********************************************/
|
|
@@ -5958,6 +6022,7 @@
|
|
|
5958
6022
|
} else {
|
|
5959
6023
|
gobj_change_state(gobj, "ST_SESSION");
|
|
5960
6024
|
priv.inside_on_open = true;
|
|
6025
|
+
priv.retry_ms = 0;
|
|
5961
6026
|
if (!priv.inform_on_close) {
|
|
5962
6027
|
priv.inform_on_close = true;
|
|
5963
6028
|
let kw_on_open = {
|
|
@@ -6381,6 +6446,7 @@
|
|
|
6381
6446
|
exports.safeSrc = safeSrc;
|
|
6382
6447
|
exports.sdata_flag_t = sdata_flag_t;
|
|
6383
6448
|
exports.send_http_json_post = send_http_json_post;
|
|
6449
|
+
exports.set_console_log_enabled = set_console_log_enabled;
|
|
6384
6450
|
exports.set_log_callback = set_log_callback;
|
|
6385
6451
|
exports.set_remote_log_functions = set_remote_log_functions;
|
|
6386
6452
|
exports.set_timeout = set_timeout;
|