@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 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 { config, nextVersion, logger } = globalThis.platformatic
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 { basePath, config } = globalThis.platformatic
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
- globalThis.platformatic.notifyConfig(nextConfig)
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
- globalThis.platformatic ??= {}
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
- let client = globalThis.platformatic.valkeyClients.get(url)
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
- globalThis.platformatic.valkeyClients.set(url, client)
65
+ valkeyClients.set(url, client)
56
66
 
57
- globalThis.platformatic.events.on('plt:next:close', () => {
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 loggerConfig = globalThis.platformatic?.config?.logger
77
+ const config = getConfig()
78
+ const loggerConfig = config.logger
67
79
 
68
80
  const pinoOptions = {
69
81
  ...loggerConfig,
70
- level: globalThis.platformatic?.logLevel ?? loggerConfig?.level ?? 'info'
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
- if (globalThis.platformatic?.applicationId) {
80
- pinoOptions.name = `cache:${globalThis.platformatic.applicationId}`
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: globalThis.platformatic?.workerId
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(globalThis.platformatic.root)
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: globalThis.platformatic.applicationId,
108
- workerId: globalThis.platformatic.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 baseConfig = globalThis.platformatic.config.cache
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 (globalThis.platformatic) {
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 } = globalThis.platformatic.prometheus
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
- if (!this.#standalone && globalThis.platformatic?.config) {
51
- this.#config ??= globalThis.platformatic.config.cache
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 (globalThis.platformatic?.prometheus) {
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 } = globalThis.platformatic.prometheus
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
- globalThis.platformatic.events.emit('plt:next:close')
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
- globalThis.platformatic.config = this.config
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
 
@@ -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
- globalThis.platformatic.events.emit('plt:next:close')
127
+ const events = getEvents()
128
+ events.emit('plt:next:close')
127
129
 
128
130
  if (!this.#app || !this.#server?.listening) {
129
131
  return
@@ -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(globalThis.platformatic.root), 'next.config.ts')
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 (!globalThis.platformatic.config.next?.useExperimentalAdapter) {
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
- if (globalThis.platformatic.config.next?.useExperimentalAdapter) {
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.54.0",
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/foundation": "3.54.0",
29
- "@platformatic/basic": "3.54.0"
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.54.0",
47
- "@platformatic/service": "3.54.0"
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.54.0.json",
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