om-memory-system 5.8.0 → 5.9.0
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/cli/web-command.js +1 -1
- package/dist/services/web-server.d.ts +1 -1
- package/dist/services/web-server.js +1 -1
- package/dist/services/web-update-runtime.d.ts +1 -1
- package/dist/services/web-update-runtime.js +2 -1
- package/dist/services/web-update.d.ts +8 -0
- package/dist/services/web-update.js +27 -0
- package/dist/web/assets/index-Bhk1P5Z7.js +170 -0
- package/dist/web/index.html +1 -1
- package/package.json +1 -1
- package/dist/web/assets/index-B94xLmhL.js +0 -170
package/dist/cli/web-command.js
CHANGED
|
@@ -156,7 +156,7 @@ export async function runWebCommand(args, options = {}, online, handover = {}, u
|
|
|
156
156
|
const { existsSync } = await import("node:fs");
|
|
157
157
|
// Every restart onto the new copy runs the launcher, the login item's included.
|
|
158
158
|
const canRestart = () => existsSync(launcherPath(ommsDir()));
|
|
159
|
-
server.setWebUpdate(startWebUpdate(() => powerAction("update"), canRestart));
|
|
159
|
+
server.setWebUpdate(startWebUpdate(() => powerAction("update"), canRestart, () => server.powerActionRunning));
|
|
160
160
|
// A newer `web install` asked this web app to give up the port.
|
|
161
161
|
server.setOnStepAside(async () => {
|
|
162
162
|
clearInterval(keeper);
|
|
@@ -43,7 +43,7 @@ export declare class WebServer {
|
|
|
43
43
|
private readonly startedAt;
|
|
44
44
|
private onPowerActionCallback;
|
|
45
45
|
private webUpdate;
|
|
46
|
-
|
|
46
|
+
powerActionRunning: boolean;
|
|
47
47
|
private stepAsideTimer;
|
|
48
48
|
private holdOffTimer;
|
|
49
49
|
private portsExhaustedNotified;
|
|
@@ -173,7 +173,7 @@ export class WebServer {
|
|
|
173
173
|
startedAt = Date.now();
|
|
174
174
|
onPowerActionCallback = null;
|
|
175
175
|
webUpdate = null;
|
|
176
|
-
powerActionRunning = false;
|
|
176
|
+
powerActionRunning = false; // public: the automatic update stays quiet while one runs
|
|
177
177
|
stepAsideTimer = null;
|
|
178
178
|
holdOffTimer = null;
|
|
179
179
|
portsExhaustedNotified = false;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { WebUpdate, type InstallDeps } from "./web-update.js";
|
|
2
2
|
/** The npm check and installer of a standalone web app, with the real process, npm, and clock. */
|
|
3
|
-
export declare function startWebUpdate(restart: () => Promise<string | undefined>, canRestart: () => boolean): WebUpdate;
|
|
3
|
+
export declare function startWebUpdate(restart: () => Promise<string | undefined>, canRestart: () => boolean, autoBlocked?: () => boolean): WebUpdate;
|
|
4
4
|
/** The real npm process, shared by the update button and `web update`. */
|
|
5
5
|
export declare function nodeInstallDeps(): InstallDeps;
|
|
@@ -5,7 +5,7 @@ import { log } from "./logger.js";
|
|
|
5
5
|
import { packageVersion } from "./package-version.js";
|
|
6
6
|
import { WebUpdate } from "./web-update.js";
|
|
7
7
|
/** The npm check and installer of a standalone web app, with the real process, npm, and clock. */
|
|
8
|
-
export function startWebUpdate(restart, canRestart) {
|
|
8
|
+
export function startWebUpdate(restart, canRestart, autoBlocked) {
|
|
9
9
|
const update = new WebUpdate({
|
|
10
10
|
version: packageVersion(),
|
|
11
11
|
enabled: process.env.OMMS_DISABLE_UPDATE_CHECK !== "1",
|
|
@@ -18,6 +18,7 @@ export function startWebUpdate(restart, canRestart) {
|
|
|
18
18
|
globalVersion: () => globalCommandVersion({ find: () => null }).version,
|
|
19
19
|
restart,
|
|
20
20
|
canRestart,
|
|
21
|
+
autoBlocked,
|
|
21
22
|
now: () => Date.now(),
|
|
22
23
|
});
|
|
23
24
|
update.start();
|
|
@@ -4,6 +4,8 @@ export declare const UPDATE_CHECK_INTERVAL_MS: number;
|
|
|
4
4
|
export declare const STATUS_RECHECK_AFTER_MS: number;
|
|
5
5
|
/** An install that takes longer is stopped, and the web app keeps serving. */
|
|
6
6
|
export declare const INSTALL_TIMEOUT_MS: number;
|
|
7
|
+
/** An automatic start waits this long after a failed automatic install. */
|
|
8
|
+
export declare const AUTO_RETRY_AFTER_MS: number;
|
|
7
9
|
export type UpdateState = "idle" | "installing" | "restarting" | "failed";
|
|
8
10
|
/** The `update` field of `GET /api/web/status`. */
|
|
9
11
|
export interface UpdateStatus {
|
|
@@ -39,6 +41,8 @@ export interface WebUpdateDeps {
|
|
|
39
41
|
globalVersion: () => string | null;
|
|
40
42
|
/** False when no restart could serve the new copy, such as a missing launcher. Checked before npm runs. */
|
|
41
43
|
canRestart: () => boolean;
|
|
44
|
+
/** True while a Stop or Restart runs; the automatic start stays quiet then. */
|
|
45
|
+
autoBlocked?: () => boolean;
|
|
42
46
|
/** Stop npm and its children. On Windows the shell wrapper alone would leave npm running. */
|
|
43
47
|
killTree: (child: InstallChild) => Promise<void>;
|
|
44
48
|
/** Restart onto the newest copy. Returns a failure code when this web app keeps serving. */
|
|
@@ -68,12 +72,16 @@ export declare class WebUpdate {
|
|
|
68
72
|
private started;
|
|
69
73
|
private lastCheck;
|
|
70
74
|
private checking;
|
|
75
|
+
private autoRetryAt;
|
|
76
|
+
private autoAttempt;
|
|
71
77
|
constructor(deps: WebUpdateDeps);
|
|
72
78
|
/** Check now, then every 10 minutes. A second call does nothing. */
|
|
73
79
|
start(): void;
|
|
74
80
|
/** Read npm `latest`. A failed read keeps the last result. Calls during a read share it. */
|
|
75
81
|
check(): Promise<void>;
|
|
76
82
|
private read;
|
|
83
|
+
/** Start the install the Update button starts, once a check found a release. */
|
|
84
|
+
private maybeAutoInstall;
|
|
77
85
|
status(): UpdateStatus;
|
|
78
86
|
private canInstall;
|
|
79
87
|
/** Start the install and the restart. A request while one runs joins it. */
|
|
@@ -9,6 +9,8 @@ export const UPDATE_CHECK_INTERVAL_MS = 10 * 60 * 1000;
|
|
|
9
9
|
export const STATUS_RECHECK_AFTER_MS = 60 * 1000;
|
|
10
10
|
/** An install that takes longer is stopped, and the web app keeps serving. */
|
|
11
11
|
export const INSTALL_TIMEOUT_MS = 5 * 60 * 1000;
|
|
12
|
+
/** An automatic start waits this long after a failed automatic install. */
|
|
13
|
+
export const AUTO_RETRY_AFTER_MS = 30 * 60 * 1000;
|
|
12
14
|
/** Only a plain release reaches the npm arguments; the value comes from the registry. */
|
|
13
15
|
const PLAIN_VERSION = /^\d+\.\d+\.\d+$/;
|
|
14
16
|
/** Enough of npm's error stream to find a code; the rest is dropped. */
|
|
@@ -29,6 +31,8 @@ export class WebUpdate {
|
|
|
29
31
|
started = false;
|
|
30
32
|
lastCheck = -Infinity;
|
|
31
33
|
checking = null;
|
|
34
|
+
autoRetryAt = -Infinity;
|
|
35
|
+
autoAttempt = false;
|
|
32
36
|
constructor(deps) {
|
|
33
37
|
this.deps = deps;
|
|
34
38
|
}
|
|
@@ -55,6 +59,25 @@ export class WebUpdate {
|
|
|
55
59
|
return;
|
|
56
60
|
}
|
|
57
61
|
this.available = availableUpdate(this.deps.version, latest);
|
|
62
|
+
this.maybeAutoInstall();
|
|
63
|
+
}
|
|
64
|
+
/** Start the install the Update button starts, once a check found a release. */
|
|
65
|
+
maybeAutoInstall() {
|
|
66
|
+
if (this.state === "installing" || this.state === "restarting")
|
|
67
|
+
return;
|
|
68
|
+
if (!this.available)
|
|
69
|
+
return;
|
|
70
|
+
if (this.deps.now() < this.autoRetryAt)
|
|
71
|
+
return;
|
|
72
|
+
// A check can finish while a Stop or Restart runs; the manual route has the same gate.
|
|
73
|
+
if (this.deps.autoBlocked?.())
|
|
74
|
+
return;
|
|
75
|
+
if (!this.canInstall())
|
|
76
|
+
return;
|
|
77
|
+
if (this.requestInstall() !== "accepted")
|
|
78
|
+
return;
|
|
79
|
+
this.autoAttempt = true;
|
|
80
|
+
this.deps.log("Web app auto-update started", { from: this.deps.version, to: this.available });
|
|
58
81
|
}
|
|
59
82
|
status() {
|
|
60
83
|
// An open page polls the status, so a release shows within about a minute.
|
|
@@ -78,6 +101,7 @@ export class WebUpdate {
|
|
|
78
101
|
return "no-update";
|
|
79
102
|
if (!this.canInstall())
|
|
80
103
|
return "cannot-install";
|
|
104
|
+
this.autoAttempt = false;
|
|
81
105
|
this.state = "installing";
|
|
82
106
|
this.code = null;
|
|
83
107
|
void this.install(this.available);
|
|
@@ -96,6 +120,9 @@ export class WebUpdate {
|
|
|
96
120
|
const fail = (code, exitCode) => {
|
|
97
121
|
this.state = "failed";
|
|
98
122
|
this.code = code;
|
|
123
|
+
// Only an automatic start waits before trying again; the button always works.
|
|
124
|
+
if (this.autoAttempt)
|
|
125
|
+
this.autoRetryAt = this.deps.now() + AUTO_RETRY_AFTER_MS;
|
|
99
126
|
record("failed", code, exitCode);
|
|
100
127
|
};
|
|
101
128
|
const { code, exitCode } = await runGlobalInstall(this.deps, target);
|