restty 0.1.13 → 0.1.14

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/app/index.js CHANGED
@@ -8300,6 +8300,7 @@ class OutputFilter {
8300
8300
  altScreen = false;
8301
8301
  bracketedPaste = false;
8302
8302
  focusReporting = false;
8303
+ synchronizedOutput = false;
8303
8304
  windowOpHandler;
8304
8305
  getWindowMetrics;
8305
8306
  clipboardWrite;
@@ -8333,6 +8334,9 @@ class OutputFilter {
8333
8334
  isFocusReporting() {
8334
8335
  return this.focusReporting;
8335
8336
  }
8337
+ isSynchronizedOutput() {
8338
+ return this.synchronizedOutput;
8339
+ }
8336
8340
  replyOscColor(code, rgb) {
8337
8341
  const toHex4 = (value) => Math.round(Math.max(0, Math.min(255, value)) * 257).toString(16).padStart(4, "0");
8338
8342
  const r = toHex4(rgb[0]);
@@ -8398,6 +8402,8 @@ class OutputFilter {
8398
8402
  } else if (code === 1004) {
8399
8403
  this.focusReporting = enabled;
8400
8404
  handled = true;
8405
+ } else if (code === 2026) {
8406
+ this.synchronizedOutput = enabled;
8401
8407
  }
8402
8408
  }
8403
8409
  return handled;
@@ -8581,6 +8587,7 @@ function createInputHandler(options = {}) {
8581
8587
  isBracketedPaste: () => filter.isBracketedPaste(),
8582
8588
  isFocusReporting: () => filter.isFocusReporting(),
8583
8589
  isAltScreen: () => filter.isAltScreen(),
8590
+ isSynchronizedOutput: () => filter.isSynchronizedOutput(),
8584
8591
  sendMouseEvent: (kind, event) => mouse.sendMouseEvent(kind, event)
8585
8592
  };
8586
8593
  }
@@ -50443,6 +50450,14 @@ function createResttyApp(options) {
50443
50450
  let lastKeydownSeqAt = 0;
50444
50451
  let nextBlinkTime = performance.now() + CURSOR_BLINK_MS;
50445
50452
  const ptyTransport = options.ptyTransport ?? createWebSocketPtyTransport();
50453
+ const PTY_OUTPUT_IDLE_MS = 10;
50454
+ const PTY_OUTPUT_MAX_MS = 40;
50455
+ const SYNC_OUTPUT_RESET_MS = 1000;
50456
+ const SYNC_OUTPUT_RESET_SEQ = "\x1B[?2026l";
50457
+ let ptyOutputBuffer = "";
50458
+ let ptyOutputIdleTimer = 0;
50459
+ let ptyOutputMaxTimer = 0;
50460
+ let syncOutputResetTimer = 0;
50446
50461
  let lastCursorForCpr = { row: 1, col: 1 };
50447
50462
  let inputHandler = null;
50448
50463
  let activeTheme = null;
@@ -51202,7 +51217,71 @@ function createResttyApp(options) {
51202
51217
  const label = status.active ? `${status.mode} (${status.detail})` : status.mode;
51203
51218
  setMouseStatus(label);
51204
51219
  }
51220
+ function cancelPtyOutputFlush() {
51221
+ if (ptyOutputIdleTimer) {
51222
+ clearTimeout(ptyOutputIdleTimer);
51223
+ ptyOutputIdleTimer = 0;
51224
+ }
51225
+ if (ptyOutputMaxTimer) {
51226
+ clearTimeout(ptyOutputMaxTimer);
51227
+ ptyOutputMaxTimer = 0;
51228
+ }
51229
+ }
51230
+ function cancelSyncOutputReset() {
51231
+ if (syncOutputResetTimer) {
51232
+ clearTimeout(syncOutputResetTimer);
51233
+ syncOutputResetTimer = 0;
51234
+ }
51235
+ }
51236
+ function scheduleSyncOutputReset() {
51237
+ if (syncOutputResetTimer)
51238
+ return;
51239
+ syncOutputResetTimer = setTimeout(() => {
51240
+ syncOutputResetTimer = 0;
51241
+ if (!inputHandler?.isSynchronizedOutput?.())
51242
+ return;
51243
+ const sanitized = inputHandler.filterOutput(SYNC_OUTPUT_RESET_SEQ) || SYNC_OUTPUT_RESET_SEQ;
51244
+ sendInput(sanitized, "pty");
51245
+ }, SYNC_OUTPUT_RESET_MS);
51246
+ }
51247
+ function flushPtyOutputBuffer() {
51248
+ const output = ptyOutputBuffer;
51249
+ ptyOutputBuffer = "";
51250
+ if (!output)
51251
+ return;
51252
+ sendInput(output, "pty");
51253
+ }
51254
+ function queuePtyOutput(text) {
51255
+ if (!text)
51256
+ return;
51257
+ ptyOutputBuffer += text;
51258
+ if (ptyOutputIdleTimer) {
51259
+ clearTimeout(ptyOutputIdleTimer);
51260
+ }
51261
+ ptyOutputIdleTimer = setTimeout(() => {
51262
+ ptyOutputIdleTimer = 0;
51263
+ if (ptyOutputMaxTimer) {
51264
+ clearTimeout(ptyOutputMaxTimer);
51265
+ ptyOutputMaxTimer = 0;
51266
+ }
51267
+ flushPtyOutputBuffer();
51268
+ }, PTY_OUTPUT_IDLE_MS);
51269
+ if (!ptyOutputMaxTimer) {
51270
+ ptyOutputMaxTimer = setTimeout(() => {
51271
+ ptyOutputMaxTimer = 0;
51272
+ if (ptyOutputIdleTimer) {
51273
+ clearTimeout(ptyOutputIdleTimer);
51274
+ ptyOutputIdleTimer = 0;
51275
+ }
51276
+ flushPtyOutputBuffer();
51277
+ }, PTY_OUTPUT_MAX_MS);
51278
+ }
51279
+ }
51205
51280
  function disconnectPty2() {
51281
+ flushPtyOutputBuffer();
51282
+ cancelPtyOutputFlush();
51283
+ cancelSyncOutputReset();
51284
+ ptyOutputBuffer = "";
51206
51285
  ptyTransport.disconnect();
51207
51286
  updateMouseStatus();
51208
51287
  setPtyStatus("disconnected");
@@ -51249,7 +51328,7 @@ function createResttyApp(options) {
51249
51328
  const sanitized = inputHandler ? inputHandler.filterOutput(text) : text;
51250
51329
  updateMouseStatus();
51251
51330
  if (sanitized)
51252
- sendInput(sanitized, "pty");
51331
+ queuePtyOutput(sanitized);
51253
51332
  }
51254
51333
  }
51255
51334
  });
