@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.
Files changed (124) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1208 -0
  3. package/dist/Logging/ILogger.d.ts +7 -0
  4. package/dist/Logging/ILogger.d.ts.map +1 -0
  5. package/dist/Logging/ILogger.js +2 -0
  6. package/dist/Logging/ILogger.js.map +1 -0
  7. package/dist/NodeRpcServer.d.ts +55 -0
  8. package/dist/NodeRpcServer.d.ts.map +1 -0
  9. package/dist/NodeRpcServer.js +46 -0
  10. package/dist/NodeRpcServer.js.map +1 -0
  11. package/dist/RPC/Auth.d.ts +98 -0
  12. package/dist/RPC/Auth.d.ts.map +1 -0
  13. package/dist/RPC/Auth.js +14 -0
  14. package/dist/RPC/Auth.js.map +1 -0
  15. package/dist/RPC/Codec.d.ts +24 -0
  16. package/dist/RPC/Codec.d.ts.map +1 -0
  17. package/dist/RPC/Codec.js +21 -0
  18. package/dist/RPC/Codec.js.map +1 -0
  19. package/dist/RPC/Compatibility.d.ts +39 -0
  20. package/dist/RPC/Compatibility.d.ts.map +1 -0
  21. package/dist/RPC/Compatibility.js +195 -0
  22. package/dist/RPC/Compatibility.js.map +1 -0
  23. package/dist/RPC/Core.d.ts +188 -0
  24. package/dist/RPC/Core.d.ts.map +1 -0
  25. package/dist/RPC/Core.js +354 -0
  26. package/dist/RPC/Core.js.map +1 -0
  27. package/dist/RPC/Expose.d.ts +90 -0
  28. package/dist/RPC/Expose.d.ts.map +1 -0
  29. package/dist/RPC/Expose.js +110 -0
  30. package/dist/RPC/Expose.js.map +1 -0
  31. package/dist/RPC/Idempotency.d.ts +90 -0
  32. package/dist/RPC/Idempotency.d.ts.map +1 -0
  33. package/dist/RPC/Idempotency.js +46 -0
  34. package/dist/RPC/Idempotency.js.map +1 -0
  35. package/dist/RPC/Introspection.d.ts +92 -0
  36. package/dist/RPC/Introspection.d.ts.map +1 -0
  37. package/dist/RPC/Introspection.js +188 -0
  38. package/dist/RPC/Introspection.js.map +1 -0
  39. package/dist/RPC/Introspection.types.json +1093 -0
  40. package/dist/RPC/Messages.d.ts +108 -0
  41. package/dist/RPC/Messages.d.ts.map +1 -0
  42. package/dist/RPC/Messages.js +30 -0
  43. package/dist/RPC/Messages.js.map +1 -0
  44. package/dist/RPC/Rpc.d.ts +51 -0
  45. package/dist/RPC/Rpc.d.ts.map +1 -0
  46. package/dist/RPC/Rpc.js +54 -0
  47. package/dist/RPC/Rpc.js.map +1 -0
  48. package/dist/RPC/RpcClientHandler.d.ts +129 -0
  49. package/dist/RPC/RpcClientHandler.d.ts.map +1 -0
  50. package/dist/RPC/RpcClientHandler.js +267 -0
  51. package/dist/RPC/RpcClientHandler.js.map +1 -0
  52. package/dist/RPC/RpcServerHandler.d.ts +226 -0
  53. package/dist/RPC/RpcServerHandler.d.ts.map +1 -0
  54. package/dist/RPC/RpcServerHandler.js +676 -0
  55. package/dist/RPC/RpcServerHandler.js.map +1 -0
  56. package/dist/RPC/Schema.d.ts +150 -0
  57. package/dist/RPC/Schema.d.ts.map +1 -0
  58. package/dist/RPC/Schema.js +198 -0
  59. package/dist/RPC/Schema.js.map +1 -0
  60. package/dist/RPC/Signing.d.ts +118 -0
  61. package/dist/RPC/Signing.d.ts.map +1 -0
  62. package/dist/RPC/Signing.js +171 -0
  63. package/dist/RPC/Signing.js.map +1 -0
  64. package/dist/RPC/Tokens.d.ts +49 -0
  65. package/dist/RPC/Tokens.d.ts.map +1 -0
  66. package/dist/RPC/Tokens.js +45 -0
  67. package/dist/RPC/Tokens.js.map +1 -0
  68. package/dist/RpcClient.d.ts +91 -0
  69. package/dist/RpcClient.d.ts.map +1 -0
  70. package/dist/RpcClient.js +145 -0
  71. package/dist/RpcClient.js.map +1 -0
  72. package/dist/RpcServer.d.ts +191 -0
  73. package/dist/RpcServer.d.ts.map +1 -0
  74. package/dist/RpcServer.js +293 -0
  75. package/dist/RpcServer.js.map +1 -0
  76. package/dist/Transports/Mqtt5Frame.d.ts +107 -0
  77. package/dist/Transports/Mqtt5Frame.d.ts.map +1 -0
  78. package/dist/Transports/Mqtt5Frame.js +162 -0
  79. package/dist/Transports/Mqtt5Frame.js.map +1 -0
  80. package/dist/Transports/MqttTransport.d.ts +279 -0
  81. package/dist/Transports/MqttTransport.d.ts.map +1 -0
  82. package/dist/Transports/MqttTransport.js +843 -0
  83. package/dist/Transports/MqttTransport.js.map +1 -0
  84. package/dist/Transports/Presence.d.ts +68 -0
  85. package/dist/Transports/Presence.d.ts.map +1 -0
  86. package/dist/Transports/Presence.js +21 -0
  87. package/dist/Transports/Presence.js.map +1 -0
  88. package/dist/Transports/SocketIoClientTransport.d.ts +89 -0
  89. package/dist/Transports/SocketIoClientTransport.d.ts.map +1 -0
  90. package/dist/Transports/SocketIoClientTransport.js +280 -0
  91. package/dist/Transports/SocketIoClientTransport.js.map +1 -0
  92. package/dist/Transports/SocketIoServerTransport.d.ts +135 -0
  93. package/dist/Transports/SocketIoServerTransport.d.ts.map +1 -0
  94. package/dist/Transports/SocketIoServerTransport.js +505 -0
  95. package/dist/Transports/SocketIoServerTransport.js.map +1 -0
  96. package/dist/Utilities/Converters.d.ts +22 -0
  97. package/dist/Utilities/Converters.d.ts.map +1 -0
  98. package/dist/Utilities/Converters.js +58 -0
  99. package/dist/Utilities/Converters.js.map +1 -0
  100. package/dist/Utilities/Filter.d.ts +7 -0
  101. package/dist/Utilities/Filter.d.ts.map +1 -0
  102. package/dist/Utilities/Filter.js +14 -0
  103. package/dist/Utilities/Filter.js.map +1 -0
  104. package/dist/Utilities/ReadableName.d.ts +38 -0
  105. package/dist/Utilities/ReadableName.d.ts.map +1 -0
  106. package/dist/Utilities/ReadableName.js +58 -0
  107. package/dist/Utilities/ReadableName.js.map +1 -0
  108. package/dist/Utilities/Switch.d.ts +21 -0
  109. package/dist/Utilities/Switch.d.ts.map +1 -0
  110. package/dist/Utilities/Switch.js +70 -0
  111. package/dist/Utilities/Switch.js.map +1 -0
  112. package/dist/Utilities/TryCatch.d.ts +11 -0
  113. package/dist/Utilities/TryCatch.d.ts.map +1 -0
  114. package/dist/Utilities/TryCatch.js +13 -0
  115. package/dist/Utilities/TryCatch.js.map +1 -0
  116. package/dist/index-web.d.ts +25 -0
  117. package/dist/index-web.d.ts.map +1 -0
  118. package/dist/index-web.js +28 -0
  119. package/dist/index-web.js.map +1 -0
  120. package/dist/index.d.ts +28 -0
  121. package/dist/index.d.ts.map +1 -0
  122. package/dist/index.js +30 -0
  123. package/dist/index.js.map +1 -0
  124. package/package.json +77 -0
