@web-engine-dev/change-detection
Proxy-based mutation tracking for web-engine-dev. Provides automatic change detection for components and resources, enabling efficient dirty checking and reactive updates.
Features
- Automatic Tracking: JavaScript Proxy-based mutation detection
- Tick-Based System: Frame-synchronized change tracking
- Deep Tracking: Nested object mutation detection
- Mutation Events: Subscribe to change notifications
- ECS Integration: Filter descriptors for query integration
Installation
bash
npm install @web-engine-dev/change-detection
# or
pnpm add @web-engine-dev/change-detectionQuick Start
typescript
import { createChangeDetectionSystem } from '@web-engine-dev/change-detection';
const system = createChangeDetectionSystem();
// Track an object
const position = system.track({ x: 0, y: 0 });
// Mutations are automatically detected
position.value.x = 10;
// Check change state
console.log(position.state.isChanged(system.currentTick)); // true
// Advance tick (call once per frame)
system.tick();
console.log(position.state.isChanged(system.currentTick)); // falseAPI Reference
ChangeDetectionSystem
| Method | Description |
|---|---|
currentTick | Current tick/frame number |
tick() | Advance to next tick, clears mutation history |
track<T>(value, cfg) | Wrap a value with change detection |
isChangedSince() | Check if changed after given tick |
isAddedSince() | Check if added after given tick |
onMutation(listener) | Subscribe to mutation events |
getMutationsThisTick | Get all mutations from current tick |
Configuration Options
typescript
const tracked = system.track(obj, {
deep: true, // Enable deep tracking (default: true)
exclude: ['cache'], // Properties to exclude from tracking
equals: (a, b) => {}, // Custom equality function
});Query Filters (ECS Integration)
typescript
import { changed, added } from '@web-engine-dev/change-detection';
const changedFilter = changed(Transform);
const addedFilter = added(Transform);Game Loop Pattern
typescript
const system = createChangeDetectionSystem();
const transform = system.track({
position: { x: 0, y: 0, z: 0 },
rotation: { x: 0, y: 0, z: 0, w: 1 },
});
function gameLoop() {
system.tick();
// Modify values
transform.value.position.x += velocity.x * deltaTime;
// Query changes since last tick
if (system.isChangedSince(transform, system.currentTick - 1)) {
updateRenderMatrix();
}
}