@yuneta/gobj-js 7.26.0 → 7.26.2

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.
@@ -898,17 +898,20 @@
898
898
  break;
899
899
  case data_type_t.DTP_JSON:
900
900
  jn_value2 = jn_value_;
901
- if (is_string(jn_value_)) try {
902
- jn_value2 = JSON.parse(jn_value_);
903
- } catch (error) {
904
- jn_value2 = jn_value_;
901
+ if (is_string(jn_value_)) {
902
+ const t = jn_value_.trim();
903
+ if (t.startsWith("{") || t.startsWith("[")) try {
904
+ jn_value2 = JSON.parse(t);
905
+ } catch (error) {
906
+ jn_value2 = jn_value_;
907
+ }
905
908
  }
906
909
  break;
907
910
  case data_type_t.DTP_POINTER: jn_value2 = jn_value_;
908
911
  }
909
912
  if (jn_value2 === void 0) log_error(`${gobj_short_name(gobj)}: attr undefined: ${it.name}`);
910
913
  sdata[it.name] = jn_value2;
911
- if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(it.name)) gobj.priv[it.name] = jn_value2;
914
+ if (is_object(gobj.priv) && Object.prototype.hasOwnProperty.call(gobj.priv, it.name)) gobj.priv[it.name] = jn_value2;
912
915
  if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
913
916
  if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, it.name);
914
917
  }
@@ -2111,7 +2114,7 @@
2111
2114
  function gobj_read_attr(gobj, name, src) {
2112
2115
  let jn_attrs = gobj.jn_attrs;
2113
2116
  if (name in jn_attrs) {
2114
- if (jn_attrs.hasOwnProperty(name)) {
2117
+ if (Object.prototype.hasOwnProperty.call(jn_attrs, name)) {
2115
2118
  let value = jn_attrs[name];
2116
2119
  if (gobj.gclass.gmt.mt_reading) return gobj.gclass.gmt.mt_reading(gobj, name, value);
2117
2120
  return value;
@@ -2217,9 +2220,9 @@
2217
2220
  if (ss.length <= 1) {
2218
2221
  let key = path;
2219
2222
  if (key in jn_attrs) {
2220
- if (jn_attrs.hasOwnProperty(key)) {
2223
+ if (Object.prototype.hasOwnProperty.call(jn_attrs, key)) {
2221
2224
  jn_attrs[key] = value;
2222
- if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(key)) gobj.priv[key] = value;
2225
+ if (is_object(gobj.priv) && Object.prototype.hasOwnProperty.call(gobj.priv, key)) gobj.priv[key] = value;
2223
2226
  if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
2224
2227
  if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, key);
2225
2228
  }
@@ -2240,9 +2243,9 @@
2240
2243
  }
2241
2244
  let jn_attrs = gobj.jn_attrs;
2242
2245
  if (key in jn_attrs) {
2243
- if (jn_attrs.hasOwnProperty(key)) {
2246
+ if (Object.prototype.hasOwnProperty.call(jn_attrs, key)) {
2244
2247
  jn_attrs[key] = value;
2245
- if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(key)) gobj.priv[key] = value;
2248
+ if (is_object(gobj.priv) && Object.prototype.hasOwnProperty.call(gobj.priv, key)) gobj.priv[key] = value;
2246
2249
  if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
2247
2250
  if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, key);
2248
2251
  }
@@ -2269,7 +2272,7 @@
2269
2272
  if (exclude_flag && it.flag & exclude_flag) continue;
2270
2273
  if (include_flag === -1 || it.flag & include_flag) {
2271
2274
  set_default(gobj, gobj.jn_attrs, it);
2272
- if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(it.name)) gobj.priv[it.name] = gobj.jn_attrs[it.name];
2275
+ if (is_object(gobj.priv) && Object.prototype.hasOwnProperty.call(gobj.priv, it.name)) gobj.priv[it.name] = gobj.jn_attrs[it.name];
2273
2276
  if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, it.name);
2274
2277
  }
2275
2278
  }
@@ -2303,7 +2306,7 @@
2303
2306
  let hs = gobj_hsdata2(gobj, name, false);
2304
2307
  if (hs) {
2305
2308
  hs[name] = parseBoolean(value);
2306
- if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] = hs[name];
2309
+ if (is_object(gobj.priv) && Object.prototype.hasOwnProperty.call(gobj.priv, name)) gobj.priv[name] = hs[name];
2307
2310
  if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
2308
2311
  if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, name);
