dsh-plugin-upgrader 1.0.2 → 1.1.1
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/CHANGELOG.md +134 -0
- package/README.en.md +29 -3
- package/README.md +24 -3
- package/lib/client.js +178 -26
- package/lib/host/install.d.ts +11 -1
- package/lib/host/install.d.ts.map +1 -1
- package/lib/host/install.js +189 -6
- package/lib/host/install.js.map +1 -1
- package/lib/host/manager.d.ts +35 -0
- package/lib/host/manager.d.ts.map +1 -1
- package/lib/host/manager.js.map +1 -1
- package/lib/host/overview.d.ts.map +1 -1
- package/lib/host/overview.js +68 -5
- package/lib/host/overview.js.map +1 -1
- package/lib/host/progress.d.ts +28 -0
- package/lib/host/progress.d.ts.map +1 -0
- package/lib/host/progress.js +21 -0
- package/lib/host/progress.js.map +1 -0
- package/lib/host/registry.d.ts +48 -1
- package/lib/host/registry.d.ts.map +1 -1
- package/lib/host/registry.js +124 -22
- package/lib/host/registry.js.map +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +174 -30
- package/lib/index.js.map +1 -1
- package/package.json +3 -2
package/lib/client.js
CHANGED
|
@@ -61,6 +61,9 @@ window.__ModuleLoader__.load({
|
|
|
61
61
|
upToDate: "\u5168\u90E8\u5DF2\u662F\u6700\u65B0",
|
|
62
62
|
upgrade: "\u5347\u7EA7",
|
|
63
63
|
upgrading: "\u5347\u7EA7\u4E2D\u2026",
|
|
64
|
+
selfUpdate: "\u7528\u9875\u9762\u5B89\u88C5\u5668\u5347\u7EA7",
|
|
65
|
+
selfUpdateHint: "\u63D2\u4EF6\u4E0D\u80FD\u5378\u8F7D\u81EA\u5DF1\u518D\u88C5\u56DE\u81EA\u5DF1\uFF0C\u6240\u4EE5\u8FD9\u4E00\u6B65\u4EA4\u7ED9\u63D2\u4EF6\u9875\u81EA\u5DF1\u7684\u5B89\u88C5\u6D41\u7A0B",
|
|
66
|
+
selfUpdateUnavailable: "\u8FD9\u4E00\u9875\u6CA1\u6709\u63D0\u4F9B\u5B89\u88C5\u5165\u53E3\uFF0C\u8BF7\u5728\u300C\u5DF2\u5B89\u88C5\u300D\u91CC\u7528\u5B98\u65B9\u5B89\u88C5\u5BF9\u8BDD\u6846\u5347\u7EA7\u672C\u63D2\u4EF6\u3002",
|
|
64
67
|
history: "\u5386\u53F2\u7248\u672C",
|
|
65
68
|
hideHistory: "\u6536\u8D77\u5386\u53F2",
|
|
66
69
|
github: "GitHub \u4E3B\u9875",
|
|
@@ -82,19 +85,32 @@ window.__ModuleLoader__.load({
|
|
|
82
85
|
openPage: "\u5728\u5DF2\u5B89\u88C5\u4E2D\u67E5\u770B",
|
|
83
86
|
noHistory: "\u6CA1\u6709\u53EF\u7528\u7684\u7248\u672C\u8BB0\u5F55",
|
|
84
87
|
noHistoryWhy: "\u8FD9\u4E2A\u5305\u4E0D\u662F\u4ECE npm \u6CE8\u518C\u8868\u5B89\u88C5\u7684\uFF0C\u6CA1\u6709\u53D1\u5E03\u5386\u53F2\u3002",
|
|
88
|
+
historyFailed: "\u7248\u672C\u5217\u8868\u8BFB\u53D6\u5931\u8D25\uFF0C\u70B9\u300C\u68C0\u67E5\u66F4\u65B0\u300D\u53EF\u91CD\u8BD5",
|
|
85
89
|
versions: (n) => `${n} \u4E2A\u7248\u672C`,
|
|
86
90
|
showingNewest: (n) => `\u5217\u51FA\u6700\u65B0 ${n} \u4E2A`,
|
|
87
91
|
progress: (done, total) => `\u6B63\u5728\u5904\u7406 ${done}/${total}`,
|
|
92
|
+
elapsed: (text) => `\u5DF2\u7528\u65F6 ${text}`,
|
|
93
|
+
phaseInstalling: "\u6B63\u5728\u4E0B\u8F7D\u5E76\u5B89\u88C5",
|
|
94
|
+
phaseApplying: "\u6B63\u5728\u5199\u5165\u914D\u7F6E",
|
|
95
|
+
phaseCancelling: "\u6B63\u5728\u53D6\u6D88",
|
|
96
|
+
phaseWaiting: "\u51C6\u5907\u4E2D",
|
|
97
|
+
registryAttempt: (index, total) => `\u6CE8\u518C\u8868 ${index}/${total}\uFF0C\u4E0A\u4E00\u4E2A\u8D85\u65F6\u4F1A\u81EA\u52A8\u6362\u6E90`,
|
|
98
|
+
slowHint: "\u9996\u6B21\u5B89\u88C5\u6216\u9700\u8981\u6821\u9A8C\u4F9D\u8D56\u65F6\u4F1A\u6BD4\u8F83\u6162\uFF0C\u65E5\u5FD7\u91CC\u80FD\u770B\u5230\u771F\u5B9E\u8FDB\u5EA6\u3002",
|
|
99
|
+
cancelRequested: "\u5DF2\u8BF7\u6C42\u53D6\u6D88",
|
|
100
|
+
stalled: "\u8FD9\u4E00\u6B65\u5DF2\u7ECF\u5F88\u4E45\u6CA1\u6709\u8F93\u51FA\u4E86\uFF0C\u53EF\u4EE5\u53D6\u6D88\u540E\u91CD\u8BD5\u3002",
|
|
101
|
+
staleSnapshot: "\u72B6\u6001\u5DF2\u505C\u6B62\u66F4\u65B0\uFF0C\u8BF7\u68C0\u67E5\u66F4\u65B0",
|
|
88
102
|
cancel: "\u53D6\u6D88",
|
|
89
103
|
cancelling: "\u6B63\u5728\u53D6\u6D88\u2026",
|
|
90
104
|
restart: "\u9700\u8981\u91CD\u542F DSH \u624D\u4F1A\u751F\u6548\u3002",
|
|
91
105
|
restartHint: "\u5DF2\u4FDD\u5B58\u7684\u6539\u52A8\u5728\u4E0B\u6B21\u542F\u52A8\u65F6\u751F\u6548\u3002",
|
|
106
|
+
reloadForAppearance: "\u4E3B\u9898\u63D2\u4EF6\u5DF2\u66F4\u65B0\uFF0C\u6B63\u5728\u91CD\u65B0\u52A0\u8F7D\u9875\u9762\u4EE5\u6062\u590D\u4E3B\u9898\u5916\u89C2\uFF08\u4E3B\u9898\u914D\u7F6E\u4FDD\u5B58\u5728\u78C1\u76D8\u4E0A\uFF0C\u4E0D\u4F1A\u4E22\u5931\uFF09\u3002",
|
|
92
107
|
done: "\u5B8C\u6210",
|
|
93
108
|
failed: "\u5931\u8D25",
|
|
94
109
|
failedSome: (n) => `${n} \u4E2A\u5931\u8D25`,
|
|
95
110
|
jobDone: "\u6279\u91CF\u5347\u7EA7\u5B8C\u6210",
|
|
96
111
|
jobCancelled: "\u5DF2\u53D6\u6D88",
|
|
97
112
|
busyAdopted: "\u5DF2\u6709\u4E00\u6279\u5347\u7EA7\u6B63\u5728\u8FDB\u884C\uFF0C\u5DF2\u63A5\u7740\u663E\u793A\u5B83\u7684\u8FDB\u5EA6\u3002",
|
|
113
|
+
lostJob: "\u5347\u7EA7\u8FDB\u5EA6\u5DF2\u5931\u53BB\u8054\u7CFB\uFF08\u5BBF\u4E3B\u53EF\u80FD\u91CD\u542F\u8FC7\uFF09\u3002\u8BF7\u68C0\u67E5\u66F4\u65B0\uFF0C\u786E\u8BA4\u63D2\u4EF6\u5F53\u524D\u7248\u672C\u3002",
|
|
98
114
|
log: "\u8FD0\u884C\u65E5\u5FD7",
|
|
99
115
|
showLog: "\u67E5\u770B\u65E5\u5FD7",
|
|
100
116
|
hideLog: "\u6536\u8D77\u65E5\u5FD7",
|
|
@@ -126,6 +142,9 @@ window.__ModuleLoader__.load({
|
|
|
126
142
|
upToDate: "Everything is up to date",
|
|
127
143
|
upgrade: "Upgrade",
|
|
128
144
|
upgrading: "Upgrading\u2026",
|
|
145
|
+
selfUpdate: "Upgrade via the page",
|
|
146
|
+
selfUpdateHint: "A plugin cannot uninstall and reinstall itself, so this runs the plugin page own installer",
|
|
147
|
+
selfUpdateUnavailable: "This page offers no install entry; upgrade this plugin from the Installed tab instead.",
|
|
129
148
|
history: "Version history",
|
|
130
149
|
hideHistory: "Hide history",
|
|
131
150
|
github: "GitHub page",
|
|
@@ -147,19 +166,32 @@ window.__ModuleLoader__.load({
|
|
|
147
166
|
openPage: "Open in Installed",
|
|
148
167
|
noHistory: "No published versions found",
|
|
149
168
|
noHistoryWhy: "This package was not installed from an npm registry, so it has no published history.",
|
|
169
|
+
historyFailed: 'Could not read the version list; "Check for updates" retries it',
|
|
150
170
|
versions: (n) => `${n} versions`,
|
|
151
171
|
showingNewest: (n) => `showing newest ${n}`,
|
|
152
172
|
progress: (done, total) => `Working on ${done}/${total}`,
|
|
173
|
+
elapsed: (text) => `${text} elapsed`,
|
|
174
|
+
phaseInstalling: "Downloading and installing",
|
|
175
|
+
phaseApplying: "Writing the profile",
|
|
176
|
+
phaseCancelling: "Cancelling",
|
|
177
|
+
phaseWaiting: "Preparing",
|
|
178
|
+
registryAttempt: (index, total) => `Registry ${index}/${total}; a timeout falls back to the next`,
|
|
179
|
+
slowHint: "A first install, or one that must verify dependencies, takes a while \u2014 the log shows what is happening.",
|
|
180
|
+
cancelRequested: "Cancellation requested",
|
|
181
|
+
stalled: "This step has produced no output for a long time; cancel it and retry.",
|
|
182
|
+
staleSnapshot: "status stopped updating \u2014 check for updates",
|
|
153
183
|
cancel: "Cancel",
|
|
154
184
|
cancelling: "Cancelling\u2026",
|
|
155
185
|
restart: "Restart DSH to finish.",
|
|
156
186
|
restartHint: "Saved changes take effect on the next start.",
|
|
187
|
+
reloadForAppearance: "The theme plugin was updated; reloading the page to restore its look (its settings are on disk and are not lost).",
|
|
157
188
|
done: "done",
|
|
158
189
|
failed: "failed",
|
|
159
190
|
failedSome: (n) => `${n} failed`,
|
|
160
191
|
jobDone: "Batch upgrade finished",
|
|
161
192
|
jobCancelled: "Cancelled",
|
|
162
193
|
busyAdopted: "A batch is already running; showing its progress instead.",
|
|
194
|
+
lostJob: "Lost contact with the upgrade (the host may have restarted). Check for updates to confirm the installed version.",
|
|
163
195
|
log: "Run log",
|
|
164
196
|
showLog: "Show log",
|
|
165
197
|
hideLog: "Hide log",
|
|
@@ -205,6 +237,16 @@ window.__ModuleLoader__.load({
|
|
|
205
237
|
window.open(url, "_blank", "noopener,noreferrer");
|
|
206
238
|
}
|
|
207
239
|
}
|
|
240
|
+
function formatElapsed(ms) {
|
|
241
|
+
if (!Number.isFinite(ms) || ms < 0) return "0s";
|
|
242
|
+
const total = Math.floor(ms / 1e3);
|
|
243
|
+
if (total < 60) return `${total}s`;
|
|
244
|
+
const minutes = Math.floor(total / 60);
|
|
245
|
+
const seconds = total % 60;
|
|
246
|
+
if (minutes < 60) return `${minutes}m ${String(seconds).padStart(2, "0")}s`;
|
|
247
|
+
const hours = Math.floor(minutes / 60);
|
|
248
|
+
return `${hours}h ${String(minutes % 60).padStart(2, "0")}m`;
|
|
249
|
+
}
|
|
208
250
|
function resolveVersionLink(row, version) {
|
|
209
251
|
const raw = typeof version.href === "string" ? version.href : typeof version.url === "string" && typeof row.repoUrl === "string" && version.url.startsWith("/") ? `${row.repoUrl}${version.url}` : version.url;
|
|
210
252
|
return typeof raw === "string" && /^https?:\/\//i.test(raw) ? raw : void 0;
|
|
@@ -335,6 +377,16 @@ window.__ModuleLoader__.load({
|
|
|
335
377
|
);
|
|
336
378
|
return alive;
|
|
337
379
|
}
|
|
380
|
+
var APPEARANCE_PATTERN = /(^|[/@-])(skin|theme|dream-skin|wallpaper|appearance)([/@.-]|$)/i;
|
|
381
|
+
function isAppearancePackage(name2) {
|
|
382
|
+
return APPEARANCE_PATTERN.test(name2);
|
|
383
|
+
}
|
|
384
|
+
function replacedAppearance(results) {
|
|
385
|
+
if (!Array.isArray(results)) return false;
|
|
386
|
+
return results.some(
|
|
387
|
+
(result) => result.ok === true && result.changed !== false && typeof result.name === "string" && isAppearancePackage(result.name)
|
|
388
|
+
);
|
|
389
|
+
}
|
|
338
390
|
|
|
339
391
|
// src/client/styles.ts
|
|
340
392
|
var STYLE_ID = "dsh-plugin-upgrader-style";
|
|
@@ -352,7 +404,7 @@ window.__ModuleLoader__.load({
|
|
|
352
404
|
.dsh-pu-btn { display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 12px; border-radius: 8px; font-size: 12px; font-weight: 500; cursor: pointer; border: 1px solid var(--dsw-alias-border-l1); background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); transition: background .15s ease, border-color .15s ease, opacity .15s ease; font-family: inherit; }
|
|
353
405
|
.dsh-pu-btn:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); border-color: var(--dsw-alias-border-l2); }
|
|
354
406
|
.dsh-pu-btn:disabled { opacity: .5; cursor: default; }
|
|
355
|
-
.dsh-pu-btn.is-primary { background: var(--dsw-alias-button-primary-fill); border-color: transparent; color: #fff; }
|
|
407
|
+
.dsh-pu-btn.is-primary { background: var(--dsw-alias-button-primary-fill); border-color: transparent; color: var(--dsw-alias-label-primary-inverted, #fff); }
|
|
356
408
|
.dsh-pu-btn.is-primary:hover:not(:disabled) { background: var(--dsw-alias-button-primary-hover); }
|
|
357
409
|
.dsh-pu-btn.is-ghost { background: transparent; border-color: transparent; color: var(--dsw-alias-label-secondary); padding: 0 8px; }
|
|
358
410
|
.dsh-pu-btn.is-ghost:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-primary); }
|
|
@@ -384,6 +436,8 @@ window.__ModuleLoader__.load({
|
|
|
384
436
|
.dsh-pu-name { font-size: 13px; font-weight: 600; display: flex; align-items: center; gap: 8px; min-width: 0; }
|
|
385
437
|
.dsh-pu-name span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
386
438
|
.dsh-pu-desc { font-size: 11px; color: var(--dsw-alias-label-tertiary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
439
|
+
.dsh-pu-note { font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
440
|
+
.dsh-pu-note.is-err { color: var(--dsw-alias-state-error-primary); }
|
|
387
441
|
.dsh-pu-mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 11px; color: var(--dsw-alias-label-secondary); }
|
|
388
442
|
.dsh-pu-tag { font-size: 10px; line-height: 1; padding: 3px 6px; border-radius: 999px; border: 1px solid var(--dsw-alias-border-l1); color: var(--dsw-alias-label-secondary); font-weight: 500; white-space: nowrap; }
|
|
389
443
|
.dsh-pu-tag.is-new { border-color: var(--dsw-alias-brand-primary); color: var(--dsw-alias-brand-primary); background: color-mix(in srgb, var(--dsw-alias-brand-primary) 14%, transparent); }
|
|
@@ -412,7 +466,10 @@ window.__ModuleLoader__.load({
|
|
|
412
466
|
.dsh-pu-job-head { display: flex; align-items: center; gap: 10px; font-size: 12px; }
|
|
413
467
|
.dsh-pu-job-head .dsh-pu-grow { flex: 1; min-width: 0; }
|
|
414
468
|
.dsh-pu-bar { height: 4px; border-radius: 999px; background: var(--dsw-alias-bg-layer-3); overflow: hidden; }
|
|
415
|
-
.dsh-pu-bar
|
|
469
|
+
.dsh-pu-bar-inner { height: 100%; border-radius: 999px; background: var(--dsw-alias-brand-primary); transition: width .25s ease; }
|
|
470
|
+
.dsh-pu-bar-inner.is-busy { width: 40%; transition: none; animation: dsh-pu-indeterminate 1.4s ease-in-out infinite; }
|
|
471
|
+
@keyframes dsh-pu-indeterminate { 0% { transform: translateX(-100%); } 100% { transform: translateX(250%); } }
|
|
472
|
+
.dsh-pu-hint { font-size: 11px; color: var(--dsw-alias-label-tertiary); }
|
|
416
473
|
.dsh-pu-log { max-height: 160px; overflow: auto; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 10.5px; line-height: 1.55; color: var(--dsw-alias-label-secondary); white-space: pre-wrap; word-break: break-word; border-top: 1px dashed var(--dsw-alias-border-l1); padding-top: 8px; margin: 0; }
|
|
417
474
|
.dsh-pu-banner { display: flex; align-items: center; gap: 8px; font-size: 11.5px; padding: 7px 10px; border-radius: 8px; border: 1px solid var(--dsw-alias-border-l1); background: var(--dsw-alias-bg-layer-2); color: var(--dsw-alias-label-secondary); }
|
|
418
475
|
.dsh-pu-banner.is-warn { border-color: var(--dsw-alias-state-warn-primary); color: var(--dsw-alias-state-warn-primary); }
|
|
@@ -420,10 +477,23 @@ window.__ModuleLoader__.load({
|
|
|
420
477
|
.dsh-pu-foot { display: flex; align-items: center; gap: 10px; font-size: 11px; color: var(--dsw-alias-label-tertiary); flex-wrap: wrap; }
|
|
421
478
|
.dsh-pu-spin { width: 12px; height: 12px; border-radius: 50%; border: 2px solid var(--dsw-alias-border-l2); border-top-color: var(--dsw-alias-brand-primary); animation: dsh-pu-spin .8s linear infinite; flex: none; }
|
|
422
479
|
@keyframes dsh-pu-spin { to { transform: rotate(360deg); } }
|
|
423
|
-
@media (prefers-reduced-motion: reduce) { .dsh-pu-spin { animation-duration: 2.4s; } }
|
|
480
|
+
@media (prefers-reduced-motion: reduce) { .dsh-pu-spin { animation-duration: 2.4s; } .dsh-pu-bar-inner.is-busy { animation-duration: 3s; } }
|
|
424
481
|
`;
|
|
425
482
|
|
|
426
483
|
// src/client/components/JobPanel.ts
|
|
484
|
+
var CLOCK_MS = 1e3;
|
|
485
|
+
var STALE_SNAPSHOT_MS = 20 * 1e3;
|
|
486
|
+
function useNow(running, from) {
|
|
487
|
+
const React = getReact();
|
|
488
|
+
const [now, setNow] = React.useState(() => Date.now());
|
|
489
|
+
React.useEffect(() => {
|
|
490
|
+
if (!running || from === void 0) return void 0;
|
|
491
|
+
setNow(Date.now());
|
|
492
|
+
const timer = setInterval(() => setNow(Date.now()), CLOCK_MS);
|
|
493
|
+
return () => clearInterval(timer);
|
|
494
|
+
}, [running, from]);
|
|
495
|
+
return now;
|
|
496
|
+
}
|
|
427
497
|
function JobPanel(props) {
|
|
428
498
|
const h = getH();
|
|
429
499
|
const React = getReact();
|
|
@@ -434,6 +504,16 @@ window.__ModuleLoader__.load({
|
|
|
434
504
|
const percent = total === 0 ? 0 : Math.round(done / total * 100);
|
|
435
505
|
const running = job.status === "running" || job.status === "queued";
|
|
436
506
|
const failed = job.failed ?? 0;
|
|
507
|
+
const inStep = running && job.current !== void 0;
|
|
508
|
+
const now = useNow(inStep, job.stepStartedAt);
|
|
509
|
+
const stamp = `${job.id}|${job.stepStartedAt ?? ""}|${job.done ?? 0}|${job.status}`;
|
|
510
|
+
const lastChange = React.useRef({ stamp, at: Date.now() });
|
|
511
|
+
if (lastChange.current.stamp !== stamp) lastChange.current = { stamp, at: Date.now() };
|
|
512
|
+
const stale = inStep && Date.now() - lastChange.current.at > STALE_SNAPSHOT_MS;
|
|
513
|
+
const stepMs = job.stepStartedAt === void 0 ? 0 : Math.max(0, now - job.stepStartedAt);
|
|
514
|
+
const phaseKey = job.phase === "installing" ? "phaseInstalling" : job.phase === "applying" ? "phaseApplying" : job.phase === "cancelling" ? "phaseCancelling" : "phaseWaiting";
|
|
515
|
+
const phaseText = job.attempt !== void 0 && job.attempt.total > 1 ? t("registryAttempt", job.attempt.index, job.attempt.total) : t(phaseKey);
|
|
516
|
+
const headline = running ? t("progress", done, total) : job.status === "cancelled" ? t("jobCancelled") : t("jobDone");
|
|
437
517
|
return h(
|
|
438
518
|
"div",
|
|
439
519
|
{ className: "dsh-pu-job" },
|
|
@@ -444,8 +524,17 @@ window.__ModuleLoader__.load({
|
|
|
444
524
|
h(
|
|
445
525
|
"span",
|
|
446
526
|
{ className: "dsh-pu-grow" },
|
|
447
|
-
|
|
448
|
-
job.current === void 0 ? null : h("span", { className: "dsh-pu-mono" }, ` ${job.current}`)
|
|
527
|
+
headline,
|
|
528
|
+
job.current === void 0 ? null : h("span", { className: "dsh-pu-mono" }, ` ${job.current}`),
|
|
529
|
+
inStep ? h(
|
|
530
|
+
"span",
|
|
531
|
+
{ className: "dsh-pu-dim" },
|
|
532
|
+
` \xB7 ${phaseText} \xB7 ${t("elapsed", formatElapsed(stepMs))}`
|
|
533
|
+
) : null,
|
|
534
|
+
// Once the snapshot stops moving the clock is reporting a number nobody
|
|
535
|
+
// is updating, so say so instead of letting it climb.
|
|
536
|
+
stale ? h("span", { className: "dsh-pu-dim" }, ` \xB7 ${t("staleSnapshot")}`) : null,
|
|
537
|
+
job.abandoned === true ? h("span", { className: "dsh-pu-dim" }, ` \xB7 ${t("stalled")}`) : null
|
|
449
538
|
),
|
|
450
539
|
failed > 0 ? h("span", { className: "dsh-pu-tag is-err" }, t("failedSome", failed)) : null,
|
|
451
540
|
running ? h(
|
|
@@ -459,7 +548,12 @@ window.__ModuleLoader__.load({
|
|
|
459
548
|
showLog ? t("hideLog") : t("showLog")
|
|
460
549
|
)
|
|
461
550
|
),
|
|
462
|
-
h(
|
|
551
|
+
h(
|
|
552
|
+
"div",
|
|
553
|
+
{ className: "dsh-pu-bar" },
|
|
554
|
+
inStep ? h("div", { className: "dsh-pu-bar-inner is-busy" }) : h("div", { className: "dsh-pu-bar-inner", style: { width: `${percent}%` } })
|
|
555
|
+
),
|
|
556
|
+
inStep ? h("div", { className: "dsh-pu-hint" }, t("slowHint")) : null,
|
|
463
557
|
showLog && Array.isArray(job.log) ? h("pre", { className: "dsh-pu-log" }, job.log.join("\n")) : null
|
|
464
558
|
);
|
|
465
559
|
}
|
|
@@ -508,7 +602,13 @@ window.__ModuleLoader__.load({
|
|
|
508
602
|
disabled: busy || version.current === true,
|
|
509
603
|
onClick: () => onSwitch(row, version.version)
|
|
510
604
|
},
|
|
511
|
-
|
|
605
|
+
/*
|
|
606
|
+
* "Back to latest" is only meaningful when the row is not already on it.
|
|
607
|
+
* The label used to key on `version.version === row.latest` alone, so the
|
|
608
|
+
* version the user is running offered to switch to itself whenever the
|
|
609
|
+
* host had not marked it current.
|
|
610
|
+
*/
|
|
611
|
+
version.version === row.latest && version.current !== true ? t("back") : t("switchTo")
|
|
512
612
|
)
|
|
513
613
|
);
|
|
514
614
|
}
|
|
@@ -518,12 +618,17 @@ window.__ModuleLoader__.load({
|
|
|
518
618
|
const h = getH();
|
|
519
619
|
const React = getReact();
|
|
520
620
|
const { row, t, busy, picked, onToggle, onUpgrade, onSwitch, onApprove, onOpenPage } = props;
|
|
621
|
+
const { self, onInstallSelf } = props;
|
|
622
|
+
const { onRetryHistory } = props;
|
|
521
623
|
const [open, setOpen] = React.useState(false);
|
|
522
624
|
const versions = Array.isArray(row.versions) ? row.versions : [];
|
|
523
625
|
const hasHistory = versions.length > 0;
|
|
524
|
-
const
|
|
626
|
+
const selfUpdate = self === true && row.latest !== void 0 && row.latest !== row.version;
|
|
627
|
+
const selectable = row.upgradable === true && self !== true;
|
|
525
628
|
const status = row.error !== void 0 && row.error !== null ? "err" : row.upgradable ? "new" : "idle";
|
|
526
|
-
const
|
|
629
|
+
const failure = row.versionError !== void 0 && row.versionError !== "" ? row.versionError : void 0;
|
|
630
|
+
const retriable = failure !== void 0 && /unreachable|timeout|registry \d|github/i.test(failure);
|
|
631
|
+
const versionNote = failure === void 0 ? void 0 : failure === "not a profile-managed package" ? t("sourcePath") : failure;
|
|
527
632
|
const pendingBuilds = Array.isArray(row.pendingBuilds) ? row.pendingBuilds : [];
|
|
528
633
|
return h(
|
|
529
634
|
"div",
|
|
@@ -566,7 +671,22 @@ window.__ModuleLoader__.load({
|
|
|
566
671
|
"div",
|
|
567
672
|
{ className: "dsh-pu-desc" },
|
|
568
673
|
row.description !== void 0 && row.description !== "" ? row.description : versionNote ?? row.name
|
|
569
|
-
)
|
|
674
|
+
),
|
|
675
|
+
failure !== void 0 && retriable ? h(
|
|
676
|
+
"div",
|
|
677
|
+
{ className: "dsh-pu-note is-err", title: failure },
|
|
678
|
+
`${t("historyFailed")}: ${failure}`,
|
|
679
|
+
typeof onRetryHistory === "function" ? h(
|
|
680
|
+
"button",
|
|
681
|
+
{
|
|
682
|
+
type: "button",
|
|
683
|
+
className: "dsh-pu-btn is-ghost is-tiny",
|
|
684
|
+
disabled: busy,
|
|
685
|
+
onClick: onRetryHistory
|
|
686
|
+
},
|
|
687
|
+
t("retry")
|
|
688
|
+
) : null
|
|
689
|
+
) : null
|
|
570
690
|
),
|
|
571
691
|
h(
|
|
572
692
|
"div",
|
|
@@ -587,6 +707,16 @@ window.__ModuleLoader__.load({
|
|
|
587
707
|
onClick: () => onUpgrade(row)
|
|
588
708
|
},
|
|
589
709
|
t("upgrade")
|
|
710
|
+
) : selfUpdate && typeof onInstallSelf === "function" ? h(
|
|
711
|
+
"button",
|
|
712
|
+
{
|
|
713
|
+
type: "button",
|
|
714
|
+
className: "dsh-pu-btn is-primary is-tiny",
|
|
715
|
+
disabled: busy,
|
|
716
|
+
title: `${t("selfUpdateHint")} \u2192${row.latest}`,
|
|
717
|
+
onClick: () => onInstallSelf(row, row.latest)
|
|
718
|
+
},
|
|
719
|
+
t("selfUpdate")
|
|
590
720
|
) : null,
|
|
591
721
|
typeof row.repoUrl === "string" ? h(
|
|
592
722
|
"button",
|
|
@@ -654,6 +784,8 @@ window.__ModuleLoader__.load({
|
|
|
654
784
|
}
|
|
655
785
|
|
|
656
786
|
// src/client/components/Tab.ts
|
|
787
|
+
var SELF_NAME = "dsh-plugin-upgrader";
|
|
788
|
+
var APPEARANCE_RELOAD_DELAY_MS = 1200;
|
|
657
789
|
function Tab(props) {
|
|
658
790
|
const h = getH();
|
|
659
791
|
const React = getReact();
|
|
@@ -675,14 +807,27 @@ window.__ModuleLoader__.load({
|
|
|
675
807
|
setBusyName(void 0);
|
|
676
808
|
setCancelling(false);
|
|
677
809
|
reload(false);
|
|
810
|
+
if (settled === void 0) {
|
|
811
|
+
setJob(void 0);
|
|
812
|
+
setBanner({ tone: "warn", text: t("lostJob") });
|
|
813
|
+
return settled;
|
|
814
|
+
}
|
|
678
815
|
const failures = Array.isArray(settled?.results) ? settled.results.filter((result) => result.ok !== true) : [];
|
|
679
816
|
if (failures.length > 0) {
|
|
680
817
|
setBanner({
|
|
681
818
|
tone: "err",
|
|
682
|
-
text: failures.map((failure) =>
|
|
819
|
+
text: failures.map((failure) => {
|
|
820
|
+
const code = failure.message ?? "error";
|
|
821
|
+
return failure.detail === void 0 ? `${failure.name}: ${code}` : `${failure.name}: ${failure.detail} (${code})`;
|
|
822
|
+
}).join(" \xB7 ")
|
|
683
823
|
});
|
|
684
824
|
} else if (settled?.results?.some((result) => result.application === "restart-required") === true) {
|
|
685
825
|
setBanner({ tone: "warn", text: t("restart") });
|
|
826
|
+
} else if (replacedAppearance(settled?.results)) {
|
|
827
|
+
setBanner({ tone: "info", text: t("reloadForAppearance") });
|
|
828
|
+
window.setTimeout(() => {
|
|
829
|
+
window.location.reload();
|
|
830
|
+
}, APPEARANCE_RELOAD_DELAY_MS);
|
|
686
831
|
}
|
|
687
832
|
return settled;
|
|
688
833
|
},
|
|
@@ -703,31 +848,23 @@ window.__ModuleLoader__.load({
|
|
|
703
848
|
if (steps.length === 0) return;
|
|
704
849
|
setBanner(void 0);
|
|
705
850
|
setBusyName(label);
|
|
851
|
+
setJob({ id: "", status: "queued", total: steps.length, done: 0, failed: 0, log: [] });
|
|
706
852
|
const outcome = await submitJob(steps, watch);
|
|
707
853
|
if (!alive.current) return;
|
|
708
|
-
if (outcome.kind === "started") {
|
|
709
|
-
|
|
710
|
-
id: outcome.id,
|
|
711
|
-
status: "queued",
|
|
712
|
-
total: steps.length,
|
|
713
|
-
done: 0,
|
|
714
|
-
failed: 0,
|
|
715
|
-
log: []
|
|
716
|
-
});
|
|
717
|
-
return;
|
|
718
|
-
}
|
|
719
|
-
if (outcome.kind === "adopted") {
|
|
720
|
-
setBanner({ tone: "warn", text: t("busyAdopted") });
|
|
854
|
+
if (outcome.kind === "started" || outcome.kind === "adopted") {
|
|
855
|
+
if (outcome.kind === "adopted") setBanner({ tone: "warn", text: t("busyAdopted") });
|
|
721
856
|
return;
|
|
722
857
|
}
|
|
723
858
|
setBusyName(void 0);
|
|
859
|
+
setJob(void 0);
|
|
724
860
|
const failure = outcome.error;
|
|
725
861
|
setBanner({ tone: "err", text: failure instanceof Error ? failure.message : String(failure) });
|
|
726
862
|
},
|
|
727
863
|
[alive, t, watch]
|
|
728
864
|
);
|
|
729
865
|
const rows = Array.isArray(data?.bundles) ? data.bundles : [];
|
|
730
|
-
const
|
|
866
|
+
const batchable = (row) => row.upgradable === true && row.name !== SELF_NAME;
|
|
867
|
+
const upgradable = rows.filter(batchable);
|
|
731
868
|
const needle = query.trim().toLowerCase();
|
|
732
869
|
const filtered = needle === "" ? rows : rows.filter(
|
|
733
870
|
(row) => row.name.toLowerCase().includes(needle) || String(row.title ?? "").toLowerCase().includes(needle)
|
|
@@ -751,6 +888,18 @@ window.__ModuleLoader__.load({
|
|
|
751
888
|
const pendingBuilds = Array.isArray(row.pendingBuilds) ? row.pendingBuilds : [];
|
|
752
889
|
void run([stepOf(row, row.latest ?? row.version ?? "", "upgrade", pendingBuilds)], row.name);
|
|
753
890
|
};
|
|
891
|
+
const installSelf = React.useCallback(
|
|
892
|
+
(row, version) => {
|
|
893
|
+
const install = props.install;
|
|
894
|
+
if (typeof install !== "function") {
|
|
895
|
+
setBanner({ tone: "warn", text: t("selfUpdateUnavailable") });
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
setBanner(void 0);
|
|
899
|
+
install({ spec: `${row.name}@${version}`, title: row.title, version });
|
|
900
|
+
},
|
|
901
|
+
[props.install, t]
|
|
902
|
+
);
|
|
754
903
|
const upgradeAll = () => {
|
|
755
904
|
void run(
|
|
756
905
|
upgradable.map((row) => stepOf(row, row.latest ?? row.version ?? "", "upgrade")),
|
|
@@ -908,7 +1057,10 @@ window.__ModuleLoader__.load({
|
|
|
908
1057
|
onUpgrade: upgradeOne,
|
|
909
1058
|
onSwitch: switchOne,
|
|
910
1059
|
onApprove: approveAndRetry,
|
|
911
|
-
onOpenPage: typeof props.openPackage === "function" ? props.openPackage : void 0
|
|
1060
|
+
onOpenPage: typeof props.openPackage === "function" ? props.openPackage : void 0,
|
|
1061
|
+
self: row.name === SELF_NAME,
|
|
1062
|
+
onInstallSelf: installSelf,
|
|
1063
|
+
onRetryHistory: () => reload(true)
|
|
912
1064
|
})
|
|
913
1065
|
)
|
|
914
1066
|
),
|
package/lib/host/install.d.ts
CHANGED
|
@@ -10,6 +10,15 @@
|
|
|
10
10
|
import type { ChangeResult, PluginManager, StepRecord } from './manager.ts';
|
|
11
11
|
/** Progress sink for one job. */
|
|
12
12
|
export type LogSink = (message: string) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Called with the id of the installation currently in flight.
|
|
15
|
+
*
|
|
16
|
+
* `runStep` mints the id it hands the manager, and cancellation needs exactly
|
|
17
|
+
* that id: the manager answers `not-running` for anything else. Reporting it
|
|
18
|
+
* here lets the job record stay cancellable across the whole step, including
|
|
19
|
+
* the removal a version replacement starts with.
|
|
20
|
+
*/
|
|
21
|
+
export type RequestIdSink = (requestId: string) => void;
|
|
13
22
|
/** One step's outcome, including every failure stage. */
|
|
14
23
|
export interface StepOutcome {
|
|
15
24
|
name: string;
|
|
@@ -58,9 +67,10 @@ export declare function restoreEnabledState(manager: PluginManager, step: Pick<S
|
|
|
58
67
|
* @param manager - the plugin manager.
|
|
59
68
|
* @param step - the requested change.
|
|
60
69
|
* @param log - progress sink.
|
|
70
|
+
* @param announce - receives the request id the step installs under.
|
|
61
71
|
* @returns the outcome record.
|
|
62
72
|
*/
|
|
63
|
-
export declare function runStep(manager: PluginManager, step: StepRecord, log: LogSink): Promise<StepOutcome>;
|
|
73
|
+
export declare function runStep(manager: PluginManager, step: StepRecord, log: LogSink, announce?: RequestIdSink): Promise<StepOutcome>;
|
|
64
74
|
/**
|
|
65
75
|
* Whether a step names something this plugin is willing to install.
|
|
66
76
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/host/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/host/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAc,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEvF,iCAAiC;AACjC,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;AAE/C;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;AAEvD,yDAAyD;AACzD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,EAAE,EAAE,OAAO,CAAA;IACX,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,WAAW,CAAC,EAAE,YAAY,CAAC,aAAa,CAAC,CAAA;IACzC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAA;IACvC,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,aAAa,CAAC,EAAE;QACd,QAAQ,EAAE,MAAM,CAAA;QAChB,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,QAAQ,CAAC,EAAE,OAAO,CAAA;QAClB,IAAI,CAAC,EAAE,MAAM,CAAA;KACd,CAAA;CACF;AAED,gCAAgC;AAChC,eAAO,MAAM,OAAO,aAAyC,CAAA;AA6K7D;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,EAC9B,MAAM,EAAE,OAAO,GAAG,SAAS,EAC3B,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAuB9B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,OAAO,EACZ,QAAQ,CAAC,EAAE,aAAa,GACvB,OAAO,CAAC,WAAW,CAAC,CAgHtB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAM9D"}
|