react-router-effect 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +286 -108
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +4 -3
- package/dist/{route-data-MgSnnR33.d.mts → route-data-CWBxnNAA.d.mts} +7 -1
- package/dist/server.d.mts +140 -74
- package/dist/server.mjs +286 -140
- package/dist/vite.d.mts +35 -14
- package/dist/vite.mjs +47 -13
- package/package.json +12 -7
- package/src/assets.ts +212 -0
- package/src/check.ts +8 -0
- package/src/factory.ts +20 -10
- package/src/server-entry.ts +2 -1
- package/src/server.ts +307 -295
- package/src/vite.ts +109 -32
package/dist/server.d.mts
CHANGED
|
@@ -1,55 +1,111 @@
|
|
|
1
|
-
import { C as ReturnableDataError, _ as NameError, a as RegisteredMeta, g as LibraryHandled, h as IsAny, m as FailureResponse, o as RegisteredRecover, p as FactoryTypes, y as RouteHandlers } from "./route-data-
|
|
2
|
-
import {
|
|
3
|
-
import { Register, ServerBuild } from "react-router";
|
|
4
|
-
import { HttpPlatform, HttpServerError, HttpServerRequest, HttpServerResponse } from "effect/http";
|
|
5
|
-
declare namespace server_d_exports {
|
|
6
|
-
export { App, BuildSource, ClientAssetServices, ClientBuildError, Options, make };
|
|
7
|
-
}
|
|
1
|
+
import { C as ReturnableDataError, _ as NameError, a as RegisteredMeta, g as LibraryHandled, h as IsAny, m as FailureResponse, o as RegisteredRecover, p as FactoryTypes, y as RouteHandlers } from "./route-data-CWBxnNAA.mjs";
|
|
2
|
+
import { Context, Effect, FileSystem, Layer, Option, Path, Scope } from "effect";
|
|
3
|
+
import { Register, RouterContextProvider, ServerBuild } from "react-router";
|
|
4
|
+
import { HttpPlatform, HttpRouter, HttpServerError, HttpServerRequest, HttpServerResponse } from "effect/http";
|
|
8
5
|
/** A React Router server build, or a function that loads it, as in `createRequestHandler`. */
|
|
9
6
|
type BuildSource = ServerBuild | (() => ServerBuild | Promise<ServerBuild>);
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
};
|
|
18
|
-
/** React Router's server mode. Defaults to `process.env.NODE_ENV`. */
|
|
19
|
-
readonly mode?: string | undefined;
|
|
7
|
+
declare const ReactRouter_base: Context.ServiceClass<ReactRouter, "react-router-effect/ReactRouter", {
|
|
8
|
+
/**
|
|
9
|
+
* The build, when the layer loaded it once at startup: a build value, or
|
|
10
|
+
* a build function in production mode. `None` when the build loads for
|
|
11
|
+
* each request.
|
|
12
|
+
*/
|
|
13
|
+
readonly build: Option.Option<ServerBuild>;
|
|
20
14
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* hashed names and are cached for a year as immutable, other files for an
|
|
24
|
-
* hour. It serves like `express.static`: a directory serves its index file,
|
|
25
|
-
* such as a prerendered page, its path without the trailing slash redirects
|
|
26
|
-
* to the path with it, dotfiles are not served, and a request it does not
|
|
27
|
-
* serve goes to React Router. Like `express.static`, it looks each GET and
|
|
28
|
-
* HEAD request up in the file system. It serves only a build that it loads
|
|
29
|
-
* once: in production mode, or a build value. A
|
|
30
|
-
* development build is never served, since Vite serves the client there, nor
|
|
31
|
-
* is a `publicPath` on another origin. Making the app fails with a
|
|
32
|
-
* {@link ClientBuildError} when it cannot read the directory. Needs the
|
|
33
|
-
* platform's file system, which `NodeHttpServer.layer` and the other server
|
|
34
|
-
* layers provide.
|
|
15
|
+
* Answers the current request with React Router. The Scope is the
|
|
16
|
+
* request's scope: the resources that `loadContext` opens close with it.
|
|
35
17
|
*/
|
|
36
|
-
readonly
|
|
18
|
+
readonly handle: Effect.Effect<HttpServerResponse.HttpServerResponse, HttpServerError.RequestError, HttpServerRequest.HttpServerRequest | Scope.Scope>;
|
|
19
|
+
}>;
|
|
20
|
+
/**
|
|
21
|
+
* React Router, as a service of the Effect HTTP app. `ReactRouter.layer`
|
|
22
|
+
* provides it, and `ReactRouter.routes` registers it on the app's router as
|
|
23
|
+
* the catch-all route.
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* export const App = ReactRouter.routes.pipe(
|
|
27
|
+
* Layer.provide(
|
|
28
|
+
* ReactRouter.layer({
|
|
29
|
+
* build: () => import("virtual:react-router/server-build"),
|
|
30
|
+
* factory: routeFactory,
|
|
31
|
+
* mode: import.meta.env.MODE,
|
|
32
|
+
* }),
|
|
33
|
+
* ),
|
|
34
|
+
* );
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @stability unstable
|
|
38
|
+
*/
|
|
39
|
+
export declare class ReactRouter extends ReactRouter_base {
|
|
40
|
+
/**
|
|
41
|
+
* Provides React Router. A build value, or a build function in production
|
|
42
|
+
* mode, loads when the layer builds. Provide one value of this layer to
|
|
43
|
+
* every layer that reads the service: two values load the build twice.
|
|
44
|
+
*
|
|
45
|
+
* @stability unstable
|
|
46
|
+
*/
|
|
47
|
+
static readonly layer: <R = never>(options: ReactRouter.Options<R>) => Layer.Layer<ReactRouter, never, Exclude<R, Scope.Scope>>;
|
|
48
|
+
/**
|
|
49
|
+
* Registers React Router as the catch-all route of the app's router, on
|
|
50
|
+
* `*`, for every method of `HttpMethod.all` but HEAD. A route that the app
|
|
51
|
+
* registers itself wins over it, also a route on `/`, such as the
|
|
52
|
+
* prerendered home page of `ReactRouterAssets.layer`. A HEAD request uses
|
|
53
|
+
* the GET route of its path, React Router's or the app's own, as Express
|
|
54
|
+
* does. A method outside `HttpMethod.all` gets the router's 404. Register
|
|
55
|
+
* it at the root of the router: under a prefix, React Router does not get
|
|
56
|
+
* the path that it expects.
|
|
57
|
+
*
|
|
58
|
+
* @stability unstable
|
|
59
|
+
*/
|
|
60
|
+
static readonly routes: Layer.Layer<never, never, HttpRouter.HttpRouter | ReactRouter | HttpRouter.Request<"Error", HttpServerError.InternalError> | HttpRouter.Request<"Error", HttpServerError.RequestParseError> | HttpRouter.Request<"Error", HttpServerError.RouteNotFound>>;
|
|
61
|
+
}
|
|
62
|
+
export declare namespace ReactRouter {
|
|
37
63
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
64
|
+
* The options of {@link ReactRouter.layer}. `R` is the requirement of `loadContext`.
|
|
65
|
+
*
|
|
66
|
+
* @stability unstable
|
|
41
67
|
*/
|
|
42
|
-
|
|
68
|
+
interface Options<R = never> {
|
|
69
|
+
/** The server build: `() => import("virtual:react-router/server-build")`. */
|
|
70
|
+
readonly build: BuildSource;
|
|
71
|
+
/** The route factory whose runner, runtime and error model route Effects use. */
|
|
72
|
+
readonly factory: {
|
|
73
|
+
readonly handlers: RouteHandlers;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* React Router's server mode, such as `import.meta.env.MODE` in a Vite
|
|
77
|
+
* app. React Router runs in production mode for any mode but
|
|
78
|
+
* `development` and `test`, and so does the layer: it loads a build
|
|
79
|
+
* function for each request only in those two modes.
|
|
80
|
+
*/
|
|
81
|
+
readonly mode: "development" | "production" | "test" | (string & {});
|
|
82
|
+
/**
|
|
83
|
+
* Makes React Router's load context for each request, as `getLoadContext`
|
|
84
|
+
* does for `@react-router/express`. Plain loaders and actions, and
|
|
85
|
+
* `handleRequest` in `entry.server.tsx`, read its values with
|
|
86
|
+
* `context.get`. Route Effects read services from their Effect context,
|
|
87
|
+
* so an app gives them services with router middleware, not here. The
|
|
88
|
+
* adapter adds its own keys to the provider. The Effect gets the services
|
|
89
|
+
* of `R` from the layer, and the services of the request, which win over
|
|
90
|
+
* the services of the layer. A defect answers an empty 500.
|
|
91
|
+
*/
|
|
92
|
+
readonly loadContext?: ((request: HttpServerRequest.HttpServerRequest) => Effect.Effect<RouterContextProvider, never, R>) | undefined;
|
|
93
|
+
}
|
|
43
94
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
95
|
+
declare namespace assets_d_exports {
|
|
96
|
+
export { ClientBuildError, layer };
|
|
97
|
+
}
|
|
98
|
+
declare const ClientBuildError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
47
99
|
readonly _tag: "ClientBuildError";
|
|
48
100
|
} & Readonly<A>;
|
|
49
101
|
/**
|
|
50
|
-
* The
|
|
51
|
-
*
|
|
52
|
-
*
|
|
102
|
+
* The layer cannot serve the client build: it cannot read the directory, or
|
|
103
|
+
* a file name has a `*`, which the router cannot match. The build's
|
|
104
|
+
* `assetsBuildDirectory` is relative to the working directory of the server,
|
|
105
|
+
* so `directory` is the path that it resolved to.
|
|
106
|
+
*
|
|
107
|
+
* @stability unstable
|
|
108
|
+
* @since 2.2.0
|
|
53
109
|
*/
|
|
54
110
|
declare class ClientBuildError extends ClientBuildError_base<{
|
|
55
111
|
readonly message: string;
|
|
@@ -57,44 +113,46 @@ declare class ClientBuildError extends ClientBuildError_base<{
|
|
|
57
113
|
readonly directory: string;
|
|
58
114
|
readonly cause: unknown;
|
|
59
115
|
}> {}
|
|
60
|
-
/** True when the options serve the client build. */
|
|
61
|
-
type ServesClientAssets<O> = O extends {
|
|
62
|
-
readonly clientAssets: infer Serves;
|
|
63
|
-
} ? [Serves] extends [false | undefined] ? false : true : false;
|
|
64
|
-
/**
|
|
65
|
-
* The Effect HTTP app {@link make} makes. Serving the client build adds the
|
|
66
|
-
* static file server's errors to its errors.
|
|
67
|
-
*/
|
|
68
|
-
type App<O extends Options> = Effect.Effect<HttpServerResponse.HttpServerResponse, HttpServerError.RequestError | (ServesClientAssets<O> extends true ? HttpServerError.HttpServerError : never), HttpServerRequest.HttpServerRequest>;
|
|
69
116
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* `clientAssets` it reads the client build's directory, so a missing one fails
|
|
73
|
-
* the server's start with a {@link ClientBuildError} and not its requests.
|
|
117
|
+
* Registers the routes of the client build on the app's router, for GET and
|
|
118
|
+
* HEAD, under the build's `publicPath`.
|
|
74
119
|
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
120
|
+
* The hashed directory is the directory of the build's manifest URL, such as
|
|
121
|
+
* `/assets`. The build plugin writes the files with a content hash in their
|
|
122
|
+
* names there. Its files are cached for a year as immutable, and a request
|
|
123
|
+
* under it for a file that the directory does not have gets a 404. The
|
|
124
|
+
* files are served from that directory only, so a path with `..` does not
|
|
125
|
+
* reach the other files of the client build.
|
|
77
126
|
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
127
|
+
* Each other file gets its own route, and is cached for an hour. A directory
|
|
128
|
+
* with an `index.html`, such as a prerendered page, gets a route that serves
|
|
129
|
+
* its `index.html`, and its path without the trailing slash redirects. The
|
|
130
|
+
* layer serves no path with a segment that starts with a dot, such as
|
|
131
|
+
* `.vite/`, as `express.static` ignores dotfiles. A root `index.html`, such
|
|
132
|
+
* as a prerendered home page, gets the route `/`, which wins over the
|
|
133
|
+
* catch-all of `ReactRouter.routes`. Any other request goes on to the app's
|
|
134
|
+
* other routes.
|
|
83
135
|
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
136
|
+
* The layer reads the client build when it builds, so a file that something
|
|
137
|
+
* adds outside the hashed directory later is served after a restart. It
|
|
138
|
+
* fails with a {@link ClientBuildError} when it cannot read the client build
|
|
139
|
+
* directory, or when a file name has a `*`, which the router cannot match.
|
|
140
|
+
* A route of the app with the path of a file fails the server's start.
|
|
141
|
+
*
|
|
142
|
+
* The layer registers nothing for a build that loads for each request, such
|
|
143
|
+
* as a development build, since Vite serves the client there. It also
|
|
144
|
+
* registers nothing for a `publicPath` on another origin.
|
|
89
145
|
*
|
|
90
|
-
*
|
|
91
|
-
* request
|
|
146
|
+
* The routes of this layer get the middleware that the app provides to this
|
|
147
|
+
* layer. To leave the server's request logger out of file requests:
|
|
92
148
|
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
149
|
+
* ```ts
|
|
150
|
+
* ReactRouterAssets.layer.pipe(Layer.provide(HttpRouter.disableLogger))
|
|
151
|
+
* ```
|
|
152
|
+
*
|
|
153
|
+
* @stability unstable
|
|
96
154
|
*/
|
|
97
|
-
declare const
|
|
155
|
+
declare const layer: Layer.Layer<never, ClientBuildError, HttpRouter.HttpRouter | ReactRouter | FileSystem.FileSystem | Path.Path | HttpPlatform.HttpPlatform>;
|
|
98
156
|
/** The route modules React Router's typegen registers, keyed by route ID. */
|
|
99
157
|
type RegisteredRouteModules = Register extends {
|
|
100
158
|
readonly routeModules: infer Modules;
|
|
@@ -112,6 +170,8 @@ type FailureMessage = "This route Effect can fail with an error the route factor
|
|
|
112
170
|
*
|
|
113
171
|
* It is an inline object type, not an interface, so the compiler prints its
|
|
114
172
|
* fields in the error rather than an alias name.
|
|
173
|
+
*
|
|
174
|
+
* @stability unstable
|
|
115
175
|
*/
|
|
116
176
|
type RouteEffectFailure<Route, Export, Unhandled, Missing, Invalid> = {
|
|
117
177
|
readonly "react-router-effect": FailureMessage;
|
|
@@ -158,6 +218,8 @@ type SameType<A, B> = [A] extends [B] ? ([B] extends [A] ? true : false) : false
|
|
|
158
218
|
/**
|
|
159
219
|
* A disagreement between the `Register` of `react-router-effect` and the
|
|
160
220
|
* factory, which would type plain Effect routes' data wrongly.
|
|
221
|
+
*
|
|
222
|
+
* @stability unstable
|
|
161
223
|
*/
|
|
162
224
|
interface RegisterMismatch<Key, Factory, Registered> {
|
|
163
225
|
readonly register: Key;
|
|
@@ -172,6 +234,8 @@ type Failures<Modules, Types> = Types extends FactoryTypes<infer DomainError, in
|
|
|
172
234
|
* The failures of every Effect route function across the route modules React
|
|
173
235
|
* Router's typegen registers, and the registration mismatches, as objects.
|
|
174
236
|
* `never` when everything is handled. `RouteEffectCheck` reports them.
|
|
237
|
+
*
|
|
238
|
+
* @stability unstable
|
|
175
239
|
*/
|
|
176
240
|
type RouteEffectFailures<Factory, Modules = RegisteredRouteModules> = Failures<Modules, TypesOf<Factory>>;
|
|
177
241
|
/** A printable name for an error tag or another unhandled error type. */
|
|
@@ -213,6 +277,8 @@ type FailureLines<Failure> = Failure extends {
|
|
|
213
277
|
* factory's runtime and request context. A middleware may also fail with what
|
|
214
278
|
* its `next()` fails with. The check also fails when the `Register` of
|
|
215
279
|
* `react-router-effect` disagrees with the factory.
|
|
280
|
+
*
|
|
281
|
+
* @stability unstable
|
|
216
282
|
*/
|
|
217
283
|
type RouteEffectCheck<Factory, Modules = RegisteredRouteModules> = { readonly [Line in FailureLines<RouteEffectFailures<Factory, Modules>>]: Line; };
|
|
218
|
-
export {
|
|
284
|
+
export { assets_d_exports as ReactRouterAssets, type RegisterMismatch, type RouteEffectCheck, type RouteEffectFailure, type RouteEffectFailures };
|