rankrunners-cms 0.0.18 → 0.0.19

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.
package/README.md CHANGED
@@ -571,25 +571,46 @@ Update the `server.ts` script, or add a Tanstack Start middleware to handle `[si
571
571
  // Build static routes with intelligent preloading
572
572
  const { routes } = await initializeStaticRoutes(CLIENT_DIRECTORY)
573
573
 
574
- // Add sitemap routes
575
- routes['/*'] = (req: Request) => {
576
- const url = new URL(req.url)
577
- const pathname = url.pathname
578
-
579
- // Serve the sitemap if we are asking for it
580
- if (pathname === 'robots.txt' || pathname.endsWith('.xml')) {
581
- const sitemapFile = pathname.substring(1)
582
- return downloadSitemapAsResponse(sitemapFile)
583
- }
584
-
585
- // Otherwise, pass to TanStack Start handler
586
- try {
587
- return handler.fetch(req)
588
- } catch (error) {
589
- log.error(`Server handler error: ${String(error)}`)
574
+ // Import sitemap handler dynamically to help Bun bundle it
575
+ const downloadSitemapAsResponse = (
576
+ await import('rankrunners-cms/src/api/client/sitemap')
577
+ ).downloadSitemapAsResponse
578
+
579
+ // Create Bun server
580
+ const server = Bun.serve({
581
+ port: SERVER_PORT,
582
+
583
+ routes: {
584
+ // Serve static assets, robots.txt, sitemaps (*.xml), and all other routes
585
+ ...routes,
586
+ '/*': (req: Request) => {
587
+ const url = new URL(req.url)
588
+ const pathname = url.pathname
589
+
590
+ // Check if it's a sitemap file (ends with .xml)
591
+ if (pathname === 'robots.txt' || pathname.endsWith('.xml')) {
592
+ const sitemapFile = pathname.substring(1) // Remove leading slash
593
+ return downloadSitemapAsResponse(sitemapFile)
594
+ }
595
+
596
+ // Otherwise, pass to TanStack Start handler
597
+ try {
598
+ return handler.fetch(req)
599
+ } catch (error) {
600
+ log.error(`Server handler error: ${String(error)}`)
601
+ return new Response('Internal Server Error', { status: 500 })
602
+ }
603
+ },
604
+ },
605
+
606
+ // Global error handler
607
+ error(error) {
608
+ log.error(
609
+ `Uncaught server error: ${error instanceof Error ? error.message : String(error)}`,
610
+ )
590
611
  return new Response('Internal Server Error', { status: 500 })
591
- }
592
- }
612
+ },
613
+ })
593
614
  ```
594
615
 
595
616
  ---
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "rankrunners-cms",
3
3
  "type": "module",
4
- "version": "0.0.18",
4
+ "version": "0.0.19",
5
5
  "peerDependencies": {
6
- "@puckeditor/core": "^0.21.0",
6
+ "@puckeditor/core": "^0.21.1",
7
7
  "next": "^16.1.2",
8
8
  "@tanstack/router-core": "^1.150.0",
9
9
  "@tanstack/react-router": "^1.150.0",
@@ -29,15 +29,14 @@
29
29
  }
30
30
  },
31
31
  "devDependencies": {
32
- "@types/react": "^19.2.8",
33
- "bun-types": "^1.3.6",
32
+ "@types/react": "^19.2.11",
33
+ "bun-types": "^1.3.8",
34
34
  "typescript": "^5.9.3",
35
- "@tanstack/router-core": "^1.150.0",
36
- "@tanstack/react-router": "^1.150.0",
37
- "next": "^16.1.3",
35
+ "@tanstack/router-core": "^1.158.0",
36
+ "@tanstack/react-router": "^1.158.0",
37
+ "next": "^16.1.6",
38
38
  "valibot": "^1.2.0",
39
- "lucide-react": "^0.562.0",
40
- "react": "^19.2.3"
39
+ "lucide-react": "^0.563.0"
41
40
  },
