@platformatic/next 3.54.0 → 3.56.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 +8 -0
- package/index.js +8 -3
- package/lib/caching/valkey-common.js +26 -13
- package/lib/caching/valkey-components.js +5 -3
- package/lib/caching/valkey-isr.js +7 -4
- package/lib/capability.js +4 -2
- package/lib/image-optimizer.js +3 -1
- package/lib/loader-next-15.cjs +7 -3
- package/package.json +6 -5
- package/schema.json +81 -1
package/config.d.ts
CHANGED
|
@@ -259,6 +259,8 @@ export interface PlatformaticNextJsConfig {
|
|
|
259
259
|
maxHeapTotal?: number | string;
|
|
260
260
|
maxYoungGeneration?: number | string;
|
|
261
261
|
codeRangeSize?: number | string;
|
|
262
|
+
bufferPoolSize?: number | string;
|
|
263
|
+
defaultHighWaterMark?: number | string;
|
|
262
264
|
};
|
|
263
265
|
undici?: {
|
|
264
266
|
agentOptions?: {
|
|
@@ -361,6 +363,10 @@ export interface PlatformaticNextJsConfig {
|
|
|
361
363
|
* The label name to use for the application identifier in metrics (e.g., applicationId, serviceId)
|
|
362
364
|
*/
|
|
363
365
|
applicationLabel?: string;
|
|
366
|
+
/**
|
|
367
|
+
* Enable outgoing HTTP client request duration metrics
|
|
368
|
+
*/
|
|
369
|
+
httpClientMetrics?: boolean | string;
|
|
364
370
|
readiness?:
|
|
365
371
|
| boolean
|
|
366
372
|
| {
|
|
@@ -619,6 +625,8 @@ export interface PlatformaticNextJsConfig {
|
|
|
619
625
|
maxHeapTotal?: number | string;
|
|
620
626
|
maxYoungGeneration?: number | string;
|
|
621
627
|
codeRangeSize?: number | string;
|
|
628
|
+
bufferPoolSize?: number | string;
|
|
629
|
+
defaultHighWaterMark?: number | string;
|
|
622
630
|
};
|
|
623
631
|
arguments?: string[];
|
|
624
632
|
env?: {
|
package/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { kMetadata } from '@platformatic/foundation'
|
|
2
|
+
import { getBasePath, getConfig, getLogger, getNextVersion, getNotifyConfig } from '@platformatic/globals'
|
|
2
3
|
import { resolve as resolvePath } from 'node:path'
|
|
3
4
|
import { getCacheHandlerPath, NextCapability } from './lib/capability.js'
|
|
4
5
|
import { loadConfiguration } from './lib/config.js'
|
|
@@ -9,7 +10,9 @@ export function getAdapterPath () {
|
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
function enhanceNextCacheConfig (nextConfig, modifications) {
|
|
12
|
-
const
|
|
13
|
+
const config = getConfig()
|
|
14
|
+
const nextVersion = getNextVersion()
|
|
15
|
+
const logger = getLogger()
|
|
13
16
|
|
|
14
17
|
if (!config.cache?.adapter || config.cache?.enabled === false) return
|
|
15
18
|
|
|
@@ -62,7 +65,9 @@ export async function enhanceNextConfig (nextConfig, ...args) {
|
|
|
62
65
|
nextConfig = await nextConfig(...args)
|
|
63
66
|
}
|
|
64
67
|
|
|
65
|
-
const
|
|
68
|
+
const basePath = getBasePath()
|
|
69
|
+
const config = getConfig()
|
|
70
|
+
const notifyConfig = getNotifyConfig()
|
|
66
71
|
|
|
67
72
|
if (typeof nextConfig.basePath === 'undefined') {
|
|
68
73
|
nextConfig.basePath = basePath
|
|
@@ -82,7 +87,7 @@ export async function enhanceNextConfig (nextConfig, ...args) {
|
|
|
82
87
|
nextConfig.env.PLT_NEXT_MODIFICATIONS = JSON.stringify(Object.fromEntries(modifications))
|
|
83
88
|
}
|
|
84
89
|
|
|
85
|
-
|
|
90
|
+
notifyConfig(nextConfig)
|
|
86
91
|
return nextConfig
|
|
87
92
|
}
|
|
88
93
|
|
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
import { buildPinoFormatters, buildPinoTimestamp } from '@platformatic/foundation'
|
|
2
|
+
import {
|
|
3
|
+
getApplicationId,
|
|
4
|
+
getConfig,
|
|
5
|
+
getEvents,
|
|
6
|
+
getLogLevel,
|
|
7
|
+
getRoot,
|
|
8
|
+
getValkeyClients,
|
|
9
|
+
getWorkerId,
|
|
10
|
+
updateGlobals
|
|
11
|
+
} from '@platformatic/globals'
|
|
2
12
|
import { existsSync, readFileSync } from 'node:fs'
|
|
3
13
|
import { createRequire } from 'node:module'
|
|
4
14
|
import { hostname } from 'node:os'
|
|
@@ -12,8 +22,7 @@ const require = createRequire(import.meta.url)
|
|
|
12
22
|
let Redis
|
|
13
23
|
let msgpackr
|
|
14
24
|
|
|
15
|
-
|
|
16
|
-
globalThis.platformatic.valkeyClients = new Map()
|
|
25
|
+
updateGlobals({ valkeyClients: new Map() })
|
|
17
26
|
|
|
18
27
|
export function keyFor (prefix, subprefix, section, key) {
|
|
19
28
|
let result = prefix?.length ? prefix + ':' : ''
|
|
@@ -48,13 +57,15 @@ export function ensureMsgpackr () {
|
|
|
48
57
|
}
|
|
49
58
|
|
|
50
59
|
export function getConnection (url) {
|
|
51
|
-
|
|
60
|
+
const valkeyClients = getValkeyClients()
|
|
61
|
+
let client = valkeyClients.get(url)
|
|
52
62
|
|
|
53
63
|
if (!client) {
|
|
54
64
|
client = new Redis(url, { enableAutoPipelining: true })
|
|
55
|
-
|
|
65
|
+
valkeyClients.set(url, client)
|
|
56
66
|
|
|
57
|
-
|
|
67
|
+
const events = getEvents()
|
|
68
|
+
events.on('plt:next:close', () => {
|
|
58
69
|
client.disconnect(false)
|
|
59
70
|
})
|
|
60
71
|
}
|
|
@@ -63,11 +74,12 @@ export function getConnection (url) {
|
|
|
63
74
|
}
|
|
64
75
|
|
|
65
76
|
export function createPlatformaticLogger () {
|
|
66
|
-
const
|
|
77
|
+
const config = getConfig()
|
|
78
|
+
const loggerConfig = config.logger
|
|
67
79
|
|
|
68
80
|
const pinoOptions = {
|
|
69
81
|
...loggerConfig,
|
|
70
|
-
level:
|
|
82
|
+
level: getLogLevel({ throwOnMissing: false }) ?? loggerConfig?.level ?? 'info'
|
|
71
83
|
}
|
|
72
84
|
if (pinoOptions.formatters) {
|
|
73
85
|
pinoOptions.formatters = buildPinoFormatters(pinoOptions.formatters)
|
|
@@ -76,8 +88,9 @@ export function createPlatformaticLogger () {
|
|
|
76
88
|
pinoOptions.timestamp = buildPinoTimestamp(pinoOptions.timestamp)
|
|
77
89
|
}
|
|
78
90
|
|
|
79
|
-
|
|
80
|
-
|
|
91
|
+
const applicationId = getApplicationId()
|
|
92
|
+
if (applicationId) {
|
|
93
|
+
pinoOptions.name = `cache:${applicationId}`
|
|
81
94
|
}
|
|
82
95
|
|
|
83
96
|
if (pinoOptions.base !== null) {
|
|
@@ -85,7 +98,7 @@ export function createPlatformaticLogger () {
|
|
|
85
98
|
...(pinoOptions.base ?? {}),
|
|
86
99
|
pid: process.pid,
|
|
87
100
|
hostname: hostname(),
|
|
88
|
-
worker:
|
|
101
|
+
worker: getWorkerId()
|
|
89
102
|
}
|
|
90
103
|
} else if (pinoOptions.base === null) {
|
|
91
104
|
pinoOptions.base = undefined
|
|
@@ -95,7 +108,7 @@ export function createPlatformaticLogger () {
|
|
|
95
108
|
}
|
|
96
109
|
|
|
97
110
|
export function getPlatformaticSubprefix () {
|
|
98
|
-
const root = fileURLToPath(
|
|
111
|
+
const root = fileURLToPath(getRoot())
|
|
99
112
|
|
|
100
113
|
return existsSync(resolve(root, '.next/BUILD_ID'))
|
|
101
114
|
? readFileSync(resolve(root, '.next/BUILD_ID'), 'utf-8').trim()
|
|
@@ -104,8 +117,8 @@ export function getPlatformaticSubprefix () {
|
|
|
104
117
|
|
|
105
118
|
export function getPlatformaticMeta () {
|
|
106
119
|
return {
|
|
107
|
-
applicationId:
|
|
108
|
-
workerId:
|
|
120
|
+
applicationId: getApplicationId(),
|
|
121
|
+
workerId: getWorkerId()
|
|
109
122
|
}
|
|
110
123
|
}
|
|
111
124
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ensureLoggableError } from '@platformatic/foundation'
|
|
2
|
+
import { getConfig, getPrometheus, hasField } from '@platformatic/globals'
|
|
2
3
|
import { ReadableStream } from 'node:stream/web'
|
|
3
4
|
import {
|
|
4
5
|
createPlatformaticLogger,
|
|
@@ -46,7 +47,8 @@ export class CacheHandler {
|
|
|
46
47
|
ensureRedis()
|
|
47
48
|
ensureMsgpackr()
|
|
48
49
|
|
|
49
|
-
const
|
|
50
|
+
const platformaticConfig = getConfig()
|
|
51
|
+
const baseConfig = platformaticConfig.cache
|
|
50
52
|
const resolvedConfig = options.configKey ? { ...baseConfig, ...baseConfig[options.configKey] } : baseConfig
|
|
51
53
|
|
|
52
54
|
this.#config ??= resolvedConfig
|
|
@@ -72,7 +74,7 @@ export class CacheHandler {
|
|
|
72
74
|
throw new Error('Please provide a the "store" option.')
|
|
73
75
|
}
|
|
74
76
|
|
|
75
|
-
if (
|
|
77
|
+
if (hasField('prometheus')) {
|
|
76
78
|
this.#registerMetrics()
|
|
77
79
|
}
|
|
78
80
|
}
|
|
@@ -255,7 +257,7 @@ export class CacheHandler {
|
|
|
255
257
|
}
|
|
256
258
|
|
|
257
259
|
#registerMetrics () {
|
|
258
|
-
const { client, registry } =
|
|
260
|
+
const { client, registry } = getPrometheus()
|
|
259
261
|
|
|
260
262
|
this.#cacheHitMetric =
|
|
261
263
|
registry.getSingleMetric(this.#cacheHitMetricDef.name) ??
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ensureLoggableError } from '@platformatic/foundation'
|
|
2
|
+
import { getConfig, getPrometheus, hasField } from '@platformatic/globals'
|
|
2
3
|
import {
|
|
3
4
|
createPlatformaticLogger,
|
|
4
5
|
deserialize,
|
|
@@ -47,8 +48,10 @@ export class CacheHandler {
|
|
|
47
48
|
this.#subprefix = options.subprefix
|
|
48
49
|
this.#meta = options.meta
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
const platformaticConfig = getConfig({ throwOnMissing: false })
|
|
52
|
+
|
|
53
|
+
if (!this.#standalone && platformaticConfig) {
|
|
54
|
+
this.#config ??= platformaticConfig.cache
|
|
52
55
|
this.#logger ??= createPlatformaticLogger()
|
|
53
56
|
this.#store ??= getConnection(this.#config.url)
|
|
54
57
|
this.#maxTTL ??= this.#config.maxTTL
|
|
@@ -75,7 +78,7 @@ export class CacheHandler {
|
|
|
75
78
|
throw new Error('Please provide a the "store" option.')
|
|
76
79
|
}
|
|
77
80
|
|
|
78
|
-
if (
|
|
81
|
+
if (hasField('prometheus')) {
|
|
79
82
|
this.#registerMetrics()
|
|
80
83
|
}
|
|
81
84
|
}
|
|
@@ -286,7 +289,7 @@ export class CacheHandler {
|
|
|
286
289
|
}
|
|
287
290
|
|
|
288
291
|
#registerMetrics () {
|
|
289
|
-
const { client, registry } =
|
|
292
|
+
const { client, registry } = getPrometheus()
|
|
290
293
|
|
|
291
294
|
this.#cacheHitMetric =
|
|
292
295
|
registry.getSingleMetric(CACHE_HIT_METRIC.name) ??
|
package/lib/capability.js
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
importFile,
|
|
10
10
|
resolvePackageViaCJS
|
|
11
11
|
} from '@platformatic/basic'
|
|
12
|
+
import { getEvents, updateGlobals } from '@platformatic/globals'
|
|
12
13
|
import { ChildProcess } from 'node:child_process'
|
|
13
14
|
import { once } from 'node:events'
|
|
14
15
|
import { readFile, writeFile } from 'node:fs/promises'
|
|
@@ -115,7 +116,8 @@ export class NextCapability extends BaseCapability {
|
|
|
115
116
|
return this.stopCommand()
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
|
|
119
|
+
const events = getEvents()
|
|
120
|
+
events.emit('plt:next:close')
|
|
119
121
|
|
|
120
122
|
if (this.isProduction && this.#server) {
|
|
121
123
|
await this._closeServer(this.#server)
|
|
@@ -339,7 +341,7 @@ export class NextCapability extends BaseCapability {
|
|
|
339
341
|
|
|
340
342
|
async #startProductionNext () {
|
|
341
343
|
try {
|
|
342
|
-
|
|
344
|
+
updateGlobals({ config: this.config })
|
|
343
345
|
await this.childManager.inject()
|
|
344
346
|
const { nextStart } = await importFile(resolvePath(this.#next, './dist/cli/next-start.js'))
|
|
345
347
|
|
package/lib/image-optimizer.js
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
} from '@platformatic/basic'
|
|
10
10
|
import { cleanBasePath } from '@platformatic/basic/lib/utils.js'
|
|
11
11
|
import { ensureLoggableError } from '@platformatic/foundation/lib/errors.js'
|
|
12
|
+
import { getEvents } from '@platformatic/globals'
|
|
12
13
|
import { createQueue } from '@platformatic/image-optimizer'
|
|
13
14
|
import { FileStorage, MemoryStorage, RedisStorage } from '@platformatic/job-queue'
|
|
14
15
|
import inject from 'light-my-request'
|
|
@@ -123,7 +124,8 @@ export class NextImageOptimizerCapability extends BaseCapability {
|
|
|
123
124
|
await super.stop()
|
|
124
125
|
await this.#queue?.stop()
|
|
125
126
|
|
|
126
|
-
|
|
127
|
+
const events = getEvents()
|
|
128
|
+
events.emit('plt:next:close')
|
|
127
129
|
|
|
128
130
|
if (!this.#app || !this.#server?.listening) {
|
|
129
131
|
return
|
package/lib/loader-next-15.cjs
CHANGED
|
@@ -15,10 +15,11 @@ const {
|
|
|
15
15
|
variableDeclarator
|
|
16
16
|
} = require('@babel/types')
|
|
17
17
|
const { transformSync } = require('amaro')
|
|
18
|
+
const { getConfig, getRoot } = require('@platformatic/globals')
|
|
18
19
|
|
|
19
20
|
const originalReadFile = fsPromises.readFile
|
|
20
21
|
const originalReadFileSync = fs.readFileSync
|
|
21
|
-
const targetFile = resolve(fileURLToPath(
|
|
22
|
+
const targetFile = resolve(fileURLToPath(getRoot()), 'next.config.ts')
|
|
22
23
|
|
|
23
24
|
const originalId = '__pltEnhanceNextConfig'
|
|
24
25
|
|
|
@@ -122,8 +123,9 @@ function restoreReadMethods () {
|
|
|
122
123
|
|
|
123
124
|
async function patchNextConfigTS (contents) {
|
|
124
125
|
let transformed = contents
|
|
126
|
+
const config = getConfig()
|
|
125
127
|
|
|
126
|
-
if (!
|
|
128
|
+
if (!config.next?.useExperimentalAdapter) {
|
|
127
129
|
const { code } = transformSync(contents.toString('utf-8'), { mode: 'strip-only' })
|
|
128
130
|
const transformer = detectFormat(code) === 'esm' ? transformESM : transformCJS
|
|
129
131
|
transformed = transformer(code)
|
|
@@ -157,7 +159,9 @@ fs.readFileSync = function readAndPatchNextConfigTSSync (url, options) {
|
|
|
157
159
|
return contents
|
|
158
160
|
}
|
|
159
161
|
|
|
160
|
-
|
|
162
|
+
const config = getConfig()
|
|
163
|
+
|
|
164
|
+
if (config.next?.useExperimentalAdapter) {
|
|
161
165
|
return contents
|
|
162
166
|
}
|
|
163
167
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/next",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.56.0",
|
|
4
4
|
"description": "Platformatic Next.js Capability",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -25,8 +25,9 @@
|
|
|
25
25
|
"light-my-request": "^6.0.0",
|
|
26
26
|
"msgpackr": "^1.11.2",
|
|
27
27
|
"semver": "^7.6.3",
|
|
28
|
-
"@platformatic/
|
|
29
|
-
"@platformatic/
|
|
28
|
+
"@platformatic/basic": "3.56.0",
|
|
29
|
+
"@platformatic/foundation": "3.56.0",
|
|
30
|
+
"@platformatic/globals": "3.56.0"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
33
|
"@fastify/reply-from": "^12.0.0",
|
|
@@ -43,8 +44,8 @@
|
|
|
43
44
|
"next": "^16.1.0",
|
|
44
45
|
"typescript": "^5.5.4",
|
|
45
46
|
"ws": "^8.18.0",
|
|
46
|
-
"@platformatic/gateway": "3.
|
|
47
|
-
"@platformatic/service": "3.
|
|
47
|
+
"@platformatic/gateway": "3.56.0",
|
|
48
|
+
"@platformatic/service": "3.56.0"
|
|
48
49
|
},
|
|
49
50
|
"engines": {
|
|
50
51
|
"node": ">=22.19.0"
|
package/schema.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$id": "https://schemas.platformatic.dev/@platformatic/next/3.
|
|
2
|
+
"$id": "https://schemas.platformatic.dev/@platformatic/next/3.56.0.json",
|
|
3
3
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
4
|
"title": "Platformatic Next.js Config",
|
|
5
5
|
"type": "object",
|
|
@@ -606,6 +606,28 @@
|
|
|
606
606
|
"type": "string"
|
|
607
607
|
}
|
|
608
608
|
]
|
|
609
|
+
},
|
|
610
|
+
"bufferPoolSize": {
|
|
611
|
+
"anyOf": [
|
|
612
|
+
{
|
|
613
|
+
"type": "number",
|
|
614
|
+
"minimum": 0
|
|
615
|
+
},
|
|
616
|
+
{
|
|
617
|
+
"type": "string"
|
|
618
|
+
}
|
|
619
|
+
]
|
|
620
|
+
},
|
|
621
|
+
"defaultHighWaterMark": {
|
|
622
|
+
"anyOf": [
|
|
623
|
+
{
|
|
624
|
+
"type": "number",
|
|
625
|
+
"minimum": 0
|
|
626
|
+
},
|
|
627
|
+
{
|
|
628
|
+
"type": "string"
|
|
629
|
+
}
|
|
630
|
+
]
|
|
609
631
|
}
|
|
610
632
|
},
|
|
611
633
|
"additionalProperties": false
|
|
@@ -1315,6 +1337,30 @@
|
|
|
1315
1337
|
}
|
|
1316
1338
|
],
|
|
1317
1339
|
"default": 268435456
|
|
1340
|
+
},
|
|
1341
|
+
"bufferPoolSize": {
|
|
1342
|
+
"anyOf": [
|
|
1343
|
+
{
|
|
1344
|
+
"type": "number",
|
|
1345
|
+
"minimum": 0
|
|
1346
|
+
},
|
|
1347
|
+
{
|
|
1348
|
+
"type": "string"
|
|
1349
|
+
}
|
|
1350
|
+
],
|
|
1351
|
+
"default": 262144
|
|
1352
|
+
},
|
|
1353
|
+
"defaultHighWaterMark": {
|
|
1354
|
+
"anyOf": [
|
|
1355
|
+
{
|
|
1356
|
+
"type": "number",
|
|
1357
|
+
"minimum": 0
|
|
1358
|
+
},
|
|
1359
|
+
{
|
|
1360
|
+
"type": "string"
|
|
1361
|
+
}
|
|
1362
|
+
],
|
|
1363
|
+
"default": 262144
|
|
1318
1364
|
}
|
|
1319
1365
|
},
|
|
1320
1366
|
"additionalProperties": false
|
|
@@ -1597,6 +1643,18 @@
|
|
|
1597
1643
|
"default": "applicationId",
|
|
1598
1644
|
"description": "The label name to use for the application identifier in metrics (e.g., applicationId, serviceId)"
|
|
1599
1645
|
},
|
|
1646
|
+
"httpClientMetrics": {
|
|
1647
|
+
"anyOf": [
|
|
1648
|
+
{
|
|
1649
|
+
"type": "boolean"
|
|
1650
|
+
},
|
|
1651
|
+
{
|
|
1652
|
+
"type": "string"
|
|
1653
|
+
}
|
|
1654
|
+
],
|
|
1655
|
+
"default": false,
|
|
1656
|
+
"description": "Enable outgoing HTTP client request duration metrics"
|
|
1657
|
+
},
|
|
1600
1658
|
"readiness": {
|
|
1601
1659
|
"anyOf": [
|
|
1602
1660
|
{
|
|
@@ -2328,6 +2386,28 @@
|
|
|
2328
2386
|
"type": "string"
|
|
2329
2387
|
}
|
|
2330
2388
|
]
|
|
2389
|
+
},
|
|
2390
|
+
"bufferPoolSize": {
|
|
2391
|
+
"anyOf": [
|
|
2392
|
+
{
|
|
2393
|
+
"type": "number",
|
|
2394
|
+
"minimum": 0
|
|
2395
|
+
},
|
|
2396
|
+
{
|
|
2397
|
+
"type": "string"
|
|
2398
|
+
}
|
|
2399
|
+
]
|
|
2400
|
+
},
|
|
2401
|
+
"defaultHighWaterMark": {
|
|
2402
|
+
"anyOf": [
|
|
2403
|
+
{
|
|
2404
|
+
"type": "number",
|
|
2405
|
+
"minimum": 0
|
|
2406
|
+
},
|
|
2407
|
+
{
|
|
2408
|
+
"type": "string"
|
|
2409
|
+
}
|
|
2410
|
+
]
|
|
2331
2411
|
}
|
|
2332
2412
|
},
|
|
2333
2413
|
"additionalProperties": false
|