@yuneta/gobj-ui 7.25.19 → 7.25.21

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
@@ -586,21 +586,40 @@ Two layout facts the browser taught this component, both worth keeping:
586
586
  `"graph"`), `$container` (mounted by the parent).
587
587
  - Input events: `EV_SET_JSON {json}` (replace the whole document; `ST_EMPTY` →
588
588
  `ST_READY`), `EV_SUBTREE_LOADED {path, json}` (splice a fetched subtree),
589
- `EV_SUBTREE_ERROR {path, error}`, `EV_SET_VIEW_MODE {mode}` (`"tree"` /
589
+ `EV_SUBTREE_ERROR {path, error | i18n, by_design}`, `EV_SET_VIEW_MODE {mode}` (`"tree"` /
590
590
  `"text"` / `"graph"`; **no mode advances** to the next view, which is what
591
591
  the two-view toggle did when the list was two long), plus `EV_REFRESH` /
592
592
  `EV_SHOW` / `EV_HIDE` / `EV_LANGUAGE_CHANGED`.
593
593
  - Output event: `EV_EXPAND_PATH {path, size}` (`EVF_OUTPUT_EVENT`) — the parent
594
594
  must declare it in its own FSM (CHILD subscription model), and ANSWER it: the
595
595
  stub shows "loading" until `EV_SUBTREE_LOADED` or `EV_SUBTREE_ERROR` arrives.
596
+ **Every** way the drill can fail is an answer: a request asked out of
597
+ session, or refused by the transport on its way out, never reaches the
598
+ backend, so no answer will ever come back for it -- the host answers it
599
+ itself (`C_YUI_TREEDB_TOPICS` / `C_YUI_TREEDB_GRAPH` since `7.25.21`: `i18n:
600
+ "no session"`, or the transport's refusal as `error`). While a path is
601
+ pending the viewer ignores every click on it, so a drill left unanswered
602
+ is a dead stub for the life of the viewer.
596
603
  A host that cannot read a subtree says so with the error, as
597
604
  `C_YUI_TREEDB_TOPIC_WITH_FORM` does for its schema, cell and table viewers
598
605
  since `7.25.19` (before, it declared nothing: *"Event NOT DEFINED"*):
599
606
  ```js
600
- gobj_send_event(src, "EV_SUBTREE_ERROR",
601
- {path: kw.path, error: t("this part cannot be loaded here")}, gobj);
602
- ``` That is the ONLY
603
- one, on purpose: this viewer is a child of its host and subscribes it to
607
+ gobj_send_event(src, "EV_SUBTREE_ERROR", {
608
+ path: kw.path,
609
+ i18n: "this part cannot be loaded here", // a KEY: t(key) + data-i18n
610
+ by_design: true // not a failure: logged as a warning
611
+ }, gobj);
612
+ ```
613
+ `error` is text, drawn as it came (a backend's comment); `i18n` is a key,
614
+ so the stub changes language with the app -- a text translated by the host
615
+ stays in the language it was sent in. The name `i18n` is the one a
616
+ `validate-locales` scan looks for, so the key stays visible to it. `by_design`
617
+ says the host CANNOT, which is not a failure: the viewer logs it as a
618
+ WARNING, and anything else as an ERROR. Before `7.25.20` the form sent
619
+ `t(...)`, and every click on a stub logged an ERROR, which broke a
620
+ clean-console check and reached the backend through the remote log.
621
+
622
+ `EV_EXPAND_PATH` is the ONLY output event, on purpose: this viewer is a child of its host and subscribes it to
604
623
  everything it publishes, so every output event is a mandatory declaration in
605
624
  every host's FSM. The graph child's `EV_JSON_ITEM_CLICKED` stops here
606
625
  (`7.21.0` forwarded it and broke exactly that way); a host that wants node
@@ -1900,10 +1919,34 @@ worked only in a test whose fake transport echoed the whole request. The host
1900
1919
  now puts the topic in the echo it asks for:
1901
1920
 
1902
1921
  ```js
1903
- kw.__md_command__ = {topic_name: "__graphs__", graph_topic: "users"};
1922
+ kw.__md_command__ = {topic_name: "__graphs__", graph_topic: "users", graphs_load: 3};
1904
1923
  // the answer: __md_iev__.command_stack[0].kw === that echo, and nothing else
1905
1924
  ```
1906
1925
 
1926
+ **A refusal belongs to the LOAD its write was sent from** (since `7.25.20`).
1927
+ "A reload forgets it" held only for a refusal that arrived BEFORE the reload:
1928
+ one answered after it was applied to the fresh load -- Save, Refresh, then the
1929
+ refusal lands -- and lit Save over nothing changed, and pressing it wrote a
1930
+ record identical to what the backend holds. The engine now counts its loads
1931
+ (each `EV_CLEAR_DATA` starts one) and puts the number in every `EV_UPDATE_NODE`
1932
+ of `__graphs__` as `graphs_load`; the host echoes it in `__md_command__` and
1933
+ hands it back with `EV_GRAPHS_WRITE_REFUSED {topic, graphs_load}`. A refusal of
1934
+ an earlier load is logged as a warning and ignored. A host that sends no
1935
+ `graphs_load` is taken at its word, as before:
1936
+
1937
+ ```js
1938
+ // in the host: the engine's load, from the EV_UPDATE_NODE it published
1939
+ gobj_send_event(engine, "EV_GRAPHS_WRITE_REFUSED",
1940
+ {topic: record.topic, graphs_load: kw.graphs_load}, gobj);
1941
+ ```
1942
+
1943
+ **A `__graphs__` create echo moves only its own topic** (since `7.25.20`), as
1944
+ an update echo has since `7.25.19` (`apply_graphs_echo()`). The first record of
1945
+ a topic's arrangement -- from this browser or another -- rebuilt the saved
1946
+ copies of EVERY topic from the live objects the view arranges in place, so an
1947
+ unsaved change of another topic (a look reset in edition, say) counted as saved
1948
+ and the next Save did not write it.
1949
+
1907
1950
  **Every saved look has a way back, in the context menu** (since `7.23.134`,
1908
1951
  replacing `reset sizes` / `reset topic sizes`). In edition, the node, the port
1909
1952
  and the edge menus each offer three resets — this one, its kind (`reset topic
@@ -2381,7 +2424,13 @@ else.
2381
2424
  consumer's locales carry). A write that ends with an error -- a drop
2382
2425
  included -- still applies a position that waited, as a load does. Out of
2383
2426
  session a load is not asked at all (no *"not in session"* errors); the
2384
- reconnect loads.
2427
+ reconnect loads. **Nor is a write** (7.25.20): each one of the queue asks
2428
+ first, and out of session the writes end with `cannot reach the treedb`, a
2429
+ warning, and a reload owed to the next session. A direct `C_IEVENT_CLI`
2430
+ answers a command out of session with `null`, the answer of a request that
2431
+ left, so before this the editor sat in `ST_SAVING`, inert, until another
2432
+ drop. (gui_agent's `C_AGENT_TREEDB_LINK` answers an error string there, so
2433
+ it was not hit.)
2385
2434
  - **A dialog is built on ONE model, and a load that replaces it closes it**
2386
2435
  (7.25.9). Every load that lands bumps `model_gen`; a dialog records the one
2387
2436
  it was opened on, and its Save, its import Preview/Run, an orphan delete and
@@ -14743,10 +14743,18 @@ function push_collapsed_row(ctx, value, segments, depth, key, rows) {
14743
14743
  },
14744
14744
  is_pending ? "loading" : "click to load"
14745
14745
  ]);
