@lark-apaas/fullstack-cli 1.1.66-alpha.20260902192310 → 1.1.66-alpha.20260903064712

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/fullstack-cli",
3
- "version": "1.1.66-alpha.20260902192310",
3
+ "version": "1.1.66-alpha.20260903064712",
4
4
  "description": "CLI tool for fullstack template management",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -18,6 +18,8 @@ const MAX_MANIFEST_BYTES = 1024 * 1024;
18
18
  const MAX_READINESS_RESPONSE_BYTES = 64 * 1024;
19
19
  const SOURCE_RETRY_INITIAL_DELAY_MS = 250;
20
20
  const SOURCE_RETRY_MAX_DELAY_MS = 5_000;
21
+ const DEFAULT_SOURCE_START_DELAY_MS = 15_000;
22
+ const TEST_SOURCE_START_DELAY_ARG = '--miaoda-test-source-start-delay-ms=';
21
23
  const RUNTIME_CONTROL_ENV_KEYS = new Set([
22
24
  'MIAODA_COLD_START_DECISION_FILE',
23
25
  'MIAODA_DEPENDENCY_READY_FILE',
@@ -91,6 +93,7 @@ const shutdownTimeoutMs = positiveDuration(
91
93
  5_000
92
94
  );
93
95
  const drainTimeoutMs = positiveDuration('MIAODA_NEST_DRAIN_TIMEOUT_MS', 5_000);
96
+ const sourceStartDelayMs = sourceStartDelayForRuntime();
94
97
  const processStartTicks =
95
98
  readLinuxProcessStartTicks(process.pid) ||
96
99
  String(
@@ -221,12 +224,29 @@ let resolveLifetime;
221
224
  const lifetime = new Promise(resolve => {
222
225
  resolveLifetime = resolve;
223
226
  });
227
+ let firstHtmlTransferredAtMs = 0;
228
+ let resolveFirstHtmlTransferred;
229
+ const firstHtmlTransferred = new Promise(resolve => {
230
+ resolveFirstHtmlTransferred = resolve;
231
+ });
224
232
 
225
233
  function positiveDuration(name, fallback) {
226
234
  const value = Number(process.env[name] || fallback);
227
235
  return Number.isFinite(value) && value > 0 ? value : fallback;
228
236
  }
229
237
 
238
+ function sourceStartDelayForRuntime() {
239
+ const testArgument = process.argv
240
+ .slice(2)
241
+ .find(argument => argument.startsWith(TEST_SOURCE_START_DELAY_ARG));
242
+ if (!testArgument) return DEFAULT_SOURCE_START_DELAY_MS;
243
+ const value = Number(testArgument.slice(TEST_SOURCE_START_DELAY_ARG.length));
244
+ if (!Number.isFinite(value) || value < 0) {
245
+ throw new Error('MIAODA_NEST_TEST_SOURCE_START_DELAY_INVALID');
246
+ }
247
+ return value;
248
+ }
249
+
230
250
  function validateRuntimeConfiguration() {
231
251
  if (process.env.MIAODA_NEST_BUNDLE_HANDOFF_ENABLED !== 'true') {
232
252
  throw new Error('MIAODA_NEST_BUNDLE_HANDOFF_DISABLED');
@@ -964,6 +984,36 @@ function retain(upstream) {
964
984
  };
965
985
  }
966
986
 
987
+ function observeFirstCacheHtmlTransfer(request, response, upstreamResponse) {
988
+ if (
989
+ firstHtmlTransferredAtMs ||
990
+ request.method !== 'GET' ||
991
+ activeUpstream !== cacheUpstream ||
992
+ upstreamResponse.statusCode < 200 ||
993
+ upstreamResponse.statusCode >= 400 ||
994
+ !String(upstreamResponse.headers['content-type'] || '')
995
+ .toLowerCase()
996
+ .startsWith('text/html')
997
+ ) {
998
+ return;
999
+ }
1000
+ response.once('finish', () => {
1001
+ if (firstHtmlTransferredAtMs) return;
1002
+ firstHtmlTransferredAtMs = Date.now();
1003
+ resolveFirstHtmlTransferred(firstHtmlTransferredAtMs);
1004
+ process.stderr.write(
1005
+ `${JSON.stringify({
1006
+ event: 'miaoda_nest_html_transferred',
1007
+ bootId,
1008
+ generationId: currentGenerationId,
1009
+ sourceStartDelayMs,
1010
+ atMs: firstHtmlTransferredAtMs,
1011
+ elapsedMs: firstHtmlTransferredAtMs - restoreEpochMs,
1012
+ })}\n`
1013
+ );
1014
+ });
1015
+ }
1016
+
967
1017
  function createProxy() {
968
1018
  const server = http.createServer((request, response) => {
969
1019
  const upstream = activeUpstream;
@@ -982,6 +1032,7 @@ function createProxy() {
982
1032
  headers: request.headers,
983
1033
  },
984
1034
  upstreamResponse => {
1035
+ observeFirstCacheHtmlTransfer(request, response, upstreamResponse);
985
1036
  response.writeHead(
986
1037
  upstreamResponse.statusCode || 502,
987
1038
  upstreamResponse.statusMessage || '',
@@ -1590,6 +1641,18 @@ async function waitForReceipt(expectedGenerationId) {
1590
1641
  if (shuttingDown) throw new Error('MIAODA_NEST_RUNTIME_STOPPING');
1591
1642
  }
1592
1643
 
1644
+ async function waitForSourceStartWindow() {
1645
+ if (sourceStartDelayMs === 0) return;
1646
+ const htmlTransferredAtMs = await firstHtmlTransferred;
1647
+ const deadline = htmlTransferredAtMs + sourceStartDelayMs;
1648
+ while (!shuttingDown && Date.now() < deadline) {
1649
+ await new Promise(resolve =>
1650
+ setTimeout(resolve, Math.min(50, deadline - Date.now()))
1651
+ );
1652
+ }
1653
+ if (shuttingDown) throw new Error('MIAODA_NEST_RUNTIME_STOPPING');
1654
+ }
1655
+
1593
1656
  async function runActionPluginInit(baseEnv) {
1594
1657
  const record = spawnOwned(
1595
1658
  'action-plugin-init',
@@ -1708,6 +1771,21 @@ async function startAndPromoteSource(baseEnv, expectedCapabilityIds) {
1708
1771
 
1709
1772
  async function promoteSource(expectedGenerationId, expectedCapabilityIds) {
1710
1773
  await waitForReceipt(expectedGenerationId);
1774
+ await waitForSourceStartWindow();
1775
+ const sourceStartingAtMs = Date.now();
1776
+ process.stderr.write(
1777
+ `${JSON.stringify({
1778
+ event: 'miaoda_nest_source_starting',
1779
+ bootId,
1780
+ generationId: currentGenerationId,
1781
+ sourceStartDelayMs,
1782
+ atMs: sourceStartingAtMs,
1783
+ elapsedMs: sourceStartingAtMs - restoreEpochMs,
1784
+ htmlToSourceStartMs: firstHtmlTransferredAtMs
1785
+ ? sourceStartingAtMs - firstHtmlTransferredAtMs
1786
+ : 0,
1787
+ })}\n`
1788
+ );
1711
1789
  let retryDelayMs = SOURCE_RETRY_INITIAL_DELAY_MS;
1712
1790
  let baseEnv;
1713
1791
  while (!shuttingDown && !baseEnv) {