velocious 1.0.356 → 1.0.358

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 (62) hide show
  1. package/README.md +9 -0
  2. package/build/src/application.d.ts.map +1 -1
  3. package/build/src/application.js +3 -1
  4. package/build/src/background-jobs/main.d.ts.map +1 -1
  5. package/build/src/background-jobs/main.js +3 -1
  6. package/build/src/background-jobs/worker.d.ts.map +1 -1
  7. package/build/src/background-jobs/worker.js +4 -1
  8. package/build/src/beacon/client.d.ts +113 -0
  9. package/build/src/beacon/client.d.ts.map +1 -0
  10. package/build/src/beacon/client.js +224 -0
  11. package/build/src/beacon/in-process-broker.d.ts +22 -0
  12. package/build/src/beacon/in-process-broker.d.ts.map +1 -0
  13. package/build/src/beacon/in-process-broker.js +61 -0
  14. package/build/src/beacon/in-process-client.d.ts +74 -0
  15. package/build/src/beacon/in-process-client.d.ts.map +1 -0
  16. package/build/src/beacon/in-process-client.js +99 -0
  17. package/build/src/beacon/server.d.ts +61 -0
  18. package/build/src/beacon/server.d.ts.map +1 -0
  19. package/build/src/beacon/server.js +115 -0
  20. package/build/src/beacon/types.d.ts +76 -0
  21. package/build/src/beacon/types.d.ts.map +1 -0
  22. package/build/src/beacon/types.js +42 -0
  23. package/build/src/cli/commands/beacon.d.ts +5 -0
  24. package/build/src/cli/commands/beacon.d.ts.map +1 -0
  25. package/build/src/cli/commands/beacon.js +7 -0
  26. package/build/src/configuration-types.d.ts +36 -1
  27. package/build/src/configuration-types.d.ts.map +1 -1
  28. package/build/src/configuration-types.js +10 -1
  29. package/build/src/configuration.d.ts +114 -1
  30. package/build/src/configuration.d.ts.map +1 -1
  31. package/build/src/configuration.js +247 -2
  32. package/build/src/controller.d.ts +8 -0
  33. package/build/src/controller.d.ts.map +1 -1
  34. package/build/src/controller.js +39 -17
  35. package/build/src/database/drivers/base.d.ts.map +1 -1
  36. package/build/src/database/drivers/base.js +8 -1
  37. package/build/src/environment-handlers/base.d.ts +32 -0
  38. package/build/src/environment-handlers/base.d.ts.map +1 -1
  39. package/build/src/environment-handlers/base.js +48 -1
  40. package/build/src/environment-handlers/node/cli/commands/beacon.d.ts +5 -0
  41. package/build/src/environment-handlers/node/cli/commands/beacon.d.ts.map +1 -0
  42. package/build/src/environment-handlers/node/cli/commands/beacon.js +18 -0
  43. package/build/src/environment-handlers/node.d.ts +1 -0
  44. package/build/src/environment-handlers/node.d.ts.map +1 -1
  45. package/build/src/environment-handlers/node.js +52 -2
  46. package/build/src/http-server/client/index.d.ts.map +1 -1
  47. package/build/src/http-server/client/index.js +2 -1
  48. package/build/src/http-server/client/request-runner.d.ts +7 -1
  49. package/build/src/http-server/client/request-runner.d.ts.map +1 -1
  50. package/build/src/http-server/client/request-runner.js +46 -1
  51. package/build/src/http-server/client/request-timing.d.ts +75 -0
  52. package/build/src/http-server/client/request-timing.d.ts.map +1 -0
  53. package/build/src/http-server/client/request-timing.js +128 -0
  54. package/build/src/http-server/client/websocket-session.d.ts.map +1 -1
  55. package/build/src/http-server/client/websocket-session.js +4 -1
  56. package/build/src/logger/console-logger.d.ts +2 -2
  57. package/build/src/logger/file-logger.d.ts +2 -2
  58. package/build/src/routes/resolver.d.ts +21 -1
  59. package/build/src/routes/resolver.d.ts.map +1 -1
  60. package/build/src/routes/resolver.js +38 -6
  61. package/build/tsconfig.tsbuildinfo +1 -1
  62. package/package.json +1 -1
