retold-data-service 2.0.21 → 2.0.23

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.
Files changed (37) hide show
  1. package/.quackage-comprehension-loader.json +19 -0
  2. package/bin/retold-data-service-clone.js +4 -1
  3. package/generate-bookstore-comprehension.js +645 -0
  4. package/package.json +7 -7
  5. package/source/Retold-Data-Service.js +30 -2
  6. package/source/services/comprehension-loader/ComprehensionLoader-Command-Load.js +345 -0
  7. package/source/services/comprehension-loader/ComprehensionLoader-Command-Schema.js +97 -0
  8. package/source/services/comprehension-loader/ComprehensionLoader-Command-Session.js +221 -0
  9. package/source/services/comprehension-loader/ComprehensionLoader-Command-WebUI.js +57 -0
  10. package/source/services/comprehension-loader/Retold-Data-Service-ComprehensionLoader.js +536 -0
  11. package/source/services/comprehension-loader/pict-app/Pict-Application-ComprehensionLoader-Configuration.json +9 -0
  12. package/source/services/comprehension-loader/pict-app/Pict-Application-ComprehensionLoader.js +86 -0
  13. package/source/services/comprehension-loader/pict-app/Pict-ComprehensionLoader-Bundle.js +6 -0
  14. package/source/services/comprehension-loader/pict-app/providers/Pict-Provider-ComprehensionLoader.js +760 -0
  15. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Layout.js +360 -0
  16. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Load.js +472 -0
  17. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Schema.js +119 -0
  18. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Session.js +269 -0
  19. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Source.js +330 -0
  20. package/source/services/comprehension-loader/web/comprehension-loader.js +6794 -0
  21. package/source/services/comprehension-loader/web/comprehension-loader.js.map +1 -0
  22. package/source/services/comprehension-loader/web/comprehension-loader.min.js +2 -0
  23. package/source/services/comprehension-loader/web/comprehension-loader.min.js.map +1 -0
  24. package/source/services/comprehension-loader/web/index.html +17 -0
  25. package/source/services/data-cloner/DataCloner-Command-Schema.js +407 -15
  26. package/source/services/data-cloner/Retold-Data-Service-DataCloner.js +59 -1
  27. package/source/services/data-cloner/pict-app/Pict-Application-DataCloner.js +1 -0
  28. package/source/services/data-cloner/pict-app/providers/Pict-Provider-DataCloner.js +125 -5
  29. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Connection.js +18 -8
  30. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Deploy.js +104 -1
  31. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Export.js +1 -1
  32. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Layout.js +12 -0
  33. package/source/services/data-cloner/web/data-cloner.js +201 -139
  34. package/source/services/data-cloner/web/data-cloner.js.map +1 -1
  35. package/source/services/data-cloner/web/data-cloner.min.js +1 -1
  36. package/source/services/data-cloner/web/data-cloner.min.js.map +1 -1
  37. package/test/RetoldDataService_tests.js +225 -0
