@camstack/server 1.1.20 → 1.1.22
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.
|
@@ -1,21 +1,38 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createEventBusProxyRouter = createEventBusProxyRouter;
|
|
4
2
|
/**
|
|
5
|
-
* EventBus proxy router — allows forked workers to emit events to
|
|
6
|
-
* hub's EventBus via tRPC.
|
|
3
|
+
* EventBus proxy router — allows forked workers to emit events to, and
|
|
4
|
+
* read the recent-events registry of, the hub's EventBus via tRPC.
|
|
7
5
|
*
|
|
8
6
|
* Workers call `trpc.eventBusProxy.emit.mutate(event)` from their
|
|
9
7
|
* `context.eventBus.emit()` implementation. The hub-side router
|
|
10
8
|
* deserializes the event and emits it on the real EventBus.
|
|
11
9
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* `getRecent` exposes the hub's retained recent-events registry to forked
|
|
11
|
+
* addon runners. Post the `retainRecent` change (f5a93332) ONLY the hub
|
|
12
|
+
* main process keeps the `recent[]` buffer — a child runner's own
|
|
13
|
+
* `ctx.eventBus.getRecent()` now returns `[]`. Addons that need event
|
|
14
|
+
* HISTORY (e.g. advanced-notifier's `testRule`) must read it from the hub
|
|
15
|
+
* over this proxy instead of their local, non-retaining bus. This router
|
|
16
|
+
* is in `CORE_NAMESPACES` (`core-cap-bridge.ts`), so the call reaches the
|
|
17
|
+
* hub's `services.eventBus` from any hub-local child over the UDS/core-cap
|
|
18
|
+
* path — exactly like `capabilities.*` / `system.*`.
|
|
19
|
+
*
|
|
20
|
+
* `subscribe` is routed through the existing `live.onEvent` subscription
|
|
21
|
+
* and `systemEvents.subscribe` routers — no duplication needed here.
|
|
14
22
|
*
|
|
15
23
|
* Introduced in session 7 (EventBus wiring for forked addons).
|
|
16
24
|
*/
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.createEventBusProxyRouter = createEventBusProxyRouter;
|
|
17
27
|
const zod_1 = require("zod");
|
|
18
28
|
const trpc_middleware_js_1 = require("../trpc/trpc.middleware.js");
|
|
29
|
+
/**
|
|
30
|
+
* Upper bound on the `getRecent` limit — kept in step with the hub's
|
|
31
|
+
* `recent[]` ring-buffer size (`MAX_RECENT_EVENTS` in `event-bus-core.ts`).
|
|
32
|
+
* Duplicated as a local literal rather than imported so this router does
|
|
33
|
+
* not depend on the event-bus core internals.
|
|
34
|
+
*/
|
|
35
|
+
const MAX_RECENT_EVENTS = 1000;
|
|
19
36
|
const SystemEventInputSchema = zod_1.z.object({
|
|
20
37
|
id: zod_1.z.string(),
|
|
21
38
|
timestamp: zod_1.z.string(), // ISO 8601 — converted to Date on emit
|
|
@@ -26,6 +43,50 @@ const SystemEventInputSchema = zod_1.z.object({
|
|
|
26
43
|
category: zod_1.z.string(),
|
|
27
44
|
data: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()),
|
|
28
45
|
});
|
|
46
|
+
/**
|
|
47
|
+
* `getRecent` input — mirrors `systemEvents.getRecent`'s category/limit
|
|
48
|
+
* semantics. `category` accepts a single string or an array so a caller
|
|
49
|
+
* can whitelist the categories it cares about server-side; `limit` is
|
|
50
|
+
* capped at the hub's `recent[]` buffer size (`MAX_RECENT_EVENTS`).
|
|
51
|
+
*/
|
|
52
|
+
const GetRecentInputSchema = zod_1.z.object({
|
|
53
|
+
category: zod_1.z.union([zod_1.z.string(), zod_1.z.array(zod_1.z.string())]).optional(),
|
|
54
|
+
limit: zod_1.z.number().int().min(1).max(MAX_RECENT_EVENTS).optional(),
|
|
55
|
+
});
|
|
56
|
+
/**
|
|
57
|
+
* Serialized recent event — `timestamp` is an ISO-8601 string so the
|
|
58
|
+
* shape survives every transport (UDS/MsgPack, Moleculer) unchanged.
|
|
59
|
+
* Callers reconstruct the `Date` on receipt. Mirrors the serialization
|
|
60
|
+
* used by `systemEvents.getRecent`.
|
|
61
|
+
*/
|
|
62
|
+
const RecentEventOutputSchema = zod_1.z.object({
|
|
63
|
+
id: zod_1.z.string(),
|
|
64
|
+
timestamp: zod_1.z.string(),
|
|
65
|
+
source: zod_1.z.object({
|
|
66
|
+
type: zod_1.z.string(),
|
|
67
|
+
id: zod_1.z.union([zod_1.z.string(), zod_1.z.number()]),
|
|
68
|
+
nodeId: zod_1.z.string().optional(),
|
|
69
|
+
addonId: zod_1.z.string().optional(),
|
|
70
|
+
deviceId: zod_1.z.number().optional(),
|
|
71
|
+
}),
|
|
72
|
+
category: zod_1.z.string(),
|
|
73
|
+
data: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()),
|
|
74
|
+
});
|
|
75
|
+
function serializeRecentEvent(e) {
|
|
76
|
+
return {
|
|
77
|
+
id: e.id,
|
|
78
|
+
timestamp: new Date(e.timestamp).toISOString(),
|
|
79
|
+
source: {
|
|
80
|
+
type: e.source.type,
|
|
81
|
+
id: e.source.id,
|
|
82
|
+
...(e.source.nodeId ? { nodeId: e.source.nodeId } : {}),
|
|
83
|
+
...(e.source.addonId ? { addonId: e.source.addonId } : {}),
|
|
84
|
+
...(e.source.deviceId !== undefined ? { deviceId: e.source.deviceId } : {}),
|
|
85
|
+
},
|
|
86
|
+
category: e.category,
|
|
87
|
+
data: e.data,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
29
90
|
function createEventBusProxyRouter(eventBus) {
|
|
30
91
|
return (0, trpc_middleware_js_1.trpcRouter)({
|
|
31
92
|
emit: trpc_middleware_js_1.protectedProcedure
|
|
@@ -41,5 +102,13 @@ function createEventBusProxyRouter(eventBus) {
|
|
|
41
102
|
});
|
|
42
103
|
return { ok: true };
|
|
43
104
|
}),
|
|
105
|
+
getRecent: trpc_middleware_js_1.protectedProcedure
|
|
106
|
+
.input(GetRecentInputSchema)
|
|
107
|
+
.output(zod_1.z.array(RecentEventOutputSchema))
|
|
108
|
+
.query(({ input }) => {
|
|
109
|
+
return eventBus
|
|
110
|
+
.getRecent(input.category !== undefined ? { category: input.category } : undefined, input.limit)
|
|
111
|
+
.map(serializeRecentEvent);
|
|
112
|
+
}),
|
|
44
113
|
});
|
|
45
114
|
}
|
|
@@ -36,7 +36,12 @@ class EventBusService {
|
|
|
36
36
|
if (this.broker === broker)
|
|
37
37
|
return;
|
|
38
38
|
this.broker = broker;
|
|
39
|
-
|
|
39
|
+
// The hub main process is the ONLY process that serves `getRecent` — so it
|
|
40
|
+
// is the only bus that opts into retaining the recent[] registry. Child
|
|
41
|
+
// addon runners + remote agents leave `retainRecent` false: their events
|
|
42
|
+
// are one-shot (fire-and-forget), fanned out to local subscribers but never
|
|
43
|
+
// accumulated, so their heap can't grow an unbounded recent[] backlog.
|
|
44
|
+
const inner = (0, system_1.getBrokerEventBus)(broker, { retainRecent: true });
|
|
40
45
|
this.inner = inner;
|
|
41
46
|
// Replay deferred subscriptions onto the real bus.
|
|
42
47
|
for (const sub of this.deferredSubs) {
|
|
@@ -436,7 +436,20 @@ class MoleculerService {
|
|
|
436
436
|
registry: this.localChildRegistry,
|
|
437
437
|
parentBus: this.eventBus,
|
|
438
438
|
parentNodeId: hubNodeId,
|
|
439
|
+
// D2: relay via pass-through so the bridge's wildcard is not counted as
|
|
440
|
+
// local interest (uniform with the agent; harmless here since the hub
|
|
441
|
+
// retains and always accepts inbound cross-node events anyway).
|
|
442
|
+
subscribePassthrough: (handler) => (0, system_1.subscribePassthrough)(this.broker, handler),
|
|
439
443
|
});
|
|
444
|
+
// D2: expose the hub's aggregate child interest to its `$event-bus`
|
|
445
|
+
// inbound gate for uniformity with the agent. NOTE: the hub main process
|
|
446
|
+
// opts into `retainRecent` (it serves `getRecent` + the admin-ui live
|
|
447
|
+
// event stream), so `crossNodeAcceptsCategory` always accepts every
|
|
448
|
+
// inbound category here — the hub never filters agent-origin events. This
|
|
449
|
+
// wiring is therefore harmless-but-uniform; the real efficiency win is on
|
|
450
|
+
// agents (non-retaining nodes).
|
|
451
|
+
const hubChildRegistry = this.localChildRegistry;
|
|
452
|
+
(0, system_1.setNodeEventInterest)(this.broker, () => hubChildRegistry.aggregateEventInterest());
|
|
440
453
|
}
|
|
441
454
|
}
|
|
442
455
|
/**
|