@viewscript/renderer 0.1.0-202605140639

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.
Files changed (89) hide show
  1. package/dist/ast/types.d.ts +403 -0
  2. package/dist/ast/types.js +33 -0
  3. package/dist/compiler/chunk-splitter.d.ts +98 -0
  4. package/dist/compiler/chunk-splitter.js +361 -0
  5. package/dist/index.d.ts +55 -0
  6. package/dist/index.js +17 -0
  7. package/dist/rasterizer/__tests__/error-distribution.test.d.ts +7 -0
  8. package/dist/rasterizer/__tests__/error-distribution.test.js +322 -0
  9. package/dist/rasterizer/canvas-mapper.d.ts +280 -0
  10. package/dist/rasterizer/canvas-mapper.js +414 -0
  11. package/dist/rasterizer/error-distribution.d.ts +143 -0
  12. package/dist/rasterizer/error-distribution.js +231 -0
  13. package/dist/rasterizer/gradient-mapper.d.ts +223 -0
  14. package/dist/rasterizer/gradient-mapper.js +352 -0
  15. package/dist/rasterizer/topology-rounding.d.ts +151 -0
  16. package/dist/rasterizer/topology-rounding.js +347 -0
  17. package/dist/runtime/__tests__/event-backpressure.test.d.ts +10 -0
  18. package/dist/runtime/__tests__/event-backpressure.test.js +190 -0
  19. package/dist/runtime/event-backpressure.d.ts +393 -0
  20. package/dist/runtime/event-backpressure.js +458 -0
  21. package/dist/runtime/render-loop.d.ts +277 -0
  22. package/dist/runtime/render-loop.js +435 -0
  23. package/dist/runtime/wasm-resource-manager.d.ts +122 -0
  24. package/dist/runtime/wasm-resource-manager.js +253 -0
  25. package/dist/runtime/wgpu-renderer-adapter.d.ts +168 -0
  26. package/dist/runtime/wgpu-renderer-adapter.js +230 -0
  27. package/dist/semantic/__tests__/semantic-translator.test.d.ts +4 -0
  28. package/dist/semantic/__tests__/semantic-translator.test.js +203 -0
  29. package/dist/semantic/semantic-translator.d.ts +229 -0
  30. package/dist/semantic/semantic-translator.js +398 -0
  31. package/package.json +28 -0
  32. package/playwright-report/data/0bafe4e0863f0e244bba68a838f73241f8f2efaa.md +226 -0
  33. package/playwright-report/data/9281aca8abfb06c6cecb35d5ddd13d61f8c752d8.md +226 -0
  34. package/playwright-report/index.html +90 -0
  35. package/playwright.config.ts +160 -0
  36. package/screenshot-chrome.png +0 -0
  37. package/screenshots/visual-demo-verification.png +0 -0
  38. package/screenshots/visual-demo.png +0 -0
  39. package/src/ast/types.ts +473 -0
  40. package/src/compiler/chunk-splitter.ts +534 -0
  41. package/src/index.ts +62 -0
  42. package/src/rasterizer/__tests__/error-distribution.test.ts +382 -0
  43. package/src/rasterizer/canvas-mapper.ts +677 -0
  44. package/src/rasterizer/error-distribution.ts +344 -0
  45. package/src/rasterizer/gradient-mapper.ts +563 -0
  46. package/src/rasterizer/topology-rounding.ts +499 -0
  47. package/src/runtime/__tests__/event-backpressure.test.ts +254 -0
  48. package/src/runtime/event-backpressure.ts +622 -0
  49. package/src/runtime/render-loop.ts +660 -0
  50. package/src/runtime/wasm-resource-manager.ts +349 -0
  51. package/src/runtime/wgpu-renderer-adapter.ts +318 -0
  52. package/src/semantic/__tests__/semantic-translator.test.ts +263 -0
  53. package/src/semantic/semantic-translator.ts +637 -0
  54. package/test-results/.last-run.json +4 -0
  55. package/tests/e2e/async-race.spec.ts +612 -0
  56. package/tests/e2e/bilayer-sync.spec.ts +405 -0
  57. package/tests/e2e/failures/.gitkeep +0 -0
  58. package/tests/e2e/fullstack.spec.ts +681 -0
  59. package/tests/e2e/g1-continuity.spec.ts +703 -0
  60. package/tests/e2e/golden/.gitkeep +0 -0
  61. package/tests/e2e/golden/conic-color-wheel.raw +0 -0
  62. package/tests/e2e/golden/conic-color-wheel.sha256 +1 -0
  63. package/tests/e2e/golden/conic-rotated.raw +0 -0
  64. package/tests/e2e/golden/conic-rotated.sha256 +1 -0
  65. package/tests/e2e/golden/linear-45deg.raw +0 -0
  66. package/tests/e2e/golden/linear-45deg.sha256 +1 -0
  67. package/tests/e2e/golden/linear-horizontal.raw +0 -0
  68. package/tests/e2e/golden/linear-horizontal.sha256 +1 -0
  69. package/tests/e2e/golden/linear-multi-stop.raw +0 -0
  70. package/tests/e2e/golden/linear-multi-stop.sha256 +1 -0
  71. package/tests/e2e/golden/radial-circle-center.raw +0 -0
  72. package/tests/e2e/golden/radial-circle-center.sha256 +1 -0
  73. package/tests/e2e/golden/radial-offset.raw +0 -0
  74. package/tests/e2e/golden/radial-offset.sha256 +1 -0
  75. package/tests/e2e/golden/tile-mirror.raw +0 -0
  76. package/tests/e2e/golden/tile-mirror.sha256 +1 -0
  77. package/tests/e2e/golden/tile-repeat.raw +0 -0
  78. package/tests/e2e/golden/tile-repeat.sha256 +1 -0
  79. package/tests/e2e/gradient-animation.spec.ts +606 -0
  80. package/tests/e2e/memory-stability.spec.ts +396 -0
  81. package/tests/e2e/path-topology.spec.ts +674 -0
  82. package/tests/e2e/performance-profile.spec.ts +501 -0
  83. package/tests/e2e/screenshot.spec.ts +60 -0
  84. package/tests/e2e/test-harness.html +1005 -0
  85. package/tests/e2e/text-layout.spec.ts +451 -0
  86. package/tests/e2e/visual-demo.html +340 -0
  87. package/tests/e2e/visual-regression.spec.ts +335 -0
  88. package/tsconfig.json +12 -0
  89. package/vitest.config.ts +8 -0
