@vistagenic/vista 0.2.10 → 0.2.13

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.
Files changed (77) hide show
  1. package/bin/vista.js +183 -36
  2. package/dist/bin/build-rsc-flashpack.d.ts +4 -0
  3. package/dist/bin/build-rsc-flashpack.js +29 -0
  4. package/dist/bin/build-rsc.js +61 -16
  5. package/dist/bin/build.js +36 -13
  6. package/dist/bin/devtools-indicator-snippet.js +30 -0
  7. package/dist/bin/file-scanner.d.ts +1 -1
  8. package/dist/bin/file-scanner.js +8 -0
  9. package/dist/bin/flashpack-runner.d.ts +1 -0
  10. package/dist/bin/flashpack-runner.js +61 -0
  11. package/dist/bin/server-component-plugin.d.ts +6 -4
  12. package/dist/bin/server-component-plugin.js +22 -69
  13. package/dist/bin/webpack.config.d.ts +3 -0
  14. package/dist/bin/webpack.config.js +12 -3
  15. package/dist/build/manifest.d.ts +17 -3
  16. package/dist/build/manifest.js +99 -23
  17. package/dist/build/rsc/compiler.d.ts +2 -0
  18. package/dist/build/rsc/compiler.js +25 -5
  19. package/dist/build/rsc/react-client-reference-manifest.d.ts +22 -0
  20. package/dist/build/rsc/react-client-reference-manifest.js +219 -0
  21. package/dist/build/rsc/server-manifest.d.ts +23 -2
  22. package/dist/build/rsc/server-manifest.js +162 -24
  23. package/dist/build/standalone.d.ts +31 -0
  24. package/dist/build/standalone.js +334 -0
  25. package/dist/client/rsc-router.d.ts +31 -0
  26. package/dist/client/rsc-router.js +89 -0
  27. package/dist/config.d.ts +23 -0
  28. package/dist/config.js +106 -5
  29. package/dist/constants.d.ts +2 -0
  30. package/dist/constants.js +3 -1
  31. package/dist/flashpack/command.d.ts +8 -0
  32. package/dist/flashpack/command.js +134 -0
  33. package/dist/flashpack/runtime.d.ts +39 -0
  34. package/dist/flashpack/runtime.js +249 -0
  35. package/dist/server/app-router-runtime.d.ts +26 -0
  36. package/dist/server/app-router-runtime.js +321 -0
  37. package/dist/server/artifact-validator.js +21 -1
  38. package/dist/server/cache.d.ts +10 -0
  39. package/dist/server/cache.js +270 -0
  40. package/dist/server/client-boundary.js +20 -2
  41. package/dist/server/engine.js +236 -159
  42. package/dist/server/fetch-policy.d.ts +2 -0
  43. package/dist/server/fetch-policy.js +123 -0
  44. package/dist/server/index.d.ts +7 -0
  45. package/dist/server/index.js +131 -22
  46. package/dist/server/module-boundary-validator.d.ts +15 -0
  47. package/dist/server/module-boundary-validator.js +262 -0
  48. package/dist/server/module-compile-hook.d.ts +7 -0
  49. package/dist/server/module-compile-hook.js +662 -0
  50. package/dist/server/ppr.d.ts +18 -0
  51. package/dist/server/ppr.js +59 -0
  52. package/dist/server/request-context.d.ts +31 -0
  53. package/dist/server/request-context.js +95 -0
  54. package/dist/server/rsc-engine-flashpack.d.ts +4 -0
  55. package/dist/server/rsc-engine-flashpack.js +27 -0
  56. package/dist/server/rsc-engine.d.ts +2 -0
  57. package/dist/server/rsc-engine.js +589 -317
  58. package/dist/server/rsc-upstream.js +539 -233
  59. package/dist/server/runtime-actions.d.ts +5 -0
  60. package/dist/server/runtime-actions.js +80 -0
  61. package/dist/server/runtime-artifacts.d.ts +11 -0
  62. package/dist/server/runtime-artifacts.js +35 -0
  63. package/dist/server/segment-config.d.ts +37 -0
  64. package/dist/server/segment-config.js +205 -0
  65. package/dist/server/spawn-permissions.d.ts +2 -0
  66. package/dist/server/spawn-permissions.js +21 -0
  67. package/dist/server/static-cache.d.ts +15 -1
  68. package/dist/server/static-cache.js +83 -3
  69. package/dist/server/static-generator.js +254 -100
  70. package/dist/server/structure-validator.d.ts +1 -1
  71. package/dist/server/structure-validator.js +26 -5
  72. package/dist/server/structure-watch.js +1 -1
  73. package/dist/server/typed-api-runtime.d.ts +1 -0
  74. package/dist/server/typed-api-runtime.js +145 -25
  75. package/dist/server/vista-import-map.d.ts +1 -0
  76. package/dist/server/vista-import-map.js +123 -0
  77. package/package.json +13 -1
