veryfront 0.1.57 → 0.1.59

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.59",
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,CAsDrD,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;AAwND;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAG7D"}
@@ -3,7 +3,7 @@ import * as dntShim from "../../../_dnt.shims.js";
3
3
  import { join } from "../../platform/compat/path/index.js";
4
4
  import { createFileSystem } from "../../platform/compat/fs.js";
5
5
  import { transformToESM } from "../../transforms/esm-transform.js";
6
- import { serverLogger } from "../../utils/index.js";
6
+ import { serverLogger, VERSION } from "../../utils/index.js";
7
7
  import { HTTP_NOT_FOUND, HTTP_OK, HTTP_SERVER_ERROR } from "../../utils/index.js";
8
8
  import { getContentTypeForPath } from "../../server/handlers/utils/content-types.js";
9
9
  import { createSecureFs } from "../../security/index.js";
@@ -76,6 +76,10 @@ export default {};
76
76
  `export default {};`,
77
77
  ].join("\n") + "\n",
78
78
  "_dnt.polyfills": `export default {};\n`,
79
+ // Deno import-map alias stub for browser/HTTP-served framework modules.
80
+ // Must be a JS module (not JSON) because esbuild strips `with { type: "json" }`
81
+ // at es2020 target, and browsers reject JSON MIME type without the assertion.
82
+ "_veryfront/_deno-config": `export default ${JSON.stringify({ version: VERSION })};\n`,
79
83
  };
80
84
  const DEV_MODULE_PREFIX = /^\/(?:_vf_modules|_veryfront\/modules)\//;
81
85
  const SNIPPET_MODULE_PREFIX = /^\/_vf_modules\/_snippets\/([a-f0-9]+)\.js/;
