nmtjs 0.16.1 → 0.17.0-beta.2

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 (224) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +41 -1
  3. package/dist/index.d.ts +22 -161
  4. package/dist/index.js +24 -53
  5. package/dist/index.js.map +1 -1
  6. package/package.json +11 -63
  7. package/src/index.ts +71 -91
  8. package/bin/cli.js +0 -2
  9. package/dist/cli.d.ts +0 -1
  10. package/dist/cli.js +0 -137
  11. package/dist/cli.js.map +0 -1
  12. package/dist/codegen.d.ts +0 -5
  13. package/dist/codegen.js +0 -18
  14. package/dist/codegen.js.map +0 -1
  15. package/dist/config.d.ts +0 -47
  16. package/dist/config.js +0 -16
  17. package/dist/config.js.map +0 -1
  18. package/dist/entrypoints/cli.d.ts +0 -1
  19. package/dist/entrypoints/cli.js +0 -12
  20. package/dist/entrypoints/cli.js.map +0 -1
  21. package/dist/entrypoints/main.d.ts +0 -5
  22. package/dist/entrypoints/main.js +0 -248
  23. package/dist/entrypoints/main.js.map +0 -1
  24. package/dist/entrypoints/thread.d.ts +0 -16
  25. package/dist/entrypoints/thread.js +0 -182
  26. package/dist/entrypoints/thread.js.map +0 -1
  27. package/dist/entrypoints/worker.d.ts +0 -9
  28. package/dist/entrypoints/worker.js +0 -143
  29. package/dist/entrypoints/worker.js.map +0 -1
  30. package/dist/resolver.d.ts +0 -2
  31. package/dist/resolver.js +0 -7
  32. package/dist/resolver.js.map +0 -1
  33. package/dist/runtime/application/index.d.ts +0 -1
  34. package/dist/runtime/application/index.js +0 -2
  35. package/dist/runtime/application/index.js.map +0 -1
  36. package/dist/runtime/constants.d.ts +0 -8
  37. package/dist/runtime/constants.js +0 -5
  38. package/dist/runtime/constants.js.map +0 -1
  39. package/dist/runtime/enums.d.ts +0 -10
  40. package/dist/runtime/enums.js +0 -13
  41. package/dist/runtime/enums.js.map +0 -1
  42. package/dist/runtime/hooks.d.ts +0 -1
  43. package/dist/runtime/hooks.js +0 -2
  44. package/dist/runtime/hooks.js.map +0 -1
  45. package/dist/runtime/index.d.ts +0 -28
  46. package/dist/runtime/index.js +0 -29
  47. package/dist/runtime/index.js.map +0 -1
  48. package/dist/runtime/injectables.d.ts +0 -69
  49. package/dist/runtime/injectables.js +0 -40
  50. package/dist/runtime/injectables.js.map +0 -1
  51. package/dist/runtime/jobs/job.d.ts +0 -146
  52. package/dist/runtime/jobs/job.js +0 -89
  53. package/dist/runtime/jobs/job.js.map +0 -1
  54. package/dist/runtime/jobs/manager.d.ts +0 -131
  55. package/dist/runtime/jobs/manager.js +0 -309
  56. package/dist/runtime/jobs/manager.js.map +0 -1
  57. package/dist/runtime/jobs/router.d.ts +0 -296
  58. package/dist/runtime/jobs/router.js +0 -458
  59. package/dist/runtime/jobs/router.js.map +0 -1
  60. package/dist/runtime/jobs/runner.d.ts +0 -103
  61. package/dist/runtime/jobs/runner.js +0 -425
  62. package/dist/runtime/jobs/runner.js.map +0 -1
  63. package/dist/runtime/jobs/step.d.ts +0 -26
  64. package/dist/runtime/jobs/step.js +0 -18
  65. package/dist/runtime/jobs/step.js.map +0 -1
  66. package/dist/runtime/jobs/types.d.ts +0 -86
  67. package/dist/runtime/jobs/types.js +0 -5
  68. package/dist/runtime/jobs/types.js.map +0 -1
  69. package/dist/runtime/metrics/metric.d.ts +0 -8
  70. package/dist/runtime/metrics/metric.js +0 -11
  71. package/dist/runtime/metrics/metric.js.map +0 -1
  72. package/dist/runtime/metrics/registry.d.ts +0 -3
  73. package/dist/runtime/metrics/registry.js +0 -5
  74. package/dist/runtime/metrics/registry.js.map +0 -1
  75. package/dist/runtime/metrics/server.d.ts +0 -7
  76. package/dist/runtime/metrics/server.js +0 -53
  77. package/dist/runtime/metrics/server.js.map +0 -1
  78. package/dist/runtime/plugin.d.ts +0 -2
  79. package/dist/runtime/plugin.js +0 -2
  80. package/dist/runtime/plugin.js.map +0 -1
  81. package/dist/runtime/runtime.d.ts +0 -27
  82. package/dist/runtime/runtime.js +0 -77
  83. package/dist/runtime/runtime.js.map +0 -1
  84. package/dist/runtime/scheduler/index.d.ts +0 -22
  85. package/dist/runtime/scheduler/index.js +0 -20
  86. package/dist/runtime/scheduler/index.js.map +0 -1
  87. package/dist/runtime/server/applications.d.ts +0 -91
  88. package/dist/runtime/server/applications.js +0 -171
  89. package/dist/runtime/server/applications.js.map +0 -1
  90. package/dist/runtime/server/config.d.ts +0 -148
  91. package/dist/runtime/server/config.js +0 -33
  92. package/dist/runtime/server/config.js.map +0 -1
  93. package/dist/runtime/server/environment.d.ts +0 -43
  94. package/dist/runtime/server/environment.js +0 -33
  95. package/dist/runtime/server/environment.js.map +0 -1
  96. package/dist/runtime/server/error-policy.d.ts +0 -62
  97. package/dist/runtime/server/error-policy.js +0 -73
  98. package/dist/runtime/server/error-policy.js.map +0 -1
  99. package/dist/runtime/server/hmr-coordinator.d.ts +0 -37
  100. package/dist/runtime/server/hmr-coordinator.js +0 -94
  101. package/dist/runtime/server/hmr-coordinator.js.map +0 -1
  102. package/dist/runtime/server/jobs.d.ts +0 -54
  103. package/dist/runtime/server/jobs.js +0 -176
  104. package/dist/runtime/server/jobs.js.map +0 -1
  105. package/dist/runtime/server/lifecycle.d.ts +0 -85
  106. package/dist/runtime/server/lifecycle.js +0 -177
  107. package/dist/runtime/server/lifecycle.js.map +0 -1
  108. package/dist/runtime/server/managed-worker.d.ts +0 -158
  109. package/dist/runtime/server/managed-worker.js +0 -420
  110. package/dist/runtime/server/managed-worker.js.map +0 -1
  111. package/dist/runtime/server/pool-manager.d.ts +0 -85
  112. package/dist/runtime/server/pool-manager.js +0 -129
  113. package/dist/runtime/server/pool-manager.js.map +0 -1
  114. package/dist/runtime/server/proxy.d.ts +0 -21
  115. package/dist/runtime/server/proxy.js +0 -76
  116. package/dist/runtime/server/proxy.js.map +0 -1
  117. package/dist/runtime/server/server.d.ts +0 -60
  118. package/dist/runtime/server/server.js +0 -163
  119. package/dist/runtime/server/server.js.map +0 -1
  120. package/dist/runtime/server/types.d.ts +0 -31
  121. package/dist/runtime/server/types.js +0 -2
  122. package/dist/runtime/server/types.js.map +0 -1
  123. package/dist/runtime/server/worker-pool.d.ts +0 -121
  124. package/dist/runtime/server/worker-pool.js +0 -171
  125. package/dist/runtime/server/worker-pool.js.map +0 -1
  126. package/dist/runtime/store/index.d.ts +0 -3
  127. package/dist/runtime/store/index.js +0 -23
  128. package/dist/runtime/store/index.js.map +0 -1
  129. package/dist/runtime/subscription/manager.d.ts +0 -49
  130. package/dist/runtime/subscription/manager.js +0 -170
  131. package/dist/runtime/subscription/manager.js.map +0 -1
  132. package/dist/runtime/subscription/redis.d.ts +0 -18
  133. package/dist/runtime/subscription/redis.js +0 -119
  134. package/dist/runtime/subscription/redis.js.map +0 -1
  135. package/dist/runtime/types.d.ts +0 -95
  136. package/dist/runtime/types.js +0 -2
  137. package/dist/runtime/types.js.map +0 -1
  138. package/dist/runtime/workers/application.d.ts +0 -29
  139. package/dist/runtime/workers/application.js +0 -77
  140. package/dist/runtime/workers/application.js.map +0 -1
  141. package/dist/runtime/workers/base.d.ts +0 -14
  142. package/dist/runtime/workers/base.js +0 -41
  143. package/dist/runtime/workers/base.js.map +0 -1
  144. package/dist/runtime/workers/cli.d.ts +0 -1
  145. package/dist/runtime/workers/cli.js +0 -2
  146. package/dist/runtime/workers/cli.js.map +0 -1
  147. package/dist/runtime/workers/job.d.ts +0 -20
  148. package/dist/runtime/workers/job.js +0 -170
  149. package/dist/runtime/workers/job.js.map +0 -1
  150. package/dist/vite/builder.d.ts +0 -5
  151. package/dist/vite/builder.js +0 -79
  152. package/dist/vite/builder.js.map +0 -1
  153. package/dist/vite/config.d.ts +0 -28
  154. package/dist/vite/config.js +0 -22
  155. package/dist/vite/config.js.map +0 -1
  156. package/dist/vite/plugins.d.ts +0 -2
  157. package/dist/vite/plugins.js +0 -43
  158. package/dist/vite/plugins.js.map +0 -1
  159. package/dist/vite/runners/worker.d.ts +0 -3
  160. package/dist/vite/runners/worker.js +0 -34
  161. package/dist/vite/runners/worker.js.map +0 -1
  162. package/dist/vite/server.d.ts +0 -3
  163. package/dist/vite/server.js +0 -36
  164. package/dist/vite/server.js.map +0 -1
  165. package/dist/vite/servers/main.d.ts +0 -8
  166. package/dist/vite/servers/main.js +0 -24
  167. package/dist/vite/servers/main.js.map +0 -1
  168. package/dist/vite/servers/worker.d.ts +0 -13
  169. package/dist/vite/servers/worker.js +0 -124
  170. package/dist/vite/servers/worker.js.map +0 -1
  171. package/src/cli.ts +0 -162
  172. package/src/codegen.ts +0 -30
  173. package/src/config.ts +0 -69
  174. package/src/entrypoints/cli.ts +0 -13
  175. package/src/entrypoints/main.ts +0 -317
  176. package/src/entrypoints/thread.ts +0 -223
  177. package/src/entrypoints/worker.ts +0 -174
  178. package/src/resolver.ts +0 -7
  179. package/src/runtime/application/index.ts +0 -1
  180. package/src/runtime/constants.ts +0 -13
  181. package/src/runtime/enums.ts +0 -12
  182. package/src/runtime/hooks.ts +0 -1
  183. package/src/runtime/index.ts +0 -29
  184. package/src/runtime/injectables.ts +0 -101
  185. package/src/runtime/jobs/job.ts +0 -467
  186. package/src/runtime/jobs/manager.ts +0 -454
  187. package/src/runtime/jobs/router.ts +0 -967
  188. package/src/runtime/jobs/runner.ts +0 -583
  189. package/src/runtime/jobs/step.ts +0 -66
  190. package/src/runtime/jobs/types.ts +0 -116
  191. package/src/runtime/metrics/metric.ts +0 -18
  192. package/src/runtime/metrics/registry.ts +0 -11
  193. package/src/runtime/metrics/server.ts +0 -69
  194. package/src/runtime/plugin.ts +0 -2
  195. package/src/runtime/runtime.ts +0 -103
  196. package/src/runtime/scheduler/index.ts +0 -39
  197. package/src/runtime/server/applications.ts +0 -264
  198. package/src/runtime/server/config.ts +0 -199
  199. package/src/runtime/server/environment.ts +0 -71
  200. package/src/runtime/server/error-policy.ts +0 -132
  201. package/src/runtime/server/hmr-coordinator.ts +0 -116
  202. package/src/runtime/server/jobs.ts +0 -266
  203. package/src/runtime/server/lifecycle.ts +0 -234
  204. package/src/runtime/server/managed-worker.ts +0 -546
  205. package/src/runtime/server/pool-manager.ts +0 -187
  206. package/src/runtime/server/proxy.ts +0 -119
  207. package/src/runtime/server/server.ts +0 -218
  208. package/src/runtime/server/types.ts +0 -32
  209. package/src/runtime/server/worker-pool.ts +0 -275
  210. package/src/runtime/store/index.ts +0 -30
  211. package/src/runtime/subscription/manager.ts +0 -307
  212. package/src/runtime/subscription/redis.ts +0 -159
  213. package/src/runtime/types.ts +0 -84
  214. package/src/runtime/workers/application.ts +0 -133
  215. package/src/runtime/workers/base.ts +0 -65
  216. package/src/runtime/workers/cli.ts +0 -0
  217. package/src/runtime/workers/job.ts +0 -142
  218. package/src/vite/builder.ts +0 -94
  219. package/src/vite/config.ts +0 -45
  220. package/src/vite/plugins.ts +0 -53
  221. package/src/vite/runners/worker.ts +0 -55
  222. package/src/vite/server.ts +0 -55
  223. package/src/vite/servers/main.ts +0 -41
  224. package/src/vite/servers/worker.ts +0 -177
