@kdonev/termscape 0.1.9 → 0.2.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/README.md +111 -45
- package/dist/cli-args.d.ts +10 -0
- package/dist/cli-args.d.ts.map +1 -1
- package/dist/cli-args.js +2 -0
- package/dist/cli-args.js.map +1 -1
- package/dist/cli.js +15 -258
- package/dist/cli.js.map +1 -1
- package/dist/hub.d.ts +28 -1
- package/dist/hub.d.ts.map +1 -1
- package/dist/hub.js +65 -2
- package/dist/hub.js.map +1 -1
- package/dist/hub.tgz +0 -0
- package/dist/main.d.ts +7 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +343 -0
- package/dist/main.js.map +1 -0
- package/dist/protocol/domain.d.ts +35 -0
- package/dist/protocol/domain.d.ts.map +1 -1
- package/dist/protocol/domain.js +31 -2
- package/dist/protocol/domain.js.map +1 -1
- package/dist/protocol/index.d.ts +1 -0
- package/dist/protocol/index.d.ts.map +1 -1
- package/dist/protocol/index.js +1 -0
- package/dist/protocol/index.js.map +1 -1
- package/dist/protocol/mouse.d.ts +14 -0
- package/dist/protocol/mouse.d.ts.map +1 -1
- package/dist/protocol/mouse.js +16 -0
- package/dist/protocol/mouse.js.map +1 -1
- package/dist/protocol/peer.d.ts +23 -0
- package/dist/protocol/peer.d.ts.map +1 -1
- package/dist/protocol/peer.js +45 -1
- package/dist/protocol/peer.js.map +1 -1
- package/dist/protocol/version.d.ts +12 -0
- package/dist/protocol/version.d.ts.map +1 -0
- package/dist/protocol/version.js +37 -0
- package/dist/protocol/version.js.map +1 -0
- package/dist/protocol/ws.d.ts +103 -1
- package/dist/protocol/ws.d.ts.map +1 -1
- package/dist/protocol/ws.js +45 -1
- package/dist/protocol/ws.js.map +1 -1
- package/dist/remote/enroll.d.ts.map +1 -1
- package/dist/remote/enroll.js +22 -1
- package/dist/remote/enroll.js.map +1 -1
- package/dist/remote/join.d.ts.map +1 -1
- package/dist/remote/join.js +10 -1
- package/dist/remote/join.js.map +1 -1
- package/dist/remote/peer-serve.d.ts.map +1 -1
- package/dist/remote/peer-serve.js +23 -0
- package/dist/remote/peer-serve.js.map +1 -1
- package/dist/remote/peer.d.ts +7 -0
- package/dist/remote/peer.d.ts.map +1 -1
- package/dist/remote/peer.js +25 -1
- package/dist/remote/peer.js.map +1 -1
- package/dist/remote/registry.d.ts +24 -2
- package/dist/remote/registry.d.ts.map +1 -1
- package/dist/remote/registry.js +91 -5
- package/dist/remote/registry.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +76 -8
- package/dist/server.js.map +1 -1
- package/dist/session/manager.d.ts.map +1 -1
- package/dist/session/manager.js +7 -1
- package/dist/session/manager.js.map +1 -1
- package/dist/session/paste-image.d.ts +19 -0
- package/dist/session/paste-image.d.ts.map +1 -0
- package/dist/session/paste-image.js +65 -0
- package/dist/session/paste-image.js.map +1 -0
- package/dist/supervisor.d.ts +44 -0
- package/dist/supervisor.d.ts.map +1 -0
- package/dist/supervisor.js +125 -0
- package/dist/supervisor.js.map +1 -0
- package/dist/update/host.d.ts +19 -0
- package/dist/update/host.d.ts.map +1 -0
- package/dist/update/host.js +56 -0
- package/dist/update/host.js.map +1 -0
- package/dist/update/install.d.ts +38 -0
- package/dist/update/install.d.ts.map +1 -0
- package/dist/update/install.js +81 -0
- package/dist/update/install.js.map +1 -0
- package/dist/update/post-install.d.ts +2 -0
- package/dist/update/post-install.d.ts.map +1 -0
- package/dist/update/post-install.js +39 -0
- package/dist/update/post-install.js.map +1 -0
- package/dist/update/restart.d.ts +31 -0
- package/dist/update/restart.d.ts.map +1 -0
- package/dist/update/restart.js +65 -0
- package/dist/update/restart.js.map +1 -0
- package/dist/update/resume.d.ts +5 -0
- package/dist/update/resume.d.ts.map +1 -0
- package/dist/update/resume.js +47 -0
- package/dist/update/resume.js.map +1 -0
- package/dist/update/updater.d.ts +57 -0
- package/dist/update/updater.d.ts.map +1 -0
- package/dist/update/updater.js +190 -0
- package/dist/update/updater.js.map +1 -0
- package/dist/window/app-window.js +43 -1
- package/dist/window/app-window.js.map +1 -1
- package/package.json +1 -1
- package/web/assets/index-85NfOib0.js +111 -0
- package/web/assets/index-Czi_vAR-.css +1 -0
- package/web/index.html +2 -2
- package/web/assets/index-gfbbNQK4.css +0 -1
- package/web/assets/index-i7fXLKF0.js +0 -111
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resume.d.ts","sourceRoot":"","sources":["../../src/update/resume.ts"],"names":[],"mappings":"AAwBA,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,GAAG,SAAa,GAAG,IAAI,CAG3E;AAED,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,GAAG,SAAa,GAAG,MAAM,EAAE,CAkBzD"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { paths } from '../paths.js';
|
|
4
|
+
/**
|
|
5
|
+
* Which agents were running when a hub went down to be updated, so the hub
|
|
6
|
+
* that replaces it can bring exactly those back.
|
|
7
|
+
*
|
|
8
|
+
* Only an update writes this. Stopping a hub by hand is a decision about the
|
|
9
|
+
* agents too, and those come back stopped, as they always have.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* An update that never finished - an installer that failed, a machine that
|
|
13
|
+
* went to sleep halfway - must not resume agents at some unrelated start
|
|
14
|
+
* days later.
|
|
15
|
+
*/
|
|
16
|
+
const MAX_AGE_MS = 30 * 60_000;
|
|
17
|
+
export function resumeFile() {
|
|
18
|
+
return join(paths.home(), 'resume.json');
|
|
19
|
+
}
|
|
20
|
+
export function saveResumeList(sessionIds, now = Date.now()) {
|
|
21
|
+
const list = { at: now, sessionIds };
|
|
22
|
+
writeFileSync(resumeFile(), JSON.stringify(list));
|
|
23
|
+
}
|
|
24
|
+
/** Read and remove the list, so it is acted on once. Empty when stale or absent. */
|
|
25
|
+
export function takeResumeList(now = Date.now()) {
|
|
26
|
+
const file = resumeFile();
|
|
27
|
+
let raw;
|
|
28
|
+
try {
|
|
29
|
+
raw = readFileSync(file, 'utf8');
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
rmSync(file, { force: true });
|
|
35
|
+
try {
|
|
36
|
+
const list = JSON.parse(raw);
|
|
37
|
+
if (typeof list.at !== 'number' || now - list.at > MAX_AGE_MS)
|
|
38
|
+
return [];
|
|
39
|
+
return Array.isArray(list.sessionIds)
|
|
40
|
+
? list.sessionIds.filter((id) => typeof id === 'string')
|
|
41
|
+
: [];
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=resume.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resume.js","sourceRoot":"","sources":["../../src/update/resume.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC;;;;;;GAMG;AAEH;;;;GAIG;AACH,MAAM,UAAU,GAAG,EAAE,GAAG,MAAM,CAAC;AAO/B,MAAM,UAAU,UAAU;IACxB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,aAAa,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,UAAoB,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IACnE,MAAM,IAAI,GAAe,EAAE,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;IACjD,aAAa,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,cAAc,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IAC7C,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;IAC1B,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAwB,CAAC;QACpD,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,IAAI,GAAG,GAAG,IAAI,CAAC,EAAE,GAAG,UAAU;YAAE,OAAO,EAAE,CAAC;QACzE,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;YACnC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,EAAgB,EAAE,CAAC,OAAO,EAAE,KAAK,QAAQ,CAAC;YACtE,CAAC,CAAC,EAAE,CAAC;IACT,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import { type InstallKind, type UpdateInfo } from '../protocol/index.js';
|
|
3
|
+
import type { RestartPlan } from './restart.js';
|
|
4
|
+
export interface UpdaterOptions {
|
|
5
|
+
currentVersion: string;
|
|
6
|
+
kind: InstallKind;
|
|
7
|
+
/** Whether a supervisor is there to start the new version. */
|
|
8
|
+
canRestart: boolean;
|
|
9
|
+
/** This hub's own cli.js, which a global update leaves where it is. */
|
|
10
|
+
cliPath: string;
|
|
11
|
+
/** The command line the next hub should get. Read at restart, not before. */
|
|
12
|
+
restartArgs: () => string[];
|
|
13
|
+
/** Hand the plan to whoever owns the process, and exit into it. */
|
|
14
|
+
restart: (plan: RestartPlan) => void;
|
|
15
|
+
/** A failure the previous hub hit on its way out, reported by this one. */
|
|
16
|
+
initialError?: string | null;
|
|
17
|
+
/** Tests stand in for npm and the registry. */
|
|
18
|
+
fetchLatest?: () => Promise<string>;
|
|
19
|
+
prepare?: (kind: InstallKind, version: string) => Promise<RestartPlan>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Whether a newer termscape is out, and installing it on request.
|
|
23
|
+
*
|
|
24
|
+
* Checking is automatic and silent: a machine with no network, or a registry
|
|
25
|
+
* having a bad minute, costs nothing but a button that does not appear. What
|
|
26
|
+
* is never automatic is the restart. That takes every agent on this machine
|
|
27
|
+
* down with it, so it waits for someone to press the button.
|
|
28
|
+
*/
|
|
29
|
+
export declare class Updater extends EventEmitter {
|
|
30
|
+
private readonly opts;
|
|
31
|
+
private latest;
|
|
32
|
+
private state;
|
|
33
|
+
private error;
|
|
34
|
+
private timer;
|
|
35
|
+
constructor(opts: UpdaterOptions);
|
|
36
|
+
info(): UpdateInfo;
|
|
37
|
+
start(): void;
|
|
38
|
+
stop(): void;
|
|
39
|
+
check(): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Fetch the new release while this hub keeps running, then hand over.
|
|
42
|
+
* Throws - into the ack of whoever pressed the button - for anything that
|
|
43
|
+
* stops short of the restart.
|
|
44
|
+
*/
|
|
45
|
+
apply(): Promise<void>;
|
|
46
|
+
private prepare;
|
|
47
|
+
private changed;
|
|
48
|
+
}
|
|
49
|
+
/** The newest release on the registry. */
|
|
50
|
+
export declare function fetchLatest(): Promise<string>;
|
|
51
|
+
/**
|
|
52
|
+
* Where a package fetched by `npm exec` lives, read off the PATH npm built
|
|
53
|
+
* for the command it ran: npm puts the package's own .bin on it, inside the
|
|
54
|
+
* npx cache. Null when no entry there holds this version.
|
|
55
|
+
*/
|
|
56
|
+
export declare function findNpxCli(pathVar: string, version: string): string | null;
|
|
57
|
+
//# sourceMappingURL=updater.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"updater.d.ts","sourceRoot":"","sources":["../../src/update/updater.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,EAAW,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAQhD,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,WAAW,CAAC;IAClB,8DAA8D;IAC9D,UAAU,EAAE,OAAO,CAAC;IACpB,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,WAAW,EAAE,MAAM,MAAM,EAAE,CAAC;IAC5B,mEAAmE;IACnE,OAAO,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACrC,2EAA2E;IAC3E,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;CACxE;AAED;;;;;;;GAOG;AACH,qBAAa,OAAQ,SAAQ,YAAY;IAM3B,OAAO,CAAC,QAAQ,CAAC,IAAI;IALjC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,KAAK,CAA+B;gBAEf,IAAI,EAAE,cAAc;IAMjD,IAAI,IAAI,UAAU;IAUlB,KAAK,IAAI,IAAI;IAWb,IAAI,IAAI,IAAI;IAKN,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAY5B;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAoCd,OAAO;IAgBrB,OAAO,CAAC,OAAO;CAGhB;AAED,0CAA0C;AAC1C,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAUnD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgB1E"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { delimiter, dirname, join } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { isNewer } from '../protocol/index.js';
|
|
6
|
+
import { debug } from '../debug.js';
|
|
7
|
+
import { PACKAGE_NAME, runNpm } from './install.js';
|
|
8
|
+
/** The first look waits for the hub to settle; the rest are far apart. */
|
|
9
|
+
const FIRST_CHECK_MS = 10_000;
|
|
10
|
+
const CHECK_EVERY_MS = 6 * 60 * 60_000;
|
|
11
|
+
const DEFAULT_REGISTRY = 'https://registry.npmjs.org';
|
|
12
|
+
/**
|
|
13
|
+
* Whether a newer termscape is out, and installing it on request.
|
|
14
|
+
*
|
|
15
|
+
* Checking is automatic and silent: a machine with no network, or a registry
|
|
16
|
+
* having a bad minute, costs nothing but a button that does not appear. What
|
|
17
|
+
* is never automatic is the restart. That takes every agent on this machine
|
|
18
|
+
* down with it, so it waits for someone to press the button.
|
|
19
|
+
*/
|
|
20
|
+
export class Updater extends EventEmitter {
|
|
21
|
+
opts;
|
|
22
|
+
latest = null;
|
|
23
|
+
state;
|
|
24
|
+
error;
|
|
25
|
+
timer = null;
|
|
26
|
+
constructor(opts) {
|
|
27
|
+
super();
|
|
28
|
+
this.opts = opts;
|
|
29
|
+
this.error = opts.initialError ?? null;
|
|
30
|
+
this.state = this.error ? 'failed' : 'idle';
|
|
31
|
+
}
|
|
32
|
+
info() {
|
|
33
|
+
return {
|
|
34
|
+
latest: this.latest,
|
|
35
|
+
kind: this.opts.kind,
|
|
36
|
+
canRestart: this.opts.canRestart,
|
|
37
|
+
state: this.state,
|
|
38
|
+
error: this.error,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
start() {
|
|
42
|
+
if (this.timer)
|
|
43
|
+
return;
|
|
44
|
+
const tick = () => {
|
|
45
|
+
void this.check();
|
|
46
|
+
this.timer = setTimeout(tick, CHECK_EVERY_MS);
|
|
47
|
+
this.timer.unref();
|
|
48
|
+
};
|
|
49
|
+
this.timer = setTimeout(tick, FIRST_CHECK_MS);
|
|
50
|
+
this.timer.unref();
|
|
51
|
+
}
|
|
52
|
+
stop() {
|
|
53
|
+
if (this.timer)
|
|
54
|
+
clearTimeout(this.timer);
|
|
55
|
+
this.timer = null;
|
|
56
|
+
}
|
|
57
|
+
async check() {
|
|
58
|
+
try {
|
|
59
|
+
const latest = await (this.opts.fetchLatest ?? fetchLatest)();
|
|
60
|
+
if (latest === this.latest)
|
|
61
|
+
return;
|
|
62
|
+
this.latest = latest;
|
|
63
|
+
debug('update', `latest ${latest}, running ${this.opts.currentVersion}`);
|
|
64
|
+
this.changed();
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
debug('update', `check failed: ${err.message}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Fetch the new release while this hub keeps running, then hand over.
|
|
72
|
+
* Throws - into the ack of whoever pressed the button - for anything that
|
|
73
|
+
* stops short of the restart.
|
|
74
|
+
*/
|
|
75
|
+
async apply() {
|
|
76
|
+
const { kind, canRestart, currentVersion } = this.opts;
|
|
77
|
+
const target = this.latest;
|
|
78
|
+
if (target === null || !isNewer(target, currentVersion)) {
|
|
79
|
+
throw new Error('already up to date');
|
|
80
|
+
}
|
|
81
|
+
if (kind !== 'npx' && kind !== 'global') {
|
|
82
|
+
throw new Error('this hub was not installed from npm; update it the way it was installed');
|
|
83
|
+
}
|
|
84
|
+
if (!canRestart) {
|
|
85
|
+
throw new Error('this hub cannot restart itself; stop it and start termscape again once to enable updates');
|
|
86
|
+
}
|
|
87
|
+
if (this.state === 'downloading' || this.state === 'restarting') {
|
|
88
|
+
throw new Error('an update is already under way');
|
|
89
|
+
}
|
|
90
|
+
this.state = 'downloading';
|
|
91
|
+
this.error = null;
|
|
92
|
+
this.changed();
|
|
93
|
+
let plan;
|
|
94
|
+
try {
|
|
95
|
+
plan = await (this.opts.prepare ?? ((k, v) => this.prepare(k, v)))(kind, target);
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
this.state = 'failed';
|
|
99
|
+
this.error = err.message;
|
|
100
|
+
this.changed();
|
|
101
|
+
throw err;
|
|
102
|
+
}
|
|
103
|
+
this.state = 'restarting';
|
|
104
|
+
this.changed();
|
|
105
|
+
// A moment for the ack and the broadcast to leave before the sockets go.
|
|
106
|
+
setTimeout(() => this.opts.restart(plan), 300);
|
|
107
|
+
}
|
|
108
|
+
async prepare(kind, version) {
|
|
109
|
+
const args = this.opts.restartArgs();
|
|
110
|
+
if (kind === 'npx') {
|
|
111
|
+
const cli = await fetchIntoNpxCache(version);
|
|
112
|
+
return { command: process.execPath, args: [cli, ...args] };
|
|
113
|
+
}
|
|
114
|
+
// A global install replaces files this hub holds open, which Windows
|
|
115
|
+
// refuses, so the install runs between this hub and the next one - from
|
|
116
|
+
// a script beside this file, started by the supervisor.
|
|
117
|
+
const script = join(dirname(fileURLToPath(import.meta.url)), 'post-install.js');
|
|
118
|
+
return {
|
|
119
|
+
command: process.execPath,
|
|
120
|
+
args: [script, version, this.opts.cliPath, ...args],
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
changed() {
|
|
124
|
+
this.emit('change', this.info());
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/** The newest release on the registry. */
|
|
128
|
+
export async function fetchLatest() {
|
|
129
|
+
const registry = (process.env.TERMSCAPE_UPDATE_REGISTRY ?? DEFAULT_REGISTRY).replace(/\/$/, '');
|
|
130
|
+
const res = await fetch(`${registry}/${PACKAGE_NAME}/latest`, {
|
|
131
|
+
headers: { accept: 'application/json' },
|
|
132
|
+
signal: AbortSignal.timeout(15_000),
|
|
133
|
+
});
|
|
134
|
+
if (!res.ok)
|
|
135
|
+
throw new Error(`registry answered ${res.status}`);
|
|
136
|
+
const body = (await res.json());
|
|
137
|
+
if (typeof body.version !== 'string')
|
|
138
|
+
throw new Error('registry sent no version');
|
|
139
|
+
return body.version;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Where a package fetched by `npm exec` lives, read off the PATH npm built
|
|
143
|
+
* for the command it ran: npm puts the package's own .bin on it, inside the
|
|
144
|
+
* npx cache. Null when no entry there holds this version.
|
|
145
|
+
*/
|
|
146
|
+
export function findNpxCli(pathVar, version) {
|
|
147
|
+
for (const entry of pathVar.split(delimiter)) {
|
|
148
|
+
if (!/[\\/]_npx[\\/]/.test(entry) || !/[\\/]\.bin[\\/]?$/.test(entry))
|
|
149
|
+
continue;
|
|
150
|
+
const pkgDir = join(entry, '..', ...PACKAGE_NAME.split('/'));
|
|
151
|
+
const cli = join(pkgDir, 'dist', 'cli.js');
|
|
152
|
+
if (!existsSync(cli))
|
|
153
|
+
continue;
|
|
154
|
+
try {
|
|
155
|
+
const manifest = JSON.parse(readFileSync(join(pkgDir, 'package.json'), 'utf8'));
|
|
156
|
+
if (manifest.version === version)
|
|
157
|
+
return cli;
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
// Not this one; keep looking.
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Put a release into npx's cache and return the path of its cli.js.
|
|
167
|
+
*
|
|
168
|
+
* `npm exec` is what `npx` is, so this lands exactly where a fresh
|
|
169
|
+
* `npx @kdonev/termscape@<v>` would have. The new hub is then started with
|
|
170
|
+
* plain `node`, not through npm, which would otherwise sit between the
|
|
171
|
+
* supervisor and the hub for the rest of the session.
|
|
172
|
+
*/
|
|
173
|
+
async function fetchIntoNpxCache(version) {
|
|
174
|
+
const out = await runNpm([
|
|
175
|
+
'exec',
|
|
176
|
+
'--yes',
|
|
177
|
+
`--package=${PACKAGE_NAME}@${version}`,
|
|
178
|
+
'--',
|
|
179
|
+
'node',
|
|
180
|
+
'-p',
|
|
181
|
+
'process.env.PATH',
|
|
182
|
+
]);
|
|
183
|
+
const lines = out.trim().split(/\r?\n/);
|
|
184
|
+
const cli = findNpxCli(lines[lines.length - 1] ?? '', version);
|
|
185
|
+
if (!cli) {
|
|
186
|
+
throw new Error(`npm fetched ${PACKAGE_NAME}@${version} but it is not in the npx cache`);
|
|
187
|
+
}
|
|
188
|
+
return cli;
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=updater.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"updater.js","sourceRoot":"","sources":["../../src/update/updater.ts"],"names":[],"mappings":"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"}
|
|
@@ -128,7 +128,49 @@ async function main() {
|
|
|
128
128
|
// Nothing has been shown yet, so a tab is still a fair substitute.
|
|
129
129
|
unavailable('cannot open a webview', err);
|
|
130
130
|
}
|
|
131
|
-
|
|
131
|
+
/*
|
|
132
|
+
* @webviewjs/webview does not run a native message loop: it pumps the
|
|
133
|
+
* platform's native events from a JS timer at this interval, 16ms by
|
|
134
|
+
* default. Measured, with a low-level Windows mouse hook correlated
|
|
135
|
+
* against the page's own clock: Ctrl+wheel events reached this process 17,
|
|
136
|
+
* 313, 1079, 2135, 3771 and 6180ms late across six gestures on WebView2,
|
|
137
|
+
* the delay growing gesture over gesture rather than settling between
|
|
138
|
+
* them; the browser's own event timestamp to the page's handler was 0-1ms
|
|
139
|
+
* every time, so nothing downstream of this process was at fault; and
|
|
140
|
+
* setting interval to 1 removes the delay entirely.
|
|
141
|
+
*
|
|
142
|
+
* The likely explanation - not an established one - is that pumpEvents()
|
|
143
|
+
* cannot keep the queue drained at 16ms under wheel input, and the backlog
|
|
144
|
+
* compounds rather than clearing between gestures. Upstream's own docs do
|
|
145
|
+
* not agree on this: getting-started/event-loop.md says pumpEvents()
|
|
146
|
+
* "drains the OS message queue" each call, while api/application.md calls
|
|
147
|
+
* it "one batch". The arithmetic does not cleanly support a one-message-
|
|
148
|
+
* per-tick ceiling either - at ~62/sec against a wheel that produced 64
|
|
149
|
+
* messages/sec, the ~1.5/sec surplus would take roughly 258 seconds of
|
|
150
|
+
* continuous wheeling to build a 6180ms backlog, not the well-under-two-
|
|
151
|
+
* seconds these six gestures actually spanned. Whatever the real mechanism
|
|
152
|
+
* turns out to be, interval 1 fixes the measured symptom.
|
|
153
|
+
*
|
|
154
|
+
* Scoped to Windows because that is where it was measured, not because the
|
|
155
|
+
* pump is Windows-specific: it is the same JS timer on WKWebView and
|
|
156
|
+
* WebKitGTK, so the same ceiling plausibly exists there too. Left at the
|
|
157
|
+
* default off Windows because nobody has measured it there, and a busy
|
|
158
|
+
* timer is not worth spending on a platform where no one has seen the
|
|
159
|
+
* symptom.
|
|
160
|
+
*
|
|
161
|
+
* ponytail: this is a busy timer, waking up a thousand times a second for
|
|
162
|
+
* a window that is usually idle, costing about 2.4% of a core on Windows
|
|
163
|
+
* measured over 30s idle (1.41% at 16ms, 3.80% at 1ms) - and, per the above,
|
|
164
|
+
* scoped to where the symptom was actually reproduced rather than to where
|
|
165
|
+
* the bug is known to be absent. Both upgrade paths are upstream's to give:
|
|
166
|
+
* a pumpEvents() that reports whether work remains, so this could back off
|
|
167
|
+
* instead of polling at a fixed rate regardless of load - nothing in the
|
|
168
|
+
* current API says whether the queue drained or the app merely stayed
|
|
169
|
+
* alive, `false` means the latter (app.run()'s own wrapper is `if
|
|
170
|
+
* (!pumpEvents()) stop()`) - or a real blocking message loop on its own
|
|
171
|
+
* thread.
|
|
172
|
+
*/
|
|
173
|
+
await app.whenReady(process.platform === 'win32' ? { interval: 1 } : {});
|
|
132
174
|
}
|
|
133
175
|
main().catch((err) => {
|
|
134
176
|
console.error('[app]', err);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-window.js","sourceRoot":"","sources":["../../src/window/app-window.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"app-window.js","sourceRoot":"","sources":["../../src/window/app-window.ts"],"names":[],"mappings":"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"}
|