( req: ExpressRequest, res: ExpressResponse, component: ReactElement, )
| 85 | |
| 86 | // Handle server actions. |
| 87 | async function handleAction( |
| 88 | req: ExpressRequest, |
| 89 | res: ExpressResponse, |
| 90 | component: ReactElement, |
| 91 | ) { |
| 92 | let id = req.get('rsc-action-id'); |
| 93 | let request = new Request('http://localhost' + req.url, { |
| 94 | method: 'POST', |
| 95 | headers: req.headers as any, |
| 96 | body: Readable.toWeb(req) as ReadableStream, |
| 97 | // @ts-ignore |
| 98 | duplex: 'half', |
| 99 | }); |
| 100 | |
| 101 | if (id) { |
| 102 | let action = await loadServerAction(id); |
| 103 | let body = req.is('multipart/form-data') |
| 104 | ? await request.formData() |
| 105 | : await request.text(); |
| 106 | let args = await decodeReply<any[]>(body); |
| 107 | let result = action.apply(null, args); |
| 108 | try { |
| 109 | // Wait for any mutations |
| 110 | await result; |
| 111 | } catch (x) { |
| 112 | // We handle the error on the client |
| 113 | } |
| 114 | |
| 115 | await render(req, res, component, result); |
| 116 | } else { |
| 117 | // Form submitted by browser (progressive enhancement). |
| 118 | let formData = await request.formData(); |
| 119 | let action = await decodeAction(formData); |
| 120 | try { |
| 121 | // Wait for any mutations |
| 122 | await action(); |
| 123 | } catch (err) { |
| 124 | // TODO render error page? |
| 125 | } |
| 126 | await render(req, res, component); |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | let server = app.listen(3001); |
| 131 | console.log('Server listening on port 3001'); |
no test coverage detected