Deferred by design from #451 (initial @stitchapi/download release). Byte-offset resume — reconnecting a dropped download from where it stopped instead of re-fetching from byte 0 — is unimplemented on the client side.
What already exists
- Server-side rig primitives (
packages/core/test/support/mock-server.ts): serveRange → 206 Partial Content + correct Content-Range; forceStatusOnRange: 416 | 200 (unsatisfiable / ignore-Range trap); etag / lastModified / acceptRanges validators — built as scaffolding for exactly this.
- Core
download() is a buffered surface that never sends Range; its interpret rejects non-200/204 (a stray 206 fails today — M1).
Why it's new code, not a rewire
Verified: the SSE resume seams (resumeToken/applyResume) fire only for a surface with a stream hook, so they do not apply to the buffered download surface.
Proposal (per ADR 0005, in @stitchapi/download wrapping download())
- buildRequest: inject
Range: bytes=N- on a resumed attempt.
- interpret: branch
206 (continue) / 200 (server ignored Range → discard partial, restart) / 416 (done-or-restart, never infinite-retry the same Range).
- If-Range: guard with a strong ETag or
Last-Modified (never a weak ETag); a changed validator ⇒ 200 full body ⇒ discard the stale partial and restart (never stitch two generations together).
- Refuse byte-offset resume when the response
Content-Encoding is a real coding (gate on response CE, not the Accept-Encoding sent).
References
Rig spec §2.4 (R1–R16), oracles §4, cell X22. The client-side resume assertions (R6–R16) are already gated in the rig, waiting on this.
Deferred by design from #451 (initial
@stitchapi/downloadrelease). Byte-offset resume — reconnecting a dropped download from where it stopped instead of re-fetching from byte 0 — is unimplemented on the client side.What already exists
packages/core/test/support/mock-server.ts):serveRange→206 Partial Content+ correctContent-Range;forceStatusOnRange: 416 | 200(unsatisfiable / ignore-Range trap);etag/lastModified/acceptRangesvalidators — built as scaffolding for exactly this.download()is a buffered surface that never sendsRange; itsinterpretrejects non-200/204 (a stray206fails today — M1).Why it's new code, not a rewire
Verified: the SSE resume seams (
resumeToken/applyResume) fire only for a surface with astreamhook, so they do not apply to the buffered download surface.Proposal (per ADR 0005, in
@stitchapi/downloadwrappingdownload())Range: bytes=N-on a resumed attempt.206(continue) /200(server ignored Range → discard partial, restart) /416(done-or-restart, never infinite-retry the same Range).Last-Modified(never a weak ETag); a changed validator ⇒200full body ⇒ discard the stale partial and restart (never stitch two generations together).Content-Encodingis a real coding (gate on response CE, not theAccept-Encodingsent).References
Rig spec §2.4 (R1–R16), oracles §4, cell X22. The client-side resume assertions (R6–R16) are already gated in the rig, waiting on this.