Files
cairnquire/apps/server/internal/httpserver/static/sync.js

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,
};
})();