@platformatic/runtime 3.4.1 → 3.5.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.
Files changed (49) hide show
  1. package/README.md +1 -1
  2. package/config.d.ts +224 -77
  3. package/eslint.config.js +3 -5
  4. package/index.d.ts +73 -24
  5. package/index.js +173 -29
  6. package/lib/config.js +279 -197
  7. package/lib/errors.js +126 -34
  8. package/lib/generator.js +640 -0
  9. package/lib/logger.js +43 -41
  10. package/lib/management-api.js +109 -118
  11. package/lib/prom-server.js +202 -16
  12. package/lib/runtime.js +1963 -585
  13. package/lib/scheduler.js +119 -0
  14. package/lib/schema.js +22 -234
  15. package/lib/shared-http-cache.js +43 -0
  16. package/lib/upgrade.js +6 -8
  17. package/lib/utils.js +6 -61
  18. package/lib/version.js +7 -0
  19. package/lib/versions/v1.36.0.js +2 -4
  20. package/lib/versions/v1.5.0.js +2 -4
  21. package/lib/versions/v2.0.0.js +3 -5
  22. package/lib/versions/v3.0.0.js +16 -0
  23. package/lib/worker/controller.js +302 -0
  24. package/lib/worker/http-cache.js +171 -0
  25. package/lib/worker/interceptors.js +190 -10
  26. package/lib/worker/itc.js +146 -59
  27. package/lib/worker/main.js +220 -81
  28. package/lib/worker/messaging.js +182 -0
  29. package/lib/worker/round-robin-map.js +62 -0
  30. package/lib/worker/shared-context.js +22 -0
  31. package/lib/worker/symbols.js +14 -5
  32. package/package.json +47 -38
  33. package/schema.json +1383 -55
  34. package/help/compile.txt +0 -8
  35. package/help/help.txt +0 -5
  36. package/help/start.txt +0 -21
  37. package/index.test-d.ts +0 -41
  38. package/lib/build-server.js +0 -69
  39. package/lib/compile.js +0 -98
  40. package/lib/dependencies.js +0 -59
  41. package/lib/generator/README.md +0 -32
  42. package/lib/generator/errors.js +0 -10
  43. package/lib/generator/runtime-generator.d.ts +0 -37
  44. package/lib/generator/runtime-generator.js +0 -498
  45. package/lib/start.js +0 -190
  46. package/lib/worker/app.js +0 -278
  47. package/lib/worker/default-stackable.js +0 -33
  48. package/lib/worker/metrics.js +0 -122
  49. package/runtime.mjs +0 -54
