All Challenges
4 PointsIntermediateReactive Architecture
00:00
Reactive Signal, Computed & Effect Engine from Scratch
Build a fine-grained reactive primitives system (Signals, Computed Signals, and Auto-Tracking Effects) with dependency graph cleanup and microtask batching.
### Problem Overview
Modern frontend frameworks (Angular Signals, SolidJS, Vue Reactivity, Preact Signals) rely on fine-grained reactivity.
Your goal is to build the core reactive primitives from scratch: `signal()`, `computed()`, and `effect()`.
### Functional Requirements
1. **`createSignal<T>(initialValue: T): [() => T, (nextValue: T | ((prev: T) => T)) => void]`**:
- Returns a getter that automatically registers the active running effect as a subscriber.
- Returns a setter that triggers registered subscribers when the value changes (`Object.is` equality check).
2. **`createComputed<T>(fn: () => T): () => T`**:
- Lazy evaluation: only recalculates when dependencies change.
- Memoizes the calculated value.
3. **`createEffect(fn: () => void | (() => void)): () => void`**:
- Automatically tracks all signals accessed during execution.
- Re-runs whenever any dependency updates.
- Supports cleanup functions returned from previous effect executions.
4. **`batch(fn: () => void): void`**:
- Batches multiple signal updates so effects only re-execute once at the end of the batch.
### Code Smell Guardrails
- **Zombie Subscriptions & Memory Leaks**: When an effect branches into different conditional logic (`if (cond) sigA() else sigB()`), unaccessed signals must be cleaned up from the dependency list!
- **Infinite Loops**: Circular dependencies must be detected or handled gracefully.
AI Review Rubric Dimensions (1–10 Points):
- Dynamic dependency subscription cleanup
- Fine-grained reactivity graph
- Batched microtask execution
- Object.is dirty checking
solution.tsTYPESCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
26 lines•738 characters•
AI Review Ready