retold-data-service 2.0.32 → 2.0.34
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/docs/_cover.md +1 -1
- package/docs/_version.json +7 -0
- package/docs/css/docuserve.css +277 -23
- package/docs/endpoints.md +2 -2
- package/docs/index.html +2 -2
- package/docs/initialization.md +6 -6
- package/docs/retold-catalog.json +18 -18
- package/docs/retold-keyword-index.json +1 -1
- package/docs/schema-definition.md +6 -6
- package/package.json +4 -3
- package/source/services/data-cloner/DataCloner-Command-Headless.js +3 -1
- package/source/services/data-cloner/DataCloner-Command-Sync.js +30 -0
- package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Sync.js +68 -5
- package/source/services/data-cloner/web/data-cloner.js +91 -11
- package/source/services/data-cloner/web/data-cloner.js.map +1 -1
- package/source/services/data-cloner/web/data-cloner.min.js +1 -1
- package/source/services/data-cloner/web/data-cloner.min.js.map +1 -1
package/docs/_cover.md
CHANGED
package/docs/css/docuserve.css
CHANGED
|
@@ -1,73 +1,327 @@
|
|
|
1
1
|
/* ============================================================================
|
|
2
|
-
Pict Docuserve - Base Styles
|
|
2
|
+
Pict Docuserve - Base Styles & Theme Variables
|
|
3
3
|
============================================================================ */
|
|
4
4
|
|
|
5
|
-
/*
|
|
6
|
-
|
|
5
|
+
/* ----------------------------------------------------------------------------
|
|
6
|
+
Theme variables — light defaults on :root.
|
|
7
|
+
Dark mode applies when either:
|
|
8
|
+
(a) the user explicitly selected dark via <html data-theme="dark">
|
|
9
|
+
(b) the user hasn't chosen anything AND the system prefers dark
|
|
10
|
+
An explicit <html data-theme="light"> pins the light palette regardless.
|
|
11
|
+
---------------------------------------------------------------------------- */
|
|
12
|
+
|
|
13
|
+
:root
|
|
14
|
+
{
|
|
15
|
+
/* Surfaces */
|
|
16
|
+
--docuserve-bg: #FDFBF7;
|
|
17
|
+
--docuserve-bg-elevated: #FFFFFF;
|
|
18
|
+
--docuserve-border: #DDD6CA;
|
|
19
|
+
--docuserve-border-soft: #EAE3D8;
|
|
20
|
+
|
|
21
|
+
/* Text */
|
|
22
|
+
--docuserve-text: #2A241E;
|
|
23
|
+
--docuserve-text-strong: #3D3229;
|
|
24
|
+
--docuserve-text-muted: #5E5549;
|
|
25
|
+
--docuserve-text-dim: #8A7F72;
|
|
26
|
+
|
|
27
|
+
/* Accent / links */
|
|
28
|
+
--docuserve-accent: #2E7D74;
|
|
29
|
+
--docuserve-accent-hover: #236660;
|
|
30
|
+
|
|
31
|
+
/* Top bar */
|
|
32
|
+
--docuserve-topbar-bg: #3D3229;
|
|
33
|
+
--docuserve-topbar-text: #E8E0D4;
|
|
34
|
+
--docuserve-topbar-text-muted: #B5AA9A;
|
|
35
|
+
--docuserve-topbar-text-dim: #8A7F72;
|
|
36
|
+
--docuserve-topbar-hover-bg: #524438;
|
|
37
|
+
--docuserve-topbar-version-bg: rgba(255, 255, 255, 0.06);
|
|
38
|
+
--docuserve-topbar-version-border: rgba(255, 255, 255, 0.08);
|
|
39
|
+
--docuserve-topbar-version-text: #B5AA9A;
|
|
40
|
+
|
|
41
|
+
/* Sidebar */
|
|
42
|
+
--docuserve-sidebar-bg: #FAF7F1;
|
|
43
|
+
--docuserve-sidebar-border: #DDD6CA;
|
|
44
|
+
--docuserve-sidebar-border-soft: #E5DED1;
|
|
45
|
+
--docuserve-sidebar-text: #423D37;
|
|
46
|
+
--docuserve-sidebar-group-title: #3D3229;
|
|
47
|
+
--docuserve-sidebar-module-text: #5E5549;
|
|
48
|
+
--docuserve-sidebar-hover-bg: #EAE3D8;
|
|
49
|
+
--docuserve-sidebar-hover-text: #2E7D74;
|
|
50
|
+
--docuserve-sidebar-active-bg: #E5DED1;
|
|
51
|
+
--docuserve-sidebar-active-text: #2E7D74;
|
|
52
|
+
--docuserve-sidebar-search-bg: #FFFFFF;
|
|
53
|
+
--docuserve-sidebar-search-border: #DDD6CA;
|
|
54
|
+
|
|
55
|
+
/* Inline code */
|
|
56
|
+
--docuserve-inline-code-bg: #F0ECE4;
|
|
57
|
+
--docuserve-inline-code-text: #9E3A50;
|
|
58
|
+
|
|
59
|
+
/* Code block panel */
|
|
60
|
+
--docuserve-code-bg: #F6F3EE;
|
|
61
|
+
--docuserve-code-border: #E5DED1;
|
|
62
|
+
--docuserve-code-gutter-bg: #EFEAE0;
|
|
63
|
+
--docuserve-code-gutter-border: #DDD6CA;
|
|
64
|
+
--docuserve-code-gutter-text: #A59986;
|
|
65
|
+
--docuserve-code-text: #2A241E;
|
|
66
|
+
|
|
67
|
+
/* Syntax tokens — low-chroma dark-on-light palette */
|
|
68
|
+
--docuserve-tok-keyword: #A03472;
|
|
69
|
+
--docuserve-tok-string: #1A6640;
|
|
70
|
+
--docuserve-tok-number: #B25A00;
|
|
71
|
+
--docuserve-tok-comment: #8A7F72;
|
|
72
|
+
--docuserve-tok-operator: #2E7D74;
|
|
73
|
+
--docuserve-tok-punctuation: #2A241E;
|
|
74
|
+
--docuserve-tok-function: #2A5DB0;
|
|
75
|
+
--docuserve-tok-property: #9E3A50;
|
|
76
|
+
--docuserve-tok-tag: #9E3A50;
|
|
77
|
+
--docuserve-tok-attr-name: #B25A00;
|
|
78
|
+
--docuserve-tok-attr-value: #1A6640;
|
|
79
|
+
|
|
80
|
+
/* Tables, blockquotes, mermaid */
|
|
81
|
+
--docuserve-table-header-bg: #F5F0E8;
|
|
82
|
+
--docuserve-table-row-alt-bg: #F9F6F0;
|
|
83
|
+
--docuserve-blockquote-bg: #F7F5F0;
|
|
84
|
+
--docuserve-blockquote-border: #2E7D74;
|
|
85
|
+
--docuserve-blockquote-text: #5E5549;
|
|
86
|
+
--docuserve-mermaid-bg: #FFFFFF;
|
|
87
|
+
|
|
88
|
+
/* Scrollbars */
|
|
89
|
+
--docuserve-scrollbar-track: #F5F0E8;
|
|
90
|
+
--docuserve-scrollbar-thumb: #D4CCBE;
|
|
91
|
+
--docuserve-scrollbar-thumb-hover: #B5AA9A;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@media (prefers-color-scheme: dark)
|
|
95
|
+
{
|
|
96
|
+
:root:not([data-theme="light"])
|
|
97
|
+
{
|
|
98
|
+
--docuserve-bg: #15120F;
|
|
99
|
+
--docuserve-bg-elevated: #1B1814;
|
|
100
|
+
--docuserve-border: #2F2823;
|
|
101
|
+
--docuserve-border-soft: #26211C;
|
|
102
|
+
|
|
103
|
+
--docuserve-text: #E8E0D4;
|
|
104
|
+
--docuserve-text-strong: #F2ECE0;
|
|
105
|
+
--docuserve-text-muted: #B5AA9A;
|
|
106
|
+
--docuserve-text-dim: #7A6F62;
|
|
107
|
+
|
|
108
|
+
--docuserve-accent: #5DB8A8;
|
|
109
|
+
--docuserve-accent-hover: #7FCCB8;
|
|
110
|
+
|
|
111
|
+
--docuserve-topbar-bg: #1A1612;
|
|
112
|
+
--docuserve-topbar-text: #E8E0D4;
|
|
113
|
+
--docuserve-topbar-text-muted: #B5AA9A;
|
|
114
|
+
--docuserve-topbar-text-dim: #7A6F62;
|
|
115
|
+
--docuserve-topbar-hover-bg: #2A241E;
|
|
116
|
+
--docuserve-topbar-version-bg: rgba(255, 255, 255, 0.05);
|
|
117
|
+
--docuserve-topbar-version-border: rgba(255, 255, 255, 0.09);
|
|
118
|
+
--docuserve-topbar-version-text: #B5AA9A;
|
|
119
|
+
|
|
120
|
+
--docuserve-sidebar-bg: #1B1814;
|
|
121
|
+
--docuserve-sidebar-border: #2F2823;
|
|
122
|
+
--docuserve-sidebar-border-soft: #26211C;
|
|
123
|
+
--docuserve-sidebar-text: #C9C0B3;
|
|
124
|
+
--docuserve-sidebar-group-title: #F2ECE0;
|
|
125
|
+
--docuserve-sidebar-module-text: #B5AA9A;
|
|
126
|
+
--docuserve-sidebar-hover-bg: #2A241E;
|
|
127
|
+
--docuserve-sidebar-hover-text: #7FCCB8;
|
|
128
|
+
--docuserve-sidebar-active-bg: #2F2823;
|
|
129
|
+
--docuserve-sidebar-active-text: #7FCCB8;
|
|
130
|
+
--docuserve-sidebar-search-bg: #26211C;
|
|
131
|
+
--docuserve-sidebar-search-border: #2F2823;
|
|
132
|
+
|
|
133
|
+
--docuserve-inline-code-bg: #2A241E;
|
|
134
|
+
--docuserve-inline-code-text: #E8B07A;
|
|
135
|
+
|
|
136
|
+
--docuserve-code-bg: #1E1A17;
|
|
137
|
+
--docuserve-code-border: #2F2823;
|
|
138
|
+
--docuserve-code-gutter-bg: #17130F;
|
|
139
|
+
--docuserve-code-gutter-border: #2F2823;
|
|
140
|
+
--docuserve-code-gutter-text: #6A6052;
|
|
141
|
+
--docuserve-code-text: #E8E0D4;
|
|
142
|
+
|
|
143
|
+
--docuserve-tok-keyword: #C678DD;
|
|
144
|
+
--docuserve-tok-string: #98C379;
|
|
145
|
+
--docuserve-tok-number: #D19A66;
|
|
146
|
+
--docuserve-tok-comment: #7F848E;
|
|
147
|
+
--docuserve-tok-operator: #56B6C2;
|
|
148
|
+
--docuserve-tok-punctuation: #E8E0D4;
|
|
149
|
+
--docuserve-tok-function: #61AFEF;
|
|
150
|
+
--docuserve-tok-property: #E06C75;
|
|
151
|
+
--docuserve-tok-tag: #E06C75;
|
|
152
|
+
--docuserve-tok-attr-name: #D19A66;
|
|
153
|
+
--docuserve-tok-attr-value: #98C379;
|
|
154
|
+
|
|
155
|
+
--docuserve-table-header-bg: #26211C;
|
|
156
|
+
--docuserve-table-row-alt-bg: #1F1B17;
|
|
157
|
+
--docuserve-blockquote-bg: #1F1B17;
|
|
158
|
+
--docuserve-blockquote-border: #5DB8A8;
|
|
159
|
+
--docuserve-blockquote-text: #C9C0B3;
|
|
160
|
+
--docuserve-mermaid-bg: #E8E0D4;
|
|
161
|
+
|
|
162
|
+
--docuserve-scrollbar-track: #1B1814;
|
|
163
|
+
--docuserve-scrollbar-thumb: #3A322B;
|
|
164
|
+
--docuserve-scrollbar-thumb-hover: #524438;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
:root[data-theme="dark"]
|
|
169
|
+
{
|
|
170
|
+
--docuserve-bg: #15120F;
|
|
171
|
+
--docuserve-bg-elevated: #1B1814;
|
|
172
|
+
--docuserve-border: #2F2823;
|
|
173
|
+
--docuserve-border-soft: #26211C;
|
|
174
|
+
|
|
175
|
+
--docuserve-text: #E8E0D4;
|
|
176
|
+
--docuserve-text-strong: #F2ECE0;
|
|
177
|
+
--docuserve-text-muted: #B5AA9A;
|
|
178
|
+
--docuserve-text-dim: #7A6F62;
|
|
179
|
+
|
|
180
|
+
--docuserve-accent: #5DB8A8;
|
|
181
|
+
--docuserve-accent-hover: #7FCCB8;
|
|
182
|
+
|
|
183
|
+
--docuserve-topbar-bg: #1A1612;
|
|
184
|
+
--docuserve-topbar-text: #E8E0D4;
|
|
185
|
+
--docuserve-topbar-text-muted: #B5AA9A;
|
|
186
|
+
--docuserve-topbar-text-dim: #7A6F62;
|
|
187
|
+
--docuserve-topbar-hover-bg: #2A241E;
|
|
188
|
+
--docuserve-topbar-version-bg: rgba(255, 255, 255, 0.05);
|
|
189
|
+
--docuserve-topbar-version-border: rgba(255, 255, 255, 0.09);
|
|
190
|
+
--docuserve-topbar-version-text: #B5AA9A;
|
|
191
|
+
|
|
192
|
+
--docuserve-sidebar-bg: #1B1814;
|
|
193
|
+
--docuserve-sidebar-border: #2F2823;
|
|
194
|
+
--docuserve-sidebar-border-soft: #26211C;
|
|
195
|
+
--docuserve-sidebar-text: #C9C0B3;
|
|
196
|
+
--docuserve-sidebar-group-title: #F2ECE0;
|
|
197
|
+
--docuserve-sidebar-module-text: #B5AA9A;
|
|
198
|
+
--docuserve-sidebar-hover-bg: #2A241E;
|
|
199
|
+
--docuserve-sidebar-hover-text: #7FCCB8;
|
|
200
|
+
--docuserve-sidebar-active-bg: #2F2823;
|
|
201
|
+
--docuserve-sidebar-active-text: #7FCCB8;
|
|
202
|
+
--docuserve-sidebar-search-bg: #26211C;
|
|
203
|
+
--docuserve-sidebar-search-border: #2F2823;
|
|
204
|
+
|
|
205
|
+
--docuserve-inline-code-bg: #2A241E;
|
|
206
|
+
--docuserve-inline-code-text: #E8B07A;
|
|
207
|
+
|
|
208
|
+
--docuserve-code-bg: #1E1A17;
|
|
209
|
+
--docuserve-code-border: #2F2823;
|
|
210
|
+
--docuserve-code-gutter-bg: #17130F;
|
|
211
|
+
--docuserve-code-gutter-border: #2F2823;
|
|
212
|
+
--docuserve-code-gutter-text: #6A6052;
|
|
213
|
+
--docuserve-code-text: #E8E0D4;
|
|
214
|
+
|
|
215
|
+
--docuserve-tok-keyword: #C678DD;
|
|
216
|
+
--docuserve-tok-string: #98C379;
|
|
217
|
+
--docuserve-tok-number: #D19A66;
|
|
218
|
+
--docuserve-tok-comment: #7F848E;
|
|
219
|
+
--docuserve-tok-operator: #56B6C2;
|
|
220
|
+
--docuserve-tok-punctuation: #E8E0D4;
|
|
221
|
+
--docuserve-tok-function: #61AFEF;
|
|
222
|
+
--docuserve-tok-property: #E06C75;
|
|
223
|
+
--docuserve-tok-tag: #E06C75;
|
|
224
|
+
--docuserve-tok-attr-name: #D19A66;
|
|
225
|
+
--docuserve-tok-attr-value: #98C379;
|
|
226
|
+
|
|
227
|
+
--docuserve-table-header-bg: #26211C;
|
|
228
|
+
--docuserve-table-row-alt-bg: #1F1B17;
|
|
229
|
+
--docuserve-blockquote-bg: #1F1B17;
|
|
230
|
+
--docuserve-blockquote-border: #5DB8A8;
|
|
231
|
+
--docuserve-blockquote-text: #C9C0B3;
|
|
232
|
+
--docuserve-mermaid-bg: #E8E0D4;
|
|
233
|
+
|
|
234
|
+
--docuserve-scrollbar-track: #1B1814;
|
|
235
|
+
--docuserve-scrollbar-thumb: #3A322B;
|
|
236
|
+
--docuserve-scrollbar-thumb-hover: #524438;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/* ----------------------------------------------------------------------------
|
|
240
|
+
Reset and base
|
|
241
|
+
---------------------------------------------------------------------------- */
|
|
242
|
+
|
|
243
|
+
*, *::before, *::after
|
|
244
|
+
{
|
|
7
245
|
box-sizing: border-box;
|
|
8
246
|
}
|
|
9
247
|
|
|
10
|
-
html, body
|
|
248
|
+
html, body
|
|
249
|
+
{
|
|
11
250
|
margin: 0;
|
|
12
251
|
padding: 0;
|
|
13
252
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
14
253
|
font-size: 16px;
|
|
15
254
|
line-height: 1.5;
|
|
16
|
-
color:
|
|
17
|
-
background-color:
|
|
255
|
+
color: var(--docuserve-text);
|
|
256
|
+
background-color: var(--docuserve-bg);
|
|
18
257
|
-webkit-font-smoothing: antialiased;
|
|
19
258
|
-moz-osx-font-smoothing: grayscale;
|
|
259
|
+
transition: background-color 0.15s ease, color 0.15s ease;
|
|
20
260
|
}
|
|
21
261
|
|
|
22
262
|
/* Typography */
|
|
23
|
-
h1, h2, h3, h4, h5, h6
|
|
263
|
+
h1, h2, h3, h4, h5, h6
|
|
264
|
+
{
|
|
24
265
|
margin-top: 0;
|
|
25
266
|
line-height: 1.3;
|
|
267
|
+
color: var(--docuserve-text-strong);
|
|
26
268
|
}
|
|
27
269
|
|
|
28
|
-
a
|
|
29
|
-
|
|
270
|
+
a
|
|
271
|
+
{
|
|
272
|
+
color: var(--docuserve-accent);
|
|
30
273
|
text-decoration: none;
|
|
31
274
|
}
|
|
32
275
|
|
|
33
|
-
a:hover
|
|
34
|
-
|
|
276
|
+
a:hover
|
|
277
|
+
{
|
|
278
|
+
color: var(--docuserve-accent-hover);
|
|
35
279
|
}
|
|
36
280
|
|
|
37
281
|
/* Application container */
|
|
38
|
-
#Docuserve-Application-Container
|
|
282
|
+
#Docuserve-Application-Container
|
|
283
|
+
{
|
|
39
284
|
min-height: 100vh;
|
|
40
285
|
}
|
|
41
286
|
|
|
42
287
|
/* Utility: scrollbar styling */
|
|
43
|
-
::-webkit-scrollbar
|
|
288
|
+
::-webkit-scrollbar
|
|
289
|
+
{
|
|
44
290
|
width: 8px;
|
|
291
|
+
height: 8px;
|
|
45
292
|
}
|
|
46
293
|
|
|
47
|
-
::-webkit-scrollbar-track
|
|
48
|
-
|
|
294
|
+
::-webkit-scrollbar-track
|
|
295
|
+
{
|
|
296
|
+
background: var(--docuserve-scrollbar-track);
|
|
49
297
|
}
|
|
50
298
|
|
|
51
|
-
::-webkit-scrollbar-thumb
|
|
52
|
-
|
|
299
|
+
::-webkit-scrollbar-thumb
|
|
300
|
+
{
|
|
301
|
+
background: var(--docuserve-scrollbar-thumb);
|
|
53
302
|
border-radius: 4px;
|
|
54
303
|
}
|
|
55
304
|
|
|
56
|
-
::-webkit-scrollbar-thumb:hover
|
|
57
|
-
|
|
305
|
+
::-webkit-scrollbar-thumb:hover
|
|
306
|
+
{
|
|
307
|
+
background: var(--docuserve-scrollbar-thumb-hover);
|
|
58
308
|
}
|
|
59
309
|
|
|
60
310
|
/* Responsive adjustments */
|
|
61
|
-
@media (max-width: 768px)
|
|
62
|
-
|
|
311
|
+
@media (max-width: 768px)
|
|
312
|
+
{
|
|
313
|
+
html
|
|
314
|
+
{
|
|
63
315
|
font-size: 14px;
|
|
64
316
|
}
|
|
65
317
|
|
|
66
|
-
#Docuserve-Sidebar-Container
|
|
318
|
+
#Docuserve-Sidebar-Container
|
|
319
|
+
{
|
|
67
320
|
display: none;
|
|
68
321
|
}
|
|
69
322
|
|
|
70
|
-
.docuserve-body
|
|
323
|
+
.docuserve-body
|
|
324
|
+
{
|
|
71
325
|
flex-direction: column;
|
|
72
326
|
}
|
|
73
327
|
}
|
package/docs/endpoints.md
CHANGED
|
@@ -7,8 +7,8 @@ Once initialized, Retold Data Service automatically creates RESTful endpoints fo
|
|
|
7
7
|
All endpoints follow the Meadow Endpoints URL pattern:
|
|
8
8
|
|
|
9
9
|
```
|
|
10
|
-
/{Version}/{Entity}
|
|
11
|
-
/{Version}/{Entity}s
|
|
10
|
+
/{Version}/{Entity} -- singular entity operations (Read, Create, Update, Delete)
|
|
11
|
+
/{Version}/{Entity}s -- plural entity operations (Reads, Count)
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
The version defaults to `1.0`.
|
package/docs/index.html
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
|
7
|
-
<meta name="description" content="Documentation
|
|
7
|
+
<meta name="description" content="Retold Data Service v2.0.33 Documentation — Serve up a whole model!">
|
|
8
8
|
|
|
9
|
-
<title>Documentation</title>
|
|
9
|
+
<title>Retold Data Service v2.0.33 Documentation</title>
|
|
10
10
|
|
|
11
11
|
<!-- Application Stylesheet -->
|
|
12
12
|
<link href="css/docuserve.css" rel="stylesheet">
|
package/docs/initialization.md
CHANGED
|
@@ -30,12 +30,12 @@ _Fable.RetoldDataService.initializeService(
|
|
|
30
30
|
When `initializeService()` is called, the following steps run in order:
|
|
31
31
|
|
|
32
32
|
```
|
|
33
|
-
1. onBeforeInitialize()
|
|
34
|
-
2. Start Orator web server
|
|
35
|
-
3. initializePersistenceEngine()
|
|
36
|
-
4. onInitialize()
|
|
37
|
-
5. initializeDataEndpoints()
|
|
38
|
-
6. onAfterInitialize()
|
|
33
|
+
1. onBeforeInitialize() <- your custom hook
|
|
34
|
+
2. Start Orator web server <- if AutoStartOrator is true
|
|
35
|
+
3. initializePersistenceEngine() <- loads the storage provider module
|
|
36
|
+
4. onInitialize() <- your custom hook
|
|
37
|
+
5. initializeDataEndpoints() <- loads model, creates DAL + endpoints
|
|
38
|
+
6. onAfterInitialize() <- your custom hook
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
### Step 5: initializeDataEndpoints()
|
package/docs/retold-catalog.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"Generated": "2026-
|
|
2
|
+
"Generated": "2026-04-10T17:22:17.521Z",
|
|
3
3
|
"GitHubOrg": "stevenvelozo",
|
|
4
4
|
"DefaultBranch": "master",
|
|
5
5
|
"Groups": [
|
|
@@ -50,23 +50,6 @@
|
|
|
50
50
|
}
|
|
51
51
|
]
|
|
52
52
|
},
|
|
53
|
-
{
|
|
54
|
-
"Name": "Debug",
|
|
55
|
-
"Key": "debug",
|
|
56
|
-
"Description": "",
|
|
57
|
-
"Modules": [
|
|
58
|
-
{
|
|
59
|
-
"Name": "data",
|
|
60
|
-
"Repo": "data",
|
|
61
|
-
"Group": "debug",
|
|
62
|
-
"Branch": "master",
|
|
63
|
-
"HasDocs": false,
|
|
64
|
-
"HasCover": false,
|
|
65
|
-
"Sidebar": [],
|
|
66
|
-
"DocFiles": []
|
|
67
|
-
}
|
|
68
|
-
]
|
|
69
|
-
},
|
|
70
53
|
{
|
|
71
54
|
"Name": "Dist",
|
|
72
55
|
"Key": "dist",
|
|
@@ -123,6 +106,23 @@
|
|
|
123
106
|
}
|
|
124
107
|
]
|
|
125
108
|
},
|
|
109
|
+
{
|
|
110
|
+
"Name": "Source",
|
|
111
|
+
"Key": "source",
|
|
112
|
+
"Description": "",
|
|
113
|
+
"Modules": [
|
|
114
|
+
{
|
|
115
|
+
"Name": "services",
|
|
116
|
+
"Repo": "services",
|
|
117
|
+
"Group": "source",
|
|
118
|
+
"Branch": "master",
|
|
119
|
+
"HasDocs": false,
|
|
120
|
+
"HasCover": false,
|
|
121
|
+
"Sidebar": [],
|
|
122
|
+
"DocFiles": []
|
|
123
|
+
}
|
|
124
|
+
]
|
|
125
|
+
},
|
|
126
126
|
{
|
|
127
127
|
"Name": "Test",
|
|
128
128
|
"Key": "test",
|
|
@@ -43,7 +43,7 @@ $Name 200
|
|
|
43
43
|
|
|
44
44
|
| Symbol | Meaning | Meadow Type |
|
|
45
45
|
|--------|---------|-------------|
|
|
46
|
-
| `!` | Table/entity name |
|
|
46
|
+
| `!` | Table/entity name | -- |
|
|
47
47
|
| `@` | Auto-increment ID | `AutoIdentity` |
|
|
48
48
|
| `%` | Auto GUID | `AutoGUID` |
|
|
49
49
|
| `&` | DateTime column | `CreateDate`, `UpdateDate`, `DeleteDate`, or `DateTime` |
|
|
@@ -121,8 +121,8 @@ This runs `cd test && npx stricture -i model/ddl/BookStore.ddl` to regenerate th
|
|
|
121
121
|
| `Deleted` | Soft-delete flag | On Delete (set to 1) |
|
|
122
122
|
| `DeleteDate` | Deletion timestamp | On Delete |
|
|
123
123
|
| `DeleteIDUser` | Deleter user ID | On Delete |
|
|
124
|
-
| `String` | Text data |
|
|
125
|
-
| `Integer` | Numeric data |
|
|
126
|
-
| `Decimal` | Decimal data |
|
|
127
|
-
| `Boolean` | Boolean data |
|
|
128
|
-
| `DateTime` | Date/time data |
|
|
124
|
+
| `String` | Text data | -- |
|
|
125
|
+
| `Integer` | Numeric data | -- |
|
|
126
|
+
| `Decimal` | Decimal data | -- |
|
|
127
|
+
| `Boolean` | Boolean data | -- |
|
|
128
|
+
| `DateTime` | Date/time data | -- |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "retold-data-service",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.34",
|
|
4
4
|
"description": "Serve up a whole model!",
|
|
5
5
|
"main": "source/Retold-Data-Service.js",
|
|
6
6
|
"bin": {
|
|
@@ -60,8 +60,9 @@
|
|
|
60
60
|
"homepage": "https://github.com/stevenvelozo/retold-data-service",
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"meadow-connection-sqlite": "^1.0.18",
|
|
63
|
+
"pict-docuserve": "^0.1.5",
|
|
63
64
|
"puppeteer": "^24.40.0",
|
|
64
|
-
"quackage": "^1.0
|
|
65
|
+
"quackage": "^1.1.0",
|
|
65
66
|
"stricture": "^4.0.2",
|
|
66
67
|
"supertest": "^7.2.2"
|
|
67
68
|
},
|
|
@@ -73,7 +74,7 @@
|
|
|
73
74
|
"meadow-connection-mysql": "^1.0.14",
|
|
74
75
|
"meadow-endpoints": "^4.0.15",
|
|
75
76
|
"meadow-integration": "^1.0.23",
|
|
76
|
-
"meadow-migrationmanager": "^0.0.
|
|
77
|
+
"meadow-migrationmanager": "^0.0.9",
|
|
77
78
|
"orator": "^6.0.4",
|
|
78
79
|
"orator-http-proxy": "^1.0.5",
|
|
79
80
|
"orator-serviceserver-restify": "^2.0.10",
|
|
@@ -251,7 +251,9 @@ module.exports = (pDataClonerService, pConfig, pCLIOptions, fCallback) =>
|
|
|
251
251
|
PageSize: tmpSync.PageSize || 100,
|
|
252
252
|
SyncDeletedRecords: !!tmpSync.SyncDeletedRecords,
|
|
253
253
|
MaxRecordsPerEntity: tmpMaxRecords || tmpSync.MaxRecordsPerEntity || 0,
|
|
254
|
-
DateTimePrecisionMS: tmpSync.DateTimePrecisionMS
|
|
254
|
+
DateTimePrecisionMS: tmpSync.DateTimePrecisionMS,
|
|
255
|
+
BackSyncTimeLimit: tmpSync.BackSyncTimeLimit,
|
|
256
|
+
TrueUpPageSize: tmpSync.TrueUpPageSize
|
|
255
257
|
});
|
|
256
258
|
|
|
257
259
|
tmpFable.log.info(`Headless: Starting ${tmpSyncBody.SyncMode} sync...`);
|
|
@@ -89,6 +89,36 @@ module.exports = (pDataClonerService, pOratorServiceServer) =>
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
// Update BackSyncTimeLimit on MeadowSync and all sync entities
|
|
93
|
+
if (tmpBody.hasOwnProperty('BackSyncTimeLimit'))
|
|
94
|
+
{
|
|
95
|
+
let tmpBackSyncTimeLimit = parseInt(tmpBody.BackSyncTimeLimit, 10);
|
|
96
|
+
if (!isNaN(tmpBackSyncTimeLimit) && tmpBackSyncTimeLimit > 0)
|
|
97
|
+
{
|
|
98
|
+
tmpFable.MeadowSync.BackSyncTimeLimit = tmpBackSyncTimeLimit;
|
|
99
|
+
let tmpEntityNames = Object.keys(tmpFable.MeadowSync.MeadowSyncEntities);
|
|
100
|
+
for (let i = 0; i < tmpEntityNames.length; i++)
|
|
101
|
+
{
|
|
102
|
+
tmpFable.MeadowSync.MeadowSyncEntities[tmpEntityNames[i]].BackSyncTimeLimit = tmpBackSyncTimeLimit;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Update TrueUpPageSize on MeadowSync and all sync entities
|
|
108
|
+
if (tmpBody.hasOwnProperty('TrueUpPageSize'))
|
|
109
|
+
{
|
|
110
|
+
let tmpTrueUpPageSize = parseInt(tmpBody.TrueUpPageSize, 10);
|
|
111
|
+
if (!isNaN(tmpTrueUpPageSize) && tmpTrueUpPageSize > 0)
|
|
112
|
+
{
|
|
113
|
+
tmpFable.MeadowSync.TrueUpPageSize = tmpTrueUpPageSize;
|
|
114
|
+
let tmpEntityNames = Object.keys(tmpFable.MeadowSync.MeadowSyncEntities);
|
|
115
|
+
for (let i = 0; i < tmpEntityNames.length; i++)
|
|
116
|
+
{
|
|
117
|
+
tmpFable.MeadowSync.MeadowSyncEntities[tmpEntityNames[i]].TrueUpPageSize = tmpTrueUpPageSize;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
92
122
|
// If no tables specified, sync all entities
|
|
93
123
|
if (tmpSelectedTables.length === 0)
|
|
94
124
|
{
|
|
@@ -7,6 +7,25 @@ class DataClonerSyncView extends libPictView
|
|
|
7
7
|
super(pFable, pOptions, pServiceHash);
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
onSyncModeChanged()
|
|
11
|
+
{
|
|
12
|
+
let tmpMode = document.querySelector('input[name="syncMode"]:checked').value;
|
|
13
|
+
|
|
14
|
+
// Hide all mode-specific option panels
|
|
15
|
+
let tmpPanels = document.querySelectorAll('[id^="syncModeOptions-"]');
|
|
16
|
+
for (let i = 0; i < tmpPanels.length; i++)
|
|
17
|
+
{
|
|
18
|
+
tmpPanels[i].style.display = 'none';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Show the panel for the selected mode (if one exists)
|
|
22
|
+
let tmpPanel = document.getElementById('syncModeOptions-' + tmpMode);
|
|
23
|
+
if (tmpPanel)
|
|
24
|
+
{
|
|
25
|
+
tmpPanel.style.display = 'block';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
10
29
|
startSync()
|
|
11
30
|
{
|
|
12
31
|
let tmpSelectedTables = this.pict.views['DataCloner-Schema'].getSelectedTables();
|
|
@@ -34,6 +53,18 @@ class DataClonerSyncView extends libPictView
|
|
|
34
53
|
if (tmpMaxRecords > 0) tmpPostBody.MaxRecordsPerEntity = tmpMaxRecords;
|
|
35
54
|
if (tmpLogToFile) tmpPostBody.LogToFile = true;
|
|
36
55
|
if (tmpAdvancedIDPagination) tmpPostBody.UseAdvancedIDPagination = true;
|
|
56
|
+
|
|
57
|
+
// Strategy-specific options
|
|
58
|
+
if (tmpSyncMode === 'OngoingEventualConsistency')
|
|
59
|
+
{
|
|
60
|
+
let tmpBackSyncTimeLimit = parseInt(document.getElementById('backSyncTimeLimit').value, 10);
|
|
61
|
+
if (tmpBackSyncTimeLimit > 0) tmpPostBody.BackSyncTimeLimit = tmpBackSyncTimeLimit;
|
|
62
|
+
}
|
|
63
|
+
if (tmpSyncMode === 'TrueUp')
|
|
64
|
+
{
|
|
65
|
+
let tmpTrueUpPageSize = parseInt(document.getElementById('trueUpPageSize').value, 10);
|
|
66
|
+
if (tmpTrueUpPageSize > 0) tmpPostBody.TrueUpPageSize = tmpTrueUpPageSize;
|
|
67
|
+
}
|
|
37
68
|
this.pict.providers.DataCloner.api('POST', '/clone/sync/start', tmpPostBody)
|
|
38
69
|
.then(function(pData)
|
|
39
70
|
{
|
|
@@ -507,16 +538,48 @@ module.exports.default_configuration =
|
|
|
507
538
|
|
|
508
539
|
<div style="margin-bottom:10px">
|
|
509
540
|
<label style="margin-bottom:6px">Sync Mode</label>
|
|
510
|
-
<div style="display:flex; gap:
|
|
541
|
+
<div style="display:flex; gap:12px 20px; align-items:center; flex-wrap:wrap">
|
|
511
542
|
<label style="font-weight:normal; margin:0; cursor:pointer">
|
|
512
|
-
<input type="radio" name="syncMode" id="syncModeInitial" value="Initial" checked> Initial
|
|
513
|
-
<span style="color:#888; font-size:0.85em">(full clone
|
|
543
|
+
<input type="radio" name="syncMode" id="syncModeInitial" value="Initial" checked onchange="pict.views['DataCloner-Sync'].onSyncModeChanged()"> Initial
|
|
544
|
+
<span style="color:#888; font-size:0.85em">(full clone)</span>
|
|
514
545
|
</label>
|
|
515
546
|
<label style="font-weight:normal; margin:0; cursor:pointer">
|
|
516
|
-
<input type="radio" name="syncMode" id="syncModeOngoing" value="Ongoing"> Ongoing
|
|
517
|
-
<span style="color:#888; font-size:0.85em">(delta
|
|
547
|
+
<input type="radio" name="syncMode" id="syncModeOngoing" value="Ongoing" onchange="pict.views['DataCloner-Sync'].onSyncModeChanged()"> Ongoing
|
|
548
|
+
<span style="color:#888; font-size:0.85em">(delta sync)</span>
|
|
518
549
|
</label>
|
|
550
|
+
<label style="font-weight:normal; margin:0; cursor:pointer">
|
|
551
|
+
<input type="radio" name="syncMode" id="syncModeOngoingEventualConsistency" value="OngoingEventualConsistency" onchange="pict.views['DataCloner-Sync'].onSyncModeChanged()"> Eventual
|
|
552
|
+
<span style="color:#888; font-size:0.85em">(time-budgeted back-sync)</span>
|
|
553
|
+
</label>
|
|
554
|
+
<label style="font-weight:normal; margin:0; cursor:pointer">
|
|
555
|
+
<input type="radio" name="syncMode" id="syncModeTrueUp" value="TrueUp" onchange="pict.views['DataCloner-Sync'].onSyncModeChanged()"> True-Up
|
|
556
|
+
<span style="color:#888; font-size:0.85em">(linear walk, one-time)</span>
|
|
557
|
+
</label>
|
|
558
|
+
<label style="font-weight:normal; margin:0; cursor:pointer">
|
|
559
|
+
<input type="radio" name="syncMode" id="syncModeComparisonOnly" value="ComparisonOnly" onchange="pict.views['DataCloner-Sync'].onSyncModeChanged()"> Compare
|
|
560
|
+
<span style="color:#888; font-size:0.85em">(diff report, no sync)</span>
|
|
561
|
+
</label>
|
|
562
|
+
</div>
|
|
563
|
+
</div>
|
|
564
|
+
|
|
565
|
+
<div id="syncModeOptions-OngoingEventualConsistency" style="display:none; margin-bottom:10px">
|
|
566
|
+
<div style="display:flex; gap:8px; align-items:flex-end">
|
|
567
|
+
<div style="flex:0 0 220px">
|
|
568
|
+
<label for="backSyncTimeLimit">Back-Sync Time Budget (ms)</label>
|
|
569
|
+
<input type="number" id="backSyncTimeLimit" value="30000" min="1000" max="600000" style="margin-bottom:0">
|
|
570
|
+
</div>
|
|
571
|
+
</div>
|
|
572
|
+
<div style="font-size:0.8em; color:#888; padding-left:4px">Milliseconds devoted to backwards bisection per entity before pulling new records (default: 30000)</div>
|
|
573
|
+
</div>
|
|
574
|
+
|
|
575
|
+
<div id="syncModeOptions-TrueUp" style="display:none; margin-bottom:10px">
|
|
576
|
+
<div style="display:flex; gap:8px; align-items:flex-end">
|
|
577
|
+
<div style="flex:0 0 220px">
|
|
578
|
+
<label for="trueUpPageSize">True-Up Page Size</label>
|
|
579
|
+
<input type="number" id="trueUpPageSize" value="500" min="10" max="10000" style="margin-bottom:0">
|
|
580
|
+
</div>
|
|
519
581
|
</div>
|
|
582
|
+
<div style="font-size:0.8em; color:#888; padding-left:4px">Records per page for the linear keyset walk (default: 500)</div>
|
|
520
583
|
</div>
|
|
521
584
|
|
|
522
585
|
<div class="checkbox-row">
|