package/dist/config.js CHANGED
@@ -3,12 +3,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.defaultConfig = exports.defaultTypedApiConfig = exports.defaultStructureValidationConfig = void 0;
6
+ exports.defaultConfig = exports.defaultCacheComponentsConfig = exports.defaultTypedApiConfig = exports.defaultStructureValidationConfig = void 0;
7
7
  exports.resolveStructureValidationConfig = resolveStructureValidationConfig;
8
+ exports.resolveEngineVariant = resolveEngineVariant;
9
+ exports.applyEngineVariantToEnv = applyEngineVariantToEnv;
10
+ exports.resolveAndApplyEngineVariant = resolveAndApplyEngineVariant;
8
11
  exports.resolveTypedApiConfig = resolveTypedApiConfig;
12
+ exports.resolveCacheComponentsConfig = resolveCacheComponentsConfig;
9
13
  exports.loadConfig = loadConfig;
10
14
  const path_1 = __importDefault(require("path"));
11
15
  const fs_1 = __importDefault(require("fs"));
16
+ const NodeModule = require('module');
12
17
  exports.defaultStructureValidationConfig = {
13
18
  enabled: true,
14
19
  mode: 'strict',
@@ -21,13 +26,20 @@ exports.defaultTypedApiConfig = {
21
26
  serialization: 'json',
22
27
  bodySizeLimitBytes: 1024 * 1024,
23
28
  };
29
+ exports.defaultCacheComponentsConfig = {
30
+ enabled: false,
31
+ };
24
32
  exports.defaultConfig = {
25
33
  images: {},
34
+ engine: {
35
+ variant: 'default',
36
+ },
26
37
  validation: {
27
38
  structure: { ...exports.defaultStructureValidationConfig },
28
39
  },
29
40
  experimental: {
30
41
  typedApi: { ...exports.defaultTypedApiConfig },
42
+ cacheComponents: { ...exports.defaultCacheComponentsConfig },
31
43
  },
32
44
  };
33
45
  /**
@@ -39,6 +51,49 @@ function resolveStructureValidationConfig(config) {
39
51
  ...(config.validation?.structure ?? {}),
40
52
  };
41
53
  }
54
+ function normalizeEngineVariant(raw) {
55
+ const value = String(raw ?? '')
56
+ .trim()
57
+ .toLowerCase();
58
+ if (!value)
59
+ return undefined;
60
+ if (value === 'default' || value === 'webpack')
61
+ return 'default';
62
+ if (value === 'flashpack')
63
+ return 'flashpack';
64
+ return undefined;
65
+ }
66
+ function readEngineVariantFromConfig(config) {
67
+ if (!config || !config.engine)
68
+ return undefined;
69
+ if (typeof config.engine === 'string') {
70
+ return normalizeEngineVariant(config.engine);
71
+ }
72
+ return normalizeEngineVariant(config.engine.variant);
73
+ }
74
+ function readEngineVariantFromEnv(env) {
75
+ const explicit = normalizeEngineVariant(env.VISTA_ENGINE_VARIANT || env.VISTA_ENGINE);
76
+ if (explicit)
77
+ return explicit;
78
+ if (env.VISTA_FLASHPACK === 'true')
79
+ return 'flashpack';
80
+ if (env.VISTA_FLASHPACK === 'false')
81
+ return 'default';
82
+ return undefined;
83
+ }
84
+ function resolveEngineVariant(config, env = process.env) {
85
+ return readEngineVariantFromEnv(env) || readEngineVariantFromConfig(config) || 'default';
86
+ }
87
+ function applyEngineVariantToEnv(variant, env = process.env) {
88
+ env.VISTA_ENGINE = variant;
89
+ env.VISTA_ENGINE_VARIANT = variant;
90
+ env.VISTA_FLASHPACK = variant === 'flashpack' ? 'true' : 'false';
91
+ return variant;
92
+ }
93
+ function resolveAndApplyEngineVariant(config, env = process.env) {
94
+ const variant = resolveEngineVariant(config, env);
95
+ return applyEngineVariantToEnv(variant, env);
96
+ }
42
97
  /**
43
98
  * Resolve and sanitize experimental typed API config.
44
99
  */
@@ -58,10 +113,28 @@ function resolveTypedApiConfig(config) {
58
113
  bodySizeLimitBytes,
59
114
  };
60
115
  }
