78 lines
2.4 KiB
JavaScript
78 lines
2.4 KiB
JavaScript
async function loadWorkspace({
|
|
document,
|
|
window = null,
|
|
createLoader = createFeatureLoader,
|
|
schedule = callback => setTimeout(callback,750),
|
|
}) {
|
|
let cameOnline = false;
|
|
let replayed = false;
|
|
let retryInFlight = null;
|
|
const captureOnline = () => { cameOnline = true; };
|
|
window?.addEventListener('online', captureOnline);
|
|
const status = document.querySelector('#my-work-action-status');
|
|
const retryButton = document.querySelector('#retry-workspace');
|
|
const urls = Object.fromEntries(['today-timer', 'planning'].map(name => [name,
|
|
document.querySelector(`meta[name="stackchain-feature-${name}"]`)?.content || ''
|
|
]));
|
|
const originalUrls = {...urls};
|
|
const loader = createLoader({document, urls});
|
|
|
|
let attempts = 0;
|
|
const load = () => {
|
|
if (attempts++) Object.keys(urls).forEach(name => {
|
|
urls[name] = originalUrls[name] + '?retry=' + attempts;
|
|
});
|
|
return Promise.all(Object.keys(urls).map(name => loader.load(name)));
|
|
};
|
|
const waitForRecovery = () => new Promise(resolve => {
|
|
if (status) status.textContent = 'Workspace unavailable. Reconnect or retry.';
|
|
if (retryButton) {
|
|
retryButton.hidden = retryButton.disabled = false;
|
|
}
|
|
|
|
const recover = () => {
|
|
if (retryInFlight) return retryInFlight;
|
|
if (retryButton) retryButton.disabled = true;
|
|
retryInFlight = load().then(() => {
|
|
window?.removeEventListener('online', recover);
|
|
resolve();
|
|
}).catch(() => {
|
|
if (status) status.textContent = 'Workspace unavailable. Reconnect or retry.';
|
|
if (retryButton) retryButton.disabled = false;
|
|
}).finally(() => {
|
|
retryInFlight = null;
|
|
});
|
|
return retryInFlight;
|
|
};
|
|
|
|
window?.removeEventListener('online', captureOnline);
|
|
window?.addEventListener('online', recover);
|
|
retryButton?.addEventListener('click', recover);
|
|
});
|
|
|
|
try {
|
|
await load();
|
|
} catch {
|
|
await new Promise(resolve => schedule(resolve));
|
|
try {
|
|
await load();
|
|
} catch {
|
|
await waitForRecovery();
|
|
}
|
|
}
|
|
|
|
window?.removeEventListener('online', captureOnline);
|
|
if (retryButton) retryButton.hidden = true;
|
|
if (status) status.textContent = '';
|
|
return {
|
|
replayOnline(callback) {
|
|
if (replayed) return;
|
|
replayed = true;
|
|
window?.removeEventListener('online', captureOnline);
|
|
if (cameOnline) callback();
|
|
},
|
|
};
|
|
}
|
|
|
|
if (typeof module !== 'undefined' && module.exports) module.exports = loadWorkspace;
|