@@ -331,6 +335,7 @@ const EMBEDDED_SRC_DIR = join(FRAMEWORK_ROOT, "dist", "framework-src");
331
335
  async function findSourceFile(secureFs, projectDir, basePath) {
332
336
  // Extensions including .src for compiled binary embedded sources
333
337
  const extensions = [
338
+ ".json",
334
339
  ".tsx.src",
335
340
  ".ts.src",
336
341
  ".jsx.src",
@@ -347,7 +352,7 @@ async function findSourceFile(secureFs, projectDir, basePath) {
347
352
  logger.debug("findSourceFile called", { projectDir, basePath });
348
353
  const hasKnownExt = extensions.some((ext) => basePath.endsWith(ext));
349
354
  const rawBasePathWithoutExt = hasKnownExt
350
- ? basePath.replace(/\.(tsx|ts|jsx|js|mdx|md)(\.src)?$/, "")
355
+ ? basePath.replace(/\.(json|tsx|ts|jsx|js|mdx|md)(\.src)?$/, "")
351
356
  : basePath;
352
357
  let basePathWithoutExt = rawBasePathWithoutExt.replace(/^\/+/, "");
353
358
  if (basePathWithoutExt.startsWith("_vf_modules/")) {
@@ -374,7 +379,7 @@ async function findSourceFile(secureFs, projectDir, basePath) {
374
379
  basePath: basePathWithoutExt,
375
380
  });
376
381
  return {
377
- path: `embedded:${basePathWithoutExt}`,
382
+ path: `embedded:${basePath}`,
378
383
  isFrameworkFile: true,
379
384
  embeddedContent,
380
385
  };
@@ -388,20 +393,24 @@ async function findSourceFile(secureFs, projectDir, basePath) {
388
393
  const pathWithinFramework = stripPrefix
389
394
  ? basePathWithoutExt.slice(prefix.length)
390
395
  : 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 };
396
+ // Try direct file match first, then index file fallback
397
+ const candidates = [pathWithinFramework, `${pathWithinFramework}/index`];
398
+ for (const candidate of candidates) {
399
+ for (const ext of extensions) {
400
+ const frameworkPath = join(frameworkDir, candidate + ext);
401
+ try {
402
+ const stat = await platformFs.stat(frameworkPath);
403
+ if (stat.isFile) {
404
+ logger.debug(`Found framework ${label} file`, {
405
+ basePath: basePathWithoutExt,
406
+ resolvedPath: frameworkPath,
407
+ });
408
+ return { path: frameworkPath, isFrameworkFile: true };
409
+ }
410
+ }
411
+ catch (_) {
412
+ /* expected: file may not exist at this extension */
401
413
  }
402
- }
403
- catch (_) {
404
- /* expected: file may not exist at this extension */
405
414
  }
406
415
  }
407
416
  }
@@ -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;IASzD,OAAO,CAAC,IAAI,EAAE,mBAAmB,EAAE,GAAG,EAAE,cAAc,GAAG,aAAa;CAkDvE;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
  *
@@ -22,21 +22,36 @@ export class VeryfrontStrategy {
22
22
  matches(specifier, _ctx) {
23
23
  return (specifier.startsWith("#veryfront/") ||
24
24
  specifier.startsWith("veryfront/") ||
25
- specifier === "veryfront");
25
+ specifier === "veryfront" ||
26
+ specifier === "#deno-config");
26
27
  }
27
28
  rewrite(info, ctx) {
28
29
  const specifier = info.specifier;
30
+ // Handle #deno-config — Deno import-map alias that doesn't exist in browsers.
31
+ // Rewrite to a JS module (not JSON) because esbuild strips `with { type: "json" }`
32
+ // at es2020 target and browsers reject JSON MIME without the assertion.
33
+ if (specifier === "#deno-config") {
34
+ return { specifier: "/_vf_modules/_veryfront/_deno-config.js" };
35
+ }
29
36
  // Handle #veryfront/* (internal framework imports)
30
37
  if (specifier.startsWith("#veryfront/")) {
31
38
  const path = specifier.slice("#veryfront/".length);
32
39
  // Try resolving via deno.json mappings first (veryfront/head → react/components/Head.js)
33
40
  const mapped = resolveVeryfrontModuleUrl(`veryfront/${path}`);
34
41
  if (mapped) {
35
- // For SSR, append ?ssr=true to signal server-side rendering
36
42
  if (ctx.target === "ssr")
37
43
  return { specifier: `${mapped}?ssr=true` };
38
44
  return { specifier: mapped };
39
45
  }
46
+ // Try resolving via #veryfront/* import map (handles paths where the
47
+ // filesystem layout differs from the specifier, e.g. #veryfront/compat/console
48
+ // maps to src/platform/compat/console/index.ts, not src/compat/console.ts)
49
+ const internalMapped = resolveInternalModuleUrl(specifier);
50
+ if (internalMapped) {
51
+ if (ctx.target === "ssr")
52
+ return { specifier: `${internalMapped}?ssr=true` };
53
+ return { specifier: internalMapped };
54
+ }
40
55
  const builtUrl = buildVeryfrontModuleUrl(path);
41
56
  if (ctx.target === "ssr")
42
57
  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
  }
@@ -1,4 +1,4 @@
1
- export declare const VERSION: string;
1
+ export declare const VERSION = "0.1.59";
2
2
  export declare const SERVER_START_TIME: number;
3
3
  export interface BuildVersion {
4
4
  framework: string;
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../src/src/utils/version.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,OAAO,EAAE,MAA6B,CAAC;AAEpD,eAAO,MAAM,iBAAiB,EAAE,MAAmB,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,kBAAkB,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,YAAY,CAM1E"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../src/src/utils/version.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,WAAW,CAAC;AAEhC,eAAO,MAAM,iBAAiB,EAAE,MAAmB,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,kBAAkB,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,YAAY,CAM1E"}
@@ -1,9 +1,6 @@
1
- import denoConfig from "../../deno.js";
2
- function getVersionFromDeno() {
3
- return typeof denoConfig.version === "string" ? denoConfig.version : "0.0.0";
4
- }
5
- // Use deno.json version directly to avoid env access at module load
6
- export const VERSION = getVersionFromDeno();
1
+ // Keep in sync with deno.json version.
2
+ // scripts/release.ts updates this constant during releases.
3
+ export const VERSION = "0.1.59";
7
4
  export const SERVER_START_TIME = Date.now();
8
5
  export function createBuildVersion(projectUpdatedAt) {
9
6
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.1.57",
3
+ "version": "0.1.59",
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.59",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "exclude": [
@@ -6,7 +6,7 @@ import { join } from "../../platform/compat/path/index.js";
6
6
  import type { RuntimeAdapter } from "../../platform/adapters/base.js";
7
7
  import { createFileSystem } from "../../platform/compat/fs.js";
8
8
  import { type TransformOptions, transformToESM } from "../../transforms/esm-transform.js";
9
- import { serverLogger } from "../../utils/index.js";
9
+ import { serverLogger, VERSION } from "../../utils/index.js";
10
10
  import { HTTP_NOT_FOUND, HTTP_OK, HTTP_SERVER_ERROR } from "../../utils/index.js";
11
11
  import { getContentTypeForPath } from "../../server/handlers/utils/content-types.js";
12
12
  import { createSecureFs } from "../../security/index.js";
@@ -81,6 +81,10 @@ export default {};
81
81
  `export default {};`,
82
82
  ].join("\n") + "\n",
83
83
  "_dnt.polyfills": `export default {};\n`,
84
+ // Deno import-map alias stub for browser/HTTP-served framework modules.
85
+ // Must be a JS module (not JSON) because esbuild strips `with { type: "json" }`
86
+ // at es2020 target, and browsers reject JSON MIME type without the assertion.
87
+ "_veryfront/_deno-config": `export default ${JSON.stringify({ version: VERSION })};\n`,
84
88
  };
85
89
 
86
90
  const DEV_MODULE_PREFIX = /^\/(?:_vf_modules|_veryfront\/modules)\//;
@@ -449,6 +453,7 @@ async function findSourceFile(
449
453
  ): Promise<FindSourceFileResult | null> {
450
454
  // Extensions including .src for compiled binary embedded sources
451
455
  const extensions = [
456
+ ".json",
452
457
  ".tsx.src",
453
458
  ".ts.src",
454
459
  ".jsx.src",
@@ -467,7 +472,7 @@ async function findSourceFile(
467
472
 
468
473
  const hasKnownExt = extensions.some((ext) => basePath.endsWith(ext));
469
474
  const rawBasePathWithoutExt = hasKnownExt
470
- ? basePath.replace(/\.(tsx|ts|jsx|js|mdx|md)(\.src)?$/, "")
475
+ ? basePath.replace(/\.(json|tsx|ts|jsx|js|mdx|md)(\.src)?$/, "")
471
476
  : basePath;
472
477
  let basePathWithoutExt = rawBasePathWithoutExt.replace(/^\/+/, "");
473
478
  if (basePathWithoutExt.startsWith("_vf_modules/")) {
@@ -496,7 +501,7 @@ async function findSourceFile(
496
501
  basePath: basePathWithoutExt,
497
502
  });
498
503
  return {
499
- path: `embedded:${basePathWithoutExt}`,
504
+ path: `embedded:${basePath}`,
500
505
  isFrameworkFile: true,
501
506
  embeddedContent,
502
507
  };
@@ -514,19 +519,23 @@ async function findSourceFile(
514
519
  ? basePathWithoutExt.slice(prefix.length)
515
520
  : basePathWithoutExt;
516
521
 
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 };
522
+ // Try direct file match first, then index file fallback
523
+ const candidates = [pathWithinFramework, `${pathWithinFramework}/index`];
524
+ for (const candidate of candidates) {
525
+ for (const ext of extensions) {
526
+ const frameworkPath = join(frameworkDir, candidate + ext);
527
+ try {
528
+ const stat = await platformFs.stat(frameworkPath);
529
+ if (stat.isFile) {
530
+ logger.debug(`Found framework ${label} file`, {
531
+ basePath: basePathWithoutExt,
532
+ resolvedPath: frameworkPath,
533
+ });
534
+ return { path: frameworkPath, isFrameworkFile: true };
535
+ }
536
+ } catch (_) {
537
+ /* expected: file may not exist at this extension */
527
538
  }
528
- } catch (_) {
529
- /* expected: file may not exist at this extension */
530
539
  }
531
540
  }
532
541
  }
@@ -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.
@@ -33,23 +36,38 @@ export class VeryfrontStrategy implements ImportRewriteStrategy {
33
36
  return (
34
37
  specifier.startsWith("#veryfront/") ||
35
38
  specifier.startsWith("veryfront/") ||
36
- specifier === "veryfront"
39
+ specifier === "veryfront" ||
40
+ specifier === "#deno-config"
37
41
  );
38
42
  }
39
43
 
40
44
  rewrite(info: ImportSpecifierInfo, ctx: RewriteContext): RewriteResult {
41
45
  const specifier = info.specifier;
42
46
 
47
+ // Handle #deno-config — Deno import-map alias that doesn't exist in browsers.
48
+ // Rewrite to a JS module (not JSON) because esbuild strips `with { type: "json" }`
49
+ // at es2020 target and browsers reject JSON MIME without the assertion.
50
+ if (specifier === "#deno-config") {
51
+ return { specifier: "/_vf_modules/_veryfront/_deno-config.js" };
52
+ }
53
+
43
54
  // Handle #veryfront/* (internal framework imports)
44
55
  if (specifier.startsWith("#veryfront/")) {
45
56
  const path = specifier.slice("#veryfront/".length);
46
57
  // Try resolving via deno.json mappings first (veryfront/head → react/components/Head.js)
47
58
  const mapped = resolveVeryfrontModuleUrl(`veryfront/${path}`);
48
59
  if (mapped) {
49
- // For SSR, append ?ssr=true to signal server-side rendering
50
60
  if (ctx.target === "ssr") return { specifier: `${mapped}?ssr=true` };
51
61
  return { specifier: mapped };
52
62
  }
63
+ // Try resolving via #veryfront/* import map (handles paths where the
64
+ // filesystem layout differs from the specifier, e.g. #veryfront/compat/console
65
+ // maps to src/platform/compat/console/index.ts, not src/compat/console.ts)
66
+ const internalMapped = resolveInternalModuleUrl(specifier);
67
+ if (internalMapped) {
68
+ if (ctx.target === "ssr") return { specifier: `${internalMapped}?ssr=true` };
69
+ return { specifier: internalMapped };
70
+ }
53
71
  const builtUrl = buildVeryfrontModuleUrl(path);
54
72
  if (ctx.target === "ssr") return { specifier: `${builtUrl}?ssr=true` };
55
73
  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
  }
@@ -1,11 +1,6 @@
1
- import denoConfig from "../../deno.js";
2
-
3
- function getVersionFromDeno(): string {
4
- return typeof denoConfig.version === "string" ? denoConfig.version : "0.0.0";
5
- }
6
-
7
- // Use deno.json version directly to avoid env access at module load
8
- export const VERSION: string = getVersionFromDeno();
1
+ // Keep in sync with deno.json version.
2
+ // scripts/release.ts updates this constant during releases.
3
+ export const VERSION = "0.1.59";
9
4
 
10
5
  export const SERVER_START_TIME: number = Date.now();
11
6