@absolutejs/absolute 0.19.0-beta.704 → 0.19.0-beta.705
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/angular/components/constants.js +21 -0
- package/dist/angular/index.js +53 -73
- package/dist/angular/index.js.map +9 -9
- package/dist/angular/server.js +52 -72
- package/dist/angular/server.js.map +9 -9
- package/dist/build.js +8 -7
- package/dist/build.js.map +7 -7
- package/dist/cli/index.js +312 -285
- package/dist/client/index.js +4 -3
- package/dist/client/index.js.map +3 -3
- package/dist/index.js +88 -64
- package/dist/index.js.map +15 -15
- package/dist/islands/index.js +5 -4
- package/dist/islands/index.js.map +5 -5
- package/dist/react/index.js +49 -69
- package/dist/react/index.js.map +9 -9
- package/dist/react/jsxDevRuntimeCompat.js +1 -6
- package/dist/react/jsxDevRuntimeCompat.js.map +3 -3
- package/dist/react/server.js +43 -64
- package/dist/react/server.js.map +7 -7
- package/dist/src/angular/components/constants.d.ts +21 -0
- package/dist/src/angular/pageHandler.d.ts +6 -1
- package/dist/src/angular/ssrRender.d.ts +1 -1
- package/dist/src/constants.d.ts +21 -0
- package/dist/src/core/ssrCache.d.ts +1 -1
- package/dist/src/core/wrapPageHandlerWithStreamingSlots.d.ts +1 -1
- package/dist/src/react/jsxDevRuntimeCompat.d.ts +3 -6
- package/dist/src/react/pageHandler.d.ts +2 -1
- package/dist/src/svelte/pageHandler.d.ts +2 -2
- package/dist/src/utils/defineConfig.d.ts +2 -2
- package/dist/src/utils/loadConfig.d.ts +38 -2
- package/dist/src/vue/components/Image.d.ts +2 -2
- package/dist/src/vue/components/index.d.ts +1 -1
- package/dist/src/vue/index.d.ts +1 -1
- package/dist/src/vue/pageHandler.d.ts +2 -1
- package/dist/svelte/index.js +34 -49
- package/dist/svelte/index.js.map +9 -9
- package/dist/svelte/server.js +31 -47
- package/dist/svelte/server.js.map +8 -8
- package/dist/vue/components/Image.js +18 -18
- package/dist/vue/components/Image.js.map +3 -3
- package/dist/vue/components/index.js +77 -62
- package/dist/vue/components/index.js.map +5 -5
- package/dist/vue/index.js +119 -133
- package/dist/vue/index.js.map +12 -12
- package/dist/vue/server.js +40 -70
- package/dist/vue/server.js.map +7 -7
- package/package.json +42 -42
package/dist/cli/index.js
CHANGED
|
@@ -18,7 +18,7 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
|
18
18
|
var __require = import.meta.require;
|
|
19
19
|
|
|
20
20
|
// src/constants.ts
|
|
21
|
-
var ANSI_ESCAPE_LENGTH = 3, ASCII_SPACE = 32, BASE_36_RADIX = 36, BYTES_PER_KILOBYTE = 1024, CLI_ARGS_OFFSET = 3, DEFAULT_PORT = 3000, HOURS_IN_DAY = 24, HOURS_IN_HALF_DAY = 12, MAX_ERROR_LENGTH = 200, MILLISECONDS_IN_A_SECOND = 1000, MINUTES_IN_AN_HOUR = 60, SECONDS_IN_A_MINUTE = 60, MILLISECONDS_IN_A_MINUTE, MILLISECONDS_IN_A_DAY, SIGINT_EXIT_CODE = 130, SIGTERM_EXIT_CODE = 143, TIME_PRECISION = 2, TWO_THIRDS, UNFOUND_INDEX = -1;
|
|
21
|
+
var ANSI_ESCAPE_LENGTH = 3, ASCII_SPACE = 32, BASE_36_RADIX = 36, BYTES_PER_KILOBYTE = 1024, CLI_ARGS_OFFSET = 3, DEFAULT_PORT = 3000, HTTP_STATUS_OK = 200, HOURS_IN_DAY = 24, HOURS_IN_HALF_DAY = 12, MAX_ERROR_LENGTH = 200, MILLISECONDS_IN_A_SECOND = 1000, MINUTES_IN_AN_HOUR = 60, SECONDS_IN_A_MINUTE = 60, MILLISECONDS_IN_A_MINUTE, MILLISECONDS_IN_A_DAY, SIGINT_EXIT_CODE = 130, SIGTERM_EXIT_CODE = 143, TIME_PRECISION = 2, TWO_THIRDS, UNFOUND_INDEX = -1, WORKSPACE_COMMAND_ARGS_OFFSET = 3, WORKSPACE_FAILURE_LOG_PRINT_LIMIT = 30, WORKSPACE_FAILURE_RECENT_LOG_LIMIT = 60, WORKSPACE_READY_ATTEMPT_TIMEOUT_MS = 5000, WORKSPACE_READY_PROBE_INTERVAL_MS = 250, WORKSPACE_READY_TIMEOUT_MS = 30000, WORKSPACE_SHUTDOWN_TIMEOUT_MS = 1e4, WORKSPACE_TUI_DEFAULT_HEIGHT = 28, WORKSPACE_TUI_DEFAULT_WIDTH = 100, WORKSPACE_TUI_ESCAPE_SEQUENCE_TIMEOUT_MS = 30, WORKSPACE_TUI_FOOTER_LINE_COUNT = 3, WORKSPACE_TUI_MIN_LOG_HEIGHT = 3, WORKSPACE_TUI_MIN_SERVICE_NAME_WIDTH = 7, WORKSPACE_TUI_MIN_TARGET_WIDTH = 8, WORKSPACE_TUI_MIN_WRAP_WIDTH = 12, WORKSPACE_TUI_PROMPT_CURSOR_OFFSET = 3, WORKSPACE_TUI_RECENT_LOG_LIMIT = 40, WORKSPACE_TUI_RENDER_DEBOUNCE_MS = 16, WORKSPACE_TUI_STATUS_WIDTH = 10, WORKSPACE_TUI_TARGET_PADDING_WIDTH = 6, WORKSPACE_TUI_VISIBILITY_WIDTH = 8;
|
|
22
22
|
var init_constants = __esm(() => {
|
|
23
23
|
MILLISECONDS_IN_A_MINUTE = MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTE;
|
|
24
24
|
MILLISECONDS_IN_A_DAY = MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTE * MINUTES_IN_AN_HOUR * HOURS_IN_DAY;
|
|
@@ -222,7 +222,7 @@ var RESERVED_TOP_LEVEL_KEYS, isObject = (value) => typeof value === "object" &&
|
|
|
222
222
|
return false;
|
|
223
223
|
}
|
|
224
224
|
return entries.every(([, value]) => isServiceCandidate(value));
|
|
225
|
-
}, getWorkspaceServices = (config) => {
|
|
225
|
+
}, isConfigInput = (value) => isObject(value), getWorkspaceServices = (config) => {
|
|
226
226
|
if (!isWorkspaceConfig(config)) {
|
|
227
227
|
throw new Error("absolute.config.ts is not a multi-service config. Define top-level named services with `entry` or `command` before using `absolute workspace dev`.");
|
|
228
228
|
}
|
|
@@ -249,6 +249,16 @@ var RESERVED_TOP_LEVEL_KEYS, isObject = (value) => typeof value === "object" &&
|
|
|
249
249
|
...serviceConfig
|
|
250
250
|
} = service;
|
|
251
251
|
return serviceConfig;
|
|
252
|
+
}, loadConfig = async (configPath2) => {
|
|
253
|
+
const config = await loadRawConfig(configPath2);
|
|
254
|
+
const serviceName = process.env.ABSOLUTE_WORKSPACE_SERVICE_NAME;
|
|
255
|
+
if (typeof serviceName === "string" && serviceName.length > 0) {
|
|
256
|
+
return projectServiceConfig(config, serviceName);
|
|
257
|
+
}
|
|
258
|
+
if (isWorkspaceConfig(config)) {
|
|
259
|
+
throw new Error("absolute.config.ts defines multiple services. Use `absolute workspace dev` or set ABSOLUTE_WORKSPACE_SERVICE_NAME before loading a specific service config.");
|
|
260
|
+
}
|
|
261
|
+
return config;
|
|
252
262
|
}, loadRawConfig = async (configPath2) => {
|
|
253
263
|
const resolved = resolve(configPath2 ?? process.env.ABSOLUTE_CONFIG ?? "absolute.config.ts");
|
|
254
264
|
const mod = await import(resolved);
|
|
@@ -257,20 +267,10 @@ var RESERVED_TOP_LEVEL_KEYS, isObject = (value) => typeof value === "object" &&
|
|
|
257
267
|
throw new Error(`Config file "${resolved}" does not export a valid configuration.
|
|
258
268
|
Expected: export default defineConfig({ ... })`);
|
|
259
269
|
}
|
|
260
|
-
if (!
|
|
270
|
+
if (!isConfigInput(config)) {
|
|
261
271
|
throw new Error(`Config file "${resolved}" must export an object configuration.`);
|
|
262
272
|
}
|
|
263
273
|
return config;
|
|
264
|
-
}, loadConfig = async (configPath2) => {
|
|
265
|
-
const config = await loadRawConfig(configPath2);
|
|
266
|
-
const serviceName = process.env.ABSOLUTE_WORKSPACE_SERVICE_NAME;
|
|
267
|
-
if (typeof serviceName === "string" && serviceName.length > 0) {
|
|
268
|
-
return projectServiceConfig(config, serviceName);
|
|
269
|
-
}
|
|
270
|
-
if (isWorkspaceConfig(config)) {
|
|
271
|
-
throw new Error("absolute.config.ts defines multiple services. Use `absolute workspace dev` or set ABSOLUTE_WORKSPACE_SERVICE_NAME before loading a specific service config.");
|
|
272
|
-
}
|
|
273
|
-
return config;
|
|
274
274
|
};
|
|
275
275
|
var init_loadConfig = __esm(() => {
|
|
276
276
|
RESERVED_TOP_LEVEL_KEYS = new Set([
|
|
@@ -734,16 +734,21 @@ var SERVER_OUTPUT_LIMIT = 4000, STARTUP_POLL_INTERVAL_MS = 100, DEFAULT_STARTUP_
|
|
|
734
734
|
}, waitForServerReady = async (port) => {
|
|
735
735
|
const deadline = performance.now() + getStartupTimeoutMs();
|
|
736
736
|
while (performance.now() < deadline) {
|
|
737
|
-
|
|
738
|
-
if (res) {
|
|
739
|
-
await res.body?.cancel().catch(() => {
|
|
740
|
-
return;
|
|
741
|
-
});
|
|
737
|
+
if (await probePrerenderServer(port)) {
|
|
742
738
|
return true;
|
|
743
739
|
}
|
|
744
740
|
await Bun.sleep(STARTUP_POLL_INTERVAL_MS);
|
|
745
741
|
}
|
|
746
742
|
return false;
|
|
743
|
+
}, probePrerenderServer = async (port) => {
|
|
744
|
+
const res = await fetch(`http://localhost:${port}/`).catch(() => null);
|
|
745
|
+
if (!res) {
|
|
746
|
+
return false;
|
|
747
|
+
}
|
|
748
|
+
await res.body?.cancel().catch(() => {
|
|
749
|
+
return;
|
|
750
|
+
});
|
|
751
|
+
return true;
|
|
747
752
|
}, captureStreamOutput = (stream, output) => {
|
|
748
753
|
if (!stream)
|
|
749
754
|
return;
|
|
@@ -822,7 +827,7 @@ var cliTag3 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
822
827
|
result.push(fullPath);
|
|
823
828
|
}
|
|
824
829
|
return result;
|
|
825
|
-
},
|
|
830
|
+
}, readPackageVersion4 = (candidate) => {
|
|
826
831
|
try {
|
|
827
832
|
const pkg = JSON.parse(readFileSync9(candidate, "utf-8"));
|
|
828
833
|
if (pkg.name !== "@absolutejs/absolute")
|
|
@@ -834,7 +839,7 @@ var cliTag3 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
834
839
|
}
|
|
835
840
|
}, resolvePackageVersion3 = (candidates) => {
|
|
836
841
|
for (const candidate of candidates) {
|
|
837
|
-
const version2 =
|
|
842
|
+
const version2 = readPackageVersion4(candidate);
|
|
838
843
|
if (version2)
|
|
839
844
|
return version2;
|
|
840
845
|
}
|
|
@@ -1348,15 +1353,11 @@ Found ${errorCount} error${suffix}.`;
|
|
|
1348
1353
|
await mkdir2(cacheDir, { recursive: true });
|
|
1349
1354
|
const checks = [];
|
|
1350
1355
|
checks.push(hasVue ? buildVueTscCheck(cacheDir) : buildTscCheck(cacheDir));
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
checks.push(buildSvelteCheck(cacheDir, svelteDir));
|
|
1354
|
-
}
|
|
1356
|
+
for (const svelteDir of hasSvelte ? svelteDirs : []) {
|
|
1357
|
+
checks.push(buildSvelteCheck(cacheDir, svelteDir));
|
|
1355
1358
|
}
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
checks.push(buildAngularCheck(cacheDir, angularDir));
|
|
1359
|
-
}
|
|
1359
|
+
for (const angularDir of hasAngular ? angularDirs : []) {
|
|
1360
|
+
checks.push(buildAngularCheck(cacheDir, angularDir));
|
|
1360
1361
|
}
|
|
1361
1362
|
const results = await Promise.all(checks);
|
|
1362
1363
|
const failed = results.filter((res) => res.exitCode !== 0);
|
|
@@ -1999,18 +2000,19 @@ var getAbsoluteVersion = () => {
|
|
|
1999
2000
|
resolve4(import.meta.dir, "..", "..", "package.json"),
|
|
2000
2001
|
resolve4(import.meta.dir, "..", "..", "..", "package.json")
|
|
2001
2002
|
];
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
const pkg = JSON.parse(readFileSync5(pkgPath, "utf-8"));
|
|
2006
|
-
const ver = pkg.version;
|
|
2007
|
-
return ver;
|
|
2008
|
-
}
|
|
2003
|
+
const pkgPath = candidates.find((candidate) => existsSync6(candidate));
|
|
2004
|
+
if (pkgPath)
|
|
2005
|
+
return readPackageVersion(pkgPath);
|
|
2009
2006
|
} catch {
|
|
2010
2007
|
return getPackageVersion("@absolutejs/absolute");
|
|
2011
2008
|
}
|
|
2012
2009
|
return getPackageVersion("@absolutejs/absolute");
|
|
2013
2010
|
};
|
|
2011
|
+
var readPackageVersion = (pkgPath) => {
|
|
2012
|
+
const pkg = JSON.parse(readFileSync5(pkgPath, "utf-8"));
|
|
2013
|
+
const ver = pkg.version;
|
|
2014
|
+
return ver;
|
|
2015
|
+
};
|
|
2014
2016
|
var detectCI = () => {
|
|
2015
2017
|
const { env: env2 } = process;
|
|
2016
2018
|
if (env2.GITHUB_ACTIONS)
|
|
@@ -2258,14 +2260,14 @@ import { basename, resolve as resolve5 } from "path";
|
|
|
2258
2260
|
var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`;
|
|
2259
2261
|
var resolvePackageVersion = (candidates) => {
|
|
2260
2262
|
for (const candidate of candidates) {
|
|
2261
|
-
const version2 =
|
|
2263
|
+
const version2 = readPackageVersion2(candidate);
|
|
2262
2264
|
if (version2) {
|
|
2263
2265
|
return version2;
|
|
2264
2266
|
}
|
|
2265
2267
|
}
|
|
2266
2268
|
return "";
|
|
2267
2269
|
};
|
|
2268
|
-
var
|
|
2270
|
+
var readPackageVersion2 = (candidate) => {
|
|
2269
2271
|
try {
|
|
2270
2272
|
const pkg = JSON.parse(readFileSync7(candidate, "utf-8"));
|
|
2271
2273
|
if (pkg.name !== "@absolutejs/absolute")
|
|
@@ -2659,54 +2661,49 @@ var appendRightEdge = (value, width, marker) => {
|
|
|
2659
2661
|
}
|
|
2660
2662
|
return `${padLine(value, Math.max(0, width - 1))}${marker}`;
|
|
2661
2663
|
};
|
|
2664
|
+
var splitLongWord = (word, width) => {
|
|
2665
|
+
const parts = [];
|
|
2666
|
+
for (let index = 0;index < word.length; index += width) {
|
|
2667
|
+
parts.push(word.slice(index, index + width));
|
|
2668
|
+
}
|
|
2669
|
+
return parts;
|
|
2670
|
+
};
|
|
2671
|
+
var appendWrappedWord = (lines, current, word, width) => {
|
|
2672
|
+
if (current.length === 0) {
|
|
2673
|
+
if (word.length <= width)
|
|
2674
|
+
return word;
|
|
2675
|
+
lines.push(...splitLongWord(word, width));
|
|
2676
|
+
return "";
|
|
2677
|
+
}
|
|
2678
|
+
const next = `${current} ${word}`;
|
|
2679
|
+
if (next.length <= width)
|
|
2680
|
+
return next;
|
|
2681
|
+
lines.push(current);
|
|
2682
|
+
if (word.length <= width)
|
|
2683
|
+
return word;
|
|
2684
|
+
lines.push(...splitLongWord(word, width));
|
|
2685
|
+
return "";
|
|
2686
|
+
};
|
|
2687
|
+
var wrapLine = (line, width) => {
|
|
2688
|
+
if (line.length === 0)
|
|
2689
|
+
return [""];
|
|
2690
|
+
if (line.length <= width)
|
|
2691
|
+
return [line];
|
|
2692
|
+
const lines = [];
|
|
2693
|
+
let current = "";
|
|
2694
|
+
for (const word of line.split(/\s+/)) {
|
|
2695
|
+
current = appendWrappedWord(lines, current, word, width);
|
|
2696
|
+
}
|
|
2697
|
+
if (current.length > 0)
|
|
2698
|
+
lines.push(current);
|
|
2699
|
+
return lines;
|
|
2700
|
+
};
|
|
2662
2701
|
var wrapText = (value, width) => {
|
|
2663
2702
|
if (width <= 0) {
|
|
2664
2703
|
return [""];
|
|
2665
2704
|
}
|
|
2666
|
-
const lines =
|
|
2667
|
-
|
|
2668
|
-
`)) {
|
|
2669
|
-
const line = rawLine.trimEnd();
|
|
2670
|
-
if (line.length === 0) {
|
|
2671
|
-
lines.push("");
|
|
2672
|
-
continue;
|
|
2673
|
-
}
|
|
2674
|
-
if (line.length <= width) {
|
|
2675
|
-
lines.push(line);
|
|
2676
|
-
continue;
|
|
2677
|
-
}
|
|
2678
|
-
const words = line.split(/\s+/);
|
|
2679
|
-
let current = "";
|
|
2680
|
-
for (const word of words) {
|
|
2681
|
-
if (current.length === 0) {
|
|
2682
|
-
if (word.length <= width) {
|
|
2683
|
-
current = word;
|
|
2684
|
-
continue;
|
|
2685
|
-
}
|
|
2686
|
-
for (let index = 0;index < word.length; index += width) {
|
|
2687
|
-
lines.push(word.slice(index, index + width));
|
|
2688
|
-
}
|
|
2689
|
-
continue;
|
|
2690
|
-
}
|
|
2691
|
-
const next = `${current} ${word}`;
|
|
2692
|
-
if (next.length <= width) {
|
|
2693
|
-
current = next;
|
|
2694
|
-
continue;
|
|
2695
|
-
}
|
|
2696
|
-
lines.push(current);
|
|
2697
|
-
if (word.length <= width) {
|
|
2698
|
-
current = word;
|
|
2699
|
-
continue;
|
|
2700
|
-
}
|
|
2701
|
-
for (let index = 0;index < word.length; index += width) {
|
|
2702
|
-
lines.push(word.slice(index, index + width));
|
|
2703
|
-
}
|
|
2704
|
-
current = "";
|
|
2705
|
-
}
|
|
2706
|
-
if (current.length > 0) {
|
|
2707
|
-
lines.push(current);
|
|
2708
|
-
}
|
|
2709
|
-
}
|
|
2705
|
+
const lines = value.split(`
|
|
2706
|
+
`).flatMap((rawLine) => wrapLine(rawLine.trimEnd(), width));
|
|
2710
2707
|
return lines.length > 0 ? lines : [""];
|
|
2711
2708
|
};
|
|
2712
2709
|
var formatTimestamp2 = () => new Date().toLocaleTimeString([], {
|
|
@@ -2811,7 +2808,7 @@ var createWorkspaceTui = ({
|
|
|
2811
2808
|
renderTimer = setTimeout(() => {
|
|
2812
2809
|
renderTimer = null;
|
|
2813
2810
|
render();
|
|
2814
|
-
},
|
|
2811
|
+
}, WORKSPACE_TUI_RENDER_DEBOUNCE_MS);
|
|
2815
2812
|
};
|
|
2816
2813
|
const clearPendingEscape = () => {
|
|
2817
2814
|
if (!escapeTimer) {
|
|
@@ -2826,7 +2823,7 @@ var createWorkspaceTui = ({
|
|
|
2826
2823
|
escapeTimer = null;
|
|
2827
2824
|
escapeBuffer = "";
|
|
2828
2825
|
exitEscapeMode();
|
|
2829
|
-
},
|
|
2826
|
+
}, WORKSPACE_TUI_ESCAPE_SEQUENCE_TIMEOUT_MS);
|
|
2830
2827
|
};
|
|
2831
2828
|
const resetPrompt = () => {
|
|
2832
2829
|
promptBuffer = "";
|
|
@@ -2848,16 +2845,16 @@ var createWorkspaceTui = ({
|
|
|
2848
2845
|
if (disposed) {
|
|
2849
2846
|
return;
|
|
2850
2847
|
}
|
|
2851
|
-
const width = process.stdout.columns ??
|
|
2852
|
-
const height = process.stdout.rows ??
|
|
2848
|
+
const width = process.stdout.columns ?? WORKSPACE_TUI_DEFAULT_WIDTH;
|
|
2849
|
+
const height = process.stdout.rows ?? WORKSPACE_TUI_DEFAULT_HEIGHT;
|
|
2853
2850
|
const servicesSnapshot = [...serviceStates.values()];
|
|
2854
2851
|
const workspaceStatus = getWorkspaceStatus(servicesSnapshot);
|
|
2855
2852
|
const statusLabel = workspaceStatus === "ready" && readyDurationMs !== null ? `${colors.dim}ready in${colors.reset} ${colors.bold}${getDurationString(readyDurationMs)}${colors.reset}` : `${colors.dim}${workspaceStatus}${colors.reset}`;
|
|
2856
2853
|
const title = `${colors.cyan}${colors.bold}ABSOLUTEJS WORKSPACE${colors.reset} ${colors.dim}v${version2}${colors.reset} ${statusLabel}`;
|
|
2857
2854
|
const divider = `${colors.dim}${"\u2500".repeat(Math.max(width, 1))}${colors.reset}`;
|
|
2858
|
-
const serviceNameWidth = Math.max(
|
|
2859
|
-
const visibilityWidth =
|
|
2860
|
-
const statusWidth =
|
|
2855
|
+
const serviceNameWidth = Math.max(WORKSPACE_TUI_MIN_SERVICE_NAME_WIDTH, ...servicesSnapshot.map((service) => service.name.length));
|
|
2856
|
+
const visibilityWidth = WORKSPACE_TUI_VISIBILITY_WIDTH;
|
|
2857
|
+
const statusWidth = WORKSPACE_TUI_STATUS_WIDTH;
|
|
2861
2858
|
const rows = [];
|
|
2862
2859
|
rows.push(padLine(title, width));
|
|
2863
2860
|
rows.push(divider);
|
|
@@ -2865,21 +2862,21 @@ var createWorkspaceTui = ({
|
|
|
2865
2862
|
for (const service of servicesSnapshot) {
|
|
2866
2863
|
const stateColor = getStatusColor(service.status);
|
|
2867
2864
|
const detail = service.detail ? ` \xB7 ${service.detail}` : "";
|
|
2868
|
-
const targetWidth = Math.max(width - serviceNameWidth - visibilityWidth - statusWidth -
|
|
2865
|
+
const targetWidth = Math.max(width - serviceNameWidth - visibilityWidth - statusWidth - WORKSPACE_TUI_TARGET_PADDING_WIDTH, WORKSPACE_TUI_MIN_TARGET_WIDTH);
|
|
2869
2866
|
const target = truncateText(`${getTargetLabel(service)}${detail}`, targetWidth);
|
|
2870
2867
|
const targetColor = service.visibility === "public" && service.status !== "ready" ? colors.dim : colors.reset;
|
|
2871
2868
|
const row = `${colors.bold}${service.name.padEnd(serviceNameWidth)}${colors.reset} ${colors.dim}${service.visibility.padEnd(visibilityWidth)}${colors.reset} ${stateColor}${service.status.padEnd(statusWidth)}${colors.reset} ${targetColor}${target}${colors.reset}`;
|
|
2872
2869
|
rows.push(padLine(row, width));
|
|
2873
2870
|
}
|
|
2874
2871
|
rows.push(divider);
|
|
2875
|
-
const footerLines =
|
|
2872
|
+
const footerLines = WORKSPACE_TUI_FOOTER_LINE_COUNT;
|
|
2876
2873
|
const fixedHeight = rows.length + footerLines;
|
|
2877
|
-
const logHeight = Math.max(height - fixedHeight,
|
|
2874
|
+
const logHeight = Math.max(height - fixedHeight, WORKSPACE_TUI_MIN_LOG_HEIGHT);
|
|
2878
2875
|
const logWidth = Math.max(width - 1, 1);
|
|
2879
2876
|
const contentLines = helpVisible ? helpLines : logEntries.flatMap((entry) => {
|
|
2880
2877
|
const prefixPlain = `${entry.timestamp} [${entry.source}] `;
|
|
2881
2878
|
const prefixColor = `${colors.dim}${entry.timestamp}${colors.reset} ${getSourceColor(entry.source)}[${entry.source}]${colors.reset} `;
|
|
2882
|
-
const wrapped = wrapText(entry.message, Math.max(logWidth - prefixPlain.length,
|
|
2879
|
+
const wrapped = wrapText(entry.message, Math.max(logWidth - prefixPlain.length, WORKSPACE_TUI_MIN_WRAP_WIDTH));
|
|
2883
2880
|
return wrapped.map((line, index) => {
|
|
2884
2881
|
if (index === 0) {
|
|
2885
2882
|
return `${prefixColor}${getLogColor(entry.level)}${line}${colors.reset}`;
|
|
@@ -2927,7 +2924,7 @@ var createWorkspaceTui = ({
|
|
|
2927
2924
|
`);
|
|
2928
2925
|
process.stdout.write(`\x1B[H${screen}`);
|
|
2929
2926
|
if (shellMode) {
|
|
2930
|
-
const promptColumn = Math.min(promptBuffer.length +
|
|
2927
|
+
const promptColumn = Math.min(promptBuffer.length + WORKSPACE_TUI_PROMPT_CURSOR_OFFSET, width);
|
|
2931
2928
|
const promptRow = Math.min(rows.length, height);
|
|
2932
2929
|
process.stdout.write(`\x1B[${promptRow};${promptColumn}H\x1B[?25h`);
|
|
2933
2930
|
return;
|
|
@@ -2971,7 +2968,7 @@ var createWorkspaceTui = ({
|
|
|
2971
2968
|
logScrollOffset = 0;
|
|
2972
2969
|
scheduleRender();
|
|
2973
2970
|
};
|
|
2974
|
-
const getRecentLogs = (limit =
|
|
2971
|
+
const getRecentLogs = (limit = WORKSPACE_TUI_RECENT_LOG_LIMIT) => logEntries.slice(Math.max(0, logEntries.length - limit));
|
|
2975
2972
|
const getServiceSnapshot = () => [...serviceStates.values()].map((service) => ({
|
|
2976
2973
|
detail: service.detail,
|
|
2977
2974
|
name: service.name,
|
|
@@ -2983,21 +2980,35 @@ var createWorkspaceTui = ({
|
|
|
2983
2980
|
if (!shellMode || shellHistory.length === 0) {
|
|
2984
2981
|
return;
|
|
2985
2982
|
}
|
|
2986
|
-
if (direction === "up") {
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
} else if (shellHistoryIndex <= 0) {
|
|
2983
|
+
if (direction === "up" && shellHistoryIndex < shellHistory.length - 1) {
|
|
2984
|
+
shellHistoryIndex++;
|
|
2985
|
+
}
|
|
2986
|
+
if (direction === "down" && shellHistoryIndex <= 0) {
|
|
2991
2987
|
shellHistoryIndex = UNFOUND_INDEX;
|
|
2992
2988
|
promptBuffer = "";
|
|
2993
2989
|
scheduleRender();
|
|
2994
2990
|
return;
|
|
2995
|
-
}
|
|
2991
|
+
}
|
|
2992
|
+
if (direction === "down") {
|
|
2996
2993
|
shellHistoryIndex--;
|
|
2997
2994
|
}
|
|
2998
2995
|
promptBuffer = shellHistoryIndex === UNFOUND_INDEX ? "" : shellHistory[shellHistory.length - 1 - shellHistoryIndex] ?? "";
|
|
2999
2996
|
scheduleRender();
|
|
3000
2997
|
};
|
|
2998
|
+
const handleArrowEscape = (direction) => {
|
|
2999
|
+
clearPendingEscape();
|
|
3000
|
+
escapeBuffer = "";
|
|
3001
|
+
if (shellMode) {
|
|
3002
|
+
navigateShellHistory(direction);
|
|
3003
|
+
return;
|
|
3004
|
+
}
|
|
3005
|
+
scrollLogs(direction);
|
|
3006
|
+
};
|
|
3007
|
+
const handleScrollEscape = (mode) => {
|
|
3008
|
+
clearPendingEscape();
|
|
3009
|
+
escapeBuffer = "";
|
|
3010
|
+
scrollLogs(mode);
|
|
3011
|
+
};
|
|
3001
3012
|
const scrollLogs = (direction) => {
|
|
3002
3013
|
if (helpVisible) {
|
|
3003
3014
|
return;
|
|
@@ -3052,47 +3063,27 @@ var createWorkspaceTui = ({
|
|
|
3052
3063
|
return;
|
|
3053
3064
|
}
|
|
3054
3065
|
if (escapeBuffer === `${ESCAPE}[A`) {
|
|
3055
|
-
|
|
3056
|
-
escapeBuffer = "";
|
|
3057
|
-
if (shellMode) {
|
|
3058
|
-
navigateShellHistory("up");
|
|
3059
|
-
} else {
|
|
3060
|
-
scrollLogs("up");
|
|
3061
|
-
}
|
|
3066
|
+
handleArrowEscape("up");
|
|
3062
3067
|
return;
|
|
3063
3068
|
}
|
|
3064
3069
|
if (escapeBuffer === `${ESCAPE}[B`) {
|
|
3065
|
-
|
|
3066
|
-
escapeBuffer = "";
|
|
3067
|
-
if (shellMode) {
|
|
3068
|
-
navigateShellHistory("down");
|
|
3069
|
-
} else {
|
|
3070
|
-
scrollLogs("down");
|
|
3071
|
-
}
|
|
3070
|
+
handleArrowEscape("down");
|
|
3072
3071
|
return;
|
|
3073
3072
|
}
|
|
3074
3073
|
if (escapeBuffer === `${ESCAPE}[5~`) {
|
|
3075
|
-
|
|
3076
|
-
escapeBuffer = "";
|
|
3077
|
-
scrollLogs("pageUp");
|
|
3074
|
+
handleScrollEscape("pageUp");
|
|
3078
3075
|
return;
|
|
3079
3076
|
}
|
|
3080
3077
|
if (escapeBuffer === `${ESCAPE}[6~`) {
|
|
3081
|
-
|
|
3082
|
-
escapeBuffer = "";
|
|
3083
|
-
scrollLogs("pageDown");
|
|
3078
|
+
handleScrollEscape("pageDown");
|
|
3084
3079
|
return;
|
|
3085
3080
|
}
|
|
3086
3081
|
if (escapeBuffer === `${ESCAPE}[H` || escapeBuffer === `${ESCAPE}[1~`) {
|
|
3087
|
-
|
|
3088
|
-
escapeBuffer = "";
|
|
3089
|
-
scrollLogs("home");
|
|
3082
|
+
handleScrollEscape("home");
|
|
3090
3083
|
return;
|
|
3091
3084
|
}
|
|
3092
3085
|
if (escapeBuffer === `${ESCAPE}[F` || escapeBuffer === `${ESCAPE}[4~`) {
|
|
3093
|
-
|
|
3094
|
-
escapeBuffer = "";
|
|
3095
|
-
scrollLogs("end");
|
|
3086
|
+
handleScrollEscape("end");
|
|
3096
3087
|
return;
|
|
3097
3088
|
}
|
|
3098
3089
|
if (/^\x1b\[[0-9]*$/.test(escapeBuffer)) {
|
|
@@ -3101,6 +3092,40 @@ var createWorkspaceTui = ({
|
|
|
3101
3092
|
}
|
|
3102
3093
|
exitEscapeMode();
|
|
3103
3094
|
};
|
|
3095
|
+
const handleBackspace = () => {
|
|
3096
|
+
if (!shellMode) {
|
|
3097
|
+
return;
|
|
3098
|
+
}
|
|
3099
|
+
if (promptBuffer.length > 0) {
|
|
3100
|
+
promptBuffer = promptBuffer.slice(0, UNFOUND_INDEX);
|
|
3101
|
+
scheduleRender();
|
|
3102
|
+
return;
|
|
3103
|
+
}
|
|
3104
|
+
resetPrompt();
|
|
3105
|
+
};
|
|
3106
|
+
const handleEnter = async () => {
|
|
3107
|
+
if (!shellMode) {
|
|
3108
|
+
return;
|
|
3109
|
+
}
|
|
3110
|
+
await submitShellCommand();
|
|
3111
|
+
};
|
|
3112
|
+
const handlePrintableChar = async (char) => {
|
|
3113
|
+
if (shellMode) {
|
|
3114
|
+
promptBuffer += char;
|
|
3115
|
+
scheduleRender();
|
|
3116
|
+
return;
|
|
3117
|
+
}
|
|
3118
|
+
if (char === "$") {
|
|
3119
|
+
shellMode = true;
|
|
3120
|
+
promptBuffer = "";
|
|
3121
|
+
scheduleRender();
|
|
3122
|
+
return;
|
|
3123
|
+
}
|
|
3124
|
+
const shortcut = SHORTCUTS2.get(char.toLowerCase());
|
|
3125
|
+
if (shortcut) {
|
|
3126
|
+
await runShortcut(shortcut);
|
|
3127
|
+
}
|
|
3128
|
+
};
|
|
3104
3129
|
const handleChar = async (char) => {
|
|
3105
3130
|
if (char === "\x03") {
|
|
3106
3131
|
await actions.quit();
|
|
@@ -3116,42 +3141,18 @@ var createWorkspaceTui = ({
|
|
|
3116
3141
|
return;
|
|
3117
3142
|
}
|
|
3118
3143
|
if (char === "\x7F" || char === "\b") {
|
|
3119
|
-
|
|
3120
|
-
return;
|
|
3121
|
-
}
|
|
3122
|
-
if (promptBuffer.length > 0) {
|
|
3123
|
-
promptBuffer = promptBuffer.slice(0, UNFOUND_INDEX);
|
|
3124
|
-
scheduleRender();
|
|
3125
|
-
return;
|
|
3126
|
-
}
|
|
3127
|
-
resetPrompt();
|
|
3144
|
+
handleBackspace();
|
|
3128
3145
|
return;
|
|
3129
3146
|
}
|
|
3130
3147
|
if (char === "\r" || char === `
|
|
3131
3148
|
`) {
|
|
3132
|
-
|
|
3133
|
-
await submitShellCommand();
|
|
3134
|
-
}
|
|
3149
|
+
await handleEnter();
|
|
3135
3150
|
return;
|
|
3136
3151
|
}
|
|
3137
3152
|
if (char.charCodeAt(0) < ASCII_SPACE) {
|
|
3138
3153
|
return;
|
|
3139
3154
|
}
|
|
3140
|
-
|
|
3141
|
-
if (char === "$") {
|
|
3142
|
-
shellMode = true;
|
|
3143
|
-
promptBuffer = "";
|
|
3144
|
-
scheduleRender();
|
|
3145
|
-
return;
|
|
3146
|
-
}
|
|
3147
|
-
const shortcut = SHORTCUTS2.get(char.toLowerCase());
|
|
3148
|
-
if (shortcut) {
|
|
3149
|
-
await runShortcut(shortcut);
|
|
3150
|
-
}
|
|
3151
|
-
return;
|
|
3152
|
-
}
|
|
3153
|
-
promptBuffer += char;
|
|
3154
|
-
scheduleRender();
|
|
3155
|
+
await handlePrintableChar(char);
|
|
3155
3156
|
};
|
|
3156
3157
|
const onResize = () => {
|
|
3157
3158
|
scheduleRender();
|
|
@@ -3176,6 +3177,16 @@ var createWorkspaceTui = ({
|
|
|
3176
3177
|
process.stdout.on("resize", onResize);
|
|
3177
3178
|
render();
|
|
3178
3179
|
};
|
|
3180
|
+
const disposeInput = () => {
|
|
3181
|
+
if (!input) {
|
|
3182
|
+
return;
|
|
3183
|
+
}
|
|
3184
|
+
input.off("data", onData);
|
|
3185
|
+
setRawMode(false);
|
|
3186
|
+
if (input !== process.stdin) {
|
|
3187
|
+
input.destroy();
|
|
3188
|
+
}
|
|
3189
|
+
};
|
|
3179
3190
|
const dispose = () => {
|
|
3180
3191
|
if (disposed) {
|
|
3181
3192
|
return;
|
|
@@ -3187,13 +3198,7 @@ var createWorkspaceTui = ({
|
|
|
3187
3198
|
renderTimer = null;
|
|
3188
3199
|
}
|
|
3189
3200
|
process.stdout.off("resize", onResize);
|
|
3190
|
-
|
|
3191
|
-
input.off("data", onData);
|
|
3192
|
-
setRawMode(false);
|
|
3193
|
-
if (input !== process.stdin) {
|
|
3194
|
-
input.destroy();
|
|
3195
|
-
}
|
|
3196
|
-
}
|
|
3201
|
+
disposeInput();
|
|
3197
3202
|
process.stdout.write("\x1B[?25h\x1B[?1049l");
|
|
3198
3203
|
};
|
|
3199
3204
|
return {
|
|
@@ -3217,11 +3222,7 @@ var sanitizeLogFileName = (value) => value.replace(/[^a-zA-Z0-9._-]/g, "_") || "
|
|
|
3217
3222
|
var createWorkspaceLogSink = (appendLog) => {
|
|
3218
3223
|
const logDirectory = resolve6(".absolutejs", "workspace", "logs");
|
|
3219
3224
|
mkdirSync4(logDirectory, { recursive: true });
|
|
3220
|
-
|
|
3221
|
-
if (file.endsWith(".log")) {
|
|
3222
|
-
unlinkSync(resolve6(logDirectory, file));
|
|
3223
|
-
}
|
|
3224
|
-
}
|
|
3225
|
+
readdirSync(logDirectory).filter((file) => file.endsWith(".log")).forEach((file) => unlinkSync(resolve6(logDirectory, file)));
|
|
3225
3226
|
writeFileSync2(resolve6(logDirectory, "all.log"), "");
|
|
3226
3227
|
writeFileSync2(resolve6(logDirectory, "workspace.log"), "");
|
|
3227
3228
|
const initializedSources = new Set(["workspace"]);
|
|
@@ -3249,13 +3250,13 @@ var createWorkspaceLogSink = (appendLog) => {
|
|
|
3249
3250
|
}
|
|
3250
3251
|
};
|
|
3251
3252
|
};
|
|
3252
|
-
var
|
|
3253
|
+
var readPackageVersion3 = (candidate) => {
|
|
3253
3254
|
try {
|
|
3254
3255
|
const pkg = JSON.parse(readFileSync8(candidate, "utf-8"));
|
|
3255
3256
|
if (pkg.name !== "@absolutejs/absolute") {
|
|
3256
3257
|
return null;
|
|
3257
3258
|
}
|
|
3258
|
-
const version2 = pkg
|
|
3259
|
+
const { version: version2 } = pkg;
|
|
3259
3260
|
return version2;
|
|
3260
3261
|
} catch {
|
|
3261
3262
|
return null;
|
|
@@ -3268,7 +3269,7 @@ var resolvePackageVersion2 = () => {
|
|
|
3268
3269
|
resolve6(import.meta.dir, "..", "..", "..", "..", "package.json")
|
|
3269
3270
|
];
|
|
3270
3271
|
for (const candidate of candidates) {
|
|
3271
|
-
const version2 =
|
|
3272
|
+
const version2 = readPackageVersion3(candidate);
|
|
3272
3273
|
if (version2) {
|
|
3273
3274
|
return version2;
|
|
3274
3275
|
}
|
|
@@ -3290,7 +3291,7 @@ var getDefaultReadyConfig = (service) => {
|
|
|
3290
3291
|
}
|
|
3291
3292
|
return;
|
|
3292
3293
|
};
|
|
3293
|
-
var normalizeExpectedStatuses = (value) => Array.isArray(value) ? value : [value ??
|
|
3294
|
+
var normalizeExpectedStatuses = (value) => Array.isArray(value) ? value : [value ?? HTTP_STATUS_OK];
|
|
3294
3295
|
var resolveServiceHttpUrl = (service, path) => {
|
|
3295
3296
|
if (!path.startsWith("/")) {
|
|
3296
3297
|
throw new Error(`ready path must start with "/" for service probes. Received "${path}".`);
|
|
@@ -3307,20 +3308,20 @@ var resolveHttpReadyProbe = (service, ready) => {
|
|
|
3307
3308
|
type: "http",
|
|
3308
3309
|
url: resolveServiceHttpUrl(service, ready),
|
|
3309
3310
|
method: "GET",
|
|
3310
|
-
expectStatus: [
|
|
3311
|
+
expectStatus: [HTTP_STATUS_OK],
|
|
3311
3312
|
headers: {},
|
|
3312
|
-
intervalMs:
|
|
3313
|
-
timeoutMs:
|
|
3313
|
+
intervalMs: WORKSPACE_READY_PROBE_INTERVAL_MS,
|
|
3314
|
+
timeoutMs: WORKSPACE_READY_TIMEOUT_MS
|
|
3314
3315
|
};
|
|
3315
3316
|
}
|
|
3316
3317
|
return {
|
|
3317
|
-
|
|
3318
|
-
url: ready,
|
|
3319
|
-
method: "GET",
|
|
3320
|
-
expectStatus: [200],
|
|
3318
|
+
expectStatus: [HTTP_STATUS_OK],
|
|
3321
3319
|
headers: {},
|
|
3322
|
-
intervalMs:
|
|
3323
|
-
|
|
3320
|
+
intervalMs: WORKSPACE_READY_PROBE_INTERVAL_MS,
|
|
3321
|
+
method: "GET",
|
|
3322
|
+
timeoutMs: WORKSPACE_READY_TIMEOUT_MS,
|
|
3323
|
+
type: "http",
|
|
3324
|
+
url: ready
|
|
3324
3325
|
};
|
|
3325
3326
|
}
|
|
3326
3327
|
if (ready.path && ready.url) {
|
|
@@ -3336,8 +3337,8 @@ var resolveHttpReadyProbe = (service, ready) => {
|
|
|
3336
3337
|
method: ready.method ?? "GET",
|
|
3337
3338
|
expectStatus: normalizeExpectedStatuses(ready.expectStatus),
|
|
3338
3339
|
headers: ready.headers ?? {},
|
|
3339
|
-
intervalMs: ready.intervalMs ??
|
|
3340
|
-
timeoutMs: ready.timeoutMs ??
|
|
3340
|
+
intervalMs: ready.intervalMs ?? WORKSPACE_READY_PROBE_INTERVAL_MS,
|
|
3341
|
+
timeoutMs: ready.timeoutMs ?? WORKSPACE_READY_TIMEOUT_MS
|
|
3341
3342
|
};
|
|
3342
3343
|
};
|
|
3343
3344
|
var resolveReadyProbe = (service, ready = service.ready ?? getDefaultReadyConfig(service)) => {
|
|
@@ -3352,22 +3353,22 @@ var resolveReadyProbe = (service, ready = service.ready ?? getDefaultReadyConfig
|
|
|
3352
3353
|
type: "tcp",
|
|
3353
3354
|
host: ready.host ?? getServicePublicHost(service),
|
|
3354
3355
|
port: ready.port,
|
|
3355
|
-
intervalMs: ready.intervalMs ??
|
|
3356
|
-
timeoutMs: ready.timeoutMs ??
|
|
3356
|
+
intervalMs: ready.intervalMs ?? WORKSPACE_READY_PROBE_INTERVAL_MS,
|
|
3357
|
+
timeoutMs: ready.timeoutMs ?? WORKSPACE_READY_TIMEOUT_MS
|
|
3357
3358
|
};
|
|
3358
3359
|
}
|
|
3359
3360
|
if (ready.type === "command") {
|
|
3360
3361
|
return {
|
|
3361
|
-
type: "command",
|
|
3362
3362
|
command: ready.command,
|
|
3363
|
-
intervalMs: ready.intervalMs ??
|
|
3364
|
-
timeoutMs: ready.timeoutMs ??
|
|
3363
|
+
intervalMs: ready.intervalMs ?? WORKSPACE_READY_PROBE_INTERVAL_MS,
|
|
3364
|
+
timeoutMs: ready.timeoutMs ?? WORKSPACE_READY_TIMEOUT_MS,
|
|
3365
|
+
type: "command"
|
|
3365
3366
|
};
|
|
3366
3367
|
}
|
|
3367
3368
|
if (ready.type === "delay") {
|
|
3368
3369
|
return {
|
|
3369
|
-
|
|
3370
|
-
|
|
3370
|
+
ms: ready.ms,
|
|
3371
|
+
type: "delay"
|
|
3371
3372
|
};
|
|
3372
3373
|
}
|
|
3373
3374
|
return resolveHttpReadyProbe(service, ready);
|
|
@@ -3376,7 +3377,7 @@ var probeHttpReady = async (ready) => {
|
|
|
3376
3377
|
const response = await fetch(ready.url, {
|
|
3377
3378
|
method: ready.method,
|
|
3378
3379
|
headers: ready.headers,
|
|
3379
|
-
signal: AbortSignal.timeout(Math.min(ready.timeoutMs,
|
|
3380
|
+
signal: AbortSignal.timeout(Math.min(ready.timeoutMs, WORKSPACE_READY_ATTEMPT_TIMEOUT_MS))
|
|
3380
3381
|
});
|
|
3381
3382
|
return ready.expectStatus.includes(response.status);
|
|
3382
3383
|
};
|
|
@@ -3388,7 +3389,7 @@ var probeTcpReady = async (ready) => new Promise((resolveProbe) => {
|
|
|
3388
3389
|
const timeout = setTimeout(() => {
|
|
3389
3390
|
socket.destroy();
|
|
3390
3391
|
resolveProbe(false);
|
|
3391
|
-
}, Math.min(ready.timeoutMs,
|
|
3392
|
+
}, Math.min(ready.timeoutMs, WORKSPACE_READY_ATTEMPT_TIMEOUT_MS));
|
|
3392
3393
|
socket.once("connect", () => {
|
|
3393
3394
|
clearTimeout(timeout);
|
|
3394
3395
|
socket.end();
|
|
@@ -3412,7 +3413,7 @@ var probeCommandReady = async (ready, service) => {
|
|
|
3412
3413
|
try {
|
|
3413
3414
|
processHandle.kill();
|
|
3414
3415
|
} catch {}
|
|
3415
|
-
}, Math.min(ready.timeoutMs,
|
|
3416
|
+
}, Math.min(ready.timeoutMs, WORKSPACE_READY_ATTEMPT_TIMEOUT_MS));
|
|
3416
3417
|
try {
|
|
3417
3418
|
const exitCode = await processHandle.exited;
|
|
3418
3419
|
return exitCode === 0;
|
|
@@ -3431,16 +3432,24 @@ var waitForReady = async (service) => {
|
|
|
3431
3432
|
}
|
|
3432
3433
|
const startedAt = Date.now();
|
|
3433
3434
|
while (Date.now() - startedAt < resolved.timeoutMs) {
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
return;
|
|
3438
|
-
}
|
|
3439
|
-
} catch {}
|
|
3435
|
+
if (await probeReady(resolved, service)) {
|
|
3436
|
+
return;
|
|
3437
|
+
}
|
|
3440
3438
|
await sleep(resolved.intervalMs);
|
|
3441
3439
|
}
|
|
3442
3440
|
throw new Error(resolved.type === "http" ? `service did not become ready within ${resolved.timeoutMs}ms (${resolved.url})` : resolved.type === "tcp" ? `service did not become ready within ${resolved.timeoutMs}ms (tcp://${resolved.host}:${resolved.port})` : `service did not become ready within ${resolved.timeoutMs}ms (${resolved.command.join(" ")})`);
|
|
3443
3441
|
};
|
|
3442
|
+
var probeReady = async (resolved, service) => {
|
|
3443
|
+
try {
|
|
3444
|
+
if (resolved.type === "http")
|
|
3445
|
+
return probeHttpReady(resolved);
|
|
3446
|
+
if (resolved.type === "tcp")
|
|
3447
|
+
return probeTcpReady(resolved);
|
|
3448
|
+
return probeCommandReady(resolved, service);
|
|
3449
|
+
} catch {
|
|
3450
|
+
return false;
|
|
3451
|
+
}
|
|
3452
|
+
};
|
|
3444
3453
|
var resolveShutdownHook = (shutdown) => {
|
|
3445
3454
|
if (!shutdown) {
|
|
3446
3455
|
return null;
|
|
@@ -3448,12 +3457,12 @@ var resolveShutdownHook = (shutdown) => {
|
|
|
3448
3457
|
if (Array.isArray(shutdown)) {
|
|
3449
3458
|
return {
|
|
3450
3459
|
command: shutdown,
|
|
3451
|
-
timeoutMs:
|
|
3460
|
+
timeoutMs: WORKSPACE_SHUTDOWN_TIMEOUT_MS
|
|
3452
3461
|
};
|
|
3453
3462
|
}
|
|
3454
3463
|
return {
|
|
3455
3464
|
command: shutdown.command,
|
|
3456
|
-
timeoutMs: shutdown.timeoutMs ??
|
|
3465
|
+
timeoutMs: shutdown.timeoutMs ?? WORKSPACE_SHUTDOWN_TIMEOUT_MS
|
|
3457
3466
|
};
|
|
3458
3467
|
};
|
|
3459
3468
|
var runShutdownHook = async (service, onLog) => {
|
|
@@ -3477,11 +3486,7 @@ var runShutdownHook = async (service, onLog) => {
|
|
|
3477
3486
|
}, hook.timeoutMs);
|
|
3478
3487
|
try {
|
|
3479
3488
|
const exitCode = await processHandle.exited;
|
|
3480
|
-
|
|
3481
|
-
onLog("workspace", `${service.name} shutdown hook finished.`, "success");
|
|
3482
|
-
return;
|
|
3483
|
-
}
|
|
3484
|
-
onLog("workspace", `${service.name} shutdown hook exited with code ${exitCode || 1}.`, "warn");
|
|
3489
|
+
onLog("workspace", exitCode === 0 ? `${service.name} shutdown hook finished.` : `${service.name} shutdown hook exited with code ${exitCode || 1}.`, exitCode === 0 ? "success" : "warn");
|
|
3485
3490
|
} finally {
|
|
3486
3491
|
clearTimeout(timeout);
|
|
3487
3492
|
}
|
|
@@ -3521,36 +3526,38 @@ var pipeProcessLogs = (name, processHandle, appendLog) => {
|
|
|
3521
3526
|
const forward = async (stream, level) => {
|
|
3522
3527
|
let buffer = "";
|
|
3523
3528
|
const reader = stream.getReader();
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
break;
|
|
3529
|
-
}
|
|
3530
|
-
if (!value) {
|
|
3531
|
-
continue;
|
|
3532
|
-
}
|
|
3533
|
-
buffer += Buffer.from(value).toString();
|
|
3534
|
-
const lines = buffer.split(`
|
|
3535
|
-
`);
|
|
3536
|
-
buffer = lines.pop() ?? "";
|
|
3537
|
-
for (const line of lines) {
|
|
3538
|
-
if (line.trim().length === 0) {
|
|
3539
|
-
continue;
|
|
3540
|
-
}
|
|
3541
|
-
appendLog(name, line, level);
|
|
3542
|
-
}
|
|
3543
|
-
}
|
|
3544
|
-
} finally {
|
|
3545
|
-
if (buffer.trim().length > 0) {
|
|
3546
|
-
appendLog(name, buffer, level);
|
|
3547
|
-
}
|
|
3548
|
-
reader.releaseLock();
|
|
3529
|
+
let chunk = await readLogChunk(reader);
|
|
3530
|
+
while (chunk !== null) {
|
|
3531
|
+
buffer = appendLogChunk(buffer, chunk, name, level, appendLog);
|
|
3532
|
+
chunk = await readLogChunk(reader);
|
|
3549
3533
|
}
|
|
3534
|
+
appendRemainingLogBuffer(buffer, name, level, appendLog);
|
|
3535
|
+
reader.releaseLock();
|
|
3550
3536
|
};
|
|
3551
3537
|
forward(processHandle.stdout, "info");
|
|
3552
3538
|
forward(processHandle.stderr, "error");
|
|
3553
3539
|
};
|
|
3540
|
+
var readLogChunk = async (reader) => {
|
|
3541
|
+
const { done, value } = await reader.read();
|
|
3542
|
+
if (done)
|
|
3543
|
+
return null;
|
|
3544
|
+
if (!value)
|
|
3545
|
+
return "";
|
|
3546
|
+
return Buffer.from(value).toString();
|
|
3547
|
+
};
|
|
3548
|
+
var appendLogChunk = (buffer, chunk, name, level, appendLog) => {
|
|
3549
|
+
const lines = `${buffer}${chunk}`.split(`
|
|
3550
|
+
`);
|
|
3551
|
+
const nextBuffer = lines.pop() ?? "";
|
|
3552
|
+
lines.filter((line) => line.trim().length > 0).forEach((line) => appendLog(name, line, level));
|
|
3553
|
+
return nextBuffer;
|
|
3554
|
+
};
|
|
3555
|
+
var appendRemainingLogBuffer = (buffer, name, level, appendLog) => {
|
|
3556
|
+
if (buffer.trim().length === 0) {
|
|
3557
|
+
return;
|
|
3558
|
+
}
|
|
3559
|
+
appendLog(name, buffer, level);
|
|
3560
|
+
};
|
|
3554
3561
|
var getServicePublicHost = (service) => {
|
|
3555
3562
|
const host = service.env?.HOST ?? process.env.HOST ?? "localhost";
|
|
3556
3563
|
if (host === "0.0.0.0" || host === "::") {
|
|
@@ -3561,35 +3568,37 @@ var getServicePublicHost = (service) => {
|
|
|
3561
3568
|
var getServiceProtocol = (service) => service.env?.ABSOLUTE_HTTPS === "true" || process.env.ABSOLUTE_HTTPS === "true" ? "https" : "http";
|
|
3562
3569
|
var createWorkspaceServiceEnv = (services) => {
|
|
3563
3570
|
const workspaceEnv = {};
|
|
3564
|
-
for (const [name, service] of Object.entries(services)) {
|
|
3565
|
-
if (!service.port) {
|
|
3566
|
-
continue;
|
|
3567
|
-
}
|
|
3571
|
+
for (const [name, service] of Object.entries(services).filter(([, service2]) => Boolean(service2.port))) {
|
|
3568
3572
|
const envKey = `ABSOLUTE_SERVICE_${name.toUpperCase().replace(/[^A-Z0-9]+/g, "_")}_URL`;
|
|
3569
3573
|
workspaceEnv[envKey] = `${getServiceProtocol(service)}://${getServicePublicHost(service)}:${service.port}`;
|
|
3570
3574
|
}
|
|
3571
3575
|
return workspaceEnv;
|
|
3572
3576
|
};
|
|
3577
|
+
var getDefinedProcessEnv = () => Object.fromEntries(Object.entries(process.env).filter((entry) => typeof entry[1] === "string"));
|
|
3578
|
+
var resolveAbsoluteServiceConfigPath = (service, cwd, options) => {
|
|
3579
|
+
if (service.config)
|
|
3580
|
+
return resolve6(cwd, service.config);
|
|
3581
|
+
if (options.configPath)
|
|
3582
|
+
return resolve6(options.configPath);
|
|
3583
|
+
if (process.env.ABSOLUTE_CONFIG)
|
|
3584
|
+
return resolve6(process.env.ABSOLUTE_CONFIG);
|
|
3585
|
+
return;
|
|
3586
|
+
};
|
|
3573
3587
|
var resolveService = (name, service, workspaceEnv, options) => {
|
|
3574
3588
|
const cwd = resolve6(service.cwd ?? ".");
|
|
3575
|
-
const envVars = {
|
|
3576
|
-
...process.env,
|
|
3577
|
-
...workspaceEnv,
|
|
3578
|
-
...service.env,
|
|
3589
|
+
const envVars = Object.assign(getDefinedProcessEnv(), workspaceEnv, service.env, {
|
|
3579
3590
|
ABSOLUTE_WORKSPACE_MANAGED: "1",
|
|
3580
3591
|
ABSOLUTE_WORKSPACE_SERVICE_NAME: name,
|
|
3581
3592
|
ABSOLUTE_WORKSPACE_SERVICE_VISIBILITY: getVisibility(service),
|
|
3582
3593
|
FORCE_COLOR: "1",
|
|
3583
3594
|
NODE_ENV: "development"
|
|
3584
|
-
};
|
|
3595
|
+
});
|
|
3585
3596
|
if (service.port && !envVars.PORT) {
|
|
3586
3597
|
envVars.PORT = String(service.port);
|
|
3587
3598
|
}
|
|
3588
3599
|
if (isAbsoluteService(service)) {
|
|
3589
|
-
const configPath2 = service
|
|
3590
|
-
|
|
3591
|
-
envVars.ABSOLUTE_CONFIG = configPath2;
|
|
3592
|
-
}
|
|
3600
|
+
const configPath2 = resolveAbsoluteServiceConfigPath(service, cwd, options);
|
|
3601
|
+
Object.assign(envVars, configPath2 ? { ABSOLUTE_CONFIG: configPath2 } : {});
|
|
3593
3602
|
const command = [
|
|
3594
3603
|
process.execPath,
|
|
3595
3604
|
"--hot",
|
|
@@ -3656,30 +3665,43 @@ var workspace = async (subcommand, options) => {
|
|
|
3656
3665
|
});
|
|
3657
3666
|
const workspaceLogs = createWorkspaceLogSink(tui.addLog);
|
|
3658
3667
|
const addLog = workspaceLogs.appendLog;
|
|
3668
|
+
const killProcess = (service) => {
|
|
3669
|
+
try {
|
|
3670
|
+
service.process.kill();
|
|
3671
|
+
} catch {}
|
|
3672
|
+
};
|
|
3673
|
+
const runShutdownHookSafely = async (service) => {
|
|
3674
|
+
try {
|
|
3675
|
+
await runShutdownHook(service.resolved, addLog);
|
|
3676
|
+
} catch (error) {
|
|
3677
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3678
|
+
addLog("workspace", `${service.name} shutdown hook failed: ${message}`, "warn");
|
|
3679
|
+
}
|
|
3680
|
+
};
|
|
3659
3681
|
const killProcesses = async () => {
|
|
3660
3682
|
const snapshot = [...running];
|
|
3661
3683
|
running.length = 0;
|
|
3662
|
-
|
|
3663
|
-
try {
|
|
3664
|
-
service.process.kill();
|
|
3665
|
-
} catch {}
|
|
3666
|
-
}
|
|
3684
|
+
snapshot.forEach((service) => killProcess(service));
|
|
3667
3685
|
await Promise.all(snapshot.map((service) => service.process.exited));
|
|
3668
3686
|
for (const service of snapshot.reverse()) {
|
|
3669
|
-
|
|
3670
|
-
await runShutdownHook(service.resolved, addLog);
|
|
3671
|
-
} catch (error) {
|
|
3672
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3673
|
-
addLog("workspace", `${service.name} shutdown hook failed: ${message}`, "warn");
|
|
3674
|
-
}
|
|
3687
|
+
await runShutdownHookSafely(service);
|
|
3675
3688
|
}
|
|
3676
3689
|
};
|
|
3690
|
+
const appendRecentLogs = (lines, logsToPrint) => {
|
|
3691
|
+
if (logsToPrint.length === 0) {
|
|
3692
|
+
return;
|
|
3693
|
+
}
|
|
3694
|
+
lines.push("", "Recent logs:");
|
|
3695
|
+
logsToPrint.forEach((entry) => {
|
|
3696
|
+
lines.push(` ${entry.timestamp} [${entry.source}] ${entry.message}`);
|
|
3697
|
+
});
|
|
3698
|
+
};
|
|
3677
3699
|
const printFailureSummary = (exitCode) => {
|
|
3678
3700
|
const servicesSnapshot = tui.getServiceSnapshot();
|
|
3679
|
-
const recentLogs = tui.getRecentLogs(
|
|
3701
|
+
const recentLogs = tui.getRecentLogs(WORKSPACE_FAILURE_RECENT_LOG_LIMIT);
|
|
3680
3702
|
const failedServices = servicesSnapshot.filter((service) => service.status === "error");
|
|
3681
3703
|
const relevantLogs = recentLogs.filter((entry) => entry.level === "error" || entry.level === "warn" || entry.source === "workspace" || failedServices.some((service) => service.name === entry.source));
|
|
3682
|
-
const logsToPrint = (relevantLogs.length > 0 ? relevantLogs : recentLogs).slice(-
|
|
3704
|
+
const logsToPrint = (relevantLogs.length > 0 ? relevantLogs : recentLogs).slice(-WORKSPACE_FAILURE_LOG_PRINT_LIMIT);
|
|
3683
3705
|
const lines = [
|
|
3684
3706
|
"",
|
|
3685
3707
|
`\x1B[31mABSOLUTEJS WORKSPACE exited with code ${exitCode}\x1B[0m`,
|
|
@@ -3690,12 +3712,7 @@ var workspace = async (subcommand, options) => {
|
|
|
3690
3712
|
return ` - ${service.name}: ${service.status} \xB7 ${service.target}${detail}`;
|
|
3691
3713
|
})
|
|
3692
3714
|
];
|
|
3693
|
-
|
|
3694
|
-
lines.push("", "Recent logs:");
|
|
3695
|
-
for (const entry of logsToPrint) {
|
|
3696
|
-
lines.push(` ${entry.timestamp} [${entry.source}] ${entry.message}`);
|
|
3697
|
-
}
|
|
3698
|
-
}
|
|
3715
|
+
appendRecentLogs(lines, logsToPrint);
|
|
3699
3716
|
lines.push("");
|
|
3700
3717
|
process.stderr.write(`${lines.join(`
|
|
3701
3718
|
`)}
|
|
@@ -3710,6 +3727,34 @@ var workspace = async (subcommand, options) => {
|
|
|
3710
3727
|
process.kill(processHandle.pid, signal);
|
|
3711
3728
|
} catch {}
|
|
3712
3729
|
};
|
|
3730
|
+
const resumeRunningServices = () => {
|
|
3731
|
+
running.forEach((service) => {
|
|
3732
|
+
sendSignalToService(service.process, "SIGCONT");
|
|
3733
|
+
});
|
|
3734
|
+
paused = false;
|
|
3735
|
+
};
|
|
3736
|
+
const markRunningServicesReady = () => {
|
|
3737
|
+
running.forEach((service) => {
|
|
3738
|
+
readyServiceNames.add(service.name);
|
|
3739
|
+
tui.setServiceStatus(service.name, "ready");
|
|
3740
|
+
});
|
|
3741
|
+
};
|
|
3742
|
+
const pauseRunningServices = () => {
|
|
3743
|
+
running.forEach((service) => {
|
|
3744
|
+
sendSignalToService(service.process, "SIGSTOP");
|
|
3745
|
+
readyServiceNames.delete(service.name);
|
|
3746
|
+
tui.setServiceStatus(service.name, "paused");
|
|
3747
|
+
});
|
|
3748
|
+
paused = true;
|
|
3749
|
+
};
|
|
3750
|
+
const killStaleServicePort = (port) => {
|
|
3751
|
+
if (port <= 0) {
|
|
3752
|
+
return;
|
|
3753
|
+
}
|
|
3754
|
+
killStaleProcesses(port, (message) => {
|
|
3755
|
+
addLog("workspace", message, "warn");
|
|
3756
|
+
});
|
|
3757
|
+
};
|
|
3713
3758
|
const shutdown = async (exitCode = 0) => {
|
|
3714
3759
|
if (shuttingDown) {
|
|
3715
3760
|
return;
|
|
@@ -3721,10 +3766,7 @@ var workspace = async (subcommand, options) => {
|
|
|
3721
3766
|
printFailureSummary(exitCode);
|
|
3722
3767
|
}
|
|
3723
3768
|
if (paused) {
|
|
3724
|
-
|
|
3725
|
-
sendSignalToService(service.process, "SIGCONT");
|
|
3726
|
-
}
|
|
3727
|
-
paused = false;
|
|
3769
|
+
resumeRunningServices();
|
|
3728
3770
|
}
|
|
3729
3771
|
await killProcesses();
|
|
3730
3772
|
process.exit(exitCode);
|
|
@@ -3738,11 +3780,7 @@ var workspace = async (subcommand, options) => {
|
|
|
3738
3780
|
}
|
|
3739
3781
|
const resolved = resolveService(name, service, workspaceEnv, options);
|
|
3740
3782
|
const port = (resolved.service.port ?? Number(resolved.env.PORT ?? "")) || DEFAULT_PORT;
|
|
3741
|
-
|
|
3742
|
-
killStaleProcesses(port, (message) => {
|
|
3743
|
-
addLog("workspace", message, "warn");
|
|
3744
|
-
});
|
|
3745
|
-
}
|
|
3783
|
+
killStaleServicePort(port);
|
|
3746
3784
|
if (isAbsoluteService(resolved.service) && resolved.configPath && !existsSync8(resolved.configPath)) {
|
|
3747
3785
|
throw new Error(`${name} references missing config "${resolved.configPath}"`);
|
|
3748
3786
|
}
|
|
@@ -3788,10 +3826,7 @@ var workspace = async (subcommand, options) => {
|
|
|
3788
3826
|
}
|
|
3789
3827
|
restarting = true;
|
|
3790
3828
|
if (paused) {
|
|
3791
|
-
|
|
3792
|
-
sendSignalToService(service.process, "SIGCONT");
|
|
3793
|
-
}
|
|
3794
|
-
paused = false;
|
|
3829
|
+
resumeRunningServices();
|
|
3795
3830
|
}
|
|
3796
3831
|
addLog("workspace", "Restarting workspace...", "info");
|
|
3797
3832
|
readyServiceNames.clear();
|
|
@@ -3806,20 +3841,12 @@ var workspace = async (subcommand, options) => {
|
|
|
3806
3841
|
};
|
|
3807
3842
|
const togglePause = () => {
|
|
3808
3843
|
if (paused) {
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
readyServiceNames.add(service.name);
|
|
3812
|
-
tui.setServiceStatus(service.name, "ready");
|
|
3813
|
-
}
|
|
3844
|
+
resumeRunningServices();
|
|
3845
|
+
markRunningServicesReady();
|
|
3814
3846
|
paused = false;
|
|
3815
3847
|
addLog("workspace", "Workspace resumed.", "success");
|
|
3816
3848
|
} else {
|
|
3817
|
-
|
|
3818
|
-
sendSignalToService(service.process, "SIGSTOP");
|
|
3819
|
-
readyServiceNames.delete(service.name);
|
|
3820
|
-
tui.setServiceStatus(service.name, "paused");
|
|
3821
|
-
}
|
|
3822
|
-
paused = true;
|
|
3849
|
+
pauseRunningServices();
|
|
3823
3850
|
addLog("workspace", "Workspace paused.", "warn");
|
|
3824
3851
|
}
|
|
3825
3852
|
};
|
|
@@ -3885,7 +3912,7 @@ init_telemetryEvent();
|
|
|
3885
3912
|
init_constants();
|
|
3886
3913
|
init_utils();
|
|
3887
3914
|
var [command] = process.argv.slice(2);
|
|
3888
|
-
var [workspaceCommand] = process.argv.slice(
|
|
3915
|
+
var [workspaceCommand] = process.argv.slice(WORKSPACE_COMMAND_ARGS_OFFSET);
|
|
3889
3916
|
var args = process.argv.slice(CLI_ARGS_OFFSET);
|
|
3890
3917
|
var parseNamedArg = (flag) => {
|
|
3891
3918
|
const idx = args.indexOf(flag);
|