Booking Client (Renderer) API Changes - v1.69.0
Release: v1.69.0
Package: @seatmap.pro/renderer
Date: 2026-07-09
Summary
Backward Compatible: YES – no method signatures or configuration options were removed.
New Options: 1 (requestTimeoutMs)
Modified Behavior: 6 areas (event-load contract, section callbacks, section-state APIs, seat-lock, custom seat-state rendering, table price dot)
Deprecations: 0
Removed Runtime Dependency: hammerjs
Migration Required: NO for most integrations. Several changes correct methods and callbacks that previously behaved incorrectly; integrations that depended on the old (incorrect) behavior should review the “Modified Behavior” section below.
Most of these changes come from the SEAT-1046 renderer audit (SEAT-1050, SEAT-1051, SEAT-1052, SEAT-1053, SEAT-1054, SEAT-1067), plus SEAT-1038 (gestures), SEAT-1030 and SEAT-1032 (tables).
New Configuration Options
requestTimeoutMs (SEAT-1050)
Status: New
Description: Bounds how long the renderer waits for a booking API request (schema and prices) before it aborts and shows the loader error state. Protects the embedded widget from hanging indefinitely on a stalled network.
API:
interface IBookingRendererSettings {
requestTimeoutMs?: number; // NEW: default 30000 (30 seconds)
}
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
requestTimeoutMs |
number |
No | 30000 |
Per-request timeout for booking API GETs, in milliseconds |
Behavior:
- On timeout, the pending request aborts and rejects with a
TimeoutErrorDOMException, and the renderer surfaces the loader error state. - On browsers without
AbortSignal.timeout, the renderer degrades gracefully rather than throwing.
const renderer = new SeatmapBookingRenderer(document.getElementById('seatmap'), {
publicKey: 'your-api-key',
requestTimeoutMs: 15000,
});
Modified Behavior
None of the following change a method signature. They correct observable behavior; review any integration that relied on the previous behavior.
loadEvent() now resolves after a full load and rejects on failure (SEAT-1050)
- Before:
loadEvent()resolved after the first paint, before prices and rows had finished loading and applying. - After:
loadEvent()resolves only after schema, prices, and rows are loaded and applied, and rejects – after showing the loader error – if any request fails.
try {
await renderer.loadEvent('event-123');
// Prices and rows are now fully applied.
} catch (err) {
// A load/timeout failure now rejects here (and the widget shows its error state).
}
A fast load failure no longer flashes an error that immediately disappears, and destroying the renderer mid-load (React StrictMode, SPA navigation) no longer produces unhandled promise rejections.
Section click and selection callbacks now include priceId (SEAT-1032)
- Section callback payloads now carry
priceId. priceisundefined(previouslyNaN) when a table/section price label is non-numeric (for example “VIP”).
This also fixes whole-table selection for tables whose price label is non-numeric: the selection gate now keys off priceId instead of a numeric parse of the label, and handles priceId === 0 correctly.
Section-state clearing APIs honor the no-argument form (SEAT-1051, SEAT-1067)
unselectSection(),enableSection(), andunfilterSection()with no argument now clear the respective state on all sections (previously silently ignored).highlightSection()with no argument highlights all sections;highlightSection(id, true)clears that section’s highlight (previously both were no-ops).setOutlineStates(undefined, { <state>: true })bulk updates now apply to every outline and keep the internal state cache consistent (previously only bulk clears were processed).- Bulk updates now skip decorative (id-0) outlines, and reconciliation after an outline rebuild is applied silently – it does not emit
sectionStateChangedfor sections whose state did not actually change.
Selected, unavailable, filtered, and highlighted section states now also survive an outline rebuild (for example when setPricesData runs); previously a price refresh silently reset them.
setSectionSelection() replaces, enableSeatsByIds() honors its argument (SEAT-1052)
setSectionSelection(sections)now replaces the current selection with exactly the sections passed;setSectionSelection([])clears it. Previously each call accumulated selection and[]was ignored.enableSeatsByIds(ids)now unlocks only the listed seats. Previously it could re-enable seats outside the provided list, undoing a precedingdisableSeatsByIds(...).
Custom seat states render during pan and zoom (SEAT-1052)
setSeatsState(ids, stateKey)states now appear immediately during a pan/zoom gesture and re-render correctly when a different state is assigned to the same seats (previously a custom state could stay invisible until ~150 ms after a gesture ended).- Outline hit-testing now resolves a section whose id is
0on click and hover (previously treated as “no section”).
Table price dot honors the editor toggle (SEAT-1030)
When a table’s “Show price dot” option is switched off in the editor, the renderer hides the colored price dot and re-centers the table label.
Removed Runtime Dependency
hammerjs replaced by native Pointer Events (SEAT-1038)
Pan, tap, and pinch-to-zoom gesture handling was rewritten from Hammer.js onto the browser-native Pointer Events API. hammerjs and @types/hammerjs were removed from the package.
- End-user behavior: Unchanged – gesture parity is preserved (pan/tap thresholds, pinch scale/center math, post-pinch pan suppression), with cleaner handling of interrupted gestures via
pointercancel. - Integrator build impact: The externalized/UMD build no longer declares
hammerjsas an external, so aHammerglobal is no longer required when bundling or embedding the renderer. The bundle drops one runtime dependency.
Bug Fixes
Minimap navigation (SEAT-1053)
Clicking the minimap now centers the main view on the exact point under the cursor, including on letterboxed minimaps and venues whose coordinate origin is not (0, 0). Dragging the viewport indicator now pans the venue live as you drag, and releasing a drag no longer makes the viewport jump.
Clean repeated loads and teardown (SEAT-1054)
- Calling
loadEventagain destroys the previous section-outline SVG before building the new one, so repeated loads no longer stack overlapping outline layers; marker pins are re-parented into the new outline SVG. - A WebGL-to-Canvas2D fallback mid-session now removes only its own canvas instead of clearing the host element, preserving the loader bar and surrounding customer DOM. Teardown releases WebGL programs, buffers, and textures.
- If a WebGL context cannot be created even though WebGL reports as available, the renderer falls back to Canvas2D. The stage canvas uses a class instead of a fixed
id, so two renderer instances can coexist on one page.
Migration Guide
From the previous release to v1.69.0
-
Update the package:
npm install @seatmap.pro/renderer@1.69.0 # or yarn add @seatmap.pro/renderer@1.69.0 -
No signature changes are required. Review these behavior corrections against your integration:
- If you
await loadEvent(...)and assumed prices/rows might not be applied yet, you can now rely on completion; add acatchto handle load/timeout rejections. - If you call
setSectionSelection(...)expecting it to add to the current selection, note it now replaces; pass the full desired set (and[]to clear). - If you rely on
enableSeatsByIds(...)re-enabling seats beyond the ids you pass, pass every id you intend to unlock. - If you call the no-argument
unselectSection()/enableSection()/unfilterSection()/highlightSection()orhighlightSection(id, true)and depended on them being no-ops, they now perform the documented action. - If your section-click handler parsed
price, note it is nowundefined(notNaN) for non-numeric labels, andpriceIdis now available. - If you bundle the UMD build, you can drop any
Hammerglobal you were providing.
- If you
-
Optionally set
requestTimeoutMsif 30 seconds is not the right ceiling for your network conditions.
Related Changes
- See Deployment Changes for the database migration and dependency notes.
- See Release Notes for the product-focused overview.