@@ -0,0 +1,224 @@
1
+ // @ts-check
2
+ import { randomUUID } from "node:crypto";
3
+ import net from "node:net";
4
+ import JsonSocket from "../background-jobs/json-socket.js";
5
+ import EventEmitter from "../utils/event-emitter.js";
6
+ const DEFAULT_RECONNECT_DELAY_MS = 1000;
7
+ const MAX_RECONNECT_DELAY_MS = 30_000;
8
+ /**
9
+ * @typedef {function(import("./types.js").BeaconBroadcastMessage): void} BeaconBroadcastHandler
10
+ */
11
+ /**
12
+ * BeaconClient connects to a `velocious beacon` daemon and exchanges
13
+ * broadcasts with all peer processes connected to the same daemon.
14
+ *
15
+ * Lifecycle:
16
+ * const client = new BeaconClient({host, port, peerType: "server"})
17
+ * await client.connect() // resolves on first successful connect
18
+ * client.onBroadcast((message) => { ... }) // every fan-out
19
+ * client.publish({channel, broadcastParams, body})
20
+ * await client.close()
21
+ *
22
+ * Reconnect: on socket close (without an explicit `close()` call) the
23
+ * client schedules a reconnect with exponential backoff. While the
24
+ * underlying socket is down, `publish(...)` returns false and the
25
+ * caller can fall back to local-only delivery; subsequent reconnects do
26
+ * not replay missed publishes (Beacon is pubsub, not a queue).
27
+ */
28
+ export default class BeaconClient extends EventEmitter {
29
+ /**
30
+ * @param {object} args - Options.
31
+ * @param {string} args.host - Beacon host.
32
+ * @param {number} args.port - Beacon port.
33
+ * @param {string} [args.peerType] - Optional human-readable peer label.
34
+ * @param {string} [args.peerId] - Optional explicit peer id (defaults to a random UUID).
35
+ * @param {number} [args.reconnectDelayMs] - Starting reconnect delay in ms.
36
+ * @param {number} [args.maxReconnectDelayMs] - Maximum reconnect delay in ms.
37
+ */
38
+ constructor({ host, port, peerType, peerId, reconnectDelayMs, maxReconnectDelayMs }) {
39
+ super();
40
+ this.host = host;
41
+ this.port = port;
42
+ this.peerType = peerType;
43
+ this.peerId = peerId || randomUUID();
44
+ this._initialReconnectDelayMs = reconnectDelayMs ?? DEFAULT_RECONNECT_DELAY_MS;
45
+ this._maxReconnectDelayMs = maxReconnectDelayMs ?? MAX_RECONNECT_DELAY_MS;
46
+ this._reconnectDelayMs = this._initialReconnectDelayMs;
47
+ /** @type {JsonSocket | undefined} */
48
+ this._jsonSocket = undefined;
49
+ /** @type {net.Socket | undefined} */
50
+ this._socket = undefined;
51
+ this._connected = false;
52
+ this._closed = false;
53
+ /** @type {NodeJS.Timeout | undefined} */
54
+ this._reconnectTimer = undefined;
55
+ /** @type {Promise<void> | undefined} */
56
+ this._connectPromise = undefined;
57
+ /**
58
+ * Last socket error observed while connected, surfaced as the disconnect reason.
59
+ * @type {Error | undefined}
60
+ */
61
+ this._lastSocketError = undefined;
62
+ }
63
+ /** @returns {string} - The peer id sent on the hello handshake. */
64
+ getPeerId() { return this.peerId; }
65
+ /** @returns {boolean} - Whether the underlying socket is currently connected. */
66
+ isConnected() { return this._connected; }
67
+ /**
68
+ * Resolves on the first successful connect. Subsequent calls return
69
+ * the same promise. Subsequent reconnects after a drop are silent —
70
+ * use `on("connect")` / `on("disconnect", reason)` to observe them.
71
+ * The `disconnect` listener receives an `Error` reason: either the
72
+ * underlying socket error, or `Error("Beacon broker disconnected")`
73
+ * when the close had no preceding error.
74
+ * @returns {Promise<void>}
75
+ */
76
+ async connect() {
77
+ if (this._closed)
78
+ throw new Error("BeaconClient has been closed");
79
+ if (this._connectPromise)
80
+ return await this._connectPromise;
81
+ this._connectPromise = new Promise((resolve, reject) => {
82
+ const onConnect = () => {
83
+ this.off("connect", onConnect);
84
+ this.off("connect-error", onError);
85
+ resolve();
86
+ };
87
+ const onError = (/** @type {Error} */ error) => {
88
+ this.off("connect", onConnect);
89
+ this.off("connect-error", onError);
90
+ reject(error);
91
+ };
92
+ this.on("connect", onConnect);
93
+ this.on("connect-error", onError);
94
+ });
95
+ this._openSocket();
96
+ return await this._connectPromise;
97
+ }
98
+ /**
99
+ * Publishes a broadcast message to all peers (including this one,
100
+ * unless the daemon is restarted mid-publish).
101
+ * @param {object} args - Broadcast args.
102
+ * @param {string} args.channel - Channel name.
103
+ * @param {Record<string, any>} args.broadcastParams - Routing params.
104
+ * @param {any} args.body - Message body.
105
+ * @returns {boolean} - True if the publish was written to the socket. False if the client is currently disconnected.
106
+ */
107
+ publish({ channel, broadcastParams, body }) {
108
+ if (!this._connected || !this._jsonSocket)
109
+ return false;
110
+ /** @type {import("./types.js").BeaconBroadcastMessage} */
111
+ const message = {
112
+ type: "broadcast",
113
+ channel,
114
+ broadcastParams,
115
+ body,
116
+ originPeerId: this.peerId
117
+ };
118
+ try {
119
+ this._jsonSocket.send(message);
120
+ return true;
121
+ }
122
+ catch {
123
+ return false;
124
+ }
125
+ }
126
+ /**
127
+ * Registers a handler called once for every `broadcast` message
128
+ * received from the daemon (including echoes of this client's own
129
+ * publishes — synapse-style fan-out).
130
+ * @param {BeaconBroadcastHandler} handler - Handler.
131
+ * @returns {() => void} - Unregister function.
132
+ */
133
+ onBroadcast(handler) {
134
+ this.on("broadcast", handler);
135
+ return () => this.off("broadcast", handler);
136
+ }
137
+ /** @returns {Promise<void>} - Resolves once the socket is closed. */
138
+ async close() {
139
+ this._closed = true;
140
+ if (this._reconnectTimer) {
141
+ clearTimeout(this._reconnectTimer);
142
+ this._reconnectTimer = undefined;
143
+ }
144
+ if (this._socket) {
145
+ const socket = this._socket;
146
+ await new Promise((resolve) => {
147
+ socket.once("close", () => resolve(undefined));
148
+ socket.end();
149
+ });
150
+ }
151
+ }
152
+ /**
153
+ * @returns {void}
154
+ */
155
+ _openSocket() {
156
+ if (this._closed)
157
+ return;
158
+ const socket = net.createConnection({ host: this.host, port: this.port });
159
+ this._socket = socket;
160
+ const jsonSocket = new JsonSocket(socket);
161
+ this._jsonSocket = jsonSocket;
162
+ socket.on("connect", () => {
163
+ this._connected = true;
164
+ this._reconnectDelayMs = this._initialReconnectDelayMs;
165
+ jsonSocket.send({
166
+ type: "hello",
167
+ role: "client",
168
+ peerId: this.peerId,
169
+ peerType: this.peerType
170
+ });
171
+ this.emit("connect");
172
+ });
173
+ jsonSocket.on("message", (/** @type {import("./types.js").BeaconSocketMessage} */ message) => {
174
+ if (message?.type === "broadcast") {
175
+ this.emit("broadcast", message);
176
+ }
177
+ });
178
+ jsonSocket.on("error", (error) => {
179
+ if (!this._connected) {
180
+ // Initial connect failed — surface to `connect()`'s promise via `connect-error`.
181
+ // No `error` emit: that channel is for established-session errors; the
182
+ // initial-connect path is owned by `connect-error`.
183
+ this.emit("connect-error", error);
184
+ }
185
+ else {
186
+ // Established session error. Cache so the upcoming `close` event can
187
+ // surface it as the disconnect reason.
188
+ this._lastSocketError = error;
189
+ this.emit("error", error);
190
+ }
191
+ });
192
+ jsonSocket.on("close", () => {
193
+ const wasConnected = this._connected;
194
+ this._connected = false;
195
+ this._jsonSocket = undefined;
196
+ this._socket = undefined;
197
+ // Explicit close() sets `_closed = true` before ending the socket.
198
+ // Don't surface user-initiated teardown as a disconnect "error" —
199
+ // only network-driven drops should be reported.
200
+ if (wasConnected && !this._closed) {
201
+ const reason = this._lastSocketError || new Error("Beacon broker disconnected");
202
+ this.emit("disconnect", reason);
203
+ }
204
+ this._lastSocketError = undefined;
205
+ if (this._closed)
206
+ return;
207
+ this._scheduleReconnect();
208
+ });
209
+ }
210
+ /**
211
+ * @returns {void}
212
+ */
213
+ _scheduleReconnect() {
214
+ if (this._reconnectTimer)
215
+ return;
216
+ const delay = this._reconnectDelayMs;
217
+ this._reconnectTimer = setTimeout(() => {
218
+ this._reconnectTimer = undefined;
219
+ this._reconnectDelayMs = Math.min(delay * 2, this._maxReconnectDelayMs);
220
+ this._openSocket();
221
+ }, delay);
222
+ }
223
+ }
224
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2JlYWNvbi9jbGllbnQuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxhQUFhLENBQUE7QUFDdEMsT0FBTyxHQUFHLE1BQU0sVUFBVSxDQUFBO0FBRTFCLE9BQU8sVUFBVSxNQUFNLG1DQUFtQyxDQUFBO0FBQzFELE9BQU8sWUFBWSxNQUFNLDJCQUEyQixDQUFBO0FBRXBELE1BQU0sMEJBQTBCLEdBQUcsSUFBSSxDQUFBO0FBQ3ZDLE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxDQUFBO0FBRXJDOztHQUVHO0FBRUg7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQkc7QUFDSCxNQUFNLENBQUMsT0FBTyxPQUFPLFlBQWEsU0FBUSxZQUFZO0lBQ3BEOzs7Ozs7OztPQVFHO0lBQ0gsWUFBWSxFQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxtQkFBbUIsRUFBQztRQUMvRSxLQUFLLEVBQUUsQ0FBQTtRQUNQLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFBO1FBQ2hCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFBO1FBQ2hCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFBO1FBQ3hCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxJQUFJLFVBQVUsRUFBRSxDQUFBO1FBQ3BDLElBQUksQ0FBQyx3QkFBd0IsR0FBRyxnQkFBZ0IsSUFBSSwwQkFBMEIsQ0FBQTtRQUM5RSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsbUJBQW1CLElBQUksc0JBQXNCLENBQUE7UUFDekUsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQyx3QkFBd0IsQ0FBQTtRQUN0RCxxQ0FBcUM7UUFDckMsSUFBSSxDQUFDLFdBQVcsR0FBRyxTQUFTLENBQUE7UUFDNUIscUNBQXFDO1FB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LFNBQVMsQ0FBQTtZQUM1QixJQUFJLENBQUMsT0FBTyxHQUFHLFNBQVMsQ0FBQTtZQUV4QixtRUFBbUU7WUFDbkUsa0VBQWtFO1lBQ2xFLGdEQUFnRDtZQUNoRCxJQUFJLFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDbEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixJQUFJLElBQUksS0FBSyxDQUFDLDRCQUE0QixDQUFDLENBQUE7Z0JBRS9FLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFBO1lBQ2pDLENBQUM7WUFFRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsU0FBUyxDQUFBO1lBRWpDLElBQUksSUFBSSxDQUFDLE9BQU87Z0JBQUUsT0FBTTtZQUV4QixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQTtRQUMzQixDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFFRDs7T0FFRztJQUNILGtCQUFrQjtRQUNoQixJQUFJLElBQUksQ0FBQyxlQUFlO1lBQUUsT0FBTTtRQUVoQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUE7UUFFcEMsSUFBSSxDQUFDLGVBQWUsR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ3JDLElBQUksQ0FBQyxlQUFlLEdBQUcsU0FBUyxDQUFBO1lBQ2hDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUE7WUFDdkUsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFBO1FBQ3BCLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQTtJQUNYLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQge3JhbmRvbVVVSUR9IGZyb20gXCJub2RlOmNyeXB0b1wiXG5pbXBvcnQgbmV0IGZyb20gXCJub2RlOm5ldFwiXG5cbmltcG9ydCBKc29uU29ja2V0IGZyb20gXCIuLi9iYWNrZ3JvdW5kLWpvYnMvanNvbi1zb2NrZXQuanNcIlxuaW1wb3J0IEV2ZW50RW1pdHRlciBmcm9tIFwiLi4vdXRpbHMvZXZlbnQtZW1pdHRlci5qc1wiXG5cbmNvbnN0IERFRkFVTFRfUkVDT05ORUNUX0RFTEFZX01TID0gMTAwMFxuY29uc3QgTUFYX1JFQ09OTkVDVF9ERUxBWV9NUyA9IDMwXzAwMFxuXG4vKipcbiAqIEB0eXBlZGVmIHtmdW5jdGlvbihpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkJlYWNvbkJyb2FkY2FzdE1lc3NhZ2UpOiB2b2lkfSBCZWFjb25Ccm9hZGNhc3RIYW5kbGVyXG4gKi9cblxuLyoqXG4gKiBCZWFjb25DbGllbnQgY29ubmVjdHMgdG8gYSBgdmVsb2Npb3VzIGJlYWNvbmAgZGFlbW9uIGFuZCBleGNoYW5nZXNcbiAqIGJyb2FkY2FzdHMgd2l0aCBhbGwgcGVlciBwcm9jZXNzZXMgY29ubmVjdGVkIHRvIHRoZSBzYW1lIGRhZW1vbi5cbiAqXG4gKiBMaWZlY3ljbGU6XG4gKiAgIGNvbnN0IGNsaWVudCA9IG5ldyBCZWFjb25DbGllbnQoe2hvc3QsIHBvcnQsIHBlZXJUeXBlOiBcInNlcnZlclwifSlcbiAqICAgYXdhaXQgY2xpZW50LmNvbm5lY3QoKSAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZXNvbHZlcyBvbiBmaXJzdCBzdWNjZXNzZnVsIGNvbm5lY3RcbiAqICAgY2xpZW50Lm9uQnJvYWRjYXN0KChtZXNzYWdlKSA9PiB7IC4uLiB9KSAgICAgICAvLyBldmVyeSBmYW4tb3V0XG4gKiAgIGNsaWVudC5wdWJsaXNoKHtjaGFubmVsLCBicm9hZGNhc3RQYXJhbXMsIGJvZHl9KVxuICogICBhd2FpdCBjbGllbnQuY2xvc2UoKVxuICpcbiAqIFJlY29ubmVjdDogb24gc29ja2V0IGNsb3NlICh3aXRob3V0IGFuIGV4cGxpY2l0IGBjbG9zZSgpYCBjYWxsKSB0aGVcbiAqIGNsaWVudCBzY2hlZHVsZXMgYSByZWNvbm5lY3Qgd2l0aCBleHBvbmVudGlhbCBiYWNrb2ZmLiBXaGlsZSB0aGVcbiAqIHVuZGVybHlpbmcgc29ja2V0IGlzIGRvd24sIGBwdWJsaXNoKC4uLilgIHJldHVybnMgZmFsc2UgYW5kIHRoZVxuICogY2FsbGVyIGNhbiBmYWxsIGJhY2sgdG8gbG9jYWwtb25seSBkZWxpdmVyeTsgc3Vic2VxdWVudCByZWNvbm5lY3RzIGRvXG4gKiBub3QgcmVwbGF5IG1pc3NlZCBwdWJsaXNoZXMgKEJlYWNvbiBpcyBwdWJzdWIsIG5vdCBhIHF1ZXVlKS5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQmVhY29uQ2xpZW50IGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuaG9zdCAtIEJlYWNvbiBob3N0LlxuICAgKiBAcGFyYW0ge251bWJlcn0gYXJncy5wb3J0IC0gQmVhY29uIHBvcnQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYXJncy5wZWVyVHlwZV0gLSBPcHRpb25hbCBodW1hbi1yZWFkYWJsZSBwZWVyIGxhYmVsLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2FyZ3MucGVlcklkXSAtIE9wdGlvbmFsIGV4cGxpY2l0IHBlZXIgaWQgKGRlZmF1bHRzIHRvIGEgcmFuZG9tIFVVSUQpLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW2FyZ3MucmVjb25uZWN0RGVsYXlNc10gLSBTdGFydGluZyByZWNvbm5lY3QgZGVsYXkgaW4gbXMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJncy5tYXhSZWNvbm5lY3REZWxheU1zXSAtIE1heGltdW0gcmVjb25uZWN0IGRlbGF5IGluIG1zLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe2hvc3QsIHBvcnQsIHBlZXJUeXBlLCBwZWVySWQsIHJlY29ubmVjdERlbGF5TXMsIG1heFJlY29ubmVjdERlbGF5TXN9KSB7XG4gICAgc3VwZXIoKVxuICAgIHRoaXMuaG9zdCA9IGhvc3RcbiAgICB0aGlzLnBvcnQgPSBwb3J0XG4gICAgdGhpcy5wZWVyVHlwZSA9IHBlZXJUeXBlXG4gICAgdGhpcy5wZWVySWQgPSBwZWVySWQgfHwgcmFuZG9tVVVJRCgpXG4gICAgdGhpcy5faW5pdGlhbFJlY29ubmVjdERlbGF5TXMgPSByZWNvbm5lY3REZWxheU1zID8/IERFRkFVTFRfUkVDT05ORUNUX0RFTEFZX01TXG4gICAgdGhpcy5fbWF4UmVjb25uZWN0RGVsYXlNcyA9IG1heFJlY29ubmVjdERlbGF5TXMgPz8gTUFYX1JFQ09OTkVDVF9ERUxBWV9NU1xuICAgIHRoaXMuX3JlY29ubmVjdERlbGF5TXMgPSB0aGlzLl9pbml0aWFsUmVjb25uZWN0RGVsYXlNc1xuICAgIC8qKiBAdHlwZSB7SnNvblNvY2tldCB8IHVuZGVmaW5lZH0gKi9cbiAgICB0aGlzLl9qc29uU29ja2V0ID0gdW5kZWZpbmVkXG4gICAgLyoqIEB0eXBlIHtuZXQuU29ja2V0IHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMuX3NvY2tldCA9IHVuZGVmaW5lZFxuICAgIHRoaXMuX2Nvbm5lY3RlZCA9IGZhbHNlXG4gICAgdGhpcy5fY2xvc2VkID0gZmFsc2VcbiAgICAvKiogQHR5cGUge05vZGVKUy5UaW1lb3V0IHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMuX3JlY29ubmVjdFRpbWVyID0gdW5kZWZpbmVkXG4gICAgLyoqIEB0eXBlIHtQcm9taXNlPHZvaWQ+IHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMuX2Nvbm5lY3RQcm9taXNlID0gdW5kZWZpbmVkXG4gICAgLyoqXG4gICAgICogTGFzdCBzb2NrZXQgZXJyb3Igb2JzZXJ2ZWQgd2hpbGUgY29ubmVjdGVkLCBzdXJmYWNlZCBhcyB0aGUgZGlzY29ubmVjdCByZWFzb24uXG4gICAgICogQHR5cGUge0Vycm9yIHwgdW5kZWZpbmVkfVxuICAgICAqL1xuICAgIHRoaXMuX2xhc3RTb2NrZXRFcnJvciA9IHVuZGVmaW5lZFxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtzdHJpbmd9IC0gVGhlIHBlZXIgaWQgc2VudCBvbiB0aGUgaGVsbG8gaGFuZHNoYWtlLiAqL1xuICBnZXRQZWVySWQoKSB7IHJldHVybiB0aGlzLnBlZXJJZCB9XG5cbiAgLyoqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdGhlIHVuZGVybHlpbmcgc29ja2V0IGlzIGN1cnJlbnRseSBjb25uZWN0ZWQuICovXG4gIGlzQ29ubmVjdGVkKCkgeyByZXR1cm4gdGhpcy5fY29ubmVjdGVkIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgb24gdGhlIGZpcnN0IHN1Y2Nlc3NmdWwgY29ubmVjdC4gU3Vic2VxdWVudCBjYWxscyByZXR1cm5cbiAgICogdGhlIHNhbWUgcHJvbWlzZS4gU3Vic2VxdWVudCByZWNvbm5lY3RzIGFmdGVyIGEgZHJvcCBhcmUgc2lsZW50IOKAlFxuICAgKiB1c2UgYG9uKFwiY29ubmVjdFwiKWAgLyBgb24oXCJkaXNjb25uZWN0XCIsIHJlYXNvbilgIHRvIG9ic2VydmUgdGhlbS5cbiAgICogVGhlIGBkaXNjb25uZWN0YCBsaXN0ZW5lciByZWNlaXZlcyBhbiBgRXJyb3JgIHJlYXNvbjogZWl0aGVyIHRoZVxuICAgKiB1bmRlcmx5aW5nIHNvY2tldCBlcnJvciwgb3IgYEVycm9yKFwiQmVhY29uIGJyb2tlciBkaXNjb25uZWN0ZWRcIilgXG4gICAqIHdoZW4gdGhlIGNsb3NlIGhhZCBubyBwcmVjZWRpbmcgZXJyb3IuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgKi9cbiAgYXN5bmMgY29ubmVjdCgpIHtcbiAgICBpZiAodGhpcy5fY2xvc2VkKSB0aHJvdyBuZXcgRXJyb3IoXCJCZWFjb25DbGllbnQgaGFzIGJlZW4gY2xvc2VkXCIpXG4gICAgaWYgKHRoaXMuX2Nvbm5lY3RQcm9taXNlKSByZXR1cm4gYXdhaXQgdGhpcy5fY29ubmVjdFByb21pc2VcblxuICAgIHRoaXMuX2Nvbm5lY3RQcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3Qgb25Db25uZWN0ID0gKCkgPT4ge1xuICAgICAgICB0aGlzLm9mZihcImNvbm5lY3RcIiwgb25Db25uZWN0KVxuICAgICAgICB0aGlzLm9mZihcImNvbm5lY3QtZXJyb3JcIiwgb25FcnJvcilcbiAgICAgICAgcmVzb2x2ZSgpXG4gICAgICB9XG4gICAgICBjb25zdCBvbkVycm9yID0gKC8qKiBAdHlwZSB7RXJyb3J9ICovIGVycm9yKSA9PiB7XG4gICAgICAgIHRoaXMub2ZmKFwiY29ubmVjdFwiLCBvbkNvbm5lY3QpXG4gICAgICAgIHRoaXMub2ZmKFwiY29ubmVjdC1lcnJvclwiLCBvbkVycm9yKVxuICAgICAgICByZWplY3QoZXJyb3IpXG4gICAgICB9XG5cbiAgICAgIHRoaXMub24oXCJjb25uZWN0XCIsIG9uQ29ubmVjdClcbiAgICAgIHRoaXMub24oXCJjb25uZWN0LWVycm9yXCIsIG9uRXJyb3IpXG4gICAgfSlcblxuICAgIHRoaXMuX29wZW5Tb2NrZXQoKVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuX2Nvbm5lY3RQcm9taXNlXG4gIH1cblxuICAvKipcbiAgICogUHVibGlzaGVzIGEgYnJvYWRjYXN0IG1lc3NhZ2UgdG8gYWxsIHBlZXJzIChpbmNsdWRpbmcgdGhpcyBvbmUsXG4gICAqIHVubGVzcyB0aGUgZGFlbW9uIGlzIHJlc3RhcnRlZCBtaWQtcHVibGlzaCkuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQnJvYWRjYXN0IGFyZ3MuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmNoYW5uZWwgLSBDaGFubmVsIG5hbWUuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gYXJncy5icm9hZGNhc3RQYXJhbXMgLSBSb3V0aW5nIHBhcmFtcy5cbiAgICogQHBhcmFtIHthbnl9IGFyZ3MuYm9keSAtIE1lc3NhZ2UgYm9keS5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gVHJ1ZSBpZiB0aGUgcHVibGlzaCB3YXMgd3JpdHRlbiB0byB0aGUgc29ja2V0LiBGYWxzZSBpZiB0aGUgY2xpZW50IGlzIGN1cnJlbnRseSBkaXNjb25uZWN0ZWQuXG4gICAqL1xuICBwdWJsaXNoKHtjaGFubmVsLCBicm9hZGNhc3RQYXJhbXMsIGJvZHl9KSB7XG4gICAgaWYgKCF0aGlzLl9jb25uZWN0ZWQgfHwgIXRoaXMuX2pzb25Tb2NrZXQpIHJldHVybiBmYWxzZVxuXG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkJlYWNvbkJyb2FkY2FzdE1lc3NhZ2V9ICovXG4gICAgY29uc3QgbWVzc2FnZSA9IHtcbiAgICAgIHR5cGU6IFwiYnJvYWRjYXN0XCIsXG4gICAgICBjaGFubmVsLFxuICAgICAgYnJvYWRjYXN0UGFyYW1zLFxuICAgICAgYm9keSxcbiAgICAgIG9yaWdpblBlZXJJZDogdGhpcy5wZWVySWRcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgdGhpcy5fanNvblNvY2tldC5zZW5kKG1lc3NhZ2UpXG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBhIGhhbmRsZXIgY2FsbGVkIG9uY2UgZm9yIGV2ZXJ5IGBicm9hZGNhc3RgIG1lc3NhZ2VcbiAgICogcmVjZWl2ZWQgZnJvbSB0aGUgZGFlbW9uIChpbmNsdWRpbmcgZWNob2VzIG9mIHRoaXMgY2xpZW50J3Mgb3duXG4gICAqIHB1Ymxpc2hlcyDigJQgc3luYXBzZS1zdHlsZSBmYW4tb3V0KS5cbiAgICogQHBhcmFtIHtCZWFjb25Ccm9hZGNhc3RIYW5kbGVyfSBoYW5kbGVyIC0gSGFuZGxlci5cbiAgICogQHJldHVybnMgeygpID0+IHZvaWR9IC0gVW5yZWdpc3RlciBmdW5jdGlvbi5cbiAgICovXG4gIG9uQnJvYWRjYXN0KGhhbmRsZXIpIHtcbiAgICB0aGlzLm9uKFwiYnJvYWRjYXN0XCIsIGhhbmRsZXIpXG4gICAgcmV0dXJuICgpID0+IHRoaXMub2ZmKFwiYnJvYWRjYXN0XCIsIGhhbmRsZXIpXG4gIH1cblxuICAvKiogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgb25jZSB0aGUgc29ja2V0IGlzIGNsb3NlZC4gKi9cbiAgYXN5bmMgY2xvc2UoKSB7XG4gICAgdGhpcy5fY2xvc2VkID0gdHJ1ZVxuXG4gICAgaWYgKHRoaXMuX3JlY29ubmVjdFRpbWVyKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5fcmVjb25uZWN0VGltZXIpXG4gICAgICB0aGlzLl9yZWNvbm5lY3RUaW1lciA9IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIGlmICh0aGlzLl9zb2NrZXQpIHtcbiAgICAgIGNvbnN0IHNvY2tldCA9IHRoaXMuX3NvY2tldFxuXG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICBzb2NrZXQub25jZShcImNsb3NlXCIsICgpID0+IHJlc29sdmUodW5kZWZpbmVkKSlcbiAgICAgICAgc29ja2V0LmVuZCgpXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIF9vcGVuU29ja2V0KCkge1xuICAgIGlmICh0aGlzLl9jbG9zZWQpIHJldHVyblxuXG4gICAgY29uc3Qgc29ja2V0ID0gbmV0LmNyZWF0ZUNvbm5lY3Rpb24oe2hvc3Q6IHRoaXMuaG9zdCwgcG9ydDogdGhpcy5wb3J0fSlcbiAgICB0aGlzLl9zb2NrZXQgPSBzb2NrZXRcbiAgICBjb25zdCBqc29uU29ja2V0ID0gbmV3IEpzb25Tb2NrZXQoc29ja2V0KVxuICAgIHRoaXMuX2pzb25Tb2NrZXQgPSBqc29uU29ja2V0XG5cbiAgICBzb2NrZXQub24oXCJjb25uZWN0XCIsICgpID0+IHtcbiAgICAgIHRoaXMuX2Nvbm5lY3RlZCA9IHRydWVcbiAgICAgIHRoaXMuX3JlY29ubmVjdERlbGF5TXMgPSB0aGlzLl9pbml0aWFsUmVjb25uZWN0RGVsYXlNc1xuXG4gICAgICBqc29uU29ja2V0LnNlbmQoe1xuICAgICAgICB0eXBlOiBcImhlbGxvXCIsXG4gICAgICAgIHJvbGU6IFwiY2xpZW50XCIsXG4gICAgICAgIHBlZXJJZDogdGhpcy5wZWVySWQsXG4gICAgICAgIHBlZXJUeXBlOiB0aGlzLnBlZXJUeXBlXG4gICAgICB9KVxuXG4gICAgICB0aGlzLmVtaXQoXCJjb25uZWN0XCIpXG4gICAgfSlcblxuICAgIGpzb25Tb2NrZXQub24oXCJtZXNzYWdlXCIsICgvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuQmVhY29uU29ja2V0TWVzc2FnZX0gKi8gbWVzc2FnZSkgPT4ge1xuICAgICAgaWYgKG1lc3NhZ2U/LnR5cGUgPT09IFwiYnJvYWRjYXN0XCIpIHtcbiAgICAgICAgdGhpcy5lbWl0KFwiYnJvYWRjYXN0XCIsIG1lc3NhZ2UpXG4gICAgICB9XG4gICAgfSlcblxuICAgIGpzb25Tb2NrZXQub24oXCJlcnJvclwiLCAoZXJyb3IpID0+IHtcbiAgICAgIGlmICghdGhpcy5fY29ubmVjdGVkKSB7XG4gICAgICAgIC8vIEluaXRpYWwgY29ubmVjdCBmYWlsZWQg4oCUIHN1cmZhY2UgdG8gYGNvbm5lY3QoKWAncyBwcm9taXNlIHZpYSBgY29ubmVjdC1lcnJvcmAuXG4gICAgICAgIC8vIE5vIGBlcnJvcmAgZW1pdDogdGhhdCBjaGFubmVsIGlzIGZvciBlc3RhYmxpc2hlZC1zZXNzaW9uIGVycm9yczsgdGhlXG4gICAgICAgIC8vIGluaXRpYWwtY29ubmVjdCBwYXRoIGlzIG93bmVkIGJ5IGBjb25uZWN0LWVycm9yYC5cbiAgICAgICAgdGhpcy5lbWl0KFwiY29ubmVjdC1lcnJvclwiLCBlcnJvcilcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEVzdGFibGlzaGVkIHNlc3Npb24gZXJyb3IuIENhY2hlIHNvIHRoZSB1cGNvbWluZyBgY2xvc2VgIGV2ZW50IGNhblxuICAgICAgICAvLyBzdXJmYWNlIGl0IGFzIHRoZSBkaXNjb25uZWN0IHJlYXNvbi5cbiAgICAgICAgdGhpcy5fbGFzdFNvY2tldEVycm9yID0gZXJyb3JcbiAgICAgICAgdGhpcy5lbWl0KFwiZXJyb3JcIiwgZXJyb3IpXG4gICAgICB9XG4gICAgfSlcblxuICAgIGpzb25Tb2NrZXQub24oXCJjbG9zZVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCB3YXNDb25uZWN0ZWQgPSB0aGlzLl9jb25uZWN0ZWRcblxuICAgICAgdGhpcy5fY29ubmVjdGVkID0gZmFsc2VcbiAgICAgIHRoaXMuX2pzb25Tb2NrZXQgPSB1bmRlZmluZWRcbiAgICAgIHRoaXMuX3NvY2tldCA9IHVuZGVmaW5lZFxuXG4gICAgICAvLyBFeHBsaWNpdCBjbG9zZSgpIHNldHMgYF9jbG9zZWQgPSB0cnVlYCBiZWZvcmUgZW5kaW5nIHRoZSBzb2NrZXQuXG4gICAgICAvLyBEb24ndCBzdXJmYWNlIHVzZXItaW5pdGlhdGVkIHRlYXJkb3duIGFzIGEgZGlzY29ubmVjdCBcImVycm9yXCIg4oCUXG4gICAgICAvLyBvbmx5IG5ldHdvcmstZHJpdmVuIGRyb3BzIHNob3VsZCBiZSByZXBvcnRlZC5cbiAgICAgIGlmICh3YXNDb25uZWN0ZWQgJiYgIXRoaXMuX2Nsb3NlZCkge1xuICAgICAgICBjb25zdCByZWFzb24gPSB0aGlzLl9sYXN0U29ja2V0RXJyb3IgfHwgbmV3IEVycm9yKFwiQmVhY29uIGJyb2tlciBkaXNjb25uZWN0ZWRcIilcblxuICAgICAgICB0aGlzLmVtaXQoXCJkaXNjb25uZWN0XCIsIHJlYXNvbilcbiAgICAgIH1cblxuICAgICAgdGhpcy5fbGFzdFNvY2tldEVycm9yID0gdW5kZWZpbmVkXG5cbiAgICAgIGlmICh0aGlzLl9jbG9zZWQpIHJldHVyblxuXG4gICAgICB0aGlzLl9zY2hlZHVsZVJlY29ubmVjdCgpXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIF9zY2hlZHVsZVJlY29ubmVjdCgpIHtcbiAgICBpZiAodGhpcy5fcmVjb25uZWN0VGltZXIpIHJldHVyblxuXG4gICAgY29uc3QgZGVsYXkgPSB0aGlzLl9yZWNvbm5lY3REZWxheU1zXG5cbiAgICB0aGlzLl9yZWNvbm5lY3RUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5fcmVjb25uZWN0VGltZXIgPSB1bmRlZmluZWRcbiAgICAgIHRoaXMuX3JlY29ubmVjdERlbGF5TXMgPSBNYXRoLm1pbihkZWxheSAqIDIsIHRoaXMuX21heFJlY29ubmVjdERlbGF5TXMpXG4gICAgICB0aGlzLl9vcGVuU29ja2V0KClcbiAgICB9LCBkZWxheSlcbiAgfVxufVxuIl19
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Registers a peer with the broker. Returns an unregister function.
3
+ * @param {InProcessPeer} peer - Peer instance.
4
+ * @returns {() => void} - Unregister function.
5
+ */
6
+ export function registerInProcessPeer(peer: InProcessPeer): () => void;
7
+ /**
8
+ * Schedules a fan-out of the given message to every registered peer.
9
+ * Each delivery is its own microtask so handlers run in the order peers
10
+ * registered, but never synchronously inside the publish call.
11
+ * @param {import("./types.js").BeaconBroadcastMessage} message - Broadcast message.
12
+ * @returns {void}
13
+ */
14
+ export function publishToInProcessPeers(message: import("./types.js").BeaconBroadcastMessage): void;
15
+ /**
16
+ * @returns {number} - Current peer count. Exposed for diagnostics and tests.
17
+ */
18
+ export function getInProcessPeerCount(): number;
19
+ export type InProcessPeer = {
20
+ _receiveBroadcast: (message: import("./types.js").BeaconBroadcastMessage) => void;
21
+ };
22
+ //# sourceMappingURL=in-process-broker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-process-broker.d.ts","sourceRoot":"","sources":["../../../src/beacon/in-process-broker.js"],"names":[],"mappings":"AAyBA;;;;GAIG;AACH,4CAHW,aAAa,GACX,MAAM,IAAI,CAQtB;AAED;;;;;;GAMG;AACH,iDAHW,OAAO,YAAY,EAAE,sBAAsB,GACzC,IAAI,CAehB;AAED;;GAEG;AACH,yCAFa,MAAM,CAIlB;4BA7Ca;IAAC,iBAAiB,EAAE,CAAC,OAAO,EAAE,OAAO,YAAY,EAAE,sBAAsB,KAAK,IAAI,CAAA;CAAC"}
@@ -0,0 +1,61 @@
1
+ // @ts-check
2
+ /**
3
+ * Module-level broker singleton for in-process Beacon mode.
4
+ *
5
+ * Every `InProcessBeaconClient` registers itself here on `connect()` and
6
+ * unregisters on `close()`. `publish(message)` schedules a microtask
7
+ * fan-out to every registered peer's `_receiveBroadcast(message)`. The
8
+ * microtask boundary keeps "publish, then receive" ordering safe even
9
+ * when the publisher and a subscriber are the same client — without it,
10
+ * a synchronous fan-out could re-enter the caller mid-publish if a
11
+ * broadcast handler synchronously published again.
12
+ *
13
+ * Designed for two scenarios:
14
+ * 1. Tests with multiple `Configuration` instances in one process
15
+ * (no TCP socket setup, deterministic ordering via microtasks).
16
+ * 2. Single-process production deployments that want the same
17
+ * `broadcastToChannel` ergonomics without running the daemon.
18
+ */
19
+ /** @typedef {{_receiveBroadcast: (message: import("./types.js").BeaconBroadcastMessage) => void}} InProcessPeer */
20
+ /** @type {Set<InProcessPeer>} */
21
+ const peers = new Set();
22
+ /**
23
+ * Registers a peer with the broker. Returns an unregister function.
24
+ * @param {InProcessPeer} peer - Peer instance.
25
+ * @returns {() => void} - Unregister function.
26
+ */
27
+ export function registerInProcessPeer(peer) {
28
+ peers.add(peer);
29
+ return () => {
30
+ peers.delete(peer);
31
+ };
32
+ }
33
+ /**
34
+ * Schedules a fan-out of the given message to every registered peer.
35
+ * Each delivery is its own microtask so handlers run in the order peers
36
+ * registered, but never synchronously inside the publish call.
37
+ * @param {import("./types.js").BeaconBroadcastMessage} message - Broadcast message.
38
+ * @returns {void}
39
+ */
40
+ export function publishToInProcessPeers(message) {
41
+ for (const peer of peers) {
42
+ queueMicrotask(() => {
43
+ try {
44
+ peer._receiveBroadcast(message);
45
+ }
46
+ catch (error) {
47
+ // Mirrors the daemon's per-peer fan-out resilience: a thrown
48
+ // handler on one peer must not prevent delivery to others. The
49
+ // caller's framework-error path covers higher-level reporting.
50
+ console.error("In-process Beacon peer threw during broadcast delivery:", error);
51
+ }
52
+ });
53
+ }
54
+ }
55
+ /**
56
+ * @returns {number} - Current peer count. Exposed for diagnostics and tests.
57
+ */
58
+ export function getInProcessPeerCount() {
59
+ return peers.size;
60
+ }
61
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW4tcHJvY2Vzcy1icm9rZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYmVhY29uL2luLXByb2Nlc3MtYnJva2VyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWjs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUVILG1IQUFtSDtBQUVuSCxpQ0FBaUM7QUFDakMsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQTtBQUV2Qjs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLHFCQUFxQixDQUFDLElBQUk7SUFDeEMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUVmLE9BQU8sR0FBRyxFQUFFO1FBQ1YsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUNwQixDQUFDLENBQUE7QUFDSCxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLHVCQUF1QixDQUFDLE9BQU87SUFDN0MsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUN6QixjQUFjLENBQUMsR0FBRyxFQUFFO1lBQ2xCLElBQUksQ0FBQztnQkFDSCxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUE7WUFDakMsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsNkRBQTZEO2dCQUM3RCwrREFBK0Q7Z0JBQy9ELCtEQUErRDtnQkFDL0QsT0FBTyxDQUFDLEtBQUssQ0FBQyx5REFBeUQsRUFBRSxLQUFLLENBQUMsQ0FBQTtZQUNqRixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDO0FBQ0gsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLHFCQUFxQjtJQUNuQyxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUE7QUFDbkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG4vKipcbiAqIE1vZHVsZS1sZXZlbCBicm9rZXIgc2luZ2xldG9uIGZvciBpbi1wcm9jZXNzIEJlYWNvbiBtb2RlLlxuICpcbiAqIEV2ZXJ5IGBJblByb2Nlc3NCZWFjb25DbGllbnRgIHJlZ2lzdGVycyBpdHNlbGYgaGVyZSBvbiBgY29ubmVjdCgpYCBhbmRcbiAqIHVucmVnaXN0ZXJzIG9uIGBjbG9zZSgpYC4gYHB1Ymxpc2gobWVzc2FnZSlgIHNjaGVkdWxlcyBhIG1pY3JvdGFza1xuICogZmFuLW91dCB0byBldmVyeSByZWdpc3RlcmVkIHBlZXIncyBgX3JlY2VpdmVCcm9hZGNhc3QobWVzc2FnZSlgLiBUaGVcbiAqIG1pY3JvdGFzayBib3VuZGFyeSBrZWVwcyBcInB1Ymxpc2gsIHRoZW4gcmVjZWl2ZVwiIG9yZGVyaW5nIHNhZmUgZXZlblxuICogd2hlbiB0aGUgcHVibGlzaGVyIGFuZCBhIHN1YnNjcmliZXIgYXJlIHRoZSBzYW1lIGNsaWVudCDigJQgd2l0aG91dCBpdCxcbiAqIGEgc3luY2hyb25vdXMgZmFuLW91dCBjb3VsZCByZS1lbnRlciB0aGUgY2FsbGVyIG1pZC1wdWJsaXNoIGlmIGFcbiAqIGJyb2FkY2FzdCBoYW5kbGVyIHN5bmNocm9ub3VzbHkgcHVibGlzaGVkIGFnYWluLlxuICpcbiAqIERlc2lnbmVkIGZvciB0d28gc2NlbmFyaW9zOlxuICogICAxLiBUZXN0cyB3aXRoIG11bHRpcGxlIGBDb25maWd1cmF0aW9uYCBpbnN0YW5jZXMgaW4gb25lIHByb2Nlc3NcbiAqICAgICAgKG5vIFRDUCBzb2NrZXQgc2V0dXAsIGRldGVybWluaXN0aWMgb3JkZXJpbmcgdmlhIG1pY3JvdGFza3MpLlxuICogICAyLiBTaW5nbGUtcHJvY2VzcyBwcm9kdWN0aW9uIGRlcGxveW1lbnRzIHRoYXQgd2FudCB0aGUgc2FtZVxuICogICAgICBgYnJvYWRjYXN0VG9DaGFubmVsYCBlcmdvbm9taWNzIHdpdGhvdXQgcnVubmluZyB0aGUgZGFlbW9uLlxuICovXG5cbi8qKiBAdHlwZWRlZiB7e19yZWNlaXZlQnJvYWRjYXN0OiAobWVzc2FnZTogaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5CZWFjb25Ccm9hZGNhc3RNZXNzYWdlKSA9PiB2b2lkfX0gSW5Qcm9jZXNzUGVlciAqL1xuXG4vKiogQHR5cGUge1NldDxJblByb2Nlc3NQZWVyPn0gKi9cbmNvbnN0IHBlZXJzID0gbmV3IFNldCgpXG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgcGVlciB3aXRoIHRoZSBicm9rZXIuIFJldHVybnMgYW4gdW5yZWdpc3RlciBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7SW5Qcm9jZXNzUGVlcn0gcGVlciAtIFBlZXIgaW5zdGFuY2UuXG4gKiBAcmV0dXJucyB7KCkgPT4gdm9pZH0gLSBVbnJlZ2lzdGVyIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJJblByb2Nlc3NQZWVyKHBlZXIpIHtcbiAgcGVlcnMuYWRkKHBlZXIpXG5cbiAgcmV0dXJuICgpID0+IHtcbiAgICBwZWVycy5kZWxldGUocGVlcilcbiAgfVxufVxuXG4vKipcbiAqIFNjaGVkdWxlcyBhIGZhbi1vdXQgb2YgdGhlIGdpdmVuIG1lc3NhZ2UgdG8gZXZlcnkgcmVnaXN0ZXJlZCBwZWVyLlxuICogRWFjaCBkZWxpdmVyeSBpcyBpdHMgb3duIG1pY3JvdGFzayBzbyBoYW5kbGVycyBydW4gaW4gdGhlIG9yZGVyIHBlZXJzXG4gKiByZWdpc3RlcmVkLCBidXQgbmV2ZXIgc3luY2hyb25vdXNseSBpbnNpZGUgdGhlIHB1Ymxpc2ggY2FsbC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5CZWFjb25Ccm9hZGNhc3RNZXNzYWdlfSBtZXNzYWdlIC0gQnJvYWRjYXN0IG1lc3NhZ2UuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHB1Ymxpc2hUb0luUHJvY2Vzc1BlZXJzKG1lc3NhZ2UpIHtcbiAgZm9yIChjb25zdCBwZWVyIG9mIHBlZXJzKSB7XG4gICAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcGVlci5fcmVjZWl2ZUJyb2FkY2FzdChtZXNzYWdlKVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLy8gTWlycm9ycyB0aGUgZGFlbW9uJ3MgcGVyLXBlZXIgZmFuLW91dCByZXNpbGllbmNlOiBhIHRocm93blxuICAgICAgICAvLyBoYW5kbGVyIG9uIG9uZSBwZWVyIG11c3Qgbm90IHByZXZlbnQgZGVsaXZlcnkgdG8gb3RoZXJzLiBUaGVcbiAgICAgICAgLy8gY2FsbGVyJ3MgZnJhbWV3b3JrLWVycm9yIHBhdGggY292ZXJzIGhpZ2hlci1sZXZlbCByZXBvcnRpbmcuXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJJbi1wcm9jZXNzIEJlYWNvbiBwZWVyIHRocmV3IGR1cmluZyBicm9hZGNhc3QgZGVsaXZlcnk6XCIsIGVycm9yKVxuICAgICAgfVxuICAgIH0pXG4gIH1cbn1cblxuLyoqXG4gKiBAcmV0dXJucyB7bnVtYmVyfSAtIEN1cnJlbnQgcGVlciBjb3VudC4gRXhwb3NlZCBmb3IgZGlhZ25vc3RpY3MgYW5kIHRlc3RzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW5Qcm9jZXNzUGVlckNvdW50KCkge1xuICByZXR1cm4gcGVlcnMuc2l6ZVxufVxuIl19
@@ -0,0 +1,74 @@
1
+ declare const InProcessBeaconClient_base: typeof import("eventemitter3").EventEmitter;
2
+ /**
3
+ * @typedef {function(import("./types.js").BeaconBroadcastMessage): void} BeaconBroadcastHandler
4
+ */
5
+ /**
6
+ * In-process counterpart to `BeaconClient`. Registers with the
7
+ * module-level `in-process-broker` singleton so peers in the same
8
+ * process exchange broadcasts without ever touching TCP. Implements the
9
+ * same external surface as `BeaconClient` (`connect`, `publish`,
10
+ * `onBroadcast`, `isConnected`, `getPeerId`, `close`) so
11
+ * `Configuration` can use either client interchangeably.
12
+ *
13
+ * Lifecycle differs from `BeaconClient` in two intentional ways:
14
+ * - `connect()` resolves immediately; there is no broker to wait for.
15
+ * - There is no reconnect loop and no `connect-error` / `disconnect`
16
+ * event surface, because nothing can fail.
17
+ */
18
+ export default class InProcessBeaconClient extends InProcessBeaconClient_base {
19
+ /**
20
+ * @param {object} [args] - Options.
21
+ * @param {string} [args.peerType] - Optional human-readable peer label.
22
+ * @param {string} [args.peerId] - Optional explicit peer id (defaults to a random UUID).
23
+ */
24
+ constructor({ peerType, peerId }?: {
25
+ peerType?: string | undefined;
26
+ peerId?: string | undefined;
27
+ });
28
+ peerType: string | undefined;
29
+ peerId: string;
30
+ _connected: boolean;
31
+ /** @type {(() => void) | undefined} */
32
+ _unregister: (() => void) | undefined;
33
+ /** @returns {string} - Peer id. */
34
+ getPeerId(): string;
35
+ /** @returns {boolean} - Whether the peer is registered with the broker. */
36
+ isConnected(): boolean;
37
+ /**
38
+ * Registers with the in-process broker. Idempotent.
39
+ * @returns {Promise<void>}
40
+ */
41
+ connect(): Promise<void>;
42
+ /**
43
+ * Publishes a broadcast to every registered peer (including this
44
+ * one). Returns false if `connect()` hasn't been called yet, matching
45
+ * `BeaconClient` semantics.
46
+ * @param {object} args - Broadcast args.
47
+ * @param {string} args.channel - Channel name.
48
+ * @param {Record<string, any>} args.broadcastParams - Routing params.
49
+ * @param {any} args.body - Message body.
50
+ * @returns {boolean} - True when the broadcast was queued.
51
+ */
52
+ publish({ channel, broadcastParams, body }: {
53
+ channel: string;
54
+ broadcastParams: Record<string, any>;
55
+ body: any;
56
+ }): boolean;
57
+ /**
58
+ * Registers a handler called once for every broadcast received.
59
+ * @param {BeaconBroadcastHandler} handler - Handler.
60
+ * @returns {() => void} - Unregister function.
61
+ */
62
+ onBroadcast(handler: BeaconBroadcastHandler): () => void;
63
+ /**
64
+ * Receives a broadcast from the broker. Called by `in-process-broker`.
65
+ * @param {import("./types.js").BeaconBroadcastMessage} message - Broadcast message.
66
+ * @returns {void}
67
+ */
68
+ _receiveBroadcast(message: import("./types.js").BeaconBroadcastMessage): void;
69
+ /** @returns {Promise<void>} - Unregisters from the broker. */
70
+ close(): Promise<void>;
71
+ }
72
+ export type BeaconBroadcastHandler = (arg0: import("./types.js").BeaconBroadcastMessage) => void;
73
+ export {};
74
+ //# sourceMappingURL=in-process-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-process-client.d.ts","sourceRoot":"","sources":["../../../src/beacon/in-process-client.js"],"names":[],"mappings":";AAOA;;GAEG;AAEH;;;;;;;;;;;;GAYG;AACH;IACE;;;;OAIG;IACH,mCAHG;QAAsB,QAAQ;QACR,MAAM;KAC9B,EAQA;IALC,6BAAwB;IACxB,eAAoC;IACpC,oBAAuB;IACvB,uCAAuC;IACvC,aADW,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CACP;IAG9B,mCAAmC;IACnC,aADc,MAAM,CACc;IAElC,2EAA2E;IAC3E,eADc,OAAO,CACmB;IAExC;;;OAGG;IACH,WAFa,OAAO,CAAC,IAAI,CAAC,CAQzB;IAED;;;;;;;;;OASG;IACH,4CALG;QAAqB,OAAO,EAApB,MAAM;QACoB,eAAe,EAAzC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;QACT,IAAI,EAAd,GAAG;KACX,GAAU,OAAO,CAiBnB;IAED;;;;OAIG;IACH,qBAHW,sBAAsB,GACpB,MAAM,IAAI,CAKtB;IAED;;;;OAIG;IACH,2BAHW,OAAO,YAAY,EAAE,sBAAsB,GACzC,IAAI,CAIhB;IAED,8DAA8D;IAC9D,SADc,OAAO,CAAC,IAAI,CAAC,CAK1B;CACF;qCArGY,CAAS,IAA2C,EAA3C,OAAO,YAAY,EAAE,sBAAsB,KAAG,IAAI"}
@@ -0,0 +1,99 @@
1
+ // @ts-check
2
+ import { randomUUID } from "node:crypto";
3
+ import EventEmitter from "../utils/event-emitter.js";
4
+ import { publishToInProcessPeers, registerInProcessPeer } from "./in-process-broker.js";
5
+ /**
6
+ * @typedef {function(import("./types.js").BeaconBroadcastMessage): void} BeaconBroadcastHandler
7
+ */
8
+ /**
9
+ * In-process counterpart to `BeaconClient`. Registers with the
10
+ * module-level `in-process-broker` singleton so peers in the same
11
+ * process exchange broadcasts without ever touching TCP. Implements the
12
+ * same external surface as `BeaconClient` (`connect`, `publish`,
13
+ * `onBroadcast`, `isConnected`, `getPeerId`, `close`) so
14
+ * `Configuration` can use either client interchangeably.
15
+ *
16
+ * Lifecycle differs from `BeaconClient` in two intentional ways:
17
+ * - `connect()` resolves immediately; there is no broker to wait for.
18
+ * - There is no reconnect loop and no `connect-error` / `disconnect`
19
+ * event surface, because nothing can fail.
20
+ */
21
+ export default class InProcessBeaconClient extends EventEmitter {
22
+ /**
23
+ * @param {object} [args] - Options.
24
+ * @param {string} [args.peerType] - Optional human-readable peer label.
25
+ * @param {string} [args.peerId] - Optional explicit peer id (defaults to a random UUID).
26
+ */
27
+ constructor({ peerType, peerId } = {}) {
28
+ super();
29
+ this.peerType = peerType;
30
+ this.peerId = peerId || randomUUID();
31
+ this._connected = false;
32
+ /** @type {(() => void) | undefined} */
33
+ this._unregister = undefined;
34
+ }
35
+ /** @returns {string} - Peer id. */
36
+ getPeerId() { return this.peerId; }
37
+ /** @returns {boolean} - Whether the peer is registered with the broker. */
38
+ isConnected() { return this._connected; }
39
+ /**
40
+ * Registers with the in-process broker. Idempotent.
41
+ * @returns {Promise<void>}
42
+ */
43
+ async connect() {
44
+ if (this._connected)
45
+ return;
46
+ this._unregister = registerInProcessPeer(this);
47
+ this._connected = true;
48
+ this.emit("connect");
49
+ }
50
+ /**
51
+ * Publishes a broadcast to every registered peer (including this
52
+ * one). Returns false if `connect()` hasn't been called yet, matching
53
+ * `BeaconClient` semantics.
54
+ * @param {object} args - Broadcast args.
55
+ * @param {string} args.channel - Channel name.
56
+ * @param {Record<string, any>} args.broadcastParams - Routing params.
57
+ * @param {any} args.body - Message body.
58
+ * @returns {boolean} - True when the broadcast was queued.
59
+ */
60
+ publish({ channel, broadcastParams, body }) {
61
+ if (!this._connected)
62
+ return false;
63
+ /** @type {import("./types.js").BeaconBroadcastMessage} */
64
+ const message = {
65
+ type: "broadcast",
66
+ channel,
67
+ broadcastParams,
68
+ body,
69
+ originPeerId: this.peerId
70
+ };
71
+ publishToInProcessPeers(message);
72
+ return true;
73
+ }
74
+ /**
75
+ * Registers a handler called once for every broadcast received.
76
+ * @param {BeaconBroadcastHandler} handler - Handler.
77
+ * @returns {() => void} - Unregister function.
78
+ */
79
+ onBroadcast(handler) {
80
+ this.on("broadcast", handler);
81
+ return () => this.off("broadcast", handler);
82
+ }
83
+ /**
84
+ * Receives a broadcast from the broker. Called by `in-process-broker`.
85
+ * @param {import("./types.js").BeaconBroadcastMessage} message - Broadcast message.
86
+ * @returns {void}
87
+ */
88
+ _receiveBroadcast(message) {
89
+ this.emit("broadcast", message);
90
+ }
91
+ /** @returns {Promise<void>} - Unregisters from the broker. */
92
+ async close() {
93
+ if (this._unregister)
94
+ this._unregister();
95
+ this._unregister = undefined;
96
+ this._connected = false;
97
+ }
98
+ }
99
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW4tcHJvY2Vzcy1jbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYmVhY29uL2luLXByb2Nlc3MtY2xpZW50LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sYUFBYSxDQUFBO0FBRXRDLE9BQU8sWUFBWSxNQUFNLDJCQUEyQixDQUFBO0FBQ3BELE9BQU8sRUFBQyx1QkFBdUIsRUFBRSxxQkFBcUIsRUFBQyxNQUFNLHdCQUF3QixDQUFBO0FBRXJGOztHQUVHO0FBRUg7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsTUFBTSxDQUFDLE9BQU8sT0FBTyxxQkFBc0IsU0FBUSxZQUFZO0lBQzdEOzs7O09BSUc7SUFDSCxZQUFZLEVBQUMsUUFBUSxFQUFFLE1BQU0sRUFBQyxHQUFHLEVBQUU7UUFDakMsS0FBSyxFQUFFLENBQUE7UUFDUCxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQTtRQUN4QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sSUFBSSxVQUFVLEVBQUUsQ0FBQTtRQUNwQyxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQTtRQUN2Qix1Q0FBdUM7UUFDdkMsSUFBSSxDQUFDLFdBQVcsR0FBRyxTQUFTLENBQUE7SUFDOUIsQ0FBQztJQUVELG1DQUFtQztJQUNuQyxTQUFTLEtBQUssT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFBLENBQUMsQ0FBQztJQUVsQywyRUFBMkU7SUFDM0UsV0FBVyxLQUFLLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQSxDQUFDLENBQUM7SUFFeEM7OztPQUdHO0lBQ0gsS0FBSyxDQUFDLE9BQU87UUFDWCxJQUFJLElBQUksQ0FBQyxVQUFVO1lBQUUsT0FBTTtRQUUzQixJQUFJLENBQUMsV0FBVyxHQUFHLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFBO1FBQzlDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFBO1FBQ3RCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUE7SUFDdEIsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNILE9BQU8sQ0FBQyxFQUFDLE9BQU8sRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFDO1FBQ3RDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVTtZQUFFLE9BQU8sS0FBSyxDQUFBO1FBRWxDLDBEQUEwRDtRQUMxRCxNQUFNLE9BQU8sR0FBRztZQUNkLElBQUksRUFBRSxXQUFXO1lBQ2pCLE9BQU87WUFDUCxlQUFlO1lBQ2YsSUFBSTtZQUNKLFlBQVksRUFBRSxJQUFJLENBQUMsTUFBTTtTQUMxQixDQUFBO1FBRUQsdUJBQXVCLENBQUMsT0FBTyxDQUFDLENBQUE7UUFFaEMsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILFdBQVcsQ0FBQyxPQUFPO1FBQ2pCLElBQUksQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFBO1FBQzdCLE9BQU8sR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUE7SUFDN0MsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxpQkFBaUIsQ0FBQyxPQUFPO1FBQ3ZCLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFBO0lBQ2pDLENBQUM7SUFFRCw4REFBOEQ7SUFDOUQsS0FBSyxDQUFDLEtBQUs7UUFDVCxJQUFJLElBQUksQ0FBQyxXQUFXO1lBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFBO1FBQ3hDLElBQUksQ0FBQyxXQUFXLEdBQUcsU0FBUyxDQUFBO1FBQzVCLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFBO0lBQ3pCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQge3JhbmRvbVVVSUR9IGZyb20gXCJub2RlOmNyeXB0b1wiXG5cbmltcG9ydCBFdmVudEVtaXR0ZXIgZnJvbSBcIi4uL3V0aWxzL2V2ZW50LWVtaXR0ZXIuanNcIlxuaW1wb3J0IHtwdWJsaXNoVG9JblByb2Nlc3NQZWVycywgcmVnaXN0ZXJJblByb2Nlc3NQZWVyfSBmcm9tIFwiLi9pbi1wcm9jZXNzLWJyb2tlci5qc1wiXG5cbi8qKlxuICogQHR5cGVkZWYge2Z1bmN0aW9uKGltcG9ydChcIi4vdHlwZXMuanNcIikuQmVhY29uQnJvYWRjYXN0TWVzc2FnZSk6IHZvaWR9IEJlYWNvbkJyb2FkY2FzdEhhbmRsZXJcbiAqL1xuXG4vKipcbiAqIEluLXByb2Nlc3MgY291bnRlcnBhcnQgdG8gYEJlYWNvbkNsaWVudGAuIFJlZ2lzdGVycyB3aXRoIHRoZVxuICogbW9kdWxlLWxldmVsIGBpbi1wcm9jZXNzLWJyb2tlcmAgc2luZ2xldG9uIHNvIHBlZXJzIGluIHRoZSBzYW1lXG4gKiBwcm9jZXNzIGV4Y2hhbmdlIGJyb2FkY2FzdHMgd2l0aG91dCBldmVyIHRvdWNoaW5nIFRDUC4gSW1wbGVtZW50cyB0aGVcbiAqIHNhbWUgZXh0ZXJuYWwgc3VyZmFjZSBhcyBgQmVhY29uQ2xpZW50YCAoYGNvbm5lY3RgLCBgcHVibGlzaGAsXG4gKiBgb25Ccm9hZGNhc3RgLCBgaXNDb25uZWN0ZWRgLCBgZ2V0UGVlcklkYCwgYGNsb3NlYCkgc29cbiAqIGBDb25maWd1cmF0aW9uYCBjYW4gdXNlIGVpdGhlciBjbGllbnQgaW50ZXJjaGFuZ2VhYmx5LlxuICpcbiAqIExpZmVjeWNsZSBkaWZmZXJzIGZyb20gYEJlYWNvbkNsaWVudGAgaW4gdHdvIGludGVudGlvbmFsIHdheXM6XG4gKiAgIC0gYGNvbm5lY3QoKWAgcmVzb2x2ZXMgaW1tZWRpYXRlbHk7IHRoZXJlIGlzIG5vIGJyb2tlciB0byB3YWl0IGZvci5cbiAqICAgLSBUaGVyZSBpcyBubyByZWNvbm5lY3QgbG9vcCBhbmQgbm8gYGNvbm5lY3QtZXJyb3JgIC8gYGRpc2Nvbm5lY3RgXG4gKiAgICAgZXZlbnQgc3VyZmFjZSwgYmVjYXVzZSBub3RoaW5nIGNhbiBmYWlsLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJblByb2Nlc3NCZWFjb25DbGllbnQgZXh0ZW5kcyBFdmVudEVtaXR0ZXIge1xuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IFthcmdzXSAtIE9wdGlvbnMuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYXJncy5wZWVyVHlwZV0gLSBPcHRpb25hbCBodW1hbi1yZWFkYWJsZSBwZWVyIGxhYmVsLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2FyZ3MucGVlcklkXSAtIE9wdGlvbmFsIGV4cGxpY2l0IHBlZXIgaWQgKGRlZmF1bHRzIHRvIGEgcmFuZG9tIFVVSUQpLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe3BlZXJUeXBlLCBwZWVySWR9ID0ge30pIHtcbiAgICBzdXBlcigpXG4gICAgdGhpcy5wZWVyVHlwZSA9IHBlZXJUeXBlXG4gICAgdGhpcy5wZWVySWQgPSBwZWVySWQgfHwgcmFuZG9tVVVJRCgpXG4gICAgdGhpcy5fY29ubmVjdGVkID0gZmFsc2VcbiAgICAvKiogQHR5cGUgeygoKSA9PiB2b2lkKSB8IHVuZGVmaW5lZH0gKi9cbiAgICB0aGlzLl91bnJlZ2lzdGVyID0gdW5kZWZpbmVkXG4gIH1cblxuICAvKiogQHJldHVybnMge3N0cmluZ30gLSBQZWVyIGlkLiAqL1xuICBnZXRQZWVySWQoKSB7IHJldHVybiB0aGlzLnBlZXJJZCB9XG5cbiAgLyoqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdGhlIHBlZXIgaXMgcmVnaXN0ZXJlZCB3aXRoIHRoZSBicm9rZXIuICovXG4gIGlzQ29ubmVjdGVkKCkgeyByZXR1cm4gdGhpcy5fY29ubmVjdGVkIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIHdpdGggdGhlIGluLXByb2Nlc3MgYnJva2VyLiBJZGVtcG90ZW50LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIGNvbm5lY3QoKSB7XG4gICAgaWYgKHRoaXMuX2Nvbm5lY3RlZCkgcmV0dXJuXG5cbiAgICB0aGlzLl91bnJlZ2lzdGVyID0gcmVnaXN0ZXJJblByb2Nlc3NQZWVyKHRoaXMpXG4gICAgdGhpcy5fY29ubmVjdGVkID0gdHJ1ZVxuICAgIHRoaXMuZW1pdChcImNvbm5lY3RcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaXNoZXMgYSBicm9hZGNhc3QgdG8gZXZlcnkgcmVnaXN0ZXJlZCBwZWVyIChpbmNsdWRpbmcgdGhpc1xuICAgKiBvbmUpLiBSZXR1cm5zIGZhbHNlIGlmIGBjb25uZWN0KClgIGhhc24ndCBiZWVuIGNhbGxlZCB5ZXQsIG1hdGNoaW5nXG4gICAqIGBCZWFjb25DbGllbnRgIHNlbWFudGljcy5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBCcm9hZGNhc3QgYXJncy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuY2hhbm5lbCAtIENoYW5uZWwgbmFtZS5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBhcmdzLmJyb2FkY2FzdFBhcmFtcyAtIFJvdXRpbmcgcGFyYW1zLlxuICAgKiBAcGFyYW0ge2FueX0gYXJncy5ib2R5IC0gTWVzc2FnZSBib2R5LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBUcnVlIHdoZW4gdGhlIGJyb2FkY2FzdCB3YXMgcXVldWVkLlxuICAgKi9cbiAgcHVibGlzaCh7Y2hhbm5lbCwgYnJvYWRjYXN0UGFyYW1zLCBib2R5fSkge1xuICAgIGlmICghdGhpcy5fY29ubmVjdGVkKSByZXR1cm4gZmFsc2VcblxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5CZWFjb25Ccm9hZGNhc3RNZXNzYWdlfSAqL1xuICAgIGNvbnN0IG1lc3NhZ2UgPSB7XG4gICAgICB0eXBlOiBcImJyb2FkY2FzdFwiLFxuICAgICAgY2hhbm5lbCxcbiAgICAgIGJyb2FkY2FzdFBhcmFtcyxcbiAgICAgIGJvZHksXG4gICAgICBvcmlnaW5QZWVySWQ6IHRoaXMucGVlcklkXG4gICAgfVxuXG4gICAgcHVibGlzaFRvSW5Qcm9jZXNzUGVlcnMobWVzc2FnZSlcblxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGEgaGFuZGxlciBjYWxsZWQgb25jZSBmb3IgZXZlcnkgYnJvYWRjYXN0IHJlY2VpdmVkLlxuICAgKiBAcGFyYW0ge0JlYWNvbkJyb2FkY2FzdEhhbmRsZXJ9IGhhbmRsZXIgLSBIYW5kbGVyLlxuICAgKiBAcmV0dXJucyB7KCkgPT4gdm9pZH0gLSBVbnJlZ2lzdGVyIGZ1bmN0aW9uLlxuICAgKi9cbiAgb25Ccm9hZGNhc3QoaGFuZGxlcikge1xuICAgIHRoaXMub24oXCJicm9hZGNhc3RcIiwgaGFuZGxlcilcbiAgICByZXR1cm4gKCkgPT4gdGhpcy5vZmYoXCJicm9hZGNhc3RcIiwgaGFuZGxlcilcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNlaXZlcyBhIGJyb2FkY2FzdCBmcm9tIHRoZSBicm9rZXIuIENhbGxlZCBieSBgaW4tcHJvY2Vzcy1icm9rZXJgLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuQmVhY29uQnJvYWRjYXN0TWVzc2FnZX0gbWVzc2FnZSAtIEJyb2FkY2FzdCBtZXNzYWdlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIF9yZWNlaXZlQnJvYWRjYXN0KG1lc3NhZ2UpIHtcbiAgICB0aGlzLmVtaXQoXCJicm9hZGNhc3RcIiwgbWVzc2FnZSlcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBVbnJlZ2lzdGVycyBmcm9tIHRoZSBicm9rZXIuICovXG4gIGFzeW5jIGNsb3NlKCkge1xuICAgIGlmICh0aGlzLl91bnJlZ2lzdGVyKSB0aGlzLl91bnJlZ2lzdGVyKClcbiAgICB0aGlzLl91bnJlZ2lzdGVyID0gdW5kZWZpbmVkXG4gICAgdGhpcy5fY29ubmVjdGVkID0gZmFsc2VcbiAgfVxufVxuIl19
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Beacon broker daemon.
3
+ *
4
+ * Accepts JsonSocket connections from any number of peer processes and
5
+ * fans every `broadcast` message out to every connected peer.
6
+ * Intentionally stateless — there is no persistence, no replay, no
7
+ * channel-name filtering on the daemon. Per-process subscription
8
+ * matching (already implemented by `_broadcastToChannelLocal`) does the
9
+ * filtering.
10
+ */
11
+ export default class BeaconServer {
12
+ /**
13
+ * @param {object} args - Options.
14
+ * @param {import("../configuration.js").default} args.configuration - Configuration.
15
+ * @param {string} [args.host] - Hostname to bind. Defaults to the configured beacon host.
16
+ * @param {number} [args.port] - Port to bind. Defaults to the configured beacon port.
17
+ */
18
+ constructor({ configuration, host, port }: {
19
+ configuration: import("../configuration.js").default;
20
+ host?: string | undefined;
21
+ port?: number | undefined;
22
+ });
23
+ configuration: import("../configuration.js").default;
24
+ host: string;
25
+ port: number;
26
+ logger: Logger;
27
+ /** @type {Set<JsonSocket>} */
28
+ peers: Set<JsonSocket>;
29
+ /** @type {net.Server | undefined} */
30
+ server: net.Server | undefined;
31
+ /**
32
+ * @returns {Promise<void>} - Resolves when listening.
33
+ */
34
+ start(): Promise<void>;
35
+ /**
36
+ * @returns {Promise<void>} - Resolves when closed.
37
+ */
38
+ stop(): Promise<void>;
39
+ /**
40
+ * @returns {number} - Bound port.
41
+ */
42
+ getPort(): number;
43
+ /**
44
+ * @returns {number} - Number of connected peers.
45
+ */
46
+ getPeerCount(): number;
47
+ /**
48
+ * @param {import("net").Socket} socket - Socket.
49
+ * @returns {void}
50
+ */
51
+ _handleConnection(socket: import("net").Socket): void;
52
+ /**
53
+ * @param {import("./types.js").BeaconBroadcastMessage} message - Broadcast message.
54
+ * @returns {void}
55
+ */
56
+ _fanOut(message: import("./types.js").BeaconBroadcastMessage): void;
57
+ }
58
+ import Logger from "../logger.js";
59
+ import JsonSocket from "../background-jobs/json-socket.js";
60
+ import net from "net";
61
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/beacon/server.js"],"names":[],"mappings":"AAOA;;;;;;;;;GASG;AACH;IACE;;;;;OAKG;IACH,2CAJG;QAAoD,aAAa,EAAzD,OAAO,qBAAqB,EAAE,OAAO;QACvB,IAAI;QACJ,IAAI;KAC5B,EAWA;IATC,qDAAkC;IAElC,aAA+B;IAC/B,aAAyD;IACzD,eAA8B;IAC9B,8BAA8B;IAC9B,OADW,GAAG,CAAC,UAAU,CAAC,CACJ;IACtB,qCAAqC;IACrC,QADW,GAAG,CAAC,MAAM,GAAG,SAAS,CACV;IAGzB;;OAEG;IACH,SAFa,OAAO,CAAC,IAAI,CAAC,CAgBzB;IAED;;OAEG;IACH,QAFa,OAAO,CAAC,IAAI,CAAC,CAYzB;IAED;;OAEG;IACH,WAFa,MAAM,CAIlB;IAED;;OAEG;IACH,gBAFa,MAAM,CAIlB;IAED;;;OAGG;IACH,0BAHW,OAAO,KAAK,EAAE,MAAM,GAClB,IAAI,CA6BhB;IAED;;;OAGG;IACH,iBAHW,OAAO,YAAY,EAAE,sBAAsB,GACzC,IAAI,CAUhB;CACF;mBA7HkB,cAAc;uBADV,mCAAmC;gBAF1C,KAAK"}