restty 0.1.21 → 0.1.23
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/README.md +85 -0
- package/dist/app/clipboard-paste.d.ts +5 -0
- package/dist/app/index.d.ts +3 -2
- package/dist/app/restty.d.ts +201 -0
- package/dist/app/types.d.ts +21 -0
- package/dist/{chunk-ym658zhj.js → chunk-mkkhfg0z.js} +970 -40
- package/dist/index.d.ts +2 -2
- package/dist/input/output.d.ts +10 -1
- package/dist/input/types.d.ts +2 -0
- package/dist/internal.js +1 -1
- package/dist/restty.js +4 -2
- package/dist/xterm.d.ts +77 -0
- package/dist/xterm.js +254 -0
- package/package.json +6 -1
|
@@ -8576,6 +8576,10 @@ class OutputFilter {
|
|
|
8576
8576
|
clipboardWrite;
|
|
8577
8577
|
clipboardRead;
|
|
8578
8578
|
getDefaultColors;
|
|
8579
|
+
semanticPromptSeen = false;
|
|
8580
|
+
promptClickEvents = false;
|
|
8581
|
+
promptInputActive = false;
|
|
8582
|
+
commandRunning = false;
|
|
8579
8583
|
constructor(options) {
|
|
8580
8584
|
this.getCursorPosition = options.getCursorPosition;
|
|
8581
8585
|
this.sendReply = options.sendReply;
|
|
@@ -8607,6 +8611,80 @@ class OutputFilter {
|
|
|
8607
8611
|
isSynchronizedOutput() {
|
|
8608
8612
|
return this.synchronizedOutput;
|
|
8609
8613
|
}
|
|
8614
|
+
isPromptClickEventsEnabled() {
|
|
8615
|
+
return this.semanticPromptSeen && this.promptClickEvents && this.promptInputActive && !this.commandRunning && !this.altScreen;
|
|
8616
|
+
}
|
|
8617
|
+
encodePromptClickEvent(cell) {
|
|
8618
|
+
if (!this.isPromptClickEventsEnabled())
|
|
8619
|
+
return "";
|
|
8620
|
+
const row = Math.max(1, Math.floor(cell.row) + 1);
|
|
8621
|
+
const col = Math.max(1, Math.floor(cell.col) + 1);
|
|
8622
|
+
return `\x1B[<0;${col};${row}M`;
|
|
8623
|
+
}
|
|
8624
|
+
readOsc133BoolOption(options, key) {
|
|
8625
|
+
if (!options)
|
|
8626
|
+
return null;
|
|
8627
|
+
const prefix = `${key}=`;
|
|
8628
|
+
const fields = options.split(";");
|
|
8629
|
+
for (let i = 0;i < fields.length; i += 1) {
|
|
8630
|
+
const field = fields[i];
|
|
8631
|
+
if (!field.startsWith(prefix))
|
|
8632
|
+
continue;
|
|
8633
|
+
const value = field.slice(prefix.length);
|
|
8634
|
+
if (value === "1")
|
|
8635
|
+
return true;
|
|
8636
|
+
if (value === "0")
|
|
8637
|
+
return false;
|
|
8638
|
+
return null;
|
|
8639
|
+
}
|
|
8640
|
+
return null;
|
|
8641
|
+
}
|
|
8642
|
+
observeSemanticPromptOsc(action, options) {
|
|
8643
|
+
const clickEvents = this.readOsc133BoolOption(options, "click_events");
|
|
8644
|
+
if (clickEvents !== null)
|
|
8645
|
+
this.promptClickEvents = clickEvents;
|
|
8646
|
+
switch (action) {
|
|
8647
|
+
case "A":
|
|
8648
|
+
case "B":
|
|
8649
|
+
case "I":
|
|
8650
|
+
this.semanticPromptSeen = true;
|
|
8651
|
+
this.promptInputActive = true;
|
|
8652
|
+
this.commandRunning = false;
|
|
8653
|
+
break;
|
|
8654
|
+
case "C":
|
|
8655
|
+
this.semanticPromptSeen = true;
|
|
8656
|
+
this.promptInputActive = false;
|
|
8657
|
+
this.commandRunning = true;
|
|
8658
|
+
break;
|
|
8659
|
+
case "D":
|
|
8660
|
+
this.semanticPromptSeen = true;
|
|
8661
|
+
this.promptInputActive = false;
|
|
8662
|
+
this.commandRunning = false;
|
|
8663
|
+
break;
|
|
8664
|
+
case "P":
|
|
8665
|
+
this.semanticPromptSeen = true;
|
|
8666
|
+
break;
|
|
8667
|
+
default:
|
|
8668
|
+
break;
|
|
8669
|
+
}
|
|
8670
|
+
}
|
|
8671
|
+
observeOsc(seq) {
|
|
8672
|
+
const content = seq.slice(2);
|
|
8673
|
+
const sep = content.indexOf(";");
|
|
8674
|
+
if (sep < 0)
|
|
8675
|
+
return;
|
|
8676
|
+
const code = content.slice(0, sep);
|
|
8677
|
+
if (code !== "133")
|
|
8678
|
+
return;
|
|
8679
|
+
const rest = content.slice(sep + 1);
|
|
8680
|
+
if (!rest)
|
|
8681
|
+
return;
|
|
8682
|
+
const action = rest[0] ?? "";
|
|
8683
|
+
if (!action)
|
|
8684
|
+
return;
|
|
8685
|
+
const options = rest.length > 2 && rest[1] === ";" ? rest.slice(2) : "";
|
|
8686
|
+
this.observeSemanticPromptOsc(action, options);
|
|
8687
|
+
}
|
|
8610
8688
|
replyOscColor(code, rgb) {
|
|
8611
8689
|
const toHex4 = (value) => Math.round(Math.max(0, Math.min(255, value)) * 257).toString(16).padStart(4, "0");
|
|
8612
8690
|
const r = toHex4(rgb[0]);
|
|
@@ -8749,6 +8827,7 @@ class OutputFilter {
|
|
|
8749
8827
|
break;
|
|
8750
8828
|
}
|
|
8751
8829
|
const seq2 = data.slice(i, j2);
|
|
8830
|
+
this.observeOsc(seq2);
|
|
8752
8831
|
if (!this.handleOsc(seq2)) {
|
|
8753
8832
|
result += data.slice(i, j2 + terminatorLen);
|
|
8754
8833
|
}
|
|
@@ -8858,6 +8937,8 @@ function createInputHandler(options = {}) {
|
|
|
8858
8937
|
isFocusReporting: () => filter.isFocusReporting(),
|
|
8859
8938
|
isAltScreen: () => filter.isAltScreen(),
|
|
8860
8939
|
isSynchronizedOutput: () => filter.isSynchronizedOutput(),
|
|
8940
|
+
isPromptClickEventsEnabled: () => filter.isPromptClickEventsEnabled(),
|
|
8941
|
+
encodePromptClickEvent: (cell) => filter.encodePromptClickEvent(cell),
|
|
8861
8942
|
sendMouseEvent: (kind, event) => mouse.sendMouseEvent(kind, event)
|
|
8862
8943
|
};
|
|
8863
8944
|
}
|
|
@@ -26723,6 +26804,17 @@ function buildFontAtlasIfNeeded(params) {
|
|
|
26723
26804
|
};
|
|
26724
26805
|
}
|
|
26725
26806
|
|
|
26807
|
+
// src/app/clipboard-paste.ts
|
|
26808
|
+
function readPastePayloadFromDataTransfer(dataTransfer) {
|
|
26809
|
+
if (!dataTransfer)
|
|
26810
|
+
return null;
|
|
26811
|
+
const text = dataTransfer.getData("text/plain") || "";
|
|
26812
|
+
return text ? {
|
|
26813
|
+
kind: "text",
|
|
26814
|
+
text
|
|
26815
|
+
} : null;
|
|
26816
|
+
}
|
|
26817
|
+
|
|
26726
26818
|
// src/app/font-sources.ts
|
|
26727
26819
|
var DEFAULT_FONT_SOURCES = [
|
|
26728
26820
|
{
|
|
@@ -50315,6 +50407,8 @@ var DEFAULT_EMOJI_CONSTRAINT = {
|
|
|
50315
50407
|
};
|
|
50316
50408
|
function createResttyApp(options) {
|
|
50317
50409
|
const { canvas: canvasInput, imeInput: imeInputInput, elements, callbacks } = options;
|
|
50410
|
+
const beforeInputHook = options.beforeInput;
|
|
50411
|
+
const beforeRenderOutputHook = options.beforeRenderOutput;
|
|
50318
50412
|
const session = options.session ?? getDefaultResttyAppSession();
|
|
50319
50413
|
const textShaper = exports_dist;
|
|
50320
50414
|
if (!canvasInput) {
|
|
@@ -50558,6 +50652,11 @@ function createResttyApp(options) {
|
|
|
50558
50652
|
panLastY: 0,
|
|
50559
50653
|
pendingTimer: 0
|
|
50560
50654
|
};
|
|
50655
|
+
const desktopSelectionState = {
|
|
50656
|
+
pendingPointerId: null,
|
|
50657
|
+
pendingCell: null,
|
|
50658
|
+
startedWithActiveSelection: false
|
|
50659
|
+
};
|
|
50561
50660
|
const linkState = {
|
|
50562
50661
|
hoverId: 0,
|
|
50563
50662
|
hoverUri: ""
|
|
@@ -50577,11 +50676,7 @@ function createResttyApp(options) {
|
|
|
50577
50676
|
function updateCanvasCursor() {
|
|
50578
50677
|
if (!canvas)
|
|
50579
50678
|
return;
|
|
50580
|
-
|
|
50581
|
-
canvas.style.cursor = "text";
|
|
50582
|
-
return;
|
|
50583
|
-
}
|
|
50584
|
-
canvas.style.cursor = linkState.hoverId ? "pointer" : "default";
|
|
50679
|
+
canvas.style.cursor = "text";
|
|
50585
50680
|
}
|
|
50586
50681
|
function isTouchPointer(event) {
|
|
50587
50682
|
return event.pointerType === "touch";
|
|
@@ -50595,6 +50690,11 @@ function createResttyApp(options) {
|
|
|
50595
50690
|
touchSelectionState.pendingCell = null;
|
|
50596
50691
|
touchSelectionState.pendingStartedAt = 0;
|
|
50597
50692
|
}
|
|
50693
|
+
function clearPendingDesktopSelection() {
|
|
50694
|
+
desktopSelectionState.pendingPointerId = null;
|
|
50695
|
+
desktopSelectionState.pendingCell = null;
|
|
50696
|
+
desktopSelectionState.startedWithActiveSelection = false;
|
|
50697
|
+
}
|
|
50598
50698
|
function tryActivatePendingTouchSelection(pointerId) {
|
|
50599
50699
|
if (touchSelectionMode !== "long-press")
|
|
50600
50700
|
return false;
|
|
@@ -50610,6 +50710,7 @@ function createResttyApp(options) {
|
|
|
50610
50710
|
return true;
|
|
50611
50711
|
}
|
|
50612
50712
|
function beginSelectionDrag(cell, pointerId) {
|
|
50713
|
+
clearPendingDesktopSelection();
|
|
50613
50714
|
selectionState.active = true;
|
|
50614
50715
|
selectionState.dragging = true;
|
|
50615
50716
|
selectionState.anchor = cell;
|
|
@@ -51411,6 +51512,7 @@ function createResttyApp(options) {
|
|
|
51411
51512
|
});
|
|
51412
51513
|
inputHandler.setMouseMode("auto");
|
|
51413
51514
|
function clearSelection() {
|
|
51515
|
+
clearPendingDesktopSelection();
|
|
51414
51516
|
selectionState.active = false;
|
|
51415
51517
|
selectionState.dragging = false;
|
|
51416
51518
|
selectionState.anchor = null;
|
|
@@ -51593,15 +51695,18 @@ function createResttyApp(options) {
|
|
|
51593
51695
|
function sendKeyInput(text, source = "key") {
|
|
51594
51696
|
if (!text)
|
|
51595
51697
|
return;
|
|
51698
|
+
const intercepted = runBeforeInputHook(text, source);
|
|
51699
|
+
if (!intercepted)
|
|
51700
|
+
return;
|
|
51596
51701
|
if (source !== "program" && (selectionState.active || selectionState.dragging)) {
|
|
51597
51702
|
clearSelection();
|
|
51598
51703
|
}
|
|
51599
51704
|
if (ptyTransport.isConnected()) {
|
|
51600
|
-
const payload = inputHandler.mapKeyForPty(
|
|
51705
|
+
const payload = inputHandler.mapKeyForPty(intercepted);
|
|
51601
51706
|
ptyTransport.sendInput(payload);
|
|
51602
51707
|
return;
|
|
51603
51708
|
}
|
|
51604
|
-
sendInput(
|
|
51709
|
+
sendInput(intercepted, source, { skipHooks: true });
|
|
51605
51710
|
}
|
|
51606
51711
|
function formatPasteText(text) {
|
|
51607
51712
|
if (!inputHandler?.isBracketedPaste?.())
|
|
@@ -51613,6 +51718,13 @@ function createResttyApp(options) {
|
|
|
51613
51718
|
return;
|
|
51614
51719
|
sendKeyInput(formatPasteText(text));
|
|
51615
51720
|
}
|
|
51721
|
+
function sendPastePayloadFromDataTransfer(dataTransfer) {
|
|
51722
|
+
const payload = readPastePayloadFromDataTransfer(dataTransfer);
|
|
51723
|
+
if (!payload)
|
|
51724
|
+
return false;
|
|
51725
|
+
sendPasteText(payload.text);
|
|
51726
|
+
return true;
|
|
51727
|
+
}
|
|
51616
51728
|
function openLink(uri) {
|
|
51617
51729
|
if (!uri || typeof window === "undefined")
|
|
51618
51730
|
return;
|
|
@@ -51660,6 +51772,7 @@ function createResttyApp(options) {
|
|
|
51660
51772
|
}
|
|
51661
51773
|
}
|
|
51662
51774
|
if (shouldRoutePointerToAppMouse(event.shiftKey) && !shouldPreferLocalPrimarySelection(event) && inputHandler.sendMouseEvent("down", event)) {
|
|
51775
|
+
clearPendingDesktopSelection();
|
|
51663
51776
|
event.preventDefault();
|
|
51664
51777
|
canvas.setPointerCapture?.(event.pointerId);
|
|
51665
51778
|
return;
|
|
@@ -51695,7 +51808,9 @@ function createResttyApp(options) {
|
|
|
51695
51808
|
event.preventDefault();
|
|
51696
51809
|
const cell = normalizeSelectionCell(positionToCell(event));
|
|
51697
51810
|
updateLinkHover(cell);
|
|
51698
|
-
|
|
51811
|
+
desktopSelectionState.pendingPointerId = event.pointerId;
|
|
51812
|
+
desktopSelectionState.pendingCell = cell;
|
|
51813
|
+
desktopSelectionState.startedWithActiveSelection = selectionState.active;
|
|
51699
51814
|
};
|
|
51700
51815
|
const onPointerMove = (event) => {
|
|
51701
51816
|
if (scrollbarDragState.pointerId === event.pointerId) {
|
|
@@ -51747,6 +51862,19 @@ function createResttyApp(options) {
|
|
|
51747
51862
|
return;
|
|
51748
51863
|
}
|
|
51749
51864
|
const cell = normalizeSelectionCell(positionToCell(event));
|
|
51865
|
+
if (desktopSelectionState.pendingPointerId === event.pointerId && desktopSelectionState.pendingCell) {
|
|
51866
|
+
const anchor = desktopSelectionState.pendingCell;
|
|
51867
|
+
if (anchor.row !== cell.row || anchor.col !== cell.col) {
|
|
51868
|
+
beginSelectionDrag(anchor, event.pointerId);
|
|
51869
|
+
selectionState.focus = cell;
|
|
51870
|
+
updateLinkHover(null);
|
|
51871
|
+
updateCanvasCursor();
|
|
51872
|
+
needsRender = true;
|
|
51873
|
+
return;
|
|
51874
|
+
}
|
|
51875
|
+
updateLinkHover(cell);
|
|
51876
|
+
return;
|
|
51877
|
+
}
|
|
51750
51878
|
if (selectionState.dragging) {
|
|
51751
51879
|
event.preventDefault();
|
|
51752
51880
|
selectionState.focus = cell;
|
|
@@ -51794,6 +51922,12 @@ function createResttyApp(options) {
|
|
|
51794
51922
|
return;
|
|
51795
51923
|
}
|
|
51796
51924
|
const cell = normalizeSelectionCell(positionToCell(event));
|
|
51925
|
+
const clearSelectionFromClick = desktopSelectionState.pendingPointerId === event.pointerId && desktopSelectionState.startedWithActiveSelection && !selectionState.dragging;
|
|
51926
|
+
if (desktopSelectionState.pendingPointerId === event.pointerId) {
|
|
51927
|
+
clearPendingDesktopSelection();
|
|
51928
|
+
}
|
|
51929
|
+
if (clearSelectionFromClick)
|
|
51930
|
+
clearSelection();
|
|
51797
51931
|
if (selectionState.dragging) {
|
|
51798
51932
|
event.preventDefault();
|
|
51799
51933
|
selectionState.dragging = false;
|
|
@@ -51811,6 +51945,14 @@ function createResttyApp(options) {
|
|
|
51811
51945
|
}
|
|
51812
51946
|
updateLinkHover(cell);
|
|
51813
51947
|
}
|
|
51948
|
+
if (!selectionState.active && event.button === 0 && !event.shiftKey && !event.altKey && !event.ctrlKey && !event.metaKey && inputHandler.isPromptClickEventsEnabled()) {
|
|
51949
|
+
const seq = inputHandler.encodePromptClickEvent(cell);
|
|
51950
|
+
if (seq) {
|
|
51951
|
+
event.preventDefault();
|
|
51952
|
+
sendKeyInput(seq);
|
|
51953
|
+
return;
|
|
51954
|
+
}
|
|
51955
|
+
}
|
|
51814
51956
|
if (!selectionState.active && event.button === 0 && linkState.hoverUri) {
|
|
51815
51957
|
openLink(linkState.hoverUri);
|
|
51816
51958
|
}
|
|
@@ -51819,6 +51961,9 @@ function createResttyApp(options) {
|
|
|
51819
51961
|
if (scrollbarDragState.pointerId === event.pointerId) {
|
|
51820
51962
|
scrollbarDragState.pointerId = null;
|
|
51821
51963
|
}
|
|
51964
|
+
if (desktopSelectionState.pendingPointerId === event.pointerId) {
|
|
51965
|
+
clearPendingDesktopSelection();
|
|
51966
|
+
}
|
|
51822
51967
|
if (isTouchPointer(event)) {
|
|
51823
51968
|
if (touchSelectionState.pendingPointerId === event.pointerId) {
|
|
51824
51969
|
clearPendingTouchSelection();
|
|
@@ -51911,13 +52056,16 @@ function createResttyApp(options) {
|
|
|
51911
52056
|
if (imeState.composing)
|
|
51912
52057
|
return;
|
|
51913
52058
|
if (event.inputType === "insertFromPaste") {
|
|
52059
|
+
event.preventDefault();
|
|
52060
|
+
suppressNextInput = true;
|
|
51914
52061
|
const pasteText = event.dataTransfer?.getData("text/plain") || event.data || "";
|
|
51915
52062
|
if (pasteText) {
|
|
51916
|
-
event.preventDefault();
|
|
51917
|
-
suppressNextInput = true;
|
|
51918
52063
|
sendPasteText(pasteText);
|
|
51919
52064
|
imeInput.value = "";
|
|
52065
|
+
return;
|
|
51920
52066
|
}
|
|
52067
|
+
sendPastePayloadFromDataTransfer(event.dataTransfer);
|
|
52068
|
+
imeInput.value = "";
|
|
51921
52069
|
return;
|
|
51922
52070
|
}
|
|
51923
52071
|
const text = inputHandler.encodeBeforeInput(event);
|
|
@@ -51954,13 +52102,16 @@ function createResttyApp(options) {
|
|
|
51954
52102
|
const onPaste = (event) => {
|
|
51955
52103
|
if (!wasmReady || !wasmHandle)
|
|
51956
52104
|
return;
|
|
52105
|
+
event.preventDefault();
|
|
52106
|
+
suppressNextInput = true;
|
|
51957
52107
|
const text = event.clipboardData?.getData("text/plain") || "";
|
|
51958
52108
|
if (text) {
|
|
51959
|
-
event.preventDefault();
|
|
51960
|
-
suppressNextInput = true;
|
|
51961
52109
|
sendPasteText(text);
|
|
51962
52110
|
imeInput.value = "";
|
|
52111
|
+
return;
|
|
51963
52112
|
}
|
|
52113
|
+
sendPastePayloadFromDataTransfer(event.clipboardData);
|
|
52114
|
+
imeInput.value = "";
|
|
51964
52115
|
};
|
|
51965
52116
|
imeInput.addEventListener("compositionstart", onCompositionStart);
|
|
51966
52117
|
imeInput.addEventListener("compositionupdate", onCompositionUpdate);
|
|
@@ -53235,6 +53386,36 @@ function createResttyApp(options) {
|
|
|
53235
53386
|
needsRender = true;
|
|
53236
53387
|
lastRenderTime = 0;
|
|
53237
53388
|
}
|
|
53389
|
+
function resize(cols, rows) {
|
|
53390
|
+
const nextCols = Math.max(1, Math.floor(Number(cols)));
|
|
53391
|
+
const nextRows = Math.max(1, Math.floor(Number(rows)));
|
|
53392
|
+
if (!Number.isFinite(nextCols) || !Number.isFinite(nextRows))
|
|
53393
|
+
return;
|
|
53394
|
+
const dpr = window.devicePixelRatio || 1;
|
|
53395
|
+
if (dpr !== currentDpr) {
|
|
53396
|
+
currentDpr = dpr;
|
|
53397
|
+
if (dprEl)
|
|
53398
|
+
dprEl.textContent = dpr.toFixed(2);
|
|
53399
|
+
callbacks?.onDpr?.(dpr);
|
|
53400
|
+
}
|
|
53401
|
+
const metrics = computeCellMetrics2();
|
|
53402
|
+
if (!metrics)
|
|
53403
|
+
return;
|
|
53404
|
+
canvas.width = Math.max(1, nextCols * metrics.cellW);
|
|
53405
|
+
canvas.height = Math.max(1, nextRows * metrics.cellH);
|
|
53406
|
+
if (sizeEl)
|
|
53407
|
+
sizeEl.textContent = `${canvas.width}x${canvas.height}`;
|
|
53408
|
+
callbacks?.onCanvasSize?.(canvas.width, canvas.height);
|
|
53409
|
+
resizeState.dpr = currentDpr;
|
|
53410
|
+
resizeState.active = true;
|
|
53411
|
+
resizeState.lastAt = performance.now();
|
|
53412
|
+
resizeState.cols = nextCols;
|
|
53413
|
+
resizeState.rows = nextRows;
|
|
53414
|
+
updateGrid();
|
|
53415
|
+
scheduleTerminalResizeCommit(nextCols, nextRows, { immediate: true });
|
|
53416
|
+
needsRender = true;
|
|
53417
|
+
lastRenderTime = 0;
|
|
53418
|
+
}
|
|
53238
53419
|
function scheduleSizeUpdate() {
|
|
53239
53420
|
updateSize();
|
|
53240
53421
|
if (sizeRaf)
|
|
@@ -53244,22 +53425,35 @@ function createResttyApp(options) {
|
|
|
53244
53425
|
updateSize();
|
|
53245
53426
|
});
|
|
53246
53427
|
}
|
|
53428
|
+
function focusTypingInput() {
|
|
53429
|
+
canvas.focus({ preventScroll: true });
|
|
53430
|
+
if (!imeInput)
|
|
53431
|
+
return;
|
|
53432
|
+
imeInput.focus({ preventScroll: true });
|
|
53433
|
+
if (typeof document !== "undefined" && document.activeElement !== imeInput) {
|
|
53434
|
+
requestAnimationFrame(() => {
|
|
53435
|
+
if (document.activeElement === canvas)
|
|
53436
|
+
imeInput.focus({ preventScroll: true });
|
|
53437
|
+
});
|
|
53438
|
+
}
|
|
53439
|
+
}
|
|
53440
|
+
function focus() {
|
|
53441
|
+
focusTypingInput();
|
|
53442
|
+
isFocused = typeof document !== "undefined" && imeInput ? document.activeElement === canvas || document.activeElement === imeInput : true;
|
|
53443
|
+
}
|
|
53444
|
+
function blur() {
|
|
53445
|
+
if (imeInput && document.activeElement === imeInput) {
|
|
53446
|
+
imeInput.blur();
|
|
53447
|
+
}
|
|
53448
|
+
if (document.activeElement === canvas) {
|
|
53449
|
+
canvas.blur();
|
|
53450
|
+
}
|
|
53451
|
+
isFocused = false;
|
|
53452
|
+
}
|
|
53247
53453
|
function bindFocusEvents() {
|
|
53248
53454
|
if (!attachCanvasEvents)
|
|
53249
53455
|
return;
|
|
53250
53456
|
canvas.tabIndex = 0;
|
|
53251
|
-
const focusTypingInput = () => {
|
|
53252
|
-
canvas.focus({ preventScroll: true });
|
|
53253
|
-
if (!imeInput)
|
|
53254
|
-
return;
|
|
53255
|
-
imeInput.focus({ preventScroll: true });
|
|
53256
|
-
if (typeof document !== "undefined" && document.activeElement !== imeInput) {
|
|
53257
|
-
requestAnimationFrame(() => {
|
|
53258
|
-
if (document.activeElement === canvas)
|
|
53259
|
-
imeInput.focus({ preventScroll: true });
|
|
53260
|
-
});
|
|
53261
|
-
}
|
|
53262
|
-
};
|
|
53263
53457
|
const handleFocus = () => {
|
|
53264
53458
|
isFocused = true;
|
|
53265
53459
|
focusTypingInput();
|
|
@@ -56063,12 +56257,48 @@ function createResttyApp(options) {
|
|
|
56063
56257
|
return text.replace(/\r?\n/g, `\r
|
|
56064
56258
|
`);
|
|
56065
56259
|
}
|
|
56066
|
-
function
|
|
56260
|
+
function runBeforeInputHook(text, source) {
|
|
56261
|
+
if (!beforeInputHook)
|
|
56262
|
+
return text;
|
|
56263
|
+
try {
|
|
56264
|
+
const next = beforeInputHook({ text, source });
|
|
56265
|
+
if (next === null)
|
|
56266
|
+
return null;
|
|
56267
|
+
if (typeof next === "string")
|
|
56268
|
+
return next;
|
|
56269
|
+
return text;
|
|
56270
|
+
} catch (error) {
|
|
56271
|
+
console.error("[restty] beforeInput hook error:", error);
|
|
56272
|
+
return text;
|
|
56273
|
+
}
|
|
56274
|
+
}
|
|
56275
|
+
function runBeforeRenderOutputHook(text, source) {
|
|
56276
|
+
if (!beforeRenderOutputHook)
|
|
56277
|
+
return text;
|
|
56278
|
+
try {
|
|
56279
|
+
const next = beforeRenderOutputHook({ text, source });
|
|
56280
|
+
if (next === null)
|
|
56281
|
+
return null;
|
|
56282
|
+
if (typeof next === "string")
|
|
56283
|
+
return next;
|
|
56284
|
+
return text;
|
|
56285
|
+
} catch (error) {
|
|
56286
|
+
console.error("[restty] beforeRenderOutput hook error:", error);
|
|
56287
|
+
return text;
|
|
56288
|
+
}
|
|
56289
|
+
}
|
|
56290
|
+
function sendInput(text, source = "program", options2 = {}) {
|
|
56067
56291
|
if (!wasmReady || !wasm || !wasmHandle)
|
|
56068
56292
|
return;
|
|
56069
56293
|
if (!text)
|
|
56070
56294
|
return;
|
|
56071
|
-
|
|
56295
|
+
let intercepted = text;
|
|
56296
|
+
if (!options2.skipHooks) {
|
|
56297
|
+
intercepted = source === "pty" ? runBeforeRenderOutputHook(text, source) : runBeforeInputHook(text, source);
|
|
56298
|
+
}
|
|
56299
|
+
if (!intercepted)
|
|
56300
|
+
return;
|
|
56301
|
+
const normalized = source === "pty" ? intercepted : normalizeNewlines(intercepted);
|
|
56072
56302
|
if (source === "key") {
|
|
56073
56303
|
const bytes = textEncoder3.encode(normalized);
|
|
56074
56304
|
const hex = Array.from(bytes, (b3) => b3.toString(16).padStart(2, "0")).join(" ");
|
|
@@ -56134,6 +56364,8 @@ function createResttyApp(options) {
|
|
|
56134
56364
|
return false;
|
|
56135
56365
|
}
|
|
56136
56366
|
async function pasteFromClipboard() {
|
|
56367
|
+
if (typeof navigator === "undefined" || !navigator.clipboard)
|
|
56368
|
+
return false;
|
|
56137
56369
|
try {
|
|
56138
56370
|
const text = await navigator.clipboard.readText();
|
|
56139
56371
|
if (text) {
|
|
@@ -56145,6 +56377,15 @@ function createResttyApp(options) {
|
|
|
56145
56377
|
}
|
|
56146
56378
|
return false;
|
|
56147
56379
|
}
|
|
56380
|
+
async function handlePasteShortcut(event) {
|
|
56381
|
+
const pasted = await pasteFromClipboard();
|
|
56382
|
+
if (pasted)
|
|
56383
|
+
return;
|
|
56384
|
+
const seq = inputHandler.encodeKeyEvent(event);
|
|
56385
|
+
if (!seq)
|
|
56386
|
+
return;
|
|
56387
|
+
sendKeyInput(seq);
|
|
56388
|
+
}
|
|
56148
56389
|
function clearScreen() {
|
|
56149
56390
|
sendInput("\x1B[2J\x1B[H");
|
|
56150
56391
|
}
|
|
@@ -56193,7 +56434,9 @@ function createResttyApp(options) {
|
|
|
56193
56434
|
}
|
|
56194
56435
|
if (wantsPaste) {
|
|
56195
56436
|
event.preventDefault();
|
|
56196
|
-
|
|
56437
|
+
if (imeInput)
|
|
56438
|
+
imeInput.focus({ preventScroll: true });
|
|
56439
|
+
handlePasteShortcut(event);
|
|
56197
56440
|
return;
|
|
56198
56441
|
}
|
|
56199
56442
|
const seq = inputHandler.encodeKeyEvent(event);
|
|
@@ -56395,6 +56638,9 @@ function createResttyApp(options) {
|
|
|
56395
56638
|
copySelectionToClipboard,
|
|
56396
56639
|
pasteFromClipboard,
|
|
56397
56640
|
dumpAtlasForCodepoint,
|
|
56641
|
+
resize,
|
|
56642
|
+
focus,
|
|
56643
|
+
blur,
|
|
56398
56644
|
updateSize,
|
|
56399
56645
|
getBackend: () => backend
|
|
56400
56646
|
};
|
|
@@ -56514,6 +56760,8 @@ function createResttyAppPaneManager(options) {
|
|
|
56514
56760
|
}
|
|
56515
56761
|
|
|
56516
56762
|
// src/app/restty.ts
|
|
56763
|
+
var RESTTY_PLUGIN_API_VERSION = 1;
|
|
56764
|
+
|
|
56517
56765
|
class ResttyPaneHandle {
|
|
56518
56766
|
resolvePane;
|
|
56519
56767
|
constructor(resolvePane) {
|
|
@@ -56573,6 +56821,15 @@ class ResttyPaneHandle {
|
|
|
56573
56821
|
dumpAtlasForCodepoint(cp) {
|
|
56574
56822
|
this.resolvePane().app.dumpAtlasForCodepoint(cp);
|
|
56575
56823
|
}
|
|
56824
|
+
resize(cols, rows) {
|
|
56825
|
+
this.resolvePane().app.resize(cols, rows);
|
|
56826
|
+
}
|
|
56827
|
+
focus() {
|
|
56828
|
+
this.resolvePane().app.focus();
|
|
56829
|
+
}
|
|
56830
|
+
blur() {
|
|
56831
|
+
this.resolvePane().app.blur();
|
|
56832
|
+
}
|
|
56576
56833
|
updateSize(force) {
|
|
56577
56834
|
this.resolvePane().app.updateSize(force);
|
|
56578
56835
|
}
|
|
@@ -56587,25 +56844,105 @@ class ResttyPaneHandle {
|
|
|
56587
56844
|
class Restty {
|
|
56588
56845
|
paneManager;
|
|
56589
56846
|
fontSources;
|
|
56847
|
+
pluginListeners = new Map;
|
|
56848
|
+
pluginRuntimes = new Map;
|
|
56849
|
+
pluginDiagnostics = new Map;
|
|
56850
|
+
inputInterceptors = [];
|
|
56851
|
+
outputInterceptors = [];
|
|
56852
|
+
lifecycleHooks = [];
|
|
56853
|
+
renderHooks = [];
|
|
56854
|
+
nextInterceptorId = 1;
|
|
56855
|
+
nextInterceptorOrder = 1;
|
|
56590
56856
|
constructor(options) {
|
|
56591
|
-
const {
|
|
56857
|
+
const {
|
|
56858
|
+
createInitialPane = true,
|
|
56859
|
+
appOptions,
|
|
56860
|
+
fontSources,
|
|
56861
|
+
onPaneCreated,
|
|
56862
|
+
onPaneClosed,
|
|
56863
|
+
onPaneSplit,
|
|
56864
|
+
onActivePaneChange,
|
|
56865
|
+
onLayoutChanged,
|
|
56866
|
+
...paneManagerOptions
|
|
56867
|
+
} = options;
|
|
56592
56868
|
this.fontSources = fontSources ? [...fontSources] : undefined;
|
|
56593
56869
|
const mergedAppOptions = (context) => {
|
|
56594
56870
|
const resolved = typeof appOptions === "function" ? appOptions(context) : appOptions ?? {};
|
|
56595
|
-
|
|
56596
|
-
|
|
56871
|
+
const resolvedBeforeInput = resolved.beforeInput;
|
|
56872
|
+
const resolvedBeforeRenderOutput = resolved.beforeRenderOutput;
|
|
56597
56873
|
return {
|
|
56598
56874
|
...resolved,
|
|
56599
|
-
fontSources: this.fontSources
|
|
56875
|
+
...this.fontSources ? { fontSources: this.fontSources } : {},
|
|
56876
|
+
beforeInput: ({ text, source }) => {
|
|
56877
|
+
const maybeUserText = resolvedBeforeInput?.({ text, source });
|
|
56878
|
+
if (maybeUserText === null)
|
|
56879
|
+
return null;
|
|
56880
|
+
const current = maybeUserText === undefined ? text : maybeUserText;
|
|
56881
|
+
return this.applyInputInterceptors(context.id, current, source);
|
|
56882
|
+
},
|
|
56883
|
+
beforeRenderOutput: ({ text, source }) => {
|
|
56884
|
+
this.runRenderHooks({
|
|
56885
|
+
phase: "before",
|
|
56886
|
+
paneId: context.id,
|
|
56887
|
+
text,
|
|
56888
|
+
source,
|
|
56889
|
+
dropped: false
|
|
56890
|
+
});
|
|
56891
|
+
const maybeUserText = resolvedBeforeRenderOutput?.({ text, source });
|
|
56892
|
+
if (maybeUserText === null) {
|
|
56893
|
+
this.runRenderHooks({
|
|
56894
|
+
phase: "after",
|
|
56895
|
+
paneId: context.id,
|
|
56896
|
+
text,
|
|
56897
|
+
source,
|
|
56898
|
+
dropped: true
|
|
56899
|
+
});
|
|
56900
|
+
return null;
|
|
56901
|
+
}
|
|
56902
|
+
const current = maybeUserText === undefined ? text : maybeUserText;
|
|
56903
|
+
const next = this.applyOutputInterceptors(context.id, current, source);
|
|
56904
|
+
this.runRenderHooks({
|
|
56905
|
+
phase: "after",
|
|
56906
|
+
paneId: context.id,
|
|
56907
|
+
text: next === null ? current : next,
|
|
56908
|
+
source,
|
|
56909
|
+
dropped: next === null
|
|
56910
|
+
});
|
|
56911
|
+
return next;
|
|
56912
|
+
}
|
|
56600
56913
|
};
|
|
56601
56914
|
};
|
|
56602
56915
|
this.paneManager = createResttyAppPaneManager({
|
|
56603
56916
|
...paneManagerOptions,
|
|
56604
|
-
appOptions: mergedAppOptions
|
|
56917
|
+
appOptions: mergedAppOptions,
|
|
56918
|
+
onPaneCreated: (pane) => {
|
|
56919
|
+
this.emitPluginEvent("pane:created", { paneId: pane.id });
|
|
56920
|
+
onPaneCreated?.(pane);
|
|
56921
|
+
},
|
|
56922
|
+
onPaneClosed: (pane) => {
|
|
56923
|
+
this.emitPluginEvent("pane:closed", { paneId: pane.id });
|
|
56924
|
+
onPaneClosed?.(pane);
|
|
56925
|
+
},
|
|
56926
|
+
onPaneSplit: (sourcePane, createdPane, direction) => {
|
|
56927
|
+
this.emitPluginEvent("pane:split", {
|
|
56928
|
+
sourcePaneId: sourcePane.id,
|
|
56929
|
+
createdPaneId: createdPane.id,
|
|
56930
|
+
direction
|
|
56931
|
+
});
|
|
56932
|
+
onPaneSplit?.(sourcePane, createdPane, direction);
|
|
56933
|
+
},
|
|
56934
|
+
onActivePaneChange: (pane) => {
|
|
56935
|
+
this.emitPluginEvent("pane:active-changed", { paneId: pane?.id ?? null });
|
|
56936
|
+
onActivePaneChange?.(pane);
|
|
56937
|
+
},
|
|
56938
|
+
onLayoutChanged: () => {
|
|
56939
|
+
this.emitPluginEvent("layout:changed", {});
|
|
56940
|
+
onLayoutChanged?.();
|
|
56941
|
+
}
|
|
56605
56942
|
});
|
|
56606
56943
|
if (createInitialPane) {
|
|
56607
56944
|
const focus = typeof createInitialPane === "object" ? createInitialPane.focus ?? true : true;
|
|
56608
|
-
this.
|
|
56945
|
+
this.createInitialPane({ focus });
|
|
56609
56946
|
}
|
|
56610
56947
|
}
|
|
56611
56948
|
getPanes() {
|
|
@@ -56656,16 +56993,63 @@ class Restty {
|
|
|
56656
56993
|
await Promise.all(updates);
|
|
56657
56994
|
}
|
|
56658
56995
|
createInitialPane(options) {
|
|
56659
|
-
|
|
56996
|
+
this.runLifecycleHooks({ phase: "before", action: "create-initial-pane" });
|
|
56997
|
+
const pane = this.paneManager.createInitialPane(options);
|
|
56998
|
+
this.runLifecycleHooks({
|
|
56999
|
+
phase: "after",
|
|
57000
|
+
action: "create-initial-pane",
|
|
57001
|
+
paneId: pane.id,
|
|
57002
|
+
ok: true
|
|
57003
|
+
});
|
|
57004
|
+
return pane;
|
|
56660
57005
|
}
|
|
56661
57006
|
splitActivePane(direction) {
|
|
56662
|
-
|
|
57007
|
+
const sourcePaneId = this.getActivePane()?.id ?? null;
|
|
57008
|
+
this.runLifecycleHooks({
|
|
57009
|
+
phase: "before",
|
|
57010
|
+
action: "split-active-pane",
|
|
57011
|
+
paneId: sourcePaneId,
|
|
57012
|
+
direction
|
|
57013
|
+
});
|
|
57014
|
+
const pane = this.paneManager.splitActivePane(direction);
|
|
57015
|
+
this.runLifecycleHooks({
|
|
57016
|
+
phase: "after",
|
|
57017
|
+
action: "split-active-pane",
|
|
57018
|
+
sourcePaneId: sourcePaneId ?? undefined,
|
|
57019
|
+
createdPaneId: pane?.id ?? null,
|
|
57020
|
+
direction,
|
|
57021
|
+
ok: !!pane
|
|
57022
|
+
});
|
|
57023
|
+
return pane;
|
|
56663
57024
|
}
|
|
56664
57025
|
splitPane(id, direction) {
|
|
56665
|
-
|
|
57026
|
+
this.runLifecycleHooks({
|
|
57027
|
+
phase: "before",
|
|
57028
|
+
action: "split-pane",
|
|
57029
|
+
paneId: id,
|
|
57030
|
+
direction
|
|
57031
|
+
});
|
|
57032
|
+
const pane = this.paneManager.splitPane(id, direction);
|
|
57033
|
+
this.runLifecycleHooks({
|
|
57034
|
+
phase: "after",
|
|
57035
|
+
action: "split-pane",
|
|
57036
|
+
sourcePaneId: id,
|
|
57037
|
+
createdPaneId: pane?.id ?? null,
|
|
57038
|
+
direction,
|
|
57039
|
+
ok: !!pane
|
|
57040
|
+
});
|
|
57041
|
+
return pane;
|
|
56666
57042
|
}
|
|
56667
57043
|
closePane(id) {
|
|
56668
|
-
|
|
57044
|
+
this.runLifecycleHooks({ phase: "before", action: "close-pane", paneId: id });
|
|
57045
|
+
const ok = this.paneManager.closePane(id);
|
|
57046
|
+
this.runLifecycleHooks({
|
|
57047
|
+
phase: "after",
|
|
57048
|
+
action: "close-pane",
|
|
57049
|
+
paneId: id,
|
|
57050
|
+
ok
|
|
57051
|
+
});
|
|
57052
|
+
return ok;
|
|
56669
57053
|
}
|
|
56670
57054
|
getPaneStyleOptions() {
|
|
56671
57055
|
return this.paneManager.getStyleOptions();
|
|
@@ -56674,10 +57058,34 @@ class Restty {
|
|
|
56674
57058
|
this.paneManager.setStyleOptions(options);
|
|
56675
57059
|
}
|
|
56676
57060
|
setActivePane(id, options) {
|
|
57061
|
+
this.runLifecycleHooks({
|
|
57062
|
+
phase: "before",
|
|
57063
|
+
action: "set-active-pane",
|
|
57064
|
+
paneId: id
|
|
57065
|
+
});
|
|
56677
57066
|
this.paneManager.setActivePane(id, options);
|
|
57067
|
+
const activePaneId = this.getActivePane()?.id ?? null;
|
|
57068
|
+
this.runLifecycleHooks({
|
|
57069
|
+
phase: "after",
|
|
57070
|
+
action: "set-active-pane",
|
|
57071
|
+
paneId: activePaneId,
|
|
57072
|
+
ok: activePaneId === id
|
|
57073
|
+
});
|
|
56678
57074
|
}
|
|
56679
57075
|
markPaneFocused(id, options) {
|
|
57076
|
+
this.runLifecycleHooks({
|
|
57077
|
+
phase: "before",
|
|
57078
|
+
action: "mark-pane-focused",
|
|
57079
|
+
paneId: id
|
|
57080
|
+
});
|
|
56680
57081
|
this.paneManager.markPaneFocused(id, options);
|
|
57082
|
+
const focusedPaneId = this.getFocusedPane()?.id ?? null;
|
|
57083
|
+
this.runLifecycleHooks({
|
|
57084
|
+
phase: "after",
|
|
57085
|
+
action: "mark-pane-focused",
|
|
57086
|
+
paneId: focusedPaneId,
|
|
57087
|
+
ok: focusedPaneId === id
|
|
57088
|
+
});
|
|
56681
57089
|
}
|
|
56682
57090
|
requestLayoutSync() {
|
|
56683
57091
|
this.paneManager.requestLayoutSync();
|
|
@@ -56685,14 +57093,193 @@ class Restty {
|
|
|
56685
57093
|
hideContextMenu() {
|
|
56686
57094
|
this.paneManager.hideContextMenu();
|
|
56687
57095
|
}
|
|
57096
|
+
async use(plugin, options) {
|
|
57097
|
+
if (!plugin || typeof plugin !== "object") {
|
|
57098
|
+
throw new Error("Restty plugin must be an object");
|
|
57099
|
+
}
|
|
57100
|
+
const pluginId = plugin.id?.trim?.() ?? "";
|
|
57101
|
+
if (!pluginId) {
|
|
57102
|
+
throw new Error("Restty plugin id is required");
|
|
57103
|
+
}
|
|
57104
|
+
if (typeof plugin.activate !== "function") {
|
|
57105
|
+
throw new Error(`Restty plugin ${pluginId} must define activate(context)`);
|
|
57106
|
+
}
|
|
57107
|
+
if (this.pluginRuntimes.has(pluginId))
|
|
57108
|
+
return;
|
|
57109
|
+
try {
|
|
57110
|
+
this.assertPluginCompatibility(pluginId, plugin);
|
|
57111
|
+
} catch (error) {
|
|
57112
|
+
this.pluginDiagnostics.set(pluginId, {
|
|
57113
|
+
id: pluginId,
|
|
57114
|
+
version: plugin.version?.trim?.() || null,
|
|
57115
|
+
apiVersion: Number.isFinite(plugin.apiVersion) ? Number(plugin.apiVersion) : null,
|
|
57116
|
+
requires: plugin.requires ?? null,
|
|
57117
|
+
active: false,
|
|
57118
|
+
activatedAt: null,
|
|
57119
|
+
lastError: this.errorToMessage(error)
|
|
57120
|
+
});
|
|
57121
|
+
throw error;
|
|
57122
|
+
}
|
|
57123
|
+
const runtime2 = {
|
|
57124
|
+
plugin: this.normalizePluginMetadata(plugin, pluginId),
|
|
57125
|
+
cleanup: null,
|
|
57126
|
+
activatedAt: Date.now(),
|
|
57127
|
+
options,
|
|
57128
|
+
disposers: []
|
|
57129
|
+
};
|
|
57130
|
+
this.pluginDiagnostics.set(pluginId, {
|
|
57131
|
+
id: pluginId,
|
|
57132
|
+
version: runtime2.plugin.version?.trim?.() || null,
|
|
57133
|
+
apiVersion: Number.isFinite(runtime2.plugin.apiVersion) ? Number(runtime2.plugin.apiVersion) : null,
|
|
57134
|
+
requires: runtime2.plugin.requires ?? null,
|
|
57135
|
+
active: false,
|
|
57136
|
+
activatedAt: null,
|
|
57137
|
+
lastError: null
|
|
57138
|
+
});
|
|
57139
|
+
this.pluginRuntimes.set(pluginId, runtime2);
|
|
57140
|
+
try {
|
|
57141
|
+
const cleanup = await runtime2.plugin.activate(this.createPluginContext(runtime2), runtime2.options);
|
|
57142
|
+
runtime2.cleanup = this.normalizePluginCleanup(cleanup);
|
|
57143
|
+
runtime2.activatedAt = Date.now();
|
|
57144
|
+
this.updatePluginDiagnostic(pluginId, {
|
|
57145
|
+
active: true,
|
|
57146
|
+
activatedAt: runtime2.activatedAt,
|
|
57147
|
+
lastError: null
|
|
57148
|
+
});
|
|
57149
|
+
this.emitPluginEvent("plugin:activated", { pluginId });
|
|
57150
|
+
} catch (error) {
|
|
57151
|
+
this.teardownPluginRuntime(runtime2);
|
|
57152
|
+
this.pluginRuntimes.delete(pluginId);
|
|
57153
|
+
this.updatePluginDiagnostic(pluginId, {
|
|
57154
|
+
active: false,
|
|
57155
|
+
activatedAt: null,
|
|
57156
|
+
lastError: this.errorToMessage(error)
|
|
57157
|
+
});
|
|
57158
|
+
throw error;
|
|
57159
|
+
}
|
|
57160
|
+
}
|
|
57161
|
+
async loadPlugins(manifest, registry) {
|
|
57162
|
+
const results = [];
|
|
57163
|
+
for (let i3 = 0;i3 < manifest.length; i3 += 1) {
|
|
57164
|
+
const item = manifest[i3];
|
|
57165
|
+
const pluginId = item.id?.trim?.() ?? "";
|
|
57166
|
+
if (!pluginId) {
|
|
57167
|
+
results.push({
|
|
57168
|
+
id: "",
|
|
57169
|
+
status: "failed",
|
|
57170
|
+
error: "Restty plugin manifest entry is missing id"
|
|
57171
|
+
});
|
|
57172
|
+
continue;
|
|
57173
|
+
}
|
|
57174
|
+
if (item.enabled === false) {
|
|
57175
|
+
results.push({ id: pluginId, status: "skipped", error: null });
|
|
57176
|
+
continue;
|
|
57177
|
+
}
|
|
57178
|
+
const entry = this.lookupPluginRegistryEntry(registry, pluginId);
|
|
57179
|
+
if (!entry) {
|
|
57180
|
+
const message = `Restty plugin ${pluginId} was not found in registry`;
|
|
57181
|
+
this.setPluginLoadError(pluginId, message);
|
|
57182
|
+
results.push({ id: pluginId, status: "missing", error: message });
|
|
57183
|
+
continue;
|
|
57184
|
+
}
|
|
57185
|
+
let plugin;
|
|
57186
|
+
try {
|
|
57187
|
+
plugin = await this.resolvePluginRegistryEntry(entry);
|
|
57188
|
+
} catch (error) {
|
|
57189
|
+
const message = this.errorToMessage(error);
|
|
57190
|
+
this.setPluginLoadError(pluginId, message);
|
|
57191
|
+
results.push({ id: pluginId, status: "failed", error: message });
|
|
57192
|
+
continue;
|
|
57193
|
+
}
|
|
57194
|
+
const resolvedId = plugin.id?.trim?.() ?? "";
|
|
57195
|
+
if (resolvedId !== pluginId) {
|
|
57196
|
+
const message = `Restty plugin registry entry ${pluginId} resolved to id ${resolvedId || "(empty)"}`;
|
|
57197
|
+
this.setPluginLoadError(pluginId, message);
|
|
57198
|
+
results.push({ id: pluginId, status: "failed", error: message });
|
|
57199
|
+
continue;
|
|
57200
|
+
}
|
|
57201
|
+
try {
|
|
57202
|
+
await this.use(plugin, item.options);
|
|
57203
|
+
results.push({ id: pluginId, status: "loaded", error: null });
|
|
57204
|
+
} catch (error) {
|
|
57205
|
+
results.push({
|
|
57206
|
+
id: pluginId,
|
|
57207
|
+
status: "failed",
|
|
57208
|
+
error: this.errorToMessage(error)
|
|
57209
|
+
});
|
|
57210
|
+
}
|
|
57211
|
+
}
|
|
57212
|
+
return results;
|
|
57213
|
+
}
|
|
57214
|
+
unuse(pluginId) {
|
|
57215
|
+
const key = pluginId?.trim?.() ?? "";
|
|
57216
|
+
if (!key)
|
|
57217
|
+
return false;
|
|
57218
|
+
const runtime2 = this.pluginRuntimes.get(key);
|
|
57219
|
+
if (!runtime2)
|
|
57220
|
+
return false;
|
|
57221
|
+
this.pluginRuntimes.delete(key);
|
|
57222
|
+
this.teardownPluginRuntime(runtime2);
|
|
57223
|
+
this.updatePluginDiagnostic(key, {
|
|
57224
|
+
active: false,
|
|
57225
|
+
activatedAt: null
|
|
57226
|
+
});
|
|
57227
|
+
this.emitPluginEvent("plugin:deactivated", { pluginId: key });
|
|
57228
|
+
return true;
|
|
57229
|
+
}
|
|
57230
|
+
plugins() {
|
|
57231
|
+
return Array.from(this.pluginRuntimes.keys());
|
|
57232
|
+
}
|
|
57233
|
+
pluginInfo(pluginId) {
|
|
57234
|
+
if (typeof pluginId === "string") {
|
|
57235
|
+
const key = pluginId.trim();
|
|
57236
|
+
if (!key)
|
|
57237
|
+
return null;
|
|
57238
|
+
return this.buildPluginInfo(key);
|
|
57239
|
+
}
|
|
57240
|
+
const keys = new Set;
|
|
57241
|
+
for (const key of this.pluginDiagnostics.keys())
|
|
57242
|
+
keys.add(key);
|
|
57243
|
+
for (const key of this.pluginRuntimes.keys())
|
|
57244
|
+
keys.add(key);
|
|
57245
|
+
return Array.from(keys).sort((a3, b3) => a3.localeCompare(b3)).map((key) => this.buildPluginInfo(key)).filter((entry) => entry !== null);
|
|
57246
|
+
}
|
|
56688
57247
|
destroy() {
|
|
57248
|
+
const pluginIds = this.plugins();
|
|
57249
|
+
for (let i3 = 0;i3 < pluginIds.length; i3 += 1) {
|
|
57250
|
+
this.unuse(pluginIds[i3]);
|
|
57251
|
+
}
|
|
56689
57252
|
this.paneManager.destroy();
|
|
56690
57253
|
}
|
|
56691
57254
|
connectPty(url = "") {
|
|
56692
|
-
this.requireActivePaneHandle()
|
|
57255
|
+
const pane = this.requireActivePaneHandle();
|
|
57256
|
+
this.runLifecycleHooks({
|
|
57257
|
+
phase: "before",
|
|
57258
|
+
action: "connect-pty",
|
|
57259
|
+
paneId: pane.id
|
|
57260
|
+
});
|
|
57261
|
+
pane.connectPty(url);
|
|
57262
|
+
this.runLifecycleHooks({
|
|
57263
|
+
phase: "after",
|
|
57264
|
+
action: "connect-pty",
|
|
57265
|
+
paneId: pane.id,
|
|
57266
|
+
ok: true
|
|
57267
|
+
});
|
|
56693
57268
|
}
|
|
56694
57269
|
disconnectPty() {
|
|
56695
|
-
this.requireActivePaneHandle()
|
|
57270
|
+
const pane = this.requireActivePaneHandle();
|
|
57271
|
+
this.runLifecycleHooks({
|
|
57272
|
+
phase: "before",
|
|
57273
|
+
action: "disconnect-pty",
|
|
57274
|
+
paneId: pane.id
|
|
57275
|
+
});
|
|
57276
|
+
pane.disconnectPty();
|
|
57277
|
+
this.runLifecycleHooks({
|
|
57278
|
+
phase: "after",
|
|
57279
|
+
action: "disconnect-pty",
|
|
57280
|
+
paneId: pane.id,
|
|
57281
|
+
ok: true
|
|
57282
|
+
});
|
|
56696
57283
|
}
|
|
56697
57284
|
isPtyConnected() {
|
|
56698
57285
|
return this.requireActivePaneHandle().isPtyConnected();
|
|
@@ -56739,6 +57326,58 @@ class Restty {
|
|
|
56739
57326
|
dumpAtlasForCodepoint(cp) {
|
|
56740
57327
|
this.requireActivePaneHandle().dumpAtlasForCodepoint(cp);
|
|
56741
57328
|
}
|
|
57329
|
+
resize(cols, rows) {
|
|
57330
|
+
const pane = this.requireActivePaneHandle();
|
|
57331
|
+
this.runLifecycleHooks({
|
|
57332
|
+
phase: "before",
|
|
57333
|
+
action: "resize",
|
|
57334
|
+
paneId: pane.id,
|
|
57335
|
+
cols,
|
|
57336
|
+
rows
|
|
57337
|
+
});
|
|
57338
|
+
pane.resize(cols, rows);
|
|
57339
|
+
this.runLifecycleHooks({
|
|
57340
|
+
phase: "after",
|
|
57341
|
+
action: "resize",
|
|
57342
|
+
paneId: pane.id,
|
|
57343
|
+
cols,
|
|
57344
|
+
rows,
|
|
57345
|
+
ok: true
|
|
57346
|
+
});
|
|
57347
|
+
this.emitPluginEvent("pane:resized", { paneId: pane.id, cols, rows });
|
|
57348
|
+
}
|
|
57349
|
+
focus() {
|
|
57350
|
+
const pane = this.requireActivePaneHandle();
|
|
57351
|
+
this.runLifecycleHooks({
|
|
57352
|
+
phase: "before",
|
|
57353
|
+
action: "focus",
|
|
57354
|
+
paneId: pane.id
|
|
57355
|
+
});
|
|
57356
|
+
pane.focus();
|
|
57357
|
+
this.runLifecycleHooks({
|
|
57358
|
+
phase: "after",
|
|
57359
|
+
action: "focus",
|
|
57360
|
+
paneId: pane.id,
|
|
57361
|
+
ok: true
|
|
57362
|
+
});
|
|
57363
|
+
this.emitPluginEvent("pane:focused", { paneId: pane.id });
|
|
57364
|
+
}
|
|
57365
|
+
blur() {
|
|
57366
|
+
const pane = this.requireActivePaneHandle();
|
|
57367
|
+
this.runLifecycleHooks({
|
|
57368
|
+
phase: "before",
|
|
57369
|
+
action: "blur",
|
|
57370
|
+
paneId: pane.id
|
|
57371
|
+
});
|
|
57372
|
+
pane.blur();
|
|
57373
|
+
this.runLifecycleHooks({
|
|
57374
|
+
phase: "after",
|
|
57375
|
+
action: "blur",
|
|
57376
|
+
paneId: pane.id,
|
|
57377
|
+
ok: true
|
|
57378
|
+
});
|
|
57379
|
+
this.emitPluginEvent("pane:blurred", { paneId: pane.id });
|
|
57380
|
+
}
|
|
56742
57381
|
updateSize(force) {
|
|
56743
57382
|
this.requireActivePaneHandle().updateSize(force);
|
|
56744
57383
|
}
|
|
@@ -56761,9 +57400,300 @@ class Restty {
|
|
|
56761
57400
|
}
|
|
56762
57401
|
return this.makePaneHandle(pane.id);
|
|
56763
57402
|
}
|
|
57403
|
+
createPluginContext(runtime2) {
|
|
57404
|
+
return {
|
|
57405
|
+
restty: this,
|
|
57406
|
+
options: runtime2.options,
|
|
57407
|
+
panes: () => this.panes(),
|
|
57408
|
+
pane: (id) => this.pane(id),
|
|
57409
|
+
activePane: () => this.activePane(),
|
|
57410
|
+
focusedPane: () => this.focusedPane(),
|
|
57411
|
+
on: (event, listener) => {
|
|
57412
|
+
return {
|
|
57413
|
+
dispose: this.attachRuntimeDisposer(runtime2, "event", this.onPluginEvent(event, listener))
|
|
57414
|
+
};
|
|
57415
|
+
},
|
|
57416
|
+
addInputInterceptor: (interceptor, options) => {
|
|
57417
|
+
return {
|
|
57418
|
+
dispose: this.attachRuntimeDisposer(runtime2, "input-interceptor", this.addInputInterceptor(runtime2.plugin.id, interceptor, options))
|
|
57419
|
+
};
|
|
57420
|
+
},
|
|
57421
|
+
addOutputInterceptor: (interceptor, options) => {
|
|
57422
|
+
return {
|
|
57423
|
+
dispose: this.attachRuntimeDisposer(runtime2, "output-interceptor", this.addOutputInterceptor(runtime2.plugin.id, interceptor, options))
|
|
57424
|
+
};
|
|
57425
|
+
},
|
|
57426
|
+
addLifecycleHook: (hook, options) => {
|
|
57427
|
+
return {
|
|
57428
|
+
dispose: this.attachRuntimeDisposer(runtime2, "lifecycle-hook", this.addLifecycleHook(runtime2.plugin.id, hook, options))
|
|
57429
|
+
};
|
|
57430
|
+
},
|
|
57431
|
+
addRenderHook: (hook, options) => {
|
|
57432
|
+
return {
|
|
57433
|
+
dispose: this.attachRuntimeDisposer(runtime2, "render-hook", this.addRenderHook(runtime2.plugin.id, hook, options))
|
|
57434
|
+
};
|
|
57435
|
+
}
|
|
57436
|
+
};
|
|
57437
|
+
}
|
|
57438
|
+
attachRuntimeDisposer(runtime2, kind, dispose) {
|
|
57439
|
+
const entry = {
|
|
57440
|
+
kind,
|
|
57441
|
+
active: true,
|
|
57442
|
+
dispose: () => {
|
|
57443
|
+
if (!entry.active)
|
|
57444
|
+
return;
|
|
57445
|
+
entry.active = false;
|
|
57446
|
+
dispose();
|
|
57447
|
+
}
|
|
57448
|
+
};
|
|
57449
|
+
runtime2.disposers.push(entry);
|
|
57450
|
+
return entry.dispose;
|
|
57451
|
+
}
|
|
57452
|
+
addInputInterceptor(pluginId, interceptor, options) {
|
|
57453
|
+
return this.registerInterceptor(this.inputInterceptors, pluginId, interceptor, options);
|
|
57454
|
+
}
|
|
57455
|
+
addOutputInterceptor(pluginId, interceptor, options) {
|
|
57456
|
+
return this.registerInterceptor(this.outputInterceptors, pluginId, interceptor, options);
|
|
57457
|
+
}
|
|
57458
|
+
addLifecycleHook(pluginId, hook, options) {
|
|
57459
|
+
return this.registerInterceptor(this.lifecycleHooks, pluginId, hook, options);
|
|
57460
|
+
}
|
|
57461
|
+
addRenderHook(pluginId, hook, options) {
|
|
57462
|
+
return this.registerInterceptor(this.renderHooks, pluginId, hook, options);
|
|
57463
|
+
}
|
|
57464
|
+
registerInterceptor(bucket, pluginId, interceptor, options) {
|
|
57465
|
+
const entry = {
|
|
57466
|
+
id: this.nextInterceptorId++,
|
|
57467
|
+
pluginId,
|
|
57468
|
+
priority: Number.isFinite(options?.priority) ? Number(options?.priority) : 0,
|
|
57469
|
+
order: this.nextInterceptorOrder++,
|
|
57470
|
+
interceptor
|
|
57471
|
+
};
|
|
57472
|
+
bucket.push(entry);
|
|
57473
|
+
bucket.sort((a3, b3) => {
|
|
57474
|
+
if (a3.priority !== b3.priority)
|
|
57475
|
+
return a3.priority - b3.priority;
|
|
57476
|
+
return a3.order - b3.order;
|
|
57477
|
+
});
|
|
57478
|
+
return () => {
|
|
57479
|
+
const index = bucket.findIndex((current) => current.id === entry.id);
|
|
57480
|
+
if (index >= 0) {
|
|
57481
|
+
bucket.splice(index, 1);
|
|
57482
|
+
}
|
|
57483
|
+
};
|
|
57484
|
+
}
|
|
57485
|
+
applyInputInterceptors(paneId, text, source) {
|
|
57486
|
+
return this.applyInterceptors(this.inputInterceptors, "input", { paneId, text, source });
|
|
57487
|
+
}
|
|
57488
|
+
applyOutputInterceptors(paneId, text, source) {
|
|
57489
|
+
return this.applyInterceptors(this.outputInterceptors, "output", { paneId, text, source });
|
|
57490
|
+
}
|
|
57491
|
+
runLifecycleHooks(payload) {
|
|
57492
|
+
this.runHooks(this.lifecycleHooks, "lifecycle", payload);
|
|
57493
|
+
}
|
|
57494
|
+
runRenderHooks(payload) {
|
|
57495
|
+
this.runHooks(this.renderHooks, "render", payload);
|
|
57496
|
+
}
|
|
57497
|
+
applyInterceptors(bucket, kind, payload) {
|
|
57498
|
+
let currentText = payload.text;
|
|
57499
|
+
for (let i3 = 0;i3 < bucket.length; i3 += 1) {
|
|
57500
|
+
const entry = bucket[i3];
|
|
57501
|
+
try {
|
|
57502
|
+
const result = entry.interceptor({ ...payload, text: currentText });
|
|
57503
|
+
if (result === null)
|
|
57504
|
+
return null;
|
|
57505
|
+
if (typeof result === "string")
|
|
57506
|
+
currentText = result;
|
|
57507
|
+
} catch (error) {
|
|
57508
|
+
console.error(`[restty plugin] ${kind} interceptor error (${entry.pluginId}):`, error);
|
|
57509
|
+
}
|
|
57510
|
+
}
|
|
57511
|
+
return currentText;
|
|
57512
|
+
}
|
|
57513
|
+
runHooks(bucket, kind, payload) {
|
|
57514
|
+
for (let i3 = 0;i3 < bucket.length; i3 += 1) {
|
|
57515
|
+
const entry = bucket[i3];
|
|
57516
|
+
try {
|
|
57517
|
+
entry.interceptor(payload);
|
|
57518
|
+
} catch (error) {
|
|
57519
|
+
console.error(`[restty plugin] ${kind} hook error (${entry.pluginId}):`, error);
|
|
57520
|
+
}
|
|
57521
|
+
}
|
|
57522
|
+
}
|
|
57523
|
+
normalizePluginMetadata(plugin, pluginId) {
|
|
57524
|
+
return {
|
|
57525
|
+
...plugin,
|
|
57526
|
+
id: pluginId,
|
|
57527
|
+
version: plugin.version?.trim?.() || undefined,
|
|
57528
|
+
apiVersion: Number.isFinite(plugin.apiVersion) ? Math.trunc(Number(plugin.apiVersion)) : undefined,
|
|
57529
|
+
requires: plugin.requires ?? undefined
|
|
57530
|
+
};
|
|
57531
|
+
}
|
|
57532
|
+
assertPluginCompatibility(pluginId, plugin) {
|
|
57533
|
+
const version = plugin.version?.trim?.();
|
|
57534
|
+
if (version !== undefined && !version) {
|
|
57535
|
+
throw new Error(`Restty plugin ${pluginId} has an empty version`);
|
|
57536
|
+
}
|
|
57537
|
+
if (plugin.apiVersion !== undefined) {
|
|
57538
|
+
if (!Number.isInteger(plugin.apiVersion) || plugin.apiVersion < 1) {
|
|
57539
|
+
throw new Error(`Restty plugin ${pluginId} has invalid apiVersion ${String(plugin.apiVersion)}`);
|
|
57540
|
+
}
|
|
57541
|
+
if (plugin.apiVersion !== RESTTY_PLUGIN_API_VERSION) {
|
|
57542
|
+
throw new Error(`Restty plugin ${pluginId} requires apiVersion ${plugin.apiVersion}, current is ${RESTTY_PLUGIN_API_VERSION}`);
|
|
57543
|
+
}
|
|
57544
|
+
}
|
|
57545
|
+
const requirement = plugin.requires?.pluginApi;
|
|
57546
|
+
if (requirement === undefined)
|
|
57547
|
+
return;
|
|
57548
|
+
if (typeof requirement === "number") {
|
|
57549
|
+
if (!Number.isInteger(requirement) || requirement < 1) {
|
|
57550
|
+
throw new Error(`Restty plugin ${pluginId} has invalid requires.pluginApi value`);
|
|
57551
|
+
}
|
|
57552
|
+
if (requirement !== RESTTY_PLUGIN_API_VERSION) {
|
|
57553
|
+
throw new Error(`Restty plugin ${pluginId} requires pluginApi ${requirement}, current is ${RESTTY_PLUGIN_API_VERSION}`);
|
|
57554
|
+
}
|
|
57555
|
+
return;
|
|
57556
|
+
}
|
|
57557
|
+
const min = requirement.min;
|
|
57558
|
+
const max = requirement.max;
|
|
57559
|
+
if (!Number.isInteger(min) || min < 1) {
|
|
57560
|
+
throw new Error(`Restty plugin ${pluginId} has invalid requires.pluginApi.min`);
|
|
57561
|
+
}
|
|
57562
|
+
if (max !== undefined && (!Number.isInteger(max) || max < min)) {
|
|
57563
|
+
throw new Error(`Restty plugin ${pluginId} has invalid requires.pluginApi.max`);
|
|
57564
|
+
}
|
|
57565
|
+
if (RESTTY_PLUGIN_API_VERSION < min || max !== undefined && RESTTY_PLUGIN_API_VERSION > max) {
|
|
57566
|
+
const range = max === undefined ? `>=${min}` : `${min}-${max}`;
|
|
57567
|
+
throw new Error(`Restty plugin ${pluginId} requires pluginApi range ${range}, current is ${RESTTY_PLUGIN_API_VERSION}`);
|
|
57568
|
+
}
|
|
57569
|
+
}
|
|
57570
|
+
lookupPluginRegistryEntry(registry, pluginId) {
|
|
57571
|
+
if (registry instanceof Map) {
|
|
57572
|
+
return registry.get(pluginId) ?? null;
|
|
57573
|
+
}
|
|
57574
|
+
if (Object.prototype.hasOwnProperty.call(registry, pluginId)) {
|
|
57575
|
+
return registry[pluginId];
|
|
57576
|
+
}
|
|
57577
|
+
return null;
|
|
57578
|
+
}
|
|
57579
|
+
async resolvePluginRegistryEntry(entry) {
|
|
57580
|
+
if (typeof entry === "function") {
|
|
57581
|
+
return await entry();
|
|
57582
|
+
}
|
|
57583
|
+
return entry;
|
|
57584
|
+
}
|
|
57585
|
+
setPluginLoadError(pluginId, message) {
|
|
57586
|
+
this.pluginDiagnostics.set(pluginId, {
|
|
57587
|
+
id: pluginId,
|
|
57588
|
+
version: null,
|
|
57589
|
+
apiVersion: null,
|
|
57590
|
+
requires: null,
|
|
57591
|
+
active: false,
|
|
57592
|
+
activatedAt: null,
|
|
57593
|
+
lastError: message
|
|
57594
|
+
});
|
|
57595
|
+
}
|
|
57596
|
+
updatePluginDiagnostic(pluginId, patch) {
|
|
57597
|
+
const current = this.pluginDiagnostics.get(pluginId);
|
|
57598
|
+
if (!current)
|
|
57599
|
+
return;
|
|
57600
|
+
this.pluginDiagnostics.set(pluginId, {
|
|
57601
|
+
...current,
|
|
57602
|
+
...patch
|
|
57603
|
+
});
|
|
57604
|
+
}
|
|
57605
|
+
buildPluginInfo(pluginId) {
|
|
57606
|
+
const diagnostic = this.pluginDiagnostics.get(pluginId) ?? null;
|
|
57607
|
+
const runtime2 = this.pluginRuntimes.get(pluginId) ?? null;
|
|
57608
|
+
if (!diagnostic && !runtime2)
|
|
57609
|
+
return null;
|
|
57610
|
+
const plugin = runtime2?.plugin;
|
|
57611
|
+
const listeners = runtime2 ? runtime2.disposers.filter((entry) => entry.active && entry.kind === "event").length : 0;
|
|
57612
|
+
const inputInterceptors = runtime2 ? runtime2.disposers.filter((entry) => entry.active && entry.kind === "input-interceptor").length : 0;
|
|
57613
|
+
const outputInterceptors = runtime2 ? runtime2.disposers.filter((entry) => entry.active && entry.kind === "output-interceptor").length : 0;
|
|
57614
|
+
const lifecycleHooks = runtime2 ? runtime2.disposers.filter((entry) => entry.active && entry.kind === "lifecycle-hook").length : 0;
|
|
57615
|
+
const renderHooks = runtime2 ? runtime2.disposers.filter((entry) => entry.active && entry.kind === "render-hook").length : 0;
|
|
57616
|
+
return {
|
|
57617
|
+
id: pluginId,
|
|
57618
|
+
version: plugin?.version?.trim?.() || diagnostic?.version || null,
|
|
57619
|
+
apiVersion: plugin?.apiVersion ?? (Number.isFinite(diagnostic?.apiVersion) ? diagnostic?.apiVersion : null),
|
|
57620
|
+
requires: plugin?.requires ?? diagnostic?.requires ?? null,
|
|
57621
|
+
active: runtime2 ? true : diagnostic?.active ?? false,
|
|
57622
|
+
activatedAt: runtime2?.activatedAt ?? diagnostic?.activatedAt ?? null,
|
|
57623
|
+
lastError: diagnostic?.lastError ?? null,
|
|
57624
|
+
listeners,
|
|
57625
|
+
inputInterceptors,
|
|
57626
|
+
outputInterceptors,
|
|
57627
|
+
lifecycleHooks,
|
|
57628
|
+
renderHooks
|
|
57629
|
+
};
|
|
57630
|
+
}
|
|
57631
|
+
errorToMessage(error) {
|
|
57632
|
+
if (error instanceof Error)
|
|
57633
|
+
return error.message || error.name || "Unknown error";
|
|
57634
|
+
return String(error);
|
|
57635
|
+
}
|
|
57636
|
+
onPluginEvent(event, listener) {
|
|
57637
|
+
let listeners = this.pluginListeners.get(event);
|
|
57638
|
+
if (!listeners) {
|
|
57639
|
+
listeners = new Set;
|
|
57640
|
+
this.pluginListeners.set(event, listeners);
|
|
57641
|
+
}
|
|
57642
|
+
const wrapped = listener;
|
|
57643
|
+
listeners.add(wrapped);
|
|
57644
|
+
return () => {
|
|
57645
|
+
const current = this.pluginListeners.get(event);
|
|
57646
|
+
if (!current)
|
|
57647
|
+
return;
|
|
57648
|
+
current.delete(wrapped);
|
|
57649
|
+
if (current.size === 0) {
|
|
57650
|
+
this.pluginListeners.delete(event);
|
|
57651
|
+
}
|
|
57652
|
+
};
|
|
57653
|
+
}
|
|
57654
|
+
emitPluginEvent(event, payload) {
|
|
57655
|
+
const listeners = this.pluginListeners.get(event);
|
|
57656
|
+
if (!listeners || listeners.size === 0)
|
|
57657
|
+
return;
|
|
57658
|
+
const snapshot = Array.from(listeners);
|
|
57659
|
+
for (let i3 = 0;i3 < snapshot.length; i3 += 1) {
|
|
57660
|
+
try {
|
|
57661
|
+
snapshot[i3](payload);
|
|
57662
|
+
} catch (error) {
|
|
57663
|
+
console.error(`[restty plugin] listener error (${String(event)}):`, error);
|
|
57664
|
+
}
|
|
57665
|
+
}
|
|
57666
|
+
}
|
|
57667
|
+
teardownPluginRuntime(runtime2) {
|
|
57668
|
+
for (let i3 = 0;i3 < runtime2.disposers.length; i3 += 1) {
|
|
57669
|
+
try {
|
|
57670
|
+
runtime2.disposers[i3].dispose();
|
|
57671
|
+
} catch {}
|
|
57672
|
+
}
|
|
57673
|
+
runtime2.disposers.length = 0;
|
|
57674
|
+
const cleanup = runtime2.cleanup;
|
|
57675
|
+
runtime2.cleanup = null;
|
|
57676
|
+
if (!cleanup)
|
|
57677
|
+
return;
|
|
57678
|
+
try {
|
|
57679
|
+
cleanup();
|
|
57680
|
+
} catch (error) {
|
|
57681
|
+
console.error(`[restty plugin] cleanup error (${runtime2.plugin.id}):`, error);
|
|
57682
|
+
}
|
|
57683
|
+
}
|
|
57684
|
+
normalizePluginCleanup(cleanup) {
|
|
57685
|
+
if (!cleanup)
|
|
57686
|
+
return null;
|
|
57687
|
+
if (typeof cleanup === "function")
|
|
57688
|
+
return cleanup;
|
|
57689
|
+
if (typeof cleanup === "object" && typeof cleanup.dispose === "function") {
|
|
57690
|
+
return () => cleanup.dispose();
|
|
57691
|
+
}
|
|
57692
|
+
return null;
|
|
57693
|
+
}
|
|
56764
57694
|
}
|
|
56765
57695
|
function createRestty(options) {
|
|
56766
57696
|
return new Restty(options);
|
|
56767
57697
|
}
|
|
56768
57698
|
|
|
56769
|
-
export { BOX_LINE_MAP, BOX_STYLE_NONE, BOX_STYLE_LIGHT, BOX_STYLE_HEAVY, BOX_STYLE_DOUBLE, isPrivateUse, isSpaceCp, isBoxDrawing, isBlockElement, isLegacyComputing, isPowerline, isBraille, isGraphicsElement, isSymbolCp, applyAlpha, pushRect, pushRectSnapped, pushRectBox, drawBlockElement, drawBoxDrawing, drawBraille, drawPowerline, constrainGlyphBox, RECT_SHADER, GLYPH_SHADER, initWebGPUCore, initWebGPU, initWebGL, ensureInstanceBuffer, configureContext, ensureGLInstanceBuffer, createResizeState, createScrollbarState, ResttyWasm, loadResttyWasm, createInputHandler, NERD_SYMBOL_RANGES, isNerdSymbolCodepoint, fontHeightUnits, computeCellMetrics, createGridState, updateGridState, clamp, isSymbolFont, isNerdSymbolFont, fontMaxCellSpan, fontScaleOverride, fontRasterScale, createFontEntry, resetFontEntry, createFontManagerState, fontHasGlyph, fontAdvanceUnits, glyphWidthUnits, pickFontIndexForText, tryFetchFontBuffer, tryLocalFontBuffer, loadPrimaryFontBuffer, loadFallbackFontBuffers, NERD_CONSTRAINTS, getNerdConstraint, createPtyConnection, connectPty, disconnectPty, sendPtyInput, sendPtyResize, isPtyConnected, createWebSocketPtyTransport, parseGhosttyColor, colorToFloats, colorToRgbU32, parseGhosttyTheme, listBuiltinThemeNames, isBuiltinThemeName, getBuiltinThemeSource, getBuiltinTheme, createImeState, setPreedit, clearPreedit, startComposition, updateComposition, endComposition, syncImeSelection, updateImePosition, PREEDIT_BG, PREEDIT_ACTIVE_BG, PREEDIT_FG, PREEDIT_UL, PREEDIT_CARET, ResttyPaneHandle, Restty, createRestty };
|
|
57699
|
+
export { BOX_LINE_MAP, BOX_STYLE_NONE, BOX_STYLE_LIGHT, BOX_STYLE_HEAVY, BOX_STYLE_DOUBLE, isPrivateUse, isSpaceCp, isBoxDrawing, isBlockElement, isLegacyComputing, isPowerline, isBraille, isGraphicsElement, isSymbolCp, applyAlpha, pushRect, pushRectSnapped, pushRectBox, drawBlockElement, drawBoxDrawing, drawBraille, drawPowerline, constrainGlyphBox, RECT_SHADER, GLYPH_SHADER, initWebGPUCore, initWebGPU, initWebGL, ensureInstanceBuffer, configureContext, ensureGLInstanceBuffer, createResizeState, createScrollbarState, ResttyWasm, loadResttyWasm, createInputHandler, NERD_SYMBOL_RANGES, isNerdSymbolCodepoint, fontHeightUnits, computeCellMetrics, createGridState, updateGridState, clamp, isSymbolFont, isNerdSymbolFont, fontMaxCellSpan, fontScaleOverride, fontRasterScale, createFontEntry, resetFontEntry, createFontManagerState, fontHasGlyph, fontAdvanceUnits, glyphWidthUnits, pickFontIndexForText, tryFetchFontBuffer, tryLocalFontBuffer, loadPrimaryFontBuffer, loadFallbackFontBuffers, NERD_CONSTRAINTS, getNerdConstraint, createPtyConnection, connectPty, disconnectPty, sendPtyInput, sendPtyResize, isPtyConnected, createWebSocketPtyTransport, parseGhosttyColor, colorToFloats, colorToRgbU32, parseGhosttyTheme, listBuiltinThemeNames, isBuiltinThemeName, getBuiltinThemeSource, getBuiltinTheme, createImeState, setPreedit, clearPreedit, startComposition, updateComposition, endComposition, syncImeSelection, updateImePosition, PREEDIT_BG, PREEDIT_ACTIVE_BG, PREEDIT_FG, PREEDIT_UL, PREEDIT_CARET, RESTTY_PLUGIN_API_VERSION, ResttyPaneHandle, Restty, createRestty };
|