frontend-patterns/research/experiments/feature-release/reload-host.js
tegwick f273a190f0 Test activation conflicts and draft-preserving application reload
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0cffe-206f-7323-89d3-b20ca4cf4bf9
2026-09-26 23:30:15 +02:00

44 lines
2.4 KiB
JavaScript

const input = document.getElementById('draft');
const status = document.getElementById('status');
const key = 'fep-review-draft';
const startup = JSON.parse(document.getElementById('startup').textContent);
window.observed = {startup, outcomes: [], evaluations: [], restored: false};
window.pendingUnknown = false;
window.failStorage = false;
let blocked = false;
const saved = sessionStorage.getItem(key);
if (saved) {
const record = JSON.parse(saved);
input.value = record.text;
if (record.schema !== startup.draftSchema) {
blocked = true; input.readOnly = true; status.textContent = 'Recovery required: draft schema mismatch';
} else {window.observed.restored = true; status.textContent = 'Draft restored';}
}
if (!saved) status.textContent = 'Ready';
window.feature = await import('reports');
document.getElementById('version').textContent = window.feature.version;
window.ready = true;
window.requestReload = async choice => {
if (choice === 'stay') {status.textContent = 'Update deferred'; return false;}
if (blocked) {status.textContent = 'Recovery required: draft schema mismatch'; return false;}
if (window.pendingUnknown) {status.textContent = 'Resolve unknown operation outcome first'; return false;}
const latest = await fetch('/activation').then(r => r.json());
// Recheck after asynchronous work; edits made while checking must not be replaced by an old snapshot.
if (window.pendingUnknown) {status.textContent = 'Resolve unknown operation outcome first'; return false;}
if (choice !== 'discard' && latest.draftSchema !== 1) {
status.textContent = 'Update deferred: incompatible draft schema'; return false;
}
try {
if (window.failStorage) throw new Error('injected storage refusal');
if (choice === 'discard') sessionStorage.removeItem(key);
else {
const record = {schema: 1, text: input.value, base: 'record-v1'};
sessionStorage.setItem(key, JSON.stringify(record));
if (sessionStorage.getItem(key) !== JSON.stringify(record)) throw new Error('write verification failed');
}
} catch {status.textContent = 'Update deferred: draft storage failed'; return false;}
location.reload();return true;
};
document.getElementById('stay').onclick = () => window.requestReload('stay');
document.getElementById('preserve').onclick = () => window.requestReload('preserve');
document.getElementById('discard').onclick = () => window.requestReload('discard');