Sync generated provider output

This commit is contained in:
github-actions[bot]
2026-09-01 21:10:03 +00:00
parent 6bc4f242c7
commit a70acd2823
48 changed files with 5136 additions and 704 deletions
@@ -64,6 +64,26 @@
};
}
function hasFrameworkHmrOwnership(el) {
for (let node = el; node; node = node.parentElement) {
let keys = [];
try { keys = Object.getOwnPropertyNames(node); } catch {}
if (keys.some((key) => (
key.startsWith('__reactFiber$')
|| key.startsWith('__reactProps$')
|| key.startsWith('__reactContainer$')
|| key === '_reactRootContainer'
|| key === '__vueParentComponent'
|| key === '__vue_app__'
|| key === '__vnode'
|| key === '__svelte_meta'
))) {
return true;
}
}
return false;
}
function id8() {
if (crypto?.randomUUID) return crypto.randomUUID().replace(/-/g, '').slice(0, 8);
return (Math.random().toString(16).slice(2) + Date.now().toString(16)).slice(0, 8);
@@ -128,6 +148,7 @@
desc,
rectIsUsableAnchor,
makeFrozenAnchor,
hasFrameworkHmrOwnership,
id8,
cssId,
liveUiRoot,
@@ -71,17 +71,38 @@
return checkpointRevision;
}
function readHandledIds() {
const raw = safeRead(handledKey);
if (!raw) return [];
try {
const parsed = JSON.parse(raw);
if (Array.isArray(parsed)) {
return parsed.filter(id => typeof id === 'string' && id);
}
if (typeof parsed === 'string' && parsed) return [parsed];
} catch { /* legacy values were stored as a plain session id */ }
return [raw];
}
function markHandled(id) {
if (!id) return;
safeWrite(handledKey, id);
const ids = readHandledIds().filter(existing => existing !== id);
ids.push(id);
safeWrite(handledKey, JSON.stringify(ids.slice(-8)));
}
function isHandled(id) {
return !!id && safeRead(handledKey) === id;
return !!id && readHandledIds().includes(id);
}
function clearHandled() {
safeRemove(handledKey);
function clearHandled(id) {
if (!id) {
safeRemove(handledKey);
return;
}
const remaining = readHandledIds().filter(existing => existing !== id);
if (remaining.length > 0) safeWrite(handledKey, JSON.stringify(remaining));
else safeRemove(handledKey);
}
function writeScrollY(y) {
+275 -40
View File
@@ -121,6 +121,10 @@
let hoveredElement = null;
let selectedElement = null;
let currentSessionId = null;
// Advances when the user begins configuring a fresh edit, before that edit
// has a server session id. Deferred recovery captures this revision so an
// older accept/discard can never reload over a replacement configuration.
let liveInteractionRevision = 0;
let expectedVariants = 0;
let arrivedVariants = 0;
let visibleVariant = 0;
@@ -188,6 +192,9 @@
// when the real accept result arrives or a new session starts.
let awaitingAcceptResult = null;
let variantObserver = null;
const discardedFrameworkWrapperWatchers = new Map();
const handledRuntimeWrapperWatchers = new Map();
const handledRuntimeWrapperReloadSessions = new Set();
let variantSelectionInFlight = false;
let variantSelectionPromise = null;
let recoveringEmptyCycling = false;
@@ -208,6 +215,7 @@
const SCROLL_ANCHOR_LOCK_ID = 'impeccable-scroll-anchor-lock';
const VARIANT_STATE_STYLE_ID = 'impeccable-variant-state';
const DISCARD_STATE_STYLE_ID = 'impeccable-discard-state';
const HANDLED_WRAPPER_RELOAD_KEY = PREFIX + '-handled-wrapper-reload';
// Dedicated key for scroll position - SEPARATE from LS_KEY so that
// saveSession's state updates don't clobber a carefully-captured scrollY.
@@ -270,6 +278,7 @@
desc,
rectIsUsableAnchor,
makeFrozenAnchor,
hasFrameworkHmrOwnership,
id8,
cssId,
liveUiRoot,
@@ -2034,6 +2043,16 @@
syncSteerQueueHint();
}
function beginNewLiveConfiguration() {
liveInteractionRevision += 1;
setLiveState('CONFIGURING');
}
function deferredRecoverySuperseded(sessionId, recoveryRevision) {
return liveInteractionRevision !== recoveryRevision
|| !!(currentSessionId && currentSessionId !== sessionId);
}
/** Element used to position the floating bar / shader during a session. */
function resolveBarAnchor() {
if (svelteComponentSession?.sessionId === currentSessionId && (state === 'GENERATING' || state === 'CYCLING')) {
@@ -5036,7 +5055,7 @@
&& el.parentElement
&& document.body.contains(el)
&& !own(el)
&& !el.closest?.('[data-impeccable-variants]');
&& !el.closest?.('[data-impeccable-variants],[data-impeccable-carbonize]');
}
function elementMatchesOriginalMarkup(liveEl, origContent) {
@@ -6608,19 +6627,78 @@
document.getElementById(VARIANT_STATE_STYLE_ID)?.remove();
}
function discardStateStyleId(sessionId) {
return DISCARD_STATE_STYLE_ID + '-' + sessionId;
}
function showOriginalDuringDiscard(sessionId) {
if (!sessionId) return;
let styleEl = document.getElementById(DISCARD_STATE_STYLE_ID);
let styleEl = document.getElementById(discardStateStyleId(sessionId));
if (!styleEl) {
styleEl = document.createElement('style');
styleEl.id = DISCARD_STATE_STYLE_ID;
styleEl.id = discardStateStyleId(sessionId);
(document.head || document.documentElement).appendChild(styleEl);
}
styleEl.dataset.impeccableDiscardSession = sessionId;
const wrapper = '[data-impeccable-variants="' + sessionId + '"]';
styleEl.textContent = wrapper + ' > [data-impeccable-variant]:not([data-impeccable-variant="original"]) { display:none !important; }\n'
+ wrapper + ' > [data-impeccable-variant="original"] { display:block !important; }';
}
function removeDiscardStateStylesheet(sessionId) {
if (!sessionId) return;
document.getElementById(discardStateStyleId(sessionId))?.remove();
}
function releaseDiscardedStaticWrapper(wrapper, sessionId) {
removeDiscardStateStylesheet(sessionId);
if (!wrapper) return;
const orig = wrapper.querySelector('[data-impeccable-variant="original"]');
const content = orig?.firstElementChild;
if (content && wrapper.parentElement) {
wrapper.parentElement.replaceChild(content, wrapper);
return;
}
wrapper.remove();
}
function watchForDiscardedFrameworkWrapperRemoval(sessionId) {
if (!sessionId || !document.body) return;
if (discardedFrameworkWrapperWatchers.has(sessionId)) return;
const selector = '[data-impeccable-variants="' + sessionId + '"]';
let observer = null;
let timer = null;
const stopWatching = function() {
observer?.disconnect();
if (timer) clearTimeout(timer);
discardedFrameworkWrapperWatchers.delete(sessionId);
};
const finishIfGone = function() {
if (document.querySelector(selector)) return false;
removeDiscardStateStylesheet(sessionId);
stopWatching();
return true;
};
if (finishIfGone()) return;
observer = new MutationObserver(finishIfGone);
observer.observe(document.body, { childList: true, subtree: true });
const resolveStillMounted = function() {
if (finishIfGone()) return;
const replacementActive = !!currentSessionId
|| (state !== 'IDLE' && state !== 'PICKING');
if (replacementActive) {
timer = setTimeout(resolveStillMounted, 12000);
discardedFrameworkWrapperWatchers.get(sessionId).timer = timer;
return;
}
removeDiscardStateStylesheet(sessionId);
stopWatching();
location.reload();
};
timer = setTimeout(resolveStillMounted, 12000);
discardedFrameworkWrapperWatchers.set(sessionId, { observer, timer });
}
function resolveScrollLockAnchorTop() {
const anchor = resolveBarAnchor();
if (!anchor?.isConnected) return null;
@@ -7335,7 +7413,7 @@
hideInsertLine();
configureKind = 'insert';
selectedElement = placeholder;
setLiveState('CONFIGURING');
beginNewLiveConfiguration();
hideHighlight();
clearAnnotations();
showAnnotOverlay(placeholder);
@@ -7353,7 +7431,7 @@
e.preventDefault();
e.stopPropagation();
selectedElement = hoveredElement;
setLiveState('CONFIGURING');
beginNewLiveConfiguration();
showHighlight(selectedElement);
clearAnnotations();
showAnnotOverlay(selectedElement);
@@ -7530,7 +7608,7 @@
} else if (e.key === 'Enter') {
e.preventDefault();
selectedElement = hoveredElement;
setLiveState('CONFIGURING');
beginNewLiveConfiguration();
showHighlight(selectedElement);
clearAnnotations();
showAnnotOverlay(selectedElement);
@@ -8535,6 +8613,7 @@ void main() {
}
function scheduleAcceptCleanup(accepted) {
const recoveryRevision = liveInteractionRevision;
queueMicrotask(function() {
if (pendingAcceptedSession?.id !== accepted?.id) return;
// Svelte previews live in an adapter-owned mount rather than in source
@@ -8551,8 +8630,10 @@ void main() {
// races. Static servers still need a fallback, but it must not keep Live
// in SAVING or block the user's next pick.
if (!accepted?.isSvelteComponent) {
watchForHandledRuntimeWrapper(accepted?.id, recoveryRevision);
setTimeout(function() {
if (!acceptedDomAlreadyClean(accepted)) ensureAcceptedDomClean(accepted);
if (deferredRecoverySuperseded(accepted?.id, recoveryRevision)) return;
if (!acceptedDomAlreadyClean(accepted)) ensureAcceptedDomClean(accepted, recoveryRevision);
}, 1200);
}
}
@@ -8585,13 +8666,27 @@ void main() {
&& matches.every((el) => !el.closest('[data-impeccable-variants],[data-impeccable-variant],[data-impeccable-carbonize]'));
}
function ensureAcceptedDomClean(pending) {
function ensureAcceptedDomClean(pending, recoveryRevision) {
// Background cleanup for an accepted session must never mutate or reload
// a newer comparison the user has already started.
if (deferredRecoverySuperseded(pending?.id, recoveryRevision)) return;
if (acceptedDomAlreadyClean(pending)) return;
const sessionId = pending?.id;
const variantId = pending?.variant;
const wrappers = findAcceptedRuntimeWrappers(sessionId);
if (hasFrameworkHmrOwnership(wrappers[0] || pending?.parentElement)) {
// Vite can coalesce rapid scaffold/carbonize writes and leave the last
// framework-owned preview tree mounted even though source is clean. Give
// HMR another grace window, then reload from clean source rather than
// violating reconciler ownership with a manual DOM mutation.
setTimeout(function() {
if (deferredRecoverySuperseded(pending?.id, recoveryRevision)) return;
if (!acceptedDomAlreadyClean(pending)) location.reload();
}, 2000);
return;
}
if (wrappers.length === 0) {
restoreAcceptedDomFromSnapshot(pending);
restoreAcceptedDomFromSnapshot(pending, recoveryRevision);
return;
}
for (const wrapper of wrappers) {
@@ -8608,7 +8703,7 @@ void main() {
}
wrapper.remove();
}
if (!acceptedDomAlreadyClean(pending)) restoreAcceptedDomFromSnapshot(pending);
if (!acceptedDomAlreadyClean(pending)) restoreAcceptedDomFromSnapshot(pending, recoveryRevision);
}
function findAcceptedRuntimeWrappers(sessionId) {
@@ -8619,17 +8714,17 @@ void main() {
])];
}
function restoreAcceptedDomFromSnapshot(pending) {
function restoreAcceptedDomFromSnapshot(pending, recoveryRevision) {
if (acceptedDomAlreadyClean(pending)) return;
if (!pending?.acceptedHtml) {
reloadAfterMissingAcceptedDom(pending);
reloadAfterMissingAcceptedDom(pending, recoveryRevision);
return;
}
const parent = pending.parentElement?.isConnected
? pending.parentElement
: (pending.parentSelector ? document.querySelector(pending.parentSelector) : null);
if (!parent) {
reloadAfterMissingAcceptedDom(pending);
reloadAfterMissingAcceptedDom(pending, recoveryRevision);
return;
}
const template = document.createElement('template');
@@ -8638,10 +8733,11 @@ void main() {
? pending.nextSibling
: null;
parent.insertBefore(template.content, anchor);
if (!acceptedDomAlreadyClean(pending)) reloadAfterMissingAcceptedDom(pending);
if (!acceptedDomAlreadyClean(pending)) reloadAfterMissingAcceptedDom(pending, recoveryRevision);
}
function reloadAfterMissingAcceptedDom(pending) {
function reloadAfterMissingAcceptedDom(pending, recoveryRevision) {
if (deferredRecoverySuperseded(pending?.id, recoveryRevision)) return;
if (acceptedDomAlreadyClean(pending)) return;
if (pending?.id && document.querySelector('[data-impeccable-variants="' + pending.id + '"]')) return;
location.reload();
@@ -8991,14 +9087,15 @@ void main() {
return sessionState.isHandled(id);
}
function clearHandled() {
sessionState.clearHandled();
function clearHandled(sessionId) {
sessionState.clearHandled(sessionId);
}
function cleanup(options) {
const restoreOriginal = options?.restoreOriginal === true;
const instantChrome = options?.instantChrome === true;
const cleanupSessionId = currentSessionId;
const cleanupRevision = liveInteractionRevision;
clearMountErrorCard();
lastReportedMountFailure = null;
if (svelteComponentSession?.sessionId === cleanupSessionId) {
@@ -9016,19 +9113,41 @@ void main() {
else wrapper.style.display = 'none';
}
setTimeout(function() {
document.getElementById(DISCARD_STATE_STYLE_ID)?.remove();
if (!cleanupSessionId) return;
const lateWrapper = document.querySelector('[data-impeccable-variants="' + cleanupSessionId + '"]');
if (!lateWrapper) return;
const orig = lateWrapper.querySelector('[data-impeccable-variant="original"]');
if (orig) {
const content = orig.firstElementChild;
if (content) {
lateWrapper.parentElement.replaceChild(content, lateWrapper);
return;
}
const recoverySuperseded = deferredRecoverySuperseded(cleanupSessionId, cleanupRevision);
if (!cleanupSessionId) {
removeDiscardStateStylesheet();
return;
}
lateWrapper.remove();
const lateWrapper = document.querySelector('[data-impeccable-variants="' + cleanupSessionId + '"]');
if (!lateWrapper) {
removeDiscardStateStylesheet(cleanupSessionId);
return;
}
if (recoverySuperseded) {
if (hasFrameworkHmrOwnership(lateWrapper)) {
watchForDiscardedFrameworkWrapperRemoval(cleanupSessionId);
} else {
releaseDiscardedStaticWrapper(lateWrapper, cleanupSessionId);
}
return;
}
if (hasFrameworkHmrOwnership(lateWrapper)) {
// As on accept, never restructure framework-owned DOM. If HMR missed
// the final source rewrite, reload once after a grace window so the
// discarded source becomes authoritative without a reconciler race.
setTimeout(function() {
const staleWrapper = document.querySelector('[data-impeccable-variants="' + cleanupSessionId + '"]');
if (deferredRecoverySuperseded(cleanupSessionId, cleanupRevision)) {
if (!staleWrapper) removeDiscardStateStylesheet(cleanupSessionId);
else watchForDiscardedFrameworkWrapperRemoval(cleanupSessionId);
return;
}
removeDiscardStateStylesheet(cleanupSessionId);
if (staleWrapper) location.reload();
}, 2000);
return;
}
releaseDiscardedStaticWrapper(lateWrapper, cleanupSessionId);
}, 2000);
}
hideBar(instantChrome);
@@ -9111,12 +9230,122 @@ void main() {
// Resume an active variant session after HMR/page reload.
// If a [data-impeccable-variants] wrapper exists in the DOM, the agent wrote
// variants before HMR fired. Pick up where we left off.
function resumeSession() {
function handledWrapperReloadKey(sessionId) {
return HANDLED_WRAPPER_RELOAD_KEY + ':' + sessionId;
}
function clearHandledWrapperReloadStamp(sessionId) {
try {
if (sessionId) {
sessionStorage.removeItem(handledWrapperReloadKey(sessionId));
const legacy = sessionStorage.getItem(HANDLED_WRAPPER_RELOAD_KEY) || '';
if (legacy === sessionId || legacy.startsWith(sessionId + ':')) {
sessionStorage.removeItem(HANDLED_WRAPPER_RELOAD_KEY);
}
return;
}
sessionStorage.removeItem(HANDLED_WRAPPER_RELOAD_KEY);
for (let i = sessionStorage.length - 1; i >= 0; i--) {
const key = sessionStorage.key(i);
if (key?.startsWith(HANDLED_WRAPPER_RELOAD_KEY + ':')) sessionStorage.removeItem(key);
}
} catch {}
}
function scheduleHandledRuntimeWrapperReload(wrapper, recoveryRevision = liveInteractionRevision) {
const sessionId = wrapper?.dataset?.impeccableVariants
|| wrapper?.dataset?.impeccableCarbonize;
if (!sessionId || !isSessionHandled(sessionId)) return false;
if (deferredRecoverySuperseded(sessionId, recoveryRevision)) return true;
if (handledRuntimeWrapperReloadSessions.has(sessionId)) return true;
let reloadAttempts = 0;
try {
reloadAttempts = Number(sessionStorage.getItem(handledWrapperReloadKey(sessionId))) || 0;
if (reloadAttempts >= 2) return true;
sessionStorage.setItem(handledWrapperReloadKey(sessionId), String(reloadAttempts + 1));
} catch {}
handledRuntimeWrapperReloadSessions.add(sessionId);
// A framework refresh can replace the variants tree with an intermediate
// carbonize tree and reload the page, cancelling the original accept timer.
// Let the file-side cleanup settle, then reload once from authoritative
// source. The sessionStorage stamp prevents a stale dev-server response
// from turning this recovery into a reload loop.
setTimeout(function() {
if (deferredRecoverySuperseded(sessionId, recoveryRevision)) {
clearHandledWrapperReloadStamp(sessionId);
handledRuntimeWrapperReloadSessions.delete(sessionId);
return;
}
const staleWrapper = document.querySelector(
'[data-impeccable-variants="' + sessionId + '"],'
+ '[data-impeccable-carbonize="' + sessionId + '"]',
);
if (staleWrapper) location.reload();
else {
clearHandledWrapperReloadStamp(sessionId);
handledRuntimeWrapperReloadSessions.delete(sessionId);
}
}, 3000);
return true;
}
function watchForHandledRuntimeWrapper(sessionId, recoveryRevision = liveInteractionRevision) {
if (!sessionId || !document.body) return;
const existing = handledRuntimeWrapperWatchers.get(sessionId);
existing?.observer.disconnect();
if (existing?.timer) clearTimeout(existing.timer);
const findHandledWrapper = function() {
const wrapper = document.querySelector(
'[data-impeccable-variants="' + sessionId + '"],'
+ '[data-impeccable-carbonize="' + sessionId + '"]',
);
if (wrapper) scheduleHandledRuntimeWrapperReload(wrapper, recoveryRevision);
};
// Vite can briefly render the clean accepted tree, then apply a delayed
// carbonize refresh after the one-shot accept fallback has already passed.
// Keep a bounded scout alive through that refresh window so a late stale
// framework tree still reloads from the now-authoritative source.
const observer = new MutationObserver(findHandledWrapper);
observer.observe(document.body, { childList: true, subtree: true });
const timer = setTimeout(function() {
if (handledRuntimeWrapperWatchers.get(sessionId)?.observer !== observer) return;
observer.disconnect();
handledRuntimeWrapperWatchers.delete(sessionId);
}, 12000);
handledRuntimeWrapperWatchers.set(sessionId, { observer, timer });
findHandledWrapper();
}
function restoreSessionSupersedingHandledWrapper(runtimeWrapper) {
const handledSessionId = runtimeWrapper?.dataset?.impeccableVariants
|| runtimeWrapper?.dataset?.impeccableCarbonize;
if (!handledSessionId || !isSessionHandled(handledSessionId)) return false;
// Accept releases the picker before carbonize finishes, so a replacement
// generation can already be durable while the prior handled wrapper is
// still mounted. Restore that newer session before the stale-wrapper
// recovery path gets a chance to reload or consume its retry budget.
const saved = loadSession();
if (!saved?.id || saved.id === handledSessionId || isSessionHandled(saved.id)) return false;
if (currentSessionId === saved.id) return true;
return restoreSessionWithoutWrapper('browser_resumed_over_handled_wrapper');
}
function resumeSession(recoveryRevision = liveInteractionRevision) {
const wrapper = document.querySelector('[data-impeccable-variants]');
const runtimeWrapper = wrapper || document.querySelector('[data-impeccable-carbonize]');
if (restoreSessionSupersedingHandledWrapper(runtimeWrapper)) return true;
if (scheduleHandledRuntimeWrapperReload(runtimeWrapper, recoveryRevision)) return false;
if (!wrapper) {
if (restoreSessionWithoutWrapper('browser_resumed_without_wrapper')) return true;
clearSession();
clearHandled();
// Keep the bounded handled-id history durable. A framework can hydrate a
// completed wrapper well after initialization, and a later reload must
// still recognize that wrapper as recovery work rather than resume it.
return false;
}
@@ -9136,7 +9365,7 @@ void main() {
wrapper.remove();
if (restoreSessionWithoutWrapper('browser_resumed_svelte_orphan_wrapper')) return true;
clearSession();
clearHandled();
clearHandled(sessionId);
return false;
}
@@ -12520,22 +12749,28 @@ void main() {
connectSSE();
// Check for an active session to resume (variant wrapper already in DOM after HMR)
if (!resumeSession()) {
const resumed = resumeSession();
if (!resumed) {
console.log('[impeccable] Live variant mode ready. Hover over elements to pick one.');
// SvelteKit (and any framework that hydrates after HTML parse) may add
// the variant wrapper AFTER init runs. Watch for it and retry resume
// once it appears. Disconnect on first hit.
} else {
console.log('[impeccable] Resumed active variant session ' + currentSessionId + ' (' + arrivedVariants + '/' + expectedVariants + ' variants).');
}
// SvelteKit, React, and other frameworks may restore a durable session
// before hydration adds its variant wrapper. Keep a deferred-wrapper scout
// whenever init did not see a runtime wrapper, even if local/server state
// was already restored successfully. Disconnect on the first wrapper hit.
if (!resumed || !document.querySelector('[data-impeccable-variants],[data-impeccable-carbonize]')) {
const deferredResumeRevision = liveInteractionRevision;
const scout = new MutationObserver(() => {
const wrapper = document.querySelector('[data-impeccable-variants]');
const wrapper = document.querySelector('[data-impeccable-variants],[data-impeccable-carbonize]');
if (!wrapper) return;
scout.disconnect();
if (resumeSession()) {
if (resumeSession(deferredResumeRevision)) {
console.log('[impeccable] Resumed deferred session ' + currentSessionId + ' (post-hydration).');
}
});
scout.observe(document.body, { childList: true, subtree: true });
} else {
console.log('[impeccable] Resumed active variant session ' + currentSessionId + ' (' + arrivedVariants + '/' + expectedVariants + ' variants).');
}
if (state === 'IDLE' && (pickActive || insertActive)) setLiveState('PICKING');