@platformatic/node 3.13.1 → 3.14.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
@@ -117,7 +117,20 @@ export interface PlatformaticNodeJsConfig {
117
117
  services?: {
118
118
  [k: string]: unknown;
119
119
  }[];
120
- workers?: number | string;
120
+ workers?:
121
+ | number
122
+ | string
123
+ | {
124
+ static?: number;
125
+ dynamic?: boolean;
126
+ minimum?: number;
127
+ maximum?: number;
128
+ total?: number;
129
+ maxMemory?: number;
130
+ cooldown?: number;
131
+ gracePeriod?: number;
132
+ [k: string]: unknown;
133
+ };
121
134
  workersRestartDelay?: number | string;
122
135
  logger?: {
123
136
  level: (
@@ -325,6 +338,37 @@ export interface PlatformaticNodeJsConfig {
325
338
  };
326
339
  plugins?: string[];
327
340
  timeout?: number | string;
341
+ /**
342
+ * Configuration for exporting metrics to an OTLP endpoint
343
+ */
344
+ otlpExporter?: {
345
+ /**
346
+ * Enable or disable OTLP metrics export
347
+ */
348
+ enabled?: boolean | string;
349
+ /**
350
+ * OTLP endpoint URL (e.g., http://collector:4318/v1/metrics)
351
+ */
352
+ endpoint: string;
353
+ /**
354
+ * Interval in milliseconds between metric pushes
355
+ */
356
+ interval?: number | string;
357
+ /**
358
+ * Additional HTTP headers for authentication
359
+ */
360
+ headers?: {
361
+ [k: string]: string;
362
+ };
363
+ /**
364
+ * Service name for OTLP resource attributes
365
+ */
366
+ serviceName?: string;
367
+ /**
368
+ * Service version for OTLP resource attributes
369
+ */
370
+ serviceVersion?: string;
371
+ };
328
372
  };
329
373
  telemetry?: {
330
374
  enabled?: boolean | string;
@@ -408,13 +452,28 @@ export interface PlatformaticNodeJsConfig {
408
452
  maxTotalMemory?: number;
409
453
  minWorkers?: number;
410
454
  maxWorkers?: number;
455
+ cooldownSec?: number;
456
+ gracePeriod?: number;
457
+ /**
458
+ * @deprecated
459
+ */
411
460
  scaleUpELU?: number;
461
+ /**
462
+ * @deprecated
463
+ */
412
464
  scaleDownELU?: number;
465
+ /**
466
+ * @deprecated
467
+ */
413
468
  timeWindowSec?: number;
469
+ /**
470
+ * @deprecated
471
+ */
414
472
  scaleDownTimeWindowSec?: number;
415
- cooldownSec?: number;
473
+ /**
474
+ * @deprecated
475
+ */
416
476
  scaleIntervalSec?: number;
417
- gracePeriod?: number;
418
477
  };
419
478
  inspectorOptions?: {
420
479
  host?: string;
package/lib/capability.js CHANGED
@@ -100,6 +100,7 @@ export class NodeCapability extends BaseCapability {
100
100
  #isKoa
101
101
  #appClose
102
102
  #useHttpForDispatch
103
+ #factory
103
104
 
104
105
  constructor (root, config, context) {
105
106
  super('nodejs', version, root, config, context)
@@ -156,15 +157,15 @@ export class NodeCapability extends BaseCapability {
156
157
  this.#module = this.#module.default || this.#module
157
158
 
158
159
  // Deal with application
159
- const factory = ['build', 'create'].find(f => typeof this.#module[f] === 'function')
160
+ this.#factory = ['build', 'create'].find(f => typeof this.#module[f] === 'function')
160
161
  this.#appClose = this.#module['close']
161
162
 
162
163
  if (this.#hasServer()) {
163
- if (factory) {
164
+ if (this.#factory) {
164
165
  // We have build function, this Capability will not use HTTP unless it is the entrypoint
165
166
  serverPromise.cancel()
166
167
 
167
- this.#app = await this.#module[factory]()
168
+ this.#app = await this.#module[this.#factory]()
168
169
  this.#isFastify = isFastify(this.#app)
169
170
  this.#isKoa = isKoa(this.#app)
170
171
 
@@ -194,12 +195,21 @@ export class NodeCapability extends BaseCapability {
194
195
  }
195
196
 
196
197
  #hasServer () {
197
- return this.config.node?.hasServer !== false && this.#module.hasServer !== false
198
+ return this.config.node?.hasServer !== false && this.#module?.hasServer !== false
198
199
  }
199
200
 
200
201
  async stop () {
201
202
  await super.stop()
202
203
 
204
+ // Emit the close event so that an application can handle it
205
+ const closeHandled = globalThis.platformatic.events.emit('close')
206
+
207
+ if (!this.#isFastify && !this.#appClose && !closeHandled) {
208
+ this.logger.warn(
209
+ `Please export a "close" function or register a "close" event handler in globalThis.platformatic.events for application "${this.applicationId}" to make sure resources have been closed properly and avoid exit timeouts.`
210
+ )
211
+ }
212
+
203
213
  if (this.status === 'starting') {
204
214
  await Unpromise.race([once(this, 'started'), once(this, 'start:error')])
205
215
  }
@@ -208,9 +218,14 @@ export class NodeCapability extends BaseCapability {
208
218
  return this.stopCommand()
209
219
  }
210
220
 
211
- // for no-server apps, we support custom close method
212
- if (this.#appClose && !this.#hasServer()) {
213
- return this.#appClose()
221
+ // If we have a close function, always invoke it
222
+ if (this.#appClose) {
223
+ await this.#appClose()
224
+ }
225
+
226
+ // for no-server apps, nothing else to do
227
+ if (!this.#hasServer()) {
228
+ return
214
229
  }
215
230
 
216
231
  // This is needed if the capability was subclassed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/node",
3
- "version": "3.13.1",
3
+ "version": "3.14.0",
4
4
  "description": "Platformatic Node.js Capability",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -18,9 +18,9 @@
18
18
  "@watchable/unpromise": "^1.0.2",
19
19
  "json5": "^2.2.3",
20
20
  "light-my-request": "^6.0.0",
21
- "@platformatic/basic": "3.13.1",
22
- "@platformatic/generators": "3.13.1",
23
- "@platformatic/foundation": "3.13.1"
21
+ "@platformatic/foundation": "3.14.0",
22
+ "@platformatic/basic": "3.14.0",
23
+ "@platformatic/generators": "3.14.0"
24
24
  },
25
25
  "devDependencies": {
26
26
  "cleaner-spec-reporter": "^0.5.0",
@@ -32,8 +32,8 @@
32
32
  "neostandard": "^0.12.0",
33
33
  "tsx": "^4.19.0",
34
34
  "typescript": "^5.5.4",
35
- "@platformatic/service": "3.13.1",
36
- "@platformatic/gateway": "3.13.1"
35
+ "@platformatic/gateway": "3.14.0",
36
+ "@platformatic/service": "3.14.0"
37
37
  },
38
38
  "engines": {
39
39
  "node": ">=22.19.0"
package/schema.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://schemas.platformatic.dev/@platformatic/node/3.13.1.json",
2
+ "$id": "https://schemas.platformatic.dev/@platformatic/node/3.14.0.json",
3
3
  "$schema": "http://json-schema.org/draft-07/schema#",
4
4
  "title": "Platformatic Node.js Config",
5
5
  "type": "object",
@@ -429,11 +429,27 @@
429
429
  "workers": {
430
430
  "anyOf": [
431
431
  {
432
- "type": "number",
433
- "minimum": 1
432
+ "type": "number"
434
433
  },
435
434
  {
436
435
  "type": "string"
436
+ },
437
+ {
438
+ "type": "object",
439
+ "properties": {
440
+ "static": {
441
+ "type": "number",
442
+ "minimum": 1
443
+ },
444
+ "minimum": {
445
+ "type": "number",
446
+ "minimum": 1
447
+ },
448
+ "maximum": {
449
+ "type": "number",
450
+ "minimum": 0
451
+ }
452
+ }
437
453
  }
438
454
  ]
439
455
  },
@@ -654,6 +670,43 @@
654
670
  },
655
671
  {
656
672
  "type": "string"
673
+ },
674
+ {
675
+ "type": "object",
676
+ "properties": {
677
+ "static": {
678
+ "type": "number",
679
+ "minimum": 1
680
+ },
681
+ "dynamic": {
682
+ "type": "boolean",
683
+ "default": false
684
+ },
685
+ "minimum": {
686
+ "type": "number",
687
+ "minimum": 1
688
+ },
689
+ "maximum": {
690
+ "type": "number",
691
+ "minimum": 0
692
+ },
693
+ "total": {
694
+ "type": "number",
695
+ "minimum": 1
696
+ },
697
+ "maxMemory": {
698
+ "type": "number",
699
+ "minimum": 0
700
+ },
701
+ "cooldown": {
702
+ "type": "number",
703
+ "minimum": 0
704
+ },
705
+ "gracePeriod": {
706
+ "type": "number",
707
+ "minimum": 0
708
+ }
709
+ }
657
710
  }
658
711
  ]
659
712
  },
@@ -1430,6 +1483,58 @@
1430
1483
  }
1431
1484
  ],
1432
1485
  "default": 10000
1486
+ },
1487
+ "otlpExporter": {
1488
+ "type": "object",
1489
+ "description": "Configuration for exporting metrics to an OTLP endpoint",
1490
+ "properties": {
1491
+ "enabled": {
1492
+ "anyOf": [
1493
+ {
1494
+ "type": "boolean"
1495
+ },
1496
+ {
1497
+ "type": "string"
1498
+ }
1499
+ ],
1500
+ "description": "Enable or disable OTLP metrics export"
1501
+ },
1502
+ "endpoint": {
1503
+ "type": "string",
1504
+ "description": "OTLP endpoint URL (e.g., http://collector:4318/v1/metrics)"
1505
+ },
1506
+ "interval": {
1507
+ "anyOf": [
1508
+ {
1509
+ "type": "integer"
1510
+ },
1511
+ {
1512
+ "type": "string"
1513
+ }
1514
+ ],
1515
+ "default": 60000,
1516
+ "description": "Interval in milliseconds between metric pushes"
1517
+ },
1518
+ "headers": {
1519
+ "type": "object",
1520
+ "additionalProperties": {
1521
+ "type": "string"
1522
+ },
1523
+ "description": "Additional HTTP headers for authentication"
1524
+ },
1525
+ "serviceName": {
1526
+ "type": "string",
1527
+ "description": "Service name for OTLP resource attributes"
1528
+ },
1529
+ "serviceVersion": {
1530
+ "type": "string",
1531
+ "description": "Service version for OTLP resource attributes"
1532
+ }
1533
+ },
1534
+ "required": [
1535
+ "endpoint"
1536
+ ],
1537
+ "additionalProperties": false
1433
1538
  }
1434
1539
  },
1435
1540
  "additionalProperties": false
@@ -1589,35 +1694,40 @@
1589
1694
  "type": "number",
1590
1695
  "minimum": 1
1591
1696
  },
1697
+ "cooldownSec": {
1698
+ "type": "number",
1699
+ "minimum": 0
1700
+ },
1701
+ "gracePeriod": {
1702
+ "type": "number",
1703
+ "minimum": 0
1704
+ },
1592
1705
  "scaleUpELU": {
1593
1706
  "type": "number",
1594
1707
  "minimum": 0,
1595
- "maximum": 1
1708
+ "maximum": 1,
1709
+ "deprecated": true
1596
1710
  },
1597
1711
  "scaleDownELU": {
1598
1712
  "type": "number",
1599
1713
  "minimum": 0,
1600
- "maximum": 1
1714
+ "maximum": 1,
1715
+ "deprecated": true
1601
1716
  },
1602
1717
  "timeWindowSec": {
1603
1718
  "type": "number",
1604
- "minimum": 0
1719
+ "minimum": 0,
1720
+ "deprecated": true
1605
1721
  },
1606
1722
  "scaleDownTimeWindowSec": {
1607
1723
  "type": "number",
1608
- "minimum": 0
1609
- },
1610
- "cooldownSec": {
1611
- "type": "number",
1612
- "minimum": 0
1724
+ "minimum": 0,
1725
+ "deprecated": true
1613
1726
  },
1614
1727
  "scaleIntervalSec": {
1615
1728
  "type": "number",
1616
- "minimum": 0
1617
- },
1618
- "gracePeriod": {
1619
- "type": "number",
1620
- "minimum": 0
1729
+ "minimum": 0,
1730
+ "deprecated": true
1621
1731
  }
1622
1732
  },
1623
1733
  "additionalProperties": false