veryfront 0.1.131 → 0.1.136

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 (140) hide show
  1. package/esm/_dnt.polyfills.d.ts +11 -0
  2. package/esm/_dnt.polyfills.d.ts.map +1 -1
  3. package/esm/_dnt.polyfills.js +14 -0
  4. package/esm/cli/commands/build/handler.js +2 -0
  5. package/esm/cli/commands/deploy/command.d.ts.map +1 -1
  6. package/esm/cli/commands/deploy/command.js +2 -0
  7. package/esm/cli/commands/files/command.d.ts.map +1 -1
  8. package/esm/cli/commands/files/command.js +1 -0
  9. package/esm/cli/commands/uploads/command.d.ts.map +1 -1
  10. package/esm/cli/commands/uploads/command.js +1 -0
  11. package/esm/cli/help/tips.d.ts +3 -0
  12. package/esm/cli/help/tips.d.ts.map +1 -1
  13. package/esm/cli/help/tips.js +15 -1
  14. package/esm/cli/router.d.ts.map +1 -1
  15. package/esm/cli/router.js +4 -0
  16. package/esm/cli/shared/animation.d.ts +3 -0
  17. package/esm/cli/shared/animation.d.ts.map +1 -0
  18. package/esm/cli/shared/animation.js +23 -0
  19. package/esm/cli/templates/manifest.d.ts +6 -0
  20. package/esm/cli/templates/manifest.js +12 -6
  21. package/esm/cli/ui/progress.d.ts.map +1 -1
  22. package/esm/cli/ui/progress.js +13 -1
  23. package/esm/deno.js +1 -1
  24. package/esm/src/agent/index.d.ts +1 -1
  25. package/esm/src/agent/index.d.ts.map +1 -1
  26. package/esm/src/agent/runtime/ai-stream-handler.d.ts.map +1 -1
  27. package/esm/src/agent/runtime/ai-stream-handler.js +56 -5
  28. package/esm/src/agent/runtime/index.d.ts.map +1 -1
  29. package/esm/src/agent/runtime/index.js +21 -3
  30. package/esm/src/agent/runtime/model-tool-converter.d.ts +5 -1
  31. package/esm/src/agent/runtime/model-tool-converter.d.ts.map +1 -1
  32. package/esm/src/agent/runtime/model-tool-converter.js +35 -4
  33. package/esm/src/agent/runtime/tool-helpers.d.ts +2 -1
  34. package/esm/src/agent/runtime/tool-helpers.d.ts.map +1 -1
  35. package/esm/src/agent/runtime/tool-helpers.js +6 -3
  36. package/esm/src/agent/types.d.ts +19 -0
  37. package/esm/src/agent/types.d.ts.map +1 -1
  38. package/esm/src/channels/control-plane.d.ts +67 -0
  39. package/esm/src/channels/control-plane.d.ts.map +1 -1
  40. package/esm/src/channels/control-plane.js +27 -0
  41. package/esm/src/discovery/handlers/tool-handler.d.ts.map +1 -1
  42. package/esm/src/discovery/handlers/tool-handler.js +12 -2
  43. package/esm/src/html/html-injection.d.ts +2 -0
  44. package/esm/src/html/html-injection.d.ts.map +1 -1
  45. package/esm/src/html/html-injection.js +10 -5
  46. package/esm/src/html/nonce-injection.d.ts +3 -0
  47. package/esm/src/html/nonce-injection.d.ts.map +1 -0
  48. package/esm/src/html/nonce-injection.js +249 -0
  49. package/esm/src/internal-agents/ag-ui-sse.d.ts +1 -0
  50. package/esm/src/internal-agents/ag-ui-sse.d.ts.map +1 -1
  51. package/esm/src/internal-agents/ag-ui-sse.js +18 -0
  52. package/esm/src/internal-agents/run-stream.d.ts.map +1 -1
  53. package/esm/src/internal-agents/run-stream.js +26 -4
  54. package/esm/src/platform/adapters/fs/veryfront/proxy-manager.d.ts +1 -0
  55. package/esm/src/platform/adapters/fs/veryfront/proxy-manager.d.ts.map +1 -1
  56. package/esm/src/platform/adapters/fs/veryfront/proxy-manager.js +15 -1
  57. package/esm/src/platform/adapters/fs/veryfront/types.d.ts +2 -0
  58. package/esm/src/platform/adapters/fs/veryfront/types.d.ts.map +1 -1
  59. package/esm/src/platform/adapters/fs/veryfront/websocket-manager.d.ts.map +1 -1
  60. package/esm/src/platform/adapters/fs/veryfront/websocket-manager.js +2 -0
  61. package/esm/src/proxy/handler.d.ts.map +1 -1
  62. package/esm/src/proxy/handler.js +25 -5
  63. package/esm/src/react/components/Head.d.ts +9 -0
  64. package/esm/src/react/components/Head.d.ts.map +1 -1
  65. package/esm/src/react/components/Head.js +9 -0
  66. package/esm/src/react/context/index.d.ts +9 -0
  67. package/esm/src/react/context/index.d.ts.map +1 -1
  68. package/esm/src/react/context/index.js +9 -0
  69. package/esm/src/react/router/index.d.ts +9 -0
  70. package/esm/src/react/router/index.d.ts.map +1 -1
  71. package/esm/src/react/router/index.js +9 -0
  72. package/esm/src/rendering/orchestrator/html.d.ts +1 -0
  73. package/esm/src/rendering/orchestrator/html.d.ts.map +1 -1
  74. package/esm/src/rendering/orchestrator/html.js +81 -89
  75. package/esm/src/rendering/script-page-handling.js +1 -0
  76. package/esm/src/server/handlers/dev/framework-candidates.generated.d.ts.map +1 -1
  77. package/esm/src/server/handlers/dev/framework-candidates.generated.js +9 -0
  78. package/esm/src/server/handlers/request/ssr/ssr-response-builder.d.ts.map +1 -1
  79. package/esm/src/server/handlers/request/ssr/ssr-response-builder.js +3 -7
  80. package/esm/src/server/handlers/request/static.handler.d.ts.map +1 -1
  81. package/esm/src/server/handlers/request/static.handler.js +18 -10
  82. package/esm/src/tool/factory.d.ts.map +1 -1
  83. package/esm/src/tool/factory.js +14 -4
  84. package/esm/src/tool/types.d.ts +2 -0
  85. package/esm/src/tool/types.d.ts.map +1 -1
  86. package/esm/src/transforms/pipeline/stages/ssr-vf-modules/constants.d.ts +1 -0
  87. package/esm/src/transforms/pipeline/stages/ssr-vf-modules/constants.d.ts.map +1 -1
  88. package/esm/src/transforms/pipeline/stages/ssr-vf-modules/constants.js +3 -0
  89. package/esm/src/transforms/pipeline/stages/ssr-vf-modules/import-finder.d.ts.map +1 -1
  90. package/esm/src/transforms/pipeline/stages/ssr-vf-modules/import-finder.js +4 -2
  91. package/esm/src/transforms/pipeline/stages/ssr-vf-modules/index.d.ts +1 -1
  92. package/esm/src/transforms/pipeline/stages/ssr-vf-modules/index.d.ts.map +1 -1
  93. package/esm/src/transforms/pipeline/stages/ssr-vf-modules/index.js +10 -9
  94. package/esm/src/transforms/pipeline/stages/ssr-vf-modules/path-resolver.d.ts.map +1 -1
  95. package/esm/src/transforms/pipeline/stages/ssr-vf-modules/path-resolver.js +3 -1
  96. package/esm/src/utils/version-constant.d.ts +1 -1
  97. package/esm/src/utils/version-constant.js +1 -1
  98. package/package.json +1 -1
  99. package/src/_dnt.polyfills.ts +27 -0
  100. package/src/cli/commands/build/handler.ts +3 -0
  101. package/src/cli/commands/deploy/command.ts +3 -0
  102. package/src/cli/commands/files/command.ts +1 -0
  103. package/src/cli/commands/uploads/command.ts +3 -0
  104. package/src/cli/help/tips.ts +18 -1
  105. package/src/cli/router.ts +5 -0
  106. package/src/cli/shared/animation.ts +25 -0
  107. package/src/cli/templates/manifest.js +12 -6
  108. package/src/cli/ui/progress.ts +13 -1
  109. package/src/deno.js +1 -1
  110. package/src/src/agent/index.ts +2 -0
  111. package/src/src/agent/runtime/ai-stream-handler.ts +64 -6
  112. package/src/src/agent/runtime/index.ts +26 -1
  113. package/src/src/agent/runtime/model-tool-converter.ts +47 -3
  114. package/src/src/agent/runtime/tool-helpers.ts +15 -3
  115. package/src/src/agent/types.ts +23 -0
  116. package/src/src/channels/control-plane.ts +31 -0
  117. package/src/src/discovery/handlers/tool-handler.ts +13 -2
  118. package/src/src/html/html-injection.ts +16 -5
  119. package/src/src/html/nonce-injection.ts +300 -0
  120. package/src/src/internal-agents/ag-ui-sse.ts +20 -0
  121. package/src/src/internal-agents/run-stream.ts +35 -4
  122. package/src/src/platform/adapters/fs/veryfront/proxy-manager.ts +29 -3
  123. package/src/src/platform/adapters/fs/veryfront/types.ts +2 -0
  124. package/src/src/platform/adapters/fs/veryfront/websocket-manager.ts +2 -0
  125. package/src/src/proxy/handler.ts +43 -5
  126. package/src/src/react/components/Head.tsx +10 -0
  127. package/src/src/react/context/index.tsx +10 -0
  128. package/src/src/react/router/index.tsx +10 -0
  129. package/src/src/rendering/orchestrator/html.ts +125 -100
  130. package/src/src/rendering/script-page-handling.ts +1 -0
  131. package/src/src/server/handlers/dev/framework-candidates.generated.ts +9 -0
  132. package/src/src/server/handlers/request/ssr/ssr-response-builder.ts +7 -11
  133. package/src/src/server/handlers/request/static.handler.ts +22 -10
  134. package/src/src/tool/factory.ts +17 -4
  135. package/src/src/tool/types.ts +2 -0
  136. package/src/src/transforms/pipeline/stages/ssr-vf-modules/constants.ts +4 -0
  137. package/src/src/transforms/pipeline/stages/ssr-vf-modules/import-finder.ts +4 -2
  138. package/src/src/transforms/pipeline/stages/ssr-vf-modules/index.ts +18 -15
  139. package/src/src/transforms/pipeline/stages/ssr-vf-modules/path-resolver.ts +4 -1
  140. package/src/src/utils/version-constant.ts +1 -1
