97 lines
2.5 KiB
JavaScript
97 lines
2.5 KiB
JavaScript
(function () {
|
|
if (!window.MDHubCache) {
|
|
return;
|
|
}
|
|
|
|
function normalizeDocPath(path) {
|
|
if (!path) return "";
|
|
return path.replace(/^\/+/, "");
|
|
}
|
|
|
|
async function postDocument(path, content, baseHash) {
|
|
const response = await fetch("/api/documents/" + normalizeDocPath(path), {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({ content: content, baseHash: baseHash || "" }),
|
|
});
|
|
|
|
const payload = await response.json().catch(function () {
|
|
return {};
|
|
});
|
|
|
|
if (!response.ok) {
|
|
if (response.status === 409) {
|
|
const conflict = new Error("document conflict");
|
|
conflict.name = "DocumentConflictError";
|
|
conflict.details = payload;
|
|
throw conflict;
|
|
}
|
|
throw new Error("save failed");
|
|
}
|
|
|
|
return payload;
|
|
}
|
|
|
|
async function saveDocument(path, content, baseHash) {
|
|
const normalizedPath = window.MDHubCache.normalizePath("/docs/" + normalizeDocPath(path));
|
|
|
|
try {
|
|
const result = await postDocument(path, content, baseHash);
|
|
await window.MDHubCache.deletePendingEdit(normalizedPath);
|
|
return {
|
|
status: "saved",
|
|
result: result,
|
|
};
|
|
} catch (error) {
|
|
if (error.name === "DocumentConflictError") {
|
|
await window.MDHubCache.putPendingEdit(normalizedPath, content, baseHash);
|
|
await window.MDHubCache.markPendingEditConflict(normalizedPath, error.details);
|
|
return {
|
|
status: "conflict",
|
|
conflict: error.details,
|
|
};
|
|
}
|
|
await window.MDHubCache.putPendingEdit(normalizedPath, content, baseHash);
|
|
return {
|
|
status: "queued",
|
|
};
|
|
}
|
|
}
|
|
|
|
async function syncPending() {
|
|
if (!navigator.onLine) {
|
|
return;
|
|
}
|
|
|
|
const pending = await window.MDHubCache.getPendingEdits();
|
|
pending.sort(function (a, b) {
|
|
return (a.updatedAt || 0) - (b.updatedAt || 0);
|
|
});
|
|
|
|
for (const edit of pending) {
|
|
try {
|
|
await postDocument(edit.path.replace(/^\/docs\//, ""), edit.content, edit.baseHash);
|
|
await window.MDHubCache.deletePendingEdit(edit.path);
|
|
} catch (error) {
|
|
if (error.name === "DocumentConflictError") {
|
|
await window.MDHubCache.markPendingEditConflict(edit.path, error.details);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
window.addEventListener("online", function () {
|
|
syncPending().catch(function () {});
|
|
});
|
|
|
|
syncPending().catch(function () {});
|
|
|
|
window.MDHubSync = {
|
|
saveDocument: saveDocument,
|
|
syncPending: syncPending,
|
|
};
|
|
})();
|