@platformatic/react-router 3.29.0 → 3.30.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/config.d.ts +4 -6
- package/lib/capability.js +111 -62
- package/package.json +9 -11
- package/schema.json +33 -5
package/config.d.ts
CHANGED
|
@@ -133,6 +133,8 @@ export interface PlatformaticReactRouterConfig {
|
|
|
133
133
|
maxMemory?: number;
|
|
134
134
|
cooldown?: number;
|
|
135
135
|
gracePeriod?: number;
|
|
136
|
+
scaleUpELU?: number;
|
|
137
|
+
scaleDownELU?: number;
|
|
136
138
|
[k: string]: unknown;
|
|
137
139
|
};
|
|
138
140
|
workersRestartDelay?: number | string;
|
|
@@ -465,13 +467,7 @@ export interface PlatformaticReactRouterConfig {
|
|
|
465
467
|
maxWorkers?: number;
|
|
466
468
|
cooldownSec?: number;
|
|
467
469
|
gracePeriod?: number;
|
|
468
|
-
/**
|
|
469
|
-
* @deprecated
|
|
470
|
-
*/
|
|
471
470
|
scaleUpELU?: number;
|
|
472
|
-
/**
|
|
473
|
-
* @deprecated
|
|
474
|
-
*/
|
|
475
471
|
scaleDownELU?: number;
|
|
476
472
|
/**
|
|
477
473
|
* @deprecated
|
|
@@ -535,6 +531,8 @@ export interface PlatformaticReactRouterConfig {
|
|
|
535
531
|
static?: number;
|
|
536
532
|
minimum?: number;
|
|
537
533
|
maximum?: number;
|
|
534
|
+
scaleUpELU?: number;
|
|
535
|
+
scaleDownELU?: number;
|
|
538
536
|
[k: string]: unknown;
|
|
539
537
|
};
|
|
540
538
|
health?: {
|
package/lib/capability.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import fastifyStatic from '@fastify/static'
|
|
1
2
|
import {
|
|
2
3
|
cleanBasePath,
|
|
3
4
|
createServerListener,
|
|
@@ -8,13 +9,12 @@ import {
|
|
|
8
9
|
resolvePackageViaCJS
|
|
9
10
|
} from '@platformatic/basic'
|
|
10
11
|
import { ViteCapability } from '@platformatic/vite'
|
|
11
|
-
import
|
|
12
|
-
import express from 'express'
|
|
13
|
-
import inject from 'light-my-request'
|
|
12
|
+
import fastify from 'fastify'
|
|
14
13
|
import { existsSync } from 'node:fs'
|
|
15
14
|
import { readFile, writeFile } from 'node:fs/promises'
|
|
16
|
-
import { dirname, resolve } from 'node:path'
|
|
17
|
-
import {
|
|
15
|
+
import { dirname, join, resolve } from 'node:path'
|
|
16
|
+
import { Readable } from 'node:stream'
|
|
17
|
+
import { createRequestHandler } from 'react-router'
|
|
18
18
|
import { satisfies } from 'semver'
|
|
19
19
|
import { packageJson } from './schema.js'
|
|
20
20
|
|
|
@@ -22,7 +22,6 @@ const supportedVersions = '^7.0.0'
|
|
|
22
22
|
|
|
23
23
|
export class ReactRouterCapability extends ViteCapability {
|
|
24
24
|
#app
|
|
25
|
-
#server
|
|
26
25
|
#reactRouter
|
|
27
26
|
#basePath
|
|
28
27
|
|
|
@@ -55,6 +54,11 @@ export class ReactRouterCapability extends ViteCapability {
|
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
async start ({ listen }) {
|
|
57
|
+
// Make this idempotent
|
|
58
|
+
if (this.url) {
|
|
59
|
+
return this.url
|
|
60
|
+
}
|
|
61
|
+
|
|
58
62
|
const config = this.config
|
|
59
63
|
const reactRouterConfig = await this.#getReactRouterConfig()
|
|
60
64
|
|
|
@@ -69,6 +73,8 @@ export class ReactRouterCapability extends ViteCapability {
|
|
|
69
73
|
}
|
|
70
74
|
|
|
71
75
|
if (reactRouterConfig.ssr) {
|
|
76
|
+
await super._start({ listen })
|
|
77
|
+
|
|
72
78
|
return this.#startSSRProduction(listen)
|
|
73
79
|
}
|
|
74
80
|
}
|
|
@@ -76,22 +82,6 @@ export class ReactRouterCapability extends ViteCapability {
|
|
|
76
82
|
return super.start({ listen })
|
|
77
83
|
}
|
|
78
84
|
|
|
79
|
-
async stop () {
|
|
80
|
-
const reactRouterConfig = await this.#getReactRouterConfig()
|
|
81
|
-
|
|
82
|
-
if (reactRouterConfig.ssr) {
|
|
83
|
-
await this._stop()
|
|
84
|
-
|
|
85
|
-
if (this.#server?.listening) {
|
|
86
|
-
await this._closeServer(this.#server)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return super.stop()
|
|
93
|
-
}
|
|
94
|
-
|
|
95
85
|
async build () {
|
|
96
86
|
const config = this.config
|
|
97
87
|
const command = config.application.commands.build
|
|
@@ -109,7 +99,7 @@ export class ReactRouterCapability extends ViteCapability {
|
|
|
109
99
|
|
|
110
100
|
await writeFile(
|
|
111
101
|
resolve(this.root, config.reactRouter.outputDirectory, '.platformatic-build.json'),
|
|
112
|
-
JSON.stringify({ basePath: reactRouterConfig.basename ?? '/' }),
|
|
102
|
+
JSON.stringify({ basePath: basePath ?? reactRouterConfig.basename ?? '/' }),
|
|
113
103
|
'utf-8'
|
|
114
104
|
)
|
|
115
105
|
}
|
|
@@ -119,16 +109,6 @@ export class ReactRouterCapability extends ViteCapability {
|
|
|
119
109
|
return super.getMeta(reactRouterConfig.basename)
|
|
120
110
|
}
|
|
121
111
|
|
|
122
|
-
async inject (injectParams, onInject) {
|
|
123
|
-
const reactRouterConfig = await this.#getReactRouterConfig()
|
|
124
|
-
|
|
125
|
-
if (this.isProduction && reactRouterConfig.ssr) {
|
|
126
|
-
return this.#inject(injectParams, onInject)
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return super.inject(injectParams, onInject)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
112
|
async #getReactRouterConfig () {
|
|
133
113
|
const ext = ['ts', 'js'].find(ext => existsSync(resolve(this.root, `react-router.config.${ext}`)))
|
|
134
114
|
|
|
@@ -150,16 +130,8 @@ export class ReactRouterCapability extends ViteCapability {
|
|
|
150
130
|
createServerListener(false, false, { backlog: serverOptions.backlog })
|
|
151
131
|
}
|
|
152
132
|
|
|
153
|
-
this.#
|
|
154
|
-
|
|
155
|
-
.listen(listenOptions, function () {
|
|
156
|
-
resolve(this)
|
|
157
|
-
})
|
|
158
|
-
.on('error', reject)
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
this.url = getServerUrl(this.#server)
|
|
162
|
-
|
|
133
|
+
await this.#app.listen(listenOptions)
|
|
134
|
+
this.url = getServerUrl(this.#app.server)
|
|
163
135
|
return this.url
|
|
164
136
|
}
|
|
165
137
|
|
|
@@ -171,33 +143,110 @@ export class ReactRouterCapability extends ViteCapability {
|
|
|
171
143
|
this.verifyOutputDirectory(serverRoot)
|
|
172
144
|
this.#basePath = await this._getBasePathFromBuildInfo()
|
|
173
145
|
|
|
174
|
-
const
|
|
146
|
+
const serverModule = await importFile(resolve(serverRoot, 'index.js'))
|
|
175
147
|
|
|
176
|
-
// Setup
|
|
177
|
-
this.#app =
|
|
148
|
+
// Setup fastify
|
|
149
|
+
this.#app = fastify({ loggerInstance: this.logger })
|
|
178
150
|
this._setApp(this.#app)
|
|
179
|
-
this.#app.disable('x-powered-by')
|
|
180
|
-
this.#app.use(pinoHttp({ logger: this.logger }))
|
|
181
|
-
this.#app.use(this.#basePath, express.static(clientRoot))
|
|
182
|
-
this.#app.all(
|
|
183
|
-
`${ensureTrailingSlash(cleanBasePath(this.#basePath))}*`,
|
|
184
|
-
createRequestHandler({ build: () => entrypoint })
|
|
185
|
-
)
|
|
186
151
|
|
|
152
|
+
let assetsRoot = clientRoot
|
|
153
|
+
let publicPath = '/'
|
|
154
|
+
let mainHandler
|
|
155
|
+
|
|
156
|
+
// Since it uses the Fetch API, we don't need to parse the request body.
|
|
157
|
+
this.#app.removeAllContentTypeParsers()
|
|
158
|
+
this.#app.addContentTypeParser('*', function (_, payload, done) {
|
|
159
|
+
done(null, payload)
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
// Custom entrypoint
|
|
163
|
+
if (serverModule.entrypoint) {
|
|
164
|
+
mainHandler = createRequestHandler(() => serverModule.entrypoint, process.env.NODE_ENV)
|
|
165
|
+
// Adapts @react-router/serve to fastify
|
|
166
|
+
} else {
|
|
167
|
+
if (serverModule.assetsBuildDirectory) {
|
|
168
|
+
assetsRoot = resolve(this.root, serverModule.assetsBuildDirectory)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (serverModule.publicPath) {
|
|
172
|
+
publicPath = serverModule.publicPath ?? '/'
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// RSC build
|
|
176
|
+
if (typeof serverModule.default === 'function') {
|
|
177
|
+
if (serverModule.unstable_reactRouterServeConfig) {
|
|
178
|
+
if (serverModule.unstable_reactRouterServeConfig.assetsBuildDirectory) {
|
|
179
|
+
assetsRoot = resolve(this.root, serverModule.unstable_reactRouterServeConfig.assetsBuildDirectory)
|
|
180
|
+
}
|
|
181
|
+
if (serverModule.unstable_reactRouterServeConfig.publicPath) {
|
|
182
|
+
publicPath = serverModule.unstable_reactRouterServeConfig.publicPath
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
mainHandler = serverModule.default
|
|
187
|
+
} else {
|
|
188
|
+
mainHandler = createRequestHandler(serverModule, process.env.NODE_ENV)
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
await this.#app.register(fastifyStatic, {
|
|
193
|
+
root: resolve(assetsRoot, 'assets'),
|
|
194
|
+
prefix: join(this.#basePath, 'assets'),
|
|
195
|
+
prefixAvoidTrailingSlash: true,
|
|
196
|
+
schemaHide: true,
|
|
197
|
+
decorateReply: false
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
if (publicPath !== '/') {
|
|
201
|
+
await this.#app.register(fastifyStatic, {
|
|
202
|
+
root: resolve(assetsRoot, 'assets'),
|
|
203
|
+
prefix: join(this.#basePath, publicPath),
|
|
204
|
+
prefixAvoidTrailingSlash: true,
|
|
205
|
+
schemaHide: true,
|
|
206
|
+
decorateReply: false
|
|
207
|
+
})
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
this.#app.all(`${ensureTrailingSlash(cleanBasePath(this.#basePath))}*`, this.#handleRequest.bind(this, mainHandler))
|
|
211
|
+
|
|
212
|
+
await this.#app.ready()
|
|
187
213
|
await this._collectMetrics()
|
|
188
|
-
return this.url
|
|
189
214
|
}
|
|
190
215
|
|
|
191
|
-
|
|
192
|
-
|
|
216
|
+
#handleRequest (handle, req) {
|
|
217
|
+
// Support aborting
|
|
218
|
+
const ac = new AbortController()
|
|
219
|
+
let ended = false
|
|
220
|
+
|
|
221
|
+
req.raw.on('aborted', () => ac.abort())
|
|
222
|
+
req.raw.on('end', () => { ended = true })
|
|
223
|
+
req.raw.on('close', () => {
|
|
224
|
+
if (!ended) {
|
|
225
|
+
ac.abort()
|
|
226
|
+
}
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
const headers = new Headers()
|
|
230
|
+
for (const [key, value] of Object.entries(req.headers)) {
|
|
231
|
+
if (value) {
|
|
232
|
+
headers.set(key, Array.isArray(value) ? value.join(',') : value)
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
let body
|
|
193
237
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
return
|
|
238
|
+
if (!['GET', 'HEAD'].includes(req.method)) {
|
|
239
|
+
body = Readable.toWeb(req.raw)
|
|
197
240
|
}
|
|
198
241
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
242
|
+
return handle(
|
|
243
|
+
new Request(`${req.protocol}://${req.hostname}${req.raw.url}`, {
|
|
244
|
+
method: req.method,
|
|
245
|
+
headers,
|
|
246
|
+
body,
|
|
247
|
+
duplex: body ? 'half' : undefined,
|
|
248
|
+
signal: ac.signal
|
|
249
|
+
})
|
|
250
|
+
)
|
|
202
251
|
}
|
|
203
252
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/react-router",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.30.0",
|
|
4
4
|
"description": "Platformatic React Router Capability",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -15,23 +15,21 @@
|
|
|
15
15
|
},
|
|
16
16
|
"homepage": "https://github.com/platformatic/platformatic#readme",
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"pino-http": "^10.2.0",
|
|
18
|
+
"@fastify/static": "^8.0.0",
|
|
19
|
+
"fastify": "^5.7.0",
|
|
21
20
|
"semver": "^7.6.3",
|
|
22
|
-
"@platformatic/basic": "3.
|
|
23
|
-
"@platformatic/
|
|
24
|
-
"@platformatic/
|
|
21
|
+
"@platformatic/basic": "3.30.0",
|
|
22
|
+
"@platformatic/foundation": "3.30.0",
|
|
23
|
+
"@platformatic/vite": "3.30.0"
|
|
25
24
|
},
|
|
26
25
|
"devDependencies": {
|
|
27
26
|
"@react-router/dev": "^7.10.0",
|
|
28
|
-
"@react-router/express": "^7.10.1",
|
|
29
27
|
"@react-router/node": "^7.10.0",
|
|
30
28
|
"@types/react": "^19.1.11",
|
|
31
29
|
"@types/react-dom": "^19.1.7",
|
|
32
30
|
"cleaner-spec-reporter": "^0.5.0",
|
|
33
31
|
"eslint": "9",
|
|
34
|
-
"fastify": "^5.
|
|
32
|
+
"fastify": "^5.7.0",
|
|
35
33
|
"isbot": "^5.1.17",
|
|
36
34
|
"json-schema-to-typescript": "^15.0.1",
|
|
37
35
|
"neostandard": "^0.12.0",
|
|
@@ -42,8 +40,8 @@
|
|
|
42
40
|
"typescript": "^5.5.4",
|
|
43
41
|
"vite": "^7.1.7",
|
|
44
42
|
"ws": "^8.18.0",
|
|
45
|
-
"@platformatic/
|
|
46
|
-
"@platformatic/
|
|
43
|
+
"@platformatic/gateway": "3.30.0",
|
|
44
|
+
"@platformatic/service": "3.30.0"
|
|
47
45
|
},
|
|
48
46
|
"engines": {
|
|
49
47
|
"node": ">=22.19.0"
|
package/schema.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$id": "https://schemas.platformatic.dev/@platformatic/react-router/3.
|
|
2
|
+
"$id": "https://schemas.platformatic.dev/@platformatic/react-router/3.30.0.json",
|
|
3
3
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
4
|
"title": "Platformatic React Router Config",
|
|
5
5
|
"type": "object",
|
|
@@ -456,6 +456,16 @@
|
|
|
456
456
|
"maximum": {
|
|
457
457
|
"type": "number",
|
|
458
458
|
"minimum": 0
|
|
459
|
+
},
|
|
460
|
+
"scaleUpELU": {
|
|
461
|
+
"type": "number",
|
|
462
|
+
"minimum": 0,
|
|
463
|
+
"maximum": 1
|
|
464
|
+
},
|
|
465
|
+
"scaleDownELU": {
|
|
466
|
+
"type": "number",
|
|
467
|
+
"minimum": 0,
|
|
468
|
+
"maximum": 1
|
|
459
469
|
}
|
|
460
470
|
}
|
|
461
471
|
}
|
|
@@ -735,6 +745,16 @@
|
|
|
735
745
|
"gracePeriod": {
|
|
736
746
|
"type": "number",
|
|
737
747
|
"minimum": 0
|
|
748
|
+
},
|
|
749
|
+
"scaleUpELU": {
|
|
750
|
+
"type": "number",
|
|
751
|
+
"minimum": 0,
|
|
752
|
+
"maximum": 1
|
|
753
|
+
},
|
|
754
|
+
"scaleDownELU": {
|
|
755
|
+
"type": "number",
|
|
756
|
+
"minimum": 0,
|
|
757
|
+
"maximum": 1
|
|
738
758
|
}
|
|
739
759
|
}
|
|
740
760
|
}
|
|
@@ -1767,14 +1787,12 @@
|
|
|
1767
1787
|
"scaleUpELU": {
|
|
1768
1788
|
"type": "number",
|
|
1769
1789
|
"minimum": 0,
|
|
1770
|
-
"maximum": 1
|
|
1771
|
-
"deprecated": true
|
|
1790
|
+
"maximum": 1
|
|
1772
1791
|
},
|
|
1773
1792
|
"scaleDownELU": {
|
|
1774
1793
|
"type": "number",
|
|
1775
1794
|
"minimum": 0,
|
|
1776
|
-
"maximum": 1
|
|
1777
|
-
"deprecated": true
|
|
1795
|
+
"maximum": 1
|
|
1778
1796
|
},
|
|
1779
1797
|
"timeWindowSec": {
|
|
1780
1798
|
"type": "number",
|
|
@@ -1975,6 +1993,16 @@
|
|
|
1975
1993
|
"maximum": {
|
|
1976
1994
|
"type": "number",
|
|
1977
1995
|
"minimum": 0
|
|
1996
|
+
},
|
|
1997
|
+
"scaleUpELU": {
|
|
1998
|
+
"type": "number",
|
|
1999
|
+
"minimum": 0,
|
|
2000
|
+
"maximum": 1
|
|
2001
|
+
},
|
|
2002
|
+
"scaleDownELU": {
|
|
2003
|
+
"type": "number",
|
|
2004
|
+
"minimum": 0,
|
|
2005
|
+
"maximum": 1
|
|
1978
2006
|
}
|
|
1979
2007
|
}
|
|
1980
2008
|
}
|