@@ -1041,6 +1041,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
1041
1041
  "Hover",
1042
1042
  "HydratingChatRootFixture():",
1043
1043
  "HydratingChatStyleProviderFixture():",
1044
+ "HydratingColorModeScriptFixture():",
1044
1045
  "HydratingHeadStyleFixture():",
1045
1046
  "I",
1046
1047
  "IconElementSpec",
@@ -2040,6 +2041,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
2040
2041
  "as",
2041
2042
  "asking",
2042
2043
  "assert(root,",
2044
+ "assert(script,",
2043
2045
  "assert(style,",
2044
2046
  "assert,",
2045
2047
  "assertEquals",
@@ -3157,6 +3159,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
3157
3159
  "hover:underline",
3158
3160
  "href={doc.url}",
3159
3161
  "href={props.href}",
3162
+ "html",
3160
3163
  "html.replaceAll(",
3161
3164
  "html:",
3162
3165
  "html>",
@@ -3170,6 +3173,8 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
3170
3173
  "https://example.com/",
3171
3174
  "hydrateAndReadManagedHeadStyleNonce(",
3172
3175
  "hydrateAndReadManagedHeadStyleNonce(<HydratingHeadStyleFixture",
3176
+ "hydrateAndReadScriptNonce(<HydratingColorModeScriptFixture",
3177
+ "hydrateAndReadScriptNonce(element:",
3173
3178
  "hydrateAndReadStyleNonce(<HydratingChatRootFixture",