@@ -0,0 +1,360 @@
1
+ const libPictView = require('pict-view');
2
+
3
+ class ComprehensionLoaderLayoutView extends libPictView
4
+ {
5
+ constructor(pFable, pOptions, pServiceHash)
6
+ {
7
+ super(pFable, pOptions, pServiceHash);
8
+ }
9
+
10
+ onAfterRender()
11
+ {
12
+ // Render all section views into their containers
13
+ this.pict.views['ComprehensionLoader-Session'].render();
14
+ this.pict.views['ComprehensionLoader-Schema'].render();
15
+ this.pict.views['ComprehensionLoader-Source'].render();
16
+ this.pict.views['ComprehensionLoader-Load'].render();
17
+
18
+ this.pict.CSSMap.injectCSS();
19
+ }
20
+
21
+ toggleSection(pSectionId)
22
+ {
23
+ let tmpCard = document.getElementById(pSectionId);
24
+ if (!tmpCard) return;
25
+ tmpCard.classList.toggle('open');
26
+ }
27
+
28
+ expandAllSections()
29
+ {
30
+ let tmpCards = document.querySelectorAll('.accordion-card');
31
+ for (let i = 0; i < tmpCards.length; i++)
32
+ {
33
+ tmpCards[i].classList.add('open');
34
+ }
35
+ }
36
+
37
+ collapseAllSections()
38
+ {
39
+ let tmpCards = document.querySelectorAll('.accordion-card');
40
+ for (let i = 0; i < tmpCards.length; i++)
41
+ {
42
+ tmpCards[i].classList.remove('open');
43
+ }
44
+ }
45
+
46
+ toggleStatusDetail()
47
+ {
48
+ let tmpDetail = document.getElementById('liveStatusDetail');
49
+ let tmpMeta = document.getElementById('liveStatusMeta');
50
+ let tmpMessage = document.getElementById('liveStatusMessage');
51
+ let tmpToggle = document.getElementById('liveStatusToggle');
52
+ let tmpBar = document.getElementById('liveStatusBar');
53
+ if (!tmpDetail) return;
54
+
55
+ let tmpIsExpanded = tmpDetail.style.display !== 'none';
56
+
57
+ if (tmpIsExpanded)
58
+ {
59
+ tmpDetail.style.display = 'none';
60
+ tmpMeta.style.display = '';
61
+ tmpMessage.style.display = '';
62
+ tmpToggle.innerHTML = '&#9660;';
63
+ tmpBar.classList.remove('expanded');
64
+ this.pict.providers.ComprehensionLoader.onStatusDetailCollapsed();
65
+ }
66
+ else
67
+ {
68
+ tmpDetail.style.display = '';
69
+ tmpMeta.style.display = 'none';
70
+ tmpMessage.style.display = 'none';
71
+ tmpToggle.innerHTML = '&#9650;';
72
+ tmpBar.classList.add('expanded');
73
+ this.pict.providers.ComprehensionLoader.onStatusDetailExpanded();
74
+ }
75
+ }
76
+ }
77
+
78
+ module.exports = ComprehensionLoaderLayoutView;
79
+
80
+ module.exports.default_configuration =
81
+ {
82
+ ViewIdentifier: 'ComprehensionLoader-Layout',
83
+ DefaultRenderable: 'ComprehensionLoader-Layout',
84
+ DefaultDestinationAddress: '#ComprehensionLoader-Application-Container',
85
+ CSS: /*css*/`
86
+ * { box-sizing: border-box; margin: 0; padding: 0; }
87
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f5f5f5; color: #333; padding: 20px; }
88
+ h1 { margin-bottom: 20px; color: #1a1a1a; }
89
+ h2 { margin-bottom: 12px; color: #444; font-size: 1.2em; border-bottom: 2px solid #ddd; padding-bottom: 6px; }
90
+
91
+ .section { background: #fff; border-radius: 8px; padding: 20px; margin-bottom: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
92
+
93
+ /* Accordion layout */
94
+ .accordion-row { display: flex; gap: 0; margin-bottom: 16px; align-items: stretch; }
95
+ .accordion-number {
96
+ flex: 0 0 48px; display: flex; align-items: flex-start; justify-content: center;
97
+ padding-top: 16px; font-size: 1.6em; font-weight: 700; color: #4a90d9;
98
+ user-select: none;
99
+ }
100
+ .accordion-card {
101
+ flex: 1; background: #fff; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);
102
+ overflow: hidden; min-width: 0;
103
+ }
104
+ .accordion-header {
105
+ display: flex; align-items: center; padding: 14px 20px; cursor: pointer;
106
+ user-select: none; gap: 12px; transition: background 0.15s; line-height: 1.4;
107
+ }
108
+ .accordion-header:hover { background: #fafafa; }
109
+ .accordion-title { font-weight: 600; color: #333; font-size: 1.05em; white-space: nowrap; }
110
+ .accordion-preview { flex: 1; font-style: italic; color: #888; font-size: 0.9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
111
+ .accordion-toggle {
112
+ flex: 0 0 20px; display: flex; align-items: center; justify-content: center;
113
+ border-radius: 4px; transition: background 0.15s, transform 0.25s; font-size: 0.7em; color: #888;
114
+ }
115
+ .accordion-header:hover .accordion-toggle { background: #eee; color: #555; }
116
+ .accordion-card.open .accordion-toggle { transform: rotate(180deg); }
117
+ .accordion-body { padding: 0 20px 20px; display: none; }
118
+ .accordion-card.open .accordion-body { display: block; }
119
+ .accordion-card.open .accordion-header { border-bottom: 1px solid #eee; }
120
+ .accordion-card.open .accordion-preview { display: none; }
121
+
122
+ /* Action controls (go link + auto checkbox) */
123
+ .accordion-actions { display: flex; align-items: baseline; gap: 8px; flex-shrink: 0; }
124
+ .accordion-card.open .accordion-actions { display: none; }
125
+ .accordion-go {
126
+ font-size: 0.82em; color: #4a90d9; cursor: pointer; text-decoration: none;
127
+ font-weight: 500; white-space: nowrap; padding: 2px 6px; border-radius: 3px;
128
+ transition: background 0.15s;
129
+ }
130
+ .accordion-go:hover { background: #e8f0fe; text-decoration: underline; }
131
+ .accordion-auto {
132
+ font-size: 0.82em; color: #999; white-space: nowrap; cursor: pointer;
133
+ }
134
+ .accordion-auto .auto-label { display: none; }
135
+ .accordion-auto:hover .auto-label { display: inline; }
136
+ .accordion-auto input[type="checkbox"] { width: auto; margin: 0; cursor: pointer; vertical-align: middle; position: relative; top: 0px; opacity: 0.75; transition: opacity 0.15s; }
137
+ .accordion-auto:hover input[type="checkbox"] { opacity: 1; }
138
+ .accordion-auto:hover { color: #666; }
139
+
140
+ /* Phase status indicator */
141
+ .accordion-phase {
142
+ flex: 0 0 auto; display: none; align-items: center; justify-content: center;
143
+ font-size: 0.85em; line-height: 1;
144
+ }
145
+ .accordion-phase.visible { display: flex; }
146
+ .accordion-phase-ok { color: #28a745; }
147
+ .accordion-phase-error { color: #dc3545; }
148
+ .accordion-phase-busy { color: #28a745; }
149
+ .accordion-phase-busy .phase-spinner {
150
+ display: inline-block; width: 14px; height: 14px;
151
+ border: 2px solid #28a745; border-top-color: transparent; border-radius: 50%;
152
+ animation: phase-spin 0.8s linear infinite; vertical-align: middle;
153
+ }
154
+ @keyframes phase-spin {
155
+ to { transform: rotate(360deg); }
156
+ }
157
+
158
+ .accordion-controls {
159
+ display: flex; gap: 8px; margin-bottom: 12px; justify-content: flex-end;
160
+ }
161
+ .accordion-controls button {
162
+ padding: 4px 10px; font-size: 0.82em; font-weight: 500; background: none;
163
+ border: 1px solid #ccc; border-radius: 4px; color: #666; cursor: pointer; margin: 0;
164
+ }
165
+ .accordion-controls button:hover { background: #f0f0f0; border-color: #aaa; color: #333; }
166
+
167
+ label { display: block; font-weight: 600; margin-bottom: 4px; font-size: 0.9em; }
168
+ input[type="text"], input[type="password"], input[type="number"] {
169
+ width: 100%; padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px;
170
+ font-size: 0.95em; margin-bottom: 10px;
171
+ }
172
+ input[type="text"]:focus, input[type="password"]:focus, input[type="number"]:focus {
173
+ outline: none; border-color: #4a90d9;
174
+ }
175
+
176
+ button {
177
+ padding: 8px 16px; border: none; border-radius: 4px; cursor: pointer;
178
+ font-size: 0.9em; font-weight: 600; margin-right: 8px; margin-bottom: 8px;
179
+ }
180
+ button.primary { background: #4a90d9; color: #fff; }
181
+ button.primary:hover { background: #357abd; }
182
+ button.secondary { background: #6c757d; color: #fff; }
183
+ button.secondary:hover { background: #5a6268; }
184
+ button.danger { background: #dc3545; color: #fff; }
185
+ button.danger:hover { background: #c82333; }
186
+ button.success { background: #28a745; color: #fff; }
187
+ button.success:hover { background: #218838; }
188
+ button:disabled { opacity: 0.5; cursor: not-allowed; }
189
+
190
+ .status { padding: 8px 12px; border-radius: 4px; margin-top: 10px; font-size: 0.9em; }
191
+ .status.ok { background: #d4edda; color: #155724; }
192
+ .status.error { background: #f8d7da; color: #721c24; }
193
+ .status.info { background: #d1ecf1; color: #0c5460; }
194
+ .status.warn { background: #fff3cd; color: #856404; }
195
+
196
+ .inline-group { display: flex; gap: 8px; align-items: flex-end; margin-bottom: 10px; }
197
+ .inline-group > div { flex: 1; }
198
+
199
+ a { color: #4a90d9; }
200
+
201
+ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px; font-size: 0.95em; margin-bottom: 10px; }
202
+
203
+ .checkbox-row { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
204
+ .checkbox-row input[type="checkbox"] { width: auto; margin: 0; }
205
+ .checkbox-row label { display: inline; margin: 0; font-weight: normal; cursor: pointer; }
206
+
207
+ /* Live Status Bar */
208
+ .live-status-bar {
209
+ background: #fff; border-radius: 8px; margin-bottom: 16px;
210
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
211
+ position: sticky; top: 0; z-index: 100; border-left: 4px solid #6c757d;
212
+ }
213
+ .live-status-bar.phase-idle { border-left-color: #6c757d; }
214
+ .live-status-bar.phase-disconnected { border-left-color: #dc3545; }
215
+ .live-status-bar.phase-ready { border-left-color: #4a90d9; }
216
+ .live-status-bar.phase-loading { border-left-color: #28a745; }
217
+ .live-status-bar.phase-stopping { border-left-color: #ffc107; }
218
+ .live-status-bar.phase-complete { border-left-color: #28a745; }
219
+
220
+ .live-status-dot {
221
+ width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0;
222
+ background: #6c757d;
223
+ }
224
+ .live-status-bar.phase-idle .live-status-dot { background: #6c757d; }
225
+ .live-status-bar.phase-disconnected .live-status-dot { background: #dc3545; }
226
+ .live-status-bar.phase-ready .live-status-dot { background: #4a90d9; }
227
+ .live-status-bar.phase-loading .live-status-dot {
228
+ background: #28a745;
229
+ animation: live-pulse 1.5s ease-in-out infinite;
230
+ }
231
+ .live-status-bar.phase-stopping .live-status-dot {
232
+ background: #ffc107;
233
+ animation: live-pulse 0.8s ease-in-out infinite;
234
+ }
235
+ .live-status-bar.phase-complete .live-status-dot { background: #28a745; }
236
+
237
+ @keyframes live-pulse {
238
+ 0%, 100% { opacity: 1; transform: scale(1); }
239
+ 50% { opacity: 0.4; transform: scale(0.8); }
240
+ }
241
+
242
+ .live-status-message { flex: 1; font-size: 0.92em; color: #333; line-height: 1.4; }
243
+
244
+ .live-status-meta {
245
+ display: flex; gap: 16px; flex-shrink: 0; font-size: 0.82em; color: #666;
246
+ }
247
+ .live-status-meta-item { white-space: nowrap; }
248
+ .live-status-meta-item strong { color: #333; }
249
+
250
+ .live-status-progress-bar {
251
+ height: 3px; background: #e9ecef; border-radius: 2px; overflow: hidden;
252
+ position: absolute; bottom: 0; left: 0; right: 0;
253
+ }
254
+ .live-status-progress-fill {
255
+ height: 100%; background: #28a745; transition: width 1s ease;
256
+ }
257
+ /* Expandable status bar */
258
+ .live-status-header {
259
+ display: flex; align-items: center; gap: 14px; cursor: pointer;
260
+ padding: 14px 20px; user-select: none;
261
+ }
262
+ .live-status-bar.expanded .live-status-header {
263
+ border-bottom: 1px solid #e9ecef; padding-bottom: 10px;
264
+ }
265
+ .live-status-expand-toggle {
266
+ flex: 0 0 20px; display: flex; align-items: center; justify-content: center;
267
+ font-size: 0.7em; color: #888; transition: transform 0.25s;
268
+ }
269
+ .live-status-bar.expanded .live-status-expand-toggle { transform: rotate(180deg); }
270
+
271
+ .live-status-detail {
272
+ padding: 12px 20px 16px; max-height: 60vh; overflow-y: auto;
273
+ }
274
+
275
+ /* Status Detail Sections */
276
+ .status-detail-section { margin-bottom: 14px; }
277
+ .status-detail-section:last-child { margin-bottom: 0; }
278
+ .status-detail-section-title {
279
+ font-size: 0.85em; font-weight: 600; color: #555; text-transform: uppercase;
280
+ letter-spacing: 0.5px; margin-bottom: 8px; padding-bottom: 4px;
281
+ border-bottom: 1px solid #eee;
282
+ }
283
+
284
+ /* Running Operations */
285
+ .running-op-row {
286
+ display: flex; align-items: center; gap: 12px; padding: 6px 0;
287
+ font-size: 0.9em;
288
+ }
289
+ .running-op-name { font-weight: 600; min-width: 180px; }
290
+ .running-op-bar {
291
+ flex: 1; height: 8px; background: #e9ecef; border-radius: 4px; overflow: hidden;
292
+ min-width: 120px;
293
+ }
294
+ .running-op-bar-fill { height: 100%; background: #4a90d9; transition: width 0.5s ease; }
295
+ .running-op-count { font-size: 0.85em; color: #666; white-space: nowrap; }
296
+ .running-op-pending { color: #888; font-size: 0.85em; font-style: italic; padding: 4px 0; }
297
+
298
+ /* Completed Operations */
299
+ .completed-op-row { padding: 8px 0; border-bottom: 1px solid #f0f0f0; }
300
+ .completed-op-row:last-child { border-bottom: none; }
301
+ .completed-op-header {
302
+ display: flex; align-items: center; gap: 10px; font-size: 0.9em; margin-bottom: 4px;
303
+ }
304
+ .completed-op-name { font-weight: 600; }
305
+ .completed-op-stats { color: #666; font-size: 0.85em; }
306
+ .completed-op-checkmark { color: #28a745; }
307
+
308
+ /* Error Operations */
309
+ .error-op-row { padding: 6px 0; border-bottom: 1px solid #f0f0f0; font-size: 0.9em; }
310
+ .error-op-row:last-child { border-bottom: none; }
311
+ .error-op-header { display: flex; align-items: center; gap: 8px; }
312
+ .error-op-name { font-weight: 600; color: #dc3545; }
313
+ .error-op-status { font-size: 0.82em; color: #dc3545; }
314
+ .error-op-message { font-size: 0.82em; color: #888; margin-top: 2px; padding-left: 18px; }
315
+ `,
316
+ Templates:
317
+ [
318
+ {
319
+ Hash: 'ComprehensionLoader-Layout',
320
+ Template: /*html*/`
321
+ <h1>Retold Comprehension Loader</h1>
322
+
323
+ <!-- Live Status Bar (Expandable) -->
324
+ <div id="liveStatusBar" class="live-status-bar phase-idle" style="position:relative">
325
+ <div class="live-status-header" onclick="pict.views['ComprehensionLoader-Layout'].toggleStatusDetail()">
326
+ <div class="live-status-dot"></div>
327
+ <div class="live-status-message" id="liveStatusMessage">Idle</div>
328
+ <div class="live-status-meta" id="liveStatusMeta"></div>
329
+ <div class="live-status-expand-toggle" id="liveStatusToggle">&#9660;</div>
330
+ </div>
331
+ <div class="live-status-detail" id="liveStatusDetail" style="display:none">
332
+ <div id="ComprehensionLoader-Throughput-Histogram"></div>
333
+ <div id="ComprehensionLoader-StatusDetail-Container"></div>
334
+ </div>
335
+ <div class="live-status-progress-bar"><div class="live-status-progress-fill" id="liveStatusProgressFill" style="width:0%"></div></div>
336
+ </div>
337
+
338
+ <!-- Expand / Collapse All -->
339
+ <div class="accordion-controls">
340
+ <button onclick="pict.views['ComprehensionLoader-Layout'].expandAllSections()">Expand All</button>
341
+ <button onclick="pict.views['ComprehensionLoader-Layout'].collapseAllSections()">Collapse All</button>
342
+ </div>
343
+
344
+ <!-- Section containers -->
345
+ <div id="ComprehensionLoader-Section-Session"></div>
346
+ <div id="ComprehensionLoader-Section-Schema"></div>
347
+ <div id="ComprehensionLoader-Section-Source"></div>
348
+ <div id="ComprehensionLoader-Section-Load"></div>
349
+ `
350
+ }
351
+ ],
352
+ Renderables:
353
+ [
354
+ {
355
+ RenderableHash: 'ComprehensionLoader-Layout',
356
+ TemplateHash: 'ComprehensionLoader-Layout',
357
+ DestinationAddress: '#ComprehensionLoader-Application-Container'
358
+ }
359
+ ]
360
+ };