API reference

Application

Effront アプリケーションとサービスの定義に使う API のリファレンス。

@effront/core の Application は、ルートとサービス Layer をまとめ、配信を担うホストとは独立したアプリケーション定義を作ります。

アプリケーション定義の例

import { Application } from "@effront/core";
import { Effect } from "effect";

const EFFRONT = Application.effront();
const RootLayout = EFFRONT.Layout.make({
  render: ({ children }) =>
    Effect.succeed(
      <html lang="en">
        <head>
          <title>Example</title>
        </head>
        <body>{children}</body>
      </html>,
    ),
});
const Home = EFFRONT.Page.make({
  render: () => Effect.succeed(<h1>Home</h1>),
});

export default EFFRONT.make({
  routes: EFFRONT.Routes.make({ layout: RootLayout }).page("/", Home),
});

この定義は / を Home に対応させますが、サーバーは起動しません。 ホストアダプター が定義を受け取って配信します。

Application.effront

Application.effront<Services = never>() は実行時の引数を取らず、EFFRONT ファクトリーを返します。 Services はアプリケーション Layer が提供するサービスを宣言します。

定義を複数のモジュールに分ける場合は、共有するファクトリーを一つ公開します。

import { Application } from "@effront/core";

export const EFFRONT = Application.effront();

サービスの型が同じでも、呼び出しごとに異なる ID が作られます。 異なる ID の Routes、Page、Layout、Loading、Middleware を混在させると TypeError が発生します。 ファクトリーには、描画用ファクトリー、Routes と Middleware、ServerFn があります。

EFFRONT.make

EFFRONT.make({ routes, layer? }) は ApplicationDefinition<Services, ApplicationError, Requirements> を返します。

オプション契約
routes同じ ID の Routes。ルート直下に Layout があり、ツリーに Page が一つ以上必要。子の Layout だけでは不十分。
layerLayer.Layer<Services, ApplicationError, HttpRouter.HttpRouter | Requirements>。Services が never でない限り必須。省略時は Layer.empty。

ApplicationError は Layer 構築時のエラー型です。 Requirements は外部サービスの要件を保持します。 HTTP ハンドラーが HttpRouter.HttpRouter を提供するため、Services が never でも Layer で独自 HTTP ルートを登録できます。

make が推論した定義からサービス型と外部要件型を取り出すには、@effront/core の ApplicationServices<Application> と ApplicationRequirements<Application> を使います。 ApplicationRequirements はランタイムが所有する HttpRouter.HttpRouter の要件を除外します。

import type { ApplicationRequirements, ApplicationServices } from "@effront/core";
import application from "./entry.effront";

type Services = ApplicationServices<typeof application>;
type HostRequirements = ApplicationRequirements<typeof application>;

Layer の取得は make の呼び出し時ではなく、リクエストごとに行います。 ホストはレスポンス本文の完了、失敗、キャンセルまでリクエスト Scope を保持する必要があります。

ネイティブ HTTP は、ホストが提供する外部サービスの要件を保持します。 Workers Fetch は、HttpRouter と HttpServerRequest で満たせる要件だけを受け付けます。 makeHttpEffect と Alchemy アダプター は、ホスト所有のサービス参照を捕捉できますが、サービスの寿命は延長しません。

EFFRONT.withMiddleware

EFFRONT.withMiddleware(middleware) は、元と同じ ID と make 関数を持つ派生ファクトリーを返します。 元のファクトリーは変更しません。 派生ファクトリーでは、ミドルウェアが提供するサービスも利用できます。

派生ファクトリーで作る定義ミドルウェアの動作
Routesルートグループでミドルウェアを有効にする。
Page、Layout、Component有効なミドルウェアスコープを必要とする。自身では有効にしない。
ServerFn呼び出し時に保持したミドルウェアチェーンを適用する。

ミドルウェアは同じ ID を持ち、その依存サービスがファクトリーから利用可能である必要があります。 別の ID のミドルウェアや、同じチェーンでの重複は TypeError になります。 ハンドラーの入力と実行順序は Routes と Middleware を参照してください。