Skip to content

[feat]: Add option for observing external mutations#10

Closed
arielsalminen wants to merge 78 commits intomainfrom
feature/mutation-observer
Closed

[feat]: Add option for observing external mutations#10
arielsalminen wants to merge 78 commits intomainfrom
feature/mutation-observer

Conversation

@arielsalminen
Copy link
Copy Markdown
Member

@arielsalminen arielsalminen commented Mar 25, 2026

This draft PR addresses #9 by adding an opt-in observe behavior for Primitive Components.

While this improves the framework usage ergonomics in certain scenarios, I don’t think if it’s worth it to actually ship given the performance implications and complexity it adds and new edge cases it introduces. Primitive Components also default to Light DOM for progressive enhancement, which is the root cause for this limitation.

This option would only make a difference in this scenario:

  • Component has a render() method.
  • It uses the default Light DOM mode.
  • User wants to support programmatically triggering a re-render when someone is directly modifying textContent instead of the built-in text prop.

Right now, you have to do this when you want to dynamically update text of a Primitive Component after initial render:

<elena-button>Current count: 0</elena-button>

<script type="module">
  let count = 0;
  const button = document.querySelector("elena-button");

  button.addEventListener("click", () => {
    count++;
    button.text = "Current count: " + count;
  });
</script>

With the proposed changes, you could set static observe = true and also do:

<elena-button>Current count: 0</elena-button>

<script type="module">
  let count = 0;
  const button = document.querySelector("elena-button");

  button.addEventListener("click", () => {
    count++;
    button.textContent = "Current count: " + count;
  });
</script>

In a framework world, this would enable the following without having to use the text prop:

import { useState } from 'react'

export default App() {
  const [count, setCount] = useState(0)
  return (
    <elena-button onClick={() => setCount(count + 1)}>{count}</elena-button>
  )
}

Currently, we document the limitation in at least these locations:

While I am not yet convinced this should become a part of the core library, we’ll let this discussion evolve.

The fundamental tension is that this feature tries to undo what frameworks do to Light DOM. The existing text prop approach documented in the gotchas is more reliable than the one introduced here because it works WITH Elena’s prop system rather than trying to reverse-engineer external DOM mutations.

This would also probably introduce issue with Angular + Zone.js that monkey-patches MutationObserver. When Elena's observer callback in this version fires, Zone.js would see it as an async task and trigger a new change detection cycle. If that cycle re-evaluates a template binding and re-sets textContent to the same value, you could get an oscillation loop.

Another options is also perhaps addressing this with a better/clearer documentation instead? There is also the existing, undocumented possibility, that you can create a framework wrapper component that passes the children to the text prop instead.

Edit: The performance part has been improved and the tests no longer show a difference neither in initial rendering speed of up to 1000x Elena components on page or re-renders based on prop changes. But there is still the fact that when you enable observe for a component that gets repeated thousands of times in a view, this could create performance concerns.

@arielsalminen arielsalminen self-assigned this Mar 25, 2026
@arielsalminen arielsalminen added the enhancement New feature or request label Mar 25, 2026
@arielsalminen arielsalminen changed the title [feat]: observe external mutations (opt-in) [feat]: observe external mutations Mar 25, 2026
@arielsalminen arielsalminen changed the title [feat]: observe external mutations [feat]: Observe external mutations Mar 25, 2026
@arielsalminen arielsalminen added wontfix This will not be worked on and removed enhancement New feature or request labels Mar 26, 2026
@arielsalminen arielsalminen changed the title [feat]: Observe external mutations [feat]: Add option for observing external mutations Mar 27, 2026
@arielsalminen arielsalminen added enhancement New feature or request and removed wontfix This will not be worked on labels Mar 27, 2026
@arielsalminen arielsalminen added the question Further information is requested label Mar 27, 2026
@arielsalminen arielsalminen linked an issue Mar 27, 2026 that may be closed by this pull request
3 tasks
@arielsalminen arielsalminen removed the enhancement New feature or request label Mar 28, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 29, 2026

PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://elenajs.com/pr-preview/pr-10/

Built to branch gh-pages at 2026-04-13 03:23 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 31, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA c076a6f.
Ensure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice.

Scanned Files

None

@arielsalminen arielsalminen reopened this Apr 13, 2026
@netlify
Copy link
Copy Markdown

netlify bot commented Apr 14, 2026

Deploy Preview for elenajs ready!

Name Link
🔨 Latest commit c076a6f
🔍 Latest deploy log https://app.netlify.com/projects/elenajs/deploys/69de6ce1cdb69f000778d91d
😎 Deploy Preview https://deploy-preview-10--elenajs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

question Further information is requested

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat]: Support dynamic textContent with Primitive Components

1 participant