From 5b370b69e3ffcff6c3bbb9b28e7d0b48f111fb2f Mon Sep 17 00:00:00 2001 From: giles Date: Mon, 23 Mar 2026 17:59:10 +0000 Subject: [PATCH] Fix island state preservation: revert force-dispose to dispose The ocaml branch introduced force-dispose-islands-in for outerHTML swaps, which destroyed hydrated islands (including their live signals). This broke the core hypermedia+reactive pattern: the header island's colour state was lost on navigation, and lakes weren't being morph-updated. Reverted to production behaviour: dispose-islands-in skips hydrated islands. The morph algorithm then preserves them (matching by data-sx-island name) and only morphs their lake content. Co-Authored-By: Claude Opus 4.6 (1M context) --- shared/static/scripts/sx-browser.js | 4 ++-- web/orchestration.sx | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/shared/static/scripts/sx-browser.js b/shared/static/scripts/sx-browser.js index 1835da9..5d4006a 100644 --- a/shared/static/scripts/sx-browser.js +++ b/shared/static/scripts/sx-browser.js @@ -14,7 +14,7 @@ // ========================================================================= var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } }); - var SX_VERSION = "2026-03-23T16:18:55Z"; + var SX_VERSION = "2026-03-23T17:58:42Z"; function isNil(x) { return x === NIL || x === null || x === undefined; } function isSxTruthy(x) { return x !== false && !isNil(x); } @@ -4039,7 +4039,7 @@ return processElements(t); }); return (function() { var selectSel = domGetAttr(el, "sx-select"); var content = (isSxTruthy(selectSel) ? selectFromContainer(container, selectSel) : childrenToFragment(container)); - (isSxTruthy((swapStyle == "outerHTML")) ? forceDisposeIslandsIn(target) : disposeIslandsIn(target)); + disposeIslandsIn(target); return withTransition(useTransition, function() { swapDomNodes(target, content, swapStyle); return postSwap(target); }); })(); diff --git a/web/orchestration.sx b/web/orchestration.sx index c4ef781..a5a22c6 100644 --- a/web/orchestration.sx +++ b/web/orchestration.sx @@ -292,12 +292,10 @@ (content (if select-sel (select-from-container container select-sel) (children-to-fragment container)))) - ;; Dispose old islands before swap. - ;; outerHTML replaces the target entirely — force-dispose all islands. - ;; Other swap styles (innerHTML, beforeend, etc.) may preserve islands. - (if (= swap-style "outerHTML") - (force-dispose-islands-in target) - (dispose-islands-in target)) + ;; Dispose non-hydrated islands before swap. + ;; Hydrated islands are preserved — the morph algorithm + ;; keeps their live signals and only morphs their lakes. + (dispose-islands-in target) ;; Swap (with-transition use-transition (fn ()