@platformatic/remix 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 CHANGED
@@ -133,6 +133,8 @@ export interface PlatformaticRemixConfig {
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 PlatformaticRemixConfig {
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 PlatformaticRemixConfig {
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 { createRequestHandler } from '@remix-run/express'
12
- import express from 'express'
13
- import inject from 'light-my-request'
12
+ import { createRequestHandler } from '@remix-run/node'
13
+ import fastify from 'fastify'
14
14
  import { existsSync } from 'node:fs'
15
15
  import { readFile } from 'node:fs/promises'
16
- import { dirname, resolve } from 'node:path'
17
- import { pinoHttp } from 'pino-http'
16
+ import { dirname, join, resolve } from 'node:path'
17
+ import { Readable } from 'node:stream'
18
18
  import { satisfies } from 'semver'
19
19
  import { packageJson } from './schema.js'
20
20
 
@@ -22,7 +22,6 @@ const supportedVersions = '^2.0.0'
22
22
 
23
23
  export class RemixCapability extends ViteCapability {
24
24
  #app
25
- #server
26
25
  #remix
27
26
  #basePath
28
27
 
@@ -60,7 +59,7 @@ export class RemixCapability extends ViteCapability {
60
59
  return this.url
61
60
  }
62
61
 
63
- await this._start()
62
+ await this._start({ listen })
64
63
 
65
64
  const config = this.config
66
65
  const command = config.application.commands[this.isProduction ? 'production' : 'development']
@@ -72,20 +71,6 @@ export class RemixCapability extends ViteCapability {
72
71
  return this.isProduction ? this.#startProduction(listen) : this.#startDevelopment(listen)
73
72
  }
74
73
 
75
- async stop () {
76
- await super.stop()
77
-
78
- if (this.childManager) {
79
- return this.stopCommand()
80
- }
81
-
82
- if (this.isProduction) {
83
- return this.#stopProduction()
84
- } else if (this.#app) {
85
- return this.#app.close()
86
- }
87
- }
88
-
89
74
  async build () {
90
75
  const config = this.config
91
76
  const command = config.application.commands.build
@@ -114,23 +99,6 @@ export class RemixCapability extends ViteCapability {
114
99
  }
115
100
  }
116
101
 
117
- async inject (injectParams, onInject) {
118
- if (!this.isProduction) {
119
- return super.inject(injectParams, onInject)
120
- }
121
-
122
- const res = await inject(this.#app, injectParams, onInject)
123
-
124
- /* c8 ignore next 3 */
125
- if (onInject) {
126
- return
127
- }
128
-
129
- // Since inject might be called from the main thread directly via ITC, let's clean it up
130
- const { statusCode, headers, body, payload, rawPayload } = res
131
- return { statusCode, headers, body, payload, rawPayload }
132
- }
133
-
134
102
  getMeta () {
135
103
  if (!this.isProduction) {
136
104
  return super.getMeta()
@@ -177,16 +145,8 @@ export class RemixCapability extends ViteCapability {
177
145
  createServerListener(false, false, { backlog: serverOptions.backlog })
178
146
  }
179
147
 
180
- this.#server = await new Promise((resolve, reject) => {
181
- return this.#app
182
- .listen(listenOptions, function () {
183
- resolve(this)
184
- })
185
- .on('error', reject)
186
- })
187
-
188
- this.url = getServerUrl(this.#server)
189
-
148
+ await this.#app.listen(listenOptions)
149
+ this.url = getServerUrl(this.#app.server)
190
150
  return this.url
191
151
  }
192
152
 
@@ -196,23 +156,66 @@ export class RemixCapability extends ViteCapability {
196
156
  const build = await importFile(resolve(this.root, `${outputDirectory}/server/index.js`))
197
157
  this.#basePath = ensureTrailingSlash(cleanBasePath(build.basename))
198
158
 
199
- // Setup express app
200
- this.#app = express()
201
- this.#app.disable('x-powered-by')
202
- this.#app.use(pinoHttp({ logger: this.logger }))
203
- this.#app.use(this.#basePath, express.static(resolve(this.root, `${outputDirectory}/client`)))
204
- this.#app.all(`${ensureTrailingSlash(cleanBasePath(this.#basePath))}*`, createRequestHandler({ build }))
205
-
159
+ // Setup fastify
160
+ this.#app = fastify({ loggerInstance: this.logger })
161
+ this._setApp(this.#app)
162
+
163
+ // Since it uses the Fetch API, we don't need to parse the request body.
164
+ this.#app.removeAllContentTypeParsers()
165
+ this.#app.addContentTypeParser('*', function (_, payload, done) {
166
+ done(null, payload)
167
+ })
168
+
169
+ await this.#app.register(fastifyStatic, {
170
+ root: resolve(this.root, `${outputDirectory}/client/assets`),
171
+ prefix: join(this.#basePath, 'assets'),
172
+ prefixAvoidTrailingSlash: true,
173
+ schemaHide: true
174
+ })
175
+
176
+ this.#app.all(
177
+ `${ensureTrailingSlash(cleanBasePath(this.#basePath))}*`,
178
+ this.#handleRequest.bind(this, createRequestHandler(build, process.env.NODE_ENV))
179
+ )
180
+
181
+ await this.#app.ready()
206
182
  await this._collectMetrics()
207
- return this.url
208
183
  }
209
184
 
210
- async #stopProduction () {
211
- /* c8 ignore next 3 */
212
- if (!this.#server?.listening) {
213
- return
185
+ #handleRequest (handle, req) {
186
+ // Support aborting
187
+ const ac = new AbortController()
188
+ let ended = false
189
+
190
+ req.raw.on('aborted', () => ac.abort())
191
+ req.raw.on('end', () => { ended = true })
192
+ req.raw.on('close', () => {
193
+ if (!ended) {
194
+ ac.abort()
195
+ }
196
+ })
197
+
198
+ const headers = new Headers()
199
+ for (const [key, value] of Object.entries(req.headers)) {
200
+ if (value) {
201
+ headers.set(key, Array.isArray(value) ? value.join(',') : value)
202
+ }
214
203
  }
215
204
 
216
- return this._closeServer(this.#server)
205
+ let body
206
+
207
+ if (!['GET', 'HEAD'].includes(req.method)) {
208
+ body = Readable.toWeb(req.raw)
209
+ }
210
+
211
+ return handle(
212
+ new Request(`${req.protocol}://${req.hostname}${req.raw.url}`, {
213
+ method: req.method,
214
+ headers,
215
+ body,
216
+ duplex: body ? 'half' : undefined,
217
+ signal: ac.signal
218
+ })
219
+ )
217
220
  }
218
221
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/remix",
3
- "version": "3.29.0",
3
+ "version": "3.30.0",
4
4
  "description": "Platformatic Remix Capability",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -15,14 +15,12 @@
15
15
  },
16
16
  "homepage": "https://github.com/platformatic/platformatic#readme",
17
17
  "dependencies": {
18
- "@remix-run/express": "^2.16.8",
19
- "express": "^4.19.2",
20
- "light-my-request": "^6.0.0",
21
- "pino-http": "^10.2.0",
18
+ "@fastify/static": "^8.0.0",
19
+ "fastify": "^5.7.0",
22
20
  "semver": "^7.6.3",
23
- "@platformatic/basic": "3.29.0",
24
- "@platformatic/foundation": "3.29.0",
25
- "@platformatic/vite": "3.29.0"
21
+ "@platformatic/basic": "3.30.0",
22
+ "@platformatic/foundation": "3.30.0",
23
+ "@platformatic/vite": "3.30.0"
26
24
  },
27
25
  "devDependencies": {
28
26
  "@remix-run/dev": "^2.16.8",
@@ -32,7 +30,7 @@
32
30
  "@types/react-dom": "^19.1.7",
33
31
  "cleaner-spec-reporter": "^0.5.0",
34
32
  "eslint": "9",
35
- "fastify": "^5.0.0",
33
+ "fastify": "^5.7.0",
36
34
  "isbot": "^5.1.17",
37
35
  "json-schema-to-typescript": "^15.0.1",
38
36
  "neostandard": "^0.12.0",
@@ -41,8 +39,8 @@
41
39
  "typescript": "^5.5.4",
42
40
  "vite": "^7.0.0",
43
41
  "ws": "^8.18.0",
44
- "@platformatic/gateway": "3.29.0",
45
- "@platformatic/service": "3.29.0"
42
+ "@platformatic/service": "3.30.0",
43
+ "@platformatic/gateway": "3.30.0"
46
44
  },
47
45
  "engines": {
48
46
  "node": ">=22.19.0"
package/schema.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://schemas.platformatic.dev/@platformatic/remix/3.29.0.json",
2
+ "$id": "https://schemas.platformatic.dev/@platformatic/remix/3.30.0.json",
3
3
  "$schema": "http://json-schema.org/draft-07/schema#",
4
4
  "title": "Platformatic Remix 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
  }