@platformatic/runtime 1.53.3 → 2.0.0-alpha.10

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 (178) hide show
  1. package/config.d.ts +284 -0
  2. package/eslint.config.js +8 -0
  3. package/fixtures/botched-start/platformatic.runtime.json +1 -1
  4. package/fixtures/botched-start/services/a/platformatic.service.json +1 -1
  5. package/fixtures/composerApp/platformatic.composer.json +1 -1
  6. package/fixtures/configs/{monorepo-hotreload.json → invalid-autoload-with-services.json} +8 -8
  7. package/fixtures/configs/invalid-entrypoint.json +1 -1
  8. package/fixtures/configs/invalid-schema-type.config.json +1 -1
  9. package/fixtures/configs/missing-property.config.json +1 -1
  10. package/fixtures/configs/missing-service-config.json +1 -1
  11. package/fixtures/configs/monorepo-composer-no-autoload.json +32 -0
  12. package/fixtures/configs/monorepo-composer.json +2 -2
  13. package/fixtures/configs/monorepo-create-cycle.json +2 -3
  14. package/fixtures/configs/monorepo-missing-dependencies.json +9 -0
  15. package/fixtures/configs/monorepo-no-cycles.json +2 -3
  16. package/fixtures/configs/monorepo-openapi.json +2 -2
  17. package/fixtures/configs/{hotreload.json → monorepo-watch-env.json} +2 -3
  18. package/fixtures/configs/monorepo-watch-single.json +12 -0
  19. package/fixtures/configs/monorepo-watch.json +26 -9
  20. package/fixtures/configs/monorepo-with-dependencies.json +2 -2
  21. package/fixtures/configs/{monorepo-client-without-id.json → monorepo-with-management-api-without-metrics.json} +5 -8
  22. package/fixtures/configs/monorepo-with-management-api.json +2 -3
  23. package/fixtures/configs/monorepo-with-metrics.json +1 -2
  24. package/fixtures/configs/monorepo.json +2 -3
  25. package/fixtures/configs/no-services.config.json +1 -1
  26. package/fixtures/configs/no-sources.config.json +1 -1
  27. package/fixtures/configs/service-throws-on-start.json +1 -1
  28. package/fixtures/configs/service-with-env-port.json +2 -3
  29. package/fixtures/configs/service-with-stdio.json +12 -0
  30. package/fixtures/configs/{monorepo-hotreload-env.json → watch.json} +2 -3
  31. package/fixtures/crash-on-bootstrap/platformatic.runtime.json +15 -0
  32. package/fixtures/crash-on-bootstrap/services/service-1/platformatic.service.json +14 -0
  33. package/fixtures/crash-on-bootstrap/services/service-1/plugin.js +5 -0
  34. package/fixtures/crash-on-bootstrap/services/service-2/platformatic.service.json +14 -0
  35. package/fixtures/crash-on-bootstrap/services/service-2/plugin.js +5 -0
  36. package/fixtures/dbApp/platformatic.db.json +1 -1
  37. package/fixtures/dbAppNoName/platformatic.db.json +1 -1
  38. package/fixtures/dbAppNoPackageJson/platformatic.db.json +1 -1
  39. package/fixtures/dbAppWithMigrationError/platformatic.db.json +1 -1
  40. package/fixtures/do-not-reload-dependencies/platformatic.service.json +1 -1
  41. package/fixtures/do-not-restart-on-crash/platformatic.runtime.json +3 -2
  42. package/fixtures/do-not-restart-on-crash/services/a/platformatic.service.json +1 -1
  43. package/fixtures/express/platformatic.runtime.json +1 -1
  44. package/fixtures/express/services/a/platformatic.service.json +1 -1
  45. package/fixtures/express/services/b/platformatic.service.json +1 -1
  46. package/fixtures/external-client/platformatic.service.json +1 -1
  47. package/fixtures/interceptors/idp.js +2 -2
  48. package/fixtures/interceptors/platformatic.runtime.json +1 -1
  49. package/fixtures/interceptors/services/a/platformatic.service.json +1 -1
  50. package/fixtures/interceptors-2/platformatic.runtime.json +1 -1
  51. package/fixtures/interceptors-2/services/a/platformatic.service.json +1 -1
  52. package/fixtures/leven/platformatic.runtime.json +2 -3
  53. package/fixtures/leven/services/deeply-spittle/platformatic.service.json +1 -1
  54. package/fixtures/leven/services/rainy-empire/platformatic.composer.json +1 -1
  55. package/fixtures/management-api/platformatic.json +8 -4
  56. package/fixtures/management-api/services/service-1/platformatic.json +1 -1
  57. package/fixtures/management-api/services/service-1/plugin.js +4 -3
  58. package/fixtures/management-api/services/service-2/platformatic.json +1 -1
  59. package/fixtures/management-api/services/service-db/platformatic.db.json +1 -1
  60. package/fixtures/management-api-custom-labels/platformatic.json +2 -3
  61. package/fixtures/management-api-custom-labels/services/service-1/platformatic.json +1 -1
  62. package/fixtures/management-api-custom-labels/services/service-1/plugin.js +4 -3
  63. package/fixtures/management-api-custom-labels/services/service-2/platformatic.json +1 -1
  64. package/fixtures/management-api-custom-labels/services/service-db/platformatic.db.json +1 -1
  65. package/fixtures/management-api-without-metrics/platformatic.json +3 -3
  66. package/fixtures/management-api-without-metrics/services/service-1/platformatic.json +1 -1
  67. package/fixtures/monorepo/composerApp/platformatic.composer.json +1 -2
  68. package/fixtures/monorepo/dbApp/platformatic.db.json +1 -1
  69. package/fixtures/monorepo/serviceApp/platformatic.service.json +3 -2
  70. package/fixtures/monorepo/serviceApp/with-logger/with-logger.cjs +2 -2
  71. package/fixtures/monorepo/serviceApp/with-logger/with-logger.d.ts +7 -7
  72. package/fixtures/monorepo/serviceAppWithLogger/platformatic.service.json +1 -1
  73. package/fixtures/monorepo/serviceAppWithLogger/plugin.js +12 -0
  74. package/fixtures/monorepo/serviceAppWithMultiplePlugins/platformatic.service.json +3 -2
  75. package/fixtures/monorepo-missing-dependencies/composer/platformatic.json +24 -0
  76. package/fixtures/monorepo-openapi/serviceAppWithoutOpenapi/platformatic.service.json +1 -1
  77. package/fixtures/monorepo-watch/service1/platformatic.service.json +1 -1
  78. package/fixtures/monorepo-with-dependencies/main/platformatic.json +1 -1
  79. package/fixtures/monorepo-with-dependencies/service-1/platformatic.json +1 -1
  80. package/fixtures/monorepo-with-dependencies/service-2/platformatic.json +1 -1
  81. package/fixtures/no-env.service.json +1 -1
  82. package/fixtures/preload/platformatic.runtime.json +1 -1
  83. package/fixtures/preload/services/a/platformatic.service.json +1 -1
  84. package/fixtures/prom-server/platformatic.json +2 -3
  85. package/fixtures/prom-server/services/service-1/platformatic.json +1 -1
  86. package/fixtures/prom-server/services/service-2/platformatic.json +1 -1
  87. package/fixtures/restart-on-crash/platformatic.runtime.json +1 -1
  88. package/fixtures/restart-on-crash/services/a/platformatic.service.json +1 -1
  89. package/fixtures/sample-runtime/package.json +1 -1
  90. package/fixtures/sample-runtime/platformatic.json +2 -3
  91. package/fixtures/sample-runtime/services/rival/package.json +1 -1
  92. package/fixtures/sample-runtime/services/rival/platformatic.json +1 -1
  93. package/fixtures/sample-runtime-with-2-services/package.json +1 -1
  94. package/fixtures/sample-runtime-with-2-services/platformatic.json +2 -3
  95. package/fixtures/sample-runtime-with-2-services/services/foobar/package.json +1 -1
  96. package/fixtures/sample-runtime-with-2-services/services/foobar/platformatic.json +1 -1
  97. package/fixtures/sample-runtime-with-2-services/services/rival/package.json +1 -1
  98. package/fixtures/sample-runtime-with-2-services/services/rival/platformatic.json +1 -1
  99. package/fixtures/server/logger-transport/platformatic.runtime.json +2 -3
  100. package/fixtures/server/logger-transport/services/echo/platformatic.service.json +1 -1
  101. package/fixtures/server/overrides-service/platformatic.runtime.json +2 -3
  102. package/fixtures/server/overrides-service/services/echo/platformatic.service.json +1 -1
  103. package/fixtures/server/runtime-server/platformatic.runtime.json +2 -3
  104. package/fixtures/server/runtime-server/services/echo/platformatic.service.json +1 -1
  105. package/fixtures/serviceAppThrowsOnStart/platformatic.service.json +1 -1
  106. package/fixtures/stackables/node_modules/foo/foo.js +2 -1
  107. package/fixtures/start-command-in-runtime.js +1 -1
  108. package/fixtures/stdio/platformatic.service.json +6 -0
  109. package/fixtures/stdio/plugin.js +24 -0
  110. package/fixtures/telemetry/platformatic.runtime.json +2 -3
  111. package/fixtures/telemetry/services/echo/platformatic.service.json +1 -1
  112. package/fixtures/telemetry/services/echo/routes/span.js +16 -2
  113. package/fixtures/telemetry/services/service-1/platformatic.service.json +19 -0
  114. package/fixtures/telemetry/services/service-1/routes/echo.js +7 -0
  115. package/fixtures/typescript/platformatic.runtime.json +2 -3
  116. package/fixtures/typescript/services/composer/platformatic.composer.json +1 -1
  117. package/fixtures/typescript/services/movies/global.d.ts +2 -3
  118. package/fixtures/typescript/services/movies/platformatic.db.json +1 -1
  119. package/fixtures/typescript/services/movies/types/Movie.d.ts +3 -3
  120. package/fixtures/typescript/services/movies/types/index.d.ts +6 -6
  121. package/fixtures/typescript/services/titles/client/client.d.ts +35 -35
  122. package/fixtures/typescript/services/titles/platformatic.service.json +1 -1
  123. package/fixtures/typescript-custom-flags/platformatic.runtime.json +2 -3
  124. package/fixtures/typescript-custom-flags/services/composer/platformatic.composer.json +1 -1
  125. package/fixtures/typescript-custom-flags/services/movies/global.d.ts +2 -3
  126. package/fixtures/typescript-custom-flags/services/movies/platformatic.db.json +1 -1
  127. package/fixtures/typescript-custom-flags/services/movies/types/Movie.d.ts +3 -3
  128. package/fixtures/typescript-custom-flags/services/movies/types/index.d.ts +6 -6
  129. package/fixtures/typescript-custom-flags/services/titles/client/client.d.ts +35 -35
  130. package/fixtures/typescript-custom-flags/services/titles/platformatic.service.json +1 -1
  131. package/fixtures/typescript-no-env/platformatic.runtime.json +2 -3
  132. package/fixtures/typescript-no-env/services/composer/platformatic.composer.json +1 -1
  133. package/fixtures/typescript-no-env/services/movies/global.d.ts +2 -3
  134. package/fixtures/typescript-no-env/services/movies/platformatic.db.json +1 -1
  135. package/fixtures/typescript-no-env/services/movies/types/Movie.d.ts +3 -3
  136. package/fixtures/typescript-no-env/services/movies/types/index.d.ts +6 -6
  137. package/fixtures/typescript-no-env/services/titles/client/client.d.ts +35 -35
  138. package/fixtures/typescript-no-env/services/titles/platformatic.service.json +1 -1
  139. package/index.d.ts +7 -8
  140. package/index.js +15 -10
  141. package/index.test-d.ts +10 -12
  142. package/lib/build-server.js +23 -15
  143. package/lib/compile.js +56 -13
  144. package/lib/config.js +27 -139
  145. package/lib/dependencies.js +59 -0
  146. package/lib/errors.js +6 -2
  147. package/lib/generator/errors.js +1 -1
  148. package/lib/generator/runtime-generator.d.ts +15 -15
  149. package/lib/generator/runtime-generator.js +81 -66
  150. package/lib/logger.js +55 -0
  151. package/lib/management-api.js +29 -44
  152. package/lib/prom-server.js +5 -9
  153. package/lib/runtime.js +1005 -0
  154. package/lib/schema.js +46 -44
  155. package/lib/start.js +49 -117
  156. package/lib/upgrade.js +4 -3
  157. package/lib/utils.js +49 -1
  158. package/lib/versions/v1.36.0.js +1 -1
  159. package/lib/versions/v1.5.0.js +1 -1
  160. package/lib/versions/v2.0.0.js +17 -0
  161. package/lib/worker/app.js +266 -0
  162. package/lib/worker/default-stackable.js +32 -0
  163. package/lib/worker/itc.js +149 -0
  164. package/lib/worker/main.js +129 -0
  165. package/lib/worker/metrics.js +106 -0
  166. package/lib/worker/symbols.js +7 -0
  167. package/package.json +44 -44
  168. package/runtime.mjs +11 -6
  169. package/schema.json +25 -13
  170. package/fixtures/monorepo/serviceApp/platformatic.service-client-without-id.json +0 -21
  171. package/lib/api-client.js +0 -497
  172. package/lib/api.js +0 -397
  173. package/lib/app.js +0 -365
  174. package/lib/load-config.js +0 -20
  175. package/lib/loader.mjs +0 -103
  176. package/lib/message-port-writable.js +0 -50
  177. package/lib/worker.js +0 -182
  178. /package/lib/{interceptors.js → worker/interceptors.js} +0 -0