42
41
  "dependencies": {
43
42
  "classnames": "^2.5.1",
@@ -0,0 +1,57 @@
1
+ import type { CMSUserData } from "../../editor";
2
+ import { fetchWithCache } from "../../libs";
3
+ import { CMS_BASE_URL, SITE_ID } from "../constants";
4
+
5
+ export const getPageContents = async (
6
+ pathname: string,
7
+ allPageData: Record<string, CMSUserData<any>>,
8
+ previewToken?: string,
9
+ ) => {
10
+ // remove trailing (left and right) slashes
11
+ pathname = pathname.replace(/^\/+|\/+$/g, "");
12
+
13
+ try {
14
+ const res = await fetchWithCache(
15
+ `${CMS_BASE_URL}/public/seo/${SITE_ID}/pages/${pathname}`,
16
+ {
17
+ headers: {
18
+ "Content-Type": "application/json",
19
+ },
20
+ },
21
+ );
22
+
23
+ if (res.ok) {
24
+ const json = (await res.json()) as { content?: string };
25
+
26
+ if (json.content) {
27
+ const content = JSON.parse(json.content) as CMSUserData<any>;
28
+
29
+ if (content.root && content.content) {
30
+ return content;
31
+ }
32
+ }
33
+ }
34
+
35
+ const actualData = allPageData[pathname as keyof typeof allPageData];
36
+
37
+ if (actualData) {
38
+ // Starting new page from existing published data
39
+ return actualData as CMSUserData<any>;
40
+ }
41
+
42
+ // Starting new blank page
43
+ } catch (error) {
44
+ console.error("Error fetching page data:", error);
45
+ }
46
+
47
+ if (previewToken) {
48
+ // New blank page in preview mode
49
+ return {
50
+ content: [],
51
+ root: { props: { title: "New Page" } },
52
+ zones: {},
53
+ };
54
+ }
55
+
56
+ return null;
57
+ };
@@ -1,56 +1,7 @@
1
1
  import { useEffect, useState } from "react";
2
2
  import type { CMSUserData } from "../types";
3
3
  import { Render, type Config } from "@puckeditor/core";
4
- import { CMS_BASE_URL, SITE_ID } from "../../api";
5
- import { fetchWithCache } from "../../libs";
6
-
7
- const getPageContents = async (
8
- pathname: string,
9
- allPageData: Record<string, CMSUserData<any>>,
10
- ) => {
11
- // remove trailing (left and right) slashes
12
- pathname = pathname.replace(/^\/+|\/+$/g, "");
13
-
14
- try {
15
- const res = await fetchWithCache(
16
- `${CMS_BASE_URL}/public/seo/${SITE_ID}/pages/${pathname}`,
17
- {
18
- headers: {
19
- "Content-Type": "application/json",
20
- },
21
- },
22
- );
23
-
24
- if (res.ok) {
25
- const json = (await res.json()) as { content?: string };
26
-
27
- if (json.content) {
28
- const content = JSON.parse(json.content) as CMSUserData<any>;
29
-
30
- if (content.root && content.content) {
31
- return content;
32
- }
33
- }
34
- }
35
-
36
- const actualData = allPageData[pathname as keyof typeof allPageData];
37
-
38
- if (actualData) {
39
- // Starting new page from existing published data
40
- return actualData as CMSUserData<any>;
41
- }
42
-
43
- // Starting new blank page
44
- } catch (error) {
45
- console.error("Error fetching page data:", error);
46
- }
47
-
48
- return {
49
- content: [],
50
- root: { props: { title: "New Page" } },
51
- zones: {},
52
- };
53
- };
4
+ import { getPageContents } from "../../api/client/pages";
54
5
 
55
6
  export type PageRendererContentProps = {
56
7
  pathname: string;
@@ -82,4 +33,4 @@ export const PageRendererContent = ({
82
33
  }
83
34
 
84
35
  return <Render config={config} data={data} />;
85
- };
36
+ };
@@ -0,0 +1,15 @@
1
+ import { Render, type Config } from "@puckeditor/core";
2
+ import type { CMSUserData } from "../types";
3
+
4
+ export type PageRendererSSRProps = {
5
+ config: Config;
6
+ data: CMSUserData<any>;
7
+ };
8
+
9
+ /**
10
+ * SSR-compatible PageRenderer that receives pre-fetched data from the loader.
11
+ * Use this component with TanStack Router's loader for server-side rendering.
12
+ */
13
+ export const PageRendererSSR = ({ config, data }: PageRendererSSRProps) => {
14
+ return <Render config={config} data={data} />;
15
+ };
@@ -126,7 +126,7 @@ export const BaseEditor =
126
126
  alert("Failed to upload changes to CMS");
127
127
  } else {
128
128
  alert(
129
- "Changes uploaded successfully to CMS! The page will now reflect the changes."
129
+ "Changes uploaded successfully to CMS! The page will now reflect the changes.",
130
130
  );
131
131
  }
132
132
  } catch (error) {
@@ -141,9 +141,6 @@ export const BaseEditor =
141
141
  iframe={{
142
142
  enabled: true,
143
143
  }}
144
- fieldTransforms={{
145
- userField: ({ value }) => value, // Included to check types
146
- }}
147
144
  overrides={{
148
145
  fieldTypes: {
149
146
  // Example of user field provided via overrides
@@ -1,9 +1,7 @@
1
- "use client";
2
-
3
- import { BaseEditor } from "../../editor/render/Preview";
4
- import { usePathnameTanstack, useSearchParamsTanstack } from "../hooks";
1
+ import { BaseEditor } from '../../editor/render/Preview'
2
+ import { usePathnameTanstack, useSearchParamsTanstack } from '../hooks'
5
3
 
6
4
  export const EditorTanstack = BaseEditor({
7
5
  usePathname: usePathnameTanstack,
8
6
  useSearchParams: useSearchParamsTanstack,
9
- });
7
+ })
@@ -9,6 +9,10 @@ export type PageRendererTanstackInitializerProps = {
9
9
  allPageData: Record<string, CMSUserData<any>>;
10
10
  };
11
11
 
12
+ /**
13
+ * Use PageRendererTanstackSSR for SSR support instead.
14
+ * This component fetches data on the client side.
15
+ */
12
16
  export const PageRendererTanstack =
13
17
  ({ config, allPageData }: PageRendererTanstackInitializerProps) =>
14
18
  () => {