@touchcastllc/napster-companion-api-dev 1.0.0-alpha.86 → 1.5.0-alpha.1

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.
@@ -22,6 +22,17 @@ export declare const PERSIST_NAVIGATE_EVENT = "napster:persist:navigate";
22
22
  * off it, so the marker is defined in exactly one place.
23
23
  */
24
24
  export declare const SITE_FRAME_CLASS = "np_site-frame";
25
+ /**
26
+ * Browsing-context name of the site frame. Form submissions are routed into the frame by
27
+ * pointing `form.target` here, letting the BROWSER perform the submit (works for POST,
28
+ * which no URL-based re-navigation could replay).
29
+ */
30
+ export declare const SITE_FRAME_NAME = "np_site_frame";
31
+ /**
32
+ * Class of the navigation progress bar shown while a wrapped page loads. Styled in
33
+ * `Persistence.css`; exists because browser chrome ignores an in-iframe navigation.
34
+ */
35
+ export declare const SITE_PROGRESS_CLASS = "np_site-progress";
25
36
  /**
26
37
  * True when the current window is running INSIDE our own persistence site frame (the
27
38
  * `.np_site-frame` iframe) rather than the top document or a third-party embed. Both entry
@@ -292,6 +292,18 @@ export interface avatarStyleConfig {
292
292
  * Allows both string and number values for CSS properties.
293
293
  */
294
294
  export type StyleObject = Partial<CSSStyleDeclaration>;
295
+ /**
296
+ * Styling for the navigation progress bar — see
297
+ * {@link PersistenceOptions.navigationProgress}. Both map onto CSS custom properties,
298
+ * so a stylesheet can override them instead
299
+ * (`--np-persist-progress-color` / `--np-persist-progress-height`).
300
+ */
301
+ export interface NavigationProgressOptions {
302
+ /** Any CSS colour. Default: `"#be369d"`. */
303
+ color?: string;
304
+ /** Any CSS length. Default: `"3px"`. */
305
+ height?: string;
306
+ }
295
307
  /**
296
308
  * Cross-page persistence options. Works with BOTH entry points — `init` and
297
309
  * `initWithButton` share the same persistence engine.
@@ -302,30 +314,93 @@ export interface PersistenceOptions {
302
314
  /**
303
315
  * Defer the iframe wrap until the user first navigates. The landing page stays
304
316
  * fully native — no iframe — and the wrap happens on the first allowed link click.
305
- * Default: `false` (eager wrap on connect). Off by default because on-navigate only
306
- * catches anchor clicks: a programmatic redirect on the landing page would fall
307
- * through and end the session.
317
+ * **Default: `false`** (eager wrap on connect).
318
+ *
319
+ * Eager costs one reload of the current page up front, but is unconditional: once
320
+ * wrapped, EVERY navigation happens inside the frame. Deferring avoids that reload for
321
+ * the many sessions that never leave the landing page, but it has to intercept the
322
+ * navigation to work, and interception can be defeated — by a programmatic redirect
323
+ * (`location.href = …`), or by a site handler calling `stopPropagation()` on the click.
324
+ * Either one ends the session. Sites that navigate from JS should dispatch
325
+ * {@link PERSIST_NAVIGATE_EVENT}, which the engine routes through the wrap.
308
326
  */
309
327
  iframeOnNavigate?: boolean;
310
328
  /**
311
- * URLs/domains excluded from persistence: instead of loading inside the iframe they
312
- * open as a normal top-level navigation (which ends the session). Use for pages that
313
- * can't be framed (auth / SSO) or shouldn't be (checkout, signout). Cross-origin
314
- * links always open top-level by default, so this only matters for same-origin.
329
+ * Pages of YOUR OWN site that must not be framed: they open as a normal top-level
330
+ * navigation, which ends the session. Use for anything that breaks inside an iframe
331
+ * or shouldn't be wrapped — auth / SSO, checkout, sign-out.
332
+ *
333
+ * Same-origin only, and that is not a limitation: anything cross-origin already opens
334
+ * top-level unless you list it under {@link include}.
315
335
  */
