npm package: @revas-hq/kit-http-react-router
Description: This package provides adapter functions and default implementations to integrate the Revas Kit's endpoint and HTTP transport layers (`@revas-hq/kit-endpoint`, `@revas-hq/kit-http`) seamlessly with React Router V6/V7 loaders and actions.
Latest version: 0.0.16

# Revas Kit: HTTP React Router Adapter (`@revas-hq/kit-http-react-router`)

This package provides adapter functions and default implementations to integrate the Revas Kit's endpoint and HTTP transport layers (`@revas-hq/kit-endpoint`, `@revas-hq/kit-http`) seamlessly with React Router V6/V7 loaders and actions.

It offers `createLoader` and `createAction` factory functions that orchestrate the Revas Kit HTTP request lifecycle within the context of a React Router request handler.

## Installation

```bash
npm install @revas-hq/kit-http-react-router @revas-hq/kit-http @revas-hq/kit-endpoint @revas-hq/kit-context react-router
# or
yarn add @revas-hq/kit-http-react-router @revas-hq/kit-http @revas-hq/kit-endpoint @revas-hq/kit-context react-router
```

## Features

- **createLoader / createAction Factories**: Generate React Router compatible loader/action functions from Revas Kit configuration.
- **Lifecycle Orchestration**: Automatically manages the sequence: RequestFunctions -> DecodeRequestFunction -> Endpoint -> ResponseFunctions -> EncodeResponseFunction.
- **Error Handling**: Catches errors from any stage and uses a configurable EncodeErrorFunction to generate the final error Response.
- **Default Handlers**: Provides sensible defaults for common React Router use cases:
  - `encodeResponse`: Handles JSON data (`json()`), redirects (`redirect()`), and existing Response objects.
  - `panicEncodeError`: Re-throws errors to let React Router's ErrorBoundary handle them.
  - `noopDecodeRequest`: A decoder that does nothing, useful when no request body/param parsing is needed.
- **Context Management**: Creates and manages the Revas Kit Context internally.
- **Parameter Merging**: Merges React Router route parameters (`params`) into `URLSearchParams` for easy access in decoders/request functions.
- **OpenTelemetry Integration**: Includes basic tracing spans for the handler execution.

## Usage

### 1. Configuration (main.ts or Setup File)

Define your endpoints, decoders, and middleware, then use `createLoader` or `createAction` to build the final handler functions. Register these handlers in your service container (if using one).

```ts
// ~/main.ts (Example Setup)

import { createServiceContainer, ServiceContainer } from '@revas-hq/kit-service-container';
import type { Endpoint } from '@revas-hq/kit-endpoint';
import type { DecodeRequestFunction } from '@revas-hq/kit-http';
import { createLoader, createAction } from '@revas-hq/kit-http-react-router';
import { captureAuthorizationHeader, createAuthorizeMiddleware, createAuthorizationHeaderTokenSource } from '@revas-hq/kit-auth';
import type { LoaderFunctionArgs, ActionFunctionArgs } from 'react-router-dom';

// Define types for handlers stored in container
type ReactRouterLoader = (args: LoaderFunctionArgs) => Promise<unknown>;
type ReactRouterAction = (args: ActionFunctionArgs) => Promise<unknown>;

// Example Endpoint, Decoder, Auth setup...
interface MyRequest { id: string; }
interface MyResponse { data: string; }
const myEndpoint: Endpoint<MyRequest, MyResponse> = /* ... endpoint logic ... */;
const myDecoder: DecodeRequestFunction<MyRequest> = /* ... decoder logic ... */;
const tokenSource = createAuthorizationHeaderTokenSource();
const authorize = createAuthorizeMiddleware(tokenSource);

async function initializeContainer(): Promise<ServiceContainer> {
    const container = createServiceContainer();

    // Wrap endpoint with middleware
    const authorizedEndpoint = authorize(myEndpoint);

    // Create loader function using the factory
    const myLoaderFunc = createLoader({
        endpoint: authorizedEndpoint,
        decodeRequest: myDecoder,
        beforeFunctions: [captureAuthorizationHeader], // Runs before decode
        // Uses default encodeResponse and panicEncodeError
    });

    // Register the created loader function
    container.register<ReactRouterLoader>('loader:myResource', myLoaderFunc);

    // Similarly for actions using createAction(...)
    // const myActionFunc = createAction({ ... });
    // container.register<ReactRouterAction>('action:myResource', myActionFunc);

    return container;
}

// Export singleton container accessor
export const container: () => Promise<ServiceContainer> = /* ... singleton logic ... */;
```

### 2. Usage in Route File (*.tsx)

Import the container, resolve the specific loader/action function by key, and export it for React Router.

```tsx
// routes/my-resource.tsx (Example)

import * as React from 'react';
import { useLoaderData } from 'react-router-dom';
import type { LoaderFunctionArgs } from 'react-router-dom';
import { container } from '~/main'; // Import container accessor

// Define expected loader data type
interface LoaderData { data: string; }

// Export the loader function for React Router
export async function loader(args: LoaderFunctionArgs): Promise<unknown> {
    const appContainer = await container();
    // Resolve the handler created in main.ts
    const handler = appContainer.resolve<(args: LoaderFunctionArgs) => Promise<unknown>>('loader:myResource');
    // Execute the handler - it runs the full Revas Kit lifecycle
    return handler(args);
}

// --- React Component ---
export default function MyResourcePage() {
    const data = useLoaderData() as LoaderData;
    return <div>Data: {data.data}</div>;
}

// Similarly for actions: export async function action(...) and resolve/call the action handler.
```

## Default Handlers

You can override the default behaviors by providing your own functions in the `CreateHandlerFunctionArgs`:

- `encodeResponse`: Provide a custom `EncodeResponseFunction` (from kit-http).
- `encodeError`: Provide a custom `EncodeErrorFunction` (from kit-http) to format error responses differently (e.g., specific JSON structure).
- `decodeRequest`: Provide your specific `DecodeRequestFunction` (from kit-http).
- `beforeFunctions`: An array of `RequestFunctions` (from kit-http).
- `afterFunctions`: An array of `ResponseFunctions` (from kit-http).

See `@revas-hq/kit-http` for the signatures of these functions.

## License

This project is licensed under the MIT License. See the LICENSE file for details.