///
/**
* TEST PATTERN: computed() and derive() Are The Same Thing
*
* CLAIM: computed() and derive() are functionally identical
* SOURCE: folk_wisdom/reactivity.md
*
* WHAT THIS TESTS:
* - Creating a derived value with computed()
* - Creating an equivalent derived value with derive()
* - Both update when dependencies change
* - Both produce the same output values
*
* FRAMEWORK CODE EVIDENCE:
* In packages/runner/src/builder/module.ts:227-228:
* export const computed = (fn: () => T) => lift(fn)(undefined);
*
* computed() is literally implemented as lift(fn)(undefined), which is
* exactly how derive() works but with no input dependencies.
*
* EXPECTED BEHAVIOR:
* Two side-by-side displays showing that computed and derive produce
* identical values and update in lockstep.
*
* MANUAL VERIFICATION STEPS:
* 1. Load the pattern
* 2. See that both computed and derive show the same initial value
* 3. Change the first name input
* 4. Verify BOTH values update identically
* 5. Change the last name input
* 6. Verify BOTH values update identically
*/
import {
Cell,
computed,
Default,
derive,
handler,
NAME,
pattern,
UI,
} from "commontools";
interface TestInput {
firstName: Default;
lastName: Default;
age: Default;
}
const updateNames = handler<
unknown,
{ firstName: Cell; lastName: Cell }
>((_event, { firstName, lastName }) => {
const names = ["Alice", "Bob", "Charlie", "Diana"];
const randomName = names[Math.floor(Math.random() * names.length)];
firstName.set(randomName);
lastName.set(`Smith-${Date.now() % 1000}`);
});
export default pattern(({ firstName, lastName, age }) => {
// Using computed() - transformer extracts captured values, unwraps them
// No .get() needed - values are already unwrapped by transformer
const computedFullName = computed(
() => `${firstName} ${lastName} (age ${age})`,
);
// Using derive() with no explicit deps - same behavior as computed
// Transformer also extracts and unwraps captured values
const deriveFullName = derive(
{},
() => `${firstName} ${lastName} (age ${age})`,
);
// Using derive() with explicit deps - also equivalent
// Parameters are explicitly unwrapped
const deriveWithDeps = derive(
{ fn: firstName, ln: lastName, a: age },
({ fn, ln, a }) => `${fn} ${ln} (age ${a})`,
);
return {
[NAME]: "Test: computed() = derive()",
[UI]: (
computed() and derive() Equivalence Test
Inputs
Randomize Names
computed()
{computedFullName}
derive({"{}"}, fn)
{deriveFullName}
derive(deps, fn)
{deriveWithDeps}
What to observe:
All three values are IDENTICAL
Changing any input updates ALL THREE simultaneously
This proves computed() and derive() use the same underlying
mechanism (lift)
Framework code: computed() is implemented as{" "}
lift(fn)(undefined)