dsh-zen-remote 2.3.11 → 2.4.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/CHANGELOG.md +39 -78
- package/README.md +94 -84
- package/README.zh-CN.md +90 -81
- package/bin/zen-remote.mjs +5 -0
- package/docs/interface.md +6 -6
- package/docs/remote-access.en.md +6 -4
- package/docs/remote-access.md +6 -4
- package/dsh-push.mjs +96 -10
- package/lib/adapters/dsh-better-sidebar/index.js +7 -3
- package/lib/adapters/dsh-better-sidebar/index.js.map +1 -1
- package/lib/admin-routes.js +10 -2
- package/lib/admin-routes.js.map +1 -1
- package/lib/cli/args.js +251 -0
- package/lib/cli/args.js.map +1 -0
- package/lib/cli/bootstrap.js +449 -0
- package/lib/cli/bootstrap.js.map +1 -0
- package/lib/cli/command-setup.js +484 -0
- package/lib/cli/command-setup.js.map +1 -0
- package/lib/cli/commands-client.js +359 -0
- package/lib/cli/commands-client.js.map +1 -0
- package/lib/cli/commands-host.js +1108 -0
- package/lib/cli/commands-host.js.map +1 -0
- package/lib/cli/commands-status.js +279 -0
- package/lib/cli/commands-status.js.map +1 -0
- package/lib/cli/config-writer.js +334 -0
- package/lib/cli/config-writer.js.map +1 -0
- package/lib/cli/context.js +10 -0
- package/lib/cli/context.js.map +1 -0
- package/lib/cli/i18n.js +620 -0
- package/lib/cli/i18n.js.map +1 -0
- package/lib/cli/ipc-client.js +160 -0
- package/lib/cli/ipc-client.js.map +1 -0
- package/lib/cli/ipc-server.js +464 -0
- package/lib/cli/ipc-server.js.map +1 -0
- package/lib/cli/main.js +245 -0
- package/lib/cli/main.js.map +1 -0
- package/lib/cli/qr-terminal.js +48 -0
- package/lib/cli/qr-terminal.js.map +1 -0
- package/lib/client-data/qr.js +286 -0
- package/lib/client-data/qr.js.map +1 -0
- package/lib/client-routes.js +308 -25
- package/lib/client-routes.js.map +1 -1
- package/lib/client.js +1013 -229
- package/lib/config.js +50 -12
- package/lib/config.js.map +1 -1
- package/lib/debug-report.js +28 -1
- package/lib/debug-report.js.map +1 -1
- package/lib/fetch-route-intercept.js +334 -26
- package/lib/fetch-route-intercept.js.map +1 -1
- package/lib/index.js +564 -363
- package/lib/index.js.map +1 -1
- package/lib/intercept.js +1833 -280
- package/lib/intercept.js.map +1 -1
- package/lib/lan-gate-server.cjs +36 -10
- package/lib/merge-streams.js +103 -11
- package/lib/merge-streams.js.map +1 -1
- package/lib/plugin-route-intercept.js +93 -63
- package/lib/plugin-route-intercept.js.map +1 -1
- package/lib/relay-access.js +8 -1
- package/lib/relay-access.js.map +1 -1
- package/lib/relay-client.js +133 -4
- package/lib/relay-client.js.map +1 -1
- package/lib/relay-pool.js +275 -0
- package/lib/relay-pool.js.map +1 -0
- package/lib/relay-server.js +269 -17
- package/lib/relay-server.js.map +1 -1
- package/lib/restart-fields.js +6 -4
- package/lib/restart-fields.js.map +1 -1
- package/lib/share-store.js +65 -27
- package/lib/share-store.js.map +1 -1
- package/lib/state-store.js +400 -0
- package/lib/state-store.js.map +1 -0
- package/lib/types/adapters/dsh-better-sidebar/index.d.ts +3 -2
- package/lib/types/adapters/dsh-better-sidebar/index.d.ts.map +1 -1
- package/lib/types/admin-routes.d.ts.map +1 -1
- package/lib/types/cli/args.d.ts +78 -0
- package/lib/types/cli/args.d.ts.map +1 -0
- package/lib/types/cli/bootstrap.d.ts +170 -0
- package/lib/types/cli/bootstrap.d.ts.map +1 -0
- package/lib/types/cli/command-setup.d.ts +72 -0
- package/lib/types/cli/command-setup.d.ts.map +1 -0
- package/lib/types/cli/commands-client.d.ts +36 -0
- package/lib/types/cli/commands-client.d.ts.map +1 -0
- package/lib/types/cli/commands-host.d.ts +82 -0
- package/lib/types/cli/commands-host.d.ts.map +1 -0
- package/lib/types/cli/commands-status.d.ts +46 -0
- package/lib/types/cli/commands-status.d.ts.map +1 -0
- package/lib/types/cli/config-writer.d.ts +92 -0
- package/lib/types/cli/config-writer.d.ts.map +1 -0
- package/lib/types/cli/context.d.ts +39 -0
- package/lib/types/cli/context.d.ts.map +1 -0
- package/lib/types/cli/i18n.d.ts +32 -0
- package/lib/types/cli/i18n.d.ts.map +1 -0
- package/lib/types/cli/ipc-client.d.ts +83 -0
- package/lib/types/cli/ipc-client.d.ts.map +1 -0
- package/lib/types/cli/ipc-server.d.ts +113 -0
- package/lib/types/cli/ipc-server.d.ts.map +1 -0
- package/lib/types/cli/main.d.ts +57 -0
- package/lib/types/cli/main.d.ts.map +1 -0
- package/lib/types/cli/qr-terminal.d.ts +17 -0
- package/lib/types/cli/qr-terminal.d.ts.map +1 -0
- package/lib/types/client/RemoteStatusIcon.d.ts.map +1 -1
- package/lib/types/client/current-session-report.d.ts +4 -0
- package/lib/types/client/current-session-report.d.ts.map +1 -1
- package/lib/types/client/effects/model-group-side.d.ts.map +1 -1
- package/lib/types/client/effects/remote-session.d.ts.map +1 -1
- package/lib/types/client/locales.d.ts +47 -3
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/settings/SettingsSection.d.ts.map +1 -1
- package/lib/types/client/settings/settings-css.d.ts +1 -1
- package/lib/types/client/settings/settings-css.d.ts.map +1 -1
- package/lib/types/client/styles/remote-session.css.d.ts +1 -1
- package/lib/types/client/styles/remote-session.css.d.ts.map +1 -1
- package/lib/types/client/wizard/GatewayWizard.d.ts.map +1 -1
- package/lib/types/client/wizard/cards/ProxyCard.d.ts.map +1 -1
- package/lib/types/client/wizard/wizard-css.d.ts +1 -1
- package/lib/types/client/wizard/wizard-css.d.ts.map +1 -1
- package/lib/types/client-data/model-group-side.d.ts +23 -2
- package/lib/types/client-data/model-group-side.d.ts.map +1 -1
- package/lib/types/client-data/remote-status.d.ts +47 -1
- package/lib/types/client-data/remote-status.d.ts.map +1 -1
- package/lib/types/client-data/settings-form.d.ts +85 -1
- package/lib/types/client-data/settings-form.d.ts.map +1 -1
- package/lib/types/client-data/wizard.d.ts +56 -1
- package/lib/types/client-data/wizard.d.ts.map +1 -1
- package/lib/types/client-routes.d.ts +25 -1
- package/lib/types/client-routes.d.ts.map +1 -1
- package/lib/types/config.d.ts +40 -14
- package/lib/types/config.d.ts.map +1 -1
- package/lib/types/debug-report.d.ts.map +1 -1
- package/lib/types/fetch-route-intercept.d.ts +66 -8
- package/lib/types/fetch-route-intercept.d.ts.map +1 -1
- package/lib/types/index.d.ts +9 -2
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/intercept.d.ts +72 -10
- package/lib/types/intercept.d.ts.map +1 -1
- package/lib/types/merge-streams.d.ts +79 -1
- package/lib/types/merge-streams.d.ts.map +1 -1
- package/lib/types/plugin-route-intercept.d.ts +25 -9
- package/lib/types/plugin-route-intercept.d.ts.map +1 -1
- package/lib/types/relay-access.d.ts +3 -1
- package/lib/types/relay-access.d.ts.map +1 -1
- package/lib/types/relay-client.d.ts +23 -2
- package/lib/types/relay-client.d.ts.map +1 -1
- package/lib/types/relay-pool.d.ts +148 -0
- package/lib/types/relay-pool.d.ts.map +1 -0
- package/lib/types/relay-server.d.ts +30 -3
- package/lib/types/relay-server.d.ts.map +1 -1
- package/lib/types/restart-fields.d.ts +5 -5
- package/lib/types/restart-fields.d.ts.map +1 -1
- package/lib/types/share-store.d.ts.map +1 -1
- package/lib/types/state-store.d.ts +179 -0
- package/lib/types/state-store.d.ts.map +1 -0
- package/lib/types/upload-limits.d.ts +15 -0
- package/lib/types/upload-limits.d.ts.map +1 -1
- package/lib/types/virtual-id.d.ts +21 -0
- package/lib/types/virtual-id.d.ts.map +1 -1
- package/lib/types/wizard/probe.d.ts.map +1 -1
- package/lib/types/wizard/proxy-snippets.d.ts +3 -0
- package/lib/types/wizard/proxy-snippets.d.ts.map +1 -1
- package/lib/types/wizard/routes.d.ts +1 -0
- package/lib/types/wizard/routes.d.ts.map +1 -1
- package/lib/types/wizard/status.d.ts +9 -0
- package/lib/types/wizard/status.d.ts.map +1 -1
- package/lib/types/wizard/verify.d.ts +3 -0
- package/lib/types/wizard/verify.d.ts.map +1 -1
- package/lib/upload-limits.js +15 -0
- package/lib/upload-limits.js.map +1 -1
- package/lib/virtual-id.js +60 -0
- package/lib/virtual-id.js.map +1 -1
- package/lib/wizard/probe.js +46 -1
- package/lib/wizard/probe.js.map +1 -1
- package/lib/wizard/proxy-snippets.js +14 -1
- package/lib/wizard/proxy-snippets.js.map +1 -1
- package/lib/wizard/routes.js +23 -4
- package/lib/wizard/routes.js.map +1 -1
- package/lib/wizard/status.js +21 -0
- package/lib/wizard/status.js.map +1 -1
- package/lib/wizard/verify.js +31 -8
- package/lib/wizard/verify.js.map +1 -1
- package/package.json +8 -4
- package/pwa/icons/badge-96.png +0 -0
- package/pwa/icons/badge.svg +1 -0
- package/pwa/manifest.json +2 -1
- package/pwa/sw.js +3 -1
- package/scripts/check-debug-report.mjs +41 -1
- package/scripts/check-settings-form.mjs +14 -3
- package/scripts/check-settings-view.mjs +247 -0
- package/scripts/check-wizard-ui.mjs +37 -0
- package/src/adapters/dsh-better-sidebar/index.ts +7 -3
- package/src/admin-routes.ts +10 -2
- package/src/cli/args.ts +289 -0
- package/src/cli/bootstrap.ts +569 -0
- package/src/cli/command-setup.ts +540 -0
- package/src/cli/commands-client.ts +369 -0
- package/src/cli/commands-host.ts +1127 -0
- package/src/cli/commands-status.ts +296 -0
- package/src/cli/config-writer.ts +354 -0
- package/src/cli/context.ts +38 -0
- package/src/cli/i18n.ts +645 -0
- package/src/cli/ipc-client.ts +216 -0
- package/src/cli/ipc-server.ts +531 -0
- package/src/cli/main.ts +285 -0
- package/src/cli/qr-terminal.ts +49 -0
- package/src/client/RemoteStatusIcon.tsx +4 -1
- package/src/client/current-session-report.ts +28 -4
- package/src/client/effects/model-group-side.ts +19 -5
- package/src/client/effects/remote-session.ts +26 -6
- package/src/client/locales.ts +96 -6
- package/src/client/settings/SettingsSection.tsx +287 -92
- package/src/client/settings/settings-css.ts +18 -0
- package/src/client/styles/remote-session.css.ts +15 -1
- package/src/client/wizard/GatewayWizard.tsx +470 -109
- package/src/client/wizard/cards/ProxyCard.tsx +2 -1
- package/src/client/wizard/wizard-css.ts +23 -0
- package/src/client-data/model-group-side.ts +37 -10
- package/src/client-data/remote-status.ts +112 -17
- package/src/client-data/settings-form.ts +164 -8
- package/src/client-data/wizard.ts +112 -2
- package/src/client-routes.ts +334 -26
- package/src/config.ts +62 -16
- package/src/debug-report.ts +27 -1
- package/src/fetch-route-intercept.ts +381 -32
- package/src/index.ts +566 -367
- package/src/intercept.ts +1866 -286
- package/src/merge-streams.ts +155 -10
- package/src/plugin-route-intercept.ts +120 -71
- package/src/relay-access.ts +14 -3
- package/src/relay-client.ts +163 -5
- package/src/relay-pool.ts +387 -0
- package/src/relay-server.ts +312 -16
- package/src/restart-fields.ts +6 -4
- package/src/share-store.ts +59 -26
- package/src/state-store.ts +428 -0
- package/src/upload-limits.ts +16 -0
- package/src/virtual-id.ts +57 -0
- package/src/wizard/probe.ts +54 -2
- package/src/wizard/proxy-snippets.ts +17 -2
- package/src/wizard/routes.ts +24 -5
- package/src/wizard/status.ts +28 -0
- package/src/wizard/verify.ts +33 -11
- package/AGENTS.md +0 -185
- package/docs/adr/0001-plugin-bridge-forwards-plugin-routes.md +0 -15
- package/docs/adr/0002-relay-emulates-websocket.md +0 -8
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n.js","sourceRoot":"","sources":["../../src/cli/i18n.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI-2 IPC client: the CLI half of the local control channel that
|
|
3
|
+
* `src/cli/ipc-server.ts` serves inside the DSH plugin process. Discovery
|
|
4
|
+
* walks the same candidate socket paths the server binds (or a single
|
|
5
|
+
* explicit `--socket` path), pings each existing one with a short 200ms
|
|
6
|
+
* budget, and sorts the answers into three buckets the command layer can
|
|
7
|
+
* speak about: LIVE instances whose `cliProtocolVersion` matches, sockets
|
|
8
|
+
* speaking a DIFFERENT protocol version (the upgrade-prompt case), and paths
|
|
9
|
+
* that refused us with EACCES / EPERM (the "DSH runs as another user, try
|
|
10
|
+
* `sudo -E`" case).
|
|
11
|
+
*
|
|
12
|
+
* The request helper is a thin http-over-Unix-socket (Windows: named pipe)
|
|
13
|
+
* round trip. Transport errors REJECT — a dead socket is a real failure the
|
|
14
|
+
* caller must see — while HTTP error statuses resolve normally: the IPC
|
|
15
|
+
* protocol answers every failure as JSON (`{ ok: false, error: … }`), so a
|
|
16
|
+
* 409 wrong-role or 409 env-shadowed is data, not an exception.
|
|
17
|
+
*/
|
|
18
|
+
import { request as httpRequest } from 'node:http';
|
|
19
|
+
import { statSync } from 'node:fs';
|
|
20
|
+
import { CLI_CONFIG_ROUTE, CLI_PING_ROUTE, CLI_PROTOCOL_VERSION, candidateSocketPaths } from './ipc-server.js';
|
|
21
|
+
import { CLIENT_DEBUG_REPORT_ROUTE, CLIENT_STATUS_ROUTE } from '../client-routes.js';
|
|
22
|
+
/** Discovery ping budget: finding out whether anything answers must stay
|
|
23
|
+
* fast — up to 8 candidates × 200ms is the worst case, and every absent
|
|
24
|
+
* path skips the probe entirely. */
|
|
25
|
+
const PING_TIMEOUT_MS = 200;
|
|
26
|
+
const DEFAULT_REQUEST_TIMEOUT_MS = 15_000;
|
|
27
|
+
const DEBUG_REPORT_TIMEOUT_MS = 30_000;
|
|
28
|
+
function errnoCode(error) {
|
|
29
|
+
if (!(error instanceof Error))
|
|
30
|
+
return undefined;
|
|
31
|
+
const code = error.code;
|
|
32
|
+
return typeof code === 'string' ? code : undefined;
|
|
33
|
+
}
|
|
34
|
+
function isDenied(error) {
|
|
35
|
+
const code = errnoCode(error);
|
|
36
|
+
return code === 'EACCES' || code === 'EPERM';
|
|
37
|
+
}
|
|
38
|
+
/** One http round trip over the socket. Rejects on transport errors; HTTP
|
|
39
|
+
* error statuses are answers, not failures. */
|
|
40
|
+
function ipcRequest(socketPath, method, route, body, timeoutMs) {
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
const payload = body === undefined ? undefined : JSON.stringify(body);
|
|
43
|
+
const headers = {};
|
|
44
|
+
if (payload !== undefined) {
|
|
45
|
+
headers['content-type'] = 'application/json';
|
|
46
|
+
headers['content-length'] = String(Buffer.byteLength(payload));
|
|
47
|
+
}
|
|
48
|
+
const req = httpRequest({ socketPath, method, path: route, headers, agent: false, timeout: timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS }, (res) => {
|
|
49
|
+
const chunks = [];
|
|
50
|
+
res.on('data', (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
|
|
51
|
+
res.on('end', () => resolve({ status: res.statusCode ?? 0, headers: res.headers, text: Buffer.concat(chunks).toString('utf8') }));
|
|
52
|
+
res.on('error', reject);
|
|
53
|
+
});
|
|
54
|
+
req.on('timeout', () => {
|
|
55
|
+
req.destroy();
|
|
56
|
+
reject(new Error(`IPC request timed out after ${timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS}ms: ${method} ${route}`));
|
|
57
|
+
});
|
|
58
|
+
req.on('error', reject);
|
|
59
|
+
if (payload !== undefined)
|
|
60
|
+
req.write(payload);
|
|
61
|
+
req.end();
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
async function probeCandidate(socketPath, probeEvenIfAbsent) {
|
|
65
|
+
let statDenied = false;
|
|
66
|
+
try {
|
|
67
|
+
statSync(socketPath);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
if (isDenied(error))
|
|
71
|
+
statDenied = true;
|
|
72
|
+
else if (!probeEvenIfAbsent)
|
|
73
|
+
return { kind: 'absent' };
|
|
74
|
+
// A missing explicit path is still probed below — the connect error tells
|
|
75
|
+
// the same story, and ENOENT is not a permission problem.
|
|
76
|
+
}
|
|
77
|
+
if (statDenied)
|
|
78
|
+
return { kind: 'denied' };
|
|
79
|
+
let answer;
|
|
80
|
+
try {
|
|
81
|
+
answer = await ipcRequest(socketPath, 'GET', CLI_PING_ROUTE, undefined, PING_TIMEOUT_MS);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
return isDenied(error) ? { kind: 'denied' } : { kind: 'dead' };
|
|
85
|
+
}
|
|
86
|
+
if (answer.status !== 200)
|
|
87
|
+
return { kind: 'dead' };
|
|
88
|
+
let parsed;
|
|
89
|
+
try {
|
|
90
|
+
parsed = JSON.parse(answer.text);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return { kind: 'dead' };
|
|
94
|
+
}
|
|
95
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
96
|
+
return { kind: 'dead' };
|
|
97
|
+
const body = parsed;
|
|
98
|
+
if (body.ok !== true)
|
|
99
|
+
return { kind: 'dead' };
|
|
100
|
+
const reported = typeof body.cliProtocolVersion === 'number' ? body.cliProtocolVersion : undefined;
|
|
101
|
+
if (reported !== CLI_PROTOCOL_VERSION)
|
|
102
|
+
return { kind: 'mismatch', reportedVersion: reported };
|
|
103
|
+
return { kind: 'live', ping: parsed };
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Walk the CLI socket candidates under `dshHome` (or only `explicitSocket`)
|
|
107
|
+
* and classify every answering socket. Absent candidates are skipped without
|
|
108
|
+
* a probe; a dead file that merely squats a candidate name simply answers
|
|
109
|
+
* nothing and lands nowhere.
|
|
110
|
+
*/
|
|
111
|
+
export async function discoverCliSockets(options) {
|
|
112
|
+
const paths = options.explicitSocket !== undefined
|
|
113
|
+
? [options.explicitSocket]
|
|
114
|
+
: candidateSocketPaths(options.dshHome, options.platform ?? process.platform);
|
|
115
|
+
const found = { live: [], versionMismatch: [], permissionDenied: [] };
|
|
116
|
+
for (const socketPath of paths) {
|
|
117
|
+
const verdict = await probeCandidate(socketPath, options.explicitSocket !== undefined);
|
|
118
|
+
if (verdict.kind === 'live')
|
|
119
|
+
found.live.push({ ...verdict.ping, socketPath });
|
|
120
|
+
else if (verdict.kind === 'mismatch')
|
|
121
|
+
found.versionMismatch.push({ socketPath, cliProtocolVersion: verdict.reportedVersion });
|
|
122
|
+
else if (verdict.kind === 'denied')
|
|
123
|
+
found.permissionDenied.push(socketPath);
|
|
124
|
+
}
|
|
125
|
+
return found;
|
|
126
|
+
}
|
|
127
|
+
function parseBody(text) {
|
|
128
|
+
try {
|
|
129
|
+
return JSON.parse(text);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return text;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* A client bound to one socket path. `request` is the generic escape hatch
|
|
137
|
+
* for routes added in later CLI phases; the named methods cover the routes
|
|
138
|
+
* this phase already drives.
|
|
139
|
+
*/
|
|
140
|
+
export function createCliIpcClient(socketPath) {
|
|
141
|
+
const request = async (method, path, body, timeoutMs) => {
|
|
142
|
+
const answer = await ipcRequest(socketPath, method, path, body, timeoutMs);
|
|
143
|
+
return { status: answer.status, body: parseBody(answer.text), headers: answer.headers };
|
|
144
|
+
};
|
|
145
|
+
return {
|
|
146
|
+
socketPath,
|
|
147
|
+
ping: async () => {
|
|
148
|
+
const result = await request('GET', CLI_PING_ROUTE, undefined, PING_TIMEOUT_MS);
|
|
149
|
+
return result.body;
|
|
150
|
+
},
|
|
151
|
+
getStatus: async () => (await request('GET', CLIENT_STATUS_ROUTE)).body,
|
|
152
|
+
getDebugReport: async () => (await request('GET', CLIENT_DEBUG_REPORT_ROUTE, undefined, DEBUG_REPORT_TIMEOUT_MS)).body,
|
|
153
|
+
writeConfig: async (input) => await request('POST', CLI_CONFIG_ROUTE, {
|
|
154
|
+
...(input.set === undefined ? {} : { set: input.set }),
|
|
155
|
+
...(input.unset === undefined ? {} : { unset: input.unset }),
|
|
156
|
+
}),
|
|
157
|
+
request,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=ipc-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipc-client.js","sourceRoot":"","sources":["../../src/cli/ipc-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CLI's local IPC control server (CLI-1): a small HTTP server over a
|
|
3
|
+
* 0600 Unix domain socket (`<dshHome>/zen-remote-cli.sock`, Windows: a named
|
|
4
|
+
* pipe), owned by the DSH plugin process. Every DSH `webServer` route sits
|
|
5
|
+
* behind signed-cookie auth, and the pieces the CLI must drive (the relay
|
|
6
|
+
* pool, the managed Caddy / cloudflared children, the wizard state) follow
|
|
7
|
+
* the plugin's single-in-process-owner discipline — so the CLI talks to THIS
|
|
8
|
+
* process over THIS socket instead of a second entry point. Same user, same
|
|
9
|
+
* machine: the 0600 socket IS the authentication.
|
|
10
|
+
*
|
|
11
|
+
* Lifecycle: the server is module-level (one per process, per dshHome). A
|
|
12
|
+
* plugin row reload — including the role flips `restart-watcher` triggers —
|
|
13
|
+
* re-acquires it and swaps the request DELEGATE in place; the underlying
|
|
14
|
+
* socket never unbinds, so a CLI session survives every reload. When the
|
|
15
|
+
* last owning row released it and a short grace period passes without a new
|
|
16
|
+
* acquire, the server closes and the socket file is removed (the grace
|
|
17
|
+
* covers the cordis dispose order, where the OLD row's disposer runs after
|
|
18
|
+
* the NEW row's apply — a plain refcount would tear down between them).
|
|
19
|
+
*
|
|
20
|
+
* The wiring side (src/index.ts) folds the acquire/release into the existing
|
|
21
|
+
* `'dsh-zen-remote: restart watcher'` effect on purpose: test/
|
|
22
|
+
* role-wiring.test.cjs pins the exact number of top-level `ctx.effect`
|
|
23
|
+
* registrations per role, so the IPC lifecycle may not add one.
|
|
24
|
+
*/
|
|
25
|
+
import { createServer, get } from 'node:http';
|
|
26
|
+
import { chmodSync, existsSync, unlinkSync } from 'node:fs';
|
|
27
|
+
import { join } from 'node:path';
|
|
28
|
+
import { connectsRole, servesRole } from '../config.js';
|
|
29
|
+
import { responseJson } from '../http.js';
|
|
30
|
+
import { ADMIN_ROUTE_PREFIX } from '../admin-routes.js';
|
|
31
|
+
import { CLIENT_ROUTE_PREFIX } from '../client-routes.js';
|
|
32
|
+
import { WIZARD_ROUTE_PREFIX } from '../wizard/routes.js';
|
|
33
|
+
/** The CLI protocol's major version. A client asking for a different one is
|
|
34
|
+
* talking to a build it cannot drive (SPEC: refuse and tell the user to
|
|
35
|
+
* upgrade the plugin). */
|
|
36
|
+
export const CLI_PROTOCOL_VERSION = 1;
|
|
37
|
+
/** The protocol handshake route. */
|
|
38
|
+
export const CLI_PING_ROUTE = '/_dsh/zen-remote/cli/ping';
|
|
39
|
+
/** The config-write route (POST `{set, unset}` → the anti-shadowing writer). */
|
|
40
|
+
export const CLI_CONFIG_ROUTE = '/_dsh/zen-remote/cli/config';
|
|
41
|
+
/** Socket file / pipe basename: `zen-remote-cli.sock`, `-2.sock`, … */
|
|
42
|
+
export const CLI_SOCKET_BASENAME = 'zen-remote-cli';
|
|
43
|
+
/** How long a fully-released IPC server waits for a re-acquire (the hot
|
|
44
|
+
* reload window: cordis runs the OLD row's disposer AFTER the new apply, so
|
|
45
|
+
* refcount 0 is momentary during every reload). Exported for tests. */
|
|
46
|
+
export const CLI_CLOSE_GRACE_MS = 250;
|
|
47
|
+
/** Inbound config body cap — the CLI writes a few fields at a time. */
|
|
48
|
+
const MAX_BODY_BYTES = 16 * 1024;
|
|
49
|
+
/** Socket paths the process still holds, for the exit-time cleanup. */
|
|
50
|
+
const boundSocketFiles = new Set();
|
|
51
|
+
let exitHookInstalled = false;
|
|
52
|
+
function ensureExitHook() {
|
|
53
|
+
if (exitHookInstalled)
|
|
54
|
+
return;
|
|
55
|
+
exitHookInstalled = true;
|
|
56
|
+
process.on('exit', () => {
|
|
57
|
+
for (const path of boundSocketFiles) {
|
|
58
|
+
try {
|
|
59
|
+
unlinkSync(path);
|
|
60
|
+
}
|
|
61
|
+
catch { /* already gone */ }
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The bind candidates, in backoff order: `<dshHome>/zen-remote-cli.sock`,
|
|
67
|
+
* then `-2.sock` … `-8.sock` (two DSH instances on one machine — a web
|
|
68
|
+
* profile and a headless one — each get their own channel). Windows has no
|
|
69
|
+
* filesystem sockets: named pipes under the package's pipe name
|
|
70
|
+
* `dsh-zen-remote-cli` with the same numbering.
|
|
71
|
+
*/
|
|
72
|
+
export function candidateSocketPaths(dshHome, platform = process.platform) {
|
|
73
|
+
const out = [];
|
|
74
|
+
for (let n = 1; n <= 8; n += 1) {
|
|
75
|
+
if (platform === 'win32') {
|
|
76
|
+
out.push(n === 1 ? `\\\\.\\pipe\\dsh-${CLI_SOCKET_BASENAME}` : `\\\\.\\pipe\\dsh-${CLI_SOCKET_BASENAME}-${n}`);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
out.push(join(dshHome, n === 1 ? `${CLI_SOCKET_BASENAME}.sock` : `${CLI_SOCKET_BASENAME}-${n}.sock`));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
/** Is something ANSWERING on this socket path? A stale file (a dead
|
|
85
|
+
* instance's leftover, or a plain file that merely squats the name) answers
|
|
86
|
+
* nothing and may be cleaned; a live DSH instance answers its ping and must
|
|
87
|
+
* be left alone. */
|
|
88
|
+
function probeAlive(socketPath) {
|
|
89
|
+
return new Promise((resolve) => {
|
|
90
|
+
let settled = false;
|
|
91
|
+
const done = (value) => {
|
|
92
|
+
if (settled)
|
|
93
|
+
return;
|
|
94
|
+
settled = true;
|
|
95
|
+
resolve(value);
|
|
96
|
+
};
|
|
97
|
+
const req = get({ socketPath, path: CLI_PING_ROUTE, timeout: 150 }, (res) => {
|
|
98
|
+
res.resume();
|
|
99
|
+
done(true);
|
|
100
|
+
});
|
|
101
|
+
req.on('timeout', () => {
|
|
102
|
+
req.destroy();
|
|
103
|
+
done(false);
|
|
104
|
+
});
|
|
105
|
+
req.on('error', () => done(false));
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
/** Read the whole body under the cap and demand one JSON object. Same
|
|
109
|
+
* contract as every route module's reader: empty body → `{}`, malformed or
|
|
110
|
+
* oversized → null. */
|
|
111
|
+
async function readJsonObject(req) {
|
|
112
|
+
const declared = req.headers['content-length'];
|
|
113
|
+
const expected = declared === undefined ? undefined : Number(declared);
|
|
114
|
+
if (expected !== undefined && Number.isSafeInteger(expected) && expected > MAX_BODY_BYTES)
|
|
115
|
+
return null;
|
|
116
|
+
const chunks = [];
|
|
117
|
+
let size = 0;
|
|
118
|
+
for await (const chunk of req) {
|
|
119
|
+
const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
120
|
+
size += bytes.length;
|
|
121
|
+
if (size > MAX_BODY_BYTES)
|
|
122
|
+
return null;
|
|
123
|
+
chunks.push(bytes);
|
|
124
|
+
}
|
|
125
|
+
const text = Buffer.concat(chunks).toString('utf8');
|
|
126
|
+
if (text.trim() === '')
|
|
127
|
+
return {};
|
|
128
|
+
try {
|
|
129
|
+
const parsed = JSON.parse(text);
|
|
130
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
131
|
+
return null;
|
|
132
|
+
return parsed;
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function plainObject(value) {
|
|
139
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
140
|
+
? value
|
|
141
|
+
: undefined;
|
|
142
|
+
}
|
|
143
|
+
function isErrnoCode(error, code) {
|
|
144
|
+
return error instanceof Error && 'code' in error && error.code === code;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Bind one CLI IPC server: walk the candidate paths, probing occupied files
|
|
148
|
+
* for a live owner (skip those), cleaning stale ones, and answering with the
|
|
149
|
+
* bound handle. Throws when every candidate is taken by a live instance.
|
|
150
|
+
*/
|
|
151
|
+
export async function createCliIpcServer(options) {
|
|
152
|
+
const platform = options.platform ?? process.platform;
|
|
153
|
+
const isWin = platform === 'win32';
|
|
154
|
+
let delegate = options.delegate;
|
|
155
|
+
let current;
|
|
156
|
+
let socketPath = '';
|
|
157
|
+
const routeListener = (req, res) => {
|
|
158
|
+
void handleCliRequest(req, res, () => delegate);
|
|
159
|
+
};
|
|
160
|
+
for (const candidate of candidateSocketPaths(options.dshHome, platform)) {
|
|
161
|
+
if (!isWin && existsSync(candidate)) {
|
|
162
|
+
if (await probeAlive(candidate))
|
|
163
|
+
continue;
|
|
164
|
+
try {
|
|
165
|
+
unlinkSync(candidate);
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
continue; // unwritable squatter — try the next name
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const server = createServer(routeListener);
|
|
172
|
+
try {
|
|
173
|
+
await new Promise((resolve, reject) => {
|
|
174
|
+
server.once('error', reject);
|
|
175
|
+
server.listen(candidate, () => resolve());
|
|
176
|
+
});
|
|
177
|
+
current = server;
|
|
178
|
+
socketPath = candidate;
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
// EADDRINUSE (another process won the race) or any other bind failure
|
|
183
|
+
// — the remaining candidates are the fallback, never a crash.
|
|
184
|
+
server.close();
|
|
185
|
+
if (!isErrnoCode(error, 'EADDRINUSE'))
|
|
186
|
+
void error;
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (current === undefined) {
|
|
191
|
+
throw new Error(`every ${CLI_SOCKET_BASENAME} candidate is occupied by a live instance (${options.dshHome})`);
|
|
192
|
+
}
|
|
193
|
+
if (!isWin) {
|
|
194
|
+
try {
|
|
195
|
+
chmodSync(socketPath, 0o600);
|
|
196
|
+
}
|
|
197
|
+
catch { /* exotic filesystems — the 0700 home is the outer wall */ }
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
// Named pipes carry no unlinkable file; nothing to register for exit.
|
|
201
|
+
}
|
|
202
|
+
if (!isWin) {
|
|
203
|
+
boundSocketFiles.add(socketPath);
|
|
204
|
+
ensureExitHook();
|
|
205
|
+
}
|
|
206
|
+
// The listen-phase `once('error')` is spent; later server-level errors
|
|
207
|
+
// (accept failures on a dying socket) must not crash the host process.
|
|
208
|
+
current.on('error', () => { });
|
|
209
|
+
// The listening handle must not hold the event loop open (the same
|
|
210
|
+
// discipline as the restart watcher's poll and the fetch-route fallback
|
|
211
|
+
// timer): the DSH host process stays alive on its own services anyway,
|
|
212
|
+
// and a composition whose everything-else has shut down should still be
|
|
213
|
+
// able to exit. The exit hook above still cleans the socket file.
|
|
214
|
+
if (typeof current.unref === 'function')
|
|
215
|
+
current.unref();
|
|
216
|
+
let closed = false;
|
|
217
|
+
return {
|
|
218
|
+
socketPath,
|
|
219
|
+
swapDelegate(next) {
|
|
220
|
+
delegate = next;
|
|
221
|
+
},
|
|
222
|
+
close() {
|
|
223
|
+
if (closed)
|
|
224
|
+
return Promise.resolve();
|
|
225
|
+
closed = true;
|
|
226
|
+
boundSocketFiles.delete(socketPath);
|
|
227
|
+
return new Promise((resolve) => {
|
|
228
|
+
const finish = () => {
|
|
229
|
+
if (!isWin) {
|
|
230
|
+
try {
|
|
231
|
+
unlinkSync(socketPath);
|
|
232
|
+
}
|
|
233
|
+
catch { /* the server's own close unlink usually got here first */ }
|
|
234
|
+
}
|
|
235
|
+
resolve();
|
|
236
|
+
};
|
|
237
|
+
current.close(() => finish());
|
|
238
|
+
if (typeof current.closeAllConnections === 'function')
|
|
239
|
+
current.closeAllConnections();
|
|
240
|
+
});
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
/** The per-request dispatch: version headers on EVERY answer first, then the
|
|
245
|
+
* two CLI routes, then the role-gated forwards into the row's handlers. */
|
|
246
|
+
async function handleCliRequest(req, res, getDelegate) {
|
|
247
|
+
try {
|
|
248
|
+
const delegate = getDelegate();
|
|
249
|
+
res.setHeader('x-zr-cli-version', String(CLI_PROTOCOL_VERSION));
|
|
250
|
+
res.setHeader('x-zr-plugin-version', delegate.pluginVersion());
|
|
251
|
+
const url = new URL(req.url ?? '/', 'http://dsh.internal');
|
|
252
|
+
const route = url.pathname;
|
|
253
|
+
const method = req.method ?? 'GET';
|
|
254
|
+
if (route === CLI_PING_ROUTE) {
|
|
255
|
+
if (method !== 'GET') {
|
|
256
|
+
res.setHeader('Allow', 'GET');
|
|
257
|
+
responseJson(res, 405, { ok: false, error: { code: 'method-not-allowed', message: 'Use GET' } });
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
const role = delegate.role();
|
|
261
|
+
const profileName = delegate.profileName();
|
|
262
|
+
responseJson(res, 200, {
|
|
263
|
+
ok: true,
|
|
264
|
+
cliProtocolVersion: CLI_PROTOCOL_VERSION,
|
|
265
|
+
pluginVersion: delegate.pluginVersion(),
|
|
266
|
+
pid: process.pid,
|
|
267
|
+
role,
|
|
268
|
+
serves: servesRole(role),
|
|
269
|
+
connects: connectsRole(role),
|
|
270
|
+
serverName: delegate.serverName(),
|
|
271
|
+
...(profileName === undefined ? {} : { profileName }),
|
|
272
|
+
});
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
if (route === CLI_CONFIG_ROUTE) {
|
|
276
|
+
if (method !== 'POST') {
|
|
277
|
+
res.setHeader('Allow', 'POST');
|
|
278
|
+
responseJson(res, 405, { ok: false, error: { code: 'method-not-allowed', message: 'Use POST' } });
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
const body = await readJsonObject(req);
|
|
282
|
+
if (body === null) {
|
|
283
|
+
responseJson(res, 400, { ok: false, error: { code: 'bad-request', message: 'The request body must be one JSON object' } });
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const set = body.set === undefined ? undefined : plainObject(body.set);
|
|
287
|
+
const rawUnset = body.unset === undefined ? undefined : body.unset;
|
|
288
|
+
const unset = Array.isArray(rawUnset) && rawUnset.every((item) => typeof item === 'string')
|
|
289
|
+
? rawUnset
|
|
290
|
+
: undefined;
|
|
291
|
+
if ((body.set !== undefined && set === undefined) || (body.unset !== undefined && unset === undefined)) {
|
|
292
|
+
responseJson(res, 400, { ok: false, error: { code: 'bad-request', message: '`set` must be an object and `unset` a string array' } });
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
let result;
|
|
296
|
+
try {
|
|
297
|
+
result = delegate.writeConfig({
|
|
298
|
+
...(set === undefined ? {} : { set }),
|
|
299
|
+
...(unset === undefined ? {} : { unset }),
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
catch (error) {
|
|
303
|
+
responseJson(res, 500, { ok: false, error: { code: 'internal', message: error instanceof Error ? error.message : String(error) } });
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
if (!result.ok) {
|
|
307
|
+
responseJson(res, 409, { ok: false, error: { code: result.code, field: result.field, envVar: result.envVar } });
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
responseJson(res, 200, { ok: true, values: result.values });
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
if (route === WIZARD_ROUTE_PREFIX || route.startsWith(`${WIZARD_ROUTE_PREFIX}/`)) {
|
|
314
|
+
await forwardIfRole(req, res, delegate, delegate.wizardHandler);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
if (route === ADMIN_ROUTE_PREFIX || route.startsWith(`${ADMIN_ROUTE_PREFIX}/`)) {
|
|
318
|
+
await forwardIfRole(req, res, delegate, delegate.adminHandler);
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
if (route === CLIENT_ROUTE_PREFIX || route.startsWith(`${CLIENT_ROUTE_PREFIX}/`)) {
|
|
322
|
+
// The pairing surfaces belong to a dialing role; remote-status and the
|
|
323
|
+
// debug report are every role's own (the host answers its empty
|
|
324
|
+
// conclusion). SPEC pins exactly this split.
|
|
325
|
+
const sub = route.slice(CLIENT_ROUTE_PREFIX.length) || '/';
|
|
326
|
+
const pairingOnly = new Set(['/status', '/claim', '/unpair', '/reconnect']);
|
|
327
|
+
const required = pairingOnly.has(sub) ? 'client' : undefined;
|
|
328
|
+
if (required !== undefined && !connectsRole(delegate.role())) {
|
|
329
|
+
wrongRole(res, delegate.role(), required);
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
if (delegate.clientHandler === undefined) {
|
|
333
|
+
responseJson(res, 503, { ok: false, error: { code: 'unavailable', message: 'no client handler in this row generation' } });
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
await delegate.clientHandler(req, res);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
responseJson(res, 404, { ok: false, error: { code: 'not-found', message: 'Unknown CLI route' } });
|
|
340
|
+
}
|
|
341
|
+
catch (error) {
|
|
342
|
+
// A malformed req.url (`new URL` throwing) or a broken delegate must
|
|
343
|
+
// never escape as an unhandled rejection — the handler owns the whole
|
|
344
|
+
// response lifecycle.
|
|
345
|
+
if (!res.headersSent) {
|
|
346
|
+
responseJson(res, 500, { ok: false, error: { code: 'internal', message: error instanceof Error ? error.message : String(error) } });
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
res.destroy();
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
/** The host-side role gate: answer 409 wrong-role (or 503 when the row never
|
|
354
|
+
* built the handler) and stop there, or forward into the row's handler. */
|
|
355
|
+
async function forwardIfRole(req, res, delegate, handler) {
|
|
356
|
+
if (!servesRole(delegate.role())) {
|
|
357
|
+
wrongRole(res, delegate.role(), 'host');
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
if (handler === undefined) {
|
|
361
|
+
responseJson(res, 503, { ok: false, error: { code: 'unavailable', message: 'no host handler in this row generation' } });
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
await handler(req, res);
|
|
365
|
+
}
|
|
366
|
+
function wrongRole(res, role, required) {
|
|
367
|
+
responseJson(res, 409, { ok: false, error: { code: 'wrong-role', role, required } });
|
|
368
|
+
}
|
|
369
|
+
const acquisitions = new Map();
|
|
370
|
+
/**
|
|
371
|
+
* A stand-in delegate for the bind window: between `listen` succeeding and
|
|
372
|
+
* the acquiring row's swap landing (one microtask later), a request would
|
|
373
|
+
* otherwise meet no delegate at all. It answers EVERYTHING through the
|
|
374
|
+
* entry's pending delegate — which `acquireCliIpcServer` sets synchronously
|
|
375
|
+
* — so the stub is only visible when literally no row ever acquired, and
|
|
376
|
+
* its write refuses rather than pretending.
|
|
377
|
+
*/
|
|
378
|
+
function bootstrapDelegateFor(getEntry) {
|
|
379
|
+
return {
|
|
380
|
+
role: () => getEntry()?.pendingDelegate?.role() ?? 'host',
|
|
381
|
+
serverName: () => getEntry()?.pendingDelegate?.serverName() ?? '',
|
|
382
|
+
profileName: () => getEntry()?.pendingDelegate?.profileName(),
|
|
383
|
+
pluginVersion: () => getEntry()?.pendingDelegate?.pluginVersion() ?? 'unknown',
|
|
384
|
+
writeConfig: (input) => {
|
|
385
|
+
const current = getEntry()?.pendingDelegate;
|
|
386
|
+
if (current === undefined)
|
|
387
|
+
throw new Error('no plugin row has acquired the CLI IPC server yet');
|
|
388
|
+
return current.writeConfig(input);
|
|
389
|
+
},
|
|
390
|
+
wizardHandler: undefined,
|
|
391
|
+
adminHandler: undefined,
|
|
392
|
+
clientHandler: undefined,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Acquire (or hot-swap into) this process's IPC server for `dshHome`.
|
|
397
|
+
* Synchronous on purpose: apply() runs inside cordis and cannot await. The
|
|
398
|
+
* returned handle's `release()` is the row disposer; a release that hits
|
|
399
|
+
* refcount 0 closes the server after {@link CLI_CLOSE_GRACE_MS} unless a new
|
|
400
|
+
* row acquires first.
|
|
401
|
+
*/
|
|
402
|
+
export function acquireCliIpcServer(dshHome, delegate) {
|
|
403
|
+
let entry = acquisitions.get(dshHome);
|
|
404
|
+
if (entry === undefined) {
|
|
405
|
+
// The entry the bind closure reads through `getEntry` — assigned right
|
|
406
|
+
// after the (synchronous) object literal completes, long before any
|
|
407
|
+
// request callback can run.
|
|
408
|
+
let creating;
|
|
409
|
+
const created = {
|
|
410
|
+
starting: createCliIpcServer({ dshHome, delegate: bootstrapDelegateFor(() => creating) }),
|
|
411
|
+
server: undefined,
|
|
412
|
+
pendingDelegate: undefined,
|
|
413
|
+
refCount: 0,
|
|
414
|
+
closed: false,
|
|
415
|
+
graceTimer: undefined,
|
|
416
|
+
};
|
|
417
|
+
creating = created;
|
|
418
|
+
entry = created;
|
|
419
|
+
acquisitions.set(dshHome, created);
|
|
420
|
+
void created.starting
|
|
421
|
+
.then((server) => {
|
|
422
|
+
created.server = server;
|
|
423
|
+
if (created.closed) {
|
|
424
|
+
void server.close();
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
if (created.pendingDelegate !== undefined)
|
|
428
|
+
server.swapDelegate(created.pendingDelegate);
|
|
429
|
+
})
|
|
430
|
+
.catch(() => {
|
|
431
|
+
// Every candidate was taken by live instances — drop the slot so a
|
|
432
|
+
// later acquire can retry from scratch.
|
|
433
|
+
if (acquisitions.get(dshHome) === created)
|
|
434
|
+
acquisitions.delete(dshHome);
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
if (entry.graceTimer !== undefined) {
|
|
438
|
+
clearTimeout(entry.graceTimer);
|
|
439
|
+
entry.graceTimer = undefined;
|
|
440
|
+
}
|
|
441
|
+
entry.refCount += 1;
|
|
442
|
+
entry.pendingDelegate = delegate;
|
|
443
|
+
if (entry.server !== undefined && !entry.closed)
|
|
444
|
+
entry.server.swapDelegate(delegate);
|
|
445
|
+
return {
|
|
446
|
+
release() {
|
|
447
|
+
if (entry.refCount > 0)
|
|
448
|
+
entry.refCount -= 1;
|
|
449
|
+
if (entry.refCount > 0 || entry.closed || entry.graceTimer !== undefined)
|
|
450
|
+
return;
|
|
451
|
+
entry.graceTimer = setTimeout(() => {
|
|
452
|
+
entry.graceTimer = undefined;
|
|
453
|
+
if (entry.refCount > 0 || entry.closed)
|
|
454
|
+
return;
|
|
455
|
+
acquisitions.delete(dshHome);
|
|
456
|
+
entry.closed = true;
|
|
457
|
+
void entry.starting.then((server) => server.close()).catch(() => { });
|
|
458
|
+
}, CLI_CLOSE_GRACE_MS);
|
|
459
|
+
if (typeof entry.graceTimer.unref === 'function')
|
|
460
|
+
entry.graceTimer.unref();
|
|
461
|
+
},
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
//# sourceMappingURL=ipc-server.js.map
|