@seatlayer/js 0.7.3 → 0.9.0

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.d.cts CHANGED
@@ -271,6 +271,40 @@ declare class EmbeddedDesigner {
271
271
  * so plain host CSS can restyle too.
272
272
  */
273
273
 
274
+ /**
275
+ * Stable checkout-handoff contract (P4). Passed as the THIRD argument to
276
+ * `onCheckout(hold, seats, handoff)` — additive, so the legacy `(hold, seats)`
277
+ * shape used by DesiPass web-v2 (SDK 0.7.3+) is untouched. This is the object to
278
+ * build your order against: it is self-contained (holdId, expiry, currency, and
279
+ * per-line tier + price) and never changes shape across minor releases.
280
+ */
281
+ interface CheckoutLineItem {
282
+ /** Seat label (or GA synthetic-unit label). */
283
+ label: string;
284
+ /** Chart object id (row/booth/GA area) the unit belongs to. */
285
+ objectId: string;
286
+ objectType: 'seat' | 'booth' | 'ga';
287
+ categoryKey: string;
288
+ /** Chosen ticket tier id (Adult/Child/…), or null when the category has no tiers. */
289
+ tierId: string | null;
290
+ /** Unit price in MAJOR currency units (e.g. 45 = 45.00). Server-authoritative. */
291
+ unitPrice: number;
292
+ /** ISO-4217, resolved server-side (per-event override → org → USD). */
293
+ currency: string;
294
+ quantity: number;
295
+ }
296
+ interface CheckoutHandoff {
297
+ /** Server hold id — pass this to YOUR book call. */
298
+ holdId: string;
299
+ /** Epoch ms the hold expires (after any extensions). */
300
+ expiresAt: number;
301
+ /** ISO-4217 currency for the whole order. */
302
+ currency: string;
303
+ /** Priced line items (tier + unit price + currency), server-authoritative. */
304
+ lineItems: CheckoutLineItem[];
305
+ /** Convenience total in major units (Σ unitPrice × quantity). */
306
+ total: number;
307
+ }
274
308
  /** Host theme overrides — any subset; unset keys fall back to the org's chart theme, then defaults. */
275
309
  interface SeatPickerTheme {
276
310
  /** Brand accent (CTA, active chips, hold pill). */
@@ -324,11 +358,26 @@ interface SeatPickerOptions {
324
358
  * price · Add/Cancel) instead of adding straight to the tray. Default false.
325
359
  */
326
360
  confirmSelection?: boolean;
361
+ /**
362
+ * Offer a "View from seat" 360° preview (confirm popover + tray chips). The
363
+ * panorama is generated from the chart geometry, or the organizer's uploaded
364
+ * photo when a seat carries one. Default true; set false to hide the affordance.
365
+ */
366
+ seatView?: boolean;
327
367
  /**
328
368
  * Buyer pressed the CTA and the hold succeeded — hand off to YOUR checkout.
329
- * The hold carries holdId, expiresAt, seat labels and priced line items.
369
+ * `hold` and `seats` are the legacy args (unchanged since 0.6). `handoff` (P4)
370
+ * is the stable, self-contained {@link CheckoutHandoff} to build your order
371
+ * against — holdId, expiry, currency and priced line items. Prefer it.
330
372
  */
331
- onCheckout?: (hold: HoldResult, seats: PickerSeat[]) => void;
373
+ onCheckout?: (hold: HoldResult, seats: PickerSeat[], handoff: CheckoutHandoff) => void;
374
+ /**
375
+ * The held seats were BOOKED (P4) — your server completed payment and the
376
+ * booking landed over the realtime channel while the widget was still open.
377
+ * The widget shows a success state; use this to advance your own UI (receipt,
378
+ * redirect). Fires once per hold.
379
+ */
380
+ onBooked?: (handoff: CheckoutHandoff) => void;
332
381
  /** Selection changed (tap or best-available). */
333
382
  onSelectionChange?: (seats: PickerSeat[]) => void;
334
383
  /** The open hold expired server-side (widget already reset itself). */
@@ -350,6 +399,14 @@ declare class SeatPicker {
350
399
  private toastTimer;
351
400
  private currency;
352
401
  private hold;
402
+ /** Latest server expiry for the open hold (moves on extend). */
403
+ private holdExpiresAt;
404
+ /** True once we handed off to checkout — arms booked-confirmation detection. */
405
+ private handedOff;
406
+ /** Guards single onBooked + single success overlay per hold. */
407
+ private bookedShown;
408
+ private extendEl;
409
+ private bookedEl;
353
410
  private gaQty;
354
411
  private tipEl;
355
412
  private tipPos;
@@ -359,6 +416,12 @@ declare class SeatPicker {
359
416
  private a11yFilter;
360
417
  private baQty;
361
418
  private baCat;
419
+ private rungsEl;
420
+ private floorsEl;
421
+ private secCardEl;
422
+ private viewEl;
423
+ private viewCleanup;
424
+ private allSeatsCache;
362
425
  private modalScrim;
363
426
  private prevFocus;
364
427
  private escHandler;
@@ -374,11 +437,34 @@ declare class SeatPicker {
374
437
  static open(options: Omit<SeatPickerOptions, 'container'>): Promise<SeatPicker>;
375
438
  constructor(options: SeatPickerOptions);
376
439
  render(): Promise<this>;
440
+ /** The "Need more time?" prompt shown in the hold's final EXTEND_PROMPT_MS. */
441
+ private buildExtendPrompt;
442
+ /** Success overlay + onBooked fire when the held seats settle to booked. */
443
+ private buildBookedOverlay;
444
+ /** Build the rung pills (charts with sections) and floor switcher (>1 floor). */
445
+ private buildArenaChrome;
446
+ /** Reflect the engine's current LOD rung onto the pill group. */
447
+ private syncRung;
448
+ /** Reflect the active floor onto the switcher rail. */
449
+ private syncFloors;
450
+ /** Show (or clear, on null) the tapped-section summary card. */
451
+ private showSectionCard;
377
452
  /** aria-live readout when keyboard focus lands on a seat. */
378
453
  private announceSeat;
379
454
  private showConfirm;
380
455
  private reanchorConfirm;
381
456
  private closeConfirm;
457
+ private seatViewEnabled;
458
+ /** Every bookable seat (cached) — neighbor heads for the generated panorama. */
459
+ private allSeats;
460
+ /**
461
+ * Open the drag-to-look-around 360° preview for a seat. Uses the organizer's
462
+ * uploaded photo (seat.viewUrl) when present, else a panorama generated from
463
+ * the chart geometry — the stage placed at this seat's true bearing + size.
464
+ * Zero extra dependencies: an equirectangular image panned with `repeat-x`.
465
+ */
466
+ private openSeatView;
467
+ private closeSeatView;
382
468
  private money;
383
469
  private syncPrices;
384
470
  /** A live delta took one of OUR selected (not yet held) seats — evict + tell the buyer. */
@@ -387,6 +473,21 @@ declare class SeatPicker {
387
473
  private handleCta;
388
474
  private startHoldTimer;
389
475
  private stopHoldTimer;
476
+ /** Show/refresh (or hide) the "Need more time?" prompt with the live seconds left. */
477
+ private setExtendPrompt;
478
+ private handleExtend;
479
+ /**
480
+ * Fire the booked-confirmation state once the buyer's held seats settle to
481
+ * booked. The controller clears its own hold the moment every held label reads
482
+ * 'booked' over the realtime channel (clearBookedHoldIfSettled), and this runs
483
+ * on the same onStatusChange — so `currentHold() === null` while we still hold
484
+ * a checkout handoff means "sold", not expired (expiry clears via onHoldExpired
485
+ * on a different path, which nulls this.hold first).
486
+ */
487
+ private detectBooked;
488
+ private showBooked;
489
+ /** Assemble the stable {@link CheckoutHandoff} from a hold's server line items. */
490
+ private buildHandoff;
390
491
  private toast;
391
492
  private placeTooltip;
392
493
  private updateTooltip;
@@ -396,4 +497,4 @@ declare class SeatPicker {
396
497
  destroy(): void;
397
498
  }
398
499
 
399
- export { ApiError, type BestAvailableResult, EmbeddedDesigner, type EmbeddedDesignerEventType, type EmbeddedDesignerMessage, type EmbeddedDesignerOptions, type GAAreaAvailability, type HoldConflict, type HoldLineItem, type HoldResult, SeatPicker, type SeatPickerOptions, type SeatPickerTheme, SeatingChart, type SeatingChartOptions, type SelectedSeat };
500
+ export { ApiError, type BestAvailableResult, type CheckoutHandoff, type CheckoutLineItem, EmbeddedDesigner, type EmbeddedDesignerEventType, type EmbeddedDesignerMessage, type EmbeddedDesignerOptions, type GAAreaAvailability, type HoldConflict, type HoldLineItem, type HoldResult, SeatPicker, type SeatPickerOptions, type SeatPickerTheme, SeatingChart, type SeatingChartOptions, type SelectedSeat };
package/dist/index.d.ts CHANGED
@@ -271,6 +271,40 @@ declare class EmbeddedDesigner {
271
271
  * so plain host CSS can restyle too.
272
272
  */
273
273
 
274
+ /**
275
+ * Stable checkout-handoff contract (P4). Passed as the THIRD argument to
276
+ * `onCheckout(hold, seats, handoff)` — additive, so the legacy `(hold, seats)`
277
+ * shape used by DesiPass web-v2 (SDK 0.7.3+) is untouched. This is the object to
278
+ * build your order against: it is self-contained (holdId, expiry, currency, and
279
+ * per-line tier + price) and never changes shape across minor releases.
280
+ */
281
+ interface CheckoutLineItem {
282
+ /** Seat label (or GA synthetic-unit label). */
283
+ label: string;
284
+ /** Chart object id (row/booth/GA area) the unit belongs to. */
285
+ objectId: string;
286
+ objectType: 'seat' | 'booth' | 'ga';
287
+ categoryKey: string;
288
+ /** Chosen ticket tier id (Adult/Child/…), or null when the category has no tiers. */
289
+ tierId: string | null;
290
+ /** Unit price in MAJOR currency units (e.g. 45 = 45.00). Server-authoritative. */
291
+ unitPrice: number;
292
+ /** ISO-4217, resolved server-side (per-event override → org → USD). */
293
+ currency: string;
294
+ quantity: number;
295
+ }
296
+ interface CheckoutHandoff {
297
+ /** Server hold id — pass this to YOUR book call. */
298
+ holdId: string;
299
+ /** Epoch ms the hold expires (after any extensions). */
300
+ expiresAt: number;
301
+ /** ISO-4217 currency for the whole order. */
302
+ currency: string;
303
+ /** Priced line items (tier + unit price + currency), server-authoritative. */
304
+ lineItems: CheckoutLineItem[];
305
+ /** Convenience total in major units (Σ unitPrice × quantity). */
306
+ total: number;
307
+ }
274
308
  /** Host theme overrides — any subset; unset keys fall back to the org's chart theme, then defaults. */
275
309
  interface SeatPickerTheme {
276
310
  /** Brand accent (CTA, active chips, hold pill). */
@@ -324,11 +358,26 @@ interface SeatPickerOptions {
324
358
  * price · Add/Cancel) instead of adding straight to the tray. Default false.
325
359
  */
326
360
  confirmSelection?: boolean;
361
+ /**
362
+ * Offer a "View from seat" 360° preview (confirm popover + tray chips). The
363
+ * panorama is generated from the chart geometry, or the organizer's uploaded
364
+ * photo when a seat carries one. Default true; set false to hide the affordance.
365
+ */
366
+ seatView?: boolean;
327
367
  /**
328
368
  * Buyer pressed the CTA and the hold succeeded — hand off to YOUR checkout.
329
- * The hold carries holdId, expiresAt, seat labels and priced line items.
369
+ * `hold` and `seats` are the legacy args (unchanged since 0.6). `handoff` (P4)
370
+ * is the stable, self-contained {@link CheckoutHandoff} to build your order
371
+ * against — holdId, expiry, currency and priced line items. Prefer it.
330
372
  */
331
- onCheckout?: (hold: HoldResult, seats: PickerSeat[]) => void;
373
+ onCheckout?: (hold: HoldResult, seats: PickerSeat[], handoff: CheckoutHandoff) => void;
374
+ /**
375
+ * The held seats were BOOKED (P4) — your server completed payment and the
376
+ * booking landed over the realtime channel while the widget was still open.
377
+ * The widget shows a success state; use this to advance your own UI (receipt,
378
+ * redirect). Fires once per hold.
379
+ */
380
+ onBooked?: (handoff: CheckoutHandoff) => void;
332
381
  /** Selection changed (tap or best-available). */
333
382
  onSelectionChange?: (seats: PickerSeat[]) => void;
334
383
  /** The open hold expired server-side (widget already reset itself). */
@@ -350,6 +399,14 @@ declare class SeatPicker {
350
399
  private toastTimer;
351
400
  private currency;
352
401
  private hold;
402
+ /** Latest server expiry for the open hold (moves on extend). */
403
+ private holdExpiresAt;
404
+ /** True once we handed off to checkout — arms booked-confirmation detection. */
405
+ private handedOff;
406
+ /** Guards single onBooked + single success overlay per hold. */
407
+ private bookedShown;
408
+ private extendEl;
409
+ private bookedEl;
353
410
  private gaQty;
354
411
  private tipEl;
355
412
  private tipPos;
@@ -359,6 +416,12 @@ declare class SeatPicker {
359
416
  private a11yFilter;
360
417
  private baQty;
361
418
  private baCat;
419
+ private rungsEl;
420
+ private floorsEl;
421
+ private secCardEl;
422
+ private viewEl;
423
+ private viewCleanup;
424
+ private allSeatsCache;
362
425
  private modalScrim;
363
426
  private prevFocus;
364
427
  private escHandler;
@@ -374,11 +437,34 @@ declare class SeatPicker {
374
437
  static open(options: Omit<SeatPickerOptions, 'container'>): Promise<SeatPicker>;
375
438
  constructor(options: SeatPickerOptions);
376
439
  render(): Promise<this>;
440
+ /** The "Need more time?" prompt shown in the hold's final EXTEND_PROMPT_MS. */
441
+ private buildExtendPrompt;
442
+ /** Success overlay + onBooked fire when the held seats settle to booked. */
443
+ private buildBookedOverlay;
444
+ /** Build the rung pills (charts with sections) and floor switcher (>1 floor). */
445
+ private buildArenaChrome;
446
+ /** Reflect the engine's current LOD rung onto the pill group. */
447
+ private syncRung;
448
+ /** Reflect the active floor onto the switcher rail. */
449
+ private syncFloors;
450
+ /** Show (or clear, on null) the tapped-section summary card. */
451
+ private showSectionCard;
377
452
  /** aria-live readout when keyboard focus lands on a seat. */
378
453
  private announceSeat;
379
454
  private showConfirm;
380
455
  private reanchorConfirm;
381
456
  private closeConfirm;
457
+ private seatViewEnabled;
458
+ /** Every bookable seat (cached) — neighbor heads for the generated panorama. */
459
+ private allSeats;
460
+ /**
461
+ * Open the drag-to-look-around 360° preview for a seat. Uses the organizer's
462
+ * uploaded photo (seat.viewUrl) when present, else a panorama generated from
463
+ * the chart geometry — the stage placed at this seat's true bearing + size.
464
+ * Zero extra dependencies: an equirectangular image panned with `repeat-x`.
465
+ */
466
+ private openSeatView;
467
+ private closeSeatView;
382
468
  private money;
383
469
  private syncPrices;
384
470
  /** A live delta took one of OUR selected (not yet held) seats — evict + tell the buyer. */
@@ -387,6 +473,21 @@ declare class SeatPicker {
387
473
  private handleCta;
388
474
  private startHoldTimer;
389
475
  private stopHoldTimer;
476
+ /** Show/refresh (or hide) the "Need more time?" prompt with the live seconds left. */
477
+ private setExtendPrompt;
478
+ private handleExtend;
479
+ /**
480
+ * Fire the booked-confirmation state once the buyer's held seats settle to
481
+ * booked. The controller clears its own hold the moment every held label reads
482
+ * 'booked' over the realtime channel (clearBookedHoldIfSettled), and this runs
483
+ * on the same onStatusChange — so `currentHold() === null` while we still hold
484
+ * a checkout handoff means "sold", not expired (expiry clears via onHoldExpired
485
+ * on a different path, which nulls this.hold first).
486
+ */
487
+ private detectBooked;
488
+ private showBooked;
489
+ /** Assemble the stable {@link CheckoutHandoff} from a hold's server line items. */
490
+ private buildHandoff;
390
491
  private toast;
391
492
  private placeTooltip;
392
493
  private updateTooltip;
@@ -396,4 +497,4 @@ declare class SeatPicker {
396
497
  destroy(): void;
397
498
  }
398
499
 
399
- export { ApiError, type BestAvailableResult, EmbeddedDesigner, type EmbeddedDesignerEventType, type EmbeddedDesignerMessage, type EmbeddedDesignerOptions, type GAAreaAvailability, type HoldConflict, type HoldLineItem, type HoldResult, SeatPicker, type SeatPickerOptions, type SeatPickerTheme, SeatingChart, type SeatingChartOptions, type SelectedSeat };
500
+ export { ApiError, type BestAvailableResult, type CheckoutHandoff, type CheckoutLineItem, EmbeddedDesigner, type EmbeddedDesignerEventType, type EmbeddedDesignerMessage, type EmbeddedDesignerOptions, type GAAreaAvailability, type HoldConflict, type HoldLineItem, type HoldResult, SeatPicker, type SeatPickerOptions, type SeatPickerTheme, SeatingChart, type SeatingChartOptions, type SelectedSeat };