diff --git a/index.js b/index.js
index 4dfea78..fab21f1 100644
--- a/index.js
+++ b/index.js
@@ -1,3 +1,4 @@
export { registerDevtools } from './src/devtools.js';
export { LitAtom } from './integrations/lit.js';
-export { atom, selector } from './src/core.js';
\ No newline at end of file
+export { AtomLitElement } from './integrations/lit-auto.js';
+export { atom, selector } from './src/core.js';
diff --git a/integrations/lit-auto.js b/integrations/lit-auto.js
new file mode 100644
index 0000000..c3d1c22
--- /dev/null
+++ b/integrations/lit-auto.js
@@ -0,0 +1,67 @@
+import {LitElement} from 'lit-element';
+
+const reactor = Symbol();
+
+export class Reactor {
+ constructor(callback) {
+ this.callback = callback;
+ this.atoms = new Set();
+ }
+
+ dispose() {
+ for (const key of this.atoms) {
+ const found = atoms.get(key);
+ if (found) {
+ found.removeEventListener(key, this.callback);
+ }
+ }
+ }
+
+ track(fn) {
+ const originalGet = atoms.get;
+
+ atoms.get = (key) => {
+ this.atoms.add(key);
+ return originalGet.call(atoms, key);
+ };
+
+ fn();
+
+ atoms.get = originalGet;
+
+ for (const [key, atom] of atoms.entries()) {
+ if (this.atoms.has(key)) {
+ atom.addEventListener(key, this.callback);
+ }
+ }
+ }
+}
+
+export class AtomLitElement extends LitElement {
+ connectedCallback() {
+ super.connectedCallback();
+
+ this[reactor] = new Reactor(() => {
+ this.requestUpdate();
+ });
+ }
+
+ disconnectedCallback() {
+ super.disconnectedCallback();
+
+ if (this[reactor]) {
+ this[reactor].dispose();
+ this[reactor] = undefined;
+ }
+ }
+
+ update(change) {
+ const instance = this[reactor];
+
+ if (instance) {
+ instance.track(super.update.bind(this, change));
+ } else {
+ super.update(change);
+ }
+ }
+}
diff --git a/test/lit/lit.test.js b/test/lit/lit.test.js
index e9427c0..7da5478 100644
--- a/test/lit/lit.test.js
+++ b/test/lit/lit.test.js
@@ -1,7 +1,8 @@
import { expect, fixture } from '@open-wc/testing';
import { LitElement } from 'lit-element';
-import { LitAtom } from '../../src/lit.js';
+import { LitAtom } from '../../integrations/lit.js';
import { atom, selector } from '../../src/core.js';
+import { AtomLitElement } from '../../integrations/lit-auto.js';
const [count, setCount] = atom({
key: 'count',
@@ -13,7 +14,36 @@ class BasicAtom extends LitAtom(LitElement) {
}
customElements.define('basic-atom', BasicAtom);
+class AutomaticAtom extends AtomLitElement {
+ render() {
+ return html`${count.getState()}`;
+ }
+}
+customElements.define('automatic-atom', AutomaticAtom);
+
describe('lit', () => {
+ describe('auto', () => {
+ let el;
+
+ beforeEach(() => {
+ el = await fixture('');
+ });
+
+ afterEach(() => {
+ el.remove();
+ });
+
+ it('initializes correctly', () => {
+ expect(el.shadowRoot.textContent).to.equal('1');
+ });
+
+ it('updates correctly with `setCount`', async () => {
+ setCount(old => old + 1);
+ await el.updateComplete;
+ expect(el.shadowRoot.textContent).to.equal('2');
+ });
+ });
+
describe('atoms', () => {
it('initializes correctly', async () => {
const el = await fixture('');