ENbext.dev
DocumentationPRISM (natif bext)

Traduction automatique depuis l’anglais. Consulter l’original.

Sur cette page

Conventions de données PRISM

Les itinéraires PRISM sont des composants bext — purs (props) => string (ou Promise<string> pour les pages asynchrones). Ils rendent le côté serveur via Le moteur d'exécution h() de @bext-stack/framework ; il n'y a pas de React, pas de DOM virtuel, pas de cycle de vie côté client. Voir PRISM pour la présentation du framework.

Pour les pages qui nécessitent une récupération de données ou une gestion de mutation côté serveur, PRISM propose les conventions loader et action de style Remix : colocalisez le gestionnaire de données avec le composant dans le même fichier de route, et PRISM l'appelle sur le serveur avant l'exécution du composant.

Anatomie d'une route de données#

tsx
// src/app/posts/[id]/page.tsx

export async function loader({ request, params }: LoaderArgs) {
  const post = await db.post.findUnique({ where: { id: params.id } });
  if (!post) throw new Response("Not Found", { status: 404 });
  return { post };
}

export async function action({ request, params }: ActionArgs) {
  const form = await request.formData();
  await db.post.update({
    where: { id: params.id },
    data: { title: form.get("title") as string },
  });
  return { ok: true };
}

export default function PostPage({ data, actionData }: PageProps) {
  return (
    <article>
      <h1>{data.post.title}</h1>
      {actionData?.ok && <p>Saved.</p>}
      <form method="post">
        <input name="title" defaultValue={data.post.title} />
        <button type="submit">Save</button>
      </form>
    </article>
  );
}

Trois exports depuis le même module :

  • loader — fonctionne pour GET / HEAD. La valeur de retour est transmise comme props.data au composant.
  • action — fonctionne pour POST / PUT / DELETE / PATCH. Valeur de retour est transmis sous la forme props.actionData. PRISM réexécute loader après une action réussie afin que la page s'affiche avec de nouvelles données, correspondant à la sémantique Remix.
  • default — le composant bext (renvoie string ou AsyncIterable<string>).

Règles d'expédition#

Méthode A un chargeur A de l'action Qu'est-ce qui court
GET / HEAD Oui n'importe lequel loader → composant
GET / HEAD Non n'importe lequel composant uniquement
Non-GET n'importe lequel Oui action → loader → composant
Non-GET n'importe lequel Non composant uniquement

La décision se produit dans Rust, avant que le pool de rendu ne soit engagé — voir PrismDataCall::for_request dans crates/bext-core/src/framework/prism_data.rs. Si la route n'exporte aucun gestionnaire, PRISM emprunte le même chemin de code sans données qu'il a toujours ; la convention est strictement additive.

Détection des exportations#

PRISM analyse les fichiers source de route au moment de la construction pour quatre canoniques export shapes:

ts
export async function loader(...) {}
export function loader(...) {}
export const loader = ...
export { loader }

…et les mêmes quatre pour action. Le détecteur est intentionnellement au niveau de la source - pas d'analyseur ESM, juste des correspondances de sous-chaînes - car les fichiers de route sont petits et les faux positifs sont inoffensifs (le temps d'exécution échoue lorsque l'exportation n'existe pas réellement).

Un faux négatif connu : export { something as loader }. Si vous renommez un identifiant dans une liste d'exportation, le détecteur ne le remarquera pas. Utilisez l’une des quatre formes canoniques ci-dessus.

Lancer des réponses#

L’un ou l’autre gestionnaire peut throw new Response(...) pour court-circuiter le rendu. PRISM récupère la réponse lancée et la renvoie textuellement. Utilisez-le pour les 404, les redirections et les portes d'authentification sans polluer le code des composants :

ts
export async function loader({ request }: LoaderArgs) {
  const session = await getSession(request);
  if (!session.user) {
    throw new Response(null, {
      status: 302,
      headers: { Location: "/login" },
    });
  }
  return { user: session.user };
}

TypeScript#

PRISM exporte LoaderArgs, ActionArgs et PageProps depuis @bext-stack/framework. Le générique PageProps déduit data et actionData des types de retour frères loader / action, vous obtenez donc une inférence de bout en bout sans annotations explicites :

ts
import type { LoaderArgs, PageProps } from "@bext-stack/framework";

export async function loader({ params }: LoaderArgs) {
  return { post: await load(params.id) };
}

export default function Page({ data }: PageProps<typeof loader>) {
  // data.post inferred
}
Remarque

Le détecteur d'exportation au niveau source utilise la correspondance de sous-chaînes et non une analyse complète. Le formulaire export { something as loader } est un faux négatif connu : utilisez l'un des quatre codes canoniques. Formes export async function loader / export const loader = … pour assurer la détection.

Mises en garde#

  • Pas encore connecté au pool de rendu. A partir de E7, la détection et la logique de répartition sont actives dans bext-core avec une couverture unitaire, mais le chemin de rendu V8/V8 appelle toujours directement le composant. Le câblage du saut intermédiaire loader / action dans le pool de rendu atterrit dans le suivi E7 - même cadence que la répartition du sous-processus SolidStart.
  • Le JSON renvoyé par l'exécution est sérialisé via JSON.stringify. Date, BigInt et les instances de classe perdront leur type. Le support de Superjson est sur la feuille de route.
  • Aucun routage imbriqué pour l'instant. Dans Remix, les routes parents obtiennent leur Posséder loader. Le routeur du PRISM est plat pour l'instant ; Les chargeurs de route parent arrivent lorsque PRISM développe des mises en page imbriquées au-delà du modèle de mise en page unique actuel.

Documents associés#

Modifier cette page ↗Besoin d’aide ? ↗
Rechercher dans la documentation

Saisissez un sujet, une commande ou une question.