@@ -1,159 +0,0 @@
1
- import EventEmitter, { on } from 'node:events'
2
-
3
- import type { RuntimePlugin } from '@nmtjs/application'
4
- import type { Logger } from '@nmtjs/core'
5
- import { isAbortError } from '@nmtjs/common'
6
- import {
7
- CoreInjectables,
8
- createFactoryInjectable,
9
- provision,
10
- } from '@nmtjs/core'
11
-
12
- import type { Store } from '../types.ts'
13
- import type {
14
- SubscriptionAdapterEvent,
15
- SubscriptionAdapterType,
16
- } from './manager.ts'
17
- import { storeConfig, subscriptionAdapter } from '../injectables.ts'
18
- import { createStoreClient } from '../store/index.ts'
19
-
20
- export class RedisSubscriptionAdapter implements SubscriptionAdapterType {
21
- protected readonly events = new EventEmitter()
22
- protected readonly listeners = new Map<string, number>()
23
- protected readonly logger?: Logger
24
- protected subscriberClient?: Store
25
-
26
- constructor(
27
- protected readonly client: Store,
28
- logger?: Logger,
29
- ) {
30
- this.logger = logger?.child({ component: RedisSubscriptionAdapter.name })
31
- }
32
-
33
- async initialize() {
34
- this.logger?.debug('Initializing Redis adapter')
35
-
36
- // Create a dedicated subscriber client (Redis requires separate clients for pub/sub)
37
- this.subscriberClient = this.client.duplicate()
38
-
39
- // Set up message handler
40
- this.subscriberClient.on('message', (channel: string, message: string) => {
41
- try {
42
- const parsed = JSON.parse(message)
43
- this.logger?.trace({ channel }, 'Received Redis message')
44
- this.events.emit(channel, parsed)
45
- } catch (error) {
46
- this.logger?.warn({ channel, error }, 'Failed to parse Redis message')
47
- }
48
- })
49
-
50
- this.logger?.debug('Redis adapter initialized')
51
- }
52
-
53
- async dispose() {
54
- this.logger?.debug('Disposing Redis adapter')
55
-
56
- if (this.subscriberClient) {
57
- await this.subscriberClient.quit()
58
- this.subscriberClient = undefined
59
- }
60
-
61
- this.logger?.debug('Redis adapter disposed')
62
- }
63
-
64
- async publish(channel: string, payload: any): Promise<boolean> {
65
- this.logger?.trace({ channel }, 'Publishing Redis message')
66
-
67
- try {
68
- await this.client.publish(channel, JSON.stringify(payload))
69
- this.logger?.trace({ channel }, 'Published Redis message')
70
- return true
71
- } catch (error) {
72
- this.logger?.warn({ channel, error }, 'Failed to publish Redis message')
73
- return false
74
- }
75
- }
76
-
77
- async *subscribe(
78
- channel: string,
79
- signal?: AbortSignal,
80
- ): AsyncGenerator<SubscriptionAdapterEvent> {
81
- if (!this.subscriberClient) {
82
- throw new Error('RedisSubscriptionAdapter not initialized')
83
- }
84
-
85
- this.logger?.debug({ channel }, 'Opening Redis channel listener')
86
-
87
- if (!this.listeners.has(channel)) {
88
- await this.subscriberClient.subscribe(channel)
89
- this.listeners.set(channel, 1)
90
- this.logger?.debug({ channel, listeners: 1 }, 'Subscribed Redis channel')
91
- } else {
92
- const listeners = this.listeners.get(channel)! + 1
93
- this.listeners.set(channel, listeners)
94
- this.logger?.trace(
95
- { channel, listeners },
96
- 'Reusing Redis channel listener',
97
- )
98
- }
99
-
100
- try {
101
- signal?.throwIfAborted()
102
- for await (const [payload] of on(this.events, channel, { signal })) {
103
- this.logger?.trace({ channel }, 'Delivering Redis message')
104
- yield { channel, payload }
105
- }
106
- } catch (error: any) {
107
- if (isAbortError(error)) {
108
- this.logger?.trace({ channel }, 'Redis channel listener aborted')
109
- throw error
110
- }
111
-
112
- this.logger?.warn({ channel, error }, 'Redis channel listener failed')
113
- } finally {
114
- const count = this.listeners.get(channel)
115
- if (count !== undefined) {
116
- if (count > 1) {
117
- const listeners = count - 1
118
- this.listeners.set(channel, listeners)
119
- this.logger?.trace(
120
- { channel, listeners },
121
- 'Detached Redis channel listener',
122
- )
123
- } else {
124
- await this.subscriberClient?.unsubscribe(channel)
125
- this.listeners.delete(channel)
126
- this.logger?.debug(
127
- { channel, listeners: 0 },
128
- 'Unsubscribed Redis channel',
129
- )
130
- }
131
- }
132
- }
133
- }
134
- }
135
-
136
- export const RedisSubscriptionAdapterPlugin = (): RuntimePlugin => {
137
- const adapterFactory = createFactoryInjectable(
138
- {
139
- dependencies: { config: storeConfig, logger: CoreInjectables.logger },
140
- factory: async ({ config, logger }) => {
141
- const connection = await createStoreClient(config)
142
- const adapter = new RedisSubscriptionAdapter(connection, logger)
143
- await adapter.initialize()
144
- return { adapter, connection }
145
- },
146
- pick: ({ adapter }) => adapter,
147
- dispose: async ({ adapter, connection }) => {
148
- await adapter.dispose()
149
- await connection.quit()
150
- },
151
- },
152
- 'RedisSubscriptionAdapter',
153
- )
154
-
155
- return {
156
- name: 'redis-subscription-adapter',
157
- injections: [provision(subscriptionAdapter, adapterFactory)],
158
- }
159
- }
@@ -1,84 +0,0 @@
1
- import type { ApplicationHostDefinition } from '@nmtjs/application'
2
- import type { ProxyableTransportType } from '@nmtjs/gateway'
3
- import type { Redis, RedisOptions } from 'ioredis'
4
- import type { Redis as Valkey, RedisOptions as ValkeyOptions } from 'iovalkey'
5
-
6
- import type { StoreType } from './enums.ts'
7
-
8
- export type WorkerThreadErrorOrigin = 'bootstrap' | 'start' | 'runtime'
9
-
10
- export type ThreadErrorMessage = {
11
- message: string
12
- name?: string
13
- stack?: string
14
- origin: WorkerThreadErrorOrigin
15
- fatal: boolean
16
- }
17
-
18
- export type WorkerThreadError = Error & {
19
- origin?: WorkerThreadErrorOrigin
20
- fatal?: boolean
21
- }
22
-
23
- export type ServerPortMessageTypes = {
24
- stop: undefined
25
- task: { id: string; task: WorkerJobTask }
26
- }
27
-
28
- export type ThreadPortMessageTypes = {
29
- ready: { hosts?: { type: ProxyableTransportType; url: string }[] }
30
- error: ThreadErrorMessage
31
- task: { id: string; task: JobTaskResult }
32
- }
33
-
34
- export type ServerPortMessage = {
35
- [K in keyof ServerPortMessageTypes]: {
36
- type: K
37
- data: ServerPortMessageTypes[K]
38
- }
39
- }[keyof ServerPortMessageTypes]
40
-
41
- export type ThreadPortMessage = {
42
- [K in keyof ThreadPortMessageTypes]: {
43
- type: K
44
- data: ThreadPortMessageTypes[K]
45
- }
46
- }[keyof ThreadPortMessageTypes]
47
-
48
- export interface WorkerTask {
49
- type?: string
50
- payload?: any
51
- }
52
-
53
- export type WorkerJobTask = { jobId: string; jobName: string; data: any }
54
-
55
- export type JobTaskResult = {
56
- [K in keyof JobTaskResultTypes]: { type: K } & JobTaskResultTypes[K]
57
- }[keyof JobTaskResultTypes]
58
-
59
- export type JobTaskResultTypes = {
60
- success: { result?: unknown }
61
- error: { error: any }
62
- unrecoverable_error: { error: any }
63
- job_not_found: {}
64
- queue_job_not_found: {}
65
- }
66
-
67
- export type ApplicationDefinitionType =
68
- | { type: 'neemata'; definition: ApplicationHostDefinition }
69
- | { type: 'custom'; definition: any }
70
-
71
- export interface Applications
72
- extends Record<string, ApplicationDefinitionType> {}
73
-
74
- export type StoreTypes = {
75
- [StoreType.Redis]: Redis
76
- [StoreType.Valkey]: Valkey
77
- }
78
- export type StoreTypeOptions = {
79
- [StoreType.Redis]: RedisOptions
80
- [StoreType.Valkey]: ValkeyOptions
81
- }
82
-
83
- export type Store = StoreTypes[StoreType]
84
- export type StoreOptions = StoreTypeOptions[StoreType]
@@ -1,133 +0,0 @@
1
- import type {
2
- ApplicationHost,
3
- ApplicationHostDefinition,
4
- ApplicationHostOptions,
5
- ApplicationResolvedProcedure,
6
- ApplicationTransport,
7
- NeemataApplication,
8
- TransportOptionsOf,
9
- } from '@nmtjs/application'
10
- import type { Gateway, GatewayOptions } from '@nmtjs/gateway'
11
- import { createApplicationHost, LifecycleHook } from '@nmtjs/application'
12
- import { JsonFormat } from '@nmtjs/json-format/server'
13
- import { MsgpackFormat } from '@nmtjs/msgpack-format/server'
14
- import { ProtocolFormats } from '@nmtjs/protocol/server'
15
-
16
- import type { ServerApplicationConfig, ServerConfig } from '../server/config.ts'
17
- import { WorkerType } from '../enums.ts'
18
- import { BaseWorkerRuntime } from './base.ts'
19
-
20
- export interface ApplicationWorkerRuntimeOptions {
21
- name: string
22
- path: string
23
- transports: ServerApplicationConfig['threads'][number]
24
- }
25
-
26
- export class ApplicationWorkerRuntime extends BaseWorkerRuntime {
27
- host!: ApplicationHost
28
-
29
- constructor(
30
- readonly config: ServerConfig,
31
- readonly runtimeOptions: ApplicationWorkerRuntimeOptions,
32
- protected hostDefinition: ApplicationHostDefinition,
33
- ) {
34
- super(
35
- config,
36
- {
37
- logger: config.logger,
38
- name: `Worker ${runtimeOptions.name}`,
39
- plugins: [],
40
- },
41
- WorkerType.Application,
42
- )
43
- }
44
-
45
- get application(): NeemataApplication {
46
- return this.host.application
47
- }
48
-
49
- get api() {
50
- return this.application.api
51
- }
52
-
53
- get applicationHooks() {
54
- return this.application.applicationHooks
55
- }
56
-
57
- get gateway(): Gateway<ApplicationResolvedProcedure> {
58
- return this.host.gateway
59
- }
60
-
61
- get transports(): GatewayOptions<ApplicationResolvedProcedure>['transports'] {
62
- return this.host.transports
63
- }
64
-
65
- async start() {
66
- await this.initialize()
67
- this.host = createApplicationHost(this.hostDefinition.application, {
68
- name: this.runtimeOptions.name,
69
- logger: this.logger,
70
- container: this.container,
71
- formats: new ProtocolFormats([new JsonFormat(), new MsgpackFormat()]),
72
- ...this.resolveHostOptions(),
73
- })
74
- return this.host.start()
75
- }
76
-
77
- async stop() {
78
- await this.host.stop()
79
- await this.dispose()
80
- await this.lifecycleHooks.callHook(LifecycleHook.Stop)
81
- }
82
-
83
- async reload(hostDefinition: ApplicationHostDefinition): Promise<void> {
84
- this.hostDefinition = hostDefinition
85
- await this.host.reloadApplication(hostDefinition.application)
86
- }
87
-
88
- protected *_dependents() {}
89
-
90
- protected resolveHostOptions(): Pick<
91
- ApplicationHostOptions,
92
- 'transports' | 'gateway' | 'identity'
93
- > {
94
- const config = this.config.applications[
95
- this.runtimeOptions.name
96
- ] as ServerApplicationConfig
97
-
98
- if (!config) {
99
- throw new Error(
100
- `Missing server application config: ${this.runtimeOptions.name}`,
101
- )
102
- }
103
-
104
- return {
105
- transports: createHostTransportConfig(
106
- this.hostDefinition.transports,
107
- this.runtimeOptions.transports,
108
- ),
109
- gateway: this.hostDefinition.gateway,
110
- identity: this.hostDefinition.identity,
111
- }
112
- }
113
- }
114
-
115
- function createHostTransportConfig<
116
- Transports extends Record<string, ApplicationTransport>,
117
- >(
118
- transports: Transports,
119
- options: { [K in keyof Transports]: TransportOptionsOf<Transports[K]> },
120
- ) {
121
- const config = {} as {
122
- [K in keyof Transports]: {
123
- transport: Transports[K]
124
- options: TransportOptionsOf<Transports[K]>
125
- }
126
- }
127
-
128
- for (const key in transports) {
129
- config[key] = { transport: transports[key], options: options[key] }
130
- }
131
-
132
- return config
133
- }
@@ -1,65 +0,0 @@
1
- import type { Provision } from '@nmtjs/core'
2
- import { CoreInjectables, provision } from '@nmtjs/core'
3
-
4
- import type { WorkerType } from '../enums.ts'
5
- import type { BaseRuntimeOptions } from '../runtime.ts'
6
- import type { ServerConfig } from '../server/config.ts'
7
- import * as injectables from '../injectables.ts'
8
- import { JobManager } from '../jobs/manager.ts'
9
- import { BaseRuntime } from '../runtime.ts'
10
-
11
- export abstract class BaseWorkerRuntime extends BaseRuntime {
12
- jobManager?: JobManager
13
-
14
- constructor(
15
- readonly config: ServerConfig,
16
- options: BaseRuntimeOptions,
17
- readonly workerType: WorkerType,
18
- ) {
19
- super(options)
20
-
21
- if (this.config.store) {
22
- this.jobManager = new JobManager(
23
- this.config.store,
24
- this.config.jobs ? Array.from(this.config.jobs.jobs.values()) : [],
25
- )
26
- }
27
- }
28
-
29
- async initialize(): Promise<void> {
30
- const injections: Provision[] = [
31
- provision(CoreInjectables.logger, this.logger),
32
- provision(injectables.workerType, this.workerType),
33
- ]
34
-
35
- if (this.config.store) {
36
- injections.push(provision(injectables.storeConfig, this.config.store))
37
- }
38
-
39
- if (this.config.subscription) {
40
- injections.push(
41
- provision(
42
- injectables.subscriptionAdapter,
43
- this.config.subscription.adapter,
44
- ),
45
- )
46
- }
47
-
48
- if (this.jobManager) {
49
- injections.push(
50
- provision(injectables.jobManager, this.jobManager.publicInstance),
51
- )
52
- }
53
-
54
- this.container.provide(injections)
55
- await super.initialize()
56
- }
57
-
58
- protected async _initialize(): Promise<void> {
59
- await this.jobManager?.initialize()
60
- }
61
-
62
- protected async _dispose(): Promise<void> {
63
- await this.jobManager?.terminate()
64
- }
65
- }
File without changes
@@ -1,142 +0,0 @@
1
- import type { MessagePort } from 'node:worker_threads'
2
-
3
- import { LifecycleHook } from '@nmtjs/application'
4
- import { UnrecoverableError } from 'bullmq'
5
-
6
- import type { JobProgressCheckpoint } from '../jobs/types.ts'
7
- import type { ServerConfig } from '../server/config.ts'
8
- import type { ServerPortMessage, ThreadPortMessage } from '../types.ts'
9
- import { WorkerType } from '../enums.ts'
10
- import { jobWorkerPool } from '../injectables.ts'
11
- import { ApplicationWorkerJobRunner } from '../jobs/runner.ts'
12
- import { BaseWorkerRuntime } from './base.ts'
13
-
14
- export interface JobWorkerRuntimeOptions {
15
- poolName: string
16
- port: MessagePort
17
- }
18
-
19
- export class JobWorkerRuntime extends BaseWorkerRuntime {
20
- jobRunner!: ApplicationWorkerJobRunner
21
-
22
- constructor(
23
- readonly config: ServerConfig,
24
- readonly runtimeOptions: JobWorkerRuntimeOptions,
25
- ) {
26
- super(
27
- config,
28
- { logger: config.logger, name: `Job Worker ${runtimeOptions.poolName}` },
29
- WorkerType.Job,
30
- )
31
- }
32
-
33
- async start() {
34
- await this.initialize()
35
- await this.lifecycleHooks.callHook(LifecycleHook.Start)
36
- }
37
-
38
- async stop() {
39
- await this.lifecycleHooks.callHook(LifecycleHook.Stop)
40
- await this.dispose()
41
- }
42
-
43
- async initialize(): Promise<void> {
44
- // Validate all jobs are complete before accepting work
45
- if (this.config.jobs) {
46
- for (const job of this.config.jobs.jobs.values()) {
47
- if (!job.returnHandler) {
48
- throw new Error(
49
- `Job "${job.name}" is incomplete. Jobs must call .return() to be finalized before use.`,
50
- )
51
- }
52
- }
53
- }
54
-
55
- this.container.provide(jobWorkerPool, this.runtimeOptions.poolName)
56
- await super.initialize()
57
- }
58
-
59
- protected async _initialize(): Promise<void> {
60
- await super._initialize()
61
-
62
- this.jobRunner = new ApplicationWorkerJobRunner({
63
- logger: this.logger,
64
- container: this.container,
65
- lifecycleHooks: this.lifecycleHooks,
66
- })
67
-
68
- this.runtimeOptions.port.on('message', async (msg: ServerPortMessage) => {
69
- if (msg.type === 'task') {
70
- const { id, task } = msg.data
71
- try {
72
- const job = this.config.jobs?.jobs.get(task.jobName)
73
- if (!job) {
74
- this.runtimeOptions.port.postMessage({
75
- type: 'task',
76
- data: { id, task: { type: 'job_not_found' } },
77
- } satisfies ThreadPortMessage)
78
- return
79
- }
80
-
81
- using cancellationSignal = this.jobManager!.cancellationSignal(
82
- job,
83
- task.jobId,
84
- )
85
- const queue = this.jobManager!.getQueue(job).queue
86
- const bullJob = await queue.getJob(task.jobId)
87
- if (!bullJob) {
88
- throw new UnrecoverableError(
89
- `Job ${task.jobId} not found in queue (may have been removed)`,
90
- )
91
- }
92
-
93
- // Load checkpoint from BullMQ progress for resume support
94
- const checkpoint = bullJob.progress as
95
- | JobProgressCheckpoint
96
- | undefined
97
-
98
- const result = await this.jobRunner.runJob(job, task.data, {
99
- signal: cancellationSignal,
100
- queueJob: bullJob,
101
- result: checkpoint?.result,
102
- stepResults: checkpoint?.stepResults,
103
- currentStepIndex: checkpoint?.stepIndex ?? 0,
104
- progress: checkpoint?.progress,
105
- })
106
- this.runtimeOptions.port.postMessage({
107
- type: 'task',
108
- data: { id, task: { type: 'success', result } },
109
- })
110
- } catch (error) {
111
- if (error instanceof UnrecoverableError) {
112
- this.runtimeOptions.port.postMessage({
113
- type: 'task',
114
- data: { id, task: { type: 'unrecoverable_error', error } },
115
- } satisfies ThreadPortMessage)
116
- } else {
117
- this.runtimeOptions.port.postMessage({
118
- type: 'task',
119
- data: { id, task: { type: 'error', error } },
120
- } satisfies ThreadPortMessage)
121
- }
122
- }
123
- }
124
- })
125
- }
126
-
127
- protected async _dispose(): Promise<void> {
128
- this.runtimeOptions.port.removeAllListeners('message')
129
- await super._dispose()
130
- }
131
-
132
- protected *_dependents() {
133
- if (this.config.jobs) {
134
- for (const job of this.config.jobs.jobs.values()) {
135
- yield job
136
- // we explicitly DO NOT WANT to yield steps here, so per-job container
137
- // resolves them independently each time — creates more isolation
138
- // yield* job.jobSteps
139
- }
140
- }
141
- }
142
- }
@@ -1,94 +0,0 @@
1
- import { isBuiltin } from 'node:module'
2
- import { resolve } from 'node:path'
3
-
4
- import type { UserConfig } from 'vite'
5
- import { mergeConfig, build as viteBuild } from 'vite'
6
-
7
- import type { NeemataConfig } from '../config.ts'
8
- import type { ViteConfigOptions } from './config.ts'
9
- import { createConfig } from './config.ts'
10
- import { plugins } from './plugins.ts'
11
-
12
- export async function createBuilder(
13
- configOptions: ViteConfigOptions,
14
- neemataConfig: NeemataConfig,
15
- ) {
16
- const config = createConfig(configOptions)
17
- async function build(): Promise<any> {
18
- const packageJson = await import(resolve('./package.json'), {
19
- with: { type: 'json' },
20
- }).then((mod) => mod.default)
21
-
22
- return await viteBuild(
23
- mergeConfig(
24
- {
25
- appType: 'custom',
26
- clearScreen: false,
27
- resolve: { alias: config.alias, noExternal: true },
28
- plugins: [...plugins],
29
- build: {
30
- lib: { entry: config.entries, formats: ['es'] },
31
- ssr: true,
32
- ssrEmitAssets: true,
33
- target: 'node24',
34
- sourcemap: true,
35
- outDir: resolve('./dist'),
36
- minify: true,
37
- emptyOutDir: true,
38
- rolldownOptions: {
39
- platform: 'node',
40
- external: (id) => {
41
- if (neemataConfig.externalDependencies === 'all') return true
42
- if (
43
- isBuiltin(id) ||
44
- id.includes('nmtjs/src/vite/servers') ||
45
- id.includes('nmtjs/src/vite/runners')
46
- )
47
- return true
48
-
49
- if (neemataConfig.externalDependencies === 'prod') {
50
- const prodDeps = Object.keys(packageJson.dependencies ?? {})
51
- if (prodDeps.includes(id)) return true
52
- }
53
-
54
- if (Array.isArray(neemataConfig.externalDependencies)) {
55
- for (const dep of neemataConfig.externalDependencies) {
56
- if (typeof dep === 'string' && dep === id) return true
57
- if (dep instanceof RegExp && dep.test(id)) return true
58
- }
59
- }
60
-
61
- return false
62
- },
63
- transform: {
64
- define: {
65
- __VITE_CONFIG__: '""',
66
- __APPLICATIONS_CONFIG__: JSON.stringify(
67
- JSON.stringify(
68
- Object.fromEntries(
69
- Object.entries(configOptions.applicationImports).map(
70
- ([appName, { type }]) => [
71
- appName,
72
- { type, specifier: `./application.${appName}.js` },
73
- ],
74
- ),
75
- ),
76
- ),
77
- ),
78
- },
79
- },
80
- output: {
81
- entryFileNames: '[name].js',
82
- chunkFileNames: '[name]-[hash].js',
83
- assetFileNames: '[name][extname]',
84
- },
85
- },
86
- chunkSizeWarningLimit: 10_000,
87
- },
88
- } satisfies UserConfig,
89
- neemataConfig.vite,
90
- ),
91
- )
92
- }
93
- return { build }
94
- }