@@ -0,0 +1,226 @@
1
+ # Instructions
2
+
3
+ - Following Playwright test failed.
4
+ - Explain why, be concise, respect Playwright best practices.
5
+ - Provide a snippet of code with the fix, if possible.
6
+
7
+ # Test info
8
+
9
+ - Name: gradient-animation.spec.ts >> Gradient Rendering: Conic (Sweep) Gradients >> renders rotated conic gradient
10
+ - Location: tests/e2e/gradient-animation.spec.ts:254:3
11
+
12
+ # Error details
13
+
14
+ ```
15
+ Error: expect(received).toBeGreaterThan(expected)
16
+
17
+ Expected: > 255
18
+ Received: 1
19
+ ```
20
+
21
+ # Test source
22
+
23
+ ```ts
24
+ 167 | css: 'radial-gradient(circle at center, white, black)',
25
+ 168 | bounds: { x: 0, y: 0, width: 100, height: 100 },
26
+ 169 | });
27
+ 170 |
28
+ 171 | // Center should be white, corners should be dark
29
+ 172 | const center = getPixelColor(pixelBuffer, 100, 100, 50, 50);
30
+ 173 | const corner = getPixelColor(pixelBuffer, 100, 100, 5, 5);
31
+ 174 |
32
+ 175 | expect(center.r).toBeGreaterThan(200);
33
+ 176 | expect(center.g).toBeGreaterThan(200);
34
+ 177 | expect(center.b).toBeGreaterThan(200);
35
+ 178 |
36
+ 179 | expect(corner.r).toBeLessThan(100);
37
+ 180 | expect(corner.g).toBeLessThan(100);
38
+ 181 | expect(corner.b).toBeLessThan(100);
39
+ 182 |
40
+ 183 | await compareGolden(pixelBuffer, 'radial-circle-center');
41
+ 184 | });
42
+ 185 |
43
+ 186 | /**
44
+ 187 | * Test: Offset focal point radial gradient
45
+ 188 | *
46
+ 189 | * CSS: radial-gradient(circle at 25% 25%, red, blue)
47
+ 190 | * Expected: Gradient center offset to top-left quadrant
48
+ 191 | */
49
+ 192 | test('renders offset radial gradient', async ({ page }) => {
50
+ 193 | await setupDeterministicRenderer(page);
51
+ 194 |
52
+ 195 | const pixelBuffer = await renderGradient(page, {
53
+ 196 | type: 'radial-gradient',
54
+ 197 | css: 'radial-gradient(circle at 25% 25%, red, blue)',
55
+ 198 | bounds: { x: 0, y: 0, width: 100, height: 100 },
56
+ 199 | });
57
+ 200 |
58
+ 201 | // Point at 25%, 25% should be red (center of gradient)
59
+ 202 | const focalPoint = getPixelColor(pixelBuffer, 100, 100, 25, 25);
60
+ 203 |
61
+ 204 | expect(focalPoint.r).toBeGreaterThan(200);
62
+ 205 | expect(focalPoint.b).toBeLessThan(100);
63
+ 206 |
64
+ 207 | await compareGolden(pixelBuffer, 'radial-offset');
65
+ 208 | });
66
+ 209 | });
67
+ 210 |
68
+ 211 | // =============================================================================
69
+ 212 | // Conic Gradient Tests
70
+ 213 | // =============================================================================
71
+ 214 |
72
+ 215 | test.describe('Gradient Rendering: Conic (Sweep) Gradients', () => {
73
+ 216 | test.beforeAll(async () => {
74
+ 217 | ensureDirectories();
75
+ 218 | });
76
+ 219 |
77
+ 220 | /**
78
+ 221 | * Test: Color wheel conic gradient
79
+ 222 | *
80
+ 223 | * CSS: conic-gradient(from 0deg, red, yellow, lime, cyan, blue, magenta, red)
81
+ 224 | * Expected: Full color wheel around center
82
+ 225 | */
83
+ 226 | test('renders color wheel conic gradient', async ({ page }) => {
84
+ 227 | await setupDeterministicRenderer(page);
85
+ 228 |
86
+ 229 | const pixelBuffer = await renderGradient(page, {
87
+ 230 | type: 'conic-gradient',
88
+ 231 | css: 'conic-gradient(from 0deg, red, yellow, lime, cyan, blue, magenta, red)',
89
+ 232 | bounds: { x: 0, y: 0, width: 100, height: 100 },
90
+ 233 | });
91
+ 234 |
92
+ 235 | // Sample at 0deg (right), 90deg (bottom), 180deg (left), 270deg (top)
93
+ 236 | // relative to center (50, 50)
94
+ 237 | const right = getPixelColor(pixelBuffer, 100, 100, 95, 50); // 0deg - red
95
+ 238 | const bottom = getPixelColor(pixelBuffer, 100, 100, 50, 95); // 90deg - between yellow and lime
96
+ 239 | const left = getPixelColor(pixelBuffer, 100, 100, 5, 50); // 180deg - cyan
97
+ 240 | const top = getPixelColor(pixelBuffer, 100, 100, 50, 5); // 270deg - blue/magenta
98
+ 241 |
99
+ 242 | // Right edge (0deg) should be red
100
+ 243 | expect(right.r).toBeGreaterThan(150);
101
+ 244 |
102
+ 245 | await compareGolden(pixelBuffer, 'conic-color-wheel');
103
+ 246 | });
104
+ 247 |
105
+ 248 | /**
106
+ 249 | * Test: Rotated conic gradient
107
+ 250 | *
108
+ 251 | * CSS: conic-gradient(from 90deg at center, red, blue)
109
+ 252 | * Expected: Gradient starts from bottom instead of right
110
+ 253 | */
111
+ 254 | test('renders rotated conic gradient', async ({ page }) => {
112
+ 255 | await setupDeterministicRenderer(page);
113
+ 256 |
114
+ 257 | const pixelBuffer = await renderGradient(page, {
115
+ 258 | type: 'conic-gradient',
116
+ 259 | css: 'conic-gradient(from 90deg at center, red, blue)',
117
+ 260 | bounds: { x: 0, y: 0, width: 100, height: 100 },
118
+ 261 | });
119
+ 262 |
120
+ 263 | // With 90deg rotation, red should be at bottom, blue at top
121
+ 264 | const bottom = getPixelColor(pixelBuffer, 100, 100, 50, 95);
122
+ 265 | const top = getPixelColor(pixelBuffer, 100, 100, 50, 5);
123
+ 266 |
124
+ > 267 | expect(bottom.r).toBeGreaterThan(bottom.b); // More red at bottom
125
+ | ^ Error: expect(received).toBeGreaterThan(expected)
126
+ 268 | expect(top.b).toBeGreaterThan(top.r); // More blue at top
127
+ 269 |
128
+ 270 | await compareGolden(pixelBuffer, 'conic-rotated');
129
+ 271 | });
130
+ 272 | });
131
+ 273 |
132
+ 274 | // =============================================================================
133
+ 275 | // T-Vector Animation Tests
134
+ 276 | // =============================================================================
135
+ 277 |
136
+ 278 | test.describe('Gradient Animation: T-Vector Binding', () => {
137
+ 279 | test.beforeAll(async () => {
138
+ 280 | ensureDirectories();
139
+ 281 | });
140
+ 282 |
141
+ 283 | /**
142
+ 284 | * Test: Animated gradient angle
143
+ 285 | *
144
+ 286 | * T-vector controls the gradient angle: as T increases, angle rotates.
145
+ 287 | * This validates that P-dimension constraints properly propagate to GPU.
146
+ 288 | */
147
+ 289 | test('animates gradient angle via T-vector', async ({ page }) => {
148
+ 290 | await setupDeterministicRenderer(page);
149
+ 291 |
150
+ 292 | // Frame 1: T=0, angle=0deg
151
+ 293 | const frame1 = await renderAnimatedGradient(page, {
152
+ 294 | type: 'linear-gradient',
153
+ 295 | baseAngle: 0,
154
+ 296 | tValue: 0,
155
+ 297 | anglePerT: 90, // 90 degrees per T unit
156
+ 298 | colors: ['red', 'blue'],
157
+ 299 | bounds: { x: 0, y: 0, width: 100, height: 100 },
158
+ 300 | });
159
+ 301 |
160
+ 302 | // Frame 2: T=1, angle=90deg
161
+ 303 | const frame2 = await renderAnimatedGradient(page, {
162
+ 304 | type: 'linear-gradient',
163
+ 305 | baseAngle: 0,
164
+ 306 | tValue: 1,
165
+ 307 | anglePerT: 90,
166
+ 308 | colors: ['red', 'blue'],
167
+ 309 | bounds: { x: 0, y: 0, width: 100, height: 100 },
168
+ 310 | });
169
+ 311 |
170
+ 312 | // Frame 1 should be horizontal (red on left)
171
+ 313 | const f1Left = getPixelColor(frame1, 100, 100, 10, 50);
172
+ 314 | expect(f1Left.r).toBeGreaterThan(f1Left.b);
173
+ 315 |
174
+ 316 | // Frame 2 should be vertical (red on top)
175
+ 317 | const f2Top = getPixelColor(frame2, 100, 100, 50, 10);
176
+ 318 | expect(f2Top.r).toBeGreaterThan(f2Top.b);
177
+ 319 |
178
+ 320 | // Frames should be different
179
+ 321 | const hash1 = computeHash(frame1);
180
+ 322 | const hash2 = computeHash(frame2);
181
+ 323 | expect(hash1).not.toBe(hash2);
182
+ 324 | });
183
+ 325 |
184
+ 326 | /**
185
+ 327 | * Test: Animated color stop positions
186
+ 328 | *
187
+ 329 | * T-vector controls color stop positions for dynamic effects.
188
+ 330 | */
189
+ 331 | test('animates color stop positions via T-vector', async ({ page }) => {
190
+ 332 | await setupDeterministicRenderer(page);
191
+ 333 |
192
+ 334 | // Frame 1: First stop at 30%
193
+ 335 | const frame1 = await renderAnimatedGradient(page, {
194
+ 336 | type: 'linear-gradient',
195
+ 337 | baseAngle: 90, // Top to bottom
196
+ 338 | tValue: 0.3,
197
+ 339 | colors: ['red', 'blue'],
198
+ 340 | stopPositions: [{ base: 0, tFactor: 1 }, { base: 1, tFactor: 0 }],
199
+ 341 | bounds: { x: 0, y: 0, width: 100, height: 100 },
200
+ 342 | });
201
+ 343 |
202
+ 344 | // Frame 2: First stop at 70%
203
+ 345 | const frame2 = await renderAnimatedGradient(page, {
204
+ 346 | type: 'linear-gradient',
205
+ 347 | baseAngle: 90,
206
+ 348 | tValue: 0.7,
207
+ 349 | colors: ['red', 'blue'],
208
+ 350 | stopPositions: [{ base: 0, tFactor: 1 }, { base: 1, tFactor: 0 }],
209
+ 351 | bounds: { x: 0, y: 0, width: 100, height: 100 },
210
+ 352 | });
211
+ 353 |
212
+ 354 | // In frame 1, red extends further (to ~30% from top)
213
+ 355 | // In frame 2, red extends much further (to ~70% from top)
214
+ 356 | const f1Mid = getPixelColor(frame1, 100, 100, 50, 50);
215
+ 357 | const f2Mid = getPixelColor(frame2, 100, 100, 50, 50);
216
+ 358 |
217
+ 359 | // Frame 2 middle should have more red than frame 1 middle
218
+ 360 | expect(f2Mid.r).toBeGreaterThan(f1Mid.r);
219
+ 361 | });
220
+ 362 | });
221
+ 363 |
222
+ 364 | // =============================================================================
223
+ 365 | // Tile Mode Tests
224
+ 366 | // =============================================================================
225
+ 367 |
226
+ ```