14746
- if (err) children.push([
14746
+ if (err && err.is_key) children.push([
14747
+ "span",
14748
+ {
14749
+ class: "JSON_STUB_ERR has-text-danger is-size-7 ml-2",
14750
+ "data-i18n": err.error
14751
+ },
14752
+ (0, i18next.t)(err.error)
14753
+ ]);
14754
+ else if (err) children.push([
14747
14755
  "span",
14748
14756
  { class: "JSON_STUB_ERR has-text-danger is-size-7 ml-2" },
14749
- String(err)
14757
+ String(err.error)
14750
14758
  ]);
14751
14759
  let attrs = {
14752
14760
  class: "JSON_ROW JSON_COLLAPSED" + (is_pending ? " is-pending" : ""),
@@ -14963,14 +14971,32 @@ function ac_subtree_loaded(gobj, event, kw, src) {
14963
14971
  return 0;
14964
14972
  }
14965
14973
  /************************************************************
14966
- * EV_SUBTREE_ERROR { path, error } — mark the failed branch
14974
+ * EV_SUBTREE_ERROR { path, error | i18n, by_design }
14975
+ * — mark the branch that was not loaded.
14976
+ *
14977
+ * `error` is text, drawn as it came (a backend's comment).
14978
+ * `i18n` is a KEY, drawn as t(key) with data-i18n so the stub
14979
+ * changes language with the app (a text translated by the host
14980
+ * stays in the language it was sent in). The name is the one a
14981
+ * locale check scans for (`i18n: "<key>"`), so the key of every
14982
+ * host stays visible to it.
14983
+ * `by_design`: the host answers that it CANNOT read a subtree
14984
+ * (a form holds records, a pasted pad has no backend) -- that is
14985
+ * not a failure, and it is logged as a warning. Anything else is
14986
+ * a load that failed, logged as an error.
14967
14987
  ************************************************************/
14968
14988
  function ac_subtree_error(gobj, event, kw, src) {
14969
14989
  let priv = gobj.priv;
14970
14990
  let path = kw.path || "";
14991
+ let is_key = !!kw.i18n;
14992
+ let error = kw.i18n || kw.error || "error";
14971
14993
  priv.pending.delete(path);
14972
- priv.errors.set(path, kw.error || "error");
14973
- (0, _yuneta_gobj_js.log_error)(`${GCLASS_NAME$13}: subtree load failed at '${path}': ${kw.error || ""}`);
14994
+ priv.errors.set(path, {
14995
+ error,
14996
+ is_key
14997
+ });
14998
+ if (kw.by_design) (0, _yuneta_gobj_js.log_warning)(`${GCLASS_NAME$13}: subtree not loaded at '${path}': ${error}`);
14999
+ else (0, _yuneta_gobj_js.log_error)(`${GCLASS_NAME$13}: subtree load failed at '${path}': ${error}`);
14974
15000
  render_view$1(gobj);
14975
15001
  return 0;
14976
15002
  }
@@ -16023,7 +16049,8 @@ function ac_hide_diff(gobj, event, kw, src) {
16023
16049
  function ac_expand_path$1(gobj, event, kw, src) {
16024
16050
  (0, _yuneta_gobj_js.gobj_send_event)(src, "EV_SUBTREE_ERROR", {
16025
16051
  path: kw && kw.path || "",
16026
- error: (0, i18next.t)("collapsed in the source")
16052
+ i18n: "collapsed in the source",
16053
+ by_design: true
16027
16054
  }, gobj);
16028
16055
  return 0;
16029
16056
  }
@@ -25109,6 +25136,27 @@ function request_schema_file(gobj) {
25109
25136
  if (ret) (0, _yuneta_gobj_js.log_error)(ret);
25110
25137
  }
25111
25138
  /************************************************************
25139
+ * A drill (or the whole document) that will get no answer from the
25140
+ * backend is answered HERE, or its stub shows "loading" for the life
25141
+ * of the viewer: C_YUI_JSON ignores every click on a pending path.
25142
+ * `answer` is {i18n: <key>} or {error: <text>}.
25143
+ ************************************************************/
25144
+ function answer_print_tranger_refused$1(gobj, path, answer) {
25145
+ let jv = gobj.priv.json_gobj;
25146
+ if (!jv || !(0, _yuneta_gobj_js.is_gobj)(jv) || (0, _yuneta_gobj_js.gobj_is_destroying)(jv)) return;
25147
+ if (path) (0, _yuneta_gobj_js.gobj_send_event)(jv, "EV_SUBTREE_ERROR", Object.assign({ path }, answer), gobj);
25148
+ else yui_shell_show_error(yui_shell_of(gobj), answer.i18n || answer.error, { t: i18next.t });
25149
+ }
25150
+ /************************************************************
25151
+ * The text of a transport's refusal: gobj_command() answers a string,
25152
+ * a command response or a number.
25153
+ ************************************************************/
25154
+ function refusal_text$1(ret) {
25155
+ if (typeof ret === "string" && ret) return ret;
25156
+ if (ret && typeof ret === "object" && typeof ret.comment === "string" && ret.comment) return ret.comment;
25157
+ return "print-tranger failed";
25158
+ }
25159
+ /************************************************************
25112
25160
  * The whole tranger, for the raw-json viewer.
25113
25161
  ************************************************************/
25114
25162
  function request_print_tranger$1(gobj, path) {
@@ -25116,11 +25164,12 @@ function request_print_tranger$1(gobj, path) {
25116
25164
  let remote = (0, _yuneta_gobj_js.gobj_read_pointer_attr)(gobj, "gobj_remote_yuno");
25117
25165
  if (!remote) {
25118
25166
  (0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: No gobj_remote_yuno defined`);
25119
- let jv = priv.json_gobj;
25120
- if (path && jv && (0, _yuneta_gobj_js.is_gobj)(jv) && !(0, _yuneta_gobj_js.gobj_is_destroying)(jv)) (0, _yuneta_gobj_js.gobj_send_event)(jv, "EV_SUBTREE_ERROR", {
25121
- path,
25122
- error: (0, i18next.t)("no session")
25123
- }, gobj);
25167
+ answer_print_tranger_refused$1(gobj, path, { i18n: "no session" });
25168
+ return;
25169
+ }
25170
+ if (!is_connected$1(gobj)) {
25171
+ (0, _yuneta_gobj_js.log_warning)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: print-tranger '${path || ""}' not asked: no session`);
25172
+ answer_print_tranger_refused$1(gobj, path, { i18n: "no session" });
25124
25173
  return;
25125
25174
  }
25126
25175
  let ret = (0, _yuneta_gobj_js.gobj_command)(remote, "print-tranger", {
@@ -25131,7 +25180,10 @@ function request_print_tranger$1(gobj, path) {
25131
25180
  path: path || "",
25132
25181
  __md_command__: { path: path || "" }
25133
25182
  }, gobj);
25134
- if (ret) (0, _yuneta_gobj_js.log_error)(ret);
25183
+ if (ret) {
25184
+ (0, _yuneta_gobj_js.log_error)(ret);
25185
+ answer_print_tranger_refused$1(gobj, path, { error: refusal_text$1(ret) });
25186
+ }
25135
25187
  }
25136
25188
  /***************************************************************
25137
25189
  * The last gate before a write leaves for the yuno. The per-topic
@@ -29470,7 +29522,8 @@ function ac_expand_path(gobj, event, kw, src) {
29470
29522
  let path = kw && kw.path || "";
29471
29523
  (0, _yuneta_gobj_js.gobj_send_event)(src, "EV_SUBTREE_ERROR", {
29472
29524
  path,
29473
- error: (0, i18next.t)("this part cannot be loaded here")
29525
+ i18n: "this part cannot be loaded here",
29526
+ by_design: true
29474
29527
  }, gobj);
29475
29528
  return 0;
29476
29529
  }
@@ -59294,6 +59347,7 @@ var PRIVATE_DATA$4 = {
59294
59347
  _graph_properties: {},
59295
59348
  _saved_graph_properties: {},
59296
59349
  _graphs_writes_owed: {},
59350
+ _graphs_load: 0,
59297
59351
  yet_showed: false,
59298
59352
  edit_mode: false,
59299
59353
  operation_mode: null,
@@ -61003,7 +61057,8 @@ function save_topic_graph_properties(gobj, topic_name) {
61003
61057
  list_dict: true,
61004
61058
  autolink: false,
61005
61059
  create: true
61006
- }
61060
+ },
61061
+ graphs_load: priv._graphs_load
61007
61062
  };
61008
61063
  (0, _yuneta_gobj_js.gobj_publish_event)(gobj, "EV_UPDATE_NODE", kw_update);
61009
61064
  }
@@ -65784,6 +65839,7 @@ function ac_clear_data(gobj, event, kw, src) {
65784
65839
  hide_create_popover(gobj);
65785
65840
  (0, _yuneta_gobj_js.gobj_write_attr)(gobj, "records", {});
65786
65841
  priv._graphs_writes_owed = {};
65842
+ priv._graphs_load++;
65787
65843
  priv._nodes_total = 0;
65788
65844
  priv._nodes_placed = 0;
65789
65845
  priv._fold_model = null;
@@ -65885,12 +65941,19 @@ function ac_save_graph(gobj, event, kw, src) {
65885
65941
  /************************************************************
65886
65942
  * The host says a write of `__graphs__` did not land: the
65887
65943
  * backend refused it, the transport refused it on the way out,
65888
- * or there was no session to send it on. kw: {topic}
65944
+ * or there was no session to send it on.
65945
+ * kw: {topic, graphs_load}
65889
65946
  *
65890
65947
  * save_topic_graph_properties() recorded it as saved before it
65891
65948
  * left. Forgotten now, and the Save is lit again: the next Save
65892
65949
  * writes the topic again. Before, the view believed the backend
65893
65950
  * held the arrangement, and the next Save had nothing to write.
65951
+ *
65952
+ * `graphs_load` is the load the write was sent from, echoed by the
65953
+ * host. A refusal of an EARLIER load is about an arrangement the
65954
+ * reload replaced with what the backend holds: applied, it lit the
65955
+ * Save over nothing changed (before gobj-ui 7.25.20). A host that
65956
+ * echoes no load is taken at its word, as before.
65894
65957
  ************************************************************/
65895
65958
  function ac_graphs_write_refused(gobj, event, kw, src) {
65896
65959
  let priv = gobj.priv;
@@ -65899,6 +65962,10 @@ function ac_graphs_write_refused(gobj, event, kw, src) {
65899
65962
  (0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: ${event} names no topic`);
65900
65963
  return -1;
65901
65964
  }
65965
+ if (kw.graphs_load !== void 0 && kw.graphs_load !== priv._graphs_load) {
65966
+ (0, _yuneta_gobj_js.log_warning)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: a refused write of the arrangement of '${topic_name}' belongs to an earlier load: ignored`);
65967
+ return 0;
65968
+ }
65902
65969
  (0, _yuneta_gobj_js.log_warning)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: the arrangement of '${topic_name}' was not saved: the next Save writes it again`);
65903
65970
  forget_refused_graphs_write(priv._saved_graph_properties, topic_name);
65904
65971
  priv._graphs_writes_owed[topic_name] = true;
@@ -65932,7 +65999,7 @@ function ac_node_created(gobj, event, kw, src) {
65932
65999
  if (!priv.descs || !priv.graph) return 0;
65933
66000
  if (topic_name === "__graphs__") {
65934
66001
  priv.__graphs__.push(node);
65935
- build_graph_properties(gobj);
66002
+ apply_graphs_echo(priv._graph_properties, priv._saved_graph_properties, priv.__graphs__, node);
65936
66003
  settle_owed_graphs_write(gobj, node);
65937
66004
  return 0;
65938
66005
  }
@@ -68302,6 +68369,27 @@ function close_json_viewer(gobj) {
68302
68369
  }
68303
68370
  }
68304
68371
  /************************************************************
68372
+ * A drill (or the whole document) that will get no answer from the
68373
+ * backend is answered HERE, or its stub shows "loading" for the life
68374
+ * of the viewer: C_YUI_JSON ignores every click on a pending path.
68375
+ * `answer` is {i18n: <key>} or {error: <text>}.
68376
+ ************************************************************/
68377
+ function answer_print_tranger_refused(gobj, path, answer) {
68378
+ let jv = gobj.priv.json_gobj;
68379
+ if (!jv || !(0, _yuneta_gobj_js.is_gobj)(jv) || (0, _yuneta_gobj_js.gobj_is_destroying)(jv)) return;
68380
+ if (path) (0, _yuneta_gobj_js.gobj_send_event)(jv, "EV_SUBTREE_ERROR", Object.assign({ path }, answer), gobj);
68381
+ else yui_shell_show_error(yui_shell_of(gobj), answer.i18n || answer.error, { t: i18next.t });
68382
+ }
68383
+ /************************************************************
68384
+ * The text of a transport's refusal: gobj_command() answers a string,
68385
+ * a command response or a number.
68386
+ ************************************************************/
68387
+ function refusal_text(ret) {
68388
+ if (typeof ret === "string" && ret) return ret;
68389
+ if (ret && typeof ret === "object" && typeof ret.comment === "string" && ret.comment) return ret.comment;
68390
+ return "print-tranger failed";
68391
+ }
68392
+ /************************************************************
68305
68393
  * Fetch the treedb's raw tranger (or one subtree when `path` is set) as
68306
68394
  * bounded, drillable JSON. Collapsed at 100 so a huge tranger stays a
68307
68395
  * small payload of `__collapsed__` stubs the viewer expands on demand.
@@ -68310,11 +68398,12 @@ function request_print_tranger(gobj, path) {
68310
68398
  let priv = gobj.priv;
68311
68399
  if (!priv.gobj_remote_yuno) {
68312
68400
  (0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: No gobj_remote_yuno defined`);
68313
- let jv = priv.json_gobj;
68314
- if (path && jv && (0, _yuneta_gobj_js.is_gobj)(jv) && !(0, _yuneta_gobj_js.gobj_is_destroying)(jv)) (0, _yuneta_gobj_js.gobj_send_event)(jv, "EV_SUBTREE_ERROR", {
68315
- path,
68316
- error: (0, i18next.t)("no session")
68317
- }, gobj);
68401
+ answer_print_tranger_refused(gobj, path, { i18n: "no session" });
68402
+ return;
68403
+ }
68404
+ if (!is_connected(gobj)) {
68405
+ (0, _yuneta_gobj_js.log_warning)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: print-tranger '${path || ""}' not asked: no session`);
68406
+ answer_print_tranger_refused(gobj, path, { i18n: "no session" });
68318
68407
  return;
68319
68408
  }
68320
68409
  let ret = (0, _yuneta_gobj_js.gobj_command)(priv.gobj_remote_yuno, "print-tranger", {
@@ -68325,7 +68414,10 @@ function request_print_tranger(gobj, path) {
68325
68414
  path: path || "",
68326
68415
  __md_command__: { path: path || "" }
68327
68416
  }, gobj);
68328
- if (ret) (0, _yuneta_gobj_js.log_error)(ret);
68417
+ if (ret) {
68418
+ (0, _yuneta_gobj_js.log_error)(ret);
68419
+ answer_print_tranger_refused(gobj, path, { error: refusal_text(ret) });
68420
+ }
68329
68421
  }
68330
68422
  /************************************************************
68331
68423
  * Populate layout dropdown from child's available layouts
@@ -68422,7 +68514,7 @@ function treedb_create_node(gobj, treedb_name, topic_name, record, options) {
68422
68514
  /************************************************************
68423
68515
  * Command to remote service
68424
68516
  ************************************************************/
68425
- function treedb_update_node(gobj, treedb_name, topic_name, record, options) {
68517
+ function treedb_update_node(gobj, treedb_name, topic_name, record, options, graphs_load) {
68426
68518
  let priv = gobj.priv;
68427
68519
  if (!priv.gobj_remote_yuno) {
68428
68520
  (0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: No gobj_remote_yuno defined`);
@@ -68437,7 +68529,10 @@ function treedb_update_node(gobj, treedb_name, topic_name, record, options) {
68437
68529
  options: options || {}
68438
68530
  };
68439
68531
  kw.__md_command__ = { topic_name };
68440
- if (topic_name === "__graphs__") kw.__md_command__.graph_topic = graph_topic_of(record);
68532
+ if (topic_name === "__graphs__") {
68533
+ kw.__md_command__.graph_topic = graph_topic_of(record);
68534
+ if (graphs_load !== void 0) kw.__md_command__.graphs_load = graphs_load;
68535
+ }
68441
68536
  let ret = (0, _yuneta_gobj_js.gobj_command)(priv.gobj_remote_yuno, command, kw, gobj);
68442
68537
  if (ret) {
68443
68538
  (0, _yuneta_gobj_js.log_error)(ret);
@@ -68741,7 +68836,7 @@ function ac_mt_command_answer$1(gobj, event, kw, src) {
68741
68836
  case "delete-node":
68742
68837
  case "link-nodes":
68743
68838
  case "unlink-nodes":
68744
- if (result < 0 && command === "update-node") graphs_write_refused(gobj, (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "topic_name", "", 0), (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "graph_topic", "", 0));
68839
+ if (result < 0 && command === "update-node") graphs_write_refused(gobj, (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "topic_name", "", 0), (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "graph_topic", "", 0), kw_command ? kw_command.graphs_load : void 0);
68745
68840
  if (result >= 0 && (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "topic_name", "", 0) !== "__graphs__") {
68746
68841
  let written = {
68747
68842
  treedb_name: priv.treedb_name,
@@ -68996,17 +69091,18 @@ function ac_update_node(gobj, event, kw, src) {
68996
69091
  let topic_name = kw.topic_name;
68997
69092
  let record = kw.record;
68998
69093
  let options = kw.options || {};
69094
+ let graphs_load = kw.graphs_load;
68999
69095
  if (refuse_if_readonly$1(gobj, event)) {
69000
- graphs_write_refused(gobj, topic_name, graph_topic_of(record));
69096
+ graphs_write_refused(gobj, topic_name, graph_topic_of(record), graphs_load);
69001
69097
  return -1;
69002
69098
  }
69003
69099
  if (topic_name === "__graphs__" && !is_connected(gobj)) {
69004
69100
  (0, _yuneta_gobj_js.log_warning)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: no session, the arrangement was not sent`);
69005
- graphs_write_refused(gobj, topic_name, graph_topic_of(record));
69101
+ graphs_write_refused(gobj, topic_name, graph_topic_of(record), graphs_load);
69006
69102
  return -1;
69007
69103
  }
69008
- let ret = treedb_update_node(gobj, treedb_name, topic_name, record, options);
69009
- if (ret < 0) graphs_write_refused(gobj, topic_name, graph_topic_of(record));
69104
+ let ret = treedb_update_node(gobj, treedb_name, topic_name, record, options, graphs_load);
69105
+ if (ret < 0) graphs_write_refused(gobj, topic_name, graph_topic_of(record), graphs_load);
69010
69106
  return ret;
69011
69107
  }
69012
69108
  /************************************************************
@@ -69021,9 +69117,11 @@ function graph_topic_of(record) {
69021
69117
  * (C_G6_NODES_TREE) took it for granted when it left -- nothing
69022
69118
  * answers it when it lands -- so it is told, and its next Save
69023
69119
  * writes the topic again. Other topics are the operator's data:
69024
- * the answer's error says what happened to them.
69120
+ * the answer's error says what happened to them. `graphs_load` is
69121
+ * the engine's load the write was sent from, handed back so it can
69122
+ * tell a refusal of an earlier load from one of the current.
69025
69123
  ************************************************************/
69026
- function graphs_write_refused(gobj, topic_name, topic) {
69124
+ function graphs_write_refused(gobj, topic_name, topic, graphs_load) {
69027
69125
  let priv = gobj.priv;
69028
69126
  if (topic_name !== "__graphs__") return;
69029
69127
  if (!topic) {
@@ -69031,7 +69129,9 @@ function graphs_write_refused(gobj, topic_name, topic) {
69031
69129
  return;
69032
69130
  }
69033
69131
  if (!priv.gobj_nodes_tree) return;
69034
- (0, _yuneta_gobj_js.gobj_send_event)(priv.gobj_nodes_tree, "EV_GRAPHS_WRITE_REFUSED", { topic }, gobj);
69132
+ let kw = { topic };
69133
+ if (graphs_load !== void 0) kw.graphs_load = graphs_load;
69134
+ (0, _yuneta_gobj_js.gobj_send_event)(priv.gobj_nodes_tree, "EV_GRAPHS_WRITE_REFUSED", kw, gobj);
69035
69135
  }
69036
69136
  /********************************************
69037
69137
  * Message from G6_nodes_tree
@@ -75222,13 +75322,18 @@ function run_next_write(gobj) {
75222
75322
  let write = priv.save_queue[0];
75223
75323
  let command = write_command(write.op);
75224
75324
  let options = write_options(write.op);
75325
+ if (!transport_in_session(gobj)) {
75326
+ (0, _yuneta_gobj_js.log_warning)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: no session, '${command}' of '${write.topic_name}' was not sent`);
75327
+ priv.reload_on_open = true;
75328
+ return end_writes(gobj, "cannot reach the treedb");
75329
+ }
75225
75330
  priv.write_tag++;
75226
75331
  if (remote_command(gobj, command, {
75227
75332
  topic_name: write.topic_name,
75228
75333
  record: write.record,
75229
75334
  options,
75230
75335
  record_id: write.record.id || ""
75231
- }, { write: priv.write_tag }) < 0) return end_writes(gobj, (0, i18next.t)("cannot reach the treedb"));
75336
+ }, { write: priv.write_tag }) < 0) return end_writes(gobj, "cannot reach the treedb");
75232
75337
  return 0;
75233
75338
  }
75234
75339
  /***************************************************************