@absolutejs/absolute 0.19.0-beta.706 → 0.19.0-beta.708
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 +1 -19
- package/dist/angular/browser.js.map +3 -3
- package/dist/angular/components/constants.js +78 -0
- package/dist/angular/components/core/streamingSlotRegistrar.js +58 -0
- package/dist/angular/components/core/streamingSlotRegistry.js +114 -0
- package/dist/angular/components/defer-slot-payload.js +6 -0
- package/dist/angular/components/defer-slot-templates.directive.js +44 -0
- package/dist/angular/components/defer-slot.component.js +149 -0
- package/dist/angular/components/image.component.js +202 -0
- package/dist/angular/components/index.js +4 -0
- package/dist/angular/components/stream-slot.component.js +103 -0
- package/dist/angular/index.js +91 -36
- package/dist/angular/index.js.map +6 -6
- package/dist/angular/server.js +91 -36
- package/dist/angular/server.js.map +6 -6
- package/dist/build.js +242 -162
- package/dist/build.js.map +12 -12
- package/dist/cli/index.js +214 -142
- package/dist/client/index.js +86 -31
- package/dist/client/index.js.map +4 -4
- package/dist/core/streamingSlotRegistrar.js +1 -19
- package/dist/core/streamingSlotRegistrar.js.map +2 -2
- package/dist/core/streamingSlotRegistry.js +1 -19
- package/dist/core/streamingSlotRegistry.js.map +2 -2
- package/dist/dev/client/constants.ts +26 -0
- package/dist/dev/client/cssUtils.ts +307 -0
- package/dist/dev/client/domDiff.ts +226 -0
- package/dist/dev/client/domState.ts +421 -0
- package/dist/dev/client/domTracker.ts +61 -0
- package/dist/dev/client/errorOverlay.ts +184 -0
- package/dist/dev/client/frameworkDetect.ts +63 -0
- package/dist/dev/client/handlers/angular.ts +578 -0
- package/dist/dev/client/handlers/angularRuntime.ts +231 -0
- package/dist/dev/client/handlers/html.ts +364 -0
- package/dist/dev/client/handlers/htmx.ts +278 -0
- package/dist/dev/client/handlers/react.ts +108 -0
- package/dist/dev/client/handlers/rebuild.ts +153 -0
- package/dist/dev/client/handlers/svelte.ts +334 -0
- package/dist/dev/client/handlers/vue.ts +292 -0
- package/dist/dev/client/headPatch.ts +233 -0
- package/dist/dev/client/hmrClient.ts +273 -0
- package/dist/dev/client/hmrState.ts +14 -0
- package/dist/dev/client/moduleVersions.ts +62 -0
- package/dist/dev/client/reactRefreshSetup.ts +31 -0
- package/dist/index.js +282 -187
- package/dist/index.js.map +15 -15
- package/dist/islands/browser.js +1 -19
- package/dist/islands/browser.js.map +2 -2
- package/dist/islands/index.js +80 -26
- package/dist/islands/index.js.map +5 -5
- package/dist/react/browser.js +7 -25
- package/dist/react/browser.js.map +2 -2
- package/dist/react/components/browser/index.js +101 -101
- package/dist/react/components/index.js +104 -122
- package/dist/react/components/index.js.map +3 -3
- package/dist/react/hooks/index.js +1 -19
- package/dist/react/hooks/index.js.map +2 -2
- package/dist/react/index.js +101 -46
- package/dist/react/index.js.map +6 -6
- package/dist/react/jsxDevRuntimeCompat.js +1 -19
- package/dist/react/jsxDevRuntimeCompat.js.map +2 -2
- package/dist/react/server.js +13 -30
- package/dist/react/server.js.map +4 -4
- package/dist/src/angular/components/constants.d.ts +75 -0
- package/dist/src/angular/components/defer-slot-templates.directive.d.ts +7 -0
- package/dist/src/angular/components/defer-slot.component.d.ts +5 -2
- package/dist/src/angular/components/image.component.d.ts +5 -2
- package/dist/src/angular/components/index.d.ts +4 -4
- package/dist/src/angular/components/stream-slot.component.d.ts +3 -0
- package/dist/src/client/streamSwap.d.ts +0 -10
- package/dist/src/constants.d.ts +1 -0
- package/dist/src/dev/rebuildTrigger.d.ts +1 -1
- package/dist/src/svelte/renderToPipeableStream.d.ts +2 -2
- package/dist/src/svelte/renderToReadableStream.d.ts +2 -2
- package/dist/src/svelte/renderToString.d.ts +2 -2
- package/dist/src/vue/components/Image.d.ts +3 -3
- package/dist/svelte/browser.js +1 -19
- package/dist/svelte/browser.js.map +2 -2
- package/dist/svelte/components/AwaitSlot.svelte +39 -0
- package/dist/svelte/components/AwaitSlot.svelte.d.ts +2 -0
- package/dist/svelte/components/Head.svelte +144 -0
- package/dist/svelte/components/Head.svelte.d.ts +2 -0
- package/dist/svelte/components/Image.svelte +164 -0
- package/dist/svelte/components/Image.svelte.d.ts +5 -0
- package/dist/svelte/components/Island.svelte +71 -0
- package/dist/svelte/components/Island.svelte.d.ts +5 -0
- package/dist/svelte/components/JsonLd.svelte +21 -0
- package/dist/svelte/components/JsonLd.svelte.d.ts +2 -0
- package/dist/svelte/components/StreamSlot.svelte +41 -0
- package/dist/svelte/components/StreamSlot.svelte.d.ts +2 -0
- package/dist/svelte/index.js +93 -37
- package/dist/svelte/index.js.map +7 -7
- package/dist/svelte/server.js +16 -32
- package/dist/svelte/server.js.map +5 -5
- package/dist/types/globals.d.ts +130 -0
- package/dist/vue/browser.js +1 -19
- package/dist/vue/browser.js.map +2 -2
- package/dist/vue/components/Image.js +1 -19
- package/dist/vue/components/Image.js.map +3 -3
- package/dist/vue/components/index.js +1 -19
- package/dist/vue/components/index.js.map +3 -3
- package/dist/vue/index.js +91 -36
- package/dist/vue/index.js.map +7 -7
- package/dist/vue/server.js +13 -30
- 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;
|
|
@@ -663,17 +663,26 @@ var SERVER_OUTPUT_LIMIT = 4000, STARTUP_POLL_INTERVAL_MS = 100, DEFAULT_STARTUP_
|
|
|
663
663
|
const visited = new Set;
|
|
664
664
|
const queue = ["/"];
|
|
665
665
|
const routes = [];
|
|
666
|
-
|
|
666
|
+
const crawlNextRoute = async () => {
|
|
667
667
|
const path = queue.shift();
|
|
668
|
-
if (!path
|
|
669
|
-
|
|
668
|
+
if (!path) {
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
671
|
+
if (visited.has(path)) {
|
|
672
|
+
await crawlNextRoute();
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
670
675
|
visited.add(path);
|
|
671
676
|
const html = await fetchRoute(baseUrl, path).catch(() => null);
|
|
672
|
-
if (!html)
|
|
673
|
-
|
|
677
|
+
if (!html) {
|
|
678
|
+
await crawlNextRoute();
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
674
681
|
routes.push(path);
|
|
675
682
|
queue.push(...extractLinks(html, visited));
|
|
676
|
-
|
|
683
|
+
await crawlNextRoute();
|
|
684
|
+
};
|
|
685
|
+
await crawlNextRoute();
|
|
677
686
|
return routes;
|
|
678
687
|
}, rerenderRoute = async (route, port, prerenderDir) => {
|
|
679
688
|
try {
|
|
@@ -723,9 +732,7 @@ var SERVER_OUTPUT_LIMIT = 4000, STARTUP_POLL_INTERVAL_MS = 100, DEFAULT_STARTUP_
|
|
|
723
732
|
dir: prerenderDir,
|
|
724
733
|
routes: new Map
|
|
725
734
|
};
|
|
726
|
-
|
|
727
|
-
await prerenderRoute(baseUrl, route, prerenderDir, result, log);
|
|
728
|
-
}
|
|
735
|
+
await routes.reduce((chain, route) => chain.then(() => prerenderRoute(baseUrl, route, prerenderDir, result, log)), Promise.resolve());
|
|
729
736
|
return result;
|
|
730
737
|
}, getStartupTimeoutMs = () => {
|
|
731
738
|
const rawTimeout = Bun.env.ABSOLUTE_PRERENDER_STARTUP_TIMEOUT_MS;
|
|
@@ -733,13 +740,17 @@ var SERVER_OUTPUT_LIMIT = 4000, STARTUP_POLL_INTERVAL_MS = 100, DEFAULT_STARTUP_
|
|
|
733
740
|
return Number.isFinite(parsedTimeout) && parsedTimeout > 0 ? parsedTimeout : DEFAULT_STARTUP_TIMEOUT_MS;
|
|
734
741
|
}, waitForServerReady = async (port) => {
|
|
735
742
|
const deadline = performance.now() + getStartupTimeoutMs();
|
|
736
|
-
|
|
743
|
+
const pollServer = async () => {
|
|
744
|
+
if (performance.now() >= deadline) {
|
|
745
|
+
return false;
|
|
746
|
+
}
|
|
737
747
|
if (await probePrerenderServer(port)) {
|
|
738
748
|
return true;
|
|
739
749
|
}
|
|
740
750
|
await Bun.sleep(STARTUP_POLL_INTERVAL_MS);
|
|
741
|
-
|
|
742
|
-
|
|
751
|
+
return pollServer();
|
|
752
|
+
};
|
|
753
|
+
return pollServer();
|
|
743
754
|
}, probePrerenderServer = async (port) => {
|
|
744
755
|
const res = await fetch(`http://localhost:${port}/`).catch(() => null);
|
|
745
756
|
if (!res) {
|
|
@@ -756,10 +767,11 @@ var SERVER_OUTPUT_LIMIT = 4000, STARTUP_POLL_INTERVAL_MS = 100, DEFAULT_STARTUP_
|
|
|
756
767
|
const decoder = new TextDecoder;
|
|
757
768
|
const read = () => {
|
|
758
769
|
reader.read().then(({ done, value }) => {
|
|
759
|
-
if (done)
|
|
770
|
+
if (done) {
|
|
760
771
|
return;
|
|
772
|
+
}
|
|
761
773
|
output.push(decoder.decode(value, { stream: true }));
|
|
762
|
-
read();
|
|
774
|
+
return read();
|
|
763
775
|
}).catch(() => {});
|
|
764
776
|
};
|
|
765
777
|
read();
|
|
@@ -853,12 +865,15 @@ var cliTag3 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
853
865
|
return null;
|
|
854
866
|
}
|
|
855
867
|
}, resolveBuildModule2 = async (candidates) => {
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
return mod;
|
|
868
|
+
const [candidate, ...remaining] = candidates;
|
|
869
|
+
if (!candidate) {
|
|
870
|
+
return;
|
|
860
871
|
}
|
|
861
|
-
|
|
872
|
+
const mod = await tryImportBuild2(candidate);
|
|
873
|
+
if (mod) {
|
|
874
|
+
return mod;
|
|
875
|
+
}
|
|
876
|
+
return resolveBuildModule2(remaining);
|
|
862
877
|
}, resolveJsxDevRuntimeCompatPath2 = () => {
|
|
863
878
|
const candidates = [
|
|
864
879
|
resolve7(import.meta.dir, "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
|
|
@@ -1203,7 +1218,7 @@ var isCommandService3 = (service) => service.kind === "command" || Array.isArray
|
|
|
1203
1218
|
}, shellEscape = (value) => `'${value.replaceAll("'", "'\\''")}'`, runShell = async (name, command) => run(name, ["/bin/bash", "-lc", command]), findBin = (name) => {
|
|
1204
1219
|
const local = resolve8("node_modules", ".bin", name);
|
|
1205
1220
|
return existsSync10(local) ? local : null;
|
|
1206
|
-
}, stripAnsi3 = (str) => str.replace(
|
|
1221
|
+
}, ANSI_COLOR_REGEX, ANSI_PURPLE_REGEX, ANSI_CYAN_REGEX, ANSI_TOKEN_END_REGEX, stripAnsi3 = (str) => str.replace(ANSI_COLOR_REGEX, ""), formatSvelteOutput = (output) => {
|
|
1207
1222
|
const cwd = `${process.cwd()}/`;
|
|
1208
1223
|
const summaryMatch = stripAnsi3(output).match(/svelte-check found (\d+) error/);
|
|
1209
1224
|
const errorCount = summaryMatch ? parseInt(summaryMatch[1] ?? "0", 10) : 0;
|
|
@@ -1220,10 +1235,10 @@ var isCommandService3 = (service) => service.kind === "command" || Array.isArray
|
|
|
1220
1235
|
`\x1B[96m${pathMatch[1]}\x1B[0m:\x1B[93m${pathMatch[2]}\x1B[0m`
|
|
1221
1236
|
];
|
|
1222
1237
|
}
|
|
1223
|
-
if (result.includes(
|
|
1238
|
+
if (result.includes(ANSI_PURPLE_REGEX)) {
|
|
1224
1239
|
const plainLine = stripAnsi3(result);
|
|
1225
|
-
const before = stripAnsi3(result.split(
|
|
1226
|
-
const token = stripAnsi3((result.split(
|
|
1240
|
+
const before = stripAnsi3(result.split(ANSI_PURPLE_REGEX)[0] ?? "");
|
|
1241
|
+
const token = stripAnsi3((result.split(ANSI_PURPLE_REGEX)[1] ?? "").split(ANSI_TOKEN_END_REGEX)[0] ?? "");
|
|
1227
1242
|
if (!token)
|
|
1228
1243
|
return [result];
|
|
1229
1244
|
const expanded = before.replace(/\t/g, " ");
|
|
@@ -1234,7 +1249,7 @@ var isCommandService3 = (service) => service.kind === "command" || Array.isArray
|
|
|
1234
1249
|
`${" ".repeat(expanded.length)}\x1B[91m${underline}\x1B[0m`
|
|
1235
1250
|
];
|
|
1236
1251
|
}
|
|
1237
|
-
if (
|
|
1252
|
+
if (ANSI_CYAN_REGEX.test(result) && !result.includes("Error") && !result.includes(ANSI_PURPLE_REGEX)) {
|
|
1238
1253
|
return [];
|
|
1239
1254
|
}
|
|
1240
1255
|
return [result];
|
|
@@ -1377,6 +1392,11 @@ Found ${errorCount} error${suffix}.`;
|
|
|
1377
1392
|
};
|
|
1378
1393
|
var init_typecheck = __esm(() => {
|
|
1379
1394
|
init_loadConfig();
|
|
1395
|
+
init_constants();
|
|
1396
|
+
ANSI_COLOR_REGEX = new RegExp(`${String.fromCharCode(ANSI_ESCAPE_CODE)}\\[[0-9;]*m`, "g");
|
|
1397
|
+
ANSI_PURPLE_REGEX = `${String.fromCharCode(ANSI_ESCAPE_CODE)}[35m`;
|
|
1398
|
+
ANSI_CYAN_REGEX = new RegExp(`^${String.fromCharCode(ANSI_ESCAPE_CODE)}\\[36m|\\t`);
|
|
1399
|
+
ANSI_TOKEN_END_REGEX = new RegExp(`${String.fromCharCode(ANSI_ESCAPE_CODE)}\\[3[69]m`);
|
|
1380
1400
|
TYPECHECK_EXCLUDE = [
|
|
1381
1401
|
"../node_modules/**/*",
|
|
1382
1402
|
"../**/.absolutejs/**/*",
|
|
@@ -1431,7 +1451,10 @@ var trySetRawMode = () => {
|
|
|
1431
1451
|
} catch {
|
|
1432
1452
|
return null;
|
|
1433
1453
|
}
|
|
1434
|
-
return
|
|
1454
|
+
return {
|
|
1455
|
+
destroyOnDispose: false,
|
|
1456
|
+
stream: process.stdin
|
|
1457
|
+
};
|
|
1435
1458
|
};
|
|
1436
1459
|
var openTtyStream = () => {
|
|
1437
1460
|
const fromStdin = trySetRawMode();
|
|
@@ -1441,7 +1464,10 @@ var openTtyStream = () => {
|
|
|
1441
1464
|
try {
|
|
1442
1465
|
const ttyStream = new ReadStream(openSync("/dev/tty", "r"));
|
|
1443
1466
|
ttyStream.setRawMode(true);
|
|
1444
|
-
return
|
|
1467
|
+
return {
|
|
1468
|
+
destroyOnDispose: true,
|
|
1469
|
+
stream: ttyStream
|
|
1470
|
+
};
|
|
1445
1471
|
} catch {
|
|
1446
1472
|
return null;
|
|
1447
1473
|
}
|
|
@@ -1633,19 +1659,19 @@ var createInteractiveHandler = (actions) => {
|
|
|
1633
1659
|
processChar(str.charAt(idx));
|
|
1634
1660
|
}
|
|
1635
1661
|
};
|
|
1636
|
-
const
|
|
1637
|
-
const input =
|
|
1662
|
+
const ttyInput = openTtyStream();
|
|
1663
|
+
const input = ttyInput?.stream ?? process.stdin;
|
|
1638
1664
|
input.resume();
|
|
1639
1665
|
input.on("data", onData);
|
|
1640
1666
|
const disposeTtyStream = () => {
|
|
1641
|
-
if (!
|
|
1667
|
+
if (!ttyInput) {
|
|
1642
1668
|
return;
|
|
1643
1669
|
}
|
|
1644
1670
|
try {
|
|
1645
|
-
|
|
1671
|
+
ttyInput.stream.setRawMode?.(false);
|
|
1646
1672
|
} catch {}
|
|
1647
|
-
if (
|
|
1648
|
-
|
|
1673
|
+
if (ttyInput.destroyOnDispose) {
|
|
1674
|
+
ttyInput.stream.destroy?.();
|
|
1649
1675
|
}
|
|
1650
1676
|
};
|
|
1651
1677
|
const dispose = () => {
|
|
@@ -1668,7 +1694,7 @@ init_loadConfig();
|
|
|
1668
1694
|
init_utils();
|
|
1669
1695
|
var cliTag = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`;
|
|
1670
1696
|
var confirmPrompt = (message, defaultYes = true) => {
|
|
1671
|
-
const { promise, resolve:
|
|
1697
|
+
const { promise, resolve: resolvePrompt } = Promise.withResolvers();
|
|
1672
1698
|
let selected = defaultYes;
|
|
1673
1699
|
const render = () => {
|
|
1674
1700
|
const yes = selected ? "\x1B[36m\u25CF\x1B[0m Yes" : "\x1B[2m\u25CB Yes\x1B[0m";
|
|
@@ -1694,7 +1720,7 @@ var confirmPrompt = (message, defaultYes = true) => {
|
|
|
1694
1720
|
process.stdout.write(`\x1B[2K\x1B[32m\u25C7\x1B[0m ${message}
|
|
1695
1721
|
\x1B[2K \x1B[2m${label}\x1B[0m
|
|
1696
1722
|
\x1B[?25h`);
|
|
1697
|
-
|
|
1723
|
+
resolvePrompt(selected);
|
|
1698
1724
|
} else if (key === "\x03") {
|
|
1699
1725
|
process.stdout.write("\x1B[?25h");
|
|
1700
1726
|
process.stdin.setRawMode(false);
|
|
@@ -2203,9 +2229,7 @@ var runTool = async (adapter, args) => {
|
|
|
2203
2229
|
batches.push(changed.slice(idx, idx + MAX_FILES_PER_BATCH));
|
|
2204
2230
|
}
|
|
2205
2231
|
const failedFiles = new Set;
|
|
2206
|
-
|
|
2207
|
-
await runBatch(adapter, batch, args, failedFiles);
|
|
2208
|
-
}
|
|
2232
|
+
await batches.reduce((chain, batch) => chain.then(() => runBatch(adapter, batch, args, failedFiles)), Promise.resolve());
|
|
2209
2233
|
for (const file of failedFiles) {
|
|
2210
2234
|
delete cache.files[file];
|
|
2211
2235
|
}
|
|
@@ -2285,13 +2309,15 @@ var readPackageVersion2 = (candidate) => {
|
|
|
2285
2309
|
return null;
|
|
2286
2310
|
};
|
|
2287
2311
|
var resolveBuildModule = async (candidates) => {
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
return mod;
|
|
2292
|
-
}
|
|
2312
|
+
const [candidate, ...remaining] = candidates;
|
|
2313
|
+
if (!candidate) {
|
|
2314
|
+
return;
|
|
2293
2315
|
}
|
|
2294
|
-
|
|
2316
|
+
const mod = await tryImportBuild(candidate);
|
|
2317
|
+
if (mod) {
|
|
2318
|
+
return mod;
|
|
2319
|
+
}
|
|
2320
|
+
return resolveBuildModule(remaining);
|
|
2295
2321
|
};
|
|
2296
2322
|
var tryImportBuild = async (candidate) => {
|
|
2297
2323
|
try {
|
|
@@ -2581,7 +2607,8 @@ import { openSync as openSync2 } from "fs";
|
|
|
2581
2607
|
import { ReadStream as ReadStream2 } from "tty";
|
|
2582
2608
|
var MAX_LOG_ENTRIES = 400;
|
|
2583
2609
|
var ESCAPE = "\x1B";
|
|
2584
|
-
var ANSI_REGEX =
|
|
2610
|
+
var ANSI_REGEX = new RegExp(`${String.fromCharCode(ANSI_ESCAPE_CODE)}\\[[0-?]*[ -/]*[@-~]`, "g");
|
|
2611
|
+
var ANSI_ESCAPE_PREFIX = `${ESCAPE}[`;
|
|
2585
2612
|
var SHORTCUTS2 = new Map([
|
|
2586
2613
|
["c", "clear"],
|
|
2587
2614
|
["h", "help"],
|
|
@@ -2773,6 +2800,17 @@ var getWorkspaceStatus = (services) => {
|
|
|
2773
2800
|
}
|
|
2774
2801
|
return "ready";
|
|
2775
2802
|
};
|
|
2803
|
+
var getVisibleLogContent = (contentLines, logHeight, logScrollOffset) => {
|
|
2804
|
+
const end = Math.max(0, contentLines.length - logScrollOffset);
|
|
2805
|
+
const start2 = Math.max(0, end - logHeight);
|
|
2806
|
+
return contentLines.slice(start2, end);
|
|
2807
|
+
};
|
|
2808
|
+
var isPartialEscapeSequence = (value) => {
|
|
2809
|
+
if (!value.startsWith(ANSI_ESCAPE_PREFIX)) {
|
|
2810
|
+
return false;
|
|
2811
|
+
}
|
|
2812
|
+
return Array.from(value.slice(ANSI_ESCAPE_PREFIX.length)).every((char) => char >= "0" && char <= "9");
|
|
2813
|
+
};
|
|
2776
2814
|
var createWorkspaceTui = ({
|
|
2777
2815
|
actions,
|
|
2778
2816
|
services,
|
|
@@ -2896,11 +2934,7 @@ var createWorkspaceTui = ({
|
|
|
2896
2934
|
lastLogViewportHeight = logHeight;
|
|
2897
2935
|
logScrollOffset = Math.min(logScrollOffset, Math.max(0, contentLines.length - logHeight));
|
|
2898
2936
|
}
|
|
2899
|
-
const visibleContent = helpVisible ? contentLines.slice(0, logHeight) : (
|
|
2900
|
-
const end = Math.max(0, contentLines.length - logScrollOffset);
|
|
2901
|
-
const start3 = Math.max(0, end - logHeight);
|
|
2902
|
-
return contentLines.slice(start3, end);
|
|
2903
|
-
})();
|
|
2937
|
+
const visibleContent = helpVisible ? contentLines.slice(0, logHeight) : getVisibleLogContent(contentLines, logHeight, logScrollOffset);
|
|
2904
2938
|
const maxLogScrollOffset = !helpVisible ? Math.max(0, contentLines.length - logHeight) : 0;
|
|
2905
2939
|
const shouldShowScrollbar = !helpVisible && maxLogScrollOffset > 0;
|
|
2906
2940
|
const scrollbarThumbHeight = shouldShowScrollbar ? Math.max(1, Math.min(logHeight, Math.round(logHeight / contentLines.length * logHeight))) : 0;
|
|
@@ -3093,7 +3127,7 @@ var createWorkspaceTui = ({
|
|
|
3093
3127
|
handleScrollEscape("end");
|
|
3094
3128
|
return;
|
|
3095
3129
|
}
|
|
3096
|
-
if (
|
|
3130
|
+
if (isPartialEscapeSequence(escapeBuffer)) {
|
|
3097
3131
|
armEscapeTimer();
|
|
3098
3132
|
return;
|
|
3099
3133
|
}
|
|
@@ -3161,16 +3195,15 @@ var createWorkspaceTui = ({
|
|
|
3161
3195
|
}
|
|
3162
3196
|
await handlePrintableChar(char);
|
|
3163
3197
|
};
|
|
3198
|
+
const processInputChars = async (chars) => {
|
|
3199
|
+
await Array.from(chars).reduce((chain, char) => chain.then(() => handleChar(char)), Promise.resolve());
|
|
3200
|
+
};
|
|
3164
3201
|
const onResize = () => {
|
|
3165
3202
|
scheduleRender();
|
|
3166
3203
|
};
|
|
3167
3204
|
const onData = (chunk) => {
|
|
3168
3205
|
const chars = chunk.toString();
|
|
3169
|
-
(
|
|
3170
|
-
for (const char of chars) {
|
|
3171
|
-
await handleChar(char);
|
|
3172
|
-
}
|
|
3173
|
-
})();
|
|
3206
|
+
processInputChars(chars);
|
|
3174
3207
|
};
|
|
3175
3208
|
const start2 = () => {
|
|
3176
3209
|
process.stdout.write("\x1B[?1049h\x1B[2J\x1B[H\x1B[?25l");
|
|
@@ -3222,8 +3255,8 @@ var createWorkspaceTui = ({
|
|
|
3222
3255
|
|
|
3223
3256
|
// src/cli/scripts/workspace.ts
|
|
3224
3257
|
init_utils();
|
|
3225
|
-
var ANSI_REGEX2 =
|
|
3226
|
-
var sleep = (
|
|
3258
|
+
var ANSI_REGEX2 = new RegExp(`${String.fromCharCode(ANSI_ESCAPE_CODE)}\\[[0-?]*[ -/]*[@-~]`, "g");
|
|
3259
|
+
var sleep = (durationMs) => Bun.sleep(durationMs);
|
|
3227
3260
|
var stripAnsi2 = (value) => value.replace(ANSI_REGEX2, "");
|
|
3228
3261
|
var sanitizeLogFileName = (value) => value.replace(/[^a-zA-Z0-9._-]/g, "_") || "unknown";
|
|
3229
3262
|
var createWorkspaceLogSink = (appendLog) => {
|
|
@@ -3250,11 +3283,11 @@ var createWorkspaceLogSink = (appendLog) => {
|
|
|
3250
3283
|
appendFileSync(resolve6(logDirectory, "all.log"), line);
|
|
3251
3284
|
};
|
|
3252
3285
|
return {
|
|
3253
|
-
logDirectory,
|
|
3254
3286
|
appendLog: (source, message, level = "info") => {
|
|
3255
3287
|
writeLog(source, message, level);
|
|
3256
3288
|
appendLog(source, message, level);
|
|
3257
|
-
}
|
|
3289
|
+
},
|
|
3290
|
+
logDirectory
|
|
3258
3291
|
};
|
|
3259
3292
|
};
|
|
3260
3293
|
var readPackageVersion3 = (candidate) => {
|
|
@@ -3299,6 +3332,7 @@ var getDefaultReadyConfig = (service) => {
|
|
|
3299
3332
|
return;
|
|
3300
3333
|
};
|
|
3301
3334
|
var normalizeExpectedStatuses = (value) => Array.isArray(value) ? value : [value ?? HTTP_STATUS_OK];
|
|
3335
|
+
var runSequentially = (items, action) => items.reduce((chain, item) => chain.then(() => action(item)), Promise.resolve());
|
|
3302
3336
|
var resolveServiceHttpUrl = (service, path) => {
|
|
3303
3337
|
if (!path.startsWith("/")) {
|
|
3304
3338
|
throw new Error(`ready path must start with "/" for service probes. Received "${path}".`);
|
|
@@ -3310,17 +3344,18 @@ var resolveServiceHttpUrl = (service, path) => {
|
|
|
3310
3344
|
};
|
|
3311
3345
|
var resolveHttpReadyProbe = (service, ready) => {
|
|
3312
3346
|
if (typeof ready === "string") {
|
|
3313
|
-
if (isAbsoluteService(service)) {
|
|
3347
|
+
if (!isAbsoluteService(service)) {
|
|
3314
3348
|
return {
|
|
3315
|
-
type: "http",
|
|
3316
|
-
url: resolveServiceHttpUrl(service, ready),
|
|
3317
|
-
method: "GET",
|
|
3318
3349
|
expectStatus: [HTTP_STATUS_OK],
|
|
3319
3350
|
headers: {},
|
|
3320
3351
|
intervalMs: WORKSPACE_READY_PROBE_INTERVAL_MS,
|
|
3321
|
-
|
|
3352
|
+
method: "GET",
|
|
3353
|
+
timeoutMs: WORKSPACE_READY_TIMEOUT_MS,
|
|
3354
|
+
type: "http",
|
|
3355
|
+
url: ready
|
|
3322
3356
|
};
|
|
3323
3357
|
}
|
|
3358
|
+
const url2 = resolveServiceHttpUrl(service, ready);
|
|
3324
3359
|
return {
|
|
3325
3360
|
expectStatus: [HTTP_STATUS_OK],
|
|
3326
3361
|
headers: {},
|
|
@@ -3328,26 +3363,38 @@ var resolveHttpReadyProbe = (service, ready) => {
|
|
|
3328
3363
|
method: "GET",
|
|
3329
3364
|
timeoutMs: WORKSPACE_READY_TIMEOUT_MS,
|
|
3330
3365
|
type: "http",
|
|
3331
|
-
url:
|
|
3366
|
+
url: url2
|
|
3332
3367
|
};
|
|
3333
3368
|
}
|
|
3334
3369
|
if (ready.path && ready.url) {
|
|
3335
3370
|
throw new Error('ready HTTP probe cannot define both "path" and "url".');
|
|
3336
3371
|
}
|
|
3337
|
-
const url =
|
|
3372
|
+
const url = resolveHttpReadyProbeUrl(service, ready);
|
|
3338
3373
|
if (!url) {
|
|
3339
3374
|
throw new Error('ready HTTP probe requires either "url" or "path".');
|
|
3340
3375
|
}
|
|
3341
3376
|
return {
|
|
3342
|
-
type: "http",
|
|
3343
|
-
url,
|
|
3344
|
-
method: ready.method ?? "GET",
|
|
3345
3377
|
expectStatus: normalizeExpectedStatuses(ready.expectStatus),
|
|
3346
3378
|
headers: ready.headers ?? {},
|
|
3347
3379
|
intervalMs: ready.intervalMs ?? WORKSPACE_READY_PROBE_INTERVAL_MS,
|
|
3348
|
-
|
|
3380
|
+
method: ready.method ?? "GET",
|
|
3381
|
+
timeoutMs: ready.timeoutMs ?? WORKSPACE_READY_TIMEOUT_MS,
|
|
3382
|
+
type: "http",
|
|
3383
|
+
url
|
|
3349
3384
|
};
|
|
3350
3385
|
};
|
|
3386
|
+
var resolveHttpReadyProbeUrl = (service, ready) => {
|
|
3387
|
+
if (ready.path) {
|
|
3388
|
+
return resolveServiceHttpUrl(service, ready.path);
|
|
3389
|
+
}
|
|
3390
|
+
if (ready.url) {
|
|
3391
|
+
return ready.url;
|
|
3392
|
+
}
|
|
3393
|
+
if (isAbsoluteService(service)) {
|
|
3394
|
+
return resolveServiceHttpUrl(service, "/hmr-status");
|
|
3395
|
+
}
|
|
3396
|
+
return null;
|
|
3397
|
+
};
|
|
3351
3398
|
var resolveReadyProbe = (service, ready = service.ready ?? getDefaultReadyConfig(service)) => {
|
|
3352
3399
|
if (ready === false || !ready) {
|
|
3353
3400
|
return null;
|
|
@@ -3357,11 +3404,11 @@ var resolveReadyProbe = (service, ready = service.ready ?? getDefaultReadyConfig
|
|
|
3357
3404
|
}
|
|
3358
3405
|
if (ready.type === "tcp") {
|
|
3359
3406
|
return {
|
|
3360
|
-
type: "tcp",
|
|
3361
3407
|
host: ready.host ?? getServicePublicHost(service),
|
|
3362
|
-
port: ready.port,
|
|
3363
3408
|
intervalMs: ready.intervalMs ?? WORKSPACE_READY_PROBE_INTERVAL_MS,
|
|
3364
|
-
|
|
3409
|
+
port: ready.port,
|
|
3410
|
+
timeoutMs: ready.timeoutMs ?? WORKSPACE_READY_TIMEOUT_MS,
|
|
3411
|
+
type: "tcp"
|
|
3365
3412
|
};
|
|
3366
3413
|
}
|
|
3367
3414
|
if (ready.type === "command") {
|
|
@@ -3381,14 +3428,16 @@ var resolveReadyProbe = (service, ready = service.ready ?? getDefaultReadyConfig
|
|
|
3381
3428
|
return resolveHttpReadyProbe(service, ready);
|
|
3382
3429
|
};
|
|
3383
3430
|
var probeHttpReady = async (ready) => {
|
|
3431
|
+
const signal = AbortSignal.timeout(Math.min(ready.timeoutMs, WORKSPACE_READY_ATTEMPT_TIMEOUT_MS));
|
|
3384
3432
|
const response = await fetch(ready.url, {
|
|
3385
|
-
method: ready.method,
|
|
3386
3433
|
headers: ready.headers,
|
|
3387
|
-
|
|
3434
|
+
method: ready.method,
|
|
3435
|
+
signal
|
|
3388
3436
|
});
|
|
3389
3437
|
return ready.expectStatus.includes(response.status);
|
|
3390
3438
|
};
|
|
3391
|
-
var probeTcpReady = async (ready) =>
|
|
3439
|
+
var probeTcpReady = async (ready) => {
|
|
3440
|
+
const { promise, resolve: resolveProbe } = Promise.withResolvers();
|
|
3392
3441
|
const socket = createConnection({
|
|
3393
3442
|
host: ready.host,
|
|
3394
3443
|
port: ready.port
|
|
@@ -3407,7 +3456,8 @@ var probeTcpReady = async (ready) => new Promise((resolveProbe) => {
|
|
|
3407
3456
|
socket.destroy();
|
|
3408
3457
|
resolveProbe(false);
|
|
3409
3458
|
});
|
|
3410
|
-
|
|
3459
|
+
return promise;
|
|
3460
|
+
};
|
|
3411
3461
|
var probeCommandReady = async (ready, service) => {
|
|
3412
3462
|
const processHandle = Bun.spawn(ready.command, {
|
|
3413
3463
|
cwd: service.cwd,
|
|
@@ -3437,14 +3487,30 @@ var waitForReady = async (service) => {
|
|
|
3437
3487
|
await sleep(resolved.ms);
|
|
3438
3488
|
return;
|
|
3439
3489
|
}
|
|
3440
|
-
const
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
return;
|
|
3444
|
-
}
|
|
3445
|
-
await sleep(resolved.intervalMs);
|
|
3490
|
+
const isReady = await pollReady(resolved, service, Date.now());
|
|
3491
|
+
if (isReady) {
|
|
3492
|
+
return;
|
|
3446
3493
|
}
|
|
3447
|
-
throw new Error(
|
|
3494
|
+
throw new Error(formatReadyTimeoutMessage(resolved));
|
|
3495
|
+
};
|
|
3496
|
+
var pollReady = async (resolved, service, startedAt) => {
|
|
3497
|
+
if (Date.now() - startedAt >= resolved.timeoutMs) {
|
|
3498
|
+
return false;
|
|
3499
|
+
}
|
|
3500
|
+
if (await probeReady(resolved, service)) {
|
|
3501
|
+
return true;
|
|
3502
|
+
}
|
|
3503
|
+
await sleep(resolved.intervalMs);
|
|
3504
|
+
return pollReady(resolved, service, startedAt);
|
|
3505
|
+
};
|
|
3506
|
+
var formatReadyTimeoutMessage = (resolved) => {
|
|
3507
|
+
if (resolved.type === "http") {
|
|
3508
|
+
return `service did not become ready within ${resolved.timeoutMs}ms (${resolved.url})`;
|
|
3509
|
+
}
|
|
3510
|
+
if (resolved.type === "tcp") {
|
|
3511
|
+
return `service did not become ready within ${resolved.timeoutMs}ms (tcp://${resolved.host}:${resolved.port})`;
|
|
3512
|
+
}
|
|
3513
|
+
return `service did not become ready within ${resolved.timeoutMs}ms (${resolved.command.join(" ")})`;
|
|
3448
3514
|
};
|
|
3449
3515
|
var probeReady = async (resolved, service) => {
|
|
3450
3516
|
try {
|
|
@@ -3533,13 +3599,17 @@ var pipeProcessLogs = (name, processHandle, appendLog) => {
|
|
|
3533
3599
|
const forward = async (stream, level) => {
|
|
3534
3600
|
let buffer = "";
|
|
3535
3601
|
const reader = stream.getReader();
|
|
3536
|
-
|
|
3537
|
-
|
|
3602
|
+
const forwardNextChunk = async () => {
|
|
3603
|
+
const chunk = await readLogChunk(reader);
|
|
3604
|
+
if (chunk === null) {
|
|
3605
|
+
appendRemainingLogBuffer(buffer, name, level, appendLog);
|
|
3606
|
+
reader.releaseLock();
|
|
3607
|
+
return;
|
|
3608
|
+
}
|
|
3538
3609
|
buffer = appendLogChunk(buffer, chunk, name, level, appendLog);
|
|
3539
|
-
|
|
3540
|
-
}
|
|
3541
|
-
|
|
3542
|
-
reader.releaseLock();
|
|
3610
|
+
await forwardNextChunk();
|
|
3611
|
+
};
|
|
3612
|
+
await forwardNextChunk();
|
|
3543
3613
|
};
|
|
3544
3614
|
forward(processHandle.stdout, "info");
|
|
3545
3615
|
forward(processHandle.stderr, "error");
|
|
@@ -3575,7 +3645,7 @@ var getServicePublicHost = (service) => {
|
|
|
3575
3645
|
var getServiceProtocol = (service) => service.env?.ABSOLUTE_HTTPS === "true" || process.env.ABSOLUTE_HTTPS === "true" ? "https" : "http";
|
|
3576
3646
|
var createWorkspaceServiceEnv = (services) => {
|
|
3577
3647
|
const workspaceEnv = {};
|
|
3578
|
-
for (const [name, service] of Object.entries(services).filter(([,
|
|
3648
|
+
for (const [name, service] of Object.entries(services).filter(([, filteredService]) => Boolean(filteredService.port))) {
|
|
3579
3649
|
const envKey = `ABSOLUTE_SERVICE_${name.toUpperCase().replace(/[^A-Z0-9]+/g, "_")}_URL`;
|
|
3580
3650
|
workspaceEnv[envKey] = `${getServiceProtocol(service)}://${getServicePublicHost(service)}:${service.port}`;
|
|
3581
3651
|
}
|
|
@@ -3690,9 +3760,7 @@ var workspace = async (subcommand, options) => {
|
|
|
3690
3760
|
running.length = 0;
|
|
3691
3761
|
snapshot.forEach((service) => killProcess(service));
|
|
3692
3762
|
await Promise.all(snapshot.map((service) => service.process.exited));
|
|
3693
|
-
|
|
3694
|
-
await runShutdownHookSafely(service);
|
|
3695
|
-
}
|
|
3763
|
+
await runSequentially(snapshot.reverse(), runShutdownHookSafely);
|
|
3696
3764
|
};
|
|
3697
3765
|
const appendRecentLogs = (lines, logsToPrint) => {
|
|
3698
3766
|
if (logsToPrint.length === 0) {
|
|
@@ -3778,54 +3846,58 @@ var workspace = async (subcommand, options) => {
|
|
|
3778
3846
|
await killProcesses();
|
|
3779
3847
|
process.exit(exitCode);
|
|
3780
3848
|
};
|
|
3849
|
+
const handleServiceExit = (runningService, exitCode) => {
|
|
3850
|
+
if (shuttingDown || restarting) {
|
|
3851
|
+
return;
|
|
3852
|
+
}
|
|
3853
|
+
if (!running.includes(runningService)) {
|
|
3854
|
+
return;
|
|
3855
|
+
}
|
|
3856
|
+
const serviceName = runningService.name;
|
|
3857
|
+
const normalizedExitCode = exitCode || 1;
|
|
3858
|
+
tui.setServiceStatus(serviceName, "error", `exit code ${normalizedExitCode}`);
|
|
3859
|
+
readyServiceNames.delete(serviceName);
|
|
3860
|
+
addLog("workspace", `${serviceName} exited with code ${normalizedExitCode}. Shutting down workspace.`, "error");
|
|
3861
|
+
shutdown(normalizedExitCode);
|
|
3862
|
+
};
|
|
3863
|
+
const startService = async (name) => {
|
|
3864
|
+
const service = services[name];
|
|
3865
|
+
if (!service) {
|
|
3866
|
+
throw new Error(`services is missing "${name}"`);
|
|
3867
|
+
}
|
|
3868
|
+
const resolved = resolveService(name, service, workspaceEnv, options);
|
|
3869
|
+
const port = (resolved.service.port ?? Number(resolved.env.PORT ?? "")) || DEFAULT_PORT;
|
|
3870
|
+
killStaleServicePort(port);
|
|
3871
|
+
if (isAbsoluteService(resolved.service) && resolved.configPath && !existsSync8(resolved.configPath)) {
|
|
3872
|
+
throw new Error(`${name} references missing config "${resolved.configPath}"`);
|
|
3873
|
+
}
|
|
3874
|
+
serviceBootStartedAt.set(name, performance.now());
|
|
3875
|
+
readyServiceNames.delete(name);
|
|
3876
|
+
tui.setServiceStatus(name, restarting ? "restarting" : "starting");
|
|
3877
|
+
const processHandle = Bun.spawn(resolved.command, {
|
|
3878
|
+
cwd: resolved.cwd,
|
|
3879
|
+
env: resolved.env,
|
|
3880
|
+
stderr: "pipe",
|
|
3881
|
+
stdin: "ignore",
|
|
3882
|
+
stdout: "pipe"
|
|
3883
|
+
});
|
|
3884
|
+
pipeProcessLogs(name, processHandle, addLog);
|
|
3885
|
+
const runningService = {
|
|
3886
|
+
name,
|
|
3887
|
+
process: processHandle,
|
|
3888
|
+
resolved
|
|
3889
|
+
};
|
|
3890
|
+
running.push(runningService);
|
|
3891
|
+
processHandle.exited.then(handleServiceExit.bind(null, runningService));
|
|
3892
|
+
await waitForReady(resolved);
|
|
3893
|
+
const startedAt = serviceBootStartedAt.get(name);
|
|
3894
|
+
const readyDuration = typeof startedAt === "number" ? `ready in ${getDurationString(performance.now() - startedAt)}` : undefined;
|
|
3895
|
+
readyServiceNames.add(name);
|
|
3896
|
+
tui.setServiceStatus(name, "ready", readyDuration);
|
|
3897
|
+
};
|
|
3781
3898
|
const startServices = async () => {
|
|
3782
3899
|
tui.setReadyDuration(null);
|
|
3783
|
-
|
|
3784
|
-
const service = services[name];
|
|
3785
|
-
if (!service) {
|
|
3786
|
-
throw new Error(`services is missing "${name}"`);
|
|
3787
|
-
}
|
|
3788
|
-
const resolved = resolveService(name, service, workspaceEnv, options);
|
|
3789
|
-
const port = (resolved.service.port ?? Number(resolved.env.PORT ?? "")) || DEFAULT_PORT;
|
|
3790
|
-
killStaleServicePort(port);
|
|
3791
|
-
if (isAbsoluteService(resolved.service) && resolved.configPath && !existsSync8(resolved.configPath)) {
|
|
3792
|
-
throw new Error(`${name} references missing config "${resolved.configPath}"`);
|
|
3793
|
-
}
|
|
3794
|
-
serviceBootStartedAt.set(name, performance.now());
|
|
3795
|
-
readyServiceNames.delete(name);
|
|
3796
|
-
tui.setServiceStatus(name, restarting ? "restarting" : "starting");
|
|
3797
|
-
const processHandle = Bun.spawn(resolved.command, {
|
|
3798
|
-
cwd: resolved.cwd,
|
|
3799
|
-
env: resolved.env,
|
|
3800
|
-
stderr: "pipe",
|
|
3801
|
-
stdin: "ignore",
|
|
3802
|
-
stdout: "pipe"
|
|
3803
|
-
});
|
|
3804
|
-
pipeProcessLogs(name, processHandle, addLog);
|
|
3805
|
-
const runningService = {
|
|
3806
|
-
name,
|
|
3807
|
-
process: processHandle,
|
|
3808
|
-
resolved
|
|
3809
|
-
};
|
|
3810
|
-
running.push(runningService);
|
|
3811
|
-
processHandle.exited.then((exitCode) => {
|
|
3812
|
-
if (shuttingDown || restarting) {
|
|
3813
|
-
return;
|
|
3814
|
-
}
|
|
3815
|
-
if (!running.includes(runningService)) {
|
|
3816
|
-
return;
|
|
3817
|
-
}
|
|
3818
|
-
tui.setServiceStatus(name, "error", `exit code ${exitCode || 1}`);
|
|
3819
|
-
readyServiceNames.delete(name);
|
|
3820
|
-
addLog("workspace", `${name} exited with code ${exitCode || 1}. Shutting down workspace.`, "error");
|
|
3821
|
-
shutdown(exitCode || 1);
|
|
3822
|
-
});
|
|
3823
|
-
await waitForReady(resolved);
|
|
3824
|
-
const startedAt = serviceBootStartedAt.get(name);
|
|
3825
|
-
const readyDuration = typeof startedAt === "number" ? `ready in ${getDurationString(performance.now() - startedAt)}` : undefined;
|
|
3826
|
-
readyServiceNames.add(name);
|
|
3827
|
-
tui.setServiceStatus(name, "ready", readyDuration);
|
|
3828
|
-
}
|
|
3900
|
+
await runSequentially(orderedNames, startService);
|
|
3829
3901
|
};
|
|
3830
3902
|
const restartWorkspace = async () => {
|
|
3831
3903
|
if (shuttingDown || restarting) {
|
|
@@ -3910,7 +3982,7 @@ var workspace = async (subcommand, options) => {
|
|
|
3910
3982
|
tui.start();
|
|
3911
3983
|
await startServices();
|
|
3912
3984
|
tui.setReadyDuration(performance.now() - workspaceBootStartedAt);
|
|
3913
|
-
await
|
|
3985
|
+
await Promise.withResolvers().promise;
|
|
3914
3986
|
};
|
|
3915
3987
|
|
|
3916
3988
|
// src/cli/index.ts
|