@seatlayer/js 0.40.0 → 0.41.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.cjs +37 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +48 -9
- package/dist/index.d.ts +48 -9
- package/dist/index.js +37 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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
|
|
1278
|
-
*
|
|
1279
|
-
*
|
|
1280
|
-
*
|
|
1281
|
-
*
|
|
1282
|
-
*
|
|
1283
|
-
*
|
|
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)
|
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
|
|
1278
|
-
*
|
|
1279
|
-
*
|
|
1280
|
-
*
|
|
1281
|
-
*
|
|
1282
|
-
*
|
|
1283
|
-
*
|
|
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)
|
package/dist/index.js
CHANGED
|
@@ -906,6 +906,7 @@ var SeatingChart = class {
|
|
|
906
906
|
this.mount = null;
|
|
907
907
|
this.hostEl = null;
|
|
908
908
|
this.rendered = false;
|
|
909
|
+
this.retryBtn = null;
|
|
909
910
|
this.mode_ = null;
|
|
910
911
|
this.tipEl = null;
|
|
911
912
|
this.tipPos = { x: 0, y: 0 };
|
|
@@ -967,6 +968,7 @@ var SeatingChart = class {
|
|
|
967
968
|
const info = await this.controller.render(host);
|
|
968
969
|
if (!info) {
|
|
969
970
|
this.rendered = false;
|
|
971
|
+
if (this.opts.errorDisplay !== "none") this.showLoadFailure(host);
|
|
970
972
|
return this;
|
|
971
973
|
}
|
|
972
974
|
this.controller.setViewMode(this.opts.initialView ?? "flat");
|
|
@@ -1257,10 +1259,36 @@ var SeatingChart = class {
|
|
|
1257
1259
|
}
|
|
1258
1260
|
return ok;
|
|
1259
1261
|
}
|
|
1262
|
+
/**
|
|
1263
|
+
* The visible failure state. Deliberately inline-styled and dependency-free:
|
|
1264
|
+
* this renders on a stranger's website, where our stylesheet may not have
|
|
1265
|
+
* loaded (the chart fetch just failed) and where inheriting the host's own
|
|
1266
|
+
* styles is likelier to produce something unreadable than something on-brand.
|
|
1267
|
+
*/
|
|
1268
|
+
showLoadFailure(host) {
|
|
1269
|
+
const box = document.createElement("div");
|
|
1270
|
+
box.setAttribute("role", "status");
|
|
1271
|
+
box.style.cssText = 'display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;width:100%;height:100%;min-height:180px;box-sizing:border-box;padding:24px;text-align:center;font:500 14px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:#3b4256;';
|
|
1272
|
+
const text = document.createElement("div");
|
|
1273
|
+
text.textContent = "The seat map didn\u2019t load.";
|
|
1274
|
+
box.appendChild(text);
|
|
1275
|
+
const btn = document.createElement("button");
|
|
1276
|
+
btn.type = "button";
|
|
1277
|
+
btn.textContent = "Try again";
|
|
1278
|
+
btn.style.cssText = "appearance:none;border:1px solid #c9cede;background:#fff;color:#10162a;border-radius:8px;padding:8px 16px;font:600 13px/1 inherit;cursor:pointer;";
|
|
1279
|
+
btn.addEventListener("click", () => {
|
|
1280
|
+
this.destroy();
|
|
1281
|
+
void this.render().catch((err) => this.opts.onError?.(err));
|
|
1282
|
+
});
|
|
1283
|
+
box.appendChild(btn);
|
|
1284
|
+
this.retryBtn = btn;
|
|
1285
|
+
host.appendChild(box);
|
|
1286
|
+
}
|
|
1260
1287
|
destroy() {
|
|
1261
1288
|
this.realtime?.stop();
|
|
1262
1289
|
this.realtime = null;
|
|
1263
1290
|
this.access?.clear();
|
|
1291
|
+
this.retryBtn = null;
|
|
1264
1292
|
if (this.hostEl && this.onTipMove) this.hostEl.removeEventListener("mousemove", this.onTipMove);
|
|
1265
1293
|
this.tipEl = null;
|
|
1266
1294
|
this.onTipMove = null;
|
|
@@ -5447,7 +5475,15 @@ var SeatPicker = class _SeatPicker {
|
|
|
5447
5475
|
this.checkoutPanel = mountCheckout({
|
|
5448
5476
|
root: this.root,
|
|
5449
5477
|
state,
|
|
5450
|
-
|
|
5478
|
+
// `returnUrl` rides along so a redirecting gateway can come back to the
|
|
5479
|
+
// HOST's page. The server validates its origin against the organizer's
|
|
5480
|
+
// declared embed domains and silently falls back to our own buyer page
|
|
5481
|
+
// when it does not match, so passing one can never redirect a paid buyer
|
|
5482
|
+
// somewhere the organizer did not sanction.
|
|
5483
|
+
startSession: (input) => this.pubApi.startCheckout(this.opts.event, {
|
|
5484
|
+
...input,
|
|
5485
|
+
...this.opts.returnUrl ? { returnUrl: this.opts.returnUrl } : {}
|
|
5486
|
+
}),
|
|
5451
5487
|
orderStatus: (orderId) => this.pubApi.orderStatus(orderId),
|
|
5452
5488
|
onCancel: () => {
|
|
5453
5489
|
this.checkoutPanel = null;
|