@camstack/server 1.0.0 → 1.0.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/{src/agent-status-page.ts → dist/agent-status-page.js} +30 -45
- package/dist/api/addon-upload.js +441 -0
- package/dist/api/addons-custom.router.js +91 -0
- package/dist/api/auth-whoami.js +55 -0
- package/dist/api/bridge-addons.router.js +109 -0
- package/dist/api/capabilities.router.js +229 -0
- package/dist/api/core/addon-settings.router.js +117 -0
- package/dist/api/core/agents.router.js +73 -0
- package/dist/api/core/auth.router.js +286 -0
- package/dist/api/core/bulk-update-coordinator.js +229 -0
- package/dist/api/core/cap-providers.js +1124 -0
- package/dist/api/core/capabilities.router.js +138 -0
- package/dist/api/core/collection-preference.js +17 -0
- package/dist/api/core/event-bus-proxy.router.js +45 -0
- package/dist/api/core/hwaccel.router.js +91 -0
- package/dist/api/core/live-events.router.js +61 -0
- package/dist/api/core/logs.router.js +172 -0
- package/dist/api/core/notifications.router.js +67 -0
- package/dist/api/core/repl.router.js +35 -0
- package/dist/api/core/settings-backend.router.js +121 -0
- package/dist/api/core/stream-probe.router.js +58 -0
- package/dist/api/core/system-events.router.js +100 -0
- package/dist/api/health/health.routes.js +68 -0
- package/{src/api/oauth2/consent-page.ts → dist/api/oauth2/consent-page.js} +11 -20
- package/dist/api/oauth2/oauth2-routes.js +219 -0
- package/dist/api/trpc/cap-mount-helpers.js +194 -0
- package/dist/api/trpc/cap-route-error-formatter.js +133 -0
- package/dist/api/trpc/client-ip.js +147 -0
- package/dist/api/trpc/core-cap-bridge.js +115 -0
- package/dist/api/trpc/generated-cap-mounts.js +388 -0
- package/dist/api/trpc/generated-cap-routers.js +7635 -0
- package/dist/api/trpc/scope-access.js +93 -0
- package/dist/api/trpc/trpc.context.js +184 -0
- package/dist/api/trpc/trpc.middleware.js +139 -0
- package/dist/api/trpc/trpc.router.js +188 -0
- package/dist/auth/session-cookie.js +47 -0
- package/dist/boot/boot-config.js +241 -0
- package/dist/boot/integration-id-backfill.js +76 -0
- package/dist/boot/post-boot.service.js +85 -0
- package/dist/core/addon/addon-call-gateway.js +99 -0
- package/dist/core/addon/addon-package.service.js +1560 -0
- package/dist/core/addon/addon-registry.service.js +2739 -0
- package/{src/core/addon/addon-row-manifest.ts → dist/core/addon/addon-row-manifest.js} +5 -5
- package/dist/core/addon/addon-search.service.js +62 -0
- package/dist/core/addon/addon-settings-provider.js +102 -0
- package/dist/core/addon/addon.tokens.js +5 -0
- package/dist/core/addon-bridge/addon-bridge.service.js +145 -0
- package/dist/core/addon-pages/addon-pages.service.js +107 -0
- package/dist/core/addon-widgets/addon-widgets.service.js +120 -0
- package/dist/core/agent/agent-registry.service.js +477 -0
- package/dist/core/auth/auth.service.js +10 -0
- package/dist/core/capability/capability.service.js +58 -0
- package/dist/core/config/config.schema.js +7 -0
- package/dist/core/config/config.service.js +10 -0
- package/dist/core/events/event-bus.service.js +83 -0
- package/dist/core/feature/feature.service.js +10 -0
- package/dist/core/lifecycle/lifecycle-state-machine.js +6 -0
- package/dist/core/logging/log-ring-buffer.js +6 -0
- package/dist/core/logging/logging.service.js +130 -0
- package/dist/core/logging/scoped-logger.js +6 -0
- package/dist/core/moleculer/cap-call-fn.js +50 -0
- package/dist/core/moleculer/cap-route-authority.js +122 -0
- package/dist/core/moleculer/moleculer.service.js +898 -0
- package/dist/core/network/network-quality.service.js +7 -0
- package/dist/core/notification/notification-wrapper.service.js +33 -0
- package/dist/core/notification/toast-wrapper.service.js +25 -0
- package/dist/core/provider/provider.tokens.js +4 -0
- package/dist/core/repl/repl-engine.service.js +140 -0
- package/dist/core/storage/fs-storage-backend.js +6 -0
- package/dist/core/storage/storage-location-manager.js +6 -0
- package/dist/core/storage/storage.service.js +7 -0
- package/dist/core/streaming/stream-probe.service.js +209 -0
- package/dist/core/topology/topology-emitter.service.js +106 -0
- package/dist/launcher.js +325 -0
- package/dist/main.js +1098 -0
- package/dist/manual-boot.js +227 -0
- package/package.json +5 -1
- package/src/__tests__/addon-install-e2e.test.ts +0 -74
- package/src/__tests__/addon-pages-e2e.test.ts +0 -200
- package/src/__tests__/addon-route-session.test.ts +0 -17
- package/src/__tests__/addon-settings-router.spec.ts +0 -67
- package/src/__tests__/addon-upload.spec.ts +0 -475
- package/src/__tests__/agent-registry.spec.ts +0 -179
- package/src/__tests__/agent-status-page.spec.ts +0 -82
- package/src/__tests__/auth-session-cookie.test.ts +0 -48
- package/src/__tests__/bulk-update-coordinator.spec.ts +0 -303
- package/src/__tests__/cap-ownership-authority.spec.ts +0 -431
- package/src/__tests__/cap-providers/cap-providers-location-import.spec.ts +0 -206
- package/src/__tests__/cap-providers/cap-usage-graph.spec.ts +0 -37
- package/src/__tests__/cap-providers/compute-topology-categories.spec.ts +0 -110
- package/src/__tests__/cap-providers/integrations-delete-cascade.spec.ts +0 -292
- package/src/__tests__/cap-providers-bulk-update.spec.ts +0 -408
- package/src/__tests__/cap-route-adapter.spec.ts +0 -302
- package/src/__tests__/cap-routers/_meta.spec.ts +0 -199
- package/src/__tests__/cap-routers/addon-settings.router.spec.ts +0 -115
- package/src/__tests__/cap-routers/broker-routing.router.spec.ts +0 -177
- package/src/__tests__/cap-routers/cap-route-error-formatter.spec.ts +0 -125
- package/src/__tests__/cap-routers/capabilities-node.spec.ts +0 -68
- package/src/__tests__/cap-routers/device-link-overlay.spec.ts +0 -137
- package/src/__tests__/cap-routers/device-manager-aggregate.router.spec.ts +0 -194
- package/src/__tests__/cap-routers/harness.ts +0 -163
- package/src/__tests__/cap-routers/metrics-provider.router.spec.ts +0 -133
- package/src/__tests__/cap-routers/null-provider-guard.spec.ts +0 -64
- package/src/__tests__/cap-routers/pipeline-executor.router.spec.ts +0 -159
- package/src/__tests__/cap-routers/settings-store.router.spec.ts +0 -291
- package/src/__tests__/capability-e2e.test.ts +0 -384
- package/src/__tests__/cli-e2e.test.ts +0 -150
- package/src/__tests__/core-cap-bridge.spec.ts +0 -91
- package/src/__tests__/dev-bootstrap-shm-ring.spec.ts +0 -40
- package/src/__tests__/device-settings-contribution-dispatch.spec.ts +0 -280
- package/src/__tests__/embedded-deps-e2e.test.ts +0 -125
- package/src/__tests__/event-bus-proxy-router.spec.ts +0 -75
- package/src/__tests__/fixtures/mock-analysis-addon-a.ts +0 -37
- package/src/__tests__/fixtures/mock-analysis-addon-b.ts +0 -37
- package/src/__tests__/fixtures/mock-log-addon.ts +0 -37
- package/src/__tests__/fixtures/mock-storage-addon.ts +0 -40
- package/src/__tests__/framework-allowlist.spec.ts +0 -96
- package/src/__tests__/framework-installer-defer-restart.spec.ts +0 -165
- package/src/__tests__/https-e2e.test.ts +0 -124
- package/src/__tests__/lifecycle-e2e.test.ts +0 -189
- package/src/__tests__/live-events-subscription.spec.ts +0 -149
- package/src/__tests__/moleculer/uds-readiness.spec.ts +0 -150
- package/src/__tests__/moleculer/uds-topology.spec.ts +0 -418
- package/src/__tests__/moleculer/uds-unowned-call.spec.ts +0 -383
- package/src/__tests__/moleculer-register-node-idempotency.spec.ts +0 -273
- package/src/__tests__/native-cap-route.spec.ts +0 -427
- package/src/__tests__/oauth2-account-linking.spec.ts +0 -867
- package/src/__tests__/post-boot-restart.spec.ts +0 -161
- package/src/__tests__/singleton-contention.test.ts +0 -499
- package/src/__tests__/streaming-diagnostic.test.ts +0 -615
- package/src/__tests__/streaming-scale.test.ts +0 -314
- package/src/__tests__/uds-addon-call-wiring.spec.ts +0 -242
- package/src/__tests__/uds-log-ingest.spec.ts +0 -183
- package/src/api/__tests__/addons-custom.spec.ts +0 -148
- package/src/api/__tests__/capabilities.router.test.ts +0 -56
- package/src/api/addon-upload.ts +0 -529
- package/src/api/addons-custom.router.ts +0 -101
- package/src/api/auth-whoami.ts +0 -101
- package/src/api/bridge-addons.router.ts +0 -122
- package/src/api/capabilities.router.ts +0 -265
- package/src/api/core/__tests__/auth-router-totp.spec.ts +0 -297
- package/src/api/core/__tests__/integration-markers.spec.ts +0 -10
- package/src/api/core/addon-settings.router.ts +0 -127
- package/src/api/core/agents.router.ts +0 -86
- package/src/api/core/auth.router.ts +0 -322
- package/src/api/core/bulk-update-coordinator.ts +0 -305
- package/src/api/core/cap-providers.ts +0 -1339
- package/src/api/core/capabilities.router.ts +0 -149
- package/src/api/core/collection-preference.ts +0 -40
- package/src/api/core/event-bus-proxy.router.ts +0 -45
- package/src/api/core/hwaccel.router.ts +0 -108
- package/src/api/core/live-events.router.ts +0 -67
- package/src/api/core/logs.router.ts +0 -195
- package/src/api/core/notifications.router.ts +0 -66
- package/src/api/core/repl.router.ts +0 -39
- package/src/api/core/settings-backend.router.ts +0 -140
- package/src/api/core/stream-probe.router.ts +0 -57
- package/src/api/core/system-events.router.ts +0 -125
- package/src/api/health/health.routes.ts +0 -117
- package/src/api/oauth2/__tests__/oauth2-routes.spec.ts +0 -62
- package/src/api/oauth2/oauth2-routes.ts +0 -281
- package/src/api/trpc/__tests__/client-ip.spec.ts +0 -146
- package/src/api/trpc/__tests__/scope-access-device.spec.ts +0 -268
- package/src/api/trpc/__tests__/scope-access.spec.ts +0 -102
- package/src/api/trpc/__tests__/webrtc-session-ua-enrich.spec.ts +0 -136
- package/src/api/trpc/cap-mount-helpers.ts +0 -245
- package/src/api/trpc/cap-route-error-formatter.ts +0 -171
- package/src/api/trpc/client-ip.ts +0 -147
- package/src/api/trpc/core-cap-bridge.ts +0 -154
- package/src/api/trpc/generated-cap-mounts.ts +0 -1240
- package/src/api/trpc/generated-cap-routers.ts +0 -11523
- package/src/api/trpc/scope-access.ts +0 -110
- package/src/api/trpc/trpc.context.ts +0 -258
- package/src/api/trpc/trpc.middleware.ts +0 -146
- package/src/api/trpc/trpc.router.ts +0 -389
- package/src/auth/session-cookie.ts +0 -54
- package/src/boot/__tests__/integration-id-backfill.spec.ts +0 -131
- package/src/boot/boot-config.ts +0 -259
- package/src/boot/integration-id-backfill.ts +0 -109
- package/src/boot/post-boot.service.ts +0 -105
- package/src/core/addon/__tests__/addon-registry-capability.test.ts +0 -62
- package/src/core/addon/__tests__/addon-row-manifest.spec.ts +0 -62
- package/src/core/addon/addon-call-gateway.ts +0 -171
- package/src/core/addon/addon-package.service.ts +0 -1787
- package/src/core/addon/addon-registry.service.ts +0 -3130
- package/src/core/addon/addon-search.service.ts +0 -91
- package/src/core/addon/addon-settings-provider.ts +0 -220
- package/src/core/addon/addon.tokens.ts +0 -2
- package/src/core/addon-bridge/addon-bridge.service.ts +0 -130
- package/src/core/addon-pages/addon-pages.service.spec.ts +0 -117
- package/src/core/addon-pages/addon-pages.service.ts +0 -82
- package/src/core/addon-widgets/addon-widgets.service.ts +0 -95
- package/src/core/agent/agent-registry.service.ts +0 -529
- package/src/core/auth/auth.service.spec.ts +0 -86
- package/src/core/auth/auth.service.ts +0 -8
- package/src/core/capability/capability.service.ts +0 -66
- package/src/core/config/config.schema.ts +0 -3
- package/src/core/config/config.service.spec.ts +0 -175
- package/src/core/config/config.service.ts +0 -7
- package/src/core/events/event-bus.service.spec.ts +0 -235
- package/src/core/events/event-bus.service.ts +0 -89
- package/src/core/feature/feature.service.spec.ts +0 -99
- package/src/core/feature/feature.service.ts +0 -8
- package/src/core/lifecycle/lifecycle-state-machine.spec.ts +0 -166
- package/src/core/lifecycle/lifecycle-state-machine.ts +0 -3
- package/src/core/logging/log-ring-buffer.ts +0 -3
- package/src/core/logging/logging.service.spec.ts +0 -287
- package/src/core/logging/logging.service.ts +0 -143
- package/src/core/logging/scoped-logger.ts +0 -3
- package/src/core/moleculer/cap-call-fn.spec.ts +0 -173
- package/src/core/moleculer/cap-call-fn.ts +0 -107
- package/src/core/moleculer/cap-route-authority.ts +0 -194
- package/src/core/moleculer/moleculer.service.ts +0 -1072
- package/src/core/network/network-quality.service.spec.ts +0 -53
- package/src/core/network/network-quality.service.ts +0 -5
- package/src/core/notification/notification-wrapper.service.ts +0 -34
- package/src/core/notification/toast-wrapper.service.ts +0 -27
- package/src/core/provider/provider.tokens.ts +0 -1
- package/src/core/repl/repl-engine.service.spec.ts +0 -444
- package/src/core/repl/repl-engine.service.ts +0 -155
- package/src/core/storage/fs-storage-backend.spec.ts +0 -70
- package/src/core/storage/fs-storage-backend.ts +0 -3
- package/src/core/storage/storage-location-manager.spec.ts +0 -130
- package/src/core/storage/storage-location-manager.ts +0 -3
- package/src/core/storage/storage.service.spec.ts +0 -73
- package/src/core/storage/storage.service.ts +0 -3
- package/src/core/streaming/stream-probe.service.ts +0 -221
- package/src/core/topology/topology-emitter.service.ts +0 -105
- package/src/launcher.ts +0 -314
- package/src/main.ts +0 -1245
- package/src/manual-boot.ts +0 -301
- package/tsconfig.build.json +0 -8
- package/tsconfig.json +0 -33
- package/vitest.config.ts +0 -26
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Live events subscription — unit + in-process e2e test.
|
|
3
|
-
*
|
|
4
|
-
* Proves that an event emitted on `EventBusService` is delivered to a
|
|
5
|
-
* consumer that went through `live.onEvent` → `iterableSubscription`.
|
|
6
|
-
* This is the same path UI components use via the WS client (AlertBell,
|
|
7
|
-
* EngineTab). If this test passes but the UI still doesn't receive
|
|
8
|
-
* events, the bug is downstream in the WS adapter, not in the routing.
|
|
9
|
-
*/
|
|
10
|
-
import { describe, it, expect, vi } from 'vitest'
|
|
11
|
-
import { SystemEventBus } from '@camstack/core'
|
|
12
|
-
import { createLiveEventsRouter } from '../api/core/live-events.router.js'
|
|
13
|
-
import { makeCtx } from './cap-routers/harness.js'
|
|
14
|
-
import type { EventBusService } from '../core/events/event-bus.service.js'
|
|
15
|
-
|
|
16
|
-
function sleep(ms: number): Promise<void> {
|
|
17
|
-
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function makeEvent(category: string, data: Record<string, unknown> = {}) {
|
|
21
|
-
return {
|
|
22
|
-
id: `evt-${Math.random().toString(36).slice(2, 8)}`,
|
|
23
|
-
timestamp: new Date(),
|
|
24
|
-
source: { type: 'pipeline' as const, id: 'benchmark' },
|
|
25
|
-
category,
|
|
26
|
-
data: { type: `pipeline.${category}`, ...data },
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
describe('live events subscription', () => {
|
|
31
|
-
it('delivers events emitted AFTER subscription', async () => {
|
|
32
|
-
const bus = new SystemEventBus() as unknown as EventBusService
|
|
33
|
-
const router = createLiveEventsRouter(bus, {
|
|
34
|
-
getDeviceRegistry: () => ({ getAll: () => [], getAllForAddon: () => [] }),
|
|
35
|
-
} as never)
|
|
36
|
-
const caller = router.createCaller(makeCtx('admin'))
|
|
37
|
-
|
|
38
|
-
const iter = await caller.onEvent({ category: 'benchmark.progress' })
|
|
39
|
-
|
|
40
|
-
// Collect received events concurrently while emitting.
|
|
41
|
-
const received: Array<{ category: string; data: Record<string, unknown> }> = []
|
|
42
|
-
const collector = (async () => {
|
|
43
|
-
for await (const ev of iter) {
|
|
44
|
-
received.push({ category: ev.category, data: ev.data })
|
|
45
|
-
if (received.length >= 3) return
|
|
46
|
-
}
|
|
47
|
-
})()
|
|
48
|
-
|
|
49
|
-
// Give the async generator a tick to wire up its internal promise.
|
|
50
|
-
await sleep(10)
|
|
51
|
-
|
|
52
|
-
bus.emit(makeEvent('benchmark.progress', { iteration: 1, totalMs: 50 }))
|
|
53
|
-
bus.emit(makeEvent('benchmark.progress', { iteration: 2, totalMs: 48 }))
|
|
54
|
-
bus.emit(makeEvent('other.category', { ignored: true }))
|
|
55
|
-
bus.emit(makeEvent('benchmark.progress', { iteration: 3, totalMs: 52 }))
|
|
56
|
-
|
|
57
|
-
await collector
|
|
58
|
-
|
|
59
|
-
expect(received).toHaveLength(3)
|
|
60
|
-
expect(received.map((r) => r.data.iteration)).toEqual([1, 2, 3])
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
it('filters events that do not match the requested category', async () => {
|
|
64
|
-
const bus = new SystemEventBus() as unknown as EventBusService
|
|
65
|
-
const router = createLiveEventsRouter(bus, {
|
|
66
|
-
getDeviceRegistry: () => ({ getAll: () => [], getAllForAddon: () => [] }),
|
|
67
|
-
} as never)
|
|
68
|
-
const caller = router.createCaller(makeCtx('admin'))
|
|
69
|
-
|
|
70
|
-
const iter = await caller.onEvent({ category: 'benchmark.progress' })
|
|
71
|
-
|
|
72
|
-
const received: string[] = []
|
|
73
|
-
const stop = vi.fn()
|
|
74
|
-
const collector = (async () => {
|
|
75
|
-
for await (const ev of iter) {
|
|
76
|
-
received.push(ev.category)
|
|
77
|
-
if (received.length >= 2) {
|
|
78
|
-
stop()
|
|
79
|
-
return
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
})()
|
|
83
|
-
|
|
84
|
-
await sleep(10)
|
|
85
|
-
|
|
86
|
-
// Emit a mix — only 'benchmark.progress' should pass.
|
|
87
|
-
bus.emit(makeEvent('alert.created', {}))
|
|
88
|
-
bus.emit(makeEvent('benchmark.progress', { iteration: 1 }))
|
|
89
|
-
bus.emit(makeEvent('benchmark.heartbeat', {}))
|
|
90
|
-
bus.emit(makeEvent('alert.updated', {}))
|
|
91
|
-
bus.emit(makeEvent('benchmark.progress', { iteration: 2 }))
|
|
92
|
-
|
|
93
|
-
await collector
|
|
94
|
-
|
|
95
|
-
expect(received).toEqual(['benchmark.progress', 'benchmark.progress'])
|
|
96
|
-
expect(stop).toHaveBeenCalledOnce()
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
it('receives recent events via recentSystemEvents query', async () => {
|
|
100
|
-
const bus = new SystemEventBus() as unknown as EventBusService
|
|
101
|
-
const router = createLiveEventsRouter(bus, {
|
|
102
|
-
getDeviceRegistry: () => ({ getAll: () => [], getAllForAddon: () => [] }),
|
|
103
|
-
} as never)
|
|
104
|
-
const caller = router.createCaller(makeCtx('admin'))
|
|
105
|
-
|
|
106
|
-
bus.emit(makeEvent('benchmark.progress', { iteration: 1 }))
|
|
107
|
-
bus.emit(makeEvent('alert.created', {}))
|
|
108
|
-
bus.emit(makeEvent('benchmark.progress', { iteration: 2 }))
|
|
109
|
-
|
|
110
|
-
const recent = await caller.recentSystemEvents({ category: 'benchmark.progress', limit: 10 })
|
|
111
|
-
expect(recent).toHaveLength(2)
|
|
112
|
-
// recentSystemEvents returns newest-first
|
|
113
|
-
const iterations = recent.map((e) => e.data.iteration as number).toSorted((a, b) => a - b)
|
|
114
|
-
expect(iterations).toEqual([1, 2])
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
it('delivers bursts — multiple events queued before the consumer drains', async () => {
|
|
118
|
-
// Reproduces the benchmark scenario where runBenchmark emits 3 events
|
|
119
|
-
// back-to-back; the subscription should buffer them and deliver all 3.
|
|
120
|
-
const bus = new SystemEventBus() as unknown as EventBusService
|
|
121
|
-
const router = createLiveEventsRouter(bus, {
|
|
122
|
-
getDeviceRegistry: () => ({ getAll: () => [], getAllForAddon: () => [] }),
|
|
123
|
-
} as never)
|
|
124
|
-
const caller = router.createCaller(makeCtx('admin'))
|
|
125
|
-
|
|
126
|
-
const iter = await caller.onEvent({ category: 'benchmark.progress' })
|
|
127
|
-
|
|
128
|
-
const received: number[] = []
|
|
129
|
-
const collector = (async () => {
|
|
130
|
-
for await (const ev of iter) {
|
|
131
|
-
received.push(ev.data.iteration as number)
|
|
132
|
-
if (received.length >= 5) return
|
|
133
|
-
}
|
|
134
|
-
})()
|
|
135
|
-
|
|
136
|
-
// Let the generator body run through its first `await`, registering the
|
|
137
|
-
// bus subscription. Without this tick subscribe() hasn't attached yet.
|
|
138
|
-
await sleep(20)
|
|
139
|
-
|
|
140
|
-
// Emit 5 events synchronously — no awaits between.
|
|
141
|
-
for (let i = 1; i <= 5; i++) {
|
|
142
|
-
bus.emit(makeEvent('benchmark.progress', { iteration: i }))
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
await collector
|
|
146
|
-
|
|
147
|
-
expect(received).toEqual([1, 2, 3, 4, 5])
|
|
148
|
-
})
|
|
149
|
-
})
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* UDS readiness snapshot wiring — unit test for Task D1.
|
|
3
|
-
*
|
|
4
|
-
* Verifies that:
|
|
5
|
-
* 1. The hub's `LocalChildRegistry.onReadinessSnapshotRequest` is wired to
|
|
6
|
-
* return `readinessRegistry.getSnapshotForTransport()` — the same records
|
|
7
|
-
* `$readiness.getSnapshot` returns, now also reachable over UDS.
|
|
8
|
-
* 2. The agent's `agentUdsRegistry.onReadinessSnapshotRequest` is wired to
|
|
9
|
-
* return its own registry's snapshot.
|
|
10
|
-
*
|
|
11
|
-
* We do NOT spin up a full broker — instead we test the wiring function
|
|
12
|
-
* `wireReadinessSnapshotHandler` which is extracted from the hub/agent setup
|
|
13
|
-
* so the glue code is unit-testable.
|
|
14
|
-
*/
|
|
15
|
-
import { describe, it, expect, vi } from 'vitest'
|
|
16
|
-
import type { IReadinessRegistryRecord } from '@camstack/types'
|
|
17
|
-
|
|
18
|
-
// --------------------------------------------------------------------------
|
|
19
|
-
// Helpers
|
|
20
|
-
// --------------------------------------------------------------------------
|
|
21
|
-
|
|
22
|
-
interface FakeReadinessRegistry {
|
|
23
|
-
getSnapshotForTransport(): readonly IReadinessRegistryRecord[]
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
interface FakeLocalChildRegistry {
|
|
27
|
-
onReadinessSnapshotRequest(handler: () => readonly IReadinessRegistryRecord[]): void
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Minimal wiring function — production code calls exactly this at the same
|
|
32
|
-
* site in moleculer.service.ts and agent-bootstrap.ts.
|
|
33
|
-
*/
|
|
34
|
-
function wireReadinessSnapshotHandler(
|
|
35
|
-
childRegistry: FakeLocalChildRegistry,
|
|
36
|
-
readinessRegistry: FakeReadinessRegistry,
|
|
37
|
-
): void {
|
|
38
|
-
childRegistry.onReadinessSnapshotRequest(() => readinessRegistry.getSnapshotForTransport())
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// --------------------------------------------------------------------------
|
|
42
|
-
// Tests
|
|
43
|
-
// --------------------------------------------------------------------------
|
|
44
|
-
|
|
45
|
-
describe('D1 — wireReadinessSnapshotHandler', () => {
|
|
46
|
-
it('registers a handler on the child registry', () => {
|
|
47
|
-
const childReg: FakeLocalChildRegistry = {
|
|
48
|
-
onReadinessSnapshotRequest: vi.fn(),
|
|
49
|
-
}
|
|
50
|
-
const readinessReg: FakeReadinessRegistry = {
|
|
51
|
-
getSnapshotForTransport: () => [],
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
wireReadinessSnapshotHandler(childReg, readinessReg)
|
|
55
|
-
|
|
56
|
-
expect(childReg.onReadinessSnapshotRequest).toHaveBeenCalledOnce()
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
it('the registered handler returns getSnapshotForTransport() records', () => {
|
|
60
|
-
const records: IReadinessRegistryRecord[] = [
|
|
61
|
-
{
|
|
62
|
-
capName: 'pipeline-executor',
|
|
63
|
-
scope: { type: 'global' },
|
|
64
|
-
state: 'ready',
|
|
65
|
-
generation: 'gen-abc',
|
|
66
|
-
epoch: 1,
|
|
67
|
-
lastChange: 1_000_000,
|
|
68
|
-
sourceNodeId: 'hub/pipeline-executor',
|
|
69
|
-
},
|
|
70
|
-
]
|
|
71
|
-
|
|
72
|
-
let capturedHandler: (() => readonly IReadinessRegistryRecord[]) | null = null
|
|
73
|
-
const childReg: FakeLocalChildRegistry = {
|
|
74
|
-
onReadinessSnapshotRequest: (h) => {
|
|
75
|
-
capturedHandler = h
|
|
76
|
-
},
|
|
77
|
-
}
|
|
78
|
-
const readinessReg: FakeReadinessRegistry = {
|
|
79
|
-
getSnapshotForTransport: () => records,
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
wireReadinessSnapshotHandler(childReg, readinessReg)
|
|
83
|
-
|
|
84
|
-
expect(capturedHandler).not.toBeNull()
|
|
85
|
-
const result = capturedHandler!()
|
|
86
|
-
expect(result).toBe(records)
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
it('handler calls getSnapshotForTransport on every invocation (live snapshot)', () => {
|
|
90
|
-
const getSnapshot = vi
|
|
91
|
-
.fn<[], readonly IReadinessRegistryRecord[]>()
|
|
92
|
-
.mockReturnValueOnce([])
|
|
93
|
-
.mockReturnValueOnce([
|
|
94
|
-
{
|
|
95
|
-
capName: 'stream-broker',
|
|
96
|
-
scope: { type: 'node', nodeId: 'hub' },
|
|
97
|
-
state: 'ready',
|
|
98
|
-
generation: 'gen-1',
|
|
99
|
-
epoch: 1,
|
|
100
|
-
lastChange: 1_000,
|
|
101
|
-
sourceNodeId: 'hub',
|
|
102
|
-
},
|
|
103
|
-
])
|
|
104
|
-
|
|
105
|
-
let capturedHandler: (() => readonly IReadinessRegistryRecord[]) | null = null
|
|
106
|
-
const childReg: FakeLocalChildRegistry = {
|
|
107
|
-
onReadinessSnapshotRequest: (h) => {
|
|
108
|
-
capturedHandler = h
|
|
109
|
-
},
|
|
110
|
-
}
|
|
111
|
-
const readinessReg: FakeReadinessRegistry = { getSnapshotForTransport: getSnapshot }
|
|
112
|
-
|
|
113
|
-
wireReadinessSnapshotHandler(childReg, readinessReg)
|
|
114
|
-
|
|
115
|
-
expect(capturedHandler!()).toHaveLength(0)
|
|
116
|
-
expect(capturedHandler!()).toHaveLength(1)
|
|
117
|
-
expect(getSnapshot).toHaveBeenCalledTimes(2)
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
it('handler snapshot reflects current registry state (not a frozen copy)', () => {
|
|
121
|
-
const mutableRecords: IReadinessRegistryRecord[] = []
|
|
122
|
-
const readinessReg: FakeReadinessRegistry = {
|
|
123
|
-
getSnapshotForTransport: () => [...mutableRecords],
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
let capturedHandler: (() => readonly IReadinessRegistryRecord[]) | null = null
|
|
127
|
-
const childReg: FakeLocalChildRegistry = {
|
|
128
|
-
onReadinessSnapshotRequest: (h) => {
|
|
129
|
-
capturedHandler = h
|
|
130
|
-
},
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
wireReadinessSnapshotHandler(childReg, readinessReg)
|
|
134
|
-
|
|
135
|
-
expect(capturedHandler!()).toHaveLength(0)
|
|
136
|
-
|
|
137
|
-
mutableRecords.push({
|
|
138
|
-
capName: 'motion-detector',
|
|
139
|
-
scope: { type: 'device', deviceId: 7 },
|
|
140
|
-
state: 'starting',
|
|
141
|
-
generation: 'gen-2',
|
|
142
|
-
epoch: 0,
|
|
143
|
-
lastChange: 2_000,
|
|
144
|
-
sourceNodeId: 'hub/provider-reolink',
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
expect(capturedHandler!()).toHaveLength(1)
|
|
148
|
-
expect(capturedHandler!()[0]!.capName).toBe('motion-detector')
|
|
149
|
-
})
|
|
150
|
-
})
|