@nextsparkjs/core 0.1.0-beta.141 → 0.1.0-beta.142

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.
@@ -0,0 +1,7 @@
1
+ /**
2
+ * CORE SECURITY LAYOUT - NOT OVERRIDEABLE BY THEMES
3
+ */
4
+ export declare function DashboardAuthLayout({ children }: {
5
+ children: React.ReactNode;
6
+ }): import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=DashboardAuthLayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DashboardAuthLayout.d.ts","sourceRoot":"","sources":["../../../../src/components/dashboard/layouts/DashboardAuthLayout.tsx"],"names":[],"mappings":"AA2EA;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACT,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B,2CAEA"}
@@ -0,0 +1,44 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { useAuth } from "../../../hooks/useAuth.js";
4
+ import { useRouter } from "next/navigation";
5
+ import { useEffect, Suspense } from "react";
6
+ import { Loader2 } from "lucide-react";
7
+ import { DashboardTranslationPreloader } from "../../../lib/i18n/DashboardTranslationPreloader.js";
8
+ import { TranslationDebugger } from "../../../utils/dev/TranslationDebugger.js";
9
+ import { useEnsureUserMetadata } from "../../../hooks/useEnsureUserMetadata.js";
10
+ import { useAuthMethodDetector } from "../../../hooks/useAuthMethodDetector.js";
11
+ function AuthMethodDetectorWrapper() {
12
+ useAuthMethodDetector();
13
+ return null;
14
+ }
15
+ function DashboardLayoutContent({ children }) {
16
+ const { user, isLoading } = useAuth();
17
+ const router = useRouter();
18
+ useEnsureUserMetadata();
19
+ useEffect(() => {
20
+ if (!isLoading && !user) {
21
+ router.push("/login");
22
+ }
23
+ }, [user, isLoading, router]);
24
+ if (isLoading) {
25
+ return /* @__PURE__ */ jsx("div", { className: "min-h-screen flex items-center justify-center", children: /* @__PURE__ */ jsx(Loader2, { className: "h-8 w-8 animate-spin text-muted-foreground" }) });
26
+ }
27
+ if (!user) {
28
+ return null;
29
+ }
30
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
31
+ /* @__PURE__ */ jsx(DashboardTranslationPreloader, {}, "dashboard-translation-preloader"),
32
+ /* @__PURE__ */ jsx(TranslationDebugger, {}, "translation-debugger"),
33
+ /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(AuthMethodDetectorWrapper, {}) }, "auth-method-detector"),
34
+ /* @__PURE__ */ jsx("div", { "data-cy": "dashboard-container", children }, "dashboard-children")
35
+ ] });
36
+ }
37
+ function DashboardAuthLayout({
38
+ children
39
+ }) {
40
+ return /* @__PURE__ */ jsx(DashboardLayoutContent, { children });
41
+ }
42
+ export {
43
+ DashboardAuthLayout
44
+ };
@@ -1,4 +1,5 @@
1
1
  export { AuthGuard } from './AuthGuard';
2
+ export { DashboardAuthLayout } from './DashboardAuthLayout';
2
3
  export { DashboardShell } from './DashboardShell';
3
4
  export { Sidebar } from './Sidebar';
4
5
  export { TopNavbar } from './TopNavbar';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/dashboard/layouts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/dashboard/layouts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA"}
@@ -1,9 +1,11 @@
1
1
  import { AuthGuard } from "./AuthGuard.js";
2
+ import { DashboardAuthLayout } from "./DashboardAuthLayout.js";
2
3
  import { DashboardShell } from "./DashboardShell.js";
3
4
  import { Sidebar } from "./Sidebar.js";
4
5
  import { TopNavbar } from "./TopNavbar.js";
