first commit
This commit is contained in:
201
apps/miniprogram/utils/terminalSession.js
Normal file
201
apps/miniprogram/utils/terminalSession.js
Normal file
@@ -0,0 +1,201 @@
|
||||
/* global wx, console, module, require */
|
||||
|
||||
const { buildTerminalSessionSnapshot, normalizeTerminalSessionSnapshot } = require("./terminalSessionState");
|
||||
|
||||
const TERMINAL_SESSION_STORAGE_KEY = "remoteconn.terminal.session.v1";
|
||||
const TERMINAL_BUFFER_STORAGE_KEY = "remoteconn.terminal.buffer.v1";
|
||||
|
||||
function normalizePositiveInt(value, fallback, min) {
|
||||
const parsed = Number(value);
|
||||
if (!Number.isFinite(parsed)) return fallback;
|
||||
const normalized = Math.round(parsed);
|
||||
if (normalized < min) return fallback;
|
||||
return normalized;
|
||||
}
|
||||
|
||||
function normalizeTerminalSnapshotStyle(input) {
|
||||
const source = input && typeof input === "object" ? input : null;
|
||||
if (!source) return null;
|
||||
const fg = String(source.fg || "").trim();
|
||||
const bg = String(source.bg || "").trim();
|
||||
const bold = source.bold === true;
|
||||
const underline = source.underline === true;
|
||||
if (!fg && !bg && !bold && !underline) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
fg,
|
||||
bg,
|
||||
bold,
|
||||
underline
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeTerminalSnapshotStyleTable(input) {
|
||||
const rows = Array.isArray(input) ? input : [];
|
||||
return rows.map((item) => normalizeTerminalSnapshotStyle(item)).filter(Boolean);
|
||||
}
|
||||
|
||||
function normalizeTerminalSnapshotRun(input, styleCount) {
|
||||
const source = input && typeof input === "object" ? input : null;
|
||||
if (!source) return null;
|
||||
const text =
|
||||
typeof source.t === "string" ? source.t : typeof source.text === "string" ? source.text : "";
|
||||
const rawColumns = Number(source.c !== undefined ? source.c : source.columns);
|
||||
const columns = Number.isFinite(rawColumns) ? Math.max(0, Math.round(rawColumns)) : 0;
|
||||
if (!text && columns <= 0) {
|
||||
return null;
|
||||
}
|
||||
const next = {};
|
||||
if (text) next.t = text;
|
||||
if (columns > 0) next.c = columns;
|
||||
if (source.f === 1 || source.fixed === true) {
|
||||
next.f = 1;
|
||||
}
|
||||
const rawStyleIndex = Number(source.s !== undefined ? source.s : source.styleIndex);
|
||||
if (Number.isInteger(rawStyleIndex) && rawStyleIndex >= 0 && rawStyleIndex < styleCount) {
|
||||
next.s = rawStyleIndex;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
function normalizeTerminalSnapshotStyledLines(input, styleTable) {
|
||||
const rows = Array.isArray(input) ? input : [];
|
||||
const styleCount = Array.isArray(styleTable) ? styleTable.length : 0;
|
||||
return rows.map((line) => {
|
||||
const runs = Array.isArray(line) ? line : [];
|
||||
return runs.map((run) => normalizeTerminalSnapshotRun(run, styleCount)).filter(Boolean);
|
||||
});
|
||||
}
|
||||
|
||||
function readTerminalSessionRaw() {
|
||||
try {
|
||||
const value = wx.getStorageSync(TERMINAL_SESSION_STORAGE_KEY);
|
||||
return value && typeof value === "object" ? value : null;
|
||||
} catch (error) {
|
||||
console.warn("[terminalSession.read]", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function getTerminalSessionSnapshot(now = Date.now()) {
|
||||
const snapshot = normalizeTerminalSessionSnapshot(readTerminalSessionRaw(), now);
|
||||
if (snapshot) {
|
||||
return snapshot;
|
||||
}
|
||||
clearTerminalSessionSnapshot();
|
||||
return null;
|
||||
}
|
||||
|
||||
function saveTerminalSessionSnapshot(snapshot, now = Date.now()) {
|
||||
const normalized = normalizeTerminalSessionSnapshot(snapshot, now);
|
||||
if (!normalized) {
|
||||
clearTerminalSessionSnapshot();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
wx.setStorageSync(TERMINAL_SESSION_STORAGE_KEY, normalized);
|
||||
return normalized;
|
||||
} catch (error) {
|
||||
console.warn("[terminalSession.write]", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function createTerminalSessionSnapshot(input, now = Date.now()) {
|
||||
const snapshot = buildTerminalSessionSnapshot(input, now);
|
||||
if (!snapshot) return null;
|
||||
return saveTerminalSessionSnapshot(snapshot, now);
|
||||
}
|
||||
|
||||
function markTerminalSessionResumable(patch, now = Date.now()) {
|
||||
return createTerminalSessionSnapshot({ ...(patch || {}), status: "resumable" }, now);
|
||||
}
|
||||
|
||||
function normalizeTerminalBufferSnapshot(input, now = Date.now()) {
|
||||
const source = input && typeof input === "object" ? input : null;
|
||||
if (!source) return null;
|
||||
const sessionKey = String(source.sessionKey || "").trim();
|
||||
if (!sessionKey) return null;
|
||||
const lines = Array.isArray(source.lines) ? source.lines.filter((item) => typeof item === "string") : [];
|
||||
const styleTable = normalizeTerminalSnapshotStyleTable(source.styleTable);
|
||||
const styledLines = normalizeTerminalSnapshotStyledLines(source.styledLines, styleTable);
|
||||
const replayText = typeof source.replayText === "string" ? source.replayText : "";
|
||||
const cursorRow = Number(source.cursorRow);
|
||||
const cursorCol = Number(source.cursorCol);
|
||||
const savedAt = Number(source.savedAt);
|
||||
const bufferCols = normalizePositiveInt(source.bufferCols, 80, 1);
|
||||
const bufferRows = normalizePositiveInt(source.bufferRows, 24, 1);
|
||||
return {
|
||||
version: styledLines.length > 0 ? 2 : 1,
|
||||
sessionKey,
|
||||
lines,
|
||||
styleTable,
|
||||
styledLines,
|
||||
replayText,
|
||||
bufferCols,
|
||||
bufferRows,
|
||||
cursorRow: Number.isFinite(cursorRow) ? Math.max(0, Math.round(cursorRow)) : 0,
|
||||
cursorCol: Number.isFinite(cursorCol) ? Math.max(0, Math.round(cursorCol)) : 0,
|
||||
savedAt: Number.isFinite(savedAt) ? Math.round(savedAt) : now
|
||||
};
|
||||
}
|
||||
|
||||
function saveTerminalBufferSnapshot(snapshot, now = Date.now()) {
|
||||
const normalized = normalizeTerminalBufferSnapshot(snapshot, now);
|
||||
if (!normalized) {
|
||||
clearTerminalBufferSnapshot();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
wx.setStorageSync(TERMINAL_BUFFER_STORAGE_KEY, normalized);
|
||||
return normalized;
|
||||
} catch (error) {
|
||||
console.warn("[terminalBuffer.write]", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function getTerminalBufferSnapshot(sessionKey, now = Date.now()) {
|
||||
const targetSessionKey = String(sessionKey || "").trim();
|
||||
if (!targetSessionKey) return null;
|
||||
try {
|
||||
const raw = wx.getStorageSync(TERMINAL_BUFFER_STORAGE_KEY);
|
||||
const normalized = normalizeTerminalBufferSnapshot(raw, now);
|
||||
if (!normalized || normalized.sessionKey !== targetSessionKey) {
|
||||
return null;
|
||||
}
|
||||
return normalized;
|
||||
} catch (error) {
|
||||
console.warn("[terminalBuffer.read]", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function clearTerminalBufferSnapshot() {
|
||||
try {
|
||||
wx.removeStorageSync(TERMINAL_BUFFER_STORAGE_KEY);
|
||||
} catch (error) {
|
||||
console.warn("[terminalBuffer.clear]", error);
|
||||
}
|
||||
}
|
||||
|
||||
function clearTerminalSessionSnapshot() {
|
||||
try {
|
||||
wx.removeStorageSync(TERMINAL_SESSION_STORAGE_KEY);
|
||||
} catch (error) {
|
||||
console.warn("[terminalSession.clear]", error);
|
||||
}
|
||||
clearTerminalBufferSnapshot();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getTerminalSessionSnapshot,
|
||||
saveTerminalSessionSnapshot,
|
||||
createTerminalSessionSnapshot,
|
||||
markTerminalSessionResumable,
|
||||
getTerminalBufferSnapshot,
|
||||
saveTerminalBufferSnapshot,
|
||||
clearTerminalBufferSnapshot,
|
||||
clearTerminalSessionSnapshot
|
||||
};
|
||||
Reference in New Issue
Block a user