@source-repo/rpc-cli 3.0.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/LICENSE +21 -0
- package/README.md +1131 -0
- package/dist/bench.d.ts +66 -0
- package/dist/bench.d.ts.map +1 -0
- package/dist/bench.js +109 -0
- package/dist/bench.js.map +1 -0
- package/dist/broker.d.ts +61 -0
- package/dist/broker.d.ts.map +1 -0
- package/dist/broker.js +56 -0
- package/dist/broker.js.map +1 -0
- package/dist/bus.d.ts +142 -0
- package/dist/bus.d.ts.map +1 -0
- package/dist/bus.js +272 -0
- package/dist/bus.js.map +1 -0
- package/dist/bus.types.json +269 -0
- package/dist/conform.d.ts +75 -0
- package/dist/conform.d.ts.map +1 -0
- package/dist/conform.js +152 -0
- package/dist/conform.js.map +1 -0
- package/dist/console.d.ts +285 -0
- package/dist/console.d.ts.map +1 -0
- package/dist/console.js +686 -0
- package/dist/console.js.map +1 -0
- package/dist/console.types.json +1730 -0
- package/dist/extract.d.ts +37 -0
- package/dist/extract.d.ts.map +1 -0
- package/dist/extract.js +272 -0
- package/dist/extract.js.map +1 -0
- package/dist/fake.d.ts +58 -0
- package/dist/fake.d.ts.map +1 -0
- package/dist/fake.js +164 -0
- package/dist/fake.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +905 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp.d.ts +15 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +507 -0
- package/dist/mcp.js.map +1 -0
- package/dist/network.d.ts +58 -0
- package/dist/network.d.ts.map +1 -0
- package/dist/network.js +64 -0
- package/dist/network.js.map +1 -0
- package/dist/record.d.ts +74 -0
- package/dist/record.d.ts.map +1 -0
- package/dist/record.js +221 -0
- package/dist/record.js.map +1 -0
- package/dist/tapping.d.ts +11 -0
- package/dist/tapping.d.ts.map +1 -0
- package/dist/tapping.js +71 -0
- package/dist/tapping.js.map +1 -0
- package/dist/verbs.d.ts +59 -0
- package/dist/verbs.d.ts.map +1 -0
- package/dist/verbs.js +324 -0
- package/dist/verbs.js.map +1 -0
- package/dist/web/app.css +1 -0
- package/dist/web/app.js +2063 -0
- package/dist/web/app.js.map +1 -0
- package/dist/web/index.html +13 -0
- package/package.json +65 -0
package/dist/mcp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { RpcServer, type MessageSigner, type MessageVerifier, type Transport } from '@source-repo/rpc';
|
|
2
|
+
/**
|
|
3
|
+
* Joining a network the way every command here joins one: an MQTT broker, a socket.io hub, or both.
|
|
4
|
+
*
|
|
5
|
+
* The three commands that do this - console, mcp and the one-shot verbs - had the same twenty lines
|
|
6
|
+
* of transport construction each, which is three places to forget `prefix` in. The console still
|
|
7
|
+
* builds its own server, because it prepends the socket.io transport that serves the browser, so it
|
|
8
|
+
* takes the transports and keeps the server; the others take both.
|
|
9
|
+
*/
|
|
10
|
+
export interface NetworkOptions {
|
|
11
|
+
/** Watch an MQTT network. Either this or `hub`, or both. */
|
|
12
|
+
broker?: string;
|
|
13
|
+
/** Watch a socket.io network by connecting to a hub. */
|
|
14
|
+
hub?: string;
|
|
15
|
+
/** MQTT topic namespace. A hub has none, so this does nothing for `hub` alone. */
|
|
16
|
+
prefix?: string;
|
|
17
|
+
name: string;
|
|
18
|
+
callTimeout: number;
|
|
19
|
+
/** Sign outgoing frames, so a server configured with `verify` accepts them. */
|
|
20
|
+
sign?: MessageSigner;
|
|
21
|
+
/** Require and check signatures on incoming frames. Optional even when signing. */
|
|
22
|
+
verify?: MessageVerifier;
|
|
23
|
+
/** Handshake credentials for a hub that authenticates. No flag: a secret does not belong in `ps`. */
|
|
24
|
+
hubCredentials?: unknown;
|
|
25
|
+
/**
|
|
26
|
+
* Talk to an `https://`, `wss://` or `mqtts://` peer without checking its certificate.
|
|
27
|
+
*
|
|
28
|
+
* Deliberately unsafe, and off. It exists because a plant's development bus often has a
|
|
29
|
+
* self-signed certificate and a debugging tool that cannot reach it is no use - but anything
|
|
30
|
+
* able to answer on that address can then read and rewrite what this command sends.
|
|
31
|
+
*/
|
|
32
|
+
insecureTls?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/** The links a set of options asks for, in the order the commands have always built them. */
|
|
35
|
+
export declare const networkTransports: (options: NetworkOptions) => Transport[];
|
|
36
|
+
export interface ConnectedNetwork {
|
|
37
|
+
network: RpcServer;
|
|
38
|
+
/** Every peer visible on any link, kept current as they arrive and leave. */
|
|
39
|
+
online: Set<string>;
|
|
40
|
+
close: () => Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A window onto the network: an RpcServer that exposes nothing and exists to look and to call.
|
|
44
|
+
*
|
|
45
|
+
* The online set is seeded from the registry after ready() rather than only from the events, since
|
|
46
|
+
* transports are built asynchronously and whoever announced themselves during startup has already
|
|
47
|
+
* been and gone by the time a listener could be attached.
|
|
48
|
+
*/
|
|
49
|
+
export declare const connectNetwork: (options: NetworkOptions) => Promise<ConnectedNetwork>;
|
|
50
|
+
/**
|
|
51
|
+
* Waits for a peer to be addressable rather than failing on the first attempt.
|
|
52
|
+
*
|
|
53
|
+
* ready() means the links are up, not that presence has arrived - and over MQTT retained presence
|
|
54
|
+
* lands a moment after the subscription does. A one-shot command that gave up on that gap would
|
|
55
|
+
* fail intermittently for reasons nobody could reproduce.
|
|
56
|
+
*/
|
|
57
|
+
export declare const awaitPeer: (connected: ConnectedNetwork, peer: string, timeout: number) => Promise<boolean>;
|
|
58
|
+
//# sourceMappingURL=network.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../src/network.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,SAAS,EAA2C,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE9J;;;;;;;GAOG;AAEH,MAAM,WAAW,cAAc;IAC3B,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,wDAAwD;IACxD,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,+EAA+E;IAC/E,IAAI,CAAC,EAAE,aAAa,CAAA;IACpB,mFAAmF;IACnF,MAAM,CAAC,EAAE,eAAe,CAAA;IACxB,qGAAqG;IACrG,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,6FAA6F;AAC7F,eAAO,MAAM,iBAAiB,YAAa,cAAc,KAAG,SAAS,EAuBpE,CAAA;AAED,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,SAAS,CAAA;IAClB,6EAA6E;IAC7E,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACnB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,YAAmB,cAAc,KAAG,OAAO,CAAC,gBAAgB,CAkBtF,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,cAAqB,gBAAgB,QAAQ,MAAM,WAAW,MAAM,qBAOzF,CAAA"}
|
package/dist/network.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { MqttTransport, RpcServer, SocketIoClientTransport, TransportEvent } from '@source-repo/rpc';
|
|
2
|
+
/** The links a set of options asks for, in the order the commands have always built them. */
|
|
3
|
+
export const networkTransports = (options) => [
|
|
4
|
+
...(options.broker
|
|
5
|
+
? [
|
|
6
|
+
new MqttTransport(options.name, options.broker, {
|
|
7
|
+
...(options.prefix ? { prefix: options.prefix } : {}),
|
|
8
|
+
...(options.sign ? { sign: options.sign } : {}),
|
|
9
|
+
...(options.verify ? { verify: options.verify } : {}),
|
|
10
|
+
...(options.insecureTls ? { allowInsecureTls: true } : {})
|
|
11
|
+
})
|
|
12
|
+
]
|
|
13
|
+
: []),
|
|
14
|
+
...(options.hub
|
|
15
|
+
? [
|
|
16
|
+
new SocketIoClientTransport(options.name, options.hub, [], { ...(options.hubCredentials ? { auth: options.hubCredentials } : {}) }, true, options.insecureTls)
|
|
17
|
+
]
|
|
18
|
+
: [])
|
|
19
|
+
];
|
|
20
|
+
/**
|
|
21
|
+
* A window onto the network: an RpcServer that exposes nothing and exists to look and to call.
|
|
22
|
+
*
|
|
23
|
+
* The online set is seeded from the registry after ready() rather than only from the events, since
|
|
24
|
+
* transports are built asynchronously and whoever announced themselves during startup has already
|
|
25
|
+
* been and gone by the time a listener could be attached.
|
|
26
|
+
*/
|
|
27
|
+
export const connectNetwork = async (options) => {
|
|
28
|
+
if (!options.broker && !options.hub)
|
|
29
|
+
throw new Error('connectNetwork: give it a broker, a hub, or both');
|
|
30
|
+
const online = new Set();
|
|
31
|
+
const network = new RpcServer({
|
|
32
|
+
name: options.name,
|
|
33
|
+
callTimeout: options.callTimeout,
|
|
34
|
+
readyTimeout: 15000,
|
|
35
|
+
transports: networkTransports(options)
|
|
36
|
+
});
|
|
37
|
+
await network.ready();
|
|
38
|
+
for (const peer of network.peers.names())
|
|
39
|
+
if (peer !== options.name)
|
|
40
|
+
online.add(peer);
|
|
41
|
+
for (const transport of network.transports) {
|
|
42
|
+
transport.on(TransportEvent.peerOnline, (peer) => void (peer !== options.name && online.add(peer)));
|
|
43
|
+
transport.on(TransportEvent.peerGone, (peer) => void online.delete(peer));
|
|
44
|
+
}
|
|
45
|
+
return { network, online, close: () => network.close() };
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Waits for a peer to be addressable rather than failing on the first attempt.
|
|
49
|
+
*
|
|
50
|
+
* ready() means the links are up, not that presence has arrived - and over MQTT retained presence
|
|
51
|
+
* lands a moment after the subscription does. A one-shot command that gave up on that gap would
|
|
52
|
+
* fail intermittently for reasons nobody could reproduce.
|
|
53
|
+
*/
|
|
54
|
+
export const awaitPeer = async (connected, peer, timeout) => {
|
|
55
|
+
const deadline = Date.now() + timeout;
|
|
56
|
+
for (;;) {
|
|
57
|
+
if (connected.online.has(peer) || connected.network.peers.names().includes(peer))
|
|
58
|
+
return true;
|
|
59
|
+
if (Date.now() >= deadline)
|
|
60
|
+
return false;
|
|
61
|
+
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=network.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.js","sourceRoot":"","sources":["../src/network.ts"],"names":[],"mappings":"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"}
|
package/dist/record.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { type NetworkOptions } from './network.js';
|
|
2
|
+
import type { TapFilter, TappedFrame } from './bus.js';
|
|
3
|
+
/**
|
|
4
|
+
* Writing a session down, and playing it back at something else.
|
|
5
|
+
*
|
|
6
|
+
* The tap already produces correlated, self-describing frames, so a recording is that stream in a
|
|
7
|
+
* file. What it is for is the question a plant asks constantly and no test framework answers: this
|
|
8
|
+
* new device is supposed to behave like the old one - does it? Capture an hour of the working
|
|
9
|
+
* plant, replay it at the replacement, and compare the answers.
|
|
10
|
+
*
|
|
11
|
+
* jsonl rather than anything cleverer, so `grep`, `jq` and `wc -l` work on it and a recording made
|
|
12
|
+
* today can still be read when whatever wrote it is gone.
|
|
13
|
+
*/
|
|
14
|
+
/** The first line of a recording, so a file that is not one is refused rather than half-read. */
|
|
15
|
+
export interface RecordingHeader {
|
|
16
|
+
msgrpc: 'recording';
|
|
17
|
+
version: 1;
|
|
18
|
+
at: number;
|
|
19
|
+
filter: TapFilter;
|
|
20
|
+
/** Who was doing the watching, for whoever reads the file later and wonders what it can see. */
|
|
21
|
+
sources: string[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* MsgPack carries Date and Uint8Array as values; JSON carries neither, and a recording that turned
|
|
25
|
+
* a timestamp into a string would replay something the device never received. Both are tagged on
|
|
26
|
+
* the way out and restored on the way back, which is the same problem the console's argument fields
|
|
27
|
+
* solve when they walk typed JSON before sending it.
|
|
28
|
+
*/
|
|
29
|
+
export declare const encodeValue: (value: unknown) => unknown;
|
|
30
|
+
export declare const decodeValue: (value: unknown) => unknown;
|
|
31
|
+
export interface RecordOptions extends NetworkOptions {
|
|
32
|
+
out: string;
|
|
33
|
+
filter: TapFilter;
|
|
34
|
+
}
|
|
35
|
+
export declare const startRecording: (options: RecordOptions) => Promise<{
|
|
36
|
+
sources: string[];
|
|
37
|
+
frames: () => number;
|
|
38
|
+
close: () => Promise<void>;
|
|
39
|
+
}>;
|
|
40
|
+
/** A recording, read back. */
|
|
41
|
+
export declare const readRecording: (path: string) => {
|
|
42
|
+
header: RecordingHeader;
|
|
43
|
+
frames: TappedFrame[];
|
|
44
|
+
};
|
|
45
|
+
export interface ReplayOptions extends NetworkOptions {
|
|
46
|
+
file: string;
|
|
47
|
+
/** Send every call here instead of to whoever received it originally. */
|
|
48
|
+
against?: string;
|
|
49
|
+
/** Higher is faster. 0 or less sends with no waiting at all. */
|
|
50
|
+
speed: number;
|
|
51
|
+
/** How long to wait for each addressee to appear before giving up on it. */
|
|
52
|
+
wait?: number;
|
|
53
|
+
}
|
|
54
|
+
/** What one recorded call did the second time round. */
|
|
55
|
+
export interface ReplayedCall {
|
|
56
|
+
namespace: string;
|
|
57
|
+
method: string;
|
|
58
|
+
params: unknown[];
|
|
59
|
+
target: string;
|
|
60
|
+
/** matched, differed, failed, or sent - the last meaning there was nothing recorded to compare. */
|
|
61
|
+
outcome: 'matched' | 'differed' | 'failed' | 'sent';
|
|
62
|
+
expected?: unknown;
|
|
63
|
+
got?: unknown;
|
|
64
|
+
error?: string;
|
|
65
|
+
ms: number;
|
|
66
|
+
}
|
|
67
|
+
export declare const replaySession: (options: ReplayOptions, onCall?: (call: ReplayedCall) => void) => Promise<{
|
|
68
|
+
calls: ReplayedCall[];
|
|
69
|
+
matched: number;
|
|
70
|
+
differed: number;
|
|
71
|
+
failed: number;
|
|
72
|
+
sent: number;
|
|
73
|
+
}>;
|
|
74
|
+
//# sourceMappingURL=record.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../src/record.ts"],"names":[],"mappings":"AAEA,OAAO,EAA6B,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAE7E,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAEtD;;;;;;;;;;GAUG;AAEH,iGAAiG;AACjG,MAAM,WAAW,eAAe;IAC5B,MAAM,EAAE,WAAW,CAAA;IACnB,OAAO,EAAE,CAAC,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,SAAS,CAAA;IACjB,gGAAgG;IAChG,OAAO,EAAE,MAAM,EAAE,CAAA;CACpB;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,UAAW,OAAO,KAAG,OAM5C,CAAA;AAED,eAAO,MAAM,WAAW,UAAW,OAAO,KAAG,OAS5C,CAAA;AAED,MAAM,WAAW,aAAc,SAAQ,cAAc;IACjD,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,SAAS,CAAA;CACpB;AAED,eAAO,MAAM,cAAc,YAAmB,aAAa;;;;EAsC1D,CAAA;AAED,8BAA8B;AAC9B,eAAO,MAAM,aAAa,SAAU,MAAM;;;CAazC,CAAA;AAED,MAAM,WAAW,aAAc,SAAQ,cAAc;IACjD,IAAI,EAAE,MAAM,CAAA;IACZ,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAA;IACb,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wDAAwD;AACxD,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,OAAO,EAAE,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,mGAAmG;IACnG,OAAO,EAAE,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAA;IACnD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,EAAE,EAAE,MAAM,CAAA;CACb;AAsBD,eAAO,MAAM,aAAa,YAAmB,aAAa,WAAW,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI;;;;;;EAyGhG,CAAA"}
|
package/dist/record.js
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { appendFileSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { RpcMessageType } from '@source-repo/rpc';
|
|
3
|
+
import { awaitPeer, connectNetwork } from './network.js';
|
|
4
|
+
import { openTap } from './tapping.js';
|
|
5
|
+
/**
|
|
6
|
+
* MsgPack carries Date and Uint8Array as values; JSON carries neither, and a recording that turned
|
|
7
|
+
* a timestamp into a string would replay something the device never received. Both are tagged on
|
|
8
|
+
* the way out and restored on the way back, which is the same problem the console's argument fields
|
|
9
|
+
* solve when they walk typed JSON before sending it.
|
|
10
|
+
*/
|
|
11
|
+
export const encodeValue = (value) => {
|
|
12
|
+
if (value instanceof Date)
|
|
13
|
+
return { $date: value.toISOString() };
|
|
14
|
+
if (value instanceof Uint8Array)
|
|
15
|
+
return { $bytes: Buffer.from(value).toString('hex') };
|
|
16
|
+
if (Array.isArray(value))
|
|
17
|
+
return value.map(encodeValue);
|
|
18
|
+
if (value && typeof value === 'object')
|
|
19
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, encodeValue(entry)]));
|
|
20
|
+
return value;
|
|
21
|
+
};
|
|
22
|
+
export const decodeValue = (value) => {
|
|
23
|
+
if (Array.isArray(value))
|
|
24
|
+
return value.map(decodeValue);
|
|
25
|
+
if (value && typeof value === 'object') {
|
|
26
|
+
const tagged = value;
|
|
27
|
+
if (typeof tagged.$date === 'string')
|
|
28
|
+
return new Date(tagged.$date);
|
|
29
|
+
if (typeof tagged.$bytes === 'string')
|
|
30
|
+
return Uint8Array.from(Buffer.from(tagged.$bytes, 'hex'));
|
|
31
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, decodeValue(entry)]));
|
|
32
|
+
}
|
|
33
|
+
return value;
|
|
34
|
+
};
|
|
35
|
+
export const startRecording = async (options) => {
|
|
36
|
+
const connected = await connectNetwork(options);
|
|
37
|
+
let written = 0;
|
|
38
|
+
// Appended line by line rather than held and written at the end: a recording is most wanted
|
|
39
|
+
// from the run that ended badly, and a process killed mid-session should leave what it saw.
|
|
40
|
+
const write = (line) => appendFileSync(options.out, JSON.stringify(line) + '\n');
|
|
41
|
+
// Held until the header is down. The header names the sources, which are only known once the
|
|
42
|
+
// tap is open, and writing it afterwards would truncate the file over any frame that arrived
|
|
43
|
+
// in between - the first moments of a recording being exactly the ones worth keeping.
|
|
44
|
+
let pending = [];
|
|
45
|
+
const lineFor = (frame) => ({
|
|
46
|
+
...frame,
|
|
47
|
+
...(frame.params ? { params: encodeValue(frame.params) } : {}),
|
|
48
|
+
...(frame.result !== undefined ? { result: encodeValue(frame.result) } : {})
|
|
49
|
+
});
|
|
50
|
+
const tap = await openTap(connected, options, options.filter, (frame) => {
|
|
51
|
+
written++;
|
|
52
|
+
if (pending)
|
|
53
|
+
pending.push(lineFor(frame));
|
|
54
|
+
else
|
|
55
|
+
write(lineFor(frame));
|
|
56
|
+
});
|
|
57
|
+
const header = { msgrpc: 'recording', version: 1, at: Date.now(), filter: options.filter, sources: tap.sources };
|
|
58
|
+
writeFileSync(options.out, JSON.stringify(header) + '\n');
|
|
59
|
+
const buffered = pending;
|
|
60
|
+
pending = undefined;
|
|
61
|
+
for (const line of buffered)
|
|
62
|
+
write(line);
|
|
63
|
+
return {
|
|
64
|
+
sources: tap.sources,
|
|
65
|
+
frames: () => written,
|
|
66
|
+
close: async () => {
|
|
67
|
+
await tap.close();
|
|
68
|
+
await connected.close();
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
/** A recording, read back. */
|
|
73
|
+
export const readRecording = (path) => {
|
|
74
|
+
const lines = readFileSync(path, 'utf8').split('\n').filter(Boolean);
|
|
75
|
+
if (!lines.length)
|
|
76
|
+
throw new Error(`${path} is empty`);
|
|
77
|
+
let header;
|
|
78
|
+
try {
|
|
79
|
+
header = JSON.parse(lines[0]);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
throw new Error(`${path} does not start with a recording header`);
|
|
83
|
+
}
|
|
84
|
+
if (header?.msgrpc !== 'recording')
|
|
85
|
+
throw new Error(`${path} is not a Source RPC recording`);
|
|
86
|
+
if (header.version !== 1)
|
|
87
|
+
throw new Error(`${path} is a version ${header.version} recording, and this only reads version 1`);
|
|
88
|
+
const frames = lines.slice(1).map((line) => JSON.parse(line));
|
|
89
|
+
return { header, frames };
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Deep equality for what came back against what was recorded.
|
|
93
|
+
*
|
|
94
|
+
* Dates and byte strings compare by value: a reply carrying `new Date(...)` is the same answer as
|
|
95
|
+
* the recorded one when the instants match, and `===` would say otherwise for every single call.
|
|
96
|
+
*/
|
|
97
|
+
const same = (a, b) => {
|
|
98
|
+
if (a instanceof Date || b instanceof Date)
|
|
99
|
+
return a instanceof Date && b instanceof Date && a.getTime() === b.getTime();
|
|
100
|
+
if (a instanceof Uint8Array || b instanceof Uint8Array)
|
|
101
|
+
return a instanceof Uint8Array && b instanceof Uint8Array && a.length === b.length && a.every((byte, index) => byte === b[index]);
|
|
102
|
+
if (Array.isArray(a) || Array.isArray(b))
|
|
103
|
+
return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((entry, index) => same(entry, b[index]));
|
|
104
|
+
if (a && b && typeof a === 'object' && typeof b === 'object') {
|
|
105
|
+
const left = Object.keys(a);
|
|
106
|
+
const right = Object.keys(b);
|
|
107
|
+
if (left.length !== right.length)
|
|
108
|
+
return false;
|
|
109
|
+
return left.every((key) => same(a[key], b[key]));
|
|
110
|
+
}
|
|
111
|
+
return a === b;
|
|
112
|
+
};
|
|
113
|
+
export const replaySession = async (options, onCall) => {
|
|
114
|
+
const { frames } = readRecording(options.file);
|
|
115
|
+
const connected = await connectNetwork(options);
|
|
116
|
+
// A reply carries no method of its own, so the recorded answer for a call is found by its id -
|
|
117
|
+
// the same pairing the tap does when it reports one.
|
|
118
|
+
const replies = new Map();
|
|
119
|
+
for (const frame of frames)
|
|
120
|
+
if (frame.id && (frame.kind === RpcMessageType.success || frame.kind === RpcMessageType.error))
|
|
121
|
+
replies.set(frame.id, frame);
|
|
122
|
+
const calls = frames.filter((frame) => frame.kind === RpcMessageType.CallInstanceMethod);
|
|
123
|
+
const results = [];
|
|
124
|
+
let previous;
|
|
125
|
+
// Every addressee has to be reachable before the first call goes out. ready() means the links
|
|
126
|
+
// are up, not that presence has arrived, and a replay that started regardless spent its first
|
|
127
|
+
// call waiting out a timeout against a peer that was moments from appearing.
|
|
128
|
+
const targets = new Set(calls.map((call) => options.against ?? call.target));
|
|
129
|
+
const missing = new Set();
|
|
130
|
+
await Promise.all([...targets].map(async (target) => void ((await awaitPeer(connected, target, options.wait ?? 5000)) || missing.add(target))));
|
|
131
|
+
try {
|
|
132
|
+
for (const call of calls) {
|
|
133
|
+
// The original spacing, so a device that only misbehaves under the rate it actually
|
|
134
|
+
// sees is given that rate rather than a burst.
|
|
135
|
+
if (previous !== undefined && options.speed > 0) {
|
|
136
|
+
const gap = (call.at - previous) / options.speed;
|
|
137
|
+
if (gap > 0)
|
|
138
|
+
await new Promise((resolve) => setTimeout(resolve, Math.min(gap, 60000)));
|
|
139
|
+
}
|
|
140
|
+
previous = call.at;
|
|
141
|
+
const target = options.against ?? call.target;
|
|
142
|
+
const namespace = call.namespace ?? '';
|
|
143
|
+
const method = call.method ?? '';
|
|
144
|
+
const params = decodeValue(call.params ?? []) ?? [];
|
|
145
|
+
const started = Date.now();
|
|
146
|
+
const outcome = { namespace, method, params, target, outcome: 'sent', ms: 0 };
|
|
147
|
+
if (missing.has(target)) {
|
|
148
|
+
// Said once per call rather than waited out per call: twelve calls at a peer that is
|
|
149
|
+
// not there is twelve timeouts and one fact.
|
|
150
|
+
outcome.error = `${target} is not on this network`;
|
|
151
|
+
outcome.outcome = 'failed';
|
|
152
|
+
results.push(outcome);
|
|
153
|
+
onCall?.(outcome);
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
if (!call.params) {
|
|
157
|
+
// Recorded without payloads, so there are no arguments to send. Reported rather
|
|
158
|
+
// than sent empty, which would call the method with nothing and compare that.
|
|
159
|
+
outcome.error = 'recorded without payloads, so it cannot be replayed';
|
|
160
|
+
outcome.outcome = 'failed';
|
|
161
|
+
results.push(outcome);
|
|
162
|
+
onCall?.(outcome);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
try {
|
|
166
|
+
const proxy = await connected.network.proxy(namespace, target);
|
|
167
|
+
const got = await proxy.remote[method](...params);
|
|
168
|
+
outcome.ms = Date.now() - started;
|
|
169
|
+
const recorded = call.id ? replies.get(call.id) : undefined;
|
|
170
|
+
if (!recorded || (recorded.kind === RpcMessageType.success && recorded.result === undefined)) {
|
|
171
|
+
// Nothing to compare against is not a pass. Counted apart, so a run of these
|
|
172
|
+
// cannot be read as a device that matched.
|
|
173
|
+
outcome.outcome = 'sent';
|
|
174
|
+
outcome.got = got;
|
|
175
|
+
}
|
|
176
|
+
else if (recorded.kind === RpcMessageType.error) {
|
|
177
|
+
outcome.outcome = 'differed';
|
|
178
|
+
outcome.expected = `${recorded.code}: ${recorded.error ?? ''}`.trim();
|
|
179
|
+
outcome.got = got;
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
const expected = decodeValue(recorded.result);
|
|
183
|
+
outcome.outcome = same(expected, got) ? 'matched' : 'differed';
|
|
184
|
+
outcome.expected = expected;
|
|
185
|
+
outcome.got = got;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch (e) {
|
|
189
|
+
outcome.ms = Date.now() - started;
|
|
190
|
+
const failure = e;
|
|
191
|
+
const recorded = call.id ? replies.get(call.id) : undefined;
|
|
192
|
+
// A call that failed the same way it failed when recorded is a match: a device that
|
|
193
|
+
// refuses what the old one refused is behaving.
|
|
194
|
+
if (recorded?.kind === RpcMessageType.error && recorded.code === failure.code) {
|
|
195
|
+
outcome.outcome = 'matched';
|
|
196
|
+
outcome.expected = `${recorded.code}: ${recorded.error ?? ''}`.trim();
|
|
197
|
+
outcome.got = `${failure.code}: ${failure.message ?? ''}`.trim();
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
outcome.outcome = 'failed';
|
|
201
|
+
outcome.error = `${failure.code ? failure.code + ': ' : ''}${failure.message ?? String(e)}`;
|
|
202
|
+
if (recorded?.kind === RpcMessageType.success)
|
|
203
|
+
outcome.expected = decodeValue(recorded.result);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
results.push(outcome);
|
|
207
|
+
onCall?.(outcome);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
finally {
|
|
211
|
+
await connected.close();
|
|
212
|
+
}
|
|
213
|
+
return {
|
|
214
|
+
calls: results,
|
|
215
|
+
matched: results.filter((call) => call.outcome === 'matched').length,
|
|
216
|
+
differed: results.filter((call) => call.outcome === 'differed').length,
|
|
217
|
+
failed: results.filter((call) => call.outcome === 'failed').length,
|
|
218
|
+
sent: results.filter((call) => call.outcome === 'sent').length
|
|
219
|
+
};
|
|
220
|
+
};
|
|
221
|
+
//# sourceMappingURL=record.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record.js","sourceRoot":"","sources":["../src/record.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type TapFilter, type TappedFrame } from './bus.js';
|
|
2
|
+
import type { ConnectedNetwork, NetworkOptions } from './network.js';
|
|
3
|
+
export interface OpenTap {
|
|
4
|
+
/** Who is doing the watching: peer names, or 'this process' for an MQTT tap held here. */
|
|
5
|
+
sources: string[];
|
|
6
|
+
close: () => Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
export declare const openTap: (connected: ConnectedNetwork, options: NetworkOptions & {
|
|
9
|
+
settle?: number;
|
|
10
|
+
}, filter: TapFilter, onFrame: (frame: TappedFrame) => void) => Promise<OpenTap>;
|
|
11
|
+
//# sourceMappingURL=tapping.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tapping.d.ts","sourceRoot":"","sources":["../src/tapping.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAyBpE,MAAM,WAAW,OAAO;IACpB,0FAA0F;IAC1F,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7B;AAED,eAAO,MAAM,OAAO,cACL,gBAAgB,WAClB,cAAc,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,UACrC,SAAS,WACR,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,KACtC,OAAO,CAAC,OAAO,CAoEjB,CAAA"}
|
package/dist/tapping.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { MqttTransport, TransportEvent } from '@source-repo/rpc';
|
|
2
|
+
import { BusService } from './bus.js';
|
|
3
|
+
/** How long to wait for presence before deciding nothing here can watch. */
|
|
4
|
+
const DEFAULT_SETTLE = 2000;
|
|
5
|
+
export const openTap = async (connected, options, filter, onFrame) => {
|
|
6
|
+
const sources = [];
|
|
7
|
+
const closers = [];
|
|
8
|
+
if (options.broker) {
|
|
9
|
+
// A connection of its own, for the reason MqttTransport's `tap` option documents: a peer
|
|
10
|
+
// subscribed to both its own topic and the wildcard covering it has overlapping
|
|
11
|
+
// subscriptions, and a broker may deliver a matching message once per subscription.
|
|
12
|
+
const bus = new BusService(options.name);
|
|
13
|
+
bus.on('frame', (frame) => onFrame(frame));
|
|
14
|
+
const link = new MqttTransport(`${options.name}-tap`, options.broker, {
|
|
15
|
+
...(options.prefix ? { prefix: options.prefix } : {}),
|
|
16
|
+
tap: true,
|
|
17
|
+
presence: false
|
|
18
|
+
});
|
|
19
|
+
link.on(TransportEvent.relayed, (relayed) => bus.observe(relayed));
|
|
20
|
+
await link.open();
|
|
21
|
+
await link.ready();
|
|
22
|
+
await bus.tap(filter);
|
|
23
|
+
sources.push('this process');
|
|
24
|
+
closers.push(async () => {
|
|
25
|
+
await bus.releaseAll();
|
|
26
|
+
await link.close();
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
// ready() means the links are up, not that presence has arrived. Scanning immediately finds an
|
|
30
|
+
// empty network on a bus that is plainly there, and the tap then watches nothing at all - which
|
|
31
|
+
// reads as a quiet plant rather than as the race it is.
|
|
32
|
+
const deadline = Date.now() + (options.settle ?? DEFAULT_SETTLE);
|
|
33
|
+
while (!connected.online.size && Date.now() < deadline)
|
|
34
|
+
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
35
|
+
// Every peer at once rather than one after another: a peer that is registered and no longer
|
|
36
|
+
// answering costs a whole call timeout, and in sequence that is one per stale peer.
|
|
37
|
+
const described = await Promise.all([...connected.online].map(async (peer) => {
|
|
38
|
+
const description = await connected.network
|
|
39
|
+
.proxy('msgrpc', peer)
|
|
40
|
+
.then((proxy) => proxy.remote.describe())
|
|
41
|
+
.catch(() => undefined);
|
|
42
|
+
return { peer, hasBus: !!description?.namespaces.some((namespace) => namespace.name === 'bus') };
|
|
43
|
+
}));
|
|
44
|
+
for (const { peer, hasBus } of described) {
|
|
45
|
+
if (!hasBus)
|
|
46
|
+
continue;
|
|
47
|
+
try {
|
|
48
|
+
const proxy = await connected.network.proxy('bus', peer);
|
|
49
|
+
const answer = await proxy.remote.tap(filter);
|
|
50
|
+
const handler = (frame) => onFrame(frame);
|
|
51
|
+
await proxy.remote.on('frame', handler);
|
|
52
|
+
sources.push(peer);
|
|
53
|
+
closers.push(async () => {
|
|
54
|
+
await proxy.remote.off('frame', handler).catch(() => undefined);
|
|
55
|
+
await proxy.remote.untap(answer.token).catch(() => undefined);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// One bus that refuses does not stop the others, and a tap that opened nothing is
|
|
60
|
+
// reported by its empty source list rather than by failing.
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
sources,
|
|
65
|
+
close: async () => {
|
|
66
|
+
for (const closer of closers)
|
|
67
|
+
await closer().catch(() => undefined);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=tapping.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tapping.js","sourceRoot":"","sources":["../src/tapping.ts"],"names":[],"mappings":"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"}
|