wattpm 3.41.0 → 3.43.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/README.md CHANGED
@@ -19,18 +19,19 @@ Watt supports the stacks you love most, including [Next.js](https://nextjs.org/)
19
19
 
20
20
  ```bash
21
21
  # Create a new application
22
- npx wattpm@latest init
22
+ npx wattpm@latest create
23
23
 
24
24
  # Or install manually:
25
25
  npm install wattpm
26
26
  ```
27
27
 
28
28
  Follow our [Quick Start Guide](https://docs.platformatic.dev/docs/getting-started/quick-start)
29
- guide to get up and running with Platformatic.
29
+ to get up and running with Watt.
30
30
 
31
31
  ## Documentation
32
32
 
33
- - [Getting Started](https://docs.platformatic.dev/docs/getting-started/quick-start)
33
+ - [Quick Start](https://docs.platformatic.dev/docs/getting-started/quick-start)
34
+ - [Running Your Project in Watt](https://docs.platformatic.dev/docs/getting-started/port-your-app)
34
35
  - [Reference](https://docs.platformatic.dev/docs/reference/wattpm/overview)
35
36
  - [Guides](https://docs.platformatic.dev/docs/guides/build-modular-monolith)
36
37
 
package/index.js CHANGED
@@ -14,6 +14,7 @@ import { applicationsCommand, configCommand, envCommand, psCommand } from './lib
14
14
  import { metricsCommand } from './lib/commands/metrics.js'
15
15
  import { pprofCommand } from './lib/commands/pprof.js'
16
16
  import { replCommand } from './lib/commands/repl.js'
17
+ import { heapSnapshotCommand } from './lib/commands/snapshot.js'
17
18
  import { version } from './lib/schema.js'
18
19
 
19
20
  export * from './lib/schema.js'
@@ -116,6 +117,9 @@ export async function main () {
116
117
  case 'pprof':
117
118
  command = pprofCommand
118
119
  break
120
+ case 'heap-snapshot':
121
+ command = heapSnapshotCommand
122
+ break
119
123
  case 'repl':
120
124
  command = replCommand
121
125
  break
@@ -20,7 +20,8 @@ async function loadCommands () {
20
20
  'inject',
21
21
  'metrics',
22
22
  'pprof',
23
- 'repl'
23
+ 'repl',
24
+ 'snapshot'
24
25
  ]) {
25
26
  const category = await import(`./${file}.js`)
26
27
  Object.assign(commands, category.help)
@@ -168,20 +168,20 @@ export const help = {
168
168
  description: 'Profile CPU or heap usage of running application',
169
169
  options: [
170
170
  {
171
- name: '--type, -t',
171
+ usage: '--type, -t',
172
172
  description: 'Profile type: "cpu" for CPU wall time (default) or "heap" for heap memory'
173
173
  },
174
174
  {
175
- name: '--source-maps, -s',
175
+ usage: '--source-maps, -s',
176
176
  description: 'Enable source map support to resolve TypeScript and other transpiled code locations in profiles'
177
177
  },
178
178
  {
179
- name: '--node-modules-source-maps, -n',
179
+ usage: '--node-modules-source-maps, -n',
180
180
  description:
181
181
  'Comma-separated list of node_modules packages to load source maps from (e.g., "next,@next/next-server")'
182
182
  },
183
183
  {
184
- name: '--dir, -d',
184
+ usage: '--dir, -d',
185
185
  description:
186
186
  'Directory to save the profile data to (default: current working directory). Only used with "stop" subcommand.'
187
187
  }
@@ -0,0 +1,99 @@
1
+ import { RuntimeApiClient, getMatchingRuntime } from '@platformatic/control'
2
+ import { ensureLoggableError, logFatalError, parseArgs } from '@platformatic/foundation'
3
+ import { bold } from 'colorette'
4
+ import { createWriteStream } from 'node:fs'
5
+ import { resolve } from 'node:path'
6
+ import { pipeline } from 'node:stream/promises'
7
+
8
+ export async function heapSnapshotCommand (logger, args) {
9
+ const client = new RuntimeApiClient({ logger, socket: this.socket })
10
+
11
+ try {
12
+ const { positionals, values } = parseArgs(
13
+ args,
14
+ {
15
+ dir: { type: 'string', short: 'd' }
16
+ },
17
+ false
18
+ )
19
+
20
+ const [runtime, remainingPositionals] = await getMatchingRuntime(client, positionals)
21
+ const { applications: runtimeApplications } = await client.getRuntimeApplications(runtime.pid)
22
+
23
+ const applicationId = remainingPositionals[0]
24
+ const timestamp = new Date().toISOString().replace(/:/g, '-').replace(/\./g, '-')
25
+ const outputDir = values.dir || process.cwd()
26
+
27
+ if (applicationId) {
28
+ const application = runtimeApplications.find(s => s.id === applicationId)
29
+ if (!application) {
30
+ return logFatalError(logger, `Application not found: ${applicationId}`)
31
+ }
32
+
33
+ logger.info(`Taking heap snapshot for application ${bold(applicationId)}...`)
34
+ const body = await client.takeApplicationHeapSnapshot(runtime.pid, applicationId)
35
+ const filename = `heap-${applicationId}-${timestamp}.heapsnapshot`
36
+ const filepath = resolve(outputDir, filename)
37
+ await pipeline(body, createWriteStream(filepath))
38
+ logger.info(`Heap snapshot saved to ${bold(filepath)}`)
39
+ } else {
40
+ for (const application of runtimeApplications) {
41
+ try {
42
+ logger.info(`Taking heap snapshot for application ${bold(application.id)}...`)
43
+ const body = await client.takeApplicationHeapSnapshot(runtime.pid, application.id)
44
+ const filename = `heap-${application.id}-${timestamp}.heapsnapshot`
45
+ const filepath = resolve(outputDir, filename)
46
+ await pipeline(body, createWriteStream(filepath))
47
+ logger.info(`Heap snapshot saved to ${bold(filepath)}`)
48
+ } catch (error) {
49
+ logger.warn(`Failed to take heap snapshot for application ${application.id}: ${error.message}`)
50
+ }
51
+ }
52
+ }
53
+ } catch (error) {
54
+ if (error.code === 'PLT_CTR_RUNTIME_NOT_FOUND') {
55
+ return logFatalError(logger, 'Cannot find a matching runtime.')
56
+ } else if (error.message && error.message.includes('Application not found')) {
57
+ return logFatalError(logger, error.message)
58
+ } else {
59
+ return logFatalError(
60
+ logger,
61
+ { error: ensureLoggableError(error) },
62
+ `Cannot take heap snapshot: ${error.message}`
63
+ )
64
+ }
65
+ } finally {
66
+ await client.close()
67
+ }
68
+ }
69
+
70
+ export const help = {
71
+ 'heap-snapshot': {
72
+ usage: 'heap-snapshot [id] [application] [options]',
73
+ description: 'Take a heap snapshot of a running application',
74
+ options: [
75
+ {
76
+ usage: '--dir, -d',
77
+ description: 'Directory to save the heap snapshot to (default: current working directory)'
78
+ }
79
+ ],
80
+ args: [
81
+ {
82
+ name: 'id',
83
+ description:
84
+ 'The process ID or the name of the application (it can be omitted only if there is a single application running)'
85
+ },
86
+ {
87
+ name: 'application',
88
+ description: 'The application ID to snapshot (if omitted, snapshots all applications)'
89
+ }
90
+ ],
91
+ footer:
92
+ 'Takes a V8 heap snapshot of a running application and saves it as a .heapsnapshot file.\n' +
93
+ 'The resulting file can be loaded in Chrome DevTools (Memory tab) for analysis.\n\n' +
94
+ 'Examples:\n' +
95
+ ' wattpm heap-snapshot my-app # Take heap snapshot of my-app\n' +
96
+ ' wattpm heap-snapshot --dir=/tmp/snapshots my-app # Save to specific directory\n' +
97
+ ' wattpm heap-snapshot # Snapshot all applications'
98
+ }
99
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wattpm",
3
- "version": "3.41.0",
3
+ "version": "3.43.0",
4
4
  "description": "The Node.js Application Server",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -30,9 +30,9 @@
30
30
  "pino-pretty": "^13.0.0",
31
31
  "split2": "^4.2.0",
32
32
  "table": "^6.8.2",
33
- "@platformatic/foundation": "3.41.0",
34
- "@platformatic/runtime": "3.41.0",
35
- "@platformatic/control": "3.41.0"
33
+ "@platformatic/foundation": "3.43.0",
34
+ "@platformatic/control": "3.43.0",
35
+ "@platformatic/runtime": "3.43.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "cleaner-spec-reporter": "^0.5.0",
@@ -44,7 +44,7 @@
44
44
  "neostandard": "^0.12.0",
45
45
  "typescript": "^5.5.4",
46
46
  "undici": "^7.0.0",
47
- "@platformatic/node": "3.41.0"
47
+ "@platformatic/node": "3.43.0"
48
48
  },
49
49
  "engines": {
50
50
  "node": ">=22.19.0"
package/schema.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://schemas.platformatic.dev/wattpm/3.41.0.json",
2
+ "$id": "https://schemas.platformatic.dev/wattpm/3.43.0.json",
3
3
  "$schema": "http://json-schema.org/draft-07/schema#",
4
4
  "title": "Platformatic Runtime Config",
5
5
  "type": "object",
@@ -2751,6 +2751,9 @@
2751
2751
  "type": "string"
2752
2752
  }
2753
2753
  },
2754
+ "envfile": {
2755
+ "type": "string"
2756
+ },
2754
2757
  "sourceMaps": {
2755
2758
  "type": "boolean",
2756
2759
  "default": false