@carlonicora/nextjs-jsonapi 4.0.5 → 4.0.7

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.
Files changed (29) hide show
  1. package/dist/{BlockNoteEditor-H6EXQD46.js → BlockNoteEditor-J7EF7BRX.js} +9 -9
  2. package/dist/{BlockNoteEditor-H6EXQD46.js.map → BlockNoteEditor-J7EF7BRX.js.map} +1 -1
  3. package/dist/{BlockNoteEditor-L3STMBP2.mjs → BlockNoteEditor-KOHN3SSR.mjs} +2 -2
  4. package/dist/billing/index.js +335 -335
  5. package/dist/billing/index.mjs +1 -1
  6. package/dist/{chunk-3JET3LL7.js → chunk-3M7D6NXU.js} +20 -13
  7. package/dist/chunk-3M7D6NXU.js.map +1 -0
  8. package/dist/{chunk-KX2776OK.mjs → chunk-3W3VVX2N.mjs} +322 -315
  9. package/dist/chunk-3W3VVX2N.mjs.map +1 -0
  10. package/dist/client/index.js +2 -2
  11. package/dist/client/index.mjs +1 -1
  12. package/dist/components/index.js +2 -2
  13. package/dist/components/index.mjs +1 -1
  14. package/dist/contexts/index.js +2 -2
  15. package/dist/contexts/index.mjs +1 -1
  16. package/dist/features/analytics/index.js +88 -88
  17. package/dist/features/analytics/index.mjs +1 -1
  18. package/dist/features/help/index.js +31 -31
  19. package/dist/features/help/index.mjs +1 -1
  20. package/dist/features/tokenusage/index.js +75 -75
  21. package/dist/features/tokenusage/index.mjs +1 -1
  22. package/package.json +1 -1
  23. package/src/components/navigations/RecentPagesNavigator.tsx +11 -1
  24. package/src/components/navigations/__tests__/RecentPagesNavigator.spec.tsx +19 -0
  25. package/src/shadcnui/ui/__tests__/sidebar.session.test.tsx +136 -0
  26. package/src/shadcnui/ui/sidebar.tsx +21 -13
  27. package/dist/chunk-3JET3LL7.js.map +0 -1
  28. package/dist/chunk-KX2776OK.mjs.map +0 -1
  29. /package/dist/{BlockNoteEditor-L3STMBP2.mjs.map → BlockNoteEditor-KOHN3SSR.mjs.map} +0 -0
@@ -18,6 +18,7 @@ import { PanelLeftIcon } from "lucide-react";
18
18
  import { useDir } from "../../contexts/DirectionContext";
19
19
  import type { SessionSnapshot } from "../../server/ServerSession";
20
20
  import { mapThenable } from "../../utils/map-thenable";
21
+ import { getViewportContext } from "../../utils/use-mobile";
21
22
 
22
23
  const SIDEBAR_COOKIE_NAME = "sidebar_state";
23
24
  const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
@@ -91,8 +92,9 @@ type SidebarProviderProps = React.ComponentProps<"div"> & {
91
92
  };
92
93
 
93
94
  function SidebarProvider({ session, ...props }: SidebarProviderProps) {
94
- // With a session the viewport comes from the session snapshot, so
95
- // useIsMobile() is never called; without one the behaviour is unchanged.
95
+ // With a session useIsMobile() is never called: it would suspend the
96
+ // provider. The core reads the ViewportProvider's context without unwrapping
97
+ // it; without a session the behaviour is unchanged.
96
98
  if (session) return <SidebarProviderCore {...props} session={session} />;
97
99
  return <ViewportSidebarProvider {...props} />;
98
100
  }
@@ -113,22 +115,28 @@ function SidebarProviderCore({
113
115
  children,
114
116
  ...props
115
117
  }: SidebarProviderProps & { viewportIsMobile?: boolean }) {
118
+ // With a session, the live value is the ViewportProvider's: its
119
+ // session-seeded promise first (same snapshot, so SSR and first paint match),
120
+ // then every measurement. Read raw, never unwrapped here, so the provider does
121
+ // not suspend. Outside a ViewportProvider, fall back to the session snapshot.
122
+ const viewport = React.useContext(getViewportContext());
123
+ const hasViewport = viewport !== undefined;
116
124
  const sessionIsMobile = React.useMemo(
117
- () => (session ? mapThenable(session, (s) => s.isMobile) : undefined),
118
- [session],
125
+ () => (session && !hasViewport ? mapThenable(session, (s) => s.isMobile) : undefined),
126
+ [session, hasViewport],
119
127
  );
120
- const isMobile: boolean | Promise<boolean> = sessionIsMobile ?? viewportIsMobile;
128
+ const isMobile: boolean | Promise<boolean> = session ? (viewport ?? sessionIsMobile!) : viewportIsMobile;
121
129
 
122
130
  // Synchronous reads (toggle, keyboard shortcut) cannot suspend: they use the
123
- // last resolved value, false until the session resolves.
124
- const isMobileRef = React.useRef<boolean>(viewportIsMobile);
131
+ // last resolved value, false until the first one arrives.
132
+ const isMobileRef = React.useRef<boolean>(typeof isMobile === "boolean" ? isMobile : false);
125
133
  React.useEffect(() => {
126
- if (!sessionIsMobile) {
127
- isMobileRef.current = viewportIsMobile;
134
+ if (!(isMobile instanceof Promise)) {
135
+ isMobileRef.current = isMobile;
128
136
  return;
129
137
  }
130
138
  let cancelled = false;
131
- sessionIsMobile
139
+ isMobile
132
140
  .then((value) => {
133
141
  if (!cancelled) isMobileRef.current = value;
134
142
  })
@@ -136,7 +144,7 @@ function SidebarProviderCore({
136
144
  return () => {
137
145
  cancelled = true;
138
146
  };
139
- }, [sessionIsMobile, viewportIsMobile]);
147
+ }, [isMobile]);
140
148
 
141
149
  const [openMobile, setOpenMobile] = React.useState(false);
142
150
 
@@ -183,9 +191,9 @@ function SidebarProviderCore({
183
191
 
184
192
  // Helper to toggle the sidebar.
185
193
  const toggleSidebar = React.useCallback(() => {
186
- const mobile = sessionIsMobile ? isMobileRef.current : viewportIsMobile;
194
+ const mobile = typeof isMobile === "boolean" ? isMobile : isMobileRef.current;
187
195
  return mobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);
188
- }, [sessionIsMobile, viewportIsMobile, setOpen, setOpenMobile]);
196
+ }, [isMobile, setOpen, setOpenMobile]);
189
197
 
190
198
  // Adds a keyboard shortcut to toggle the sidebar.
191
199
  React.useEffect(() => {