@yuneta/gobj-js 7.25.6 → 7.25.8

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 CHANGED
@@ -300,6 +300,24 @@ gobj_subscribe_event(source_gobj, "EV_DATA_READY", {}, subscriber_gobj);
300
300
  gobj_unsubscribe_event(source_gobj, "EV_DATA_READY", {}, subscriber_gobj);
301
301
  ```
302
302
 
303
+ **Which kw a subscriber gets** (since 7.25.8, the same rule as the C kernel):
304
+
305
+ - A subscription with a non-empty `__local__` (keys removed) or `__global__`
306
+ (keys added) gets a **twin** of the published kw: a new top-level object,
307
+ with the nested values shared. `__global__` goes in as a copy. What one
308
+ subscription removes or adds reaches only its own subscriber.
309
+ - Every other subscriber gets the **same** kw as the publisher. A receiver that
310
+ changes the kw it got must change a copy of its own (`C_IEVENT_CLI`'s
311
+ `mt_inject_event` does this before it writes its ievent stack).
312
+ - `__filter__` and `mt_publication_filter` see the publisher's kw.
313
+
314
+ ```javascript
315
+ gobj_subscribe_event(pub, "EV_X", {__global__: {tag: "a"}}, sub_a); // gets {v: 1, tag: "a"}
316
+ gobj_subscribe_event(pub, "EV_X", {__local__: {secret: 0}}, sub_b); // gets {v: 1}
317
+ gobj_subscribe_event(pub, "EV_X", {__filter__: {v: 1}}, sub_c); // gets the publisher's kw
318
+ gobj_publish_event(pub, "EV_X", {v: 1, secret: "s"}); // the kw stays {v: 1, secret: "s"}
319
+ ```
320
+
303
321
  ### GObject Tree (Yuno)
304
322
 
305
323
  GObjects form a parent-child tree. The root is the **Yuno**. Services live directly under the Yuno. Each GObject has exactly one parent (except the Yuno itself).
@@ -558,7 +576,11 @@ kw_get_dict_value(gobj, kw, path, default_value, flag)
558
576
  // KW_EXTRACT takes out only a value the reader answers with: a value
559
577
  // of another type stays in the kw.
560
578
 
561
- kw_set_dict_value(gobj, kw, path, value)
579
+ kw_set_dict_value(gobj, kw, path, value) // 0, or -1 logged
580
+ // A middle segment that is null or a scalar cannot hold the path:
581
+ // kw_set_dict_value() logs and answers -1, the kw is left as it was,
582
+ // and a reader with KW_CREATE answers its default (as C):
583
+ // kw_get_int(gobj, {a: null}, "a`b", 5, KW_CREATE) → 5, kw unchanged
562
584
  kw_set_subdict_value(gobj, kw, path, key, value)
563
585
 
564
586
  kw_match_simple(kw, filter) // → boolean
@@ -2954,11 +2954,10 @@ function gobj_publish_event(publisher, event, kw) {
2954
2954
  let __global__ = kw_get_dict(publisher, subs, "__global__", null, 0);
2955
2955
  let __local__ = kw_get_dict(publisher, subs, "__local__", null, 0);
2956
2956
  let __filter__ = kw_get_dict_value(publisher, subs, "__filter__", null, 0);
2957
- let kw2publish = kw;
2958
2957
  let topublish = 1;
2959
- if (publisher.gclass.gmt.mt_publication_filter) topublish = publisher.gclass.gmt.mt_publication_filter(publisher, event, kw2publish, subscriber);
2958
+ if (publisher.gclass.gmt.mt_publication_filter) topublish = publisher.gclass.gmt.mt_publication_filter(publisher, event, kw, subscriber);
2960
2959
  else if (json_size(__filter__) > 0) {
2961
- topublish = kw_match_simple(kw2publish, __filter__) ? 1 : 0;
2960
+ topublish = kw_match_simple(kw, __filter__) ? 1 : 0;
2962
2961
  if (tracea) {
2963
2962
  trace_machine(sprintf("💜💜🔄%s publishing with filter, event '%s', subscriber'%s', publisher %s", topublish ? "👍" : "👎", event ? event : "", gobj_short_name(subscriber), gobj_short_name(publisher)));
2964
2963
  trace_json(__filter__);
@@ -2972,9 +2971,11 @@ function gobj_publish_event(publisher, event, kw) {
2972
2971
  if (!gobj_has_event(subscriber, ev_.event_name, 0)) continue;
2973
2972
  }
2974
2973
  }
2975
- if (__local__) kw_pop(kw2publish, __local__);
2974
+ let kw2publish = kw;
2975
+ if (json_size(__local__) > 0 || json_size(__global__) > 0) kw2publish = Object.assign({}, kw);
2976
+ if (json_size(__local__) > 0) kw_pop(kw2publish, __local__);
2976
2977
  if (__config__) {}
2977
- if (__global__) json_object_update(kw2publish, __global__);
2978
+ if (json_size(__global__) > 0) json_object_update(kw2publish, json_deep_copy(__global__));
2978
2979
  if (tracea) {
2979
2980
  if (__trace_machine_format__ === 1) trace_machine(sprintf("🔝🔄 %s (%s) %s%s", event ? event : "", event ? event : "", !subscriber.running ? "!!" : "", gobj_short_name(subscriber)));
2980
2981
  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)));
@@ -3978,7 +3979,12 @@ function kw_set_dict_value(gobj, kw, path, value) {
3978
3979
  let key = ss[i];
3979
3980
  if (i === len - 1) kw[key] = value;
3980
3981
  else {
3981
- if (kw[key] === void 0) kw[key] = {};
3982
+ let seg = kw[key];
3983
+ if (seg === void 0) kw[key] = {};
3984
+ else if (!is_object(seg) && !is_array(seg)) {
3985
+ log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}kw_set_dict_value(): segment '${key}' is not a dict or a list: '${path}'`);
3986
+ return -1;
3987
+ }
3982
3988
  kw = kw[key];
3983
3989
  }
3984
3990
  }
@@ -6702,7 +6708,8 @@ function mt_inject_event(gobj, event, kw, src) {
6702
6708
  window.console.error(`Not in session`);
6703
6709
  return -1;
6704
6710
  }
6705
- if (!kw) kw = {};
6711
+ kw = Object.assign({}, is_object(kw) ? kw : {});
6712
+ if (is_object(kw["__md_iev__"])) kw["__md_iev__"] = json_deep_copy(kw["__md_iev__"]);
6706
6713
  if (msg_iev_get_stack(gobj, kw, IEVENT_STACK_ID)) {} else {
6707
6714
  let jn_ievent_id = build_cli_ievent_request(gobj, gobj_name(src), kw_get_str(gobj, kw, "__service__", 0, 0));
6708
6715
  json_object_del(kw, "__service__");