@adecore/shell 0.49.3 → 0.49.4
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/updater.d.ts +1 -0
- package/dist/updater.js +69 -5
- package/package.json +1 -1
- package/src/updater.ts +89 -6
package/dist/updater.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export declare const createUpdater: (options: UpdaterOptions) => {
|
|
|
21
21
|
start: () => void;
|
|
22
22
|
configure: (autoDownload: unknown) => void;
|
|
23
23
|
check: () => Promise<void>;
|
|
24
|
+
setAllowPrerelease: (allow: boolean) => void;
|
|
24
25
|
download: () => Promise<void>;
|
|
25
26
|
install: () => boolean;
|
|
26
27
|
};
|
package/dist/updater.js
CHANGED
|
@@ -26,6 +26,10 @@ export const createUpdater = (options) => {
|
|
|
26
26
|
let updater = null;
|
|
27
27
|
let timer = null;
|
|
28
28
|
let installing = false;
|
|
29
|
+
let allowPrerelease = null;
|
|
30
|
+
// What stops the download a check offered, also one it started by itself.
|
|
31
|
+
let download = null;
|
|
32
|
+
let checkAgain = false;
|
|
29
33
|
const setState = (patch) => {
|
|
30
34
|
state = { ...state, ...patch };
|
|
31
35
|
options.publish(state);
|
|
@@ -36,6 +40,16 @@ export const createUpdater = (options) => {
|
|
|
36
40
|
options.onQuit?.(false);
|
|
37
41
|
}
|
|
38
42
|
};
|
|
43
|
+
const refused = (version) => allowPrerelease === false && version?.includes('-') === true;
|
|
44
|
+
/* A prerelease the person no longer follows: nothing may finish it or install it, also not a quit, which installs what is downloaded. */
|
|
45
|
+
const discard = () => {
|
|
46
|
+
download?.cancel();
|
|
47
|
+
download = null;
|
|
48
|
+
if (updater) {
|
|
49
|
+
updater.autoInstallOnAppQuit = false;
|
|
50
|
+
}
|
|
51
|
+
setState({ status: 'idle', version: undefined, percent: undefined, error: null, errorCode: null });
|
|
52
|
+
};
|
|
39
53
|
const check = async () => {
|
|
40
54
|
// Nothing to learn while a check or a download runs, or while a build waits to be installed.
|
|
41
55
|
if (!updater || state.status === 'checking' || state.status === 'downloading' || state.status === 'ready') {
|
|
@@ -43,12 +57,22 @@ export const createUpdater = (options) => {
|
|
|
43
57
|
}
|
|
44
58
|
options.beforeCheck?.();
|
|
45
59
|
try {
|
|
46
|
-
await updater.checkForUpdates();
|
|
60
|
+
const result = await updater.checkForUpdates();
|
|
61
|
+
download = result?.cancellationToken ?? null;
|
|
62
|
+
// The track changed under this check, and with autoDownload its download already runs.
|
|
63
|
+
if (refused(result?.updateInfo.version)) {
|
|
64
|
+
download?.cancel();
|
|
65
|
+
download = null;
|
|
66
|
+
}
|
|
47
67
|
}
|
|
48
68
|
catch (e) {
|
|
49
69
|
// checkForUpdates rejects as well as emitting `error`; the state is already set there.
|
|
50
70
|
log('Update check failed', e);
|
|
51
71
|
}
|
|
72
|
+
if (checkAgain) {
|
|
73
|
+
checkAgain = false;
|
|
74
|
+
await check();
|
|
75
|
+
}
|
|
52
76
|
};
|
|
53
77
|
return {
|
|
54
78
|
state: () => state,
|
|
@@ -60,11 +84,33 @@ export const createUpdater = (options) => {
|
|
|
60
84
|
const loaded = options.load();
|
|
61
85
|
// The page sends its preference before the first check, so nothing downloads for someone who turned it off.
|
|
62
86
|
loaded.autoDownload = false;
|
|
87
|
+
if (allowPrerelease !== null) {
|
|
88
|
+
loaded.allowPrerelease = allowPrerelease;
|
|
89
|
+
}
|
|
63
90
|
loaded.on('checking-for-update', () => setState({ status: 'checking', error: null, errorCode: null }));
|
|
64
|
-
loaded.on('update-available', (info) =>
|
|
91
|
+
loaded.on('update-available', (info) => {
|
|
92
|
+
if (refused(info.version)) {
|
|
93
|
+
discard();
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
setState({ status: 'available', version: info.version, error: null, errorCode: null });
|
|
97
|
+
});
|
|
65
98
|
loaded.on('update-not-available', () => setState({ status: 'current', version: undefined, error: null, errorCode: null }));
|
|
66
|
-
loaded.on('download-progress', (progress) =>
|
|
67
|
-
|
|
99
|
+
loaded.on('download-progress', (progress) => {
|
|
100
|
+
// What is left of a download `discard` stopped, which has no version to tell it by.
|
|
101
|
+
if (state.version !== undefined) {
|
|
102
|
+
setState({ status: 'downloading', percent: progress.percent });
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
loaded.on('update-downloaded', (info) => {
|
|
106
|
+
if (refused(info.version)) {
|
|
107
|
+
discard();
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
loaded.autoInstallOnAppQuit = true;
|
|
111
|
+
download = null;
|
|
112
|
+
setState({ status: 'ready', version: info.version, percent: 100 });
|
|
113
|
+
});
|
|
68
114
|
loaded.on('error', (e) => {
|
|
69
115
|
installFailed();
|
|
70
116
|
const { code, detail } = describeUpdateError(e.message);
|
|
@@ -87,12 +133,30 @@ export const createUpdater = (options) => {
|
|
|
87
133
|
timer ??= every(() => void check(), UPDATE_INTERVAL_MS);
|
|
88
134
|
},
|
|
89
135
|
check,
|
|
136
|
+
/*
|
|
137
|
+
* Which releases the updater offers. Without this call it follows the running version. Leaving
|
|
138
|
+
* prereleases also drops one that is offered, downloading or waiting to install; a check that runs
|
|
139
|
+
* under the old answer is asked again once it ends.
|
|
140
|
+
*/
|
|
141
|
+
setAllowPrerelease: (allow) => {
|
|
142
|
+
allowPrerelease = allow;
|
|
143
|
+
if (!updater) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
updater.allowPrerelease = allow;
|
|
147
|
+
if (refused(state.version)) {
|
|
148
|
+
discard();
|
|
149
|
+
}
|
|
150
|
+
else if (state.status === 'checking') {
|
|
151
|
+
checkAgain = true;
|
|
152
|
+
}
|
|
153
|
+
},
|
|
90
154
|
download: async () => {
|
|
91
155
|
if (!updater) {
|
|
92
156
|
return;
|
|
93
157
|
}
|
|
94
158
|
try {
|
|
95
|
-
await updater.downloadUpdate();
|
|
159
|
+
await updater.downloadUpdate(download ?? undefined);
|
|
96
160
|
}
|
|
97
161
|
catch (e) {
|
|
98
162
|
log('Update download failed', e);
|
package/package.json
CHANGED
package/src/updater.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AppUpdater } from 'electron-updater';
|
|
1
|
+
import type { AppUpdater, UpdateCheckResult } from 'electron-updater';
|
|
2
2
|
import type { UpdateErrorCode, UpdateState } from './bridge/update.ts';
|
|
3
3
|
|
|
4
4
|
/* Often enough that a release lands the same day, rarely enough to be invisible. */
|
|
@@ -55,6 +55,10 @@ export const createUpdater = (options: UpdaterOptions) => {
|
|
|
55
55
|
let updater: AppUpdater | null = null;
|
|
56
56
|
let timer: unknown = null;
|
|
57
57
|
let installing = false;
|
|
58
|
+
let allowPrerelease: boolean | null = null;
|
|
59
|
+
// What stops the download a check offered, also one it started by itself.
|
|
60
|
+
let download: UpdateCheckResult['cancellationToken'] | null = null;
|
|
61
|
+
let checkAgain = false;
|
|
58
62
|
|
|
59
63
|
const setState = (patch: Partial<UpdateState>): void => {
|
|
60
64
|
state = { ...state, ...patch };
|
|
@@ -68,6 +72,20 @@ export const createUpdater = (options: UpdaterOptions) => {
|
|
|
68
72
|
}
|
|
69
73
|
};
|
|
70
74
|
|
|
75
|
+
const refused = (version: string | undefined): boolean => allowPrerelease === false && version?.includes('-') === true;
|
|
76
|
+
|
|
77
|
+
/* A prerelease the person no longer follows: nothing may finish it or install it, also not a quit, which installs what is downloaded. */
|
|
78
|
+
const discard = (): void => {
|
|
79
|
+
download?.cancel();
|
|
80
|
+
download = null;
|
|
81
|
+
|
|
82
|
+
if (updater) {
|
|
83
|
+
updater.autoInstallOnAppQuit = false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
setState({ status: 'idle', version: undefined, percent: undefined, error: null, errorCode: null });
|
|
87
|
+
};
|
|
88
|
+
|
|
71
89
|
const check = async (): Promise<void> => {
|
|
72
90
|
// Nothing to learn while a check or a download runs, or while a build waits to be installed.
|
|
73
91
|
if (!updater || state.status === 'checking' || state.status === 'downloading' || state.status === 'ready') {
|
|
@@ -77,11 +95,23 @@ export const createUpdater = (options: UpdaterOptions) => {
|
|
|
77
95
|
options.beforeCheck?.();
|
|
78
96
|
|
|
79
97
|
try {
|
|
80
|
-
await updater.checkForUpdates();
|
|
98
|
+
const result = await updater.checkForUpdates();
|
|
99
|
+
download = result?.cancellationToken ?? null;
|
|
100
|
+
|
|
101
|
+
// The track changed under this check, and with autoDownload its download already runs.
|
|
102
|
+
if (refused(result?.updateInfo.version)) {
|
|
103
|
+
download?.cancel();
|
|
104
|
+
download = null;
|
|
105
|
+
}
|
|
81
106
|
} catch (e) {
|
|
82
107
|
// checkForUpdates rejects as well as emitting `error`; the state is already set there.
|
|
83
108
|
log('Update check failed', e);
|
|
84
109
|
}
|
|
110
|
+
|
|
111
|
+
if (checkAgain) {
|
|
112
|
+
checkAgain = false;
|
|
113
|
+
await check();
|
|
114
|
+
}
|
|
85
115
|
};
|
|
86
116
|
|
|
87
117
|
return {
|
|
@@ -96,11 +126,43 @@ export const createUpdater = (options: UpdaterOptions) => {
|
|
|
96
126
|
const loaded = options.load();
|
|
97
127
|
// The page sends its preference before the first check, so nothing downloads for someone who turned it off.
|
|
98
128
|
loaded.autoDownload = false;
|
|
129
|
+
|
|
130
|
+
if (allowPrerelease !== null) {
|
|
131
|
+
loaded.allowPrerelease = allowPrerelease;
|
|
132
|
+
}
|
|
133
|
+
|
|
99
134
|
loaded.on('checking-for-update', () => setState({ status: 'checking', error: null, errorCode: null }));
|
|
100
|
-
|
|
135
|
+
|
|
136
|
+
loaded.on('update-available', (info) => {
|
|
137
|
+
if (refused(info.version)) {
|
|
138
|
+
discard();
|
|
139
|
+
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
setState({ status: 'available', version: info.version, error: null, errorCode: null });
|
|
144
|
+
});
|
|
145
|
+
|
|
101
146
|
loaded.on('update-not-available', () => setState({ status: 'current', version: undefined, error: null, errorCode: null }));
|
|
102
|
-
|
|
103
|
-
loaded.on('
|
|
147
|
+
|
|
148
|
+
loaded.on('download-progress', (progress) => {
|
|
149
|
+
// What is left of a download `discard` stopped, which has no version to tell it by.
|
|
150
|
+
if (state.version !== undefined) {
|
|
151
|
+
setState({ status: 'downloading', percent: progress.percent });
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
loaded.on('update-downloaded', (info) => {
|
|
156
|
+
if (refused(info.version)) {
|
|
157
|
+
discard();
|
|
158
|
+
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
loaded.autoInstallOnAppQuit = true;
|
|
163
|
+
download = null;
|
|
164
|
+
setState({ status: 'ready', version: info.version, percent: 100 });
|
|
165
|
+
});
|
|
104
166
|
|
|
105
167
|
loaded.on('error', (e) => {
|
|
106
168
|
installFailed();
|
|
@@ -128,13 +190,34 @@ export const createUpdater = (options: UpdaterOptions) => {
|
|
|
128
190
|
|
|
129
191
|
check,
|
|
130
192
|
|
|
193
|
+
/*
|
|
194
|
+
* Which releases the updater offers. Without this call it follows the running version. Leaving
|
|
195
|
+
* prereleases also drops one that is offered, downloading or waiting to install; a check that runs
|
|
196
|
+
* under the old answer is asked again once it ends.
|
|
197
|
+
*/
|
|
198
|
+
setAllowPrerelease: (allow: boolean): void => {
|
|
199
|
+
allowPrerelease = allow;
|
|
200
|
+
|
|
201
|
+
if (!updater) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
updater.allowPrerelease = allow;
|
|
206
|
+
|
|
207
|
+
if (refused(state.version)) {
|
|
208
|
+
discard();
|
|
209
|
+
} else if (state.status === 'checking') {
|
|
210
|
+
checkAgain = true;
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
|
|
131
214
|
download: async (): Promise<void> => {
|
|
132
215
|
if (!updater) {
|
|
133
216
|
return;
|
|
134
217
|
}
|
|
135
218
|
|
|
136
219
|
try {
|
|
137
|
-
await updater.downloadUpdate();
|
|
220
|
+
await updater.downloadUpdate(download ?? undefined);
|
|
138
221
|
} catch (e) {
|
|
139
222
|
log('Update download failed', e);
|
|
140
223
|
}
|