@@ -55497,7 +55576,7 @@ function createResttyApp(options) {
55497
55576
  return;
55498
55577
  if (!text)
55499
55578
  return;
55500
- const normalized = normalizeNewlines(text);
55579
+ const normalized = source === "pty" ? text : normalizeNewlines(text);
55501
55580
  if (source === "key") {
55502
55581
  const bytes = textEncoder3.encode(normalized);
55503
55582
  const hex = Array.from(bytes, (b3) => b3.toString(16).padStart(2, "0")).join(" ");
@@ -55519,8 +55598,13 @@ function createResttyApp(options) {
55519
55598
  clearSelection();
55520
55599
  }
55521
55600
  writeToWasm(wasmHandle, normalized);
55522
- wasm.renderUpdate(wasmHandle);
55523
55601
  flushWasmOutputToPty();
55602
+ if (source === "pty" && inputHandler?.isSynchronizedOutput?.()) {
55603
+ scheduleSyncOutputReset();
55604
+ return;
55605
+ }
55606
+ cancelSyncOutputReset();
55607
+ wasm.renderUpdate(wasmHandle);
55524
55608
  if (source === "key" && wasmExports?.restty_debug_cursor_x && wasmExports?.restty_debug_cursor_y) {
55525
55609
  const ax = wasmExports.restty_debug_cursor_x(wasmHandle);
55526
55610
  const ay = wasmExports.restty_debug_cursor_y(wasmHandle);
@@ -55749,6 +55833,7 @@ function createResttyApp(options) {
55749
55833
  clearTimeout(terminalResizeTimer);
55750
55834
  terminalResizeTimer = 0;
55751
55835
  }
55836
+ cancelSyncOutputReset();
55752
55837
  pendingTerminalResize = null;
55753
55838
  disconnectPty2();
55754
55839
  ptyTransport.destroy?.();
package/dist/index.js CHANGED
@@ -8300,6 +8300,7 @@ class OutputFilter {
8300
8300
  altScreen = false;
8301
8301
  bracketedPaste = false;
8302
8302
  focusReporting = false;
8303
+ synchronizedOutput = false;
8303
8304
  windowOpHandler;
8304
8305
  getWindowMetrics;
8305
8306
  clipboardWrite;
@@ -8333,6 +8334,9 @@ class OutputFilter {
8333
8334
  isFocusReporting() {
8334
8335
  return this.focusReporting;
8335
8336
  }
8337
+ isSynchronizedOutput() {
8338
+ return this.synchronizedOutput;
8339
+ }
8336
8340
  replyOscColor(code, rgb) {
8337
8341
  const toHex4 = (value) => Math.round(Math.max(0, Math.min(255, value)) * 257).toString(16).padStart(4, "0");
8338
8342
  const r = toHex4(rgb[0]);
@@ -8398,6 +8402,8 @@ class OutputFilter {
8398
8402
  } else if (code === 1004) {
8399
8403
  this.focusReporting = enabled;
8400
8404
  handled = true;
8405
+ } else if (code === 2026) {
8406
+ this.synchronizedOutput = enabled;
8401
8407
  }
8402
8408
  }
8403
8409
  return handled;
@@ -8581,6 +8587,7 @@ function createInputHandler(options = {}) {
8581
8587
  isBracketedPaste: () => filter.isBracketedPaste(),
8582
8588
  isFocusReporting: () => filter.isFocusReporting(),
8583
8589
  isAltScreen: () => filter.isAltScreen(),
8590
+ isSynchronizedOutput: () => filter.isSynchronizedOutput(),
8584
8591
  sendMouseEvent: (kind, event) => mouse.sendMouseEvent(kind, event)
8585
8592
  };
8586
8593
  }
@@ -50443,6 +50450,14 @@ function createResttyApp(options) {
50443
50450
  let lastKeydownSeqAt = 0;
50444
50451
  let nextBlinkTime = performance.now() + CURSOR_BLINK_MS;
50445
50452
  const ptyTransport = options.ptyTransport ?? createWebSocketPtyTransport();
50453
+ const PTY_OUTPUT_IDLE_MS = 10;
50454
+ const PTY_OUTPUT_MAX_MS = 40;
50455
+ const SYNC_OUTPUT_RESET_MS = 1000;
50456
+ const SYNC_OUTPUT_RESET_SEQ = "\x1B[?2026l";
50457
+ let ptyOutputBuffer = "";
50458
+ let ptyOutputIdleTimer = 0;
50459
+ let ptyOutputMaxTimer = 0;
50460
+ let syncOutputResetTimer = 0;
50446
50461
  let lastCursorForCpr = { row: 1, col: 1 };
50447
50462
  let inputHandler = null;
50448
50463
  let activeTheme = null;
@@ -51202,7 +51217,71 @@ function createResttyApp(options) {
51202
51217
  const label = status.active ? `${status.mode} (${status.detail})` : status.mode;
51203
51218
  setMouseStatus(label);
51204
51219
  }
51220
+ function cancelPtyOutputFlush() {
51221
+ if (ptyOutputIdleTimer) {
51222
+ clearTimeout(ptyOutputIdleTimer);
51223
+ ptyOutputIdleTimer = 0;
51224
+ }
51225
+ if (ptyOutputMaxTimer) {
51226
+ clearTimeout(ptyOutputMaxTimer);
51227
+ ptyOutputMaxTimer = 0;
51228
+ }
51229
+ }
51230
+ function cancelSyncOutputReset() {
51231
+ if (syncOutputResetTimer) {
51232
+ clearTimeout(syncOutputResetTimer);
51233
+ syncOutputResetTimer = 0;
51234
+ }
51235
+ }
51236
+ function scheduleSyncOutputReset() {
51237
+ if (syncOutputResetTimer)
51238
+ return;
51239
+ syncOutputResetTimer = setTimeout(() => {
51240
+ syncOutputResetTimer = 0;
51241
+ if (!inputHandler?.isSynchronizedOutput?.())
51242
+ return;
51243
+ const sanitized = inputHandler.filterOutput(SYNC_OUTPUT_RESET_SEQ) || SYNC_OUTPUT_RESET_SEQ;
51244
+ sendInput(sanitized, "pty");
51245
+ }, SYNC_OUTPUT_RESET_MS);
51246
+ }
51247
+ function flushPtyOutputBuffer() {
51248
+ const output = ptyOutputBuffer;
51249
+ ptyOutputBuffer = "";
51250
+ if (!output)
51251
+ return;
51252
+ sendInput(output, "pty");
51253
+ }
51254
+ function queuePtyOutput(text) {
51255
+ if (!text)
51256
+ return;
51257
+ ptyOutputBuffer += text;
51258
+ if (ptyOutputIdleTimer) {
51259
+ clearTimeout(ptyOutputIdleTimer);
51260
+ }
51261
+ ptyOutputIdleTimer = setTimeout(() => {
51262
+ ptyOutputIdleTimer = 0;
51263
+ if (ptyOutputMaxTimer) {
51264
+ clearTimeout(ptyOutputMaxTimer);
51265
+ ptyOutputMaxTimer = 0;
51266
+ }
51267
+ flushPtyOutputBuffer();
51268
+ }, PTY_OUTPUT_IDLE_MS);
51269
+ if (!ptyOutputMaxTimer) {
51270
+ ptyOutputMaxTimer = setTimeout(() => {
51271
+ ptyOutputMaxTimer = 0;
51272
+ if (ptyOutputIdleTimer) {
51273
+ clearTimeout(ptyOutputIdleTimer);
51274
+ ptyOutputIdleTimer = 0;
51275
+ }
51276
+ flushPtyOutputBuffer();
51277
+ }, PTY_OUTPUT_MAX_MS);
51278
+ }
51279
+ }
51205
51280
  function disconnectPty2() {
51281
+ flushPtyOutputBuffer();
51282
+ cancelPtyOutputFlush();
51283
+ cancelSyncOutputReset();
51284
+ ptyOutputBuffer = "";
51206
51285
  ptyTransport.disconnect();
51207
51286
  updateMouseStatus();
51208
51287
  setPtyStatus("disconnected");
@@ -51249,7 +51328,7 @@ function createResttyApp(options) {
51249
51328
  const sanitized = inputHandler ? inputHandler.filterOutput(text) : text;
51250
51329
  updateMouseStatus();
51251
51330
  if (sanitized)
51252
- sendInput(sanitized, "pty");
51331
+ queuePtyOutput(sanitized);
51253
51332
  }
51254
51333
  }
51255
51334
  });
@@ -55497,7 +55576,7 @@ function createResttyApp(options) {
55497
55576
  return;
55498
55577
  if (!text)
55499
55578
  return;
55500
- const normalized = normalizeNewlines(text);
55579
+ const normalized = source === "pty" ? text : normalizeNewlines(text);
55501
55580
  if (source === "key") {
55502
55581
  const bytes = textEncoder3.encode(normalized);
55503
55582
  const hex = Array.from(bytes, (b3) => b3.toString(16).padStart(2, "0")).join(" ");
@@ -55519,8 +55598,13 @@ function createResttyApp(options) {
55519
55598
  clearSelection();
55520
55599
  }
55521
55600
  writeToWasm(wasmHandle, normalized);
55522
- wasm.renderUpdate(wasmHandle);
55523
55601
  flushWasmOutputToPty();
55602
+ if (source === "pty" && inputHandler?.isSynchronizedOutput?.()) {
55603
+ scheduleSyncOutputReset();
55604
+ return;
55605
+ }
55606
+ cancelSyncOutputReset();
55607
+ wasm.renderUpdate(wasmHandle);
55524
55608
  if (source === "key" && wasmExports?.restty_debug_cursor_x && wasmExports?.restty_debug_cursor_y) {
55525
55609
  const ax = wasmExports.restty_debug_cursor_x(wasmHandle);
55526
55610
  const ay = wasmExports.restty_debug_cursor_y(wasmHandle);
@@ -55749,6 +55833,7 @@ function createResttyApp(options) {
55749
55833
  clearTimeout(terminalResizeTimer);
55750
55834
  terminalResizeTimer = 0;
55751
55835
  }
55836
+ cancelSyncOutputReset();
55752
55837
  pendingTerminalResize = null;
55753
55838
  disconnectPty2();
55754
55839
  ptyTransport.destroy?.();
@@ -751,6 +751,7 @@ class OutputFilter {
751
751
  altScreen = false;
752
752
  bracketedPaste = false;
753
753
  focusReporting = false;
754
+ synchronizedOutput = false;
754
755
  windowOpHandler;
755
756
  getWindowMetrics;
756
757
  clipboardWrite;
@@ -784,6 +785,9 @@ class OutputFilter {
784
785
  isFocusReporting() {
785
786
  return this.focusReporting;
786
787
  }
788
+ isSynchronizedOutput() {
789
+ return this.synchronizedOutput;
790
+ }
787
791
  replyOscColor(code, rgb) {
788
792
  const toHex4 = (value) => Math.round(Math.max(0, Math.min(255, value)) * 257).toString(16).padStart(4, "0");
789
793
  const r = toHex4(rgb[0]);
@@ -849,6 +853,8 @@ class OutputFilter {
849
853
  } else if (code === 1004) {
850
854
  this.focusReporting = enabled;
851
855
  handled = true;
856
+ } else if (code === 2026) {
857
+ this.synchronizedOutput = enabled;
852
858
  }
853
859
  }
854
860
  return handled;
@@ -1032,6 +1038,7 @@ function createInputHandler(options = {}) {
1032
1038
  isBracketedPaste: () => filter.isBracketedPaste(),
1033
1039
  isFocusReporting: () => filter.isFocusReporting(),
1034
1040
  isAltScreen: () => filter.isAltScreen(),
1041
+ isSynchronizedOutput: () => filter.isSynchronizedOutput(),
1035
1042
  sendMouseEvent: (kind, event) => mouse.sendMouseEvent(kind, event)
1036
1043
  };
1037
1044
  }
@@ -33,6 +33,7 @@ export declare class OutputFilter {
33
33
  private altScreen;
34
34
  private bracketedPaste;
35
35
  private focusReporting;
36
+ private synchronizedOutput;
36
37
  private windowOpHandler?;
37
38
  private getWindowMetrics?;
38
39
  private clipboardWrite?;
@@ -45,6 +46,7 @@ export declare class OutputFilter {
45
46
  isAltScreen(): boolean;
46
47
  isBracketedPaste(): boolean;
47
48
  isFocusReporting(): boolean;
49
+ isSynchronizedOutput(): boolean;
48
50
  private replyOscColor;
49
51
  private handleOsc;
50
52
  private handleModeSeq;
@@ -152,6 +152,7 @@ export type InputHandler = {
152
152
  isBracketedPaste: () => boolean;
153
153
  isFocusReporting: () => boolean;
154
154
  isAltScreen: () => boolean;
155
+ isSynchronizedOutput: () => boolean;
155
156
  /**
156
157
  * Encode pointer input as terminal mouse events (SGR).
157
158
  */
package/dist/internal.js CHANGED
@@ -8300,6 +8300,7 @@ class OutputFilter {
8300
8300
  altScreen = false;
8301
8301
  bracketedPaste = false;
8302
8302
  focusReporting = false;
8303
+ synchronizedOutput = false;
8303
8304
  windowOpHandler;
8304
8305
  getWindowMetrics;
8305
8306
  clipboardWrite;
@@ -8333,6 +8334,9 @@ class OutputFilter {
8333
8334
  isFocusReporting() {
8334
8335
  return this.focusReporting;
8335
8336
  }
8337
+ isSynchronizedOutput() {
8338
+ return this.synchronizedOutput;
8339
+ }
8336
8340
  replyOscColor(code, rgb) {
8337
8341
  const toHex4 = (value) => Math.round(Math.max(0, Math.min(255, value)) * 257).toString(16).padStart(4, "0");
8338
8342
  const r = toHex4(rgb[0]);
@@ -8398,6 +8402,8 @@ class OutputFilter {
8398
8402
  } else if (code === 1004) {
8399
8403
  this.focusReporting = enabled;
8400
8404
  handled = true;
8405
+ } else if (code === 2026) {
8406
+ this.synchronizedOutput = enabled;
8401
8407
  }
8402
8408
  }
8403
8409
  return handled;
@@ -8581,6 +8587,7 @@ function createInputHandler(options = {}) {
8581
8587
  isBracketedPaste: () => filter.isBracketedPaste(),
8582
8588
  isFocusReporting: () => filter.isFocusReporting(),
8583
8589
  isAltScreen: () => filter.isAltScreen(),
8590
+ isSynchronizedOutput: () => filter.isSynchronizedOutput(),
8584
8591
  sendMouseEvent: (kind, event) => mouse.sendMouseEvent(kind, event)
8585
8592
  };
8586
8593
  }
@@ -50443,6 +50450,14 @@ function createResttyApp(options) {
50443
50450
  let lastKeydownSeqAt = 0;
50444
50451
  let nextBlinkTime = performance.now() + CURSOR_BLINK_MS;
50445
50452
  const ptyTransport = options.ptyTransport ?? createWebSocketPtyTransport();
50453
+ const PTY_OUTPUT_IDLE_MS = 10;
50454
+ const PTY_OUTPUT_MAX_MS = 40;
50455
+ const SYNC_OUTPUT_RESET_MS = 1000;
50456
+ const SYNC_OUTPUT_RESET_SEQ = "\x1B[?2026l";
50457
+ let ptyOutputBuffer = "";
50458
+ let ptyOutputIdleTimer = 0;
50459
+ let ptyOutputMaxTimer = 0;
50460
+ let syncOutputResetTimer = 0;
50446
50461
  let lastCursorForCpr = { row: 1, col: 1 };
50447
50462
  let inputHandler = null;
50448
50463
  let activeTheme = null;
@@ -51202,7 +51217,71 @@ function createResttyApp(options) {
51202
51217
  const label = status.active ? `${status.mode} (${status.detail})` : status.mode;
51203
51218
  setMouseStatus(label);
51204
51219
  }
51220
+ function cancelPtyOutputFlush() {
51221
+ if (ptyOutputIdleTimer) {
51222
+ clearTimeout(ptyOutputIdleTimer);
51223
+ ptyOutputIdleTimer = 0;
51224
+ }
51225
+ if (ptyOutputMaxTimer) {
51226
+ clearTimeout(ptyOutputMaxTimer);
51227
+ ptyOutputMaxTimer = 0;
51228
+ }
51229
+ }
51230
+ function cancelSyncOutputReset() {
51231
+ if (syncOutputResetTimer) {
51232
+ clearTimeout(syncOutputResetTimer);
51233
+ syncOutputResetTimer = 0;
51234
+ }
51235
+ }
51236
+ function scheduleSyncOutputReset() {
51237
+ if (syncOutputResetTimer)
51238
+ return;
51239
+ syncOutputResetTimer = setTimeout(() => {
51240
+ syncOutputResetTimer = 0;
51241
+ if (!inputHandler?.isSynchronizedOutput?.())
51242
+ return;
51243
+ const sanitized = inputHandler.filterOutput(SYNC_OUTPUT_RESET_SEQ) || SYNC_OUTPUT_RESET_SEQ;
51244
+ sendInput(sanitized, "pty");
51245
+ }, SYNC_OUTPUT_RESET_MS);
51246
+ }
51247
+ function flushPtyOutputBuffer() {
51248
+ const output = ptyOutputBuffer;
51249
+ ptyOutputBuffer = "";
51250
+ if (!output)
51251
+ return;
51252
+ sendInput(output, "pty");
51253
+ }
51254
+ function queuePtyOutput(text) {
51255
+ if (!text)
51256
+ return;
51257
+ ptyOutputBuffer += text;
51258
+ if (ptyOutputIdleTimer) {
51259
+ clearTimeout(ptyOutputIdleTimer);
51260
+ }
51261
+ ptyOutputIdleTimer = setTimeout(() => {
51262
+ ptyOutputIdleTimer = 0;
51263
+ if (ptyOutputMaxTimer) {
51264
+ clearTimeout(ptyOutputMaxTimer);
51265
+ ptyOutputMaxTimer = 0;
51266
+ }
51267
+ flushPtyOutputBuffer();
51268
+ }, PTY_OUTPUT_IDLE_MS);
51269
+ if (!ptyOutputMaxTimer) {
51270
+ ptyOutputMaxTimer = setTimeout(() => {
51271
+ ptyOutputMaxTimer = 0;
51272
+ if (ptyOutputIdleTimer) {
51273
+ clearTimeout(ptyOutputIdleTimer);
51274
+ ptyOutputIdleTimer = 0;
51275
+ }
51276
+ flushPtyOutputBuffer();
51277
+ }, PTY_OUTPUT_MAX_MS);
51278
+ }
51279
+ }
51205
51280
  function disconnectPty2() {
51281
+ flushPtyOutputBuffer();
51282
+ cancelPtyOutputFlush();
51283
+ cancelSyncOutputReset();
51284
+ ptyOutputBuffer = "";
51206
51285
  ptyTransport.disconnect();
51207
51286
  updateMouseStatus();
51208
51287
  setPtyStatus("disconnected");
@@ -51249,7 +51328,7 @@ function createResttyApp(options) {
51249
51328
  const sanitized = inputHandler ? inputHandler.filterOutput(text) : text;
51250
51329
  updateMouseStatus();
51251
51330
  if (sanitized)
51252
- sendInput(sanitized, "pty");
51331
+ queuePtyOutput(sanitized);
51253
51332
  }
51254
51333
  }
51255
51334
  });
@@ -55497,7 +55576,7 @@ function createResttyApp(options) {
55497
55576
  return;
55498
55577
  if (!text)
55499
55578
  return;
55500
- const normalized = normalizeNewlines(text);
55579
+ const normalized = source === "pty" ? text : normalizeNewlines(text);
55501
55580
  if (source === "key") {
55502
55581
  const bytes = textEncoder3.encode(normalized);
55503
55582
  const hex = Array.from(bytes, (b3) => b3.toString(16).padStart(2, "0")).join(" ");
@@ -55519,8 +55598,13 @@ function createResttyApp(options) {
55519
55598
  clearSelection();
55520
55599
  }
55521
55600
  writeToWasm(wasmHandle, normalized);
55522
- wasm.renderUpdate(wasmHandle);
55523
55601
  flushWasmOutputToPty();
55602
+ if (source === "pty" && inputHandler?.isSynchronizedOutput?.()) {
55603
+ scheduleSyncOutputReset();
55604
+ return;
55605
+ }
55606
+ cancelSyncOutputReset();
55607
+ wasm.renderUpdate(wasmHandle);
55524
55608
  if (source === "key" && wasmExports?.restty_debug_cursor_x && wasmExports?.restty_debug_cursor_y) {
55525
55609
  const ax = wasmExports.restty_debug_cursor_x(wasmHandle);
55526
55610
  const ay = wasmExports.restty_debug_cursor_y(wasmHandle);
@@ -55749,6 +55833,7 @@ function createResttyApp(options) {
55749
55833
  clearTimeout(terminalResizeTimer);
55750
55834
  terminalResizeTimer = 0;
55751
55835
  }
55836
+ cancelSyncOutputReset();
55752
55837
  pendingTerminalResize = null;
55753
55838
  disconnectPty2();
55754
55839
  ptyTransport.destroy?.();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "restty",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
4
4
  "description": "Browser terminal rendering library powered by WASM, WebGPU/WebGL2, and TypeScript text shaping.",
5
5
  "keywords": [
6
6
  "terminal",