package/lib/api.js DELETED
@@ -1,397 +0,0 @@
1
- 'use strict'
2
-
3
- const { once } = require('node:events')
4
- const { getGlobalDispatcher, setGlobalDispatcher } = require('undici')
5
- const { createFastifyInterceptor } = require('fastify-undici-dispatcher')
6
- const { PlatformaticApp } = require('./app')
7
- const errors = require('./errors')
8
- const { printSchema } = require('graphql')
9
- const { Bus } = require('@platformatic/bus')
10
-
11
- class RuntimeApi {
12
- #services
13
- #dispatcher
14
- #interceptor
15
- #logger
16
- #bus
17
-
18
- constructor (config, logger, loaderPort, composedInterceptors = []) {
19
- this.#services = new Map()
20
- this.#logger = logger
21
- this.#setupBus()
22
- const telemetryConfig = config.telemetry
23
- const metricsConfig = config.metrics
24
-
25
- for (let i = 0; i < config.services.length; ++i) {
26
- const service = config.services[i]
27
- const serviceTelemetryConfig = telemetryConfig
28
- ? {
29
- ...telemetryConfig,
30
- serviceName: `${telemetryConfig.serviceName}-${service.id}`
31
- }
32
- : null
33
-
34
- // If the service is an entrypoint and runtime server config is defined, use it.
35
- let serverConfig = null
36
- if (config.server && service.entrypoint) {
37
- serverConfig = config.server
38
- } else if (service.useHttp) {
39
- serverConfig = {
40
- port: 0,
41
- host: '127.0.0.1',
42
- keepAliveTimeout: 5000
43
- }
44
- }
45
-
46
- const app = new PlatformaticApp(service, loaderPort, logger, serviceTelemetryConfig, serverConfig, !!config.managementApi, metricsConfig)
47
-
48
- this.#services.set(service.id, app)
49
- }
50
-
51
- this.#interceptor = createFastifyInterceptor({
52
- // setting the domain here allows for fail-fast scenarios
53
- domain: '.plt.local'
54
- })
55
-
56
- composedInterceptors.unshift(this.#interceptor)
57
-
58
- this.#dispatcher = getGlobalDispatcher().compose(composedInterceptors)
59
- setGlobalDispatcher(this.#dispatcher)
60
- }
61
-
62
- async startListening (parentPort) {
63
- parentPort.on('message', async (message) => {
64
- const command = message?.command
65
- if (command) {
66
- if (command === 'plt:close') {
67
- // We close everything because they might be using
68
- // a FinalizationRegistry and it may stuck us in an infinite loop.
69
- // This is a workaround for
70
- // https://github.com/nodejs/node/issues/47748
71
- // https://github.com/nodejs/node/issues/49344
72
- // Remove once https://github.com/nodejs/node/pull/51290 is released
73
- // on all lines.
74
- // Likely to be removed when we drop support for Node.js 18.
75
- if (this.#dispatcher) {
76
- await this.#dispatcher.close()
77
- }
78
- setImmediate(process.exit) // Exit the worker thread.
79
- return
80
- }
81
-
82
- const res = await this.#executeCommand(message)
83
- parentPort.postMessage(res)
84
- return
85
- }
86
- await this.#handleProcessLevelEvent(message)
87
- })
88
- }
89
-
90
- async #handleProcessLevelEvent (message) {
91
- const services = [...this.#services.values()]
92
- await Promise.allSettled(services.map(async (service) => {
93
- await service.handleProcessLevelEvent(message)
94
- }))
95
-
96
- for (const service of services) {
97
- const serviceStatus = service.getStatus()
98
- if (
99
- serviceStatus === 'starting' ||
100
- serviceStatus === 'started'
101
- ) return
102
- }
103
-
104
- if (this.#dispatcher) {
105
- await this.#dispatcher.close()
106
- }
107
-
108
- process.exit() // Exit the worker thread if all services are stopped
109
- }
110
-
111
- async #executeCommand (message) {
112
- const { operationId, command, params } = message
113
- try {
114
- const res = await this.#runCommandHandler(command, params)
115
- return { operationId, error: null, data: JSON.stringify(res || null) }
116
- } catch (err) {
117
- return { operationId, error: err.message, code: err.code }
118
- }
119
- }
120
-
121
- async #runCommandHandler (command, params) {
122
- switch (command) {
123
- case 'plt:start-services':
124
- return this.startServices(params)
125
- case 'plt:stop-services':
126
- return this.stopServices(params)
127
- case 'plt:restart-services':
128
- return this.#restartServices(params)
129
- case 'plt:get-entrypoint-details':
130
- return this.#getEntrypointDetails(params)
131
- case 'plt:get-services':
132
- return this.#getServices(params)
133
- case 'plt:get-service-details':
134
- return this.#getServiceDetails(params)
135
- case 'plt:get-service-config':
136
- return this.#getServiceConfig(params)
137
- case 'plt:get-service-openapi-schema':
138
- return this.#getServiceOpenapiSchema(params)
139
- case 'plt:get-service-graphql-schema':
140
- return this.#getServiceGraphqlSchema(params)
141
- case 'plt:get-metrics':
142
- return this.#getMetrics(params)
143
- case 'plt:start-service':
144
- return this.#startService(params)
145
- case 'plt:stop-service':
146
- return this.#stopService(params)
147
- case 'plt:inject':
148
- return this.#inject(params)
149
- /* c8 ignore next 2 */
150
- default:
151
- throw new errors.UnknownRuntimeAPICommandError(command)
152
- }
153
- }
154
-
155
- async startServices () {
156
- let entrypointUrl = null
157
- for (const service of this.#services.values()) {
158
- await service.start()
159
-
160
- if (service.appConfig.entrypoint) {
161
- entrypointUrl = service.server.url
162
- }
163
-
164
- const serviceUrl = new URL(service.appConfig.localUrl)
165
- this.#interceptor.route(serviceUrl.host, service.server)
166
- }
167
- this.#bus.broadcast('runtime:services:started')
168
- return entrypointUrl
169
- }
170
-
171
- async stopServices () {
172
- const stopServiceReqs = []
173
- for (const service of this.#services.values()) {
174
- const serviceStatus = service.getStatus()
175
- if (serviceStatus === 'starting') {
176
- stopServiceReqs.push(
177
- once(service, 'start').then(() => service.stop())
178
- )
179
- }
180
- if (serviceStatus === 'started') {
181
- stopServiceReqs.push(service.stop())
182
- }
183
- }
184
- await Promise.all(stopServiceReqs)
185
- this.#bus.broadcast('runtime:services:stopped')
186
- }
187
-
188
- async #restartServices () {
189
- let entrypointUrl = null
190
- for (const service of this.#services.values()) {
191
- const serviceStatus = service.getStatus()
192
- if (serviceStatus === 'starting') {
193
- await once(service, 'start')
194
- }
195
-
196
- await service.restart(true)
197
-
198
- if (service.appConfig.entrypoint) {
199
- entrypointUrl = service.server.url
200
- }
201
-
202
- const serviceUrl = new URL(service.appConfig.localUrl)
203
- this.#interceptor.route(serviceUrl.host, service.server)
204
- }
205
- this.#bus.broadcast('runtime:services:restarted')
206
- return entrypointUrl
207
- }
208
-
209
- #getEntrypointDetails () {
210
- for (const service of this.#services.values()) {
211
- if (service.appConfig.entrypoint) {
212
- return this.#getServiceDetails({ id: service.appConfig.id })
213
- }
214
- }
215
- return null
216
- }
217
-
218
- #getServices () {
219
- const services = { services: [] }
220
-
221
- for (const service of this.#services.values()) {
222
- const serviceId = service.appConfig.id
223
- const serviceDetails = this.#getServiceDetails({ id: serviceId })
224
- if (serviceDetails.entrypoint) {
225
- services.entrypoint = serviceId
226
- }
227
- services.services.push(serviceDetails)
228
- }
229
-
230
- return services
231
- }
232
-
233
- #getServiceById (id) {
234
- const service = this.#services.get(id)
235
-
236
- if (!service) {
237
- const listOfServices = this.#getServices().services.map(svc => svc.id).join(', ')
238
- throw new errors.ServiceNotFoundError(listOfServices)
239
- }
240
-
241
- return service
242
- }
243
-
244
- #getServiceDetails ({ id }) {
245
- const service = this.#getServiceById(id)
246
- const status = service.getStatus()
247
-
248
- const type = service.config?.configType
249
- const version = service.config?.app?.configManagerConfig.version ?? null
250
- const { entrypoint, dependencies, localUrl } = service.appConfig
251
-
252
- const serviceDetails = {
253
- id,
254
- type,
255
- status,
256
- version,
257
- localUrl,
258
- entrypoint,
259
- dependencies
260
- }
261
-
262
- if (entrypoint) {
263
- serviceDetails.url = status === 'started' ? service.server.url : null
264
- }
265
-
266
- return serviceDetails
267
- }
268
-
269
- #getServiceConfig ({ id }) {
270
- const service = this.#getServiceById(id)
271
-
272
- const serviceStatus = service.getStatus()
273
- if (serviceStatus !== 'started') {
274
- throw new errors.ServiceNotStartedError(id)
275
- }
276
-
277
- return service.config.configManager.current
278
- }
279
-
280
- async #getServiceOpenapiSchema ({ id }) {
281
- const service = this.#getServiceById(id)
282
-
283
- const serviceStatus = service.getStatus()
284
- if (serviceStatus !== 'started') {
285
- throw new errors.ServiceNotStartedError(id)
286
- }
287
-
288
- if (typeof service.server.swagger !== 'function') {
289
- return null
290
- }
291
-
292
- try {
293
- await service.server.ready()
294
- const openapiSchema = service.server.swagger()
295
- return openapiSchema
296
- } catch (err) {
297
- throw new errors.FailedToRetrieveOpenAPISchemaError(id, err.message)
298
- }
299
- }
300
-
301
- async #getServiceGraphqlSchema ({ id }) {
302
- const service = this.#getServiceById(id)
303
-
304
- const serviceStatus = service.getStatus()
305
- if (serviceStatus !== 'started') {
306
- throw new errors.ServiceNotStartedError(id)
307
- }
308
-
309
- if (typeof service.server.graphql !== 'function') {
310
- return null
311
- }
312
-
313
- try {
314
- await service.server.ready()
315
- const graphqlSchema = printSchema(service.server.graphql.schema)
316
- return graphqlSchema
317
- } catch (err) {
318
- throw new errors.FailedToRetrieveGraphQLSchemaError(id, err.message)
319
- }
320
- }
321
-
322
- async #getMetrics ({ format }) {
323
- let metrics = null
324
-
325
- for (const service of this.#services.values()) {
326
- const serviceId = service.appConfig.id
327
- const serviceStatus = service.getStatus()
328
- if (serviceStatus !== 'started') {
329
- throw new errors.ServiceNotStartedError(serviceId)
330
- }
331
-
332
- const promRegister = service.server.metrics?.client?.register
333
-
334
- if (promRegister) {
335
- if (metrics === null) {
336
- metrics = format === 'json' ? [] : ''
337
- }
338
- if (format === 'json') {
339
- metrics.push(...await promRegister.getMetricsAsJSON())
340
- } else {
341
- const serviceMetrics = await promRegister.metrics()
342
- metrics += serviceMetrics
343
- }
344
- }
345
- }
346
-
347
- return { metrics }
348
- }
349
-
350
- async #startService ({ id }) {
351
- const service = this.#getServiceById(id)
352
- const serviceStatus = service.getStatus()
353
-
354
- if (serviceStatus === 'starting') {
355
- await once(service, 'start')
356
- } else {
357
- await service.start()
358
- }
359
- this.#bus.broadcast('runtime:service:started', id)
360
- }
361
-
362
- async #stopService ({ id }) {
363
- const service = this.#getServiceById(id)
364
- const serviceStatus = service.getStatus()
365
-
366
- if (serviceStatus === 'starting') {
367
- await once(service, 'start')
368
- }
369
-
370
- await service.stop()
371
- this.#bus.broadcast('runtime:service:stopped', id)
372
- }
373
-
374
- async #inject ({ id, injectParams }) {
375
- const service = this.#getServiceById(id)
376
-
377
- const serviceStatus = service.getStatus()
378
- if (serviceStatus !== 'started') {
379
- throw new errors.ServiceNotStartedError(id)
380
- }
381
-
382
- const res = await service.server.inject(injectParams)
383
- // Return only serializable properties.
384
- return {
385
- statusCode: res.statusCode,
386
- statusMessage: res.statusMessage,
387
- headers: res.headers,
388
- body: res.body
389
- }
390
- }
391
-
392
- #setupBus (config) {
393
- this.#bus = new Bus('$root')
394
- }
395
- }
396
-
397
- module.exports = RuntimeApi