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 +88 -3
- package/dist/index.js +88 -3
- package/dist/input/index.js +7 -0
- package/dist/input/output.d.ts +2 -0
- package/dist/input/types.d.ts +1 -0
- package/dist/internal.js +88 -3
- package/package.json +1 -1
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
|
-
|
|
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
|
-
|
|
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/input/index.js
CHANGED
|
@@ -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
|
}
|
package/dist/input/output.d.ts
CHANGED
|
@@ -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;
|
package/dist/input/types.d.ts
CHANGED
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
|
-
|
|
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?.();
|