3174
3179
  "hydrateAndReadStyleNonce(<HydratingChatStyleProviderFixture",
3175
3180
  "hydrateAndReadStyleNonce(element:",
@@ -3238,6 +3243,8 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
3238
3243
  "initialContent:",
3239
3244
  "initialContent={content}",
3240
3245
  "initialize(config:",
3246
+ "injectNonceIntoInlineTags(html:",
3247
+ "injectNonceIntoInlineTags(renderToString(element),",
3241
3248
  "injectNonceIntoStyleTags(html:",
3242
3249
  "injectNonceIntoStyleTags(renderToString(element),",
3243
3250
  "injected",
@@ -4381,6 +4388,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
4381
4388
  "replace(",
4382
4389
  "replace(/",
4383
4390
  "replace(/:",
4391
+ "replaceAll(",
4384
4392
  "requestAnimationFrame(()",
4385
4393
  "requestAnimationFrame:",
4386
4394
  "reset",
@@ -4457,6 +4465,7 @@ export const FRAMEWORK_CANDIDATES: readonly string[] = [
4457
4465
  "score:",
4458
4466
  "score?:",
4459
4467
  "script",
4468
+ "script.getAttribute(",
4460
4469
  "script[nonce],",
4461
4470
  "script}",
4462
4471
  "scrollAreaRef",
@@ -15,15 +15,7 @@ import { getContentType } from "../../utils/content-types.js";
15
15
  import type { SSRRenderResult } from "../../../services/rendering/ssr.service.js";
16
16
  import { ErrorPages } from "../../../utils/error-html.js";
17
17
  import type { ResponseBuilder } from "../../../../security/http/response/builder.js";
18
- import { escapeHtml } from "../../../../html/html-escape.js";
19
-
20
- function addNonceToInlineTags(html: string, nonce: string): string {
21
- const escapedNonce = escapeHtml(nonce);
22
- return html.replace(
23
- /<(script|style)\b(?![^>]*\bnonce\s*=)([^>]*)>/giu,
24
- `<$1$2 nonce="${escapedNonce}">`,
25
- );
26
- }
18
+ import { addNonceToHtmlStream, addNonceToHtmlTags } from "../../../../html/nonce-injection.js";
27
19
 
28
20
  /**
29
21
  * Build an HTTP response from an SSR render result.
@@ -47,7 +39,11 @@ export async function buildSSRResponse(
47
39
  .withSecurity(ctx.securityConfig ?? undefined, req)
48
40
  .withClientHints()
49
41
  .withCache("no-cache")
50
- .withContentType(getContentType(".html"), result.stream, result.status);
42
+ .withContentType(
43
+ getContentType(".html"),
44
+ addNonceToHtmlStream(result.stream, builder.nonce),
45
+ result.status,
46
+ );
51
47
 
52
48
  if (!isHeadRequest) return response;
53
49
 
@@ -70,7 +66,7 @@ export async function buildSSRResponse(
70
66
  : typeof result.stream === "string"
71
67
  ? result.stream
72
68
  : ErrorPages.serverError();
73
- const html = addNonceToInlineTags(content, builder.nonce);
69
+ const html = addNonceToHtmlTags(content, builder.nonce);
74
70
  const body = isHeadRequest ? null : html;
75
71
 
76
72
  let response = builder
@@ -21,6 +21,12 @@ import {
21
21
  } from "../../../utils/constants/index.js";
22
22
  import { withSpan } from "../../../observability/tracing/otlp-setup.js";
23
23
  import { StaticFileService } from "../../services/static/index.js";
24
+ import { addNonceToHtmlTags } from "../../../html/nonce-injection.js";
25
+ import { computeEtag } from "../utils/etag.js";
26
+
27
+ function isHtmlResponse(contentType: string): boolean {
28
+ return /\btext\/html\b/i.test(contentType);
29
+ }
24
30
 
25
31
  export class StaticHandler extends BaseHandler {
26
32
  metadata: HandlerMetadata = {
@@ -59,6 +65,8 @@ export class StaticHandler extends BaseHandler {
59
65
  const isHead = method === "HEAD";
60
66
  const isLocal = !!ctx.isLocalProject;
61
67
  const isPreviewMode = ctx.requestContext?.mode === "preview" && !isLocal;
68
+ const builder = this.createResponseBuilder(ctx)
69
+ .withCORS(req, ctx.securityConfig?.cors);
62
70
 
63
71
  const result = await this.staticService.resolveFile(pathname, {
64
72
  projectDir: ctx.projectDir,
@@ -70,8 +78,7 @@ export class StaticHandler extends BaseHandler {
70
78
  if (!result) {
71
79
  if (!this.staticService.isAssetRequest(pathname)) return null;
72
80
 
73
- return this.createResponseBuilder(ctx)
74
- .withCORS(req, ctx.securityConfig?.cors)
81
+ return builder
75
82
  .withSecurity(ctx.securityConfig ?? undefined, req)
76
83
  .withCache("no-cache")
77
84
  .withContentType(
@@ -81,19 +88,24 @@ export class StaticHandler extends BaseHandler {
81
88
  );
82
89
  }
83
90
 
84
- if (hasMatchingEtag(req, result.etag)) {
85
- return this.createResponseBuilder(ctx)
86
- .withCORS(req, ctx.securityConfig?.cors)
91
+ const responseData = isHtmlResponse(result.contentType)
92
+ ? new TextEncoder().encode(
93
+ addNonceToHtmlTags(new TextDecoder().decode(result.data), builder.nonce),
94
+ )
95
+ : result.data;
96
+ const etag = computeEtag(responseData);
97
+
98
+ if (hasMatchingEtag(req, etag)) {
99
+ return builder
87
100
  .withSecurity(ctx.securityConfig ?? undefined, req)
88
- .notModified(result.etag);
101
+ .notModified(etag);
89
102
  }
90
103
 
91
- const body: dntShim.BodyInit | null = isHead ? null : result.data.slice();
92
- const response = this.createResponseBuilder(ctx)
93
- .withCORS(req, ctx.securityConfig?.cors)
104
+ const body: dntShim.BodyInit | null = isHead ? null : responseData.slice();
105
+ const response = builder
94
106
  .withSecurity(ctx.securityConfig ?? undefined, req)
95
107
  .withCache(result.cacheStrategy)
96
- .withETag(result.etag)
108
+ .withETag(etag)
97
109
  .withContentType(result.contentType, body, HTTP_OK);
98
110
 
99
111
  this.logDebug(
@@ -127,10 +127,18 @@ function generateToolId(): string {
127
127
  return `tool_${Date.now()}_${toolIdCounter++}`;
128
128
  }
129
129
 
130
+ function markGeneratedToolId<TInput, TOutput>(tool: Tool<TInput, TOutput>): Tool<TInput, TOutput> {
131
+ return {
132
+ ...tool,
133
+ __veryfrontGeneratedId: tool.id,
134
+ };
135
+ }
136
+
130
137
  export function tool<TInput = unknown, TOutput = unknown>(
131
138
  config: ToolConfig<TInput, TOutput>,
132
139
  ): Tool<TInput, TOutput> {
133
- const id = config.id || generateToolId();
140
+ const explicitId = typeof config.id === "string" && config.id.length > 0 ? config.id : undefined;
141
+ const id = explicitId ?? generateToolId();
134
142
 
135
143
  const inputSchemaJson = convertSchemaToJson(
136
144
  config.inputSchema,
@@ -139,7 +147,7 @@ export function tool<TInput = unknown, TOutput = unknown>(
139
147
  config.allowUnknownSchema ?? false,
140
148
  );
141
149
 
142
- return {
150
+ const createdTool: Tool<TInput, TOutput> = {
143
151
  id,
144
152
  type: "function" as const,
145
153
  description: config.description,
@@ -163,6 +171,8 @@ export function tool<TInput = unknown, TOutput = unknown>(
163
171
  },
164
172
  mcp: config.mcp,
165
173
  };
174
+
175
+ return explicitId ? createdTool : markGeneratedToolId(createdTool);
166
176
  }
167
177
 
168
178
  export interface DynamicToolConfig {
@@ -179,11 +189,12 @@ export interface DynamicToolConfig {
179
189
  }
180
190
 
181
191
  export function dynamicTool(config: DynamicToolConfig): Tool<unknown, unknown> {
182
- const id = config.id || generateToolId();
192
+ const explicitId = typeof config.id === "string" && config.id.length > 0 ? config.id : undefined;
193
+ const id = explicitId ?? generateToolId();
183
194
 
184
195
  const inputSchemaJson = convertSchemaToJson(config.inputSchema, id, "DYNAMIC_TOOL", true);
185
196
 
186
- return {
197
+ const createdTool: Tool<unknown, unknown> = {
187
198
  id,
188
199
  type: "dynamic" as const,
189
200
  description: config.description,
@@ -202,4 +213,6 @@ export function dynamicTool(config: DynamicToolConfig): Tool<unknown, unknown> {
202
213
  },
203
214
  mcp: config.mcp,
204
215
  };
216
+
217
+ return explicitId ? createdTool : markGeneratedToolId(createdTool);
205
218
  }
@@ -74,6 +74,8 @@ type ToolType = "function" | "dynamic";
74
74
  export interface Tool<TInput = any, TOutput = any> {
75
75
  /** Tool ID */
76
76
  id: string;
77
+ /** Internal marker used to distinguish autogenerated placeholder ids from explicit ids. */
78
+ __veryfrontGeneratedId?: string;
77
79
 
78
80
  /**
79
81
  * Tool type discriminator
@@ -39,6 +39,10 @@ export const FRAMEWORK_LOOKUPS: Array<[prefix: string, frameworkDir: string]> =
39
39
  // Singleflight for framework module file writes to prevent race conditions
40
40
  export const frameworkWriteFlight = new Singleflight<string>();
41
41
 
42
+ // Singleflight for top-level framework source transforms so concurrent user
43
+ // modules importing the same veryfront/* module do not receive cycle placeholders.
44
+ export const frameworkTransformFlight = new Singleflight<string>();
45
+
42
46
  // Cache for already-transformed #veryfront/ dependencies to avoid cycles and redundant work
43
47
  export const veryfrontTransformCache = new Map<string, string>();
44
48
 
@@ -9,8 +9,10 @@
9
9
  export function findVfModuleImports(code: string): string[] {
10
10
  const imports: string[] = [];
11
11
  // Note: \s* allows zero whitespace (minified code: from"..." has no space)
12
- // Only match _veryfront/ framework modules, not user project files
13
- const pattern = /from\s*["'](\/\_vf\_modules\/_veryfront\/[^"']+)["']/g;
12
+ // Only match _veryfront/ framework modules, not user project files.
13
+ // Handle both raw "/_vf_modules/..." specifiers and malformed
14
+ // "file:///_vf_modules/..." variants that can leak out of stale caches.
15
+ const pattern = /from\s*["']((?:file:\/\/)?\/_vf_modules\/_veryfront\/[^"']+)["']/g;
14
16
 
15
17
  let match: RegExpExecArray | null;
16
18
  while ((match = pattern.exec(code)) !== null) {
@@ -32,6 +32,7 @@ import {
32
32
  EXTENSIONS,
33
33
  FRAMEWORK_LOOKUPS,
34
34
  FRAMEWORK_ROOT,
35
+ frameworkTransformFlight,
35
36
  LOG_PREFIX,
36
37
  } from "./constants.js";
37
38
 
@@ -56,6 +57,7 @@ export {
56
57
  FRAMEWORK_LOOKUPS,
57
58
  FRAMEWORK_ROOT,
58
59
  frameworkFileCache,
60
+ frameworkTransformFlight,
59
61
  frameworkWriteFlight,
60
62
  LOG_PREFIX,
61
63
  MAX_RELATIVE_IMPORT_DEPTH,
@@ -138,21 +140,22 @@ export const ssrVfModulesPlugin: TransformPlugin = {
138
140
  contentLength: resolved.content.length,
139
141
  });
140
142
 
141
- const transformed = await transformFrameworkSource(
142
- resolved.content,
143
- resolved.sourcePath,
144
- ctx.reactVersion ?? REACT_DEFAULT_VERSION,
145
- ctx.projectDir,
146
- fs,
147
- );
148
-
149
- // Skip cycle placeholders - don't cache or use them
150
- if (isCyclePlaceholder(transformed)) {
151
- logger.warn(`${LOG_PREFIX} Cycle detected for ${vfModulePath}, skipping cache`);
152
- continue;
153
- }
154
-
155
- const cachePath = await cacheTransformedCode(transformed, vfModulePath, fs);
143
+ const cachePath = await frameworkTransformFlight.do(resolved.sourcePath, async () => {
144
+ const transformed = await transformFrameworkSource(
145
+ resolved.content,
146
+ resolved.sourcePath,
147
+ ctx.reactVersion ?? REACT_DEFAULT_VERSION,
148
+ ctx.projectDir,
149
+ fs,
150
+ );
151
+
152
+ // Skip cycle placeholders - don't cache or use them
153
+ if (isCyclePlaceholder(transformed)) {
154
+ throw new Error(`Cycle detected while transforming ${vfModulePath}`);
155
+ }
156
+
157
+ return await cacheTransformedCode(transformed, vfModulePath, fs);
158
+ });
156
159
  replacements.set(vfModulePath, `file://${cachePath}`);
157
160
 
158
161
  logger.debug(`${LOG_PREFIX} Transformed ${vfModulePath} -> file://${cachePath}`);
@@ -51,13 +51,16 @@ export async function resolveFrameworkFile(
51
51
  fs: ReturnType<typeof createFileSystem>,
52
52
  existsFn: (path: string) => Promise<boolean> = exists,
53
53
  ): Promise<{ sourcePath: string; content: string } | null> {
54
- const pathWithoutPrefix = vfModulePath
54
+ const normalizedVfModulePath = vfModulePath.replace(/^file:\/\/(?=\/_vf_modules\/)/, "");
55
+
56
+ const pathWithoutPrefix = normalizedVfModulePath
55
57
  .replace(/^\/_vf_modules\//, "")
56
58
  .replace(/\?.*$/, "")
57
59
  .replace(/\.js$/, "");
58
60
 
59
61
  logger.debug(`${LOG_PREFIX} resolveFrameworkFile`, {
60
62
  input: vfModulePath,
63
+ normalizedVfModulePath,
61
64
  pathWithoutPrefix,
62
65
  lookupDirs: FRAMEWORK_LOOKUPS.map(([p, d]) => ({ prefix: p, dir: d })),
63
66
  });
@@ -1,3 +1,3 @@
1
1
  // Keep in sync with deno.json version.
2
2
  // scripts/release.ts updates this constant during releases.
3
- export const VERSION = "0.1.131";
3
+ export const VERSION = "0.1.136";