@undefineds.co/xpod 0.3.53 → 0.3.54

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 (117) hide show
  1. package/config/cli.json +72 -0
  2. package/config/components-ignore.json +21 -0
  3. package/config/extensions.local.initializer.json +77 -8
  4. package/config/resolver.json +72 -4
  5. package/dist/api/ApiServer.d.ts +12 -0
  6. package/dist/api/ApiServer.js +14 -3
  7. package/dist/api/ApiServer.js.map +1 -1
  8. package/dist/api/auth/NodeTokenAuthenticator.d.ts +0 -8
  9. package/dist/api/auth/NodeTokenAuthenticator.js +3 -46
  10. package/dist/api/auth/NodeTokenAuthenticator.js.map +1 -1
  11. package/dist/api/container/local.js +5 -36
  12. package/dist/api/container/local.js.map +1 -1
  13. package/dist/api/container/routes.js +6 -0
  14. package/dist/api/container/routes.js.map +1 -1
  15. package/dist/api/handlers/EdgeNodeSignalHandler.js +25 -3
  16. package/dist/api/handlers/EdgeNodeSignalHandler.js.map +1 -1
  17. package/dist/api/handlers/ReachabilityHandler.d.ts +13 -0
  18. package/dist/api/handlers/ReachabilityHandler.js +388 -0
  19. package/dist/api/handlers/ReachabilityHandler.js.map +1 -0
  20. package/dist/api/runs/InngestRunExecutionBackend.d.ts +2 -2
  21. package/dist/api/tasks/InngestTaskScheduler.d.ts +4 -4
  22. package/dist/components/components.jsonld +14 -2
  23. package/dist/components/context.jsonld +439 -3
  24. package/dist/edge/EdgeNodeAgent.d.ts +43 -0
  25. package/dist/edge/EdgeNodeAgent.js +208 -1
  26. package/dist/edge/EdgeNodeAgent.js.map +1 -1
  27. package/dist/edge/EdgeNodeAgent.jsonld +166 -0
  28. package/dist/edge/EdgeNodeAgentInitializer.d.ts +20 -2
  29. package/dist/edge/EdgeNodeAgentInitializer.js +53 -2
  30. package/dist/edge/EdgeNodeAgentInitializer.js.map +1 -1
  31. package/dist/edge/EdgeNodeAgentInitializer.jsonld +409 -0
  32. package/dist/edge/reachability/CanonicalFetch.d.ts +7 -0
  33. package/dist/edge/reachability/CanonicalFetch.js +49 -0
  34. package/dist/edge/reachability/CanonicalFetch.js.map +1 -0
  35. package/dist/edge/reachability/CanonicalFetch.jsonld +25 -0
  36. package/dist/edge/reachability/ManagedClientFetch.d.ts +26 -0
  37. package/dist/edge/reachability/ManagedClientFetch.js +155 -0
  38. package/dist/edge/reachability/ManagedClientFetch.js.map +1 -0
  39. package/dist/edge/reachability/ManagedClientFetch.jsonld +83 -0
  40. package/dist/edge/reachability/ManagedClientP2PSmoke.d.ts +16 -0
  41. package/dist/edge/reachability/ManagedClientP2PSmoke.js +31 -0
  42. package/dist/edge/reachability/ManagedClientP2PSmoke.js.map +1 -0
  43. package/dist/edge/reachability/ManagedClientP2PSmoke.jsonld +65 -0
  44. package/dist/edge/reachability/ManagedRouteSelector.d.ts +7 -0
  45. package/dist/edge/reachability/ManagedRouteSelector.js +43 -0
  46. package/dist/edge/reachability/ManagedRouteSelector.js.map +1 -0
  47. package/dist/edge/reachability/ManagedRouteSelector.jsonld +29 -0
  48. package/dist/edge/reachability/P2PDataPlane.d.ts +37 -0
  49. package/dist/edge/reachability/P2PDataPlane.js +160 -0
  50. package/dist/edge/reachability/P2PDataPlane.js.map +1 -0
  51. package/dist/edge/reachability/P2PDataPlane.jsonld +134 -0
  52. package/dist/edge/reachability/P2PRealnetAcceptance.d.ts +74 -0
  53. package/dist/edge/reachability/P2PRealnetAcceptance.js +240 -0
  54. package/dist/edge/reachability/P2PRealnetAcceptance.js.map +1 -0
  55. package/dist/edge/reachability/P2PRealnetAcceptance.jsonld +283 -0
  56. package/dist/edge/reachability/P2PSignalingClient.d.ts +24 -0
  57. package/dist/edge/reachability/P2PSignalingClient.js +138 -0
  58. package/dist/edge/reachability/P2PSignalingClient.js.map +1 -0
  59. package/dist/edge/reachability/P2PSignalingClient.jsonld +79 -0
  60. package/dist/edge/reachability/ReachabilitySessionService.d.ts +55 -0
  61. package/dist/edge/reachability/ReachabilitySessionService.js +439 -0
  62. package/dist/edge/reachability/ReachabilitySessionService.js.map +1 -0
  63. package/dist/edge/reachability/ReachabilitySessionService.jsonld +196 -0
  64. package/dist/edge/reachability/RouteSetBuilder.d.ts +2 -0
  65. package/dist/edge/reachability/RouteSetBuilder.js +205 -0
  66. package/dist/edge/reachability/RouteSetBuilder.js.map +1 -0
  67. package/dist/edge/reachability/TcpP2PDataPlaneTransport.d.ts +47 -0
  68. package/dist/edge/reachability/TcpP2PDataPlaneTransport.js +281 -0
  69. package/dist/edge/reachability/TcpP2PDataPlaneTransport.js.map +1 -0
  70. package/dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld +183 -0
  71. package/dist/edge/reachability/TcpP2PSignalingSession.d.ts +149 -0
  72. package/dist/edge/reachability/TcpP2PSignalingSession.js +699 -0
  73. package/dist/edge/reachability/TcpP2PSignalingSession.js.map +1 -0
  74. package/dist/edge/reachability/TcpP2PSignalingSession.jsonld +474 -0
  75. package/dist/edge/reachability/index.d.ts +12 -0
  76. package/dist/edge/reachability/index.js +29 -0
  77. package/dist/edge/reachability/index.js.map +1 -0
  78. package/dist/edge/reachability/types.d.ts +114 -0
  79. package/dist/edge/reachability/types.js +3 -0
  80. package/dist/edge/reachability/types.js.map +1 -0
  81. package/dist/edge/reachability/types.jsonld +457 -0
  82. package/dist/http/EdgeNodeProxyHttpHandler.d.ts +2 -0
  83. package/dist/http/EdgeNodeProxyHttpHandler.js +19 -1
  84. package/dist/http/EdgeNodeProxyHttpHandler.js.map +1 -1
  85. package/dist/http/EdgeNodeProxyHttpHandler.jsonld +8 -0
  86. package/dist/identity/drizzle/EdgeNodeRepository.js +1 -1
  87. package/dist/identity/drizzle/EdgeNodeRepository.js.map +1 -1
  88. package/dist/index.d.ts +4 -1
  89. package/dist/index.js +5 -2
  90. package/dist/index.js.map +1 -1
  91. package/dist/runtime/bootstrap.js +8 -0
  92. package/dist/runtime/bootstrap.js.map +1 -1
  93. package/dist/service/EdgeNodeSignalClient.js +5 -1
  94. package/dist/service/EdgeNodeSignalClient.js.map +1 -1
  95. package/dist/storage/rdf/PostgresRdfEngine.d.ts +1 -0
  96. package/dist/storage/rdf/PostgresRdfEngine.js +53 -37
  97. package/dist/storage/rdf/PostgresRdfEngine.js.map +1 -1
  98. package/dist/storage/rdf/PostgresRdfEngine.jsonld +4 -0
  99. package/dist/test-utils/index.d.ts +2 -0
  100. package/dist/test-utils/index.js +3 -1
  101. package/dist/test-utils/index.js.map +1 -1
  102. package/dist/test-utils/local-managed-client-p2p-e2e-smoke.d.ts +63 -0
  103. package/dist/test-utils/local-managed-client-p2p-e2e-smoke.js +478 -0
  104. package/dist/test-utils/local-managed-client-p2p-e2e-smoke.js.map +1 -0
  105. package/package.json +11 -4
  106. package/static/app/assets/_commonjsHelpers-B-UnjaXt.js +1 -0
  107. package/static/app/assets/index-AaQ1qxhy.js +171 -0
  108. package/static/app/assets/inrupt-smoke.js +131 -0
  109. package/static/app/assets/main.css +1 -0
  110. package/static/app/assets/main.js +6 -6
  111. package/static/app/index.html +2 -1
  112. package/static/app/inrupt-smoke.html +14 -0
  113. package/static/app/reachability.html +221 -0
  114. package/static/app/reachability.svg +7 -0
  115. package/static/app/reachability.webmanifest +18 -0
  116. package/static/app/signal-pod.html +293 -0
  117. package/static/app/assets/index.css +0 -1
