feat: sidebar runtime extraction + history-safe commands + checklist updates
This commit is contained in:
@@ -199,10 +199,153 @@ function runSessionConflictAction(action, deps) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 接受磁盘版本:用磁盘快照替换当前 session 内容。
|
||||
* 依赖通过 deps 注入,确保 runtime 不依赖 inline 作用域闭包。
|
||||
* @param {Object} session
|
||||
* @param {Object} deps
|
||||
* @param {Function} deps.setSessionStatus
|
||||
* @param {Function} deps.fetchLatestResourceSnapshot
|
||||
* @param {Function} deps.applyResourceSnapshotToSession
|
||||
* @param {Function} deps.fetchLatestSessionAggregate
|
||||
* @param {Function} deps.applyAggregateSnapshotToSession
|
||||
*/
|
||||
function acceptDiskVersion(session, deps) {
|
||||
deps = deps || {};
|
||||
var setSessionStatus = deps.setSessionStatus || function() {};
|
||||
var fetchLatestResourceSnapshot = deps.fetchLatestResourceSnapshot || function() { return Promise.resolve(null); };
|
||||
var applyResourceSnapshotToSession = deps.applyResourceSnapshotToSession || function() {};
|
||||
var fetchLatestSessionAggregate = deps.fetchLatestSessionAggregate || function() { return Promise.resolve(null); };
|
||||
var applyAggregateSnapshotToSession = deps.applyAggregateSnapshotToSession || function() {};
|
||||
|
||||
setSessionStatus(session, 'conflict-resolving', '正在接受磁盘版本...');
|
||||
if (session.sessionKind === 'resource') {
|
||||
return fetchLatestResourceSnapshot(session).then(function(latestResource) {
|
||||
applyResourceSnapshotToSession(session, latestResource, 'mnote-web-resource-conflict-accept-disk');
|
||||
});
|
||||
}
|
||||
return fetchLatestSessionAggregate(session).then(function(latest) {
|
||||
applyAggregateSnapshotToSession(session, latest, 'mnote-web-conflict-accept-disk');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 保留当前编辑器版本:读取 editor 实时文本,更新 conflictDetectionKey,
|
||||
* 清空冲突标记,持久化后关闭冲突面板。
|
||||
* 依赖通过 deps 注入。
|
||||
* @param {Object} session
|
||||
* @param {Object} deps
|
||||
* @param {Function} deps.setSessionStatus
|
||||
* @param {Function} deps.fetchLatestResourceSnapshot - 返回 Promise<Object>
|
||||
* @param {Function} deps.fetchLatestSessionAggregate - 返回 Promise<Object>
|
||||
* @param {Function} deps.sessionViews - session → views[]
|
||||
* @param {Function} deps.currentEditorText - view → string
|
||||
* @param {Function} deps.normalizePlainText - string → string
|
||||
* @param {Function} deps.hydrateMindmapAttrsFromDom - (doc, root) → doc
|
||||
* @param {Function} deps.textToTiptapDocument - string → doc
|
||||
* @param {Function} deps.conflictDetectionKeyFromBody - body → string
|
||||
* @param {Function} deps.clearSessionConflictSurface - session → void
|
||||
* @param {Function} deps.persistSession - session → Promise
|
||||
*/
|
||||
function keepCurrentEditorVersion(session, deps) {
|
||||
deps = deps || {};
|
||||
var setSessionStatus = deps.setSessionStatus || function() {};
|
||||
var fetchLatestResourceSnapshot = deps.fetchLatestResourceSnapshot || function() { return Promise.resolve(null); };
|
||||
var fetchLatestSessionAggregate = deps.fetchLatestSessionAggregate || function() { return Promise.resolve(null); };
|
||||
var sessionViews = deps.sessionViews || function() { return []; };
|
||||
var currentEditorText = deps.currentEditorText || function() { return ''; };
|
||||
var normalizePlainText = deps.normalizePlainText || function(s) { return s; };
|
||||
var hydrateMindmapAttrsFromDom = deps.hydrateMindmapAttrsFromDom || function(doc) { return doc; };
|
||||
var textToTiptapDocument = deps.textToTiptapDocument || function(s) { return {type: 'doc', content: [{type: 'paragraph', content: [{type: 'text', text: s}]}]}; };
|
||||
var conflictDetectionKeyFromBody = deps.conflictDetectionKeyFromBody || function() { return ''; };
|
||||
var clearSessionConflictSurface = deps.clearSessionConflictSurface || function() {};
|
||||
var persistSession = deps.persistSession || function() { return Promise.resolve(); };
|
||||
|
||||
setSessionStatus(session, 'conflict-resolving', '正在保留当前编辑器版本...');
|
||||
var latestPromise = session.sessionKind === 'resource'
|
||||
? fetchLatestResourceSnapshot(session)
|
||||
: fetchLatestSessionAggregate(session);
|
||||
return latestPromise.then(function(latest) {
|
||||
var hydrateView = sessionViews(session).find(function(item) { return item.mountId != null; }) || sessionViews(session)[0];
|
||||
if (hydrateView) {
|
||||
var liveText = normalizePlainText(currentEditorText(hydrateView));
|
||||
if (liveText) {
|
||||
session.currentTiptapDocument = hydrateMindmapAttrsFromDom(
|
||||
textToTiptapDocument(liveText),
|
||||
hydrateView.runtimeDescriptor && hydrateView.runtimeDescriptor.root,
|
||||
);
|
||||
}
|
||||
session.currentSerialized = JSON.stringify(session.currentTiptapDocument);
|
||||
}
|
||||
var nextKey = session.sessionKind === 'resource'
|
||||
? String((latest && (latest.fileVersion || latest.conflictDetectionKey) || '')).trim()
|
||||
: conflictDetectionKeyFromBody((latest && latest.body) || {});
|
||||
if (nextKey) {
|
||||
session.conflictDetectionKey = nextKey;
|
||||
session.lastExternalConflictDetectionKey = nextKey;
|
||||
}
|
||||
session.hasExternalConflict = false;
|
||||
session.externalChangePending = false;
|
||||
session.saving = false;
|
||||
session.dirty = true;
|
||||
clearSessionConflictSurface(session);
|
||||
return persistSession(session);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 写回合并结果:将 merge textarea 中的文本写入 session,
|
||||
* 更新 conflictDetectionKey,清除冲突标记,持久化后移除面板。
|
||||
* @param {Object} session
|
||||
* @param {HTMLElement|null} panel - 待移除的面板 DOM
|
||||
* @param {string} mergedText
|
||||
* @param {Object} deps
|
||||
* @param {Function} deps.setSessionStatus
|
||||
* @param {Function} deps.fetchLatestResourceSnapshot - Promise<Object>
|
||||
* @param {Function} deps.fetchLatestSessionAggregate - Promise<Object>
|
||||
* @param {Function} deps.conflictDetectionKeyFromBody - body → string
|
||||
* @param {Function} deps.textToTiptapDocument - string → doc
|
||||
* @param {Function} deps.persistSession - session → Promise
|
||||
*/
|
||||
function writeMergedConflictResult(session, panel, mergedText, deps) {
|
||||
deps = deps || {};
|
||||
var setSessionStatus = deps.setSessionStatus || function() {};
|
||||
var fetchLatestResourceSnapshot = deps.fetchLatestResourceSnapshot || function() { return Promise.resolve(null); };
|
||||
var fetchLatestSessionAggregate = deps.fetchLatestSessionAggregate || function() { return Promise.resolve(null); };
|
||||
var conflictDetectionKeyFromBody = deps.conflictDetectionKeyFromBody || function() { return ''; };
|
||||
var textToTiptapDocument = deps.textToTiptapDocument || function(s) { return {type: 'doc', content: [{type: 'paragraph', content: [{type: 'text', text: s}]}]}; };
|
||||
var persistSession = deps.persistSession || function() { return Promise.resolve(); };
|
||||
|
||||
setSessionStatus(session, 'conflict-resolving', '正在写回合并结果...');
|
||||
var latestPromise = session.sessionKind === 'resource'
|
||||
? fetchLatestResourceSnapshot(session)
|
||||
: fetchLatestSessionAggregate(session);
|
||||
return latestPromise.then(function(latest) {
|
||||
var nextKey = session.sessionKind === 'resource'
|
||||
? String((latest && (latest.fileVersion || latest.conflictDetectionKey) || '')).trim()
|
||||
: conflictDetectionKeyFromBody((latest && latest.body) || {});
|
||||
if (nextKey) {
|
||||
session.conflictDetectionKey = nextKey;
|
||||
session.lastExternalConflictDetectionKey = nextKey;
|
||||
}
|
||||
session.currentTiptapDocument = textToTiptapDocument(String(mergedText || ''));
|
||||
session.currentSerialized = JSON.stringify(session.currentTiptapDocument);
|
||||
session.hasExternalConflict = false;
|
||||
session.externalChangePending = false;
|
||||
session.saving = false;
|
||||
session.dirty = true;
|
||||
if (panel && typeof panel.remove === 'function') panel.remove();
|
||||
return persistSession(session);
|
||||
});
|
||||
}
|
||||
|
||||
window.__mnoteDocumentConflictPanelRuntime = {
|
||||
clearSessionConflictSurface: clearSessionConflictSurface,
|
||||
createSessionConflictPanel: createSessionConflictPanel,
|
||||
mountSessionConflictPanel: mountSessionConflictPanel,
|
||||
populateSessionConflictDiffPanel: populateSessionConflictDiffPanel,
|
||||
runSessionConflictAction: runSessionConflictAction
|
||||
runSessionConflictAction: runSessionConflictAction,
|
||||
acceptDiskVersion: acceptDiskVersion,
|
||||
keepCurrentEditorVersion: keepCurrentEditorVersion,
|
||||
writeMergedConflictResult: writeMergedConflictResult
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user