c8ctl-plugin-nano 1.51.0 → 1.53.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/agentic-endpoint.mjs +27 -4
- package/c8ctl-plugin.js +317 -649
- package/package.json +10 -9
- package/supervisor.dist.js +2 -2
- package/work-relay.mjs +147 -0
package/agentic-endpoint.mjs
CHANGED
|
@@ -108,10 +108,18 @@ function negotiatedSupport(remoteAdvertisement) {
|
|
|
108
108
|
* producer fences its stale predecessor on the hub's incarnation ring)
|
|
109
109
|
* @param {{ claimRelease: boolean, steer: boolean }} params.support negotiated capabilities
|
|
110
110
|
* @param {{ warn?: Function, debug?: Function }} [params.logger]
|
|
111
|
+
* @param {(state: 'connected' | 'disconnected') => void} [params.onConnectionState]
|
|
112
|
+
* optional observer invoked on connection-state transitions: `'connected'`
|
|
113
|
+
* once the transport opens and `'disconnected'` when it drops (fired at most
|
|
114
|
+
* once per drop). A throwing observer is caught and logged, never propagated.
|
|
111
115
|
* @returns {import('./supervisor.dist.js').RawEmitClient}
|
|
112
116
|
*/
|
|
113
|
-
function openHostConnection({ url, transportFactory, incarnation, support, logger }) {
|
|
117
|
+
function openHostConnection({ url, transportFactory, incarnation, support, logger, onConnectionState }) {
|
|
114
118
|
const log = logger || {};
|
|
119
|
+
const notifyState = (state) => {
|
|
120
|
+
if (typeof onConnectionState !== 'function') return;
|
|
121
|
+
try { onConnectionState(state); } catch (err) { log.debug?.(`agentic onConnectionState threw — ${err?.message || err}`); }
|
|
122
|
+
};
|
|
115
123
|
const openCbs = [];
|
|
116
124
|
const closeCbs = [];
|
|
117
125
|
let steerRoute = null;
|
|
@@ -139,7 +147,13 @@ function openHostConnection({ url, transportFactory, incarnation, support, logge
|
|
|
139
147
|
closedFired = true;
|
|
140
148
|
open = false;
|
|
141
149
|
hasClosed = true;
|
|
142
|
-
|
|
150
|
+
// Guard each subscriber: a throwing onClose callback must not abort the loop
|
|
151
|
+
// or prevent notifyState('disconnected') from firing (which would strand the
|
|
152
|
+
// connection-state observer and could crash the worker/supervisor on a drop).
|
|
153
|
+
for (const cb of closeCbs) {
|
|
154
|
+
try { cb(); } catch (err) { log.debug?.(`agentic onClose subscriber threw — ${err?.message || err}`); }
|
|
155
|
+
}
|
|
156
|
+
notifyState('disconnected');
|
|
143
157
|
};
|
|
144
158
|
|
|
145
159
|
const send = (lane, family, payload) => {
|
|
@@ -186,7 +200,12 @@ function openHostConnection({ url, transportFactory, incarnation, support, logge
|
|
|
186
200
|
transport = transportFactory(url, {
|
|
187
201
|
onOpen() {
|
|
188
202
|
open = true;
|
|
189
|
-
|
|
203
|
+
// Guard each subscriber: a throwing onOpen callback must not abort the loop
|
|
204
|
+
// or prevent notifyState('connected') from firing.
|
|
205
|
+
for (const cb of openCbs) {
|
|
206
|
+
try { cb(); } catch (err) { log.debug?.(`agentic onOpen subscriber threw — ${err?.message || err}`); }
|
|
207
|
+
}
|
|
208
|
+
notifyState('connected');
|
|
190
209
|
},
|
|
191
210
|
onFrame(bytes) {
|
|
192
211
|
handleInbound(bytes);
|
|
@@ -293,11 +312,14 @@ function openHostConnection({ url, transportFactory, incarnation, support, logge
|
|
|
293
312
|
* the peer's advertised support; omit to assume full support (see {@link negotiatedSupport})
|
|
294
313
|
* @param {number} [opts.incarnationBase] first transcript incarnation (default `Date.now()`)
|
|
295
314
|
* @param {import('@nanobpm/urban-agent-client').TransportFactory} [opts.transportFactory] injectable transport (tests)
|
|
315
|
+
* @param {(state: 'connected'|'disconnected') => void} [opts.onConnectionState] observer fired
|
|
316
|
+
* when a connection opens/drops, so a caller can track the single host connection's
|
|
317
|
+
* liveness (e.g. the supervisor activity marker's agentic status)
|
|
296
318
|
* @param {{ warn?: Function, debug?: Function }} [opts.logger]
|
|
297
319
|
* @returns {Promise<() => import('./supervisor.dist.js').RawEmitClient>} a synchronous `connect` factory
|
|
298
320
|
*/
|
|
299
321
|
export async function createRawEmitConnect(opts) {
|
|
300
|
-
const { url, token, credential, remoteAdvertisement, incarnationBase, transportFactory, logger } = opts || {};
|
|
322
|
+
const { url, token, credential, remoteAdvertisement, incarnationBase, transportFactory, logger, onConnectionState } = opts || {};
|
|
301
323
|
if (typeof url !== 'string' || url.trim() === '') {
|
|
302
324
|
throw new Error('createRawEmitConnect requires an agentic channel base url');
|
|
303
325
|
}
|
|
@@ -318,6 +340,7 @@ export async function createRawEmitConnect(opts) {
|
|
|
318
340
|
incarnation: generation++,
|
|
319
341
|
support,
|
|
320
342
|
logger,
|
|
343
|
+
onConnectionState,
|
|
321
344
|
});
|
|
322
345
|
}
|
|
323
346
|
|