stitch2 0.24.2 → 0.24.3

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/dist/canvas.html CHANGED
@@ -677,6 +677,10 @@ const frameSrc = (s) => `/${s.path}?pick&canvas=${s.viewportHeight ?? 844}${lang
677
677
  // The rest show the picture the server renders (/api/shot). Without pictures (no Chromium), frames in view stay
678
678
  // live at any zoom, still at most MAX_LIVE. ----
679
679
  const LIVE_ZOOM = 0.3, MAX_LIVE = 6, SHOTS_AT_ONCE = 3
680
+ // A picture costs the server a whole page render. A frame narrower than MIN_SHOT_PX on screen shows nothing you could read, so it is not
681
+ // asked for (fit-all with hundreds of screens would otherwise queue a render of every one, and again after every shared file or link change),
682
+ // and at most SHOTS_QUEUED pictures wait at a time, the nearest to the middle first; as they arrive the next ones are asked for.
683
+ const MIN_SHOT_PX = 64, SHOTS_QUEUED = 24
680
684
  let shotRev = 0, shotErrors = 0, syncTimer
681
685
  const shotsFailed = () => shotErrors > 2
682
686
  const scheduleSync = () => { clearTimeout(syncTimer); syncTimer = setTimeout(syncLive, 120) }
@@ -787,7 +791,11 @@ function syncLive() {
787
791
  // Keep the page until its picture is loaded; switching zoom must never reveal an empty frame.
788
792
  for (const f of frames.values()) if (f.iframe && !live.has(f) && (!visible.has(f) || (f.img.complete && f.img.naturalWidth))) unmount(f)
789
793
  for (const f of live) mount(f)
790
- shotQueue = near.map(({ f }) => [f, shotUrl(f.screen)])
794
+ shotQueue = near
795
+ .filter(({ f }) => f.screen.width * view.z >= MIN_SHOT_PX)
796
+ .map(({ f }) => [f, shotUrl(f.screen)])
797
+ .filter(([f, url]) => f.img.getAttribute('src') !== url)
798
+ .slice(0, SHOTS_QUEUED)
791
799
  pumpShots()
792
800
  }
793
801
 
@@ -1168,12 +1176,14 @@ events.onmessage = async (e) => {
1168
1176
  // (tokens.tailwind.css), the components.
1169
1177
  const shared = paths.some((p) => /\.(css|js|mjs)$/.test(p) || p.startsWith('components/'))
1170
1178
  if (shared) shotRev++
1171
- for (const f of frames.values()) {
1172
- if (shared || html.includes(f.screen.path)) {
1173
- f.iframe?.contentWindow?.location.reload()
1174
- f.el.classList.remove('changed'); void f.el.offsetWidth; f.el.classList.add('changed')
1175
- }
1179
+ // One reflow for all the frames that flash, not one each: approving a version can touch every screen that linked to it.
1180
+ const touched = [...frames.values()].filter((f) => shared || html.includes(f.screen.path))
1181
+ for (const f of touched) {
1182
+ f.iframe?.contentWindow?.location.reload()
1183
+ f.el.classList.remove('changed')
1176
1184
  }
1185
+ void viewport.offsetWidth
1186
+ for (const f of touched) f.el.classList.add('changed')
1177
1187
  scheduleSync()
1178
1188
  }
1179
1189
 
package/dist/shots.js CHANGED
@@ -31,8 +31,13 @@ function sharedStamp() {
31
31
  if (depth < 4)
32
32
  walk(join(dir, e.name), depth + 1);
33
33
  }
34
- else if (!e.name.endsWith('.html') && !(depth === 0 && REPORTS.has(e.name)))
35
- newest = Math.max(newest, statSync(join(dir, e.name)).mtimeMs);
34
+ else if (!e.name.endsWith('.html') && !(depth === 0 && REPORTS.has(e.name))) {
35
+ // A link to nothing (a symlinked folder that is not there on this machine) is not a file that can change a picture.
36
+ try {
37
+ newest = Math.max(newest, statSync(join(dir, e.name)).mtimeMs);
38
+ }
39
+ catch { }
40
+ }
36
41
  }
37
42
  };
38
43
  walk(ROOT, 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stitch2",
3
- "version": "0.24.2",
3
+ "version": "0.24.3",
4
4
  "description": "A design canvas, layout and type checks, component consistency and screen versioning for agent-built UI, on Google's DESIGN.md format.",
5
5
  "license": "MIT",
6
6
  "author": "ifokeev",