Skip to content
Source
Sign inSign up
Open History to see the last commit

WorkerCache.local.test.ts

83 lines2.8 KB

1import * as Cloudflare from "@alchemy.run/cloudflare";
2import { expect } from "@alchemy.run/test";
3import * as Test from "@alchemy.run/test/Alchemy";
4import * as Data from "effect/Data";
5import * as Effect from "effect/Effect";
6import * as HttpClient from "effect/http/HttpClient";
7import { MinimumLogLevel } from "effect/References";
8import * as Schedule from "effect/Schedule";
9import * as pathe from "pathe";
10​
11// `dev: true` runs local providers behind the RPC sidecar proxy by default,
12// matching the process topology of the real `alchemy dev` command.
13const { test } = Test.make({
14 providers: Cloudflare.providers(),
15 dev: true,
16});
17​
18const logLevel = Effect.provideService(MinimumLogLevel, process.env.DEBUG ? "Debug" : "Info");
19​
20class WorkerNotReady extends Data.TaggedError("WorkerNotReady")<{
21 status: number;
22}> {}
23​
24const getText = (url: string) =>
25 Effect.gen(function* () {
26 const client = yield* HttpClient.HttpClient;
27 const res = yield* client.get(url).pipe(
28 Effect.flatMap((res) =>
29 res.status === 200
30 ? Effect.succeed(res)
31 : Effect.fail(new WorkerNotReady({ status: res.status })),
32 ),
33 Effect.retry({
34 while: (error) => error instanceof WorkerNotReady,
35 schedule: Schedule.exponential("250 millis"),
36 times: 20,
37 }),
38 );
39 return yield* res.text;
40 }).pipe(Effect.orDie);
41​
42/**
43 * Workers Cache is not emulated locally — neither Worker-wide `cache` nor
44 * per-entrypoint `entrypoints` (Miniflare's `cache` option is the Cache
45 * API, not Workers Cache). `alchemy dev` accepts the config and invokes
46 * every entrypoint on every request.
47 */
48test.provider(
49 "entrypoints is accepted locally and every entrypoint runs uncached",
50 (stack) =>
51 Effect.gen(function* () {
52 yield* stack.destroy();
53​
54 const { worker } = yield* stack.deploy(
55 Effect.gen(function* () {
56 return {
57 worker: yield* Cloudflare.Worker("entrypoint-cache-local", {
58 main: pathe.resolve(import.meta.dirname, "fixtures/cache/entrypoint-worker.ts"),
59 entrypoints: {
60 default: { cache: { enabled: true } },
61 Public: { cache: { enabled: true } },
62 },
63 }),
64 };
65 }),
66 );
67 expect(worker.url).toMatch(/^http:\/\/localhost:\d+/);
68​
69 const layers = (body: string) => /^gw:([^|]+)\|pub:(.+)$/.exec(body)?.slice(1);
70 const first = layers(yield* getText(`${worker.url}/gateway`));
71 const second = layers(yield* getText(`${worker.url}/gateway`));
72 expect(first).toHaveLength(2);
73 expect(second).toHaveLength(2);
74 expect(second![0]).not.toEqual(first![0]);
75 expect(second![1]).not.toEqual(first![1]);
76​
77 yield* stack.destroy();
78 }).pipe(logLevel),
79 {
80 tags: ["provider:cloudflare", "provider:cloudflare:worker", "local"],
81 timeout: 120_000,
82 },
83);