@@ -0,0 +1,188 @@
1
+ import { EventEmitter } from 'events';
2
+ import { RpcIdentity } from './Auth.js';
3
+ import { FrameCodec } from './Codec.js';
4
+ /**
5
+ * Upper bound on the framed header, in bytes, including the delimiter.
6
+ *
7
+ * It has to fit the largest header this library builds: two 128-character peer names, a timestamp,
8
+ * a sequence number, a hop count, a 24-character nonce and an 88-character Ed25519 signature come
9
+ * to roughly 470 bytes. The old value of 256 was under that, and since the receiver stopped looking
10
+ * for the delimiter at the limit, every frame with a header past it was dropped without a word -
11
+ * signed frames from peers whose names were merely descriptive, at around 34 characters each.
12
+ */
13
+ export declare const MAX_HEADER_LENGTH = 1024;
14
+ export declare const HEADER_DELIMITER = "$";
15
+ /**
16
+ * Lifecycle events emitted by transports. Transports are EventEmitters, so anything above them
17
+ * can react to the link coming and going rather than discovering it via a call timeout.
18
+ *
19
+ * connected/disconnected are emitted by client-side transports on every transition, including
20
+ * reconnects. peerGone is emitted by server-side transports when an identified peer's connection
21
+ * drops, and peerOnline when one announces itself, which is how a peer is discovered at all.
22
+ * rejected is emitted when an inbound frame fails an authentication check. unroutable is emitted
23
+ * when a frame cannot be delivered to its target. peerDisplaced is emitted when a new connection
24
+ * announces a name another live connection already holds, and takes the route over.
25
+ *
26
+ * relayed is the one that is not about the link: it reports a frame this server is passing between
27
+ * two other peers, which is the only place traffic nobody here sent or received can be observed.
28
+ * It fires once per relayed frame, so it is emitted only when something is listening - see the
29
+ * guard at the call site.
30
+ */
31
+ export declare const TransportEvent: {
32
+ readonly connected: 'connected';
33
+ readonly disconnected: 'disconnected';
34
+ readonly peerOnline: 'peerOnline';
35
+ readonly peerGone: 'peerGone';
36
+ readonly peerDisplaced: 'peerDisplaced';
37
+ readonly rejected: 'rejected';
38
+ readonly unroutable: 'unroutable';
39
+ readonly transportError: 'transportError';
40
+ readonly relayed: 'relayed';
41
+ };
42
+ /** A frame passing through this server on its way between two other peers. */
43
+ export interface RelayedFrame {
44
+ source: string;
45
+ target: string;
46
+ message: Message;
47
+ }
48
+ export interface IGenericModule<I = unknown, IP = unknown, O = unknown, OP = unknown> {
49
+ readyFlag: boolean;
50
+ pipe(target: IGenericModule): void;
51
+ receive(message: I, source: string, target?: string): Promise<void>;
52
+ receivePayload(payload: IP, source: string, target?: string): Promise<void>;
53
+ send(message: O, source: string, target?: string): Promise<void>;
54
+ sendPayload(payload: OP, messageType: MessageType, source: string, target?: string): Promise<void>;
55
+ ready(): Promise<boolean>;
56
+ getName(): string;
57
+ targetExists(name: string, level?: number): IGenericModule | undefined;
58
+ isTransport(): boolean;
59
+ close(): Promise<void>;
60
+ }
61
+ /**
62
+ * Which module a peer name was last seen on, so a reply can be routed back out of the transport
63
+ * its request arrived on.
64
+ *
65
+ * This was a static on GenericModule, which meant every client and server in one process shared a
66
+ * single map keyed by names supplied by remote peers. Two graphs using the same peer name routed
67
+ * into each other's transports, entries were never removed, and it grew for the life of the
68
+ * process. One registry is now shared by one connected set of modules and nothing wider.
69
+ */
70
+ export declare class PeerRegistry {
71
+ /** Upper bound, since the keys come off the wire. Least recently seen entries go first. */
72
+ maxPeers: number;
73
+ private peers;
74
+ constructor(
75
+ /** Upper bound, since the keys come off the wire. Least recently seen entries go first. */
76
+ maxPeers?: number);
77
+ set(source: string, module: IGenericModule): void;
78
+ get(source: string): IGenericModule<unknown, unknown, unknown, unknown> | undefined;
79
+ delete(source: string): boolean;
80
+ clear(): void;
81
+ get size(): number;
82
+ /** Every peer currently routed through one module, which is how a bridge lists what it can reach. */
83
+ namesFor(module: IGenericModule): string[];
84
+ names(): string[];
85
+ }
86
+ /**
87
+ * A module that owns its wire format. RpcClient and RpcServer drive these directly rather than
88
+ * through a converter, so a transport whose framing is structured can see the message itself.
89
+ */
90
+ export type Transport = GenericModule<Message, unknown, Message, unknown> & {
91
+ codec: FrameCodec;
92
+ };
93
+ export interface MessageHeader {
94
+ source: string;
95
+ target: string;
96
+ time: number;
97
+ seq: number;
98
+ /** How many relays this frame has already passed through. Absent means none. */
99
+ hops?: number;
100
+ /** Present on signed frames: single-use value that makes a captured frame unreplayable. */
101
+ nonce?: string;
102
+ /** Present on signed frames: base64 signature over the fields above plus the payload. */
103
+ sig?: string;
104
+ }
105
+ export declare class GenericModule<I = unknown, IP = unknown, O = unknown, OP = unknown> extends EventEmitter implements IGenericModule<I, IP, O, OP> {
106
+ name: string;
107
+ destinations: {
108
+ id: string;
109
+ target: IGenericModule;
110
+ }[];
111
+ /**
112
+ * Shared with the other modules in this graph by usePeerRegistry(). A module built on its own
113
+ * gets a private one, so it still routes correctly without leaking into anyone else's.
114
+ */
115
+ peerRegistry: PeerRegistry;
116
+ readyFlag: boolean;
117
+ seq: number;
118
+ constructor(name: string, sources?: IGenericModule<unknown, unknown, I, IP>[]);
119
+ /**
120
+ * Waits for this module to come up, and gives up rather than waiting forever.
121
+ *
122
+ * The loop used to have no way out: a module that never became ready - one that failed to
123
+ * start, or was closed while something still awaited it - spun on a 10 ms timer for the life of
124
+ * the process, which is also long enough to keep the process alive with nothing left to do.
125
+ * Returning false says what happened; the overrides in RpcClient and RpcServer throw with the
126
+ * startup error instead, which is more than a bare module knows.
127
+ */
128
+ ready(timeout?: number): Promise<boolean>;
129
+ open(): Promise<void>;
130
+ close(): Promise<void>;
131
+ /**
132
+ * Build the header a frame will carry. Separate from framing so a transport that signs can
133
+ * see the exact field values before they are serialised, and add its signature to them.
134
+ */
135
+ buildHeader(source: string, target: string, extra?: Partial<MessageHeader>): MessageHeader;
136
+ prependHeader(source: string, target: string, message: string | Uint8Array): string | Uint8Array;
137
+ /**
138
+ * Throws when the header will not fit the frame, rather than emitting one no receiver can read.
139
+ * The sender is the only party that can do anything about an over-long peer name, and it learns
140
+ * nothing from a frame that leaves correctly and is discarded at the far end.
141
+ */
142
+ frameMessage(header: MessageHeader, message: string | Uint8Array): string | Uint8Array;
143
+ /**
144
+ * Split a frame into its header and payload. Never throws: every frame here came off the
145
+ * network, and one malformed frame from one peer must not take down a process serving the rest.
146
+ * The third element says why nothing was extracted, so a dropped frame can be diagnosed instead
147
+ * of merely disappearing.
148
+ */
149
+ extractHeader(message: string | Uint8Array): [MessageHeader | undefined, string | Uint8Array, string?];
150
+ getName(): string;
151
+ targetExists(name: string, level?: number): IGenericModule<unknown, unknown, unknown, unknown> | undefined;
152
+ pipe(target: IGenericModule<O, OP, unknown, unknown>): () => void;
153
+ receive(message: I, source: string, target: string): Promise<void>;
154
+ receivePayload(message: IP, source: string, target: string): Promise<void>;
155
+ send(message: O, source: string, target: string): Promise<void>;
156
+ setKnownSource(source: string): void;
157
+ /** Route peer lookups for this module through a registry shared with the rest of its graph. */
158
+ usePeerRegistry(registry: PeerRegistry): this;
159
+ /**
160
+ * The authenticated identity bound to a peer name, for transports that authenticate.
161
+ * Undefined means this transport cannot vouch for the peer, not that the peer is untrusted.
162
+ */
163
+ getIdentity(source: string): RpcIdentity | undefined;
164
+ sendPayload(payload: OP, messageType: MessageType, source: string, target: string): Promise<void>;
165
+ isTransport(): boolean;
166
+ }
167
+ export declare enum MessageType {
168
+ RequestMessage = "REQUEST",
169
+ ResponseMessage = "RESPONSE",
170
+ ErrorMessage = "ERROR",
171
+ EventMessage = "EVENT",
172
+ UnknownMessage = "UNKNOWN"
173
+ }
174
+ export interface Payload {
175
+ }
176
+ export declare class Message<P = Payload> {
177
+ type?: MessageType;
178
+ payload?: P;
179
+ }
180
+ export declare class MessageModule<I extends Message<IP>, IP extends Payload, O extends Message<OP>, OP extends Payload> extends GenericModule<I, IP, O, OP> {
181
+ name: string;
182
+ constructor(name: string, sources?: IGenericModule<Message, unknown, I, IP>[]);
183
+ pipe(target: IGenericModule<O, OP, Message, unknown>): () => void;
184
+ receive(message: I, source: string, target: string): Promise<void>;
185
+ send(message: O, source: string, target?: string): Promise<void>;
186
+ sendPayload(payload: OP, messageType: MessageType, source: string, target?: string): Promise<void>;
187
+ }
188
+ //# sourceMappingURL=Core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Core.d.ts","sourceRoot":"","sources":["../../src/RPC/Core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,354 @@
1
+ import { EventEmitter } from 'events';
2
+ import { stringToUint8Array, uint8ArrayToString } from 'uint8array-extras';
3
+ import { v4 as uuidv4 } from 'uuid';
4
+ /**
5
+ * Upper bound on the framed header, in bytes, including the delimiter.
6
+ *
7
+ * It has to fit the largest header this library builds: two 128-character peer names, a timestamp,
8
+ * a sequence number, a hop count, a 24-character nonce and an 88-character Ed25519 signature come
9
+ * to roughly 470 bytes. The old value of 256 was under that, and since the receiver stopped looking
10
+ * for the delimiter at the limit, every frame with a header past it was dropped without a word -
11
+ * signed frames from peers whose names were merely descriptive, at around 34 characters each.
12
+ */
13
+ export const MAX_HEADER_LENGTH = 1024;
14
+ export const HEADER_DELIMITER = '$';
15
+ const CHAR = { openBrace: 0x7b, closeBrace: 0x7d, quote: 0x22, backslash: 0x5c, delimiter: 0x24 };
16
+ /**
17
+ * Index of the delimiter that ends the header, or -1 when there is no header to be found.
18
+ *
19
+ * Deliberately not indexOf('$'): the header is JSON, and a peer name containing a '$' puts one
20
+ * inside a quoted string where it is data rather than punctuation. Splitting on the first one cut
21
+ * the header mid-string, and the JSON.parse that followed threw - on the MQTT path, into an
22
+ * unhandled rejection. Reading with JSON's own quoting rules makes the split unambiguous, so a name
23
+ * can never reshape the frame it travels in.
24
+ *
25
+ * Scans code units rather than decoded text because every character it looks for is ASCII, and
26
+ * UTF-8 never produces those bytes inside a multi-byte sequence. A payload cut mid-character
27
+ * therefore cannot confuse it, which the previous decode-the-first-256-bytes approach could.
28
+ */
29
+ const findHeaderEnd = (at, length) => {
30
+ if (length === 0 || at(0) !== CHAR.openBrace)
31
+ return -1;
32
+ const limit = Math.min(length, MAX_HEADER_LENGTH);
33
+ let depth = 0;
34
+ let inString = false;
35
+ let escaped = false;
36
+ for (let index = 0; index < limit; index++) {
37
+ const code = at(index);
38
+ if (inString) {
39
+ if (escaped)
40
+ escaped = false;
41
+ else if (code === CHAR.backslash)
42
+ escaped = true;
43
+ else if (code === CHAR.quote)
44
+ inString = false;
45
+ continue;
46
+ }
47
+ if (code === CHAR.quote)
48
+ inString = true;
49
+ else if (code === CHAR.openBrace)
50
+ depth++;
51
+ else if (code === CHAR.closeBrace && --depth === 0) {
52
+ // The delimiter has to be the very next byte, or this is not a framed message.
53
+ const delimiter = index + 1;
54
+ return delimiter < limit && at(delimiter) === CHAR.delimiter ? delimiter : -1;
55
+ }
56
+ }
57
+ return -1;
58
+ };
59
+ /**
60
+ * Lifecycle events emitted by transports. Transports are EventEmitters, so anything above them
61
+ * can react to the link coming and going rather than discovering it via a call timeout.
62
+ *
63
+ * connected/disconnected are emitted by client-side transports on every transition, including
64
+ * reconnects. peerGone is emitted by server-side transports when an identified peer's connection
65
+ * drops, and peerOnline when one announces itself, which is how a peer is discovered at all.
66
+ * rejected is emitted when an inbound frame fails an authentication check. unroutable is emitted
67
+ * when a frame cannot be delivered to its target. peerDisplaced is emitted when a new connection
68
+ * announces a name another live connection already holds, and takes the route over.
69
+ *
70
+ * relayed is the one that is not about the link: it reports a frame this server is passing between
71
+ * two other peers, which is the only place traffic nobody here sent or received can be observed.
72
+ * It fires once per relayed frame, so it is emitted only when something is listening - see the
73
+ * guard at the call site.
74
+ */
75
+ export const TransportEvent = {
76
+ connected: 'connected',
77
+ disconnected: 'disconnected',
78
+ peerOnline: 'peerOnline',
79
+ peerGone: 'peerGone',
80
+ peerDisplaced: 'peerDisplaced',
81
+ rejected: 'rejected',
82
+ unroutable: 'unroutable',
83
+ transportError: 'transportError',
84
+ relayed: 'relayed'
85
+ };
86
+ /**
87
+ * Which module a peer name was last seen on, so a reply can be routed back out of the transport
88
+ * its request arrived on.
89
+ *
90
+ * This was a static on GenericModule, which meant every client and server in one process shared a
91
+ * single map keyed by names supplied by remote peers. Two graphs using the same peer name routed
92
+ * into each other's transports, entries were never removed, and it grew for the life of the
93
+ * process. One registry is now shared by one connected set of modules and nothing wider.
94
+ */
95
+ export class PeerRegistry {
96
+ maxPeers;
97
+ peers = new Map();
98
+ constructor(
99
+ /** Upper bound, since the keys come off the wire. Least recently seen entries go first. */
100
+ maxPeers = 10000) {
101
+ this.maxPeers = maxPeers;
102
+ }
103
+ set(source, module) {
104
+ // Re-inserting moves the entry to the end, which is what makes eviction least-recent-first.
105
+ this.peers.delete(source);
106
+ this.peers.set(source, module);
107
+ while (this.peers.size > this.maxPeers) {
108
+ const oldest = this.peers.keys().next();
109
+ if (oldest.done)
110
+ break;
111
+ this.peers.delete(oldest.value);
112
+ }
113
+ }
114
+ get(source) {
115
+ return this.peers.get(source);
116
+ }
117
+ delete(source) {
118
+ return this.peers.delete(source);
119
+ }
120
+ clear() {
121
+ this.peers.clear();
122
+ }
123
+ get size() {
124
+ return this.peers.size;
125
+ }
126
+ /** Every peer currently routed through one module, which is how a bridge lists what it can reach. */
127
+ namesFor(module) {
128
+ const result = [];
129
+ for (const [name, carrier] of this.peers)
130
+ if (carrier === module)
131
+ result.push(name);
132
+ return result;
133
+ }
134
+ names() {
135
+ return [...this.peers.keys()];
136
+ }
137
+ }
138
+ export class GenericModule extends EventEmitter {
139
+ name;
140
+ destinations = [];
141
+ /**
142
+ * Shared with the other modules in this graph by usePeerRegistry(). A module built on its own
143
+ * gets a private one, so it still routes correctly without leaking into anyone else's.
144
+ */
145
+ peerRegistry = new PeerRegistry();
146
+ readyFlag = false;
147
+ seq = 0;
148
+ constructor(name, sources) {
149
+ super();
150
+ this.name = name;
151
+ if (!name)
152
+ this.name = uuidv4();
153
+ if (sources) {
154
+ sources.forEach((src) => {
155
+ src.pipe(this);
156
+ });
157
+ }
158
+ }
159
+ /**
160
+ * Waits for this module to come up, and gives up rather than waiting forever.
161
+ *
162
+ * The loop used to have no way out: a module that never became ready - one that failed to
163
+ * start, or was closed while something still awaited it - spun on a 10 ms timer for the life of
164
+ * the process, which is also long enough to keep the process alive with nothing left to do.
165
+ * Returning false says what happened; the overrides in RpcClient and RpcServer throw with the
166
+ * startup error instead, which is more than a bare module knows.
167
+ */
168
+ async ready(timeout = 30000) {
169
+ const deadline = Date.now() + timeout;
170
+ while (!this.readyFlag) {
171
+ if (Date.now() > deadline)
172
+ return false;
173
+ await new Promise((res) => setTimeout(res, 10));
174
+ }
175
+ return true;
176
+ }
177
+ async open() { }
178
+ async close() { }
179
+ /**
180
+ * Build the header a frame will carry. Separate from framing so a transport that signs can
181
+ * see the exact field values before they are serialised, and add its signature to them.
182
+ */
183
+ buildHeader(source, target, extra) {
184
+ return { source, target, time: Date.now(), seq: this.seq++, ...extra };
185
+ }
186
+ prependHeader(source, target, message) {
187
+ return this.frameMessage(this.buildHeader(source, target), message);
188
+ }
189
+ /**
190
+ * Throws when the header will not fit the frame, rather than emitting one no receiver can read.
191
+ * The sender is the only party that can do anything about an over-long peer name, and it learns
192
+ * nothing from a frame that leaves correctly and is discarded at the far end.
193
+ */
194
+ frameMessage(header, message) {
195
+ const headerText = JSON.stringify(header) + HEADER_DELIMITER;
196
+ const headerBuffer = stringToUint8Array(headerText);
197
+ if (headerBuffer.length > MAX_HEADER_LENGTH)
198
+ throw new Error(`message header is ${headerBuffer.length} bytes, over the ${MAX_HEADER_LENGTH} byte limit ` +
199
+ `(source '${header.source}', target '${header.target}') - shorten the peer names`);
200
+ if (typeof message === 'string')
201
+ return headerText + message;
202
+ const result = new Uint8Array(headerBuffer.length + message.length);
203
+ result.set(headerBuffer, 0);
204
+ result.set(message, headerBuffer.length);
205
+ return result;
206
+ }
207
+ /**
208
+ * Split a frame into its header and payload. Never throws: every frame here came off the
209
+ * network, and one malformed frame from one peer must not take down a process serving the rest.
210
+ * The third element says why nothing was extracted, so a dropped frame can be diagnosed instead
211
+ * of merely disappearing.
212
+ */
213
+ extractHeader(message) {
214
+ const isText = typeof message === 'string';
215
+ const end = isText
216
+ ? findHeaderEnd((index) => message.charCodeAt(index), message.length)
217
+ : findHeaderEnd((index) => message[index], message.length);
218
+ if (end < 0)
219
+ return [undefined, '', 'no msgrpc header'];
220
+ const headerText = isText ? message.substring(0, end) : uint8ArrayToString(message.subarray(0, end));
221
+ let header;
222
+ try {
223
+ header = JSON.parse(headerText);
224
+ }
225
+ catch (e) {
226
+ return [undefined, '', `unparsable header: ${String(e)}`];
227
+ }
228
+ if (!header || typeof header !== 'object')
229
+ return [undefined, '', 'header is not an object'];
230
+ if (typeof header.target !== 'string' || !header.target)
231
+ return [undefined, '', 'header names no target'];
232
+ if (typeof header.source !== 'string' || !header.source)
233
+ return [undefined, '', 'header names no source'];
234
+ const start = end + HEADER_DELIMITER.length;
235
+ // Copied rather than viewed: the MQTT path hands us a view over a pooled Node Buffer, which
236
+ // is reused for the next packet the moment this one returns.
237
+ const payload = isText ? message.substring(start) : message.slice(start);
238
+ this.setKnownSource(header.source);
239
+ return [header, payload];
240
+ }
241
+ getName() {
242
+ return this.name;
243
+ }
244
+ targetExists(name, level) {
245
+ let result;
246
+ if (this.name === name) {
247
+ result = this;
248
+ }
249
+ const knownPeer = this.peerRegistry.get(name);
250
+ if (knownPeer)
251
+ result = knownPeer;
252
+ if (!result) {
253
+ this.destinations.map((dest) => {
254
+ if (!result && !dest.target.isTransport() && dest.target.targetExists(name, (level ? level : 0) + 1))
255
+ result = dest.target;
256
+ });
257
+ }
258
+ return result;
259
+ }
260
+ pipe(target) {
261
+ const id = uuidv4();
262
+ this.destinations.push({ id, target });
263
+ return () => {
264
+ this.destinations = this.destinations.filter((el) => el.id !== id);
265
+ };
266
+ }
267
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
268
+ async receive(message, source, target) {
269
+ return;
270
+ }
271
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
272
+ async receivePayload(message, source, target) {
273
+ return;
274
+ }
275
+ async send(message, source, target) {
276
+ await Promise.all(this.destinations.map(async (dest) => {
277
+ return await dest.target.receive(message, source, target);
278
+ }));
279
+ }
280
+ setKnownSource(source) {
281
+ this.peerRegistry.set(source, this);
282
+ }
283
+ /** Route peer lookups for this module through a registry shared with the rest of its graph. */
284
+ usePeerRegistry(registry) {
285
+ this.peerRegistry = registry;
286
+ return this;
287
+ }
288
+ /**
289
+ * The authenticated identity bound to a peer name, for transports that authenticate.
290
+ * Undefined means this transport cannot vouch for the peer, not that the peer is untrusted.
291
+ */
292
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
293
+ getIdentity(source) {
294
+ return undefined;
295
+ }
296
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
297
+ async sendPayload(payload, messageType, source, target) { }
298
+ isTransport() {
299
+ return false;
300
+ }
301
+ }
302
+ export var MessageType;
303
+ (function (MessageType) {
304
+ MessageType["RequestMessage"] = "REQUEST";
305
+ MessageType["ResponseMessage"] = "RESPONSE";
306
+ MessageType["ErrorMessage"] = "ERROR";
307
+ MessageType["EventMessage"] = "EVENT";
308
+ MessageType["UnknownMessage"] = "UNKNOWN";
309
+ })(MessageType || (MessageType = {}));
310
+ export class Message {
311
+ type;
312
+ payload;
313
+ }
314
+ const makeMessage = (payload, source, target, messageType) => {
315
+ const result = new Message();
316
+ result.type = messageType ? messageType : MessageType.UnknownMessage;
317
+ result.payload = payload;
318
+ return result;
319
+ };
320
+ export class MessageModule extends GenericModule {
321
+ name;
322
+ constructor(name, sources) {
323
+ super(name);
324
+ this.name = name;
325
+ if (!name)
326
+ this.name = uuidv4();
327
+ if (sources) {
328
+ sources.forEach((src) => {
329
+ src.pipe(this);
330
+ });
331
+ }
332
+ }
333
+ pipe(target) {
334
+ const id = uuidv4();
335
+ this.destinations.push({ id, target });
336
+ return () => {
337
+ this.destinations = this.destinations.filter((el) => el.id !== id);
338
+ };
339
+ }
340
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
341
+ receive(message, source, target) {
342
+ return Promise.resolve();
343
+ }
344
+ async send(message, source, target) {
345
+ await Promise.all(this.destinations.map(async (dest) => {
346
+ return await dest.target.receive(message, source, target);
347
+ }));
348
+ }
349
+ async sendPayload(payload, messageType, source, target) {
350
+ const message = makeMessage(payload, this.name, target, messageType);
351
+ await this.send(message, source, target);
352
+ }
353
+ }
354
+ //# sourceMappingURL=Core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Core.js","sourceRoot":"","sources":["../../src/RPC/Core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ import type { RpcCallContext } from './Auth.js';
2
+ import type { RpcMethodSemantics } from './Messages.js';
3
+ /**
4
+ * How calls into one exposed instance may overlap.
5
+ *
6
+ * `parallel` is the default and has always been the behaviour: calls run as they arrive, which is
7
+ * right for stateless services and for unrelated devices behind one server. It is not right for a
8
+ * long-lived object holding mutable state, where `setMode('manual'); start(); setSetpoint(80)` from
9
+ * one caller can interleave with `stop(); setMode('automatic')` from another and leave a machine in
10
+ * a combination neither of them asked for.
11
+ *
12
+ * `serial` runs one call at a time per exposed instance. A function instead runs one call at a time
13
+ * per key it returns, which is how a server fronting many devices keeps each device's commands in
14
+ * order without serialising the whole server behind the slowest one.
15
+ *
16
+ * **A serial instance must not call back into itself over RPC.** The second call queues behind the
17
+ * first, which is waiting for it, and neither ever runs. That is why `parallel` remains the default
18
+ * rather than the safer-sounding option: serialising by default would deadlock re-entrant designs
19
+ * that work today, silently and only under load.
20
+ */
21
+ export type RpcExecution = 'parallel' | 'serial' | ((context: RpcCallContext) => string);
22
+ export interface RpcMethodOptions {
23
+ /**
24
+ * What this method does to the world: `query`, `idempotent-command` or
25
+ * `non-repeatable-command`. Read by a caller deciding whether an uncertain answer may be
26
+ * retried, and by the server deciding whether to consult a durable idempotency store.
27
+ */
28
+ semantics?: RpcMethodSemantics;
29
+ }
30
+ type RpcMethodDecorator<This, Args extends unknown[], Return> = (target: (this: This, ...args: Args) => Return, context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>) => void;
31
+ /**
32
+ * Marks a method as remotely callable, and optionally says what it does to the world.
33
+ *
34
+ * ```typescript
35
+ * class Plant {
36
+ * @rpc async readSetpoint() { ... } // marked, nothing declared
37
+ * @rpc({ semantics: 'idempotent-command' }) async writeSetpoint(v: number) { ... }
38
+ * @rpc({ semantics: 'non-repeatable-command' }) async advanceBatch() { ... }
39
+ * private recompute() { ... } // unmarked, so unreachable
40
+ * }
41
+ * ```
42
+ *
43
+ * Both spellings are the same decorator: bare `@rpc` where there is nothing to say, and `@rpc({…})`
44
+ * where there is. A standard ECMAScript decorator either way, so no experimentalDecorators is
45
+ * needed, and the mark is recorded per instance at construction, which is when the RPC layer needs
46
+ * it.
47
+ */
48
+ export declare function rpc<This, Args extends unknown[], Return>(target: (this: This, ...args: Args) => Return, context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>): void;
49
+ export declare function rpc<This, Args extends unknown[], Return>(options: RpcMethodOptions): RpcMethodDecorator<This, Args, Return>;
50
+ /**
51
+ * Marks methods without decorators, for JavaScript callers or code that prefers not to use them.
52
+ * Names that are not functions on the prototype are rejected, since a typo would silently expose
53
+ * nothing.
54
+ */
55
+ export declare const exposeMethods: <T>(constructor: new (...args: never[]) => T, methods: string[]) => new (...args: never[]) => T;
56
+ export interface DeclaredNamespace {
57
+ name: string;
58
+ version?: string;
59
+ execution?: RpcExecution;
60
+ }
61
+ /**
62
+ * Declares the name a class is exposed under, and optionally the version of its contract and how
63
+ * its calls may overlap.
64
+ *
65
+ * The exposure name only existed at the call site - `exposeClassInstance(instance, 'plant')` - so
66
+ * nothing reading the source could tell which namespace a class belongs to. Declaring it here lets
67
+ * the extraction CLI key a schema correctly, and lets exposeClassInstance take the name as read.
68
+ *
69
+ * ```typescript
70
+ * @rpcNamespace('plant', { version: '3', execution: 'serial' })
71
+ * class Plant { @rpc async writeSetpoint(value: number) { ... } }
72
+ * ```
73
+ */
74
+ export declare const rpcNamespace: (name: string, options?: {
75
+ version?: string;
76
+ execution?: RpcExecution;
77
+ }) => <T extends abstract new (...args: never[]) => unknown>(target: T, _context: ClassDecoratorContext) => T;
78
+ /** The namespace an instance's class declares, walking up so a subclass inherits it. */
79
+ export declare const declaredNamespace: (instance: object) => DeclaredNamespace | undefined;
80
+ /** The marked method names for an instance, or undefined when the class marks nothing. */
81
+ export declare const markedMethods: (instance: object) => Set<string> | undefined;
82
+ /**
83
+ * The semantics an instance's methods declare, walking the chain so a subclass inherits them.
84
+ *
85
+ * A subclass that redeclares wins, which is why the nearest constructor is consulted first: an
86
+ * override that turns a query into a command has to be able to say so.
87
+ */
88
+ export declare const declaredSemantics: (instance: object) => Map<string, RpcMethodSemantics>;
89
+ export {};
90
+ //# sourceMappingURL=Expose.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Expose.d.ts","sourceRoot":"","sources":["../../src/RPC/Expose.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAEvD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,QAAQ,GAAG,CAAC,CAAC,OAAO,EAAE,cAAc,KAAK,MAAM,CAAC,CAAA;AA4BxF,MAAM,WAAW,gBAAgB;IAC7B;;;;OAIG;IACH,SAAS,CAAC,EAAE,kBAAkB,CAAA;CACjC;AAED,KAAK,kBAAkB,CAAC,IAAI,EAAE,IAAI,SAAS,OAAO,EAAE,EAAE,MAAM,IAAI,CAC5D,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,EAC7C,OAAO,EAAE,2BAA2B,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,KAChF,IAAI,CAAA;AAaT;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,GAAG,CAAC,IAAI,EAAE,IAAI,SAAS,OAAO,EAAE,EAAE,MAAM,EACpD,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,EAC7C,OAAO,EAAE,2BAA2B,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,GAClF,IAAI,CAAA;AACP,wBAAgB,GAAG,CAAC,IAAI,EAAE,IAAI,SAAS,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;AAY5H;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,eAAe,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,WAAW,MAAM,EAAE,mBAAhC,KAAK,EAAE,KAAK,CAOvE,CAAA;AAKD,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,YAAY,CAAA;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,YAAY,SACd,MAAM,YAAW;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,YAAY,CAAA;CAAE,MACrE,CAAC,SAAS,QAAQ,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,UAAU,CAAC,YAAY,qBAAqB,MAGhG,CAAA;AAEL,wFAAwF;AACxF,eAAO,MAAM,iBAAiB,aAAc,MAAM,kCAMjD,CAAA;AAED,0FAA0F;AAC1F,eAAO,MAAM,aAAa,aAAc,MAAM,KAAG,GAAG,CAAC,MAAM,CAAC,GAAG,SAO9D,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,aAAc,MAAM,KAAG,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAMlF,CAAA"}