2309
2312
  }
@@ -2319,7 +2322,7 @@
2319
2322
  let hs = gobj_hsdata2(gobj, name, false);
2320
2323
  if (hs) {
2321
2324
  hs[name] = parseInt(value);
2322
- if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] = hs[name];
2325
+ if (is_object(gobj.priv) && Object.prototype.hasOwnProperty.call(gobj.priv, name)) gobj.priv[name] = hs[name];
2323
2326
  if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
2324
2327
  if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, name);
2325
2328
  }
@@ -2335,7 +2338,7 @@
2335
2338
  let hs = gobj_hsdata2(gobj, name, false);
2336
2339
  if (hs) {
2337
2340
  hs[name] = String(value);
2338
- if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] = hs[name];
2341
+ if (is_object(gobj.priv) && Object.prototype.hasOwnProperty.call(gobj.priv, name)) gobj.priv[name] = hs[name];
2339
2342
  if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
2340
2343
  if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, name);
2341
2344
  }
@@ -2602,7 +2605,7 @@
2602
2605
  } catch (e) {
2603
2606
  __inside__--;
2604
2607
  if (!(e && e.__gobj_logged__)) {
2605
- log_error(`${gobj_short_name(dst)}: action of ${event} in ${dst.current_state.state_name} THREW: ${e && e.stack ? e.stack : e}`);
2608
+ log_error(`${gobj_short_name(dst)}: action of ${event} in ${state.state_name} THREW: ${e && e.stack ? e.stack : e}`);
2606
2609
  try {
2607
2610
  e.__gobj_logged__ = true;
2608
2611
  } catch (e2) {}
@@ -2723,8 +2726,8 @@
2723
2726
  kw,
2724
2727
  renamed_event: ""
2725
2728
  };
2726
- let kw_match = Object.assign({}, kw);
2727
- let config_match = Object.assign({}, __config__);
2729
+ let kw_match = json_object_update({}, kw);
2730
+ let config_match = json_object_update({}, __config__);
2728
2731
  kw_match.__config__ = config_match;
2729
2732
  let renamed_event = "";
2730
2733
  let rename = config_match.__rename_event_name__;
@@ -2732,7 +2735,7 @@
2732
2735
  if (event_type) {
2733
2736
  renamed_event = event_type.event_name;
2734
2737
  delete config_match.__rename_event_name__;
2735
- if (event && json_size(kw_match.__global__) > 0) kw_match.__global__ = Object.assign({}, kw_match.__global__, { __original_event_name__: event });
2738
+ if (event && json_size(kw_match.__global__) > 0) kw_match.__global__ = json_object_update(json_object_update({}, kw_match.__global__), { __original_event_name__: event });
2736
2739
  }
2737
2740
  delete config_match.__hard_subscription__;
2738
2741
  delete config_match.__own_event__;
@@ -3108,7 +3111,7 @@
3108
3111
  }
3109
3112
  }
3110
3113
  let kw2publish = kw;
3111
- if (json_size(__local__) > 0 || json_size(__global__) > 0) kw2publish = Object.assign({}, kw);
3114
+ if (json_size(__local__) > 0 || json_size(__global__) > 0) kw2publish = json_object_update({}, kw);
3112
3115
  if (json_size(__local__) > 0) kw_pop(kw2publish, __local__);
3113
3116
  if (__config__) {}
3114
3117
  if (json_size(__global__) > 0) json_object_update(kw2publish, json_deep_copy(__global__));
