@replit/river 0.10.13 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-GKPT5YQE.js +90 -0
- package/dist/transport/impls/stdio/stdio.cjs +43 -33
- package/dist/transport/impls/stdio/stdio.js +6 -6
- package/dist/transport/impls/unixsocket/client.cjs +43 -33
- package/dist/transport/impls/unixsocket/client.js +6 -6
- package/dist/transport/impls/unixsocket/server.cjs +43 -33
- package/dist/transport/impls/unixsocket/server.js +6 -6
- package/package.json +1 -1
- package/dist/chunk-3MQETIGZ.js +0 -80
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Connection
|
|
3
|
+
} from "./chunk-LQXPKF3A.js";
|
|
4
|
+
|
|
5
|
+
// transport/transforms/messageFraming.ts
|
|
6
|
+
import { Transform } from "node:stream";
|
|
7
|
+
var Uint32LengthPrefixFraming = class extends Transform {
|
|
8
|
+
receivedBuffer;
|
|
9
|
+
maxBufferSizeBytes;
|
|
10
|
+
constructor({
|
|
11
|
+
preAllocatedBufferSize,
|
|
12
|
+
maxBufferSizeBytes,
|
|
13
|
+
...options
|
|
14
|
+
}) {
|
|
15
|
+
super(options);
|
|
16
|
+
this.maxBufferSizeBytes = maxBufferSizeBytes;
|
|
17
|
+
this.receivedBuffer = Buffer.alloc(preAllocatedBufferSize);
|
|
18
|
+
}
|
|
19
|
+
_transform(chunk, _encoding, cb) {
|
|
20
|
+
if (this.receivedBuffer.byteLength + chunk.byteLength > this.maxBufferSizeBytes) {
|
|
21
|
+
const err = new Error(
|
|
22
|
+
`buffer overflow: ${this.receivedBuffer.byteLength}B > ${this.maxBufferSizeBytes}B`
|
|
23
|
+
);
|
|
24
|
+
this.emit("error", err);
|
|
25
|
+
return cb(err);
|
|
26
|
+
}
|
|
27
|
+
this.receivedBuffer = Buffer.concat([this.receivedBuffer, chunk]);
|
|
28
|
+
while (this.receivedBuffer.length > 4) {
|
|
29
|
+
const claimedMessageLength = this.receivedBuffer.readUInt32BE(0) + 4;
|
|
30
|
+
if (this.receivedBuffer.length >= claimedMessageLength) {
|
|
31
|
+
const message = this.receivedBuffer.subarray(4, claimedMessageLength);
|
|
32
|
+
this.push(message);
|
|
33
|
+
this.receivedBuffer = this.receivedBuffer.subarray(claimedMessageLength);
|
|
34
|
+
} else {
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
cb();
|
|
39
|
+
}
|
|
40
|
+
_flush(cb) {
|
|
41
|
+
if (this.receivedBuffer.length) {
|
|
42
|
+
this.emit("error", new Error("got incomplete message while flushing"));
|
|
43
|
+
}
|
|
44
|
+
this.receivedBuffer = Buffer.alloc(0);
|
|
45
|
+
cb();
|
|
46
|
+
}
|
|
47
|
+
_destroy(error, callback) {
|
|
48
|
+
this.receivedBuffer = Buffer.alloc(0);
|
|
49
|
+
super._destroy(error, callback);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
function createLengthEncodedStream(options) {
|
|
53
|
+
return new Uint32LengthPrefixFraming({
|
|
54
|
+
maxBufferSizeBytes: options?.maxBufferSizeBytes ?? 16 * 1024 * 1024,
|
|
55
|
+
// 16MB
|
|
56
|
+
preAllocatedBufferSize: options?.preAllocatedBufferSize ?? 16 * 1024
|
|
57
|
+
// 16KB
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
var MessageFramer = {
|
|
61
|
+
createFramedStream: createLengthEncodedStream,
|
|
62
|
+
write: (buf) => {
|
|
63
|
+
const lengthPrefix = Buffer.alloc(4);
|
|
64
|
+
lengthPrefix.writeUInt32BE(buf.length, 0);
|
|
65
|
+
return Buffer.concat([lengthPrefix, buf]);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// transport/impls/stdio/connection.ts
|
|
70
|
+
var StreamConnection = class extends Connection {
|
|
71
|
+
output;
|
|
72
|
+
constructor(transport, connectedTo, output) {
|
|
73
|
+
super(transport, connectedTo);
|
|
74
|
+
this.output = output;
|
|
75
|
+
}
|
|
76
|
+
send(payload) {
|
|
77
|
+
if (!this.output.writable) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
return this.output.write(MessageFramer.write(payload));
|
|
81
|
+
}
|
|
82
|
+
async close() {
|
|
83
|
+
this.output.end();
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export {
|
|
88
|
+
MessageFramer,
|
|
89
|
+
StreamConnection
|
|
90
|
+
};
|
|
@@ -73,59 +73,69 @@ var NaiveJsonCodec = {
|
|
|
73
73
|
// logging/index.ts
|
|
74
74
|
var log;
|
|
75
75
|
|
|
76
|
-
// transport/transforms/
|
|
76
|
+
// transport/transforms/messageFraming.ts
|
|
77
77
|
var import_node_stream = require("stream");
|
|
78
|
-
var
|
|
79
|
-
|
|
80
|
-
buffer;
|
|
78
|
+
var Uint32LengthPrefixFraming = class extends import_node_stream.Transform {
|
|
79
|
+
receivedBuffer;
|
|
81
80
|
maxBufferSizeBytes;
|
|
82
|
-
constructor({
|
|
81
|
+
constructor({
|
|
82
|
+
preAllocatedBufferSize,
|
|
83
|
+
maxBufferSizeBytes,
|
|
84
|
+
...options
|
|
85
|
+
}) {
|
|
83
86
|
super(options);
|
|
84
87
|
this.maxBufferSizeBytes = maxBufferSizeBytes;
|
|
85
|
-
this.
|
|
86
|
-
this.buffer = Buffer.alloc(0);
|
|
88
|
+
this.receivedBuffer = Buffer.alloc(preAllocatedBufferSize);
|
|
87
89
|
}
|
|
88
|
-
// tldr; backpressure will be automatically applied for transform streams
|
|
89
|
-
// but it relies on both the input/output streams connected on either end having
|
|
90
|
-
// implemented backpressure properly
|
|
91
|
-
// see: https://nodejs.org/en/guides/backpressuring-in-streams#lifecycle-of-pipe
|
|
92
90
|
_transform(chunk, _encoding, cb) {
|
|
93
|
-
|
|
94
|
-
let position;
|
|
95
|
-
while ((position = data.indexOf(this.delimiter)) !== -1) {
|
|
96
|
-
this.push(data.subarray(0, position));
|
|
97
|
-
data = data.subarray(position + this.delimiter.length);
|
|
98
|
-
}
|
|
99
|
-
if (data.byteLength > this.maxBufferSizeBytes) {
|
|
91
|
+
if (this.receivedBuffer.byteLength + chunk.byteLength > this.maxBufferSizeBytes) {
|
|
100
92
|
const err = new Error(
|
|
101
|
-
`buffer overflow: ${
|
|
93
|
+
`buffer overflow: ${this.receivedBuffer.byteLength}B > ${this.maxBufferSizeBytes}B`
|
|
102
94
|
);
|
|
103
95
|
this.emit("error", err);
|
|
104
96
|
return cb(err);
|
|
105
97
|
}
|
|
106
|
-
this.
|
|
98
|
+
this.receivedBuffer = Buffer.concat([this.receivedBuffer, chunk]);
|
|
99
|
+
while (this.receivedBuffer.length > 4) {
|
|
100
|
+
const claimedMessageLength = this.receivedBuffer.readUInt32BE(0) + 4;
|
|
101
|
+
if (this.receivedBuffer.length >= claimedMessageLength) {
|
|
102
|
+
const message = this.receivedBuffer.subarray(4, claimedMessageLength);
|
|
103
|
+
this.push(message);
|
|
104
|
+
this.receivedBuffer = this.receivedBuffer.subarray(claimedMessageLength);
|
|
105
|
+
} else {
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
107
109
|
cb();
|
|
108
110
|
}
|
|
109
111
|
_flush(cb) {
|
|
110
|
-
if (this.
|
|
111
|
-
this.
|
|
112
|
+
if (this.receivedBuffer.length) {
|
|
113
|
+
this.emit("error", new Error("got incomplete message while flushing"));
|
|
112
114
|
}
|
|
113
|
-
this.
|
|
115
|
+
this.receivedBuffer = Buffer.alloc(0);
|
|
114
116
|
cb();
|
|
115
117
|
}
|
|
116
118
|
_destroy(error, callback) {
|
|
117
|
-
this.
|
|
119
|
+
this.receivedBuffer = Buffer.alloc(0);
|
|
118
120
|
super._destroy(error, callback);
|
|
119
121
|
}
|
|
120
122
|
};
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
delimiter: options?.delimiter ?? defaultDelimiter,
|
|
125
|
-
maxBufferSizeBytes: options?.maxBufferSizeBytes ?? 16 * 1024 * 1024
|
|
123
|
+
function createLengthEncodedStream(options) {
|
|
124
|
+
return new Uint32LengthPrefixFraming({
|
|
125
|
+
maxBufferSizeBytes: options?.maxBufferSizeBytes ?? 16 * 1024 * 1024,
|
|
126
126
|
// 16MB
|
|
127
|
+
preAllocatedBufferSize: options?.preAllocatedBufferSize ?? 16 * 1024
|
|
128
|
+
// 16KB
|
|
127
129
|
});
|
|
128
130
|
}
|
|
131
|
+
var MessageFramer = {
|
|
132
|
+
createFramedStream: createLengthEncodedStream,
|
|
133
|
+
write: (buf) => {
|
|
134
|
+
const lengthPrefix = Buffer.alloc(4);
|
|
135
|
+
lengthPrefix.writeUInt32BE(buf.length, 0);
|
|
136
|
+
return Buffer.concat([lengthPrefix, buf]);
|
|
137
|
+
}
|
|
138
|
+
};
|
|
129
139
|
|
|
130
140
|
// transport/transport.ts
|
|
131
141
|
var import_value = require("@sinclair/typebox/value");
|
|
@@ -444,7 +454,7 @@ var StreamConnection = class extends Connection {
|
|
|
444
454
|
if (!this.output.writable) {
|
|
445
455
|
return false;
|
|
446
456
|
}
|
|
447
|
-
return this.output.write(
|
|
457
|
+
return this.output.write(MessageFramer.write(payload));
|
|
448
458
|
}
|
|
449
459
|
async close() {
|
|
450
460
|
this.output.end();
|
|
@@ -467,8 +477,8 @@ var StdioTransport = class extends Transport {
|
|
|
467
477
|
constructor(clientId, input = process.stdin, output = process.stdout, providedOptions) {
|
|
468
478
|
const options = { ...defaultOptions, ...providedOptions };
|
|
469
479
|
super(options.codec, clientId);
|
|
470
|
-
const
|
|
471
|
-
this.input = input.pipe(
|
|
480
|
+
const framedMessageStream = MessageFramer.createFramedStream();
|
|
481
|
+
this.input = input.pipe(framedMessageStream);
|
|
472
482
|
this.output = output;
|
|
473
483
|
let conn = void 0;
|
|
474
484
|
this.input.on("data", (msg) => {
|
|
@@ -480,7 +490,7 @@ var StdioTransport = class extends Transport {
|
|
|
480
490
|
this.handleMsg(parsedMsg);
|
|
481
491
|
});
|
|
482
492
|
const cleanup = () => {
|
|
483
|
-
|
|
493
|
+
framedMessageStream.destroy();
|
|
484
494
|
if (conn) {
|
|
485
495
|
this.onDisconnect(conn);
|
|
486
496
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from "../../../chunk-
|
|
2
|
+
MessageFramer,
|
|
3
|
+
StreamConnection
|
|
4
|
+
} from "../../../chunk-GKPT5YQE.js";
|
|
5
5
|
import "../../../chunk-ORAG7IAU.js";
|
|
6
6
|
import {
|
|
7
7
|
NaiveJsonCodec
|
|
@@ -30,8 +30,8 @@ var StdioTransport = class extends Transport {
|
|
|
30
30
|
constructor(clientId, input = process.stdin, output = process.stdout, providedOptions) {
|
|
31
31
|
const options = { ...defaultOptions, ...providedOptions };
|
|
32
32
|
super(options.codec, clientId);
|
|
33
|
-
const
|
|
34
|
-
this.input = input.pipe(
|
|
33
|
+
const framedMessageStream = MessageFramer.createFramedStream();
|
|
34
|
+
this.input = input.pipe(framedMessageStream);
|
|
35
35
|
this.output = output;
|
|
36
36
|
let conn = void 0;
|
|
37
37
|
this.input.on("data", (msg) => {
|
|
@@ -43,7 +43,7 @@ var StdioTransport = class extends Transport {
|
|
|
43
43
|
this.handleMsg(parsedMsg);
|
|
44
44
|
});
|
|
45
45
|
const cleanup = () => {
|
|
46
|
-
|
|
46
|
+
framedMessageStream.destroy();
|
|
47
47
|
if (conn) {
|
|
48
48
|
this.onDisconnect(conn);
|
|
49
49
|
}
|
|
@@ -379,59 +379,69 @@ var NaiveJsonCodec = {
|
|
|
379
379
|
}
|
|
380
380
|
};
|
|
381
381
|
|
|
382
|
-
// transport/transforms/
|
|
382
|
+
// transport/transforms/messageFraming.ts
|
|
383
383
|
var import_node_stream = require("stream");
|
|
384
|
-
var
|
|
385
|
-
|
|
386
|
-
buffer;
|
|
384
|
+
var Uint32LengthPrefixFraming = class extends import_node_stream.Transform {
|
|
385
|
+
receivedBuffer;
|
|
387
386
|
maxBufferSizeBytes;
|
|
388
|
-
constructor({
|
|
387
|
+
constructor({
|
|
388
|
+
preAllocatedBufferSize,
|
|
389
|
+
maxBufferSizeBytes,
|
|
390
|
+
...options
|
|
391
|
+
}) {
|
|
389
392
|
super(options);
|
|
390
393
|
this.maxBufferSizeBytes = maxBufferSizeBytes;
|
|
391
|
-
this.
|
|
392
|
-
this.buffer = Buffer.alloc(0);
|
|
394
|
+
this.receivedBuffer = Buffer.alloc(preAllocatedBufferSize);
|
|
393
395
|
}
|
|
394
|
-
// tldr; backpressure will be automatically applied for transform streams
|
|
395
|
-
// but it relies on both the input/output streams connected on either end having
|
|
396
|
-
// implemented backpressure properly
|
|
397
|
-
// see: https://nodejs.org/en/guides/backpressuring-in-streams#lifecycle-of-pipe
|
|
398
396
|
_transform(chunk, _encoding, cb) {
|
|
399
|
-
|
|
400
|
-
let position;
|
|
401
|
-
while ((position = data.indexOf(this.delimiter)) !== -1) {
|
|
402
|
-
this.push(data.subarray(0, position));
|
|
403
|
-
data = data.subarray(position + this.delimiter.length);
|
|
404
|
-
}
|
|
405
|
-
if (data.byteLength > this.maxBufferSizeBytes) {
|
|
397
|
+
if (this.receivedBuffer.byteLength + chunk.byteLength > this.maxBufferSizeBytes) {
|
|
406
398
|
const err = new Error(
|
|
407
|
-
`buffer overflow: ${
|
|
399
|
+
`buffer overflow: ${this.receivedBuffer.byteLength}B > ${this.maxBufferSizeBytes}B`
|
|
408
400
|
);
|
|
409
401
|
this.emit("error", err);
|
|
410
402
|
return cb(err);
|
|
411
403
|
}
|
|
412
|
-
this.
|
|
404
|
+
this.receivedBuffer = Buffer.concat([this.receivedBuffer, chunk]);
|
|
405
|
+
while (this.receivedBuffer.length > 4) {
|
|
406
|
+
const claimedMessageLength = this.receivedBuffer.readUInt32BE(0) + 4;
|
|
407
|
+
if (this.receivedBuffer.length >= claimedMessageLength) {
|
|
408
|
+
const message = this.receivedBuffer.subarray(4, claimedMessageLength);
|
|
409
|
+
this.push(message);
|
|
410
|
+
this.receivedBuffer = this.receivedBuffer.subarray(claimedMessageLength);
|
|
411
|
+
} else {
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
413
415
|
cb();
|
|
414
416
|
}
|
|
415
417
|
_flush(cb) {
|
|
416
|
-
if (this.
|
|
417
|
-
this.
|
|
418
|
+
if (this.receivedBuffer.length) {
|
|
419
|
+
this.emit("error", new Error("got incomplete message while flushing"));
|
|
418
420
|
}
|
|
419
|
-
this.
|
|
421
|
+
this.receivedBuffer = Buffer.alloc(0);
|
|
420
422
|
cb();
|
|
421
423
|
}
|
|
422
424
|
_destroy(error, callback) {
|
|
423
|
-
this.
|
|
425
|
+
this.receivedBuffer = Buffer.alloc(0);
|
|
424
426
|
super._destroy(error, callback);
|
|
425
427
|
}
|
|
426
428
|
};
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
delimiter: options?.delimiter ?? defaultDelimiter,
|
|
431
|
-
maxBufferSizeBytes: options?.maxBufferSizeBytes ?? 16 * 1024 * 1024
|
|
429
|
+
function createLengthEncodedStream(options) {
|
|
430
|
+
return new Uint32LengthPrefixFraming({
|
|
431
|
+
maxBufferSizeBytes: options?.maxBufferSizeBytes ?? 16 * 1024 * 1024,
|
|
432
432
|
// 16MB
|
|
433
|
+
preAllocatedBufferSize: options?.preAllocatedBufferSize ?? 16 * 1024
|
|
434
|
+
// 16KB
|
|
433
435
|
});
|
|
434
436
|
}
|
|
437
|
+
var MessageFramer = {
|
|
438
|
+
createFramedStream: createLengthEncodedStream,
|
|
439
|
+
write: (buf) => {
|
|
440
|
+
const lengthPrefix = Buffer.alloc(4);
|
|
441
|
+
lengthPrefix.writeUInt32BE(buf.length, 0);
|
|
442
|
+
return Buffer.concat([lengthPrefix, buf]);
|
|
443
|
+
}
|
|
444
|
+
};
|
|
435
445
|
|
|
436
446
|
// transport/impls/unixsocket/client.ts
|
|
437
447
|
var import_node_net = require("net");
|
|
@@ -447,7 +457,7 @@ var StreamConnection = class extends Connection {
|
|
|
447
457
|
if (!this.output.writable) {
|
|
448
458
|
return false;
|
|
449
459
|
}
|
|
450
|
-
return this.output.write(
|
|
460
|
+
return this.output.write(MessageFramer.write(payload));
|
|
451
461
|
}
|
|
452
462
|
async close() {
|
|
453
463
|
this.output.end();
|
|
@@ -477,15 +487,15 @@ var UnixDomainSocketClientTransport = class extends Transport {
|
|
|
477
487
|
}
|
|
478
488
|
const sock = (0, import_node_net.createConnection)(this.path);
|
|
479
489
|
const conn = new StreamConnection(this, to, sock);
|
|
480
|
-
const
|
|
481
|
-
sock.pipe(
|
|
490
|
+
const framedMessageStream = MessageFramer.createFramedStream();
|
|
491
|
+
sock.pipe(framedMessageStream).on("data", (data) => {
|
|
482
492
|
const parsedMsg = this.parseMsg(data);
|
|
483
493
|
if (parsedMsg) {
|
|
484
494
|
this.handleMsg(parsedMsg);
|
|
485
495
|
}
|
|
486
496
|
});
|
|
487
497
|
const cleanup = () => {
|
|
488
|
-
|
|
498
|
+
framedMessageStream.destroy();
|
|
489
499
|
if (conn) {
|
|
490
500
|
this.onDisconnect(conn);
|
|
491
501
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from "../../../chunk-
|
|
2
|
+
MessageFramer,
|
|
3
|
+
StreamConnection
|
|
4
|
+
} from "../../../chunk-GKPT5YQE.js";
|
|
5
5
|
import "../../../chunk-ORAG7IAU.js";
|
|
6
6
|
import "../../../chunk-WVT5QXMZ.js";
|
|
7
7
|
import {
|
|
@@ -39,15 +39,15 @@ var UnixDomainSocketClientTransport = class extends Transport {
|
|
|
39
39
|
}
|
|
40
40
|
const sock = createConnection(this.path);
|
|
41
41
|
const conn = new StreamConnection(this, to, sock);
|
|
42
|
-
const
|
|
43
|
-
sock.pipe(
|
|
42
|
+
const framedMessageStream = MessageFramer.createFramedStream();
|
|
43
|
+
sock.pipe(framedMessageStream).on("data", (data) => {
|
|
44
44
|
const parsedMsg = this.parseMsg(data);
|
|
45
45
|
if (parsedMsg) {
|
|
46
46
|
this.handleMsg(parsedMsg);
|
|
47
47
|
}
|
|
48
48
|
});
|
|
49
49
|
const cleanup = () => {
|
|
50
|
-
|
|
50
|
+
framedMessageStream.destroy();
|
|
51
51
|
if (conn) {
|
|
52
52
|
this.onDisconnect(conn);
|
|
53
53
|
}
|
|
@@ -379,59 +379,69 @@ var NaiveJsonCodec = {
|
|
|
379
379
|
}
|
|
380
380
|
};
|
|
381
381
|
|
|
382
|
-
// transport/transforms/
|
|
382
|
+
// transport/transforms/messageFraming.ts
|
|
383
383
|
var import_node_stream = require("stream");
|
|
384
|
-
var
|
|
385
|
-
|
|
386
|
-
buffer;
|
|
384
|
+
var Uint32LengthPrefixFraming = class extends import_node_stream.Transform {
|
|
385
|
+
receivedBuffer;
|
|
387
386
|
maxBufferSizeBytes;
|
|
388
|
-
constructor({
|
|
387
|
+
constructor({
|
|
388
|
+
preAllocatedBufferSize,
|
|
389
|
+
maxBufferSizeBytes,
|
|
390
|
+
...options
|
|
391
|
+
}) {
|
|
389
392
|
super(options);
|
|
390
393
|
this.maxBufferSizeBytes = maxBufferSizeBytes;
|
|
391
|
-
this.
|
|
392
|
-
this.buffer = Buffer.alloc(0);
|
|
394
|
+
this.receivedBuffer = Buffer.alloc(preAllocatedBufferSize);
|
|
393
395
|
}
|
|
394
|
-
// tldr; backpressure will be automatically applied for transform streams
|
|
395
|
-
// but it relies on both the input/output streams connected on either end having
|
|
396
|
-
// implemented backpressure properly
|
|
397
|
-
// see: https://nodejs.org/en/guides/backpressuring-in-streams#lifecycle-of-pipe
|
|
398
396
|
_transform(chunk, _encoding, cb) {
|
|
399
|
-
|
|
400
|
-
let position;
|
|
401
|
-
while ((position = data.indexOf(this.delimiter)) !== -1) {
|
|
402
|
-
this.push(data.subarray(0, position));
|
|
403
|
-
data = data.subarray(position + this.delimiter.length);
|
|
404
|
-
}
|
|
405
|
-
if (data.byteLength > this.maxBufferSizeBytes) {
|
|
397
|
+
if (this.receivedBuffer.byteLength + chunk.byteLength > this.maxBufferSizeBytes) {
|
|
406
398
|
const err = new Error(
|
|
407
|
-
`buffer overflow: ${
|
|
399
|
+
`buffer overflow: ${this.receivedBuffer.byteLength}B > ${this.maxBufferSizeBytes}B`
|
|
408
400
|
);
|
|
409
401
|
this.emit("error", err);
|
|
410
402
|
return cb(err);
|
|
411
403
|
}
|
|
412
|
-
this.
|
|
404
|
+
this.receivedBuffer = Buffer.concat([this.receivedBuffer, chunk]);
|
|
405
|
+
while (this.receivedBuffer.length > 4) {
|
|
406
|
+
const claimedMessageLength = this.receivedBuffer.readUInt32BE(0) + 4;
|
|
407
|
+
if (this.receivedBuffer.length >= claimedMessageLength) {
|
|
408
|
+
const message = this.receivedBuffer.subarray(4, claimedMessageLength);
|
|
409
|
+
this.push(message);
|
|
410
|
+
this.receivedBuffer = this.receivedBuffer.subarray(claimedMessageLength);
|
|
411
|
+
} else {
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
413
415
|
cb();
|
|
414
416
|
}
|
|
415
417
|
_flush(cb) {
|
|
416
|
-
if (this.
|
|
417
|
-
this.
|
|
418
|
+
if (this.receivedBuffer.length) {
|
|
419
|
+
this.emit("error", new Error("got incomplete message while flushing"));
|
|
418
420
|
}
|
|
419
|
-
this.
|
|
421
|
+
this.receivedBuffer = Buffer.alloc(0);
|
|
420
422
|
cb();
|
|
421
423
|
}
|
|
422
424
|
_destroy(error, callback) {
|
|
423
|
-
this.
|
|
425
|
+
this.receivedBuffer = Buffer.alloc(0);
|
|
424
426
|
super._destroy(error, callback);
|
|
425
427
|
}
|
|
426
428
|
};
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
delimiter: options?.delimiter ?? defaultDelimiter,
|
|
431
|
-
maxBufferSizeBytes: options?.maxBufferSizeBytes ?? 16 * 1024 * 1024
|
|
429
|
+
function createLengthEncodedStream(options) {
|
|
430
|
+
return new Uint32LengthPrefixFraming({
|
|
431
|
+
maxBufferSizeBytes: options?.maxBufferSizeBytes ?? 16 * 1024 * 1024,
|
|
432
432
|
// 16MB
|
|
433
|
+
preAllocatedBufferSize: options?.preAllocatedBufferSize ?? 16 * 1024
|
|
434
|
+
// 16KB
|
|
433
435
|
});
|
|
434
436
|
}
|
|
437
|
+
var MessageFramer = {
|
|
438
|
+
createFramedStream: createLengthEncodedStream,
|
|
439
|
+
write: (buf) => {
|
|
440
|
+
const lengthPrefix = Buffer.alloc(4);
|
|
441
|
+
lengthPrefix.writeUInt32BE(buf.length, 0);
|
|
442
|
+
return Buffer.concat([lengthPrefix, buf]);
|
|
443
|
+
}
|
|
444
|
+
};
|
|
435
445
|
|
|
436
446
|
// transport/impls/stdio/connection.ts
|
|
437
447
|
var StreamConnection = class extends Connection {
|
|
@@ -444,7 +454,7 @@ var StreamConnection = class extends Connection {
|
|
|
444
454
|
if (!this.output.writable) {
|
|
445
455
|
return false;
|
|
446
456
|
}
|
|
447
|
-
return this.output.write(
|
|
457
|
+
return this.output.write(MessageFramer.write(payload));
|
|
448
458
|
}
|
|
449
459
|
async close() {
|
|
450
460
|
this.output.end();
|
|
@@ -468,8 +478,8 @@ var UnixDomainSocketServerTransport = class extends Transport {
|
|
|
468
478
|
}
|
|
469
479
|
connectionListener = (sock) => {
|
|
470
480
|
let conn = void 0;
|
|
471
|
-
const
|
|
472
|
-
sock.pipe(
|
|
481
|
+
const framedMessageStream = MessageFramer.createFramedStream();
|
|
482
|
+
sock.pipe(framedMessageStream).on("data", (data) => {
|
|
473
483
|
const parsedMsg = this.parseMsg(data);
|
|
474
484
|
if (!parsedMsg) {
|
|
475
485
|
return;
|
|
@@ -481,7 +491,7 @@ var UnixDomainSocketServerTransport = class extends Transport {
|
|
|
481
491
|
this.handleMsg(parsedMsg);
|
|
482
492
|
});
|
|
483
493
|
const cleanup = () => {
|
|
484
|
-
|
|
494
|
+
framedMessageStream.destroy();
|
|
485
495
|
if (conn) {
|
|
486
496
|
this.onDisconnect(conn);
|
|
487
497
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from "../../../chunk-
|
|
2
|
+
MessageFramer,
|
|
3
|
+
StreamConnection
|
|
4
|
+
} from "../../../chunk-GKPT5YQE.js";
|
|
5
5
|
import "../../../chunk-ORAG7IAU.js";
|
|
6
6
|
import "../../../chunk-WVT5QXMZ.js";
|
|
7
7
|
import {
|
|
@@ -32,8 +32,8 @@ var UnixDomainSocketServerTransport = class extends Transport {
|
|
|
32
32
|
}
|
|
33
33
|
connectionListener = (sock) => {
|
|
34
34
|
let conn = void 0;
|
|
35
|
-
const
|
|
36
|
-
sock.pipe(
|
|
35
|
+
const framedMessageStream = MessageFramer.createFramedStream();
|
|
36
|
+
sock.pipe(framedMessageStream).on("data", (data) => {
|
|
37
37
|
const parsedMsg = this.parseMsg(data);
|
|
38
38
|
if (!parsedMsg) {
|
|
39
39
|
return;
|
|
@@ -45,7 +45,7 @@ var UnixDomainSocketServerTransport = class extends Transport {
|
|
|
45
45
|
this.handleMsg(parsedMsg);
|
|
46
46
|
});
|
|
47
47
|
const cleanup = () => {
|
|
48
|
-
|
|
48
|
+
framedMessageStream.destroy();
|
|
49
49
|
if (conn) {
|
|
50
50
|
this.onDisconnect(conn);
|
|
51
51
|
}
|
package/package.json
CHANGED
package/dist/chunk-3MQETIGZ.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Connection
|
|
3
|
-
} from "./chunk-LQXPKF3A.js";
|
|
4
|
-
|
|
5
|
-
// transport/transforms/delim.ts
|
|
6
|
-
import { Transform } from "node:stream";
|
|
7
|
-
var DelimiterParser = class extends Transform {
|
|
8
|
-
delimiter;
|
|
9
|
-
buffer;
|
|
10
|
-
maxBufferSizeBytes;
|
|
11
|
-
constructor({ delimiter, maxBufferSizeBytes, ...options }) {
|
|
12
|
-
super(options);
|
|
13
|
-
this.maxBufferSizeBytes = maxBufferSizeBytes;
|
|
14
|
-
this.delimiter = Buffer.from(delimiter);
|
|
15
|
-
this.buffer = Buffer.alloc(0);
|
|
16
|
-
}
|
|
17
|
-
// tldr; backpressure will be automatically applied for transform streams
|
|
18
|
-
// but it relies on both the input/output streams connected on either end having
|
|
19
|
-
// implemented backpressure properly
|
|
20
|
-
// see: https://nodejs.org/en/guides/backpressuring-in-streams#lifecycle-of-pipe
|
|
21
|
-
_transform(chunk, _encoding, cb) {
|
|
22
|
-
let data = Buffer.concat([this.buffer, chunk]);
|
|
23
|
-
let position;
|
|
24
|
-
while ((position = data.indexOf(this.delimiter)) !== -1) {
|
|
25
|
-
this.push(data.subarray(0, position));
|
|
26
|
-
data = data.subarray(position + this.delimiter.length);
|
|
27
|
-
}
|
|
28
|
-
if (data.byteLength > this.maxBufferSizeBytes) {
|
|
29
|
-
const err = new Error(
|
|
30
|
-
`buffer overflow: ${data.byteLength}B > ${this.maxBufferSizeBytes}B`
|
|
31
|
-
);
|
|
32
|
-
this.emit("error", err);
|
|
33
|
-
return cb(err);
|
|
34
|
-
}
|
|
35
|
-
this.buffer = data;
|
|
36
|
-
cb();
|
|
37
|
-
}
|
|
38
|
-
_flush(cb) {
|
|
39
|
-
if (this.buffer.length) {
|
|
40
|
-
this.push(this.buffer);
|
|
41
|
-
}
|
|
42
|
-
this.buffer = Buffer.alloc(0);
|
|
43
|
-
cb();
|
|
44
|
-
}
|
|
45
|
-
_destroy(error, callback) {
|
|
46
|
-
this.buffer = Buffer.alloc(0);
|
|
47
|
-
super._destroy(error, callback);
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
var defaultDelimiter = Buffer.from("\n");
|
|
51
|
-
function createDelimitedStream(options) {
|
|
52
|
-
return new DelimiterParser({
|
|
53
|
-
delimiter: options?.delimiter ?? defaultDelimiter,
|
|
54
|
-
maxBufferSizeBytes: options?.maxBufferSizeBytes ?? 16 * 1024 * 1024
|
|
55
|
-
// 16MB
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// transport/impls/stdio/connection.ts
|
|
60
|
-
var StreamConnection = class extends Connection {
|
|
61
|
-
output;
|
|
62
|
-
constructor(transport, connectedTo, output) {
|
|
63
|
-
super(transport, connectedTo);
|
|
64
|
-
this.output = output;
|
|
65
|
-
}
|
|
66
|
-
send(payload) {
|
|
67
|
-
if (!this.output.writable) {
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
return this.output.write(Buffer.concat([payload, defaultDelimiter]));
|
|
71
|
-
}
|
|
72
|
-
async close() {
|
|
73
|
-
this.output.end();
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export {
|
|
78
|
-
createDelimitedStream,
|
|
79
|
-
StreamConnection
|
|
80
|
-
};
|