@sparkelf/dsh-plus 0.1.0-rc.31 → 0.1.0-rc.32
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/lib/bin.js
CHANGED
|
@@ -204,6 +204,31 @@ async function waitForServer(url, timeoutMilliseconds) {
|
|
|
204
204
|
}
|
|
205
205
|
return false;
|
|
206
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* Wait until the launcher's log carries the authenticated URL.
|
|
209
|
+
*
|
|
210
|
+
* Readiness and the printed line are separate events: the server answers before the
|
|
211
|
+
* launcher finishes its own startup, so the log is polled here rather than read once.
|
|
212
|
+
*
|
|
213
|
+
* @param logPath - the launcher's log file.
|
|
214
|
+
* @param timeoutMilliseconds - how long to keep polling.
|
|
215
|
+
* @returns the printed URL, or undefined when it never appeared.
|
|
216
|
+
*/
|
|
217
|
+
async function waitForAuthenticatedUrl(logPath, timeoutMilliseconds) {
|
|
218
|
+
const deadline = Date.now() + timeoutMilliseconds;
|
|
219
|
+
for (;;) {
|
|
220
|
+
let text = "";
|
|
221
|
+
try {
|
|
222
|
+
text = readFileSync(logPath, "utf8");
|
|
223
|
+
} catch {}
|
|
224
|
+
const found = /dsh web: (http:\/\/\S+)/u.exec(text);
|
|
225
|
+
if (found?.[1] !== void 0) return found[1];
|
|
226
|
+
if (Date.now() >= deadline) return void 0;
|
|
227
|
+
await new Promise((resolveDelay) => {
|
|
228
|
+
setTimeout(resolveDelay, 250);
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
207
232
|
//#endregion
|
|
208
233
|
//#region lib/types/standalone-profile.js
|
|
209
234
|
/**
|
|
@@ -550,12 +575,13 @@ async function startDetached(home, entry, options) {
|
|
|
550
575
|
if (isRunning(pid)) process.kill(pid, "SIGTERM");
|
|
551
576
|
return 1;
|
|
552
577
|
}
|
|
578
|
+
const opened = await waitForAuthenticatedUrl(logPath, READY_TIMEOUT_MILLISECONDS) ?? url;
|
|
553
579
|
writeState(home, {
|
|
554
580
|
pid,
|
|
555
581
|
port,
|
|
556
|
-
url
|
|
582
|
+
url: opened
|
|
557
583
|
});
|
|
558
|
-
console.log("Plus is running at " +
|
|
584
|
+
console.log("Plus is running at " + opened);
|
|
559
585
|
console.log("Logs: " + logPath);
|
|
560
586
|
console.log("Stop it with: dsh-plus stop");
|
|
561
587
|
return 0;
|
|
@@ -13,7 +13,7 @@ import { createRequire } from 'node:module';
|
|
|
13
13
|
import { dirname, join } from 'node:path';
|
|
14
14
|
import { fileURLToPath } from 'node:url';
|
|
15
15
|
import { newerVersion } from "./registry-versions.js";
|
|
16
|
-
import { DEFAULT_PORT, STOP_GRACE_MILLISECONDS, choosePort, clearState, isRunning, portAvailable, readState, spawnServer, stateDirectory, waitForServer, writeState, } from "./standalone-server.js";
|
|
16
|
+
import { DEFAULT_PORT, STOP_GRACE_MILLISECONDS, choosePort, clearState, isRunning, portAvailable, readState, spawnServer, stateDirectory, waitForAuthenticatedUrl, waitForServer, writeState, } from "./standalone-server.js";
|
|
17
17
|
import { STANDALONE_PROFILE, ensureProfile, readDistributionProfile, resolvePaths, } from "./standalone-profile.js";
|
|
18
18
|
/** Milliseconds a start waits for the server to answer before reporting failure. */
|
|
19
19
|
const READY_TIMEOUT_MILLISECONDS = 90_000;
|
|
@@ -137,8 +137,13 @@ async function startDetached(home, entry, options) {
|
|
|
137
137
|
process.kill(pid, 'SIGTERM');
|
|
138
138
|
return 1;
|
|
139
139
|
}
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
// The launcher prints the URL carrying the process launch token, and the server
|
|
141
|
+
// refuses every request without the cookie that token mints. Reporting the bare
|
|
142
|
+
// address sends the user to a 401 that tells them to reopen the launcher's URL,
|
|
143
|
+
// which lives only in the log this command points at.
|
|
144
|
+
const opened = await waitForAuthenticatedUrl(logPath, READY_TIMEOUT_MILLISECONDS) ?? url;
|
|
145
|
+
writeState(home, { pid, port, url: opened });
|
|
146
|
+
console.log('Plus is running at ' + opened);
|
|
142
147
|
console.log('Logs: ' + logPath);
|
|
143
148
|
console.log('Stop it with: dsh-plus stop');
|
|
144
149
|
return 0;
|
|
@@ -56,4 +56,15 @@ export declare function spawnServer(options: {
|
|
|
56
56
|
* @returns whether the server answered within the budget.
|
|
57
57
|
*/
|
|
58
58
|
export declare function waitForServer(url: string, timeoutMilliseconds: number): Promise<boolean>;
|
|
59
|
+
/**
|
|
60
|
+
* Wait until the launcher's log carries the authenticated URL.
|
|
61
|
+
*
|
|
62
|
+
* Readiness and the printed line are separate events: the server answers before the
|
|
63
|
+
* launcher finishes its own startup, so the log is polled here rather than read once.
|
|
64
|
+
*
|
|
65
|
+
* @param logPath - the launcher's log file.
|
|
66
|
+
* @param timeoutMilliseconds - how long to keep polling.
|
|
67
|
+
* @returns the printed URL, or undefined when it never appeared.
|
|
68
|
+
*/
|
|
69
|
+
export declare function waitForAuthenticatedUrl(logPath: string, timeoutMilliseconds: number): Promise<string | undefined>;
|
|
59
70
|
//# sourceMappingURL=standalone-server.d.ts.map
|
|
@@ -126,4 +126,33 @@ export async function waitForServer(url, timeoutMilliseconds) {
|
|
|
126
126
|
}
|
|
127
127
|
return false;
|
|
128
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Wait until the launcher's log carries the authenticated URL.
|
|
131
|
+
*
|
|
132
|
+
* Readiness and the printed line are separate events: the server answers before the
|
|
133
|
+
* launcher finishes its own startup, so the log is polled here rather than read once.
|
|
134
|
+
*
|
|
135
|
+
* @param logPath - the launcher's log file.
|
|
136
|
+
* @param timeoutMilliseconds - how long to keep polling.
|
|
137
|
+
* @returns the printed URL, or undefined when it never appeared.
|
|
138
|
+
*/
|
|
139
|
+
export async function waitForAuthenticatedUrl(logPath, timeoutMilliseconds) {
|
|
140
|
+
const deadline = Date.now() + timeoutMilliseconds;
|
|
141
|
+
for (;;) {
|
|
142
|
+
let text = '';
|
|
143
|
+
try {
|
|
144
|
+
text = readFileSync(logPath, 'utf8');
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// The launcher creates the log before it prints, so an absent file is a race
|
|
148
|
+
// with its first write rather than an error to report.
|
|
149
|
+
}
|
|
150
|
+
const found = /dsh web: (http:\/\/\S+)/u.exec(text);
|
|
151
|
+
if (found?.[1] !== undefined)
|
|
152
|
+
return found[1];
|
|
153
|
+
if (Date.now() >= deadline)
|
|
154
|
+
return undefined;
|
|
155
|
+
await new Promise((resolveDelay) => { setTimeout(resolveDelay, 250); });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
129
158
|
//# sourceMappingURL=standalone-server.js.map
|
package/package.json
CHANGED