@@ -3610,7 +3613,7 @@
3610
3613
  if ((is_secret_name(key.slice(-128)) || value_is_secret && key === "value") && value !== void 0 && value !== null && value !== "") shown = "********";
3611
3614
  else shown = _json_mask_secrets(value, memo, depth + 1, budget);
3612
3615
  if (shown !== value) changed = true;
3613
- result[key] = shown;
3616
+ set_own_key(result, key, shown);
3614
3617
  }
3615
3618
  if (truncated) result["<more>"] = MASK_TOO_LARGE;
3616
3619
  }
@@ -3645,10 +3648,7 @@
3645
3648
  ************************************************************/
3646
3649
  function duplicate_objects(...sourceObjects) {
3647
3650
  const result = {};
3648
- for (const obj of sourceObjects) {
3649
- const clonedObj = structuredClone(obj);
3650
- Object.assign(result, clonedObj);
3651
- }
3651
+ for (const obj of sourceObjects) json_object_update(result, structuredClone(obj));
3652
3652
  return result;
3653
3653
  }
3654
3654
  /************************************************************
@@ -3682,7 +3682,7 @@
3682
3682
  ************************************************************/
3683
3683
  function json_object_update(destination, source) {
3684
3684
  if (!source) return destination;
3685
- for (let property of Object.keys(source)) destination[property] = source[property];
3685
+ for (let property of Object.keys(source)) set_own_key(destination, property, source[property]);
3686
3686
  return destination;
3687
3687
  }
3688
3688
  /************************************************************
@@ -3691,7 +3691,7 @@
3691
3691
  ************************************************************/
3692
3692
  function json_object_update_existing(destination, source) {
3693
3693
  if (!source) return destination;
3694
- for (let property in source) if (source.hasOwnProperty(property) && destination.hasOwnProperty(property)) destination[property] = source[property];
3694
+ for (let property in source) if (Object.prototype.hasOwnProperty.call(source, property) && Object.prototype.hasOwnProperty.call(destination, property)) set_own_key(destination, property, source[property]);
3695
3695
  return destination;
3696
3696
  }
3697
3697
  /************************************************************
@@ -3700,32 +3700,32 @@
3700
3700
  ************************************************************/
3701
3701
  function json_object_update_missing(destination, source) {
3702
3702
  if (!source) return destination;
3703
- for (let property in source) if (source.hasOwnProperty(property) && !destination.hasOwnProperty(property)) destination[property] = source[property];
3703
+ for (let property in source) if (Object.prototype.hasOwnProperty.call(source, property) && !Object.prototype.hasOwnProperty.call(destination, property)) set_own_key(destination, property, source[property]);
3704
3704
  return destination;
3705
3705
  }
3706
3706
  /************************************************************
3707
3707
  * Simulate jansson function
3708
3708
  ************************************************************/
3709
3709
  function json_object_get(o, key) {
3710
- if (o && o.hasOwnProperty(key)) return o[key];
3710
+ if (o && Object.prototype.hasOwnProperty.call(o, key)) return o[key];
3711
3711
  }
3712
3712
  /************************************************************
3713
3713
  * Simulate jansson function
3714
3714
  ************************************************************/
3715
3715
  function json_object_del(o, k) {
3716
- if (o && o.hasOwnProperty(k)) delete o[k];
3716
+ if (o && Object.prototype.hasOwnProperty.call(o, k)) delete o[k];
3717
3717
  }
3718
3718
  /************************************************************
3719
3719
  * Simulate jansson function
3720
3720
  ************************************************************/
3721
3721
  function json_object_set(o, k, v) {
3722
- o[k] = v;
3722
+ set_own_key(o, k, v);
3723
3723
  }
3724
3724
  /************************************************************
3725
3725
  * Simulate jansson function
3726
3726
  ************************************************************/
3727
3727
  function json_object_set_new(o, k, v) {
3728
- o[k] = v;
3728
+ set_own_key(o, k, v);
3729
3729
  }
3730
3730
  /************************************************************
3731
3731
  * Simulate jansson function
@@ -3969,22 +3969,20 @@
3969
3969
  ************************************************************/
