3.7 KiB
3.7 KiB
range-response
(no submodules)
Purpose
RFC 7233 §2.1 single-range Response builder for packed-resource
delivery from the Service Worker. Browsers ask for ranges when streaming
audio, scrubbing video, or resuming a download — this module is the
helper the SW invokes to serve those ranges out of the already-decoded
bytes it cached. The helper keeps SW code small: parse, branch, build
Response. No state, no allocations beyond the response body slice.
Features
- Single-range
bytes=<start>-<end>parsing with normalised open-ended (bytes=100-) and suffix (bytes=-100) forms. 206 Partial ContentwithContent-Range,Accept-Ranges: bytes, andContent-Lengthheaders when the request is a valid single range above the configured threshold.200 OKwithAccept-Ranges: bytesfor unranged requests or bodies below the threshold (default 256 KiB).416 Range Not Satisfiablefor multi-range or malformed ranges, with aContent-Range: bytes */<total>header per spec.412 Precondition FailedforIf-RangeETag mismatches.Accept-Ranges: bytesadvertised on every successful response so clients know the resource supports ranges going forward.
Usage: Basic Example
import { serveRangeResponse } from "@suaveplan/packer-browser";
self.addEventListener("fetch", (event) => {
const req = (event as FetchEvent).request;
const body = getCachedBody(req); // application-specific
(event as FetchEvent).respondWith(
serveRangeResponse(req, body, { contentType: "audio/mpeg" })
);
});
Usage: Advanced Example
import {
serveRangeResponse,
DEFAULT_RANGE_THRESHOLD_BYTES,
} from "@suaveplan/packer-browser";
function buildResponse(req: Request, body: Uint8Array, etag: string) {
return serveRangeResponse(req, body, {
contentType: "video/mp4",
etag,
// Lower the threshold for small clips that benefit from range
// hopping (e.g. sprite-sheet image maps).
rangeThreshold: DEFAULT_RANGE_THRESHOLD_BYTES / 8,
});
}
API Reference
parseRange(header: string | null, totalBytes: number): ParseRangeResult- Returns
nullwhen header is absent or non-bytes unit. - Returns
"multi-range"when the header carries more than one range. - Returns
"invalid"when malformed or out-of-bounds. - Returns
ParsedByteRange { start, end }otherwise.
- Returns
serveRangeResponse(request: Request, body: Uint8Array, opts?: ServeRangeResponseOptions): Responseopts.contentType— defaults toapplication/octet-stream.opts.etag— when present, enablesIf-Rangeevaluation.opts.rangeThreshold— minimum body size to enable 206 (default262144).
DEFAULT_RANGE_THRESHOLD_BYTES: number—262144.
Implementation Notes
- The 256 KiB default threshold is chosen empirically: below this size
the cost of slicing + emitting a 206 outweighs the saving for typical
consumers (a single round-trip with the full body is cheaper). The
threshold is fully configurable via
RunServiceWorkerOptions.rangeThreshold. - The helper does NOT support multi-range responses (
multipart/byteranges). RFC 7233 explicitly permits servers to return either 416 or fall back to 200; this implementation chooses 416 to surface the limit immediately so clients can issue single-range follow-ups. If-Rangeis interpreted as strong ETag equality. Date-basedIf-Rangevalues are treated as etags and will mismatch any configured etag; callers that want HTTP-date semantics should setopts.etagto the date string they expect.- Every successful response advertises
Accept-Ranges: bytes, even the below-threshold 200, so the next client request can choose to issue a ranged follow-up.