feat: execute route and release recovery contracts

This commit is contained in:
donghyeon-ka
2026-07-26 14:26:39 +09:00
parent a33e93d4d4
commit ce0040e407
49 changed files with 1761 additions and 373 deletions
+30
View File
@@ -13,6 +13,7 @@ const runtime = {
AUTH_MODE: "demo",
REQUEST_TIMEOUT_MS: 4321,
MAX_RETRY_ATTEMPTS: 0,
RELEASE_MANIFEST_URL: "/release-manifest.json",
},
};
const release = /** @type {const} */ ({
@@ -25,6 +26,7 @@ const release = /** @type {const} */ ({
assetManifestHash: "hash-a",
releaseId: "release-a",
builtAt: "2026-07-25T00:00:00Z",
routeChunks: { "route-home": "assets/home.js" },
});
describe("runtime adapter composition", () => {
@@ -59,6 +61,34 @@ describe("runtime adapter composition", () => {
expect(adapters.outputPorts.session.getState()).toBe("integration-failed");
});
it("refetches the active release manifest with no-store semantics", async () => {
const activeRelease = {
...release,
buildId: "build-b",
releaseId: "release-b",
routeChunks: { "route-home": "assets/home-b.js" },
};
const fetcher = vi.fn(async () => Response.json(activeRelease));
const adapters = await createRuntimeAdapters({
runtime:
/** @type {Parameters<typeof createRuntimeAdapters>[0]["runtime"]} */ (
runtime
),
release,
fetcher,
host: {},
});
await expect(adapters.outputPorts.releaseInfo.refresh()).resolves.toMatchObject({
buildId: "build-b",
releaseId: "release-b",
});
expect(fetcher).toHaveBeenCalledWith("/release-manifest.json", {
cache: "no-store",
headers: { Accept: "application/json" },
});
});
it("injects runtime timeout and max-attempt policy into HTTP execution", async () => {
const scheduled =
/** @type {Array<{callback: () => void, milliseconds: number}>} */ ([]);