61
- function mergeConfig(userConfig) {
116
+ function resolveCacheComponentsConfig(config) {
117
+ const merged = {
118
+ ...exports.defaultCacheComponentsConfig,
119
+ ...(config.experimental?.cacheComponents ?? {}),
120
+ };
62
121
  return {
122
+ enabled: Boolean(merged.enabled),
123
+ };
124
+ }
125
+ function mergeConfig(userConfig) {
126
+ const mergedBase = {
63
127
  ...exports.defaultConfig,
64
128
  ...userConfig,
129
+ };
130
+ const resolvedEngineVariant = readEngineVariantFromConfig(userConfig) ||
131
+ readEngineVariantFromConfig(exports.defaultConfig) ||
132
+ 'default';
133
+ return {
134
+ ...mergedBase,
135
+ engine: {
136
+ variant: resolvedEngineVariant,
137
+ },
65
138
  images: {
66
139
  ...(exports.defaultConfig.images ?? {}),
67
140
  ...(userConfig.images ?? {}),
@@ -85,20 +158,48 @@ function mergeConfig(userConfig) {
85
158
  ...exports.defaultTypedApiConfig,
86
159
  ...(userConfig.experimental?.typedApi ?? {}),
87
160
  },
161
+ cacheComponents: {
162
+ ...exports.defaultCacheComponentsConfig,
163
+ ...(userConfig.experimental?.cacheComponents ?? {}),
164
+ },
88
165
  },
89
166
  };
90
167
  }
168
+ function loadBundledConfigModule(configPath, cwd) {
169
+ const { buildSync } = require('esbuild');
170
+ const result = buildSync({
171
+ entryPoints: [configPath],
172
+ absWorkingDir: cwd,
173
+ bundle: true,
174
+ platform: 'node',
175
+ format: 'cjs',
176
+ target: ['node20'],
177
+ write: false,
178
+ packages: 'external',
179
+ sourcemap: false,
180
+ logLevel: 'silent',
181
+ });
182
+ const bundledConfig = result.outputFiles?.[0]?.text;
183
+ if (!bundledConfig) {
184
+ throw new Error(`Failed to bundle config: ${configPath}`);
185
+ }
186
+ const virtualConfigPath = path_1.default.join(path_1.default.dirname(configPath), `.__vista_config_runtime__.${path_1.default.basename(configPath, path_1.default.extname(configPath))}.cjs`);
187
+ const runtimeModule = new NodeModule(virtualConfigPath, module);
188
+ runtimeModule.filename = virtualConfigPath;
189
+ runtimeModule.paths = NodeModule._nodeModulePaths(path_1.default.dirname(configPath));
190
+ runtimeModule._compile(bundledConfig, virtualConfigPath);
191
+ return runtimeModule.exports;
192
+ }
91
193
  function loadConfig(cwd = process.cwd()) {
92
194
  const tsPath = path_1.default.join(cwd, 'vista.config.ts');
93
195
  const jsPath = path_1.default.join(cwd, 'vista.config.js');
94
196
  try {
95
197
  if (fs_1.default.existsSync(tsPath)) {
96
- // We assume ts-node is registered by engine or bin
97
- const mod = require(tsPath);
198
+ const mod = loadBundledConfigModule(tsPath, cwd);
98
199
  return mergeConfig(mod.default || mod);
99
200
  }
100
201
  else if (fs_1.default.existsSync(jsPath)) {
101
- const mod = require(jsPath);
202
+ const mod = loadBundledConfigModule(jsPath, cwd);
102
203
  return mergeConfig(mod.default || mod);
103
204
  }
104
205
  }
@@ -8,6 +8,8 @@
8
8
  export declare const FRAMEWORK_NAME = "vista";
9
9
  /** Hidden build output directory name */
10
10
  export declare const BUILD_DIR = ".vista";
11
+ /** Flashpack workspace/runtime directory name */
12
+ export declare const FLASH_DIR = ".flash";
11
13
  /** Base URL prefix for all framework-served assets */
12
14
  export declare const URL_PREFIX = "/_vista";
13
15
  /** Static chunks URL path */
package/dist/constants.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * only this file (and the Rust equivalent naming.rs) needs to change.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.LOG_IGNORE_PREFIXES = exports.LOCAL_FONT_PREFIX = exports.MOUNT_ID_PREFIX = exports.THEME_SETTER = exports.WRAPPED_MARKER = exports.CLIENT_COMPONENTS_FLAG = exports.CLIENT_MANIFEST_FLAG = exports.SERVER_DEFINE = exports.BUILD_ID_DEFINE = exports.RSC_DATA_FLAG = exports.CLIENT_REFS_FLAG = exports.CONFIG_FLAG = exports.HYDRATE_DOCUMENT_FLAG = exports.STRUCTURE_ENDPOINT = exports.SSE_ENDPOINT = exports.IMAGE_ENDPOINT = exports.STATIC_CHUNKS_PATH = exports.URL_PREFIX = exports.BUILD_DIR = exports.FRAMEWORK_NAME = void 0;
9
+ exports.LOG_IGNORE_PREFIXES = exports.LOCAL_FONT_PREFIX = exports.MOUNT_ID_PREFIX = exports.THEME_SETTER = exports.WRAPPED_MARKER = exports.CLIENT_COMPONENTS_FLAG = exports.CLIENT_MANIFEST_FLAG = exports.SERVER_DEFINE = exports.BUILD_ID_DEFINE = exports.RSC_DATA_FLAG = exports.CLIENT_REFS_FLAG = exports.CONFIG_FLAG = exports.HYDRATE_DOCUMENT_FLAG = exports.STRUCTURE_ENDPOINT = exports.SSE_ENDPOINT = exports.IMAGE_ENDPOINT = exports.STATIC_CHUNKS_PATH = exports.URL_PREFIX = exports.FLASH_DIR = exports.BUILD_DIR = exports.FRAMEWORK_NAME = void 0;
10
10
  // ============================================================================
11
11
  // Framework Identity
12
12
  // ============================================================================
@@ -17,6 +17,8 @@ exports.FRAMEWORK_NAME = 'vista';
17
17
  // ============================================================================
18
18
  /** Hidden build output directory name */
19
19
  exports.BUILD_DIR = '.vista';
20
+ /** Flashpack workspace/runtime directory name */
21
+ exports.FLASH_DIR = '.flash';
20
22
  // ============================================================================
21
23
  // URL Prefixes (/_vista/ — equivalent to Next.js /_next/)
22
24
  // ============================================================================
@@ -0,0 +1,8 @@
1
+ type FlashpackCommandPhase = 'dev' | 'build' | 'start';
2
+ interface RunFlashpackCommandOptions {
3
+ cwd?: string;
4
+ port?: string | number;
5
+ strict?: boolean;
6
+ }
7
+ export declare function runFlashpackEngineCommand(phase: FlashpackCommandPhase, options?: RunFlashpackCommandOptions): Promise<void>;
8
+ export default runFlashpackEngineCommand;
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.runFlashpackEngineCommand = runFlashpackEngineCommand;
7
+ const path_1 = __importDefault(require("path"));
8
+ const child_process_1 = require("child_process");
9
+ const build_rsc_1 = require("../bin/build-rsc");
10
+ const rsc_engine_1 = require("../server/rsc-engine");
11
+ const spawn_permissions_1 = require("../server/spawn-permissions");
12
+ const runtime_1 = require("./runtime");
13
+ function resolveMode(phase) {
14
+ if (phase === 'dev') {
15
+ return 'development';
16
+ }
17
+ return process.env.NODE_ENV === 'development' ? 'development' : 'production';
18
+ }
19
+ function getRunnerPath() {
20
+ return path_1.default.resolve(__dirname, '..', 'bin', 'flashpack-runner.js');
21
+ }
22
+ function formatRustFailure(message) {
23
+ return `[flashpack] Rust command unavailable: ${message}`;
24
+ }
25
+ async function fallbackToCore(phase, port) {
26
+ const normalizedPort = Number(port || process.env.PORT || 3003) || 3003;
27
+ process.env.VISTA_ENGINE = 'flashpack';
28
+ process.env.VISTA_ENGINE_VARIANT = 'flashpack';
29
+ process.env.VISTA_FLASHPACK = 'true';
30
+ process.env.VISTA_FLASHPACK_PIPELINE = 'js-fallback';
31
+ if (phase === 'build') {
32
+ await (0, build_rsc_1.buildRSC)(false);
33
+ return;
34
+ }
35
+ if (phase === 'dev') {
36
+ const result = await (0, build_rsc_1.buildRSC)(true);
37
+ (0, rsc_engine_1.startRSCServer)({
38
+ port: normalizedPort,
39
+ compiler: result.clientCompiler,
40
+ });
41
+ return;
42
+ }
43
+ (0, rsc_engine_1.startRSCServer)({
44
+ port: normalizedPort,
45
+ });
46
+ }
47
+ async function runFlashpackEngineCommand(phase, options = {}) {
48
+ const cwd = options.cwd || process.cwd();
49
+ const strict = options.strict ?? process.env.VISTA_FLASHPACK_STRICT !== 'false';
50
+ const mode = resolveMode(phase);
51
+ const runnerPath = getRunnerPath();
52
+ const port = options.port || process.env.PORT || 3003;
53
+ const prepare = (0, runtime_1.runFlashpackRustCli)({
54
+ cwd,
55
+ phase: phase,
56
+ mode,
57
+ action: 'prepare',
58
+ });
59
+ if (prepare.error || prepare.status !== 0) {
60
+ if (strict) {
61
+ throw new Error(formatRustFailure(prepare.error || 'unknown failure'));
62
+ }
63
+ await fallbackToCore(phase, port);
64
+ return;
65
+ }
66
+ const workspaceRoot = prepare.workspaceRoot;
67
+ const cargoCommand = prepare.cargoCommand;
68
+ if (!workspaceRoot || !cargoCommand) {
69
+ if (strict) {
70
+ throw new Error('[flashpack] Rust workspace unavailable for flashpack command.');
71
+ }
72
+ await fallbackToCore(phase, port);
73
+ return;
74
+ }
75
+ await new Promise((resolve, reject) => {
76
+ const child = (0, child_process_1.spawn)(cargoCommand, [
77
+ 'run',
78
+ '-q',
79
+ '-p',
80
+ 'flashpack-cli',
81
+ '--',
82
+ '--cwd',
83
+ cwd,
84
+ '--phase',
85
+ phase,
86
+ '--mode',
87
+ mode,
88
+ '--action',
89
+ 'run',
90
+ '--node',
91
+ process.execPath,
92
+ '--runner',
93
+ runnerPath,
94
+ '--port',
95
+ String(port),
96
+ ], {
97
+ cwd: workspaceRoot,
98
+ env: {
99
+ ...process.env,
100
+ VISTA_ENGINE: 'flashpack',
101
+ VISTA_ENGINE_VARIANT: 'flashpack',
102
+ VISTA_FLASHPACK: 'true',
103
+ VISTA_FLASHPACK_PIPELINE: 'rust-cli',
104
+ },
105
+ stdio: 'inherit',
106
+ windowsHide: true,
107
+ });
108
+ child.once('error', async (error) => {
109
+ const message = (0, spawn_permissions_1.isPermissionDeniedSpawnError)(error)
110
+ ? formatRustFailure(`spawn blocked by environment permissions (${(0, spawn_permissions_1.getErrorMessage)(error)})`)
111
+ : formatRustFailure((0, spawn_permissions_1.getErrorMessage)(error));
112
+ if (!strict) {
113
+ try {
114
+ await fallbackToCore(phase, port);
115
+ resolve();
116
+ return;
117
+ }
118
+ catch (fallbackError) {
119
+ reject(fallbackError);
120
+ return;
121
+ }
122
+ }
123
+ reject(new Error(message));
124
+ });
125
+ child.once('exit', (code, signal) => {
126
+ if (code === 0) {
127
+ resolve();
128
+ return;
129
+ }
130
+ reject(new Error(`[flashpack] Rust command failed for ${phase} (code=${code}, signal=${signal || 'none'})`));
131
+ });
132
+ });
133
+ }
134
+ exports.default = runFlashpackEngineCommand;
@@ -0,0 +1,39 @@
1
+ export type FlashpackPhase = 'dev' | 'build' | 'start';
2
+ export type FlashpackMode = 'development' | 'production';
3
+ export interface FlashpackPrepareOptions {
4
+ cwd: string;
5
+ phase: FlashpackPhase;
6
+ mode: FlashpackMode;
7
+ allowFallback?: boolean;
8
+ }
9
+ export interface FlashpackPrepareResult {
10
+ flashDir: string;
11
+ rustPipelineUsed: boolean;
12
+ workspaceRoot: string | null;
13
+ graphPath: string;
14
+ }
15
+ export declare function findFlashpackWorkspaceRoot(startCwd: string): string | null;
16
+ export declare function bootstrapFlashDirectories(cwd: string): string;
17
+ export declare function resolveCargoCommand(): string;
18
+ export interface FlashpackRustCliOptions {
19
+ cwd: string;
20
+ phase: FlashpackPhase;
21
+ mode: FlashpackMode;
22
+ action?: 'prepare' | 'run';
23
+ runnerPath?: string;
24
+ nodeCommand?: string;
25
+ port?: number | string;
26
+ }
27
+ export interface FlashpackRustCliResult {
28
+ flashDir: string;
29
+ workspaceRoot: string | null;
30
+ cargoCommand: string | null;
31
+ args: string[];
32
+ logPath: string;
33
+ graphPath: string;
34
+ runtimeManifestPath: string;
35
+ error?: string;
36
+ status: number | null;
37
+ }
38
+ export declare function runFlashpackRustCli(options: FlashpackRustCliOptions): FlashpackRustCliResult;
39
+ export declare function prepareFlashpackRuntime(options: FlashpackPrepareOptions): FlashpackPrepareResult;
@@ -0,0 +1,249 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.findFlashpackWorkspaceRoot = findFlashpackWorkspaceRoot;
7
+ exports.bootstrapFlashDirectories = bootstrapFlashDirectories;
8
+ exports.resolveCargoCommand = resolveCargoCommand;
9
+ exports.runFlashpackRustCli = runFlashpackRustCli;
10
+ exports.prepareFlashpackRuntime = prepareFlashpackRuntime;
11
+ const fs_1 = __importDefault(require("fs"));
12
+ const path_1 = __importDefault(require("path"));
13
+ const child_process_1 = require("child_process");
14
+ const constants_1 = require("../constants");
15
+ const native_scanner_1 = require("../build/rsc/native-scanner");
16
+ function ensureDir(absolutePath) {
17
+ fs_1.default.mkdirSync(absolutePath, { recursive: true });
18
+ }
19
+ function writeJsonFile(absolutePath, payload) {
20
+ ensureDir(path_1.default.dirname(absolutePath));
21
+ fs_1.default.writeFileSync(absolutePath, JSON.stringify(payload, null, 2));
22
+ }
23
+ function removeLegacyFlashArtifacts(cwd, flashDir) {
24
+ for (const legacyPath of [
25
+ path_1.default.join(cwd, '.turbo'),
26
+ path_1.default.join(flashDir, 'cache', 'turbo'),
27
+ path_1.default.join(flashDir, 'turbo'),
28
+ ]) {
29
+ if (!fs_1.default.existsSync(legacyPath)) {
30
+ continue;
31
+ }
32
+ fs_1.default.rmSync(legacyPath, { recursive: true, force: true });
33
+ }
34
+ }
35
+ function findFlashpackWorkspaceRoot(startCwd) {
36
+ let current = path_1.default.resolve(startCwd);
37
+ while (true) {
38
+ const candidate = path_1.default.join(current, 'flashpack', 'xtask', 'Cargo.toml');
39
+ if (fs_1.default.existsSync(candidate)) {
40
+ return current;
41
+ }
42
+ const parent = path_1.default.dirname(current);
43
+ if (parent === current)
44
+ break;
45
+ current = parent;
46
+ }
47
+ return null;
48
+ }
49
+ function bootstrapFlashDirectories(cwd) {
50
+ const flashDir = path_1.default.join(cwd, constants_1.FLASH_DIR);
51
+ removeLegacyFlashArtifacts(cwd, flashDir);
52
+ const dirs = [
53
+ flashDir,
54
+ path_1.default.join(flashDir, 'graph'),
55
+ path_1.default.join(flashDir, 'logs'),
56
+ path_1.default.join(flashDir, 'runtime'),
57
+ path_1.default.join(flashDir, 'state'),
58
+ ];
59
+ dirs.forEach(ensureDir);
60
+ return flashDir;
61
+ }
62
+ function resolveCargoCommand() {
63
+ if (process.env.CARGO && process.env.CARGO.trim().length > 0) {
64
+ return process.env.CARGO.trim();
65
+ }
66
+ if (process.platform === 'win32') {
67
+ const whereResult = (0, child_process_1.spawnSync)('where.exe', ['cargo'], {
68
+ encoding: 'utf-8',
69
+ stdio: 'pipe',
70
+ });
71
+ if (whereResult.status === 0) {
72
+ const first = String(whereResult.stdout || '')
73
+ .split(/\r?\n/)
74
+ .map((line) => line.trim())
75
+ .find((line) => line.length > 0);
76
+ if (first)
77
+ return first;
78
+ }
79
+ return 'cargo.exe';
80
+ }
81
+ const whichResult = (0, child_process_1.spawnSync)('which', ['cargo'], {
82
+ encoding: 'utf-8',
83
+ stdio: 'pipe',
84
+ });
85
+ if (whichResult.status === 0) {
86
+ const first = String(whichResult.stdout || '')
87
+ .split(/\r?\n/)
88
+ .map((line) => line.trim())
89
+ .find((line) => line.length > 0);
90
+ if (first)
91
+ return first;
92
+ }
93
+ return 'cargo';
94
+ }
95
+ function buildRustCliArgs(options, graphPath) {
96
+ const args = [
97
+ 'run',
98
+ '-q',
99
+ '-p',
100
+ 'flashpack-cli',
101
+ '--',
102
+ '--cwd',
103
+ options.cwd,
104
+ '--phase',
105
+ options.phase,
106
+ '--mode',
107
+ options.mode,
108
+ '--action',
109
+ options.action || 'prepare',
110
+ ];
111
+ if (options.runnerPath) {
112
+ args.push('--runner', options.runnerPath);
113
+ }
114
+ if (options.nodeCommand) {
115
+ args.push('--node', options.nodeCommand);
116
+ }
117
+ if (options.port !== undefined && options.port !== null && String(options.port).trim().length > 0) {
118
+ args.push('--port', String(options.port));
119
+ }
120
+ return args;
121
+ }
122
+ function runFlashpackRustCli(options) {
123
+ const flashDir = bootstrapFlashDirectories(options.cwd);
124
+ const workspaceRoot = findFlashpackWorkspaceRoot(options.cwd);
125
+ const graphPath = path_1.default.join(flashDir, 'graph', `${options.phase}-rust.json`);
126
+ const runtimeManifestPath = path_1.default.join(flashDir, 'runtime', `${options.phase}-manifest.json`);
127
+ const logPath = path_1.default.join(flashDir, 'logs', `${options.phase}-cli.log`);
128
+ if (!workspaceRoot) {
129
+ return {
130
+ flashDir,
131
+ workspaceRoot: null,
132
+ cargoCommand: null,
133
+ args: [],
134
+ logPath,
135
+ graphPath,
136
+ runtimeManifestPath,
137
+ error: `Rust workspace not found from ${options.cwd}. Expected flashpack/xtask/Cargo.toml in an ancestor directory.`,
138
+ status: null,
139
+ };
140
+ }
141
+ const cargoCommand = resolveCargoCommand();
142
+ const args = buildRustCliArgs(options, graphPath);
143
+ const result = (0, child_process_1.spawnSync)(cargoCommand, args, {
144
+ cwd: workspaceRoot,
145
+ encoding: 'utf-8',
146
+ stdio: 'pipe',
147
+ });
148
+ const log = [
149
+ `[flashpack] workspace=${workspaceRoot}`,
150
+ `[flashpack] command=${cargoCommand} ${args.join(' ')}`,
151
+ `[flashpack] status=${result.status ?? 'null'}`,
152
+ `[flashpack] error=${result.error ? result.error.message : ''}`,
153
+ '[flashpack] stdout:',
154
+ result.stdout || '',
155
+ '[flashpack] stderr:',
156
+ result.stderr || '',
157
+ ].join('\n');
158
+ fs_1.default.writeFileSync(logPath, log);
159
+ return {
160
+ flashDir,
161
+ workspaceRoot,
162
+ cargoCommand,
163
+ args,
164
+ logPath,
165
+ graphPath,
166
+ runtimeManifestPath,
167
+ error: result.error
168
+ ? result.error.message
169
+ : result.status === 0
170
+ ? undefined
171
+ : (result.stderr || result.stdout || 'unknown cargo failure').trim(),
172
+ status: result.status ?? null,
173
+ };
174
+ }
175
+ function prepareFlashpackRuntime(options) {
176
+ const { cwd, phase, mode, allowFallback = true } = options;
177
+ const flashDir = bootstrapFlashDirectories(cwd);
178
+ const now = new Date().toISOString();
179
+ const graphPath = path_1.default.join(flashDir, 'graph', `${phase}.json`);
180
+ writeJsonFile(path_1.default.join(flashDir, 'state', 'latest.json'), {
181
+ engine: 'flashpack',
182
+ phase,
183
+ mode,
184
+ timestamp: now,
185
+ cwd,
186
+ });
187
+ writeJsonFile(graphPath, {
188
+ engine: 'flashpack',
189
+ phase,
190
+ mode,
191
+ generatedBy: 'vista-ts-bootstrap',
192
+ timestamp: now,
193
+ });
194
+ const appDir = path_1.default.join(cwd, 'app');
195
+ if ((0, native_scanner_1.isNativeAvailable)() && fs_1.default.existsSync(appDir)) {
196
+ const nativeScan = (0, native_scanner_1.scanAppNative)(appDir);
197
+ if (nativeScan) {
198
+ const nativeGraphPath = path_1.default.join(flashDir, 'graph', `${phase}-rust.json`);
199
+ writeJsonFile(nativeGraphPath, {
200
+ engine: 'flashpack',
201
+ pipeline: 'rust-napi',
202
+ phase,
203
+ mode,
204
+ timestamp: now,
205
+ appDir,
206
+ stats: {
207
+ totalFiles: nativeScan.totalFiles,
208
+ scanTimeMs: nativeScan.scanTimeMs,
209
+ clientComponents: nativeScan.clientComponents.length,
210
+ serverComponents: nativeScan.serverComponents.length,
211
+ pages: nativeScan.pages.length,
212
+ layouts: nativeScan.layouts.length,
213
+ apiRoutes: nativeScan.apiRoutes.length,
214
+ errors: nativeScan.errors.length,
215
+ },
216
+ });
217
+ return {
218
+ flashDir,
219
+ rustPipelineUsed: true,
220
+ workspaceRoot: null,
221
+ graphPath: nativeGraphPath,
222
+ };
223
+ }
224
+ }
225
+ const rustResult = runFlashpackRustCli({
226
+ cwd,
227
+ phase,
228
+ mode,
229
+ action: 'prepare',
230
+ });
231
+ if (rustResult.error || rustResult.status !== 0) {
232
+ const detail = rustResult.error || 'unknown cargo failure';
233
+ if (!allowFallback) {
234
+ throw new Error(`[flashpack] Rust pipeline failed: ${detail}`);
235
+ }
236
+ return {
237
+ flashDir,
238
+ rustPipelineUsed: false,
239
+ workspaceRoot: rustResult.workspaceRoot,
240
+ graphPath,
241
+ };
242
+ }
243
+ return {
244
+ flashDir,
245
+ rustPipelineUsed: true,
246
+ workspaceRoot: rustResult.workspaceRoot,
247
+ graphPath: rustResult.graphPath,
248
+ };
249
+ }
@@ -0,0 +1,26 @@
1
+ type InterceptionMarker = '(.)' | '(..)' | '(..)(..)' | '(...)';
2
+ export interface MatchedAppModule {
3
+ filePath: string;
4
+ params: Record<string, string>;
5
+ source: 'page' | 'default' | 'interception';
6
+ }
7
+ export interface ParallelSlotMatch extends MatchedAppModule {
8
+ slotName: string;
9
+ slotRootDir: string;
10
+ }
11
+ export declare function resolveConventionModule(dir: string, stem: string): string | null;
12
+ export declare function parseInterceptionSegment(segment: string): {
13
+ marker: InterceptionMarker;
14
+ target: string;
15
+ } | null;
16
+ export declare function isInterceptionRouteSegment(segment: string): boolean;
17
+ export declare function isRouteGroupSegment(segment: string): boolean;
18
+ export declare function isParallelRouteSegment(segment: string): boolean;
19
+ export declare function resolveParallelSlotMatches(input: {
20
+ appDir: string;
21
+ layoutPath: string;
22
+ pathname: string;
23
+ }): ParallelSlotMatch[];
24
+ export declare function resolveDirectoryChain(rootDir: string, entryFilePath: string): string[];
25
+ export declare function resolveNearestSegmentNotFoundPath(appDir: string, startDir: string): string | null;
26
+ export {};