@seatlayer/js 0.40.0 → 0.42.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
@@ -603,6 +603,21 @@ interface SeatingChartOptions {
603
603
  */
604
604
  onSelectedObjectUnavailable?: (event: SelectedObjectUnavailableEvent) => void;
605
605
  onError?: (err: unknown) => void;
606
+ /**
607
+ * What the BUYER sees when the chart cannot load.
608
+ *
609
+ * `'message'` (the default) renders a plain, styleable notice with a Try
610
+ * again button. This used to be silent unconditionally: `render()` returned
611
+ * with an EMPTY mounted div and only `onError` fired, so a host that had not
612
+ * wired `onError` — or had wired it to a logger — showed buyers a blank
613
+ * rectangle where the seat map belongs, on the host's own domain, which
614
+ * reads as a broken website rather than a temporary fault. `SeatPicker` has
615
+ * always failed loud with a retry; this is the embed class catching up.
616
+ *
617
+ * `'none'` restores the silent behaviour for hosts that render their own
618
+ * failure UI from `onError`.
619
+ */
620
+ errorDisplay?: 'message' | 'none';
606
621
  /**
607
622
  * Multi-floor charts only: fires when the buyer taps a deck in the stacked
608
623
  * 3D view, after the picker switches to that floor — lets the host page sync
@@ -624,6 +639,7 @@ declare class SeatingChart {
624
639
  private mount;
625
640
  private hostEl;
626
641
  private rendered;
642
+ private retryBtn;
627
643
  private mode_;
628
644
  private tipEl;
629
645
  private tipPos;
@@ -768,6 +784,13 @@ declare class SeatingChart {
768
784
  * true when a fresh bearer is held; the realtime feed restarts with it.
769
785
  */
770
786
  refreshAccess(): Promise<boolean>;
787
+ /**
788
+ * The visible failure state. Deliberately inline-styled and dependency-free:
789
+ * this renders on a stranger's website, where our stylesheet may not have
790
+ * loaded (the chart fetch just failed) and where inheriting the host's own
791
+ * styles is likelier to produce something unreadable than something on-brand.
792
+ */
793
+ private showLoadFailure;
771
794
  destroy(): void;
772
795
  }
773
796
 
