@rivetjs/router 0.1.0-alpha.0 → 0.1.0-alpha.1
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/adapters/files.d.ts +13 -0
- package/adapters/files.js +58 -6
- package/adapters/node.d.ts +22 -5
- package/adapters/node.js +113 -67
- package/adapters/static.js +1 -1
- package/adapters/target-build.d.ts +5 -2
- package/adapters/vercel.d.ts +4 -2
- package/adapters/vercel.js +1 -1
- package/build/codegen.d.ts +13 -0
- package/build/codegen.js +152 -35
- package/build/dev-errors.d.ts +6 -2
- package/build/dev-errors.js +15 -4
- package/build/lazy-rows.d.ts +19 -0
- package/build/lazy-rows.js +59 -0
- package/build/migrate.d.ts +20 -4
- package/build/migrate.js +300 -61
- package/build/reach.d.ts +60 -0
- package/build/reach.js +302 -0
- package/build/routes.d.ts +9 -4
- package/build/routes.js +30 -13
- package/build/vite.d.ts +13 -0
- package/build/vite.js +165 -7
- package/cli/rivet.js +3 -2
- package/client/dev.js +17 -0
- package/client/index.d.ts +4 -0
- package/client/index.js +34 -0
- package/client/route-context.d.ts +1 -1
- package/index.d.ts +22 -25
- package/index.js +2 -1
- package/package.json +4 -4
- package/server/app.d.ts +7 -1
- package/server/app.js +38 -5
- package/server/deferred.d.ts +12 -0
- package/server/deferred.js +60 -0
- package/server/handler.d.ts +56 -12
- package/server/handler.js +46 -8
- package/server/index.d.ts +1 -1
- package/server/module.d.ts +7 -7
- package/server/module.js +52 -34
- package/server/render.d.ts +2 -0
- package/server/render.js +3 -0
- package/server/route-cache.d.ts +74 -4
- package/server/route-cache.js +77 -6
- package/server/shell-build.d.ts +3 -0
- package/server/shell-build.js +2 -0
- package/server/shell-cache.d.ts +8 -0
- package/server/shell-cache.js +836 -0
- package/shared/server-exports.d.ts +78 -0
- package/shared/server-exports.js +77 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { RequestEvent } from "../server/handler.js";
|
|
2
|
+
import type { RouteId } from "../index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Tag key of a server export: an own non-enumerable property whose value is the kind. `Symbol.for`
|
|
5
|
+
* (not a module-local registry): route modules and the server bundle's router may be different
|
|
6
|
+
* module instances.
|
|
7
|
+
*/
|
|
8
|
+
export declare const SERVER_EXPORT: unique symbol;
|
|
9
|
+
/** What a server export is: the name of the wrapper that made it. */
|
|
10
|
+
export type ServerKind = "load" | "guard" | "actions" | "entries" | "headers" | "onRequest" | "onGet" | "onPost" | "onPut" | "onPatch" | "onDelete" | "onOptions";
|
|
11
|
+
/** A value tagged as a server export of kind `K` (still callable / usable as `V`). */
|
|
12
|
+
export type ServerExport<K extends ServerKind, V> = V & {
|
|
13
|
+
readonly [SERVER_EXPORT]: K;
|
|
14
|
+
};
|
|
15
|
+
type Params = Record<string, string> | RouteId;
|
|
16
|
+
/** Request handler result: a `Response` ends the request; `undefined` continues; an `HttpError` is thrown or returned. */
|
|
17
|
+
type HandlerResult = Response | undefined | void | Promise<Response | undefined | void>;
|
|
18
|
+
type ActionFn = {
|
|
19
|
+
bivariance(event: RequestEvent): unknown;
|
|
20
|
+
}["bivariance"];
|
|
21
|
+
/**
|
|
22
|
+
* Marks a deferred loader (`load(fn, { defer: true })`): an own non-enumerable property of the wrapped function. The
|
|
23
|
+
* handler starts it with the request and renders without awaiting it (`server/deferred.ts`).
|
|
24
|
+
*/
|
|
25
|
+
export declare const DEFER: unique symbol;
|
|
26
|
+
declare const deferred: unique symbol;
|
|
27
|
+
/**
|
|
28
|
+
* The data of a deferred loader (`load(fn, { defer: true })`): a handle the page renders through a boundary —
|
|
29
|
+
* `<Async load={() => data}>` / `resource(() => data)` — while the shell streams without waiting for it. On the server
|
|
30
|
+
* it follows this request's run of the loader (started with the request); after a client navigation (the data
|
|
31
|
+
* endpoint awaits deferred loaders) the slot holds the resolved value itself, which boundaries take as it is. Reading
|
|
32
|
+
* it directly (`data.title`) is a bug: dev throws `DeferredDataError`.
|
|
33
|
+
*/
|
|
34
|
+
export interface Deferred<T> extends PromiseLike<T> {
|
|
35
|
+
readonly [deferred]: T;
|
|
36
|
+
}
|
|
37
|
+
/** Options of `load(fn, options)`. */
|
|
38
|
+
export interface LoadOptions {
|
|
39
|
+
/**
|
|
40
|
+
* Start the loader with the request but do not wait for it before rendering: the page's (layout's) `data` is a
|
|
41
|
+
* `Deferred<T>`, rendered through `<Async load={() => data}>` / `resource(() => data)`; the response streams the
|
|
42
|
+
* shell first and the boundary's content when the loader settles. Client navigations (`?_rivet=data`) get the
|
|
43
|
+
* resolved value. A deferred loader cannot set headers or cookies (TypeError: the response head is already out).
|
|
44
|
+
*/
|
|
45
|
+
readonly defer?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/** Loader: data for the page / layout (`data` prop; `PageProps<typeof loader>`). Runs on the server only. */
|
|
48
|
+
export declare function load<T, P extends Params = Record<string, string>>(fn: (event: RequestEvent<P>) => T, options?: LoadOptions & {
|
|
49
|
+
readonly defer?: false;
|
|
50
|
+
}): ServerExport<"load", (event: RequestEvent<P>) => T>;
|
|
51
|
+
/** Deferred loader (`{ defer: true }`): the data is a `Deferred<T>` the page renders through a boundary. */
|
|
52
|
+
export declare function load<T, P extends Params = Record<string, string>>(fn: (event: RequestEvent<P>) => T, options: LoadOptions & {
|
|
53
|
+
readonly defer: true;
|
|
54
|
+
}): ServerExport<"load", (event: RequestEvent<P>) => Deferred<Awaited<T>>>;
|
|
55
|
+
/** Guard: runs outer → inner before loaders and actions; return a `Response` / throw `redirect()` / `deny()` to stop. */
|
|
56
|
+
export declare function guard<T, P extends Params = Record<string, string>>(fn: (event: RequestEvent<P>) => T): ServerExport<"guard", (event: RequestEvent<P>) => T>;
|
|
57
|
+
/** Form actions (`POST ?/name`): `{ name: (event) => result }`; `fail(status, data)` for validation errors. */
|
|
58
|
+
export declare function actions<A extends Record<string, ActionFn>>(map: A): ServerExport<"actions", A>;
|
|
59
|
+
/** Params to prerender a dynamic route (static builds): one object of param values per page (optional params may be absent). */
|
|
60
|
+
export declare function entries<T extends Iterable<object> | Promise<Iterable<object>>>(fn: () => T): ServerExport<"entries", () => T>;
|
|
61
|
+
/** Response headers of the route (`HeadersInit`), after the guards. */
|
|
62
|
+
export declare function headers<P extends Params = Record<string, string>>(fn: (event: RequestEvent<P>) => HeadersInit | undefined): ServerExport<"headers", (event: RequestEvent<P>) => HeadersInit | undefined>;
|
|
63
|
+
type Handler<P extends Params> = (event: RequestEvent<P>) => HandlerResult;
|
|
64
|
+
/** Any method, before guards (outer → inner); a returned `Response` ends the request. */
|
|
65
|
+
export declare function onRequest<P extends Params = Record<string, string>>(fn: Handler<P>): ServerExport<"onRequest", Handler<P>>;
|
|
66
|
+
/** GET / HEAD request handler (endpoint routes: must return the `Response`; pages: middleware before the guards). */
|
|
67
|
+
export declare function onGet<P extends Params = Record<string, string>>(fn: Handler<P>): ServerExport<"onGet", Handler<P>>;
|
|
68
|
+
/** POST request handler (pages: before actions; endpoints: answers). */
|
|
69
|
+
export declare function onPost<P extends Params = Record<string, string>>(fn: Handler<P>): ServerExport<"onPost", Handler<P>>;
|
|
70
|
+
/** PUT request handler. */
|
|
71
|
+
export declare function onPut<P extends Params = Record<string, string>>(fn: Handler<P>): ServerExport<"onPut", Handler<P>>;
|
|
72
|
+
/** PATCH request handler. */
|
|
73
|
+
export declare function onPatch<P extends Params = Record<string, string>>(fn: Handler<P>): ServerExport<"onPatch", Handler<P>>;
|
|
74
|
+
/** DELETE request handler. */
|
|
75
|
+
export declare function onDelete<P extends Params = Record<string, string>>(fn: Handler<P>): ServerExport<"onDelete", Handler<P>>;
|
|
76
|
+
/** OPTIONS (CORS preflight): no CSRF check; nothing answered → `204` + `Allow`. */
|
|
77
|
+
export declare function onOptions<P extends Params = Record<string, string>>(fn: Handler<P>): ServerExport<"onOptions", Handler<P>>;
|
|
78
|
+
export {};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tag key of a server export: an own non-enumerable property whose value is the kind. `Symbol.for`
|
|
3
|
+
* (not a module-local registry): route modules and the server bundle's router may be different
|
|
4
|
+
* module instances.
|
|
5
|
+
*/
|
|
6
|
+
export const SERVER_EXPORT = Symbol.for("rivet.server");
|
|
7
|
+
function tag(kind, value) {
|
|
8
|
+
Object.defineProperty(value, SERVER_EXPORT, { value: kind });
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
// A fresh function per wrapper call: `onGet(h)` and `onPost(h)` with one `h` keep their own kinds.
|
|
12
|
+
function wrap(kind, fn) {
|
|
13
|
+
if (typeof fn !== "function")
|
|
14
|
+
throw new TypeError(`${kind}() expects a function`);
|
|
15
|
+
return tag(kind, fn.bind(undefined));
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Marks a deferred loader (`load(fn, { defer: true })`): an own non-enumerable property of the wrapped function. The
|
|
19
|
+
* handler starts it with the request and renders without awaiting it (`server/deferred.ts`).
|
|
20
|
+
*/
|
|
21
|
+
export const DEFER = Symbol.for("rivet.defer");
|
|
22
|
+
export function load(fn, options) {
|
|
23
|
+
const loader = wrap("load", fn);
|
|
24
|
+
if (options?.defer)
|
|
25
|
+
Object.defineProperty(loader, DEFER, { value: true });
|
|
26
|
+
return loader;
|
|
27
|
+
}
|
|
28
|
+
/** Guard: runs outer → inner before loaders and actions; return a `Response` / throw `redirect()` / `deny()` to stop. */
|
|
29
|
+
export function guard(fn) {
|
|
30
|
+
return wrap("guard", fn);
|
|
31
|
+
}
|
|
32
|
+
/** Form actions (`POST ?/name`): `{ name: (event) => result }`; `fail(status, data)` for validation errors. */
|
|
33
|
+
export function actions(map) {
|
|
34
|
+
if (typeof map !== "object" || map === null)
|
|
35
|
+
throw new TypeError("actions() expects an object of functions");
|
|
36
|
+
const copy = { ...map };
|
|
37
|
+
for (const name of Object.keys(copy))
|
|
38
|
+
if (typeof copy[name] !== "function")
|
|
39
|
+
throw new TypeError(`actions(): \`${name}\` is not a function`);
|
|
40
|
+
return tag("actions", copy);
|
|
41
|
+
}
|
|
42
|
+
/** Params to prerender a dynamic route (static builds): one object of param values per page (optional params may be absent). */
|
|
43
|
+
export function entries(fn) {
|
|
44
|
+
return wrap("entries", fn);
|
|
45
|
+
}
|
|
46
|
+
/** Response headers of the route (`HeadersInit`), after the guards. */
|
|
47
|
+
export function headers(fn) {
|
|
48
|
+
return wrap("headers", fn);
|
|
49
|
+
}
|
|
50
|
+
/** Any method, before guards (outer → inner); a returned `Response` ends the request. */
|
|
51
|
+
export function onRequest(fn) {
|
|
52
|
+
return wrap("onRequest", fn);
|
|
53
|
+
}
|
|
54
|
+
/** GET / HEAD request handler (endpoint routes: must return the `Response`; pages: middleware before the guards). */
|
|
55
|
+
export function onGet(fn) {
|
|
56
|
+
return wrap("onGet", fn);
|
|
57
|
+
}
|
|
58
|
+
/** POST request handler (pages: before actions; endpoints: answers). */
|
|
59
|
+
export function onPost(fn) {
|
|
60
|
+
return wrap("onPost", fn);
|
|
61
|
+
}
|
|
62
|
+
/** PUT request handler. */
|
|
63
|
+
export function onPut(fn) {
|
|
64
|
+
return wrap("onPut", fn);
|
|
65
|
+
}
|
|
66
|
+
/** PATCH request handler. */
|
|
67
|
+
export function onPatch(fn) {
|
|
68
|
+
return wrap("onPatch", fn);
|
|
69
|
+
}
|
|
70
|
+
/** DELETE request handler. */
|
|
71
|
+
export function onDelete(fn) {
|
|
72
|
+
return wrap("onDelete", fn);
|
|
73
|
+
}
|
|
74
|
+
/** OPTIONS (CORS preflight): no CSRF check; nothing answered → `204` + `Allow`. */
|
|
75
|
+
export function onOptions(fn) {
|
|
76
|
+
return wrap("onOptions", fn);
|
|
77
|
+
}
|