@yuneta/gobj-ui 7.25.13 → 7.25.15
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 +61 -15
- package/dist/gobj-ui.cjs.js +209 -74
- package/dist/gobj-ui.es.js +209 -74
- package/package.json +1 -1
- package/src/c_g6_nodes_tree.js +42 -11
- package/src/c_yui_schema_editor.js +104 -37
- package/src/c_yui_treedb_graph.js +53 -6
- package/src/c_yui_treedb_topic_with_form.js +10 -10
- package/src/c_yui_treedb_topics.js +37 -32
- package/src/form_busy.js +2 -3
- package/src/form_time_value.js +1 -1
- package/src/form_time_value.test.js +1 -1
- package/src/form_writes_in_flight.js +1 -2
- package/src/g6_nodes_tree_fsm.test.js +33 -0
- package/src/graph_save_plan.js +28 -0
- package/src/graph_save_plan.test.js +36 -2
- package/src/host_drafts.js +2 -3
- package/src/schema_editor_drafts.wiring.test.js +1 -1
- package/src/schema_editor_reload.wiring.test.js +178 -46
- package/src/schema_editor_transport.wiring.test.js +2 -2
- package/src/schema_version_bump.test.js +1 -1
- package/src/shell_modals.js +2 -3
- package/src/shell_toast_once.test.js +10 -10
- package/src/table_cell_text.js +1 -1
- package/src/treedb_graph_writes.wiring.test.js +208 -0
- package/src/treedb_topics_transport.wiring.test.js +80 -12
- package/src/yui_row_search.test.js +1 -1
- package/src/yui_table_select.test.js +1 -1
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* through the real gclasses (C_YUI_SHELL, C_YUI_TREEDB_TOPICS) on a
|
|
6
6
|
* document double. The helper (form_writes_in_flight.js) was tested
|
|
7
7
|
* and right; what failed was that two hosts never called the action
|
|
8
|
-
* that uses it
|
|
8
|
+
* that uses it, which no helper test
|
|
9
9
|
* can see.
|
|
10
10
|
*
|
|
11
11
|
* Copyright (c) 2026, ArtGins.
|
|
@@ -30,6 +30,7 @@ const {register_c_yui_treedb_topics} = await import("./c_yui_treedb_topics.js");
|
|
|
30
30
|
|
|
31
31
|
const logged = [];
|
|
32
32
|
const answers = []; /* what the fake forms were told */
|
|
33
|
+
const loaded = []; /* the rows each fake form was loaded with */
|
|
33
34
|
const commands = []; /* what the fake transport was asked */
|
|
34
35
|
|
|
35
36
|
/*
|
|
@@ -57,6 +58,12 @@ function ac_form_answer(gobj, event, kw, src)
|
|
|
57
58
|
return 0;
|
|
58
59
|
}
|
|
59
60
|
|
|
61
|
+
function ac_form_load(gobj, event, kw, src)
|
|
62
|
+
{
|
|
63
|
+
loaded.push({topic: gobj.priv_topic, rows: kw});
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
|
|
60
67
|
let yuno = null;
|
|
61
68
|
let remote = null;
|
|
62
69
|
|
|
@@ -76,10 +83,11 @@ beforeAll(() => {
|
|
|
76
83
|
);
|
|
77
84
|
gclass_create(
|
|
78
85
|
"C_YUI_TREEDB_TOPIC_WITH_FORM",
|
|
79
|
-
[["EV_WRITE_DONE", 0], ["EV_WRITE_REFUSED", 0]],
|
|
86
|
+
[["EV_WRITE_DONE", 0], ["EV_WRITE_REFUSED", 0], ["EV_LOAD_NODES", 0]],
|
|
80
87
|
[["ST_IDLE", [
|
|
81
88
|
["EV_WRITE_DONE", ac_form_answer, null],
|
|
82
|
-
["EV_WRITE_REFUSED", ac_form_answer, null]
|
|
89
|
+
["EV_WRITE_REFUSED", ac_form_answer, null],
|
|
90
|
+
["EV_LOAD_NODES", ac_form_load, null]
|
|
83
91
|
]]],
|
|
84
92
|
{},
|
|
85
93
|
0,
|
|
@@ -115,6 +123,7 @@ beforeEach(() => {
|
|
|
115
123
|
logged.length = 0;
|
|
116
124
|
answers.length = 0;
|
|
117
125
|
commands.length = 0;
|
|
126
|
+
loaded.length = 0;
|
|
118
127
|
});
|
|
119
128
|
|
|
120
129
|
function build(name)
|
|
@@ -136,7 +145,9 @@ function build(name)
|
|
|
136
145
|
|
|
137
146
|
const forms = {};
|
|
138
147
|
for(const topic of ["users", "roles"]) {
|
|
139
|
-
forms
|
|
148
|
+
/* Named as the view names its forms: the answer of a `nodes`
|
|
149
|
+
* finds its table by that name. */
|
|
150
|
+
forms[topic] = gobj_create(`${name}_topics?${topic}`, "C_YUI_TREEDB_TOPIC_WITH_FORM",
|
|
140
151
|
{topic_name: topic}, topics);
|
|
141
152
|
forms[topic].priv_topic = topic;
|
|
142
153
|
}
|
|
@@ -277,13 +288,12 @@ describe("a write cut by the drop does not reload out of session", () => {
|
|
|
277
288
|
gobj_send_event(topics, "EV_TRANSPORT_STATE", {connected: false}, topics);
|
|
278
289
|
expect(nodes_asked()).toEqual([]);
|
|
279
290
|
|
|
280
|
-
/* The reconnect
|
|
281
|
-
*
|
|
291
|
+
/* The reconnect reads every open table -- once, though two edges
|
|
292
|
+
* report it. */
|
|
282
293
|
gobj_change_state(remote, "ST_SESSION");
|
|
283
294
|
gobj_send_event(topics, "EV_TRANSPORT_STATE", {connected: true}, topics);
|
|
284
|
-
yui_shell_set_connection_state(shell, false);
|
|
285
295
|
yui_shell_set_connection_state(shell, true);
|
|
286
|
-
expect(nodes_asked()).toEqual(["users"]);
|
|
296
|
+
expect(nodes_asked().sort()).toEqual(["roles", "users"]);
|
|
287
297
|
expect(errors()).toEqual([]);
|
|
288
298
|
});
|
|
289
299
|
|
|
@@ -303,7 +313,7 @@ describe("a write cut by the drop does not reload out of session", () => {
|
|
|
303
313
|
|
|
304
314
|
gobj_change_state(remote, "ST_SESSION");
|
|
305
315
|
yui_shell_set_connection_state(shell, true);
|
|
306
|
-
expect(nodes_asked()).toEqual(["users"]);
|
|
316
|
+
expect(nodes_asked().sort()).toEqual(["roles", "users"]);
|
|
307
317
|
expect(errors()).toEqual([]);
|
|
308
318
|
});
|
|
309
319
|
|
|
@@ -322,20 +332,78 @@ describe("a write cut by the drop does not reload out of session", () => {
|
|
|
322
332
|
|
|
323
333
|
gobj_change_state(remote, "ST_SESSION");
|
|
324
334
|
gobj_send_event(topics, "EV_TRANSPORT_STATE", {connected: true}, topics);
|
|
325
|
-
expect(nodes_asked()).toEqual(["roles"]);
|
|
335
|
+
expect(nodes_asked().sort()).toEqual(["roles", "users"]);
|
|
326
336
|
expect(errors().filter((m) => m.includes("not in session"))).toEqual([]);
|
|
327
337
|
});
|
|
328
338
|
|
|
329
|
-
test("a write refused IN session reloads its topic at once
|
|
339
|
+
test("a write refused IN session reloads its topic at once", () => {
|
|
330
340
|
const {shell, topics} = build("t9");
|
|
331
341
|
yui_shell_set_connection_state(shell, true);
|
|
332
342
|
gobj_send_event(topics, "EV_UPDATE_FIELD",
|
|
333
343
|
{topic_name: "users", id: "x", field: "name", value: "typed"}, topics);
|
|
334
344
|
gobj_send_event(topics, "EV_MT_COMMAND_ANSWER", failed_write("users", 0), remote);
|
|
335
345
|
expect(nodes_asked()).toEqual(["users"]);
|
|
346
|
+
});
|
|
347
|
+
});
|
|
336
348
|
|
|
349
|
+
/*
|
|
350
|
+
* The answer of a `nodes`, the way C_IEVENT_CLI delivers it.
|
|
351
|
+
*/
|
|
352
|
+
function nodes_answer_of(topic_name, rows)
|
|
353
|
+
{
|
|
354
|
+
return {result: 0, comment: "", data: rows, __md_iev__: {
|
|
355
|
+
command_stack: [{command: "nodes", kw: {topic_name: topic_name}}]
|
|
356
|
+
}};
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
describe("what the drop hid is read again on the reconnect", () => {
|
|
360
|
+
|
|
361
|
+
test("a node created during the drop is in its table after the reconnect", () => {
|
|
362
|
+
const {shell, topics} = build("t10");
|
|
363
|
+
yui_shell_set_connection_state(shell, true);
|
|
364
|
+
|
|
365
|
+
/* No write in flight: the session just drops. While it is down,
|
|
366
|
+
* another writer creates a user; its EV_TREEDB_NODE_CREATED is
|
|
367
|
+
* published to nobody. */
|
|
368
|
+
gobj_change_state(remote, "ST_DISCONNECTED");
|
|
337
369
|
gobj_send_event(topics, "EV_TRANSPORT_STATE", {connected: false}, topics);
|
|
370
|
+
yui_shell_set_connection_state(shell, false);
|
|
371
|
+
expect(nodes_asked()).toEqual([]);
|
|
372
|
+
|
|
373
|
+
gobj_change_state(remote, "ST_SESSION");
|
|
338
374
|
gobj_send_event(topics, "EV_TRANSPORT_STATE", {connected: true}, topics);
|
|
339
|
-
|
|
375
|
+
yui_shell_set_connection_state(shell, true);
|
|
376
|
+
|
|
377
|
+
/* Every open table is read once, though two edges said "up". */
|
|
378
|
+
expect(nodes_asked().sort()).toEqual(["roles", "users"]);
|
|
379
|
+
|
|
380
|
+
gobj_send_event(topics, "EV_MT_COMMAND_ANSWER",
|
|
381
|
+
nodes_answer_of("users", [{id: "x"}, {id: "created_during_the_drop"}]), remote);
|
|
382
|
+
expect(loaded).toEqual([
|
|
383
|
+
{topic: "users", rows: [{id: "x"}, {id: "created_during_the_drop"}]}
|
|
384
|
+
]);
|
|
385
|
+
expect(errors()).toEqual([]);
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
test("an 'up' with no drop before it reads nothing", () => {
|
|
389
|
+
const {shell, topics} = build("t11");
|
|
390
|
+
yui_shell_set_connection_state(shell, true);
|
|
391
|
+
gobj_send_event(topics, "EV_TRANSPORT_STATE", {connected: true}, topics);
|
|
392
|
+
expect(nodes_asked()).toEqual([]);
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
test("an edge that says 'up' before the transport is in session waits", () => {
|
|
396
|
+
const {shell, topics} = build("t12");
|
|
397
|
+
yui_shell_set_connection_state(shell, true);
|
|
398
|
+
gobj_change_state(remote, "ST_DISCONNECTED");
|
|
399
|
+
yui_shell_set_connection_state(shell, false);
|
|
400
|
+
|
|
401
|
+
yui_shell_set_connection_state(shell, true);
|
|
402
|
+
expect(nodes_asked()).toEqual([]);
|
|
403
|
+
expect(errors().filter((m) => m.includes("not in session"))).toEqual([]);
|
|
404
|
+
|
|
405
|
+
gobj_change_state(remote, "ST_SESSION");
|
|
406
|
+
gobj_send_event(topics, "EV_TRANSPORT_STATE", {connected: true}, topics);
|
|
407
|
+
expect(nodes_asked().sort()).toEqual(["roles", "users"]);
|
|
340
408
|
});
|
|
341
409
|
});
|
|
@@ -115,7 +115,7 @@ describe("is_hook_size", () => {
|
|
|
115
115
|
* The children of a hook as the NODE EVENTS deliver them: `{id,
|
|
116
116
|
* topic_name}`, with no hook_name. Not taken for a reference, their
|
|
117
117
|
* topic_name -- the same word on every row -- was a wildcard for every
|
|
118
|
-
* row that had received an UPDATED
|
|
118
|
+
* row that had received an UPDATED.
|
|
119
119
|
*/
|
|
120
120
|
describe("a hook's children as the node events deliver them", () => {
|
|
121
121
|
const row = {id: "w1", devices: [{id: "d7", topic_name: "devices"}]};
|
|
@@ -59,7 +59,7 @@ describe("reading and dropping the selection", () => {
|
|
|
59
59
|
* A table as the delete of the treedb topic table meets it AFTER a
|
|
60
60
|
* confirmation: rows came and went while the dialog was open. A position
|
|
61
61
|
* names whatever row sits there now; an id names the row the question named
|
|
62
|
-
* (the regression of d60ec78
|
|
62
|
+
* (the regression of d60ec78).
|
|
63
63
|
*/
|
|
64
64
|
function fake_table(rows, index)
|
|
65
65
|
{
|