@seatlayer/js 0.71.1 → 0.71.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +15 -15
- package/dist/index.d.cts +1671 -1416
- package/dist/index.d.ts +1671 -1416
- package/dist/index.js +14 -14
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { PickerSeat, PickerGAArea,
|
|
1
|
+
import { PickerSeat, PickerGAArea, PickerMapTheme, PickerTransport, PickerSelectionValidator, RendererViewMode, PickerSelectionValidity, SeatHoverDetails, SectionSummary, ChartTheme, LodRung, PickerController, AccessibilityType, ExpandedSeat } from '@seatlayer/core';
|
|
2
2
|
export { ExpandedSeat, PickerMapTheme, PickerSelectionValidator, PickerSelectionValidity, PickerSelectionViolation, RendererViewMode, SeatHoverDetails } from '@seatlayer/core';
|
|
3
|
-
import * as _seatlayer_core_core_seatConfidence from '@seatlayer/core/core/seatConfidence';
|
|
4
|
-
import { Venue3DHandle } from '@seatlayer/core/view3d';
|
|
5
3
|
import { T as ThemeMode } from './channelsMode-goczEzyt.js';
|
|
6
4
|
export { A as AccessIntentForbidsDetails, a as AccessLinkRecord, b as AccessLinkReveal, c as AccessLinkState, d as AccessLinkStatus, e as AccessLinkStatusRecord, f as ArchiveBlockedDetails, g as AssignmentBuckets, h as AssignmentDropDetails, i as AssignmentResult, B as BucketRow, C as ChannelAccessIntent, j as ChannelAccessSummary, k as ChannelAllocationPage, l as ChannelAttribution, m as ChannelAuditEntry, n as ChannelAuditPage, o as ChannelCounts, p as ChannelListResult, q as ChannelPreviewProjection, r as ChannelRecord, s as ChannelReport, t as ChannelReportLinkRecord, u as ChannelReportLinkReveal, v as ChannelReportResult, w as ChannelReportRow, x as ChannelSeatStatus, y as ChannelState, z as ChannelsCapabilities, D as ChannelsClient, E as ChannelsMode, F as ChannelsModeHost, G as ChannelsRowView, H as ChannelsSeatView, I as ControlRoomActivityEntry, J as ControlRoomSectionMetric, K as ControlRoomSnapshot, L as EventCategoryAssignmentResult, M as EventScopedManageToken, N as EventTableBookingMode, O as EventTableBookingResult, P as IntentSwitchBlockedDetails, Q as InventoryBooking, R as InventoryBookingActivity, S as InventoryBookingDetail, U as InventoryBookingObject, V as InventoryBookingState, W as InventoryBookingsPage, X as InventoryBookingsQuery, Y as LogEntry, Z as LogPage, _ as ManageApi, $ as ManageApiError, a0 as ReportByStatus, a1 as ReportCategoryMeta, a2 as ReportCategoryRow, a3 as ReportResult, a4 as SeatManager, a5 as SeatManagerActionResult, a6 as SeatManagerActivity, a7 as SeatManagerCapability, a8 as SeatManagerConnection, a9 as SeatManagerFilteredSection, aa as SeatManagerMode, ab as SeatManagerOptions, ac as SeatManagerSelectionValidity, ad as SeatManagerTallies, ae as SelectionSourceRow } from './channelsMode-goczEzyt.js';
|
|
5
|
+
import * as _seatlayer_core_core_seatConfidence from '@seatlayer/core/core/seatConfidence';
|
|
6
|
+
import { Venue3DHandle } from '@seatlayer/core/view3d';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Buyer access context — the browser half of the Sales Channels contract
|
|
@@ -622,168 +622,299 @@ type SeatingChartBuyerView = 'map' | 'venue3d';
|
|
|
622
622
|
type SeatingChartNavigationMode = 'orbit' | 'pan';
|
|
623
623
|
|
|
624
624
|
/**
|
|
625
|
-
*
|
|
625
|
+
* Buyer-safe ticket-offer availability shared by the canonical picker and the
|
|
626
|
+
* hosted event-page templates.
|
|
626
627
|
*
|
|
627
|
-
*
|
|
628
|
-
*
|
|
629
|
-
*
|
|
630
|
-
* + booking to the controller, so the SDK inherits every fix made for the live
|
|
631
|
-
* buyer page and the demo picker.
|
|
628
|
+
* This module intentionally owns the wire parser. A hosted page, iframe, popup
|
|
629
|
+
* and SDK mount must refuse or accept the same payload; duplicating this reader
|
|
630
|
+
* is how one surface eventually prints a price another surface will not charge.
|
|
632
631
|
*/
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
632
|
+
type SaleState = 'on-sale' | 'low' | 'sold-out' | 'presale' | 'closed';
|
|
633
|
+
interface TicketOfferSummary {
|
|
634
|
+
/** Legacy ordering fields kept for older page templates and payloads. */
|
|
635
|
+
index: number;
|
|
636
|
+
count: number;
|
|
637
|
+
/** Units currently available at this offer price; null means unlimited. */
|
|
638
|
+
remaining: number | null;
|
|
639
|
+
/** Buyer-facing fields added by the offers UX. Absent on older workers. */
|
|
640
|
+
id?: string;
|
|
641
|
+
name?: string;
|
|
642
|
+
categoryKey?: string | null;
|
|
643
|
+
startsAt?: number | null;
|
|
644
|
+
endsAt?: number | null;
|
|
645
|
+
}
|
|
646
|
+
interface TicketOfferPrice {
|
|
641
647
|
categoryKey: string;
|
|
648
|
+
/** Major units. What a hold on this category is charged right now. */
|
|
642
649
|
price: number;
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
650
|
+
/** Major units, or null. Printed only when genuinely higher. */
|
|
651
|
+
previousPrice: number | null;
|
|
652
|
+
/** Offer provenance for the price row. Absent on older workers. */
|
|
653
|
+
offerId?: string;
|
|
654
|
+
offerName?: string;
|
|
655
|
+
remaining?: number | null;
|
|
656
|
+
startsAt?: number | null;
|
|
657
|
+
endsAt?: number | null;
|
|
658
|
+
}
|
|
659
|
+
interface ChannelPriceOverride {
|
|
660
|
+
categoryKey: string;
|
|
661
|
+
tierId: string | null;
|
|
662
|
+
price: number;
|
|
663
|
+
}
|
|
664
|
+
/** Pricing configuration projected only for the private channels in this grant. */
|
|
665
|
+
interface BuyerChannelPricing {
|
|
666
|
+
assignmentVersion: number;
|
|
667
|
+
channels: Array<{
|
|
668
|
+
channelId: string;
|
|
669
|
+
pricingVersion: number;
|
|
670
|
+
priceOverrides: ChannelPriceOverride[];
|
|
671
|
+
}>;
|
|
672
|
+
objects: Array<{
|
|
673
|
+
label: string;
|
|
674
|
+
channelId: string;
|
|
651
675
|
}>;
|
|
652
676
|
}
|
|
677
|
+
interface TicketOfferAvailability {
|
|
678
|
+
state: SaleState;
|
|
679
|
+
/** Currently advertised offer price, in minor units. */
|
|
680
|
+
fromPrice: number | null;
|
|
681
|
+
previousPrice: number | null;
|
|
682
|
+
currency: string | null;
|
|
683
|
+
/** The highest-priority active buy offer, when one exists. */
|
|
684
|
+
release: TicketOfferSummary | null;
|
|
685
|
+
/** The next scheduled price offer. It does not close ordinary ticket sales. */
|
|
686
|
+
upcoming: TicketOfferSummary | null;
|
|
687
|
+
/** Server-resolved active offer prices by category, in major units. */
|
|
688
|
+
prices: TicketOfferPrice[];
|
|
689
|
+
channelPricing: BuyerChannelPricing | null;
|
|
690
|
+
}
|
|
691
|
+
/** Parse a public offer payload without repairing a half-understood price. */
|
|
692
|
+
declare function parseTicketOfferAvailability(body: unknown): TicketOfferAvailability | null;
|
|
693
|
+
/** Translate the server-resolved category map into SeatPicker pricing. */
|
|
694
|
+
declare function ticketOfferPrices(availability: TicketOfferAvailability | null): Record<string, number>;
|
|
695
|
+
|
|
653
696
|
/**
|
|
654
|
-
*
|
|
655
|
-
*
|
|
656
|
-
*
|
|
697
|
+
* pickerTypes — the SeatPicker public option/theme/pricing contract, plus the
|
|
698
|
+
* two internal shapes (`SectionLike`, `PriceBand`) the picker reads off a
|
|
699
|
+
* ChartDoc.
|
|
700
|
+
*
|
|
701
|
+
* Split out of SeatPicker.ts verbatim; these declarations are the widget's
|
|
702
|
+
* published API surface, so SeatPicker.ts re-exports every public name from
|
|
703
|
+
* here and `@seatlayer/js`'s entry (src/index.ts) is untouched. Types only —
|
|
704
|
+
* nothing in this file emits a byte of runtime JavaScript.
|
|
657
705
|
*/
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
salesClosed: boolean;
|
|
670
|
-
};
|
|
671
|
-
branding: {
|
|
672
|
-
accent?: ChartTheme['accent'];
|
|
673
|
-
accentInk?: ChartTheme['accentInk'];
|
|
674
|
-
background?: ChartTheme['background'];
|
|
675
|
-
textColor?: ChartTheme['textColor'];
|
|
676
|
-
brandName?: ChartTheme['brandName'];
|
|
677
|
-
logoUrl?: ChartTheme['logoUrl'];
|
|
678
|
-
/** Native must render SeatLayer attribution when it owns chrome and this is true. */
|
|
679
|
-
attributionRequired: boolean;
|
|
680
|
-
};
|
|
681
|
-
features: {
|
|
682
|
-
ga: boolean;
|
|
683
|
-
tiers: boolean;
|
|
684
|
-
floors: boolean;
|
|
685
|
-
zones: boolean;
|
|
686
|
-
sections: boolean;
|
|
687
|
-
bestAvailable: boolean;
|
|
688
|
-
accessibilityFilter: boolean;
|
|
689
|
-
limitedViewFilter: boolean;
|
|
690
|
-
/** Real lazy-loaded WebGL venue view, not the retired isometric projection. */
|
|
691
|
-
venue3d: boolean;
|
|
692
|
-
/** Authored or chart-derived view-from-seat panorama. */
|
|
693
|
-
seatView: boolean;
|
|
694
|
-
};
|
|
695
|
-
catalog: {
|
|
696
|
-
categories: Array<{
|
|
697
|
-
key: string;
|
|
698
|
-
label: string;
|
|
699
|
-
color: string;
|
|
700
|
-
price: number;
|
|
701
|
-
available: number;
|
|
702
|
-
tiers: Array<{
|
|
703
|
-
id: string;
|
|
704
|
-
name: string;
|
|
705
|
-
price: number;
|
|
706
|
-
currency?: string;
|
|
707
|
-
}>;
|
|
708
|
-
}>;
|
|
709
|
-
zones: Array<{
|
|
710
|
-
id: string;
|
|
711
|
-
label: string;
|
|
712
|
-
color?: string;
|
|
713
|
-
}>;
|
|
714
|
-
sections: Array<{
|
|
715
|
-
id: string;
|
|
716
|
-
label: string;
|
|
717
|
-
displayLabel?: string;
|
|
718
|
-
zoneId?: string;
|
|
719
|
-
}>;
|
|
720
|
-
gaAreas: GAAreaAvailability[];
|
|
721
|
-
bestAvailableZones: Array<{
|
|
722
|
-
id: string;
|
|
723
|
-
label: string;
|
|
724
|
-
}>;
|
|
725
|
-
};
|
|
726
|
-
map: {
|
|
727
|
-
floors: Array<{
|
|
728
|
-
id: string;
|
|
729
|
-
name: string;
|
|
730
|
-
}>;
|
|
731
|
-
activeFloorId: string | null;
|
|
732
|
-
rung: LodRung;
|
|
733
|
-
focusedSectionId: string | null;
|
|
734
|
-
focusedSection: SectionSummary | null;
|
|
735
|
-
viewMode: RendererViewMode;
|
|
736
|
-
buyerView: SeatingChartBuyerView;
|
|
737
|
-
view3dTargetSeatId: string | null;
|
|
738
|
-
view3dNavigationMode: SeatingChartNavigationMode;
|
|
739
|
-
colorblindSafe: boolean;
|
|
740
|
-
categoryFilter: string[] | null;
|
|
741
|
-
accessibilityFilter: string[] | null;
|
|
742
|
-
hideLimitedView: boolean;
|
|
743
|
-
};
|
|
744
|
-
selection: {
|
|
745
|
-
seats: SelectedSeat[];
|
|
746
|
-
validity: PickerSelectionValidity | null;
|
|
747
|
-
maxSelection: number;
|
|
748
|
-
};
|
|
749
|
-
access: {
|
|
750
|
-
configured: boolean;
|
|
751
|
-
status: 'public' | 'ready' | 'expired' | 'unavailable';
|
|
752
|
-
reason?: string;
|
|
753
|
-
};
|
|
754
|
-
}
|
|
755
|
-
interface SeatingChartOptions {
|
|
756
|
-
/** CSS selector or an HTMLElement to render into. */
|
|
757
|
-
container: string | HTMLElement;
|
|
758
|
-
/** Event key, e.g. `ev_xxx`. */
|
|
759
|
-
event: string;
|
|
760
|
-
/** API origin. Defaults to https://api.seatlayer.io. */
|
|
761
|
-
apiBase?: string;
|
|
706
|
+
|
|
707
|
+
/**
|
|
708
|
+
* Stable checkout-handoff contract (P4). Passed as the THIRD argument to
|
|
709
|
+
* `onCheckout(hold, seats, handoff)` — additive, so the legacy `(hold, seats)`
|
|
710
|
+
* shape used by DesiPass web-v2 (SDK 0.7.3+) is untouched. This is the object to
|
|
711
|
+
* build your order against: it is self-contained (holdId, expiry, currency, and
|
|
712
|
+
* per-line tier + price) and never changes shape across minor releases.
|
|
713
|
+
*/
|
|
714
|
+
interface CheckoutLineItem {
|
|
715
|
+
/** Seat label (or GA synthetic-unit label) — the stable booking identity. */
|
|
716
|
+
label: string;
|
|
762
717
|
/**
|
|
763
|
-
*
|
|
764
|
-
*
|
|
765
|
-
*
|
|
718
|
+
* Buyer-facing name (the designer's `displayLabel` override), when set.
|
|
719
|
+
* Show this in YOUR order summary; `label` stays the booking identity you
|
|
720
|
+
* pass to the book call. Absent = no override, fall back to `label`.
|
|
766
721
|
*/
|
|
767
|
-
|
|
722
|
+
displayLabel?: string;
|
|
768
723
|
/**
|
|
769
|
-
* Buyer
|
|
770
|
-
*
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
724
|
+
* Buyer-facing type word override (seats.io "Displayed type", e.g. "Table",
|
|
725
|
+
* "Bench", "Box"), when the designer set one. Absent = the default word.
|
|
726
|
+
*/
|
|
727
|
+
displayType?: string;
|
|
728
|
+
/** Chart object id (row/booth/GA area) the unit belongs to. */
|
|
729
|
+
objectId: string;
|
|
730
|
+
objectType: 'seat' | 'booth' | 'ga' | 'table';
|
|
731
|
+
categoryKey: string;
|
|
732
|
+
/** Chosen ticket tier id (Adult/Child/…), or null when the category has no tiers. */
|
|
733
|
+
tierId: string | null;
|
|
734
|
+
/** Unit price in MAJOR currency units (e.g. 45 = 45.00). Server-authoritative. */
|
|
735
|
+
unitPrice: number;
|
|
736
|
+
/** ISO-4217, resolved server-side (per-event override → org → USD). */
|
|
737
|
+
currency: string;
|
|
738
|
+
quantity: number;
|
|
739
|
+
/**
|
|
740
|
+
* The renderer's own seat id, when this line resolves to a placed object.
|
|
776
741
|
*
|
|
777
|
-
*
|
|
778
|
-
*
|
|
779
|
-
*
|
|
780
|
-
* on its own, and a failed refresh stops the scoped operation rather than
|
|
781
|
-
* retrying it anonymously.
|
|
742
|
+
* Present so a host can join a cart line to the same unit in `selection[]`
|
|
743
|
+
* by identity rather than by string label. Absent for a GA synthetic unit,
|
|
744
|
+
* which has no seat, and for a held line whose label no longer resolves.
|
|
782
745
|
*/
|
|
783
|
-
|
|
746
|
+
seatId?: string;
|
|
784
747
|
/**
|
|
785
|
-
*
|
|
786
|
-
*
|
|
748
|
+
* Buyer-facing spatial address — the same three fields a tapped seat carries.
|
|
749
|
+
*
|
|
750
|
+
* Best Available and a resumed hold both produce lines that were never in
|
|
751
|
+
* the renderer selection, so a host joining cart→selection to render "Stalls
|
|
752
|
+
* D · Row C · Seat 6" got nothing back and the line arrived anonymous. The
|
|
753
|
+
* address now travels ON the line, which is where the host reads it anyway.
|
|
754
|
+
* Absent when the chart does not carry that level of address.
|
|
755
|
+
*/
|
|
756
|
+
sectionLabel?: string;
|
|
757
|
+
rowLabel?: string;
|
|
758
|
+
seatNumber?: string;
|
|
759
|
+
}
|
|
760
|
+
interface CheckoutHandoff {
|
|
761
|
+
/** Server hold id — pass this to YOUR book call. */
|
|
762
|
+
holdId: string;
|
|
763
|
+
/** Epoch ms the hold expires (after any extensions). */
|
|
764
|
+
expiresAt: number;
|
|
765
|
+
/** ISO-4217 currency for the whole order. */
|
|
766
|
+
currency: string;
|
|
767
|
+
/** Priced line items (tier + unit price + currency), server-authoritative. */
|
|
768
|
+
lineItems: CheckoutLineItem[];
|
|
769
|
+
/** Convenience total in major units (Σ unitPrice × quantity). */
|
|
770
|
+
total: number;
|
|
771
|
+
}
|
|
772
|
+
/** Host-authoritative pricing — see {@link SeatPickerOptions.pricing}. */
|
|
773
|
+
interface SeatPickerPricing {
|
|
774
|
+
/** Unit prices by category key: a flat number, or `{ base, tiers: { tierId: price } }`. */
|
|
775
|
+
prices?: Record<string, number | {
|
|
776
|
+
base?: number;
|
|
777
|
+
tiers?: Record<string, number>;
|
|
778
|
+
}>;
|
|
779
|
+
/** Custom money renderer (e.g. `(n) => n + '€'`). Defaults to Intl currency formatting. */
|
|
780
|
+
formatter?: (amount: number, currency: string) => string;
|
|
781
|
+
}
|
|
782
|
+
/** Optional constraints for the server-authoritative best-available pick. */
|
|
783
|
+
interface SeatPickerBestAvailableOptions {
|
|
784
|
+
/** Prefer a contiguous premium block, falling back to the best overall block. */
|
|
785
|
+
preferPremium?: boolean;
|
|
786
|
+
/** Restrict the search to one configured chart zone. */
|
|
787
|
+
zoneId?: string;
|
|
788
|
+
}
|
|
789
|
+
/** Buyer-facing surface shown by the full picker widget. */
|
|
790
|
+
type SeatPickerBuyerView = 'map' | 'venue3d';
|
|
791
|
+
/** Optional camera intent when switching the buyer-facing surface. */
|
|
792
|
+
interface SeatPickerBuyerViewOptions {
|
|
793
|
+
/** Enter (or remain in) 3D and fly the camera to this seat id. */
|
|
794
|
+
flyToSeatId?: string;
|
|
795
|
+
/** When already in 3D, return the camera to the venue overview. */
|
|
796
|
+
resetView?: boolean;
|
|
797
|
+
}
|
|
798
|
+
/** Host theme overrides — any subset; unset keys fall back to the org's chart theme, then defaults. */
|
|
799
|
+
interface SeatPickerTheme {
|
|
800
|
+
/**
|
|
801
|
+
* Light, dark, or follow the reader's own `prefers-color-scheme`.
|
|
802
|
+
*
|
|
803
|
+
* OPT-IN. Omit it and the widget renders exactly what it always did: the
|
|
804
|
+
* chart's authored ground, the organizer's colours, your own overrides. Set
|
|
805
|
+
* it and the built-in token set for that side takes the GROUND roles —
|
|
806
|
+
* background, surface, ink, muted ink, hairlines, and the drawn map's own
|
|
807
|
+
* canvas — while the organizer's accent, font, radius and logo, and every
|
|
808
|
+
* colour you state explicitly below, stay exactly as they are.
|
|
809
|
+
*
|
|
810
|
+
* `'auto'` is re-read live: a buyer who flips their phone into dark mode
|
|
811
|
+
* mid-purchase keeps their seats and their hold.
|
|
812
|
+
*/
|
|
813
|
+
mode?: ThemeMode;
|
|
814
|
+
/** Brand accent (CTA, active chips, hold pill). */
|
|
815
|
+
accent?: string;
|
|
816
|
+
/** Ink on the accent (button labels). */
|
|
817
|
+
accentInk?: string;
|
|
818
|
+
/** Widget background. */
|
|
819
|
+
background?: string;
|
|
820
|
+
/** Panel/card surface color. */
|
|
821
|
+
surface?: string;
|
|
822
|
+
/** Primary text color. */
|
|
823
|
+
text?: string;
|
|
824
|
+
/** Secondary text color. */
|
|
825
|
+
muted?: string;
|
|
826
|
+
/** Hairline/border color. */
|
|
827
|
+
line?: string;
|
|
828
|
+
/** Font stack for all widget chrome. */
|
|
829
|
+
fontFamily?: string;
|
|
830
|
+
/** Corner radius base (px). */
|
|
831
|
+
radius?: number;
|
|
832
|
+
/** Header logo URL (falls back to the org logo from the chart theme, then a monogram). */
|
|
833
|
+
logoUrl?: string;
|
|
834
|
+
/** Brand/event fallback name for the monogram. */
|
|
835
|
+
brandName?: string;
|
|
836
|
+
/**
|
|
837
|
+
* The DRAWN MAP, which the tokens above deliberately do not reach.
|
|
838
|
+
*
|
|
839
|
+
* Everything else on this interface is CSS: it re-inks panels, buttons and
|
|
840
|
+
* the sidebar. The seat map is a canvas, painted from the chart document's
|
|
841
|
+
* own `ChartTheme`, so a host could re-ink the whole widget and still be
|
|
842
|
+
* looking at somebody else's dark venue in the middle of it (which is exactly
|
|
843
|
+
* what SeatLayer's own light event-page palettes did, found 2026-08-07).
|
|
844
|
+
*
|
|
845
|
+
* Nested rather than flattened because `background` already means the
|
|
846
|
+
* WIDGET's background here and the canvas ground is a different surface —
|
|
847
|
+
* two things one word cannot carry.
|
|
848
|
+
*
|
|
849
|
+
* Set it only when you can vouch for the result: these colours are drawn
|
|
850
|
+
* behind and beside live seat statuses (held, sold, selected), and the map is
|
|
851
|
+
* the one part of this widget a buyer has to be able to read.
|
|
852
|
+
*/
|
|
853
|
+
map?: PickerMapTheme;
|
|
854
|
+
}
|
|
855
|
+
/** Fine-grained WebMCP exposure — see `SeatPickerOptions.webMcp`. */
|
|
856
|
+
interface SeatPickerWebMcpOptions {
|
|
857
|
+
/** Also register `seatlayer_hold_selection`, which reserves the selection.
|
|
858
|
+
* Default false: holds stay a human tap. */
|
|
859
|
+
holds?: boolean;
|
|
860
|
+
/**
|
|
861
|
+
* Exact, trustworthy origins whose in-page agents may discover these tools
|
|
862
|
+
* across an iframe boundary, for example `https://tickets.example.com`.
|
|
863
|
+
*
|
|
864
|
+
* Same-origin and browser-provided agents do not need this. Cross-origin
|
|
865
|
+
* embeds also need `allow="tools"` on the iframe. Never derive this list from
|
|
866
|
+
* request data; keep it as an explicit integrator allowlist.
|
|
867
|
+
*/
|
|
868
|
+
exposedTo?: string[];
|
|
869
|
+
}
|
|
870
|
+
interface SeatPickerOptions {
|
|
871
|
+
/** CSS selector or element to mount into. Omit when using SeatPicker.open(). */
|
|
872
|
+
container?: string | HTMLElement;
|
|
873
|
+
/** Event key, e.g. `ev_xxx`. */
|
|
874
|
+
event: string;
|
|
875
|
+
/** API origin. Defaults to https://api.seatlayer.io. */
|
|
876
|
+
apiBase?: string;
|
|
877
|
+
/**
|
|
878
|
+
* Custom data transport. Defaults to the CORS-trivial PubApi against
|
|
879
|
+
* `apiBase`. Inject to run the widget against another backend adapter (the
|
|
880
|
+
* SeatLayer dashboard's own transport) or a fully local mock (demos).
|
|
881
|
+
*/
|
|
882
|
+
transport?: PickerTransport;
|
|
883
|
+
/**
|
|
884
|
+
* Publishable account key (`pk_live_…` / `pk_test_…`) for a public
|
|
885
|
+
* Platform/SDK Event. With no explicit buyer-access token/provider, the SDK
|
|
886
|
+
* uses it to bootstrap one origin-bound, Public-sale-only session directly
|
|
887
|
+
* from SeatLayer and receives chart + inventory in the same request.
|
|
888
|
+
*
|
|
889
|
+
* This is not buyer identity and cannot request private channels. An explicit
|
|
890
|
+
* `buyerAccessTokenProvider` or `buyerAccessToken` below always takes
|
|
891
|
+
* precedence for login, presale, partner or other scoped inventory.
|
|
892
|
+
*/
|
|
893
|
+
publicKey?: string;
|
|
894
|
+
/**
|
|
895
|
+
* Buyer access session provider — the recommended way to show private channel
|
|
896
|
+
* inventory (Sales Channels guide §6).
|
|
897
|
+
*
|
|
898
|
+
* Called with a `reason` whenever the widget needs a bearer: first
|
|
899
|
+
* acquisition, a near/actual expiry, a 401 `buyer_access_expired`, a realtime
|
|
900
|
+
* reconnect, or `refreshAccess()`. It should POST to YOUR backend, which
|
|
901
|
+
* mints the session with your secret key and returns `{ token, expiresAt }`.
|
|
902
|
+
*
|
|
903
|
+
* The token lives in memory for the widget's lifetime and nowhere else: never
|
|
904
|
+
* in storage, never in a URL, never in a log or an error message. Refresh
|
|
905
|
+
* returns the same or a narrower scope; the widget never widens to Public
|
|
906
|
+
* sale on its own, and a failed refresh stops the scoped operation rather
|
|
907
|
+
* than retrying it anonymously. Any held seats stay held — a hold is
|
|
908
|
+
* relinquished by its own opaque capability, not by channel access, so
|
|
909
|
+
* losing access never strands inventory (guide §9).
|
|
910
|
+
*
|
|
911
|
+
* Ignored when a custom `transport` is supplied: that host owns its own
|
|
912
|
+
* credentials.
|
|
913
|
+
*/
|
|
914
|
+
buyerAccessTokenProvider?: BuyerAccessTokenProvider;
|
|
915
|
+
/**
|
|
916
|
+
* One-shot escape hatch for hosts that already own the session lifecycle.
|
|
917
|
+
* Cannot be renewed — when it lapses the widget reports `onAccessExpired`
|
|
787
918
|
* and then `onAccessUnavailable`. Prefer `buyerAccessTokenProvider`.
|
|
788
919
|
*/
|
|
789
920
|
buyerAccessToken?: string | BuyerAccessToken;
|
|
@@ -793,1444 +924,1423 @@ interface SeatingChartOptions {
|
|
|
793
924
|
selectedObjects?: string[];
|
|
794
925
|
/** Object ids or public labels the buyer may select. Omit for all free objects. */
|
|
795
926
|
selectableObjects?: string[] | null;
|
|
796
|
-
/** Require exactly this many seated/table guest units before
|
|
927
|
+
/** Require exactly this many total seated/table/GA guest units before checkout. */
|
|
797
928
|
numberOfPlacesToSelect?: number;
|
|
798
|
-
/** Optional
|
|
929
|
+
/** Optional sale guards evaluated after every change and enforced before a
|
|
930
|
+
* hold: minimum quantity, consecutive seats, and/or no stranded singles. */
|
|
799
931
|
selectionValidators?: PickerSelectionValidator[];
|
|
800
932
|
/**
|
|
801
|
-
* BCP 47 language for the widget UI
|
|
802
|
-
*
|
|
803
|
-
*
|
|
933
|
+
* BCP 47 language for the widget UI. 37 languages ship; omit this and each
|
|
934
|
+
* buyer gets their own `navigator.languages`, falling back to English.
|
|
935
|
+
* Read once at render — there is no way to change it on a live chart.
|
|
804
936
|
*/
|
|
805
937
|
locale?: string;
|
|
806
|
-
/**
|
|
807
|
-
* Per-key string overrides layered over the active locale — white-label copy
|
|
808
|
-
* without shipping a whole bundle, e.g. `{ 'map.fromPrice': 'ab {price}' }`.
|
|
809
|
-
*/
|
|
938
|
+
/** Per-key string overrides layered over the active locale. */
|
|
810
939
|
messages?: Record<string, string>;
|
|
811
940
|
/**
|
|
812
|
-
* Show an in-
|
|
941
|
+
* Show an in-picker language switcher offering exactly these languages.
|
|
813
942
|
*
|
|
814
|
-
* Opt-in and curated on purpose
|
|
815
|
-
*
|
|
816
|
-
* disagree is worse than either alone. A
|
|
817
|
-
* German venue wants de/en/pl in
|
|
818
|
-
*
|
|
943
|
+
* Opt-in and curated on purpose. Omit it and there is no control: the widget
|
|
944
|
+
* sits inside someone else's page, and a multilingual host site already has
|
|
945
|
+
* its own switcher — two that can disagree is worse than either alone. A
|
|
946
|
+
* curated list also beats offering all 37: a German venue wants de/en/pl in
|
|
947
|
+
* the menu, not Welsh.
|
|
948
|
+
*
|
|
949
|
+
* Switching keeps the buyer's selection; it does not re-render the chart.
|
|
819
950
|
*/
|
|
820
951
|
languages?: string[];
|
|
821
|
-
/** ISO 4217 currency
|
|
952
|
+
/** ISO 4217 currency fallback (the org/event currency on the chart wins). */
|
|
822
953
|
currency?: string;
|
|
954
|
+
/** Colorblind-safe rendering (Okabe-Ito palette, hollow booked seats). */
|
|
955
|
+
colorblindSafe?: boolean;
|
|
823
956
|
/**
|
|
824
|
-
*
|
|
825
|
-
*
|
|
826
|
-
*
|
|
957
|
+
* How a big chart's seats arrive: 'progressive' (default) shows the venue's
|
|
958
|
+
* sections as soon as the chart lands and fills the seats in a section at a
|
|
959
|
+
* time, nearest the viewport first; 'plain' builds the whole scene in one
|
|
960
|
+
* step. Small charts are built in one step either way.
|
|
827
961
|
*/
|
|
828
|
-
|
|
829
|
-
/**
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
*
|
|
833
|
-
* real 3D venue view (`setBuyerView('venue3d')`); they remain accepted for
|
|
834
|
-
* source compatibility and will be removed in the next major. Use `'flat'`. */
|
|
962
|
+
loadingReveal?: 'progressive' | 'plain';
|
|
963
|
+
/** Initial map projection. Buyers now toggle **Map (flat 2D) + 3D** only; the
|
|
964
|
+
* legacy `perspective` (2.5D) value is still ACCEPTED for source compatibility
|
|
965
|
+
* but is deprecated — it is coerced to `flat` with a one-time console warning.
|
|
966
|
+
* The 3D venue view is entered from the Map/3D control, not this option. */
|
|
835
967
|
initialView?: RendererViewMode;
|
|
836
|
-
/**
|
|
968
|
+
/**
|
|
969
|
+
* Offer the interactive 3D venue view (Map | 3D toggle + a "See it in 3D"
|
|
970
|
+
* action on the seat-confirm card). Default true. The 3D button is shown only
|
|
971
|
+
* when this is not false AND the browser exposes WebGL2; there are ZERO GL
|
|
972
|
+
* bytes on the wire until the buyer actually opens 3D (the OGL chunk is
|
|
973
|
+
* dynamically imported on first use). Set false for embed hosts that must
|
|
974
|
+
* stay strictly 2D. */
|
|
837
975
|
enable3D?: boolean;
|
|
838
|
-
/**
|
|
839
|
-
|
|
840
|
-
|
|
976
|
+
/**
|
|
977
|
+
* Seat-count ceiling above which 3D is not offered. Default: 60,000 seats on
|
|
978
|
+
* desktop, reduced to 30,000 on a device that reports itself as small/low-core.
|
|
979
|
+
*
|
|
980
|
+
* The 53,018-seat evidence is desktop-only; that scale remains unmeasured on
|
|
981
|
+
* phones, which is why the small-device default stays conservative. The 3D
|
|
982
|
+
* scene holds every seat resident until a streaming rung exists. */
|
|
841
983
|
max3DSeats?: number;
|
|
842
984
|
/**
|
|
843
|
-
*
|
|
844
|
-
*
|
|
845
|
-
*
|
|
985
|
+
* Expose this picker to an AI agent running in the buyer's browser (WebMCP).
|
|
986
|
+
*
|
|
987
|
+
* Off by default and inert everywhere the API is absent (every WebView, every
|
|
988
|
+
* browser without it) — an integrator opts in per picker. `true` registers
|
|
989
|
+
* four tools: describe the event, search for seats (read-only — it never
|
|
990
|
+
* touches inventory), select seats on the map, and read the basket.
|
|
991
|
+
*
|
|
992
|
+
* `{ holds: true }` adds a fifth that reserves the selection, i.e. presses
|
|
993
|
+
* the checkout button. That is deliberately separate: a hold takes real
|
|
994
|
+
* inventory off the market, and an agent looping over events must not be able
|
|
995
|
+
* to lock a venue. Leave it off unless you want an agent to be able to commit.
|
|
996
|
+
*
|
|
997
|
+
* Cross-origin embeds: the HOST page must mark the iframe `allow="tools"`
|
|
998
|
+
* and the picker must list that host's exact origin in `exposedTo`, or an
|
|
999
|
+
* in-page agent in the host cannot discover the frame's tools.
|
|
846
1000
|
*/
|
|
847
|
-
|
|
848
|
-
/** Internal hosted-runtime control. Defaults true for direct web embeds. */
|
|
849
|
-
showTestModeIndicator?: boolean;
|
|
850
|
-
/** Internal hosted-runtime control. Defaults true, subject to white-label entitlement. */
|
|
851
|
-
showAttribution?: boolean;
|
|
1001
|
+
webMcp?: boolean | SeatPickerWebMcpOptions;
|
|
852
1002
|
/**
|
|
853
|
-
*
|
|
854
|
-
*
|
|
855
|
-
* or not the built-in tooltip is enabled.
|
|
1003
|
+
* Fires when the buyer enters/leaves 3D or targets a seat there. Hosts can
|
|
1004
|
+
* mirror this small, non-sensitive state into a shareable URL.
|
|
856
1005
|
*/
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
/** The configured selection rules have just become valid. */
|
|
862
|
-
onSelectionValid?: (seats: SelectedSeat[]) => void;
|
|
863
|
-
/** The configured selection rules have just become invalid. */
|
|
864
|
-
onSelectionInvalid?: (state: PickerSelectionValidity) => void;
|
|
865
|
-
/** A manual or programmatic selection reached the active maximum. */
|
|
866
|
-
onSelectionLimit?: (maxSelection: number) => void;
|
|
867
|
-
onHold?: (result: HoldResult) => void;
|
|
868
|
-
/** A prior active hold was restored with resumeHold(). */
|
|
869
|
-
onHoldRestored?: (result: HoldResult) => void;
|
|
870
|
-
onHoldExpired?: () => void;
|
|
871
|
-
onGAClick?: (area: GAAreaAvailability) => void;
|
|
1006
|
+
onBuyerViewChange?: (state: {
|
|
1007
|
+
view: SeatPickerBuyerView;
|
|
1008
|
+
seatId?: string;
|
|
1009
|
+
}) => void;
|
|
872
1010
|
/**
|
|
873
|
-
*
|
|
874
|
-
*
|
|
875
|
-
*
|
|
876
|
-
*
|
|
877
|
-
|
|
878
|
-
|
|
1011
|
+
* Optional analytics sink for the widget's journey and performance events.
|
|
1012
|
+
* Emits `chart_rendered` once per successful load with total time, step
|
|
1013
|
+
* timings and anonymous chart-size counts, plus the 3D venue-view journey
|
|
1014
|
+
* (`3d_opened`, `3d_orbit_engaged`, `3d_seat_picked`,
|
|
1015
|
+
* `3d_cinematic_played`/`_skipped`/`_cancelled`, panorama outcomes, and WebGL
|
|
1016
|
+
* context loss/recovery)
|
|
1017
|
+
* with `{ surface: 'buyer' }` merged into the props. A throwing sink never
|
|
1018
|
+
* breaks the widget. Route it to your product analytics (e.g. PostHog). */
|
|
1019
|
+
onAnalytics?: (event: string, props: Record<string, unknown>) => void;
|
|
879
1020
|
/**
|
|
880
|
-
*
|
|
881
|
-
*
|
|
882
|
-
* `
|
|
883
|
-
*
|
|
1021
|
+
* Every seat of a progressively revealed chart is now built and painted.
|
|
1022
|
+
*
|
|
1023
|
+
* `render()` resolves with the section shells and the nearest seats — the
|
|
1024
|
+
* rest arrive in idle slices. A host that needs "the whole venue is on
|
|
1025
|
+
* screen" waits for this rather than for `render()`. Fires exactly once per
|
|
1026
|
+
* chart, and never for a chart small enough to build in one step (there is
|
|
1027
|
+
* nothing to wait for: `render()` already was that moment).
|
|
884
1028
|
*/
|
|
885
|
-
|
|
1029
|
+
onSeatsRevealed?: () => void;
|
|
886
1030
|
/**
|
|
887
|
-
*
|
|
888
|
-
*
|
|
889
|
-
*
|
|
1031
|
+
* Optional organiser-defined campaign/referral label (max 120 characters).
|
|
1032
|
+
* On the public SeatLayer transport it is frozen onto the hold, then copied
|
|
1033
|
+
* to the Managed order, organiser reporting and booking webhook. It grants no
|
|
1034
|
+
* inventory access and is ignored by host-supplied transports.
|
|
890
1035
|
*/
|
|
891
|
-
|
|
1036
|
+
referral?: string;
|
|
892
1037
|
/**
|
|
893
|
-
*
|
|
894
|
-
*
|
|
895
|
-
*
|
|
1038
|
+
* Hide the "Powered by SeatLayer" attribution badge in the side panel foot.
|
|
1039
|
+
* The chart theme's own `hideBadge` flag (paid orgs) also hides it — the badge
|
|
1040
|
+
* is shown only when BOTH this option and the theme flag are unset/false.
|
|
896
1041
|
*/
|
|
897
|
-
|
|
898
|
-
onError?: (err: unknown) => void;
|
|
1042
|
+
hideBadge?: boolean;
|
|
899
1043
|
/**
|
|
900
|
-
*
|
|
901
|
-
*
|
|
902
|
-
*
|
|
903
|
-
*
|
|
904
|
-
*
|
|
905
|
-
* wired `onError` — or had wired it to a logger — showed buyers a blank
|
|
906
|
-
* rectangle where the seat map belongs, on the host's own domain, which
|
|
907
|
-
* reads as a broken website rather than a temporary fault. `SeatPicker` has
|
|
908
|
-
* always failed loud with a retry; this is the embed class catching up.
|
|
1044
|
+
* Hide the picker's event identity (logo, event name and venue/date metadata)
|
|
1045
|
+
* when the host surface already presents the same event heading. The hold
|
|
1046
|
+
* timer, sales status and modal close controls remain available. The identity
|
|
1047
|
+
* is restored automatically while the picker is full screen so it never
|
|
1048
|
+
* loses context on a small device or an expanded map. Default false.
|
|
909
1049
|
*
|
|
910
|
-
*
|
|
911
|
-
*
|
|
1050
|
+
* A mounted host can update this through `setEventDetailsHidden()` when its
|
|
1051
|
+
* own event chrome arrives asynchronously.
|
|
912
1052
|
*/
|
|
913
|
-
|
|
1053
|
+
hideEventDetails?: boolean;
|
|
914
1054
|
/**
|
|
915
|
-
*
|
|
916
|
-
*
|
|
917
|
-
*
|
|
1055
|
+
* Start the wide-layout ticket panel collapsed so the map owns the full
|
|
1056
|
+
* width (map-first hosts, small embeds). The buyer reopens it with the
|
|
1057
|
+
* "Tickets" pill beside Map|3D, and it opens itself the moment a seat lands
|
|
1058
|
+
* in the cart — a collapsed panel must never hide a checkout. Narrow
|
|
1059
|
+
* layouts ignore this (the bottom sheet is already the collapse). A mounted
|
|
1060
|
+
* host can drive it later through `setPanelCollapsed()`. Default false.
|
|
918
1061
|
*/
|
|
919
|
-
|
|
920
|
-
/**
|
|
921
|
-
|
|
922
|
-
/** Availability changed after a live frame or explicit refresh. */
|
|
923
|
-
onStatusChange?: () => void;
|
|
924
|
-
/** The server closed sales for this event. */
|
|
925
|
-
onSalesClosed?: () => void;
|
|
926
|
-
/** A programmatic/native map-control action changed serializable map state. */
|
|
927
|
-
onMapStateChange?: () => void;
|
|
928
|
-
/** rAF-coalesced camera-frame signal for in-page overlays; not native state. */
|
|
929
|
-
onViewChange?: () => void;
|
|
930
|
-
/** Real buyer-view transitions and 3D camera targets. */
|
|
931
|
-
onBuyerViewChange?: (state: {
|
|
932
|
-
view: SeatingChartBuyerView;
|
|
933
|
-
seatId?: string;
|
|
934
|
-
}) => void;
|
|
1062
|
+
panelCollapsed?: boolean;
|
|
1063
|
+
/** Host theme overrides — see SeatPickerTheme. */
|
|
1064
|
+
theme?: SeatPickerTheme;
|
|
935
1065
|
/**
|
|
936
|
-
*
|
|
937
|
-
*
|
|
938
|
-
*
|
|
1066
|
+
* Host-authoritative pricing. When your shop charges different prices than
|
|
1067
|
+
* the chart's stored category prices, pass them here so the buyer sees the
|
|
1068
|
+
* price they will actually pay — on the map tooltip, confirm popover, price
|
|
1069
|
+
* panel, tray, totals, and in the checkout handoff's line items. Keyed by
|
|
1070
|
+
* category key; per-tier overrides nest under `tiers`. Unlisted categories
|
|
1071
|
+
* fall back to the chart price.
|
|
939
1072
|
*/
|
|
940
|
-
|
|
941
|
-
}
|
|
942
|
-
declare class SeatingChart {
|
|
943
|
-
private readonly opts;
|
|
944
|
-
private readonly controller;
|
|
945
|
-
/** Publishable key used only by the public-only direct bootstrap path. */
|
|
946
|
-
readonly publicKey?: string;
|
|
947
|
-
private mount;
|
|
948
|
-
private hostEl;
|
|
1073
|
+
pricing?: SeatPickerPricing;
|
|
949
1074
|
/**
|
|
950
|
-
*
|
|
951
|
-
*
|
|
952
|
-
*
|
|
953
|
-
* inert rather than relying on the host's visual stacking alone.
|
|
1075
|
+
* Fires when the server-resolved active offer changes. Hosted event pages use
|
|
1076
|
+
* this to keep their headline, sticky bar and the canonical picker on the
|
|
1077
|
+
* same live fact. The picker remains fully functional when it is omitted.
|
|
954
1078
|
*/
|
|
955
|
-
|
|
956
|
-
/**
|
|
957
|
-
|
|
958
|
-
private rendered;
|
|
959
|
-
private mode_;
|
|
960
|
-
private eventInfo;
|
|
961
|
-
private maxSelection_;
|
|
962
|
-
private colorblindSafe_;
|
|
963
|
-
private categoryFilter_;
|
|
964
|
-
private accessibilityFilter_;
|
|
965
|
-
private hideLimitedView_;
|
|
966
|
-
private focusedSection_;
|
|
967
|
-
/** Last rung already exposed to native chrome; raw camera frames stay in-canvas. */
|
|
968
|
-
private lastReportedViewRung_;
|
|
969
|
-
private accessState_;
|
|
970
|
-
private tipEl;
|
|
971
|
-
private tipPos;
|
|
972
|
-
private onTipMove;
|
|
973
|
-
/** Null for the ordinary public chart — the tokenless path is untouched. */
|
|
974
|
-
private readonly access;
|
|
975
|
-
private readonly api;
|
|
976
|
-
private readonly apiBase;
|
|
977
|
-
private readonly buyerAssetUrls;
|
|
978
|
-
private readonly immersive;
|
|
979
|
-
private realtime;
|
|
980
|
-
constructor(options: SeatingChartOptions);
|
|
1079
|
+
onOfferAvailabilityChange?: (availability: TicketOfferAvailability | null) => void;
|
|
1080
|
+
/** Hold TTL in ms passed to hold(); server clamps to its own limits. */
|
|
1081
|
+
holdTtlMs?: number;
|
|
981
1082
|
/**
|
|
982
|
-
*
|
|
983
|
-
*
|
|
984
|
-
*
|
|
1083
|
+
* An opaque hold id supplied by the host to restore after navigation. It is
|
|
1084
|
+
* verified against the event and active server state before anything renders
|
|
1085
|
+
* as owned by this buyer.
|
|
985
1086
|
*/
|
|
986
|
-
|
|
987
|
-
/** Record the current rung before publishing an explicit state mutation. */
|
|
988
|
-
private notifyMapStateChange;
|
|
989
|
-
/** Fetch the chart, mount the renderer, seed statuses and go live. Idempotent. */
|
|
990
|
-
render(): Promise<this>;
|
|
1087
|
+
initialHoldId?: string;
|
|
991
1088
|
/**
|
|
992
|
-
*
|
|
993
|
-
*
|
|
994
|
-
*
|
|
995
|
-
* overlay keeps it out of the layout flow so it never disturbs the SDK v0.22
|
|
996
|
-
* fill-height resize contract. Mirrors the full widget's mark + wordmark and
|
|
997
|
-
* reuses the `picker.poweredBy` i18n string.
|
|
1089
|
+
* Automatically remember the active hold id in sessionStorage and restore it
|
|
1090
|
+
* when this event's picker mounts again. Default true. Set false when the host
|
|
1091
|
+
* owns hold persistence and supplies initialHoldId itself.
|
|
998
1092
|
*/
|
|
999
|
-
|
|
1000
|
-
private placeTooltip;
|
|
1001
|
-
private updateTooltip;
|
|
1093
|
+
restoreHold?: boolean;
|
|
1002
1094
|
/**
|
|
1003
|
-
*
|
|
1004
|
-
*
|
|
1005
|
-
*
|
|
1006
|
-
*
|
|
1007
|
-
* The widget already surfaces this visually with the test-mode ribbon; this
|
|
1008
|
-
* getter is for hosts that draw their own chrome — notably a native WebView
|
|
1009
|
-
* wrapper, which must be able to tell an integrator that the build they are
|
|
1010
|
-
* about to ship is pointed at a test event.
|
|
1095
|
+
* Render the real chart and live seat statuses without allowing selection,
|
|
1096
|
+
* holds or checkout. This is for venue previews and pre-sale Website pages;
|
|
1097
|
+
* it is enforced by the widget even if the event later opens while mounted.
|
|
1098
|
+
* Default false.
|
|
1011
1099
|
*/
|
|
1100
|
+
readOnly?: boolean;
|
|
1012
1101
|
/**
|
|
1013
|
-
*
|
|
1014
|
-
*
|
|
1015
|
-
*
|
|
1016
|
-
*
|
|
1017
|
-
*
|
|
1018
|
-
* Each language names itself (`LOCALE_NAMES`): a reader scanning for their
|
|
1019
|
-
* own language finds "Deutsch", never "German". An English list is
|
|
1020
|
-
* unreadable to exactly the people who need it.
|
|
1102
|
+
* Confirm mode: tapping a seat shows a confirmation card with section, row,
|
|
1103
|
+
* seat, category, price and Select/Cancel before it enters the tray. Default
|
|
1104
|
+
* true for the full buyer picker; set false only when the host supplies its
|
|
1105
|
+
* own equivalent confirmation UI.
|
|
1021
1106
|
*/
|
|
1022
|
-
|
|
1107
|
+
confirmSelection?: boolean;
|
|
1023
1108
|
/**
|
|
1024
|
-
*
|
|
1109
|
+
* Offer a "View from seat" 360° preview (confirm popover + tray chips). The
|
|
1110
|
+
* panorama is generated from the chart geometry, or the organizer's uploaded
|
|
1111
|
+
* photo when a seat carries one. Default true; set false to hide the affordance.
|
|
1112
|
+
*/
|
|
1113
|
+
seatView?: boolean;
|
|
1114
|
+
/**
|
|
1115
|
+
* WHERE the buyer goes once their seats are held. Default `'handoff'`.
|
|
1025
1116
|
*
|
|
1026
|
-
*
|
|
1027
|
-
*
|
|
1028
|
-
*
|
|
1029
|
-
*
|
|
1030
|
-
*
|
|
1031
|
-
*
|
|
1117
|
+
* 'handoff' (default, and every integration that has ever existed) the
|
|
1118
|
+
* widget fires {@link onCheckout} with a holdId and priced line
|
|
1119
|
+
* items, and YOUR server takes the money. Nothing about this path
|
|
1120
|
+
* changes, and no payment code is even downloaded.
|
|
1121
|
+
* 'hosted' the widget takes the money through the gateway the ORGANIZER
|
|
1122
|
+
* connected, on their account — the "sell tickets with no
|
|
1123
|
+
* backend" path. Requires the org to be on hosted checkout and
|
|
1124
|
+
* the event to have a gateway assigned; when it does not, this
|
|
1125
|
+
* falls back to `'handoff'` for that buyer rather than dead-ending
|
|
1126
|
+
* them, and reports why through {@link onCheckoutUnavailable}.
|
|
1032
1127
|
*
|
|
1033
|
-
*
|
|
1034
|
-
*
|
|
1035
|
-
* it
|
|
1128
|
+
* Named for the destination rather than as a boolean flag because there is a
|
|
1129
|
+
* real third answer coming and `hostedCheckout: true` would have no room for
|
|
1130
|
+
* it; spelling the default out also makes a host's intent legible in their own
|
|
1131
|
+
* source instead of hiding it in an absent option.
|
|
1132
|
+
*
|
|
1133
|
+
* TWO THINGS ARE WORTH KNOWING BEFORE YOU SWITCH THIS ON:
|
|
1134
|
+
*
|
|
1135
|
+
* 1. It needs the widget's own transport. A host-supplied `transport` owns its
|
|
1136
|
+
* credentials and its backend, so hosted checkout stays off there (with one
|
|
1137
|
+
* console warning) rather than reaching past it to api.seatlayer.io.
|
|
1138
|
+
* 2. WHERE A HOSTED GATEWAY RETURNS THE BUYER is settled by {@link returnUrl}
|
|
1139
|
+
* and by the organizer. Without one — or from an origin the organizer has
|
|
1140
|
+
* not declared — the buyer comes back to SeatLayer's own buyer page and is
|
|
1141
|
+
* confirmed THERE, not in this widget. Declare the embedding site under
|
|
1142
|
+
* Embed domains in the dashboard and pass `returnUrl`, and the buyer
|
|
1143
|
+
* returns to your page instead. In-page gateways never navigate away at
|
|
1144
|
+
* all, so they are unaffected either way.
|
|
1036
1145
|
*/
|
|
1037
|
-
|
|
1038
|
-
getMode(): 'live' | 'test' | null;
|
|
1039
|
-
/** Atomic, token-free display state for native-owned picker chrome. */
|
|
1040
|
-
getPickerState(): SeatingChartPickerState;
|
|
1041
|
-
getCategoryAvailability(): Record<string, number>;
|
|
1042
|
-
getBestAvailableZones(): Array<{
|
|
1043
|
-
id: string;
|
|
1044
|
-
label: string;
|
|
1045
|
-
}>;
|
|
1046
|
-
getActiveFloorId(): string | null;
|
|
1047
|
-
getRung(): LodRung;
|
|
1048
|
-
getFocusedSection(): string | null;
|
|
1049
|
-
focusSection(sectionId: string): void;
|
|
1050
|
-
overview(): void;
|
|
1051
|
-
setRung(rung: LodRung): void;
|
|
1052
|
-
setCategoryFilter(categoryKeys: string[] | null, focus?: boolean): void;
|
|
1053
|
-
setAccessibilityFilter(types: string[] | null): void;
|
|
1054
|
-
setCommercialLimitedFilter(on: boolean): void;
|
|
1055
|
-
/** Current selection with prices resolved from the chart categories. */
|
|
1056
|
-
getSelection(): SelectedSeat[];
|
|
1057
|
-
/** Select free objects by engine id or public label. Returns newly selected objects. */
|
|
1058
|
-
selectObjects(objects: string[]): SelectedSeat[];
|
|
1059
|
-
/** Deselect objects by engine id or public label. */
|
|
1060
|
-
deselectObjects(objects: string[]): void;
|
|
1061
|
-
/** Clear every unheld selection. */
|
|
1062
|
-
clearSelection(): void;
|
|
1063
|
-
/** Select every selectable object in the named categories. */
|
|
1064
|
-
selectCategories(categoryKeys: string[]): SelectedSeat[];
|
|
1065
|
-
/** Deselect every selected object in the named categories. */
|
|
1066
|
-
deselectCategories(categoryKeys: string[]): void;
|
|
1067
|
-
/** Replace the buyer-selectable object allow-list without remounting. */
|
|
1068
|
-
setSelectableObjects(objects: string[] | null): void;
|
|
1069
|
-
/** Change the selection cap without remounting. */
|
|
1070
|
-
setMaxSelection(maxSelection: number): void;
|
|
1071
|
-
/** Current selection-rule validity, or null when no rules were configured. */
|
|
1072
|
-
getSelectionValidity(): PickerSelectionValidity | null;
|
|
1073
|
-
/** Hold the current selection. Resolves the hold, or null on a 409 conflict. */
|
|
1074
|
-
hold(options?: {
|
|
1075
|
-
ttlMs?: number;
|
|
1076
|
-
}): Promise<HoldResult | null>;
|
|
1146
|
+
checkout?: 'handoff' | 'hosted';
|
|
1077
1147
|
/**
|
|
1078
|
-
*
|
|
1079
|
-
* `
|
|
1080
|
-
*
|
|
1081
|
-
*
|
|
1082
|
-
*
|
|
1083
|
-
*
|
|
1084
|
-
*
|
|
1148
|
+
* Where a redirecting gateway should send the buyer back to, for
|
|
1149
|
+
* `checkout: 'hosted'`.
|
|
1150
|
+
*
|
|
1151
|
+
* The server keeps this URL's path and query and adds only a non-secret
|
|
1152
|
+
* `seatlayer_checkout=success|cancelled` outcome. The SDK keeps the order id
|
|
1153
|
+
* in this tab's sessionStorage before leaving for the gateway. Point this at
|
|
1154
|
+
* a page on the same origin (often `window.location.href`) and mount a picker
|
|
1155
|
+
* there so it can resume without putting the order capability in a URL.
|
|
1156
|
+
*
|
|
1157
|
+
* It is validated, not trusted: the organizer declares their embed origins
|
|
1158
|
+
* in the dashboard, and an undeclared origin is ignored rather than
|
|
1159
|
+
* refused — the sale still completes, the buyer just finishes on
|
|
1160
|
+
* SeatLayer's page. Supplying a URL therefore cannot authorize it, which is
|
|
1161
|
+
* what stops a copied snippet from redirecting a paid buyer anywhere it
|
|
1162
|
+
* likes.
|
|
1163
|
+
* As with every script embed, code already running on the host origin can
|
|
1164
|
+
* read that origin's sessionStorage; iframe embedding provides SOP isolation.
|
|
1085
1165
|
*/
|
|
1086
|
-
|
|
1087
|
-
ttlMs?: number;
|
|
1088
|
-
}): Promise<HoldResult | null>;
|
|
1089
|
-
/** Restore an active hold by its opaque id without extending its expiry. */
|
|
1090
|
-
resumeHold(holdId: string): Promise<HoldResult | null>;
|
|
1091
|
-
/** @internal Throwing variant of {@link resumeHold} for the native host adapter. See {@link holdOrThrow}. */
|
|
1092
|
-
resumeHoldOrThrow(holdId: string): Promise<HoldResult | null>;
|
|
1166
|
+
returnUrl?: string;
|
|
1093
1167
|
/**
|
|
1094
|
-
*
|
|
1095
|
-
* hold
|
|
1096
|
-
* is
|
|
1097
|
-
*
|
|
1098
|
-
*
|
|
1168
|
+
* Buyer pressed the CTA and the hold succeeded — hand off to YOUR checkout.
|
|
1169
|
+
* `hold` and `seats` are the legacy args (unchanged since 0.6). `handoff` (P4)
|
|
1170
|
+
* is the stable, self-contained {@link CheckoutHandoff} to build your order
|
|
1171
|
+
* against — holdId, expiry, currency and priced line items. Prefer it.
|
|
1172
|
+
*
|
|
1173
|
+
* Under `checkout: 'hosted'` this fires ONLY when hosted checkout cannot run
|
|
1174
|
+
* for this event, so a host can keep one code path for both. It never fires
|
|
1175
|
+
* alongside a payment the widget is taking itself.
|
|
1099
1176
|
*/
|
|
1100
|
-
|
|
1101
|
-
/** Current active hold known to this chart, if any. */
|
|
1102
|
-
getCurrentHold(): HoldResult | null;
|
|
1103
|
-
getGAAreas(): GAAreaAvailability[];
|
|
1104
|
-
holdGA(areaId: string, qty: number, options?: {
|
|
1105
|
-
tierId?: string | null;
|
|
1106
|
-
ttlMs?: number;
|
|
1107
|
-
}): Promise<HoldResult | null>;
|
|
1108
|
-
/** @internal Throwing variant of {@link holdGA} for the native host adapter. See {@link holdOrThrow}. */
|
|
1109
|
-
holdGAOrThrow(areaId: string, qty: number, options?: {
|
|
1110
|
-
tierId?: string | null;
|
|
1111
|
-
ttlMs?: number;
|
|
1112
|
-
}): Promise<HoldResult | null>;
|
|
1177
|
+
onCheckout?: (hold: HoldResult, seats: PickerSeat[], handoff: CheckoutHandoff) => void;
|
|
1113
1178
|
/**
|
|
1114
|
-
*
|
|
1115
|
-
*
|
|
1116
|
-
*
|
|
1179
|
+
* `checkout: 'hosted'` was asked for and this event cannot take money.
|
|
1180
|
+
* The seats ARE held — the buyer is mid-journey — so this is a routing
|
|
1181
|
+
* decision, not an error, and it is never collapsed into {@link onError}.
|
|
1182
|
+
*
|
|
1183
|
+
* `reason` carries the server's three-way answer verbatim, because two of the
|
|
1184
|
+
* three give opposite advice: `payments_off_for_event` means the organizer
|
|
1185
|
+
* deliberately does not sell this event online (nothing is wrong), while
|
|
1186
|
+
* `unavailable_for_event` means they switched it on and it is broken. Anything
|
|
1187
|
+
* unreadable — a failed lookup, an older worker — reads as `not_configured`,
|
|
1188
|
+
* which asserts the least about them.
|
|
1189
|
+
*
|
|
1190
|
+
* `onCheckout` fires immediately after this with the same hold. Supply either
|
|
1191
|
+
* (or both) and you own the next screen; supply NEITHER and the widget shows
|
|
1192
|
+
* the buyer an honest card of its own rather than swallowing the press.
|
|
1117
1193
|
*/
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
}): Promise<BestAvailableResult | null>;
|
|
1123
|
-
/** @internal Throwing variant of {@link bestAvailable} for the native host adapter. See {@link holdOrThrow}. */
|
|
1124
|
-
bestAvailableOrThrow(qty: number, categoryKey?: string, options?: {
|
|
1125
|
-
zoneId?: string;
|
|
1126
|
-
preferPremium?: boolean;
|
|
1127
|
-
ttlMs?: number;
|
|
1128
|
-
}): Promise<BestAvailableResult | null>;
|
|
1194
|
+
onCheckoutUnavailable?: (event: {
|
|
1195
|
+
reason: PaymentOptionsReason;
|
|
1196
|
+
handoff: CheckoutHandoff;
|
|
1197
|
+
}) => void;
|
|
1129
1198
|
/**
|
|
1130
|
-
*
|
|
1131
|
-
*
|
|
1132
|
-
*
|
|
1133
|
-
*
|
|
1134
|
-
*
|
|
1199
|
+
* `checkout: 'hosted'` only — the gateway's webhook landed and the order is
|
|
1200
|
+
* PAID. The one signal a host with no backend actually needs, and the only
|
|
1201
|
+
* place a receipt can come from on a page that has no server of its own.
|
|
1202
|
+
*
|
|
1203
|
+
* Distinct from {@link onBooked}, which reports the same sale seen from the
|
|
1204
|
+
* seat map over the realtime channel and cannot fire at all for a buyer whose
|
|
1205
|
+
* widget was torn down by a redirect to the gateway.
|
|
1135
1206
|
*/
|
|
1136
|
-
|
|
1137
|
-
/** Confirm/update an unheld variable table's guest quantity locally. */
|
|
1138
|
-
setTableQuantity(label: string, quantity: number): boolean;
|
|
1207
|
+
onOrderConfirmed?: (order: OrderStatusResult) => void;
|
|
1139
1208
|
/**
|
|
1140
|
-
*
|
|
1141
|
-
*
|
|
1209
|
+
* The held seats were BOOKED (P4) — your server completed payment and the
|
|
1210
|
+
* booking landed over the realtime channel while the widget was still open.
|
|
1211
|
+
* The widget shows a success state; use this to advance your own UI (receipt,
|
|
1212
|
+
* redirect). Fires once per hold.
|
|
1142
1213
|
*/
|
|
1143
|
-
|
|
1144
|
-
/**
|
|
1145
|
-
|
|
1214
|
+
onBooked?: (handoff: CheckoutHandoff) => void;
|
|
1215
|
+
/** Selection changed (tap or best-available). */
|
|
1216
|
+
onSelectionChange?: (seats: PickerSeat[]) => void;
|
|
1217
|
+
/** Selection-rule state after each selection change. */
|
|
1218
|
+
onSelectionValidityChange?: (state: PickerSelectionValidity) => void;
|
|
1219
|
+
/** The configured selection rules have just become valid. */
|
|
1220
|
+
onSelectionValid?: (seats: PickerSeat[]) => void;
|
|
1221
|
+
/** The configured selection rules have just become invalid. */
|
|
1222
|
+
onSelectionInvalid?: (state: PickerSelectionValidity) => void;
|
|
1223
|
+
/** A selection attempt reached the active maximum. */
|
|
1224
|
+
onSelectionLimit?: (maxSelection: number) => void;
|
|
1146
1225
|
/**
|
|
1147
|
-
*
|
|
1148
|
-
*
|
|
1149
|
-
*
|
|
1226
|
+
* Active hold changed because it was created, restored, extended, partially
|
|
1227
|
+
* released, or fully released. Hosts should persist this state for route
|
|
1228
|
+
* navigation and clear their checkout cart when `hold` becomes null.
|
|
1150
1229
|
*/
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
setColorblindSafe(on: boolean): void;
|
|
1159
|
-
/** Switch the 2D canvas projection.
|
|
1160
|
-
* @deprecated `'isometric'` and `'perspective'` are retired in favour of the
|
|
1161
|
-
* real 3D venue view (`setBuyerView('venue3d')`); accepted for source
|
|
1162
|
-
* compatibility until the next major. */
|
|
1163
|
-
setViewMode(mode: RendererViewMode): void;
|
|
1164
|
-
/** Current canvas projection. */
|
|
1165
|
-
getViewMode(): RendererViewMode;
|
|
1166
|
-
/** Zoom in one step (same increment as the wheel/pinch gesture). */
|
|
1167
|
-
zoomIn(): void;
|
|
1168
|
-
/** Zoom out one step. */
|
|
1169
|
-
zoomOut(): void;
|
|
1170
|
-
/** Reset the camera so the whole chart fits the container. */
|
|
1171
|
-
zoomToFit(): void;
|
|
1172
|
-
/** Enter or leave the same real lazy-loaded venue scene as SeatPicker. */
|
|
1173
|
-
setBuyerView(view: SeatingChartBuyerView, options?: {
|
|
1174
|
-
flyToSeatId?: string;
|
|
1175
|
-
resetView?: boolean;
|
|
1176
|
-
}): Promise<void>;
|
|
1177
|
-
getBuyerView(): SeatingChartBuyerView;
|
|
1178
|
-
/** Open an authored or chart-derived 360° view for one physical seat. */
|
|
1179
|
-
openSeatView(seatId: string): Promise<void>;
|
|
1180
|
-
/** Explicit Rotate / Move control for native and custom picker chrome. */
|
|
1181
|
-
setVenue3DNavigationMode(mode: SeatingChartNavigationMode): void;
|
|
1230
|
+
onHoldChange?: (hold: HoldResult | null, seats: PickerSeat[], handoff: CheckoutHandoff | null) => void;
|
|
1231
|
+
/** The open hold expired server-side (widget already reset itself). */
|
|
1232
|
+
onHoldExpired?: () => void;
|
|
1233
|
+
/** A prior active hold was verified and restored into the tray. */
|
|
1234
|
+
onHoldRestored?: (hold: HoldResult, seats: PickerSeat[], handoff: CheckoutHandoff) => void;
|
|
1235
|
+
/** Modal only: the buyer closed the picker (ESC / scrim / ✕). */
|
|
1236
|
+
onClose?: () => void;
|
|
1182
1237
|
/**
|
|
1183
|
-
*
|
|
1184
|
-
*
|
|
1185
|
-
*
|
|
1186
|
-
*
|
|
1187
|
-
* intentional: an iOS WKWebView can receive the same physical tap beneath a
|
|
1188
|
-
* Flutter overlay even when the Flutter widget is wrapped in IgnorePointer.
|
|
1189
|
-
* Programmatic bridge commands continue to work, so a prompt can still open
|
|
1190
|
-
* view-from-seat or 3D and then re-enable interaction after the handoff.
|
|
1238
|
+
* The buyer access session lapsed. `refreshed` says whether the provider
|
|
1239
|
+
* already recovered it — false means private inventory is now unavailable and
|
|
1240
|
+
* `onAccessUnavailable` follows. Never collapsed into `onError`: an expiry is
|
|
1241
|
+
* a recoverable, buyer-explainable state, not a network failure (guide §10).
|
|
1191
1242
|
*/
|
|
1192
|
-
|
|
1193
|
-
private applyInteractionState;
|
|
1194
|
-
/** Release the current hold (if any). No-op when nothing is held. */
|
|
1195
|
-
release(): Promise<void>;
|
|
1196
|
-
/** Release selected labels from the current hold while keeping the remainder. */
|
|
1197
|
-
releaseLabels(labels: string[]): Promise<boolean>;
|
|
1198
|
-
/** Tear everything down: close the socket, stop timers, drop the canvas. */
|
|
1243
|
+
onAccessExpired?: (event: BuyerAccessExpiredEvent) => void;
|
|
1199
1244
|
/**
|
|
1200
|
-
*
|
|
1201
|
-
*
|
|
1202
|
-
*
|
|
1203
|
-
*
|
|
1204
|
-
* and its own legacy frames. Nothing about the public path changes.
|
|
1245
|
+
* Private inventory is unavailable and refreshing will not fix it — revoked,
|
|
1246
|
+
* paused, wrong origin/event/mode, or the provider failed. Carries a reason,
|
|
1247
|
+
* never a channel name, id, colour or count. The widget shows its own
|
|
1248
|
+
* explanatory panel; return nothing to keep it, or handle the state yourself.
|
|
1205
1249
|
*/
|
|
1206
|
-
|
|
1207
|
-
/** Re-read live inventory without remounting or dropping buyer state. */
|
|
1208
|
-
refreshAvailability(): Promise<void>;
|
|
1250
|
+
onAccessUnavailable?: (event: BuyerAccessUnavailableEvent) => void;
|
|
1209
1251
|
/**
|
|
1210
|
-
*
|
|
1211
|
-
*
|
|
1212
|
-
*
|
|
1252
|
+
* Selected-but-unheld units stopped being selectable — someone else took
|
|
1253
|
+
* them, or an allocation change moved them out of this buyer's scope. The
|
|
1254
|
+
* widget has already dropped them from the tray.
|
|
1213
1255
|
*/
|
|
1214
|
-
|
|
1256
|
+
onSelectedObjectUnavailable?: (event: SelectedObjectUnavailableEvent) => void;
|
|
1215
1257
|
/**
|
|
1216
|
-
*
|
|
1217
|
-
*
|
|
1218
|
-
*
|
|
1219
|
-
*
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
* that Vue and Angular never got, and nothing in any build caught it, because a
|
|
1234
|
-
* missing prop in a hand-written list is not a type error anywhere.
|
|
1235
|
-
*
|
|
1236
|
-
* So the lists live here, next to the class they describe, and the wrappers
|
|
1237
|
-
* iterate them. Adding a method to `SeatingChart` that buyers should be able to
|
|
1238
|
-
* call now means adding one entry to {@link SEATING_CHART_HANDLE_METHODS}; every
|
|
1239
|
-
* wrapper picks it up, and the wrapper tests fail until each one exposes it.
|
|
1240
|
-
*
|
|
1241
|
-
* Types only against `SeatingChart` — this module imports no runtime value from
|
|
1242
|
-
* it, so it costs a host nothing but the two arrays and the binder below.
|
|
1243
|
-
*/
|
|
1258
|
+
* A buyer tapped a general-admission area (on the map, or in the tray's
|
|
1259
|
+
* `Areas` list) and the widget is about to open its own quantity prompt.
|
|
1260
|
+
*
|
|
1261
|
+
* Return `true` to take the interaction over completely — the built-in
|
|
1262
|
+
* popover/sheet is suppressed, and the host drives the choice with whatever
|
|
1263
|
+
* UI it likes, landing the result through `prompt.confirm(quantity)` (a plain
|
|
1264
|
+
* number for a single-tier area, or `{ [tierId]: quantity }`) or dropping it
|
|
1265
|
+
* with `prompt.cancel()`. Return anything else (or nothing) and the built-in
|
|
1266
|
+
* prompt opens as usual, so this is also usable as a plain notification.
|
|
1267
|
+
*
|
|
1268
|
+
* `prompt.max` already folds in the area's live availability AND the
|
|
1269
|
+
* order-wide ticket cap minus everything chosen elsewhere; a `confirm` above
|
|
1270
|
+
* it is clamped rather than rejected.
|
|
1271
|
+
*/
|
|
1272
|
+
onGAPrompt?: (prompt: GAPromptRequest) => boolean | void;
|
|
1273
|
+
onError?: (err: unknown) => void;
|
|
1274
|
+
}
|
|
1244
1275
|
|
|
1245
1276
|
/**
|
|
1246
|
-
*
|
|
1247
|
-
* from your app.
|
|
1277
|
+
* SeatingChart — the embeddable buyer picker.
|
|
1248
1278
|
*
|
|
1249
|
-
*
|
|
1250
|
-
*
|
|
1279
|
+
* A thin wrapper over the shared PickerController (src/picker/PickerController):
|
|
1280
|
+
* it owns the mount <div> + the public embed contract (hold-only — the SDK hands
|
|
1281
|
+
* the holdId to the host page for a server-side book) and delegates all transport
|
|
1282
|
+
* + booking to the controller, so the SDK inherits every fix made for the live
|
|
1283
|
+
* buyer page and the demo picker.
|
|
1251
1284
|
*/
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
/**
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
}): Promise<HoldResult | null>;
|
|
1268
|
-
/** Ask the server for the `qty` best free seats and hold them atomically. */
|
|
1269
|
-
bestAvailable(qty: number, categoryKey?: string): Promise<BestAvailableResult | null>;
|
|
1270
|
-
/** Release the current hold (if any). */
|
|
1271
|
-
release(): Promise<void>;
|
|
1272
|
-
/** Release some held labels while keeping the remainder active. */
|
|
1273
|
-
releaseLabels(labels: string[]): Promise<boolean>;
|
|
1274
|
-
/** The current selection, with prices resolved from the chart categories. */
|
|
1275
|
-
getSelection(): SelectedSeat[];
|
|
1276
|
-
/** Select free objects by engine id or public label. */
|
|
1277
|
-
selectObjects(objects: string[]): SelectedSeat[];
|
|
1278
|
-
/** Deselect objects by engine id or public label. */
|
|
1279
|
-
deselectObjects(objects: string[]): void;
|
|
1280
|
-
/** Clear every unheld selection. */
|
|
1281
|
-
clearSelection(): void;
|
|
1282
|
-
/** Select every selectable object in the named categories. */
|
|
1283
|
-
selectCategories(categoryKeys: string[]): SelectedSeat[];
|
|
1284
|
-
/** Deselect every selected object in the named categories. */
|
|
1285
|
-
deselectCategories(categoryKeys: string[]): void;
|
|
1286
|
-
/** Replace the buyer-selectable object allow-list without rebuilding. */
|
|
1287
|
-
setSelectableObjects(objects: string[] | null): void;
|
|
1288
|
-
/** Change the selection cap without rebuilding. */
|
|
1289
|
-
setMaxSelection(maxSelection: number): void;
|
|
1290
|
-
/** Current exact-count validity, or null when no exact count was configured. */
|
|
1291
|
-
getSelectionValidity(): PickerSelectionValidity | null;
|
|
1292
|
-
/**
|
|
1293
|
-
* Choose a ticket tier for a selected seat (e.g. Adult → Child). Available
|
|
1294
|
-
* `tiers` are on each `SelectedSeat`; `tierId=null` reverts to the default.
|
|
1295
|
-
*/
|
|
1296
|
-
setSeatTier(seatId: string, tierId: string | null): void;
|
|
1297
|
-
/**
|
|
1298
|
-
* Floors of a multi-floor chart — `[{ id, name }]` (single-floor charts
|
|
1299
|
-
* return one entry; empty before render()). Pair with setFloor().
|
|
1300
|
-
*/
|
|
1301
|
-
getFloors(): {
|
|
1285
|
+
|
|
1286
|
+
/** A seat as surfaced to the host page (prices resolved from the chart's categories). */
|
|
1287
|
+
type SelectedSeat = PickerSeat;
|
|
1288
|
+
interface GAAreaAvailability {
|
|
1289
|
+
id: string;
|
|
1290
|
+
label: string;
|
|
1291
|
+
capacity: number;
|
|
1292
|
+
available: number;
|
|
1293
|
+
categoryKey: string;
|
|
1294
|
+
price: number;
|
|
1295
|
+
currency: string;
|
|
1296
|
+
/** Buyer-facing copy authored separately from stable inventory identity. */
|
|
1297
|
+
displayLabel?: string;
|
|
1298
|
+
displayType?: string;
|
|
1299
|
+
tiers?: Array<{
|
|
1302
1300
|
id: string;
|
|
1303
1301
|
name: string;
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
setFloor(floorId: string): void;
|
|
1307
|
-
/** Toggle colorblind-safe rendering at runtime (see the `colorblindSafe` prop). */
|
|
1308
|
-
setColorblindSafe(on: boolean): void;
|
|
1309
|
-
/** Zoom in one step (same increment as the wheel/pinch gesture). */
|
|
1310
|
-
zoomIn(): void;
|
|
1311
|
-
/** Zoom out one step. */
|
|
1312
|
-
zoomOut(): void;
|
|
1313
|
-
/** Reset the camera so the whole chart fits the container. */
|
|
1314
|
-
zoomToFit(): void;
|
|
1315
|
-
/**
|
|
1316
|
-
* Re-acquire the buyer access session after your app re-authorizes the buyer
|
|
1317
|
-
* (Sales Channels). Resolves false when the chart is not access-scoped.
|
|
1318
|
-
*/
|
|
1319
|
-
refreshAccess(): Promise<boolean>;
|
|
1302
|
+
price: number;
|
|
1303
|
+
}>;
|
|
1320
1304
|
}
|
|
1321
1305
|
/**
|
|
1322
|
-
*
|
|
1323
|
-
*
|
|
1324
|
-
|
|
1325
|
-
declare const SEATING_CHART_HANDLE_METHODS: readonly ["hold", "resumeHold", "getCurrentHold", "getGAAreas", "holdGA", "bestAvailable", "release", "releaseLabels", "getSelection", "selectObjects", "deselectObjects", "clearSelection", "selectCategories", "deselectCategories", "setSelectableObjects", "setMaxSelection", "getSelectionValidity", "setSeatTier", "getFloors", "setFloor", "setColorblindSafe", "zoomIn", "zoomOut", "zoomToFit", "refreshAccess"];
|
|
1326
|
-
type SeatingChartHandleMethod = (typeof SEATING_CHART_HANDLE_METHODS)[number];
|
|
1327
|
-
/**
|
|
1328
|
-
* Build the forwarding object every wrapper exposes.
|
|
1329
|
-
*
|
|
1330
|
-
* `getInstance` is a function rather than the instance itself: a wrapper's
|
|
1331
|
-
* handle is created ONCE and must keep working across rebuilds, so it has to
|
|
1332
|
-
* read the current chart on each call instead of capturing one.
|
|
1333
|
-
*/
|
|
1334
|
-
declare function bindSeatingChartHandle(getInstance: () => SeatingChart | null): SeatingChartHandle;
|
|
1335
|
-
/**
|
|
1336
|
-
* Props whose change means a DIFFERENT chart, so the wrapper tears the canvas
|
|
1337
|
-
* down and builds a new one. Everything else is read live: a parent re-render
|
|
1338
|
-
* must never destroy a canvas mid-selection.
|
|
1339
|
-
*
|
|
1340
|
-
* `initialView` and `errorDisplay` are here because they are read once at
|
|
1341
|
-
* construction and never re-applied — leaving them out does not make them
|
|
1342
|
-
* "live", it makes them silently ignored after mount, which is the worse of the
|
|
1343
|
-
* two behaviours. React already treated them this way; Vue and Angular did not
|
|
1344
|
-
* expose them at all.
|
|
1345
|
-
*/
|
|
1346
|
-
declare const SEATING_CHART_IDENTITY_PROPS: readonly ["event", "apiBase", "maxSelection", "numberOfPlacesToSelect", "selectionValidators", "publicKey", "locale", "currency", "colorblindSafe", "initialView", "errorDisplay"];
|
|
1347
|
-
type SeatingChartIdentityProp = (typeof SEATING_CHART_IDENTITY_PROPS)[number];
|
|
1348
|
-
/** Non-callback options a wrapper accepts as props/inputs and passes straight through. */
|
|
1349
|
-
declare const SEATING_CHART_VALUE_PROPS: readonly ["event", "apiBase", "maxSelection", "numberOfPlacesToSelect", "selectionValidators", "publicKey", "locale", "currency", "colorblindSafe", "initialView", "errorDisplay", "selectedObjects", "selectableObjects", "messages", "seatTooltip", "buyerAccessTokenProvider", "buyerAccessToken"];
|
|
1350
|
-
type SeatingChartValueProp = (typeof SEATING_CHART_VALUE_PROPS)[number];
|
|
1351
|
-
/** Every callback option a wrapper wires to its own event mechanism. */
|
|
1352
|
-
declare const SEATING_CHART_CALLBACK_PROPS: readonly ["onSelectionChange", "onSelectionValidityChange", "onSelectionValid", "onSelectionInvalid", "onSelectionLimit", "onHold", "onHoldRestored", "onHoldExpired", "onGAClick", "onGAPrompt", "onError", "onDeckTap", "onHint", "onSeatHover", "onAccessExpired", "onAccessUnavailable", "onSelectedObjectUnavailable"];
|
|
1353
|
-
type SeatingChartCallbackProp = (typeof SEATING_CHART_CALLBACK_PROPS)[number];
|
|
1354
|
-
/** The value half of the options, as a wrapper holds it. */
|
|
1355
|
-
type SeatingChartValues = Pick<SeatingChartOptions, SeatingChartValueProp>;
|
|
1356
|
-
/** The callback half, already bound to the wrapper's event mechanism. */
|
|
1357
|
-
type SeatingChartCallbacks = Pick<SeatingChartOptions, SeatingChartCallbackProp>;
|
|
1358
|
-
/**
|
|
1359
|
-
* Assemble the options literal for `new SeatingChart(...)`.
|
|
1360
|
-
*
|
|
1361
|
-
* Picks by the lists above rather than spreading, so a wrapper cannot pass a
|
|
1362
|
-
* stray prop of its own (React's `className`/`style`, Vue's attrs) into the
|
|
1363
|
-
* SDK, and cannot forget one either.
|
|
1364
|
-
*/
|
|
1365
|
-
declare function buildSeatingChartOptions(container: HTMLElement, values: Partial<SeatingChartValues>, callbacks: SeatingChartCallbacks): SeatingChartOptions;
|
|
1366
|
-
|
|
1367
|
-
/**
|
|
1368
|
-
* A secure, framework-neutral host for the SeatLayer chart Designer.
|
|
1369
|
-
*
|
|
1370
|
-
* The Designer remains an iframe so a platform never gives its SeatLayer secret
|
|
1371
|
-
* key to a browser. This class owns the iframe lifecycle and accepts messages
|
|
1372
|
-
* only from that iframe's exact origin.
|
|
1306
|
+
* Serializable state exposed to hosted native picker chrome. It deliberately
|
|
1307
|
+
* contains buyer-display data only: never API keys, buyer-access bearers,
|
|
1308
|
+
* provider callbacks, or the active hold id.
|
|
1373
1309
|
*/
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1310
|
+
interface SeatingChartPickerState {
|
|
1311
|
+
event: {
|
|
1312
|
+
key: string;
|
|
1313
|
+
name: string;
|
|
1314
|
+
venue: string | null;
|
|
1315
|
+
startsAt: number | null;
|
|
1316
|
+
timezone: string | null;
|
|
1317
|
+
currency: string;
|
|
1318
|
+
locale: string | null;
|
|
1319
|
+
posterUrl: string | null;
|
|
1320
|
+
mode: 'live' | 'test';
|
|
1321
|
+
salesClosed: boolean;
|
|
1322
|
+
};
|
|
1323
|
+
branding: {
|
|
1324
|
+
accent?: ChartTheme['accent'];
|
|
1325
|
+
accentInk?: ChartTheme['accentInk'];
|
|
1326
|
+
background?: ChartTheme['background'];
|
|
1327
|
+
textColor?: ChartTheme['textColor'];
|
|
1328
|
+
brandName?: ChartTheme['brandName'];
|
|
1329
|
+
logoUrl?: ChartTheme['logoUrl'];
|
|
1330
|
+
/** Native must render SeatLayer attribution when it owns chrome and this is true. */
|
|
1331
|
+
attributionRequired: boolean;
|
|
1332
|
+
};
|
|
1333
|
+
features: {
|
|
1334
|
+
ga: boolean;
|
|
1335
|
+
tiers: boolean;
|
|
1336
|
+
floors: boolean;
|
|
1337
|
+
zones: boolean;
|
|
1338
|
+
sections: boolean;
|
|
1339
|
+
bestAvailable: boolean;
|
|
1340
|
+
accessibilityFilter: boolean;
|
|
1341
|
+
limitedViewFilter: boolean;
|
|
1342
|
+
/** Real lazy-loaded WebGL venue view, not the retired isometric projection. */
|
|
1343
|
+
venue3d: boolean;
|
|
1344
|
+
/** Authored or chart-derived view-from-seat panorama. */
|
|
1345
|
+
seatView: boolean;
|
|
1346
|
+
};
|
|
1347
|
+
catalog: {
|
|
1348
|
+
categories: Array<{
|
|
1349
|
+
key: string;
|
|
1350
|
+
label: string;
|
|
1351
|
+
color: string;
|
|
1352
|
+
price: number;
|
|
1353
|
+
available: number;
|
|
1354
|
+
tiers: Array<{
|
|
1355
|
+
id: string;
|
|
1356
|
+
name: string;
|
|
1357
|
+
price: number;
|
|
1358
|
+
currency?: string;
|
|
1359
|
+
}>;
|
|
1360
|
+
}>;
|
|
1361
|
+
zones: Array<{
|
|
1362
|
+
id: string;
|
|
1363
|
+
label: string;
|
|
1364
|
+
color?: string;
|
|
1365
|
+
}>;
|
|
1366
|
+
sections: Array<{
|
|
1367
|
+
id: string;
|
|
1368
|
+
label: string;
|
|
1369
|
+
displayLabel?: string;
|
|
1370
|
+
zoneId?: string;
|
|
1371
|
+
}>;
|
|
1372
|
+
gaAreas: GAAreaAvailability[];
|
|
1373
|
+
bestAvailableZones: Array<{
|
|
1374
|
+
id: string;
|
|
1375
|
+
label: string;
|
|
1376
|
+
}>;
|
|
1377
|
+
};
|
|
1378
|
+
map: {
|
|
1379
|
+
floors: Array<{
|
|
1380
|
+
id: string;
|
|
1381
|
+
name: string;
|
|
1382
|
+
}>;
|
|
1383
|
+
activeFloorId: string | null;
|
|
1384
|
+
rung: LodRung;
|
|
1385
|
+
focusedSectionId: string | null;
|
|
1386
|
+
focusedSection: SectionSummary | null;
|
|
1387
|
+
viewMode: RendererViewMode;
|
|
1388
|
+
buyerView: SeatingChartBuyerView;
|
|
1389
|
+
view3dTargetSeatId: string | null;
|
|
1390
|
+
view3dNavigationMode: SeatingChartNavigationMode;
|
|
1391
|
+
colorblindSafe: boolean;
|
|
1392
|
+
/** Chrome the HOST draws over the map, in CSS px, echoed back so a native
|
|
1393
|
+
* shell can confirm what framing is honouring. Zero when none reported. */
|
|
1394
|
+
viewportInsets: {
|
|
1395
|
+
top: number;
|
|
1396
|
+
right: number;
|
|
1397
|
+
bottom: number;
|
|
1398
|
+
left: number;
|
|
1399
|
+
};
|
|
1400
|
+
categoryFilter: string[] | null;
|
|
1401
|
+
accessibilityFilter: string[] | null;
|
|
1402
|
+
hideLimitedView: boolean;
|
|
1403
|
+
};
|
|
1404
|
+
selection: {
|
|
1405
|
+
seats: SelectedSeat[];
|
|
1406
|
+
validity: PickerSelectionValidity | null;
|
|
1407
|
+
maxSelection: number;
|
|
1408
|
+
};
|
|
1409
|
+
access: {
|
|
1410
|
+
configured: boolean;
|
|
1411
|
+
status: 'public' | 'ready' | 'expired' | 'unavailable';
|
|
1412
|
+
reason?: string;
|
|
1413
|
+
};
|
|
1414
|
+
}
|
|
1415
|
+
interface SeatingChartOptions {
|
|
1416
|
+
/** CSS selector or an HTMLElement to render into. */
|
|
1417
|
+
container: string | HTMLElement;
|
|
1418
|
+
/** Event key, e.g. `ev_xxx`. */
|
|
1419
|
+
event: string;
|
|
1420
|
+
/** API origin. Defaults to https://api.seatlayer.io. */
|
|
1421
|
+
apiBase?: string;
|
|
1423
1422
|
/**
|
|
1424
|
-
*
|
|
1425
|
-
*
|
|
1426
|
-
*
|
|
1423
|
+
* Publishable account key for direct Public-sale bootstrap of a Platform/SDK
|
|
1424
|
+
* Event. It is never buyer identity and cannot request private inventory.
|
|
1425
|
+
* An explicit buyer-access provider/token below always takes precedence.
|
|
1427
1426
|
*/
|
|
1428
|
-
|
|
1427
|
+
publicKey?: string;
|
|
1429
1428
|
/**
|
|
1430
|
-
*
|
|
1431
|
-
*
|
|
1432
|
-
* fill its box rather than be measured.
|
|
1433
|
-
*
|
|
1434
|
-
* - `'fill'` (default): container-aware. On mount the SDK probes whether the
|
|
1435
|
-
* host gave the container a DEFINITE (bounded) height:
|
|
1436
|
-
* - **Bounded container** (a fixed-height block, `height`/`max-height`,
|
|
1437
|
-
* `flex:1; min-h:0`, a resolved `%`, etc.) → the iframe fills 100% of
|
|
1438
|
-
* that block and tracks its size live via a `ResizeObserver`.
|
|
1439
|
-
* - **Content-sized container** (the block collapses to whatever the iframe
|
|
1440
|
-
* measures — typical full-page usage) → the iframe grows so its bottom
|
|
1441
|
-
* edge reaches the bottom of the viewport (`window.innerHeight -
|
|
1442
|
-
* iframe.top`), recomputed (rAF-throttled) on `resize` /
|
|
1443
|
-
* `orientationchange` / `scroll`.
|
|
1444
|
-
* Either way the result is clamped to `minHeight`. The verdict is cached but
|
|
1445
|
-
* re-probed on `resize`/`orientationchange` so a responsive host layout can
|
|
1446
|
-
* flip between the two. The legacy `seatlayer.designer.resize` message is
|
|
1447
|
-
* ignored in `'fill'` mode: it is circular, because the fixed-position shell
|
|
1448
|
-
* just echoes the iframe height.
|
|
1449
|
-
* - a number: a fixed pixel height. In this mode the legacy resize message is
|
|
1450
|
-
* still honoured (unless `autoResize` is `false`) so older hosts keep growing.
|
|
1429
|
+
* Buyer access session provider — the recommended way to render private
|
|
1430
|
+
* channel inventory (Sales Channels guide §6).
|
|
1451
1431
|
*
|
|
1452
|
-
*
|
|
1453
|
-
*
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
/** Minimum height (px) that `'fill'` mode clamps to. Defaults to `480`. */
|
|
1457
|
-
minHeight?: number;
|
|
1458
|
-
/**
|
|
1459
|
-
* Auto-grow the iframe to the height the Designer reports over the resize
|
|
1460
|
-
* protocol (`seatlayer.designer.resize`). Only applies when `height` is a fixed
|
|
1461
|
-
* number; ignored in `'fill'` mode. Defaults to `true`. Set `false` when the
|
|
1462
|
-
* host sizes a fixed-height iframe itself.
|
|
1463
|
-
*/
|
|
1464
|
-
autoResize?: boolean;
|
|
1465
|
-
/**
|
|
1466
|
-
* Called when the user presses "Try again" on the error card. Use it to mint a
|
|
1467
|
-
* fresh Designer session and call `setDesignerUrl()` with the new URL, which
|
|
1468
|
-
* recreates the iframe and returns to the loading state. When omitted, "Try
|
|
1469
|
-
* again" reloads the current `designerUrl` in place.
|
|
1432
|
+
* Called with a `reason` whenever the SDK needs a bearer: first acquisition,
|
|
1433
|
+
* a near/actual expiry, a 401 `buyer_access_expired`, a realtime reconnect,
|
|
1434
|
+
* or `refreshAccess()`. It should POST to YOUR backend, which mints the
|
|
1435
|
+
* session with your secret key and returns `{ token, expiresAt }`.
|
|
1470
1436
|
*
|
|
1471
|
-
*
|
|
1472
|
-
*
|
|
1437
|
+
* The token lives in memory for the widget's lifetime and nowhere else: never
|
|
1438
|
+
* in storage, never in a URL, never in a log or an error message. Refresh
|
|
1439
|
+
* returns the same or a narrower scope — the SDK never widens to Public sale
|
|
1440
|
+
* on its own, and a failed refresh stops the scoped operation rather than
|
|
1441
|
+
* retrying it anonymously.
|
|
1473
1442
|
*/
|
|
1474
|
-
|
|
1443
|
+
buyerAccessTokenProvider?: BuyerAccessTokenProvider;
|
|
1475
1444
|
/**
|
|
1476
|
-
*
|
|
1477
|
-
*
|
|
1478
|
-
*
|
|
1479
|
-
*
|
|
1480
|
-
* - **Renew proactively.** From each `ready` message's `expiresAt` it schedules
|
|
1481
|
-
* a silent relaunch shortly before the session lapses (~3 min ahead; for a
|
|
1482
|
-
* TTL under 15 min it renews after 80% of the remaining life, and never
|
|
1483
|
-
* sooner than 30s after `ready`). The host mints a fresh session and swaps
|
|
1484
|
-
* `designerUrl`, so the editor keeps working with no error card.
|
|
1485
|
-
* - **Recover on expiry.** If an expiry error still slips through (a slept
|
|
1486
|
-
* laptop woke past the renewal window, say) it makes ONE automatic relaunch
|
|
1487
|
-
* attempt before showing the "Try again" card, and only falls back to the
|
|
1488
|
-
* card if that relaunch also fails.
|
|
1489
|
-
*
|
|
1490
|
-
* Defaults to `true` whenever `onRequestRelaunch` is provided; a no-op without
|
|
1491
|
-
* it. Set `false` to keep the fully manual "Try again" behavior.
|
|
1445
|
+
* One-shot escape hatch for hosts that already own the session lifecycle.
|
|
1446
|
+
* Cannot be renewed — when it lapses the widget reports `onAccessExpired`
|
|
1447
|
+
* and then `onAccessUnavailable`. Prefer `buyerAccessTokenProvider`.
|
|
1492
1448
|
*/
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
/**
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
private designerOrigin;
|
|
1505
|
-
private overlay;
|
|
1506
|
-
private timeoutTimer;
|
|
1507
|
-
/** Proactive session-renewal timer; armed from each `ready`, cleared on re-mount. */
|
|
1508
|
-
private renewTimer;
|
|
1509
|
-
/** Last identity-checked session expiry, so a live policy change can re-arm. */
|
|
1510
|
-
private sessionExpiresAt;
|
|
1449
|
+
buyerAccessToken?: string | BuyerAccessToken;
|
|
1450
|
+
/** Max seats selectable at once (default 10). */
|
|
1451
|
+
maxSelection?: number;
|
|
1452
|
+
/** Object ids or public labels selected after live availability is loaded. */
|
|
1453
|
+
selectedObjects?: string[];
|
|
1454
|
+
/** Object ids or public labels the buyer may select. Omit for all free objects. */
|
|
1455
|
+
selectableObjects?: string[] | null;
|
|
1456
|
+
/** Require exactly this many seated/table guest units before the selection is valid. */
|
|
1457
|
+
numberOfPlacesToSelect?: number;
|
|
1458
|
+
/** Optional local selection guards, enforced again before hold. */
|
|
1459
|
+
selectionValidators?: PickerSelectionValidator[];
|
|
1511
1460
|
/**
|
|
1512
|
-
*
|
|
1513
|
-
*
|
|
1514
|
-
*
|
|
1461
|
+
* BCP 47 language for the widget UI — `'de'`, `'es-MX'`, etc. Falls back to
|
|
1462
|
+
* the browser language, then English. 37 languages ship. The German
|
|
1463
|
+
* bundle (etc.) is fetched on demand so unused languages cost nothing.
|
|
1515
1464
|
*/
|
|
1516
|
-
|
|
1517
|
-
private phase;
|
|
1465
|
+
locale?: string;
|
|
1518
1466
|
/**
|
|
1519
|
-
*
|
|
1520
|
-
*
|
|
1521
|
-
* shed the chart/workspace identity the live session already established.
|
|
1467
|
+
* Per-key string overrides layered over the active locale — white-label copy
|
|
1468
|
+
* without shipping a whole bundle, e.g. `{ 'map.fromPrice': 'ab {price}' }`.
|
|
1522
1469
|
*/
|
|
1523
|
-
|
|
1524
|
-
private restoreContainerPosition;
|
|
1525
|
-
private pinned;
|
|
1526
|
-
private frameStyleBeforeFs;
|
|
1527
|
-
private docOverflowBeforeFs;
|
|
1528
|
-
private bodyOverflowBeforeFs;
|
|
1529
|
-
private fsKeyHandler;
|
|
1530
|
-
/** Latest height (px string) the Designer reported; re-applied after unpin. */
|
|
1531
|
-
private lastAutoHeight;
|
|
1532
|
-
private fillRaf;
|
|
1533
|
-
private reprobeRaf;
|
|
1534
|
-
private fillListening;
|
|
1535
|
-
/** Resolved container element (fill measurement + ResizeObserver target). */
|
|
1536
|
-
private containerEl;
|
|
1537
|
-
/** Cached fill verdict: 'container' = bounded block, 'viewport' = full page. */
|
|
1538
|
-
private fillMode;
|
|
1539
|
-
/** Live block-size tracking in container-fill mode; disconnected on destroy. */
|
|
1540
|
-
private resizeObs;
|
|
1541
|
-
constructor(options: EmbeddedDesignerOptions);
|
|
1542
|
-
mount(): HTMLIFrameElement;
|
|
1543
|
-
/** Replace the iframe instead of assigning a new fragment to an existing one. */
|
|
1544
|
-
setDesignerUrl(designerUrl: string): HTMLIFrameElement;
|
|
1545
|
-
getIframe(): HTMLIFrameElement | null;
|
|
1546
|
-
/** Update iframe sizing without replacing the live Designer session. */
|
|
1547
|
-
setSizing(height: 'fill' | number | undefined, minHeight: number | undefined): void;
|
|
1548
|
-
/** Update renewal/expiry-recovery policy without replacing the iframe. */
|
|
1549
|
-
setRelaunchPolicy(onRequestRelaunch: (() => void) | undefined, autoRenewSession: boolean | undefined): void;
|
|
1550
|
-
destroy(): void;
|
|
1551
|
-
private loadingStateEnabled;
|
|
1552
|
-
private autoResizeEnabled;
|
|
1553
|
-
/** Fill mode is the default; a numeric `height` opts into a fixed pixel box. */
|
|
1554
|
-
private fillEnabled;
|
|
1555
|
-
/** Write an SDK-managed height with `!important` so a host theme can't win. */
|
|
1556
|
-
private setFrameHeight;
|
|
1470
|
+
messages?: Record<string, string>;
|
|
1557
1471
|
/**
|
|
1558
|
-
*
|
|
1559
|
-
* fixed block the embed should fill 100% of — versus a content-sized container
|
|
1560
|
-
* that collapses to whatever the iframe measures (full-page usage).
|
|
1472
|
+
* Show an in-chart language switcher offering exactly these languages.
|
|
1561
1473
|
*
|
|
1562
|
-
*
|
|
1563
|
-
*
|
|
1564
|
-
*
|
|
1565
|
-
*
|
|
1566
|
-
*
|
|
1567
|
-
* heights, and leaves a mere `min-height` floor classified as content-sized so
|
|
1568
|
-
* full-page hosts keep the old viewport-fill behavior.
|
|
1569
|
-
*/
|
|
1570
|
-
private detectFillMode;
|
|
1571
|
-
/**
|
|
1572
|
-
* Size the iframe for the current fill verdict, clamped to `minHeight`. In
|
|
1573
|
-
* container mode it fills 100% of the bounded block; in viewport mode its
|
|
1574
|
-
* bottom edge meets the bottom of the viewport (`window.innerHeight - top`).
|
|
1575
|
-
* No-op while pinned fullscreen (the pin fills the viewport itself).
|
|
1474
|
+
* Opt-in and curated on purpose: the chart sits inside someone else's page,
|
|
1475
|
+
* a multilingual host already has its own switcher, and two that can
|
|
1476
|
+
* disagree is worse than either alone. A curated list also beats all 37 — a
|
|
1477
|
+
* German venue wants de/en/pl in the menu, not Welsh. Fewer than two
|
|
1478
|
+
* resolvable entries renders nothing.
|
|
1576
1479
|
*/
|
|
1577
|
-
|
|
1578
|
-
/**
|
|
1579
|
-
|
|
1480
|
+
languages?: string[];
|
|
1481
|
+
/** ISO 4217 currency for on-map prices (default USD). */
|
|
1482
|
+
currency?: string;
|
|
1580
1483
|
/**
|
|
1581
|
-
*
|
|
1582
|
-
*
|
|
1583
|
-
*
|
|
1484
|
+
* Colorblind-safe rendering: category hues switch to an Okabe-Ito palette
|
|
1485
|
+
* and booked seats render hollow, so state never relies on hue alone.
|
|
1486
|
+
* Toggleable later with setColorblindSafe().
|
|
1584
1487
|
*/
|
|
1585
|
-
|
|
1586
|
-
/**
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1488
|
+
colorblindSafe?: boolean;
|
|
1489
|
+
/** Host-authoritative colors for the drawn canvas, separate from native chrome. */
|
|
1490
|
+
mapTheme?: PickerMapTheme;
|
|
1491
|
+
/** Light / dark / follow-the-reader for the DRAWN map — the embed has no
|
|
1492
|
+
* chrome to re-token, so a mode here means only the canvas ground, and
|
|
1493
|
+
* `mapTheme` still outranks it. Switchable with {@link SeatingChart.setThemeMode}. */
|
|
1494
|
+
theme?: {
|
|
1495
|
+
mode?: ThemeMode | null;
|
|
1496
|
+
};
|
|
1497
|
+
/** Initial canvas projection.
|
|
1498
|
+
* @deprecated `'isometric'` and `'perspective'` are retired in favour of the
|
|
1499
|
+
* real 3D venue view (`setBuyerView('venue3d')`); they remain accepted for
|
|
1500
|
+
* source compatibility and will be removed in the next major. Use `'flat'`. */
|
|
1501
|
+
initialView?: RendererViewMode;
|
|
1502
|
+
/** Offer the real, lazy-loaded interactive venue view. Default true. */
|
|
1503
|
+
enable3D?: boolean;
|
|
1504
|
+
/** Offer authored/generated view-from-seat inspection. Default true. */
|
|
1505
|
+
enableSeatView?: boolean;
|
|
1506
|
+
/** Optional device-specific ceiling for offering the venue WebGL scene. */
|
|
1507
|
+
max3DSeats?: number;
|
|
1590
1508
|
/**
|
|
1591
|
-
*
|
|
1592
|
-
*
|
|
1593
|
-
*
|
|
1509
|
+
* Built-in seat tooltip on mouse hover (seat · category · price · status).
|
|
1510
|
+
* Rendered inside the widget so every host gets it; default true. Turn off
|
|
1511
|
+
* to draw your own popover from onSeatHover.
|
|
1594
1512
|
*/
|
|
1595
|
-
|
|
1596
|
-
/**
|
|
1597
|
-
|
|
1598
|
-
|
|
1513
|
+
seatTooltip?: boolean;
|
|
1514
|
+
/** Internal hosted-runtime control. Defaults true for direct web embeds. */
|
|
1515
|
+
showTestModeIndicator?: boolean;
|
|
1516
|
+
/** Internal hosted-runtime control. Defaults true, subject to white-label entitlement. */
|
|
1517
|
+
showAttribution?: boolean;
|
|
1599
1518
|
/**
|
|
1600
|
-
*
|
|
1601
|
-
*
|
|
1602
|
-
*
|
|
1519
|
+
* Seat hover with everything a popover needs (category label/color, resolved
|
|
1520
|
+
* tier-aware price, live status, currency); null on hover-out. Fires whether
|
|
1521
|
+
* or not the built-in tooltip is enabled.
|
|
1603
1522
|
*/
|
|
1604
|
-
|
|
1605
|
-
|
|
1523
|
+
onSeatHover?: (details: SeatHoverDetails | null) => void;
|
|
1524
|
+
onSelectionChange?: (seats: SelectedSeat[]) => void;
|
|
1525
|
+
/** Selection-rule state after each selection change. */
|
|
1526
|
+
onSelectionValidityChange?: (state: PickerSelectionValidity) => void;
|
|
1527
|
+
/** The configured selection rules have just become valid. */
|
|
1528
|
+
onSelectionValid?: (seats: SelectedSeat[]) => void;
|
|
1529
|
+
/** The configured selection rules have just become invalid. */
|
|
1530
|
+
onSelectionInvalid?: (state: PickerSelectionValidity) => void;
|
|
1531
|
+
/** A manual or programmatic selection reached the active maximum. */
|
|
1532
|
+
onSelectionLimit?: (maxSelection: number) => void;
|
|
1533
|
+
onHold?: (result: HoldResult) => void;
|
|
1534
|
+
/** A prior active hold was restored with resumeHold(). */
|
|
1535
|
+
onHoldRestored?: (result: HoldResult) => void;
|
|
1536
|
+
onHoldExpired?: () => void;
|
|
1537
|
+
onGAClick?: (area: GAAreaAvailability) => void;
|
|
1606
1538
|
/**
|
|
1607
|
-
*
|
|
1608
|
-
*
|
|
1609
|
-
*
|
|
1610
|
-
*
|
|
1611
|
-
* - normal TTL (≥ 15 min): renew {@link RENEW_LEAD_MS} (~3 min) before expiry;
|
|
1612
|
-
* - short TTL (< 15 min): renew after {@link RENEW_SHORT_TTL_FRACTION} (80%) of
|
|
1613
|
-
* the remaining life, so the lead can't overshoot the whole session;
|
|
1614
|
-
* - either way, never sooner than {@link RENEW_MIN_DELAY_MS} (30s) after `ready`
|
|
1615
|
-
* so a burst of `ready` messages can't spin the host.
|
|
1616
|
-
*
|
|
1617
|
-
* Re-armed on every `ready`; cleared on destroy / setDesignerUrl (via re-mount).
|
|
1618
|
-
* A no-op when auto-renewal is off or `expiresAt` is missing/already past — the
|
|
1619
|
-
* expiry-error path recovers a session that has already lapsed.
|
|
1539
|
+
* Mirror of {@link SeatPickerOptions.onGAPrompt}. The low-level chart draws no
|
|
1540
|
+
* quantity UI of its own, so this fires purely as the "the buyer wants to pick
|
|
1541
|
+
* a quantity here" signal, with the same pre-computed `min`/`max`/`tiers` the
|
|
1542
|
+
* full widget would have used; the return value is accepted and ignored.
|
|
1620
1543
|
*/
|
|
1621
|
-
|
|
1622
|
-
private ensureContainerPositioned;
|
|
1623
|
-
private restoreContainerStyle;
|
|
1624
|
-
private removeOverlay;
|
|
1625
|
-
private showError;
|
|
1626
|
-
private handleTryAgain;
|
|
1544
|
+
onGAPrompt?: (prompt: GAPromptRequest) => boolean | void;
|
|
1627
1545
|
/**
|
|
1628
|
-
*
|
|
1629
|
-
*
|
|
1546
|
+
* The buyer access session lapsed. `refreshed` says whether the provider
|
|
1547
|
+
* already recovered it — false means private inventory is now unavailable and
|
|
1548
|
+
* `onAccessUnavailable` follows. Distinct from `onError` on purpose: this is
|
|
1549
|
+
* never a network failure (guide §10).
|
|
1630
1550
|
*/
|
|
1631
|
-
|
|
1632
|
-
private buildSkeleton;
|
|
1633
|
-
private buildErrorCard;
|
|
1634
|
-
private handleMessage;
|
|
1635
|
-
}
|
|
1636
|
-
|
|
1637
|
-
/**
|
|
1638
|
-
* Buyer-safe ticket-offer availability shared by the canonical picker and the
|
|
1639
|
-
* hosted event-page templates.
|
|
1640
|
-
*
|
|
1641
|
-
* This module intentionally owns the wire parser. A hosted page, iframe, popup
|
|
1642
|
-
* and SDK mount must refuse or accept the same payload; duplicating this reader
|
|
1643
|
-
* is how one surface eventually prints a price another surface will not charge.
|
|
1644
|
-
*/
|
|
1645
|
-
type SaleState = 'on-sale' | 'low' | 'sold-out' | 'presale' | 'closed';
|
|
1646
|
-
interface TicketOfferSummary {
|
|
1647
|
-
/** Legacy ordering fields kept for older page templates and payloads. */
|
|
1648
|
-
index: number;
|
|
1649
|
-
count: number;
|
|
1650
|
-
/** Units currently available at this offer price; null means unlimited. */
|
|
1651
|
-
remaining: number | null;
|
|
1652
|
-
/** Buyer-facing fields added by the offers UX. Absent on older workers. */
|
|
1653
|
-
id?: string;
|
|
1654
|
-
name?: string;
|
|
1655
|
-
categoryKey?: string | null;
|
|
1656
|
-
startsAt?: number | null;
|
|
1657
|
-
endsAt?: number | null;
|
|
1658
|
-
}
|
|
1659
|
-
interface TicketOfferPrice {
|
|
1660
|
-
categoryKey: string;
|
|
1661
|
-
/** Major units. What a hold on this category is charged right now. */
|
|
1662
|
-
price: number;
|
|
1663
|
-
/** Major units, or null. Printed only when genuinely higher. */
|
|
1664
|
-
previousPrice: number | null;
|
|
1665
|
-
/** Offer provenance for the price row. Absent on older workers. */
|
|
1666
|
-
offerId?: string;
|
|
1667
|
-
offerName?: string;
|
|
1668
|
-
remaining?: number | null;
|
|
1669
|
-
startsAt?: number | null;
|
|
1670
|
-
endsAt?: number | null;
|
|
1671
|
-
}
|
|
1672
|
-
interface ChannelPriceOverride {
|
|
1673
|
-
categoryKey: string;
|
|
1674
|
-
tierId: string | null;
|
|
1675
|
-
price: number;
|
|
1676
|
-
}
|
|
1677
|
-
/** Pricing configuration projected only for the private channels in this grant. */
|
|
1678
|
-
interface BuyerChannelPricing {
|
|
1679
|
-
assignmentVersion: number;
|
|
1680
|
-
channels: Array<{
|
|
1681
|
-
channelId: string;
|
|
1682
|
-
pricingVersion: number;
|
|
1683
|
-
priceOverrides: ChannelPriceOverride[];
|
|
1684
|
-
}>;
|
|
1685
|
-
objects: Array<{
|
|
1686
|
-
label: string;
|
|
1687
|
-
channelId: string;
|
|
1688
|
-
}>;
|
|
1689
|
-
}
|
|
1690
|
-
interface TicketOfferAvailability {
|
|
1691
|
-
state: SaleState;
|
|
1692
|
-
/** Currently advertised offer price, in minor units. */
|
|
1693
|
-
fromPrice: number | null;
|
|
1694
|
-
previousPrice: number | null;
|
|
1695
|
-
currency: string | null;
|
|
1696
|
-
/** The highest-priority active buy offer, when one exists. */
|
|
1697
|
-
release: TicketOfferSummary | null;
|
|
1698
|
-
/** The next scheduled price offer. It does not close ordinary ticket sales. */
|
|
1699
|
-
upcoming: TicketOfferSummary | null;
|
|
1700
|
-
/** Server-resolved active offer prices by category, in major units. */
|
|
1701
|
-
prices: TicketOfferPrice[];
|
|
1702
|
-
channelPricing: BuyerChannelPricing | null;
|
|
1703
|
-
}
|
|
1704
|
-
/** Parse a public offer payload without repairing a half-understood price. */
|
|
1705
|
-
declare function parseTicketOfferAvailability(body: unknown): TicketOfferAvailability | null;
|
|
1706
|
-
/** Translate the server-resolved category map into SeatPicker pricing. */
|
|
1707
|
-
declare function ticketOfferPrices(availability: TicketOfferAvailability | null): Record<string, number>;
|
|
1708
|
-
|
|
1709
|
-
/**
|
|
1710
|
-
* pickerTypes — the SeatPicker public option/theme/pricing contract, plus the
|
|
1711
|
-
* two internal shapes (`SectionLike`, `PriceBand`) the picker reads off a
|
|
1712
|
-
* ChartDoc.
|
|
1713
|
-
*
|
|
1714
|
-
* Split out of SeatPicker.ts verbatim; these declarations are the widget's
|
|
1715
|
-
* published API surface, so SeatPicker.ts re-exports every public name from
|
|
1716
|
-
* here and `@seatlayer/js`'s entry (src/index.ts) is untouched. Types only —
|
|
1717
|
-
* nothing in this file emits a byte of runtime JavaScript.
|
|
1718
|
-
*/
|
|
1719
|
-
|
|
1720
|
-
/**
|
|
1721
|
-
* Stable checkout-handoff contract (P4). Passed as the THIRD argument to
|
|
1722
|
-
* `onCheckout(hold, seats, handoff)` — additive, so the legacy `(hold, seats)`
|
|
1723
|
-
* shape used by DesiPass web-v2 (SDK 0.7.3+) is untouched. This is the object to
|
|
1724
|
-
* build your order against: it is self-contained (holdId, expiry, currency, and
|
|
1725
|
-
* per-line tier + price) and never changes shape across minor releases.
|
|
1726
|
-
*/
|
|
1727
|
-
interface CheckoutLineItem {
|
|
1728
|
-
/** Seat label (or GA synthetic-unit label) — the stable booking identity. */
|
|
1729
|
-
label: string;
|
|
1551
|
+
onAccessExpired?: (event: BuyerAccessExpiredEvent) => void;
|
|
1730
1552
|
/**
|
|
1731
|
-
*
|
|
1732
|
-
*
|
|
1733
|
-
*
|
|
1553
|
+
* Private inventory is unavailable and refreshing will not fix it — revoked,
|
|
1554
|
+
* paused, wrong origin/event/mode, or the provider failed. Carries a reason,
|
|
1555
|
+
* never a channel name, id, colour or count.
|
|
1734
1556
|
*/
|
|
1735
|
-
|
|
1557
|
+
onAccessUnavailable?: (event: BuyerAccessUnavailableEvent) => void;
|
|
1736
1558
|
/**
|
|
1737
|
-
*
|
|
1738
|
-
*
|
|
1559
|
+
* Selected-but-unheld units stopped being selectable — someone else took
|
|
1560
|
+
* them, or an allocation change moved them out of this buyer's scope. The
|
|
1561
|
+
* widget has already dropped them from the selection.
|
|
1739
1562
|
*/
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
objectId: string;
|
|
1743
|
-
objectType: 'seat' | 'booth' | 'ga' | 'table';
|
|
1744
|
-
categoryKey: string;
|
|
1745
|
-
/** Chosen ticket tier id (Adult/Child/…), or null when the category has no tiers. */
|
|
1746
|
-
tierId: string | null;
|
|
1747
|
-
/** Unit price in MAJOR currency units (e.g. 45 = 45.00). Server-authoritative. */
|
|
1748
|
-
unitPrice: number;
|
|
1749
|
-
/** ISO-4217, resolved server-side (per-event override → org → USD). */
|
|
1750
|
-
currency: string;
|
|
1751
|
-
quantity: number;
|
|
1752
|
-
}
|
|
1753
|
-
interface CheckoutHandoff {
|
|
1754
|
-
/** Server hold id — pass this to YOUR book call. */
|
|
1755
|
-
holdId: string;
|
|
1756
|
-
/** Epoch ms the hold expires (after any extensions). */
|
|
1757
|
-
expiresAt: number;
|
|
1758
|
-
/** ISO-4217 currency for the whole order. */
|
|
1759
|
-
currency: string;
|
|
1760
|
-
/** Priced line items (tier + unit price + currency), server-authoritative. */
|
|
1761
|
-
lineItems: CheckoutLineItem[];
|
|
1762
|
-
/** Convenience total in major units (Σ unitPrice × quantity). */
|
|
1763
|
-
total: number;
|
|
1764
|
-
}
|
|
1765
|
-
/** Host-authoritative pricing — see {@link SeatPickerOptions.pricing}. */
|
|
1766
|
-
interface SeatPickerPricing {
|
|
1767
|
-
/** Unit prices by category key: a flat number, or `{ base, tiers: { tierId: price } }`. */
|
|
1768
|
-
prices?: Record<string, number | {
|
|
1769
|
-
base?: number;
|
|
1770
|
-
tiers?: Record<string, number>;
|
|
1771
|
-
}>;
|
|
1772
|
-
/** Custom money renderer (e.g. `(n) => n + '€'`). Defaults to Intl currency formatting. */
|
|
1773
|
-
formatter?: (amount: number, currency: string) => string;
|
|
1774
|
-
}
|
|
1775
|
-
/** Optional constraints for the server-authoritative best-available pick. */
|
|
1776
|
-
interface SeatPickerBestAvailableOptions {
|
|
1777
|
-
/** Prefer a contiguous premium block, falling back to the best overall block. */
|
|
1778
|
-
preferPremium?: boolean;
|
|
1779
|
-
/** Restrict the search to one configured chart zone. */
|
|
1780
|
-
zoneId?: string;
|
|
1781
|
-
}
|
|
1782
|
-
/** Buyer-facing surface shown by the full picker widget. */
|
|
1783
|
-
type SeatPickerBuyerView = 'map' | 'venue3d';
|
|
1784
|
-
/** Optional camera intent when switching the buyer-facing surface. */
|
|
1785
|
-
interface SeatPickerBuyerViewOptions {
|
|
1786
|
-
/** Enter (or remain in) 3D and fly the camera to this seat id. */
|
|
1787
|
-
flyToSeatId?: string;
|
|
1788
|
-
/** When already in 3D, return the camera to the venue overview. */
|
|
1789
|
-
resetView?: boolean;
|
|
1790
|
-
}
|
|
1791
|
-
/** Host theme overrides — any subset; unset keys fall back to the org's chart theme, then defaults. */
|
|
1792
|
-
interface SeatPickerTheme {
|
|
1563
|
+
onSelectedObjectUnavailable?: (event: SelectedObjectUnavailableEvent) => void;
|
|
1564
|
+
onError?: (err: unknown) => void;
|
|
1793
1565
|
/**
|
|
1794
|
-
*
|
|
1566
|
+
* What the BUYER sees when the chart cannot load.
|
|
1795
1567
|
*
|
|
1796
|
-
*
|
|
1797
|
-
*
|
|
1798
|
-
*
|
|
1799
|
-
*
|
|
1800
|
-
*
|
|
1801
|
-
*
|
|
1568
|
+
* `'message'` (the default) renders a plain, styleable notice with a Try
|
|
1569
|
+
* again button. This used to be silent unconditionally: `render()` returned
|
|
1570
|
+
* with an EMPTY mounted div and only `onError` fired, so a host that had not
|
|
1571
|
+
* wired `onError` — or had wired it to a logger — showed buyers a blank
|
|
1572
|
+
* rectangle where the seat map belongs, on the host's own domain, which
|
|
1573
|
+
* reads as a broken website rather than a temporary fault. `SeatPicker` has
|
|
1574
|
+
* always failed loud with a retry; this is the embed class catching up.
|
|
1802
1575
|
*
|
|
1803
|
-
* `'
|
|
1804
|
-
*
|
|
1576
|
+
* `'none'` restores the silent behaviour for hosts that render their own
|
|
1577
|
+
* failure UI from `onError`.
|
|
1805
1578
|
*/
|
|
1806
|
-
|
|
1807
|
-
/**
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
/**
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
/**
|
|
1824
|
-
|
|
1825
|
-
/**
|
|
1826
|
-
|
|
1827
|
-
/**
|
|
1828
|
-
|
|
1579
|
+
errorDisplay?: 'message' | 'none';
|
|
1580
|
+
/** Which pieces of the IMMERSIVE scene's own chrome this embed draws. The
|
|
1581
|
+
* 2D chrome each has its own option above; the 3D caption, seat stepper and
|
|
1582
|
+
* camera dock come from inside the lazy venue chunk, where an embedding
|
|
1583
|
+
* host had no way to reach them — so a native shell that already draws all
|
|
1584
|
+
* three drew them twice. Absent or `true` = drawn, exactly as before. */
|
|
1585
|
+
chrome?: {
|
|
1586
|
+
view3dCaption?: boolean;
|
|
1587
|
+
view3dSeatStepper?: boolean;
|
|
1588
|
+
view3dControlDock?: boolean;
|
|
1589
|
+
};
|
|
1590
|
+
/**
|
|
1591
|
+
* Multi-floor charts only: fires when the buyer taps a deck in the stacked
|
|
1592
|
+
* 3D view, after the picker switches to that floor — lets the host page sync
|
|
1593
|
+
* its own floor UI (tabs, labels) with the map.
|
|
1594
|
+
*/
|
|
1595
|
+
onDeckTap?: (floorId: string) => void;
|
|
1596
|
+
/** Big-venue section focus state for host-owned navigation chrome. */
|
|
1597
|
+
onSectionFocus?: (summary: SectionSummary | null) => void;
|
|
1598
|
+
/** Availability changed after a live frame or explicit refresh. */
|
|
1599
|
+
onStatusChange?: () => void;
|
|
1600
|
+
/** The server closed sales for this event. */
|
|
1601
|
+
onSalesClosed?: () => void;
|
|
1602
|
+
/** A programmatic/native map-control action changed serializable map state. */
|
|
1603
|
+
onMapStateChange?: () => void;
|
|
1604
|
+
/** rAF-coalesced camera-frame signal for in-page overlays; not native state. */
|
|
1605
|
+
onViewChange?: () => void;
|
|
1606
|
+
/** Real buyer-view transitions and 3D camera targets. */
|
|
1607
|
+
onBuyerViewChange?: (state: {
|
|
1608
|
+
view: SeatingChartBuyerView;
|
|
1609
|
+
seatId?: string;
|
|
1610
|
+
}) => void;
|
|
1829
1611
|
/**
|
|
1830
|
-
*
|
|
1831
|
-
*
|
|
1832
|
-
*
|
|
1833
|
-
* the sidebar. The seat map is a canvas, painted from the chart document's
|
|
1834
|
-
* own `ChartTheme`, so a host could re-ink the whole widget and still be
|
|
1835
|
-
* looking at somebody else's dark venue in the middle of it (which is exactly
|
|
1836
|
-
* what SeatLayer's own light event-page palettes did, found 2026-08-07).
|
|
1837
|
-
*
|
|
1838
|
-
* Nested rather than flattened because `background` already means the
|
|
1839
|
-
* WIDGET's background here and the canvas ground is a different surface —
|
|
1840
|
-
* two things one word cannot carry.
|
|
1841
|
-
*
|
|
1842
|
-
* Set it only when you can vouch for the result: these colours are drawn
|
|
1843
|
-
* behind and beside live seat statuses (held, sold, selected), and the map is
|
|
1844
|
-
* the one part of this widget a buyer has to be able to read.
|
|
1612
|
+
* Non-blocking, localized selection advice — currently the orphan-seat hint
|
|
1613
|
+
* (the selection would strand a single free seat between taken neighbors).
|
|
1614
|
+
* `null` clears it. Purely informational; nothing is ever prevented.
|
|
1845
1615
|
*/
|
|
1846
|
-
|
|
1616
|
+
onHint?: (message: string | null) => void;
|
|
1847
1617
|
}
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
/**
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1618
|
+
declare class SeatingChart {
|
|
1619
|
+
private readonly opts;
|
|
1620
|
+
private readonly controller;
|
|
1621
|
+
/** Publishable key used only by the public-only direct bootstrap path. */
|
|
1622
|
+
readonly publicKey?: string;
|
|
1623
|
+
private mount;
|
|
1624
|
+
private hostEl;
|
|
1855
1625
|
/**
|
|
1856
|
-
*
|
|
1857
|
-
*
|
|
1858
|
-
*
|
|
1626
|
+
* Native hosts can render a Flutter/Swift/Kotlin decision surface above this
|
|
1627
|
+
* DOM tree. UIKit platform views still participate in hit testing beneath a
|
|
1628
|
+
* composited native overlay, so the runtime must be able to make its own DOM
|
|
1629
|
+
* inert rather than relying on the host's visual stacking alone.
|
|
1859
1630
|
*/
|
|
1860
|
-
|
|
1631
|
+
private interactionEnabled_;
|
|
1632
|
+
/** The organizer's language for this event, learned when the chart resolves. */
|
|
1633
|
+
private eventLocale;
|
|
1634
|
+
private rendered;
|
|
1635
|
+
private mode_;
|
|
1636
|
+
private eventInfo;
|
|
1637
|
+
private maxSelection_;
|
|
1638
|
+
private colorblindSafe_;
|
|
1639
|
+
private readonly hostSurface;
|
|
1640
|
+
private categoryFilter_;
|
|
1641
|
+
private accessibilityFilter_;
|
|
1642
|
+
private hideLimitedView_;
|
|
1643
|
+
private focusedSection_;
|
|
1644
|
+
/** Last rung already exposed to native chrome; raw camera frames stay in-canvas. */
|
|
1645
|
+
private lastReportedViewRung_;
|
|
1646
|
+
private accessState_;
|
|
1647
|
+
private tipEl;
|
|
1648
|
+
private tipPos;
|
|
1649
|
+
private onTipMove;
|
|
1650
|
+
/** Null for the ordinary public chart — the tokenless path is untouched. */
|
|
1651
|
+
private readonly access;
|
|
1652
|
+
private readonly api;
|
|
1653
|
+
private readonly apiBase;
|
|
1654
|
+
private readonly buyerAssetUrls;
|
|
1655
|
+
private readonly immersive;
|
|
1656
|
+
private realtime;
|
|
1657
|
+
constructor(options: SeatingChartOptions);
|
|
1861
1658
|
/**
|
|
1862
|
-
*
|
|
1863
|
-
*
|
|
1864
|
-
*
|
|
1865
|
-
* from SeatLayer and receives chart + inventory in the same request.
|
|
1866
|
-
*
|
|
1867
|
-
* This is not buyer identity and cannot request private channels. An explicit
|
|
1868
|
-
* `buyerAccessTokenProvider` or `buyerAccessToken` below always takes
|
|
1869
|
-
* precedence for login, presale, partner or other scoped inventory.
|
|
1659
|
+
* Camera x/y/scale is renderer-local and deliberately absent from the native
|
|
1660
|
+
* picker snapshot. Keep pan and pinch frames on the canvas; only a semantic
|
|
1661
|
+
* rung transition needs to wake native chrome.
|
|
1870
1662
|
*/
|
|
1871
|
-
|
|
1663
|
+
private handleViewChange;
|
|
1664
|
+
/** Record the current rung before publishing an explicit state mutation. */
|
|
1665
|
+
private notifyMapStateChange;
|
|
1666
|
+
/** Fetch the chart, mount the renderer, seed statuses and go live. Idempotent. */
|
|
1667
|
+
render(): Promise<this>;
|
|
1872
1668
|
/**
|
|
1873
|
-
*
|
|
1874
|
-
*
|
|
1875
|
-
*
|
|
1876
|
-
*
|
|
1877
|
-
*
|
|
1878
|
-
*
|
|
1879
|
-
* mints the session with your secret key and returns `{ token, expiresAt }`.
|
|
1880
|
-
*
|
|
1881
|
-
* The token lives in memory for the widget's lifetime and nowhere else: never
|
|
1882
|
-
* in storage, never in a URL, never in a log or an error message. Refresh
|
|
1883
|
-
* returns the same or a narrower scope; the widget never widens to Public
|
|
1884
|
-
* sale on its own, and a failed refresh stops the scoped operation rather
|
|
1885
|
-
* than retrying it anonymously. Any held seats stay held — a hold is
|
|
1886
|
-
* relinquished by its own opaque capability, not by channel access, so
|
|
1887
|
-
* losing access never strands inventory (guide §9).
|
|
1888
|
-
*
|
|
1889
|
-
* Ignored when a custom `transport` is supplied: that host owns its own
|
|
1890
|
-
* credentials.
|
|
1669
|
+
* Attribution badge pinned to the embed's bottom-right, linking to
|
|
1670
|
+
* seatlayer.io. Rendered as an absolutely-positioned overlay with
|
|
1671
|
+
* self-contained inline styles — the SDK embed ships no widget CSS, and an
|
|
1672
|
+
* overlay keeps it out of the layout flow so it never disturbs the SDK v0.22
|
|
1673
|
+
* fill-height resize contract. Mirrors the full widget's mark + wordmark and
|
|
1674
|
+
* reuses the `picker.poweredBy` i18n string.
|
|
1891
1675
|
*/
|
|
1892
|
-
|
|
1676
|
+
private buildBadge;
|
|
1677
|
+
private placeTooltip;
|
|
1678
|
+
private updateTooltip;
|
|
1893
1679
|
/**
|
|
1894
|
-
*
|
|
1895
|
-
*
|
|
1896
|
-
*
|
|
1680
|
+
* Whether the SERVED event is a live or a test event (`sk_test_` keys create
|
|
1681
|
+
* test events, which never book real inventory). `null` before render()
|
|
1682
|
+
* resolves — the mode comes from the server with the chart, not from options.
|
|
1683
|
+
*
|
|
1684
|
+
* The widget already surfaces this visually with the test-mode ribbon; this
|
|
1685
|
+
* getter is for hosts that draw their own chrome — notably a native WebView
|
|
1686
|
+
* wrapper, which must be able to tell an integrator that the build they are
|
|
1687
|
+
* about to ship is pointed at a test event.
|
|
1897
1688
|
*/
|
|
1898
|
-
buyerAccessToken?: string | BuyerAccessToken;
|
|
1899
|
-
/** Max seats selectable at once (default 10). */
|
|
1900
|
-
maxSelection?: number;
|
|
1901
|
-
/** Object ids or public labels selected after live availability is loaded. */
|
|
1902
|
-
selectedObjects?: string[];
|
|
1903
|
-
/** Object ids or public labels the buyer may select. Omit for all free objects. */
|
|
1904
|
-
selectableObjects?: string[] | null;
|
|
1905
|
-
/** Require exactly this many total seated/table/GA guest units before checkout. */
|
|
1906
|
-
numberOfPlacesToSelect?: number;
|
|
1907
|
-
/** Optional sale guards evaluated after every change and enforced before a
|
|
1908
|
-
* hold: minimum quantity, consecutive seats, and/or no stranded singles. */
|
|
1909
|
-
selectionValidators?: PickerSelectionValidator[];
|
|
1910
1689
|
/**
|
|
1911
|
-
*
|
|
1912
|
-
*
|
|
1913
|
-
*
|
|
1690
|
+
* The opt-in language switcher, offering exactly the languages the host
|
|
1691
|
+
* named. Absent unless `languages` lists at least two — a menu with one
|
|
1692
|
+
* entry is furniture, and an unrequested one duplicates the switcher a
|
|
1693
|
+
* multilingual host site already has.
|
|
1694
|
+
*
|
|
1695
|
+
* Each language names itself (`LOCALE_NAMES`): a reader scanning for their
|
|
1696
|
+
* own language finds "Deutsch", never "German". An English list is
|
|
1697
|
+
* unreadable to exactly the people who need it.
|
|
1914
1698
|
*/
|
|
1915
|
-
|
|
1916
|
-
/** Per-key string overrides layered over the active locale. */
|
|
1917
|
-
messages?: Record<string, string>;
|
|
1699
|
+
private buildLanguageSwitcher;
|
|
1918
1700
|
/**
|
|
1919
|
-
*
|
|
1701
|
+
* Change the language of a LIVE chart, keeping the buyer's selection.
|
|
1920
1702
|
*
|
|
1921
|
-
*
|
|
1922
|
-
*
|
|
1923
|
-
*
|
|
1924
|
-
*
|
|
1925
|
-
*
|
|
1703
|
+
* `locale` is otherwise read once at render, which is fine for a page that
|
|
1704
|
+
* knows its language up front and useless for one with a language switcher.
|
|
1705
|
+
* The competing embed API can only `rerender()`, and that clears the
|
|
1706
|
+
* selection — losing someone's seats because they changed language is not an
|
|
1707
|
+
* acceptable trade, so this rebuilds the map through `refreshMapCopy()`,
|
|
1708
|
+
* which restores the selection on the far side.
|
|
1926
1709
|
*
|
|
1927
|
-
*
|
|
1710
|
+
* Returns the locale that actually became active: an unsupported or
|
|
1711
|
+
* not-yet-translated tag resolves to English rather than throwing, exactly as
|
|
1712
|
+
* it does at first render.
|
|
1928
1713
|
*/
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1714
|
+
setLocale(next: string | null | undefined): Promise<string>;
|
|
1715
|
+
getMode(): 'live' | 'test' | null;
|
|
1716
|
+
/** Atomic, token-free display state for native-owned picker chrome. */
|
|
1717
|
+
getPickerState(): SeatingChartPickerState;
|
|
1718
|
+
getCategoryAvailability(): Record<string, number>;
|
|
1719
|
+
getBestAvailableZones(): Array<{
|
|
1720
|
+
id: string;
|
|
1721
|
+
label: string;
|
|
1722
|
+
}>;
|
|
1723
|
+
getActiveFloorId(): string | null;
|
|
1724
|
+
getRung(): LodRung;
|
|
1725
|
+
getFocusedSection(): string | null;
|
|
1726
|
+
focusSection(sectionId: string): void;
|
|
1727
|
+
overview(): void;
|
|
1728
|
+
setRung(rung: LodRung): void;
|
|
1729
|
+
setCategoryFilter(categoryKeys: string[] | null, focus?: boolean): void;
|
|
1730
|
+
setAccessibilityFilter(types: string[] | null): void;
|
|
1731
|
+
setCommercialLimitedFilter(on: boolean): void;
|
|
1732
|
+
/** Current selection with prices resolved from the chart categories. */
|
|
1733
|
+
getSelection(): SelectedSeat[];
|
|
1734
|
+
/** Select free objects by engine id or public label. Returns newly selected objects. */
|
|
1735
|
+
selectObjects(objects: string[]): SelectedSeat[];
|
|
1736
|
+
/** Deselect objects by engine id or public label. */
|
|
1737
|
+
deselectObjects(objects: string[]): void;
|
|
1738
|
+
/** Clear every unheld selection. */
|
|
1739
|
+
clearSelection(): void;
|
|
1740
|
+
/** Select every selectable object in the named categories. */
|
|
1741
|
+
selectCategories(categoryKeys: string[]): SelectedSeat[];
|
|
1742
|
+
/** Deselect every selected object in the named categories. */
|
|
1743
|
+
deselectCategories(categoryKeys: string[]): void;
|
|
1744
|
+
/** Replace the buyer-selectable object allow-list without remounting. */
|
|
1745
|
+
setSelectableObjects(objects: string[] | null): void;
|
|
1746
|
+
/** Change the selection cap without remounting. */
|
|
1747
|
+
setMaxSelection(maxSelection: number): void;
|
|
1748
|
+
/** Current selection-rule validity, or null when no rules were configured. */
|
|
1749
|
+
getSelectionValidity(): PickerSelectionValidity | null;
|
|
1750
|
+
/** Hold the current selection. Resolves the hold, or null on a 409 conflict. */
|
|
1751
|
+
hold(options?: {
|
|
1752
|
+
ttlMs?: number;
|
|
1753
|
+
}): Promise<HoldResult | null>;
|
|
1754
|
+
/**
|
|
1755
|
+
* @internal Like {@link hold} but RE-THROWS the structured API error (409
|
|
1756
|
+
* `reason`/`code` + `conflicts`) instead of swallowing it into `onError` +
|
|
1757
|
+
* `null`. The native WebView host adapter needs the throw so it can answer the
|
|
1758
|
+
* originating command with a correlated error carrying the SPECIFIC reason
|
|
1759
|
+
* (`sold_out` vs `not_enough_together`); the public method above keeps the
|
|
1760
|
+
* catch-and-onError contract that direct web consumers rely on. Not a stable
|
|
1761
|
+
* part of the embed API.
|
|
1762
|
+
*/
|
|
1763
|
+
holdOrThrow(options?: {
|
|
1764
|
+
ttlMs?: number;
|
|
1765
|
+
}): Promise<HoldResult | null>;
|
|
1766
|
+
/** Restore an active hold by its opaque id without extending its expiry. */
|
|
1767
|
+
resumeHold(holdId: string): Promise<HoldResult | null>;
|
|
1768
|
+
/** @internal Throwing variant of {@link resumeHold} for the native host adapter. See {@link holdOrThrow}. */
|
|
1769
|
+
resumeHoldOrThrow(holdId: string): Promise<HoldResult | null>;
|
|
1770
|
+
/**
|
|
1771
|
+
* Push the OPEN hold's expiry out ("need more time?"). Resolves the refreshed
|
|
1772
|
+
* hold, or `null` when there is nothing held or the server refused (the hold
|
|
1773
|
+
* is gone, already expired, or at its renewal cap) — refusal is a normal
|
|
1774
|
+
* outcome, not an error, so the host decides the copy. The client-side expiry
|
|
1775
|
+
* timer is re-armed to match, so `onHoldExpired` won't fire early.
|
|
1776
|
+
*/
|
|
1777
|
+
extendHold(ttlMs?: number): Promise<HoldResult | null>;
|
|
1778
|
+
/** Current active hold known to this chart, if any. */
|
|
1779
|
+
getCurrentHold(): HoldResult | null;
|
|
1780
|
+
getGAAreas(): GAAreaAvailability[];
|
|
1781
|
+
holdGA(areaId: string, qty: number, options?: {
|
|
1782
|
+
tierId?: string | null;
|
|
1783
|
+
ttlMs?: number;
|
|
1784
|
+
}): Promise<HoldResult | null>;
|
|
1785
|
+
/** @internal Throwing variant of {@link holdGA} for the native host adapter. See {@link holdOrThrow}. */
|
|
1786
|
+
holdGAOrThrow(areaId: string, qty: number, options?: {
|
|
1787
|
+
tierId?: string | null;
|
|
1788
|
+
ttlMs?: number;
|
|
1789
|
+
}): Promise<HoldResult | null>;
|
|
1934
1790
|
/**
|
|
1935
|
-
*
|
|
1936
|
-
*
|
|
1937
|
-
*
|
|
1938
|
-
* step. Small charts are built in one step either way.
|
|
1791
|
+
* Ask the server for the `qty` best free seats and hold them atomically.
|
|
1792
|
+
* `options.ttlMs` sets the checkout window exactly like {@link hold}; omit it
|
|
1793
|
+
* and the server falls back to the event setting, then its own default.
|
|
1939
1794
|
*/
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
* dynamically imported on first use). Set false for embed hosts that must
|
|
1952
|
-
* stay strictly 2D. */
|
|
1953
|
-
enable3D?: boolean;
|
|
1795
|
+
bestAvailable(qty: number, categoryKey?: string, options?: {
|
|
1796
|
+
zoneId?: string;
|
|
1797
|
+
preferPremium?: boolean;
|
|
1798
|
+
ttlMs?: number;
|
|
1799
|
+
}): Promise<BestAvailableResult | null>;
|
|
1800
|
+
/** @internal Throwing variant of {@link bestAvailable} for the native host adapter. See {@link holdOrThrow}. */
|
|
1801
|
+
bestAvailableOrThrow(qty: number, categoryKey?: string, options?: {
|
|
1802
|
+
zoneId?: string;
|
|
1803
|
+
preferPremium?: boolean;
|
|
1804
|
+
ttlMs?: number;
|
|
1805
|
+
}): Promise<BestAvailableResult | null>;
|
|
1954
1806
|
/**
|
|
1955
|
-
*
|
|
1956
|
-
*
|
|
1957
|
-
*
|
|
1958
|
-
*
|
|
1959
|
-
*
|
|
1960
|
-
|
|
1961
|
-
|
|
1807
|
+
* Choose a ticket tier for a selected seat (e.g. Adult → Child). The seat's
|
|
1808
|
+
* available `tiers` are on each `SelectedSeat` from `getSelection()` /
|
|
1809
|
+
* `onSelectionChange`. Re-emits the selection with the new tier + price, and
|
|
1810
|
+
* the tier rides along in the next `hold()` / `onHold` per seat. `tierId=null`
|
|
1811
|
+
* reverts to the default tier.
|
|
1812
|
+
*/
|
|
1813
|
+
setSeatTier(seatId: string, tierId: string | null): void;
|
|
1814
|
+
/** Confirm/update an unheld variable table's guest quantity locally. */
|
|
1815
|
+
setTableQuantity(label: string, quantity: number): boolean;
|
|
1962
1816
|
/**
|
|
1963
|
-
*
|
|
1964
|
-
*
|
|
1817
|
+
* Atomically replace an active variable-table hold with a new guest count.
|
|
1818
|
+
* Returns null for an inapplicable/invalid quantity or a refused replacement.
|
|
1965
1819
|
*/
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
}) => void;
|
|
1820
|
+
replaceTableQuantity(label: string, quantity: number, ttlMs?: number): Promise<HoldResult | null>;
|
|
1821
|
+
/** @internal Throwing variant used by the correlated native bridge. */
|
|
1822
|
+
replaceTableQuantityOrThrow(label: string, quantity: number, ttlMs?: number): Promise<HoldResult | null>;
|
|
1970
1823
|
/**
|
|
1971
|
-
*
|
|
1972
|
-
*
|
|
1973
|
-
*
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1824
|
+
* Floors of a multi-floor chart — `[{ id, name }]` (single-floor charts
|
|
1825
|
+
* return one entry; empty before render()). Pair with setFloor() to build a
|
|
1826
|
+
* host-side floor switcher.
|
|
1827
|
+
*/
|
|
1828
|
+
getFloors(): {
|
|
1829
|
+
id: string;
|
|
1830
|
+
name: string;
|
|
1831
|
+
}[];
|
|
1832
|
+
/** Switch the shown floor (2D). Warns + no-ops on single-floor charts. */
|
|
1833
|
+
setFloor(floorId: string): void;
|
|
1834
|
+
/** Toggle colorblind-safe rendering at runtime (see options.colorblindSafe). */
|
|
1835
|
+
setColorblindSafe(on: boolean): void;
|
|
1836
|
+
/** Switch the 2D canvas projection.
|
|
1837
|
+
* @deprecated `'isometric'` and `'perspective'` are retired in favour of the
|
|
1838
|
+
* real 3D venue view (`setBuyerView('venue3d')`); accepted for source
|
|
1839
|
+
* compatibility until the next major. */
|
|
1840
|
+
setViewMode(mode: RendererViewMode): void;
|
|
1841
|
+
/** Current canvas projection. */
|
|
1842
|
+
getViewMode(): RendererViewMode;
|
|
1843
|
+
/** Zoom in one step (same increment as the wheel/pinch gesture). */
|
|
1844
|
+
zoomIn(): void;
|
|
1845
|
+
/** Zoom out one step. */
|
|
1846
|
+
zoomOut(): void;
|
|
1847
|
+
/** Reset the camera so the whole chart fits the container. */
|
|
1848
|
+
zoomToFit(): void;
|
|
1980
1849
|
/**
|
|
1981
|
-
*
|
|
1850
|
+
* Light / dark / follow-the-reader, applied to a LIVE map.
|
|
1982
1851
|
*
|
|
1983
|
-
*
|
|
1984
|
-
*
|
|
1985
|
-
*
|
|
1986
|
-
*
|
|
1987
|
-
*
|
|
1852
|
+
* This is a repaint, not a remount. It re-inks the canvas through the
|
|
1853
|
+
* controller's in-place rebuild, which keeps the buyer's selection, the
|
|
1854
|
+
* section they had opened and the exact camera pose — a native shell
|
|
1855
|
+
* flipping the OS appearance must not cost the buyer their seats or their
|
|
1856
|
+
* place in the venue. `null` hands the ground back to the chart's own
|
|
1857
|
+
* colours; an explicit `mapTheme` still outranks any mode.
|
|
1988
1858
|
*/
|
|
1989
|
-
|
|
1859
|
+
/** A repaint, not a remount: the buyer keeps their selection, their focused
|
|
1860
|
+
* section and their camera. See ./seatingChartHostSurface. */
|
|
1861
|
+
setThemeMode(mode: ThemeMode | null, options?: {
|
|
1862
|
+
mapTheme?: PickerMapTheme | null;
|
|
1863
|
+
}): void;
|
|
1864
|
+
/** The mode the host asked for — `'auto'`, not what `auto` resolved to. */
|
|
1865
|
+
getThemeMode(): ThemeMode | null;
|
|
1866
|
+
/** Report the chrome the HOST draws over the map, in CSS px, so framing
|
|
1867
|
+
* aims at what the buyer can see. See ./seatingChartHostSurface. */
|
|
1868
|
+
setViewportInsets(insets: {
|
|
1869
|
+
top?: number;
|
|
1870
|
+
right?: number;
|
|
1871
|
+
bottom?: number;
|
|
1872
|
+
left?: number;
|
|
1873
|
+
} | null): void;
|
|
1874
|
+
/** The insets in force; all zero when the host reported none. */
|
|
1875
|
+
getViewportInsets(): {
|
|
1876
|
+
top: number;
|
|
1877
|
+
right: number;
|
|
1878
|
+
bottom: number;
|
|
1879
|
+
left: number;
|
|
1880
|
+
};
|
|
1881
|
+
/** Enter or leave the same real lazy-loaded venue scene as SeatPicker. */
|
|
1882
|
+
setBuyerView(view: SeatingChartBuyerView, options?: {
|
|
1883
|
+
flyToSeatId?: string;
|
|
1884
|
+
resetView?: boolean;
|
|
1885
|
+
}): Promise<void>;
|
|
1886
|
+
getBuyerView(): SeatingChartBuyerView;
|
|
1887
|
+
/** Open an authored or chart-derived 360° view for one physical seat. */
|
|
1888
|
+
openSeatView(seatId: string): Promise<void>;
|
|
1889
|
+
/** Explicit Rotate / Move control for native and custom picker chrome. */
|
|
1890
|
+
setVenue3DNavigationMode(mode: SeatingChartNavigationMode): void;
|
|
1990
1891
|
/**
|
|
1991
|
-
*
|
|
1992
|
-
*
|
|
1993
|
-
*
|
|
1994
|
-
*
|
|
1892
|
+
* Enable or suppress all buyer input inside this chart without unmounting it.
|
|
1893
|
+
*
|
|
1894
|
+
* Native SDKs use this while a native confirmation, quantity prompt, loading
|
|
1895
|
+
* surface or error surface owns the chart area. Disabling input in the DOM is
|
|
1896
|
+
* intentional: an iOS WKWebView can receive the same physical tap beneath a
|
|
1897
|
+
* Flutter overlay even when the Flutter widget is wrapped in IgnorePointer.
|
|
1898
|
+
* Programmatic bridge commands continue to work, so a prompt can still open
|
|
1899
|
+
* view-from-seat or 3D and then re-enable interaction after the handoff.
|
|
1995
1900
|
*/
|
|
1996
|
-
|
|
1901
|
+
setInteractionEnabled(enabled: boolean): void;
|
|
1902
|
+
private applyInteractionState;
|
|
1903
|
+
/** Release the current hold (if any). No-op when nothing is held. */
|
|
1904
|
+
release(): Promise<void>;
|
|
1905
|
+
/** Release selected labels from the current hold while keeping the remainder. */
|
|
1906
|
+
releaseLabels(labels: string[]): Promise<boolean>;
|
|
1907
|
+
/** Tear everything down: close the socket, stop timers, drop the canvas. */
|
|
1997
1908
|
/**
|
|
1998
|
-
*
|
|
1999
|
-
*
|
|
2000
|
-
*
|
|
1909
|
+
* Realtime for an access-scoped chart.
|
|
1910
|
+
*
|
|
1911
|
+
* A tokenless chart never gets here: `access` is null, `PubApi.socketUrl()`
|
|
1912
|
+
* returns the URL it always has, and PickerController keeps its own socket
|
|
1913
|
+
* and its own legacy frames. Nothing about the public path changes.
|
|
2001
1914
|
*/
|
|
2002
|
-
|
|
1915
|
+
private startRealtime;
|
|
1916
|
+
/** Re-read live inventory without remounting or dropping buyer state. */
|
|
1917
|
+
refreshAvailability(): Promise<void>;
|
|
2003
1918
|
/**
|
|
2004
|
-
*
|
|
2005
|
-
*
|
|
2006
|
-
*
|
|
2007
|
-
* is restored automatically while the picker is full screen so it never
|
|
2008
|
-
* loses context on a small device or an expanded map. Default false.
|
|
2009
|
-
*
|
|
2010
|
-
* A mounted host can update this through `setEventDetailsHidden()` when its
|
|
2011
|
-
* own event chrome arrives asynchronously.
|
|
1919
|
+
* Re-acquire the buyer access session — call after your app has re-authorized
|
|
1920
|
+
* the buyer (a revoked session cannot be recovered any other way). Resolves
|
|
1921
|
+
* true when a fresh bearer is held; the realtime feed restarts with it.
|
|
2012
1922
|
*/
|
|
2013
|
-
|
|
1923
|
+
refreshAccess(): Promise<boolean>;
|
|
2014
1924
|
/**
|
|
2015
|
-
*
|
|
2016
|
-
*
|
|
2017
|
-
*
|
|
2018
|
-
*
|
|
2019
|
-
* layouts ignore this (the bottom sheet is already the collapse). A mounted
|
|
2020
|
-
* host can drive it later through `setPanelCollapsed()`. Default false.
|
|
1925
|
+
* The visible failure state. Deliberately inline-styled and dependency-free:
|
|
1926
|
+
* this renders on a stranger's website, where our stylesheet may not have
|
|
1927
|
+
* loaded (the chart fetch just failed) and where inheriting the host's own
|
|
1928
|
+
* styles is likelier to produce something unreadable than something on-brand.
|
|
2021
1929
|
*/
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
1930
|
+
private showLoadFailure;
|
|
1931
|
+
destroy(): void;
|
|
1932
|
+
}
|
|
1933
|
+
|
|
1934
|
+
/**
|
|
1935
|
+
* seatingChartBinding — the single source of truth the framework wrappers bind
|
|
1936
|
+
* against.
|
|
1937
|
+
*
|
|
1938
|
+
* `@seatlayer/react`, `@seatlayer/vue` and `@seatlayer/angular` are supposed to
|
|
1939
|
+
* be thin: mount a `SeatingChart`, forward the props, forward the callbacks,
|
|
1940
|
+
* expose the imperative handle. In practice each of them hand-wrote all three
|
|
1941
|
+
* lists, and they drifted — React grew `initialView` and `errorDisplay` props
|
|
1942
|
+
* that Vue and Angular never got, and nothing in any build caught it, because a
|
|
1943
|
+
* missing prop in a hand-written list is not a type error anywhere.
|
|
1944
|
+
*
|
|
1945
|
+
* So the lists live here, next to the class they describe, and the wrappers
|
|
1946
|
+
* iterate them. Adding a method to `SeatingChart` that buyers should be able to
|
|
1947
|
+
* call now means adding one entry to {@link SEATING_CHART_HANDLE_METHODS}; every
|
|
1948
|
+
* wrapper picks it up, and the wrapper tests fail until each one exposes it.
|
|
1949
|
+
*
|
|
1950
|
+
* Types only against `SeatingChart` — this module imports no runtime value from
|
|
1951
|
+
* it, so it costs a host nothing but the two arrays and the binder below.
|
|
1952
|
+
*/
|
|
1953
|
+
|
|
1954
|
+
/**
|
|
1955
|
+
* Imperative handle exposed by every wrapper — call these to drive the picker
|
|
1956
|
+
* from your app.
|
|
1957
|
+
*
|
|
1958
|
+
* Angular is the one exception to the naming: its component surfaces `hold` as
|
|
1959
|
+
* `holdSelection`, because `hold` is already taken by its `@Output()` event.
|
|
1960
|
+
*/
|
|
1961
|
+
interface SeatingChartHandle {
|
|
1962
|
+
/** Hold the current selection. Resolves the hold, or `null` on a 409 conflict. */
|
|
1963
|
+
hold(options?: {
|
|
1964
|
+
ttlMs?: number;
|
|
1965
|
+
}): Promise<HoldResult | null>;
|
|
1966
|
+
/** Restore an active hold by its opaque id. */
|
|
1967
|
+
resumeHold(holdId: string): Promise<HoldResult | null>;
|
|
1968
|
+
/** Current active hold known to the chart. */
|
|
1969
|
+
getCurrentHold(): HoldResult | null;
|
|
1970
|
+
/** GA areas with live remaining capacity. */
|
|
1971
|
+
getGAAreas(): GAAreaAvailability[];
|
|
1972
|
+
/** Atomically hold a quantity from one GA area. */
|
|
1973
|
+
holdGA(areaId: string, qty: number, options?: {
|
|
1974
|
+
tierId?: string | null;
|
|
1975
|
+
ttlMs?: number;
|
|
1976
|
+
}): Promise<HoldResult | null>;
|
|
1977
|
+
/** Ask the server for the `qty` best free seats and hold them atomically. */
|
|
1978
|
+
bestAvailable(qty: number, categoryKey?: string): Promise<BestAvailableResult | null>;
|
|
1979
|
+
/** Release the current hold (if any). */
|
|
1980
|
+
release(): Promise<void>;
|
|
1981
|
+
/** Release some held labels while keeping the remainder active. */
|
|
1982
|
+
releaseLabels(labels: string[]): Promise<boolean>;
|
|
1983
|
+
/** The current selection, with prices resolved from the chart categories. */
|
|
1984
|
+
getSelection(): SelectedSeat[];
|
|
1985
|
+
/** Select free objects by engine id or public label. */
|
|
1986
|
+
selectObjects(objects: string[]): SelectedSeat[];
|
|
1987
|
+
/** Deselect objects by engine id or public label. */
|
|
1988
|
+
deselectObjects(objects: string[]): void;
|
|
1989
|
+
/** Clear every unheld selection. */
|
|
1990
|
+
clearSelection(): void;
|
|
1991
|
+
/** Select every selectable object in the named categories. */
|
|
1992
|
+
selectCategories(categoryKeys: string[]): SelectedSeat[];
|
|
1993
|
+
/** Deselect every selected object in the named categories. */
|
|
1994
|
+
deselectCategories(categoryKeys: string[]): void;
|
|
1995
|
+
/** Replace the buyer-selectable object allow-list without rebuilding. */
|
|
1996
|
+
setSelectableObjects(objects: string[] | null): void;
|
|
1997
|
+
/** Change the selection cap without rebuilding. */
|
|
1998
|
+
setMaxSelection(maxSelection: number): void;
|
|
1999
|
+
/** Current exact-count validity, or null when no exact count was configured. */
|
|
2000
|
+
getSelectionValidity(): PickerSelectionValidity | null;
|
|
2025
2001
|
/**
|
|
2026
|
-
*
|
|
2027
|
-
*
|
|
2028
|
-
* price they will actually pay — on the map tooltip, confirm popover, price
|
|
2029
|
-
* panel, tray, totals, and in the checkout handoff's line items. Keyed by
|
|
2030
|
-
* category key; per-tier overrides nest under `tiers`. Unlisted categories
|
|
2031
|
-
* fall back to the chart price.
|
|
2002
|
+
* Choose a ticket tier for a selected seat (e.g. Adult → Child). Available
|
|
2003
|
+
* `tiers` are on each `SelectedSeat`; `tierId=null` reverts to the default.
|
|
2032
2004
|
*/
|
|
2033
|
-
|
|
2005
|
+
setSeatTier(seatId: string, tierId: string | null): void;
|
|
2034
2006
|
/**
|
|
2035
|
-
*
|
|
2036
|
-
*
|
|
2037
|
-
* same live fact. The picker remains fully functional when it is omitted.
|
|
2007
|
+
* Floors of a multi-floor chart — `[{ id, name }]` (single-floor charts
|
|
2008
|
+
* return one entry; empty before render()). Pair with setFloor().
|
|
2038
2009
|
*/
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2010
|
+
getFloors(): {
|
|
2011
|
+
id: string;
|
|
2012
|
+
name: string;
|
|
2013
|
+
}[];
|
|
2014
|
+
/** Switch the shown floor (2D). Warns + no-ops on single-floor charts. */
|
|
2015
|
+
setFloor(floorId: string): void;
|
|
2016
|
+
/** Toggle colorblind-safe rendering at runtime (see the `colorblindSafe` prop). */
|
|
2017
|
+
setColorblindSafe(on: boolean): void;
|
|
2018
|
+
/** Zoom in one step (same increment as the wheel/pinch gesture). */
|
|
2019
|
+
zoomIn(): void;
|
|
2020
|
+
/** Zoom out one step. */
|
|
2021
|
+
zoomOut(): void;
|
|
2022
|
+
/** Reset the camera so the whole chart fits the container. */
|
|
2023
|
+
zoomToFit(): void;
|
|
2042
2024
|
/**
|
|
2043
|
-
*
|
|
2044
|
-
*
|
|
2045
|
-
* as owned by this buyer.
|
|
2025
|
+
* Re-acquire the buyer access session after your app re-authorizes the buyer
|
|
2026
|
+
* (Sales Channels). Resolves false when the chart is not access-scoped.
|
|
2046
2027
|
*/
|
|
2047
|
-
|
|
2028
|
+
refreshAccess(): Promise<boolean>;
|
|
2029
|
+
}
|
|
2030
|
+
/**
|
|
2031
|
+
* Every method a wrapper must forward. The wrappers build their handle by
|
|
2032
|
+
* iterating this, so the list IS the contract rather than a description of it.
|
|
2033
|
+
*/
|
|
2034
|
+
declare const SEATING_CHART_HANDLE_METHODS: readonly ["hold", "resumeHold", "getCurrentHold", "getGAAreas", "holdGA", "bestAvailable", "release", "releaseLabels", "getSelection", "selectObjects", "deselectObjects", "clearSelection", "selectCategories", "deselectCategories", "setSelectableObjects", "setMaxSelection", "getSelectionValidity", "setSeatTier", "getFloors", "setFloor", "setColorblindSafe", "zoomIn", "zoomOut", "zoomToFit", "refreshAccess"];
|
|
2035
|
+
type SeatingChartHandleMethod = (typeof SEATING_CHART_HANDLE_METHODS)[number];
|
|
2036
|
+
/**
|
|
2037
|
+
* Build the forwarding object every wrapper exposes.
|
|
2038
|
+
*
|
|
2039
|
+
* `getInstance` is a function rather than the instance itself: a wrapper's
|
|
2040
|
+
* handle is created ONCE and must keep working across rebuilds, so it has to
|
|
2041
|
+
* read the current chart on each call instead of capturing one.
|
|
2042
|
+
*/
|
|
2043
|
+
declare function bindSeatingChartHandle(getInstance: () => SeatingChart | null): SeatingChartHandle;
|
|
2044
|
+
/**
|
|
2045
|
+
* Props whose change means a DIFFERENT chart, so the wrapper tears the canvas
|
|
2046
|
+
* down and builds a new one. Everything else is read live: a parent re-render
|
|
2047
|
+
* must never destroy a canvas mid-selection.
|
|
2048
|
+
*
|
|
2049
|
+
* `initialView` and `errorDisplay` are here because they are read once at
|
|
2050
|
+
* construction and never re-applied — leaving them out does not make them
|
|
2051
|
+
* "live", it makes them silently ignored after mount, which is the worse of the
|
|
2052
|
+
* two behaviours. React already treated them this way; Vue and Angular did not
|
|
2053
|
+
* expose them at all.
|
|
2054
|
+
*/
|
|
2055
|
+
declare const SEATING_CHART_IDENTITY_PROPS: readonly ["event", "apiBase", "maxSelection", "numberOfPlacesToSelect", "selectionValidators", "publicKey", "locale", "currency", "colorblindSafe", "initialView", "errorDisplay"];
|
|
2056
|
+
type SeatingChartIdentityProp = (typeof SEATING_CHART_IDENTITY_PROPS)[number];
|
|
2057
|
+
/** Non-callback options a wrapper accepts as props/inputs and passes straight through. */
|
|
2058
|
+
declare const SEATING_CHART_VALUE_PROPS: readonly ["event", "apiBase", "maxSelection", "numberOfPlacesToSelect", "selectionValidators", "publicKey", "locale", "currency", "colorblindSafe", "initialView", "errorDisplay", "selectedObjects", "selectableObjects", "messages", "seatTooltip", "buyerAccessTokenProvider", "buyerAccessToken"];
|
|
2059
|
+
type SeatingChartValueProp = (typeof SEATING_CHART_VALUE_PROPS)[number];
|
|
2060
|
+
/** Every callback option a wrapper wires to its own event mechanism. */
|
|
2061
|
+
declare const SEATING_CHART_CALLBACK_PROPS: readonly ["onSelectionChange", "onSelectionValidityChange", "onSelectionValid", "onSelectionInvalid", "onSelectionLimit", "onHold", "onHoldRestored", "onHoldExpired", "onGAClick", "onGAPrompt", "onError", "onDeckTap", "onHint", "onSeatHover", "onAccessExpired", "onAccessUnavailable", "onSelectedObjectUnavailable"];
|
|
2062
|
+
type SeatingChartCallbackProp = (typeof SEATING_CHART_CALLBACK_PROPS)[number];
|
|
2063
|
+
/** The value half of the options, as a wrapper holds it. */
|
|
2064
|
+
type SeatingChartValues = Pick<SeatingChartOptions, SeatingChartValueProp>;
|
|
2065
|
+
/** The callback half, already bound to the wrapper's event mechanism. */
|
|
2066
|
+
type SeatingChartCallbacks = Pick<SeatingChartOptions, SeatingChartCallbackProp>;
|
|
2067
|
+
/**
|
|
2068
|
+
* Assemble the options literal for `new SeatingChart(...)`.
|
|
2069
|
+
*
|
|
2070
|
+
* Picks by the lists above rather than spreading, so a wrapper cannot pass a
|
|
2071
|
+
* stray prop of its own (React's `className`/`style`, Vue's attrs) into the
|
|
2072
|
+
* SDK, and cannot forget one either.
|
|
2073
|
+
*/
|
|
2074
|
+
declare function buildSeatingChartOptions(container: HTMLElement, values: Partial<SeatingChartValues>, callbacks: SeatingChartCallbacks): SeatingChartOptions;
|
|
2075
|
+
|
|
2076
|
+
/**
|
|
2077
|
+
* A secure, framework-neutral host for the SeatLayer chart Designer.
|
|
2078
|
+
*
|
|
2079
|
+
* The Designer remains an iframe so a platform never gives its SeatLayer secret
|
|
2080
|
+
* key to a browser. This class owns the iframe lifecycle and accepts messages
|
|
2081
|
+
* only from that iframe's exact origin.
|
|
2082
|
+
*/
|
|
2083
|
+
type EmbeddedDesignerEventType = 'seatlayer.designer.ready' | 'seatlayer.designer.saved' | 'seatlayer.designer.published' | 'seatlayer.designer.close' | 'seatlayer.designer.error';
|
|
2084
|
+
interface EmbeddedDesignerMessage {
|
|
2085
|
+
type: EmbeddedDesignerEventType;
|
|
2086
|
+
chartId?: string;
|
|
2087
|
+
workspaceId?: string;
|
|
2088
|
+
expiresAt?: number;
|
|
2089
|
+
code?: string;
|
|
2090
|
+
message?: string;
|
|
2091
|
+
meta?: unknown;
|
|
2048
2092
|
/**
|
|
2049
|
-
*
|
|
2050
|
-
*
|
|
2051
|
-
*
|
|
2093
|
+
* Set by the Designer on an error it raised while the editor was already
|
|
2094
|
+
* running (a failed autosave, thumbnail upload, reload…). Such an error is
|
|
2095
|
+
* about ONE operation, not about the session, so the SDK reports it to the
|
|
2096
|
+
* host and leaves the live editor mounted instead of replacing it with the
|
|
2097
|
+
* dead-end card. Absent on older Designer builds — see
|
|
2098
|
+
* {@link EmbeddedDesigner} for the phase-based fallback.
|
|
2052
2099
|
*/
|
|
2053
|
-
|
|
2100
|
+
fatal?: boolean;
|
|
2101
|
+
/** The operation that failed, when `fatal` is `false` (e.g. `'save'`). */
|
|
2102
|
+
action?: string;
|
|
2103
|
+
}
|
|
2104
|
+
interface EmbeddedDesignerOptions {
|
|
2105
|
+
/** The short-lived URL returned by your backend's Designer-session call. */
|
|
2106
|
+
designerUrl: string;
|
|
2107
|
+
/** CSS selector or element where the iframe is mounted. */
|
|
2108
|
+
container: string | HTMLElement;
|
|
2054
2109
|
/**
|
|
2055
|
-
*
|
|
2056
|
-
*
|
|
2057
|
-
*
|
|
2058
|
-
* Default false.
|
|
2110
|
+
* Verify the message belongs to the chart your backend opened. When set, the
|
|
2111
|
+
* id is required on `ready` and every runtime lifecycle message. Only an error
|
|
2112
|
+
* raised before the iframe resolves its session may omit it.
|
|
2059
2113
|
*/
|
|
2060
|
-
|
|
2114
|
+
expectedChartId?: string;
|
|
2061
2115
|
/**
|
|
2062
|
-
*
|
|
2063
|
-
*
|
|
2064
|
-
*
|
|
2065
|
-
* own equivalent confirmation UI.
|
|
2116
|
+
* Verify the message belongs to the workspace your backend opened. Uses the
|
|
2117
|
+
* same ready/runtime requirement and pre-session error exception as
|
|
2118
|
+
* `expectedChartId`.
|
|
2066
2119
|
*/
|
|
2067
|
-
|
|
2120
|
+
expectedWorkspaceId?: string;
|
|
2121
|
+
title?: string;
|
|
2122
|
+
className?: string;
|
|
2123
|
+
style?: Partial<CSSStyleDeclaration>;
|
|
2124
|
+
allow?: string;
|
|
2125
|
+
referrerPolicy?: ReferrerPolicy;
|
|
2068
2126
|
/**
|
|
2069
|
-
*
|
|
2070
|
-
*
|
|
2071
|
-
*
|
|
2127
|
+
* Show the built-in branded loading skeleton and error/expiry card inside the
|
|
2128
|
+
* container while the Designer boots. Defaults to `true`. Set `false` when the
|
|
2129
|
+
* host renders its own loading and error chrome.
|
|
2072
2130
|
*/
|
|
2073
|
-
|
|
2131
|
+
showLoadingState?: boolean;
|
|
2074
2132
|
/**
|
|
2075
|
-
*
|
|
2076
|
-
*
|
|
2077
|
-
*
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
*
|
|
2082
|
-
*
|
|
2083
|
-
*
|
|
2084
|
-
* the event to have a gateway assigned; when it does not, this
|
|
2085
|
-
* falls back to `'handoff'` for that buyer rather than dead-ending
|
|
2086
|
-
* them, and reports why through {@link onCheckoutUnavailable}.
|
|
2087
|
-
*
|
|
2088
|
-
* Named for the destination rather than as a boolean flag because there is a
|
|
2089
|
-
* real third answer coming and `hostedCheckout: true` would have no room for
|
|
2090
|
-
* it; spelling the default out also makes a host's intent legible in their own
|
|
2091
|
-
* source instead of hiding it in an absent option.
|
|
2133
|
+
* If the Designer never posts `ready` within this many milliseconds, the host
|
|
2134
|
+
* transitions to the error card with a timeout message. Defaults to `20000`.
|
|
2135
|
+
* Only used when `showLoadingState` is enabled.
|
|
2136
|
+
*/
|
|
2137
|
+
loadingTimeoutMs?: number;
|
|
2138
|
+
/**
|
|
2139
|
+
* How to size the iframe's height. The Designer is a full application (its
|
|
2140
|
+
* shell is `position:fixed; height:100dvh`), not flowing content, so it should
|
|
2141
|
+
* fill its box rather than be measured.
|
|
2092
2142
|
*
|
|
2093
|
-
*
|
|
2143
|
+
* - `'fill'` (default): container-aware. On mount the SDK probes whether the
|
|
2144
|
+
* host gave the container a DEFINITE (bounded) height:
|
|
2145
|
+
* - **Bounded container** (a fixed-height block, `height`/`max-height`,
|
|
2146
|
+
* `flex:1; min-h:0`, a resolved `%`, etc.) → the iframe fills 100% of
|
|
2147
|
+
* that block and tracks its size live via a `ResizeObserver`.
|
|
2148
|
+
* - **Content-sized container** (the block collapses to whatever the iframe
|
|
2149
|
+
* measures — typical full-page usage) → the iframe grows so its bottom
|
|
2150
|
+
* edge reaches the bottom of the viewport (`window.innerHeight -
|
|
2151
|
+
* iframe.top`), recomputed (rAF-throttled) on `resize` /
|
|
2152
|
+
* `orientationchange` / `scroll`.
|
|
2153
|
+
* Either way the result is clamped to `minHeight`. The verdict is cached but
|
|
2154
|
+
* re-probed on `resize`/`orientationchange` so a responsive host layout can
|
|
2155
|
+
* flip between the two. The legacy `seatlayer.designer.resize` message is
|
|
2156
|
+
* ignored in `'fill'` mode: it is circular, because the fixed-position shell
|
|
2157
|
+
* just echoes the iframe height.
|
|
2158
|
+
* - a number: a fixed pixel height. In this mode the legacy resize message is
|
|
2159
|
+
* still honoured (unless `autoResize` is `false`) so older hosts keep growing.
|
|
2094
2160
|
*
|
|
2095
|
-
*
|
|
2096
|
-
*
|
|
2097
|
-
* console warning) rather than reaching past it to api.seatlayer.io.
|
|
2098
|
-
* 2. WHERE A HOSTED GATEWAY RETURNS THE BUYER is settled by {@link returnUrl}
|
|
2099
|
-
* and by the organizer. Without one — or from an origin the organizer has
|
|
2100
|
-
* not declared — the buyer comes back to SeatLayer's own buyer page and is
|
|
2101
|
-
* confirmed THERE, not in this widget. Declare the embedding site under
|
|
2102
|
-
* Embed domains in the dashboard and pass `returnUrl`, and the buyer
|
|
2103
|
-
* returns to your page instead. In-page gateways never navigate away at
|
|
2104
|
-
* all, so they are unaffected either way.
|
|
2161
|
+
* All SDK-managed heights are written with `!important` priority so a host
|
|
2162
|
+
* theme's `iframe { height: … !important }` cannot override them.
|
|
2105
2163
|
*/
|
|
2106
|
-
|
|
2164
|
+
height?: 'fill' | number;
|
|
2165
|
+
/** Minimum height (px) that `'fill'` mode clamps to. Defaults to `480`. */
|
|
2166
|
+
minHeight?: number;
|
|
2107
2167
|
/**
|
|
2108
|
-
*
|
|
2109
|
-
* `
|
|
2110
|
-
*
|
|
2111
|
-
*
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
*
|
|
2168
|
+
* Auto-grow the iframe to the height the Designer reports over the resize
|
|
2169
|
+
* protocol (`seatlayer.designer.resize`). Only applies when `height` is a fixed
|
|
2170
|
+
* number; ignored in `'fill'` mode. Defaults to `true`. Set `false` when the
|
|
2171
|
+
* host sizes a fixed-height iframe itself.
|
|
2172
|
+
*/
|
|
2173
|
+
autoResize?: boolean;
|
|
2174
|
+
/**
|
|
2175
|
+
* Called when the user presses "Try again" on the error card. Use it to mint a
|
|
2176
|
+
* fresh Designer session and call `setDesignerUrl()` with the new URL, which
|
|
2177
|
+
* recreates the iframe and returns to the loading state. When omitted, "Try
|
|
2178
|
+
* again" reloads the current `designerUrl` in place.
|
|
2116
2179
|
*
|
|
2117
|
-
*
|
|
2118
|
-
*
|
|
2119
|
-
* refused — the sale still completes, the buyer just finishes on
|
|
2120
|
-
* SeatLayer's page. Supplying a URL therefore cannot authorize it, which is
|
|
2121
|
-
* what stops a copied snippet from redirecting a paid buyer anywhere it
|
|
2122
|
-
* likes.
|
|
2123
|
-
* As with every script embed, code already running on the host origin can
|
|
2124
|
-
* read that origin's sessionStorage; iframe embedding provides SOP isolation.
|
|
2180
|
+
* When supplied, it also powers automatic session renewal — see
|
|
2181
|
+
* {@link EmbeddedDesignerOptions.autoRenewSession}.
|
|
2125
2182
|
*/
|
|
2126
|
-
|
|
2183
|
+
onRequestRelaunch?: () => void;
|
|
2127
2184
|
/**
|
|
2128
|
-
*
|
|
2129
|
-
*
|
|
2130
|
-
*
|
|
2131
|
-
* against — holdId, expiry, currency and priced line items. Prefer it.
|
|
2185
|
+
* Keep long editing sessions alive without the user ever hitting the expiry
|
|
2186
|
+
* wall. Designer sessions are short-lived security tokens; when the host wires
|
|
2187
|
+
* `onRequestRelaunch` the SDK, with this enabled, will:
|
|
2132
2188
|
*
|
|
2133
|
-
*
|
|
2134
|
-
*
|
|
2135
|
-
*
|
|
2189
|
+
* - **Renew proactively.** From each `ready` message's `expiresAt` it schedules
|
|
2190
|
+
* a silent relaunch shortly before the session lapses (~3 min ahead; for a
|
|
2191
|
+
* TTL under 15 min it renews after 80% of the remaining life, and never
|
|
2192
|
+
* sooner than 30s after `ready`). The host mints a fresh session and swaps
|
|
2193
|
+
* `designerUrl`, so the editor keeps working with no error card.
|
|
2194
|
+
* - **Recover on expiry.** If an expiry error still slips through (a slept
|
|
2195
|
+
* laptop woke past the renewal window, say) it makes ONE automatic relaunch
|
|
2196
|
+
* attempt before showing the "Try again" card, and only falls back to the
|
|
2197
|
+
* card if that relaunch also fails.
|
|
2198
|
+
*
|
|
2199
|
+
* Defaults to `true` whenever `onRequestRelaunch` is provided; a no-op without
|
|
2200
|
+
* it. Set `false` to keep the fully manual "Try again" behavior.
|
|
2136
2201
|
*/
|
|
2137
|
-
|
|
2202
|
+
autoRenewSession?: boolean;
|
|
2203
|
+
onReady?: (message: EmbeddedDesignerMessage) => void;
|
|
2204
|
+
onSaved?: (message: EmbeddedDesignerMessage) => void;
|
|
2205
|
+
onPublished?: (message: EmbeddedDesignerMessage) => void;
|
|
2206
|
+
onClose?: (message: EmbeddedDesignerMessage) => void;
|
|
2207
|
+
onError?: (message: EmbeddedDesignerMessage) => void;
|
|
2208
|
+
}
|
|
2209
|
+
/** Mount, replace, and destroy a scoped Designer iframe safely. */
|
|
2210
|
+
declare class EmbeddedDesigner {
|
|
2211
|
+
private options;
|
|
2212
|
+
private frame;
|
|
2213
|
+
private designerOrigin;
|
|
2214
|
+
private overlay;
|
|
2215
|
+
private timeoutTimer;
|
|
2216
|
+
/** Proactive session-renewal timer; armed from each `ready`, cleared on re-mount. */
|
|
2217
|
+
private renewTimer;
|
|
2218
|
+
/** Last identity-checked session expiry, so a live policy change can re-arm. */
|
|
2219
|
+
private sessionExpiresAt;
|
|
2138
2220
|
/**
|
|
2139
|
-
*
|
|
2140
|
-
*
|
|
2141
|
-
*
|
|
2142
|
-
*
|
|
2143
|
-
* `reason` carries the server's three-way answer verbatim, because two of the
|
|
2144
|
-
* three give opposite advice: `payments_off_for_event` means the organizer
|
|
2145
|
-
* deliberately does not sell this event online (nothing is wrong), while
|
|
2146
|
-
* `unavailable_for_event` means they switched it on and it is broken. Anything
|
|
2147
|
-
* unreadable — a failed lookup, an older worker — reads as `not_configured`,
|
|
2148
|
-
* which asserts the least about them.
|
|
2149
|
-
*
|
|
2150
|
-
* `onCheckout` fires immediately after this with the same hold. Supply either
|
|
2151
|
-
* (or both) and you own the next screen; supply NEITHER and the widget shows
|
|
2152
|
-
* the buyer an honest card of its own rather than swallowing the press.
|
|
2221
|
+
* One automatic recovery relaunch is allowed per expiry. Reset ONLY when a fresh
|
|
2222
|
+
* `ready` arrives — deliberately not on re-mount — so a session that keeps failing
|
|
2223
|
+
* to load can't loop the host through endless silent relaunches.
|
|
2153
2224
|
*/
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
handoff: CheckoutHandoff;
|
|
2157
|
-
}) => void;
|
|
2225
|
+
private autoRecoverUsed;
|
|
2226
|
+
private phase;
|
|
2158
2227
|
/**
|
|
2159
|
-
*
|
|
2160
|
-
*
|
|
2161
|
-
*
|
|
2162
|
-
*
|
|
2163
|
-
* Distinct from {@link onBooked}, which reports the same sale seen from the
|
|
2164
|
-
* seat map over the realtime channel and cannot fire at all for a buyer whose
|
|
2165
|
-
* widget was torn down by a redirect to the gateway.
|
|
2228
|
+
* Set only after an identity-checked `ready`. Unlike `phase`, this remains true
|
|
2229
|
+
* if a later fatal error renders the error card, so no subsequent callback can
|
|
2230
|
+
* shed the chart/workspace identity the live session already established.
|
|
2166
2231
|
*/
|
|
2167
|
-
|
|
2232
|
+
private identityEstablished;
|
|
2233
|
+
private restoreContainerPosition;
|
|
2234
|
+
private pinned;
|
|
2235
|
+
private frameStyleBeforeFs;
|
|
2236
|
+
private docOverflowBeforeFs;
|
|
2237
|
+
private bodyOverflowBeforeFs;
|
|
2238
|
+
private fsKeyHandler;
|
|
2239
|
+
/** Latest height (px string) the Designer reported; re-applied after unpin. */
|
|
2240
|
+
private lastAutoHeight;
|
|
2241
|
+
private fillRaf;
|
|
2242
|
+
private reprobeRaf;
|
|
2243
|
+
private fillListening;
|
|
2244
|
+
/** Resolved container element (fill measurement + ResizeObserver target). */
|
|
2245
|
+
private containerEl;
|
|
2246
|
+
/** Cached fill verdict: 'container' = bounded block, 'viewport' = full page. */
|
|
2247
|
+
private fillMode;
|
|
2248
|
+
/** Live block-size tracking in container-fill mode; disconnected on destroy. */
|
|
2249
|
+
private resizeObs;
|
|
2250
|
+
constructor(options: EmbeddedDesignerOptions);
|
|
2251
|
+
mount(): HTMLIFrameElement;
|
|
2252
|
+
/** Replace the iframe instead of assigning a new fragment to an existing one. */
|
|
2253
|
+
setDesignerUrl(designerUrl: string): HTMLIFrameElement;
|
|
2254
|
+
getIframe(): HTMLIFrameElement | null;
|
|
2255
|
+
/** Update iframe sizing without replacing the live Designer session. */
|
|
2256
|
+
setSizing(height: 'fill' | number | undefined, minHeight: number | undefined): void;
|
|
2257
|
+
/** Update renewal/expiry-recovery policy without replacing the iframe. */
|
|
2258
|
+
setRelaunchPolicy(onRequestRelaunch: (() => void) | undefined, autoRenewSession: boolean | undefined): void;
|
|
2259
|
+
destroy(): void;
|
|
2260
|
+
private loadingStateEnabled;
|
|
2261
|
+
private autoResizeEnabled;
|
|
2262
|
+
/** Fill mode is the default; a numeric `height` opts into a fixed pixel box. */
|
|
2263
|
+
private fillEnabled;
|
|
2264
|
+
/** Write an SDK-managed height with `!important` so a host theme can't win. */
|
|
2265
|
+
private setFrameHeight;
|
|
2168
2266
|
/**
|
|
2169
|
-
*
|
|
2170
|
-
*
|
|
2171
|
-
*
|
|
2172
|
-
*
|
|
2267
|
+
* Decide whether the host gave the container a DEFINITE (bounded) height — a
|
|
2268
|
+
* fixed block the embed should fill 100% of — versus a content-sized container
|
|
2269
|
+
* that collapses to whatever the iframe measures (full-page usage).
|
|
2270
|
+
*
|
|
2271
|
+
* We drive the iframe to two extreme heights within a single synchronous task
|
|
2272
|
+
* and watch whether the container follows: a bounded box barely moves, a
|
|
2273
|
+
* content-sized one grows with the iframe. Because we restore the height before
|
|
2274
|
+
* yielding, the browser only lays out — it never paints the extremes, so there
|
|
2275
|
+
* is no visible flash. Works for px, resolved `%`, and flex (`flex:1;min-h:0`)
|
|
2276
|
+
* heights, and leaves a mere `min-height` floor classified as content-sized so
|
|
2277
|
+
* full-page hosts keep the old viewport-fill behavior.
|
|
2173
2278
|
*/
|
|
2174
|
-
|
|
2175
|
-
/** Selection changed (tap or best-available). */
|
|
2176
|
-
onSelectionChange?: (seats: PickerSeat[]) => void;
|
|
2177
|
-
/** Selection-rule state after each selection change. */
|
|
2178
|
-
onSelectionValidityChange?: (state: PickerSelectionValidity) => void;
|
|
2179
|
-
/** The configured selection rules have just become valid. */
|
|
2180
|
-
onSelectionValid?: (seats: PickerSeat[]) => void;
|
|
2181
|
-
/** The configured selection rules have just become invalid. */
|
|
2182
|
-
onSelectionInvalid?: (state: PickerSelectionValidity) => void;
|
|
2183
|
-
/** A selection attempt reached the active maximum. */
|
|
2184
|
-
onSelectionLimit?: (maxSelection: number) => void;
|
|
2279
|
+
private detectFillMode;
|
|
2185
2280
|
/**
|
|
2186
|
-
*
|
|
2187
|
-
*
|
|
2188
|
-
*
|
|
2281
|
+
* Size the iframe for the current fill verdict, clamped to `minHeight`. In
|
|
2282
|
+
* container mode it fills 100% of the bounded block; in viewport mode its
|
|
2283
|
+
* bottom edge meets the bottom of the viewport (`window.innerHeight - top`).
|
|
2284
|
+
* No-op while pinned fullscreen (the pin fills the viewport itself).
|
|
2189
2285
|
*/
|
|
2190
|
-
|
|
2191
|
-
/**
|
|
2192
|
-
|
|
2193
|
-
/** A prior active hold was verified and restored into the tray. */
|
|
2194
|
-
onHoldRestored?: (hold: HoldResult, seats: PickerSeat[], handoff: CheckoutHandoff) => void;
|
|
2195
|
-
/** Modal only: the buyer closed the picker (ESC / scrim / ✕). */
|
|
2196
|
-
onClose?: () => void;
|
|
2286
|
+
private applyFill;
|
|
2287
|
+
/** rAF-throttled fill recompute, so a burst of scroll/RO ticks coalesces. */
|
|
2288
|
+
private scheduleFill;
|
|
2197
2289
|
/**
|
|
2198
|
-
*
|
|
2199
|
-
*
|
|
2200
|
-
* `
|
|
2201
|
-
* a recoverable, buyer-explainable state, not a network failure (guide §10).
|
|
2290
|
+
* rAF-throttled re-probe: a host layout change (responsive breakpoint, a block
|
|
2291
|
+
* gaining/losing a definite height) can flip the verdict, so `resize` /
|
|
2292
|
+
* `orientationchange` re-detect and swap the container observer accordingly.
|
|
2202
2293
|
*/
|
|
2203
|
-
|
|
2294
|
+
private scheduleReprobe;
|
|
2295
|
+
/** Attach/detach the container ResizeObserver to match the current verdict. */
|
|
2296
|
+
private syncContainerObserver;
|
|
2297
|
+
private startFill;
|
|
2298
|
+
private stopFill;
|
|
2204
2299
|
/**
|
|
2205
|
-
*
|
|
2206
|
-
*
|
|
2207
|
-
*
|
|
2208
|
-
* explanatory panel; return nothing to keep it, or handle the state yourself.
|
|
2300
|
+
* Pin the iframe over the host page as a viewport-filling overlay. We save the
|
|
2301
|
+
* iframe's inline style and the document scroll state so `unpinFullscreen`
|
|
2302
|
+
* restores everything exactly. Escape (host-side) also exits.
|
|
2209
2303
|
*/
|
|
2210
|
-
|
|
2304
|
+
private pinFullscreen;
|
|
2305
|
+
/** Undo `pinFullscreen`: restore the iframe style + scroll lock. Idempotent. */
|
|
2306
|
+
private unpinFullscreen;
|
|
2307
|
+
private clearTimeoutTimer;
|
|
2211
2308
|
/**
|
|
2212
|
-
*
|
|
2213
|
-
*
|
|
2214
|
-
*
|
|
2309
|
+
* Auto-renewal (proactive + one expiry recovery) is on when the host wired a
|
|
2310
|
+
* relaunch hook and did not opt out. Without the hook there is nothing to call,
|
|
2311
|
+
* so it is a no-op.
|
|
2215
2312
|
*/
|
|
2216
|
-
|
|
2313
|
+
private autoRenewEnabled;
|
|
2314
|
+
private clearRenewTimer;
|
|
2217
2315
|
/**
|
|
2218
|
-
*
|
|
2219
|
-
*
|
|
2316
|
+
* Arm the proactive renewal timer from a `ready` message's `expiresAt` (epoch
|
|
2317
|
+
* ms). We relaunch a comfortable lead before expiry so the host can mint a fresh
|
|
2318
|
+
* session and swap `designerUrl` without the user ever seeing the expiry card:
|
|
2220
2319
|
*
|
|
2221
|
-
*
|
|
2222
|
-
*
|
|
2223
|
-
*
|
|
2224
|
-
*
|
|
2225
|
-
*
|
|
2226
|
-
* prompt opens as usual, so this is also usable as a plain notification.
|
|
2320
|
+
* - normal TTL (≥ 15 min): renew {@link RENEW_LEAD_MS} (~3 min) before expiry;
|
|
2321
|
+
* - short TTL (< 15 min): renew after {@link RENEW_SHORT_TTL_FRACTION} (80%) of
|
|
2322
|
+
* the remaining life, so the lead can't overshoot the whole session;
|
|
2323
|
+
* - either way, never sooner than {@link RENEW_MIN_DELAY_MS} (30s) after `ready`
|
|
2324
|
+
* so a burst of `ready` messages can't spin the host.
|
|
2227
2325
|
*
|
|
2228
|
-
*
|
|
2229
|
-
*
|
|
2230
|
-
*
|
|
2326
|
+
* Re-armed on every `ready`; cleared on destroy / setDesignerUrl (via re-mount).
|
|
2327
|
+
* A no-op when auto-renewal is off or `expiresAt` is missing/already past — the
|
|
2328
|
+
* expiry-error path recovers a session that has already lapsed.
|
|
2231
2329
|
*/
|
|
2232
|
-
|
|
2233
|
-
|
|
2330
|
+
private scheduleRenewal;
|
|
2331
|
+
private ensureContainerPositioned;
|
|
2332
|
+
private restoreContainerStyle;
|
|
2333
|
+
private removeOverlay;
|
|
2334
|
+
private showError;
|
|
2335
|
+
private handleTryAgain;
|
|
2336
|
+
/**
|
|
2337
|
+
* Build (or rebuild) the overlay for the given phase. A single overlay element
|
|
2338
|
+
* is reused so we never stack stale skeletons or cards.
|
|
2339
|
+
*/
|
|
2340
|
+
private renderOverlay;
|
|
2341
|
+
private buildSkeleton;
|
|
2342
|
+
private buildErrorCard;
|
|
2343
|
+
private handleMessage;
|
|
2234
2344
|
}
|
|
2235
2345
|
|
|
2236
2346
|
/** What the saved-seat comparison chip needs from the widget around it. */
|
|
@@ -2261,6 +2371,143 @@ declare class View3dCompareChip {
|
|
|
2261
2371
|
mainButton(): HTMLElement | null;
|
|
2262
2372
|
}
|
|
2263
2373
|
|
|
2374
|
+
/**
|
|
2375
|
+
* The cart's arithmetic, in ONE place.
|
|
2376
|
+
*
|
|
2377
|
+
* Held server lines, freshly-picked seats and pending GA quantities, all priced
|
|
2378
|
+
* through the picker's own `paidPrice`. The tray renders from this and the
|
|
2379
|
+
* WebMCP `get_selection` tool reads it, so a buyer looking at the sheet and an
|
|
2380
|
+
* agent asking what is selected can never be told two different totals — which
|
|
2381
|
+
* is exactly what a second copy of these six reduces would eventually produce.
|
|
2382
|
+
*
|
|
2383
|
+
* It lives here rather than on SeatPicker because that file is pinned at its
|
|
2384
|
+
* size in the app's file-size ratchet and may not grow, and because a pure
|
|
2385
|
+
* function over a named slice is easier to check than a method with fifty
|
|
2386
|
+
* neighbours.
|
|
2387
|
+
*/
|
|
2388
|
+
|
|
2389
|
+
/** A chart category as far as pricing is concerned. */
|
|
2390
|
+
interface PricedCategory {
|
|
2391
|
+
key?: string;
|
|
2392
|
+
price?: number;
|
|
2393
|
+
tiers?: {
|
|
2394
|
+
id?: string;
|
|
2395
|
+
price: number;
|
|
2396
|
+
}[];
|
|
2397
|
+
}
|
|
2398
|
+
|
|
2399
|
+
/**
|
|
2400
|
+
* WebMCP tools for the buyer picker (`webMcp` option, off by default).
|
|
2401
|
+
*
|
|
2402
|
+
* An AI agent running in the buyer's browser drives the REAL widget through the
|
|
2403
|
+
* same functions a tap does — search, select, and (only when the integrator
|
|
2404
|
+
* opts in) hold — instead of guessing at pixels. Nothing here runs unless the
|
|
2405
|
+
* host asked for it, and nothing here may break a render: a runtime without the
|
|
2406
|
+
* API, or one that rejects a registration, costs one console.warn. The module
|
|
2407
|
+
* talks to a narrow `WebMcpHost` rather than to `SeatPicker`, so every tool is
|
|
2408
|
+
* testable without mounting a widget.
|
|
2409
|
+
*/
|
|
2410
|
+
/** Event facts the picker learned when the chart loaded. */
|
|
2411
|
+
interface WebMcpEventFacts {
|
|
2412
|
+
name: string;
|
|
2413
|
+
venue: string | null;
|
|
2414
|
+
startsAt: number | null;
|
|
2415
|
+
timezone: string | null;
|
|
2416
|
+
currency: string;
|
|
2417
|
+
salesClosed: boolean;
|
|
2418
|
+
}
|
|
2419
|
+
interface WebMcpCategoryFacts {
|
|
2420
|
+
key: string;
|
|
2421
|
+
label: string;
|
|
2422
|
+
price?: number;
|
|
2423
|
+
priceRange?: {
|
|
2424
|
+
min: number;
|
|
2425
|
+
max: number;
|
|
2426
|
+
};
|
|
2427
|
+
available: number;
|
|
2428
|
+
}
|
|
2429
|
+
/** One bookable seat, flattened for search. Ids/labels stay the picker's. */
|
|
2430
|
+
interface WebMcpSeatFacts {
|
|
2431
|
+
id: string;
|
|
2432
|
+
label: string;
|
|
2433
|
+
/** Contiguity owner: the logical row a run may not bridge. */
|
|
2434
|
+
rowKey: string;
|
|
2435
|
+
/** Section owner, used by the `together: false` relaxation. */
|
|
2436
|
+
sectionKey: string;
|
|
2437
|
+
/** Seat order inside the row; a missing integer marks an aisle. */
|
|
2438
|
+
index: number;
|
|
2439
|
+
categoryKey: string;
|
|
2440
|
+
/** The price the buyer would actually pay (channel/host overrides applied). */
|
|
2441
|
+
price: number;
|
|
2442
|
+
zoneId?: string;
|
|
2443
|
+
available: boolean;
|
|
2444
|
+
}
|
|
2445
|
+
/** Buyer-facing words for one seat — the SAME short row/seat the widget's own
|
|
2446
|
+
* seat card prints, never the raw row label ("Stalls A A"), which repeats the
|
|
2447
|
+
* section and reads to an agent as a bug. */
|
|
2448
|
+
interface WebMcpSeatWords {
|
|
2449
|
+
section: string;
|
|
2450
|
+
row: string;
|
|
2451
|
+
seat: string;
|
|
2452
|
+
category: string;
|
|
2453
|
+
}
|
|
2454
|
+
interface WebMcpSelectionState {
|
|
2455
|
+
seats: Array<WebMcpSeatWords & {
|
|
2456
|
+
id: string;
|
|
2457
|
+
label: string;
|
|
2458
|
+
price: number;
|
|
2459
|
+
}>;
|
|
2460
|
+
count: number;
|
|
2461
|
+
total: number;
|
|
2462
|
+
currency: string;
|
|
2463
|
+
hold: {
|
|
2464
|
+
id: string;
|
|
2465
|
+
expiresAt: number;
|
|
2466
|
+
} | null;
|
|
2467
|
+
validity: unknown;
|
|
2468
|
+
}
|
|
2469
|
+
type WebMcpHoldOutcome = {
|
|
2470
|
+
ok: true;
|
|
2471
|
+
hold: {
|
|
2472
|
+
id: string;
|
|
2473
|
+
expiresAt: number;
|
|
2474
|
+
};
|
|
2475
|
+
handoff?: unknown;
|
|
2476
|
+
} | {
|
|
2477
|
+
ok: false;
|
|
2478
|
+
reason: string;
|
|
2479
|
+
};
|
|
2480
|
+
/** Everything the tools need from the widget, and nothing else. */
|
|
2481
|
+
interface WebMcpHost {
|
|
2482
|
+
event(): WebMcpEventFacts | null;
|
|
2483
|
+
selectionLimits(): {
|
|
2484
|
+
max: number;
|
|
2485
|
+
required: number | null;
|
|
2486
|
+
};
|
|
2487
|
+
categories(): WebMcpCategoryFacts[];
|
|
2488
|
+
zones(): Array<{
|
|
2489
|
+
id: string;
|
|
2490
|
+
label: string;
|
|
2491
|
+
}>;
|
|
2492
|
+
hasPremiumSeats(): boolean;
|
|
2493
|
+
seats(): WebMcpSeatFacts[];
|
|
2494
|
+
/** Buyer-facing spatial words for one seat, resolved lazily per result. */
|
|
2495
|
+
describeSeat(id: string): WebMcpSeatWords | null;
|
|
2496
|
+
selection(): WebMcpSelectionState;
|
|
2497
|
+
clearSelection(): void;
|
|
2498
|
+
selectObjects(ids: string[]): void;
|
|
2499
|
+
hold(): Promise<WebMcpHoldOutcome>;
|
|
2500
|
+
}
|
|
2501
|
+
interface WebMcpRegistration {
|
|
2502
|
+
/** Tool names actually registered, in registration order. */
|
|
2503
|
+
names: string[];
|
|
2504
|
+
/** Abort the registration signal; unregister by name where supported. */
|
|
2505
|
+
dispose: () => void;
|
|
2506
|
+
}
|
|
2507
|
+
|
|
2508
|
+
/** What `PickerController.render()` reports back about the loaded event. */
|
|
2509
|
+
type PickerRenderInfo = NonNullable<Awaited<ReturnType<PickerController['render']>>>;
|
|
2510
|
+
|
|
2264
2511
|
declare class SeatPicker implements GaPromptPicker {
|
|
2265
2512
|
/** @internal Read by pickerGaPrompt for the `onGAPrompt` host hook. */
|
|
2266
2513
|
readonly opts: SeatPickerOptions;
|
|
@@ -2277,7 +2524,7 @@ declare class SeatPicker implements GaPromptPicker {
|
|
|
2277
2524
|
/** @internal */ readonly controller: PickerController;
|
|
2278
2525
|
/** @internal */ maxTickets: number;
|
|
2279
2526
|
/** Exact ticket count required before checkout; null keeps ordinary 1..max behavior. */
|
|
2280
|
-
|
|
2527
|
+
/** @internal */ readonly exactTickets: number | null;
|
|
2281
2528
|
private lastSelectionValidity;
|
|
2282
2529
|
/** Original host pricing, kept separate from live server offer overrides. */
|
|
2283
2530
|
private readonly hostPricing;
|
|
@@ -2287,7 +2534,11 @@ declare class SeatPicker implements GaPromptPicker {
|
|
|
2287
2534
|
/** @internal */ root: HTMLDivElement | null;
|
|
2288
2535
|
private mapHost;
|
|
2289
2536
|
private rendered;
|
|
2290
|
-
|
|
2537
|
+
/** @internal */ destroyed: boolean;
|
|
2538
|
+
/** @internal Chart-load facts; WebMCP's describe_event answers from them. */
|
|
2539
|
+
renderInfo: PickerRenderInfo | null;
|
|
2540
|
+
/** @internal Live WebMCP registration, when the host opted in. */
|
|
2541
|
+
webMcp: WebMcpRegistration | null;
|
|
2291
2542
|
/** Bumped on every locale REQUEST, so a load that resolves late can tell it
|
|
2292
2543
|
* is no longer the one asked for. See {@link applyActiveLocale}. */
|
|
2293
2544
|
private localeGeneration;
|
|
@@ -2304,15 +2555,15 @@ declare class SeatPicker implements GaPromptPicker {
|
|
|
2304
2555
|
private offerVisibilityHandler;
|
|
2305
2556
|
/** Short-lived UI motion timers; all are cancelled on destroy. */
|
|
2306
2557
|
private motionTimers;
|
|
2307
|
-
|
|
2558
|
+
/** @internal */ currency: string;
|
|
2308
2559
|
private eventTimezone;
|
|
2309
2560
|
/** The event's formatted date-time (event-zone), reused by the closed-state note. */
|
|
2310
2561
|
private eventWhenText;
|
|
2311
2562
|
private offerAvailability;
|
|
2312
2563
|
/** Server-authoritative channel rules, projected only for this buyer scope. */
|
|
2313
2564
|
private readonly channelByObject;
|
|
2314
|
-
|
|
2315
|
-
|
|
2565
|
+
/** @internal */ readonly pricesByChannel: Map<string, ChannelPriceOverride[]>;
|
|
2566
|
+
/** @internal */ hold: HoldResult | null;
|
|
2316
2567
|
/** Latest server expiry for the open hold (moves on extend). */
|
|
2317
2568
|
private holdExpiresAt;
|
|
2318
2569
|
/** True once we handed off to checkout — arms booked-confirmation detection. */
|
|
@@ -2539,6 +2790,9 @@ declare class SeatPicker implements GaPromptPicker {
|
|
|
2539
2790
|
/** Controller callbacks are wired once, before the first async chart load. */
|
|
2540
2791
|
private wireController;
|
|
2541
2792
|
render(): Promise<this>;
|
|
2793
|
+
/** @internal Both hand off to pickerWebMcpBridge, which owns the mapping. */
|
|
2794
|
+
registerAgentTools(): Promise<void>;
|
|
2795
|
+
/** @internal */ webMcpHost(holds: boolean): WebMcpHost;
|
|
2542
2796
|
/** Wire host chrome after the skeleton exists and before the renderer owns its map host. */
|
|
2543
2797
|
private wireBuyerShell;
|
|
2544
2798
|
/**
|
|
@@ -2656,7 +2910,7 @@ declare class SeatPicker implements GaPromptPicker {
|
|
|
2656
2910
|
/** A completed hold gets one short map ripple per concrete seat. */
|
|
2657
2911
|
private flashHeldSeats;
|
|
2658
2912
|
/** Update only the action affordance; selection callbacks must not refire. */
|
|
2659
|
-
|
|
2913
|
+
/** @internal */ committedSelection(): PickerSeat[];
|
|
2660
2914
|
private pendingSelectionCount;
|
|
2661
2915
|
private heldTicketCount;
|
|
2662
2916
|
/** @internal */ totalTicketCount(): number;
|
|
@@ -2676,10 +2930,11 @@ declare class SeatPicker implements GaPromptPicker {
|
|
|
2676
2930
|
/** Attach the F3 overview minimap into the bottom-left chrome region. */
|
|
2677
2931
|
private buildMinimap;
|
|
2678
2932
|
/** Effective category summary price. Object-specific channel prices are added to the range below. */
|
|
2679
|
-
|
|
2680
|
-
/**
|
|
2681
|
-
|
|
2682
|
-
|
|
2933
|
+
/** @internal */ catPrice(c: PricedCategory): number | undefined;
|
|
2934
|
+
/** @internal */ catPriceRange(c: PricedCategory): {
|
|
2935
|
+
min: number;
|
|
2936
|
+
max: number;
|
|
2937
|
+
} | undefined;
|
|
2683
2938
|
/** Build the compact price selector in the panel header. Choosing a band both
|
|
2684
2939
|
* filters availability and smoothly frames the matching seats on the map. */
|
|
2685
2940
|
private buildPriceFilter;
|
|
@@ -2818,7 +3073,7 @@ declare class SeatPicker implements GaPromptPicker {
|
|
|
2818
3073
|
*/
|
|
2819
3074
|
private removeHeldLabels;
|
|
2820
3075
|
private handleChangeSeats;
|
|
2821
|
-
|
|
3076
|
+
/** @internal */ handleCta(): Promise<void>;
|
|
2822
3077
|
private startHoldTimer;
|
|
2823
3078
|
private stopHoldTimer;
|
|
2824
3079
|
/** Show/refresh (or hide) the "Need more time?" prompt with the live seconds left. */
|
|
@@ -3747,4 +4002,4 @@ interface AttachPickerFrameOptions {
|
|
|
3747
4002
|
*/
|
|
3748
4003
|
declare function attachPickerFrame(iframe: HTMLIFrameElement, opts?: AttachPickerFrameOptions): () => void;
|
|
3749
4004
|
|
|
3750
|
-
export { ApiError, type AttachPickerFrameOptions, type BestAvailableResult, BuyerAccessContext, type BuyerAccessExpiredEvent, type BuyerAccessRefreshReason, type BuyerAccessToken, type BuyerAccessTokenProvider, BuyerAccessUnavailableError, type BuyerAccessUnavailableEvent, type BuyerAccessUnavailableReason, BuyerRealtimeClient, type BuyerRealtimeOptions, type CheckoutHandoff, type CheckoutLineItem, type CheckoutSessionResult, EmbeddedDesigner, type EmbeddedDesignerEventType, type EmbeddedDesignerMessage, type EmbeddedDesignerOptions, type GAAreaAvailability, type GAPromptRequest, type GaPromptTier, type HoldConflict, type HoldLineItem, type HoldResult, type OrderStatusResult, type PaymentOptionsReason, type PaymentOptionsResult, type PaymentProviderName, type PerformanceGroupAvailability, type PerformanceGroupCheckoutHandoff, type PerformanceGroupDescriptor, PerformanceGroupDestroyedError, type PerformanceGroupHold, type PerformanceGroupHoldAllocation, type PerformanceGroupOperationEvent, type PerformanceGroupOperationState, PerformanceGroupPicker, type PerformanceGroupPickerOptions, type PerformanceGroupRecoveryState, type PerformanceGroupSeatAllocation, type PerformanceGroupSelectionMode, type PerformanceGroupStatusEvent, type Projection, type PubApiOptions, type RealtimeSink, type ResumedHoldResult, SEATING_CHART_CALLBACK_PROPS, SEATING_CHART_HANDLE_METHODS, SEATING_CHART_IDENTITY_PROPS, SEATING_CHART_VALUE_PROPS, type SaleState, SeasonApiError, type SeasonAvailability, type SeasonCheckoutHandoff, type SeasonDescriptor, type SeasonOperation, type SeasonOperationState, SeasonPicker, type SeasonPickerOptions, SeasonRecoveryTimeoutError, type SeasonRenewalIntent, type SeasonStatusEvent, SeatPicker, type SeatPickerBestAvailableOptions, type SeatPickerBuyerView, type SeatPickerBuyerViewOptions, type SeatPickerOptions, type SeatPickerPricing, type SeatPickerTheme, SeatingChart, type SeatingChartCallbackProp, type SeatingChartCallbacks, type SeatingChartHandle, type SeatingChartHandleMethod, type SeatingChartIdentityProp, type SeatingChartOptions, type SeatingChartValueProp, type SeatingChartValues, type SelectedObjectUnavailableEvent, type SelectedSeat, type StatusChange, type SubscribeTicket, ThemeMode, type TicketOfferAvailability, type TicketOfferPrice, type TicketOfferSummary, attachPickerFrame, bindSeatingChartHandle, buildSeatingChartOptions, createBuyerAccessContext, createControllerSink, parseTicketOfferAvailability, shortOperationReference, ticketOfferPrices };
|
|
4005
|
+
export { ApiError, type AttachPickerFrameOptions, type BestAvailableResult, BuyerAccessContext, type BuyerAccessExpiredEvent, type BuyerAccessRefreshReason, type BuyerAccessToken, type BuyerAccessTokenProvider, BuyerAccessUnavailableError, type BuyerAccessUnavailableEvent, type BuyerAccessUnavailableReason, BuyerRealtimeClient, type BuyerRealtimeOptions, type CheckoutHandoff, type CheckoutLineItem, type CheckoutSessionResult, EmbeddedDesigner, type EmbeddedDesignerEventType, type EmbeddedDesignerMessage, type EmbeddedDesignerOptions, type GAAreaAvailability, type GAPromptRequest, type GaPromptTier, type HoldConflict, type HoldLineItem, type HoldResult, type OrderStatusResult, type PaymentOptionsReason, type PaymentOptionsResult, type PaymentProviderName, type PerformanceGroupAvailability, type PerformanceGroupCheckoutHandoff, type PerformanceGroupDescriptor, PerformanceGroupDestroyedError, type PerformanceGroupHold, type PerformanceGroupHoldAllocation, type PerformanceGroupOperationEvent, type PerformanceGroupOperationState, PerformanceGroupPicker, type PerformanceGroupPickerOptions, type PerformanceGroupRecoveryState, type PerformanceGroupSeatAllocation, type PerformanceGroupSelectionMode, type PerformanceGroupStatusEvent, type Projection, type PubApiOptions, type RealtimeSink, type ResumedHoldResult, SEATING_CHART_CALLBACK_PROPS, SEATING_CHART_HANDLE_METHODS, SEATING_CHART_IDENTITY_PROPS, SEATING_CHART_VALUE_PROPS, type SaleState, SeasonApiError, type SeasonAvailability, type SeasonCheckoutHandoff, type SeasonDescriptor, type SeasonOperation, type SeasonOperationState, SeasonPicker, type SeasonPickerOptions, SeasonRecoveryTimeoutError, type SeasonRenewalIntent, type SeasonStatusEvent, SeatPicker, type SeatPickerBestAvailableOptions, type SeatPickerBuyerView, type SeatPickerBuyerViewOptions, type SeatPickerOptions, type SeatPickerPricing, type SeatPickerTheme, type SeatPickerWebMcpOptions, SeatingChart, type SeatingChartCallbackProp, type SeatingChartCallbacks, type SeatingChartHandle, type SeatingChartHandleMethod, type SeatingChartIdentityProp, type SeatingChartOptions, type SeatingChartValueProp, type SeatingChartValues, type SelectedObjectUnavailableEvent, type SelectedSeat, type StatusChange, type SubscribeTicket, ThemeMode, type TicketOfferAvailability, type TicketOfferPrice, type TicketOfferSummary, attachPickerFrame, bindSeatingChartHandle, buildSeatingChartOptions, createBuyerAccessContext, createControllerSink, parseTicketOfferAvailability, shortOperationReference, ticketOfferPrices };
|