@blu3ph4ntom/inval 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -17
- package/package.json +3 -4
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ inval: 50 widgets, change 1 width 4,230K ops/s (10x faster)
|
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
-
## Why Enterprise Teams Choose Inval
|
|
14
|
+
## Why Enterprise Teams Should Choose Inval
|
|
15
15
|
|
|
16
16
|
### The Problem Nobody Talks About
|
|
17
17
|
|
|
@@ -49,6 +49,32 @@ bun add @blu3ph4ntom/inval
|
|
|
49
49
|
pnpm add @blu3ph4ntom/inval
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
### Why More Code?
|
|
53
|
+
|
|
54
|
+
Yes, `const area = node({ dependsOn: { w, h }, compute: ({ w, h }) => w * h })` is more verbose than `const area = width * height`.
|
|
55
|
+
|
|
56
|
+
**But consider what's missing from the simple version:**
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// This is what your simple version is actually doing:
|
|
60
|
+
function getArea() {
|
|
61
|
+
// Did width or height change since last call?
|
|
62
|
+
// Do I need to recompute or can I return cached?
|
|
63
|
+
// What if I forgot a dependency and it's stale?
|
|
64
|
+
// What if height depends on width indirectly?
|
|
65
|
+
// How do I debug why it recomputed?
|
|
66
|
+
return width * height
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Inval gives you:
|
|
71
|
+
- **Explicit dependencies** — No more guessing what's cached
|
|
72
|
+
- **Debug tools** — `why(node)` tells you exactly what invalidated
|
|
73
|
+
- **Incremental updates** — Only recompute what changed
|
|
74
|
+
- **Production confidence** — 71 tests, deterministic behavior
|
|
75
|
+
|
|
76
|
+
**For simple cases** — use plain variables. **When layout gets complex** — Inval scales.
|
|
77
|
+
|
|
52
78
|
---
|
|
53
79
|
|
|
54
80
|
## The Inval Difference
|
|
@@ -56,24 +82,26 @@ pnpm add @blu3ph4ntom/inval
|
|
|
56
82
|
### Before (Naive Approach)
|
|
57
83
|
|
|
58
84
|
```typescript
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
|
|
85
|
+
// Without a dependency graph, you must recompute everything
|
|
86
|
+
// or manually track what depends on what
|
|
87
|
+
function updateLayout(newWidth) {
|
|
88
|
+
const contentWidth = newWidth - sidebarWidth
|
|
89
|
+
const cardHeight = textHeight(contentWidth, cardText)
|
|
90
|
+
const rowOffset = index * cardHeight
|
|
91
|
+
const visibleRange = computeVisible(scrollTop, rowOffset)
|
|
92
|
+
// Either recompute all of these, or try to memoize each one
|
|
93
|
+
}
|
|
66
94
|
```
|
|
67
95
|
|
|
68
96
|
### After (With Inval)
|
|
69
97
|
|
|
70
98
|
```typescript
|
|
71
|
-
import { input, node
|
|
99
|
+
import { input, node } from '@blu3ph4ntom/inval'
|
|
72
100
|
|
|
73
101
|
const width = input(800)
|
|
74
102
|
const contentWidth = node({
|
|
75
103
|
dependsOn: { w: width },
|
|
76
|
-
compute: ({ w }) => w -
|
|
104
|
+
compute: ({ w }) => w - sidebarWidth
|
|
77
105
|
})
|
|
78
106
|
const cardHeight = node({
|
|
79
107
|
dependsOn: { cw: contentWidth },
|
|
@@ -82,14 +110,14 @@ const cardHeight = node({
|
|
|
82
110
|
|
|
83
111
|
width.set(600)
|
|
84
112
|
// Only contentWidth and cardHeight recompute
|
|
85
|
-
// visibleRange
|
|
86
|
-
//
|
|
113
|
+
// visibleRange stays clean if it doesn't depend on width
|
|
114
|
+
// The library handles incremental updates automatically
|
|
87
115
|
```
|
|
88
116
|
|
|
89
117
|
**You get:**
|
|
90
|
-
- 10x faster performance on layout changes
|
|
118
|
+
- 10x faster performance on layout changes (benchmarked)
|
|
91
119
|
- Exact knowledge of what recomputed (via `why()`)
|
|
92
|
-
-
|
|
120
|
+
- No more manual memoization guessing
|
|
93
121
|
|
|
94
122
|
---
|
|
95
123
|
|
|
@@ -122,12 +150,14 @@ why(area) // ['area', 'width'] — trace exact invalidation path
|
|
|
122
150
|
### Dashboard: 50 Widgets, One Width Change
|
|
123
151
|
|
|
124
152
|
```
|
|
125
|
-
naive: 417,000 ops/s (recomputes all
|
|
126
|
-
inval: 4,230,000 ops/s (recomputes only
|
|
153
|
+
naive: 417,000 ops/s (recomputes all computed nodes)
|
|
154
|
+
inval: 4,230,000 ops/s (recomputes only affected nodes)
|
|
127
155
|
─────────────────────────────────────────────────────────────
|
|
128
156
|
10.1x faster in production-like scenario
|
|
129
157
|
```
|
|
130
158
|
|
|
159
|
+
Note: The naive comparison uses direct function calls without any optimization (no memoization, no dependency tracking). Your actual results will vary based on implementation.
|
|
160
|
+
|
|
131
161
|
### Virtualized List: 1000 Items, Width Change
|
|
132
162
|
|
|
133
163
|
```
|
|
@@ -424,8 +454,19 @@ open demo/pure/index.html # With inval
|
|
|
424
454
|
open demo/without-inval/index.html # Without inval (naive)
|
|
425
455
|
```
|
|
426
456
|
|
|
457
|
+
### Live Demo
|
|
458
|
+
|
|
459
|
+
A side-by-side dashboard demo showing the difference between using Inval vs naive approach:
|
|
460
|
+
|
|
461
|
+
- **demo/pure/index.html** — Uses Inval for incremental updates
|
|
462
|
+
- **demo/without-inval/index.html** — Recomputes everything on each change
|
|
463
|
+
|
|
464
|
+

|
|
465
|
+
|
|
466
|
+
The left panel uses Inval: notice the cached count stays high after initial computation. The right panel recomputes everything on each change.
|
|
467
|
+
|
|
427
468
|
---
|
|
428
469
|
|
|
429
470
|
## License
|
|
430
471
|
|
|
431
|
-
MIT — free for commercial use.
|
|
472
|
+
MIT — free for commercial use.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blu3ph4ntom/inval",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Deterministic, incremental layout invalidation engine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -47,14 +47,13 @@
|
|
|
47
47
|
"license": "MIT",
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"esbuild": "^0.25.11",
|
|
50
|
-
"playwright": "^1.59.1",
|
|
51
50
|
"typescript": "^5.7.0"
|
|
52
51
|
},
|
|
53
52
|
"repository": {
|
|
54
53
|
"type": "git",
|
|
55
|
-
"url": "https://github.com/
|
|
54
|
+
"url": "https://github.com/Blu3ph4ntom/inval.git"
|
|
56
55
|
},
|
|
57
|
-
"homepage": "https://github.com/
|
|
56
|
+
"homepage": "https://github.com/Blu3ph4ntom/inval#readme",
|
|
58
57
|
"bugs": {
|
|
59
58
|
"url": "https://github.com/blu3ph4ntom/inval/issues"
|
|
60
59
|
},
|