@xterm/xterm 6.1.0-beta.236 → 6.1.0-beta.238

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xterm/xterm",
3
3
  "description": "Full xterm terminal, in your browser",
4
- "version": "6.1.0-beta.236",
4
+ "version": "6.1.0-beta.238",
5
5
  "main": "lib/xterm.js",
6
6
  "module": "lib/xterm.mjs",
7
7
  "style": "css/xterm.css",
@@ -111,5 +111,5 @@
111
111
  "ws": "^8.2.3",
112
112
  "xterm-benchmark": "^0.3.1"
113
113
  },
114
- "commit": "c28f3c8d73dce01f95b9df93774225a8faf1ead8"
114
+ "commit": "280dc0a36ad35eb28eee8a0822cc2cecac3a2e28"
115
115
  }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Copyright (c) 2026 The xterm.js authors. All rights reserved.
3
+ * @license MIT
4
+ */
5
+
6
+ /**
7
+ * Accumulates string data from multiple chunks without O(n²) string concatenation.
8
+ */
9
+ export class StringBuilder {
10
+ private _chunks: string[] = [];
11
+ private _length = 0;
12
+
13
+ public get length(): number {
14
+ return this._length;
15
+ }
16
+
17
+ public reset(): void {
18
+ this._chunks.length = 0;
19
+ this._length = 0;
20
+ }
21
+
22
+ public append(chunk: string): void {
23
+ this._chunks.push(chunk);
24
+ this._length += chunk.length;
25
+ }
26
+
27
+ public toString(): string {
28
+ return this._chunks.join('');
29
+ }
30
+ }
31
+
32
+ /**
33
+ * String builder that rejects payloads larger than a fixed limit.
34
+ */
35
+ export class LimitedStringBuilder {
36
+ private readonly _builder = new StringBuilder();
37
+
38
+ constructor(private readonly _limit: number) { }
39
+
40
+ public get length(): number {
41
+ return this._builder.length;
42
+ }
43
+
44
+ public get limit(): number {
45
+ return this._limit;
46
+ }
47
+
48
+ public reset(): void {
49
+ this._builder.reset();
50
+ }
51
+
52
+ /**
53
+ * @returns true if the limit was exceeded (buffer is cleared in that case)
54
+ */
55
+ public append(chunk: string): boolean {
56
+ this._builder.append(chunk);
57
+ if (this._builder.length > this._limit) {
58
+ this._builder.reset();
59
+ return true;
60
+ }
61
+ return false;
62
+ }
63
+
64
+ public toString(): string {
65
+ return this._builder.toString();
66
+ }
67
+ }
@@ -6,4 +6,4 @@
6
6
  /**
7
7
  * The xterm.js version. This is updated by the publish script from package.json.
8
8
  */
