@seatlayer/js 0.67.15 → 0.68.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/README.md CHANGED
@@ -68,6 +68,7 @@ import { SeatingChart } from '@seatlayer/js';
68
68
  const chart = new SeatingChart({
69
69
  container: '#chart',
70
70
  event: 'ev_9f3a',
71
+ publicKey: 'pk_test_…',
71
72
  onHold: ({ holdId }) => bookOnYourServer(holdId),
72
73
  });
73
74
 
@@ -77,6 +78,15 @@ const hold = await chart.hold(); // null on a 409 conflict
77
78
  chart.destroy();
78
79
  ```
79
80
 
81
+ For an ordinary Public sale on a Platform/SDK event, `publicKey` starts one
82
+ direct bootstrap after SeatLayer validates the key, event mode, and browser's
83
+ exact registered origin. The SDK keeps the returned Public-only bearer in
84
+ memory, and the bootstrap carries the chart plus compact inventory status
85
+ together. Login, presale, partner, and channel inventory instead use
86
+ `buyerAccessTokenProvider` or `buyerAccessToken` from your authenticated
87
+ backend; either explicit credential takes precedence over `publicKey`. Managed
88
+ public/unlisted events retain anonymous event-key access and omit `publicKey`.
89
+
80
90
  ## Fixed Renewable Season (private-beta candidate)
81
91
 
82
92
  The Season source is merged for development, but it is not included in the
@@ -223,13 +233,28 @@ callers must use an event-scoped `mse_` grant.
223
233
 
224
234
  ## Embed the chart Designer
225
235
 
226
- For organizer-facing venue design, use `EmbeddedDesigner`. Your backend mints the
227
- short-lived `designerUrl`; the browser receives no SeatLayer secret key. The wrapper
228
- creates the iframe, recreates it for a new session URL, and validates every
229
- `postMessage` by iframe source and exact Designer origin.
236
+ For organizer-facing venue design, use `EmbeddedDesigner`. Your backend
237
+ authenticates and authorizes the organizer, then requests a short-lived session
238
+ from SeatLayer with `sk_…`; SeatLayer mints the `dse_…` token and returns
239
+ `designerUrl`. Never expose the secret or call SeatLayer's Designer-session
240
+ endpoint from browser code. The wrapper creates the iframe, recreates it for a
241
+ new session URL, and validates every `postMessage` by iframe source and exact
242
+ Designer origin.
243
+
244
+ Start that required backend request on authenticated route intent or page load,
245
+ not on the final **Open Designer** click. Keep the response no-store and the
246
+ session in memory, and race its promise with the SDK import and editor shell.
247
+ An authenticated server-rendered page may instead include `designerUrl` in a
248
+ no-store bootstrap. The iframe still waits for the session; the win comes from
249
+ overlapping the trusted request with SDK and shell loading.
230
250
 
231
251
  ```js
232
- import { EmbeddedDesigner } from '@seatlayer/js';
252
+ const sdkPromise = import('@seatlayer/js');
253
+ const sessionPromise = requestDesignerSession(); // authenticated + no-store
254
+ const [{ EmbeddedDesigner }, session] = await Promise.all([
255
+ sdkPromise,
256
+ sessionPromise,
257
+ ]);
233
258
 