3970
3970
  function kw_has_key(kw, key) {
3971
3971
  if (key in kw) {
3972
- if (kw.hasOwnProperty(key)) return true;
3972
+ if (Object.prototype.hasOwnProperty.call(kw, key)) return true;
3973
3973
  }
3974
3974
  return false;
3975
3975
  }
3976
3976
  /************************************************************
3977
3977
  * A key that reaches the prototype chain instead of the data:
3978
- * "__proto__", "constructor" or "prototype" when the object
3979
- * does not hold it as its OWN key. A walk through one of them
3978
+ * any key the object does not hold as its OWN key. A walk through one of them
3980
3979
  * read, or WROTE, Object.prototype: the flat id
3981
3980
  * "__proto__`polluted" set a key on every object of the page.
3982
3981
  * In C they are keys like any other, so here too: read them
3983
3982
  * only as own keys, and write "__proto__" as an own key.
3984
3983
  ************************************************************/
3985
3984
  function is_prototype_segment(obj, key) {
3986
- if (key === "__proto__" || key === "constructor" || key === "prototype") return !Object.prototype.hasOwnProperty.call(obj, key);
3987
- return false;
3985
+ return !Object.prototype.hasOwnProperty.call(obj, key);
3988
3986
  }
3989
3987
  function set_own_key(obj, key, value) {
3990
3988
  if (key === "__proto__") Object.defineProperty(obj, key, {
@@ -4023,6 +4021,13 @@
4023
4021
  let ss = path.split("`");
4024
4022
  let len = ss.length;
4025
4023
  for (let i = 0; i < len; i++) {
4024
+ if (is_array(kw)) {
4025
+ if (!/^[0-9]+$/.test(ss[i])) {
4026
+ if (verbose) log_error(`${prefix}path not found: '${path}'`);
4027
+ return;
4028
+ }
4029
+ ss[i] = String(Number(ss[i]));
4030
+ }
4026
4031
  if (is_prototype_segment(kw, ss[i])) {
4027
4032
  if (verbose) log_error(`${prefix}path not found: '${path}'`);
4028
4033
  return;
@@ -4440,7 +4445,7 @@
4440
4445
  log_error("subdict is not an object");
4441
4446
  return -1;
4442
4447
  }
4443
- subdict[key] = value;
4448
+ set_own_key(subdict, key, value);
4444
4449
  return 0;
4445
4450
  }
4446
4451
  /***************************************************************************
@@ -4567,14 +4572,14 @@
4567
4572
  let kw_clone = {};
4568
4573
  if (is_string(keys) && !empty_string(keys)) {
4569
4574
  let key = keys;
4570
- if (kw.hasOwnProperty(key)) kw_clone[key] = kw[key];
4575
+ if (Object.prototype.hasOwnProperty.call(kw, key)) set_own_key(kw_clone, key, kw[key]);
4571
4576
  else if (verbose) log_error(`${gobj_short_name(gobj)}: key not found: ${key}`);
4572
4577
  } else if (is_object(keys) && json_object_size(keys) > 0) {
4573
- for (let key of Object.keys(keys)) if (kw.hasOwnProperty(key)) kw_clone[key] = kw[key];
4578
+ for (let key of Object.keys(keys)) if (Object.prototype.hasOwnProperty.call(kw, key)) set_own_key(kw_clone, key, kw[key]);
4574
4579
  else if (verbose) log_error(`${gobj_short_name(gobj)}: key not found: ${key}`);
4575
4580
  } else if (is_array(keys) && json_array_size(keys) > 0) for (let j = 0; j < keys.length; j++) {
4576
4581
  let key = keys[j];
4577
- if (kw.hasOwnProperty(key)) kw_clone[key] = kw[key];
4582
+ if (Object.prototype.hasOwnProperty.call(kw, key)) set_own_key(kw_clone, key, kw[key]);
4578
4583
  else if (verbose) log_error(`${gobj_short_name(gobj)}: key not found: ${key}`);
4579
4584
  }
4580
4585
  else return kw;
@@ -4596,14 +4601,14 @@
4596
4601
  json_object_update(kw_clone, kw);
4597
4602
  if (is_string(keys) && !empty_string(keys)) {
4598
4603
  let key = keys;
4599
- if (kw.hasOwnProperty(key)) json_object_del(kw_clone, key);
4604
+ if (Object.prototype.hasOwnProperty.call(kw, key)) json_object_del(kw_clone, key);
4600
4605
  else if (verbose) log_error(`${gobj_short_name(gobj)}: key not found: ${key}`);
4601
4606
  } else if (is_object(keys) && json_object_size(keys) > 0) {
4602
- for (let key of Object.keys(keys)) if (kw.hasOwnProperty(key)) json_object_del(kw_clone, key);
4607
+ for (let key of Object.keys(keys)) if (Object.prototype.hasOwnProperty.call(kw, key)) json_object_del(kw_clone, key);
4603
4608
  else if (verbose) log_error(`${gobj_short_name(gobj)}: key not found: ${key}`);
4604
4609
  } else if (is_array(keys) && json_array_size(keys) > 0) for (let j = 0; j < keys.length; j++) {
4605
4610
  let key = keys[j];
4606
- if (kw.hasOwnProperty(key)) json_object_del(kw_clone, key);
4611
+ if (Object.prototype.hasOwnProperty.call(kw, key)) json_object_del(kw_clone, key);
4607
4612
  else if (verbose) log_error(`${gobj_short_name(gobj)}: key not found: ${key}`);
4608
4613
  }
4609
4614
  else return {};
@@ -4748,7 +4753,7 @@
4748
4753
  else if (is_array(kw)) for (let i = 0; i < kw.length; i++) {
4749
4754
  let kv = kw[i];
4750
4755
  let id = kw_get_str(gobj, kv, "id", "", kw_flag_t.KW_REQUIRED);
4751
- if (!empty_string(id)) new_dict[id] = kv;
4756
+ if (!empty_string(id)) set_own_key(new_dict, id, kv);
4752
4757
  }
4753
4758
  else log_error(`${gobj_short_name(gobj)} kwid_new_dict: data type unknown`);
4754
4759
  return new_dict;
@@ -4834,7 +4839,7 @@
4834
4839
  let new_ids = [];
4835
4840
  if (is_string(ids)) new_ids.push(ids);
4836
4841
  else if (is_object(ids)) {
4837
- for (let id in ids) if (ids.hasOwnProperty(id)) new_ids.push(id);
4842
+ for (let id in ids) if (Object.prototype.hasOwnProperty.call(ids, id)) new_ids.push(id);
4838
4843
  } else if (is_array(ids)) ids.forEach(function(item) {
4839
4844
  if (is_string(item)) {
4840
4845
  if (!empty_string(item)) new_ids.push(item);
@@ -5087,7 +5092,7 @@
5087
5092
  function _traverse_dict(obj, callback, full_path) {
5088
5093
  if (full_path === void 0 || !is_string(full_path)) full_path = "";
5089
5094
  for (let key of Object.keys(obj)) {
5090
- if (!obj.hasOwnProperty(key)) continue;
5095
+ if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
5091
5096
  let sufix = (full_path.length ? "`" : "") + key;
5092
5097
  full_path += sufix;
5093
5098
  callback.apply(this, [
@@ -5194,11 +5199,11 @@
5194
5199
  }
5195
5200
  if (ids.length === 0 && v) {
5196
5201
  if (is_array(v)) v.push(kw);
5197
- else if (v["id"] === kw["id"]) Object.assign(v, kw);
5202
+ else if (v["id"] === kw["id"]) json_object_update(v, kw);
5198
5203
  else {
5199
5204
  let v_ = kw_get_dict_value(null, v, jdb.hook, [], 1);
5200
5205
  let v__ = _jdb_get(v_, jdb.hook, kw["id"], false);
5201
- if (v__) Object.assign(v__, kw);
5206
+ if (v__) json_object_update(v__, kw);
5202
5207
  else v_.push(kw);
5203
5208
  }
5204
5209
  }
@@ -5565,6 +5570,10 @@
5565
5570
  * as a bare string, or "<img src=x onerror=...>" runs.
5566
5571
  * Pass it as a Text node, which is always text:
5567
5572
  * ['span', {}, document.createTextNode(value)]
5573
+ * In a LIST of children a node (element, svg, Text) is
5574
+ * appended as it is and a string is always text -- but a
5575
+ * list whose first item is a string is read as ONE
5576
+ * description (the string is its tag).
5568
5577
  * if attrs['i18n'] is not empty then (or 'data-i18n' or 'data_i18next')
5569
5578
  * it will be overridden with the translation
5570
5579
  * content = translate(attrs['i18n']));
@@ -5617,8 +5626,11 @@
5617
5626
  } else if (is_array(content)) {
5618
5627
  if (content.length > 0) {
5619
5628
  if (is_string(content[0])) el.appendChild(createElement2(content, translate_fn));
5620
- else for (let child of content) if (Array.isArray(child) && child.length > 0) el.appendChild(createElement2(child, translate_fn));
5621
- else if (child instanceof HTMLElement) el.appendChild(child);
5629
+ else for (let child of content) if (Array.isArray(child)) {
5630
+ if (child.length > 0) el.appendChild(createElement2(child, translate_fn));
5631
+ } else if (child instanceof Node) el.appendChild(child);
5632
+ else if (is_string(child)) el.appendChild(document.createTextNode(child));
5633
+ else if (child !== null && child !== void 0 && child !== false) log_error(`createElement2: child ignored, type ${typeof child}`);
5622
5634
  }
5623
5635
  } else if (content instanceof HTMLElement || content instanceof Text || content instanceof SVGElement) el.appendChild(content);
5624
5636
  else if (content != null) {
@@ -5968,7 +5980,7 @@
5968
5980
  return;
5969
5981
  }
5970
5982
  if (depth === 0) return;
5971
- flat[path] = value;
5983
+ set_own_key(flat, path, value);
5972
5984
  };
5973
5985
  if (jn === void 0 || jn === null) return flat;
5974
5986
  walk(jn, "", 0);
@@ -6051,12 +6063,12 @@
6051
6063
  removed: {},
6052
6064
  changed: {}
6053
6065
  };
6054
- for (const key of Object.keys(a)) if (!Object.prototype.hasOwnProperty.call(b, key)) diff.removed[key] = a[key];
6055
- else if (!flat_value_equal(a[key], b[key])) diff.changed[key] = {
6066
+ for (const key of Object.keys(a)) if (!Object.prototype.hasOwnProperty.call(b, key)) set_own_key(diff.removed, key, a[key]);
6067
+ else if (!flat_value_equal(a[key], b[key])) set_own_key(diff.changed, key, {
6056
6068
  from: a[key],
6057
6069
  to: b[key]
6058
- };
6059
- for (const key of Object.keys(b)) if (!Object.prototype.hasOwnProperty.call(a, key)) diff.added[key] = b[key];
6070
+ });
6071
+ for (const key of Object.keys(b)) if (!Object.prototype.hasOwnProperty.call(a, key)) set_own_key(diff.added, key, b[key]);
6060
6072
  return diff;
6061
6073
  }
6062
6074
  /************************************************************
@@ -6070,11 +6082,11 @@
6070
6082
  if (flat === null || typeof flat !== "object" || Array.isArray(flat)) throw new Error("flat_apply: a flat json is an object of id -> value");
6071
6083
  if (diff === null || typeof diff !== "object") throw new Error("flat_apply: a diff is the object flat_diff() answers");
6072
6084
  for (const key of Object.keys(diff.removed || {})) delete flat[key];
6073
- for (const key of Object.keys(diff.added || {})) flat[key] = diff.added[key];
6085
+ for (const key of Object.keys(diff.added || {})) set_own_key(flat, key, diff.added[key]);
6074
6086
  for (const key of Object.keys(diff.changed || {})) {
6075
6087
  const change = diff.changed[key];
6076
6088
  if (!change || !Object.prototype.hasOwnProperty.call(change, "to")) throw new Error(`flat_apply: changed '${key}' without a 'to'`);
6077
- flat[key] = change.to;
6089
+ set_own_key(flat, key, change.to);
6078
6090
  }
6079
6091
  return flat;
6080
6092
  }
@@ -7164,7 +7176,7 @@
7164
7176
  window.console.error(`Not in session`);
7165
7177
  return -1;
7166
7178
  }
7167
- kw = Object.assign({}, is_object(kw) ? kw : {});
7179
+ kw = json_object_update({}, is_object(kw) ? kw : {});
7168
7180
  if (is_object(kw["__md_iev__"])) kw["__md_iev__"] = json_deep_copy(kw["__md_iev__"]);
7169
7181
  if (msg_iev_get_stack(gobj, kw, IEVENT_STACK_ID)) {} else {
7170
7182
  let jn_ievent_id = build_cli_ievent_request(gobj, gobj_name(src), kw_get_str(gobj, kw, "__service__", 0, 0));
@@ -7216,18 +7228,25 @@
7216
7228
  if (gobj.priv.websocket) log_error(`Websocket ALREADY setup`);
7217
7229
  const url = gobj_read_str_attr(gobj, "url");
7218
7230
  log_debug(`====> Starting WebSocket to '${url}' (${gobj_short_name(gobj)})`);
7231
+ const ws_seq = ++gobj.priv.ws_seq;
7219
7232
  let websocket;
7220
7233
  try {
7221
7234
  websocket = new WebSocket(url);
7222
7235
  } catch (e) {
7223
7236
  log_error(`${gobj_short_name(gobj)}: Cannot open WebSocket to '${url}', Error: ${e.message}`);
7237
+ gobj_post_event(gobj, "EV_ON_CLOSE", {
7238
+ url,
7239
+ ws_seq,
7240
+ code: 1006,
7241
+ reason: e.message,
7242
+ was_clean: false
7243
+ }, gobj);
7224
7244
  return null;
7225
7245
  }
7226
7246
  if (!websocket) {
7227
7247
  log_error(`${gobj_short_name(gobj)}: Failed to initialize WebSocket.`);
7228
7248
  return null;
7229
7249
  }
7230
- const ws_seq = ++gobj.priv.ws_seq;
7231
7250
  websocket.onopen = () => {
7232
7251
  if (ws_seq !== gobj.priv.ws_seq || gobj_is_destroying(gobj)) return;
7233
7252
  gobj_send_event(gobj, "EV_ON_OPEN", {
@@ -7480,6 +7499,7 @@
7480
7499
  function ac_on_close(gobj, event, kw, src) {
7481
7500
  let priv = gobj.priv;
7482
7501
  let url = kw.url;
7502
+ if (kw.ws_seq !== void 0 && kw.ws_seq !== priv.ws_seq) return 0;
7483
7503
  set_remote_log_functions();
7484
7504
  log_warning(`${gobj_short_name(gobj)}: WebSocket closed ${url} (Code: ${kw.code}, Reason: "${kw.reason}", Clean: ${kw.was_clean})`);
7485
7505
  if (priv.websocket) {
@@ -7497,7 +7517,7 @@
7497
7517
  remote_yuno_role: priv.remote_yuno_role,
7498
7518
  remote_yuno_service: priv.remote_yuno_service
7499
7519
  });
7500
- } else {
7520
+ } else if (!gobj_is_running(gobj)) {} else {
7501
7521
  log_warning(`${gobj_short_name(gobj)}: EV_ON_OPEN_ERROR cannot open ${url} (Code: ${kw.code}, Reason: "${kw.reason}", Clean: ${kw.was_clean})`);
7502
7522
  gobj_publish_event(gobj, "EV_ON_OPEN_ERROR", {
7503
7523
  url,