@absolutejs/absolute 0.19.0-beta.705 → 0.19.0-beta.707
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/browser.js +6 -4
- package/dist/angular/browser.js.map +3 -3
- package/dist/angular/components/constants.js +1 -0
- package/dist/angular/index.js +17 -10
- package/dist/angular/index.js.map +5 -5
- package/dist/angular/server.js +17 -10
- package/dist/angular/server.js.map +5 -5
- package/dist/build.js +126 -66
- package/dist/build.js.map +12 -12
- package/dist/cli/index.js +186 -126
- package/dist/dev/client/cssUtils.ts +47 -47
- package/dist/dev/client/handlers/angular.ts +40 -19
- package/dist/dev/client/handlers/angularRuntime.ts +28 -8
- package/dist/dev/client/handlers/html.ts +6 -5
- package/dist/dev/client/handlers/htmx.ts +8 -2
- package/dist/dev/client/handlers/svelte.ts +16 -14
- package/dist/dev/client/hmrClient.ts +25 -3
- package/dist/dev/client/reactRefreshSetup.ts +2 -3
- package/dist/index.js +151 -79
- package/dist/index.js.map +14 -14
- package/dist/islands/index.js +4 -4
- package/dist/islands/index.js.map +4 -4
- package/dist/react/index.js +17 -10
- package/dist/react/index.js.map +5 -5
- package/dist/react/server.js +15 -8
- package/dist/react/server.js.map +4 -4
- package/dist/src/angular/components/constants.d.ts +1 -0
- package/dist/src/build/buildAngularVendor.d.ts +3 -4
- package/dist/src/constants.d.ts +1 -0
- package/dist/src/utils/imageProcessing.d.ts +1 -1
- package/dist/src/vue/components/Image.d.ts +1 -1
- package/dist/svelte/index.js +17 -10
- package/dist/svelte/index.js.map +5 -5
- package/dist/svelte/server.js +15 -8
- package/dist/svelte/server.js.map +4 -4
- package/dist/types/globals.d.ts +1 -0
- package/dist/vue/index.js +17 -10
- package/dist/vue/index.js.map +5 -5
- package/dist/vue/server.js +15 -8
- package/dist/vue/server.js.map +4 -4
- package/package.json +1 -1
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, 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;
|
|
21
|
+
var ANSI_ESCAPE_CODE = 27, 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;
|
|
@@ -853,12 +853,15 @@ var cliTag3 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
853
853
|
return null;
|
|
854
854
|
}
|
|
855
855
|
}, resolveBuildModule2 = async (candidates) => {
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
return mod;
|
|
856
|
+
const [candidate, ...remaining] = candidates;
|
|
857
|
+
if (!candidate) {
|
|
858
|
+
return;
|
|
860
859
|
}
|
|
861
|
-
|
|
860
|
+
const mod = await tryImportBuild2(candidate);
|
|
861
|
+
if (mod) {
|
|
862
|
+
return mod;
|
|
863
|
+
}
|
|
864
|
+
return resolveBuildModule2(remaining);
|
|
862
865
|
}, resolveJsxDevRuntimeCompatPath2 = () => {
|
|
863
866
|
const candidates = [
|
|
864
867
|
resolve7(import.meta.dir, "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
|
|
@@ -1203,7 +1206,7 @@ var isCommandService3 = (service) => service.kind === "command" || Array.isArray
|
|
|
1203
1206
|
}, shellEscape = (value) => `'${value.replaceAll("'", "'\\''")}'`, runShell = async (name, command) => run(name, ["/bin/bash", "-lc", command]), findBin = (name) => {
|
|
1204
1207
|
const local = resolve8("node_modules", ".bin", name);
|
|
1205
1208
|
return existsSync10(local) ? local : null;
|
|
1206
|
-
}, stripAnsi3 = (str) => str.replace(
|
|
1209
|
+
}, ANSI_COLOR_REGEX, ANSI_PURPLE_REGEX, ANSI_CYAN_REGEX, ANSI_TOKEN_END_REGEX, stripAnsi3 = (str) => str.replace(ANSI_COLOR_REGEX, ""), formatSvelteOutput = (output) => {
|
|
1207
1210
|
const cwd = `${process.cwd()}/`;
|
|
1208
1211
|
const summaryMatch = stripAnsi3(output).match(/svelte-check found (\d+) error/);
|
|
1209
1212
|
const errorCount = summaryMatch ? parseInt(summaryMatch[1] ?? "0", 10) : 0;
|
|
@@ -1220,10 +1223,10 @@ var isCommandService3 = (service) => service.kind === "command" || Array.isArray
|
|
|
1220
1223
|
`\x1B[96m${pathMatch[1]}\x1B[0m:\x1B[93m${pathMatch[2]}\x1B[0m`
|
|
1221
1224
|
];
|
|
1222
1225
|
}
|
|
1223
|
-
if (result.includes(
|
|
1226
|
+
if (result.includes(ANSI_PURPLE_REGEX)) {
|
|
1224
1227
|
const plainLine = stripAnsi3(result);
|
|
1225
|
-
const before = stripAnsi3(result.split(
|
|
1226
|
-
const token = stripAnsi3((result.split(
|
|
1228
|
+
const before = stripAnsi3(result.split(ANSI_PURPLE_REGEX)[0] ?? "");
|
|
1229
|
+
const token = stripAnsi3((result.split(ANSI_PURPLE_REGEX)[1] ?? "").split(ANSI_TOKEN_END_REGEX)[0] ?? "");
|
|
1227
1230
|
if (!token)
|
|
1228
1231
|
return [result];
|
|
1229
1232
|
const expanded = before.replace(/\t/g, " ");
|
|
@@ -1234,7 +1237,7 @@ var isCommandService3 = (service) => service.kind === "command" || Array.isArray
|
|
|
1234
1237
|
`${" ".repeat(expanded.length)}\x1B[91m${underline}\x1B[0m`
|
|
1235
1238
|
];
|
|
1236
1239
|
}
|
|
1237
|
-
if (
|
|
1240
|
+
if (ANSI_CYAN_REGEX.test(result) && !result.includes("Error") && !result.includes(ANSI_PURPLE_REGEX)) {
|
|
1238
1241
|
return [];
|
|
1239
1242
|
}
|
|
1240
1243
|
return [result];
|
|
@@ -1377,6 +1380,11 @@ Found ${errorCount} error${suffix}.`;
|
|
|
1377
1380
|
};
|
|
1378
1381
|
var init_typecheck = __esm(() => {
|
|
1379
1382
|
init_loadConfig();
|
|
1383
|
+
init_constants();
|
|
1384
|
+
ANSI_COLOR_REGEX = new RegExp(`${String.fromCharCode(ANSI_ESCAPE_CODE)}\\[[0-9;]*m`, "g");
|
|
1385
|
+
ANSI_PURPLE_REGEX = `${String.fromCharCode(ANSI_ESCAPE_CODE)}[35m`;
|
|
1386
|
+
ANSI_CYAN_REGEX = new RegExp(`^${String.fromCharCode(ANSI_ESCAPE_CODE)}\\[36m|\\t`);
|
|
1387
|
+
ANSI_TOKEN_END_REGEX = new RegExp(`${String.fromCharCode(ANSI_ESCAPE_CODE)}\\[3[69]m`);
|
|
1380
1388
|
TYPECHECK_EXCLUDE = [
|
|
1381
1389
|
"../node_modules/**/*",
|
|
1382
1390
|
"../**/.absolutejs/**/*",
|
|
@@ -1431,7 +1439,10 @@ var trySetRawMode = () => {
|
|
|
1431
1439
|
} catch {
|
|
1432
1440
|
return null;
|
|
1433
1441
|
}
|
|
1434
|
-
return
|
|
1442
|
+
return {
|
|
1443
|
+
destroyOnDispose: false,
|
|
1444
|
+
stream: process.stdin
|
|
1445
|
+
};
|
|
1435
1446
|
};
|
|
1436
1447
|
var openTtyStream = () => {
|
|
1437
1448
|
const fromStdin = trySetRawMode();
|
|
@@ -1441,7 +1452,10 @@ var openTtyStream = () => {
|
|
|
1441
1452
|
try {
|
|
1442
1453
|
const ttyStream = new ReadStream(openSync("/dev/tty", "r"));
|
|
1443
1454
|
ttyStream.setRawMode(true);
|
|
1444
|
-
return
|
|
1455
|
+
return {
|
|
1456
|
+
destroyOnDispose: true,
|
|
1457
|
+
stream: ttyStream
|
|
1458
|
+
};
|
|
1445
1459
|
} catch {
|
|
1446
1460
|
return null;
|
|
1447
1461
|
}
|
|
@@ -1633,19 +1647,19 @@ var createInteractiveHandler = (actions) => {
|
|
|
1633
1647
|
processChar(str.charAt(idx));
|
|
1634
1648
|
}
|
|
1635
1649
|
};
|
|
1636
|
-
const
|
|
1637
|
-
const input =
|
|
1650
|
+
const ttyInput = openTtyStream();
|
|
1651
|
+
const input = ttyInput?.stream ?? process.stdin;
|
|
1638
1652
|
input.resume();
|
|
1639
1653
|
input.on("data", onData);
|
|
1640
1654
|
const disposeTtyStream = () => {
|
|
1641
|
-
if (!
|
|
1655
|
+
if (!ttyInput) {
|
|
1642
1656
|
return;
|
|
1643
1657
|
}
|
|
1644
1658
|
try {
|
|
1645
|
-
|
|
1659
|
+
ttyInput.stream.setRawMode?.(false);
|
|
1646
1660
|
} catch {}
|
|
1647
|
-
if (
|
|
1648
|
-
|
|
1661
|
+
if (ttyInput.destroyOnDispose) {
|
|
1662
|
+
ttyInput.stream.destroy?.();
|
|
1649
1663
|
}
|
|
1650
1664
|
};
|
|
1651
1665
|
const dispose = () => {
|
|
@@ -2196,9 +2210,7 @@ var runTool = async (adapter, args) => {
|
|
|
2196
2210
|
batches.push(changed.slice(idx, idx + MAX_FILES_PER_BATCH));
|
|
2197
2211
|
}
|
|
2198
2212
|
const failedFiles = new Set;
|
|
2199
|
-
|
|
2200
|
-
await runBatch(adapter, batch, args, failedFiles);
|
|
2201
|
-
}
|
|
2213
|
+
await batches.reduce((chain, batch) => chain.then(() => runBatch(adapter, batch, args, failedFiles)), Promise.resolve());
|
|
2202
2214
|
for (const file of failedFiles) {
|
|
2203
2215
|
delete cache.files[file];
|
|
2204
2216
|
}
|
|
@@ -2278,13 +2290,15 @@ var readPackageVersion2 = (candidate) => {
|
|
|
2278
2290
|
return null;
|
|
2279
2291
|
};
|
|
2280
2292
|
var resolveBuildModule = async (candidates) => {
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
return mod;
|
|
2285
|
-
}
|
|
2293
|
+
const [candidate, ...remaining] = candidates;
|
|
2294
|
+
if (!candidate) {
|
|
2295
|
+
return;
|
|
2286
2296
|
}
|
|
2287
|
-
|
|
2297
|
+
const mod = await tryImportBuild(candidate);
|
|
2298
|
+
if (mod) {
|
|
2299
|
+
return mod;
|
|
2300
|
+
}
|
|
2301
|
+
return resolveBuildModule(remaining);
|
|
2288
2302
|
};
|
|
2289
2303
|
var tryImportBuild = async (candidate) => {
|
|
2290
2304
|
try {
|
|
@@ -2574,7 +2588,8 @@ import { openSync as openSync2 } from "fs";
|
|
|
2574
2588
|
import { ReadStream as ReadStream2 } from "tty";
|
|
2575
2589
|
var MAX_LOG_ENTRIES = 400;
|
|
2576
2590
|
var ESCAPE = "\x1B";
|
|
2577
|
-
var ANSI_REGEX =
|
|
2591
|
+
var ANSI_REGEX = new RegExp(`${String.fromCharCode(ANSI_ESCAPE_CODE)}\\[[0-?]*[ -/]*[@-~]`, "g");
|
|
2592
|
+
var ANSI_ESCAPE_PREFIX = `${ESCAPE}[`;
|
|
2578
2593
|
var SHORTCUTS2 = new Map([
|
|
2579
2594
|
["c", "clear"],
|
|
2580
2595
|
["h", "help"],
|
|
@@ -2766,6 +2781,17 @@ var getWorkspaceStatus = (services) => {
|
|
|
2766
2781
|
}
|
|
2767
2782
|
return "ready";
|
|
2768
2783
|
};
|
|
2784
|
+
var getVisibleLogContent = (contentLines, logHeight, logScrollOffset) => {
|
|
2785
|
+
const end = Math.max(0, contentLines.length - logScrollOffset);
|
|
2786
|
+
const start2 = Math.max(0, end - logHeight);
|
|
2787
|
+
return contentLines.slice(start2, end);
|
|
2788
|
+
};
|
|
2789
|
+
var isPartialEscapeSequence = (value) => {
|
|
2790
|
+
if (!value.startsWith(ANSI_ESCAPE_PREFIX)) {
|
|
2791
|
+
return false;
|
|
2792
|
+
}
|
|
2793
|
+
return Array.from(value.slice(ANSI_ESCAPE_PREFIX.length)).every((char) => char >= "0" && char <= "9");
|
|
2794
|
+
};
|
|
2769
2795
|
var createWorkspaceTui = ({
|
|
2770
2796
|
actions,
|
|
2771
2797
|
services,
|
|
@@ -2889,11 +2915,7 @@ var createWorkspaceTui = ({
|
|
|
2889
2915
|
lastLogViewportHeight = logHeight;
|
|
2890
2916
|
logScrollOffset = Math.min(logScrollOffset, Math.max(0, contentLines.length - logHeight));
|
|
2891
2917
|
}
|
|
2892
|
-
const visibleContent = helpVisible ? contentLines.slice(0, logHeight) : (
|
|
2893
|
-
const end = Math.max(0, contentLines.length - logScrollOffset);
|
|
2894
|
-
const start3 = Math.max(0, end - logHeight);
|
|
2895
|
-
return contentLines.slice(start3, end);
|
|
2896
|
-
})();
|
|
2918
|
+
const visibleContent = helpVisible ? contentLines.slice(0, logHeight) : getVisibleLogContent(contentLines, logHeight, logScrollOffset);
|
|
2897
2919
|
const maxLogScrollOffset = !helpVisible ? Math.max(0, contentLines.length - logHeight) : 0;
|
|
2898
2920
|
const shouldShowScrollbar = !helpVisible && maxLogScrollOffset > 0;
|
|
2899
2921
|
const scrollbarThumbHeight = shouldShowScrollbar ? Math.max(1, Math.min(logHeight, Math.round(logHeight / contentLines.length * logHeight))) : 0;
|
|
@@ -3086,7 +3108,7 @@ var createWorkspaceTui = ({
|
|
|
3086
3108
|
handleScrollEscape("end");
|
|
3087
3109
|
return;
|
|
3088
3110
|
}
|
|
3089
|
-
if (
|
|
3111
|
+
if (isPartialEscapeSequence(escapeBuffer)) {
|
|
3090
3112
|
armEscapeTimer();
|
|
3091
3113
|
return;
|
|
3092
3114
|
}
|
|
@@ -3154,16 +3176,15 @@ var createWorkspaceTui = ({
|
|
|
3154
3176
|
}
|
|
3155
3177
|
await handlePrintableChar(char);
|
|
3156
3178
|
};
|
|
3179
|
+
const processInputChars = async (chars) => {
|
|
3180
|
+
await Array.from(chars).reduce((chain, char) => chain.then(() => handleChar(char)), Promise.resolve());
|
|
3181
|
+
};
|
|
3157
3182
|
const onResize = () => {
|
|
3158
3183
|
scheduleRender();
|
|
3159
3184
|
};
|
|
3160
3185
|
const onData = (chunk) => {
|
|
3161
3186
|
const chars = chunk.toString();
|
|
3162
|
-
(
|
|
3163
|
-
for (const char of chars) {
|
|
3164
|
-
await handleChar(char);
|
|
3165
|
-
}
|
|
3166
|
-
})();
|
|
3187
|
+
processInputChars(chars);
|
|
3167
3188
|
};
|
|
3168
3189
|
const start2 = () => {
|
|
3169
3190
|
process.stdout.write("\x1B[?1049h\x1B[2J\x1B[H\x1B[?25l");
|
|
@@ -3215,8 +3236,8 @@ var createWorkspaceTui = ({
|
|
|
3215
3236
|
|
|
3216
3237
|
// src/cli/scripts/workspace.ts
|
|
3217
3238
|
init_utils();
|
|
3218
|
-
var ANSI_REGEX2 =
|
|
3219
|
-
var sleep = (
|
|
3239
|
+
var ANSI_REGEX2 = new RegExp(`${String.fromCharCode(ANSI_ESCAPE_CODE)}\\[[0-?]*[ -/]*[@-~]`, "g");
|
|
3240
|
+
var sleep = (durationMs) => Bun.sleep(durationMs);
|
|
3220
3241
|
var stripAnsi2 = (value) => value.replace(ANSI_REGEX2, "");
|
|
3221
3242
|
var sanitizeLogFileName = (value) => value.replace(/[^a-zA-Z0-9._-]/g, "_") || "unknown";
|
|
3222
3243
|
var createWorkspaceLogSink = (appendLog) => {
|
|
@@ -3243,11 +3264,11 @@ var createWorkspaceLogSink = (appendLog) => {
|
|
|
3243
3264
|
appendFileSync(resolve6(logDirectory, "all.log"), line);
|
|
3244
3265
|
};
|
|
3245
3266
|
return {
|
|
3246
|
-
logDirectory,
|
|
3247
3267
|
appendLog: (source, message, level = "info") => {
|
|
3248
3268
|
writeLog(source, message, level);
|
|
3249
3269
|
appendLog(source, message, level);
|
|
3250
|
-
}
|
|
3270
|
+
},
|
|
3271
|
+
logDirectory
|
|
3251
3272
|
};
|
|
3252
3273
|
};
|
|
3253
3274
|
var readPackageVersion3 = (candidate) => {
|
|
@@ -3292,6 +3313,7 @@ var getDefaultReadyConfig = (service) => {
|
|
|
3292
3313
|
return;
|
|
3293
3314
|
};
|
|
3294
3315
|
var normalizeExpectedStatuses = (value) => Array.isArray(value) ? value : [value ?? HTTP_STATUS_OK];
|
|
3316
|
+
var runSequentially = (items, action) => items.reduce((chain, item) => chain.then(() => action(item)), Promise.resolve());
|
|
3295
3317
|
var resolveServiceHttpUrl = (service, path) => {
|
|
3296
3318
|
if (!path.startsWith("/")) {
|
|
3297
3319
|
throw new Error(`ready path must start with "/" for service probes. Received "${path}".`);
|
|
@@ -3303,17 +3325,18 @@ var resolveServiceHttpUrl = (service, path) => {
|
|
|
3303
3325
|
};
|
|
3304
3326
|
var resolveHttpReadyProbe = (service, ready) => {
|
|
3305
3327
|
if (typeof ready === "string") {
|
|
3306
|
-
if (isAbsoluteService(service)) {
|
|
3328
|
+
if (!isAbsoluteService(service)) {
|
|
3307
3329
|
return {
|
|
3308
|
-
type: "http",
|
|
3309
|
-
url: resolveServiceHttpUrl(service, ready),
|
|
3310
|
-
method: "GET",
|
|
3311
3330
|
expectStatus: [HTTP_STATUS_OK],
|
|
3312
3331
|
headers: {},
|
|
3313
3332
|
intervalMs: WORKSPACE_READY_PROBE_INTERVAL_MS,
|
|
3314
|
-
|
|
3333
|
+
method: "GET",
|
|
3334
|
+
timeoutMs: WORKSPACE_READY_TIMEOUT_MS,
|
|
3335
|
+
type: "http",
|
|
3336
|
+
url: ready
|
|
3315
3337
|
};
|
|
3316
3338
|
}
|
|
3339
|
+
const url2 = resolveServiceHttpUrl(service, ready);
|
|
3317
3340
|
return {
|
|
3318
3341
|
expectStatus: [HTTP_STATUS_OK],
|
|
3319
3342
|
headers: {},
|
|
@@ -3321,26 +3344,38 @@ var resolveHttpReadyProbe = (service, ready) => {
|
|
|
3321
3344
|
method: "GET",
|
|
3322
3345
|
timeoutMs: WORKSPACE_READY_TIMEOUT_MS,
|
|
3323
3346
|
type: "http",
|
|
3324
|
-
url:
|
|
3347
|
+
url: url2
|
|
3325
3348
|
};
|
|
3326
3349
|
}
|
|
3327
3350
|
if (ready.path && ready.url) {
|
|
3328
3351
|
throw new Error('ready HTTP probe cannot define both "path" and "url".');
|
|
3329
3352
|
}
|
|
3330
|
-
const url =
|
|
3353
|
+
const url = resolveHttpReadyProbeUrl(service, ready);
|
|
3331
3354
|
if (!url) {
|
|
3332
3355
|
throw new Error('ready HTTP probe requires either "url" or "path".');
|
|
3333
3356
|
}
|
|
3334
3357
|
return {
|
|
3335
|
-
type: "http",
|
|
3336
|
-
url,
|
|
3337
|
-
method: ready.method ?? "GET",
|
|
3338
3358
|
expectStatus: normalizeExpectedStatuses(ready.expectStatus),
|
|
3339
3359
|
headers: ready.headers ?? {},
|
|
3340
3360
|
intervalMs: ready.intervalMs ?? WORKSPACE_READY_PROBE_INTERVAL_MS,
|
|
3341
|
-
|
|
3361
|
+
method: ready.method ?? "GET",
|
|
3362
|
+
timeoutMs: ready.timeoutMs ?? WORKSPACE_READY_TIMEOUT_MS,
|
|
3363
|
+
type: "http",
|
|
3364
|
+
url
|
|
3342
3365
|
};
|
|
3343
3366
|
};
|
|
3367
|
+
var resolveHttpReadyProbeUrl = (service, ready) => {
|
|
3368
|
+
if (ready.path) {
|
|
3369
|
+
return resolveServiceHttpUrl(service, ready.path);
|
|
3370
|
+
}
|
|
3371
|
+
if (ready.url) {
|
|
3372
|
+
return ready.url;
|
|
3373
|
+
}
|
|
3374
|
+
if (isAbsoluteService(service)) {
|
|
3375
|
+
return resolveServiceHttpUrl(service, "/hmr-status");
|
|
3376
|
+
}
|
|
3377
|
+
return null;
|
|
3378
|
+
};
|
|
3344
3379
|
var resolveReadyProbe = (service, ready = service.ready ?? getDefaultReadyConfig(service)) => {
|
|
3345
3380
|
if (ready === false || !ready) {
|
|
3346
3381
|
return null;
|
|
@@ -3350,11 +3385,11 @@ var resolveReadyProbe = (service, ready = service.ready ?? getDefaultReadyConfig
|
|
|
3350
3385
|
}
|
|
3351
3386
|
if (ready.type === "tcp") {
|
|
3352
3387
|
return {
|
|
3353
|
-
type: "tcp",
|
|
3354
3388
|
host: ready.host ?? getServicePublicHost(service),
|
|
3355
|
-
port: ready.port,
|
|
3356
3389
|
intervalMs: ready.intervalMs ?? WORKSPACE_READY_PROBE_INTERVAL_MS,
|
|
3357
|
-
|
|
3390
|
+
port: ready.port,
|
|
3391
|
+
timeoutMs: ready.timeoutMs ?? WORKSPACE_READY_TIMEOUT_MS,
|
|
3392
|
+
type: "tcp"
|
|
3358
3393
|
};
|
|
3359
3394
|
}
|
|
3360
3395
|
if (ready.type === "command") {
|
|
@@ -3374,14 +3409,16 @@ var resolveReadyProbe = (service, ready = service.ready ?? getDefaultReadyConfig
|
|
|
3374
3409
|
return resolveHttpReadyProbe(service, ready);
|
|
3375
3410
|
};
|
|
3376
3411
|
var probeHttpReady = async (ready) => {
|
|
3412
|
+
const signal = AbortSignal.timeout(Math.min(ready.timeoutMs, WORKSPACE_READY_ATTEMPT_TIMEOUT_MS));
|
|
3377
3413
|
const response = await fetch(ready.url, {
|
|
3378
|
-
method: ready.method,
|
|
3379
3414
|
headers: ready.headers,
|
|
3380
|
-
|
|
3415
|
+
method: ready.method,
|
|
3416
|
+
signal
|
|
3381
3417
|
});
|
|
3382
3418
|
return ready.expectStatus.includes(response.status);
|
|
3383
3419
|
};
|
|
3384
|
-
var probeTcpReady = async (ready) =>
|
|
3420
|
+
var probeTcpReady = async (ready) => {
|
|
3421
|
+
const { promise, resolve: resolveProbe } = Promise.withResolvers();
|
|
3385
3422
|
const socket = createConnection({
|
|
3386
3423
|
host: ready.host,
|
|
3387
3424
|
port: ready.port
|
|
@@ -3400,7 +3437,8 @@ var probeTcpReady = async (ready) => new Promise((resolveProbe) => {
|
|
|
3400
3437
|
socket.destroy();
|
|
3401
3438
|
resolveProbe(false);
|
|
3402
3439
|
});
|
|
3403
|
-
|
|
3440
|
+
return promise;
|
|
3441
|
+
};
|
|
3404
3442
|
var probeCommandReady = async (ready, service) => {
|
|
3405
3443
|
const processHandle = Bun.spawn(ready.command, {
|
|
3406
3444
|
cwd: service.cwd,
|
|
@@ -3430,14 +3468,30 @@ var waitForReady = async (service) => {
|
|
|
3430
3468
|
await sleep(resolved.ms);
|
|
3431
3469
|
return;
|
|
3432
3470
|
}
|
|
3433
|
-
const
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3471
|
+
const isReady = await pollReady(resolved, service, Date.now());
|
|
3472
|
+
if (isReady) {
|
|
3473
|
+
return;
|
|
3474
|
+
}
|
|
3475
|
+
throw new Error(formatReadyTimeoutMessage(resolved));
|
|
3476
|
+
};
|
|
3477
|
+
var pollReady = async (resolved, service, startedAt) => {
|
|
3478
|
+
if (Date.now() - startedAt >= resolved.timeoutMs) {
|
|
3479
|
+
return false;
|
|
3480
|
+
}
|
|
3481
|
+
if (await probeReady(resolved, service)) {
|
|
3482
|
+
return true;
|
|
3483
|
+
}
|
|
3484
|
+
await sleep(resolved.intervalMs);
|
|
3485
|
+
return pollReady(resolved, service, startedAt);
|
|
3486
|
+
};
|
|
3487
|
+
var formatReadyTimeoutMessage = (resolved) => {
|
|
3488
|
+
if (resolved.type === "http") {
|
|
3489
|
+
return `service did not become ready within ${resolved.timeoutMs}ms (${resolved.url})`;
|
|
3490
|
+
}
|
|
3491
|
+
if (resolved.type === "tcp") {
|
|
3492
|
+
return `service did not become ready within ${resolved.timeoutMs}ms (tcp://${resolved.host}:${resolved.port})`;
|
|
3439
3493
|
}
|
|
3440
|
-
|
|
3494
|
+
return `service did not become ready within ${resolved.timeoutMs}ms (${resolved.command.join(" ")})`;
|
|
3441
3495
|
};
|
|
3442
3496
|
var probeReady = async (resolved, service) => {
|
|
3443
3497
|
try {
|
|
@@ -3526,13 +3580,17 @@ var pipeProcessLogs = (name, processHandle, appendLog) => {
|
|
|
3526
3580
|
const forward = async (stream, level) => {
|
|
3527
3581
|
let buffer = "";
|
|
3528
3582
|
const reader = stream.getReader();
|
|
3529
|
-
|
|
3530
|
-
|
|
3583
|
+
const forwardNextChunk = async () => {
|
|
3584
|
+
const chunk = await readLogChunk(reader);
|
|
3585
|
+
if (chunk === null) {
|
|
3586
|
+
appendRemainingLogBuffer(buffer, name, level, appendLog);
|
|
3587
|
+
reader.releaseLock();
|
|
3588
|
+
return;
|
|
3589
|
+
}
|
|
3531
3590
|
buffer = appendLogChunk(buffer, chunk, name, level, appendLog);
|
|
3532
|
-
|
|
3533
|
-
}
|
|
3534
|
-
|
|
3535
|
-
reader.releaseLock();
|
|
3591
|
+
await forwardNextChunk();
|
|
3592
|
+
};
|
|
3593
|
+
await forwardNextChunk();
|
|
3536
3594
|
};
|
|
3537
3595
|
forward(processHandle.stdout, "info");
|
|
3538
3596
|
forward(processHandle.stderr, "error");
|
|
@@ -3568,7 +3626,7 @@ var getServicePublicHost = (service) => {
|
|
|
3568
3626
|
var getServiceProtocol = (service) => service.env?.ABSOLUTE_HTTPS === "true" || process.env.ABSOLUTE_HTTPS === "true" ? "https" : "http";
|
|
3569
3627
|
var createWorkspaceServiceEnv = (services) => {
|
|
3570
3628
|
const workspaceEnv = {};
|
|
3571
|
-
for (const [name, service] of Object.entries(services).filter(([,
|
|
3629
|
+
for (const [name, service] of Object.entries(services).filter(([, filteredService]) => Boolean(filteredService.port))) {
|
|
3572
3630
|
const envKey = `ABSOLUTE_SERVICE_${name.toUpperCase().replace(/[^A-Z0-9]+/g, "_")}_URL`;
|
|
3573
3631
|
workspaceEnv[envKey] = `${getServiceProtocol(service)}://${getServicePublicHost(service)}:${service.port}`;
|
|
3574
3632
|
}
|
|
@@ -3683,9 +3741,7 @@ var workspace = async (subcommand, options) => {
|
|
|
3683
3741
|
running.length = 0;
|
|
3684
3742
|
snapshot.forEach((service) => killProcess(service));
|
|
3685
3743
|
await Promise.all(snapshot.map((service) => service.process.exited));
|
|
3686
|
-
|
|
3687
|
-
await runShutdownHookSafely(service);
|
|
3688
|
-
}
|
|
3744
|
+
await runSequentially(snapshot.reverse(), runShutdownHookSafely);
|
|
3689
3745
|
};
|
|
3690
3746
|
const appendRecentLogs = (lines, logsToPrint) => {
|
|
3691
3747
|
if (logsToPrint.length === 0) {
|
|
@@ -3771,54 +3827,58 @@ var workspace = async (subcommand, options) => {
|
|
|
3771
3827
|
await killProcesses();
|
|
3772
3828
|
process.exit(exitCode);
|
|
3773
3829
|
};
|
|
3830
|
+
const handleServiceExit = (runningService, exitCode) => {
|
|
3831
|
+
if (shuttingDown || restarting) {
|
|
3832
|
+
return;
|
|
3833
|
+
}
|
|
3834
|
+
if (!running.includes(runningService)) {
|
|
3835
|
+
return;
|
|
3836
|
+
}
|
|
3837
|
+
const serviceName = runningService.name;
|
|
3838
|
+
const normalizedExitCode = exitCode || 1;
|
|
3839
|
+
tui.setServiceStatus(serviceName, "error", `exit code ${normalizedExitCode}`);
|
|
3840
|
+
readyServiceNames.delete(serviceName);
|
|
3841
|
+
addLog("workspace", `${serviceName} exited with code ${normalizedExitCode}. Shutting down workspace.`, "error");
|
|
3842
|
+
shutdown(normalizedExitCode);
|
|
3843
|
+
};
|
|
3844
|
+
const startService = async (name) => {
|
|
3845
|
+
const service = services[name];
|
|
3846
|
+
if (!service) {
|
|
3847
|
+
throw new Error(`services is missing "${name}"`);
|
|
3848
|
+
}
|
|
3849
|
+
const resolved = resolveService(name, service, workspaceEnv, options);
|
|
3850
|
+
const port = (resolved.service.port ?? Number(resolved.env.PORT ?? "")) || DEFAULT_PORT;
|
|
3851
|
+
killStaleServicePort(port);
|
|
3852
|
+
if (isAbsoluteService(resolved.service) && resolved.configPath && !existsSync8(resolved.configPath)) {
|
|
3853
|
+
throw new Error(`${name} references missing config "${resolved.configPath}"`);
|
|
3854
|
+
}
|
|
3855
|
+
serviceBootStartedAt.set(name, performance.now());
|
|
3856
|
+
readyServiceNames.delete(name);
|
|
3857
|
+
tui.setServiceStatus(name, restarting ? "restarting" : "starting");
|
|
3858
|
+
const processHandle = Bun.spawn(resolved.command, {
|
|
3859
|
+
cwd: resolved.cwd,
|
|
3860
|
+
env: resolved.env,
|
|
3861
|
+
stderr: "pipe",
|
|
3862
|
+
stdin: "ignore",
|
|
3863
|
+
stdout: "pipe"
|
|
3864
|
+
});
|
|
3865
|
+
pipeProcessLogs(name, processHandle, addLog);
|
|
3866
|
+
const runningService = {
|
|
3867
|
+
name,
|
|
3868
|
+
process: processHandle,
|
|
3869
|
+
resolved
|
|
3870
|
+
};
|
|
3871
|
+
running.push(runningService);
|
|
3872
|
+
processHandle.exited.then(handleServiceExit.bind(null, runningService));
|
|
3873
|
+
await waitForReady(resolved);
|
|
3874
|
+
const startedAt = serviceBootStartedAt.get(name);
|
|
3875
|
+
const readyDuration = typeof startedAt === "number" ? `ready in ${getDurationString(performance.now() - startedAt)}` : undefined;
|
|
3876
|
+
readyServiceNames.add(name);
|
|
3877
|
+
tui.setServiceStatus(name, "ready", readyDuration);
|
|
3878
|
+
};
|
|
3774
3879
|
const startServices = async () => {
|
|
3775
3880
|
tui.setReadyDuration(null);
|
|
3776
|
-
|
|
3777
|
-
const service = services[name];
|
|
3778
|
-
if (!service) {
|
|
3779
|
-
throw new Error(`services is missing "${name}"`);
|
|
3780
|
-
}
|
|
3781
|
-
const resolved = resolveService(name, service, workspaceEnv, options);
|
|
3782
|
-
const port = (resolved.service.port ?? Number(resolved.env.PORT ?? "")) || DEFAULT_PORT;
|
|
3783
|
-
killStaleServicePort(port);
|
|
3784
|
-
if (isAbsoluteService(resolved.service) && resolved.configPath && !existsSync8(resolved.configPath)) {
|
|
3785
|
-
throw new Error(`${name} references missing config "${resolved.configPath}"`);
|
|
3786
|
-
}
|
|
3787
|
-
serviceBootStartedAt.set(name, performance.now());
|
|
3788
|
-
readyServiceNames.delete(name);
|
|
3789
|
-
tui.setServiceStatus(name, restarting ? "restarting" : "starting");
|
|
3790
|
-
const processHandle = Bun.spawn(resolved.command, {
|
|
3791
|
-
cwd: resolved.cwd,
|
|
3792
|
-
env: resolved.env,
|
|
3793
|
-
stderr: "pipe",
|
|
3794
|
-
stdin: "ignore",
|
|
3795
|
-
stdout: "pipe"
|
|
3796
|
-
});
|
|
3797
|
-
pipeProcessLogs(name, processHandle, addLog);
|
|
3798
|
-
const runningService = {
|
|
3799
|
-
name,
|
|
3800
|
-
process: processHandle,
|
|
3801
|
-
resolved
|
|
3802
|
-
};
|
|
3803
|
-
running.push(runningService);
|
|
3804
|
-
processHandle.exited.then((exitCode) => {
|
|
3805
|
-
if (shuttingDown || restarting) {
|
|
3806
|
-
return;
|
|
3807
|
-
}
|
|
3808
|
-
if (!running.includes(runningService)) {
|
|
3809
|
-
return;
|
|
3810
|
-
}
|
|
3811
|
-
tui.setServiceStatus(name, "error", `exit code ${exitCode || 1}`);
|
|
3812
|
-
readyServiceNames.delete(name);
|
|
3813
|
-
addLog("workspace", `${name} exited with code ${exitCode || 1}. Shutting down workspace.`, "error");
|
|
3814
|
-
shutdown(exitCode || 1);
|
|
3815
|
-
});
|
|
3816
|
-
await waitForReady(resolved);
|
|
3817
|
-
const startedAt = serviceBootStartedAt.get(name);
|
|
3818
|
-
const readyDuration = typeof startedAt === "number" ? `ready in ${getDurationString(performance.now() - startedAt)}` : undefined;
|
|
3819
|
-
readyServiceNames.add(name);
|
|
3820
|
-
tui.setServiceStatus(name, "ready", readyDuration);
|
|
3821
|
-
}
|
|
3881
|
+
await runSequentially(orderedNames, startService);
|
|
3822
3882
|
};
|
|
3823
3883
|
const restartWorkspace = async () => {
|
|
3824
3884
|
if (shuttingDown || restarting) {
|
|
@@ -3903,7 +3963,7 @@ var workspace = async (subcommand, options) => {
|
|
|
3903
3963
|
tui.start();
|
|
3904
3964
|
await startServices();
|
|
3905
3965
|
tui.setReadyDuration(performance.now() - workspaceBootStartedAt);
|
|
3906
|
-
await
|
|
3966
|
+
await Promise.withResolvers().promise;
|
|
3907
3967
|
};
|
|
3908
3968
|
|
|
3909
3969
|
// src/cli/index.ts
|
|
@@ -179,61 +179,61 @@ export const reloadCSSStylesheets = (manifest: Record<string, string>) => {
|
|
|
179
179
|
});
|
|
180
180
|
};
|
|
181
181
|
|
|
182
|
-
const createCSSLoadPromise = (linkElement: HTMLLinkElement, newHref: string) =>
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
};
|
|
182
|
+
const createCSSLoadPromise = (linkElement: HTMLLinkElement, newHref: string) => {
|
|
183
|
+
const { promise, resolve } = Promise.withResolvers<void>();
|
|
184
|
+
let resolved = false;
|
|
185
|
+
const doResolve = function () {
|
|
186
|
+
if (resolved) return;
|
|
187
|
+
resolved = true;
|
|
188
|
+
resolve();
|
|
189
|
+
};
|
|
191
190
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
return sheets.some(
|
|
197
|
-
(sheet) =>
|
|
198
|
-
sheet.href &&
|
|
199
|
-
sheet.href.includes(newHref.split('?')[0] ?? '')
|
|
200
|
-
);
|
|
201
|
-
} catch {
|
|
202
|
-
return false;
|
|
203
|
-
}
|
|
204
|
-
};
|
|
191
|
+
const verifyCSSOM = function () {
|
|
192
|
+
try {
|
|
193
|
+
const sheets = Array.from(document.styleSheets);
|
|
205
194
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
}
|
|
215
|
-
};
|
|
216
|
-
requestAnimationFrame(checkCSSOM);
|
|
217
|
-
};
|
|
195
|
+
return sheets.some(
|
|
196
|
+
(sheet) =>
|
|
197
|
+
sheet.href && sheet.href.includes(newHref.split('?')[0] ?? '')
|
|
198
|
+
);
|
|
199
|
+
} catch {
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
};
|
|
218
203
|
|
|
219
|
-
|
|
220
|
-
|
|
204
|
+
linkElement.onload = function () {
|
|
205
|
+
let checkCount = 0;
|
|
206
|
+
const checkCSSOM = function () {
|
|
207
|
+
checkCount++;
|
|
208
|
+
if (verifyCSSOM() || checkCount > CSS_MAX_CHECK_ATTEMPTS) {
|
|
221
209
|
doResolve();
|
|
222
|
-
}
|
|
210
|
+
} else {
|
|
211
|
+
requestAnimationFrame(checkCSSOM);
|
|
212
|
+
}
|
|
223
213
|
};
|
|
214
|
+
requestAnimationFrame(checkCSSOM);
|
|
215
|
+
};
|
|
224
216
|
|
|
217
|
+
linkElement.onerror = function () {
|
|
225
218
|
setTimeout(() => {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}, CSS_SHEET_READY_TIMEOUT_MS);
|
|
219
|
+
doResolve();
|
|
220
|
+
}, CSS_ERROR_RESOLVE_DELAY_MS);
|
|
221
|
+
};
|
|
230
222
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
223
|
+
setTimeout(() => {
|
|
224
|
+
if (linkElement.sheet && !resolved) {
|
|
225
|
+
doResolve();
|
|
226
|
+
}
|
|
227
|
+
}, CSS_SHEET_READY_TIMEOUT_MS);
|
|
228
|
+
|
|
229
|
+
setTimeout(() => {
|
|
230
|
+
if (!resolved) {
|
|
231
|
+
doResolve();
|
|
232
|
+
}
|
|
233
|
+
}, CSS_MAX_PARSE_TIMEOUT_MS);
|
|
234
|
+
|
|
235
|
+
return promise;
|
|
236
|
+
};
|
|
237
237
|
|
|
238
238
|
const removeLinks = (linksToRemove: HTMLLinkElement[]) => {
|
|
239
239
|
linksToRemove.forEach((link) => {
|