package/index.js CHANGED
@@ -1,29 +1,173 @@
1
- 'use strict'
2
-
3
- const { buildServer } = require('./lib/build-server')
4
- const { compile } = require('./lib/compile')
5
- const errors = require('./lib/errors')
6
- const { platformaticRuntime, wrapConfigInRuntimeConfig } = require('./lib/config')
7
- const RuntimeGenerator = require('./lib/generator/runtime-generator')
8
- const { Runtime } = require('./lib/runtime')
9
- const { buildRuntime, start, startCommand } = require('./lib/start')
10
- const symbols = require('./lib/worker/symbols')
11
- const { loadConfig, getRuntimeLogsDir } = require('./lib/utils')
12
-
13
- const platformaticVersion = require('./package.json').version
14
-
15
- module.exports.buildServer = buildServer
16
- module.exports.buildRuntime = buildRuntime
17
- module.exports.compile = compile
18
- module.exports.errors = errors
19
- module.exports.Generator = RuntimeGenerator
20
- module.exports.getRuntimeLogsDir = getRuntimeLogsDir
21
- module.exports.loadConfig = loadConfig
22
- module.exports.platformaticRuntime = platformaticRuntime
23
- module.exports.schema = platformaticRuntime.schema
24
- module.exports.start = start
25
- module.exports.startCommand = startCommand
26
- module.exports.symbols = symbols
27
- module.exports.Runtime = Runtime
28
- module.exports.wrapConfigInRuntimeConfig = wrapConfigInRuntimeConfig
29
- module.exports.version = platformaticVersion
1
+ import { resolve, validationOptions } from '@platformatic/basic'
2
+ import {
3
+ abstractLogger,
4
+ ensureLoggableError,
5
+ extractModuleFromSchemaUrl,
6
+ findRuntimeConfigurationFile,
7
+ kMetadata,
8
+ loadConfigurationModule,
9
+ loadConfiguration as utilsLoadConfiguration
10
+ } from '@platformatic/foundation'
11
+ import closeWithGrace from 'close-with-grace'
12
+ import inspector from 'node:inspector'
13
+ import { transform, wrapInRuntimeConfig } from './lib/config.js'
14
+ import { NodeInspectorFlagsNotSupportedError } from './lib/errors.js'
15
+ import { Runtime } from './lib/runtime.js'
16
+ import { schema } from './lib/schema.js'
17
+ import { upgrade } from './lib/upgrade.js'
18
+
19
+ async function restartRuntime (runtime) {
20
+ runtime.logger.info('Received SIGUSR2, restarting all applications ...')
21
+
22
+ try {
23
+ await runtime.restart()
24
+ } catch (err) {
25
+ runtime.logger.error({ err: ensureLoggableError(err) }, 'Failed to restart applications.')
26
+ }
27
+ }
28
+
29
+ function handleSignal (runtime, config) {
30
+ // The very first time we add a listener for SIGUSR2,
31
+ // ignore it since it comes from close-with-grace and we want to use to restart the runtime
32
+ function filterCloseWithGraceSIGUSR2 (event, listener) {
33
+ if (event === 'SIGUSR2') {
34
+ process.removeListener('SIGUSR2', listener)
35
+ process.removeListener('newListener', filterCloseWithGraceSIGUSR2)
36
+ }
37
+ }
38
+
39
+ process.on('newListener', filterCloseWithGraceSIGUSR2)
40
+
41
+ const cwg = closeWithGrace({ delay: config.gracefulShutdown?.runtime ?? 10000 }, async event => {
42
+ if (event.err instanceof Error) {
43
+ console.error(event.err)
44
+ }
45
+ await runtime.close()
46
+ })
47
+
48
+ /* c8 ignore next 3 */
49
+ const restartListener = restartRuntime.bind(null, runtime)
50
+ process.on('SIGUSR2', restartListener)
51
+
52
+ runtime.on('closed', () => {
53
+ process.removeListener('SIGUSR2', restartListener)
54
+ cwg.uninstall()
55
+ })
56
+ }
57
+
58
+ export async function loadConfiguration (configOrRoot, sourceOrConfig, context) {
59
+ const { root, source } = await resolve(configOrRoot, sourceOrConfig, 'runtime')
60
+
61
+ // First of all, load the configuration without any validation
62
+ const config = await utilsLoadConfiguration(source)
63
+ const mod = extractModuleFromSchemaUrl(config)
64
+ if (mod?.module !== '@platformatic/runtime') {
65
+ return wrapInRuntimeConfig(config, context)
66
+ }
67
+
68
+ return utilsLoadConfiguration(source, context?.schema ?? schema, {
69
+ validationOptions,
70
+ transform,
71
+ upgrade,
72
+ replaceEnv: true,
73
+ root,
74
+ ...context
75
+ })
76
+ }
77
+
78
+ export async function loadApplicationsCommands () {
79
+ const applications = {}
80
+ const commands = {}
81
+ const help = {}
82
+
83
+ let config
84
+ try {
85
+ const file = await findRuntimeConfigurationFile(abstractLogger, process.cwd(), null, false, false)
86
+
87
+ /* c8 ignore next 3 - Hard to test */
88
+ if (!file) {
89
+ throw new Error('No runtime configuration file found.')
90
+ }
91
+
92
+ config = await loadConfiguration(file)
93
+
94
+ /* c8 ignore next 3 - Hard to test */
95
+ if (!config) {
96
+ throw new Error('No runtime configuration file found.')
97
+ }
98
+ } catch {
99
+ return { applications, commands, help }
100
+ }
101
+
102
+ for (const application of config.applications) {
103
+ try {
104
+ const applicationConfig = await utilsLoadConfiguration(application.config)
105
+ const pkg = await loadConfigurationModule(application.path, applicationConfig)
106
+
107
+ if (pkg.createCommands) {
108
+ const definition = await pkg.createCommands(application.id)
109
+ for (const command of Object.keys(definition.commands)) {
110
+ applications[command] = application
111
+ }
112
+
113
+ Object.assign(commands, definition.commands)
114
+ Object.assign(help, definition.help)
115
+ }
116
+ /* c8 ignore next 3 - Hard to test */
117
+ } catch {
118
+ // No-op, ignore the application
119
+ }
120
+ }
121
+
122
+ return { applications, commands, help }
123
+ }
124
+
125
+ export async function create (configOrRoot, sourceOrConfig, context) {
126
+ const config = await loadConfiguration(configOrRoot, sourceOrConfig, context)
127
+
128
+ if (inspector.url() && !config[kMetadata].env.VSCODE_INSPECTOR_OPTIONS) {
129
+ throw new NodeInspectorFlagsNotSupportedError()
130
+ }
131
+
132
+ let runtime = new Runtime(config, context)
133
+ handleSignal(runtime, config)
134
+
135
+ // Handle port handling
136
+ if (context?.start) {
137
+ let port = config.server?.port
138
+
139
+ while (true) {
140
+ try {
141
+ await runtime.start()
142
+ break
143
+ } catch (err) {
144
+ if ((err.code !== 'EADDRINUSE' && err.code !== 'EACCES') || context?.skipPortInUseHandling) {
145
+ throw err
146
+ }
147
+
148
+ await runtime.close()
149
+
150
+ // Get the actual port from the error message if original port was 0
151
+ if (!port) {
152
+ const mo = err.message.match(/ address already in use (.+)/)
153
+ const url = new URL(`http://${mo[1]}`)
154
+ port = Number(url.port)
155
+ }
156
+
157
+ config.server.port = ++port
158
+ runtime = new Runtime(config, context)
159
+ handleSignal(runtime, config)
160
+ }
161
+ }
162
+ }
163
+
164
+ return runtime
165
+ }
166
+
167
+ export { transform, wrapInRuntimeConfig } from './lib/config.js'
168
+ export * as errors from './lib/errors.js'
169
+ export { RuntimeGenerator as Generator, WrappedGenerator } from './lib/generator.js'
170
+ export { Runtime } from './lib/runtime.js'
171
+ export { schema } from './lib/schema.js'
172
+ export * from './lib/version.js'
173
+ export * as symbols from './lib/worker/symbols.js'