9
- export const XTERM_VERSION = '6.1.0-beta.236';
9
+ export const XTERM_VERSION = '6.1.0-beta.238';
@@ -7,6 +7,7 @@ import { IApcHandler, IHandlerCollection, ApcFallbackHandlerType, IApcParser, IS
7
7
  import { ParserConstants } from 'common/parser/Constants';
8
8
  import { utf32ToString } from 'common/input/TextDecoder';
9
9
  import { IDisposable } from 'common/Types';
10
+ import { LimitedStringBuilder } from 'common/StringBuilder';
10
11
 
11
12
  const EMPTY_HANDLERS: IApcHandler[] = [];
12
13
 
@@ -153,13 +154,13 @@ export class ApcParser implements IApcParser {
153
154
  export class ApcHandler implements IApcHandler {
154
155
  private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;
155
156
 
156
- private _data = '';
157
+ private _data = new LimitedStringBuilder(ApcHandler._payloadLimit);
157
158
  private _hitLimit: boolean = false;
158
159
 
159
160
  constructor(private _handler: (data: string) => boolean | Promise<boolean>) { }
160
161
 
161
162
  public start(): void {
162
- this._data = '';
163
+ this._data.reset();
163
164
  this._hitLimit = false;
164
165
  }
165
166
 
@@ -167,9 +168,7 @@ export class ApcHandler implements IApcHandler {
167
168
  if (this._hitLimit) {
168
169
  return;
169
170
  }
170
- this._data += utf32ToString(data, start, end);
171
- if (this._data.length > ApcHandler._payloadLimit) {
172
- this._data = '';
171
+ if (this._data.append(utf32ToString(data, start, end))) {
173
172
  this._hitLimit = true;
174
173
  }
175
174
  }
@@ -179,18 +178,18 @@ export class ApcHandler implements IApcHandler {
179
178
  if (this._hitLimit) {
180
179
  ret = false;
181
180
  } else if (success) {
182
- ret = this._handler(this._data);
181
+ ret = this._handler(this._data.toString());
183
182
  if (ret instanceof Promise) {
184
183
  // need to hold data until `ret` got resolved
185
184
  // dont care for errors, data will be freed anyway on next start
186
185
  return ret.then(res => {
187
- this._data = '';
186
+ this._data.reset();
188
187
  this._hitLimit = false;
189
188
  return res;
190
189
  });
191
190
  }
192
191
  }
193
- this._data = '';
192
+ this._data.reset();
194
193
  this._hitLimit = false;
195
194
  return ret;
196
195
  }
@@ -8,6 +8,7 @@ import { IDcsHandler, IParams, IHandlerCollection, IDcsParser, DcsFallbackHandle
8
8
  import { utf32ToString } from 'common/input/TextDecoder';
9
9
  import { Params } from 'common/parser/Params';
10
10
  import { ParserConstants } from 'common/parser/Constants';
11
+ import { LimitedStringBuilder } from 'common/StringBuilder';
11
12
 
12
13
  const EMPTY_HANDLERS: IDcsHandler[] = [];
13
14
 
@@ -140,7 +141,7 @@ EMPTY_PARAMS.addParam(0);
140
141
  export class DcsHandler implements IDcsHandler {
141
142
  private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;
142
143
 
143
- private _data = '';
144
+ private _data = new LimitedStringBuilder(DcsHandler._payloadLimit);
144
145
  private _params: IParams = EMPTY_PARAMS;
145
146
  private _hitLimit: boolean = false;
146
147
 
@@ -152,7 +153,7 @@ export class DcsHandler implements IDcsHandler {
152
153
  // perf optimization:
153
154
  // clone only, if we have non empty params, otherwise stick with default
154
155
  this._params = (params.length > 1 || params.params[0]) ? params.clone() : EMPTY_PARAMS;
155
- this._data = '';
156
+ this._data.reset();
156
157
  this._hitLimit = false;
157
158
  }
158
159
 
@@ -160,9 +161,7 @@ export class DcsHandler implements IDcsHandler {
160
161
  if (this._hitLimit) {
161
162
  return;
162
163
  }
163
- this._data += utf32ToString(data, start, end);
164
- if (this._data.length > DcsHandler._payloadLimit) {
165
- this._data = '';
164
+ if (this._data.append(utf32ToString(data, start, end))) {
166
165
  this._hitLimit = true;
167
166
  }
168
167
  }
@@ -172,20 +171,20 @@ export class DcsHandler implements IDcsHandler {
172
171
  if (this._hitLimit) {
173
172
  ret = false;
174
173
  } else if (success) {
175
- ret = this._handler(this._data, this._params);
174
+ ret = this._handler(this._data.toString(), this._params);
176
175
  if (ret instanceof Promise) {
177
176
  // need to hold data and params until `ret` got resolved
178
177
  // dont care for errors, data will be freed anyway on next start
179
178
  return ret.then(res => {
180
179
  this._params = EMPTY_PARAMS;
181
- this._data = '';
180
+ this._data.reset();
182
181
  this._hitLimit = false;
183
182
  return res;
184
183
  });
185
184
  }
186
185
  }
187
186
  this._params = EMPTY_PARAMS;
188
- this._data = '';
187
+ this._data.reset();
189
188
  this._hitLimit = false;
190
189
  return ret;
191
190
  }
@@ -7,6 +7,7 @@ import { IOscHandler, IHandlerCollection, OscFallbackHandlerType, IOscParser, IS
7
7
  import { OscState, ParserConstants } from 'common/parser/Constants';
8
8
  import { utf32ToString } from 'common/input/TextDecoder';
9
9
  import { IDisposable } from 'common/Types';
10
+ import { LimitedStringBuilder } from 'common/StringBuilder';
10
11
 
11
12
  const EMPTY_HANDLERS: IOscHandler[] = [];
12
13
 
@@ -194,13 +195,13 @@ export class OscParser implements IOscParser {
194
195
  export class OscHandler implements IOscHandler {
195
196
  private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;
196
197
 
197
- private _data = '';
198
+ private _data = new LimitedStringBuilder(OscHandler._payloadLimit);
198
199
  private _hitLimit: boolean = false;
199
200
 
200
201
  constructor(private _handler: (data: string) => boolean | Promise<boolean>) { }
201
202
 
202
203
  public start(): void {
203
- this._data = '';
204
+ this._data.reset();
204
205
  this._hitLimit = false;
205
206
  }
206
207
 
@@ -208,9 +209,7 @@ export class OscHandler implements IOscHandler {
208
209
  if (this._hitLimit) {
209
210
  return;
210
211
  }
211
- this._data += utf32ToString(data, start, end);
212
- if (this._data.length > OscHandler._payloadLimit) {
213
- this._data = '';
212
+ if (this._data.append(utf32ToString(data, start, end))) {
214
213
  this._hitLimit = true;
215
214
  }
216
215
  }
@@ -220,18 +219,18 @@ export class OscHandler implements IOscHandler {
220
219
  if (this._hitLimit) {
221
220
  ret = false;
222
221
  } else if (success) {
223
- ret = this._handler(this._data);
222
+ ret = this._handler(this._data.toString());
224
223
  if (ret instanceof Promise) {
225
224
  // need to hold data until `ret` got resolved
226
225
  // dont care for errors, data will be freed anyway on next start
227
226
  return ret.then(res => {
228
- this._data = '';
227
+ this._data.reset();
229
228
  this._hitLimit = false;
230
229
  return res;
231
230
  });
232
231
  }
233
232
  }
234
- this._data = '';
233
+ this._data.reset();
235
234
  this._hitLimit = false;
236
235
  return ret;
237
236
  }