nmtjs 0.16.0 → 0.17.0-beta.1
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.md +1 -1
- package/README.md +41 -1
- package/dist/index.d.ts +22 -121
- package/dist/index.js +24 -53
- package/dist/index.js.map +1 -1
- package/package.json +11 -63
- package/src/index.ts +71 -91
- package/bin/cli.js +0 -2
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -137
- package/dist/cli.js.map +0 -1
- package/dist/codegen.d.ts +0 -5
- package/dist/codegen.js +0 -18
- package/dist/codegen.js.map +0 -1
- package/dist/config.d.ts +0 -47
- package/dist/config.js +0 -16
- package/dist/config.js.map +0 -1
- package/dist/entrypoints/cli.d.ts +0 -1
- package/dist/entrypoints/cli.js +0 -12
- package/dist/entrypoints/cli.js.map +0 -1
- package/dist/entrypoints/main.d.ts +0 -5
- package/dist/entrypoints/main.js +0 -248
- package/dist/entrypoints/main.js.map +0 -1
- package/dist/entrypoints/thread.d.ts +0 -16
- package/dist/entrypoints/thread.js +0 -182
- package/dist/entrypoints/thread.js.map +0 -1
- package/dist/entrypoints/worker.d.ts +0 -9
- package/dist/entrypoints/worker.js +0 -143
- package/dist/entrypoints/worker.js.map +0 -1
- package/dist/resolver.d.ts +0 -2
- package/dist/resolver.js +0 -7
- package/dist/resolver.js.map +0 -1
- package/dist/runtime/application/index.d.ts +0 -1
- package/dist/runtime/application/index.js +0 -2
- package/dist/runtime/application/index.js.map +0 -1
- package/dist/runtime/constants.d.ts +0 -8
- package/dist/runtime/constants.js +0 -5
- package/dist/runtime/constants.js.map +0 -1
- package/dist/runtime/enums.d.ts +0 -10
- package/dist/runtime/enums.js +0 -13
- package/dist/runtime/enums.js.map +0 -1
- package/dist/runtime/hooks.d.ts +0 -1
- package/dist/runtime/hooks.js +0 -2
- package/dist/runtime/hooks.js.map +0 -1
- package/dist/runtime/index.d.ts +0 -28
- package/dist/runtime/index.js +0 -29
- package/dist/runtime/index.js.map +0 -1
- package/dist/runtime/injectables.d.ts +0 -28
- package/dist/runtime/injectables.js +0 -24
- package/dist/runtime/injectables.js.map +0 -1
- package/dist/runtime/jobs/job.d.ts +0 -146
- package/dist/runtime/jobs/job.js +0 -89
- package/dist/runtime/jobs/job.js.map +0 -1
- package/dist/runtime/jobs/manager.d.ts +0 -131
- package/dist/runtime/jobs/manager.js +0 -309
- package/dist/runtime/jobs/manager.js.map +0 -1
- package/dist/runtime/jobs/router.d.ts +0 -296
- package/dist/runtime/jobs/router.js +0 -458
- package/dist/runtime/jobs/router.js.map +0 -1
- package/dist/runtime/jobs/runner.d.ts +0 -103
- package/dist/runtime/jobs/runner.js +0 -425
- package/dist/runtime/jobs/runner.js.map +0 -1
- package/dist/runtime/jobs/step.d.ts +0 -26
- package/dist/runtime/jobs/step.js +0 -18
- package/dist/runtime/jobs/step.js.map +0 -1
- package/dist/runtime/jobs/types.d.ts +0 -86
- package/dist/runtime/jobs/types.js +0 -5
- package/dist/runtime/jobs/types.js.map +0 -1
- package/dist/runtime/metrics/metric.d.ts +0 -8
- package/dist/runtime/metrics/metric.js +0 -11
- package/dist/runtime/metrics/metric.js.map +0 -1
- package/dist/runtime/metrics/registry.d.ts +0 -3
- package/dist/runtime/metrics/registry.js +0 -5
- package/dist/runtime/metrics/registry.js.map +0 -1
- package/dist/runtime/metrics/server.d.ts +0 -7
- package/dist/runtime/metrics/server.js +0 -53
- package/dist/runtime/metrics/server.js.map +0 -1
- package/dist/runtime/plugin.d.ts +0 -2
- package/dist/runtime/plugin.js +0 -2
- package/dist/runtime/plugin.js.map +0 -1
- package/dist/runtime/runtime.d.ts +0 -27
- package/dist/runtime/runtime.js +0 -77
- package/dist/runtime/runtime.js.map +0 -1
- package/dist/runtime/scheduler/index.d.ts +0 -22
- package/dist/runtime/scheduler/index.js +0 -20
- package/dist/runtime/scheduler/index.js.map +0 -1
- package/dist/runtime/server/applications.d.ts +0 -91
- package/dist/runtime/server/applications.js +0 -171
- package/dist/runtime/server/applications.js.map +0 -1
- package/dist/runtime/server/config.d.ts +0 -148
- package/dist/runtime/server/config.js +0 -33
- package/dist/runtime/server/config.js.map +0 -1
- package/dist/runtime/server/environment.d.ts +0 -43
- package/dist/runtime/server/environment.js +0 -33
- package/dist/runtime/server/environment.js.map +0 -1
- package/dist/runtime/server/error-policy.d.ts +0 -62
- package/dist/runtime/server/error-policy.js +0 -73
- package/dist/runtime/server/error-policy.js.map +0 -1
- package/dist/runtime/server/hmr-coordinator.d.ts +0 -37
- package/dist/runtime/server/hmr-coordinator.js +0 -94
- package/dist/runtime/server/hmr-coordinator.js.map +0 -1
- package/dist/runtime/server/jobs.d.ts +0 -54
- package/dist/runtime/server/jobs.js +0 -176
- package/dist/runtime/server/jobs.js.map +0 -1
- package/dist/runtime/server/lifecycle.d.ts +0 -85
- package/dist/runtime/server/lifecycle.js +0 -177
- package/dist/runtime/server/lifecycle.js.map +0 -1
- package/dist/runtime/server/managed-worker.d.ts +0 -158
- package/dist/runtime/server/managed-worker.js +0 -420
- package/dist/runtime/server/managed-worker.js.map +0 -1
- package/dist/runtime/server/pool-manager.d.ts +0 -85
- package/dist/runtime/server/pool-manager.js +0 -129
- package/dist/runtime/server/pool-manager.js.map +0 -1
- package/dist/runtime/server/proxy.d.ts +0 -21
- package/dist/runtime/server/proxy.js +0 -76
- package/dist/runtime/server/proxy.js.map +0 -1
- package/dist/runtime/server/server.d.ts +0 -60
- package/dist/runtime/server/server.js +0 -163
- package/dist/runtime/server/server.js.map +0 -1
- package/dist/runtime/server/types.d.ts +0 -31
- package/dist/runtime/server/types.js +0 -2
- package/dist/runtime/server/types.js.map +0 -1
- package/dist/runtime/server/worker-pool.d.ts +0 -121
- package/dist/runtime/server/worker-pool.js +0 -171
- package/dist/runtime/server/worker-pool.js.map +0 -1
- package/dist/runtime/store/index.d.ts +0 -3
- package/dist/runtime/store/index.js +0 -23
- package/dist/runtime/store/index.js.map +0 -1
- package/dist/runtime/subscription/manager.d.ts +0 -49
- package/dist/runtime/subscription/manager.js +0 -170
- package/dist/runtime/subscription/manager.js.map +0 -1
- package/dist/runtime/subscription/redis.d.ts +0 -18
- package/dist/runtime/subscription/redis.js +0 -120
- package/dist/runtime/subscription/redis.js.map +0 -1
- package/dist/runtime/types.d.ts +0 -95
- package/dist/runtime/types.js +0 -2
- package/dist/runtime/types.js.map +0 -1
- package/dist/runtime/workers/application.d.ts +0 -29
- package/dist/runtime/workers/application.js +0 -77
- package/dist/runtime/workers/application.js.map +0 -1
- package/dist/runtime/workers/base.d.ts +0 -16
- package/dist/runtime/workers/base.js +0 -46
- package/dist/runtime/workers/base.js.map +0 -1
- package/dist/runtime/workers/cli.d.ts +0 -1
- package/dist/runtime/workers/cli.js +0 -2
- package/dist/runtime/workers/cli.js.map +0 -1
- package/dist/runtime/workers/job.d.ts +0 -20
- package/dist/runtime/workers/job.js +0 -170
- package/dist/runtime/workers/job.js.map +0 -1
- package/dist/vite/builder.d.ts +0 -5
- package/dist/vite/builder.js +0 -79
- package/dist/vite/builder.js.map +0 -1
- package/dist/vite/config.d.ts +0 -28
- package/dist/vite/config.js +0 -22
- package/dist/vite/config.js.map +0 -1
- package/dist/vite/plugins.d.ts +0 -2
- package/dist/vite/plugins.js +0 -43
- package/dist/vite/plugins.js.map +0 -1
- package/dist/vite/runners/worker.d.ts +0 -3
- package/dist/vite/runners/worker.js +0 -34
- package/dist/vite/runners/worker.js.map +0 -1
- package/dist/vite/server.d.ts +0 -3
- package/dist/vite/server.js +0 -36
- package/dist/vite/server.js.map +0 -1
- package/dist/vite/servers/main.d.ts +0 -8
- package/dist/vite/servers/main.js +0 -24
- package/dist/vite/servers/main.js.map +0 -1
- package/dist/vite/servers/worker.d.ts +0 -13
- package/dist/vite/servers/worker.js +0 -124
- package/dist/vite/servers/worker.js.map +0 -1
- package/src/cli.ts +0 -162
- package/src/codegen.ts +0 -30
- package/src/config.ts +0 -69
- package/src/entrypoints/cli.ts +0 -13
- package/src/entrypoints/main.ts +0 -317
- package/src/entrypoints/thread.ts +0 -223
- package/src/entrypoints/worker.ts +0 -174
- package/src/resolver.ts +0 -7
- package/src/runtime/application/index.ts +0 -1
- package/src/runtime/constants.ts +0 -13
- package/src/runtime/enums.ts +0 -12
- package/src/runtime/hooks.ts +0 -1
- package/src/runtime/index.ts +0 -29
- package/src/runtime/injectables.ts +0 -72
- package/src/runtime/jobs/job.ts +0 -467
- package/src/runtime/jobs/manager.ts +0 -454
- package/src/runtime/jobs/router.ts +0 -967
- package/src/runtime/jobs/runner.ts +0 -583
- package/src/runtime/jobs/step.ts +0 -66
- package/src/runtime/jobs/types.ts +0 -116
- package/src/runtime/metrics/metric.ts +0 -18
- package/src/runtime/metrics/registry.ts +0 -11
- package/src/runtime/metrics/server.ts +0 -69
- package/src/runtime/plugin.ts +0 -2
- package/src/runtime/runtime.ts +0 -103
- package/src/runtime/scheduler/index.ts +0 -39
- package/src/runtime/server/applications.ts +0 -264
- package/src/runtime/server/config.ts +0 -199
- package/src/runtime/server/environment.ts +0 -71
- package/src/runtime/server/error-policy.ts +0 -132
- package/src/runtime/server/hmr-coordinator.ts +0 -116
- package/src/runtime/server/jobs.ts +0 -266
- package/src/runtime/server/lifecycle.ts +0 -234
- package/src/runtime/server/managed-worker.ts +0 -546
- package/src/runtime/server/pool-manager.ts +0 -187
- package/src/runtime/server/proxy.ts +0 -119
- package/src/runtime/server/server.ts +0 -218
- package/src/runtime/server/types.ts +0 -32
- package/src/runtime/server/worker-pool.ts +0 -275
- package/src/runtime/store/index.ts +0 -30
- package/src/runtime/subscription/manager.ts +0 -310
- package/src/runtime/subscription/redis.ts +0 -157
- package/src/runtime/types.ts +0 -84
- package/src/runtime/workers/application.ts +0 -133
- package/src/runtime/workers/base.ts +0 -71
- package/src/runtime/workers/cli.ts +0 -0
- package/src/runtime/workers/job.ts +0 -142
- package/src/vite/builder.ts +0 -94
- package/src/vite/config.ts +0 -45
- package/src/vite/plugins.ts +0 -53
- package/src/vite/runners/worker.ts +0 -55
- package/src/vite/server.ts +0 -55
- package/src/vite/servers/main.ts +0 -41
- package/src/vite/servers/worker.ts +0 -177
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ApplicationHost,
|
|
3
|
-
ApplicationHostDefinition,
|
|
4
|
-
TransportOptionsOf,
|
|
5
|
-
} from '@nmtjs/application'
|
|
6
|
-
import type { LoggingOptions } from '@nmtjs/core'
|
|
7
|
-
import type { ApplicationOptions } from '@nmtjs/proxy'
|
|
8
|
-
import type { Applications } from 'nmtjs/runtime/types'
|
|
9
|
-
|
|
10
|
-
import type { StoreType } from '../enums.ts'
|
|
11
|
-
import type { AnyJob } from '../jobs/job.ts'
|
|
12
|
-
import type { JobsSchedulerOptions } from '../scheduler/index.ts'
|
|
13
|
-
import type { SubscriptionAdapterType } from '../subscription/manager.ts'
|
|
14
|
-
import type { StoreTypeOptions } from '../types.ts'
|
|
15
|
-
import { kServerConfig } from '../constants.ts'
|
|
16
|
-
|
|
17
|
-
export type ServerPoolOptions = {
|
|
18
|
-
/**
|
|
19
|
-
* Number of worker threads
|
|
20
|
-
*/
|
|
21
|
-
threads: number
|
|
22
|
-
/**
|
|
23
|
-
* Max number of jobs per worker
|
|
24
|
-
*/
|
|
25
|
-
jobs: number
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export type ServerStoreConfig =
|
|
29
|
-
| { type: StoreType.Redis; options: StoreTypeOptions[StoreType.Redis] }
|
|
30
|
-
| { type: StoreType.Valkey; options: StoreTypeOptions[StoreType.Valkey] }
|
|
31
|
-
|
|
32
|
-
export type ServerApplicationConfig<T = ApplicationHostDefinition> =
|
|
33
|
-
T extends ApplicationHostDefinition<any, infer Transports>
|
|
34
|
-
? {
|
|
35
|
-
threads: {
|
|
36
|
-
[K in keyof Transports]: TransportOptionsOf<Transports[K]>
|
|
37
|
-
}[]
|
|
38
|
-
}
|
|
39
|
-
: T extends ApplicationHost<infer Transports>
|
|
40
|
-
? {
|
|
41
|
-
threads: {
|
|
42
|
-
[K in keyof Transports]: TransportOptionsOf<Transports[K]>
|
|
43
|
-
}[]
|
|
44
|
-
}
|
|
45
|
-
: any
|
|
46
|
-
|
|
47
|
-
export type ServerJobsConfig = {
|
|
48
|
-
pools: Record<string, ServerPoolOptions>
|
|
49
|
-
jobs?: AnyJob[]
|
|
50
|
-
/**
|
|
51
|
-
* @deprecated Scheduler is currently being refactored and is not available.
|
|
52
|
-
* Using this option will throw an error at startup.
|
|
53
|
-
*/
|
|
54
|
-
scheduler?: JobsSchedulerOptions
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
type ServerApplicationDefinitionConfig<T> = T extends {
|
|
58
|
-
type: 'neemata'
|
|
59
|
-
definition: infer Definition
|
|
60
|
-
}
|
|
61
|
-
? ServerApplicationConfig<Definition>
|
|
62
|
-
: ServerApplicationConfig<any>
|
|
63
|
-
|
|
64
|
-
export interface ServerConfigInit {
|
|
65
|
-
logger: LoggingOptions
|
|
66
|
-
applications: {
|
|
67
|
-
[K in keyof Applications]: ServerApplicationDefinitionConfig<
|
|
68
|
-
Applications[K]
|
|
69
|
-
>
|
|
70
|
-
}
|
|
71
|
-
store?: ServerStoreConfig
|
|
72
|
-
/**
|
|
73
|
-
* Proxy configuration. Enabling this will start a reverse proxy server that handles TLS, routing,
|
|
74
|
-
* load balancing, and health checks for your applications.
|
|
75
|
-
*
|
|
76
|
-
* The applications will be accessible via `<hostname>:<port>/<application-name>/**`
|
|
77
|
-
*
|
|
78
|
-
* Requires adding `@nmtjs/proxy` package to your dependencies
|
|
79
|
-
* and [`cargo`](https://doc.rust-lang.org/cargo/getting-started/installation.html) alongside with
|
|
80
|
-
* [`rustc`](https://www.rust-lang.org/tools/install) to be available globally for building native modules.
|
|
81
|
-
*/
|
|
82
|
-
proxy?: {
|
|
83
|
-
port: number
|
|
84
|
-
hostname: string
|
|
85
|
-
applications: {
|
|
86
|
-
[K in keyof Applications]?: Omit<ApplicationOptions, 'name'>
|
|
87
|
-
}
|
|
88
|
-
threads?: number
|
|
89
|
-
healthChecks?: { interval?: number }
|
|
90
|
-
tls?: { key: string; cert: string }
|
|
91
|
-
}
|
|
92
|
-
jobs?: ServerJobsConfig
|
|
93
|
-
commands?: {}
|
|
94
|
-
subscription?: { adapter: SubscriptionAdapterType }
|
|
95
|
-
deploymentId?: string
|
|
96
|
-
metrics?: {
|
|
97
|
-
/**
|
|
98
|
-
* @default '/metrics'
|
|
99
|
-
*/
|
|
100
|
-
path?: string
|
|
101
|
-
/**
|
|
102
|
-
* @default 9187
|
|
103
|
-
*/
|
|
104
|
-
port?: number
|
|
105
|
-
/**
|
|
106
|
-
* @default 0.0.0.0
|
|
107
|
-
*/
|
|
108
|
-
host?: string
|
|
109
|
-
|
|
110
|
-
push?: {
|
|
111
|
-
/**
|
|
112
|
-
* Pushgateway URL (including protocol and port)
|
|
113
|
-
*
|
|
114
|
-
* @default http://127.0.0.1:9091
|
|
115
|
-
*/
|
|
116
|
-
url?: string
|
|
117
|
-
/**
|
|
118
|
-
* Job name for the pushgateway
|
|
119
|
-
*/
|
|
120
|
-
name: string
|
|
121
|
-
/**
|
|
122
|
-
* Push interval in milliseconds
|
|
123
|
-
*/
|
|
124
|
-
interval: number
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export interface ServerConfig {
|
|
130
|
-
[kServerConfig]: true
|
|
131
|
-
logger: ServerConfigInit['logger']
|
|
132
|
-
applications: ServerConfigInit['applications']
|
|
133
|
-
store: ServerConfigInit['store']
|
|
134
|
-
/**
|
|
135
|
-
* Proxy configuration. Enabling this will start a reverse proxy server that handles TLS, routing,
|
|
136
|
-
* load balancing, and health checks for your applications.
|
|
137
|
-
*
|
|
138
|
-
* The applications will be accessible via `<hostname>:<port>/<application-name>/**`
|
|
139
|
-
*
|
|
140
|
-
* Requires adding `@nmtjs/proxy` package to your dependencies
|
|
141
|
-
*/
|
|
142
|
-
proxy: ServerConfigInit['proxy']
|
|
143
|
-
jobs?: {
|
|
144
|
-
pools: ServerJobsConfig['pools']
|
|
145
|
-
jobs: Map<string, AnyJob>
|
|
146
|
-
/**
|
|
147
|
-
* @deprecated Scheduler is currently being refactored and is not available.
|
|
148
|
-
* Using this option will throw an error at startup.
|
|
149
|
-
*/
|
|
150
|
-
scheduler?: JobsSchedulerOptions
|
|
151
|
-
}
|
|
152
|
-
commands?: {}
|
|
153
|
-
subscription: ServerConfigInit['subscription']
|
|
154
|
-
deploymentId: ServerConfigInit['deploymentId']
|
|
155
|
-
metrics?: ServerConfigInit['metrics']
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
export function defineServer(options: ServerConfigInit): ServerConfig {
|
|
159
|
-
const {
|
|
160
|
-
deploymentId,
|
|
161
|
-
logger,
|
|
162
|
-
commands,
|
|
163
|
-
proxy,
|
|
164
|
-
store,
|
|
165
|
-
applications,
|
|
166
|
-
subscription,
|
|
167
|
-
metrics,
|
|
168
|
-
} = options
|
|
169
|
-
|
|
170
|
-
let jobs: ServerConfig['jobs'] | undefined
|
|
171
|
-
if (options.jobs) {
|
|
172
|
-
const map = new Map<string, AnyJob>()
|
|
173
|
-
for (const job of options.jobs.jobs ?? []) map.set(job.name, job)
|
|
174
|
-
for (const { job } of options.jobs.scheduler?.entries ?? [])
|
|
175
|
-
map.set(job.name, job)
|
|
176
|
-
jobs = {
|
|
177
|
-
pools: options.jobs.pools,
|
|
178
|
-
jobs: map,
|
|
179
|
-
scheduler: options.jobs.scheduler,
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return Object.freeze({
|
|
184
|
-
[kServerConfig]: true,
|
|
185
|
-
deploymentId,
|
|
186
|
-
logger,
|
|
187
|
-
commands,
|
|
188
|
-
proxy,
|
|
189
|
-
store,
|
|
190
|
-
applications,
|
|
191
|
-
subscription,
|
|
192
|
-
jobs,
|
|
193
|
-
metrics,
|
|
194
|
-
} as const)
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
export function isServerConfig(value: any): value is ServerConfig {
|
|
198
|
-
return Boolean(value?.[kServerConfig])
|
|
199
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import type { ViteDevServer } from 'vite'
|
|
2
|
-
|
|
3
|
-
import type { ErrorPolicy } from './error-policy.ts'
|
|
4
|
-
import type { HMRCoordinator } from './hmr-coordinator.ts'
|
|
5
|
-
import { getErrorPolicy } from './error-policy.ts'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Encapsulates everything that differs between Dev and Prod environments.
|
|
9
|
-
* This provides a clean abstraction over environment-specific behavior.
|
|
10
|
-
*/
|
|
11
|
-
export interface RuntimeEnvironment {
|
|
12
|
-
readonly mode: 'development' | 'production'
|
|
13
|
-
readonly errorPolicy: ErrorPolicy
|
|
14
|
-
readonly hmr: HMRCoordinator | null // null in prod
|
|
15
|
-
readonly vite: ViteDevServer | null // null in prod
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Options for creating a development environment.
|
|
20
|
-
*/
|
|
21
|
-
export interface DevEnvironmentOptions {
|
|
22
|
-
vite?: ViteDevServer
|
|
23
|
-
hmr?: HMRCoordinator
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Creates a RuntimeEnvironment for the given mode.
|
|
28
|
-
*
|
|
29
|
-
* @param mode - 'development' or 'production'
|
|
30
|
-
* @param options - Optional configuration (vite server for dev mode)
|
|
31
|
-
*/
|
|
32
|
-
export function createRuntimeEnvironment(
|
|
33
|
-
mode: 'development' | 'production',
|
|
34
|
-
options?: DevEnvironmentOptions,
|
|
35
|
-
): RuntimeEnvironment {
|
|
36
|
-
const errorPolicy = getErrorPolicy(mode)
|
|
37
|
-
|
|
38
|
-
if (mode === 'development') {
|
|
39
|
-
return {
|
|
40
|
-
mode,
|
|
41
|
-
errorPolicy,
|
|
42
|
-
hmr: options?.hmr ?? null,
|
|
43
|
-
vite: options?.vite ?? null,
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Production mode - no HMR or Vite
|
|
48
|
-
return { mode, errorPolicy, hmr: null, vite: null }
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Type guard to check if environment is development mode.
|
|
53
|
-
*/
|
|
54
|
-
export function isDevEnvironment(
|
|
55
|
-
env: RuntimeEnvironment,
|
|
56
|
-
): env is RuntimeEnvironment & {
|
|
57
|
-
mode: 'development'
|
|
58
|
-
hmr: HMRCoordinator | null
|
|
59
|
-
vite: ViteDevServer | null
|
|
60
|
-
} {
|
|
61
|
-
return env.mode === 'development'
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Type guard to check if environment is production mode.
|
|
66
|
-
*/
|
|
67
|
-
export function isProdEnvironment(
|
|
68
|
-
env: RuntimeEnvironment,
|
|
69
|
-
): env is RuntimeEnvironment & { mode: 'production'; hmr: null; vite: null } {
|
|
70
|
-
return env.mode === 'production'
|
|
71
|
-
}
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import type { WorkerType } from '../enums.ts'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Context provided to error policy decisions about worker failures.
|
|
5
|
-
*/
|
|
6
|
-
export interface WorkerErrorContext {
|
|
7
|
-
workerId: string
|
|
8
|
-
workerType: WorkerType
|
|
9
|
-
consecutiveFailures: number
|
|
10
|
-
totalFailures: number
|
|
11
|
-
lastStableTime: number | null
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Actions that can be taken in response to errors.
|
|
16
|
-
*/
|
|
17
|
-
export type ErrorAction =
|
|
18
|
-
| { type: 'exit'; code: number }
|
|
19
|
-
| { type: 'restart'; delay: number }
|
|
20
|
-
| { type: 'wait' } // Dev only: wait for HMR fix
|
|
21
|
-
| { type: 'ignore' }
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Interface defining error handling behavior for different environments.
|
|
25
|
-
* Dev and Prod modes have different requirements and this interface makes those explicit.
|
|
26
|
-
*/
|
|
27
|
-
export interface ErrorPolicy {
|
|
28
|
-
/** How to handle server startup failure */
|
|
29
|
-
onStartupError(error: Error): ErrorAction
|
|
30
|
-
|
|
31
|
-
/** How to handle worker crash */
|
|
32
|
-
onWorkerError(error: Error, context: WorkerErrorContext): ErrorAction
|
|
33
|
-
|
|
34
|
-
/** Delay before restarting a failed worker */
|
|
35
|
-
getRestartDelay(consecutiveFailures: number): number
|
|
36
|
-
|
|
37
|
-
/** Whether to continue if some workers are down */
|
|
38
|
-
readonly allowDegradedMode: boolean
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Calculates exponential backoff delay with a cap.
|
|
43
|
-
* @param failures - Number of consecutive failures
|
|
44
|
-
* @param base - Base delay in ms (default: 100)
|
|
45
|
-
* @param maxDelay - Maximum delay in ms (default: 5000)
|
|
46
|
-
*/
|
|
47
|
-
function exponentialBackoff(
|
|
48
|
-
failures: number,
|
|
49
|
-
base = 100,
|
|
50
|
-
maxDelay = 5000,
|
|
51
|
-
): number {
|
|
52
|
-
return Math.min(base * 2 ** Math.max(0, failures - 1), maxDelay)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Time window in ms after which a worker is considered "stable".
|
|
57
|
-
* If stable, consecutive failure count is reset on next error.
|
|
58
|
-
*/
|
|
59
|
-
const STABILITY_WINDOW_MS = 30_000
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Maximum retries before giving up in dev mode.
|
|
63
|
-
*/
|
|
64
|
-
const DEV_MAX_RETRIES = 1
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Maximum retries before exiting in prod mode.
|
|
68
|
-
*/
|
|
69
|
-
const PROD_MAX_RETRIES = 3
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Development Error Policy
|
|
73
|
-
*
|
|
74
|
-
* - Startup errors: Wait for HMR fix (don't exit)
|
|
75
|
-
* - Worker errors: Restart with exponential backoff
|
|
76
|
-
* - After 10 consecutive failures: Stop retrying, wait for HMR fix
|
|
77
|
-
* - Stability window: Reset failure count if worker was stable for 30s+
|
|
78
|
-
* - Degraded mode: Allowed (keep serving with partial workers)
|
|
79
|
-
*/
|
|
80
|
-
export const DevErrorPolicy: ErrorPolicy = {
|
|
81
|
-
onStartupError: () => ({ type: 'wait' }),
|
|
82
|
-
|
|
83
|
-
onWorkerError: (_error, ctx) => {
|
|
84
|
-
// Check if worker was stable before this failure
|
|
85
|
-
const wasStable =
|
|
86
|
-
ctx.lastStableTime !== null &&
|
|
87
|
-
Date.now() - ctx.lastStableTime > STABILITY_WINDOW_MS
|
|
88
|
-
|
|
89
|
-
// Reset failure count if was stable
|
|
90
|
-
const effectiveFailures = wasStable ? 1 : ctx.consecutiveFailures
|
|
91
|
-
|
|
92
|
-
if (effectiveFailures >= DEV_MAX_RETRIES) {
|
|
93
|
-
return { type: 'wait' } // Stop trying, wait for HMR fix
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return { type: 'restart', delay: exponentialBackoff(effectiveFailures) }
|
|
97
|
-
},
|
|
98
|
-
|
|
99
|
-
getRestartDelay: (n) => exponentialBackoff(n),
|
|
100
|
-
allowDegradedMode: true,
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Production Error Policy
|
|
105
|
-
*
|
|
106
|
-
* - Startup errors: Exit immediately with code 1
|
|
107
|
-
* - Worker errors: Restart up to 3 times, then exit
|
|
108
|
-
* - No stability window consideration (each failure counts)
|
|
109
|
-
* - Degraded mode: Not allowed (all workers must be healthy)
|
|
110
|
-
*/
|
|
111
|
-
export const ProdErrorPolicy: ErrorPolicy = {
|
|
112
|
-
onStartupError: () => ({ type: 'exit', code: 1 }),
|
|
113
|
-
|
|
114
|
-
onWorkerError: (_error, ctx) => {
|
|
115
|
-
if (ctx.consecutiveFailures >= PROD_MAX_RETRIES) {
|
|
116
|
-
return { type: 'exit', code: 1 }
|
|
117
|
-
}
|
|
118
|
-
return { type: 'restart', delay: 1000 }
|
|
119
|
-
},
|
|
120
|
-
|
|
121
|
-
getRestartDelay: () => 1000,
|
|
122
|
-
allowDegradedMode: false,
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Get the appropriate error policy for the given mode.
|
|
127
|
-
*/
|
|
128
|
-
export function getErrorPolicy(
|
|
129
|
-
mode: 'development' | 'production',
|
|
130
|
-
): ErrorPolicy {
|
|
131
|
-
return mode === 'development' ? DevErrorPolicy : ProdErrorPolicy
|
|
132
|
-
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import type { Logger } from '@nmtjs/core'
|
|
2
|
-
|
|
3
|
-
import type { ServerLifecycle } from './lifecycle.ts'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* HMRCoordinator handles HMR (Hot Module Replacement) with proper supersede logic.
|
|
7
|
-
*
|
|
8
|
-
* When a reload is in progress and another HMR event arrives, the pending reload
|
|
9
|
-
* is superseded by the latest - only the most recent config is applied.
|
|
10
|
-
*
|
|
11
|
-
* This component is only used in development mode.
|
|
12
|
-
*/
|
|
13
|
-
export class HMRCoordinator {
|
|
14
|
-
/** Currently executing reload, if any */
|
|
15
|
-
private active: Promise<void> | null = null
|
|
16
|
-
|
|
17
|
-
/** Pending reload - only the latest request is kept */
|
|
18
|
-
private pendingResolvers: {
|
|
19
|
-
resolve: () => void
|
|
20
|
-
reject: (e: Error) => void
|
|
21
|
-
} | null = null
|
|
22
|
-
|
|
23
|
-
/** Whether a reload is pending after the current one completes */
|
|
24
|
-
private hasPending = false
|
|
25
|
-
|
|
26
|
-
private logger: Logger
|
|
27
|
-
|
|
28
|
-
constructor(
|
|
29
|
-
private readonly lifecycle: ServerLifecycle,
|
|
30
|
-
logger: Logger,
|
|
31
|
-
) {
|
|
32
|
-
this.logger = logger.child({ component: 'HMRCoordinator' })
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Schedule a reload. If a reload is already in progress, supersedes any pending reload.
|
|
37
|
-
*
|
|
38
|
-
* @returns Promise that resolves when this reload completes (or is superseded)
|
|
39
|
-
*/
|
|
40
|
-
async scheduleReload(): Promise<void> {
|
|
41
|
-
// If no active reload, execute immediately
|
|
42
|
-
if (!this.active) {
|
|
43
|
-
return this.executeReload()
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Supersede any existing pending reload - resolve previous waiter
|
|
47
|
-
if (this.pendingResolvers) {
|
|
48
|
-
this.logger.debug('Superseding pending reload with new request')
|
|
49
|
-
this.pendingResolvers.resolve()
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Mark that we have a pending reload
|
|
53
|
-
this.hasPending = true
|
|
54
|
-
|
|
55
|
-
// Create new pending promise for this caller
|
|
56
|
-
return new Promise((resolve, reject) => {
|
|
57
|
-
this.pendingResolvers = { resolve, reject }
|
|
58
|
-
})
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Execute a reload, handling the pending queue.
|
|
63
|
-
*/
|
|
64
|
-
private async executeReload(): Promise<void> {
|
|
65
|
-
this.logger.debug('HMR reload starting')
|
|
66
|
-
|
|
67
|
-
this.active = this.doReload()
|
|
68
|
-
|
|
69
|
-
try {
|
|
70
|
-
await this.active
|
|
71
|
-
this.logger.debug('HMR reload complete')
|
|
72
|
-
} finally {
|
|
73
|
-
this.active = null
|
|
74
|
-
|
|
75
|
-
// If there's a pending reload, execute it now
|
|
76
|
-
if (this.hasPending && this.pendingResolvers) {
|
|
77
|
-
const { resolve, reject } = this.pendingResolvers
|
|
78
|
-
this.pendingResolvers = null
|
|
79
|
-
this.hasPending = false
|
|
80
|
-
this.executeReload().then(resolve, reject)
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Perform the actual reload via the lifecycle.
|
|
87
|
-
*/
|
|
88
|
-
private async doReload(): Promise<void> {
|
|
89
|
-
// Check if lifecycle can reload
|
|
90
|
-
if (this.lifecycle.canReload) {
|
|
91
|
-
await this.lifecycle.reload()
|
|
92
|
-
} else if (this.lifecycle.canStart) {
|
|
93
|
-
// If in failed/idle state, try to start
|
|
94
|
-
await this.lifecycle.start()
|
|
95
|
-
} else {
|
|
96
|
-
this.logger.warn(
|
|
97
|
-
{ state: this.lifecycle.currentState },
|
|
98
|
-
'Cannot reload in current state',
|
|
99
|
-
)
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Check if a reload is currently in progress.
|
|
105
|
-
*/
|
|
106
|
-
get isReloading(): boolean {
|
|
107
|
-
return this.active !== null
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Check if there's a pending reload waiting.
|
|
112
|
-
*/
|
|
113
|
-
get isPending(): boolean {
|
|
114
|
-
return this.hasPending
|
|
115
|
-
}
|
|
116
|
-
}
|