veryfront 0.1.81 → 0.1.83
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 +1 -1
- package/esm/src/platform/adapters/base.d.ts +4 -1
- package/esm/src/platform/adapters/base.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/github/adapter.d.ts +2 -1
- package/esm/src/platform/adapters/fs/github/adapter.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/github/adapter.js +2 -2
- package/esm/src/platform/adapters/fs/github/stat-operations.d.ts +2 -1
- package/esm/src/platform/adapters/fs/github/stat-operations.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/github/stat-operations.js +2 -2
- package/esm/src/platform/adapters/fs/veryfront/adapter.d.ts +2 -2
- package/esm/src/platform/adapters/fs/veryfront/adapter.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/adapter.js +17 -2
- package/esm/src/platform/adapters/fs/veryfront/multi-project-adapter.d.ts +2 -2
- package/esm/src/platform/adapters/fs/veryfront/multi-project-adapter.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/multi-project-adapter.js +2 -2
- package/esm/src/platform/adapters/fs/veryfront/read-operations.d.ts +1 -0
- package/esm/src/platform/adapters/fs/veryfront/read-operations.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/stat-operations.d.ts +6 -2
- package/esm/src/platform/adapters/fs/veryfront/stat-operations.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/stat-operations.js +131 -21
- package/esm/src/platform/adapters/fs/veryfront/types.d.ts +2 -1
- package/esm/src/platform/adapters/fs/veryfront/types.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/wrapper.d.ts +2 -2
- package/esm/src/platform/adapters/fs/wrapper.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/wrapper.js +2 -2
- package/esm/src/rendering/app-route-resolver.js +0 -9
- package/esm/src/rendering/orchestrator/file-resolver/index.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/file-resolver/index.js +17 -0
- package/esm/src/rendering/orchestrator/module-loader/index.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/module-loader/index.js +7 -20
- package/esm/src/rendering/page-resolution/page-resolver.d.ts.map +1 -1
- package/esm/src/rendering/page-resolution/page-resolver.js +19 -6
- package/esm/src/rendering/router-detection.d.ts +1 -0
- package/esm/src/rendering/router-detection.d.ts.map +1 -1
- package/esm/src/rendering/router-detection.js +3 -0
- package/esm/src/transforms/esm/bundle-manifest.d.ts +3 -1
- package/esm/src/transforms/esm/bundle-manifest.d.ts.map +1 -1
- package/esm/src/transforms/esm/bundle-manifest.js +2 -2
- package/esm/src/transforms/esm/cached-bundle-validation.d.ts +9 -0
- package/esm/src/transforms/esm/cached-bundle-validation.d.ts.map +1 -0
- package/esm/src/transforms/esm/cached-bundle-validation.js +25 -0
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/distributed-cache.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/distributed-cache.js +9 -21
- package/esm/src/transforms/pipeline/index.d.ts.map +1 -1
- package/esm/src/transforms/pipeline/index.js +8 -24
- package/esm/src/types/entities/getEntityInfo.d.ts.map +1 -1
- package/esm/src/types/entities/getEntityInfo.js +59 -42
- package/package.json +1 -1
- package/src/deno.js +1 -1
- package/src/src/platform/adapters/base.ts +5 -1
- package/src/src/platform/adapters/fs/github/adapter.ts +3 -2
- package/src/src/platform/adapters/fs/github/stat-operations.ts +3 -2
- package/src/src/platform/adapters/fs/veryfront/adapter.ts +24 -3
- package/src/src/platform/adapters/fs/veryfront/multi-project-adapter.ts +6 -3
- package/src/src/platform/adapters/fs/veryfront/read-operations.ts +1 -0
- package/src/src/platform/adapters/fs/veryfront/stat-operations.ts +161 -25
- package/src/src/platform/adapters/fs/veryfront/types.ts +2 -1
- package/src/src/platform/adapters/fs/wrapper.ts +10 -3
- package/src/src/rendering/app-route-resolver.ts +0 -8
- package/src/src/rendering/orchestrator/file-resolver/index.ts +19 -0
- package/src/src/rendering/orchestrator/module-loader/index.ts +11 -19
- package/src/src/rendering/page-resolution/page-resolver.ts +26 -17
- package/src/src/rendering/router-detection.ts +7 -0
- package/src/src/transforms/esm/bundle-manifest.ts +6 -3
- package/src/src/transforms/esm/cached-bundle-validation.ts +40 -0
- package/src/src/transforms/mdx/esm-module-loader/module-fetcher/distributed-cache.ts +13 -24
- package/src/src/transforms/pipeline/index.ts +8 -26
- package/src/src/types/entities/getEntityInfo.ts +78 -59
|
@@ -9,14 +9,11 @@
|
|
|
9
9
|
|
|
10
10
|
import type { Logger } from "../../../../utils/logger/logger.js";
|
|
11
11
|
import { detokenizeAllCachePaths, tokenizeAllVeryFrontPaths } from "../../../../cache/index.js";
|
|
12
|
-
import { cacheHttpImportsToLocal
|
|
12
|
+
import { cacheHttpImportsToLocal } from "../../../esm/http-cache.js";
|
|
13
13
|
import { loadImportMap } from "../../../../modules/import-map/index.js";
|
|
14
14
|
import { extractHttpBundlePaths } from "../../../../modules/react-loader/ssr-module-loader/http-bundle-helpers.js";
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
storeBundleManifest,
|
|
18
|
-
validateBundleGroup,
|
|
19
|
-
} from "../../../esm/bundle-manifest.js";
|
|
15
|
+
import { createBundleManifest, storeBundleManifest } from "../../../esm/bundle-manifest.js";
|
|
16
|
+
import { validateCachedBundlesByManifestOrCode } from "../../../esm/cached-bundle-validation.js";
|
|
20
17
|
import { getHttpBundleCacheDir } from "../../../../utils/cache-dir.js";
|
|
21
18
|
import { FRAMEWORK_ROOT, LOG_PREFIX_MDX_LOADER } from "../constants.js";
|
|
22
19
|
import { getDistributedTransformBackend } from "../../../esm/transform-cache.js";
|
|
@@ -86,31 +83,23 @@ export async function readDistributedCache(
|
|
|
86
83
|
const bundleManifestKey = `${transformCacheKey}:bm`;
|
|
87
84
|
const manifestId = await distributedCache.get(bundleManifestKey).catch(() => null);
|
|
88
85
|
|
|
89
|
-
if (
|
|
86
|
+
if (moduleCode) {
|
|
90
87
|
const cacheDir = getHttpBundleCacheDir();
|
|
91
|
-
const validation = await
|
|
88
|
+
const validation = await validateCachedBundlesByManifestOrCode(
|
|
89
|
+
moduleCode,
|
|
90
|
+
manifestId ?? undefined,
|
|
91
|
+
cacheDir,
|
|
92
|
+
);
|
|
92
93
|
if (!validation.valid) {
|
|
93
|
-
log.warn(`${LOG_PREFIX_MDX_LOADER}
|
|
94
|
+
log.warn(`${LOG_PREFIX_MDX_LOADER} Cached HTTP bundle validation failed`, {
|
|
94
95
|
normalizedPath,
|
|
95
|
-
manifestId: manifestId
|
|
96
|
+
manifestId: manifestId?.slice(0, 12),
|
|
96
97
|
failedHashes: validation.failedHashes,
|
|
98
|
+
reason: validation.reason,
|
|
99
|
+
source: validation.source,
|
|
97
100
|
});
|
|
98
101
|
moduleCode = null;
|
|
99
102
|
}
|
|
100
|
-
} else {
|
|
101
|
-
// Use detokenized code for bundle path extraction
|
|
102
|
-
const bundlePaths = extractHttpBundlePaths(moduleCode);
|
|
103
|
-
if (bundlePaths.length > 0) {
|
|
104
|
-
const cacheDir = getHttpBundleCacheDir();
|
|
105
|
-
const failed = await ensureHttpBundlesExist(bundlePaths, cacheDir);
|
|
106
|
-
if (failed.length > 0) {
|
|
107
|
-
log.warn(`${LOG_PREFIX_MDX_LOADER} Some HTTP bundles could not be recovered`, {
|
|
108
|
-
normalizedPath,
|
|
109
|
-
failed,
|
|
110
|
-
});
|
|
111
|
-
moduleCode = null;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
103
|
}
|
|
115
104
|
|
|
116
105
|
// Use detokenized code for framework path checks
|
|
@@ -31,10 +31,8 @@ import {
|
|
|
31
31
|
ssrVfModulesPlugin,
|
|
32
32
|
} from "./stages/index.js";
|
|
33
33
|
import { createFileSystem, exists } from "../../platform/compat/fs.js";
|
|
34
|
-
import { ensureHttpBundlesExist } from "../esm/http-cache.js";
|
|
35
|
-
import { extractHttpBundlePaths } from "../../modules/react-loader/ssr-module-loader/http-bundle-helpers.js";
|
|
36
34
|
import { getHttpBundleCacheDir } from "../../utils/cache-dir.js";
|
|
37
|
-
import {
|
|
35
|
+
import { validateCachedBundlesByManifestOrCode } from "../esm/cached-bundle-validation.js";
|
|
38
36
|
import { extractFrameworkBundlePaths } from "../shared/framework-bundle-paths.js";
|
|
39
37
|
|
|
40
38
|
const SSR_PIPELINE: TransformPlugin[] = [
|
|
@@ -130,31 +128,15 @@ async function validateCachedBundles(
|
|
|
130
128
|
cacheKey: string,
|
|
131
129
|
): Promise<boolean> {
|
|
132
130
|
const cacheDir = getHttpBundleCacheDir();
|
|
131
|
+
const validation = await validateCachedBundlesByManifestOrCode(code, bundleManifestId, cacheDir);
|
|
132
|
+
if (validation.valid) return true;
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
if (bundleManifestId) {
|
|
136
|
-
const validation = await validateBundleGroup(bundleManifestId, cacheDir);
|
|
137
|
-
if (validation.valid) return true;
|
|
138
|
-
|
|
139
|
-
logger.debug("Bundle manifest validation failed", {
|
|
140
|
-
cacheKey: cacheKey.slice(-40),
|
|
141
|
-
manifestId: bundleManifestId.slice(0, 12),
|
|
142
|
-
failedCount: validation.failedHashes.length,
|
|
143
|
-
});
|
|
144
|
-
return false;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Fall back to extracting bundle paths from code and validating each
|
|
148
|
-
const bundlePaths = extractHttpBundlePaths(code);
|
|
149
|
-
if (bundlePaths.length === 0) return true;
|
|
150
|
-
|
|
151
|
-
const failed = await ensureHttpBundlesExist(bundlePaths, cacheDir);
|
|
152
|
-
if (failed.length === 0) return true;
|
|
153
|
-
|
|
154
|
-
logger.debug("HTTP bundle validation failed", {
|
|
134
|
+
logger.debug("Cached HTTP bundle validation failed", {
|
|
155
135
|
cacheKey: cacheKey.slice(-40),
|
|
156
|
-
|
|
157
|
-
|
|
136
|
+
manifestId: bundleManifestId?.slice(0, 12),
|
|
137
|
+
failedCount: validation.failedHashes.length,
|
|
138
|
+
reason: validation.reason,
|
|
139
|
+
source: validation.source,
|
|
158
140
|
});
|
|
159
141
|
return false;
|
|
160
142
|
}
|
|
@@ -43,49 +43,55 @@ export async function getEntityInfo(
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
try {
|
|
46
|
+
const shouldReadDirectly = adapter
|
|
47
|
+
? isExtendedFSAdapter(adapter.fs) && adapter.fs.isVeryfrontAdapter()
|
|
48
|
+
: false;
|
|
49
|
+
|
|
50
|
+
let content: string;
|
|
46
51
|
if (adapter) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
52
|
+
if (!shouldReadDirectly) {
|
|
53
|
+
try {
|
|
54
|
+
const stat = await withFallback(
|
|
55
|
+
() => adapter.fs.stat(normalizedPath),
|
|
56
|
+
async () => {
|
|
57
|
+
const exists = await fs.exists(filePath);
|
|
58
|
+
if (!exists) {
|
|
59
|
+
throw toError(
|
|
60
|
+
createError({
|
|
61
|
+
type: "file",
|
|
62
|
+
message: "File not found",
|
|
63
|
+
context: { path: filePath, operation: "read" },
|
|
64
|
+
}),
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
return await fs.stat(filePath);
|
|
68
|
+
},
|
|
69
|
+
{ operationName: "stat:getEntityInfo", logError: false },
|
|
70
|
+
);
|
|
65
71
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
if (!stat.isFile) return null;
|
|
73
|
+
} catch (error) {
|
|
74
|
+
entityInfoScope.runSync(
|
|
75
|
+
() => {
|
|
76
|
+
throw error;
|
|
77
|
+
},
|
|
78
|
+
{ path: filePath, details: { reason: "stat-failed" } },
|
|
79
|
+
undefined,
|
|
80
|
+
);
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
76
83
|
}
|
|
77
|
-
} else {
|
|
78
|
-
const exists = await fs.exists(filePath);
|
|
79
|
-
if (!exists) return null;
|
|
80
|
-
}
|
|
81
84
|
|
|
82
|
-
|
|
83
|
-
? await withFallback(
|
|
85
|
+
content = await withFallback(
|
|
84
86
|
() => adapter.fs.readFile(normalizedPath),
|
|
85
87
|
() => fs.readTextFile(filePath),
|
|
86
88
|
{ operationName: "readFile:getEntityInfo", logError: false },
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
+
);
|
|
90
|
+
} else {
|
|
91
|
+
const exists = await fs.exists(filePath);
|
|
92
|
+
if (!exists) return null;
|
|
93
|
+
content = await fs.readTextFile(filePath);
|
|
94
|
+
}
|
|
89
95
|
|
|
90
96
|
const ext = pathHelper.extname(filePath).toLowerCase();
|
|
91
97
|
|
|
@@ -171,26 +177,30 @@ export async function getEntityBySlug(
|
|
|
171
177
|
return await withSpan(
|
|
172
178
|
"types.getEntityBySlug",
|
|
173
179
|
async () => {
|
|
174
|
-
const
|
|
180
|
+
const normalizedSlug = normalizeSlug(slug);
|
|
181
|
+
const isVeryfrontRoute = normalizedSlug.startsWith(".veryfront/") ||
|
|
182
|
+
normalizedSlug === ".veryfront";
|
|
175
183
|
const resolveFile = adapter?.fs.resolveFile;
|
|
176
184
|
|
|
177
185
|
logger.debug("START", {
|
|
178
186
|
slug,
|
|
187
|
+
normalizedSlug,
|
|
179
188
|
projectDir,
|
|
180
189
|
isVeryfrontRoute,
|
|
181
190
|
hasResolveFile: !!resolveFile,
|
|
182
191
|
});
|
|
183
192
|
|
|
184
193
|
if (resolveFile) {
|
|
185
|
-
const basePaths = [pathHelper.join(projectDir, "pages",
|
|
194
|
+
const basePaths = [pathHelper.join(projectDir, "pages", normalizedSlug)];
|
|
186
195
|
|
|
187
|
-
if (isVeryfrontRoute) basePaths.unshift(pathHelper.join(projectDir,
|
|
188
|
-
if (
|
|
196
|
+
if (isVeryfrontRoute) basePaths.unshift(pathHelper.join(projectDir, normalizedSlug));
|
|
197
|
+
if (normalizedSlug === "index" || normalizedSlug === "") {
|
|
189
198
|
basePaths.unshift(pathHelper.join(projectDir, "pages", "index"));
|
|
190
199
|
}
|
|
191
200
|
|
|
192
201
|
logger.debug("Checking paths (resolveFile branch)", {
|
|
193
202
|
slug,
|
|
203
|
+
normalizedSlug,
|
|
194
204
|
basePaths,
|
|
195
205
|
});
|
|
196
206
|
|
|
@@ -208,13 +218,14 @@ export async function getEntityBySlug(
|
|
|
208
218
|
if (info?.entity.isPage) {
|
|
209
219
|
logger.debug("Found page via resolveFile", {
|
|
210
220
|
slug,
|
|
221
|
+
normalizedSlug,
|
|
211
222
|
path: info.entity.path,
|
|
212
223
|
});
|
|
213
224
|
return info;
|
|
214
225
|
}
|
|
215
226
|
}
|
|
216
227
|
|
|
217
|
-
const slugParts =
|
|
228
|
+
const slugParts = normalizedSlug === "" ? [] : normalizedSlug.split("/");
|
|
218
229
|
for (let depth = slugParts.length - 1; depth >= 0; depth--) {
|
|
219
230
|
const parentPath = slugParts.slice(0, depth).join("/");
|
|
220
231
|
const pagesDir = parentPath
|
|
@@ -259,33 +270,33 @@ export async function getEntityBySlug(
|
|
|
259
270
|
}
|
|
260
271
|
}
|
|
261
272
|
|
|
262
|
-
logger.debug("No page found via resolveFile branch", { slug });
|
|
273
|
+
logger.debug("No page found via resolveFile branch", { slug, normalizedSlug });
|
|
263
274
|
return null;
|
|
264
275
|
}
|
|
265
276
|
|
|
266
277
|
const possiblePaths = [
|
|
267
|
-
pathHelper.join(projectDir, "pages", `${
|
|
268
|
-
pathHelper.join(projectDir, "pages", `${
|
|
269
|
-
pathHelper.join(projectDir, "pages", `${
|
|
270
|
-
pathHelper.join(projectDir, "pages", `${
|
|
271
|
-
pathHelper.join(projectDir, "pages", `${
|
|
272
|
-
pathHelper.join(projectDir, "pages", `${
|
|
273
|
-
pathHelper.join(projectDir, "pages", `${
|
|
274
|
-
pathHelper.join(projectDir, "pages", `${
|
|
275
|
-
pathHelper.join(projectDir, "pages", `${
|
|
276
|
-
pathHelper.join(projectDir, "pages", `${
|
|
278
|
+
pathHelper.join(projectDir, "pages", `${normalizedSlug}.mdx`),
|
|
279
|
+
pathHelper.join(projectDir, "pages", `${normalizedSlug}.md`),
|
|
280
|
+
pathHelper.join(projectDir, "pages", `${normalizedSlug}.tsx`),
|
|
281
|
+
pathHelper.join(projectDir, "pages", `${normalizedSlug}.jsx`),
|
|
282
|
+
pathHelper.join(projectDir, "pages", `${normalizedSlug}.ts`),
|
|
283
|
+
pathHelper.join(projectDir, "pages", `${normalizedSlug}/index.mdx`),
|
|
284
|
+
pathHelper.join(projectDir, "pages", `${normalizedSlug}/index.md`),
|
|
285
|
+
pathHelper.join(projectDir, "pages", `${normalizedSlug}/index.tsx`),
|
|
286
|
+
pathHelper.join(projectDir, "pages", `${normalizedSlug}/index.jsx`),
|
|
287
|
+
pathHelper.join(projectDir, "pages", `${normalizedSlug}/index.ts`),
|
|
277
288
|
];
|
|
278
289
|
|
|
279
290
|
if (isVeryfrontRoute) {
|
|
280
291
|
possiblePaths.unshift(
|
|
281
|
-
pathHelper.join(projectDir, `${
|
|
282
|
-
pathHelper.join(projectDir, `${
|
|
283
|
-
pathHelper.join(projectDir, `${
|
|
284
|
-
pathHelper.join(projectDir, `${
|
|
292
|
+
pathHelper.join(projectDir, `${normalizedSlug}.mdx`),
|
|
293
|
+
pathHelper.join(projectDir, `${normalizedSlug}.md`),
|
|
294
|
+
pathHelper.join(projectDir, `${normalizedSlug}.tsx`),
|
|
295
|
+
pathHelper.join(projectDir, `${normalizedSlug}.ts`),
|
|
285
296
|
);
|
|
286
297
|
}
|
|
287
298
|
|
|
288
|
-
if (
|
|
299
|
+
if (normalizedSlug === "index" || normalizedSlug === "") {
|
|
289
300
|
possiblePaths.unshift(
|
|
290
301
|
pathHelper.join(projectDir, "pages", "index.mdx"),
|
|
291
302
|
pathHelper.join(projectDir, "pages", "index.md"),
|
|
@@ -302,7 +313,7 @@ export async function getEntityBySlug(
|
|
|
302
313
|
if (info?.entity.isPage) return info;
|
|
303
314
|
}
|
|
304
315
|
|
|
305
|
-
const slugParts =
|
|
316
|
+
const slugParts = normalizedSlug === "" ? [] : normalizedSlug.split("/");
|
|
306
317
|
for (let depth = slugParts.length - 1; depth >= 0; depth--) {
|
|
307
318
|
const parentPath = slugParts.slice(0, depth).join("/");
|
|
308
319
|
const pagesDir = parentPath
|
|
@@ -356,7 +367,11 @@ export async function getEntityBySlug(
|
|
|
356
367
|
|
|
357
368
|
return null;
|
|
358
369
|
},
|
|
359
|
-
{
|
|
370
|
+
{
|
|
371
|
+
"entity.slug": slug,
|
|
372
|
+
"entity.normalized_slug": normalizeSlug(slug),
|
|
373
|
+
"entity.projectDir": projectDir,
|
|
374
|
+
},
|
|
360
375
|
);
|
|
361
376
|
}
|
|
362
377
|
|
|
@@ -448,3 +463,7 @@ function getSlugFromPath(filePath: string): string {
|
|
|
448
463
|
const parentDir = parts[parts.length - 2];
|
|
449
464
|
return parentDir === "pages" ? "" : parentDir ?? "";
|
|
450
465
|
}
|
|
466
|
+
|
|
467
|
+
function normalizeSlug(slug: string): string {
|
|
468
|
+
return slug === "/" ? "" : slug.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
469
|
+
}
|