234
259
  const designer = new EmbeddedDesigner({
235
260
  container: '#venue-designer',
@@ -239,9 +264,9 @@ const designer = new EmbeddedDesigner({
239
264
  onPublished: ({ chartId }) => refreshVenue(chartId),
240
265
  onClose: () => closeVenueEditor(),
241
266
  onError: ({ code, message }) => showError(code ?? message),
242
- // Mint a fresh session when the user retries an expired/failed editor:
267
+ // Request a fresh session through your backend on retry/expiry:
243
268
  onRequestRelaunch: async () => {
244
- const next = await mintDesignerSession(session.chartId);
269
+ const next = await requestDesignerSession(session.chartId);
245
270
  designer.setDesignerUrl(next.designerUrl);
246
271
  },
247
272
  });
@@ -280,7 +305,7 @@ CSS files or external assets.
280
305
  | --- | --- | --- | --- |
281
306
  | `showLoadingState` | `boolean` | `true` | Render the built-in skeleton and error card. Set `false` when you draw your own chrome. |
282
307
  | `loadingTimeoutMs` | `number` | `20000` | If `ready` never arrives within this window, show the error card with a timeout message. |
283
- | `onRequestRelaunch` | `() => void` | — | Called by **"Try again"** _and_ by automatic renewal (below). Mint a fresh session and call `setDesignerUrl()`; the iframe recreates and returns to loading. When omitted, "Try again" reloads the current URL in place. |
308
+ | `onRequestRelaunch` | `() => void` | — | Called by **"Try again"** _and_ by automatic renewal (below). Request a fresh session through your backend and call `setDesignerUrl()`; the iframe recreates and returns to loading. When omitted, "Try again" reloads the current URL in place. |
284
309
  | `autoRenewSession` | `boolean` | `true`¹ | Silently renew the session before it expires and auto-recover once if an expiry error slips through. ¹Defaults `true` only when `onRequestRelaunch` is provided; a no-op without it. Set `false` for fully manual "Try again". |
285
310
 
286
311
  `setDesignerUrl()` always returns the host to the loading state, so a relaunch
@@ -288,20 +313,21 @@ flow needs no extra bookkeeping.
288
313
 
289
314
  ### Session lifecycle
290
315
 
291
- Designer sessions are **short-lived by design**: your backend mints a `dse_`
292
- token (default 1 hour, up to 4 hours via `expiresInSeconds`) and bakes it into
293
- `designerUrl`. Pick a TTL that fits how long organizers actually edit — longer is
294
- not automatically better; the renewal below keeps even a multi-hour session alive.
316
+ Designer sessions are **short-lived by design**: your backend authorizes and
317
+ requests one, then SeatLayer mints a `dse_` token (default 1 hour, up to 4 hours
318
+ via `expiresInSeconds`) into `designerUrl`. Pick a TTL that fits how long
319
+ organizers actually edit — longer is not automatically better; the renewal
320
+ below keeps even a multi-hour session alive.
295
321
 
296
- Provide `onRequestRelaunch` returning (or awaiting) a freshly minted session, and
297
- the SDK turns expiry into a non-event:
322
+ Provide `onRequestRelaunch` returning (or awaiting) a freshly requested session,
323
+ and the SDK turns expiry into a non-event:
298
324
 
299
325
  - **Silent proactive renewal.** From each `ready` message's `expiresAt` the SDK
300
326
  schedules an automatic relaunch shortly before the session lapses — ~3 minutes
301
327
  ahead, or, for a TTL under 15 minutes, after 80% of the remaining life (never
302
- sooner than 30s after `ready`). Your `onRequestRelaunch` mints a fresh session
303
- and swaps `designerUrl`, so editing continues with no expiry card. The timer
304
- re-arms from every `ready`.
328
+ sooner than 30s after `ready`). Your `onRequestRelaunch` requests a fresh
329
+ session through your backend and swaps `designerUrl`, so editing continues
330
+ with no expiry card. The timer re-arms from every `ready`.
305
331
  - **Automatic expiry recovery.** If an expiry error still arrives (a laptop that
306
332
  slept past the renewal window, say), the SDK makes **one** automatic relaunch
307
333
  attempt before showing the "Try again" card, and only falls back to the card if
@@ -315,9 +341,9 @@ const designer = new EmbeddedDesigner({
315
341
  container: '#venue-designer',
316
342
  designerUrl: session.designerUrl,
317
343
  expectedChartId: session.chartId,
318
- // Mint a fresh session on renewal, expiry recovery, or "Try again":
344
+ // Request a fresh session on renewal, expiry recovery, or "Try again":
319
345
  onRequestRelaunch: async () => {
320
- const next = await mintDesignerSession(session.chartId); // your backend, up to 4h TTL
346
+ const next = await requestDesignerSession(session.chartId); // your backend, up to 4h TTL
321
347
  designer.setDesignerUrl(next.designerUrl); // recreates the iframe
322
348
  },
323
349
  // autoRenewSession defaults to true because onRequestRelaunch is present.
@@ -328,7 +354,8 @@ designer.mount();
328
354
  ## API
329
355
 
330
356
  `new SeatingChart(options)` — options: `container` (selector or element, required),
331
- `event` (key, required), `apiBase?`, `maxSelection?` (default 10),
357
+ `event` (key, required), `apiBase?`, `publicKey?`,
358
+ `buyerAccessTokenProvider?`, `buyerAccessToken?`, `maxSelection?` (default 10),
332
359
  `selectedObjects?`, `selectableObjects?`, `numberOfPlacesToSelect?`,
333
360
  `selectionValidators?`,
334
361
  `onSelectionChange?`, `onSelectionValidityChange?`, `onHold?`,