@dudousxd/nestjs-media-dashboard 0.12.0 → 0.12.2

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.
@@ -10,7 +10,11 @@ import { type OpenConsoleOptions } from '../client/console-session.js';
10
10
  export interface UseOpenConsoleResult {
11
11
  /** Start the mint-then-navigate. Never rejects — read `error` instead. */
12
12
  open: () => void;
13
- /** True from the click until the navigation starts, or until it fails. */
13
+ /**
14
+ * True from the click until the navigation starts, or until it fails. Stays true across a
15
+ * successful mint (see below) and is cleared again if the browser restores this page from the
16
+ * back/forward cache.
17
+ */
14
18
  isPending: boolean;
15
19
  /**
16
20
  * The last refusal, or `null`. Cleared when `open()` is called again.
@@ -1 +1 @@
1
- {"version":3,"file":"use-open-console.d.ts","sourceRoot":"","sources":["../../src/react/use-open-console.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,kBAAkB,EAAoB,MAAM,8BAA8B,CAAC;AAEzF;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,0EAA0E;IAC1E,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,0EAA0E;IAC1E,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;;;OAOG;IACH,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,uEAAuE;IACvE,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,kBAAuB,GAAG,oBAAoB,CA2B1F;AAED;;;;;;;;GAQG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,GAAE,kBAAuB,GAAG;IACjF,WAAW,EAAE,SAAS,OAAO,EAAE,CAAC;IAChC,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC,CAeA"}
1
+ {"version":3,"file":"use-open-console.d.ts","sourceRoot":"","sources":["../../src/react/use-open-console.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,kBAAkB,EAAoB,MAAM,8BAA8B,CAAC;AAEzF;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,0EAA0E;IAC1E,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB;;;;OAIG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;;;OAOG;IACH,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,uEAAuE;IACvE,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,kBAAuB,GAAG,oBAAoB,CAiD1F;AAED;;;;;;;;GAQG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,GAAE,kBAAuB,GAAG;IACjF,WAAW,EAAE,SAAS,OAAO,EAAE,CAAC;IAChC,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC,CAeA"}
@@ -1,4 +1,4 @@
1
- import { useCallback, useRef, useState } from 'react';
1
+ import { useCallback, useEffect, useRef, useState } from 'react';
2
2
  import { openMediaConsole } from '../client/console-session.js';
3
3
  export function useOpenMediaConsole(options = {}) {
4
4
  const [isPending, setIsPending] = useState(false);
@@ -15,12 +15,35 @@ export function useOpenMediaConsole(options = {}) {
15
15
  // Deliberately NOT clearing `isPending` on success: the navigation is already underway and
16
16
  // this component is about to be torn down. Flipping the button back to idle first produces
17
17
  // a visible flicker of "ready to click again" on a page that is leaving.
18
+ //
19
+ // The page does not always die, though — see the `pageshow` effect below, which is the
20
+ // other half of this decision.
18
21
  })
19
22
  .catch((cause) => {
20
23
  setError(cause instanceof Error ? cause : new Error(String(cause)));
21
24
  setIsPending(false);
22
25
  });
23
26
  }, []);
27
+ // The other half of "don't clear `isPending` on success". Leaving the flag set assumes the page
28
+ // is destroyed by the navigation — but the back/forward cache does NOT destroy it: pressing Back
29
+ // restores this very page from memory with React state intact, so the user returns to a spinner
30
+ // that never stops on a button that is disabled precisely because `isPending` is still true.
31
+ // A bfcache restore is only observable as `pageshow` with `persisted: true`; there is no unmount,
32
+ // no re-render and no fresh mount to hang the reset off, which is why this listener exists and
33
+ // must not be "simplified" into clearing the flag on the success path (that reintroduces the
34
+ // flicker) or into an unconditional `pageshow` handler (that fires on ordinary loads too).
35
+ useEffect(() => {
36
+ // SSR-safe: no window on the server, and nothing to restore there either.
37
+ if (typeof window === 'undefined')
38
+ return;
39
+ const onPageShow = (event) => {
40
+ if (!event.persisted)
41
+ return;
42
+ setIsPending(false);
43
+ };
44
+ window.addEventListener('pageshow', onPageShow);
45
+ return () => window.removeEventListener('pageshow', onPageShow);
46
+ }, []);
24
47
  const reset = useCallback(() => setError(null), []);
25
48
  return { open, isPending, error, reset };
26
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"use-open-console.js","sourceRoot":"","sources":["../../src/react/use-open-console.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,EAA2B,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AA4BzF,MAAM,UAAU,mBAAmB,CAAC,UAA8B,EAAE;IAClE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IAEvD,kGAAkG;IAClG,wFAAwF;IACxF,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACnC,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;IAE7B,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE;QAC5B,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,KAAK,gBAAgB,CAAC,UAAU,CAAC,OAAO,CAAC;aACtC,IAAI,CAAC,GAAG,EAAE;YACT,2FAA2F;YAC3F,2FAA2F;YAC3F,yEAAyE;QAC3E,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;YACxB,QAAQ,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACpE,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC,CAAC,CAAC;IACP,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAEpD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC3C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,+BAA+B,CAAC,UAA8B,EAAE;IAI9E,OAAO;QACL,gGAAgG;QAChG,4FAA4F;QAC5F,+FAA+F;QAC/F,SAAS;QACT,WAAW,EAAE;YACX,OAAO;YACP,SAAS;YACT,MAAM;YACN,OAAO,CAAC,QAAQ,IAAI,IAAI;YACxB,OAAO,CAAC,WAAW,IAAI,IAAI;SACnB;QACV,UAAU,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC;KAC5C,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"use-open-console.js","sourceRoot":"","sources":["../../src/react/use-open-console.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjE,OAAO,EAA2B,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAgCzF,MAAM,UAAU,mBAAmB,CAAC,UAA8B,EAAE;IAClE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IAEvD,kGAAkG;IAClG,wFAAwF;IACxF,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACnC,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;IAE7B,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE;QAC5B,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,KAAK,gBAAgB,CAAC,UAAU,CAAC,OAAO,CAAC;aACtC,IAAI,CAAC,GAAG,EAAE;YACT,2FAA2F;YAC3F,2FAA2F;YAC3F,yEAAyE;YACzE,EAAE;YACF,uFAAuF;YACvF,+BAA+B;QACjC,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;YACxB,QAAQ,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACpE,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC,CAAC,CAAC;IACP,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,gGAAgG;IAChG,iGAAiG;IACjG,gGAAgG;IAChG,6FAA6F;IAC7F,kGAAkG;IAClG,+FAA+F;IAC/F,6FAA6F;IAC7F,2FAA2F;IAC3F,SAAS,CAAC,GAAG,EAAE;QACb,0EAA0E;QAC1E,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAO;QAC1C,MAAM,UAAU,GAAG,CAAC,KAA0B,EAAE,EAAE;YAChD,IAAI,CAAC,KAAK,CAAC,SAAS;gBAAE,OAAO;YAC7B,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAChD,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAClE,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAEpD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC3C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,+BAA+B,CAAC,UAA8B,EAAE;IAI9E,OAAO;QACL,gGAAgG;QAChG,4FAA4F;QAC5F,+FAA+F;QAC/F,SAAS;QACT,WAAW,EAAE;YACX,OAAO;YACP,SAAS;YACT,MAAM;YACN,OAAO,CAAC,QAAQ,IAAI,IAAI;YACxB,OAAO,CAAC,WAAW,IAAI,IAAI;SACnB;QACV,UAAU,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC;KAC5C,CAAC;AACJ,CAAC"}
@@ -1730,7 +1730,17 @@ var MediaDashboardModule = class _MediaDashboardModule {
1730
1730
  ...imports ?? [],
1731
1731
  MediaConsoleApiModule.register({
1732
1732
  actions,
1733
- cookiePath: apiBasePath,
1733
+ // `Path=/`, deliberately NOT scoped to `apiBasePath` (nor to `basePath`): the two mounts
1734
+ // are independently configurable and can live at unrelated paths (e.g. a `/media` UI
1735
+ // with a `/api/media/console` API). Scoped to the API base, the browser withheld the
1736
+ // cookie on the full-page navigation to `basePath`, so the freshly minted session could
1737
+ // not open the console it was minted for — the launcher landed on the unauthenticated
1738
+ // page. Scoping to `basePath` instead would just move the failure to the API calls.
1739
+ // The cookie is HttpOnly + signed + short-lived, so the broader scope is a reasonable
1740
+ // trade for being correct in any mount configuration. Matches nestjs-durable-dashboard
1741
+ // and nestjs-agent-dashboard; telescope can scope to its mount because its UI and API
1742
+ // always share one root.
1743
+ cookiePath: "/",
1734
1744
  authProvider,
1735
1745
  imports,
1736
1746
  ...options.guards ? {