316
336
  exclude?: {
317
- /** Hostnames to exclude (exact host or a parent domain, e.g. `"napster.com"`). */
318
- domains?: string[];
319
- /** URLs to exclude: an absolute `"https://…"` (exact/prefix) or a same-origin path prefix. */
337
+ /** An absolute `"https://…"` (exact or prefix) or a same-origin path prefix (`"/checkout"`). */
320
338
  urls?: string[];
321
339
  };
340
+ /**
341
+ * Other people's domains that ARE allowed to load inside the site frame, so following
342
+ * a link to them keeps the session alive instead of ending it. Everything cross-origin
343
+ * breaks out by default; this is the exception list.
344
+ *
345
+ * ```ts
346
+ * include: { domains: ["docs.example.com", "partner.io"] }
347
+ * ```
348
+ *
349
+ * Matches the exact host or any subdomain of it. Only add a domain you control or have
350
+ * agreed with, and know what you give up — inside a cross-origin page the engine can
351
+ * see nothing:
352
+ *
353
+ * - the site must permit framing at all; one that sends `X-Frame-Options: DENY` or a
354
+ * restrictive `frame-ancestors` shows a blank frame, and that cannot be detected;
355
+ * - links clicked in there are not intercepted, so the user can wander anywhere and
356
+ * nothing brings them back;
357
+ * - the address bar stops following the frame, and back/forward stop syncing with it;
358
+ * - ending the session there cannot reload the page the user is on, so it unwraps to
359
+ * the last page of your own site instead.
360
+ */
361
+ include?: {
362
+ /** Hostnames allowed inside the frame (exact host or a parent domain, e.g. `"example.com"`). */
363
+ domains?: string[];
364
+ };
322
365
  /** Value for the site iframe's `allow` attribute (Permissions Policy). Default: `"autoplay; clipboard-write"`. */
323
366
  iframeAllowAttribute?: string;
367
+ /**
368
+ * Show a thin progress bar at the top of the page while a page loads into the site
369
+ * frame. **Off by default** — opt in with `true`, or with an object to restyle it.
370
+ *
371
+ * Worth turning on because a navigation inside the iframe drives no browser chrome:
372
+ * no tab spinner, no reload-turns-into-stop. Without some indicator, a click the
373
+ * engine took over looks dead for the whole load. Covers navigation both before the
374
+ * wrap and inside the frame afterwards. Leave it off if the site already shows its
375
+ * own navigation indicator.
376
+ *
377
+ * ```ts
378
+ * navigationProgress: true // default styling
379
+ * navigationProgress: { color: "#00b3ff" } // brand colour
380
+ * navigationProgress: { color: "#fff", height: "2px" }
381
+ * ```
382
+ */
383
+ navigationProgress?: boolean | NavigationProgressOptions;
324
384
  /**
325
385
  * While a persisted session is active, mirror the iframe's path into the address bar
326
386
  * and follow parent back/forward into the iframe. Same-origin only. Default: `true`.
327
387
  */
328
388
  syncHistory?: boolean;
389
+ /**
390
+ * Keep Back from leaving the persisted site while a session is live. Default: `true`.
391
+ * Requires {@link syncHistory} (the engine keys off the history entries it owns).
392
+ *
393
+ * Back/forward BETWEEN pages of the session keep working normally. Only the step that
394
+ * would leave the site is refused — that step unloads the top document, and with it
395
+ * the live session, mid-conversation. At that boundary Back does nothing.
396
+ *
397
+ * Note this is a back-button trap, and users do notice: repeated presses that appear
398
+ * stuck read as the site holding them hostage. Set to `false` to let Back leave (the
399
+ * session ends and the page unwraps normally), and prefer that on sites where exiting
400
+ * quickly matters more than keeping the session alive. It cannot trap everything
401
+ * either — a long-press on Back jumps several entries at once and leaves regardless.
402
+ */
403
+ trapBackNavigation?: boolean;
329
404
  }
330
405
  /**
331
406
  * Main configuration object passed to `init(token, config)`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@touchcastllc/napster-companion-api-dev",
3
- "version": "1.0.0-alpha.86",
3
+ "version": "1.5.0-alpha.1",
4
4
  "keywords": [
5
5
  "napster",
6
6
  "companion-api",