From cb1a6b79d488654e5ae92b4732597abab5aae541 Mon Sep 17 00:00:00 2001 From: Vance Ingalls Date: Fri, 19 Jun 2026 03:44:20 -0700 Subject: [PATCH 1/4] fix(slideshow): address split-PR review findings on #1585 Genuinely-open findings from the #1580/#1590/#1591/#1592 reviews (the rest were already fixed on this branch: CSP handlers, manifest version, UUID ids, float keys, presenter 1s-timer): core (#1580): - isManifest rejects a non-object/array manifest (e.g. [42,null]) explicitly - resolveSlideshow flags duplicate slideSequence ids instead of silent overwrite player (#1590): - present() window.open uses noopener,noreferrer (audience syncs via channel) - BroadcastChannel name is per-deck (keyed on pathname) to avoid same-origin cross-talk between decks - add observedAttributes + attributeChangedCallback so runtime sound/mode toggles re-render studio (#1591/#1592): - persistSlideshowManifest no-op gate (skip write when HTML is unchanged) - surface persist failures (console.error) instead of silent .catch(()=>{}) - confirm before deleting a branch sequence (data-loss + dangling hotspots) + tests for the collision + non-object-manifest rejection. 20 core / 106 player / 53 studio pass; tsc/lint/fmt/fallow clean; deck still renders. --- .../core/src/slideshow/parseSlideshow.test.ts | 17 +++++++++++++ packages/core/src/slideshow/parseSlideshow.ts | 6 ++++- .../slideshow/hyperframes-slideshow.test.ts | 9 ++++--- .../src/slideshow/hyperframes-slideshow.ts | 15 ++++++++++- .../src/slideshow/slideshowPresenter.ts | 12 ++++++++- .../src/components/panels/SlideshowPanel.tsx | 25 ++++++++++++++++--- .../studio/src/utils/setSlideshowManifest.ts | 4 +++ 7 files changed, 78 insertions(+), 10 deletions(-) diff --git a/packages/core/src/slideshow/parseSlideshow.test.ts b/packages/core/src/slideshow/parseSlideshow.test.ts index d9207243f..1633d5881 100644 --- a/packages/core/src/slideshow/parseSlideshow.test.ts +++ b/packages/core/src/slideshow/parseSlideshow.test.ts @@ -37,6 +37,11 @@ describe("parseSlideshowManifest", () => { expect(() => parseSlideshowManifest(html)).toThrow(); }); + it("rejects a non-object manifest (e.g. a JSON array)", () => { + const html = ``; + expect(() => parseSlideshowManifest(html)).toThrow(); + }); + it("throws when a slide entry is malformed (sceneId not a string)", () => { const html = `