@seatlayer/js 0.25.0 → 0.27.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
@@ -18,7 +18,7 @@ interface HoldConflict {
18
18
  interface HoldLineItem {
19
19
  label: string;
20
20
  objectId: string;
21
- objectType: 'seat' | 'booth' | 'ga';
21
+ objectType: 'seat' | 'booth' | 'ga' | 'table';
22
22
  categoryKey: string;
23
23
  tierId: string | null;
24
24
  /** Price in major currency units (for example 45 means $45.00). */
@@ -151,6 +151,7 @@ declare class SeatingChart {
151
151
  private mount;
152
152
  private hostEl;
153
153
  private rendered;
154
+ private mode_;
154
155
  private tipEl;
155
156
  private tipPos;
156
157
  private onTipMove;
@@ -168,14 +169,47 @@ declare class SeatingChart {
168
169
  private buildBadge;
169
170
  private placeTooltip;
170
171
  private updateTooltip;
172
+ /**
173
+ * Whether the SERVED event is a live or a test event (`sk_test_` keys create
174
+ * test events, which never book real inventory). `null` before render()
175
+ * resolves — the mode comes from the server with the chart, not from options.
176
+ *
177
+ * The widget already surfaces this visually with the test-mode ribbon; this
178
+ * getter is for hosts that draw their own chrome — notably a native WebView
179
+ * wrapper, which must be able to tell an integrator that the build they are
180
+ * about to ship is pointed at a test event.
181
+ */
182
+ getMode(): 'live' | 'test' | null;
171
183
  /** Current selection with prices resolved from the chart categories. */
172
184
  getSelection(): SelectedSeat[];
173
185
  /** Hold the current selection. Resolves the hold, or null on a 409 conflict. */
174
186
  hold(options?: {
175
187
  ttlMs?: number;
176
188
  }): Promise<HoldResult | null>;
189
+ /**
190
+ * @internal Like {@link hold} but RE-THROWS the structured API error (409
191
+ * `reason`/`code` + `conflicts`) instead of swallowing it into `onError` +
192
+ * `null`. The native WebView host adapter needs the throw so it can answer the
193
+ * originating command with a correlated error carrying the SPECIFIC reason
194
+ * (`sold_out` vs `not_enough_together`); the public method above keeps the
195
+ * catch-and-onError contract that direct web consumers rely on. Not a stable
196
+ * part of the embed API.
197
+ */
198
+ holdOrThrow(options?: {
199
+ ttlMs?: number;
200
+ }): Promise<HoldResult | null>;
177
201
  /** Restore an active hold by its opaque id without extending its expiry. */
178
202
  resumeHold(holdId: string): Promise<HoldResult | null>;
203
+ /** @internal Throwing variant of {@link resumeHold} for the native host adapter. See {@link holdOrThrow}. */
204
+ resumeHoldOrThrow(holdId: string): Promise<HoldResult | null>;
205
+ /**
206
+ * Push the OPEN hold's expiry out ("need more time?"). Resolves the refreshed
207
+ * hold, or `null` when there is nothing held or the server refused (the hold
208
+ * is gone, already expired, or at its renewal cap) — refusal is a normal
209
+ * outcome, not an error, so the host decides the copy. The client-side expiry
210
+ * timer is re-armed to match, so `onHoldExpired` won't fire early.
211
+ */
212
+ extendHold(ttlMs?: number): Promise<HoldResult | null>;
179
213
  /** Current active hold known to this chart, if any. */
180
214
  getCurrentHold(): HoldResult | null;
181
215
  getGAAreas(): GAAreaAvailability[];
@@ -183,8 +217,15 @@ declare class SeatingChart {
183
217
  tierId?: string | null;
184
218
  ttlMs?: number;
185
219
  }): Promise<HoldResult | null>;
220
+ /** @internal Throwing variant of {@link holdGA} for the native host adapter. See {@link holdOrThrow}. */
221
+ holdGAOrThrow(areaId: string, qty: number, options?: {
222
+ tierId?: string | null;
223
+ ttlMs?: number;
224
+ }): Promise<HoldResult | null>;
186
225
  /** Ask the server for the `qty` best free seats and hold them atomically. */
187
226
  bestAvailable(qty: number, categoryKey?: string): Promise<BestAvailableResult | null>;
227
+ /** @internal Throwing variant of {@link bestAvailable} for the native host adapter. See {@link holdOrThrow}. */
228
+ bestAvailableOrThrow(qty: number, categoryKey?: string): Promise<BestAvailableResult | null>;
188
229
  /**
189
230
  * Choose a ticket tier for a selected seat (e.g. Adult → Child). The seat's
190
231
  * available `tiers` are on each `SelectedSeat` from `getSelection()` /
@@ -488,11 +529,11 @@ declare class EmbeddedDesigner {
488
529
  * per-line tier + price) and never changes shape across minor releases.
489
530
  */
490
531
  interface CheckoutLineItem {
491
- /** Seat label (or GA synthetic-unit label). */
532
+ /** Seat, table-group, or GA synthetic-unit label. */
492
533
  label: string;
493
534
  /** Chart object id (row/booth/GA area) the unit belongs to. */
494
535
  objectId: string;
495
- objectType: 'seat' | 'booth' | 'ga';
536
+ objectType: 'seat' | 'booth' | 'ga' | 'table';
496
537
  categoryKey: string;
497
538
  /** Chosen ticket tier id (Adult/Child/…), or null when the category has no tiers. */
498
539
  tierId: string | null;
package/dist/index.d.ts CHANGED
@@ -18,7 +18,7 @@ interface HoldConflict {
18
18
  interface HoldLineItem {
19
19
  label: string;
20
20
  objectId: string;
21
- objectType: 'seat' | 'booth' | 'ga';
21
+ objectType: 'seat' | 'booth' | 'ga' | 'table';
22
22
  categoryKey: string;
23
23
  tierId: string | null;
24
24
  /** Price in major currency units (for example 45 means $45.00). */
@@ -151,6 +151,7 @@ declare class SeatingChart {
151
151
  private mount;
152
152
  private hostEl;
153
153
  private rendered;
154
+ private mode_;
154
155
  private tipEl;
155
156
  private tipPos;
156
157
  private onTipMove;
@@ -168,14 +169,47 @@ declare class SeatingChart {
168
169
  private buildBadge;
169
170
  private placeTooltip;
170
171
  private updateTooltip;
172
+ /**
173
+ * Whether the SERVED event is a live or a test event (`sk_test_` keys create
174
+ * test events, which never book real inventory). `null` before render()
175
+ * resolves — the mode comes from the server with the chart, not from options.
176
+ *
177
+ * The widget already surfaces this visually with the test-mode ribbon; this
178
+ * getter is for hosts that draw their own chrome — notably a native WebView
179
+ * wrapper, which must be able to tell an integrator that the build they are
180
+ * about to ship is pointed at a test event.
181
+ */
182
+ getMode(): 'live' | 'test' | null;
171
183
  /** Current selection with prices resolved from the chart categories. */
172
184
  getSelection(): SelectedSeat[];
173
185
  /** Hold the current selection. Resolves the hold, or null on a 409 conflict. */
174
186
  hold(options?: {
175
187
  ttlMs?: number;
176
188
  }): Promise<HoldResult | null>;
189
+ /**
190
+ * @internal Like {@link hold} but RE-THROWS the structured API error (409
191
+ * `reason`/`code` + `conflicts`) instead of swallowing it into `onError` +
192
+ * `null`. The native WebView host adapter needs the throw so it can answer the
193
+ * originating command with a correlated error carrying the SPECIFIC reason
194
+ * (`sold_out` vs `not_enough_together`); the public method above keeps the
195
+ * catch-and-onError contract that direct web consumers rely on. Not a stable
196
+ * part of the embed API.
197
+ */
198
+ holdOrThrow(options?: {
199
+ ttlMs?: number;
200
+ }): Promise<HoldResult | null>;
177
201
  /** Restore an active hold by its opaque id without extending its expiry. */
178
202
  resumeHold(holdId: string): Promise<HoldResult | null>;
203
+ /** @internal Throwing variant of {@link resumeHold} for the native host adapter. See {@link holdOrThrow}. */
204
+ resumeHoldOrThrow(holdId: string): Promise<HoldResult | null>;
205
+ /**
206
+ * Push the OPEN hold's expiry out ("need more time?"). Resolves the refreshed
207
+ * hold, or `null` when there is nothing held or the server refused (the hold
208
+ * is gone, already expired, or at its renewal cap) — refusal is a normal
209
+ * outcome, not an error, so the host decides the copy. The client-side expiry
210
+ * timer is re-armed to match, so `onHoldExpired` won't fire early.
211
+ */
212
+ extendHold(ttlMs?: number): Promise<HoldResult | null>;
179
213
  /** Current active hold known to this chart, if any. */
180
214
  getCurrentHold(): HoldResult | null;
181
215
  getGAAreas(): GAAreaAvailability[];
@@ -183,8 +217,15 @@ declare class SeatingChart {
183
217
  tierId?: string | null;
184
218
  ttlMs?: number;
185
219
  }): Promise<HoldResult | null>;
220
+ /** @internal Throwing variant of {@link holdGA} for the native host adapter. See {@link holdOrThrow}. */
221
+ holdGAOrThrow(areaId: string, qty: number, options?: {
222
+ tierId?: string | null;
223
+ ttlMs?: number;
224
+ }): Promise<HoldResult | null>;
186
225
  /** Ask the server for the `qty` best free seats and hold them atomically. */
187
226
  bestAvailable(qty: number, categoryKey?: string): Promise<BestAvailableResult | null>;
227
+ /** @internal Throwing variant of {@link bestAvailable} for the native host adapter. See {@link holdOrThrow}. */
228
+ bestAvailableOrThrow(qty: number, categoryKey?: string): Promise<BestAvailableResult | null>;
188
229
  /**
189
230
  * Choose a ticket tier for a selected seat (e.g. Adult → Child). The seat's
190
231
  * available `tiers` are on each `SelectedSeat` from `getSelection()` /
@@ -488,11 +529,11 @@ declare class EmbeddedDesigner {
488
529
  * per-line tier + price) and never changes shape across minor releases.
489
530
  */
490
531
  interface CheckoutLineItem {
491
- /** Seat label (or GA synthetic-unit label). */
532
+ /** Seat, table-group, or GA synthetic-unit label. */
492
533
  label: string;
493
534
  /** Chart object id (row/booth/GA area) the unit belongs to. */
494
535
  objectId: string;
495
- objectType: 'seat' | 'booth' | 'ga';
536
+ objectType: 'seat' | 'booth' | 'ga' | 'table';
496
537
  categoryKey: string;
497
538
  /** Chosen ticket tier id (Adult/Child/…), or null when the category has no tiers. */
498
539
  tierId: string | null;
package/dist/index.js CHANGED
@@ -25,7 +25,13 @@ async function request(base, path, init = {}) {
25
25
  const data = isJson ? await res.json().catch(() => null) : null;
26
26
  if (!res.ok) {
27
27
  const err = data;
28
- throw new ApiError(res.status, err?.error ?? `request_failed_${res.status}`, err?.code, err?.conflicts, err?.reason);
28
+ throw new ApiError(
29
+ res.status,
30
+ err?.error ?? `request_failed_${res.status}`,
31
+ err?.code ?? err?.error,
32
+ err?.conflicts,
33
+ err?.reason
34
+ );
29
35
  }
30
36
  return data;
31
37
  }
@@ -98,6 +104,7 @@ var SeatingChart = class {
98
104
  this.mount = null;
99
105
  this.hostEl = null;
100
106
  this.rendered = false;
107
+ this.mode_ = null;
101
108
  this.tipEl = null;
102
109
  this.tipPos = { x: 0, y: 0 };
103
110
  this.onTipMove = null;
@@ -151,6 +158,7 @@ var SeatingChart = class {
151
158
  this.rendered = false;
152
159
  return this;
153
160
  }
161
+ this.mode_ = info.mode === "test" ? "test" : "live";
154
162
  if (this.opts.seatTooltip !== false) {
155
163
  const tip = document.createElement("div");
156
164
  tip.setAttribute("role", "tooltip");
@@ -224,6 +232,19 @@ var SeatingChart = class {
224
232
  this.tipEl.style.display = "block";
225
233
  this.placeTooltip();
226
234
  }
235
+ /**
236
+ * Whether the SERVED event is a live or a test event (`sk_test_` keys create
237
+ * test events, which never book real inventory). `null` before render()
238
+ * resolves — the mode comes from the server with the chart, not from options.
239
+ *
240
+ * The widget already surfaces this visually with the test-mode ribbon; this
241
+ * getter is for hosts that draw their own chrome — notably a native WebView
242
+ * wrapper, which must be able to tell an integrator that the build they are
243
+ * about to ship is pointed at a test event.
244
+ */
245
+ getMode() {
246
+ return this.mode_;
247
+ }
227
248
  /** Current selection with prices resolved from the chart categories. */
228
249
  getSelection() {
229
250
  return this.controller.getSelection();
@@ -231,17 +252,49 @@ var SeatingChart = class {
231
252
  /** Hold the current selection. Resolves the hold, or null on a 409 conflict. */
232
253
  async hold(options = {}) {
233
254
  try {
234
- const h = await this.controller.hold(void 0, options.ttlMs);
235
- return h ? { holdId: h.holdId, expiresAt: h.expiresAt, seats: h.seats, items: h.items } : null;
255
+ return await this.holdOrThrow(options);
236
256
  } catch (err) {
237
257
  this.opts.onError?.(err);
238
258
  return null;
239
259
  }
240
260
  }
261
+ /**
262
+ * @internal Like {@link hold} but RE-THROWS the structured API error (409
263
+ * `reason`/`code` + `conflicts`) instead of swallowing it into `onError` +
264
+ * `null`. The native WebView host adapter needs the throw so it can answer the
265
+ * originating command with a correlated error carrying the SPECIFIC reason
266
+ * (`sold_out` vs `not_enough_together`); the public method above keeps the
267
+ * catch-and-onError contract that direct web consumers rely on. Not a stable
268
+ * part of the embed API.
269
+ */
270
+ async holdOrThrow(options = {}) {
271
+ const h = await this.controller.hold(void 0, options.ttlMs);
272
+ return h ? { holdId: h.holdId, expiresAt: h.expiresAt, seats: h.seats, items: h.items } : null;
273
+ }
241
274
  /** Restore an active hold by its opaque id without extending its expiry. */
242
275
  async resumeHold(holdId) {
243
276
  try {
244
- const h = await this.controller.resumeHold(holdId);
277
+ return await this.resumeHoldOrThrow(holdId);
278
+ } catch (err) {
279
+ this.opts.onError?.(err);
280
+ return null;
281
+ }
282
+ }
283
+ /** @internal Throwing variant of {@link resumeHold} for the native host adapter. See {@link holdOrThrow}. */
284
+ async resumeHoldOrThrow(holdId) {
285
+ const h = await this.controller.resumeHold(holdId);
286
+ return h ? { holdId: h.holdId, expiresAt: h.expiresAt, seats: h.seats, items: h.items } : null;
287
+ }
288
+ /**
289
+ * Push the OPEN hold's expiry out ("need more time?"). Resolves the refreshed
290
+ * hold, or `null` when there is nothing held or the server refused (the hold
291
+ * is gone, already expired, or at its renewal cap) — refusal is a normal
292
+ * outcome, not an error, so the host decides the copy. The client-side expiry
293
+ * timer is re-armed to match, so `onHoldExpired` won't fire early.
294
+ */
295
+ async extendHold(ttlMs) {
296
+ try {
297
+ const h = await this.controller.extendHold(ttlMs);
245
298
  return h ? { holdId: h.holdId, expiresAt: h.expiresAt, seats: h.seats, items: h.items } : null;
246
299
  } catch (err) {
247
300
  this.opts.onError?.(err);
@@ -258,23 +311,31 @@ var SeatingChart = class {
258
311
  }
259
312
  async holdGA(areaId, qty, options = {}) {
260
313
  try {
261
- const h = await this.controller.holdGA(areaId, qty, options);
262
- return h ? { holdId: h.holdId, expiresAt: h.expiresAt, seats: h.seats, items: h.items } : null;
314
+ return await this.holdGAOrThrow(areaId, qty, options);
263
315
  } catch (err) {
264
316
  this.opts.onError?.(err);
265
317
  return null;
266
318
  }
267
319
  }
320
+ /** @internal Throwing variant of {@link holdGA} for the native host adapter. See {@link holdOrThrow}. */
321
+ async holdGAOrThrow(areaId, qty, options = {}) {
322
+ const h = await this.controller.holdGA(areaId, qty, options);
323
+ return h ? { holdId: h.holdId, expiresAt: h.expiresAt, seats: h.seats, items: h.items } : null;
324
+ }
268
325
  /** Ask the server for the `qty` best free seats and hold them atomically. */
269
326
  async bestAvailable(qty, categoryKey) {
270
327
  try {
271
- const h = await this.controller.bestAvailable(qty, categoryKey);
272
- return h ? { holdId: h.holdId, expiresAt: h.expiresAt, labels: h.labels, seats: h.seats, items: h.items } : null;
328
+ return await this.bestAvailableOrThrow(qty, categoryKey);
273
329
  } catch (err) {
274
330
  this.opts.onError?.(err);
275
331
  return null;
276
332
  }
277
333
  }
334
+ /** @internal Throwing variant of {@link bestAvailable} for the native host adapter. See {@link holdOrThrow}. */
335
+ async bestAvailableOrThrow(qty, categoryKey) {
336
+ const h = await this.controller.bestAvailable(qty, categoryKey);
337
+ return h ? { holdId: h.holdId, expiresAt: h.expiresAt, labels: h.labels, seats: h.seats, items: h.items } : null;
338
+ }
278
339
  /**
279
340
  * Choose a ticket tier for a selected seat (e.g. Adult → Child). The seat's
280
341
  * available `tiers` are on each `SelectedSeat` from `getSelection()` /
@@ -335,6 +396,7 @@ var SeatingChart = class {
335
396
  this.hostEl = null;
336
397
  this.mount = null;
337
398
  this.rendered = false;
399
+ this.mode_ = null;
338
400
  }
339
401
  };
340
402