fix: preserve reconnect across deferred workspace startup
Some checks failed
CI / lint (pull_request) Successful in 2m49s
CI / build-release (pull_request) Successful in 6s
CI / browser-journey (pull_request) Failing after 2m53s
CI / release-candidate (pull_request) Has been skipped

This commit is contained in:
timmy 2026-08-17 01:41:22 +00:00
parent 0a4c9a0ae8
commit 377fd889c5
4 changed files with 36 additions and 4 deletions

View File

@ -7388,8 +7388,9 @@
updateDeliveryReceiptControls();
if (!navigator.onLine) await showOfflineStatus();
window.addEventListener('offline', showOfflineStatus);
window.addEventListener('online', reconnectOutboxes);
workspaceLifecycle.replayOnline(reconnectOutboxes);
const reconnectAfterOnline = () => setTimeout(reconnectOutboxes, 500);
window.addEventListener('online', reconnectAfterOnline);
workspaceLifecycle.replayOnline(reconnectAfterOnline);
qs('#refresh').addEventListener('click', load);
qs('#plan-today').addEventListener('click', event => openPlanToday(event.currentTarget));

View File

@ -383,6 +383,17 @@ async function warmOptionalFeature(cache, staleCacheNames, asset) {
await cache.add(asset);
}
async function cachedOptionalFeature(request) {
const cached = await caches.match(request);
if (cached) return cached;
const response = await fetch(request);
if (response.ok) {
const cache = await caches.open(CACHE);
await cache.put(request, response.clone());
}
return response;
}
self.addEventListener('activate', event => {
event.waitUntil((async () => {
const keys = await caches.keys();
@ -635,6 +646,6 @@ self.addEventListener('fetch', event => {
return;
}
if (url.origin === self.location.origin && OPTIONAL_FEATURES.includes(url.pathname)) {
event.respondWith(caches.match(request).then(cached => cached || fetch(request)));
event.respondWith(cachedOptionalFeature(request));
}
});

View File

@ -48,4 +48,5 @@ def test_dashboard_uses_reconnect_flush_after_live_identity_refresh():
assert '<script src="static/reconnect-outboxes.js"></script>' in index
assert "const reconnectOutboxes = createReconnectOutboxes({" in dashboard
assert "restoreIdentity: login => { activeFlushLogin = login; confirmedOwnerLogin = login; }" in dashboard
assert "window.addEventListener('online', reconnectOutboxes);" in dashboard
assert "window.addEventListener('online', reconnectAfterOnline);" in dashboard
assert "setTimeout(reconnectOutboxes, 500)" in dashboard

View File

@ -1108,6 +1108,25 @@ def test_offline_activation_migrates_cached_optional_feature_before_deleting_old
assert state["claimed"] is True
def test_successful_optional_feature_fetch_is_cached_for_offline_reopen():
result = run_worker_scenario(
"""
const asset = '/dashboard/feature-today-timer-test.js';
context.self.__testOptionalFeatures.push(asset);
const response = await dispatch('fetch', {
method: 'GET', mode: 'cors',
url: 'https://forge.example/dashboard/feature-today-timer-test.js',
});
process.stdout.write(JSON.stringify({ body: await response.text(), state }));
"""
)
assert result["body"] == "network"
assert result["state"]["puts"] == [
"https://forge.example/dashboard/feature-today-timer-test.js"
]
def test_activate_warms_optional_features_without_blocking_siblings_or_claim():
result = run_worker_scenario(
"""