Skip to content

Commit

Permalink
Adds cached example.
Browse files Browse the repository at this point in the history
  • Loading branch information
dgp1130 committed Dec 28, 2023
1 parent 62dd19d commit 2ef0301
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/demo/reactivity/cached-value.test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<title>`cached-value` tests</title>
<meta charset="utf8">
</head>
<body></body>
</html>
74 changes: 74 additions & 0 deletions src/demo/reactivity/cached-value.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { parseHtml } from 'hydroactive/testing.js';
import { CachedValue } from './cached-value.js';

describe('cached-value', () => {
afterEach(() => {
for (const node of document.body.childNodes) node.remove();
});

function render({ count }: { count: number }) {
return parseHtml(CachedValue, `
<cached-value>
<div>The current count is: <span id="count">${count}</span>.</div>
<div>Pi computed to that many decimal places is:
<span id="pi">${computePiWithPrecision(count)}</span>.
</div>
<div>
Pi is still:
<span id="pi-again">${computePiWithPrecision(count)}</span>.
</div>
<button>+</button>
</cached-value>
`);
}

function computePiWithPrecision(precision: number): string {
const length = '3.'.length + precision;
return Math.PI.toFixed(48).slice(0, length).padEnd(length, '0');
}

describe('CachedValue', () => {
it('does not re-render on hydration', async () => {
const el = render({ count: 5 });
document.body.appendChild(el);

await el.stable();

expect(el.querySelector('#count')!.textContent).toBe('5');
expect(el.querySelector('#pi')!.textContent).toBe('3.14159');
expect(el.querySelector('#pi-again')!.textContent).toBe('3.14159');
});

it('increments on click', async () => {
const el = render({ count: 5 });
document.body.appendChild(el);

(el.querySelector('button')! as HTMLElement).click();

await el.stable();

expect(el.querySelector('#count')!.textContent).toBe('6');
expect(el.querySelector('#pi')!.textContent).toBe('3.141592');
expect(el.querySelector('#pi-again')!.textContent).toBe('3.141592');
});

it('reuses the PI computation', async () => {
const consoleSpy = spyOn(console, 'log');

const el = render({ count: 5 });
document.body.appendChild(el);

await el.stable();

expect(consoleSpy)
.toHaveBeenCalledOnceWith('Computing PI to 5 digits...');
consoleSpy.calls.reset();

(el.querySelector('button')! as HTMLElement).click();
await el.stable();

expect(consoleSpy)
.toHaveBeenCalledOnceWith('Computing PI to 6 digits...');
});
});
});
36 changes: 36 additions & 0 deletions src/demo/reactivity/cached-value.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { defineComponent } from 'hydroactive';
import { cached } from 'hydroactive/signals.js';

/** Uses `cached` to avoid repeatedly executing an expensive computed signal. */
export const CachedValue = defineComponent('cached-value', (comp) => {
const count = comp.live('#count', Number);
comp.listen('button', 'click', () => { count.set(count() + 1); });

// Define a computed with `cached` to cache the result. No matter how many
// times `pi()` is called, the result will be reused as long as `count` does
// not change.
const pi = cached(() => {
console.log(`Computing PI to ${count()} digits...`);
return computePiWithPrecision(count());
});

// `pi` is read twice here, and both will update automatically, but it will
// only be computed once.
comp.bind('#pi', () => pi());
comp.bind('#pi-again', () => pi());
});

declare global {
interface HTMLElementTagNameMap {
'cached-value': InstanceType<typeof CachedValue>;
}
}

/**
* Pretend this is computationally expensive and we don't want to run it more
* than we need to.
*/
function computePiWithPrecision(precision: number): string {
const length = '3.'.length + precision;
return Math.PI.toFixed(48).slice(0, length).padEnd(length, '0');
}
15 changes: 15 additions & 0 deletions src/demo/reactivity/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,20 @@ <h2>Computed Value</h2>

<script src="./computed-value.js" type="module"></script>
</computed-value>

<cached-value>
<h2>Cached Value</h2>

<div>The current count is: <span id="count">10</span>.</div>
<div>Pi computed to that many decimal places is:
<span id="pi">3.141592653</span>.
</div>
<div>
Pi is still: <span id="pi-again">3.141592653</span>.
</div>
<button>+</button>

<script src="./cached-value.js" type="module"></script>
</cached-value>
</body>
</html>

0 comments on commit 2ef0301

Please sign in to comment.