@peers-app/peers-sdk 0.27.4 → 0.28.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 (92) hide show
  1. package/dist/context/user-context.d.ts +7 -1
  2. package/dist/context/user-context.js +4 -9
  3. package/dist/contracts/contract-proxy.d.ts +5 -0
  4. package/dist/contracts/contract-proxy.js +2 -2
  5. package/dist/contracts/contract-resolvers.d.ts +2 -2
  6. package/dist/contracts/contract-resolvers.js +14 -15
  7. package/dist/contracts/contract-transport.d.ts +2 -1
  8. package/dist/contracts/contract-transport.js +24 -2
  9. package/dist/contracts/system/network-contracts.d.ts +1 -1
  10. package/dist/contracts/tool-catalog-service.js +1 -1
  11. package/dist/contracts/tool-catalog.js +6 -2
  12. package/dist/data/assistants.d.ts +3 -3
  13. package/dist/data/authority-write-checks.d.ts +42 -0
  14. package/dist/data/authority-write-checks.js +324 -0
  15. package/dist/data/change-tracking.d.ts +4 -4
  16. package/dist/data/create-group.js +1 -0
  17. package/dist/data/devices.d.ts +27 -4
  18. package/dist/data/devices.js +31 -0
  19. package/dist/data/group-authority.d.ts +111 -0
  20. package/dist/data/group-authority.js +281 -0
  21. package/dist/data/group-members.d.ts +8 -2
  22. package/dist/data/group-members.js +41 -18
  23. package/dist/data/group-permissions.d.ts +15 -31
  24. package/dist/data/group-permissions.js +25 -95
  25. package/dist/data/group-resign.d.ts +38 -0
  26. package/dist/data/group-resign.js +71 -0
  27. package/dist/data/groups.d.ts +11 -0
  28. package/dist/data/groups.js +31 -13
  29. package/dist/data/index.d.ts +3 -0
  30. package/dist/data/index.js +3 -0
  31. package/dist/data/invites.d.ts +14 -0
  32. package/dist/data/orm/index.d.ts +1 -0
  33. package/dist/data/orm/index.js +1 -0
  34. package/dist/data/orm/sql.data-source.d.ts +2 -2
  35. package/dist/data/orm/sql.data-source.js +8 -9
  36. package/dist/data/orm/table-container.js +14 -8
  37. package/dist/data/orm/write-checks.d.ts +89 -0
  38. package/dist/data/orm/write-checks.js +115 -0
  39. package/dist/data/package-table-identity.d.ts +6 -0
  40. package/dist/data/package-table-identity.js +51 -0
  41. package/dist/data/package-version-resolver.d.ts +15 -0
  42. package/dist/data/package-version-resolver.js +58 -3
  43. package/dist/data/package-versions.d.ts +20 -14
  44. package/dist/data/package-versions.js +15 -9
  45. package/dist/data/packages.d.ts +6 -1
  46. package/dist/data/packages.js +15 -20
  47. package/dist/data/persistent-vars.js +2 -39
  48. package/dist/data/sync-recovery-queue.d.ts +4 -4
  49. package/dist/data/sync-recovery-queue.js +7 -1
  50. package/dist/data/tool-access-approvals.d.ts +3 -3
  51. package/dist/data/user-permissions.d.ts +33 -2
  52. package/dist/data/user-permissions.js +87 -10
  53. package/dist/data/users.d.ts +49 -12
  54. package/dist/data/users.js +21 -1
  55. package/dist/data/workflows.d.ts +1 -1
  56. package/dist/device/binary-peer-connection-v2.d.ts +8 -16
  57. package/dist/device/binary-peer-connection-v2.js +15 -31
  58. package/dist/device/connection.d.ts +35 -44
  59. package/dist/device/connection.js +188 -186
  60. package/dist/device/device.d.ts +1 -8
  61. package/dist/device/device.js +1 -30
  62. package/dist/device/frame-cipher.d.ts +1 -1
  63. package/dist/device/frame-cipher.js +1 -1
  64. package/dist/device/get-trust-level-fn.js +3 -6
  65. package/dist/device/socket.type.d.ts +6 -12
  66. package/dist/device-pairing/types.d.ts +26 -26
  67. package/dist/identity/user-row-change.d.ts +3 -1
  68. package/dist/identity/user-row-change.js +33 -18
  69. package/dist/invites/group-approval.js +23 -24
  70. package/dist/invites/invite-messages.d.ts +250 -28
  71. package/dist/invites/invite-token.d.ts +18 -0
  72. package/dist/invites/invite-token.js +2 -0
  73. package/dist/keys.d.ts +7 -0
  74. package/dist/keys.js +27 -0
  75. package/dist/package-installer/package-installer.d.ts +1 -1
  76. package/dist/package-installer/package-installer.js +8 -3
  77. package/dist/package-installer/package-propagation.d.ts +2 -0
  78. package/dist/package-installer/package-propagation.js +20 -38
  79. package/dist/package-installer/package-remote-checker.js +15 -3
  80. package/dist/package-loader/isolated-artifact.js +0 -2
  81. package/dist/package-loader/package-loader.js +6 -0
  82. package/dist/types/peer-device.d.ts +2 -0
  83. package/dist/types/workflow.d.ts +2 -2
  84. package/package.json +1 -1
  85. package/dist/data/package-permissions.d.ts +0 -14
  86. package/dist/data/package-permissions.js +0 -26
  87. package/dist/data/package-version-permissions.d.ts +0 -14
  88. package/dist/data/package-version-permissions.js +0 -30
  89. package/dist/device/binary-peer-connection.d.ts +0 -58
  90. package/dist/device/binary-peer-connection.js +0 -516
  91. package/dist/device/streamed-socket.d.ts +0 -23
  92. package/dist/device/streamed-socket.js +0 -255
