@yuneta/gobj-ui 7.23.185 → 7.23.187
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/dist/gobj-ui.cjs.js +201 -43
- package/dist/gobj-ui.es.js +202 -44
- package/package.json +1 -1
- package/src/c_g6_nodes_tree.js +105 -39
- package/src/c_yui_schema_editor.js +3 -1
- package/src/c_yui_treedb_topics.js +81 -11
- package/src/graph_save_plan.js +108 -0
- package/src/graph_save_plan.test.js +146 -0
- package/src/yui_icons.css +9 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/***********************************************************************
|
|
2
|
+
* graph_save_plan.test.js
|
|
3
|
+
*
|
|
4
|
+
* A Save of the graph writes the topics that CHANGED.
|
|
5
|
+
*
|
|
6
|
+
* Measured before this existed, on a live agent treedb: one node
|
|
7
|
+
* of `public_services` dragged, Save pressed, and the store took
|
|
8
|
+
* five `__graphs__` records -- one per topic the view had loaded
|
|
9
|
+
* -- of which four were identical, byte for byte, to the records
|
|
10
|
+
* under them. An append-only store keeps them for ever.
|
|
11
|
+
*
|
|
12
|
+
* The cases below are the ones that decide whether a topic is
|
|
13
|
+
* written, and two of them are the reason this is a module of its
|
|
14
|
+
* own rather than three lines inside the Save.
|
|
15
|
+
*
|
|
16
|
+
* Copyright (c) 2026, ArtGins.
|
|
17
|
+
* All Rights Reserved.
|
|
18
|
+
***********************************************************************/
|
|
19
|
+
import {describe, test, expect} from "vitest";
|
|
20
|
+
import {
|
|
21
|
+
plan_graph_saves, topic_arrangement_changed, arrangement_of
|
|
22
|
+
} from "./graph_save_plan.js";
|
|
23
|
+
|
|
24
|
+
const ORIGIN = "f3163a9f-1f37-412a-b8c9-87a4341f14de";
|
|
25
|
+
|
|
26
|
+
function layout(nodes, extra)
|
|
27
|
+
{
|
|
28
|
+
return Object.assign({nodes: nodes, __origin__: ORIGIN}, extra || {});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* The shape of the real case: five topics, one card moved. */
|
|
32
|
+
function five_topics()
|
|
33
|
+
{
|
|
34
|
+
return {
|
|
35
|
+
realms: layout({"artgins.utilities.all": {x: 398, y: 605}}),
|
|
36
|
+
yunos: layout({"1": {x: 130, y: 815}, "2": {x: 398, y: 815}}),
|
|
37
|
+
binaries: layout({emailsender: {x: 197, y: 985}}),
|
|
38
|
+
configurations: layout({"emailsender.artgins": {x: 63, y: 985}}),
|
|
39
|
+
public_services: layout({"1": {x: 993.7299656271935, y: 1119.9412968754768}}),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
describe("plan_graph_saves", () => {
|
|
44
|
+
test("nothing moved, nothing is written", () => {
|
|
45
|
+
const live = five_topics();
|
|
46
|
+
const saved = five_topics();
|
|
47
|
+
expect(plan_graph_saves(live, saved)).toEqual([]);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test("one card moved writes ONE topic, not five", () => {
|
|
51
|
+
const live = five_topics();
|
|
52
|
+
const saved = five_topics();
|
|
53
|
+
live.public_services.nodes["1"].x = 811.7299656271935;
|
|
54
|
+
live.public_services.nodes["1"].y = 1167.9412968754768;
|
|
55
|
+
expect(plan_graph_saves(live, saved)).toEqual(["public_services"]);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test("a topic the backend has never seen is written", () => {
|
|
59
|
+
const live = five_topics();
|
|
60
|
+
const saved = five_topics();
|
|
61
|
+
delete saved.binaries;
|
|
62
|
+
expect(plan_graph_saves(live, saved)).toEqual(["binaries"]);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("...unless it holds nothing: an empty arrangement is not a layout", () => {
|
|
66
|
+
const live = five_topics();
|
|
67
|
+
const saved = five_topics();
|
|
68
|
+
delete saved.binaries;
|
|
69
|
+
live.binaries = {};
|
|
70
|
+
expect(plan_graph_saves(live, saved)).toEqual([]);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("no saved side at all is the first Save: every topic with content", () => {
|
|
74
|
+
expect(plan_graph_saves(five_topics(), {})).toEqual(
|
|
75
|
+
["realms", "yunos", "binaries", "configurations", "public_services"]
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("a different __origin__ is not a change", () => {
|
|
80
|
+
const live = five_topics();
|
|
81
|
+
const saved = five_topics();
|
|
82
|
+
live.yunos.__origin__ = "another-browser-entirely";
|
|
83
|
+
expect(plan_graph_saves(live, saved)).toEqual([]);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("the order the keys were built in is not a change", () => {
|
|
87
|
+
const saved = {yunos: {nodes: {a: {x: 1, y: 2}}, __origin__: ORIGIN}};
|
|
88
|
+
const live = {yunos: {__origin__: ORIGIN, nodes: {a: {y: 2, x: 1}}}};
|
|
89
|
+
expect(plan_graph_saves(live, saved)).toEqual([]);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test("a node that lost its entry is a change", () => {
|
|
93
|
+
const live = five_topics();
|
|
94
|
+
const saved = five_topics();
|
|
95
|
+
delete live.yunos.nodes["2"];
|
|
96
|
+
expect(plan_graph_saves(live, saved)).toEqual(["yunos"]);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test("what is not a position counts too: defaults and edges", () => {
|
|
100
|
+
const live = five_topics();
|
|
101
|
+
const saved = five_topics();
|
|
102
|
+
live.realms.defaults = {fill: "#123456"};
|
|
103
|
+
live.binaries.edges = {"binaries^a|yunos": {lineWidth: 3}};
|
|
104
|
+
expect(plan_graph_saves(live, saved)).toEqual(["realms", "binaries"]);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test("a size added to a card is a change", () => {
|
|
108
|
+
const live = five_topics();
|
|
109
|
+
const saved = five_topics();
|
|
110
|
+
live.binaries.nodes.emailsender.size = [260, 120];
|
|
111
|
+
expect(plan_graph_saves(live, saved)).toEqual(["binaries"]);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test("it answers a plan, never undefined", () => {
|
|
115
|
+
expect(plan_graph_saves(null, null)).toEqual([]);
|
|
116
|
+
expect(plan_graph_saves(undefined, five_topics())).toEqual([]);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
describe("topic_arrangement_changed", () => {
|
|
121
|
+
test("no saved record and content: TRUE", () => {
|
|
122
|
+
expect(topic_arrangement_changed(layout({a: {x: 1, y: 1}}), undefined)).toBe(true);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test("no saved record and nothing to say: FALSE", () => {
|
|
126
|
+
expect(topic_arrangement_changed({}, undefined)).toBe(false);
|
|
127
|
+
expect(topic_arrangement_changed({__origin__: ORIGIN}, undefined)).toBe(false);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test("the same arrangement: FALSE", () => {
|
|
131
|
+
const props = layout({a: {x: 1, y: 1}});
|
|
132
|
+
expect(topic_arrangement_changed(props, props)).toBe(false);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
describe("arrangement_of", () => {
|
|
137
|
+
test("drops who wrote it and keeps the rest", () => {
|
|
138
|
+
expect(arrangement_of(layout({a: {x: 1, y: 1}}, {defaults: {fill: "#fff"}})))
|
|
139
|
+
.toEqual({nodes: {a: {x: 1, y: 1}}, defaults: {fill: "#fff"}});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test("anything that is not an object holds no arrangement", () => {
|
|
143
|
+
expect(arrangement_of(null)).toEqual({});
|
|
144
|
+
expect(arrangement_of("nodes")).toEqual({});
|
|
145
|
+
});
|
|
146
|
+
});
|
package/src/yui_icons.css
CHANGED
|
@@ -176,6 +176,15 @@
|
|
|
176
176
|
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 576 512'%3E%3Cpath d='M41-24.9c-9.4-9.4-24.6-9.4-33.9 0S-2.3-.3 7 9.1l528 528c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-96.4-96.4c2.7-2.4 5.4-4.8 8-7.2 46.8-43.5 78.1-95.4 93-131.1 3.3-7.9 3.3-16.7 0-24.6-14.9-35.7-46.2-87.7-93-131.1-47.1-43.7-111.8-80.6-192.6-80.6-56.8 0-105.6 18.2-146 44.2L41-24.9zM204.5 138.7c23.5-16.8 52.4-26.7 83.5-26.7 79.5 0 144 64.5 144 144 0 31.1-9.9 59.9-26.7 83.5l-34.7-34.7c12.7-21.4 17-47.7 10.1-73.7-13.7-51.2-66.4-81.6-117.6-67.9-8.6 2.3-16.7 5.7-24 10l-34.7-34.7zM325.3 395.1c-11.9 3.2-24.4 4.9-37.3 4.9-79.5 0-144-64.5-144-144 0-12.9 1.7-25.4 4.9-37.3L69.4 139.2c-32.6 36.8-55 75.8-66.9 104.5-3.3 7.9-3.3 16.7 0 24.6 14.9 35.7 46.2 87.7 93 131.1 47.1 43.7 111.8 80.6 192.6 80.6 37.3 0 71.2-7.9 101.5-20.6l-64.2-64.2z'/%3E%3C/svg%3E");
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
+
/* The SCHEMA of a treedb -- its plan, as against the `hexagon-nodes`
|
|
180
|
+
* of the DATA graph. The two sat on the same glyph in the same
|
|
181
|
+
* toolbar, one button apart, and nothing but the label told them
|
|
182
|
+
* apart. */
|
|
183
|
+
.yi-compass-drafting::before {
|
|
184
|
+
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M99.3 256.1l69.4-119.9c-5.6-12.2-8.8-25.8-8.8-40.2 0-53 43-96 96-96s96 43 96 96c0 14.3-3.1 27.9-8.8 40.2l44.4 76.7c-23.1 26-53.7 45.1-88.4 53.8L256 191.9 187.9 309.5c21.5 6.8 44.3 10.5 68.1 10.5 70.7 0 133.8-32.7 174.9-84 11.1-13.8 31.2-16 45-5s16 31.2 5 45c-52.7 65.8-133.9 108-224.8 108-35.4 0-69.4-6.4-100.7-18.1L98.7 463.7C94 471.8 87 478.4 78.6 482.6L23.2 510.3c-5 2.5-10.9 2.2-15.6-.7S0 501.5 0 496l0-55.4c0-8.4 2.2-16.7 6.5-24.1l60-103.7c-12.8-11.2-24.6-23.5-35.3-36.8-11.1-13.8-8.8-33.9 5-45s33.9-8.8 45 5c5.7 7.1 11.8 13.8 18.2 20.1zM381.1 407.9c32.5-13 62.4-31 88.9-52.9l35.6 61.5c4.2 7.3 6.5 15.6 6.5 24.1l0 55.4c0 5.5-2.9 10.7-7.6 13.6s-10.6 3.2-15.6 .7l-55.4-27.7c-8.4-4.2-15.4-10.8-20.1-18.9l-32.3-55.8zM256 128a32 32 0 1 0 0-64 32 32 0 1 0 0 64z'/%3E%3C/svg%3E");
|
|
185
|
+
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M99.3 256.1l69.4-119.9c-5.6-12.2-8.8-25.8-8.8-40.2 0-53 43-96 96-96s96 43 96 96c0 14.3-3.1 27.9-8.8 40.2l44.4 76.7c-23.1 26-53.7 45.1-88.4 53.8L256 191.9 187.9 309.5c21.5 6.8 44.3 10.5 68.1 10.5 70.7 0 133.8-32.7 174.9-84 11.1-13.8 31.2-16 45-5s16 31.2 5 45c-52.7 65.8-133.9 108-224.8 108-35.4 0-69.4-6.4-100.7-18.1L98.7 463.7C94 471.8 87 478.4 78.6 482.6L23.2 510.3c-5 2.5-10.9 2.2-15.6-.7S0 501.5 0 496l0-55.4c0-8.4 2.2-16.7 6.5-24.1l60-103.7c-12.8-11.2-24.6-23.5-35.3-36.8-11.1-13.8-8.8-33.9 5-45s33.9-8.8 45 5c5.7 7.1 11.8 13.8 18.2 20.1zM381.1 407.9c32.5-13 62.4-31 88.9-52.9l35.6 61.5c4.2 7.3 6.5 15.6 6.5 24.1l0 55.4c0 5.5-2.9 10.7-7.6 13.6s-10.6 3.2-15.6 .7l-55.4-27.7c-8.4-4.2-15.4-10.8-20.1-18.9l-32.3-55.8zM256 128a32 32 0 1 0 0-64 32 32 0 1 0 0 64z'/%3E%3C/svg%3E");
|
|
186
|
+
}
|
|
187
|
+
|
|
179
188
|
.yi-hexagon-nodes::before {
|
|
180
189
|
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E%3Cpath d='M248 106.6c18.9-9 32-28.3 32-50.6c0-30.9-25.1-56-56-56s-56 25.1-56 56c0 22.3 13.1 41.6 32 50.6l0 98.8c-2.8 1.3-5.5 2.9-8 4.7l-80.1-45.8c1.6-20.8-8.6-41.6-27.9-52.8C57.2 96 23 105.2 7.5 132S1.2 193 28 208.5c1.3 .8 2.6 1.5 4 2.1l0 90.8c-1.3 .6-2.7 1.3-4 2.1C1.2 319-8 353.2 7.5 380S57.2 416 84 400.5c19.3-11.1 29.4-32 27.8-52.8l50.5-28.9c-11.5-11.2-19.9-25.6-23.8-41.7L88 306.1c-2.6-1.8-5.2-3.3-8-4.7l0-90.8c2.8-1.3 5.5-2.9 8-4.7l80.1 45.8c-.1 1.4-.2 2.8-.2 4.3c0 22.3 13.1 41.6 32 50.6l0 98.8c-18.9 9-32 28.3-32 50.6c0 30.9 25.1 56 56 56s56-25.1 56-56c0-22.3-13.1-41.6-32-50.6l0-98.8c2.8-1.3 5.5-2.9 8-4.7l80.1 45.8c-1.6 20.8 8.6 41.6 27.8 52.8c26.8 15.5 61 6.3 76.5-20.5s6.3-61-20.5-76.5c-1.3-.8-2.7-1.5-4-2.1l0-90.8c1.4-.6 2.7-1.3 4-2.1c26.8-15.5 36-49.7 20.5-76.5S390.8 96 364 111.5c-19.3 11.1-29.4 32-27.8 52.8l-50.6 28.9c11.5 11.2 19.9 25.6 23.8 41.7L360 205.9c2.6 1.8 5.2 3.3 8 4.7l0 90.8c-2.8 1.3-5.5 2.9-8 4.6l-80.1-45.8c.1-1.4 .2-2.8 .2-4.3c0-22.3-13.1-41.6-32-50.6l0-98.8z'/%3E%3C/svg%3E");
|
|
181
190
|
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E%3Cpath d='M248 106.6c18.9-9 32-28.3 32-50.6c0-30.9-25.1-56-56-56s-56 25.1-56 56c0 22.3 13.1 41.6 32 50.6l0 98.8c-2.8 1.3-5.5 2.9-8 4.7l-80.1-45.8c1.6-20.8-8.6-41.6-27.9-52.8C57.2 96 23 105.2 7.5 132S1.2 193 28 208.5c1.3 .8 2.6 1.5 4 2.1l0 90.8c-1.3 .6-2.7 1.3-4 2.1C1.2 319-8 353.2 7.5 380S57.2 416 84 400.5c19.3-11.1 29.4-32 27.8-52.8l50.5-28.9c-11.5-11.2-19.9-25.6-23.8-41.7L88 306.1c-2.6-1.8-5.2-3.3-8-4.7l0-90.8c2.8-1.3 5.5-2.9 8-4.7l80.1 45.8c-.1 1.4-.2 2.8-.2 4.3c0 22.3 13.1 41.6 32 50.6l0 98.8c-18.9 9-32 28.3-32 50.6c0 30.9 25.1 56 56 56s56-25.1 56-56c0-22.3-13.1-41.6-32-50.6l0-98.8c2.8-1.3 5.5-2.9 8-4.7l80.1 45.8c-1.6 20.8 8.6 41.6 27.8 52.8c26.8 15.5 61 6.3 76.5-20.5s6.3-61-20.5-76.5c-1.3-.8-2.7-1.5-4-2.1l0-90.8c1.4-.6 2.7-1.3 4-2.1c26.8-15.5 36-49.7 20.5-76.5S390.8 96 364 111.5c-19.3 11.1-29.4 32-27.8 52.8l-50.6 28.9c11.5 11.2 19.9 25.6 23.8 41.7L360 205.9c2.6 1.8 5.2 3.3 8 4.7l0 90.8c-2.8 1.3-5.5 2.9-8 4.6l-80.1-45.8c.1-1.4 .2-2.8 .2-4.3c0-22.3-13.1-41.6-32-50.6l0-98.8z'/%3E%3C/svg%3E");
|