@nextsparkjs/core 0.1.0-beta.132 → 0.1.0-beta.134

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.
@@ -2,7 +2,12 @@
2
2
  * PageRenderer Component
3
3
  *
4
4
  * Renders pages from the Page Builder by iterating over blocks
5
- * and dynamically loading block components from the registry.
5
+ * and loading block components from the SSR registry.
6
+ *
7
+ * Block components are loaded via next/dynamic (ssr: true) for per-block
8
+ * code splitting. Each block gets its own JS chunk — only blocks used on
9
+ * the page have their JS loaded by the browser. SSR renders full HTML
10
+ * so content is visible without client JS (SEO-safe).
6
11
  *
7
12
  * @module core/components/public/pageBuilder
8
13
  */
@@ -1 +1 @@
1
- {"version":3,"file":"PageRenderer.d.ts","sourceRoot":"","sources":["../../../../src/components/public/pageBuilder/PageRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAmD1D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAA;QACV,KAAK,EAAE,MAAM,CAAA;QACb,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,EAAE,aAAa,EAAE,CAAA;QACvB,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;CACF;AAED,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,EAAE,iBAAiB,2CA+BvD"}
1
+ {"version":3,"file":"PageRenderer.d.ts","sourceRoot":"","sources":["../../../../src/components/public/pageBuilder/PageRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAsC1D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAA;QACV,KAAK,EAAE,MAAM,CAAA;QACb,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,EAAE,aAAa,EAAE,CAAA;QACvB,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;CACF;AAED,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,EAAE,iBAAiB,2CA+BvD"}
@@ -1,13 +1,6 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { Suspense } from "react";
3
- import { getBlockComponent, normalizeBlockProps } from "../../../lib/blocks/loader.js";
4
- function BlockSkeleton() {
5
- return /* @__PURE__ */ jsx("div", { className: "w-full py-12 px-4 animate-pulse", children: /* @__PURE__ */ jsxs("div", { className: "max-w-7xl mx-auto", children: [
6
- /* @__PURE__ */ jsx("div", { className: "h-8 bg-muted rounded w-3/4 mb-4" }),
7
- /* @__PURE__ */ jsx("div", { className: "h-4 bg-muted rounded w-full mb-2" }),
8
- /* @__PURE__ */ jsx("div", { className: "h-4 bg-muted rounded w-5/6" })
9
- ] }) });
10
- }
3
+ import { getBlockComponentSSR, normalizeBlockProps } from "../../../lib/blocks/loader.js";
11
4
  function BlockError({ blockSlug }) {
12
5
  return /* @__PURE__ */ jsx("div", { className: "w-full py-12 px-4 bg-destructive/10 border border-destructive/20 rounded", children: /* @__PURE__ */ jsxs("div", { className: "max-w-7xl mx-auto text-center", children: [
13
6
  /* @__PURE__ */ jsxs("p", { className: "text-destructive", children: [
@@ -18,13 +11,13 @@ function BlockError({ blockSlug }) {
18
11
  ] }) });
19
12
  }
20
13
  function BlockRenderer({ block }) {
21
- const BlockComponent = getBlockComponent(block.blockSlug);
14
+ const BlockComponent = getBlockComponentSSR(block.blockSlug);
22
15
  if (!BlockComponent) {
23
16
  console.warn(`Block component not found for slug: ${block.blockSlug}`);
24
17
  return /* @__PURE__ */ jsx(BlockError, { blockSlug: block.blockSlug });
25
18
  }
26
19
  const normalizedProps = normalizeBlockProps(block.props);
27
- return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(BlockSkeleton, {}), children: /* @__PURE__ */ jsx(BlockComponent, { ...normalizedProps }) });
20
+ return /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(BlockComponent, { ...normalizedProps }) });
28
21
  }
29
22
  function PageRenderer({ page }) {
30
23
  const blocks = Array.isArray(page.blocks) ? page.blocks : [];
@@ -22,6 +22,15 @@ export declare function getBlockComponents(): Record<string, BlockComponent>;
22
22
  * @returns The block component or undefined if not found
23
23
  */
24
24
  export declare function getBlockComponent(slug: string): BlockComponent | undefined;
25
+ /**
26
+ * Get all SSR block components (direct imports, no React.lazy)
27
+ * Use for public page rendering where no-JS SSR is required
28
+ */
29
+ export declare function getBlockComponentsSSR(): Record<string, BlockComponent>;
30
+ /**
31
+ * Get a specific SSR block component by slug (direct import, no React.lazy)
32
+ */
33
+ export declare function getBlockComponentSSR(slug: string): BlockComponent | undefined;
25
34
  /**
26
35
  * Check if a block exists in the registry
27
36
  *
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/lib/blocks/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAIrC,KAAK,cAAc,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;AAExC;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAEnE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAE1E;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgD3F"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/lib/blocks/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAIrC,KAAK,cAAc,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;AAExC;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAEnE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAE1E;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAEtE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAE7E;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgD3F"}
@@ -1,10 +1,16 @@
1
- import { BLOCK_COMPONENTS } from "@nextsparkjs/registries/block-registry";
1
+ import { BLOCK_COMPONENTS, BLOCK_COMPONENTS_SSR } from "@nextsparkjs/registries/block-registry";
2
2
  function getBlockComponents() {
3
3
  return BLOCK_COMPONENTS;
4
4
  }
5
5
  function getBlockComponent(slug) {
6
6
  return BLOCK_COMPONENTS[slug];
7
7
  }
8
+ function getBlockComponentsSSR() {
9
+ return BLOCK_COMPONENTS_SSR;
10
+ }
11
+ function getBlockComponentSSR(slug) {
12
+ return BLOCK_COMPONENTS_SSR[slug];
13
+ }
8
14
  function hasBlock(slug) {
9
15
  return slug in BLOCK_COMPONENTS;
10
16
  }
@@ -48,7 +54,9 @@ function normalizeBlockProps(props) {
48
54
  }
49
55
  export {
50
56
  getBlockComponent,
57
+ getBlockComponentSSR,
51
58
  getBlockComponents,
59
+ getBlockComponentsSSR,
52
60
  hasBlock,
53
61
  normalizeBlockProps
54
62
  };
@@ -1,5 +1,5 @@
1
1
  {
2
- "generated": "2026-04-01T20:21:39.786Z",
2
+ "generated": "2026-04-07T15:29:52.891Z",
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.132",
3
+ "version": "0.1.0-beta.134",
4
4
  "description": "NextSpark - The complete SaaS framework for Next.js",
5
5
  "license": "MIT",
6
6
  "author": "NextSpark <hello@nextspark.dev>",
@@ -462,7 +462,7 @@
462
462
  "tailwind-merge": "^3.3.1",
463
463
  "uuid": "^13.0.0",
464
464
  "zod": "^4.1.5",
465
- "@nextsparkjs/testing": "0.1.0-beta.132"
465
+ "@nextsparkjs/testing": "0.1.0-beta.134"
466
466
  },
467
467
  "scripts": {
468
468
  "postinstall": "node scripts/postinstall.mjs || true",
@@ -47,6 +47,13 @@ export const BLOCK_CATEGORIES: string[] = []
47
47
 
48
48
  export const BLOCK_COMPONENTS: Record<string, React.LazyExoticComponent<React.ComponentType<unknown>>> = {}
49
49
 
50
+ /**
51
+ * Direct-imported block components for SSR rendering
52
+ * No React.lazy, no Suspense — HTML is fully visible without JS
53
+ */
54
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
+ export const BLOCK_COMPONENTS_SSR: Record<string, React.ComponentType<any>> = {}
56
+
50
57
  export const BLOCK_METADATA = {
51
58
  totalBlocks: 0,
52
59
  categories: [],
@@ -120,6 +127,7 @@ export const BLOCK_METADATA = {
120
127
  */
121
128
 
122
129
  import React from 'react'
130
+ import dynamic from 'next/dynamic'
123
131
  import type { BlockConfig, BlockCategory } from '${convertCorePath('@/core/types', outputFilePath, config)}'
124
132
 
125
133
  ${fieldImports}
@@ -141,6 +149,18 @@ ${blocks.map(block => {
141
149
  }).join(',\n')}
142
150
  }
143
151
 
152
+ /**
153
+ * Code-split block components for SSR rendering via next/dynamic.
154
+ * Each block is a separate JS chunk — only blocks used on the page are loaded.
155
+ * SSR is enabled (default) so HTML is fully visible without client JS.
156
+ */
157
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
158
+ export const BLOCK_COMPONENTS_SSR: Record<string, React.ComponentType<any>> = {
159
+ ${blocks.map(block => {
160
+ return ` '${block.slug}': dynamic(() => import('${block.paths.component}'), { ssr: true })`
161
+ }).join(',\n')}
162
+ }
163
+
144
164
  /**
145
165
  * Block registry metadata
146
166
  */
@@ -133,7 +133,7 @@ export interface PluginRegistryEntry {
133
133
  hasAssets: boolean
134
134
  }
135
135
 
136
- export const PLUGIN_REGISTRY = {
136
+ export const PLUGIN_REGISTRY: Record<string, PluginRegistryEntry> = {
137
137
  ${registryEntries}
138
138
  }
139
139
 
@@ -6,6 +6,8 @@ export const BLOCK_REGISTRY: Record<string, any> = {}
6
6
 
7
7
  export const BLOCK_COMPONENTS: Record<string, any> = {}
8
8
 
9
+ export const BLOCK_COMPONENTS_SSR: Record<string, any> = {}
10
+
9
11
  export const BLOCK_METADATA = {
10
12
  generated: new Date().toISOString(),
11
13
  totalBlocks: 0,