@source-repo/rpc 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 +1208 -0
- package/dist/Logging/ILogger.d.ts +7 -0
- package/dist/Logging/ILogger.d.ts.map +1 -0
- package/dist/Logging/ILogger.js +2 -0
- package/dist/Logging/ILogger.js.map +1 -0
- package/dist/NodeRpcServer.d.ts +55 -0
- package/dist/NodeRpcServer.d.ts.map +1 -0
- package/dist/NodeRpcServer.js +46 -0
- package/dist/NodeRpcServer.js.map +1 -0
- package/dist/RPC/Auth.d.ts +98 -0
- package/dist/RPC/Auth.d.ts.map +1 -0
- package/dist/RPC/Auth.js +14 -0
- package/dist/RPC/Auth.js.map +1 -0
- package/dist/RPC/Codec.d.ts +24 -0
- package/dist/RPC/Codec.d.ts.map +1 -0
- package/dist/RPC/Codec.js +21 -0
- package/dist/RPC/Codec.js.map +1 -0
- package/dist/RPC/Compatibility.d.ts +39 -0
- package/dist/RPC/Compatibility.d.ts.map +1 -0
- package/dist/RPC/Compatibility.js +195 -0
- package/dist/RPC/Compatibility.js.map +1 -0
- package/dist/RPC/Core.d.ts +188 -0
- package/dist/RPC/Core.d.ts.map +1 -0
- package/dist/RPC/Core.js +354 -0
- package/dist/RPC/Core.js.map +1 -0
- package/dist/RPC/Expose.d.ts +90 -0
- package/dist/RPC/Expose.d.ts.map +1 -0
- package/dist/RPC/Expose.js +110 -0
- package/dist/RPC/Expose.js.map +1 -0
- package/dist/RPC/Idempotency.d.ts +90 -0
- package/dist/RPC/Idempotency.d.ts.map +1 -0
- package/dist/RPC/Idempotency.js +46 -0
- package/dist/RPC/Idempotency.js.map +1 -0
- package/dist/RPC/Introspection.d.ts +92 -0
- package/dist/RPC/Introspection.d.ts.map +1 -0
- package/dist/RPC/Introspection.js +188 -0
- package/dist/RPC/Introspection.js.map +1 -0
- package/dist/RPC/Introspection.types.json +1093 -0
- package/dist/RPC/Messages.d.ts +108 -0
- package/dist/RPC/Messages.d.ts.map +1 -0
- package/dist/RPC/Messages.js +30 -0
- package/dist/RPC/Messages.js.map +1 -0
- package/dist/RPC/Rpc.d.ts +51 -0
- package/dist/RPC/Rpc.d.ts.map +1 -0
- package/dist/RPC/Rpc.js +54 -0
- package/dist/RPC/Rpc.js.map +1 -0
- package/dist/RPC/RpcClientHandler.d.ts +129 -0
- package/dist/RPC/RpcClientHandler.d.ts.map +1 -0
- package/dist/RPC/RpcClientHandler.js +267 -0
- package/dist/RPC/RpcClientHandler.js.map +1 -0
- package/dist/RPC/RpcServerHandler.d.ts +226 -0
- package/dist/RPC/RpcServerHandler.d.ts.map +1 -0
- package/dist/RPC/RpcServerHandler.js +676 -0
- package/dist/RPC/RpcServerHandler.js.map +1 -0
- package/dist/RPC/Schema.d.ts +150 -0
- package/dist/RPC/Schema.d.ts.map +1 -0
- package/dist/RPC/Schema.js +198 -0
- package/dist/RPC/Schema.js.map +1 -0
- package/dist/RPC/Signing.d.ts +118 -0
- package/dist/RPC/Signing.d.ts.map +1 -0
- package/dist/RPC/Signing.js +171 -0
- package/dist/RPC/Signing.js.map +1 -0
- package/dist/RPC/Tokens.d.ts +49 -0
- package/dist/RPC/Tokens.d.ts.map +1 -0
- package/dist/RPC/Tokens.js +45 -0
- package/dist/RPC/Tokens.js.map +1 -0
- package/dist/RpcClient.d.ts +91 -0
- package/dist/RpcClient.d.ts.map +1 -0
- package/dist/RpcClient.js +145 -0
- package/dist/RpcClient.js.map +1 -0
- package/dist/RpcServer.d.ts +191 -0
- package/dist/RpcServer.d.ts.map +1 -0
- package/dist/RpcServer.js +293 -0
- package/dist/RpcServer.js.map +1 -0
- package/dist/Transports/Mqtt5Frame.d.ts +107 -0
- package/dist/Transports/Mqtt5Frame.d.ts.map +1 -0
- package/dist/Transports/Mqtt5Frame.js +162 -0
- package/dist/Transports/Mqtt5Frame.js.map +1 -0
- package/dist/Transports/MqttTransport.d.ts +279 -0
- package/dist/Transports/MqttTransport.d.ts.map +1 -0
- package/dist/Transports/MqttTransport.js +843 -0
- package/dist/Transports/MqttTransport.js.map +1 -0
- package/dist/Transports/Presence.d.ts +68 -0
- package/dist/Transports/Presence.d.ts.map +1 -0
- package/dist/Transports/Presence.js +21 -0
- package/dist/Transports/Presence.js.map +1 -0
- package/dist/Transports/SocketIoClientTransport.d.ts +89 -0
- package/dist/Transports/SocketIoClientTransport.d.ts.map +1 -0
- package/dist/Transports/SocketIoClientTransport.js +280 -0
- package/dist/Transports/SocketIoClientTransport.js.map +1 -0
- package/dist/Transports/SocketIoServerTransport.d.ts +135 -0
- package/dist/Transports/SocketIoServerTransport.d.ts.map +1 -0
- package/dist/Transports/SocketIoServerTransport.js +505 -0
- package/dist/Transports/SocketIoServerTransport.js.map +1 -0
- package/dist/Utilities/Converters.d.ts +22 -0
- package/dist/Utilities/Converters.d.ts.map +1 -0
- package/dist/Utilities/Converters.js +58 -0
- package/dist/Utilities/Converters.js.map +1 -0
- package/dist/Utilities/Filter.d.ts +7 -0
- package/dist/Utilities/Filter.d.ts.map +1 -0
- package/dist/Utilities/Filter.js +14 -0
- package/dist/Utilities/Filter.js.map +1 -0
- package/dist/Utilities/ReadableName.d.ts +38 -0
- package/dist/Utilities/ReadableName.d.ts.map +1 -0
- package/dist/Utilities/ReadableName.js +58 -0
- package/dist/Utilities/ReadableName.js.map +1 -0
- package/dist/Utilities/Switch.d.ts +21 -0
- package/dist/Utilities/Switch.d.ts.map +1 -0
- package/dist/Utilities/Switch.js +70 -0
- package/dist/Utilities/Switch.js.map +1 -0
- package/dist/Utilities/TryCatch.d.ts +11 -0
- package/dist/Utilities/TryCatch.d.ts.map +1 -0
- package/dist/Utilities/TryCatch.js +13 -0
- package/dist/Utilities/TryCatch.js.map +1 -0
- package/dist/index-web.d.ts +25 -0
- package/dist/index-web.d.ts.map +1 -0
- package/dist/index-web.js +28 -0
- package/dist/index-web.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Payload } from './Core.js';
|
|
2
|
+
/**
|
|
3
|
+
* The RPC message vocabulary, in a module of its own because both the handlers and the transports
|
|
4
|
+
* need it. A transport whose wire format is structured - MQTT 5 carries the method, correlation
|
|
5
|
+
* and reply address as packet properties - has to know what a call, a result, an error and an
|
|
6
|
+
* event are in order to map them.
|
|
7
|
+
*/
|
|
8
|
+
export declare enum RpcMessageType {
|
|
9
|
+
CallInstanceMethod = "POST",
|
|
10
|
+
success = "SUCCESS",
|
|
11
|
+
error = "ERROR",
|
|
12
|
+
event = "EVENT"
|
|
13
|
+
}
|
|
14
|
+
export interface RpcMessage extends Payload {
|
|
15
|
+
type: RpcMessageType;
|
|
16
|
+
}
|
|
17
|
+
export interface RpcCallInstanceMethodPayload extends RpcMessage {
|
|
18
|
+
id: string;
|
|
19
|
+
path: string;
|
|
20
|
+
method: string;
|
|
21
|
+
params: unknown[];
|
|
22
|
+
/**
|
|
23
|
+
* Contract version the caller was built against, when it has a schema. The server compares it
|
|
24
|
+
* with the version it serves and refuses only when the two are structurally incompatible.
|
|
25
|
+
*/
|
|
26
|
+
version?: string;
|
|
27
|
+
/**
|
|
28
|
+
* How many milliseconds the caller will still be waiting, measured when it sent this. A server
|
|
29
|
+
* that finds the budget spent answers `Timeout` instead of running the method.
|
|
30
|
+
*
|
|
31
|
+
* A duration, not a moment. An absolute deadline would be exact if every peer agreed on the
|
|
32
|
+
* time, and one of the peers here is a browser page whose clock belongs to whoever is sitting
|
|
33
|
+
* at it - so a wrong clock would refuse every command it sent, which is a worse failure than
|
|
34
|
+
* the one this prevents. The receiver stamps arrival by its own clock and counts from there,
|
|
35
|
+
* and on MQTT 5 the broker's own expiry accounts for the part of the journey it queued.
|
|
36
|
+
*/
|
|
37
|
+
ttl?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Names the command this call *is*, as opposed to `id`, which names this attempt at it.
|
|
40
|
+
*
|
|
41
|
+
* Two attempts at one command carry one key, which is what lets a server with a durable
|
|
42
|
+
* idempotency store answer the second from the first's outcome instead of running it again.
|
|
43
|
+
* Absent means the request id is the key, which still covers a redelivery of the same packet
|
|
44
|
+
* but not an operator pressing the button a second time - those are different attempts.
|
|
45
|
+
*/
|
|
46
|
+
idempotencyKey?: string;
|
|
47
|
+
}
|
|
48
|
+
export type RpcErrorCode = 'ClassNotFound' | 'MethodNotFound' | 'Exception' | 'Timeout' | 'TransportError' | 'Unauthorized' | 'Forbidden' | 'InvalidParams' | 'IncompatibleVersion'
|
|
49
|
+
/**
|
|
50
|
+
* The call was sent and its outcome is not known: it may have run, it may not, and nothing here
|
|
51
|
+
* can tell which.
|
|
52
|
+
*
|
|
53
|
+
* Distinct from `TransportError`, which is the honest answer when a request never left - a
|
|
54
|
+
* failed encode, a closed link, a broker that refused the publish. The difference is the whole
|
|
55
|
+
* point. "It failed" invites a retry; "I do not know" says to go and look, and for a
|
|
56
|
+
* non-repeatable command that distinction is the difference between one pump start and two.
|
|
57
|
+
*/
|
|
58
|
+
| 'UnknownOutcome';
|
|
59
|
+
/**
|
|
60
|
+
* What a method does to the world, which decides what a caller may do about an uncertain answer.
|
|
61
|
+
*
|
|
62
|
+
* Most RPC systems make it easy to call a function and leave this to prose. On a plant it is the
|
|
63
|
+
* distinction that matters: retrying a read costs a round trip, and retrying a start costs a second
|
|
64
|
+
* start.
|
|
65
|
+
*
|
|
66
|
+
* - `query` changes nothing, so it can be repeated at will.
|
|
67
|
+
* - `idempotent-command` changes something, but arriving twice leaves the same state as arriving
|
|
68
|
+
* once - `setSetpoint(1200)`, `close()`, anything that assigns rather than accumulates.
|
|
69
|
+
* - `non-repeatable-command` must not be sent again on an uncertain answer, because a second
|
|
70
|
+
* arrival is a second effect - `dispense()`, `advanceBatch()`, `resetTotaliser()`.
|
|
71
|
+
*
|
|
72
|
+
* Undeclared means undeclared. The library will not guess a method is safe to repeat, and will not
|
|
73
|
+
* pretend a read is dangerous either; what it does instead is refuse to *silently* do anything that
|
|
74
|
+
* depends on knowing.
|
|
75
|
+
*/
|
|
76
|
+
export type RpcMethodSemantics = 'query' | 'idempotent-command' | 'non-repeatable-command';
|
|
77
|
+
/** Increasing order of what a repeat costs, so a contract change can be judged against it. */
|
|
78
|
+
export declare const SEMANTICS_RISK: {
|
|
79
|
+
[semantics in RpcMethodSemantics]: number;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* A remote error flattened into something that survives MsgPack/JSON encoding.
|
|
83
|
+
* An Error instance keeps `message` and `stack` on non-enumerable properties, so encoding one
|
|
84
|
+
* directly yields an empty object - it has to be copied onto a plain object first.
|
|
85
|
+
*/
|
|
86
|
+
export interface RpcRemoteError {
|
|
87
|
+
name: string;
|
|
88
|
+
message: string;
|
|
89
|
+
stack?: string;
|
|
90
|
+
}
|
|
91
|
+
export declare const toRemoteError: (e: unknown) => RpcRemoteError;
|
|
92
|
+
export interface RpcErrorPayload extends RpcMessage {
|
|
93
|
+
/** Id of the originating request, so the caller's pending promise can be settled. */
|
|
94
|
+
id: string;
|
|
95
|
+
code: RpcErrorCode;
|
|
96
|
+
error?: RpcRemoteError;
|
|
97
|
+
}
|
|
98
|
+
export interface RpcSuccessPayload extends RpcMessage {
|
|
99
|
+
id: string;
|
|
100
|
+
result: unknown;
|
|
101
|
+
}
|
|
102
|
+
export interface RpcEventPayload extends RpcMessage {
|
|
103
|
+
event: string;
|
|
104
|
+
params: unknown[];
|
|
105
|
+
/** Instance the event came from. Lets a wire format name the emitter, as MQTT 5 does. */
|
|
106
|
+
path?: string;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=Messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Messages.d.ts","sourceRoot":"","sources":["../../src/RPC/Messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC;;;;;GAKG;AAEH,oBAAY,cAAc;IACtB,kBAAkB,SAAS;IAC3B,OAAO,YAAY;IACnB,KAAK,UAAU;IACf,KAAK,UAAU;CAClB;AAED,MAAM,WAAW,UAAW,SAAQ,OAAO;IACvC,IAAI,EAAE,cAAc,CAAA;CACvB;AAED,MAAM,WAAW,4BAA6B,SAAQ,UAAU;IAC5D,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,OAAO,EAAE,CAAA;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;;;;;;OASG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,MAAM,YAAY,GAClB,eAAe,GACf,gBAAgB,GAChB,WAAW,GACX,SAAS,GACT,gBAAgB,GAChB,cAAc,GACd,WAAW,GACX,eAAe,GACf,qBAAqB;AACvB;;;;;;;;GAQG;GACD,gBAAgB,CAAA;AAEtB;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,oBAAoB,GAAG,wBAAwB,CAAA;AAE1F,8FAA8F;AAC9F,eAAO,MAAM,cAAc,EAAE;KAAG,SAAS,IAAI,kBAAkB,GAAG,MAAM;CAIvE,CAAA;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,eAAO,MAAM,aAAa,MAAO,OAAO,KAAG,cAQ1C,CAAA;AAED,MAAM,WAAW,eAAgB,SAAQ,UAAU;IAC/C,qFAAqF;IACrF,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,YAAY,CAAA;IAClB,KAAK,CAAC,EAAE,cAAc,CAAA;CACzB;AACD,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACjD,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,OAAO,CAAA;CAClB;AACD,MAAM,WAAW,eAAgB,SAAQ,UAAU;IAC/C,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,OAAO,EAAE,CAAA;IACjB,yFAAyF;IACzF,IAAI,CAAC,EAAE,MAAM,CAAA;CAChB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The RPC message vocabulary, in a module of its own because both the handlers and the transports
|
|
3
|
+
* need it. A transport whose wire format is structured - MQTT 5 carries the method, correlation
|
|
4
|
+
* and reply address as packet properties - has to know what a call, a result, an error and an
|
|
5
|
+
* event are in order to map them.
|
|
6
|
+
*/
|
|
7
|
+
export var RpcMessageType;
|
|
8
|
+
(function (RpcMessageType) {
|
|
9
|
+
RpcMessageType["CallInstanceMethod"] = "POST";
|
|
10
|
+
RpcMessageType["success"] = "SUCCESS";
|
|
11
|
+
RpcMessageType["error"] = "ERROR";
|
|
12
|
+
RpcMessageType["event"] = "EVENT";
|
|
13
|
+
})(RpcMessageType || (RpcMessageType = {}));
|
|
14
|
+
/** Increasing order of what a repeat costs, so a contract change can be judged against it. */
|
|
15
|
+
export const SEMANTICS_RISK = {
|
|
16
|
+
query: 0,
|
|
17
|
+
'idempotent-command': 1,
|
|
18
|
+
'non-repeatable-command': 2
|
|
19
|
+
};
|
|
20
|
+
export const toRemoteError = (e) => {
|
|
21
|
+
if (e instanceof Error)
|
|
22
|
+
return { name: e.name, message: e.message, stack: e.stack };
|
|
23
|
+
if (e && typeof e === 'object') {
|
|
24
|
+
const candidate = e;
|
|
25
|
+
if (typeof candidate.message === 'string')
|
|
26
|
+
return { name: typeof candidate.name === 'string' ? candidate.name : 'Error', message: candidate.message };
|
|
27
|
+
}
|
|
28
|
+
return { name: 'Error', message: String(e) };
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=Messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Messages.js","sourceRoot":"","sources":["../../src/RPC/Messages.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,MAAM,CAAN,IAAY,cAKX;AALD,WAAY,cAAc;IACtB,6CAA2B,CAAA;IAC3B,qCAAmB,CAAA;IACnB,iCAAe,CAAA;IACf,iCAAe,CAAA;AACnB,CAAC,EALW,cAAc,KAAd,cAAc,QAKzB;AA8ED,8FAA8F;AAC9F,MAAM,CAAC,MAAM,cAAc,GAAkD;IACzE,KAAK,EAAE,CAAC;IACR,oBAAoB,EAAE,CAAC;IACvB,wBAAwB,EAAE,CAAC;CAC9B,CAAA;AAaD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAU,EAAkB,EAAE;IACxD,IAAI,CAAC,YAAY,KAAK;QAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAA;IACnF,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,CAA0C,CAAA;QAC5D,IAAI,OAAO,SAAS,CAAC,OAAO,KAAK,QAAQ;YACrC,OAAO,EAAE,IAAI,EAAE,OAAO,SAAS,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,CAAA;IAClH,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;AAChD,CAAC,CAAA"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { ExposeOptions } from './RpcServerHandler.js';
|
|
2
|
+
/**
|
|
3
|
+
* The Source RPC port. An unconfigured server listens here, an unconfigured client dials here, and
|
|
4
|
+
* `source-rpc broker` runs a bus here.
|
|
5
|
+
*
|
|
6
|
+
* Having one number rather than three is the whole of the argument: a well-known port is what lets
|
|
7
|
+
* `mqtt://broker:1883` and `http://bus:7843` both be written from memory, and what makes a port map
|
|
8
|
+
* in a compose file readable without a comment on each line.
|
|
9
|
+
*
|
|
10
|
+
* 7843 rather than anything in the 80xx range, which is where a developer's other work already
|
|
11
|
+
* lives - 8080, 8081, 8085 are taken on any machine that has been used for a while, and a default
|
|
12
|
+
* that collides on the laptop is a default nobody keeps. This is quiet ground: high enough to need
|
|
13
|
+
* no privilege, low enough to stay clear of the ephemeral range, and not the neighbour of anything
|
|
14
|
+
* that would be mistaken for it.
|
|
15
|
+
*/
|
|
16
|
+
export declare const defaultWebSocketPort = 7843;
|
|
17
|
+
/**
|
|
18
|
+
* Where anything that serves a browser puts its HTTP port. `source-rpc console` defaults here.
|
|
19
|
+
*
|
|
20
|
+
* Adjacent to the RPC port rather than derived by an offset: they are read together, and 7843/7844
|
|
21
|
+
* is one thing to remember. A single process needs only one of them - the console serves its page
|
|
22
|
+
* and its RPC on the same listener - so the second number is for running a bus and a console on one
|
|
23
|
+
* host, which is the ordinary case.
|
|
24
|
+
*/
|
|
25
|
+
export declare const defaultWebPort: number;
|
|
26
|
+
/**
|
|
27
|
+
* The same two services with TLS: `rpc-tls` and `console-tls`.
|
|
28
|
+
*
|
|
29
|
+
* A thousand above their plaintext counterparts, deliberately **not** adjacent to them. The last
|
|
30
|
+
* two digits still match, so 7843/8843 is one number to remember with a rule attached - but no
|
|
31
|
+
* range covers both, and `allow 7843:7846` is the rule somebody writes at the end of a long day. A
|
|
32
|
+
* firewall that meant to publish only the encrypted port should not be able to open the other one
|
|
33
|
+
* by fencepost. MQTT draws the same line for the same reason, 1883 against 8883, so the habit
|
|
34
|
+
* transfers.
|
|
35
|
+
*
|
|
36
|
+
* These say where to *find* a service, not what any process must do. A port carries TLS because it
|
|
37
|
+
* was given a certificate, never because of its number - see `--cert`/`--key` in the CLI, which
|
|
38
|
+
* moves to these ports when it is given the material and stays put when it is not.
|
|
39
|
+
*/
|
|
40
|
+
export declare const defaultSecureWebSocketPort: number;
|
|
41
|
+
export declare const defaultSecureWebPort: number;
|
|
42
|
+
export interface IManageRpc {
|
|
43
|
+
exposeClassInstance(instance: object, name?: string, options?: number | ExposeOptions): void;
|
|
44
|
+
exposeClass<T>(constructor: new (...args: unknown[]) => T, aliasName?: string): void;
|
|
45
|
+
exposeObject(obj: object, name: string): void;
|
|
46
|
+
expose(methodName: string, method: () => void): void;
|
|
47
|
+
createRpcInstance(className: string, instanceName?: string, ...args: unknown[]): Promise<string | undefined>;
|
|
48
|
+
}
|
|
49
|
+
export declare const isEventFunction: (prop: string) => prop is "addListener" | "emit" | "getMaxListeners" | "off" | "on" | "once" | "prependListener" | "prependOnceListener" | "removeAllListeners" | "removeListener" | "setMaxListeners";
|
|
50
|
+
export declare const isPromiseFunction: (prop: string) => prop is "catch" | "then";
|
|
51
|
+
//# sourceMappingURL=Rpc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Rpc.d.ts","sourceRoot":"","sources":["../../src/RPC/Rpc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAE1D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,OAAO,CAAA;AAExC;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,QAA2B,CAAA;AAEtD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,0BAA0B,QAA8B,CAAA;AACrE,eAAO,MAAM,oBAAoB,QAAwB,CAAA;AAEzD,MAAM,WAAW,UAAU;IACvB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAAA;IAC5F,WAAW,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpF,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7C,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,GAAG,IAAI,CAAA;IACpD,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;CAC/G;AAED,eAAO,MAAM,eAAe,SAAU,MAAM,yLAYd,CAAA;AAE9B,eAAO,MAAM,iBAAiB,SAAU,MAAM,6BAAwC,CAAA"}
|
package/dist/RPC/Rpc.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Source RPC port. An unconfigured server listens here, an unconfigured client dials here, and
|
|
3
|
+
* `source-rpc broker` runs a bus here.
|
|
4
|
+
*
|
|
5
|
+
* Having one number rather than three is the whole of the argument: a well-known port is what lets
|
|
6
|
+
* `mqtt://broker:1883` and `http://bus:7843` both be written from memory, and what makes a port map
|
|
7
|
+
* in a compose file readable without a comment on each line.
|
|
8
|
+
*
|
|
9
|
+
* 7843 rather than anything in the 80xx range, which is where a developer's other work already
|
|
10
|
+
* lives - 8080, 8081, 8085 are taken on any machine that has been used for a while, and a default
|
|
11
|
+
* that collides on the laptop is a default nobody keeps. This is quiet ground: high enough to need
|
|
12
|
+
* no privilege, low enough to stay clear of the ephemeral range, and not the neighbour of anything
|
|
13
|
+
* that would be mistaken for it.
|
|
14
|
+
*/
|
|
15
|
+
export const defaultWebSocketPort = 7843;
|
|
16
|
+
/**
|
|
17
|
+
* Where anything that serves a browser puts its HTTP port. `source-rpc console` defaults here.
|
|
18
|
+
*
|
|
19
|
+
* Adjacent to the RPC port rather than derived by an offset: they are read together, and 7843/7844
|
|
20
|
+
* is one thing to remember. A single process needs only one of them - the console serves its page
|
|
21
|
+
* and its RPC on the same listener - so the second number is for running a bus and a console on one
|
|
22
|
+
* host, which is the ordinary case.
|
|
23
|
+
*/
|
|
24
|
+
export const defaultWebPort = defaultWebSocketPort + 1;
|
|
25
|
+
/**
|
|
26
|
+
* The same two services with TLS: `rpc-tls` and `console-tls`.
|
|
27
|
+
*
|
|
28
|
+
* A thousand above their plaintext counterparts, deliberately **not** adjacent to them. The last
|
|
29
|
+
* two digits still match, so 7843/8843 is one number to remember with a rule attached - but no
|
|
30
|
+
* range covers both, and `allow 7843:7846` is the rule somebody writes at the end of a long day. A
|
|
31
|
+
* firewall that meant to publish only the encrypted port should not be able to open the other one
|
|
32
|
+
* by fencepost. MQTT draws the same line for the same reason, 1883 against 8883, so the habit
|
|
33
|
+
* transfers.
|
|
34
|
+
*
|
|
35
|
+
* These say where to *find* a service, not what any process must do. A port carries TLS because it
|
|
36
|
+
* was given a certificate, never because of its number - see `--cert`/`--key` in the CLI, which
|
|
37
|
+
* moves to these ports when it is given the material and stays put when it is not.
|
|
38
|
+
*/
|
|
39
|
+
export const defaultSecureWebSocketPort = defaultWebSocketPort + 1000;
|
|
40
|
+
export const defaultSecureWebPort = defaultWebPort + 1000;
|
|
41
|
+
export const isEventFunction = (prop) => prop === 'on' ||
|
|
42
|
+
prop === 'addListener' ||
|
|
43
|
+
prop === 'prependListener' ||
|
|
44
|
+
prop === 'once' ||
|
|
45
|
+
prop === 'prependOnceListener' ||
|
|
46
|
+
prop === 'off' ||
|
|
47
|
+
prop === 'removeListener' ||
|
|
48
|
+
prop === 'emit' ||
|
|
49
|
+
prop === 'removeListener' ||
|
|
50
|
+
prop === 'removeAllListeners' ||
|
|
51
|
+
prop === 'setMaxListeners' ||
|
|
52
|
+
prop === 'getMaxListeners';
|
|
53
|
+
export const isPromiseFunction = (prop) => prop === 'then' || prop === 'catch';
|
|
54
|
+
//# sourceMappingURL=Rpc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Rpc.js","sourceRoot":"","sources":["../../src/RPC/Rpc.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAA;AAExC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,oBAAoB,GAAG,CAAC,CAAA;AAEtD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,oBAAoB,GAAG,IAAI,CAAA;AACrE,MAAM,CAAC,MAAM,oBAAoB,GAAG,cAAc,GAAG,IAAI,CAAA;AAUzD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAY,EAAE,EAAE,CAC5C,IAAI,KAAK,IAAI;IACb,IAAI,KAAK,aAAa;IACtB,IAAI,KAAK,iBAAiB;IAC1B,IAAI,KAAK,MAAM;IACf,IAAI,KAAK,qBAAqB;IAC9B,IAAI,KAAK,KAAK;IACd,IAAI,KAAK,gBAAgB;IACzB,IAAI,KAAK,MAAM;IACf,IAAI,KAAK,gBAAgB;IACzB,IAAI,KAAK,oBAAoB;IAC7B,IAAI,KAAK,iBAAiB;IAC1B,IAAI,KAAK,iBAAiB,CAAA;AAE9B,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,OAAO,CAAA"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { MessageModule, Message, GenericModule } from './Core.js';
|
|
2
|
+
import { RpcErrorCode, RpcMessage } from './RpcServerHandler.js';
|
|
3
|
+
export declare const defaultCallTimeout = 10000;
|
|
4
|
+
/**
|
|
5
|
+
* Identifies one subscription: which peer, which exposed instance, which event.
|
|
6
|
+
*
|
|
7
|
+
* Handlers used to be registered under the bare event name, so a client watching `alarm` on two
|
|
8
|
+
* namespaces - or on two peers over one MQTT transport - delivered each event to all of them. An
|
|
9
|
+
* empty source matches any peer, for a proxy created without a target.
|
|
10
|
+
*/
|
|
11
|
+
export declare const subscriptionKey: (source: string, namespace: string, event: string) => string;
|
|
12
|
+
export declare class RpcError extends Error {
|
|
13
|
+
code: RpcErrorCode;
|
|
14
|
+
/** Stack trace from the remote peer, when it sent one. */
|
|
15
|
+
remoteStack?: string | undefined;
|
|
16
|
+
constructor(code: RpcErrorCode, message?: string,
|
|
17
|
+
/** Stack trace from the remote peer, when it sent one. */
|
|
18
|
+
remoteStack?: string | undefined);
|
|
19
|
+
}
|
|
20
|
+
export interface RpcClientEmitter extends MessageModule<Message<RpcMessage>, RpcMessage, Message<RpcMessage>, RpcMessage> {
|
|
21
|
+
on(event: string, handler: (_event: string, params: unknown[]) => void): this;
|
|
22
|
+
emit(event: string, params: unknown[]): boolean;
|
|
23
|
+
removeListener(event: string, handler: (params: unknown[]) => void): this;
|
|
24
|
+
}
|
|
25
|
+
export type PromiseResolver<T> = {
|
|
26
|
+
resolve: (result: T) => void;
|
|
27
|
+
reject: (reason?: unknown) => void;
|
|
28
|
+
};
|
|
29
|
+
/** What a caller can say about one call that the library cannot work out for itself. */
|
|
30
|
+
export interface RpcCallOptions {
|
|
31
|
+
/**
|
|
32
|
+
* Names the command, so a second attempt at it is recognised as the same one.
|
|
33
|
+
*
|
|
34
|
+
* The case this exists for: an operator presses "start pump", the answer is `UnknownOutcome`,
|
|
35
|
+
* and they press it again. Without a key those are two commands and a server with a durable
|
|
36
|
+
* idempotency store will run both. With one they are two attempts at a command that runs once,
|
|
37
|
+
* and the second gets the first's answer.
|
|
38
|
+
*
|
|
39
|
+
* It has to come from whatever identifies the operator's intent - a work order, a batch step, a
|
|
40
|
+
* button press id. A value generated per attempt would defeat the purpose, since that is what
|
|
41
|
+
* the request id already is.
|
|
42
|
+
*/
|
|
43
|
+
idempotencyKey?: string;
|
|
44
|
+
}
|
|
45
|
+
/** A proxy with per-call options attached. See `$with` on a proxy. */
|
|
46
|
+
export type WithOptions<T> = {
|
|
47
|
+
$with(options: RpcCallOptions): T;
|
|
48
|
+
};
|
|
49
|
+
export declare class RpcClientHandler extends MessageModule<Message<RpcMessage>, RpcMessage, Message<RpcMessage>, RpcMessage> implements RpcClientEmitter {
|
|
50
|
+
callTimeout: number;
|
|
51
|
+
responsePromiseMap: Map<string, PromiseResolver<unknown>>;
|
|
52
|
+
responseTimeoutMap: Map<string, NodeJS.Timeout>;
|
|
53
|
+
/** Contract versions this client was built against, by namespace, declared on each call. */
|
|
54
|
+
schemaVersions?: {
|
|
55
|
+
[namespace: string]: string | undefined;
|
|
56
|
+
};
|
|
57
|
+
/** Remote subscriptions held by this client, replayed by resubscribe() after a reconnect. */
|
|
58
|
+
subscriptions: Map<string, {
|
|
59
|
+
remote?: string;
|
|
60
|
+
instanceName: string;
|
|
61
|
+
event: string;
|
|
62
|
+
}>;
|
|
63
|
+
eventEmitter: {
|
|
64
|
+
[index: string]: unknown;
|
|
65
|
+
};
|
|
66
|
+
constructor(name: string, sources?: GenericModule<unknown, unknown, Message, RpcMessage>[], callTimeout?: number);
|
|
67
|
+
receive(message: Message<RpcMessage>, source?: string, target?: string): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Routes an event to the handlers registered for that peer and that instance, rather than to
|
|
70
|
+
* everything listening for the name.
|
|
71
|
+
*/
|
|
72
|
+
private deliverEvent;
|
|
73
|
+
/**
|
|
74
|
+
* Run one subscriber without letting it unwind into the transport that delivered the event.
|
|
75
|
+
*
|
|
76
|
+
* These are application callbacks reached from a transport's inbound loop, so a handler that
|
|
77
|
+
* threw propagated all the way back out and became an unhandled rejection - one subscriber's
|
|
78
|
+
* bug ending the process for everything else the client was doing.
|
|
79
|
+
*/
|
|
80
|
+
private deliverSafely;
|
|
81
|
+
/**
|
|
82
|
+
* Re-issue every remote subscription this client holds. Called after the transport reconnects:
|
|
83
|
+
* if the server kept its state the calls are no-ops on its side, and if the server restarted
|
|
84
|
+
* they rebuild it. Either way the outgoing frames re-identify this client to the server, which
|
|
85
|
+
* is what makes server-pushed events addressable again.
|
|
86
|
+
*/
|
|
87
|
+
resubscribe(): Promise<number>;
|
|
88
|
+
/**
|
|
89
|
+
* Reject every in-flight call. A reply to a call that was in flight when the link dropped can
|
|
90
|
+
* no longer reach us, so failing now beats making every caller wait out the full timeout.
|
|
91
|
+
*
|
|
92
|
+
* How it failed depends on whether the request got out. One that never left cannot have run, and
|
|
93
|
+
* `TransportError` says so; one that was published and never answered may have run, and only
|
|
94
|
+
* `UnknownOutcome` is true of it. Reporting both the same way was the library telling callers
|
|
95
|
+
* that a command had failed when what it knew was that it had lost track of it.
|
|
96
|
+
*/
|
|
97
|
+
failPendingCalls(reason: string): void;
|
|
98
|
+
/**
|
|
99
|
+
* Requests this client handed to a transport without it complaining.
|
|
100
|
+
*
|
|
101
|
+
* Not proof of delivery - nothing here can have that - but proof that the frame left, which is
|
|
102
|
+
* the line between a command that certainly did not run and one that might have.
|
|
103
|
+
*/
|
|
104
|
+
private sentRequests;
|
|
105
|
+
/** Detach a pending call and cancel its timeout. Returns undefined if it already settled. */
|
|
106
|
+
private takePending;
|
|
107
|
+
/**
|
|
108
|
+
* Call a method on the RPC server.
|
|
109
|
+
* @param method The method to call.
|
|
110
|
+
* @param additionalParameter The (optional) additionalParameter to include. See the JsonRpc class for more details.
|
|
111
|
+
* @param params
|
|
112
|
+
*/
|
|
113
|
+
call(remote: string | undefined, instanceName: string, method: string, ...params: unknown[]): Promise<unknown>;
|
|
114
|
+
/**
|
|
115
|
+
* Call with per-call options. `call` is this with none.
|
|
116
|
+
*
|
|
117
|
+
* The only option so far is the idempotency key, which is the one thing a caller can say that
|
|
118
|
+
* the library cannot work out for itself: whether this is a new command or another go at one it
|
|
119
|
+
* has already sent.
|
|
120
|
+
*/
|
|
121
|
+
callWith(options: RpcCallOptions, remote: string | undefined, instanceName: string, method: string, ...params: unknown[]): Promise<unknown>;
|
|
122
|
+
/**
|
|
123
|
+
* Create a proxy object - a sort of wrapper for calling methods and listening for events.
|
|
124
|
+
* @param name Name of an existing instance on the server instance. If in the form "name: Class" an instance of type Class will be created
|
|
125
|
+
* on the server if it does not already exist.
|
|
126
|
+
*/
|
|
127
|
+
proxy<T>(name: string, remote?: string, options?: RpcCallOptions): T & WithOptions<T>;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=RpcClientHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RpcClientHandler.d.ts","sourceRoot":"","sources":["../../src/RPC/RpcClientHandler.ts"],"names":[],"mappings":"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"}
|