5
6
  export {
6
7
  AuthGuard,
8
+ DashboardAuthLayout,
7
9
  DashboardShell,
8
10
  Sidebar,
9
11
  TopNavbar
@@ -1,5 +1,5 @@
1
1
  {
2
- "generated": "2026-04-13T21:11:51.036Z",
2
+ "generated": "2026-04-13T22:13:02.894Z",
3
3
  "totalClasses": 1078,
4
4
  "classes": [
5
5
  "!text-2xl",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextsparkjs/core",
3
- "version": "0.1.0-beta.141",
3
+ "version": "0.1.0-beta.142",
4
4
  "description": "NextSpark - The complete SaaS framework for Next.js",
5
5
  "license": "MIT",
6
6
  "author": "NextSpark <hello@nextspark.dev>",
@@ -463,7 +463,7 @@
463
463
  "tailwind-merge": "^3.3.1",
464
464
  "uuid": "^13.0.0",
465
465
  "zod": "^4.1.5",
466
- "@nextsparkjs/testing": "0.1.0-beta.141"
466
+ "@nextsparkjs/testing": "0.1.0-beta.142"
467
467
  },
468
468
  "scripts": {
469
469
  "postinstall": "node scripts/postinstall.mjs || true",
@@ -495,71 +495,37 @@ ${(() => {
495
495
 
496
496
  console.log(`[TranslationRegistry] PPR enabled — generating static exports for locale '${defaultLocale}'`)
497
497
 
498
- // Collect entity translations for the default locale (theme entities)
499
- const defaultLocaleEntityTranslations = entityTranslations.filter(
500
- t => t.themeName === config.activeTheme && t.locale === defaultLocale
501
- )
502
-
503
- // Collect plugin entity translations for the default locale
504
- // Only include plugin entities that are NOT already in the theme (plugin = fallback)
505
- const themeEntityNames = new Set(defaultLocaleEntityTranslations.map(t => t.entityName))
506
- const defaultLocalePluginEntityTranslations = pluginEntityTranslations.filter(
507
- t => t.locale === defaultLocale && !themeEntityNames.has(t.entityName)
508
- )
509
-
510
- const allEntityTranslations = [...defaultLocaleEntityTranslations, ...defaultLocalePluginEntityTranslations]
511
-
512
- // Generate import statements for entity translations
513
- const entityImports = allEntityTranslations.map((t, i) => {
514
- const varName = `_entity${i}Messages`
515
- return `import ${varName} from '${t.filePath}'`
516
- }).join('\n')
517
-
518
- // Generate the entity messages object entries
519
- const entityEntries = allEntityTranslations.map((t, i) => {
520
- const varName = `_entity${i}Messages`
521
- return ` '${t.entityName}': ${varName}`
522
- }).join(',\n')
523
-
524
- const hasEntities = allEntityTranslations.length > 0
525
- const entityImportsBlock = hasEntities ? `\n// Entity and plugin entity translations (default locale)\n${entityImports}\n` : ''
526
- const entityMergeBlock = hasEntities
527
- ? `
528
- const _entityMessages: Record<string, unknown> = {
529
- ${entityEntries}
530
- }
531
-
532
- export const STATIC_MESSAGES: Record<string, unknown> = _deepMerge(
533
- _deepMerge(
534
- _coreMessages as unknown as Record<string, unknown>,
535
- (_themeMessages as { default?: Record<string, unknown> }).default ?? _themeMessages as unknown as Record<string, unknown>
536
- ),
537
- _entityMessages
538
- )`
539
- : `
540
- export const STATIC_MESSAGES: Record<string, unknown> = _deepMerge(
541
- _coreMessages as unknown as Record<string, unknown>,
542
- (_themeMessages as { default?: Record<string, unknown> }).default ?? _themeMessages as unknown as Record<string, unknown>
543
- )`
544
-
545
- if (hasEntities) {
546
- console.log(`[TranslationRegistry] PPR static messages include ${allEntityTranslations.length} entity translations`)
547
- }
498
+ // NOTE: Entity/plugin translations are NOT included in STATIC_MESSAGES.
499
+ // STATIC_MESSAGES is used by the root layout's StaticIntlProvider and gets
500
+ // serialized into the RSC payload of EVERY page (including public pages).
501
+ // Including entity translations (~500KB+) would bloat public page payloads
502
+ // and degrade PageSpeed scores significantly.
503
+ //
504
+ // Entity translations are loaded dynamically via loadMergedTranslations()
505
+ // for authenticated pages. Dashboard layouts should use NextIntlClientProvider
506
+ // with server-loaded messages to provide entity translations to client components.
548
507
 
549
508
  return `/**
550
509
  * PPR: Static messages for the default locale (pre-merged at build time)
551
510
  *
552
511
  * Used by the root layout's StaticIntlProvider to render content
553
512
  * in the PPR static shell without accessing cookies/headers.
554
- * Core messages are deep-merged with theme + entity + plugin messages.
513
+ * Core messages are deep-merged with theme messages only.
514
+ *
515
+ * NOTE: Entity/plugin translations are NOT included here to avoid bloating
516
+ * the RSC payload of public pages. Dashboard pages load entity translations
517
+ * via NextIntlClientProvider in the dashboard layout.
555
518
  */
556
519
  import { deepMergeMessages as _deepMerge } from '@nextsparkjs/core/lib/translations/registry'
557
520
  import _coreMessages from '@nextsparkjs/core/messages/${defaultLocale}/index.js'
558
521
  import _themeMessages from '${defaultThemeTranslation.filePath}'
559
- ${entityImportsBlock}
522
+
560
523
  export const DEFAULT_LOCALE = '${defaultLocale}' as const
561
524
  export const DEFAULT_THEME_MODE = '${defaultThemeMode}' as const
562
- ${entityMergeBlock}`
525
+ export const STATIC_MESSAGES: Record<string, unknown> = _deepMerge(
526
+ _coreMessages as unknown as Record<string, unknown>,
527
+ (_themeMessages as { default?: Record<string, unknown> }).default ?? _themeMessages as unknown as Record<string, unknown>
528
+ )`
563
529
  })()}
564
530
  `
565
531
  }