Rebuild invalidated retained component anchors
This commit is contained in:
parent
d636b63e04
commit
00918de9d4
@ -3460,10 +3460,20 @@ The candidate uses resolved VALUE, DEPS, and NODES."
|
|||||||
(car output-range))))
|
(car output-range))))
|
||||||
(etaf-runtime-candidate-artifacts runtime))
|
(etaf-runtime-candidate-artifacts runtime))
|
||||||
(push identity (etaf-runtime-candidate-rendered-identities runtime))
|
(push identity (etaf-runtime-candidate-rendered-identities runtime))
|
||||||
(list candidate
|
(let ((committed-artifact
|
||||||
(gethash (etaf--semantic-component-artifact-key committed)
|
(and (etaf--semantic-component-artifact-key committed)
|
||||||
(etaf-runtime-artifact-registry runtime))
|
(gethash (etaf--semantic-component-artifact-key committed)
|
||||||
(gethash effect-id (etaf-runtime-candidate-artifacts runtime))))))
|
(etaf-runtime-artifact-registry runtime)))))
|
||||||
|
;; Descendant-only publications invalidate cached ancestor artifacts
|
||||||
|
;; while retaining the ancestor semantic tree. When that ancestor
|
||||||
|
;; becomes dirty on a later turn, rebuild its committed backend anchor
|
||||||
|
;; from the immutable generation before diffing the new render.
|
||||||
|
(unless committed-artifact
|
||||||
|
(setq committed-artifact
|
||||||
|
(etaf--runtime-rebuild-component-artifact runtime committed)))
|
||||||
|
(list candidate committed-artifact
|
||||||
|
(gethash effect-id
|
||||||
|
(etaf-runtime-candidate-artifacts runtime)))))))
|
||||||
|
|
||||||
(defun etaf--runtime-render-dirty-range (runtime effect range)
|
(defun etaf--runtime-render-dirty-range (runtime effect range)
|
||||||
"Evaluate RUNTIME dirty RANGE EFFECT without running its Component owner."
|
"Evaluate RUNTIME dirty RANGE EFFECT without running its Component owner."
|
||||||
|
|||||||
@ -86,6 +86,8 @@
|
|||||||
(defvar etaf-test-transparent-parent-renders 0)
|
(defvar etaf-test-transparent-parent-renders 0)
|
||||||
(defvar etaf-test-transparent-inner-renders 0)
|
(defvar etaf-test-transparent-inner-renders 0)
|
||||||
(defvar etaf-test-transparent-outer-renders 0)
|
(defvar etaf-test-transparent-outer-renders 0)
|
||||||
|
(defvar etaf-test-ancestor-parent-source nil)
|
||||||
|
(defvar etaf-test-ancestor-child-source nil)
|
||||||
(defvar etaf-test-context-provider-source nil)
|
(defvar etaf-test-context-provider-source nil)
|
||||||
(defvar etaf-test-context-provider-renders 0)
|
(defvar etaf-test-context-provider-renders 0)
|
||||||
(defvar etaf-test-context-consumer-renders 0)
|
(defvar etaf-test-context-consumer-renders 0)
|
||||||
@ -594,6 +596,19 @@
|
|||||||
"Place a transparent Component chain in one material parent."
|
"Place a transparent Component chain in one material parent."
|
||||||
:view (column (etaf-test-transparent-outer)))
|
:view (column (etaf-test-transparent-outer)))
|
||||||
|
|
||||||
|
(etaf-define-component etaf-test-ancestor-artifact-child ()
|
||||||
|
"Render a child whose local update invalidates ancestor artifacts."
|
||||||
|
:view
|
||||||
|
(text (expr :value
|
||||||
|
(if (etaf-value etaf-test-ancestor-child-source)
|
||||||
|
"detail" "child"))))
|
||||||
|
|
||||||
|
(etaf-define-component etaf-test-ancestor-artifact-parent ()
|
||||||
|
"Render a parent that can update after one descendant-only publication."
|
||||||
|
:view
|
||||||
|
(column :bgcolor (etaf-value etaf-test-ancestor-parent-source)
|
||||||
|
(etaf-test-ancestor-artifact-child)))
|
||||||
|
|
||||||
(etaf-define-component etaf-test-generation-context-consumer ()
|
(etaf-define-component etaf-test-generation-context-consumer ()
|
||||||
"Render one generation-owned Context dependency."
|
"Render one generation-owned Context dependency."
|
||||||
:setup
|
:setup
|
||||||
@ -3813,6 +3828,35 @@ Event composition is a Runtime contract, not a UI-library helper contract."
|
|||||||
(etaf-unmount runtime))
|
(etaf-unmount runtime))
|
||||||
(when-let ((buffer (get-buffer buffer-name))) (kill-buffer buffer)))))
|
(when-let ((buffer (get-buffer buffer-name))) (kill-buffer buffer)))))
|
||||||
|
|
||||||
|
(ert-deftest etaf-runtime-parent-rerender-rebuilds-invalidated-artifact ()
|
||||||
|
"Rebuild a committed parent anchor after a descendant-only publication."
|
||||||
|
(let ((buffer-name " *etaf-ancestor-artifact-test*")
|
||||||
|
(etaf-test-ancestor-parent-source (etaf-ref "light"))
|
||||||
|
(etaf-test-ancestor-child-source (etaf-ref nil)))
|
||||||
|
(unwind-protect
|
||||||
|
(progn
|
||||||
|
(etaf-mount buffer-name
|
||||||
|
(etaf-view (etaf-test-ancestor-artifact-parent)))
|
||||||
|
(setf (etaf-value etaf-test-ancestor-child-source) t)
|
||||||
|
(let* ((runtime (etaf-runtime-for-buffer buffer-name))
|
||||||
|
(generation (etaf-runtime-current-generation runtime))
|
||||||
|
(parent
|
||||||
|
(etaf--generation-semantic
|
||||||
|
generation '(etaf-test-ancestor-artifact-parent (root)))))
|
||||||
|
(should (etaf--semantic-component-p parent))
|
||||||
|
(should-not (etaf--semantic-component-artifact-key parent))
|
||||||
|
(setf (etaf-value etaf-test-ancestor-parent-source) "dark")
|
||||||
|
(should (equal
|
||||||
|
(plist-get
|
||||||
|
(etaf-runtime-host-props-for
|
||||||
|
runtime '(etaf-host (root :view)))
|
||||||
|
:bgcolor)
|
||||||
|
"dark"))))
|
||||||
|
(when-let ((runtime (etaf-runtime-for-buffer buffer-name)))
|
||||||
|
(etaf-unmount runtime))
|
||||||
|
(when-let ((buffer (get-buffer buffer-name)))
|
||||||
|
(kill-buffer buffer)))))
|
||||||
|
|
||||||
(ert-deftest etaf-runtime-context-provider-promotes-consumer-atomically ()
|
(ert-deftest etaf-runtime-context-provider-promotes-consumer-atomically ()
|
||||||
"Promote Context provider/consumer frames only with their generation."
|
"Promote Context provider/consumer frames only with their generation."
|
||||||
(let ((buffer-name " *etaf-generation-context-test*")
|
(let ((buffer-name " *etaf-generation-context-test*")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user