@reckona/mreact-router 0.0.189 → 0.0.191
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 +17 -4
- package/bin/mreact-router.js +23 -0
- package/dist/adapters/aws-lambda.d.ts +33 -13
- package/dist/adapters/aws-lambda.d.ts.map +1 -1
- package/dist/adapters/aws-lambda.js +128 -20
- package/dist/adapters/aws-lambda.js.map +1 -1
- package/dist/adapters/cloudflare.d.ts +18 -0
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js.map +1 -1
- package/dist/adapters/edge.d.ts +2 -0
- package/dist/adapters/edge.d.ts.map +1 -1
- package/dist/adapters/edge.js.map +1 -1
- package/dist/adapters/node.d.ts +16 -2
- package/dist/adapters/node.d.ts.map +1 -1
- package/dist/adapters/node.js.map +1 -1
- package/dist/build.d.ts +6 -0
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +57 -12
- package/dist/build.js.map +1 -1
- package/dist/cache.d.ts +8 -0
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +34 -13
- package/dist/cache.js.map +1 -1
- package/dist/cli-options.d.ts +4 -1
- package/dist/cli-options.d.ts.map +1 -1
- package/dist/cli-options.js +63 -3
- package/dist/cli-options.js.map +1 -1
- package/dist/cli.js +12 -0
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +1 -0
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +6 -2
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +19 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -5
- package/dist/index.js.map +1 -1
- package/dist/link.d.ts +22 -1
- package/dist/link.d.ts.map +1 -1
- package/dist/link.js +130 -5
- package/dist/link.js.map +1 -1
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +514 -517
- package/dist/render.js.map +1 -1
- package/dist/request.d.ts +10 -0
- package/dist/request.d.ts.map +1 -0
- package/dist/request.js +6 -0
- package/dist/request.js.map +1 -0
- package/dist/typed-routes.d.ts +4 -5
- package/dist/typed-routes.d.ts.map +1 -1
- package/dist/typed-routes.js.map +1 -1
- package/dist/vite.d.ts +6 -0
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +4 -1
- package/dist/vite.js.map +1 -1
- package/package.json +19 -13
- package/src/adapters/aws-lambda.ts +227 -56
- package/src/adapters/cloudflare.ts +59 -0
- package/src/adapters/edge.ts +14 -0
- package/src/adapters/node.ts +44 -2
- package/src/build.ts +113 -16
- package/src/cache.ts +39 -17
- package/src/cli-options.ts +92 -6
- package/src/cli.ts +12 -0
- package/src/client.ts +2 -1
- package/src/config.ts +10 -2
- package/src/index.ts +57 -10
- package/src/link.ts +205 -10
- package/src/render.ts +5 -7
- package/src/request.ts +35 -0
- package/src/typed-routes.ts +4 -4
- package/src/vite.ts +30 -1
package/README.md
CHANGED
|
@@ -363,7 +363,7 @@ For Cloudflare Pages advanced mode, run `mreact-router package cloudflare-pages
|
|
|
363
363
|
User Vite plugins from the project config are forwarded into router bundle builds after the `mreact-router` plugin itself is removed, so MDX-style syntax transforms and custom content loaders can participate in server, client, Cloudflare, and prerender bundles. Vite `define` values are also forwarded into generated Cloudflare server bundles, including `import.meta.env.*` aliases and plain define identifiers used by loaders and route handlers. Client assets, route stylesheet assets imported by pages/layouts/templates or special `error.tsx`/`not-found.tsx` boundaries, and copied public assets are served only when they appear in the generated manifest allow-list. Dynamic routes resolve modules through a build-time registry keyed by `route.file`, not by constructing module ids from request input. Generated Cloudflare route modules preserve app-router layout/template shells and named slots for both string and `stream = true` pages, including route-local `<Await>` boundaries and local server-component imports. Generated Cloudflare server route modules dispatch method exports such as `GET`, `POST`, and `ALL` with decoded dynamic params plus `context.env`, `context.context`, `context.request`, and `context.route`, so handlers can use Worker bindings directly. Cloudflare page rendering installs the per-request query client scope before loader, page, metadata, and document rendering, so server-rendered helpers can call `getQueryClient()` even in runtimes without `AsyncLocalStorage`. The Cloudflare adapter marks streamed HTML with `Cache-Control: no-transform` and `Content-Encoding: identity` so Workers compression does not gzip-buffer the first shell before placeholders can paint. Pass `onResponse` to add cross-cutting response headers to rendered, static, asset, reload, not-found, and error responses. If a generated Cloudflare route module cannot produce the `data-mreact-route-id` marker contract required by client navigation, the adapter returns a reload signal for `x-mreact-navigation: 1` requests so the browser performs a normal document navigation without first buffering the full HTML response.
|
|
364
364
|
|
|
365
365
|
For AWS Lambda, use `createPreloadedAwsLambdaRequestHandler()` with API Gateway
|
|
366
|
-
HTTP API v2 or Lambda Function URL payload format 2.0:
|
|
366
|
+
HTTP API v2 or Lambda Function URL payload format 2.0. It validates the event before materializing runtime files or starting preload work:
|
|
367
367
|
|
|
368
368
|
```ts
|
|
369
369
|
import { createPreloadedAwsLambdaRequestHandler } from "@reckona/mreact-router/adapters/aws-lambda";
|
|
@@ -377,17 +377,30 @@ export const handler = await createPreloadedAwsLambdaRequestHandler({
|
|
|
377
377
|
});
|
|
378
378
|
```
|
|
379
379
|
|
|
380
|
+
When a deployment deliberately trades Lambda initialization time for lower first-valid-request latency, call `warmAwsLambdaRuntime()` explicitly before creating the handler:
|
|
381
|
+
|
|
382
|
+
```ts
|
|
383
|
+
import {
|
|
384
|
+
createPreloadedAwsLambdaRequestHandler,
|
|
385
|
+
warmAwsLambdaRuntime,
|
|
386
|
+
} from "@reckona/mreact-router/adapters/aws-lambda";
|
|
387
|
+
|
|
388
|
+
const options = { importPolicy: "generated" as const, outDir: ".mreact" };
|
|
389
|
+
await warmAwsLambdaRuntime(options);
|
|
390
|
+
export const handler = await createPreloadedAwsLambdaRequestHandler(options);
|
|
391
|
+
```
|
|
392
|
+
|
|
380
393
|
Production adapters enforce the app-router import policy when bundling loaders, middleware, route handlers, metadata, and server actions. `mreact-router build` writes `.mreact/server/import-policy.json` from server-side static imports. The built Node server used by `mreact-router start .mreact`, `renderBuiltAppRequest()`, and `createBuiltRequestRuntime()` reads that generated policy automatically and merges its runtime packages with any explicit policy options. Lambda handlers can use `importPolicy: "generated"`. You can still pass an explicit `importPolicy.allowedPackages` list when you need a hand-audited policy.
|
|
381
394
|
|
|
382
|
-
For Lambda deployments, build with `mreact-router build --target=aws-lambda` or `buildApp({ targets: ["aws-lambda"] })`. The target writes Node-compatible server/client output, `.mreact/server/import-policy.json`, and
|
|
395
|
+
For Lambda deployments, build with `mreact-router build --target=aws-lambda` or `buildApp({ targets: ["aws-lambda"] })`. The generated buffered and streaming handlers warm the same middleware policy during module initialization by default and then use request handlers with duplicate preload disabled. The artifact manifest records `mreact-handler.handler` and `mreact-streaming-handler.handler` separately. Select a broader or disabled initialization policy with `--aws-lambda-preload=hot-route-requests|all|none` or `buildApp({ awsLambdaPreload: "all", targets: ["aws-lambda"] })` only after measuring the packaged handler; pair `hot-route-requests` with `--aws-lambda-preload-routes=/,/login` or `awsLambdaPreloadRoutes`. `none` disables generated module preload but still materializes the writable runtime directory during generated handler import. The package command preserves the build-generated policy unless package options explicitly override it. The target writes Node-compatible server/client output, `.mreact/server/import-policy.json`, and generated Lambda entries while skipping `.mreact/cloudflare` route modules, so loaders and server helpers may import Node-only dependencies such as database drivers without being bundled for the Workers runtime.
|
|
383
396
|
|
|
384
|
-
Package Lambda deployments with `mreact-router package aws-lambda --from .mreact --out .lambda` instead of pointing deployment tooling at the full project checkout. AWS Lambda enforces a 250 MB unzipped deployment package limit, and the runtime only needs `.mreact/`, `mreact-handler.mjs`, `package.json` / lockfiles, and production `node_modules`; `src/`, tests, dev dependencies, build caches, and Vite/Vitest/Playwright tooling are not required. `mreact-router build --target=aws-lambda` keeps compiled server route artifacts in `.mreact/server/server-modules/*.json` instead of embedding them in one large server manifest, writes compiled module bodies as hashed `.mjs` files, and keeps request/control artifacts separate from render artifacts so loader redirects do not read page render bundles. AWS Lambda request/control artifacts bundle the generated import-policy packages they use for loaders, middleware, route handlers, and metadata, reducing first-hit package resolution on sparse Lambda traffic while leaving render-only, server action, custom handler, and adapter dependencies in production `node_modules`. `createAwsLambdaRequestHandler()` treats `outDir` as read-only and materializes generated runtime files under `/tmp/mreact-router/<hash>/runtime` by default, with a `node_modules` symlink back to the deployed package root. Direct `createAwsLambdaRequestHandler()` and `createAwsLambdaStreamingRequestHandler()` handlers start only middleware and shared runtime preload in the background by default, so all-route preload work does not compete with the first user request. If a request arrives before preload finishes, middleware is resolved first, middleware responses or redirects return without loading the matched page artifact, and continuing requests load only the matched route's artifact closure. Static middleware `config.matcher` and `config.id` values are checked before importing the middleware module, so unmatched health checks and route-local middleware skips avoid evaluating heavyweight middleware dependencies. Route request artifacts omit page render exports, and built loader and route metadata artifacts are split, so loader redirects do not evaluate page-only or metadata-only dependencies before render or metadata is needed. Loader redirects settle before page component server transforms and render imports for non-stream routes, stream routes without a loading boundary, and stream loading routes whose loader source contains router control-flow helpers such as `redirect()` or `notFound()`.
|
|
397
|
+
Package Lambda deployments with `mreact-router package aws-lambda --from .mreact --out .lambda` instead of pointing deployment tooling at the full project checkout. AWS Lambda enforces a 250 MB unzipped deployment package limit, and the runtime only needs `.mreact/`, `mreact-handler.mjs`, `package.json` / lockfiles, and production `node_modules`; `src/`, tests, dev dependencies, build caches, and Vite/Vitest/Playwright tooling are not required. `mreact-router build --target=aws-lambda` keeps compiled server route artifacts in `.mreact/server/server-modules/*.json` instead of embedding them in one large server manifest, writes compiled module bodies as hashed `.mjs` files, and keeps request/control artifacts separate from render artifacts so loader redirects do not read page render bundles. AWS Lambda request/control artifacts bundle the generated import-policy packages they use for loaders, middleware, route handlers, and metadata, reducing first-hit package resolution on sparse Lambda traffic while leaving render-only, server action, custom handler, and adapter dependencies in production `node_modules`. `createAwsLambdaRequestHandler()` treats `outDir` as read-only and materializes generated runtime files under `/tmp/mreact-router/<hash>/runtime` by default, with a `node_modules` symlink back to the deployed package root. Direct `createAwsLambdaRequestHandler()` and `createAwsLambdaStreamingRequestHandler()` handlers start only middleware and shared runtime preload in the background by default, so all-route preload work does not compete with the first user request. If a request arrives before preload finishes, middleware is resolved first, middleware responses or redirects return without loading the matched page artifact, and continuing requests load only the matched route's artifact closure. Static middleware `config.matcher` and `config.id` values are checked before importing the middleware module, so unmatched health checks and route-local middleware skips avoid evaluating heavyweight middleware dependencies. Route request artifacts omit page render exports, and built loader and route metadata artifacts are split, so loader redirects do not evaluate page-only or metadata-only dependencies before render or metadata is needed. Loader redirects settle before page component server transforms and render imports for non-stream routes, stream routes without a loading boundary, and stream loading routes whose loader source contains router control-flow helpers such as `redirect()` or `notFound()`. `createPreloadedAwsLambdaRequestHandler()` validates the first event before it starts full preload. When a deployment intentionally accepts extra Lambda initialization work to reduce first-valid-request latency, call `await warmAwsLambdaRuntime(options)` during controlled initialization before creating the handler. Pass `runtimeDir` only when you need to control that writable cache location. With pnpm, run `pnpm --dir .lambda install --prod --frozen-lockfile --ignore-scripts --config.node-linker=hoisted`. pnpm's default isolated linker is symlink-heavy, so verify the artifact's symlink count with `find .lambda -type l | wc -l` and measure actual file bytes in addition to `du -sh .lambda` before upload. Packages listed in the generated import policy may still be needed by render-only modules, inferred server actions, custom handlers, or adapter code, so keep them installed in that production artifact.
|
|
385
398
|
|
|
386
399
|
When a deployment needs custom adapter options such as `serverActions.authorize`, `onResponse`, `errorHandler`, or `allowedHosts`, create an app handler and package it with `mreact-router package aws-lambda --from .mreact --out .lambda --handler src/lambda.ts`. The package command bundles that handler into `.lambda/mreact-handler.mjs`, resolves app-local TypeScript imports with Vite-style extensionless paths, and keeps package imports external so production `node_modules` remains the runtime dependency boundary. If the handler imports the same app server modules that routes also import, those modules are compiled into the handler bundle separately from the mreact route artifacts; use `getServerRuntimeState()` for state that must be shared through the router runtime instead of relying on module singletons.
|
|
387
400
|
|
|
388
401
|
Configure `allowedHosts` for production Lambda deployments so absolute URLs, redirects, cache keys, and metadata cannot be derived from attacker-controlled Host input. The Lambda adapter uses `Host` by default and only reads `x-forwarded-host` when `hostPolicy: "trusted-proxy"` is set. It also ignores `x-forwarded-proto` unless `trustForwardedProto: true` is configured, deriving the request scheme from the Lambda event protocol when available and otherwise defaulting to HTTPS.
|
|
389
402
|
|
|
390
|
-
Use the Lambda `preload` option to tune that trade-off. Direct handlers default to `"middleware"` so cold starts do not kick off all route module imports in parallel with the first request. `createPreloadedAwsLambdaRequestHandler()` and `createPreloadedAwsLambdaStreamingRequestHandler()` default to `"all"`
|
|
403
|
+
Use the Lambda `preload` option to tune that trade-off. Direct handlers default to `"middleware"` so cold starts do not kick off all route module imports in parallel with the first request. `createPreloadedAwsLambdaRequestHandler()` and `createPreloadedAwsLambdaStreamingRequestHandler()` default to `"all"` after event validation. Call `warmAwsLambdaRuntime()` explicitly when initialization-time full preload is an intentional deployment choice. Set `preload: "none"` to disable background preload, `preload: "all"` only when you have measured that all-route background preload helps the deployed function, `preload: { mode: "hot-routes", routes: ["/", "/dashboard"] }` with `warmAwsLambdaRuntime()` to warm selected route closures including render modules before valid traffic, or `preload: { mode: "hot-route-requests", routes: ["/", "/login"] }` to warm only middleware plus selected route loader/server-route request modules without evaluating page/layout render modules. For direct handlers that cannot use top-level async initialization, add `wait: "before-render"` to an object preload strategy to let page-rendering invocations wait for the already-started preload after loader redirects have had a chance to return; add `wait: "first-request"` only when the first invocation can pay the full preload cost. Lambda request timing reports `first-request` waits as `preloadWaitMs`, and render timing reports `before-render` waits as `preloadWaitMs`.
|
|
391
404
|
|
|
392
405
|
Set `timings: true` on `createAwsLambdaRequestHandler()` or `createAwsLambdaStreamingRequestHandler()` when you need low-overhead Lambda phase diagnostics. The adapter emits a `router:request:timing` debug log event with `eventToRequestMs`, `runtimeDirMs`, `renderMs`, and response serialization or streaming time, so production measurements can separate API Gateway event normalization, runtime materialization, route rendering, and Lambda response conversion. It also forwards `router:render:timing` debug events for route-level phases such as route matching, middleware, loader start/wait, source analysis, page module load, page component render, route slot render, layout module load, layout component render, metadata, and response construction. Loader timings split module load/evaluation (`loaderModuleLoadMs`) from user loader execution (`loaderExecutionMs`) inside the existing `loaderWaitMs` envelope, source analysis reports `sourceAnalysisArtifactMs` when a built analysis summary is reused, and middleware timings similarly split `middlewareModuleLoadMs` from `middlewareExecutionMs` inside `middlewareMs`. Buffered handlers report `responseSerializationMs` as the total conversion phase and split it into `streamDrainMs`, `streamReadMs`, `streamConcatMs`, and `bodyEncodeMs`; streaming handlers report `responseStreamingMs` as the total streaming phase and split it into `streamWaitMs` and `streamWriteMs`.
|
|
393
406
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const builtCliUrl = new URL("../dist/cli.js", import.meta.url);
|
|
4
|
+
|
|
5
|
+
try {
|
|
6
|
+
await import(builtCliUrl.href);
|
|
7
|
+
} catch (error) {
|
|
8
|
+
if (
|
|
9
|
+
error !== null &&
|
|
10
|
+
typeof error === "object" &&
|
|
11
|
+
"code" in error &&
|
|
12
|
+
error.code === "ERR_MODULE_NOT_FOUND" &&
|
|
13
|
+
"url" in error &&
|
|
14
|
+
error.url === builtCliUrl.href
|
|
15
|
+
) {
|
|
16
|
+
console.error(
|
|
17
|
+
"mreact-router has not been built yet. Run the workspace or package build before invoking the CLI.",
|
|
18
|
+
);
|
|
19
|
+
process.exitCode = 1;
|
|
20
|
+
} else {
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -4,11 +4,23 @@ import type { AppRouterImportPolicy } from "../import-policy.js";
|
|
|
4
4
|
import { type AppRouterLogger } from "../logger.js";
|
|
5
5
|
import type { AppRouterResponseHook } from "../render.js";
|
|
6
6
|
import type { RouterInstrumentation } from "../trace.js";
|
|
7
|
-
/** Re-exports
|
|
8
|
-
export type {
|
|
7
|
+
/** Re-exports cache contracts used by AWS Lambda handlers. */
|
|
8
|
+
export type { AppRouterCache, AppRouterCacheEntry } from "../cache.js";
|
|
9
|
+
/** Re-exports server action contracts used by AWS Lambda handlers. */
|
|
10
|
+
export type { AppRouterAllowedServerAction, AppRouterServerActionOptions, } from "../actions.js";
|
|
11
|
+
/** Re-exports logger contracts used by AWS Lambda handlers. */
|
|
12
|
+
export type { AppRouterCspInlineNonceWarningLogEvent, AppRouterLogger, AppRouterLogError, AppRouterLogEvent, AppRouterRenderTimingLogEvent, AppRouterRequestEndLogEvent, AppRouterRequestErrorLogEvent, AppRouterRequestStartLogEvent, AppRouterRequestTimingLogEvent, AppRouterRuntime, } from "../logger.js";
|
|
13
|
+
/** Re-exports response hook contracts used by AWS Lambda handlers. */
|
|
14
|
+
export type { AppRouterResponseHook, AppRouterResponseHookContext } from "../render.js";
|
|
15
|
+
/** Re-exports build contracts referenced by AWS Lambda handler options. */
|
|
16
|
+
export type { BuiltPrerenderedRoute } from "../build.js";
|
|
17
|
+
/** Re-exports router instrumentation hooks and events for AWS Lambda handlers. */
|
|
18
|
+
export type { RouterInstrumentation, RouterMiddlewareEndInstrumentationEvent, RouterMiddlewareInstrumentationEvent, RouterRequestEndInstrumentationEvent, RouterRequestInstrumentationEvent, RouterRouteEndInstrumentationEvent, RouterRouteInstrumentationEvent, RouterTraceContext, } from "../trace.js";
|
|
9
19
|
/** Re-exports app-router import policy controls for AWS Lambda handlers. */
|
|
10
20
|
export type { AppRouterImportPolicy } from "../import-policy.js";
|
|
11
21
|
import { type AppRouterPrerenderStore, type RequestHostPolicy, type ResponseSinkStrategy } from "../serve.js";
|
|
22
|
+
/** Re-exports request and rendering contracts used by AWS Lambda handlers. */
|
|
23
|
+
export type { AppRouterPrerenderStore, RequestHostPolicy, ResponseSinkStrategy, } from "../serve.js";
|
|
12
24
|
/**
|
|
13
25
|
* Represents the AWS API Gateway HTTP API v2 event consumed by buffered handlers.
|
|
14
26
|
*/
|
|
@@ -17,15 +29,15 @@ export interface AwsLambdaHttpEventV2 {
|
|
|
17
29
|
cookies?: string[] | undefined;
|
|
18
30
|
headers?: Record<string, string | undefined> | undefined;
|
|
19
31
|
isBase64Encoded?: boolean | undefined;
|
|
20
|
-
rawPath
|
|
21
|
-
rawQueryString
|
|
22
|
-
requestContext
|
|
23
|
-
http
|
|
24
|
-
method
|
|
32
|
+
rawPath: string;
|
|
33
|
+
rawQueryString: string;
|
|
34
|
+
requestContext: {
|
|
35
|
+
http: {
|
|
36
|
+
method: string;
|
|
25
37
|
protocol?: string | undefined;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
version
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
version: "2.0";
|
|
29
41
|
}
|
|
30
42
|
/**
|
|
31
43
|
* Represents the AWS API Gateway HTTP API v2 result returned by buffered handlers.
|
|
@@ -109,11 +121,17 @@ export type AwsLambdaStreamingRequestHandler<TContext = unknown> = (event: AwsLa
|
|
|
109
121
|
*/
|
|
110
122
|
export declare function createAwsLambdaRequestHandler(options: AwsLambdaRequestHandlerOptions): AwsLambdaRequestHandler;
|
|
111
123
|
/**
|
|
112
|
-
* Creates a buffered AWS Lambda handler
|
|
124
|
+
* Creates a buffered AWS Lambda handler that starts full runtime preparation after the first valid event.
|
|
113
125
|
*
|
|
114
|
-
*
|
|
126
|
+
* Invalid events are rejected before runtime materialization or preload work begins.
|
|
115
127
|
*/
|
|
116
128
|
export declare function createPreloadedAwsLambdaRequestHandler(options: AwsLambdaRequestHandlerOptions): Promise<AwsLambdaRequestHandler>;
|
|
129
|
+
/**
|
|
130
|
+
* Explicitly materializes and preloads a built Lambda runtime before request handling.
|
|
131
|
+
*
|
|
132
|
+
* Call this during controlled Lambda initialization only when the extra startup work is preferable to first-valid-request latency. Request handlers always validate events before they start runtime work.
|
|
133
|
+
*/
|
|
134
|
+
export declare function warmAwsLambdaRuntime(options: AwsLambdaRequestHandlerOptions): Promise<void>;
|
|
117
135
|
/**
|
|
118
136
|
* Creates an AWS Lambda streaming response handler for built app-router output.
|
|
119
137
|
*
|
|
@@ -121,7 +139,9 @@ export declare function createPreloadedAwsLambdaRequestHandler(options: AwsLambd
|
|
|
121
139
|
*/
|
|
122
140
|
export declare function createAwsLambdaStreamingRequestHandler<TContext = unknown>(options: AwsLambdaRequestHandlerOptions): AwsLambdaStreamingRequestHandler<TContext>;
|
|
123
141
|
/**
|
|
124
|
-
* Creates a streaming AWS Lambda handler
|
|
142
|
+
* Creates a streaming AWS Lambda handler that starts full runtime preparation after the first valid event.
|
|
143
|
+
*
|
|
144
|
+
* Invalid events are rejected before runtime materialization or preload work begins.
|
|
125
145
|
*/
|
|
126
146
|
export declare function createPreloadedAwsLambdaStreamingRequestHandler<TContext = unknown>(options: AwsLambdaRequestHandlerOptions): Promise<AwsLambdaStreamingRequestHandler<TContext>>;
|
|
127
147
|
//# sourceMappingURL=aws-lambda.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aws-lambda.d.ts","sourceRoot":"","sources":["../../src/adapters/aws-lambda.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAKjE,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEzD,
|
|
1
|
+
{"version":3,"file":"aws-lambda.d.ts","sourceRoot":"","sources":["../../src/adapters/aws-lambda.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,21 @@ import { dirname, join } from "node:path";
|
|
|
6
6
|
import { normalizeBuiltAppRuntimePreloadStrategy, } from "../preload-policy.js";
|
|
7
7
|
import { emitRouterLog, logDurationMs, logError, logNow, requestLogFields, } from "../logger.js";
|
|
8
8
|
import { createBuiltRequestRuntime, preloadBuiltAppRuntime, resolveRequestHost, warnIfImplicitHostTrust, } from "../serve.js";
|
|
9
|
+
const invalidAwsLambdaHttpEventV2Diagnostic = 'Expected an AWS Lambda HTTP API payload format 2.0 event with rawPath and requestContext.http.method.';
|
|
10
|
+
function invalidAwsLambdaHttpEventV2Result() {
|
|
11
|
+
return {
|
|
12
|
+
body: invalidAwsLambdaHttpEventV2Diagnostic,
|
|
13
|
+
headers: { "content-type": "text/plain; charset=utf-8" },
|
|
14
|
+
isBase64Encoded: false,
|
|
15
|
+
statusCode: 400,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function invalidAwsLambdaHttpEventV2Response() {
|
|
19
|
+
return new Response(invalidAwsLambdaHttpEventV2Diagnostic, {
|
|
20
|
+
headers: { "content-type": "text/plain; charset=utf-8" },
|
|
21
|
+
status: 400,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
9
24
|
/**
|
|
10
25
|
* Creates a buffered AWS Lambda HTTP API v2 handler for built app-router output.
|
|
11
26
|
*
|
|
@@ -13,24 +28,65 @@ import { createBuiltRequestRuntime, preloadBuiltAppRuntime, resolveRequestHost,
|
|
|
13
28
|
*/
|
|
14
29
|
export function createAwsLambdaRequestHandler(options) {
|
|
15
30
|
warnIfImplicitHostTrust(options);
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
31
|
+
let handler;
|
|
32
|
+
return async (event) => {
|
|
33
|
+
try {
|
|
34
|
+
validateAwsLambdaHttpEventV2(event);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return invalidAwsLambdaHttpEventV2Result();
|
|
38
|
+
}
|
|
39
|
+
handler ??= (() => {
|
|
40
|
+
const runtimeDirPromise = prepareAwsLambdaRuntimeDir(options);
|
|
41
|
+
const runtimePreloadPromise = startAwsLambdaRuntimePreload(options, runtimeDirPromise, "middleware");
|
|
42
|
+
void runtimePreloadPromise?.catch(() => { });
|
|
43
|
+
return createAwsLambdaRequestHandlerFromRuntime(options, runtimeDirPromise, runtimePreloadPromise, "middleware");
|
|
44
|
+
})();
|
|
45
|
+
return await handler(event);
|
|
46
|
+
};
|
|
20
47
|
}
|
|
21
48
|
/**
|
|
22
|
-
* Creates a buffered AWS Lambda handler
|
|
49
|
+
* Creates a buffered AWS Lambda handler that starts full runtime preparation after the first valid event.
|
|
23
50
|
*
|
|
24
|
-
*
|
|
51
|
+
* Invalid events are rejected before runtime materialization or preload work begins.
|
|
25
52
|
*/
|
|
26
53
|
export async function createPreloadedAwsLambdaRequestHandler(options) {
|
|
54
|
+
warnIfImplicitHostTrust(options);
|
|
55
|
+
let handler;
|
|
56
|
+
return async (event) => {
|
|
57
|
+
try {
|
|
58
|
+
validateAwsLambdaHttpEventV2(event);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return invalidAwsLambdaHttpEventV2Result();
|
|
62
|
+
}
|
|
63
|
+
handler ??= (() => {
|
|
64
|
+
const runtimeDirPromise = prepareAwsLambdaRuntimeDir(options);
|
|
65
|
+
const runtimePreloadPromise = startAwsLambdaRuntimePreload(options, runtimeDirPromise, "all");
|
|
66
|
+
void runtimePreloadPromise?.catch(() => { });
|
|
67
|
+
return createAwsLambdaRequestHandlerFromRuntime(options, runtimeDirPromise, runtimePreloadPromise);
|
|
68
|
+
})();
|
|
69
|
+
return await handler(event);
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Explicitly materializes and preloads a built Lambda runtime before request handling.
|
|
74
|
+
*
|
|
75
|
+
* Call this during controlled Lambda initialization only when the extra startup work is preferable to first-valid-request latency. Request handlers always validate events before they start runtime work.
|
|
76
|
+
*/
|
|
77
|
+
export async function warmAwsLambdaRuntime(options) {
|
|
27
78
|
warnIfImplicitHostTrust(options);
|
|
28
79
|
const runtimeDir = await prepareAwsLambdaRuntimeDir(options);
|
|
29
80
|
await preloadAwsLambdaRuntime(options, runtimeDir);
|
|
30
|
-
return createAwsLambdaRequestHandlerFromRuntime(options, Promise.resolve(runtimeDir));
|
|
31
81
|
}
|
|
32
82
|
function createAwsLambdaRequestHandlerFromRuntime(options, runtimeDirPromise, runtimePreloadPromise, defaultPreloadMode = "all") {
|
|
33
83
|
return async (event) => {
|
|
84
|
+
try {
|
|
85
|
+
validateAwsLambdaHttpEventV2(event);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return invalidAwsLambdaHttpEventV2Result();
|
|
89
|
+
}
|
|
34
90
|
const startedAt = logNow();
|
|
35
91
|
const phases = createAwsLambdaTimingPhases(options);
|
|
36
92
|
const eventToRequestStartedAt = phaseStartedAt(phases);
|
|
@@ -107,20 +163,49 @@ function createAwsLambdaRequestHandlerFromRuntime(options, runtimeDirPromise, ru
|
|
|
107
163
|
export function createAwsLambdaStreamingRequestHandler(options) {
|
|
108
164
|
warnIfImplicitHostTrust(options);
|
|
109
165
|
const runtime = awsLambdaRuntime();
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
166
|
+
let handler;
|
|
167
|
+
return runtime.streamifyResponse(async (event, responseStream, context) => {
|
|
168
|
+
try {
|
|
169
|
+
validateAwsLambdaHttpEventV2(event);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
await streamResponseToLambda(invalidAwsLambdaHttpEventV2Response(), responseStream, runtime);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
handler ??= (() => {
|
|
176
|
+
const runtimeDirPromise = prepareAwsLambdaRuntimeDir(options);
|
|
177
|
+
const runtimePreloadPromise = startAwsLambdaRuntimePreload(options, runtimeDirPromise, "middleware");
|
|
178
|
+
void runtimePreloadPromise?.catch(() => { });
|
|
179
|
+
return createAwsLambdaStreamingRequestHandlerFromRuntime(options, runtime, runtimeDirPromise, runtimePreloadPromise, "middleware");
|
|
180
|
+
})();
|
|
181
|
+
await handler(event, responseStream, context);
|
|
182
|
+
});
|
|
114
183
|
}
|
|
115
184
|
/**
|
|
116
|
-
* Creates a streaming AWS Lambda handler
|
|
185
|
+
* Creates a streaming AWS Lambda handler that starts full runtime preparation after the first valid event.
|
|
186
|
+
*
|
|
187
|
+
* Invalid events are rejected before runtime materialization or preload work begins.
|
|
117
188
|
*/
|
|
118
189
|
export async function createPreloadedAwsLambdaStreamingRequestHandler(options) {
|
|
119
190
|
warnIfImplicitHostTrust(options);
|
|
120
191
|
const runtime = awsLambdaRuntime();
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
192
|
+
let handler;
|
|
193
|
+
return runtime.streamifyResponse(async (event, responseStream, context) => {
|
|
194
|
+
try {
|
|
195
|
+
validateAwsLambdaHttpEventV2(event);
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
await streamResponseToLambda(invalidAwsLambdaHttpEventV2Response(), responseStream, runtime);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
handler ??= (() => {
|
|
202
|
+
const runtimeDirPromise = prepareAwsLambdaRuntimeDir(options);
|
|
203
|
+
const runtimePreloadPromise = startAwsLambdaRuntimePreload(options, runtimeDirPromise, "all");
|
|
204
|
+
void runtimePreloadPromise?.catch(() => { });
|
|
205
|
+
return createAwsLambdaStreamingRequestHandlerFromRuntime(options, runtime, runtimeDirPromise, runtimePreloadPromise);
|
|
206
|
+
})();
|
|
207
|
+
await handler(event, responseStream, context);
|
|
208
|
+
});
|
|
124
209
|
}
|
|
125
210
|
function startAwsLambdaRuntimePreload(options, runtimeDirPromise, defaultMode = "all") {
|
|
126
211
|
const preload = normalizeAwsLambdaPreload(options.preload, defaultMode);
|
|
@@ -213,6 +298,13 @@ function normalizeAwsLambdaPreload(strategy, defaultMode = "all") {
|
|
|
213
298
|
}
|
|
214
299
|
function createAwsLambdaStreamingRequestHandlerFromRuntime(options, runtime, runtimeDirPromise, runtimePreloadPromise, defaultPreloadMode = "all") {
|
|
215
300
|
return runtime.streamifyResponse(async (event, responseStream, _context) => {
|
|
301
|
+
try {
|
|
302
|
+
validateAwsLambdaHttpEventV2(event);
|
|
303
|
+
}
|
|
304
|
+
catch {
|
|
305
|
+
await streamResponseToLambda(invalidAwsLambdaHttpEventV2Response(), responseStream, runtime);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
216
308
|
const startedAt = logNow();
|
|
217
309
|
const phases = createAwsLambdaTimingPhases(options);
|
|
218
310
|
const eventToRequestStartedAt = phaseStartedAt(phases);
|
|
@@ -337,6 +429,7 @@ function isNodeErrorCode(error, code) {
|
|
|
337
429
|
error.code === code);
|
|
338
430
|
}
|
|
339
431
|
function eventToRequest(event, options) {
|
|
432
|
+
validateAwsLambdaHttpEventV2(event);
|
|
340
433
|
const headers = eventHeaders(event);
|
|
341
434
|
const rawHost = lambdaRequestHost(headers, options);
|
|
342
435
|
const host = resolveRequestHost({
|
|
@@ -346,11 +439,9 @@ function eventToRequest(event, options) {
|
|
|
346
439
|
rawHost: rawHost ?? undefined,
|
|
347
440
|
});
|
|
348
441
|
const protocol = lambdaRequestProtocol(event, headers, options);
|
|
349
|
-
const rawPath = event.rawPath
|
|
350
|
-
const rawQueryString = event.rawQueryString ===
|
|
351
|
-
|
|
352
|
-
: `?${event.rawQueryString}`;
|
|
353
|
-
const method = event.requestContext?.http?.method ?? "GET";
|
|
442
|
+
const rawPath = event.rawPath;
|
|
443
|
+
const rawQueryString = event.rawQueryString === "" ? "" : `?${event.rawQueryString}`;
|
|
444
|
+
const method = event.requestContext.http.method;
|
|
354
445
|
const init = {
|
|
355
446
|
headers,
|
|
356
447
|
method,
|
|
@@ -361,6 +452,23 @@ function eventToRequest(event, options) {
|
|
|
361
452
|
}
|
|
362
453
|
return new Request(`${protocol}://${host}${rawPath}${rawQueryString}`, init);
|
|
363
454
|
}
|
|
455
|
+
function validateAwsLambdaHttpEventV2(event) {
|
|
456
|
+
const candidate = event;
|
|
457
|
+
if (typeof candidate !== "object" ||
|
|
458
|
+
candidate === null ||
|
|
459
|
+
candidate.version !== "2.0" ||
|
|
460
|
+
typeof candidate.rawPath !== "string" ||
|
|
461
|
+
!candidate.rawPath.startsWith("/") ||
|
|
462
|
+
typeof candidate.rawQueryString !== "string" ||
|
|
463
|
+
typeof candidate.requestContext !== "object" ||
|
|
464
|
+
candidate.requestContext === null ||
|
|
465
|
+
typeof (candidate.requestContext.http) !== "object" ||
|
|
466
|
+
candidate.requestContext.http === null ||
|
|
467
|
+
typeof (candidate.requestContext.http.method) !== "string" ||
|
|
468
|
+
candidate.requestContext.http.method === "") {
|
|
469
|
+
throw new Error(invalidAwsLambdaHttpEventV2Diagnostic);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
364
472
|
function lambdaRequestHost(headers, options) {
|
|
365
473
|
if (options.hostPolicy === "trusted-proxy") {
|
|
366
474
|
return firstForwardedValue(headers.get("x-forwarded-host")) ?? headers.get("host");
|