Skip to content

Commit 6e309c1

Browse files
committed
feat: implement editor operation queue to manage concurrent editor instances and improve cleanup process
1 parent 4634607 commit 6e309c1

1 file changed

Lines changed: 70 additions & 11 deletions

File tree

‎lib/x2t.ts‎

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,38 @@ export function getDocumentType(fileType: string): string | null {
943943
}
944944
// Global media mapping object
945945
const media: Record<string, string> = {};
946+
947+
// Editor operation queue to prevent concurrent operations
948+
let editorOperationQueue: Promise<void> = Promise.resolve();
949+
950+
/**
951+
* Queue editor operations to prevent concurrent editor creation/destruction
952+
*/
953+
async function queueEditorOperation<T>(operation: () => Promise<T>): Promise<T> {
954+
// Wait for previous operations to complete
955+
await editorOperationQueue;
956+
957+
// Create a new promise for this operation
958+
let resolveOperation: () => void;
959+
let rejectOperation: (error: any) => void;
960+
const operationPromise = new Promise<void>((resolve, reject) => {
961+
resolveOperation = resolve;
962+
rejectOperation = reject;
963+
});
964+
965+
// Update the queue
966+
editorOperationQueue = operationPromise;
967+
968+
try {
969+
const result = await operation();
970+
resolveOperation!();
971+
return result;
972+
} catch (error) {
973+
rejectOperation!(error);
974+
throw error;
975+
}
976+
}
977+
946978
/**
947979
* Handle file write request (mainly for handling pasted images)
948980
* @param event - OnlyOffice editor file write event
@@ -1029,18 +1061,40 @@ function createEditorInstance(config: {
10291061
binData: ArrayBuffer | string;
10301062
media?: any;
10311063
}) {
1032-
// Clean up old editor instance
1033-
if (window.editor) {
1034-
window.editor.destroyEditor();
1035-
window.editor = undefined;
1036-
}
1064+
return queueEditorOperation(async () => {
1065+
// Clean up old editor instance properly
1066+
if (window.editor) {
1067+
try {
1068+
console.log('Destroying previous editor instance...');
1069+
window.editor.destroyEditor();
1070+
// Wait a bit for destroy to complete
1071+
await new Promise((resolve) => setTimeout(resolve, 150));
1072+
} catch (error) {
1073+
console.warn('Error destroying previous editor:', error);
1074+
}
1075+
window.editor = undefined;
1076+
}
1077+
1078+
// Clean up iframe container to ensure clean state
1079+
const iframeContainer = document.getElementById('iframe');
1080+
if (iframeContainer) {
1081+
// Remove all child elements
1082+
while (iframeContainer.firstChild) {
1083+
iframeContainer.removeChild(iframeContainer.firstChild);
1084+
}
1085+
}
10371086

1038-
const { fileName, fileType, binData, media } = config;
1087+
// Additional delay to ensure cleanup completes before creating new editor
1088+
// This is especially important when switching between different document types
1089+
await new Promise((resolve) => setTimeout(resolve, 150));
10391090

1040-
const editorLang = getOnlyOfficeLang();
1041-
console.log('Setting OnlyOffice editor language to:', editorLang);
1091+
const { fileName, fileType, binData, media } = config;
10421092

1043-
window.editor = new window.DocsAPI.DocEditor('iframe', {
1093+
const editorLang = getOnlyOfficeLang();
1094+
console.log('Creating new editor instance for:', fileName, 'type:', fileType);
1095+
1096+
try {
1097+
window.editor = new window.DocsAPI.DocEditor('iframe', {
10441098
document: {
10451099
title: fileName,
10461100
url: fileName, // Use file name as identifier
@@ -1096,6 +1150,11 @@ function createEditorInstance(config: {
10961150
writeFile: handleWriteFile,
10971151
},
10981152
});
1153+
} catch (error) {
1154+
console.error('Error creating editor instance:', error);
1155+
throw error;
1156+
}
1157+
});
10991158
}
11001159

11011160
// Merged file operation method
@@ -1129,8 +1188,8 @@ export async function handleDocumentOperation(options: {
11291188
documentData = await convertDocument(file);
11301189
}
11311190

1132-
// Create editor instance
1133-
createEditorInstance({
1191+
// Create editor instance (now returns a Promise, uses queue internally)
1192+
await createEditorInstance({
11341193
fileName,
11351194
fileType,
11361195
binData: documentData.bin,

0 commit comments

Comments
 (0)