/// import type { RequestHandler } from '../src/react_router_adapter.js' import { HttpContext } from '@adonisjs/core/http' import type { ApplicationService } from '@adonisjs/core/types' import { RouterContextProvider } from 'react-router' import '../src/types/main.js' declare module '@adonisjs/core/types' { interface ContainerBindings { reactRouter: Promise } } declare module '@adonisjs/core/http' { interface HttpContext { reactRouterHandler: () => Promise } } export default class ReactRouterProvider { static needsApplication = true private reactRouterBundle: string constructor(protected app: ApplicationService) { this.reactRouterBundle = app.makeURL('react-router/server/server.js').href } async boot() { const { createRequestHandler } = await import('../src/react_router_adapter.js') const env = this.app.getEnvironment() if (env !== 'web' && env !== 'test') { return } const vite = await this.app.container.make('vite') const devServer = vite.getDevServer() const build = (this.app.inDev || this.app.inTest) && devServer ? () => devServer.ssrLoadModule('virtual:react-router/server-build') : await import(this.reactRouterBundle) const requestHandler = createRequestHandler({ build, getLoadContext: (context) => { const ctx = new RouterContextProvider() // avoid breaking changes by using the migration strategy from https://reactrouter.com/how-to/middleware#migration-from-apploadcontext Object.assign(ctx, { http: context.http, make: context.container.make.bind(context.container), }) return ctx }, }) const app = this.app HttpContext.getter( 'reactRouterHandler', function (this: HttpContext) { return () => requestHandler({ http: this, container: app.container, }) }, false ) } }