@camstack/server 0.1.8 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -7
- package/src/__tests__/addon-install-e2e.test.ts +0 -1
- package/src/__tests__/addon-pages-e2e.test.ts +40 -18
- package/src/__tests__/addon-settings-router.spec.ts +6 -1
- package/src/__tests__/addon-upload.spec.ts +91 -29
- package/src/__tests__/agent-registry.spec.ts +26 -9
- package/src/__tests__/agent-status-page.spec.ts +1 -3
- package/src/__tests__/auth-session-cookie.test.ts +28 -1
- package/src/__tests__/bulk-update-coordinator.spec.ts +48 -31
- package/src/__tests__/cap-ownership-authority.spec.ts +39 -8
- package/src/__tests__/cap-providers/cap-providers-location-import.spec.ts +24 -4
- package/src/__tests__/cap-providers/cap-usage-graph.spec.ts +17 -3
- package/src/__tests__/cap-providers/compute-topology-categories.spec.ts +57 -11
- package/src/__tests__/cap-providers/integrations-delete-cascade.spec.ts +64 -15
- package/src/__tests__/cap-providers-bulk-update.spec.ts +27 -7
- package/src/__tests__/cap-route-adapter.spec.ts +28 -15
- package/src/__tests__/cap-routers/_meta.spec.ts +6 -7
- package/src/__tests__/cap-routers/addon-settings.router.spec.ts +19 -10
- package/src/__tests__/cap-routers/broker-routing.router.spec.ts +14 -6
- package/src/__tests__/cap-routers/cap-route-error-formatter.spec.ts +3 -1
- package/src/__tests__/cap-routers/capabilities-node.spec.ts +18 -5
- package/src/__tests__/cap-routers/device-link-overlay.spec.ts +11 -6
- package/src/__tests__/cap-routers/device-manager-aggregate.router.spec.ts +72 -20
- package/src/__tests__/cap-routers/harness.ts +11 -7
- package/src/__tests__/cap-routers/metrics-provider.router.spec.ts +17 -3
- package/src/__tests__/cap-routers/null-provider-guard.spec.ts +5 -7
- package/src/__tests__/cap-routers/pipeline-executor.router.spec.ts +35 -11
- package/src/__tests__/cap-routers/settings-store.router.spec.ts +59 -15
- package/src/__tests__/capability-e2e.test.ts +9 -11
- package/src/__tests__/cli-e2e.test.ts +80 -59
- package/src/__tests__/core-cap-bridge.spec.ts +3 -1
- package/src/__tests__/dev-bootstrap-shm-ring.spec.ts +12 -2
- package/src/__tests__/device-settings-contribution-dispatch.spec.ts +61 -30
- package/src/__tests__/embedded-deps-e2e.test.ts +35 -19
- package/src/__tests__/event-bus-proxy-router.spec.ts +3 -0
- package/src/__tests__/framework-allowlist.spec.ts +5 -4
- package/src/__tests__/https-e2e.test.ts +12 -6
- package/src/__tests__/lifecycle-e2e.test.ts +60 -11
- package/src/__tests__/live-events-subscription.spec.ts +17 -18
- package/src/__tests__/moleculer/uds-readiness.spec.ts +11 -4
- package/src/__tests__/moleculer/uds-topology.spec.ts +39 -11
- package/src/__tests__/moleculer/uds-unowned-call.spec.ts +71 -17
- package/src/__tests__/moleculer-register-node-idempotency.spec.ts +16 -7
- package/src/__tests__/native-cap-route.spec.ts +42 -19
- package/src/__tests__/oauth2-account-linking.spec.ts +63 -17
- package/src/__tests__/singleton-contention.test.ts +23 -11
- package/src/__tests__/streaming-diagnostic.test.ts +156 -53
- package/src/__tests__/streaming-scale.test.ts +69 -35
- package/src/__tests__/uds-addon-call-wiring.spec.ts +6 -1
- package/src/agent-status-page.ts +4 -3
- package/src/api/__tests__/addons-custom.spec.ts +22 -8
- package/src/api/__tests__/capabilities.router.test.ts +18 -9
- package/src/api/addon-upload.ts +46 -15
- package/src/api/addons-custom.router.ts +7 -6
- package/src/api/auth-whoami.ts +3 -1
- package/src/api/bridge-addons.router.ts +3 -1
- package/src/api/capabilities.router.ts +117 -78
- package/src/api/core/__tests__/auth-router-totp.spec.ts +57 -16
- package/src/api/core/addon-settings.router.ts +4 -1
- package/src/api/core/agents.router.ts +52 -53
- package/src/api/core/auth.router.ts +55 -36
- package/src/api/core/bulk-update-coordinator.ts +25 -22
- package/src/api/core/cap-providers.ts +346 -202
- package/src/api/core/capabilities.router.ts +30 -23
- package/src/api/core/hwaccel.router.ts +37 -10
- package/src/api/core/live-events.router.ts +16 -9
- package/src/api/core/logs.router.ts +54 -25
- package/src/api/core/notifications.router.ts +2 -1
- package/src/api/core/repl.router.ts +1 -3
- package/src/api/core/settings-backend.router.ts +68 -70
- package/src/api/core/system-events.router.ts +41 -32
- package/src/api/health/health.routes.ts +7 -13
- package/src/api/oauth2/__tests__/oauth2-routes.spec.ts +12 -2
- package/src/api/oauth2/consent-page.ts +4 -3
- package/src/api/oauth2/oauth2-routes.ts +41 -12
- package/src/api/trpc/__tests__/scope-access-device.spec.ts +68 -23
- package/src/api/trpc/__tests__/scope-access.spec.ts +8 -13
- package/src/api/trpc/__tests__/webrtc-session-ua-enrich.spec.ts +10 -2
- package/src/api/trpc/cap-mount-helpers.ts +64 -55
- package/src/api/trpc/cap-route-error-formatter.ts +17 -9
- package/src/api/trpc/core-cap-bridge.ts +3 -1
- package/src/api/trpc/generated-cap-mounts.ts +593 -351
- package/src/api/trpc/generated-cap-routers.ts +3680 -579
- package/src/api/trpc/scope-access.ts +7 -7
- package/src/api/trpc/trpc.context.ts +7 -4
- package/src/api/trpc/trpc.middleware.ts +4 -2
- package/src/api/trpc/trpc.router.ts +79 -46
- package/src/auth/session-cookie.ts +10 -0
- package/src/boot/__tests__/integration-id-backfill.spec.ts +21 -6
- package/src/boot/boot-config.ts +103 -122
- package/src/boot/post-boot.service.ts +5 -3
- package/src/core/addon/__tests__/addon-registry-capability.test.ts +12 -3
- package/src/core/addon/addon-call-gateway.ts +20 -6
- package/src/core/addon/addon-package.service.ts +183 -89
- package/src/core/addon/addon-registry.service.ts +1163 -1305
- package/src/core/addon/addon-search.service.ts +2 -1
- package/src/core/addon/addon-settings-provider.ts +27 -7
- package/src/core/addon-bridge/addon-bridge.service.ts +11 -6
- package/src/core/addon-pages/addon-pages.service.ts +3 -1
- package/src/core/addon-widgets/addon-widgets.service.ts +5 -2
- package/src/core/agent/agent-registry.service.ts +60 -38
- package/src/core/auth/auth.service.spec.ts +6 -8
- package/src/core/config/config.service.spec.ts +1 -1
- package/src/core/events/event-bus.service.spec.ts +44 -21
- package/src/core/events/event-bus.service.ts +5 -1
- package/src/core/feature/feature.service.spec.ts +4 -1
- package/src/core/lifecycle/lifecycle-state-machine.spec.ts +8 -10
- package/src/core/logging/logging.service.spec.ts +61 -21
- package/src/core/logging/logging.service.ts +12 -3
- package/src/core/moleculer/cap-call-fn.spec.ts +17 -10
- package/src/core/moleculer/cap-call-fn.ts +5 -1
- package/src/core/moleculer/cap-route-authority.ts +18 -6
- package/src/core/moleculer/moleculer.service.ts +120 -32
- package/src/core/network/network-quality.service.spec.ts +6 -1
- package/src/core/notification/notification-wrapper.service.ts +1 -3
- package/src/core/notification/toast-wrapper.service.ts +1 -5
- package/src/core/repl/repl-engine.service.spec.ts +66 -39
- package/src/core/repl/repl-engine.service.ts +11 -12
- package/src/core/storage/storage-location-manager.spec.ts +12 -3
- package/src/core/streaming/stream-probe.service.ts +22 -13
- package/src/core/topology/topology-emitter.service.ts +5 -1
- package/src/launcher.ts +14 -9
- package/src/main.ts +602 -531
- package/src/manual-boot.ts +133 -154
- package/tsconfig.json +20 -8
package/src/manual-boot.ts
CHANGED
|
@@ -6,59 +6,59 @@
|
|
|
6
6
|
* dependency graph.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import Fastify from
|
|
10
|
-
import type { FastifyInstance } from
|
|
11
|
-
import type { InfraContext } from
|
|
9
|
+
import Fastify from 'fastify'
|
|
10
|
+
import type { FastifyInstance } from 'fastify'
|
|
11
|
+
import type { InfraContext } from './boot/boot-config'
|
|
12
12
|
|
|
13
|
-
import { ConfigService } from
|
|
14
|
-
import { LoggingService } from
|
|
15
|
-
import { EventBusService } from
|
|
16
|
-
import { StorageService } from
|
|
17
|
-
import { CapabilityService } from
|
|
18
|
-
import { FeatureService } from
|
|
19
|
-
import { AuthService } from
|
|
20
|
-
import { StreamProbeService } from
|
|
21
|
-
import { NetworkQualityService } from
|
|
22
|
-
import { ToastServiceWrapper } from
|
|
23
|
-
import { NotificationServiceWrapper } from
|
|
24
|
-
import { AddonPagesService } from
|
|
25
|
-
import { AddonWidgetsService } from
|
|
26
|
-
import { AddonBridgeService } from
|
|
27
|
-
import { MoleculerService } from
|
|
28
|
-
import { AgentRegistryService } from
|
|
29
|
-
import { AddonRegistryService } from
|
|
30
|
-
import { AddonSearchService } from
|
|
31
|
-
import { AddonPackageService } from
|
|
32
|
-
import { ReplEngineService } from
|
|
33
|
-
import { TopologyEmitterService } from
|
|
34
|
-
import { PostBootService } from
|
|
13
|
+
import { ConfigService } from './core/config/config.service'
|
|
14
|
+
import { LoggingService } from './core/logging/logging.service'
|
|
15
|
+
import { EventBusService } from './core/events/event-bus.service'
|
|
16
|
+
import { StorageService } from './core/storage/storage.service'
|
|
17
|
+
import { CapabilityService } from './core/capability/capability.service'
|
|
18
|
+
import { FeatureService } from './core/feature/feature.service'
|
|
19
|
+
import { AuthService } from './core/auth/auth.service'
|
|
20
|
+
import { StreamProbeService } from './core/streaming/stream-probe.service'
|
|
21
|
+
import { NetworkQualityService } from './core/network/network-quality.service'
|
|
22
|
+
import { ToastServiceWrapper } from './core/notification/toast-wrapper.service'
|
|
23
|
+
import { NotificationServiceWrapper } from './core/notification/notification-wrapper.service'
|
|
24
|
+
import { AddonPagesService } from './core/addon-pages/addon-pages.service'
|
|
25
|
+
import { AddonWidgetsService } from './core/addon-widgets/addon-widgets.service'
|
|
26
|
+
import { AddonBridgeService } from './core/addon-bridge/addon-bridge.service'
|
|
27
|
+
import { MoleculerService } from './core/moleculer/moleculer.service'
|
|
28
|
+
import { AgentRegistryService } from './core/agent/agent-registry.service'
|
|
29
|
+
import { AddonRegistryService } from './core/addon/addon-registry.service'
|
|
30
|
+
import { AddonSearchService } from './core/addon/addon-search.service'
|
|
31
|
+
import { AddonPackageService } from './core/addon/addon-package.service'
|
|
32
|
+
import { ReplEngineService } from './core/repl/repl-engine.service'
|
|
33
|
+
import { TopologyEmitterService } from './core/topology/topology-emitter.service'
|
|
34
|
+
import { PostBootService } from './boot/post-boot.service'
|
|
35
35
|
|
|
36
36
|
// ---------------------------------------------------------------------------
|
|
37
37
|
// Types
|
|
38
38
|
// ---------------------------------------------------------------------------
|
|
39
39
|
|
|
40
|
-
type AnyCtor<T> = abstract new (...args: never[]) => T
|
|
40
|
+
type AnyCtor<T> = abstract new (...args: never[]) => T
|
|
41
41
|
|
|
42
42
|
export interface BootedApp {
|
|
43
43
|
/** Resolve a service by its constructor. Throws if unregistered. */
|
|
44
|
-
get<T>(ctor: AnyCtor<T>): T
|
|
44
|
+
get<T>(ctor: AnyCtor<T>): T
|
|
45
45
|
/** Returns the Fastify instance for plugin registration. */
|
|
46
|
-
getHttpAdapter(): { getInstance(): FastifyInstance }
|
|
46
|
+
getHttpAdapter(): { getInstance(): FastifyInstance }
|
|
47
47
|
/** Register a permissive CORS hook (allow all origins). */
|
|
48
|
-
enableCors(): void
|
|
48
|
+
enableCors(): void
|
|
49
49
|
/** Register SIGTERM/SIGINT → close() for graceful shutdown. */
|
|
50
|
-
enableShutdownHooks(): void
|
|
50
|
+
enableShutdownHooks(): void
|
|
51
51
|
/** Run OnModuleInit hooks in the order Nest's dependency graph produces. */
|
|
52
|
-
init(): Promise<void
|
|
52
|
+
init(): Promise<void>
|
|
53
53
|
/** Start the Fastify HTTP server. */
|
|
54
|
-
listen(port: number, host: string): Promise<void
|
|
54
|
+
listen(port: number, host: string): Promise<void>
|
|
55
55
|
/** Run OnModuleDestroy hooks in reverse init order, then close Fastify. */
|
|
56
|
-
close(): Promise<void
|
|
56
|
+
close(): Promise<void>
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
interface BootOptions {
|
|
60
|
-
infra: InfraContext
|
|
61
|
-
fastifyOpts: Record<string, unknown
|
|
60
|
+
infra: InfraContext
|
|
61
|
+
fastifyOpts: Record<string, unknown>
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
// ---------------------------------------------------------------------------
|
|
@@ -66,23 +66,21 @@ interface BootOptions {
|
|
|
66
66
|
// ---------------------------------------------------------------------------
|
|
67
67
|
|
|
68
68
|
class ServiceContainer {
|
|
69
|
-
private readonly services = new Map<unknown, unknown>()
|
|
69
|
+
private readonly services = new Map<unknown, unknown>()
|
|
70
70
|
|
|
71
71
|
register<T extends object>(ctor: AnyCtor<T>, instance: T): void {
|
|
72
|
-
this.services.set(ctor, instance)
|
|
72
|
+
this.services.set(ctor, instance)
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
get<T>(ctor: AnyCtor<T>): T {
|
|
76
|
-
const inst = this.services.get(ctor)
|
|
76
|
+
const inst = this.services.get(ctor)
|
|
77
77
|
if (inst === undefined) {
|
|
78
|
-
throw new Error(`ServiceContainer: ${ctor.name} is not registered`)
|
|
78
|
+
throw new Error(`ServiceContainer: ${ctor.name} is not registered`)
|
|
79
79
|
}
|
|
80
80
|
if (!(inst instanceof ctor)) {
|
|
81
|
-
throw new Error(
|
|
82
|
-
`ServiceContainer: ${ctor.name} instance type mismatch at resolve time`,
|
|
83
|
-
);
|
|
81
|
+
throw new Error(`ServiceContainer: ${ctor.name} instance type mismatch at resolve time`)
|
|
84
82
|
}
|
|
85
|
-
return inst
|
|
83
|
+
return inst
|
|
86
84
|
}
|
|
87
85
|
}
|
|
88
86
|
|
|
@@ -91,56 +89,48 @@ class ServiceContainer {
|
|
|
91
89
|
// ---------------------------------------------------------------------------
|
|
92
90
|
|
|
93
91
|
export async function bootManual(opts: BootOptions): Promise<BootedApp> {
|
|
94
|
-
const { infra, fastifyOpts } = opts
|
|
95
|
-
void infra
|
|
92
|
+
const { infra, fastifyOpts } = opts
|
|
93
|
+
void infra // infraContext is consumed by main.ts directly (locationManager, etc.)
|
|
96
94
|
|
|
97
|
-
const configPath =
|
|
98
|
-
process.env.CONFIG_PATH ?? "camstack-data/config.yaml";
|
|
95
|
+
const configPath = process.env.CONFIG_PATH ?? 'camstack-data/config.yaml'
|
|
99
96
|
|
|
100
97
|
// ---- Layer 0: services with no service deps -----------------------------
|
|
101
|
-
const configService = new ConfigService(configPath)
|
|
102
|
-
const storageService = new StorageService()
|
|
103
|
-
const capabilityService = new CapabilityService()
|
|
104
|
-
const networkQualityService = new NetworkQualityService()
|
|
105
|
-
const toastWrapper = new ToastServiceWrapper()
|
|
98
|
+
const configService = new ConfigService(configPath)
|
|
99
|
+
const storageService = new StorageService()
|
|
100
|
+
const capabilityService = new CapabilityService()
|
|
101
|
+
const networkQualityService = new NetworkQualityService()
|
|
102
|
+
const toastWrapper = new ToastServiceWrapper()
|
|
106
103
|
|
|
107
104
|
// ---- Layer 1: need ConfigService / LoggingService -----------------------
|
|
108
|
-
const loggingService = new LoggingService(configService)
|
|
109
|
-
const eventBusService = new EventBusService(configService)
|
|
105
|
+
const loggingService = new LoggingService(configService)
|
|
106
|
+
const eventBusService = new EventBusService(configService)
|
|
110
107
|
// Wire device-name cache for log formatter — subscribes here so the
|
|
111
108
|
// very first DeviceRegistered event populates the cache before any
|
|
112
109
|
// log line needing `deviceName` is emitted.
|
|
113
|
-
loggingService.attachDeviceNameStream(eventBusService)
|
|
114
|
-
const featureService = new FeatureService(configService)
|
|
115
|
-
const authService = new AuthService(configService)
|
|
116
|
-
const streamProbeService = new StreamProbeService(loggingService)
|
|
117
|
-
const addonBridgeService = new AddonBridgeService(loggingService)
|
|
118
|
-
const addonSearchService = new AddonSearchService(loggingService)
|
|
110
|
+
loggingService.attachDeviceNameStream(eventBusService)
|
|
111
|
+
const featureService = new FeatureService(configService)
|
|
112
|
+
const authService = new AuthService(configService)
|
|
113
|
+
const streamProbeService = new StreamProbeService(loggingService)
|
|
114
|
+
const addonBridgeService = new AddonBridgeService(loggingService)
|
|
115
|
+
const addonSearchService = new AddonSearchService(loggingService)
|
|
119
116
|
|
|
120
117
|
// ---- Layer 2: need Layer 0/1 -------------------------------------------
|
|
121
|
-
const notificationWrapper = new NotificationServiceWrapper(
|
|
122
|
-
|
|
123
|
-
loggingService,
|
|
124
|
-
);
|
|
125
|
-
const addonPagesService = new AddonPagesService(
|
|
126
|
-
loggingService,
|
|
127
|
-
configService,
|
|
128
|
-
capabilityService,
|
|
129
|
-
);
|
|
118
|
+
const notificationWrapper = new NotificationServiceWrapper(capabilityService, loggingService)
|
|
119
|
+
const addonPagesService = new AddonPagesService(loggingService, configService, capabilityService)
|
|
130
120
|
const moleculerService = new MoleculerService(
|
|
131
121
|
eventBusService,
|
|
132
122
|
configService,
|
|
133
123
|
loggingService,
|
|
134
124
|
capabilityService,
|
|
135
125
|
streamProbeService,
|
|
136
|
-
)
|
|
126
|
+
)
|
|
137
127
|
|
|
138
128
|
// ---- Layer 3: need Moleculer / AddonRegistry ---------------------------
|
|
139
129
|
const agentRegistryService = new AgentRegistryService(
|
|
140
130
|
eventBusService,
|
|
141
131
|
moleculerService,
|
|
142
132
|
capabilityService,
|
|
143
|
-
)
|
|
133
|
+
)
|
|
144
134
|
const addonRegistryService = new AddonRegistryService(
|
|
145
135
|
loggingService,
|
|
146
136
|
eventBusService,
|
|
@@ -149,11 +139,11 @@ export async function bootManual(opts: BootOptions): Promise<BootedApp> {
|
|
|
149
139
|
capabilityService,
|
|
150
140
|
moleculerService,
|
|
151
141
|
streamProbeService,
|
|
152
|
-
)
|
|
142
|
+
)
|
|
153
143
|
// AgentRegistryService needs the hub addon registry for placement-based
|
|
154
144
|
// reconciliation, but is constructed first (it has no other dependency
|
|
155
145
|
// on AddonRegistryService) — wire it post-construction.
|
|
156
|
-
agentRegistryService.setAddonRegistry(addonRegistryService)
|
|
146
|
+
agentRegistryService.setAddonRegistry(addonRegistryService)
|
|
157
147
|
|
|
158
148
|
// ---- Layer 4: need AddonRegistry ---------------------------------------
|
|
159
149
|
// AddonWidgetsService — needs AddonRegistryService for the bundled-addon
|
|
@@ -162,7 +152,7 @@ export async function bootManual(opts: BootOptions): Promise<BootedApp> {
|
|
|
162
152
|
loggingService,
|
|
163
153
|
capabilityService,
|
|
164
154
|
addonRegistryService,
|
|
165
|
-
)
|
|
155
|
+
)
|
|
166
156
|
const addonPackageService = new AddonPackageService(
|
|
167
157
|
loggingService,
|
|
168
158
|
eventBusService,
|
|
@@ -170,50 +160,46 @@ export async function bootManual(opts: BootOptions): Promise<BootedApp> {
|
|
|
170
160
|
addonRegistryService,
|
|
171
161
|
notificationWrapper,
|
|
172
162
|
toastWrapper,
|
|
173
|
-
)
|
|
163
|
+
)
|
|
174
164
|
const replEngineService = new ReplEngineService(
|
|
175
165
|
addonRegistryService,
|
|
176
166
|
eventBusService,
|
|
177
167
|
loggingService,
|
|
178
|
-
)
|
|
168
|
+
)
|
|
179
169
|
const topologyEmitterService = new TopologyEmitterService(
|
|
180
170
|
eventBusService,
|
|
181
171
|
agentRegistryService,
|
|
182
172
|
addonRegistryService,
|
|
183
|
-
)
|
|
184
|
-
const postBootService = new PostBootService(
|
|
185
|
-
addonRegistryService,
|
|
186
|
-
eventBusService,
|
|
187
|
-
loggingService,
|
|
188
|
-
);
|
|
173
|
+
)
|
|
174
|
+
const postBootService = new PostBootService(addonRegistryService, eventBusService, loggingService)
|
|
189
175
|
|
|
190
176
|
// ---- Container ---------------------------------------------------------
|
|
191
|
-
const container = new ServiceContainer()
|
|
192
|
-
container.register(ConfigService, configService)
|
|
193
|
-
container.register(LoggingService, loggingService)
|
|
194
|
-
container.register(EventBusService, eventBusService)
|
|
195
|
-
container.register(StorageService, storageService)
|
|
196
|
-
container.register(CapabilityService, capabilityService)
|
|
197
|
-
container.register(FeatureService, featureService)
|
|
198
|
-
container.register(AuthService, authService)
|
|
199
|
-
container.register(StreamProbeService, streamProbeService)
|
|
200
|
-
container.register(NetworkQualityService, networkQualityService)
|
|
201
|
-
container.register(ToastServiceWrapper, toastWrapper)
|
|
202
|
-
container.register(NotificationServiceWrapper, notificationWrapper)
|
|
203
|
-
container.register(AddonPagesService, addonPagesService)
|
|
204
|
-
container.register(AddonWidgetsService, addonWidgetsService)
|
|
205
|
-
container.register(AddonBridgeService, addonBridgeService)
|
|
206
|
-
container.register(MoleculerService, moleculerService)
|
|
207
|
-
container.register(AgentRegistryService, agentRegistryService)
|
|
208
|
-
container.register(AddonRegistryService, addonRegistryService)
|
|
209
|
-
container.register(AddonSearchService, addonSearchService)
|
|
210
|
-
container.register(AddonPackageService, addonPackageService)
|
|
211
|
-
container.register(ReplEngineService, replEngineService)
|
|
212
|
-
container.register(TopologyEmitterService, topologyEmitterService)
|
|
213
|
-
container.register(PostBootService, postBootService)
|
|
177
|
+
const container = new ServiceContainer()
|
|
178
|
+
container.register(ConfigService, configService)
|
|
179
|
+
container.register(LoggingService, loggingService)
|
|
180
|
+
container.register(EventBusService, eventBusService)
|
|
181
|
+
container.register(StorageService, storageService)
|
|
182
|
+
container.register(CapabilityService, capabilityService)
|
|
183
|
+
container.register(FeatureService, featureService)
|
|
184
|
+
container.register(AuthService, authService)
|
|
185
|
+
container.register(StreamProbeService, streamProbeService)
|
|
186
|
+
container.register(NetworkQualityService, networkQualityService)
|
|
187
|
+
container.register(ToastServiceWrapper, toastWrapper)
|
|
188
|
+
container.register(NotificationServiceWrapper, notificationWrapper)
|
|
189
|
+
container.register(AddonPagesService, addonPagesService)
|
|
190
|
+
container.register(AddonWidgetsService, addonWidgetsService)
|
|
191
|
+
container.register(AddonBridgeService, addonBridgeService)
|
|
192
|
+
container.register(MoleculerService, moleculerService)
|
|
193
|
+
container.register(AgentRegistryService, agentRegistryService)
|
|
194
|
+
container.register(AddonRegistryService, addonRegistryService)
|
|
195
|
+
container.register(AddonSearchService, addonSearchService)
|
|
196
|
+
container.register(AddonPackageService, addonPackageService)
|
|
197
|
+
container.register(ReplEngineService, replEngineService)
|
|
198
|
+
container.register(TopologyEmitterService, topologyEmitterService)
|
|
199
|
+
container.register(PostBootService, postBootService)
|
|
214
200
|
|
|
215
201
|
// ---- Fastify instance --------------------------------------------------
|
|
216
|
-
const fastify = Fastify(fastifyOpts)
|
|
202
|
+
const fastify = Fastify(fastifyOpts)
|
|
217
203
|
|
|
218
204
|
// /health and /health/* — registered in `main.ts` via
|
|
219
205
|
// `registerHealthRoutes` once MoleculerService + AgentRegistryService are
|
|
@@ -221,75 +207,69 @@ export async function bootManual(opts: BootOptions): Promise<BootedApp> {
|
|
|
221
207
|
// (see `packages/agent/src/agent-http.ts`).
|
|
222
208
|
|
|
223
209
|
// ---- Shutdown coordination --------------------------------------------
|
|
224
|
-
let closed = false
|
|
225
|
-
let shutdownHooksRegistered = false
|
|
210
|
+
let closed = false
|
|
211
|
+
let shutdownHooksRegistered = false
|
|
226
212
|
|
|
227
213
|
const close = async (): Promise<void> => {
|
|
228
|
-
if (closed) return
|
|
229
|
-
closed = true
|
|
214
|
+
if (closed) return
|
|
215
|
+
closed = true
|
|
230
216
|
const logErr = (label: string, err: unknown): void => {
|
|
231
|
-
console.error(`[manual-boot] ${label} destroy failed:`, err)
|
|
232
|
-
}
|
|
217
|
+
console.error(`[manual-boot] ${label} destroy failed:`, err)
|
|
218
|
+
}
|
|
233
219
|
try {
|
|
234
|
-
topologyEmitterService.onModuleDestroy()
|
|
220
|
+
topologyEmitterService.onModuleDestroy()
|
|
235
221
|
} catch (err) {
|
|
236
|
-
logErr(
|
|
222
|
+
logErr('TopologyEmitter', err)
|
|
237
223
|
}
|
|
238
224
|
try {
|
|
239
|
-
await addonRegistryService.onModuleDestroy()
|
|
225
|
+
await addonRegistryService.onModuleDestroy()
|
|
240
226
|
} catch (err) {
|
|
241
|
-
logErr(
|
|
227
|
+
logErr('AddonRegistry', err)
|
|
242
228
|
}
|
|
243
229
|
try {
|
|
244
|
-
await addonBridgeService.onModuleDestroy()
|
|
230
|
+
await addonBridgeService.onModuleDestroy()
|
|
245
231
|
} catch (err) {
|
|
246
|
-
logErr(
|
|
232
|
+
logErr('AddonBridge', err)
|
|
247
233
|
}
|
|
248
234
|
try {
|
|
249
|
-
await moleculerService.onModuleDestroy()
|
|
235
|
+
await moleculerService.onModuleDestroy()
|
|
250
236
|
} catch (err) {
|
|
251
|
-
logErr(
|
|
237
|
+
logErr('Moleculer', err)
|
|
252
238
|
}
|
|
253
239
|
try {
|
|
254
|
-
await fastify.close()
|
|
240
|
+
await fastify.close()
|
|
255
241
|
} catch (err) {
|
|
256
|
-
logErr(
|
|
242
|
+
logErr('Fastify', err)
|
|
257
243
|
}
|
|
258
|
-
}
|
|
244
|
+
}
|
|
259
245
|
|
|
260
246
|
return {
|
|
261
247
|
get<T>(ctor: AnyCtor<T>): T {
|
|
262
|
-
return container.get(ctor)
|
|
248
|
+
return container.get(ctor)
|
|
263
249
|
},
|
|
264
250
|
getHttpAdapter() {
|
|
265
|
-
return { getInstance: () => fastify }
|
|
251
|
+
return { getInstance: () => fastify }
|
|
266
252
|
},
|
|
267
253
|
enableCors() {
|
|
268
|
-
fastify.addHook(
|
|
269
|
-
reply.header(
|
|
270
|
-
reply.header(
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
reply.header(
|
|
275
|
-
"access-control-allow-headers",
|
|
276
|
-
"content-type,authorization",
|
|
277
|
-
);
|
|
278
|
-
if (request.method === "OPTIONS") {
|
|
279
|
-
reply.status(204).send();
|
|
254
|
+
fastify.addHook('onRequest', async (request, reply) => {
|
|
255
|
+
reply.header('access-control-allow-origin', '*')
|
|
256
|
+
reply.header('access-control-allow-methods', 'GET,POST,PUT,DELETE,OPTIONS,PATCH')
|
|
257
|
+
reply.header('access-control-allow-headers', 'content-type,authorization')
|
|
258
|
+
if (request.method === 'OPTIONS') {
|
|
259
|
+
reply.status(204).send()
|
|
280
260
|
}
|
|
281
|
-
})
|
|
261
|
+
})
|
|
282
262
|
},
|
|
283
263
|
enableShutdownHooks() {
|
|
284
|
-
if (shutdownHooksRegistered) return
|
|
285
|
-
shutdownHooksRegistered = true
|
|
264
|
+
if (shutdownHooksRegistered) return
|
|
265
|
+
shutdownHooksRegistered = true
|
|
286
266
|
const handler = (): void => {
|
|
287
267
|
close().catch((err) => {
|
|
288
|
-
console.error(
|
|
289
|
-
})
|
|
290
|
-
}
|
|
291
|
-
process.once(
|
|
292
|
-
process.once(
|
|
268
|
+
console.error('[manual-boot] shutdown close failed:', err)
|
|
269
|
+
})
|
|
270
|
+
}
|
|
271
|
+
process.once('SIGTERM', handler)
|
|
272
|
+
process.once('SIGINT', handler)
|
|
293
273
|
},
|
|
294
274
|
async init() {
|
|
295
275
|
// Init order (dependency-graph-derived):
|
|
@@ -297,26 +277,25 @@ export async function bootManual(opts: BootOptions): Promise<BootedApp> {
|
|
|
297
277
|
// 2. AddonBridgeService — no cross-service deps
|
|
298
278
|
// 3. AgentRegistryService — subscribes to broker.localBus.on('$node.connected')
|
|
299
279
|
// 4. AddonRegistryService — boots every addon (needs broker live + config)
|
|
300
|
-
await moleculerService.onModuleInit()
|
|
301
|
-
await addonBridgeService.onModuleInit()
|
|
302
|
-
agentRegistryService.onModuleInit()
|
|
303
|
-
await addonRegistryService.onModuleInit()
|
|
280
|
+
await moleculerService.onModuleInit()
|
|
281
|
+
await addonBridgeService.onModuleInit()
|
|
282
|
+
agentRegistryService.onModuleInit()
|
|
283
|
+
await addonRegistryService.onModuleInit()
|
|
304
284
|
// Reconcile already-connected agents now that the hub's installed
|
|
305
285
|
// addon set is populated. Agents online before the hub started never
|
|
306
286
|
// fire a fresh `$node.connected` event, so the per-connect trigger
|
|
307
287
|
// alone would miss them — this catches the boot-time case (e.g. a
|
|
308
288
|
// long-running dev-agent with a now-stale addon). Fire-and-forget so
|
|
309
289
|
// an unreachable agent never delays boot.
|
|
310
|
-
void agentRegistryService.reconcileConnectedAgents()
|
|
290
|
+
void agentRegistryService.reconcileConnectedAgents()
|
|
311
291
|
// Topology emitter must boot AFTER AgentRegistry + AddonRegistry —
|
|
312
292
|
// its initial snapshot reads both. Subscribes to lifecycle events
|
|
313
293
|
// for incremental snapshots and emits a periodic safety net.
|
|
314
|
-
topologyEmitterService.onModuleInit()
|
|
294
|
+
topologyEmitterService.onModuleInit()
|
|
315
295
|
},
|
|
316
296
|
async listen(port, host) {
|
|
317
|
-
await fastify.listen({ port, host })
|
|
297
|
+
await fastify.listen({ port, host })
|
|
318
298
|
},
|
|
319
299
|
close,
|
|
320
|
-
}
|
|
300
|
+
}
|
|
321
301
|
}
|
|
322
|
-
|
package/tsconfig.json
CHANGED
|
@@ -1,21 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"extends": "../../tsconfig.base.json",
|
|
3
3
|
"compilerOptions": {
|
|
4
|
-
"target": "
|
|
4
|
+
"target": "ES2023",
|
|
5
5
|
"module": "CommonJS",
|
|
6
6
|
"moduleResolution": "node",
|
|
7
|
-
"lib": [
|
|
8
|
-
|
|
7
|
+
"lib": [
|
|
8
|
+
"ES2023"
|
|
9
|
+
],
|
|
9
10
|
"strict": true,
|
|
10
11
|
"esModuleInterop": true,
|
|
11
12
|
"experimentalDecorators": true,
|
|
12
13
|
"emitDecoratorMetadata": true,
|
|
13
|
-
"declaration":
|
|
14
|
+
"declaration": false,
|
|
14
15
|
"resolveJsonModule": true,
|
|
15
16
|
"skipLibCheck": true,
|
|
16
|
-
"types": [
|
|
17
|
-
|
|
17
|
+
"types": [
|
|
18
|
+
"node"
|
|
19
|
+
],
|
|
20
|
+
"baseUrl": "../..",
|
|
21
|
+
"ignoreDeprecations": "6.0",
|
|
22
|
+
"noEmit": true
|
|
18
23
|
},
|
|
19
|
-
"include": [
|
|
20
|
-
|
|
24
|
+
"include": [
|
|
25
|
+
"src"
|
|
26
|
+
],
|
|
27
|
+
"exclude": [
|
|
28
|
+
"src/scripts",
|
|
29
|
+
"src/**/__tests__",
|
|
30
|
+
"src/**/*.spec.ts",
|
|
31
|
+
"src/**/*.test.ts"
|
|
32
|
+
]
|
|
21
33
|
}
|