payload-live-preview 2.2.2 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -30
- package/dist/adapters/astro/PreviewBoundary.astro +17 -4
- package/dist/adapters/astro/RichText.astro +13 -2
- package/dist/adapters/astro/index.d.ts +7 -7
- package/dist/adapters/astro/index.js +1 -1
- package/dist/adapters/astro/index.js.map +1 -1
- package/dist/adapters/astro/middleware-entry.d.ts +3 -3
- package/dist/adapters/astro/middleware-entry.js +1 -1
- package/dist/adapters/astro/middleware-entry.js.map +1 -1
- package/dist/adapters/nextjs/index.d.ts +2 -2
- package/dist/adapters/nextjs/index.js +1 -1
- package/dist/adapters/nextjs/index.js.map +1 -1
- package/dist/adapters/nuxt/index.d.ts +4 -4
- package/dist/adapters/nuxt/index.js +1 -1
- package/dist/adapters/nuxt/index.js.map +1 -1
- package/dist/adapters/nuxt/module.d.ts +1 -1
- package/dist/adapters/react/index.d.ts +2 -2
- package/dist/adapters/react/index.js +1 -1
- package/dist/adapters/react/index.js.map +1 -1
- package/dist/adapters/sveltekit/index.d.ts +5 -5
- package/dist/adapters/sveltekit/index.js +1 -1
- package/dist/adapters/sveltekit/index.js.map +1 -1
- package/dist/adapters/vue/index.d.ts +2 -2
- package/dist/adapters/vue/index.js +1 -1
- package/dist/adapters/vue/index.js.map +1 -1
- package/dist/client.cjs +1 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +15 -3
- package/dist/client.d.ts +15 -3
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/codegen-astro.js +1 -1
- package/dist/codegen-astro.js.map +1 -1
- package/dist/codegen-cli.js +1 -1
- package/dist/codegen-cli.js.map +1 -1
- package/dist/codegen.cjs +1 -1
- package/dist/codegen.cjs.map +1 -1
- package/dist/codegen.js +1 -1
- package/dist/codegen.js.map +1 -1
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +139 -4
- package/dist/core.d.ts +139 -4
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/doctor-cli.d.ts +1 -1
- package/dist/doctor-cli.js +1 -1
- package/dist/doctor-cli.js.map +1 -1
- package/dist/doctor.d.ts +2 -2
- package/dist/doctor.js +1 -1
- package/dist/doctor.js.map +1 -1
- package/dist/{document-session-Bkd181PV.d.ts → document-session-BuYuO3ae.d.ts} +27 -2
- package/dist/{fragment-endpoint-CLRpNQ3n.d.ts → fragment-endpoint-CQE_7MKi.d.ts} +1 -1
- package/dist/fragment.cjs +1 -1
- package/dist/fragment.cjs.map +1 -1
- package/dist/fragment.d.cts +6 -2
- package/dist/fragment.d.ts +6 -2
- package/dist/fragment.js +1 -1
- package/dist/fragment.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +73 -12
- package/dist/index.d.ts +73 -12
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lean.cjs +1 -1
- package/dist/lean.cjs.map +1 -1
- package/dist/lean.js +1 -1
- package/dist/lean.js.map +1 -1
- package/dist/lexical.cjs +1 -1
- package/dist/lexical.cjs.map +1 -1
- package/dist/lexical.d.cts +16 -4
- package/dist/lexical.d.ts +16 -4
- package/dist/lexical.js +1 -1
- package/dist/lexical.js.map +1 -1
- package/dist/{locals-zz2gi9dj.d.ts → locals-CyzDKfKU.d.ts} +7 -1
- package/dist/{middleware-CI-UTf6R.d.ts → middleware-Dnt6u4nF.d.ts} +2 -2
- package/dist/{options-CnYybG51.d.ts → options-DTzhFVJ4.d.ts} +13 -1
- package/dist/plugin.cjs +1 -1
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +15 -9
- package/dist/plugin.d.ts +15 -9
- package/dist/plugin.js +1 -1
- package/dist/plugin.js.map +1 -1
- package/dist/plugins.cjs +1 -1
- package/dist/plugins.cjs.map +1 -1
- package/dist/plugins.d.cts +8 -2
- package/dist/plugins.d.ts +8 -2
- package/dist/plugins.js +1 -1
- package/dist/plugins.js.map +1 -1
- package/dist/{probe-D-IHg9dF.d.ts → probe-afwdYebU.d.ts} +6 -2
- package/dist/server.cjs +1 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +19 -1
- package/dist/server.d.ts +19 -1
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/structural.d.cts +2 -0
- package/dist/structural.d.ts +2 -0
- package/package.json +2 -1
package/dist/client.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.cjs","names":["detectInitialLocale","document","lang","documentElement","getAttribute","length","readHtmlLang","navigator","language","readNavigatorLanguage","ELEMENT_ID","documentLeases","WeakMap","clearLeaseMessage","lease","timer","clearTimeout","messageNode","remove","A11yAnnouncer","german","constructor","locale","targetDocument","activeDocument","documentLocale","this","test","isGerman","mount","body","get","element","owned","refs","set","acquireDocumentLease","leased","isConnected","ownerDocument","getElementById","createElement","id","setAttribute","style","cssText","appendChild","announceConnected","say","announceDisconnected","announceUpdate","count","String","announcePartial","detach","delete","message","parentNode","createTextNode","hasChildNodes","data","previousSibling","setTimeout","visit","state","nodes","Error","enter","value","depth","active","has","add","parseFieldSchema","raw","parseFields","WeakSet","Array","isArray","out","entry","parsed","parseFieldEntry","push","record","name","type","fields","blocks","slug","Object","hasOwn","Reflect","includes","parseBlockSchema","result","relationTo","targets","target","optionalFieldOk","check","optionalTypeOk","isPlainObject","prototype","getPrototypeOf","NULL_AS_ABSENT_FIELDS","CAPABILITY_DECLARATIONS","basic","since","observed","PROTOCOL_CAPABILITIES","keys","negotiateProtocol","theirs","sanitisedTheirs","Number","isFinite","Math","floor","effectiveTheirs","negotiated","min","seen","Set","capabilities","capability","ours","observeThenableResult","then","Promise","resolve","catch","sameRevision","a","b","generation","revision","MessageBus","matcher","handlers","boundListener","attachedTarget","queueHead","queueTail","lastAccepted","replayedGeneration","latestAcceptedAttempt","attach","window","committed","listener","event","receive","origin","reportInvalid","resetQueue","addEventListener","error","removeEventListener","advanceGeneration","replayLastAccepted","accepted","handler","onReplay","matchesOrigin","invokeHandler","structuredClone","forgetLastAccepted","sendReady","origins","payload","ready","protocolVersion","postMessage","matchesSource","v","x","isLivePreviewMessage","dispatchUpdate","normalized","field","deleteProperty","fieldSchemaJSON","normalizeLivePreviewMessage","isDocumentEventMessage","onDocumentEvent","focusFieldOf","onFocusField","hasUpdateData","isCurrentGeneration","messageRevision","validator","validateToken","commitUpdate","pending","verdict","next","enqueue","previewToken","settleValidation","approved","drainQueue","dequeue","onUpdate","attempt","snapshot","withoutToken","snapshotForReplay","reason","onInvalid","sourcePolicy","source","parent","opener","args","expected","isolateDiagnostic","diagnostic","noopDiagnostic","safeConsoleError","console","safeConsoleWarn","warn","safeConsoleDebug","debug","HOW_TO_GET_IT","reported","reportOmittedFeature","feature","createA11y","options","__LEAN_BUILD__","enableA11y","refuseA11y","root","nodeType","isDocumentRoot","a11yLocale","buildA11y","defaultSendReady","Window","definedOnly","key","entries","STRUCTURAL_TYPES","walk","schemas","basePath","namedTabs","schema","path","block","lookupSchema","index","fieldPath","wildcardPath","replace","getId","item","getBlockType","blockType","diffArray","prev","every","patches","prevIndexById","Map","i","consumedFromPrev","to","kind","from","prevItem","shallowEqual","oldValue","diffById","diffByPosition","is","aRec","bRec","aKeys","bKeys","MAP","text","textarea","richText","email","number","checkbox","date","select","radio","array","group","tabs","row","collapsible","relationship","upload","point","json","code","ui","SAFE_PROTOCOLS","RELATIVE_PATH","PROTOCOL_RELATIVE","PARSER_IGNORED","SCHEME_GAPS","SCHEME","isSafeUrl","url","trimmed","trim","startsWith","URL","protocol","scheme","exec","toLowerCase","spellsUnsafeScheme","isExternalHttpUrl","BLOCKED_ATTRIBUTES","URL_ATTRIBUTES","isWritableAttribute","valueIdentity","JSON","stringify","resolveUnfaithfulPatchMode","onUnfaithfulPatch","onUnboundChange","reportUnfaithfulPatch","deps","mode","last","reportedUnfaithful","identity","now","Date","repeated","at","display","shortfall","activeUpdate","fieldName","unfaithfulCount","unfaithfulFields","log","unfaithfulPatches","reportUnboundChange","FORMATTING_RENDERERS","shownValue","tagName","textContent","excerpt","slice","noWriteCallbacks","markNoWriteCallback","callback","FieldChangeTracker","previous","lastFields","priorFields","keepValues","previousFields","isBaseline","diff","dependencies","isCurrent","alwaysCurrent","baseline","changed","invalidated","dependencyEntries","dependents","dependent","reset","BLOCKED_KEYS","resolveFieldValue","preferLocale","localized","readOwn","direct","current","resolved","segment","split","object","hasOwnProperty","call","bindingValue","fallbackLocale","bindingIdentity","own","siblings","hrefField","srcField","altField","combined","format","sibling","FRAGMENT_ATTRIBUTE","FRAGMENT_KEY_ATTRIBUTE","enclosingFragment","closest","planBoundaries","strategy","boundaries","ownerKeys","covered","covers","fragmentBoundary","resolveStrategy","explicit","collectionOwnerKey","documentId","nonEmpty","isBindingInScope","owner","readDocumentId","isContainer","shapeOf","child","populates","samePopulation","before","after","sameValue","pathChanged","uncoveredChangedPaths","coverage","uncovered","visits","reachesBelow","childKeys","SYSTEM_FIELD_NAMES","createPathCoverage","cache","rendering","inScope","names","bindings","some","binding","rendered","filter","declaration","boundNames","coverPaths","anyBelow","candidates","prefix","candidate","cover","namePathCoverage","flatMap","paths","stripLocaleSuffix","suffix","endsWith","createFieldReach","localised","whole","below","base","localisedBindingNames","declaredSubfields","unboundChangedFields","touched","subfields","reach","unbound","SELF_SUFFICIENT_TYPES","SELF_SUFFICIENT_NODES","NO_DEPENDENCIES","MergeNeed","rawChanges","resolvedLocale","trailing","openUntil","requestAttempt","decide","transaction","rawData","emitter","islands","listenerCount","values","rendersAReference","isPath","strategies","fragment","querySelector","readsPopulatedValues","fieldType","explicitFieldType","looksLikeLexicalRoot","holdsReference","rendersRichTextByShape","forceRender","merge","localeChanged","verdictFor","schemaIndex","request","merger","windowMs","dropQueued","leading","status","settle","promise","createPending","flush","recordMerged","doc","resetRawChanges","destroy","isScalar","boundName","hasBindingBelow","namesAReference","node","pop","children","linkType","ProtocolTracker","negotiation","observe","fresh","join","applyVersion","remoteVersion","namesAnotherDocument","previewedSlug","globalSlug","collectionSlug","entitySlug","previewedId","owesForceRender","completed","RelationshipTracker","lastIdentity","inspect","externallyUpdatedRelationship","updatedAt","edit","commit","inspection","isNew","prefersReducedMotion","win","matchMedia","matches","FieldRevealer","lastField","reveal","rect","getBoundingClientRect","vertically","bottom","top","innerHeight","horizontally","right","left","innerWidth","isInViewport","scrollIntoView","behavior","revealElement","revealBinding","revealer","defaultView","RevealLedger","note","slot","revealIdentities","revealTarget","IGNORED","RevisionDisplayLedger","host","outstanding","report","failed","ended","begin","view","shortfalls","deferred","awaiting","queued","publish","end","requestSettle","handIsland","confirmed","queueMicrotask","awaitingIslands","thrownFragment","boundary","RuntimeState","started","suspended","deferredStart","hydration","updateCount","supersededCount","completedCount","skippedUnchangedCount","lastFlush","absentFields","warnedOrphanFields","warnedStrategy","warnedUnattributableMessage","warnedVisibilityGate","warnedFragmentFallback","warnedIslandStart","warnedEscalationUnavailable","warnedProtocolShape","checkedServerFormat","escalatedCount","autoBindSearchMs","autoBindGuesses","warnedForeignSource","lastAppliedIdentity","navigationReplayPending","navigationBindingReplay","revealLedger","fragmentStats","superseded","routeStats","refreshes","partial","refused","loopStopped","fragmentControllers","routeController","routeRetry","routeRefreshOwed","routeAwaitsSave","fragmentsOwed","readyTimers","changes","merges","relationships","isRunning","complete","countsAsUpdate","forgetOwedWork","clear","supersedeStrategies","controller","unsettled","abort","abortStrategies","route","BindingWriter","instanceContext","renderRichText","sanitizerPolicy","serverURL","reportUnfaithful","writing","apply","update","schemaEntry","renderer","schemaType","mapped","payloadTypeToRenderer","resolveFieldType","resolveRenderer","fail","emitElementUpdate","src","context","allFields","hidesWhenEmpty","toggleAttribute","isEmptyLexicalRoot","isEmptyFieldValue","targetAttribute","attribute","removeAttribute","stringValue","applyAttributeBinding","shown","watchServerFormatting","outcome","render","invokeRenderer","rendererUsesNoWriteOutcome","reportServerFormatting","emitWhile","previousValue","nextValue","receivedAt","applied","cause","parseDependencyList","mergeDependencyMaps","maps","merged","map","bucket","dependencyMapFromBinding","dependsOn","ISLAND_ATTRIBUTE","ISLAND_SELECTOR","OWNED_ATTRIBUTE","isMorphBoundary","hasAttribute","isIslandBoundary","editable","islandAllowsPatching","island","isIslandRoot","isAwaitingIslandHydration","ISLAND_IDENTITY","renderedSlots","unmountedIslands","isAstroIsland","slotMarkup","markup","querySelectorAll","parentElement","innerHTML","retainIslandBoundary","live","slots","customElements","observedAttributes","observesProps","props","astroIslandsIn","islandStartBlocker","directive","astro","FIELD_ATTRIBUTE","TYPE_ATTRIBUTE","TARGET_ATTRIBUTE_ATTRIBUTE","HREF_ATTRIBUTE","SRC_ATTRIBUTE","ALT_ATTRIBUTE","ARRAY_TEMPLATE_ATTRIBUTE","ARRAY_SEPARATOR_ATTRIBUTE","LOCALE_ATTRIBUTE","FORMAT_ATTRIBUTE","RICH_TEXT_ATTRIBUTE","HTML_ATTRIBUTE","ARRAY_ATTRIBUTE","STRUCTURAL_ATTRIBUTE","OWNER_ATTRIBUTE","DEPENDS_ATTRIBUTE","STRATEGY_ATTRIBUTE","BOUNDARY_ATTRIBUTE","GUESSED_ATTRIBUTE","COVERS_ATTRIBUTE","BINDING_ATTRIBUTES","FIELD_SELECTOR","OWNER_SELECTOR","NAVIGATION_REPLAY_SELECTOR","resolveBindingOwner","CUSTOM_RENDERER_KEY","VALID_FIELD_TYPES","isRendererKey","hasSameBindingIdentity","strategyKind","ElementCache","entriesByField","entryByElement","islandRoots","ownersByIsland","navigationRoots","coverDeclarations","renderedDeclarations","alwaysTrue","dependencyMap","islandOwners","navigationReplayRoots","buildFromRoot","t0","performance","elementCount","collectIslands","renderingStrategy","fieldCount","size","durationMs","resolveBinding","replaceEntry","removeEntry","append","getByElement","indexOf","splice","arrayTemplate","arraySeparator","guessed","inputType","MAX_NODES","MAX_BODY","FORBIDDEN","hasControl","charCodeAt","maximum","encodeURIComponent","put","defineProperty","writable","configurable","enumerable","stripTrailingSlashes","copyLegacyData","characters","copy","planLegacyPopulation","apiRoute","isSafeInteger","groups","unique","tick","level","relation","collection","selected","scope","fieldRelation","hasMany","allowed","selectedCollection","rich","find","requests","username","password","search","hash","part","identities","first","comma","chunk","proposed","query","URLSearchParams","limit","ids","async","populationBody","response","signal","reader","cancelled","finished","obsolete","Symbol","interrupt","interrupted","aborted","cancel","once","bind","race","getReader","activeReader","chunks","bytes","read","done","byteLength","Uint8Array","position","parse","TextDecoder","decode","releaseLock","fillLegacyPopulation","safe","docs","found","isPathSegment","maxLength","character","codePoint","codePointAt","hasControlCharacter","isSafeSlug","isSafeId","DataMerger","fetchFn","inflight","destroyDepth","withoutTrailingSlashes","canMerge","endpointOf","legacy","plan","fetch","AbortController","population","method","credentials","redirect","ok","endpoint","flattenLocales","headers","wrongIdentity","VERSION","PAYLOAD_2","fieldTyping","populatesRelationships","documentEvents","PAYLOAD_3","UNKNOWN","ASTRO_SSR_ATTRIBUTE","WATCHED_ANYWHERE","TRACKED_SELECTOR","ObserverManager","callbacks","debounceMs","rootMargin","visible","mutation","intersection","debounceTimer","mutationDebounceMs","intersectionRootMargin","start","previousGeneration","stop","MutationObserver","mutations","handleMutations","IntersectionObserver","handleIntersection","threshold","childList","subtree","attributes","attributeFilter","disconnect","observeElement","unobserveElement","unobserve","markVisible","isVisible","hydratedAstroIsland","onIslandHydrated","m","attributeName","addedNodes","containsTrackedElement","removedNodes","hasStructuralImpact","onStructuralChange","isIntersecting","onVisibilityChange","LifetimeScope","closed","release","run","close","reverse","BINDING_SELECTOR","signalSlot","w","armed","commits","onCommit","waiters","armReactCommitSignal","hook","__REACT_DEVTOOLS_GLOBAL_HOOK__","renderers","supportsFiber","inject","internals","installedHook","onCommitFiberRoot","rendererId","rest","waiter","forget","awaitSettled","onSettled","capMs","VUE_APP_PROPERTY","mountedApp","armVueMountSignal","proto","Element","getOwnPropertyDescriptor","app","nuxt","$nuxt","isHydrating","settleOnceHydrated","startAfterParse","startNow","WAITS","later","startHydrated","defer","hydrated","react","_root","HYDRATION_WAIT_CAP_MS","judge","container","ownsBindings","containerInfo","fiber","memoizedState","tag","dehydrated","hasDehydratedBoundary","ownsHydratedBindings","whenReactCommitted","vue","mountedAround","sveltekit","page","mounted","observer","AWAITED","readDocumentBody","HeartbeatTimer","timeoutMs","onTimeout","handle","lastKick","kick","arm","resume","elapsed","max","remaining","delay","lastKickAt","ConnectionState","markConnected","transition","markDisconnected","BOOLEAN_WORDS","NUMERIC","ENUM_TOKEN","LOCALE_CODE","SKIPPED_TAGS","isBindableValue","minLength","isRecord","bindableValues","claim","media","rawName","childValue","isBoundary","namespaceURI","soleText","firstChild","nextSibling","isCandidateAttribute","hits","byElement","elements","byField","firstElementChild","nextElementSibling","textClaim","getAttributeNames","shape","stamps","href","matched","alt","searchUnique","searchRoot","rollback","observers","written","cacheTouched","adopt","when","adopted","abandon","ownerKeysForUpdate","scopeBindingsByOwner","collectionKey","messageOwnerKeys","NavigationReplay","awaitingHydration","delivered","confirmations","reapplyBindings","currentTransaction","renderData","schedule","reapplyIslands","hydrationCompleted","replay","dispatchIslands","displayed","confirmation","dispatchSnapshotToIslands","hasLateRouteBinding","fieldsForElements","unrunFragmentPlan","onlyElements","fragmentBoundariesRun","contains","held","detail","dispatched","dispatchEvent","CustomEvent","bubbles","dispatchIslandUpdate","isAddressable","warned","isBindableScalar","isJoinResult","SLOT","for","trustedHtml","html","policy","policies","realm","globalThis","existing","created","shared","override","auto","api","trustedTypes","createPolicy","factory","createHTML","input","resolvePolicy","STATE_ATTRIBUTES","keyOf","keyAttributes","morphElement","sameKind","liveBoundary","renderedBoundary","retainBoundary","focus","captureFocus","syncAttributes","retainChildrenOf","liveKeyed","keyed","duplicate","onDuplicateKey","indexKeyed","keyedElements","liveUnkeyed","childNodes","claimed","usedKeys","renderedNodes","cursor","unkeyedIndex","kept","reconcile","replaceWith","replaceChild","following","isBlankText","insertBefore","morphChildren","restoreFocus","nodeValue","Node","TEXT_NODE","activeElement","HTMLElement","selection","HTMLInputElement","HTMLTextAreaElement","selectionStart","selectionEnd","preventScroll","setSelectionRange","reportDroppedAttribute","ALLOWED_TAGS","FORM_CONTROLS","REMOVE_COMPLETELY","ATTR_GLOBAL","ATTR_ARIA_PREFIX","ATTR_DATA_PREFIX","ATTR_BY_TAG","img","picture","audio","video","time","abbr","q","blockquote","table","th","td","col","colgroup","ol","li","pre","SanitizerEnvironmentError","TEMPLATE_ATTRIBUTES","DOCUMENT_SLOT","sanitizeHtml","sanitizeHtmlWithPolicy","resolveDocument","environmentError","instancePolicy","attrMap","attrs","allowedTags","attrByTag","allowFormControls","templateMode","allowedData","additionalAllowedTags","forEach","additionalAllowedAttributes","attr","allowedDataAttributes","pass","template","content","sanitizeFragment","serialize","env","process","isDevelopmentProcess","holder","warnOnce","__INLINE_BUILD__","writer","sanitizeElement","tagAttrs","isSafeSrcset","sanitizeAttributes","anchor","hardenAnchor","HTML_ESCAPES","freeze","HTML_ESCAPE_PATTERN","escapeHtml","char","ATTR_ESCAPES","ATTR_ESCAPE_PATTERN","escapeHtmlAttribute","PLACEHOLDER_PATTERN","collectTemplateKeys","items","interpolateArrayTemplate","knownKeys","placeholder","sharedItemAttributes","everyItem","inheritItemAttributes","safeStringify","isEmptyValue","lruGet","lruSet","oldest","lruTrim","TEMPLATE_EXTRA_TAGS","TEMPLATE_EXTRA_ATTRIBUTES","CUSTOM_TAG_PATTERN","optionsByTemplate","templateSanitizeOptions","cached","tags","match","matchAll","KEY_ATTRIBUTE","NESTED_KEY_ATTRIBUTE","NESTED_TEMPLATE_ATTRIBUTE","applyStructuralPatches","prepareStructuralPlan","commitStructuralPlan","store","morph","isManagedNestedSlot","_live","nextItems","memory","templateKeys","initialChildren","keyedChildren","indexByAttribute","reserved","readKey","takeIndexedElement","replaces","renders","renderItem","nestedSlots","prepareNestedSlots","prepareReconciliation","patch","createPatchPlan","mutated","retained","liveSlot","renderedSlot","synchronizeAttributes","getMemory","rememberItem","oldItem","newItem","prevValue","oldSlotsByKey","findDirectNestedSlots","plans","newSlot","oldSlot","nextTemplate","previousTemplate","nextNested","readNestedArray","resolvedNext","templateChanged","ancestor","nested","indexed","warnFragmentFallback","warnUnsupportedStrategy","warnEscalationUnavailable","warnInstead","StrategyRunner","planFragments","planned","inOwnerScope","escalateUnfaithful","routeRefreshed","coveringBoundaries","pendingFragments","runFragments","refreshRoute","hasUnboundChange","answered","navigated","subfieldCoverage","plansRoute","named","routeTouched","blocked","cloneNode","releaseDisconnectedIslands","known","blocker","morphFragment","missing","warnIslandStart","rebuildCache","patchFallback","restoreGuesses","scheduler","pendingCount","revealPending","updatedCount","runRoute","routeFailed","refreshAfterSave","armRouteRetry","delayMs","forSave","stats","lands","refresh","retryAfter","currentData","reapply","transform","transformForBinding","originalValue","transformValue","transformed","returnedThenable","TypeError","err","emit","NOTHING_CHANGED","MERGE_FAILED","UpdatePipeline","a11y","runtimeDisplayHost","_data","createLeanStrategyRunner","scheduleAllFields","navigationReplay","handleUpdate","heartbeat","observeCapabilities","acceptDataUpdate","handleReplay","reapplyNavigationBindings","reapplyNavigationIslands","relationshipInspection","buildSchemaIndex","incumbent","relationshipEdit","acceptRevision","timestamp","connection","processUpdate","resolveIncomingFields","dataFor","cancelRevision","applyFields","refined","autoBind","guesses","folded","keep","adoptUniqueBindings","coalesced","mergeWindowMs","applyMerged","lateBindings","owed","fragmentTouched","trackIdentity","skipUnchanged","scheduled","revealEditedField","ownsAnyBinding","createFieldAddressability","childName","uncoveredDocumentPaths","diagnoseOrphanFields","notifyIslands","restoreUniqueBindings","onFlush","unfaithful","revealField","documentSaved","UpdateScheduler","maxWaitMs","gateThresholdValue","gateDisabled","getCacheSize","scheduleFrame","cancelFrame","activeFlushes","debounceToken","deadlineTimer","frameHandle","frameFallback","frameToken","windowUntil","activeRevision","activeRevisionCancelled","destroying","visibilityGateThreshold","disableVisibilityGate","requestAnimationFrame","cancelAnimationFrame","armDebounce","clearWork","cancelScheduledWork","flushNow","notifyVisible","didApply","statsFor","retarget","retargetBuffer","replayCount","gateThreshold","gateActive","opensTheWindow","requestFrame","token","clearFrameFallback","frame","clearDeadline","appliedFields","batchEntry","nothingToScrollTo","buffer","box","width","height","READY_RETRY_DELAYS_MS","LivePreviewRuntime","pipeline","rootSentinel","closingSession","observedRoot","replayRetainedOnStart","isInsideIsland","bus","originMatcher","eventSourcePolicy","dataMerge","heartbeatMs","onHeartbeatTimeout","readyTargets","lockedOrigin","openScope","readyState","onReady","startWhenReady","startupHost","rollbackFailedStart","step","reportError","observerRoot","watchRootReplacement","buildCacheAndObserve","recoverSuspendedSession","suspendedHeartbeatExpired","sendReadyAfterStart","suspend","wasConnected","closingScope","refreshCache","followReplacedRoot","navigationCommit","cancelActiveUpdate","fieldNames","owners","version","trusted","locked","sort","profile","revisions","skippedUnchanged","orphanFields","ownerScoped","localeCompare","searchMs","fidelity","canEscalate","escalated","fragments","inFlight","visibilityGateActive","plugins","buildInspection","previousIslandOwners","previousNavigationRoots","added","removed","addedIslands","isIdleDisconnected","countSuperseded","EventEmitter","regular","on","register","off","emitSequential","shouldContinue","eligible","invoke","removeAllListeners","eventNames","label","isInIframe","self","isDevMode","nodeEnv","readNodeEnv","location","hostname","LOCALHOST_PATTERN","VALID_ORIGIN_PATTERN","LOCALHOST_HANDSHAKE_PORTS","readParentOrigin","ancestors","ancestorOrigins","OriginDetector","additionalOrigins","normalised","normaliseOrigin","referrerOrigin","enableReferrerDetection","referrer","allowLocalhost","enableLocalhostMatching","forceDevMode","lockOrigin","unlockOrigin","enumerate","port","referrerWasAvailable","isProductionUnconfigured","isReferrerOnlyTrust","noopDisposer","ResourceScope","pluginName","resources","assertOpen","cleanup","track","acquire","finalize","disposed","stage","resource","dispose","activate","counts","subscription","ScopedPluginEvents","events","subscriptions","subscribe","untypedHandler","callerEligible","subscriptionActive","wrapped","PluginManager","config","registerRenderer","onTransformError","initializing","teardowns","transforms","mutationQueue","queuedHooks","registerFieldRenderer","plugin","registerNow","unregister","unregisterNow","destroyAll","destroyAllNow","applyTransforms","registrations","registration","list","describe","cleanups","incompatibility","compat","runtimeVersion","runtime","range","parseVersion","alternative","comparators","comparator","operator","order","delta","compare","satisfiesComparator","satisfiesRange","isInteger","incompatibilityOf","refuse","createContext","runHook","init","registerTransform","registerCleanup","getConfig","existingTeardown","holdQueue","teardown","destroyPlugin","operation","RendererRegistry","layers","layer","stack","wasTop","previousLayer","previousRenderer","ALIGNMENT_NUMERIC","ALIGNMENT_STRING","resolveAlignment","fmt","resolveIndent","indent","dirAttribute","direction","layoutClassAttribute","align","classes","VALID_TAGS","asRecord","readMedia","resolveMediaUrl","server","sanitizeIdent","pickRelationLabel","title","BLANK_TARGET","linkRenderer","ctx","renderChildren","internalUrl","resolveUrl","titleAttr","extractText","dimensionAttributes","typeAttribute","mimeType","registry","lookupBlockRenderer","UNRENDERED_BLOCK_SELECTOR","renderBlockNode","baseClass","custom","onUnrenderedBlock","spanAttribute","BUILTIN_NODE_RENDERERS","paragraph","heading","tagRaw","listType","startAttr","checkAttr","listitem","valueAttr","link","autolink","quote","linebreak","horizontalrule","tab","mime","renderVideo","renderAudio","renderImage","filename","renderFallbackLink","classAttr","inlineBlock","tablerow","tablecell","header","warnedNoSanitizer","isLexicalContent","renderNode","extractPlainText","createTextRenderer","warnedElements","toPlainString","hasForeignChildren","escapeAndLinebreak","warnedKept","warnedLost","WRAPPER_TAGS","richTextRenderer","unrendered","verdicts","only","className","wrapperOf","placeholders","pairs","pairUnrenderedBlocks","replaceChildren","writeKeepingUnrenderedBlocks","sanitize","requireDocument","warnNoSanitizerOnce","lexicalToHtml","placeholderClass","lost","reportUnrenderedBlock","pair","fits","standing","front","shorter","lastElementChild","back","previousElementSibling","htmlRenderer","acceptUrl","createLinkRenderer","toHref","urlRenderer","HAS_SCHEME","emailRenderer","IMAGE_SOURCE_ATTRIBUTES","chosenSizes","clearImage","writeImage","sizes","sources","sizeSources","chosen","baseURI","sameUrl","sameShape","original","widths","parts","srcsetUrl","srcset","abs","NAMES_A_SOURCE","imageRenderer","pickSource","pickAlt","backgroundImage","escapeCssUrl","uploadRenderer","relationshipRenderer","selectRenderer","toValues","checked","option","labelFor","multiple","writeSelect","FALSE_STRINGS","checkboxRenderer","toBoolean","NUMBER_CACHE","DATE_CACHE","buildKey","localePart","serialised","stableStringify","inner","DATE_STYLES","TIME_STYLES","CURRENCY_CODE","FRACTION_DIGITS","dateFormat","numberFormat","formatOptionsFor","spec","separator","argument","dateStyle","timeStyle","minimumFractionDigits","maximumFractionDigits","currency","toUpperCase","parseValueFormat","warnUnknownFormat","dateRenderer","valid","isNaN","getTime","fallback","toISOString","DEFAULT_DATE_OPTIONS","Intl","DateTimeFormat","getDateTimeFormat","formatDate","day","getFullYear","padStart","pad","getMonth","getDate","clock","getHours","getMinutes","formatForInput","numberRenderer","num","NumberFormat","getNumberFormat","arrayRenderer","renderTemplate","templateOptions","createStructuralArrayRenderer","states","warnedContainers","warnedKeys","rawValue","warnMissingTemplate","previousState","domSnapshot","readDomKeySnapshot","__payloadDomPosition","sameDomKeySnapshot","needsForcedRender","nextKeys","itemKey","warnDuplicateKey","previousKeys","stable","warnAboutKeys","codes","builtinRenderers","omittedRenderer","V2_RUNTIME_DEFAULTS","disableReferrerDetection","V1_RUNTIME_DEFAULTS","invert","LivePreviewClient","detector","rendererRegistry","destroyed","tornDown","destroyPromise","rawConfig","rows","defaults","withProfileDefaults","mergeDepth","assertMergeDepthExplicit","allowedOrigins","disableLocalhostMatching","stateless","buildBuiltinRenderers","mergeFetch","e","autoStart","isInPreviewContext","isInPopup","resolveDestroy","rejectDestroy","reject","finish","finally","use","unuse","refreshAfterNavigation","reportPreviewFocus","targetOrigin","DIAGNOSTIC_CODES","NoTrustedOrigin","ReferrerOnlyTrust","PluginIncompatible","ProfileFeatureOmitted","OrphanField","UnattributableUpdate","UnboundField","VisibilityGateDeferred","UnsafeAttributeWrite","TextTargetHasChildren","MissingArrayTemplate","StructuralItemUnkeyed","StructuralDuplicateKey","StructuralUnstableKeys","UnsupportedStrategy","UnknownValueFormat","SanitizerDroppedAttribute","UnrenderedBlockKept","UnfaithfulPatch","ServerFormatReplaced","UnrenderedBlockLost","MessageRejected","TokenRejected","ProtocolShapeUnknown","HandlerThrew","TransformThrew","RendererThrew","StartupFailed","ReadyFailed","HydrationWaitTimedOut","AuditRuntimeMissing","AuditNoFrameAncestors","AuditFrameOptionsBlocks","AuditBindingsExposed","AuditGateThresholdExceeded","AuditUnownedBindings","AuditNoBindings","AuditNotAPage","FragmentRequestFailed","FragmentResponseInvalid","FragmentUnauthorized","FragmentSuperseded","RouteRefreshLoop","FragmentStrategyUnavailable","UnboundChangeRefresh","EscalationUnavailable","IslandStartUnavailable","RouteRefreshUnconfirmed","V2ReadinessGap","RuntimeOnPublicPage","resolveTarget","initLivePreview","client","registerRouteRefresh"],"sources":["../src/detection/locale.ts","../src/core/a11y.ts","../src/schema/parser.ts","../src/core/message-guards.ts","../src/core/protocol-version.ts","../src/core/thenable.ts","../src/core/message-bus.ts","../src/core/diagnostics.ts","../src/core/profile.ts","../src/core/runtime-wiring.ts","../src/types/defined-only.ts","../src/schema/walker.ts","../src/schema/diff.ts","../src/schema/field-type-map.ts","../src/security/url-validator.ts","../src/core/attribute-binding.ts","../src/core/value-identity.ts","../src/core/fidelity.ts","../src/core/internal-outcome.ts","../src/core/field-changes.ts","../src/core/field-value.ts","../src/core/strategies.ts","../src/core/binding-owner.ts","../src/core/subfield-coverage.ts","../src/core/unbound-fields.ts","../src/core/merge-need.ts","../src/core/protocol-tracker.ts","../src/core/relationship-tracker.ts","../src/core/reveal.ts","../src/core/reveal-ledger.ts","../src/core/revision-display.ts","../src/core/runtime-state.ts","../src/core/binding-writer.ts","../src/core/dependencies.ts","../src/core/islands.ts","../src/core/cache.ts","../src/core/legacy-population.ts","../src/core/data-merger.ts","../src/version.ts","../package.json","../src/core/protocol-profile.ts","../src/core/observers.ts","../src/core/lifetime-scope.ts","../src/core/hydration.ts","../src/core/hydration-vue.ts","../src/core/startup.ts","../src/core/hydration-sveltekit.ts","../src/core/state.ts","../src/core/auto-bind.ts","../src/core/update-owner.ts","../src/core/navigation-replay.ts","../src/core/orphan-diagnostics.ts","../src/security/trusted-types.ts","../src/core/morph.ts","../src/security/sanitizer-report.ts","../src/security/sanitizer.ts","../src/types/dev-warning.ts","../src/security/escape.ts","../src/core/array-template.ts","../src/field-types/utils.ts","../src/core/lru.ts","../src/core/template-sanitize.ts","../src/core/structural-applier.ts","../src/core/strategy-warnings.ts","../src/core/strategy-runner.ts","../src/core/transform-value.ts","../src/core/update-pipeline.ts","../src/core/strategy-runner-lean.ts","../src/core/update-scheduler.ts","../src/core/lifecycle.ts","../src/core/inspection/snapshot.ts","../src/events/emitter.ts","../src/detection/environment.ts","../src/detection/origin.ts","../src/plugins/resource-scope.ts","../src/plugins/scoped-events.ts","../src/plugins/manager.ts","../src/plugins/compat.ts","../src/plugins/renderer-registry.ts","../src/lexical/utils.ts","../src/lexical/nodes/paragraph.ts","../src/lexical/nodes/heading.ts","../src/lexical/value-shapes.ts","../src/lexical/nodes/link.ts","../src/lexical/nodes/code.ts","../src/lexical/nodes/upload.ts","../src/lexical/nodes/relationship.ts","../src/lexical/blocks/registry.ts","../src/lexical/nodes/block.ts","../src/lexical/nodes/table.ts","../src/lexical/nodes/builtin.ts","../src/lexical/nodes/text.ts","../src/lexical/types.ts","../src/lexical/nodes/list.ts","../src/lexical/nodes/quote.ts","../src/lexical/nodes/linebreak.ts","../src/lexical/registry.ts","../src/lexical/render.ts","../src/field-types/text.ts","../src/field-types/rich-text.ts","../src/field-types/html.ts","../src/field-types/unsafe-url.ts","../src/field-types/url.ts","../src/field-types/email.ts","../src/field-types/media.ts","../src/field-types/image.ts","../src/field-types/upload.ts","../src/field-types/relationship.ts","../src/field-types/select.ts","../src/field-types/checkbox.ts","../src/core/intl-cache.ts","../src/field-types/value-format.ts","../src/field-types/date.ts","../src/field-types/number.ts","../src/field-types/array.ts","../src/field-types/structural-array.ts","../src/field-types/registry.ts","../src/field-types/index.ts","../src/types/defaults-profile.ts","../src/client/index.ts","../src/client/config.ts","../src/types/merge-depth.ts","../src/client/preview-focus.ts","../src/core/diagnostic-codes.ts","../src/core/route-refresh.ts"],"sourcesContent":["/** The locale for `Intl` renders before Payload names one: `<html lang>`, then `navigator.language`, then `'en'`. */\n\nconst FALLBACK_LOCALE = 'en';\n\n/** @internal */\nexport function detectInitialLocale(): string {\n return readHtmlLang() ?? readNavigatorLanguage() ?? FALLBACK_LOCALE;\n}\n\nfunction readHtmlLang(): string | undefined {\n if (typeof document === 'undefined') return undefined;\n const lang = document.documentElement.getAttribute('lang');\n return lang === null || lang.length === 0 ? undefined : lang;\n}\n\nfunction readNavigatorLanguage(): string | undefined {\n if (typeof navigator === 'undefined') return undefined;\n const lang = navigator.language;\n return typeof lang === 'string' && lang.length > 0 ? lang : undefined;\n}\n","/**\n * One polite `aria-live` region per document, leased by every announcer on\n * the page, for connect / update / disconnect announcements. The package clears\n * its message node after a moment so a later message creates a fresh text change.\n */\n\nimport { detectInitialLocale } from '@detection/locale';\n\nconst ELEMENT_ID = 'payload-live-preview-a11y';\nconst CLEAR_DELAY_MS = 1500;\nconst STYLE =\n 'position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;' +\n 'clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0';\n\nfunction isGerman(locale: string): boolean {\n return /^de(?:[-_]|$)/i.test(locale);\n}\n\n/** Shared per document; reference-counted so one client cannot remove another's region. */\ninterface DocumentLease {\n element: HTMLElement | null;\n /** Created by this package (removable) rather than adopted from the page. */\n owned: boolean;\n messageNode: Text | null;\n refs: number;\n timer: ReturnType<typeof setTimeout> | null;\n}\n\nconst documentLeases = new WeakMap<Document, DocumentLease>();\n\nfunction acquireDocumentLease(activeDocument: Document): DocumentLease {\n let lease = documentLeases.get(activeDocument);\n if (lease === undefined) {\n lease = { element: null, owned: false, messageNode: null, refs: 0, timer: null };\n documentLeases.set(activeDocument, lease);\n }\n lease.refs += 1;\n return lease;\n}\n\n/** Remove only the package-owned message node, never consumer children. */\nfunction clearLeaseMessage(lease: DocumentLease): void {\n if (lease.timer !== null) {\n clearTimeout(lease.timer);\n lease.timer = null;\n }\n lease.messageNode?.remove();\n lease.messageNode = null;\n}\n\nexport class A11yAnnouncer {\n private readonly german: boolean;\n private readonly document: Document | null;\n private lease: DocumentLease | null = null;\n\n constructor(locale?: string, targetDocument?: Document | null) {\n const activeDocument = targetDocument ?? (typeof document === 'undefined' ? null : document);\n const documentLocale = activeDocument?.documentElement.getAttribute('lang') ?? '';\n this.german = isGerman(\n locale ?? (documentLocale.length > 0 ? documentLocale : detectInitialLocale()),\n );\n this.document = activeDocument;\n // The region mounts on the first announcement: a <head> inline script runs before `body` exists.\n }\n\n /** The shared region, or `null` without a body yet (announcements are then dropped). */\n private mount(): HTMLElement | null {\n const activeDocument = this.document;\n if (activeDocument?.body == null) return null;\n this.lease ??= acquireDocumentLease(activeDocument);\n const lease = this.lease;\n const leased = lease.element;\n if (leased?.isConnected && leased.ownerDocument === activeDocument) return leased;\n // The host removed or replaced the region between announcements.\n if (leased !== null) {\n const owned = lease.owned;\n clearLeaseMessage(lease);\n if (owned) leased.remove();\n }\n let element = activeDocument.getElementById(ELEMENT_ID);\n lease.owned = element === null;\n if (element === null) {\n element = activeDocument.createElement('div');\n element.id = ELEMENT_ID;\n element.setAttribute('role', 'status');\n element.setAttribute('aria-live', 'polite');\n element.setAttribute('aria-atomic', 'true');\n // Through the CSSOM: a strict `style-src` refuses a `style` attribute,\n // not declarations set on `element.style`.\n element.style.cssText = STYLE;\n activeDocument.body.appendChild(element);\n }\n lease.element = element;\n return element;\n }\n\n announceConnected(): void {\n this.say(this.german ? 'Vorschau verbunden' : 'Live preview connected');\n }\n\n announceDisconnected(): void {\n this.say(this.german ? 'Vorschau getrennt' : 'Live preview disconnected');\n }\n\n announceUpdate(count: number): void {\n if (count <= 0) return;\n this.say(\n this.german\n ? `${String(count)} ${count === 1 ? 'Änderung' : 'Änderungen'} angewendet`\n : `${String(count)} ${count === 1 ? 'change' : 'changes'} applied`,\n );\n }\n\n /** A revision settled with a step that fell short (ADR 0023); the counts said only what was written. */\n announcePartial(): void {\n this.say(this.german ? 'Vorschau teilweise aktualisiert' : 'Preview partly updated');\n }\n\n /** Release the lease; the last release removes an owned region but leaves an adopted one. Idempotent. */\n detach(): void {\n const lease = this.lease;\n const activeDocument = this.document;\n if (lease === null || activeDocument === null) return;\n this.lease = null;\n lease.refs -= 1;\n if (lease.refs > 0) return;\n const element = lease.element;\n if (element !== null) clearLeaseMessage(lease);\n if (lease.owned) element?.remove();\n lease.element = null;\n documentLeases.delete(activeDocument);\n }\n\n private say(message: string): void {\n const element = this.mount();\n const lease = this.lease;\n if (element === null || lease === null) return;\n let messageNode = lease.messageNode;\n if (messageNode?.parentNode !== element) {\n // A dedicated text node leaves consumer-owned children untouched.\n messageNode?.remove();\n messageNode = element.ownerDocument.createTextNode(\n element.hasChildNodes() ? ` ${message}` : message,\n );\n lease.messageNode = messageNode;\n element.appendChild(messageNode);\n } else {\n messageNode.data = messageNode.previousSibling === null ? message : ` ${message}`;\n }\n if (lease.timer !== null) clearTimeout(lease.timer);\n const timer = setTimeout(() => {\n if (lease.timer === timer && lease.element === element) clearLeaseMessage(lease);\n }, CLEAR_DELAY_MS);\n lease.timer = timer;\n }\n}\n","/**\n * Validates the `fieldSchemaJSON` the admin sends. Entries that fail\n * validation are dropped, never thrown: a Payload/runtime version mismatch\n * must not take the preview down.\n */\n\nimport type { PayloadBlockSchema, PayloadFieldSchema } from '@/types/payload-protocol';\n\ninterface ParseState {\n nodes: number;\n readonly active: WeakSet<object>;\n}\nfunction visit(state: ParseState): void {\n if (++state.nodes > 10_000) throw new Error('invalid or oversized field schema');\n}\nfunction enter(value: object, state: ParseState, depth: number): void {\n visit(state);\n if (depth > 64 || state.active.has(value)) throw new Error('invalid or oversized field schema');\n state.active.add(value);\n}\n\nexport function parseFieldSchema(raw: unknown): readonly PayloadFieldSchema[] {\n try {\n return parseFields(raw, { nodes: 0, active: new WeakSet() }, 0);\n } catch {\n return [];\n }\n}\n\nfunction parseFields(\n raw: unknown,\n state: ParseState,\n depth: number,\n): readonly PayloadFieldSchema[] {\n if (!Array.isArray(raw)) return [];\n enter(raw, state, depth);\n const out: PayloadFieldSchema[] = [];\n for (const entry of raw) {\n const parsed = parseFieldEntry(entry, state, depth);\n if (parsed) out.push(parsed);\n }\n state.active.delete(raw);\n return out;\n}\n\nfunction parseFieldEntry(\n value: unknown,\n state: ParseState,\n depth: number,\n): PayloadFieldSchema | undefined {\n visit(state);\n if (typeof value !== 'object' || value === null) return undefined;\n const record = value as Record<string, unknown>;\n const name = record['name'];\n const type = record['type'];\n if (typeof name !== 'string' || name.length === 0) return undefined;\n if (typeof type !== 'string' || type.length === 0) return undefined;\n\n const fields = parseFields(record['fields'], state, depth + 1);\n const blocks = parseBlockSchema(record['blocks'], state, depth + 1);\n\n const result: Record<string, unknown> = { ...record, name, type };\n const relationTo = record['relationTo'];\n if (Array.isArray(relationTo)) {\n const targets: unknown[] = [];\n for (const target of relationTo) {\n visit(state);\n targets.push(target);\n }\n result['relationTo'] = targets;\n }\n if (fields.length > 0) result['fields'] = fields;\n else delete result['fields'];\n if (blocks.length > 0) result['blocks'] = blocks;\n else delete result['blocks'];\n\n return result as unknown as PayloadFieldSchema;\n}\n\nfunction parseBlockSchema(\n raw: unknown,\n state: ParseState,\n depth: number,\n): readonly PayloadBlockSchema[] {\n if (typeof raw === 'object' && raw !== null && !Array.isArray(raw)) {\n enter(raw, state, depth);\n const blocks: PayloadBlockSchema[] = [];\n for (const slug in raw) {\n if (!Object.hasOwn(raw, slug)) continue;\n visit(state);\n const entry: unknown = Reflect.get(raw, slug);\n if (\n typeof entry !== 'object' ||\n entry === null ||\n ['__proto__', 'constructor', 'prototype'].includes(slug)\n ) {\n continue;\n }\n blocks.push({\n ...(entry as Record<string, unknown>),\n slug,\n fields: parseFields((entry as Record<string, unknown>)['fields'], state, depth + 1),\n });\n }\n state.active.delete(raw);\n return blocks;\n }\n if (!Array.isArray(raw)) return [];\n enter(raw, state, depth);\n const out: PayloadBlockSchema[] = [];\n for (const entry of raw) {\n visit(state);\n if (typeof entry !== 'object' || entry === null) continue;\n const record = entry as Record<string, unknown>;\n const slug = record['slug'];\n if (typeof slug !== 'string' || slug.length === 0) continue;\n const fields = parseFields(record['fields'], state, depth + 1);\n out.push({ ...record, slug, fields });\n }\n state.active.delete(raw);\n return out;\n}\n","/**\n * Shape guards for the messages the bus accepts. `null` counts as absent, as\n * JSON bridges send it. The schema parser owns bounded, fail-closed normalization.\n */\n\nimport type {\n PayloadDocumentEventMessage,\n PayloadLivePreviewMessage,\n} from '@/types/payload-protocol';\nimport { parseFieldSchema } from '@schema/parser';\n\nexport function isObjectMessage(value: unknown): value is { type: string } {\n return (\n typeof value === 'object' && value !== null && 'type' in value && typeof value.type === 'string'\n );\n}\n\n/** A `payload-live-preview` message: `data` a plain object when present, scalars of the right type or absent. */\nexport function isLivePreviewMessage(value: { type: string }): value is PayloadLivePreviewMessage {\n const v = value as Record<string, unknown>;\n if (v['data'] !== undefined && v['data'] !== null && !isPlainObject(v['data'])) return false;\n return (\n optionalTypeOk(v['fieldSchemaJSON'], (x) => Array.isArray(x)) &&\n optionalTypeOk(v['globalSlug'], (x) => typeof x === 'string') &&\n optionalTypeOk(v['collectionSlug'], (x) => typeof x === 'string') &&\n optionalTypeOk(v['locale'], (x) => typeof x === 'string') &&\n optionalTypeOk(v['ready'], (x) => typeof x === 'boolean') &&\n optionalTypeOk(v['previewToken'], (x) => typeof x === 'string') &&\n optionalTypeOk(v['protocolVersion'], (x) => typeof x === 'number')\n );\n}\n\n/** The non-empty field name of a `payload-live-preview-focus` message, else `undefined`. */\nexport function focusFieldOf(value: { type: string }): string | undefined {\n const field = (value as Record<string, unknown>)['field'];\n return typeof field === 'string' && field.length > 0 ? field : undefined;\n}\n\n/** Stock Payload sends only the `type`; custom senders may add the typed fields (omitted, never `null`). */\nexport function isDocumentEventMessage(value: {\n type: string;\n}): value is PayloadDocumentEventMessage {\n const v = value as Record<string, unknown>;\n return (\n optionalFieldOk(v['action'], (x) => x === 'updated' || x === 'created' || x === 'deleted') &&\n optionalFieldOk(v['slug'], (x) => typeof x === 'string') &&\n optionalFieldOk(v['id'], (x) => typeof x === 'string' || Number.isFinite(x))\n );\n}\n\nfunction optionalFieldOk(value: unknown, check: (v: unknown) => boolean): boolean {\n return value === undefined || check(value);\n}\n\nfunction optionalTypeOk(value: unknown, check: (v: unknown) => boolean): boolean {\n return value === undefined || value === null || check(value);\n}\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) return false;\n const prototype = Object.getPrototypeOf(value) as object | null;\n return prototype === null || Object.getPrototypeOf(prototype) === null;\n}\n\nconst NULL_AS_ABSENT_FIELDS = [\n 'data',\n 'fieldSchemaJSON',\n 'globalSlug',\n 'collectionSlug',\n 'locale',\n 'ready',\n 'previewToken',\n 'protocolVersion',\n] as const satisfies readonly (keyof PayloadLivePreviewMessage)[];\n\n/**\n * Drop `null` optionals so downstream sees the strict public type, and parse\n * the field schema entry by entry (malformed entries are dropped). Unknown\n * fields stay, for protocol evolution.\n */\nexport function normalizeLivePreviewMessage(\n message: PayloadLivePreviewMessage,\n): PayloadLivePreviewMessage {\n const normalized = { ...message };\n for (const field of NULL_AS_ABSENT_FIELDS) {\n const wireValue: unknown = Reflect.get(normalized, field);\n if (wireValue === null) Reflect.deleteProperty(normalized, field);\n }\n if (!Array.isArray(normalized.fieldSchemaJSON)) return normalized;\n return {\n ...normalized,\n fieldSchemaJSON: parseFieldSchema(normalized.fieldSchemaJSON),\n };\n}\n","/**\n * Protocol negotiation. A capability is granted either by the version a peer\n * announces or by observation, since the stock Payload admin announces none:\n * what it can do is read off the messages it sends. See ADR 0010.\n */\n\n/** Bumped only when this library's understanding of the wire format changes. @internal */\nexport const LIBRARY_PROTOCOL_VERSION = 4;\n\n/** How a capability becomes active. @internal */\nexport type CapabilitySource = 'version' | 'observed';\n\n/** @internal */\nexport interface CapabilityDeclaration {\n /** Enabled once the negotiated version reaches this (for announced peers). */\n readonly since: number;\n /** The wire signal that grants this capability to a peer announcing no version. */\n readonly observed?:\n 'schema' | 'locale' | 'preview-token' | 'document-event' | 'relationship-event';\n}\n\n/** What activates each capability; the prose lives in `CAPABILITY_DOCUMENTATION`. */\nexport const CAPABILITY_DECLARATIONS = {\n basic: { since: 1 },\n 'schema-json': { since: 2, observed: 'schema' },\n locale: { since: 2, observed: 'locale' },\n 'preview-token': { since: 3, observed: 'preview-token' },\n 'nested-arrays': { since: 4 },\n 'recursive-diffs': { since: 4 },\n 'document-events': { since: 4, observed: 'document-event' },\n 'relationship-events': { since: 4, observed: 'relationship-event' },\n} as const satisfies Record<string, CapabilityDeclaration>;\n\nexport type ProtocolCapability = keyof typeof CAPABILITY_DECLARATIONS;\n\n/** Every declared capability, in declaration order. @internal */\nexport const PROTOCOL_CAPABILITIES = Object.keys(\n CAPABILITY_DECLARATIONS,\n) as readonly ProtocolCapability[];\n\nexport interface ProtocolNegotiation {\n /** This library's protocol version. */\n readonly ours: number;\n /** The remote party's version, when it announced one. */\n readonly theirs: number | undefined;\n /** `min(ours, theirs ?? 1)` — the version both sides actually share. */\n readonly negotiated: number;\n /** Capabilities active at the negotiated version or seen on the wire. */\n readonly capabilities: ReadonlySet<ProtocolCapability>;\n /** The subset that was observed on the wire rather than granted by version. */\n readonly observed: ReadonlySet<ProtocolCapability>;\n}\n\n/** Deterministic; the runtime re-runs it whenever either input changes. */\nexport function negotiateProtocol(\n theirs: number | undefined,\n observed: Iterable<ProtocolCapability> = [],\n): ProtocolNegotiation {\n const sanitisedTheirs =\n typeof theirs === 'number' && Number.isFinite(theirs) && theirs >= 1\n ? Math.floor(theirs)\n : undefined;\n const effectiveTheirs = sanitisedTheirs ?? 1;\n const negotiated = Math.min(LIBRARY_PROTOCOL_VERSION, effectiveTheirs);\n const seen = new Set<ProtocolCapability>(observed);\n const capabilities = new Set<ProtocolCapability>();\n for (const capability of PROTOCOL_CAPABILITIES) {\n if (negotiated >= CAPABILITY_DECLARATIONS[capability].since || seen.has(capability)) {\n capabilities.add(capability);\n }\n }\n return {\n ours: LIBRARY_PROTOCOL_VERSION,\n ...(sanitisedTheirs !== undefined ? { theirs: sanitisedTheirs } : { theirs: undefined }),\n negotiated,\n capabilities,\n observed: seen,\n };\n}\n\n/** @internal */\nexport function hasCapability(\n negotiation: ProtocolNegotiation,\n capability: ProtocolCapability,\n): boolean {\n return negotiation.capabilities.has(capability);\n}\n\n/** The capabilities a single message demonstrates, by its shape alone. */\nexport function observeCapabilities(message: {\n readonly fieldSchemaJSON?: unknown;\n readonly locale?: unknown;\n readonly previewToken?: unknown;\n readonly externallyUpdatedRelationship?: unknown;\n}): readonly ProtocolCapability[] {\n const seen: ProtocolCapability[] = [];\n if (Array.isArray(message.fieldSchemaJSON)) seen.push('schema-json');\n if (typeof message.locale === 'string') seen.push('locale');\n if (typeof message.previewToken === 'string') seen.push('preview-token');\n if (\n typeof message.externallyUpdatedRelationship === 'object' &&\n message.externallyUpdatedRelationship !== null\n ) {\n seen.push('relationship-events');\n }\n return seen;\n}\n","/**\n * Detect an invalid async result in a synchronous extension point.\n *\n * Rejected native Promises otherwise become unhandled after the caller falls\n * back synchronously. Assimilating the result through a handled Promise keeps\n * that contract violation observable only through the runtime's explicit\n * error channel.\n */\nexport function observeThenableResult(value: unknown): boolean {\n if ((typeof value !== 'object' || value === null) && typeof value !== 'function') return false;\n if (typeof (value as { readonly then?: unknown }).then !== 'function') return false;\n void Promise.resolve(value).catch(() => undefined);\n return true;\n}\n","/**\n * postMessage ingress: origin and source checks, per-type shape guards, the\n * ordered preview-token validation queue, and the `ready` handshake. The bus\n * never throws; a rejected message is dropped or reported via `onInvalid`.\n * Consumer callbacks may detach or re-attach the bus synchronously, so\n * anything that runs after one re-checks the generation it started in.\n * See ADR 0004.\n */\n\nimport type {\n PayloadDocumentEventMessage,\n PayloadLivePreviewMessage,\n} from '@/types/payload-protocol';\nimport {\n focusFieldOf,\n isDocumentEventMessage,\n isLivePreviewMessage,\n isObjectMessage,\n isPlainObject,\n normalizeLivePreviewMessage,\n} from './message-guards';\nimport { LIBRARY_PROTOCOL_VERSION } from './protocol-version';\nimport { observeThenableResult } from './thenable';\n\nexport type OriginMatcher = (origin: string) => boolean;\n\n/** Identity of a data-bearing update: `revision` is monotonic, `generation` names the listener attachment. */\nexport interface MessageRevision {\n readonly revision: number;\n readonly generation: number;\n}\nexport function sameRevision(a: MessageRevision, b: MessageRevision): boolean {\n return a.generation === b.generation && a.revision === b.revision;\n}\n\nexport type InvalidReason = 'origin' | 'shape' | 'type' | 'token' | 'source';\n\nexport interface MessageHandlers {\n /** A validated update; data-bearing ones carry their revision, ready handshakes do not. */\n readonly onUpdate: (\n msg: PayloadLivePreviewMessage,\n origin: string,\n messageRevision?: MessageRevision,\n ) => void;\n /** A locally retained, previously accepted update replayed in a new lifecycle generation. */\n readonly onReplay?: (\n msg: PayloadLivePreviewMessage,\n origin: string,\n messageRevision: MessageRevision,\n ) => void;\n readonly onDocumentEvent: (msg: PayloadDocumentEventMessage, origin: string) => void;\n /** The admin reports the cursor moved into a field (reveal tier 2). */\n readonly onFocusField?: (field: string, origin: string) => void;\n readonly onInvalid?: (reason: InvalidReason, origin: string) => void;\n /** `'parent-or-opener'` refuses every window but the framing/opening one, even from an allowed origin. */\n readonly sourcePolicy?: 'any' | 'parent-or-opener';\n /**\n * Gate for data-bearing updates. Verdicts commit in arrival order, so an\n * earlier update is dispatched before a later one even when its validation\n * resolves later; an error counts as rejection.\n */\n readonly validateToken?: (\n token: string | undefined,\n origin: string,\n ) => boolean | Promise<boolean>;\n}\n\n/** One entry of the validation queue: a singly linked list in arrival order. */\ninterface PendingValidation {\n readonly generation: number;\n readonly message: PayloadLivePreviewMessage;\n readonly origin: string;\n readonly messageRevision: MessageRevision | undefined;\n /** `undefined` until the validator settled; only literal `true` approves. */\n verdict: boolean | undefined;\n next: PendingValidation | undefined;\n}\n\ninterface AcceptedUpdate {\n readonly generation: number;\n readonly message: PayloadLivePreviewMessage;\n readonly origin: string;\n}\n\n/** Keep consumer callbacks from mutating the snapshot reserved for navigation replay. */\nfunction snapshotForReplay(message: PayloadLivePreviewMessage): PayloadLivePreviewMessage | null {\n const withoutToken = { ...message };\n delete withoutToken.previewToken;\n try {\n return structuredClone(withoutToken);\n } catch {\n // A real postMessage payload is cloneable. A synthetic non-cloneable one\n // may still be processed once, but retaining it would make replay mutable.\n return null;\n }\n}\n\nexport class MessageBus {\n private readonly matcher: OriginMatcher;\n private readonly handlers: MessageHandlers;\n private boundListener: ((event: MessageEvent) => void) | undefined = undefined;\n private attachedTarget: Window | undefined = undefined;\n private generation = 0;\n private revision = 0;\n private queueHead: PendingValidation | undefined = undefined;\n private queueTail: PendingValidation | undefined = undefined;\n private lastAccepted: AcceptedUpdate | undefined = undefined;\n private replayedGeneration = 0;\n /** Identity of the newest accepted data commit, including one still crossing the clone boundary. */\n private latestAcceptedAttempt: object | undefined = undefined;\n\n constructor(matcher: OriginMatcher, handlers: MessageHandlers) {\n this.matcher = matcher;\n this.handlers = handlers;\n }\n\n /** Start listening on `target`. Idempotent. */\n attach(target: Window = window): void {\n if (this.attachedTarget !== undefined) return;\n let committed = false;\n const listener = (event: MessageEvent): void => {\n // Each attachment owns its listener; a stale one must not borrow the new generation.\n if (!committed || this.boundListener !== listener) return;\n const generation = this.generation;\n try {\n this.receive(event, generation, target);\n } catch {\n // A synthetic event can carry throwing accessors; that is a shape failure.\n let origin: string;\n try {\n origin = event.origin;\n } catch {\n origin = '';\n }\n this.reportInvalid('shape', origin, generation);\n }\n };\n this.generation += 1;\n this.resetQueue();\n this.attachedTarget = target;\n this.boundListener = listener;\n try {\n target.addEventListener('message', listener);\n } catch (error) {\n // Invalidate before rollback: a hook may already have attached a newer generation.\n if (this.boundListener === listener) {\n this.attachedTarget = undefined;\n this.boundListener = undefined;\n this.resetQueue();\n }\n try {\n target.removeEventListener('message', listener);\n } catch {\n // Keep the original failure.\n }\n throw error;\n }\n if (this.boundListener === listener) {\n committed = true;\n } else {\n try {\n target.removeEventListener('message', listener);\n } catch {\n // The listener is identity-gated above even if removal fails.\n }\n }\n }\n\n /** Stop listening. Idempotent. */\n detach(): void {\n const target = this.attachedTarget;\n const listener = this.boundListener;\n if (target === undefined || listener === undefined) return;\n // Invalidate first so a listener already on the stack sees an obsolete generation.\n this.attachedTarget = undefined;\n this.boundListener = undefined;\n this.resetQueue();\n target.removeEventListener('message', listener);\n }\n\n /** Invalidate pending validations while staying attached (heartbeat expiry). */\n advanceGeneration(): boolean {\n if (this.attachedTarget === undefined) return false;\n this.generation += 1;\n this.resetQueue();\n return true;\n }\n\n /**\n * Re-dispatch the last data-bearing update under the current generation.\n * Only an update already accepted in an older generation is eligible; its\n * preview token is never retained or replayed. @internal\n */\n replayLastAccepted(): boolean {\n const accepted = this.lastAccepted;\n const generation = this.generation;\n const handler = this.handlers.onReplay;\n if (\n handler === undefined ||\n accepted === undefined ||\n accepted.generation >= generation ||\n this.replayedGeneration === generation\n ) {\n return false;\n }\n // Origin matching fails closed outside the attached generation it ran in,\n // and it is consumer code that may accept a newer message reentrantly.\n // Never let the older snapshot run after it.\n if (!this.matchesOrigin(accepted.origin, generation) || this.lastAccepted !== accepted) {\n return false;\n }\n this.replayedGeneration = generation;\n const revision = { generation, revision: (this.revision += 1) };\n // Clone for every replay: hooks may mutate what they receive, but the\n // retained copy is the baseline for later navigations too. It came out\n // of structuredClone, so cloning it again cannot throw.\n this.invokeHandler(\n generation,\n handler,\n structuredClone(accepted.message),\n accepted.origin,\n revision,\n );\n return true;\n }\n\n /** Forget retained document data when the connection expires or the owner is destroyed. @internal */\n forgetLastAccepted(): void {\n this.lastAccepted = undefined;\n this.replayedGeneration = 0;\n this.latestAcceptedAttempt = undefined;\n }\n\n /** Post the `ready` handshake to every target for every origin. */\n static sendReady(targets: readonly Window[], origins: readonly string[]): void {\n const payload: PayloadLivePreviewMessage = {\n type: 'payload-live-preview',\n ready: true,\n protocolVersion: LIBRARY_PROTOCOL_VERSION,\n };\n for (const target of targets) {\n for (const origin of origins) {\n try {\n target.postMessage(payload, origin);\n } catch {\n // A malformed origin is the consumer's configuration problem.\n }\n }\n }\n }\n\n private receive(event: MessageEvent, generation: number, target: Window): void {\n const origin = event.origin;\n if (!this.matchesOrigin(origin, generation)) {\n this.reportInvalid('origin', origin, generation);\n return;\n }\n if (!this.matchesSource(event, target)) {\n this.reportInvalid('source', origin, generation);\n return;\n }\n const data: unknown = event.data;\n if (!isObjectMessage(data)) {\n this.reportInvalid('shape', origin, generation);\n return;\n }\n switch (data.type) {\n case 'payload-live-preview':\n if (!isLivePreviewMessage(data)) {\n this.reportInvalid('shape', origin, generation);\n return;\n }\n this.dispatchUpdate(normalizeLivePreviewMessage(data), origin, generation);\n return;\n case 'payload-document-event':\n if (!isDocumentEventMessage(data)) {\n this.reportInvalid('shape', origin, generation);\n return;\n }\n this.invokeHandler(generation, this.handlers.onDocumentEvent, data, origin);\n return;\n case 'payload-live-preview-focus': {\n const field = focusFieldOf(data);\n if (field === undefined) {\n this.reportInvalid('shape', origin, generation);\n return;\n }\n this.invokeHandler(generation, this.handlers.onFocusField, field, origin);\n return;\n }\n default:\n this.reportInvalid('type', origin, generation);\n }\n }\n\n private dispatchUpdate(\n message: PayloadLivePreviewMessage,\n origin: string,\n generation: number,\n ): void {\n const hasUpdateData = isPlainObject(message.data);\n if (!this.isCurrentGeneration(generation)) return;\n // A shape-valid data update consumes its revision before validation; a rejected token leaves a gap.\n const messageRevision = hasUpdateData\n ? { generation, revision: (this.revision += 1) }\n : undefined;\n const validator = this.handlers.validateToken;\n if (!this.isCurrentGeneration(generation)) return;\n if (validator === undefined) {\n this.commitUpdate(message, origin, generation, messageRevision);\n return;\n }\n // The data-less ready handshake carries no token and passes, so the admin learns we listen.\n if (message.ready === true && message.data === undefined) {\n this.commitUpdate(message, origin, generation, undefined);\n return;\n }\n const pending: PendingValidation = {\n generation,\n message,\n origin,\n messageRevision,\n verdict: undefined,\n next: undefined,\n };\n this.enqueue(pending);\n let verdict: unknown;\n try {\n // Invoked eagerly; only the commit waits for earlier queue entries.\n verdict = validator(message.previewToken, origin);\n } catch {\n this.settleValidation(pending, false);\n return;\n }\n if (typeof verdict === 'boolean') {\n this.settleValidation(pending, verdict);\n return;\n }\n // Assimilate any thenable; only literal `true` approves.\n void Promise.resolve(verdict).then(\n (approved) => {\n this.settleValidation(pending, approved === true);\n },\n () => {\n this.settleValidation(pending, false);\n },\n );\n }\n\n private settleValidation(pending: PendingValidation, approved: boolean): void {\n pending.verdict = approved;\n this.drainQueue(pending.generation);\n }\n\n private drainQueue(generation: number): void {\n while (this.isCurrentGeneration(generation)) {\n const pending = this.queueHead;\n if (pending === undefined) return;\n // The matcher may have narrowed since ingress (origin lock); an obsolete\n // origin must not hold the queue head and block the locked origin's work.\n if (!this.matchesOrigin(pending.origin, generation)) {\n if (!this.dequeue(pending)) continue;\n this.reportInvalid('origin', pending.origin, pending.generation);\n continue;\n }\n if (pending.verdict === undefined) return;\n if (!this.dequeue(pending)) continue;\n if (pending.verdict) {\n this.commitUpdate(\n pending.message,\n pending.origin,\n pending.generation,\n pending.messageRevision,\n );\n } else {\n this.reportInvalid('token', pending.origin, pending.generation);\n }\n }\n }\n\n private commitUpdate(\n message: PayloadLivePreviewMessage,\n origin: string,\n generation: number,\n messageRevision: MessageRevision | undefined,\n ): void {\n if (messageRevision === undefined) {\n this.invokeHandler(generation, this.handlers.onUpdate, message, origin);\n } else {\n const attempt = {};\n this.latestAcceptedAttempt = attempt;\n const snapshot = snapshotForReplay(message);\n // Cloning synthetic input can run accessors. If one accepted a newer\n // message reentrantly, the older commit must not overwrite or follow it.\n if (this.latestAcceptedAttempt !== attempt || !this.isCurrentGeneration(generation)) return;\n this.lastAccepted = snapshot === null ? undefined : { generation, message: snapshot, origin };\n this.invokeHandler(generation, this.handlers.onUpdate, message, origin, messageRevision);\n }\n }\n\n private reportInvalid(reason: InvalidReason, origin: string, generation: number): void {\n this.invokeHandler(generation, this.handlers.onInvalid, reason, origin);\n }\n\n /** Under `'parent-or-opener'`, whether the event came from the attached window's parent or opener. */\n private matchesSource(event: MessageEvent, target: Window): boolean {\n if (this.handlers.sourcePolicy !== 'parent-or-opener') return true;\n try {\n // Only a window is a source: a missing one matches nothing, not even a missing opener.\n const source: unknown = event.source;\n if (typeof source !== 'object' || source === null) return false;\n const parent = target.parent;\n if (parent !== target && source === parent) return true;\n const opener: unknown = target.opener;\n return source === opener;\n } catch {\n return false;\n }\n }\n\n /** Fail-closed: only literal `true` from the matcher, and only within the generation it ran in. */\n private matchesOrigin(origin: string, generation: number): boolean {\n try {\n const approved: unknown = this.isCurrentGeneration(generation) && this.matcher(origin);\n return approved === true && this.isCurrentGeneration(generation);\n } catch {\n return false;\n }\n }\n\n /** Callbacks run only in a current generation and must not unwind the listener or the drain. */\n private invokeHandler<TArgs extends unknown[]>(\n generation: number,\n handler: ((...args: TArgs) => unknown) | undefined,\n ...args: TArgs\n ): void {\n if (handler === undefined || !this.isCurrentGeneration(generation)) return;\n try {\n observeThenableResult(handler(...args));\n } catch {\n // Isolated by contract.\n }\n }\n\n private isCurrentGeneration(generation: number): boolean {\n return this.attachedTarget !== undefined && this.generation === generation;\n }\n\n private enqueue(pending: PendingValidation): void {\n if (this.queueTail === undefined) this.queueHead = pending;\n else this.queueTail.next = pending;\n this.queueTail = pending;\n }\n\n /** Advance the head past `expected`, unless a matcher reset the queue meanwhile. */\n private dequeue(expected: PendingValidation): boolean {\n if (this.queueHead !== expected) return false;\n this.queueHead = expected.next;\n if (this.queueHead === undefined) this.queueTail = undefined;\n return true;\n }\n\n private resetQueue(): void {\n this.queueHead = undefined;\n this.queueTail = undefined;\n }\n}\n","import { observeThenableResult } from './thenable';\n\n/**\n * Diagnostics are observability, never control flow: a consumer logger may\n * throw or return a rejected thenable, and reporting a failure must not become\n * a second failure. Invocation stays synchronous for ordinary loggers.\n */\nexport function isolateDiagnostic(\n diagnostic: (...args: unknown[]) => unknown,\n): (...args: unknown[]) => void {\n return (...args): void => {\n try {\n observeThenableResult(diagnostic(...args));\n } catch {\n // Diagnostics must not become a second failure boundary.\n }\n };\n}\n\n/** Shared allocation-free default for disabled diagnostic channels. */\nexport function noopDiagnostic(): void {\n // Intentionally empty.\n}\n\n// Access, invocation and thenable inspection all happen inside the wrapper, so\n// a missing or hostile console cannot escape.\nexport const safeConsoleError = isolateDiagnostic((...args) =>\n (console.error as (...values: unknown[]) => unknown)(...args),\n);\n\nexport const safeConsoleWarn = isolateDiagnostic((...args) =>\n (console.warn as (...values: unknown[]) => unknown)(...args),\n);\n\nexport const safeConsoleDebug = isolateDiagnostic((...args) =>\n // eslint-disable-next-line no-console -- best-effort development diagnostics\n (console.debug as (...values: unknown[]) => unknown)(...args),\n);\n","/**\n * The build profile: which features are compiled into the inline runtime.\n *\n * `scripts/build-runtime.ts` builds the runtime twice — once with everything,\n * once with `__LEAN_BUILD__` defined — and the generator embeds whichever the\n * page asked for. The flag is read into a constant so esbuild folds it and\n * drops the branch, and with it every module only that branch referenced. In\n * the programmatic client the define is absent, so nothing is dropped there.\n *\n * A profile is a byte trade, never a behaviour trade in disguise: a page that\n * needs what the lean profile left out is told so (LP0104) instead of quietly\n * doing nothing.\n *\n * The flag itself is not exported. Each guard site reads `__LEAN_BUILD__`\n * directly, in expression position, because that is the only shape esbuild\n * folds — `src/types/build-flags.d.ts` explains why, with what was measured.\n */\n\nimport { safeConsoleWarn } from './diagnostics';\n\n/** What the lean profile leaves out, in the words the documentation uses. */\nexport type OmittedFeature =\n | 'structural arrays'\n | 'array templates'\n | 'server-rendered fragments'\n | 'route refreshes'\n | 'screen-reader announcements'\n | 'auto-binding';\n\nconst HOW_TO_GET_IT: Readonly<Record<OmittedFeature, string>> = {\n 'structural arrays': 'data-payload-type=\"array\" and keyed lists',\n 'array templates': 'data-payload-array-template',\n 'server-rendered fragments': 'data-payload-fragment boundaries',\n 'route refreshes': 'data-payload-strategy=\"route\" and bindings in <head>',\n 'screen-reader announcements': 'the aria-live region',\n 'auto-binding': \"autoBind: 'unique'\",\n};\n\nconst reported = new Set<OmittedFeature>();\n\n/**\n * Report once per feature and per page. The markup is the cause and it does not\n * change between updates, so a second message would only be noise.\n */\nexport function reportOmittedFeature(feature: OmittedFeature): void {\n if (reported.has(feature)) return;\n reported.add(feature);\n safeConsoleWarn(\n `[live-preview] LP0104: this page carries the lean runtime, which leaves out ${feature} ` +\n `(${HOW_TO_GET_IT[feature]}). The elements are left as the server rendered them. ` +\n `Remove \\`runtime: LEAN_RUNTIME\\` to get the full runtime.`,\n );\n}\n","/**\n * What the runtime builds around itself before it starts: the screen-reader\n * announcer, and where the `ready` handshake goes.\n *\n * Apart in this module for two reasons. The announcer is the one dependency the\n * lean profile leaves out, and the guard that drops it has to sit in expression\n * position at the seam (`src/types/build-flags.d.ts`); and `lifecycle.ts` is the\n * runtime's own lifecycle, which stays readable only if the wiring around it\n * lives next door rather than inside.\n */\n\nimport { A11yAnnouncer } from './a11y';\nimport { MessageBus } from './message-bus';\nimport { reportOmittedFeature } from './profile';\nimport type { RuntimeOptions } from './runtime-options';\n\n/**\n * The announcer and its locale table are ~800 bytes gzip the lean profile does\n * without; a page that asked for announcements is told instead (./profile).\n */\nexport function createA11y(options: RuntimeOptions): A11yAnnouncer | null {\n return typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__\n ? refuseA11y(options)\n : buildA11y(options);\n}\n\nfunction refuseA11y(options: RuntimeOptions): null {\n if (options.enableA11y !== false) reportOmittedFeature('screen-reader announcements');\n return null;\n}\n\nfunction buildA11y(options: RuntimeOptions): A11yAnnouncer | null {\n if (options.enableA11y === false) return null;\n const root = options.root;\n const targetDocument =\n root === undefined ? undefined : isDocumentRoot(root) ? root : root.ownerDocument;\n return new A11yAnnouncer(options.a11yLocale, targetDocument);\n}\n\n/** Node types are stable across realms; global constructors are not. */\nfunction isDocumentRoot(root: Document | Element): root is Document {\n return root.nodeType === 9;\n}\n\n/** The framing or opening window, which is the only one that asked for a preview. */\nexport function defaultSendReady(origins: readonly string[]): void {\n if (typeof window === 'undefined') return;\n const targets: Window[] = [];\n if (window.parent !== window) targets.push(window.parent);\n if (window.opener instanceof Window) targets.push(window.opener);\n MessageBus.sendReady(targets, origins);\n}\n","/** Drops `undefined`-valued keys, so a literal built from optional inputs satisfies `exactOptionalPropertyTypes`. */\n\nexport type DefinedOnly<T> = { readonly [K in keyof T]-?: Exclude<T[K], undefined> };\n\nexport function definedOnly<T extends object>(source: T): DefinedOnly<T> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(source)) {\n if (value !== undefined) result[key] = value;\n }\n return result as DefinedOnly<T>;\n}\n","/**\n * Flattens a parsed field schema into dotted paths (`hero.title`,\n * `sections.*.heading`). Named tabs in Payload 2 own data beneath their name;\n * rows, collapsibles and the older custom tab lookup retain flat inner paths.\n * Separate flat and fully named passes prevent nested tabs multiplying paths.\n */\n\nimport type {\n PayloadBlockSchema,\n PayloadFieldSchema,\n PayloadFieldType,\n} from '@/types/payload-protocol';\n\nexport type SchemaIndex = ReadonlyMap<string, PayloadFieldSchema>;\n\nconst STRUCTURAL_TYPES: ReadonlySet<PayloadFieldType> = new Set<PayloadFieldType>([\n 'tabs',\n 'row',\n 'collapsible',\n]);\n\nexport function buildSchemaIndex(\n schemas: readonly PayloadFieldSchema[],\n basePath = '',\n): SchemaIndex {\n const out = new Map<string, PayloadFieldSchema>();\n walk(schemas, basePath, out, false);\n walk(schemas, basePath, out, true);\n return out;\n}\n\nfunction walk(\n schemas: readonly PayloadFieldSchema[],\n basePath: string,\n out: Map<string, PayloadFieldSchema>,\n namedTabs: boolean,\n): void {\n for (const schema of schemas) {\n if (STRUCTURAL_TYPES.has(schema.type)) {\n const fields = schema.fields;\n if (fields) {\n const path =\n namedTabs && schema.type === 'tabs'\n ? basePath === ''\n ? schema.name\n : `${basePath}.${schema.name}`\n : basePath;\n walk(fields, path, out, namedTabs);\n }\n continue;\n }\n const path = basePath === '' ? schema.name : `${basePath}.${schema.name}`;\n out.set(path, schema);\n if (schema.type === 'group') {\n if (schema.fields) walk(schema.fields, path, out, namedTabs);\n } else if (schema.type === 'array' && schema.fields) {\n walk(schema.fields, `${path}.*`, out, namedTabs);\n } else if (schema.type === 'blocks' && schema.blocks) {\n for (const block of schema.blocks) {\n walk(block.fields, `${path}.*.${block.slug}`, out, namedTabs);\n }\n }\n }\n}\n\n/** Schema for `fieldPath`; numeric segments are retried as `*` wildcards. */\nexport function lookupSchema(\n index: SchemaIndex,\n fieldPath: string,\n): PayloadFieldSchema | undefined {\n if (index.has(fieldPath)) return index.get(fieldPath);\n const wildcardPath = fieldPath.replace(/\\.\\d+(?=\\.|$)/g, '.*');\n if (index.has(wildcardPath)) return index.get(wildcardPath);\n return undefined;\n}\n\nexport function lookupBlockSchema(\n index: SchemaIndex,\n blocksFieldPath: string,\n blockType: string,\n): PayloadBlockSchema | undefined {\n const schema = lookupSchema(index, blocksFieldPath);\n if (!schema?.blocks) return undefined;\n return schema.blocks.find((b) => b.slug === blockType);\n}\n","/**\n * Structural diff for array and blocks fields. Items with an `id` are keyed\n * (moves are detected); without ids the diff is positional.\n * @internal\n */\n\nexport type ArrayPatch =\n | { readonly kind: 'insert'; readonly index: number; readonly value: unknown }\n | { readonly kind: 'remove'; readonly index: number; readonly value: unknown }\n | {\n readonly kind: 'move';\n readonly from: number;\n readonly to: number;\n readonly value: unknown;\n }\n | { readonly kind: 'update'; readonly index: number; readonly value: unknown }\n | {\n readonly kind: 'replace';\n readonly index: number;\n readonly oldValue: unknown;\n readonly value: unknown;\n };\n\nfunction getId(item: unknown): string | number | undefined {\n if (typeof item !== 'object' || item === null) return undefined;\n const id = (item as Record<string, unknown>)['id'];\n if (typeof id === 'string' || typeof id === 'number') return id;\n return undefined;\n}\n\nfunction getBlockType(item: unknown): string | undefined {\n if (typeof item !== 'object' || item === null) return undefined;\n const blockType = (item as Record<string, unknown>)['blockType'];\n return typeof blockType === 'string' ? blockType : undefined;\n}\n\n/** Patches that turn `prev` into `next`; a changed `blockType` is a `replace`, never an `update`. */\nexport function diffArray(\n prev: readonly unknown[],\n next: readonly unknown[],\n): readonly ArrayPatch[] {\n const haveIds = next.every((item) => getId(item) !== undefined);\n if (haveIds) return diffById(prev, next);\n return diffByPosition(prev, next);\n}\n\nfunction diffById(prev: readonly unknown[], next: readonly unknown[]): readonly ArrayPatch[] {\n const patches: ArrayPatch[] = [];\n const prevIndexById = new Map<string | number, number>();\n for (let i = 0; i < prev.length; i += 1) {\n const id = getId(prev[i]);\n if (id !== undefined) prevIndexById.set(id, i);\n }\n\n const consumedFromPrev = new Set<number>();\n for (let to = 0; to < next.length; to += 1) {\n const item = next[to];\n const id = getId(item);\n if (id === undefined) {\n patches.push({ kind: 'insert', index: to, value: item });\n continue;\n }\n const from = prevIndexById.get(id);\n if (from === undefined) {\n patches.push({ kind: 'insert', index: to, value: item });\n continue;\n }\n consumedFromPrev.add(from);\n const prevItem = prev[from];\n if (getBlockType(prevItem) !== getBlockType(item)) {\n patches.push({ kind: 'replace', index: to, oldValue: prevItem, value: item });\n continue;\n }\n if (from !== to) {\n patches.push({ kind: 'move', from, to, value: item });\n }\n if (!shallowEqual(prevItem, item)) {\n patches.push({ kind: 'update', index: to, value: item });\n }\n }\n\n for (let i = 0; i < prev.length; i += 1) {\n if (consumedFromPrev.has(i)) continue;\n patches.push({ kind: 'remove', index: i, value: prev[i] });\n }\n return patches;\n}\n\nfunction diffByPosition(prev: readonly unknown[], next: readonly unknown[]): readonly ArrayPatch[] {\n const patches: ArrayPatch[] = [];\n const min = Math.min(prev.length, next.length);\n for (let i = 0; i < min; i += 1) {\n if (!shallowEqual(prev[i], next[i])) {\n patches.push({ kind: 'update', index: i, value: next[i] });\n }\n }\n if (next.length > prev.length) {\n for (let i = prev.length; i < next.length; i += 1) {\n patches.push({ kind: 'insert', index: i, value: next[i] });\n }\n }\n if (prev.length > next.length) {\n for (let i = next.length; i < prev.length; i += 1) {\n patches.push({ kind: 'remove', index: i, value: prev[i] });\n }\n }\n return patches;\n}\n\n// Shallow on purpose: any nested reference change is an update, and the\n// renderer reconciles deeper differences itself.\nfunction shallowEqual(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;\n const aRec = a as Record<string, unknown>;\n const bRec = b as Record<string, unknown>;\n const aKeys = Object.keys(aRec);\n const bKeys = Object.keys(bRec);\n if (aKeys.length !== bKeys.length) return false;\n for (const key of aKeys) {\n if (!Object.is(aRec[key], bRec[key])) return false;\n }\n return true;\n}\n","/**\n * Payload field type → renderer name. Structural containers the walker has\n * already flattened, and types without a display, map to `text` so a new\n * Payload field type never leaves a binding without a renderer.\n */\n\nimport type { FieldType } from '@core/types';\nimport type { PayloadFieldType } from '@/types/payload-protocol';\n\nconst MAP: Readonly<Record<PayloadFieldType, FieldType>> = {\n text: 'text',\n textarea: 'textarea',\n richText: 'richText',\n email: 'email',\n number: 'number',\n checkbox: 'checkbox',\n date: 'date',\n select: 'select',\n radio: 'radio',\n array: 'array',\n blocks: 'blocks',\n group: 'text',\n tabs: 'text',\n row: 'text',\n collapsible: 'text',\n relationship: 'relationship',\n upload: 'upload',\n point: 'text',\n json: 'text',\n code: 'text',\n ui: 'text',\n};\n\n/** `undefined` for a type not in the table, so the caller can fall back to the DOM attribute. */\nexport function payloadTypeToRenderer(type: string): FieldType | undefined {\n if (Object.prototype.hasOwnProperty.call(MAP, type)) {\n return MAP[type as PayloadFieldType];\n }\n return undefined;\n}\n","/**\n * URL safety: the one scheme allow-list the runtime, the client and the\n * sanitizer share. Empty strings are not safe (`<a href=\"\">` is never emitted).\n */\n\nconst SAFE_PROTOCOLS: ReadonlySet<string> = new Set(['http:', 'https:', 'mailto:', 'tel:']);\n\nconst RELATIVE_PATH = /^(?:\\.{1,2}\\/|[a-zA-Z0-9_-]+\\/?)/;\n\n// The URL parser treats `\\` as `/` for special schemes, so `/\\evil.com`\n// resolves to another origin rather than to a same-origin path.\nconst PROTOCOL_RELATIVE = /^[\\\\/]{2}/;\n\n/** The URL parser drops these anywhere in the input before it looks at anything. */\nconst PARSER_IGNORED = /[\\t\\n\\r]/g;\n\n/**\n * What is dropped from a value before it is read for a scheme: JavaScript's\n * whitespace and DOMPurify's `ATTR_WHITESPACE` together. That is ASCII\n * controls and spaces, the no-break spaces, the byte-order mark and the Unicode\n * space and format ranges. The URL parser keeps most of these, so `java\n * script:` is a relative path to it; a sanitizer in front of an older parser\n * reads a scheme through the gaps, and the union stays at least as strict as\n * each of the two.\n */\n/* eslint-disable no-control-regex -- the class takes in DOMPurify's, which has controls */\nconst SCHEME_GAPS = /[\\s\\u0000-\\u001f\\u180e\\u2000-\\u2029]/g;\n/* eslint-enable no-control-regex */\nconst SCHEME = /^([a-z][a-z0-9+.-]*):/i;\n\n/** Whether `value`, with the gaps closed, starts with a scheme the allow-list does not hold. */\nfunction spellsUnsafeScheme(value: string): boolean {\n const scheme = SCHEME.exec(value.replace(SCHEME_GAPS, ''))?.[1];\n return scheme !== undefined && !SAFE_PROTOCOLS.has(`${scheme.toLowerCase()}:`);\n}\n\n/** `true` only for absolute `http`/`https`/`mailto`/`tel` URLs, protocol-relative URLs, paths, `#`/`?` fragments and relative paths. */\nexport function isSafeUrl(url: unknown): boolean {\n if (typeof url !== 'string') return false;\n const trimmed = url.trim().replace(PARSER_IGNORED, '');\n if (trimmed.length === 0) return false;\n if (trimmed.startsWith('#') || trimmed.startsWith('?')) return true;\n if (PROTOCOL_RELATIVE.test(trimmed)) return true;\n if (trimmed.startsWith('/')) return true;\n try {\n const parsed = new URL(trimmed);\n return SAFE_PROTOCOLS.has(parsed.protocol);\n } catch {\n return RELATIVE_PATH.test(trimmed) && !spellsUnsafeScheme(trimmed);\n }\n}\n\n/** Whether a URL points at another HTTP(S) origin, protocol-relative forms included, and so needs `noopener` hardening; every URL these two patterns match is one `isSafeUrl` admits. */\nexport function isExternalHttpUrl(url: string): boolean {\n const trimmed = url.trim().replace(PARSER_IGNORED, '');\n return /^https?:\\/\\//i.test(trimmed) || PROTOCOL_RELATIVE.test(trimmed);\n}\n\n/** The safe scheme set, for tests and introspection. */\nexport const SAFE_URL_PROTOCOLS: ReadonlySet<string> = SAFE_PROTOCOLS;\n","/**\n * Policed writes for `data-payload-attribute` bindings. The value is\n * remote-controlled, so event handlers, `style`, `srcdoc`, `formaction`/`form`,\n * `id`/`name` (DOM clobbering) and `srcset` (multi-URL syntax) are refused,\n * URL-bearing attributes must pass `isSafeUrl`, and non-scalars never write.\n */\n\nimport { isSafeUrl } from '@security/url-validator';\n\nconst BLOCKED_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'style',\n 'srcdoc',\n 'formaction',\n 'form',\n 'id',\n 'name',\n 'is',\n 'srcset',\n 'imagesrcset',\n]);\n\nconst URL_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'href',\n 'src',\n 'poster',\n 'cite',\n 'action',\n 'xlink:href',\n 'data',\n]);\n\nexport type AttributeApplyResult = 'applied' | 'blocked';\n\n/**\n * Whether this package may write an attribute of this name at all — event\n * handlers, `style`, the two DOM-clobbering names and the multi-URL ones\n * excluded. One rule, two callers: the binding below writes a remote value into\n * it, and the array renderers copy one from the page's own markup onto an item\n * they rebuilt (`src/core/array-template.ts`).\n */\nexport function isWritableAttribute(name: string): boolean {\n return !name.startsWith('on') && !BLOCKED_ATTRIBUTES.has(name);\n}\n\n/** Returns `'blocked'` without touching the DOM when the write is refused. */\nexport function applyAttributeBinding(\n element: Element,\n attribute: string,\n value: unknown,\n): AttributeApplyResult {\n const name = attribute.toLowerCase().trim();\n if (name.length === 0) return 'blocked';\n if (!isWritableAttribute(name)) return 'blocked';\n\n if (value === null || value === undefined) {\n element.removeAttribute(name);\n return 'applied';\n }\n if (typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean') {\n return 'blocked';\n }\n const stringValue = String(value);\n\n if (URL_ATTRIBUTES.has(name) && !isSafeUrl(stringValue)) return 'blocked';\n\n element.setAttribute(name, stringValue);\n return 'applied';\n}\n","/**\n * Stable identity for a field value, so two messages can be compared without\n * rendering either — every keystroke ships the whole document, of which one\n * field changed. Equality is structural (plain, unsorted JSON): Payload\n * allocates a fresh object graph per message, so reference identity would skip\n * nothing. A value JSON cannot represent has no identity and counts as\n * changed, which is the safe direction — a false \"equal\" leaves a stale\n * binding, a false \"different\" only renders once more.\n */\n\n/** Past this size the comparison is no longer obviously cheaper than the render it avoids. */\nexport const IDENTITY_SIZE_LIMIT = 64 * 1024;\n\n/**\n * Canonical string for `value`, or `undefined` when it cannot have one.\n * Primitives carry a type tag, so `1` and `'1'` differ even though a text\n * renderer prints them alike — that is the renderer's decision, not this one.\n */\nexport function valueIdentity(value: unknown): string | undefined {\n switch (typeof value) {\n case 'string':\n return value.length > IDENTITY_SIZE_LIMIT ? undefined : `s:${value}`;\n case 'number':\n // Object.is semantics at the top level: NaN equals NaN, -0 is not 0.\n return `n:${Object.is(value, -0) ? '-0' : String(value)}`;\n case 'boolean':\n return `b:${value ? '1' : '0'}`;\n case 'bigint':\n return `i:${String(value)}`;\n case 'undefined':\n return 'u';\n case 'object': {\n if (value === null) return 'z';\n let json: string;\n try {\n // Throws on a cycle and on a nested BigInt; both mean \"no identity\".\n json = JSON.stringify(value);\n } catch {\n return undefined;\n }\n return json.length > IDENTITY_SIZE_LIMIT ? undefined : `o:${json}`;\n }\n case 'symbol':\n case 'function':\n return undefined;\n }\n}\n","/**\n * What the runtime does about a patch it knows will not reach what the server\n * would have drawn: a renderer that refused the value, a Lexical block whose\n * markup the write had to drop. The finding is made where the write happens;\n * the policy and the ledger live here, so the pipeline can hand the region to a\n * strategy once the flush is over instead of leaving the page worse off.\n *\n * A changed field with no binding at all is the same judgement made one step\n * earlier — there is no element to write to — and `StrategyRunner` reaches it\n * from `unbound-fields.ts` before anything is scheduled.\n */\n\nimport type { RuntimeDeps, RuntimeState } from './runtime-state';\nimport type { CachedElement } from './types';\nimport { valueIdentity } from './value-identity';\n\n/**\n * `'ignore'` keeps the degraded patch, which is what 2.0 shipped under the\n * name `onUnboundChange: 'ignore'`. `'warn'` keeps it and says so (LP0411).\n * `'escalate'`, the default, asks a server to draw the region instead: the\n * fragment strategy when a boundary covers the binding, the route otherwise.\n *\n * Without a strategy to escalate to, every mode keeps the patch. A page that\n * cannot ask a server for better markup is not helped by being told twice.\n */\nexport type UnfaithfulPatchMode = 'ignore' | 'warn' | 'escalate';\n\n/**\n * Both spellings of the option; the 2.0 name stays until 3.0. Explicitly\n * `| undefined`, because one caller reads them out of the inline script's\n * positional tuple, where an omitted slot is exactly that.\n */\nexport interface UnfaithfulPatchOptions {\n readonly onUnfaithfulPatch?: UnfaithfulPatchMode | undefined;\n readonly onUnboundChange?: 'ignore' | 'route' | undefined;\n}\n\n/**\n * The 2.0 name maps onto the new one without loss: `'route'` was this option's\n * escalation and `'ignore'` its opt-out. Only an omitted option takes the new\n * default — a project that wrote `'ignore'` down chose it, and keeps it.\n */\nexport function resolveUnfaithfulPatchMode(options: UnfaithfulPatchOptions): UnfaithfulPatchMode {\n // `'ignore'` is the only thing the old name can still say that the new\n // default does not: its `'route'` and its absence both mean escalate now.\n return (\n options.onUnfaithfulPatch ?? (options.onUnboundChange === 'ignore' ? 'ignore' : 'escalate')\n );\n}\n\n/** The value an element was last reported or handed over with, and when. */\nexport interface UnfaithfulReport {\n readonly identity: string | undefined;\n readonly at: number;\n}\n\n/** How long an element waits before a new value of it is escalated again. */\nconst ESCALATE_AGAIN_MS = 1000;\n\n/**\n * Record one binding this revision could not patch faithfully, and queue it for\n * the escalation the flush will run.\n *\n * Counted, and said as LP0411, once per element: the cause is the markup or the\n * value's shape, so the next message would report the same thing. Under\n * `'escalate'` a later revision with a new value is handed over again, since\n * the region the server drew still shows the old one: at most once a second\n * per element, so typing is not a refresh per keystroke, and never with the\n * value it was last handed over with, which the re-apply after a route render\n * hands the renderer again. A value held back by that second is handed over by\n * the first report after it, the re-apply included.\n *\n * Counted under every mode, before the mode decides anything: `inspect()` has\n * to be able to say \"three patches fell short, none was escalated\" on the page\n * whose owner chose `'ignore'` as much as on the one that has no strategy.\n */\nexport function reportUnfaithfulPatch(\n deps: RuntimeDeps,\n state: RuntimeState,\n target: CachedElement,\n reason: string,\n value: unknown,\n): void {\n const mode = deps.onUnfaithfulPatch;\n const last = state.reportedUnfaithful.get(target.element);\n const identity = valueIdentity(value);\n const now = Date.now();\n const repeated =\n last !== undefined &&\n (mode !== 'escalate' ||\n identity === undefined ||\n identity === last.identity ||\n now - last.at < ESCALATE_AGAIN_MS);\n // Kept, not queued: under 'warn' and 'ignore', and for a repeat. The\n // revision does not show the field (ADR 0023).\n if (repeated || mode !== 'escalate') {\n state.display.shortfall(state.activeUpdate, { kind: 'unfaithful', field: target.fieldName });\n }\n if (repeated) return;\n state.reportedUnfaithful.set(target.element, { identity, at: now });\n if (last === undefined) {\n state.unfaithfulCount += 1;\n state.unfaithfulFields.add(target.fieldName);\n if (mode === 'ignore') return;\n if (mode === 'warn') {\n deps.warn(`[live-preview] LP0411: \"${target.fieldName}\" ${reason}`);\n return;\n }\n }\n deps.log('LP0411', target.fieldName, reason);\n state.unfaithfulPatches.push(target);\n}\n\n/**\n * Record a changed field the page has no binding for: the same judgement one\n * step earlier, where there is no element to write to and so nothing to queue.\n * The whole route is the only answer to it, and `StrategyRunner` asks for that\n * itself.\n *\n * Once per field name, for the reason LP0411 is once per element: the cause is\n * the markup, so the next keystroke into the same field would report the same\n * thing. Counted under every mode and on a page with no strategy at all —\n * that page is the one `inspect().fidelity` was written for, and it was the one\n * page the reading said nothing about.\n *\n * No message of its own: LP0203 (LP0201 when the value is empty) already names\n * the field, once, from the same rule. The return value says whether this was the first time, so an escalation\n * is counted against the findings it answered rather than against a keystroke.\n */\nexport function reportUnboundChange(state: RuntimeState, fieldName: string): boolean {\n if (state.unfaithfulFields.has(fieldName)) return false;\n state.unfaithfulFields.add(fieldName);\n state.unfaithfulCount += 1;\n return true;\n}\n\n/**\n * Renderers that turn a stored value into a presentation, so the template that\n * printed the same field had to choose one too. A `text` binding whose content\n * differs is an edit; a `date`, `number` or `checkbox` binding whose content\n * differs is two answers to the question the runtime cannot ask —\n * `data-payload-format` is where the answer belongs.\n */\nconst FORMATTING_RENDERERS: ReadonlySet<string> = new Set(['date', 'number', 'checkbox']);\n\n/** Cap on either reading in the message: a diagnostic is a pointer, not a dump. */\nconst EXCERPT = 40;\n\n/**\n * What the element shows, when a difference there would be worth reporting —\n * `undefined` when it would not, so an ordinary page pays one `Set` lookup per\n * binding and reads no DOM at all.\n *\n * Called before the renderer writes, and only for the first write to a\n * binding: after that the element holds the runtime's own output, and\n * comparing it with the runtime's next output says nothing about the template.\n */\nexport function watchServerFormatting(\n deps: RuntimeDeps,\n state: RuntimeState,\n target: CachedElement,\n type: string,\n): string | undefined {\n if (deps.onUnfaithfulPatch === 'ignore') return undefined;\n if (target.format !== undefined || !FORMATTING_RENDERERS.has(type)) return undefined;\n if (state.checkedServerFormat.has(target.element)) return undefined;\n state.checkedServerFormat.add(target.element);\n const shown = shownValue(target.element);\n // An empty anchor lost nothing, and the boundary case (LP0201) is elsewhere.\n return shown.trim().length > 0 ? shown : undefined;\n}\n\n/**\n * Called once the renderer has written: both readings of the same value now\n * exist, and if they differ the page no longer matches the server.\n *\n * It reports and stops there. Escalating would hand the region to the route,\n * which redraws the template's format, which the re-apply overwrites again —\n * measured under Z3 — so the honest move is to name the two candidates and the\n * attribute that settles either of them.\n */\nexport function reportServerFormatting(\n deps: RuntimeDeps,\n target: CachedElement,\n before: string,\n): void {\n const after = shownValue(target.element);\n if (after === before) return;\n deps.warn(\n `[live-preview] LP0412: \"${target.fieldName}\" showed ${excerpt(before)}, the patch wrote ` +\n `${excerpt(after)} — either an edit that arrived before the preview connected, or a ` +\n 'template that formats this value differently. Set data-payload-format to match it.',\n );\n}\n\n/** The channel the date, number and checkbox renderers write. */\nfunction shownValue(element: Element): string {\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n return (element as HTMLInputElement).value;\n }\n return element.textContent;\n}\n\nfunction excerpt(value: string): string {\n const text = value.trim();\n return JSON.stringify(text.length > EXCERPT ? `${text.slice(0, EXCERPT)}…` : text);\n}\n","/**\n * Public renderer callbacks return `void`, but a JavaScript implementation may\n * return anything. Only callbacks marked here may reserve exact `false` as\n * \"no write\", so a custom renderer's incidental boolean cannot change the\n * lifecycle's applied counts.\n */\n\ntype Callback = (...args: never[]) => unknown;\n\nconst noWriteCallbacks = new WeakSet<Callback>();\n\n/** Mark a package-owned callback whose exact `false` return means no write. */\nexport function markNoWriteCallback<T extends Callback>(callback: T): T {\n noWriteCallbacks.add(callback);\n return callback;\n}\n\n/** Whether `callback` owns the internal exact-false sentinel contract. */\nexport function usesNoWriteOutcome(callback: Callback): boolean {\n return noWriteCallbacks.has(callback);\n}\n\n/** Check a renderer object without detaching its public method at the call site. */\nexport function rendererUsesNoWriteOutcome(renderer: { readonly render: Callback }): boolean {\n return noWriteCallbacks.has(renderer.render);\n}\n","/**\n * The one per-message diff of top-level field values. Strategies, dependency\n * invalidation and reveal all consume it, so \"changed\" means the same thing\n * everywhere.\n */\n\nimport type { DependencyMap } from './dependencies';\nimport { valueIdentity } from './value-identity';\n\nexport interface FieldChanges {\n /** Fields whose value differs from the previous message; every field on the first one. */\n readonly changed: ReadonlySet<string>;\n /** Dependents of changed fields, per the dependency map. */\n readonly invalidated: ReadonlySet<string>;\n /**\n * The first message of a connection, where `changed` means \"everything the\n * document has\" rather than \"what the editor just did\". A caller that acts on\n * a change rather than rendering one has to sit this message out.\n */\n readonly baseline: boolean;\n}\n\nexport class FieldChangeTracker {\n private previous: Map<string, string | undefined> | null = null;\n private lastFields: Readonly<Record<string, unknown>> | undefined;\n private priorFields: Readonly<Record<string, unknown>> | undefined;\n\n /**\n * Keep the message's values, not only their identities, so the one before\n * the last diff can be compared below the top level (ADR 0022). Off by\n * default: it holds one more document.\n */\n keepValues = false;\n\n /** The fields of the message before the last diff, while `keepValues` is on. */\n get previousFields(): Readonly<Record<string, unknown>> | undefined {\n return this.priorFields;\n }\n\n get isBaseline(): boolean {\n return this.previous === null;\n }\n\n /** Diff `fields` against the previous message and remember them for the next call. */\n diff(fields: Readonly<Record<string, unknown>>, dependencies: DependencyMap): FieldChanges;\n diff(\n fields: Readonly<Record<string, unknown>>,\n dependencies: DependencyMap,\n isCurrent: () => boolean,\n ): FieldChanges | null;\n diff(\n fields: Readonly<Record<string, unknown>>,\n dependencies: DependencyMap,\n isCurrent: () => boolean = alwaysCurrent,\n ): FieldChanges | null {\n const previous = this.previous;\n const baseline = previous === null;\n const next = new Map<string, string | undefined>();\n const changed = new Set<string>();\n const entries = Object.entries(fields);\n if (!isCurrent()) return null;\n for (const [name, value] of entries) {\n const identity = valueIdentity(value);\n if (!isCurrent()) return null;\n next.set(name, identity);\n // A value without an identity always counts as changed: rendering once\n // more is cheap, a stale binding is not.\n if (previous === null || identity === undefined || previous.get(name) !== identity) {\n changed.add(name);\n }\n }\n if (previous !== null) {\n for (const name of previous.keys()) if (!next.has(name)) changed.add(name);\n }\n const invalidated = new Set<string>();\n const dependencyEntries = Object.entries(dependencies);\n if (!isCurrent()) return null;\n for (const [source, dependents] of dependencyEntries) {\n if (!changed.has(source)) continue;\n for (const dependent of dependents) {\n invalidated.add(dependent);\n if (!isCurrent()) return null;\n }\n }\n if (!isCurrent()) return null;\n this.previous = next;\n this.priorFields = this.keepValues ? this.lastFields : undefined;\n this.lastFields = this.keepValues ? fields : undefined;\n return { changed, invalidated, baseline };\n }\n\n reset(): void {\n this.previous = null;\n this.lastFields = undefined;\n this.priorFields = undefined;\n }\n}\n\nfunction alwaysCurrent(): boolean {\n return true;\n}\n","/**\n * Field-path resolution for bindings and sibling-field metadata, prototype-safe,\n * and the identity of everything one binding renders — which is the same\n * question one step later, because the siblings are part of the answer.\n */\n\nimport type { CachedElement } from './types';\nimport { valueIdentity } from './value-identity';\n\nconst BLOCKED_KEYS: ReadonlySet<string> = new Set(['__proto__', 'prototype', 'constructor']);\n\n/**\n * Resolve a dotted field path, preferring a `_<locale>` suffix when one is\n * active. Prototype-chain properties and pollution-prone segments never resolve.\n */\nexport function resolveFieldValue(\n fields: Record<string, unknown>,\n path: string,\n locale: string | undefined,\n preferLocale = false,\n): unknown {\n if (preferLocale && locale !== undefined) {\n const localized = readOwn(fields, `${path}_${locale}`);\n if (localized !== undefined) return localized;\n }\n const direct = readOwn(fields, path);\n if (direct !== undefined) return direct;\n\n if (path.includes('.')) {\n let current: unknown = fields;\n let resolved = true;\n for (const segment of path.split('.')) {\n if (BLOCKED_KEYS.has(segment) || current === null || typeof current !== 'object') {\n resolved = false;\n break;\n }\n current = readOwn(current as Record<string, unknown>, segment);\n if (current === undefined) {\n resolved = false;\n break;\n }\n }\n if (resolved) return current;\n }\n\n return locale === undefined ? undefined : readOwn(fields, `${path}_${locale}`);\n}\n\nfunction readOwn(object: Record<string, unknown>, key: string): unknown {\n if (BLOCKED_KEYS.has(key) || !Object.prototype.hasOwnProperty.call(object, key)) {\n return undefined;\n }\n return object[key];\n}\n\n/**\n * The value a binding renders. A binding that names its own locale reads that\n * locale and nothing else; one that does not falls back to the message locale.\n */\nexport function bindingValue(\n fields: Record<string, unknown>,\n target: { readonly locale?: string | undefined },\n fieldName: string,\n fallbackLocale: string | undefined,\n): unknown {\n return resolveFieldValue(\n fields,\n fieldName,\n target.locale ?? fallbackLocale,\n target.locale !== undefined,\n );\n}\n\n/**\n * Identity of everything a binding renders: its value, any sibling\n * href/src/alt fields, and the format and locale the renderer writes it in.\n */\nexport function bindingIdentity(\n target: CachedElement,\n value: unknown,\n fields: Record<string, unknown>,\n locale: string | undefined,\n): string | undefined {\n const own = valueIdentity(value);\n if (own === undefined) return undefined;\n const siblings = [target.hrefField, target.srcField, target.altField];\n // The same 12.34 is a new write under `number:2` or `de-DE`. JSON keeps the\n // two apart from each other and from the value, whatever they contain.\n let combined = JSON.stringify([target.format, target.locale ?? locale]) + own;\n for (const sibling of siblings) {\n if (sibling === undefined || sibling.length === 0) continue;\n const resolved = bindingValue(fields, target, sibling, locale);\n const identity = valueIdentity(resolved);\n if (identity === undefined) return undefined;\n combined += `|${sibling}=${identity}`;\n }\n return combined;\n}\n","/**\n * How a bound region is brought up to date: the runtime patches it, a server\n * renders a `data-payload-fragment` boundary from the unsaved form state, or\n * the whole route refreshes. Core carries only the seam — which boundaries a\n * strategy owns and what it may do — so a patch-only page pays for nothing\n * more; the orchestration lives in `payload-live-preview/fragment`.\n */\nimport type { DiagnosticCode } from './diagnostic-codes';\nimport type { CachedElement } from './types';\nimport type { OwnerScope } from './unbound-fields';\n\n/** What produced an update: the runtime's DOM patching, a server-rendered fragment, or a route refresh. */\nexport type UpdateSource = 'patch' | 'fragment' | 'route';\n\n/** Marks a server-rendered boundary; the value is the registry id the server may render. @internal */\nexport const FRAGMENT_ATTRIBUTE = 'data-payload-fragment';\n/** Distinguishes several boundaries of one registry id; unique among siblings. @internal */\nexport const FRAGMENT_KEY_ATTRIBUTE = 'data-payload-fragment-key';\n\n/** The nearest fragment boundary enclosing `element` (the element itself included). */\nexport function enclosingFragment(element: Element): Element | null {\n return element.closest(`[${FRAGMENT_ATTRIBUTE}]`);\n}\n\n/**\n * Where a render planned for `planned` lands. A host component that re-renders\n * its region while the render is in flight swaps the element and keeps the\n * identity, so a boundary no longer in the document stands for the one that\n * is: the single connected boundary with its id and key that `inScope` admits.\n * Two candidates name no single region, and none means it is gone (H06).\n */\nexport function liveBoundary(\n root: Document | Element,\n planned: Element,\n inScope: (boundary: Element) => boolean,\n): Element | undefined {\n if (planned.isConnected) return planned;\n const id = planned.getAttribute(FRAGMENT_ATTRIBUTE);\n const key = planned.getAttribute(FRAGMENT_KEY_ATTRIBUTE);\n let found: Element | undefined;\n for (const candidate of root.querySelectorAll(`[${FRAGMENT_ATTRIBUTE}]`)) {\n if (candidate.getAttribute(FRAGMENT_ATTRIBUTE) !== id) continue;\n if (candidate.getAttribute(FRAGMENT_KEY_ATTRIBUTE) !== key || !inScope(candidate)) continue;\n if (found !== undefined) return undefined;\n found = candidate;\n }\n return found;\n}\n\n/** One revision, as a strategy sees it, with the runtime capabilities it may use. */\nexport interface FragmentContext {\n readonly root: ParentNode;\n readonly revision: number;\n readonly receivedAt: number;\n readonly fields: Readonly<Record<string, unknown>>;\n readonly locale: string | undefined;\n readonly collectionSlug: string | undefined;\n readonly globalSlug: string | undefined;\n /** Aborted when a newer revision arrives or the runtime stops. */\n readonly signal: AbortSignal;\n /** Whether this revision is still the current one. */\n readonly isCurrent: () => boolean;\n /** Morph server-rendered HTML into a boundary; no-op after supersession (Trusted Types and the keyed morph apply). */\n readonly morph: (boundary: Element, html: string) => void;\n /** Patch the boundary's owned bindings from this revision; no-op after supersession. */\n readonly patch: (boundary: Element) => void;\n /** Debug log through the runtime's logger, with the diagnostic code. */\n readonly log: (code: DiagnosticCode, detail: string) => void;\n /** Report a boundary rendered. */\n readonly rendered: (boundary: Element, id: string, key: string | undefined) => void;\n /** Report a boundary failed and patched instead; emits the `error` and `fragmentRender` events. */\n readonly failed: (\n boundary: Element,\n id: string,\n key: string | undefined,\n code: DiagnosticCode,\n reason: string,\n ) => void;\n}\n\nexport interface FragmentReport {\n readonly rendered: number;\n readonly failed: number;\n readonly superseded: number;\n}\n\n/** A fragment strategy: which boundaries it owns for a revision, and how it renders them. */\nexport interface FragmentStrategy {\n /** The boundaries this update re-renders; their inner bindings are left to the strategy. */\n readonly plan: (root: ParentNode, changedFields: ReadonlySet<string>) => readonly Element[];\n /** Render the planned boundaries; resolves once every one settled. */\n readonly render: (\n context: FragmentContext,\n boundaries: readonly Element[],\n ) => Promise<FragmentReport>;\n}\n\n/** The boundaries a revision hands the fragment strategy, and the bindings they take from the patch. */\nexport interface FragmentPlan {\n readonly boundaries: readonly Element[];\n readonly strategy: FragmentStrategy;\n readonly ownerKeys: OwnerScope;\n /** Whether a binding sits inside a boundary the strategy renders this revision. */\n readonly covers: (target: CachedElement) => boolean;\n}\n\n/** A plan over boundaries already chosen, whichever question chose them. */\nexport function planBoundaries(\n strategy: FragmentStrategy,\n boundaries: readonly Element[],\n ownerKeys: OwnerScope,\n): FragmentPlan {\n const covered = new Set(boundaries);\n return {\n boundaries,\n strategy,\n ownerKeys,\n covers: (target) =>\n target.fragmentBoundary !== undefined && covered.has(target.fragmentBoundary),\n };\n}\n\n/** One revision, as the route strategy sees it. */\nexport interface RouteContext {\n readonly revision: number;\n readonly receivedAt: number;\n /** Aborted when a newer revision asks for a refresh of its own, a navigation commits, or the runtime stops. */\n readonly signal: AbortSignal;\n /**\n * Whether the refresh may still land. A newer revision that asks for no\n * refresh of its own does not end it: the route is the server's, so the\n * refresh lands for that revision, which the runtime then re-applies.\n */\n readonly isCurrent: () => boolean;\n readonly log: (code: DiagnosticCode, detail: string) => void;\n /**\n * Ask to be run again in `delayMs`, once. A strategy that refuses a refresh\n * because it is rate-limiting itself uses this: the window is a rate limit\n * and not a filter, so what falls inside it still has to reach the preview.\n * The runtime runs at most one such request, and only while the revision that\n * asked is still the current one.\n */\n readonly retryAfter?: (delayMs: number) => void;\n}\n\n/**\n * What one refresh did. `refreshed` asserts that the strategy rendered the\n * current unsaved revision. `partial` completed a render whose data source was\n * not proven current; the runtime still reapplies every binding it can reach.\n * `refused` is the strategy's own brake and not a failure.\n */\nexport type RouteOutcome = 'refreshed' | 'partial' | 'failed' | 'refused' | 'superseded';\n\n/** What the runtime tells a route planner about the update it plans for. */\nexport interface RoutePlanContext {\n /**\n * Whether an element belongs to the update: always `true` without\n * `scopeBindingsByOwner`, otherwise only inside the document the update\n * names. A marker outside it asks for nothing.\n */\n readonly inScope: (element: Element) => boolean;\n}\n\n/**\n * Whether a revision needs the whole route re-rendered, and how. After a\n * refresh the runtime rescans and re-applies the revision, so reachable\n * unsaved bindings land on the fresh markup. The runtime always passes\n * `context`; a planner written before it existed still works, but plans for\n * markers of every document.\n */\nexport interface RouteStrategy {\n readonly plan: (\n root: ParentNode,\n changedFields: ReadonlySet<string>,\n context?: RoutePlanContext,\n ) => boolean;\n readonly refresh: (context: RouteContext) => Promise<RouteOutcome>;\n}\n\nexport interface StrategyHandlers {\n readonly fragment?: FragmentStrategy;\n readonly route?: RouteStrategy;\n}\n\nconst STRATEGY_ATTRIBUTE = 'data-payload-strategy';\n\n/**\n * Explicit `data-payload-strategy` wins; otherwise a binding inside a fragment\n * boundary belongs to the fragment, one in `<head>` to the route, the rest is\n * patched. An unknown explicit value resolves to `undefined` (LP0407).\n * @internal\n */\nexport function resolveStrategy(element: Element): UpdateSource | undefined {\n const explicit = element.getAttribute(STRATEGY_ATTRIBUTE);\n if (explicit !== null && explicit.length > 0) {\n return explicit === 'patch' || explicit === 'fragment' || explicit === 'route'\n ? explicit\n : undefined;\n }\n if (enclosingFragment(element) !== null) return 'fragment';\n if (element.closest('head') !== null) return 'route';\n return 'patch';\n}\n","/**\n * Document ownership for bindings. A field name alone cannot identify a\n * binding on a page that previews several documents — `title` may belong to a\n * global, to shared SEO metadata and to every card at once. An owner marker\n * names the document a subtree belongs to, as a plain comparable string:\n * `global:<slug>`, `collection:<slug>`, `collection:<slug>:<id>`.\n */\n\n/** Identity of the document an incoming message describes. */\nexport interface MessageDocumentIdentity {\n readonly globalSlug?: string | undefined;\n readonly collectionSlug?: string | undefined;\n /** Primary key of the edited document, when the payload carries one. */\n readonly documentId?: string | undefined;\n}\n\n/** Owner key naming one Payload global. */\nexport function globalOwnerKey(slug: string): string {\n return `global:${slug}`;\n}\n\n/** Owner key for a collection; without an id it claims every document of it. */\nexport function collectionOwnerKey(slug: string, documentId?: string): string {\n return documentId === undefined || documentId === ''\n ? `collection:${slug}`\n : `collection:${slug}:${documentId}`;\n}\n\nfunction nonEmpty(value: string | undefined): value is string {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * Owner keys this message may address, or `null` when it carries no usable\n * identity — the runtime treats that as fail-closed rather than guessing. A\n * marker naming an id stays unreachable while the id is unknown: an unproven\n * identity must not satisfy an exact claim.\n */\nexport function messageOwnerKeys(identity: MessageDocumentIdentity): readonly string[] | null {\n if (nonEmpty(identity.globalSlug)) return [globalOwnerKey(identity.globalSlug)];\n if (!nonEmpty(identity.collectionSlug)) return null;\n const collectionKey = collectionOwnerKey(identity.collectionSlug);\n return nonEmpty(identity.documentId)\n ? [collectionKey, collectionOwnerKey(identity.collectionSlug, identity.documentId)]\n : [collectionKey];\n}\n\n/** Whether a binding may receive an update addressed to `keys`; an unowned binding never may. */\nexport function isBindingInScope(\n owner: string | undefined,\n keys: readonly string[] | null,\n): boolean {\n if (keys === null || owner === undefined) return false;\n return keys.includes(owner);\n}\n\n/** The document id Payload sends alongside the edited values; only scalars prove an identity. */\nexport function readDocumentId(fields: Record<string, unknown>): string | undefined {\n const id: unknown = fields['id'];\n if (typeof id === 'string' && id.length > 0) return id;\n if (typeof id === 'number' && Number.isFinite(id)) return String(id);\n return undefined;\n}\n","/**\n * Which paths below a group changed without anything on the page to show\n * them (ADR 0022). The diff names top-level fields; under\n * `subfieldCoverage: 'declared'` a group covered only through its descendants\n * is compared with the previous message path by path, and a changed path\n * needs its own binding or a declared cover. A document a merge populated and\n * the id it replaced are the same value: population is not an edit.\n */\n\nimport { valueIdentity } from './value-identity';\n\nexport type SubfieldCoverage = 'descendant' | 'declared';\n\n/** Deeper than this, what is left counts as one changed path. */\nexport const SUBFIELD_DEPTH_LIMIT = 8;\n/** Nodes compared per field before the rest counts as one changed path. */\nexport const SUBFIELD_VISIT_LIMIT = 1024;\n\n/** What the page offers for a path; built once per update from the cache and the owner scope. */\nexport interface PathCoverage {\n /** A binding on the path, or a cover on it or on an ancestor. */\n readonly covers: (path: string) => boolean;\n /** A binding or a cover somewhere below the path. */\n readonly reachesBelow: (path: string) => boolean;\n}\n\nexport interface UncoveredPath {\n readonly path: string;\n /** The current value there, `undefined` where the path was removed. */\n readonly value: unknown;\n}\n\nfunction isContainer(value: unknown): value is Record<string, unknown> | readonly unknown[] {\n return typeof value === 'object' && value !== null;\n}\n\nfunction shapeOf(value: unknown): 'array' | 'object' | 'scalar' {\n if (Array.isArray(value)) return 'array';\n return isContainer(value) ? 'object' : 'scalar';\n}\n\n/** The keys to compare below a container: the new ones, and any the previous value had. */\nfunction childKeys(\n previous: unknown,\n next: Record<string, unknown> | readonly unknown[],\n): string[] {\n const keys = new Set(Object.keys(next));\n if (isContainer(previous)) for (const key of Object.keys(previous)) keys.add(key);\n return [...keys];\n}\n\nfunction child(value: unknown, key: string): unknown {\n return isContainer(value) ? (value as Record<string, unknown>)[key] : undefined;\n}\n\n/** Whether `document` is what a merge puts where the message has the bare `id`. */\nfunction populates(document: unknown, id: unknown): boolean {\n return (\n (typeof id === 'string' || typeof id === 'number') &&\n isContainer(document) &&\n !Array.isArray(document) &&\n (document as Record<string, unknown>)['id'] === id\n );\n}\n\n/**\n * Whether two values differ only in what the server populated: the same shape\n * all the way down, except that one holds a document where the other holds its\n * id. The admin posts a relationship or an upload as its id in every message\n * and the merge answers with the document, so a revision rendered before the\n * answer and the one after it meet both forms of one value.\n */\nfunction samePopulation(before: unknown, after: unknown): boolean {\n if (!isContainer(before) || !isContainer(after)) {\n return (\n populates(before, after) ||\n populates(after, before) ||\n valueIdentity(before) === valueIdentity(after)\n );\n }\n if (Array.isArray(before) !== Array.isArray(after)) return false;\n const keys = Object.keys(after);\n if (keys.length !== Object.keys(before).length) return false;\n return keys.every(\n (key) => Object.hasOwn(before, key) && samePopulation(child(before, key), child(after, key)),\n );\n}\n\n/**\n * Whether the two values are one: equal, or equal but for population. An id\n * and its document are told apart without a walk, whatever the document's\n * size. The walk itself needs an identity on both sides, which bounds it by\n * the identity's size limit and keeps it out of a cycle; a value without one\n * counts as changed, as it does for the top-level diff.\n */\nfunction sameValue(before: unknown, after: unknown): boolean {\n const identity = valueIdentity(after);\n const previous = valueIdentity(before);\n if (identity !== undefined && identity === previous) return true;\n if (populates(before, after) || populates(after, before)) return true;\n return identity !== undefined && previous !== undefined && samePopulation(before, after);\n}\n\n/**\n * Whether the value at a dotted path changed between two messages, by the\n * rule the walk below applies. A route-bound element names such a path\n * (`layout.1.note`) while the diff names only its field.\n */\nexport function pathChanged(\n path: string,\n previous: Readonly<Record<string, unknown>>,\n next: Readonly<Record<string, unknown>>,\n): boolean {\n let before: unknown = previous;\n let after: unknown = next;\n for (const key of path.split('.')) {\n before = child(before, key);\n after = child(after, key);\n }\n return !sameValue(before, after);\n}\n\n/**\n * The changed paths below `field` that nothing covers, as the largest\n * uncovered subtrees: a path with nothing bound or covered beneath it is\n * reported whole rather than leaf by leaf. `previous` is `undefined` for a\n * document read without a diff, which makes every path \"changed\".\n */\nexport function uncoveredChangedPaths(\n field: string,\n previous: unknown,\n next: unknown,\n coverage: PathCoverage,\n): UncoveredPath[] {\n const uncovered: UncoveredPath[] = [];\n let visits = 0;\n const visit = (path: string, before: unknown, after: unknown, depth: number): void => {\n visits += 1;\n if (coverage.covers(path) || sameValue(before, after)) return;\n // A path that changed shape — a group that became a scalar, went away or\n // replaced one — changed as a whole, whatever is covered inside it. Without\n // a previous message (`undefined`) there is no shape to compare.\n const reshaped = before !== undefined && shapeOf(before) !== shapeOf(after);\n const descend =\n !reshaped &&\n isContainer(after) &&\n coverage.reachesBelow(path) &&\n depth < SUBFIELD_DEPTH_LIMIT;\n if (!descend) {\n uncovered.push({ path, value: after });\n return;\n }\n const keys = childKeys(before, after);\n // A new, empty group: nothing inside to compare, so the node itself changed.\n if (keys.length === 0) uncovered.push({ path, value: after });\n for (const key of keys) {\n // Out of budget: this node stands for whatever of it is left unvisited.\n if (visits >= SUBFIELD_VISIT_LIMIT) {\n uncovered.push({ path, value: after });\n return;\n }\n visit(`${path}.${key}`, child(before, key), child(after, key), depth + 1);\n }\n };\n visit(field, previous, next, 0);\n return uncovered;\n}\n","/**\n * Whether an incoming field has somewhere on the page to land.\n *\n * Two callers ask, for different reasons: LP0201 reports a field that never\n * has an anchor, and `onUnfaithfulPatch` decides whether a revision needs the\n * whole route. They have to answer the same way, so the lookup lives here\n * rather than in either of them — the locale suffix Payload appends, the owner\n * scope, and the fact that the diff names top-level fields while a binding may\n * name a path inside one.\n */\n\nimport { isBindingInScope } from './binding-owner';\nimport type { ElementCache } from './cache';\nimport {\n pathChanged,\n uncoveredChangedPaths,\n type PathCoverage,\n type SubfieldCoverage,\n type UncoveredPath,\n} from './subfield-coverage';\n\n/** Document fields Payload ships in every update that nobody binds to. */\nexport const SYSTEM_FIELD_NAMES: ReadonlySet<string> = new Set([\n 'id',\n '_id',\n 'createdAt',\n 'updatedAt',\n 'createdBy',\n 'updatedBy',\n '_status',\n 'globalType',\n 'collection',\n 'locale',\n 'localized',\n]);\n\n/** Owner keys as the update resolved them; `false` means scoping is off. */\nexport type OwnerScope = readonly string[] | null | false;\n\n/** Answers for one update; the locale index behind it is built at most once. */\nexport type FieldAddressability = (fieldName: string) => boolean;\n\n/**\n * `field_locale` names an element-local locale may consume while the message\n * locale differs, so those bindings are addressable under their suffixed name.\n */\nfunction localisedBindingNames(cache: ElementCache, ownerKeys: OwnerScope): Set<string> {\n const names = new Set<string>();\n for (const [fieldName, bindings] of cache.entries()) {\n for (const binding of bindings) {\n if (ownerKeys !== false && !isBindingInScope(binding.owner, ownerKeys)) continue;\n if (binding.locale !== undefined) names.add(`${fieldName}_${binding.locale}`);\n }\n }\n return names;\n}\n\n/**\n * A binding on a path inside the field — `hero.eyebrow` for the field `hero` —\n * makes it addressable. The diff names top-level fields only, so without this\n * every group and array on the page would look unbound.\n */\nexport function hasBindingBelow(\n cache: ElementCache,\n fieldName: string,\n ownerKeys: OwnerScope,\n): boolean {\n const prefix = `${fieldName}.`;\n for (const [boundName, bindings] of cache.entries()) {\n if (!boundName.startsWith(prefix)) continue;\n if (ownerKeys === false) return true;\n if (bindings.some((binding) => isBindingInScope(binding.owner, ownerKeys))) return true;\n }\n return false;\n}\n\n/** The strategies configured for this page; only they render what a boundary or marker depends on. */\nexport interface ServerRendering {\n readonly fragment?: unknown;\n readonly route?: unknown;\n}\n\n/**\n * The page's answer for any path in one update's owner scope: the bound names,\n * the declared covers (ADR 0022) and the fields a boundary or route marker\n * depends on when its strategy is configured, read once, then the same name\n * rule the overlay applies.\n */\nexport function createPathCoverage(\n cache: ElementCache,\n ownerKeys: OwnerScope,\n rendering: ServerRendering = {},\n): PathCoverage {\n const inScope = (owner: string | undefined): boolean =>\n ownerKeys === false || isBindingInScope(owner, ownerKeys);\n const names: string[] = [];\n for (const [fieldName, bindings] of cache.entries()) {\n if (bindings.some((binding) => inScope(binding.owner))) names.push(fieldName);\n }\n const rendered = cache.rendered.filter(\n (declaration) => rendering[declaration.strategy] !== undefined,\n );\n const covers = [...cache.covers, ...rendered]\n .filter((cover) => inScope(cover.owner))\n .flatMap((cover) => cover.paths);\n return namePathCoverage(names, covers);\n}\n\nexport function stripLocaleSuffix(name: string, locale: string | undefined): string {\n if (locale === undefined || locale.length === 0) return name;\n const suffix = `_${locale}`;\n return name.endsWith(suffix) ? name.slice(0, -suffix.length) : name;\n}\n\n/** Whether any binding on the page belongs to the document this update carries. */\nexport function ownsAnyBinding(cache: ElementCache, ownerKeys: readonly string[] | null): boolean {\n for (const binding of cache.values()) {\n if (isBindingInScope(binding.owner, ownerKeys)) return true;\n }\n return false;\n}\n\n/**\n * The same rule for a caller that has names rather than the cache: the\n * `data-payload-field` values in a document, which is all a plugin can see\n * (`src/plugins/built-in/unbound-fields-overlay.ts`).\n *\n * It answers the first three of the four questions below — exact name, the\n * locale-stripped base, a binding on a path inside the field. The fourth needs\n * each binding's own `data-payload-locale`, which is a property of the element\n * rather than of its name, so a caller with names alone cannot ask it.\n */\nexport function createNameAddressability(\n boundNames: Iterable<string>,\n locale: string | undefined,\n coverPaths: Iterable<string>,\n): FieldAddressability {\n const coverage = namePathCoverage(boundNames, coverPaths);\n const reaches = (name: string): boolean => coverage.covers(name) || coverage.reachesBelow(name);\n return (fieldName) => {\n if (reaches(fieldName)) return true;\n const base = stripLocaleSuffix(fieldName, locale);\n return base !== fieldName && reaches(base);\n };\n}\n\n/** Coverage from names alone: the bound names and the declared cover paths in a document. */\nfunction namePathCoverage(\n boundNames: Iterable<string>,\n coverPaths: Iterable<string>,\n): PathCoverage {\n const names = new Set(boundNames);\n const covers = [...coverPaths];\n const anyBelow = (candidates: Iterable<string>, path: string): boolean => {\n const prefix = `${path}.`;\n for (const candidate of candidates) if (candidate.startsWith(prefix)) return true;\n return false;\n };\n return {\n covers: (path) =>\n names.has(path) || covers.some((cover) => cover === path || path.startsWith(`${cover}.`)),\n reachesBelow: (path) => anyBelow(names, path) || anyBelow(covers, path),\n };\n}\n\n/**\n * The declared mode for a caller with names (the overlay): the uncovered paths\n * inside the groups the document reaches only below the top level.\n */\nexport function uncoveredNamePaths(\n fields: Readonly<Record<string, unknown>>,\n boundNames: Iterable<string>,\n locale: string | undefined,\n coverPaths: Iterable<string>,\n): string[] {\n const coverage = namePathCoverage(boundNames, coverPaths);\n const found: string[] = [];\n for (const [fieldName, value] of Object.entries(fields)) {\n if (SYSTEM_FIELD_NAMES.has(fieldName)) continue;\n const root = stripLocaleSuffix(fieldName, locale);\n if (coverage.covers(root) || !coverage.reachesBelow(root)) continue;\n for (const { path } of uncoveredChangedPaths(root, undefined, value, coverage)) {\n found.push(path);\n }\n }\n return found;\n}\n\n/**\n * The predicate for one update. The localised index is built on first use:\n * most fields are answered by the two cheap lookups before it.\n */\nexport function createFieldAddressability(\n cache: ElementCache,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n rendering?: ServerRendering,\n): FieldAddressability {\n const coverage = createPathCoverage(cache, ownerKeys, rendering);\n const reach = createFieldReach(cache, locale, ownerKeys, coverage);\n return (fieldName) => reach(fieldName) !== 'none';\n}\n\n/**\n * How far the page reaches into a field: `whole` when a binding or a cover\n * sits on it, `below` when only paths inside it are bound or covered — the\n * case ADR 0022's declared mode looks into — and `none`.\n */\nfunction createFieldReach(\n cache: ElementCache,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n coverage: PathCoverage = createPathCoverage(cache, ownerKeys),\n): (fieldName: string) => 'whole' | 'below' | 'none' {\n let localised: Set<string> | undefined;\n const whole = coverage.covers;\n const below = coverage.reachesBelow;\n return (fieldName) => {\n const base = stripLocaleSuffix(fieldName, locale);\n if (whole(fieldName) || (base !== fieldName && whole(base))) return 'whole';\n localised ??= localisedBindingNames(cache, ownerKeys);\n if (localised.has(fieldName)) return 'whole';\n if (below(fieldName) || (base !== fieldName && below(base))) return 'below';\n return 'none';\n };\n}\n\n/** The previous and current message, when the declared mode compares below the top level. */\nexport interface SubfieldValues {\n readonly previous: Readonly<Record<string, unknown>>;\n readonly next: Readonly<Record<string, unknown>>;\n}\n\n/**\n * The declared mode asked of a document rather than a diff, for LP0203: the\n * uncovered paths inside the groups the page reaches only below the top level.\n */\nexport function uncoveredDocumentPaths(\n cache: ElementCache,\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n rendering?: ServerRendering,\n): UncoveredPath[] {\n const coverage = createPathCoverage(cache, ownerKeys, rendering);\n const reach = createFieldReach(cache, locale, ownerKeys, coverage);\n const found: UncoveredPath[] = [];\n for (const [fieldName, value] of Object.entries(fields)) {\n if (SYSTEM_FIELD_NAMES.has(fieldName) || reach(fieldName) !== 'below') continue;\n const root = stripLocaleSuffix(fieldName, locale);\n found.push(...uncoveredChangedPaths(root, undefined, value, coverage));\n }\n return found;\n}\n\n/** What the declared mode compares for one revision, or `undefined` where it does not apply. */\nexport function declaredSubfields(\n mode: SubfieldCoverage,\n previous: Readonly<Record<string, unknown>> | undefined,\n next: Readonly<Record<string, unknown>> | undefined,\n): SubfieldValues | undefined {\n return mode === 'declared' && previous !== undefined && next !== undefined\n ? { previous, next }\n : undefined;\n}\n\n/**\n * `touched` with the paths inside its fields that route-bound elements name and\n * that changed, for the route planners: a marker on `layout.1.note` asks about\n * that path while the diff names `layout`. Without the previous message, which\n * only the declared mode keeps, a path changes with its field.\n */\nexport function routeTouched(\n cache: ElementCache,\n touched: ReadonlySet<string>,\n subfields?: SubfieldValues,\n): ReadonlySet<string> {\n const named = cache.rendered.flatMap((declaration) =>\n declaration.strategy === 'route' ? declaration.paths : [],\n );\n for (const [fieldName, bindings] of cache.entries()) {\n if (bindings.some((binding) => binding.strategyKind === 'route')) named.push(fieldName);\n }\n const changed = new Set(touched);\n for (const path of named) {\n const [field = path] = path.split('.');\n if (!touched.has(field)) continue;\n if (subfields === undefined || pathChanged(path, subfields.previous, subfields.next)) {\n changed.add(path);\n }\n }\n return changed;\n}\n\n/**\n * The fields a revision changed that the page has nowhere to put: the rule\n * above, asked of a diff instead of a document. Both profiles ask it — the full\n * one to decide whether the whole route is the only honest answer, the lean one\n * because the finding is worth recording even where nothing can act on it — so\n * it stands here, beside the rule it is made of, rather than in either runner.\n */\nexport function unboundChangedFields(\n cache: ElementCache,\n touched: ReadonlySet<string>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n subfields?: SubfieldValues,\n rendering?: ServerRendering,\n): string[] {\n const coverage = createPathCoverage(cache, ownerKeys, rendering);\n const reach = createFieldReach(cache, locale, ownerKeys, coverage);\n const unbound: string[] = [];\n for (const fieldName of touched) {\n if (SYSTEM_FIELD_NAMES.has(fieldName)) continue;\n const kind = reach(fieldName);\n if (kind === 'none') unbound.push(fieldName);\n if (kind !== 'below' || subfields === undefined) continue;\n const root = stripLocaleSuffix(fieldName, locale);\n const { previous, next } = subfields;\n for (const { path } of uncoveredChangedPaths(\n root,\n previous[fieldName],\n next[fieldName],\n coverage,\n )) {\n unbound.push(path);\n }\n }\n return unbound;\n}\n","/**\n * Whether an accepted message has to be resolved against the server before the\n * page can render it, and how many round trips a burst of them may cost. The\n * merge exists to populate relationships and uploads, so a page that renders\n * none of them needs no request at all. A message in the same locale that moved\n * no populated field is answered from its own values over what the last merge\n * resolved, and what is left goes out once at the start of a burst and once at\n * its end.\n *\n * Conservative in one direction on purpose: a request left out that was needed\n * puts an id where a name belongs and leaves it there, while one request too\n * many costs a round trip nobody sees.\n */\n\nimport { lookupSchema, type SchemaIndex } from '@schema/index';\nimport type { ElementCache } from './cache';\nimport type { DataMerger, MergeRequest, MergeResult } from './data-merger';\nimport type { DependencyMap } from './dependencies';\nimport { looksLikeLexicalRoot } from './binding-writer';\nimport { bindingValue } from './field-value';\nimport { FieldChangeTracker } from './field-changes';\nimport type { RuntimeDeps, UpdateTransaction } from './runtime-state';\nimport { FRAGMENT_ATTRIBUTE } from './strategies';\nimport { hasBindingBelow, SYSTEM_FIELD_NAMES } from './unbound-fields';\n\n/**\n * Renderer keys and Payload types whose value the panel posts complete: a\n * scalar, with nothing inside it and nothing behind it to resolve. One\n * vocabulary answers both questions asked here — whether a page reads anything\n * the server populates, and whether one field does — because they are the same\n * question about a binding and about a value.\n */\nconst SELF_SUFFICIENT_TYPES: ReadonlySet<string> = new Set([\n 'text',\n 'textarea',\n 'email',\n 'number',\n 'checkbox',\n 'date',\n 'select',\n 'radio',\n 'point',\n 'code',\n 'json',\n 'ui',\n 'html',\n]);\n\n/**\n * Lexical nodes whose whole content is in the message. Anything else — an\n * upload, a relationship, a block, a node this package does not know — may name\n * a document the server fills in, and so may a link whose target is one.\n */\nconst SELF_SUFFICIENT_NODES: ReadonlySet<string> = new Set([\n 'root',\n 'paragraph',\n 'text',\n 'heading',\n 'quote',\n 'list',\n 'listitem',\n 'linebreak',\n 'tab',\n 'horizontalrule',\n 'code',\n 'code-highlight',\n 'table',\n 'tablerow',\n 'tablecell',\n 'link',\n 'autolink',\n]);\n\n/** The raw diff answers \"what did the editor move\", which no dependency map changes. */\nconst NO_DEPENDENCIES: DependencyMap = {};\n\nexport interface MergePlan {\n /** Whether the server can still add something to these values. */\n readonly merge: boolean;\n /** The best document without it: this message's own values over the last resolved one. */\n readonly fields: Record<string, unknown>;\n}\n\nexport interface CoalescedMerge {\n /** Whether the request went out now. A deferred one lands after the window and refines what was rendered. */\n readonly leading: boolean;\n readonly result: Promise<MergeResult>;\n}\n\ninterface PendingMerge {\n readonly promise: Promise<MergeResult>;\n readonly settle: (result: MergeResult) => void;\n}\n\ninterface TrailingMerge {\n readonly request: MergeRequest;\n readonly pending: PendingMerge;\n timer: ReturnType<typeof setTimeout> | null;\n}\n\nexport class MergeNeed {\n /** Raw fields last considered for population, without confusing edits with server-added values. */\n private readonly rawChanges = new FieldChangeTracker();\n private resolved: Record<string, unknown> | null = null;\n /** Null leaves required population unresolved; undefined is the resolved default locale. */\n private resolvedLocale: string | undefined | null = null;\n private trailing: TrailingMerge | null = null;\n private openUntil = 0;\n private requestAttempt = 0;\n\n /**\n * The decision, in the order the audit found the ways to get it wrong.\n *\n * 1. **Nothing on the page reads a populated value**, either because nobody\n * reads anything (LP-4) or because every binding renders a plain scalar.\n * See `readsPopulatedValues`. A binding that declares no type and holds\n * rich text naming a document is not plain, whatever its element says:\n * see `rendersRichTextByShape`.\n * 2. **Nothing populated moved** (LP-3): the fields the editor changed are\n * scalars that name no document, so they are taken from the message and\n * the rest is carried over from what the last merge resolved. Typing a\n * title costs nothing.\n *\n * What is left needs the server. It still renders at once — from the same\n * carried-over document — so the answer is not what the page waits for;\n * `request()` decides how often it is actually asked.\n */\n decide(deps: RuntimeDeps, transaction: UpdateTransaction): MergePlan {\n const raw = transaction.rawData;\n if (\n !readsPopulatedValues(deps) &&\n !rendersRichTextByShape(deps.cache, raw, transaction.locale)\n ) {\n if (transaction.forceRender) this.resolvedLocale = null;\n return { merge: false, fields: raw };\n }\n // Unobserved edits still need comparison when a population consumer returns.\n const { changed } = this.rawChanges.diff(raw, NO_DEPENDENCIES);\n // Population depends on the accepted locale even when relationship IDs stay\n // put. A page with no population consumer leaves the retained context alone.\n const localeChanged = this.resolvedLocale !== transaction.locale;\n const base = this.resolved;\n // The first message has nothing to carry over, so it buys the document once.\n if (base === null) {\n this.resolved = raw;\n return { merge: true, fields: raw };\n }\n const fields: Record<string, unknown> = { ...base };\n // A related save (LP-1) or an accepted locale change can alter population\n // without moving a relationship ID in the raw form values.\n if (transaction.forceRender) this.resolvedLocale = null;\n let merge = transaction.forceRender || localeChanged;\n for (const field of changed) {\n const value = raw[field];\n if (SYSTEM_FIELD_NAMES.has(field)) {\n fields[field] = value;\n continue;\n }\n const verdict = verdictFor(field, base[field], value, deps.cache, transaction.schemaIndex);\n if (verdict !== 'own') {\n merge = true;\n this.resolvedLocale = null;\n }\n if (verdict !== 'keep') fields[field] = value;\n }\n this.resolved = fields;\n return { merge, fields };\n }\n\n /**\n * One request goes out now and the rest of a burst share the one that follows\n * its last message. The abort stays where it was: `DataMerger` still drops an\n * answer a newer request superseded, and what changes here is only how often\n * it is asked.\n *\n * The window is the scheduler's debounce, because it is the same burst: the\n * writes of one are coalesced into a single flush, and this is the request\n * behind them. A page that turns the debounce off turns this off with it.\n */\n request(merger: DataMerger, windowMs: number, request: MergeRequest): CoalescedMerge {\n const attempt = ++this.requestAttempt;\n const now = Date.now();\n if (now >= this.openUntil) {\n // The clock has closed the window, but its timer may not have run: a busy\n // main thread or a throttled engine fires it late. Left queued, that older\n // request would go out after this one, and `DataMerger` — which keeps the\n // newest request — would drop this keystroke's answer; measured in WebKit\n // as a preview one keystroke behind. This request carries the newer values.\n this.openUntil = now + windowMs;\n this.dropQueued();\n // Cancellation can accept newer work before this leading request dispatches.\n if (this.requestAttempt !== attempt) {\n return { leading: true, result: Promise.resolve({ status: 'superseded' }) };\n }\n return { leading: true, result: merger.merge(request) };\n }\n const previous = this.trailing;\n const pending = previous?.pending ?? createPending();\n const trailing: TrailingMerge = { request, pending, timer: null };\n this.trailing = trailing;\n this.openUntil = now + windowMs;\n if (previous !== null && previous.timer !== null) clearTimeout(previous.timer);\n if (this.trailing !== trailing) return { leading: false, result: pending.promise };\n const timer = setTimeout(() => {\n this.flush(merger, trailing);\n }, windowMs);\n if (this.trailing === trailing) trailing.timer = timer;\n else clearTimeout(timer);\n return { leading: false, result: pending.promise };\n }\n\n /** The server's document replaces what was carried over; the next message builds on it. */\n recordMerged(doc: Record<string, unknown>, locale?: string): void {\n this.resolved = doc;\n this.resolvedLocale = locale;\n }\n\n /** Start a navigation replay from a raw baseline while retaining the last complete server document. */\n resetRawChanges(): void {\n this.rawChanges.reset();\n }\n\n destroy(): void {\n this.requestAttempt += 1;\n this.openUntil = 0;\n this.dropQueued();\n }\n\n /** Drop a queued request; whoever waits on it keeps what they already rendered. */\n private dropQueued(): void {\n const trailing = this.trailing;\n this.trailing = null;\n if (trailing === null) return;\n if (trailing.timer !== null) clearTimeout(trailing.timer);\n trailing.pending.settle({ status: 'superseded' });\n }\n\n private flush(merger: DataMerger, trailing: TrailingMerge): void {\n // A cancelled callback must never consume a successor's queued request.\n if (this.trailing !== trailing) return;\n this.trailing = null;\n trailing.timer = null;\n // The owned DataMerger fulfills one of its three outcomes, including request failures.\n void merger.merge(trailing.request).then(trailing.pending.settle);\n }\n}\n\n/** What one changed field's own value is worth. */\ntype FieldVerdict =\n /** Everything the page can render is in it. */\n | 'own'\n /** It can be rendered now, and the server may still complete something inside it. */\n | 'ask'\n /** It is a bare id where a document stood; writing it would put that id on the page. */\n | 'keep';\n\nfunction verdictFor(\n field: string,\n previous: unknown,\n value: unknown,\n cache: ElementCache,\n schemaIndex: SchemaIndex | undefined,\n): FieldVerdict {\n // A structure — a rich-text tree, an array, a group — may hold a reference\n // inside it, and the message's own copy of it is still what the editor typed.\n if (!isScalar(value)) return 'ask';\n if (!isScalar(previous) || namesAReference(field, cache, schemaIndex)) return 'keep';\n // A field that was empty can be filled with either a word or an id, and the\n // two look alike. Render it and ask: a word must not wait for the answer.\n return previous == null ? 'ask' : 'own';\n}\n\n/** A document id and a title are both strings; only the schema or a binding says which this is. */\nfunction namesAReference(\n field: string,\n cache: ElementCache,\n schemaIndex: SchemaIndex | undefined,\n): boolean {\n const schema = schemaIndex === undefined ? undefined : lookupSchema(schemaIndex, field);\n if (schema !== undefined && !SELF_SUFFICIENT_TYPES.has(schema.type)) return true;\n if (cache.get(field)?.some(rendersAReference) === true) return true;\n // `venue.title` is a page saying the field holds a document; the owner scope\n // is off here on purpose, because a binding in any document still says so.\n return hasBindingBelow(cache, field, false);\n}\n\nfunction rendersAReference(binding: { readonly fieldType: string }): boolean {\n // A project renderer is unknown ground: it may resolve the value itself.\n return !SELF_SUFFICIENT_TYPES.has(binding.fieldType);\n}\n\n/**\n * Whether anything on this page reads a value the server would populate.\n *\n * Two findings meet here. LP-4: a page with no binding, no island, no boundary\n * a fragment strategy would render and no listener reading the document has\n * nobody to hand the answer to — measured on such a page, 17 keystrokes cost 19\n * authenticated POSTs. LP-3: a page whose every binding is a plain scalar\n * renderer on a top-level field renders the panel's own values exactly, so the\n * merge could only hand back what the message already carries.\n *\n * The route is deliberately not a reason to ask. Since Z3 an unbound change\n * escalates to it by default, but a refresh re-renders the page from the server\n * and never looks at these values.\n */\nfunction readsPopulatedValues(deps: RuntimeDeps): boolean {\n const { cache, emitter } = deps;\n if (cache.islands.length > 0) return true;\n if (emitter.listenerCount('beforeUpdate') > 0 || emitter.listenerCount('afterUpdate') > 0) {\n return true;\n }\n for (const binding of cache.values()) {\n // A reference renderer, a value with structure, or a path inside a field.\n if (rendersAReference(binding) || binding.fieldName.includes('.')) return true;\n if (isPath(binding.hrefField) || isPath(binding.srcField) || isPath(binding.altField)) {\n return true;\n }\n }\n // A boundary is rendered by a server that is handed exactly these fields.\n return (\n deps.strategies.fragment !== undefined &&\n deps.root.querySelector(`[${FRAGMENT_ATTRIBUTE}]`) !== null\n );\n}\n\n/**\n * Whether a binding that declares no type holds rich text with something in it\n * the server fills in. The writer renders a Lexical root as rich text whatever\n * the element says (binding-writer.ts), and Payload 3's admin posts the nodes\n * inside it as bare IDs, so without this the image in a rich-text field was\n * written from its ID — which draws nothing — on a page that marked the\n * element with `data-payload-field` alone. Asked of the value, because the\n * same field holds an upload in one message and none in the next.\n */\nfunction rendersRichTextByShape(\n cache: ElementCache,\n raw: Record<string, unknown>,\n locale: string | undefined,\n): boolean {\n for (const binding of cache.values()) {\n // A declared type is what the writer renders; only the default `text` goes by the shape.\n if (binding.fieldType !== 'text' || binding.explicitFieldType === true) continue;\n // Read as the writer reads it, the binding's own locale first.\n const value = bindingValue(raw, binding, binding.fieldName, locale);\n if (looksLikeLexicalRoot(value) && holdsReference((value as { root: unknown }).root)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Walked with a stack rather than recursion, because the editor decides how\n * deep a tree goes. A message is a structured clone, which keeps a cycle, so a\n * node is walked once.\n */\nfunction holdsReference(root: unknown): boolean {\n const pending: unknown[] = [root];\n const seen = new Set<object>();\n for (let node = pending.pop(); node !== undefined; node = pending.pop()) {\n if (typeof node !== 'object' || node === null || seen.has(node)) continue;\n seen.add(node);\n const { type, fields, children } = node as {\n readonly type?: unknown;\n readonly fields?: { readonly linkType?: unknown } | null;\n readonly children?: unknown;\n };\n // `has` answers false for a type that is missing or not a string, and that node is asked for too.\n if (!SELF_SUFFICIENT_NODES.has(type as string)) return true;\n if (fields?.linkType === 'internal') return true;\n if (Array.isArray(children)) for (const child of children as unknown[]) pending.push(child);\n }\n return false;\n}\n\nfunction isScalar(value: unknown): boolean {\n return value === null || (typeof value !== 'object' && typeof value !== 'function');\n}\n\nfunction isPath(field: string | undefined): boolean {\n return field?.includes('.') === true;\n}\n\nfunction createPending(): PendingMerge {\n let settle!: (result: MergeResult) => void;\n const promise = new Promise<MergeResult>((resolve) => {\n settle = resolve;\n });\n return { promise, settle };\n}\n","/** Tracks the announced protocol version and the capabilities seen on the wire. */\n\nimport {\n LIBRARY_PROTOCOL_VERSION,\n negotiateProtocol,\n type ProtocolCapability,\n type ProtocolNegotiation,\n} from './protocol-version';\n\nexport class ProtocolTracker {\n negotiation: ProtocolNegotiation = negotiateProtocol(undefined);\n readonly observed = new Set<ProtocolCapability>();\n\n /** Record capabilities a message demonstrated; the stock admin announces no version. */\n observe(capabilities: readonly ProtocolCapability[], log: (...args: unknown[]) => void): void {\n const fresh = capabilities.filter((capability) => !this.observed.has(capability));\n if (fresh.length === 0) return;\n for (const capability of fresh) this.observed.add(capability);\n this.negotiation = negotiateProtocol(this.negotiation.theirs, this.observed);\n log('protocol', `observed=${fresh.join(',')}`);\n }\n\n applyVersion(remoteVersion: number, log: (...args: unknown[]) => void): void {\n const current = this.negotiation;\n if (current.theirs === remoteVersion) return;\n const next = negotiateProtocol(remoteVersion, this.observed);\n this.negotiation = next;\n if (next.negotiated === current.negotiated) return;\n log(\n 'protocol',\n `ours=${LIBRARY_PROTOCOL_VERSION}`,\n `theirs=${remoteVersion}`,\n `negotiated=${next.negotiated}`,\n );\n }\n}\n","/**\n * Reads `externallyUpdatedRelationship` as an edge, not as a level. Payload's\n * panel fills the field from `useDocumentEvents().mostRecentUpdate`, a state\n * that every save of the previewed document raises and that nothing ever\n * clears, so the same event repeats in every message for the rest of the\n * session. Two questions make it news again: has the event changed since the\n * last one, and does it name a document other than the one on this page.\n */\n\nimport type {\n PayloadDocumentEventDetail,\n PayloadLivePreviewMessage,\n} from '@/types/payload-protocol';\nimport { readDocumentId } from './binding-owner';\n\n/**\n * Whether the event names a document other than the one this message previews.\n * A message that says which document that is settles it in both directions;\n * one that does not is taken at the event's word, because the repeat is\n * already handled by the identity and one re-render costs less than a drawer\n * edit the page never shows.\n */\nfunction namesAnotherDocument(\n event: PayloadDocumentEventDetail,\n message: PayloadLivePreviewMessage,\n): boolean {\n const previewedSlug = message.globalSlug ?? message.collectionSlug;\n if (typeof previewedSlug !== 'string' || event.entitySlug !== previewedSlug) return true;\n // The same entity. A global holds one document, so the event is its own\n // save; a collection is proven different only when both ids are known and\n // differ.\n const id = readDocumentId(event);\n const previewedId = readDocumentId(message.data ?? {});\n return id !== undefined && previewedId !== undefined && id !== previewedId;\n}\n\n/**\n * Whether the revision a new one supersedes still owes the page a drawer edit.\n *\n * The edit is news on exactly one message, and the panel posts the repeat in\n * the same burst: it supersedes the revision that carried the edit before the\n * server's populated answer arrives, so that answer is dropped, and the repeat\n * asks for nothing itself. The obligation passes to whoever supersedes it and\n * stops at the revision that completes.\n */\nexport function owesForceRender(\n previous: { readonly forceRender: boolean; readonly completed: boolean } | null,\n): boolean {\n return previous !== null && previous.forceRender && !previous.completed;\n}\n\n/** A fully read candidate whose identity can be committed after the revision gate. */\nexport interface RelationshipInspection {\n readonly identity: string;\n readonly edit: PayloadDocumentEventDetail | null;\n}\n\n/** Remembers the last document event the panel sent, so its repeats are one event. */\nexport class RelationshipTracker {\n /**\n * Identity of the last event seen. Not `id` alone: a global's save carries\n * none, and an identity that required one would read every global save as a\n * new document.\n */\n private lastIdentity: string | undefined = undefined;\n\n /**\n * The edit this message brings that the page has not acted on yet: a changed\n * event about another document. `null` for a message without the field, for\n * the repeat, and for the previewed document's own save.\n */\n inspect(message: PayloadLivePreviewMessage): RelationshipInspection | null {\n const event = message.externallyUpdatedRelationship;\n if (typeof event !== 'object' || event === null) return null;\n const identity = JSON.stringify([event.entitySlug, readDocumentId(event), event.updatedAt]);\n const isNew = identity !== this.lastIdentity;\n return {\n identity,\n edit: isNew && namesAnotherDocument(event, message) ? event : null,\n };\n }\n\n /**\n * Claim an inspection only after its revision is still current. Reading the\n * candidate may run synthetic accessors, so mutating in `inspect` would let\n * a stale outer message overwrite the identity a reentrant message set.\n */\n commit(inspection: RelationshipInspection): PayloadDocumentEventDetail | null {\n const isNew = inspection.identity !== this.lastIdentity;\n this.lastIdentity = inspection.identity;\n return isNew ? inspection.edit : null;\n }\n}\n","/**\n * Scroll the edited field's bound element into view. Deliberately quiet: only\n * when the target is off-screen and only when the edited field changed since\n * the last reveal, so continuous typing never re-scrolls and a deliberate\n * scroll-away is not fought. Honours `prefers-reduced-motion`.\n */\n\n/** The slice of `Window` this reads, so it tests without a browser. */\nexport interface RevealWindow {\n readonly innerHeight: number;\n readonly innerWidth: number;\n matchMedia?: (query: string) => { readonly matches: boolean };\n}\n\n/** The slice of `Element` this module needs. */\nexport interface RevealElement {\n getBoundingClientRect: () => {\n readonly top: number;\n readonly bottom: number;\n readonly left: number;\n readonly right: number;\n };\n scrollIntoView: (options?: {\n behavior?: 'auto' | 'smooth';\n block?: 'center' | 'nearest' | 'start';\n }) => void;\n}\n\n/** Whether the viewer asked for reduced motion; smooth scrolling is suppressed when so. */\nexport function prefersReducedMotion(win: RevealWindow): boolean {\n try {\n return win.matchMedia?.('(prefers-reduced-motion: reduce)').matches === true;\n } catch {\n return false;\n }\n}\n\n/** A visible sliver counts: an element the editor can already see is never scrolled to. */\nexport function isInViewport(element: RevealElement, win: RevealWindow): boolean {\n const rect = element.getBoundingClientRect();\n const vertically = rect.bottom > 0 && rect.top < win.innerHeight;\n const horizontally = rect.right > 0 && rect.left < win.innerWidth;\n return vertically && horizontally;\n}\n\n/** Outcome of a reveal attempt, for the caller's diagnostics. */\nexport type RevealOutcome = 'revealed' | 'already-visible';\n\n/** Scroll `element` into view only when it is off-screen. */\nexport function revealElement(element: RevealElement, win: RevealWindow): RevealOutcome {\n if (isInViewport(element, win)) return 'already-visible';\n element.scrollIntoView({\n behavior: prefersReducedMotion(win) ? 'auto' : 'smooth',\n block: 'center',\n });\n return 'revealed';\n}\n\n/** Remembers the last field revealed, so only a change of field scrolls again. */\nexport class FieldRevealer {\n #lastField: string | undefined;\n\n /** `skipped-same` when this is still the field last revealed. */\n reveal(\n fieldName: string,\n element: RevealElement,\n win: RevealWindow,\n ): RevealOutcome | 'skipped-same' {\n if (fieldName === this.#lastField) return 'skipped-same';\n this.#lastField = fieldName;\n return revealElement(element, win);\n }\n\n /** Forget the last field, after a navigation that rebuilt the page. */\n reset(): void {\n this.#lastField = undefined;\n }\n}\n\n/**\n * Scroll one binding into view. Keyed by document as well as field: two\n * documents on one page have their own `title`, and revealing one must not\n * count as revealing the other.\n */\nexport function revealBinding(\n revealer: FieldRevealer,\n target: {\n readonly element: Element;\n readonly owner?: string | undefined;\n readonly fieldName: string;\n },\n): RevealOutcome | 'skipped-same' | 'no-element' {\n const win = target.element.ownerDocument.defaultView as RevealWindow | null;\n if (win === null) return 'no-element';\n return revealer.reveal(`${target.owner ?? ''} ${target.fieldName}`, target.element, win);\n}\n","/**\n * Which value each owned field was last seen with, and the one binding a\n * revision should scroll to: the bookkeeping behind \"reveal the edited field\",\n * kept apart from the pipeline that schedules the writes.\n *\n * Keyed by document, locale and field rather than by element. The element a\n * fragment renders does not survive its own re-render, but the field it shows\n * is the same field.\n *\n * The ledger is written only when a revision reaches its reveal point, not when\n * a candidate is noted. Writing at once lost reveals: an identical re-send\n * superseded the revision that had noted the change, then found nothing new.\n */\n\nimport { valueIdentity } from './value-identity';\n\n/** What the ledger needs of a binding: the key parts, and the element to reveal. */\nexport interface RevealKey {\n readonly owner?: string | undefined;\n readonly locale?: string | undefined;\n readonly fieldName: string;\n}\n\n/** The per-revision slot the ledger fills; the transaction carries it. */\nexport interface RevealSlot<T extends RevealKey> {\n revealIdentities: [key: string, identity: string][];\n revealTarget: T | undefined;\n}\n\nexport class RevealLedger {\n private readonly seen = new Map<string, string>();\n\n /**\n * Record what this binding's value looks like now and, for the first binding\n * whose value moved, mark it as the one to reveal.\n *\n * The first message is a baseline and a binding new to the page is not an\n * edit, so an unseen key only records. A value too large or cyclic to compare\n * cannot claim to have changed either, or it would take the reveal from a\n * field that did.\n */\n note<T extends RevealKey>(slot: RevealSlot<T>, target: T, value: unknown): void {\n const identity = valueIdentity(value);\n if (identity === undefined) return;\n const key = `${target.owner ?? ''}\u0000${target.locale ?? ''}\u0000${target.fieldName}`;\n const seen = this.seen.get(key);\n if (seen === undefined) {\n // A baseline is recorded at once: nothing is owed for it.\n this.seen.set(key, identity);\n return;\n }\n if (seen === identity) return;\n slot.revealIdentities.push([key, identity]);\n slot.revealTarget ??= target;\n }\n\n /**\n * The revision reached its reveal point: what it saw is now what the ledger\n * shows, whether or not there is anything to scroll to. Hands out the\n * binding to reveal once; a second call finds the slot empty.\n */\n commit<T extends RevealKey>(slot: RevealSlot<T>): T | undefined {\n for (const [key, identity] of slot.revealIdentities) this.seen.set(key, identity);\n slot.revealIdentities = [];\n const target = slot.revealTarget;\n slot.revealTarget = undefined;\n return target;\n }\n}\n","/**\n * How completely the page shows one revision (ADR 0023). The session counters\n * say what happened over a session; this says, for the revision in flight,\n * whether work is outstanding and which step fell short, so a host does not\n * have to attribute route outcomes and fragment fallbacks itself.\n */\n\nimport type { DiagnosticCode } from './diagnostic-codes';\nimport type { RuntimeDeps, RuntimeState, UpdateTransaction } from './runtime-state';\nimport { FRAGMENT_ATTRIBUTE, FRAGMENT_KEY_ATTRIBUTE, type RouteOutcome } from './strategies';\n\n/** Where a revision stands: work left, shown, shown with shortfalls, awaiting an island, or replaced (ADR 0023). */\nexport type RevisionDisplayState = 'pending' | 'current' | 'partial' | 'unconfirmed' | 'superseded';\n\n/** One step that kept a settled revision from being current. */\nexport type RevisionShortfall =\n | {\n readonly kind: 'fragment';\n readonly id: string;\n readonly key: string | undefined;\n readonly code: DiagnosticCode;\n }\n | { readonly kind: 'route-saved' }\n | { readonly kind: 'route-failed'; readonly outcome: RouteOutcome }\n | { readonly kind: 'unfaithful' | 'unbound'; readonly field: string }\n | { readonly kind: 'write'; readonly field: string; readonly code: DiagnosticCode }\n | { readonly kind: 'merge' };\n\n/** How completely the page shows one accepted revision (ADR 0023). */\nexport interface RevisionDisplay {\n /** The message revision this record is about. */\n readonly revision: number;\n /** `pending` while work is left; the other states once it settled. */\n readonly state: RevisionDisplayState;\n /** What kept a settled revision from being current; empty unless `state` is `partial`. */\n readonly shortfalls: readonly RevisionShortfall[];\n /** Writes the visibility gate holds until their element is seen; they count as landed. */\n readonly deferred: number;\n /** Islands the revision was handed to that have not called `displayed()`. */\n readonly awaitingIslands: number;\n}\n\n/** What the ledger asks of the runtime: whether work is left, where a settled state goes, and where a failure to say it goes. */\nexport interface RevisionDisplayHost<K> {\n readonly outstanding: (key: K) => boolean;\n readonly report: (display: RevisionDisplay) => void;\n readonly failed: (error: unknown) => void;\n}\n\ninterface Entry<K> {\n key: K | undefined;\n readonly revision: number;\n readonly shortfalls: RevisionShortfall[];\n readonly seen: Set<string>;\n deferred: number;\n awaiting: number;\n reported: RevisionDisplayState | undefined;\n queued: boolean;\n}\n\n/** What an older revision's island is handed: its confirmation no longer counts. */\nconst IGNORED = (): void => undefined;\n\nexport class RevisionDisplayLedger<K extends object> {\n host: RevisionDisplayHost<K> = { outstanding: () => false, report: IGNORED, failed: IGNORED };\n private entry: Entry<K> | null = null;\n private ended: RevisionDisplay | undefined;\n\n /**\n * A newer revision was accepted. The one before it reports now: superseded\n * if it had work left, otherwise the state it reached and had not yet said.\n */\n begin(key: K, revision: number): void {\n const previous = this.entry;\n const view = previous === null ? undefined : this.view(previous);\n // Publish the new owner before a report can end it or accept a newer one.\n if (previous !== null) previous.key = undefined;\n this.ended = undefined;\n this.entry = {\n key,\n revision,\n shortfalls: [],\n seen: new Set(),\n deferred: 0,\n awaiting: 0,\n reported: undefined,\n queued: false,\n };\n if (previous !== null && view !== undefined) {\n this.publish(previous, view.state === 'pending' ? { ...view, state: 'superseded' } : view);\n }\n }\n\n /** End this owner: retain only its display facts, never its transaction or live confirmations. */\n end(): void {\n const entry = this.entry;\n if (entry === null) return;\n this.entry = null;\n try {\n this.ended = this.view(entry);\n } finally {\n // Island and microtask closures may retain the entry after its owner ended.\n entry.key = undefined;\n }\n }\n\n /** The latest accepted revision's record, as `inspect()` reads it. */\n snapshot(): RevisionDisplay | undefined {\n if (this.entry !== null) return this.view(this.entry);\n return this.ended === undefined\n ? undefined\n : { ...this.ended, shortfalls: [...this.ended.shortfalls] };\n }\n\n /** Record a shortfall against `key` while it is the latest revision; the same one twice counts once. */\n shortfall(key: K | null, shortfall: RevisionShortfall): void {\n const entry = this.entry;\n if (entry?.key !== key) return;\n const id = JSON.stringify(shortfall);\n if (entry.seen.has(id)) return;\n entry.seen.add(id);\n entry.shortfalls.push(shortfall);\n this.requestSettle(entry.key);\n }\n\n /** How many of the revision's writes the visibility gate holds, as of its latest flush. */\n deferred(key: K, count: number): void {\n if (this.entry?.key === key) this.entry.deferred = count;\n }\n\n /**\n * An island is handed the revision; the returned callback is its\n * `displayed()`. Late, repeated or superseded calls do nothing.\n */\n handIsland(key: K): () => void {\n const entry = this.entry;\n if (entry?.key !== key) return IGNORED;\n entry.awaiting += 1;\n let confirmed = false;\n return () => {\n if (confirmed || this.entry !== entry) return;\n confirmed = true;\n entry.awaiting -= 1;\n this.settle(entry);\n };\n }\n\n /**\n * Look again once the current task's synchronous work is done: a flush\n * hands islands the revision after it completes, and those count.\n */\n requestSettle(key: K): void {\n const entry = this.entry;\n if (entry?.key !== key || entry.queued) return;\n entry.queued = true;\n queueMicrotask(() => {\n entry.queued = false;\n // Nothing awaits this task: a throw would reach no one but the console.\n try {\n if (this.entry === entry) this.settle(entry);\n } catch (error) {\n this.host.failed(error);\n }\n });\n }\n\n private settle(entry: Entry<K>): void {\n const view = this.view(entry);\n if (view.state !== 'pending') this.publish(entry, view);\n }\n\n private publish(entry: Entry<K>, view: RevisionDisplay): void {\n if (entry.reported === view.state) return;\n entry.reported = view.state;\n this.host.report(view);\n }\n\n private view(entry: Entry<K>): RevisionDisplay {\n // Only the latest entry is viewed; `begin` alone says `superseded`.\n const state: RevisionDisplayState =\n entry.key !== undefined && this.host.outstanding(entry.key)\n ? 'pending'\n : entry.shortfalls.length > 0\n ? 'partial'\n : entry.awaiting > 0\n ? 'unconfirmed'\n : 'current';\n return {\n revision: entry.revision,\n state,\n shortfalls: [...entry.shortfalls],\n deferred: entry.deferred,\n awaitingIslands: entry.awaiting,\n };\n }\n}\n\n/**\n * The runtime's answer to \"is work left\": a revision not yet complete, a\n * boundary still rendering, a route refresh in flight or held back by its\n * window, or writes not flushed. The route counts for whichever revision is\n * current, because it lands for that one (ADR 0004 §4d).\n */\nexport function runtimeDisplayHost(\n deps: Pick<RuntimeDeps, 'scheduler' | 'emitter' | 'a11y' | 'log'>,\n state: Pick<RuntimeState, 'routeController' | 'routeRetry'>,\n): RevisionDisplayHost<UpdateTransaction> {\n return {\n outstanding: (transaction) =>\n !transaction.completed ||\n transaction.pendingFragments > 0 ||\n state.routeController !== null ||\n state.routeRetry !== null ||\n deps.scheduler.pendingCount > 0,\n report: (display) => {\n if (display.state === 'partial') deps.a11y?.announcePartial();\n void deps.emitter.emit('revisionDisplay', display);\n },\n failed: (error) => {\n deps.log('revision display failed:', error);\n },\n };\n}\n\n/** A strategy that threw renders none of its boundaries; each fell back to a patch (LP0801). */\nexport function thrownFragment(boundary: Element): RevisionShortfall {\n const key = boundary.getAttribute(FRAGMENT_KEY_ATTRIBUTE);\n return {\n kind: 'fragment',\n id: boundary.getAttribute(FRAGMENT_ATTRIBUTE) ?? '',\n key: key === null || key.length === 0 ? undefined : key,\n code: 'LP0801',\n };\n}\n","/**\n * What the runtime owns for its lifetime (`RuntimeDeps`) and what changes as it\n * runs (`RuntimeState`). Both are shared by the pipeline collaborators.\n */\n\nimport type {\n PayloadFieldSchema,\n PayloadLivePreviewData,\n PayloadLivePreviewMessage,\n} from '@/types/payload-protocol';\nimport type { EventEmitter } from '@events/emitter';\nimport type { SchemaIndex } from '@schema/index';\nimport type { SanitizerPolicyMode } from '@security/sanitizer';\nimport type { A11yAnnouncer } from './a11y';\nimport type { AutoBindMode, KeptGuesses } from './auto-bind';\nimport type { ElementCache } from './cache';\nimport type { DataMerger } from './data-merger';\nimport type { UnfaithfulPatchMode, UnfaithfulReport } from './fidelity';\nimport type { HydrationMode, HydrationState } from './hydration';\nimport { FieldChangeTracker } from './field-changes';\nimport { MergeNeed } from './merge-need';\nimport type { MessageBus, MessageRevision } from './message-bus';\nimport type { ObserverManager } from './observers';\nimport { ProtocolTracker } from './protocol-tracker';\nimport { RelationshipTracker } from './relationship-tracker';\nimport { FieldRevealer } from './reveal';\nimport { RevealLedger } from './reveal-ledger';\nimport { RevisionDisplayLedger } from './revision-display';\nimport type { RuntimeOptions } from './runtime-options';\nimport type { ConnectionState, HeartbeatTimer } from './state';\nimport type { SubfieldCoverage } from './subfield-coverage';\nimport type { StrategyHandlers } from './strategies';\nimport type { CachedElement, FieldRenderer, RichTextRenderer } from './types';\nimport type { FlushStats, UpdateScheduler } from './update-scheduler';\n\n/** One accepted message on its way to the DOM. See ADR 0004. */\nexport interface UpdateTransaction {\n readonly revision: MessageRevision;\n readonly message: PayloadLivePreviewMessage;\n /** Raw fields captured once when the data-bearing update or replay was accepted. */\n readonly rawData: Record<string, unknown>;\n readonly locale: string | undefined;\n readonly schema: readonly PayloadFieldSchema[] | undefined;\n readonly schemaIndex: SchemaIndex | undefined;\n readonly receivedAt: number;\n /** A save in another document may change populated values only, so render everything. */\n readonly forceRender: boolean;\n /** Whether this transaction came from a newly accepted remote message and contributes to revision counters. */\n readonly countsAsUpdate: boolean;\n /** Latest raw or populated data this revision rendered, retained for late streamed bindings. */\n renderData: PayloadLivePreviewData | undefined;\n /** Fragment boundaries already handed to the strategy for this revision. */\n readonly fragmentBoundariesRun: WeakSet<Element>;\n /** Top-level fields whose value changed since the previous message, plus their dependents. */\n touched: ReadonlySet<string>;\n /** The connection's first message, where every field counts as changed. */\n baseline: boolean;\n /** The first message after a router commit or a restore: every field counts as changed, on markup the server just rendered. */\n navigated: boolean;\n /** Dependents of changed fields; re-applied even when their own value is unchanged. */\n invalidated: ReadonlySet<string>;\n /**\n * First binding whose value changed; revealed once its write landed. The\n * binding itself, not its field name: several documents on one page share\n * field names, and only this one belongs to the edited document.\n */\n revealTarget: CachedElement | undefined;\n /**\n * Identities the reveal ledger will record once this revision reaches its\n * reveal point — not before. A revision superseded on the way there never\n * revealed, so the ledger must still show the previous value: the message\n * that supersedes it is then the one that owes the reveal.\n */\n revealIdentities: [key: string, identity: string][];\n pendingFragments: number;\n routeRefreshed: boolean;\n cancelled: boolean;\n /** Terminal: the scheduled writes reached the DOM (or there were none). */\n completed: boolean;\n}\n\nexport interface RuntimeDeps {\n readonly emitter: EventEmitter;\n readonly cache: ElementCache;\n readonly observers: ObserverManager;\n readonly scheduler: UpdateScheduler;\n readonly bus: MessageBus;\n readonly connection: ConnectionState;\n readonly heartbeat: HeartbeatTimer;\n readonly renderers: Readonly<Record<string, FieldRenderer>>;\n readonly resolveRenderer: NonNullable<RuntimeOptions['resolveRenderer']>;\n readonly transformValue: RuntimeOptions['transformValue'];\n readonly renderRichText: RichTextRenderer | undefined;\n readonly sanitizerPolicy: SanitizerPolicyMode | undefined;\n readonly root: Document | Element;\n readonly readyTargets: () => readonly string[];\n readonly sendReady: (origins: readonly string[]) => void;\n readonly onHeartbeatTimeout: RuntimeOptions['onHeartbeatTimeout'];\n readonly log: (...args: unknown[]) => void;\n readonly warn: (...args: unknown[]) => void;\n readonly a11y: A11yAnnouncer | null;\n readonly merger: DataMerger | null;\n /** The server the merger reads from: where a media path in a populated document points. */\n readonly serverURL: string | undefined;\n /** How long a burst of messages may share one merge; the scheduler's debounce window. */\n readonly mergeWindowMs: number;\n readonly scopeBindingsByOwner: boolean;\n /** ADR 0022: whether one bound descendant covers a group, or each changed path needs its own. */\n readonly subfieldCoverage: SubfieldCoverage;\n readonly lockedOrigin: () => string | undefined;\n readonly skipUnchanged: boolean;\n readonly dependencies: Readonly<Record<string, readonly string[]>>;\n readonly strategies: StrategyHandlers;\n readonly revealEditedField: boolean;\n /** What to do about a patch the runtime knows cannot match the server's render. */\n readonly onUnfaithfulPatch: UnfaithfulPatchMode;\n /** Whether the first message is searched for bindings by value (ADR 0014). */\n readonly autoBind: AutoBindMode;\n /** The framework whose first commit the start waits for (ADR 0015); `undefined` on a page that declared none. */\n readonly hydration: HydrationMode | undefined;\n}\n\nexport class RuntimeState {\n started = false;\n /** Set by `suspend()`; lets `destroy()` finish a suspended instance. */\n suspended = false;\n /** Cancels a startup still waiting — for `DOMContentLoaded`, or for the framework's first commit (ADR 0015). */\n deferredStart: (() => void) | null = null;\n /** How far the wait for hydration got; `idle` on a page that declared none. */\n hydration: HydrationState = 'idle';\n activeUpdate: UpdateTransaction | null = null;\n locale: string | undefined = undefined;\n schema: readonly PayloadFieldSchema[] | undefined = undefined;\n schemaIndex: SchemaIndex | undefined = undefined;\n updateCount = 0;\n supersededCount = 0;\n completedCount = 0;\n skippedUnchangedCount = 0;\n lastFlush: FlushStats | null = null;\n readonly absentFields = new Set<string>();\n readonly warnedOrphanFields = new Set<string>();\n readonly warnedStrategy = new WeakSet<Element>();\n warnedUnattributableMessage = false;\n warnedVisibilityGate = false;\n warnedFragmentFallback = false;\n /** LP0809 is reported once: every later island would fail for the same page-level reason. */\n warnedIslandStart = false;\n /** LP0808 is said once: escalation was asked for and nothing on the page can do it. */\n warnedEscalationUnavailable = false;\n /** LP0503 is reported once: a drifting sender repeats the same shape on every keystroke. */\n warnedProtocolShape = false;\n /** The value each element that fell short was last reported or handed over with, and when (`fidelity.ts`). */\n readonly reportedUnfaithful = new WeakMap<Element, UnfaithfulReport>();\n /** Bindings whose first write has already been held against what the template printed (LP0412). */\n readonly checkedServerFormat = new WeakSet<Element>();\n /** Bindings this revision could not patch faithfully, drained by the flush that escalates them. */\n unfaithfulPatches: CachedElement[] = [];\n /** Every binding ever reported unfaithful, and how many of them a strategy was handed; `inspect().fidelity`. */\n unfaithfulCount = 0;\n escalatedCount = 0;\n readonly unfaithfulFields = new Set<string>();\n /** What the one auto-binding search cost, for `inspect()`; `undefined` until it ran. */\n autoBindSearchMs: number | undefined = undefined;\n /** What that search bound, looked for again after a route refresh (ADR 0014); `null` until it ran. */\n autoBindGuesses: KeptGuesses | null = null;\n\n /**\n * Whether the first message refused for coming from the wrong window has been\n * reported. `eventSourcePolicy` flipped from `'any'` to `'parent-or-opener'`\n * in 2.0, so a 1.x arrangement that posts from anywhere else stops working on\n * upgrade — silently, because a refusal only reaches the debug log.\n */\n warnedForeignSource = false;\n /** Identity of the value each element last applied; reset when the markup is re-rendered. */\n lastAppliedIdentity = new WeakMap<Element, string>();\n /** The next full snapshot follows a router commit, not the initial server baseline. */\n navigationReplayPending = false;\n /** New bindings streamed into the current navigated document receive its latest accepted data. */\n navigationBindingReplay = false;\n /** What each owned field was last seen with, for the reveal decision only. */\n readonly revealLedger = new RevealLedger();\n /** How completely the page shows the latest accepted revision (ADR 0023). */\n readonly display = new RevisionDisplayLedger<UpdateTransaction>();\n readonly fragmentStats = { rendered: 0, failed: 0, superseded: 0 };\n readonly routeStats = { refreshes: 0, partial: 0, failed: 0, refused: 0, loopStopped: 0 };\n /**\n * Every fragment batch still rendering, with the boundaries it has not\n * settled yet; streamed bindings can start more than one per revision.\n */\n readonly fragmentControllers = new Map<AbortController, ReadonlySet<Element>>();\n routeController: AbortController | null = null;\n /** The trailing run a refused refresh asked for; at most one, and always the newest. */\n routeRetry: ReturnType<typeof setTimeout> | null = null;\n /**\n * A trailing run a newer revision took over before it ran. That revision\n * plans from its own diff, which no longer names the field the older one\n * changed, so the debt is carried here until a refresh runs. A refresh\n * already running is not owed: it lands for the newer revision.\n */\n routeRefreshOwed = false;\n /**\n * The route was last rendered from the saved document for a revision holding\n * edits that render could not show (`partial`, ADR 0018): the next save, which\n * puts them on the server, renders it again.\n */\n routeAwaitsSave = false;\n /**\n * Boundaries a newer revision cut short before they settled: the same debt,\n * per boundary, settled when a render of the boundary starts.\n */\n readonly fragmentsOwed = new Set<Element>();\n readonly readyTimers: ReturnType<typeof setTimeout>[] = [];\n readonly revealer = new FieldRevealer();\n readonly changes = new FieldChangeTracker();\n readonly merges = new MergeNeed();\n readonly protocol = new ProtocolTracker();\n readonly relationships = new RelationshipTracker();\n\n /** Read through a method: TypeScript keeps a narrowed `started` across the calls that can flip it. */\n isRunning(): boolean {\n return this.started;\n }\n\n /** Whether `transaction` may still touch the DOM; re-checked after every reentrant callback. */\n isCurrent(transaction: UpdateTransaction): boolean {\n return this.started && this.activeUpdate === transaction;\n }\n\n complete(transaction: UpdateTransaction): void {\n // Asked again after a refresh re-applies it: only then is a refused route settled.\n this.display.requestSettle(transaction);\n if (transaction.completed) return;\n transaction.completed = true;\n if (transaction.countsAsUpdate) this.completedCount += 1;\n }\n\n /** A new route or session starts clean: no refresh or boundary render is owed to it. */\n forgetOwedWork(): void {\n this.routeRefreshOwed = false;\n this.routeAwaitsSave = false;\n this.fragmentsOwed.clear();\n }\n\n /**\n * A newer revision supersedes the older one's revision-bound work: boundary\n * renders carry its fields, and a trailing refresh runs for the revision that\n * asked. Both become debts the newer revision settles, because its message\n * carries the older one's values too while its own diff no longer names them\n * (PHD-07). The route refresh in flight is not revision-bound — it renders\n * the server's view of the route — so it runs on and lands for whichever\n * revision is current then; only a refresh of that revision's own replaces it.\n */\n supersedeStrategies(): void {\n if (this.routeRetry !== null) {\n clearTimeout(this.routeRetry);\n this.routeRetry = null;\n this.routeRefreshOwed = true;\n }\n for (const [controller, unsettled] of this.fragmentControllers) {\n for (const boundary of unsettled) this.fragmentsOwed.add(boundary);\n controller.abort();\n }\n this.fragmentControllers.clear();\n }\n\n /** Abort all strategy work, the route refresh included: a navigation, a lost connection or a stop. */\n abortStrategies(): void {\n this.supersedeStrategies();\n const route = this.routeController;\n this.routeController = null;\n route?.abort();\n }\n}\n","/**\n * Writes one scheduled value into its bound element: renderer resolution,\n * the attribute or renderer write, and the `elementUpdate` event. Every\n * consumer callback may accept a newer revision synchronously, so the\n * transaction is re-checked after each one (ADR 0004).\n */\n\nimport { definedOnly } from '@/types/defined-only';\nimport { sameRevision } from './message-bus';\nimport { lookupSchema, payloadTypeToRenderer } from '@schema/index';\nimport { applyAttributeBinding } from './attribute-binding';\nimport { reportServerFormatting, reportUnfaithfulPatch, watchServerFormatting } from './fidelity';\nimport { rendererUsesNoWriteOutcome } from './internal-outcome';\nimport { type RuntimeDeps, type RuntimeState, type UpdateTransaction } from './runtime-state';\nimport type { CachedElement, FieldRenderer, RenderContext, RendererKey } from './types';\nimport type { ScheduledUpdate } from './update-scheduler';\n\nexport class BindingWriter {\n /** The value being written, which a renderer's report of a shortfall is about. */\n private writing: unknown;\n /** The instance's share of every `RenderContext`, built once: a write allocates the context alone. */\n private readonly instanceContext: Pick<\n RenderContext,\n 'renderRichText' | 'sanitizerPolicy' | 'serverURL' | 'reportUnfaithful'\n >;\n\n constructor(\n private readonly deps: RuntimeDeps,\n private readonly state: RuntimeState,\n ) {\n this.instanceContext = definedOnly({\n renderRichText: deps.renderRichText,\n sanitizerPolicy: deps.sanitizerPolicy,\n serverURL: deps.serverURL,\n // A renderer already holds its target, so one closure per instance says\n // as much as one per write and allocates nothing during an update.\n reportUnfaithful: (target: CachedElement, reason: string): void => {\n reportUnfaithfulPatch(deps, state, target, reason, this.writing);\n },\n });\n }\n\n /** Scheduler callback. `false` means nothing reached the DOM. */\n apply(update: ScheduledUpdate): boolean {\n const { deps, state } = this;\n const transaction = state.activeUpdate;\n if (\n transaction === null ||\n update.revision === undefined ||\n !sameRevision(transaction.revision, update.revision) ||\n !state.isCurrent(transaction)\n ) {\n return false;\n }\n const { target, value } = update;\n const schemaEntry =\n transaction.schemaIndex !== undefined\n ? lookupSchema(transaction.schemaIndex, target.fieldName)\n : undefined;\n let type = resolveFieldType(target, schemaEntry?.type);\n // Payload 3.x sends no schema; a Lexical root is unmistakable.\n if (type === 'text' && target.explicitFieldType !== true && looksLikeLexicalRoot(value)) {\n type = 'richText';\n }\n let renderer: FieldRenderer | undefined;\n try {\n renderer = deps.resolveRenderer(type, target);\n } catch (error) {\n return this.fail(transaction, target.fieldName, error);\n }\n if (!state.isCurrent(transaction)) return false;\n const emitElementUpdate = deps.emitter.listenerCount('elementUpdate') > 0;\n // Custom-element accessors run application code, so this is a boundary too.\n const previous = emitElementUpdate ? readElementSnapshot(target.element) : undefined;\n if (!state.isCurrent(transaction)) return false;\n const context: RenderContext = {\n allFields: update.allFields,\n locale: target.locale ?? transaction.locale,\n schema: schemaEntry,\n ...this.instanceContext,\n };\n // A boundary anchor stays out of layout and the accessibility tree while empty.\n if (target.hidesWhenEmpty === true) {\n target.element.toggleAttribute('hidden', isEmptyFieldValue(value));\n }\n try {\n if (target.targetAttribute !== undefined) {\n if (applyAttributeBinding(target.element, target.targetAttribute, value) === 'blocked') {\n deps.warn(\n `[live-preview] LP0401: refused to write \"${target.fieldName}\" into attribute \"${target.targetAttribute}\"`,\n );\n state.display.shortfall(transaction, {\n kind: 'write',\n field: target.fieldName,\n code: 'LP0401',\n });\n return false;\n }\n } else if (renderer !== undefined) {\n // Read before the write, because afterwards the template's own reading\n // of this value is gone (Z20). Costs nothing unless this is the first\n // write to a binding a formatting renderer owns.\n const shown = watchServerFormatting(deps, state, target, type);\n this.writing = value;\n const outcome = invokeRenderer(renderer, target, value, context);\n if (outcome === false && rendererUsesNoWriteOutcome(renderer)) {\n // The renderer refused the value it was given, so the element still\n // shows what the server put there — right until the next edit makes\n // it stale. That is the moment to ask for better markup.\n reportUnfaithfulPatch(\n deps,\n state,\n target,\n `is a value ${renderer.name} cannot render`,\n value,\n );\n return false;\n }\n if (shown !== undefined) reportServerFormatting(deps, target, shown);\n } else {\n deps.log('no renderer for', type);\n reportUnfaithfulPatch(deps, state, target, `has no renderer for \"${type}\"`, value);\n return false;\n }\n } catch (error) {\n return this.fail(transaction, target.fieldName, error);\n }\n if (!state.isCurrent(transaction)) return false;\n if (emitElementUpdate) {\n void deps.emitter.emitWhile(\n 'elementUpdate',\n {\n element: target.element,\n fieldName: target.fieldName,\n previousValue: previous,\n nextValue: value,\n revision: transaction.revision.revision,\n receivedAt: transaction.receivedAt,\n source: 'patch',\n },\n () => state.isCurrent(transaction),\n );\n }\n // The first handler runs before emitWhile yields; a reentrant newer\n // revision must not count this write as applied.\n const applied = state.isCurrent(transaction);\n if (applied) {\n if (update.valueIdentity !== undefined) {\n state.lastAppliedIdentity.set(target.element, update.valueIdentity);\n } else {\n state.lastAppliedIdentity.delete(target.element);\n }\n }\n return applied;\n }\n\n private fail(transaction: UpdateTransaction, field: string, cause: unknown): false {\n if (!this.state.isCurrent(transaction)) return false;\n this.state.display.shortfall(transaction, { kind: 'write', field, code: 'LP0603' });\n const error = cause instanceof Error ? cause : new Error(String(cause));\n void this.deps.emitter.emitWhile('error', { error, context: 'renderer', code: 'LP0603' }, () =>\n this.state.isCurrent(transaction),\n );\n return false;\n }\n}\n\n/** Explicit `data-payload-type` wins over the schema, which wins over tag heuristics. */\nfunction resolveFieldType(target: CachedElement, schemaType: string | undefined): RendererKey {\n if (target.explicitFieldType) return target.fieldType;\n if (schemaType !== undefined) {\n const mapped = payloadTypeToRenderer(schemaType);\n if (mapped !== undefined) return mapped;\n }\n return target.fieldType;\n}\n\n/** Built-in renderers may return exact `false` for a deliberate no-write; the public type stays `void`. */\nfunction invokeRenderer(\n renderer: FieldRenderer,\n target: CachedElement,\n value: unknown,\n context: RenderContext,\n): unknown {\n // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n return renderer.render(target, value, context);\n}\n\n/**\n * Same shape test as `isLexicalContent`, duplicated so core does not pull the\n * Lexical renderer. The merge decision asks it too, so it reads a value the way\n * this writer will render it.\n */\nexport function looksLikeLexicalRoot(value: unknown): boolean {\n if (typeof value !== 'object' || value === null || !('root' in value)) return false;\n const root = value.root;\n return (\n typeof root === 'object' &&\n root !== null &&\n Array.isArray((root as { children?: unknown }).children)\n );\n}\n\n/**\n * A Lexical root that shows nothing: no node, or paragraphs with no children\n * of their own, which is what Lexical leaves in a field an editor emptied.\n * It is as empty as `null`, for the anchor that hides and for the rich-text\n * write.\n */\nexport function isEmptyLexicalRoot(value: unknown): boolean {\n if (!looksLikeLexicalRoot(value)) return false;\n return (value as { root: { children: readonly unknown[] } }).root.children.every((node) => {\n const { type, children } = (node ?? {}) as { type?: unknown; children?: unknown };\n return type === 'paragraph' && (!Array.isArray(children) || children.length === 0);\n });\n}\n\nfunction readElementSnapshot(element: Element): unknown {\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n return (element as HTMLInputElement).value;\n }\n if (element.tagName === 'IMG') return (element as HTMLImageElement).src;\n return element.textContent;\n}\n\nfunction isEmptyFieldValue(value: unknown): boolean {\n if (value === null || value === undefined) return true;\n if (typeof value === 'string') return value.trim().length === 0;\n return (Array.isArray(value) && value.length === 0) || isEmptyLexicalRoot(value);\n}\n","/**\n * One source → dependents map for `skipUnchanged`. Markup declares it the\n * other way round (`data-payload-depends=\"price\"` on the element bound to\n * `priceLabel`) because an author names what a binding needs; the runtime\n * option is keyed by source because the scheduler asks what changed.\n * @internal\n */\n\nexport type DependencyMap = Readonly<Record<string, readonly string[]>>;\n\n/**\n * Field names from an attribute value. Separators are commas and\n * whitespace; empty entries are dropped; order is kept, duplicates removed.\n * @internal\n */\nexport function parseDependencyList(value: string | null | undefined): readonly string[] {\n if (value === null || value === undefined) return [];\n const seen = new Set<string>();\n const names: string[] = [];\n for (const raw of value.split(/[\\s,]+/)) {\n const name = raw.trim();\n if (name.length === 0 || seen.has(name)) continue;\n seen.add(name);\n names.push(name);\n }\n return names;\n}\n\n/**\n * Merge dependency maps (source → dependents). Later maps add to earlier\n * ones; a dependent is listed once per source.\n * @internal\n */\nexport function mergeDependencyMaps(...maps: readonly DependencyMap[]): DependencyMap {\n const merged = new Map<string, Set<string>>();\n for (const map of maps) {\n for (const [source, dependents] of Object.entries(map)) {\n let bucket = merged.get(source);\n if (bucket === undefined) {\n bucket = new Set();\n merged.set(source, bucket);\n }\n for (const dependent of dependents) bucket.add(dependent);\n }\n }\n const result: Record<string, readonly string[]> = {};\n for (const [source, dependents] of merged) result[source] = [...dependents];\n return result;\n}\n\n/**\n * The map an element's `data-payload-depends` contributes: every declared\n * source points at this binding's field.\n * @internal\n */\nexport function dependencyMapFromBinding(\n fieldName: string,\n dependsOn: readonly string[],\n): DependencyMap {\n const map: Record<string, readonly string[]> = {};\n for (const source of dependsOn) {\n if (source === fieldName) continue;\n map[source] = [fieldName];\n }\n return map;\n}\n","/**\n * Hydrated islands own their subtree, so the runtime never patches inside one.\n * Instead every flush that carried a change dispatches `payload-live-preview:update`\n * on each island root with the update in `detail`, whether or not a binding\n * outside the islands was written. `data-payload-island=\"patch\"` opts back in.\n * Server HTML reaches an Astro island only through Astro's own props handoff\n * (ADR 0021). @internal\n */\n\nexport const ISLAND_EVENT = 'payload-live-preview:update';\n/** @internal */\nexport const ISLAND_ATTRIBUTE = 'data-payload-island';\nexport const ISLAND_SELECTOR = `astro-island, [${ISLAND_ATTRIBUTE}]`;\n/** The opt-out for a subtree the site scripts itself: the morph never enters it. @internal */\nexport const OWNED_ATTRIBUTE = 'data-payload-owned';\n/**\n * The opt-in for a custom element: present on the live and on the rendered host\n * (its value is ignored), the morph edits the host's attributes and light DOM\n * instead of retaining it whole (ADR 0008 §10). @internal\n */\nexport const MORPH_ATTRIBUTE = 'data-payload-morph';\n\n/**\n * The ownership rule (ADR 0008 §4): a subtree the morph never enters. Custom\n * elements own their subtree unless the template opts in with\n * `data-payload-morph` (§10), islands are a framework's, `contenteditable`\n * is the visitor's, `data-payload-owned` is the site's. The coordinators hand\n * this rule to the engine as `MorphOptions.boundary`; the engine itself only\n * pairs, edits and keeps focus (§9). @beta\n */\nexport function isMorphBoundary(element: Element): boolean {\n const customElement = element.tagName.toLowerCase().includes('-');\n if (customElement && !element.hasAttribute(MORPH_ATTRIBUTE)) return true;\n if (isIslandBoundary(element) || element.hasAttribute(OWNED_ATTRIBUTE)) return true;\n const editable = element.getAttribute('contenteditable');\n return editable !== null && editable !== 'false';\n}\n\nexport interface IslandUpdateDetail {\n readonly fields: Readonly<Record<string, unknown>>;\n readonly revision: number;\n readonly receivedAt: number;\n readonly locale: string | undefined;\n /**\n * Call once the island has rendered this revision, for instance from an\n * effect after its framework committed. Until every island handed the\n * revision has called it, `inspect().revisions.display` says `unconfirmed`\n * (ADR 0023). Repeated, late or superseded calls do nothing.\n */\n readonly displayed: () => void;\n}\n\nfunction isIslandRoot(element: Element): boolean {\n return element.tagName.toLowerCase() === 'astro-island' || element.hasAttribute(ISLAND_ATTRIBUTE);\n}\n\nfunction islandAllowsPatching(island: Element): boolean {\n return island.getAttribute(ISLAND_ATTRIBUTE) === 'patch';\n}\n\n/** Whether `element` itself is an island root that did not opt into patching. */\nexport function isIslandBoundary(element: Element): boolean {\n return isIslandRoot(element) && !islandAllowsPatching(element);\n}\n\n/** Whether `element` (or an ancestor) is an island that did not opt into patching. @internal */\nexport function isInsideIsland(element: Element): boolean {\n let current: Element | null = element;\n while (current !== null) {\n if (isIslandBoundary(current)) return true;\n current = current.parentElement;\n }\n return false;\n}\n\n/** Island roots under `root` that receive update events. */\nexport function collectIslands(root: ParentNode): Element[] {\n const islands: Element[] = [];\n for (const island of root.querySelectorAll(ISLAND_SELECTOR)) {\n if (!islandAllowsPatching(island)) islands.push(island);\n }\n return islands;\n}\n\n/** Astro keeps `ssr` until the framework listener has finished hydrating. @internal */\nexport function isAwaitingIslandHydration(island: Element): boolean {\n return island.tagName.toLowerCase() === 'astro-island' && island.hasAttribute('ssr');\n}\n\nexport function dispatchIslandUpdate(\n islands: readonly Element[],\n detail: IslandUpdateDetail,\n isCurrent: () => boolean,\n): number {\n let dispatched = 0;\n for (const island of islands) {\n if (!isCurrent()) break;\n island.dispatchEvent(\n new CustomEvent<IslandUpdateDetail>(ISLAND_EVENT, { detail, bubbles: false }),\n );\n dispatched += 1;\n if (!isCurrent()) break;\n }\n return dispatched;\n}\n\n/** What decides whether a live `astro-island` still renders the rendered one's component (ADR 0021). */\nconst ISLAND_IDENTITY = [\n 'component-url',\n 'component-export',\n 'renderer-url',\n 'client',\n 'opts',\n 'before-hydration-url',\n] as const;\n/** Slot markup each island was last rendered with; Astro reads slots once, at hydration. */\nconst renderedSlots = new WeakMap<Element, string>();\nconst unmountedIslands = new WeakSet<Element>();\n\nfunction isAstroIsland(element: Element): boolean {\n return element.tagName.toLowerCase() === 'astro-island';\n}\n\nfunction slotMarkup(island: Element): string {\n let markup = '';\n for (const slot of island.querySelectorAll('astro-slot, template[data-astro-template]')) {\n if (slot.parentElement?.closest('astro-island') !== island) continue;\n const name = slot.getAttribute('name') ?? slot.getAttribute('data-astro-template') ?? '';\n markup += `${name}\\u0000${slot.innerHTML}\\u0000`;\n }\n return markup;\n}\n\n/** Only an upgraded island whose class observes `props` re-hydrates in place. */\nfunction observesProps(island: Element): boolean {\n const constructor = island.ownerDocument.defaultView?.customElements.get('astro-island') as\n (CustomElementConstructor & { readonly observedAttributes?: unknown }) | undefined;\n return (\n constructor !== undefined &&\n island instanceof constructor &&\n Array.isArray(constructor.observedAttributes) &&\n constructor.observedAttributes.includes('props')\n );\n}\n\n/**\n * The package's decision for a boundary pair (ADR 0021). A boundary other than\n * an Astro island stays whole (ADR 0008 §4). An island that still renders the\n * same component, with the same slots, keeps its framework state: it takes the\n * rendered props the way Astro's router hands them to a persisted island,\n * `ssr` first, then `props`. Anything else is replaced, and hydrates fresh.\n * @beta\n */\nexport function retainIslandBoundary(live: Element, rendered: Element): boolean {\n if (!isAstroIsland(live) || !isAstroIsland(rendered)) return true;\n const slots = slotMarkup(rendered);\n const retained =\n ISLAND_IDENTITY.every((name) => live.getAttribute(name) === rendered.getAttribute(name)) &&\n (renderedSlots.get(live) ?? slotMarkup(live)) === slots &&\n (live.getAttribute('props') === rendered.getAttribute('props') || observesProps(live));\n if (!retained) {\n renderedSlots.set(rendered, slots);\n return false;\n }\n renderedSlots.set(live, slots);\n const props = rendered.getAttribute('props');\n if (props !== live.getAttribute('props')) {\n live.setAttribute('ssr', '');\n if (props === null) live.removeAttribute('props');\n else live.setAttribute('props', props);\n }\n return true;\n}\n\n/** The Astro islands under `root`, to compare before and after a morph. @internal */\nexport function astroIslandsIn(root: ParentNode): Element[] {\n return Array.from(root.querySelectorAll('astro-island'));\n}\n\n/**\n * Astro's framework clients release their roots on `astro:unmount`, which its\n * router sends after a swap. A morph that disconnects an island sends it once\n * itself, so a removed React root does not outlive its markup. @internal\n */\nexport function releaseDisconnectedIslands(islands: readonly Element[]): void {\n for (const island of islands) {\n if (island.isConnected || unmountedIslands.has(island)) continue;\n unmountedIslands.add(island);\n island.dispatchEvent(new CustomEvent('astro:unmount'));\n }\n}\n\n/**\n * Why an inserted island cannot start: fragment scripts never run, so the page\n * itself must have loaded Astro's island element and this client directive.\n * @internal\n */\nexport function islandStartBlocker(island: Element): 'element' | 'directive' | undefined {\n const view = island.ownerDocument.defaultView;\n if (view?.customElements.get('astro-island') === undefined) return 'element';\n const directive = island.getAttribute('client');\n const astro: unknown = Reflect.get(view, 'Astro');\n if (directive === null || typeof astro !== 'object' || astro === null) return 'directive';\n return Reflect.get(astro, directive) === undefined ? 'directive' : undefined;\n}\n","/**\n * Maps field names to their bound elements so an update walks the cache, not\n * the DOM. Everything an update needs about a binding is resolved here, once,\n * at build time.\n */\n\nimport {\n dependencyMapFromBinding,\n mergeDependencyMaps,\n parseDependencyList,\n type DependencyMap,\n} from './dependencies';\nimport { collectIslands } from './islands';\nimport { enclosingFragment, FRAGMENT_ATTRIBUTE, resolveStrategy } from './strategies';\nimport type { CachedElement, ElementPredicate, FieldType, RendererKey } from './types';\n\nexport const FIELD_ATTRIBUTE = 'data-payload-field';\nexport const TYPE_ATTRIBUTE = 'data-payload-type';\nexport const TARGET_ATTRIBUTE_ATTRIBUTE = 'data-payload-attribute';\nexport const HREF_ATTRIBUTE = 'data-payload-href';\nexport const SRC_ATTRIBUTE = 'data-payload-src';\nexport const ALT_ATTRIBUTE = 'data-payload-alt';\nexport const ARRAY_TEMPLATE_ATTRIBUTE = 'data-payload-array-template';\nexport const ARRAY_SEPARATOR_ATTRIBUTE = 'data-payload-array-separator';\nexport const LOCALE_ATTRIBUTE = 'data-payload-locale';\nexport const FORMAT_ATTRIBUTE = 'data-payload-format';\nexport const RICH_TEXT_ATTRIBUTE = 'data-payload-richtext';\nexport const HTML_ATTRIBUTE = 'data-payload-html';\nexport const ARRAY_ATTRIBUTE = 'data-payload-array';\nexport const STRUCTURAL_ATTRIBUTE = 'data-payload-structural';\nexport const OWNER_ATTRIBUTE = 'data-payload-owner';\nexport const DEPENDS_ATTRIBUTE = 'data-payload-depends';\nexport const STRATEGY_ATTRIBUTE = 'data-payload-strategy';\nexport const BOUNDARY_ATTRIBUTE = 'data-payload-boundary';\n/**\n * Written by the runtime, never by a template: the value an auto-binding\n * matched on (ADR 0014). Its presence is what tells a guessed binding from a\n * declared one, in `inspect()` and in the overlay.\n */\nexport const GUESSED_ATTRIBUTE = 'data-payload-guessed';\n/** Field paths a page accounts for without binding them, and everything below them (ADR 0022). */\nexport const COVERS_ATTRIBUTE = 'data-payload-covers';\nexport const INPUT_TYPE_ATTRIBUTE = 'type';\n\n/**\n * Attributes captured in a `CachedElement`. The mutation observer watches\n * exactly this list, so a snapshot can never go stale on a mounted element.\n */\nexport const BINDING_ATTRIBUTES: readonly string[] = [\n FIELD_ATTRIBUTE,\n TYPE_ATTRIBUTE,\n TARGET_ATTRIBUTE_ATTRIBUTE,\n HREF_ATTRIBUTE,\n SRC_ATTRIBUTE,\n ALT_ATTRIBUTE,\n ARRAY_TEMPLATE_ATTRIBUTE,\n ARRAY_SEPARATOR_ATTRIBUTE,\n LOCALE_ATTRIBUTE,\n FORMAT_ATTRIBUTE,\n RICH_TEXT_ATTRIBUTE,\n HTML_ATTRIBUTE,\n ARRAY_ATTRIBUTE,\n STRUCTURAL_ATTRIBUTE,\n OWNER_ATTRIBUTE,\n DEPENDS_ATTRIBUTE,\n STRATEGY_ATTRIBUTE,\n BOUNDARY_ATTRIBUTE,\n INPUT_TYPE_ATTRIBUTE,\n];\n\nconst FIELD_SELECTOR = `[${FIELD_ATTRIBUTE}]`;\nconst OWNER_SELECTOR = `[${OWNER_ATTRIBUTE}]`;\n/** Structural strategy roots whose arrival after navigation needs the retained document. @internal */\nexport const NAVIGATION_REPLAY_SELECTOR = `[${FRAGMENT_ATTRIBUTE}], [${STRATEGY_ATTRIBUTE}=\"route\"]`;\n\n/** The document a binding belongs to: its nearest `data-payload-owner`, itself included. */\nexport function resolveBindingOwner(element: Element): string | undefined {\n const owner = element.closest(OWNER_SELECTOR)?.getAttribute(OWNER_ATTRIBUTE);\n return owner === null || owner === undefined || owner.length === 0 ? undefined : owner;\n}\n\n/** `namespace:name` — a project renderer key can never be a typo of a built-in type. */\nconst CUSTOM_RENDERER_KEY = /^[a-z][a-z0-9-]*:[a-z][a-z0-9-]*$/i;\n\nconst VALID_FIELD_TYPES: ReadonlySet<FieldType> = new Set<FieldType>([\n 'text',\n 'textarea',\n 'richText',\n 'email',\n 'number',\n 'checkbox',\n 'date',\n 'select',\n 'radio',\n 'array',\n 'blocks',\n 'group',\n 'tabs',\n 'row',\n 'collapsible',\n 'relationship',\n 'upload',\n 'point',\n 'json',\n 'code',\n 'ui',\n 'html',\n 'url',\n 'image',\n 'structural-array',\n]);\n\nfunction isRendererKey(value: string): value is RendererKey {\n return VALID_FIELD_TYPES.has(value as FieldType) || CUSTOM_RENDERER_KEY.test(value);\n}\n\n/** One `data-payload-covers` declaration: the paths it names, for the owner it sits under. */\nexport interface CoverDeclaration {\n readonly paths: readonly string[];\n readonly owner: string | undefined;\n}\n\n/** The fields a fragment boundary or a route marker depends on, which its strategy renders. */\nexport interface RenderedDeclaration extends CoverDeclaration {\n readonly strategy: 'fragment' | 'route';\n}\n\n/**\n * The strategy that renders what an element depends on, by the planners' own\n * rules: the fragment planner takes every named boundary, the route planner a\n * route-bound element — marked `route`, or a binding in `<head>` left unmarked\n * (`src/fragment/boundary.ts`, `src/fragment/route.ts`). @internal\n */\nexport function renderingStrategy(element: Element): RenderedDeclaration['strategy'] | undefined {\n if ((element.getAttribute(FRAGMENT_ATTRIBUTE) ?? '').length > 0) return 'fragment';\n const explicit = element.getAttribute(STRATEGY_ATTRIBUTE);\n if (explicit !== null) return explicit === 'route' ? 'route' : undefined;\n return element.hasAttribute(FIELD_ATTRIBUTE) && element.closest('head') !== null\n ? 'route'\n : undefined;\n}\n\nexport interface CacheBuildStats {\n readonly elementCount: number;\n readonly fieldCount: number;\n readonly durationMs: number;\n}\n\nexport interface ElementCacheOptions {\n /** Restricts which elements are accepted. Defaults to all. */\n readonly filter?: ElementPredicate;\n}\n\n/** Metadata that decides whether buffered work still addresses the same owned strategy target. */\nexport function hasSameBindingIdentity(a: CachedElement, b: CachedElement): boolean {\n return (\n a.fieldName === b.fieldName &&\n a.locale === b.locale &&\n a.owner === b.owner &&\n a.strategyKind === b.strategyKind &&\n a.fragmentBoundary === b.fragmentBoundary\n );\n}\n\n/**\n * Elements share a field name when the same field is rendered in several\n * places; within a field the order is DOM order.\n */\nexport class ElementCache {\n private readonly entriesByField = new Map<string, CachedElement[]>();\n private entryByElement = new WeakMap<Element, CachedElement>();\n private readonly filter: ElementPredicate;\n private count = 0;\n private dependencies: DependencyMap | null = null;\n private islandRoots: readonly Element[] = [];\n private ownersByIsland: ReadonlyMap<Element, string | undefined> = new Map();\n private navigationRoots: readonly Element[] = [];\n private coverDeclarations: readonly CoverDeclaration[] = [];\n private renderedDeclarations: readonly RenderedDeclaration[] = [];\n\n constructor(options: ElementCacheOptions = {}) {\n this.filter = options.filter ?? alwaysTrue;\n }\n\n /** Source → dependents declared with `data-payload-depends`; memoised until the cache changes. */\n dependencyMap(): DependencyMap {\n if (this.dependencies !== null) return this.dependencies;\n const maps: DependencyMap[] = [];\n for (const binding of this.values()) {\n if (binding.dependsOn !== undefined) {\n maps.push(dependencyMapFromBinding(binding.fieldName, binding.dependsOn));\n }\n }\n this.dependencies = mergeDependencyMaps(...maps);\n return this.dependencies;\n }\n\n /** Island roots under the last built root, for update events. */\n get islands(): readonly Element[] {\n return this.islandRoots;\n }\n\n /** Owner identities captured with `islands`; used to detect a live retarget. @internal */\n get islandOwners(): ReadonlyMap<Element, string | undefined> {\n return this.ownersByIsland;\n }\n\n /** `data-payload-covers` declarations under the last built root. */\n get covers(): readonly CoverDeclaration[] {\n return this.coverDeclarations;\n }\n\n /** Boundaries and route markers under the last built root that name the fields they depend on. */\n get rendered(): readonly RenderedDeclaration[] {\n return this.renderedDeclarations;\n }\n\n /** Fieldless strategy roots under the last built root, for navigation replay. */\n get navigationReplayRoots(): readonly Element[] {\n return this.navigationRoots;\n }\n\n buildFromRoot(root: ParentNode): CacheBuildStats {\n const t0 = performance.now();\n this.clear();\n let elementCount = 0;\n for (const element of root.querySelectorAll(FIELD_SELECTOR)) {\n if (this.add(element) !== undefined) elementCount += 1;\n }\n this.islandRoots = collectIslands(root);\n this.ownersByIsland = new Map(\n this.islandRoots.map((island) => [island, resolveBindingOwner(island)]),\n );\n this.navigationRoots = [...root.querySelectorAll(NAVIGATION_REPLAY_SELECTOR)].filter(\n (element) =>\n this.filter(element) &&\n (element.hasAttribute(FRAGMENT_ATTRIBUTE) ||\n (element.getAttribute(FIELD_ATTRIBUTE) ?? '').length === 0),\n );\n this.coverDeclarations = [...root.querySelectorAll(`[${COVERS_ATTRIBUTE}]`)]\n .filter((element) => this.filter(element))\n .map((element) => ({\n paths: parseDependencyList(element.getAttribute(COVERS_ATTRIBUTE)),\n owner: resolveBindingOwner(element),\n }));\n this.renderedDeclarations = [...root.querySelectorAll(`[${DEPENDS_ATTRIBUTE}]`)]\n .filter((element) => this.filter(element))\n .flatMap((element): RenderedDeclaration[] => {\n const strategy = renderingStrategy(element);\n if (strategy === undefined) return [];\n const paths = parseDependencyList(element.getAttribute(DEPENDS_ATTRIBUTE));\n return [{ strategy, paths, owner: resolveBindingOwner(element) }];\n });\n return {\n elementCount,\n fieldCount: this.entriesByField.size,\n durationMs: performance.now() - t0,\n };\n }\n\n /**\n * Insert or replace a single element's binding. Re-adding refreshes the\n * snapshot in place; an element that is now filtered or unbound is removed.\n */\n add(element: Element): CachedElement | undefined {\n // Resolve before mutating so a throwing filter leaves the old entry intact.\n const entry = this.filter(element) ? this.resolveBinding(element) : undefined;\n const previous = this.entryByElement.get(element);\n this.dependencies = null;\n if (entry === undefined) {\n if (previous !== undefined) this.removeEntry(element, previous);\n return undefined;\n }\n if (previous !== undefined && this.replaceEntry(previous, entry)) {\n this.entryByElement.set(element, entry);\n return entry;\n }\n if (previous !== undefined) this.removeEntry(element, previous);\n this.append(entry);\n this.entryByElement.set(element, entry);\n return entry;\n }\n\n /** Returns whether a binding was removed. */\n remove(element: Element): boolean {\n const entry = this.entryByElement.get(element);\n if (!entry) return false;\n this.dependencies = null;\n return this.removeEntry(element, entry);\n }\n\n get(fieldName: string): readonly CachedElement[] | undefined {\n return this.entriesByField.get(fieldName);\n }\n\n getByElement(element: Element): CachedElement | undefined {\n return this.entryByElement.get(element);\n }\n\n get fieldCount(): number {\n return this.entriesByField.size;\n }\n\n get elementCount(): number {\n return this.count;\n }\n\n entries(): IterableIterator<[string, readonly CachedElement[]]> {\n return this.entriesByField.entries() as IterableIterator<[string, readonly CachedElement[]]>;\n }\n\n *values(): IterableIterator<CachedElement> {\n for (const bucket of this.entriesByField.values()) yield* bucket;\n }\n\n has(element: Element): boolean {\n return this.entryByElement.has(element);\n }\n\n clear(): void {\n this.entriesByField.clear();\n // WeakMap cannot be cleared; a detached element must not observe stale membership.\n this.entryByElement = new WeakMap();\n this.count = 0;\n this.dependencies = null;\n this.islandRoots = [];\n this.ownersByIsland = new Map();\n this.navigationRoots = [];\n this.coverDeclarations = [];\n this.renderedDeclarations = [];\n }\n\n /** Replace in place when the field bucket is unchanged, preserving order. */\n private replaceEntry(previous: CachedElement, next: CachedElement): boolean {\n if (previous.fieldName !== next.fieldName) return false;\n const bucket = this.entriesByField.get(previous.fieldName);\n const index = bucket === undefined ? -1 : bucket.indexOf(previous);\n if (bucket === undefined || index < 0) return false;\n bucket[index] = next;\n return true;\n }\n\n private removeEntry(element: Element, entry: CachedElement): boolean {\n this.entryByElement.delete(element);\n const bucket = this.entriesByField.get(entry.fieldName);\n const index = bucket === undefined ? -1 : bucket.indexOf(entry);\n if (bucket === undefined || index < 0) return false;\n bucket.splice(index, 1);\n if (bucket.length === 0) this.entriesByField.delete(entry.fieldName);\n this.count -= 1;\n return true;\n }\n\n private append(entry: CachedElement): void {\n const bucket = this.entriesByField.get(entry.fieldName);\n if (bucket) bucket.push(entry);\n else this.entriesByField.set(entry.fieldName, [entry]);\n this.count += 1;\n }\n\n private resolveBinding(element: Element): CachedElement | undefined {\n const fieldName = element.getAttribute(FIELD_ATTRIBUTE);\n if (fieldName === null || fieldName.length === 0) return undefined;\n const explicit = element.getAttribute(TYPE_ATTRIBUTE);\n const targetAttribute = element.getAttribute(TARGET_ATTRIBUTE_ATTRIBUTE);\n const hrefField = element.getAttribute(HREF_ATTRIBUTE);\n const srcField = element.getAttribute(SRC_ATTRIBUTE);\n const altField = element.getAttribute(ALT_ATTRIBUTE);\n const arrayTemplate = element.getAttribute(ARRAY_TEMPLATE_ATTRIBUTE);\n const arraySeparator = element.getAttribute(ARRAY_SEPARATOR_ATTRIBUTE);\n const locale = element.getAttribute(LOCALE_ATTRIBUTE);\n const format = element.getAttribute(FORMAT_ATTRIBUTE);\n const owner = resolveBindingOwner(element);\n const dependsOn = parseDependencyList(element.getAttribute(DEPENDS_ATTRIBUTE));\n const strategy = element.getAttribute(STRATEGY_ATTRIBUTE);\n const guessed = element.getAttribute(GUESSED_ATTRIBUTE);\n const fragmentBoundary = enclosingFragment(element);\n return {\n element,\n fieldName,\n fieldType: resolveFieldType(element),\n explicitFieldType: explicit !== null && isRendererKey(explicit),\n strategyKind: resolveStrategy(element) ?? 'unknown',\n ...(fragmentBoundary !== null ? { fragmentBoundary } : {}),\n ...(targetAttribute !== null && targetAttribute.length > 0 ? { targetAttribute } : {}),\n ...(hrefField !== null && hrefField.length > 0 ? { hrefField } : {}),\n ...(srcField !== null && srcField.length > 0 ? { srcField } : {}),\n ...(altField !== null && altField.length > 0 ? { altField } : {}),\n ...(arrayTemplate !== null ? { arrayTemplate } : {}),\n ...(arraySeparator !== null ? { arraySeparator } : {}),\n ...(locale !== null && locale.length > 0 ? { locale } : {}),\n ...(format !== null && format.length > 0 ? { format } : {}),\n ...(owner !== undefined ? { owner } : {}),\n ...(dependsOn.length > 0 ? { dependsOn } : {}),\n ...(strategy !== null && strategy.length > 0 ? { strategy } : {}),\n ...(element.hasAttribute(BOUNDARY_ATTRIBUTE) ? { hidesWhenEmpty: true } : {}),\n ...(guessed !== null ? { guessed } : {}),\n };\n }\n}\n\n/** Explicit `data-payload-type`, then element heuristics, then `text`. */\nexport function resolveFieldType(element: Element): RendererKey {\n const explicit = element.getAttribute(TYPE_ATTRIBUTE);\n if (explicit !== null && isRendererKey(explicit)) return explicit;\n if (element.hasAttribute(RICH_TEXT_ATTRIBUTE)) return 'richText';\n if (element.hasAttribute(HTML_ATTRIBUTE)) return 'html';\n if (element.hasAttribute(STRUCTURAL_ATTRIBUTE)) return 'structural-array';\n if (element.hasAttribute(ARRAY_ATTRIBUTE)) return 'array';\n if (element.tagName === 'IMG') return 'image';\n if (element.tagName === 'A') return 'url';\n if (element.tagName === 'TIME') return 'date';\n if (element.tagName === 'INPUT') {\n const inputType = (element as HTMLInputElement).type;\n if (inputType === 'checkbox') return 'checkbox';\n if (inputType === 'number') return 'number';\n if (inputType === 'date' || inputType === 'datetime-local') return 'date';\n }\n return 'text';\n}\n\nfunction alwaysTrue(): boolean {\n return true;\n}\n","/**\n * Payload 2 posts raw form values and a schema, rather than a server merge target.\n * Plan collection GETs from that schema and fill an independent document only\n * after every requested identity is present; the caller owns request cancellation.\n */\nimport type { PayloadFieldSchema } from '@/types/payload-protocol';\nimport { isPlainObject } from './message-guards';\n\nconst MAX_DEPTH = 64;\nconst MAX_NODES = 10_000;\nconst MAX_IDS = 1_000;\nconst MAX_REQUESTS = 64;\nconst MAX_URL = 8_192;\nconst MAX_BODY = 1_048_576;\nconst MAX_CHUNKS = 10_000;\nconst CHUNK = 20;\nconst FORBIDDEN = new Set(['__proto__', 'constructor', 'prototype']);\ntype RecordValue = Record<string, unknown>;\ninterface Slot {\n readonly owner: RecordValue | unknown[];\n readonly key: string | number;\n readonly id: string;\n}\nexport interface LegacyRequest {\n readonly url: string;\n readonly ids: ReadonlySet<string>;\n readonly slots: readonly Slot[];\n}\nexport interface LegacyPlan {\n readonly doc: RecordValue;\n readonly requests: readonly LegacyRequest[];\n}\n\nfunction fail(): never {\n throw new Error('invalid or oversized legacy population');\n}\nfunction hasControl(value: string): boolean {\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n if (code <= 31 || code === 127) return true;\n }\n return false;\n}\nfunction segment(value: unknown, maximum: number): value is string {\n if (\n typeof value !== 'string' ||\n value.length === 0 ||\n value.length > maximum ||\n value === '.' ||\n value === '..'\n ) {\n return false;\n }\n if (value.includes('/') || value.includes('\\\\') || hasControl(value)) return false;\n try {\n encodeURIComponent(value);\n return true;\n } catch {\n return false;\n }\n}\nfunction slug(value: unknown): value is string {\n return segment(value, 128) && !/[?#%]/u.test(value) && !FORBIDDEN.has(value);\n}\nfunction id(value: unknown): string {\n if (Number.isFinite(value)) return String(value);\n if (segment(value, 512)) return value;\n return fail();\n}\nfunction own(record: RecordValue | unknown[], key: string | number): unknown {\n return Object.hasOwn(record, key) ? Reflect.get(record, key) : undefined;\n}\nfunction put(record: RecordValue | unknown[], key: string | number, value: unknown): void {\n Object.defineProperty(record, key, {\n value,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n}\nfunction stripTrailingSlashes(value: string): string {\n let end = value.length;\n while (end > 0 && value.charCodeAt(end - 1) === 47) end -= 1;\n return value.slice(0, end);\n}\n\n/** Copy only structured data, bounded before the planner follows any relation. */\nexport function copyLegacyData(value: unknown): unknown {\n const active = new WeakSet();\n let nodes = 0;\n let characters = 0;\n function copy(value: unknown, depth: number): unknown {\n if (++nodes > MAX_NODES || depth > MAX_DEPTH) return fail();\n if (typeof value === 'string') {\n characters += value.length;\n if (characters > MAX_BODY) fail();\n return value;\n }\n if (value === null || value === undefined || typeof value === 'boolean') return value;\n if (typeof value === 'number') return Number.isFinite(value) ? value : fail();\n if (!Array.isArray(value) && !isPlainObject(value)) return fail();\n if (Array.isArray(value)) {\n if (value.length > MAX_NODES) fail();\n for (let index = 0; index < value.length; index += 1) {\n if (!Object.hasOwn(value, index)) fail();\n }\n }\n if (active.has(value)) return fail();\n active.add(value);\n const result: RecordValue | unknown[] = Array.isArray(value) ? [] : {};\n for (const key of Object.keys(value)) {\n put(result, key, copy(Reflect.get(value, key), depth + 1));\n }\n active.delete(value);\n return result;\n }\n return copy(value, 0);\n}\n\nexport function planLegacyPopulation(\n data: RecordValue,\n schema: readonly PayloadFieldSchema[],\n serverURL: string,\n apiRoute: string,\n depth: number,\n locale?: string,\n): LegacyPlan {\n if (!Number.isSafeInteger(depth) || depth < 0 || depth > MAX_DEPTH) return fail();\n if (\n locale !== undefined &&\n (typeof locale !== 'string' || locale.length > 128 || hasControl(locale))\n ) {\n fail();\n }\n const doc = copyLegacyData(data);\n if (!isPlainObject(doc)) return fail();\n const groups = new Map<string, Slot[]>();\n const unique = new Set<string>();\n let nodes = 0;\n const active = new WeakSet();\n const tick = (level: number): void => {\n if (++nodes > MAX_NODES || level > MAX_DEPTH) fail();\n };\n\n function relation(\n owner: RecordValue | unknown[],\n key: string | number,\n collection: string,\n value: unknown,\n ): void {\n if (value === null || value === undefined || value === '') return;\n const selected = isPlainObject(value) ? own(value, 'id') : value;\n const identity = id(selected);\n if (depth === 0) {\n put(owner, key, selected);\n return;\n }\n const scope = JSON.stringify([collection, identity]);\n unique.add(scope);\n if (unique.size > MAX_IDS) fail();\n const slots = groups.get(collection) ?? [];\n slots.push({ owner, key, id: identity });\n groups.set(collection, slots);\n }\n function fieldRelation(\n owner: RecordValue | unknown[],\n key: string | number,\n field: PayloadFieldSchema,\n ): void {\n if (field.hasMany !== undefined && typeof field.hasMany !== 'boolean') fail();\n const allowed = field.relationTo;\n const value = own(owner, key);\n if (Array.isArray(allowed)) {\n if (allowed.length === 0) fail();\n const collection = isPlainObject(value) ? own(value, 'relationTo') : undefined;\n let selectedCollection: string | undefined;\n for (const candidate of allowed) {\n tick(0);\n if (!slug(candidate)) fail();\n if (candidate === collection) selectedCollection = candidate;\n }\n if (value === null || value === undefined || value === '') return;\n if (!isPlainObject(value) || selectedCollection === undefined) fail();\n relation(value, 'value', selectedCollection, own(value, 'value'));\n } else {\n if (!slug(allowed)) fail();\n relation(owner, key, allowed, value);\n }\n }\n function rich(value: unknown, level: number): void {\n tick(level);\n if (!Array.isArray(value) && !isPlainObject(value)) return;\n if (\n isPlainObject(value) &&\n Object.hasOwn(value, 'relationTo') &&\n Object.hasOwn(value, 'value')\n ) {\n const collection = own(value, 'relationTo');\n if (!slug(collection)) fail();\n relation(value, 'value', collection, own(value, 'value'));\n return;\n }\n for (const key of Object.keys(value)) rich(Reflect.get(value, key), level + 1);\n }\n function walk(fields: readonly PayloadFieldSchema[], record: RecordValue, level: number): void {\n tick(level);\n if (active.has(fields)) fail();\n active.add(fields);\n for (const field of fields) {\n tick(level);\n if (!isPlainObject(field) || !segment(field.name, 512) || FORBIDDEN.has(field.name)) fail();\n const value = own(record, field.name);\n if (field.type === 'relationship' || field.type === 'upload') {\n if (field.hasMany) {\n if (value !== null && value !== undefined && !Array.isArray(value)) fail();\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i += 1) fieldRelation(value, i, field);\n } else fieldRelation(record, field.name, field);\n } else fieldRelation(record, field.name, field);\n } else if (field.type === 'group' || field.type === 'tabs') {\n if (value != null && !isPlainObject(value)) fail();\n if (isPlainObject(value) && field.fields) walk(field.fields, value, level + 1);\n } else if (field.type === 'row' || field.type === 'collapsible') {\n if (field.fields) walk(field.fields, record, level + 1);\n } else if (field.type === 'array' || field.type === 'blocks') {\n if (value === 0) put(record, field.name, []);\n else if (value != null && !Array.isArray(value)) fail();\n if (Array.isArray(value)) {\n for (const row of value) {\n if (!isPlainObject(row)) fail();\n if (field.type === 'array' && field.fields) walk(field.fields, row, level + 1);\n else if (field.type === 'blocks') {\n const blockType = own(row, 'blockType');\n const block = field.blocks?.find((candidate) => {\n tick(level);\n return candidate.slug === blockType;\n });\n if (block === undefined) fail();\n walk(block.fields, row, level + 1);\n }\n }\n }\n } else if (field.type === 'richText') rich(value, level + 1);\n }\n active.delete(fields);\n }\n walk(schema, doc, 0);\n if (groups.size > 25) fail();\n const requests: LegacyRequest[] = [];\n if (groups.size === 0) return { doc, requests };\n const base = new URL(serverURL);\n if (\n !['http:', 'https:'].includes(base.protocol) ||\n base.username ||\n base.password ||\n base.search ||\n base.hash\n ) {\n fail();\n }\n if (\n !apiRoute.startsWith('/') ||\n apiRoute.includes('\\\\') ||\n /[%?#]/u.test(apiRoute) ||\n hasControl(apiRoute)\n ) {\n fail();\n }\n if (apiRoute.split('/').some((part) => part === '.' || part === '..')) fail();\n const prefix = `${stripTrailingSlashes(serverURL)}${stripTrailingSlashes(apiRoute)}/`;\n for (const [collection, slots] of groups) {\n const identities = [...new Set(slots.map((slot) => slot.id))];\n let index = 0;\n while (index < identities.length) {\n const first = identities[index];\n if (first === undefined) fail();\n const comma = first.includes(',');\n const chunk: string[] = [];\n let url = '';\n while (index < identities.length && chunk.length < CHUNK) {\n const next = identities[index];\n if (next === undefined || (chunk.length > 0 && (comma || next.includes(',')))) break;\n const proposed = [...chunk, next];\n const query = new URLSearchParams({\n depth: String(depth),\n limit: String(proposed.length),\n });\n if (locale !== undefined) query.set('locale', locale);\n query.set(comma ? 'where[id][equals]' : 'where[id][in]', comma ? next : proposed.join(','));\n const candidate = `${prefix}${encodeURIComponent(collection)}?${query}`;\n if (candidate.length > MAX_URL) {\n if (chunk.length === 0) fail();\n break;\n }\n if (new URL(candidate).origin !== base.origin) fail();\n chunk.push(next);\n index += 1;\n url = candidate;\n }\n if (chunk.length === 0 || requests.length >= MAX_REQUESTS) fail();\n const ids = new Set(chunk);\n requests.push({\n url,\n ids,\n slots: slots.filter((slot) => ids.has(slot.id)),\n });\n }\n }\n return { doc, requests };\n}\n\n/** Native bodies stop at byte and chunk limits; injected json-only shims still get shape limits. */\nexport async function populationBody(\n response: Response,\n signal: AbortSignal,\n current: () => boolean,\n): Promise<unknown> {\n let reader: ReadableStreamDefaultReader<Uint8Array> | undefined;\n let cancelled = false;\n let finished = false;\n const obsolete = Symbol();\n let interrupt: (() => void) | undefined;\n const interrupted = new Promise<typeof obsolete>((resolve) => {\n interrupt = () => {\n resolve(obsolete);\n };\n });\n const check = (): void => {\n if (!current() || signal.aborted) fail();\n };\n const cancel = (): void => {\n if (reader === undefined || cancelled) return;\n cancelled = true;\n try {\n void Promise.resolve(reader.cancel()).catch(() => {\n /* teardown remains authoritative */\n });\n } catch {\n /* teardown remains authoritative */\n }\n };\n const abort = (): void => {\n interrupt?.();\n cancel();\n };\n signal.addEventListener('abort', abort, { once: true });\n try {\n check();\n const body = response.body ?? null;\n check();\n if (body === null) {\n const json: () => Promise<unknown> = response.json.bind(response);\n check();\n const value: unknown = await Promise.race([\n Promise.resolve().then(() => {\n check();\n return json();\n }),\n interrupted,\n ]);\n check();\n if (value === obsolete) fail();\n return value;\n }\n const getReader: () => ReadableStreamDefaultReader<Uint8Array> = body.getReader.bind(body);\n check();\n const activeReader = getReader();\n reader = activeReader;\n check();\n const chunks: Uint8Array[] = [];\n let bytes = 0;\n let count = 0;\n for (;;) {\n const pending = Promise.resolve().then(() => {\n check();\n const read = activeReader.read.bind(activeReader);\n check();\n return read();\n });\n const result = await Promise.race([pending, interrupted]);\n check();\n if (result === obsolete) fail();\n if (result.done) break;\n bytes += result.value.byteLength;\n if (++count > MAX_CHUNKS || bytes > MAX_BODY) fail();\n chunks.push(result.value);\n }\n finished = true;\n const data = new Uint8Array(bytes);\n let position = 0;\n for (const chunk of chunks) {\n data.set(chunk, position);\n position += chunk.byteLength;\n }\n try {\n return JSON.parse(new TextDecoder().decode(data));\n } catch {\n return fail();\n }\n } finally {\n signal.removeEventListener('abort', abort);\n if (!finished) cancel();\n try {\n reader?.releaseLock();\n } catch {\n /* a hostile pending read cannot own cleanup */\n }\n }\n}\n\nexport function fillLegacyPopulation(request: LegacyRequest, body: unknown): void {\n const safe = copyLegacyData(body);\n if (!isPlainObject(safe)) fail();\n const docs = own(safe, 'docs');\n if (!Array.isArray(docs) || docs.length > CHUNK) fail();\n const found = new Map<string, unknown>();\n for (const raw of docs) {\n if (!isPlainObject(raw)) fail();\n const identity = id(own(raw, 'id'));\n if (!request.ids.has(identity) || found.has(identity)) fail();\n found.set(identity, raw);\n }\n if (found.size !== request.ids.size) fail();\n for (const slot of request.slots) put(slot.owner, slot.key, found.get(slot.id));\n}\n","/**\n * Payload 3 raw form values use its REST merge with the method-override header.\n * Payload 2 sends a schema instead of a target, so it uses local values and\n * collection GETs to populate references. A newer merge aborts the one in flight,\n * and captured attempt identity drops obsolete results even when a shim ignores abort.\n */\n\nimport { isolateDiagnostic, noopDiagnostic } from './diagnostics';\nimport type { PayloadFieldSchema } from '@/types/payload-protocol';\nimport { fillLegacyPopulation, planLegacyPopulation, populationBody } from './legacy-population';\n\nexport interface DataMergerOptions {\n /** Payload server origin, e.g. `https://cms.example.com`. */\n readonly serverURL: string;\n /** REST route prefix. Defaults to `/api`. */\n readonly apiRoute?: string;\n /** Population depth requested from the server. Defaults to `1`. */\n readonly depth?: number;\n readonly fetchFn?: typeof fetch;\n readonly log?: (...args: unknown[]) => void;\n}\n\nexport interface MergeRequest {\n readonly schema?: readonly PayloadFieldSchema[] | undefined;\n readonly collectionSlug?: string | undefined;\n readonly globalSlug?: string | undefined;\n readonly data: Record<string, unknown>;\n readonly locale?: string | undefined;\n}\n\n/** `superseded`: a newer merge replaced this one. `unavailable`: fall back to the raw values. */\nexport type MergeResult =\n | { readonly status: 'merged'; readonly doc: Record<string, unknown> }\n | { readonly status: 'superseded' }\n | { readonly status: 'unavailable' };\n\ninterface MergeTarget {\n readonly path: string;\n readonly field: 'id' | 'globalType';\n readonly value: string;\n}\n\nfunction hasControlCharacter(value: string): boolean {\n for (const character of value) {\n // An iterated character always has a code point; 0 keeps the type and fails closed.\n const codePoint = character.codePointAt(0) ?? 0;\n if (codePoint <= 0x1f || codePoint === 0x7f) return true;\n }\n return false;\n}\n\n/** One path segment: non-empty, bounded, not a dot segment, without separators or control characters. */\nfunction isPathSegment(value: string, maxLength: number): boolean {\n return (\n value.length > 0 &&\n value.length <= maxLength &&\n value !== '.' &&\n value !== '..' &&\n !value.includes('/') &&\n !value.includes('\\\\') &&\n !hasControlCharacter(value)\n );\n}\n\n/** A slug is one of Payload's own names; `?` and `#` never belong in one. */\nfunction isSafeSlug(value: string): boolean {\n return isPathSegment(value, 128) && !value.includes('?') && !value.includes('#');\n}\n\n/** An id comes from the form values; a string one is encoded, so `?` and `#` may appear. */\nfunction isSafeId(value: unknown): value is string | number {\n if (typeof value === 'number') return Number.isFinite(value);\n return typeof value === 'string' && isPathSegment(value, 512);\n}\n\n/**\n * Trailing slashes off a base URL, without a regular expression: `/\\/+$/`\n * backtracks over a long run of slashes and takes quadratic time on input the\n * page supplies (CodeQL js/polynomial-redos).\n */\nfunction withoutTrailingSlashes(value: string): string {\n let end = value.length;\n while (value.endsWith('/', end)) end -= 1;\n return value.slice(0, end);\n}\n\nexport class DataMerger {\n private readonly serverURL: string;\n private readonly apiRoute: string;\n private readonly depth: number;\n private readonly fetchFn: typeof fetch | undefined;\n private readonly log: (...args: unknown[]) => void;\n private inflight: AbortController | null = null;\n private attempt = 0;\n private destroyDepth = 0;\n\n constructor(options: DataMergerOptions) {\n this.serverURL = withoutTrailingSlashes(options.serverURL);\n const route = options.apiRoute ?? '/api';\n this.apiRoute = route.startsWith('/') ? route : `/${route}`;\n this.depth = options.depth ?? 1;\n this.fetchFn = options.fetchFn;\n this.log = isolateDiagnostic(options.log ?? noopDiagnostic);\n }\n\n /** A v2 schema plans local values and GETs; a v3 target needs its document identity. */\n canMerge(request: MergeRequest): boolean {\n try {\n const schema = request.schema;\n if (schema !== undefined) {\n planLegacyPopulation(\n request.data,\n schema,\n this.serverURL,\n this.apiRoute,\n this.depth,\n request.locale,\n );\n return true;\n }\n return this.endpointOf(request) !== null;\n } catch {\n return false;\n }\n }\n\n /**\n * The path and its response identity, or `null` when no safe one exists. A request\n * accessor that throws counts as none, and so does a lone surrogate, which\n * `encodeURIComponent` refuses with a `URIError`.\n */\n private endpointOf(request: MergeRequest): MergeTarget | null {\n try {\n // An empty global slug means \"collection document\" on the wire.\n const globalSlug = request.globalSlug;\n if (globalSlug) {\n return isSafeSlug(globalSlug)\n ? {\n path: `globals/${encodeURIComponent(globalSlug)}`,\n field: 'globalType',\n value: globalSlug,\n }\n : null;\n }\n const collectionSlug = request.collectionSlug ?? '';\n const id: unknown = request.data['id'];\n if (!isSafeSlug(collectionSlug) || !isSafeId(id)) return null;\n return {\n path: `${encodeURIComponent(collectionSlug)}/${encodeURIComponent(String(id))}`,\n field: 'id',\n value: String(id),\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Fulfills merged, superseded or unavailable. Supported request, fetch and\n * response failures are outcomes; isolated diagnostics cannot reject the merge.\n */\n async merge(request: MergeRequest): Promise<MergeResult> {\n if (this.destroyDepth > 0) return { status: 'superseded' };\n // Claim the attempt before aborting: abort listeners and fetch shims are\n // reentrant, and a newer merge they start must win. Nothing but this class\n // aborts the signal, and only after the counter moved, so the counter\n // alone decides who was superseded.\n const attempt = (this.attempt += 1);\n const previous = this.inflight;\n this.inflight = null;\n let controller: AbortController | null = null;\n let legacy = false;\n const superseded = (): boolean => this.attempt !== attempt;\n try {\n previous?.abort();\n if (superseded()) return { status: 'superseded' };\n const schema = request.schema;\n legacy = schema !== undefined;\n if (schema !== undefined) {\n const plan = planLegacyPopulation(\n request.data,\n schema,\n this.serverURL,\n this.apiRoute,\n this.depth,\n request.locale,\n );\n if (superseded()) return { status: 'superseded' };\n if (plan.requests.length === 0) return { status: 'merged', doc: plan.doc };\n const fetchFn = this.fetchFn ?? (typeof fetch === 'function' ? fetch : undefined);\n if (superseded()) return { status: 'superseded' };\n if (fetchFn === undefined) return { status: 'unavailable' };\n controller = new AbortController();\n this.inflight = controller;\n for (const population of plan.requests) {\n const response = await fetchFn(population.url, {\n method: 'GET',\n credentials: 'include',\n redirect: 'error',\n signal: controller.signal,\n });\n if (superseded()) return { status: 'superseded' };\n const ok = response.ok;\n if (superseded()) return { status: 'superseded' };\n if (!ok) {\n const status = response.status;\n if (superseded()) return { status: 'superseded' };\n controller.abort();\n if (superseded()) return { status: 'superseded' };\n this.log('merge HTTP', status);\n return superseded() ? { status: 'superseded' } : { status: 'unavailable' };\n }\n const body = await populationBody(response, controller.signal, () => !superseded());\n if (superseded()) return { status: 'superseded' };\n fillLegacyPopulation(population, body);\n if (superseded()) return { status: 'superseded' };\n }\n return { status: 'merged', doc: plan.doc };\n }\n // The endpoint reads the request's own values, which may be consumer\n // getters that start a newer merge before throwing.\n const endpoint = this.endpointOf(request);\n if (superseded()) return { status: 'superseded' };\n if (endpoint === null) return { status: 'unavailable' };\n const fetchFn = this.fetchFn ?? (typeof fetch === 'function' ? fetch : undefined);\n if (superseded()) return { status: 'superseded' };\n if (fetchFn === undefined) return { status: 'unavailable' };\n // Serialize before publishing the controller: accessors may accept newer work.\n const body = JSON.stringify({\n data: request.data,\n depth: this.depth,\n flattenLocales: false,\n locale: request.locale,\n });\n if (superseded()) return { status: 'superseded' };\n controller = new AbortController();\n this.inflight = controller;\n const url = `${this.serverURL}${this.apiRoute}/${endpoint.path}`;\n const response = await fetchFn(url, {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Payload-HTTP-Method-Override': 'GET',\n },\n // The admin already flattens locales before posting; an absent locale\n // is left out of the JSON.\n body,\n signal: controller.signal,\n });\n // A fetch shim may ignore the signal; the attempt is authoritative.\n if (superseded()) return { status: 'superseded' };\n const ok = response.ok;\n if (superseded()) return { status: 'superseded' };\n if (!ok) {\n const status = response.status;\n if (superseded()) return { status: 'superseded' };\n this.log('merge HTTP', status, url);\n return superseded() ? { status: 'superseded' } : { status: 'unavailable' };\n }\n const json: () => Promise<unknown> = response.json.bind(response);\n if (superseded()) return { status: 'superseded' };\n const merged: unknown = await json();\n if (superseded()) return { status: 'superseded' };\n if (merged === null || typeof merged !== 'object' || Array.isArray(merged)) {\n this.log('merge invalid', url);\n return superseded() ? { status: 'superseded' } : { status: 'unavailable' };\n }\n const doc = merged as Record<string, unknown>;\n // Missing IDs remain compatible with projected responses. An explicit\n // identity must match the dispatched target, never mutable request data.\n const identity = doc[endpoint.field];\n const wrongIdentity =\n Object.hasOwn(doc, endpoint.field) &&\n (endpoint.field === 'id'\n ? !isSafeId(identity) || String(identity) !== endpoint.value\n : identity !== endpoint.value);\n if (superseded()) return { status: 'superseded' };\n if (wrongIdentity) {\n this.log('merge invalid', url);\n return superseded() ? { status: 'superseded' } : { status: 'unavailable' };\n }\n return { status: 'merged', doc };\n } catch (error) {\n if (superseded()) return { status: 'superseded' };\n if (legacy) {\n controller?.abort();\n if (superseded()) return { status: 'superseded' };\n }\n this.log(\n 'merge exception',\n legacy ? new Error('legacy population could not be resolved') : error,\n );\n if (superseded()) return { status: 'superseded' };\n return { status: 'unavailable' };\n } finally {\n // Only the newest attempt's controller is ever in flight: a superseded\n // attempt's is gone already, and its successor's is left alone.\n if (this.inflight === controller) this.inflight = null;\n }\n }\n\n /** Abort any in-flight merge. The merger stays usable across a stop/start cycle. */\n destroy(): void {\n this.attempt += 1;\n const inflight = this.inflight;\n this.inflight = null;\n this.destroyDepth += 1;\n try {\n inflight?.abort();\n } finally {\n this.destroyDepth -= 1;\n }\n }\n}\n","/** The package version, read from package.json so the entries and the inline runtime cannot drift. */\n\nimport pkg from '../package.json' with { type: 'json' };\n\n/** @internal */\nexport const VERSION: string = pkg.version;\n","{\n \"name\": \"payload-live-preview\",\n \"version\": \"2.2.2\",\n \"description\": \"Live preview for Payload CMS on server-rendered and static frontends (Astro, Next.js, SvelteKit, Nuxt, plain HTML), with React and Vue hooks for client-rendered apps.\",\n \"author\": \"relative23\",\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"packageManager\": \"npm@12.0.2\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n },\n \"./core\": {\n \"import\": {\n \"types\": \"./dist/core.d.ts\",\n \"default\": \"./dist/core.js\"\n },\n \"require\": {\n \"types\": \"./dist/core.d.cts\",\n \"default\": \"./dist/core.cjs\"\n }\n },\n \"./astro\": {\n \"import\": {\n \"types\": \"./dist/adapters/astro/index.d.ts\",\n \"default\": \"./dist/adapters/astro/index.js\"\n }\n },\n \"./nextjs\": {\n \"import\": {\n \"types\": \"./dist/adapters/nextjs/index.d.ts\",\n \"default\": \"./dist/adapters/nextjs/index.js\"\n },\n \"default\": {\n \"types\": \"./dist/adapters/nextjs/index.d.ts\",\n \"default\": \"./dist/adapters/nextjs/index.js\"\n }\n },\n \"./sveltekit\": {\n \"import\": {\n \"types\": \"./dist/adapters/sveltekit/index.d.ts\",\n \"default\": \"./dist/adapters/sveltekit/index.js\"\n }\n },\n \"./nuxt\": {\n \"import\": {\n \"types\": \"./dist/adapters/nuxt/index.d.ts\",\n \"default\": \"./dist/adapters/nuxt/index.js\"\n }\n },\n \"./nuxt-module\": {\n \"import\": {\n \"types\": \"./dist/adapters/nuxt/module.d.ts\",\n \"default\": \"./dist/adapters/nuxt/module.js\"\n }\n },\n \"./react\": {\n \"import\": {\n \"types\": \"./dist/adapters/react/index.d.ts\",\n \"default\": \"./dist/adapters/react/index.js\"\n }\n },\n \"./vue\": {\n \"import\": {\n \"types\": \"./dist/adapters/vue/index.d.ts\",\n \"default\": \"./dist/adapters/vue/index.js\"\n }\n },\n \"./codegen\": {\n \"import\": {\n \"types\": \"./dist/codegen.d.ts\",\n \"default\": \"./dist/codegen.js\"\n },\n \"require\": {\n \"types\": \"./dist/codegen.d.cts\",\n \"default\": \"./dist/codegen.cjs\"\n }\n },\n \"./codegen/astro\": {\n \"import\": {\n \"types\": \"./dist/codegen-astro.d.ts\",\n \"default\": \"./dist/codegen-astro.js\"\n }\n },\n \"./annotate\": {\n \"import\": {\n \"types\": \"./dist/annotate.d.ts\",\n \"default\": \"./dist/annotate.js\"\n }\n },\n \"./doctor\": {\n \"import\": {\n \"types\": \"./dist/doctor.d.ts\",\n \"default\": \"./dist/doctor.js\"\n }\n },\n \"./migrate\": {\n \"import\": {\n \"types\": \"./dist/migrate.d.ts\",\n \"default\": \"./dist/migrate.js\"\n }\n },\n \"./payload\": {\n \"import\": {\n \"types\": \"./dist/payload.d.ts\",\n \"default\": \"./dist/payload.js\"\n },\n \"require\": {\n \"types\": \"./dist/payload.d.cts\",\n \"default\": \"./dist/payload.cjs\"\n }\n },\n \"./plugin\": {\n \"import\": {\n \"types\": \"./dist/plugin.d.ts\",\n \"default\": \"./dist/plugin.js\"\n },\n \"require\": {\n \"types\": \"./dist/plugin.d.cts\",\n \"default\": \"./dist/plugin.cjs\"\n }\n },\n \"./server\": {\n \"import\": {\n \"types\": \"./dist/server.d.ts\",\n \"default\": \"./dist/server.js\"\n },\n \"require\": {\n \"types\": \"./dist/server.d.cts\",\n \"default\": \"./dist/server.cjs\"\n }\n },\n \"./client\": {\n \"import\": {\n \"types\": \"./dist/client.d.ts\",\n \"default\": \"./dist/client.js\"\n },\n \"require\": {\n \"types\": \"./dist/client.d.cts\",\n \"default\": \"./dist/client.cjs\"\n }\n },\n \"./structural\": {\n \"import\": {\n \"types\": \"./dist/structural.d.ts\",\n \"default\": \"./dist/structural.js\"\n },\n \"require\": {\n \"types\": \"./dist/structural.d.cts\",\n \"default\": \"./dist/structural.cjs\"\n }\n },\n \"./lexical\": {\n \"import\": {\n \"types\": \"./dist/lexical.d.ts\",\n \"default\": \"./dist/lexical.js\"\n },\n \"require\": {\n \"types\": \"./dist/lexical.d.cts\",\n \"default\": \"./dist/lexical.cjs\"\n }\n },\n \"./plugins\": {\n \"import\": {\n \"types\": \"./dist/plugins.d.ts\",\n \"default\": \"./dist/plugins.js\"\n },\n \"require\": {\n \"types\": \"./dist/plugins.d.cts\",\n \"default\": \"./dist/plugins.cjs\"\n }\n },\n \"./lean\": {\n \"import\": {\n \"types\": \"./dist/lean.d.ts\",\n \"default\": \"./dist/lean.js\"\n },\n \"require\": {\n \"types\": \"./dist/lean.d.cts\",\n \"default\": \"./dist/lean.cjs\"\n }\n },\n \"./fragment\": {\n \"import\": {\n \"types\": \"./dist/fragment.d.ts\",\n \"default\": \"./dist/fragment.js\"\n },\n \"require\": {\n \"types\": \"./dist/fragment.d.cts\",\n \"default\": \"./dist/fragment.cjs\"\n }\n },\n \"./astro/RichText.astro\": \"./dist/adapters/astro/RichText.astro\",\n \"./astro/PreviewBoundary.astro\": \"./dist/adapters/astro/PreviewBoundary.astro\",\n \"./astro/middleware-entry\": {\n \"import\": {\n \"types\": \"./dist/adapters/astro/middleware-entry.d.ts\",\n \"default\": \"./dist/adapters/astro/middleware-entry.js\"\n }\n },\n \"./package.json\": \"./package.json\"\n },\n \"bin\": {\n \"pll-codegen\": \"./dist/codegen-cli.js\",\n \"pll\": \"./dist/doctor-cli.js\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"sideEffects\": false,\n \"scripts\": {\n \"build:runtime\": \"node -e \\\"const c=require('node:child_process'),e={...process.env};if(!e.SOURCE_DATE_EPOCH){const g=c.spawnSync('git',['show','-s','--format=%ct','HEAD'],{encoding:'utf8'});if(g.status===0)e.SOURCE_DATE_EPOCH=g.stdout.trim()}process.exit(c.spawnSync(process.execPath,['--import','tsx',process.argv[1]],{stdio:'inherit',env:e}).status??1)\\\" scripts/build-runtime.ts\",\n \"build\": \"npm run build:runtime && tsx scripts/build-dist.ts && npm run build:assets && npm run test:bundle && npm run test:treeshake && npm run test:edge && npm run test:interaction && npm run test:protocol-semantics\",\n \"build:assets\": \"node -e \\\"const fs=require('node:fs');for(const f of ['RichText','PreviewBoundary','FragmentBridge'])fs.copyFileSync('src/adapters/astro/'+f+'.astro','dist/adapters/astro/'+f+'.astro')\\\"\",\n \"dev\": \"tsup --watch\",\n \"pretest\": \"npm run build:runtime\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:security-corpus\": \"vitest run tests/unit/security/sanitizer-corpus.test.ts tests/unit/property/sanitizer-fuzz.property.test.ts\",\n \"test:unit\": \"vitest run tests/unit\",\n \"test:integration\": \"vitest run tests/integration\",\n \"test:e2e\": \"playwright test\",\n \"test:e2e:next-base-path\": \"playwright test --config playwright.next-base-path.config.ts\",\n \"test:e2e:next-production\": \"playwright test --config playwright.next-production.config.ts\",\n \"test:e2e:next-webpack-production\": \"playwright test --config playwright.next-webpack-production.config.ts\",\n \"test:e2e:next-continuation\": \"playwright test --config playwright.next-continuation.config.ts\",\n \"test:e2e:sveltekit-continuation\": \"playwright test --config playwright.sveltekit-continuation.config.ts\",\n \"test:e2e:nuxt-continuation\": \"playwright test --config playwright.nuxt-continuation.config.ts\",\n \"test:e2e:astro-continuation\": \"playwright test --config playwright.astro-continuation.config.ts\",\n \"test:e2e:astro-resources\": \"playwright test --config playwright.astro-resources.config.ts\",\n \"test:e2e:html-continuation\": \"playwright test --config playwright.html-continuation.config.ts\",\n \"test:e2e:vue-continuation\": \"playwright test --config playwright.vue-continuation.config.ts\",\n \"test:e2e:react-continuation\": \"playwright test --config playwright.react-continuation.config.ts\",\n \"test:e2e:nuxt-production\": \"playwright test --config playwright.nuxt-production.config.ts\",\n \"test:e2e:sveltekit-production\": \"playwright test --config playwright.sveltekit-production.config.ts\",\n \"check:fixtures\": \"tsx scripts/check-fixture-freshness.ts\",\n \"check:generated\": \"tsx scripts/check-generated-runtime.ts\",\n \"test:e2e:real-payload\": \"playwright test --config playwright.real-payload.config.ts\",\n \"test:acl:real-payload\": \"tsx scripts/check-payload-acl.ts\",\n \"test:a11y\": \"playwright test tests/e2e/specs/accessibility.spec.ts\",\n \"test:soak\": \"playwright test --config playwright.soak.config.ts\",\n \"test:browser-bench\": \"playwright test --config playwright.bench.config.ts\",\n \"test:bench\": \"vitest bench tests/benchmarks\",\n \"test:bench:codspeed\": \"vitest bench --run --config vitest.bench.config.ts\",\n \"test:bundle\": \"tsx scripts/check-bundle-size.ts\",\n \"test:interaction\": \"tsx scripts/check-interaction-budgets.ts\",\n \"test:protocol-semantics\": \"tsx scripts/check-protocol-semantics.ts\",\n \"test:upstream-findings\": \"tsx scripts/check-upstream-findings.ts\",\n \"test:treeshake\": \"tsx scripts/check-tree-shaking.ts\",\n \"test:edge\": \"NODE_OPTIONS='--experimental-vm-modules --no-warnings' tsx scripts/check-edge-runtime.ts\",\n \"compat:check\": \"tsx scripts/compat-table.ts --check\",\n \"compat:write\": \"tsx scripts/compat-table.ts --write\",\n \"compat:refresh\": \"tsx scripts/compat-table.ts --refresh\",\n \"compat:record\": \"tsx scripts/record-compat-results.ts && prettier --write quality/compat-matrix.json && tsx scripts/compat-table.ts --write && prettier --write README.md\",\n \"diagnostics:check\": \"tsx scripts/diagnostic-table.ts --check\",\n \"test:package\": \"tsx scripts/check-package.ts\",\n \"audit:gate\": \"tsx scripts/audit-gate.ts\",\n \"test:smoke\": \"tsx scripts/post-publish-smoke.ts\",\n \"test:coverage\": \"vitest run --coverage\",\n \"test:coverage:diff\": \"tsx scripts/coverage-policy.ts\",\n \"test:policy\": \"tsx scripts/test-policy.ts\",\n \"test:architecture\": \"tsx scripts/architecture-policy.ts && tsx scripts/check-complexity.ts && tsx scripts/check-trusted-core.ts && tsx scripts/compare-scope.ts --check && tsx scripts/workflow-contracts.ts && tsx scripts/docs-contracts.ts && tsx scripts/check-resource-inventory.ts && knip --no-progress --treat-config-hints-as-errors\",\n \"test:property\": \"vitest run tests/unit/property\",\n \"test:mutation\": \"stryker run stryker.config.js\",\n \"test:mutation:policy:pr\": \"tsx scripts/mutation-policy.ts --policy quality/mutation-policy-pr.json --report test-results/stryker-pr.json\",\n \"test:mutation:policy:core\": \"tsx scripts/mutation-policy.ts --policy quality/mutation-policy-core.json --report test-results/stryker-core.json\",\n \"test:mutation:policy\": \"tsx scripts/mutation-policy.ts\",\n \"test:leak\": \"node --expose-gc --import tsx scripts/leak-soak.ts\",\n \"test:leak:quick\": \"node --expose-gc --import tsx scripts/leak-soak.ts --quick\",\n \"api:update\": \"npm run build && tsx scripts/check-package.ts --update-api-reports\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"eslint .\",\n \"lint:fix\": \"eslint . --fix\",\n \"format\": \"prettier --write \\\"src/**/*.ts\\\" \\\"tests/**/*.ts\\\" \\\"scripts/**/*.ts\\\" \\\"*.{js,cjs,mjs,ts,json,jsonc,yml,yaml,md}\\\" \\\"quality/**/*.json\\\" \\\"docs/**/*.md\\\" \\\"type-tests/**/*.md\\\" \\\".prettierrc.json\\\" \\\".changeset/*.{json,md}\\\" \\\".github/**/*.{yml,yaml,json}\\\" \\\"examples/**/*.{ts,tsx,js,cjs,mjs,json}\\\" && prettier --write \\\"type-tests/packed/*.fixture\\\" --parser typescript\",\n \"format:check\": \"prettier --check \\\"src/**/*.ts\\\" \\\"tests/**/*.ts\\\" \\\"scripts/**/*.ts\\\" \\\"*.{js,cjs,mjs,ts,json,jsonc,yml,yaml,md}\\\" \\\"quality/**/*.json\\\" \\\"docs/**/*.md\\\" \\\"type-tests/**/*.md\\\" \\\".prettierrc.json\\\" \\\".changeset/*.{json,md}\\\" \\\".github/**/*.{yml,yaml,json}\\\" \\\"examples/**/*.{ts,tsx,js,cjs,mjs,json}\\\" && prettier --check \\\"type-tests/packed/*.fixture\\\" --parser typescript\",\n \"check\": \"npm run typecheck && npm run lint && npm run format:check && npm run test:policy && npm run test:architecture && npm run compat:check && npm run diagnostics:check && npm run test\",\n \"prepublishOnly\": \"npm run build && npm run check && npm run format:check && npm run test:package\",\n \"changeset\": \"changeset\",\n \"version\": \"changeset version && tsx scripts/sync-lockfile-metadata.ts && npm run build:runtime\",\n \"release\": \"tsx scripts/publish-artifact.ts\",\n \"test:docs\": \"tsx scripts/docs-contracts.ts\"\n },\n \"devDependencies\": {\n \"@arethetypeswrong/cli\": \"^0.18.5\",\n \"@axe-core/playwright\": \"^4.13.0\",\n \"@changesets/cli\": \"^2.31.1\",\n \"@codspeed/vitest-plugin\": \"^5.7.1\",\n \"@eslint/js\": \"^10.0.1\",\n \"@fast-check/vitest\": \"^0.4.1\",\n \"@microsoft/api-extractor\": \"^7.58.12\",\n \"@payloadcms/live-preview\": \"^3.88.0\",\n \"@playwright/test\": \"^1.62.1\",\n \"@stryker-mutator/core\": \"^9.6.1\",\n \"@stryker-mutator/vitest-runner\": \"^9.6.1\",\n \"@testing-library/react\": \"^16.3.3\",\n \"@types/jsdom\": \"^30.0.0\",\n \"@types/node\": \"^22.20.1\",\n \"@types/react\": \"^19.2.18\",\n \"@types/react-dom\": \"^19.2.7\",\n \"@vitest/coverage-v8\": \"^4.1.12\",\n \"dompurify\": \"^3.4.15\",\n \"esbuild\": \"^0.28.2\",\n \"eslint\": \"^10.8.1\",\n \"fast-check\": \"^4.9.0\",\n \"globals\": \"^17.11.0\",\n \"jsdom\": \"^29.1.1\",\n \"knip\": \"^6.32.2\",\n \"linkedom\": \"^0.18.14\",\n \"prettier\": \"^3.9.6\",\n \"publint\": \"^0.3.23\",\n \"react\": \"^19.3.1\",\n \"react-dom\": \"^19.3.1\",\n \"svelte\": \"^5.57.3\",\n \"terser\": \"^5.46.1\",\n \"ts-morph\": \"^28.0.0\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.23.12\",\n \"typescript\": \"^5.9.3\",\n \"typescript-eslint\": \"^8.67.0\",\n \"vite\": \"^7.3.6\",\n \"vitest\": \"^4.1.12\",\n \"vue\": \"^3.5.44\",\n \"yaml\": \"^2.9.0\"\n },\n \"overrides\": {\n \"qs\": \"6.16.1\",\n \"tsup\": {\n \"esbuild\": \"0.28.2\"\n }\n },\n \"allowScripts\": {\n \"esbuild@0.28.2\": true,\n \"fsevents@2.3.2\": false,\n \"fsevents@2.3.3\": false\n },\n \"keywords\": [\n \"astro\",\n \"astro-payload\",\n \"astro-cms\",\n \"astro-integration\",\n \"astro-live-preview\",\n \"payload\",\n \"payload-cms\",\n \"payload-plugin\",\n \"payload-live-preview\",\n \"live-preview\",\n \"preview\",\n \"cms\",\n \"headless\",\n \"headless-cms\",\n \"lexical\",\n \"sveltekit\",\n \"nuxt\",\n \"nextjs\",\n \"react\",\n \"vue\",\n \"ssr\",\n \"framework-agnostic\"\n ],\n \"peerDependencies\": {\n \"astro\": \">=4.0.0 <8.0.0\",\n \"payload\": \"^2.0.0 || ^3.0.0 || ^4.0.0-0\",\n \"react\": \">=18\",\n \"react-dom\": \">=18\",\n \"svelte\": \">=5\",\n \"ts-morph\": \"^28.0.0\",\n \"vite\": \">=5.4.0 <9.0.0\",\n \"vue\": \">=3.3\"\n },\n \"peerDependenciesMeta\": {\n \"astro\": {\n \"optional\": true\n },\n \"payload\": {\n \"optional\": true\n },\n \"react\": {\n \"optional\": true\n },\n \"react-dom\": {\n \"optional\": true\n },\n \"svelte\": {\n \"optional\": true\n },\n \"ts-morph\": {\n \"optional\": true\n },\n \"vue\": {\n \"optional\": true\n },\n \"vite\": {\n \"optional\": true\n }\n },\n \"engines\": {\n \"node\": \">=20.19.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"provenance\": true\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/relative23/payload-live-preview.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/relative23/payload-live-preview/issues\"\n },\n \"homepage\": \"https://github.com/relative23/payload-live-preview#readme\"\n}\n","/**\n * What the peer does, derived from the capabilities its messages showed —\n * the runtime never asks which Payload version it is talking to. Unknown\n * until the admin reveals its shape. See ADR 0010.\n */\nimport type { ProtocolCapability } from './protocol-version';\n\nexport type ProtocolProfileName = 'unknown' | 'payload-2' | 'payload-3';\n\nexport interface ProtocolProfile {\n readonly name: ProtocolProfileName;\n /** Where field types come from. */\n readonly fieldTyping: 'schema' | 'heuristic';\n /**\n * Legacy transport label, retained for 2.x compatibility. `admin` identifies\n * Payload 2's schema-based path; observed messages can contain raw relation IDs,\n * which the shared merger populates with collection GETs. `server` identifies\n * the Payload 3 merge path. This label alone does not describe population state.\n */\n readonly populatesRelationships: 'admin' | 'server';\n /** Whether the peer reports document saves and relationship edits. */\n readonly documentEvents: boolean;\n}\n\nconst PAYLOAD_2: ProtocolProfile = {\n name: 'payload-2',\n fieldTyping: 'schema',\n populatesRelationships: 'admin',\n documentEvents: false,\n};\nconst PAYLOAD_3: ProtocolProfile = {\n name: 'payload-3',\n fieldTyping: 'heuristic',\n populatesRelationships: 'server',\n documentEvents: true,\n};\nconst UNKNOWN: ProtocolProfile = {\n name: 'unknown',\n fieldTyping: 'heuristic',\n populatesRelationships: 'server',\n documentEvents: false,\n};\n\n/**\n * `schema-json` on the wire is the Payload 2.x signature: 3.x removed\n * `fieldSchemaJSON`. Document or relationship events are 3.x-only. Until\n * either shows, the peer is unknown and treated like 3.x for merging — the\n * conservative choice, because a needless REST merge costs a request while\n * a missing one loses populated relationships.\n */\nexport function detectProtocolProfile(observed: ReadonlySet<ProtocolCapability>): ProtocolProfile {\n if (observed.has('schema-json')) return PAYLOAD_2;\n if (observed.has('document-events') || observed.has('relationship-events')) return PAYLOAD_3;\n return UNKNOWN;\n}\n","/**\n * Mutation and intersection observers: ask the host to rebuild the cache when\n * bindings appear, vanish or change metadata, and track which bound elements\n * are in the viewport so off-screen writes can wait. Kept apart from cache and\n * scheduler so tests can run without the browser observer APIs.\n */\n\nimport {\n BINDING_ATTRIBUTES,\n COVERS_ATTRIBUTE,\n DEPENDS_ATTRIBUTE,\n FIELD_ATTRIBUTE,\n NAVIGATION_REPLAY_SELECTOR,\n OWNER_ATTRIBUTE,\n} from './cache';\nimport { ISLAND_ATTRIBUTE, ISLAND_SELECTOR } from './islands';\n\nexport interface ObserverCallbacks {\n readonly onStructuralChange: () => void;\n readonly onIslandHydrated?: (island: Element) => void;\n readonly onVisibilityChange: (element: Element, isVisible: boolean) => void;\n}\n\nexport interface ObserverOptions {\n /** Debounce for mutation batches in ms. Default 100. */\n readonly mutationDebounceMs?: number;\n /** `rootMargin` for the IntersectionObserver. Default `200px`. */\n readonly intersectionRootMargin?: string;\n}\n\nconst DEFAULT_DEBOUNCE_MS = 100;\nconst DEFAULT_ROOT_MARGIN = '200px';\nconst ASTRO_SSR_ATTRIBUTE = 'ssr';\n/** `nodeType` is stable across realms; the global `Node` constructor is not. */\nconst ELEMENT_NODE = 1;\n/**\n * Read from elements that need not be bindings: the field, the owner a binding\n * inherits, and what a page declares it accounts for — `data-payload-covers`\n * anywhere, `data-payload-depends` on a boundary or route marker (ADR 0022).\n */\nconst WATCHED_ANYWHERE: readonly string[] = [\n FIELD_ATTRIBUTE,\n OWNER_ATTRIBUTE,\n COVERS_ATTRIBUTE,\n DEPENDS_ATTRIBUTE,\n];\nconst TRACKED_SELECTOR = `[${FIELD_ATTRIBUTE}], [${COVERS_ATTRIBUTE}], ${ISLAND_SELECTOR}, ${NAVIGATION_REPLAY_SELECTOR}`;\n\nexport class ObserverManager {\n private readonly callbacks: ObserverCallbacks;\n private readonly debounceMs: number;\n private readonly rootMargin: string;\n private readonly visible = new Set<Element>();\n private mutation: MutationObserver | null = null;\n private intersection: IntersectionObserver | null = null;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n /** Bumped by every start/stop so deliveries from an older lifetime are inert. */\n private generation = 0;\n\n constructor(callbacks: ObserverCallbacks, options: ObserverOptions = {}) {\n this.callbacks = callbacks;\n this.debounceMs = options.mutationDebounceMs ?? DEFAULT_DEBOUNCE_MS;\n this.rootMargin = options.intersectionRootMargin ?? DEFAULT_ROOT_MARGIN;\n }\n\n /** Observe `root`; a repeated start hands over cleanly. */\n start(root: Node): void {\n const previousGeneration = this.generation;\n this.stop();\n const generation = previousGeneration + 1;\n // A disconnect hook may have started a newer generation; it owns the lifecycle.\n if (this.generation !== generation) return;\n let mutation: MutationObserver | null = null;\n let intersection: IntersectionObserver | null = null;\n try {\n mutation = new MutationObserver((mutations) => {\n this.handleMutations(mutations, generation);\n });\n // Both resources exist before either is live, so a missing IntersectionObserver leaves nothing behind.\n intersection = new IntersectionObserver(\n (entries) => {\n this.handleIntersection(entries, generation);\n },\n { rootMargin: this.rootMargin, threshold: 0 },\n );\n mutation.observe(root, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\n ...BINDING_ATTRIBUTES,\n COVERS_ATTRIBUTE,\n ISLAND_ATTRIBUTE,\n ASTRO_SSR_ATTRIBUTE,\n ],\n });\n } catch (error) {\n mutation?.disconnect();\n intersection?.disconnect();\n throw error;\n }\n if (this.generation !== generation) {\n mutation.disconnect();\n intersection.disconnect();\n return;\n }\n this.mutation = mutation;\n this.intersection = intersection;\n }\n\n observeElement(element: Element): void {\n this.intersection?.observe(element);\n }\n\n unobserveElement(element: Element): void {\n this.intersection?.unobserve(element);\n this.visible.delete(element);\n }\n\n /** Seed visibility (tests). */\n markVisible(element: Element, visible: boolean): void {\n if (visible) this.visible.add(element);\n else this.visible.delete(element);\n }\n\n isVisible(element: Element): boolean {\n return this.visible.has(element);\n }\n\n /** Disconnect everything; safe to repeat. */\n stop(): void {\n // Invalidate first so queued deliveries and the timer are inert before disconnecting.\n this.generation += 1;\n const timer = this.debounceTimer;\n const mutation = this.mutation;\n const intersection = this.intersection;\n this.debounceTimer = null;\n this.mutation = null;\n this.intersection = null;\n this.visible.clear();\n if (timer !== null) clearTimeout(timer);\n try {\n mutation?.disconnect();\n } finally {\n intersection?.disconnect();\n }\n }\n\n private handleMutations(mutations: readonly MutationRecord[], generation: number): void {\n if (!this.isCurrentGeneration(generation)) return;\n for (const mutation of mutations) {\n const island = hydratedAstroIsland(mutation);\n if (island === null) continue;\n this.callbacks.onIslandHydrated?.(island);\n if (!this.isCurrentGeneration(generation)) return;\n }\n if (!hasStructuralImpact(mutations)) return;\n if (this.debounceTimer !== null) clearTimeout(this.debounceTimer);\n const timer = setTimeout(() => {\n if (!this.isCurrentGeneration(generation) || this.debounceTimer !== timer) return;\n this.debounceTimer = null;\n this.callbacks.onStructuralChange();\n }, this.debounceMs);\n this.debounceTimer = timer;\n }\n\n private handleIntersection(\n entries: readonly IntersectionObserverEntry[],\n generation: number,\n ): void {\n for (const entry of entries) {\n if (!this.isCurrentGeneration(generation)) return;\n const { target } = entry;\n if (entry.isIntersecting) {\n if (this.visible.has(target)) continue;\n this.visible.add(target);\n this.callbacks.onVisibilityChange(target, true);\n } else if (this.visible.has(target)) {\n this.visible.delete(target);\n this.callbacks.onVisibilityChange(target, false);\n }\n }\n }\n\n private isCurrentGeneration(generation: number): boolean {\n return this.generation === generation && this.intersection !== null;\n }\n}\n\nfunction hydratedAstroIsland(mutation: MutationRecord): Element | null {\n if (\n mutation.type !== 'attributes' ||\n mutation.attributeName !== ASTRO_SSR_ATTRIBUTE ||\n mutation.target.nodeType !== ELEMENT_NODE\n ) {\n return null;\n }\n const target = mutation.target as Element;\n return target.tagName.toLowerCase() === 'astro-island' &&\n !target.hasAttribute(ASTRO_SSR_ATTRIBUTE)\n ? target\n : null;\n}\n\n/** Whether a mutation batch can change what is bound; unrelated DOM activity never rebuilds. */\nfunction hasStructuralImpact(mutations: readonly MutationRecord[]): boolean {\n for (const m of mutations) {\n if (m.type === 'attributes' && m.attributeName === ISLAND_ATTRIBUTE) return true;\n if (m.type === 'attributes' && m.attributeName !== null) {\n if (WATCHED_ANYWHERE.includes(m.attributeName)) return true;\n // Other metadata (notably the native `type`) matters only on an element\n // that is a binding.\n if (\n BINDING_ATTRIBUTES.includes(m.attributeName) &&\n m.target.nodeType === ELEMENT_NODE &&\n (m.target as Element).hasAttribute(FIELD_ATTRIBUTE)\n ) {\n return true;\n }\n }\n for (const node of m.addedNodes) if (containsTrackedElement(node)) return true;\n for (const node of m.removedNodes) if (containsTrackedElement(node)) return true;\n }\n return false;\n}\n\nfunction containsTrackedElement(node: Node): boolean {\n if (node.nodeType !== ELEMENT_NODE) return false;\n const element = node as Element;\n return element.matches(TRACKED_SELECTOR) || element.querySelector(TRACKED_SELECTOR) !== null;\n}\n","/**\n * A lifetime scope: what is owned inside it is released together, in reverse\n * order, when it closes, each release guarded so one that throws does not\n * stop the rest. The runtime opens one per session (`start()`) and closes it\n * on `destroy()`, `suspend()` and a failed start alike (ADR 0005, 2.1 note).\n * The plugin manager's `ResourceScope` is the same idea with staging, commit\n * and per-kind counts on top; this is the form the inline runtime carries.\n */\n\nexport type Release = () => void;\n\nexport class LifetimeScope {\n readonly #owned: Release[] = [];\n readonly #log: (...args: unknown[]) => void;\n #closed = false;\n\n constructor(log: (...args: unknown[]) => void) {\n this.#log = log;\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n\n /** Own a release; a closed scope runs it at once. */\n own(release: Release): void {\n if (this.#closed) {\n this.#run(release);\n return;\n }\n this.#owned.push(release);\n }\n\n /** Release everything owned, the last first; idempotent. */\n close(): void {\n if (this.#closed) return;\n this.#closed = true;\n const owned = this.#owned.splice(0).reverse();\n for (const release of owned) this.#run(release);\n }\n\n #run(release: Release): void {\n try {\n release();\n } catch (error) {\n this.#log('runtime cleanup failed:', error);\n }\n }\n}\n","/**\n * Waiting for React before the first write (ADR 0015).\n *\n * A page a framework hydrates is not final when it is parsed: the client\n * bundle arrives later, walks the server markup and compares it with what it\n * would have rendered. A value the runtime wrote in between is a mismatch —\n * React 19 throws, discards the tree under the nearest Suspense boundary,\n * renders it again on the client, and the write is gone with it. Measured on\n * the Next fixture on 2026-09-11: the write at 93 ms, React's fiber on the\n * bound element at 174 ms, `Hydration failed` at 180 ms.\n *\n * Neither Next nor React says when hydration is done. What React does expose,\n * since 16 and for its own DevTools, is its instrumentation protocol: when\n * `react-dom` evaluates it looks for `window.__REACT_DEVTOOLS_GLOBAL_HOOK__`,\n * calls `inject()` if the hook says `supportsFiber`, and from then on\n * `onCommitFiberRoot(rendererId, root)` after every commit — each call guarded\n * by `typeof … === 'function'` and a `try`. The first commit of a root that\n * holds a binding and no longer has dehydrated server boundaries is the moment\n * React has taken the markup over; everything before it is too early, and a\n * commit into a root without a binding (Next's dev overlay commits three times\n * before the app does) is not ours to wait for.\n *\n * Two bundles read this: the runtime, which arms the hook when it starts, and\n * the bootstrap for asset delivery (`./loader`, built armed), where the runtime\n * itself is fetched and may evaluate after `react-dom`. They share one window\n * slot, read late, the way the route-refresh seam does.\n */\n\n/** The framework whose first commit the start waits for; `./hydration-vue` and `./hydration-sveltekit` read the others. */\nexport type HydrationMode = 'react' | 'vue' | 'sveltekit';\nexport type HydrationOutcome = 'committed' | 'timed-out';\nexport type HydrationState = 'idle' | 'waiting' | HydrationOutcome;\n\n/**\n * How long the runtime waits for the commit before it starts anyway and says\n * so (LP0607). A page whose React never commits is broken; a preview that never\n * connects would hide that, one that connects five seconds late and says why\n * does not. A hydration slower than this regenerates the tree once, as before.\n */\nexport const HYDRATION_WAIT_CAP_MS = 5000;\n\n/** Where the prelude and the runtime meet. */\nexport const HYDRATION_SLOT = '__livePreviewHydration';\n\n/**\n * `[data-payload-field]`, spelled out rather than imported from `./cache`: the\n * armed bootstrap bundles this module beside the loader, and the import dragged\n * the cache's other selectors into a script that is measured to the byte. A\n * test holds it equal to `FIELD_ATTRIBUTE`.\n */\nexport const BINDING_SELECTOR = '[data-payload-field]';\n\n/**\n * What the two bundles share. The bootstrap only records: every root React\n * committed goes to `commits` until the runtime, which alone knows what a\n * binding is, sets `onCommit` and judges the backlog and everything after.\n * Recording rather than judging keeps the armed bootstrap to the bytes the\n * delivery budgets hold a bootstrap to.\n */\ninterface HydrationSignal extends HydrationWait {\n armed: boolean;\n commits: unknown[];\n onCommit: ((container: unknown) => void) | undefined;\n}\n\n/**\n * What a wait shares whichever framework it is for: whether the framework has\n * taken the tree over, and who is waiting to hear it. The Vue observer keeps\n * one of its own (`./hydration-vue`); the cap and the cancel are the same.\n */\nexport interface HydrationWait {\n committed: boolean;\n waiters: (() => void)[];\n}\n\n/** The root React hands the hook after a commit; `containerInfo` is the DOM node it rendered into. */\ninterface FiberLike {\n readonly tag?: number;\n readonly child?: FiberLike | null;\n readonly sibling?: FiberLike | null;\n readonly memoizedState?: unknown;\n}\n\ninterface FiberRootLike {\n readonly containerInfo?: unknown;\n readonly current?: FiberLike | null;\n}\n\n/**\n * The part of React's hook this module touches; the rest belongs to React and\n * its DevTools. React itself guards every other call it makes on the hook with\n * `typeof … === 'function'`; Fast Refresh (`react-refresh`, which every\n * development server runs) additionally walks `renderers` when it attaches,\n * and throws on a hook without the map — measured on the Next fixture, where\n * a hook without it stopped the page from hydrating at all.\n */\ninterface DevToolsHook {\n supportsFiber?: boolean;\n renderers?: Map<number, unknown>;\n inject?: (internals: unknown) => number;\n onCommitFiberRoot?: (\n this: unknown,\n rendererId: number,\n root?: FiberRootLike,\n ...rest: unknown[]\n ) => void;\n}\n\ntype HookWindow = Window & {\n __REACT_DEVTOOLS_GLOBAL_HOOK__?: DevToolsHook;\n [HYDRATION_SLOT]?: HydrationSignal;\n};\n\nfunction signalSlot(): HydrationSignal | undefined {\n if (typeof window === 'undefined') return undefined;\n const w = window as HookWindow;\n return (w[HYDRATION_SLOT] ??= {\n armed: false,\n committed: false,\n commits: [],\n onCommit: undefined,\n waiters: [],\n });\n}\n\n/**\n * Arm before React evaluates: install the hook React injects into when the\n * page has none, or wrap `onCommitFiberRoot` on the one that is there — the\n * React DevTools extension injects its own at `document_start`, and it keeps\n * working because the previous function runs first. Idempotent.\n */\nexport function armReactCommitSignal(): void {\n const signal = signalSlot();\n if (signal === undefined || signal.armed) return;\n signal.armed = true;\n const w = window as HookWindow;\n const hook = (w.__REACT_DEVTOOLS_GLOBAL_HOOK__ ??= installedHook());\n const previous = hook.onCommitFiberRoot;\n hook.onCommitFiberRoot = function (this: unknown, rendererId, root, ...rest) {\n try {\n previous?.call(this, rendererId, root, ...rest);\n } catch {\n // The DevTools backend's failure is not ours to propagate; React would\n // swallow it too.\n }\n if (signal.onCommit === undefined) signal.commits.push(root);\n else signal.onCommit(root);\n };\n}\n\n/**\n * The hook React finds when the page has none: what `injectInternals` reads\n * (`supportsFiber`, `inject`) and what Fast Refresh reads (`renderers`, kept\n * the way DevTools keeps it — one id per renderer, so the two React copies a\n * development server runs are not one to it).\n */\nfunction installedHook(): DevToolsHook {\n const renderers = new Map<number, unknown>();\n return {\n supportsFiber: true,\n renderers,\n inject: (internals) => {\n const id = renderers.size + 1;\n renderers.set(id, internals);\n return id;\n },\n };\n}\n\n/** A Document, or a container with a binding inside — the tree the runtime writes into. */\nfunction ownsBindings(container: unknown): boolean {\n const node = container as Partial<Pick<Element, 'nodeType' | 'querySelector'>> | null | undefined;\n return node?.nodeType === 9 || node?.querySelector?.(BINDING_SELECTOR) != null;\n}\n\n/**\n * A streamed React root may commit before every server boundary has been\n * claimed. React 18/19's Suspense fiber (tag 13), and React 19's Activity fiber\n * (tag 31), keep the server Comment in `memoizedState.dehydrated` until a later\n * root commit claims it. Starting between those commits lets that later\n * hydration regenerate markup the runtime has already edited.\n */\nfunction hasDehydratedBoundary(root: FiberRootLike): boolean {\n const pending: FiberLike[] = [];\n if (root.current !== null && root.current !== undefined) pending.push(root.current);\n while (pending.length > 0) {\n const fiber = pending.pop();\n if (fiber === undefined) continue;\n const state = fiber.memoizedState;\n if (\n (fiber.tag === 13 || fiber.tag === 31) &&\n typeof state === 'object' &&\n state !== null &&\n 'dehydrated' in state &&\n typeof state.dehydrated === 'object' &&\n state.dehydrated !== null &&\n 'nodeType' in state.dehydrated &&\n state.dehydrated.nodeType === 8\n ) {\n return true;\n }\n if (fiber.sibling !== null && fiber.sibling !== undefined) pending.push(fiber.sibling);\n if (fiber.child !== null && fiber.child !== undefined) pending.push(fiber.child);\n }\n return false;\n}\n\n/** A binding-owning root after its streamed server boundaries are all claimed. */\nfunction ownsHydratedBindings(value: unknown): boolean {\n const root = value as FiberRootLike | null | undefined;\n return root != null && ownsBindings(root.containerInfo) && !hasDehydratedBoundary(root);\n}\n\n/** The framework has taken the tree over: every waiter hears it, once. */\nexport function settle(signal: HydrationWait): void {\n signal.committed = true;\n const waiters = signal.waiters;\n signal.waiters = [];\n for (const waiter of waiters) waiter();\n}\n\nfunction forget(signal: HydrationWait, waiter: () => void): void {\n const index = signal.waiters.indexOf(waiter);\n if (index >= 0) signal.waiters.splice(index, 1);\n}\n\n/**\n * Call back once the signal settles, or after `capMs` without it. Returns\n * `null` without calling back when it already has — a bfcache restore does\n * not wait again — and otherwise a cancel for a runtime that stops waiting.\n */\nexport function awaitSettled(\n signal: HydrationWait,\n onSettled: (outcome: HydrationOutcome) => void,\n capMs: number,\n): (() => void) | null {\n if (signal.committed) return null;\n let timer: ReturnType<typeof setTimeout> | null = null;\n const waiter = (): void => {\n if (timer !== null) clearTimeout(timer);\n timer = null;\n onSettled('committed');\n };\n signal.waiters.push(waiter);\n timer = setTimeout(() => {\n timer = null;\n forget(signal, waiter);\n onSettled('timed-out');\n }, capMs);\n return () => {\n if (timer !== null) clearTimeout(timer);\n timer = null;\n forget(signal, waiter);\n };\n}\n\n/**\n * Call back once React has committed a root that holds a binding and no\n * dehydrated server boundary, or after `capMs` without one. Arms the signal if\n * nothing has yet.\n */\nexport function whenReactCommitted(\n onSettled: (outcome: HydrationOutcome) => void,\n capMs = HYDRATION_WAIT_CAP_MS,\n): (() => void) | null {\n armReactCommitSignal();\n const signal = signalSlot();\n if (signal === undefined) return null;\n if (signal.onCommit === undefined) {\n // The runtime is the one that can judge a commit; the bootstrap may have\n // recorded some before it ran. The backlog first, then every commit live.\n const judge = (root: unknown): void => {\n if (!signal.committed && ownsHydratedBindings(root)) settle(signal);\n };\n signal.onCommit = judge;\n for (const root of signal.commits.splice(0)) judge(root);\n }\n return awaitSettled(signal, onSettled, capMs);\n}\n","/**\n * Waiting for Vue before the first write (ADR 0015, addendum of 2026-09-11).\n *\n * Vue's `hydrate()` walks the server markup and repairs what differs from its\n * own render, in place and quietly (development logs `Hydration completed but\n * contains mismatches.`). A value the runtime wrote before that is a mismatch\n * and is put back. Measured on the Nuxt fixture on 2026-09-11: the write at\n * 25.5 ms, hydration at 93.7 ms, the server's values back in the same tick;\n * what put them right again was the admin answering the runtime's second\n * `ready` at 500 ms — and a real admin answers `ready` once.\n *\n * Vue says nothing when it is done. What `runtime-core` does, in every build\n * and right after `hydrate()` has returned, is `rootContainer.__vue_app__ = app`\n * (`apiCreateApp.ts`, `mount`): the property Vue DevTools and `app.unmount()`\n * find the app by. The assignment is the signal. An accessor on\n * `Element.prototype` sees it without polling, files the app on the element\n * as an own property exactly as the assignment would have, and settles once\n * the container holds a binding — a widget mounted beside the page is not\n * ours to wait for. A runtime that evaluates after the mount (asset delivery)\n * finds the own property on an ancestor of its first binding instead, so no\n * armed bootstrap is needed: the signal is state, not an event.\n *\n * A Nuxt app hands its `$nuxt` on the same object, and a page whose setup\n * awaits real time hydrates its subtree only when the root Suspense resolves\n * (measured: `__vue_app__` at 494 ms, the subtree at 895 ms). Nuxt marks that\n * with `isHydrating`, cleared synchronously when the Suspense resolves and\n * before `app:suspense:resolve` runs — so an app still hydrating at the\n * mount is waited for through that hook, and one that is not settles at once.\n *\n * Not used, and why: `data-v-app` is set by `createApp().mount` only, never by\n * `createSSRApp()`'s (measured, and in `runtime-dom`); the DevTools hook\n * (`__VUE_DEVTOOLS_GLOBAL_HOOK__`, `app:init`) exists in development builds and\n * under `__VUE_PROD_DEVTOOLS__` only; a MutationObserver sees nothing on a\n * clean hydration; `window.useNuxtApp` is Nuxt's, set before the mount, and\n * `useNuxtApp()` needs Nuxt's context to answer from outside a component.\n */\n\nimport {\n BINDING_SELECTOR,\n HYDRATION_WAIT_CAP_MS,\n awaitSettled,\n settle,\n type HydrationOutcome,\n type HydrationWait,\n} from './hydration';\n\n/** Where runtime-core leaves the app on its container. */\nexport const VUE_APP_PROPERTY = '__vue_app__';\n\n/** One slot on the window, so a second copy of the runtime shares the state rather than the accessor. */\nexport const VUE_HYDRATION_SLOT = '__livePreviewVueHydration';\n\n/** The Nuxt hook that runs once the root Suspense has resolved, its subtree hydrated. */\nconst NUXT_HYDRATED_HOOK = 'app:suspense:resolve';\n\ninterface VueMountSignal extends HydrationWait {\n armed: boolean;\n}\n\n/** The two things read off a Nuxt app: whether it is still hydrating, and the hook that ends it. */\ninterface NuxtAppLike {\n readonly isHydrating?: boolean;\n readonly hook?: (name: string, fn: () => void) => unknown;\n}\n\ntype VueWindow = Window & { [VUE_HYDRATION_SLOT]?: VueMountSignal };\n\nfunction signalSlot(): VueMountSignal | undefined {\n if (typeof window === 'undefined') return undefined;\n const w = window as VueWindow;\n return (w[VUE_HYDRATION_SLOT] ??= { armed: false, committed: false, waiters: [] });\n}\n\n/** Vue's assignment lands as an own property; only that counts, never the accessor. */\nfunction mountedApp(node: Node): unknown {\n return Object.prototype.hasOwnProperty.call(node, VUE_APP_PROPERTY)\n ? (node as unknown as Record<string, unknown>)[VUE_APP_PROPERTY]\n : undefined;\n}\n\n/**\n * Arm before Vue mounts: the accessor on `Element.prototype` that turns the\n * mount into a signal. Idempotent, and it leaves a seam another copy of the\n * runtime — or a tool — already holds alone; the slot is shared either way,\n * and the accessor reads it live rather than closing over one.\n */\nexport function armVueMountSignal(): void {\n const signal = signalSlot();\n if (signal === undefined || signal.armed) return;\n signal.armed = true;\n const proto = Element.prototype;\n if (Object.getOwnPropertyDescriptor(proto, VUE_APP_PROPERTY) !== undefined) return;\n Object.defineProperty(proto, VUE_APP_PROPERTY, {\n configurable: true,\n get: () => undefined,\n set(this: Element, app: unknown) {\n Object.defineProperty(this, VUE_APP_PROPERTY, {\n value: app,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n const live = signalSlot();\n if (live === undefined || live.committed || this.querySelector(BINDING_SELECTOR) === null) {\n return;\n }\n settleOnceHydrated(live, app);\n },\n });\n}\n\n/** Mounted, and — for a Nuxt app whose Suspense is still pending — hydrated too. */\nfunction settleOnceHydrated(signal: VueMountSignal, app: unknown): void {\n const nuxt = (app as { $nuxt?: NuxtAppLike } | null | undefined)?.$nuxt;\n if (nuxt?.isHydrating === true && typeof nuxt.hook === 'function') {\n nuxt.hook(NUXT_HYDRATED_HOOK, () => {\n if (!signal.committed) settle(signal);\n });\n return;\n }\n settle(signal);\n}\n\n/** Whether an app already sits on an ancestor of a binding under `root` — the runtime came after Vue. */\nfunction mountedAround(root: Document | Element): boolean {\n for (let node = root.querySelector(BINDING_SELECTOR); node !== null; node = node.parentElement) {\n if (mountedApp(node) !== undefined) return true;\n }\n return false;\n}\n\n/**\n * Call back once Vue has mounted — and, on Nuxt, hydrated — an app around a\n * binding of `root`, or after `capMs` without one. Arms the signal if nothing\n * has yet; `null` when it already happened.\n */\nexport function whenVueMounted(\n root: Document | Element,\n onSettled: (outcome: HydrationOutcome) => void,\n capMs = HYDRATION_WAIT_CAP_MS,\n): (() => void) | null {\n armVueMountSignal();\n const signal = signalSlot();\n if (signal === undefined) return null;\n if (!signal.committed && mountedAround(root)) settle(signal);\n return awaitSettled(signal, onSettled, capMs);\n}\n","/**\n * When the runtime may start: after the document has parsed, and on a page\n * that declares hydration after the framework's first commit — React's, Vue's\n * mount, or SvelteKit's root mounting — or the cap (ADR 0015).\n *\n * `lifecycle.ts` owns the resources a start acquires and how a failed one is\n * rolled back; this module owns only the waiting. It moved out when the\n * second wait pushed the lifecycle past its 500 lines, and it stays a chain of\n * plain functions over a small host so that a stage running after `start()`\n * has returned still rolls back and reports the way a synchronous failure\n * throws — the host's `later` is that seam, and `defer` is how `release()`\n * abandons whichever wait is in progress.\n */\n\nimport {\n HYDRATION_WAIT_CAP_MS,\n armReactCommitSignal,\n whenReactCommitted,\n type HydrationMode,\n type HydrationOutcome,\n type HydrationState,\n} from './hydration';\nimport { armVueMountSignal, whenVueMounted } from './hydration-vue';\nimport { whenSvelteKitMounted } from './hydration-sveltekit';\n\n/** What the startup chain needs from the runtime. */\nexport interface StartupHost {\n readonly root: Document | Element;\n readonly hydration: HydrationMode | undefined;\n /** Whether the runtime is still meant to start; a stop in between abandons the chain. */\n isRunning(): boolean;\n /** Keeps the way to abandon the wait in progress, for `release()`. */\n defer(cancel: () => void): void;\n /** Runs a stage after `start()` has returned: a throw is rolled back and reported, not lost. */\n later(step: () => void): void;\n /** Records how far the wait for hydration got, for `inspect()`. */\n hydrated(state: HydrationState): void;\n warn(message: string): void;\n /** Acquires the resources; throws into the caller when synchronous. */\n startNow(): void;\n}\n\n/**\n * Synchronous when nothing is pending. Otherwise the host is handed a cancel\n * and the chain continues through `later` once the wait ends.\n */\nexport function startWhenReady(host: StartupHost): void {\n // Armed before anything defers: the framework may evaluate before DOMContentLoaded.\n if (host.hydration === 'react') armReactCommitSignal();\n else if (host.hydration === 'vue') armVueMountSignal();\n const { root } = host;\n if (!isDocumentRoot(root) || root.readyState !== 'loading') {\n startAfterParse(host);\n return;\n }\n const onReady = (): void => {\n if (!host.isRunning()) return;\n host.later(() => {\n startAfterParse(host);\n });\n };\n root.addEventListener('DOMContentLoaded', onReady, { once: true });\n host.defer(() => {\n root.removeEventListener('DOMContentLoaded', onReady);\n });\n}\n\n/** A page a framework hydrates is not final until the framework has committed. */\nfunction startAfterParse(host: StartupHost): void {\n const mode = host.hydration;\n if (mode === undefined) {\n host.startNow();\n return;\n }\n const onSettled = (outcome: HydrationOutcome): void => {\n host.later(() => {\n startHydrated(host, mode, outcome);\n });\n };\n const pending = WAITS[mode](host.root, onSettled);\n // Already committed — a bfcache restore does not wait again.\n if (pending === null) {\n startHydrated(host, mode, 'committed');\n return;\n }\n host.defer(pending);\n host.hydrated('waiting');\n}\n\n/** One wait per framework; each returns `null` when there is nothing left to wait for. */\nconst WAITS: Record<\n HydrationMode,\n (root: Document | Element, onSettled: (outcome: HydrationOutcome) => void) => (() => void) | null\n> = {\n react: (_root, onSettled) => whenReactCommitted(onSettled),\n vue: whenVueMounted,\n sveltekit: whenSvelteKitMounted,\n};\n\n/** What LP0607 says the runtime waited for. */\nconst AWAITED: Record<HydrationMode, string> = {\n react: 'React commit',\n vue: 'Vue mount',\n sveltekit: 'SvelteKit mount',\n};\n\nfunction startHydrated(host: StartupHost, mode: HydrationMode, outcome: HydrationOutcome): void {\n host.hydrated(outcome);\n if (outcome === 'timed-out') {\n host.warn(\n `[live-preview] LP0607: no ${AWAITED[mode]} in ${String(HYDRATION_WAIT_CAP_MS)} ms; started without waiting for hydration.`,\n );\n }\n host.startNow();\n}\n\n/** Node types are stable across realms; global constructors are not. */\nexport function isDocumentRoot(root: Document | Element): root is Document {\n return root.nodeType === 9;\n}\n\n/** Unlike lib.dom's declaration, a document running in `<head>` may not have a body yet. */\nexport function readDocumentBody(root: Document): HTMLElement | null {\n return root.body;\n}\n","/**\n * Waiting for SvelteKit before the first write (ADR 0015, addendum of 2026-10-01).\n *\n * Svelte's hydration claims the server's nodes and then runs each template\n * effect once; `set_text` compares its value with the node's text and writes\n * its own where they differ. A value the runtime wrote before that is put back,\n * quietly, as Vue does. Measured on the SvelteKit fixture's `/navigation` under\n * eight Playwright workers on 2026-09-30: the runtime's write, then 4 to 20 ms\n * later the server's title on the same node, in 5 to 7 of 40 runs.\n *\n * Neither Svelte nor SvelteKit says when hydration is done. What SvelteKit's\n * generated root does (read in 2.0.0 and in 2.70.2, the fixture's) is render\n * its route announcer (`<div id=\"svelte-announcer\">`) under `{#if mounted}`,\n * with `mounted` set in the root's `onMount`: after the tree below it has been\n * hydrated and its template effects have run. The element is state, not an\n * event, so a runtime that evaluates after the mount (asset delivery) finds it.\n *\n * A page served with `csr = false` has no client and never renders the\n * announcer; waiting for it would cost every such page the cap. SvelteKit's\n * start script assigns its global (`__sveltekit_dev`, `__sveltekit_<hash>`)\n * only on a page it will hydrate, and by `DOMContentLoaded` that classic\n * script has run, so a page without the global starts at once.\n */\n\nimport {\n HYDRATION_WAIT_CAP_MS,\n awaitSettled,\n settle,\n type HydrationOutcome,\n type HydrationWait,\n} from './hydration';\n\n/** The live region SvelteKit's root renders once it has mounted (`write_root.js`). */\nexport const SVELTEKIT_ANNOUNCER_ID = 'svelte-announcer';\n\n/** What the global SvelteKit's start script assigns begins with (`get_global_name`). */\nexport const SVELTEKIT_GLOBAL_PREFIX = '__sveltekit_';\n\n/** SvelteKit's client will run on this page: its start script left its global. */\nfunction clientStarts(): boolean {\n return Object.keys(window).some((key) => key.startsWith(SVELTEKIT_GLOBAL_PREFIX));\n}\n\n/**\n * Call back once SvelteKit's root has mounted, its announcer in the document,\n * or after `capMs` without it. `null` when there is nothing to wait for: the\n * root has mounted already, or no SvelteKit client runs on the page.\n */\nexport function whenSvelteKitMounted(\n root: Document | Element,\n onSettled: (outcome: HydrationOutcome) => void,\n capMs = HYDRATION_WAIT_CAP_MS,\n): (() => void) | null {\n // The announcer is the document's, whatever part of it the runtime binds.\n const page = root.ownerDocument ?? root;\n const mounted = (): boolean => page.querySelector(`#${SVELTEKIT_ANNOUNCER_ID}`) !== null;\n if (mounted() || !clientStarts()) return null;\n const signal: HydrationWait = { committed: false, waiters: [] };\n const observer = new MutationObserver(() => {\n if (!signal.committed && mounted()) settle(signal);\n });\n observer.observe(page, { childList: true, subtree: true });\n const cancel = awaitSettled(\n signal,\n (outcome) => {\n observer.disconnect();\n onSettled(outcome);\n },\n capMs,\n );\n return () => {\n observer.disconnect();\n cancel?.();\n };\n}\n","/** Connection status and the heartbeat that decides a disconnect. */\n\nexport type ConnectionStatus = 'disconnected' | 'connecting' | 'connected';\n\nexport interface HeartbeatOptions {\n /**\n * Silence before declaring a timeout. `0` disables the timer, which is right\n * for the stock Payload protocol: it sends messages only on edits, so any\n * idle timeout would report false disconnects.\n */\n readonly timeoutMs?: number;\n readonly onTimeout: () => void;\n}\n\nexport class HeartbeatTimer {\n private readonly timeoutMs: number;\n private readonly onTimeout: () => void;\n private handle: ReturnType<typeof setTimeout> | null = null;\n private lastKick: number | null = null;\n\n constructor(options: HeartbeatOptions) {\n this.timeoutMs = options.timeoutMs ?? 0;\n this.onTimeout = options.onTimeout;\n }\n\n /** Called on every valid message; re-arms the timeout. */\n kick(): void {\n this.lastKick = Date.now();\n if (this.timeoutMs <= 0) return;\n this.stop();\n this.arm(this.timeoutMs);\n }\n\n /**\n * Re-arm after a lifecycle pause without granting a fresh trust window.\n * Returns whether the old deadline expired while the timer was stopped.\n */\n resume(): boolean {\n if (this.timeoutMs <= 0 || this.handle !== null || this.lastKick === null) return false;\n const elapsed = Math.max(0, Date.now() - this.lastKick);\n const remaining = this.timeoutMs - elapsed;\n if (remaining <= 0) {\n this.lastKick = null;\n this.onTimeout();\n return true;\n }\n this.arm(Math.min(remaining, this.timeoutMs));\n return false;\n }\n\n private arm(delay: number): void {\n const handle = setTimeout(() => {\n if (this.handle !== handle) return;\n this.handle = null;\n this.lastKick = null;\n this.onTimeout();\n }, delay);\n this.handle = handle;\n }\n\n stop(): void {\n if (this.handle === null) return;\n clearTimeout(this.handle);\n this.handle = null;\n }\n\n get lastKickAt(): number {\n return this.lastKick ?? 0;\n }\n\n get pending(): boolean {\n return this.handle !== null;\n }\n}\n\nexport class ConnectionState {\n private current: ConnectionStatus = 'disconnected';\n\n get status(): ConnectionStatus {\n return this.current;\n }\n\n /** Returns whether the status changed. */\n markConnected(): boolean {\n return this.transition('connected');\n }\n\n markDisconnected(): boolean {\n return this.transition('disconnected');\n }\n\n private transition(next: ConnectionStatus): boolean {\n if (this.current === next) return false;\n this.current = next;\n return true;\n }\n}\n","/**\n * Auto-binding (ADR 0014). On the connection's first message the document and\n * the DOM are two views of the same state, so a scalar field's value can be\n * looked for in the page: where it stands as the whole content of exactly one\n * element — its only text node, or one attribute the writer may set — that\n * element is bound to the field as if `data-payload-field` had been written\n * there. No match, several, a partial one, one split across nodes: nothing,\n * and the field stays unbound, which since Z3 escalates instead of degrading.\n *\n * Two jobs, two exports. `findUniqueBindings` is the search, the exclusions and\n * the candidate rule, and reads the DOM only. `adoptUniqueBindings` writes the\n * winners onto their elements as the attributes a template would have carried,\n * plus `data-payload-guessed` holding the value that matched, and registers\n * them with the cache. Stamping is what lets a cache rebuild find a guess again\n * the way it finds any binding, and what lets `inspect()` and the overlay tell\n * a guess from a declaration.\n */\n\nimport { isWritableAttribute } from './attribute-binding';\nimport { isBindingInScope } from './binding-owner';\nimport {\n ALT_ATTRIBUTE,\n FIELD_ATTRIBUTE,\n GUESSED_ATTRIBUTE,\n HREF_ATTRIBUTE,\n TARGET_ATTRIBUTE_ATTRIBUTE,\n TYPE_ATTRIBUTE,\n resolveBindingOwner,\n} from './cache';\nimport { isIslandBoundary, OWNED_ATTRIBUTE } from './islands';\nimport type { RuntimeDeps, RuntimeState } from './runtime-state';\nimport { stripLocaleSuffix, SYSTEM_FIELD_NAMES, type OwnerScope } from './unbound-fields';\n\n/** `'unique'` searches once, on the first message; `'off'` (the default) never. */\nexport type AutoBindMode = 'off' | 'unique';\n\n/** An author's no: the element and everything under it is never guessed into. */\nexport const NO_BIND_ATTRIBUTE = 'data-payload-no-bind';\n/** The morph's boundary (`src/core/morph.ts`) is this search's boundary too: a subtree the site scripts itself. */\n\n/**\n * Below this many characters a value is not looked for at all. Measured, not\n * chosen: on the trap corpus (`tests/fixtures/auto-bind-traps`) 13 is the\n * shortest floor at which no trap binds — at 12 the byline `Ada Lovelace`,\n * printed by a related post and never by the template, is a unique match in\n * the wrong place. The shortest value the shipped fixtures bind that a unique\n * match finds is `Visit Payload`, 13. So the floor separates the corpus with\n * no margin either way; what it is for are the short tokens ADR 0014 names,\n * and a phrase that occurs exactly once and in the wrong place is kept out by\n * nothing but its rarity.\n */\nexport const AUTO_BIND_MIN_LENGTH = 13;\n\nconst BOOLEAN_WORDS: ReadonlySet<string> = new Set(['true', 'false', 'yes', 'no', 'on', 'off']);\n/** Digits with the separators a date, a time, a price or a phone number carry. */\nconst NUMERIC = /^[\\d\\s.,:+/-]+$/u;\n/** A single lower-case token: an enum value, a slug, a code. */\nconst ENUM_TOKEN = /^[a-z][a-z0-9_-]*$/u;\n/** `de`, `de-AT`, `zh_Hant`, `sr-Latn-RS`. */\nconst LOCALE_CODE = /^[a-z]{2,3}(?:[-_][A-Za-z0-9]{2,8})*$/u;\n\n/** Elements whose text is code, metadata or a form value, not content. */\nconst SKIPPED_TAGS: ReadonlySet<string> = new Set([\n 'SCRIPT',\n 'STYLE',\n 'TEMPLATE',\n 'TITLE',\n 'NOSCRIPT',\n 'TEXTAREA',\n 'SELECT',\n 'OPTION',\n 'INPUT',\n 'IFRAME',\n]);\nconst HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n\nexport interface AutoBindCandidate {\n readonly element: Element;\n readonly fieldName: string;\n /** The value that matched: the text, or the attribute's value. */\n readonly matched: string;\n /** The attribute whose whole value matched; absent for a text match. */\n readonly attribute?: string;\n /** The `data-payload-*` attributes a template would have written for this binding. */\n readonly stamps: Readonly<Record<string, string>>;\n}\n\n/** A value's owner: the field, and whether it is an upload (matched by its `url` against an `<img>`). */\nexport interface Claim {\n readonly field: string;\n readonly media: boolean;\n}\n\n/**\n * What the baseline search adopted, kept for the server re-render a route\n * refresh morphs the page toward: that markup carries no stamp, so the guesses\n * are looked for again there — these fields, by these values — and nothing\n * else is. ADR 0014 §1 still holds for everything the baseline did not find.\n */\nexport interface KeptGuesses {\n /** The fields the guesses bound, a folded second field (`data-payload-href`, `data-payload-alt`) included. */\n readonly fields: ReadonlySet<string>;\n /** The texts they were found by, each claiming its field. */\n readonly values: ReadonlyMap<string, Claim>;\n}\n\n/** Whether a scalar is worth looking for: the short and shapeless ones match by accident. */\nexport function isBindableValue(value: unknown, minLength = AUTO_BIND_MIN_LENGTH): value is string {\n if (typeof value !== 'string') return false;\n const text = value.trim();\n if (text.length < minLength) return false;\n if (NUMERIC.test(text) || BOOLEAN_WORDS.has(text.toLowerCase())) return false;\n return !ENUM_TOKEN.test(text) && !LOCALE_CODE.test(text);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * The values to look for, keyed by the exact text a match must equal. A value\n * two fields share maps to `null`: the element would be unique, the field not.\n * Groups are opened one level under the dotted name a binding would carry; an\n * upload is looked for by its `url`; a document with an `id` and no `url` is\n * another document, and its scalars are not this one's.\n */\nexport function bindableValues(\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n minLength = AUTO_BIND_MIN_LENGTH,\n): Map<string, Claim | null> {\n const values = new Map<string, Claim | null>();\n const claim = (text: string, field: string, media: boolean): void => {\n values.set(text, values.has(text) ? null : { field, media });\n };\n for (const [rawName, value] of Object.entries(fields)) {\n if (SYSTEM_FIELD_NAMES.has(rawName)) continue;\n const name = stripLocaleSuffix(rawName, locale);\n if (isBindableValue(value, minLength)) {\n claim(value.trim(), name, false);\n } else if (isRecord(value)) {\n if (typeof value['url'] === 'string') {\n claim(value['url'], name, true);\n } else if (!('id' in value) && !('_id' in value)) {\n for (const [child, childValue] of Object.entries(value)) {\n if (SYSTEM_FIELD_NAMES.has(child) || !isBindableValue(childValue, minLength)) continue;\n claim(childValue.trim(), `${name}.${child}`, false);\n }\n }\n }\n }\n return values;\n}\n\n/** Where the search stops: nothing at or under this element may be claimed. */\nfunction isBoundary(element: Element): boolean {\n if (element.namespaceURI !== HTML_NAMESPACE || SKIPPED_TAGS.has(element.tagName)) return true;\n if (\n element.hasAttribute(FIELD_ATTRIBUTE) ||\n element.hasAttribute(NO_BIND_ATTRIBUTE) ||\n element.hasAttribute(OWNED_ATTRIBUTE) ||\n isIslandBoundary(element)\n ) {\n return true;\n }\n const editable = element.getAttribute('contenteditable');\n return editable !== null && editable !== 'false';\n}\n\n/**\n * The element's whole text, when it is exactly one text node — comments and\n * whitespace-only nodes aside — and no element. A second text node is a value\n * split across nodes; an element child is markup a text write would destroy.\n */\nfunction soleText(element: Element): string | undefined {\n let text: string | undefined;\n for (let child = element.firstChild; child !== null; child = child.nextSibling) {\n if (child.nodeType === 1) return undefined;\n if (child.nodeType !== 3) continue;\n const data = (child as Text).data.trim();\n if (data.length === 0) continue;\n if (text !== undefined) return undefined;\n text = data;\n }\n return text;\n}\n\n/** No second rule beyond the writer's own; `value` is the visitor's, and `data-payload-*` is ours. */\nfunction isCandidateAttribute(name: string): boolean {\n return isWritableAttribute(name) && !name.startsWith('data-payload-') && name !== 'value';\n}\n\ninterface ElementHits {\n /** The field whose value is the element's whole text. */\n text?: string;\n /** Attribute name → the field whose value it carries. */\n readonly attributes: Map<string, Claim>;\n}\n\ninterface Search {\n readonly values: ReadonlyMap<string, Claim | null>;\n readonly byElement: Map<Element, ElementHits>;\n /** Every element a field was found on; a field with more than one is ambiguous. */\n readonly byField: Map<string, Set<Element>>;\n}\n\nfunction record(search: Search, element: Element, claim: Claim): ElementHits {\n let hits = search.byElement.get(element);\n if (hits === undefined) {\n hits = { attributes: new Map() };\n search.byElement.set(element, hits);\n }\n let elements = search.byField.get(claim.field);\n if (elements === undefined) {\n elements = new Set();\n search.byField.set(claim.field, elements);\n }\n elements.add(element);\n return hits;\n}\n\n/**\n * One pass, depth first, in document order; the element under a boundary is\n * never looked at. Sibling pointers rather than `children` and `attributes`:\n * the live collections cost twenty times the walk in jsdom, where the\n * interaction gate measures this, and nothing in a browser.\n */\nfunction walk(element: Element, search: Search): void {\n for (let child = element.firstElementChild; child !== null; child = child.nextElementSibling) {\n if (isBoundary(child)) continue;\n const text = soleText(child);\n const textClaim = text === undefined ? undefined : search.values.get(text);\n if (textClaim != null && !textClaim.media) {\n record(search, child, textClaim).text = textClaim.field;\n }\n for (const name of child.getAttributeNames()) {\n if (!isCandidateAttribute(name)) continue;\n const claim = search.values.get(child.getAttribute(name) ?? '');\n if (claim == null) continue;\n // An upload is matched by its file, and an `<img>` is the one element that renders one.\n if (claim.media && (child.tagName !== 'IMG' || name !== 'src')) continue;\n record(search, child, claim).attributes.set(name, claim);\n }\n walk(child, search);\n }\n}\n\n/**\n * What a template would have written for this element. One binding per\n * element: the text wins, and the two idioms a template has for a second\n * field on the same element — `data-payload-href` on a link, `data-payload-alt`\n * on an image — are used when the second field matched that attribute.\n */\nfunction shape(\n element: Element,\n text: string | undefined,\n attributes: ReadonlyMap<string, string>,\n): AutoBindCandidate | undefined {\n const tag = element.tagName;\n if (text !== undefined) {\n const stamps: Record<string, string> = { [FIELD_ATTRIBUTE]: text };\n if (tag === 'A') {\n const href = attributes.get('href');\n // The url renderer derives the href from the text; a guess that never\n // matched the href must not clear it, so the text renderer is named.\n if (href === undefined) stamps[TYPE_ATTRIBUTE] = 'text';\n else if (href !== text) stamps[HREF_ATTRIBUTE] = href;\n }\n return { element, fieldName: text, matched: soleText(element) ?? '', stamps };\n }\n if (tag === 'IMG') {\n const src = attributes.get('src');\n if (src !== undefined) {\n const alt = attributes.get('alt');\n return {\n element,\n fieldName: src,\n matched: element.getAttribute('src') ?? '',\n attribute: 'src',\n stamps: {\n [FIELD_ATTRIBUTE]: src,\n ...(alt !== undefined && alt !== src ? { [ALT_ATTRIBUTE]: alt } : {}),\n },\n };\n }\n }\n // A link whose text did not match keeps its text: only the attribute is written.\n const first = attributes.entries().next();\n if (first.done) return undefined;\n const [name, field] = first.value;\n return {\n element,\n fieldName: field,\n matched: element.getAttribute(name) ?? '',\n attribute: name,\n stamps: { [FIELD_ATTRIBUTE]: field, [TARGET_ATTRIBUTE_ATTRIBUTE]: name },\n };\n}\n\n/**\n * The bindings the page allows, in document order: for every field found on\n * exactly one element, that element with the attributes a template would have\n * given it. `root` is searched as a whole; the caller decides that a document's\n * root is its body.\n */\nexport function findUniqueBindings(\n root: Element,\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n minLength = AUTO_BIND_MIN_LENGTH,\n): AutoBindCandidate[] {\n return searchUnique(root, bindableValues(fields, locale, minLength));\n}\n\n/** The search proper, over a value table already decided on. */\nfunction searchUnique(\n root: Element,\n values: ReadonlyMap<string, Claim | null>,\n): AutoBindCandidate[] {\n const search: Search = { values, byElement: new Map(), byField: new Map() };\n if (values.size > 0 && !isBoundary(root)) walk(root, search);\n const unique = (field: string): boolean => search.byField.get(field)?.size === 1;\n const candidates: AutoBindCandidate[] = [];\n for (const [element, hits] of search.byElement) {\n const text = hits.text !== undefined && unique(hits.text) ? hits.text : undefined;\n const attributes = new Map<string, string>();\n for (const [name, claim] of hits.attributes) {\n if (unique(claim.field)) attributes.set(name, claim.field);\n }\n const candidate = shape(element, text, attributes);\n if (candidate !== undefined) candidates.push(candidate);\n }\n return candidates;\n}\n\n/** A document's root is its body: a binding in `<head>` needs the attribute and the route strategy. */\nfunction searchRoot(root: Document | Element): Element | null {\n return root.nodeType === 9 ? (root as Document).body : (root as Element);\n}\n\n/**\n * Run the search once and make its winners bindings. Returns how many. The\n * stamps land on the elements first, so the cache resolves each guess exactly\n * as it resolves a declared binding — and so the mutation observer's rebuild,\n * which the stamps themselves trigger, finds them again.\n */\nexport function adoptUniqueBindings(\n deps: RuntimeDeps,\n state: RuntimeState,\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n isCurrent: () => boolean,\n): number {\n if (!isCurrent()) return 0;\n const started = performance.now();\n const root = searchRoot(deps.root);\n const values = bindableValues(fields, locale);\n if (!isCurrent()) return 0;\n const candidates = root === null ? [] : searchUnique(root, values);\n if (!isCurrent()) return 0;\n const adopted = adopt(deps, candidates, ownerKeys, 'on the first message', isCurrent);\n if (!isCurrent()) return 0;\n const guesses = keep(values, adopted);\n const elapsed = performance.now() - started;\n if (!isCurrent()) return 0;\n state.autoBindGuesses = guesses;\n state.autoBindSearchMs = elapsed;\n return adopted.length;\n}\n\n/**\n * After a server render — a route refresh, or a fragment in its boundary: the\n * server's markup carries no stamp, so the guesses the baseline made are gone\n * from what it rendered. Look for them again, by the value\n * each was found by and by the field's value in this revision — the server\n * may have rendered either, the document as it was saved or a draft it\n * autosaved since. A field found by both, on two elements, is ambiguous and\n * stays unbound. Nothing the baseline did not bind is looked for: a second\n * baseline would be a second chance at a wrong match, and the first one is\n * the only moment the page is known to show the document (ADR 0014 §1).\n */\nexport function restoreUniqueBindings(\n deps: RuntimeDeps,\n state: RuntimeState,\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n isCurrent: () => boolean,\n): number {\n if (!isCurrent()) return 0;\n const kept = state.autoBindGuesses;\n const root = searchRoot(deps.root);\n if (kept === null || kept.fields.size === 0 || root === null) return 0;\n const values = new Map<string, Claim | null>(kept.values);\n for (const [text, claim] of bindableValues(fields, locale)) {\n if (claim === null || !kept.fields.has(claim.field)) continue;\n const known = values.get(text);\n if (known === undefined) values.set(text, claim);\n else if (known?.field !== claim.field) values.set(text, null);\n }\n if (!isCurrent()) return 0;\n const candidates = searchUnique(root, values);\n if (!isCurrent()) return 0;\n return adopt(deps, candidates, ownerKeys, 'after a server render', isCurrent).length;\n}\n\ninterface AdoptionMutation {\n readonly element: Element;\n readonly attributes: {\n readonly name: string;\n readonly before: string | null;\n readonly written: string;\n }[];\n cacheTouched: boolean;\n observed: boolean;\n}\n\n/** Undo only values this attempt still owns; a reentrant writer's different value wins. */\nfunction rollback(deps: RuntimeDeps, mutations: readonly AdoptionMutation[]): void {\n for (let index = mutations.length - 1; index >= 0; index -= 1) {\n const mutation = mutations[index];\n if (mutation === undefined) continue;\n if (mutation.observed) deps.observers.unobserveElement(mutation.element);\n for (let attribute = mutation.attributes.length - 1; attribute >= 0; attribute -= 1) {\n const changed = mutation.attributes[attribute];\n if (changed === undefined) continue;\n const { name, before, written } = changed;\n if (before === written || mutation.element.getAttribute(name) !== written) continue;\n if (before === null) mutation.element.removeAttribute(name);\n else mutation.element.setAttribute(name, before);\n }\n if (!mutation.cacheTouched) continue;\n if (mutation.element.hasAttribute(FIELD_ATTRIBUTE)) deps.cache.add(mutation.element);\n else deps.cache.remove(mutation.element);\n }\n}\n\n/** Stamp the candidates, register them, say so; returns the ones that became bindings. */\nfunction adopt(\n deps: RuntimeDeps,\n candidates: readonly AutoBindCandidate[],\n ownerKeys: OwnerScope,\n when: string,\n isCurrent: () => boolean,\n): AutoBindCandidate[] {\n const adopted: AutoBindCandidate[] = [];\n const mutations: AdoptionMutation[] = [];\n const abandon = (): AutoBindCandidate[] => {\n rollback(deps, mutations);\n return [];\n };\n for (const candidate of candidates) {\n if (!isCurrent()) return abandon();\n const { element } = candidate;\n if (element.hasAttribute(FIELD_ATTRIBUTE)) continue;\n if (!isCurrent()) return abandon();\n // Under owner scoping a guess outside the message's document would never\n // be written to; better to leave it unbound than to bind it to nothing.\n if (ownerKeys !== false && !isBindingInScope(resolveBindingOwner(element), ownerKeys)) continue;\n if (!isCurrent()) return abandon();\n const mutation: AdoptionMutation = {\n element,\n attributes: [],\n cacheTouched: false,\n observed: false,\n };\n mutations.push(mutation);\n for (const [name, value] of [\n ...Object.entries(candidate.stamps),\n [GUESSED_ATTRIBUTE, candidate.matched] as const,\n ]) {\n const before = element.getAttribute(name);\n if (!isCurrent()) return abandon();\n mutation.attributes.push({ name, before, written: value });\n element.setAttribute(name, value);\n if (!isCurrent()) return abandon();\n }\n mutation.cacheTouched = true;\n if (deps.cache.add(element) === undefined) {\n // The cache's own filter refused it; restore metadata the unbound element carried before the attempt.\n rollback(deps, [mutation]);\n mutations.pop();\n continue;\n }\n if (!isCurrent()) return abandon();\n deps.observers.observeElement(element);\n mutation.observed = true;\n if (!isCurrent()) return abandon();\n deps.log(\n 'autoBind',\n candidate.fieldName,\n '→',\n `<${element.tagName.toLowerCase()}>`,\n candidate.attribute ?? 'text',\n JSON.stringify(candidate.matched),\n when,\n );\n if (!isCurrent()) return abandon();\n adopted.push(candidate);\n }\n return adopted;\n}\n\n/** The fields the adopted guesses bound, and the values that found them. */\nfunction keep(\n values: ReadonlyMap<string, Claim | null>,\n adopted: readonly AutoBindCandidate[],\n): KeptGuesses {\n const fields = new Set<string>();\n for (const { fieldName, stamps } of adopted) {\n fields.add(fieldName);\n for (const name of [HREF_ATTRIBUTE, ALT_ATTRIBUTE]) {\n const folded = stamps[name];\n if (folded !== undefined) fields.add(folded);\n }\n }\n const kept = new Map<string, Claim>();\n for (const [text, claim] of values) {\n if (claim !== null && fields.has(claim.field)) kept.set(text, claim);\n }\n return { fields, values: kept };\n}\n","/**\n * Resolve and enforce the document owner scope shared by every update stage.\n * Keeping the warning here makes every caller use the same fail-closed decision.\n */\n\nimport { messageOwnerKeys, readDocumentId } from './binding-owner';\nimport type { RuntimeDeps, RuntimeState, UpdateTransaction } from './runtime-state';\nimport type { OwnerScope } from './unbound-fields';\n\nexport function ownerKeysForUpdate(\n deps: RuntimeDeps,\n state: RuntimeState,\n transaction: UpdateTransaction,\n fields: Record<string, unknown>,\n): OwnerScope {\n if (!deps.scopeBindingsByOwner) return false;\n const { message } = transaction;\n const keys = messageOwnerKeys({\n globalSlug: typeof message.globalSlug === 'string' ? message.globalSlug : undefined,\n collectionSlug: typeof message.collectionSlug === 'string' ? message.collectionSlug : undefined,\n documentId: readDocumentId(fields),\n });\n if (keys === null && !state.warnedUnattributableMessage) {\n state.warnedUnattributableMessage = true;\n deps.warn(\n '[live-preview] LP0202: scopeBindingsByOwner: update names no document; nothing applied',\n );\n }\n return keys;\n}\n","/**\n * Keeps a locally retained navigation document aligned with DOM that arrives\n * after the router's commit. It scopes late work to newly discovered targets\n * and never treats the replay as fresh editor traffic.\n */\n\nimport type { PayloadLivePreviewData } from '@/types/payload-protocol';\nimport { isBindingInScope } from './binding-owner';\nimport {\n DEPENDS_ATTRIBUTE,\n FIELD_ATTRIBUTE,\n resolveBindingOwner,\n STRATEGY_ATTRIBUTE,\n} from './cache';\nimport { parseDependencyList } from './dependencies';\nimport { bindingValue } from './field-value';\nimport { dispatchIslandUpdate, isAwaitingIslandHydration } from './islands';\nimport type { RuntimeDeps, RuntimeState, UpdateTransaction } from './runtime-state';\nimport { planBoundaries, resolveStrategy, type FragmentPlan } from './strategies';\nimport type { OwnerScope } from './unbound-fields';\nimport { ownerKeysForUpdate } from './update-owner';\n\ninterface NavigationReplayHost {\n readonly schedule: (\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n elements: ReadonlySet<Element>,\n ) => void;\n}\n\nexport class NavigationReplay {\n private readonly awaitingHydration = new WeakSet<Element>();\n /** A fallback flush may carry the same snapshot after the no-patch handoff. */\n private readonly delivered = new WeakMap<PayloadLivePreviewData, WeakSet<Element>>();\n /** Each island confirms a revision once, however often it is handed it (ADR 0023). */\n private readonly confirmations = new WeakMap<\n Element,\n { readonly transaction: UpdateTransaction; readonly displayed: () => void }\n >();\n\n constructor(\n private readonly deps: RuntimeDeps,\n private readonly state: RuntimeState,\n private readonly host: NavigationReplayHost,\n ) {}\n\n reapplyBindings(elements: ReadonlySet<Element>): void {\n const transaction = this.currentTransaction();\n if (transaction?.renderData === undefined) return;\n this.host.schedule(transaction, transaction.renderData, elements);\n }\n\n reapplyIslands(islands: readonly Element[], hydrationCompleted = false): void {\n const replay = hydrationCompleted\n ? islands.filter((island) => this.awaitingHydration.delete(island))\n : islands;\n const active = this.state.activeUpdate;\n const transaction =\n hydrationCompleted && active !== null && this.state.isCurrent(active)\n ? active\n : this.currentTransaction();\n if (transaction?.renderData === undefined) return;\n this.dispatchIslands(transaction, transaction.renderData, replay);\n }\n\n dispatchIslands(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n islands: readonly Element[],\n ): void {\n const ownerKeys = ownerKeysForUpdate(this.deps, this.state, transaction, data.fields);\n const isCurrent = (): boolean => !transaction.cancelled && this.state.isCurrent(transaction);\n if (!isCurrent()) return;\n let delivered = this.delivered.get(data);\n if (delivered === undefined) {\n delivered = new WeakSet();\n this.delivered.set(data, delivered);\n }\n for (const island of islands) {\n const owner = resolveBindingOwner(island);\n if (!isCurrent()) return;\n if (ownerKeys !== false && !isBindingInScope(owner, ownerKeys)) {\n this.awaitingHydration.delete(island);\n continue;\n }\n // Counted while it hydrates too: it owes the revision a render.\n const displayed = this.confirmation(island, transaction);\n if (isAwaitingIslandHydration(island)) {\n this.awaitingHydration.add(island);\n } else {\n this.awaitingHydration.delete(island);\n if (delivered.has(island)) continue;\n // Claim before calling application code: it can re-enter this fanout.\n delivered.add(island);\n dispatchSnapshotToIslands(transaction, data, [island], isCurrent, displayed);\n }\n }\n }\n\n hasLateRouteBinding(\n elements: ReadonlySet<Element>,\n ownerKeys: OwnerScope,\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n ): boolean {\n for (const element of elements) {\n if (\n (element.getAttribute(FIELD_ATTRIBUTE) ?? '').length > 0 ||\n element.getAttribute(STRATEGY_ATTRIBUTE) !== 'route'\n ) {\n continue;\n }\n if (ownerKeys !== false && !isBindingInScope(resolveBindingOwner(element), ownerKeys)) {\n continue;\n }\n const dependsOn = parseDependencyList(element.getAttribute(DEPENDS_ATTRIBUTE));\n if (dependsOn.length === 0 || dependsOn.some((field) => transaction.touched.has(field))) {\n return true;\n }\n }\n for (const [fieldName, bindings] of this.deps.cache.entries()) {\n for (const target of bindings) {\n if (!elements.has(target.element)) continue;\n if (ownerKeys !== false && !isBindingInScope(target.owner, ownerKeys)) continue;\n const kind = target.strategyKind ?? resolveStrategy(target.element) ?? 'unknown';\n if (kind !== 'route') continue;\n const value = bindingValue(data.fields, target, fieldName, transaction.locale);\n if (!this.state.isCurrent(transaction)) return false;\n if (value !== undefined) return true;\n }\n }\n return false;\n }\n\n fieldsForElements(\n elements: ReadonlySet<Element>,\n touched: ReadonlySet<string>,\n ): ReadonlySet<string> {\n const fields = new Set(touched);\n for (const [fieldName, bindings] of this.deps.cache.entries()) {\n if (bindings.some((target) => elements.has(target.element))) fields.add(fieldName);\n }\n return fields;\n }\n\n /**\n * The boundaries of `plan` this revision has not rendered yet. `null` stays\n * the answer for a page without a fragment strategy only: a plan left with no\n * boundary still has a handler, and the pipeline reads `null` as LP0806.\n */\n unrunFragmentPlan(\n transaction: UpdateTransaction,\n plan: FragmentPlan | null,\n onlyElements: ReadonlySet<Element> | undefined,\n ): FragmentPlan | null {\n if (plan === null) return null;\n const boundaries = plan.boundaries.filter(\n (boundary) =>\n !transaction.fragmentBoundariesRun.has(boundary) &&\n (onlyElements === undefined ||\n [...onlyElements].some((element) => element === boundary || boundary.contains(element))),\n );\n return planBoundaries(plan.strategy, boundaries, plan.ownerKeys);\n }\n\n private confirmation(island: Element, transaction: UpdateTransaction): () => void {\n const held = this.confirmations.get(island);\n if (held?.transaction === transaction) return held.displayed;\n const displayed = this.state.display.handIsland(transaction);\n this.confirmations.set(island, { transaction, displayed });\n return displayed;\n }\n\n private currentTransaction(): UpdateTransaction | null {\n const transaction = this.state.activeUpdate;\n return this.state.navigationBindingReplay &&\n transaction !== null &&\n this.state.isCurrent(transaction)\n ? transaction\n : null;\n }\n}\n\nexport function dispatchSnapshotToIslands(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n islands: readonly Element[],\n isCurrent: () => boolean,\n displayed: () => void,\n): void {\n dispatchIslandUpdate(\n islands,\n {\n fields: data.fields,\n revision: transaction.revision.revision,\n receivedAt: transaction.receivedAt,\n locale: transaction.locale,\n displayed,\n },\n isCurrent,\n );\n}\n","/**\n * A scalar field arrived for which the page has no binding. What that means\n * depends on the value that came with it, so two codes say two things. An\n * empty string with no anchor is LP0201: the template most likely renders the\n * anchor only while the field is non-empty, and an edit has nowhere to land. A\n * value with no anchor is LP0203: the page does not show this field, which on\n * a page that renders a subset of the document is the normal case — the line\n * says where the fact is visible instead of asking for an anchor the page\n * never meant to have.\n *\n * Reported once per field name, because the cause is the markup rather than the\n * edit. `onUnfaithfulPatch` acts on the same fact per revision; both read the\n * addressability rules from `unbound-fields.ts`.\n */\n\nimport type { ElementCache } from './cache';\nimport type { RuntimeDeps } from './runtime-state';\nimport {\n createFieldAddressability,\n ownsAnyBinding,\n stripLocaleSuffix,\n SYSTEM_FIELD_NAMES,\n uncoveredDocumentPaths,\n type FieldAddressability,\n type OwnerScope,\n} from './unbound-fields';\n\ninterface OrphanDiagnosticContext {\n readonly cache: ElementCache;\n readonly warned: Set<string>;\n readonly warn: (...args: unknown[]) => void;\n}\n\n/**\n * Asked of the message's own values, not of a merged document: where the form\n * holds the id of an upload, a merge puts the upload's own fields, and those\n * are not fields of this document an anchor could show.\n */\nexport function diagnoseOrphanFields(\n deps: Pick<RuntimeDeps, 'cache' | 'warn' | 'subfieldCoverage' | 'strategies'>,\n warned: Set<string>,\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n): void {\n const { cache, strategies } = deps;\n const context: OrphanDiagnosticContext = { cache, warned, warn: deps.warn };\n if (cache.fieldCount === 0) return;\n // With scoping on, a page that renders none of this document is normal.\n if (ownerKeys !== false && !ownsAnyBinding(cache, ownerKeys)) return;\n // A field a configured strategy renders from a boundary or marker is shown.\n const isAddressable = createFieldAddressability(cache, locale, ownerKeys, strategies);\n for (const [rawName, value] of Object.entries(fields)) {\n if (SYSTEM_FIELD_NAMES.has(rawName)) continue;\n // Only scalars: an unbound relationship or block array is a template\n // decision, not the missing anchor this code is about.\n if (isBindableScalar(value)) {\n report(context, isAddressable, rawName, locale, value);\n continue;\n }\n if (!isPlainObject(value) || isAddressable(rawName) || isJoinResult(value)) continue;\n // A group with no anchor anywhere. `admission.priceFrom` is as bindable as\n // `slug` and was reported as neither, so the report names the scalar\n // instead of staying silent about the object around it. One level only:\n // deeper the shape is a rich-text tree more often than a group, and an\n // array's missing anchor stays a template decision at every depth.\n //\n // Restrained to a group the predicate above already calls unaddressable,\n // which is what keeps this in step with `onUnfaithfulPatch`: it escalates\n // on exactly these fields, and this says the same thing more precisely.\n const group = stripLocaleSuffix(rawName, locale);\n for (const [childName, childValue] of Object.entries(value)) {\n if (!isBindableScalar(childValue) || SYSTEM_FIELD_NAMES.has(childName)) continue;\n report(context, isAddressable, `${group}.${childName}`, locale, childValue);\n }\n }\n if (deps.subfieldCoverage !== 'declared') return;\n // ADR 0022: inside a group the page reaches only below the top level, each\n // uncovered path is named the same way, scalars and one level of a group.\n const uncovered = uncoveredDocumentPaths(cache, fields, locale, ownerKeys, strategies);\n for (const { path, value } of uncovered) {\n if (isBindableScalar(value)) report(context, isAddressable, path, locale, value);\n if (!isPlainObject(value) || isJoinResult(value)) continue;\n for (const [childName, childValue] of Object.entries(value)) {\n if (isBindableScalar(childValue)) {\n report(context, isAddressable, `${path}.${childName}`, locale, childValue);\n }\n }\n }\n}\n\nfunction report(\n context: OrphanDiagnosticContext,\n isAddressable: FieldAddressability,\n name: string,\n locale: string | undefined,\n value: unknown,\n): void {\n const { warned, warn } = context;\n if (warned.has(name) || isAddressable(name)) return;\n warned.add(name);\n const attribute = `data-payload-field=\"${stripLocaleSuffix(name, locale)}\"`;\n if (value === '') {\n warn(\n `[live-preview] LP0201: no <… ${attribute}> for the empty field \"${name}\"; ` +\n 'render the anchor unconditionally so edits to an empty field have somewhere to land.',\n );\n return;\n }\n warn(\n `[live-preview] LP0203: field \"${name}\" has a value and no <… ${attribute}> on this page; editing it ` +\n 'changes nothing here. Expected where the page shows part of the document: inspect().fidelity.fields ' +\n 'lists these, onUnfaithfulPatch decides whether a server render is asked for.',\n );\n}\n\nfunction isBindableScalar(value: unknown): boolean {\n const type = typeof value;\n return type === 'string' || type === 'number' || type === 'boolean' || type === 'bigint';\n}\n\n/**\n * What Payload puts in a join field: other documents and the page metadata\n * beside them (`hasNextPage`, `totalDocs`). A join is virtual, so nothing in it\n * is a field of this document an editor types into or a page anchors.\n */\nfunction isJoinResult(value: Record<string, unknown>): boolean {\n return Array.isArray(value['docs']) && typeof value['hasNextPage'] === 'boolean';\n}\n\n/** A group, as opposed to an array or a null: the one shape worth looking into. */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","/**\n * Trusted Types: every HTML sink routes through one policy, `payload-live-preview`,\n * whose `createHTML` is the identity — what reaches a sink is already sanitized\n * or escaped. Without the API, strings pass through untouched.\n */\n\n/** The subset of the Trusted Types API this module needs. */\nexport interface TrustedHtmlPolicyLike {\n createHTML(input: string): unknown;\n}\n\ninterface TrustedTypesFactoryLike {\n createPolicy(\n name: string,\n rules: { createHTML: (input: string) => string },\n ): TrustedHtmlPolicyLike;\n}\n\n/** @internal */\nexport const TRUSTED_TYPES_POLICY_NAME = 'payload-live-preview';\n\n// Held on the realm, not in this module: every package entry is its own bundle\n// with its own copy of this file, and a page's `trusted-types` directive allows\n// the name once. A second copy that asked for it again would be refused and fall\n// back to strings; instead every copy shares the one policy, and a policy set\n// through one entry reaches the others.\nconst SLOT: unique symbol = Symbol.for('payload-live-preview.trusted-types');\ninterface SharedPolicies {\n override?: TrustedHtmlPolicyLike | null | undefined;\n auto?: TrustedHtmlPolicyLike | null | undefined;\n}\ninterface Realm {\n [SLOT]?: SharedPolicies | undefined;\n}\nfunction shared(): SharedPolicies {\n const realm = globalThis as Realm;\n const existing = realm[SLOT];\n if (existing !== undefined) return existing;\n const created: SharedPolicies = {};\n realm[SLOT] = created;\n return created;\n}\n\n/**\n * Use `policy` for every sink, `null` to assign plain strings, `undefined` to\n * return to the auto-created package policy.\n */\nexport function setTrustedTypesPolicy(policy: TrustedHtmlPolicyLike | null | undefined): void {\n shared().override = policy;\n}\n\nfunction factory(): TrustedTypesFactoryLike | undefined {\n const candidate = (globalThis as { trustedTypes?: unknown }).trustedTypes;\n if (typeof candidate !== 'object' || candidate === null) return undefined;\n const create = (candidate as { createPolicy?: unknown }).createPolicy;\n return typeof create === 'function' ? (candidate as TrustedTypesFactoryLike) : undefined;\n}\n\nfunction resolvePolicy(): TrustedHtmlPolicyLike | null {\n const policies = shared();\n if (policies.override !== undefined) return policies.override;\n if (policies.auto !== undefined) return policies.auto;\n const api = factory();\n try {\n policies.auto =\n api === undefined\n ? null\n : api.createPolicy(TRUSTED_TYPES_POLICY_NAME, { createHTML: (input) => input });\n } catch {\n // The site's `trusted-types` directive does not list this name; the\n // sink assignment will surface the enforcement error.\n policies.auto = null;\n }\n return policies.auto;\n}\n\n/** `html` as a `TrustedHTML` when a policy exists, else the string. Typed `string` for `innerHTML`. @internal */\nexport function trustedHtml(html: string): string {\n const policy = resolvePolicy();\n if (policy === null) return html;\n return policy.createHTML(html) as string;\n}\n\n/** Test hook: forget the auto-created policy. */\nexport function __resetTrustedTypesForTests(): void {\n (globalThis as Realm)[SLOT] = undefined;\n}\n","/**\n * Keyed DOM morph, the engine: edits a live element toward a freshly rendered\n * one while retaining compatible, paired live nodes. Those nodes keep their\n * live properties; an incompatible or unpaired node is replaced and loses\n * them. It pairs children by key or position, synchronises attributes with the\n * state exception and keeps focus across a retained move; which subtrees it\n * never enters is the coordinator's rule, handed in as\n * `MorphOptions.boundary` and defaulting to the package's (`isMorphBoundary`\n * in islands.ts). See ADR 0008, §9 for the line between the two. A custom\n * element is such a boundary unless both of its sides carry\n * `data-payload-morph` (§10).\n */\n\nimport { isMorphBoundary } from './islands';\n\n/** Attributes the CMS controls only when the template names them (ADR 0008 §3). */\nconst STATE_ATTRIBUTES: ReadonlySet<string> = new Set(['open', 'value', 'checked', 'selected']);\n\n/** @beta */\nexport interface MorphOptions {\n /** Attributes that key child elements for pairing, tried in order; unkeyed children pair by position. */\n readonly keyAttributes: readonly string[];\n /** Called once per parent when two children share a key; the later ones pair by position. */\n readonly onDuplicateKey?: (parent: Element, key: string) => void;\n /** Elements whose attributes are synchronised but whose children are left alone (nested structural slots). */\n readonly retainChildrenOf?: (live: Element, rendered: Element) => boolean;\n /**\n * The ownership rule: a structurally compatible live/rendered pair for\n * which this returns `true` on both sides is retained whole and never\n * entered (ADR 0008 §4). The package's rule — custom elements, islands,\n * `contenteditable`, `data-payload-owned` — is the default. A supplied rule\n * replaces that default; compose it with the exported `isMorphBoundary`\n * predicate to add package-compatible boundaries.\n */\n readonly boundary?: (element: Element) => boolean;\n /**\n * Decides a live/rendered pair that are both boundaries: `true` keeps the\n * live one, after any handoff to its owner; `false` replaces it with the\n * rendered one. Without it every such pair is kept whole (ADR 0008 §4). The\n * package's coordinators hand in `retainIslandBoundary`, under which an\n * Astro island that still renders the same component takes the rendered\n * props through Astro's own handoff (ADR 0021).\n */\n readonly retainBoundary?: (live: Element, rendered: Element) => boolean;\n}\n\n/** Empty attribute values (boolean markers such as `data-payload-island`) are not keys. */\nfunction keyOf(element: Element, options: MorphOptions): string | undefined {\n for (const attribute of options.keyAttributes) {\n const value = element.getAttribute(attribute);\n if (value !== null && value.length > 0) return `${attribute}=${value}`;\n }\n return undefined;\n}\n\n/** Whether `live` can be edited toward `rendered` instead of being replaced by it, under `boundary` (the package's rule by default). @internal */\nexport function isMorphCompatible(\n live: Element,\n rendered: Element,\n boundary: (element: Element) => boolean = isMorphBoundary,\n): boolean {\n return (\n live.tagName === rendered.tagName &&\n live.namespaceURI === rendered.namespaceURI &&\n !boundary(live) &&\n !boundary(rendered)\n );\n}\n\n/**\n * Morph `live` toward `rendered`. Returns `live` when it was retained, or\n * `rendered` when the two are incompatible and the caller must replace.\n * `rendered` is consumed: its children may move into `live`.\n *\n * @beta\n */\nexport function morphElement(live: Element, rendered: Element, options: MorphOptions): Element {\n if (!sameKind(live, rendered)) return rendered;\n const boundary = options.boundary ?? isMorphBoundary;\n const liveBoundary = boundary(live);\n const renderedBoundary = boundary(rendered);\n if (liveBoundary || renderedBoundary) {\n if (!liveBoundary || !renderedBoundary) return rendered;\n return (options.retainBoundary?.(live, rendered) ?? true) ? live : rendered;\n }\n const focus = captureFocus(live);\n syncAttributes(live, rendered);\n if (options.retainChildrenOf?.(live, rendered) !== true) morphChildren(live, rendered, options);\n restoreFocus(focus);\n return live;\n}\n\n/** Match attributes, except that state-bearing ones change only when `rendered` carries them. */\nexport function syncAttributes(live: Element, rendered: Element): void {\n for (const attribute of Array.from(live.attributes)) {\n if (rendered.hasAttribute(attribute.name)) continue;\n if (STATE_ATTRIBUTES.has(attribute.name.toLowerCase())) continue;\n live.removeAttribute(attribute.name);\n }\n for (const attribute of Array.from(rendered.attributes)) {\n if (live.getAttribute(attribute.name) !== attribute.value) {\n live.setAttribute(attribute.name, attribute.value);\n }\n }\n}\n\nfunction morphChildren(live: Element, rendered: Element, options: MorphOptions): void {\n const liveKeyed = indexKeyed(live, options);\n const keyedElements = new Set<Node>(liveKeyed.values());\n const liveUnkeyed = Array.from(live.childNodes).filter((node) => !keyedElements.has(node));\n const claimed = new Set<Node>();\n const usedKeys = new Set<string>();\n const renderedNodes = Array.from(rendered.childNodes);\n let cursor: Node | null = live.firstChild;\n let unkeyedIndex = 0;\n\n for (let i = 0; i < renderedNodes.length; i += 1) {\n const next = renderedNodes[i] as Node;\n let kept: Node | null = null;\n let key = next instanceof Element ? keyOf(next, options) : undefined;\n // A repeated key on the rendered side pairs positionally like a live duplicate.\n if (key !== undefined && usedKeys.has(key)) key = undefined;\n if (key !== undefined) {\n usedKeys.add(key);\n const candidate = liveKeyed.get(key);\n if (candidate !== undefined && !claimed.has(candidate)) {\n kept = reconcile(candidate, next, options) === candidate ? candidate : null;\n if (kept === null) {\n candidate.replaceWith(next);\n claimed.add(next);\n cursor = next.nextSibling;\n continue;\n }\n }\n } else {\n while (unkeyedIndex < liveUnkeyed.length) {\n const candidate = liveUnkeyed[unkeyedIndex] as Node;\n unkeyedIndex += 1;\n if (claimed.has(candidate)) continue;\n if (sameKind(candidate, next)) {\n kept = reconcile(candidate, next, options) === candidate ? candidate : null;\n if (kept === null) {\n live.replaceChild(next, candidate);\n claimed.add(next);\n cursor = next.nextSibling;\n }\n break;\n }\n if (candidate instanceof Element) {\n // `next` is a text/comment, or an element whose kind the following\n // rendered node matches: an insertion, so the live element stays for it.\n const following = renderedNodes[i + 1];\n if (\n !(next instanceof Element) ||\n (following !== undefined && sameKind(candidate, following))\n ) {\n unkeyedIndex -= 1;\n break;\n }\n live.replaceChild(next, candidate);\n claimed.add(next);\n cursor = next.nextSibling;\n break;\n }\n if (!(next instanceof Element)) {\n // Text vs comment: replace rather than rewrite one node type's value into the other.\n live.replaceChild(next, candidate);\n claimed.add(next);\n cursor = next.nextSibling;\n break;\n }\n // A surplus live text/comment before the element `next` needs; removed below.\n }\n if (kept === null && claimed.has(next)) continue;\n }\n\n const node: Node = kept ?? next;\n claimed.add(node);\n // Whitespace-only text the template did not render is surplus. Stepping the\n // cursor over it keeps a retained element where it is: `insertBefore` on a\n // node already in the tree is a remove-and-insert, which blurs a focused input.\n while (cursor !== null && cursor !== node && !claimed.has(cursor) && isBlankText(cursor)) {\n cursor = cursor.nextSibling;\n }\n if (node !== cursor) live.insertBefore(node, cursor);\n cursor = node.nextSibling;\n }\n\n for (const child of Array.from(live.childNodes)) {\n if (!claimed.has(child)) child.remove();\n }\n}\n\n/** Retain `candidate` when it can be edited toward `next`; otherwise report `next`. */\nfunction reconcile(candidate: Node, next: Node, options: MorphOptions): Node {\n if (candidate instanceof Element && next instanceof Element) {\n return morphElement(candidate, next, options);\n }\n if (candidate.nodeValue !== next.nodeValue) candidate.nodeValue = next.nodeValue;\n return candidate;\n}\n\nfunction isBlankText(node: Node): boolean {\n return node.nodeType === Node.TEXT_NODE && (node.nodeValue ?? '').trim().length === 0;\n}\n\nfunction sameKind(a: Node, b: Node): boolean {\n if (a.nodeType !== b.nodeType) return false;\n if (a instanceof Element && b instanceof Element) {\n return a.tagName === b.tagName && a.namespaceURI === b.namespaceURI;\n }\n return true;\n}\n\n/** First element per key; later duplicates are left as they are and pair positionally. */\nfunction indexKeyed(parent: Element, options: MorphOptions): Map<string, Element> {\n const keyed = new Map<string, Element>();\n let duplicate: string | undefined;\n for (const child of Array.from(parent.children)) {\n const key = keyOf(child, options);\n if (key === undefined) continue;\n if (keyed.has(key)) {\n duplicate ??= key.slice(key.indexOf('=') + 1);\n continue;\n }\n keyed.set(key, child);\n }\n if (duplicate !== undefined) options.onDuplicateKey?.(parent, duplicate);\n return keyed;\n}\n\n/** @internal */\nexport interface FocusSnapshot {\n readonly element: HTMLElement;\n readonly selection: readonly [number | null, number | null] | null;\n}\n\n/**\n * A keyed move is a remove-and-insert, which blurs; remember what had focus.\n * The structural applier moves items itself and uses the same pair around\n * its commit, so a move it makes keeps focus the way a move the morph makes\n * does (ADR 0008 §1). @internal\n */\nexport function captureFocus(live: Element): FocusSnapshot | null {\n const active = live.ownerDocument.activeElement;\n if (!(active instanceof HTMLElement) || !live.contains(active)) return null;\n const selection =\n active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement\n ? ([active.selectionStart, active.selectionEnd] as const)\n : null;\n return { element: active, selection };\n}\n\n/** @internal */\nexport function restoreFocus(snapshot: FocusSnapshot | null): void {\n if (snapshot === null) return;\n const { element, selection } = snapshot;\n if (element.ownerDocument.activeElement === element || !element.isConnected) return;\n try {\n element.focus({ preventScroll: true });\n const [start, end] = selection ?? [null, null];\n if (start !== null && end !== null) {\n (element as HTMLInputElement).setSelectionRange(start, end);\n }\n } catch {\n // Not focusable any more; nothing to restore.\n }\n}\n","/**\n * LP0409 — what the strict sanitizer removed that the 1.x default kept.\n *\n * `sanitizerPolicy` defaults to `'strict'` since 2.0; before that it was\n * `'compat'`, which let `id` and every `data-*` through, and `name` only where\n * a per-tag list allowed it. The difference\n * only shows when a binding *writes* markup, so a project that upgrades and\n * whose rich text carries its own hooks loses them at the moment an editor\n * types — silently, and in the preview only. Measured on a real consumer: a\n * `data-partner-scroll` attribute driving a CSS selector disappeared on the\n * first write, with nothing said anywhere.\n *\n * So it is said here: once per attribute name per page, with the reason that\n * applies to that name rather than one sentence covering three different\n * decisions. This is a report, never a behaviour — the attribute stays removed.\n */\n\n/**\n * `console.warn` behind a try/catch rather than `@core/diagnostics`: `security`\n * is a leaf layer and may not import `core` (scripts/architecture-rules.ts), and\n * the shared helper's extra work — tolerating a logger that returns a thenable —\n * is for consumer-supplied loggers. This sink is fixed.\n */\nfunction warn(message: string): void {\n try {\n console.warn(message);\n } catch {\n // A diagnostic must never become a second failure.\n }\n}\n\nconst reported = new Set<string>();\n\n/** The binding prefix, restated rather than imported: this module must not pull the applier in. */\nconst BINDING_PREFIX = 'data-payload-';\n\nfunction reason(name: string): string {\n if (name.startsWith(BINDING_PREFIX)) {\n return (\n 'A binding inside CMS content is refused by design — an editor could otherwise ' +\n 'aim a write at any element on the page (docs/security.md)'\n );\n }\n if (name === 'id' || name === 'name') {\n return (\n 'CMS content that can name an element can shadow a global of that name — ' +\n 'DOM clobbering, refused by design (docs/security.md)'\n );\n }\n return (\n 'Put it on an element the template owns, or set ' +\n \"`sanitizerPolicy: 'compat'` to keep every `data-*` as 1.x did\"\n );\n}\n\n/**\n * Report one removal. Only for attributes `'compat'` would have kept: everything\n * else the sanitizer drops was refused in 1.x too and is not news to anyone.\n */\nexport function reportDroppedAttribute(name: string): void {\n if (reported.has(name)) return;\n reported.add(name);\n warn(\n `[live-preview] LP0409: the strict sanitizer removed \\`${name}\\` from written markup; ` +\n `the 1.x default (\\`sanitizerPolicy: 'compat'\\`) kept it. ${reason(name)}.`,\n );\n}\n\n/** Test seam: the report is once per page, and a test is not a page. */\nexport function resetDroppedAttributeReports(): void {\n reported.clear();\n}\n","/**\n * HTML sanitizer built on the host parser (`<template>`): allow-listed tags\n * and attributes, validated URLs, hardened external links, no `style`.\n * Needs a DOM; string-only sanitizers are historically brittle.\n */\n\nimport { warnOnce } from '@/types/dev-warning';\nimport { trustedHtml } from './trusted-types';\nimport { isSafeUrl, isExternalHttpUrl } from './url-validator';\nimport { reportDroppedAttribute } from './sanitizer-report';\n\ndeclare const __INLINE_BUILD__: boolean | undefined;\n\n/** Tags kept with their content. Others are unwrapped unless in `REMOVE_COMPLETELY`. */\nconst ALLOWED_TAGS: ReadonlySet<string> = new Set([\n 'p',\n 'br',\n 'strong',\n 'b',\n 'em',\n 'i',\n 'u',\n 's',\n 'strike',\n 'mark',\n 'small',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'ul',\n 'ol',\n 'li',\n 'dl',\n 'dt',\n 'dd',\n 'blockquote',\n 'code',\n 'pre',\n 'kbd',\n 'samp',\n 'var',\n 'a',\n 'span',\n 'div',\n 'section',\n 'article',\n 'aside',\n 'header',\n 'footer',\n 'nav',\n 'figure',\n 'figcaption',\n 'img',\n 'picture',\n 'source',\n 'audio',\n 'video',\n 'sub',\n 'sup',\n 'hr',\n 'time',\n 'abbr',\n 'cite',\n 'q',\n 'table',\n 'thead',\n 'tbody',\n 'tfoot',\n 'tr',\n 'th',\n 'td',\n 'caption',\n 'colgroup',\n 'col',\n]);\n\n/** Tags `allowFormControls` re-admits for author templates; `form` is deliberately not one. */\nconst FORM_CONTROLS: ReadonlySet<string> = new Set([\n 'input',\n 'button',\n 'textarea',\n 'select',\n 'option',\n 'label',\n]);\n\n/** Removed with their children: the content itself is the hazard. */\nconst REMOVE_COMPLETELY: ReadonlySet<string> = new Set([\n 'script',\n 'style',\n 'iframe',\n 'object',\n 'embed',\n 'link',\n 'meta',\n 'base',\n 'form',\n 'input',\n 'button',\n 'select',\n 'textarea',\n 'svg',\n 'math',\n 'template',\n 'frame',\n 'frameset',\n 'noframes',\n 'noscript',\n]);\n\nconst ATTR_GLOBAL: ReadonlySet<string> = new Set([\n 'id',\n 'class',\n 'lang',\n 'dir',\n 'title',\n 'role',\n 'tabindex',\n]);\n\nconst ATTR_ARIA_PREFIX = 'aria-';\nconst ATTR_DATA_PREFIX = 'data-';\nconst BINDING_DATA_PREFIX = 'data-payload-';\n\nconst ATTR_BY_TAG: Readonly<Record<string, ReadonlySet<string>>> = {\n a: new Set(['href', 'target', 'rel', 'download', 'hreflang', 'type']),\n img: new Set(['src', 'srcset', 'sizes', 'alt', 'width', 'height', 'loading', 'decoding']),\n picture: new Set([]),\n source: new Set(['src', 'srcset', 'sizes', 'type', 'media']),\n audio: new Set(['src', 'controls', 'autoplay', 'loop', 'muted', 'preload']),\n video: new Set([\n 'src',\n 'poster',\n 'controls',\n 'autoplay',\n 'loop',\n 'muted',\n 'preload',\n 'width',\n 'height',\n 'playsinline',\n ]),\n time: new Set(['datetime']),\n abbr: new Set(['title']),\n q: new Set(['cite']),\n blockquote: new Set(['cite']),\n table: new Set(['summary']),\n th: new Set(['colspan', 'rowspan', 'scope', 'headers', 'abbr']),\n td: new Set(['colspan', 'rowspan', 'headers']),\n col: new Set(['span']),\n colgroup: new Set(['span']),\n ol: new Set(['start', 'reversed', 'type']),\n li: new Set(['value']),\n code: new Set(['class']),\n pre: new Set(['class']),\n};\n\n// Checked however the attribute was admitted: `additionalAllowedAttributes` can re-admit the form ones.\nconst URL_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'href',\n 'src',\n 'cite',\n 'poster',\n 'action',\n 'formaction',\n]);\n\n/** Parses `sanitizeHtml` spends before it gives up on an output that will not settle. */\nconst MAX_PASSES = 6;\n\n// Numeric nodeType constants keep an injected SSR document independent of a\n// browser-global `Node` constructor.\nconst ELEMENT_NODE = 1;\nconst COMMENT_NODE = 8;\n\n/** Thrown by `sanitizeHtml()` without a `document`, or with one that cannot write what it cleaned. */\nexport class SanitizerEnvironmentError extends Error {\n override readonly name = 'SanitizerEnvironmentError';\n}\n\n/**\n * `'strict'` (default) strips `id`, `name` and `data-payload-*` and passes\n * other `data-*` only via `allowedDataAttributes`; `'compat'` keeps them.\n */\nexport type SanitizerPolicyMode = 'compat' | 'strict';\n\nexport interface SanitizeOptions {\n /** Overrides the module default set by `setSanitizerPolicy()`. */\n readonly policy?: SanitizerPolicyMode;\n /** `data-*` attributes (full names) that pass under `'strict'`; `data-payload-*` never does. */\n readonly allowedDataAttributes?: readonly string[];\n /**\n * Keep `input`, `button`, `textarea`, `select`, `option` and `label` — only\n * for markup the page author wrote, never for CMS content. `form`,\n * handlers, `style` and unsafe URLs stay dropped.\n */\n readonly allowFormControls?: boolean;\n /** Extra tags to allow. Lower-case, untrimmed. */\n readonly additionalAllowedTags?: readonly string[];\n /**\n * Extra per-tag attributes, lower-case. Cannot re-admit handlers, `style`, or —\n * under `'strict'` — `id`, `name` and `data-payload-*`; their URLs are checked.\n */\n readonly additionalAllowedAttributes?: Readonly<Record<string, readonly string[]>>;\n /**\n * The input is a page-author item template, so `'strict'` keeps the\n * applier's reconciliation attributes (`TEMPLATE_ATTRIBUTES`) and nothing\n * else — every other `data-payload-*` is still stripped, so a template can\n * never add a binding.\n */\n readonly templateMode?: boolean;\n /**\n * The DOM to parse with, for this call: an SSR document such as linkedom's\n * or jsdom's. Wins over `setSanitizerDocument()` and over the global\n * `document`, and two callers with two documents never share one.\n */\n readonly document?: SanitizerDocument;\n}\n\n/** What `templateMode` keeps under `'strict'`. */\nconst TEMPLATE_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'id',\n 'name',\n 'data-payload-key',\n 'data-payload-morph',\n 'data-payload-nested-key',\n 'data-payload-nested-template',\n]);\n\ninterface ResolvedPolicy {\n readonly allowedTags: ReadonlySet<string>;\n readonly allowFormControls: boolean;\n readonly templateMode: boolean;\n readonly mode: SanitizerPolicyMode;\n readonly allowedData: ReadonlySet<string>;\n readonly attrByTag: ReadonlyMap<string, ReadonlySet<string>>;\n}\n\nlet defaultMode: SanitizerPolicyMode = 'strict';\n\n/**\n * The default for calls without an explicit `policy`, per package entry. A\n * runtime carries its own `sanitizerPolicy` and never writes here (ADR 0002).\n */\nexport function setSanitizerPolicy(mode: SanitizerPolicyMode): void {\n defaultMode = mode;\n}\n\n/** `instancePolicy` sits between a per-call `options.policy` and the process default. */\nfunction resolvePolicy(\n options: SanitizeOptions | undefined,\n instancePolicy: SanitizerPolicyMode | undefined,\n): ResolvedPolicy {\n const mode = options?.policy ?? instancePolicy ?? defaultMode;\n if (!options) {\n const attrMap = new Map<string, ReadonlySet<string>>();\n for (const [tag, attrs] of Object.entries(ATTR_BY_TAG)) attrMap.set(tag, attrs);\n return {\n allowedTags: ALLOWED_TAGS,\n attrByTag: attrMap,\n allowFormControls: false,\n templateMode: false,\n mode,\n allowedData: new Set(),\n };\n }\n const allowed = new Set(ALLOWED_TAGS);\n options.additionalAllowedTags?.forEach((tag) => allowed.add(tag));\n if (options.allowFormControls === true) for (const tag of FORM_CONTROLS) allowed.add(tag);\n const attrMap = new Map<string, ReadonlySet<string>>();\n for (const [tag, attrs] of Object.entries(ATTR_BY_TAG)) attrMap.set(tag, attrs);\n for (const [tag, attrs] of Object.entries(options.additionalAllowedAttributes ?? {})) {\n const merged = new Set(attrMap.get(tag));\n for (const attr of attrs) merged.add(attr);\n attrMap.set(tag, merged);\n }\n return {\n allowedTags: allowed,\n attrByTag: attrMap,\n allowFormControls: options.allowFormControls === true,\n templateMode: options.templateMode === true,\n mode,\n allowedData: new Set(options.allowedDataAttributes?.map((name) => name.toLowerCase())),\n };\n}\n\n/** The `Document` surface the sanitizer needs; jsdom, linkedom and happy-dom all provide it. */\nexport interface SanitizerDocument {\n createElement: (tagName: string) => {\n innerHTML: string;\n readonly content: ParentNode;\n };\n}\n\n// Held on the realm, not in this module: every package entry is its own bundle\n// with its own copy of this file, and a document supplied through the root has\n// to reach the rich text `payload-live-preview/lexical` renders.\nconst DOCUMENT_SLOT: unique symbol = Symbol.for('payload-live-preview.sanitizer-document');\n\ninterface DocumentSlot {\n [DOCUMENT_SLOT]?: SanitizerDocument | undefined;\n}\n\n/**\n * Supply a `Document` for SSR, e.g. linkedom's `parseHTML(...).document`;\n * `null` clears it, for every entry. The fallback for a call that names no\n * document of its own.\n *\n * @deprecated Since 2.1 a call names its document: `sanitizeHtml(html, { document })`,\n * `lexicalToHtml(content, { document })`. The process-wide slot stays until 3.0\n * (ADR 0007 ledger).\n */\nexport function setSanitizerDocument(doc: SanitizerDocument | null): void {\n warnOnce(\n 'set-sanitizer-document',\n '`setSanitizerDocument()` is removed in 3.0: pass the document per call, ' +\n '`sanitizeHtml(html, { document })` or `lexicalToHtml(content, { document })` (ADR 0026).',\n );\n (globalThis as DocumentSlot)[DOCUMENT_SLOT] = doc ?? undefined;\n}\n\n/**\n * Sanitize `html`; malformed input is recovered by the parser first. The\n * result is a fixed point: sanitising it again changes nothing.\n *\n * @throws {SanitizerEnvironmentError} when no DOM is available.\n */\nexport function sanitizeHtml(html: string, options?: SanitizeOptions): string {\n return sanitizeHtmlWithPolicy(html, undefined, options);\n}\n\n/**\n * The runtime's entry: `policy` is one instance's, applied unless `options`\n * carry their own, so two clients on a page never share a policy through\n * this module. Not public — a direct caller has `options.policy`.\n */\nexport function sanitizeHtmlWithPolicy(\n html: string,\n policy: SanitizerPolicyMode | undefined,\n options?: SanitizeOptions,\n): string {\n const doc = options?.document ?? resolveDocument();\n if (!doc) throw environmentError();\n if (html === '') return '';\n\n const resolved = resolvePolicy(options, policy);\n // Unwrapping an unknown tag can leave a tree no parser produces (an `a` in an\n // `a`), and the consumer's `innerHTML` rebuilds it as the parser would. So\n // what is written is parsed and sanitised again until a pass changes nothing\n // (ADR 0016, 2026-10-02): the string returned is the one the consumer gets.\n let markup = html;\n for (let pass = 0; pass < MAX_PASSES; pass += 1) {\n const template = doc.createElement('template');\n // The sanitizer's own parse is a sink too: under Trusted Types it needs the policy.\n template.innerHTML = trustedHtml(markup);\n // Read once, and never write the template back: linkedom's `content` is a\n // copy of the template's children, so the template still held the parse\n // and the input came back unsanitised (2.2.1).\n const fragment = template.content;\n sanitizeFragment(fragment, resolved);\n const written = serialize(fragment);\n if (written === markup) return written;\n markup = written;\n }\n warnOnce(\n 'sanitizer-unsettled',\n `sanitizeHtml: the output did not settle after ${String(MAX_PASSES)} passes, so it returned an empty string (ADR 0016).`,\n );\n return '';\n}\n\n// Read the define at each branch rather than through a helper: a bundler\n// folds the substituted literal in place, but will not inline a call, and the\n// SSR-only class and override must not reach the browser runtime.\nfunction environmentError(): Error {\n if (typeof __INLINE_BUILD__ !== 'undefined' && __INLINE_BUILD__) {\n return new Error('sanitizeHtml needs a DOM');\n }\n return new SanitizerEnvironmentError(\n 'sanitizeHtml needs a DOM; pass one per call during SSR: { document } (linkedom, jsdom).',\n );\n}\n\n/**\n * Writes the cleaned nodes themselves, through an element of their own\n * document, where a browser keeps them inert. No such element, or one that does\n * not end up holding them, would write something else: refused, not returned.\n */\nfunction serialize(fragment: ParentNode): string {\n const writer = fragment.ownerDocument?.createElement('div');\n if (writer === undefined) throw environmentError();\n const first = fragment.firstChild;\n writer.append(fragment);\n if (writer.firstChild !== first) throw environmentError();\n return writer.innerHTML;\n}\n\nfunction resolveDocument(): SanitizerDocument | undefined {\n if (typeof __INLINE_BUILD__ === 'undefined' || !__INLINE_BUILD__) {\n const override = (globalThis as DocumentSlot)[DOCUMENT_SLOT];\n if (override) return override;\n }\n if (typeof document === 'undefined') return undefined;\n return document;\n}\n\n/** Whether a DOM is available — the global or an injected one — for callers that treat sanitizing as optional. */\nexport function hasSanitizerDocument(): boolean {\n return resolveDocument() !== undefined;\n}\n\nfunction sanitizeFragment(node: ParentNode, policy: ResolvedPolicy): void {\n // Snapshot: children are mutated during the walk.\n for (const child of Array.from(node.childNodes)) {\n if (child.nodeType === ELEMENT_NODE) {\n sanitizeElement(child as Element, policy);\n } else if (child.nodeType === COMMENT_NODE) {\n child.remove();\n }\n }\n}\n\nfunction sanitizeElement(element: Element, policy: ResolvedPolicy): void {\n const tag = element.tagName.toLowerCase();\n\n if (REMOVE_COMPLETELY.has(tag) && !(policy.allowFormControls && FORM_CONTROLS.has(tag))) {\n element.remove();\n return;\n }\n\n if (!policy.allowedTags.has(tag)) {\n sanitizeFragment(element, policy);\n element.replaceWith(...element.childNodes);\n return;\n }\n\n sanitizeAttributes(element, tag, policy);\n if (tag === 'a') hardenAnchor(element);\n sanitizeFragment(element, policy);\n}\n\nfunction sanitizeAttributes(element: Element, tag: string, policy: ResolvedPolicy): void {\n const tagAttrs = policy.attrByTag.get(tag);\n\n for (const attr of Array.from(element.attributes)) {\n const name = attr.name.toLowerCase();\n if (name.startsWith('on') || name === 'style') {\n element.removeAttribute(attr.name);\n continue;\n }\n // A parsed element's `is` value is immutable and the serialiser writes it\n // back even after the attribute is gone, so removing it would hand the\n // re-parse the page's customised built-in by name. Emptied instead: an\n // empty `is` names nothing (docs/security.md §5c).\n if (name === 'is') {\n element.setAttribute('is', '');\n continue;\n }\n if (policy.mode === 'strict') {\n if (policy.templateMode && TEMPLATE_ATTRIBUTES.has(name)) continue;\n // DOM clobbering and binding injection (docs/security.md §5c). Checked\n // before the allow-list so an extension cannot re-admit them.\n if (name === 'id' || name === 'name' || name.startsWith(BINDING_DATA_PREFIX)) {\n element.removeAttribute(attr.name);\n // `compat` kept `name` only where a per-tag list allowed it, so only\n // there did the upgrade change anything to report.\n if (name !== 'name' || tagAttrs?.has(name) === true) reportDroppedAttribute(name);\n continue;\n }\n if (name.startsWith(ATTR_DATA_PREFIX)) {\n if (!policy.allowedData.has(name)) {\n element.removeAttribute(attr.name);\n reportDroppedAttribute(name);\n }\n continue;\n }\n if (ATTR_GLOBAL.has(name) || name.startsWith(ATTR_ARIA_PREFIX)) continue;\n } else if (\n ATTR_GLOBAL.has(name) ||\n name.startsWith(ATTR_ARIA_PREFIX) ||\n name.startsWith(ATTR_DATA_PREFIX)\n ) {\n continue;\n }\n if (tagAttrs?.has(name)) {\n if (URL_ATTRIBUTES.has(name) && !isSafeUrl(attr.value)) {\n element.removeAttribute(attr.name);\n } else if (name === 'srcset' && !isSafeSrcset(attr.value)) {\n element.removeAttribute(attr.name);\n } else if (name === 'ping' && !attr.value.trim().split(/\\s+/u).every(isSafeUrl)) {\n // `ping` is a list of URLs; one unsafe target refuses the attribute.\n element.removeAttribute(attr.name);\n }\n continue;\n }\n element.removeAttribute(attr.name);\n }\n}\n\n/** Every `srcset` candidate must pass; partial rewriting would silently change what renders. */\nfunction isSafeSrcset(value: string): boolean {\n for (const candidate of value.split(',')) {\n const trimmed = candidate.trim();\n if (trimmed.length === 0) continue;\n // The URL ends at the first whitespace; what follows is the descriptor. The\n // candidate as a whole must pass too: a scheme can be spelled across that gap.\n const [url = trimmed] = trimmed.split(/\\s/, 1);\n if (!isSafeUrl(url) || !isSafeUrl(trimmed)) return false;\n }\n return true;\n}\n\nfunction hardenAnchor(anchor: Element): void {\n const href = anchor.getAttribute('href');\n if (href === null || !isExternalHttpUrl(href)) return;\n anchor.setAttribute('rel', 'noopener noreferrer');\n if (!anchor.hasAttribute('target')) anchor.setAttribute('target', '_blank');\n}\n\n/** The built-in allow-lists, for documentation and tests. */\nexport const SANITIZER_POLICY = Object.freeze({\n allowedTags: ALLOWED_TAGS,\n removeCompletely: REMOVE_COMPLETELY,\n globalAttributes: ATTR_GLOBAL,\n attributesByTag: ATTR_BY_TAG,\n urlAttributes: URL_ATTRIBUTES,\n});\n","/**\n * One development warning per process. The set of issued keys lives on\n * `globalThis` so two package copies in one process still warn once.\n */\n\nconst WARNED_KEY = '__payloadLivePreviewDeprecationsWarned';\n\n/** `true` outside a production build; `false` when `NODE_ENV` is production or unknown. */\nexport function isDevelopmentProcess(): boolean {\n try {\n const env = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process\n ?.env;\n if (env === undefined) return false;\n return env['NODE_ENV'] !== 'production';\n } catch {\n return false;\n }\n}\n\n/** Warn once per process for `key`, outside production only. */\nexport function warnOnce(key: string, message: string): void {\n if (!isDevelopmentProcess()) return;\n const holder = globalThis as unknown as Record<string, Set<string> | undefined>;\n const warned = (holder[WARNED_KEY] ??= new Set<string>());\n if (warned.has(key)) return;\n warned.add(key);\n try {\n console.warn(`[payload-live-preview] ${message}`);\n } catch {\n // A console that throws must not break a request.\n }\n}\n\n/**\n * The deprecated options the adapters and the inline generator both accept;\n * an adapter hands them on to the generator, and the shared keys keep that to\n * one warning each (ADR 0026).\n */\nexport function warnDeprecatedOptions(options: {\n readonly defaults?: string | undefined;\n readonly onUnboundChange?: string | undefined;\n}): void {\n if (options.defaults === 'v1') {\n warnOnce(\n 'defaults-v1',\n \"`defaults: 'v1'` is removed in 3.0: `pll migrate` writes the 1.x rows it stands for \" +\n 'into your options, where they keep working (ADR 0026).',\n );\n }\n if (options.onUnboundChange !== undefined) {\n warnOnce(\n 'on-unbound-change',\n \"`onUnboundChange` is removed in 3.0: name it `onUnfaithfulPatch`, where 'route' is \" +\n \"'escalate'; `pll migrate` renames it (ADR 0026).\",\n );\n }\n}\n\n/** Test hook: forget every warning issued so far. */\nexport function resetDevWarnings(): void {\n const holder = globalThis as unknown as Record<string, Set<string> | undefined>;\n holder[WARNED_KEY] = undefined;\n}\n","/** HTML and CSS escaping primitives (OWASP XSS Prevention Cheat Sheet). DOM-free. */\n\nconst HTML_ESCAPES: Readonly<Record<string, string>> = Object.freeze({\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n '/': '/',\n '`': '`',\n '=': '=',\n});\n\nconst HTML_ESCAPE_PATTERN = /[&<>\"'/`=]/g;\n\n/** Escape `text` for an element body or a *quoted* attribute value; strings only, and unquoted attributes are not covered. */\nexport function escapeHtml(text: string): string {\n // The character class and the map are coupled: every match is a key.\n // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style\n return text.replace(HTML_ESCAPE_PATTERN, (char) => HTML_ESCAPES[char] as string);\n}\n\n/** Escape a value for a CSS `url(...)` literal; this stops the break-out, not the scheme, so pair it with `isSafeUrl()`. */\nexport function escapeCssUrl(value: string): string {\n return value.replace(/['\"()\\\\]/g, '\\\\$&');\n}\n\nconst ATTR_ESCAPES: Readonly<Record<string, string>> = Object.freeze({\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n});\n\nconst ATTR_ESCAPE_PATTERN = /[&<>\"']/g;\n\n/** Escape a value for a *quoted* HTML attribute, leaving URL characters intact; it validates no scheme, so run `isSafeUrl()` on `href`/`src` first. @internal */\nexport function escapeHtmlAttribute(value: string): string {\n // The character class and the map are coupled: every match is a key.\n // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style\n return value.replace(ATTR_ESCAPE_PATTERN, (char) => ATTR_ESCAPES[char] as string);\n}\n\n/** `escapeHtml()` then newlines to `<br>`; the order is what makes it safe. */\nexport function escapeAndLinebreak(text: string): string {\n return escapeHtml(text).replace(/\\r\\n|\\r|\\n/g, '<br>');\n}\n","/**\n * One array item out of one template: the interpolation, and the attributes the\n * template cannot know about.\n *\n * A replacement value is data, not template syntax: one `replace()` per key\n * would re-interpret `{{index}}` text that an earlier value introduced, and\n * would apply `String.replace`'s `$` semantics to CMS content.\n */\n\nimport { escapeHtml } from '@security/escape';\nimport { isWritableAttribute } from './attribute-binding';\n\nconst PLACEHOLDER_PATTERN = /\\{\\{([\\s\\S]*?)\\}\\}/g;\n\n/** The runtime's own annotations; a rebuilt item gets its own, never a copy. */\nconst BINDING_ATTRIBUTE_PREFIX = 'data-payload-';\n\n/** An attribute name and its value, as they travel from an old item to a new one. */\nexport type InheritedAttribute = readonly [name: string, value: string];\n\nfunction hasOwn(record: object, key: PropertyKey): boolean {\n return Object.prototype.hasOwnProperty.call(record, key);\n}\n\n/**\n * Every key any item carries. A placeholder naming one of these is a field of\n * this array, so a row that happens to lack it renders as nothing; a\n * placeholder no row can fill is a typo in the template and stays visible.\n */\nexport function collectTemplateKeys(items: readonly unknown[]): ReadonlySet<string> {\n const keys = new Set<string>();\n for (const item of items) {\n if (typeof item !== 'object' || item === null) continue;\n for (const key of Object.keys(item)) keys.add(key);\n }\n return keys;\n}\n\nexport function interpolateArrayTemplate(\n template: string,\n item: unknown,\n index: number,\n stringify: (value: unknown) => string,\n knownKeys?: ReadonlySet<string>,\n): string {\n const record = typeof item === 'object' && item !== null ? item : null;\n\n return template.replace(PLACEHOLDER_PATTERN, (placeholder, key: string) => {\n // Preserve the established object-field precedence when an object itself\n // has an `index` or `value` property. Otherwise these are reserved tokens.\n if (record !== null && hasOwn(record, key)) {\n return escapeHtml(stringify(Reflect.get(record, key)));\n }\n if (record === null && key === 'value') return escapeHtml(stringify(item));\n if (key === 'index') return String(index);\n // A field other rows carry: this one simply has none. Writing the\n // placeholder would print template syntax on the page, which is what an\n // editor sees the moment a row is added and not every field is filled in.\n if (record !== null && knownKeys?.has(key) === true) return '';\n return placeholder;\n });\n}\n\n/**\n * What the items already in `container` all carry, and an item rebuilt from the\n * template therefore has to carry too.\n *\n * A framework's scoped styles hang on a marker its compiler writes into the\n * markup — Astro's `data-astro-cid-…`, Vue's `data-v-…`, Svelte's class — and\n * the author's `data-payload-array-template` has none of it. The rebuilt list\n * then renders unstyled next to the one the server sent, while the write itself\n * succeeds, so nothing in the runtime can notice. Naming no framework is the\n * point: what identifies these attributes is that every item of the list has\n * them with the same value, which per-row state by definition does not.\n */\nexport function sharedItemAttributes(container: Element): readonly InheritedAttribute[] {\n const items = container.children;\n const first = items[0];\n if (first === undefined) return [];\n const shared: InheritedAttribute[] = [];\n for (const { name, value } of Array.from(first.attributes)) {\n if (!isWritableAttribute(name) || name.startsWith(BINDING_ATTRIBUTE_PREFIX)) continue;\n let everyItem = true;\n for (let index = 1; index < items.length && everyItem; index += 1) {\n everyItem = items[index]?.getAttribute(name) === value;\n }\n if (everyItem) shared.push([name, value]);\n }\n return shared;\n}\n\n/** Give a rebuilt item what its predecessors shared; the template's own value wins. */\nexport function inheritItemAttributes(item: Element, shared: readonly InheritedAttribute[]): void {\n for (const [name, value] of shared) {\n if (!item.hasAttribute(name)) item.setAttribute(name, value);\n }\n}\n","/** Value coercion shared by the field renderers. */\n\n/** Display string for any value: primitives as-is, objects as JSON, `null`/`undefined` as `''`. */\nexport function safeStringify(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {\n return String(value);\n }\n try {\n return JSON.stringify(value);\n } catch {\n return '';\n }\n}\n\n/** The three values every renderer treats as \"clear\" (docs/renderers.md, value semantics). */\nexport function isEmptyValue(value: unknown): value is null | undefined | '' {\n return value === null || value === undefined || value === '';\n}\n","/**\n * LRU discipline for a module-scoped lookup `Map` (ADR 0003 §3). Functions\n * over the caller's own `Map` rather than a wrapper class: the inline bundle\n * mangles function names but not property names, so a class would pay for\n * every `this.entries` in full. A `Map` iterates in insertion order, which a\n * touch on every hit turns into recency order. Values are never `undefined`,\n * and a write follows a miss — a key already present keeps its position.\n */\n\n/** Read and touch: a hit becomes the newest entry. */\nexport function lruGet<K, V>(map: Map<K, V>, key: K): V | undefined {\n const value = map.get(key);\n if (value !== undefined) {\n map.delete(key);\n map.set(key, value);\n }\n return value;\n}\n\n/** Write as the newest entry, dropping the oldest ones past `limit`; returns `value`. */\nexport function lruSet<K, V>(map: Map<K, V>, key: K, value: V, limit: number): V {\n map.set(key, value);\n lruTrim(map, limit);\n return value;\n}\n\n/** Drop the oldest entries until `limit` holds. */\nexport function lruTrim<K>(map: Map<K, unknown>, limit: number): void {\n for (const oldest of map.keys()) {\n if (map.size <= limit) break;\n map.delete(oldest);\n }\n}\n","/**\n * Sanitizer options for item templates (`data-payload-array-template`,\n * nested templates). A template is the page author's markup and every\n * interpolated value is escaped to text before the sanitizer runs, so it may\n * carry form controls and custom elements the rich-text policy refuses.\n * Event handlers, `style` and unsafe URLs are still stripped.\n *\n * Some entries below are already admitted by the sanitizer through another\n * route — `video` and `audio` by the tag allow-list, `select` by\n * `allowFormControls`, `name` by `templateMode`, and `controls`, `muted`,\n * `loop`, `poster` and `src` by the per-tag attribute map. They are kept\n * because this list states what a template may contain, and an allow-list\n * that depends on a second list staying unchanged is the more fragile of the\n * two arrangements. Mutating those entries changes nothing observable, so\n * they survive mutation testing by construction; the behaviour they describe\n * is pinned in `tests/unit/core/template-sanitize.test.ts` instead.\n */\n\nimport type { SanitizeOptions } from '@security/sanitizer';\nimport { lruGet, lruSet } from './lru';\n\nconst TEMPLATE_EXTRA_TAGS: readonly string[] = [\n 'input',\n 'textarea',\n 'select',\n 'option',\n 'button',\n 'label',\n 'details',\n 'summary',\n 'dialog',\n 'video',\n 'audio',\n 'progress',\n 'meter',\n];\n\nconst TEMPLATE_EXTRA_ATTRIBUTES: readonly string[] = [\n 'type',\n 'name',\n 'placeholder',\n 'open',\n 'disabled',\n 'readonly',\n 'required',\n 'checked',\n 'selected',\n 'value',\n 'min',\n 'max',\n 'step',\n 'rows',\n 'cols',\n 'for',\n 'controls',\n 'muted',\n 'loop',\n 'poster',\n 'src',\n];\n\nconst CUSTOM_TAG_PATTERN = /<([a-z][a-z0-9]*(?:-[a-z0-9]+)+)\\b/gi;\n\n// 64 like the intl cache: more than a page declares, and a nested template is\n// interpolated with its parent's, so an outer value or `{{index}}` that lands\n// in it mints a key per item and per keystroke (ADR 0003 §3).\nexport const TEMPLATE_CACHE_LIMIT = 64;\nconst optionsByTemplate = new Map<string, SanitizeOptions>();\n\n/** Options for one template; memoised per template string. */\nexport function templateSanitizeOptions(template: string): SanitizeOptions {\n const cached = lruGet(optionsByTemplate, template);\n if (cached !== undefined) return cached;\n const tags = new Set(TEMPLATE_EXTRA_TAGS);\n for (const match of template.matchAll(CUSTOM_TAG_PATTERN)) {\n const tag = match[1]?.toLowerCase();\n if (tag !== undefined) tags.add(tag);\n }\n const attributes: Record<string, readonly string[]> = {};\n for (const tag of tags) attributes[tag] = TEMPLATE_EXTRA_ATTRIBUTES;\n const options: SanitizeOptions = {\n additionalAllowedTags: [...tags],\n additionalAllowedAttributes: attributes,\n allowFormControls: true,\n templateMode: true,\n };\n return lruSet(optionsByTemplate, template, options, TEMPLATE_CACHE_LIMIT);\n}\n","/**\n * Applies an `ArrayPatch[]` diff to a container as keyed DOM operations\n * instead of rebuilding the list, so consumer state on surviving children is\n * kept. Items are paired by `data-payload-key` (the item `id`); items without\n * one pair by position. Nested arrays reconcile recursively through\n * `data-payload-nested-key` slots. See ADR 0008.\n */\n\nimport { sanitizeHtmlWithPolicy, type SanitizerPolicyMode } from '@security/sanitizer';\nimport { trustedHtml } from '@security/trusted-types';\nimport {\n collectTemplateKeys,\n inheritItemAttributes,\n interpolateArrayTemplate,\n sharedItemAttributes,\n type InheritedAttribute,\n} from './array-template';\nimport { safeStringify } from '@field-types/utils';\nimport { diffArray, type ArrayPatch } from '@schema/diff';\nimport { isMorphBoundary, retainIslandBoundary } from './islands';\nimport { captureFocus, restoreFocus, morphElement } from './morph';\nimport { templateSanitizeOptions } from './template-sanitize';\n\n/** @internal */\nexport const KEY_ATTRIBUTE = 'data-payload-key';\nconst NESTED_KEY_ATTRIBUTE = 'data-payload-nested-key';\nconst NESTED_TEMPLATE_ATTRIBUTE = 'data-payload-nested-template';\n\n/** Last value seen per item key, per container; owned by the caller so instances never share it. @internal */\nexport type StructuralStore = WeakMap<Element, Map<string, unknown>>;\n\n/** @internal */\nexport function createStructuralStore(): StructuralStore {\n return new WeakMap<Element, Map<string, unknown>>();\n}\n\n/** @internal */\nexport interface StructuralApplyOptions {\n readonly template: string;\n readonly container: Element;\n readonly patches: readonly ArrayPatch[];\n /** The full new array; inserts and replaces render by index from it. */\n readonly nextItems: readonly unknown[];\n /** Pass the same store across renders so nested arrays diff incrementally. */\n readonly store: StructuralStore;\n /** Re-render existing items even when unchanged. */\n readonly forceRender?: boolean;\n /** The instance's policy for item markup; absent, the process default applies. */\n readonly sanitizerPolicy?: SanitizerPolicyMode | undefined;\n /** Edit a changed item in place instead of replacing it. Default `true`. */\n readonly morph?: boolean;\n /** Reported once per container when two items share a key (`LP0405`). */\n readonly onDuplicateKey?: (container: Element, key: string) => void;\n}\n\n/**\n * Returns `true` for a DOM mutation, `false` for an already-current tree, and\n * `null` when an item's markup has no sanitized element root — preflighted\n * before any mutation, so the previous DOM and memory stay intact.\n * @internal\n */\nexport function applyStructuralPatches(options: StructuralApplyOptions): boolean | null {\n const plan = prepareStructuralPlan(options.container, options.patches, options);\n if (plan === null) return null;\n return commitStructuralPlan(plan, options.store, {\n morph: options.morph ?? true,\n onDuplicateKey: options.onDuplicateKey,\n });\n}\n\n// Plan records are tuples: many are created per recursive render, and named\n// keys would repeat in the inline bundle.\ntype StructuralPlan = readonly [\n container: Element,\n entries: readonly ReconciliationEntry[],\n nextItems: readonly unknown[],\n];\ntype ReconciliationEntry = readonly [\n index: number,\n live: Element | null,\n rendered: Element | undefined,\n nestedSlots: readonly NestedSlotPlan[],\n /** A `replace` patch: a different item, never morphed toward. */\n replace: boolean,\n];\ntype NestedSlotPlan = readonly [\n live: Element | null,\n rendered: Element,\n children: StructuralPlan | undefined,\n];\n\n// One per container, not per item, so — unlike the tuples above — named keys\n// cost the inline bundle nothing per render.\ntype RenderEnv = Pick<\n StructuralApplyOptions,\n 'template' | 'nextItems' | 'forceRender' | 'store' | 'sanitizerPolicy'\n>;\n\ninterface CommitOptions {\n readonly morph: boolean;\n readonly onDuplicateKey: ((container: Element, key: string) => void) | undefined;\n}\n\n/** A rendered slot that still carries a nested template keeps its children for its own plan. */\nfunction isManagedNestedSlot(_live: Element, rendered: Element): boolean {\n return (\n rendered.hasAttribute(NESTED_KEY_ATTRIBUTE) && rendered.hasAttribute(NESTED_TEMPLATE_ATTRIBUTE)\n );\n}\n\n/** Materialise the whole recursive replacement tree before touching live DOM. */\nfunction prepareStructuralPlan(\n container: Element,\n patches: readonly ArrayPatch[],\n env: RenderEnv,\n): StructuralPlan | null {\n const entries = prepareReconciliation(container, createPatchPlan(patches), env);\n return entries === null ? null : [container, entries, env.nextItems];\n}\n\nfunction commitStructuralPlan(\n plan: StructuralPlan,\n store: StructuralStore,\n options: CommitOptions,\n): boolean {\n const [container, entries, nextItems] = plan;\n const claimed = new Set<Element>();\n let mutated = false;\n // Placing a retained item is a remove-and-insert, which blurs whatever the\n // visitor had focused inside it; the morph does the same for a move it\n // makes and restores afterwards, so the commit does too.\n const focus = captureFocus(container);\n for (const [index, live, rendered, nestedSlots, replace] of entries) {\n let node = live;\n if (rendered !== undefined) {\n // Morph a compatible live item in place; otherwise transplant its live\n // nested slots into the rendered item and swap.\n const retained =\n options.morph && !replace && live !== null\n ? morphElement(live, rendered, {\n keyAttributes: [KEY_ATTRIBUTE, NESTED_KEY_ATTRIBUTE],\n boundary: isMorphBoundary,\n retainBoundary: retainIslandBoundary,\n retainChildrenOf: isManagedNestedSlot,\n ...(options.onDuplicateKey !== undefined\n ? { onDuplicateKey: options.onDuplicateKey }\n : {}),\n }) === live\n : false;\n if (!retained) {\n for (const [liveSlot, renderedSlot] of nestedSlots) {\n if (liveSlot === null) continue;\n synchronizeAttributes(liveSlot, renderedSlot);\n renderedSlot.replaceWith(liveSlot);\n }\n }\n for (const [, , children] of nestedSlots) {\n if (children !== undefined) commitStructuralPlan(children, store, options);\n }\n if (retained) {\n mutated = true;\n } else {\n if (live !== null) {\n live.replaceWith(rendered);\n mutated = true;\n }\n node = rendered;\n }\n }\n if (node === null) continue;\n const before = container.children[index] ?? null;\n if (node !== before) {\n container.insertBefore(node, before);\n mutated = true;\n }\n claimed.add(node);\n }\n // `nextItems` is the source of truth; this also drops SSR children the first value did not carry.\n for (const child of Array.from(container.children)) {\n if (claimed.has(child)) continue;\n child.remove();\n mutated = true;\n }\n restoreFocus(focus);\n const memory = getMemory(container, store);\n memory.clear();\n for (const value of nextItems) rememberItem(memory, value);\n return mutated;\n}\n\n/**\n * Pair every final item with a live child (by key, else by position) and\n * render what needs rendering. Patch indices describe `next`, live indices\n * move during reconciliation, so keyed nodes are resolved from the DOM first.\n */\nfunction prepareReconciliation(\n container: Element,\n plan: PatchPlan,\n env: RenderEnv,\n): readonly ReconciliationEntry[] | null {\n const { template, nextItems, forceRender = false, store, sanitizerPolicy } = env;\n const memory = store.get(container);\n // Read before anything is rendered: what the current items share is what the\n // template cannot say, and an inserted item has no predecessor of its own.\n const shared = sharedItemAttributes(container);\n const templateKeys = collectTemplateKeys(nextItems);\n const initialChildren = Array.from(container.children);\n const keyedChildren = indexByAttribute(initialChildren, KEY_ATTRIBUTE);\n const reserved = new Set<Element>();\n const entries: ReconciliationEntry[] = [];\n for (let index = 0; index < nextItems.length; index += 1) {\n const value = nextItems[index];\n const key = readKey(value);\n let live =\n key === undefined\n ? (initialChildren[index] ?? null)\n : (takeIndexedElement(keyedChildren, key) ?? null);\n if (live !== null && reserved.has(live)) live = null;\n if (live !== null) reserved.add(live);\n const replace = plan.replaces.has(index);\n const needsRender = forceRender || plan.renders.has(index) || live === null;\n const rendered = needsRender\n ? renderItem(\n container.ownerDocument,\n template,\n value,\n index,\n sanitizerPolicy,\n shared,\n templateKeys,\n )\n : undefined;\n if (rendered === null) return null;\n const nestedSlots =\n rendered === undefined\n ? []\n : prepareNestedSlots(\n replace ? null : live,\n rendered,\n value,\n key === undefined ? undefined : memory?.get(key),\n env,\n );\n if (nestedSlots === null) return null;\n entries.push([index, live, rendered, nestedSlots, replace]);\n }\n return entries;\n}\n\ninterface PatchPlan {\n readonly renders: ReadonlySet<number>;\n readonly replaces: ReadonlySet<number>;\n}\n\nfunction createPatchPlan(patches: readonly ArrayPatch[]): PatchPlan {\n const renders = new Set<number>();\n const replaces = new Set<number>();\n for (const patch of patches) {\n if (patch.kind === 'insert' || patch.kind === 'update') renders.add(patch.index);\n else if (patch.kind === 'replace') {\n renders.add(patch.index);\n replaces.add(patch.index);\n }\n }\n return { renders, replaces };\n}\n\n/** Plan each direct nested slot; a failure at any depth aborts before commit. */\nfunction prepareNestedSlots(\n oldItem: Element | null,\n newItem: Element,\n nextValue: unknown,\n prevValue: unknown,\n env: RenderEnv,\n): readonly NestedSlotPlan[] | null {\n const oldSlots = oldItem === null ? [] : findDirectNestedSlots(oldItem);\n const oldSlotsByKey = indexByAttribute(oldSlots, NESTED_KEY_ATTRIBUTE);\n const plans: NestedSlotPlan[] = [];\n for (const newSlot of findDirectNestedSlots(newItem)) {\n const key = newSlot.getAttribute(NESTED_KEY_ATTRIBUTE);\n if (key === null) continue;\n const oldSlot = takeIndexedElement(oldSlotsByKey, key) ?? null;\n const nextTemplate = newSlot.getAttribute(NESTED_TEMPLATE_ATTRIBUTE);\n // Without a nested template the slot's rendered static content is authoritative.\n const liveSlot = nextTemplate ? oldSlot : null;\n const previousTemplate = liveSlot?.getAttribute(NESTED_TEMPLATE_ATTRIBUTE) ?? null;\n let children: StructuralPlan | undefined;\n if (nextTemplate) {\n const nextNested = readNestedArray(nextValue, key);\n if (nextNested !== undefined || liveSlot !== null) {\n const resolvedNext = nextNested ?? [];\n const prevNested = liveSlot === null ? [] : (readNestedArray(prevValue, key) ?? []);\n const patches = diffArray(prevNested, resolvedNext);\n const templateChanged = liveSlot !== null && previousTemplate !== nextTemplate;\n if (patches.length > 0 || templateChanged) {\n children =\n prepareStructuralPlan(liveSlot ?? newSlot, patches, {\n template: nextTemplate,\n nextItems: resolvedNext,\n forceRender: templateChanged,\n store: env.store,\n sanitizerPolicy: env.sanitizerPolicy,\n }) ?? undefined;\n if (children === undefined) return null;\n }\n }\n }\n plans.push([liveSlot, newSlot, children]);\n }\n return plans;\n}\n\n/** Only the outermost nested slots: a transplanted slot owns the recursion below it. */\nfunction findDirectNestedSlots(item: Element): readonly Element[] {\n return Array.from(item.querySelectorAll(`[${NESTED_KEY_ATTRIBUTE}]`)).filter((slot) => {\n let ancestor = slot.parentElement;\n while (ancestor !== null && ancestor !== item) {\n if (ancestor.hasAttribute(NESTED_KEY_ATTRIBUTE)) return false;\n ancestor = ancestor.parentElement;\n }\n return ancestor === item;\n });\n}\n\nfunction synchronizeAttributes(target: Element, source: Element): void {\n for (const attribute of Array.from(target.attributes)) {\n if (!source.hasAttribute(attribute.name)) target.removeAttribute(attribute.name);\n }\n for (const attribute of Array.from(source.attributes)) {\n if (target.getAttribute(attribute.name) !== attribute.value) {\n target.setAttribute(attribute.name, attribute.value);\n }\n }\n}\n\nfunction readNestedArray(value: unknown, key: string): readonly unknown[] | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const nested = (value as Record<string, unknown>)[key];\n return Array.isArray(nested) ? (nested as readonly unknown[]) : undefined;\n}\n\nfunction getMemory(container: Element, store: StructuralStore): Map<string, unknown> {\n let map = store.get(container);\n if (!map) {\n map = new Map();\n store.set(container, map);\n }\n return map;\n}\n\nfunction rememberItem(memory: Map<string, unknown>, value: unknown): void {\n const key = readKey(value);\n if (key !== undefined) memory.set(key, value);\n}\n\nfunction readKey(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const id = (value as Record<string, unknown>)['id'];\n return typeof id === 'string' || typeof id === 'number' ? String(id) : undefined;\n}\n\nfunction indexByAttribute(elements: readonly Element[], attribute: string): Map<string, Element[]> {\n const indexed = new Map<string, Element[]>();\n // Reverse order so pop() yields duplicates in DOM order.\n for (let index = elements.length - 1; index >= 0; index -= 1) {\n const element = elements[index];\n if (element === undefined) continue;\n const key = element.getAttribute(attribute);\n if (key === null) continue;\n const bucket = indexed.get(key);\n if (bucket === undefined) indexed.set(key, [element]);\n else bucket.push(element);\n }\n return indexed;\n}\n\nfunction takeIndexedElement(indexed: Map<string, Element[]>, key: string): Element | undefined {\n return indexed.get(key)?.pop();\n}\n\n/** Render one item; its `id` is stamped as `data-payload-key` so later diffs find it. */\nfunction renderItem(\n ownerDocument: Document,\n template: string,\n value: unknown,\n index: number,\n policy: SanitizerPolicyMode | undefined,\n shared: readonly InheritedAttribute[],\n knownKeys: ReadonlySet<string>,\n): Element | null {\n const filled = interpolateArrayTemplate(template, value, index, safeStringify, knownKeys);\n const safe = sanitizeHtmlWithPolicy(filled, policy, templateSanitizeOptions(template));\n const host = ownerDocument.createElement('template');\n host.innerHTML = trustedHtml(safe);\n const first = host.content.firstElementChild;\n if (!first) return null;\n // Before the morph, which strips from the live item every attribute the\n // rendered one lacks: the marker has to be on this side to survive.\n inheritItemAttributes(first, shared);\n const key = readKey(value);\n if (key !== undefined) first.setAttribute(KEY_ATTRIBUTE, key);\n return first;\n}\n","/**\n * The warnings about a page's strategies, kept apart from the runner that\n * usually issues them: the lean profile has no runner (see ./profile) and still\n * owes a page the first two, because they describe the markup, not the strategy\n * machinery. LP0808 says the configuration names no strategy at all, and LP0809\n * that a fragment's Astro island cannot start on this page.\n */\n\nimport type { RuntimeDeps, RuntimeState } from './runtime-state';\nimport type { CachedElement } from './types';\n\n/** LP0806, once: a fragment boundary with no handler is patched instead. */\nexport function warnFragmentFallback(\n deps: RuntimeDeps,\n state: RuntimeState,\n target: CachedElement,\n): void {\n if (state.warnedFragmentFallback) return;\n state.warnedFragmentFallback = true;\n deps.warn(\n `[live-preview] LP0806: \"${target.fieldName}\" asks for the fragment strategy but no handler is configured; patching instead`,\n );\n}\n\n/** LP0407, once per element: an unknown strategy is left alone, not guessed at. */\nexport function warnUnsupportedStrategy(\n deps: RuntimeDeps,\n state: RuntimeState,\n target: CachedElement,\n): void {\n if (state.warnedStrategy.has(target.element)) return;\n state.warnedStrategy.add(target.element);\n deps.warn(\n `[live-preview] LP0407: \"${target.fieldName}\" asks for strategy \"${String(target.strategy)}\"; only patch, fragment and route exist`,\n );\n}\n\n/**\n * LP0808, once: the default asks for a server render and this page has nothing\n * to ask. Said with the count that brought it up: a page that keeps producing\n * findings is the page that needs the line, not one line per finding. A page\n * with a fragment strategy and no route reaches here too, when a boundary of\n * this document does not cover every one of them (strategy-runner.ts hands a\n * boundary all of them or none), and is told that rather than that nothing is\n * configured.\n */\nexport function warnEscalationUnavailable(\n deps: RuntimeDeps,\n state: RuntimeState,\n count: number,\n): void {\n if (state.warnedEscalationUnavailable) return;\n state.warnedEscalationUnavailable = true;\n const shortfall = `[live-preview] LP0808: onUnfaithfulPatch: 'escalate' has nowhere to go: ${String(count)} field(s) fell short`;\n const warnInstead = \"or onUnfaithfulPatch: 'warn' to keep the patch and say so.\";\n deps.warn(\n deps.strategies.fragment === undefined\n ? `${shortfall} and no route or fragment strategy is configured. Set routeStrategy: true or fragments: { endpoint }, ${warnInstead}`\n : `${shortfall}, not all of them inside a data-payload-fragment boundary of this document, ` +\n 'and no route strategy is configured. ' +\n `Cover them with a boundary or add the route strategy, ${warnInstead}`,\n );\n}\n\n/** LP0809, once: fragment scripts never run, so the page must already start Astro islands. */\nexport function warnIslandStart(\n deps: RuntimeDeps,\n state: RuntimeState,\n island: Element,\n blocker: 'element' | 'directive',\n): void {\n if (state.warnedIslandStart) return;\n state.warnedIslandStart = true;\n const missing =\n blocker === 'element' ? '<astro-island>' : `client:${island.getAttribute('client') ?? ''}`;\n deps.warn(\n `[live-preview] LP0809: a fragment island cannot start: this page never loaded ${missing}; render one on the page`,\n );\n}\n","/**\n * Runs the fragment and route strategies for a revision. A strategy that\n * throws or rejects is treated as failed, never left to reject the runtime.\n */\n\nimport type { PayloadLivePreviewData } from '@/types/payload-protocol';\nimport { trustedHtml } from '@security/trusted-types';\nimport { isBindingInScope } from './binding-owner';\nimport { resolveBindingOwner } from './cache';\nimport { reportUnboundChange } from './fidelity';\nimport { bindingValue } from './field-value';\nimport {\n astroIslandsIn,\n isMorphBoundary,\n islandStartBlocker,\n releaseDisconnectedIslands,\n retainIslandBoundary,\n} from './islands';\nimport { morphElement } from './morph';\nimport type { RuntimeDeps, RuntimeState, UpdateTransaction } from './runtime-state';\nimport { thrownFragment } from './revision-display';\nimport {\n liveBoundary,\n planBoundaries,\n type FragmentContext,\n type FragmentPlan,\n type RouteOutcome,\n type RouteStrategy,\n} from './strategies';\nimport { KEY_ATTRIBUTE } from './structural-applier';\nimport {\n warnEscalationUnavailable,\n warnFragmentFallback,\n warnIslandStart,\n warnUnsupportedStrategy,\n} from './strategy-warnings';\nimport {\n declaredSubfields,\n routeTouched,\n unboundChangedFields,\n type OwnerScope,\n type SubfieldValues,\n} from './unbound-fields';\nimport type { CachedElement } from './types';\n\n/** What the pipeline lends the runner. */\nexport interface StrategyHost {\n readonly reapply: (transaction: UpdateTransaction, data: PayloadLivePreviewData) => void;\n readonly transform: (\n target: CachedElement,\n value: unknown,\n allFields: Record<string, unknown>,\n isCurrent: () => boolean,\n ) => unknown;\n readonly rebuildCache: () => void;\n /** A server render — the route, or a fragment boundary — dropped the stamps a guess lives by; look for the baseline's guesses again (ADR 0014). */\n readonly restoreGuesses: (transaction: UpdateTransaction, data: PayloadLivePreviewData) => void;\n /** Scroll to the binding this revision marked, if it has not been revealed yet. */\n readonly revealPending: (transaction: UpdateTransaction) => void;\n}\n\nexport class StrategyRunner {\n constructor(\n private readonly deps: RuntimeDeps,\n private readonly state: RuntimeState,\n private readonly host: StrategyHost,\n ) {}\n\n /**\n * The boundaries this revision renders: those its diff touches, and those a\n * newer revision cut short before they settled that are still on the page.\n * A debt is settled when a render of its boundary starts, so a late-binding\n * pass, which renders only what streamed in, leaves the rest owed.\n */\n planFragments(touched: ReadonlySet<string>, ownerKeys: OwnerScope): FragmentPlan | null {\n const { deps, state } = this;\n const strategy = deps.strategies.fragment;\n if (strategy === undefined) return null;\n const planned = new Set(strategy.plan(deps.root, touched));\n for (const boundary of state.fragmentsOwed) {\n if (deps.root.contains(boundary)) planned.add(boundary);\n else state.fragmentsOwed.delete(boundary);\n }\n const boundaries = [...planned].filter((boundary) => inOwnerScope(boundary, ownerKeys));\n return planBoundaries(strategy, boundaries, ownerKeys);\n }\n\n /**\n * Hand the bindings this revision could not patch faithfully to a server:\n * the fragment strategy when a boundary covers every one of them, the route\n * otherwise. All of them or none — a boundary renders its own region, so a\n * finding outside every boundary is only answered by the whole route.\n *\n * A revision that already refreshed the route is left alone: the second\n * request would fetch the bytes the first one just brought.\n */\n escalateUnfaithful(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n targets: readonly CachedElement[],\n ownerKeys: OwnerScope,\n ): void {\n if (transaction.routeRefreshed) {\n this.kept(transaction, targets);\n return;\n }\n const { fragment, route } = this.deps.strategies;\n const covered = fragment === undefined ? undefined : coveringBoundaries(targets);\n const boundaries =\n covered === undefined || covered.every((boundary) => inOwnerScope(boundary, ownerKeys))\n ? covered\n : undefined;\n if (fragment !== undefined && boundaries !== undefined) {\n this.state.escalatedCount += targets.length;\n transaction.pendingFragments += boundaries.length;\n void this.runFragments(transaction, data, planBoundaries(fragment, boundaries, ownerKeys));\n return;\n }\n if (route === undefined) {\n // Only 'escalate' queues a patch for this method (fidelity.ts), so the\n // page that reaches here with no strategy is the one the line is for.\n warnEscalationUnavailable(this.deps, this.state, targets.length);\n this.kept(transaction, targets);\n return;\n }\n this.state.escalatedCount += targets.length;\n void this.refreshRoute(transaction, data, route);\n }\n\n /** Patches that fell short and stay as they are: the revision does not show those fields. */\n private kept(transaction: UpdateTransaction, targets: readonly CachedElement[]): void {\n for (const target of targets) {\n this.state.display.shortfall(transaction, { kind: 'unfaithful', field: target.fieldName });\n }\n }\n\n /**\n * Whether this revision changed a field the page cannot patch — one with no\n * anchor anywhere, which is also how a section the template renders only\n * under a condition looks from here. The whole route is then the only honest\n * answer.\n *\n * Asked of every revision rather than only where a refresh could follow it,\n * because the finding is the same one under every mode and on a page with no\n * strategy — and that page is what `inspect().fidelity` is read on. What the\n * mode still decides is what is *done*: `'warn'` adds no line of its own\n * (LP0203, or LP0201 for an empty value, already names the field) and `'ignore'` keeps the stale value,\n * exactly as before; only the ledger sees them now.\n *\n * The baseline message is skipped, because there every field counts as\n * changed and the page has just been rendered from them anyway — and so is\n * the re-apply after a refresh, which would otherwise report it all twice.\n * A navigation's replay lands on the server's render of the saved document\n * too: a refresh would fetch those bytes again, so it is answered as a\n * partial render is, by the next save.\n */\n hasUnboundChange(transaction: UpdateTransaction, ownerKeys: OwnerScope): boolean {\n const { deps, state } = this;\n if (transaction.baseline || transaction.routeRefreshed) return false;\n const unbound = unboundChangedFields(\n deps.cache,\n transaction.touched,\n transaction.locale,\n ownerKeys,\n this.subfields(transaction),\n deps.strategies,\n );\n let answered = 0;\n for (const fieldName of unbound) if (reportUnboundChange(state, fieldName)) answered += 1;\n const [first] = unbound;\n if (first === undefined) return false;\n if (deps.onUnfaithfulPatch !== 'escalate' || deps.strategies.route === undefined) {\n if (deps.onUnfaithfulPatch === 'escalate') {\n warnEscalationUnavailable(deps, state, unbound.length);\n }\n for (const field of unbound) state.display.shortfall(transaction, { kind: 'unbound', field });\n return false;\n }\n if (transaction.navigated) {\n state.routeAwaitsSave = true;\n state.display.shortfall(transaction, { kind: 'route-saved' });\n return false;\n }\n deps.log('route', 'LP0807', `field \"${first}\" has no binding; refreshing the route`);\n state.escalatedCount += answered;\n return true;\n }\n\n /** What the declared mode compares below the top level for this revision. */\n private subfields(transaction: UpdateTransaction): SubfieldValues | undefined {\n const { previousFields } = this.state.changes;\n return declaredSubfields(\n this.deps.subfieldCoverage,\n previousFields,\n transaction.renderData?.fields,\n );\n }\n\n /**\n * Whether the route is asked for, by the strategy's planner or by a route\n * binding of a touched field, each only inside the update's owner scope: a\n * marker another document owns is that document's business (PHD-02). Both\n * see the paths inside the touched fields that route-bound elements name.\n */\n plansRoute(route: RouteStrategy, transaction: UpdateTransaction, ownerKeys: OwnerScope): boolean {\n const owned = (owner: string | undefined): boolean =>\n ownerKeys === false || isBindingInScope(owner, ownerKeys);\n const inScope = (element: Element): boolean => owned(resolveBindingOwner(element));\n const touched = routeTouched(this.deps.cache, transaction.touched, this.subfields(transaction));\n if (route.plan(this.deps.root, touched, { inScope })) return true;\n for (const [fieldName, bindings] of this.deps.cache.entries()) {\n if (!touched.has(fieldName)) continue;\n if (bindings.some((target) => target.strategyKind === 'route' && owned(target.owner))) {\n return true;\n }\n }\n return false;\n }\n\n async runFragments(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n plan: FragmentPlan,\n ): Promise<void> {\n const { deps, state } = this;\n const controller = new AbortController();\n const unsettled = new Set(plan.boundaries);\n for (const boundary of unsettled) state.fragmentsOwed.delete(boundary);\n state.fragmentControllers.set(controller, unsettled);\n const settle = (boundary: Element): void => {\n if (unsettled.delete(boundary)) transaction.pendingFragments -= 1;\n };\n const isCurrent = (): boolean => state.isCurrent(transaction) && !controller.signal.aborted;\n const live = (boundary: Element): Element | undefined =>\n liveBoundary(deps.root, boundary, (candidate) => inOwnerScope(candidate, plan.ownerKeys));\n const { emitter } = deps;\n const { message } = transaction;\n const revision = transaction.revision.revision;\n const receivedAt = transaction.receivedAt;\n const context: FragmentContext = {\n root: deps.root,\n revision,\n receivedAt,\n fields: data.fields,\n locale: transaction.locale,\n collectionSlug:\n typeof message.collectionSlug === 'string' ? message.collectionSlug : undefined,\n globalSlug: typeof message.globalSlug === 'string' ? message.globalSlug : undefined,\n signal: controller.signal,\n isCurrent,\n log: (code, detail) => {\n deps.log('fragment', code, detail);\n },\n morph: (boundary, html) => {\n const target = isCurrent() ? live(boundary) : undefined;\n if (target === undefined) return;\n morphFragment(target, html, (island, blocker) => {\n warnIslandStart(this.deps, this.state, island, blocker);\n });\n },\n patch: (boundary) => {\n const target = live(boundary);\n if (target === undefined) return;\n // A copy's bindings reach the cache only after the structural debounce.\n if (target !== boundary) this.host.rebuildCache();\n this.patchFallback(transaction, data, target, plan.ownerKeys, isCurrent);\n },\n rendered: (planned, id, key) => {\n settle(planned);\n const element = live(planned) ?? planned;\n void emitter.emitWhile(\n 'fragmentRender',\n { element, id, key, status: 'rendered', revision, receivedAt },\n isCurrent,\n );\n },\n failed: (planned, id, key, code, reason) => {\n settle(planned);\n const element = live(planned) ?? planned;\n state.display.shortfall(transaction, { kind: 'fragment', id, key, code });\n const detail = `fragment \"${id}\" fell back to patch: ${reason}`;\n // Logged where the failure is, not where an exception would have been:\n // the supplied strategy answers a timeout or a refusal with an outcome\n // and never throws, so the `catch` around `render()` below is not on\n // this path and its LP0801 reached no log sink at all.\n deps.log('fragment', code, detail);\n void emitter.emitWhile(\n 'error',\n { error: new Error(detail), context: 'fragment', code },\n isCurrent,\n );\n void emitter.emitWhile(\n 'fragmentRender',\n { element, id, key, status: 'failed', code, revision, receivedAt },\n isCurrent,\n );\n },\n };\n let report = { rendered: 0, failed: 0, superseded: 0 };\n try {\n report = await plan.strategy.render(context, plan.boundaries);\n } catch (error) {\n deps.log('fragment', 'LP0801', error);\n if (isCurrent()) {\n for (const boundary of plan.boundaries) {\n context.patch(boundary);\n state.display.shortfall(transaction, thrownFragment(boundary));\n }\n report = { rendered: 0, failed: plan.boundaries.length, superseded: 0 };\n }\n }\n state.fragmentStats.rendered += report.rendered;\n state.fragmentStats.failed += report.failed;\n state.fragmentStats.superseded += report.superseded;\n state.fragmentControllers.delete(controller);\n for (const boundary of unsettled) settle(boundary);\n if (!isCurrent()) return;\n // A rendered boundary holds the server's markup, which carries no stamp: the\n // guesses in it go back on, as after a refresh, before the revision counts\n // as complete. Without this a guess in a boundary did not outlive the first\n // message, which renders the boundary as well.\n if (report.rendered > 0) this.host.restoreGuesses(transaction, data);\n if (transaction.pendingFragments === 0 && deps.scheduler.pendingCount === 0) {\n state.complete(transaction);\n }\n // The edited field may be one the server just rendered: its element is only\n // in place now, so this is the earliest point it can be scrolled to.\n this.host.revealPending(transaction);\n if (!isCurrent()) return;\n if (report.rendered === 0 || emitter.listenerCount('afterUpdate') === 0) return;\n void emitter.emitWhile(\n 'afterUpdate',\n {\n data,\n updatedCount: report.rendered,\n durationMs: Date.now() - receivedAt,\n revision,\n receivedAt,\n source: 'fragment',\n },\n isCurrent,\n );\n }\n\n /** Refresh the route once per revision, then re-apply the revision onto the fresh markup. */\n async refreshRoute(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n strategy: RouteStrategy,\n ): Promise<void> {\n const { deps, state } = this;\n if (transaction.routeRefreshed) {\n state.routeStats.loopStopped += 1;\n deps.log(\n 'route',\n 'LP0805',\n `revision ${String(transaction.revision.revision)} asked for a second refresh`,\n );\n return;\n }\n // A refusal counts as asked as well: the trailing run below is this\n // revision's one refresh, and nothing else may start a second.\n transaction.routeRefreshed = true;\n await this.runRoute(transaction, data, strategy, false).catch((error: unknown) => {\n this.routeFailed(error);\n });\n }\n\n /**\n * Payload saved the document, and the route was last rendered from the older\n * save (`routeAwaitsSave`): render it again, now that the server has the edits.\n * Payload posts the event once the save landed, so no delay is guessed at.\n */\n refreshAfterSave(): void {\n const { deps, state } = this;\n const { route } = deps.strategies;\n const current = state.activeUpdate;\n // A stopped runtime has no active update, so this also refuses after stop().\n if (!state.routeAwaitsSave || route === undefined || current?.renderData === undefined) return;\n deps.log('route', 'document saved; refreshing the route');\n this.runRoute(current, current.renderData, route, true).catch((error: unknown) => {\n this.routeFailed(error);\n });\n }\n\n /**\n * Nothing awaits a refresh, so an unexpected throw after it returned, while\n * the page is re-applied onto the fresh markup, would otherwise escape as an\n * unhandled rejection. The strategy's own throw is an outcome (LP0801).\n */\n private routeFailed(error: unknown): void {\n this.deps.log('route refresh failed:', error);\n }\n\n /**\n * The trailing run of a refused refresh: the strategy's window closes and the\n * request it held back runs, once. It cannot loop — a refresh re-renders the\n * page from the server and produces no message, so nothing asks again.\n */\n private armRouteRetry(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n strategy: RouteStrategy,\n delayMs: number,\n forSave: boolean,\n ): void {\n const { state } = this;\n if (state.routeRetry !== null) clearTimeout(state.routeRetry);\n state.routeRetry = setTimeout(() => {\n state.routeRetry = null;\n if (!state.isCurrent(transaction)) return;\n this.runRoute(transaction, data, strategy, forSave).catch((error: unknown) => {\n this.routeFailed(error);\n });\n }, delayMs);\n }\n\n /**\n * One trip through the strategy, whether the revision asked for it or the\n * window did. It replaces a refresh still in flight, and it lands for the\n * revision that is current when it returns, which need not be the one that\n * asked (ADR 0004 §4d).\n */\n private async runRoute(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n strategy: RouteStrategy,\n forSave: boolean,\n ): Promise<void> {\n const { deps, state } = this;\n const stats = state.routeStats;\n const controller = new AbortController();\n state.routeController?.abort();\n state.routeController = controller;\n // A stop aborts it too, so the signal alone says whether it may still land.\n const lands = (): boolean => !controller.signal.aborted;\n let outcome: RouteOutcome;\n try {\n outcome = await strategy.refresh({\n revision: transaction.revision.revision,\n receivedAt: transaction.receivedAt,\n signal: controller.signal,\n isCurrent: lands,\n log: (code, detail) => {\n deps.log('route', code, detail);\n },\n retryAfter: (delayMs) => {\n this.armRouteRetry(transaction, data, strategy, delayMs, forSave);\n },\n });\n } catch (error) {\n deps.log('route', 'LP0801', error);\n outcome = 'failed';\n }\n if (!lands()) return;\n // Whatever replaces this refresh, ends the route or stops the session\n // aborts it first, so it is still the one in flight and a revision is\n // current; the null check only narrows the type.\n state.routeController = null;\n const current = state.activeUpdate;\n if (current === null) return;\n // The current revision's latest data, which a merge may have refined since\n // the refresh started. One still resolving its fields has none yet: it\n // applies itself onto whatever the route shows when it gets there.\n const currentData = current.renderData;\n const isCurrent = (): boolean => state.isCurrent(current);\n if (outcome === 'partial') state.display.shortfall(current, { kind: 'route-saved' });\n // A refusal with its trailing run armed is not an outcome yet: that run is.\n else if (\n outcome === 'failed' ||\n outcome === 'superseded' ||\n (outcome === 'refused' && state.routeRetry === null)\n ) {\n state.display.shortfall(current, { kind: 'route-failed', outcome });\n }\n if (outcome === 'refreshed' || outcome === 'partial') {\n stats.refreshes += 1;\n if (outcome === 'partial') stats.partial += 1;\n state.routeAwaitsSave = outcome === 'partial' && !forSave;\n // Route markup has no local application identities; every prior stamp is stale.\n state.lastAppliedIdentity = new WeakMap();\n // The fresh markup carries no stamp: the guesses go back on before the\n // cache is rebuilt from it, or the rebuild would not know them.\n if (currentData !== undefined) this.host.restoreGuesses(current, currentData);\n this.host.rebuildCache();\n if (currentData === undefined || !isCurrent()) return;\n this.host.reapply(current, currentData);\n if (deps.emitter.listenerCount('afterUpdate') > 0) {\n void deps.emitter.emitWhile(\n 'afterUpdate',\n {\n data: currentData,\n // The strategy replaced the whole route, so every binding now on\n // the page carries new markup; the unsaved fields scheduled just\n // above report themselves in their own `patch` batch.\n updatedCount: deps.cache.elementCount,\n durationMs: Date.now() - current.receivedAt,\n revision: current.revision.revision,\n receivedAt: current.receivedAt,\n source: 'route',\n },\n isCurrent,\n );\n }\n return;\n }\n // A refusal is a pause, not a breakage; counting the two together is how\n // `failed: 3` came to stand in an inspection where nothing was wrong.\n if (outcome === 'failed') stats.failed += 1;\n else if (outcome === 'refused') stats.refused += 1;\n // Either way the page shows what it can now: the window holds back the\n // server, not the bindings this revision could already have written.\n if (currentData !== undefined) this.host.reapply(current, currentData);\n }\n\n /** LP0806, once: a fragment boundary with no handler is patched instead. */\n warnFragmentFallback(target: CachedElement): void {\n warnFragmentFallback(this.deps, this.state, target);\n }\n\n /** LP0407, once per element: an unknown strategy is left alone, not guessed at. */\n warnUnsupportedStrategy(target: CachedElement): void {\n warnUnsupportedStrategy(this.deps, this.state, target);\n }\n\n /** The deterministic fallback: patch the boundary's own bindings from the same revision. */\n private patchFallback(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n boundary: Element,\n ownerKeys: OwnerScope,\n isCurrent: () => boolean,\n ): void {\n if (!isCurrent()) return;\n for (const [fieldName, bindings] of this.deps.cache.entries()) {\n for (const target of bindings) {\n if (target.fragmentBoundary !== boundary) continue;\n if (ownerKeys !== false && !isBindingInScope(target.owner, ownerKeys)) continue;\n const value = bindingValue(data.fields, target, fieldName, transaction.locale);\n if (value === undefined || !isCurrent()) continue;\n this.deps.scheduler.schedule({\n target,\n value: this.host.transform(target, value, data.fields, isCurrent),\n allFields: data.fields,\n revision: transaction.revision,\n data,\n });\n }\n }\n }\n}\n\n/** The distinct boundaries around `targets`, or `undefined` when one sits outside them all. */\nfunction coveringBoundaries(targets: readonly CachedElement[]): Element[] | undefined {\n const boundaries: Element[] = [];\n for (const target of targets) {\n const boundary = target.fragmentBoundary;\n if (boundary === undefined) return undefined;\n if (!boundaries.includes(boundary)) boundaries.push(boundary);\n }\n return boundaries;\n}\n\n/** Whether the document that owns `element` is inside the update's owner scope. */\nfunction inOwnerScope(element: Element, ownerKeys: OwnerScope): boolean {\n return ownerKeys === false || isBindingInScope(resolveBindingOwner(element), ownerKeys);\n}\n\n/**\n * Morph server-rendered HTML into the boundary; compatible retained nodes keep\n * live state. Islands follow ADR 0021: removed ones are released, and an\n * inserted one the page cannot start is reported rather than scripted.\n */\nfunction morphFragment(\n boundary: Element,\n html: string,\n blocked: (island: Element, blocker: 'element' | 'directive') => void,\n): void {\n const template = boundary.ownerDocument.createElement('template');\n template.innerHTML = trustedHtml(html);\n const rendered = boundary.cloneNode(false) as Element;\n rendered.append(template.content);\n const before = astroIslandsIn(boundary);\n morphElement(boundary, rendered, {\n keyAttributes: [KEY_ATTRIBUTE],\n boundary: isMorphBoundary,\n retainBoundary: retainIslandBoundary,\n });\n releaseDisconnectedIslands(before);\n const known = new Set(before);\n for (const island of astroIslandsIn(boundary)) {\n const blocker = known.has(island) ? undefined : islandStartBlocker(island);\n if (blocker !== undefined) blocked(island, blocker);\n }\n}\n","/**\n * The plugin boundary on a value's way to its binding. Transforms are consumer\n * code: their result is frozen into the scheduler entry, an error is reported\n * as LP0602 and the original value kept, and a thenable is a contract error —\n * a transform that awaits would hand the scheduler a promise to render.\n */\n\nimport type { RuntimeDeps } from './runtime-state';\nimport { observeThenableResult } from './thenable';\nimport type { CachedElement } from './types';\n\n/** Never awaited: every consumer callback may accept a newer revision synchronously (ADR 0004). */\nexport function transformForBinding(\n deps: RuntimeDeps,\n target: CachedElement,\n originalValue: unknown,\n allFields: Record<string, unknown>,\n isCurrent: () => boolean,\n): unknown {\n const transform = deps.transformValue;\n if (transform === undefined) return originalValue;\n try {\n const transformed = transform(\n target.fieldName,\n originalValue,\n { element: target.element, allFields },\n isCurrent,\n );\n const returnedThenable = observeThenableResult(transformed);\n if (!isCurrent()) return originalValue;\n if (returnedThenable) {\n throw new TypeError(\n `Transform for \"${target.fieldName}\" returned a thenable; transforms must be synchronous`,\n );\n }\n return transformed;\n } catch (err) {\n if (!isCurrent()) return originalValue;\n const error = err instanceof Error ? err : new Error(String(err));\n void deps.emitter.emit('error', { error, context: 'transform', code: 'LP0602' });\n return originalValue;\n }\n}\n","/**\n * From an accepted message to scheduled writes: merge, diff, plan the\n * strategies, schedule each binding, and finish the revision on flush.\n */\n\nimport type { PayloadLivePreviewData, PayloadLivePreviewMessage } from '@/types/payload-protocol';\nimport { buildSchemaIndex } from '@schema/index';\nimport { adoptUniqueBindings, restoreUniqueBindings } from './auto-bind';\nimport { isBindingInScope } from './binding-owner';\nimport type { MergeResult } from './data-merger';\nimport { mergeDependencyMaps } from './dependencies';\nimport { bindingIdentity, bindingValue } from './field-value';\nimport { type MessageRevision, sameRevision } from './message-bus';\nimport { NavigationReplay } from './navigation-replay';\nimport { diagnoseOrphanFields } from './orphan-diagnostics';\nimport { reportOmittedFeature } from './profile';\nimport { observeCapabilities } from './protocol-version';\nimport { owesForceRender } from './relationship-tracker';\nimport { revealBinding } from './reveal';\nimport { runtimeDisplayHost } from './revision-display';\nimport { type RuntimeDeps, type RuntimeState, type UpdateTransaction } from './runtime-state';\nimport { resolveStrategy } from './strategies';\nimport { StrategyRunner } from './strategy-runner';\nimport { createLeanStrategyRunner, type StrategyRunnerLike } from './strategy-runner-lean';\nimport { transformForBinding } from './transform-value';\nimport { ownerKeysForUpdate } from './update-owner';\nimport type { FlushStats, ScheduledUpdate } from './update-scheduler';\n\n/** A refinement moved no field: it completes values the revision already applied. */\nconst NOTHING_CHANGED: ReadonlySet<string> = new Set();\n/** The populated re-fetch failed; the message's own values stand in (ADR 0023). */\nconst MERGE_FAILED = { kind: 'merge' } as const;\n\nexport class UpdatePipeline {\n private readonly strategies: StrategyRunnerLike;\n private readonly navigationReplay: NavigationReplay;\n\n constructor(\n private readonly deps: RuntimeDeps,\n private readonly state: RuntimeState,\n rebuildCache: () => void,\n ) {\n state.changes.keepValues = deps.subfieldCoverage === 'declared';\n state.display.host = runtimeDisplayHost(deps, state);\n // Esbuild folds this choice; the lean branch drops the server-rendering strategies.\n this.strategies =\n typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__\n ? createLeanStrategyRunner(deps, state)\n : new StrategyRunner(deps, state, {\n reapply: (transaction, data) => {\n this.scheduleAllFields(transaction, data);\n },\n transform: (target, value, allFields, isCurrent) =>\n transformForBinding(deps, target, value, allFields, isCurrent),\n rebuildCache,\n restoreGuesses: (transaction, data) => {\n this.restoreGuesses(transaction, data);\n },\n revealPending: (transaction) => {\n this.revealPending(transaction);\n },\n });\n this.navigationReplay = new NavigationReplay(deps, state, {\n schedule: (transaction, data, elements) => {\n this.scheduleAllFields(transaction, data, elements);\n },\n });\n }\n\n handleUpdate(\n message: PayloadLivePreviewMessage,\n origin: string,\n revision: MessageRevision | undefined,\n ): void {\n const { deps, state } = this;\n deps.heartbeat.kick();\n state.protocol.observe(observeCapabilities(message), deps.log);\n const rawData = message.data;\n if (rawData === undefined) {\n if (message.protocolVersion !== undefined) {\n state.protocol.applyVersion(message.protocolVersion, deps.log);\n }\n return;\n }\n if (revision === undefined) return;\n this.acceptDataUpdate(message, rawData, origin, revision, true);\n }\n\n handleReplay(\n message: PayloadLivePreviewMessage,\n origin: string,\n revision: MessageRevision,\n ): void {\n const rawData = message.data;\n if (rawData === undefined) return;\n this.acceptDataUpdate(message, rawData, origin, revision, false);\n }\n\n reapplyNavigationBindings(elements: ReadonlySet<Element>): void {\n this.navigationReplay.reapplyBindings(elements);\n }\n\n /** Hand a streamed island only the retained document it has not seen yet. */\n reapplyNavigationIslands(islands: readonly Element[], hydrationCompleted = false): void {\n this.navigationReplay.reapplyIslands(islands, hydrationCompleted);\n }\n\n private acceptDataUpdate(\n message: PayloadLivePreviewMessage,\n rawData: Record<string, unknown>,\n origin: string,\n revision: MessageRevision,\n countsAsUpdate: boolean,\n ): void {\n const { deps, state } = this;\n // A level, not an edge: the panel repeats its last document event in every\n // message and never clears it, so only a changed event about a document\n // other than this one is news (LP-1).\n const relationshipInspection = countsAsUpdate ? state.relationships.inspect(message) : null;\n const locale = typeof message.locale === 'string' ? message.locale : state.locale;\n let schema = state.schema;\n let schemaIndex = state.schemaIndex;\n if (Array.isArray(message.fieldSchemaJSON)) {\n schema = message.fieldSchemaJSON;\n schemaIndex = buildSchemaIndex(message.fieldSchemaJSON);\n }\n // Schema parsing and synthetic message accessors are trust boundaries. A\n // newer accepted revision that reentered there already owns the runtime.\n const incumbent = state.activeUpdate;\n if (\n !state.isRunning() ||\n (incumbent !== null && incumbent.revision.revision > revision.revision)\n ) {\n return;\n }\n const relationshipEdit =\n relationshipInspection === null ? null : state.relationships.commit(relationshipInspection);\n const previous = incumbent;\n const transaction: UpdateTransaction = {\n revision,\n message,\n rawData,\n locale,\n schema,\n schemaIndex,\n receivedAt: Date.now(),\n forceRender: relationshipEdit !== null || owesForceRender(previous),\n countsAsUpdate,\n renderData: undefined,\n fragmentBoundariesRun: new WeakSet(),\n touched: new Set(),\n baseline: false,\n navigated: false,\n invalidated: new Set(),\n revealTarget: undefined,\n revealIdentities: [],\n pendingFragments: 0,\n routeRefreshed: false,\n cancelled: false,\n completed: false,\n };\n // Acceptance is the single supersession point. Only a revision that never\n // reached its terminal state counts as superseded. Publish the new owner\n // before aborting: an AbortSignal listener may accept a newer revision.\n state.locale = locale;\n state.schema = schema;\n state.schemaIndex = schemaIndex;\n if (previous !== null && !previous.completed && previous.countsAsUpdate) {\n state.supersededCount += 1;\n }\n state.activeUpdate = transaction;\n if (countsAsUpdate) state.updateCount += 1;\n state.display.begin(transaction, revision.revision);\n if (!state.isCurrent(transaction)) return;\n deps.scheduler.acceptRevision(revision);\n if (!state.isCurrent(transaction)) return;\n state.supersedeStrategies();\n if (!state.isCurrent(transaction)) return;\n if (relationshipEdit !== null) {\n void deps.emitter.emitWhile(\n 'relationshipUpdate',\n { detail: relationshipEdit, timestamp: Date.now() },\n () => state.isCurrent(transaction),\n );\n if (!state.isCurrent(transaction)) return;\n }\n if (countsAsUpdate && message.protocolVersion !== undefined) {\n state.protocol.applyVersion(message.protocolVersion, deps.log);\n if (!state.isCurrent(transaction)) return;\n }\n if (countsAsUpdate && deps.connection.markConnected()) {\n deps.a11y?.announceConnected();\n void deps.emitter.emit('connect', { origin, timestamp: Date.now() });\n if (!state.isCurrent(transaction)) return;\n deps.log('connection', 'disconnected', '→', 'connected');\n if (!state.isCurrent(transaction)) return;\n }\n // Nothing awaits this, so an unexpected throw would leave the page as an\n // unhandled rejection — a console error the host cannot attribute, and a\n // process exit under `--unhandled-rejections=strict`.\n void this.processUpdate(transaction).catch((error: unknown) => {\n deps.log('update failed:', error);\n });\n }\n\n private async processUpdate(transaction: UpdateTransaction): Promise<void> {\n const { deps, state } = this;\n const fields = await this.resolveIncomingFields(transaction);\n if (fields === null || !state.isCurrent(transaction)) return;\n const data = this.dataFor(transaction, fields);\n if (deps.emitter.listenerCount('beforeUpdate') > 0) {\n const completed = await deps.emitter.emitWhile(\n 'beforeUpdate',\n {\n data,\n revision: transaction.revision.revision,\n receivedAt: transaction.receivedAt,\n source: 'patch',\n cancel: (): void => {\n transaction.cancelled = true;\n deps.scheduler.cancelRevision(transaction.revision);\n },\n },\n () => !transaction.cancelled && state.isCurrent(transaction),\n );\n if (!completed || transaction.cancelled || !state.isCurrent(transaction)) return;\n }\n this.applyFields(transaction, data, false);\n }\n\n private dataFor(\n transaction: UpdateTransaction,\n fields: Record<string, unknown>,\n ): PayloadLivePreviewData {\n const { message } = transaction;\n return {\n fields,\n ...(transaction.schema !== undefined ? { schema: transaction.schema } : {}),\n ...(typeof message.globalSlug === 'string' ? { globalSlug: message.globalSlug } : {}),\n ...(typeof message.collectionSlug === 'string'\n ? { collectionSlug: message.collectionSlug }\n : {}),\n ...(transaction.locale !== undefined ? { locale: transaction.locale } : {}),\n };\n }\n\n /**\n * Diff against what the page last showed, then schedule. A refinement is the\n * populated answer to values this revision already applied: it keeps the diff\n * in step without letting population count as an edit, because no strategy\n * may be planned a second time for one message.\n */\n private applyFields(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n refined: boolean,\n ): void {\n const { deps, state } = this;\n if (!state.isCurrent(transaction)) return;\n if (state.changes.isBaseline && !refined && deps.autoBind !== 'off') {\n // Once, on the message that describes what the server rendered (ADR 0014\n // §1). The lean profile leaves the search out; esbuild folds the branch.\n if (typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__) {\n reportOmittedFeature('auto-binding');\n } else {\n const scope = ownerKeysForUpdate(deps, state, transaction, data.fields);\n adoptUniqueBindings(deps, state, data.fields, transaction.locale, scope, () =>\n state.isCurrent(transaction),\n );\n }\n if (!state.isCurrent(transaction)) return;\n }\n const dependencies = mergeDependencyMaps(deps.dependencies, deps.cache.dependencyMap());\n if (!state.isCurrent(transaction)) return;\n const changes = state.changes.diff(data.fields, dependencies, () =>\n state.isCurrent(transaction),\n );\n if (changes === null) return;\n const navigationReplay = !refined && state.navigationReplayPending;\n if (navigationReplay) {\n state.navigationReplayPending = false;\n state.navigationBindingReplay = true;\n }\n // A navigation replay counts every field as changed but is not the baseline.\n transaction.baseline = changes.baseline && !navigationReplay;\n transaction.navigated = navigationReplay;\n transaction.invalidated = refined ? NOTHING_CHANGED : changes.invalidated;\n transaction.touched = refined\n ? NOTHING_CHANGED\n : new Set([...changes.changed, ...changes.invalidated]);\n transaction.renderData = data;\n this.scheduleAllFields(transaction, data);\n }\n\n /** The document to render: merged when the server has something to add, else the message's own values; `null` when superseded. */\n private async resolveIncomingFields(\n transaction: UpdateTransaction,\n ): Promise<Record<string, unknown> | null> {\n const { deps, state } = this;\n const raw = transaction.rawData;\n if (deps.merger === null) return raw;\n const plan = state.merges.decide(deps, transaction);\n if (!plan.merge) return plan.fields;\n const { message } = transaction;\n const coalesced = state.merges.request(deps.merger, deps.mergeWindowMs, {\n collectionSlug: message.collectionSlug,\n globalSlug: message.globalSlug,\n data: raw,\n ...(transaction.schema === undefined ? {} : { schema: transaction.schema }),\n locale: transaction.locale,\n });\n // A request the burst shares is not one the page waits for: it renders what\n // it already has, and the answer refines it when the window closes.\n if (!coalesced.leading) {\n void this.applyMerged(transaction, coalesced.result).catch((error: unknown) => {\n deps.log('update failed:', error);\n });\n return plan.fields;\n }\n const result = await coalesced.result;\n if (!state.isCurrent(transaction)) return null;\n if (result.status === 'merged') {\n state.merges.recordMerged(result.doc, transaction.locale);\n return result.doc;\n }\n if (result.status === 'superseded') return null;\n state.display.shortfall(transaction, MERGE_FAILED);\n return plan.fields;\n }\n\n /** Whoever is still current when the shared merge lands gets the populated document. */\n private async applyMerged(\n transaction: UpdateTransaction,\n pending: Promise<MergeResult>,\n ): Promise<void> {\n const { state } = this;\n const result = await pending;\n if (result.status === 'unavailable') state.display.shortfall(transaction, MERGE_FAILED);\n if (result.status !== 'merged' || !state.isCurrent(transaction)) return;\n state.merges.recordMerged(result.doc, transaction.locale);\n this.applyFields(transaction, this.dataFor(transaction, result.doc), true);\n }\n\n scheduleAllFields(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n onlyElements?: ReadonlySet<Element>,\n ): void {\n const { deps, state } = this;\n if (!state.isCurrent(transaction)) return;\n const lateBindings = onlyElements !== undefined;\n const isCurrent = (): boolean => state.isCurrent(transaction);\n const ownerKeys = ownerKeysForUpdate(deps, state, transaction, data.fields);\n if (!isCurrent()) return;\n const { touched } = transaction;\n // A revision that touches the route refreshes it first; the re-apply lands on the fresh markup.\n const route = deps.strategies.route;\n if (\n lateBindings &&\n route !== undefined &&\n !transaction.routeRefreshed &&\n this.navigationReplay.hasLateRouteBinding(onlyElements, ownerKeys, transaction, data)\n ) {\n if (isCurrent()) void this.strategies.refreshRoute(transaction, data, route);\n return;\n }\n const unbound = !lateBindings && this.strategies.hasUnboundChange(transaction, ownerKeys);\n // A revision inherits a refused refresh; a baseline cannot owe one.\n const owed = state.routeRefreshOwed;\n if (\n !lateBindings &&\n route !== undefined &&\n !transaction.routeRefreshed &&\n (unbound || owed || this.strategies.plansRoute(route, transaction, ownerKeys)) &&\n isCurrent()\n ) {\n state.routeRefreshOwed = false;\n void this.strategies.refreshRoute(transaction, data, route);\n return;\n }\n const fragmentTouched = lateBindings\n ? this.navigationReplay.fieldsForElements(onlyElements, touched)\n : touched;\n const plan = this.navigationReplay.unrunFragmentPlan(\n transaction,\n this.strategies.planFragments(fragmentTouched, ownerKeys),\n onlyElements,\n );\n if (!isCurrent()) return;\n // Only `skipUnchanged` needs it now; the reveal keeps its own ledger.\n const trackIdentity = deps.skipUnchanged;\n let scheduled = 0;\n for (const [fieldName, bindings] of deps.cache.entries()) {\n if (!isCurrent()) return;\n for (const target of bindings) {\n if (onlyElements !== undefined && !onlyElements.has(target.element)) continue;\n if (ownerKeys !== false && !isBindingInScope(target.owner, ownerKeys)) continue;\n // A binding inside a boundary the server renders is patched only as the\n // fallback — but it can still be the field being edited, so the reveal\n // has to notice it here, before the boundary is re-rendered.\n if (plan?.covers(target) === true) {\n // Resolving the value is only worth it when something reveals.\n if (deps.revealEditedField) {\n const raw = bindingValue(data.fields, target, fieldName, transaction.locale);\n state.revealLedger.note(transaction, target, raw);\n }\n continue;\n }\n const kind = target.strategyKind ?? resolveStrategy(target.element) ?? 'unknown';\n if (kind === 'unknown') {\n this.strategies.warnUnsupportedStrategy(target);\n continue;\n }\n if (kind === 'fragment' && plan === null) this.strategies.warnFragmentFallback(target);\n const value = bindingValue(data.fields, target, fieldName, transaction.locale);\n if (value === undefined) {\n state.absentFields.add(fieldName);\n continue;\n }\n // Noted before `skipUnchanged` can skip the write: the reveal ledger is\n // its own record, and a binding whose write is unchanged since the last\n // one that landed may still be the field whose reveal was superseded.\n if (!lateBindings && deps.revealEditedField) {\n state.revealLedger.note(transaction, target, value);\n }\n if (!isCurrent()) return;\n const transformed = transformForBinding(deps, target, value, data.fields, isCurrent);\n if (!isCurrent()) return;\n // A binding renders its own value *and* the sibling fields bound to\n // href/src/alt, so its identity must cover them: otherwise an edit to\n // the sibling alone looks unchanged and the link or image stays stale.\n const identity = trackIdentity\n ? bindingIdentity(target, transformed, data.fields, transaction.locale)\n : undefined;\n const last = state.lastAppliedIdentity.get(target.element);\n if (\n !transaction.forceRender &&\n deps.skipUnchanged &&\n identity !== undefined &&\n last === identity &&\n !transaction.invalidated.has(fieldName)\n ) {\n state.skippedUnchangedCount += 1;\n continue;\n }\n const update: ScheduledUpdate = {\n target,\n value: transformed,\n allFields: data.fields,\n revision: transaction.revision,\n ...(lateBindings ? {} : { data }),\n valueIdentity: identity,\n };\n deps.scheduler.schedule(update);\n scheduled += 1;\n }\n }\n if (!lateBindings) {\n diagnoseOrphanFields(\n deps,\n state.warnedOrphanFields,\n transaction.rawData,\n transaction.locale,\n ownerKeys,\n );\n }\n if (!isCurrent()) return;\n if (plan !== null && plan.boundaries.length > 0) {\n for (const boundary of plan.boundaries) transaction.fragmentBoundariesRun.add(boundary);\n transaction.pendingFragments += plan.boundaries.length;\n void this.strategies.runFragments(transaction, data, plan);\n }\n if (lateBindings || !isCurrent()) return;\n // Islands consume the snapshot, not fragment markup. Only completion and\n // reveal wait for pending requests or a synchronously scheduled fallback.\n if (scheduled === 0) {\n if (transaction.pendingFragments === 0 && deps.scheduler.pendingCount === 0) {\n state.complete(transaction);\n this.revealPending(transaction);\n }\n this.notifyIslands(transaction, data);\n }\n }\n\n /** Islands hear every revision that carried a change, whether or not a write landed outside them. */\n private notifyIslands(transaction: UpdateTransaction, data: PayloadLivePreviewData): void {\n if (transaction.touched.size === 0) return;\n this.navigationReplay.dispatchIslands(transaction, data, this.deps.cache.islands);\n }\n\n /**\n * A server render — the route, or a fragment boundary — replaced markup\n * without the stamps a guess lives by; look for the baseline's guesses\n * again, and for nothing else (ADR 0014).\n */\n private restoreGuesses(transaction: UpdateTransaction, data: PayloadLivePreviewData): void {\n const { deps, state } = this;\n if (deps.autoBind === 'off' || state.autoBindGuesses === null) return;\n // Nothing reaches this in the lean build, which renders no route and no\n // fragment. A folded branch, not an early return: esbuild drops the branch\n // before linking and a statement after `return` only after it, and the\n // search's module was in the lean artifact until the guard took this shape.\n if (!(typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__)) {\n const scope = ownerKeysForUpdate(deps, state, transaction, data.fields);\n restoreUniqueBindings(deps, state, data.fields, transaction.locale, scope, () =>\n state.isCurrent(transaction),\n );\n }\n }\n\n /** Scheduler callback after every flush, including one that applied nothing. */\n onFlush(stats: FlushStats): void {\n const { deps, state } = this;\n state.lastFlush = stats;\n if (stats.deferred > 0 && !state.warnedVisibilityGate) {\n state.warnedVisibilityGate = true;\n deps.warn(\n `[live-preview] LP0301: visibility gate held ${String(stats.deferred)} off-screen update(s) until scrolled into view; see visibilityGateThreshold`,\n );\n }\n const { revision, data } = stats;\n if (revision === undefined) return;\n const transaction = state.activeUpdate;\n if (\n transaction === null ||\n !state.isCurrent(transaction) ||\n !sameRevision(transaction.revision, revision)\n ) {\n return;\n }\n state.display.deferred(transaction, stats.deferred);\n if (transaction.pendingFragments === 0) state.complete(transaction);\n const isCurrent = (): boolean =>\n state.isCurrent(transaction) && sameRevision(transaction.revision, revision);\n const renderData = data ?? transaction.renderData;\n // Reveal first: scrolling to a deferred off-screen edit is what replays it.\n this.revealPending(transaction);\n if (!isCurrent()) return;\n // Before the applied check: a flush that applied nothing is where every renderer refused.\n const unfaithful = state.unfaithfulPatches;\n if (unfaithful.length > 0) {\n state.unfaithfulPatches = [];\n if (renderData !== undefined) {\n const scope = ownerKeysForUpdate(deps, state, transaction, renderData.fields);\n this.strategies.escalateUnfaithful(transaction, renderData, unfaithful, scope);\n }\n if (!isCurrent()) return;\n }\n if (data === undefined) return;\n if (stats.applied > 0) deps.a11y?.announceUpdate(stats.applied);\n if (!isCurrent()) return;\n // An island still needs its event when `skipUnchanged` leaves every outer binding untouched.\n this.notifyIslands(transaction, data);\n if (!isCurrent() || stats.applied === 0 || deps.emitter.listenerCount('afterUpdate') === 0) {\n return;\n }\n void deps.emitter.emitWhile(\n 'afterUpdate',\n {\n data,\n updatedCount: stats.applied,\n durationMs: stats.durationMs,\n revision: revision.revision,\n receivedAt: transaction.receivedAt,\n source: 'patch',\n },\n isCurrent,\n );\n }\n\n /**\n * Reveal the binding this revision marked, once. Called from the patch flush\n * and again once fragments land, because only one of the two runs for any\n * given field, and a fragment-rendered element is in place only afterwards.\n */\n revealPending(transaction: UpdateTransaction): void {\n const target = this.state.revealLedger.commit(transaction);\n if (target === undefined) return;\n try {\n revealBinding(this.state.revealer, target);\n } catch (error) {\n this.deps.log('reveal', error);\n }\n }\n\n /**\n * Scroll one field's bound element into view; the admin-focus path (tier 2)\n * names a field, so it takes the first binding — a focus message carries no\n * document identity to choose between several.\n */\n revealField(fieldName: string): ReturnType<typeof revealBinding> {\n const target = this.deps.cache.get(fieldName)?.[0];\n return target === undefined ? 'no-element' : revealBinding(this.state.revealer, target);\n }\n\n /** Payload saved the document; a route rendered from the older save may render again. */\n documentSaved(): void {\n this.strategies.refreshAfterSave();\n }\n}\n","/**\n * The strategy runner the lean profile gets instead of the real one: it plans\n * nothing, renders nothing, and says so once per feature (LP0104). Its purpose\n * is that the pipeline needs no branch of its own — it holds a runner either\n * way, and the profile decides which.\n *\n * Because this module names the real runner only as a type, the lean build\n * drops that file and everything only it referenced: the morph, the fragment\n * protocol client's server half, and the route refresh.\n */\n\nimport { reportUnboundChange } from './fidelity';\nimport { reportOmittedFeature } from './profile';\nimport type { StrategyRunner } from './strategy-runner';\nimport { warnFragmentFallback, warnUnsupportedStrategy } from './strategy-warnings';\nimport type { RuntimeDeps, RuntimeState, UpdateTransaction } from './runtime-state';\nimport { declaredSubfields, unboundChangedFields, type OwnerScope } from './unbound-fields';\nimport type { CachedElement } from './types';\n\n/** What `UpdatePipeline` calls on a runner; both profiles satisfy it. */\nexport type StrategyRunnerLike = Pick<\n StrategyRunner,\n | 'planFragments'\n | 'escalateUnfaithful'\n | 'hasUnboundChange'\n | 'plansRoute'\n | 'runFragments'\n | 'refreshRoute'\n | 'refreshAfterSave'\n | 'warnFragmentFallback'\n | 'warnUnsupportedStrategy'\n>;\n\nexport function createLeanStrategyRunner(\n deps: RuntimeDeps,\n state: RuntimeState,\n): StrategyRunnerLike {\n return {\n planFragments: (): null => null,\n // Nothing to escalate to. The pipeline still drains its queue, so a page\n // that keeps producing findings does not keep producing entries; the\n // patches stay as they are, and the revision says so (ADR 0023).\n escalateUnfaithful: (transaction, _data, targets): void => {\n for (const { fieldName: field } of targets) {\n state.display.shortfall(transaction, { kind: 'unfaithful', field });\n }\n },\n // Nothing here to escalate to, and the finding is still worth recording:\n // a page that changes a field it does not bind is the page\n // `inspect().fidelity` is read on, and `escalated` staying 0 beside it is\n // the truth about this profile rather than silence about the change.\n hasUnboundChange: (transaction: UpdateTransaction, ownerKeys: OwnerScope): boolean => {\n if (transaction.baseline) return false;\n const unbound = unboundChangedFields(\n deps.cache,\n transaction.touched,\n transaction.locale,\n ownerKeys,\n declaredSubfields(\n deps.subfieldCoverage,\n state.changes.previousFields,\n transaction.renderData?.fields,\n ),\n );\n for (const field of unbound) {\n reportUnboundChange(state, field);\n state.display.shortfall(transaction, { kind: 'unbound', field });\n }\n return false;\n },\n plansRoute: (): boolean => false,\n runFragments: (): Promise<void> => Promise.resolve(),\n // A page that carries a route prelude anyway (it can be injected by hand)\n // still gets no refresh here: this runtime has no code for one.\n refreshRoute: (): Promise<void> => {\n reportOmittedFeature('route refreshes');\n return Promise.resolve();\n },\n // No route was rendered, so no save has one to render again.\n refreshAfterSave: (): void => undefined,\n warnFragmentFallback: (target: CachedElement): void => {\n reportOmittedFeature('server-rendered fragments');\n warnFragmentFallback(deps, state, target);\n },\n warnUnsupportedStrategy: (target: CachedElement): void => {\n warnUnsupportedStrategy(deps, state, target);\n },\n };\n}\n","/**\n * Debounce, frame batching and off-screen replay for scheduled writes. The\n * first write of a quiet phase does not wait for the window: it goes out on the\n * next frame and opens the window that batches the rest of the burst, so an\n * isolated keystroke costs a frame instead of a whole debounce. The scheduler\n * never writes the DOM; the injected `apply` callback does.\n */\n\nimport type { PayloadLivePreviewData } from '@/types/payload-protocol';\nimport { hasSameBindingIdentity } from './cache';\nimport { usesNoWriteOutcome } from './internal-outcome';\nimport { type MessageRevision, sameRevision } from './message-bus';\nimport type { CachedElement } from './types';\n\nexport interface ScheduledUpdate {\n readonly target: CachedElement;\n readonly value: unknown;\n readonly allFields: Record<string, unknown>;\n /** Revision revision; runtime-produced entries always carry one. */\n readonly revision?: MessageRevision | undefined;\n readonly data?: PayloadLivePreviewData | undefined;\n /** `valueIdentity(value)`, computed once by the pipeline for skip and reveal. */\n readonly valueIdentity?: string | undefined;\n}\n\nexport type ApplyUpdate = (update: ScheduledUpdate) => void;\n\nexport interface UpdateSchedulerOptions {\n /** Debounce window in ms; the write that opens it does not wait for it. Default 50. */\n readonly debounceMs?: number;\n /** Longest a flush may be postponed by continuous scheduling. Default `4 * debounceMs`. */\n readonly maxWaitMs?: number;\n /** Deferred writes replay when the host reports the element visible via `notifyVisible()`. */\n readonly isVisible: (element: Element) => boolean;\n /** Apply every write immediately regardless of visibility. Default `false`. */\n readonly disableVisibilityGate?: boolean;\n /** Cached-element count above which the gate activates. Default 50. */\n readonly visibilityGateThreshold?: number;\n readonly getCacheSize: () => number;\n readonly onFlush?: (stats: FlushStats) => void;\n /** Frame scheduler; defaults to `requestAnimationFrame`. Tests inject a synchronous one. */\n readonly scheduleFrame?: (callback: FrameRequestCallback) => number;\n readonly cancelFrame?: (handle: number) => void;\n}\n\nexport interface FlushStats {\n readonly applied: number;\n /** Field names applied, in order; `applied` alone cannot say which binding stayed stale. */\n readonly appliedFields: readonly string[];\n readonly deferred: number;\n readonly durationMs: number;\n readonly revision?: MessageRevision;\n readonly data?: PayloadLivePreviewData;\n}\n\n/** Exported so the merge behind a burst of writes can share the window that batches them. */\nexport const DEFAULT_DEBOUNCE_MS = 50;\n/** Exported so `pll doctor` can prove its own copy of the number has not drifted. */\nexport const DEFAULT_VISIBILITY_THRESHOLD = 50;\n/**\n * Longest a write waits for an animation frame. WebKit gave a visible\n * cross-origin preview frame none for seconds (the real-admin suite, 2026-10-22,\n * `animationFramesIn600ms: 0`): the document had arrived and the page kept the\n * old text. Frames come every 16 to 33 ms where they come at all.\n */\nconst FRAME_FALLBACK_MS = 100;\n\ninterface BufferEntry {\n target: CachedElement;\n value: unknown;\n allFields: Record<string, unknown>;\n revision: MessageRevision | undefined;\n data: PayloadLivePreviewData | undefined;\n valueIdentity: string | undefined;\n}\n\nexport class UpdateScheduler {\n private readonly apply: ApplyUpdate;\n private readonly debounceMs: number;\n private readonly maxWaitMs: number;\n private readonly isVisible: (element: Element) => boolean;\n private readonly gateThresholdValue: number;\n private readonly gateDisabled: boolean;\n private readonly getCacheSize: () => number;\n private readonly onFlush: ((stats: FlushStats) => void) | undefined;\n private readonly scheduleFrame: (callback: FrameRequestCallback) => number;\n private readonly cancelFrame: (handle: number) => void;\n private pending = new Map<Element, BufferEntry>();\n private readonly replay = new Map<Element, BufferEntry>();\n private readonly activeFlushes = new Set<Map<Element, BufferEntry>>();\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private debounceToken = 0;\n private deadlineTimer: ReturnType<typeof setTimeout> | null = null;\n private frameHandle: number | null = null;\n private frameFallback: ReturnType<typeof setTimeout> | null = null;\n private frameToken = 0;\n /** End of the window the leading write opened; inside it a write waits for the debounce. */\n private windowUntil = 0;\n private activeRevision: MessageRevision | null = null;\n private activeRevisionCancelled = false;\n private destroying = false;\n\n constructor(apply: ApplyUpdate, options: UpdateSchedulerOptions) {\n this.apply = apply;\n this.debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;\n this.maxWaitMs = options.maxWaitMs ?? this.debounceMs * 4;\n this.isVisible = options.isVisible;\n this.gateThresholdValue = options.visibilityGateThreshold ?? DEFAULT_VISIBILITY_THRESHOLD;\n this.gateDisabled = options.disableVisibilityGate ?? false;\n this.getCacheSize = options.getCacheSize;\n this.onFlush = options.onFlush;\n this.scheduleFrame =\n options.scheduleFrame ??\n (typeof requestAnimationFrame === 'function'\n ? requestAnimationFrame.bind(globalThis)\n : (callback) =>\n setTimeout(() => {\n callback(performance.now());\n }, 0) as unknown as number);\n this.cancelFrame =\n options.cancelFrame ??\n (typeof cancelAnimationFrame === 'function'\n ? cancelAnimationFrame.bind(globalThis)\n : (handle) => {\n clearTimeout(handle as unknown as ReturnType<typeof setTimeout>);\n });\n }\n\n /** Queue a write; a later write for the same element replaces it until the flush. */\n schedule(update: ScheduledUpdate): void {\n if (this.destroying) return;\n if (update.revision !== undefined) {\n if (this.activeRevisionCancelled) return;\n if (this.activeRevision === null || !sameRevision(update.revision, this.activeRevision)) {\n return;\n }\n }\n const existing = this.pending.get(update.target.element);\n if (existing) {\n existing.value = update.value;\n existing.allFields = update.allFields;\n existing.revision = update.revision;\n existing.data = update.data;\n existing.valueIdentity = update.valueIdentity;\n } else {\n this.pending.set(update.target.element, {\n target: update.target,\n value: update.value,\n allFields: update.allFields,\n revision: update.revision,\n data: update.data,\n valueIdentity: update.valueIdentity,\n });\n }\n this.armDebounce();\n }\n\n /**\n * Make `revision` the sole revision allowed to schedule, flush or replay.\n * Older buffered work is dropped even if the new revision is later cancelled.\n */\n acceptRevision(revision: MessageRevision): void {\n if (this.destroying) return;\n if (this.activeRevision !== null && sameRevision(revision, this.activeRevision)) return;\n if (this.activeRevision !== null && compareRevision(revision, this.activeRevision) < 0) return;\n this.clearWork();\n this.activeRevision = revision;\n this.activeRevisionCancelled = false;\n // Publish ownership before host cancellation can accept or end another owner.\n this.cancelScheduledWork();\n }\n\n /** Cancel buffered work for exactly one revision without reviving its predecessor. */\n cancelRevision(revision: MessageRevision): void {\n if (this.activeRevision === null || !sameRevision(revision, this.activeRevision)) return;\n this.clearWork();\n this.activeRevisionCancelled = true;\n this.cancelScheduledWork();\n }\n\n /** Flush immediately, bypassing the debounce. */\n flushNow(): FlushStats {\n this.cancelScheduledWork();\n return this.flush();\n }\n\n /** Apply the buffered value for an element that scrolled into view. */\n notifyVisible(element: Element): void {\n const entry = this.replay.get(element);\n if (!entry) return;\n this.replay.delete(element);\n if (!this.isCurrent(entry)) return;\n const t0 = performance.now();\n const applied = this.didApply(entry) ? 1 : 0;\n this.onFlush?.(\n this.statsFor(\n entry,\n applied,\n 0,\n performance.now() - t0,\n applied === 1 ? [entry.target.fieldName] : [],\n ),\n );\n }\n\n /**\n * Point buffered work at a rebuilt cache entry for the same element and\n * field. A different field or locale is a different binding: drop the work.\n */\n retarget(target: CachedElement): void {\n this.retargetBuffer(this.pending, target);\n this.retargetBuffer(this.replay, target);\n for (const flush of this.activeFlushes) this.retargetBuffer(flush, target);\n }\n\n forget(element: Element): void {\n this.pending.delete(element);\n this.replay.delete(element);\n for (const flush of this.activeFlushes) flush.delete(element);\n }\n\n /** Cancel timers and drop buffered state without draining it. */\n destroy(): void {\n if (this.destroying) return;\n // Host cancellation must not open another frame while this owner closes.\n this.destroying = true;\n try {\n this.clearWork();\n this.activeRevision = null;\n this.activeRevisionCancelled = false;\n // A restarted scheduler is a quiet page again, not the tail of a burst.\n this.windowUntil = 0;\n this.cancelScheduledWork();\n } finally {\n this.destroying = false;\n }\n }\n\n get pendingCount(): number {\n return this.pending.size;\n }\n\n get replayCount(): number {\n return this.replay.size;\n }\n\n get gateThreshold(): number {\n return this.gateThresholdValue;\n }\n\n get gateActive(): boolean {\n return !this.gateDisabled && this.getCacheSize() > this.gateThresholdValue;\n }\n\n private armDebounce(): void {\n const now = Date.now();\n const opensTheWindow = now >= this.windowUntil;\n this.windowUntil = now + this.debounceMs;\n // The debounce coalesces a burst, and the write that opens one is not yet a\n // burst: it costs a frame, and the window it opens batches what follows.\n // With the merge gone from the common path (see `MergeNeed`), that frame is\n // the whole distance between a keystroke and the page.\n if (opensTheWindow) {\n this.requestFrame();\n return;\n }\n const token = (this.debounceToken += 1);\n const timer = this.debounceTimer;\n this.debounceTimer = null;\n if (timer !== null) clearTimeout(timer);\n // clearTimeout is a host boundary; a reentrant schedule owns a newer token.\n if (this.debounceToken !== token) return;\n const next = setTimeout(() => {\n if (this.debounceToken !== token) return;\n this.debounceTimer = null;\n // The window a leading write opened is usually already empty when it\n // closes; flushing then would report a write nobody made.\n if (this.pending.size > 0) this.requestFrame();\n }, this.debounceMs);\n if (this.debounceToken === token) this.debounceTimer = next;\n // Continuous scheduling (key repeat) must not postpone the flush forever.\n if (this.deadlineTimer === null && this.maxWaitMs > this.debounceMs) {\n this.deadlineTimer = setTimeout(() => {\n this.deadlineTimer = null;\n if (this.pending.size > 0) this.requestFrame();\n }, this.maxWaitMs);\n }\n }\n\n private requestFrame(): void {\n const token = (this.frameToken += 1);\n const handle = this.frameHandle;\n this.frameHandle = null;\n this.clearFrameFallback();\n if (handle !== null) this.cancelFrame(handle);\n if (this.frameToken !== token) return;\n let completed = false;\n // The frame or the fallback, whichever comes first, writes; the other finds the token spent.\n const run = (): void => {\n if (this.frameToken !== token || completed) return;\n completed = true;\n const frame = this.frameHandle;\n this.frameHandle = null;\n this.clearFrameFallback();\n if (frame !== null) this.cancelFrame(frame);\n this.flush();\n };\n const next = this.scheduleFrame(run);\n // An injected scheduler may run the callback synchronously; never publish a spent handle.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (completed || this.frameToken !== token) return;\n this.frameHandle = next;\n this.frameFallback = setTimeout(run, FRAME_FALLBACK_MS);\n }\n\n private clearFrameFallback(): void {\n // clearTimeout ignores undefined, so a null guard here would be a branch without a behaviour.\n clearTimeout(this.frameFallback ?? undefined);\n this.frameFallback = null;\n }\n\n private flush(): FlushStats {\n const t0 = performance.now();\n this.clearDeadline();\n const gateActive = this.gateActive;\n const pending = this.pending;\n this.pending = new Map();\n let applied = 0;\n const appliedFields: string[] = [];\n let deferred = 0;\n let batchEntry: BufferEntry | undefined;\n this.activeFlushes.add(pending);\n try {\n for (const entry of pending.values()) {\n if (!this.isCurrent(entry)) continue;\n const visible =\n !gateActive || this.isVisible(entry.target.element) || nothingToScrollTo(entry.target);\n // The visibility callback is consumer code and may change the revision.\n if (!this.isCurrent(entry)) continue;\n batchEntry ??= entry;\n if (!visible) {\n this.replay.set(entry.target.element, entry);\n deferred += 1;\n continue;\n }\n this.replay.delete(entry.target.element);\n if (this.didApply(entry)) {\n applied += 1;\n appliedFields.push(entry.target.fieldName);\n }\n }\n } finally {\n this.activeFlushes.delete(pending);\n }\n const stats = this.statsFor(\n batchEntry,\n applied,\n deferred,\n performance.now() - t0,\n appliedFields,\n );\n this.onFlush?.(stats);\n return stats;\n }\n\n private isCurrent(entry: BufferEntry): boolean {\n return (\n entry.revision === undefined ||\n (!this.activeRevisionCancelled &&\n this.activeRevision !== null &&\n sameRevision(entry.revision, this.activeRevision))\n );\n }\n\n private didApply(entry: BufferEntry): boolean {\n // Only a runtime-marked callback may report exact `false` as \"no write\".\n // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n const outcome: unknown = this.apply(entry);\n return outcome !== false || !usesNoWriteOutcome(this.apply);\n }\n\n private retargetBuffer(buffer: Map<Element, BufferEntry>, target: CachedElement): void {\n const entry = buffer.get(target.element);\n if (entry === undefined) return;\n if (!hasSameBindingIdentity(entry.target, target)) {\n buffer.delete(target.element);\n return;\n }\n entry.target = target;\n }\n\n private clearWork(): void {\n this.pending.clear();\n this.replay.clear();\n for (const flush of this.activeFlushes) flush.clear();\n }\n\n private statsFor(\n entry: BufferEntry | undefined,\n applied: number,\n deferred: number,\n durationMs: number,\n appliedFields: readonly string[],\n ): FlushStats {\n return {\n applied,\n appliedFields,\n deferred,\n durationMs,\n ...(entry?.revision !== undefined ? { revision: entry.revision } : {}),\n ...(entry?.data !== undefined ? { data: entry.data } : {}),\n };\n }\n\n private clearDeadline(): void {\n if (this.deadlineTimer === null) return;\n clearTimeout(this.deadlineTimer);\n this.deadlineTimer = null;\n }\n\n private cancelScheduledWork(): void {\n const debounceTimer = this.debounceTimer;\n const frameHandle = this.frameHandle;\n // Revoke tokens before calling host cancellation, so a hook that\n // schedules newer work is not clobbered by this older cleanup.\n this.debounceToken += 1;\n this.frameToken += 1;\n this.debounceTimer = null;\n this.frameHandle = null;\n this.clearDeadline();\n this.clearFrameFallback();\n if (debounceTimer !== null) clearTimeout(debounceTimer);\n if (frameHandle !== null) this.cancelFrame(frameHandle);\n }\n}\n\n/**\n * An empty-field anchor that is hidden, or has no size, never scrolls into\n * view: the gate would hold the one write that can show it for good. Asked\n * after the visibility callback, so only of an anchor not seen yet.\n */\nfunction nothingToScrollTo(target: CachedElement): boolean {\n if (target.hidesWhenEmpty !== true) return false;\n const { element } = target;\n if (element.hasAttribute('hidden')) return true;\n const box = element.getBoundingClientRect();\n return box.width === 0 || box.height === 0;\n}\n\nfunction compareRevision(a: MessageRevision, b: MessageRevision): number {\n if (a.generation !== b.generation) return a.generation - b.generation;\n return a.revision - b.revision;\n}\n","/**\n * `LivePreviewRuntime` owns the primitives and hands accepted messages to the update pipeline.\n * It never speaks postMessage or walks the DOM during an update. See ADR 0004.\n */\n\nimport { createA11y, defaultSendReady } from './runtime-wiring';\nimport { BindingWriter } from './binding-writer';\nimport { ElementCache, hasSameBindingIdentity } from './cache';\nimport { DataMerger } from './data-merger';\nimport type { DiagnosticCode } from './diagnostic-codes';\nimport { isolateDiagnostic, noopDiagnostic, safeConsoleWarn } from './diagnostics';\nimport { resolveUnfaithfulPatchMode } from './fidelity';\nimport { buildInspection } from './inspection/snapshot';\nimport type { LivePreviewInspection } from './inspection/types';\nimport { markNoWriteCallback } from './internal-outcome';\nimport { isInsideIsland } from './islands';\nimport { MessageBus } from './message-bus';\nimport { ObserverManager } from './observers';\nimport { LifetimeScope } from './lifetime-scope';\nimport type { ProtocolNegotiation } from './protocol-version';\nimport type { RuntimeOptions } from './runtime-options';\nimport { RuntimeState, type RuntimeDeps } from './runtime-state';\nimport { isDocumentRoot, readDocumentBody, startWhenReady, type StartupHost } from './startup';\nimport { ConnectionState, HeartbeatTimer } from './state';\nimport type { CachedElement } from './types';\nimport { UpdatePipeline } from './update-pipeline';\nimport { DEFAULT_DEBOUNCE_MS, UpdateScheduler } from './update-scheduler';\n\nexport type { RuntimeOptions } from './runtime-options';\nexport { resolveFieldValue } from './field-value';\n\n/** Re-broadcast `ready` a few times to absorb admin-side init latency. */\nconst READY_RETRY_DELAYS_MS = [0, 500, 1000, 2000] as const;\n\nexport class LivePreviewRuntime {\n private readonly deps: RuntimeDeps;\n private readonly state = new RuntimeState();\n private readonly pipeline: UpdatePipeline;\n private readonly writer: BindingWriter;\n private rootSentinel: MutationObserver | null = null;\n /** The session's resources, released together in reverse order when it ends (ADR 0005, 2.1 note). */\n private scope: LifetimeScope | null = null;\n /** Prevent a cleanup callback from opening a session inside the one being torn down. */\n private closingSession = false;\n private observedRoot: Node | null = null;\n private replayRetainedOnStart = false;\n\n constructor(options: RuntimeOptions) {\n const { emitter, renderers } = options;\n const log = options.log === undefined ? noopDiagnostic : isolateDiagnostic(options.log);\n const warn = options.warn === undefined ? safeConsoleWarn : isolateDiagnostic(options.warn);\n const root = options.root ?? (typeof document !== 'undefined' ? document : undefined);\n // Name the missing option here instead of failing at the first DOM read in start().\n if (root === undefined) throw new Error('LivePreviewRuntime: no document; pass options.root');\n // Bindings inside a hydrated island are the island's business (ADR 0008 §4).\n const cache = new ElementCache({ filter: (element) => !isInsideIsland(element) });\n const observers = new ObserverManager(\n {\n onStructuralChange: () => {\n this.rebuildCache();\n },\n onIslandHydrated: (island) => {\n this.pipeline.reapplyNavigationIslands([island], true);\n },\n onVisibilityChange: (element, visible) => {\n if (visible) scheduler.notifyVisible(element);\n },\n },\n options.intersectionRootMargin !== undefined\n ? { intersectionRootMargin: options.intersectionRootMargin }\n : {},\n );\n const scheduler = new UpdateScheduler(\n markNoWriteCallback((update) => this.writer.apply(update)),\n {\n ...(options.debounceMs !== undefined ? { debounceMs: options.debounceMs } : {}),\n ...(options.disableVisibilityGate !== undefined\n ? { disableVisibilityGate: options.disableVisibilityGate }\n : {}),\n ...(options.visibilityGateThreshold !== undefined\n ? { visibilityGateThreshold: options.visibilityGateThreshold }\n : {}),\n isVisible: (element) => observers.isVisible(element),\n getCacheSize: () => cache.elementCount,\n onFlush: (stats) => {\n this.pipeline.onFlush(stats);\n },\n },\n );\n const bus = new MessageBus(options.originMatcher, {\n onUpdate: (message, origin, revision) => {\n this.pipeline.handleUpdate(message, origin, revision);\n },\n onReplay: (message, origin, revision) => {\n this.pipeline.handleReplay(message, origin, revision);\n },\n onDocumentEvent: () => {\n this.state.protocol.observe(['document-events'], log);\n void emitter.emit('documentSave', { timestamp: Date.now() });\n this.pipeline.documentSaved();\n },\n onFocusField: (field) => {\n if (this.deps.revealEditedField) this.pipeline.revealField(field);\n },\n onInvalid: (reason, origin) => {\n if (reason === 'token') {\n const error = new Error(`Preview token rejected (origin: ${origin})`);\n void emitter.emit('error', { error, context: 'token', code: 'LP0502' });\n }\n // An unknown shape from a trusted origin is protocol drift, not an attack.\n // Report it here once: without `debug`, no other boundary makes it visible.\n if ((reason === 'shape' || reason === 'type') && !this.state.warnedProtocolShape) {\n this.state.warnedProtocolShape = true;\n warn(\n `[live-preview] LP0503: ${origin} posted a message this runtime does not recognise ` +\n `(${reason === 'type' ? 'unknown message type' : 'unexpected shape'}); it was ` +\n 'ignored. A newer Payload or a custom sender: check that the versions match.',\n );\n }\n // This refusal default changed in 2.0. An admin posting from outside the\n // framing or opening window silently stops updates, so report it once.\n if (reason === 'source' && !this.state.warnedForeignSource) {\n this.state.warnedForeignSource = true;\n warn(\n `[live-preview] LP0501: a message from ${origin} was ignored because it did not come ` +\n 'from the window that framed or opened this page. `eventSourcePolicy` is ' +\n \"'parent-or-opener' by default since 2.0, where 1.x accepted any window on a \" +\n \"trusted origin. Set `eventSourcePolicy: 'any'` if the admin posts from elsewhere.\",\n );\n }\n log('LP0501 message rejected:', reason, origin);\n },\n ...(options.validateToken !== undefined ? { validateToken: options.validateToken } : {}),\n ...(options.eventSourcePolicy !== undefined\n ? { sourcePolicy: options.eventSourcePolicy }\n : {}),\n });\n const merge = options.dataMerge;\n this.deps = {\n emitter,\n cache,\n observers,\n scheduler,\n bus,\n connection: new ConnectionState(),\n heartbeat: new HeartbeatTimer({\n ...(options.heartbeatMs !== undefined ? { timeoutMs: options.heartbeatMs } : {}),\n onTimeout: () => {\n this.onHeartbeatTimeout();\n },\n }),\n renderers,\n resolveRenderer: options.resolveRenderer ?? ((fieldType) => renderers[fieldType]),\n transformValue: options.transformValue,\n renderRichText: options.renderRichText,\n sanitizerPolicy: options.sanitizerPolicy,\n root,\n readyTargets:\n typeof options.readyTargets === 'function'\n ? options.readyTargets\n : (\n (targets) => (): readonly string[] =>\n targets\n )(options.readyTargets),\n sendReady: options.sendReady ?? defaultSendReady,\n onHeartbeatTimeout: options.onHeartbeatTimeout,\n log,\n warn,\n a11y: createA11y(options),\n serverURL: merge?.serverURL,\n merger:\n merge === undefined\n ? null\n : new DataMerger({\n serverURL: merge.serverURL,\n ...(merge.apiRoute !== undefined ? { apiRoute: merge.apiRoute } : {}),\n ...(merge.depth !== undefined ? { depth: merge.depth } : {}),\n ...(merge.fetchFn !== undefined ? { fetchFn: merge.fetchFn } : {}),\n log,\n }),\n mergeWindowMs: options.debounceMs ?? DEFAULT_DEBOUNCE_MS,\n scopeBindingsByOwner: options.scopeBindingsByOwner === true,\n subfieldCoverage: options.subfieldCoverage ?? 'descendant',\n lockedOrigin: options.lockedOrigin ?? ((): undefined => undefined),\n skipUnchanged: options.skipUnchanged === true,\n dependencies: options.dependencies ?? {},\n strategies: options.strategies ?? {},\n revealEditedField: options.revealEditedField === true,\n onUnfaithfulPatch: resolveUnfaithfulPatchMode(options),\n autoBind: options.autoBind ?? 'off',\n hydration: options.hydration,\n };\n this.writer = new BindingWriter(this.deps, this.state);\n this.pipeline = new UpdatePipeline(this.deps, this.state, () => {\n this.rebuildCache();\n });\n }\n\n /**\n * Build the cache, attach observers and listeners, broadcast `ready`.\n * Returns `false` when already started. While the document is still\n * parsing the real start waits for `DOMContentLoaded`; on a page that\n * declares hydration it then waits for React's first commit as well\n * (ADR 0015), so the first write lands on markup React keeps.\n */\n start(): boolean {\n const { state } = this;\n if (state.isRunning() || this.closingSession) return false;\n if (state.suspended) this.replayRetainedOnStart = true;\n state.started = true;\n state.suspended = false;\n this.openScope();\n try {\n startWhenReady(this.startupHost());\n return true;\n } catch (error) {\n this.rollbackFailedStart();\n throw error;\n }\n }\n\n /** The runtime as the startup chain sees it (./startup). */\n private startupHost(): StartupHost {\n const { state, deps } = this;\n return {\n root: deps.root,\n hydration: deps.hydration,\n isRunning: () => state.isRunning(),\n defer: (cancel) => {\n state.deferredStart = cancel;\n this.scope?.own(() => {\n if (state.deferredStart !== cancel) return;\n state.deferredStart = null;\n cancel();\n });\n },\n later: (step) => {\n state.deferredStart = null;\n try {\n step();\n } catch (error) {\n // start() already returned; roll back and report through the error event.\n this.rollbackFailedStart();\n this.reportError(error, 'startup', 'LP0605');\n }\n },\n hydrated: (hydration) => {\n state.hydration = hydration;\n },\n warn: deps.warn,\n startNow: () => {\n this.startNow();\n },\n };\n }\n\n private startNow(): void {\n const { state, deps } = this;\n if (!state.isRunning()) return;\n const observerRoot: Node | null = isDocumentRoot(deps.root)\n ? readDocumentBody(deps.root)\n : deps.root;\n if (observerRoot === null) throw new Error('LivePreviewRuntime: document.body unavailable');\n deps.observers.start(observerRoot);\n this.observedRoot = observerRoot;\n this.watchRootReplacement();\n // Observers first: the cache scan registers its elements with them.\n this.buildCacheAndObserve();\n if (!state.isRunning()) return;\n deps.bus.attach();\n void deps.emitter.emitWhile('init', { timestamp: Date.now() }, () => state.isRunning());\n if (!state.isRunning()) return;\n const recoverSuspendedSession = this.replayRetainedOnStart;\n this.replayRetainedOnStart = false;\n const suspendedHeartbeatExpired = recoverSuspendedSession && deps.heartbeat.resume();\n if (!state.isRunning()) return;\n if (recoverSuspendedSession && !suspendedHeartbeatExpired) {\n state.forgetOwedWork();\n state.merges.resetRawChanges();\n state.unfaithfulPatches = [];\n state.revealer.reset();\n state.lastAppliedIdentity = new WeakMap();\n state.changes.reset();\n state.navigationReplayPending = true;\n if (!deps.bus.replayLastAccepted()) state.navigationReplayPending = false;\n if (!state.isRunning()) return;\n }\n for (const delay of READY_RETRY_DELAYS_MS) {\n if (!state.isRunning()) return;\n if (delay === 0) {\n deps.sendReady(deps.readyTargets());\n } else {\n state.readyTimers.push(\n setTimeout(() => {\n if (state.isRunning()) this.sendReadyAfterStart();\n }, delay),\n );\n }\n }\n }\n\n /**\n * Release the message ingress and observers but keep the configuration, so\n * `start()` brings the same instance back — what a back/forward-cache\n * restore needs, since it re-runs no scripts.\n */\n suspend(): boolean {\n if (!this.state.isRunning()) return false;\n const wasConnected = this.release();\n this.state.suspended = true;\n if (wasConnected) {\n void this.deps.emitter.emit('disconnect', { reason: 'unload', timestamp: Date.now() });\n }\n return true;\n }\n\n destroy(): void {\n const { state, deps } = this;\n if (!state.isRunning() && !state.suspended) return;\n const wasConnected = state.isRunning() ? this.release() : false;\n state.suspended = false;\n this.replayRetainedOnStart = false;\n deps.bus.forgetLastAccepted();\n if (wasConnected) {\n void deps.emitter.emit('disconnect', { reason: 'destroy', timestamp: Date.now() });\n }\n deps.a11y?.detach();\n void deps.emitter.emit('destroy', { timestamp: Date.now() });\n }\n\n /** One scope per session: destroy, suspend and failed starts invalidate it and close in reverse. */\n private openScope(): void {\n const { state, deps } = this;\n const scope = new LifetimeScope(deps.log);\n scope.own(() => {\n deps.merger?.destroy();\n state.merges.destroy();\n });\n scope.own(() => {\n deps.scheduler.destroy();\n });\n scope.own(() => {\n deps.observers.stop();\n });\n scope.own(() => {\n this.rootSentinel?.disconnect();\n this.rootSentinel = null;\n this.observedRoot = null;\n });\n scope.own(() => {\n state.abortStrategies();\n });\n scope.own(() => {\n deps.bus.detach();\n });\n scope.own(() => {\n deps.heartbeat.stop();\n });\n scope.own(() => {\n for (const handle of state.readyTimers) clearTimeout(handle);\n state.readyTimers.length = 0;\n });\n this.scope = scope;\n }\n\n private release(): boolean {\n const { state, deps } = this;\n state.display.end();\n state.activeUpdate = null;\n state.navigationBindingReplay = false;\n state.started = false;\n const closingScope = this.scope;\n this.scope = null;\n this.closingSession = true;\n try {\n closingScope?.close();\n } finally {\n this.closingSession = false;\n }\n deps.cache.clear();\n return deps.connection.markDisconnected();\n }\n\n private rollbackFailedStart(): void {\n this.release();\n try {\n this.deps.a11y?.detach();\n } catch (error) {\n this.deps.log('runtime cleanup failed:', error);\n }\n }\n\n /** Re-scan the DOM and re-register every binding. */\n refreshCache(): void {\n if (!this.state.isRunning()) return;\n this.state.revealer.reset();\n if (!this.followReplacedRoot()) this.rebuildCache();\n }\n\n /**\n * Supersede work owned by the route being left, then rescan and locally\n * replay the last accepted snapshot. The ordinary public refresh keeps\n * buffered work; only a confirmed router commit crosses this boundary.\n * @internal\n */\n navigationCommit(): void {\n const { state, deps } = this;\n // Before startup owns the bus/cache, its parse/hydration wait scans and sends the handshake.\n if (!state.isRunning() || state.deferredStart !== null) return;\n // Finish destructive cleanup before opening the next ingress generation.\n // Abort/fetch listeners may synchronously post a newer document; the second\n // cancellation retains it instead of letting this older cleanup tear it down.\n this.cancelActiveUpdate(true);\n deps.merger?.destroy();\n state.merges.destroy();\n state.abortStrategies();\n this.cancelActiveUpdate(true);\n state.forgetOwedWork();\n state.merges.resetRawChanges();\n state.unfaithfulPatches = [];\n state.revealer.reset();\n // A retained element's previous value identity says nothing about the new route's DOM.\n state.lastAppliedIdentity = new WeakMap();\n state.changes.reset();\n if (!state.isRunning()) return;\n deps.bus.advanceGeneration();\n state.navigationReplayPending = true;\n if (!this.followReplacedRoot()) this.rebuildCache();\n if (!state.isRunning()) return;\n deps.bus.replayLastAccepted();\n if (state.isRunning()) this.sendReadyAfterStart();\n }\n\n /** Some routers swap `document.body` on navigation, leaving observers on a detached node. */\n private watchRootReplacement(): void {\n const { root } = this.deps;\n if (!isDocumentRoot(root) || typeof MutationObserver === 'undefined') return;\n this.rootSentinel?.disconnect();\n this.rootSentinel = new MutationObserver(() => {\n this.followReplacedRoot();\n });\n this.rootSentinel.observe(root.documentElement, { childList: true });\n }\n\n /** Rebind observers and cache to a replaced body; returns whether it did. */\n private followReplacedRoot(): boolean {\n const { root } = this.deps;\n if (!this.state.isRunning() || !isDocumentRoot(root)) return false;\n const body = readDocumentBody(root);\n if (body === null || body === this.observedRoot) return false;\n this.observedRoot = body;\n this.deps.observers.start(body);\n this.rebuildCache();\n return true;\n }\n\n get status(): 'disconnected' | 'connecting' | 'connected' {\n return this.deps.connection.status;\n }\n\n get cache(): ElementCache {\n return this.deps.cache;\n }\n\n get updateCount(): number {\n return this.state.updateCount;\n }\n\n /** Negotiated protocol view, `min(library, remote)`. */\n get protocol(): ProtocolNegotiation {\n return this.state.protocol.negotiation;\n }\n\n /** Point-in-time read of runtime state for diagnosing a preview that is not updating. */\n inspect(): LivePreviewInspection {\n return buildInspection(this.deps, this.state);\n }\n\n private buildCacheAndObserve(): void {\n const { state, deps } = this;\n if (!state.isRunning()) return;\n const stats = deps.cache.buildFromRoot(deps.root);\n deps.log('cache', stats);\n if (!state.isRunning()) return;\n void deps.emitter.emitWhile('cacheRefresh', stats, () => state.isRunning());\n if (!state.isRunning()) return;\n for (const entry of deps.cache.values()) {\n if (!state.isRunning()) return;\n deps.observers.observeElement(entry.element);\n }\n }\n\n private rebuildCache(): void {\n const { state, deps } = this;\n if (!state.isRunning()) return;\n const previous = new Map<Element, CachedElement>();\n const previousIslandOwners = deps.cache.islandOwners;\n const previousNavigationRoots = new Set(deps.cache.navigationReplayRoots);\n for (const entry of deps.cache.values()) {\n previous.set(entry.element, entry);\n deps.observers.unobserveElement(entry.element);\n }\n this.buildCacheAndObserve();\n if (!state.isRunning()) return;\n const added = new Set<Element>(\n deps.cache.navigationReplayRoots.filter((root) => !previousNavigationRoots.has(root)),\n );\n // Buffered work survives only while the same element is bound to the same field.\n for (const entry of deps.cache.values()) {\n const before = previous.get(entry.element);\n if (before !== undefined && hasSameBindingIdentity(before, entry)) {\n deps.scheduler.retarget(entry);\n } else {\n deps.scheduler.forget(entry.element);\n added.add(entry.element);\n }\n previous.delete(entry.element);\n }\n for (const removed of previous.values()) deps.scheduler.forget(removed.element);\n if (added.size > 0) this.pipeline.reapplyNavigationBindings(added);\n const addedIslands = deps.cache.islands.filter(\n (island) =>\n !previousIslandOwners.has(island) ||\n (deps.scopeBindingsByOwner &&\n previousIslandOwners.get(island) !== deps.cache.islandOwners.get(island)),\n );\n if (addedIslands.length > 0) this.pipeline.reapplyNavigationIslands(addedIslands);\n }\n\n private onHeartbeatTimeout(): void {\n const { state, deps } = this;\n if (!state.isRunning()) return;\n // Cleanup belongs to the expiring generation; a synchronous abort listener cannot\n // reconnect into the generation this same cleanup is about to destroy.\n this.cancelActiveUpdate(false);\n deps.merger?.destroy();\n state.merges.destroy();\n state.abortStrategies();\n this.cancelActiveUpdate(false);\n if (!state.isRunning()) return;\n deps.bus.advanceGeneration();\n deps.bus.forgetLastAccepted();\n state.navigationBindingReplay = false;\n const wasConnected = deps.connection.markDisconnected();\n // Release the origin lock before the disconnect event: a listener may\n // reconnect from another allow-listed origin synchronously.\n try {\n deps.onHeartbeatTimeout?.();\n } catch (error) {\n deps.log('heartbeat:', error);\n }\n if (!state.isRunning()) return;\n if (wasConnected && this.isIdleDisconnected()) {\n deps.a11y?.announceDisconnected();\n void deps.emitter.emitWhile('disconnect', { reason: 'timeout', timestamp: Date.now() }, () =>\n this.isIdleDisconnected(),\n );\n if (!state.isRunning()) return;\n if (this.isIdleDisconnected()) deps.log('connection', 'connected', '→', 'disconnected');\n if (!state.isRunning()) return;\n }\n this.sendReadyAfterStart();\n }\n\n /** Cancel whichever revision owns work now; cleanup callbacks may install a newer one. */\n private cancelActiveUpdate(countSuperseded: boolean): void {\n const { state, deps } = this;\n const active = state.activeUpdate;\n state.display.end();\n state.activeUpdate = null;\n if (active === null) return;\n active.cancelled = true;\n deps.scheduler.cancelRevision(active.revision);\n if (countSuperseded && !active.completed && active.countsAsUpdate) {\n state.supersededCount += 1;\n }\n }\n\n /** Later handshake retries are best-effort and must not escape timer callbacks. */\n private sendReadyAfterStart(): void {\n try {\n this.deps.sendReady(this.deps.readyTargets());\n } catch (error) {\n this.reportError(error, 'ready', 'LP0606');\n }\n }\n\n private reportError(cause: unknown, context: string, code: DiagnosticCode): void {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n void this.deps.emitter.emit('error', { error, context, code });\n }\n\n private isIdleDisconnected(): boolean {\n return (\n this.state.isRunning() &&\n this.deps.connection.status === 'disconnected' &&\n this.state.activeUpdate === null\n );\n }\n}\n","/** Assembles the `inspect()` snapshot. Reads state only; sends nothing anywhere. */\n\nimport { VERSION } from '../../version';\nimport { detectProtocolProfile } from '../protocol-profile';\nimport type { RuntimeDeps, RuntimeState } from '../runtime-state';\nimport type { LivePreviewInspection } from './types';\n\nexport function buildInspection(deps: RuntimeDeps, state: RuntimeState): LivePreviewInspection {\n const { cache, scheduler } = deps;\n const negotiation = state.protocol.negotiation;\n const active = state.activeUpdate;\n const flush = state.lastFlush;\n const fieldNames: string[] = [];\n const owners = new Set<string>();\n const guessed: { field: string; matched: string; attribute: string | undefined }[] = [];\n for (const [fieldName, bindings] of cache.entries()) {\n fieldNames.push(fieldName);\n for (const binding of bindings) {\n if (binding.owner !== undefined) owners.add(binding.owner);\n if (binding.guessed !== undefined) {\n guessed.push({\n field: fieldName,\n matched: binding.guessed,\n attribute:\n binding.targetAttribute ?? (binding.element.tagName === 'IMG' ? 'src' : undefined),\n });\n }\n }\n }\n return {\n version: VERSION,\n started: state.started,\n status: deps.connection.status,\n origins: { trusted: [...deps.readyTargets()], locked: deps.lockedOrigin() },\n protocol: {\n ours: negotiation.ours,\n theirs: negotiation.theirs,\n negotiated: negotiation.negotiated,\n capabilities: [...negotiation.capabilities].sort(),\n observed: [...negotiation.observed].sort(),\n profile: detectProtocolProfile(negotiation.observed).name,\n },\n revisions: {\n accepted: state.updateCount,\n superseded: state.supersededCount,\n completed: state.completedCount,\n skippedUnchanged: state.skippedUnchangedCount,\n active: active === null ? undefined : active.revision.revision,\n display: state.display.snapshot(),\n },\n bindings: {\n elements: cache.elementCount,\n fields: cache.fieldCount,\n fieldNames: fieldNames.sort(),\n absentFields: [...state.absentFields].sort(),\n orphanFields: [...state.warnedOrphanFields].sort(),\n ownerScoped: deps.scopeBindingsByOwner,\n owners: [...owners].sort(),\n guessed: guessed.sort((left, right) => left.field.localeCompare(right.field)),\n autoBind: { mode: deps.autoBind, searchMs: state.autoBindSearchMs },\n },\n route: { handler: deps.strategies.route !== undefined, ...state.routeStats },\n fidelity: {\n mode: deps.onUnfaithfulPatch,\n canEscalate: deps.strategies.fragment !== undefined || deps.strategies.route !== undefined,\n unfaithful: state.unfaithfulCount,\n escalated: state.escalatedCount,\n fields: [...state.unfaithfulFields].sort(),\n },\n hydration: { mode: deps.hydration ?? 'off', state: state.hydration },\n fragments: {\n handler: deps.strategies.fragment !== undefined,\n inFlight: active?.pendingFragments ?? 0,\n ...state.fragmentStats,\n },\n scheduler: {\n pending: scheduler.pendingCount,\n deferred: scheduler.replayCount,\n visibilityGateThreshold: scheduler.gateThreshold,\n visibilityGateActive: scheduler.gateActive,\n lastFlush:\n flush === null\n ? undefined\n : {\n applied: flush.applied,\n appliedFields: flush.appliedFields,\n deferred: flush.deferred,\n durationMs: flush.durationMs,\n },\n },\n plugins: [],\n renderers: Object.keys(deps.renderers).sort(),\n };\n}\n","/**\n * Per-instance typed emitter: handlers run sequentially in registration order,\n * may be async, and a throwing one is logged and isolated. See ADR 0002.\n */\n\nimport type { EventHandler, LivePreviewEventMap, Unsubscribe } from './types';\nimport { safeConsoleError } from '@core/diagnostics';\n\ntype AnyHandler = EventHandler<unknown>;\n\n// `object`, not `Record<string, unknown>`: interfaces with readonly and\n// exact-optional properties must be usable as maps.\nexport class EventEmitter<TMap extends object = LivePreviewEventMap> {\n readonly #regular = new Map<keyof TMap, Set<AnyHandler>>();\n readonly #once = new Map<keyof TMap, Set<AnyHandler>>();\n\n on<E extends keyof TMap>(event: E, handler: EventHandler<TMap[E]>): Unsubscribe {\n return this.#register(this.#regular, event, handler as AnyHandler);\n }\n\n once<E extends keyof TMap>(event: E, handler: EventHandler<TMap[E]>): Unsubscribe {\n return this.#register(this.#once, event, handler as AnyHandler);\n }\n\n off<E extends keyof TMap>(event: E, handler: EventHandler<TMap[E]>): void {\n this.#remove(this.#regular, event, handler as AnyHandler);\n this.#remove(this.#once, event, handler as AnyHandler);\n }\n\n /** Dispatch to every handler: regular ones first, then `once` handlers. */\n async emit<E extends keyof TMap>(event: E, payload: TMap[E]): Promise<void> {\n await this.#emitSequential(event, payload);\n }\n\n /**\n * Dispatch while `shouldContinue()` holds — checked around every handler, so\n * an obsolete transaction cannot resume across an await.\n * @internal\n */\n async emitWhile<E extends keyof TMap>(\n event: E,\n payload: TMap[E],\n shouldContinue: () => boolean,\n ): Promise<boolean> {\n return this.#emitSequential(event, payload, shouldContinue);\n }\n\n async #emitSequential<E extends keyof TMap>(\n event: E,\n payload: TMap[E],\n shouldContinue?: () => boolean,\n ): Promise<boolean> {\n const eligible = (): boolean => shouldContinue?.() ?? true;\n if (!eligible()) return false;\n const regular = this.#regular.get(event);\n if (regular) {\n for (const handler of [...regular]) {\n if (!eligible()) return false;\n await this.#invoke(handler, payload, event);\n if (!eligible()) return false;\n }\n }\n if (!eligible()) return false;\n const once = this.#once.get(event);\n if (once && once.size > 0) {\n const snapshot = [...once];\n this.#once.delete(event);\n for (const handler of snapshot) {\n if (!eligible()) return false;\n await this.#invoke(handler, payload, event);\n if (!eligible()) return false;\n }\n }\n return eligible();\n }\n\n /** Registered handlers for `event`, `on` and `once` together. */\n listenerCount(event: keyof TMap): number {\n return (this.#regular.get(event)?.size ?? 0) + (this.#once.get(event)?.size ?? 0);\n }\n\n /** Remove every handler, or only those of `event`. */\n removeAllListeners(event?: keyof TMap): void {\n if (event === undefined) {\n this.#regular.clear();\n this.#once.clear();\n return;\n }\n this.#regular.delete(event);\n this.#once.delete(event);\n }\n\n /** Event names with at least one handler. */\n eventNames(): (keyof TMap)[] {\n const names = new Set<keyof TMap>();\n for (const key of this.#regular.keys()) names.add(key);\n for (const key of this.#once.keys()) names.add(key);\n return [...names];\n }\n\n #register(\n bucket: Map<keyof TMap, Set<AnyHandler>>,\n event: keyof TMap,\n handler: AnyHandler,\n ): Unsubscribe {\n let set = bucket.get(event);\n if (!set) {\n set = new Set();\n bucket.set(event, set);\n }\n set.add(handler);\n return () => {\n this.#remove(bucket, event, handler);\n };\n }\n\n #remove(bucket: Map<keyof TMap, Set<AnyHandler>>, event: keyof TMap, handler: AnyHandler): void {\n const set = bucket.get(event);\n if (set === undefined) return;\n set.delete(handler);\n if (set.size === 0) bucket.delete(event);\n }\n\n async #invoke(handler: AnyHandler, payload: unknown, event: keyof TMap): Promise<void> {\n try {\n await handler(payload);\n } catch (err) {\n const label =\n typeof event === 'string' || typeof event === 'number' ? String(event) : '<event>';\n safeConsoleError(`[live-preview] LP0601: handler for \"${label}\" threw:`, err);\n }\n }\n}\n","/**\n * Where the runtime is running: framed, opened, or on a developer's machine.\n * Nothing reads bundler-injected variables; a Vite consumer passes\n * `import.meta.env.X` explicitly (docs/astro.md).\n * @internal\n */\n\nexport function isInIframe(): boolean {\n if (typeof window === 'undefined') return false;\n try {\n return window.self !== window.top;\n } catch {\n // A cross-origin parent throws on the comparison; that is an iframe.\n return true;\n }\n}\n\n/** @internal */\nexport function isInPopup(): boolean {\n if (typeof window === 'undefined') return false;\n return window.opener != null;\n}\n\n/** An iframe or a popup; top-level navigation never starts the preview. @internal */\nexport function isInPreviewContext(): boolean {\n return isInIframe() || isInPopup();\n}\n\n/** Under Node, `NODE_ENV !== 'production'`; in a browser the hostname, which is the only signal a bundle has. @internal */\nexport function isDevMode(): boolean {\n const nodeEnv = readNodeEnv();\n if (nodeEnv !== undefined) return nodeEnv !== 'production';\n if (typeof window !== 'undefined') {\n const host = window.location.hostname;\n return host === 'localhost' || host === '127.0.0.1';\n }\n return false;\n}\n\nfunction readNodeEnv(): string | undefined {\n if (typeof process === 'undefined') return undefined;\n const value = process.env['NODE_ENV'];\n return typeof value === 'string' ? value : undefined;\n}\n","/**\n * Which admin origins the runtime trusts: explicit ones always, the\n * `document.referrer` origin only when none is configured, any localhost port\n * in development. See docs/security.md §1. The handshake goes to the trusted\n * origins, and to guessed localhost ports only while the browser names no parent.\n */\n\nimport { isDevMode, isInIframe } from './environment';\n\nconst LOCALHOST_PATTERN = /^https?:\\/\\/(localhost|127\\.0\\.0\\.1)(?::\\d+)?$/i;\nconst VALID_ORIGIN_PATTERN = /^https?:\\/\\/[^/?#\\s]+$/i;\n\n/** Ports the handshake broadcasts to when the localhost pattern is on; matching itself is unrestricted. */\nconst LOCALHOST_HANDSHAKE_PORTS: readonly number[] = [\n 3000, 3001, 3333, 4000, 4321, 5000, 5173, 5174, 8000, 8080, 8888, 9000,\n];\n\nexport interface OriginDetectorOptions {\n /** Explicit origins to trust. Always allowed. */\n readonly additionalOrigins?: readonly string[];\n /** Set to `false` to ignore `document.referrer`. */\n readonly enableReferrerDetection?: boolean;\n /** Set to `false` to ignore the localhost pattern even in development. */\n readonly enableLocalhostMatching?: boolean;\n /** Override dev-mode detection. */\n readonly forceDevMode?: boolean;\n /** Override `document.referrer` for tests. */\n readonly referrer?: string;\n}\n\nconst enum OriginSlot {\n ExplicitOrigins,\n ReferrerOrigin,\n AllowLocalhost,\n ReferrerWasAvailable,\n LockedOrigin,\n ParentOrigin,\n}\n\ntype OriginState = [\n explicitOrigins: ReadonlySet<string>,\n referrerOrigin: string | undefined,\n allowLocalhost: boolean,\n referrerWasAvailable: boolean,\n lockedOrigin: string | undefined,\n parentOrigin: string | undefined,\n];\n\n/**\n * The framing parent's origin, where the browser names it: Chromium and WebKit\n * do (`location.ancestorOrigins`), Firefox does not. Never a trust source, only\n * where the handshake is worth sending.\n */\nfunction readParentOrigin(): string | undefined {\n if (typeof location === 'undefined') return undefined;\n const ancestors = (location as { readonly ancestorOrigins?: ArrayLike<string> }).ancestorOrigins;\n return ancestors?.[0];\n}\n\n/** The trusted-origin policy: the union of the candidate sources, narrowed to one by `lockOrigin()`. */\nexport class OriginDetector {\n readonly #state: OriginState;\n\n constructor(options: OriginDetectorOptions = {}) {\n const explicit = new Set<string>();\n for (const origin of options.additionalOrigins ?? []) {\n const normalised = normaliseOrigin(origin);\n if (normalised !== undefined) explicit.add(normalised);\n }\n let referrerOrigin: string | undefined;\n if (options.enableReferrerDetection ?? true) {\n const referrer =\n options.referrer ?? (typeof document !== 'undefined' ? document.referrer : '');\n if (referrer.length > 0) {\n try {\n const origin = new URL(referrer).origin;\n if (origin && origin !== 'null') referrerOrigin = origin;\n } catch {\n // opaque referrer\n }\n }\n }\n const allowLocalhost =\n (options.enableLocalhostMatching ?? true) && (options.forceDevMode ?? isDevMode());\n this.#state = [\n explicit,\n referrerOrigin,\n allowLocalhost,\n referrerOrigin !== undefined,\n undefined,\n readParentOrigin(),\n ];\n }\n\n /** Whether `origin` is trusted: the locked origin alone once locked, otherwise the policy above. */\n matches(origin: string): boolean {\n if (origin.length === 0 || origin === 'null') return false;\n if (this.#state[OriginSlot.LockedOrigin] !== undefined) {\n return origin === this.#state[OriginSlot.LockedOrigin];\n }\n if (this.#state[OriginSlot.ExplicitOrigins].has(origin)) return true;\n // The referrer is a fallback, not a union member: any embedder lands there.\n if (\n this.#state[OriginSlot.ExplicitOrigins].size === 0 &&\n this.#state[OriginSlot.ReferrerOrigin] !== undefined &&\n origin === this.#state[OriginSlot.ReferrerOrigin]\n ) {\n return true;\n }\n if (this.#state[OriginSlot.AllowLocalhost] && LOCALHOST_PATTERN.test(origin)) return true;\n return false;\n }\n\n /** Narrow trust to `origin`; refused (`false`) when it is not currently trusted. */\n lockOrigin(origin: string): boolean {\n if (!this.matches(origin)) return false;\n this.#state[OriginSlot.LockedOrigin] = origin;\n return true;\n }\n\n /** Release the lock (heartbeat timeout) so another allow-listed origin may reconnect. Returns the previous lock. */\n unlockOrigin(): string | undefined {\n const previous = this.#state[OriginSlot.LockedOrigin];\n this.#state[OriginSlot.LockedOrigin] = undefined;\n return previous;\n }\n\n get lockedOrigin(): string | undefined {\n return this.#state[OriginSlot.LockedOrigin];\n }\n\n /**\n * Every origin the `ready` handshake is broadcast to. The localhost pattern\n * expands to the common dev ports, a guess that costs a console error per\n * wrong port, so a parent the browser names replaces it: that origin when the\n * pattern trusts it, none when it is not on localhost.\n */\n enumerate(): string[] {\n if (this.#state[OriginSlot.LockedOrigin] !== undefined) {\n return [this.#state[OriginSlot.LockedOrigin]];\n }\n const result = new Set<string>(this.#state[OriginSlot.ExplicitOrigins]);\n if (\n this.#state[OriginSlot.ExplicitOrigins].size === 0 &&\n this.#state[OriginSlot.ReferrerOrigin] !== undefined\n ) {\n result.add(this.#state[OriginSlot.ReferrerOrigin]);\n }\n const parent = this.#state[OriginSlot.ParentOrigin];\n if (this.#state[OriginSlot.AllowLocalhost] && parent !== undefined) {\n if (LOCALHOST_PATTERN.test(parent)) result.add(parent);\n } else if (this.#state[OriginSlot.AllowLocalhost]) {\n for (const port of LOCALHOST_HANDSHAKE_PORTS) {\n result.add(`http://localhost:${String(port)}`);\n result.add(`http://127.0.0.1:${String(port)}`);\n }\n }\n return [...result];\n }\n\n /** Whether `document.referrer` contributed an origin (absent under `Referrer-Policy: no-referrer`). */\n get referrerWasAvailable(): boolean {\n return this.#state[OriginSlot.ReferrerWasAvailable];\n }\n\n /** Framed, outside development, with no trusted origin at all: the host should warn (LP0101). */\n get isProductionUnconfigured(): boolean {\n if (!isInIframe()) return false;\n if (this.#state[OriginSlot.ExplicitOrigins].size > 0) return false;\n if (this.#state[OriginSlot.AllowLocalhost]) return false;\n if (this.#state[OriginSlot.ReferrerOrigin] !== undefined) return false;\n return true;\n }\n\n /** The referrer is the only trust source, so any framing site may drive the preview (LP0102). */\n get isReferrerOnlyTrust(): boolean {\n if (this.#state[OriginSlot.ExplicitOrigins].size > 0) return false;\n if (this.#state[OriginSlot.AllowLocalhost]) return false;\n return this.#state[OriginSlot.ReferrerOrigin] !== undefined;\n }\n}\n\n/** The canonical `http(s)://host[:port]` form of `value`, or `undefined` when it is not one. */\nexport function normaliseOrigin(value: string): string | undefined {\n const trimmed = value.trim();\n if (trimmed.length === 0) return undefined;\n try {\n const url = new URL(trimmed);\n if (url.protocol !== 'http:' && url.protocol !== 'https:') return undefined;\n if (!VALID_ORIGIN_PATTERN.test(url.origin)) return undefined;\n return url.origin;\n } catch {\n return undefined;\n }\n}\n","/**\n * Registration-local resource scope: every listener, transform, renderer\n * layer and cleanup a plugin registers is staged here until `init` commits\n * and released together, in reverse order, when the plugin goes. See ADR 0005.\n */\n\nimport { observeThenableResult } from '@core/thenable';\nimport type { PluginDisposer } from './types';\n\nexport type ResourceKind = 'transform' | 'renderer' | 'subscription' | 'cleanup';\n\ninterface ScopedResource {\n readonly kind: ResourceKind;\n readonly acquire: (() => PluginDisposer | undefined) | undefined;\n readonly finalize: (() => void) | undefined;\n cleanup: PluginDisposer | undefined;\n disposed: boolean;\n}\n\nexport const noopDisposer: PluginDisposer = () => undefined;\n\nexport class ResourceScope {\n readonly #pluginName: string;\n readonly #log: (...args: unknown[]) => void;\n // Insertion order gives commit/reverse-teardown order; short-lived entries\n // (once listeners) leave immediately instead of accumulating until removal.\n readonly #resources = new Set<ScopedResource>();\n #state: 'staging' | 'committing' | 'active' | 'closed' = 'staging';\n\n constructor(pluginName: string, log: (...args: unknown[]) => void) {\n this.#pluginName = pluginName;\n this.#log = log;\n }\n\n assertOpen(): void {\n if (this.#state === 'closed') {\n throw new Error(`Plugin context for \"${this.#pluginName}\" is no longer active`);\n }\n }\n\n get active(): boolean {\n return this.#state === 'active';\n }\n\n /** Whether a retained context still belongs to this registration. */\n eligible(): boolean {\n return this.#state !== 'closed';\n }\n\n /** Own a resource the plugin itself already acquired. */\n own(cleanup: PluginDisposer): PluginDisposer {\n this.assertOpen();\n return this.#track({\n kind: 'cleanup',\n acquire: undefined,\n finalize: undefined,\n cleanup,\n disposed: false,\n });\n }\n\n /** Stage a manager-owned resource; an active scope acquires it at once. */\n stage(\n kind: ResourceKind,\n acquire: () => PluginDisposer | undefined,\n finalize?: () => void,\n ): PluginDisposer {\n this.assertOpen();\n const resource: ScopedResource = {\n kind,\n acquire,\n finalize,\n cleanup: undefined,\n disposed: false,\n };\n const dispose = this.#track(resource);\n if (this.#state === 'active') {\n try {\n this.#activate(resource);\n } catch (error) {\n this.#dispose(resource);\n throw error;\n }\n }\n return dispose;\n }\n\n /** Live resources by kind, what `inspect().plugins` reports. */\n counts(): Record<ResourceKind, number> {\n const counts: Record<ResourceKind, number> = {\n transform: 0,\n renderer: 0,\n subscription: 0,\n cleanup: 0,\n };\n for (const resource of this.#resources) counts[resource.kind] += 1;\n return counts;\n }\n\n /** Publish every staged resource at once after `init` succeeded. */\n commit(): void {\n if (this.#state !== 'staging') {\n throw new Error(`Plugin context for \"${this.#pluginName}\" cannot be committed`);\n }\n this.#state = 'committing';\n try {\n for (const resource of this.#resources) this.#activate(resource);\n this.#state = 'active';\n } catch (error) {\n this.close();\n throw error;\n }\n }\n\n close(): void {\n if (this.#state === 'closed') return;\n this.#state = 'closed';\n for (const resource of [...this.#resources].reverse()) this.#dispose(resource);\n this.#resources.clear();\n }\n\n #track(resource: ScopedResource): PluginDisposer {\n this.#resources.add(resource);\n return (): void => {\n this.#dispose(resource);\n };\n }\n\n #activate(resource: ScopedResource): void {\n if (resource.disposed || resource.cleanup !== undefined || resource.acquire === undefined) {\n return;\n }\n const cleanup = resource.acquire();\n resource.cleanup = cleanup ?? noopDisposer;\n }\n\n #dispose(resource: ScopedResource): void {\n if (resource.disposed) return;\n resource.disposed = true;\n this.#resources.delete(resource);\n const cleanup = resource.cleanup;\n resource.cleanup = undefined;\n if (cleanup !== undefined) {\n try {\n // A `void` cleanup may still return a thenable; observe it without awaiting.\n const cleanupWithResult: () => unknown = cleanup;\n if (observeThenableResult(cleanupWithResult())) {\n this.#log(\n `plugin \"${this.#pluginName}\" cleanup returned a Promise/thenable; cleanups must be synchronous`,\n );\n }\n } catch (error) {\n this.#log(`plugin \"${this.#pluginName}\" cleanup failed:`, error);\n }\n }\n try {\n resource.finalize?.();\n } catch (error) {\n this.#log(`plugin \"${this.#pluginName}\" cleanup failed:`, error);\n }\n }\n}\n","/**\n * Event facade handed to a plugin: subscriptions are owned by the plugin's\n * scope, emits go to the client's emitter. It implements the emitter surface\n * without extending it, so no unused base emitter is allocated per plugin.\n */\n\nimport type { EventEmitter } from '@events/emitter';\nimport type { EventHandler, LivePreviewEventMap, Unsubscribe } from '@events/types';\nimport { noopDisposer, type ResourceScope } from './resource-scope';\nimport type { PluginEvents } from './types';\n\ninterface OwnedSubscription {\n readonly kind: 'on' | 'once';\n readonly event: keyof LivePreviewEventMap;\n readonly handler: EventHandler<unknown>;\n dispose: Unsubscribe;\n}\n\nexport class ScopedPluginEvents implements PluginEvents {\n readonly #events: EventEmitter;\n readonly #scope: ResourceScope;\n readonly #subscriptions = new Set<OwnedSubscription>();\n\n constructor(events: EventEmitter, scope: ResourceScope) {\n this.#events = events;\n this.#scope = scope;\n }\n\n on<E extends keyof LivePreviewEventMap>(\n event: E,\n handler: EventHandler<LivePreviewEventMap[E]>,\n ): Unsubscribe {\n return this.#subscribe('on', event, handler);\n }\n\n once<E extends keyof LivePreviewEventMap>(\n event: E,\n handler: EventHandler<LivePreviewEventMap[E]>,\n ): Unsubscribe {\n return this.#subscribe('once', event, handler);\n }\n\n off<E extends keyof LivePreviewEventMap>(\n event: E,\n handler: EventHandler<LivePreviewEventMap[E]>,\n ): void {\n const untypedHandler = handler as EventHandler<unknown>;\n for (const subscription of [...this.#subscriptions]) {\n if (subscription.event === event && subscription.handler === untypedHandler) {\n subscription.dispose();\n }\n }\n }\n\n emit<E extends keyof LivePreviewEventMap>(\n event: E,\n payload: LivePreviewEventMap[E],\n ): Promise<void> {\n this.#scope.assertOpen();\n return this.#events.emit(event, payload);\n }\n\n emitWhile<E extends keyof LivePreviewEventMap>(\n event: E,\n payload: LivePreviewEventMap[E],\n shouldContinue: () => boolean,\n ): Promise<boolean> {\n this.#scope.assertOpen();\n return this.#events.emitWhile(event, payload, () => {\n if (!this.#scope.eligible()) return false;\n const callerEligible = shouldContinue();\n // The predicate is plugin code and may close this scope re-entrantly.\n if (!this.#scope.eligible()) return false;\n return callerEligible;\n });\n }\n\n listenerCount(event: keyof LivePreviewEventMap): number {\n let count = 0;\n for (const subscription of this.#subscriptions) {\n if (subscription.event === event) count += 1;\n }\n return count;\n }\n\n removeAllListeners(event?: keyof LivePreviewEventMap): void {\n for (const subscription of [...this.#subscriptions]) {\n if (event === undefined || subscription.event === event) subscription.dispose();\n }\n }\n\n eventNames(): (keyof LivePreviewEventMap)[] {\n const names = new Set<keyof LivePreviewEventMap>();\n for (const subscription of this.#subscriptions) names.add(subscription.event);\n return [...names];\n }\n\n #subscribe<E extends keyof LivePreviewEventMap>(\n kind: 'on' | 'once',\n event: E,\n handler: EventHandler<LivePreviewEventMap[E]>,\n ): Unsubscribe {\n this.#scope.assertOpen();\n\n const untypedHandler = handler as EventHandler<unknown>;\n const existing = [...this.#subscriptions].find(\n (subscription) =>\n subscription.kind === kind &&\n subscription.event === event &&\n subscription.handler === untypedHandler,\n );\n if (existing !== undefined) return existing.dispose;\n\n // A distinct wrapper per scope: two plugins passing the same handler\n // reference must be revocable independently in the Set-based emitter.\n let dispose = noopDisposer;\n let subscriptionActive = true;\n const wrapped: EventHandler<LivePreviewEventMap[E]> = async (payload) => {\n if (!this.#scope.active || !subscriptionActive) return;\n // Mirror the base emitter, which drops a once bucket before dispatch.\n if (kind === 'once') dispose();\n await handler(payload);\n };\n const subscription: OwnedSubscription = {\n kind,\n event,\n handler: untypedHandler,\n dispose: noopDisposer,\n };\n dispose = this.#scope.stage(\n 'subscription',\n () => this.#events[kind](event, wrapped),\n () => {\n subscriptionActive = false;\n this.#subscriptions.delete(subscription);\n },\n );\n subscription.dispose = dispose;\n this.#subscriptions.add(subscription);\n return dispose;\n }\n}\n","/**\n * Per-instance plugin manager. Mutations run through one call-order queue;\n * while a queue-held hook is pending, a requested mutation takes the direct\n * path because that hook may be awaiting it. See ADR 0005.\n */\n\nimport type { FieldRenderer } from '@core/types';\nimport type { PluginInspection } from '@core/inspection/types';\nimport { LIBRARY_PROTOCOL_VERSION } from '@core/protocol-version';\nimport { VERSION } from '@/version';\nimport { incompatibilityOf } from './compat';\nimport { isolateDiagnostic } from '@core/diagnostics';\nimport { observeThenableResult } from '@core/thenable';\nimport type { EventEmitter } from '@events/emitter';\nimport { ResourceScope } from './resource-scope';\nimport { ScopedPluginEvents } from './scoped-events';\nimport type { FieldTransform, LivePreviewPlugin, PluginContext } from './types';\n\nexport interface PluginManagerOptions {\n readonly events: EventEmitter;\n readonly config: Readonly<Record<string, unknown>>;\n /** Add one renderer layer to the host; may return the layer's disposer. */\n readonly registerFieldRenderer: (renderer: FieldRenderer) => void;\n /** Receives transform contract failures for the runtime's `error` event. */\n readonly onTransformError?: (error: Error) => unknown;\n readonly log: (...args: unknown[]) => void;\n}\n\ninterface PluginRegistration {\n readonly plugin: LivePreviewPlugin;\n readonly scope: ResourceScope;\n}\n\ninterface InitializingPluginRegistration {\n readonly scope: ResourceScope;\n cancelled: boolean;\n}\n\ninterface TransformRegistration {\n readonly transform: FieldTransform;\n active: boolean;\n}\n\nfunction isPluginDisposer(value: unknown): value is (() => void) | undefined {\n return typeof value === 'function';\n}\n\nexport class PluginManager {\n readonly #events: EventEmitter;\n readonly #config: Readonly<Record<string, unknown>>;\n // The public callback type is void; the client host returns its layer disposer through it.\n readonly #registerRenderer: (renderer: FieldRenderer) => unknown;\n readonly #onTransformError: ((error: Error) => void) | undefined;\n readonly #log: (...args: unknown[]) => void;\n readonly #plugins = new Map<string, PluginRegistration>();\n readonly #initializing = new Map<string, InitializingPluginRegistration>();\n readonly #teardowns = new Map<string, Promise<void>>();\n readonly #destroying = new Set<string>();\n readonly #transforms = new Map<string, TransformRegistration[]>();\n #mutationQueue: Promise<void> = Promise.resolve();\n // Hooks awaited by the queue entry in flight. Hooks started on the direct\n // path never hold the queue, so they must not open it for others.\n #queuedHooks = 0;\n\n constructor(options: PluginManagerOptions) {\n this.#events = options.events;\n this.#config = options.config;\n this.#registerRenderer = options.registerFieldRenderer;\n this.#log = isolateDiagnostic(options.log);\n const onTransformError = options.onTransformError;\n this.#onTransformError =\n onTransformError === undefined\n ? undefined\n : isolateDiagnostic((...args: unknown[]): unknown => {\n // Private and single-callered: `applyTransforms` normalizes to an\n // Error before it reports one.\n const error = args[0] as Error;\n try {\n return onTransformError(error);\n } catch (reportError) {\n this.#log('transform error reporter failed:', reportError);\n return undefined;\n }\n });\n }\n\n /** Register a plugin transactionally; concurrent mutations run in call order. */\n register(plugin: LivePreviewPlugin): Promise<void> {\n if (this.#queuedHooks > 0) return this.#registerNow(plugin, false);\n return this.#enqueue(() => this.#registerNow(plugin, true));\n }\n\n /** Remove one plugin and every resource its registration created. */\n unregister(name: string): Promise<void> {\n if (this.#queuedHooks > 0) return this.#unregisterNow(name, false);\n return this.#enqueue(async () => {\n await this.#unregisterNow(name, true);\n });\n }\n\n /** Destroy every registration; one failure never strands another. */\n destroyAll(): Promise<void> {\n if (this.#queuedHooks > 0) return this.#destroyAllNow(false);\n return this.#enqueue(async () => {\n await this.#destroyAllNow(true);\n });\n }\n\n /** Apply active transforms in registration order; a failure returns the original value. */\n applyTransforms(\n fieldName: string,\n value: unknown,\n context: { readonly element: Element; readonly allFields: Record<string, unknown> },\n isCurrent?: () => boolean,\n ): unknown {\n const registrations = this.#transforms.get(fieldName);\n if (registrations === undefined || registrations.length === 0) return value;\n\n let result: unknown = value;\n for (const registration of [...registrations]) {\n if (!registration.active) continue;\n const { transform } = registration;\n if (isCurrent?.() === false) return value;\n try {\n result = transform(result, {\n fieldName,\n element: context.element,\n allFields: context.allFields,\n });\n const returnedThenable = observeThenableResult(result);\n // A transform may synchronously let a newer message in; then its\n // result belongs to a superseded revision and is not reported.\n if (isCurrent?.() === false) return value;\n if (returnedThenable) {\n throw new TypeError(\n `Transform for \"${fieldName}\" returned a Promise/thenable; transforms must be synchronous`,\n );\n }\n } catch (error) {\n if (isCurrent?.() === false) return value;\n const normalized = error instanceof Error ? error : new Error(String(error));\n this.#log(`transform for \"${fieldName}\" failed:`, normalized);\n this.#onTransformError?.(normalized);\n return value;\n }\n }\n return result;\n }\n\n list(): readonly string[] {\n return [...this.#plugins.keys()];\n }\n\n /** Every plugin with its state and live registrations (`inspect().plugins`). */\n snapshot(): readonly PluginInspection[] {\n const entries: PluginInspection[] = [];\n const describe = (\n name: string,\n version: string | undefined,\n state: PluginInspection['state'],\n scope: ResourceScope,\n ): PluginInspection => {\n const counts = scope.counts();\n return {\n name,\n version,\n state,\n registrations: {\n transforms: counts.transform,\n renderers: counts.renderer,\n subscriptions: counts.subscription,\n cleanups: counts.cleanup,\n },\n };\n };\n for (const [name, initializing] of this.#initializing) {\n entries.push(describe(name, undefined, 'initializing', initializing.scope));\n }\n for (const [name, registration] of this.#plugins) {\n entries.push(describe(name, registration.plugin.version, 'active', registration.scope));\n }\n // A name with a pending teardown left `#plugins` before the teardown began.\n for (const name of this.#teardowns.keys()) {\n entries.push({\n name,\n version: undefined,\n state: 'tearing-down',\n registrations: { transforms: 0, renderers: 0, subscriptions: 0, cleanups: 0 },\n });\n }\n return entries;\n }\n\n get size(): number {\n return this.#plugins.size;\n }\n\n async #registerNow(plugin: LivePreviewPlugin, queued: boolean): Promise<void> {\n if (\n this.#plugins.has(plugin.name) ||\n this.#initializing.has(plugin.name) ||\n this.#teardowns.has(plugin.name)\n ) {\n this.#log(`plugin \"${plugin.name}\" already registered`);\n return;\n }\n\n const incompatibility = incompatibilityOf(plugin.compat, VERSION, LIBRARY_PROTOCOL_VERSION);\n if (incompatibility !== undefined) {\n this.#refuse(plugin.name, incompatibility);\n return;\n }\n const scope = new ResourceScope(plugin.name, this.#log);\n const context = this.#createContext(plugin.name, scope);\n const initializing: InitializingPluginRegistration = { scope, cancelled: false };\n this.#initializing.set(plugin.name, initializing);\n try {\n await this.#runHook(() => plugin.init(context), queued);\n if (initializing.cancelled) return;\n scope.commit();\n } catch (error) {\n scope.close();\n if (!initializing.cancelled) this.#log(`plugin \"${plugin.name}\" init failed:`, error);\n return;\n } finally {\n if (this.#initializing.get(plugin.name) === initializing) {\n this.#initializing.delete(plugin.name);\n }\n }\n\n this.#plugins.set(plugin.name, { plugin, scope });\n this.#log(`plugin \"${plugin.name}\" registered`);\n }\n\n /** A refused plugin is an integration mistake; it reaches the `error` event, not only the log. */\n #refuse(name: string, reason: string): void {\n const message = `plugin \"${name}\" refused: ${reason}`;\n this.#log(message);\n void this.#events.emit('error', {\n error: new Error(message),\n context: 'plugin',\n code: 'LP0103',\n });\n }\n\n #createContext(pluginName: string, scope: ResourceScope): PluginContext {\n return {\n events: new ScopedPluginEvents(this.#events, scope),\n registerFieldRenderer: (renderer) => {\n scope.stage('renderer', () => {\n const result = this.#registerRenderer(renderer);\n return isPluginDisposer(result) ? result : undefined;\n });\n },\n registerTransform: (fieldName, transform) => {\n const registration: TransformRegistration = { transform, active: false };\n scope.stage('transform', () => {\n registration.active = true;\n const existing = this.#transforms.get(fieldName);\n if (existing === undefined) this.#transforms.set(fieldName, [registration]);\n else existing.push(registration);\n\n return () => {\n registration.active = false;\n const current = this.#transforms.get(fieldName);\n if (current === undefined) return;\n const index = current.indexOf(registration);\n if (index >= 0) current.splice(index, 1);\n if (current.length === 0) this.#transforms.delete(fieldName);\n };\n });\n },\n registerCleanup: (cleanup) => {\n scope.own(cleanup);\n },\n getConfig: () => this.#config,\n log: (...args) => {\n this.#log(`[${pluginName}]`, ...args);\n },\n };\n }\n\n #unregisterNow(name: string, queued: boolean): Promise<void> {\n const initializing = this.#initializing.get(name);\n if (initializing !== undefined) {\n initializing.cancelled = true;\n initializing.scope.close();\n return Promise.resolve();\n }\n\n const existingTeardown = this.#teardowns.get(name);\n if (existingTeardown !== undefined) {\n // A destroy hook removing its own name cannot await the teardown that\n // awaits it; its resources are already revoked, so this is complete.\n if (this.#destroying.has(name)) return Promise.resolve();\n return queued ? this.#holdQueue(existingTeardown) : existingTeardown;\n }\n const registration = this.#plugins.get(name);\n if (registration === undefined) return Promise.resolve();\n\n // Revoke before consumer code runs: a throwing destroy keeps no access,\n // and a same-name registration from inside destroy stays a duplicate.\n this.#plugins.delete(name);\n registration.scope.close();\n const teardown = Promise.resolve().then(() =>\n this.#destroyPlugin(name, registration.plugin, queued),\n );\n this.#teardowns.set(name, teardown);\n void teardown.then(() => {\n if (this.#teardowns.get(name) === teardown) this.#teardowns.delete(name);\n });\n return teardown;\n }\n\n async #destroyPlugin(name: string, plugin: LivePreviewPlugin, queued: boolean): Promise<void> {\n if (plugin.destroy === undefined) return;\n this.#destroying.add(name);\n try {\n await this.#runHook(() => plugin.destroy?.(), queued);\n } catch (error) {\n this.#log(`plugin \"${name}\" destroy failed:`, error);\n } finally {\n this.#destroying.delete(name);\n }\n }\n\n async #destroyAllNow(queued: boolean): Promise<void> {\n for (const initializing of this.#initializing.values()) {\n initializing.cancelled = true;\n initializing.scope.close();\n }\n const names = [...this.#plugins.keys()];\n for (const name of names) await this.#unregisterNow(name, queued);\n }\n\n async #runHook(hook: () => void | Promise<void>, queued: boolean): Promise<void> {\n if (!queued) {\n await hook();\n return;\n }\n await this.#holdQueue(Promise.resolve().then(hook));\n }\n\n async #holdQueue(pending: Promise<void>): Promise<void> {\n this.#queuedHooks += 1;\n try {\n await pending;\n } finally {\n this.#queuedHooks -= 1;\n }\n }\n\n #enqueue(operation: () => void | Promise<void>): Promise<void> {\n const result = this.#mutationQueue.then(operation);\n // Keep the tail usable after an escaped error; the caller still sees it on `result`.\n this.#mutationQueue = result.catch((error: unknown) => {\n this.#log('plugin manager mutation failed:', error);\n });\n return result;\n }\n}\n","/**\n * Plugin compatibility claims. The range grammar is the subset a plugin\n * author writes (`*`, `1.2.3`, `^`, `~`, `>=`, `>`, `<`, `<=`, space-joined\n * conjunctions, `||` alternatives); prerelease tags are ignored.\n */\n\nexport interface PluginCompatibility {\n /** A semver range the runtime's `VERSION` must satisfy, e.g. `>=2.0.0`. */\n readonly runtime?: string;\n /** The highest postMessage protocol version the plugin understands. */\n readonly protocol?: number;\n}\n\ntype Version = readonly [number, number, number];\n\nfunction parseVersion(text: string): Version | undefined {\n const match = /^v?(\\d+)\\.(\\d+)\\.(\\d+)/.exec(text.trim());\n if (match === null) return undefined;\n return [Number(match[1]), Number(match[2]), Number(match[3])];\n}\n\nfunction compare(a: Version, b: Version): number {\n for (let index = 0; index < 3; index += 1) {\n const delta = (a[index] ?? 0) - (b[index] ?? 0);\n if (delta !== 0) return delta;\n }\n return 0;\n}\n\nfunction satisfiesComparator(version: Version, comparator: string): boolean {\n const trimmed = comparator.trim();\n if (trimmed === '' || trimmed === '*') return true;\n const match = /^(\\^|~|>=|<=|>|<|=)?\\s*v?(\\d+)\\.(\\d+)\\.(\\d+)/.exec(trimmed);\n if (match === null) return false;\n const operator = match[1] ?? '=';\n const target: Version = [Number(match[2]), Number(match[3]), Number(match[4])];\n const order = compare(version, target);\n switch (operator) {\n case '=':\n return order === 0;\n case '>':\n return order > 0;\n case '>=':\n return order >= 0;\n case '<':\n return order < 0;\n case '<=':\n return order <= 0;\n case '~':\n return order >= 0 && version[0] === target[0] && version[1] === target[1];\n case '^':\n if (order < 0) return false;\n if (target[0] > 0) return version[0] === target[0];\n if (target[1] > 0) return version[0] === 0 && version[1] === target[1];\n return version[0] === 0 && version[1] === 0 && version[2] === target[2];\n default:\n return false;\n }\n}\n\n/** Whether `version` satisfies `range`; anything unparsable never satisfies. */\nexport function satisfiesRange(version: string, range: string): boolean {\n const parsed = parseVersion(version);\n if (parsed === undefined) return false;\n const alternatives = range.split('||');\n return alternatives.some((alternative) => {\n const comparators = alternative\n .trim()\n .split(/\\s+/)\n .filter((part) => part.length > 0);\n if (comparators.length === 0) return alternative.trim() === '' && range.trim() === '';\n return comparators.every((comparator) => satisfiesComparator(parsed, comparator));\n });\n}\n\n/** Why a plugin was refused, or `undefined` when it fits. */\nexport function incompatibilityOf(\n compat: PluginCompatibility | undefined,\n runtimeVersion: string,\n protocolVersion: number,\n): string | undefined {\n if (compat === undefined) return undefined;\n if (compat.runtime !== undefined && !satisfiesRange(runtimeVersion, compat.runtime)) {\n return `declares runtime ${compat.runtime}, this runtime is ${runtimeVersion}`;\n }\n if (compat.protocol !== undefined) {\n if (!Number.isInteger(compat.protocol) || compat.protocol < 1) {\n return `declares an invalid protocol version ${String(compat.protocol)}`;\n }\n if (compat.protocol < protocolVersion) {\n return `declares protocol ${String(compat.protocol)}, this runtime speaks ${String(protocolVersion)}`;\n }\n }\n return undefined;\n}\n","/**\n * Per-client renderer layers: built-ins are the base, plugin registrations\n * stack above per field type, and removing a layer by identity reveals the\n * one beneath. See ADR 0005.\n */\n\nimport type { FieldRenderer, RendererKey } from '@core/types';\nimport type { PluginDisposer } from './types';\n\ninterface RendererLayer {\n readonly renderer: FieldRenderer;\n}\n\nexport class RendererRegistry {\n readonly #base: Readonly<Record<string, FieldRenderer>>;\n readonly #active: Record<string, FieldRenderer>;\n readonly #layers = new Map<RendererKey, RendererLayer[]>();\n\n constructor(base: Readonly<Record<string, FieldRenderer>>) {\n this.#base = base;\n this.#active = { ...base };\n }\n\n /** Stable live map, retained for the runtime's `renderers` option. */\n get renderers(): Readonly<Record<string, FieldRenderer>> {\n return this.#active;\n }\n\n resolve(fieldType: RendererKey): FieldRenderer | undefined {\n return this.#active[fieldType];\n }\n\n register(renderer: FieldRenderer): PluginDisposer {\n const fieldType = renderer.name;\n const layer: RendererLayer = { renderer };\n const stack = this.#layers.get(fieldType);\n if (stack === undefined) this.#layers.set(fieldType, [layer]);\n else stack.push(layer);\n this.#active[fieldType] = renderer;\n\n let active = true;\n return () => {\n if (!active) return;\n active = false;\n\n const current = this.#layers.get(fieldType);\n if (current === undefined) return;\n const index = current.indexOf(layer);\n if (index < 0) return;\n const wasTop = index === current.length - 1;\n current.splice(index, 1);\n if (current.length === 0) this.#layers.delete(fieldType);\n if (!wasTop) return;\n\n const previousLayer = current.at(-1);\n const previousRenderer = previousLayer?.renderer ?? this.#base[fieldType];\n if (previousRenderer === undefined) Reflect.deleteProperty(this.#active, fieldType);\n else this.#active[fieldType] = previousRenderer;\n };\n }\n}\n","/** Attribute helpers shared by the block-level node renderers. */\n\nimport type { LexicalNode } from './types';\n\nconst ALIGNMENT_NUMERIC: Readonly<Record<number, string>> = {\n 1: 'left',\n 2: 'center',\n 3: 'right',\n 4: 'justify',\n};\n\nconst ALIGNMENT_STRING = new Set(['left', 'center', 'right', 'justify', 'start', 'end']);\n\n/** Alignment of a block node; Payload emits it as a string or as Lexical's numeric format. */\nexport function resolveAlignment(node: LexicalNode): string | undefined {\n const fmt = node.format;\n if (typeof fmt === 'string' && ALIGNMENT_STRING.has(fmt)) return fmt;\n if (typeof fmt === 'number') return ALIGNMENT_NUMERIC[fmt];\n return undefined;\n}\n\nexport function resolveIndent(node: LexicalNode): number {\n const indent = node.indent;\n return typeof indent === 'number' && indent > 0 ? indent : 0;\n}\n\nexport function dirAttribute(node: LexicalNode): string {\n if (node.direction === 'rtl') return ' dir=\"rtl\"';\n if (node.direction === 'ltr') return ' dir=\"ltr\"';\n return '';\n}\n\n/**\n * Alignment and indent as `lp-align-*` / `lp-indent-N` classes. The sanitizer\n * strips `style` under every policy, so inline CSS would never reach the page.\n */\nexport function layoutClassAttribute(node: LexicalNode): string {\n const align = resolveAlignment(node);\n const indent = resolveIndent(node);\n const classes: string[] = [];\n if (align !== undefined) classes.push(`lp-align-${align}`);\n if (indent > 0) classes.push(`lp-indent-${String(indent)}`);\n return classes.length === 0 ? '' : ` class=\"${classes.join(' ')}\"`;\n}\n","import type { NodeRenderer } from '../registry';\nimport { dirAttribute, layoutClassAttribute } from '../utils';\n\nconst paragraphRenderer: NodeRenderer = (node, ctx): string => {\n const children = ctx.renderChildren(node.children ?? []);\n return `<p${dirAttribute(node)}${layoutClassAttribute(node)}>${children}</p>`;\n};\n\nexport { paragraphRenderer };\n","/** `heading` renderer; an unknown `tag` (transient editor states emit them) falls back to `h2`. */\n\nimport type { NodeRenderer } from '../registry';\nimport { dirAttribute, layoutClassAttribute } from '../utils';\n\nconst VALID_TAGS = new Set(['h1', 'h2', 'h3', 'h4', 'h5', 'h6']);\n\nconst headingRenderer: NodeRenderer = (node, ctx): string => {\n const tagRaw = typeof node['tag'] === 'string' ? node['tag'].toLowerCase() : 'h2';\n const tag = VALID_TAGS.has(tagRaw) ? tagRaw : 'h2';\n const children = ctx.renderChildren(node.children ?? []);\n return `<${tag}${dirAttribute(node)}${layoutClassAttribute(node)}>${children}</${tag}>`;\n};\n\nexport { headingRenderer };\n","/**\n * Value-shape helpers shared by the Lexical node renderers and the field\n * renderers. They live here because `field-types` may import `lexical`, never\n * the reverse (scripts/architecture-policy.ts).\n */\n\nexport interface MediaShape {\n readonly id?: string | number;\n readonly url?: string;\n readonly alt?: string;\n readonly filename?: string;\n readonly mimeType?: string;\n readonly width?: number;\n readonly height?: number;\n readonly sizes?: Readonly<\n Record<\n string,\n {\n readonly url?: string;\n readonly width?: number;\n readonly height?: number;\n readonly mimeType?: string;\n }\n >\n >;\n}\n\nexport interface RelationShape {\n readonly id?: string | number;\n readonly title?: string;\n readonly name?: string;\n readonly slug?: string;\n readonly url?: string;\n}\n\nexport function asRecord(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nexport function readMedia(value: unknown): MediaShape | undefined {\n return asRecord(value);\n}\n\n/**\n * A media document's URL as the preview should load it. Unless its config sets\n * `serverURL`, Payload returns a path on its own origin (`/api/media/file/a.png`);\n * its admin resolves the path against the server, and the preview, framed on\n * another origin, would otherwise ask itself for the file. Only such a path is\n * Payload's to place: any other URL, and every URL when no server is known, is\n * written as delivered. A result on another origin than the server's (`/\\host`\n * is one, to the URL parser) is discarded.\n */\nexport function resolveMediaUrl(url: string, serverURL: string | undefined): string {\n if (serverURL === undefined || serverURL === '' || !url.startsWith('/')) return url;\n try {\n const server = new URL(serverURL);\n const resolved = new URL(url, server);\n return resolved.origin === server.origin ? resolved.href : url;\n } catch {\n return url;\n }\n}\n\n/** Reduce `value` to `[a-z0-9_-]` so it can be a class-name fragment without escaping. */\nexport function sanitizeIdent(value: string): string {\n return value.replace(/[^a-zA-Z0-9_-]/g, '-').toLowerCase();\n}\n\nfunction nonEmpty(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\n/** Label precedence for a populated relation: `title`, `name`, `slug`, then `id`. */\nexport function pickRelationLabel(value: RelationShape): string | undefined {\n const label = nonEmpty(value.title) ?? nonEmpty(value.name) ?? nonEmpty(value.slug);\n if (label !== undefined) return label;\n return value.id === undefined ? undefined : String(value.id);\n}\n","/**\n * `link` / `autolink` renderer. Payload 3.x serialises links as\n * `{ fields: { linkType, url, newTab, doc } }`; vanilla Lexical puts `url`\n * and `target` on the node itself. Both shapes are read, Payload's first.\n */\n\nimport { escapeHtml, escapeHtmlAttribute } from '@security/escape';\nimport { isExternalHttpUrl, isSafeUrl } from '@security/url-validator';\nimport type { NodeRenderer } from '../registry';\nimport type { LexicalNode } from '../types';\nimport { asRecord } from '../value-shapes';\n\nconst BLANK_TARGET = ' target=\"_blank\" rel=\"noopener noreferrer\"';\n\nconst linkRenderer: NodeRenderer = (node, ctx): string => {\n const children = ctx.renderChildren(node.children ?? []);\n const fields = asRecord(node['fields']);\n const url = resolveUrl(node, fields);\n if (url === undefined || !isSafeUrl(url)) return children;\n const titleAttr =\n typeof node['title'] === 'string' ? ` title=\"${escapeHtml(node['title'])}\"` : '';\n return `<a href=\"${escapeHtmlAttribute(url)}\"${targetAttribute(node, fields, url)}${titleAttr}>${children}</a>`;\n};\n\nfunction resolveUrl(\n node: LexicalNode,\n fields: Record<string, unknown> | undefined,\n): string | undefined {\n if (fields?.['linkType'] === 'internal') return internalUrl(fields['doc']);\n const url = fields?.['url'] ?? node['url'];\n return typeof url === 'string' && url.length > 0 ? url : undefined;\n}\n\n/** An internal link needs the populated document; a bare id has no route to offer. */\nfunction internalUrl(doc: unknown): string | undefined {\n const value = asRecord(asRecord(doc)?.['value']);\n const url = value?.['url'];\n if (typeof url === 'string' && url.length > 0) return url;\n const slug = value?.['slug'];\n return typeof slug === 'string' && slug.length > 0 ? `/${slug}` : undefined;\n}\n\n/** `_blank` always carries `noopener noreferrer`, whichever side asked for it. */\nfunction targetAttribute(\n node: LexicalNode,\n fields: Record<string, unknown> | undefined,\n url: string,\n): string {\n if (fields?.['newTab'] === true || isExternalHttpUrl(url)) return BLANK_TARGET;\n const target = typeof node['target'] === 'string' ? node['target'] : '';\n if (target === '') return '';\n if (target === '_blank') return BLANK_TARGET;\n return ` target=\"${escapeHtml(target)}\"`;\n}\n\nexport { linkRenderer };\n","/** `code` (fenced block) and `code-highlight` (token span) renderers. */\n\nimport { escapeHtml } from '@security/escape';\nimport type { NodeRenderer } from '../registry';\nimport type { LexicalNode } from '../types';\nimport { sanitizeIdent } from '../value-shapes';\n\nconst codeRenderer: NodeRenderer = (node): string => {\n const language = sanitizeIdent(typeof node['language'] === 'string' ? node['language'] : '');\n const langClass = language === '' ? '' : ` class=\"language-${language}\"`;\n return `<pre><code${langClass}>${escapeHtml(extractText(node))}</code></pre>`;\n};\n\nconst codeHighlightRenderer: NodeRenderer = (node): string => {\n const text = typeof node.text === 'string' ? node.text : '';\n const highlight =\n typeof node['highlightType'] === 'string'\n ? ` class=\"token-${sanitizeIdent(node['highlightType'])}\"`\n : '';\n return `<span${highlight}>${escapeHtml(text)}</span>`;\n};\n\nexport { codeRenderer, codeHighlightRenderer };\n\nfunction extractText(node: LexicalNode): string {\n if (typeof node.text === 'string') return node.text;\n if (!node.children) return '';\n let out = '';\n for (const child of node.children) out += extractText(child);\n return out;\n}\n","/**\n * `upload` renderer: `<img>` for image (or unknown) MIME types, `<video>` /\n * `<audio>` for media, a download link otherwise. An unsafe URL renders nothing.\n */\n\nimport { escapeHtml, escapeHtmlAttribute } from '@security/escape';\nimport { isSafeUrl } from '@security/url-validator';\nimport type { NodeRenderer } from '../registry';\nimport { readMedia, type MediaShape } from '../value-shapes';\n\nconst uploadRenderer: NodeRenderer = (node): string => {\n const value = readMedia(node['value']);\n if (value === undefined) return '';\n const url = value.url;\n if (typeof url !== 'string' || !isSafeUrl(url)) return '';\n\n const mime = typeof value.mimeType === 'string' ? value.mimeType : '';\n if (mime.startsWith('video/')) return renderVideo(value, url);\n if (mime.startsWith('audio/')) return renderAudio(value, url);\n if (mime === '' || mime.startsWith('image/')) return renderImage(value, url);\n return renderFallbackLink(value, url);\n};\n\nexport { uploadRenderer };\n\nfunction dimensionAttributes(value: MediaShape): string {\n const width = typeof value.width === 'number' ? ` width=\"${String(value.width)}\"` : '';\n const height = typeof value.height === 'number' ? ` height=\"${String(value.height)}\"` : '';\n return `${width}${height}`;\n}\n\nfunction typeAttribute(value: MediaShape): string {\n return typeof value.mimeType === 'string' ? ` type=\"${escapeHtmlAttribute(value.mimeType)}\"` : '';\n}\n\nfunction renderImage(value: MediaShape, url: string): string {\n const alt = typeof value.alt === 'string' ? escapeHtml(value.alt) : '';\n return `<img src=\"${escapeHtmlAttribute(url)}\" alt=\"${alt}\"${dimensionAttributes(value)} loading=\"lazy\" decoding=\"async\">`;\n}\n\nfunction renderVideo(value: MediaShape, url: string): string {\n return `<video controls${dimensionAttributes(value)}><source src=\"${escapeHtmlAttribute(url)}\"${typeAttribute(value)}></video>`;\n}\n\nfunction renderAudio(value: MediaShape, url: string): string {\n return `<audio controls><source src=\"${escapeHtmlAttribute(url)}\"${typeAttribute(value)}></audio>`;\n}\n\nfunction renderFallbackLink(value: MediaShape, url: string): string {\n const label = typeof value.filename === 'string' ? escapeHtml(value.filename) : escapeHtml(url);\n return `<a href=\"${escapeHtmlAttribute(url)}\" target=\"_blank\" rel=\"noopener noreferrer\">${label}</a>`;\n}\n","/** `relationship` renderer: a link when the populated document carries a URL, a span otherwise. */\n\nimport { escapeHtml, escapeHtmlAttribute } from '@security/escape';\nimport { isSafeUrl } from '@security/url-validator';\nimport type { NodeRenderer } from '../registry';\nimport { asRecord, pickRelationLabel, sanitizeIdent, type RelationShape } from '../value-shapes';\n\nconst relationshipRenderer: NodeRenderer = (node): string => {\n const relationTo = typeof node['relationTo'] === 'string' ? node['relationTo'] : '';\n const value = asRecord(node['value']) as RelationShape | undefined;\n const label = escapeHtml((value && pickRelationLabel(value)) ?? `#${relationTo}`);\n const slug = sanitizeIdent(relationTo);\n const classAttr =\n slug === '' ? ' class=\"lp-relation\"' : ` class=\"lp-relation lp-relation--${slug}\"`;\n const url = value?.url;\n if (typeof url === 'string' && isSafeUrl(url)) {\n return `<a href=\"${escapeHtmlAttribute(url)}\"${classAttr}>${label}</a>`;\n }\n return `<span${classAttr}>${label}</span>`;\n};\n\nexport { relationshipRenderer };\n","/** Block-renderer registry keyed by Payload block slug; consulted by the `block` and `inlineBlock` nodes. */\n\nimport type { LexicalNode } from '../types';\n\nexport interface BlockRenderContext {\n /** Render nested Lexical content through the node registry. */\n readonly renderChildren: (children: readonly LexicalNode[]) => string;\n}\n\n/** Receives the block's `fields` (with `blockType`) and returns HTML. */\nexport type BlockRenderer = (\n fields: Record<string, unknown>,\n context: BlockRenderContext,\n) => string;\n\nconst registry = new Map<string, BlockRenderer>();\n\n/** Register or replace the renderer for `blockType`. */\nexport function registerBlockRenderer(blockType: string, renderer: BlockRenderer): void {\n registry.set(blockType, renderer);\n}\n\n/** @internal */\nexport function lookupBlockRenderer(blockType: string): BlockRenderer | undefined {\n return registry.get(blockType);\n}\n\n/** @internal */\nexport function registeredBlockTypes(): readonly string[] {\n return [...registry.keys()];\n}\n\n/** Test-only: clear the registry. */\nexport function __resetBlockRegistryForTests(): void {\n registry.clear();\n}\n","/**\n * `block` and `inlineBlock` renderers for Payload's BlocksFeature. The block\n * registry is consulted first; without a renderer for the slug the node becomes\n * an empty, class-tagged element a consumer can style or replace.\n *\n * That element is a placeholder, not a rendering. `UNRENDERED_BLOCK_SELECTOR`\n * names it so the write path can keep the markup the server already rendered\n * for the block in its place, instead of replacing a figure and its image with\n * an empty div (LP0410). Whether that succeeds is decided there, not here: this\n * renderer only tells the context which slug it had no renderer for, and the\n * write says what became of it (LP0410 kept, LP0413 lost).\n */\n\nimport { lookupBlockRenderer } from '../blocks/registry';\nimport type { NodeRenderer, RenderNodeContext } from '../registry';\nimport type { LexicalNode } from '../types';\nimport { asRecord, sanitizeIdent } from '../value-shapes';\n\n/**\n * The placeholders above, in the rendered tree. Both are empty by construction,\n * and a registered renderer's output is not: it carries the block's content and\n * its own class (`lp-block-callout`, …).\n */\nexport const UNRENDERED_BLOCK_SELECTOR = '.lp-block:empty,.lp-inline-block:empty';\n\nfunction renderBlockNode(\n node: LexicalNode,\n ctx: RenderNodeContext,\n tag: 'div' | 'span',\n baseClass: string,\n): string {\n const fields = asRecord(node['fields']) ?? {};\n const blockType = typeof fields['blockType'] === 'string' ? fields['blockType'] : '';\n const slug = sanitizeIdent(blockType);\n const classes = slug === '' ? baseClass : `${baseClass} ${baseClass}--${slug}`;\n if (blockType !== '') {\n const custom = lookupBlockRenderer(blockType) ?? lookupBlockRenderer(slug);\n if (custom) return custom(fields, { renderChildren: ctx.renderChildren });\n // The real slug is known only here — the class carries `sanitizeIdent(slug)`,\n // and a hint that names the wrong one to register is no hint.\n ctx.onUnrenderedBlock?.(blockType, classes);\n }\n return `<${tag} class=\"${classes}\"></${tag}>`;\n}\n\nconst blockRenderer: NodeRenderer = (node, ctx) => renderBlockNode(node, ctx, 'div', 'lp-block');\n\nconst inlineBlockRenderer: NodeRenderer = (node, ctx) =>\n renderBlockNode(node, ctx, 'span', 'lp-inline-block');\n\nexport { blockRenderer, inlineBlockRenderer };\n","/** `table` / `tablerow` / `tablecell` renderers for the `@lexical/table` shapes Payload's table feature emits. */\n\nimport type { NodeRenderer } from '../registry';\nimport { dirAttribute } from '../utils';\n\n// `@lexical/table` TableCellHeaderStates: ROW marks a cell in a header row, COLUMN one in a header column.\nconst HEADER_ROW = 1;\nconst HEADER_COLUMN = 2;\n\nconst tableRenderer: NodeRenderer = (node, ctx) =>\n `<table${dirAttribute(node)}><tbody>${ctx.renderChildren(node.children ?? [])}</tbody></table>`;\n\nconst tableRowRenderer: NodeRenderer = (node, ctx) =>\n `<tr>${ctx.renderChildren(node.children ?? [])}</tr>`;\n\nconst tableCellRenderer: NodeRenderer = (node, ctx): string => {\n const header = typeof node['headerState'] === 'number' ? node['headerState'] : 0;\n const tag = (header & (HEADER_ROW | HEADER_COLUMN)) === 0 ? 'td' : 'th';\n const scope =\n header === HEADER_ROW ? ' scope=\"col\"' : header === HEADER_COLUMN ? ' scope=\"row\"' : '';\n return `<${tag}${scope}${spanAttribute('colspan', node['colSpan'])}${spanAttribute('rowspan', node['rowSpan'])}>${ctx.renderChildren(node.children ?? [])}</${tag}>`;\n};\n\nfunction spanAttribute(name: string, value: unknown): string {\n return typeof value === 'number' && value > 1 ? ` ${name}=\"${String(value)}\"` : '';\n}\n\nexport { tableRenderer, tableRowRenderer, tableCellRenderer };\n","import type { NodeRenderer } from '../registry';\nimport { textRenderer } from './text';\nimport { paragraphRenderer } from './paragraph';\nimport { headingRenderer } from './heading';\nimport { listRenderer, listItemRenderer } from './list';\nimport { linkRenderer } from './link';\nimport { quoteRenderer } from './quote';\nimport { codeRenderer, codeHighlightRenderer } from './code';\nimport { linebreakRenderer, horizontalRuleRenderer, tabRenderer } from './linebreak';\nimport { uploadRenderer } from './upload';\nimport { relationshipRenderer } from './relationship';\nimport { blockRenderer, inlineBlockRenderer } from './block';\nimport { tableCellRenderer, tableRenderer, tableRowRenderer } from './table';\n\n// A value table instead of `register()` calls at import time: a consumer that\n// never renders Lexical content must not carry these under `sideEffects: false`.\nexport const BUILTIN_NODE_RENDERERS: Readonly<Record<string, NodeRenderer>> = {\n text: textRenderer,\n paragraph: paragraphRenderer,\n heading: headingRenderer,\n list: listRenderer,\n listitem: listItemRenderer,\n link: linkRenderer,\n autolink: linkRenderer,\n quote: quoteRenderer,\n code: codeRenderer,\n 'code-highlight': codeHighlightRenderer,\n linebreak: linebreakRenderer,\n horizontalrule: horizontalRuleRenderer,\n tab: tabRenderer,\n upload: uploadRenderer,\n relationship: relationshipRenderer,\n block: blockRenderer,\n inlineBlock: inlineBlockRenderer,\n table: tableRenderer,\n tablerow: tableRowRenderer,\n tablecell: tableCellRenderer,\n};\n","/** `text` renderer. Format flags wrap in a fixed order so equal input gives byte-equal output. */\n\nimport { escapeHtml } from '@security/escape';\nimport type { LexicalNode } from '../types';\nimport { TextFormat } from '../types';\nimport type { NodeRenderer } from '../registry';\n\nconst textRenderer: NodeRenderer = (node: LexicalNode): string => {\n const raw = typeof node.text === 'string' ? node.text : '';\n let out = escapeHtml(raw);\n const format = typeof node.format === 'number' ? node.format : 0;\n if ((format & TextFormat.CODE) !== 0) out = `<code>${out}</code>`;\n if ((format & TextFormat.BOLD) !== 0) out = `<strong>${out}</strong>`;\n if ((format & TextFormat.ITALIC) !== 0) out = `<em>${out}</em>`;\n if ((format & TextFormat.UNDERLINE) !== 0) out = `<u>${out}</u>`;\n if ((format & TextFormat.STRIKETHROUGH) !== 0) out = `<s>${out}</s>`;\n if ((format & TextFormat.SUBSCRIPT) !== 0) out = `<sub>${out}</sub>`;\n if ((format & TextFormat.SUPERSCRIPT) !== 0) out = `<sup>${out}</sup>`;\n if ((format & TextFormat.HIGHLIGHT) !== 0) out = `<mark>${out}</mark>`;\n return out;\n};\n\nexport { textRenderer };\n","/**\n * Lexical document types. Only `type` and `children` are required; every\n * other property is forwarded opaquely to the renderer for that node type.\n */\n\n/** Lexical text-format bitmask; flags combine (`BOLD | ITALIC === 3`). @internal */\nexport const TextFormat = {\n BOLD: 1,\n ITALIC: 2,\n STRIKETHROUGH: 4,\n UNDERLINE: 8,\n CODE: 16,\n SUBSCRIPT: 32,\n SUPERSCRIPT: 64,\n HIGHLIGHT: 128,\n} as const;\n\nexport interface LexicalNode {\n readonly type: string;\n readonly version?: number;\n readonly format?: number | string;\n readonly indent?: number;\n readonly direction?: 'ltr' | 'rtl' | null;\n readonly children?: readonly LexicalNode[];\n readonly text?: string;\n readonly [extra: string]: unknown;\n}\n\nexport interface LexicalRoot {\n readonly root: {\n readonly type?: string;\n readonly children: readonly LexicalNode[];\n readonly direction?: 'ltr' | 'rtl' | null;\n readonly format?: number | string;\n readonly indent?: number;\n readonly [extra: string]: unknown;\n };\n}\n","/** `list` / `listitem` renderers: `bullet` → `<ul>`, `number` → `<ol>`, `check` → `<ul role=\"list\">` with `aria-checked` items. */\n\nimport { escapeHtml } from '@security/escape';\nimport type { NodeRenderer } from '../registry';\nimport { dirAttribute, layoutClassAttribute } from '../utils';\n\nconst listRenderer: NodeRenderer = (node, ctx): string => {\n const listType = typeof node['listType'] === 'string' ? node['listType'] : 'bullet';\n const tag = listType === 'number' ? 'ol' : 'ul';\n const startAttr =\n listType === 'number' && typeof node['start'] === 'number' && node['start'] > 1\n ? ` start=\"${String(node['start'])}\"`\n : '';\n const checkAttr = listType === 'check' ? ' role=\"list\"' : '';\n const children = ctx.renderChildren(node.children ?? []);\n return `<${tag}${dirAttribute(node)}${layoutClassAttribute(node)}${startAttr}${checkAttr}>${children}</${tag}>`;\n};\n\nconst listItemRenderer: NodeRenderer = (node, ctx): string => {\n const children = ctx.renderChildren(node.children ?? []);\n if (typeof node['checked'] === 'boolean') {\n const state = node['checked'] ? 'true' : 'false';\n return `<li role=\"checkbox\" aria-checked=\"${state}\"${layoutClassAttribute(node)}>${children}</li>`;\n }\n const valueAttr =\n typeof node['value'] === 'number' ? ` value=\"${escapeHtml(String(node['value']))}\"` : '';\n return `<li${dirAttribute(node)}${layoutClassAttribute(node)}${valueAttr}>${children}</li>`;\n};\n\nexport { listRenderer, listItemRenderer };\n","import type { NodeRenderer } from '../registry';\nimport { dirAttribute, layoutClassAttribute } from '../utils';\n\nconst quoteRenderer: NodeRenderer = (node, ctx): string => {\n const children = ctx.renderChildren(node.children ?? []);\n return `<blockquote${dirAttribute(node)}${layoutClassAttribute(node)}>${children}</blockquote>`;\n};\n\nexport { quoteRenderer };\n","import type { NodeRenderer } from '../registry';\n\nconst linebreakRenderer: NodeRenderer = () => '<br>';\nconst horizontalRuleRenderer: NodeRenderer = () => '<hr>';\nconst tabRenderer: NodeRenderer = () => '\\t';\n\nexport { linebreakRenderer, horizontalRuleRenderer, tabRenderer };\n","/** Node-renderer registry: consumer registrations layered over the built-in table. */\n\nimport type { LexicalNode } from './types';\nimport { BUILTIN_NODE_RENDERERS } from './nodes/builtin';\n\nexport interface RenderNodeContext {\n /** Render child nodes through the registry. */\n readonly renderChildren: (children: readonly LexicalNode[]) => string;\n /** Text alignment of a block node, or `undefined`. */\n readonly resolveAlignment: (node: LexicalNode) => string | undefined;\n /** Indent level of a node, `0` when none. */\n readonly resolveIndent: (node: LexicalNode) => number;\n /**\n * Where a `block` or `inlineBlock` without a renderer is reported, with the\n * slug Payload sent and the class of the placeholder written in its place.\n * `undefined` on a plain `lexicalToHtml()` call; the `richText` write sets it.\n */\n readonly onUnrenderedBlock?: ((blockType: string, placeholderClass: string) => void) | undefined;\n}\n\nexport type NodeRenderer = (node: LexicalNode, context: RenderNodeContext) => string;\n\nconst registry = new Map<string, NodeRenderer>();\n\n/** Register or replace the renderer for `type`. */\nexport function register(type: string, renderer: NodeRenderer): void {\n registry.set(type, renderer);\n}\n\n/** @internal */\nexport function lookup(type: string): NodeRenderer | undefined {\n return registry.get(type) ?? BUILTIN_NODE_RENDERERS[type];\n}\n\nexport function registeredTypes(): readonly string[] {\n return [...new Set([...Object.keys(BUILTIN_NODE_RENDERERS), ...registry.keys()])];\n}\n\n/** Test-only: drop consumer registrations. */\nexport function __resetForTests(): void {\n registry.clear();\n}\n","/**\n * Lexical → HTML. Each node dispatches to the renderer registered for its\n * `type`; an unknown node renders its children so content is never lost.\n */\n\nimport { sanitizeHtml, hasSanitizerDocument, type SanitizerDocument } from '@security/sanitizer';\nimport { lookup, type RenderNodeContext } from './registry';\nimport type { LexicalNode, LexicalRoot } from './types';\nimport { resolveAlignment, resolveIndent } from './utils';\n\nexport interface LexicalRenderOptions {\n /** Pass the result through `sanitizeHtml()` (default `true`). */\n readonly sanitize?: boolean;\n /**\n * The DOM the sanitizer parses with, for this call: an SSR document such as\n * linkedom's or jsdom's. Without it the document `setSanitizerDocument()`\n * supplied is used, then the global one; with neither the result is\n * unsanitised and warns once.\n */\n readonly document?: SanitizerDocument;\n /**\n * Throw instead of returning unsanitised HTML when no document is available:\n * the `SanitizerEnvironmentError` `sanitizeHtml()` throws (ADR 0025). Off in\n * 2.x, where the call warns once and returns the markup; the default in 3.0.\n */\n readonly requireDocument?: boolean;\n /**\n * Called for every `block` or `inlineBlock` the registry has no renderer\n * for, with the block's slug as Payload sent it and the class its empty\n * placeholder carries. The `richText` write listens: it is the one caller\n * that later knows whether the server's markup for the block survived, so\n * the diagnostic is spoken there (LP0410, LP0413), not here.\n */\n readonly onUnrenderedBlock?: (blockType: string, placeholderClass: string) => void;\n}\n\nlet warnedNoSanitizer = false;\n\n/** @internal */\nexport function isLexicalContent(value: unknown): value is LexicalRoot {\n if (typeof value !== 'object' || value === null) return false;\n if (!('root' in value)) return false;\n const root = value.root;\n if (typeof root !== 'object' || root === null) return false;\n if (!('children' in root)) return false;\n return Array.isArray(root.children);\n}\n\n/** Render a Lexical document to HTML; without a document the result is unsanitised and warns once, or throws under `requireDocument`. */\nexport function lexicalToHtml(content: LexicalRoot, options: LexicalRenderOptions = {}): string {\n if (!isLexicalContent(content)) return '';\n const html = createContext(options.onUnrenderedBlock).renderChildren(content.root.children);\n if (options.sanitize === false) return html;\n if (options.document !== undefined) return sanitizeHtml(html, { document: options.document });\n // Without a DOM this throws the sanitizer's own error.\n if (options.requireDocument === true || hasSanitizerDocument()) return sanitizeHtml(html);\n warnNoSanitizerOnce();\n return html;\n}\n\n/** Plain text of a document, paragraphs separated by `\\n`. */\nexport function lexicalToPlainText(content: LexicalRoot): string {\n if (!isLexicalContent(content)) return '';\n return content.root.children.map(extractPlainText).join('\\n').trim();\n}\n\n/** Test-only: allow the SSR warning to fire again. */\nexport function __resetSanitizerWarningForTests(): void {\n warnedNoSanitizer = false;\n}\n\n/**\n * One context per document: `renderChildren` closes over it so a nested\n * block — a `block` inside a list item, an `inlineBlock` inside a paragraph —\n * reports to the same listener as a top-level one.\n */\nfunction createContext(\n onUnrenderedBlock: RenderNodeContext['onUnrenderedBlock'],\n): RenderNodeContext {\n const context: RenderNodeContext = {\n renderChildren: (children) => {\n let out = '';\n for (const child of children) out += renderNode(child, context);\n return out;\n },\n resolveAlignment,\n resolveIndent,\n onUnrenderedBlock,\n };\n return context;\n}\n\nfunction renderNode(node: LexicalNode, context: RenderNodeContext): string {\n const renderer = lookup(node.type);\n if (renderer) return renderer(node, context);\n return node.children !== undefined ? context.renderChildren(node.children) : '';\n}\n\nfunction extractPlainText(node: LexicalNode): string {\n if (typeof node.text === 'string') return node.text;\n if (node.type === 'linebreak') return '\\n';\n if (node.children === undefined) return '';\n let out = '';\n for (const child of node.children) out += extractPlainText(child);\n return out;\n}\n\n// This layer may not import `@core/diagnostics` (architecture policy), so the\n// warn-once lives here; a hostile or absent console must not break rendering.\nfunction warnNoSanitizerOnce(): void {\n if (warnedNoSanitizer) return;\n warnedNoSanitizer = true;\n try {\n console.warn(\n '[live-preview] lexicalToHtml() has no sanitizer document and returned unsanitised HTML; ' +\n 'pass { document } (linkedom, jsdom) per call. 3.0 throws here instead: opt in now with ' +\n '{ requireDocument: true }. See \"HTML sanitization\" in docs/security.md.',\n );\n } catch {\n // Diagnostics never become a second failure.\n }\n}\n","/**\n * `text` / `textarea` renderer. An element with structured children is left\n * alone (warned once) unless it opts in with `data-payload-text`, so a styled\n * wrapper is not destroyed by a value meant for its text node. An element whose\n * text already reads the value is left alone either way.\n */\n\nimport { isLexicalContent, lexicalToPlainText } from '@lexical/render';\nimport { trustedHtml } from '@security/trusted-types';\nimport { escapeAndLinebreak } from '@security/escape';\nimport { safeConsoleWarn } from '@core/diagnostics';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport type { FieldRenderer, RendererKey } from '@core/types';\n\nconst TEXT_OPT_IN_ATTRIBUTE = 'data-payload-text';\n\n/** Build the renderer with its own warn-once state; one per client (ADR 0002). */\nexport function createTextRenderer(name: RendererKey = 'text'): FieldRenderer {\n const warnedElements = new WeakSet<Element>();\n\n return {\n name,\n render: /* @__PURE__ */ markNoWriteCallback((target, value) => {\n const element = target.element;\n const text = toPlainString(value);\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n (element as HTMLInputElement | HTMLTextAreaElement).value = text;\n return;\n }\n // Writing the same words again would only drop the markup the server\n // drew around them, such as a `<span lang>`.\n if (element.textContent.trim() === text.trim()) return;\n if (hasForeignChildren(element) && !element.hasAttribute(TEXT_OPT_IN_ATTRIBUTE)) {\n warnOnce(warnedElements, element, target.fieldName);\n return false;\n }\n if (text.includes('\\n') || text.includes('\\r')) {\n element.innerHTML = trustedHtml(escapeAndLinebreak(text));\n return;\n }\n element.textContent = text;\n return;\n }),\n };\n}\n\n// `<br>` is this renderer's own multiline output, not a consumer wrapper;\n// counting it froze every multiline binding after its first write.\nfunction hasForeignChildren(element: Element): boolean {\n return element.querySelector(':scope > :not(br)') !== null;\n}\n\nfunction warnOnce(warnedElements: WeakSet<Element>, element: Element, fieldName: string): void {\n if (warnedElements.has(element)) return;\n warnedElements.add(element);\n safeConsoleWarn(\n `[live-preview] LP0402: Skipping text update for \"${fieldName}\": ` +\n `<${element.tagName.toLowerCase()}> has structured children. Move ` +\n `data-payload-field to the value element, or add data-payload-text to replace them.`,\n );\n}\n\nfunction toPlainString(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (isLexicalContent(value)) return lexicalToPlainText(value);\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n return JSON.stringify(value);\n}\n","/**\n * `richText` renderer: a Lexical root or an HTML string. A project\n * `renderRichText` takes precedence; its output is sanitised like every\n * other HTML write.\n *\n * The Lexical write keeps the markup the server rendered for a block the\n * registry cannot render, rather than replacing it with the empty placeholder\n * the node renderer produces for one, and it keeps the wrapper a template put\n * around the whole field. The verdict is spoken here, after the write, because\n * only the write knows it: LP0410 when the server's markup stands, LP0413 when\n * the two trees did not line up and it is gone — and the second goes through\n * `context.reportUnfaithful` too, which is the case `onUnfaithfulPatch`\n * escalates.\n */\n\nimport { isLexicalContent, lexicalToHtml } from '@lexical/render';\nimport { UNRENDERED_BLOCK_SELECTOR } from '@lexical/nodes/block';\nimport { trustedHtml } from '@security/trusted-types';\nimport { sanitizeHtmlWithPolicy } from '@security/sanitizer';\nimport { isEmptyLexicalRoot } from '@core/binding-writer';\nimport { FIELD_ATTRIBUTE } from '@core/cache';\nimport { safeConsoleWarn } from '@core/diagnostics';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport type { CachedElement, FieldRenderer, RenderContext } from '@core/types';\nimport { isEmptyValue } from './utils';\n\n/** Block slugs already reported, one set per verdict: a block kept once may still be lost later. */\nconst warnedKept = new Set<string>();\nconst warnedLost = new Set<string>();\n\n/** The containers a template wraps rich text in; Lexical renders none of them for content. */\nconst WRAPPER_TAGS: ReadonlySet<string> = new Set(['DIV', 'SECTION', 'ARTICLE']);\n\nconst richTextRenderer: FieldRenderer = {\n name: 'richText',\n render: /* @__PURE__ */ markNoWriteCallback((target, value, context) => {\n const element = target.element;\n if (isEmptyValue(value)) {\n element.textContent = '';\n return;\n }\n const policy = context.sanitizerPolicy;\n if (context.renderRichText !== undefined) {\n const html = context.renderRichText(value, {\n fieldName: target.fieldName,\n element,\n locale: context.locale,\n });\n element.innerHTML = trustedHtml(sanitizeHtmlWithPolicy(html, policy));\n return;\n }\n if (isLexicalContent(value)) {\n // Empty paragraphs only: cleared as `null` is. A project renderer above decides for itself.\n if (isEmptyLexicalRoot(value)) {\n element.textContent = '';\n return;\n }\n // Slug by placeholder class: the class is what the write finds standing.\n const unrendered = new Map<string, string>();\n const lexical = lexicalToHtml(value, {\n // Lexical would otherwise sanitise with the process default; the sink\n // below does it with the instance's policy instead.\n sanitize: false,\n onUnrenderedBlock: (blockType, placeholderClass) => {\n unrendered.set(placeholderClass, blockType);\n },\n });\n const verdicts = writeKeepingUnrenderedBlocks(\n element,\n sanitizeHtmlWithPolicy(lexical, policy),\n );\n for (const [placeholderClass, lost] of verdicts) {\n const blockType = unrendered.get(placeholderClass);\n if (blockType !== undefined) reportUnrenderedBlock(target, context, blockType, lost);\n }\n return;\n }\n if (typeof value === 'string') {\n element.innerHTML = trustedHtml(sanitizeHtmlWithPolicy(value, policy));\n return;\n }\n return false;\n }),\n};\n\n/**\n * Write `html` into `element`, but move the live element standing where an\n * unrendered block's placeholder stands over into the new tree first. Every\n * pairing is resolved before the first move: a move takes a child out of the\n * live element, which would shift the position each later one is read at.\n *\n * Returns a verdict per placeholder class: `false` where a live element that\n * was not itself a placeholder took the placeholder's place, `true` where one\n * is still standing over markup the element had — the descent found no\n * counterpart, so this write lost what the server drew for that block. No\n * verdict where there was nothing to keep: a container the page left empty,\n * or a placeholder an earlier write put there, whose loss was reported then.\n */\nfunction writeKeepingUnrenderedBlocks(\n element: Element,\n html: string,\n): ReadonlyMap<string, boolean> {\n const rendered = element.cloneNode(false) as Element;\n rendered.innerHTML = trustedHtml(html);\n const target = wrapperOf(element, rendered) ?? element;\n const verdicts = new Map<string, boolean>();\n const placeholders = rendered.querySelectorAll(UNRENDERED_BLOCK_SELECTOR);\n if (placeholders.length > 0 && target.firstElementChild !== null) {\n const pairs: [placeholder: Element, live: Element][] = [];\n pairUnrenderedBlocks(target, rendered, pairs);\n for (const [placeholder, live] of pairs) {\n placeholder.replaceWith(live);\n if (!live.matches(UNRENDERED_BLOCK_SELECTOR)) verdicts.set(placeholder.className, false);\n }\n // A placeholder the moves left in the tree is one no live element answered for.\n for (const placeholder of placeholders) {\n if (placeholder.parentNode !== null) verdicts.set(placeholder.className, true);\n }\n }\n target.replaceChildren(...rendered.childNodes);\n return verdicts;\n}\n\n/**\n * The one wrapper a template puts around rich text when the server renders it\n * — `<div class=\"prose\">` around the blocks, the usual Tailwind shape — or\n * `null` when the rendered document is written straight into `element`. The\n * wrapper stays, because the typography hangs on its class, and the pairing\n * runs inside it, where the blocks are; without this the live tree had one\n * child where the rendered one had five, and the descent stopped before it\n * reached the block (measured on the demo, Z29).\n *\n * A wrapper is the element's only child, of a kind Lexical does not render\n * content as, with no binding of its own, standing where the rendered document\n * has elements unlike it: a `<div>` a registered block renders is content, and\n * the paragraph typed after it must not be written into it. A document of one\n * element keeps the wrapper too, unless that element is a placeholder or of\n * the wrapper's own tag: then the wrapper may be the block the server drew, and\n * the positional pairing answers for it.\n */\nfunction wrapperOf(element: Element, rendered: Element): Element | null {\n const child = element.firstElementChild;\n const only = rendered.children.length === 1 ? rendered.firstElementChild : null;\n if (child?.nextElementSibling !== null || rendered.children.length === 0) return null;\n if (!WRAPPER_TAGS.has(child.tagName) || child.hasAttribute(FIELD_ATTRIBUTE)) return null;\n if (only?.tagName === child.tagName || only?.matches(UNRENDERED_BLOCK_SELECTOR) === true) {\n return null;\n }\n for (const block of rendered.children) {\n if (block.tagName === child.tagName && block.className === child.className) return null;\n }\n return child;\n}\n\n/**\n * Pair each placeholder with the live element in its position. Both trees\n * describe the same document, so position is the only key there is — the server\n * writes no id to match on. Where the child counts differ, an edit added or\n * removed a node somewhere in between: the pairing walks in from both ends and\n * stops at the first two that cannot be one node, two tags, or a placeholder\n * against an element of a tag the document renders beside it. A placeholder\n * left in between is written, which is what this renderer did before.\n */\nfunction pairUnrenderedBlocks(\n live: Element,\n rendered: Element,\n kept: [placeholder: Element, live: Element][],\n): void {\n const pair = (block: Element, element: Element): void => {\n if (block.matches(UNRENDERED_BLOCK_SELECTOR)) kept.push([block, element]);\n else pairUnrenderedBlocks(element, block, kept);\n };\n // Nothing moves until every pairing is known, so walking siblings is stable.\n let element = live.firstElementChild;\n let block = rendered.firstElementChild;\n if (live.children.length === rendered.children.length) {\n for (; element !== null && block !== null; element = element.nextElementSibling) {\n pair(block, element);\n block = block.nextElementSibling;\n }\n return;\n }\n const tags = new Set<string>();\n for (const child of rendered.children) {\n if (!child.matches(UNRENDERED_BLOCK_SELECTOR)) tags.add(child.tagName);\n }\n const fits = (candidate: Element, standing: Element): boolean =>\n candidate.matches(UNRENDERED_BLOCK_SELECTOR)\n ? !tags.has(standing.tagName)\n : candidate.tagName === standing.tagName;\n let front = 0;\n for (; element !== null && block !== null && fits(block, element); front += 1) {\n pair(block, element);\n element = element.nextElementSibling;\n block = block.nextElementSibling;\n }\n const shorter = Math.min(live.children.length, rendered.children.length);\n element = live.lastElementChild;\n block = rendered.lastElementChild;\n for (let back = front; back < shorter && element !== null && block !== null; back += 1) {\n if (!fits(block, element)) return;\n pair(block, element);\n element = element.previousElementSibling;\n block = block.previousElementSibling;\n }\n}\n\n/**\n * Say what became of a block nobody registered a renderer for, once per slug\n * and verdict. Not through the runtime's `warn` option: a renderer has no\n * channel to it, and `RenderContext` carries the one thing that matters more —\n * the report that lets a strategy redraw the region the write just degraded.\n */\nfunction reportUnrenderedBlock(\n target: CachedElement,\n context: RenderContext,\n blockType: string,\n lost: boolean,\n): void {\n if (lost) {\n context.reportUnfaithful?.(target, `lost the markup the server drew for block \"${blockType}\"`);\n }\n const warned = lost ? warnedLost : warnedKept;\n if (warned.has(blockType)) return;\n warned.add(blockType);\n safeConsoleWarn(\n `[live-preview] ${\n lost\n ? `LP0413: no renderer for block \"${blockType}\", and the markup the server rendered for it is lost.`\n : `LP0410: no renderer for block \"${blockType}\"; keeping what the server rendered for it.`\n } Register one with registerBlockRenderer().`,\n );\n}\n\n/** Test-only: let LP0410 and LP0413 fire again. */\nexport function __resetBlockWarningsForTests(): void {\n warnedKept.clear();\n warnedLost.clear();\n}\n\nexport { richTextRenderer };\n","/** `html` renderer (`data-payload-type=\"html\"`): the value is sanitised, then injected. */\n\nimport { sanitizeHtmlWithPolicy } from '@security/sanitizer';\nimport { trustedHtml } from '@security/trusted-types';\nimport type { FieldRenderer } from '@core/types';\nimport { isEmptyValue, safeStringify } from './utils';\n\nconst htmlRenderer: FieldRenderer = {\n name: 'html',\n render(target, value, context) {\n if (isEmptyValue(value)) {\n target.element.textContent = '';\n return;\n }\n const html = typeof value === 'string' ? value : safeStringify(value);\n target.element.innerHTML = trustedHtml(sanitizeHtmlWithPolicy(html, context.sanitizerPolicy));\n },\n};\n\nexport { htmlRenderer };\n","/** URL acceptance shared by the renderers that write `href` / `src`: one LP0401 warning per element. */\n\nimport { safeConsoleWarn } from '@core/diagnostics';\nimport { resolveMediaUrl } from '@lexical/value-shapes';\nimport { isSafeUrl } from '@security/url-validator';\n\n// Keyed by element so a second client on the same page does not repeat the warning.\nconst warned = new WeakSet<Element>();\n\nexport type UrlOutcome =\n | { readonly kind: 'none' }\n | { readonly kind: 'unsafe' }\n | { readonly kind: 'safe'; readonly url: string };\n\n/**\n * `none` when there is no URL to write, `unsafe` (warned once) when it fails `isSafeUrl`.\n * `serverURL` is passed for a URL out of a media document only: a path in it is Payload's\n * (`resolveMediaUrl`), while one an author typed into a text field is the site's own.\n */\nexport function acceptUrl(\n element: Element,\n fieldName: string,\n candidate: unknown,\n serverURL?: string,\n): UrlOutcome {\n if (typeof candidate !== 'string' || candidate.length === 0) return { kind: 'none' };\n const url = resolveMediaUrl(candidate, serverURL);\n if (isSafeUrl(url)) return { kind: 'safe', url };\n if (!warned.has(element)) {\n warned.add(element);\n safeConsoleWarn(\n `[live-preview] LP0401: refused an unsafe URL for \"${fieldName}\" on ` +\n `<${element.tagName.toLowerCase()}>; the attribute was cleared.`,\n );\n }\n return { kind: 'unsafe' };\n}\n","/**\n * `url` renderer and the factory the `email` renderer shares. On an `<a>` the\n * value (or the `data-payload-href` sibling) becomes `href`; the value is\n * always the visible text.\n */\n\nimport { resolveFieldValue } from '@core/field-value';\nimport type { FieldRenderer, RendererKey } from '@core/types';\nimport { acceptUrl } from './unsafe-url';\nimport { isEmptyValue, safeStringify } from './utils';\n\n/** Build the link renderer named `name`; `toHref` derives the URL from the field value. */\nexport function createLinkRenderer(\n name: RendererKey,\n toHref: (value: string) => string = (value) => value,\n): FieldRenderer {\n return {\n name,\n render(target, value, context) {\n const element = target.element;\n if (isEmptyValue(value)) {\n clear(element);\n return;\n }\n const text = safeStringify(value);\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n (element as HTMLInputElement | HTMLTextAreaElement).value = text;\n return;\n }\n if (element.tagName === 'A') {\n const hrefField = target.hrefField;\n const candidate =\n hrefField === undefined || hrefField.length === 0\n ? toHref(text)\n : resolveFieldValue(\n context.allFields,\n hrefField,\n context.locale,\n target.locale !== undefined,\n );\n const outcome = acceptUrl(element, target.fieldName, candidate);\n if (outcome.kind === 'safe') element.setAttribute('href', outcome.url);\n else if (outcome.kind === 'unsafe') element.removeAttribute('href');\n }\n element.textContent = text;\n },\n };\n}\n\nfunction clear(element: Element): void {\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n (element as HTMLInputElement | HTMLTextAreaElement).value = '';\n return;\n }\n element.removeAttribute('href');\n element.textContent = '';\n}\n\nexport const urlRenderer: FieldRenderer = createLinkRenderer('url');\n","/** `email` renderer: a bare address becomes a `mailto:` link, a value with a scheme is used as written. */\n\nimport type { FieldRenderer } from '@core/types';\nimport { createLinkRenderer } from './url';\n\nconst HAS_SCHEME = /^[a-zA-Z][a-zA-Z0-9+.-]*:/;\n\nfunction mailtoHref(value: string): string {\n const trimmed = value.trim();\n if (HAS_SCHEME.test(trimmed) || !trimmed.includes('@')) return trimmed;\n return `mailto:${trimmed}`;\n}\n\nexport const emailRenderer: FieldRenderer = createLinkRenderer('email', mailtoHref);\n","/** `<img>` writes shared by the image and upload renderers. */\n\nimport { isSafeUrl } from '@security/url-validator';\nimport { resolveMediaUrl, type MediaShape } from '@lexical/value-shapes';\n\nconst IMAGE_SOURCE_ATTRIBUTES = ['src', 'srcset', 'sizes'] as const;\n\n/** One image a media document offers: the original, or one of its `sizes`. */\ninterface Source {\n readonly name?: string;\n readonly url: string;\n readonly width: number;\n readonly height?: number | undefined;\n readonly mimeType?: string | undefined;\n}\n\n/** The size each `<img>` was last written with, so the next image the editor picks gets the same one. */\nconst chosenSizes = new WeakMap<HTMLImageElement, string>();\n\nexport function clearImage(img: HTMLImageElement): void {\n for (const name of IMAGE_SOURCE_ATTRIBUTES) img.removeAttribute(name);\n}\n\n/**\n * A server-rendered `srcset` would keep winning over a new `src`, so it is\n * rebuilt or removed together with `sizes`. It offers the picture the element\n * shows: the size whose URL the element's `src` is — the template's choice, or\n * the last write's once the editor picks another image — else the original,\n * and of the rest only what has its shape and format, one per width. A crop\n * of another shape is another picture. `url` is already resolved; the sizes\n * are resolved against `serverURL`.\n */\nexport function writeImage(\n img: HTMLImageElement,\n url: string,\n media: MediaShape | undefined,\n serverURL?: string,\n): void {\n const sizes = sizeSources(media, serverURL);\n const shown = img.getAttribute('src');\n const chosen =\n sizes.find((size) => shown !== null && sameUrl(img, size.url, shown)) ??\n sizes.find((size) => size.name === chosenSizes.get(img));\n if (chosen?.name === undefined) chosenSizes.delete(img);\n else chosenSizes.set(img, chosen.name);\n img.src = chosen?.url ?? url;\n const shape = chosen ?? media;\n const candidates = sizes.filter((size) => sameShape(size, shape));\n if (candidates.length === 0) {\n img.removeAttribute('srcset');\n img.removeAttribute('sizes');\n return;\n }\n if (typeof media?.width === 'number' && typeof media.url === 'string') {\n const original = resolveMediaUrl(media.url, serverURL);\n const source = { ...media, url: original, width: media.width };\n if (isSafeUrl(original) && sameShape(source, shape)) candidates.push(source);\n }\n // Two candidates of one width say nothing the first does not; the browser keeps the first anyway.\n const widths = new Set<number>();\n const parts: string[] = [];\n for (const source of candidates) {\n if (widths.has(source.width)) continue;\n widths.add(source.width);\n parts.push(`${srcsetUrl(source.url)} ${String(source.width)}w`);\n }\n const srcset = parts.join(', ');\n img.setAttribute('srcset', srcset);\n}\n\nfunction sizeSources(media: MediaShape | undefined, serverURL: string | undefined): Source[] {\n const sources: Source[] = [];\n for (const [name, size] of Object.entries(media?.sizes ?? {})) {\n if (typeof size.url !== 'string' || typeof size.width !== 'number') continue;\n const url = resolveMediaUrl(size.url, serverURL);\n if (isSafeUrl(url)) sources.push({ ...size, name, url, width: size.width });\n }\n return sources;\n}\n\nfunction sameUrl(img: HTMLImageElement, a: string, b: string): boolean {\n try {\n return new URL(a, img.baseURI).href === new URL(b, img.baseURI).href;\n } catch {\n return a === b;\n }\n}\n\n/**\n * Whether `source` is the same picture as `shape` at another width. What\n * either leaves out cannot tell them apart. Payload scales a size's height\n * from the original's and rounds it, so a pixel at the larger width is the\n * same shape.\n */\nfunction sameShape(\n source: Partial<Source>,\n shape: (Pick<Source, 'height' | 'mimeType'> & { readonly width?: number }) | undefined,\n): boolean {\n if (shape === undefined) return true;\n if (\n typeof source.mimeType === 'string' &&\n typeof shape.mimeType === 'string' &&\n source.mimeType !== shape.mimeType\n ) {\n return false;\n }\n const { width, height } = shape;\n if (\n typeof width !== 'number' ||\n typeof height !== 'number' ||\n typeof source.width !== 'number' ||\n typeof source.height !== 'number'\n ) {\n return true;\n }\n return Math.abs(source.width * height - source.height * width) <= Math.max(width, source.width);\n}\n\n// Commas and whitespace delimit srcset candidates and cannot appear raw in a URL there.\nfunction srcsetUrl(url: string): string {\n return url.replace(/[\\s,]/g, encodeURIComponent);\n}\n","/**\n * `image` renderer: `src`/`alt`/`srcset` on an `<img>`, a CSS background on\n * anything else. The value is a media object, a URL string, or resolved from\n * the `data-payload-src` / `data-payload-alt` sibling fields; a binding whose\n * alt is its own field holds alt text, not a source.\n */\n\nimport { escapeCssUrl } from '@security/escape';\nimport { resolveFieldValue } from '@core/field-value';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport type { CachedElement, FieldRenderer, RenderContext } from '@core/types';\nimport { readMedia, type MediaShape } from '@lexical/value-shapes';\nimport { clearImage, writeImage } from './media';\nimport { acceptUrl } from './unsafe-url';\nimport { isEmptyValue } from './utils';\n\n/** A path, a file name or a URL: a `/`, `.` or `:` somewhere, and no whitespace anywhere. */\nconst NAMES_A_SOURCE = /^\\S*[/.:]\\S*$/;\n\nconst imageRenderer: FieldRenderer = {\n name: 'image',\n render: /* @__PURE__ */ markNoWriteCallback((target, value, context) => {\n const element = target.element;\n if (\n element.tagName === 'IMG' &&\n target.altField === target.fieldName &&\n target.srcField === undefined &&\n (typeof value === 'string' || isEmptyValue(value))\n ) {\n (element as HTMLImageElement).alt = value ?? '';\n return;\n }\n if (isEmptyValue(value)) {\n clear(element);\n return;\n }\n const preferLocale = target.locale !== undefined;\n const { media, candidate } = pickSource(target, value, context, preferLocale);\n // A word or an id is no address, though the URL parser would take either for a relative path.\n if (\n media === undefined &&\n typeof candidate === 'string' &&\n !NAMES_A_SOURCE.test(candidate.trim())\n ) {\n return false;\n }\n // Only a media document's path is Payload's; a string an author typed is the site's own.\n const outcome = acceptUrl(\n element,\n target.fieldName,\n candidate,\n media === undefined ? undefined : context.serverURL,\n );\n if (outcome.kind === 'none') return false;\n if (outcome.kind === 'unsafe') {\n clear(element);\n return;\n }\n if (element.tagName === 'IMG') {\n const img = element as HTMLImageElement;\n writeImage(img, outcome.url, media, context.serverURL);\n const alt = pickAlt(media, target.altField, context.allFields, context.locale, preferLocale);\n if (alt !== undefined) img.alt = alt;\n return;\n }\n (element as HTMLElement).style.backgroundImage = `url('${escapeCssUrl(outcome.url)}')`;\n return;\n }),\n};\n\nfunction clear(element: Element): void {\n if (element.tagName === 'IMG') clearImage(element as HTMLImageElement);\n else (element as HTMLElement).style.backgroundImage = '';\n}\n\nfunction pickSource(\n target: CachedElement,\n value: unknown,\n context: RenderContext,\n preferLocale: boolean,\n): { readonly media: MediaShape | undefined; readonly candidate: unknown } {\n const source =\n target.srcField !== undefined && target.srcField.length > 0\n ? resolveFieldValue(context.allFields, target.srcField, context.locale, preferLocale)\n : value;\n const media = readMedia(source);\n return { media, candidate: media === undefined ? source : media.url };\n}\n\nfunction pickAlt(\n media: MediaShape | undefined,\n altField: string | undefined,\n allFields: Record<string, unknown>,\n locale: string | undefined,\n preferLocale: boolean,\n): string | undefined {\n if (altField !== undefined && altField.length > 0) {\n const sibling = resolveFieldValue(allFields, altField, locale, preferLocale);\n return typeof sibling === 'string' ? sibling : undefined;\n }\n return media?.alt;\n}\n\nexport { imageRenderer };\n","/** `upload` renderer: an image on `<img>`, a download link on `<a>`, an injected link elsewhere. */\n\nimport { escapeHtml, escapeHtmlAttribute } from '@security/escape';\nimport { trustedHtml } from '@security/trusted-types';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport type { FieldRenderer } from '@core/types';\nimport { readMedia } from '@lexical/value-shapes';\nimport { clearImage, writeImage } from './media';\nimport { acceptUrl } from './unsafe-url';\nimport { isEmptyValue } from './utils';\n\nconst uploadRenderer: FieldRenderer = {\n name: 'upload',\n render: /* @__PURE__ */ markNoWriteCallback((target, value, context) => {\n const element = target.element;\n if (isEmptyValue(value)) {\n clear(element);\n return;\n }\n const media = readMedia(value);\n if (media === undefined) return false;\n const outcome = acceptUrl(element, target.fieldName, media.url, context.serverURL);\n if (outcome.kind === 'none') return false;\n if (outcome.kind === 'unsafe') {\n clear(element);\n return;\n }\n const url = outcome.url;\n if (element.tagName === 'IMG') {\n const img = element as HTMLImageElement;\n writeImage(img, url, media, context.serverURL);\n if (media.alt !== undefined) img.alt = media.alt;\n return;\n }\n if (element.tagName === 'A') {\n element.setAttribute('href', url);\n element.textContent = media.filename ?? url;\n return;\n }\n const label = escapeHtml(media.filename ?? url);\n element.innerHTML = trustedHtml(`<a href=\"${escapeHtmlAttribute(url)}\">${label}</a>`);\n return;\n }),\n};\n\nfunction clear(element: Element): void {\n if (element.tagName === 'IMG') {\n clearImage(element as HTMLImageElement);\n return;\n }\n element.removeAttribute('href');\n element.textContent = '';\n}\n\nexport { uploadRenderer };\n","/** `relationship` renderer: the relation's label as text; on an `<a>` a populated `url` becomes `href`. */\n\nimport type { FieldRenderer } from '@core/types';\nimport { asRecord, pickRelationLabel, type RelationShape } from '@lexical/value-shapes';\nimport { acceptUrl } from './unsafe-url';\nimport { isEmptyValue, safeStringify } from './utils';\n\nconst relationshipRenderer: FieldRenderer = {\n name: 'relationship',\n render(target, value) {\n const element = target.element;\n if (isEmptyValue(value)) {\n element.removeAttribute('href');\n element.textContent = '';\n return;\n }\n if (element.tagName === 'A' && !Array.isArray(value)) {\n const outcome = acceptUrl(element, target.fieldName, asRecord(value)?.['url']);\n if (outcome.kind === 'safe') element.setAttribute('href', outcome.url);\n else if (outcome.kind === 'unsafe') element.removeAttribute('href');\n }\n element.textContent = Array.isArray(value) ? value.map(label).join(', ') : label(value);\n },\n};\n\nfunction label(value: unknown): string {\n const record = asRecord(value) as RelationShape | undefined;\n if (record === undefined) return safeStringify(value);\n return pickRelationLabel(record) ?? '';\n}\n\nexport { relationshipRenderer };\n","/**\n * `select` / `radio` renderer. Form controls receive option values; other\n * elements show the option labels from the field schema when the admin sent\n * one, else the values.\n */\n\nimport type { FieldRenderer, RenderContext } from '@core/types';\nimport { asRecord } from '@lexical/value-shapes';\nimport { isEmptyValue, safeStringify } from './utils';\n\nconst selectRenderer: FieldRenderer = {\n name: 'select',\n render(target, value, context) {\n const element = target.element;\n const values = isEmptyValue(value) ? [] : toValues(value);\n if (element.tagName === 'SELECT') {\n writeSelect(element as HTMLSelectElement, values);\n return;\n }\n if (element.tagName === 'INPUT' && (element as HTMLInputElement).type === 'radio') {\n const radio = element as HTMLInputElement;\n radio.checked = values.includes(radio.value);\n return;\n }\n element.textContent = values.map((item) => labelFor(item, context)).join(', ');\n },\n};\n\nfunction toValues(value: unknown): readonly string[] {\n if (Array.isArray(value)) return value.map(safeStringify);\n return [safeStringify(value)];\n}\n\n// `.value = 'a, b'` on a multiple select selects nothing; options are set one by one.\nfunction writeSelect(select: HTMLSelectElement, values: readonly string[]): void {\n if (select.multiple) {\n for (const option of Array.from(select.options)) {\n option.selected = values.includes(option.value);\n }\n return;\n }\n select.value = values[0] ?? '';\n}\n\nfunction labelFor(value: string, context: RenderContext): string {\n const options = context.schema?.['options'];\n if (!Array.isArray(options)) return value;\n for (const option of options) {\n const record = asRecord(option);\n if (record === undefined || safeStringify(record['value']) !== value) continue;\n return typeof record['label'] === 'string' ? record['label'] : value;\n }\n return value;\n}\n\nexport { selectRenderer };\n","/** `checkbox` renderer: `checked` on an input, `aria-checked` where present, `true`/`false` text otherwise. */\n\nimport type { FieldRenderer } from '@core/types';\n\nconst FALSE_STRINGS = new Set(['', 'false', '0', 'off', 'no']);\n\nconst checkboxRenderer: FieldRenderer = {\n name: 'checkbox',\n render(target, value) {\n const element = target.element;\n const checked = toBoolean(value);\n if (element.tagName === 'INPUT' && (element as HTMLInputElement).type === 'checkbox') {\n (element as HTMLInputElement).checked = checked;\n return;\n }\n if (element.hasAttribute('aria-checked')) {\n element.setAttribute('aria-checked', checked ? 'true' : 'false');\n return;\n }\n element.textContent = checked ? 'true' : 'false';\n },\n};\n\n// Form state and query parameters arrive as strings; `Boolean('false')` is not an answer.\nfunction toBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return !FALSE_STRINGS.has(value.trim().toLowerCase());\n if (typeof value === 'number') return value !== 0;\n return value !== null && value !== undefined;\n}\n\nexport { checkboxRenderer };\n","/**\n * Memoised `Intl` formatters, keyed by locale and options. Constructing them\n * per call dominates render time for arrays of many numeric or date fields,\n * and a formatter is a pure function of its key, so one instance is safe to\n * share across the page. Bounded so a language switcher cannot grow it without\n * limit.\n */\n\nimport { lruGet, lruSet, lruTrim } from './lru';\n\nconst NUMBER_CACHE = new Map<string, Intl.NumberFormat>();\nconst DATE_CACHE = new Map<string, Intl.DateTimeFormat>();\n\nconst DEFAULT_MAX_ENTRIES = 64;\n\nlet maxEntries = DEFAULT_MAX_ENTRIES;\n\n/** Internal test helper — purges every cached formatter. */\nexport function __resetIntlCache(): void {\n NUMBER_CACHE.clear();\n DATE_CACHE.clear();\n maxEntries = DEFAULT_MAX_ENTRIES;\n}\n\n/** Adjust the LRU bound. Returns the previous value. */\nexport function setIntlCacheLimit(limit: number): number {\n if (!Number.isFinite(limit) || limit < 1) return maxEntries;\n const previous = maxEntries;\n maxEntries = Math.floor(limit);\n lruTrim(NUMBER_CACHE, maxEntries);\n lruTrim(DATE_CACHE, maxEntries);\n return previous;\n}\n\n/** Cache occupancy, for tests and dev observability. */\nexport function intlCacheSize(): { readonly numbers: number; readonly dates: number } {\n return { numbers: NUMBER_CACHE.size, dates: DATE_CACHE.size };\n}\n\nexport function getNumberFormat(\n locale: string | undefined,\n options?: Intl.NumberFormatOptions,\n): Intl.NumberFormat {\n const key = buildKey(locale, options);\n return (\n lruGet(NUMBER_CACHE, key) ??\n lruSet(NUMBER_CACHE, key, new Intl.NumberFormat(locale, options), maxEntries)\n );\n}\n\nexport function getDateTimeFormat(\n locale: string | undefined,\n options?: Intl.DateTimeFormatOptions,\n): Intl.DateTimeFormat {\n const key = buildKey(locale, options);\n return (\n lruGet(DATE_CACHE, key) ??\n lruSet(DATE_CACHE, key, new Intl.DateTimeFormat(locale, options), maxEntries)\n );\n}\n\nfunction buildKey(locale: string | undefined, options: unknown): string {\n // Stable key order so equivalent option objects share a slot, and an empty\n // one collapses to the bare-locale key.\n const localePart = locale ?? '';\n if (options === undefined || options === null) return localePart;\n const serialised = stableStringify(options);\n if (serialised === '{}') return localePart;\n return `${localePart}|${serialised}`;\n}\n\nfunction stableStringify(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value);\n if (Array.isArray(value)) {\n return `[${value.map((v) => stableStringify(v)).join(',')}]`;\n }\n const record = value as Record<string, unknown>;\n const keys = Object.keys(record).sort();\n const parts: string[] = [];\n for (const key of keys) {\n const inner = record[key];\n if (inner === undefined) continue;\n parts.push(`${JSON.stringify(key)}:${stableStringify(inner)}`);\n }\n return `{${parts.join(',')}}`;\n}\n","/**\n * `data-payload-format`: a closed vocabulary deciding how a date or a number is\n * written. Without it a bound price shows the raw amount and a bound date an\n * ISO instant, so a template that formats on the server has to leave both\n * unbound — which is where an edit becomes invisible.\n *\n * Closed on purpose. Anything a consumer could pass here would be code running\n * inside the preview, and the runtime takes no code from the page. Two\n * renderers read it, so the parsing lives beside them rather than in either.\n *\n * `relative` (\"in 3 days\") is deliberately absent: choosing the unit and its\n * rounding is policy, not formatting, and two readers will want different\n * answers. A project that needs it renders it on the server behind a fragment.\n */\n\nimport { safeConsoleWarn } from '@core/diagnostics';\n\n/** What a renderer does with a parsed vocabulary entry. */\nexport type ValueFormat =\n | { readonly kind: 'date'; readonly options: Intl.DateTimeFormatOptions }\n | { readonly kind: 'number'; readonly options: Intl.NumberFormatOptions };\n\nconst DATE_STYLES = new Set(['short', 'medium', 'long', 'full']);\nconst TIME_STYLES = new Set(['short', 'medium', 'long', 'full']);\n\n/** ISO 4217: three letters, and `Intl` rejects anything else at construction. */\nconst CURRENCY_CODE = /^[A-Za-z]{3}$/u;\nconst FRACTION_DIGITS = /^[0-4]$/u;\n\n/**\n * `undefined` for a spec this vocabulary does not contain — the caller then\n * keeps its own default formatting and reports LP0408 once for that element.\n */\nexport function parseValueFormat(spec: string): ValueFormat | undefined {\n const separator = spec.indexOf(':');\n const name = separator === -1 ? spec : spec.slice(0, separator);\n const argument = separator === -1 ? undefined : spec.slice(separator + 1);\n\n switch (name) {\n case 'date':\n if (argument === undefined) return dateFormat({ dateStyle: 'medium' });\n return DATE_STYLES.has(argument)\n ? dateFormat({ dateStyle: argument as Intl.DateTimeFormatOptions['dateStyle'] })\n : undefined;\n case 'time':\n if (argument === undefined) return dateFormat({ timeStyle: 'short' });\n return TIME_STYLES.has(argument)\n ? dateFormat({ timeStyle: argument as Intl.DateTimeFormatOptions['timeStyle'] })\n : undefined;\n case 'datetime':\n // The bare form is the renderer's own default, so `datetime` changes\n // nothing and exists to be written down next to the others.\n if (argument === undefined) return dateFormat({ dateStyle: 'medium', timeStyle: 'short' });\n return DATE_STYLES.has(argument)\n ? dateFormat({\n dateStyle: argument as Intl.DateTimeFormatOptions['dateStyle'],\n timeStyle: argument === 'short' ? 'short' : 'medium',\n })\n : undefined;\n case 'number':\n if (argument === undefined) return numberFormat({});\n if (!FRACTION_DIGITS.test(argument)) return undefined;\n return numberFormat({\n minimumFractionDigits: Number(argument),\n maximumFractionDigits: Number(argument),\n });\n case 'currency':\n if (argument === undefined || !CURRENCY_CODE.test(argument)) return undefined;\n return numberFormat({ style: 'currency', currency: argument.toUpperCase() });\n case 'percent':\n return argument === undefined ? numberFormat({ style: 'percent' }) : undefined;\n default:\n return undefined;\n }\n}\n\nfunction dateFormat(options: Intl.DateTimeFormatOptions): ValueFormat {\n return { kind: 'date', options };\n}\n\nfunction numberFormat(options: Intl.NumberFormatOptions): ValueFormat {\n return { kind: 'number', options };\n}\n\nconst warned = new WeakSet<Element>();\n\n/** Reported once per element: the markup is the cause, and it does not change. */\nexport function warnUnknownFormat(element: Element, fieldName: string, spec: string): void {\n if (warned.has(element)) return;\n warned.add(element);\n safeConsoleWarn(\n `[live-preview] LP0408: data-payload-format=\"${spec}\" on \"${fieldName}\" is not a ` +\n 'known format; the default formatting was used. Known: date, time, datetime (each also ' +\n ':short|medium|long|full), number, number:0-4, currency:XXX, percent.',\n );\n}\n\n/**\n * The options a renderer should use, or `undefined` to keep its own default —\n * which is also the answer when the spec belongs to the other renderer, so\n * `currency:EUR` on a date changes nothing rather than breaking it.\n */\nexport function formatOptionsFor<K extends ValueFormat['kind']>(\n kind: K,\n spec: string | undefined,\n element: Element,\n fieldName: string,\n): Extract<ValueFormat, { kind: K }>['options'] | undefined {\n if (spec === undefined || spec === '') return undefined;\n const parsed = parseValueFormat(spec);\n if (parsed === undefined) {\n warnUnknownFormat(element, fieldName, spec);\n return undefined;\n }\n if (parsed.kind !== kind) return undefined;\n return parsed.options;\n}\n","/**\n * `date` renderer. `<time>` gets an ISO `datetime` plus a localised label;\n * date inputs get the value in the visitor's local time zone, because that is\n * what the control displays.\n */\n\nimport { detectInitialLocale } from '@detection/locale';\nimport { getDateTimeFormat } from '@core/intl-cache';\nimport type { CachedElement, FieldRenderer, RenderContext } from '@core/types';\nimport { isEmptyValue, safeStringify } from './utils';\nimport { formatOptionsFor } from './value-format';\n\nconst dateRenderer: FieldRenderer = {\n name: 'date',\n render(target, value, context) {\n const element = target.element;\n if (isEmptyValue(value)) {\n if (element.tagName === 'INPUT') (element as HTMLInputElement).value = '';\n else {\n element.removeAttribute('datetime');\n element.textContent = '';\n }\n return;\n }\n const raw = typeof value === 'number' ? value : safeStringify(value);\n const date = new Date(raw);\n const valid = !Number.isNaN(date.getTime());\n const fallback = String(raw);\n if (element.tagName === 'INPUT') {\n (element as HTMLInputElement).value = valid\n ? formatForInput((element as HTMLInputElement).type, date)\n : fallback;\n return;\n }\n if (element.tagName === 'TIME') {\n element.setAttribute('datetime', valid ? date.toISOString() : fallback);\n }\n element.textContent = valid ? formatDate(date, target, context) : fallback;\n },\n};\n\nconst DEFAULT_DATE_OPTIONS: Intl.DateTimeFormatOptions = {\n dateStyle: 'medium',\n timeStyle: 'short',\n};\n\nfunction formatDate(date: Date, target: CachedElement, context: RenderContext): string {\n const locale = target.locale ?? context.locale ?? detectInitialLocale();\n const options =\n formatOptionsFor('date', target.format, target.element, target.fieldName) ??\n DEFAULT_DATE_OPTIONS;\n try {\n return getDateTimeFormat(locale, options).format(date);\n } catch {\n return date.toISOString();\n }\n}\n\n/** Value for `<input type=\"date|datetime-local|time\">` in local time; other inputs get the ISO instant. */\nexport function formatForInput(type: string, date: Date): string {\n const day = `${String(date.getFullYear()).padStart(4, '0')}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\n const clock = `${pad(date.getHours())}:${pad(date.getMinutes())}`;\n if (type === 'date') return day;\n if (type === 'datetime-local') return `${day}T${clock}`;\n if (type === 'time') return clock;\n return date.toISOString();\n}\n\nfunction pad(value: number): string {\n return String(value).padStart(2, '0');\n}\n\nexport { dateRenderer };\n","/** `number` renderer: raw value on inputs, `Intl.NumberFormat` elsewhere. */\n\nimport { detectInitialLocale } from '@detection/locale';\nimport { getNumberFormat } from '@core/intl-cache';\nimport type { CachedElement, FieldRenderer, RenderContext } from '@core/types';\nimport { isEmptyValue, safeStringify } from './utils';\nimport { formatOptionsFor } from './value-format';\n\nconst numberRenderer: FieldRenderer = {\n name: 'number',\n render(target, value, context) {\n const element = target.element;\n if (isEmptyValue(value)) {\n if (element.tagName === 'INPUT') (element as HTMLInputElement).value = '';\n else element.textContent = '';\n return;\n }\n const num = typeof value === 'number' ? value : Number(safeStringify(value));\n if (Number.isNaN(num)) {\n element.textContent = safeStringify(value);\n return;\n }\n if (element.tagName === 'INPUT') {\n (element as HTMLInputElement).value = String(num);\n return;\n }\n element.textContent = format(num, target, context);\n },\n};\n\nfunction format(num: number, target: CachedElement, context: RenderContext): string {\n const locale = target.locale ?? context.locale ?? detectInitialLocale();\n const options = formatOptionsFor('number', target.format, target.element, target.fieldName);\n try {\n return getNumberFormat(locale, options).format(num);\n } catch {\n // An `Intl` option this build rejects — an unknown currency, say.\n return String(num);\n }\n}\n\nexport { numberRenderer };\n","/**\n * `array` / `blocks` renderer. With `data-payload-array-template` each item\n * is interpolated into the template (`{{key}}`, `{{value}}`, `{{index}}`);\n * without one, items are joined by `data-payload-array-separator`.\n */\n\nimport { sanitizeHtmlWithPolicy } from '@security/sanitizer';\nimport { trustedHtml } from '@security/trusted-types';\nimport {\n collectTemplateKeys,\n inheritItemAttributes,\n interpolateArrayTemplate,\n sharedItemAttributes,\n} from '@core/array-template';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport { templateSanitizeOptions } from '@core/template-sanitize';\nimport type { FieldRenderer } from '@core/types';\nimport { isEmptyValue, safeStringify } from './utils';\n\nconst arrayRenderer: FieldRenderer = {\n name: 'array',\n render: /* @__PURE__ */ markNoWriteCallback((target, value, context) => {\n const element = target.element;\n if (isEmptyValue(value)) {\n element.textContent = '';\n return;\n }\n if (!Array.isArray(value)) return false;\n const template = target.arrayTemplate;\n if (template !== undefined && template.length > 0) {\n const html = renderTemplate(template, value);\n const policy = context.sanitizerPolicy;\n const templateOptions = templateSanitizeOptions(template);\n // Read before the write: the items about to be replaced are the only\n // record of what the server put on them.\n const shared = sharedItemAttributes(element);\n element.innerHTML = trustedHtml(sanitizeHtmlWithPolicy(html, policy, templateOptions));\n for (const item of Array.from(element.children)) inheritItemAttributes(item, shared);\n return;\n }\n element.textContent = value.map(safeStringify).join(target.arraySeparator ?? ', ');\n return;\n }),\n};\n\nfunction renderTemplate(template: string, items: readonly unknown[]): string {\n const knownKeys = collectTemplateKeys(items);\n let out = '';\n for (let i = 0; i < items.length; i += 1) {\n out += interpolateArrayTemplate(template, items[i], i, safeStringify, knownKeys);\n }\n return out;\n}\n\nexport { arrayRenderer };\n","/**\n * `structural-array` renderer (`data-payload-structural`): diffs the previous\n * and next item lists and patches the container through the keyed morph\n * (ADR 0008). All diff memory lives in the closure, one per client.\n */\n\nimport { safeConsoleWarn } from '@core/diagnostics';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport {\n applyStructuralPatches,\n createStructuralStore,\n KEY_ATTRIBUTE,\n type StructuralStore,\n} from '@core/structural-applier';\nimport { diffArray } from '@schema/diff';\nimport type { FieldRenderer } from '@core/types';\nimport { isEmptyValue } from './utils';\n\ninterface StructuralRenderState {\n readonly values: readonly unknown[];\n readonly template: string;\n readonly domSnapshot: readonly (string | null)[];\n}\n\ntype WarnedCodes = WeakMap<Element, Set<string>>;\n\n/** @internal */\nexport function createStructuralArrayRenderer(): FieldRenderer {\n const states = new WeakMap<Element, StructuralRenderState>();\n const warnedContainers = new WeakSet<Element>();\n const warnedKeys: WarnedCodes = new WeakMap();\n const store: StructuralStore = createStructuralStore();\n\n return {\n name: 'structural-array',\n render: /* @__PURE__ */ markNoWriteCallback((target, rawValue, context) => {\n const value = isEmptyValue(rawValue) ? [] : rawValue;\n if (!Array.isArray(value)) return false;\n const container = target.element;\n const template = target.arrayTemplate;\n if (template === undefined || template.length === 0) {\n warnMissingTemplate(warnedContainers, container, target.fieldName);\n return false;\n }\n const previousState = states.get(container);\n const domSnapshot = readDomKeySnapshot(container);\n const previous = previousState?.values ?? valuesFromDomSnapshot(domSnapshot);\n const patches = diffArray(previous, value);\n const forceRender = needsForcedRender(previousState, template, domSnapshot);\n if (patches.length === 0 && !forceRender) {\n states.set(container, { values: value.slice(), template, domSnapshot });\n return false;\n }\n warnAboutKeys(warnedKeys, container, target.fieldName, previousState?.values, value);\n const applied = applyStructuralPatches({\n template,\n container,\n patches,\n nextItems: value,\n store,\n forceRender,\n sanitizerPolicy: context.sanitizerPolicy,\n onDuplicateKey: (owner, key) => {\n warnDuplicateKey(warnedKeys, owner, target.fieldName, key);\n },\n });\n if (applied === null) return false;\n states.set(container, {\n values: value.slice(),\n template,\n domSnapshot: readDomKeySnapshot(container),\n });\n return applied ? undefined : false;\n }),\n };\n}\n\nfunction needsForcedRender(\n previous: StructuralRenderState | undefined,\n template: string,\n domSnapshot: readonly (string | null)[],\n): boolean {\n if (previous === undefined) return true;\n return previous.template !== template || !sameDomKeySnapshot(previous.domSnapshot, domSnapshot);\n}\n\n// SSR markup exists before any in-memory snapshot; its direct-child keys let\n// the first update reconcile instead of appending a second copy.\nfunction readDomKeySnapshot(container: Element): readonly (string | null)[] {\n return Array.from(container.children, (child) => child.getAttribute(KEY_ATTRIBUTE));\n}\n\nfunction valuesFromDomSnapshot(snapshot: readonly (string | null)[]): readonly unknown[] {\n return snapshot.map((key, position) =>\n key === null ? { __payloadDomPosition: position } : { id: key },\n );\n}\n\nfunction sameDomKeySnapshot(\n previous: readonly (string | null)[],\n current: readonly (string | null)[],\n): boolean {\n if (previous.length !== current.length) return false;\n return previous.every((key, index) => key === current[index]);\n}\n\nfunction warnMissingTemplate(\n warnedContainers: WeakSet<Element>,\n container: Element,\n fieldName: string,\n): void {\n if (warnedContainers.has(container)) return;\n warnedContainers.add(container);\n safeConsoleWarn(\n `[live-preview] LP0403: Skipping structural update for \"${fieldName}\": ` +\n `<${container.tagName.toLowerCase()} data-payload-structural> needs ` +\n `data-payload-array-template (for example \"<li>{{label}}</li>\").`,\n );\n}\n\nfunction itemKey(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const id = (value as Record<string, unknown>)['id'];\n return typeof id === 'string' || typeof id === 'number' ? String(id) : undefined;\n}\n\n/** Key problems degrade the morph, they do not break it; each is announced once per container (ADR 0008 §5). */\nfunction warnAboutKeys(\n warned: WarnedCodes,\n container: Element,\n fieldName: string,\n previous: readonly unknown[] | undefined,\n next: readonly unknown[],\n): void {\n const nextKeys = next.map(itemKey);\n const seen = new Set<string>();\n const duplicate = nextKeys.find((key) => {\n if (key === undefined) return false;\n if (seen.has(key)) return true;\n seen.add(key);\n return false;\n });\n if (duplicate !== undefined) warnDuplicateKey(warned, container, fieldName, duplicate);\n if (nextKeys.some((key) => key === undefined)) {\n warnOnce(\n warned,\n container,\n 'LP0404',\n `LP0404: an item of \"${fieldName}\" has no id and pairs by ` +\n 'position, so an insert re-renders every row after it. Give items a stable id.',\n );\n }\n if (previous?.length === next.length && next.length > 1) {\n const previousKeys = new Set(previous.map(itemKey).filter((key) => key !== undefined));\n const stable = nextKeys.some((key) => key !== undefined && previousKeys.has(key));\n if (previousKeys.size > 0 && !stable) {\n warnOnce(\n warned,\n container,\n 'LP0406',\n `LP0406: every key of \"${fieldName}\" changed at once; the ` +\n 'source generates ids per message, so no item can be retained across updates.',\n );\n }\n }\n}\n\n// Reached from the pre-diff check and from the morph's nested-slot check; one site, one message.\nfunction warnDuplicateKey(\n warned: WarnedCodes,\n owner: Element,\n fieldName: string,\n key: string,\n): void {\n warnOnce(\n warned,\n owner,\n 'LP0405',\n `LP0405: two items of \"${fieldName}\" share the key \"${key}\"; later ones pair by ` +\n 'position. Make `id` unique per item.',\n );\n}\n\nfunction warnOnce(warned: WarnedCodes, container: Element, code: string, message: string): void {\n let codes = warned.get(container);\n if (codes === undefined) {\n codes = new Set();\n warned.set(container, codes);\n }\n if (codes.has(code)) return;\n codes.add(code);\n safeConsoleWarn(`[live-preview] ${message}`);\n}\n","/**\n * Explicit renderer overrides, layered above the defaults each time a map is\n * built. The registry never retains the defaults, so stateful ones can be\n * recreated per client.\n */\n\nimport type { FieldRenderer, RendererKey } from '@core/types';\n\nconst builtinRenderers = new Map<RendererKey, FieldRenderer>();\n\nexport function buildBuiltinRenderers(\n defaults: readonly FieldRenderer[] = [],\n): Readonly<Record<string, FieldRenderer>> {\n const out: Record<string, FieldRenderer> = {};\n for (const renderer of defaults) out[renderer.name] = renderer;\n for (const [type, renderer] of builtinRenderers) out[type] = renderer;\n return Object.freeze(out);\n}\n\n/** Register or replace an override for maps built afterwards. */\nexport function registerBuiltinRenderer(renderer: FieldRenderer): void {\n builtinRenderers.set(renderer.name, renderer);\n}\n\n/** Test-only: clear the overrides. */\nexport function __resetBuiltinRenderersForTests(): void {\n builtinRenderers.clear();\n}\n","/** Built-in field renderers, assembled as values so `sideEffects: false` bundlers keep them all. */\n\nimport type { FieldRenderer } from '@core/types';\nimport { createTextRenderer } from './text';\nimport { richTextRenderer } from './rich-text';\nimport { htmlRenderer } from './html';\nimport { urlRenderer } from './url';\nimport { emailRenderer } from './email';\nimport { imageRenderer } from './image';\nimport { uploadRenderer } from './upload';\nimport { relationshipRenderer } from './relationship';\nimport { selectRenderer } from './select';\nimport { checkboxRenderer } from './checkbox';\nimport { dateRenderer } from './date';\nimport { numberRenderer } from './number';\nimport { arrayRenderer } from './array';\nimport { createStructuralArrayRenderer } from './structural-array';\nimport {\n buildBuiltinRenderers as buildRegistry,\n registerBuiltinRenderer,\n __resetBuiltinRenderersForTests,\n} from './registry';\nimport { reportOmittedFeature } from '@core/profile';\n\n/**\n * The array renderers carry the keyed morph, the structural applier and the item\n * templates — the largest optional cluster in the runtime. The lean profile\n * answers a page that needs them with LP0104 instead (@core/profile).\n */\nfunction arrayRenderers(): readonly FieldRenderer[] {\n return typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__\n ? [\n omittedRenderer('array', 'structural arrays'),\n omittedRenderer('blocks', 'structural arrays'),\n ]\n : [arrayRenderer, { ...arrayRenderer, name: 'blocks' }];\n}\n\n/** A renderer that only explains itself: the lean profile does not carry this field type. */\nfunction omittedRenderer(name: FieldRenderer['name'], feature: 'structural arrays'): FieldRenderer {\n return {\n name,\n render() {\n reportOmittedFeature(feature);\n },\n };\n}\n\n/** One renderer map per client; the stateful text and structural renderers are created fresh each call. @internal */\nexport function buildBuiltinRenderers(): Readonly<Record<string, FieldRenderer>> {\n // Built per call: a module-level table would pin every renderer into any\n // consumer importing an unrelated symbol from the root barrel.\n const stateless: readonly FieldRenderer[] = [\n richTextRenderer,\n htmlRenderer,\n urlRenderer,\n emailRenderer,\n imageRenderer,\n uploadRenderer,\n relationshipRenderer,\n selectRenderer,\n { ...selectRenderer, name: 'radio' },\n checkboxRenderer,\n dateRenderer,\n numberRenderer,\n ...arrayRenderers(),\n ];\n\n return buildRegistry([\n createTextRenderer('text'),\n createTextRenderer('textarea'),\n ...stateless,\n ...(typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__\n ? []\n : [createStructuralArrayRenderer()]),\n ]);\n}\n\nexport { registerBuiltinRenderer, __resetBuiltinRenderersForTests };\nexport type { PayloadMedia, PayloadRelationship } from './types';\n","/**\n * The two defaults profiles, row by row. 2.0 ships `v2`; `defaults: 'v1'` opts\n * back into the 1.x table for a staged migration. Each row belongs to exactly\n * one side — the adapter's request decision or the browser runtime — and a\n * test asserts the profile assigns every readiness row that has an option, so\n * a row added later cannot be forgotten. See ADR 0007.\n *\n * It lives in the leaf `types` domain, like `merge-depth.ts`, because the\n * inline generator resolves the profile too, and the generator is server-side\n * code that may not reach the browser runtime in `core`.\n */\n\n/** `'v2'` is the 2.0 default; `'v1'` is the 1.x table. */\nexport type DefaultsProfile = 'v1' | 'v2';\n\n/** How the runtime decides which windows may post updates. */\nexport type EventSourcePolicy = 'any' | 'parent-or-opener';\n\n/** Readiness rows that are options, keyed by the option they set. */\nexport const READINESS_ROWS = Object.freeze({\n strict: 'production response changes require an authorized context',\n previewSignals: 'query-only intent signal',\n disableReferrerDetection: 'referrer trust off',\n eventSourcePolicy: 'messages must come from parent/opener',\n skipUnchanged: 'skip unchanged bindings by default',\n sanitizerPolicy: 'hardened sanitizer id/data-* policy',\n} as const);\n\n/** Options an adapter's request decision reads from the profile. */\nexport interface AdapterProfileDefaults {\n readonly strict: boolean;\n readonly previewSignals: readonly ('query' | 'fetch-dest' | 'referer')[];\n}\n\n/** Options the browser runtime reads from the profile (through the inline configuration). */\nexport interface RuntimeProfileDefaults {\n readonly disableReferrerDetection: boolean;\n readonly eventSourcePolicy: EventSourcePolicy;\n readonly skipUnchanged: boolean;\n readonly sanitizerPolicy: 'compat' | 'strict';\n}\n\nexport const V2_ADAPTER_DEFAULTS: AdapterProfileDefaults = Object.freeze({\n strict: true,\n previewSignals: Object.freeze(['query'] as const),\n});\n\nexport const V2_RUNTIME_DEFAULTS: RuntimeProfileDefaults = Object.freeze({\n disableReferrerDetection: true,\n eventSourcePolicy: 'parent-or-opener',\n skipUnchanged: true,\n sanitizerPolicy: 'strict',\n});\n\n/** The 1.x table, spelled out so the profiles compare row by row. */\nexport const V1_ADAPTER_DEFAULTS: AdapterProfileDefaults = Object.freeze({\n strict: false,\n previewSignals: Object.freeze(['query', 'fetch-dest', 'referer'] as const),\n});\n\nexport const V1_RUNTIME_DEFAULTS: RuntimeProfileDefaults = Object.freeze({\n disableReferrerDetection: false,\n eventSourcePolicy: 'any',\n skipUnchanged: false,\n sanitizerPolicy: 'compat',\n});\n\n/** Only an explicit `'v1'` opts out; everything else gets the hardened rows. */\nexport function adapterDefaultsFor(profile: DefaultsProfile | undefined): AdapterProfileDefaults {\n return profile === 'v1' ? V1_ADAPTER_DEFAULTS : V2_ADAPTER_DEFAULTS;\n}\n\nexport function runtimeDefaultsFor(profile: DefaultsProfile | undefined): RuntimeProfileDefaults {\n return profile === 'v1' ? V1_RUNTIME_DEFAULTS : V2_RUNTIME_DEFAULTS;\n}\n","/**\n * `LivePreviewClient`: a `LivePreviewRuntime` with its own emitter, plugin\n * manager and renderer registry. A page that only needs a working preview uses\n * `generateInlineScript()` instead.\n */\n\nimport { assertMergeDepthExplicit } from '@/types/merge-depth';\nimport { LivePreviewRuntime, type RuntimeOptions } from '@core/lifecycle';\nimport type { LivePreviewInspection } from '@core/inspection/types';\nimport type { CachedElement, RendererKey } from '@core/types';\nimport { EventEmitter } from '@events/emitter';\nimport { OriginDetector } from '@detection/origin';\nimport { PluginManager } from '@plugins/manager';\nimport { RendererRegistry } from '@plugins/renderer-registry';\nimport type { LivePreviewPlugin } from '@plugins/types';\nimport { isDevMode, isInPreviewContext } from '@detection/environment';\nimport { buildBuiltinRenderers } from '@field-types/index';\nimport { definedOnly } from '@/types/defined-only';\nimport { withProfileDefaults, type LivePreviewClientConfig } from './config';\nimport { noopDiagnostic, safeConsoleDebug } from '@core/diagnostics';\n\n/** `T` with every property optional and `undefined`-able, for literals built from optional inputs. */\ntype Loose<T> = { readonly [K in keyof T]?: T[K] | undefined };\n\nfunction invert(value: boolean | undefined): boolean | undefined {\n return value === undefined ? undefined : !value;\n}\n\nexport class LivePreviewClient {\n readonly #emitter = new EventEmitter();\n readonly #detector: OriginDetector;\n readonly #rendererRegistry: RendererRegistry;\n readonly #runtime: LivePreviewRuntime;\n readonly #plugins: PluginManager;\n readonly #log: (...args: unknown[]) => void;\n #started = false;\n #destroyed = false;\n #tornDown = false;\n #destroyPromise: Promise<void> | null = null;\n\n constructor(rawConfig: LivePreviewClientConfig = {}) {\n const config = withProfileDefaults(rawConfig);\n const serverURL = config.serverURL ?? '';\n assertMergeDepthExplicit({\n defaults: rawConfig.defaults,\n serverURL,\n mergeDepth: config.mergeDepth,\n });\n const debug = config.debug ?? isDevMode();\n this.#log = debug\n ? (...args): void => {\n safeConsoleDebug('[live-preview]', ...args);\n }\n : noopDiagnostic;\n\n this.#detector = new OriginDetector(\n definedOnly({\n additionalOrigins: config.allowedOrigins,\n enableReferrerDetection: invert(config.disableReferrerDetection),\n enableLocalhostMatching: invert(config.disableLocalhostMatching),\n }),\n );\n\n if (this.#detector.isProductionUnconfigured) {\n this.#log('no trusted origin could be detected — set allowedOrigins');\n }\n\n this.#rendererRegistry = new RendererRegistry(buildBuiltinRenderers());\n\n this.#plugins = new PluginManager({\n events: this.#emitter,\n config: Object.freeze({ ...config }),\n registerFieldRenderer: (renderer) => this.#rendererRegistry.register(renderer),\n onTransformError: (error) => {\n void this.#emitter.emit('error', { error, context: 'transform', code: 'LP0602' });\n },\n log: this.#log,\n });\n\n this.#runtime = new LivePreviewRuntime(\n definedOnly({\n root: config.root,\n renderers: this.#rendererRegistry.renderers,\n resolveRenderer: (fieldType: RendererKey, target: CachedElement) =>\n config.resolveRenderer?.(fieldType, target) ?? this.#rendererRegistry.resolve(fieldType),\n renderRichText: config.renderRichText,\n sanitizerPolicy: config.sanitizerPolicy,\n transformValue: (\n fieldName: string,\n value: unknown,\n context: { readonly element: Element; readonly allFields: Record<string, unknown> },\n isCurrent?: () => boolean,\n ) => this.#plugins.applyTransforms(fieldName, value, context, isCurrent),\n originMatcher: (origin: string) => this.#detector.matches(origin),\n // Read per handshake, not once: after a lock, a bfcache restore must\n // re-broadcast to the locked origin alone, not every pre-lock candidate.\n readyTargets: () => this.#detector.enumerate(),\n emitter: this.#emitter,\n dataMerge:\n serverURL === ''\n ? undefined\n : definedOnly({\n serverURL,\n apiRoute: config.apiRoute,\n depth: config.mergeDepth,\n fetchFn: config.mergeFetch,\n }),\n debounceMs: config.debounceMs,\n heartbeatMs: config.heartbeatMs,\n intersectionRootMargin: config.intersectionRootMargin,\n scopeBindingsByOwner: config.scopeBindingsByOwner,\n skipUnchanged: config.skipUnchanged,\n revealEditedField: config.revealEditedField,\n autoBind: config.autoBind,\n subfieldCoverage: config.subfieldCoverage,\n eventSourcePolicy: config.eventSourcePolicy,\n dependencies: config.dependencies,\n strategies: config.strategies,\n disableVisibilityGate: config.disableVisibilityGate,\n visibilityGateThreshold: config.visibilityGateThreshold,\n enableA11y: config.enableA11y,\n a11yLocale: config.a11yLocale,\n onHeartbeatTimeout: () => {\n this.#detector.unlockOrigin();\n },\n lockedOrigin: () => this.#detector.lockedOrigin,\n validateToken: config.validateToken,\n log: this.#log,\n } satisfies Loose<RuntimeOptions>),\n );\n\n this.#emitter.on('connect', (e) => {\n this.#detector.lockOrigin(e.origin);\n });\n\n if (config.autoStart !== false) {\n this.start();\n }\n }\n\n /**\n * Start the runtime: `true` while eligible and started or scheduled for DOM\n * readiness, `false` once destroyed or outside a preview context.\n */\n start(): boolean {\n if (this.#destroyed) return false;\n if (this.#started) {\n // A deferred DOM-ready startup can fail after this returned and roll\n // itself back; this call retries it.\n this.#runtime.start();\n return true;\n }\n if (!isInPreviewContext()) return false;\n const started = this.#runtime.start();\n if (started) this.#started = true;\n return started;\n }\n\n /**\n * Release the message ingress, keeping plugins and renderers, for `pagehide`:\n * a bfcache restore re-runs no script, so an attached client would return\n * bound to a frozen page. `false` when nothing was running.\n */\n suspend(): boolean {\n if (this.#destroyed || !this.#started) return false;\n return this.#runtime.suspend();\n }\n\n /** Reacquire after `suspend()`: the same path as `start()`, because a restored document needs the same rebuild. */\n resume(): boolean {\n if (this.#destroyed || !this.#started) return false;\n return this.#runtime.start();\n }\n\n /** Stop the runtime and tear down every plugin. Idempotent; concurrent callers share one promise. */\n destroy(): Promise<void> {\n if (this.#destroyPromise !== null) return this.#destroyPromise;\n this.#destroyed = true;\n let resolveDestroy!: () => void;\n let rejectDestroy!: (reason: unknown) => void;\n const inFlight = new Promise<void>((resolve, reject) => {\n resolveDestroy = resolve;\n rejectDestroy = reject;\n });\n // Published before the teardown: a `destroy` handler calling destroy()\n // re-entrantly must get this same promise.\n this.#destroyPromise = inFlight;\n const finish = (): void => {\n this.#emitter.removeAllListeners();\n this.#tornDown = true;\n };\n try {\n this.#runtime.destroy();\n void this.#plugins.destroyAll().finally(finish).then(resolveDestroy, rejectDestroy);\n } catch (error) {\n finish();\n rejectDestroy(error);\n }\n return inFlight;\n }\n\n async use(plugin: LivePreviewPlugin): Promise<void> {\n if (this.#destroyed) throw new Error('LivePreviewClient: already destroyed');\n await this.#plugins.register(plugin);\n }\n\n /** Unregister a plugin and release everything its registration owned. Still allowed from a destroy hook during teardown. */\n async unuse(name: string): Promise<void> {\n if (this.#tornDown) throw new Error('LivePreviewClient: already destroyed');\n await this.#plugins.unregister(name);\n }\n\n /** Re-scan bindings after replacing markup without crossing a navigation boundary. */\n refreshCache(): void {\n this.#runtime.refreshCache();\n }\n\n /** Re-scan bindings and locally replay the last accepted document after a router commit. */\n refreshAfterNavigation(): void {\n this.#runtime.navigationCommit();\n }\n\n get events(): EventEmitter {\n return this.#emitter;\n }\n\n /** Names of the registered plugins. */\n get plugins(): readonly string[] {\n return this.#plugins.list();\n }\n\n get status(): 'disconnected' | 'connecting' | 'connected' {\n return this.#runtime.status;\n }\n\n /**\n * Point-in-time read of runtime state, no I/O: `bindings.orphanFields` when a\n * field refuses to update, `scheduler.deferred` when updates stop below the fold.\n */\n inspect(): LivePreviewInspection {\n return { ...this.#runtime.inspect(), plugins: this.#plugins.snapshot() };\n }\n\n /** Number of accepted updates so far. */\n get updateCount(): number {\n return this.#runtime.updateCount;\n }\n\n /** `true` once `destroy()` has been called. */\n get destroyed(): boolean {\n return this.#destroyed;\n }\n}\n\n/** A started client, or `null` when the page is not a preview context. */\nexport function initLivePreview(config: LivePreviewClientConfig = {}): LivePreviewClient | null {\n const client = new LivePreviewClient({ ...config, autoStart: false });\n return client.start() ? client : null;\n}\n\nexport type { LivePreviewClientConfig } from './config';\n","/**\n * `LivePreviewClient` configuration. Defaults are the 2.0 rows; `defaults: 'v1'`\n * restores the 1.x values named per option (ADR 0007).\n */\n\nimport type { CachedElement, FieldRenderer, RendererKey, RichTextRenderer } from '@core/types';\nimport type { StrategyHandlers } from '@core/strategies';\nimport {\n runtimeDefaultsFor,\n type DefaultsProfile,\n type EventSourcePolicy,\n} from '@/types/defaults-profile';\n\nexport interface LivePreviewClientConfig {\n /** Explicit trusted admin origins. */\n readonly allowedOrigins?: readonly string[];\n /** Payload origin; every update is then re-fetched through the REST API so relations arrive populated. Requires `mergeDepth`. */\n readonly serverURL?: string;\n /** REST route prefix used with `serverURL`. Default `/api`. */\n readonly apiRoute?: string;\n /** Population depth used with `serverURL`. Required with it; `defaults: 'v1'` falls back to `1`. */\n readonly mergeDepth?: number;\n /** Custom fetch for the `serverURL` merge request: attach auth headers or route through a proxy. */\n readonly mergeFetch?: typeof fetch;\n /** Verbose console output. Defaults to dev-mode detection. */\n readonly debug?: boolean;\n /** Debounce window for incoming updates. Default 50 ms. */\n readonly debounceMs?: number;\n /** Heartbeat timeout in ms; `0` disables it (default), because the admin posts only on edits. */\n readonly heartbeatMs?: number;\n /** IntersectionObserver `rootMargin`. Default `200px`. */\n readonly intersectionRootMargin?: string;\n /** Update only bindings under a matching `data-payload-owner`; an unowned binding is then never updated. Default `false`. */\n readonly scopeBindingsByOwner?: boolean;\n /** Skip a binding whose value did not change. Default `true`; `defaults: 'v1'` sets `false`. */\n readonly skipUnchanged?: boolean;\n /** Scroll the preview to the field being edited when its value changes. Default `false`. */\n readonly revealEditedField?: boolean;\n /**\n * Find bindings by value on the connection's first message: a scalar whose\n * value is the whole content of exactly one element is bound to it as if\n * `data-payload-field` stood there; every guess is stamped `data-payload-guessed`\n * and listed in `inspect().bindings.guessed`. Default `'off'`.\n */\n readonly autoBind?: 'off' | 'unique';\n /**\n * How a group counts as covered (ADR 0022). `'descendant'` (default): one\n * bound path inside it covers all of it. `'declared'`: each changed path\n * inside such a group needs its own binding or a `data-payload-covers`\n * declaration; an uncovered one is an unbound change.\n */\n readonly subfieldCoverage?: 'descendant' | 'declared';\n /** Fields whose change re-applies other bindings regardless of their own value: `{ price: ['priceLabel'] }`. Used with `skipUnchanged`. */\n readonly dependencies?: Readonly<Record<string, readonly string[]>>;\n /** Strategy handlers beyond patching; `createFragmentStrategy()` from `payload-live-preview/fragment` builds one. */\n readonly strategies?: StrategyHandlers;\n /** Apply every update regardless of visibility. Default `false`. */\n readonly disableVisibilityGate?: boolean;\n /** Cache size above which off-screen updates wait for intersection. Default `50`. */\n readonly visibilityGateThreshold?: number;\n /** Mount an `aria-live` region for connections, applied updates and heartbeat disconnects. Default `true`. */\n readonly enableA11y?: boolean;\n /** Locale of the announcement strings. Defaults to the detected locale. */\n readonly a11yLocale?: string;\n /** Document root. Default `document`. */\n readonly root?: Document | Element;\n /** Renderer resolution ahead of the registry; return `undefined` to fall through. */\n readonly resolveRenderer?: (\n fieldType: RendererKey,\n target: CachedElement,\n ) => FieldRenderer | undefined;\n /** The project's rich-text renderer, shared with SSR. Its output is sanitized. */\n readonly renderRichText?: RichTextRenderer;\n /** Ignore `document.referrer` as an origin source. Default `true`; `defaults: 'v1'` sets `false`. */\n readonly disableReferrerDetection?: boolean;\n /** Disable the dev-mode localhost matcher. Default `false`. */\n readonly disableLocalhostMatching?: boolean;\n /** Which windows may post updates. Default `'parent-or-opener'`; `defaults: 'v1'` sets `'any'`. */\n readonly eventSourcePolicy?: EventSourcePolicy;\n /**\n * Sanitizer policy for this client's rich text and HTML writes. Default\n * `'strict'`; `defaults: 'v1'` sets `'compat'`. Per instance: it leaves the\n * process default that `setSanitizerPolicy()` sets for direct `sanitizeHtml()` calls alone.\n */\n readonly sanitizerPolicy?: 'compat' | 'strict';\n /** `'v2'` (default) is the 2.0 table; `'v1'` restores every 1.x row at once. Explicit options win. */\n readonly defaults?: DefaultsProfile;\n /** Start the runtime in the constructor. Default `true`. */\n readonly autoStart?: boolean;\n /** Preview-token validator; every update must then carry a `previewToken` it approves. Stock Payload sends none. */\n readonly validateToken?: (\n token: string | undefined,\n origin: string,\n ) => boolean | Promise<boolean>;\n}\n\n/** The configuration with the `defaults` profile applied: explicit options win, `'v1'` changes nothing. */\nexport function withProfileDefaults(config: LivePreviewClientConfig): LivePreviewClientConfig {\n // `'v1'` fills the rows too: the runtime's own fallbacks are the 2.0 values\n // since the default flip, so leaving the config alone would hand a v1 client\n // the strict sanitizer and `skipUnchanged` it opted out of.\n const rows = runtimeDefaultsFor(config.defaults);\n return {\n ...config,\n skipUnchanged: config.skipUnchanged ?? rows.skipUnchanged,\n disableReferrerDetection: config.disableReferrerDetection ?? rows.disableReferrerDetection,\n eventSourcePolicy: config.eventSourcePolicy ?? rows.eventSourcePolicy,\n sanitizerPolicy: config.sanitizerPolicy ?? rows.sanitizerPolicy,\n };\n}\n","/**\n * The one rule shared by the adapters, the client and the inline generator:\n * `serverURL` needs an explicit `mergeDepth` under the 2.0 defaults (ADR 0007,\n * entry 10). It lives in the leaf `types` domain because the inline generator\n * is server-side code that may not reach the browser runtime in `core`, and\n * three copies of the check had already drifted in what they treated as\n * \"no server\" and \"no depth\".\n */\n\nimport type { DefaultsProfile } from '@/types/defaults-profile';\n\n/**\n * The population depth is a deliberate choice; the 1.x default of 1 stays only\n * behind `defaults: 'v1'`. An empty `serverURL` fetches nothing and owes no\n * depth; `null` counts as omitted because the inline wire config carries it.\n */\nexport function assertMergeDepthExplicit(options: {\n readonly defaults?: DefaultsProfile | undefined;\n readonly serverURL?: string | undefined;\n readonly mergeDepth?: number | null | undefined;\n}): void {\n if (options.defaults === 'v1') return;\n if ((options.serverURL ?? '') === '' || options.mergeDepth != null) return;\n throw new Error(\n 'payload-live-preview: `serverURL` needs an explicit `mergeDepth` under the 2.0 defaults — ' +\n \"choose the population depth deliberately (0 for none), or pass `defaults: 'v1'` to keep \" +\n 'the 1.x default of 1 while migrating (ADR 0007, entry 10).',\n );\n}\n","/**\n * Admin-side reporter for \"reveal the edited section\": it names the field the\n * editor's cursor is in so the preview scrolls there without a keystroke.\n */\n\n/** The preview window (usually `iframe.contentWindow`) messages are posted to. */\nexport interface FocusReportTarget {\n postMessage: (message: unknown, targetOrigin: string) => void;\n}\n\n/** @internal */\nexport interface PreviewFocusMessage {\n readonly type: 'payload-live-preview-focus';\n readonly field: string;\n}\n\n/** Post one focus report. `targetOrigin` must be the preview's exact origin, never `'*'`. */\nexport function reportPreviewFocus(\n target: FocusReportTarget,\n field: string,\n targetOrigin: string,\n): void {\n if (field.length === 0) return;\n const message: PreviewFocusMessage = { type: 'payload-live-preview-focus', field };\n target.postMessage(message, targetOrigin);\n}\n\n/** A reporter bound to a preview window and origin; `resolveTarget` runs per report, so a re-created iframe is addressed freshly. */\nexport function createPreviewFocusReporter(\n resolveTarget: () => FocusReportTarget | null | undefined,\n targetOrigin: string,\n): (field: string) => void {\n return (field: string): void => {\n const target = resolveTarget();\n if (target === null || target === undefined) return;\n reportPreviewFocus(target, field, targetOrigin);\n };\n}\n","/**\n * Every diagnostic code the runtime and tools emit, so a consumer can branch\n * on `e.code` instead of matching message text. A code is never reused for a\n * different meaning; a retired one stays reserved.\n *\n * Browser-side reporting sites write the literal (`code: 'LP0603'`) rather than\n * reading it from this record: the frozen table would then ship in the inline\n * runtime for the sake of six characters — it did, 1 287 B in every page, for\n * the one read Z6 left in the strategy runner, and `diagnostic-codes.test.ts`\n * now holds the artifact free of it. Server-side tools may import it.\n */\n\n/**\n * Every diagnostic code the runtime can report, by name.\n *\n * ```ts\n * client.events.on('error', (e) => {\n * if (e.code === DIAGNOSTIC_CODES.TransformThrew) reportToSentry(e.error);\n * });\n * ```\n */\nexport const DIAGNOSTIC_CODES = Object.freeze({\n /** No trusted origin configured in production; nothing will be accepted. */\n NoTrustedOrigin: 'LP0101',\n /** Origin trust rests on `document.referrer`, so any framing site is trusted. */\n ReferrerOnlyTrust: 'LP0102',\n /** A plugin declares a runtime range this runtime does not satisfy; it was refused. */\n PluginIncompatible: 'LP0103',\n /** The page carries the lean runtime and needs a feature that profile leaves out. */\n ProfileFeatureOmitted: 'LP0104',\n\n /** An update named an empty field with no binding anchor on the page; an edit to it has nowhere to land. */\n OrphanField: 'LP0201',\n /** Owner scoping is on and the update names no document it could belong to. */\n UnattributableUpdate: 'LP0202',\n /** An update carried a value for a field the page binds nowhere; editing it changes nothing on this page. */\n UnboundField: 'LP0203',\n\n /** The visibility gate held offscreen writes back until they scroll into view. */\n VisibilityGateDeferred: 'LP0301',\n\n /** A value was refused because the attribute or the value itself is unsafe. */\n UnsafeAttributeWrite: 'LP0401',\n /** A text element has structured children, so replacing its text was skipped. */\n TextTargetHasChildren: 'LP0402',\n /** A structural container has no array template, so the update was skipped. */\n MissingArrayTemplate: 'LP0403',\n /** A structural item has no `id`; it pairs positionally, so an insert re-renders every row after it. */\n StructuralItemUnkeyed: 'LP0404',\n /** Two structural items share a key; later ones pair positionally. */\n StructuralDuplicateKey: 'LP0405',\n /** Every structural key changed while the length did not; the source generates keys per message. */\n StructuralUnstableKeys: 'LP0406',\n /** A binding asks for a delivery strategy this release does not have; it is left unchanged. */\n UnsupportedStrategy: 'LP0407',\n /** `data-payload-format` names a format the vocabulary does not contain; the default formatting was used instead. */\n UnknownValueFormat: 'LP0408',\n /** The strict sanitizer removed an attribute the 1.x `'compat'` policy kept. */\n SanitizerDroppedAttribute: 'LP0409',\n /** A Lexical block has no renderer; the markup the server rendered for it is kept instead. */\n UnrenderedBlockKept: 'LP0410',\n /** A patch cannot reach what the server would have drawn; `onUnfaithfulPatch` decided what happens next. */\n UnfaithfulPatch: 'LP0411',\n /** The first write to a date, number or checkbox binding replaced a different reading of the same value. */\n ServerFormatReplaced: 'LP0412',\n /** A Lexical block has no renderer, and the write could not keep the markup the server rendered for it; it is gone. */\n UnrenderedBlockLost: 'LP0413',\n\n /** A message was rejected before it reached the update pipeline. */\n MessageRejected: 'LP0501',\n /** A preview token was rejected. */\n TokenRejected: 'LP0502',\n /** A trusted origin sent a message this protocol version does not recognise. */\n ProtocolShapeUnknown: 'LP0503',\n\n /** A consumer event handler threw. */\n HandlerThrew: 'LP0601',\n /** A consumer transform threw; the original value was kept. */\n TransformThrew: 'LP0602',\n /** A renderer threw while writing a value. */\n RendererThrew: 'LP0603',\n // LP0604 is reserved and unassigned; codes are never reused or renumbered.\n /** Runtime startup failed. */\n StartupFailed: 'LP0605',\n /** Sending the ready handshake failed. */\n ReadyFailed: 'LP0606',\n /** The page declared hydration, but no React commit, Vue mount or SvelteKit mount came within the cap; the runtime started without waiting. */\n HydrationWaitTimedOut: 'LP0607',\n\n /** The audit found no runtime in a response that carried preview intent. */\n AuditRuntimeMissing: 'LP0701',\n /** The preview response declares no `frame-ancestors`. */\n AuditNoFrameAncestors: 'LP0702',\n /** `X-Frame-Options` forbids framing on a response that declares no `frame-ancestors`; `SAMEORIGIN` forbids it from another origin only. */\n AuditFrameOptionsBlocks: 'LP0703',\n /** Binding attributes are served to anonymous visitors. */\n AuditBindingsExposed: 'LP0704',\n /** More bindings than the visibility gate will write eagerly. */\n AuditGateThresholdExceeded: 'LP0705',\n /** Owner markers exist, but some bindings are outside all of them. */\n AuditUnownedBindings: 'LP0706',\n /** The preview response carries no bindings and no fragment boundary. */\n AuditNoBindings: 'LP0707',\n /** The URL did not return an HTML page, so nothing else can be judged. */\n AuditNotAPage: 'LP0708',\n /** A fragment request failed (network, timeout, server error); the boundary was patched instead. */\n FragmentRequestFailed: 'LP0801',\n /** The fragment response had the wrong content type or shape; the boundary was patched instead. */\n FragmentResponseInvalid: 'LP0802',\n /** The fragment endpoint refused the preview (not authorized); the boundary was patched instead. */\n FragmentUnauthorized: 'LP0803',\n /** A fragment response arrived for a revision that was already superseded and was discarded. */\n FragmentSuperseded: 'LP0804',\n /** A route refresh was refused: the loop guard, or the strategy's minimum interval. */\n RouteRefreshLoop: 'LP0805',\n /** A boundary asks for the fragment strategy but no fragment handler is configured; it is patched. */\n FragmentStrategyUnavailable: 'LP0806',\n /** A revision changed a field with no binding; `onUnfaithfulPatch` refreshed the route. */\n UnboundChangeRefresh: 'LP0807',\n /** `onUnfaithfulPatch: 'escalate'` found no route or fragment strategy, or no boundary, to hand an unfaithful patch to; the page keeps it. */\n EscalationUnavailable: 'LP0808',\n /** A fragment inserted an Astro island the page cannot start: it never loaded the island element or that client directive. */\n IslandStartUnavailable: 'LP0809',\n /** The host's route refresh returned no promise, so the revision was re-applied before the host committed. */\n RouteRefreshUnconfirmed: 'LP0810',\n /** A readiness row is not yet at its 2.0 value; `pll doctor --v2` reports it. */\n V2ReadinessGap: 'LP0709',\n /** The preview runtime is served to anonymous visitors, not only inside the admin frame. */\n RuntimeOnPublicPage: 'LP0710',\n} as const);\n\n/** A diagnostic code, as it appears in log output and on the `error` event. */\nexport type DiagnosticCode = (typeof DIAGNOSTIC_CODES)[keyof typeof DIAGNOSTIC_CODES];\n","/**\n * The seam between a host framework's own router and the route strategy.\n *\n * The route strategy answers a revision by fetching the route and morphing it\n * into the living page. On a page whose DOM belongs to a reconciler that is\n * working against the framework, and it was seen to break once: `removeChild`\n * on `null` inside React's commit phase, over markup this package had patched.\n * A host that re-renders the route itself does the same job without the morph\n * and without the second HTML request, so it is given the chance to.\n *\n * Why a named slot on `window` and not a reference: the runtime is an inline\n * script that builds its strategy before any application code has hydrated, so\n * there is nothing to hand a component; `window.__livePreview`, the only other\n * public surface, is created later and not at all outside a preview; and the\n * two richer extension points — plugins and events — are reachable only through\n * the programmatic client, which a page using an adapter does not have. One\n * slot, written by whoever mounts and read at the moment of a refresh, is the\n * smallest thing that survives both orders of arrival.\n */\n\n/**\n * A host's own route refresh. It must settle once the fresh markup is\n * committed: the runtime re-applies the revision on top of it, and doing that\n * against the markup being replaced would write into nodes about to be dropped.\n * A function that returns nothing is taken as already committed; the route\n * strategy says once that it could not wait (LP0810), and 3.0 requires the\n * promise (ADR 0028).\n */\nexport type RouteRefresh = () => void | Promise<void>;\n\n/** Read late, so it does not matter whether the runtime or the component came first. */\nconst SLOT = '__livePreviewRouteRefresh';\n\ntype WindowSlot = Record<string, RouteRefresh | undefined>;\n\nfunction slot(): WindowSlot | undefined {\n return typeof window === 'undefined' ? undefined : (window as unknown as WindowSlot);\n}\n\n/**\n * Lend the runtime the host's route refresh; the return value undoes it, for a\n * component's cleanup. A later registration wins, and undoing one that has\n * already been replaced does nothing — two components on one page would\n * otherwise take the slot from each other on unmount.\n */\nexport function registerRouteRefresh(refresh: RouteRefresh): () => void {\n const target = slot();\n if (target === undefined) return () => undefined;\n target[SLOT] = refresh;\n return () => {\n // Cleared rather than deleted: the slot is read through `?.` anyway, and\n // removing the key buys nothing a lint rule would not have to be argued out of.\n if (target[SLOT] === refresh) target[SLOT] = undefined;\n };\n}\n\n/** The registered refresh, or `undefined` on a page that registered none. */\nexport function readRouteRefresh(): RouteRefresh | undefined {\n return slot()?.[SLOT];\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"client.cjs","names":["detectInitialLocale","document","lang","documentElement","getAttribute","length","readHtmlLang","navigator","language","readNavigatorLanguage","ELEMENT_ID","documentLeases","WeakMap","clearLeaseMessage","lease","timer","clearTimeout","messageNode","remove","A11yAnnouncer","german","constructor","locale","targetDocument","activeDocument","documentLocale","this","test","isGerman","mount","body","get","element","owned","refs","set","acquireDocumentLease","leased","isConnected","ownerDocument","getElementById","createElement","id","setAttribute","style","cssText","appendChild","announceConnected","say","announceDisconnected","announceUpdate","count","String","announcePartial","detach","delete","message","parentNode","createTextNode","hasChildNodes","data","previousSibling","setTimeout","visit","state","nodes","Error","enter","value","depth","active","has","add","parseFieldSchema","raw","parseFields","WeakSet","Array","isArray","out","entry","parsed","parseFieldEntry","push","record","name","type","fields","blocks","slug","Object","hasOwn","Reflect","includes","parseBlockSchema","result","relationTo","targets","target","optionalFieldOk","check","optionalTypeOk","isPlainObject","prototype","getPrototypeOf","NULL_AS_ABSENT_FIELDS","CAPABILITY_DECLARATIONS","basic","since","observed","PROTOCOL_CAPABILITIES","keys","negotiateProtocol","theirs","sanitisedTheirs","Number","isFinite","Math","floor","effectiveTheirs","negotiated","min","seen","Set","capabilities","capability","ours","observeThenableResult","then","Promise","resolve","catch","sameRevision","a","b","generation","revision","MessageBus","matcher","handlers","boundListener","attachedTarget","queueHead","queueTail","lastAccepted","replayedGeneration","latestAcceptedAttempt","attach","window","committed","listener","event","receive","origin","reportInvalid","resetQueue","addEventListener","error","removeEventListener","advanceGeneration","replayLastAccepted","accepted","handler","onReplay","matchesOrigin","invokeHandler","structuredClone","forgetLastAccepted","sendReady","origins","payload","ready","protocolVersion","postMessage","matchesSource","v","x","isLivePreviewMessage","dispatchUpdate","normalized","field","deleteProperty","fieldSchemaJSON","normalizeLivePreviewMessage","isDocumentEventMessage","onDocumentEvent","focusFieldOf","onFocusField","hasUpdateData","isCurrentGeneration","messageRevision","validator","validateToken","commitUpdate","pending","verdict","next","enqueue","previewToken","settleValidation","approved","drainQueue","dequeue","onUpdate","attempt","snapshot","withoutToken","snapshotForReplay","reason","onInvalid","sourcePolicy","source","parent","opener","args","expected","isolateDiagnostic","diagnostic","noopDiagnostic","safeConsoleError","console","safeConsoleWarn","warn","safeConsoleDebug","debug","HOW_TO_GET_IT","reported","reportOmittedFeature","feature","createA11y","options","__LEAN_BUILD__","enableA11y","refuseA11y","root","nodeType","isDocumentRoot","a11yLocale","buildA11y","defaultSendReady","Window","definedOnly","key","entries","STRUCTURAL_TYPES","walk","schemas","basePath","namedTabs","schema","path","block","lookupSchema","index","fieldPath","wildcardPath","replace","getId","item","getBlockType","blockType","diffArray","prev","every","patches","prevIndexById","Map","i","consumedFromPrev","to","kind","from","prevItem","shallowEqual","oldValue","diffById","diffByPosition","is","aRec","bRec","aKeys","bKeys","MAP","text","textarea","richText","email","number","checkbox","date","select","radio","array","group","tabs","row","collapsible","relationship","upload","point","json","code","ui","SAFE_PROTOCOLS","RELATIVE_PATH","PROTOCOL_RELATIVE","PARSER_IGNORED","SCHEME_GAPS","SCHEME","isSafeUrl","url","trimmed","trim","startsWith","URL","protocol","scheme","exec","toLowerCase","spellsUnsafeScheme","isExternalHttpUrl","BLOCKED_ATTRIBUTES","URL_ATTRIBUTES","isWritableAttribute","valueIdentity","JSON","stringify","resolveUnfaithfulPatchMode","onUnfaithfulPatch","onUnboundChange","reportUnfaithfulPatch","deps","mode","last","reportedUnfaithful","identity","now","Date","repeated","at","display","shortfall","activeUpdate","fieldName","unfaithfulCount","unfaithfulFields","log","unfaithfulPatches","reportUnboundChange","FORMATTING_RENDERERS","isOptionType","shownValue","tagName","textContent","excerpt","slice","noWriteCallbacks","markNoWriteCallback","callback","FieldChangeTracker","previous","lastFields","priorFields","keepValues","previousFields","isBaseline","diff","dependencies","isCurrent","alwaysCurrent","baseline","changed","invalidated","dependencyEntries","dependents","dependent","reset","BLOCKED_KEYS","resolveFieldValue","preferLocale","localized","readOwn","direct","current","resolved","segment","split","object","hasOwnProperty","call","bindingValue","fallbackLocale","bindingIdentity","own","siblings","hrefField","srcField","altField","combined","format","sibling","FRAGMENT_ATTRIBUTE","FRAGMENT_KEY_ATTRIBUTE","enclosingFragment","closest","planBoundaries","strategy","boundaries","ownerKeys","covered","covers","fragmentBoundary","resolveStrategy","explicit","collectionOwnerKey","documentId","nonEmpty","isBindingInScope","owner","readDocumentId","isContainer","shapeOf","child","populates","samePopulation","before","after","sameValue","pathChanged","uncoveredChangedPaths","coverage","uncovered","visits","reachesBelow","childKeys","SYSTEM_FIELD_NAMES","createPathCoverage","cache","rendering","inScope","names","bindings","some","binding","rendered","filter","declaration","boundNames","coverPaths","anyBelow","candidates","prefix","candidate","cover","namePathCoverage","flatMap","paths","stripLocaleSuffix","suffix","endsWith","createFieldReach","localised","whole","below","base","localisedBindingNames","uncoveredDocumentPaths","reach","found","declaredSubfields","unboundChangedFields","touched","subfields","unbound","SELF_SUFFICIENT_TYPES","SELF_SUFFICIENT_NODES","NO_DEPENDENCIES","MergeNeed","rawChanges","resolvedLocale","trailing","openUntil","requestAttempt","decide","transaction","rawData","emitter","islands","listenerCount","values","rendersAReference","isPath","strategies","fragment","querySelector","readsPopulatedValues","fieldType","explicitFieldType","looksLikeLexicalRoot","holdsReference","rendersRichTextByShape","forceRender","merge","localeChanged","verdictFor","schemaIndex","request","merger","windowMs","dropQueued","leading","status","settle","promise","createPending","flush","recordMerged","doc","resetRawChanges","destroy","isScalar","boundName","hasBindingBelow","namesAReference","node","pop","children","linkType","isInIframe","self","top","isDevMode","nodeEnv","process","env","readNodeEnv","host","location","hostname","ProtocolTracker","negotiation","observe","fresh","join","applyVersion","remoteVersion","namesAnotherDocument","previewedSlug","globalSlug","collectionSlug","entitySlug","previewedId","owesForceRender","completed","RelationshipTracker","lastIdentity","inspect","externallyUpdatedRelationship","updatedAt","edit","commit","inspection","isNew","prefersReducedMotion","win","matchMedia","matches","FieldRevealer","lastField","reveal","closed","rect","getBoundingClientRect","vertically","bottom","innerHeight","horizontally","right","left","innerWidth","isInViewport","scrollIntoView","behavior","revealElement","revealBinding","revealer","defaultView","RevealLedger","note","slot","revealIdentities","revealTarget","IGNORED","RevisionDisplayLedger","outstanding","report","failed","ended","begin","view","shortfalls","deferred","awaiting","queued","publish","end","requestSettle","handIsland","confirmed","queueMicrotask","awaitingIslands","thrownFragment","boundary","RuntimeState","started","suspended","deferredStart","hydration","updateCount","supersededCount","completedCount","skippedUnchangedCount","lastFlush","absentFields","warnedOrphanFields","warnedStrategy","warnedUnattributableMessage","warnedVisibilityGate","warnedFragmentFallback","warnedIslandStart","warnedEscalationUnavailable","warnedProtocolShape","checkedServerFormat","rowsOfBinding","escalatedCount","autoBindSearchMs","autoBindGuesses","warnedForeignSource","lastAppliedIdentity","navigationReplayPending","navigationBindingReplay","revealLedger","fragmentStats","superseded","routeStats","refreshes","partial","refused","loopStopped","fragmentControllers","routeController","routeRetry","routeRefreshOwed","routeAwaitsSave","fragmentsOwed","readyTimers","changes","merges","relationships","isRunning","complete","countsAsUpdate","forgetOwedWork","clear","supersedeStrategies","controller","unsettled","abort","abortStrategies","route","BindingWriter","instanceContext","renderRichText","internalLinkPattern","sanitizerPolicy","serverURL","reportUnfaithful","writing","apply","update","schemaEntry","renderer","schemaType","mapped","payloadTypeToRenderer","resolveFieldType","resolveRenderer","fail","emitElementUpdate","src","context","allFields","hidesWhenEmpty","toggleAttribute","isEmptyLexicalRoot","isEmptyFieldValue","targetAttribute","attribute","removeAttribute","stringValue","applyAttributeBinding","shown","watchServerFormatting","outcome","render","invokeRenderer","rendererUsesNoWriteOutcome","reportServerFormatting","emitWhile","previousValue","nextValue","receivedAt","applied","cause","parseDependencyList","mergeDependencyMaps","maps","merged","map","bucket","dependencyMapFromBinding","dependsOn","ISLAND_ATTRIBUTE","ISLAND_SELECTOR","OWNED_ATTRIBUTE","isMorphBoundary","hasAttribute","isIslandBoundary","editable","islandAllowsPatching","island","isIslandRoot","isAwaitingIslandHydration","ISLAND_IDENTITY","renderedSlots","unmountedIslands","isAstroIsland","slotMarkup","markup","querySelectorAll","parentElement","innerHTML","retainIslandBoundary","live","slots","customElements","observedAttributes","observesProps","props","astroIslandsIn","islandStartBlocker","directive","astro","FIELD_ATTRIBUTE","TYPE_ATTRIBUTE","TARGET_ATTRIBUTE_ATTRIBUTE","HREF_ATTRIBUTE","SRC_ATTRIBUTE","ALT_ATTRIBUTE","ARRAY_TEMPLATE_ATTRIBUTE","ARRAY_SEPARATOR_ATTRIBUTE","LOCALE_ATTRIBUTE","FORMAT_ATTRIBUTE","RICH_TEXT_ATTRIBUTE","HTML_ATTRIBUTE","ARRAY_ATTRIBUTE","STRUCTURAL_ATTRIBUTE","OWNER_ATTRIBUTE","DEPENDS_ATTRIBUTE","STRATEGY_ATTRIBUTE","BOUNDARY_ATTRIBUTE","GUESSED_ATTRIBUTE","COVERS_ATTRIBUTE","BINDING_ATTRIBUTES","FIELD_SELECTOR","OWNER_SELECTOR","NAVIGATION_REPLAY_SELECTOR","resolveBindingOwner","CUSTOM_RENDERER_KEY","VALID_FIELD_TYPES","isRendererKey","hasSameBindingIdentity","strategyKind","ElementCache","entriesByField","entryByElement","islandRoots","ownersByIsland","navigationRoots","coverDeclarations","renderedDeclarations","alwaysTrue","dependencyMap","islandOwners","navigationReplayRoots","buildFromRoot","t0","performance","elementCount","collectIslands","renderingStrategy","fieldCount","size","durationMs","resolveBinding","replaceEntry","removeEntry","append","getByElement","indexOf","splice","arrayTemplate","arraySeparator","guessed","inputType","MAX_NODES","MAX_BODY","FORBIDDEN","hasControl","charCodeAt","maximum","encodeURIComponent","put","defineProperty","writable","configurable","enumerable","stripTrailingSlashes","copyLegacyData","characters","copy","planLegacyPopulation","apiRoute","isSafeInteger","groups","unique","tick","level","relation","collection","selected","scope","fieldRelation","hasMany","allowed","selectedCollection","rich","find","requests","username","password","search","hash","part","identities","first","comma","chunk","proposed","query","URLSearchParams","limit","ids","async","populationBody","response","signal","reader","cancelled","finished","obsolete","Symbol","interrupt","interrupted","aborted","cancel","once","bind","race","getReader","activeReader","chunks","bytes","read","done","byteLength","Uint8Array","position","parse","TextDecoder","decode","releaseLock","fillLegacyPopulation","safe","docs","isPathSegment","maxLength","character","codePoint","codePointAt","hasControlCharacter","isSafeSlug","isSafeId","TIMED_OUT","DataMerger","fetchFn","timeoutMs","inflight","destroyDepth","withoutTrailingSlashes","POSITIVE_INFINITY","canMerge","endpointOf","legacy","deadline","timedOut","within","work","_resolve","reject","plan","fetch","AbortController","population","method","credentials","redirect","ok","endpoint","flattenLocales","headers","wrongIdentity","VERSION","PAYLOAD_2","fieldTyping","populatesRelationships","documentEvents","PAYLOAD_3","UNKNOWN","ASTRO_SSR_ATTRIBUTE","WATCHED_ANYWHERE","TRACKED_SELECTOR","ObserverManager","callbacks","debounceMs","rootMargin","visible","mutation","intersection","debounceTimer","mutationDebounceMs","intersectionRootMargin","start","previousGeneration","stop","MutationObserver","mutations","handleMutations","IntersectionObserver","handleIntersection","threshold","childList","subtree","attributes","attributeFilter","disconnect","observeElement","unobserveElement","unobserve","markVisible","isVisible","hydratedAstroIsland","onIslandHydrated","m","attributeName","addedNodes","containsTrackedElement","removedNodes","hasStructuralImpact","onStructuralChange","isIntersecting","onVisibilityChange","LifetimeScope","release","run","close","reverse","BINDING_SELECTOR","signalSlot","w","armed","commits","onCommit","waiters","armReactCommitSignal","hook","__REACT_DEVTOOLS_GLOBAL_HOOK__","renderers","supportsFiber","inject","internals","installedHook","onCommitFiberRoot","rendererId","rest","waiter","forget","awaitSettled","onSettled","capMs","VUE_APP_PROPERTY","mountedApp","armVueMountSignal","proto","Element","getOwnPropertyDescriptor","app","nuxt","$nuxt","isHydrating","settleOnceHydrated","startAfterParse","startNow","WAITS","later","startHydrated","defer","hydrated","react","_root","HYDRATION_WAIT_CAP_MS","judge","container","ownsBindings","containerInfo","fiber","memoizedState","tag","dehydrated","hasDehydratedBoundary","ownsHydratedBindings","whenReactCommitted","vue","mountedAround","sveltekit","page","mounted","observer","manual","AWAITED","readDocumentBody","HeartbeatTimer","onTimeout","handle","lastKick","kick","arm","resume","elapsed","max","remaining","delay","lastKickAt","ConnectionState","markConnected","transition","markDisconnected","BOOLEAN_WORDS","NUMERIC","ENUM_TOKEN","LOCALE_CODE","SKIPPED_TAGS","isBindableValue","minLength","isRecord","bindableValues","claim","media","rawName","childValue","isBoundary","namespaceURI","soleText","firstChild","nextSibling","isCandidateAttribute","hits","byElement","elements","byField","firstElementChild","nextElementSibling","textClaim","getAttributeNames","shape","stamps","href","matched","alt","searchUnique","searchRoot","rollback","observers","written","cacheTouched","adopt","when","adopted","abandon","reportMovedRow","navigated","rows","rowsOnPath","prior","ownerKeysForUpdate","scopeBindingsByOwner","collectionKey","messageOwnerKeys","NavigationReplay","awaitingHydration","delivered","confirmations","reapplyBindings","currentTransaction","renderData","schedule","reapplyIslands","hydrationCompleted","replay","dispatchIslands","displayed","confirmation","dispatchSnapshotToIslands","hasLateRouteBinding","fieldsForElements","unrunFragmentPlan","onlyElements","fragmentBoundariesRun","contains","held","detail","dispatched","dispatchEvent","CustomEvent","bubbles","dispatchIslandUpdate","COVERAGE_WARNING","isAddressable","warned","isBindableScalar","isJoinResult","SLOT","for","trustedHtml","html","policy","policies","realm","globalThis","existing","created","shared","override","auto","api","trustedTypes","createPolicy","factory","createHTML","input","resolvePolicy","STATE_ATTRIBUTES","keyOf","keyAttributes","morphElement","sameKind","liveBoundary","renderedBoundary","retainBoundary","focus","captureFocus","syncAttributes","retainChildrenOf","liveKeyed","keyed","duplicate","onDuplicateKey","indexKeyed","keyedElements","liveUnkeyed","childNodes","claimed","usedKeys","renderedNodes","cursor","unkeyedIndex","kept","reconcile","replaceWith","replaceChild","following","isBlankText","insertBefore","morphChildren","restoreFocus","nodeValue","Node","TEXT_NODE","activeElement","HTMLElement","selection","HTMLInputElement","HTMLTextAreaElement","selectionStart","selectionEnd","preventScroll","setSelectionRange","reportDroppedAttribute","ALLOWED_TAGS","FORM_CONTROLS","REMOVE_COMPLETELY","ATTR_GLOBAL","ATTR_ARIA_PREFIX","ATTR_DATA_PREFIX","ATTR_BY_TAG","img","picture","audio","video","time","abbr","q","blockquote","table","th","td","col","colgroup","ol","li","pre","SanitizerEnvironmentError","TEMPLATE_ATTRIBUTES","DOCUMENT_SLOT","sanitizeHtml","sanitizeHtmlWithPolicy","resolveDocument","environmentError","instancePolicy","attrMap","attrs","allowedTags","attrByTag","allowFormControls","templateMode","allowedData","additionalAllowedTags","forEach","additionalAllowedAttributes","attr","allowedDataAttributes","pass","template","content","sanitizeFragment","serialize","isDevelopmentProcess","holder","warnOnce","__INLINE_BUILD__","writer","sanitizeElement","tagAttrs","isSafeSrcset","sanitizeAttributes","anchor","hardenAnchor","HTML_ESCAPES","freeze","HTML_ESCAPE_PATTERN","escapeHtml","char","ATTR_ESCAPES","ATTR_ESCAPE_PATTERN","escapeHtmlAttribute","PLACEHOLDER_PATTERN","collectTemplateKeys","items","interpolateArrayTemplate","knownKeys","placeholder","sharedItemAttributes","everyItem","inheritItemAttributes","safeStringify","isEmptyValue","lruGet","lruSet","oldest","lruTrim","TEMPLATE_EXTRA_TAGS","TEMPLATE_EXTRA_ATTRIBUTES","CUSTOM_TAG_PATTERN","optionsByTemplate","templateSanitizeOptions","cached","tags","match","matchAll","KEY_ATTRIBUTE","NESTED_KEY_ATTRIBUTE","NESTED_TEMPLATE_ATTRIBUTE","applyStructuralPatches","prepareStructuralPlan","commitStructuralPlan","store","morph","isManagedNestedSlot","_live","nextItems","memory","templateKeys","initialChildren","keyedChildren","indexByAttribute","reserved","readKey","takeIndexedElement","replaces","renders","renderItem","nestedSlots","prepareNestedSlots","prepareReconciliation","patch","createPatchPlan","mutated","retained","liveSlot","renderedSlot","synchronizeAttributes","getMemory","rememberItem","oldItem","newItem","prevValue","oldSlotsByKey","findDirectNestedSlots","plans","newSlot","oldSlot","nextTemplate","previousTemplate","nextNested","readNestedArray","resolvedNext","templateChanged","ancestor","nested","indexed","warnFragmentFallback","warnUnsupportedStrategy","warnEscalationUnavailable","warnInstead","StrategyRunner","planFragments","planned","inOwnerScope","escalateUnfaithful","routeRefreshed","coveringBoundaries","pendingFragments","runFragments","refreshRoute","hasUnboundChange","answered","subfieldCoverage","plansRoute","named","routeTouched","blocked","cloneNode","releaseDisconnectedIslands","known","blocker","morphFragment","missing","warnIslandStart","rebuildCache","patchFallback","restoreGuesses","scheduler","pendingCount","revealPending","updatedCount","runRoute","routeFailed","refreshAfterSave","armRouteRetry","delayMs","forSave","routeAfterSave","stats","lands","refresh","retryAfter","currentData","reapply","transform","transformForBinding","originalValue","transformValue","transformed","returnedThenable","TypeError","err","emit","NOTHING_CHANGED","MERGE_FAILED","UpdatePipeline","a11y","runtimeDisplayHost","_data","createLeanStrategyRunner","scheduleAllFields","navigationReplay","handleUpdate","heartbeat","observeCapabilities","acceptDataUpdate","handleReplay","reapplyNavigationBindings","reapplyNavigationIslands","relationshipInspection","buildSchemaIndex","incumbent","relationshipEdit","acceptRevision","timestamp","connection","processUpdate","resolveIncomingFields","dataFor","cancelRevision","applyFields","refined","autoBind","guesses","folded","keep","adoptUniqueBindings","coalesced","mergeWindowMs","applyMerged","lateBindings","owed","fragmentTouched","trackIdentity","skipUnchanged","scheduled","revealEditedField","ownsAnyBinding","createFieldAddressability","childName","coverageByDefault","warnCoverageDefault","diagnoseOrphanFields","notifyIslands","restoreUniqueBindings","onFlush","unfaithful","revealField","documentSaved","UpdateScheduler","maxWaitMs","gateThresholdValue","gateDisabled","getCacheSize","scheduleFrame","cancelFrame","activeFlushes","debounceToken","deadlineTimer","frameHandle","frameFallback","frameToken","windowUntil","activeRevision","activeRevisionCancelled","destroying","visibilityGateThreshold","disableVisibilityGate","requestAnimationFrame","cancelAnimationFrame","armDebounce","clearWork","cancelScheduledWork","flushNow","notifyVisible","didApply","statsFor","retarget","retargetBuffer","replayCount","gateThreshold","gateActive","opensTheWindow","requestFrame","token","clearFrameFallback","frame","clearDeadline","appliedFields","batchEntry","nothingToScrollTo","buffer","box","width","height","READY_RETRY_DELAYS_MS","LivePreviewRuntime","pipeline","rootSentinel","closingSession","observedRoot","replayRetainedOnStart","isInsideIsland","bus","originMatcher","eventSourcePolicy","dataMerge","heartbeatMs","onHeartbeatTimeout","readyTargets","lockedOrigin","openScope","readyState","onReady","startWhenReady","startupHost","rollbackFailedStart","step","reportError","observerRoot","watchRootReplacement","buildCacheAndObserve","recoverSuspendedSession","suspendedHeartbeatExpired","sendReadyAfterStart","suspend","wasConnected","closingScope","refreshCache","followReplacedRoot","navigationCommit","cancelActiveUpdate","fieldNames","owners","version","trusted","locked","sort","profile","revisions","skippedUnchanged","orphanFields","ownerScoped","localeCompare","searchMs","fidelity","canEscalate","escalated","fragments","inFlight","visibilityGateActive","plugins","buildInspection","previousIslandOwners","previousNavigationRoots","added","removed","addedIslands","isIdleDisconnected","countSuperseded","EventEmitter","regular","on","register","off","emitSequential","shouldContinue","eligible","invoke","removeAllListeners","eventNames","label","LOCALHOST_PATTERN","VALID_ORIGIN_PATTERN","LOCALHOST_HANDSHAKE_PORTS","readParentOrigin","ancestors","ancestorOrigins","OriginDetector","additionalOrigins","normalised","normaliseOrigin","referrerOrigin","enableReferrerDetection","referrer","allowLocalhost","enableLocalhostMatching","forceDevMode","lockOrigin","unlockOrigin","enumerate","port","referrerWasAvailable","isProductionUnconfigured","isReferrerOnlyTrust","noopDisposer","ResourceScope","pluginName","resources","assertOpen","cleanup","track","acquire","finalize","disposed","stage","resource","dispose","activate","counts","subscription","ScopedPluginEvents","events","subscriptions","subscribe","untypedHandler","callerEligible","subscriptionActive","wrapped","PluginManager","config","registerRenderer","onTransformError","initializing","teardowns","transforms","mutationQueue","queuedHooks","registerFieldRenderer","plugin","registerNow","unregister","unregisterNow","destroyAll","destroyAllNow","applyTransforms","registrations","registration","list","describe","cleanups","incompatibility","compat","runtimeVersion","runtime","range","parseVersion","alternative","comparators","comparator","operator","order","delta","compare","satisfiesComparator","satisfiesRange","isInteger","incompatibilityOf","refuse","createContext","runHook","init","registerTransform","registerCleanup","getConfig","existingTeardown","holdQueue","teardown","destroyPlugin","operation","RendererRegistry","layers","layer","stack","wasTop","previousLayer","previousRenderer","ALIGNMENT_NUMERIC","ALIGNMENT_STRING","resolveAlignment","fmt","resolveIndent","indent","dirAttribute","direction","layoutClassAttribute","align","classes","VALID_TAGS","asRecord","readMedia","resolveMediaUrl","server","sanitizeIdent","pickRelationLabel","title","PLACEHOLDER","BLANK_TARGET","linkRenderer","ctx","renderChildren","patterned","pattern","parts","_match","fillPattern","internalUrl","resolveUrl","titleAttr","extractText","dimensionAttributes","typeAttribute","mimeType","registry","lookupBlockRenderer","UNRENDERED_BLOCK_SELECTOR","renderBlockNode","baseClass","custom","onUnrenderedBlock","spanAttribute","BUILTIN_NODE_RENDERERS","paragraph","heading","tagRaw","listType","startAttr","checkAttr","listitem","valueAttr","link","autolink","quote","linebreak","horizontalrule","tab","mime","renderVideo","renderAudio","renderImage","filename","renderFallbackLink","classAttr","inlineBlock","tablerow","tablecell","header","warnedNoSanitizer","isLexicalContent","renderNode","extractPlainText","createTextRenderer","warnedElements","toPlainString","hasForeignChildren","escapeAndLinebreak","warnedKept","warnedLost","lastKeptBlocks","WRAPPER_TAGS","richTextRenderer","unrendered","blockFields","verdicts","only","className","wrapperOf","placeholders","pairs","pairUnrenderedBlocks","replaceChildren","writeKeepingUnrenderedBlocks","sanitize","requireDocument","warnNoSanitizerOnce","lexicalToHtml","placeholderClass","lost","reportUnrenderedBlock","_key","keptBlockFields","reportChangedKeptBlocks","pair","fits","standing","front","shorter","lastElementChild","back","previousElementSibling","htmlRenderer","acceptUrl","createLinkRenderer","toHref","urlRenderer","HAS_SCHEME","emailRenderer","IMAGE_SOURCE_ATTRIBUTES","chosenSizes","clearImage","dropPictureSources","writeImage","sizes","sources","variants","sizeSources","chosen","sameUrl","s","sameFormat","sameShape","original","widths","srcsetUrl","srcset","baseURI","abs","NAMES_A_SOURCE","imageRenderer","pickSource","pickAlt","backgroundImage","escapeCssUrl","uploadRenderer","relationshipRenderer","selectRenderer","toValues","checked","option","labelFor","multiple","writeSelect","FALSE_STRINGS","checkboxRenderer","toBoolean","NUMBER_CACHE","DATE_CACHE","buildKey","localePart","serialised","stableStringify","inner","DATE_STYLES","TIME_STYLES","CURRENCY_CODE","FRACTION_DIGITS","dateFormat","numberFormat","formatOptionsFor","spec","separator","argument","dateStyle","timeStyle","minimumFractionDigits","maximumFractionDigits","currency","toUpperCase","parseValueFormat","warnUnknownFormat","dateRenderer","valid","isNaN","getTime","fallback","toISOString","DEFAULT_DATE_OPTIONS","Intl","DateTimeFormat","getDateTimeFormat","formatDate","day","getFullYear","padStart","pad","getMonth","getDate","clock","getHours","getMinutes","formatForInput","numberRenderer","num","NumberFormat","getNumberFormat","arrayRenderer","renderTemplate","templateOptions","createStructuralArrayRenderer","states","warnedContainers","warnedKeys","rawValue","warnMissingTemplate","previousState","domSnapshot","readDomKeySnapshot","__payloadDomPosition","sameDomKeySnapshot","needsForcedRender","nextKeys","itemKey","warnDuplicateKey","previousKeys","stable","warnAboutKeys","codes","builtinRenderers","omittedRenderer","V2_RUNTIME_DEFAULTS","disableReferrerDetection","V1_RUNTIME_DEFAULTS","invert","LivePreviewClient","detector","rendererRegistry","destroyed","tornDown","destroyPromise","rawConfig","defaults","withProfileDefaults","mergeDepth","assertMergeDepthExplicit","allowedOrigins","disableLocalhostMatching","stateless","buildBuiltinRenderers","mergeTimeoutMs","mergeFetch","e","autoStart","isInPreviewContext","isInPopup","resolveDestroy","rejectDestroy","finish","finally","use","unuse","refreshAfterNavigation","reportPreviewFocus","targetOrigin","DIAGNOSTIC_CODES","NoTrustedOrigin","ReferrerOnlyTrust","PluginIncompatible","ProfileFeatureOmitted","OrphanField","UnattributableUpdate","UnboundField","CoverageDefaultChanges","VisibilityGateDeferred","UnsafeAttributeWrite","TextTargetHasChildren","MissingArrayTemplate","StructuralItemUnkeyed","StructuralDuplicateKey","StructuralUnstableKeys","UnsupportedStrategy","UnknownValueFormat","SanitizerDroppedAttribute","UnrenderedBlockKept","UnfaithfulPatch","ServerFormatReplaced","UnrenderedBlockLost","MessageRejected","TokenRejected","ProtocolShapeUnknown","HandlerThrew","TransformThrew","RendererThrew","StartupFailed","ReadyFailed","HydrationWaitTimedOut","AuditRuntimeMissing","AuditNoFrameAncestors","AuditFrameOptionsBlocks","AuditBindingsExposed","AuditGateThresholdExceeded","AuditUnownedBindings","AuditNoBindings","AuditNotAPage","FragmentRequestFailed","FragmentResponseInvalid","FragmentUnauthorized","FragmentSuperseded","RouteRefreshLoop","FragmentStrategyUnavailable","UnboundChangeRefresh","EscalationUnavailable","IslandStartUnavailable","RouteRefreshUnconfirmed","V2ReadinessGap","RuntimeOnPublicPage","AuditModifierWithoutField","resolveTarget","initLivePreview","client","registerRouteRefresh"],"sources":["../src/detection/locale.ts","../src/core/a11y.ts","../src/schema/parser.ts","../src/core/message-guards.ts","../src/core/protocol-version.ts","../src/core/thenable.ts","../src/core/message-bus.ts","../src/core/diagnostics.ts","../src/core/profile.ts","../src/core/runtime-wiring.ts","../src/types/defined-only.ts","../src/schema/walker.ts","../src/schema/diff.ts","../src/schema/field-type-map.ts","../src/security/url-validator.ts","../src/core/attribute-binding.ts","../src/core/value-identity.ts","../src/core/fidelity.ts","../src/core/internal-outcome.ts","../src/core/field-changes.ts","../src/core/field-value.ts","../src/core/strategies.ts","../src/core/binding-owner.ts","../src/core/subfield-coverage.ts","../src/core/unbound-fields.ts","../src/core/merge-need.ts","../src/detection/environment.ts","../src/core/protocol-tracker.ts","../src/core/relationship-tracker.ts","../src/core/reveal.ts","../src/core/reveal-ledger.ts","../src/core/revision-display.ts","../src/core/runtime-state.ts","../src/core/binding-writer.ts","../src/core/dependencies.ts","../src/core/islands.ts","../src/core/cache.ts","../src/core/legacy-population.ts","../src/core/data-merger.ts","../src/version.ts","../package.json","../src/core/protocol-profile.ts","../src/core/observers.ts","../src/core/lifetime-scope.ts","../src/core/hydration.ts","../src/core/hydration-vue.ts","../src/core/startup.ts","../src/core/hydration-sveltekit.ts","../src/core/hydration-manual.ts","../src/core/state.ts","../src/core/auto-bind.ts","../src/core/moved-rows.ts","../src/core/update-owner.ts","../src/core/navigation-replay.ts","../src/core/orphan-diagnostics.ts","../src/security/trusted-types.ts","../src/core/morph.ts","../src/security/sanitizer-report.ts","../src/security/sanitizer.ts","../src/types/dev-warning.ts","../src/security/escape.ts","../src/core/array-template.ts","../src/field-types/utils.ts","../src/core/lru.ts","../src/core/template-sanitize.ts","../src/core/structural-applier.ts","../src/core/strategy-warnings.ts","../src/core/strategy-runner.ts","../src/core/transform-value.ts","../src/core/update-pipeline.ts","../src/core/strategy-runner-lean.ts","../src/core/update-scheduler.ts","../src/core/lifecycle.ts","../src/core/inspection/snapshot.ts","../src/events/emitter.ts","../src/detection/origin.ts","../src/plugins/resource-scope.ts","../src/plugins/scoped-events.ts","../src/plugins/manager.ts","../src/plugins/compat.ts","../src/plugins/renderer-registry.ts","../src/lexical/utils.ts","../src/lexical/nodes/paragraph.ts","../src/lexical/nodes/heading.ts","../src/lexical/value-shapes.ts","../src/lexical/nodes/link.ts","../src/lexical/nodes/code.ts","../src/lexical/nodes/upload.ts","../src/lexical/nodes/relationship.ts","../src/lexical/blocks/registry.ts","../src/lexical/nodes/block.ts","../src/lexical/nodes/table.ts","../src/lexical/nodes/builtin.ts","../src/lexical/nodes/text.ts","../src/lexical/types.ts","../src/lexical/nodes/list.ts","../src/lexical/nodes/quote.ts","../src/lexical/nodes/linebreak.ts","../src/lexical/registry.ts","../src/lexical/render.ts","../src/field-types/text.ts","../src/field-types/rich-text.ts","../src/field-types/html.ts","../src/field-types/unsafe-url.ts","../src/field-types/url.ts","../src/field-types/email.ts","../src/field-types/media.ts","../src/field-types/image.ts","../src/field-types/upload.ts","../src/field-types/relationship.ts","../src/field-types/select.ts","../src/field-types/checkbox.ts","../src/core/intl-cache.ts","../src/field-types/value-format.ts","../src/field-types/date.ts","../src/field-types/number.ts","../src/field-types/array.ts","../src/field-types/structural-array.ts","../src/field-types/registry.ts","../src/field-types/index.ts","../src/types/defaults-profile.ts","../src/client/index.ts","../src/client/config.ts","../src/types/merge-depth.ts","../src/client/preview-focus.ts","../src/core/diagnostic-codes.ts","../src/core/route-refresh.ts"],"sourcesContent":["/** The locale for `Intl` renders before Payload names one: `<html lang>`, then `navigator.language`, then `'en'`. */\n\nconst FALLBACK_LOCALE = 'en';\n\n/** @internal */\nexport function detectInitialLocale(): string {\n return readHtmlLang() ?? readNavigatorLanguage() ?? FALLBACK_LOCALE;\n}\n\nfunction readHtmlLang(): string | undefined {\n if (typeof document === 'undefined') return undefined;\n const lang = document.documentElement.getAttribute('lang');\n return lang === null || lang.length === 0 ? undefined : lang;\n}\n\nfunction readNavigatorLanguage(): string | undefined {\n if (typeof navigator === 'undefined') return undefined;\n const lang = navigator.language;\n return typeof lang === 'string' && lang.length > 0 ? lang : undefined;\n}\n","/**\n * One polite `aria-live` region per document, leased by every announcer on\n * the page, for connect / update / disconnect announcements. The package clears\n * its message node after a moment so a later message creates a fresh text change.\n */\n\nimport { detectInitialLocale } from '@detection/locale';\n\nconst ELEMENT_ID = 'payload-live-preview-a11y';\nconst CLEAR_DELAY_MS = 1500;\nconst STYLE =\n 'position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;' +\n 'clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0';\n\nfunction isGerman(locale: string): boolean {\n return /^de(?:[-_]|$)/i.test(locale);\n}\n\n/** Shared per document; reference-counted so one client cannot remove another's region. */\ninterface DocumentLease {\n element: HTMLElement | null;\n /** Created by this package (removable) rather than adopted from the page. */\n owned: boolean;\n messageNode: Text | null;\n refs: number;\n timer: ReturnType<typeof setTimeout> | null;\n}\n\nconst documentLeases = new WeakMap<Document, DocumentLease>();\n\nfunction acquireDocumentLease(activeDocument: Document): DocumentLease {\n let lease = documentLeases.get(activeDocument);\n if (lease === undefined) {\n lease = { element: null, owned: false, messageNode: null, refs: 0, timer: null };\n documentLeases.set(activeDocument, lease);\n }\n lease.refs += 1;\n return lease;\n}\n\n/** Remove only the package-owned message node, never consumer children. */\nfunction clearLeaseMessage(lease: DocumentLease): void {\n if (lease.timer !== null) {\n clearTimeout(lease.timer);\n lease.timer = null;\n }\n lease.messageNode?.remove();\n lease.messageNode = null;\n}\n\nexport class A11yAnnouncer {\n private readonly german: boolean;\n private readonly document: Document | null;\n private lease: DocumentLease | null = null;\n\n constructor(locale?: string, targetDocument?: Document | null) {\n const activeDocument = targetDocument ?? (typeof document === 'undefined' ? null : document);\n const documentLocale = activeDocument?.documentElement.getAttribute('lang') ?? '';\n this.german = isGerman(\n locale ?? (documentLocale.length > 0 ? documentLocale : detectInitialLocale()),\n );\n this.document = activeDocument;\n // The region mounts on the first announcement: a <head> inline script runs before `body` exists.\n }\n\n /** The shared region, or `null` without a body yet (announcements are then dropped). */\n private mount(): HTMLElement | null {\n const activeDocument = this.document;\n if (activeDocument?.body == null) return null;\n this.lease ??= acquireDocumentLease(activeDocument);\n const lease = this.lease;\n const leased = lease.element;\n if (leased?.isConnected && leased.ownerDocument === activeDocument) return leased;\n // The host removed or replaced the region between announcements.\n if (leased !== null) {\n const owned = lease.owned;\n clearLeaseMessage(lease);\n if (owned) leased.remove();\n }\n let element = activeDocument.getElementById(ELEMENT_ID);\n lease.owned = element === null;\n if (element === null) {\n element = activeDocument.createElement('div');\n element.id = ELEMENT_ID;\n element.setAttribute('role', 'status');\n element.setAttribute('aria-live', 'polite');\n element.setAttribute('aria-atomic', 'true');\n // Through the CSSOM: a strict `style-src` refuses a `style` attribute,\n // not declarations set on `element.style`.\n element.style.cssText = STYLE;\n activeDocument.body.appendChild(element);\n }\n lease.element = element;\n return element;\n }\n\n announceConnected(): void {\n this.say(this.german ? 'Vorschau verbunden' : 'Live preview connected');\n }\n\n announceDisconnected(): void {\n this.say(this.german ? 'Vorschau getrennt' : 'Live preview disconnected');\n }\n\n announceUpdate(count: number): void {\n if (count <= 0) return;\n this.say(\n this.german\n ? `${String(count)} ${count === 1 ? 'Änderung' : 'Änderungen'} angewendet`\n : `${String(count)} ${count === 1 ? 'change' : 'changes'} applied`,\n );\n }\n\n /** A revision settled with a step that fell short (ADR 0023); the counts said only what was written. */\n announcePartial(): void {\n this.say(this.german ? 'Vorschau teilweise aktualisiert' : 'Preview partly updated');\n }\n\n /** Release the lease; the last release removes an owned region but leaves an adopted one. Idempotent. */\n detach(): void {\n const lease = this.lease;\n const activeDocument = this.document;\n if (lease === null || activeDocument === null) return;\n this.lease = null;\n lease.refs -= 1;\n if (lease.refs > 0) return;\n const element = lease.element;\n if (element !== null) clearLeaseMessage(lease);\n if (lease.owned) element?.remove();\n lease.element = null;\n documentLeases.delete(activeDocument);\n }\n\n private say(message: string): void {\n const element = this.mount();\n const lease = this.lease;\n if (element === null || lease === null) return;\n let messageNode = lease.messageNode;\n if (messageNode?.parentNode !== element) {\n // A dedicated text node leaves consumer-owned children untouched.\n messageNode?.remove();\n messageNode = element.ownerDocument.createTextNode(\n element.hasChildNodes() ? ` ${message}` : message,\n );\n lease.messageNode = messageNode;\n element.appendChild(messageNode);\n } else {\n messageNode.data = messageNode.previousSibling === null ? message : ` ${message}`;\n }\n if (lease.timer !== null) clearTimeout(lease.timer);\n const timer = setTimeout(() => {\n if (lease.timer === timer && lease.element === element) clearLeaseMessage(lease);\n }, CLEAR_DELAY_MS);\n lease.timer = timer;\n }\n}\n","/**\n * Validates the `fieldSchemaJSON` the admin sends. Entries that fail\n * validation are dropped, never thrown: a Payload/runtime version mismatch\n * must not take the preview down.\n */\n\nimport type { PayloadBlockSchema, PayloadFieldSchema } from '@/types/payload-protocol';\n\ninterface ParseState {\n nodes: number;\n readonly active: WeakSet<object>;\n}\nfunction visit(state: ParseState): void {\n if (++state.nodes > 10_000) throw new Error('invalid or oversized field schema');\n}\nfunction enter(value: object, state: ParseState, depth: number): void {\n visit(state);\n if (depth > 64 || state.active.has(value)) throw new Error('invalid or oversized field schema');\n state.active.add(value);\n}\n\nexport function parseFieldSchema(raw: unknown): readonly PayloadFieldSchema[] {\n try {\n return parseFields(raw, { nodes: 0, active: new WeakSet() }, 0);\n } catch {\n return [];\n }\n}\n\nfunction parseFields(\n raw: unknown,\n state: ParseState,\n depth: number,\n): readonly PayloadFieldSchema[] {\n if (!Array.isArray(raw)) return [];\n enter(raw, state, depth);\n const out: PayloadFieldSchema[] = [];\n for (const entry of raw) {\n const parsed = parseFieldEntry(entry, state, depth);\n if (parsed) out.push(parsed);\n }\n state.active.delete(raw);\n return out;\n}\n\nfunction parseFieldEntry(\n value: unknown,\n state: ParseState,\n depth: number,\n): PayloadFieldSchema | undefined {\n visit(state);\n if (typeof value !== 'object' || value === null) return undefined;\n const record = value as Record<string, unknown>;\n const name = record['name'];\n const type = record['type'];\n if (typeof name !== 'string' || name.length === 0) return undefined;\n if (typeof type !== 'string' || type.length === 0) return undefined;\n\n const fields = parseFields(record['fields'], state, depth + 1);\n const blocks = parseBlockSchema(record['blocks'], state, depth + 1);\n\n const result: Record<string, unknown> = { ...record, name, type };\n const relationTo = record['relationTo'];\n if (Array.isArray(relationTo)) {\n const targets: unknown[] = [];\n for (const target of relationTo) {\n visit(state);\n targets.push(target);\n }\n result['relationTo'] = targets;\n }\n if (fields.length > 0) result['fields'] = fields;\n else delete result['fields'];\n if (blocks.length > 0) result['blocks'] = blocks;\n else delete result['blocks'];\n\n return result as unknown as PayloadFieldSchema;\n}\n\nfunction parseBlockSchema(\n raw: unknown,\n state: ParseState,\n depth: number,\n): readonly PayloadBlockSchema[] {\n if (typeof raw === 'object' && raw !== null && !Array.isArray(raw)) {\n enter(raw, state, depth);\n const blocks: PayloadBlockSchema[] = [];\n for (const slug in raw) {\n if (!Object.hasOwn(raw, slug)) continue;\n visit(state);\n const entry: unknown = Reflect.get(raw, slug);\n if (\n typeof entry !== 'object' ||\n entry === null ||\n ['__proto__', 'constructor', 'prototype'].includes(slug)\n ) {\n continue;\n }\n blocks.push({\n ...(entry as Record<string, unknown>),\n slug,\n fields: parseFields((entry as Record<string, unknown>)['fields'], state, depth + 1),\n });\n }\n state.active.delete(raw);\n return blocks;\n }\n if (!Array.isArray(raw)) return [];\n enter(raw, state, depth);\n const out: PayloadBlockSchema[] = [];\n for (const entry of raw) {\n visit(state);\n if (typeof entry !== 'object' || entry === null) continue;\n const record = entry as Record<string, unknown>;\n const slug = record['slug'];\n if (typeof slug !== 'string' || slug.length === 0) continue;\n const fields = parseFields(record['fields'], state, depth + 1);\n out.push({ ...record, slug, fields });\n }\n state.active.delete(raw);\n return out;\n}\n","/**\n * Shape guards for the messages the bus accepts. `null` counts as absent, as\n * JSON bridges send it. The schema parser owns bounded, fail-closed normalization.\n */\n\nimport type {\n PayloadDocumentEventMessage,\n PayloadLivePreviewMessage,\n} from '@/types/payload-protocol';\nimport { parseFieldSchema } from '@schema/parser';\n\nexport function isObjectMessage(value: unknown): value is { type: string } {\n return (\n typeof value === 'object' && value !== null && 'type' in value && typeof value.type === 'string'\n );\n}\n\n/** A `payload-live-preview` message: `data` a plain object when present, scalars of the right type or absent. */\nexport function isLivePreviewMessage(value: { type: string }): value is PayloadLivePreviewMessage {\n const v = value as Record<string, unknown>;\n if (v['data'] !== undefined && v['data'] !== null && !isPlainObject(v['data'])) return false;\n return (\n optionalTypeOk(v['fieldSchemaJSON'], (x) => Array.isArray(x)) &&\n optionalTypeOk(v['globalSlug'], (x) => typeof x === 'string') &&\n optionalTypeOk(v['collectionSlug'], (x) => typeof x === 'string') &&\n optionalTypeOk(v['locale'], (x) => typeof x === 'string') &&\n optionalTypeOk(v['ready'], (x) => typeof x === 'boolean') &&\n optionalTypeOk(v['previewToken'], (x) => typeof x === 'string') &&\n optionalTypeOk(v['protocolVersion'], (x) => typeof x === 'number')\n );\n}\n\n/** The non-empty field name of a `payload-live-preview-focus` message, else `undefined`. */\nexport function focusFieldOf(value: { type: string }): string | undefined {\n const field = (value as Record<string, unknown>)['field'];\n return typeof field === 'string' && field.length > 0 ? field : undefined;\n}\n\n/** Stock Payload sends only the `type`; custom senders may add the typed fields (omitted, never `null`). */\nexport function isDocumentEventMessage(value: {\n type: string;\n}): value is PayloadDocumentEventMessage {\n const v = value as Record<string, unknown>;\n return (\n optionalFieldOk(v['action'], (x) => x === 'updated' || x === 'created' || x === 'deleted') &&\n optionalFieldOk(v['slug'], (x) => typeof x === 'string') &&\n optionalFieldOk(v['id'], (x) => typeof x === 'string' || Number.isFinite(x))\n );\n}\n\nfunction optionalFieldOk(value: unknown, check: (v: unknown) => boolean): boolean {\n return value === undefined || check(value);\n}\n\nfunction optionalTypeOk(value: unknown, check: (v: unknown) => boolean): boolean {\n return value === undefined || value === null || check(value);\n}\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) return false;\n const prototype = Object.getPrototypeOf(value) as object | null;\n return prototype === null || Object.getPrototypeOf(prototype) === null;\n}\n\nconst NULL_AS_ABSENT_FIELDS = [\n 'data',\n 'fieldSchemaJSON',\n 'globalSlug',\n 'collectionSlug',\n 'locale',\n 'ready',\n 'previewToken',\n 'protocolVersion',\n] as const satisfies readonly (keyof PayloadLivePreviewMessage)[];\n\n/**\n * Drop `null` optionals so downstream sees the strict public type, and parse\n * the field schema entry by entry (malformed entries are dropped). Unknown\n * fields stay, for protocol evolution.\n */\nexport function normalizeLivePreviewMessage(\n message: PayloadLivePreviewMessage,\n): PayloadLivePreviewMessage {\n const normalized = { ...message };\n for (const field of NULL_AS_ABSENT_FIELDS) {\n const wireValue: unknown = Reflect.get(normalized, field);\n if (wireValue === null) Reflect.deleteProperty(normalized, field);\n }\n if (!Array.isArray(normalized.fieldSchemaJSON)) return normalized;\n return {\n ...normalized,\n fieldSchemaJSON: parseFieldSchema(normalized.fieldSchemaJSON),\n };\n}\n","/**\n * Protocol negotiation. A capability is granted either by the version a peer\n * announces or by observation, since the stock Payload admin announces none:\n * what it can do is read off the messages it sends. See ADR 0010.\n */\n\n/** Bumped only when this library's understanding of the wire format changes. @internal */\nexport const LIBRARY_PROTOCOL_VERSION = 4;\n\n/** How a capability becomes active. @internal */\nexport type CapabilitySource = 'version' | 'observed';\n\n/** @internal */\nexport interface CapabilityDeclaration {\n /** Enabled once the negotiated version reaches this (for announced peers). */\n readonly since: number;\n /** The wire signal that grants this capability to a peer announcing no version. */\n readonly observed?:\n 'schema' | 'locale' | 'preview-token' | 'document-event' | 'relationship-event';\n}\n\n/** What activates each capability; the prose lives in `CAPABILITY_DOCUMENTATION`. */\nexport const CAPABILITY_DECLARATIONS = {\n basic: { since: 1 },\n 'schema-json': { since: 2, observed: 'schema' },\n locale: { since: 2, observed: 'locale' },\n 'preview-token': { since: 3, observed: 'preview-token' },\n 'nested-arrays': { since: 4 },\n 'recursive-diffs': { since: 4 },\n 'document-events': { since: 4, observed: 'document-event' },\n 'relationship-events': { since: 4, observed: 'relationship-event' },\n} as const satisfies Record<string, CapabilityDeclaration>;\n\nexport type ProtocolCapability = keyof typeof CAPABILITY_DECLARATIONS;\n\n/** Every declared capability, in declaration order. @internal */\nexport const PROTOCOL_CAPABILITIES = Object.keys(\n CAPABILITY_DECLARATIONS,\n) as readonly ProtocolCapability[];\n\nexport interface ProtocolNegotiation {\n /** This library's protocol version. */\n readonly ours: number;\n /** The remote party's version, when it announced one. */\n readonly theirs: number | undefined;\n /** `min(ours, theirs ?? 1)` — the version both sides actually share. */\n readonly negotiated: number;\n /** Capabilities active at the negotiated version or seen on the wire. */\n readonly capabilities: ReadonlySet<ProtocolCapability>;\n /** The subset that was observed on the wire rather than granted by version. */\n readonly observed: ReadonlySet<ProtocolCapability>;\n}\n\n/** Deterministic; the runtime re-runs it whenever either input changes. */\nexport function negotiateProtocol(\n theirs: number | undefined,\n observed: Iterable<ProtocolCapability> = [],\n): ProtocolNegotiation {\n const sanitisedTheirs =\n typeof theirs === 'number' && Number.isFinite(theirs) && theirs >= 1\n ? Math.floor(theirs)\n : undefined;\n const effectiveTheirs = sanitisedTheirs ?? 1;\n const negotiated = Math.min(LIBRARY_PROTOCOL_VERSION, effectiveTheirs);\n const seen = new Set<ProtocolCapability>(observed);\n const capabilities = new Set<ProtocolCapability>();\n for (const capability of PROTOCOL_CAPABILITIES) {\n if (negotiated >= CAPABILITY_DECLARATIONS[capability].since || seen.has(capability)) {\n capabilities.add(capability);\n }\n }\n return {\n ours: LIBRARY_PROTOCOL_VERSION,\n ...(sanitisedTheirs !== undefined ? { theirs: sanitisedTheirs } : { theirs: undefined }),\n negotiated,\n capabilities,\n observed: seen,\n };\n}\n\n/** @internal */\nexport function hasCapability(\n negotiation: ProtocolNegotiation,\n capability: ProtocolCapability,\n): boolean {\n return negotiation.capabilities.has(capability);\n}\n\n/** What a project on Payload 2 hears in development, from the runtime and from a hook. @internal */\nexport const PAYLOAD_2_HINT =\n '[payload-live-preview] This admin sends fieldSchemaJSON, which only Payload 2 does. ' +\n 'Every 2.x release of this package supports Payload 2; 3.0 supports Payload 3 and 4.';\n\n/** The capabilities a single message demonstrates, by its shape alone. */\nexport function observeCapabilities(message: {\n readonly fieldSchemaJSON?: unknown;\n readonly locale?: unknown;\n readonly previewToken?: unknown;\n readonly externallyUpdatedRelationship?: unknown;\n}): readonly ProtocolCapability[] {\n const seen: ProtocolCapability[] = [];\n if (Array.isArray(message.fieldSchemaJSON)) seen.push('schema-json');\n if (typeof message.locale === 'string') seen.push('locale');\n if (typeof message.previewToken === 'string') seen.push('preview-token');\n if (\n typeof message.externallyUpdatedRelationship === 'object' &&\n message.externallyUpdatedRelationship !== null\n ) {\n seen.push('relationship-events');\n }\n return seen;\n}\n","/**\n * Detect an invalid async result in a synchronous extension point.\n *\n * Rejected native Promises otherwise become unhandled after the caller falls\n * back synchronously. Assimilating the result through a handled Promise keeps\n * that contract violation observable only through the runtime's explicit\n * error channel.\n */\nexport function observeThenableResult(value: unknown): boolean {\n if ((typeof value !== 'object' || value === null) && typeof value !== 'function') return false;\n if (typeof (value as { readonly then?: unknown }).then !== 'function') return false;\n void Promise.resolve(value).catch(() => undefined);\n return true;\n}\n","/**\n * postMessage ingress: origin and source checks, per-type shape guards, the\n * ordered preview-token validation queue, and the `ready` handshake. The bus\n * never throws; a rejected message is dropped or reported via `onInvalid`.\n * Consumer callbacks may detach or re-attach the bus synchronously, so\n * anything that runs after one re-checks the generation it started in.\n * See ADR 0004.\n */\n\nimport type {\n PayloadDocumentEventMessage,\n PayloadLivePreviewMessage,\n} from '@/types/payload-protocol';\nimport {\n focusFieldOf,\n isDocumentEventMessage,\n isLivePreviewMessage,\n isObjectMessage,\n isPlainObject,\n normalizeLivePreviewMessage,\n} from './message-guards';\nimport { LIBRARY_PROTOCOL_VERSION } from './protocol-version';\nimport { observeThenableResult } from './thenable';\n\nexport type OriginMatcher = (origin: string) => boolean;\n\n/** Identity of a data-bearing update: `revision` is monotonic, `generation` names the listener attachment. */\nexport interface MessageRevision {\n readonly revision: number;\n readonly generation: number;\n}\nexport function sameRevision(a: MessageRevision, b: MessageRevision): boolean {\n return a.generation === b.generation && a.revision === b.revision;\n}\n\nexport type InvalidReason = 'origin' | 'shape' | 'type' | 'token' | 'source';\n\nexport interface MessageHandlers {\n /** A validated update; data-bearing ones carry their revision, ready handshakes do not. */\n readonly onUpdate: (\n msg: PayloadLivePreviewMessage,\n origin: string,\n messageRevision?: MessageRevision,\n ) => void;\n /** A locally retained, previously accepted update replayed in a new lifecycle generation. */\n readonly onReplay?: (\n msg: PayloadLivePreviewMessage,\n origin: string,\n messageRevision: MessageRevision,\n ) => void;\n readonly onDocumentEvent: (msg: PayloadDocumentEventMessage, origin: string) => void;\n /** The admin reports the cursor moved into a field (reveal tier 2). */\n readonly onFocusField?: (field: string, origin: string) => void;\n readonly onInvalid?: (reason: InvalidReason, origin: string) => void;\n /** `'parent-or-opener'` refuses every window but the framing/opening one, even from an allowed origin. */\n readonly sourcePolicy?: 'any' | 'parent-or-opener';\n /**\n * Gate for data-bearing updates. Verdicts commit in arrival order, so an\n * earlier update is dispatched before a later one even when its validation\n * resolves later; an error counts as rejection.\n */\n readonly validateToken?: (\n token: string | undefined,\n origin: string,\n ) => boolean | Promise<boolean>;\n}\n\n/** One entry of the validation queue: a singly linked list in arrival order. */\ninterface PendingValidation {\n readonly generation: number;\n readonly message: PayloadLivePreviewMessage;\n readonly origin: string;\n readonly messageRevision: MessageRevision | undefined;\n /** `undefined` until the validator settled; only literal `true` approves. */\n verdict: boolean | undefined;\n next: PendingValidation | undefined;\n}\n\ninterface AcceptedUpdate {\n readonly generation: number;\n readonly message: PayloadLivePreviewMessage;\n readonly origin: string;\n}\n\n/** Keep consumer callbacks from mutating the snapshot reserved for navigation replay. */\nfunction snapshotForReplay(message: PayloadLivePreviewMessage): PayloadLivePreviewMessage | null {\n const withoutToken = { ...message };\n delete withoutToken.previewToken;\n try {\n return structuredClone(withoutToken);\n } catch {\n // A real postMessage payload is cloneable. A synthetic non-cloneable one\n // may still be processed once, but retaining it would make replay mutable.\n return null;\n }\n}\n\nexport class MessageBus {\n private readonly matcher: OriginMatcher;\n private readonly handlers: MessageHandlers;\n private boundListener: ((event: MessageEvent) => void) | undefined = undefined;\n private attachedTarget: Window | undefined = undefined;\n private generation = 0;\n private revision = 0;\n private queueHead: PendingValidation | undefined = undefined;\n private queueTail: PendingValidation | undefined = undefined;\n private lastAccepted: AcceptedUpdate | undefined = undefined;\n private replayedGeneration = 0;\n /** Identity of the newest accepted data commit, including one still crossing the clone boundary. */\n private latestAcceptedAttempt: object | undefined = undefined;\n\n constructor(matcher: OriginMatcher, handlers: MessageHandlers) {\n this.matcher = matcher;\n this.handlers = handlers;\n }\n\n /** Start listening on `target`. Idempotent. */\n attach(target: Window = window): void {\n if (this.attachedTarget !== undefined) return;\n let committed = false;\n const listener = (event: MessageEvent): void => {\n // Each attachment owns its listener; a stale one must not borrow the new generation.\n if (!committed || this.boundListener !== listener) return;\n const generation = this.generation;\n try {\n this.receive(event, generation, target);\n } catch {\n // A synthetic event can carry throwing accessors; that is a shape failure.\n let origin: string;\n try {\n origin = event.origin;\n } catch {\n origin = '';\n }\n this.reportInvalid('shape', origin, generation);\n }\n };\n this.generation += 1;\n this.resetQueue();\n this.attachedTarget = target;\n this.boundListener = listener;\n try {\n target.addEventListener('message', listener);\n } catch (error) {\n // Invalidate before rollback: a hook may already have attached a newer generation.\n if (this.boundListener === listener) {\n this.attachedTarget = undefined;\n this.boundListener = undefined;\n this.resetQueue();\n }\n try {\n target.removeEventListener('message', listener);\n } catch {\n // Keep the original failure.\n }\n throw error;\n }\n if (this.boundListener === listener) {\n committed = true;\n } else {\n try {\n target.removeEventListener('message', listener);\n } catch {\n // The listener is identity-gated above even if removal fails.\n }\n }\n }\n\n /** Stop listening. Idempotent. */\n detach(): void {\n const target = this.attachedTarget;\n const listener = this.boundListener;\n if (target === undefined || listener === undefined) return;\n // Invalidate first so a listener already on the stack sees an obsolete generation.\n this.attachedTarget = undefined;\n this.boundListener = undefined;\n this.resetQueue();\n target.removeEventListener('message', listener);\n }\n\n /** Invalidate pending validations while staying attached (heartbeat expiry). */\n advanceGeneration(): boolean {\n if (this.attachedTarget === undefined) return false;\n this.generation += 1;\n this.resetQueue();\n return true;\n }\n\n /**\n * Re-dispatch the last data-bearing update under the current generation.\n * Only an update already accepted in an older generation is eligible; its\n * preview token is never retained or replayed. @internal\n */\n replayLastAccepted(): boolean {\n const accepted = this.lastAccepted;\n const generation = this.generation;\n const handler = this.handlers.onReplay;\n if (\n handler === undefined ||\n accepted === undefined ||\n accepted.generation >= generation ||\n this.replayedGeneration === generation\n ) {\n return false;\n }\n // Origin matching fails closed outside the attached generation it ran in,\n // and it is consumer code that may accept a newer message reentrantly.\n // Never let the older snapshot run after it.\n if (!this.matchesOrigin(accepted.origin, generation) || this.lastAccepted !== accepted) {\n return false;\n }\n this.replayedGeneration = generation;\n const revision = { generation, revision: (this.revision += 1) };\n // Clone for every replay: hooks may mutate what they receive, but the\n // retained copy is the baseline for later navigations too. It came out\n // of structuredClone, so cloning it again cannot throw.\n this.invokeHandler(\n generation,\n handler,\n structuredClone(accepted.message),\n accepted.origin,\n revision,\n );\n return true;\n }\n\n /** Forget retained document data when the connection expires or the owner is destroyed. @internal */\n forgetLastAccepted(): void {\n this.lastAccepted = undefined;\n this.replayedGeneration = 0;\n this.latestAcceptedAttempt = undefined;\n }\n\n /** Post the `ready` handshake to every target for every origin. */\n static sendReady(targets: readonly Window[], origins: readonly string[]): void {\n const payload: PayloadLivePreviewMessage = {\n type: 'payload-live-preview',\n ready: true,\n protocolVersion: LIBRARY_PROTOCOL_VERSION,\n };\n for (const target of targets) {\n for (const origin of origins) {\n try {\n target.postMessage(payload, origin);\n } catch {\n // A malformed origin is the consumer's configuration problem.\n }\n }\n }\n }\n\n private receive(event: MessageEvent, generation: number, target: Window): void {\n const origin = event.origin;\n if (!this.matchesOrigin(origin, generation)) {\n this.reportInvalid('origin', origin, generation);\n return;\n }\n if (!this.matchesSource(event, target)) {\n this.reportInvalid('source', origin, generation);\n return;\n }\n const data: unknown = event.data;\n if (!isObjectMessage(data)) {\n this.reportInvalid('shape', origin, generation);\n return;\n }\n switch (data.type) {\n case 'payload-live-preview':\n if (!isLivePreviewMessage(data)) {\n this.reportInvalid('shape', origin, generation);\n return;\n }\n this.dispatchUpdate(normalizeLivePreviewMessage(data), origin, generation);\n return;\n case 'payload-document-event':\n if (!isDocumentEventMessage(data)) {\n this.reportInvalid('shape', origin, generation);\n return;\n }\n this.invokeHandler(generation, this.handlers.onDocumentEvent, data, origin);\n return;\n case 'payload-live-preview-focus': {\n const field = focusFieldOf(data);\n if (field === undefined) {\n this.reportInvalid('shape', origin, generation);\n return;\n }\n this.invokeHandler(generation, this.handlers.onFocusField, field, origin);\n return;\n }\n default:\n this.reportInvalid('type', origin, generation);\n }\n }\n\n private dispatchUpdate(\n message: PayloadLivePreviewMessage,\n origin: string,\n generation: number,\n ): void {\n const hasUpdateData = isPlainObject(message.data);\n if (!this.isCurrentGeneration(generation)) return;\n // A shape-valid data update consumes its revision before validation; a rejected token leaves a gap.\n const messageRevision = hasUpdateData\n ? { generation, revision: (this.revision += 1) }\n : undefined;\n const validator = this.handlers.validateToken;\n if (!this.isCurrentGeneration(generation)) return;\n if (validator === undefined) {\n this.commitUpdate(message, origin, generation, messageRevision);\n return;\n }\n // The data-less ready handshake carries no token and passes, so the admin learns we listen.\n if (message.ready === true && message.data === undefined) {\n this.commitUpdate(message, origin, generation, undefined);\n return;\n }\n const pending: PendingValidation = {\n generation,\n message,\n origin,\n messageRevision,\n verdict: undefined,\n next: undefined,\n };\n this.enqueue(pending);\n let verdict: unknown;\n try {\n // Invoked eagerly; only the commit waits for earlier queue entries.\n verdict = validator(message.previewToken, origin);\n } catch {\n this.settleValidation(pending, false);\n return;\n }\n if (typeof verdict === 'boolean') {\n this.settleValidation(pending, verdict);\n return;\n }\n // Assimilate any thenable; only literal `true` approves.\n void Promise.resolve(verdict).then(\n (approved) => {\n this.settleValidation(pending, approved === true);\n },\n () => {\n this.settleValidation(pending, false);\n },\n );\n }\n\n private settleValidation(pending: PendingValidation, approved: boolean): void {\n pending.verdict = approved;\n this.drainQueue(pending.generation);\n }\n\n private drainQueue(generation: number): void {\n while (this.isCurrentGeneration(generation)) {\n const pending = this.queueHead;\n if (pending === undefined) return;\n // The matcher may have narrowed since ingress (origin lock); an obsolete\n // origin must not hold the queue head and block the locked origin's work.\n if (!this.matchesOrigin(pending.origin, generation)) {\n if (!this.dequeue(pending)) continue;\n this.reportInvalid('origin', pending.origin, pending.generation);\n continue;\n }\n if (pending.verdict === undefined) return;\n if (!this.dequeue(pending)) continue;\n if (pending.verdict) {\n this.commitUpdate(\n pending.message,\n pending.origin,\n pending.generation,\n pending.messageRevision,\n );\n } else {\n this.reportInvalid('token', pending.origin, pending.generation);\n }\n }\n }\n\n private commitUpdate(\n message: PayloadLivePreviewMessage,\n origin: string,\n generation: number,\n messageRevision: MessageRevision | undefined,\n ): void {\n if (messageRevision === undefined) {\n this.invokeHandler(generation, this.handlers.onUpdate, message, origin);\n } else {\n const attempt = {};\n this.latestAcceptedAttempt = attempt;\n const snapshot = snapshotForReplay(message);\n // Cloning synthetic input can run accessors. If one accepted a newer\n // message reentrantly, the older commit must not overwrite or follow it.\n if (this.latestAcceptedAttempt !== attempt || !this.isCurrentGeneration(generation)) return;\n this.lastAccepted = snapshot === null ? undefined : { generation, message: snapshot, origin };\n this.invokeHandler(generation, this.handlers.onUpdate, message, origin, messageRevision);\n }\n }\n\n private reportInvalid(reason: InvalidReason, origin: string, generation: number): void {\n this.invokeHandler(generation, this.handlers.onInvalid, reason, origin);\n }\n\n /** Under `'parent-or-opener'`, whether the event came from the attached window's parent or opener. */\n private matchesSource(event: MessageEvent, target: Window): boolean {\n if (this.handlers.sourcePolicy !== 'parent-or-opener') return true;\n try {\n // Only a window is a source: a missing one matches nothing, not even a missing opener.\n const source: unknown = event.source;\n if (typeof source !== 'object' || source === null) return false;\n const parent = target.parent;\n if (parent !== target && source === parent) return true;\n const opener: unknown = target.opener;\n return source === opener;\n } catch {\n return false;\n }\n }\n\n /** Fail-closed: only literal `true` from the matcher, and only within the generation it ran in. */\n private matchesOrigin(origin: string, generation: number): boolean {\n try {\n const approved: unknown = this.isCurrentGeneration(generation) && this.matcher(origin);\n return approved === true && this.isCurrentGeneration(generation);\n } catch {\n return false;\n }\n }\n\n /** Callbacks run only in a current generation and must not unwind the listener or the drain. */\n private invokeHandler<TArgs extends unknown[]>(\n generation: number,\n handler: ((...args: TArgs) => unknown) | undefined,\n ...args: TArgs\n ): void {\n if (handler === undefined || !this.isCurrentGeneration(generation)) return;\n try {\n observeThenableResult(handler(...args));\n } catch {\n // Isolated by contract.\n }\n }\n\n private isCurrentGeneration(generation: number): boolean {\n return this.attachedTarget !== undefined && this.generation === generation;\n }\n\n private enqueue(pending: PendingValidation): void {\n if (this.queueTail === undefined) this.queueHead = pending;\n else this.queueTail.next = pending;\n this.queueTail = pending;\n }\n\n /** Advance the head past `expected`, unless a matcher reset the queue meanwhile. */\n private dequeue(expected: PendingValidation): boolean {\n if (this.queueHead !== expected) return false;\n this.queueHead = expected.next;\n if (this.queueHead === undefined) this.queueTail = undefined;\n return true;\n }\n\n private resetQueue(): void {\n this.queueHead = undefined;\n this.queueTail = undefined;\n }\n}\n","import { observeThenableResult } from './thenable';\n\n/**\n * Diagnostics are observability, never control flow: a consumer logger may\n * throw or return a rejected thenable, and reporting a failure must not become\n * a second failure. Invocation stays synchronous for ordinary loggers.\n */\nexport function isolateDiagnostic(\n diagnostic: (...args: unknown[]) => unknown,\n): (...args: unknown[]) => void {\n return (...args): void => {\n try {\n observeThenableResult(diagnostic(...args));\n } catch {\n // Diagnostics must not become a second failure boundary.\n }\n };\n}\n\n/** Shared allocation-free default for disabled diagnostic channels. */\nexport function noopDiagnostic(): void {\n // Intentionally empty.\n}\n\n// Access, invocation and thenable inspection all happen inside the wrapper, so\n// a missing or hostile console cannot escape.\nexport const safeConsoleError = isolateDiagnostic((...args) =>\n (console.error as (...values: unknown[]) => unknown)(...args),\n);\n\nexport const safeConsoleWarn = isolateDiagnostic((...args) =>\n (console.warn as (...values: unknown[]) => unknown)(...args),\n);\n\nexport const safeConsoleDebug = isolateDiagnostic((...args) =>\n // eslint-disable-next-line no-console -- best-effort development diagnostics\n (console.debug as (...values: unknown[]) => unknown)(...args),\n);\n","/**\n * The build profile: which features are compiled into the inline runtime.\n *\n * `scripts/build-runtime.ts` builds the runtime twice — once with everything,\n * once with `__LEAN_BUILD__` defined — and the generator embeds whichever the\n * page asked for. The flag is read into a constant so esbuild folds it and\n * drops the branch, and with it every module only that branch referenced. In\n * the programmatic client the define is absent, so nothing is dropped there.\n *\n * A profile is a byte trade, never a behaviour trade in disguise: a page that\n * needs what the lean profile left out is told so (LP0104) instead of quietly\n * doing nothing.\n *\n * The flag itself is not exported. Each guard site reads `__LEAN_BUILD__`\n * directly, in expression position, because that is the only shape esbuild\n * folds — `src/types/build-flags.d.ts` explains why, with what was measured.\n */\n\nimport { safeConsoleWarn } from './diagnostics';\n\n/** What the lean profile leaves out, in the words the documentation uses. */\nexport type OmittedFeature =\n | 'structural arrays'\n | 'array templates'\n | 'server-rendered fragments'\n | 'route refreshes'\n | 'screen-reader announcements'\n | 'auto-binding';\n\nconst HOW_TO_GET_IT: Readonly<Record<OmittedFeature, string>> = {\n 'structural arrays': 'data-payload-type=\"array\" and keyed lists',\n 'array templates': 'data-payload-array-template',\n 'server-rendered fragments': 'data-payload-fragment boundaries',\n 'route refreshes': 'data-payload-strategy=\"route\" and bindings in <head>',\n 'screen-reader announcements': 'the aria-live region',\n 'auto-binding': \"autoBind: 'unique'\",\n};\n\nconst reported = new Set<OmittedFeature>();\n\n/**\n * Report once per feature and per page. The markup is the cause and it does not\n * change between updates, so a second message would only be noise.\n */\nexport function reportOmittedFeature(feature: OmittedFeature): void {\n if (reported.has(feature)) return;\n reported.add(feature);\n safeConsoleWarn(\n `[live-preview] LP0104: this page carries the lean runtime, which leaves out ${feature} ` +\n `(${HOW_TO_GET_IT[feature]}). The elements are left as the server rendered them. ` +\n `Remove \\`runtime: LEAN_RUNTIME\\` to get the full runtime.`,\n );\n}\n","/**\n * What the runtime builds around itself before it starts: the screen-reader\n * announcer, and where the `ready` handshake goes.\n *\n * Apart in this module for two reasons. The announcer is the one dependency the\n * lean profile leaves out, and the guard that drops it has to sit in expression\n * position at the seam (`src/types/build-flags.d.ts`); and `lifecycle.ts` is the\n * runtime's own lifecycle, which stays readable only if the wiring around it\n * lives next door rather than inside.\n */\n\nimport { A11yAnnouncer } from './a11y';\nimport { MessageBus } from './message-bus';\nimport { reportOmittedFeature } from './profile';\nimport type { RuntimeOptions } from './runtime-options';\n\n/**\n * The announcer and its locale table are ~800 bytes gzip the lean profile does\n * without; a page that asked for announcements is told instead (./profile).\n */\nexport function createA11y(options: RuntimeOptions): A11yAnnouncer | null {\n return typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__\n ? refuseA11y(options)\n : buildA11y(options);\n}\n\nfunction refuseA11y(options: RuntimeOptions): null {\n if (options.enableA11y !== false) reportOmittedFeature('screen-reader announcements');\n return null;\n}\n\nfunction buildA11y(options: RuntimeOptions): A11yAnnouncer | null {\n if (options.enableA11y === false) return null;\n const root = options.root;\n const targetDocument =\n root === undefined ? undefined : isDocumentRoot(root) ? root : root.ownerDocument;\n return new A11yAnnouncer(options.a11yLocale, targetDocument);\n}\n\n/** Node types are stable across realms; global constructors are not. */\nfunction isDocumentRoot(root: Document | Element): root is Document {\n return root.nodeType === 9;\n}\n\n/** The framing or opening window, which is the only one that asked for a preview. */\nexport function defaultSendReady(origins: readonly string[]): void {\n if (typeof window === 'undefined') return;\n const targets: Window[] = [];\n if (window.parent !== window) targets.push(window.parent);\n if (window.opener instanceof Window) targets.push(window.opener);\n MessageBus.sendReady(targets, origins);\n}\n","/** Drops `undefined`-valued keys, so a literal built from optional inputs satisfies `exactOptionalPropertyTypes`. */\n\nexport type DefinedOnly<T> = { readonly [K in keyof T]-?: Exclude<T[K], undefined> };\n\nexport function definedOnly<T extends object>(source: T): DefinedOnly<T> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(source)) {\n if (value !== undefined) result[key] = value;\n }\n return result as DefinedOnly<T>;\n}\n","/**\n * Flattens a parsed field schema into dotted paths (`hero.title`,\n * `sections.*.heading`). Named tabs in Payload 2 own data beneath their name;\n * rows, collapsibles and the older custom tab lookup retain flat inner paths.\n * Separate flat and fully named passes prevent nested tabs multiplying paths.\n */\n\nimport type {\n PayloadBlockSchema,\n PayloadFieldSchema,\n PayloadFieldType,\n} from '@/types/payload-protocol';\n\nexport type SchemaIndex = ReadonlyMap<string, PayloadFieldSchema>;\n\nconst STRUCTURAL_TYPES: ReadonlySet<PayloadFieldType> = new Set<PayloadFieldType>([\n 'tabs',\n 'row',\n 'collapsible',\n]);\n\nexport function buildSchemaIndex(\n schemas: readonly PayloadFieldSchema[],\n basePath = '',\n): SchemaIndex {\n const out = new Map<string, PayloadFieldSchema>();\n walk(schemas, basePath, out, false);\n walk(schemas, basePath, out, true);\n return out;\n}\n\nfunction walk(\n schemas: readonly PayloadFieldSchema[],\n basePath: string,\n out: Map<string, PayloadFieldSchema>,\n namedTabs: boolean,\n): void {\n for (const schema of schemas) {\n if (STRUCTURAL_TYPES.has(schema.type)) {\n const fields = schema.fields;\n if (fields) {\n const path =\n namedTabs && schema.type === 'tabs'\n ? basePath === ''\n ? schema.name\n : `${basePath}.${schema.name}`\n : basePath;\n walk(fields, path, out, namedTabs);\n }\n continue;\n }\n const path = basePath === '' ? schema.name : `${basePath}.${schema.name}`;\n out.set(path, schema);\n if (schema.type === 'group') {\n if (schema.fields) walk(schema.fields, path, out, namedTabs);\n } else if (schema.type === 'array' && schema.fields) {\n walk(schema.fields, `${path}.*`, out, namedTabs);\n } else if (schema.type === 'blocks' && schema.blocks) {\n for (const block of schema.blocks) {\n walk(block.fields, `${path}.*.${block.slug}`, out, namedTabs);\n }\n }\n }\n}\n\n/** Schema for `fieldPath`; numeric segments are retried as `*` wildcards. */\nexport function lookupSchema(\n index: SchemaIndex,\n fieldPath: string,\n): PayloadFieldSchema | undefined {\n if (index.has(fieldPath)) return index.get(fieldPath);\n const wildcardPath = fieldPath.replace(/\\.\\d+(?=\\.|$)/g, '.*');\n if (index.has(wildcardPath)) return index.get(wildcardPath);\n return undefined;\n}\n\nexport function lookupBlockSchema(\n index: SchemaIndex,\n blocksFieldPath: string,\n blockType: string,\n): PayloadBlockSchema | undefined {\n const schema = lookupSchema(index, blocksFieldPath);\n if (!schema?.blocks) return undefined;\n return schema.blocks.find((b) => b.slug === blockType);\n}\n","/**\n * Structural diff for array and blocks fields. Items with an `id` are keyed\n * (moves are detected); without ids the diff is positional.\n * @internal\n */\n\nexport type ArrayPatch =\n | { readonly kind: 'insert'; readonly index: number; readonly value: unknown }\n | { readonly kind: 'remove'; readonly index: number; readonly value: unknown }\n | {\n readonly kind: 'move';\n readonly from: number;\n readonly to: number;\n readonly value: unknown;\n }\n | { readonly kind: 'update'; readonly index: number; readonly value: unknown }\n | {\n readonly kind: 'replace';\n readonly index: number;\n readonly oldValue: unknown;\n readonly value: unknown;\n };\n\nfunction getId(item: unknown): string | number | undefined {\n if (typeof item !== 'object' || item === null) return undefined;\n const id = (item as Record<string, unknown>)['id'];\n if (typeof id === 'string' || typeof id === 'number') return id;\n return undefined;\n}\n\nfunction getBlockType(item: unknown): string | undefined {\n if (typeof item !== 'object' || item === null) return undefined;\n const blockType = (item as Record<string, unknown>)['blockType'];\n return typeof blockType === 'string' ? blockType : undefined;\n}\n\n/** Patches that turn `prev` into `next`; a changed `blockType` is a `replace`, never an `update`. */\nexport function diffArray(\n prev: readonly unknown[],\n next: readonly unknown[],\n): readonly ArrayPatch[] {\n const haveIds = next.every((item) => getId(item) !== undefined);\n if (haveIds) return diffById(prev, next);\n return diffByPosition(prev, next);\n}\n\nfunction diffById(prev: readonly unknown[], next: readonly unknown[]): readonly ArrayPatch[] {\n const patches: ArrayPatch[] = [];\n const prevIndexById = new Map<string | number, number>();\n for (let i = 0; i < prev.length; i += 1) {\n const id = getId(prev[i]);\n if (id !== undefined) prevIndexById.set(id, i);\n }\n\n const consumedFromPrev = new Set<number>();\n for (let to = 0; to < next.length; to += 1) {\n const item = next[to];\n const id = getId(item);\n if (id === undefined) {\n patches.push({ kind: 'insert', index: to, value: item });\n continue;\n }\n const from = prevIndexById.get(id);\n if (from === undefined) {\n patches.push({ kind: 'insert', index: to, value: item });\n continue;\n }\n consumedFromPrev.add(from);\n const prevItem = prev[from];\n if (getBlockType(prevItem) !== getBlockType(item)) {\n patches.push({ kind: 'replace', index: to, oldValue: prevItem, value: item });\n continue;\n }\n if (from !== to) {\n patches.push({ kind: 'move', from, to, value: item });\n }\n if (!shallowEqual(prevItem, item)) {\n patches.push({ kind: 'update', index: to, value: item });\n }\n }\n\n for (let i = 0; i < prev.length; i += 1) {\n if (consumedFromPrev.has(i)) continue;\n patches.push({ kind: 'remove', index: i, value: prev[i] });\n }\n return patches;\n}\n\nfunction diffByPosition(prev: readonly unknown[], next: readonly unknown[]): readonly ArrayPatch[] {\n const patches: ArrayPatch[] = [];\n const min = Math.min(prev.length, next.length);\n for (let i = 0; i < min; i += 1) {\n if (!shallowEqual(prev[i], next[i])) {\n patches.push({ kind: 'update', index: i, value: next[i] });\n }\n }\n if (next.length > prev.length) {\n for (let i = prev.length; i < next.length; i += 1) {\n patches.push({ kind: 'insert', index: i, value: next[i] });\n }\n }\n if (prev.length > next.length) {\n for (let i = next.length; i < prev.length; i += 1) {\n patches.push({ kind: 'remove', index: i, value: prev[i] });\n }\n }\n return patches;\n}\n\n// Shallow on purpose: any nested reference change is an update, and the\n// renderer reconciles deeper differences itself.\nfunction shallowEqual(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;\n const aRec = a as Record<string, unknown>;\n const bRec = b as Record<string, unknown>;\n const aKeys = Object.keys(aRec);\n const bKeys = Object.keys(bRec);\n if (aKeys.length !== bKeys.length) return false;\n for (const key of aKeys) {\n if (!Object.is(aRec[key], bRec[key])) return false;\n }\n return true;\n}\n","/**\n * Payload field type → renderer name. Structural containers the walker has\n * already flattened, and types without a display, map to `text` so a new\n * Payload field type never leaves a binding without a renderer.\n */\n\nimport type { FieldType } from '@core/types';\nimport type { PayloadFieldType } from '@/types/payload-protocol';\n\nconst MAP: Readonly<Record<PayloadFieldType, FieldType>> = {\n text: 'text',\n textarea: 'textarea',\n richText: 'richText',\n email: 'email',\n number: 'number',\n checkbox: 'checkbox',\n date: 'date',\n select: 'select',\n radio: 'radio',\n array: 'array',\n blocks: 'blocks',\n group: 'text',\n tabs: 'text',\n row: 'text',\n collapsible: 'text',\n relationship: 'relationship',\n upload: 'upload',\n point: 'text',\n json: 'text',\n code: 'text',\n ui: 'text',\n};\n\n/** `undefined` for a type not in the table, so the caller can fall back to the DOM attribute. */\nexport function payloadTypeToRenderer(type: string): FieldType | undefined {\n if (Object.prototype.hasOwnProperty.call(MAP, type)) {\n return MAP[type as PayloadFieldType];\n }\n return undefined;\n}\n","/**\n * URL safety: the one scheme allow-list the runtime, the client and the\n * sanitizer share. Empty strings are not safe (`<a href=\"\">` is never emitted).\n */\n\nconst SAFE_PROTOCOLS: ReadonlySet<string> = new Set(['http:', 'https:', 'mailto:', 'tel:']);\n\nconst RELATIVE_PATH = /^(?:\\.{1,2}\\/|[a-zA-Z0-9_-]+\\/?)/;\n\n// The URL parser treats `\\` as `/` for special schemes, so `/\\evil.com`\n// resolves to another origin rather than to a same-origin path.\nconst PROTOCOL_RELATIVE = /^[\\\\/]{2}/;\n\n/** The URL parser drops these anywhere in the input before it looks at anything. */\nconst PARSER_IGNORED = /[\\t\\n\\r]/g;\n\n/**\n * What is dropped from a value before it is read for a scheme: JavaScript's\n * whitespace and DOMPurify's `ATTR_WHITESPACE` together. That is ASCII\n * controls and spaces, the no-break spaces, the byte-order mark and the Unicode\n * space and format ranges. The URL parser keeps most of these, so `java\n * script:` is a relative path to it; a sanitizer in front of an older parser\n * reads a scheme through the gaps, and the union stays at least as strict as\n * each of the two.\n */\n/* eslint-disable no-control-regex -- the class takes in DOMPurify's, which has controls */\nconst SCHEME_GAPS = /[\\s\\u0000-\\u001f\\u180e\\u2000-\\u2029]/g;\n/* eslint-enable no-control-regex */\nconst SCHEME = /^([a-z][a-z0-9+.-]*):/i;\n\n/** Whether `value`, with the gaps closed, starts with a scheme the allow-list does not hold. */\nfunction spellsUnsafeScheme(value: string): boolean {\n const scheme = SCHEME.exec(value.replace(SCHEME_GAPS, ''))?.[1];\n return scheme !== undefined && !SAFE_PROTOCOLS.has(`${scheme.toLowerCase()}:`);\n}\n\n/** `true` only for absolute `http`/`https`/`mailto`/`tel` URLs, protocol-relative URLs, paths, `#`/`?` fragments and relative paths. */\nexport function isSafeUrl(url: unknown): boolean {\n if (typeof url !== 'string') return false;\n const trimmed = url.trim().replace(PARSER_IGNORED, '');\n if (trimmed.length === 0) return false;\n if (trimmed.startsWith('#') || trimmed.startsWith('?')) return true;\n if (PROTOCOL_RELATIVE.test(trimmed)) return true;\n if (trimmed.startsWith('/')) return true;\n try {\n const parsed = new URL(trimmed);\n return SAFE_PROTOCOLS.has(parsed.protocol);\n } catch {\n return RELATIVE_PATH.test(trimmed) && !spellsUnsafeScheme(trimmed);\n }\n}\n\n/** Whether a URL points at another HTTP(S) origin, protocol-relative forms included, and so needs `noopener` hardening; every URL these two patterns match is one `isSafeUrl` admits. */\nexport function isExternalHttpUrl(url: string): boolean {\n const trimmed = url.trim().replace(PARSER_IGNORED, '');\n return /^https?:\\/\\//i.test(trimmed) || PROTOCOL_RELATIVE.test(trimmed);\n}\n\n/** The safe scheme set, for tests and introspection. */\nexport const SAFE_URL_PROTOCOLS: ReadonlySet<string> = SAFE_PROTOCOLS;\n","/**\n * Policed writes for `data-payload-attribute` bindings. The value is\n * remote-controlled, so event handlers, `style`, `srcdoc`, `formaction`/`form`,\n * `id`/`name` (DOM clobbering) and `srcset` (multi-URL syntax) are refused,\n * URL-bearing attributes must pass `isSafeUrl`, and non-scalars never write.\n */\n\nimport { isSafeUrl } from '@security/url-validator';\n\nconst BLOCKED_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'style',\n 'srcdoc',\n 'formaction',\n 'form',\n 'id',\n 'name',\n 'is',\n 'srcset',\n 'imagesrcset',\n]);\n\nconst URL_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'href',\n 'src',\n 'poster',\n 'cite',\n 'action',\n 'xlink:href',\n 'data',\n]);\n\nexport type AttributeApplyResult = 'applied' | 'blocked';\n\n/**\n * Whether this package may write an attribute of this name at all — event\n * handlers, `style`, the two DOM-clobbering names and the multi-URL ones\n * excluded. One rule, two callers: the binding below writes a remote value into\n * it, and the array renderers copy one from the page's own markup onto an item\n * they rebuilt (`src/core/array-template.ts`).\n */\nexport function isWritableAttribute(name: string): boolean {\n return !name.startsWith('on') && !BLOCKED_ATTRIBUTES.has(name);\n}\n\n/** Returns `'blocked'` without touching the DOM when the write is refused. */\nexport function applyAttributeBinding(\n element: Element,\n attribute: string,\n value: unknown,\n): AttributeApplyResult {\n const name = attribute.toLowerCase().trim();\n if (name.length === 0) return 'blocked';\n if (!isWritableAttribute(name)) return 'blocked';\n\n if (value === null || value === undefined) {\n element.removeAttribute(name);\n return 'applied';\n }\n if (typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean') {\n return 'blocked';\n }\n const stringValue = String(value);\n\n if (URL_ATTRIBUTES.has(name) && !isSafeUrl(stringValue)) return 'blocked';\n\n element.setAttribute(name, stringValue);\n return 'applied';\n}\n","/**\n * Stable identity for a field value, so two messages can be compared without\n * rendering either — every keystroke ships the whole document, of which one\n * field changed. Equality is structural (plain, unsorted JSON): Payload\n * allocates a fresh object graph per message, so reference identity would skip\n * nothing. A value JSON cannot represent has no identity and counts as\n * changed, which is the safe direction — a false \"equal\" leaves a stale\n * binding, a false \"different\" only renders once more.\n */\n\n/** Past this size the comparison is no longer obviously cheaper than the render it avoids. */\nexport const IDENTITY_SIZE_LIMIT = 64 * 1024;\n\n/**\n * Canonical string for `value`, or `undefined` when it cannot have one.\n * Primitives carry a type tag, so `1` and `'1'` differ even though a text\n * renderer prints them alike — that is the renderer's decision, not this one.\n */\nexport function valueIdentity(value: unknown): string | undefined {\n switch (typeof value) {\n case 'string':\n return value.length > IDENTITY_SIZE_LIMIT ? undefined : `s:${value}`;\n case 'number':\n // Object.is semantics at the top level: NaN equals NaN, -0 is not 0.\n return `n:${Object.is(value, -0) ? '-0' : String(value)}`;\n case 'boolean':\n return `b:${value ? '1' : '0'}`;\n case 'bigint':\n return `i:${String(value)}`;\n case 'undefined':\n return 'u';\n case 'object': {\n if (value === null) return 'z';\n let json: string;\n try {\n // Throws on a cycle and on a nested BigInt; both mean \"no identity\".\n json = JSON.stringify(value);\n } catch {\n return undefined;\n }\n return json.length > IDENTITY_SIZE_LIMIT ? undefined : `o:${json}`;\n }\n case 'symbol':\n case 'function':\n return undefined;\n }\n}\n","/**\n * What the runtime does about a patch it knows will not reach what the server\n * would have drawn: a renderer that refused the value, a Lexical block whose\n * markup the write had to drop. The finding is made where the write happens;\n * the policy and the ledger live here, so the pipeline can hand the region to a\n * strategy once the flush is over instead of leaving the page worse off.\n *\n * A changed field with no binding at all is the same judgement made one step\n * earlier — there is no element to write to — and `StrategyRunner` reaches it\n * from `unbound-fields.ts` before anything is scheduled.\n */\n\nimport type { RuntimeDeps, RuntimeState } from './runtime-state';\nimport type { CachedElement } from './types';\nimport { valueIdentity } from './value-identity';\n\n/**\n * `'ignore'` keeps the degraded patch, which is what 2.0 shipped under the\n * name `onUnboundChange: 'ignore'`. `'warn'` keeps it and says so (LP0411).\n * `'escalate'`, the default, asks a server to draw the region instead: the\n * fragment strategy when a boundary covers the binding, the route otherwise.\n *\n * Without a strategy to escalate to, every mode keeps the patch. A page that\n * cannot ask a server for better markup is not helped by being told twice.\n */\nexport type UnfaithfulPatchMode = 'ignore' | 'warn' | 'escalate';\n\n/**\n * Both spellings of the option; the 2.0 name stays until 3.0. Explicitly\n * `| undefined`, because one caller reads them out of the inline script's\n * positional tuple, where an omitted slot is exactly that.\n */\nexport interface UnfaithfulPatchOptions {\n readonly onUnfaithfulPatch?: UnfaithfulPatchMode | undefined;\n readonly onUnboundChange?: 'ignore' | 'route' | undefined;\n}\n\n/**\n * The 2.0 name maps onto the new one without loss: `'route'` was this option's\n * escalation and `'ignore'` its opt-out. Only an omitted option takes the new\n * default — a project that wrote `'ignore'` down chose it, and keeps it.\n */\nexport function resolveUnfaithfulPatchMode(options: UnfaithfulPatchOptions): UnfaithfulPatchMode {\n // `'ignore'` is the only thing the old name can still say that the new\n // default does not: its `'route'` and its absence both mean escalate now.\n return (\n options.onUnfaithfulPatch ?? (options.onUnboundChange === 'ignore' ? 'ignore' : 'escalate')\n );\n}\n\n/** The value an element was last reported or handed over with, and when. */\nexport interface UnfaithfulReport {\n readonly identity: string | undefined;\n readonly at: number;\n}\n\n/** How long an element waits before a new value of it is escalated again. */\nconst ESCALATE_AGAIN_MS = 1000;\n\n/**\n * Record one binding this revision could not patch faithfully, and queue it for\n * the escalation the flush will run.\n *\n * Counted, and said as LP0411, once per element: the cause is the markup or the\n * value's shape, so the next message would report the same thing. Under\n * `'escalate'` a later revision with a new value is handed over again, since\n * the region the server drew still shows the old one: at most once a second\n * per element, so typing is not a refresh per keystroke, and never with the\n * value it was last handed over with, which the re-apply after a route render\n * hands the renderer again. A value held back by that second is handed over by\n * the first report after it, the re-apply included.\n *\n * Counted under every mode, before the mode decides anything: `inspect()` has\n * to be able to say \"three patches fell short, none was escalated\" on the page\n * whose owner chose `'ignore'` as much as on the one that has no strategy.\n */\nexport function reportUnfaithfulPatch(\n deps: RuntimeDeps,\n state: RuntimeState,\n target: CachedElement,\n reason: string,\n value: unknown,\n): void {\n const mode = deps.onUnfaithfulPatch;\n const last = state.reportedUnfaithful.get(target.element);\n const identity = valueIdentity(value);\n const now = Date.now();\n const repeated =\n last !== undefined &&\n (mode !== 'escalate' ||\n identity === undefined ||\n identity === last.identity ||\n now - last.at < ESCALATE_AGAIN_MS);\n // Kept, not queued: under 'warn' and 'ignore', and for a repeat. The\n // revision does not show the field (ADR 0023).\n if (repeated || mode !== 'escalate') {\n state.display.shortfall(state.activeUpdate, { kind: 'unfaithful', field: target.fieldName });\n }\n if (repeated) return;\n state.reportedUnfaithful.set(target.element, { identity, at: now });\n if (last === undefined) {\n state.unfaithfulCount += 1;\n state.unfaithfulFields.add(target.fieldName);\n if (mode === 'ignore') return;\n if (mode === 'warn') {\n deps.warn(`[live-preview] LP0411: \"${target.fieldName}\" ${reason}`);\n return;\n }\n }\n deps.log('LP0411', target.fieldName, reason);\n state.unfaithfulPatches.push(target);\n}\n\n/**\n * Record a changed field the page has no binding for: the same judgement one\n * step earlier, where there is no element to write to and so nothing to queue.\n * The whole route is the only answer to it, and `StrategyRunner` asks for that\n * itself.\n *\n * Once per field name, for the reason LP0411 is once per element: the cause is\n * the markup, so the next keystroke into the same field would report the same\n * thing. Counted under every mode and on a page with no strategy at all —\n * that page is the one `inspect().fidelity` was written for, and it was the one\n * page the reading said nothing about.\n *\n * No message of its own: LP0203 (LP0201 when the value is empty) already names\n * the field, once, from the same rule. The return value says whether this was the first time, so an escalation\n * is counted against the findings it answered rather than against a keystroke.\n */\nexport function reportUnboundChange(state: RuntimeState, fieldName: string): boolean {\n if (state.unfaithfulFields.has(fieldName)) return false;\n state.unfaithfulFields.add(fieldName);\n state.unfaithfulCount += 1;\n return true;\n}\n\n/**\n * Renderers that turn a stored value into a presentation, so the template that\n * printed the same field had to choose one too. A `text` binding whose content\n * differs is an edit; a `date`, `number` or `checkbox` binding whose content\n * differs is two answers to the question the runtime cannot ask —\n * `data-payload-format` is where the answer belongs.\n */\nconst FORMATTING_RENDERERS: ReadonlySet<string> = new Set([\n 'date',\n 'number',\n 'checkbox',\n 'select',\n 'radio',\n]);\n\nfunction isOptionType(type: string): boolean {\n return type === 'select' || type === 'radio';\n}\n\n/** Cap on either reading in the message: a diagnostic is a pointer, not a dump. */\nconst EXCERPT = 40;\n\n/**\n * What the element shows, when a difference there would be worth reporting —\n * `undefined` when it would not, so an ordinary page pays one `Set` lookup per\n * binding and reads no DOM at all.\n *\n * Called before the renderer writes, and only for the first write to a\n * binding: after that the element holds the runtime's own output, and\n * comparing it with the runtime's next output says nothing about the template.\n */\nexport function watchServerFormatting(\n deps: RuntimeDeps,\n state: RuntimeState,\n target: CachedElement,\n type: string,\n): string | undefined {\n if (deps.onUnfaithfulPatch === 'ignore') return undefined;\n if (target.format !== undefined || !FORMATTING_RENDERERS.has(type)) return undefined;\n // A form control holds the value itself; only printed text can be a label.\n if (isOptionType(type) && target.element.matches('select,input')) return undefined;\n if (state.checkedServerFormat.has(target.element)) return undefined;\n state.checkedServerFormat.add(target.element);\n const shown = shownValue(target.element);\n // An empty anchor lost nothing, and the boundary case (LP0201) is elsewhere.\n return shown.trim().length > 0 ? shown : undefined;\n}\n\n/**\n * Called once the renderer has written: both readings of the same value now\n * exist, and if they differ the page no longer matches the server.\n *\n * It reports and stops there. Escalating would hand the region to the route,\n * which redraws the template's format, which the re-apply overwrites again —\n * measured under Z3 — so the honest move is to name the two candidates and the\n * attribute that settles either of them.\n */\nexport function reportServerFormatting(\n deps: RuntimeDeps,\n target: CachedElement,\n before: string,\n type: string,\n): void {\n const after = shownValue(target.element);\n if (after === before) return;\n deps.warn(\n `[live-preview] LP0412: \"${target.fieldName}\" showed ${excerpt(before)}, the patch wrote ` +\n `${excerpt(after)} — ` +\n (isOptionType(type)\n ? 'Payload sends the value of an option, not its label. Render the label in a ' +\n 'data-payload-fragment boundary, or bind it with data-payload-strategy=\"route\".'\n : 'either an edit that arrived before the preview connected, or a template that ' +\n 'formats this value differently. Set data-payload-format to match it.'),\n );\n}\n\n/** The channel the formatting renderers write. */\nfunction shownValue(element: Element): string {\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n return (element as HTMLInputElement).value;\n }\n return element.textContent;\n}\n\nfunction excerpt(value: string): string {\n const text = value.trim();\n return JSON.stringify(text.length > EXCERPT ? `${text.slice(0, EXCERPT)}…` : text);\n}\n","/**\n * Public renderer callbacks return `void`, but a JavaScript implementation may\n * return anything. Only callbacks marked here may reserve exact `false` as\n * \"no write\", so a custom renderer's incidental boolean cannot change the\n * lifecycle's applied counts.\n */\n\ntype Callback = (...args: never[]) => unknown;\n\nconst noWriteCallbacks = new WeakSet<Callback>();\n\n/** Mark a package-owned callback whose exact `false` return means no write. */\nexport function markNoWriteCallback<T extends Callback>(callback: T): T {\n noWriteCallbacks.add(callback);\n return callback;\n}\n\n/** Whether `callback` owns the internal exact-false sentinel contract. */\nexport function usesNoWriteOutcome(callback: Callback): boolean {\n return noWriteCallbacks.has(callback);\n}\n\n/** Check a renderer object without detaching its public method at the call site. */\nexport function rendererUsesNoWriteOutcome(renderer: { readonly render: Callback }): boolean {\n return noWriteCallbacks.has(renderer.render);\n}\n","/**\n * The one per-message diff of top-level field values. Strategies, dependency\n * invalidation and reveal all consume it, so \"changed\" means the same thing\n * everywhere.\n */\n\nimport type { DependencyMap } from './dependencies';\nimport { valueIdentity } from './value-identity';\n\nexport interface FieldChanges {\n /** Fields whose value differs from the previous message; every field on the first one. */\n readonly changed: ReadonlySet<string>;\n /** Dependents of changed fields, per the dependency map. */\n readonly invalidated: ReadonlySet<string>;\n /**\n * The first message of a connection, where `changed` means \"everything the\n * document has\" rather than \"what the editor just did\". A caller that acts on\n * a change rather than rendering one has to sit this message out.\n */\n readonly baseline: boolean;\n}\n\nexport class FieldChangeTracker {\n private previous: Map<string, string | undefined> | null = null;\n private lastFields: Readonly<Record<string, unknown>> | undefined;\n private priorFields: Readonly<Record<string, unknown>> | undefined;\n\n /**\n * Keep the message's values, not only their identities, so the one before\n * the last diff can be compared below the top level (ADR 0022). Off by\n * default: it holds one more document.\n */\n keepValues = false;\n\n /** The fields of the message before the last diff, while `keepValues` is on. */\n get previousFields(): Readonly<Record<string, unknown>> | undefined {\n return this.priorFields;\n }\n\n get isBaseline(): boolean {\n return this.previous === null;\n }\n\n /** Diff `fields` against the previous message and remember them for the next call. */\n diff(fields: Readonly<Record<string, unknown>>, dependencies: DependencyMap): FieldChanges;\n diff(\n fields: Readonly<Record<string, unknown>>,\n dependencies: DependencyMap,\n isCurrent: () => boolean,\n ): FieldChanges | null;\n diff(\n fields: Readonly<Record<string, unknown>>,\n dependencies: DependencyMap,\n isCurrent: () => boolean = alwaysCurrent,\n ): FieldChanges | null {\n const previous = this.previous;\n const baseline = previous === null;\n const next = new Map<string, string | undefined>();\n const changed = new Set<string>();\n const entries = Object.entries(fields);\n if (!isCurrent()) return null;\n for (const [name, value] of entries) {\n const identity = valueIdentity(value);\n if (!isCurrent()) return null;\n next.set(name, identity);\n // A value without an identity always counts as changed: rendering once\n // more is cheap, a stale binding is not.\n if (previous === null || identity === undefined || previous.get(name) !== identity) {\n changed.add(name);\n }\n }\n if (previous !== null) {\n for (const name of previous.keys()) if (!next.has(name)) changed.add(name);\n }\n const invalidated = new Set<string>();\n const dependencyEntries = Object.entries(dependencies);\n if (!isCurrent()) return null;\n for (const [source, dependents] of dependencyEntries) {\n if (!changed.has(source)) continue;\n for (const dependent of dependents) {\n invalidated.add(dependent);\n if (!isCurrent()) return null;\n }\n }\n if (!isCurrent()) return null;\n this.previous = next;\n this.priorFields = this.keepValues ? this.lastFields : undefined;\n this.lastFields = this.keepValues ? fields : undefined;\n return { changed, invalidated, baseline };\n }\n\n reset(): void {\n this.previous = null;\n this.lastFields = undefined;\n this.priorFields = undefined;\n }\n}\n\nfunction alwaysCurrent(): boolean {\n return true;\n}\n","/**\n * Field-path resolution for bindings and sibling-field metadata, prototype-safe,\n * and the identity of everything one binding renders — which is the same\n * question one step later, because the siblings are part of the answer.\n */\n\nimport type { CachedElement } from './types';\nimport { valueIdentity } from './value-identity';\n\nconst BLOCKED_KEYS: ReadonlySet<string> = new Set(['__proto__', 'prototype', 'constructor']);\n\n/**\n * Resolve a dotted field path, preferring a `_<locale>` suffix when one is\n * active. Prototype-chain properties and pollution-prone segments never resolve.\n */\nexport function resolveFieldValue(\n fields: Record<string, unknown>,\n path: string,\n locale: string | undefined,\n preferLocale = false,\n): unknown {\n if (preferLocale && locale !== undefined) {\n const localized = readOwn(fields, `${path}_${locale}`);\n if (localized !== undefined) return localized;\n }\n const direct = readOwn(fields, path);\n if (direct !== undefined) return direct;\n\n if (path.includes('.')) {\n let current: unknown = fields;\n let resolved = true;\n for (const segment of path.split('.')) {\n if (BLOCKED_KEYS.has(segment) || current === null || typeof current !== 'object') {\n resolved = false;\n break;\n }\n current = readOwn(current as Record<string, unknown>, segment);\n if (current === undefined) {\n resolved = false;\n break;\n }\n }\n if (resolved) return current;\n }\n\n return locale === undefined ? undefined : readOwn(fields, `${path}_${locale}`);\n}\n\nfunction readOwn(object: Record<string, unknown>, key: string): unknown {\n if (BLOCKED_KEYS.has(key) || !Object.prototype.hasOwnProperty.call(object, key)) {\n return undefined;\n }\n return object[key];\n}\n\n/**\n * The value a binding renders. A binding that names its own locale reads that\n * locale and nothing else; one that does not falls back to the message locale.\n */\nexport function bindingValue(\n fields: Record<string, unknown>,\n target: { readonly locale?: string | undefined },\n fieldName: string,\n fallbackLocale: string | undefined,\n): unknown {\n return resolveFieldValue(\n fields,\n fieldName,\n target.locale ?? fallbackLocale,\n target.locale !== undefined,\n );\n}\n\n/**\n * Identity of everything a binding renders: its value, any sibling\n * href/src/alt fields, and the format and locale the renderer writes it in.\n */\nexport function bindingIdentity(\n target: CachedElement,\n value: unknown,\n fields: Record<string, unknown>,\n locale: string | undefined,\n): string | undefined {\n const own = valueIdentity(value);\n if (own === undefined) return undefined;\n const siblings = [target.hrefField, target.srcField, target.altField];\n // The same 12.34 is a new write under `number:2` or `de-DE`. JSON keeps the\n // two apart from each other and from the value, whatever they contain.\n let combined = JSON.stringify([target.format, target.locale ?? locale]) + own;\n for (const sibling of siblings) {\n if (sibling === undefined || sibling.length === 0) continue;\n const resolved = bindingValue(fields, target, sibling, locale);\n const identity = valueIdentity(resolved);\n if (identity === undefined) return undefined;\n combined += `|${sibling}=${identity}`;\n }\n return combined;\n}\n","/**\n * How a bound region is brought up to date: the runtime patches it, a server\n * renders a `data-payload-fragment` boundary from the unsaved form state, or\n * the whole route refreshes. Core carries only the seam — which boundaries a\n * strategy owns and what it may do — so a patch-only page pays for nothing\n * more; the orchestration lives in `payload-live-preview/fragment`.\n */\nimport type { DiagnosticCode } from './diagnostic-codes';\nimport type { CachedElement } from './types';\nimport type { OwnerScope } from './unbound-fields';\n\n/** What produced an update: the runtime's DOM patching, a server-rendered fragment, or a route refresh. */\nexport type UpdateSource = 'patch' | 'fragment' | 'route';\n\n/** Marks a server-rendered boundary; the value is the registry id the server may render. @internal */\nexport const FRAGMENT_ATTRIBUTE = 'data-payload-fragment';\n/** Distinguishes several boundaries of one registry id; unique among siblings. @internal */\nexport const FRAGMENT_KEY_ATTRIBUTE = 'data-payload-fragment-key';\n\n/** The nearest fragment boundary enclosing `element` (the element itself included). */\nexport function enclosingFragment(element: Element): Element | null {\n return element.closest(`[${FRAGMENT_ATTRIBUTE}]`);\n}\n\n/**\n * Where a render planned for `planned` lands. A host component that re-renders\n * its region while the render is in flight swaps the element and keeps the\n * identity, so a boundary no longer in the document stands for the one that\n * is: the single connected boundary with its id and key that `inScope` admits.\n * Two candidates name no single region, and none means it is gone (H06).\n */\nexport function liveBoundary(\n root: Document | Element,\n planned: Element,\n inScope: (boundary: Element) => boolean,\n): Element | undefined {\n if (planned.isConnected) return planned;\n const id = planned.getAttribute(FRAGMENT_ATTRIBUTE);\n const key = planned.getAttribute(FRAGMENT_KEY_ATTRIBUTE);\n let found: Element | undefined;\n for (const candidate of root.querySelectorAll(`[${FRAGMENT_ATTRIBUTE}]`)) {\n if (candidate.getAttribute(FRAGMENT_ATTRIBUTE) !== id) continue;\n if (candidate.getAttribute(FRAGMENT_KEY_ATTRIBUTE) !== key || !inScope(candidate)) continue;\n if (found !== undefined) return undefined;\n found = candidate;\n }\n return found;\n}\n\n/** One revision, as a strategy sees it, with the runtime capabilities it may use. */\nexport interface FragmentContext {\n readonly root: ParentNode;\n readonly revision: number;\n readonly receivedAt: number;\n readonly fields: Readonly<Record<string, unknown>>;\n readonly locale: string | undefined;\n readonly collectionSlug: string | undefined;\n readonly globalSlug: string | undefined;\n /** Aborted when a newer revision arrives or the runtime stops. */\n readonly signal: AbortSignal;\n /** Whether this revision is still the current one. */\n readonly isCurrent: () => boolean;\n /** Morph server-rendered HTML into a boundary; no-op after supersession (Trusted Types and the keyed morph apply). */\n readonly morph: (boundary: Element, html: string) => void;\n /** Patch the boundary's owned bindings from this revision; no-op after supersession. */\n readonly patch: (boundary: Element) => void;\n /** Debug log through the runtime's logger, with the diagnostic code. */\n readonly log: (code: DiagnosticCode, detail: string) => void;\n /** Report a boundary rendered. */\n readonly rendered: (boundary: Element, id: string, key: string | undefined) => void;\n /** Report a boundary failed and patched instead; emits the `error` and `fragmentRender` events. */\n readonly failed: (\n boundary: Element,\n id: string,\n key: string | undefined,\n code: DiagnosticCode,\n reason: string,\n ) => void;\n}\n\nexport interface FragmentReport {\n readonly rendered: number;\n readonly failed: number;\n readonly superseded: number;\n}\n\n/** A fragment strategy: which boundaries it owns for a revision, and how it renders them. */\nexport interface FragmentStrategy {\n /** The boundaries this update re-renders; their inner bindings are left to the strategy. */\n readonly plan: (root: ParentNode, changedFields: ReadonlySet<string>) => readonly Element[];\n /** Render the planned boundaries; resolves once every one settled. */\n readonly render: (\n context: FragmentContext,\n boundaries: readonly Element[],\n ) => Promise<FragmentReport>;\n}\n\n/** The boundaries a revision hands the fragment strategy, and the bindings they take from the patch. */\nexport interface FragmentPlan {\n readonly boundaries: readonly Element[];\n readonly strategy: FragmentStrategy;\n readonly ownerKeys: OwnerScope;\n /** Whether a binding sits inside a boundary the strategy renders this revision. */\n readonly covers: (target: CachedElement) => boolean;\n}\n\n/** A plan over boundaries already chosen, whichever question chose them. */\nexport function planBoundaries(\n strategy: FragmentStrategy,\n boundaries: readonly Element[],\n ownerKeys: OwnerScope,\n): FragmentPlan {\n const covered = new Set(boundaries);\n return {\n boundaries,\n strategy,\n ownerKeys,\n covers: (target) =>\n target.fragmentBoundary !== undefined && covered.has(target.fragmentBoundary),\n };\n}\n\n/** One revision, as the route strategy sees it. */\nexport interface RouteContext {\n readonly revision: number;\n readonly receivedAt: number;\n /** Aborted when a newer revision asks for a refresh of its own, a navigation commits, or the runtime stops. */\n readonly signal: AbortSignal;\n /**\n * Whether the refresh may still land. A newer revision that asks for no\n * refresh of its own does not end it: the route is the server's, so the\n * refresh lands for that revision, which the runtime then re-applies.\n */\n readonly isCurrent: () => boolean;\n readonly log: (code: DiagnosticCode, detail: string) => void;\n /**\n * Ask to be run again in `delayMs`, once. A strategy that refuses a refresh\n * because it is rate-limiting itself uses this: the window is a rate limit\n * and not a filter, so what falls inside it still has to reach the preview.\n * The runtime runs at most one such request, and only while the revision that\n * asked is still the current one.\n */\n readonly retryAfter?: (delayMs: number) => void;\n}\n\n/**\n * What one refresh did. `refreshed` asserts that the strategy rendered the\n * current unsaved revision. `partial` completed a render whose data source was\n * not proven current; the runtime still reapplies every binding it can reach.\n * `refused` is the strategy's own brake and not a failure.\n */\nexport type RouteOutcome = 'refreshed' | 'partial' | 'failed' | 'refused' | 'superseded';\n\n/** What the runtime tells a route planner about the update it plans for. */\nexport interface RoutePlanContext {\n /**\n * Whether an element belongs to the update: always `true` without\n * `scopeBindingsByOwner`, otherwise only inside the document the update\n * names. A marker outside it asks for nothing.\n */\n readonly inScope: (element: Element) => boolean;\n}\n\n/**\n * Whether a revision needs the whole route re-rendered, and how. After a\n * refresh the runtime rescans and re-applies the revision, so reachable\n * unsaved bindings land on the fresh markup. The runtime always passes\n * `context`; a planner written before it existed still works, but plans for\n * markers of every document.\n */\nexport interface RouteStrategy {\n readonly plan: (\n root: ParentNode,\n changedFields: ReadonlySet<string>,\n context?: RoutePlanContext,\n ) => boolean;\n readonly refresh: (context: RouteContext) => Promise<RouteOutcome>;\n}\n\nexport interface StrategyHandlers {\n readonly fragment?: FragmentStrategy;\n readonly route?: RouteStrategy;\n}\n\nconst STRATEGY_ATTRIBUTE = 'data-payload-strategy';\n\n/**\n * Explicit `data-payload-strategy` wins; otherwise a binding inside a fragment\n * boundary belongs to the fragment, one in `<head>` to the route, the rest is\n * patched. An unknown explicit value resolves to `undefined` (LP0407).\n * @internal\n */\nexport function resolveStrategy(element: Element): UpdateSource | undefined {\n const explicit = element.getAttribute(STRATEGY_ATTRIBUTE);\n if (explicit !== null && explicit.length > 0) {\n return explicit === 'patch' || explicit === 'fragment' || explicit === 'route'\n ? explicit\n : undefined;\n }\n if (enclosingFragment(element) !== null) return 'fragment';\n if (element.closest('head') !== null) return 'route';\n return 'patch';\n}\n","/**\n * Document ownership for bindings. A field name alone cannot identify a\n * binding on a page that previews several documents — `title` may belong to a\n * global, to shared SEO metadata and to every card at once. An owner marker\n * names the document a subtree belongs to, as a plain comparable string:\n * `global:<slug>`, `collection:<slug>`, `collection:<slug>:<id>`.\n */\n\n/** Identity of the document an incoming message describes. */\nexport interface MessageDocumentIdentity {\n readonly globalSlug?: string | undefined;\n readonly collectionSlug?: string | undefined;\n /** Primary key of the edited document, when the payload carries one. */\n readonly documentId?: string | undefined;\n}\n\n/** Owner key naming one Payload global. */\nexport function globalOwnerKey(slug: string): string {\n return `global:${slug}`;\n}\n\n/** Owner key for a collection; without an id it claims every document of it. */\nexport function collectionOwnerKey(slug: string, documentId?: string): string {\n return documentId === undefined || documentId === ''\n ? `collection:${slug}`\n : `collection:${slug}:${documentId}`;\n}\n\nfunction nonEmpty(value: string | undefined): value is string {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * Owner keys this message may address, or `null` when it carries no usable\n * identity — the runtime treats that as fail-closed rather than guessing. A\n * marker naming an id stays unreachable while the id is unknown: an unproven\n * identity must not satisfy an exact claim.\n */\nexport function messageOwnerKeys(identity: MessageDocumentIdentity): readonly string[] | null {\n if (nonEmpty(identity.globalSlug)) return [globalOwnerKey(identity.globalSlug)];\n if (!nonEmpty(identity.collectionSlug)) return null;\n const collectionKey = collectionOwnerKey(identity.collectionSlug);\n return nonEmpty(identity.documentId)\n ? [collectionKey, collectionOwnerKey(identity.collectionSlug, identity.documentId)]\n : [collectionKey];\n}\n\n/** Whether a binding may receive an update addressed to `keys`; an unowned binding never may. */\nexport function isBindingInScope(\n owner: string | undefined,\n keys: readonly string[] | null,\n): boolean {\n if (keys === null || owner === undefined) return false;\n return keys.includes(owner);\n}\n\n/** The document id Payload sends alongside the edited values; only scalars prove an identity. */\nexport function readDocumentId(fields: Record<string, unknown>): string | undefined {\n const id: unknown = fields['id'];\n if (typeof id === 'string' && id.length > 0) return id;\n if (typeof id === 'number' && Number.isFinite(id)) return String(id);\n return undefined;\n}\n","/**\n * Which paths below a group changed without anything on the page to show\n * them (ADR 0022). The diff names top-level fields; under\n * `subfieldCoverage: 'declared'` a group covered only through its descendants\n * is compared with the previous message path by path, and a changed path\n * needs its own binding or a declared cover. A document a merge populated and\n * the id it replaced are the same value: population is not an edit.\n */\n\nimport { valueIdentity } from './value-identity';\n\nexport type SubfieldCoverage = 'descendant' | 'declared';\n\n/** Deeper than this, what is left counts as one changed path. */\nexport const SUBFIELD_DEPTH_LIMIT = 8;\n/** Nodes compared per field before the rest counts as one changed path. */\nexport const SUBFIELD_VISIT_LIMIT = 1024;\n\n/** What the page offers for a path; built once per update from the cache and the owner scope. */\nexport interface PathCoverage {\n /** A binding on the path, or a cover on it or on an ancestor. */\n readonly covers: (path: string) => boolean;\n /** A binding or a cover somewhere below the path. */\n readonly reachesBelow: (path: string) => boolean;\n}\n\nexport interface UncoveredPath {\n readonly path: string;\n /** The current value there, `undefined` where the path was removed. */\n readonly value: unknown;\n}\n\nfunction isContainer(value: unknown): value is Record<string, unknown> | readonly unknown[] {\n return typeof value === 'object' && value !== null;\n}\n\nfunction shapeOf(value: unknown): 'array' | 'object' | 'scalar' {\n if (Array.isArray(value)) return 'array';\n return isContainer(value) ? 'object' : 'scalar';\n}\n\n/** The keys to compare below a container: the new ones, and any the previous value had. */\nfunction childKeys(\n previous: unknown,\n next: Record<string, unknown> | readonly unknown[],\n): string[] {\n const keys = new Set(Object.keys(next));\n if (isContainer(previous)) for (const key of Object.keys(previous)) keys.add(key);\n return [...keys];\n}\n\nfunction child(value: unknown, key: string): unknown {\n return isContainer(value) ? (value as Record<string, unknown>)[key] : undefined;\n}\n\n/** Whether `document` is what a merge puts where the message has the bare `id`. */\nfunction populates(document: unknown, id: unknown): boolean {\n return (\n (typeof id === 'string' || typeof id === 'number') &&\n isContainer(document) &&\n !Array.isArray(document) &&\n (document as Record<string, unknown>)['id'] === id\n );\n}\n\n/**\n * Whether two values differ only in what the server populated: the same shape\n * all the way down, except that one holds a document where the other holds its\n * id. The admin posts a relationship or an upload as its id in every message\n * and the merge answers with the document, so a revision rendered before the\n * answer and the one after it meet both forms of one value.\n */\nfunction samePopulation(before: unknown, after: unknown): boolean {\n if (!isContainer(before) || !isContainer(after)) {\n return (\n populates(before, after) ||\n populates(after, before) ||\n valueIdentity(before) === valueIdentity(after)\n );\n }\n if (Array.isArray(before) !== Array.isArray(after)) return false;\n const keys = Object.keys(after);\n if (keys.length !== Object.keys(before).length) return false;\n return keys.every(\n (key) => Object.hasOwn(before, key) && samePopulation(child(before, key), child(after, key)),\n );\n}\n\n/**\n * Whether the two values are one: equal, or equal but for population. An id\n * and its document are told apart without a walk, whatever the document's\n * size. The walk itself needs an identity on both sides, which bounds it by\n * the identity's size limit and keeps it out of a cycle; a value without one\n * counts as changed, as it does for the top-level diff.\n */\nfunction sameValue(before: unknown, after: unknown): boolean {\n const identity = valueIdentity(after);\n const previous = valueIdentity(before);\n if (identity !== undefined && identity === previous) return true;\n if (populates(before, after) || populates(after, before)) return true;\n return identity !== undefined && previous !== undefined && samePopulation(before, after);\n}\n\n/**\n * Whether the value at a dotted path changed between two messages, by the\n * rule the walk below applies. A route-bound element names such a path\n * (`layout.1.note`) while the diff names only its field.\n */\nexport function pathChanged(\n path: string,\n previous: Readonly<Record<string, unknown>>,\n next: Readonly<Record<string, unknown>>,\n): boolean {\n let before: unknown = previous;\n let after: unknown = next;\n for (const key of path.split('.')) {\n before = child(before, key);\n after = child(after, key);\n }\n return !sameValue(before, after);\n}\n\n/**\n * The changed paths below `field` that nothing covers, as the largest\n * uncovered subtrees: a path with nothing bound or covered beneath it is\n * reported whole rather than leaf by leaf. `previous` is `undefined` for a\n * document read without a diff, which makes every path \"changed\".\n */\nexport function uncoveredChangedPaths(\n field: string,\n previous: unknown,\n next: unknown,\n coverage: PathCoverage,\n): UncoveredPath[] {\n const uncovered: UncoveredPath[] = [];\n let visits = 0;\n const visit = (path: string, before: unknown, after: unknown, depth: number): void => {\n visits += 1;\n if (coverage.covers(path) || sameValue(before, after)) return;\n // A path that changed shape — a group that became a scalar, went away or\n // replaced one — changed as a whole, whatever is covered inside it. Without\n // a previous message (`undefined`) there is no shape to compare.\n const reshaped = before !== undefined && shapeOf(before) !== shapeOf(after);\n const descend =\n !reshaped &&\n isContainer(after) &&\n coverage.reachesBelow(path) &&\n depth < SUBFIELD_DEPTH_LIMIT;\n if (!descend) {\n uncovered.push({ path, value: after });\n return;\n }\n const keys = childKeys(before, after);\n // A new, empty group: nothing inside to compare, so the node itself changed.\n if (keys.length === 0) uncovered.push({ path, value: after });\n for (const key of keys) {\n // Out of budget: this node stands for whatever of it is left unvisited.\n if (visits >= SUBFIELD_VISIT_LIMIT) {\n uncovered.push({ path, value: after });\n return;\n }\n visit(`${path}.${key}`, child(before, key), child(after, key), depth + 1);\n }\n };\n visit(field, previous, next, 0);\n return uncovered;\n}\n","/**\n * Whether an incoming field has somewhere on the page to land.\n *\n * Two callers ask, for different reasons: LP0201 reports a field that never\n * has an anchor, and `onUnfaithfulPatch` decides whether a revision needs the\n * whole route. They have to answer the same way, so the lookup lives here\n * rather than in either of them — the locale suffix Payload appends, the owner\n * scope, and the fact that the diff names top-level fields while a binding may\n * name a path inside one.\n */\n\nimport { isBindingInScope } from './binding-owner';\nimport type { ElementCache } from './cache';\nimport {\n pathChanged,\n uncoveredChangedPaths,\n type PathCoverage,\n type SubfieldCoverage,\n type UncoveredPath,\n} from './subfield-coverage';\n\n/** Document fields Payload ships in every update that nobody binds to. */\nexport const SYSTEM_FIELD_NAMES: ReadonlySet<string> = new Set([\n 'id',\n '_id',\n 'createdAt',\n 'updatedAt',\n 'createdBy',\n 'updatedBy',\n '_status',\n 'globalType',\n 'collection',\n 'locale',\n 'localized',\n]);\n\n/** Owner keys as the update resolved them; `false` means scoping is off. */\nexport type OwnerScope = readonly string[] | null | false;\n\n/** Answers for one update; the locale index behind it is built at most once. */\nexport type FieldAddressability = (fieldName: string) => boolean;\n\n/**\n * `field_locale` names an element-local locale may consume while the message\n * locale differs, so those bindings are addressable under their suffixed name.\n */\nfunction localisedBindingNames(cache: ElementCache, ownerKeys: OwnerScope): Set<string> {\n const names = new Set<string>();\n for (const [fieldName, bindings] of cache.entries()) {\n for (const binding of bindings) {\n if (ownerKeys !== false && !isBindingInScope(binding.owner, ownerKeys)) continue;\n if (binding.locale !== undefined) names.add(`${fieldName}_${binding.locale}`);\n }\n }\n return names;\n}\n\n/**\n * A binding on a path inside the field — `hero.eyebrow` for the field `hero` —\n * makes it addressable. The diff names top-level fields only, so without this\n * every group and array on the page would look unbound.\n */\nexport function hasBindingBelow(\n cache: ElementCache,\n fieldName: string,\n ownerKeys: OwnerScope,\n): boolean {\n const prefix = `${fieldName}.`;\n for (const [boundName, bindings] of cache.entries()) {\n if (!boundName.startsWith(prefix)) continue;\n if (ownerKeys === false) return true;\n if (bindings.some((binding) => isBindingInScope(binding.owner, ownerKeys))) return true;\n }\n return false;\n}\n\n/** The strategies configured for this page; only they render what a boundary or marker depends on. */\nexport interface ServerRendering {\n readonly fragment?: unknown;\n readonly route?: unknown;\n}\n\n/**\n * The page's answer for any path in one update's owner scope: the bound names,\n * the declared covers (ADR 0022) and the fields a boundary or route marker\n * depends on when its strategy is configured, read once, then the same name\n * rule the overlay applies.\n */\nexport function createPathCoverage(\n cache: ElementCache,\n ownerKeys: OwnerScope,\n rendering: ServerRendering = {},\n): PathCoverage {\n const inScope = (owner: string | undefined): boolean =>\n ownerKeys === false || isBindingInScope(owner, ownerKeys);\n const names: string[] = [];\n for (const [fieldName, bindings] of cache.entries()) {\n if (bindings.some((binding) => inScope(binding.owner))) names.push(fieldName);\n }\n const rendered = cache.rendered.filter(\n (declaration) => rendering[declaration.strategy] !== undefined,\n );\n const covers = [...cache.covers, ...rendered]\n .filter((cover) => inScope(cover.owner))\n .flatMap((cover) => cover.paths);\n return namePathCoverage(names, covers);\n}\n\nexport function stripLocaleSuffix(name: string, locale: string | undefined): string {\n if (locale === undefined || locale.length === 0) return name;\n const suffix = `_${locale}`;\n return name.endsWith(suffix) ? name.slice(0, -suffix.length) : name;\n}\n\n/** Whether any binding on the page belongs to the document this update carries. */\nexport function ownsAnyBinding(cache: ElementCache, ownerKeys: readonly string[] | null): boolean {\n for (const binding of cache.values()) {\n if (isBindingInScope(binding.owner, ownerKeys)) return true;\n }\n return false;\n}\n\n/**\n * The same rule for a caller that has names rather than the cache: the\n * `data-payload-field` values in a document, which is all a plugin can see\n * (`src/plugins/built-in/unbound-fields-overlay.ts`).\n *\n * It answers the first three of the four questions below — exact name, the\n * locale-stripped base, a binding on a path inside the field. The fourth needs\n * each binding's own `data-payload-locale`, which is a property of the element\n * rather than of its name, so a caller with names alone cannot ask it.\n */\nexport function createNameAddressability(\n boundNames: Iterable<string>,\n locale: string | undefined,\n coverPaths: Iterable<string>,\n): FieldAddressability {\n const coverage = namePathCoverage(boundNames, coverPaths);\n const reaches = (name: string): boolean => coverage.covers(name) || coverage.reachesBelow(name);\n return (fieldName) => {\n if (reaches(fieldName)) return true;\n const base = stripLocaleSuffix(fieldName, locale);\n return base !== fieldName && reaches(base);\n };\n}\n\n/** Coverage from names alone: the bound names and the declared cover paths in a document. */\nfunction namePathCoverage(\n boundNames: Iterable<string>,\n coverPaths: Iterable<string>,\n): PathCoverage {\n const names = new Set(boundNames);\n const covers = [...coverPaths];\n const anyBelow = (candidates: Iterable<string>, path: string): boolean => {\n const prefix = `${path}.`;\n for (const candidate of candidates) if (candidate.startsWith(prefix)) return true;\n return false;\n };\n return {\n covers: (path) =>\n names.has(path) || covers.some((cover) => cover === path || path.startsWith(`${cover}.`)),\n reachesBelow: (path) => anyBelow(names, path) || anyBelow(covers, path),\n };\n}\n\n/**\n * The declared mode for a caller with names (the overlay): the uncovered paths\n * inside the groups the document reaches only below the top level.\n */\nexport function uncoveredNamePaths(\n fields: Readonly<Record<string, unknown>>,\n boundNames: Iterable<string>,\n locale: string | undefined,\n coverPaths: Iterable<string>,\n): string[] {\n const coverage = namePathCoverage(boundNames, coverPaths);\n const found: string[] = [];\n for (const [fieldName, value] of Object.entries(fields)) {\n if (SYSTEM_FIELD_NAMES.has(fieldName)) continue;\n const root = stripLocaleSuffix(fieldName, locale);\n if (coverage.covers(root) || !coverage.reachesBelow(root)) continue;\n for (const { path } of uncoveredChangedPaths(root, undefined, value, coverage)) {\n found.push(path);\n }\n }\n return found;\n}\n\n/**\n * The predicate for one update. The localised index is built on first use:\n * most fields are answered by the two cheap lookups before it.\n */\nexport function createFieldAddressability(\n cache: ElementCache,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n rendering?: ServerRendering,\n): FieldAddressability {\n const coverage = createPathCoverage(cache, ownerKeys, rendering);\n const reach = createFieldReach(cache, locale, ownerKeys, coverage);\n return (fieldName) => reach(fieldName) !== 'none';\n}\n\n/**\n * How far the page reaches into a field: `whole` when a binding or a cover\n * sits on it, `below` when only paths inside it are bound or covered — the\n * case ADR 0022's declared mode looks into — and `none`.\n */\nfunction createFieldReach(\n cache: ElementCache,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n coverage: PathCoverage = createPathCoverage(cache, ownerKeys),\n): (fieldName: string) => 'whole' | 'below' | 'none' {\n let localised: Set<string> | undefined;\n const whole = coverage.covers;\n const below = coverage.reachesBelow;\n return (fieldName) => {\n const base = stripLocaleSuffix(fieldName, locale);\n if (whole(fieldName) || (base !== fieldName && whole(base))) return 'whole';\n localised ??= localisedBindingNames(cache, ownerKeys);\n if (localised.has(fieldName)) return 'whole';\n if (below(fieldName) || (base !== fieldName && below(base))) return 'below';\n return 'none';\n };\n}\n\n/** The previous and current message, when the declared mode compares below the top level. */\nexport interface SubfieldValues {\n readonly previous: Readonly<Record<string, unknown>>;\n readonly next: Readonly<Record<string, unknown>>;\n}\n\n/**\n * The declared mode asked of a document rather than a diff, for LP0203: the\n * uncovered paths inside the groups the page reaches only below the top level.\n */\nexport function uncoveredDocumentPaths(\n cache: ElementCache,\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n rendering?: ServerRendering,\n): UncoveredPath[] {\n const coverage = createPathCoverage(cache, ownerKeys, rendering);\n const reach = createFieldReach(cache, locale, ownerKeys, coverage);\n const found: UncoveredPath[] = [];\n for (const [fieldName, value] of Object.entries(fields)) {\n if (SYSTEM_FIELD_NAMES.has(fieldName) || reach(fieldName) !== 'below') continue;\n const root = stripLocaleSuffix(fieldName, locale);\n found.push(...uncoveredChangedPaths(root, undefined, value, coverage));\n }\n return found;\n}\n\n/** What the declared mode compares for one revision, or `undefined` where it does not apply. */\nexport function declaredSubfields(\n mode: SubfieldCoverage,\n previous: Readonly<Record<string, unknown>> | undefined,\n next: Readonly<Record<string, unknown>> | undefined,\n): SubfieldValues | undefined {\n return mode === 'declared' && previous !== undefined && next !== undefined\n ? { previous, next }\n : undefined;\n}\n\n/**\n * `touched` with the paths inside its fields that route-bound elements name and\n * that changed, for the route planners: a marker on `layout.1.note` asks about\n * that path while the diff names `layout`. Without the previous message, which\n * only the declared mode keeps, a path changes with its field.\n */\nexport function routeTouched(\n cache: ElementCache,\n touched: ReadonlySet<string>,\n subfields?: SubfieldValues,\n): ReadonlySet<string> {\n const named = cache.rendered.flatMap((declaration) =>\n declaration.strategy === 'route' ? declaration.paths : [],\n );\n for (const [fieldName, bindings] of cache.entries()) {\n if (bindings.some((binding) => binding.strategyKind === 'route')) named.push(fieldName);\n }\n const changed = new Set(touched);\n for (const path of named) {\n const [field = path] = path.split('.');\n if (!touched.has(field)) continue;\n if (subfields === undefined || pathChanged(path, subfields.previous, subfields.next)) {\n changed.add(path);\n }\n }\n return changed;\n}\n\n/**\n * The fields a revision changed that the page has nowhere to put: the rule\n * above, asked of a diff instead of a document. Both profiles ask it — the full\n * one to decide whether the whole route is the only honest answer, the lean one\n * because the finding is worth recording even where nothing can act on it — so\n * it stands here, beside the rule it is made of, rather than in either runner.\n */\nexport function unboundChangedFields(\n cache: ElementCache,\n touched: ReadonlySet<string>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n subfields?: SubfieldValues,\n rendering?: ServerRendering,\n): string[] {\n const coverage = createPathCoverage(cache, ownerKeys, rendering);\n const reach = createFieldReach(cache, locale, ownerKeys, coverage);\n const unbound: string[] = [];\n for (const fieldName of touched) {\n if (SYSTEM_FIELD_NAMES.has(fieldName)) continue;\n const kind = reach(fieldName);\n if (kind === 'none') unbound.push(fieldName);\n if (kind !== 'below' || subfields === undefined) continue;\n const root = stripLocaleSuffix(fieldName, locale);\n const { previous, next } = subfields;\n for (const { path } of uncoveredChangedPaths(\n root,\n previous[fieldName],\n next[fieldName],\n coverage,\n )) {\n unbound.push(path);\n }\n }\n return unbound;\n}\n","/**\n * Whether an accepted message has to be resolved against the server before the\n * page can render it, and how many round trips a burst of them may cost. The\n * merge exists to populate relationships and uploads, so a page that renders\n * none of them needs no request at all. A message in the same locale that moved\n * no populated field is answered from its own values over what the last merge\n * resolved, and what is left goes out once at the start of a burst and once at\n * its end.\n *\n * Conservative in one direction on purpose: a request left out that was needed\n * puts an id where a name belongs and leaves it there, while one request too\n * many costs a round trip nobody sees.\n */\n\nimport { lookupSchema, type SchemaIndex } from '@schema/index';\nimport type { ElementCache } from './cache';\nimport type { DataMerger, MergeRequest, MergeResult } from './data-merger';\nimport type { DependencyMap } from './dependencies';\nimport { looksLikeLexicalRoot } from './binding-writer';\nimport { bindingValue } from './field-value';\nimport { FieldChangeTracker } from './field-changes';\nimport type { RuntimeDeps, UpdateTransaction } from './runtime-state';\nimport { FRAGMENT_ATTRIBUTE } from './strategies';\nimport { hasBindingBelow, SYSTEM_FIELD_NAMES } from './unbound-fields';\n\n/**\n * Renderer keys and Payload types whose value the panel posts complete: a\n * scalar, with nothing inside it and nothing behind it to resolve. One\n * vocabulary answers both questions asked here — whether a page reads anything\n * the server populates, and whether one field does — because they are the same\n * question about a binding and about a value.\n */\nconst SELF_SUFFICIENT_TYPES: ReadonlySet<string> = new Set([\n 'text',\n 'textarea',\n 'email',\n 'number',\n 'checkbox',\n 'date',\n 'select',\n 'radio',\n 'point',\n 'code',\n 'json',\n 'ui',\n 'html',\n]);\n\n/**\n * Lexical nodes whose whole content is in the message. Anything else — an\n * upload, a relationship, a block, a node this package does not know — may name\n * a document the server fills in, and so may a link whose target is one.\n */\nconst SELF_SUFFICIENT_NODES: ReadonlySet<string> = new Set([\n 'root',\n 'paragraph',\n 'text',\n 'heading',\n 'quote',\n 'list',\n 'listitem',\n 'linebreak',\n 'tab',\n 'horizontalrule',\n 'code',\n 'code-highlight',\n 'table',\n 'tablerow',\n 'tablecell',\n 'link',\n 'autolink',\n]);\n\n/** The raw diff answers \"what did the editor move\", which no dependency map changes. */\nconst NO_DEPENDENCIES: DependencyMap = {};\n\nexport interface MergePlan {\n /** Whether the server can still add something to these values. */\n readonly merge: boolean;\n /** The best document without it: this message's own values over the last resolved one. */\n readonly fields: Record<string, unknown>;\n}\n\nexport interface CoalescedMerge {\n /** Whether the request went out now. A deferred one lands after the window and refines what was rendered. */\n readonly leading: boolean;\n readonly result: Promise<MergeResult>;\n}\n\ninterface PendingMerge {\n readonly promise: Promise<MergeResult>;\n readonly settle: (result: MergeResult) => void;\n}\n\ninterface TrailingMerge {\n readonly request: MergeRequest;\n readonly pending: PendingMerge;\n timer: ReturnType<typeof setTimeout> | null;\n}\n\nexport class MergeNeed {\n /** Raw fields last considered for population, without confusing edits with server-added values. */\n private readonly rawChanges = new FieldChangeTracker();\n private resolved: Record<string, unknown> | null = null;\n /** Null leaves required population unresolved; undefined is the resolved default locale. */\n private resolvedLocale: string | undefined | null = null;\n private trailing: TrailingMerge | null = null;\n private openUntil = 0;\n private requestAttempt = 0;\n\n /**\n * The decision, in the order the audit found the ways to get it wrong.\n *\n * 1. **Nothing on the page reads a populated value**, either because nobody\n * reads anything (LP-4) or because every binding renders a plain scalar.\n * See `readsPopulatedValues`. A binding that declares no type and holds\n * rich text naming a document is not plain, whatever its element says:\n * see `rendersRichTextByShape`.\n * 2. **Nothing populated moved** (LP-3): the fields the editor changed are\n * scalars that name no document, so they are taken from the message and\n * the rest is carried over from what the last merge resolved. Typing a\n * title costs nothing.\n *\n * What is left needs the server. It still renders at once — from the same\n * carried-over document — so the answer is not what the page waits for;\n * `request()` decides how often it is actually asked.\n */\n decide(deps: RuntimeDeps, transaction: UpdateTransaction): MergePlan {\n const raw = transaction.rawData;\n if (\n !readsPopulatedValues(deps) &&\n !rendersRichTextByShape(deps.cache, raw, transaction.locale)\n ) {\n if (transaction.forceRender) this.resolvedLocale = null;\n return { merge: false, fields: raw };\n }\n // Unobserved edits still need comparison when a population consumer returns.\n const { changed } = this.rawChanges.diff(raw, NO_DEPENDENCIES);\n // Population depends on the accepted locale even when relationship IDs stay\n // put. A page with no population consumer leaves the retained context alone.\n const localeChanged = this.resolvedLocale !== transaction.locale;\n const base = this.resolved;\n // The first message has nothing to carry over, so it buys the document once.\n if (base === null) {\n this.resolved = raw;\n return { merge: true, fields: raw };\n }\n const fields: Record<string, unknown> = { ...base };\n // A related save (LP-1) or an accepted locale change can alter population\n // without moving a relationship ID in the raw form values.\n if (transaction.forceRender) this.resolvedLocale = null;\n let merge = transaction.forceRender || localeChanged;\n for (const field of changed) {\n const value = raw[field];\n if (SYSTEM_FIELD_NAMES.has(field)) {\n fields[field] = value;\n continue;\n }\n const verdict = verdictFor(field, base[field], value, deps.cache, transaction.schemaIndex);\n if (verdict !== 'own') {\n merge = true;\n this.resolvedLocale = null;\n }\n if (verdict !== 'keep') fields[field] = value;\n }\n this.resolved = fields;\n return { merge, fields };\n }\n\n /**\n * One request goes out now and the rest of a burst share the one that follows\n * its last message. The abort stays where it was: `DataMerger` still drops an\n * answer a newer request superseded, and what changes here is only how often\n * it is asked.\n *\n * The window is the scheduler's debounce, because it is the same burst: the\n * writes of one are coalesced into a single flush, and this is the request\n * behind them. A page that turns the debounce off turns this off with it.\n */\n request(merger: DataMerger, windowMs: number, request: MergeRequest): CoalescedMerge {\n const attempt = ++this.requestAttempt;\n const now = Date.now();\n if (now >= this.openUntil) {\n // The clock has closed the window, but its timer may not have run: a busy\n // main thread or a throttled engine fires it late. Left queued, that older\n // request would go out after this one, and `DataMerger` — which keeps the\n // newest request — would drop this keystroke's answer; measured in WebKit\n // as a preview one keystroke behind. This request carries the newer values.\n this.openUntil = now + windowMs;\n this.dropQueued();\n // Cancellation can accept newer work before this leading request dispatches.\n if (this.requestAttempt !== attempt) {\n return { leading: true, result: Promise.resolve({ status: 'superseded' }) };\n }\n return { leading: true, result: merger.merge(request) };\n }\n const previous = this.trailing;\n const pending = previous?.pending ?? createPending();\n const trailing: TrailingMerge = { request, pending, timer: null };\n this.trailing = trailing;\n this.openUntil = now + windowMs;\n if (previous !== null && previous.timer !== null) clearTimeout(previous.timer);\n if (this.trailing !== trailing) return { leading: false, result: pending.promise };\n const timer = setTimeout(() => {\n this.flush(merger, trailing);\n }, windowMs);\n if (this.trailing === trailing) trailing.timer = timer;\n else clearTimeout(timer);\n return { leading: false, result: pending.promise };\n }\n\n /** The server's document replaces what was carried over; the next message builds on it. */\n recordMerged(doc: Record<string, unknown>, locale?: string): void {\n this.resolved = doc;\n this.resolvedLocale = locale;\n }\n\n /** Start a navigation replay from a raw baseline while retaining the last complete server document. */\n resetRawChanges(): void {\n this.rawChanges.reset();\n }\n\n destroy(): void {\n this.requestAttempt += 1;\n this.openUntil = 0;\n this.dropQueued();\n }\n\n /** Drop a queued request; whoever waits on it keeps what they already rendered. */\n private dropQueued(): void {\n const trailing = this.trailing;\n this.trailing = null;\n if (trailing === null) return;\n if (trailing.timer !== null) clearTimeout(trailing.timer);\n trailing.pending.settle({ status: 'superseded' });\n }\n\n private flush(merger: DataMerger, trailing: TrailingMerge): void {\n // A cancelled callback must never consume a successor's queued request.\n if (this.trailing !== trailing) return;\n this.trailing = null;\n trailing.timer = null;\n // The owned DataMerger fulfills one of its three outcomes, including request failures.\n void merger.merge(trailing.request).then(trailing.pending.settle);\n }\n}\n\n/** What one changed field's own value is worth. */\ntype FieldVerdict =\n /** Everything the page can render is in it. */\n | 'own'\n /** It can be rendered now, and the server may still complete something inside it. */\n | 'ask'\n /** It is a bare id where a document stood; writing it would put that id on the page. */\n | 'keep';\n\nfunction verdictFor(\n field: string,\n previous: unknown,\n value: unknown,\n cache: ElementCache,\n schemaIndex: SchemaIndex | undefined,\n): FieldVerdict {\n // A structure — a rich-text tree, an array, a group — may hold a reference\n // inside it, and the message's own copy of it is still what the editor typed.\n if (!isScalar(value)) return 'ask';\n if (!isScalar(previous) || namesAReference(field, cache, schemaIndex)) return 'keep';\n // A field that was empty can be filled with either a word or an id, and the\n // two look alike. Render it and ask: a word must not wait for the answer.\n return previous == null ? 'ask' : 'own';\n}\n\n/** A document id and a title are both strings; only the schema or a binding says which this is. */\nfunction namesAReference(\n field: string,\n cache: ElementCache,\n schemaIndex: SchemaIndex | undefined,\n): boolean {\n const schema = schemaIndex === undefined ? undefined : lookupSchema(schemaIndex, field);\n if (schema !== undefined && !SELF_SUFFICIENT_TYPES.has(schema.type)) return true;\n if (cache.get(field)?.some(rendersAReference) === true) return true;\n // `venue.title` is a page saying the field holds a document; the owner scope\n // is off here on purpose, because a binding in any document still says so.\n return hasBindingBelow(cache, field, false);\n}\n\nfunction rendersAReference(binding: { readonly fieldType: string }): boolean {\n // A project renderer is unknown ground: it may resolve the value itself.\n return !SELF_SUFFICIENT_TYPES.has(binding.fieldType);\n}\n\n/**\n * Whether anything on this page reads a value the server would populate.\n *\n * Two findings meet here. LP-4: a page with no binding, no island, no boundary\n * a fragment strategy would render and no listener reading the document has\n * nobody to hand the answer to — measured on such a page, 17 keystrokes cost 19\n * authenticated POSTs. LP-3: a page whose every binding is a plain scalar\n * renderer on a top-level field renders the panel's own values exactly, so the\n * merge could only hand back what the message already carries.\n *\n * The route is deliberately not a reason to ask. Since Z3 an unbound change\n * escalates to it by default, but a refresh re-renders the page from the server\n * and never looks at these values.\n */\nfunction readsPopulatedValues(deps: RuntimeDeps): boolean {\n const { cache, emitter } = deps;\n if (cache.islands.length > 0) return true;\n if (emitter.listenerCount('beforeUpdate') > 0 || emitter.listenerCount('afterUpdate') > 0) {\n return true;\n }\n for (const binding of cache.values()) {\n // A reference renderer, a value with structure, or a path inside a field.\n if (rendersAReference(binding) || binding.fieldName.includes('.')) return true;\n if (isPath(binding.hrefField) || isPath(binding.srcField) || isPath(binding.altField)) {\n return true;\n }\n }\n // A boundary is rendered by a server that is handed exactly these fields.\n return (\n deps.strategies.fragment !== undefined &&\n deps.root.querySelector(`[${FRAGMENT_ATTRIBUTE}]`) !== null\n );\n}\n\n/**\n * Whether a binding that declares no type holds rich text with something in it\n * the server fills in. The writer renders a Lexical root as rich text whatever\n * the element says (binding-writer.ts), and Payload 3's admin posts the nodes\n * inside it as bare IDs, so without this the image in a rich-text field was\n * written from its ID — which draws nothing — on a page that marked the\n * element with `data-payload-field` alone. Asked of the value, because the\n * same field holds an upload in one message and none in the next.\n */\nfunction rendersRichTextByShape(\n cache: ElementCache,\n raw: Record<string, unknown>,\n locale: string | undefined,\n): boolean {\n for (const binding of cache.values()) {\n // A declared type is what the writer renders; only the default `text` goes by the shape.\n if (binding.fieldType !== 'text' || binding.explicitFieldType === true) continue;\n // Read as the writer reads it, the binding's own locale first.\n const value = bindingValue(raw, binding, binding.fieldName, locale);\n if (looksLikeLexicalRoot(value) && holdsReference((value as { root: unknown }).root)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Walked with a stack rather than recursion, because the editor decides how\n * deep a tree goes. A message is a structured clone, which keeps a cycle, so a\n * node is walked once.\n */\nfunction holdsReference(root: unknown): boolean {\n const pending: unknown[] = [root];\n const seen = new Set<object>();\n for (let node = pending.pop(); node !== undefined; node = pending.pop()) {\n if (typeof node !== 'object' || node === null || seen.has(node)) continue;\n seen.add(node);\n const { type, fields, children } = node as {\n readonly type?: unknown;\n readonly fields?: { readonly linkType?: unknown } | null;\n readonly children?: unknown;\n };\n // `has` answers false for a type that is missing or not a string, and that node is asked for too.\n if (!SELF_SUFFICIENT_NODES.has(type as string)) return true;\n if (fields?.linkType === 'internal') return true;\n if (Array.isArray(children)) for (const child of children as unknown[]) pending.push(child);\n }\n return false;\n}\n\nfunction isScalar(value: unknown): boolean {\n return value === null || (typeof value !== 'object' && typeof value !== 'function');\n}\n\nfunction isPath(field: string | undefined): boolean {\n return field?.includes('.') === true;\n}\n\nfunction createPending(): PendingMerge {\n let settle!: (result: MergeResult) => void;\n const promise = new Promise<MergeResult>((resolve) => {\n settle = resolve;\n });\n return { promise, settle };\n}\n","/**\n * Where the runtime is running: framed, opened, or on a developer's machine.\n * Nothing reads bundler-injected variables; a Vite consumer passes\n * `import.meta.env.X` explicitly (docs/astro.md).\n * @internal\n */\n\nexport function isInIframe(): boolean {\n if (typeof window === 'undefined') return false;\n try {\n return window.self !== window.top;\n } catch {\n // A cross-origin parent throws on the comparison; that is an iframe.\n return true;\n }\n}\n\n/** @internal */\nexport function isInPopup(): boolean {\n if (typeof window === 'undefined') return false;\n return window.opener != null;\n}\n\n/** An iframe or a popup; top-level navigation never starts the preview. @internal */\nexport function isInPreviewContext(): boolean {\n return isInIframe() || isInPopup();\n}\n\n/** Under Node, `NODE_ENV !== 'production'`; in a browser the hostname, which is the only signal a bundle has. @internal */\nexport function isDevMode(): boolean {\n const nodeEnv = readNodeEnv();\n if (nodeEnv !== undefined) return nodeEnv !== 'production';\n if (typeof window !== 'undefined') {\n const host = window.location.hostname;\n return host === 'localhost' || host === '127.0.0.1';\n }\n return false;\n}\n\nfunction readNodeEnv(): string | undefined {\n if (typeof process === 'undefined') return undefined;\n const value = process.env['NODE_ENV'];\n return typeof value === 'string' ? value : undefined;\n}\n","/** Tracks the announced protocol version and the capabilities seen on the wire. */\n\nimport { isDevMode } from '@detection/environment';\nimport {\n LIBRARY_PROTOCOL_VERSION,\n negotiateProtocol,\n PAYLOAD_2_HINT,\n type ProtocolCapability,\n type ProtocolNegotiation,\n} from './protocol-version';\n\nexport class ProtocolTracker {\n negotiation: ProtocolNegotiation = negotiateProtocol(undefined);\n readonly observed = new Set<ProtocolCapability>();\n\n /** Record capabilities a message demonstrated; the stock admin announces no version. */\n observe(\n capabilities: readonly ProtocolCapability[],\n log: (...args: unknown[]) => void,\n warn: (...args: unknown[]) => void,\n ): void {\n const fresh = capabilities.filter((capability) => !this.observed.has(capability));\n if (fresh.length === 0) return;\n for (const capability of fresh) this.observed.add(capability);\n this.negotiation = negotiateProtocol(this.negotiation.theirs, this.observed);\n log('protocol', `observed=${fresh.join(',')}`);\n // A byte trade like the lean profile's others: it drops the hint, not Payload 2's behaviour.\n if (\n !(typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__) &&\n fresh.includes('schema-json') &&\n isDevMode()\n ) {\n warn(PAYLOAD_2_HINT);\n }\n }\n\n applyVersion(remoteVersion: number, log: (...args: unknown[]) => void): void {\n const current = this.negotiation;\n if (current.theirs === remoteVersion) return;\n const next = negotiateProtocol(remoteVersion, this.observed);\n this.negotiation = next;\n if (next.negotiated === current.negotiated) return;\n log(\n 'protocol',\n `ours=${LIBRARY_PROTOCOL_VERSION}`,\n `theirs=${remoteVersion}`,\n `negotiated=${next.negotiated}`,\n );\n }\n}\n","/**\n * Reads `externallyUpdatedRelationship` as an edge, not as a level. Payload's\n * panel fills the field from `useDocumentEvents().mostRecentUpdate`, a state\n * that every save of the previewed document raises and that nothing ever\n * clears, so the same event repeats in every message for the rest of the\n * session. Two questions make it news again: has the event changed since the\n * last one, and does it name a document other than the one on this page.\n */\n\nimport type {\n PayloadDocumentEventDetail,\n PayloadLivePreviewMessage,\n} from '@/types/payload-protocol';\nimport { readDocumentId } from './binding-owner';\n\n/**\n * Whether the event names a document other than the one this message previews.\n * A message that says which document that is settles it in both directions;\n * one that does not is taken at the event's word, because the repeat is\n * already handled by the identity and one re-render costs less than a drawer\n * edit the page never shows.\n */\nfunction namesAnotherDocument(\n event: PayloadDocumentEventDetail,\n message: PayloadLivePreviewMessage,\n): boolean {\n const previewedSlug = message.globalSlug ?? message.collectionSlug;\n if (typeof previewedSlug !== 'string' || event.entitySlug !== previewedSlug) return true;\n // The same entity. A global holds one document, so the event is its own\n // save; a collection is proven different only when both ids are known and\n // differ.\n const id = readDocumentId(event);\n const previewedId = readDocumentId(message.data ?? {});\n return id !== undefined && previewedId !== undefined && id !== previewedId;\n}\n\n/**\n * Whether the revision a new one supersedes still owes the page a drawer edit.\n *\n * The edit is news on exactly one message, and the panel posts the repeat in\n * the same burst: it supersedes the revision that carried the edit before the\n * server's populated answer arrives, so that answer is dropped, and the repeat\n * asks for nothing itself. The obligation passes to whoever supersedes it and\n * stops at the revision that completes.\n */\nexport function owesForceRender(\n previous: { readonly forceRender: boolean; readonly completed: boolean } | null,\n): boolean {\n return previous !== null && previous.forceRender && !previous.completed;\n}\n\n/** A fully read candidate whose identity can be committed after the revision gate. */\nexport interface RelationshipInspection {\n readonly identity: string;\n readonly edit: PayloadDocumentEventDetail | null;\n}\n\n/** Remembers the last document event the panel sent, so its repeats are one event. */\nexport class RelationshipTracker {\n /**\n * Identity of the last event seen. Not `id` alone: a global's save carries\n * none, and an identity that required one would read every global save as a\n * new document.\n */\n private lastIdentity: string | undefined = undefined;\n\n /**\n * The edit this message brings that the page has not acted on yet: a changed\n * event about another document. `null` for a message without the field, for\n * the repeat, and for the previewed document's own save.\n */\n inspect(message: PayloadLivePreviewMessage): RelationshipInspection | null {\n const event = message.externallyUpdatedRelationship;\n if (typeof event !== 'object' || event === null) return null;\n const identity = JSON.stringify([event.entitySlug, readDocumentId(event), event.updatedAt]);\n const isNew = identity !== this.lastIdentity;\n return {\n identity,\n edit: isNew && namesAnotherDocument(event, message) ? event : null,\n };\n }\n\n /**\n * Claim an inspection only after its revision is still current. Reading the\n * candidate may run synthetic accessors, so mutating in `inspect` would let\n * a stale outer message overwrite the identity a reentrant message set.\n */\n commit(inspection: RelationshipInspection): PayloadDocumentEventDetail | null {\n const isNew = inspection.identity !== this.lastIdentity;\n this.lastIdentity = inspection.identity;\n return isNew ? inspection.edit : null;\n }\n}\n","/**\n * Scroll the edited field's bound element into view. Deliberately quiet: only\n * when the target is off-screen and only when the edited field changed since\n * the last reveal, so continuous typing never re-scrolls and a deliberate\n * scroll-away is not fought. Honours `prefers-reduced-motion`. A closed\n * `<details>` around the element lays nothing out, so it opens first; the same\n * ledger means a section the editor closes again stays closed.\n */\n\n/** The slice of `Window` this reads, so it tests without a browser. */\nexport interface RevealWindow {\n readonly innerHeight: number;\n readonly innerWidth: number;\n matchMedia?: (query: string) => { readonly matches: boolean };\n}\n\n/** The slice of `Element` this module needs. */\nexport interface RevealElement {\n getBoundingClientRect: () => {\n readonly top: number;\n readonly bottom: number;\n readonly left: number;\n readonly right: number;\n };\n scrollIntoView: (options?: {\n behavior?: 'auto' | 'smooth';\n block?: 'center' | 'nearest' | 'start';\n }) => void;\n closest?: (selector: string) => { setAttribute: (name: string, value: string) => void } | null;\n}\n\nconst CLOSED_DETAILS = 'details:not([open])';\n\n/** Whether the viewer asked for reduced motion; smooth scrolling is suppressed when so. */\nexport function prefersReducedMotion(win: RevealWindow): boolean {\n try {\n return win.matchMedia?.('(prefers-reduced-motion: reduce)').matches === true;\n } catch {\n return false;\n }\n}\n\n/** A visible sliver counts: an element the editor can already see is never scrolled to. */\nexport function isInViewport(element: RevealElement, win: RevealWindow): boolean {\n const rect = element.getBoundingClientRect();\n const vertically = rect.bottom > 0 && rect.top < win.innerHeight;\n const horizontally = rect.right > 0 && rect.left < win.innerWidth;\n return vertically && horizontally;\n}\n\n/** Outcome of a reveal attempt, for the caller's diagnostics. */\nexport type RevealOutcome = 'revealed' | 'already-visible';\n\n/** Scroll `element` into view only when it is off-screen. */\nexport function revealElement(element: RevealElement, win: RevealWindow): RevealOutcome {\n // Each pass opens the nearest closed one, so the next finds the one outside it.\n for (let closed; (closed = element.closest?.(CLOSED_DETAILS));) closed.setAttribute('open', '');\n if (isInViewport(element, win)) return 'already-visible';\n element.scrollIntoView({\n behavior: prefersReducedMotion(win) ? 'auto' : 'smooth',\n block: 'center',\n });\n return 'revealed';\n}\n\n/** Remembers the last field revealed, so only a change of field scrolls again. */\nexport class FieldRevealer {\n #lastField: string | undefined;\n\n /** `skipped-same` when this is still the field last revealed. */\n reveal(\n fieldName: string,\n element: RevealElement,\n win: RevealWindow,\n ): RevealOutcome | 'skipped-same' {\n if (fieldName === this.#lastField) return 'skipped-same';\n this.#lastField = fieldName;\n return revealElement(element, win);\n }\n\n /** Forget the last field, after a navigation that rebuilt the page. */\n reset(): void {\n this.#lastField = undefined;\n }\n}\n\n/**\n * Scroll one binding into view. Keyed by document as well as field: two\n * documents on one page have their own `title`, and revealing one must not\n * count as revealing the other.\n */\nexport function revealBinding(\n revealer: FieldRevealer,\n target: {\n readonly element: Element;\n readonly owner?: string | undefined;\n readonly fieldName: string;\n },\n): RevealOutcome | 'skipped-same' | 'no-element' {\n const win = target.element.ownerDocument.defaultView as RevealWindow | null;\n if (win === null) return 'no-element';\n return revealer.reveal(`${target.owner ?? ''} ${target.fieldName}`, target.element, win);\n}\n","/**\n * Which value each owned field was last seen with, and the one binding a\n * revision should scroll to: the bookkeeping behind \"reveal the edited field\",\n * kept apart from the pipeline that schedules the writes.\n *\n * Keyed by document, locale and field rather than by element. The element a\n * fragment renders does not survive its own re-render, but the field it shows\n * is the same field.\n *\n * The ledger is written only when a revision reaches its reveal point, not when\n * a candidate is noted. Writing at once lost reveals: an identical re-send\n * superseded the revision that had noted the change, then found nothing new.\n */\n\nimport { valueIdentity } from './value-identity';\n\n/** What the ledger needs of a binding: the key parts, and the element to reveal. */\nexport interface RevealKey {\n readonly owner?: string | undefined;\n readonly locale?: string | undefined;\n readonly fieldName: string;\n}\n\n/** The per-revision slot the ledger fills; the transaction carries it. */\nexport interface RevealSlot<T extends RevealKey> {\n revealIdentities: [key: string, identity: string][];\n revealTarget: T | undefined;\n}\n\nexport class RevealLedger {\n private readonly seen = new Map<string, string>();\n\n /**\n * Record what this binding's value looks like now and, for the first binding\n * whose value moved, mark it as the one to reveal.\n *\n * The first message is a baseline and a binding new to the page is not an\n * edit, so an unseen key only records. A value too large or cyclic to compare\n * cannot claim to have changed either, or it would take the reveal from a\n * field that did.\n */\n note<T extends RevealKey>(slot: RevealSlot<T>, target: T, value: unknown): void {\n const identity = valueIdentity(value);\n if (identity === undefined) return;\n const key = `${target.owner ?? ''}\u0000${target.locale ?? ''}\u0000${target.fieldName}`;\n const seen = this.seen.get(key);\n if (seen === undefined) {\n // A baseline is recorded at once: nothing is owed for it.\n this.seen.set(key, identity);\n return;\n }\n if (seen === identity) return;\n slot.revealIdentities.push([key, identity]);\n slot.revealTarget ??= target;\n }\n\n /**\n * The revision reached its reveal point: what it saw is now what the ledger\n * shows, whether or not there is anything to scroll to. Hands out the\n * binding to reveal once; a second call finds the slot empty.\n */\n commit<T extends RevealKey>(slot: RevealSlot<T>): T | undefined {\n for (const [key, identity] of slot.revealIdentities) this.seen.set(key, identity);\n slot.revealIdentities = [];\n const target = slot.revealTarget;\n slot.revealTarget = undefined;\n return target;\n }\n}\n","/**\n * How completely the page shows one revision (ADR 0023). The session counters\n * say what happened over a session; this says, for the revision in flight,\n * whether work is outstanding and which step fell short, so a host does not\n * have to attribute route outcomes and fragment fallbacks itself.\n */\n\nimport type { DiagnosticCode } from './diagnostic-codes';\nimport type { RuntimeDeps, RuntimeState, UpdateTransaction } from './runtime-state';\nimport { FRAGMENT_ATTRIBUTE, FRAGMENT_KEY_ATTRIBUTE, type RouteOutcome } from './strategies';\n\n/** Where a revision stands: work left, shown, shown with shortfalls, awaiting an island, or replaced (ADR 0023). */\nexport type RevisionDisplayState = 'pending' | 'current' | 'partial' | 'unconfirmed' | 'superseded';\n\n/** One step that kept a settled revision from being current. */\nexport type RevisionShortfall =\n | {\n readonly kind: 'fragment';\n readonly id: string;\n readonly key: string | undefined;\n readonly code: DiagnosticCode;\n }\n | { readonly kind: 'route-saved' }\n | { readonly kind: 'route-failed'; readonly outcome: RouteOutcome }\n | { readonly kind: 'unfaithful' | 'unbound'; readonly field: string }\n | { readonly kind: 'write'; readonly field: string; readonly code: DiagnosticCode }\n | { readonly kind: 'merge' };\n\n/** How completely the page shows one accepted revision (ADR 0023). */\nexport interface RevisionDisplay {\n /** The message revision this record is about. */\n readonly revision: number;\n /** `pending` while work is left; the other states once it settled. */\n readonly state: RevisionDisplayState;\n /** What kept a settled revision from being current; empty unless `state` is `partial`. */\n readonly shortfalls: readonly RevisionShortfall[];\n /** Writes the visibility gate holds until their element is seen; they count as landed. */\n readonly deferred: number;\n /** Islands the revision was handed to that have not called `displayed()`. */\n readonly awaitingIslands: number;\n}\n\n/** What the ledger asks of the runtime: whether work is left, where a settled state goes, and where a failure to say it goes. */\nexport interface RevisionDisplayHost<K> {\n readonly outstanding: (key: K) => boolean;\n readonly report: (display: RevisionDisplay) => void;\n readonly failed: (error: unknown) => void;\n}\n\ninterface Entry<K> {\n key: K | undefined;\n readonly revision: number;\n readonly shortfalls: RevisionShortfall[];\n readonly seen: Set<string>;\n deferred: number;\n awaiting: number;\n reported: RevisionDisplayState | undefined;\n queued: boolean;\n}\n\n/** What an older revision's island is handed: its confirmation no longer counts. */\nconst IGNORED = (): void => undefined;\n\nexport class RevisionDisplayLedger<K extends object> {\n host: RevisionDisplayHost<K> = { outstanding: () => false, report: IGNORED, failed: IGNORED };\n private entry: Entry<K> | null = null;\n private ended: RevisionDisplay | undefined;\n\n /**\n * A newer revision was accepted. The one before it reports now: superseded\n * if it had work left, otherwise the state it reached and had not yet said.\n */\n begin(key: K, revision: number): void {\n const previous = this.entry;\n const view = previous === null ? undefined : this.view(previous);\n // Publish the new owner before a report can end it or accept a newer one.\n if (previous !== null) previous.key = undefined;\n this.ended = undefined;\n this.entry = {\n key,\n revision,\n shortfalls: [],\n seen: new Set(),\n deferred: 0,\n awaiting: 0,\n reported: undefined,\n queued: false,\n };\n if (previous !== null && view !== undefined) {\n this.publish(previous, view.state === 'pending' ? { ...view, state: 'superseded' } : view);\n }\n }\n\n /** End this owner: retain only its display facts, never its transaction or live confirmations. */\n end(): void {\n const entry = this.entry;\n if (entry === null) return;\n this.entry = null;\n try {\n this.ended = this.view(entry);\n } finally {\n // Island and microtask closures may retain the entry after its owner ended.\n entry.key = undefined;\n }\n }\n\n /** The latest accepted revision's record, as `inspect()` reads it. */\n snapshot(): RevisionDisplay | undefined {\n if (this.entry !== null) return this.view(this.entry);\n return this.ended === undefined\n ? undefined\n : { ...this.ended, shortfalls: [...this.ended.shortfalls] };\n }\n\n /** Record a shortfall against `key` while it is the latest revision; the same one twice counts once. */\n shortfall(key: K | null, shortfall: RevisionShortfall): void {\n const entry = this.entry;\n if (entry?.key !== key) return;\n const id = JSON.stringify(shortfall);\n if (entry.seen.has(id)) return;\n entry.seen.add(id);\n entry.shortfalls.push(shortfall);\n this.requestSettle(entry.key);\n }\n\n /** How many of the revision's writes the visibility gate holds, as of its latest flush. */\n deferred(key: K, count: number): void {\n if (this.entry?.key === key) this.entry.deferred = count;\n }\n\n /**\n * An island is handed the revision; the returned callback is its\n * `displayed()`. Late, repeated or superseded calls do nothing.\n */\n handIsland(key: K): () => void {\n const entry = this.entry;\n if (entry?.key !== key) return IGNORED;\n entry.awaiting += 1;\n let confirmed = false;\n return () => {\n if (confirmed || this.entry !== entry) return;\n confirmed = true;\n entry.awaiting -= 1;\n this.settle(entry);\n };\n }\n\n /**\n * Look again once the current task's synchronous work is done: a flush\n * hands islands the revision after it completes, and those count.\n */\n requestSettle(key: K): void {\n const entry = this.entry;\n if (entry?.key !== key || entry.queued) return;\n entry.queued = true;\n queueMicrotask(() => {\n entry.queued = false;\n // Nothing awaits this task: a throw would reach no one but the console.\n try {\n if (this.entry === entry) this.settle(entry);\n } catch (error) {\n this.host.failed(error);\n }\n });\n }\n\n private settle(entry: Entry<K>): void {\n const view = this.view(entry);\n if (view.state !== 'pending') this.publish(entry, view);\n }\n\n private publish(entry: Entry<K>, view: RevisionDisplay): void {\n if (entry.reported === view.state) return;\n entry.reported = view.state;\n this.host.report(view);\n }\n\n private view(entry: Entry<K>): RevisionDisplay {\n // Only the latest entry is viewed; `begin` alone says `superseded`.\n const state: RevisionDisplayState =\n entry.key !== undefined && this.host.outstanding(entry.key)\n ? 'pending'\n : entry.shortfalls.length > 0\n ? 'partial'\n : entry.awaiting > 0\n ? 'unconfirmed'\n : 'current';\n return {\n revision: entry.revision,\n state,\n shortfalls: [...entry.shortfalls],\n deferred: entry.deferred,\n awaitingIslands: entry.awaiting,\n };\n }\n}\n\n/**\n * The runtime's answer to \"is work left\": a revision not yet complete, a\n * boundary still rendering, a route refresh in flight or held back by its\n * window, or writes not flushed. The route counts for whichever revision is\n * current, because it lands for that one (ADR 0004 §4d).\n */\nexport function runtimeDisplayHost(\n deps: Pick<RuntimeDeps, 'scheduler' | 'emitter' | 'a11y' | 'log'>,\n state: Pick<RuntimeState, 'routeController' | 'routeRetry'>,\n): RevisionDisplayHost<UpdateTransaction> {\n return {\n outstanding: (transaction) =>\n !transaction.completed ||\n transaction.pendingFragments > 0 ||\n state.routeController !== null ||\n state.routeRetry !== null ||\n deps.scheduler.pendingCount > 0,\n report: (display) => {\n if (display.state === 'partial') deps.a11y?.announcePartial();\n void deps.emitter.emit('revisionDisplay', display);\n },\n failed: (error) => {\n deps.log('revision display failed:', error);\n },\n };\n}\n\n/** A strategy that threw renders none of its boundaries; each fell back to a patch (LP0801). */\nexport function thrownFragment(boundary: Element): RevisionShortfall {\n const key = boundary.getAttribute(FRAGMENT_KEY_ATTRIBUTE);\n return {\n kind: 'fragment',\n id: boundary.getAttribute(FRAGMENT_ATTRIBUTE) ?? '',\n key: key === null || key.length === 0 ? undefined : key,\n code: 'LP0801',\n };\n}\n","/**\n * What the runtime owns for its lifetime (`RuntimeDeps`) and what changes as it\n * runs (`RuntimeState`). Both are shared by the pipeline collaborators.\n */\n\nimport type {\n PayloadFieldSchema,\n PayloadLivePreviewData,\n PayloadLivePreviewMessage,\n} from '@/types/payload-protocol';\nimport type { EventEmitter } from '@events/emitter';\nimport type { SchemaIndex } from '@schema/index';\nimport type { SanitizerPolicyMode } from '@security/sanitizer';\nimport type { A11yAnnouncer } from './a11y';\nimport type { AutoBindMode, KeptGuesses } from './auto-bind';\nimport type { ElementCache } from './cache';\nimport type { DataMerger } from './data-merger';\nimport type { UnfaithfulPatchMode, UnfaithfulReport } from './fidelity';\nimport type { HydrationMode, HydrationState } from './hydration';\nimport { FieldChangeTracker } from './field-changes';\nimport { MergeNeed } from './merge-need';\nimport type { MessageBus, MessageRevision } from './message-bus';\nimport type { ObserverManager } from './observers';\nimport { ProtocolTracker } from './protocol-tracker';\nimport { RelationshipTracker } from './relationship-tracker';\nimport { FieldRevealer } from './reveal';\nimport { RevealLedger } from './reveal-ledger';\nimport { RevisionDisplayLedger } from './revision-display';\nimport type { RuntimeOptions } from './runtime-options';\nimport type { ConnectionState, HeartbeatTimer } from './state';\nimport type { SubfieldCoverage } from './subfield-coverage';\nimport type { StrategyHandlers } from './strategies';\nimport type { CachedElement, FieldRenderer, RichTextRenderer } from './types';\nimport type { FlushStats, UpdateScheduler } from './update-scheduler';\n\n/** One accepted message on its way to the DOM. See ADR 0004. */\nexport interface UpdateTransaction {\n readonly revision: MessageRevision;\n readonly message: PayloadLivePreviewMessage;\n /** Raw fields captured once when the data-bearing update or replay was accepted. */\n readonly rawData: Record<string, unknown>;\n readonly locale: string | undefined;\n readonly schema: readonly PayloadFieldSchema[] | undefined;\n readonly schemaIndex: SchemaIndex | undefined;\n readonly receivedAt: number;\n /** A save in another document may change populated values only, so render everything. */\n readonly forceRender: boolean;\n /** Whether this transaction came from a newly accepted remote message and contributes to revision counters. */\n readonly countsAsUpdate: boolean;\n /** Latest raw or populated data this revision rendered, retained for late streamed bindings. */\n renderData: PayloadLivePreviewData | undefined;\n /** Fragment boundaries already handed to the strategy for this revision. */\n readonly fragmentBoundariesRun: WeakSet<Element>;\n /** Top-level fields whose value changed since the previous message, plus their dependents. */\n touched: ReadonlySet<string>;\n /** The connection's first message, where every field counts as changed. */\n baseline: boolean;\n /** The first message after a router commit or a restore: every field counts as changed, on markup the server just rendered. */\n navigated: boolean;\n /** Dependents of changed fields; re-applied even when their own value is unchanged. */\n invalidated: ReadonlySet<string>;\n /**\n * First binding whose value changed; revealed once its write landed. The\n * binding itself, not its field name: several documents on one page share\n * field names, and only this one belongs to the edited document.\n */\n revealTarget: CachedElement | undefined;\n /**\n * Identities the reveal ledger will record once this revision reaches its\n * reveal point — not before. A revision superseded on the way there never\n * revealed, so the ledger must still show the previous value: the message\n * that supersedes it is then the one that owes the reveal.\n */\n revealIdentities: [key: string, identity: string][];\n pendingFragments: number;\n routeRefreshed: boolean;\n cancelled: boolean;\n /** Terminal: the scheduled writes reached the DOM (or there were none). */\n completed: boolean;\n}\n\nexport interface RuntimeDeps {\n readonly emitter: EventEmitter;\n readonly cache: ElementCache;\n readonly observers: ObserverManager;\n readonly scheduler: UpdateScheduler;\n readonly bus: MessageBus;\n readonly connection: ConnectionState;\n readonly heartbeat: HeartbeatTimer;\n readonly renderers: Readonly<Record<string, FieldRenderer>>;\n readonly resolveRenderer: NonNullable<RuntimeOptions['resolveRenderer']>;\n readonly transformValue: RuntimeOptions['transformValue'];\n readonly renderRichText: RichTextRenderer | undefined;\n readonly internalLinkPattern: string | undefined;\n readonly routeAfterSave: boolean;\n /** The page left `subfieldCoverage` to the 2.x default. */\n readonly coverageByDefault: boolean;\n readonly sanitizerPolicy: SanitizerPolicyMode | undefined;\n readonly root: Document | Element;\n readonly readyTargets: () => readonly string[];\n readonly sendReady: (origins: readonly string[]) => void;\n readonly onHeartbeatTimeout: RuntimeOptions['onHeartbeatTimeout'];\n readonly log: (...args: unknown[]) => void;\n readonly warn: (...args: unknown[]) => void;\n readonly a11y: A11yAnnouncer | null;\n readonly merger: DataMerger | null;\n /** The server the merger reads from: where a media path in a populated document points. */\n readonly serverURL: string | undefined;\n /** How long a burst of messages may share one merge; the scheduler's debounce window. */\n readonly mergeWindowMs: number;\n readonly scopeBindingsByOwner: boolean;\n /** ADR 0022: whether one bound descendant covers a group, or each changed path needs its own. */\n readonly subfieldCoverage: SubfieldCoverage;\n readonly lockedOrigin: () => string | undefined;\n readonly skipUnchanged: boolean;\n readonly dependencies: Readonly<Record<string, readonly string[]>>;\n readonly strategies: StrategyHandlers;\n readonly revealEditedField: boolean;\n /** What to do about a patch the runtime knows cannot match the server's render. */\n readonly onUnfaithfulPatch: UnfaithfulPatchMode;\n /** Whether the first message is searched for bindings by value (ADR 0014). */\n readonly autoBind: AutoBindMode;\n /** The framework whose first commit the start waits for (ADR 0015); `undefined` on a page that declared none. */\n readonly hydration: HydrationMode | undefined;\n}\n\nexport class RuntimeState {\n started = false;\n /** Set by `suspend()`; lets `destroy()` finish a suspended instance. */\n suspended = false;\n /** Cancels a startup still waiting — for `DOMContentLoaded`, or for the framework's first commit (ADR 0015). */\n deferredStart: (() => void) | null = null;\n /** How far the wait for hydration got; `idle` on a page that declared none. */\n hydration: HydrationState = 'idle';\n activeUpdate: UpdateTransaction | null = null;\n locale: string | undefined = undefined;\n schema: readonly PayloadFieldSchema[] | undefined = undefined;\n schemaIndex: SchemaIndex | undefined = undefined;\n updateCount = 0;\n supersededCount = 0;\n completedCount = 0;\n skippedUnchangedCount = 0;\n lastFlush: FlushStats | null = null;\n readonly absentFields = new Set<string>();\n readonly warnedOrphanFields = new Set<string>();\n readonly warnedStrategy = new WeakSet<Element>();\n warnedUnattributableMessage = false;\n warnedVisibilityGate = false;\n warnedFragmentFallback = false;\n /** LP0809 is reported once: every later island would fail for the same page-level reason. */\n warnedIslandStart = false;\n /** LP0808 is said once: escalation was asked for and nothing on the page can do it. */\n warnedEscalationUnavailable = false;\n /** LP0503 is reported once: a drifting sender repeats the same shape on every keystroke. */\n warnedProtocolShape = false;\n /** The value each element that fell short was last reported or handed over with, and when (`fidelity.ts`). */\n readonly reportedUnfaithful = new WeakMap<Element, UnfaithfulReport>();\n /** Bindings whose first write has already been held against what the template printed (LP0412). */\n readonly checkedServerFormat = new WeakSet<Element>();\n /** The rows each binding on an index path last stood in (`moved-rows.ts`). */\n readonly rowsOfBinding = new WeakMap<Element, string>();\n /** Bindings this revision could not patch faithfully, drained by the flush that escalates them. */\n unfaithfulPatches: CachedElement[] = [];\n /** Every binding ever reported unfaithful, and how many of them a strategy was handed; `inspect().fidelity`. */\n unfaithfulCount = 0;\n escalatedCount = 0;\n readonly unfaithfulFields = new Set<string>();\n /** What the one auto-binding search cost, for `inspect()`; `undefined` until it ran. */\n autoBindSearchMs: number | undefined = undefined;\n /** What that search bound, looked for again after a route refresh (ADR 0014); `null` until it ran. */\n autoBindGuesses: KeptGuesses | null = null;\n\n /**\n * Whether the first message refused for coming from the wrong window has been\n * reported. `eventSourcePolicy` flipped from `'any'` to `'parent-or-opener'`\n * in 2.0, so a 1.x arrangement that posts from anywhere else stops working on\n * upgrade — silently, because a refusal only reaches the debug log.\n */\n warnedForeignSource = false;\n /** Identity of the value each element last applied; reset when the markup is re-rendered. */\n lastAppliedIdentity = new WeakMap<Element, string>();\n /** The next full snapshot follows a router commit, not the initial server baseline. */\n navigationReplayPending = false;\n /** New bindings streamed into the current navigated document receive its latest accepted data. */\n navigationBindingReplay = false;\n /** What each owned field was last seen with, for the reveal decision only. */\n readonly revealLedger = new RevealLedger();\n /** How completely the page shows the latest accepted revision (ADR 0023). */\n readonly display = new RevisionDisplayLedger<UpdateTransaction>();\n readonly fragmentStats = { rendered: 0, failed: 0, superseded: 0 };\n readonly routeStats = { refreshes: 0, partial: 0, failed: 0, refused: 0, loopStopped: 0 };\n /**\n * Every fragment batch still rendering, with the boundaries it has not\n * settled yet; streamed bindings can start more than one per revision.\n */\n readonly fragmentControllers = new Map<AbortController, ReadonlySet<Element>>();\n routeController: AbortController | null = null;\n /** The trailing run a refused refresh asked for; at most one, and always the newest. */\n routeRetry: ReturnType<typeof setTimeout> | null = null;\n /**\n * A trailing run a newer revision took over before it ran. That revision\n * plans from its own diff, which no longer names the field the older one\n * changed, so the debt is carried here until a refresh runs. A refresh\n * already running is not owed: it lands for the newer revision.\n */\n routeRefreshOwed = false;\n /**\n * The route was last rendered from the saved document for a revision holding\n * edits that render could not show (`partial`, ADR 0018): the next save, which\n * puts them on the server, renders it again.\n */\n routeAwaitsSave = false;\n /**\n * Boundaries a newer revision cut short before they settled: the same debt,\n * per boundary, settled when a render of the boundary starts.\n */\n readonly fragmentsOwed = new Set<Element>();\n readonly readyTimers: ReturnType<typeof setTimeout>[] = [];\n readonly revealer = new FieldRevealer();\n readonly changes = new FieldChangeTracker();\n readonly merges = new MergeNeed();\n readonly protocol = new ProtocolTracker();\n readonly relationships = new RelationshipTracker();\n\n /** Read through a method: TypeScript keeps a narrowed `started` across the calls that can flip it. */\n isRunning(): boolean {\n return this.started;\n }\n\n /** Whether `transaction` may still touch the DOM; re-checked after every reentrant callback. */\n isCurrent(transaction: UpdateTransaction): boolean {\n return this.started && this.activeUpdate === transaction;\n }\n\n complete(transaction: UpdateTransaction): void {\n // Asked again after a refresh re-applies it: only then is a refused route settled.\n this.display.requestSettle(transaction);\n if (transaction.completed) return;\n transaction.completed = true;\n if (transaction.countsAsUpdate) this.completedCount += 1;\n }\n\n /** A new route or session starts clean: no refresh or boundary render is owed to it. */\n forgetOwedWork(): void {\n this.routeRefreshOwed = false;\n this.routeAwaitsSave = false;\n this.fragmentsOwed.clear();\n }\n\n /**\n * A newer revision supersedes the older one's revision-bound work: boundary\n * renders carry its fields, and a trailing refresh runs for the revision that\n * asked. Both become debts the newer revision settles, because its message\n * carries the older one's values too while its own diff no longer names them\n * (PHD-07). The route refresh in flight is not revision-bound — it renders\n * the server's view of the route — so it runs on and lands for whichever\n * revision is current then; only a refresh of that revision's own replaces it.\n */\n supersedeStrategies(): void {\n if (this.routeRetry !== null) {\n clearTimeout(this.routeRetry);\n this.routeRetry = null;\n this.routeRefreshOwed = true;\n }\n for (const [controller, unsettled] of this.fragmentControllers) {\n for (const boundary of unsettled) this.fragmentsOwed.add(boundary);\n controller.abort();\n }\n this.fragmentControllers.clear();\n }\n\n /** Abort all strategy work, the route refresh included: a navigation, a lost connection or a stop. */\n abortStrategies(): void {\n this.supersedeStrategies();\n const route = this.routeController;\n this.routeController = null;\n route?.abort();\n }\n}\n","/**\n * Writes one scheduled value into its bound element: renderer resolution,\n * the attribute or renderer write, and the `elementUpdate` event. Every\n * consumer callback may accept a newer revision synchronously, so the\n * transaction is re-checked after each one (ADR 0004).\n */\n\nimport { definedOnly } from '@/types/defined-only';\nimport { sameRevision } from './message-bus';\nimport { lookupSchema, payloadTypeToRenderer } from '@schema/index';\nimport { applyAttributeBinding } from './attribute-binding';\nimport { reportServerFormatting, reportUnfaithfulPatch, watchServerFormatting } from './fidelity';\nimport { rendererUsesNoWriteOutcome } from './internal-outcome';\nimport { type RuntimeDeps, type RuntimeState, type UpdateTransaction } from './runtime-state';\nimport type { CachedElement, FieldRenderer, RenderContext, RendererKey } from './types';\nimport type { ScheduledUpdate } from './update-scheduler';\n\nexport class BindingWriter {\n /** The value being written, which a renderer's report of a shortfall is about. */\n private writing: unknown;\n /** The instance's share of every `RenderContext`, built once: a write allocates the context alone. */\n private readonly instanceContext: Pick<\n RenderContext,\n 'renderRichText' | 'sanitizerPolicy' | 'serverURL' | 'reportUnfaithful' | 'internalLinkPattern'\n >;\n\n constructor(\n private readonly deps: RuntimeDeps,\n private readonly state: RuntimeState,\n ) {\n this.instanceContext = definedOnly({\n renderRichText: deps.renderRichText,\n internalLinkPattern: deps.internalLinkPattern,\n sanitizerPolicy: deps.sanitizerPolicy,\n serverURL: deps.serverURL,\n // A renderer already holds its target, so one closure per instance says\n // as much as one per write and allocates nothing during an update.\n reportUnfaithful: (target: CachedElement, reason: string): void => {\n reportUnfaithfulPatch(deps, state, target, reason, this.writing);\n },\n });\n }\n\n /** Scheduler callback. `false` means nothing reached the DOM. */\n apply(update: ScheduledUpdate): boolean {\n const { deps, state } = this;\n const transaction = state.activeUpdate;\n if (\n transaction === null ||\n update.revision === undefined ||\n !sameRevision(transaction.revision, update.revision) ||\n !state.isCurrent(transaction)\n ) {\n return false;\n }\n const { target, value } = update;\n const schemaEntry =\n transaction.schemaIndex !== undefined\n ? lookupSchema(transaction.schemaIndex, target.fieldName)\n : undefined;\n let type = resolveFieldType(target, schemaEntry?.type);\n // Payload 3.x sends no schema; a Lexical root is unmistakable.\n if (type === 'text' && target.explicitFieldType !== true && looksLikeLexicalRoot(value)) {\n type = 'richText';\n }\n let renderer: FieldRenderer | undefined;\n try {\n renderer = deps.resolveRenderer(type, target);\n } catch (error) {\n return this.fail(transaction, target.fieldName, error);\n }\n if (!state.isCurrent(transaction)) return false;\n const emitElementUpdate = deps.emitter.listenerCount('elementUpdate') > 0;\n // Custom-element accessors run application code, so this is a boundary too.\n const previous = emitElementUpdate ? readElementSnapshot(target.element) : undefined;\n if (!state.isCurrent(transaction)) return false;\n const context: RenderContext = {\n allFields: update.allFields,\n locale: target.locale ?? transaction.locale,\n schema: schemaEntry,\n ...this.instanceContext,\n };\n // A boundary anchor stays out of layout and the accessibility tree while empty.\n if (target.hidesWhenEmpty === true) {\n target.element.toggleAttribute('hidden', isEmptyFieldValue(value));\n }\n try {\n if (target.targetAttribute !== undefined) {\n if (applyAttributeBinding(target.element, target.targetAttribute, value) === 'blocked') {\n deps.warn(\n `[live-preview] LP0401: refused to write \"${target.fieldName}\" into attribute \"${target.targetAttribute}\"`,\n );\n state.display.shortfall(transaction, {\n kind: 'write',\n field: target.fieldName,\n code: 'LP0401',\n });\n return false;\n }\n } else if (renderer !== undefined) {\n // Read before the write, because afterwards the template's own reading\n // of this value is gone (Z20). Costs nothing unless this is the first\n // write to a binding a formatting renderer owns.\n const shown = watchServerFormatting(deps, state, target, type);\n this.writing = value;\n const outcome = invokeRenderer(renderer, target, value, context);\n if (outcome === false && rendererUsesNoWriteOutcome(renderer)) {\n // The renderer refused the value it was given, so the element still\n // shows what the server put there — right until the next edit makes\n // it stale. That is the moment to ask for better markup.\n reportUnfaithfulPatch(\n deps,\n state,\n target,\n `is a value ${renderer.name} cannot render`,\n value,\n );\n return false;\n }\n if (shown !== undefined) reportServerFormatting(deps, target, shown, type);\n } else {\n deps.log('no renderer for', type);\n reportUnfaithfulPatch(deps, state, target, `has no renderer for \"${type}\"`, value);\n return false;\n }\n } catch (error) {\n return this.fail(transaction, target.fieldName, error);\n }\n if (!state.isCurrent(transaction)) return false;\n if (emitElementUpdate) {\n void deps.emitter.emitWhile(\n 'elementUpdate',\n {\n element: target.element,\n fieldName: target.fieldName,\n previousValue: previous,\n nextValue: value,\n revision: transaction.revision.revision,\n receivedAt: transaction.receivedAt,\n source: 'patch',\n },\n () => state.isCurrent(transaction),\n );\n }\n // The first handler runs before emitWhile yields; a reentrant newer\n // revision must not count this write as applied.\n const applied = state.isCurrent(transaction);\n if (applied) {\n if (update.valueIdentity !== undefined) {\n state.lastAppliedIdentity.set(target.element, update.valueIdentity);\n } else {\n state.lastAppliedIdentity.delete(target.element);\n }\n }\n return applied;\n }\n\n private fail(transaction: UpdateTransaction, field: string, cause: unknown): false {\n if (!this.state.isCurrent(transaction)) return false;\n this.state.display.shortfall(transaction, { kind: 'write', field, code: 'LP0603' });\n const error = cause instanceof Error ? cause : new Error(String(cause));\n void this.deps.emitter.emitWhile('error', { error, context: 'renderer', code: 'LP0603' }, () =>\n this.state.isCurrent(transaction),\n );\n return false;\n }\n}\n\n/** Explicit `data-payload-type` wins over the schema, which wins over tag heuristics. */\nfunction resolveFieldType(target: CachedElement, schemaType: string | undefined): RendererKey {\n if (target.explicitFieldType) return target.fieldType;\n if (schemaType !== undefined) {\n const mapped = payloadTypeToRenderer(schemaType);\n if (mapped !== undefined) return mapped;\n }\n return target.fieldType;\n}\n\n/** Built-in renderers may return exact `false` for a deliberate no-write; the public type stays `void`. */\nfunction invokeRenderer(\n renderer: FieldRenderer,\n target: CachedElement,\n value: unknown,\n context: RenderContext,\n): unknown {\n // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n return renderer.render(target, value, context);\n}\n\n/**\n * Same shape test as `isLexicalContent`, duplicated so core does not pull the\n * Lexical renderer. The merge decision asks it too, so it reads a value the way\n * this writer will render it.\n */\nexport function looksLikeLexicalRoot(value: unknown): boolean {\n if (typeof value !== 'object' || value === null || !('root' in value)) return false;\n const root = value.root;\n return (\n typeof root === 'object' &&\n root !== null &&\n Array.isArray((root as { children?: unknown }).children)\n );\n}\n\n/**\n * A Lexical root that shows nothing: no node, or paragraphs with no children\n * of their own, which is what Lexical leaves in a field an editor emptied.\n * It is as empty as `null`, for the anchor that hides and for the rich-text\n * write.\n */\nexport function isEmptyLexicalRoot(value: unknown): boolean {\n if (!looksLikeLexicalRoot(value)) return false;\n return (value as { root: { children: readonly unknown[] } }).root.children.every((node) => {\n const { type, children } = (node ?? {}) as { type?: unknown; children?: unknown };\n return type === 'paragraph' && (!Array.isArray(children) || children.length === 0);\n });\n}\n\nfunction readElementSnapshot(element: Element): unknown {\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n return (element as HTMLInputElement).value;\n }\n if (element.tagName === 'IMG') return (element as HTMLImageElement).src;\n return element.textContent;\n}\n\nfunction isEmptyFieldValue(value: unknown): boolean {\n if (value === null || value === undefined) return true;\n if (typeof value === 'string') return value.trim().length === 0;\n return (Array.isArray(value) && value.length === 0) || isEmptyLexicalRoot(value);\n}\n","/**\n * One source → dependents map for `skipUnchanged`. Markup declares it the\n * other way round (`data-payload-depends=\"price\"` on the element bound to\n * `priceLabel`) because an author names what a binding needs; the runtime\n * option is keyed by source because the scheduler asks what changed.\n * @internal\n */\n\nexport type DependencyMap = Readonly<Record<string, readonly string[]>>;\n\n/**\n * Field names from an attribute value. Separators are commas and\n * whitespace; empty entries are dropped; order is kept, duplicates removed.\n * @internal\n */\nexport function parseDependencyList(value: string | null | undefined): readonly string[] {\n if (value === null || value === undefined) return [];\n const seen = new Set<string>();\n const names: string[] = [];\n for (const raw of value.split(/[\\s,]+/)) {\n const name = raw.trim();\n if (name.length === 0 || seen.has(name)) continue;\n seen.add(name);\n names.push(name);\n }\n return names;\n}\n\n/**\n * Merge dependency maps (source → dependents). Later maps add to earlier\n * ones; a dependent is listed once per source.\n * @internal\n */\nexport function mergeDependencyMaps(...maps: readonly DependencyMap[]): DependencyMap {\n const merged = new Map<string, Set<string>>();\n for (const map of maps) {\n for (const [source, dependents] of Object.entries(map)) {\n let bucket = merged.get(source);\n if (bucket === undefined) {\n bucket = new Set();\n merged.set(source, bucket);\n }\n for (const dependent of dependents) bucket.add(dependent);\n }\n }\n const result: Record<string, readonly string[]> = {};\n for (const [source, dependents] of merged) result[source] = [...dependents];\n return result;\n}\n\n/**\n * The map an element's `data-payload-depends` contributes: every declared\n * source points at this binding's field.\n * @internal\n */\nexport function dependencyMapFromBinding(\n fieldName: string,\n dependsOn: readonly string[],\n): DependencyMap {\n const map: Record<string, readonly string[]> = {};\n for (const source of dependsOn) {\n if (source === fieldName) continue;\n map[source] = [fieldName];\n }\n return map;\n}\n","/**\n * Hydrated islands own their subtree, so the runtime never patches inside one.\n * Instead every flush that carried a change dispatches `payload-live-preview:update`\n * on each island root with the update in `detail`, whether or not a binding\n * outside the islands was written. `data-payload-island=\"patch\"` opts back in.\n * Server HTML reaches an Astro island only through Astro's own props handoff\n * (ADR 0021). @internal\n */\n\nexport const ISLAND_EVENT = 'payload-live-preview:update';\n/** @internal */\nexport const ISLAND_ATTRIBUTE = 'data-payload-island';\nexport const ISLAND_SELECTOR = `astro-island, [${ISLAND_ATTRIBUTE}]`;\n/** The opt-out for a subtree the site scripts itself: the morph never enters it. @internal */\nexport const OWNED_ATTRIBUTE = 'data-payload-owned';\n/**\n * The opt-in for a custom element: present on the live and on the rendered host\n * (its value is ignored), the morph edits the host's attributes and light DOM\n * instead of retaining it whole (ADR 0008 §10). @internal\n */\nexport const MORPH_ATTRIBUTE = 'data-payload-morph';\n\n/**\n * The ownership rule (ADR 0008 §4): a subtree the morph never enters. Custom\n * elements own their subtree unless the template opts in with\n * `data-payload-morph` (§10), islands are a framework's, `contenteditable`\n * is the visitor's, `data-payload-owned` is the site's. The coordinators hand\n * this rule to the engine as `MorphOptions.boundary`; the engine itself only\n * pairs, edits and keeps focus (§9). @beta\n */\nexport function isMorphBoundary(element: Element): boolean {\n const customElement = element.tagName.toLowerCase().includes('-');\n if (customElement && !element.hasAttribute(MORPH_ATTRIBUTE)) return true;\n if (isIslandBoundary(element) || element.hasAttribute(OWNED_ATTRIBUTE)) return true;\n const editable = element.getAttribute('contenteditable');\n return editable !== null && editable !== 'false';\n}\n\nexport interface IslandUpdateDetail {\n readonly fields: Readonly<Record<string, unknown>>;\n readonly revision: number;\n readonly receivedAt: number;\n readonly locale: string | undefined;\n /**\n * Call once the island has rendered this revision, for instance from an\n * effect after its framework committed. Until every island handed the\n * revision has called it, `inspect().revisions.display` says `unconfirmed`\n * (ADR 0023). Repeated, late or superseded calls do nothing.\n */\n readonly displayed: () => void;\n}\n\nfunction isIslandRoot(element: Element): boolean {\n return element.tagName.toLowerCase() === 'astro-island' || element.hasAttribute(ISLAND_ATTRIBUTE);\n}\n\nfunction islandAllowsPatching(island: Element): boolean {\n return island.getAttribute(ISLAND_ATTRIBUTE) === 'patch';\n}\n\n/** Whether `element` itself is an island root that did not opt into patching. */\nexport function isIslandBoundary(element: Element): boolean {\n return isIslandRoot(element) && !islandAllowsPatching(element);\n}\n\n/** Whether `element` (or an ancestor) is an island that did not opt into patching. @internal */\nexport function isInsideIsland(element: Element): boolean {\n let current: Element | null = element;\n while (current !== null) {\n if (isIslandBoundary(current)) return true;\n current = current.parentElement;\n }\n return false;\n}\n\n/** Island roots under `root` that receive update events. */\nexport function collectIslands(root: ParentNode): Element[] {\n const islands: Element[] = [];\n for (const island of root.querySelectorAll(ISLAND_SELECTOR)) {\n if (!islandAllowsPatching(island)) islands.push(island);\n }\n return islands;\n}\n\n/** Astro keeps `ssr` until the framework listener has finished hydrating. @internal */\nexport function isAwaitingIslandHydration(island: Element): boolean {\n return island.tagName.toLowerCase() === 'astro-island' && island.hasAttribute('ssr');\n}\n\nexport function dispatchIslandUpdate(\n islands: readonly Element[],\n detail: IslandUpdateDetail,\n isCurrent: () => boolean,\n): number {\n let dispatched = 0;\n for (const island of islands) {\n if (!isCurrent()) break;\n island.dispatchEvent(\n new CustomEvent<IslandUpdateDetail>(ISLAND_EVENT, { detail, bubbles: false }),\n );\n dispatched += 1;\n if (!isCurrent()) break;\n }\n return dispatched;\n}\n\n/** What decides whether a live `astro-island` still renders the rendered one's component (ADR 0021). */\nconst ISLAND_IDENTITY = [\n 'component-url',\n 'component-export',\n 'renderer-url',\n 'client',\n 'opts',\n 'before-hydration-url',\n] as const;\n/** Slot markup each island was last rendered with; Astro reads slots once, at hydration. */\nconst renderedSlots = new WeakMap<Element, string>();\nconst unmountedIslands = new WeakSet<Element>();\n\nfunction isAstroIsland(element: Element): boolean {\n return element.tagName.toLowerCase() === 'astro-island';\n}\n\nfunction slotMarkup(island: Element): string {\n let markup = '';\n for (const slot of island.querySelectorAll('astro-slot, template[data-astro-template]')) {\n if (slot.parentElement?.closest('astro-island') !== island) continue;\n const name = slot.getAttribute('name') ?? slot.getAttribute('data-astro-template') ?? '';\n markup += `${name}\\u0000${slot.innerHTML}\\u0000`;\n }\n return markup;\n}\n\n/** Only an upgraded island whose class observes `props` re-hydrates in place. */\nfunction observesProps(island: Element): boolean {\n const constructor = island.ownerDocument.defaultView?.customElements.get('astro-island') as\n (CustomElementConstructor & { readonly observedAttributes?: unknown }) | undefined;\n return (\n constructor !== undefined &&\n island instanceof constructor &&\n Array.isArray(constructor.observedAttributes) &&\n constructor.observedAttributes.includes('props')\n );\n}\n\n/**\n * The package's decision for a boundary pair (ADR 0021). A boundary other than\n * an Astro island stays whole (ADR 0008 §4). An island that still renders the\n * same component, with the same slots, keeps its framework state: it takes the\n * rendered props the way Astro's router hands them to a persisted island,\n * `ssr` first, then `props`. Anything else is replaced, and hydrates fresh.\n * @beta\n */\nexport function retainIslandBoundary(live: Element, rendered: Element): boolean {\n if (!isAstroIsland(live) || !isAstroIsland(rendered)) return true;\n const slots = slotMarkup(rendered);\n const retained =\n ISLAND_IDENTITY.every((name) => live.getAttribute(name) === rendered.getAttribute(name)) &&\n (renderedSlots.get(live) ?? slotMarkup(live)) === slots &&\n (live.getAttribute('props') === rendered.getAttribute('props') || observesProps(live));\n if (!retained) {\n renderedSlots.set(rendered, slots);\n return false;\n }\n renderedSlots.set(live, slots);\n const props = rendered.getAttribute('props');\n if (props !== live.getAttribute('props')) {\n live.setAttribute('ssr', '');\n if (props === null) live.removeAttribute('props');\n else live.setAttribute('props', props);\n }\n return true;\n}\n\n/** The Astro islands under `root`, to compare before and after a morph. @internal */\nexport function astroIslandsIn(root: ParentNode): Element[] {\n return Array.from(root.querySelectorAll('astro-island'));\n}\n\n/**\n * Astro's framework clients release their roots on `astro:unmount`, which its\n * router sends after a swap. A morph that disconnects an island sends it once\n * itself, so a removed React root does not outlive its markup. @internal\n */\nexport function releaseDisconnectedIslands(islands: readonly Element[]): void {\n for (const island of islands) {\n if (island.isConnected || unmountedIslands.has(island)) continue;\n unmountedIslands.add(island);\n island.dispatchEvent(new CustomEvent('astro:unmount'));\n }\n}\n\n/**\n * Why an inserted island cannot start: fragment scripts never run, so the page\n * itself must have loaded Astro's island element and this client directive.\n * @internal\n */\nexport function islandStartBlocker(island: Element): 'element' | 'directive' | undefined {\n const view = island.ownerDocument.defaultView;\n if (view?.customElements.get('astro-island') === undefined) return 'element';\n const directive = island.getAttribute('client');\n const astro: unknown = Reflect.get(view, 'Astro');\n if (directive === null || typeof astro !== 'object' || astro === null) return 'directive';\n return Reflect.get(astro, directive) === undefined ? 'directive' : undefined;\n}\n","/**\n * Maps field names to their bound elements so an update walks the cache, not\n * the DOM. Everything an update needs about a binding is resolved here, once,\n * at build time.\n */\n\nimport {\n dependencyMapFromBinding,\n mergeDependencyMaps,\n parseDependencyList,\n type DependencyMap,\n} from './dependencies';\nimport { collectIslands } from './islands';\nimport { enclosingFragment, FRAGMENT_ATTRIBUTE, resolveStrategy } from './strategies';\nimport type { CachedElement, ElementPredicate, FieldType, RendererKey } from './types';\n\nexport const FIELD_ATTRIBUTE = 'data-payload-field';\nexport const TYPE_ATTRIBUTE = 'data-payload-type';\nexport const TARGET_ATTRIBUTE_ATTRIBUTE = 'data-payload-attribute';\nexport const HREF_ATTRIBUTE = 'data-payload-href';\nexport const SRC_ATTRIBUTE = 'data-payload-src';\nexport const ALT_ATTRIBUTE = 'data-payload-alt';\nexport const ARRAY_TEMPLATE_ATTRIBUTE = 'data-payload-array-template';\nexport const ARRAY_SEPARATOR_ATTRIBUTE = 'data-payload-array-separator';\nexport const LOCALE_ATTRIBUTE = 'data-payload-locale';\nexport const FORMAT_ATTRIBUTE = 'data-payload-format';\nexport const RICH_TEXT_ATTRIBUTE = 'data-payload-richtext';\nexport const HTML_ATTRIBUTE = 'data-payload-html';\nexport const ARRAY_ATTRIBUTE = 'data-payload-array';\nexport const STRUCTURAL_ATTRIBUTE = 'data-payload-structural';\nexport const OWNER_ATTRIBUTE = 'data-payload-owner';\nexport const DEPENDS_ATTRIBUTE = 'data-payload-depends';\nexport const STRATEGY_ATTRIBUTE = 'data-payload-strategy';\nexport const BOUNDARY_ATTRIBUTE = 'data-payload-boundary';\n/**\n * Written by the runtime, never by a template: the value an auto-binding\n * matched on (ADR 0014). Its presence is what tells a guessed binding from a\n * declared one, in `inspect()` and in the overlay.\n */\nexport const GUESSED_ATTRIBUTE = 'data-payload-guessed';\n/** Field paths a page accounts for without binding them, and everything below them (ADR 0022). */\nexport const COVERS_ATTRIBUTE = 'data-payload-covers';\nexport const INPUT_TYPE_ATTRIBUTE = 'type';\n\n/**\n * Attributes captured in a `CachedElement`. The mutation observer watches\n * exactly this list, so a snapshot can never go stale on a mounted element.\n */\nexport const BINDING_ATTRIBUTES: readonly string[] = [\n FIELD_ATTRIBUTE,\n TYPE_ATTRIBUTE,\n TARGET_ATTRIBUTE_ATTRIBUTE,\n HREF_ATTRIBUTE,\n SRC_ATTRIBUTE,\n ALT_ATTRIBUTE,\n ARRAY_TEMPLATE_ATTRIBUTE,\n ARRAY_SEPARATOR_ATTRIBUTE,\n LOCALE_ATTRIBUTE,\n FORMAT_ATTRIBUTE,\n RICH_TEXT_ATTRIBUTE,\n HTML_ATTRIBUTE,\n ARRAY_ATTRIBUTE,\n STRUCTURAL_ATTRIBUTE,\n OWNER_ATTRIBUTE,\n DEPENDS_ATTRIBUTE,\n STRATEGY_ATTRIBUTE,\n BOUNDARY_ATTRIBUTE,\n INPUT_TYPE_ATTRIBUTE,\n];\n\nconst FIELD_SELECTOR = `[${FIELD_ATTRIBUTE}]`;\nconst OWNER_SELECTOR = `[${OWNER_ATTRIBUTE}]`;\n/** Structural strategy roots whose arrival after navigation needs the retained document. @internal */\nexport const NAVIGATION_REPLAY_SELECTOR = `[${FRAGMENT_ATTRIBUTE}], [${STRATEGY_ATTRIBUTE}=\"route\"]`;\n\n/** The document a binding belongs to: its nearest `data-payload-owner`, itself included. */\nexport function resolveBindingOwner(element: Element): string | undefined {\n const owner = element.closest(OWNER_SELECTOR)?.getAttribute(OWNER_ATTRIBUTE);\n return owner === null || owner === undefined || owner.length === 0 ? undefined : owner;\n}\n\n/** `namespace:name` — a project renderer key can never be a typo of a built-in type. */\nconst CUSTOM_RENDERER_KEY = /^[a-z][a-z0-9-]*:[a-z][a-z0-9-]*$/i;\n\nconst VALID_FIELD_TYPES: ReadonlySet<FieldType> = new Set<FieldType>([\n 'text',\n 'textarea',\n 'richText',\n 'email',\n 'number',\n 'checkbox',\n 'date',\n 'select',\n 'radio',\n 'array',\n 'blocks',\n 'group',\n 'tabs',\n 'row',\n 'collapsible',\n 'relationship',\n 'upload',\n 'point',\n 'json',\n 'code',\n 'ui',\n 'html',\n 'url',\n 'image',\n 'structural-array',\n]);\n\nfunction isRendererKey(value: string): value is RendererKey {\n return VALID_FIELD_TYPES.has(value as FieldType) || CUSTOM_RENDERER_KEY.test(value);\n}\n\n/** One `data-payload-covers` declaration: the paths it names, for the owner it sits under. */\nexport interface CoverDeclaration {\n readonly paths: readonly string[];\n readonly owner: string | undefined;\n}\n\n/** The fields a fragment boundary or a route marker depends on, which its strategy renders. */\nexport interface RenderedDeclaration extends CoverDeclaration {\n readonly strategy: 'fragment' | 'route';\n}\n\n/**\n * The strategy that renders what an element depends on, by the planners' own\n * rules: the fragment planner takes every named boundary, the route planner a\n * route-bound element — marked `route`, or a binding in `<head>` left unmarked\n * (`src/fragment/boundary.ts`, `src/fragment/route.ts`). @internal\n */\nexport function renderingStrategy(element: Element): RenderedDeclaration['strategy'] | undefined {\n if ((element.getAttribute(FRAGMENT_ATTRIBUTE) ?? '').length > 0) return 'fragment';\n const explicit = element.getAttribute(STRATEGY_ATTRIBUTE);\n if (explicit !== null) return explicit === 'route' ? 'route' : undefined;\n return element.hasAttribute(FIELD_ATTRIBUTE) && element.closest('head') !== null\n ? 'route'\n : undefined;\n}\n\nexport interface CacheBuildStats {\n readonly elementCount: number;\n readonly fieldCount: number;\n readonly durationMs: number;\n}\n\nexport interface ElementCacheOptions {\n /** Restricts which elements are accepted. Defaults to all. */\n readonly filter?: ElementPredicate;\n}\n\n/** Metadata that decides whether buffered work still addresses the same owned strategy target. */\nexport function hasSameBindingIdentity(a: CachedElement, b: CachedElement): boolean {\n return (\n a.fieldName === b.fieldName &&\n a.locale === b.locale &&\n a.owner === b.owner &&\n a.strategyKind === b.strategyKind &&\n a.fragmentBoundary === b.fragmentBoundary\n );\n}\n\n/**\n * Elements share a field name when the same field is rendered in several\n * places; within a field the order is DOM order.\n */\nexport class ElementCache {\n private readonly entriesByField = new Map<string, CachedElement[]>();\n private entryByElement = new WeakMap<Element, CachedElement>();\n private readonly filter: ElementPredicate;\n private count = 0;\n private dependencies: DependencyMap | null = null;\n private islandRoots: readonly Element[] = [];\n private ownersByIsland: ReadonlyMap<Element, string | undefined> = new Map();\n private navigationRoots: readonly Element[] = [];\n private coverDeclarations: readonly CoverDeclaration[] = [];\n private renderedDeclarations: readonly RenderedDeclaration[] = [];\n\n constructor(options: ElementCacheOptions = {}) {\n this.filter = options.filter ?? alwaysTrue;\n }\n\n /** Source → dependents declared with `data-payload-depends`; memoised until the cache changes. */\n dependencyMap(): DependencyMap {\n if (this.dependencies !== null) return this.dependencies;\n const maps: DependencyMap[] = [];\n for (const binding of this.values()) {\n if (binding.dependsOn !== undefined) {\n maps.push(dependencyMapFromBinding(binding.fieldName, binding.dependsOn));\n }\n }\n this.dependencies = mergeDependencyMaps(...maps);\n return this.dependencies;\n }\n\n /** Island roots under the last built root, for update events. */\n get islands(): readonly Element[] {\n return this.islandRoots;\n }\n\n /** Owner identities captured with `islands`; used to detect a live retarget. @internal */\n get islandOwners(): ReadonlyMap<Element, string | undefined> {\n return this.ownersByIsland;\n }\n\n /** `data-payload-covers` declarations under the last built root. */\n get covers(): readonly CoverDeclaration[] {\n return this.coverDeclarations;\n }\n\n /** Boundaries and route markers under the last built root that name the fields they depend on. */\n get rendered(): readonly RenderedDeclaration[] {\n return this.renderedDeclarations;\n }\n\n /** Fieldless strategy roots under the last built root, for navigation replay. */\n get navigationReplayRoots(): readonly Element[] {\n return this.navigationRoots;\n }\n\n buildFromRoot(root: ParentNode): CacheBuildStats {\n const t0 = performance.now();\n this.clear();\n let elementCount = 0;\n for (const element of root.querySelectorAll(FIELD_SELECTOR)) {\n if (this.add(element) !== undefined) elementCount += 1;\n }\n this.islandRoots = collectIslands(root);\n this.ownersByIsland = new Map(\n this.islandRoots.map((island) => [island, resolveBindingOwner(island)]),\n );\n this.navigationRoots = [...root.querySelectorAll(NAVIGATION_REPLAY_SELECTOR)].filter(\n (element) =>\n this.filter(element) &&\n (element.hasAttribute(FRAGMENT_ATTRIBUTE) ||\n (element.getAttribute(FIELD_ATTRIBUTE) ?? '').length === 0),\n );\n this.coverDeclarations = [...root.querySelectorAll(`[${COVERS_ATTRIBUTE}]`)]\n .filter((element) => this.filter(element))\n .map((element) => ({\n paths: parseDependencyList(element.getAttribute(COVERS_ATTRIBUTE)),\n owner: resolveBindingOwner(element),\n }));\n this.renderedDeclarations = [...root.querySelectorAll(`[${DEPENDS_ATTRIBUTE}]`)]\n .filter((element) => this.filter(element))\n .flatMap((element): RenderedDeclaration[] => {\n const strategy = renderingStrategy(element);\n if (strategy === undefined) return [];\n const paths = parseDependencyList(element.getAttribute(DEPENDS_ATTRIBUTE));\n return [{ strategy, paths, owner: resolveBindingOwner(element) }];\n });\n return {\n elementCount,\n fieldCount: this.entriesByField.size,\n durationMs: performance.now() - t0,\n };\n }\n\n /**\n * Insert or replace a single element's binding. Re-adding refreshes the\n * snapshot in place; an element that is now filtered or unbound is removed.\n */\n add(element: Element): CachedElement | undefined {\n // Resolve before mutating so a throwing filter leaves the old entry intact.\n const entry = this.filter(element) ? this.resolveBinding(element) : undefined;\n const previous = this.entryByElement.get(element);\n this.dependencies = null;\n if (entry === undefined) {\n if (previous !== undefined) this.removeEntry(element, previous);\n return undefined;\n }\n if (previous !== undefined && this.replaceEntry(previous, entry)) {\n this.entryByElement.set(element, entry);\n return entry;\n }\n if (previous !== undefined) this.removeEntry(element, previous);\n this.append(entry);\n this.entryByElement.set(element, entry);\n return entry;\n }\n\n /** Returns whether a binding was removed. */\n remove(element: Element): boolean {\n const entry = this.entryByElement.get(element);\n if (!entry) return false;\n this.dependencies = null;\n return this.removeEntry(element, entry);\n }\n\n get(fieldName: string): readonly CachedElement[] | undefined {\n return this.entriesByField.get(fieldName);\n }\n\n getByElement(element: Element): CachedElement | undefined {\n return this.entryByElement.get(element);\n }\n\n get fieldCount(): number {\n return this.entriesByField.size;\n }\n\n get elementCount(): number {\n return this.count;\n }\n\n entries(): IterableIterator<[string, readonly CachedElement[]]> {\n return this.entriesByField.entries() as IterableIterator<[string, readonly CachedElement[]]>;\n }\n\n *values(): IterableIterator<CachedElement> {\n for (const bucket of this.entriesByField.values()) yield* bucket;\n }\n\n has(element: Element): boolean {\n return this.entryByElement.has(element);\n }\n\n clear(): void {\n this.entriesByField.clear();\n // WeakMap cannot be cleared; a detached element must not observe stale membership.\n this.entryByElement = new WeakMap();\n this.count = 0;\n this.dependencies = null;\n this.islandRoots = [];\n this.ownersByIsland = new Map();\n this.navigationRoots = [];\n this.coverDeclarations = [];\n this.renderedDeclarations = [];\n }\n\n /** Replace in place when the field bucket is unchanged, preserving order. */\n private replaceEntry(previous: CachedElement, next: CachedElement): boolean {\n if (previous.fieldName !== next.fieldName) return false;\n const bucket = this.entriesByField.get(previous.fieldName);\n const index = bucket === undefined ? -1 : bucket.indexOf(previous);\n if (bucket === undefined || index < 0) return false;\n bucket[index] = next;\n return true;\n }\n\n private removeEntry(element: Element, entry: CachedElement): boolean {\n this.entryByElement.delete(element);\n const bucket = this.entriesByField.get(entry.fieldName);\n const index = bucket === undefined ? -1 : bucket.indexOf(entry);\n if (bucket === undefined || index < 0) return false;\n bucket.splice(index, 1);\n if (bucket.length === 0) this.entriesByField.delete(entry.fieldName);\n this.count -= 1;\n return true;\n }\n\n private append(entry: CachedElement): void {\n const bucket = this.entriesByField.get(entry.fieldName);\n if (bucket) bucket.push(entry);\n else this.entriesByField.set(entry.fieldName, [entry]);\n this.count += 1;\n }\n\n private resolveBinding(element: Element): CachedElement | undefined {\n const fieldName = element.getAttribute(FIELD_ATTRIBUTE);\n if (fieldName === null || fieldName.length === 0) return undefined;\n const explicit = element.getAttribute(TYPE_ATTRIBUTE);\n const targetAttribute = element.getAttribute(TARGET_ATTRIBUTE_ATTRIBUTE);\n const hrefField = element.getAttribute(HREF_ATTRIBUTE);\n const srcField = element.getAttribute(SRC_ATTRIBUTE);\n const altField = element.getAttribute(ALT_ATTRIBUTE);\n const arrayTemplate = element.getAttribute(ARRAY_TEMPLATE_ATTRIBUTE);\n const arraySeparator = element.getAttribute(ARRAY_SEPARATOR_ATTRIBUTE);\n const locale = element.getAttribute(LOCALE_ATTRIBUTE);\n const format = element.getAttribute(FORMAT_ATTRIBUTE);\n const owner = resolveBindingOwner(element);\n const dependsOn = parseDependencyList(element.getAttribute(DEPENDS_ATTRIBUTE));\n const strategy = element.getAttribute(STRATEGY_ATTRIBUTE);\n const guessed = element.getAttribute(GUESSED_ATTRIBUTE);\n const fragmentBoundary = enclosingFragment(element);\n return {\n element,\n fieldName,\n fieldType: resolveFieldType(element),\n explicitFieldType: explicit !== null && isRendererKey(explicit),\n strategyKind: resolveStrategy(element) ?? 'unknown',\n ...(fragmentBoundary !== null ? { fragmentBoundary } : {}),\n ...(targetAttribute !== null && targetAttribute.length > 0 ? { targetAttribute } : {}),\n ...(hrefField !== null && hrefField.length > 0 ? { hrefField } : {}),\n ...(srcField !== null && srcField.length > 0 ? { srcField } : {}),\n ...(altField !== null && altField.length > 0 ? { altField } : {}),\n ...(arrayTemplate !== null ? { arrayTemplate } : {}),\n ...(arraySeparator !== null ? { arraySeparator } : {}),\n ...(locale !== null && locale.length > 0 ? { locale } : {}),\n ...(format !== null && format.length > 0 ? { format } : {}),\n ...(owner !== undefined ? { owner } : {}),\n ...(dependsOn.length > 0 ? { dependsOn } : {}),\n ...(strategy !== null && strategy.length > 0 ? { strategy } : {}),\n ...(element.hasAttribute(BOUNDARY_ATTRIBUTE) ? { hidesWhenEmpty: true } : {}),\n ...(guessed !== null ? { guessed } : {}),\n };\n }\n}\n\n/** Explicit `data-payload-type`, then element heuristics, then `text`. */\nexport function resolveFieldType(element: Element): RendererKey {\n const explicit = element.getAttribute(TYPE_ATTRIBUTE);\n if (explicit !== null && isRendererKey(explicit)) return explicit;\n if (element.hasAttribute(RICH_TEXT_ATTRIBUTE)) return 'richText';\n if (element.hasAttribute(HTML_ATTRIBUTE)) return 'html';\n if (element.hasAttribute(STRUCTURAL_ATTRIBUTE)) return 'structural-array';\n if (element.hasAttribute(ARRAY_ATTRIBUTE)) return 'array';\n if (element.tagName === 'IMG') return 'image';\n if (element.tagName === 'A') return 'url';\n if (element.tagName === 'TIME') return 'date';\n if (element.tagName === 'INPUT') {\n const inputType = (element as HTMLInputElement).type;\n if (inputType === 'checkbox') return 'checkbox';\n if (inputType === 'number') return 'number';\n if (inputType === 'date' || inputType === 'datetime-local') return 'date';\n }\n return 'text';\n}\n\nfunction alwaysTrue(): boolean {\n return true;\n}\n","/**\n * Payload 2 posts raw form values and a schema, rather than a server merge target.\n * Plan collection GETs from that schema and fill an independent document only\n * after every requested identity is present; the caller owns request cancellation.\n */\nimport type { PayloadFieldSchema } from '@/types/payload-protocol';\nimport { isPlainObject } from './message-guards';\n\nconst MAX_DEPTH = 64;\nconst MAX_NODES = 10_000;\nconst MAX_IDS = 1_000;\nconst MAX_REQUESTS = 64;\nconst MAX_URL = 8_192;\nconst MAX_BODY = 1_048_576;\nconst MAX_CHUNKS = 10_000;\nconst CHUNK = 20;\nconst FORBIDDEN = new Set(['__proto__', 'constructor', 'prototype']);\ntype RecordValue = Record<string, unknown>;\ninterface Slot {\n readonly owner: RecordValue | unknown[];\n readonly key: string | number;\n readonly id: string;\n}\nexport interface LegacyRequest {\n readonly url: string;\n readonly ids: ReadonlySet<string>;\n readonly slots: readonly Slot[];\n}\nexport interface LegacyPlan {\n readonly doc: RecordValue;\n readonly requests: readonly LegacyRequest[];\n}\n\nfunction fail(): never {\n throw new Error('invalid or oversized legacy population');\n}\nfunction hasControl(value: string): boolean {\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n if (code <= 31 || code === 127) return true;\n }\n return false;\n}\nfunction segment(value: unknown, maximum: number): value is string {\n if (\n typeof value !== 'string' ||\n value.length === 0 ||\n value.length > maximum ||\n value === '.' ||\n value === '..'\n ) {\n return false;\n }\n if (value.includes('/') || value.includes('\\\\') || hasControl(value)) return false;\n try {\n encodeURIComponent(value);\n return true;\n } catch {\n return false;\n }\n}\nfunction slug(value: unknown): value is string {\n return segment(value, 128) && !/[?#%]/u.test(value) && !FORBIDDEN.has(value);\n}\nfunction id(value: unknown): string {\n if (Number.isFinite(value)) return String(value);\n if (segment(value, 512)) return value;\n return fail();\n}\nfunction own(record: RecordValue | unknown[], key: string | number): unknown {\n return Object.hasOwn(record, key) ? Reflect.get(record, key) : undefined;\n}\nfunction put(record: RecordValue | unknown[], key: string | number, value: unknown): void {\n Object.defineProperty(record, key, {\n value,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n}\nfunction stripTrailingSlashes(value: string): string {\n let end = value.length;\n while (end > 0 && value.charCodeAt(end - 1) === 47) end -= 1;\n return value.slice(0, end);\n}\n\n/** Copy only structured data, bounded before the planner follows any relation. */\nexport function copyLegacyData(value: unknown): unknown {\n const active = new WeakSet();\n let nodes = 0;\n let characters = 0;\n function copy(value: unknown, depth: number): unknown {\n if (++nodes > MAX_NODES || depth > MAX_DEPTH) return fail();\n if (typeof value === 'string') {\n characters += value.length;\n if (characters > MAX_BODY) fail();\n return value;\n }\n if (value === null || value === undefined || typeof value === 'boolean') return value;\n if (typeof value === 'number') return Number.isFinite(value) ? value : fail();\n if (!Array.isArray(value) && !isPlainObject(value)) return fail();\n if (Array.isArray(value)) {\n if (value.length > MAX_NODES) fail();\n for (let index = 0; index < value.length; index += 1) {\n if (!Object.hasOwn(value, index)) fail();\n }\n }\n if (active.has(value)) return fail();\n active.add(value);\n const result: RecordValue | unknown[] = Array.isArray(value) ? [] : {};\n for (const key of Object.keys(value)) {\n put(result, key, copy(Reflect.get(value, key), depth + 1));\n }\n active.delete(value);\n return result;\n }\n return copy(value, 0);\n}\n\nexport function planLegacyPopulation(\n data: RecordValue,\n schema: readonly PayloadFieldSchema[],\n serverURL: string,\n apiRoute: string,\n depth: number,\n locale?: string,\n): LegacyPlan {\n if (!Number.isSafeInteger(depth) || depth < 0 || depth > MAX_DEPTH) return fail();\n if (\n locale !== undefined &&\n (typeof locale !== 'string' || locale.length > 128 || hasControl(locale))\n ) {\n fail();\n }\n const doc = copyLegacyData(data);\n if (!isPlainObject(doc)) return fail();\n const groups = new Map<string, Slot[]>();\n const unique = new Set<string>();\n let nodes = 0;\n const active = new WeakSet();\n const tick = (level: number): void => {\n if (++nodes > MAX_NODES || level > MAX_DEPTH) fail();\n };\n\n function relation(\n owner: RecordValue | unknown[],\n key: string | number,\n collection: string,\n value: unknown,\n ): void {\n if (value === null || value === undefined || value === '') return;\n const selected = isPlainObject(value) ? own(value, 'id') : value;\n const identity = id(selected);\n if (depth === 0) {\n put(owner, key, selected);\n return;\n }\n const scope = JSON.stringify([collection, identity]);\n unique.add(scope);\n if (unique.size > MAX_IDS) fail();\n const slots = groups.get(collection) ?? [];\n slots.push({ owner, key, id: identity });\n groups.set(collection, slots);\n }\n function fieldRelation(\n owner: RecordValue | unknown[],\n key: string | number,\n field: PayloadFieldSchema,\n ): void {\n if (field.hasMany !== undefined && typeof field.hasMany !== 'boolean') fail();\n const allowed = field.relationTo;\n const value = own(owner, key);\n if (Array.isArray(allowed)) {\n if (allowed.length === 0) fail();\n const collection = isPlainObject(value) ? own(value, 'relationTo') : undefined;\n let selectedCollection: string | undefined;\n for (const candidate of allowed) {\n tick(0);\n if (!slug(candidate)) fail();\n if (candidate === collection) selectedCollection = candidate;\n }\n if (value === null || value === undefined || value === '') return;\n if (!isPlainObject(value) || selectedCollection === undefined) fail();\n relation(value, 'value', selectedCollection, own(value, 'value'));\n } else {\n if (!slug(allowed)) fail();\n relation(owner, key, allowed, value);\n }\n }\n function rich(value: unknown, level: number): void {\n tick(level);\n if (!Array.isArray(value) && !isPlainObject(value)) return;\n if (\n isPlainObject(value) &&\n Object.hasOwn(value, 'relationTo') &&\n Object.hasOwn(value, 'value')\n ) {\n const collection = own(value, 'relationTo');\n if (!slug(collection)) fail();\n relation(value, 'value', collection, own(value, 'value'));\n return;\n }\n for (const key of Object.keys(value)) rich(Reflect.get(value, key), level + 1);\n }\n function walk(fields: readonly PayloadFieldSchema[], record: RecordValue, level: number): void {\n tick(level);\n if (active.has(fields)) fail();\n active.add(fields);\n for (const field of fields) {\n tick(level);\n if (!isPlainObject(field) || !segment(field.name, 512) || FORBIDDEN.has(field.name)) fail();\n const value = own(record, field.name);\n if (field.type === 'relationship' || field.type === 'upload') {\n if (field.hasMany) {\n if (value !== null && value !== undefined && !Array.isArray(value)) fail();\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i += 1) fieldRelation(value, i, field);\n } else fieldRelation(record, field.name, field);\n } else fieldRelation(record, field.name, field);\n } else if (field.type === 'group' || field.type === 'tabs') {\n if (value != null && !isPlainObject(value)) fail();\n if (isPlainObject(value) && field.fields) walk(field.fields, value, level + 1);\n } else if (field.type === 'row' || field.type === 'collapsible') {\n if (field.fields) walk(field.fields, record, level + 1);\n } else if (field.type === 'array' || field.type === 'blocks') {\n if (value === 0) put(record, field.name, []);\n else if (value != null && !Array.isArray(value)) fail();\n if (Array.isArray(value)) {\n for (const row of value) {\n if (!isPlainObject(row)) fail();\n if (field.type === 'array' && field.fields) walk(field.fields, row, level + 1);\n else if (field.type === 'blocks') {\n const blockType = own(row, 'blockType');\n const block = field.blocks?.find((candidate) => {\n tick(level);\n return candidate.slug === blockType;\n });\n if (block === undefined) fail();\n walk(block.fields, row, level + 1);\n }\n }\n }\n } else if (field.type === 'richText') rich(value, level + 1);\n }\n active.delete(fields);\n }\n walk(schema, doc, 0);\n if (groups.size > 25) fail();\n const requests: LegacyRequest[] = [];\n if (groups.size === 0) return { doc, requests };\n const base = new URL(serverURL);\n if (\n !['http:', 'https:'].includes(base.protocol) ||\n base.username ||\n base.password ||\n base.search ||\n base.hash\n ) {\n fail();\n }\n if (\n !apiRoute.startsWith('/') ||\n apiRoute.includes('\\\\') ||\n /[%?#]/u.test(apiRoute) ||\n hasControl(apiRoute)\n ) {\n fail();\n }\n if (apiRoute.split('/').some((part) => part === '.' || part === '..')) fail();\n const prefix = `${stripTrailingSlashes(serverURL)}${stripTrailingSlashes(apiRoute)}/`;\n for (const [collection, slots] of groups) {\n const identities = [...new Set(slots.map((slot) => slot.id))];\n let index = 0;\n while (index < identities.length) {\n const first = identities[index];\n if (first === undefined) fail();\n const comma = first.includes(',');\n const chunk: string[] = [];\n let url = '';\n while (index < identities.length && chunk.length < CHUNK) {\n const next = identities[index];\n if (next === undefined || (chunk.length > 0 && (comma || next.includes(',')))) break;\n const proposed = [...chunk, next];\n const query = new URLSearchParams({\n depth: String(depth),\n limit: String(proposed.length),\n });\n if (locale !== undefined) query.set('locale', locale);\n query.set(comma ? 'where[id][equals]' : 'where[id][in]', comma ? next : proposed.join(','));\n const candidate = `${prefix}${encodeURIComponent(collection)}?${query}`;\n if (candidate.length > MAX_URL) {\n if (chunk.length === 0) fail();\n break;\n }\n if (new URL(candidate).origin !== base.origin) fail();\n chunk.push(next);\n index += 1;\n url = candidate;\n }\n if (chunk.length === 0 || requests.length >= MAX_REQUESTS) fail();\n const ids = new Set(chunk);\n requests.push({\n url,\n ids,\n slots: slots.filter((slot) => ids.has(slot.id)),\n });\n }\n }\n return { doc, requests };\n}\n\n/** Native bodies stop at byte and chunk limits; injected json-only shims still get shape limits. */\nexport async function populationBody(\n response: Response,\n signal: AbortSignal,\n current: () => boolean,\n): Promise<unknown> {\n let reader: ReadableStreamDefaultReader<Uint8Array> | undefined;\n let cancelled = false;\n let finished = false;\n const obsolete = Symbol();\n let interrupt: (() => void) | undefined;\n const interrupted = new Promise<typeof obsolete>((resolve) => {\n interrupt = () => {\n resolve(obsolete);\n };\n });\n const check = (): void => {\n if (!current() || signal.aborted) fail();\n };\n const cancel = (): void => {\n if (reader === undefined || cancelled) return;\n cancelled = true;\n try {\n void Promise.resolve(reader.cancel()).catch(() => {\n /* teardown remains authoritative */\n });\n } catch {\n /* teardown remains authoritative */\n }\n };\n const abort = (): void => {\n interrupt?.();\n cancel();\n };\n signal.addEventListener('abort', abort, { once: true });\n try {\n check();\n const body = response.body ?? null;\n check();\n if (body === null) {\n const json: () => Promise<unknown> = response.json.bind(response);\n check();\n const value: unknown = await Promise.race([\n Promise.resolve().then(() => {\n check();\n return json();\n }),\n interrupted,\n ]);\n check();\n if (value === obsolete) fail();\n return value;\n }\n const getReader: () => ReadableStreamDefaultReader<Uint8Array> = body.getReader.bind(body);\n check();\n const activeReader = getReader();\n reader = activeReader;\n check();\n const chunks: Uint8Array[] = [];\n let bytes = 0;\n let count = 0;\n for (;;) {\n const pending = Promise.resolve().then(() => {\n check();\n const read = activeReader.read.bind(activeReader);\n check();\n return read();\n });\n const result = await Promise.race([pending, interrupted]);\n check();\n if (result === obsolete) fail();\n if (result.done) break;\n bytes += result.value.byteLength;\n if (++count > MAX_CHUNKS || bytes > MAX_BODY) fail();\n chunks.push(result.value);\n }\n finished = true;\n const data = new Uint8Array(bytes);\n let position = 0;\n for (const chunk of chunks) {\n data.set(chunk, position);\n position += chunk.byteLength;\n }\n try {\n return JSON.parse(new TextDecoder().decode(data));\n } catch {\n return fail();\n }\n } finally {\n signal.removeEventListener('abort', abort);\n if (!finished) cancel();\n try {\n reader?.releaseLock();\n } catch {\n /* a hostile pending read cannot own cleanup */\n }\n }\n}\n\nexport function fillLegacyPopulation(request: LegacyRequest, body: unknown): void {\n const safe = copyLegacyData(body);\n if (!isPlainObject(safe)) fail();\n const docs = own(safe, 'docs');\n if (!Array.isArray(docs) || docs.length > CHUNK) fail();\n const found = new Map<string, unknown>();\n for (const raw of docs) {\n if (!isPlainObject(raw)) fail();\n const identity = id(own(raw, 'id'));\n if (!request.ids.has(identity) || found.has(identity)) fail();\n found.set(identity, raw);\n }\n if (found.size !== request.ids.size) fail();\n for (const slot of request.slots) put(slot.owner, slot.key, found.get(slot.id));\n}\n","/**\n * Payload 3 raw form values use its REST merge with the method-override header.\n * Payload 2 sends a schema instead of a target, so it uses local values and\n * collection GETs to populate references. A newer merge aborts the one in flight,\n * and captured attempt identity drops obsolete results even when a shim ignores abort.\n * An optional deadline aborts a merge that has not answered in time.\n */\n\nimport { isolateDiagnostic, noopDiagnostic } from './diagnostics';\nimport type { PayloadFieldSchema } from '@/types/payload-protocol';\nimport { fillLegacyPopulation, planLegacyPopulation, populationBody } from './legacy-population';\n\nexport interface DataMergerOptions {\n /** Payload server origin, e.g. `https://cms.example.com`. */\n readonly serverURL: string;\n /** REST route prefix. Defaults to `/api`. */\n readonly apiRoute?: string;\n /** Population depth requested from the server. Defaults to `1`. */\n readonly depth?: number;\n readonly fetchFn?: typeof fetch;\n readonly log?: (...args: unknown[]) => void;\n /**\n * Milliseconds a merge may wait for the server before it is aborted and reported\n * `unavailable`. Off unless a positive finite number.\n */\n readonly timeoutMs?: number;\n}\n\nexport interface MergeRequest {\n readonly schema?: readonly PayloadFieldSchema[] | undefined;\n readonly collectionSlug?: string | undefined;\n readonly globalSlug?: string | undefined;\n readonly data: Record<string, unknown>;\n readonly locale?: string | undefined;\n}\n\n/** `superseded`: a newer merge replaced this one. `unavailable`: fall back to the raw values. */\nexport type MergeResult =\n | { readonly status: 'merged'; readonly doc: Record<string, unknown> }\n | { readonly status: 'superseded' }\n | { readonly status: 'unavailable' };\n\ninterface MergeTarget {\n readonly path: string;\n readonly field: 'id' | 'globalType';\n readonly value: string;\n}\n\nfunction hasControlCharacter(value: string): boolean {\n for (const character of value) {\n // An iterated character always has a code point; 0 keeps the type and fails closed.\n const codePoint = character.codePointAt(0) ?? 0;\n if (codePoint <= 0x1f || codePoint === 0x7f) return true;\n }\n return false;\n}\n\n/** One path segment: non-empty, bounded, not a dot segment, without separators or control characters. */\nfunction isPathSegment(value: string, maxLength: number): boolean {\n return (\n value.length > 0 &&\n value.length <= maxLength &&\n value !== '.' &&\n value !== '..' &&\n !value.includes('/') &&\n !value.includes('\\\\') &&\n !hasControlCharacter(value)\n );\n}\n\n/** A slug is one of Payload's own names; `?` and `#` never belong in one. */\nfunction isSafeSlug(value: string): boolean {\n return isPathSegment(value, 128) && !value.includes('?') && !value.includes('#');\n}\n\n/** An id comes from the form values; a string one is encoded, so `?` and `#` may appear. */\nfunction isSafeId(value: unknown): value is string | number {\n if (typeof value === 'number') return Number.isFinite(value);\n return typeof value === 'string' && isPathSegment(value, 512);\n}\n\n/**\n * Trailing slashes off a base URL, without a regular expression: `/\\/+$/`\n * backtracks over a long run of slashes and takes quadratic time on input the\n * page supplies (CodeQL js/polynomial-redos).\n */\n/** What the deadline rejects with: no fetch, body or shim rejects with this object. */\nconst TIMED_OUT = new Error();\n\nfunction withoutTrailingSlashes(value: string): string {\n let end = value.length;\n while (value.endsWith('/', end)) end -= 1;\n return value.slice(0, end);\n}\n\nexport class DataMerger {\n private readonly serverURL: string;\n private readonly apiRoute: string;\n private readonly depth: number;\n private readonly fetchFn: typeof fetch | undefined;\n private readonly log: (...args: unknown[]) => void;\n private readonly timeoutMs: number | undefined;\n private inflight: AbortController | null = null;\n private attempt = 0;\n private destroyDepth = 0;\n\n constructor(options: DataMergerOptions) {\n this.serverURL = withoutTrailingSlashes(options.serverURL);\n const route = options.apiRoute ?? '/api';\n this.apiRoute = route.startsWith('/') ? route : `/${route}`;\n this.depth = options.depth ?? 1;\n this.fetchFn = options.fetchFn;\n this.log = isolateDiagnostic(options.log ?? noopDiagnostic);\n const timeoutMs = options.timeoutMs ?? 0;\n this.timeoutMs = timeoutMs > 0 && timeoutMs < Number.POSITIVE_INFINITY ? timeoutMs : undefined;\n }\n\n /** A v2 schema plans local values and GETs; a v3 target needs its document identity. */\n canMerge(request: MergeRequest): boolean {\n try {\n const schema = request.schema;\n if (schema !== undefined) {\n planLegacyPopulation(\n request.data,\n schema,\n this.serverURL,\n this.apiRoute,\n this.depth,\n request.locale,\n );\n return true;\n }\n return this.endpointOf(request) !== null;\n } catch {\n return false;\n }\n }\n\n /**\n * The path and its response identity, or `null` when no safe one exists. A request\n * accessor that throws counts as none, and so does a lone surrogate, which\n * `encodeURIComponent` refuses with a `URIError`.\n */\n private endpointOf(request: MergeRequest): MergeTarget | null {\n try {\n // An empty global slug means \"collection document\" on the wire.\n const globalSlug = request.globalSlug;\n if (globalSlug) {\n return isSafeSlug(globalSlug)\n ? {\n path: `globals/${encodeURIComponent(globalSlug)}`,\n field: 'globalType',\n value: globalSlug,\n }\n : null;\n }\n const collectionSlug = request.collectionSlug ?? '';\n const id: unknown = request.data['id'];\n if (!isSafeSlug(collectionSlug) || !isSafeId(id)) return null;\n return {\n path: `${encodeURIComponent(collectionSlug)}/${encodeURIComponent(String(id))}`,\n field: 'id',\n value: String(id),\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Fulfills merged, superseded or unavailable. Supported request, fetch and\n * response failures are outcomes; isolated diagnostics cannot reject the merge.\n */\n async merge(request: MergeRequest): Promise<MergeResult> {\n if (this.destroyDepth > 0) return { status: 'superseded' };\n // Claim the attempt before aborting: abort listeners and fetch shims are\n // reentrant, and a newer merge they start must win. Nothing but this class\n // aborts the signal, and only after the counter moved, so the counter\n // alone decides who was superseded.\n const attempt = (this.attempt += 1);\n const previous = this.inflight;\n this.inflight = null;\n let controller: AbortController | null = null;\n let legacy = false;\n const superseded = (): boolean => this.attempt !== attempt;\n // Every wait on the server races one deadline, armed with the attempt's controller at its\n // first request; a shim that ignores the abort cannot hold the merge past it, and what it\n // answers later is never read.\n const timeoutMs = this.timeoutMs;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let deadline: Promise<never> | undefined;\n let timedOut = false;\n const expired = (): boolean => timedOut;\n const within = <T>(work: Promise<T>, owned: AbortController): Promise<T> => {\n if (timeoutMs === undefined) return work;\n if (deadline === undefined) {\n deadline = new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => {\n // First: a fetch that rejects as it is aborted must still read as the deadline.\n timedOut = true;\n owned.abort();\n reject(TIMED_OUT);\n }, timeoutMs);\n });\n deadline.catch(() => undefined);\n }\n return Promise.race([work, deadline]);\n };\n try {\n previous?.abort();\n if (superseded()) return { status: 'superseded' };\n const schema = request.schema;\n legacy = schema !== undefined;\n if (schema !== undefined) {\n const plan = planLegacyPopulation(\n request.data,\n schema,\n this.serverURL,\n this.apiRoute,\n this.depth,\n request.locale,\n );\n if (superseded()) return { status: 'superseded' };\n if (plan.requests.length === 0) return { status: 'merged', doc: plan.doc };\n const fetchFn = this.fetchFn ?? (typeof fetch === 'function' ? fetch : undefined);\n if (superseded()) return { status: 'superseded' };\n if (fetchFn === undefined) return { status: 'unavailable' };\n controller = new AbortController();\n this.inflight = controller;\n for (const population of plan.requests) {\n const response = await within(\n fetchFn(population.url, {\n method: 'GET',\n credentials: 'include',\n redirect: 'error',\n signal: controller.signal,\n }),\n controller,\n );\n if (superseded()) return { status: 'superseded' };\n const ok = response.ok;\n if (superseded()) return { status: 'superseded' };\n if (!ok) {\n const status = response.status;\n if (superseded()) return { status: 'superseded' };\n controller.abort();\n if (superseded()) return { status: 'superseded' };\n this.log('merge HTTP', status);\n return superseded() ? { status: 'superseded' } : { status: 'unavailable' };\n }\n const body = await within(\n populationBody(response, controller.signal, () => !superseded()),\n controller,\n );\n if (superseded()) return { status: 'superseded' };\n fillLegacyPopulation(population, body);\n if (superseded()) return { status: 'superseded' };\n }\n return { status: 'merged', doc: plan.doc };\n }\n // The endpoint reads the request's own values, which may be consumer\n // getters that start a newer merge before throwing.\n const endpoint = this.endpointOf(request);\n if (superseded()) return { status: 'superseded' };\n if (endpoint === null) return { status: 'unavailable' };\n const fetchFn = this.fetchFn ?? (typeof fetch === 'function' ? fetch : undefined);\n if (superseded()) return { status: 'superseded' };\n if (fetchFn === undefined) return { status: 'unavailable' };\n // Serialize before publishing the controller: accessors may accept newer work.\n const body = JSON.stringify({\n data: request.data,\n depth: this.depth,\n flattenLocales: false,\n locale: request.locale,\n });\n if (superseded()) return { status: 'superseded' };\n controller = new AbortController();\n this.inflight = controller;\n const url = `${this.serverURL}${this.apiRoute}/${endpoint.path}`;\n const response = await within(\n fetchFn(url, {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Payload-HTTP-Method-Override': 'GET',\n },\n // The admin already flattens locales before posting; an absent locale\n // is left out of the JSON.\n body,\n signal: controller.signal,\n }),\n controller,\n );\n // A fetch shim may ignore the signal; the attempt is authoritative.\n if (superseded()) return { status: 'superseded' };\n const ok = response.ok;\n if (superseded()) return { status: 'superseded' };\n if (!ok) {\n const status = response.status;\n if (superseded()) return { status: 'superseded' };\n this.log('merge HTTP', status, url);\n return superseded() ? { status: 'superseded' } : { status: 'unavailable' };\n }\n const json: () => Promise<unknown> = response.json.bind(response);\n if (superseded()) return { status: 'superseded' };\n const merged: unknown = await within(json(), controller);\n if (superseded()) return { status: 'superseded' };\n if (merged === null || typeof merged !== 'object' || Array.isArray(merged)) {\n this.log('merge invalid', url);\n return superseded() ? { status: 'superseded' } : { status: 'unavailable' };\n }\n const doc = merged as Record<string, unknown>;\n // Missing IDs remain compatible with projected responses. An explicit\n // identity must match the dispatched target, never mutable request data.\n const identity = doc[endpoint.field];\n const wrongIdentity =\n Object.hasOwn(doc, endpoint.field) &&\n (endpoint.field === 'id'\n ? !isSafeId(identity) || String(identity) !== endpoint.value\n : identity !== endpoint.value);\n if (superseded()) return { status: 'superseded' };\n if (wrongIdentity) {\n this.log('merge invalid', url);\n return superseded() ? { status: 'superseded' } : { status: 'unavailable' };\n }\n return { status: 'merged', doc };\n } catch (error) {\n if (superseded()) return { status: 'superseded' };\n if (expired()) {\n this.log('merge timeout', timeoutMs);\n return { status: 'unavailable' };\n }\n if (legacy) {\n controller?.abort();\n if (superseded()) return { status: 'superseded' };\n }\n this.log(\n 'merge exception',\n legacy ? new Error('legacy population could not be resolved') : error,\n );\n if (superseded()) return { status: 'superseded' };\n return { status: 'unavailable' };\n } finally {\n clearTimeout(timer);\n // Only the newest attempt's controller is ever in flight: a superseded\n // attempt's is gone already, and its successor's is left alone.\n if (this.inflight === controller) this.inflight = null;\n }\n }\n\n /** Abort any in-flight merge. The merger stays usable across a stop/start cycle. */\n destroy(): void {\n this.attempt += 1;\n const inflight = this.inflight;\n this.inflight = null;\n this.destroyDepth += 1;\n try {\n inflight?.abort();\n } finally {\n this.destroyDepth -= 1;\n }\n }\n}\n","/** The package version, read from package.json so the entries and the inline runtime cannot drift. */\n\nimport pkg from '../package.json' with { type: 'json' };\n\n/** @internal */\nexport const VERSION: string = pkg.version;\n","{\n \"name\": \"payload-live-preview\",\n \"version\": \"2.3.1\",\n \"description\": \"Live preview for Payload CMS on server-rendered and static frontends (Astro, Next.js, SvelteKit, Nuxt, plain HTML), with React and Vue hooks for client-rendered apps.\",\n \"author\": \"relative23\",\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"packageManager\": \"npm@12.0.2\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n },\n \"./core\": {\n \"import\": {\n \"types\": \"./dist/core.d.ts\",\n \"default\": \"./dist/core.js\"\n },\n \"require\": {\n \"types\": \"./dist/core.d.cts\",\n \"default\": \"./dist/core.cjs\"\n }\n },\n \"./astro\": {\n \"import\": {\n \"types\": \"./dist/adapters/astro/index.d.ts\",\n \"default\": \"./dist/adapters/astro/index.js\"\n }\n },\n \"./nextjs\": {\n \"import\": {\n \"types\": \"./dist/adapters/nextjs/index.d.ts\",\n \"default\": \"./dist/adapters/nextjs/index.js\"\n },\n \"default\": {\n \"types\": \"./dist/adapters/nextjs/index.d.ts\",\n \"default\": \"./dist/adapters/nextjs/index.js\"\n }\n },\n \"./sveltekit\": {\n \"import\": {\n \"types\": \"./dist/adapters/sveltekit/index.d.ts\",\n \"default\": \"./dist/adapters/sveltekit/index.js\"\n }\n },\n \"./nuxt\": {\n \"import\": {\n \"types\": \"./dist/adapters/nuxt/index.d.ts\",\n \"default\": \"./dist/adapters/nuxt/index.js\"\n }\n },\n \"./nuxt-module\": {\n \"import\": {\n \"types\": \"./dist/adapters/nuxt/module.d.ts\",\n \"default\": \"./dist/adapters/nuxt/module.js\"\n }\n },\n \"./react\": {\n \"import\": {\n \"types\": \"./dist/adapters/react/index.d.ts\",\n \"default\": \"./dist/adapters/react/index.js\"\n }\n },\n \"./vue\": {\n \"import\": {\n \"types\": \"./dist/adapters/vue/index.d.ts\",\n \"default\": \"./dist/adapters/vue/index.js\"\n }\n },\n \"./codegen\": {\n \"import\": {\n \"types\": \"./dist/codegen.d.ts\",\n \"default\": \"./dist/codegen.js\"\n },\n \"require\": {\n \"types\": \"./dist/codegen.d.cts\",\n \"default\": \"./dist/codegen.cjs\"\n }\n },\n \"./codegen/astro\": {\n \"import\": {\n \"types\": \"./dist/codegen-astro.d.ts\",\n \"default\": \"./dist/codegen-astro.js\"\n }\n },\n \"./annotate\": {\n \"import\": {\n \"types\": \"./dist/annotate.d.ts\",\n \"default\": \"./dist/annotate.js\"\n }\n },\n \"./doctor\": {\n \"import\": {\n \"types\": \"./dist/doctor.d.ts\",\n \"default\": \"./dist/doctor.js\"\n }\n },\n \"./migrate\": {\n \"import\": {\n \"types\": \"./dist/migrate.d.ts\",\n \"default\": \"./dist/migrate.js\"\n }\n },\n \"./payload\": {\n \"import\": {\n \"types\": \"./dist/payload.d.ts\",\n \"default\": \"./dist/payload.js\"\n },\n \"require\": {\n \"types\": \"./dist/payload.d.cts\",\n \"default\": \"./dist/payload.cjs\"\n }\n },\n \"./plugin\": {\n \"import\": {\n \"types\": \"./dist/plugin.d.ts\",\n \"default\": \"./dist/plugin.js\"\n },\n \"require\": {\n \"types\": \"./dist/plugin.d.cts\",\n \"default\": \"./dist/plugin.cjs\"\n }\n },\n \"./server\": {\n \"import\": {\n \"types\": \"./dist/server.d.ts\",\n \"default\": \"./dist/server.js\"\n },\n \"require\": {\n \"types\": \"./dist/server.d.cts\",\n \"default\": \"./dist/server.cjs\"\n }\n },\n \"./client\": {\n \"import\": {\n \"types\": \"./dist/client.d.ts\",\n \"default\": \"./dist/client.js\"\n },\n \"require\": {\n \"types\": \"./dist/client.d.cts\",\n \"default\": \"./dist/client.cjs\"\n }\n },\n \"./structural\": {\n \"import\": {\n \"types\": \"./dist/structural.d.ts\",\n \"default\": \"./dist/structural.js\"\n },\n \"require\": {\n \"types\": \"./dist/structural.d.cts\",\n \"default\": \"./dist/structural.cjs\"\n }\n },\n \"./lexical\": {\n \"import\": {\n \"types\": \"./dist/lexical.d.ts\",\n \"default\": \"./dist/lexical.js\"\n },\n \"require\": {\n \"types\": \"./dist/lexical.d.cts\",\n \"default\": \"./dist/lexical.cjs\"\n }\n },\n \"./plugins\": {\n \"import\": {\n \"types\": \"./dist/plugins.d.ts\",\n \"default\": \"./dist/plugins.js\"\n },\n \"require\": {\n \"types\": \"./dist/plugins.d.cts\",\n \"default\": \"./dist/plugins.cjs\"\n }\n },\n \"./lean\": {\n \"import\": {\n \"types\": \"./dist/lean.d.ts\",\n \"default\": \"./dist/lean.js\"\n },\n \"require\": {\n \"types\": \"./dist/lean.d.cts\",\n \"default\": \"./dist/lean.cjs\"\n }\n },\n \"./fragment\": {\n \"import\": {\n \"types\": \"./dist/fragment.d.ts\",\n \"default\": \"./dist/fragment.js\"\n },\n \"require\": {\n \"types\": \"./dist/fragment.d.cts\",\n \"default\": \"./dist/fragment.cjs\"\n }\n },\n \"./astro/RichText.astro\": \"./dist/adapters/astro/RichText.astro\",\n \"./astro/PreviewBoundary.astro\": \"./dist/adapters/astro/PreviewBoundary.astro\",\n \"./astro/middleware-entry\": {\n \"import\": {\n \"types\": \"./dist/adapters/astro/middleware-entry.d.ts\",\n \"default\": \"./dist/adapters/astro/middleware-entry.js\"\n }\n },\n \"./package.json\": \"./package.json\"\n },\n \"bin\": {\n \"pll-codegen\": \"./dist/codegen-cli.js\",\n \"pll\": \"./dist/doctor-cli.js\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"sideEffects\": false,\n \"scripts\": {\n \"build:runtime\": \"node -e \\\"const c=require('node:child_process'),e={...process.env};if(!e.SOURCE_DATE_EPOCH){const g=c.spawnSync('git',['show','-s','--format=%ct','HEAD'],{encoding:'utf8'});if(g.status===0)e.SOURCE_DATE_EPOCH=g.stdout.trim()}process.exit(c.spawnSync(process.execPath,['--import','tsx',process.argv[1]],{stdio:'inherit',env:e}).status??1)\\\" scripts/build-runtime.ts\",\n \"build\": \"npm run build:runtime && tsx scripts/build-dist.ts && npm run build:assets && npm run test:bundle && npm run test:treeshake && npm run test:edge && npm run test:interaction && npm run test:protocol-semantics\",\n \"build:assets\": \"node -e \\\"const fs=require('node:fs');for(const f of ['RichText','PreviewBoundary','FragmentBridge'])fs.copyFileSync('src/adapters/astro/'+f+'.astro','dist/adapters/astro/'+f+'.astro')\\\"\",\n \"dev\": \"tsup --watch\",\n \"pretest\": \"npm run build:runtime\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:security-corpus\": \"vitest run tests/unit/security/sanitizer-corpus.test.ts tests/unit/property/sanitizer-fuzz.property.test.ts\",\n \"test:unit\": \"vitest run tests/unit\",\n \"test:integration\": \"vitest run tests/integration\",\n \"test:e2e\": \"playwright test\",\n \"test:e2e:next-base-path\": \"playwright test --config playwright.next-base-path.config.ts\",\n \"test:e2e:next-production\": \"playwright test --config playwright.next-production.config.ts\",\n \"test:e2e:next-webpack-production\": \"playwright test --config playwright.next-webpack-production.config.ts\",\n \"test:e2e:next-continuation\": \"playwright test --config playwright.next-continuation.config.ts\",\n \"test:e2e:sveltekit-continuation\": \"playwright test --config playwright.sveltekit-continuation.config.ts\",\n \"test:e2e:nuxt-continuation\": \"playwright test --config playwright.nuxt-continuation.config.ts\",\n \"test:e2e:astro-continuation\": \"playwright test --config playwright.astro-continuation.config.ts\",\n \"test:e2e:astro-resources\": \"playwright test --config playwright.astro-resources.config.ts\",\n \"test:e2e:html-continuation\": \"playwright test --config playwright.html-continuation.config.ts\",\n \"test:e2e:vue-continuation\": \"playwright test --config playwright.vue-continuation.config.ts\",\n \"test:e2e:react-continuation\": \"playwright test --config playwright.react-continuation.config.ts\",\n \"test:e2e:nuxt-production\": \"playwright test --config playwright.nuxt-production.config.ts\",\n \"test:e2e:sveltekit-production\": \"playwright test --config playwright.sveltekit-production.config.ts\",\n \"check:fixtures\": \"tsx scripts/check-fixture-freshness.ts\",\n \"check:generated\": \"tsx scripts/check-generated-runtime.ts\",\n \"test:e2e:real-payload\": \"playwright test --config playwright.real-payload.config.ts\",\n \"test:acl:real-payload\": \"tsx scripts/check-payload-acl.ts\",\n \"test:a11y\": \"playwright test tests/e2e/specs/accessibility.spec.ts\",\n \"test:soak\": \"playwright test --config playwright.soak.config.ts\",\n \"test:browser-bench\": \"playwright test --config playwright.bench.config.ts\",\n \"test:bench\": \"vitest bench tests/benchmarks\",\n \"test:bench:codspeed\": \"vitest bench --run --config vitest.bench.config.ts\",\n \"test:bundle\": \"tsx scripts/check-bundle-size.ts\",\n \"test:interaction\": \"tsx scripts/check-interaction-budgets.ts\",\n \"test:protocol-semantics\": \"tsx scripts/check-protocol-semantics.ts\",\n \"test:upstream-findings\": \"tsx scripts/check-upstream-findings.ts\",\n \"test:treeshake\": \"tsx scripts/check-tree-shaking.ts\",\n \"test:edge\": \"NODE_OPTIONS='--experimental-vm-modules --no-warnings' tsx scripts/check-edge-runtime.ts\",\n \"compat:check\": \"tsx scripts/compat-table.ts --check\",\n \"compat:write\": \"tsx scripts/compat-table.ts --write\",\n \"compat:refresh\": \"tsx scripts/compat-table.ts --refresh\",\n \"compat:record\": \"tsx scripts/record-compat-results.ts && prettier --write quality/compat-matrix.json && tsx scripts/compat-table.ts --write && prettier --write README.md\",\n \"diagnostics:check\": \"tsx scripts/diagnostic-table.ts --check\",\n \"test:package\": \"tsx scripts/check-package.ts\",\n \"audit:gate\": \"tsx scripts/audit-gate.ts\",\n \"test:smoke\": \"tsx scripts/post-publish-smoke.ts\",\n \"test:coverage\": \"vitest run --coverage\",\n \"test:coverage:diff\": \"tsx scripts/coverage-policy.ts\",\n \"test:policy\": \"tsx scripts/test-policy.ts\",\n \"test:architecture\": \"tsx scripts/architecture-policy.ts && tsx scripts/check-complexity.ts && tsx scripts/check-trusted-core.ts && tsx scripts/compare-scope.ts --check && tsx scripts/workflow-contracts.ts && tsx scripts/docs-contracts.ts && tsx scripts/check-resource-inventory.ts && knip --no-progress --treat-config-hints-as-errors\",\n \"test:property\": \"vitest run tests/unit/property\",\n \"test:mutation\": \"stryker run stryker.config.js\",\n \"test:mutation:policy:pr\": \"tsx scripts/mutation-policy.ts --policy quality/mutation-policy-pr.json --report test-results/stryker-pr.json\",\n \"test:mutation:policy:core\": \"tsx scripts/mutation-policy.ts --policy quality/mutation-policy-core.json --report test-results/stryker-core.json\",\n \"test:mutation:policy\": \"tsx scripts/mutation-policy.ts\",\n \"test:leak\": \"node --expose-gc --import tsx scripts/leak-soak.ts\",\n \"test:leak:quick\": \"node --expose-gc --import tsx scripts/leak-soak.ts --quick\",\n \"api:update\": \"npm run build && tsx scripts/check-package.ts --update-api-reports\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"eslint .\",\n \"lint:fix\": \"eslint . --fix\",\n \"format\": \"prettier --write \\\"src/**/*.ts\\\" \\\"tests/**/*.ts\\\" \\\"scripts/**/*.ts\\\" \\\"*.{js,cjs,mjs,ts,json,jsonc,yml,yaml,md}\\\" \\\"quality/**/*.json\\\" \\\"docs/**/*.md\\\" \\\"type-tests/**/*.md\\\" \\\".prettierrc.json\\\" \\\".changeset/*.{json,md}\\\" \\\".github/**/*.{yml,yaml,json}\\\" \\\"examples/**/*.{ts,tsx,js,cjs,mjs,json}\\\" && prettier --write \\\"type-tests/packed/*.fixture\\\" --parser typescript\",\n \"format:check\": \"prettier --check \\\"src/**/*.ts\\\" \\\"tests/**/*.ts\\\" \\\"scripts/**/*.ts\\\" \\\"*.{js,cjs,mjs,ts,json,jsonc,yml,yaml,md}\\\" \\\"quality/**/*.json\\\" \\\"docs/**/*.md\\\" \\\"type-tests/**/*.md\\\" \\\".prettierrc.json\\\" \\\".changeset/*.{json,md}\\\" \\\".github/**/*.{yml,yaml,json}\\\" \\\"examples/**/*.{ts,tsx,js,cjs,mjs,json}\\\" && prettier --check \\\"type-tests/packed/*.fixture\\\" --parser typescript\",\n \"check\": \"npm run typecheck && npm run lint && npm run format:check && npm run test:policy && npm run test:architecture && npm run compat:check && npm run diagnostics:check && npm run test\",\n \"prepublishOnly\": \"npm run build && npm run check && npm run format:check && npm run test:package\",\n \"changeset\": \"changeset\",\n \"version\": \"changeset version && tsx scripts/sync-lockfile-metadata.ts && npm run build:runtime\",\n \"version:release\": \"npm run version && npm run compat:record\",\n \"release\": \"tsx scripts/publish-artifact.ts\",\n \"test:docs\": \"tsx scripts/docs-contracts.ts\"\n },\n \"devDependencies\": {\n \"@arethetypeswrong/cli\": \"^0.18.5\",\n \"@axe-core/playwright\": \"^4.13.0\",\n \"@changesets/cli\": \"^2.31.1\",\n \"@codspeed/vitest-plugin\": \"^5.7.1\",\n \"@eslint/js\": \"^10.0.1\",\n \"@fast-check/vitest\": \"^0.4.1\",\n \"@microsoft/api-extractor\": \"^7.58.12\",\n \"@payloadcms/live-preview\": \"^3.88.0\",\n \"@playwright/test\": \"^1.62.1\",\n \"@stryker-mutator/core\": \"^9.6.1\",\n \"@stryker-mutator/vitest-runner\": \"^9.6.1\",\n \"@testing-library/react\": \"^16.3.3\",\n \"@types/jsdom\": \"^30.0.0\",\n \"@types/node\": \"^22.20.1\",\n \"@types/react\": \"^19.2.18\",\n \"@types/react-dom\": \"^19.2.7\",\n \"@vitest/coverage-v8\": \"^4.1.12\",\n \"dompurify\": \"^3.4.15\",\n \"esbuild\": \"^0.28.2\",\n \"eslint\": \"^10.8.1\",\n \"fast-check\": \"^4.9.0\",\n \"globals\": \"^17.11.0\",\n \"jsdom\": \"^29.1.1\",\n \"knip\": \"^6.32.2\",\n \"linkedom\": \"^0.18.14\",\n \"prettier\": \"^3.9.6\",\n \"publint\": \"^0.3.23\",\n \"react\": \"^19.3.1\",\n \"react-dom\": \"^19.3.1\",\n \"svelte\": \"^5.57.3\",\n \"terser\": \"^5.46.1\",\n \"ts-morph\": \"^28.0.0\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.23.12\",\n \"typescript\": \"^5.9.3\",\n \"typescript-eslint\": \"^8.67.0\",\n \"vite\": \"^7.3.6\",\n \"vitest\": \"^4.1.12\",\n \"vue\": \"^3.5.44\",\n \"yaml\": \"^2.9.0\"\n },\n \"overrides\": {\n \"qs\": \"6.16.1\",\n \"tsup\": {\n \"esbuild\": \"0.28.2\"\n }\n },\n \"allowScripts\": {\n \"esbuild@0.28.2\": true,\n \"fsevents@2.3.2\": false,\n \"fsevents@2.3.3\": false\n },\n \"keywords\": [\n \"astro\",\n \"astro-payload\",\n \"astro-cms\",\n \"astro-integration\",\n \"astro-live-preview\",\n \"payload\",\n \"payload-cms\",\n \"payload-plugin\",\n \"payload-live-preview\",\n \"live-preview\",\n \"preview\",\n \"cms\",\n \"headless\",\n \"headless-cms\",\n \"lexical\",\n \"sveltekit\",\n \"nuxt\",\n \"nextjs\",\n \"react\",\n \"vue\",\n \"ssr\",\n \"framework-agnostic\"\n ],\n \"peerDependencies\": {\n \"astro\": \">=4.0.0 <8.0.0\",\n \"payload\": \"^2.0.0 || ^3.0.0 || ^4.0.0-0\",\n \"react\": \">=18\",\n \"react-dom\": \">=18\",\n \"svelte\": \">=5\",\n \"ts-morph\": \"^28.0.0\",\n \"vite\": \">=5.4.0 <9.0.0\",\n \"vue\": \">=3.3\"\n },\n \"peerDependenciesMeta\": {\n \"astro\": {\n \"optional\": true\n },\n \"payload\": {\n \"optional\": true\n },\n \"react\": {\n \"optional\": true\n },\n \"react-dom\": {\n \"optional\": true\n },\n \"svelte\": {\n \"optional\": true\n },\n \"ts-morph\": {\n \"optional\": true\n },\n \"vue\": {\n \"optional\": true\n },\n \"vite\": {\n \"optional\": true\n }\n },\n \"engines\": {\n \"node\": \">=20.19.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"provenance\": true\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/relative23/payload-live-preview.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/relative23/payload-live-preview/issues\"\n },\n \"homepage\": \"https://github.com/relative23/payload-live-preview#readme\"\n}\n","/**\n * What the peer does, derived from the capabilities its messages showed —\n * the runtime never asks which Payload version it is talking to. Unknown\n * until the admin reveals its shape. See ADR 0010.\n */\nimport type { ProtocolCapability } from './protocol-version';\n\nexport type ProtocolProfileName = 'unknown' | 'payload-2' | 'payload-3';\n\nexport interface ProtocolProfile {\n readonly name: ProtocolProfileName;\n /** Where field types come from. */\n readonly fieldTyping: 'schema' | 'heuristic';\n /**\n * Legacy transport label, retained for 2.x compatibility. `admin` identifies\n * Payload 2's schema-based path; observed messages can contain raw relation IDs,\n * which the shared merger populates with collection GETs. `server` identifies\n * the Payload 3 merge path. This label alone does not describe population state.\n */\n readonly populatesRelationships: 'admin' | 'server';\n /** Whether the peer reports document saves and relationship edits. */\n readonly documentEvents: boolean;\n}\n\nconst PAYLOAD_2: ProtocolProfile = {\n name: 'payload-2',\n fieldTyping: 'schema',\n populatesRelationships: 'admin',\n documentEvents: false,\n};\nconst PAYLOAD_3: ProtocolProfile = {\n name: 'payload-3',\n fieldTyping: 'heuristic',\n populatesRelationships: 'server',\n documentEvents: true,\n};\nconst UNKNOWN: ProtocolProfile = {\n name: 'unknown',\n fieldTyping: 'heuristic',\n populatesRelationships: 'server',\n documentEvents: false,\n};\n\n/**\n * `schema-json` on the wire is the Payload 2.x signature: 3.x removed\n * `fieldSchemaJSON`. Document or relationship events are 3.x-only. Until\n * either shows, the peer is unknown and treated like 3.x for merging — the\n * conservative choice, because a needless REST merge costs a request while\n * a missing one loses populated relationships.\n */\nexport function detectProtocolProfile(observed: ReadonlySet<ProtocolCapability>): ProtocolProfile {\n if (observed.has('schema-json')) return PAYLOAD_2;\n if (observed.has('document-events') || observed.has('relationship-events')) return PAYLOAD_3;\n return UNKNOWN;\n}\n","/**\n * Mutation and intersection observers: ask the host to rebuild the cache when\n * bindings appear, vanish or change metadata, and track which bound elements\n * are in the viewport so off-screen writes can wait. Kept apart from cache and\n * scheduler so tests can run without the browser observer APIs.\n */\n\nimport {\n BINDING_ATTRIBUTES,\n COVERS_ATTRIBUTE,\n DEPENDS_ATTRIBUTE,\n FIELD_ATTRIBUTE,\n NAVIGATION_REPLAY_SELECTOR,\n OWNER_ATTRIBUTE,\n} from './cache';\nimport { ISLAND_ATTRIBUTE, ISLAND_SELECTOR } from './islands';\n\nexport interface ObserverCallbacks {\n readonly onStructuralChange: () => void;\n readonly onIslandHydrated?: (island: Element) => void;\n readonly onVisibilityChange: (element: Element, isVisible: boolean) => void;\n}\n\nexport interface ObserverOptions {\n /** Debounce for mutation batches in ms. Default 100. */\n readonly mutationDebounceMs?: number;\n /** `rootMargin` for the IntersectionObserver. Default `200px`. */\n readonly intersectionRootMargin?: string;\n}\n\nconst DEFAULT_DEBOUNCE_MS = 100;\nconst DEFAULT_ROOT_MARGIN = '200px';\nconst ASTRO_SSR_ATTRIBUTE = 'ssr';\n/** `nodeType` is stable across realms; the global `Node` constructor is not. */\nconst ELEMENT_NODE = 1;\n/**\n * Read from elements that need not be bindings: the field, the owner a binding\n * inherits, and what a page declares it accounts for — `data-payload-covers`\n * anywhere, `data-payload-depends` on a boundary or route marker (ADR 0022).\n */\nconst WATCHED_ANYWHERE: readonly string[] = [\n FIELD_ATTRIBUTE,\n OWNER_ATTRIBUTE,\n COVERS_ATTRIBUTE,\n DEPENDS_ATTRIBUTE,\n];\nconst TRACKED_SELECTOR = `[${FIELD_ATTRIBUTE}], [${COVERS_ATTRIBUTE}], ${ISLAND_SELECTOR}, ${NAVIGATION_REPLAY_SELECTOR}`;\n\nexport class ObserverManager {\n private readonly callbacks: ObserverCallbacks;\n private readonly debounceMs: number;\n private readonly rootMargin: string;\n private readonly visible = new Set<Element>();\n private mutation: MutationObserver | null = null;\n private intersection: IntersectionObserver | null = null;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n /** Bumped by every start/stop so deliveries from an older lifetime are inert. */\n private generation = 0;\n\n constructor(callbacks: ObserverCallbacks, options: ObserverOptions = {}) {\n this.callbacks = callbacks;\n this.debounceMs = options.mutationDebounceMs ?? DEFAULT_DEBOUNCE_MS;\n this.rootMargin = options.intersectionRootMargin ?? DEFAULT_ROOT_MARGIN;\n }\n\n /** Observe `root`; a repeated start hands over cleanly. */\n start(root: Node): void {\n const previousGeneration = this.generation;\n this.stop();\n const generation = previousGeneration + 1;\n // A disconnect hook may have started a newer generation; it owns the lifecycle.\n if (this.generation !== generation) return;\n let mutation: MutationObserver | null = null;\n let intersection: IntersectionObserver | null = null;\n try {\n mutation = new MutationObserver((mutations) => {\n this.handleMutations(mutations, generation);\n });\n // Both resources exist before either is live, so a missing IntersectionObserver leaves nothing behind.\n intersection = new IntersectionObserver(\n (entries) => {\n this.handleIntersection(entries, generation);\n },\n { rootMargin: this.rootMargin, threshold: 0 },\n );\n mutation.observe(root, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\n ...BINDING_ATTRIBUTES,\n COVERS_ATTRIBUTE,\n ISLAND_ATTRIBUTE,\n ASTRO_SSR_ATTRIBUTE,\n ],\n });\n } catch (error) {\n mutation?.disconnect();\n intersection?.disconnect();\n throw error;\n }\n if (this.generation !== generation) {\n mutation.disconnect();\n intersection.disconnect();\n return;\n }\n this.mutation = mutation;\n this.intersection = intersection;\n }\n\n observeElement(element: Element): void {\n this.intersection?.observe(element);\n }\n\n unobserveElement(element: Element): void {\n this.intersection?.unobserve(element);\n this.visible.delete(element);\n }\n\n /** Seed visibility (tests). */\n markVisible(element: Element, visible: boolean): void {\n if (visible) this.visible.add(element);\n else this.visible.delete(element);\n }\n\n isVisible(element: Element): boolean {\n return this.visible.has(element);\n }\n\n /** Disconnect everything; safe to repeat. */\n stop(): void {\n // Invalidate first so queued deliveries and the timer are inert before disconnecting.\n this.generation += 1;\n const timer = this.debounceTimer;\n const mutation = this.mutation;\n const intersection = this.intersection;\n this.debounceTimer = null;\n this.mutation = null;\n this.intersection = null;\n this.visible.clear();\n if (timer !== null) clearTimeout(timer);\n try {\n mutation?.disconnect();\n } finally {\n intersection?.disconnect();\n }\n }\n\n private handleMutations(mutations: readonly MutationRecord[], generation: number): void {\n if (!this.isCurrentGeneration(generation)) return;\n for (const mutation of mutations) {\n const island = hydratedAstroIsland(mutation);\n if (island === null) continue;\n this.callbacks.onIslandHydrated?.(island);\n if (!this.isCurrentGeneration(generation)) return;\n }\n if (!hasStructuralImpact(mutations)) return;\n if (this.debounceTimer !== null) clearTimeout(this.debounceTimer);\n const timer = setTimeout(() => {\n if (!this.isCurrentGeneration(generation) || this.debounceTimer !== timer) return;\n this.debounceTimer = null;\n this.callbacks.onStructuralChange();\n }, this.debounceMs);\n this.debounceTimer = timer;\n }\n\n private handleIntersection(\n entries: readonly IntersectionObserverEntry[],\n generation: number,\n ): void {\n for (const entry of entries) {\n if (!this.isCurrentGeneration(generation)) return;\n const { target } = entry;\n if (entry.isIntersecting) {\n if (this.visible.has(target)) continue;\n this.visible.add(target);\n this.callbacks.onVisibilityChange(target, true);\n } else if (this.visible.has(target)) {\n this.visible.delete(target);\n this.callbacks.onVisibilityChange(target, false);\n }\n }\n }\n\n private isCurrentGeneration(generation: number): boolean {\n return this.generation === generation && this.intersection !== null;\n }\n}\n\nfunction hydratedAstroIsland(mutation: MutationRecord): Element | null {\n if (\n mutation.type !== 'attributes' ||\n mutation.attributeName !== ASTRO_SSR_ATTRIBUTE ||\n mutation.target.nodeType !== ELEMENT_NODE\n ) {\n return null;\n }\n const target = mutation.target as Element;\n return target.tagName.toLowerCase() === 'astro-island' &&\n !target.hasAttribute(ASTRO_SSR_ATTRIBUTE)\n ? target\n : null;\n}\n\n/** Whether a mutation batch can change what is bound; unrelated DOM activity never rebuilds. */\nfunction hasStructuralImpact(mutations: readonly MutationRecord[]): boolean {\n for (const m of mutations) {\n if (m.type === 'attributes' && m.attributeName === ISLAND_ATTRIBUTE) return true;\n if (m.type === 'attributes' && m.attributeName !== null) {\n if (WATCHED_ANYWHERE.includes(m.attributeName)) return true;\n // Other metadata (notably the native `type`) matters only on an element\n // that is a binding.\n if (\n BINDING_ATTRIBUTES.includes(m.attributeName) &&\n m.target.nodeType === ELEMENT_NODE &&\n (m.target as Element).hasAttribute(FIELD_ATTRIBUTE)\n ) {\n return true;\n }\n }\n for (const node of m.addedNodes) if (containsTrackedElement(node)) return true;\n for (const node of m.removedNodes) if (containsTrackedElement(node)) return true;\n }\n return false;\n}\n\nfunction containsTrackedElement(node: Node): boolean {\n if (node.nodeType !== ELEMENT_NODE) return false;\n const element = node as Element;\n return element.matches(TRACKED_SELECTOR) || element.querySelector(TRACKED_SELECTOR) !== null;\n}\n","/**\n * A lifetime scope: what is owned inside it is released together, in reverse\n * order, when it closes, each release guarded so one that throws does not\n * stop the rest. The runtime opens one per session (`start()`) and closes it\n * on `destroy()`, `suspend()` and a failed start alike (ADR 0005, 2.1 note).\n * The plugin manager's `ResourceScope` is the same idea with staging, commit\n * and per-kind counts on top; this is the form the inline runtime carries.\n */\n\nexport type Release = () => void;\n\nexport class LifetimeScope {\n readonly #owned: Release[] = [];\n readonly #log: (...args: unknown[]) => void;\n #closed = false;\n\n constructor(log: (...args: unknown[]) => void) {\n this.#log = log;\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n\n /** Own a release; a closed scope runs it at once. */\n own(release: Release): void {\n if (this.#closed) {\n this.#run(release);\n return;\n }\n this.#owned.push(release);\n }\n\n /** Release everything owned, the last first; idempotent. */\n close(): void {\n if (this.#closed) return;\n this.#closed = true;\n const owned = this.#owned.splice(0).reverse();\n for (const release of owned) this.#run(release);\n }\n\n #run(release: Release): void {\n try {\n release();\n } catch (error) {\n this.#log('runtime cleanup failed:', error);\n }\n }\n}\n","/**\n * Waiting for React before the first write (ADR 0015).\n *\n * A page a framework hydrates is not final when it is parsed: the client\n * bundle arrives later, walks the server markup and compares it with what it\n * would have rendered. A value the runtime wrote in between is a mismatch —\n * React 19 throws, discards the tree under the nearest Suspense boundary,\n * renders it again on the client, and the write is gone with it. Measured on\n * the Next fixture on 2026-09-11: the write at 93 ms, React's fiber on the\n * bound element at 174 ms, `Hydration failed` at 180 ms.\n *\n * Neither Next nor React says when hydration is done. What React does expose,\n * since 16 and for its own DevTools, is its instrumentation protocol: when\n * `react-dom` evaluates it looks for `window.__REACT_DEVTOOLS_GLOBAL_HOOK__`,\n * calls `inject()` if the hook says `supportsFiber`, and from then on\n * `onCommitFiberRoot(rendererId, root)` after every commit — each call guarded\n * by `typeof … === 'function'` and a `try`. The first commit of a root that\n * holds a binding and no longer has dehydrated server boundaries is the moment\n * React has taken the markup over; everything before it is too early, and a\n * commit into a root without a binding (Next's dev overlay commits three times\n * before the app does) is not ours to wait for.\n *\n * Two bundles read this: the runtime, which arms the hook when it starts, and\n * the bootstrap for asset delivery (`./loader`, built armed), where the runtime\n * itself is fetched and may evaluate after `react-dom`. They share one window\n * slot, read late, the way the route-refresh seam does.\n */\n\n/** The framework whose first commit the start waits for; `./hydration-vue` and `./hydration-sveltekit` read the others, and `./hydration-manual` waits for the page to say so. */\nexport type HydrationMode = 'react' | 'vue' | 'sveltekit' | 'manual';\nexport type HydrationOutcome = 'committed' | 'timed-out';\nexport type HydrationState = 'idle' | 'waiting' | HydrationOutcome;\n\n/**\n * How long the runtime waits for the commit before it starts anyway and says\n * so (LP0607). A page whose React never commits is broken; a preview that never\n * connects would hide that, one that connects five seconds late and says why\n * does not. A hydration slower than this regenerates the tree once, as before.\n */\nexport const HYDRATION_WAIT_CAP_MS = 5000;\n\n/** Where the prelude and the runtime meet. */\nexport const HYDRATION_SLOT = '__livePreviewHydration';\n\n/**\n * `[data-payload-field]`, spelled out rather than imported from `./cache`: the\n * armed bootstrap bundles this module beside the loader, and the import dragged\n * the cache's other selectors into a script that is measured to the byte. A\n * test holds it equal to `FIELD_ATTRIBUTE`.\n */\nexport const BINDING_SELECTOR = '[data-payload-field]';\n\n/**\n * What the two bundles share. The bootstrap only records: every root React\n * committed goes to `commits` until the runtime, which alone knows what a\n * binding is, sets `onCommit` and judges the backlog and everything after.\n * Recording rather than judging keeps the armed bootstrap to the bytes the\n * delivery budgets hold a bootstrap to.\n */\ninterface HydrationSignal extends HydrationWait {\n armed: boolean;\n commits: unknown[];\n onCommit: ((container: unknown) => void) | undefined;\n}\n\n/**\n * What a wait shares whichever framework it is for: whether the framework has\n * taken the tree over, and who is waiting to hear it. The Vue observer keeps\n * one of its own (`./hydration-vue`); the cap and the cancel are the same.\n */\nexport interface HydrationWait {\n committed: boolean;\n waiters: (() => void)[];\n}\n\n/** The root React hands the hook after a commit; `containerInfo` is the DOM node it rendered into. */\ninterface FiberLike {\n readonly tag?: number;\n readonly child?: FiberLike | null;\n readonly sibling?: FiberLike | null;\n readonly memoizedState?: unknown;\n}\n\ninterface FiberRootLike {\n readonly containerInfo?: unknown;\n readonly current?: FiberLike | null;\n}\n\n/**\n * The part of React's hook this module touches; the rest belongs to React and\n * its DevTools. React itself guards every other call it makes on the hook with\n * `typeof … === 'function'`; Fast Refresh (`react-refresh`, which every\n * development server runs) additionally walks `renderers` when it attaches,\n * and throws on a hook without the map — measured on the Next fixture, where\n * a hook without it stopped the page from hydrating at all.\n */\ninterface DevToolsHook {\n supportsFiber?: boolean;\n renderers?: Map<number, unknown>;\n inject?: (internals: unknown) => number;\n onCommitFiberRoot?: (\n this: unknown,\n rendererId: number,\n root?: FiberRootLike,\n ...rest: unknown[]\n ) => void;\n}\n\ntype HookWindow = Window & {\n __REACT_DEVTOOLS_GLOBAL_HOOK__?: DevToolsHook;\n [HYDRATION_SLOT]?: HydrationSignal;\n};\n\nfunction signalSlot(): HydrationSignal | undefined {\n if (typeof window === 'undefined') return undefined;\n const w = window as HookWindow;\n return (w[HYDRATION_SLOT] ??= {\n armed: false,\n committed: false,\n commits: [],\n onCommit: undefined,\n waiters: [],\n });\n}\n\n/**\n * Arm before React evaluates: install the hook React injects into when the\n * page has none, or wrap `onCommitFiberRoot` on the one that is there — the\n * React DevTools extension injects its own at `document_start`, and it keeps\n * working because the previous function runs first. Idempotent.\n */\nexport function armReactCommitSignal(): void {\n const signal = signalSlot();\n if (signal === undefined || signal.armed) return;\n signal.armed = true;\n const w = window as HookWindow;\n const hook = (w.__REACT_DEVTOOLS_GLOBAL_HOOK__ ??= installedHook());\n const previous = hook.onCommitFiberRoot;\n hook.onCommitFiberRoot = function (this: unknown, rendererId, root, ...rest) {\n try {\n previous?.call(this, rendererId, root, ...rest);\n } catch {\n // The DevTools backend's failure is not ours to propagate; React would\n // swallow it too.\n }\n if (signal.onCommit === undefined) signal.commits.push(root);\n else signal.onCommit(root);\n };\n}\n\n/**\n * The hook React finds when the page has none: what `injectInternals` reads\n * (`supportsFiber`, `inject`) and what Fast Refresh reads (`renderers`, kept\n * the way DevTools keeps it — one id per renderer, so the two React copies a\n * development server runs are not one to it).\n */\nfunction installedHook(): DevToolsHook {\n const renderers = new Map<number, unknown>();\n return {\n supportsFiber: true,\n renderers,\n inject: (internals) => {\n const id = renderers.size + 1;\n renderers.set(id, internals);\n return id;\n },\n };\n}\n\n/** A Document, or a container with a binding inside — the tree the runtime writes into. */\nfunction ownsBindings(container: unknown): boolean {\n const node = container as Partial<Pick<Element, 'nodeType' | 'querySelector'>> | null | undefined;\n return node?.nodeType === 9 || node?.querySelector?.(BINDING_SELECTOR) != null;\n}\n\n/**\n * A streamed React root may commit before every server boundary has been\n * claimed. React 18/19's Suspense fiber (tag 13), and React 19's Activity fiber\n * (tag 31), keep the server Comment in `memoizedState.dehydrated` until a later\n * root commit claims it. Starting between those commits lets that later\n * hydration regenerate markup the runtime has already edited.\n */\nfunction hasDehydratedBoundary(root: FiberRootLike): boolean {\n const pending: FiberLike[] = [];\n if (root.current !== null && root.current !== undefined) pending.push(root.current);\n while (pending.length > 0) {\n const fiber = pending.pop();\n if (fiber === undefined) continue;\n const state = fiber.memoizedState;\n if (\n (fiber.tag === 13 || fiber.tag === 31) &&\n typeof state === 'object' &&\n state !== null &&\n 'dehydrated' in state &&\n typeof state.dehydrated === 'object' &&\n state.dehydrated !== null &&\n 'nodeType' in state.dehydrated &&\n state.dehydrated.nodeType === 8\n ) {\n return true;\n }\n if (fiber.sibling !== null && fiber.sibling !== undefined) pending.push(fiber.sibling);\n if (fiber.child !== null && fiber.child !== undefined) pending.push(fiber.child);\n }\n return false;\n}\n\n/** A binding-owning root after its streamed server boundaries are all claimed. */\nfunction ownsHydratedBindings(value: unknown): boolean {\n const root = value as FiberRootLike | null | undefined;\n return root != null && ownsBindings(root.containerInfo) && !hasDehydratedBoundary(root);\n}\n\n/** The framework has taken the tree over: every waiter hears it, once. */\nexport function settle(signal: HydrationWait): void {\n signal.committed = true;\n const waiters = signal.waiters;\n signal.waiters = [];\n for (const waiter of waiters) waiter();\n}\n\nfunction forget(signal: HydrationWait, waiter: () => void): void {\n const index = signal.waiters.indexOf(waiter);\n if (index >= 0) signal.waiters.splice(index, 1);\n}\n\n/**\n * Call back once the signal settles, or after `capMs` without it. Returns\n * `null` without calling back when it already has — a bfcache restore does\n * not wait again — and otherwise a cancel for a runtime that stops waiting.\n */\nexport function awaitSettled(\n signal: HydrationWait,\n onSettled: (outcome: HydrationOutcome) => void,\n capMs: number,\n): (() => void) | null {\n if (signal.committed) return null;\n let timer: ReturnType<typeof setTimeout> | null = null;\n const waiter = (): void => {\n if (timer !== null) clearTimeout(timer);\n timer = null;\n onSettled('committed');\n };\n signal.waiters.push(waiter);\n timer = setTimeout(() => {\n timer = null;\n forget(signal, waiter);\n onSettled('timed-out');\n }, capMs);\n return () => {\n if (timer !== null) clearTimeout(timer);\n timer = null;\n forget(signal, waiter);\n };\n}\n\n/**\n * Call back once React has committed a root that holds a binding and no\n * dehydrated server boundary, or after `capMs` without one. Arms the signal if\n * nothing has yet.\n */\nexport function whenReactCommitted(\n onSettled: (outcome: HydrationOutcome) => void,\n capMs = HYDRATION_WAIT_CAP_MS,\n): (() => void) | null {\n armReactCommitSignal();\n const signal = signalSlot();\n if (signal === undefined) return null;\n if (signal.onCommit === undefined) {\n // The runtime is the one that can judge a commit; the bootstrap may have\n // recorded some before it ran. The backlog first, then every commit live.\n const judge = (root: unknown): void => {\n if (!signal.committed && ownsHydratedBindings(root)) settle(signal);\n };\n signal.onCommit = judge;\n for (const root of signal.commits.splice(0)) judge(root);\n }\n return awaitSettled(signal, onSettled, capMs);\n}\n","/**\n * Waiting for Vue before the first write (ADR 0015, addendum of 2026-09-11).\n *\n * Vue's `hydrate()` walks the server markup and repairs what differs from its\n * own render, in place and quietly (development logs `Hydration completed but\n * contains mismatches.`). A value the runtime wrote before that is a mismatch\n * and is put back. Measured on the Nuxt fixture on 2026-09-11: the write at\n * 25.5 ms, hydration at 93.7 ms, the server's values back in the same tick;\n * what put them right again was the admin answering the runtime's second\n * `ready` at 500 ms — and a real admin answers `ready` once.\n *\n * Vue says nothing when it is done. What `runtime-core` does, in every build\n * and right after `hydrate()` has returned, is `rootContainer.__vue_app__ = app`\n * (`apiCreateApp.ts`, `mount`): the property Vue DevTools and `app.unmount()`\n * find the app by. The assignment is the signal. An accessor on\n * `Element.prototype` sees it without polling, files the app on the element\n * as an own property exactly as the assignment would have, and settles once\n * the container holds a binding — a widget mounted beside the page is not\n * ours to wait for. A runtime that evaluates after the mount (asset delivery)\n * finds the own property on an ancestor of its first binding instead, so no\n * armed bootstrap is needed: the signal is state, not an event.\n *\n * A Nuxt app hands its `$nuxt` on the same object, and a page whose setup\n * awaits real time hydrates its subtree only when the root Suspense resolves\n * (measured: `__vue_app__` at 494 ms, the subtree at 895 ms). Nuxt marks that\n * with `isHydrating`, cleared synchronously when the Suspense resolves and\n * before `app:suspense:resolve` runs — so an app still hydrating at the\n * mount is waited for through that hook, and one that is not settles at once.\n *\n * Not used, and why: `data-v-app` is set by `createApp().mount` only, never by\n * `createSSRApp()`'s (measured, and in `runtime-dom`); the DevTools hook\n * (`__VUE_DEVTOOLS_GLOBAL_HOOK__`, `app:init`) exists in development builds and\n * under `__VUE_PROD_DEVTOOLS__` only; a MutationObserver sees nothing on a\n * clean hydration; `window.useNuxtApp` is Nuxt's, set before the mount, and\n * `useNuxtApp()` needs Nuxt's context to answer from outside a component.\n */\n\nimport {\n BINDING_SELECTOR,\n HYDRATION_WAIT_CAP_MS,\n awaitSettled,\n settle,\n type HydrationOutcome,\n type HydrationWait,\n} from './hydration';\n\n/** Where runtime-core leaves the app on its container. */\nexport const VUE_APP_PROPERTY = '__vue_app__';\n\n/** One slot on the window, so a second copy of the runtime shares the state rather than the accessor. */\nexport const VUE_HYDRATION_SLOT = '__livePreviewVueHydration';\n\n/** The Nuxt hook that runs once the root Suspense has resolved, its subtree hydrated. */\nconst NUXT_HYDRATED_HOOK = 'app:suspense:resolve';\n\ninterface VueMountSignal extends HydrationWait {\n armed: boolean;\n}\n\n/** The two things read off a Nuxt app: whether it is still hydrating, and the hook that ends it. */\ninterface NuxtAppLike {\n readonly isHydrating?: boolean;\n readonly hook?: (name: string, fn: () => void) => unknown;\n}\n\ntype VueWindow = Window & { [VUE_HYDRATION_SLOT]?: VueMountSignal };\n\nfunction signalSlot(): VueMountSignal | undefined {\n if (typeof window === 'undefined') return undefined;\n const w = window as VueWindow;\n return (w[VUE_HYDRATION_SLOT] ??= { armed: false, committed: false, waiters: [] });\n}\n\n/** Vue's assignment lands as an own property; only that counts, never the accessor. */\nfunction mountedApp(node: Node): unknown {\n return Object.prototype.hasOwnProperty.call(node, VUE_APP_PROPERTY)\n ? (node as unknown as Record<string, unknown>)[VUE_APP_PROPERTY]\n : undefined;\n}\n\n/**\n * Arm before Vue mounts: the accessor on `Element.prototype` that turns the\n * mount into a signal. Idempotent, and it leaves a seam another copy of the\n * runtime — or a tool — already holds alone; the slot is shared either way,\n * and the accessor reads it live rather than closing over one.\n */\nexport function armVueMountSignal(): void {\n const signal = signalSlot();\n if (signal === undefined || signal.armed) return;\n signal.armed = true;\n const proto = Element.prototype;\n if (Object.getOwnPropertyDescriptor(proto, VUE_APP_PROPERTY) !== undefined) return;\n Object.defineProperty(proto, VUE_APP_PROPERTY, {\n configurable: true,\n get: () => undefined,\n set(this: Element, app: unknown) {\n Object.defineProperty(this, VUE_APP_PROPERTY, {\n value: app,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n const live = signalSlot();\n if (live === undefined || live.committed || this.querySelector(BINDING_SELECTOR) === null) {\n return;\n }\n settleOnceHydrated(live, app);\n },\n });\n}\n\n/** Mounted, and — for a Nuxt app whose Suspense is still pending — hydrated too. */\nfunction settleOnceHydrated(signal: VueMountSignal, app: unknown): void {\n const nuxt = (app as { $nuxt?: NuxtAppLike } | null | undefined)?.$nuxt;\n if (nuxt?.isHydrating === true && typeof nuxt.hook === 'function') {\n nuxt.hook(NUXT_HYDRATED_HOOK, () => {\n if (!signal.committed) settle(signal);\n });\n return;\n }\n settle(signal);\n}\n\n/** Whether an app already sits on an ancestor of a binding under `root` — the runtime came after Vue. */\nfunction mountedAround(root: Document | Element): boolean {\n for (let node = root.querySelector(BINDING_SELECTOR); node !== null; node = node.parentElement) {\n if (mountedApp(node) !== undefined) return true;\n }\n return false;\n}\n\n/**\n * Call back once Vue has mounted — and, on Nuxt, hydrated — an app around a\n * binding of `root`, or after `capMs` without one. Arms the signal if nothing\n * has yet; `null` when it already happened.\n */\nexport function whenVueMounted(\n root: Document | Element,\n onSettled: (outcome: HydrationOutcome) => void,\n capMs = HYDRATION_WAIT_CAP_MS,\n): (() => void) | null {\n armVueMountSignal();\n const signal = signalSlot();\n if (signal === undefined) return null;\n if (!signal.committed && mountedAround(root)) settle(signal);\n return awaitSettled(signal, onSettled, capMs);\n}\n","/**\n * When the runtime may start: after the document has parsed, and on a page\n * that declares hydration after the framework's first commit — React's, Vue's\n * mount, SvelteKit's root mounting, or the page's own `markHydrated()` — or the\n * cap (ADR 0015).\n *\n * `lifecycle.ts` owns the resources a start acquires and how a failed one is\n * rolled back; this module owns only the waiting. It moved out when the\n * second wait pushed the lifecycle past its 500 lines, and it stays a chain of\n * plain functions over a small host so that a stage running after `start()`\n * has returned still rolls back and reports the way a synchronous failure\n * throws — the host's `later` is that seam, and `defer` is how `release()`\n * abandons whichever wait is in progress.\n */\n\nimport {\n HYDRATION_WAIT_CAP_MS,\n armReactCommitSignal,\n whenReactCommitted,\n type HydrationMode,\n type HydrationOutcome,\n type HydrationState,\n} from './hydration';\nimport { armVueMountSignal, whenVueMounted } from './hydration-vue';\nimport { whenSvelteKitMounted } from './hydration-sveltekit';\nimport { whenMarkedHydrated } from './hydration-manual';\n\n/** What the startup chain needs from the runtime. */\nexport interface StartupHost {\n readonly root: Document | Element;\n readonly hydration: HydrationMode | undefined;\n /** Whether the runtime is still meant to start; a stop in between abandons the chain. */\n isRunning(): boolean;\n /** Keeps the way to abandon the wait in progress, for `release()`. */\n defer(cancel: () => void): void;\n /** Runs a stage after `start()` has returned: a throw is rolled back and reported, not lost. */\n later(step: () => void): void;\n /** Records how far the wait for hydration got, for `inspect()`. */\n hydrated(state: HydrationState): void;\n warn(message: string): void;\n /** Acquires the resources; throws into the caller when synchronous. */\n startNow(): void;\n}\n\n/**\n * Synchronous when nothing is pending. Otherwise the host is handed a cancel\n * and the chain continues through `later` once the wait ends.\n */\nexport function startWhenReady(host: StartupHost): void {\n // Armed before anything defers: the framework may evaluate before DOMContentLoaded.\n if (host.hydration === 'react') armReactCommitSignal();\n else if (host.hydration === 'vue') armVueMountSignal();\n const { root } = host;\n if (!isDocumentRoot(root) || root.readyState !== 'loading') {\n startAfterParse(host);\n return;\n }\n const onReady = (): void => {\n if (!host.isRunning()) return;\n host.later(() => {\n startAfterParse(host);\n });\n };\n root.addEventListener('DOMContentLoaded', onReady, { once: true });\n host.defer(() => {\n root.removeEventListener('DOMContentLoaded', onReady);\n });\n}\n\n/** A page a framework hydrates is not final until the framework has committed. */\nfunction startAfterParse(host: StartupHost): void {\n const mode = host.hydration;\n if (mode === undefined) {\n host.startNow();\n return;\n }\n const onSettled = (outcome: HydrationOutcome): void => {\n host.later(() => {\n startHydrated(host, mode, outcome);\n });\n };\n const pending = WAITS[mode](host.root, onSettled);\n // Already committed — a bfcache restore does not wait again.\n if (pending === null) {\n startHydrated(host, mode, 'committed');\n return;\n }\n host.defer(pending);\n host.hydrated('waiting');\n}\n\n/** One wait per framework; each returns `null` when there is nothing left to wait for. */\nconst WAITS: Record<\n HydrationMode,\n (root: Document | Element, onSettled: (outcome: HydrationOutcome) => void) => (() => void) | null\n> = {\n react: (_root, onSettled) => whenReactCommitted(onSettled),\n vue: whenVueMounted,\n sveltekit: whenSvelteKitMounted,\n manual: whenMarkedHydrated,\n};\n\n/** What LP0607 says the runtime waited for. */\nconst AWAITED: Record<HydrationMode, string> = {\n react: 'React commit',\n vue: 'Vue mount',\n sveltekit: 'SvelteKit mount',\n manual: 'markHydrated() call',\n};\n\nfunction startHydrated(host: StartupHost, mode: HydrationMode, outcome: HydrationOutcome): void {\n host.hydrated(outcome);\n if (outcome === 'timed-out') {\n host.warn(\n `[live-preview] LP0607: no ${AWAITED[mode]} in ${String(HYDRATION_WAIT_CAP_MS)} ms; started without waiting for hydration.`,\n );\n }\n host.startNow();\n}\n\n/** Node types are stable across realms; global constructors are not. */\nexport function isDocumentRoot(root: Document | Element): root is Document {\n return root.nodeType === 9;\n}\n\n/** Unlike lib.dom's declaration, a document running in `<head>` may not have a body yet. */\nexport function readDocumentBody(root: Document): HTMLElement | null {\n return root.body;\n}\n","/**\n * Waiting for SvelteKit before the first write (ADR 0015, addendum of 2026-10-01).\n *\n * Svelte's hydration claims the server's nodes and then runs each template\n * effect once; `set_text` compares its value with the node's text and writes\n * its own where they differ. A value the runtime wrote before that is put back,\n * quietly, as Vue does. Measured on the SvelteKit fixture's `/navigation` under\n * eight Playwright workers on 2026-09-30: the runtime's write, then 4 to 20 ms\n * later the server's title on the same node, in 5 to 7 of 40 runs.\n *\n * Neither Svelte nor SvelteKit says when hydration is done. What SvelteKit's\n * generated root does (read in 2.0.0 and in 2.70.2, the fixture's) is render\n * its route announcer (`<div id=\"svelte-announcer\">`) under `{#if mounted}`,\n * with `mounted` set in the root's `onMount`: after the tree below it has been\n * hydrated and its template effects have run. The element is state, not an\n * event, so a runtime that evaluates after the mount (asset delivery) finds it.\n *\n * A page served with `csr = false` has no client and never renders the\n * announcer; waiting for it would cost every such page the cap. SvelteKit's\n * start script assigns its global (`__sveltekit_dev`, `__sveltekit_<hash>`)\n * only on a page it will hydrate, and by `DOMContentLoaded` that classic\n * script has run, so a page without the global starts at once.\n */\n\nimport {\n HYDRATION_WAIT_CAP_MS,\n awaitSettled,\n settle,\n type HydrationOutcome,\n type HydrationWait,\n} from './hydration';\n\n/** The live region SvelteKit's root renders once it has mounted (`write_root.js`). */\nexport const SVELTEKIT_ANNOUNCER_ID = 'svelte-announcer';\n\n/** What the global SvelteKit's start script assigns begins with (`get_global_name`). */\nexport const SVELTEKIT_GLOBAL_PREFIX = '__sveltekit_';\n\n/** SvelteKit's client will run on this page: its start script left its global. */\nfunction clientStarts(): boolean {\n return Object.keys(window).some((key) => key.startsWith(SVELTEKIT_GLOBAL_PREFIX));\n}\n\n/**\n * Call back once SvelteKit's root has mounted, its announcer in the document,\n * or after `capMs` without it. `null` when there is nothing to wait for: the\n * root has mounted already, or no SvelteKit client runs on the page.\n */\nexport function whenSvelteKitMounted(\n root: Document | Element,\n onSettled: (outcome: HydrationOutcome) => void,\n capMs = HYDRATION_WAIT_CAP_MS,\n): (() => void) | null {\n // The announcer is the document's, whatever part of it the runtime binds.\n const page = root.ownerDocument ?? root;\n const mounted = (): boolean => page.querySelector(`#${SVELTEKIT_ANNOUNCER_ID}`) !== null;\n if (mounted() || !clientStarts()) return null;\n const signal: HydrationWait = { committed: false, waiters: [] };\n const observer = new MutationObserver(() => {\n if (!signal.committed && mounted()) settle(signal);\n });\n observer.observe(page, { childList: true, subtree: true });\n const cancel = awaitSettled(\n signal,\n (outcome) => {\n observer.disconnect();\n onSettled(outcome);\n },\n capMs,\n );\n return () => {\n observer.disconnect();\n cancel?.();\n };\n}\n","/**\n * Waiting for a page that says when it has hydrated (ADR 0015, addendum of\n * 2026-10-31). The React, Vue and SvelteKit waits each read a trace their\n * framework leaves; a page on any other host, or whose host left none, calls\n * `markHydrated()` instead. The page's bundle and the runtime are separate\n * scripts and either may run first, so the slot holds a state a late runtime\n * can still read rather than an event it could miss.\n */\n\nimport {\n HYDRATION_WAIT_CAP_MS,\n awaitSettled,\n settle,\n type HydrationOutcome,\n type HydrationWait,\n} from './hydration';\n\n/** Where the page's bundle and the runtime meet. */\nexport const MANUAL_HYDRATION_SLOT = '__livePreviewHydrated';\n\ntype SlotWindow = Window & { [MANUAL_HYDRATION_SLOT]?: HydrationWait };\n\nfunction signalSlot(): HydrationWait | undefined {\n if (typeof window === 'undefined') return undefined;\n const w = window as SlotWindow;\n return (w[MANUAL_HYDRATION_SLOT] ??= { committed: false, waiters: [] });\n}\n\n/**\n * Tell a runtime started with `hydration: 'manual'` that this page has hydrated, so its\n * first write lands on markup the framework keeps. Call it once your framework has\n * taken the page over; a later call changes nothing, and on a server it does nothing.\n */\nexport function markHydrated(): void {\n const signal = signalSlot();\n if (signal !== undefined) settle(signal);\n}\n\n/**\n * Call back once the page has marked itself hydrated, or after `capMs` without\n * it. `null` when there is nothing to wait for: the page has marked itself\n * already, or there is no window.\n */\nexport function whenMarkedHydrated(\n _root: Document | Element,\n onSettled: (outcome: HydrationOutcome) => void,\n capMs = HYDRATION_WAIT_CAP_MS,\n): (() => void) | null {\n const signal = signalSlot();\n return signal === undefined ? null : awaitSettled(signal, onSettled, capMs);\n}\n","/** Connection status and the heartbeat that decides a disconnect. */\n\nexport type ConnectionStatus = 'disconnected' | 'connecting' | 'connected';\n\nexport interface HeartbeatOptions {\n /**\n * Silence before declaring a timeout. `0` disables the timer, which is right\n * for the stock Payload protocol: it sends messages only on edits, so any\n * idle timeout would report false disconnects.\n */\n readonly timeoutMs?: number;\n readonly onTimeout: () => void;\n}\n\nexport class HeartbeatTimer {\n private readonly timeoutMs: number;\n private readonly onTimeout: () => void;\n private handle: ReturnType<typeof setTimeout> | null = null;\n private lastKick: number | null = null;\n\n constructor(options: HeartbeatOptions) {\n this.timeoutMs = options.timeoutMs ?? 0;\n this.onTimeout = options.onTimeout;\n }\n\n /** Called on every valid message; re-arms the timeout. */\n kick(): void {\n this.lastKick = Date.now();\n if (this.timeoutMs <= 0) return;\n this.stop();\n this.arm(this.timeoutMs);\n }\n\n /**\n * Re-arm after a lifecycle pause without granting a fresh trust window.\n * Returns whether the old deadline expired while the timer was stopped.\n */\n resume(): boolean {\n if (this.timeoutMs <= 0 || this.handle !== null || this.lastKick === null) return false;\n const elapsed = Math.max(0, Date.now() - this.lastKick);\n const remaining = this.timeoutMs - elapsed;\n if (remaining <= 0) {\n this.lastKick = null;\n this.onTimeout();\n return true;\n }\n this.arm(Math.min(remaining, this.timeoutMs));\n return false;\n }\n\n private arm(delay: number): void {\n const handle = setTimeout(() => {\n if (this.handle !== handle) return;\n this.handle = null;\n this.lastKick = null;\n this.onTimeout();\n }, delay);\n this.handle = handle;\n }\n\n stop(): void {\n if (this.handle === null) return;\n clearTimeout(this.handle);\n this.handle = null;\n }\n\n get lastKickAt(): number {\n return this.lastKick ?? 0;\n }\n\n get pending(): boolean {\n return this.handle !== null;\n }\n}\n\nexport class ConnectionState {\n private current: ConnectionStatus = 'disconnected';\n\n get status(): ConnectionStatus {\n return this.current;\n }\n\n /** Returns whether the status changed. */\n markConnected(): boolean {\n return this.transition('connected');\n }\n\n markDisconnected(): boolean {\n return this.transition('disconnected');\n }\n\n private transition(next: ConnectionStatus): boolean {\n if (this.current === next) return false;\n this.current = next;\n return true;\n }\n}\n","/**\n * Auto-binding (ADR 0014). On the connection's first message the document and\n * the DOM are two views of the same state, so a scalar field's value can be\n * looked for in the page: where it stands as the whole content of exactly one\n * element — its only text node, or one attribute the writer may set — that\n * element is bound to the field as if `data-payload-field` had been written\n * there. No match, several, a partial one, one split across nodes: nothing,\n * and the field stays unbound, which since Z3 escalates instead of degrading.\n *\n * Two jobs, two exports. `findUniqueBindings` is the search, the exclusions and\n * the candidate rule, and reads the DOM only. `adoptUniqueBindings` writes the\n * winners onto their elements as the attributes a template would have carried,\n * plus `data-payload-guessed` holding the value that matched, and registers\n * them with the cache. Stamping is what lets a cache rebuild find a guess again\n * the way it finds any binding, and what lets `inspect()` and the overlay tell\n * a guess from a declaration.\n */\n\nimport { isWritableAttribute } from './attribute-binding';\nimport { isBindingInScope } from './binding-owner';\nimport {\n ALT_ATTRIBUTE,\n FIELD_ATTRIBUTE,\n GUESSED_ATTRIBUTE,\n HREF_ATTRIBUTE,\n TARGET_ATTRIBUTE_ATTRIBUTE,\n TYPE_ATTRIBUTE,\n resolveBindingOwner,\n} from './cache';\nimport { isIslandBoundary, OWNED_ATTRIBUTE } from './islands';\nimport type { RuntimeDeps, RuntimeState } from './runtime-state';\nimport { stripLocaleSuffix, SYSTEM_FIELD_NAMES, type OwnerScope } from './unbound-fields';\n\n/** `'unique'` searches once, on the first message; `'off'` (the default) never. */\nexport type AutoBindMode = 'off' | 'unique';\n\n/** An author's no: the element and everything under it is never guessed into. */\nexport const NO_BIND_ATTRIBUTE = 'data-payload-no-bind';\n/** The morph's boundary (`src/core/morph.ts`) is this search's boundary too: a subtree the site scripts itself. */\n\n/**\n * Below this many characters a value is not looked for at all. Measured, not\n * chosen: on the trap corpus (`tests/fixtures/auto-bind-traps`) 13 is the\n * shortest floor at which no trap binds — at 12 the byline `Ada Lovelace`,\n * printed by a related post and never by the template, is a unique match in\n * the wrong place. The shortest value the shipped fixtures bind that a unique\n * match finds is `Visit Payload`, 13. So the floor separates the corpus with\n * no margin either way; what it is for are the short tokens ADR 0014 names,\n * and a phrase that occurs exactly once and in the wrong place is kept out by\n * nothing but its rarity.\n */\nexport const AUTO_BIND_MIN_LENGTH = 13;\n\nconst BOOLEAN_WORDS: ReadonlySet<string> = new Set(['true', 'false', 'yes', 'no', 'on', 'off']);\n/** Digits with the separators a date, a time, a price or a phone number carry. */\nconst NUMERIC = /^[\\d\\s.,:+/-]+$/u;\n/** A single lower-case token: an enum value, a slug, a code. */\nconst ENUM_TOKEN = /^[a-z][a-z0-9_-]*$/u;\n/** `de`, `de-AT`, `zh_Hant`, `sr-Latn-RS`. */\nconst LOCALE_CODE = /^[a-z]{2,3}(?:[-_][A-Za-z0-9]{2,8})*$/u;\n\n/** Elements whose text is code, metadata or a form value, not content. */\nconst SKIPPED_TAGS: ReadonlySet<string> = new Set([\n 'SCRIPT',\n 'STYLE',\n 'TEMPLATE',\n 'TITLE',\n 'NOSCRIPT',\n 'TEXTAREA',\n 'SELECT',\n 'OPTION',\n 'INPUT',\n 'IFRAME',\n]);\nconst HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n\nexport interface AutoBindCandidate {\n readonly element: Element;\n readonly fieldName: string;\n /** The value that matched: the text, or the attribute's value. */\n readonly matched: string;\n /** The attribute whose whole value matched; absent for a text match. */\n readonly attribute?: string;\n /** The `data-payload-*` attributes a template would have written for this binding. */\n readonly stamps: Readonly<Record<string, string>>;\n}\n\n/** A value's owner: the field, and whether it is an upload (matched by its `url` against an `<img>`). */\nexport interface Claim {\n readonly field: string;\n readonly media: boolean;\n}\n\n/**\n * What the baseline search adopted, kept for the server re-render a route\n * refresh morphs the page toward: that markup carries no stamp, so the guesses\n * are looked for again there — these fields, by these values — and nothing\n * else is. ADR 0014 §1 still holds for everything the baseline did not find.\n */\nexport interface KeptGuesses {\n /** The fields the guesses bound, a folded second field (`data-payload-href`, `data-payload-alt`) included. */\n readonly fields: ReadonlySet<string>;\n /** The texts they were found by, each claiming its field. */\n readonly values: ReadonlyMap<string, Claim>;\n}\n\n/** Whether a scalar is worth looking for: the short and shapeless ones match by accident. */\nexport function isBindableValue(value: unknown, minLength = AUTO_BIND_MIN_LENGTH): value is string {\n if (typeof value !== 'string') return false;\n const text = value.trim();\n if (text.length < minLength) return false;\n if (NUMERIC.test(text) || BOOLEAN_WORDS.has(text.toLowerCase())) return false;\n return !ENUM_TOKEN.test(text) && !LOCALE_CODE.test(text);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * The values to look for, keyed by the exact text a match must equal. A value\n * two fields share maps to `null`: the element would be unique, the field not.\n * Groups are opened one level under the dotted name a binding would carry; an\n * upload is looked for by its `url`; a document with an `id` and no `url` is\n * another document, and its scalars are not this one's.\n */\nexport function bindableValues(\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n minLength = AUTO_BIND_MIN_LENGTH,\n): Map<string, Claim | null> {\n const values = new Map<string, Claim | null>();\n const claim = (text: string, field: string, media: boolean): void => {\n values.set(text, values.has(text) ? null : { field, media });\n };\n for (const [rawName, value] of Object.entries(fields)) {\n if (SYSTEM_FIELD_NAMES.has(rawName)) continue;\n const name = stripLocaleSuffix(rawName, locale);\n if (isBindableValue(value, minLength)) {\n claim(value.trim(), name, false);\n } else if (isRecord(value)) {\n if (typeof value['url'] === 'string') {\n claim(value['url'], name, true);\n } else if (!('id' in value) && !('_id' in value)) {\n for (const [child, childValue] of Object.entries(value)) {\n if (SYSTEM_FIELD_NAMES.has(child) || !isBindableValue(childValue, minLength)) continue;\n claim(childValue.trim(), `${name}.${child}`, false);\n }\n }\n }\n }\n return values;\n}\n\n/** Where the search stops: nothing at or under this element may be claimed. */\nfunction isBoundary(element: Element): boolean {\n if (element.namespaceURI !== HTML_NAMESPACE || SKIPPED_TAGS.has(element.tagName)) return true;\n if (\n element.hasAttribute(FIELD_ATTRIBUTE) ||\n element.hasAttribute(NO_BIND_ATTRIBUTE) ||\n element.hasAttribute(OWNED_ATTRIBUTE) ||\n isIslandBoundary(element)\n ) {\n return true;\n }\n const editable = element.getAttribute('contenteditable');\n return editable !== null && editable !== 'false';\n}\n\n/**\n * The element's whole text, when it is exactly one text node — comments and\n * whitespace-only nodes aside — and no element. A second text node is a value\n * split across nodes; an element child is markup a text write would destroy.\n */\nfunction soleText(element: Element): string | undefined {\n let text: string | undefined;\n for (let child = element.firstChild; child !== null; child = child.nextSibling) {\n if (child.nodeType === 1) return undefined;\n if (child.nodeType !== 3) continue;\n const data = (child as Text).data.trim();\n if (data.length === 0) continue;\n if (text !== undefined) return undefined;\n text = data;\n }\n return text;\n}\n\n/** No second rule beyond the writer's own; `value` is the visitor's, and `data-payload-*` is ours. */\nfunction isCandidateAttribute(name: string): boolean {\n return isWritableAttribute(name) && !name.startsWith('data-payload-') && name !== 'value';\n}\n\ninterface ElementHits {\n /** The field whose value is the element's whole text. */\n text?: string;\n /** Attribute name → the field whose value it carries. */\n readonly attributes: Map<string, Claim>;\n}\n\ninterface Search {\n readonly values: ReadonlyMap<string, Claim | null>;\n readonly byElement: Map<Element, ElementHits>;\n /** Every element a field was found on; a field with more than one is ambiguous. */\n readonly byField: Map<string, Set<Element>>;\n}\n\nfunction record(search: Search, element: Element, claim: Claim): ElementHits {\n let hits = search.byElement.get(element);\n if (hits === undefined) {\n hits = { attributes: new Map() };\n search.byElement.set(element, hits);\n }\n let elements = search.byField.get(claim.field);\n if (elements === undefined) {\n elements = new Set();\n search.byField.set(claim.field, elements);\n }\n elements.add(element);\n return hits;\n}\n\n/**\n * One pass, depth first, in document order; the element under a boundary is\n * never looked at. Sibling pointers rather than `children` and `attributes`:\n * the live collections cost twenty times the walk in jsdom, where the\n * interaction gate measures this, and nothing in a browser.\n */\nfunction walk(element: Element, search: Search): void {\n for (let child = element.firstElementChild; child !== null; child = child.nextElementSibling) {\n if (isBoundary(child)) continue;\n const text = soleText(child);\n const textClaim = text === undefined ? undefined : search.values.get(text);\n if (textClaim != null && !textClaim.media) {\n record(search, child, textClaim).text = textClaim.field;\n }\n for (const name of child.getAttributeNames()) {\n if (!isCandidateAttribute(name)) continue;\n const claim = search.values.get(child.getAttribute(name) ?? '');\n if (claim == null) continue;\n // An upload is matched by its file, and an `<img>` is the one element that renders one.\n if (claim.media && (child.tagName !== 'IMG' || name !== 'src')) continue;\n record(search, child, claim).attributes.set(name, claim);\n }\n walk(child, search);\n }\n}\n\n/**\n * What a template would have written for this element. One binding per\n * element: the text wins, and the two idioms a template has for a second\n * field on the same element — `data-payload-href` on a link, `data-payload-alt`\n * on an image — are used when the second field matched that attribute.\n */\nfunction shape(\n element: Element,\n text: string | undefined,\n attributes: ReadonlyMap<string, string>,\n): AutoBindCandidate | undefined {\n const tag = element.tagName;\n if (text !== undefined) {\n const stamps: Record<string, string> = { [FIELD_ATTRIBUTE]: text };\n if (tag === 'A') {\n const href = attributes.get('href');\n // The url renderer derives the href from the text; a guess that never\n // matched the href must not clear it, so the text renderer is named.\n if (href === undefined) stamps[TYPE_ATTRIBUTE] = 'text';\n else if (href !== text) stamps[HREF_ATTRIBUTE] = href;\n }\n return { element, fieldName: text, matched: soleText(element) ?? '', stamps };\n }\n if (tag === 'IMG') {\n const src = attributes.get('src');\n if (src !== undefined) {\n const alt = attributes.get('alt');\n return {\n element,\n fieldName: src,\n matched: element.getAttribute('src') ?? '',\n attribute: 'src',\n stamps: {\n [FIELD_ATTRIBUTE]: src,\n ...(alt !== undefined && alt !== src ? { [ALT_ATTRIBUTE]: alt } : {}),\n },\n };\n }\n }\n // A link whose text did not match keeps its text: only the attribute is written.\n const first = attributes.entries().next();\n if (first.done) return undefined;\n const [name, field] = first.value;\n return {\n element,\n fieldName: field,\n matched: element.getAttribute(name) ?? '',\n attribute: name,\n stamps: { [FIELD_ATTRIBUTE]: field, [TARGET_ATTRIBUTE_ATTRIBUTE]: name },\n };\n}\n\n/**\n * The bindings the page allows, in document order: for every field found on\n * exactly one element, that element with the attributes a template would have\n * given it. `root` is searched as a whole; the caller decides that a document's\n * root is its body.\n */\nexport function findUniqueBindings(\n root: Element,\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n minLength = AUTO_BIND_MIN_LENGTH,\n): AutoBindCandidate[] {\n return searchUnique(root, bindableValues(fields, locale, minLength));\n}\n\n/** The search proper, over a value table already decided on. */\nfunction searchUnique(\n root: Element,\n values: ReadonlyMap<string, Claim | null>,\n): AutoBindCandidate[] {\n const search: Search = { values, byElement: new Map(), byField: new Map() };\n if (values.size > 0 && !isBoundary(root)) walk(root, search);\n const unique = (field: string): boolean => search.byField.get(field)?.size === 1;\n const candidates: AutoBindCandidate[] = [];\n for (const [element, hits] of search.byElement) {\n const text = hits.text !== undefined && unique(hits.text) ? hits.text : undefined;\n const attributes = new Map<string, string>();\n for (const [name, claim] of hits.attributes) {\n if (unique(claim.field)) attributes.set(name, claim.field);\n }\n const candidate = shape(element, text, attributes);\n if (candidate !== undefined) candidates.push(candidate);\n }\n return candidates;\n}\n\n/** A document's root is its body: a binding in `<head>` needs the attribute and the route strategy. */\nfunction searchRoot(root: Document | Element): Element | null {\n return root.nodeType === 9 ? (root as Document).body : (root as Element);\n}\n\n/**\n * Run the search once and make its winners bindings. Returns how many. The\n * stamps land on the elements first, so the cache resolves each guess exactly\n * as it resolves a declared binding — and so the mutation observer's rebuild,\n * which the stamps themselves trigger, finds them again.\n */\nexport function adoptUniqueBindings(\n deps: RuntimeDeps,\n state: RuntimeState,\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n isCurrent: () => boolean,\n): number {\n if (!isCurrent()) return 0;\n const started = performance.now();\n const root = searchRoot(deps.root);\n const values = bindableValues(fields, locale);\n if (!isCurrent()) return 0;\n const candidates = root === null ? [] : searchUnique(root, values);\n if (!isCurrent()) return 0;\n const adopted = adopt(deps, candidates, ownerKeys, 'on the first message', isCurrent);\n if (!isCurrent()) return 0;\n const guesses = keep(values, adopted);\n const elapsed = performance.now() - started;\n if (!isCurrent()) return 0;\n state.autoBindGuesses = guesses;\n state.autoBindSearchMs = elapsed;\n return adopted.length;\n}\n\n/**\n * After a server render — a route refresh, or a fragment in its boundary: the\n * server's markup carries no stamp, so the guesses the baseline made are gone\n * from what it rendered. Look for them again, by the value\n * each was found by and by the field's value in this revision — the server\n * may have rendered either, the document as it was saved or a draft it\n * autosaved since. A field found by both, on two elements, is ambiguous and\n * stays unbound. Nothing the baseline did not bind is looked for: a second\n * baseline would be a second chance at a wrong match, and the first one is\n * the only moment the page is known to show the document (ADR 0014 §1).\n */\nexport function restoreUniqueBindings(\n deps: RuntimeDeps,\n state: RuntimeState,\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n isCurrent: () => boolean,\n): number {\n if (!isCurrent()) return 0;\n const kept = state.autoBindGuesses;\n const root = searchRoot(deps.root);\n if (kept === null || kept.fields.size === 0 || root === null) return 0;\n const values = new Map<string, Claim | null>(kept.values);\n for (const [text, claim] of bindableValues(fields, locale)) {\n if (claim === null || !kept.fields.has(claim.field)) continue;\n const known = values.get(text);\n if (known === undefined) values.set(text, claim);\n else if (known?.field !== claim.field) values.set(text, null);\n }\n if (!isCurrent()) return 0;\n const candidates = searchUnique(root, values);\n if (!isCurrent()) return 0;\n return adopt(deps, candidates, ownerKeys, 'after a server render', isCurrent).length;\n}\n\ninterface AdoptionMutation {\n readonly element: Element;\n readonly attributes: {\n readonly name: string;\n readonly before: string | null;\n readonly written: string;\n }[];\n cacheTouched: boolean;\n observed: boolean;\n}\n\n/** Undo only values this attempt still owns; a reentrant writer's different value wins. */\nfunction rollback(deps: RuntimeDeps, mutations: readonly AdoptionMutation[]): void {\n for (let index = mutations.length - 1; index >= 0; index -= 1) {\n const mutation = mutations[index];\n if (mutation === undefined) continue;\n if (mutation.observed) deps.observers.unobserveElement(mutation.element);\n for (let attribute = mutation.attributes.length - 1; attribute >= 0; attribute -= 1) {\n const changed = mutation.attributes[attribute];\n if (changed === undefined) continue;\n const { name, before, written } = changed;\n if (before === written || mutation.element.getAttribute(name) !== written) continue;\n if (before === null) mutation.element.removeAttribute(name);\n else mutation.element.setAttribute(name, before);\n }\n if (!mutation.cacheTouched) continue;\n if (mutation.element.hasAttribute(FIELD_ATTRIBUTE)) deps.cache.add(mutation.element);\n else deps.cache.remove(mutation.element);\n }\n}\n\n/** Stamp the candidates, register them, say so; returns the ones that became bindings. */\nfunction adopt(\n deps: RuntimeDeps,\n candidates: readonly AutoBindCandidate[],\n ownerKeys: OwnerScope,\n when: string,\n isCurrent: () => boolean,\n): AutoBindCandidate[] {\n const adopted: AutoBindCandidate[] = [];\n const mutations: AdoptionMutation[] = [];\n const abandon = (): AutoBindCandidate[] => {\n rollback(deps, mutations);\n return [];\n };\n for (const candidate of candidates) {\n if (!isCurrent()) return abandon();\n const { element } = candidate;\n if (element.hasAttribute(FIELD_ATTRIBUTE)) continue;\n if (!isCurrent()) return abandon();\n // Under owner scoping a guess outside the message's document would never\n // be written to; better to leave it unbound than to bind it to nothing.\n if (ownerKeys !== false && !isBindingInScope(resolveBindingOwner(element), ownerKeys)) continue;\n if (!isCurrent()) return abandon();\n const mutation: AdoptionMutation = {\n element,\n attributes: [],\n cacheTouched: false,\n observed: false,\n };\n mutations.push(mutation);\n for (const [name, value] of [\n ...Object.entries(candidate.stamps),\n [GUESSED_ATTRIBUTE, candidate.matched] as const,\n ]) {\n const before = element.getAttribute(name);\n if (!isCurrent()) return abandon();\n mutation.attributes.push({ name, before, written: value });\n element.setAttribute(name, value);\n if (!isCurrent()) return abandon();\n }\n mutation.cacheTouched = true;\n if (deps.cache.add(element) === undefined) {\n // The cache's own filter refused it; restore metadata the unbound element carried before the attempt.\n rollback(deps, [mutation]);\n mutations.pop();\n continue;\n }\n if (!isCurrent()) return abandon();\n deps.observers.observeElement(element);\n mutation.observed = true;\n if (!isCurrent()) return abandon();\n deps.log(\n 'autoBind',\n candidate.fieldName,\n '→',\n `<${element.tagName.toLowerCase()}>`,\n candidate.attribute ?? 'text',\n JSON.stringify(candidate.matched),\n when,\n );\n if (!isCurrent()) return abandon();\n adopted.push(candidate);\n }\n return adopted;\n}\n\n/** The fields the adopted guesses bound, and the values that found them. */\nfunction keep(\n values: ReadonlyMap<string, Claim | null>,\n adopted: readonly AutoBindCandidate[],\n): KeptGuesses {\n const fields = new Set<string>();\n for (const { fieldName, stamps } of adopted) {\n fields.add(fieldName);\n for (const name of [HREF_ATTRIBUTE, ALT_ATTRIBUTE]) {\n const folded = stamps[name];\n if (folded !== undefined) fields.add(folded);\n }\n }\n const kept = new Map<string, Claim>();\n for (const [text, claim] of values) {\n if (claim !== null && fields.has(claim.field)) kept.set(text, claim);\n }\n return { fields, values: kept };\n}\n","/**\n * A binding on `items.0.title` follows the position, not the row: after a\n * reorder the title lands in the first element, while the image and the markup\n * nobody bound still belong to the row that stood there. Payload gives each row\n * an `id`, so a position that now holds another row is a patch the page cannot\n * show faithfully, and it goes to a strategy like any other.\n */\n\nimport { reportUnfaithfulPatch } from './fidelity';\nimport type { RuntimeDeps, RuntimeState } from './runtime-state';\nimport type { CachedElement } from './types';\n\n/** The ids of the rows a path passes through, `undefined` for a path through no row. */\nfunction rowsOnPath(fields: Readonly<Record<string, unknown>>, path: string): string | undefined {\n let rows: string | undefined;\n let value: unknown = fields;\n for (const segment of path.split('.')) {\n if (typeof value !== 'object' || value === null) break;\n value = (value as Record<string, unknown>)[segment];\n const id = /^\\d+$/.test(segment) ? (value as { id?: unknown } | null | undefined)?.id : null;\n if (typeof id === 'string' || typeof id === 'number') rows = `${rows ?? ''}/${String(id)}`;\n }\n return rows;\n}\n\n/** Remember the rows behind `target`, and report it when another row now stands there. */\nexport function reportMovedRow(\n deps: RuntimeDeps,\n state: RuntimeState,\n target: CachedElement,\n fields: Readonly<Record<string, unknown>>,\n navigated: boolean,\n): void {\n if (typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__) return;\n const rows = rowsOnPath(fields, target.fieldName);\n if (rows === undefined) return;\n // A replay still shows the page being left: the next message starts afresh.\n if (navigated) {\n state.rowsOfBinding.delete(target.element);\n return;\n }\n const prior = state.rowsOfBinding.get(target.element);\n state.rowsOfBinding.set(target.element, rows);\n if (prior === undefined || prior === rows) return;\n // The rows, not the value: rows of equal text move without a new value.\n reportUnfaithfulPatch(deps, state, target, 'stands in a row that moved', rows);\n}\n","/**\n * Resolve and enforce the document owner scope shared by every update stage.\n * Keeping the warning here makes every caller use the same fail-closed decision.\n */\n\nimport { messageOwnerKeys, readDocumentId } from './binding-owner';\nimport type { RuntimeDeps, RuntimeState, UpdateTransaction } from './runtime-state';\nimport type { OwnerScope } from './unbound-fields';\n\nexport function ownerKeysForUpdate(\n deps: RuntimeDeps,\n state: RuntimeState,\n transaction: UpdateTransaction,\n fields: Record<string, unknown>,\n): OwnerScope {\n if (!deps.scopeBindingsByOwner) return false;\n const { message } = transaction;\n const keys = messageOwnerKeys({\n globalSlug: typeof message.globalSlug === 'string' ? message.globalSlug : undefined,\n collectionSlug: typeof message.collectionSlug === 'string' ? message.collectionSlug : undefined,\n documentId: readDocumentId(fields),\n });\n if (keys === null && !state.warnedUnattributableMessage) {\n state.warnedUnattributableMessage = true;\n deps.warn(\n '[live-preview] LP0202: scopeBindingsByOwner: update names no document; nothing applied',\n );\n }\n return keys;\n}\n","/**\n * Keeps a locally retained navigation document aligned with DOM that arrives\n * after the router's commit. It scopes late work to newly discovered targets\n * and never treats the replay as fresh editor traffic.\n */\n\nimport type { PayloadLivePreviewData } from '@/types/payload-protocol';\nimport { isBindingInScope } from './binding-owner';\nimport {\n DEPENDS_ATTRIBUTE,\n FIELD_ATTRIBUTE,\n resolveBindingOwner,\n STRATEGY_ATTRIBUTE,\n} from './cache';\nimport { parseDependencyList } from './dependencies';\nimport { bindingValue } from './field-value';\nimport { dispatchIslandUpdate, isAwaitingIslandHydration } from './islands';\nimport type { RuntimeDeps, RuntimeState, UpdateTransaction } from './runtime-state';\nimport { planBoundaries, resolveStrategy, type FragmentPlan } from './strategies';\nimport type { OwnerScope } from './unbound-fields';\nimport { ownerKeysForUpdate } from './update-owner';\n\ninterface NavigationReplayHost {\n readonly schedule: (\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n elements: ReadonlySet<Element>,\n ) => void;\n}\n\nexport class NavigationReplay {\n private readonly awaitingHydration = new WeakSet<Element>();\n /** A fallback flush may carry the same snapshot after the no-patch handoff. */\n private readonly delivered = new WeakMap<PayloadLivePreviewData, WeakSet<Element>>();\n /** Each island confirms a revision once, however often it is handed it (ADR 0023). */\n private readonly confirmations = new WeakMap<\n Element,\n { readonly transaction: UpdateTransaction; readonly displayed: () => void }\n >();\n\n constructor(\n private readonly deps: RuntimeDeps,\n private readonly state: RuntimeState,\n private readonly host: NavigationReplayHost,\n ) {}\n\n reapplyBindings(elements: ReadonlySet<Element>): void {\n const transaction = this.currentTransaction();\n if (transaction?.renderData === undefined) return;\n this.host.schedule(transaction, transaction.renderData, elements);\n }\n\n reapplyIslands(islands: readonly Element[], hydrationCompleted = false): void {\n const replay = hydrationCompleted\n ? islands.filter((island) => this.awaitingHydration.delete(island))\n : islands;\n const active = this.state.activeUpdate;\n const transaction =\n hydrationCompleted && active !== null && this.state.isCurrent(active)\n ? active\n : this.currentTransaction();\n if (transaction?.renderData === undefined) return;\n this.dispatchIslands(transaction, transaction.renderData, replay);\n }\n\n dispatchIslands(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n islands: readonly Element[],\n ): void {\n const ownerKeys = ownerKeysForUpdate(this.deps, this.state, transaction, data.fields);\n const isCurrent = (): boolean => !transaction.cancelled && this.state.isCurrent(transaction);\n if (!isCurrent()) return;\n let delivered = this.delivered.get(data);\n if (delivered === undefined) {\n delivered = new WeakSet();\n this.delivered.set(data, delivered);\n }\n for (const island of islands) {\n const owner = resolveBindingOwner(island);\n if (!isCurrent()) return;\n if (ownerKeys !== false && !isBindingInScope(owner, ownerKeys)) {\n this.awaitingHydration.delete(island);\n continue;\n }\n // Counted while it hydrates too: it owes the revision a render.\n const displayed = this.confirmation(island, transaction);\n if (isAwaitingIslandHydration(island)) {\n this.awaitingHydration.add(island);\n } else {\n this.awaitingHydration.delete(island);\n if (delivered.has(island)) continue;\n // Claim before calling application code: it can re-enter this fanout.\n delivered.add(island);\n dispatchSnapshotToIslands(transaction, data, [island], isCurrent, displayed);\n }\n }\n }\n\n hasLateRouteBinding(\n elements: ReadonlySet<Element>,\n ownerKeys: OwnerScope,\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n ): boolean {\n for (const element of elements) {\n if (\n (element.getAttribute(FIELD_ATTRIBUTE) ?? '').length > 0 ||\n element.getAttribute(STRATEGY_ATTRIBUTE) !== 'route'\n ) {\n continue;\n }\n if (ownerKeys !== false && !isBindingInScope(resolveBindingOwner(element), ownerKeys)) {\n continue;\n }\n const dependsOn = parseDependencyList(element.getAttribute(DEPENDS_ATTRIBUTE));\n if (dependsOn.length === 0 || dependsOn.some((field) => transaction.touched.has(field))) {\n return true;\n }\n }\n for (const [fieldName, bindings] of this.deps.cache.entries()) {\n for (const target of bindings) {\n if (!elements.has(target.element)) continue;\n if (ownerKeys !== false && !isBindingInScope(target.owner, ownerKeys)) continue;\n const kind = target.strategyKind ?? resolveStrategy(target.element) ?? 'unknown';\n if (kind !== 'route') continue;\n const value = bindingValue(data.fields, target, fieldName, transaction.locale);\n if (!this.state.isCurrent(transaction)) return false;\n if (value !== undefined) return true;\n }\n }\n return false;\n }\n\n fieldsForElements(\n elements: ReadonlySet<Element>,\n touched: ReadonlySet<string>,\n ): ReadonlySet<string> {\n const fields = new Set(touched);\n for (const [fieldName, bindings] of this.deps.cache.entries()) {\n if (bindings.some((target) => elements.has(target.element))) fields.add(fieldName);\n }\n return fields;\n }\n\n /**\n * The boundaries of `plan` this revision has not rendered yet. `null` stays\n * the answer for a page without a fragment strategy only: a plan left with no\n * boundary still has a handler, and the pipeline reads `null` as LP0806.\n */\n unrunFragmentPlan(\n transaction: UpdateTransaction,\n plan: FragmentPlan | null,\n onlyElements: ReadonlySet<Element> | undefined,\n ): FragmentPlan | null {\n if (plan === null) return null;\n const boundaries = plan.boundaries.filter(\n (boundary) =>\n !transaction.fragmentBoundariesRun.has(boundary) &&\n (onlyElements === undefined ||\n [...onlyElements].some((element) => element === boundary || boundary.contains(element))),\n );\n return planBoundaries(plan.strategy, boundaries, plan.ownerKeys);\n }\n\n private confirmation(island: Element, transaction: UpdateTransaction): () => void {\n const held = this.confirmations.get(island);\n if (held?.transaction === transaction) return held.displayed;\n const displayed = this.state.display.handIsland(transaction);\n this.confirmations.set(island, { transaction, displayed });\n return displayed;\n }\n\n private currentTransaction(): UpdateTransaction | null {\n const transaction = this.state.activeUpdate;\n return this.state.navigationBindingReplay &&\n transaction !== null &&\n this.state.isCurrent(transaction)\n ? transaction\n : null;\n }\n}\n\nexport function dispatchSnapshotToIslands(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n islands: readonly Element[],\n isCurrent: () => boolean,\n displayed: () => void,\n): void {\n dispatchIslandUpdate(\n islands,\n {\n fields: data.fields,\n revision: transaction.revision.revision,\n receivedAt: transaction.receivedAt,\n locale: transaction.locale,\n displayed,\n },\n isCurrent,\n );\n}\n","/**\n * A scalar field arrived for which the page has no binding. What that means\n * depends on the value that came with it, so two codes say two things. An\n * empty string with no anchor is LP0201: the template most likely renders the\n * anchor only while the field is non-empty, and an edit has nowhere to land. A\n * value with no anchor is LP0203: the page does not show this field, which on\n * a page that renders a subset of the document is the normal case — the line\n * says where the fact is visible instead of asking for an anchor the page\n * never meant to have.\n *\n * Reported once per field name, because the cause is the markup rather than the\n * edit. `onUnfaithfulPatch` acts on the same fact per revision; both read the\n * addressability rules from `unbound-fields.ts`.\n */\n\nimport { isDevMode } from '@detection/environment';\nimport type { ElementCache } from './cache';\nimport type { RuntimeDeps } from './runtime-state';\nimport {\n createFieldAddressability,\n ownsAnyBinding,\n stripLocaleSuffix,\n SYSTEM_FIELD_NAMES,\n uncoveredDocumentPaths,\n type FieldAddressability,\n type OwnerScope,\n} from './unbound-fields';\n\n/** Marks the warning as said, in the set of field names already warned about. */\nconst COVERAGE_WARNING = ' subfieldCoverage';\n\ninterface OrphanDiagnosticContext {\n readonly cache: ElementCache;\n readonly warned: Set<string>;\n readonly warn: (...args: unknown[]) => void;\n}\n\n/**\n * Asked of the message's own values, not of a merged document: where the form\n * holds the id of an upload, a merge puts the upload's own fields, and those\n * are not fields of this document an anchor could show.\n */\nexport function diagnoseOrphanFields(\n deps: Pick<\n RuntimeDeps,\n 'cache' | 'warn' | 'subfieldCoverage' | 'strategies' | 'coverageByDefault'\n >,\n warned: Set<string>,\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n): void {\n const { cache, strategies } = deps;\n const context: OrphanDiagnosticContext = { cache, warned, warn: deps.warn };\n if (cache.fieldCount === 0) return;\n // With scoping on, a page that renders none of this document is normal.\n if (ownerKeys !== false && !ownsAnyBinding(cache, ownerKeys)) return;\n // A field a configured strategy renders from a boundary or marker is shown.\n const isAddressable = createFieldAddressability(cache, locale, ownerKeys, strategies);\n for (const [rawName, value] of Object.entries(fields)) {\n if (SYSTEM_FIELD_NAMES.has(rawName)) continue;\n // Only scalars: an unbound relationship or block array is a template\n // decision, not the missing anchor this code is about.\n if (isBindableScalar(value)) {\n report(context, isAddressable, rawName, locale, value);\n continue;\n }\n if (!isPlainObject(value) || isAddressable(rawName) || isJoinResult(value)) continue;\n // A group with no anchor anywhere. `admission.priceFrom` is as bindable as\n // `slug` and was reported as neither, so the report names the scalar\n // instead of staying silent about the object around it. One level only:\n // deeper the shape is a rich-text tree more often than a group, and an\n // array's missing anchor stays a template decision at every depth.\n //\n // Restrained to a group the predicate above already calls unaddressable,\n // which is what keeps this in step with `onUnfaithfulPatch`: it escalates\n // on exactly these fields, and this says the same thing more precisely.\n const group = stripLocaleSuffix(rawName, locale);\n for (const [childName, childValue] of Object.entries(value)) {\n if (!isBindableScalar(childValue) || SYSTEM_FIELD_NAMES.has(childName)) continue;\n report(context, isAddressable, `${group}.${childName}`, locale, childValue);\n }\n }\n if (deps.subfieldCoverage !== 'declared') {\n warnCoverageDefault(deps, warned, fields, locale, ownerKeys);\n return;\n }\n // ADR 0022: inside a group the page reaches only below the top level, each\n // uncovered path is named the same way, scalars and one level of a group.\n const uncovered = uncoveredDocumentPaths(cache, fields, locale, ownerKeys, strategies);\n for (const { path, value } of uncovered) {\n if (isBindableScalar(value)) report(context, isAddressable, path, locale, value);\n if (!isPlainObject(value) || isJoinResult(value)) continue;\n for (const [childName, childValue] of Object.entries(value)) {\n if (isBindableScalar(childValue)) {\n report(context, isAddressable, `${path}.${childName}`, locale, childValue);\n }\n }\n }\n}\n\n/**\n * Once, in development, for a page that left the option alone: under `declared`,\n * the 3.0 default, a path no binding names asks for the route, where today a\n * binding beside it covers it and an edit there changes nothing on the page.\n */\nfunction warnCoverageDefault(\n deps: Pick<RuntimeDeps, 'cache' | 'warn' | 'strategies' | 'coverageByDefault'>,\n warned: Set<string>,\n fields: Record<string, unknown>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n): void {\n if (typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__) return;\n if (!deps.coverageByDefault || warned.has(COVERAGE_WARNING) || !isDevMode()) return;\n warned.add(COVERAGE_WARNING);\n const [first] = uncoveredDocumentPaths(deps.cache, fields, locale, ownerKeys, deps.strategies);\n if (first === undefined) return;\n deps.warn(\n `[live-preview] LP0204: no binding names \"${first.path}\", and a binding elsewhere in its group ` +\n 'covers it, so an edit there changes nothing on the page. 3.0 makes ' +\n \"subfieldCoverage: 'declared' the default, where it refreshes the route. Set the option to choose now.\",\n );\n}\n\nfunction report(\n context: OrphanDiagnosticContext,\n isAddressable: FieldAddressability,\n name: string,\n locale: string | undefined,\n value: unknown,\n): void {\n const { warned, warn } = context;\n if (warned.has(name) || isAddressable(name)) return;\n warned.add(name);\n const attribute = `data-payload-field=\"${stripLocaleSuffix(name, locale)}\"`;\n if (value === '') {\n warn(\n `[live-preview] LP0201: no <… ${attribute}> for the empty field \"${name}\"; ` +\n 'render the anchor unconditionally so edits to an empty field have somewhere to land.',\n );\n return;\n }\n warn(\n `[live-preview] LP0203: field \"${name}\" has a value and no <… ${attribute}> on this page; editing it ` +\n 'changes nothing here. Expected where the page shows part of the document: inspect().fidelity.fields ' +\n 'lists these, onUnfaithfulPatch decides whether a server render is asked for.',\n );\n}\n\nfunction isBindableScalar(value: unknown): boolean {\n const type = typeof value;\n return type === 'string' || type === 'number' || type === 'boolean' || type === 'bigint';\n}\n\n/**\n * What Payload puts in a join field: other documents and the page metadata\n * beside them (`hasNextPage`, `totalDocs`). A join is virtual, so nothing in it\n * is a field of this document an editor types into or a page anchors.\n */\nfunction isJoinResult(value: Record<string, unknown>): boolean {\n return Array.isArray(value['docs']) && typeof value['hasNextPage'] === 'boolean';\n}\n\n/** A group, as opposed to an array or a null: the one shape worth looking into. */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","/**\n * Trusted Types: every HTML sink routes through one policy, `payload-live-preview`,\n * whose `createHTML` is the identity — what reaches a sink is already sanitized\n * or escaped. Without the API, strings pass through untouched.\n */\n\n/** The subset of the Trusted Types API this module needs. */\nexport interface TrustedHtmlPolicyLike {\n createHTML(input: string): unknown;\n}\n\ninterface TrustedTypesFactoryLike {\n createPolicy(\n name: string,\n rules: { createHTML: (input: string) => string },\n ): TrustedHtmlPolicyLike;\n}\n\n/** @internal */\nexport const TRUSTED_TYPES_POLICY_NAME = 'payload-live-preview';\n\n// Held on the realm, not in this module: every package entry is its own bundle\n// with its own copy of this file, and a page's `trusted-types` directive allows\n// the name once. A second copy that asked for it again would be refused and fall\n// back to strings; instead every copy shares the one policy, and a policy set\n// through one entry reaches the others.\nconst SLOT: unique symbol = Symbol.for('payload-live-preview.trusted-types');\ninterface SharedPolicies {\n override?: TrustedHtmlPolicyLike | null | undefined;\n auto?: TrustedHtmlPolicyLike | null | undefined;\n}\ninterface Realm {\n [SLOT]?: SharedPolicies | undefined;\n}\nfunction shared(): SharedPolicies {\n const realm = globalThis as Realm;\n const existing = realm[SLOT];\n if (existing !== undefined) return existing;\n const created: SharedPolicies = {};\n realm[SLOT] = created;\n return created;\n}\n\n/**\n * Use `policy` for every sink, `null` to assign plain strings, `undefined` to\n * return to the auto-created package policy.\n */\nexport function setTrustedTypesPolicy(policy: TrustedHtmlPolicyLike | null | undefined): void {\n shared().override = policy;\n}\n\nfunction factory(): TrustedTypesFactoryLike | undefined {\n const candidate = (globalThis as { trustedTypes?: unknown }).trustedTypes;\n if (typeof candidate !== 'object' || candidate === null) return undefined;\n const create = (candidate as { createPolicy?: unknown }).createPolicy;\n return typeof create === 'function' ? (candidate as TrustedTypesFactoryLike) : undefined;\n}\n\nfunction resolvePolicy(): TrustedHtmlPolicyLike | null {\n const policies = shared();\n if (policies.override !== undefined) return policies.override;\n if (policies.auto !== undefined) return policies.auto;\n const api = factory();\n try {\n policies.auto =\n api === undefined\n ? null\n : api.createPolicy(TRUSTED_TYPES_POLICY_NAME, { createHTML: (input) => input });\n } catch {\n // The site's `trusted-types` directive does not list this name; the\n // sink assignment will surface the enforcement error.\n policies.auto = null;\n }\n return policies.auto;\n}\n\n/** `html` as a `TrustedHTML` when a policy exists, else the string. Typed `string` for `innerHTML`. @internal */\nexport function trustedHtml(html: string): string {\n const policy = resolvePolicy();\n if (policy === null) return html;\n return policy.createHTML(html) as string;\n}\n\n/** Test hook: forget the auto-created policy. */\nexport function __resetTrustedTypesForTests(): void {\n (globalThis as Realm)[SLOT] = undefined;\n}\n","/**\n * Keyed DOM morph, the engine: edits a live element toward a freshly rendered\n * one while retaining compatible, paired live nodes. Those nodes keep their\n * live properties; an incompatible or unpaired node is replaced and loses\n * them. It pairs children by key or position, synchronises attributes with the\n * state exception and keeps focus across a retained move; which subtrees it\n * never enters is the coordinator's rule, handed in as\n * `MorphOptions.boundary` and defaulting to the package's (`isMorphBoundary`\n * in islands.ts). See ADR 0008, §9 for the line between the two. A custom\n * element is such a boundary unless both of its sides carry\n * `data-payload-morph` (§10).\n */\n\nimport { isMorphBoundary } from './islands';\n\n/** Attributes the CMS controls only when the template names them (ADR 0008 §3). */\nconst STATE_ATTRIBUTES: ReadonlySet<string> = new Set(['open', 'value', 'checked', 'selected']);\n\n/** @beta */\nexport interface MorphOptions {\n /** Attributes that key child elements for pairing, tried in order; unkeyed children pair by position. */\n readonly keyAttributes: readonly string[];\n /** Called once per parent when two children share a key; the later ones pair by position. */\n readonly onDuplicateKey?: (parent: Element, key: string) => void;\n /** Elements whose attributes are synchronised but whose children are left alone (nested structural slots). */\n readonly retainChildrenOf?: (live: Element, rendered: Element) => boolean;\n /**\n * The ownership rule: a structurally compatible live/rendered pair for\n * which this returns `true` on both sides is retained whole and never\n * entered (ADR 0008 §4). The package's rule — custom elements, islands,\n * `contenteditable`, `data-payload-owned` — is the default. A supplied rule\n * replaces that default; compose it with the exported `isMorphBoundary`\n * predicate to add package-compatible boundaries.\n */\n readonly boundary?: (element: Element) => boolean;\n /**\n * Decides a live/rendered pair that are both boundaries: `true` keeps the\n * live one, after any handoff to its owner; `false` replaces it with the\n * rendered one. Without it every such pair is kept whole (ADR 0008 §4). The\n * package's coordinators hand in `retainIslandBoundary`, under which an\n * Astro island that still renders the same component takes the rendered\n * props through Astro's own handoff (ADR 0021).\n */\n readonly retainBoundary?: (live: Element, rendered: Element) => boolean;\n}\n\n/** Empty attribute values (boolean markers such as `data-payload-island`) are not keys. */\nfunction keyOf(element: Element, options: MorphOptions): string | undefined {\n for (const attribute of options.keyAttributes) {\n const value = element.getAttribute(attribute);\n if (value !== null && value.length > 0) return `${attribute}=${value}`;\n }\n return undefined;\n}\n\n/** Whether `live` can be edited toward `rendered` instead of being replaced by it, under `boundary` (the package's rule by default). @internal */\nexport function isMorphCompatible(\n live: Element,\n rendered: Element,\n boundary: (element: Element) => boolean = isMorphBoundary,\n): boolean {\n return (\n live.tagName === rendered.tagName &&\n live.namespaceURI === rendered.namespaceURI &&\n !boundary(live) &&\n !boundary(rendered)\n );\n}\n\n/**\n * Morph `live` toward `rendered`. Returns `live` when it was retained, or\n * `rendered` when the two are incompatible and the caller must replace.\n * `rendered` is consumed: its children may move into `live`.\n *\n * @beta\n */\nexport function morphElement(live: Element, rendered: Element, options: MorphOptions): Element {\n if (!sameKind(live, rendered)) return rendered;\n const boundary = options.boundary ?? isMorphBoundary;\n const liveBoundary = boundary(live);\n const renderedBoundary = boundary(rendered);\n if (liveBoundary || renderedBoundary) {\n if (!liveBoundary || !renderedBoundary) return rendered;\n return (options.retainBoundary?.(live, rendered) ?? true) ? live : rendered;\n }\n const focus = captureFocus(live);\n syncAttributes(live, rendered);\n if (options.retainChildrenOf?.(live, rendered) !== true) morphChildren(live, rendered, options);\n restoreFocus(focus);\n return live;\n}\n\n/** Match attributes, except that state-bearing ones change only when `rendered` carries them. */\nexport function syncAttributes(live: Element, rendered: Element): void {\n for (const attribute of Array.from(live.attributes)) {\n if (rendered.hasAttribute(attribute.name)) continue;\n if (STATE_ATTRIBUTES.has(attribute.name.toLowerCase())) continue;\n live.removeAttribute(attribute.name);\n }\n for (const attribute of Array.from(rendered.attributes)) {\n if (live.getAttribute(attribute.name) !== attribute.value) {\n live.setAttribute(attribute.name, attribute.value);\n }\n }\n}\n\nfunction morphChildren(live: Element, rendered: Element, options: MorphOptions): void {\n const liveKeyed = indexKeyed(live, options);\n const keyedElements = new Set<Node>(liveKeyed.values());\n const liveUnkeyed = Array.from(live.childNodes).filter((node) => !keyedElements.has(node));\n const claimed = new Set<Node>();\n const usedKeys = new Set<string>();\n const renderedNodes = Array.from(rendered.childNodes);\n let cursor: Node | null = live.firstChild;\n let unkeyedIndex = 0;\n\n for (let i = 0; i < renderedNodes.length; i += 1) {\n const next = renderedNodes[i] as Node;\n let kept: Node | null = null;\n let key = next instanceof Element ? keyOf(next, options) : undefined;\n // A repeated key on the rendered side pairs positionally like a live duplicate.\n if (key !== undefined && usedKeys.has(key)) key = undefined;\n if (key !== undefined) {\n usedKeys.add(key);\n const candidate = liveKeyed.get(key);\n if (candidate !== undefined && !claimed.has(candidate)) {\n kept = reconcile(candidate, next, options) === candidate ? candidate : null;\n if (kept === null) {\n candidate.replaceWith(next);\n claimed.add(next);\n cursor = next.nextSibling;\n continue;\n }\n }\n } else {\n while (unkeyedIndex < liveUnkeyed.length) {\n const candidate = liveUnkeyed[unkeyedIndex] as Node;\n unkeyedIndex += 1;\n if (claimed.has(candidate)) continue;\n if (sameKind(candidate, next)) {\n kept = reconcile(candidate, next, options) === candidate ? candidate : null;\n if (kept === null) {\n live.replaceChild(next, candidate);\n claimed.add(next);\n cursor = next.nextSibling;\n }\n break;\n }\n if (candidate instanceof Element) {\n // `next` is a text/comment, or an element whose kind the following\n // rendered node matches: an insertion, so the live element stays for it.\n const following = renderedNodes[i + 1];\n if (\n !(next instanceof Element) ||\n (following !== undefined && sameKind(candidate, following))\n ) {\n unkeyedIndex -= 1;\n break;\n }\n live.replaceChild(next, candidate);\n claimed.add(next);\n cursor = next.nextSibling;\n break;\n }\n if (!(next instanceof Element)) {\n // Text vs comment: replace rather than rewrite one node type's value into the other.\n live.replaceChild(next, candidate);\n claimed.add(next);\n cursor = next.nextSibling;\n break;\n }\n // A surplus live text/comment before the element `next` needs; removed below.\n }\n if (kept === null && claimed.has(next)) continue;\n }\n\n const node: Node = kept ?? next;\n claimed.add(node);\n // Whitespace-only text the template did not render is surplus. Stepping the\n // cursor over it keeps a retained element where it is: `insertBefore` on a\n // node already in the tree is a remove-and-insert, which blurs a focused input.\n while (cursor !== null && cursor !== node && !claimed.has(cursor) && isBlankText(cursor)) {\n cursor = cursor.nextSibling;\n }\n if (node !== cursor) live.insertBefore(node, cursor);\n cursor = node.nextSibling;\n }\n\n for (const child of Array.from(live.childNodes)) {\n if (!claimed.has(child)) child.remove();\n }\n}\n\n/** Retain `candidate` when it can be edited toward `next`; otherwise report `next`. */\nfunction reconcile(candidate: Node, next: Node, options: MorphOptions): Node {\n if (candidate instanceof Element && next instanceof Element) {\n return morphElement(candidate, next, options);\n }\n if (candidate.nodeValue !== next.nodeValue) candidate.nodeValue = next.nodeValue;\n return candidate;\n}\n\nfunction isBlankText(node: Node): boolean {\n return node.nodeType === Node.TEXT_NODE && (node.nodeValue ?? '').trim().length === 0;\n}\n\nfunction sameKind(a: Node, b: Node): boolean {\n if (a.nodeType !== b.nodeType) return false;\n if (a instanceof Element && b instanceof Element) {\n return a.tagName === b.tagName && a.namespaceURI === b.namespaceURI;\n }\n return true;\n}\n\n/** First element per key; later duplicates are left as they are and pair positionally. */\nfunction indexKeyed(parent: Element, options: MorphOptions): Map<string, Element> {\n const keyed = new Map<string, Element>();\n let duplicate: string | undefined;\n for (const child of Array.from(parent.children)) {\n const key = keyOf(child, options);\n if (key === undefined) continue;\n if (keyed.has(key)) {\n duplicate ??= key.slice(key.indexOf('=') + 1);\n continue;\n }\n keyed.set(key, child);\n }\n if (duplicate !== undefined) options.onDuplicateKey?.(parent, duplicate);\n return keyed;\n}\n\n/** @internal */\nexport interface FocusSnapshot {\n readonly element: HTMLElement;\n readonly selection: readonly [number | null, number | null] | null;\n}\n\n/**\n * A keyed move is a remove-and-insert, which blurs; remember what had focus.\n * The structural applier moves items itself and uses the same pair around\n * its commit, so a move it makes keeps focus the way a move the morph makes\n * does (ADR 0008 §1). @internal\n */\nexport function captureFocus(live: Element): FocusSnapshot | null {\n const active = live.ownerDocument.activeElement;\n if (!(active instanceof HTMLElement) || !live.contains(active)) return null;\n const selection =\n active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement\n ? ([active.selectionStart, active.selectionEnd] as const)\n : null;\n return { element: active, selection };\n}\n\n/** @internal */\nexport function restoreFocus(snapshot: FocusSnapshot | null): void {\n if (snapshot === null) return;\n const { element, selection } = snapshot;\n if (element.ownerDocument.activeElement === element || !element.isConnected) return;\n try {\n element.focus({ preventScroll: true });\n const [start, end] = selection ?? [null, null];\n if (start !== null && end !== null) {\n (element as HTMLInputElement).setSelectionRange(start, end);\n }\n } catch {\n // Not focusable any more; nothing to restore.\n }\n}\n","/**\n * LP0409 — what the strict sanitizer removed that the 1.x default kept.\n *\n * `sanitizerPolicy` defaults to `'strict'` since 2.0; before that it was\n * `'compat'`, which let `id` and every `data-*` through, and `name` only where\n * a per-tag list allowed it. The difference\n * only shows when a binding *writes* markup, so a project that upgrades and\n * whose rich text carries its own hooks loses them at the moment an editor\n * types — silently, and in the preview only. Measured on a real consumer: a\n * `data-partner-scroll` attribute driving a CSS selector disappeared on the\n * first write, with nothing said anywhere.\n *\n * So it is said here: once per attribute name per page, with the reason that\n * applies to that name rather than one sentence covering three different\n * decisions. This is a report, never a behaviour — the attribute stays removed.\n */\n\n/**\n * `console.warn` behind a try/catch rather than `@core/diagnostics`: `security`\n * is a leaf layer and may not import `core` (scripts/architecture-rules.ts), and\n * the shared helper's extra work — tolerating a logger that returns a thenable —\n * is for consumer-supplied loggers. This sink is fixed.\n */\nfunction warn(message: string): void {\n try {\n console.warn(message);\n } catch {\n // A diagnostic must never become a second failure.\n }\n}\n\nconst reported = new Set<string>();\n\n/** The binding prefix, restated rather than imported: this module must not pull the applier in. */\nconst BINDING_PREFIX = 'data-payload-';\n\nfunction reason(name: string): string {\n if (name.startsWith(BINDING_PREFIX)) {\n return (\n 'A binding inside CMS content is refused by design — an editor could otherwise ' +\n 'aim a write at any element on the page (docs/security.md)'\n );\n }\n if (name === 'id' || name === 'name') {\n return (\n 'CMS content that can name an element can shadow a global of that name — ' +\n 'DOM clobbering, refused by design (docs/security.md)'\n );\n }\n return (\n 'Put it on an element the template owns, or set ' +\n \"`sanitizerPolicy: 'compat'` to keep every `data-*` as 1.x did\"\n );\n}\n\n/**\n * Report one removal. Only for attributes `'compat'` would have kept: everything\n * else the sanitizer drops was refused in 1.x too and is not news to anyone.\n */\nexport function reportDroppedAttribute(name: string): void {\n if (reported.has(name)) return;\n reported.add(name);\n warn(\n `[live-preview] LP0409: the strict sanitizer removed \\`${name}\\` from written markup; ` +\n `the 1.x default (\\`sanitizerPolicy: 'compat'\\`) kept it. ${reason(name)}.`,\n );\n}\n\n/** Test seam: the report is once per page, and a test is not a page. */\nexport function resetDroppedAttributeReports(): void {\n reported.clear();\n}\n","/**\n * HTML sanitizer built on the host parser (`<template>`): allow-listed tags\n * and attributes, validated URLs, hardened external links, no `style`.\n * Needs a DOM; string-only sanitizers are historically brittle.\n */\n\nimport { warnOnce } from '@/types/dev-warning';\nimport { trustedHtml } from './trusted-types';\nimport { isSafeUrl, isExternalHttpUrl } from './url-validator';\nimport { reportDroppedAttribute } from './sanitizer-report';\n\ndeclare const __INLINE_BUILD__: boolean | undefined;\n\n/** Tags kept with their content. Others are unwrapped unless in `REMOVE_COMPLETELY`. */\nconst ALLOWED_TAGS: ReadonlySet<string> = new Set([\n 'p',\n 'br',\n 'strong',\n 'b',\n 'em',\n 'i',\n 'u',\n 's',\n 'strike',\n 'mark',\n 'small',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'ul',\n 'ol',\n 'li',\n 'dl',\n 'dt',\n 'dd',\n 'blockquote',\n 'code',\n 'pre',\n 'kbd',\n 'samp',\n 'var',\n 'a',\n 'span',\n 'div',\n 'section',\n 'article',\n 'aside',\n 'header',\n 'footer',\n 'nav',\n 'figure',\n 'figcaption',\n 'img',\n 'picture',\n 'source',\n 'audio',\n 'video',\n 'sub',\n 'sup',\n 'hr',\n 'time',\n 'abbr',\n 'cite',\n 'q',\n 'table',\n 'thead',\n 'tbody',\n 'tfoot',\n 'tr',\n 'th',\n 'td',\n 'caption',\n 'colgroup',\n 'col',\n]);\n\n/** Tags `allowFormControls` re-admits for author templates; `form` is deliberately not one. */\nconst FORM_CONTROLS: ReadonlySet<string> = new Set([\n 'input',\n 'button',\n 'textarea',\n 'select',\n 'option',\n 'label',\n]);\n\n/** Removed with their children: the content itself is the hazard. */\nconst REMOVE_COMPLETELY: ReadonlySet<string> = new Set([\n 'script',\n 'style',\n 'iframe',\n 'object',\n 'embed',\n 'link',\n 'meta',\n 'base',\n 'form',\n 'input',\n 'button',\n 'select',\n 'textarea',\n 'svg',\n 'math',\n 'template',\n 'frame',\n 'frameset',\n 'noframes',\n 'noscript',\n]);\n\nconst ATTR_GLOBAL: ReadonlySet<string> = new Set([\n 'id',\n 'class',\n 'lang',\n 'dir',\n 'title',\n 'role',\n 'tabindex',\n]);\n\nconst ATTR_ARIA_PREFIX = 'aria-';\nconst ATTR_DATA_PREFIX = 'data-';\nconst BINDING_DATA_PREFIX = 'data-payload-';\n\nconst ATTR_BY_TAG: Readonly<Record<string, ReadonlySet<string>>> = {\n a: new Set(['href', 'target', 'rel', 'download', 'hreflang', 'type']),\n img: new Set(['src', 'srcset', 'sizes', 'alt', 'width', 'height', 'loading', 'decoding']),\n picture: new Set([]),\n source: new Set(['src', 'srcset', 'sizes', 'type', 'media']),\n audio: new Set(['src', 'controls', 'autoplay', 'loop', 'muted', 'preload']),\n video: new Set([\n 'src',\n 'poster',\n 'controls',\n 'autoplay',\n 'loop',\n 'muted',\n 'preload',\n 'width',\n 'height',\n 'playsinline',\n ]),\n time: new Set(['datetime']),\n abbr: new Set(['title']),\n q: new Set(['cite']),\n blockquote: new Set(['cite']),\n table: new Set(['summary']),\n th: new Set(['colspan', 'rowspan', 'scope', 'headers', 'abbr']),\n td: new Set(['colspan', 'rowspan', 'headers']),\n col: new Set(['span']),\n colgroup: new Set(['span']),\n ol: new Set(['start', 'reversed', 'type']),\n li: new Set(['value']),\n code: new Set(['class']),\n pre: new Set(['class']),\n};\n\n// Checked however the attribute was admitted: `additionalAllowedAttributes` can re-admit the form ones.\nconst URL_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'href',\n 'src',\n 'cite',\n 'poster',\n 'action',\n 'formaction',\n]);\n\n/** Parses `sanitizeHtml` spends before it gives up on an output that will not settle. */\nconst MAX_PASSES = 6;\n\n// Numeric nodeType constants keep an injected SSR document independent of a\n// browser-global `Node` constructor.\nconst ELEMENT_NODE = 1;\nconst COMMENT_NODE = 8;\n\n/** Thrown by `sanitizeHtml()` without a `document`, or with one that cannot write what it cleaned. */\nexport class SanitizerEnvironmentError extends Error {\n override readonly name = 'SanitizerEnvironmentError';\n}\n\n/**\n * `'strict'` (default) strips `id`, `name` and `data-payload-*` and passes\n * other `data-*` only via `allowedDataAttributes`; `'compat'` keeps them.\n */\nexport type SanitizerPolicyMode = 'compat' | 'strict';\n\nexport interface SanitizeOptions {\n /** Overrides the module default set by `setSanitizerPolicy()`. */\n readonly policy?: SanitizerPolicyMode;\n /** `data-*` attributes (full names) that pass under `'strict'`; `data-payload-*` never does. */\n readonly allowedDataAttributes?: readonly string[];\n /**\n * Keep `input`, `button`, `textarea`, `select`, `option` and `label` — only\n * for markup the page author wrote, never for CMS content. `form`,\n * handlers, `style` and unsafe URLs stay dropped.\n */\n readonly allowFormControls?: boolean;\n /** Extra tags to allow. Lower-case, untrimmed. */\n readonly additionalAllowedTags?: readonly string[];\n /**\n * Extra per-tag attributes, lower-case. Cannot re-admit handlers, `style`, or —\n * under `'strict'` — `id`, `name` and `data-payload-*`; their URLs are checked.\n */\n readonly additionalAllowedAttributes?: Readonly<Record<string, readonly string[]>>;\n /**\n * The input is a page-author item template, so `'strict'` keeps the\n * applier's reconciliation attributes (`TEMPLATE_ATTRIBUTES`) and nothing\n * else — every other `data-payload-*` is still stripped, so a template can\n * never add a binding.\n */\n readonly templateMode?: boolean;\n /**\n * The DOM to parse with, for this call: an SSR document such as linkedom's\n * or jsdom's. Wins over `setSanitizerDocument()` and over the global\n * `document`, and two callers with two documents never share one.\n */\n readonly document?: SanitizerDocument;\n}\n\n/** What `templateMode` keeps under `'strict'`. */\nconst TEMPLATE_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'id',\n 'name',\n 'data-payload-key',\n 'data-payload-morph',\n 'data-payload-nested-key',\n 'data-payload-nested-template',\n]);\n\ninterface ResolvedPolicy {\n readonly allowedTags: ReadonlySet<string>;\n readonly allowFormControls: boolean;\n readonly templateMode: boolean;\n readonly mode: SanitizerPolicyMode;\n readonly allowedData: ReadonlySet<string>;\n readonly attrByTag: ReadonlyMap<string, ReadonlySet<string>>;\n}\n\nlet defaultMode: SanitizerPolicyMode = 'strict';\n\n/**\n * The default for calls without an explicit `policy`, per package entry. A\n * runtime carries its own `sanitizerPolicy` and never writes here (ADR 0002).\n */\nexport function setSanitizerPolicy(mode: SanitizerPolicyMode): void {\n defaultMode = mode;\n}\n\n/** `instancePolicy` sits between a per-call `options.policy` and the process default. */\nfunction resolvePolicy(\n options: SanitizeOptions | undefined,\n instancePolicy: SanitizerPolicyMode | undefined,\n): ResolvedPolicy {\n const mode = options?.policy ?? instancePolicy ?? defaultMode;\n if (!options) {\n const attrMap = new Map<string, ReadonlySet<string>>();\n for (const [tag, attrs] of Object.entries(ATTR_BY_TAG)) attrMap.set(tag, attrs);\n return {\n allowedTags: ALLOWED_TAGS,\n attrByTag: attrMap,\n allowFormControls: false,\n templateMode: false,\n mode,\n allowedData: new Set(),\n };\n }\n const allowed = new Set(ALLOWED_TAGS);\n options.additionalAllowedTags?.forEach((tag) => allowed.add(tag));\n if (options.allowFormControls === true) for (const tag of FORM_CONTROLS) allowed.add(tag);\n const attrMap = new Map<string, ReadonlySet<string>>();\n for (const [tag, attrs] of Object.entries(ATTR_BY_TAG)) attrMap.set(tag, attrs);\n for (const [tag, attrs] of Object.entries(options.additionalAllowedAttributes ?? {})) {\n const merged = new Set(attrMap.get(tag));\n for (const attr of attrs) merged.add(attr);\n attrMap.set(tag, merged);\n }\n return {\n allowedTags: allowed,\n attrByTag: attrMap,\n allowFormControls: options.allowFormControls === true,\n templateMode: options.templateMode === true,\n mode,\n allowedData: new Set(options.allowedDataAttributes?.map((name) => name.toLowerCase())),\n };\n}\n\n/** The `Document` surface the sanitizer needs; jsdom, linkedom and happy-dom all provide it. */\nexport interface SanitizerDocument {\n createElement: (tagName: string) => {\n innerHTML: string;\n readonly content: ParentNode;\n };\n}\n\n// Held on the realm, not in this module: every package entry is its own bundle\n// with its own copy of this file, and a document supplied through the root has\n// to reach the rich text `payload-live-preview/lexical` renders.\nconst DOCUMENT_SLOT: unique symbol = Symbol.for('payload-live-preview.sanitizer-document');\n\ninterface DocumentSlot {\n [DOCUMENT_SLOT]?: SanitizerDocument | undefined;\n}\n\n/**\n * Supply a `Document` for SSR, e.g. linkedom's `parseHTML(...).document`;\n * `null` clears it, for every entry. The fallback for a call that names no\n * document of its own.\n *\n * @deprecated Since 2.1 a call names its document: `sanitizeHtml(html, { document })`,\n * `lexicalToHtml(content, { document })`. The process-wide slot stays until 3.0\n * (ADR 0007 ledger).\n */\nexport function setSanitizerDocument(doc: SanitizerDocument | null): void {\n warnOnce(\n 'set-sanitizer-document',\n '`setSanitizerDocument()` is removed in 3.0: pass the document per call, ' +\n '`sanitizeHtml(html, { document })` or `lexicalToHtml(content, { document })` (ADR 0026).',\n );\n (globalThis as DocumentSlot)[DOCUMENT_SLOT] = doc ?? undefined;\n}\n\n/**\n * Sanitize `html`; malformed input is recovered by the parser first. The\n * result is a fixed point: sanitising it again changes nothing.\n *\n * @throws {SanitizerEnvironmentError} when no DOM is available.\n */\nexport function sanitizeHtml(html: string, options?: SanitizeOptions): string {\n return sanitizeHtmlWithPolicy(html, undefined, options);\n}\n\n/**\n * The runtime's entry: `policy` is one instance's, applied unless `options`\n * carry their own, so two clients on a page never share a policy through\n * this module. Not public — a direct caller has `options.policy`.\n */\nexport function sanitizeHtmlWithPolicy(\n html: string,\n policy: SanitizerPolicyMode | undefined,\n options?: SanitizeOptions,\n): string {\n const doc = options?.document ?? resolveDocument();\n if (!doc) throw environmentError();\n if (html === '') return '';\n\n const resolved = resolvePolicy(options, policy);\n // Unwrapping an unknown tag can leave a tree no parser produces (an `a` in an\n // `a`), and the consumer's `innerHTML` rebuilds it as the parser would. So\n // what is written is parsed and sanitised again until a pass changes nothing\n // (ADR 0016, 2026-10-02): the string returned is the one the consumer gets.\n let markup = html;\n for (let pass = 0; pass < MAX_PASSES; pass += 1) {\n const template = doc.createElement('template');\n // The sanitizer's own parse is a sink too: under Trusted Types it needs the policy.\n template.innerHTML = trustedHtml(markup);\n // Read once, and never write the template back: linkedom's `content` is a\n // copy of the template's children, so the template still held the parse\n // and the input came back unsanitised (2.2.1).\n const fragment = template.content;\n sanitizeFragment(fragment, resolved);\n const written = serialize(fragment);\n if (written === markup) return written;\n markup = written;\n }\n warnOnce(\n 'sanitizer-unsettled',\n `sanitizeHtml: the output did not settle after ${String(MAX_PASSES)} passes, so it returned an empty string (ADR 0016).`,\n );\n return '';\n}\n\n// Read the define at each branch rather than through a helper: a bundler\n// folds the substituted literal in place, but will not inline a call, and the\n// SSR-only class and override must not reach the browser runtime.\nfunction environmentError(): Error {\n if (typeof __INLINE_BUILD__ !== 'undefined' && __INLINE_BUILD__) {\n return new Error('sanitizeHtml needs a DOM');\n }\n return new SanitizerEnvironmentError(\n 'sanitizeHtml needs a DOM; pass one per call during SSR: { document } (linkedom, jsdom).',\n );\n}\n\n/**\n * Writes the cleaned nodes themselves, through an element of their own\n * document, where a browser keeps them inert. No such element, or one that does\n * not end up holding them, would write something else: refused, not returned.\n */\nfunction serialize(fragment: ParentNode): string {\n const writer = fragment.ownerDocument?.createElement('div');\n if (writer === undefined) throw environmentError();\n const first = fragment.firstChild;\n writer.append(fragment);\n if (writer.firstChild !== first) throw environmentError();\n return writer.innerHTML;\n}\n\nfunction resolveDocument(): SanitizerDocument | undefined {\n if (typeof __INLINE_BUILD__ === 'undefined' || !__INLINE_BUILD__) {\n const override = (globalThis as DocumentSlot)[DOCUMENT_SLOT];\n if (override) return override;\n }\n if (typeof document === 'undefined') return undefined;\n return document;\n}\n\n/** Whether a DOM is available — the global or an injected one — for callers that treat sanitizing as optional. */\nexport function hasSanitizerDocument(): boolean {\n return resolveDocument() !== undefined;\n}\n\nfunction sanitizeFragment(node: ParentNode, policy: ResolvedPolicy): void {\n // Snapshot: children are mutated during the walk.\n for (const child of Array.from(node.childNodes)) {\n if (child.nodeType === ELEMENT_NODE) {\n sanitizeElement(child as Element, policy);\n } else if (child.nodeType === COMMENT_NODE) {\n child.remove();\n }\n }\n}\n\nfunction sanitizeElement(element: Element, policy: ResolvedPolicy): void {\n const tag = element.tagName.toLowerCase();\n\n if (REMOVE_COMPLETELY.has(tag) && !(policy.allowFormControls && FORM_CONTROLS.has(tag))) {\n element.remove();\n return;\n }\n\n if (!policy.allowedTags.has(tag)) {\n sanitizeFragment(element, policy);\n element.replaceWith(...element.childNodes);\n return;\n }\n\n sanitizeAttributes(element, tag, policy);\n if (tag === 'a') hardenAnchor(element);\n sanitizeFragment(element, policy);\n}\n\nfunction sanitizeAttributes(element: Element, tag: string, policy: ResolvedPolicy): void {\n const tagAttrs = policy.attrByTag.get(tag);\n\n for (const attr of Array.from(element.attributes)) {\n const name = attr.name.toLowerCase();\n if (name.startsWith('on') || name === 'style') {\n element.removeAttribute(attr.name);\n continue;\n }\n // A parsed element's `is` value is immutable and the serialiser writes it\n // back even after the attribute is gone, so removing it would hand the\n // re-parse the page's customised built-in by name. Emptied instead: an\n // empty `is` names nothing (docs/security.md §5c).\n if (name === 'is') {\n element.setAttribute('is', '');\n continue;\n }\n if (policy.mode === 'strict') {\n if (policy.templateMode && TEMPLATE_ATTRIBUTES.has(name)) continue;\n // DOM clobbering and binding injection (docs/security.md §5c). Checked\n // before the allow-list so an extension cannot re-admit them.\n if (name === 'id' || name === 'name' || name.startsWith(BINDING_DATA_PREFIX)) {\n element.removeAttribute(attr.name);\n // `compat` kept `name` only where a per-tag list allowed it, so only\n // there did the upgrade change anything to report.\n if (name !== 'name' || tagAttrs?.has(name) === true) reportDroppedAttribute(name);\n continue;\n }\n if (name.startsWith(ATTR_DATA_PREFIX)) {\n if (!policy.allowedData.has(name)) {\n element.removeAttribute(attr.name);\n reportDroppedAttribute(name);\n }\n continue;\n }\n if (ATTR_GLOBAL.has(name) || name.startsWith(ATTR_ARIA_PREFIX)) continue;\n } else if (\n ATTR_GLOBAL.has(name) ||\n name.startsWith(ATTR_ARIA_PREFIX) ||\n name.startsWith(ATTR_DATA_PREFIX)\n ) {\n continue;\n }\n if (tagAttrs?.has(name)) {\n if (URL_ATTRIBUTES.has(name) && !isSafeUrl(attr.value)) {\n element.removeAttribute(attr.name);\n } else if (name === 'srcset' && !isSafeSrcset(attr.value)) {\n element.removeAttribute(attr.name);\n } else if (name === 'ping' && !attr.value.trim().split(/\\s+/u).every(isSafeUrl)) {\n // `ping` is a list of URLs; one unsafe target refuses the attribute.\n element.removeAttribute(attr.name);\n }\n continue;\n }\n element.removeAttribute(attr.name);\n }\n}\n\n/** Every `srcset` candidate must pass; partial rewriting would silently change what renders. */\nfunction isSafeSrcset(value: string): boolean {\n for (const candidate of value.split(',')) {\n const trimmed = candidate.trim();\n if (trimmed.length === 0) continue;\n // The URL ends at the first whitespace; what follows is the descriptor. The\n // candidate as a whole must pass too: a scheme can be spelled across that gap.\n const [url = trimmed] = trimmed.split(/\\s/, 1);\n if (!isSafeUrl(url) || !isSafeUrl(trimmed)) return false;\n }\n return true;\n}\n\nfunction hardenAnchor(anchor: Element): void {\n const href = anchor.getAttribute('href');\n if (href === null || !isExternalHttpUrl(href)) return;\n anchor.setAttribute('rel', 'noopener noreferrer');\n if (!anchor.hasAttribute('target')) anchor.setAttribute('target', '_blank');\n}\n\n/** The built-in allow-lists, for documentation and tests. */\nexport const SANITIZER_POLICY = Object.freeze({\n allowedTags: ALLOWED_TAGS,\n removeCompletely: REMOVE_COMPLETELY,\n globalAttributes: ATTR_GLOBAL,\n attributesByTag: ATTR_BY_TAG,\n urlAttributes: URL_ATTRIBUTES,\n});\n","/**\n * One development warning per process. The set of issued keys lives on\n * `globalThis` so two package copies in one process still warn once.\n */\n\nconst WARNED_KEY = '__payloadLivePreviewDeprecationsWarned';\n\n/** `true` outside a production build; `false` when `NODE_ENV` is production or unknown. */\nexport function isDevelopmentProcess(): boolean {\n try {\n const env = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process\n ?.env;\n if (env === undefined) return false;\n return env['NODE_ENV'] !== 'production';\n } catch {\n return false;\n }\n}\n\n/** Warn once per process for `key`, outside production only. */\nexport function warnOnce(key: string, message: string): void {\n if (!isDevelopmentProcess()) return;\n const holder = globalThis as unknown as Record<string, Set<string> | undefined>;\n const warned = (holder[WARNED_KEY] ??= new Set<string>());\n if (warned.has(key)) return;\n warned.add(key);\n try {\n console.warn(`[payload-live-preview] ${message}`);\n } catch {\n // A console that throws must not break a request.\n }\n}\n\n/**\n * The deprecated options the adapters and the inline generator both accept;\n * an adapter hands them on to the generator, and the shared keys keep that to\n * one warning each (ADR 0026).\n */\nexport function warnDeprecatedOptions(options: {\n readonly defaults?: string | undefined;\n readonly onUnboundChange?: string | undefined;\n}): void {\n if (options.defaults === 'v1') {\n warnOnce(\n 'defaults-v1',\n \"`defaults: 'v1'` is removed in 3.0: `pll migrate` writes the 1.x rows it stands for \" +\n 'into your options, where they keep working (ADR 0026).',\n );\n }\n if (options.onUnboundChange !== undefined) {\n warnOnce(\n 'on-unbound-change',\n \"`onUnboundChange` is removed in 3.0: name it `onUnfaithfulPatch`, where 'route' is \" +\n \"'escalate'; `pll migrate` renames it (ADR 0026).\",\n );\n }\n}\n\n/** Test hook: forget every warning issued so far. */\nexport function resetDevWarnings(): void {\n const holder = globalThis as unknown as Record<string, Set<string> | undefined>;\n holder[WARNED_KEY] = undefined;\n}\n","/** HTML and CSS escaping primitives (OWASP XSS Prevention Cheat Sheet). DOM-free. */\n\nconst HTML_ESCAPES: Readonly<Record<string, string>> = Object.freeze({\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n '/': '/',\n '`': '`',\n '=': '=',\n});\n\nconst HTML_ESCAPE_PATTERN = /[&<>\"'/`=]/g;\n\n/** Escape `text` for an element body or a *quoted* attribute value; strings only, and unquoted attributes are not covered. */\nexport function escapeHtml(text: string): string {\n // The character class and the map are coupled: every match is a key.\n // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style\n return text.replace(HTML_ESCAPE_PATTERN, (char) => HTML_ESCAPES[char] as string);\n}\n\n/** Escape a value for a CSS `url(...)` literal; this stops the break-out, not the scheme, so pair it with `isSafeUrl()`. */\nexport function escapeCssUrl(value: string): string {\n return value.replace(/['\"()\\\\]/g, '\\\\$&');\n}\n\nconst ATTR_ESCAPES: Readonly<Record<string, string>> = Object.freeze({\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n});\n\nconst ATTR_ESCAPE_PATTERN = /[&<>\"']/g;\n\n/** Escape a value for a *quoted* HTML attribute, leaving URL characters intact; it validates no scheme, so run `isSafeUrl()` on `href`/`src` first. @internal */\nexport function escapeHtmlAttribute(value: string): string {\n // The character class and the map are coupled: every match is a key.\n // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style\n return value.replace(ATTR_ESCAPE_PATTERN, (char) => ATTR_ESCAPES[char] as string);\n}\n\n/** `escapeHtml()` then newlines to `<br>`; the order is what makes it safe. */\nexport function escapeAndLinebreak(text: string): string {\n return escapeHtml(text).replace(/\\r\\n|\\r|\\n/g, '<br>');\n}\n","/**\n * One array item out of one template: the interpolation, and the attributes the\n * template cannot know about.\n *\n * A replacement value is data, not template syntax: one `replace()` per key\n * would re-interpret `{{index}}` text that an earlier value introduced, and\n * would apply `String.replace`'s `$` semantics to CMS content.\n */\n\nimport { escapeHtml } from '@security/escape';\nimport { isWritableAttribute } from './attribute-binding';\n\nconst PLACEHOLDER_PATTERN = /\\{\\{([\\s\\S]*?)\\}\\}/g;\n\n/** The runtime's own annotations; a rebuilt item gets its own, never a copy. */\nconst BINDING_ATTRIBUTE_PREFIX = 'data-payload-';\n\n/** An attribute name and its value, as they travel from an old item to a new one. */\nexport type InheritedAttribute = readonly [name: string, value: string];\n\nfunction hasOwn(record: object, key: PropertyKey): boolean {\n return Object.prototype.hasOwnProperty.call(record, key);\n}\n\n/**\n * Every key any item carries. A placeholder naming one of these is a field of\n * this array, so a row that happens to lack it renders as nothing; a\n * placeholder no row can fill is a typo in the template and stays visible.\n */\nexport function collectTemplateKeys(items: readonly unknown[]): ReadonlySet<string> {\n const keys = new Set<string>();\n for (const item of items) {\n if (typeof item !== 'object' || item === null) continue;\n for (const key of Object.keys(item)) keys.add(key);\n }\n return keys;\n}\n\nexport function interpolateArrayTemplate(\n template: string,\n item: unknown,\n index: number,\n stringify: (value: unknown) => string,\n knownKeys?: ReadonlySet<string>,\n): string {\n const record = typeof item === 'object' && item !== null ? item : null;\n\n return template.replace(PLACEHOLDER_PATTERN, (placeholder, key: string) => {\n // Preserve the established object-field precedence when an object itself\n // has an `index` or `value` property. Otherwise these are reserved tokens.\n if (record !== null && hasOwn(record, key)) {\n return escapeHtml(stringify(Reflect.get(record, key)));\n }\n if (record === null && key === 'value') return escapeHtml(stringify(item));\n if (key === 'index') return String(index);\n // A field other rows carry: this one simply has none. Writing the\n // placeholder would print template syntax on the page, which is what an\n // editor sees the moment a row is added and not every field is filled in.\n if (record !== null && knownKeys?.has(key) === true) return '';\n return placeholder;\n });\n}\n\n/**\n * What the items already in `container` all carry, and an item rebuilt from the\n * template therefore has to carry too.\n *\n * A framework's scoped styles hang on a marker its compiler writes into the\n * markup — Astro's `data-astro-cid-…`, Vue's `data-v-…`, Svelte's class — and\n * the author's `data-payload-array-template` has none of it. The rebuilt list\n * then renders unstyled next to the one the server sent, while the write itself\n * succeeds, so nothing in the runtime can notice. Naming no framework is the\n * point: what identifies these attributes is that every item of the list has\n * them with the same value, which per-row state by definition does not.\n */\nexport function sharedItemAttributes(container: Element): readonly InheritedAttribute[] {\n const items = container.children;\n const first = items[0];\n if (first === undefined) return [];\n const shared: InheritedAttribute[] = [];\n for (const { name, value } of Array.from(first.attributes)) {\n if (!isWritableAttribute(name) || name.startsWith(BINDING_ATTRIBUTE_PREFIX)) continue;\n let everyItem = true;\n for (let index = 1; index < items.length && everyItem; index += 1) {\n everyItem = items[index]?.getAttribute(name) === value;\n }\n if (everyItem) shared.push([name, value]);\n }\n return shared;\n}\n\n/** Give a rebuilt item what its predecessors shared; the template's own value wins. */\nexport function inheritItemAttributes(item: Element, shared: readonly InheritedAttribute[]): void {\n for (const [name, value] of shared) {\n if (!item.hasAttribute(name)) item.setAttribute(name, value);\n }\n}\n","/** Value coercion shared by the field renderers. */\n\n/** Display string for any value: primitives as-is, objects as JSON, `null`/`undefined` as `''`. */\nexport function safeStringify(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {\n return String(value);\n }\n try {\n return JSON.stringify(value);\n } catch {\n return '';\n }\n}\n\n/** The three values every renderer treats as \"clear\" (docs/renderers.md, value semantics). */\nexport function isEmptyValue(value: unknown): value is null | undefined | '' {\n return value === null || value === undefined || value === '';\n}\n","/**\n * LRU discipline for a module-scoped lookup `Map` (ADR 0003 §3). Functions\n * over the caller's own `Map` rather than a wrapper class: the inline bundle\n * mangles function names but not property names, so a class would pay for\n * every `this.entries` in full. A `Map` iterates in insertion order, which a\n * touch on every hit turns into recency order. Values are never `undefined`,\n * and a write follows a miss — a key already present keeps its position.\n */\n\n/** Read and touch: a hit becomes the newest entry. */\nexport function lruGet<K, V>(map: Map<K, V>, key: K): V | undefined {\n const value = map.get(key);\n if (value !== undefined) {\n map.delete(key);\n map.set(key, value);\n }\n return value;\n}\n\n/** Write as the newest entry, dropping the oldest ones past `limit`; returns `value`. */\nexport function lruSet<K, V>(map: Map<K, V>, key: K, value: V, limit: number): V {\n map.set(key, value);\n lruTrim(map, limit);\n return value;\n}\n\n/** Drop the oldest entries until `limit` holds. */\nexport function lruTrim<K>(map: Map<K, unknown>, limit: number): void {\n for (const oldest of map.keys()) {\n if (map.size <= limit) break;\n map.delete(oldest);\n }\n}\n","/**\n * Sanitizer options for item templates (`data-payload-array-template`,\n * nested templates). A template is the page author's markup and every\n * interpolated value is escaped to text before the sanitizer runs, so it may\n * carry form controls and custom elements the rich-text policy refuses.\n * Event handlers, `style` and unsafe URLs are still stripped.\n *\n * Some entries below are already admitted by the sanitizer through another\n * route — `video` and `audio` by the tag allow-list, `select` by\n * `allowFormControls`, `name` by `templateMode`, and `controls`, `muted`,\n * `loop`, `poster` and `src` by the per-tag attribute map. They are kept\n * because this list states what a template may contain, and an allow-list\n * that depends on a second list staying unchanged is the more fragile of the\n * two arrangements. Mutating those entries changes nothing observable, so\n * they survive mutation testing by construction; the behaviour they describe\n * is pinned in `tests/unit/core/template-sanitize.test.ts` instead.\n */\n\nimport type { SanitizeOptions } from '@security/sanitizer';\nimport { lruGet, lruSet } from './lru';\n\nconst TEMPLATE_EXTRA_TAGS: readonly string[] = [\n 'input',\n 'textarea',\n 'select',\n 'option',\n 'button',\n 'label',\n 'details',\n 'summary',\n 'dialog',\n 'video',\n 'audio',\n 'progress',\n 'meter',\n];\n\nconst TEMPLATE_EXTRA_ATTRIBUTES: readonly string[] = [\n 'type',\n 'name',\n 'placeholder',\n 'open',\n 'disabled',\n 'readonly',\n 'required',\n 'checked',\n 'selected',\n 'value',\n 'min',\n 'max',\n 'step',\n 'rows',\n 'cols',\n 'for',\n 'controls',\n 'muted',\n 'loop',\n 'poster',\n 'src',\n];\n\nconst CUSTOM_TAG_PATTERN = /<([a-z][a-z0-9]*(?:-[a-z0-9]+)+)\\b/gi;\n\n// 64 like the intl cache: more than a page declares, and a nested template is\n// interpolated with its parent's, so an outer value or `{{index}}` that lands\n// in it mints a key per item and per keystroke (ADR 0003 §3).\nexport const TEMPLATE_CACHE_LIMIT = 64;\nconst optionsByTemplate = new Map<string, SanitizeOptions>();\n\n/** Options for one template; memoised per template string. */\nexport function templateSanitizeOptions(template: string): SanitizeOptions {\n const cached = lruGet(optionsByTemplate, template);\n if (cached !== undefined) return cached;\n const tags = new Set(TEMPLATE_EXTRA_TAGS);\n for (const match of template.matchAll(CUSTOM_TAG_PATTERN)) {\n const tag = match[1]?.toLowerCase();\n if (tag !== undefined) tags.add(tag);\n }\n const attributes: Record<string, readonly string[]> = {};\n for (const tag of tags) attributes[tag] = TEMPLATE_EXTRA_ATTRIBUTES;\n const options: SanitizeOptions = {\n additionalAllowedTags: [...tags],\n additionalAllowedAttributes: attributes,\n allowFormControls: true,\n templateMode: true,\n };\n return lruSet(optionsByTemplate, template, options, TEMPLATE_CACHE_LIMIT);\n}\n","/**\n * Applies an `ArrayPatch[]` diff to a container as keyed DOM operations\n * instead of rebuilding the list, so consumer state on surviving children is\n * kept. Items are paired by `data-payload-key` (the item `id`); items without\n * one pair by position. Nested arrays reconcile recursively through\n * `data-payload-nested-key` slots. See ADR 0008.\n */\n\nimport { sanitizeHtmlWithPolicy, type SanitizerPolicyMode } from '@security/sanitizer';\nimport { trustedHtml } from '@security/trusted-types';\nimport {\n collectTemplateKeys,\n inheritItemAttributes,\n interpolateArrayTemplate,\n sharedItemAttributes,\n type InheritedAttribute,\n} from './array-template';\nimport { safeStringify } from '@field-types/utils';\nimport { diffArray, type ArrayPatch } from '@schema/diff';\nimport { isMorphBoundary, retainIslandBoundary } from './islands';\nimport { captureFocus, restoreFocus, morphElement } from './morph';\nimport { templateSanitizeOptions } from './template-sanitize';\n\n/** @internal */\nexport const KEY_ATTRIBUTE = 'data-payload-key';\nconst NESTED_KEY_ATTRIBUTE = 'data-payload-nested-key';\nconst NESTED_TEMPLATE_ATTRIBUTE = 'data-payload-nested-template';\n\n/** Last value seen per item key, per container; owned by the caller so instances never share it. @internal */\nexport type StructuralStore = WeakMap<Element, Map<string, unknown>>;\n\n/** @internal */\nexport function createStructuralStore(): StructuralStore {\n return new WeakMap<Element, Map<string, unknown>>();\n}\n\n/** @internal */\nexport interface StructuralApplyOptions {\n readonly template: string;\n readonly container: Element;\n readonly patches: readonly ArrayPatch[];\n /** The full new array; inserts and replaces render by index from it. */\n readonly nextItems: readonly unknown[];\n /** Pass the same store across renders so nested arrays diff incrementally. */\n readonly store: StructuralStore;\n /** Re-render existing items even when unchanged. */\n readonly forceRender?: boolean;\n /** The instance's policy for item markup; absent, the process default applies. */\n readonly sanitizerPolicy?: SanitizerPolicyMode | undefined;\n /** Edit a changed item in place instead of replacing it. Default `true`. */\n readonly morph?: boolean;\n /** Reported once per container when two items share a key (`LP0405`). */\n readonly onDuplicateKey?: (container: Element, key: string) => void;\n}\n\n/**\n * Returns `true` for a DOM mutation, `false` for an already-current tree, and\n * `null` when an item's markup has no sanitized element root — preflighted\n * before any mutation, so the previous DOM and memory stay intact.\n * @internal\n */\nexport function applyStructuralPatches(options: StructuralApplyOptions): boolean | null {\n const plan = prepareStructuralPlan(options.container, options.patches, options);\n if (plan === null) return null;\n return commitStructuralPlan(plan, options.store, {\n morph: options.morph ?? true,\n onDuplicateKey: options.onDuplicateKey,\n });\n}\n\n// Plan records are tuples: many are created per recursive render, and named\n// keys would repeat in the inline bundle.\ntype StructuralPlan = readonly [\n container: Element,\n entries: readonly ReconciliationEntry[],\n nextItems: readonly unknown[],\n];\ntype ReconciliationEntry = readonly [\n index: number,\n live: Element | null,\n rendered: Element | undefined,\n nestedSlots: readonly NestedSlotPlan[],\n /** A `replace` patch: a different item, never morphed toward. */\n replace: boolean,\n];\ntype NestedSlotPlan = readonly [\n live: Element | null,\n rendered: Element,\n children: StructuralPlan | undefined,\n];\n\n// One per container, not per item, so — unlike the tuples above — named keys\n// cost the inline bundle nothing per render.\ntype RenderEnv = Pick<\n StructuralApplyOptions,\n 'template' | 'nextItems' | 'forceRender' | 'store' | 'sanitizerPolicy'\n>;\n\ninterface CommitOptions {\n readonly morph: boolean;\n readonly onDuplicateKey: ((container: Element, key: string) => void) | undefined;\n}\n\n/** A rendered slot that still carries a nested template keeps its children for its own plan. */\nfunction isManagedNestedSlot(_live: Element, rendered: Element): boolean {\n return (\n rendered.hasAttribute(NESTED_KEY_ATTRIBUTE) && rendered.hasAttribute(NESTED_TEMPLATE_ATTRIBUTE)\n );\n}\n\n/** Materialise the whole recursive replacement tree before touching live DOM. */\nfunction prepareStructuralPlan(\n container: Element,\n patches: readonly ArrayPatch[],\n env: RenderEnv,\n): StructuralPlan | null {\n const entries = prepareReconciliation(container, createPatchPlan(patches), env);\n return entries === null ? null : [container, entries, env.nextItems];\n}\n\nfunction commitStructuralPlan(\n plan: StructuralPlan,\n store: StructuralStore,\n options: CommitOptions,\n): boolean {\n const [container, entries, nextItems] = plan;\n const claimed = new Set<Element>();\n let mutated = false;\n // Placing a retained item is a remove-and-insert, which blurs whatever the\n // visitor had focused inside it; the morph does the same for a move it\n // makes and restores afterwards, so the commit does too.\n const focus = captureFocus(container);\n for (const [index, live, rendered, nestedSlots, replace] of entries) {\n let node = live;\n if (rendered !== undefined) {\n // Morph a compatible live item in place; otherwise transplant its live\n // nested slots into the rendered item and swap.\n const retained =\n options.morph && !replace && live !== null\n ? morphElement(live, rendered, {\n keyAttributes: [KEY_ATTRIBUTE, NESTED_KEY_ATTRIBUTE],\n boundary: isMorphBoundary,\n retainBoundary: retainIslandBoundary,\n retainChildrenOf: isManagedNestedSlot,\n ...(options.onDuplicateKey !== undefined\n ? { onDuplicateKey: options.onDuplicateKey }\n : {}),\n }) === live\n : false;\n if (!retained) {\n for (const [liveSlot, renderedSlot] of nestedSlots) {\n if (liveSlot === null) continue;\n synchronizeAttributes(liveSlot, renderedSlot);\n renderedSlot.replaceWith(liveSlot);\n }\n }\n for (const [, , children] of nestedSlots) {\n if (children !== undefined) commitStructuralPlan(children, store, options);\n }\n if (retained) {\n mutated = true;\n } else {\n if (live !== null) {\n live.replaceWith(rendered);\n mutated = true;\n }\n node = rendered;\n }\n }\n if (node === null) continue;\n const before = container.children[index] ?? null;\n if (node !== before) {\n container.insertBefore(node, before);\n mutated = true;\n }\n claimed.add(node);\n }\n // `nextItems` is the source of truth; this also drops SSR children the first value did not carry.\n for (const child of Array.from(container.children)) {\n if (claimed.has(child)) continue;\n child.remove();\n mutated = true;\n }\n restoreFocus(focus);\n const memory = getMemory(container, store);\n memory.clear();\n for (const value of nextItems) rememberItem(memory, value);\n return mutated;\n}\n\n/**\n * Pair every final item with a live child (by key, else by position) and\n * render what needs rendering. Patch indices describe `next`, live indices\n * move during reconciliation, so keyed nodes are resolved from the DOM first.\n */\nfunction prepareReconciliation(\n container: Element,\n plan: PatchPlan,\n env: RenderEnv,\n): readonly ReconciliationEntry[] | null {\n const { template, nextItems, forceRender = false, store, sanitizerPolicy } = env;\n const memory = store.get(container);\n // Read before anything is rendered: what the current items share is what the\n // template cannot say, and an inserted item has no predecessor of its own.\n const shared = sharedItemAttributes(container);\n const templateKeys = collectTemplateKeys(nextItems);\n const initialChildren = Array.from(container.children);\n const keyedChildren = indexByAttribute(initialChildren, KEY_ATTRIBUTE);\n const reserved = new Set<Element>();\n const entries: ReconciliationEntry[] = [];\n for (let index = 0; index < nextItems.length; index += 1) {\n const value = nextItems[index];\n const key = readKey(value);\n let live =\n key === undefined\n ? (initialChildren[index] ?? null)\n : (takeIndexedElement(keyedChildren, key) ?? null);\n if (live !== null && reserved.has(live)) live = null;\n if (live !== null) reserved.add(live);\n const replace = plan.replaces.has(index);\n const needsRender = forceRender || plan.renders.has(index) || live === null;\n const rendered = needsRender\n ? renderItem(\n container.ownerDocument,\n template,\n value,\n index,\n sanitizerPolicy,\n shared,\n templateKeys,\n )\n : undefined;\n if (rendered === null) return null;\n const nestedSlots =\n rendered === undefined\n ? []\n : prepareNestedSlots(\n replace ? null : live,\n rendered,\n value,\n key === undefined ? undefined : memory?.get(key),\n env,\n );\n if (nestedSlots === null) return null;\n entries.push([index, live, rendered, nestedSlots, replace]);\n }\n return entries;\n}\n\ninterface PatchPlan {\n readonly renders: ReadonlySet<number>;\n readonly replaces: ReadonlySet<number>;\n}\n\nfunction createPatchPlan(patches: readonly ArrayPatch[]): PatchPlan {\n const renders = new Set<number>();\n const replaces = new Set<number>();\n for (const patch of patches) {\n if (patch.kind === 'insert' || patch.kind === 'update') renders.add(patch.index);\n else if (patch.kind === 'replace') {\n renders.add(patch.index);\n replaces.add(patch.index);\n }\n }\n return { renders, replaces };\n}\n\n/** Plan each direct nested slot; a failure at any depth aborts before commit. */\nfunction prepareNestedSlots(\n oldItem: Element | null,\n newItem: Element,\n nextValue: unknown,\n prevValue: unknown,\n env: RenderEnv,\n): readonly NestedSlotPlan[] | null {\n const oldSlots = oldItem === null ? [] : findDirectNestedSlots(oldItem);\n const oldSlotsByKey = indexByAttribute(oldSlots, NESTED_KEY_ATTRIBUTE);\n const plans: NestedSlotPlan[] = [];\n for (const newSlot of findDirectNestedSlots(newItem)) {\n const key = newSlot.getAttribute(NESTED_KEY_ATTRIBUTE);\n if (key === null) continue;\n const oldSlot = takeIndexedElement(oldSlotsByKey, key) ?? null;\n const nextTemplate = newSlot.getAttribute(NESTED_TEMPLATE_ATTRIBUTE);\n // Without a nested template the slot's rendered static content is authoritative.\n const liveSlot = nextTemplate ? oldSlot : null;\n const previousTemplate = liveSlot?.getAttribute(NESTED_TEMPLATE_ATTRIBUTE) ?? null;\n let children: StructuralPlan | undefined;\n if (nextTemplate) {\n const nextNested = readNestedArray(nextValue, key);\n if (nextNested !== undefined || liveSlot !== null) {\n const resolvedNext = nextNested ?? [];\n const prevNested = liveSlot === null ? [] : (readNestedArray(prevValue, key) ?? []);\n const patches = diffArray(prevNested, resolvedNext);\n const templateChanged = liveSlot !== null && previousTemplate !== nextTemplate;\n if (patches.length > 0 || templateChanged) {\n children =\n prepareStructuralPlan(liveSlot ?? newSlot, patches, {\n template: nextTemplate,\n nextItems: resolvedNext,\n forceRender: templateChanged,\n store: env.store,\n sanitizerPolicy: env.sanitizerPolicy,\n }) ?? undefined;\n if (children === undefined) return null;\n }\n }\n }\n plans.push([liveSlot, newSlot, children]);\n }\n return plans;\n}\n\n/** Only the outermost nested slots: a transplanted slot owns the recursion below it. */\nfunction findDirectNestedSlots(item: Element): readonly Element[] {\n return Array.from(item.querySelectorAll(`[${NESTED_KEY_ATTRIBUTE}]`)).filter((slot) => {\n let ancestor = slot.parentElement;\n while (ancestor !== null && ancestor !== item) {\n if (ancestor.hasAttribute(NESTED_KEY_ATTRIBUTE)) return false;\n ancestor = ancestor.parentElement;\n }\n return ancestor === item;\n });\n}\n\nfunction synchronizeAttributes(target: Element, source: Element): void {\n for (const attribute of Array.from(target.attributes)) {\n if (!source.hasAttribute(attribute.name)) target.removeAttribute(attribute.name);\n }\n for (const attribute of Array.from(source.attributes)) {\n if (target.getAttribute(attribute.name) !== attribute.value) {\n target.setAttribute(attribute.name, attribute.value);\n }\n }\n}\n\nfunction readNestedArray(value: unknown, key: string): readonly unknown[] | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const nested = (value as Record<string, unknown>)[key];\n return Array.isArray(nested) ? (nested as readonly unknown[]) : undefined;\n}\n\nfunction getMemory(container: Element, store: StructuralStore): Map<string, unknown> {\n let map = store.get(container);\n if (!map) {\n map = new Map();\n store.set(container, map);\n }\n return map;\n}\n\nfunction rememberItem(memory: Map<string, unknown>, value: unknown): void {\n const key = readKey(value);\n if (key !== undefined) memory.set(key, value);\n}\n\nfunction readKey(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const id = (value as Record<string, unknown>)['id'];\n return typeof id === 'string' || typeof id === 'number' ? String(id) : undefined;\n}\n\nfunction indexByAttribute(elements: readonly Element[], attribute: string): Map<string, Element[]> {\n const indexed = new Map<string, Element[]>();\n // Reverse order so pop() yields duplicates in DOM order.\n for (let index = elements.length - 1; index >= 0; index -= 1) {\n const element = elements[index];\n if (element === undefined) continue;\n const key = element.getAttribute(attribute);\n if (key === null) continue;\n const bucket = indexed.get(key);\n if (bucket === undefined) indexed.set(key, [element]);\n else bucket.push(element);\n }\n return indexed;\n}\n\nfunction takeIndexedElement(indexed: Map<string, Element[]>, key: string): Element | undefined {\n return indexed.get(key)?.pop();\n}\n\n/** Render one item; its `id` is stamped as `data-payload-key` so later diffs find it. */\nfunction renderItem(\n ownerDocument: Document,\n template: string,\n value: unknown,\n index: number,\n policy: SanitizerPolicyMode | undefined,\n shared: readonly InheritedAttribute[],\n knownKeys: ReadonlySet<string>,\n): Element | null {\n const filled = interpolateArrayTemplate(template, value, index, safeStringify, knownKeys);\n const safe = sanitizeHtmlWithPolicy(filled, policy, templateSanitizeOptions(template));\n const host = ownerDocument.createElement('template');\n host.innerHTML = trustedHtml(safe);\n const first = host.content.firstElementChild;\n if (!first) return null;\n // Before the morph, which strips from the live item every attribute the\n // rendered one lacks: the marker has to be on this side to survive.\n inheritItemAttributes(first, shared);\n const key = readKey(value);\n if (key !== undefined) first.setAttribute(KEY_ATTRIBUTE, key);\n return first;\n}\n","/**\n * The warnings about a page's strategies, kept apart from the runner that\n * usually issues them: the lean profile has no runner (see ./profile) and still\n * owes a page the first two, because they describe the markup, not the strategy\n * machinery. LP0808 says the configuration names no strategy at all, and LP0809\n * that a fragment's Astro island cannot start on this page.\n */\n\nimport type { RuntimeDeps, RuntimeState } from './runtime-state';\nimport type { CachedElement } from './types';\n\n/** LP0806, once: a fragment boundary with no handler is patched instead. */\nexport function warnFragmentFallback(\n deps: RuntimeDeps,\n state: RuntimeState,\n target: CachedElement,\n): void {\n if (state.warnedFragmentFallback) return;\n state.warnedFragmentFallback = true;\n deps.warn(\n `[live-preview] LP0806: \"${target.fieldName}\" asks for the fragment strategy but no handler is configured; patching instead`,\n );\n}\n\n/** LP0407, once per element: an unknown strategy is left alone, not guessed at. */\nexport function warnUnsupportedStrategy(\n deps: RuntimeDeps,\n state: RuntimeState,\n target: CachedElement,\n): void {\n if (state.warnedStrategy.has(target.element)) return;\n state.warnedStrategy.add(target.element);\n deps.warn(\n `[live-preview] LP0407: \"${target.fieldName}\" asks for strategy \"${String(target.strategy)}\"; only patch, fragment and route exist`,\n );\n}\n\n/**\n * LP0808, once: the default asks for a server render and this page has nothing\n * to ask. Said with the count that brought it up: a page that keeps producing\n * findings is the page that needs the line, not one line per finding. A page\n * with a fragment strategy and no route reaches here too, when a boundary of\n * this document does not cover every one of them (strategy-runner.ts hands a\n * boundary all of them or none), and is told that rather than that nothing is\n * configured.\n */\nexport function warnEscalationUnavailable(\n deps: RuntimeDeps,\n state: RuntimeState,\n count: number,\n): void {\n if (state.warnedEscalationUnavailable) return;\n state.warnedEscalationUnavailable = true;\n const shortfall = `[live-preview] LP0808: onUnfaithfulPatch: 'escalate' has nowhere to go: ${String(count)} field(s) fell short`;\n const warnInstead = \"or onUnfaithfulPatch: 'warn' to keep the patch and say so.\";\n deps.warn(\n deps.strategies.fragment === undefined\n ? `${shortfall} and no route or fragment strategy is configured. Set routeStrategy: true or fragments: { endpoint }, ${warnInstead}`\n : `${shortfall}, not all of them inside a data-payload-fragment boundary of this document, ` +\n 'and no route strategy is configured. ' +\n `Cover them with a boundary or add the route strategy, ${warnInstead}`,\n );\n}\n\n/** LP0809, once: fragment scripts never run, so the page must already start Astro islands. */\nexport function warnIslandStart(\n deps: RuntimeDeps,\n state: RuntimeState,\n island: Element,\n blocker: 'element' | 'directive',\n): void {\n if (state.warnedIslandStart) return;\n state.warnedIslandStart = true;\n const missing =\n blocker === 'element' ? '<astro-island>' : `client:${island.getAttribute('client') ?? ''}`;\n deps.warn(\n `[live-preview] LP0809: a fragment island cannot start: this page never loaded ${missing}; render one on the page`,\n );\n}\n","/**\n * Runs the fragment and route strategies for a revision. A strategy that\n * throws or rejects is treated as failed, never left to reject the runtime.\n */\n\nimport type { PayloadLivePreviewData } from '@/types/payload-protocol';\nimport { trustedHtml } from '@security/trusted-types';\nimport { isBindingInScope } from './binding-owner';\nimport { resolveBindingOwner } from './cache';\nimport { reportUnboundChange } from './fidelity';\nimport { bindingValue } from './field-value';\nimport {\n astroIslandsIn,\n isMorphBoundary,\n islandStartBlocker,\n releaseDisconnectedIslands,\n retainIslandBoundary,\n} from './islands';\nimport { morphElement } from './morph';\nimport type { RuntimeDeps, RuntimeState, UpdateTransaction } from './runtime-state';\nimport { thrownFragment } from './revision-display';\nimport {\n liveBoundary,\n planBoundaries,\n type FragmentContext,\n type FragmentPlan,\n type RouteOutcome,\n type RouteStrategy,\n} from './strategies';\nimport { KEY_ATTRIBUTE } from './structural-applier';\nimport {\n warnEscalationUnavailable,\n warnFragmentFallback,\n warnIslandStart,\n warnUnsupportedStrategy,\n} from './strategy-warnings';\nimport {\n declaredSubfields,\n routeTouched,\n unboundChangedFields,\n type OwnerScope,\n type SubfieldValues,\n} from './unbound-fields';\nimport type { CachedElement } from './types';\n\n/** What the pipeline lends the runner. */\nexport interface StrategyHost {\n readonly reapply: (transaction: UpdateTransaction, data: PayloadLivePreviewData) => void;\n readonly transform: (\n target: CachedElement,\n value: unknown,\n allFields: Record<string, unknown>,\n isCurrent: () => boolean,\n ) => unknown;\n readonly rebuildCache: () => void;\n /** A server render — the route, or a fragment boundary — dropped the stamps a guess lives by; look for the baseline's guesses again (ADR 0014). */\n readonly restoreGuesses: (transaction: UpdateTransaction, data: PayloadLivePreviewData) => void;\n /** Scroll to the binding this revision marked, if it has not been revealed yet. */\n readonly revealPending: (transaction: UpdateTransaction) => void;\n}\n\nexport class StrategyRunner {\n constructor(\n private readonly deps: RuntimeDeps,\n private readonly state: RuntimeState,\n private readonly host: StrategyHost,\n ) {}\n\n /**\n * The boundaries this revision renders: those its diff touches, and those a\n * newer revision cut short before they settled that are still on the page.\n * A debt is settled when a render of its boundary starts, so a late-binding\n * pass, which renders only what streamed in, leaves the rest owed.\n */\n planFragments(touched: ReadonlySet<string>, ownerKeys: OwnerScope): FragmentPlan | null {\n const { deps, state } = this;\n const strategy = deps.strategies.fragment;\n if (strategy === undefined) return null;\n const planned = new Set(strategy.plan(deps.root, touched));\n for (const boundary of state.fragmentsOwed) {\n if (deps.root.contains(boundary)) planned.add(boundary);\n else state.fragmentsOwed.delete(boundary);\n }\n const boundaries = [...planned].filter((boundary) => inOwnerScope(boundary, ownerKeys));\n return planBoundaries(strategy, boundaries, ownerKeys);\n }\n\n /**\n * Hand the bindings this revision could not patch faithfully to a server:\n * the fragment strategy when a boundary covers every one of them, the route\n * otherwise. All of them or none — a boundary renders its own region, so a\n * finding outside every boundary is only answered by the whole route.\n *\n * A revision that already refreshed the route is left alone: the second\n * request would fetch the bytes the first one just brought.\n */\n escalateUnfaithful(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n targets: readonly CachedElement[],\n ownerKeys: OwnerScope,\n ): void {\n if (transaction.routeRefreshed) {\n this.kept(transaction, targets);\n return;\n }\n const { fragment, route } = this.deps.strategies;\n const covered = fragment === undefined ? undefined : coveringBoundaries(targets);\n const boundaries =\n covered === undefined || covered.every((boundary) => inOwnerScope(boundary, ownerKeys))\n ? covered\n : undefined;\n if (fragment !== undefined && boundaries !== undefined) {\n this.state.escalatedCount += targets.length;\n transaction.pendingFragments += boundaries.length;\n void this.runFragments(transaction, data, planBoundaries(fragment, boundaries, ownerKeys));\n return;\n }\n if (route === undefined) {\n // Only 'escalate' queues a patch for this method (fidelity.ts), so the\n // page that reaches here with no strategy is the one the line is for.\n warnEscalationUnavailable(this.deps, this.state, targets.length);\n this.kept(transaction, targets);\n return;\n }\n this.state.escalatedCount += targets.length;\n void this.refreshRoute(transaction, data, route);\n }\n\n /** Patches that fell short and stay as they are: the revision does not show those fields. */\n private kept(transaction: UpdateTransaction, targets: readonly CachedElement[]): void {\n for (const target of targets) {\n this.state.display.shortfall(transaction, { kind: 'unfaithful', field: target.fieldName });\n }\n }\n\n /**\n * Whether this revision changed a field the page cannot patch — one with no\n * anchor anywhere, which is also how a section the template renders only\n * under a condition looks from here. The whole route is then the only honest\n * answer.\n *\n * Asked of every revision rather than only where a refresh could follow it,\n * because the finding is the same one under every mode and on a page with no\n * strategy — and that page is what `inspect().fidelity` is read on. What the\n * mode still decides is what is *done*: `'warn'` adds no line of its own\n * (LP0203, or LP0201 for an empty value, already names the field) and `'ignore'` keeps the stale value,\n * exactly as before; only the ledger sees them now.\n *\n * The baseline message is skipped, because there every field counts as\n * changed and the page has just been rendered from them anyway — and so is\n * the re-apply after a refresh, which would otherwise report it all twice.\n * A navigation's replay lands on the server's render of the saved document\n * too: a refresh would fetch those bytes again, so it is answered as a\n * partial render is, by the next save.\n */\n hasUnboundChange(transaction: UpdateTransaction, ownerKeys: OwnerScope): boolean {\n const { deps, state } = this;\n if (transaction.baseline || transaction.routeRefreshed) return false;\n const unbound = unboundChangedFields(\n deps.cache,\n transaction.touched,\n transaction.locale,\n ownerKeys,\n this.subfields(transaction),\n deps.strategies,\n );\n let answered = 0;\n for (const fieldName of unbound) if (reportUnboundChange(state, fieldName)) answered += 1;\n const [first] = unbound;\n if (first === undefined) return false;\n if (deps.onUnfaithfulPatch !== 'escalate' || deps.strategies.route === undefined) {\n if (deps.onUnfaithfulPatch === 'escalate') {\n warnEscalationUnavailable(deps, state, unbound.length);\n }\n for (const field of unbound) state.display.shortfall(transaction, { kind: 'unbound', field });\n return false;\n }\n if (transaction.navigated) {\n state.routeAwaitsSave = true;\n state.display.shortfall(transaction, { kind: 'route-saved' });\n return false;\n }\n deps.log('route', 'LP0807', `field \"${first}\" has no binding; refreshing the route`);\n state.escalatedCount += answered;\n return true;\n }\n\n /** What the declared mode compares below the top level for this revision. */\n private subfields(transaction: UpdateTransaction): SubfieldValues | undefined {\n const { previousFields } = this.state.changes;\n return declaredSubfields(\n this.deps.subfieldCoverage,\n previousFields,\n transaction.renderData?.fields,\n );\n }\n\n /**\n * Whether the route is asked for, by the strategy's planner or by a route\n * binding of a touched field, each only inside the update's owner scope: a\n * marker another document owns is that document's business (PHD-02). Both\n * see the paths inside the touched fields that route-bound elements name.\n */\n plansRoute(route: RouteStrategy, transaction: UpdateTransaction, ownerKeys: OwnerScope): boolean {\n const owned = (owner: string | undefined): boolean =>\n ownerKeys === false || isBindingInScope(owner, ownerKeys);\n const inScope = (element: Element): boolean => owned(resolveBindingOwner(element));\n const touched = routeTouched(this.deps.cache, transaction.touched, this.subfields(transaction));\n if (route.plan(this.deps.root, touched, { inScope })) return true;\n for (const [fieldName, bindings] of this.deps.cache.entries()) {\n if (!touched.has(fieldName)) continue;\n if (bindings.some((target) => target.strategyKind === 'route' && owned(target.owner))) {\n return true;\n }\n }\n return false;\n }\n\n async runFragments(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n plan: FragmentPlan,\n ): Promise<void> {\n const { deps, state } = this;\n const controller = new AbortController();\n const unsettled = new Set(plan.boundaries);\n for (const boundary of unsettled) state.fragmentsOwed.delete(boundary);\n state.fragmentControllers.set(controller, unsettled);\n const settle = (boundary: Element): void => {\n if (unsettled.delete(boundary)) transaction.pendingFragments -= 1;\n };\n const isCurrent = (): boolean => state.isCurrent(transaction) && !controller.signal.aborted;\n const live = (boundary: Element): Element | undefined =>\n liveBoundary(deps.root, boundary, (candidate) => inOwnerScope(candidate, plan.ownerKeys));\n const { emitter } = deps;\n const { message } = transaction;\n const revision = transaction.revision.revision;\n const receivedAt = transaction.receivedAt;\n const context: FragmentContext = {\n root: deps.root,\n revision,\n receivedAt,\n fields: data.fields,\n locale: transaction.locale,\n collectionSlug:\n typeof message.collectionSlug === 'string' ? message.collectionSlug : undefined,\n globalSlug: typeof message.globalSlug === 'string' ? message.globalSlug : undefined,\n signal: controller.signal,\n isCurrent,\n log: (code, detail) => {\n deps.log('fragment', code, detail);\n },\n morph: (boundary, html) => {\n const target = isCurrent() ? live(boundary) : undefined;\n if (target === undefined) return;\n morphFragment(target, html, (island, blocker) => {\n warnIslandStart(this.deps, this.state, island, blocker);\n });\n },\n patch: (boundary) => {\n const target = live(boundary);\n if (target === undefined) return;\n // A copy's bindings reach the cache only after the structural debounce.\n if (target !== boundary) this.host.rebuildCache();\n this.patchFallback(transaction, data, target, plan.ownerKeys, isCurrent);\n },\n rendered: (planned, id, key) => {\n settle(planned);\n const element = live(planned) ?? planned;\n void emitter.emitWhile(\n 'fragmentRender',\n { element, id, key, status: 'rendered', revision, receivedAt },\n isCurrent,\n );\n },\n failed: (planned, id, key, code, reason) => {\n settle(planned);\n const element = live(planned) ?? planned;\n state.display.shortfall(transaction, { kind: 'fragment', id, key, code });\n const detail = `fragment \"${id}\" fell back to patch: ${reason}`;\n // Logged where the failure is, not where an exception would have been:\n // the supplied strategy answers a timeout or a refusal with an outcome\n // and never throws, so the `catch` around `render()` below is not on\n // this path and its LP0801 reached no log sink at all.\n deps.log('fragment', code, detail);\n void emitter.emitWhile(\n 'error',\n { error: new Error(detail), context: 'fragment', code },\n isCurrent,\n );\n void emitter.emitWhile(\n 'fragmentRender',\n { element, id, key, status: 'failed', code, revision, receivedAt },\n isCurrent,\n );\n },\n };\n let report = { rendered: 0, failed: 0, superseded: 0 };\n try {\n report = await plan.strategy.render(context, plan.boundaries);\n } catch (error) {\n deps.log('fragment', 'LP0801', error);\n if (isCurrent()) {\n for (const boundary of plan.boundaries) {\n context.patch(boundary);\n state.display.shortfall(transaction, thrownFragment(boundary));\n }\n report = { rendered: 0, failed: plan.boundaries.length, superseded: 0 };\n }\n }\n state.fragmentStats.rendered += report.rendered;\n state.fragmentStats.failed += report.failed;\n state.fragmentStats.superseded += report.superseded;\n state.fragmentControllers.delete(controller);\n for (const boundary of unsettled) settle(boundary);\n if (!isCurrent()) return;\n // A rendered boundary holds the server's markup, which carries no stamp: the\n // guesses in it go back on, as after a refresh, before the revision counts\n // as complete. Without this a guess in a boundary did not outlive the first\n // message, which renders the boundary as well.\n if (report.rendered > 0) this.host.restoreGuesses(transaction, data);\n if (transaction.pendingFragments === 0 && deps.scheduler.pendingCount === 0) {\n state.complete(transaction);\n }\n // The edited field may be one the server just rendered: its element is only\n // in place now, so this is the earliest point it can be scrolled to.\n this.host.revealPending(transaction);\n if (!isCurrent()) return;\n if (report.rendered === 0 || emitter.listenerCount('afterUpdate') === 0) return;\n void emitter.emitWhile(\n 'afterUpdate',\n {\n data,\n updatedCount: report.rendered,\n durationMs: Date.now() - receivedAt,\n revision,\n receivedAt,\n source: 'fragment',\n },\n isCurrent,\n );\n }\n\n /** Refresh the route once per revision, then re-apply the revision onto the fresh markup. */\n async refreshRoute(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n strategy: RouteStrategy,\n ): Promise<void> {\n const { deps, state } = this;\n if (transaction.routeRefreshed) {\n state.routeStats.loopStopped += 1;\n deps.log(\n 'route',\n 'LP0805',\n `revision ${String(transaction.revision.revision)} asked for a second refresh`,\n );\n return;\n }\n // A refusal counts as asked as well: the trailing run below is this\n // revision's one refresh, and nothing else may start a second.\n transaction.routeRefreshed = true;\n await this.runRoute(transaction, data, strategy, false).catch((error: unknown) => {\n this.routeFailed(error);\n });\n }\n\n /**\n * Payload saved the document, and the route was last rendered from the older\n * save (`routeAwaitsSave`): render it again, now that the server has the edits.\n * Payload posts the event once the save landed, so no delay is guessed at.\n */\n refreshAfterSave(): void {\n const { deps, state } = this;\n const { route } = deps.strategies;\n const current = state.activeUpdate;\n // A stopped runtime has no active update, so this also refuses after stop().\n if (!state.routeAwaitsSave || route === undefined || current?.renderData === undefined) return;\n deps.log('route', 'document saved; refreshing the route');\n this.runRoute(current, current.renderData, route, true).catch((error: unknown) => {\n this.routeFailed(error);\n });\n }\n\n /**\n * Nothing awaits a refresh, so an unexpected throw after it returned, while\n * the page is re-applied onto the fresh markup, would otherwise escape as an\n * unhandled rejection. The strategy's own throw is an outcome (LP0801).\n */\n private routeFailed(error: unknown): void {\n this.deps.log('route refresh failed:', error);\n }\n\n /**\n * The trailing run of a refused refresh: the strategy's window closes and the\n * request it held back runs, once. It cannot loop — a refresh re-renders the\n * page from the server and produces no message, so nothing asks again.\n */\n private armRouteRetry(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n strategy: RouteStrategy,\n delayMs: number,\n forSave: boolean,\n ): void {\n const { state } = this;\n if (state.routeRetry !== null) clearTimeout(state.routeRetry);\n state.routeRetry = setTimeout(() => {\n state.routeRetry = null;\n if (!state.isCurrent(transaction)) return;\n this.runRoute(transaction, data, strategy, forSave).catch((error: unknown) => {\n this.routeFailed(error);\n });\n }, delayMs);\n }\n\n /**\n * One trip through the strategy, whether the revision asked for it or the\n * window did. It replaces a refresh still in flight, and it lands for the\n * revision that is current when it returns, which need not be the one that\n * asked (ADR 0004 §4d).\n */\n private async runRoute(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n strategy: RouteStrategy,\n forSave: boolean,\n ): Promise<void> {\n const { deps, state } = this;\n if (deps.routeAfterSave && !forSave) {\n state.routeAwaitsSave = true;\n state.display.shortfall(transaction, { kind: 'route-saved' });\n return;\n }\n const stats = state.routeStats;\n const controller = new AbortController();\n state.routeController?.abort();\n state.routeController = controller;\n // A stop aborts it too, so the signal alone says whether it may still land.\n const lands = (): boolean => !controller.signal.aborted;\n let outcome: RouteOutcome;\n try {\n outcome = await strategy.refresh({\n revision: transaction.revision.revision,\n receivedAt: transaction.receivedAt,\n signal: controller.signal,\n isCurrent: lands,\n log: (code, detail) => {\n deps.log('route', code, detail);\n },\n retryAfter: (delayMs) => {\n this.armRouteRetry(transaction, data, strategy, delayMs, forSave);\n },\n });\n } catch (error) {\n deps.log('route', 'LP0801', error);\n outcome = 'failed';\n }\n if (!lands()) return;\n // Whatever replaces this refresh, ends the route or stops the session\n // aborts it first, so it is still the one in flight and a revision is\n // current; the null check only narrows the type.\n state.routeController = null;\n const current = state.activeUpdate;\n if (current === null) return;\n // The current revision's latest data, which a merge may have refined since\n // the refresh started. One still resolving its fields has none yet: it\n // applies itself onto whatever the route shows when it gets there.\n const currentData = current.renderData;\n const isCurrent = (): boolean => state.isCurrent(current);\n if (outcome === 'partial') state.display.shortfall(current, { kind: 'route-saved' });\n // A refusal with its trailing run armed is not an outcome yet: that run is.\n else if (\n outcome === 'failed' ||\n outcome === 'superseded' ||\n (outcome === 'refused' && state.routeRetry === null)\n ) {\n state.display.shortfall(current, { kind: 'route-failed', outcome });\n }\n if (outcome === 'refreshed' || outcome === 'partial') {\n stats.refreshes += 1;\n if (outcome === 'partial') stats.partial += 1;\n state.routeAwaitsSave = outcome === 'partial' && !forSave;\n // Route markup has no local application identities; every prior stamp is stale.\n state.lastAppliedIdentity = new WeakMap();\n // The fresh markup carries no stamp: the guesses go back on before the\n // cache is rebuilt from it, or the rebuild would not know them.\n if (currentData !== undefined) this.host.restoreGuesses(current, currentData);\n this.host.rebuildCache();\n if (currentData === undefined || !isCurrent()) return;\n this.host.reapply(current, currentData);\n if (deps.emitter.listenerCount('afterUpdate') > 0) {\n void deps.emitter.emitWhile(\n 'afterUpdate',\n {\n data: currentData,\n // The strategy replaced the whole route, so every binding now on\n // the page carries new markup; the unsaved fields scheduled just\n // above report themselves in their own `patch` batch.\n updatedCount: deps.cache.elementCount,\n durationMs: Date.now() - current.receivedAt,\n revision: current.revision.revision,\n receivedAt: current.receivedAt,\n source: 'route',\n },\n isCurrent,\n );\n }\n return;\n }\n // A refusal is a pause, not a breakage; counting the two together is how\n // `failed: 3` came to stand in an inspection where nothing was wrong.\n if (outcome === 'failed') stats.failed += 1;\n else if (outcome === 'refused') stats.refused += 1;\n // Either way the page shows what it can now: the window holds back the\n // server, not the bindings this revision could already have written.\n if (currentData !== undefined) this.host.reapply(current, currentData);\n }\n\n /** LP0806, once: a fragment boundary with no handler is patched instead. */\n warnFragmentFallback(target: CachedElement): void {\n warnFragmentFallback(this.deps, this.state, target);\n }\n\n /** LP0407, once per element: an unknown strategy is left alone, not guessed at. */\n warnUnsupportedStrategy(target: CachedElement): void {\n warnUnsupportedStrategy(this.deps, this.state, target);\n }\n\n /** The deterministic fallback: patch the boundary's own bindings from the same revision. */\n private patchFallback(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n boundary: Element,\n ownerKeys: OwnerScope,\n isCurrent: () => boolean,\n ): void {\n if (!isCurrent()) return;\n for (const [fieldName, bindings] of this.deps.cache.entries()) {\n for (const target of bindings) {\n if (target.fragmentBoundary !== boundary) continue;\n if (ownerKeys !== false && !isBindingInScope(target.owner, ownerKeys)) continue;\n const value = bindingValue(data.fields, target, fieldName, transaction.locale);\n if (value === undefined || !isCurrent()) continue;\n this.deps.scheduler.schedule({\n target,\n value: this.host.transform(target, value, data.fields, isCurrent),\n allFields: data.fields,\n revision: transaction.revision,\n data,\n });\n }\n }\n }\n}\n\n/** The distinct boundaries around `targets`, or `undefined` when one sits outside them all. */\nfunction coveringBoundaries(targets: readonly CachedElement[]): Element[] | undefined {\n const boundaries: Element[] = [];\n for (const target of targets) {\n const boundary = target.fragmentBoundary;\n if (boundary === undefined) return undefined;\n if (!boundaries.includes(boundary)) boundaries.push(boundary);\n }\n return boundaries;\n}\n\n/** Whether the document that owns `element` is inside the update's owner scope. */\nfunction inOwnerScope(element: Element, ownerKeys: OwnerScope): boolean {\n return ownerKeys === false || isBindingInScope(resolveBindingOwner(element), ownerKeys);\n}\n\n/**\n * Morph server-rendered HTML into the boundary; compatible retained nodes keep\n * live state. Islands follow ADR 0021: removed ones are released, and an\n * inserted one the page cannot start is reported rather than scripted.\n */\nfunction morphFragment(\n boundary: Element,\n html: string,\n blocked: (island: Element, blocker: 'element' | 'directive') => void,\n): void {\n const template = boundary.ownerDocument.createElement('template');\n template.innerHTML = trustedHtml(html);\n const rendered = boundary.cloneNode(false) as Element;\n rendered.append(template.content);\n const before = astroIslandsIn(boundary);\n morphElement(boundary, rendered, {\n keyAttributes: [KEY_ATTRIBUTE],\n boundary: isMorphBoundary,\n retainBoundary: retainIslandBoundary,\n });\n releaseDisconnectedIslands(before);\n const known = new Set(before);\n for (const island of astroIslandsIn(boundary)) {\n const blocker = known.has(island) ? undefined : islandStartBlocker(island);\n if (blocker !== undefined) blocked(island, blocker);\n }\n}\n","/**\n * The plugin boundary on a value's way to its binding. Transforms are consumer\n * code: their result is frozen into the scheduler entry, an error is reported\n * as LP0602 and the original value kept, and a thenable is a contract error —\n * a transform that awaits would hand the scheduler a promise to render.\n */\n\nimport type { RuntimeDeps } from './runtime-state';\nimport { observeThenableResult } from './thenable';\nimport type { CachedElement } from './types';\n\n/** Never awaited: every consumer callback may accept a newer revision synchronously (ADR 0004). */\nexport function transformForBinding(\n deps: RuntimeDeps,\n target: CachedElement,\n originalValue: unknown,\n allFields: Record<string, unknown>,\n isCurrent: () => boolean,\n): unknown {\n const transform = deps.transformValue;\n if (transform === undefined) return originalValue;\n try {\n const transformed = transform(\n target.fieldName,\n originalValue,\n { element: target.element, allFields },\n isCurrent,\n );\n const returnedThenable = observeThenableResult(transformed);\n if (!isCurrent()) return originalValue;\n if (returnedThenable) {\n throw new TypeError(\n `Transform for \"${target.fieldName}\" returned a thenable; transforms must be synchronous`,\n );\n }\n return transformed;\n } catch (err) {\n if (!isCurrent()) return originalValue;\n const error = err instanceof Error ? err : new Error(String(err));\n void deps.emitter.emit('error', { error, context: 'transform', code: 'LP0602' });\n return originalValue;\n }\n}\n","/**\n * From an accepted message to scheduled writes: merge, diff, plan the\n * strategies, schedule each binding, and finish the revision on flush.\n */\n\nimport type { PayloadLivePreviewData, PayloadLivePreviewMessage } from '@/types/payload-protocol';\nimport { buildSchemaIndex } from '@schema/index';\nimport { adoptUniqueBindings, restoreUniqueBindings } from './auto-bind';\nimport { isBindingInScope } from './binding-owner';\nimport type { MergeResult } from './data-merger';\nimport { mergeDependencyMaps } from './dependencies';\nimport { bindingIdentity, bindingValue } from './field-value';\nimport { type MessageRevision, sameRevision } from './message-bus';\nimport { reportMovedRow } from './moved-rows';\nimport { NavigationReplay } from './navigation-replay';\nimport { diagnoseOrphanFields } from './orphan-diagnostics';\nimport { reportOmittedFeature } from './profile';\nimport { observeCapabilities } from './protocol-version';\nimport { owesForceRender } from './relationship-tracker';\nimport { revealBinding } from './reveal';\nimport { runtimeDisplayHost } from './revision-display';\nimport { type RuntimeDeps, type RuntimeState, type UpdateTransaction } from './runtime-state';\nimport { resolveStrategy } from './strategies';\nimport { StrategyRunner } from './strategy-runner';\nimport { createLeanStrategyRunner, type StrategyRunnerLike } from './strategy-runner-lean';\nimport { transformForBinding } from './transform-value';\nimport { ownerKeysForUpdate } from './update-owner';\nimport type { FlushStats, ScheduledUpdate } from './update-scheduler';\n\n/** A refinement moved no field: it completes values the revision already applied. */\nconst NOTHING_CHANGED: ReadonlySet<string> = new Set();\n/** The populated re-fetch failed; the message's own values stand in (ADR 0023). */\nconst MERGE_FAILED = { kind: 'merge' } as const;\n\nexport class UpdatePipeline {\n private readonly strategies: StrategyRunnerLike;\n private readonly navigationReplay: NavigationReplay;\n\n constructor(\n private readonly deps: RuntimeDeps,\n private readonly state: RuntimeState,\n rebuildCache: () => void,\n ) {\n state.changes.keepValues = deps.subfieldCoverage === 'declared';\n state.display.host = runtimeDisplayHost(deps, state);\n // Esbuild folds this choice; the lean branch drops the server-rendering strategies.\n this.strategies =\n typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__\n ? createLeanStrategyRunner(deps, state)\n : new StrategyRunner(deps, state, {\n reapply: (transaction, data) => {\n this.scheduleAllFields(transaction, data);\n },\n transform: (target, value, allFields, isCurrent) =>\n transformForBinding(deps, target, value, allFields, isCurrent),\n rebuildCache,\n restoreGuesses: (transaction, data) => {\n this.restoreGuesses(transaction, data);\n },\n revealPending: (transaction) => {\n this.revealPending(transaction);\n },\n });\n this.navigationReplay = new NavigationReplay(deps, state, {\n schedule: (transaction, data, elements) => {\n this.scheduleAllFields(transaction, data, elements);\n },\n });\n }\n\n handleUpdate(\n message: PayloadLivePreviewMessage,\n origin: string,\n revision: MessageRevision | undefined,\n ): void {\n const { deps, state } = this;\n deps.heartbeat.kick();\n state.protocol.observe(observeCapabilities(message), deps.log, deps.warn);\n const rawData = message.data;\n if (rawData === undefined) {\n if (message.protocolVersion !== undefined) {\n state.protocol.applyVersion(message.protocolVersion, deps.log);\n }\n return;\n }\n if (revision === undefined) return;\n this.acceptDataUpdate(message, rawData, origin, revision, true);\n }\n\n handleReplay(\n message: PayloadLivePreviewMessage,\n origin: string,\n revision: MessageRevision,\n ): void {\n const rawData = message.data;\n if (rawData === undefined) return;\n this.acceptDataUpdate(message, rawData, origin, revision, false);\n }\n\n reapplyNavigationBindings(elements: ReadonlySet<Element>): void {\n this.navigationReplay.reapplyBindings(elements);\n }\n\n /** Hand a streamed island only the retained document it has not seen yet. */\n reapplyNavigationIslands(islands: readonly Element[], hydrationCompleted = false): void {\n this.navigationReplay.reapplyIslands(islands, hydrationCompleted);\n }\n\n private acceptDataUpdate(\n message: PayloadLivePreviewMessage,\n rawData: Record<string, unknown>,\n origin: string,\n revision: MessageRevision,\n countsAsUpdate: boolean,\n ): void {\n const { deps, state } = this;\n // A level, not an edge: the panel repeats its last document event in every\n // message and never clears it, so only a changed event about a document\n // other than this one is news (LP-1).\n const relationshipInspection = countsAsUpdate ? state.relationships.inspect(message) : null;\n const locale = typeof message.locale === 'string' ? message.locale : state.locale;\n let schema = state.schema;\n let schemaIndex = state.schemaIndex;\n if (Array.isArray(message.fieldSchemaJSON)) {\n schema = message.fieldSchemaJSON;\n schemaIndex = buildSchemaIndex(message.fieldSchemaJSON);\n }\n // Schema parsing and synthetic message accessors are trust boundaries. A\n // newer accepted revision that reentered there already owns the runtime.\n const incumbent = state.activeUpdate;\n if (\n !state.isRunning() ||\n (incumbent !== null && incumbent.revision.revision > revision.revision)\n ) {\n return;\n }\n const relationshipEdit =\n relationshipInspection === null ? null : state.relationships.commit(relationshipInspection);\n const previous = incumbent;\n const transaction: UpdateTransaction = {\n revision,\n message,\n rawData,\n locale,\n schema,\n schemaIndex,\n receivedAt: Date.now(),\n forceRender: relationshipEdit !== null || owesForceRender(previous),\n countsAsUpdate,\n renderData: undefined,\n fragmentBoundariesRun: new WeakSet(),\n touched: new Set(),\n baseline: false,\n navigated: false,\n invalidated: new Set(),\n revealTarget: undefined,\n revealIdentities: [],\n pendingFragments: 0,\n routeRefreshed: false,\n cancelled: false,\n completed: false,\n };\n // Acceptance is the single supersession point. Only a revision that never\n // reached its terminal state counts as superseded. Publish the new owner\n // before aborting: an AbortSignal listener may accept a newer revision.\n state.locale = locale;\n state.schema = schema;\n state.schemaIndex = schemaIndex;\n if (previous !== null && !previous.completed && previous.countsAsUpdate) {\n state.supersededCount += 1;\n }\n state.activeUpdate = transaction;\n if (countsAsUpdate) state.updateCount += 1;\n state.display.begin(transaction, revision.revision);\n if (!state.isCurrent(transaction)) return;\n deps.scheduler.acceptRevision(revision);\n if (!state.isCurrent(transaction)) return;\n state.supersedeStrategies();\n if (!state.isCurrent(transaction)) return;\n if (relationshipEdit !== null) {\n void deps.emitter.emitWhile(\n 'relationshipUpdate',\n { detail: relationshipEdit, timestamp: Date.now() },\n () => state.isCurrent(transaction),\n );\n if (!state.isCurrent(transaction)) return;\n }\n if (countsAsUpdate && message.protocolVersion !== undefined) {\n state.protocol.applyVersion(message.protocolVersion, deps.log);\n if (!state.isCurrent(transaction)) return;\n }\n if (countsAsUpdate && deps.connection.markConnected()) {\n deps.a11y?.announceConnected();\n void deps.emitter.emit('connect', { origin, timestamp: Date.now() });\n if (!state.isCurrent(transaction)) return;\n deps.log('connection', 'disconnected', '→', 'connected');\n if (!state.isCurrent(transaction)) return;\n }\n // Nothing awaits this, so an unexpected throw would leave the page as an\n // unhandled rejection — a console error the host cannot attribute, and a\n // process exit under `--unhandled-rejections=strict`.\n void this.processUpdate(transaction).catch((error: unknown) => {\n deps.log('update failed:', error);\n });\n }\n\n private async processUpdate(transaction: UpdateTransaction): Promise<void> {\n const { deps, state } = this;\n const fields = await this.resolveIncomingFields(transaction);\n if (fields === null || !state.isCurrent(transaction)) return;\n const data = this.dataFor(transaction, fields);\n if (deps.emitter.listenerCount('beforeUpdate') > 0) {\n const completed = await deps.emitter.emitWhile(\n 'beforeUpdate',\n {\n data,\n revision: transaction.revision.revision,\n receivedAt: transaction.receivedAt,\n source: 'patch',\n cancel: (): void => {\n transaction.cancelled = true;\n deps.scheduler.cancelRevision(transaction.revision);\n },\n },\n () => !transaction.cancelled && state.isCurrent(transaction),\n );\n if (!completed || transaction.cancelled || !state.isCurrent(transaction)) return;\n }\n this.applyFields(transaction, data, false);\n }\n\n private dataFor(\n transaction: UpdateTransaction,\n fields: Record<string, unknown>,\n ): PayloadLivePreviewData {\n const { message } = transaction;\n return {\n fields,\n ...(transaction.schema !== undefined ? { schema: transaction.schema } : {}),\n ...(typeof message.globalSlug === 'string' ? { globalSlug: message.globalSlug } : {}),\n ...(typeof message.collectionSlug === 'string'\n ? { collectionSlug: message.collectionSlug }\n : {}),\n ...(transaction.locale !== undefined ? { locale: transaction.locale } : {}),\n };\n }\n\n /**\n * Diff against what the page last showed, then schedule. A refinement is the\n * populated answer to values this revision already applied: it keeps the diff\n * in step without letting population count as an edit, because no strategy\n * may be planned a second time for one message.\n */\n private applyFields(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n refined: boolean,\n ): void {\n const { deps, state } = this;\n if (!state.isCurrent(transaction)) return;\n if (state.changes.isBaseline && !refined && deps.autoBind !== 'off') {\n // Once, on the message that describes what the server rendered (ADR 0014\n // §1). The lean profile leaves the search out; esbuild folds the branch.\n if (typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__) {\n reportOmittedFeature('auto-binding');\n } else {\n const scope = ownerKeysForUpdate(deps, state, transaction, data.fields);\n adoptUniqueBindings(deps, state, data.fields, transaction.locale, scope, () =>\n state.isCurrent(transaction),\n );\n }\n if (!state.isCurrent(transaction)) return;\n }\n const dependencies = mergeDependencyMaps(deps.dependencies, deps.cache.dependencyMap());\n if (!state.isCurrent(transaction)) return;\n const changes = state.changes.diff(data.fields, dependencies, () =>\n state.isCurrent(transaction),\n );\n if (changes === null) return;\n const navigationReplay = !refined && state.navigationReplayPending;\n if (navigationReplay) {\n state.navigationReplayPending = false;\n state.navigationBindingReplay = true;\n }\n // A navigation replay counts every field as changed but is not the baseline.\n transaction.baseline = changes.baseline && !navigationReplay;\n transaction.navigated = navigationReplay;\n transaction.invalidated = refined ? NOTHING_CHANGED : changes.invalidated;\n transaction.touched = refined\n ? NOTHING_CHANGED\n : new Set([...changes.changed, ...changes.invalidated]);\n transaction.renderData = data;\n this.scheduleAllFields(transaction, data);\n }\n\n /** The document to render: merged when the server has something to add, else the message's own values; `null` when superseded. */\n private async resolveIncomingFields(\n transaction: UpdateTransaction,\n ): Promise<Record<string, unknown> | null> {\n const { deps, state } = this;\n const raw = transaction.rawData;\n if (deps.merger === null) return raw;\n const plan = state.merges.decide(deps, transaction);\n if (!plan.merge) return plan.fields;\n const { message } = transaction;\n const coalesced = state.merges.request(deps.merger, deps.mergeWindowMs, {\n collectionSlug: message.collectionSlug,\n globalSlug: message.globalSlug,\n data: raw,\n ...(transaction.schema === undefined ? {} : { schema: transaction.schema }),\n locale: transaction.locale,\n });\n // A request the burst shares is not one the page waits for: it renders what\n // it already has, and the answer refines it when the window closes.\n if (!coalesced.leading) {\n void this.applyMerged(transaction, coalesced.result).catch((error: unknown) => {\n deps.log('update failed:', error);\n });\n return plan.fields;\n }\n const result = await coalesced.result;\n if (!state.isCurrent(transaction)) return null;\n if (result.status === 'merged') {\n state.merges.recordMerged(result.doc, transaction.locale);\n return result.doc;\n }\n if (result.status === 'superseded') return null;\n state.display.shortfall(transaction, MERGE_FAILED);\n return plan.fields;\n }\n\n /** Whoever is still current when the shared merge lands gets the populated document. */\n private async applyMerged(\n transaction: UpdateTransaction,\n pending: Promise<MergeResult>,\n ): Promise<void> {\n const { state } = this;\n const result = await pending;\n if (result.status === 'unavailable') state.display.shortfall(transaction, MERGE_FAILED);\n if (result.status !== 'merged' || !state.isCurrent(transaction)) return;\n state.merges.recordMerged(result.doc, transaction.locale);\n this.applyFields(transaction, this.dataFor(transaction, result.doc), true);\n }\n\n scheduleAllFields(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n onlyElements?: ReadonlySet<Element>,\n ): void {\n const { deps, state } = this;\n if (!state.isCurrent(transaction)) return;\n const lateBindings = onlyElements !== undefined;\n const isCurrent = (): boolean => state.isCurrent(transaction);\n const ownerKeys = ownerKeysForUpdate(deps, state, transaction, data.fields);\n if (!isCurrent()) return;\n const { touched } = transaction;\n // A revision that touches the route refreshes it first; the re-apply lands on the fresh markup.\n const route = deps.strategies.route;\n if (\n lateBindings &&\n route !== undefined &&\n !transaction.routeRefreshed &&\n this.navigationReplay.hasLateRouteBinding(onlyElements, ownerKeys, transaction, data)\n ) {\n if (isCurrent()) void this.strategies.refreshRoute(transaction, data, route);\n return;\n }\n const unbound = !lateBindings && this.strategies.hasUnboundChange(transaction, ownerKeys);\n // A revision inherits a refused refresh; a baseline cannot owe one.\n const owed = state.routeRefreshOwed;\n if (\n !lateBindings &&\n route !== undefined &&\n !transaction.routeRefreshed &&\n (unbound || owed || this.strategies.plansRoute(route, transaction, ownerKeys)) &&\n isCurrent()\n ) {\n state.routeRefreshOwed = false;\n void this.strategies.refreshRoute(transaction, data, route);\n return;\n }\n const fragmentTouched = lateBindings\n ? this.navigationReplay.fieldsForElements(onlyElements, touched)\n : touched;\n const plan = this.navigationReplay.unrunFragmentPlan(\n transaction,\n this.strategies.planFragments(fragmentTouched, ownerKeys),\n onlyElements,\n );\n if (!isCurrent()) return;\n const trackIdentity = deps.skipUnchanged;\n let scheduled = 0;\n for (const [fieldName, bindings] of deps.cache.entries()) {\n if (!isCurrent()) return;\n for (const target of bindings) {\n if (onlyElements !== undefined && !onlyElements.has(target.element)) continue;\n if (ownerKeys !== false && !isBindingInScope(target.owner, ownerKeys)) continue;\n // A binding inside a boundary the server renders is patched only as the\n // fallback — but it can still be the field being edited, so the reveal\n // has to notice it here, before the boundary is re-rendered.\n if (plan?.covers(target) === true) {\n // Resolving the value is only worth it when something reveals.\n if (deps.revealEditedField) {\n const raw = bindingValue(data.fields, target, fieldName, transaction.locale);\n state.revealLedger.note(transaction, target, raw);\n }\n continue;\n }\n const kind = target.strategyKind ?? resolveStrategy(target.element) ?? 'unknown';\n if (kind === 'unknown') {\n this.strategies.warnUnsupportedStrategy(target);\n continue;\n }\n if (kind === 'fragment' && plan === null) this.strategies.warnFragmentFallback(target);\n const value = bindingValue(data.fields, target, fieldName, transaction.locale);\n if (value === undefined) {\n state.absentFields.add(fieldName);\n continue;\n }\n reportMovedRow(deps, state, target, data.fields, transaction.navigated);\n // Before `skipUnchanged` can skip the write: a binding unchanged since the\n // last write that landed may still be the field whose reveal was superseded.\n if (!lateBindings && deps.revealEditedField) {\n state.revealLedger.note(transaction, target, value);\n }\n if (!isCurrent()) return;\n const transformed = transformForBinding(deps, target, value, data.fields, isCurrent);\n if (!isCurrent()) return;\n // A binding renders its own value *and* the sibling fields bound to\n // href/src/alt, so its identity must cover them: otherwise an edit to\n // the sibling alone looks unchanged and the link or image stays stale.\n const identity = trackIdentity\n ? bindingIdentity(target, transformed, data.fields, transaction.locale)\n : undefined;\n const last = state.lastAppliedIdentity.get(target.element);\n if (\n !transaction.forceRender &&\n deps.skipUnchanged &&\n identity !== undefined &&\n last === identity &&\n !transaction.invalidated.has(fieldName)\n ) {\n state.skippedUnchangedCount += 1;\n continue;\n }\n const update: ScheduledUpdate = {\n target,\n value: transformed,\n allFields: data.fields,\n revision: transaction.revision,\n ...(lateBindings ? {} : { data }),\n valueIdentity: identity,\n };\n deps.scheduler.schedule(update);\n scheduled += 1;\n }\n }\n if (!lateBindings) {\n diagnoseOrphanFields(\n deps,\n state.warnedOrphanFields,\n transaction.rawData,\n transaction.locale,\n ownerKeys,\n );\n }\n if (!isCurrent()) return;\n if (plan !== null && plan.boundaries.length > 0) {\n for (const boundary of plan.boundaries) transaction.fragmentBoundariesRun.add(boundary);\n transaction.pendingFragments += plan.boundaries.length;\n void this.strategies.runFragments(transaction, data, plan);\n }\n if (lateBindings || !isCurrent()) return;\n // Islands consume the snapshot, not fragment markup. Only completion and\n // reveal wait for pending requests or a synchronously scheduled fallback.\n if (scheduled === 0) {\n if (transaction.pendingFragments === 0 && deps.scheduler.pendingCount === 0) {\n state.complete(transaction);\n this.revealPending(transaction);\n }\n this.notifyIslands(transaction, data);\n }\n }\n\n /** Islands hear every revision that carried a change, whether or not a write landed outside them. */\n private notifyIslands(transaction: UpdateTransaction, data: PayloadLivePreviewData): void {\n if (transaction.touched.size === 0) return;\n this.navigationReplay.dispatchIslands(transaction, data, this.deps.cache.islands);\n }\n\n /**\n * A server render — the route, or a fragment boundary — replaced markup\n * without the stamps a guess lives by; look for the baseline's guesses\n * again, and for nothing else (ADR 0014).\n */\n private restoreGuesses(transaction: UpdateTransaction, data: PayloadLivePreviewData): void {\n const { deps, state } = this;\n if (deps.autoBind === 'off' || state.autoBindGuesses === null) return;\n // Nothing reaches this in the lean build, which renders no route and no\n // fragment. A folded branch, not an early return: esbuild drops the branch\n // before linking and a statement after `return` only after it, and the\n // search's module was in the lean artifact until the guard took this shape.\n if (!(typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__)) {\n const scope = ownerKeysForUpdate(deps, state, transaction, data.fields);\n restoreUniqueBindings(deps, state, data.fields, transaction.locale, scope, () =>\n state.isCurrent(transaction),\n );\n }\n }\n\n /** Scheduler callback after every flush, including one that applied nothing. */\n onFlush(stats: FlushStats): void {\n const { deps, state } = this;\n state.lastFlush = stats;\n if (stats.deferred > 0 && !state.warnedVisibilityGate) {\n state.warnedVisibilityGate = true;\n deps.warn(\n `[live-preview] LP0301: visibility gate held ${String(stats.deferred)} off-screen update(s) until scrolled into view; see visibilityGateThreshold`,\n );\n }\n const { revision, data } = stats;\n if (revision === undefined) return;\n const transaction = state.activeUpdate;\n if (\n transaction === null ||\n !state.isCurrent(transaction) ||\n !sameRevision(transaction.revision, revision)\n ) {\n return;\n }\n state.display.deferred(transaction, stats.deferred);\n if (transaction.pendingFragments === 0) state.complete(transaction);\n const isCurrent = (): boolean =>\n state.isCurrent(transaction) && sameRevision(transaction.revision, revision);\n const renderData = data ?? transaction.renderData;\n // Reveal first: scrolling to a deferred off-screen edit is what replays it.\n this.revealPending(transaction);\n if (!isCurrent()) return;\n // Before the applied check: a flush that applied nothing is where every renderer refused.\n const unfaithful = state.unfaithfulPatches;\n if (unfaithful.length > 0) {\n state.unfaithfulPatches = [];\n if (renderData !== undefined) {\n const scope = ownerKeysForUpdate(deps, state, transaction, renderData.fields);\n this.strategies.escalateUnfaithful(transaction, renderData, unfaithful, scope);\n }\n if (!isCurrent()) return;\n }\n if (data === undefined) return;\n if (stats.applied > 0) deps.a11y?.announceUpdate(stats.applied);\n if (!isCurrent()) return;\n // An island still needs its event when `skipUnchanged` leaves every outer binding untouched.\n this.notifyIslands(transaction, data);\n if (!isCurrent() || stats.applied === 0 || deps.emitter.listenerCount('afterUpdate') === 0) {\n return;\n }\n void deps.emitter.emitWhile(\n 'afterUpdate',\n {\n data,\n updatedCount: stats.applied,\n durationMs: stats.durationMs,\n revision: revision.revision,\n receivedAt: transaction.receivedAt,\n source: 'patch',\n },\n isCurrent,\n );\n }\n\n /**\n * Reveal the binding this revision marked, once. Called from the patch flush\n * and again once fragments land, because only one of the two runs for any\n * given field, and a fragment-rendered element is in place only afterwards.\n */\n revealPending(transaction: UpdateTransaction): void {\n const target = this.state.revealLedger.commit(transaction);\n if (target === undefined) return;\n try {\n revealBinding(this.state.revealer, target);\n } catch (error) {\n this.deps.log('reveal', error);\n }\n }\n\n /**\n * Scroll one field's bound element into view; the admin-focus path (tier 2)\n * names a field, so it takes the first binding — a focus message carries no\n * document identity to choose between several.\n */\n revealField(fieldName: string): ReturnType<typeof revealBinding> {\n const target = this.deps.cache.get(fieldName)?.[0];\n return target === undefined ? 'no-element' : revealBinding(this.state.revealer, target);\n }\n\n /** Payload saved the document; a route rendered from the older save may render again. */\n documentSaved(): void {\n this.strategies.refreshAfterSave();\n }\n}\n","/**\n * The strategy runner the lean profile gets instead of the real one: it plans\n * nothing, renders nothing, and says so once per feature (LP0104). Its purpose\n * is that the pipeline needs no branch of its own — it holds a runner either\n * way, and the profile decides which.\n *\n * Because this module names the real runner only as a type, the lean build\n * drops that file and everything only it referenced: the morph, the fragment\n * protocol client's server half, and the route refresh.\n */\n\nimport { reportUnboundChange } from './fidelity';\nimport { reportOmittedFeature } from './profile';\nimport type { StrategyRunner } from './strategy-runner';\nimport { warnFragmentFallback, warnUnsupportedStrategy } from './strategy-warnings';\nimport type { RuntimeDeps, RuntimeState, UpdateTransaction } from './runtime-state';\nimport { declaredSubfields, unboundChangedFields, type OwnerScope } from './unbound-fields';\nimport type { CachedElement } from './types';\n\n/** What `UpdatePipeline` calls on a runner; both profiles satisfy it. */\nexport type StrategyRunnerLike = Pick<\n StrategyRunner,\n | 'planFragments'\n | 'escalateUnfaithful'\n | 'hasUnboundChange'\n | 'plansRoute'\n | 'runFragments'\n | 'refreshRoute'\n | 'refreshAfterSave'\n | 'warnFragmentFallback'\n | 'warnUnsupportedStrategy'\n>;\n\nexport function createLeanStrategyRunner(\n deps: RuntimeDeps,\n state: RuntimeState,\n): StrategyRunnerLike {\n return {\n planFragments: (): null => null,\n // Nothing to escalate to. The pipeline still drains its queue, so a page\n // that keeps producing findings does not keep producing entries; the\n // patches stay as they are, and the revision says so (ADR 0023).\n escalateUnfaithful: (transaction, _data, targets): void => {\n for (const { fieldName: field } of targets) {\n state.display.shortfall(transaction, { kind: 'unfaithful', field });\n }\n },\n // Nothing here to escalate to, and the finding is still worth recording:\n // a page that changes a field it does not bind is the page\n // `inspect().fidelity` is read on, and `escalated` staying 0 beside it is\n // the truth about this profile rather than silence about the change.\n hasUnboundChange: (transaction: UpdateTransaction, ownerKeys: OwnerScope): boolean => {\n if (transaction.baseline) return false;\n const unbound = unboundChangedFields(\n deps.cache,\n transaction.touched,\n transaction.locale,\n ownerKeys,\n declaredSubfields(\n deps.subfieldCoverage,\n state.changes.previousFields,\n transaction.renderData?.fields,\n ),\n );\n for (const field of unbound) {\n reportUnboundChange(state, field);\n state.display.shortfall(transaction, { kind: 'unbound', field });\n }\n return false;\n },\n plansRoute: (): boolean => false,\n runFragments: (): Promise<void> => Promise.resolve(),\n // A page that carries a route prelude anyway (it can be injected by hand)\n // still gets no refresh here: this runtime has no code for one.\n refreshRoute: (): Promise<void> => {\n reportOmittedFeature('route refreshes');\n return Promise.resolve();\n },\n // No route was rendered, so no save has one to render again.\n refreshAfterSave: (): void => undefined,\n warnFragmentFallback: (target: CachedElement): void => {\n reportOmittedFeature('server-rendered fragments');\n warnFragmentFallback(deps, state, target);\n },\n warnUnsupportedStrategy: (target: CachedElement): void => {\n warnUnsupportedStrategy(deps, state, target);\n },\n };\n}\n","/**\n * Debounce, frame batching and off-screen replay for scheduled writes. The\n * first write of a quiet phase does not wait for the window: it goes out on the\n * next frame and opens the window that batches the rest of the burst, so an\n * isolated keystroke costs a frame instead of a whole debounce. The scheduler\n * never writes the DOM; the injected `apply` callback does.\n */\n\nimport type { PayloadLivePreviewData } from '@/types/payload-protocol';\nimport { hasSameBindingIdentity } from './cache';\nimport { usesNoWriteOutcome } from './internal-outcome';\nimport { type MessageRevision, sameRevision } from './message-bus';\nimport type { CachedElement } from './types';\n\nexport interface ScheduledUpdate {\n readonly target: CachedElement;\n readonly value: unknown;\n readonly allFields: Record<string, unknown>;\n /** Revision revision; runtime-produced entries always carry one. */\n readonly revision?: MessageRevision | undefined;\n readonly data?: PayloadLivePreviewData | undefined;\n /** `valueIdentity(value)`, computed once by the pipeline for skip and reveal. */\n readonly valueIdentity?: string | undefined;\n}\n\nexport type ApplyUpdate = (update: ScheduledUpdate) => void;\n\nexport interface UpdateSchedulerOptions {\n /** Debounce window in ms; the write that opens it does not wait for it. Default 50. */\n readonly debounceMs?: number;\n /** Longest a flush may be postponed by continuous scheduling. Default `4 * debounceMs`. */\n readonly maxWaitMs?: number;\n /** Deferred writes replay when the host reports the element visible via `notifyVisible()`. */\n readonly isVisible: (element: Element) => boolean;\n /** Apply every write immediately regardless of visibility. Default `false`. */\n readonly disableVisibilityGate?: boolean;\n /** Cached-element count above which the gate activates. Default 50. */\n readonly visibilityGateThreshold?: number;\n readonly getCacheSize: () => number;\n readonly onFlush?: (stats: FlushStats) => void;\n /** Frame scheduler; defaults to `requestAnimationFrame`. Tests inject a synchronous one. */\n readonly scheduleFrame?: (callback: FrameRequestCallback) => number;\n readonly cancelFrame?: (handle: number) => void;\n}\n\nexport interface FlushStats {\n readonly applied: number;\n /** Field names applied, in order; `applied` alone cannot say which binding stayed stale. */\n readonly appliedFields: readonly string[];\n readonly deferred: number;\n readonly durationMs: number;\n readonly revision?: MessageRevision;\n readonly data?: PayloadLivePreviewData;\n}\n\n/** Exported so the merge behind a burst of writes can share the window that batches them. */\nexport const DEFAULT_DEBOUNCE_MS = 50;\n/** Exported so `pll doctor` can prove its own copy of the number has not drifted. */\nexport const DEFAULT_VISIBILITY_THRESHOLD = 50;\n/**\n * Longest a write waits for an animation frame. WebKit gave a visible\n * cross-origin preview frame none for seconds (the real-admin suite, 2026-10-22,\n * `animationFramesIn600ms: 0`): the document had arrived and the page kept the\n * old text. Frames come every 16 to 33 ms where they come at all.\n */\nconst FRAME_FALLBACK_MS = 100;\n\ninterface BufferEntry {\n target: CachedElement;\n value: unknown;\n allFields: Record<string, unknown>;\n revision: MessageRevision | undefined;\n data: PayloadLivePreviewData | undefined;\n valueIdentity: string | undefined;\n}\n\nexport class UpdateScheduler {\n private readonly apply: ApplyUpdate;\n private readonly debounceMs: number;\n private readonly maxWaitMs: number;\n private readonly isVisible: (element: Element) => boolean;\n private readonly gateThresholdValue: number;\n private readonly gateDisabled: boolean;\n private readonly getCacheSize: () => number;\n private readonly onFlush: ((stats: FlushStats) => void) | undefined;\n private readonly scheduleFrame: (callback: FrameRequestCallback) => number;\n private readonly cancelFrame: (handle: number) => void;\n private pending = new Map<Element, BufferEntry>();\n private readonly replay = new Map<Element, BufferEntry>();\n private readonly activeFlushes = new Set<Map<Element, BufferEntry>>();\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private debounceToken = 0;\n private deadlineTimer: ReturnType<typeof setTimeout> | null = null;\n private frameHandle: number | null = null;\n private frameFallback: ReturnType<typeof setTimeout> | null = null;\n private frameToken = 0;\n /** End of the window the leading write opened; inside it a write waits for the debounce. */\n private windowUntil = 0;\n private activeRevision: MessageRevision | null = null;\n private activeRevisionCancelled = false;\n private destroying = false;\n\n constructor(apply: ApplyUpdate, options: UpdateSchedulerOptions) {\n this.apply = apply;\n this.debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;\n this.maxWaitMs = options.maxWaitMs ?? this.debounceMs * 4;\n this.isVisible = options.isVisible;\n this.gateThresholdValue = options.visibilityGateThreshold ?? DEFAULT_VISIBILITY_THRESHOLD;\n this.gateDisabled = options.disableVisibilityGate ?? false;\n this.getCacheSize = options.getCacheSize;\n this.onFlush = options.onFlush;\n this.scheduleFrame =\n options.scheduleFrame ??\n (typeof requestAnimationFrame === 'function'\n ? requestAnimationFrame.bind(globalThis)\n : (callback) =>\n setTimeout(() => {\n callback(performance.now());\n }, 0) as unknown as number);\n this.cancelFrame =\n options.cancelFrame ??\n (typeof cancelAnimationFrame === 'function'\n ? cancelAnimationFrame.bind(globalThis)\n : (handle) => {\n clearTimeout(handle as unknown as ReturnType<typeof setTimeout>);\n });\n }\n\n /** Queue a write; a later write for the same element replaces it until the flush. */\n schedule(update: ScheduledUpdate): void {\n if (this.destroying) return;\n if (update.revision !== undefined) {\n if (this.activeRevisionCancelled) return;\n if (this.activeRevision === null || !sameRevision(update.revision, this.activeRevision)) {\n return;\n }\n }\n const existing = this.pending.get(update.target.element);\n if (existing) {\n existing.value = update.value;\n existing.allFields = update.allFields;\n existing.revision = update.revision;\n existing.data = update.data;\n existing.valueIdentity = update.valueIdentity;\n } else {\n this.pending.set(update.target.element, {\n target: update.target,\n value: update.value,\n allFields: update.allFields,\n revision: update.revision,\n data: update.data,\n valueIdentity: update.valueIdentity,\n });\n }\n this.armDebounce();\n }\n\n /**\n * Make `revision` the sole revision allowed to schedule, flush or replay.\n * Older buffered work is dropped even if the new revision is later cancelled.\n */\n acceptRevision(revision: MessageRevision): void {\n if (this.destroying) return;\n if (this.activeRevision !== null && sameRevision(revision, this.activeRevision)) return;\n if (this.activeRevision !== null && compareRevision(revision, this.activeRevision) < 0) return;\n this.clearWork();\n this.activeRevision = revision;\n this.activeRevisionCancelled = false;\n // Publish ownership before host cancellation can accept or end another owner.\n this.cancelScheduledWork();\n }\n\n /** Cancel buffered work for exactly one revision without reviving its predecessor. */\n cancelRevision(revision: MessageRevision): void {\n if (this.activeRevision === null || !sameRevision(revision, this.activeRevision)) return;\n this.clearWork();\n this.activeRevisionCancelled = true;\n this.cancelScheduledWork();\n }\n\n /** Flush immediately, bypassing the debounce. */\n flushNow(): FlushStats {\n this.cancelScheduledWork();\n return this.flush();\n }\n\n /** Apply the buffered value for an element that scrolled into view. */\n notifyVisible(element: Element): void {\n const entry = this.replay.get(element);\n if (!entry) return;\n this.replay.delete(element);\n if (!this.isCurrent(entry)) return;\n const t0 = performance.now();\n const applied = this.didApply(entry) ? 1 : 0;\n this.onFlush?.(\n this.statsFor(\n entry,\n applied,\n 0,\n performance.now() - t0,\n applied === 1 ? [entry.target.fieldName] : [],\n ),\n );\n }\n\n /**\n * Point buffered work at a rebuilt cache entry for the same element and\n * field. A different field or locale is a different binding: drop the work.\n */\n retarget(target: CachedElement): void {\n this.retargetBuffer(this.pending, target);\n this.retargetBuffer(this.replay, target);\n for (const flush of this.activeFlushes) this.retargetBuffer(flush, target);\n }\n\n forget(element: Element): void {\n this.pending.delete(element);\n this.replay.delete(element);\n for (const flush of this.activeFlushes) flush.delete(element);\n }\n\n /** Cancel timers and drop buffered state without draining it. */\n destroy(): void {\n if (this.destroying) return;\n // Host cancellation must not open another frame while this owner closes.\n this.destroying = true;\n try {\n this.clearWork();\n this.activeRevision = null;\n this.activeRevisionCancelled = false;\n // A restarted scheduler is a quiet page again, not the tail of a burst.\n this.windowUntil = 0;\n this.cancelScheduledWork();\n } finally {\n this.destroying = false;\n }\n }\n\n get pendingCount(): number {\n return this.pending.size;\n }\n\n get replayCount(): number {\n return this.replay.size;\n }\n\n get gateThreshold(): number {\n return this.gateThresholdValue;\n }\n\n get gateActive(): boolean {\n return !this.gateDisabled && this.getCacheSize() > this.gateThresholdValue;\n }\n\n private armDebounce(): void {\n const now = Date.now();\n const opensTheWindow = now >= this.windowUntil;\n this.windowUntil = now + this.debounceMs;\n // The debounce coalesces a burst, and the write that opens one is not yet a\n // burst: it costs a frame, and the window it opens batches what follows.\n // With the merge gone from the common path (see `MergeNeed`), that frame is\n // the whole distance between a keystroke and the page.\n if (opensTheWindow) {\n this.requestFrame();\n return;\n }\n const token = (this.debounceToken += 1);\n const timer = this.debounceTimer;\n this.debounceTimer = null;\n if (timer !== null) clearTimeout(timer);\n // clearTimeout is a host boundary; a reentrant schedule owns a newer token.\n if (this.debounceToken !== token) return;\n const next = setTimeout(() => {\n if (this.debounceToken !== token) return;\n this.debounceTimer = null;\n // The window a leading write opened is usually already empty when it\n // closes; flushing then would report a write nobody made.\n if (this.pending.size > 0) this.requestFrame();\n }, this.debounceMs);\n if (this.debounceToken === token) this.debounceTimer = next;\n // Continuous scheduling (key repeat) must not postpone the flush forever.\n if (this.deadlineTimer === null && this.maxWaitMs > this.debounceMs) {\n this.deadlineTimer = setTimeout(() => {\n this.deadlineTimer = null;\n if (this.pending.size > 0) this.requestFrame();\n }, this.maxWaitMs);\n }\n }\n\n private requestFrame(): void {\n const token = (this.frameToken += 1);\n const handle = this.frameHandle;\n this.frameHandle = null;\n this.clearFrameFallback();\n if (handle !== null) this.cancelFrame(handle);\n if (this.frameToken !== token) return;\n let completed = false;\n // The frame or the fallback, whichever comes first, writes; the other finds the token spent.\n const run = (): void => {\n if (this.frameToken !== token || completed) return;\n completed = true;\n const frame = this.frameHandle;\n this.frameHandle = null;\n this.clearFrameFallback();\n if (frame !== null) this.cancelFrame(frame);\n this.flush();\n };\n const next = this.scheduleFrame(run);\n // An injected scheduler may run the callback synchronously; never publish a spent handle.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (completed || this.frameToken !== token) return;\n this.frameHandle = next;\n this.frameFallback = setTimeout(run, FRAME_FALLBACK_MS);\n }\n\n private clearFrameFallback(): void {\n // clearTimeout ignores undefined, so a null guard here would be a branch without a behaviour.\n clearTimeout(this.frameFallback ?? undefined);\n this.frameFallback = null;\n }\n\n private flush(): FlushStats {\n const t0 = performance.now();\n this.clearDeadline();\n const gateActive = this.gateActive;\n const pending = this.pending;\n this.pending = new Map();\n let applied = 0;\n const appliedFields: string[] = [];\n let deferred = 0;\n let batchEntry: BufferEntry | undefined;\n this.activeFlushes.add(pending);\n try {\n for (const entry of pending.values()) {\n if (!this.isCurrent(entry)) continue;\n const visible =\n !gateActive || this.isVisible(entry.target.element) || nothingToScrollTo(entry.target);\n // The visibility callback is consumer code and may change the revision.\n if (!this.isCurrent(entry)) continue;\n batchEntry ??= entry;\n if (!visible) {\n this.replay.set(entry.target.element, entry);\n deferred += 1;\n continue;\n }\n this.replay.delete(entry.target.element);\n if (this.didApply(entry)) {\n applied += 1;\n appliedFields.push(entry.target.fieldName);\n }\n }\n } finally {\n this.activeFlushes.delete(pending);\n }\n const stats = this.statsFor(\n batchEntry,\n applied,\n deferred,\n performance.now() - t0,\n appliedFields,\n );\n this.onFlush?.(stats);\n return stats;\n }\n\n private isCurrent(entry: BufferEntry): boolean {\n return (\n entry.revision === undefined ||\n (!this.activeRevisionCancelled &&\n this.activeRevision !== null &&\n sameRevision(entry.revision, this.activeRevision))\n );\n }\n\n private didApply(entry: BufferEntry): boolean {\n // Only a runtime-marked callback may report exact `false` as \"no write\".\n // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n const outcome: unknown = this.apply(entry);\n return outcome !== false || !usesNoWriteOutcome(this.apply);\n }\n\n private retargetBuffer(buffer: Map<Element, BufferEntry>, target: CachedElement): void {\n const entry = buffer.get(target.element);\n if (entry === undefined) return;\n if (!hasSameBindingIdentity(entry.target, target)) {\n buffer.delete(target.element);\n return;\n }\n entry.target = target;\n }\n\n private clearWork(): void {\n this.pending.clear();\n this.replay.clear();\n for (const flush of this.activeFlushes) flush.clear();\n }\n\n private statsFor(\n entry: BufferEntry | undefined,\n applied: number,\n deferred: number,\n durationMs: number,\n appliedFields: readonly string[],\n ): FlushStats {\n return {\n applied,\n appliedFields,\n deferred,\n durationMs,\n ...(entry?.revision !== undefined ? { revision: entry.revision } : {}),\n ...(entry?.data !== undefined ? { data: entry.data } : {}),\n };\n }\n\n private clearDeadline(): void {\n if (this.deadlineTimer === null) return;\n clearTimeout(this.deadlineTimer);\n this.deadlineTimer = null;\n }\n\n private cancelScheduledWork(): void {\n const debounceTimer = this.debounceTimer;\n const frameHandle = this.frameHandle;\n // Revoke tokens before calling host cancellation, so a hook that\n // schedules newer work is not clobbered by this older cleanup.\n this.debounceToken += 1;\n this.frameToken += 1;\n this.debounceTimer = null;\n this.frameHandle = null;\n this.clearDeadline();\n this.clearFrameFallback();\n if (debounceTimer !== null) clearTimeout(debounceTimer);\n if (frameHandle !== null) this.cancelFrame(frameHandle);\n }\n}\n\n/**\n * An empty-field anchor that is hidden, or has no size, never scrolls into\n * view: the gate would hold the one write that can show it for good. Asked\n * after the visibility callback, so only of an anchor not seen yet.\n */\nfunction nothingToScrollTo(target: CachedElement): boolean {\n if (target.hidesWhenEmpty !== true) return false;\n const { element } = target;\n if (element.hasAttribute('hidden')) return true;\n const box = element.getBoundingClientRect();\n return box.width === 0 || box.height === 0;\n}\n\nfunction compareRevision(a: MessageRevision, b: MessageRevision): number {\n if (a.generation !== b.generation) return a.generation - b.generation;\n return a.revision - b.revision;\n}\n","/**\n * `LivePreviewRuntime` owns the primitives and hands accepted messages to the update pipeline.\n * It never speaks postMessage or walks the DOM during an update. See ADR 0004.\n */\n\nimport { createA11y, defaultSendReady } from './runtime-wiring';\nimport { BindingWriter } from './binding-writer';\nimport { ElementCache, hasSameBindingIdentity } from './cache';\nimport { DataMerger } from './data-merger';\nimport type { DiagnosticCode } from './diagnostic-codes';\nimport { isolateDiagnostic, noopDiagnostic, safeConsoleWarn } from './diagnostics';\nimport { resolveUnfaithfulPatchMode } from './fidelity';\nimport { buildInspection } from './inspection/snapshot';\nimport type { LivePreviewInspection } from './inspection/types';\nimport { markNoWriteCallback } from './internal-outcome';\nimport { isInsideIsland } from './islands';\nimport { MessageBus } from './message-bus';\nimport { ObserverManager } from './observers';\nimport { LifetimeScope } from './lifetime-scope';\nimport type { ProtocolNegotiation } from './protocol-version';\nimport type { RuntimeOptions } from './runtime-options';\nimport { RuntimeState, type RuntimeDeps } from './runtime-state';\nimport { isDocumentRoot, readDocumentBody, startWhenReady, type StartupHost } from './startup';\nimport { ConnectionState, HeartbeatTimer } from './state';\nimport type { CachedElement } from './types';\nimport { UpdatePipeline } from './update-pipeline';\nimport { DEFAULT_DEBOUNCE_MS, UpdateScheduler } from './update-scheduler';\n\nexport type { RuntimeOptions } from './runtime-options';\nexport { resolveFieldValue } from './field-value';\n\n/** Re-broadcast `ready` a few times to absorb admin-side init latency. */\nconst READY_RETRY_DELAYS_MS = [0, 500, 1000, 2000] as const;\n\nexport class LivePreviewRuntime {\n private readonly deps: RuntimeDeps;\n private readonly state = new RuntimeState();\n private readonly pipeline: UpdatePipeline;\n private readonly writer: BindingWriter;\n private rootSentinel: MutationObserver | null = null;\n /** The session's resources, released together in reverse order when it ends (ADR 0005, 2.1 note). */\n private scope: LifetimeScope | null = null;\n /** Prevent a cleanup callback from opening a session inside the one being torn down. */\n private closingSession = false;\n private observedRoot: Node | null = null;\n private replayRetainedOnStart = false;\n\n constructor(options: RuntimeOptions) {\n const { emitter, renderers } = options;\n const log = options.log === undefined ? noopDiagnostic : isolateDiagnostic(options.log);\n const warn = options.warn === undefined ? safeConsoleWarn : isolateDiagnostic(options.warn);\n const root = options.root ?? (typeof document !== 'undefined' ? document : undefined);\n // Name the missing option here instead of failing at the first DOM read in start().\n if (root === undefined) throw new Error('LivePreviewRuntime: no document; pass options.root');\n // Bindings inside a hydrated island are the island's business (ADR 0008 §4).\n const cache = new ElementCache({ filter: (element) => !isInsideIsland(element) });\n const observers = new ObserverManager(\n {\n onStructuralChange: () => {\n this.rebuildCache();\n },\n onIslandHydrated: (island) => {\n this.pipeline.reapplyNavigationIslands([island], true);\n },\n onVisibilityChange: (element, visible) => {\n if (visible) scheduler.notifyVisible(element);\n },\n },\n options.intersectionRootMargin !== undefined\n ? { intersectionRootMargin: options.intersectionRootMargin }\n : {},\n );\n const scheduler = new UpdateScheduler(\n markNoWriteCallback((update) => this.writer.apply(update)),\n {\n ...(options.debounceMs !== undefined ? { debounceMs: options.debounceMs } : {}),\n ...(options.disableVisibilityGate !== undefined\n ? { disableVisibilityGate: options.disableVisibilityGate }\n : {}),\n ...(options.visibilityGateThreshold !== undefined\n ? { visibilityGateThreshold: options.visibilityGateThreshold }\n : {}),\n isVisible: (element) => observers.isVisible(element),\n getCacheSize: () => cache.elementCount,\n onFlush: (stats) => {\n this.pipeline.onFlush(stats);\n },\n },\n );\n const bus = new MessageBus(options.originMatcher, {\n onUpdate: (message, origin, revision) => {\n this.pipeline.handleUpdate(message, origin, revision);\n },\n onReplay: (message, origin, revision) => {\n this.pipeline.handleReplay(message, origin, revision);\n },\n onDocumentEvent: () => {\n this.state.protocol.observe(['document-events'], log, warn);\n void emitter.emit('documentSave', { timestamp: Date.now() });\n this.pipeline.documentSaved();\n },\n onFocusField: (field) => {\n if (this.deps.revealEditedField) this.pipeline.revealField(field);\n },\n onInvalid: (reason, origin) => {\n if (reason === 'token') {\n const error = new Error(`Preview token rejected (origin: ${origin})`);\n void emitter.emit('error', { error, context: 'token', code: 'LP0502' });\n }\n // An unknown shape from a trusted origin is protocol drift, not an attack.\n // Report it here once: without `debug`, no other boundary makes it visible.\n if ((reason === 'shape' || reason === 'type') && !this.state.warnedProtocolShape) {\n this.state.warnedProtocolShape = true;\n warn(\n `[live-preview] LP0503: ${origin} posted a message this runtime does not recognise ` +\n `(${reason === 'type' ? 'unknown message type' : 'unexpected shape'}); it was ` +\n 'ignored. A newer Payload or a custom sender: check that the versions match.',\n );\n }\n // This refusal default changed in 2.0. An admin posting from outside the\n // framing or opening window silently stops updates, so report it once.\n if (reason === 'source' && !this.state.warnedForeignSource) {\n this.state.warnedForeignSource = true;\n warn(\n `[live-preview] LP0501: a message from ${origin} was ignored because it did not come ` +\n 'from the window that framed or opened this page. `eventSourcePolicy` is ' +\n \"'parent-or-opener' by default since 2.0, where 1.x accepted any window on a \" +\n \"trusted origin. Set `eventSourcePolicy: 'any'` if the admin posts from elsewhere.\",\n );\n }\n log('LP0501 message rejected:', reason, origin);\n },\n ...(options.validateToken !== undefined ? { validateToken: options.validateToken } : {}),\n ...(options.eventSourcePolicy !== undefined\n ? { sourcePolicy: options.eventSourcePolicy }\n : {}),\n });\n const merge = options.dataMerge;\n this.deps = {\n emitter,\n cache,\n observers,\n scheduler,\n bus,\n connection: new ConnectionState(),\n heartbeat: new HeartbeatTimer({\n ...(options.heartbeatMs !== undefined ? { timeoutMs: options.heartbeatMs } : {}),\n onTimeout: () => {\n this.onHeartbeatTimeout();\n },\n }),\n renderers,\n resolveRenderer: options.resolveRenderer ?? ((fieldType) => renderers[fieldType]),\n transformValue: options.transformValue,\n renderRichText: options.renderRichText,\n internalLinkPattern: options.internalLinkPattern,\n routeAfterSave: options.routeAfterSave === true,\n sanitizerPolicy: options.sanitizerPolicy,\n root,\n readyTargets:\n typeof options.readyTargets === 'function'\n ? options.readyTargets\n : (\n (targets) => (): readonly string[] =>\n targets\n )(options.readyTargets),\n sendReady: options.sendReady ?? defaultSendReady,\n onHeartbeatTimeout: options.onHeartbeatTimeout,\n log,\n warn,\n a11y: createA11y(options),\n serverURL: merge?.serverURL,\n merger: merge === undefined ? null : new DataMerger({ ...merge, log }),\n mergeWindowMs: options.debounceMs ?? DEFAULT_DEBOUNCE_MS,\n scopeBindingsByOwner: options.scopeBindingsByOwner === true,\n subfieldCoverage: options.subfieldCoverage ?? 'descendant',\n coverageByDefault: options.subfieldCoverage === undefined,\n lockedOrigin: options.lockedOrigin ?? ((): undefined => undefined),\n skipUnchanged: options.skipUnchanged === true,\n dependencies: options.dependencies ?? {},\n strategies: options.strategies ?? {},\n revealEditedField: options.revealEditedField === true,\n onUnfaithfulPatch: resolveUnfaithfulPatchMode(options),\n autoBind: options.autoBind ?? 'off',\n hydration: options.hydration,\n };\n this.writer = new BindingWriter(this.deps, this.state);\n this.pipeline = new UpdatePipeline(this.deps, this.state, () => {\n this.rebuildCache();\n });\n }\n\n /**\n * Build the cache, attach observers and listeners, broadcast `ready`.\n * Returns `false` when already started. While the document is still\n * parsing the real start waits for `DOMContentLoaded`; on a page that\n * declares hydration it then waits for React's first commit as well\n * (ADR 0015), so the first write lands on markup React keeps.\n */\n start(): boolean {\n const { state } = this;\n if (state.isRunning() || this.closingSession) return false;\n if (state.suspended) this.replayRetainedOnStart = true;\n state.started = true;\n state.suspended = false;\n this.openScope();\n try {\n startWhenReady(this.startupHost());\n return true;\n } catch (error) {\n this.rollbackFailedStart();\n throw error;\n }\n }\n\n /** The runtime as the startup chain sees it (./startup). */\n private startupHost(): StartupHost {\n const { state, deps } = this;\n return {\n root: deps.root,\n hydration: deps.hydration,\n isRunning: () => state.isRunning(),\n defer: (cancel) => {\n state.deferredStart = cancel;\n this.scope?.own(() => {\n if (state.deferredStart !== cancel) return;\n state.deferredStart = null;\n cancel();\n });\n },\n later: (step) => {\n state.deferredStart = null;\n try {\n step();\n } catch (error) {\n // start() already returned; roll back and report through the error event.\n this.rollbackFailedStart();\n this.reportError(error, 'startup', 'LP0605');\n }\n },\n hydrated: (hydration) => {\n state.hydration = hydration;\n },\n warn: deps.warn,\n startNow: () => {\n this.startNow();\n },\n };\n }\n\n private startNow(): void {\n const { state, deps } = this;\n if (!state.isRunning()) return;\n const observerRoot: Node | null = isDocumentRoot(deps.root)\n ? readDocumentBody(deps.root)\n : deps.root;\n if (observerRoot === null) throw new Error('LivePreviewRuntime: document.body unavailable');\n deps.observers.start(observerRoot);\n this.observedRoot = observerRoot;\n this.watchRootReplacement();\n // Observers first: the cache scan registers its elements with them.\n this.buildCacheAndObserve();\n if (!state.isRunning()) return;\n deps.bus.attach();\n void deps.emitter.emitWhile('init', { timestamp: Date.now() }, () => state.isRunning());\n if (!state.isRunning()) return;\n const recoverSuspendedSession = this.replayRetainedOnStart;\n this.replayRetainedOnStart = false;\n const suspendedHeartbeatExpired = recoverSuspendedSession && deps.heartbeat.resume();\n if (!state.isRunning()) return;\n if (recoverSuspendedSession && !suspendedHeartbeatExpired) {\n state.forgetOwedWork();\n state.merges.resetRawChanges();\n state.unfaithfulPatches = [];\n state.revealer.reset();\n state.lastAppliedIdentity = new WeakMap();\n state.changes.reset();\n state.navigationReplayPending = true;\n if (!deps.bus.replayLastAccepted()) state.navigationReplayPending = false;\n if (!state.isRunning()) return;\n }\n for (const delay of READY_RETRY_DELAYS_MS) {\n if (!state.isRunning()) return;\n if (delay === 0) {\n deps.sendReady(deps.readyTargets());\n } else {\n state.readyTimers.push(\n setTimeout(() => {\n if (state.isRunning()) this.sendReadyAfterStart();\n }, delay),\n );\n }\n }\n }\n\n /**\n * Release the message ingress and observers but keep the configuration, so\n * `start()` brings the same instance back — what a back/forward-cache\n * restore needs, since it re-runs no scripts.\n */\n suspend(): boolean {\n if (!this.state.isRunning()) return false;\n const wasConnected = this.release();\n this.state.suspended = true;\n if (wasConnected) {\n void this.deps.emitter.emit('disconnect', { reason: 'unload', timestamp: Date.now() });\n }\n return true;\n }\n\n destroy(): void {\n const { state, deps } = this;\n if (!state.isRunning() && !state.suspended) return;\n const wasConnected = state.isRunning() ? this.release() : false;\n state.suspended = false;\n this.replayRetainedOnStart = false;\n deps.bus.forgetLastAccepted();\n if (wasConnected) {\n void deps.emitter.emit('disconnect', { reason: 'destroy', timestamp: Date.now() });\n }\n deps.a11y?.detach();\n void deps.emitter.emit('destroy', { timestamp: Date.now() });\n }\n\n /** One scope per session: destroy, suspend and failed starts invalidate it and close in reverse. */\n private openScope(): void {\n const { state, deps } = this;\n const scope = new LifetimeScope(deps.log);\n scope.own(() => {\n deps.merger?.destroy();\n state.merges.destroy();\n });\n scope.own(() => {\n deps.scheduler.destroy();\n });\n scope.own(() => {\n deps.observers.stop();\n });\n scope.own(() => {\n this.rootSentinel?.disconnect();\n this.rootSentinel = null;\n this.observedRoot = null;\n });\n scope.own(() => {\n state.abortStrategies();\n });\n scope.own(() => {\n deps.bus.detach();\n });\n scope.own(() => {\n deps.heartbeat.stop();\n });\n scope.own(() => {\n for (const handle of state.readyTimers) clearTimeout(handle);\n state.readyTimers.length = 0;\n });\n this.scope = scope;\n }\n\n private release(): boolean {\n const { state, deps } = this;\n state.display.end();\n state.activeUpdate = null;\n state.navigationBindingReplay = false;\n state.started = false;\n const closingScope = this.scope;\n this.scope = null;\n this.closingSession = true;\n try {\n closingScope?.close();\n } finally {\n this.closingSession = false;\n }\n deps.cache.clear();\n return deps.connection.markDisconnected();\n }\n\n private rollbackFailedStart(): void {\n this.release();\n try {\n this.deps.a11y?.detach();\n } catch (error) {\n this.deps.log('runtime cleanup failed:', error);\n }\n }\n\n /** Re-scan the DOM and re-register every binding. */\n refreshCache(): void {\n if (!this.state.isRunning()) return;\n this.state.revealer.reset();\n if (!this.followReplacedRoot()) this.rebuildCache();\n }\n\n /**\n * Supersede work owned by the route being left, then rescan and locally\n * replay the last accepted snapshot. The ordinary public refresh keeps\n * buffered work; only a confirmed router commit crosses this boundary.\n * @internal\n */\n navigationCommit(): void {\n const { state, deps } = this;\n // Before startup owns the bus/cache, its parse/hydration wait scans and sends the handshake.\n if (!state.isRunning() || state.deferredStart !== null) return;\n // Finish destructive cleanup before opening the next ingress generation.\n // Abort/fetch listeners may synchronously post a newer document; the second\n // cancellation retains it instead of letting this older cleanup tear it down.\n this.cancelActiveUpdate(true);\n deps.merger?.destroy();\n state.merges.destroy();\n state.abortStrategies();\n this.cancelActiveUpdate(true);\n state.forgetOwedWork();\n state.merges.resetRawChanges();\n state.unfaithfulPatches = [];\n state.revealer.reset();\n // A retained element's previous value identity says nothing about the new route's DOM.\n state.lastAppliedIdentity = new WeakMap();\n state.changes.reset();\n if (!state.isRunning()) return;\n deps.bus.advanceGeneration();\n state.navigationReplayPending = true;\n if (!this.followReplacedRoot()) this.rebuildCache();\n if (!state.isRunning()) return;\n deps.bus.replayLastAccepted();\n if (state.isRunning()) this.sendReadyAfterStart();\n }\n\n /** Some routers swap `document.body` on navigation, leaving observers on a detached node. */\n private watchRootReplacement(): void {\n const { root } = this.deps;\n if (!isDocumentRoot(root) || typeof MutationObserver === 'undefined') return;\n this.rootSentinel?.disconnect();\n this.rootSentinel = new MutationObserver(() => {\n this.followReplacedRoot();\n });\n this.rootSentinel.observe(root.documentElement, { childList: true });\n }\n\n /** Rebind observers and cache to a replaced body; returns whether it did. */\n private followReplacedRoot(): boolean {\n const { root } = this.deps;\n if (!this.state.isRunning() || !isDocumentRoot(root)) return false;\n const body = readDocumentBody(root);\n if (body === null || body === this.observedRoot) return false;\n this.observedRoot = body;\n this.deps.observers.start(body);\n this.rebuildCache();\n return true;\n }\n\n get status(): 'disconnected' | 'connecting' | 'connected' {\n return this.deps.connection.status;\n }\n\n get cache(): ElementCache {\n return this.deps.cache;\n }\n\n get updateCount(): number {\n return this.state.updateCount;\n }\n\n /** Negotiated protocol view, `min(library, remote)`. */\n get protocol(): ProtocolNegotiation {\n return this.state.protocol.negotiation;\n }\n\n /** Point-in-time read of runtime state for diagnosing a preview that is not updating. */\n inspect(): LivePreviewInspection {\n return buildInspection(this.deps, this.state);\n }\n\n private buildCacheAndObserve(): void {\n const { state, deps } = this;\n if (!state.isRunning()) return;\n const stats = deps.cache.buildFromRoot(deps.root);\n deps.log('cache', stats);\n if (!state.isRunning()) return;\n void deps.emitter.emitWhile('cacheRefresh', stats, () => state.isRunning());\n if (!state.isRunning()) return;\n for (const entry of deps.cache.values()) {\n if (!state.isRunning()) return;\n deps.observers.observeElement(entry.element);\n }\n }\n\n private rebuildCache(): void {\n const { state, deps } = this;\n if (!state.isRunning()) return;\n const previous = new Map<Element, CachedElement>();\n const previousIslandOwners = deps.cache.islandOwners;\n const previousNavigationRoots = new Set(deps.cache.navigationReplayRoots);\n for (const entry of deps.cache.values()) {\n previous.set(entry.element, entry);\n deps.observers.unobserveElement(entry.element);\n }\n this.buildCacheAndObserve();\n if (!state.isRunning()) return;\n const added = new Set<Element>(\n deps.cache.navigationReplayRoots.filter((root) => !previousNavigationRoots.has(root)),\n );\n // Buffered work survives only while the same element is bound to the same field.\n for (const entry of deps.cache.values()) {\n const before = previous.get(entry.element);\n if (before !== undefined && hasSameBindingIdentity(before, entry)) {\n deps.scheduler.retarget(entry);\n } else {\n deps.scheduler.forget(entry.element);\n added.add(entry.element);\n }\n previous.delete(entry.element);\n }\n for (const removed of previous.values()) deps.scheduler.forget(removed.element);\n if (added.size > 0) this.pipeline.reapplyNavigationBindings(added);\n const addedIslands = deps.cache.islands.filter(\n (island) =>\n !previousIslandOwners.has(island) ||\n (deps.scopeBindingsByOwner &&\n previousIslandOwners.get(island) !== deps.cache.islandOwners.get(island)),\n );\n if (addedIslands.length > 0) this.pipeline.reapplyNavigationIslands(addedIslands);\n }\n\n private onHeartbeatTimeout(): void {\n const { state, deps } = this;\n if (!state.isRunning()) return;\n // Cleanup belongs to the expiring generation; a synchronous abort listener cannot\n // reconnect into the generation this same cleanup is about to destroy.\n this.cancelActiveUpdate(false);\n deps.merger?.destroy();\n state.merges.destroy();\n state.abortStrategies();\n this.cancelActiveUpdate(false);\n if (!state.isRunning()) return;\n deps.bus.advanceGeneration();\n deps.bus.forgetLastAccepted();\n state.navigationBindingReplay = false;\n const wasConnected = deps.connection.markDisconnected();\n // Release the origin lock before the disconnect event: a listener may\n // reconnect from another allow-listed origin synchronously.\n try {\n deps.onHeartbeatTimeout?.();\n } catch (error) {\n deps.log('heartbeat:', error);\n }\n if (!state.isRunning()) return;\n if (wasConnected && this.isIdleDisconnected()) {\n deps.a11y?.announceDisconnected();\n void deps.emitter.emitWhile('disconnect', { reason: 'timeout', timestamp: Date.now() }, () =>\n this.isIdleDisconnected(),\n );\n if (!state.isRunning()) return;\n if (this.isIdleDisconnected()) deps.log('connection', 'connected', '→', 'disconnected');\n if (!state.isRunning()) return;\n }\n this.sendReadyAfterStart();\n }\n\n /** Cancel whichever revision owns work now; cleanup callbacks may install a newer one. */\n private cancelActiveUpdate(countSuperseded: boolean): void {\n const { state, deps } = this;\n const active = state.activeUpdate;\n state.display.end();\n state.activeUpdate = null;\n if (active === null) return;\n active.cancelled = true;\n deps.scheduler.cancelRevision(active.revision);\n if (countSuperseded && !active.completed && active.countsAsUpdate) {\n state.supersededCount += 1;\n }\n }\n\n /** Later handshake retries are best-effort and must not escape timer callbacks. */\n private sendReadyAfterStart(): void {\n try {\n this.deps.sendReady(this.deps.readyTargets());\n } catch (error) {\n this.reportError(error, 'ready', 'LP0606');\n }\n }\n\n private reportError(cause: unknown, context: string, code: DiagnosticCode): void {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n void this.deps.emitter.emit('error', { error, context, code });\n }\n\n private isIdleDisconnected(): boolean {\n return (\n this.state.isRunning() &&\n this.deps.connection.status === 'disconnected' &&\n this.state.activeUpdate === null\n );\n }\n}\n","/** Assembles the `inspect()` snapshot. Reads state only; sends nothing anywhere. */\n\nimport { VERSION } from '../../version';\nimport { detectProtocolProfile } from '../protocol-profile';\nimport type { RuntimeDeps, RuntimeState } from '../runtime-state';\nimport type { LivePreviewInspection } from './types';\n\nexport function buildInspection(deps: RuntimeDeps, state: RuntimeState): LivePreviewInspection {\n const { cache, scheduler } = deps;\n const negotiation = state.protocol.negotiation;\n const active = state.activeUpdate;\n const flush = state.lastFlush;\n const fieldNames: string[] = [];\n const owners = new Set<string>();\n const guessed: { field: string; matched: string; attribute: string | undefined }[] = [];\n for (const [fieldName, bindings] of cache.entries()) {\n fieldNames.push(fieldName);\n for (const binding of bindings) {\n if (binding.owner !== undefined) owners.add(binding.owner);\n if (binding.guessed !== undefined) {\n guessed.push({\n field: fieldName,\n matched: binding.guessed,\n attribute:\n binding.targetAttribute ?? (binding.element.tagName === 'IMG' ? 'src' : undefined),\n });\n }\n }\n }\n return {\n version: VERSION,\n started: state.started,\n status: deps.connection.status,\n origins: { trusted: [...deps.readyTargets()], locked: deps.lockedOrigin() },\n protocol: {\n ours: negotiation.ours,\n theirs: negotiation.theirs,\n negotiated: negotiation.negotiated,\n capabilities: [...negotiation.capabilities].sort(),\n observed: [...negotiation.observed].sort(),\n profile: detectProtocolProfile(negotiation.observed).name,\n },\n revisions: {\n accepted: state.updateCount,\n superseded: state.supersededCount,\n completed: state.completedCount,\n skippedUnchanged: state.skippedUnchangedCount,\n active: active === null ? undefined : active.revision.revision,\n display: state.display.snapshot(),\n },\n bindings: {\n elements: cache.elementCount,\n fields: cache.fieldCount,\n fieldNames: fieldNames.sort(),\n absentFields: [...state.absentFields].sort(),\n orphanFields: [...state.warnedOrphanFields].sort(),\n ownerScoped: deps.scopeBindingsByOwner,\n owners: [...owners].sort(),\n guessed: guessed.sort((left, right) => left.field.localeCompare(right.field)),\n autoBind: { mode: deps.autoBind, searchMs: state.autoBindSearchMs },\n },\n route: { handler: deps.strategies.route !== undefined, ...state.routeStats },\n fidelity: {\n mode: deps.onUnfaithfulPatch,\n canEscalate: deps.strategies.fragment !== undefined || deps.strategies.route !== undefined,\n unfaithful: state.unfaithfulCount,\n escalated: state.escalatedCount,\n fields: [...state.unfaithfulFields].sort(),\n },\n hydration: { mode: deps.hydration ?? 'off', state: state.hydration },\n fragments: {\n handler: deps.strategies.fragment !== undefined,\n inFlight: active?.pendingFragments ?? 0,\n ...state.fragmentStats,\n },\n scheduler: {\n pending: scheduler.pendingCount,\n deferred: scheduler.replayCount,\n visibilityGateThreshold: scheduler.gateThreshold,\n visibilityGateActive: scheduler.gateActive,\n lastFlush:\n flush === null\n ? undefined\n : {\n applied: flush.applied,\n appliedFields: flush.appliedFields,\n deferred: flush.deferred,\n durationMs: flush.durationMs,\n },\n },\n plugins: [],\n renderers: Object.keys(deps.renderers).sort(),\n };\n}\n","/**\n * Per-instance typed emitter: handlers run sequentially in registration order,\n * may be async, and a throwing one is logged and isolated. See ADR 0002.\n */\n\nimport type { EventHandler, LivePreviewEventMap, Unsubscribe } from './types';\nimport { safeConsoleError } from '@core/diagnostics';\n\ntype AnyHandler = EventHandler<unknown>;\n\n// `object`, not `Record<string, unknown>`: interfaces with readonly and\n// exact-optional properties must be usable as maps.\nexport class EventEmitter<TMap extends object = LivePreviewEventMap> {\n readonly #regular = new Map<keyof TMap, Set<AnyHandler>>();\n readonly #once = new Map<keyof TMap, Set<AnyHandler>>();\n\n on<E extends keyof TMap>(event: E, handler: EventHandler<TMap[E]>): Unsubscribe {\n return this.#register(this.#regular, event, handler as AnyHandler);\n }\n\n once<E extends keyof TMap>(event: E, handler: EventHandler<TMap[E]>): Unsubscribe {\n return this.#register(this.#once, event, handler as AnyHandler);\n }\n\n off<E extends keyof TMap>(event: E, handler: EventHandler<TMap[E]>): void {\n this.#remove(this.#regular, event, handler as AnyHandler);\n this.#remove(this.#once, event, handler as AnyHandler);\n }\n\n /** Dispatch to every handler: regular ones first, then `once` handlers. */\n async emit<E extends keyof TMap>(event: E, payload: TMap[E]): Promise<void> {\n await this.#emitSequential(event, payload);\n }\n\n /**\n * Dispatch while `shouldContinue()` holds — checked around every handler, so\n * an obsolete transaction cannot resume across an await.\n * @internal\n */\n async emitWhile<E extends keyof TMap>(\n event: E,\n payload: TMap[E],\n shouldContinue: () => boolean,\n ): Promise<boolean> {\n return this.#emitSequential(event, payload, shouldContinue);\n }\n\n async #emitSequential<E extends keyof TMap>(\n event: E,\n payload: TMap[E],\n shouldContinue?: () => boolean,\n ): Promise<boolean> {\n const eligible = (): boolean => shouldContinue?.() ?? true;\n if (!eligible()) return false;\n const regular = this.#regular.get(event);\n if (regular) {\n for (const handler of [...regular]) {\n if (!eligible()) return false;\n await this.#invoke(handler, payload, event);\n if (!eligible()) return false;\n }\n }\n if (!eligible()) return false;\n const once = this.#once.get(event);\n if (once && once.size > 0) {\n const snapshot = [...once];\n this.#once.delete(event);\n for (const handler of snapshot) {\n if (!eligible()) return false;\n await this.#invoke(handler, payload, event);\n if (!eligible()) return false;\n }\n }\n return eligible();\n }\n\n /** Registered handlers for `event`, `on` and `once` together. */\n listenerCount(event: keyof TMap): number {\n return (this.#regular.get(event)?.size ?? 0) + (this.#once.get(event)?.size ?? 0);\n }\n\n /** Remove every handler, or only those of `event`. */\n removeAllListeners(event?: keyof TMap): void {\n if (event === undefined) {\n this.#regular.clear();\n this.#once.clear();\n return;\n }\n this.#regular.delete(event);\n this.#once.delete(event);\n }\n\n /** Event names with at least one handler. */\n eventNames(): (keyof TMap)[] {\n const names = new Set<keyof TMap>();\n for (const key of this.#regular.keys()) names.add(key);\n for (const key of this.#once.keys()) names.add(key);\n return [...names];\n }\n\n #register(\n bucket: Map<keyof TMap, Set<AnyHandler>>,\n event: keyof TMap,\n handler: AnyHandler,\n ): Unsubscribe {\n let set = bucket.get(event);\n if (!set) {\n set = new Set();\n bucket.set(event, set);\n }\n set.add(handler);\n return () => {\n this.#remove(bucket, event, handler);\n };\n }\n\n #remove(bucket: Map<keyof TMap, Set<AnyHandler>>, event: keyof TMap, handler: AnyHandler): void {\n const set = bucket.get(event);\n if (set === undefined) return;\n set.delete(handler);\n if (set.size === 0) bucket.delete(event);\n }\n\n async #invoke(handler: AnyHandler, payload: unknown, event: keyof TMap): Promise<void> {\n try {\n await handler(payload);\n } catch (err) {\n const label =\n typeof event === 'string' || typeof event === 'number' ? String(event) : '<event>';\n safeConsoleError(`[live-preview] LP0601: handler for \"${label}\" threw:`, err);\n }\n }\n}\n","/**\n * Which admin origins the runtime trusts: explicit ones always, the\n * `document.referrer` origin only when none is configured, any localhost port\n * in development. See docs/security.md §1. The handshake goes to the trusted\n * origins, and to guessed localhost ports only while the browser names no parent.\n */\n\nimport { isDevMode, isInIframe } from './environment';\n\nconst LOCALHOST_PATTERN = /^https?:\\/\\/(localhost|127\\.0\\.0\\.1)(?::\\d+)?$/i;\nconst VALID_ORIGIN_PATTERN = /^https?:\\/\\/[^/?#\\s]+$/i;\n\n/** Ports the handshake broadcasts to when the localhost pattern is on; matching itself is unrestricted. */\nconst LOCALHOST_HANDSHAKE_PORTS: readonly number[] = [\n 3000, 3001, 3333, 4000, 4321, 5000, 5173, 5174, 8000, 8080, 8888, 9000,\n];\n\nexport interface OriginDetectorOptions {\n /** Explicit origins to trust. Always allowed. */\n readonly additionalOrigins?: readonly string[];\n /** Set to `false` to ignore `document.referrer`. */\n readonly enableReferrerDetection?: boolean;\n /** Set to `false` to ignore the localhost pattern even in development. */\n readonly enableLocalhostMatching?: boolean;\n /** Override dev-mode detection. */\n readonly forceDevMode?: boolean;\n /** Override `document.referrer` for tests. */\n readonly referrer?: string;\n}\n\nconst enum OriginSlot {\n ExplicitOrigins,\n ReferrerOrigin,\n AllowLocalhost,\n ReferrerWasAvailable,\n LockedOrigin,\n ParentOrigin,\n}\n\ntype OriginState = [\n explicitOrigins: ReadonlySet<string>,\n referrerOrigin: string | undefined,\n allowLocalhost: boolean,\n referrerWasAvailable: boolean,\n lockedOrigin: string | undefined,\n parentOrigin: string | undefined,\n];\n\n/**\n * The framing parent's origin, where the browser names it: Chromium and WebKit\n * do (`location.ancestorOrigins`), Firefox does not. Never a trust source, only\n * where the handshake is worth sending.\n */\nfunction readParentOrigin(): string | undefined {\n if (typeof location === 'undefined') return undefined;\n const ancestors = (location as { readonly ancestorOrigins?: ArrayLike<string> }).ancestorOrigins;\n return ancestors?.[0];\n}\n\n/** The trusted-origin policy: the union of the candidate sources, narrowed to one by `lockOrigin()`. */\nexport class OriginDetector {\n readonly #state: OriginState;\n\n constructor(options: OriginDetectorOptions = {}) {\n const explicit = new Set<string>();\n for (const origin of options.additionalOrigins ?? []) {\n const normalised = normaliseOrigin(origin);\n if (normalised !== undefined) explicit.add(normalised);\n }\n let referrerOrigin: string | undefined;\n if (options.enableReferrerDetection ?? true) {\n const referrer =\n options.referrer ?? (typeof document !== 'undefined' ? document.referrer : '');\n if (referrer.length > 0) {\n try {\n const origin = new URL(referrer).origin;\n if (origin && origin !== 'null') referrerOrigin = origin;\n } catch {\n // opaque referrer\n }\n }\n }\n const allowLocalhost =\n (options.enableLocalhostMatching ?? true) && (options.forceDevMode ?? isDevMode());\n this.#state = [\n explicit,\n referrerOrigin,\n allowLocalhost,\n referrerOrigin !== undefined,\n undefined,\n readParentOrigin(),\n ];\n }\n\n /** Whether `origin` is trusted: the locked origin alone once locked, otherwise the policy above. */\n matches(origin: string): boolean {\n if (origin.length === 0 || origin === 'null') return false;\n if (this.#state[OriginSlot.LockedOrigin] !== undefined) {\n return origin === this.#state[OriginSlot.LockedOrigin];\n }\n if (this.#state[OriginSlot.ExplicitOrigins].has(origin)) return true;\n // The referrer is a fallback, not a union member: any embedder lands there.\n if (\n this.#state[OriginSlot.ExplicitOrigins].size === 0 &&\n this.#state[OriginSlot.ReferrerOrigin] !== undefined &&\n origin === this.#state[OriginSlot.ReferrerOrigin]\n ) {\n return true;\n }\n if (this.#state[OriginSlot.AllowLocalhost] && LOCALHOST_PATTERN.test(origin)) return true;\n return false;\n }\n\n /** Narrow trust to `origin`; refused (`false`) when it is not currently trusted. */\n lockOrigin(origin: string): boolean {\n if (!this.matches(origin)) return false;\n this.#state[OriginSlot.LockedOrigin] = origin;\n return true;\n }\n\n /** Release the lock (heartbeat timeout) so another allow-listed origin may reconnect. Returns the previous lock. */\n unlockOrigin(): string | undefined {\n const previous = this.#state[OriginSlot.LockedOrigin];\n this.#state[OriginSlot.LockedOrigin] = undefined;\n return previous;\n }\n\n get lockedOrigin(): string | undefined {\n return this.#state[OriginSlot.LockedOrigin];\n }\n\n /**\n * Every origin the `ready` handshake is broadcast to. The localhost pattern\n * expands to the common dev ports, a guess that costs a console error per\n * wrong port, so a parent the browser names replaces it: that origin when the\n * pattern trusts it, none when it is not on localhost.\n */\n enumerate(): string[] {\n if (this.#state[OriginSlot.LockedOrigin] !== undefined) {\n return [this.#state[OriginSlot.LockedOrigin]];\n }\n const result = new Set<string>(this.#state[OriginSlot.ExplicitOrigins]);\n if (\n this.#state[OriginSlot.ExplicitOrigins].size === 0 &&\n this.#state[OriginSlot.ReferrerOrigin] !== undefined\n ) {\n result.add(this.#state[OriginSlot.ReferrerOrigin]);\n }\n const parent = this.#state[OriginSlot.ParentOrigin];\n if (this.#state[OriginSlot.AllowLocalhost] && parent !== undefined) {\n if (LOCALHOST_PATTERN.test(parent)) result.add(parent);\n } else if (this.#state[OriginSlot.AllowLocalhost]) {\n for (const port of LOCALHOST_HANDSHAKE_PORTS) {\n result.add(`http://localhost:${String(port)}`);\n result.add(`http://127.0.0.1:${String(port)}`);\n }\n }\n return [...result];\n }\n\n /** Whether `document.referrer` contributed an origin (absent under `Referrer-Policy: no-referrer`). */\n get referrerWasAvailable(): boolean {\n return this.#state[OriginSlot.ReferrerWasAvailable];\n }\n\n /** Framed, outside development, with no trusted origin at all: the host should warn (LP0101). */\n get isProductionUnconfigured(): boolean {\n if (!isInIframe()) return false;\n if (this.#state[OriginSlot.ExplicitOrigins].size > 0) return false;\n if (this.#state[OriginSlot.AllowLocalhost]) return false;\n if (this.#state[OriginSlot.ReferrerOrigin] !== undefined) return false;\n return true;\n }\n\n /** The referrer is the only trust source, so any framing site may drive the preview (LP0102). */\n get isReferrerOnlyTrust(): boolean {\n if (this.#state[OriginSlot.ExplicitOrigins].size > 0) return false;\n if (this.#state[OriginSlot.AllowLocalhost]) return false;\n return this.#state[OriginSlot.ReferrerOrigin] !== undefined;\n }\n}\n\n/** The canonical `http(s)://host[:port]` form of `value`, or `undefined` when it is not one. */\nexport function normaliseOrigin(value: string): string | undefined {\n const trimmed = value.trim();\n if (trimmed.length === 0) return undefined;\n try {\n const url = new URL(trimmed);\n if (url.protocol !== 'http:' && url.protocol !== 'https:') return undefined;\n if (!VALID_ORIGIN_PATTERN.test(url.origin)) return undefined;\n return url.origin;\n } catch {\n return undefined;\n }\n}\n","/**\n * Registration-local resource scope: every listener, transform, renderer\n * layer and cleanup a plugin registers is staged here until `init` commits\n * and released together, in reverse order, when the plugin goes. See ADR 0005.\n */\n\nimport { observeThenableResult } from '@core/thenable';\nimport type { PluginDisposer } from './types';\n\nexport type ResourceKind = 'transform' | 'renderer' | 'subscription' | 'cleanup';\n\ninterface ScopedResource {\n readonly kind: ResourceKind;\n readonly acquire: (() => PluginDisposer | undefined) | undefined;\n readonly finalize: (() => void) | undefined;\n cleanup: PluginDisposer | undefined;\n disposed: boolean;\n}\n\nexport const noopDisposer: PluginDisposer = () => undefined;\n\nexport class ResourceScope {\n readonly #pluginName: string;\n readonly #log: (...args: unknown[]) => void;\n // Insertion order gives commit/reverse-teardown order; short-lived entries\n // (once listeners) leave immediately instead of accumulating until removal.\n readonly #resources = new Set<ScopedResource>();\n #state: 'staging' | 'committing' | 'active' | 'closed' = 'staging';\n\n constructor(pluginName: string, log: (...args: unknown[]) => void) {\n this.#pluginName = pluginName;\n this.#log = log;\n }\n\n assertOpen(): void {\n if (this.#state === 'closed') {\n throw new Error(`Plugin context for \"${this.#pluginName}\" is no longer active`);\n }\n }\n\n get active(): boolean {\n return this.#state === 'active';\n }\n\n /** Whether a retained context still belongs to this registration. */\n eligible(): boolean {\n return this.#state !== 'closed';\n }\n\n /** Own a resource the plugin itself already acquired. */\n own(cleanup: PluginDisposer): PluginDisposer {\n this.assertOpen();\n return this.#track({\n kind: 'cleanup',\n acquire: undefined,\n finalize: undefined,\n cleanup,\n disposed: false,\n });\n }\n\n /** Stage a manager-owned resource; an active scope acquires it at once. */\n stage(\n kind: ResourceKind,\n acquire: () => PluginDisposer | undefined,\n finalize?: () => void,\n ): PluginDisposer {\n this.assertOpen();\n const resource: ScopedResource = {\n kind,\n acquire,\n finalize,\n cleanup: undefined,\n disposed: false,\n };\n const dispose = this.#track(resource);\n if (this.#state === 'active') {\n try {\n this.#activate(resource);\n } catch (error) {\n this.#dispose(resource);\n throw error;\n }\n }\n return dispose;\n }\n\n /** Live resources by kind, what `inspect().plugins` reports. */\n counts(): Record<ResourceKind, number> {\n const counts: Record<ResourceKind, number> = {\n transform: 0,\n renderer: 0,\n subscription: 0,\n cleanup: 0,\n };\n for (const resource of this.#resources) counts[resource.kind] += 1;\n return counts;\n }\n\n /** Publish every staged resource at once after `init` succeeded. */\n commit(): void {\n if (this.#state !== 'staging') {\n throw new Error(`Plugin context for \"${this.#pluginName}\" cannot be committed`);\n }\n this.#state = 'committing';\n try {\n for (const resource of this.#resources) this.#activate(resource);\n this.#state = 'active';\n } catch (error) {\n this.close();\n throw error;\n }\n }\n\n close(): void {\n if (this.#state === 'closed') return;\n this.#state = 'closed';\n for (const resource of [...this.#resources].reverse()) this.#dispose(resource);\n this.#resources.clear();\n }\n\n #track(resource: ScopedResource): PluginDisposer {\n this.#resources.add(resource);\n return (): void => {\n this.#dispose(resource);\n };\n }\n\n #activate(resource: ScopedResource): void {\n if (resource.disposed || resource.cleanup !== undefined || resource.acquire === undefined) {\n return;\n }\n const cleanup = resource.acquire();\n resource.cleanup = cleanup ?? noopDisposer;\n }\n\n #dispose(resource: ScopedResource): void {\n if (resource.disposed) return;\n resource.disposed = true;\n this.#resources.delete(resource);\n const cleanup = resource.cleanup;\n resource.cleanup = undefined;\n if (cleanup !== undefined) {\n try {\n // A `void` cleanup may still return a thenable; observe it without awaiting.\n const cleanupWithResult: () => unknown = cleanup;\n if (observeThenableResult(cleanupWithResult())) {\n this.#log(\n `plugin \"${this.#pluginName}\" cleanup returned a Promise/thenable; cleanups must be synchronous`,\n );\n }\n } catch (error) {\n this.#log(`plugin \"${this.#pluginName}\" cleanup failed:`, error);\n }\n }\n try {\n resource.finalize?.();\n } catch (error) {\n this.#log(`plugin \"${this.#pluginName}\" cleanup failed:`, error);\n }\n }\n}\n","/**\n * Event facade handed to a plugin: subscriptions are owned by the plugin's\n * scope, emits go to the client's emitter. It implements the emitter surface\n * without extending it, so no unused base emitter is allocated per plugin.\n */\n\nimport type { EventEmitter } from '@events/emitter';\nimport type { EventHandler, LivePreviewEventMap, Unsubscribe } from '@events/types';\nimport { noopDisposer, type ResourceScope } from './resource-scope';\nimport type { PluginEvents } from './types';\n\ninterface OwnedSubscription {\n readonly kind: 'on' | 'once';\n readonly event: keyof LivePreviewEventMap;\n readonly handler: EventHandler<unknown>;\n dispose: Unsubscribe;\n}\n\nexport class ScopedPluginEvents implements PluginEvents {\n readonly #events: EventEmitter;\n readonly #scope: ResourceScope;\n readonly #subscriptions = new Set<OwnedSubscription>();\n\n constructor(events: EventEmitter, scope: ResourceScope) {\n this.#events = events;\n this.#scope = scope;\n }\n\n on<E extends keyof LivePreviewEventMap>(\n event: E,\n handler: EventHandler<LivePreviewEventMap[E]>,\n ): Unsubscribe {\n return this.#subscribe('on', event, handler);\n }\n\n once<E extends keyof LivePreviewEventMap>(\n event: E,\n handler: EventHandler<LivePreviewEventMap[E]>,\n ): Unsubscribe {\n return this.#subscribe('once', event, handler);\n }\n\n off<E extends keyof LivePreviewEventMap>(\n event: E,\n handler: EventHandler<LivePreviewEventMap[E]>,\n ): void {\n const untypedHandler = handler as EventHandler<unknown>;\n for (const subscription of [...this.#subscriptions]) {\n if (subscription.event === event && subscription.handler === untypedHandler) {\n subscription.dispose();\n }\n }\n }\n\n emit<E extends keyof LivePreviewEventMap>(\n event: E,\n payload: LivePreviewEventMap[E],\n ): Promise<void> {\n this.#scope.assertOpen();\n return this.#events.emit(event, payload);\n }\n\n emitWhile<E extends keyof LivePreviewEventMap>(\n event: E,\n payload: LivePreviewEventMap[E],\n shouldContinue: () => boolean,\n ): Promise<boolean> {\n this.#scope.assertOpen();\n return this.#events.emitWhile(event, payload, () => {\n if (!this.#scope.eligible()) return false;\n const callerEligible = shouldContinue();\n // The predicate is plugin code and may close this scope re-entrantly.\n if (!this.#scope.eligible()) return false;\n return callerEligible;\n });\n }\n\n listenerCount(event: keyof LivePreviewEventMap): number {\n let count = 0;\n for (const subscription of this.#subscriptions) {\n if (subscription.event === event) count += 1;\n }\n return count;\n }\n\n removeAllListeners(event?: keyof LivePreviewEventMap): void {\n for (const subscription of [...this.#subscriptions]) {\n if (event === undefined || subscription.event === event) subscription.dispose();\n }\n }\n\n eventNames(): (keyof LivePreviewEventMap)[] {\n const names = new Set<keyof LivePreviewEventMap>();\n for (const subscription of this.#subscriptions) names.add(subscription.event);\n return [...names];\n }\n\n #subscribe<E extends keyof LivePreviewEventMap>(\n kind: 'on' | 'once',\n event: E,\n handler: EventHandler<LivePreviewEventMap[E]>,\n ): Unsubscribe {\n this.#scope.assertOpen();\n\n const untypedHandler = handler as EventHandler<unknown>;\n const existing = [...this.#subscriptions].find(\n (subscription) =>\n subscription.kind === kind &&\n subscription.event === event &&\n subscription.handler === untypedHandler,\n );\n if (existing !== undefined) return existing.dispose;\n\n // A distinct wrapper per scope: two plugins passing the same handler\n // reference must be revocable independently in the Set-based emitter.\n let dispose = noopDisposer;\n let subscriptionActive = true;\n const wrapped: EventHandler<LivePreviewEventMap[E]> = async (payload) => {\n if (!this.#scope.active || !subscriptionActive) return;\n // Mirror the base emitter, which drops a once bucket before dispatch.\n if (kind === 'once') dispose();\n await handler(payload);\n };\n const subscription: OwnedSubscription = {\n kind,\n event,\n handler: untypedHandler,\n dispose: noopDisposer,\n };\n dispose = this.#scope.stage(\n 'subscription',\n () => this.#events[kind](event, wrapped),\n () => {\n subscriptionActive = false;\n this.#subscriptions.delete(subscription);\n },\n );\n subscription.dispose = dispose;\n this.#subscriptions.add(subscription);\n return dispose;\n }\n}\n","/**\n * Per-instance plugin manager. Mutations run through one call-order queue;\n * while a queue-held hook is pending, a requested mutation takes the direct\n * path because that hook may be awaiting it. See ADR 0005.\n */\n\nimport type { FieldRenderer } from '@core/types';\nimport type { PluginInspection } from '@core/inspection/types';\nimport { LIBRARY_PROTOCOL_VERSION } from '@core/protocol-version';\nimport { VERSION } from '@/version';\nimport { incompatibilityOf } from './compat';\nimport { isolateDiagnostic } from '@core/diagnostics';\nimport { observeThenableResult } from '@core/thenable';\nimport type { EventEmitter } from '@events/emitter';\nimport { ResourceScope } from './resource-scope';\nimport { ScopedPluginEvents } from './scoped-events';\nimport type { FieldTransform, LivePreviewPlugin, PluginContext } from './types';\n\nexport interface PluginManagerOptions {\n readonly events: EventEmitter;\n readonly config: Readonly<Record<string, unknown>>;\n /** Add one renderer layer to the host; may return the layer's disposer. */\n readonly registerFieldRenderer: (renderer: FieldRenderer) => void;\n /** Receives transform contract failures for the runtime's `error` event. */\n readonly onTransformError?: (error: Error) => unknown;\n readonly log: (...args: unknown[]) => void;\n}\n\ninterface PluginRegistration {\n readonly plugin: LivePreviewPlugin;\n readonly scope: ResourceScope;\n}\n\ninterface InitializingPluginRegistration {\n readonly scope: ResourceScope;\n cancelled: boolean;\n}\n\ninterface TransformRegistration {\n readonly transform: FieldTransform;\n active: boolean;\n}\n\nfunction isPluginDisposer(value: unknown): value is (() => void) | undefined {\n return typeof value === 'function';\n}\n\nexport class PluginManager {\n readonly #events: EventEmitter;\n readonly #config: Readonly<Record<string, unknown>>;\n // The public callback type is void; the client host returns its layer disposer through it.\n readonly #registerRenderer: (renderer: FieldRenderer) => unknown;\n readonly #onTransformError: ((error: Error) => void) | undefined;\n readonly #log: (...args: unknown[]) => void;\n readonly #plugins = new Map<string, PluginRegistration>();\n readonly #initializing = new Map<string, InitializingPluginRegistration>();\n readonly #teardowns = new Map<string, Promise<void>>();\n readonly #destroying = new Set<string>();\n readonly #transforms = new Map<string, TransformRegistration[]>();\n #mutationQueue: Promise<void> = Promise.resolve();\n // Hooks awaited by the queue entry in flight. Hooks started on the direct\n // path never hold the queue, so they must not open it for others.\n #queuedHooks = 0;\n\n constructor(options: PluginManagerOptions) {\n this.#events = options.events;\n this.#config = options.config;\n this.#registerRenderer = options.registerFieldRenderer;\n this.#log = isolateDiagnostic(options.log);\n const onTransformError = options.onTransformError;\n this.#onTransformError =\n onTransformError === undefined\n ? undefined\n : isolateDiagnostic((...args: unknown[]): unknown => {\n // Private and single-callered: `applyTransforms` normalizes to an\n // Error before it reports one.\n const error = args[0] as Error;\n try {\n return onTransformError(error);\n } catch (reportError) {\n this.#log('transform error reporter failed:', reportError);\n return undefined;\n }\n });\n }\n\n /** Register a plugin transactionally; concurrent mutations run in call order. */\n register(plugin: LivePreviewPlugin): Promise<void> {\n if (this.#queuedHooks > 0) return this.#registerNow(plugin, false);\n return this.#enqueue(() => this.#registerNow(plugin, true));\n }\n\n /** Remove one plugin and every resource its registration created. */\n unregister(name: string): Promise<void> {\n if (this.#queuedHooks > 0) return this.#unregisterNow(name, false);\n return this.#enqueue(async () => {\n await this.#unregisterNow(name, true);\n });\n }\n\n /** Destroy every registration; one failure never strands another. */\n destroyAll(): Promise<void> {\n if (this.#queuedHooks > 0) return this.#destroyAllNow(false);\n return this.#enqueue(async () => {\n await this.#destroyAllNow(true);\n });\n }\n\n /** Apply active transforms in registration order; a failure returns the original value. */\n applyTransforms(\n fieldName: string,\n value: unknown,\n context: { readonly element: Element; readonly allFields: Record<string, unknown> },\n isCurrent?: () => boolean,\n ): unknown {\n const registrations = this.#transforms.get(fieldName);\n if (registrations === undefined || registrations.length === 0) return value;\n\n let result: unknown = value;\n for (const registration of [...registrations]) {\n if (!registration.active) continue;\n const { transform } = registration;\n if (isCurrent?.() === false) return value;\n try {\n result = transform(result, {\n fieldName,\n element: context.element,\n allFields: context.allFields,\n });\n const returnedThenable = observeThenableResult(result);\n // A transform may synchronously let a newer message in; then its\n // result belongs to a superseded revision and is not reported.\n if (isCurrent?.() === false) return value;\n if (returnedThenable) {\n throw new TypeError(\n `Transform for \"${fieldName}\" returned a Promise/thenable; transforms must be synchronous`,\n );\n }\n } catch (error) {\n if (isCurrent?.() === false) return value;\n const normalized = error instanceof Error ? error : new Error(String(error));\n this.#log(`transform for \"${fieldName}\" failed:`, normalized);\n this.#onTransformError?.(normalized);\n return value;\n }\n }\n return result;\n }\n\n list(): readonly string[] {\n return [...this.#plugins.keys()];\n }\n\n /** Every plugin with its state and live registrations (`inspect().plugins`). */\n snapshot(): readonly PluginInspection[] {\n const entries: PluginInspection[] = [];\n const describe = (\n name: string,\n version: string | undefined,\n state: PluginInspection['state'],\n scope: ResourceScope,\n ): PluginInspection => {\n const counts = scope.counts();\n return {\n name,\n version,\n state,\n registrations: {\n transforms: counts.transform,\n renderers: counts.renderer,\n subscriptions: counts.subscription,\n cleanups: counts.cleanup,\n },\n };\n };\n for (const [name, initializing] of this.#initializing) {\n entries.push(describe(name, undefined, 'initializing', initializing.scope));\n }\n for (const [name, registration] of this.#plugins) {\n entries.push(describe(name, registration.plugin.version, 'active', registration.scope));\n }\n // A name with a pending teardown left `#plugins` before the teardown began.\n for (const name of this.#teardowns.keys()) {\n entries.push({\n name,\n version: undefined,\n state: 'tearing-down',\n registrations: { transforms: 0, renderers: 0, subscriptions: 0, cleanups: 0 },\n });\n }\n return entries;\n }\n\n get size(): number {\n return this.#plugins.size;\n }\n\n async #registerNow(plugin: LivePreviewPlugin, queued: boolean): Promise<void> {\n if (\n this.#plugins.has(plugin.name) ||\n this.#initializing.has(plugin.name) ||\n this.#teardowns.has(plugin.name)\n ) {\n this.#log(`plugin \"${plugin.name}\" already registered`);\n return;\n }\n\n const incompatibility = incompatibilityOf(plugin.compat, VERSION, LIBRARY_PROTOCOL_VERSION);\n if (incompatibility !== undefined) {\n this.#refuse(plugin.name, incompatibility);\n return;\n }\n const scope = new ResourceScope(plugin.name, this.#log);\n const context = this.#createContext(plugin.name, scope);\n const initializing: InitializingPluginRegistration = { scope, cancelled: false };\n this.#initializing.set(plugin.name, initializing);\n try {\n await this.#runHook(() => plugin.init(context), queued);\n if (initializing.cancelled) return;\n scope.commit();\n } catch (error) {\n scope.close();\n if (!initializing.cancelled) this.#log(`plugin \"${plugin.name}\" init failed:`, error);\n return;\n } finally {\n if (this.#initializing.get(plugin.name) === initializing) {\n this.#initializing.delete(plugin.name);\n }\n }\n\n this.#plugins.set(plugin.name, { plugin, scope });\n this.#log(`plugin \"${plugin.name}\" registered`);\n }\n\n /** A refused plugin is an integration mistake; it reaches the `error` event, not only the log. */\n #refuse(name: string, reason: string): void {\n const message = `plugin \"${name}\" refused: ${reason}`;\n this.#log(message);\n void this.#events.emit('error', {\n error: new Error(message),\n context: 'plugin',\n code: 'LP0103',\n });\n }\n\n #createContext(pluginName: string, scope: ResourceScope): PluginContext {\n return {\n events: new ScopedPluginEvents(this.#events, scope),\n registerFieldRenderer: (renderer) => {\n scope.stage('renderer', () => {\n const result = this.#registerRenderer(renderer);\n return isPluginDisposer(result) ? result : undefined;\n });\n },\n registerTransform: (fieldName, transform) => {\n const registration: TransformRegistration = { transform, active: false };\n scope.stage('transform', () => {\n registration.active = true;\n const existing = this.#transforms.get(fieldName);\n if (existing === undefined) this.#transforms.set(fieldName, [registration]);\n else existing.push(registration);\n\n return () => {\n registration.active = false;\n const current = this.#transforms.get(fieldName);\n if (current === undefined) return;\n const index = current.indexOf(registration);\n if (index >= 0) current.splice(index, 1);\n if (current.length === 0) this.#transforms.delete(fieldName);\n };\n });\n },\n registerCleanup: (cleanup) => {\n scope.own(cleanup);\n },\n getConfig: () => this.#config,\n log: (...args) => {\n this.#log(`[${pluginName}]`, ...args);\n },\n };\n }\n\n #unregisterNow(name: string, queued: boolean): Promise<void> {\n const initializing = this.#initializing.get(name);\n if (initializing !== undefined) {\n initializing.cancelled = true;\n initializing.scope.close();\n return Promise.resolve();\n }\n\n const existingTeardown = this.#teardowns.get(name);\n if (existingTeardown !== undefined) {\n // A destroy hook removing its own name cannot await the teardown that\n // awaits it; its resources are already revoked, so this is complete.\n if (this.#destroying.has(name)) return Promise.resolve();\n return queued ? this.#holdQueue(existingTeardown) : existingTeardown;\n }\n const registration = this.#plugins.get(name);\n if (registration === undefined) return Promise.resolve();\n\n // Revoke before consumer code runs: a throwing destroy keeps no access,\n // and a same-name registration from inside destroy stays a duplicate.\n this.#plugins.delete(name);\n registration.scope.close();\n const teardown = Promise.resolve().then(() =>\n this.#destroyPlugin(name, registration.plugin, queued),\n );\n this.#teardowns.set(name, teardown);\n void teardown.then(() => {\n if (this.#teardowns.get(name) === teardown) this.#teardowns.delete(name);\n });\n return teardown;\n }\n\n async #destroyPlugin(name: string, plugin: LivePreviewPlugin, queued: boolean): Promise<void> {\n if (plugin.destroy === undefined) return;\n this.#destroying.add(name);\n try {\n await this.#runHook(() => plugin.destroy?.(), queued);\n } catch (error) {\n this.#log(`plugin \"${name}\" destroy failed:`, error);\n } finally {\n this.#destroying.delete(name);\n }\n }\n\n async #destroyAllNow(queued: boolean): Promise<void> {\n for (const initializing of this.#initializing.values()) {\n initializing.cancelled = true;\n initializing.scope.close();\n }\n const names = [...this.#plugins.keys()];\n for (const name of names) await this.#unregisterNow(name, queued);\n }\n\n async #runHook(hook: () => void | Promise<void>, queued: boolean): Promise<void> {\n if (!queued) {\n await hook();\n return;\n }\n await this.#holdQueue(Promise.resolve().then(hook));\n }\n\n async #holdQueue(pending: Promise<void>): Promise<void> {\n this.#queuedHooks += 1;\n try {\n await pending;\n } finally {\n this.#queuedHooks -= 1;\n }\n }\n\n #enqueue(operation: () => void | Promise<void>): Promise<void> {\n const result = this.#mutationQueue.then(operation);\n // Keep the tail usable after an escaped error; the caller still sees it on `result`.\n this.#mutationQueue = result.catch((error: unknown) => {\n this.#log('plugin manager mutation failed:', error);\n });\n return result;\n }\n}\n","/**\n * Plugin compatibility claims. The range grammar is the subset a plugin\n * author writes (`*`, `1.2.3`, `^`, `~`, `>=`, `>`, `<`, `<=`, space-joined\n * conjunctions, `||` alternatives); prerelease tags are ignored.\n */\n\nexport interface PluginCompatibility {\n /** A semver range the runtime's `VERSION` must satisfy, e.g. `>=2.0.0`. */\n readonly runtime?: string;\n /** The highest postMessage protocol version the plugin understands. */\n readonly protocol?: number;\n}\n\ntype Version = readonly [number, number, number];\n\nfunction parseVersion(text: string): Version | undefined {\n const match = /^v?(\\d+)\\.(\\d+)\\.(\\d+)/.exec(text.trim());\n if (match === null) return undefined;\n return [Number(match[1]), Number(match[2]), Number(match[3])];\n}\n\nfunction compare(a: Version, b: Version): number {\n for (let index = 0; index < 3; index += 1) {\n const delta = (a[index] ?? 0) - (b[index] ?? 0);\n if (delta !== 0) return delta;\n }\n return 0;\n}\n\nfunction satisfiesComparator(version: Version, comparator: string): boolean {\n const trimmed = comparator.trim();\n if (trimmed === '' || trimmed === '*') return true;\n const match = /^(\\^|~|>=|<=|>|<|=)?\\s*v?(\\d+)\\.(\\d+)\\.(\\d+)/.exec(trimmed);\n if (match === null) return false;\n const operator = match[1] ?? '=';\n const target: Version = [Number(match[2]), Number(match[3]), Number(match[4])];\n const order = compare(version, target);\n switch (operator) {\n case '=':\n return order === 0;\n case '>':\n return order > 0;\n case '>=':\n return order >= 0;\n case '<':\n return order < 0;\n case '<=':\n return order <= 0;\n case '~':\n return order >= 0 && version[0] === target[0] && version[1] === target[1];\n case '^':\n if (order < 0) return false;\n if (target[0] > 0) return version[0] === target[0];\n if (target[1] > 0) return version[0] === 0 && version[1] === target[1];\n return version[0] === 0 && version[1] === 0 && version[2] === target[2];\n default:\n return false;\n }\n}\n\n/** Whether `version` satisfies `range`; anything unparsable never satisfies. */\nexport function satisfiesRange(version: string, range: string): boolean {\n const parsed = parseVersion(version);\n if (parsed === undefined) return false;\n const alternatives = range.split('||');\n return alternatives.some((alternative) => {\n const comparators = alternative\n .trim()\n .split(/\\s+/)\n .filter((part) => part.length > 0);\n if (comparators.length === 0) return alternative.trim() === '' && range.trim() === '';\n return comparators.every((comparator) => satisfiesComparator(parsed, comparator));\n });\n}\n\n/** Why a plugin was refused, or `undefined` when it fits. */\nexport function incompatibilityOf(\n compat: PluginCompatibility | undefined,\n runtimeVersion: string,\n protocolVersion: number,\n): string | undefined {\n if (compat === undefined) return undefined;\n if (compat.runtime !== undefined && !satisfiesRange(runtimeVersion, compat.runtime)) {\n return `declares runtime ${compat.runtime}, this runtime is ${runtimeVersion}`;\n }\n if (compat.protocol !== undefined) {\n if (!Number.isInteger(compat.protocol) || compat.protocol < 1) {\n return `declares an invalid protocol version ${String(compat.protocol)}`;\n }\n if (compat.protocol < protocolVersion) {\n return `declares protocol ${String(compat.protocol)}, this runtime speaks ${String(protocolVersion)}`;\n }\n }\n return undefined;\n}\n","/**\n * Per-client renderer layers: built-ins are the base, plugin registrations\n * stack above per field type, and removing a layer by identity reveals the\n * one beneath. See ADR 0005.\n */\n\nimport type { FieldRenderer, RendererKey } from '@core/types';\nimport type { PluginDisposer } from './types';\n\ninterface RendererLayer {\n readonly renderer: FieldRenderer;\n}\n\nexport class RendererRegistry {\n readonly #base: Readonly<Record<string, FieldRenderer>>;\n readonly #active: Record<string, FieldRenderer>;\n readonly #layers = new Map<RendererKey, RendererLayer[]>();\n\n constructor(base: Readonly<Record<string, FieldRenderer>>) {\n this.#base = base;\n this.#active = { ...base };\n }\n\n /** Stable live map, retained for the runtime's `renderers` option. */\n get renderers(): Readonly<Record<string, FieldRenderer>> {\n return this.#active;\n }\n\n resolve(fieldType: RendererKey): FieldRenderer | undefined {\n return this.#active[fieldType];\n }\n\n register(renderer: FieldRenderer): PluginDisposer {\n const fieldType = renderer.name;\n const layer: RendererLayer = { renderer };\n const stack = this.#layers.get(fieldType);\n if (stack === undefined) this.#layers.set(fieldType, [layer]);\n else stack.push(layer);\n this.#active[fieldType] = renderer;\n\n let active = true;\n return () => {\n if (!active) return;\n active = false;\n\n const current = this.#layers.get(fieldType);\n if (current === undefined) return;\n const index = current.indexOf(layer);\n if (index < 0) return;\n const wasTop = index === current.length - 1;\n current.splice(index, 1);\n if (current.length === 0) this.#layers.delete(fieldType);\n if (!wasTop) return;\n\n const previousLayer = current.at(-1);\n const previousRenderer = previousLayer?.renderer ?? this.#base[fieldType];\n if (previousRenderer === undefined) Reflect.deleteProperty(this.#active, fieldType);\n else this.#active[fieldType] = previousRenderer;\n };\n }\n}\n","/** Attribute helpers shared by the block-level node renderers. */\n\nimport type { LexicalNode } from './types';\n\nconst ALIGNMENT_NUMERIC: Readonly<Record<number, string>> = {\n 1: 'left',\n 2: 'center',\n 3: 'right',\n 4: 'justify',\n};\n\nconst ALIGNMENT_STRING = new Set(['left', 'center', 'right', 'justify', 'start', 'end']);\n\n/** Alignment of a block node; Payload emits it as a string or as Lexical's numeric format. */\nexport function resolveAlignment(node: LexicalNode): string | undefined {\n const fmt = node.format;\n if (typeof fmt === 'string' && ALIGNMENT_STRING.has(fmt)) return fmt;\n if (typeof fmt === 'number') return ALIGNMENT_NUMERIC[fmt];\n return undefined;\n}\n\nexport function resolveIndent(node: LexicalNode): number {\n const indent = node.indent;\n return typeof indent === 'number' && indent > 0 ? indent : 0;\n}\n\nexport function dirAttribute(node: LexicalNode): string {\n if (node.direction === 'rtl') return ' dir=\"rtl\"';\n if (node.direction === 'ltr') return ' dir=\"ltr\"';\n return '';\n}\n\n/**\n * Alignment and indent as `lp-align-*` / `lp-indent-N` classes. The sanitizer\n * strips `style` under every policy, so inline CSS would never reach the page.\n */\nexport function layoutClassAttribute(node: LexicalNode): string {\n const align = resolveAlignment(node);\n const indent = resolveIndent(node);\n const classes: string[] = [];\n if (align !== undefined) classes.push(`lp-align-${align}`);\n if (indent > 0) classes.push(`lp-indent-${String(indent)}`);\n return classes.length === 0 ? '' : ` class=\"${classes.join(' ')}\"`;\n}\n","import type { NodeRenderer } from '../registry';\nimport { dirAttribute, layoutClassAttribute } from '../utils';\n\nconst paragraphRenderer: NodeRenderer = (node, ctx): string => {\n const children = ctx.renderChildren(node.children ?? []);\n return `<p${dirAttribute(node)}${layoutClassAttribute(node)}>${children}</p>`;\n};\n\nexport { paragraphRenderer };\n","/** `heading` renderer; an unknown `tag` (transient editor states emit them) falls back to `h2`. */\n\nimport type { NodeRenderer } from '../registry';\nimport { dirAttribute, layoutClassAttribute } from '../utils';\n\nconst VALID_TAGS = new Set(['h1', 'h2', 'h3', 'h4', 'h5', 'h6']);\n\nconst headingRenderer: NodeRenderer = (node, ctx): string => {\n const tagRaw = typeof node['tag'] === 'string' ? node['tag'].toLowerCase() : 'h2';\n const tag = VALID_TAGS.has(tagRaw) ? tagRaw : 'h2';\n const children = ctx.renderChildren(node.children ?? []);\n return `<${tag}${dirAttribute(node)}${layoutClassAttribute(node)}>${children}</${tag}>`;\n};\n\nexport { headingRenderer };\n","/**\n * Value-shape helpers shared by the Lexical node renderers and the field\n * renderers. They live here because `field-types` may import `lexical`, never\n * the reverse (scripts/architecture-policy.ts).\n */\n\nexport interface MediaShape {\n readonly id?: string | number;\n readonly url?: string;\n readonly alt?: string;\n readonly filename?: string;\n readonly mimeType?: string;\n readonly width?: number;\n readonly height?: number;\n readonly sizes?: MediaSizes;\n /** Payload 4's name for `sizes`. */\n readonly variants?: MediaSizes;\n}\n\ntype MediaSizes = Readonly<\n Record<\n string,\n {\n readonly url?: string;\n readonly width?: number;\n readonly height?: number;\n readonly mimeType?: string;\n }\n >\n>;\n\nexport interface RelationShape {\n readonly id?: string | number;\n readonly title?: string;\n readonly name?: string;\n readonly slug?: string;\n readonly url?: string;\n}\n\nexport function asRecord(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nexport function readMedia(value: unknown): MediaShape | undefined {\n return asRecord(value);\n}\n\n/**\n * A media document's URL as the preview should load it. Unless its config sets\n * `serverURL`, Payload returns a path on its own origin (`/api/media/file/a.png`);\n * its admin resolves the path against the server, and the preview, framed on\n * another origin, would otherwise ask itself for the file. Only such a path is\n * Payload's to place: any other URL, and every URL when no server is known, is\n * written as delivered. A result on another origin than the server's (`/\\host`\n * is one, to the URL parser) is discarded.\n */\nexport function resolveMediaUrl(url: string, serverURL: string | undefined): string {\n if (serverURL === undefined || serverURL === '' || !url.startsWith('/')) return url;\n try {\n const server = new URL(serverURL);\n const resolved = new URL(url, server);\n return resolved.origin === server.origin ? resolved.href : url;\n } catch {\n return url;\n }\n}\n\n/** Reduce `value` to `[a-z0-9_-]` so it can be a class-name fragment without escaping. */\nexport function sanitizeIdent(value: string): string {\n return value.replace(/[^a-zA-Z0-9_-]/g, '-').toLowerCase();\n}\n\nfunction nonEmpty(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\n/** Label precedence for a populated relation: `title`, `name`, `slug`, then `id`. */\nexport function pickRelationLabel(value: RelationShape): string | undefined {\n const label = nonEmpty(value.title) ?? nonEmpty(value.name) ?? nonEmpty(value.slug);\n if (label !== undefined) return label;\n return value.id === undefined ? undefined : String(value.id);\n}\n","/**\n * `link` / `autolink` renderer. Payload 3.x serialises links as\n * `{ fields: { linkType, url, newTab, doc } }`; vanilla Lexical puts `url`\n * and `target` on the node itself. Both shapes are read, Payload's first.\n *\n * An internal link's address is a route only the site knows. The document's own\n * `url` wins, then `internalLinkPattern`, then `/<slug>`, which is all that can be\n * said without either.\n */\n\nimport { escapeHtml, escapeHtmlAttribute } from '@security/escape';\nimport { isExternalHttpUrl, isSafeUrl } from '@security/url-validator';\nimport type { NodeRenderer, RenderNodeContext } from '../registry';\nimport type { LexicalNode } from '../types';\nimport { asRecord } from '../value-shapes';\n\nconst PLACEHOLDER = /\\{(slug|id|collection|locale)\\}/gu;\nconst BLANK_TARGET = ' target=\"_blank\" rel=\"noopener noreferrer\"';\n\nconst linkRenderer: NodeRenderer = (node, ctx): string => {\n const children = ctx.renderChildren(node.children ?? []);\n const fields = asRecord(node['fields']);\n const url = resolveUrl(node, fields, ctx);\n if (url === undefined || !isSafeUrl(url)) return children;\n const titleAttr =\n typeof node['title'] === 'string' ? ` title=\"${escapeHtml(node['title'])}\"` : '';\n return `<a href=\"${escapeHtmlAttribute(url)}\"${targetAttribute(node, fields, url)}${titleAttr}>${children}</a>`;\n};\n\nfunction resolveUrl(\n node: LexicalNode,\n fields: Record<string, unknown> | undefined,\n ctx: RenderNodeContext,\n): string | undefined {\n if (fields?.['linkType'] === 'internal') return internalUrl(fields['doc'], ctx);\n const url = fields?.['url'] ?? node['url'];\n return typeof url === 'string' && url.length > 0 ? url : undefined;\n}\n\n/** Without a pattern an internal link needs the populated document; a bare id offers no route. */\nfunction internalUrl(doc: unknown, ctx: RenderNodeContext): string | undefined {\n const relation = asRecord(doc);\n const value = asRecord(relation?.['value']);\n const url = value?.['url'];\n if (typeof url === 'string' && url.length > 0) return url;\n const patterned =\n ctx.internalLinkPattern === undefined\n ? undefined\n : fillPattern(ctx.internalLinkPattern, {\n slug: value?.['slug'],\n id: value === undefined ? relation?.['value'] : value['id'],\n collection: relation?.['relationTo'],\n locale: ctx.locale,\n });\n if (patterned !== undefined) return patterned;\n const slug = value?.['slug'];\n return typeof slug === 'string' && slug.length > 0 ? `/${slug}` : undefined;\n}\n\n/** `undefined` when a placeholder the pattern names has no value: half a route is a wrong one. */\nfunction fillPattern(pattern: string, parts: Record<string, unknown>): string | undefined {\n const read = (name: string): string | undefined => {\n const part = parts[name];\n return (typeof part === 'string' && part.length > 0) || typeof part === 'number'\n ? encodeURIComponent(part)\n : undefined;\n };\n for (const [, name = ''] of pattern.matchAll(PLACEHOLDER)) {\n if (read(name) === undefined) return undefined;\n }\n return pattern.replace(PLACEHOLDER, (_match, name: string) => read(name) ?? '');\n}\n\n/** `_blank` always carries `noopener noreferrer`, whichever side asked for it. */\nfunction targetAttribute(\n node: LexicalNode,\n fields: Record<string, unknown> | undefined,\n url: string,\n): string {\n if (fields?.['newTab'] === true || isExternalHttpUrl(url)) return BLANK_TARGET;\n const target = typeof node['target'] === 'string' ? node['target'] : '';\n if (target === '') return '';\n if (target === '_blank') return BLANK_TARGET;\n return ` target=\"${escapeHtml(target)}\"`;\n}\n\nexport { linkRenderer };\n","/** `code` (fenced block) and `code-highlight` (token span) renderers. */\n\nimport { escapeHtml } from '@security/escape';\nimport type { NodeRenderer } from '../registry';\nimport type { LexicalNode } from '../types';\nimport { sanitizeIdent } from '../value-shapes';\n\nconst codeRenderer: NodeRenderer = (node): string => {\n const language = sanitizeIdent(typeof node['language'] === 'string' ? node['language'] : '');\n const langClass = language === '' ? '' : ` class=\"language-${language}\"`;\n return `<pre><code${langClass}>${escapeHtml(extractText(node))}</code></pre>`;\n};\n\nconst codeHighlightRenderer: NodeRenderer = (node): string => {\n const text = typeof node.text === 'string' ? node.text : '';\n const highlight =\n typeof node['highlightType'] === 'string'\n ? ` class=\"token-${sanitizeIdent(node['highlightType'])}\"`\n : '';\n return `<span${highlight}>${escapeHtml(text)}</span>`;\n};\n\nexport { codeRenderer, codeHighlightRenderer };\n\nfunction extractText(node: LexicalNode): string {\n if (typeof node.text === 'string') return node.text;\n if (!node.children) return '';\n let out = '';\n for (const child of node.children) out += extractText(child);\n return out;\n}\n","/**\n * `upload` renderer: `<img>` for image (or unknown) MIME types, `<video>` /\n * `<audio>` for media, a download link otherwise. An unsafe URL renders nothing.\n */\n\nimport { escapeHtml, escapeHtmlAttribute } from '@security/escape';\nimport { isSafeUrl } from '@security/url-validator';\nimport type { NodeRenderer } from '../registry';\nimport { readMedia, type MediaShape } from '../value-shapes';\n\nconst uploadRenderer: NodeRenderer = (node): string => {\n const value = readMedia(node['value']);\n if (value === undefined) return '';\n const url = value.url;\n if (typeof url !== 'string' || !isSafeUrl(url)) return '';\n\n const mime = typeof value.mimeType === 'string' ? value.mimeType : '';\n if (mime.startsWith('video/')) return renderVideo(value, url);\n if (mime.startsWith('audio/')) return renderAudio(value, url);\n if (mime === '' || mime.startsWith('image/')) return renderImage(value, url);\n return renderFallbackLink(value, url);\n};\n\nexport { uploadRenderer };\n\nfunction dimensionAttributes(value: MediaShape): string {\n const width = typeof value.width === 'number' ? ` width=\"${String(value.width)}\"` : '';\n const height = typeof value.height === 'number' ? ` height=\"${String(value.height)}\"` : '';\n return `${width}${height}`;\n}\n\nfunction typeAttribute(value: MediaShape): string {\n return typeof value.mimeType === 'string' ? ` type=\"${escapeHtmlAttribute(value.mimeType)}\"` : '';\n}\n\nfunction renderImage(value: MediaShape, url: string): string {\n const alt = typeof value.alt === 'string' ? escapeHtml(value.alt) : '';\n return `<img src=\"${escapeHtmlAttribute(url)}\" alt=\"${alt}\"${dimensionAttributes(value)} loading=\"lazy\" decoding=\"async\">`;\n}\n\nfunction renderVideo(value: MediaShape, url: string): string {\n return `<video controls${dimensionAttributes(value)}><source src=\"${escapeHtmlAttribute(url)}\"${typeAttribute(value)}></video>`;\n}\n\nfunction renderAudio(value: MediaShape, url: string): string {\n return `<audio controls><source src=\"${escapeHtmlAttribute(url)}\"${typeAttribute(value)}></audio>`;\n}\n\nfunction renderFallbackLink(value: MediaShape, url: string): string {\n const label = typeof value.filename === 'string' ? escapeHtml(value.filename) : escapeHtml(url);\n return `<a href=\"${escapeHtmlAttribute(url)}\" target=\"_blank\" rel=\"noopener noreferrer\">${label}</a>`;\n}\n","/** `relationship` renderer: a link when the populated document carries a URL, a span otherwise. */\n\nimport { escapeHtml, escapeHtmlAttribute } from '@security/escape';\nimport { isSafeUrl } from '@security/url-validator';\nimport type { NodeRenderer } from '../registry';\nimport { asRecord, pickRelationLabel, sanitizeIdent, type RelationShape } from '../value-shapes';\n\nconst relationshipRenderer: NodeRenderer = (node): string => {\n const relationTo = typeof node['relationTo'] === 'string' ? node['relationTo'] : '';\n const value = asRecord(node['value']) as RelationShape | undefined;\n const label = escapeHtml((value && pickRelationLabel(value)) ?? `#${relationTo}`);\n const slug = sanitizeIdent(relationTo);\n const classAttr =\n slug === '' ? ' class=\"lp-relation\"' : ` class=\"lp-relation lp-relation--${slug}\"`;\n const url = value?.url;\n if (typeof url === 'string' && isSafeUrl(url)) {\n return `<a href=\"${escapeHtmlAttribute(url)}\"${classAttr}>${label}</a>`;\n }\n return `<span${classAttr}>${label}</span>`;\n};\n\nexport { relationshipRenderer };\n","/** Block-renderer registry keyed by Payload block slug; consulted by the `block` and `inlineBlock` nodes. */\n\nimport type { LexicalNode } from '../types';\n\nexport interface BlockRenderContext {\n /** Render nested Lexical content through the node registry. */\n readonly renderChildren: (children: readonly LexicalNode[]) => string;\n}\n\n/** Receives the block's `fields` (with `blockType`) and returns HTML. */\nexport type BlockRenderer = (\n fields: Record<string, unknown>,\n context: BlockRenderContext,\n) => string;\n\nconst registry = new Map<string, BlockRenderer>();\n\n/** Register or replace the renderer for `blockType`. */\nexport function registerBlockRenderer(blockType: string, renderer: BlockRenderer): void {\n registry.set(blockType, renderer);\n}\n\n/** @internal */\nexport function lookupBlockRenderer(blockType: string): BlockRenderer | undefined {\n return registry.get(blockType);\n}\n\n/** @internal */\nexport function registeredBlockTypes(): readonly string[] {\n return [...registry.keys()];\n}\n\n/** Test-only: clear the registry. */\nexport function __resetBlockRegistryForTests(): void {\n registry.clear();\n}\n","/**\n * `block` and `inlineBlock` renderers for Payload's BlocksFeature. The block\n * registry is consulted first; without a renderer for the slug the node becomes\n * an empty, class-tagged element a consumer can style or replace.\n *\n * That element is a placeholder, not a rendering. `UNRENDERED_BLOCK_SELECTOR`\n * names it so the write path can keep the markup the server already rendered\n * for the block in its place, instead of replacing a figure and its image with\n * an empty div (LP0410). Whether that succeeds is decided there, not here: this\n * renderer only tells the context which slug it had no renderer for, and the\n * write says what became of it (LP0410 kept, LP0413 lost).\n */\n\nimport { lookupBlockRenderer } from '../blocks/registry';\nimport type { NodeRenderer, RenderNodeContext } from '../registry';\nimport type { LexicalNode } from '../types';\nimport { asRecord, sanitizeIdent } from '../value-shapes';\n\n/**\n * The placeholders above, in the rendered tree. Both are empty by construction,\n * and a registered renderer's output is not: it carries the block's content and\n * its own class (`lp-block-callout`, …).\n */\nexport const UNRENDERED_BLOCK_SELECTOR = '.lp-block:empty,.lp-inline-block:empty';\n\nfunction renderBlockNode(\n node: LexicalNode,\n ctx: RenderNodeContext,\n tag: 'div' | 'span',\n baseClass: string,\n): string {\n const fields = asRecord(node['fields']) ?? {};\n const blockType = typeof fields['blockType'] === 'string' ? fields['blockType'] : '';\n const slug = sanitizeIdent(blockType);\n const classes = slug === '' ? baseClass : `${baseClass} ${baseClass}--${slug}`;\n if (blockType !== '') {\n const custom = lookupBlockRenderer(blockType) ?? lookupBlockRenderer(slug);\n if (custom) return custom(fields, { renderChildren: ctx.renderChildren });\n // The real slug is known only here — the class carries `sanitizeIdent(slug)`,\n // and a hint that names the wrong one to register is no hint.\n ctx.onUnrenderedBlock?.(blockType, classes, fields);\n }\n return `<${tag} class=\"${classes}\"></${tag}>`;\n}\n\nconst blockRenderer: NodeRenderer = (node, ctx) => renderBlockNode(node, ctx, 'div', 'lp-block');\n\nconst inlineBlockRenderer: NodeRenderer = (node, ctx) =>\n renderBlockNode(node, ctx, 'span', 'lp-inline-block');\n\nexport { blockRenderer, inlineBlockRenderer };\n","/** `table` / `tablerow` / `tablecell` renderers for the `@lexical/table` shapes Payload's table feature emits. */\n\nimport type { NodeRenderer } from '../registry';\nimport { dirAttribute } from '../utils';\n\n// `@lexical/table` TableCellHeaderStates: ROW marks a cell in a header row, COLUMN one in a header column.\nconst HEADER_ROW = 1;\nconst HEADER_COLUMN = 2;\n\nconst tableRenderer: NodeRenderer = (node, ctx) =>\n `<table${dirAttribute(node)}><tbody>${ctx.renderChildren(node.children ?? [])}</tbody></table>`;\n\nconst tableRowRenderer: NodeRenderer = (node, ctx) =>\n `<tr>${ctx.renderChildren(node.children ?? [])}</tr>`;\n\nconst tableCellRenderer: NodeRenderer = (node, ctx): string => {\n const header = typeof node['headerState'] === 'number' ? node['headerState'] : 0;\n const tag = (header & (HEADER_ROW | HEADER_COLUMN)) === 0 ? 'td' : 'th';\n const scope =\n header === HEADER_ROW ? ' scope=\"col\"' : header === HEADER_COLUMN ? ' scope=\"row\"' : '';\n return `<${tag}${scope}${spanAttribute('colspan', node['colSpan'])}${spanAttribute('rowspan', node['rowSpan'])}>${ctx.renderChildren(node.children ?? [])}</${tag}>`;\n};\n\nfunction spanAttribute(name: string, value: unknown): string {\n return typeof value === 'number' && value > 1 ? ` ${name}=\"${String(value)}\"` : '';\n}\n\nexport { tableRenderer, tableRowRenderer, tableCellRenderer };\n","import type { NodeRenderer } from '../registry';\nimport { textRenderer } from './text';\nimport { paragraphRenderer } from './paragraph';\nimport { headingRenderer } from './heading';\nimport { listRenderer, listItemRenderer } from './list';\nimport { linkRenderer } from './link';\nimport { quoteRenderer } from './quote';\nimport { codeRenderer, codeHighlightRenderer } from './code';\nimport { linebreakRenderer, horizontalRuleRenderer, tabRenderer } from './linebreak';\nimport { uploadRenderer } from './upload';\nimport { relationshipRenderer } from './relationship';\nimport { blockRenderer, inlineBlockRenderer } from './block';\nimport { tableCellRenderer, tableRenderer, tableRowRenderer } from './table';\n\n// A value table instead of `register()` calls at import time: a consumer that\n// never renders Lexical content must not carry these under `sideEffects: false`.\nexport const BUILTIN_NODE_RENDERERS: Readonly<Record<string, NodeRenderer>> = {\n text: textRenderer,\n paragraph: paragraphRenderer,\n heading: headingRenderer,\n list: listRenderer,\n listitem: listItemRenderer,\n link: linkRenderer,\n autolink: linkRenderer,\n quote: quoteRenderer,\n code: codeRenderer,\n 'code-highlight': codeHighlightRenderer,\n linebreak: linebreakRenderer,\n horizontalrule: horizontalRuleRenderer,\n tab: tabRenderer,\n upload: uploadRenderer,\n relationship: relationshipRenderer,\n block: blockRenderer,\n inlineBlock: inlineBlockRenderer,\n table: tableRenderer,\n tablerow: tableRowRenderer,\n tablecell: tableCellRenderer,\n};\n","/** `text` renderer. Format flags wrap in a fixed order so equal input gives byte-equal output. */\n\nimport { escapeHtml } from '@security/escape';\nimport type { LexicalNode } from '../types';\nimport { TextFormat } from '../types';\nimport type { NodeRenderer } from '../registry';\n\nconst textRenderer: NodeRenderer = (node: LexicalNode): string => {\n const raw = typeof node.text === 'string' ? node.text : '';\n let out = escapeHtml(raw);\n const format = typeof node.format === 'number' ? node.format : 0;\n if ((format & TextFormat.CODE) !== 0) out = `<code>${out}</code>`;\n if ((format & TextFormat.BOLD) !== 0) out = `<strong>${out}</strong>`;\n if ((format & TextFormat.ITALIC) !== 0) out = `<em>${out}</em>`;\n if ((format & TextFormat.UNDERLINE) !== 0) out = `<u>${out}</u>`;\n if ((format & TextFormat.STRIKETHROUGH) !== 0) out = `<s>${out}</s>`;\n if ((format & TextFormat.SUBSCRIPT) !== 0) out = `<sub>${out}</sub>`;\n if ((format & TextFormat.SUPERSCRIPT) !== 0) out = `<sup>${out}</sup>`;\n if ((format & TextFormat.HIGHLIGHT) !== 0) out = `<mark>${out}</mark>`;\n return out;\n};\n\nexport { textRenderer };\n","/**\n * Lexical document types. Only `type` and `children` are required; every\n * other property is forwarded opaquely to the renderer for that node type.\n */\n\n/** Lexical text-format bitmask; flags combine (`BOLD | ITALIC === 3`). @internal */\nexport const TextFormat = {\n BOLD: 1,\n ITALIC: 2,\n STRIKETHROUGH: 4,\n UNDERLINE: 8,\n CODE: 16,\n SUBSCRIPT: 32,\n SUPERSCRIPT: 64,\n HIGHLIGHT: 128,\n} as const;\n\nexport interface LexicalNode {\n readonly type: string;\n readonly version?: number;\n readonly format?: number | string;\n readonly indent?: number;\n readonly direction?: 'ltr' | 'rtl' | null;\n readonly children?: readonly LexicalNode[];\n readonly text?: string;\n readonly [extra: string]: unknown;\n}\n\nexport interface LexicalRoot {\n readonly root: {\n readonly type?: string;\n readonly children: readonly LexicalNode[];\n readonly direction?: 'ltr' | 'rtl' | null;\n readonly format?: number | string;\n readonly indent?: number;\n readonly [extra: string]: unknown;\n };\n}\n","/** `list` / `listitem` renderers: `bullet` → `<ul>`, `number` → `<ol>`, `check` → `<ul role=\"list\">` with `aria-checked` items. */\n\nimport { escapeHtml } from '@security/escape';\nimport type { NodeRenderer } from '../registry';\nimport { dirAttribute, layoutClassAttribute } from '../utils';\n\nconst listRenderer: NodeRenderer = (node, ctx): string => {\n const listType = typeof node['listType'] === 'string' ? node['listType'] : 'bullet';\n const tag = listType === 'number' ? 'ol' : 'ul';\n const startAttr =\n listType === 'number' && typeof node['start'] === 'number' && node['start'] > 1\n ? ` start=\"${String(node['start'])}\"`\n : '';\n const checkAttr = listType === 'check' ? ' role=\"list\"' : '';\n const children = ctx.renderChildren(node.children ?? []);\n return `<${tag}${dirAttribute(node)}${layoutClassAttribute(node)}${startAttr}${checkAttr}>${children}</${tag}>`;\n};\n\nconst listItemRenderer: NodeRenderer = (node, ctx): string => {\n const children = ctx.renderChildren(node.children ?? []);\n if (typeof node['checked'] === 'boolean') {\n const state = node['checked'] ? 'true' : 'false';\n return `<li role=\"checkbox\" aria-checked=\"${state}\"${layoutClassAttribute(node)}>${children}</li>`;\n }\n const valueAttr =\n typeof node['value'] === 'number' ? ` value=\"${escapeHtml(String(node['value']))}\"` : '';\n return `<li${dirAttribute(node)}${layoutClassAttribute(node)}${valueAttr}>${children}</li>`;\n};\n\nexport { listRenderer, listItemRenderer };\n","import type { NodeRenderer } from '../registry';\nimport { dirAttribute, layoutClassAttribute } from '../utils';\n\nconst quoteRenderer: NodeRenderer = (node, ctx): string => {\n const children = ctx.renderChildren(node.children ?? []);\n return `<blockquote${dirAttribute(node)}${layoutClassAttribute(node)}>${children}</blockquote>`;\n};\n\nexport { quoteRenderer };\n","import type { NodeRenderer } from '../registry';\n\nconst linebreakRenderer: NodeRenderer = () => '<br>';\nconst horizontalRuleRenderer: NodeRenderer = () => '<hr>';\nconst tabRenderer: NodeRenderer = () => '\\t';\n\nexport { linebreakRenderer, horizontalRuleRenderer, tabRenderer };\n","/** Node-renderer registry: consumer registrations layered over the built-in table. */\n\nimport type { LexicalNode } from './types';\nimport { BUILTIN_NODE_RENDERERS } from './nodes/builtin';\n\nexport interface RenderNodeContext {\n /** Render child nodes through the registry. */\n readonly renderChildren: (children: readonly LexicalNode[]) => string;\n /** Text alignment of a block node, or `undefined`. */\n readonly resolveAlignment: (node: LexicalNode) => string | undefined;\n /** Indent level of a node, `0` when none. */\n readonly resolveIndent: (node: LexicalNode) => number;\n /**\n * Where a `block` or `inlineBlock` without a renderer is reported, with the\n * slug Payload sent and the class of the placeholder written in its place.\n * `undefined` on a plain `lexicalToHtml()` call; the `richText` write sets it.\n */\n readonly onUnrenderedBlock?:\n ((blockType: string, placeholderClass: string, fields: unknown) => void) | undefined;\n /** The route of an internal link, with `{slug}`, `{id}`, `{collection}` and `{locale}`. */\n readonly internalLinkPattern?: string | undefined;\n /** What `{locale}` reads. */\n readonly locale?: string | undefined;\n}\n\nexport type NodeRenderer = (node: LexicalNode, context: RenderNodeContext) => string;\n\nconst registry = new Map<string, NodeRenderer>();\n\n/** Register or replace the renderer for `type`. */\nexport function register(type: string, renderer: NodeRenderer): void {\n registry.set(type, renderer);\n}\n\n/** @internal */\nexport function lookup(type: string): NodeRenderer | undefined {\n return registry.get(type) ?? BUILTIN_NODE_RENDERERS[type];\n}\n\nexport function registeredTypes(): readonly string[] {\n return [...new Set([...Object.keys(BUILTIN_NODE_RENDERERS), ...registry.keys()])];\n}\n\n/** Test-only: drop consumer registrations. */\nexport function __resetForTests(): void {\n registry.clear();\n}\n","/**\n * Lexical → HTML. Each node dispatches to the renderer registered for its\n * `type`; an unknown node renders its children so content is never lost.\n */\n\nimport { sanitizeHtml, hasSanitizerDocument, type SanitizerDocument } from '@security/sanitizer';\nimport { lookup, type RenderNodeContext } from './registry';\nimport type { LexicalNode, LexicalRoot } from './types';\nimport { resolveAlignment, resolveIndent } from './utils';\n\nexport interface LexicalRenderOptions {\n /** Pass the result through `sanitizeHtml()` (default `true`). */\n readonly sanitize?: boolean;\n /**\n * The DOM the sanitizer parses with, for this call: an SSR document such as\n * linkedom's or jsdom's. Without it the document `setSanitizerDocument()`\n * supplied is used, then the global one; with neither the result is\n * unsanitised and warns once.\n */\n readonly document?: SanitizerDocument;\n /**\n * Throw instead of returning unsanitised HTML when no document is available:\n * the `SanitizerEnvironmentError` `sanitizeHtml()` throws (ADR 0025). Off in\n * 2.x, where the call warns once and returns the markup; the default in 3.0.\n */\n readonly requireDocument?: boolean;\n /**\n * Called for every `block` or `inlineBlock` the registry has no renderer\n * for, with the block's slug as Payload sent it, the class its empty\n * placeholder carries and the block's fields. The `richText` write listens: it is the one caller\n * that later knows whether the server's markup for the block survived, so\n * the diagnostic is spoken there (LP0410, LP0413), not here.\n */\n readonly onUnrenderedBlock?: (\n blockType: string,\n placeholderClass: string,\n fields: unknown,\n ) => void;\n /**\n * The route of an internal link whose document has no `url` of its own, such\n * as `/{locale}/{slug}/`. `{slug}`, `{id}`, `{collection}` and `{locale}` are\n * filled in and encoded; with one of them empty the link falls back to `/<slug>`.\n */\n readonly internalLinkPattern?: string | undefined;\n /** What `{locale}` reads in `internalLinkPattern`. */\n readonly locale?: string | undefined;\n}\n\nlet warnedNoSanitizer = false;\n\n/** @internal */\nexport function isLexicalContent(value: unknown): value is LexicalRoot {\n if (typeof value !== 'object' || value === null) return false;\n if (!('root' in value)) return false;\n const root = value.root;\n if (typeof root !== 'object' || root === null) return false;\n if (!('children' in root)) return false;\n return Array.isArray(root.children);\n}\n\n/** Render a Lexical document to HTML; without a document the result is unsanitised and warns once, or throws under `requireDocument`. */\nexport function lexicalToHtml(content: LexicalRoot, options: LexicalRenderOptions = {}): string {\n if (!isLexicalContent(content)) return '';\n const html = createContext(options).renderChildren(content.root.children);\n if (options.sanitize === false) return html;\n if (options.document !== undefined) return sanitizeHtml(html, { document: options.document });\n // Without a DOM this throws the sanitizer's own error.\n if (options.requireDocument === true || hasSanitizerDocument()) return sanitizeHtml(html);\n warnNoSanitizerOnce();\n return html;\n}\n\n/** Plain text of a document, paragraphs separated by `\\n`. */\nexport function lexicalToPlainText(content: LexicalRoot): string {\n if (!isLexicalContent(content)) return '';\n return content.root.children.map(extractPlainText).join('\\n').trim();\n}\n\n/** Test-only: allow the SSR warning to fire again. */\nexport function __resetSanitizerWarningForTests(): void {\n warnedNoSanitizer = false;\n}\n\n/**\n * One context per document: `renderChildren` closes over it so a nested\n * block — a `block` inside a list item, an `inlineBlock` inside a paragraph —\n * reports to the same listener as a top-level one.\n */\nfunction createContext(options: LexicalRenderOptions): RenderNodeContext {\n const context: RenderNodeContext = {\n renderChildren: (children) => {\n let out = '';\n for (const child of children) out += renderNode(child, context);\n return out;\n },\n resolveAlignment,\n resolveIndent,\n onUnrenderedBlock: options.onUnrenderedBlock,\n internalLinkPattern: options.internalLinkPattern,\n locale: options.locale,\n };\n return context;\n}\n\nfunction renderNode(node: LexicalNode, context: RenderNodeContext): string {\n const renderer = lookup(node.type);\n if (renderer) return renderer(node, context);\n return node.children !== undefined ? context.renderChildren(node.children) : '';\n}\n\nfunction extractPlainText(node: LexicalNode): string {\n if (typeof node.text === 'string') return node.text;\n if (node.type === 'linebreak') return '\\n';\n if (node.children === undefined) return '';\n let out = '';\n for (const child of node.children) out += extractPlainText(child);\n return out;\n}\n\n// This layer may not import `@core/diagnostics` (architecture policy), so the\n// warn-once lives here; a hostile or absent console must not break rendering.\nfunction warnNoSanitizerOnce(): void {\n if (warnedNoSanitizer) return;\n warnedNoSanitizer = true;\n try {\n console.warn(\n '[live-preview] lexicalToHtml() has no sanitizer document and returned unsanitised HTML; ' +\n 'pass { document } (linkedom, jsdom) per call. 3.0 throws here instead: opt in now with ' +\n '{ requireDocument: true }. See \"HTML sanitization\" in docs/security.md.',\n );\n } catch {\n // Diagnostics never become a second failure.\n }\n}\n","/**\n * `text` / `textarea` renderer. An element with structured children is left\n * alone (warned once) unless it opts in with `data-payload-text`, so a styled\n * wrapper is not destroyed by a value meant for its text node. An element whose\n * text already reads the value is left alone either way.\n */\n\nimport { isLexicalContent, lexicalToPlainText } from '@lexical/render';\nimport { trustedHtml } from '@security/trusted-types';\nimport { escapeAndLinebreak } from '@security/escape';\nimport { safeConsoleWarn } from '@core/diagnostics';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport type { FieldRenderer, RendererKey } from '@core/types';\n\nconst TEXT_OPT_IN_ATTRIBUTE = 'data-payload-text';\n\n/** Build the renderer with its own warn-once state; one per client (ADR 0002). */\nexport function createTextRenderer(name: RendererKey = 'text'): FieldRenderer {\n const warnedElements = new WeakSet<Element>();\n\n return {\n name,\n render: /* @__PURE__ */ markNoWriteCallback((target, value) => {\n const element = target.element;\n const text = toPlainString(value);\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n (element as HTMLInputElement | HTMLTextAreaElement).value = text;\n return;\n }\n // Writing the same words again would only drop the markup the server\n // drew around them, such as a `<span lang>`.\n if (element.textContent.trim() === text.trim()) return;\n if (hasForeignChildren(element) && !element.hasAttribute(TEXT_OPT_IN_ATTRIBUTE)) {\n warnOnce(warnedElements, element, target.fieldName);\n return false;\n }\n if (text.includes('\\n') || text.includes('\\r')) {\n element.innerHTML = trustedHtml(escapeAndLinebreak(text));\n return;\n }\n element.textContent = text;\n return;\n }),\n };\n}\n\n// `<br>` is this renderer's own multiline output, not a consumer wrapper;\n// counting it froze every multiline binding after its first write.\nfunction hasForeignChildren(element: Element): boolean {\n return element.querySelector(':scope > :not(br)') !== null;\n}\n\nfunction warnOnce(warnedElements: WeakSet<Element>, element: Element, fieldName: string): void {\n if (warnedElements.has(element)) return;\n warnedElements.add(element);\n safeConsoleWarn(\n `[live-preview] LP0402: Skipping text update for \"${fieldName}\": ` +\n `<${element.tagName.toLowerCase()}> has structured children. Move ` +\n `data-payload-field to the value element, or add data-payload-text to replace them.`,\n );\n}\n\nfunction toPlainString(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (isLexicalContent(value)) return lexicalToPlainText(value);\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n return JSON.stringify(value);\n}\n","/**\n * `richText` renderer: a Lexical root or an HTML string. A project\n * `renderRichText` takes precedence; its output is sanitised like every\n * other HTML write.\n *\n * The Lexical write keeps the markup the server rendered for a block the\n * registry cannot render, rather than replacing it with the empty placeholder\n * the node renderer produces for one, and it keeps the wrapper a template put\n * around the whole field. The verdict is spoken here, after the write, because\n * only the write knows it: LP0410 when the server's markup stands, LP0413 when\n * the two trees did not line up and it is gone — and the second goes through\n * `context.reportUnfaithful` too, which is the case `onUnfaithfulPatch`\n * escalates.\n */\n\nimport { isLexicalContent, lexicalToHtml } from '@lexical/render';\nimport { UNRENDERED_BLOCK_SELECTOR } from '@lexical/nodes/block';\nimport { trustedHtml } from '@security/trusted-types';\nimport { sanitizeHtmlWithPolicy } from '@security/sanitizer';\nimport { isEmptyLexicalRoot } from '@core/binding-writer';\nimport { FIELD_ATTRIBUTE } from '@core/cache';\nimport { safeConsoleWarn } from '@core/diagnostics';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport type { CachedElement, FieldRenderer, RenderContext } from '@core/types';\nimport { isEmptyValue } from './utils';\n\n/** Block slugs already reported, one set per verdict: a block kept once may still be lost later. */\nconst warnedKept = new Set<string>();\nconst warnedLost = new Set<string>();\n/** The fields of the blocks each element last kept, to tell an edit to a block from one around it. */\nconst lastKeptBlocks = new WeakMap<Element, string>();\n\n/** The containers a template wraps rich text in; Lexical renders none of them for content. */\nconst WRAPPER_TAGS: ReadonlySet<string> = new Set(['DIV', 'SECTION', 'ARTICLE']);\n\nconst richTextRenderer: FieldRenderer = {\n name: 'richText',\n render: /* @__PURE__ */ markNoWriteCallback((target, value, context) => {\n const element = target.element;\n if (isEmptyValue(value)) {\n element.textContent = '';\n return;\n }\n const policy = context.sanitizerPolicy;\n if (context.renderRichText !== undefined) {\n const html = context.renderRichText(value, {\n fieldName: target.fieldName,\n element,\n locale: context.locale,\n });\n element.innerHTML = trustedHtml(sanitizeHtmlWithPolicy(html, policy));\n return;\n }\n if (isLexicalContent(value)) {\n // Empty paragraphs only: cleared as `null` is. A project renderer above decides for itself.\n if (isEmptyLexicalRoot(value)) {\n element.textContent = '';\n return;\n }\n // Slug by placeholder class: the class is what the write finds standing.\n const unrendered = new Map<string, string>();\n const blockFields: unknown[] = [];\n const lexical = lexicalToHtml(value, {\n // Lexical would otherwise sanitise with the process default; the sink\n // below does it with the instance's policy instead.\n sanitize: false,\n internalLinkPattern: context.internalLinkPattern,\n locale: context.locale,\n onUnrenderedBlock: (blockType, placeholderClass, fields) => {\n unrendered.set(placeholderClass, blockType);\n blockFields.push(fields);\n },\n });\n const verdicts = writeKeepingUnrenderedBlocks(\n element,\n sanitizeHtmlWithPolicy(lexical, policy),\n );\n for (const [placeholderClass, lost] of verdicts) {\n const blockType = unrendered.get(placeholderClass);\n if (blockType !== undefined) reportUnrenderedBlock(target, context, blockType, lost);\n }\n reportChangedKeptBlocks(target, context, blockFields, verdicts);\n return;\n }\n if (typeof value === 'string') {\n element.innerHTML = trustedHtml(sanitizeHtmlWithPolicy(value, policy));\n return;\n }\n return false;\n }),\n};\n\n/**\n * Write `html` into `element`, but move the live element standing where an\n * unrendered block's placeholder stands over into the new tree first. Every\n * pairing is resolved before the first move: a move takes a child out of the\n * live element, which would shift the position each later one is read at.\n *\n * Returns a verdict per placeholder class: `false` where a live element that\n * was not itself a placeholder took the placeholder's place, `true` where one\n * is still standing over markup the element had — the descent found no\n * counterpart, so this write lost what the server drew for that block. No\n * verdict where there was nothing to keep: a container the page left empty,\n * or a placeholder an earlier write put there, whose loss was reported then.\n */\nfunction writeKeepingUnrenderedBlocks(\n element: Element,\n html: string,\n): ReadonlyMap<string, boolean> {\n const rendered = element.cloneNode(false) as Element;\n rendered.innerHTML = trustedHtml(html);\n const target = wrapperOf(element, rendered) ?? element;\n const verdicts = new Map<string, boolean>();\n const placeholders = rendered.querySelectorAll(UNRENDERED_BLOCK_SELECTOR);\n if (placeholders.length > 0 && target.firstElementChild !== null) {\n const pairs: [placeholder: Element, live: Element][] = [];\n pairUnrenderedBlocks(target, rendered, pairs);\n for (const [placeholder, live] of pairs) {\n placeholder.replaceWith(live);\n if (!live.matches(UNRENDERED_BLOCK_SELECTOR)) verdicts.set(placeholder.className, false);\n }\n // A placeholder the moves left in the tree is one no live element answered for.\n for (const placeholder of placeholders) {\n if (placeholder.parentNode !== null) verdicts.set(placeholder.className, true);\n }\n }\n target.replaceChildren(...rendered.childNodes);\n return verdicts;\n}\n\n/**\n * The one wrapper a template puts around rich text when the server renders it\n * — `<div class=\"prose\">` around the blocks, the usual Tailwind shape — or\n * `null` when the rendered document is written straight into `element`. The\n * wrapper stays, because the typography hangs on its class, and the pairing\n * runs inside it, where the blocks are; without this the live tree had one\n * child where the rendered one had five, and the descent stopped before it\n * reached the block (measured on the demo, Z29).\n *\n * A wrapper is the element's only child, of a kind Lexical does not render\n * content as, with no binding of its own, standing where the rendered document\n * has elements unlike it: a `<div>` a registered block renders is content, and\n * the paragraph typed after it must not be written into it. A document of one\n * element keeps the wrapper too, unless that element is a placeholder or of\n * the wrapper's own tag: then the wrapper may be the block the server drew, and\n * the positional pairing answers for it.\n */\nfunction wrapperOf(element: Element, rendered: Element): Element | null {\n const child = element.firstElementChild;\n const only = rendered.children.length === 1 ? rendered.firstElementChild : null;\n if (child?.nextElementSibling !== null || rendered.children.length === 0) return null;\n if (!WRAPPER_TAGS.has(child.tagName) || child.hasAttribute(FIELD_ATTRIBUTE)) return null;\n if (only?.tagName === child.tagName || only?.matches(UNRENDERED_BLOCK_SELECTOR) === true) {\n return null;\n }\n for (const block of rendered.children) {\n if (block.tagName === child.tagName && block.className === child.className) return null;\n }\n return child;\n}\n\n/**\n * Pair each placeholder with the live element in its position. Both trees\n * describe the same document, so position is the only key there is — the server\n * writes no id to match on. Where the child counts differ, an edit added or\n * removed a node somewhere in between: the pairing walks in from both ends and\n * stops at the first two that cannot be one node, two tags, or a placeholder\n * against an element of a tag the document renders beside it. A placeholder\n * left in between is written, which is what this renderer did before.\n */\nfunction pairUnrenderedBlocks(\n live: Element,\n rendered: Element,\n kept: [placeholder: Element, live: Element][],\n): void {\n const pair = (block: Element, element: Element): void => {\n if (block.matches(UNRENDERED_BLOCK_SELECTOR)) kept.push([block, element]);\n else pairUnrenderedBlocks(element, block, kept);\n };\n // Nothing moves until every pairing is known, so walking siblings is stable.\n let element = live.firstElementChild;\n let block = rendered.firstElementChild;\n if (live.children.length === rendered.children.length) {\n for (; element !== null && block !== null; element = element.nextElementSibling) {\n pair(block, element);\n block = block.nextElementSibling;\n }\n return;\n }\n const tags = new Set<string>();\n for (const child of rendered.children) {\n if (!child.matches(UNRENDERED_BLOCK_SELECTOR)) tags.add(child.tagName);\n }\n const fits = (candidate: Element, standing: Element): boolean =>\n candidate.matches(UNRENDERED_BLOCK_SELECTOR)\n ? !tags.has(standing.tagName)\n : candidate.tagName === standing.tagName;\n let front = 0;\n for (; element !== null && block !== null && fits(block, element); front += 1) {\n pair(block, element);\n element = element.nextElementSibling;\n block = block.nextElementSibling;\n }\n const shorter = Math.min(live.children.length, rendered.children.length);\n element = live.lastElementChild;\n block = rendered.lastElementChild;\n for (let back = front; back < shorter && element !== null && block !== null; back += 1) {\n if (!fits(block, element)) return;\n pair(block, element);\n element = element.previousElementSibling;\n block = block.previousElementSibling;\n }\n}\n\n/**\n * Say what became of a block nobody registered a renderer for, once per slug\n * and verdict. Not through the runtime's `warn` option: a renderer has no\n * channel to it, and `RenderContext` carries the one thing that matters more —\n * the report that lets a strategy redraw the region the write just degraded.\n */\nfunction reportUnrenderedBlock(\n target: CachedElement,\n context: RenderContext,\n blockType: string,\n lost: boolean,\n): void {\n if (lost) {\n context.reportUnfaithful?.(target, `lost the markup the server drew for block \"${blockType}\"`);\n }\n const warned = lost ? warnedLost : warnedKept;\n if (warned.has(blockType)) return;\n warned.add(blockType);\n safeConsoleWarn(\n `[live-preview] ${\n lost\n ? `LP0413: no renderer for block \"${blockType}\", and the markup the server rendered for it is lost.`\n : `LP0410: no renderer for block \"${blockType}\"; keeping what the server rendered for it.`\n } Register one with registerBlockRenderer().`,\n );\n}\n\n/**\n * The server's markup for a kept block is right until the block itself changes.\n * The next edit to it writes nothing the page can show, so the region goes to a\n * strategy, as for a block whose markup was lost. Text typed around it changes\n * nothing here.\n */\nfunction reportChangedKeptBlocks(\n target: CachedElement,\n context: RenderContext,\n blockFields: readonly unknown[],\n verdicts: ReadonlyMap<string, boolean>,\n): void {\n const seen = keptBlockFields(blockFields);\n const prior = lastKeptBlocks.get(target.element);\n if (seen === undefined) lastKeptBlocks.delete(target.element);\n else lastKeptBlocks.set(target.element, seen);\n if (seen === undefined || prior === undefined || seen === prior) return;\n if ([...verdicts.values()].includes(false)) {\n context.reportUnfaithful?.(target, 'changed a block no renderer draws');\n }\n}\n\n/**\n * The blocks as a string, with a populated document reduced to its id: the merge\n * turns `media: 2` into the upload, and that is not an edit. The timestamps tell\n * a document from an array row, whose `id` says nothing about its text.\n */\nfunction keptBlockFields(blockFields: readonly unknown[]): string | undefined {\n try {\n return JSON.stringify(blockFields, (_key, value: Record<string, unknown> | null) =>\n typeof value === 'object' && value !== null && 'id' in value && 'updatedAt' in value\n ? value['id']\n : value,\n );\n } catch {\n return undefined;\n }\n}\n\n/** Test-only: let LP0410 and LP0413 fire again. */\nexport function __resetBlockWarningsForTests(): void {\n warnedKept.clear();\n warnedLost.clear();\n}\n\nexport { richTextRenderer };\n","/** `html` renderer (`data-payload-type=\"html\"`): the value is sanitised, then injected. */\n\nimport { sanitizeHtmlWithPolicy } from '@security/sanitizer';\nimport { trustedHtml } from '@security/trusted-types';\nimport type { FieldRenderer } from '@core/types';\nimport { isEmptyValue, safeStringify } from './utils';\n\nconst htmlRenderer: FieldRenderer = {\n name: 'html',\n render(target, value, context) {\n if (isEmptyValue(value)) {\n target.element.textContent = '';\n return;\n }\n const html = typeof value === 'string' ? value : safeStringify(value);\n target.element.innerHTML = trustedHtml(sanitizeHtmlWithPolicy(html, context.sanitizerPolicy));\n },\n};\n\nexport { htmlRenderer };\n","/** URL acceptance shared by the renderers that write `href` / `src`: one LP0401 warning per element. */\n\nimport { safeConsoleWarn } from '@core/diagnostics';\nimport { resolveMediaUrl } from '@lexical/value-shapes';\nimport { isSafeUrl } from '@security/url-validator';\n\n// Keyed by element so a second client on the same page does not repeat the warning.\nconst warned = new WeakSet<Element>();\n\nexport type UrlOutcome =\n | { readonly kind: 'none' }\n | { readonly kind: 'unsafe' }\n | { readonly kind: 'safe'; readonly url: string };\n\n/**\n * `none` when there is no URL to write, `unsafe` (warned once) when it fails `isSafeUrl`.\n * `serverURL` is passed for a URL out of a media document only: a path in it is Payload's\n * (`resolveMediaUrl`), while one an author typed into a text field is the site's own.\n */\nexport function acceptUrl(\n element: Element,\n fieldName: string,\n candidate: unknown,\n serverURL?: string,\n): UrlOutcome {\n if (typeof candidate !== 'string' || candidate.length === 0) return { kind: 'none' };\n const url = resolveMediaUrl(candidate, serverURL);\n if (isSafeUrl(url)) return { kind: 'safe', url };\n if (!warned.has(element)) {\n warned.add(element);\n safeConsoleWarn(\n `[live-preview] LP0401: refused an unsafe URL for \"${fieldName}\" on ` +\n `<${element.tagName.toLowerCase()}>; the attribute was cleared.`,\n );\n }\n return { kind: 'unsafe' };\n}\n","/**\n * `url` renderer and the factory the `email` renderer shares. On an `<a>` the\n * value (or the `data-payload-href` sibling) becomes `href`; the value is\n * always the visible text.\n */\n\nimport { resolveFieldValue } from '@core/field-value';\nimport type { FieldRenderer, RendererKey } from '@core/types';\nimport { acceptUrl } from './unsafe-url';\nimport { isEmptyValue, safeStringify } from './utils';\n\n/** Build the link renderer named `name`; `toHref` derives the URL from the field value. */\nexport function createLinkRenderer(\n name: RendererKey,\n toHref: (value: string) => string = (value) => value,\n): FieldRenderer {\n return {\n name,\n render(target, value, context) {\n const element = target.element;\n if (isEmptyValue(value)) {\n clear(element);\n return;\n }\n const text = safeStringify(value);\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n (element as HTMLInputElement | HTMLTextAreaElement).value = text;\n return;\n }\n if (element.tagName === 'A') {\n const hrefField = target.hrefField;\n const candidate =\n hrefField === undefined || hrefField.length === 0\n ? toHref(text)\n : resolveFieldValue(\n context.allFields,\n hrefField,\n context.locale,\n target.locale !== undefined,\n );\n const outcome = acceptUrl(element, target.fieldName, candidate);\n if (outcome.kind === 'safe') element.setAttribute('href', outcome.url);\n else if (outcome.kind === 'unsafe') element.removeAttribute('href');\n }\n element.textContent = text;\n },\n };\n}\n\nfunction clear(element: Element): void {\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n (element as HTMLInputElement | HTMLTextAreaElement).value = '';\n return;\n }\n element.removeAttribute('href');\n element.textContent = '';\n}\n\nexport const urlRenderer: FieldRenderer = createLinkRenderer('url');\n","/** `email` renderer: a bare address becomes a `mailto:` link, a value with a scheme is used as written. */\n\nimport type { FieldRenderer } from '@core/types';\nimport { createLinkRenderer } from './url';\n\nconst HAS_SCHEME = /^[a-zA-Z][a-zA-Z0-9+.-]*:/;\n\nfunction mailtoHref(value: string): string {\n const trimmed = value.trim();\n if (HAS_SCHEME.test(trimmed) || !trimmed.includes('@')) return trimmed;\n return `mailto:${trimmed}`;\n}\n\nexport const emailRenderer: FieldRenderer = createLinkRenderer('email', mailtoHref);\n","/** `<img>` writes shared by the image and upload renderers. */\n\nimport { isSafeUrl } from '@security/url-validator';\nimport { resolveMediaUrl, type MediaShape } from '@lexical/value-shapes';\n\nconst IMAGE_SOURCE_ATTRIBUTES = ['src', 'srcset', 'sizes'] as const;\n\n/** One image a media document offers: the original, or one of its `sizes`. */\ninterface Source {\n readonly name?: string;\n readonly url: string;\n readonly width: number;\n readonly height?: number | undefined;\n readonly mimeType?: string | undefined;\n}\n\n/** The size each `<img>` was last written with, so the next image the editor picks gets the same one. */\nconst chosenSizes = new WeakMap<HTMLImageElement, string>();\n\nexport function clearImage(img: HTMLImageElement): void {\n for (const name of IMAGE_SOURCE_ATTRIBUTES) img.removeAttribute(name);\n dropPictureSources(img);\n}\n\n/** A `<picture>`'s `<source>` wins over any `src`, and it still names the old image. */\nfunction dropPictureSources(img: HTMLImageElement): void {\n if (img.parentElement?.tagName !== 'PICTURE') return;\n for (const source of img.parentElement.querySelectorAll('source')) source.remove();\n}\n\n/**\n * A server-rendered `srcset` would keep winning over a new `src`, so it is\n * rebuilt or removed together with `sizes`. It offers the picture the element\n * shows: the size whose URL the element's `src` is — the template's choice, or\n * the last write's once the editor picks another image — else the original,\n * and of the rest only what has its shape and format, or its shape alone when\n * no size has its format, one per width. A crop of another shape is another picture. `url` is already resolved; the sizes\n * are resolved against `serverURL`. A `<picture>` keeps its sources while the\n * image is still the one they were drawn for.\n */\nexport function writeImage(\n img: HTMLImageElement,\n url: string,\n media: MediaShape | undefined,\n serverURL?: string,\n): void {\n const sizes = sizeSources(media, serverURL);\n const shown = img.getAttribute('src');\n const chosen =\n sizes.find((size) => shown !== null && sameUrl(img, size.url, shown)) ??\n sizes.find((size) => size.name === chosenSizes.get(img));\n if (chosen?.name === undefined) chosenSizes.delete(img);\n else chosenSizes.set(img, chosen.name);\n // A size of the same name on another image is still another image.\n if (\n shown === null ||\n !(sameUrl(img, url, shown) || sizes.some((s) => sameUrl(img, s.url, shown)))\n ) {\n dropPictureSources(img);\n }\n img.src = chosen?.url ?? url;\n const shape = chosen ?? media;\n const sameFormat = sizes.filter((size) => sameShape(size, shape));\n // Payload 4's sharp transformer writes WebP variants of a JPEG: another format, the same picture.\n const candidates =\n sameFormat.length > 0\n ? sameFormat\n : sizes.filter((size) => sameShape({ ...size, mimeType: undefined }, shape));\n if (candidates.length === 0) {\n img.removeAttribute('srcset');\n img.removeAttribute('sizes');\n return;\n }\n if (typeof media?.width === 'number' && typeof media.url === 'string') {\n const original = resolveMediaUrl(media.url, serverURL);\n const source = { ...media, url: original, width: media.width };\n if (isSafeUrl(original) && sameShape(source, shape)) candidates.push(source);\n }\n // Two candidates of one width say nothing the first does not; the browser keeps the first anyway.\n const widths = new Set<number>();\n const parts: string[] = [];\n for (const source of candidates) {\n if (widths.has(source.width)) continue;\n widths.add(source.width);\n parts.push(`${srcsetUrl(source.url)} ${String(source.width)}w`);\n }\n const srcset = parts.join(', ');\n img.setAttribute('srcset', srcset);\n}\n\nfunction sizeSources(media: MediaShape | undefined, serverURL: string | undefined): Source[] {\n const sources: Source[] = [];\n for (const [name, size] of Object.entries(media?.sizes ?? media?.variants ?? {})) {\n if (typeof size.url !== 'string' || typeof size.width !== 'number') continue;\n const url = resolveMediaUrl(size.url, serverURL);\n if (isSafeUrl(url)) sources.push({ ...size, name, url, width: size.width });\n }\n return sources;\n}\n\nfunction sameUrl(img: HTMLImageElement, a: string, b: string): boolean {\n try {\n return new URL(a, img.baseURI).href === new URL(b, img.baseURI).href;\n } catch {\n return a === b;\n }\n}\n\n/**\n * Whether `source` is the same picture as `shape` at another width. What\n * either leaves out cannot tell them apart. Payload scales a size's height\n * from the original's and rounds it, so a pixel at the larger width is the\n * same shape.\n */\nfunction sameShape(\n source: Partial<Source>,\n shape: (Pick<Source, 'height' | 'mimeType'> & { readonly width?: number }) | undefined,\n): boolean {\n if (shape === undefined) return true;\n if (\n typeof source.mimeType === 'string' &&\n typeof shape.mimeType === 'string' &&\n source.mimeType !== shape.mimeType\n ) {\n return false;\n }\n const { width, height } = shape;\n if (\n typeof width !== 'number' ||\n typeof height !== 'number' ||\n typeof source.width !== 'number' ||\n typeof source.height !== 'number'\n ) {\n return true;\n }\n return Math.abs(source.width * height - source.height * width) <= Math.max(width, source.width);\n}\n\n// Commas and whitespace delimit srcset candidates and cannot appear raw in a URL there.\nfunction srcsetUrl(url: string): string {\n return url.replace(/[\\s,]/g, encodeURIComponent);\n}\n","/**\n * `image` renderer: `src`/`alt`/`srcset` on an `<img>`, a CSS background on\n * anything else. The value is a media object, a URL string, or resolved from\n * the `data-payload-src` / `data-payload-alt` sibling fields; a binding whose\n * alt is its own field holds alt text, not a source.\n */\n\nimport { escapeCssUrl } from '@security/escape';\nimport { resolveFieldValue } from '@core/field-value';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport type { CachedElement, FieldRenderer, RenderContext } from '@core/types';\nimport { readMedia, type MediaShape } from '@lexical/value-shapes';\nimport { clearImage, writeImage } from './media';\nimport { acceptUrl } from './unsafe-url';\nimport { isEmptyValue } from './utils';\n\n/**\n * A path from `/`, `./` or `../`; a file name with an image's extension; or a\n * `/`, `.` or `:` somewhere and no whitespace. The first two may hold a space,\n * which the browser encodes. A bare word stays text: it could be a name or an id.\n */\nconst NAMES_A_SOURCE =\n /^(?:\\.{0,2}\\/|\\S*[/.:]\\S*$|.*\\.(?:avif|bmp|gif|ico|jpe?g|png|svg|tiff?|webp)$)/i;\n\nconst imageRenderer: FieldRenderer = {\n name: 'image',\n render: /* @__PURE__ */ markNoWriteCallback((target, value, context) => {\n const element = target.element;\n if (\n element.tagName === 'IMG' &&\n target.altField === target.fieldName &&\n target.srcField === undefined &&\n (typeof value === 'string' || isEmptyValue(value))\n ) {\n (element as HTMLImageElement).alt = value ?? '';\n return;\n }\n if (isEmptyValue(value)) {\n clear(element);\n return;\n }\n const preferLocale = target.locale !== undefined;\n const { media, candidate } = pickSource(target, value, context, preferLocale);\n // A word or an id is no address, though the URL parser would take either for a relative path.\n if (\n media === undefined &&\n typeof candidate === 'string' &&\n !NAMES_A_SOURCE.test(candidate.trim())\n ) {\n return false;\n }\n // Only a media document's path is Payload's; a string an author typed is the site's own.\n const outcome = acceptUrl(\n element,\n target.fieldName,\n candidate,\n media === undefined ? undefined : context.serverURL,\n );\n if (outcome.kind === 'none') return false;\n if (outcome.kind === 'unsafe') {\n clear(element);\n return;\n }\n if (element.tagName === 'IMG') {\n const img = element as HTMLImageElement;\n writeImage(img, outcome.url, media, context.serverURL);\n const alt = pickAlt(media, target.altField, context.allFields, context.locale, preferLocale);\n if (alt !== undefined) img.alt = alt;\n return;\n }\n (element as HTMLElement).style.backgroundImage = `url('${escapeCssUrl(outcome.url)}')`;\n return;\n }),\n};\n\nfunction clear(element: Element): void {\n if (element.tagName === 'IMG') clearImage(element as HTMLImageElement);\n else (element as HTMLElement).style.backgroundImage = '';\n}\n\nfunction pickSource(\n target: CachedElement,\n value: unknown,\n context: RenderContext,\n preferLocale: boolean,\n): { readonly media: MediaShape | undefined; readonly candidate: unknown } {\n const source =\n target.srcField !== undefined && target.srcField.length > 0\n ? resolveFieldValue(context.allFields, target.srcField, context.locale, preferLocale)\n : value;\n const media = readMedia(source);\n return { media, candidate: media === undefined ? source : media.url };\n}\n\nfunction pickAlt(\n media: MediaShape | undefined,\n altField: string | undefined,\n allFields: Record<string, unknown>,\n locale: string | undefined,\n preferLocale: boolean,\n): string | undefined {\n if (altField !== undefined && altField.length > 0) {\n const sibling = resolveFieldValue(allFields, altField, locale, preferLocale);\n return typeof sibling === 'string' ? sibling : undefined;\n }\n return media?.alt;\n}\n\nexport { imageRenderer };\n","/** `upload` renderer: an image on `<img>`, a download link on `<a>`, an injected link elsewhere. */\n\nimport { escapeHtml, escapeHtmlAttribute } from '@security/escape';\nimport { trustedHtml } from '@security/trusted-types';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport type { FieldRenderer } from '@core/types';\nimport { readMedia } from '@lexical/value-shapes';\nimport { clearImage, writeImage } from './media';\nimport { acceptUrl } from './unsafe-url';\nimport { isEmptyValue } from './utils';\n\nconst uploadRenderer: FieldRenderer = {\n name: 'upload',\n render: /* @__PURE__ */ markNoWriteCallback((target, value, context) => {\n const element = target.element;\n if (isEmptyValue(value)) {\n clear(element);\n return;\n }\n const media = readMedia(value);\n if (media === undefined) return false;\n const outcome = acceptUrl(element, target.fieldName, media.url, context.serverURL);\n if (outcome.kind === 'none') return false;\n if (outcome.kind === 'unsafe') {\n clear(element);\n return;\n }\n const url = outcome.url;\n if (element.tagName === 'IMG') {\n const img = element as HTMLImageElement;\n writeImage(img, url, media, context.serverURL);\n if (media.alt !== undefined) img.alt = media.alt;\n return;\n }\n if (element.tagName === 'A') {\n element.setAttribute('href', url);\n element.textContent = media.filename ?? url;\n return;\n }\n const label = escapeHtml(media.filename ?? url);\n element.innerHTML = trustedHtml(`<a href=\"${escapeHtmlAttribute(url)}\">${label}</a>`);\n return;\n }),\n};\n\nfunction clear(element: Element): void {\n if (element.tagName === 'IMG') {\n clearImage(element as HTMLImageElement);\n return;\n }\n element.removeAttribute('href');\n element.textContent = '';\n}\n\nexport { uploadRenderer };\n","/** `relationship` renderer: the relation's label as text; on an `<a>` a populated `url` becomes `href`. */\n\nimport type { FieldRenderer } from '@core/types';\nimport { asRecord, pickRelationLabel, type RelationShape } from '@lexical/value-shapes';\nimport { acceptUrl } from './unsafe-url';\nimport { isEmptyValue, safeStringify } from './utils';\n\nconst relationshipRenderer: FieldRenderer = {\n name: 'relationship',\n render(target, value) {\n const element = target.element;\n if (isEmptyValue(value)) {\n element.removeAttribute('href');\n element.textContent = '';\n return;\n }\n if (element.tagName === 'A' && !Array.isArray(value)) {\n const outcome = acceptUrl(element, target.fieldName, asRecord(value)?.['url']);\n if (outcome.kind === 'safe') element.setAttribute('href', outcome.url);\n else if (outcome.kind === 'unsafe') element.removeAttribute('href');\n }\n element.textContent = Array.isArray(value) ? value.map(label).join(', ') : label(value);\n },\n};\n\nfunction label(value: unknown): string {\n const record = asRecord(value) as RelationShape | undefined;\n if (record === undefined) return safeStringify(value);\n return pickRelationLabel(record) ?? '';\n}\n\nexport { relationshipRenderer };\n","/**\n * `select` / `radio` renderer. Form controls receive option values; other\n * elements show the option labels from the field schema when the admin sent\n * one, else the values.\n */\n\nimport type { FieldRenderer, RenderContext } from '@core/types';\nimport { asRecord } from '@lexical/value-shapes';\nimport { isEmptyValue, safeStringify } from './utils';\n\nconst selectRenderer: FieldRenderer = {\n name: 'select',\n render(target, value, context) {\n const element = target.element;\n const values = isEmptyValue(value) ? [] : toValues(value);\n if (element.tagName === 'SELECT') {\n writeSelect(element as HTMLSelectElement, values);\n return;\n }\n if (element.tagName === 'INPUT' && (element as HTMLInputElement).type === 'radio') {\n const radio = element as HTMLInputElement;\n radio.checked = values.includes(radio.value);\n return;\n }\n element.textContent = values.map((item) => labelFor(item, context)).join(', ');\n },\n};\n\nfunction toValues(value: unknown): readonly string[] {\n if (Array.isArray(value)) return value.map(safeStringify);\n return [safeStringify(value)];\n}\n\n// `.value = 'a, b'` on a multiple select selects nothing; options are set one by one.\nfunction writeSelect(select: HTMLSelectElement, values: readonly string[]): void {\n if (select.multiple) {\n for (const option of Array.from(select.options)) {\n option.selected = values.includes(option.value);\n }\n return;\n }\n select.value = values[0] ?? '';\n}\n\nfunction labelFor(value: string, context: RenderContext): string {\n const options = context.schema?.['options'];\n if (!Array.isArray(options)) return value;\n for (const option of options) {\n const record = asRecord(option);\n if (record === undefined || safeStringify(record['value']) !== value) continue;\n return typeof record['label'] === 'string' ? record['label'] : value;\n }\n return value;\n}\n\nexport { selectRenderer };\n","/** `checkbox` renderer: `checked` on an input, `aria-checked` where present, `true`/`false` text otherwise. */\n\nimport type { FieldRenderer } from '@core/types';\n\nconst FALSE_STRINGS = new Set(['', 'false', '0', 'off', 'no']);\n\nconst checkboxRenderer: FieldRenderer = {\n name: 'checkbox',\n render(target, value) {\n const element = target.element;\n const checked = toBoolean(value);\n if (element.tagName === 'INPUT' && (element as HTMLInputElement).type === 'checkbox') {\n (element as HTMLInputElement).checked = checked;\n return;\n }\n if (element.hasAttribute('aria-checked')) {\n element.setAttribute('aria-checked', checked ? 'true' : 'false');\n return;\n }\n element.textContent = checked ? 'true' : 'false';\n },\n};\n\n// Form state and query parameters arrive as strings; `Boolean('false')` is not an answer.\nfunction toBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return !FALSE_STRINGS.has(value.trim().toLowerCase());\n if (typeof value === 'number') return value !== 0;\n return value !== null && value !== undefined;\n}\n\nexport { checkboxRenderer };\n","/**\n * Memoised `Intl` formatters, keyed by locale and options. Constructing them\n * per call dominates render time for arrays of many numeric or date fields,\n * and a formatter is a pure function of its key, so one instance is safe to\n * share across the page. Bounded so a language switcher cannot grow it without\n * limit.\n */\n\nimport { lruGet, lruSet, lruTrim } from './lru';\n\nconst NUMBER_CACHE = new Map<string, Intl.NumberFormat>();\nconst DATE_CACHE = new Map<string, Intl.DateTimeFormat>();\n\nconst DEFAULT_MAX_ENTRIES = 64;\n\nlet maxEntries = DEFAULT_MAX_ENTRIES;\n\n/** Internal test helper — purges every cached formatter. */\nexport function __resetIntlCache(): void {\n NUMBER_CACHE.clear();\n DATE_CACHE.clear();\n maxEntries = DEFAULT_MAX_ENTRIES;\n}\n\n/** Adjust the LRU bound. Returns the previous value. */\nexport function setIntlCacheLimit(limit: number): number {\n if (!Number.isFinite(limit) || limit < 1) return maxEntries;\n const previous = maxEntries;\n maxEntries = Math.floor(limit);\n lruTrim(NUMBER_CACHE, maxEntries);\n lruTrim(DATE_CACHE, maxEntries);\n return previous;\n}\n\n/** Cache occupancy, for tests and dev observability. */\nexport function intlCacheSize(): { readonly numbers: number; readonly dates: number } {\n return { numbers: NUMBER_CACHE.size, dates: DATE_CACHE.size };\n}\n\nexport function getNumberFormat(\n locale: string | undefined,\n options?: Intl.NumberFormatOptions,\n): Intl.NumberFormat {\n const key = buildKey(locale, options);\n return (\n lruGet(NUMBER_CACHE, key) ??\n lruSet(NUMBER_CACHE, key, new Intl.NumberFormat(locale, options), maxEntries)\n );\n}\n\nexport function getDateTimeFormat(\n locale: string | undefined,\n options?: Intl.DateTimeFormatOptions,\n): Intl.DateTimeFormat {\n const key = buildKey(locale, options);\n return (\n lruGet(DATE_CACHE, key) ??\n lruSet(DATE_CACHE, key, new Intl.DateTimeFormat(locale, options), maxEntries)\n );\n}\n\nfunction buildKey(locale: string | undefined, options: unknown): string {\n // Stable key order so equivalent option objects share a slot, and an empty\n // one collapses to the bare-locale key.\n const localePart = locale ?? '';\n if (options === undefined || options === null) return localePart;\n const serialised = stableStringify(options);\n if (serialised === '{}') return localePart;\n return `${localePart}|${serialised}`;\n}\n\nfunction stableStringify(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value);\n if (Array.isArray(value)) {\n return `[${value.map((v) => stableStringify(v)).join(',')}]`;\n }\n const record = value as Record<string, unknown>;\n const keys = Object.keys(record).sort();\n const parts: string[] = [];\n for (const key of keys) {\n const inner = record[key];\n if (inner === undefined) continue;\n parts.push(`${JSON.stringify(key)}:${stableStringify(inner)}`);\n }\n return `{${parts.join(',')}}`;\n}\n","/**\n * `data-payload-format`: a closed vocabulary deciding how a date or a number is\n * written. Without it a bound price shows the raw amount and a bound date an\n * ISO instant, so a template that formats on the server has to leave both\n * unbound — which is where an edit becomes invisible.\n *\n * Closed on purpose. Anything a consumer could pass here would be code running\n * inside the preview, and the runtime takes no code from the page. Two\n * renderers read it, so the parsing lives beside them rather than in either.\n *\n * `relative` (\"in 3 days\") is deliberately absent: choosing the unit and its\n * rounding is policy, not formatting, and two readers will want different\n * answers. A project that needs it renders it on the server behind a fragment.\n */\n\nimport { safeConsoleWarn } from '@core/diagnostics';\n\n/** What a renderer does with a parsed vocabulary entry. */\nexport type ValueFormat =\n | { readonly kind: 'date'; readonly options: Intl.DateTimeFormatOptions }\n | { readonly kind: 'number'; readonly options: Intl.NumberFormatOptions };\n\nconst DATE_STYLES = new Set(['short', 'medium', 'long', 'full']);\nconst TIME_STYLES = new Set(['short', 'medium', 'long', 'full']);\n\n/** ISO 4217: three letters, and `Intl` rejects anything else at construction. */\nconst CURRENCY_CODE = /^[A-Za-z]{3}$/u;\nconst FRACTION_DIGITS = /^[0-4]$/u;\n\n/**\n * `undefined` for a spec this vocabulary does not contain — the caller then\n * keeps its own default formatting and reports LP0408 once for that element.\n */\nexport function parseValueFormat(spec: string): ValueFormat | undefined {\n const separator = spec.indexOf(':');\n const name = separator === -1 ? spec : spec.slice(0, separator);\n const argument = separator === -1 ? undefined : spec.slice(separator + 1);\n\n switch (name) {\n case 'date':\n if (argument === undefined) return dateFormat({ dateStyle: 'medium' });\n return DATE_STYLES.has(argument)\n ? dateFormat({ dateStyle: argument as Intl.DateTimeFormatOptions['dateStyle'] })\n : undefined;\n case 'time':\n if (argument === undefined) return dateFormat({ timeStyle: 'short' });\n return TIME_STYLES.has(argument)\n ? dateFormat({ timeStyle: argument as Intl.DateTimeFormatOptions['timeStyle'] })\n : undefined;\n case 'datetime':\n // The bare form is the renderer's own default, so `datetime` changes\n // nothing and exists to be written down next to the others.\n if (argument === undefined) return dateFormat({ dateStyle: 'medium', timeStyle: 'short' });\n return DATE_STYLES.has(argument)\n ? dateFormat({\n dateStyle: argument as Intl.DateTimeFormatOptions['dateStyle'],\n timeStyle: argument === 'short' ? 'short' : 'medium',\n })\n : undefined;\n case 'number':\n if (argument === undefined) return numberFormat({});\n if (!FRACTION_DIGITS.test(argument)) return undefined;\n return numberFormat({\n minimumFractionDigits: Number(argument),\n maximumFractionDigits: Number(argument),\n });\n case 'currency':\n if (argument === undefined || !CURRENCY_CODE.test(argument)) return undefined;\n return numberFormat({ style: 'currency', currency: argument.toUpperCase() });\n case 'percent':\n return argument === undefined ? numberFormat({ style: 'percent' }) : undefined;\n default:\n return undefined;\n }\n}\n\nfunction dateFormat(options: Intl.DateTimeFormatOptions): ValueFormat {\n return { kind: 'date', options };\n}\n\nfunction numberFormat(options: Intl.NumberFormatOptions): ValueFormat {\n return { kind: 'number', options };\n}\n\nconst warned = new WeakSet<Element>();\n\n/** Reported once per element: the markup is the cause, and it does not change. */\nexport function warnUnknownFormat(element: Element, fieldName: string, spec: string): void {\n if (warned.has(element)) return;\n warned.add(element);\n safeConsoleWarn(\n `[live-preview] LP0408: data-payload-format=\"${spec}\" on \"${fieldName}\" is not a ` +\n 'known format; the default formatting was used. Known: date, time, datetime (each also ' +\n ':short|medium|long|full), number, number:0-4, currency:XXX, percent.',\n );\n}\n\n/**\n * The options a renderer should use, or `undefined` to keep its own default —\n * which is also the answer when the spec belongs to the other renderer, so\n * `currency:EUR` on a date changes nothing rather than breaking it.\n */\nexport function formatOptionsFor<K extends ValueFormat['kind']>(\n kind: K,\n spec: string | undefined,\n element: Element,\n fieldName: string,\n): Extract<ValueFormat, { kind: K }>['options'] | undefined {\n if (spec === undefined || spec === '') return undefined;\n const parsed = parseValueFormat(spec);\n if (parsed === undefined) {\n warnUnknownFormat(element, fieldName, spec);\n return undefined;\n }\n if (parsed.kind !== kind) return undefined;\n return parsed.options;\n}\n","/**\n * `date` renderer. `<time>` gets an ISO `datetime` plus a localised label;\n * date inputs get the value in the visitor's local time zone, because that is\n * what the control displays.\n */\n\nimport { detectInitialLocale } from '@detection/locale';\nimport { getDateTimeFormat } from '@core/intl-cache';\nimport type { CachedElement, FieldRenderer, RenderContext } from '@core/types';\nimport { isEmptyValue, safeStringify } from './utils';\nimport { formatOptionsFor } from './value-format';\n\nconst dateRenderer: FieldRenderer = {\n name: 'date',\n render(target, value, context) {\n const element = target.element;\n if (isEmptyValue(value)) {\n if (element.tagName === 'INPUT') (element as HTMLInputElement).value = '';\n else {\n element.removeAttribute('datetime');\n element.textContent = '';\n }\n return;\n }\n const raw = typeof value === 'number' ? value : safeStringify(value);\n const date = new Date(raw);\n const valid = !Number.isNaN(date.getTime());\n const fallback = String(raw);\n if (element.tagName === 'INPUT') {\n (element as HTMLInputElement).value = valid\n ? formatForInput((element as HTMLInputElement).type, date)\n : fallback;\n return;\n }\n if (element.tagName === 'TIME') {\n element.setAttribute('datetime', valid ? date.toISOString() : fallback);\n }\n element.textContent = valid ? formatDate(date, target, context) : fallback;\n },\n};\n\nconst DEFAULT_DATE_OPTIONS: Intl.DateTimeFormatOptions = {\n dateStyle: 'medium',\n timeStyle: 'short',\n};\n\nfunction formatDate(date: Date, target: CachedElement, context: RenderContext): string {\n const locale = target.locale ?? context.locale ?? detectInitialLocale();\n const options =\n formatOptionsFor('date', target.format, target.element, target.fieldName) ??\n DEFAULT_DATE_OPTIONS;\n try {\n return getDateTimeFormat(locale, options).format(date);\n } catch {\n return date.toISOString();\n }\n}\n\n/** Value for `<input type=\"date|datetime-local|time\">` in local time; other inputs get the ISO instant. */\nexport function formatForInput(type: string, date: Date): string {\n const day = `${String(date.getFullYear()).padStart(4, '0')}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\n const clock = `${pad(date.getHours())}:${pad(date.getMinutes())}`;\n if (type === 'date') return day;\n if (type === 'datetime-local') return `${day}T${clock}`;\n if (type === 'time') return clock;\n return date.toISOString();\n}\n\nfunction pad(value: number): string {\n return String(value).padStart(2, '0');\n}\n\nexport { dateRenderer };\n","/** `number` renderer: raw value on inputs, `Intl.NumberFormat` elsewhere. */\n\nimport { detectInitialLocale } from '@detection/locale';\nimport { getNumberFormat } from '@core/intl-cache';\nimport type { CachedElement, FieldRenderer, RenderContext } from '@core/types';\nimport { isEmptyValue, safeStringify } from './utils';\nimport { formatOptionsFor } from './value-format';\n\nconst numberRenderer: FieldRenderer = {\n name: 'number',\n render(target, value, context) {\n const element = target.element;\n if (isEmptyValue(value)) {\n if (element.tagName === 'INPUT') (element as HTMLInputElement).value = '';\n else element.textContent = '';\n return;\n }\n const num = typeof value === 'number' ? value : Number(safeStringify(value));\n if (Number.isNaN(num)) {\n element.textContent = safeStringify(value);\n return;\n }\n if (element.tagName === 'INPUT') {\n (element as HTMLInputElement).value = String(num);\n return;\n }\n element.textContent = format(num, target, context);\n },\n};\n\nfunction format(num: number, target: CachedElement, context: RenderContext): string {\n const locale = target.locale ?? context.locale ?? detectInitialLocale();\n const options = formatOptionsFor('number', target.format, target.element, target.fieldName);\n try {\n return getNumberFormat(locale, options).format(num);\n } catch {\n // An `Intl` option this build rejects — an unknown currency, say.\n return String(num);\n }\n}\n\nexport { numberRenderer };\n","/**\n * `array` / `blocks` renderer. With `data-payload-array-template` each item\n * is interpolated into the template (`{{key}}`, `{{value}}`, `{{index}}`);\n * without one, items are joined by `data-payload-array-separator`.\n */\n\nimport { sanitizeHtmlWithPolicy } from '@security/sanitizer';\nimport { trustedHtml } from '@security/trusted-types';\nimport {\n collectTemplateKeys,\n inheritItemAttributes,\n interpolateArrayTemplate,\n sharedItemAttributes,\n} from '@core/array-template';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport { templateSanitizeOptions } from '@core/template-sanitize';\nimport type { FieldRenderer } from '@core/types';\nimport { isEmptyValue, safeStringify } from './utils';\n\nconst arrayRenderer: FieldRenderer = {\n name: 'array',\n render: /* @__PURE__ */ markNoWriteCallback((target, value, context) => {\n const element = target.element;\n if (isEmptyValue(value)) {\n element.textContent = '';\n return;\n }\n if (!Array.isArray(value)) return false;\n const template = target.arrayTemplate;\n if (template !== undefined && template.length > 0) {\n const html = renderTemplate(template, value);\n const policy = context.sanitizerPolicy;\n const templateOptions = templateSanitizeOptions(template);\n // Read before the write: the items about to be replaced are the only\n // record of what the server put on them.\n const shared = sharedItemAttributes(element);\n element.innerHTML = trustedHtml(sanitizeHtmlWithPolicy(html, policy, templateOptions));\n for (const item of Array.from(element.children)) inheritItemAttributes(item, shared);\n return;\n }\n element.textContent = value.map(safeStringify).join(target.arraySeparator ?? ', ');\n return;\n }),\n};\n\nfunction renderTemplate(template: string, items: readonly unknown[]): string {\n const knownKeys = collectTemplateKeys(items);\n let out = '';\n for (let i = 0; i < items.length; i += 1) {\n out += interpolateArrayTemplate(template, items[i], i, safeStringify, knownKeys);\n }\n return out;\n}\n\nexport { arrayRenderer };\n","/**\n * `structural-array` renderer (`data-payload-structural`): diffs the previous\n * and next item lists and patches the container through the keyed morph\n * (ADR 0008). All diff memory lives in the closure, one per client.\n */\n\nimport { safeConsoleWarn } from '@core/diagnostics';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport {\n applyStructuralPatches,\n createStructuralStore,\n KEY_ATTRIBUTE,\n type StructuralStore,\n} from '@core/structural-applier';\nimport { diffArray } from '@schema/diff';\nimport type { FieldRenderer } from '@core/types';\nimport { isEmptyValue } from './utils';\n\ninterface StructuralRenderState {\n readonly values: readonly unknown[];\n readonly template: string;\n readonly domSnapshot: readonly (string | null)[];\n}\n\ntype WarnedCodes = WeakMap<Element, Set<string>>;\n\n/** @internal */\nexport function createStructuralArrayRenderer(): FieldRenderer {\n const states = new WeakMap<Element, StructuralRenderState>();\n const warnedContainers = new WeakSet<Element>();\n const warnedKeys: WarnedCodes = new WeakMap();\n const store: StructuralStore = createStructuralStore();\n\n return {\n name: 'structural-array',\n render: /* @__PURE__ */ markNoWriteCallback((target, rawValue, context) => {\n const value = isEmptyValue(rawValue) ? [] : rawValue;\n if (!Array.isArray(value)) return false;\n const container = target.element;\n const template = target.arrayTemplate;\n if (template === undefined || template.length === 0) {\n warnMissingTemplate(warnedContainers, container, target.fieldName);\n return false;\n }\n const previousState = states.get(container);\n const domSnapshot = readDomKeySnapshot(container);\n const previous = previousState?.values ?? valuesFromDomSnapshot(domSnapshot);\n const patches = diffArray(previous, value);\n const forceRender = needsForcedRender(previousState, template, domSnapshot);\n if (patches.length === 0 && !forceRender) {\n states.set(container, { values: value.slice(), template, domSnapshot });\n return false;\n }\n warnAboutKeys(warnedKeys, container, target.fieldName, previousState?.values, value);\n const applied = applyStructuralPatches({\n template,\n container,\n patches,\n nextItems: value,\n store,\n forceRender,\n sanitizerPolicy: context.sanitizerPolicy,\n onDuplicateKey: (owner, key) => {\n warnDuplicateKey(warnedKeys, owner, target.fieldName, key);\n },\n });\n if (applied === null) return false;\n states.set(container, {\n values: value.slice(),\n template,\n domSnapshot: readDomKeySnapshot(container),\n });\n return applied ? undefined : false;\n }),\n };\n}\n\nfunction needsForcedRender(\n previous: StructuralRenderState | undefined,\n template: string,\n domSnapshot: readonly (string | null)[],\n): boolean {\n if (previous === undefined) return true;\n return previous.template !== template || !sameDomKeySnapshot(previous.domSnapshot, domSnapshot);\n}\n\n// SSR markup exists before any in-memory snapshot; its direct-child keys let\n// the first update reconcile instead of appending a second copy.\nfunction readDomKeySnapshot(container: Element): readonly (string | null)[] {\n return Array.from(container.children, (child) => child.getAttribute(KEY_ATTRIBUTE));\n}\n\nfunction valuesFromDomSnapshot(snapshot: readonly (string | null)[]): readonly unknown[] {\n return snapshot.map((key, position) =>\n key === null ? { __payloadDomPosition: position } : { id: key },\n );\n}\n\nfunction sameDomKeySnapshot(\n previous: readonly (string | null)[],\n current: readonly (string | null)[],\n): boolean {\n if (previous.length !== current.length) return false;\n return previous.every((key, index) => key === current[index]);\n}\n\nfunction warnMissingTemplate(\n warnedContainers: WeakSet<Element>,\n container: Element,\n fieldName: string,\n): void {\n if (warnedContainers.has(container)) return;\n warnedContainers.add(container);\n safeConsoleWarn(\n `[live-preview] LP0403: Skipping structural update for \"${fieldName}\": ` +\n `<${container.tagName.toLowerCase()} data-payload-structural> needs ` +\n `data-payload-array-template (for example \"<li>{{label}}</li>\").`,\n );\n}\n\nfunction itemKey(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const id = (value as Record<string, unknown>)['id'];\n return typeof id === 'string' || typeof id === 'number' ? String(id) : undefined;\n}\n\n/** Key problems degrade the morph, they do not break it; each is announced once per container (ADR 0008 §5). */\nfunction warnAboutKeys(\n warned: WarnedCodes,\n container: Element,\n fieldName: string,\n previous: readonly unknown[] | undefined,\n next: readonly unknown[],\n): void {\n const nextKeys = next.map(itemKey);\n const seen = new Set<string>();\n const duplicate = nextKeys.find((key) => {\n if (key === undefined) return false;\n if (seen.has(key)) return true;\n seen.add(key);\n return false;\n });\n if (duplicate !== undefined) warnDuplicateKey(warned, container, fieldName, duplicate);\n if (nextKeys.some((key) => key === undefined)) {\n warnOnce(\n warned,\n container,\n 'LP0404',\n `LP0404: an item of \"${fieldName}\" has no id and pairs by ` +\n 'position, so an insert re-renders every row after it. Give items a stable id.',\n );\n }\n if (previous?.length === next.length && next.length > 1) {\n const previousKeys = new Set(previous.map(itemKey).filter((key) => key !== undefined));\n const stable = nextKeys.some((key) => key !== undefined && previousKeys.has(key));\n if (previousKeys.size > 0 && !stable) {\n warnOnce(\n warned,\n container,\n 'LP0406',\n `LP0406: every key of \"${fieldName}\" changed at once; the ` +\n 'source generates ids per message, so no item can be retained across updates.',\n );\n }\n }\n}\n\n// Reached from the pre-diff check and from the morph's nested-slot check; one site, one message.\nfunction warnDuplicateKey(\n warned: WarnedCodes,\n owner: Element,\n fieldName: string,\n key: string,\n): void {\n warnOnce(\n warned,\n owner,\n 'LP0405',\n `LP0405: two items of \"${fieldName}\" share the key \"${key}\"; later ones pair by ` +\n 'position. Make `id` unique per item.',\n );\n}\n\nfunction warnOnce(warned: WarnedCodes, container: Element, code: string, message: string): void {\n let codes = warned.get(container);\n if (codes === undefined) {\n codes = new Set();\n warned.set(container, codes);\n }\n if (codes.has(code)) return;\n codes.add(code);\n safeConsoleWarn(`[live-preview] ${message}`);\n}\n","/**\n * Explicit renderer overrides, layered above the defaults each time a map is\n * built. The registry never retains the defaults, so stateful ones can be\n * recreated per client.\n */\n\nimport type { FieldRenderer, RendererKey } from '@core/types';\n\nconst builtinRenderers = new Map<RendererKey, FieldRenderer>();\n\nexport function buildBuiltinRenderers(\n defaults: readonly FieldRenderer[] = [],\n): Readonly<Record<string, FieldRenderer>> {\n const out: Record<string, FieldRenderer> = {};\n for (const renderer of defaults) out[renderer.name] = renderer;\n for (const [type, renderer] of builtinRenderers) out[type] = renderer;\n return Object.freeze(out);\n}\n\n/** Register or replace an override for maps built afterwards. */\nexport function registerBuiltinRenderer(renderer: FieldRenderer): void {\n builtinRenderers.set(renderer.name, renderer);\n}\n\n/** Test-only: clear the overrides. */\nexport function __resetBuiltinRenderersForTests(): void {\n builtinRenderers.clear();\n}\n","/** Built-in field renderers, assembled as values so `sideEffects: false` bundlers keep them all. */\n\nimport type { FieldRenderer } from '@core/types';\nimport { createTextRenderer } from './text';\nimport { richTextRenderer } from './rich-text';\nimport { htmlRenderer } from './html';\nimport { urlRenderer } from './url';\nimport { emailRenderer } from './email';\nimport { imageRenderer } from './image';\nimport { uploadRenderer } from './upload';\nimport { relationshipRenderer } from './relationship';\nimport { selectRenderer } from './select';\nimport { checkboxRenderer } from './checkbox';\nimport { dateRenderer } from './date';\nimport { numberRenderer } from './number';\nimport { arrayRenderer } from './array';\nimport { createStructuralArrayRenderer } from './structural-array';\nimport {\n buildBuiltinRenderers as buildRegistry,\n registerBuiltinRenderer,\n __resetBuiltinRenderersForTests,\n} from './registry';\nimport { reportOmittedFeature } from '@core/profile';\n\n/**\n * The array renderers carry the keyed morph, the structural applier and the item\n * templates — the largest optional cluster in the runtime. The lean profile\n * answers a page that needs them with LP0104 instead (@core/profile).\n */\nfunction arrayRenderers(): readonly FieldRenderer[] {\n return typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__\n ? [\n omittedRenderer('array', 'structural arrays'),\n omittedRenderer('blocks', 'structural arrays'),\n ]\n : [arrayRenderer, { ...arrayRenderer, name: 'blocks' }];\n}\n\n/** A renderer that only explains itself: the lean profile does not carry this field type. */\nfunction omittedRenderer(name: FieldRenderer['name'], feature: 'structural arrays'): FieldRenderer {\n return {\n name,\n render() {\n reportOmittedFeature(feature);\n },\n };\n}\n\n/** One renderer map per client; the stateful text and structural renderers are created fresh each call. @internal */\nexport function buildBuiltinRenderers(): Readonly<Record<string, FieldRenderer>> {\n // Built per call: a module-level table would pin every renderer into any\n // consumer importing an unrelated symbol from the root barrel.\n const stateless: readonly FieldRenderer[] = [\n richTextRenderer,\n htmlRenderer,\n urlRenderer,\n emailRenderer,\n imageRenderer,\n uploadRenderer,\n relationshipRenderer,\n selectRenderer,\n { ...selectRenderer, name: 'radio' },\n checkboxRenderer,\n dateRenderer,\n numberRenderer,\n ...arrayRenderers(),\n ];\n\n return buildRegistry([\n createTextRenderer('text'),\n createTextRenderer('textarea'),\n ...stateless,\n ...(typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__\n ? []\n : [createStructuralArrayRenderer()]),\n ]);\n}\n\nexport { registerBuiltinRenderer, __resetBuiltinRenderersForTests };\nexport type { PayloadMedia, PayloadRelationship } from './types';\n","/**\n * The two defaults profiles, row by row. 2.0 ships `v2`; `defaults: 'v1'` opts\n * back into the 1.x table for a staged migration. Each row belongs to exactly\n * one side — the adapter's request decision or the browser runtime — and a\n * test asserts the profile assigns every readiness row that has an option, so\n * a row added later cannot be forgotten. See ADR 0007.\n *\n * It lives in the leaf `types` domain, like `merge-depth.ts`, because the\n * inline generator resolves the profile too, and the generator is server-side\n * code that may not reach the browser runtime in `core`.\n */\n\n/** `'v2'` is the 2.0 default; `'v1'` is the 1.x table. */\nexport type DefaultsProfile = 'v1' | 'v2';\n\n/** How the runtime decides which windows may post updates. */\nexport type EventSourcePolicy = 'any' | 'parent-or-opener';\n\n/** Readiness rows that are options, keyed by the option they set. */\nexport const READINESS_ROWS = Object.freeze({\n strict: 'production response changes require an authorized context',\n previewSignals: 'query-only intent signal',\n disableReferrerDetection: 'referrer trust off',\n eventSourcePolicy: 'messages must come from parent/opener',\n skipUnchanged: 'skip unchanged bindings by default',\n sanitizerPolicy: 'hardened sanitizer id/data-* policy',\n} as const);\n\n/** Options an adapter's request decision reads from the profile. */\nexport interface AdapterProfileDefaults {\n readonly strict: boolean;\n readonly previewSignals: readonly ('query' | 'fetch-dest' | 'referer')[];\n}\n\n/** Options the browser runtime reads from the profile (through the inline configuration). */\nexport interface RuntimeProfileDefaults {\n readonly disableReferrerDetection: boolean;\n readonly eventSourcePolicy: EventSourcePolicy;\n readonly skipUnchanged: boolean;\n readonly sanitizerPolicy: 'compat' | 'strict';\n}\n\nexport const V2_ADAPTER_DEFAULTS: AdapterProfileDefaults = Object.freeze({\n strict: true,\n previewSignals: Object.freeze(['query'] as const),\n});\n\nexport const V2_RUNTIME_DEFAULTS: RuntimeProfileDefaults = Object.freeze({\n disableReferrerDetection: true,\n eventSourcePolicy: 'parent-or-opener',\n skipUnchanged: true,\n sanitizerPolicy: 'strict',\n});\n\n/** The 1.x table, spelled out so the profiles compare row by row. */\nexport const V1_ADAPTER_DEFAULTS: AdapterProfileDefaults = Object.freeze({\n strict: false,\n previewSignals: Object.freeze(['query', 'fetch-dest', 'referer'] as const),\n});\n\nexport const V1_RUNTIME_DEFAULTS: RuntimeProfileDefaults = Object.freeze({\n disableReferrerDetection: false,\n eventSourcePolicy: 'any',\n skipUnchanged: false,\n sanitizerPolicy: 'compat',\n});\n\n/** Only an explicit `'v1'` opts out; everything else gets the hardened rows. */\nexport function adapterDefaultsFor(profile: DefaultsProfile | undefined): AdapterProfileDefaults {\n return profile === 'v1' ? V1_ADAPTER_DEFAULTS : V2_ADAPTER_DEFAULTS;\n}\n\nexport function runtimeDefaultsFor(profile: DefaultsProfile | undefined): RuntimeProfileDefaults {\n return profile === 'v1' ? V1_RUNTIME_DEFAULTS : V2_RUNTIME_DEFAULTS;\n}\n","/**\n * `LivePreviewClient`: a `LivePreviewRuntime` with its own emitter, plugin\n * manager and renderer registry. A page that only needs a working preview uses\n * `generateInlineScript()` instead.\n */\n\nimport { assertMergeDepthExplicit } from '@/types/merge-depth';\nimport { LivePreviewRuntime, type RuntimeOptions } from '@core/lifecycle';\nimport type { LivePreviewInspection } from '@core/inspection/types';\nimport type { CachedElement, RendererKey } from '@core/types';\nimport { EventEmitter } from '@events/emitter';\nimport { OriginDetector } from '@detection/origin';\nimport { PluginManager } from '@plugins/manager';\nimport { RendererRegistry } from '@plugins/renderer-registry';\nimport type { LivePreviewPlugin } from '@plugins/types';\nimport { isDevMode, isInPreviewContext } from '@detection/environment';\nimport { buildBuiltinRenderers } from '@field-types/index';\nimport { definedOnly } from '@/types/defined-only';\nimport { withProfileDefaults, type LivePreviewClientConfig } from './config';\nimport { noopDiagnostic, safeConsoleDebug } from '@core/diagnostics';\n\n/** `T` with every property optional and `undefined`-able, for literals built from optional inputs. */\ntype Loose<T> = { readonly [K in keyof T]?: T[K] | undefined };\n\nfunction invert(value: boolean | undefined): boolean | undefined {\n return value === undefined ? undefined : !value;\n}\n\nexport class LivePreviewClient {\n readonly #emitter = new EventEmitter();\n readonly #detector: OriginDetector;\n readonly #rendererRegistry: RendererRegistry;\n readonly #runtime: LivePreviewRuntime;\n readonly #plugins: PluginManager;\n readonly #log: (...args: unknown[]) => void;\n #started = false;\n #destroyed = false;\n #tornDown = false;\n #destroyPromise: Promise<void> | null = null;\n\n constructor(rawConfig: LivePreviewClientConfig = {}) {\n const config = withProfileDefaults(rawConfig);\n const serverURL = config.serverURL ?? '';\n assertMergeDepthExplicit({\n defaults: rawConfig.defaults,\n serverURL,\n mergeDepth: config.mergeDepth,\n });\n const debug = config.debug ?? isDevMode();\n this.#log = debug\n ? (...args): void => {\n safeConsoleDebug('[live-preview]', ...args);\n }\n : noopDiagnostic;\n\n this.#detector = new OriginDetector(\n definedOnly({\n additionalOrigins: config.allowedOrigins,\n enableReferrerDetection: invert(config.disableReferrerDetection),\n enableLocalhostMatching: invert(config.disableLocalhostMatching),\n }),\n );\n\n if (this.#detector.isProductionUnconfigured) {\n this.#log('no trusted origin could be detected — set allowedOrigins');\n }\n\n this.#rendererRegistry = new RendererRegistry(buildBuiltinRenderers());\n\n this.#plugins = new PluginManager({\n events: this.#emitter,\n config: Object.freeze({ ...config }),\n registerFieldRenderer: (renderer) => this.#rendererRegistry.register(renderer),\n onTransformError: (error) => {\n void this.#emitter.emit('error', { error, context: 'transform', code: 'LP0602' });\n },\n log: this.#log,\n });\n\n this.#runtime = new LivePreviewRuntime(\n definedOnly({\n root: config.root,\n renderers: this.#rendererRegistry.renderers,\n resolveRenderer: (fieldType: RendererKey, target: CachedElement) =>\n config.resolveRenderer?.(fieldType, target) ?? this.#rendererRegistry.resolve(fieldType),\n renderRichText: config.renderRichText,\n internalLinkPattern: config.internalLinkPattern,\n routeAfterSave: config.routeAfterSave,\n sanitizerPolicy: config.sanitizerPolicy,\n transformValue: (\n fieldName: string,\n value: unknown,\n context: { readonly element: Element; readonly allFields: Record<string, unknown> },\n isCurrent?: () => boolean,\n ) => this.#plugins.applyTransforms(fieldName, value, context, isCurrent),\n originMatcher: (origin: string) => this.#detector.matches(origin),\n // Read per handshake, not once: after a lock, a bfcache restore must\n // re-broadcast to the locked origin alone, not every pre-lock candidate.\n readyTargets: () => this.#detector.enumerate(),\n emitter: this.#emitter,\n dataMerge:\n serverURL === ''\n ? undefined\n : definedOnly({\n serverURL,\n apiRoute: config.apiRoute,\n depth: config.mergeDepth,\n timeoutMs: config.mergeTimeoutMs,\n fetchFn: config.mergeFetch,\n }),\n debounceMs: config.debounceMs,\n heartbeatMs: config.heartbeatMs,\n intersectionRootMargin: config.intersectionRootMargin,\n scopeBindingsByOwner: config.scopeBindingsByOwner,\n skipUnchanged: config.skipUnchanged,\n revealEditedField: config.revealEditedField,\n autoBind: config.autoBind,\n subfieldCoverage: config.subfieldCoverage,\n eventSourcePolicy: config.eventSourcePolicy,\n dependencies: config.dependencies,\n strategies: config.strategies,\n disableVisibilityGate: config.disableVisibilityGate,\n visibilityGateThreshold: config.visibilityGateThreshold,\n enableA11y: config.enableA11y,\n a11yLocale: config.a11yLocale,\n onHeartbeatTimeout: () => {\n this.#detector.unlockOrigin();\n },\n lockedOrigin: () => this.#detector.lockedOrigin,\n validateToken: config.validateToken,\n log: this.#log,\n } satisfies Loose<RuntimeOptions>),\n );\n\n this.#emitter.on('connect', (e) => {\n this.#detector.lockOrigin(e.origin);\n });\n\n if (config.autoStart !== false) {\n this.start();\n }\n }\n\n /**\n * Start the runtime: `true` while eligible and started or scheduled for DOM\n * readiness, `false` once destroyed or outside a preview context.\n */\n start(): boolean {\n if (this.#destroyed) return false;\n if (this.#started) {\n // A deferred DOM-ready startup can fail after this returned and roll\n // itself back; this call retries it.\n this.#runtime.start();\n return true;\n }\n if (!isInPreviewContext()) return false;\n const started = this.#runtime.start();\n if (started) this.#started = true;\n return started;\n }\n\n /**\n * Release the message ingress, keeping plugins and renderers, for `pagehide`:\n * a bfcache restore re-runs no script, so an attached client would return\n * bound to a frozen page. `false` when nothing was running.\n */\n suspend(): boolean {\n if (this.#destroyed || !this.#started) return false;\n return this.#runtime.suspend();\n }\n\n /** Reacquire after `suspend()`: the same path as `start()`, because a restored document needs the same rebuild. */\n resume(): boolean {\n if (this.#destroyed || !this.#started) return false;\n return this.#runtime.start();\n }\n\n /** Stop the runtime and tear down every plugin. Idempotent; concurrent callers share one promise. */\n destroy(): Promise<void> {\n if (this.#destroyPromise !== null) return this.#destroyPromise;\n this.#destroyed = true;\n let resolveDestroy!: () => void;\n let rejectDestroy!: (reason: unknown) => void;\n const inFlight = new Promise<void>((resolve, reject) => {\n resolveDestroy = resolve;\n rejectDestroy = reject;\n });\n // Published before the teardown: a `destroy` handler calling destroy()\n // re-entrantly must get this same promise.\n this.#destroyPromise = inFlight;\n const finish = (): void => {\n this.#emitter.removeAllListeners();\n this.#tornDown = true;\n };\n try {\n this.#runtime.destroy();\n void this.#plugins.destroyAll().finally(finish).then(resolveDestroy, rejectDestroy);\n } catch (error) {\n finish();\n rejectDestroy(error);\n }\n return inFlight;\n }\n\n async use(plugin: LivePreviewPlugin): Promise<void> {\n if (this.#destroyed) throw new Error('LivePreviewClient: already destroyed');\n await this.#plugins.register(plugin);\n }\n\n /** Unregister a plugin and release everything its registration owned. Still allowed from a destroy hook during teardown. */\n async unuse(name: string): Promise<void> {\n if (this.#tornDown) throw new Error('LivePreviewClient: already destroyed');\n await this.#plugins.unregister(name);\n }\n\n /** Re-scan bindings after replacing markup without crossing a navigation boundary. */\n refreshCache(): void {\n this.#runtime.refreshCache();\n }\n\n /** Re-scan bindings and locally replay the last accepted document after a router commit. */\n refreshAfterNavigation(): void {\n this.#runtime.navigationCommit();\n }\n\n get events(): EventEmitter {\n return this.#emitter;\n }\n\n /** Names of the registered plugins. */\n get plugins(): readonly string[] {\n return this.#plugins.list();\n }\n\n get status(): 'disconnected' | 'connecting' | 'connected' {\n return this.#runtime.status;\n }\n\n /**\n * Point-in-time read of runtime state, no I/O: `bindings.orphanFields` when a\n * field refuses to update, `scheduler.deferred` when updates stop below the fold.\n */\n inspect(): LivePreviewInspection {\n return { ...this.#runtime.inspect(), plugins: this.#plugins.snapshot() };\n }\n\n /** Number of accepted updates so far. */\n get updateCount(): number {\n return this.#runtime.updateCount;\n }\n\n /** `true` once `destroy()` has been called. */\n get destroyed(): boolean {\n return this.#destroyed;\n }\n}\n\n/** A started client, or `null` when the page is not a preview context. */\nexport function initLivePreview(config: LivePreviewClientConfig = {}): LivePreviewClient | null {\n const client = new LivePreviewClient({ ...config, autoStart: false });\n return client.start() ? client : null;\n}\n\nexport type { LivePreviewClientConfig } from './config';\n","/**\n * `LivePreviewClient` configuration. Defaults are the 2.0 rows; `defaults: 'v1'`\n * restores the 1.x values named per option (ADR 0007).\n */\n\nimport type { CachedElement, FieldRenderer, RendererKey, RichTextRenderer } from '@core/types';\nimport type { StrategyHandlers } from '@core/strategies';\nimport {\n runtimeDefaultsFor,\n type DefaultsProfile,\n type EventSourcePolicy,\n} from '@/types/defaults-profile';\n\nexport interface LivePreviewClientConfig {\n /** Explicit trusted admin origins. */\n readonly allowedOrigins?: readonly string[];\n /** Payload origin; every update is then re-fetched through the REST API so relations arrive populated. Requires `mergeDepth`. */\n readonly serverURL?: string;\n /** REST route prefix used with `serverURL`. Default `/api`. */\n readonly apiRoute?: string;\n /** Population depth used with `serverURL`. Required with it; `defaults: 'v1'` falls back to `1`. */\n readonly mergeDepth?: number;\n /** Milliseconds the `serverURL` merge may wait before the update shows its raw values. Off by default. */\n readonly mergeTimeoutMs?: number;\n /** The route of a Lexical internal link with no `url` of its own, as `/{locale}/{slug}/`. */\n readonly internalLinkPattern?: string;\n /** Hold a route render until Payload reports the save: the route shows what is saved. */\n readonly routeAfterSave?: boolean;\n /** Custom fetch for the `serverURL` merge request: attach auth headers or route through a proxy. */\n readonly mergeFetch?: typeof fetch;\n /** Verbose console output. Defaults to dev-mode detection. */\n readonly debug?: boolean;\n /** Debounce window for incoming updates. Default 50 ms. */\n readonly debounceMs?: number;\n /** Heartbeat timeout in ms; `0` disables it (default), because the admin posts only on edits. */\n readonly heartbeatMs?: number;\n /** IntersectionObserver `rootMargin`. Default `200px`. */\n readonly intersectionRootMargin?: string;\n /** Update only bindings under a matching `data-payload-owner`; an unowned binding is then never updated. Default `false`. */\n readonly scopeBindingsByOwner?: boolean;\n /** Skip a binding whose value did not change. Default `true`; `defaults: 'v1'` sets `false`. */\n readonly skipUnchanged?: boolean;\n /** Scroll the preview to the field being edited when its value changes. Default `false`. */\n readonly revealEditedField?: boolean;\n /**\n * Find bindings by value on the connection's first message: a scalar whose\n * value is the whole content of exactly one element is bound to it as if\n * `data-payload-field` stood there; every guess is stamped `data-payload-guessed`\n * and listed in `inspect().bindings.guessed`. Default `'off'`.\n */\n readonly autoBind?: 'off' | 'unique';\n /**\n * How a group counts as covered (ADR 0022). `'descendant'` (default): one\n * bound path inside it covers all of it. `'declared'`: each changed path\n * inside such a group needs its own binding or a `data-payload-covers`\n * declaration; an uncovered one is an unbound change.\n */\n readonly subfieldCoverage?: 'descendant' | 'declared';\n /** Fields whose change re-applies other bindings regardless of their own value: `{ price: ['priceLabel'] }`. Used with `skipUnchanged`. */\n readonly dependencies?: Readonly<Record<string, readonly string[]>>;\n /** Strategy handlers beyond patching; `createFragmentStrategy()` from `payload-live-preview/fragment` builds one. */\n readonly strategies?: StrategyHandlers;\n /** Apply every update regardless of visibility. Default `false`. */\n readonly disableVisibilityGate?: boolean;\n /** Cache size above which off-screen updates wait for intersection. Default `50`. */\n readonly visibilityGateThreshold?: number;\n /** Mount an `aria-live` region for connections, applied updates and heartbeat disconnects. Default `true`. */\n readonly enableA11y?: boolean;\n /** Locale of the announcement strings. Defaults to the detected locale. */\n readonly a11yLocale?: string;\n /** Document root. Default `document`. */\n readonly root?: Document | Element;\n /** Renderer resolution ahead of the registry; return `undefined` to fall through. */\n readonly resolveRenderer?: (\n fieldType: RendererKey,\n target: CachedElement,\n ) => FieldRenderer | undefined;\n /** The project's rich-text renderer, shared with SSR. Its output is sanitized. */\n readonly renderRichText?: RichTextRenderer;\n /** Ignore `document.referrer` as an origin source. Default `true`; `defaults: 'v1'` sets `false`. */\n readonly disableReferrerDetection?: boolean;\n /** Disable the dev-mode localhost matcher. Default `false`. */\n readonly disableLocalhostMatching?: boolean;\n /** Which windows may post updates. Default `'parent-or-opener'`; `defaults: 'v1'` sets `'any'`. */\n readonly eventSourcePolicy?: EventSourcePolicy;\n /**\n * Sanitizer policy for this client's rich text and HTML writes. Default\n * `'strict'`; `defaults: 'v1'` sets `'compat'`. Per instance: it leaves the\n * process default that `setSanitizerPolicy()` sets for direct `sanitizeHtml()` calls alone.\n */\n readonly sanitizerPolicy?: 'compat' | 'strict';\n /** `'v2'` (default) is the 2.0 table; `'v1'` restores every 1.x row at once. Explicit options win. */\n readonly defaults?: DefaultsProfile;\n /** Start the runtime in the constructor. Default `true`. */\n readonly autoStart?: boolean;\n /** Preview-token validator; every update must then carry a `previewToken` it approves. Stock Payload sends none. */\n readonly validateToken?: (\n token: string | undefined,\n origin: string,\n ) => boolean | Promise<boolean>;\n}\n\n/** The configuration with the `defaults` profile applied: explicit options win, `'v1'` changes nothing. */\nexport function withProfileDefaults(config: LivePreviewClientConfig): LivePreviewClientConfig {\n // `'v1'` fills the rows too: the runtime's own fallbacks are the 2.0 values\n // since the default flip, so leaving the config alone would hand a v1 client\n // the strict sanitizer and `skipUnchanged` it opted out of.\n const rows = runtimeDefaultsFor(config.defaults);\n return {\n ...config,\n skipUnchanged: config.skipUnchanged ?? rows.skipUnchanged,\n disableReferrerDetection: config.disableReferrerDetection ?? rows.disableReferrerDetection,\n eventSourcePolicy: config.eventSourcePolicy ?? rows.eventSourcePolicy,\n sanitizerPolicy: config.sanitizerPolicy ?? rows.sanitizerPolicy,\n };\n}\n","/**\n * The one rule shared by the adapters, the client and the inline generator:\n * `serverURL` needs an explicit `mergeDepth` under the 2.0 defaults (ADR 0007,\n * entry 10). It lives in the leaf `types` domain because the inline generator\n * is server-side code that may not reach the browser runtime in `core`, and\n * three copies of the check had already drifted in what they treated as\n * \"no server\" and \"no depth\".\n */\n\nimport type { DefaultsProfile } from '@/types/defaults-profile';\n\n/**\n * The population depth is a deliberate choice; the 1.x default of 1 stays only\n * behind `defaults: 'v1'`. An empty `serverURL` fetches nothing and owes no\n * depth; `null` counts as omitted because the inline wire config carries it.\n */\nexport function assertMergeDepthExplicit(options: {\n readonly defaults?: DefaultsProfile | undefined;\n readonly serverURL?: string | undefined;\n readonly mergeDepth?: number | null | undefined;\n}): void {\n if (options.defaults === 'v1') return;\n if ((options.serverURL ?? '') === '' || options.mergeDepth != null) return;\n throw new Error(\n 'payload-live-preview: `serverURL` needs an explicit `mergeDepth` under the 2.0 defaults — ' +\n \"choose the population depth deliberately (0 for none), or pass `defaults: 'v1'` to keep \" +\n 'the 1.x default of 1 while migrating (ADR 0007, entry 10).',\n );\n}\n","/**\n * Admin-side reporter for \"reveal the edited section\": it names the field the\n * editor's cursor is in so the preview scrolls there without a keystroke.\n */\n\n/** The preview window (usually `iframe.contentWindow`) messages are posted to. */\nexport interface FocusReportTarget {\n postMessage: (message: unknown, targetOrigin: string) => void;\n}\n\n/** @internal */\nexport interface PreviewFocusMessage {\n readonly type: 'payload-live-preview-focus';\n readonly field: string;\n}\n\n/** Post one focus report. `targetOrigin` must be the preview's exact origin, never `'*'`. */\nexport function reportPreviewFocus(\n target: FocusReportTarget,\n field: string,\n targetOrigin: string,\n): void {\n if (field.length === 0) return;\n const message: PreviewFocusMessage = { type: 'payload-live-preview-focus', field };\n target.postMessage(message, targetOrigin);\n}\n\n/** A reporter bound to a preview window and origin; `resolveTarget` runs per report, so a re-created iframe is addressed freshly. */\nexport function createPreviewFocusReporter(\n resolveTarget: () => FocusReportTarget | null | undefined,\n targetOrigin: string,\n): (field: string) => void {\n return (field: string): void => {\n const target = resolveTarget();\n if (target === null || target === undefined) return;\n reportPreviewFocus(target, field, targetOrigin);\n };\n}\n","/**\n * Every diagnostic code the runtime and tools emit, so a consumer can branch\n * on `e.code` instead of matching message text. A code is never reused for a\n * different meaning; a retired one stays reserved.\n *\n * Browser-side reporting sites write the literal (`code: 'LP0603'`) rather than\n * reading it from this record: the frozen table would then ship in the inline\n * runtime for the sake of six characters — it did, 1 287 B in every page, for\n * the one read Z6 left in the strategy runner, and `diagnostic-codes.test.ts`\n * now holds the artifact free of it. Server-side tools may import it.\n */\n\n/**\n * Every diagnostic code the runtime can report, by name.\n *\n * ```ts\n * client.events.on('error', (e) => {\n * if (e.code === DIAGNOSTIC_CODES.TransformThrew) reportToSentry(e.error);\n * });\n * ```\n */\nexport const DIAGNOSTIC_CODES = Object.freeze({\n /** No trusted origin configured in production; nothing will be accepted. */\n NoTrustedOrigin: 'LP0101',\n /** Origin trust rests on `document.referrer`, so any framing site is trusted. */\n ReferrerOnlyTrust: 'LP0102',\n /** A plugin declares a runtime range this runtime does not satisfy; it was refused. */\n PluginIncompatible: 'LP0103',\n /** The page carries the lean runtime and needs a feature that profile leaves out. */\n ProfileFeatureOmitted: 'LP0104',\n\n /** An update named an empty field with no binding anchor on the page; an edit to it has nowhere to land. */\n OrphanField: 'LP0201',\n /** Owner scoping is on and the update names no document it could belong to. */\n UnattributableUpdate: 'LP0202',\n /** An update carried a value for a field the page binds nowhere; editing it changes nothing on this page. */\n UnboundField: 'LP0203',\n /** In development: a bound path covers its group under the `descendant` default, which 3.0 changes. */\n CoverageDefaultChanges: 'LP0204',\n\n /** The visibility gate held offscreen writes back until they scroll into view. */\n VisibilityGateDeferred: 'LP0301',\n\n /** A value was refused because the attribute or the value itself is unsafe. */\n UnsafeAttributeWrite: 'LP0401',\n /** A text element has structured children, so replacing its text was skipped. */\n TextTargetHasChildren: 'LP0402',\n /** A structural container has no array template, so the update was skipped. */\n MissingArrayTemplate: 'LP0403',\n /** A structural item has no `id`; it pairs positionally, so an insert re-renders every row after it. */\n StructuralItemUnkeyed: 'LP0404',\n /** Two structural items share a key; later ones pair positionally. */\n StructuralDuplicateKey: 'LP0405',\n /** Every structural key changed while the length did not; the source generates keys per message. */\n StructuralUnstableKeys: 'LP0406',\n /** A binding asks for a delivery strategy this release does not have; it is left unchanged. */\n UnsupportedStrategy: 'LP0407',\n /** `data-payload-format` names a format the vocabulary does not contain; the default formatting was used instead. */\n UnknownValueFormat: 'LP0408',\n /** The strict sanitizer removed an attribute the 1.x `'compat'` policy kept. */\n SanitizerDroppedAttribute: 'LP0409',\n /** A Lexical block has no renderer; the markup the server rendered for it is kept instead. */\n UnrenderedBlockKept: 'LP0410',\n /** A patch cannot reach what the server would have drawn; `onUnfaithfulPatch` decided what happens next. */\n UnfaithfulPatch: 'LP0411',\n /** The first write to a date, number, checkbox, select or radio binding replaced a different reading of the same value. */\n ServerFormatReplaced: 'LP0412',\n /** A Lexical block has no renderer, and the write could not keep the markup the server rendered for it; it is gone. */\n UnrenderedBlockLost: 'LP0413',\n\n /** A message was rejected before it reached the update pipeline. */\n MessageRejected: 'LP0501',\n /** A preview token was rejected. */\n TokenRejected: 'LP0502',\n /** A trusted origin sent a message this protocol version does not recognise. */\n ProtocolShapeUnknown: 'LP0503',\n\n /** A consumer event handler threw. */\n HandlerThrew: 'LP0601',\n /** A consumer transform threw; the original value was kept. */\n TransformThrew: 'LP0602',\n /** A renderer threw while writing a value. */\n RendererThrew: 'LP0603',\n // LP0604 is reserved and unassigned; codes are never reused or renumbered.\n /** Runtime startup failed. */\n StartupFailed: 'LP0605',\n /** Sending the ready handshake failed. */\n ReadyFailed: 'LP0606',\n /** The page declared hydration, but no React commit, Vue mount, SvelteKit mount or `markHydrated()` call came within the cap; the runtime started without waiting. */\n HydrationWaitTimedOut: 'LP0607',\n\n /** The audit found no runtime in a response that carried preview intent. */\n AuditRuntimeMissing: 'LP0701',\n /** The preview response declares no `frame-ancestors`. */\n AuditNoFrameAncestors: 'LP0702',\n /** `X-Frame-Options` forbids framing on a response that declares no `frame-ancestors`; `SAMEORIGIN` forbids it from another origin only. */\n AuditFrameOptionsBlocks: 'LP0703',\n /** Binding attributes are served to anonymous visitors. */\n AuditBindingsExposed: 'LP0704',\n /** More bindings than the visibility gate will write eagerly. */\n AuditGateThresholdExceeded: 'LP0705',\n /** Owner markers exist, but some bindings are outside all of them. */\n AuditUnownedBindings: 'LP0706',\n /** The preview response carries no bindings and no fragment boundary. */\n AuditNoBindings: 'LP0707',\n /** The URL did not return an HTML page, so nothing else can be judged. */\n AuditNotAPage: 'LP0708',\n /** A fragment request failed (network, timeout, server error); the boundary was patched instead. */\n FragmentRequestFailed: 'LP0801',\n /** The fragment response had the wrong content type or shape; the boundary was patched instead. */\n FragmentResponseInvalid: 'LP0802',\n /** The fragment endpoint refused the preview (not authorized); the boundary was patched instead. */\n FragmentUnauthorized: 'LP0803',\n /** A fragment response arrived for a revision that was already superseded and was discarded. */\n FragmentSuperseded: 'LP0804',\n /** A route refresh was refused: the loop guard, or the strategy's minimum interval. */\n RouteRefreshLoop: 'LP0805',\n /** A boundary asks for the fragment strategy but no fragment handler is configured; it is patched. */\n FragmentStrategyUnavailable: 'LP0806',\n /** A revision changed a field with no binding; `onUnfaithfulPatch` refreshed the route. */\n UnboundChangeRefresh: 'LP0807',\n /** `onUnfaithfulPatch: 'escalate'` found no route or fragment strategy, or no boundary, to hand an unfaithful patch to; the page keeps it. */\n EscalationUnavailable: 'LP0808',\n /** A fragment inserted an Astro island the page cannot start: it never loaded the island element or that client directive. */\n IslandStartUnavailable: 'LP0809',\n /** The host's route refresh returned no promise, so the revision was re-applied before the host committed. */\n RouteRefreshUnconfirmed: 'LP0810',\n /** A readiness row is not yet at its 2.0 value; `pll doctor --v2` reports it. */\n V2ReadinessGap: 'LP0709',\n /** The preview runtime is served to anonymous visitors, not only inside the admin frame. */\n RuntimeOnPublicPage: 'LP0710',\n /** An element carries attributes that only mean something beside `data-payload-field`, and has none. */\n AuditModifierWithoutField: 'LP0711',\n} as const);\n\n/** A diagnostic code, as it appears in log output and on the `error` event. */\nexport type DiagnosticCode = (typeof DIAGNOSTIC_CODES)[keyof typeof DIAGNOSTIC_CODES];\n","/**\n * The seam between a host framework's own router and the route strategy.\n *\n * The route strategy answers a revision by fetching the route and morphing it\n * into the living page. On a page whose DOM belongs to a reconciler that is\n * working against the framework, and it was seen to break once: `removeChild`\n * on `null` inside React's commit phase, over markup this package had patched.\n * A host that re-renders the route itself does the same job without the morph\n * and without the second HTML request, so it is given the chance to.\n *\n * Why a named slot on `window` and not a reference: the runtime is an inline\n * script that builds its strategy before any application code has hydrated, so\n * there is nothing to hand a component; `window.__livePreview`, the only other\n * public surface, is created later and not at all outside a preview; and the\n * two richer extension points — plugins and events — are reachable only through\n * the programmatic client, which a page using an adapter does not have. One\n * slot, written by whoever mounts and read at the moment of a refresh, is the\n * smallest thing that survives both orders of arrival.\n */\n\n/**\n * A host's own route refresh. It must settle once the fresh markup is\n * committed: the runtime re-applies the revision on top of it, and doing that\n * against the markup being replaced would write into nodes about to be dropped.\n * A function that returns nothing is taken as already committed; the route\n * strategy says once that it could not wait (LP0810), and 3.0 requires the\n * promise (ADR 0028).\n */\nexport type RouteRefresh = () => void | Promise<void>;\n\n/** Read late, so it does not matter whether the runtime or the component came first. */\nconst SLOT = '__livePreviewRouteRefresh';\n\ntype WindowSlot = Record<string, RouteRefresh | undefined>;\n\nfunction slot(): WindowSlot | undefined {\n return typeof window === 'undefined' ? undefined : (window as unknown as WindowSlot);\n}\n\n/**\n * Lend the runtime the host's route refresh; the return value undoes it, for a\n * component's cleanup. A later registration wins, and undoing one that has\n * already been replaced does nothing — two components on one page would\n * otherwise take the slot from each other on unmount.\n */\nexport function registerRouteRefresh(refresh: RouteRefresh): () => void {\n const target = slot();\n if (target === undefined) return () => undefined;\n target[SLOT] = refresh;\n return () => {\n // Cleared rather than deleted: the slot is read through `?.` anyway, and\n // removing the key buys nothing a lint rule would not have to be argued out of.\n if (target[SLOT] === refresh) target[SLOT] = undefined;\n };\n}\n\n/** The registered refresh, or `undefined` on a page that registered none. */\nexport function readRouteRefresh(): RouteRefresh | undefined {\n return slot()?.[SLOT];\n}\n"],"mappings":"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","ignoreList":[]}
|