veryfront 0.1.1168 → 0.1.1169

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.
@@ -1,3 +1,27 @@
1
+ type StartupErrorReporter = {
2
+ captureApplicationError: (error: unknown, context: {
3
+ boundary: string;
4
+ }) => string | undefined;
5
+ flushApplicationErrors: (timeoutMs?: number) => Promise<boolean>;
6
+ onReportingError?: (operation: "capture" | "flush", error: unknown) => void;
7
+ };
8
+ type StartupErrorReportingOptions = {
9
+ flushTimeoutMs?: number;
10
+ };
11
+ type ProductionServerDependencies = {
12
+ ensureBundlerContracts?: () => Promise<void>;
13
+ initializeErrorReporting?: () => Promise<unknown>;
14
+ loadSentryModule?: () => Promise<ProductionSentryModule>;
15
+ reporter?: StartupErrorReporter;
16
+ };
17
+ type ServeCommandDependencies = {
18
+ runProductionServer?: (options: ServeOptions) => Promise<void>;
19
+ };
20
+ type ProductionSentryModule = {
21
+ captureApplicationError: StartupErrorReporter["captureApplicationError"];
22
+ flushApplicationErrors: StartupErrorReporter["flushApplicationErrors"];
23
+ initializeSentryFromEnv: () => Promise<unknown>;
24
+ };
1
25
  export interface ServeOptions {
2
26
  mode: "combined" | "proxy" | "production";
3
27
  port: number;
@@ -7,5 +31,9 @@ export interface ServeOptions {
7
31
  binaryPath: string;
8
32
  debug: boolean;
9
33
  }
10
- export declare function serveCommand(options: ServeOptions): Promise<void>;
34
+ export declare function runWithStartupErrorReporting<T>(startup: () => Promise<T>, reporter: StartupErrorReporter, options?: StartupErrorReportingOptions): Promise<T>;
35
+ export declare function runProductionStartupWithErrorReporting<T>(startup: () => Promise<T>, reporter: StartupErrorReporter, ensureBundlerContracts?: () => Promise<void>, initializeObservability?: () => Promise<unknown>): Promise<T>;
36
+ export declare function runProductionServer(options: ServeOptions, dependencies?: ProductionServerDependencies): Promise<void>;
37
+ export declare function serveCommand(options: ServeOptions, dependencies?: ServeCommandDependencies): Promise<void>;
38
+ export {};
11
39
  //# sourceMappingURL=command.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/serve/command.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,YAAY,CAAC;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;CAChB;AAwGD,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAcvE"}
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/serve/command.ts"],"names":[],"mappings":"AAUA,KAAK,oBAAoB,GAAG;IAC1B,uBAAuB,EAAE,CACvB,KAAK,EAAE,OAAO,EACd,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,KAC1B,MAAM,GAAG,SAAS,CAAC;IACxB,sBAAsB,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACjE,gBAAgB,CAAC,EAAE,CACjB,SAAS,EAAE,SAAS,GAAG,OAAO,EAC9B,KAAK,EAAE,OAAO,KACX,IAAI,CAAC;CACX,CAAC;AAEF,KAAK,4BAA4B,GAAG;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,KAAK,4BAA4B,GAAG;IAClC,sBAAsB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,wBAAwB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACzD,QAAQ,CAAC,EAAE,oBAAoB,CAAC;CACjC,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC9B,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChE,CAAC;AAEF,KAAK,sBAAsB,GAAG;IAC5B,uBAAuB,EAAE,oBAAoB,CAAC,yBAAyB,CAAC,CAAC;IACzE,sBAAsB,EAAE,oBAAoB,CAAC,wBAAwB,CAAC,CAAC;IACvE,uBAAuB,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CACjD,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,YAAY,CAAC;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,4BAA4B,CAAC,CAAC,EAClD,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACzB,QAAQ,EAAE,oBAAoB,EAC9B,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,CAAC,CAAC,CAqBZ;AAoCD,wBAAsB,sCAAsC,CAAC,CAAC,EAC5D,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACzB,QAAQ,EAAE,oBAAoB,EAC9B,sBAAsB,GAAE,MAAM,OAAO,CAAC,IAAI,CAA6B,EACvE,uBAAuB,GAAE,MAAM,OAAO,CAAC,OAAO,CAA2B,GACxE,OAAO,CAAC,CAAC,CAAC,CAMZ;AAoED,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,YAAY,EACrB,YAAY,GAAE,4BAAiC,GAC9C,OAAO,CAAC,IAAI,CAAC,CAgFf;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,EACrB,YAAY,GAAE,wBAA6B,GAC1C,OAAO,CAAC,IAAI,CAAC,CAcf"}
@@ -4,6 +4,64 @@ import { cliLogger } from "../../utils/index.js";
4
4
  import { exitProcess, registerTerminationSignals, showLogo } from "../../utils/index.js";
5
5
  import { generateDefaultProjectId } from "../../utils/project.js";
6
6
  import { startCliProductionServer } from "../../shared/server-startup.js";
7
+ import { ensureCliBundlerContracts } from "../../shared/default-contracts.js";
8
+ const STARTUP_ERROR_FLUSH_TIMEOUT_MS = 2_000;
9
+ export async function runWithStartupErrorReporting(startup, reporter, options = {}) {
10
+ const flushTimeoutMs = options.flushTimeoutMs ?? STARTUP_ERROR_FLUSH_TIMEOUT_MS;
11
+ try {
12
+ return await startup();
13
+ }
14
+ catch (error) {
15
+ const reportingDeadline = Date.now() + flushTimeoutMs;
16
+ try {
17
+ reporter.captureApplicationError(error, { boundary: "process.startup" });
18
+ }
19
+ catch (reportingError) {
20
+ notifyReportingError(reporter, "capture", reportingError);
21
+ }
22
+ try {
23
+ await flushReporterWithDeadline(reporter, Math.max(0, reportingDeadline - Date.now()));
24
+ }
25
+ catch (reportingError) {
26
+ notifyReportingError(reporter, "flush", reportingError);
27
+ }
28
+ throw error;
29
+ }
30
+ }
31
+ function notifyReportingError(reporter, operation, error) {
32
+ try {
33
+ reporter.onReportingError?.(operation, error);
34
+ }
35
+ catch {
36
+ // Diagnostics must never replace the startup failure being reported.
37
+ }
38
+ }
39
+ async function flushReporterWithDeadline(reporter, timeoutMs) {
40
+ let timeoutId;
41
+ const flush = Promise.resolve()
42
+ .then(() => reporter.flushApplicationErrors(timeoutMs))
43
+ .catch((error) => {
44
+ notifyReportingError(reporter, "flush", error);
45
+ return false;
46
+ });
47
+ const deadline = new Promise((resolve) => {
48
+ timeoutId = setTimeout(() => resolve(false), timeoutMs);
49
+ });
50
+ try {
51
+ return await Promise.race([flush, deadline]);
52
+ }
53
+ finally {
54
+ if (timeoutId !== undefined)
55
+ clearTimeout(timeoutId);
56
+ }
57
+ }
58
+ export async function runProductionStartupWithErrorReporting(startup, reporter, ensureBundlerContracts = ensureCliBundlerContracts, initializeObservability = () => Promise.resolve()) {
59
+ return await runWithStartupErrorReporting(async () => {
60
+ await initializeObservability();
61
+ await ensureBundlerContracts();
62
+ return await startup();
63
+ }, reporter);
64
+ }
7
65
  async function runSplit(options) {
8
66
  showLogo();
9
67
  const { runSplitMode } = await import("./split-mode.js");
@@ -28,32 +86,63 @@ async function runProxy(options) {
28
86
  // Keep the process alive (Deno.serve returns immediately in compiled binaries)
29
87
  await new Promise(() => { });
30
88
  }
31
- async function runProductionServer(options) {
89
+ function createDeferredProductionStartupErrorReporter() {
90
+ let sentryModule;
91
+ return {
92
+ reporter: {
93
+ // If Sentry module acquisition fails, no remote transport exists yet.
94
+ // Preserve the acquisition failure and bound flush instead of adding a
95
+ // fallback reporter inside the startup path.
96
+ captureApplicationError: (error, context) => sentryModule?.captureApplicationError(error, context),
97
+ flushApplicationErrors: (timeoutMs) => sentryModule?.flushApplicationErrors(timeoutMs) ?? Promise.resolve(true),
98
+ onReportingError: (operation, error) => {
99
+ cliLogger.warn(`Error reporter failed to ${operation} production startup failure.`);
100
+ cliLogger.debug(`Error reporter ${operation} failure details:`, error);
101
+ },
102
+ },
103
+ setSentryModule: (loadedSentryModule) => {
104
+ sentryModule = loadedSentryModule;
105
+ },
106
+ };
107
+ }
108
+ function loadProductionSentryModule() {
109
+ return import("../../../src/observability/sentry.js");
110
+ }
111
+ export async function runProductionServer(options, dependencies = {}) {
32
112
  showLogo();
33
- const { captureApplicationError, flushApplicationErrors, initializeSentryFromEnv, } = await import("../../../src/observability/sentry.js");
34
- await initializeSentryFromEnv();
35
- const { clearAllLocalCaches } = await import("../../../src/transforms/mdx/esm-module-loader/cache/index.js");
36
- await clearAllLocalCaches();
37
- const { initializeOTLPWithApis } = await import("../../../src/observability/tracing/otlp-setup.js");
38
- const { initializeDistributedCaches } = await import("../../../src/cache/index.js");
39
- const { defaultDistributedCacheInitializers } = await import("../../../src/server/index.js");
40
- await Promise.allSettled([
41
- initializeOTLPWithApis(),
42
- initializeDistributedCaches(defaultDistributedCacheInitializers),
43
- ]);
44
- const projectDir = cwd();
45
- const shutdownController = new AbortController();
46
- const defaultProjectId = generateDefaultProjectId(projectDir);
47
- const server = await startCliProductionServer({
48
- projectDir,
49
- port: options.port,
50
- bindAddress: options.bindAddress,
51
- debug: options.debug,
52
- signal: shutdownController.signal,
53
- defaultProjectSlug: defaultProjectId,
54
- defaultProjectId,
55
- });
56
- await server.ready;
113
+ const deferredReporter = createDeferredProductionStartupErrorReporter();
114
+ const reporter = dependencies.reporter ?? deferredReporter.reporter;
115
+ const initializeErrorReporting = dependencies.initializeErrorReporting ??
116
+ (async () => {
117
+ const sentryModule = await (dependencies.loadSentryModule ?? loadProductionSentryModule)();
118
+ deferredReporter.setSentryModule(sentryModule);
119
+ await sentryModule.initializeSentryFromEnv();
120
+ });
121
+ const { server, shutdownController } = await runProductionStartupWithErrorReporting(async () => {
122
+ const { clearAllLocalCaches } = await import("../../../src/transforms/mdx/esm-module-loader/cache/index.js");
123
+ await clearAllLocalCaches();
124
+ const { initializeOTLPWithApis } = await import("../../../src/observability/tracing/otlp-setup.js");
125
+ const { initializeDistributedCaches } = await import("../../../src/cache/index.js");
126
+ const { defaultDistributedCacheInitializers } = await import("../../../src/server/index.js");
127
+ await Promise.allSettled([
128
+ initializeOTLPWithApis(),
129
+ initializeDistributedCaches(defaultDistributedCacheInitializers),
130
+ ]);
131
+ const projectDir = cwd();
132
+ const shutdownController = new AbortController();
133
+ const defaultProjectId = generateDefaultProjectId(projectDir);
134
+ const server = await startCliProductionServer({
135
+ projectDir,
136
+ port: options.port,
137
+ bindAddress: options.bindAddress,
138
+ debug: options.debug,
139
+ signal: shutdownController.signal,
140
+ defaultProjectSlug: defaultProjectId,
141
+ defaultProjectId,
142
+ });
143
+ await server.ready;
144
+ return { server, shutdownController };
145
+ }, reporter, dependencies.ensureBundlerContracts ?? ensureCliBundlerContracts, initializeErrorReporting);
57
146
  let shuttingDown = false;
58
147
  const shutdown = async (signal) => {
59
148
  if (shuttingDown)
@@ -68,18 +157,18 @@ async function runProductionServer(options) {
68
157
  });
69
158
  }
70
159
  catch (error) {
71
- captureApplicationError(error, { boundary: "process.shutdown" });
160
+ reporter.captureApplicationError(error, { boundary: "process.shutdown" });
72
161
  cliLogger.warn("Error while shutting down production server:", error);
73
162
  }
74
163
  finally {
75
- await flushApplicationErrors();
164
+ await reporter.flushApplicationErrors();
76
165
  exitProcess(0);
77
166
  }
78
167
  };
79
168
  registerTerminationSignals(shutdown);
80
169
  await new Promise(() => { });
81
170
  }
82
- export async function serveCommand(options) {
171
+ export async function serveCommand(options, dependencies = {}) {
83
172
  if (options.splitMode) {
84
173
  await runSplit(options);
85
174
  return;
@@ -89,6 +178,6 @@ export async function serveCommand(options) {
89
178
  return;
90
179
  }
91
180
  if (options.mode === "production" || options.mode === "combined") {
92
- await runProductionServer(options);
181
+ await (dependencies.runProductionServer ?? runProductionServer)(options);
93
182
  }
94
183
  }
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/serve/handler.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAyBxD,QAAA,MAAM,kBAAkB;;;;;;;;GAQtB,CAAC;AAEH,eAAO,MAAM,cAAc,EAAE,OAAO,kBAgBnC,CAAC;AAEF,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAaxE"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/serve/handler.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAgCxD,QAAA,MAAM,kBAAkB;;;;;;;;GAQtB,CAAC;AAEH,eAAO,MAAM,cAAc,EAAE,OAAO,kBAgBnC,CAAC;AAEF,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAexE"}
@@ -1,12 +1,19 @@
1
1
  import { defineSchema, lazySchema } from "../../../src/schemas/index.js";
2
- import { getEnv, getEnvNumber } from "../../../src/platform/compat/process.js";
2
+ import { getEnv } from "../../../src/platform/index.js";
3
3
  import { DEFAULT_DEV_SERVER_PORT } from "../../utils/index.js";
4
4
  import { ServerModeSchema } from "../../shared/types.js";
5
5
  import { createArgParser, parseArgsOrThrow } from "../../shared/args.js";
6
6
  import { ensureCliBundlerContracts } from "../../shared/default-contracts.js";
7
+ function readPortEnv(name, fallback) {
8
+ const value = getEnv(name);
9
+ if (value === undefined)
10
+ return fallback;
11
+ const port = Number.parseInt(value, 10);
12
+ return Number.isNaN(port) ? fallback : port;
13
+ }
7
14
  function getDefaultServePort() {
8
- const veryfrontPort = getEnvNumber("VERYFRONT_PORT", DEFAULT_DEV_SERVER_PORT);
9
- return getEnvNumber("PORT", veryfrontPort);
15
+ const veryfrontPort = readPortEnv("VERYFRONT_PORT", DEFAULT_DEV_SERVER_PORT);
16
+ return readPortEnv("PORT", veryfrontPort);
10
17
  }
11
18
  function getDefaultBindAddress() {
12
19
  return getEnv("BIND_ADDRESS")?.trim() || "0.0.0.0";
@@ -49,7 +56,9 @@ export const parseServeArgs = (args) => {
49
56
  };
50
57
  export async function handleServeCommand(args) {
51
58
  const opts = parseArgsOrThrow(parseServeArgs, "serve", args);
52
- await ensureCliBundlerContracts();
59
+ if (opts.split || opts.mode === "proxy") {
60
+ await ensureCliBundlerContracts();
61
+ }
53
62
  const { serveCommand } = await import("./command.js");
54
63
  await serveCommand({
55
64
  mode: opts.mode,
package/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.1168",
3
+ "version": "0.1.1169",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "minimumDependencyAge": {
@@ -1,3 +1,3 @@
1
1
  /** Shared version value. */
2
- export declare const VERSION = "0.1.1168";
2
+ export declare const VERSION = "0.1.1169";
3
3
  //# sourceMappingURL=version-constant.d.ts.map
@@ -1,4 +1,4 @@
1
1
  // Keep in sync with deno.json version.
2
2
  // scripts/release.ts updates this constant during releases.
3
3
  /** Shared version value. */
4
- export const VERSION = "0.1.1168";
4
+ export const VERSION = "0.1.1169";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.1.1168",
3
+ "version": "0.1.1169",
4
4
  "description": "The simplest way to build AI-powered apps",
5
5
  "keywords": [
6
6
  "react",
@@ -336,10 +336,10 @@
336
336
  "@types/react": "19.2.14",
337
337
  "@types/react-dom": "19.2.3",
338
338
  "ws": "8.21.0",
339
- "@veryfront/ext-bundler-esbuild": "0.1.1168",
340
- "@veryfront/ext-content-mdx": "0.1.1168",
341
- "@veryfront/ext-css-tailwind": "0.1.1168",
342
- "@veryfront/ext-parser-babel": "0.1.1168"
339
+ "@veryfront/ext-bundler-esbuild": "0.1.1169",
340
+ "@veryfront/ext-content-mdx": "0.1.1169",
341
+ "@veryfront/ext-css-tailwind": "0.1.1169",
342
+ "@veryfront/ext-parser-babel": "0.1.1169"
343
343
  },
344
344
  "devDependencies": {
345
345
  "@types/node": "20.9.0"