@platformatic/foundation 3.0.0-alpha.5 → 3.0.0-alpha.7

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/LICENSE CHANGED
@@ -136,7 +136,7 @@
136
136
  with Licensor regarding such Contributions.
137
137
 
138
138
  6. Trademarks. This License does not grant permission to use the trade
139
- names, trademarks, service marks, or product names of the Licensor,
139
+ names, trademarks, application marks, or product names of the Licensor,
140
140
  except as required for reasonable and customary use in describing the
141
141
  origin of the Work and reproducing the content of the NOTICE file.
142
142
 
package/index.d.ts CHANGED
@@ -3,8 +3,14 @@ import { JSONSchemaType } from 'ajv'
3
3
  import { EventEmitter } from 'node:events'
4
4
  import { Logger } from 'pino'
5
5
 
6
- // Configuration types
6
+ // Symbols
7
+ export declare const kCanceled: unique symbol
8
+ export declare const kFailedImport: unique symbol
9
+ export declare const kHandledError: unique symbol
7
10
  export declare const kMetadata: unique symbol
11
+ export declare const kTimeout: unique symbol
12
+
13
+ // Configuration types
8
14
  export declare const envVariablePattern: RegExp
9
15
  export declare const knownConfigurationFilesExtensions: string[]
10
16
  export declare const knownConfigurationFilesSchemas: RegExp[]
@@ -117,8 +123,13 @@ export declare const SchemaMustBeDefinedError: FastifyError
117
123
  export declare const ConfigurationDoesNotValidateAgainstSchemaError: FastifyError
118
124
 
119
125
  // Execution types
120
- export declare const kTimeout: unique symbol
121
126
  export declare function executeWithTimeout<T> (promise: Promise<T>, timeout: number, timeoutValue?: any): Promise<T>
127
+ export declare function executeInParallel<T, Args extends any[]> (
128
+ fn: (...args: Args) => Promise<T>,
129
+ args: Args[],
130
+ concurrency?: number,
131
+ throwOnRejections?: boolean
132
+ ): Promise<T[]>
122
133
 
123
134
  // File system types
124
135
  export declare function removeDotSlash (path: string): string