@@ -1274,17 +1297,33 @@ interface SeatPickerOptions {
1274
1297
  * 1. It needs the widget's own transport. A host-supplied `transport` owns its
1275
1298
  * credentials and its backend, so hosted checkout stays off there (with one
1276
1299
  * console warning) rather than reaching past it to api.seatlayer.io.
1277
- * 2. WHERE A HOSTED GATEWAY RETURNS THE BUYER IS THE SERVER'S CHOICE. The
1278
- * checkout session's return URL is built from the deployment's own allowed
1279
- * origins, so a buyer paying by card from an embed on your domain comes back
1280
- * to SeatLayer's buyer page and is confirmed THERE, not in this widget. The
1281
- * widget resumes in place only when it is mounted on a page that actually
1282
- * receives `?order=…&status=success` (a page on an allowed origin, and the
1283
- * in-page gateways, which never navigate away at all). Until the server
1284
- * accepts a caller-supplied return URL, treat a card payment from a
1285
- * third-party embed as "the buyer finishes on our page".
1300
+ * 2. WHERE A HOSTED GATEWAY RETURNS THE BUYER is settled by {@link returnUrl}
1301
+ * and by the organizer. Without one — or from an origin the organizer has
1302
+ * not declared the buyer comes back to SeatLayer's own buyer page and is
1303
+ * confirmed THERE, not in this widget. Declare the embedding site under
1304
+ * Embed domains in the dashboard and pass `returnUrl`, and the buyer
1305
+ * returns to your page instead. In-page gateways never navigate away at
1306
+ * all, so they are unaffected either way.
1286
1307
  */
1287
1308
  checkout?: 'handoff' | 'hosted';
1309
+ /**
1310
+ * Where a redirecting gateway should send the buyer back to, for
1311
+ * `checkout: 'hosted'`.
1312
+ *
1313
+ * The server keeps this URL verbatim — path and query included — and only
1314
+ * stamps `?order=…&status=success|cancelled` onto it, so point it at
1315
+ * whichever of YOUR pages should confirm the purchase (often just
1316
+ * `window.location.href`). Mount a picker on that page and it resumes in
1317
+ * place from those parameters.
1318
+ *
1319
+ * It is validated, not trusted: the organizer declares their embed origins
1320
+ * in the dashboard, and an undeclared origin is ignored rather than
1321
+ * refused — the sale still completes, the buyer just finishes on
1322
+ * SeatLayer's page. Supplying a URL therefore cannot authorize it, which is
1323
+ * what stops a copied snippet from redirecting a paid buyer anywhere it
1324
+ * likes.
1325
+ */
1326
+ returnUrl?: string;
1288
1327
  /**
1289
1328
  * Buyer pressed the CTA and the hold succeeded — hand off to YOUR checkout.
1290
1329
  * `hold` and `seats` are the legacy args (unchanged since 0.6). `handoff` (P4)
@@ -3537,6 +3576,17 @@ declare class ChannelsMode {
3537
3576
  private stagedDoneTimer;
3538
3577
  private lastSelectionCount;
3539
3578
  private lastCounts;
3579
+ /** The markup currently in the rail. An identical repaint is skipped, which is
3580
+ * what keeps the organizer's scroll position (and open <select>) alive. */
3581
+ private railHtml;
3582
+ /**
3583
+ * The `assignmentVersion` the allocation map was built from. Walking every
3584
+ * allocation page is the expensive half of a refresh and the server already
3585
+ * tells us, in the channels response, whether ANY seat moved. Unchanged
3586
+ * version, unchanged allocation — so the walk is skipped entirely.
3587
+ */
3588
+ private allocationVersion;
3589
+ private onVisibility;
3540
3590
  constructor(host: ChannelsModeHost, capabilities: ChannelsCapabilities);
3541
3591
  /** Called when the cockpit switches into Channels mode. */
3542
3592
  enter(): void;
@@ -3612,6 +3662,22 @@ declare class ChannelsMode {
3612
3662
  /** Set by the cockpit so a view switch can re-arm canvas selection. */
3613
3663
  onInteractionChange?: () => void;
3614
3664
  private loadPreview;
3665
+ /**
3666
+ * Replace the rail's markup — but only when it actually differs, and never at
3667
+ * the cost of where the organizer had scrolled to.
3668
+ *
3669
+ * The rail repaints on a clock, on every selection change and after every
3670
+ * mutation. Rewriting `innerHTML` each time resets `scrollTop`, which is
3671
+ * exactly what "the rail gets stuck" was: scroll down to Create channel, the
3672
+ * poll ticks, and the list snaps back to the top under the cursor. So skip the
3673
+ * write when the markup is byte-identical, and restore the offset when it is
3674
+ * not.
3675
+ *
3676
+ * Returns whether the DOM was rewritten. Callers must only re-wire listeners
3677
+ * when it was — a skipped paint keeps the old nodes AND their listeners, so
3678
+ * re-wiring would double every handler.
3679
+ */
3680
+ private setRailHtml;
3615
3681
  paintRail(): void;
3616
3682
  private viewSegmentHtml;
3617
3683
  private mapNavigationHtml;
@@ -3620,6 +3686,24 @@ declare class ChannelsMode {
3620
3686
  private listRailHtml;
3621
3687
  private selectionRailHtml;
3622
3688
  private detailRailHtml;
3689
+ /**
3690
+ * "Distribute" — how the seats in this channel actually reach a buyer.
3691
+ *
3692
+ * This replaced a four-value "access intent" picker (none / internal /
3693
+ * hosted_link / server). Two of those values did nothing anywhere: no buyer or
3694
+ * inventory path reads `access_intent`, so `none` and `internal` were labels an
3695
+ * organizer could set and then wait forever for something to happen. A third,
3696
+ * `hosted_link`, is not the organizer's to choose at all — the server sets it
3697
+ * when a buyer link is created and clears it when the last live one is revoked.
3698
+ *
3699
+ * So this is two ACTIONS, not a setting: create a buyer link, or point the
3700
+ * channel at a website integration. Both of them do something the moment they
3701
+ * are pressed. A legacy row still carrying `none` or `internal` renders the
3702
+ * neutral "not distributed yet" state with both actions offered — the stored
3703
+ * value is left alone (it is organizer-declared metadata and the API that
3704
+ * writes it is unchanged), it simply no longer has a control of its own.
3705
+ */
3706
+ private distributeHtml;
3623
3707
  /**
3624
3708
  * Read the status projection for the open channel. Never paints — the caller
3625
3709
  * decides when the rail repaints, so a poll-driven reload does not fight a
@@ -3628,12 +3712,16 @@ declare class ChannelsMode {
3628
3712
  */
3629
3713
  private loadLinks;
3630
3714
  /**
3631
- * The hosted-link section of the detail panel.
3715
+ * The buyer-link status section of the detail panel.
3632
3716
  *
3633
3717
  * STATUS ONLY, by design (comp 06 `hosted`): label, state, expiry,
3634
3718
  * redemptions, seats per buyer, live sessions. There is no Copy control here
3635
3719
  * and no field to hang one on — the URL was shown once at creation and cannot
3636
3720
  * be produced again. Rotation is the recovery path, and it says so.
3721
+ *
3722
+ * Creating a link is the Distribute card's action, not this section's, so a
3723
+ * channel with no links renders nothing here rather than an empty heading and
3724
+ * a second button saying the same thing.
3637
3725
  */
3638
3726
  private hostedLinksHtml;
3639
3727
  private linkCardHtml;
@@ -3667,6 +3755,14 @@ declare class ChannelsMode {
3667
3755
  private showApplied;
3668
3756
  private shakeStaged;
3669
3757
  private renderRenameDialog;
3758
+ /**
3759
+ * "Get embed code" — mark the channel as reached through the organizer's own
3760
+ * backend. The write itself is `setChannelAccessIntent(…, 'server')`, the same
3761
+ * API the old picker called; the difference is that it is now a deliberate
3762
+ * action with a consequence the organizer is told about, rather than one of
3763
+ * four dropdown values with no observable effect.
3764
+ */
3765
+ private chooseWebsiteIntegration;
3670
3766
  private setAccessIntent;
3671
3767
  private togglePause;
3672
3768
  private renderArchiveDialog;
package/dist/index.d.ts CHANGED
@@ -603,6 +603,21 @@ interface SeatingChartOptions {
603
603
  */
604
604
  onSelectedObjectUnavailable?: (event: SelectedObjectUnavailableEvent) => void;
605
605
  onError?: (err: unknown) => void;
606
+ /**
607
+ * What the BUYER sees when the chart cannot load.
608
+ *
609
+ * `'message'` (the default) renders a plain, styleable notice with a Try
610
+ * again button. This used to be silent unconditionally: `render()` returned
611
+ * with an EMPTY mounted div and only `onError` fired, so a host that had not
612
+ * wired `onError` — or had wired it to a logger — showed buyers a blank
613
+ * rectangle where the seat map belongs, on the host's own domain, which
614
+ * reads as a broken website rather than a temporary fault. `SeatPicker` has
615
+ * always failed loud with a retry; this is the embed class catching up.
616
+ *
617
+ * `'none'` restores the silent behaviour for hosts that render their own
618
+ * failure UI from `onError`.
619
+ */
620
+ errorDisplay?: 'message' | 'none';
606
621
  /**
607
622
  * Multi-floor charts only: fires when the buyer taps a deck in the stacked
608
623
  * 3D view, after the picker switches to that floor — lets the host page sync
@@ -624,6 +639,7 @@ declare class SeatingChart {
624
639
  private mount;
625
640
  private hostEl;
626
641
  private rendered;
642
+ private retryBtn;
627
643
  private mode_;
628
644
  private tipEl;
629
645
  private tipPos;
@@ -768,6 +784,13 @@ declare class SeatingChart {
768
784
  * true when a fresh bearer is held; the realtime feed restarts with it.
769
785
  */
770
786
  refreshAccess(): Promise<boolean>;
787
+ /**
788
+ * The visible failure state. Deliberately inline-styled and dependency-free:
789
+ * this renders on a stranger's website, where our stylesheet may not have
790
+ * loaded (the chart fetch just failed) and where inheriting the host's own
791
+ * styles is likelier to produce something unreadable than something on-brand.
792
+ */
793
+ private showLoadFailure;
771
794
  destroy(): void;
772
795
  }
773
796
 
@@ -1274,17 +1297,33 @@ interface SeatPickerOptions {
1274
1297
  * 1. It needs the widget's own transport. A host-supplied `transport` owns its
1275
1298
  * credentials and its backend, so hosted checkout stays off there (with one
1276
1299
  * console warning) rather than reaching past it to api.seatlayer.io.
1277
- * 2. WHERE A HOSTED GATEWAY RETURNS THE BUYER IS THE SERVER'S CHOICE. The
1278
- * checkout session's return URL is built from the deployment's own allowed
1279
- * origins, so a buyer paying by card from an embed on your domain comes back
1280
- * to SeatLayer's buyer page and is confirmed THERE, not in this widget. The
1281
- * widget resumes in place only when it is mounted on a page that actually
1282
- * receives `?order=…&status=success` (a page on an allowed origin, and the
1283
- * in-page gateways, which never navigate away at all). Until the server
1284
- * accepts a caller-supplied return URL, treat a card payment from a
1285
- * third-party embed as "the buyer finishes on our page".
1300
+ * 2. WHERE A HOSTED GATEWAY RETURNS THE BUYER is settled by {@link returnUrl}
1301
+ * and by the organizer. Without one — or from an origin the organizer has
1302
+ * not declared the buyer comes back to SeatLayer's own buyer page and is
1303
+ * confirmed THERE, not in this widget. Declare the embedding site under
1304
+ * Embed domains in the dashboard and pass `returnUrl`, and the buyer
1305
+ * returns to your page instead. In-page gateways never navigate away at
1306
+ * all, so they are unaffected either way.
1286
1307
  */
1287
1308
  checkout?: 'handoff' | 'hosted';
1309
+ /**
1310
+ * Where a redirecting gateway should send the buyer back to, for
1311
+ * `checkout: 'hosted'`.
1312
+ *
1313
+ * The server keeps this URL verbatim — path and query included — and only
1314
+ * stamps `?order=…&status=success|cancelled` onto it, so point it at
1315
+ * whichever of YOUR pages should confirm the purchase (often just
1316
+ * `window.location.href`). Mount a picker on that page and it resumes in
1317
+ * place from those parameters.
1318
+ *
1319
+ * It is validated, not trusted: the organizer declares their embed origins
1320
+ * in the dashboard, and an undeclared origin is ignored rather than
1321
+ * refused — the sale still completes, the buyer just finishes on
1322
+ * SeatLayer's page. Supplying a URL therefore cannot authorize it, which is
1323
+ * what stops a copied snippet from redirecting a paid buyer anywhere it
1324
+ * likes.
1325
+ */
1326
+ returnUrl?: string;
1288
1327
  /**
1289
1328
  * Buyer pressed the CTA and the hold succeeded — hand off to YOUR checkout.
1290
1329
  * `hold` and `seats` are the legacy args (unchanged since 0.6). `handoff` (P4)
@@ -3537,6 +3576,17 @@ declare class ChannelsMode {
3537
3576
  private stagedDoneTimer;
3538
3577
  private lastSelectionCount;
3539
3578
  private lastCounts;
3579
+ /** The markup currently in the rail. An identical repaint is skipped, which is
3580
+ * what keeps the organizer's scroll position (and open <select>) alive. */
3581
+ private railHtml;
3582
+ /**
3583
+ * The `assignmentVersion` the allocation map was built from. Walking every
3584
+ * allocation page is the expensive half of a refresh and the server already
3585
+ * tells us, in the channels response, whether ANY seat moved. Unchanged
3586
+ * version, unchanged allocation — so the walk is skipped entirely.
3587
+ */
3588
+ private allocationVersion;
3589
+ private onVisibility;
3540
3590
  constructor(host: ChannelsModeHost, capabilities: ChannelsCapabilities);
3541
3591
  /** Called when the cockpit switches into Channels mode. */
3542
3592
  enter(): void;
@@ -3612,6 +3662,22 @@ declare class ChannelsMode {
3612
3662
  /** Set by the cockpit so a view switch can re-arm canvas selection. */
3613
3663
  onInteractionChange?: () => void;
3614
3664
  private loadPreview;
3665
+ /**
3666
+ * Replace the rail's markup — but only when it actually differs, and never at
3667
+ * the cost of where the organizer had scrolled to.
3668
+ *
3669
+ * The rail repaints on a clock, on every selection change and after every
3670
+ * mutation. Rewriting `innerHTML` each time resets `scrollTop`, which is
3671
+ * exactly what "the rail gets stuck" was: scroll down to Create channel, the
3672
+ * poll ticks, and the list snaps back to the top under the cursor. So skip the
3673
+ * write when the markup is byte-identical, and restore the offset when it is
3674
+ * not.
3675
+ *
3676
+ * Returns whether the DOM was rewritten. Callers must only re-wire listeners
3677
+ * when it was — a skipped paint keeps the old nodes AND their listeners, so
3678
+ * re-wiring would double every handler.
3679
+ */
3680
+ private setRailHtml;
3615
3681
  paintRail(): void;
3616
3682
  private viewSegmentHtml;
3617
3683
  private mapNavigationHtml;
@@ -3620,6 +3686,24 @@ declare class ChannelsMode {
3620
3686
  private listRailHtml;
3621
3687
  private selectionRailHtml;
3622
3688
  private detailRailHtml;
3689
+ /**
3690
+ * "Distribute" — how the seats in this channel actually reach a buyer.
3691
+ *
3692
+ * This replaced a four-value "access intent" picker (none / internal /
3693
+ * hosted_link / server). Two of those values did nothing anywhere: no buyer or
3694
+ * inventory path reads `access_intent`, so `none` and `internal` were labels an
3695
+ * organizer could set and then wait forever for something to happen. A third,
3696
+ * `hosted_link`, is not the organizer's to choose at all — the server sets it
3697
+ * when a buyer link is created and clears it when the last live one is revoked.
3698
+ *
3699
+ * So this is two ACTIONS, not a setting: create a buyer link, or point the
3700
+ * channel at a website integration. Both of them do something the moment they
3701
+ * are pressed. A legacy row still carrying `none` or `internal` renders the
3702
+ * neutral "not distributed yet" state with both actions offered — the stored
3703
+ * value is left alone (it is organizer-declared metadata and the API that
3704
+ * writes it is unchanged), it simply no longer has a control of its own.
3705
+ */
3706
+ private distributeHtml;
3623
3707
  /**
3624
3708
  * Read the status projection for the open channel. Never paints — the caller
3625
3709
  * decides when the rail repaints, so a poll-driven reload does not fight a
@@ -3628,12 +3712,16 @@ declare class ChannelsMode {
3628
3712
  */
3629
3713
  private loadLinks;
3630
3714
  /**
3631
- * The hosted-link section of the detail panel.
3715
+ * The buyer-link status section of the detail panel.
3632
3716
  *
3633
3717
  * STATUS ONLY, by design (comp 06 `hosted`): label, state, expiry,
3634
3718
  * redemptions, seats per buyer, live sessions. There is no Copy control here
3635
3719
  * and no field to hang one on — the URL was shown once at creation and cannot
3636
3720
  * be produced again. Rotation is the recovery path, and it says so.
3721
+ *
3722
+ * Creating a link is the Distribute card's action, not this section's, so a
3723
+ * channel with no links renders nothing here rather than an empty heading and
3724
+ * a second button saying the same thing.
3637
3725
  */
3638
3726
  private hostedLinksHtml;
3639
3727
  private linkCardHtml;
@@ -3667,6 +3755,14 @@ declare class ChannelsMode {
3667
3755
  private showApplied;
3668
3756
  private shakeStaged;
3669
3757
  private renderRenameDialog;
3758
+ /**
3759
+ * "Get embed code" — mark the channel as reached through the organizer's own
3760
+ * backend. The write itself is `setChannelAccessIntent(…, 'server')`, the same
3761
+ * API the old picker called; the difference is that it is now a deliberate
3762
+ * action with a consequence the organizer is told about, rather than one of
3763
+ * four dropdown values with no observable effect.
3764
+ */
3765
+ private chooseWebsiteIntegration;
3670
3766
  private setAccessIntent;
3671
3767
  private togglePause;
3672
3768
  private renderArchiveDialog;