@@ -0,0 +1,281 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createTcpP2PDataPlaneTransport = createTcpP2PDataPlaneTransport;
4
+ exports.createTcpP2PDataPlaneServer = createTcpP2PDataPlaneServer;
5
+ exports.attachTcpP2PDataPlaneSocket = attachTcpP2PDataPlaneSocket;
6
+ exports.computeTcpHolePunchPlan = computeTcpHolePunchPlan;
7
+ const node_net_1 = require("node:net");
8
+ const REQUEST_ENVELOPE = 'xpod-p2p-http-request';
9
+ const RESPONSE_ENVELOPE = 'xpod-p2p-http-response';
10
+ const ERROR_ENVELOPE = 'xpod-p2p-http-error';
11
+ const DEFAULT_TIMEOUT_MS = 5_000;
12
+ const DEFAULT_WINDOW_SECONDS = 42;
13
+ const DEFAULT_MAX_CLOCK_ERROR_SECONDS = 20;
14
+ const DEFAULT_MIN_RUN_WINDOW_SECONDS = 10;
15
+ const DEFAULT_NUM_PORTS = 16;
16
+ const DEFAULT_BASE_PORT = 30_000;
17
+ const DEFAULT_PORT_RANGE = 20_000;
18
+ const LARGE_PRIME = 2654435761n;
19
+ const UINT32_MODULUS = 0xffffffffn;
20
+ function createTcpP2PDataPlaneTransport(options) {
21
+ return new TcpP2PTransport(options);
22
+ }
23
+ function createTcpP2PDataPlaneServer(options) {
24
+ return new TcpP2PServer(options);
25
+ }
26
+ function attachTcpP2PDataPlaneSocket(options) {
27
+ return attachTcpP2PDataPlaneSocketInternal(options.socket, options.handler);
28
+ }
29
+ function computeTcpHolePunchPlan(options = {}) {
30
+ const nowSeconds = options.nowSeconds ?? Math.floor(Date.now() / 1_000);
31
+ const windowSeconds = positiveInteger(options.windowSeconds, DEFAULT_WINDOW_SECONDS, 'windowSeconds');
32
+ const maxClockErrorSeconds = positiveInteger(options.maxClockErrorSeconds, DEFAULT_MAX_CLOCK_ERROR_SECONDS, 'maxClockErrorSeconds');
33
+ const minRunWindowSeconds = positiveInteger(options.minRunWindowSeconds, DEFAULT_MIN_RUN_WINDOW_SECONDS, 'minRunWindowSeconds');
34
+ const numPorts = positiveInteger(options.numPorts, DEFAULT_NUM_PORTS, 'numPorts');
35
+ const basePort = positiveInteger(options.basePort, DEFAULT_BASE_PORT, 'basePort');
36
+ const portRange = positiveInteger(options.portRange, DEFAULT_PORT_RANGE, 'portRange');
37
+ let bucket = Math.floor((nowSeconds - maxClockErrorSeconds) / windowSeconds);
38
+ let rendezvousTimeSeconds = (bucket + 1) * windowSeconds + maxClockErrorSeconds;
39
+ if (rendezvousTimeSeconds - nowSeconds < minRunWindowSeconds) {
40
+ bucket += 1;
41
+ rendezvousTimeSeconds = (bucket + 1) * windowSeconds + maxClockErrorSeconds;
42
+ }
43
+ const boundary = stableBoundary(bucket);
44
+ return {
45
+ bucket,
46
+ boundary,
47
+ rendezvousTimeSeconds,
48
+ ports: stablePorts(boundary, numPorts, basePort, portRange),
49
+ };
50
+ }
51
+ class TcpP2PTransport {
52
+ constructor(options) {
53
+ this.options = options;
54
+ this.readBuffer = '';
55
+ this.pending = new Map();
56
+ this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
57
+ this.randomId = options.randomId ?? (() => `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`);
58
+ if (options.socket) {
59
+ this.attachSocket(options.socket);
60
+ }
61
+ }
62
+ async request(frame) {
63
+ const requestId = frame.requestId ?? `tcp_${this.randomId()}`;
64
+ const requestFrame = { ...frame, requestId };
65
+ const socket = await this.ensureSocket();
66
+ const response = new Promise((resolve, reject) => {
67
+ const timeout = setTimeout(() => {
68
+ this.pending.delete(requestId);
69
+ reject(new Error(`TCP P2P request ${requestId} timed out after ${this.timeoutMs}ms`));
70
+ }, this.timeoutMs);
71
+ this.pending.set(requestId, { resolve, reject, timeout });
72
+ });
73
+ writeEnvelope(socket, { type: REQUEST_ENVELOPE, requestId, frame: requestFrame });
74
+ return response;
75
+ }
76
+ close() {
77
+ this.rejectPending(new Error('TCP P2P transport closed'));
78
+ this.socket?.destroy();
79
+ this.socket = undefined;
80
+ this.connectPromise = undefined;
81
+ this.readBuffer = '';
82
+ }
83
+ async ensureSocket() {
84
+ if (this.socket && !this.socket.destroyed) {
85
+ return this.socket;
86
+ }
87
+ if (!this.connectPromise) {
88
+ this.connectPromise = new Promise((resolve, reject) => {
89
+ const socket = (0, node_net_1.createConnection)({ host: this.options.remoteHost, port: this.options.remotePort });
90
+ const onError = (error) => {
91
+ socket.off('connect', onConnect);
92
+ reject(error);
93
+ };
94
+ const onConnect = () => {
95
+ socket.off('error', onError);
96
+ this.attachSocket(socket);
97
+ resolve(socket);
98
+ };
99
+ socket.once('error', onError);
100
+ socket.once('connect', onConnect);
101
+ });
102
+ }
103
+ return this.connectPromise;
104
+ }
105
+ attachSocket(socket) {
106
+ this.socket = socket;
107
+ socket.on('data', (chunk) => this.handleData(chunk));
108
+ socket.on('error', (error) => this.rejectPending(error));
109
+ socket.on('close', () => this.rejectPending(new Error('TCP P2P socket closed')));
110
+ }
111
+ handleData(chunk) {
112
+ this.readBuffer += chunk.toString('utf8');
113
+ const { lines, remainder } = splitLines(this.readBuffer);
114
+ this.readBuffer = remainder;
115
+ for (const line of lines) {
116
+ const envelope = parseEnvelope(line);
117
+ if (!envelope || (envelope.type !== RESPONSE_ENVELOPE && envelope.type !== ERROR_ENVELOPE)) {
118
+ continue;
119
+ }
120
+ const pending = this.pending.get(envelope.requestId);
121
+ if (!pending) {
122
+ continue;
123
+ }
124
+ clearTimeout(pending.timeout);
125
+ this.pending.delete(envelope.requestId);
126
+ if (envelope.type === ERROR_ENVELOPE) {
127
+ pending.reject(new Error(envelope.error));
128
+ continue;
129
+ }
130
+ pending.resolve(envelope.frame);
131
+ }
132
+ }
133
+ rejectPending(error) {
134
+ for (const [requestId, pending] of this.pending) {
135
+ clearTimeout(pending.timeout);
136
+ pending.reject(error);
137
+ this.pending.delete(requestId);
138
+ }
139
+ }
140
+ }
141
+ class TcpP2PServer {
142
+ constructor(options) {
143
+ this.options = options;
144
+ this.sockets = new Set();
145
+ this.host = options.host ?? '0.0.0.0';
146
+ }
147
+ async listen(port = 0) {
148
+ if (this.server) {
149
+ return;
150
+ }
151
+ const server = (0, node_net_1.createServer)((socket) => this.handleSocket(socket));
152
+ this.server = server;
153
+ await new Promise((resolve, reject) => {
154
+ server.once('listening', resolve);
155
+ server.once('error', reject);
156
+ server.listen(port, this.host);
157
+ });
158
+ }
159
+ address() {
160
+ const address = this.server?.address();
161
+ if (!address || typeof address === 'string') {
162
+ throw new Error(`Expected TCP server address info, got ${String(address)}`);
163
+ }
164
+ return address;
165
+ }
166
+ async close() {
167
+ for (const socket of this.sockets) {
168
+ socket.close();
169
+ }
170
+ this.sockets.clear();
171
+ const server = this.server;
172
+ this.server = undefined;
173
+ if (!server) {
174
+ return;
175
+ }
176
+ await new Promise((resolve, reject) => {
177
+ server.close((error) => error ? reject(error) : resolve());
178
+ });
179
+ }
180
+ handleSocket(socket) {
181
+ const handle = attachTcpP2PDataPlaneSocketInternal(socket, this.options.handler, () => {
182
+ this.sockets.delete(handle);
183
+ });
184
+ this.sockets.add(handle);
185
+ }
186
+ }
187
+ function attachTcpP2PDataPlaneSocketInternal(socket, handler, onClose) {
188
+ let readBuffer = '';
189
+ const onData = (chunk) => {
190
+ readBuffer += chunk.toString('utf8');
191
+ const split = splitLines(readBuffer);
192
+ readBuffer = split.remainder;
193
+ for (const line of split.lines) {
194
+ void handleRequestLine(socket, handler, line);
195
+ }
196
+ };
197
+ const onSocketClose = () => {
198
+ onClose?.();
199
+ };
200
+ socket.on('data', onData);
201
+ socket.on('close', onSocketClose);
202
+ return {
203
+ close() {
204
+ socket.off('data', onData);
205
+ socket.off('close', onSocketClose);
206
+ socket.destroy();
207
+ onClose?.();
208
+ },
209
+ };
210
+ }
211
+ async function handleRequestLine(socket, handler, line) {
212
+ const envelope = parseEnvelope(line);
213
+ if (!envelope || envelope.type !== REQUEST_ENVELOPE) {
214
+ return;
215
+ }
216
+ try {
217
+ const response = await handler.handleRequest(envelope.frame);
218
+ writeEnvelope(socket, { type: RESPONSE_ENVELOPE, requestId: envelope.requestId, frame: response });
219
+ }
220
+ catch (error) {
221
+ writeEnvelope(socket, {
222
+ type: ERROR_ENVELOPE,
223
+ requestId: envelope.requestId,
224
+ error: error instanceof Error ? error.message : String(error),
225
+ });
226
+ }
227
+ }
228
+ function writeEnvelope(socket, envelope) {
229
+ socket.write(`${JSON.stringify(envelope)}\n`);
230
+ }
231
+ function splitLines(value) {
232
+ const parts = value.split('\n');
233
+ return { lines: parts.slice(0, -1).filter((line) => line.length > 0), remainder: parts.at(-1) ?? '' };
234
+ }
235
+ function parseEnvelope(line) {
236
+ try {
237
+ const parsed = JSON.parse(line);
238
+ if (parsed.type === REQUEST_ENVELOPE && typeof parsed.requestId === 'string' && parsed.frame) {
239
+ return parsed;
240
+ }
241
+ if (parsed.type === RESPONSE_ENVELOPE && typeof parsed.requestId === 'string' && parsed.frame) {
242
+ return parsed;
243
+ }
244
+ if (parsed.type === ERROR_ENVELOPE && typeof parsed.requestId === 'string' && typeof parsed.error === 'string') {
245
+ return parsed;
246
+ }
247
+ }
248
+ catch {
249
+ return undefined;
250
+ }
251
+ return undefined;
252
+ }
253
+ function stableBoundary(bucket) {
254
+ const value = (BigInt(bucket) * LARGE_PRIME) % UINT32_MODULUS;
255
+ return Number(value < 0 ? value + UINT32_MODULUS : value);
256
+ }
257
+ function stablePorts(boundary, numPorts, basePort, portRange) {
258
+ const rng = mulberry32(boundary >>> 0);
259
+ const ports = new Set();
260
+ while (ports.size < numPorts) {
261
+ ports.add(basePort + Math.floor(rng() * portRange));
262
+ }
263
+ return [...ports].sort((a, b) => b - a);
264
+ }
265
+ function mulberry32(seed) {
266
+ let value = seed;
267
+ return () => {
268
+ value = (value + 0x6D2B79F5) | 0;
269
+ let result = Math.imul(value ^ (value >>> 15), 1 | value);
270
+ result ^= result + Math.imul(result ^ (result >>> 7), 61 | result);
271
+ return ((result ^ (result >>> 14)) >>> 0) / 4_294_967_296;
272
+ };
273
+ }
274
+ function positiveInteger(value, fallback, name) {
275
+ const resolved = value ?? fallback;
276
+ if (!Number.isInteger(resolved) || resolved <= 0) {
277
+ throw new Error(`${name} must be a positive integer`);
278
+ }
279
+ return resolved;
280
+ }
281
+ //# sourceMappingURL=TcpP2PDataPlaneTransport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TcpP2PDataPlaneTransport.js","sourceRoot":"","sources":["../../../src/edge/reachability/TcpP2PDataPlaneTransport.ts"],"names":[],"mappings":"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","sourcesContent":["import { createConnection, createServer, type AddressInfo, type Server, type Socket } from 'node:net';\nimport type {\n P2PDataPlaneHandler,\n P2PDataPlaneTransport,\n P2PHttpRequestFrame,\n P2PHttpResponseFrame,\n} from './P2PDataPlane';\n\nconst REQUEST_ENVELOPE = 'xpod-p2p-http-request' as const;\nconst RESPONSE_ENVELOPE = 'xpod-p2p-http-response' as const;\nconst ERROR_ENVELOPE = 'xpod-p2p-http-error' as const;\nconst DEFAULT_TIMEOUT_MS = 5_000;\nconst DEFAULT_WINDOW_SECONDS = 42;\nconst DEFAULT_MAX_CLOCK_ERROR_SECONDS = 20;\nconst DEFAULT_MIN_RUN_WINDOW_SECONDS = 10;\nconst DEFAULT_NUM_PORTS = 16;\nconst DEFAULT_BASE_PORT = 30_000;\nconst DEFAULT_PORT_RANGE = 20_000;\nconst LARGE_PRIME = 2_654_435_761n;\nconst UINT32_MODULUS = 0xffff_ffffn;\n\ntype TcpP2PEnvelope =\n | { type: typeof REQUEST_ENVELOPE; requestId: string; frame: P2PHttpRequestFrame }\n | { type: typeof RESPONSE_ENVELOPE; requestId: string; frame: P2PHttpResponseFrame }\n | { type: typeof ERROR_ENVELOPE; requestId: string; error: string };\n\nexport interface TcpP2PDataPlaneTransportOptions {\n remoteHost: string;\n remotePort: number;\n socket?: Socket;\n timeoutMs?: number;\n randomId?: () => string;\n}\n\nexport interface TcpP2PDataPlaneTransport extends P2PDataPlaneTransport {\n close(): void;\n}\n\nexport interface TcpP2PDataPlaneServerOptions {\n handler: P2PDataPlaneHandler;\n host?: string;\n}\n\nexport interface TcpP2PDataPlaneServer {\n listen(port?: number): Promise<void>;\n address(): AddressInfo;\n close(): Promise<void>;\n}\n\nexport interface TcpP2PDataPlaneSocketOptions {\n socket: Socket;\n handler: P2PDataPlaneHandler;\n}\n\nexport interface TcpP2PDataPlaneSocketHandle {\n close(): void;\n}\n\nexport interface TcpHolePunchPlanOptions {\n nowSeconds?: number;\n windowSeconds?: number;\n maxClockErrorSeconds?: number;\n minRunWindowSeconds?: number;\n numPorts?: number;\n basePort?: number;\n portRange?: number;\n}\n\nexport interface TcpHolePunchPlan {\n bucket: number;\n boundary: number;\n rendezvousTimeSeconds: number;\n ports: number[];\n}\n\nexport function createTcpP2PDataPlaneTransport(options: TcpP2PDataPlaneTransportOptions): TcpP2PDataPlaneTransport {\n return new TcpP2PTransport(options);\n}\n\nexport function createTcpP2PDataPlaneServer(options: TcpP2PDataPlaneServerOptions): TcpP2PDataPlaneServer {\n return new TcpP2PServer(options);\n}\n\nexport function attachTcpP2PDataPlaneSocket(options: TcpP2PDataPlaneSocketOptions): TcpP2PDataPlaneSocketHandle {\n return attachTcpP2PDataPlaneSocketInternal(options.socket, options.handler);\n}\n\nexport function computeTcpHolePunchPlan(options: TcpHolePunchPlanOptions = {}): TcpHolePunchPlan {\n const nowSeconds = options.nowSeconds ?? Math.floor(Date.now() / 1_000);\n const windowSeconds = positiveInteger(options.windowSeconds, DEFAULT_WINDOW_SECONDS, 'windowSeconds');\n const maxClockErrorSeconds = positiveInteger(options.maxClockErrorSeconds, DEFAULT_MAX_CLOCK_ERROR_SECONDS, 'maxClockErrorSeconds');\n const minRunWindowSeconds = positiveInteger(options.minRunWindowSeconds, DEFAULT_MIN_RUN_WINDOW_SECONDS, 'minRunWindowSeconds');\n const numPorts = positiveInteger(options.numPorts, DEFAULT_NUM_PORTS, 'numPorts');\n const basePort = positiveInteger(options.basePort, DEFAULT_BASE_PORT, 'basePort');\n const portRange = positiveInteger(options.portRange, DEFAULT_PORT_RANGE, 'portRange');\n\n let bucket = Math.floor((nowSeconds - maxClockErrorSeconds) / windowSeconds);\n let rendezvousTimeSeconds = (bucket + 1) * windowSeconds + maxClockErrorSeconds;\n if (rendezvousTimeSeconds - nowSeconds < minRunWindowSeconds) {\n bucket += 1;\n rendezvousTimeSeconds = (bucket + 1) * windowSeconds + maxClockErrorSeconds;\n }\n const boundary = stableBoundary(bucket);\n return {\n bucket,\n boundary,\n rendezvousTimeSeconds,\n ports: stablePorts(boundary, numPorts, basePort, portRange),\n };\n}\n\nclass TcpP2PTransport implements TcpP2PDataPlaneTransport {\n private readonly timeoutMs: number;\n private readonly randomId: () => string;\n private socket?: Socket;\n private connectPromise?: Promise<Socket>;\n private readBuffer = '';\n private readonly pending = new Map<string, {\n resolve: (frame: P2PHttpResponseFrame) => void;\n reject: (error: Error) => void;\n timeout: NodeJS.Timeout;\n }>();\n\n public constructor(private readonly options: TcpP2PDataPlaneTransportOptions) {\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.randomId = options.randomId ?? (() => `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`);\n if (options.socket) {\n this.attachSocket(options.socket);\n }\n }\n\n public async request(frame: P2PHttpRequestFrame): Promise<P2PHttpResponseFrame> {\n const requestId = frame.requestId ?? `tcp_${this.randomId()}`;\n const requestFrame: P2PHttpRequestFrame = { ...frame, requestId };\n const socket = await this.ensureSocket();\n const response = new Promise<P2PHttpResponseFrame>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.pending.delete(requestId);\n reject(new Error(`TCP P2P request ${requestId} timed out after ${this.timeoutMs}ms`));\n }, this.timeoutMs);\n this.pending.set(requestId, { resolve, reject, timeout });\n });\n writeEnvelope(socket, { type: REQUEST_ENVELOPE, requestId, frame: requestFrame });\n return response;\n }\n\n public close(): void {\n this.rejectPending(new Error('TCP P2P transport closed'));\n this.socket?.destroy();\n this.socket = undefined;\n this.connectPromise = undefined;\n this.readBuffer = '';\n }\n\n private async ensureSocket(): Promise<Socket> {\n if (this.socket && !this.socket.destroyed) {\n return this.socket;\n }\n if (!this.connectPromise) {\n this.connectPromise = new Promise((resolve, reject) => {\n const socket = createConnection({ host: this.options.remoteHost, port: this.options.remotePort });\n const onError = (error: Error): void => {\n socket.off('connect', onConnect);\n reject(error);\n };\n const onConnect = (): void => {\n socket.off('error', onError);\n this.attachSocket(socket);\n resolve(socket);\n };\n socket.once('error', onError);\n socket.once('connect', onConnect);\n });\n }\n return this.connectPromise;\n }\n\n private attachSocket(socket: Socket): void {\n this.socket = socket;\n socket.on('data', (chunk) => this.handleData(chunk));\n socket.on('error', (error) => this.rejectPending(error));\n socket.on('close', () => this.rejectPending(new Error('TCP P2P socket closed')));\n }\n\n private handleData(chunk: Buffer): void {\n this.readBuffer += chunk.toString('utf8');\n const { lines, remainder } = splitLines(this.readBuffer);\n this.readBuffer = remainder;\n for (const line of lines) {\n const envelope = parseEnvelope(line);\n if (!envelope || (envelope.type !== RESPONSE_ENVELOPE && envelope.type !== ERROR_ENVELOPE)) {\n continue;\n }\n const pending = this.pending.get(envelope.requestId);\n if (!pending) {\n continue;\n }\n clearTimeout(pending.timeout);\n this.pending.delete(envelope.requestId);\n if (envelope.type === ERROR_ENVELOPE) {\n pending.reject(new Error(envelope.error));\n continue;\n }\n pending.resolve(envelope.frame);\n }\n }\n\n private rejectPending(error: Error): void {\n for (const [requestId, pending] of this.pending) {\n clearTimeout(pending.timeout);\n pending.reject(error);\n this.pending.delete(requestId);\n }\n }\n}\n\nclass TcpP2PServer implements TcpP2PDataPlaneServer {\n private readonly host: string;\n private server?: Server;\n private sockets = new Set<TcpP2PDataPlaneSocketHandle>();\n\n public constructor(private readonly options: TcpP2PDataPlaneServerOptions) {\n this.host = options.host ?? '0.0.0.0';\n }\n\n public async listen(port = 0): Promise<void> {\n if (this.server) {\n return;\n }\n const server = createServer((socket) => this.handleSocket(socket));\n this.server = server;\n await new Promise<void>((resolve, reject) => {\n server.once('listening', resolve);\n server.once('error', reject);\n server.listen(port, this.host);\n });\n }\n\n public address(): AddressInfo {\n const address = this.server?.address();\n if (!address || typeof address === 'string') {\n throw new Error(`Expected TCP server address info, got ${String(address)}`);\n }\n return address;\n }\n\n public async close(): Promise<void> {\n for (const socket of this.sockets) {\n socket.close();\n }\n this.sockets.clear();\n const server = this.server;\n this.server = undefined;\n if (!server) {\n return;\n }\n await new Promise<void>((resolve, reject) => {\n server.close((error) => error ? reject(error) : resolve());\n });\n }\n\n private handleSocket(socket: Socket): void {\n const handle = attachTcpP2PDataPlaneSocketInternal(socket, this.options.handler, () => {\n this.sockets.delete(handle);\n });\n this.sockets.add(handle);\n }\n}\n\nfunction attachTcpP2PDataPlaneSocketInternal(\n socket: Socket,\n handler: P2PDataPlaneHandler,\n onClose?: () => void,\n): TcpP2PDataPlaneSocketHandle {\n let readBuffer = '';\n const onData = (chunk: Buffer): void => {\n readBuffer += chunk.toString('utf8');\n const split = splitLines(readBuffer);\n readBuffer = split.remainder;\n for (const line of split.lines) {\n void handleRequestLine(socket, handler, line);\n }\n };\n const onSocketClose = (): void => {\n onClose?.();\n };\n socket.on('data', onData);\n socket.on('close', onSocketClose);\n return {\n close(): void {\n socket.off('data', onData);\n socket.off('close', onSocketClose);\n socket.destroy();\n onClose?.();\n },\n };\n}\n\nasync function handleRequestLine(socket: Socket, handler: P2PDataPlaneHandler, line: string): Promise<void> {\n const envelope = parseEnvelope(line);\n if (!envelope || envelope.type !== REQUEST_ENVELOPE) {\n return;\n }\n try {\n const response = await handler.handleRequest(envelope.frame);\n writeEnvelope(socket, { type: RESPONSE_ENVELOPE, requestId: envelope.requestId, frame: response });\n } catch (error) {\n writeEnvelope(socket, {\n type: ERROR_ENVELOPE,\n requestId: envelope.requestId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n}\n\nfunction writeEnvelope(socket: Socket, envelope: TcpP2PEnvelope): void {\n socket.write(`${JSON.stringify(envelope)}\\n`);\n}\n\nfunction splitLines(value: string): { lines: string[]; remainder: string } {\n const parts = value.split('\\n');\n return { lines: parts.slice(0, -1).filter((line) => line.length > 0), remainder: parts.at(-1) ?? '' };\n}\n\nfunction parseEnvelope(line: string): TcpP2PEnvelope | undefined {\n try {\n const parsed = JSON.parse(line) as Partial<TcpP2PEnvelope>;\n if (parsed.type === REQUEST_ENVELOPE && typeof parsed.requestId === 'string' && parsed.frame) {\n return parsed as TcpP2PEnvelope;\n }\n if (parsed.type === RESPONSE_ENVELOPE && typeof parsed.requestId === 'string' && parsed.frame) {\n return parsed as TcpP2PEnvelope;\n }\n if (parsed.type === ERROR_ENVELOPE && typeof parsed.requestId === 'string' && typeof parsed.error === 'string') {\n return parsed as TcpP2PEnvelope;\n }\n } catch {\n return undefined;\n }\n return undefined;\n}\n\nfunction stableBoundary(bucket: number): number {\n const value = (BigInt(bucket) * LARGE_PRIME) % UINT32_MODULUS;\n return Number(value < 0 ? value + UINT32_MODULUS : value);\n}\n\nfunction stablePorts(boundary: number, numPorts: number, basePort: number, portRange: number): number[] {\n const rng = mulberry32(boundary >>> 0);\n const ports = new Set<number>();\n while (ports.size < numPorts) {\n ports.add(basePort + Math.floor(rng() * portRange));\n }\n return [...ports].sort((a, b) => b - a);\n}\n\nfunction mulberry32(seed: number): () => number {\n let value = seed;\n return () => {\n value = (value + 0x6D2B79F5) | 0;\n let result = Math.imul(value ^ (value >>> 15), 1 | value);\n result ^= result + Math.imul(result ^ (result >>> 7), 61 | result);\n return ((result ^ (result >>> 14)) >>> 0) / 4_294_967_296;\n };\n}\n\nfunction positiveInteger(value: number | undefined, fallback: number, name: string): number {\n const resolved = value ?? fallback;\n if (!Number.isInteger(resolved) || resolved <= 0) {\n throw new Error(`${name} must be a positive integer`);\n }\n return resolved;\n}\n"]}
@@ -0,0 +1,183 @@
1
+ {
2
+ "@context": [
3
+ "https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/components/context.jsonld"
4
+ ],
5
+ "@id": "npmd:@undefineds.co/xpod",
6
+ "components": [
7
+ {
8
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneTransportOptions",
9
+ "@type": "AbstractClass",
10
+ "requireElement": "TcpP2PDataPlaneTransportOptions",
11
+ "parameters": [],
12
+ "memberFields": [
13
+ {
14
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneTransportOptions__member_remoteHost",
15
+ "memberFieldName": "remoteHost"
16
+ },
17
+ {
18
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneTransportOptions__member_remotePort",
19
+ "memberFieldName": "remotePort"
20
+ },
21
+ {
22
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneTransportOptions__member_socket",
23
+ "memberFieldName": "socket"
24
+ },
25
+ {
26
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneTransportOptions__member_timeoutMs",
27
+ "memberFieldName": "timeoutMs"
28
+ },
29
+ {
30
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneTransportOptions__member_randomId",
31
+ "memberFieldName": "randomId"
32
+ }
33
+ ],
34
+ "constructorArguments": []
35
+ },
36
+ {
37
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneTransport",
38
+ "@type": "AbstractClass",
39
+ "requireElement": "TcpP2PDataPlaneTransport",
40
+ "extends": [
41
+ "undefineds:dist/edge/reachability/P2PDataPlane.jsonld#P2PDataPlaneTransport"
42
+ ],
43
+ "parameters": [],
44
+ "memberFields": [
45
+ {
46
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneTransport__member_close",
47
+ "memberFieldName": "close"
48
+ }
49
+ ],
50
+ "constructorArguments": []
51
+ },
52
+ {
53
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneServerOptions",
54
+ "@type": "AbstractClass",
55
+ "requireElement": "TcpP2PDataPlaneServerOptions",
56
+ "parameters": [],
57
+ "memberFields": [
58
+ {
59
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneServerOptions__member_handler",
60
+ "memberFieldName": "handler"
61
+ },
62
+ {
63
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneServerOptions__member_host",
64
+ "memberFieldName": "host"
65
+ }
66
+ ],
67
+ "constructorArguments": []
68
+ },
69
+ {
70
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneServer",
71
+ "@type": "AbstractClass",
72
+ "requireElement": "TcpP2PDataPlaneServer",
73
+ "parameters": [],
74
+ "memberFields": [
75
+ {
76
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneServer__member_listen",
77
+ "memberFieldName": "listen"
78
+ },
79
+ {
80
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneServer__member_address",
81
+ "memberFieldName": "address"
82
+ },
83
+ {
84
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneServer__member_close",
85
+ "memberFieldName": "close"
86
+ }
87
+ ],
88
+ "constructorArguments": []
89
+ },
90
+ {
91
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneSocketOptions",
92
+ "@type": "AbstractClass",
93
+ "requireElement": "TcpP2PDataPlaneSocketOptions",
94
+ "parameters": [],
95
+ "memberFields": [
96
+ {
97
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneSocketOptions__member_socket",
98
+ "memberFieldName": "socket"
99
+ },
100
+ {
101
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneSocketOptions__member_handler",
102
+ "memberFieldName": "handler"
103
+ }
104
+ ],
105
+ "constructorArguments": []
106
+ },
107
+ {
108
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneSocketHandle",
109
+ "@type": "AbstractClass",
110
+ "requireElement": "TcpP2PDataPlaneSocketHandle",
111
+ "parameters": [],
112
+ "memberFields": [
113
+ {
114
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpP2PDataPlaneSocketHandle__member_close",
115
+ "memberFieldName": "close"
116
+ }
117
+ ],
118
+ "constructorArguments": []
119
+ },
120
+ {
121
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpHolePunchPlanOptions",
122
+ "@type": "AbstractClass",
123
+ "requireElement": "TcpHolePunchPlanOptions",
124
+ "parameters": [],
125
+ "memberFields": [
126
+ {
127
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpHolePunchPlanOptions__member_nowSeconds",
128
+ "memberFieldName": "nowSeconds"
129
+ },
130
+ {
131
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpHolePunchPlanOptions__member_windowSeconds",
132
+ "memberFieldName": "windowSeconds"
133
+ },
134
+ {
135
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpHolePunchPlanOptions__member_maxClockErrorSeconds",
136
+ "memberFieldName": "maxClockErrorSeconds"
137
+ },
138
+ {
139
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpHolePunchPlanOptions__member_minRunWindowSeconds",
140
+ "memberFieldName": "minRunWindowSeconds"
141
+ },
142
+ {
143
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpHolePunchPlanOptions__member_numPorts",
144
+ "memberFieldName": "numPorts"
145
+ },
146
+ {
147
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpHolePunchPlanOptions__member_basePort",
148
+ "memberFieldName": "basePort"
149
+ },
150
+ {
151
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpHolePunchPlanOptions__member_portRange",
152
+ "memberFieldName": "portRange"
153
+ }
154
+ ],
155
+ "constructorArguments": []
156
+ },
157
+ {
158
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpHolePunchPlan",
159
+ "@type": "AbstractClass",
160
+ "requireElement": "TcpHolePunchPlan",
161
+ "parameters": [],
162
+ "memberFields": [
163
+ {
164
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpHolePunchPlan__member_bucket",
165
+ "memberFieldName": "bucket"
166
+ },
167
+ {
168
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpHolePunchPlan__member_boundary",
169
+ "memberFieldName": "boundary"
170
+ },
171
+ {
172
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpHolePunchPlan__member_rendezvousTimeSeconds",
173
+ "memberFieldName": "rendezvousTimeSeconds"
174
+ },
175
+ {
176
+ "@id": "undefineds:dist/edge/reachability/TcpP2PDataPlaneTransport.jsonld#TcpHolePunchPlan__member_ports",
177
+ "memberFieldName": "ports"
178
+ }
179
+ ],
180
+ "constructorArguments": []
181
+ }
182
+ ]
183
+ }
@@ -0,0 +1,149 @@
1
+ import { type Socket } from 'node:net';
2
+ import type { AccessRoute, P2PCandidateRole, P2PSession, P2PTransportCandidate } from './types';
3
+ import type { P2PSignalingClient } from './P2PSignalingClient';
4
+ import type { P2PDataPlaneHandler } from './P2PDataPlane';
5
+ import { type TcpP2PDataPlaneSocketHandle, type TcpP2PDataPlaneTransport, type TcpHolePunchPlan, type TcpHolePunchPlanOptions } from './TcpP2PDataPlaneTransport';
6
+ export declare const RAW_TCP_HOLE_PUNCH_TRANSPORT: "raw-tcp-hole-punch";
7
+ export declare const RAW_TCP_HOLE_PUNCH_CAPABILITY: "tcp-punch";
8
+ export interface CreateRawTcpHolePunchCandidatesOptions {
9
+ role: P2PCandidateRole;
10
+ sourceId: string;
11
+ host?: string;
12
+ address?: string;
13
+ createdAt?: Date;
14
+ priority?: number;
15
+ plan?: TcpHolePunchPlan;
16
+ planOptions?: TcpHolePunchPlanOptions;
17
+ candidateIdPrefix?: string;
18
+ }
19
+ export interface SignaledRawTcpP2PSessionOptions {
20
+ signaling: P2PSignalingClient;
21
+ clientId: string;
22
+ host?: string;
23
+ address?: string;
24
+ capabilities?: string[];
25
+ priority?: number;
26
+ createdAt?: Date;
27
+ plan?: TcpHolePunchPlan;
28
+ planOptions?: TcpHolePunchPlanOptions;
29
+ candidateIdPrefix?: string;
30
+ }
31
+ export interface SignaledRawTcpP2PSession {
32
+ session: P2PSession;
33
+ plan: TcpHolePunchPlan;
34
+ localCandidates: P2PTransportCandidate[];
35
+ rawTcpRoute?: AccessRoute;
36
+ }
37
+ export interface AnswerPendingRawTcpP2PSessionsOnceOptions {
38
+ signaling: P2PSignalingClient;
39
+ sourceId: string;
40
+ host?: string;
41
+ address?: string;
42
+ priority?: number;
43
+ createdAt?: Date;
44
+ candidateIdPrefix?: string;
45
+ }
46
+ export interface WaitForRawTcpRemoteCandidatesOptions {
47
+ signaling: P2PSignalingClient;
48
+ sessionIdOrUrl: string;
49
+ localRole: P2PCandidateRole;
50
+ localSourceId: string;
51
+ bucket?: number;
52
+ pollIntervalMs?: number;
53
+ timeoutMs?: number;
54
+ }
55
+ export interface ConnectRawTcpP2PTransportOptions {
56
+ localCandidates: P2PTransportCandidate[];
57
+ remoteCandidates: P2PTransportCandidate[];
58
+ connectTimeoutMs?: number;
59
+ timeoutMs?: number;
60
+ winnerSelectionWindowMs?: number;
61
+ localAddress?: string;
62
+ nowMs?: () => number;
63
+ sleepMs?: RawTcpP2PSleep;
64
+ connectSocket?: RawTcpP2PConnectSocket;
65
+ }
66
+ export interface RawTcpP2PConnectAttempt {
67
+ local: P2PTransportCandidate;
68
+ remote: P2PTransportCandidate;
69
+ remoteHost: string;
70
+ remotePort: number;
71
+ localAddress?: string;
72
+ localPort?: number;
73
+ rendezvousTimeMs: number;
74
+ timeoutMs: number;
75
+ signal?: AbortSignal;
76
+ }
77
+ export type RawTcpP2PConnectSocket = (attempt: RawTcpP2PConnectAttempt) => Promise<Socket>;
78
+ export type RawTcpP2PSleep = (ms: number, signal?: AbortSignal) => Promise<void>;
79
+ export interface NodeRawTcpP2PConnectSocketEventBase {
80
+ attempt: RawTcpP2PConnectAttempt;
81
+ error?: Error;
82
+ remainingMs?: number;
83
+ retryDelayMs?: number;
84
+ socket?: Socket;
85
+ }
86
+ export type NodeRawTcpP2PConnectSocketEvent = (NodeRawTcpP2PConnectSocketEventBase & {
87
+ type: 'attempt';
88
+ remainingMs: number;
89
+ }) | (NodeRawTcpP2PConnectSocketEventBase & {
90
+ type: 'retry';
91
+ error: Error;
92
+ remainingMs: number;
93
+ retryDelayMs: number;
94
+ }) | (NodeRawTcpP2PConnectSocketEventBase & {
95
+ type: 'success';
96
+ socket: Socket;
97
+ }) | (NodeRawTcpP2PConnectSocketEventBase & {
98
+ type: 'timeout';
99
+ error: Error;
100
+ }) | (NodeRawTcpP2PConnectSocketEventBase & {
101
+ type: 'aborted';
102
+ error?: Error;
103
+ });
104
+ export interface CreateNodeRawTcpP2PConnectSocketOptions {
105
+ retryIntervalMs?: number;
106
+ onEvent?: (event: NodeRawTcpP2PConnectSocketEvent) => void;
107
+ }
108
+ export interface ConnectSignaledRawTcpP2PTransportOptions extends SignaledRawTcpP2PSessionOptions {
109
+ connectTimeoutMs?: number;
110
+ timeoutMs?: number;
111
+ winnerSelectionWindowMs?: number;
112
+ localAddress?: string;
113
+ nowMs?: () => number;
114
+ sleepMs?: RawTcpP2PSleep;
115
+ connectSocket?: RawTcpP2PConnectSocket;
116
+ pollIntervalMs?: number;
117
+ waitTimeoutMs?: number;
118
+ }
119
+ export interface ConnectedSignaledRawTcpP2PTransport extends SignaledRawTcpP2PSession {
120
+ remoteCandidates: P2PTransportCandidate[];
121
+ transport: TcpP2PDataPlaneTransport;
122
+ }
123
+ export interface AcceptSignaledRawTcpP2PConnectionOnceOptions extends AnswerPendingRawTcpP2PSessionsOnceOptions {
124
+ handler: P2PDataPlaneHandler;
125
+ connectTimeoutMs?: number;
126
+ winnerSelectionWindowMs?: number;
127
+ localAddress?: string;
128
+ nowMs?: () => number;
129
+ sleepMs?: RawTcpP2PSleep;
130
+ connectSocket?: RawTcpP2PConnectSocket;
131
+ }
132
+ export interface AcceptedSignaledRawTcpP2PConnection {
133
+ session: P2PSession;
134
+ plan: TcpHolePunchPlan;
135
+ localCandidates: P2PTransportCandidate[];
136
+ remoteCandidates: P2PTransportCandidate[];
137
+ socketHandle: TcpP2PDataPlaneSocketHandle;
138
+ }
139
+ export declare function createNodeRawTcpP2PConnectSocket(options?: CreateNodeRawTcpP2PConnectSocketOptions): RawTcpP2PConnectSocket;
140
+ export declare function createRawTcpHolePunchCandidates(options: CreateRawTcpHolePunchCandidatesOptions): P2PTransportCandidate[];
141
+ export declare function createSignaledRawTcpP2PSession(options: SignaledRawTcpP2PSessionOptions): Promise<SignaledRawTcpP2PSession>;
142
+ export declare function answerPendingRawTcpP2PSessionsOnce(options: AnswerPendingRawTcpP2PSessionsOnceOptions): Promise<P2PSession[]>;
143
+ export declare function acceptSignaledRawTcpP2PConnectionOnce(options: AcceptSignaledRawTcpP2PConnectionOnceOptions): Promise<AcceptedSignaledRawTcpP2PConnection | undefined>;
144
+ export declare function waitForRawTcpRemoteCandidates(options: WaitForRawTcpRemoteCandidatesOptions): Promise<P2PTransportCandidate[]>;
145
+ export declare function connectSignaledRawTcpP2PTransport(options: ConnectSignaledRawTcpP2PTransportOptions): Promise<ConnectedSignaledRawTcpP2PTransport>;
146
+ export declare function connectRawTcpP2PTransport(options: ConnectRawTcpP2PTransportOptions): Promise<TcpP2PDataPlaneTransport>;
147
+ export declare function filterRawTcpRemoteCandidates(candidates: P2PTransportCandidate[], localRole: P2PCandidateRole, localSourceId: string, bucket?: number): P2PTransportCandidate[];
148
+ export declare function selectRawTcpP2PRoute(routes: AccessRoute[]): AccessRoute | undefined;
149
+ export declare function isRawTcpHolePunchCandidate(candidate: P2PTransportCandidate): boolean;