fix(hyperframes): preserve zero data-duration instead of falling back to default (#110)#119
fix(hyperframes): preserve zero data-duration instead of falling back to default (#110)#119JFJLL wants to merge 1 commit into
Conversation
… to default Fixes nexu-io#110 Two bugs in parseHyperframes prevented data-duration attributes from being read: 1. The openTag extraction regex (/<section\b[^>]*>/i) lacked a capture group, causing pick() to always return undefined. Added a capture group so pick() correctly returns the matched open tag string. 2. The original treated duration 0 as falsy, replacing it with undefined (→ default 3000ms). Replaced with an explicit empty-string check: . Added 4 vitest cases covering zero, missing, positive, and mixed durations.
|
Hey @JFJLL — heads-up: PR #118 is also open in this area. Both PRs touch |
mrcfps
left a comment
There was a problem hiding this comment.
@JFJLL thanks for tightening up the zero-duration handling here. I found one merge-safe edge case in the new conversion path where malformed duration text can now propagate as NaN; the core data-duration="0" fix and regression coverage are otherwise pointed in the right direction.
| const dataDur = Number(extractAttr(openTag, "data-duration")) || undefined; | ||
| const openTag = pick(/(<section\b[^>]*>)/i, m[0]); | ||
| const dataDurStr = extractAttr(openTag, "data-duration"); | ||
| const dataDur = dataDurStr ? Number(dataDurStr) : undefined; |
There was a problem hiding this comment.
This fixes the "0" case, but it also changes malformed non-empty values from falling through to the marker/default to winning the ?? chain as NaN. For example, data-duration="fast" now makes Number(dataDurStr) return NaN; because NaN is not nullish, line 151 selects it and exportRemotionZip() later passes that to msToFrames(f.duration), which can produce invalid Remotion output instead of using the inline marker or 3000 fallback. Please keep the explicit zero preservation while normalizing non-finite parses back to undefined, e.g. parse once and use Number.isFinite(parsed) ? parsed : undefined, with a small regression case for an invalid data-duration falling back.
Fix: Zero duration incorrectly treated as undefined
Fixes #110
Problem
In
parseHyperframes()(next/src/lib/hyperframes.ts), thedata-durationattribute was never correctly read from<section>elements due to two bugs:Missing capture group in openTag regex —
pick(/<section\b[^>]*>/i, m[0])used a regex with no capture group, sopick()always returnedundefined(since it returnsm[1]). This meantextractAttr()receivedundefinedand could never match any attributes.Falsy
||operator — The originalNumber(extractAttr(openTag, "data-duration")) || undefinedtreated a duration value of0as falsy, replacing it withundefinedand falling back to the default 3000ms.Fix
(...)to the openTag regex sopick()returns the matched string|| undefinedwith an explicit empty-string check to preserve0as a valid durationTests
Added 4 vitest cases in
next/src/lib/__tests__/hyperframes.test.ts:data-duration="0"→ duration is0(not 3000)data-duration→ defaults to3000data-duration="5000"→ duration is5000