@@ -1,516 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createBinaryPeerSocket = createBinaryPeerSocket;
4
- exports.wrapBinaryPeer = wrapBinaryPeer;
5
- exports.wrapWrtc = wrapWrtc;
6
- const msgpack_1 = require("@msgpack/msgpack");
7
- const utils_1 = require("../utils");
8
- const connection_1 = require("./connection");
9
- const get_trust_level_fn_1 = require("./get-trust-level-fn");
10
- const streamed_socket_1 = require("./streamed-socket");
11
- const tx_encoding_1 = require("./tx-encoding");
12
- // Protocol discriminator bytes for multiplexing RPC and raw byte streams
13
- const PROTOCOL_RPC = 0x00;
14
- const PROTOCOL_RAW_BYTES = 0x01;
15
- // Threshold for routing large RPC messages through raw bytes streaming.
16
- // Messages larger than this are sent via the __rpc raw bytes stream,
17
- // automatically chunked to fit transport limits with backpressure.
18
- const LARGE_MESSAGE_THRESHOLD = 64 * 1024; // 64KB
19
- // Transport-specific chunk sizes for the __rpc raw bytes path.
20
- // Must stay under the SCTP single-message limit (~256KB practical max).
21
- const RPC_CHUNK_SIZE_WRTC = 16 * 1024; // 16KB for WebRTC (fits in Unix socket kernel buffer)
22
- const RPC_CHUNK_SIZE_DEFAULT = 512 * 1024; // 512KB for WebSocket
23
- // Reserved stream ID for RPC messages sent via raw bytes
24
- const RPC_STREAM_ID = "__rpc";
25
- // Flags for __rpc stream chunking protocol:
26
- // Each message on the __rpc stream starts with a 1-byte flag.
27
- const RPC_FLAG_SINGLE = 0x00; // [0x00][encoded message] - complete in one message
28
- const RPC_FLAG_START = 0x01; // [0x01][4 bytes: totalSize][chunk data] - first chunk
29
- const RPC_FLAG_CONT = 0x02; // [0x02][chunk data] - continuation chunk
30
- // Cache for encoded stream IDs to avoid TextEncoder allocation on every send/receive
31
- const streamIdBytesCache = new Map();
32
- function getStreamIdBytes(streamId) {
33
- let cached = streamIdBytesCache.get(streamId);
34
- if (!cached) {
35
- cached = new TextEncoder().encode(streamId);
36
- streamIdBytesCache.set(streamId, cached);
37
- }
38
- return cached;
39
- }
40
- // Reverse cache: decode stream IDs from raw bytes without re-creating TextDecoder
41
- const streamIdStringCache = new Map();
42
- function decodeStreamId(bytes) {
43
- // Build a key that uniquely identifies the byte content to avoid collisions
44
- let key = `${bytes.length}`;
45
- for (let i = 0; i < bytes.length; i++) {
46
- key += `:${bytes[i]}`;
47
- }
48
- let cached = streamIdStringCache.get(key);
49
- if (cached !== undefined)
50
- return cached;
51
- cached = new TextDecoder().decode(bytes);
52
- streamIdStringCache.set(key, cached);
53
- return cached;
54
- }
55
- // Encode message metadata + data into a single Uint8Array
56
- function encodeMessage(message) {
57
- // Check if args/result is a Uint8Array - if so, flag it to keep it as raw bytes
58
- let isUint8ArrayData = false;
59
- if (message.type === "call" && message.args instanceof Uint8Array) {
60
- isUint8ArrayData = true;
61
- }
62
- else if (message.type === "callback" && message.result instanceof Uint8Array) {
63
- isUint8ArrayData = true;
64
- }
65
- // Encode metadata using msgpack (without args/result/error - those go in data)
66
- const metadata = {
67
- type: message.type,
68
- callbackId: message.callbackId,
69
- ...(message.eventName !== undefined && { eventName: message.eventName }),
70
- ...(isUint8ArrayData && { isUint8ArrayData: true }),
71
- };
72
- const metadataBytes = (0, msgpack_1.encode)(metadata);
73
- const metadataLength = metadataBytes.length;
74
- // Encode the data payload (args, result, or error)
75
- let dataBytes;
76
- if (message.type === "call" && message.args !== undefined) {
77
- // If args is already a Uint8Array, use it directly without txEncode
78
- if (isUint8ArrayData) {
79
- dataBytes = message.args;
80
- }
81
- else {
82
- dataBytes = (0, tx_encoding_1.txEncode)(message.args);
83
- }
84
- }
85
- else if (message.type === "callback") {
86
- if (message.error !== undefined) {
87
- dataBytes = (0, tx_encoding_1.txEncode)({ error: message.error });
88
- }
89
- else if (isUint8ArrayData) {
90
- // If result is a Uint8Array, use it directly
91
- dataBytes = message.result;
92
- }
93
- else {
94
- dataBytes = (0, tx_encoding_1.txEncode)({ result: message.result });
95
- }
96
- }
97
- else {
98
- dataBytes = new Uint8Array(0);
99
- }
100
- // Create combined buffer: [4 bytes length][metadata][data]
101
- const combined = new Uint8Array(4 + metadataLength + dataBytes.length);
102
- // Write metadata length as 32-bit unsigned integer (big-endian)
103
- const view = new DataView(combined.buffer, combined.byteOffset, combined.byteLength);
104
- view.setUint32(0, metadataLength, false); // big-endian
105
- // Write metadata
106
- combined.set(metadataBytes, 4);
107
- // Write data
108
- combined.set(dataBytes, 4 + metadataLength);
109
- return combined;
110
- }
111
- // Decode binary message back into IMessage
112
- function decodeMessage(bytes) {
113
- // Read metadata length
114
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
115
- const metadataLength = view.getUint32(0, false); // big-endian
116
- // Extract metadata
117
- const metadataBytes = bytes.subarray(4, 4 + metadataLength);
118
- const metadata = (0, msgpack_1.decode)(metadataBytes);
119
- // Extract data
120
- const dataBytes = bytes.subarray(4 + metadataLength);
121
- const message = {
122
- type: metadata.type,
123
- callbackId: metadata.callbackId,
124
- eventName: metadata.eventName,
125
- };
126
- // Decode the data payload
127
- if (dataBytes.length > 0) {
128
- if (message.type === "call") {
129
- // If it was a Uint8Array, use it directly without txDecode
130
- if (metadata.isUint8ArrayData) {
131
- message.args = dataBytes;
132
- }
133
- else {
134
- message.args = (0, tx_encoding_1.txDecode)(dataBytes);
135
- }
136
- }
137
- else if (message.type === "callback") {
138
- if (metadata.isUint8ArrayData) {
139
- // If it was a Uint8Array result, use it directly
140
- message.result = dataBytes;
141
- }
142
- else {
143
- const decoded = (0, tx_encoding_1.txDecode)(dataBytes);
144
- if (decoded.error !== undefined) {
145
- message.error = decoded.error;
146
- }
147
- else {
148
- message.result = decoded.result;
149
- }
150
- }
151
- }
152
- }
153
- return message;
154
- }
155
- const DEFAULT_RECEIVE_LIMITS = Object.freeze({
156
- maxRpcMessageBytes: 256 * 1024 * 1024,
157
- maxStreamMessageBytes: 256 * 1024 * 1024,
158
- reassemblyTimeoutMs: 30_000,
159
- });
160
- /**
161
- * Creates an ISocket from a binary peer without creating a full Connection.
162
- * Useful when you need to pass custom localServerAddresses to the Connection.
163
- */
164
- function createBinaryPeerSocket(connectionId, peer, protocol = "binary", receiveLimitOverrides = {}) {
165
- const handlers = {};
166
- const callbacks = {};
167
- const rawBytesHandlers = {};
168
- let isClosed = false;
169
- const stats = (0, streamed_socket_1.createSocketStats)();
170
- const receiveLimits = { ...DEFAULT_RECEIVE_LIMITS, ...receiveLimitOverrides };
171
- for (const [name, value] of Object.entries(receiveLimits)) {
172
- if (!Number.isSafeInteger(value) || value <= 0) {
173
- throw new Error(`Invalid binary peer receive limit ${name}: ${value}`);
174
- }
175
- }
176
- // Map protocol string to TransportType (needed early for threshold calculations)
177
- const transportType = protocol === "wrtc" ? "wrtc" : protocol === "ws" ? "ws" : "unknown";
178
- // Transport-specific thresholds (computed once)
179
- const HIGH_WATER_MARK = transportType === "wrtc" ? 128 * 1024 : 4 * 1024 * 1024;
180
- const LOW_WATER_MARK = transportType === "wrtc" ? 32 * 1024 : 2 * 1024 * 1024;
181
- const RPC_CHUNK_SIZE = transportType === "wrtc" ? RPC_CHUNK_SIZE_WRTC : RPC_CHUNK_SIZE_DEFAULT;
182
- // Core sendRawBytes implementation - defined early so sendRPCData can use it
183
- const sendRawBytesImpl = async (streamId, data) => {
184
- const sidBytes = getStreamIdBytes(streamId);
185
- const headerLen = 1 + 2 + sidBytes.length;
186
- const packet = new Uint8Array(headerLen + data.length);
187
- packet[0] = PROTOCOL_RAW_BYTES;
188
- const view = new DataView(packet.buffer, packet.byteOffset, packet.byteLength);
189
- view.setUint16(1, sidBytes.length, false);
190
- packet.set(sidBytes, 3);
191
- packet.set(data, headerLen);
192
- // Backpressure: wait for buffer to drain before sending more
193
- if (peer.getBufferedAmount && peer.getBufferedAmount() > HIGH_WATER_MARK) {
194
- await new Promise((resolve) => {
195
- const checkDrain = () => {
196
- if (!peer.getBufferedAmount || peer.getBufferedAmount() < LOW_WATER_MARK) {
197
- resolve();
198
- }
199
- else {
200
- setTimeout(checkDrain, 5);
201
- }
202
- };
203
- peer.on("drain", resolve);
204
- checkDrain();
205
- });
206
- }
207
- stats.bytesSent += packet.length;
208
- stats.messagesSent++;
209
- peer.send(packet);
210
- };
211
- // Serialize large RPC sends so chunked messages don't interleave
212
- let rpcSendQueue = Promise.resolve();
213
- // Helper to send RPC messages - routes large messages through raw bytes streaming
214
- // with automatic chunking to stay within transport single-message limits.
215
- const sendRPCData = (encoded) => {
216
- if (encoded.length <= LARGE_MESSAGE_THRESHOLD) {
217
- // Small message: send directly via PROTOCOL_RPC (no chunking needed)
218
- const withProtocol = new Uint8Array(1 + encoded.length);
219
- withProtocol[0] = PROTOCOL_RPC;
220
- withProtocol.set(encoded, 1);
221
- stats.bytesSent += withProtocol.length;
222
- stats.messagesSent++;
223
- peer.send(withProtocol);
224
- return Promise.resolve();
225
- }
226
- if (encoded.length <= RPC_CHUNK_SIZE) {
227
- // Fits in one raw bytes message: send with SINGLE flag
228
- const msg = new Uint8Array(1 + encoded.length);
229
- msg[0] = RPC_FLAG_SINGLE;
230
- msg.set(encoded, 1);
231
- return sendRawBytesImpl(RPC_STREAM_ID, msg);
232
- }
233
- // Large message: chunk it. Serialize through queue to prevent interleaving.
234
- const sendChunked = async () => {
235
- // First chunk: [FLAG_START][4 bytes totalSize][chunk data]
236
- const firstChunkDataSize = Math.min(RPC_CHUNK_SIZE - 5, encoded.length); // 5 = 1 flag + 4 size
237
- const firstMsg = new Uint8Array(5 + firstChunkDataSize);
238
- firstMsg[0] = RPC_FLAG_START;
239
- const view = new DataView(firstMsg.buffer, firstMsg.byteOffset, firstMsg.byteLength);
240
- view.setUint32(1, encoded.length, false);
241
- firstMsg.set(encoded.subarray(0, firstChunkDataSize), 5);
242
- await sendRawBytesImpl(RPC_STREAM_ID, firstMsg);
243
- // Continuation chunks: [FLAG_CONT][chunk data]
244
- let offset = firstChunkDataSize;
245
- while (offset < encoded.length) {
246
- const end = Math.min(offset + RPC_CHUNK_SIZE - 1, encoded.length); // 1 = flag byte
247
- const contMsg = new Uint8Array(1 + (end - offset));
248
- contMsg[0] = RPC_FLAG_CONT;
249
- contMsg.set(encoded.subarray(offset, end), 1);
250
- await sendRawBytesImpl(RPC_STREAM_ID, contMsg);
251
- offset = end;
252
- }
253
- };
254
- rpcSendQueue = rpcSendQueue.then(sendChunked, sendChunked);
255
- return rpcSendQueue;
256
- };
257
- // Reassembly state for chunked __rpc messages
258
- let rpcReassemblyBuffer = null;
259
- let rpcReassemblyOffset = 0;
260
- let rpcReassemblyTimer;
261
- function clearRpcReassembly() {
262
- if (rpcReassemblyTimer) {
263
- clearTimeout(rpcReassemblyTimer);
264
- rpcReassemblyTimer = undefined;
265
- }
266
- rpcReassemblyBuffer = null;
267
- rpcReassemblyOffset = 0;
268
- }
269
- function closeForProtocolViolation(reason) {
270
- if (isClosed) {
271
- return;
272
- }
273
- console.warn(`Closing ${protocol} peer after binary protocol violation: ${reason}`);
274
- isClosed = true;
275
- clearRpcReassembly();
276
- socket.connected = false;
277
- peer.destroy();
278
- }
279
- // Handle incoming data
280
- peer.on("data", async (data) => {
281
- try {
282
- const bytes = new Uint8Array(data);
283
- stats.bytesReceived += bytes.length;
284
- stats.messagesReceived++;
285
- if (bytes.length === 0)
286
- return;
287
- const protocolType = bytes[0];
288
- // Handle raw bytes stream
289
- if (protocolType === PROTOCOL_RAW_BYTES) {
290
- if (bytes.length < 3)
291
- return;
292
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
293
- const streamIdLength = view.getUint16(1, false);
294
- if (bytes.length < 3 + streamIdLength)
295
- return;
296
- const streamIdBytes = bytes.subarray(3, 3 + streamIdLength);
297
- const streamId = decodeStreamId(streamIdBytes);
298
- const payload = bytes.subarray(3 + streamIdLength);
299
- if (payload.length > receiveLimits.maxStreamMessageBytes) {
300
- closeForProtocolViolation("raw stream frame exceeds the message-size limit");
301
- return;
302
- }
303
- // Check if this is an RPC message sent via raw bytes (for large payloads)
304
- if (streamId === RPC_STREAM_ID) {
305
- if (payload.length === 0)
306
- return;
307
- const flag = payload[0];
308
- if (flag === RPC_FLAG_SINGLE) {
309
- // Complete message in one raw bytes send
310
- if (payload.length - 1 > receiveLimits.maxRpcMessageBytes) {
311
- closeForProtocolViolation("complete RPC exceeds the message-size limit");
312
- return;
313
- }
314
- handleRPCMessage(payload.subarray(1), handlers, callbacks, sendRPCData);
315
- }
316
- else if (flag === RPC_FLAG_START) {
317
- // First chunk of a multi-part message
318
- if (payload.length < 5)
319
- return; // flag + 4 bytes size minimum
320
- const totalSize = new DataView(payload.buffer, payload.byteOffset + 1, 4).getUint32(0, false);
321
- const chunkData = payload.subarray(5);
322
- if (totalSize === 0 ||
323
- totalSize > receiveLimits.maxRpcMessageBytes ||
324
- chunkData.length > totalSize ||
325
- rpcReassemblyBuffer) {
326
- closeForProtocolViolation("invalid, duplicate, or oversized RPC start frame");
327
- return;
328
- }
329
- rpcReassemblyBuffer = new Uint8Array(totalSize);
330
- rpcReassemblyOffset = 0;
331
- rpcReassemblyBuffer.set(chunkData, 0);
332
- rpcReassemblyOffset = chunkData.length;
333
- rpcReassemblyTimer = setTimeout(() => closeForProtocolViolation("RPC reassembly timed out"), receiveLimits.reassemblyTimeoutMs);
334
- rpcReassemblyTimer.unref?.();
335
- // Check if this single START chunk completes the message (unlikely but safe)
336
- if (rpcReassemblyOffset === totalSize) {
337
- handleRPCMessage(rpcReassemblyBuffer, handlers, callbacks, sendRPCData);
338
- clearRpcReassembly();
339
- }
340
- }
341
- else if (flag === RPC_FLAG_CONT) {
342
- // Continuation chunk
343
- if (!rpcReassemblyBuffer)
344
- return; // no START received, discard
345
- const chunkData = payload.subarray(1);
346
- if (chunkData.length > rpcReassemblyBuffer.length - rpcReassemblyOffset) {
347
- closeForProtocolViolation("RPC continuation exceeds declared size");
348
- return;
349
- }
350
- rpcReassemblyBuffer.set(chunkData, rpcReassemblyOffset);
351
- rpcReassemblyOffset += chunkData.length;
352
- if (rpcReassemblyOffset === rpcReassemblyBuffer.length) {
353
- handleRPCMessage(rpcReassemblyBuffer, handlers, callbacks, sendRPCData);
354
- clearRpcReassembly();
355
- }
356
- }
357
- else {
358
- // Legacy/unknown: treat entire payload as a complete RPC message
359
- // (backwards compat with code before chunking was added)
360
- if (payload.length > receiveLimits.maxRpcMessageBytes) {
361
- closeForProtocolViolation("legacy RPC exceeds the message-size limit");
362
- return;
363
- }
364
- handleRPCMessage(payload, handlers, callbacks, sendRPCData);
365
- }
366
- return;
367
- }
368
- const handler = rawBytesHandlers[streamId];
369
- if (handler)
370
- handler(payload);
371
- return;
372
- }
373
- // Handle RPC messages
374
- if (protocolType === PROTOCOL_RPC) {
375
- const rpcBytes = bytes.subarray(1);
376
- if (rpcBytes.length > receiveLimits.maxRpcMessageBytes) {
377
- closeForProtocolViolation("complete RPC exceeds the message-size limit");
378
- return;
379
- }
380
- handleRPCMessage(rpcBytes, handlers, callbacks, sendRPCData);
381
- return;
382
- }
383
- // Legacy format (no discriminator) for backwards compatibility
384
- if (bytes.length > receiveLimits.maxRpcMessageBytes) {
385
- closeForProtocolViolation("legacy RPC exceeds the message-size limit");
386
- return;
387
- }
388
- handleRPCMessage(bytes, handlers, callbacks, sendRPCData);
389
- }
390
- catch (err) {
391
- console.error(`Error parsing ${protocol} message:`, err);
392
- }
393
- });
394
- // Handle closure
395
- peer.on("close", () => {
396
- if (isClosed)
397
- return;
398
- isClosed = true;
399
- clearRpcReassembly();
400
- socket.connected = false;
401
- });
402
- const socket = {
403
- id: connectionId,
404
- connected: true,
405
- handlesOwnEncoding: true,
406
- transportType,
407
- stats,
408
- emit(eventName, args, callback) {
409
- const callbackId = (0, utils_1.newid)();
410
- callbacks[callbackId] = callback;
411
- const message = { type: "call", eventName, args, callbackId };
412
- const encoded = encodeMessage(message);
413
- sendRPCData(encoded);
414
- },
415
- on(eventName, handler) {
416
- handlers[eventName] = handler;
417
- },
418
- removeAllListeners(eventName) {
419
- if (eventName) {
420
- delete handlers[eventName];
421
- }
422
- else {
423
- for (const key of Object.keys(handlers)) {
424
- delete handlers[key];
425
- }
426
- }
427
- },
428
- disconnect() {
429
- peer.destroy();
430
- },
431
- sendRawBytes: sendRawBytesImpl,
432
- onRawBytes(streamId, handler) {
433
- rawBytesHandlers[streamId] = handler;
434
- },
435
- removeRawBytesHandler(streamId) {
436
- delete rawBytesHandlers[streamId];
437
- },
438
- };
439
- return socket;
440
- }
441
- // Helper to handle RPC message parsing
442
- // sendRPCData automatically routes large messages through raw bytes streaming
443
- function handleRPCMessage(bytes, handlers, callbacks, sendRPCData) {
444
- const message = decodeMessage(bytes);
445
- if (message.type === "callback") {
446
- const callback = callbacks[message.callbackId];
447
- if (callback) {
448
- delete callbacks[message.callbackId];
449
- callback(message.error, message.result);
450
- }
451
- return;
452
- }
453
- if (message.type === "call") {
454
- const eventName = message.eventName;
455
- const handler = eventName ? handlers[eventName] : undefined;
456
- if (!handler) {
457
- console.warn(eventName ? `No handler for event: ${eventName}` : "RPC call did not include an event name");
458
- return;
459
- }
460
- try {
461
- const callback = (err, result) => {
462
- const responseMessage = {
463
- type: "callback",
464
- callbackId: message.callbackId,
465
- };
466
- if (err)
467
- responseMessage.error = err;
468
- else
469
- responseMessage.result = result;
470
- const encoded = encodeMessage(responseMessage);
471
- // Use sendRPCData which auto-routes large responses through raw bytes
472
- sendRPCData(encoded);
473
- };
474
- handler(message.args, callback);
475
- }
476
- catch (error) {
477
- console.error("Error in handler", { eventName: message.eventName, error });
478
- const errorMessage = {
479
- type: "callback",
480
- callbackId: message.callbackId,
481
- error: error.message,
482
- };
483
- const encoded = encodeMessage(errorMessage);
484
- sendRPCData(encoded);
485
- }
486
- }
487
- }
488
- /**
489
- * Wraps a binary peer (WebRTC or WebSocket) into a Connection.
490
- * This is the main implementation that handles all binary protocols.
491
- */
492
- function wrapBinaryPeer(connectionId, peer, localDevice, initiator, options, getTrustLevel) {
493
- const { protocol, markTransportSecure, receiveLimits } = options;
494
- // Create the socket wrapper using shared implementation
495
- const socket = createBinaryPeerSocket(connectionId, peer, protocol, receiveLimits);
496
- const serverAddress = `${protocol}://${connectionId}`;
497
- const localServerAddresses = initiator ? undefined : [serverAddress];
498
- if (process.env.NODE_ENV !== "test") {
499
- getTrustLevel ??= (0, get_trust_level_fn_1.getTrustLevelFn)(localDevice, serverAddress);
500
- }
501
- const connection = new connection_1.Connection(socket, localDevice, localServerAddresses, getTrustLevel);
502
- // Mark transport as secure if applicable (WebRTC DTLS-SRTP, wss)
503
- if (markTransportSecure) {
504
- connection.secureLocal = true;
505
- connection.secureRemote = true;
506
- }
507
- return connection;
508
- }
509
- /**
510
- * Wraps a WebRTC peer into a Connection.
511
- * Backwards-compatible wrapper around wrapBinaryPeer.
512
- * WebRTC is encrypted at the transport layer (DTLS-SRTP), so we skip application-level encryption.
513
- */
514
- function wrapWrtc(connectionId, peer, localDevice, initiator, getTrustLevel, receiveLimits) {
515
- return wrapBinaryPeer(connectionId, peer, localDevice, initiator, { protocol: "wrtc", markTransportSecure: true, receiveLimits }, getTrustLevel);
516
- }
@@ -1,23 +0,0 @@
1
- import { type ISocket, type ISocketStats, type RPCCallback } from "./socket.type";
2
- /** Creates a new stats object for tracking socket throughput */
3
- export declare function createSocketStats(): ISocketStats;
4
- export declare class StreamedSocket implements ISocket {
5
- readonly socket: ISocket;
6
- maxChunkSize: number;
7
- readonly safeSocketChunkEventName = "__streamed-socket-chunk";
8
- readonly safeSocketResponseEventName = "__streamed-socket-response";
9
- readonly stats: ISocketStats;
10
- constructor(socket: ISocket, maxChunkSize?: number);
11
- get id(): string | undefined;
12
- get connected(): boolean | undefined;
13
- disconnect(close?: boolean): void;
14
- private readonly callbacks;
15
- emit(eventName: string, args: any, callback: RPCCallback): void;
16
- private handlers;
17
- on(eventName: string, handler: (...args: any[]) => void): void;
18
- removeAllListeners(eventName: string): void;
19
- private readonly chunkBuffers;
20
- private handleChunk;
21
- private processChunks;
22
- private handleResponse;
23
- }