Effect CommunityEC
Effect Community16mo ago
15 replies
Pivel

Implementing Vite Dev Server Middleware in an Effect Http App

Since I haven't found any example on how to use an express (connect) middleware (vite dev server for example) inside an Effect Http app, I have decided to create my own. It's a bit dirty but it works and since the middleware is only really applied in dev mode, any side effects are kept local.

class MiddlewareError extends Data.TaggedError("MiddlewareError")<{
  message: string;
}> {}

const viteMiddleware = HttpMiddleware.make((app) =>
  Effect.gen(function* () {
    if (!viteDevServer) return yield* app;

    const request = yield* HttpServerRequest.HttpServerRequest;
    const req = NodeHttpServerRequest.toIncomingMessage(request);
    const res = NodeHttpServerRequest.toServerResponse(request);

    return yield* Effect.async<
      Effect.Effect.Success<typeof app>,
      Effect.Effect.Error<typeof app> | MiddlewareError,
      Effect.Effect.Context<typeof app>
    >((resume) => {
      const listener = () => {
        resume(
          Effect.succeed(
            HttpServerResponse.raw(null, {
              status: res.statusCode,
              statusText: res.statusMessage,
            }),
          ),
        );
      };

      res.once("finish", listener);

      const next = (err?: any) => {
        if (err) {
          return resume(
            Effect.fail(new MiddlewareError({ message: String(err) })),
          );
        }

        res.off("finish", listener);

        return resume(app);
      };

      viteDevServer.middlewares(req, res, next);
    });
  }),
);
Was this page helpful?