@theia/terminal 1.28.0-next.9 → 1.29.0-next.2

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.
@@ -0,0 +1,31 @@
1
+ /// <reference types="node" />
2
+ import { Emitter, Event } from '@theia/core/lib/common/event';
3
+ export interface BufferingStreamOptions {
4
+ /**
5
+ * Max size in bytes of the chunks being emitted.
6
+ */
7
+ maxChunkSize?: number;
8
+ /**
9
+ * Amount of time in milliseconds to wait between the moment we start
10
+ * buffering data and when we emit the buffered chunk.
11
+ */
12
+ emitInterval?: number;
13
+ }
14
+ /**
15
+ * This component will buffer whatever is pushed to it and emit chunks back
16
+ * every {@link BufferingStreamOptions.emitInterval}. It will also ensure that
17
+ * the emitted chunks never exceed {@link BufferingStreamOptions.maxChunkSize}.
18
+ */
19
+ export declare class BufferingStream {
20
+ protected buffer?: Buffer;
21
+ protected timeout?: NodeJS.Timeout;
22
+ protected maxChunkSize: number;
23
+ protected emitInterval: number;
24
+ protected onDataEmitter: Emitter<Buffer>;
25
+ constructor(options?: BufferingStreamOptions);
26
+ get onData(): Event<Buffer>;
27
+ push(chunk: Buffer): void;
28
+ dispose(): void;
29
+ protected emitBufferedChunk(): void;
30
+ }
31
+ //# sourceMappingURL=buffering-stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buffering-stream.d.ts","sourceRoot":"","sources":["../../src/node/buffering-stream.ts"],"names":[],"mappings":";AAgBA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAE9D,MAAM,WAAW,sBAAsB;IACnC;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;;;GAIG;AACH,qBAAa,eAAe;IAExB,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC;IACnC,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC;IAC/B,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC;IAE/B,SAAS,CAAC,aAAa,kBAAyB;gBAEpC,OAAO,CAAC,EAAE,sBAAsB;IAK5C,IAAI,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAE1B;IAED,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IASzB,OAAO,IAAI,IAAI;IAMf,SAAS,CAAC,iBAAiB,IAAI,IAAI;CAStC"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2022 Ericsson and others.
4
+ //
5
+ // This program and the accompanying materials are made available under the
6
+ // terms of the Eclipse Public License v. 2.0 which is available at
7
+ // http://www.eclipse.org/legal/epl-2.0.
8
+ //
9
+ // This Source Code may also be made available under the following Secondary
10
+ // Licenses when the conditions for such availability set forth in the Eclipse
11
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
+ // with the GNU Classpath Exception which is available at
13
+ // https://www.gnu.org/software/classpath/license.html.
14
+ //
15
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
16
+ // *****************************************************************************
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.BufferingStream = void 0;
19
+ const event_1 = require("@theia/core/lib/common/event");
20
+ /**
21
+ * This component will buffer whatever is pushed to it and emit chunks back
22
+ * every {@link BufferingStreamOptions.emitInterval}. It will also ensure that
23
+ * the emitted chunks never exceed {@link BufferingStreamOptions.maxChunkSize}.
24
+ */
25
+ class BufferingStream {
26
+ constructor(options) {
27
+ var _a, _b;
28
+ this.onDataEmitter = new event_1.Emitter();
29
+ this.emitInterval = (_a = options === null || options === void 0 ? void 0 : options.emitInterval) !== null && _a !== void 0 ? _a : 16; // ms
30
+ this.maxChunkSize = (_b = options === null || options === void 0 ? void 0 : options.maxChunkSize) !== null && _b !== void 0 ? _b : (256 * 1024); // bytes
31
+ }
32
+ get onData() {
33
+ return this.onDataEmitter.event;
34
+ }
35
+ push(chunk) {
36
+ if (this.buffer) {
37
+ this.buffer = Buffer.concat([this.buffer, chunk]);
38
+ }
39
+ else {
40
+ this.buffer = chunk;
41
+ this.timeout = setTimeout(() => this.emitBufferedChunk(), this.emitInterval);
42
+ }
43
+ }
44
+ dispose() {
45
+ clearTimeout(this.timeout);
46
+ this.buffer = undefined;
47
+ this.onDataEmitter.dispose();
48
+ }
49
+ emitBufferedChunk() {
50
+ this.onDataEmitter.fire(this.buffer.slice(0, this.maxChunkSize));
51
+ if (this.buffer.byteLength <= this.maxChunkSize) {
52
+ this.buffer = undefined;
53
+ }
54
+ else {
55
+ this.buffer = this.buffer.slice(this.maxChunkSize);
56
+ this.timeout = setTimeout(() => this.emitBufferedChunk(), this.emitInterval);
57
+ }
58
+ }
59
+ }
60
+ exports.BufferingStream = BufferingStream;
61
+ //# sourceMappingURL=buffering-stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buffering-stream.js","sourceRoot":"","sources":["../../src/node/buffering-stream.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,0CAA0C;AAC1C,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,2EAA2E;AAC3E,gFAAgF;;;AAEhF,wDAA8D;AAc9D;;;;GAIG;AACH,MAAa,eAAe;IASxB,YAAY,OAAgC;;QAFlC,kBAAa,GAAG,IAAI,eAAO,EAAU,CAAC;QAG5C,IAAI,CAAC,YAAY,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,YAAY,mCAAI,EAAE,CAAC,CAAC,KAAK;QACtD,IAAI,CAAC,YAAY,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,YAAY,mCAAI,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ;IACvE,CAAC;IAED,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;IACpC,CAAC;IAED,IAAI,CAAC,KAAa;QACd,IAAI,IAAI,CAAC,MAAM,EAAE;YACb,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;SACrD;aAAM;YACH,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;YACpB,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;SAChF;IACL,CAAC;IAED,OAAO;QACH,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACxB,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;IACjC,CAAC;IAES,iBAAiB;QACvB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QAClE,IAAI,IAAI,CAAC,MAAO,CAAC,UAAU,IAAI,IAAI,CAAC,YAAY,EAAE;YAC9C,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;SAC3B;aAAM;YACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAO,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACpD,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;SAChF;IACL,CAAC;CACJ;AA1CD,0CA0CC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=buffering-stream.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buffering-stream.spec.d.ts","sourceRoot":"","sources":["../../src/node/buffering-stream.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2022 Ericsson and others.
4
+ //
5
+ // This program and the accompanying materials are made available under the
6
+ // terms of the Eclipse Public License v. 2.0 which is available at
7
+ // http://www.eclipse.org/legal/epl-2.0.
8
+ //
9
+ // This Source Code may also be made available under the following Secondary
10
+ // Licenses when the conditions for such availability set forth in the Eclipse
11
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
+ // with the GNU Classpath Exception which is available at
13
+ // https://www.gnu.org/software/classpath/license.html.
14
+ //
15
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
16
+ // *****************************************************************************
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ const promise_util_1 = require("@theia/core/lib/common/promise-util");
19
+ const chai_1 = require("chai");
20
+ const buffering_stream_1 = require("./buffering-stream");
21
+ describe('BufferringStream', () => {
22
+ it('should emit whatever data was buffered before the timeout', async () => {
23
+ const buffer = new buffering_stream_1.BufferingStream({ emitInterval: 1000 });
24
+ const chunkPromise = waitForChunk(buffer);
25
+ buffer.push(Buffer.from([0]));
26
+ await (0, promise_util_1.wait)(100);
27
+ buffer.push(Buffer.from([1]));
28
+ await (0, promise_util_1.wait)(100);
29
+ buffer.push(Buffer.from([2, 3, 4]));
30
+ const chunk = await chunkPromise;
31
+ (0, chai_1.expect)(chunk).deep.eq(Buffer.from([0, 1, 2, 3, 4]));
32
+ });
33
+ it('should not emit chunks bigger than maxChunkSize', async () => {
34
+ const buffer = new buffering_stream_1.BufferingStream({ maxChunkSize: 2 });
35
+ buffer.push(Buffer.from([0, 1, 2, 3, 4, 5]));
36
+ (0, chai_1.expect)(await waitForChunk(buffer)).deep.eq(Buffer.from([0, 1]));
37
+ (0, chai_1.expect)(await waitForChunk(buffer)).deep.eq(Buffer.from([2, 3]));
38
+ (0, chai_1.expect)(await waitForChunk(buffer)).deep.eq(Buffer.from([4, 5]));
39
+ });
40
+ function waitForChunk(buffer) {
41
+ return new Promise(resolve => buffer.onData(resolve));
42
+ }
43
+ });
44
+ //# sourceMappingURL=buffering-stream.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buffering-stream.spec.js","sourceRoot":"","sources":["../../src/node/buffering-stream.spec.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,0CAA0C;AAC1C,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,2EAA2E;AAC3E,gFAAgF;;AAEhF,sEAA2D;AAC3D,+BAA8B;AAC9B,yDAAqD;AAErD,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAE9B,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,MAAM,GAAG,IAAI,kCAAe,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,IAAA,mBAAI,EAAC,GAAG,CAAC,CAAC;QAChB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,IAAA,mBAAI,EAAC,GAAG,CAAC,CAAC;QAChB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC;QACjC,IAAA,aAAM,EAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,MAAM,GAAG,IAAI,kCAAe,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC,CAAC;QACxD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7C,IAAA,aAAM,EAAC,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAChE,IAAA,aAAM,EAAC,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAChE,IAAA,aAAM,EAAC,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,SAAS,YAAY,CAAC,MAAuB;QACzC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1D,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"terminal-backend-contribution.d.ts","sourceRoot":"","sources":["../../src/node/terminal-backend-contribution.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,OAAO,EAAkB,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAmB,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,kDAAkD,CAAC;AAGpF,qBACa,2BAA4B,YAAW,gBAAgB,CAAC,YAAY;IAG7E,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IAGlD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAEnC,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;CAwB7C"}
1
+ {"version":3,"file":"terminal-backend-contribution.d.ts","sourceRoot":"","sources":["../../src/node/terminal-backend-contribution.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,OAAO,EAAkB,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAmB,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,kDAAkD,CAAC;AAIpF,qBACa,2BAA4B,YAAW,gBAAgB,CAAC,YAAY;IAG7E,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IAGlD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAEnC,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;CA2B7C"}
@@ -30,6 +30,7 @@ const common_1 = require("@theia/core/lib/common");
30
30
  const node_1 = require("@theia/process/lib/node");
31
31
  const terminal_protocol_1 = require("../common/terminal-protocol");
32
32
  const core_1 = require("@theia/core/");
33
+ const buffering_stream_1 = require("./buffering-stream");
33
34
  let TerminalBackendContribution = class TerminalBackendContribution {
34
35
  configure(service) {
35
36
  service.wsChannel(`${terminal_protocol_1.terminalsPath}/:id`, (params, channel) => {
@@ -48,10 +49,13 @@ let TerminalBackendContribution = class TerminalBackendContribution {
48
49
  }
49
50
  };
50
51
  const rpc = new core_1.RpcProtocol(channel, requestHandler);
51
- output.on('data', data => {
52
- rpc.sendNotification('onData', [data]);
52
+ const buffer = new buffering_stream_1.BufferingStream();
53
+ buffer.onData(chunk => rpc.sendNotification('onData', [chunk.toString('utf8')]));
54
+ output.on('data', chunk => buffer.push(Buffer.from(chunk, 'utf8')));
55
+ channel.onClose(() => {
56
+ buffer.dispose();
57
+ output.dispose();
53
58
  });
54
- channel.onClose(() => output.dispose());
55
59
  }
56
60
  });
57
61
  }
@@ -1 +1 @@
1
- {"version":3,"file":"terminal-backend-contribution.js","sourceRoot":"","sources":["../../src/node/terminal-backend-contribution.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,2EAA2E;AAC3E,gFAAgF;;;;;;;;;;;;AAEhF,4DAAyE;AACzE,mDAAiE;AACjE,kDAA0E;AAC1E,mEAA4D;AAE5D,uCAA2C;AAG3C,IAAa,2BAA2B,GAAxC,MAAa,2BAA2B;IAQpC,SAAS,CAAC,OAAyB;QAC/B,OAAO,CAAC,SAAS,CAAC,GAAG,iCAAa,MAAM,EAAE,CAAC,MAAsB,EAAE,OAAO,EAAE,EAAE;YAC1E,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YACnC,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChD,IAAI,WAAW,YAAY,sBAAe,EAAE;gBACxC,MAAM,MAAM,GAAG,WAAW,CAAC,kBAAkB,EAAE,CAAC;gBAChD,kDAAkD;gBAClD,8DAA8D;gBAC9D,MAAM,cAAc,GAAmB,KAAK,EAAE,MAAc,EAAE,IAAW,EAAE,EAAE;oBACzE,IAAI,MAAM,KAAK,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE;wBAC/B,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;qBAC9B;yBAAM;wBACH,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4EAA4E,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;qBACpH;gBACL,CAAC,CAAC;gBAEF,MAAM,GAAG,GAAG,IAAI,kBAAW,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;gBACrD,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE;oBACrB,GAAG,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC3C,CAAC,CAAC,CAAC;gBACH,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;aAC3C;QACL,CAAC,CAAC,CAAC;IACP,CAAC;CACJ,CAAA;AA7BG;IADC,IAAA,kBAAM,EAAC,qBAAc,CAAC;8BACY,qBAAc;mEAAC;AAGlD;IADC,IAAA,kBAAM,EAAC,gBAAO,CAAC;IAAE,IAAA,iBAAK,EAAC,UAAU,CAAC;;2DACA;AAN1B,2BAA2B;IADvC,IAAA,sBAAU,GAAE;GACA,2BAA2B,CAgCvC;AAhCY,kEAA2B"}
1
+ {"version":3,"file":"terminal-backend-contribution.js","sourceRoot":"","sources":["../../src/node/terminal-backend-contribution.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,2EAA2E;AAC3E,gFAAgF;;;;;;;;;;;;AAEhF,4DAAyE;AACzE,mDAAiE;AACjE,kDAA0E;AAC1E,mEAA4D;AAE5D,uCAA2C;AAC3C,yDAAqD;AAGrD,IAAa,2BAA2B,GAAxC,MAAa,2BAA2B;IAQpC,SAAS,CAAC,OAAyB;QAC/B,OAAO,CAAC,SAAS,CAAC,GAAG,iCAAa,MAAM,EAAE,CAAC,MAAsB,EAAE,OAAO,EAAE,EAAE;YAC1E,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YACnC,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChD,IAAI,WAAW,YAAY,sBAAe,EAAE;gBACxC,MAAM,MAAM,GAAG,WAAW,CAAC,kBAAkB,EAAE,CAAC;gBAChD,kDAAkD;gBAClD,8DAA8D;gBAC9D,MAAM,cAAc,GAAmB,KAAK,EAAE,MAAc,EAAE,IAAW,EAAE,EAAE;oBACzE,IAAI,MAAM,KAAK,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE;wBAC/B,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;qBAC9B;yBAAM;wBACH,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4EAA4E,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;qBACpH;gBACL,CAAC,CAAC;gBAEF,MAAM,GAAG,GAAG,IAAI,kBAAW,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;gBACrD,MAAM,MAAM,GAAG,IAAI,kCAAe,EAAE,CAAC;gBACrC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;gBACjF,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;gBACpE,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE;oBACjB,MAAM,CAAC,OAAO,EAAE,CAAC;oBACjB,MAAM,CAAC,OAAO,EAAE,CAAC;gBACrB,CAAC,CAAC,CAAC;aACN;QACL,CAAC,CAAC,CAAC;IACP,CAAC;CACJ,CAAA;AAhCG;IADC,IAAA,kBAAM,EAAC,qBAAc,CAAC;8BACY,qBAAc;mEAAC;AAGlD;IADC,IAAA,kBAAM,EAAC,gBAAO,CAAC;IAAE,IAAA,iBAAK,EAAC,UAAU,CAAC;;2DACA;AAN1B,2BAA2B;IADvC,IAAA,sBAAU,GAAE;GACA,2BAA2B,CAmCvC;AAnCY,kEAA2B"}
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@theia/terminal",
3
- "version": "1.28.0-next.9+c0ee4dcf6bb",
3
+ "version": "1.29.0-next.2+d9715208c9f",
4
4
  "description": "Theia - Terminal Extension",
5
5
  "dependencies": {
6
- "@theia/core": "1.28.0-next.9+c0ee4dcf6bb",
7
- "@theia/editor": "1.28.0-next.9+c0ee4dcf6bb",
8
- "@theia/filesystem": "1.28.0-next.9+c0ee4dcf6bb",
9
- "@theia/process": "1.28.0-next.9+c0ee4dcf6bb",
10
- "@theia/workspace": "1.28.0-next.9+c0ee4dcf6bb",
6
+ "@theia/core": "1.29.0-next.2+d9715208c9f",
7
+ "@theia/editor": "1.29.0-next.2+d9715208c9f",
8
+ "@theia/filesystem": "1.29.0-next.2+d9715208c9f",
9
+ "@theia/process": "1.29.0-next.2+d9715208c9f",
10
+ "@theia/workspace": "1.29.0-next.2+d9715208c9f",
11
11
  "xterm": "^4.16.0",
12
12
  "xterm-addon-fit": "^0.5.0",
13
13
  "xterm-addon-search": "^0.8.2"
@@ -46,10 +46,10 @@
46
46
  "watch": "theiaext watch"
47
47
  },
48
48
  "devDependencies": {
49
- "@theia/ext-scripts": "1.27.0"
49
+ "@theia/ext-scripts": "1.28.0"
50
50
  },
51
51
  "nyc": {
52
52
  "extends": "../../configs/nyc.json"
53
53
  },
54
- "gitHead": "c0ee4dcf6bb10be905cc5a58d04b10faa3800d67"
54
+ "gitHead": "d9715208c9fba269d79ff37e5d677864d40cd4cd"
55
55
  }
@@ -0,0 +1,46 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2022 Ericsson and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { wait } from '@theia/core/lib/common/promise-util';
18
+ import { expect } from 'chai';
19
+ import { BufferingStream } from './buffering-stream';
20
+
21
+ describe('BufferringStream', () => {
22
+
23
+ it('should emit whatever data was buffered before the timeout', async () => {
24
+ const buffer = new BufferingStream({ emitInterval: 1000 });
25
+ const chunkPromise = waitForChunk(buffer);
26
+ buffer.push(Buffer.from([0]));
27
+ await wait(100);
28
+ buffer.push(Buffer.from([1]));
29
+ await wait(100);
30
+ buffer.push(Buffer.from([2, 3, 4]));
31
+ const chunk = await chunkPromise;
32
+ expect(chunk).deep.eq(Buffer.from([0, 1, 2, 3, 4]));
33
+ });
34
+
35
+ it('should not emit chunks bigger than maxChunkSize', async () => {
36
+ const buffer = new BufferingStream({ maxChunkSize: 2 });
37
+ buffer.push(Buffer.from([0, 1, 2, 3, 4, 5]));
38
+ expect(await waitForChunk(buffer)).deep.eq(Buffer.from([0, 1]));
39
+ expect(await waitForChunk(buffer)).deep.eq(Buffer.from([2, 3]));
40
+ expect(await waitForChunk(buffer)).deep.eq(Buffer.from([4, 5]));
41
+ });
42
+
43
+ function waitForChunk(buffer: BufferingStream): Promise<Buffer> {
44
+ return new Promise(resolve => buffer.onData(resolve));
45
+ }
46
+ });
@@ -0,0 +1,78 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2022 Ericsson and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { Emitter, Event } from '@theia/core/lib/common/event';
18
+
19
+ export interface BufferingStreamOptions {
20
+ /**
21
+ * Max size in bytes of the chunks being emitted.
22
+ */
23
+ maxChunkSize?: number
24
+ /**
25
+ * Amount of time in milliseconds to wait between the moment we start
26
+ * buffering data and when we emit the buffered chunk.
27
+ */
28
+ emitInterval?: number
29
+ }
30
+
31
+ /**
32
+ * This component will buffer whatever is pushed to it and emit chunks back
33
+ * every {@link BufferingStreamOptions.emitInterval}. It will also ensure that
34
+ * the emitted chunks never exceed {@link BufferingStreamOptions.maxChunkSize}.
35
+ */
36
+ export class BufferingStream {
37
+
38
+ protected buffer?: Buffer;
39
+ protected timeout?: NodeJS.Timeout;
40
+ protected maxChunkSize: number;
41
+ protected emitInterval: number;
42
+
43
+ protected onDataEmitter = new Emitter<Buffer>();
44
+
45
+ constructor(options?: BufferingStreamOptions) {
46
+ this.emitInterval = options?.emitInterval ?? 16; // ms
47
+ this.maxChunkSize = options?.maxChunkSize ?? (256 * 1024); // bytes
48
+ }
49
+
50
+ get onData(): Event<Buffer> {
51
+ return this.onDataEmitter.event;
52
+ }
53
+
54
+ push(chunk: Buffer): void {
55
+ if (this.buffer) {
56
+ this.buffer = Buffer.concat([this.buffer, chunk]);
57
+ } else {
58
+ this.buffer = chunk;
59
+ this.timeout = setTimeout(() => this.emitBufferedChunk(), this.emitInterval);
60
+ }
61
+ }
62
+
63
+ dispose(): void {
64
+ clearTimeout(this.timeout);
65
+ this.buffer = undefined;
66
+ this.onDataEmitter.dispose();
67
+ }
68
+
69
+ protected emitBufferedChunk(): void {
70
+ this.onDataEmitter.fire(this.buffer!.slice(0, this.maxChunkSize));
71
+ if (this.buffer!.byteLength <= this.maxChunkSize) {
72
+ this.buffer = undefined;
73
+ } else {
74
+ this.buffer = this.buffer!.slice(this.maxChunkSize);
75
+ this.timeout = setTimeout(() => this.emitBufferedChunk(), this.emitInterval);
76
+ }
77
+ }
78
+ }
@@ -20,6 +20,7 @@ import { TerminalProcess, ProcessManager } from '@theia/process/lib/node';
20
20
  import { terminalsPath } from '../common/terminal-protocol';
21
21
  import { MessagingService } from '@theia/core/lib/node/messaging/messaging-service';
22
22
  import { RpcProtocol } from '@theia/core/';
23
+ import { BufferingStream } from './buffering-stream';
23
24
 
24
25
  @injectable()
25
26
  export class TerminalBackendContribution implements MessagingService.Contribution {
@@ -47,10 +48,13 @@ export class TerminalBackendContribution implements MessagingService.Contributio
47
48
  };
48
49
 
49
50
  const rpc = new RpcProtocol(channel, requestHandler);
50
- output.on('data', data => {
51
- rpc.sendNotification('onData', [data]);
51
+ const buffer = new BufferingStream();
52
+ buffer.onData(chunk => rpc.sendNotification('onData', [chunk.toString('utf8')]));
53
+ output.on('data', chunk => buffer.push(Buffer.from(chunk, 'utf8')));
54
+ channel.onClose(() => {
55
+ buffer.dispose();
56
+ output.dispose();
52
57
  });
53
- channel.onClose(() => output.dispose());
54
58
  }
55
59
  });
56
60
  }