@@ -167,7 +178,7 @@ export declare function buildPinoTimestamp (timestamp: string): Function
167
178
  export declare function buildPinoOptions (
168
179
  loggerConfig: any,
169
180
  serverConfig: any,
170
- serviceId?: string,
181
+ applicationId?: string,
171
182
  workerId?: string,
172
183
  context?: any,
173
184
  root?: string
@@ -185,7 +196,6 @@ export declare const stdTimeFunctions: {
185
196
  }
186
197
 
187
198
  // Module types
188
- export declare const kFailedImport: unique symbol
189
199
  export declare const defaultPackageManager: string
190
200
 
191
201
  export declare function getLatestNpmVersion (pkg: string): Promise<string | null>
@@ -201,7 +211,7 @@ export declare function detectApplicationType (
201
211
  export declare function loadModule (require: NodeRequire, path: string): Promise<any>
202
212
 
203
213
  // Node types
204
- export declare function checkNodeVersionForServices (): void
214
+ export declare function checkNodeVersionForApplications (): void
205
215
  export declare const features: {
206
216
  node: {
207
217
  reusePort: boolean
@@ -234,7 +244,7 @@ export declare const health: JSONSchemaType<object>
234
244
  export declare const healthWithoutDefaults: JSONSchemaType<object>
235
245
  export declare const telemetryExporter: JSONSchemaType<object>
236
246
  export declare const telemetry: JSONSchemaType<object>
237
- export declare const services: JSONSchemaType<object[]>
247
+ export declare const applications: JSONSchemaType<object[]>
238
248
  export declare const runtimeUnwrappablePropertiesList: string[]
239
249
  export declare const runtimeProperties: JSONSchemaType<object>
240
250
  export declare const wrappedRuntimeProperties: JSONSchemaType<object>
package/index.js CHANGED
@@ -10,3 +10,4 @@ export * from './lib/node.js'
10
10
  export * from './lib/object.js'
11
11
  export * from './lib/schema.js'
12
12
  export * from './lib/string.js'
13
+ export * from './lib/symbols.js'
package/lib/cli.js CHANGED
@@ -152,8 +152,8 @@ export function getRoot (positionals) {
152
152
  return root
153
153
  }
154
154
 
155
- export function serviceToEnvVariable (service) {
156
- return `PLT_SERVICE_${service.toUpperCase().replaceAll(/[^A-Z0-9_]/g, '_')}_PATH`
155
+ export function applicationToEnvVariable (application) {
156
+ return `PLT_APPLICATION_${application.toUpperCase().replaceAll(/[^A-Z0-9_]/g, '_')}_PATH`
157
157
  }
158
158
 
159
159
  export async function findRuntimeConfigurationFile (
@@ -166,7 +166,7 @@ export async function findRuntimeConfigurationFile (
166
166
  ) {
167
167
  let configFile = await findConfigurationFileRecursive(root, configurationFile, '@platformatic/runtime')
168
168
 
169
- // If a runtime was not found, search for service file that we wrap in a runtime
169
+ // If a runtime was not found, search for application file that we wrap in a runtime
170
170
  if (!configFile && !configurationFile) {
171
171
  configFile = await findConfigurationFileRecursive(root, configurationFile)
172
172
  }
@@ -17,13 +17,13 @@ import {
17
17
  } from './errors.js'
18
18
  import { isFileAccessible } from './file-system.js'
19
19
  import { loadModule, splitModuleFromVersion } from './module.js'
20
+ import { kMetadata } from './symbols.js'
20
21
 
21
22
  const { parse: parseJSON5, stringify: rawStringifyJSON5 } = JSON5
22
23
  const { parse: parseTOML, stringify: stringifyTOML } = toml
23
24
 
24
25
  const kReplaceEnvIgnore = Symbol('plt.foundation.replaceEnvIgnore')
25
26
 
26
- export const kMetadata = Symbol('plt.foundation.metadata')
27
27
  export const envVariablePattern = /(?:\{{1,2})([a-z0-9_]+)(?:\}{1,2})/i
28
28
 
29
29
  export const knownConfigurationFilesExtensions = ['json', 'json5', 'yaml', 'yml', 'toml', 'tml']
@@ -120,7 +120,8 @@ export function printValidationErrors (err) {
120
120
 
121
121
  export function listRecognizedConfigurationFiles (suffixes, extensions) {
122
122
  if (typeof suffixes === 'undefined' || suffixes === null) {
123
- suffixes = ['runtime', 'service', 'application', 'db', 'composer']
123
+ // composer is retained for backward compatibility with V2
124
+ suffixes = ['runtime', 'service', 'application', 'db', 'gateway', 'composer']
124
125
  } else if (suffixes && !Array.isArray(suffixes)) {
125
126
  suffixes = [suffixes]
126
127
  } else if (!suffixes) {
package/lib/execution.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import { Unpromise } from '@watchable/unpromise'
2
2
  import { setTimeout as sleep } from 'node:timers/promises'
3
-
4
- export const kTimeout = Symbol('plt.utils.timeout')
3
+ import { kCanceled, kTimeout } from './symbols.js'
5
4
 
6
5
  export async function executeWithTimeout (promise, timeout, timeoutValue = kTimeout) {
7
6
  const ac = new AbortController()
@@ -11,3 +10,62 @@ export async function executeWithTimeout (promise, timeout, timeoutValue = kTime
11
10
  return value
12
11
  })
13
12
  }
13
+
14
+ export async function executeInParallel (fn, args, concurrency = 5, throwOnRejections = true, throwAllErrors = false) {
15
+ const { promise, resolve } = Promise.withResolvers()
16
+ const results = new Map()
17
+ let current = 0
18
+ let pending = 0
19
+ let firstError
20
+ let terminated = false
21
+
22
+ if (args.length === 0) {
23
+ return []
24
+ }
25
+
26
+ function scheduleNext () {
27
+ // While we have capacity and there are still items to process
28
+ while (current < args.length && pending < concurrency) {
29
+ const i = current++
30
+ pending++
31
+
32
+ // Perform the async operation
33
+ fn(...args[i])
34
+ .then(result => {
35
+ results.set(i, result)
36
+ })
37
+ .catch(err => {
38
+ results.set(i, err)
39
+ firstError = err
40
+ })
41
+ .finally(() => {
42
+ pending--
43
+
44
+ if (terminated) {
45
+ return
46
+ }
47
+
48
+ if ((current === args.length && pending === 0) || (firstError && throwOnRejections)) {
49
+ terminated = true
50
+ resolve()
51
+ } else {
52
+ scheduleNext()
53
+ }
54
+ })
55
+ }
56
+ }
57
+
58
+ scheduleNext()
59
+ await promise
60
+
61
+ const returnedValues = []
62
+ for (let j = 0; j < args.length; j++) {
63
+ returnedValues.push(results.has(j) ? results.get(j) : kCanceled)
64
+ }
65
+
66
+ if (firstError && throwOnRejections) {
67
+ throw throwAllErrors ? AggregateError(returnedValues, 'One or more operations failed.') : firstError
68
+ }
69
+
70
+ return returnedValues
71
+ }
package/lib/logger.js CHANGED
@@ -54,13 +54,13 @@ export function buildPinoTimestamp (timestamp) {
54
54
  return stdTimeFunctions[timestamp]
55
55
  }
56
56
 
57
- export function buildPinoOptions (loggerConfig, serverConfig, serviceId, workerId, context, root) {
57
+ export function buildPinoOptions (loggerConfig, serverConfig, applicationId, workerId, context, root) {
58
58
  const pinoOptions = {
59
59
  level: loggerConfig?.level ?? serverConfig?.level ?? 'trace'
60
60
  }
61
61
 
62
- if (serviceId) {
63
- pinoOptions.name = serviceId
62
+ if (applicationId) {
63
+ pinoOptions.name = applicationId
64
64
  }
65
65
 
66
66
  if (loggerConfig?.base) {
package/lib/module.js CHANGED
@@ -4,11 +4,10 @@ import { resolve } from 'node:path'
4
4
  import { fileURLToPath } from 'node:url'
5
5
  import { request } from 'undici'
6
6
  import { hasJavascriptFiles } from './file-system.js'
7
+ import { kFailedImport } from './symbols.js'
7
8
 
8
9
  let platformaticPackageVersion
9
10
 
10
- export const kFailedImport = Symbol('plt.utils.failedImport')
11
-
12
11
  export const defaultPackageManager = 'npm'
13
12
 
14
13
  export async function getLatestNpmVersion (pkg) {
package/lib/node.js CHANGED
@@ -3,7 +3,7 @@ import { lt, satisfies } from 'semver'
3
3
 
4
4
  const currentPlatform = platform()
5
5
 
6
- export function checkNodeVersionForServices () {
6
+ export function checkNodeVersionForApplications () {
7
7
  const currentVersion = process.version
8
8
  const minimumVersion = '22.18.0'
9
9
 
package/lib/schema.js CHANGED
@@ -618,13 +618,13 @@ export const telemetry = {
618
618
  }
619
619
  ]
620
620
  },
621
- serviceName: {
621
+ applicationName: {
622
622
  type: 'string',
623
- description: 'The name of the service. Defaults to the folder name if not specified.'
623
+ description: 'The name of the application. Defaults to the folder name if not specified.'
624
624
  },
625
625
  version: {
626
626
  type: 'string',
627
- description: 'The version of the service (optional)'
627
+ description: 'The version of the application (optional)'
628
628
  },
629
629
  skip: {
630
630
  type: 'array',
@@ -655,11 +655,11 @@ export const telemetry = {
655
655
  ]
656
656
  }
657
657
  },
658
- required: ['serviceName'],
658
+ required: ['applicationName'],
659
659
  additionalProperties: false
660
660
  }
661
661
 
662
- export const services = {
662
+ export const applications = {
663
663
  type: 'array',
664
664
  items: {
665
665
  type: 'object',
@@ -689,6 +689,13 @@ export const services = {
689
689
  },
690
690
  workers,
691
691
  health: { ...healthWithoutDefaults },
692
+ dependencies: {
693
+ type: 'array',
694
+ items: {
695
+ type: 'string'
696
+ },
697
+ default: []
698
+ },
692
699
  arguments: {
693
700
  type: 'array',
694
701
  items: {
@@ -750,10 +757,11 @@ export const services = {
750
757
  export const runtimeUnwrappablePropertiesList = [
751
758
  '$schema',
752
759
  'entrypoint',
760
+ 'applications',
753
761
  'autoload',
754
- 'services',
762
+ 'applications',
755
763
  'web',
756
- 'resolvedServicesBasePath'
764
+ 'resolvedApplicationsBasePath'
757
765
  ]
758
766
 
759
767
  export const runtimeProperties = {
@@ -802,6 +810,12 @@ export const runtimeProperties = {
802
810
  workers,
803
811
  health: { ...healthWithoutDefaults },
804
812
  preload,
813
+ dependencies: {
814
+ type: 'array',
815
+ items: {
816
+ type: 'string'
817
+ }
818
+ },
805
819
  arguments: {
806
820
  type: 'array',
807
821
  items: {
@@ -816,9 +830,10 @@ export const runtimeProperties = {
816
830
  }
817
831
  }
818
832
  },
819
- services,
833
+ applications,
834
+ services: applications,
835
+ web: applications,
820
836
  workers: { ...workers, default: 1 },
821
- web: services,
822
837
  logger,
823
838
  server,
824
839
  startTimeout: {
@@ -849,7 +864,7 @@ export const runtimeProperties = {
849
864
  ],
850
865
  default: 10000
851
866
  },
852
- service: {
867
+ application: {
853
868
  anyOf: [
854
869
  {
855
870
  type: 'number',
@@ -861,7 +876,7 @@ export const runtimeProperties = {
861
876
  }
862
877
  },
863
878
  default: {},
864
- required: ['runtime', 'service'],
879
+ required: ['runtime', 'application'],
865
880
  additionalProperties: false
866
881
  },
867
882
  health,
@@ -1081,7 +1096,7 @@ export const runtimeProperties = {
1081
1096
  }
1082
1097
  }
1083
1098
  },
1084
- serviceTimeout: {
1099
+ applicationTimeout: {
1085
1100
  anyOf: [
1086
1101
  {
1087
1102
  type: 'number',
@@ -1101,7 +1116,7 @@ export const runtimeProperties = {
1101
1116
  ],
1102
1117
  default: 30000 // 5 minutes
1103
1118
  },
1104
- resolvedServicesBasePath: {
1119
+ resolvedApplicationsBasePath: {
1105
1120
  type: 'string',
1106
1121
  default: 'external'
1107
1122
  },
@@ -1182,7 +1197,7 @@ export const schemaComponents = {
1182
1197
  healthWithoutDefaults,
1183
1198
  telemetryExporter,
1184
1199
  telemetry,
1185
- services,
1200
+ applications,
1186
1201
  runtimeProperties,
1187
1202
  wrappedRuntimeProperties,
1188
1203
  wrappedRuntime
package/lib/symbols.js ADDED
@@ -0,0 +1,5 @@
1
+ export const kCanceled = Symbol('plt.foundation.canceled')
2
+ export const kFailedImport = Symbol('plt.foundation.failedImport')
3
+ export const kHandledError = Symbol('plt.foundation.handledError')
4
+ export const kMetadata = Symbol('plt.foundation.metadata')
5
+ export const kTimeout = Symbol('plt.foundation.timeout')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/foundation",
3
- "version": "3.0.0-alpha.5",
3
+ "version": "3.0.0-alpha.7",
4
4
  "description": "Platformatic Foundation",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -33,8 +33,8 @@
33
33
  "yaml": "^2.4.1"
34
34
  },
35
35
  "devDependencies": {
36
- "borp": "^0.20.0",
37
36
  "c8": "^10.0.0",
37
+ "cleaner-spec-reporter": "^0.5.0",
38
38
  "eslint": "9",
39
39
  "fastify": "^5.0.0",
40
40
  "neostandard": "^0.12.0",
@@ -46,8 +46,7 @@
46
46
  "node": ">=22.18.0"
47
47
  },
48
48
  "scripts": {
49
- "test": "npm run lint && node --test --test-concurrency=1 --test-timeout=1200000 test/*.test.js",
50
- "coverage": "c8 -r html -r text node --test --test-concurrency=1 --test-timeout=1200000 test/*.test.js",
49
+ "test": "node --test --test-reporter=cleaner-spec-reporter --test-concurrency=1 --test-timeout=2000000 test/*.test.js test/**/*.test.js",
51
50
  "lint": "eslint"
52
51
  }
53
52
  }