veryfront 0.1.57 → 0.1.58

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/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.57",
3
+ "version": "0.1.58",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "exclude": [
@@ -1 +1 @@
1
- {"version":3,"file":"module-server.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/server/module-server.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,OAAO,KAAK,OAAO,MAAM,wBAAwB,CAAC;AAIlD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAkBtE;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAkDrD,CAAC;AASF,MAAM,WAAW,mBAAmB;IAClC,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB;IACtB,OAAO,EAAE,cAAc,CAAC;IACxB,uBAAuB;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,sDAAsD;AACtD,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAqTzG;AAmND;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAG7D"}
1
+ {"version":3,"file":"module-server.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/server/module-server.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,OAAO,KAAK,OAAO,MAAM,wBAAwB,CAAC;AAIlD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAkBtE;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAkDrD,CAAC;AASF,MAAM,WAAW,mBAAmB;IAClC,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB;IACtB,OAAO,EAAE,cAAc,CAAC;IACxB,uBAAuB;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,sDAAsD;AACtD,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAqTzG;AAuND;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAG7D"}
@@ -388,20 +388,24 @@ async function findSourceFile(secureFs, projectDir, basePath) {
388
388
  const pathWithinFramework = stripPrefix
389
389
  ? basePathWithoutExt.slice(prefix.length)
390
390
  : basePathWithoutExt;
391
- for (const ext of extensions) {
392
- const frameworkPath = join(frameworkDir, pathWithinFramework + ext);
393
- try {
394
- const stat = await platformFs.stat(frameworkPath);
395
- if (stat.isFile) {
396
- logger.debug(`Found framework ${label} file`, {
397
- basePath: basePathWithoutExt,
398
- resolvedPath: frameworkPath,
399
- });
400
- return { path: frameworkPath, isFrameworkFile: true };
391
+ // Try direct file match first, then index file fallback
392
+ const candidates = [pathWithinFramework, `${pathWithinFramework}/index`];
393
+ for (const candidate of candidates) {
394
+ for (const ext of extensions) {
395
+ const frameworkPath = join(frameworkDir, candidate + ext);
396
+ try {
397
+ const stat = await platformFs.stat(frameworkPath);
398
+ if (stat.isFile) {
399
+ logger.debug(`Found framework ${label} file`, {
400
+ basePath: basePathWithoutExt,
401
+ resolvedPath: frameworkPath,
402
+ });
403
+ return { path: frameworkPath, isFrameworkFile: true };
404
+ }
405
+ }
406
+ catch (_) {
407
+ /* expected: file may not exist at this extension */
401
408
  }
402
- }
403
- catch (_) {
404
- /* expected: file may not exist at this extension */
405
409
  }
406
410
  }
407
411
  }
@@ -1 +1 @@
1
- {"version":3,"file":"veryfront-strategy.d.ts","sourceRoot":"","sources":["../../../../../src/src/transforms/import-rewriter/strategies/veryfront-strategy.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,aAAa,EACd,MAAM,aAAa,CAAC;AAerB,qBAAa,iBAAkB,YAAW,qBAAqB;IAC7D,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,QAAQ,OAAO;IAExB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO;IAQzD,OAAO,CAAC,IAAI,EAAE,mBAAmB,EAAE,GAAG,EAAE,cAAc,GAAG,aAAa;CAoCvE;AAED,eAAO,MAAM,iBAAiB,mBAA0B,CAAC"}
1
+ {"version":3,"file":"veryfront-strategy.d.ts","sourceRoot":"","sources":["../../../../../src/src/transforms/import-rewriter/strategies/veryfront-strategy.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,aAAa,EACd,MAAM,aAAa,CAAC;AAkBrB,qBAAa,iBAAkB,YAAW,qBAAqB;IAC7D,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,QAAQ,OAAO;IAExB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO;IAQzD,OAAO,CAAC,IAAI,EAAE,mBAAmB,EAAE,GAAG,EAAE,cAAc,GAAG,aAAa;CA2CvE;AAED,eAAO,MAAM,iBAAiB,mBAA0B,CAAC"}
@@ -5,7 +5,7 @@
5
5
  * Handles: #veryfront/*, veryfront/*
6
6
  */
7
7
  import { buildVeryfrontModuleUrl } from "../url-builder.js";
8
- import { resolveVeryfrontModuleUrl } from "../../veryfront-module-urls.js";
8
+ import { resolveInternalModuleUrl, resolveVeryfrontModuleUrl, } from "../../veryfront-module-urls.js";
9
9
  /**
10
10
  * SSR-specific module overrides.
11
11
  *
@@ -32,11 +32,19 @@ export class VeryfrontStrategy {
32
32
  // Try resolving via deno.json mappings first (veryfront/head → react/components/Head.js)
33
33
  const mapped = resolveVeryfrontModuleUrl(`veryfront/${path}`);
34
34
  if (mapped) {
35
- // For SSR, append ?ssr=true to signal server-side rendering
36
35
  if (ctx.target === "ssr")
37
36
  return { specifier: `${mapped}?ssr=true` };
38
37
  return { specifier: mapped };
39
38
  }
39
+ // Try resolving via #veryfront/* import map (handles paths where the
40
+ // filesystem layout differs from the specifier, e.g. #veryfront/compat/console
41
+ // maps to src/platform/compat/console/index.ts, not src/compat/console.ts)
42
+ const internalMapped = resolveInternalModuleUrl(specifier);
43
+ if (internalMapped) {
44
+ if (ctx.target === "ssr")
45
+ return { specifier: `${internalMapped}?ssr=true` };
46
+ return { specifier: internalMapped };
47
+ }
40
48
  const builtUrl = buildVeryfrontModuleUrl(path);
41
49
  if (ctx.target === "ssr")
42
50
  return { specifier: `${builtUrl}?ssr=true` };
@@ -1 +1 @@
1
- {"version":3,"file":"path-resolver.d.ts","sourceRoot":"","sources":["../../../../../../src/src/transforms/pipeline/stages/ssr-vf-modules/path-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAU,MAAM,mCAAmC,CAAC;AAW7E,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EACvC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAmBzD;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,MAAM,EACpB,EAAE,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,GACtC,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CA6DzD;AAED;;;;;;;GAOG;AACH,wBAAsB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA+D1F;AAED;;;;;;GAMG;AACH,wBAAsB,8BAA8B,CAClD,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,GAAG,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,GACvC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiExB"}
1
+ {"version":3,"file":"path-resolver.d.ts","sourceRoot":"","sources":["../../../../../../src/src/transforms/pipeline/stages/ssr-vf-modules/path-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAU,MAAM,mCAAmC,CAAC;AAY7E,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EACvC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAmBzD;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,MAAM,EACpB,EAAE,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,GACtC,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CA6DzD;AAED;;;;;;;GAOG;AACH,wBAAsB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAkE1F;AAED;;;;;;GAMG;AACH,wBAAsB,8BAA8B,CAClD,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,GAAG,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,GACvC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiExB"}
@@ -7,6 +7,7 @@
7
7
  import { exists } from "../../../../platform/compat/fs.js";
8
8
  import { join } from "../../../../platform/compat/path/index.js";
9
9
  import { rendererLogger as logger } from "../../../../utils/index.js";
10
+ import { resolveInternalModuleTarget } from "../../../veryfront-module-urls.js";
10
11
  import { EMBEDDED_SRC_DIR, EXTENSIONS, FRAMEWORK_LOOKUPS, FRAMEWORK_ROOT, LOG_PREFIX, } from "./constants.js";
11
12
  export async function tryReadWithExtensions(fs, basePath) {
12
13
  // Try all extensions, including .src versions for embedded sources
@@ -95,7 +96,10 @@ export async function resolveFrameworkFile(vfModulePath, fs) {
95
96
  export async function resolveVeryfrontSourcePath(specifier) {
96
97
  if (!specifier.startsWith("#veryfront/"))
97
98
  return null;
98
- const relativePath = specifier.slice("#veryfront/".length);
99
+ const mappedTarget = resolveInternalModuleTarget(specifier);
100
+ if (!mappedTarget?.startsWith("./src/"))
101
+ return null;
102
+ const relativePath = mappedTarget.slice("./src/".length);
99
103
  const hasExtension = /\.(tsx?|jsx?|mjs)$/.test(relativePath);
100
104
  // Check embedded sources first (for compiled binaries), then regular src/
101
105
  // This order matches FRAMEWORK_LOOKUPS and resolveFrameworkFile to ensure
@@ -1,2 +1,11 @@
1
+ export declare function resolveVeryfrontModuleTarget(specifier: string): string | null;
2
+ export declare function resolveInternalModuleTarget(specifier: string): string | null;
1
3
  export declare function resolveVeryfrontModuleUrl(specifier: string): string | null;
4
+ /**
5
+ * Resolve an internal #veryfront/* specifier to a /_vf_modules/ URL.
6
+ * Uses the deno.json import map to get the correct filesystem path,
7
+ * which may differ from the specifier path (e.g. #veryfront/compat/console
8
+ * maps to src/platform/compat/console/index.ts, not src/compat/console.ts).
9
+ */
10
+ export declare function resolveInternalModuleUrl(specifier: string): string | null;
2
11
  //# sourceMappingURL=veryfront-module-urls.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"veryfront-module-urls.d.ts","sourceRoot":"","sources":["../../../src/src/transforms/veryfront-module-urls.ts"],"names":[],"mappings":"AAmDA,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE1E"}
1
+ {"version":3,"file":"veryfront-module-urls.d.ts","sourceRoot":"","sources":["../../../src/src/transforms/veryfront-module-urls.ts"],"names":[],"mappings":"AAwGA,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE7E;AAED,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE5E;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG1E;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGzE"}
@@ -1,41 +1,98 @@
1
1
  import denoConfig from "../../deno.js";
2
2
  const MODULE_EXT_RE = /\.(mjs|cjs|js|jsx|ts|tsx)$/;
3
3
  const SRC_PREFIX = "./src/";
4
+ function createTargetIndex() {
5
+ return {
6
+ exactTargets: new Map(),
7
+ prefixTargets: [],
8
+ };
9
+ }
10
+ function normalizeModulePath(path) {
11
+ if (!path)
12
+ return path;
13
+ if (path.endsWith("/"))
14
+ return path;
15
+ return path.replace(MODULE_EXT_RE, ".js");
16
+ }
4
17
  function toModuleServerUrl(target) {
5
18
  if (!target.startsWith(SRC_PREFIX))
6
19
  return null;
7
20
  const relative = target.slice(SRC_PREFIX.length);
8
21
  if (!relative)
9
22
  return null;
10
- const withoutExt = relative.replace(MODULE_EXT_RE, "");
11
- return `/_vf_modules/_veryfront/${withoutExt}.js`;
23
+ return `/_vf_modules/_veryfront/${normalizeModulePath(relative)}`;
12
24
  }
13
- function addMapping(map, specifier, target) {
14
- const url = toModuleServerUrl(target);
15
- if (!url)
25
+ function addMapping(index, specifier, target) {
26
+ if (!target.startsWith(SRC_PREFIX))
27
+ return;
28
+ if (specifier.endsWith("/")) {
29
+ index.prefixTargets.push({
30
+ specifierPrefix: specifier,
31
+ targetPrefix: target.endsWith("/") ? target : `${target}/`,
32
+ });
16
33
  return;
17
- map.set(specifier, url);
34
+ }
35
+ index.exactTargets.set(specifier, target);
36
+ }
37
+ function finalizeIndex(index) {
38
+ index.prefixTargets.sort((a, b) => b.specifierPrefix.length - a.specifierPrefix.length);
39
+ }
40
+ function resolveTarget(index, specifier) {
41
+ const exact = index.exactTargets.get(specifier);
42
+ if (exact)
43
+ return exact;
44
+ for (const { specifierPrefix, targetPrefix } of index.prefixTargets) {
45
+ if (!specifier.startsWith(specifierPrefix))
46
+ continue;
47
+ return `${targetPrefix}${specifier.slice(specifierPrefix.length)}`;
48
+ }
49
+ return null;
18
50
  }
19
51
  const config = denoConfig;
20
- const veryfrontModuleUrlMap = new Map();
52
+ const veryfrontTargetIndex = createTargetIndex();
53
+ const internalTargetIndex = createTargetIndex();
21
54
  for (const [specifier, target] of Object.entries(config.imports ?? {})) {
22
- if (!specifier.startsWith("veryfront/"))
23
- continue;
24
55
  if (typeof target !== "string")
25
56
  continue;
26
- addMapping(veryfrontModuleUrlMap, specifier, target);
57
+ if (specifier === "veryfront" || specifier.startsWith("veryfront/")) {
58
+ addMapping(veryfrontTargetIndex, specifier, target);
59
+ }
60
+ // Also index #veryfront imports so the import rewriter can
61
+ // generate correct /_vf_modules/ URLs that match the actual filesystem layout.
62
+ if (specifier === "#veryfront" || specifier.startsWith("#veryfront/")) {
63
+ addMapping(internalTargetIndex, specifier, target);
64
+ }
27
65
  }
28
66
  for (const [key, target] of Object.entries(config.exports ?? {})) {
29
67
  if (typeof target !== "string")
30
68
  continue;
31
69
  if (key === ".") {
32
- addMapping(veryfrontModuleUrlMap, "veryfront", target);
70
+ addMapping(veryfrontTargetIndex, "veryfront", target);
33
71
  continue;
34
72
  }
35
73
  if (!key.startsWith("./"))
36
74
  continue;
37
- addMapping(veryfrontModuleUrlMap, `veryfront/${key.slice(2)}`, target);
75
+ addMapping(veryfrontTargetIndex, `veryfront/${key.slice(2)}`, target);
76
+ }
77
+ finalizeIndex(veryfrontTargetIndex);
78
+ finalizeIndex(internalTargetIndex);
79
+ export function resolveVeryfrontModuleTarget(specifier) {
80
+ return resolveTarget(veryfrontTargetIndex, specifier);
81
+ }
82
+ export function resolveInternalModuleTarget(specifier) {
83
+ return resolveTarget(internalTargetIndex, specifier);
38
84
  }
39
85
  export function resolveVeryfrontModuleUrl(specifier) {
40
- return veryfrontModuleUrlMap.get(specifier) ?? null;
86
+ const target = resolveVeryfrontModuleTarget(specifier);
87
+ return target ? toModuleServerUrl(target) : null;
88
+ }
89
+ /**
90
+ * Resolve an internal #veryfront/* specifier to a /_vf_modules/ URL.
91
+ * Uses the deno.json import map to get the correct filesystem path,
92
+ * which may differ from the specifier path (e.g. #veryfront/compat/console
93
+ * maps to src/platform/compat/console/index.ts, not src/compat/console.ts).
94
+ */
95
+ export function resolveInternalModuleUrl(specifier) {
96
+ const target = resolveInternalModuleTarget(specifier);
97
+ return target ? toModuleServerUrl(target) : null;
41
98
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.1.57",
3
+ "version": "0.1.58",
4
4
  "description": "The simplest way to build AI-powered apps",
5
5
  "keywords": [
6
6
  "react",
package/src/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.57",
3
+ "version": "0.1.58",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "exclude": [
@@ -514,19 +514,23 @@ async function findSourceFile(
514
514
  ? basePathWithoutExt.slice(prefix.length)
515
515
  : basePathWithoutExt;
516
516
 
517
- for (const ext of extensions) {
518
- const frameworkPath = join(frameworkDir, pathWithinFramework + ext);
519
- try {
520
- const stat = await platformFs.stat(frameworkPath);
521
- if (stat.isFile) {
522
- logger.debug(`Found framework ${label} file`, {
523
- basePath: basePathWithoutExt,
524
- resolvedPath: frameworkPath,
525
- });
526
- return { path: frameworkPath, isFrameworkFile: true };
517
+ // Try direct file match first, then index file fallback
518
+ const candidates = [pathWithinFramework, `${pathWithinFramework}/index`];
519
+ for (const candidate of candidates) {
520
+ for (const ext of extensions) {
521
+ const frameworkPath = join(frameworkDir, candidate + ext);
522
+ try {
523
+ const stat = await platformFs.stat(frameworkPath);
524
+ if (stat.isFile) {
525
+ logger.debug(`Found framework ${label} file`, {
526
+ basePath: basePathWithoutExt,
527
+ resolvedPath: frameworkPath,
528
+ });
529
+ return { path: frameworkPath, isFrameworkFile: true };
530
+ }
531
+ } catch (_) {
532
+ /* expected: file may not exist at this extension */
527
533
  }
528
- } catch (_) {
529
- /* expected: file may not exist at this extension */
530
534
  }
531
535
  }
532
536
  }
@@ -12,7 +12,10 @@ import type {
12
12
  RewriteResult,
13
13
  } from "../types.js";
14
14
  import { buildVeryfrontModuleUrl } from "../url-builder.js";
15
- import { resolveVeryfrontModuleUrl } from "../../veryfront-module-urls.js";
15
+ import {
16
+ resolveInternalModuleUrl,
17
+ resolveVeryfrontModuleUrl,
18
+ } from "../../veryfront-module-urls.js";
16
19
 
17
20
  /**
18
21
  * SSR-specific module overrides.
@@ -46,10 +49,17 @@ export class VeryfrontStrategy implements ImportRewriteStrategy {
46
49
  // Try resolving via deno.json mappings first (veryfront/head → react/components/Head.js)
47
50
  const mapped = resolveVeryfrontModuleUrl(`veryfront/${path}`);
48
51
  if (mapped) {
49
- // For SSR, append ?ssr=true to signal server-side rendering
50
52
  if (ctx.target === "ssr") return { specifier: `${mapped}?ssr=true` };
51
53
  return { specifier: mapped };
52
54
  }
55
+ // Try resolving via #veryfront/* import map (handles paths where the
56
+ // filesystem layout differs from the specifier, e.g. #veryfront/compat/console
57
+ // maps to src/platform/compat/console/index.ts, not src/compat/console.ts)
58
+ const internalMapped = resolveInternalModuleUrl(specifier);
59
+ if (internalMapped) {
60
+ if (ctx.target === "ssr") return { specifier: `${internalMapped}?ssr=true` };
61
+ return { specifier: internalMapped };
62
+ }
53
63
  const builtUrl = buildVeryfrontModuleUrl(path);
54
64
  if (ctx.target === "ssr") return { specifier: `${builtUrl}?ssr=true` };
55
65
  return { specifier: builtUrl };
@@ -8,6 +8,7 @@
8
8
  import { createFileSystem, exists } from "../../../../platform/compat/fs.js";
9
9
  import { join } from "../../../../platform/compat/path/index.js";
10
10
  import { rendererLogger as logger } from "../../../../utils/index.js";
11
+ import { resolveInternalModuleTarget } from "../../../veryfront-module-urls.js";
11
12
  import {
12
13
  EMBEDDED_SRC_DIR,
13
14
  EXTENSIONS,
@@ -120,7 +121,10 @@ export async function resolveFrameworkFile(
120
121
  export async function resolveVeryfrontSourcePath(specifier: string): Promise<string | null> {
121
122
  if (!specifier.startsWith("#veryfront/")) return null;
122
123
 
123
- const relativePath = specifier.slice("#veryfront/".length);
124
+ const mappedTarget = resolveInternalModuleTarget(specifier);
125
+ if (!mappedTarget?.startsWith("./src/")) return null;
126
+
127
+ const relativePath = mappedTarget.slice("./src/".length);
124
128
  const hasExtension = /\.(tsx?|jsx?|mjs)$/.test(relativePath);
125
129
 
126
130
  // Check embedded sources first (for compiled binaries), then regular src/
@@ -8,47 +8,120 @@ type DenoConfig = {
8
8
  const MODULE_EXT_RE = /\.(mjs|cjs|js|jsx|ts|tsx)$/;
9
9
  const SRC_PREFIX = "./src/";
10
10
 
11
+ type ModuleTargetIndex = {
12
+ exactTargets: Map<string, string>;
13
+ prefixTargets: Array<{ specifierPrefix: string; targetPrefix: string }>;
14
+ };
15
+
16
+ function createTargetIndex(): ModuleTargetIndex {
17
+ return {
18
+ exactTargets: new Map<string, string>(),
19
+ prefixTargets: [],
20
+ };
21
+ }
22
+
23
+ function normalizeModulePath(path: string): string {
24
+ if (!path) return path;
25
+ if (path.endsWith("/")) return path;
26
+ return path.replace(MODULE_EXT_RE, ".js");
27
+ }
28
+
11
29
  function toModuleServerUrl(target: string): string | null {
12
30
  if (!target.startsWith(SRC_PREFIX)) return null;
13
31
 
14
32
  const relative = target.slice(SRC_PREFIX.length);
15
33
  if (!relative) return null;
16
34
 
17
- const withoutExt = relative.replace(MODULE_EXT_RE, "");
18
- return `/_vf_modules/_veryfront/${withoutExt}.js`;
35
+ return `/_vf_modules/_veryfront/${normalizeModulePath(relative)}`;
19
36
  }
20
37
 
21
38
  function addMapping(
22
- map: Map<string, string>,
39
+ index: ModuleTargetIndex,
23
40
  specifier: string,
24
41
  target: string,
25
42
  ): void {
26
- const url = toModuleServerUrl(target);
27
- if (!url) return;
28
- map.set(specifier, url);
43
+ if (!target.startsWith(SRC_PREFIX)) return;
44
+
45
+ if (specifier.endsWith("/")) {
46
+ index.prefixTargets.push({
47
+ specifierPrefix: specifier,
48
+ targetPrefix: target.endsWith("/") ? target : `${target}/`,
49
+ });
50
+ return;
51
+ }
52
+
53
+ index.exactTargets.set(specifier, target);
54
+ }
55
+
56
+ function finalizeIndex(index: ModuleTargetIndex): void {
57
+ index.prefixTargets.sort((a, b) => b.specifierPrefix.length - a.specifierPrefix.length);
58
+ }
59
+
60
+ function resolveTarget(index: ModuleTargetIndex, specifier: string): string | null {
61
+ const exact = index.exactTargets.get(specifier);
62
+ if (exact) return exact;
63
+
64
+ for (const { specifierPrefix, targetPrefix } of index.prefixTargets) {
65
+ if (!specifier.startsWith(specifierPrefix)) continue;
66
+ return `${targetPrefix}${specifier.slice(specifierPrefix.length)}`;
67
+ }
68
+
69
+ return null;
29
70
  }
30
71
 
31
72
  const config = denoConfig as DenoConfig;
32
- const veryfrontModuleUrlMap = new Map<string, string>();
73
+ const veryfrontTargetIndex = createTargetIndex();
74
+ const internalTargetIndex = createTargetIndex();
33
75
 
34
76
  for (const [specifier, target] of Object.entries(config.imports ?? {})) {
35
- if (!specifier.startsWith("veryfront/")) continue;
36
77
  if (typeof target !== "string") continue;
37
- addMapping(veryfrontModuleUrlMap, specifier, target);
78
+
79
+ if (specifier === "veryfront" || specifier.startsWith("veryfront/")) {
80
+ addMapping(veryfrontTargetIndex, specifier, target);
81
+ }
82
+
83
+ // Also index #veryfront imports so the import rewriter can
84
+ // generate correct /_vf_modules/ URLs that match the actual filesystem layout.
85
+ if (specifier === "#veryfront" || specifier.startsWith("#veryfront/")) {
86
+ addMapping(internalTargetIndex, specifier, target);
87
+ }
38
88
  }
39
89
 
40
90
  for (const [key, target] of Object.entries(config.exports ?? {})) {
41
91
  if (typeof target !== "string") continue;
42
92
 
43
93
  if (key === ".") {
44
- addMapping(veryfrontModuleUrlMap, "veryfront", target);
94
+ addMapping(veryfrontTargetIndex, "veryfront", target);
45
95
  continue;
46
96
  }
47
97
 
48
98
  if (!key.startsWith("./")) continue;
49
- addMapping(veryfrontModuleUrlMap, `veryfront/${key.slice(2)}`, target);
99
+ addMapping(veryfrontTargetIndex, `veryfront/${key.slice(2)}`, target);
100
+ }
101
+
102
+ finalizeIndex(veryfrontTargetIndex);
103
+ finalizeIndex(internalTargetIndex);
104
+
105
+ export function resolveVeryfrontModuleTarget(specifier: string): string | null {
106
+ return resolveTarget(veryfrontTargetIndex, specifier);
107
+ }
108
+
109
+ export function resolveInternalModuleTarget(specifier: string): string | null {
110
+ return resolveTarget(internalTargetIndex, specifier);
50
111
  }
51
112
 
52
113
  export function resolveVeryfrontModuleUrl(specifier: string): string | null {
53
- return veryfrontModuleUrlMap.get(specifier) ?? null;
114
+ const target = resolveVeryfrontModuleTarget(specifier);
115
+ return target ? toModuleServerUrl(target) : null;
116
+ }
117
+
118
+ /**
119
+ * Resolve an internal #veryfront/* specifier to a /_vf_modules/ URL.
120
+ * Uses the deno.json import map to get the correct filesystem path,
121
+ * which may differ from the specifier path (e.g. #veryfront/compat/console
122
+ * maps to src/platform/compat/console/index.ts, not src/compat/console.ts).
123
+ */
124
+ export function resolveInternalModuleUrl(specifier: string): string | null {
125
+ const target = resolveInternalModuleTarget(specifier);
126
+ return target ? toModuleServerUrl(target) : null;
54
127
  }