Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/modules/server/module-server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
clearReactVersionCache,
getDependencyPinningSnapshot,
} from "#veryfront/transforms/esm/package-registry.ts";
import { DEPENDENCY_PINNING_ROLLOUT_PERCENT_ENV } from "#veryfront/transforms/esm/dependency-pinning-cohort.ts";
import { buildImportMapJson, clearImportMapCache } from "../../html/utils.ts";
import { hashString } from "#veryfront/cache/hash.ts";
import { register, tryResolve, unregister } from "#veryfront/extensions/contracts.ts";
Expand Down Expand Up @@ -2868,6 +2869,38 @@ describe({ name: "serveModule", sanitizeResources: false, sanitizeOps: false },
}
});

it("serves a client boundary for a project outside the pinning cohort", async () => {
// The flag arms the rollout; the cohort decides who is in it. An armed flag
// at 0% must stay inert. It did not: the early snapshot resolve was gated on
// the flag alone, so an out-of-cohort project skipped it, then carried no
// requested key -- because its document correctly emits none -- and every
// client module answered 409 instead of being served unpinned.
const projectDir = await Deno.makeTempDir({ prefix: "vf-module-cohort-out-" });
try {
setEnv(DEPENDENCY_PINNING_ENV_FLAG, "1");
setEnv(DEPENDENCY_PINNING_ROLLOUT_PERCENT_ENV, "0");
await Deno.writeTextFile(
`${projectDir}/package.json`,
JSON.stringify({ dependencies: { react: "19.2.4" } }),
);
await Deno.mkdir(`${projectDir}/components`, { recursive: true });
await Deno.writeTextFile(
`${projectDir}/components/Widget.tsx`,
['"use client";', "export default function Widget() { return null; }"].join("\n"),
);

const url = new URL("http://localhost:3000/_vf_modules/components/Widget.js");
const response = await serve(new Request(url), projectDir);
assertEquals(response.status, 200);
assertEquals(response.headers.get("content-type")?.includes("javascript"), true);
} finally {
deleteEnv(DEPENDENCY_PINNING_ROLLOUT_PERCENT_ENV);
clearReactVersionCache();
Comment thread
coderabbitai[bot] marked this conversation as resolved.
clearImportMapCache();
await Deno.remove(projectDir, { recursive: true });
}
});

it("keeps flag-off prefix graphs byte-compatible and query-free", async () => {
const projectDir = await Deno.makeTempDir({ prefix: "vf-module-prefix-off-" });
try {
Expand Down
9 changes: 8 additions & 1 deletion src/modules/server/module-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import {
resolveProjectReactVersion,
resolveRequestedDependencyPinningSnapshot,
} from "#veryfront/transforms/esm/package-registry.ts";
import { isProjectInDependencyPinningCohort } from "#veryfront/transforms/esm/dependency-pinning-cohort.ts";
import {
appendDependencyPinningPathKey,
extractDependencyPinningPathKey,
Expand Down Expand Up @@ -414,7 +415,13 @@ export function serveModule(req: Request, options: ModuleServerOptions): Promise
requestedPinCount > 1 ||
(hasRequestedPinKey &&
(!requestedPinKey || !isCanonicalDependencyPinningCacheKey(requestedPinKey))) ||
(!hasRequestedPinKey && dependencyPinningEnabled)
// The flag arms the rollout; the cohort decides who is in it. Gating on
// the flag alone conflicted every module of every project while the
// rollout sat at 0%, because an out-of-cohort document correctly emits
// no key -- so the armed flag was never inert, which is the property it
// is supposed to have.
(!hasRequestedPinKey && dependencyPinningEnabled &&
isProjectInDependencyPinningCohort(options.projectId))
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
) {
return unknownDependencySnapshotModuleResponse(method);
}
Expand Down