Add serverless request Page builder.

This commit is contained in:
Dillon Kearns 2021-04-24 16:01:31 -07:00
parent 2b78dd89bc
commit 38d6b65477
5 changed files with 69 additions and 20 deletions

View File

@ -7,11 +7,17 @@ exports.handler =
*/ */
async function (event, context) { async function (event, context) {
console.log(JSON.stringify(event)); console.log(JSON.stringify(event));
global.staticHttpCache = {};
const compiledElmPath = path.join(__dirname, "elm-pages-cli.js"); const compiledElmPath = path.join(__dirname, "elm-pages-cli.js");
const renderer = require("../../../../generator/src/render"); const renderer = require("../../../../generator/src/render");
try { try {
const renderResult = await renderer(compiledElmPath, event.path, event); const renderResult = await renderer(
compiledElmPath,
event.path,
event,
function () {}
);
if (renderResult.kind === "json") { if (renderResult.kind === "json") {
return { return {
@ -33,6 +39,7 @@ exports.handler =
}; };
} }
} catch (error) { } catch (error) {
console.error(error);
return { return {
body: `<body><h1>Error</h1><pre>${error}</pre></body>`, body: `<body><h1>Error</h1><pre>${error}</pre></body>`,
statusCode: 500, statusCode: 500,

View File

@ -1,12 +1,15 @@
module Page.Time exposing (Data, Model, Msg, page) module Page.Time exposing (Data, Model, Msg, page)
import DataSource import DataSource
import DataSource.Http
import Document exposing (Document) import Document exposing (Document)
import Element exposing (Element) import Element exposing (Element)
import Head import Head
import Head.Seo as Seo import Head.Seo as Seo
import OptimizedDecoder
import Page exposing (Page, PageWithState, StaticPayload) import Page exposing (Page, PageWithState, StaticPayload)
import Pages.ImagePath as ImagePath import Pages.ImagePath as ImagePath
import Secrets
import Shared import Shared
@ -28,16 +31,18 @@ type alias RouteParams =
page : Page RouteParams Data page : Page RouteParams Data
page = page =
Page.singleRoute Page.serverlessRoute
{ head = head { head = head
, data = data , data = \_ _ -> data
, routeFound = \_ -> DataSource.succeed True
} }
|> Page.buildNoState { view = view } |> Page.buildNoState { view = view }
data : DataSource.DataSource String data : DataSource.DataSource String
data = data =
DataSource.succeed "TIME RESPONSE" DataSource.Http.get (Secrets.succeed "http://localhost:8080/")
OptimizedDecoder.string

View File

@ -1,6 +1,7 @@
module ServerRequest exposing (ServerRequest, expectHeader, init, optionalHeader, staticData, toStaticHttp) module ServerRequest exposing (ServerRequest, expectHeader, init, optionalHeader, staticData, toStaticHttp)
import DataSource import DataSource
import DataSource.Http
import Internal.OptimizedDecoder exposing (OptimizedDecoder) import Internal.OptimizedDecoder exposing (OptimizedDecoder)
import OptimizedDecoder import OptimizedDecoder
import Secrets import Secrets
@ -17,7 +18,7 @@ init constructor =
staticData : DataSource.DataSource String staticData : DataSource.DataSource String
staticData = staticData =
DataSource.get (Secrets.succeed "$$elm-pages$$headers") DataSource.Http.get (Secrets.succeed "$$elm-pages$$headers")
(OptimizedDecoder.field "headers" (OptimizedDecoder.field "headers"
(OptimizedDecoder.field "accept-language" OptimizedDecoder.string) (OptimizedDecoder.field "accept-language" OptimizedDecoder.string)
) )
@ -25,7 +26,7 @@ staticData =
toStaticHttp : ServerRequest decodesTo -> DataSource.DataSource decodesTo toStaticHttp : ServerRequest decodesTo -> DataSource.DataSource decodesTo
toStaticHttp (ServerRequest decoder) = toStaticHttp (ServerRequest decoder) =
DataSource.get (Secrets.succeed "$$elm-pages$$headers") decoder DataSource.Http.get (Secrets.succeed "$$elm-pages$$headers") decoder
expectHeader : String -> ServerRequest (String -> value) -> ServerRequest value expectHeader : String -> ServerRequest (String -> value) -> ServerRequest value

View File

@ -2,10 +2,11 @@ module Page exposing
( Builder(..) ( Builder(..)
, StaticPayload , StaticPayload
, withData, noData , withData, noData
, prerenderedRoute, singleRoute
, Page, buildNoState , Page, buildNoState
, PageWithState, buildWithLocalState, buildWithSharedState , PageWithState, buildWithLocalState, buildWithSharedState
, DynamicContext , DynamicContext
, prerenderedRoute, singleRoute) , serverlessRoute)
{-| {-|
@ -32,7 +33,7 @@ But before the user even requests the page, we have the following data:
- `static` - this is the static data for this specific page. If you use `noData`, then this will be `()`, meaning there is no page-specific static data. - `static` - this is the static data for this specific page. If you use `noData`, then this will be `()`, meaning there is no page-specific static data.
@docs withData, noData @docs withData, noData
@docs prerenderedRoute, singleRoute @docs prerenderedRoute, singleRoute, serverlessRoute
## Stateless Page Modules ## Stateless Page Modules
@ -51,6 +52,7 @@ import DataSource exposing (DataSource)
import Document exposing (Document) import Document exposing (Document)
import Head import Head
import Pages.PagePath exposing (PagePath) import Pages.PagePath exposing (PagePath)
import ServerRequest exposing (ServerRequest)
import Shared import Shared
@ -69,6 +71,7 @@ type alias PageWithState routeParams templateData templateModel templateMsg =
, init : StaticPayload templateData routeParams -> ( templateModel, Cmd templateMsg ) , init : StaticPayload templateData routeParams -> ( templateModel, Cmd templateMsg )
, update : StaticPayload templateData routeParams -> Maybe Browser.Navigation.Key -> templateMsg -> templateModel -> Shared.Model -> ( templateModel, Cmd templateMsg, Maybe Shared.SharedMsg ) , update : StaticPayload templateData routeParams -> Maybe Browser.Navigation.Key -> templateMsg -> templateModel -> Shared.Model -> ( templateModel, Cmd templateMsg, Maybe Shared.SharedMsg )
, subscriptions : routeParams -> PagePath -> templateModel -> Shared.Model -> Sub templateMsg , subscriptions : routeParams -> PagePath -> templateModel -> Shared.Model -> Sub templateMsg
, handleRoute : Maybe (routeParams -> DataSource Bool)
} }
@ -94,6 +97,8 @@ type Builder routeParams templateData
, head : , head :
StaticPayload templateData routeParams StaticPayload templateData routeParams
-> List Head.Tag -> List Head.Tag
, serverless : Bool
, handleRoute : Maybe (routeParams -> DataSource Bool)
} }
@ -115,6 +120,7 @@ buildNoState { view } builderState =
, init = \_ -> ( (), Cmd.none ) , init = \_ -> ( (), Cmd.none )
, update = \_ _ _ _ _ -> ( (), Cmd.none, Nothing ) , update = \_ _ _ _ _ -> ( (), Cmd.none, Nothing )
, subscriptions = \_ _ _ _ -> Sub.none , subscriptions = \_ _ _ _ -> Sub.none
, handleRoute = record.handleRoute
} }
@ -157,6 +163,7 @@ buildWithLocalState config builderState =
, subscriptions = , subscriptions =
\routeParams path templateModel sharedModel -> \routeParams path templateModel sharedModel ->
config.subscriptions routeParams path templateModel config.subscriptions routeParams path templateModel
, handleRoute = record.handleRoute
} }
@ -198,6 +205,7 @@ buildWithSharedState config builderState =
msg msg
templateModel templateModel
, subscriptions = config.subscriptions , subscriptions = config.subscriptions
, handleRoute = record.handleRoute
} }
@ -213,6 +221,8 @@ withData { data, head, staticRoutes } =
{ data = data { data = data
, staticRoutes = staticRoutes , staticRoutes = staticRoutes
, head = head , head = head
, serverless = False
, handleRoute = Nothing
} }
@ -227,6 +237,8 @@ noData { head, staticRoutes } =
{ data = \_ -> DataSource.succeed () { data = \_ -> DataSource.succeed ()
, staticRoutes = staticRoutes , staticRoutes = staticRoutes
, head = head , head = head
, serverless = False
, handleRoute = Nothing
} }
@ -240,6 +252,8 @@ singleRoute { data, head } =
{ data = \_ -> data { data = \_ -> data
, staticRoutes = DataSource.succeed [ {} ] , staticRoutes = DataSource.succeed [ {} ]
, head = head , head = head
, serverless = False
, handleRoute = Nothing
} }
@ -254,4 +268,29 @@ prerenderedRoute { data, head, routes } =
{ data = data { data = data
, staticRoutes = routes , staticRoutes = routes
, head = head , head = head
, serverless = False
, handleRoute = Nothing
} }
{-| -}
serverlessRoute :
{ data : (ServerRequest decodedRequest -> DataSource decodedRequest) -> routeParams -> DataSource data
, routeFound : routeParams -> DataSource Bool
, head : StaticPayload data routeParams -> List Head.Tag
}
-> Builder routeParams data
serverlessRoute { data, head, routeFound } =
WithData
{ data = data ServerRequest.toStaticHttp
, staticRoutes = DataSource.succeed []
, head = head
, serverless = True
, handleRoute = Just routeFound
}
type RouteFound
= Found
-- TODO other status codes, like 403?
| NotFound404

View File

@ -451,17 +451,11 @@ getStaticRoutes =
DataSource.combine DataSource.combine
[ ${templates [ ${templates
.map((name) => { .map((name) => {
if (isParameterizedRoute(name)) { return `Page.${moduleName(
return `Page.${moduleName( name
name )}.page.staticRoutes |> DataSource.map (List.map Route.${pathNormalizedName(
)}.page.staticRoutes |> DataSource.map (List.map Route.${pathNormalizedName( name
name )})`;
)})`;
} else {
return `DataSource.succeed [ Route.${routeHelpers.routeVariant(
name
)} {} ]`;
}
}) })
.join("\n , ")} .join("\n , ")}
] ]
@ -634,7 +628,10 @@ function handleRoute(name) {
"." "."
)}.page.staticRoutes |> DataSource.map (List.member routeParams)`; )}.page.staticRoutes |> DataSource.map (List.member routeParams)`;
} else { } else {
return `DataSource.succeed True`; return `Page.${name.join(".")}.page.handleRoute
|> Maybe.map (\\handler -> handler routeParams)
|> Maybe.withDefault (DataSource.succeed True)
`;
} }
} }