@hediet/linkrpc-hub 0.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/README.md +101 -0
- package/dist/chunks/config-BCvkg7jv.d.ts +566 -0
- package/dist/chunks/configFile-y6Phntqu.d.ts +9 -0
- package/dist/chunks/connectionTokenBinder.interfaces-B-beCg06.js +40 -0
- package/dist/chunks/connectionTokenBinder.interfaces-B-beCg06.js.map +1 -0
- package/dist/chunks/connectionTokenBinder.interfaces-BhzQ1DTS.d.ts +36 -0
- package/dist/chunks/hubConnectionAcceptor-B5-8JsFY.js +2768 -0
- package/dist/chunks/hubConnectionAcceptor-B5-8JsFY.js.map +1 -0
- package/dist/chunks/hubConnectionAcceptor-BwydvFa4.d.ts +1560 -0
- package/dist/chunks/index-CLIUrV88.d.ts +481 -0
- package/dist/chunks/node-CTXsQ6oa.js +460 -0
- package/dist/chunks/node-CTXsQ6oa.js.map +1 -0
- package/dist/chunks/nodeTransit-CWeFnbwt.js +444 -0
- package/dist/chunks/nodeTransit-CWeFnbwt.js.map +1 -0
- package/dist/chunks/nodeTransit-cmtZgdpW.d.ts +226 -0
- package/dist/chunks/runHub-P3YUwwdv.js +1797 -0
- package/dist/chunks/runHub-P3YUwwdv.js.map +1 -0
- package/dist/chunks/server-BAxchQhy.js +1368 -0
- package/dist/chunks/server-BAxchQhy.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +38 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.js +305 -0
- package/dist/config.js.map +1 -0
- package/dist/configFile.d.ts +2 -0
- package/dist/configFile.js +27 -0
- package/dist/configFile.js.map +1 -0
- package/dist/engine/runHub.d.ts +42 -0
- package/dist/engine/runHub.js +2 -0
- package/dist/hub/server/client.d.ts +2 -0
- package/dist/hub/server/client.js +2 -0
- package/dist/hub/server/connectionTokenBinder.d.ts +2 -0
- package/dist/hub/server/connectionTokenBinder.js +2 -0
- package/dist/hub/server/index.d.ts +5 -0
- package/dist/hub/server/index.js +5 -0
- package/dist/hub/server/node/index.d.ts +218 -0
- package/dist/hub/server/node/index.js +2 -0
- package/dist/hub/server/transit.d.ts +2 -0
- package/dist/hub/server/transit.js +2 -0
- package/dist/index.d.ts +512 -0
- package/dist/index.js +309 -0
- package/dist/index.js.map +1 -0
- package/dist/serve.d.ts +14 -0
- package/dist/serve.js +31 -0
- package/dist/serve.js.map +1 -0
- package/dist/spawn.d.ts +12 -0
- package/dist/spawn.js +25 -0
- package/dist/spawn.js.map +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { IMessageTransport, JsonValue, RequestId } from "@hediet/linkrpc";
|
|
2
|
+
import { TrafficTransitEvent } from "@hediet/linkrpc/inspection";
|
|
3
|
+
//#region src/hub/server/nodeTransit.d.ts
|
|
4
|
+
/** What kind of message crossed the node. Cancel/ping/pong are stream controls. */
|
|
5
|
+
type TransitKind = 'request' | 'notification' | 'response' | 'stream';
|
|
6
|
+
/** What the node did with the message. */
|
|
7
|
+
type TransitDisposition = 'forwarded' | 'consumed' | 'dropped' | 'unroutable';
|
|
8
|
+
/** One side of a transit: the edge, plus the request id as it appears there. */
|
|
9
|
+
interface TransitEndpoint {
|
|
10
|
+
readonly edgeId: string;
|
|
11
|
+
/** Stable topology port id. Older/custom emitters may omit it. */
|
|
12
|
+
readonly portId?: string;
|
|
13
|
+
/** JSON-RPC request id on this edge. Absent for notifications. */
|
|
14
|
+
readonly requestId?: RequestId;
|
|
15
|
+
}
|
|
16
|
+
/** Wire-shaped error mirrored onto a `response` transit. */
|
|
17
|
+
interface TransitError {
|
|
18
|
+
readonly code: number;
|
|
19
|
+
readonly message: string;
|
|
20
|
+
readonly data?: JsonValue;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A single message passing through a node. `in` absent ⇒ the message
|
|
24
|
+
* originated here; `out` absent ⇒ it was consumed or dropped here.
|
|
25
|
+
*/
|
|
26
|
+
interface NodeTransit {
|
|
27
|
+
readonly timeMs: number;
|
|
28
|
+
readonly nodeId: string;
|
|
29
|
+
readonly in?: TransitEndpoint;
|
|
30
|
+
readonly out?: TransitEndpoint;
|
|
31
|
+
readonly disposition: TransitDisposition;
|
|
32
|
+
readonly kind: TransitKind;
|
|
33
|
+
readonly method?: string;
|
|
34
|
+
readonly params?: JsonValue;
|
|
35
|
+
readonly result?: JsonValue;
|
|
36
|
+
readonly error?: TransitError;
|
|
37
|
+
}
|
|
38
|
+
/** Sink for node transits. Synchronous; keep it cheap. */
|
|
39
|
+
type NodeTransitObserver = (transit: NodeTransit) => void;
|
|
40
|
+
/** Status of a coalesced flow at the moment it is reported. */
|
|
41
|
+
type FlowStatus = 'completed' | 'failed' | 'pending' | 'dropped' | 'unroutable';
|
|
42
|
+
/** One stream frame (`$stream::send`) attached to a flow, in arrival order. */
|
|
43
|
+
interface FlowStreamMessage {
|
|
44
|
+
readonly timeMs: number;
|
|
45
|
+
/** `toCaller` = callee→caller (progress); `toCallee` = caller→callee (input/cancel). */
|
|
46
|
+
readonly dir: 'toCaller' | 'toCallee';
|
|
47
|
+
/** Reserved control verb (`cancel`/`ping`/`pong`), if this is a control frame. */
|
|
48
|
+
readonly control?: string;
|
|
49
|
+
/** App stream payload (typed per call by the originating method's stream schema). */
|
|
50
|
+
readonly payload?: JsonValue;
|
|
51
|
+
}
|
|
52
|
+
/** A coalesced logical operation, reported once (or twice: partial → final). */
|
|
53
|
+
interface FlowSummary {
|
|
54
|
+
readonly id: string;
|
|
55
|
+
readonly kind: TransitKind;
|
|
56
|
+
readonly method: string | undefined;
|
|
57
|
+
readonly params: JsonValue | undefined;
|
|
58
|
+
readonly status: FlowStatus;
|
|
59
|
+
readonly result?: JsonValue;
|
|
60
|
+
readonly error?: TransitError;
|
|
61
|
+
readonly startTs: number;
|
|
62
|
+
readonly endTs: number | undefined;
|
|
63
|
+
readonly durationMs: number;
|
|
64
|
+
/** Ordered, interleaved edge/node labels the message traversed. */
|
|
65
|
+
readonly path: readonly string[];
|
|
66
|
+
/** True when reported while still in flight (slow / stuck). */
|
|
67
|
+
readonly partial: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Stream frames (`$stream::send`) seen on this flow, in arrival order. Only
|
|
70
|
+
* populated when the hub is configured to emit stream transits (debug+); an
|
|
71
|
+
* absent/empty array means "not captured", not "no streaming happened".
|
|
72
|
+
*/
|
|
73
|
+
readonly stream?: readonly FlowStreamMessage[];
|
|
74
|
+
}
|
|
75
|
+
interface TransitAggregatorOptions {
|
|
76
|
+
/** Called once a flow settles, or once when it is first reported partial. */
|
|
77
|
+
readonly onFlow: (summary: FlowSummary) => void;
|
|
78
|
+
/** Quiet-period before a flow is flushed. Default 50ms. */
|
|
79
|
+
readonly flushDelayMs?: number;
|
|
80
|
+
/** Drop an unsettled flow after this long (leak guard). Default 5min. */
|
|
81
|
+
readonly giveUpMs?: number;
|
|
82
|
+
/**
|
|
83
|
+
* How long after a request starts its stream frames stay attached to that
|
|
84
|
+
* request's flow. Frames within this window fold into the request summary;
|
|
85
|
+
* later frames are logged independently (live), so a long-running request's
|
|
86
|
+
* stream output is visible promptly and doesn't accumulate unbounded in the
|
|
87
|
+
* pending flow. Default 1000ms.
|
|
88
|
+
*/
|
|
89
|
+
readonly streamRetainMs?: number;
|
|
90
|
+
/** Map an edgeId to a friendly label for {@link FlowSummary.path}. */
|
|
91
|
+
readonly labelOf?: (edgeId: string) => string | undefined;
|
|
92
|
+
/** Injected clock (tests). Default {@link Date.now}. */
|
|
93
|
+
readonly now?: () => number;
|
|
94
|
+
/** Injected timer (tests). Default {@link setTimeout}. */
|
|
95
|
+
readonly setTimer?: (cb: () => void, ms: number) => unknown;
|
|
96
|
+
/** Injected timer clear (tests). Default {@link clearTimeout}. */
|
|
97
|
+
readonly clearTimer?: (handle: unknown) => void;
|
|
98
|
+
/** Hash params for the notification-correlation heuristic. Default JSON. */
|
|
99
|
+
readonly hashParams?: (params: JsonValue | undefined) => string;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Coalesces {@link NodeTransit}s into per-operation {@link FlowSummary}s and
|
|
103
|
+
* reports each after a short quiet period. A fast request is reported **once**
|
|
104
|
+
* (path + params + response); a slow/stuck one is reported **partial** while
|
|
105
|
+
* in flight and again on completion.
|
|
106
|
+
*
|
|
107
|
+
* Correlation:
|
|
108
|
+
* - request ↔ response and adjacent-node hops join by shared
|
|
109
|
+
* `(edgeId, requestId)` endpoints;
|
|
110
|
+
* - **notifications** (no request id) join heuristically by
|
|
111
|
+
* `(edgeId, method, paramsHash)` — same edge + method + params ⇒ same message.
|
|
112
|
+
*/
|
|
113
|
+
declare class TransitAggregator {
|
|
114
|
+
private readonly _options;
|
|
115
|
+
private readonly _flushDelayMs;
|
|
116
|
+
private readonly _giveUpMs;
|
|
117
|
+
private readonly _streamRetainMs;
|
|
118
|
+
private readonly _now;
|
|
119
|
+
private readonly _setTimer;
|
|
120
|
+
private readonly _clearTimer;
|
|
121
|
+
private readonly _hashParams;
|
|
122
|
+
private readonly _labelOf;
|
|
123
|
+
private readonly _flows;
|
|
124
|
+
private readonly _endpointToFlow;
|
|
125
|
+
private _nextId;
|
|
126
|
+
constructor(_options: TransitAggregatorOptions);
|
|
127
|
+
add(transit: NodeTransit): void;
|
|
128
|
+
/** Drop all pending flows and timers. Does not emit. */
|
|
129
|
+
dispose(): void;
|
|
130
|
+
/** Emit pending flows as partial summaries before a diagnostic capture ends. */
|
|
131
|
+
flush(): void;
|
|
132
|
+
/** First flow registered under any of `keys`, if any (no merge/create). */
|
|
133
|
+
private _findFlow;
|
|
134
|
+
/**
|
|
135
|
+
* Report a single stream frame as its own one-line flow, correlated to its
|
|
136
|
+
* owning request by method + path (the request itself is reported separately
|
|
137
|
+
* when it settles). Used for frames that arrive after {@link _streamRetainMs}
|
|
138
|
+
* so they surface live instead of waiting on a slow request to finish.
|
|
139
|
+
*/
|
|
140
|
+
private _emitStandaloneStream;
|
|
141
|
+
/** Path for a lone stream transit (in → node → out), with labels applied. */
|
|
142
|
+
private _buildStreamPath;
|
|
143
|
+
private _endpointKeys;
|
|
144
|
+
private _merge;
|
|
145
|
+
private _armFlush;
|
|
146
|
+
private _flush;
|
|
147
|
+
private _giveUp;
|
|
148
|
+
private _delete;
|
|
149
|
+
private _summarize;
|
|
150
|
+
private _buildPath;
|
|
151
|
+
private _label;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Presentation adapter that coalesces the public traffic stream into legacy
|
|
155
|
+
* {@link FlowSummary} values. Routing and endpoint observation stay entirely
|
|
156
|
+
* behind the inspection interfaces; consumers only provide formatting/UI.
|
|
157
|
+
*/
|
|
158
|
+
declare class TrafficFlowAggregator {
|
|
159
|
+
private readonly _portLabels;
|
|
160
|
+
private readonly _aggregator;
|
|
161
|
+
constructor(options: TransitAggregatorOptions);
|
|
162
|
+
add(transit: TrafficTransitEvent): void;
|
|
163
|
+
setPortLabel(portId: string, label: string): void;
|
|
164
|
+
flush(): void;
|
|
165
|
+
dispose(): void;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Render a {@link FlowSummary} as a single, human-readable log line. Payloads
|
|
169
|
+
* are JSON-stringified and truncated. Intended for a VS Code output channel.
|
|
170
|
+
*/
|
|
171
|
+
declare function formatFlowSummary(s: FlowSummary, maxPayload?: number): string;
|
|
172
|
+
interface FlowLoggerOptions {
|
|
173
|
+
/** Sink for the formatted, one-line-per-flow output. */
|
|
174
|
+
readonly log: (line: string) => void;
|
|
175
|
+
/**
|
|
176
|
+
* Max JSON length per payload before truncation. Default 200; pass
|
|
177
|
+
* {@link Number.POSITIVE_INFINITY} for full, untruncated payloads.
|
|
178
|
+
*/
|
|
179
|
+
readonly maxPayload?: number;
|
|
180
|
+
/** Quiet-period before a flow is flushed. Default 50ms. */
|
|
181
|
+
readonly flushDelayMs?: number;
|
|
182
|
+
/** Drop an unsettled flow after this long (leak guard). Default 5min. */
|
|
183
|
+
readonly giveUpMs?: number;
|
|
184
|
+
/** Map an edgeId to a friendly label for the rendered path. */
|
|
185
|
+
readonly labelOf?: (edgeId: string) => string | undefined;
|
|
186
|
+
}
|
|
187
|
+
/** A ready-to-attach flow logger: an {@link NodeTransitObserver} + teardown. */
|
|
188
|
+
interface FlowLogger {
|
|
189
|
+
/** Wire this as a hub / overlay `onTransit` observer. */
|
|
190
|
+
readonly onTransit: NodeTransitObserver;
|
|
191
|
+
/** Flush nothing; just clear pending timers. */
|
|
192
|
+
dispose(): void;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Wire a {@link TransitAggregator} to a line sink: each settled (or partial)
|
|
196
|
+
* flow is rendered with {@link formatFlowSummary} and handed to `log`. This is
|
|
197
|
+
* the shared engine behind both the VS Code "linkrpc Flows" output channel and
|
|
198
|
+
* the CLI's `--log-messages` flag.
|
|
199
|
+
*/
|
|
200
|
+
declare function createFlowLogger(opts: FlowLoggerOptions): FlowLogger;
|
|
201
|
+
interface WireTapOptions {
|
|
202
|
+
/** Sink for the formatted, one-line-per-flow output. */
|
|
203
|
+
readonly log: (line: string) => void;
|
|
204
|
+
/** Max JSON length per payload before truncation. Default 200. */
|
|
205
|
+
readonly maxPayload?: number;
|
|
206
|
+
/** Edge label for the near end (the tapping side). Default `"local"`. */
|
|
207
|
+
readonly localLabel?: string;
|
|
208
|
+
/** Edge label for the far end (the peer). Default `"peer"`. */
|
|
209
|
+
readonly remoteLabel?: string;
|
|
210
|
+
/** Synthetic node id for the tap point. Default = {@link localLabel}. */
|
|
211
|
+
readonly nodeId?: string;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Wrap an {@link IMessageTransport} so every JSON-RPC message crossing it — in
|
|
215
|
+
* both directions — is rendered to a line sink, exactly like {@link Hub} traffic.
|
|
216
|
+
*
|
|
217
|
+
* No hub is involved: the tap point is modelled as a single node with two edges
|
|
218
|
+
* (`local`, `peer`). Each outbound message is a transit `local → peer`, each
|
|
219
|
+
* inbound one `peer → local`; requests and their responses still pair by their
|
|
220
|
+
* shared `(peer-edge, requestId)`, so the rendered flows match the hub view.
|
|
221
|
+
* Use this to inspect a *direct* connection that never touches a local hub.
|
|
222
|
+
*/
|
|
223
|
+
declare function tapTransport(inner: IMessageTransport, opts: WireTapOptions): IMessageTransport;
|
|
224
|
+
//#endregion
|
|
225
|
+
export { formatFlowSummary as _, FlowSummary as a, TrafficFlowAggregator as c, TransitDisposition as d, TransitEndpoint as f, createFlowLogger as g, WireTapOptions as h, FlowStreamMessage as i, TransitAggregator as l, TransitKind as m, FlowLoggerOptions as n, NodeTransit as o, TransitError as p, FlowStatus as r, NodeTransitObserver as s, FlowLogger as t, TransitAggregatorOptions as u, tapTransport as v };
|
|
226
|
+
//# sourceMappingURL=nodeTransit-cmtZgdpW.d.ts.map
|