diff --git a/frameworks/nextjs/app/(builder)/api/route.ts b/frameworks/nextjs/app/(builder)/api/route.ts index 25cc5bf3..324abc08 100644 --- a/frameworks/nextjs/app/(builder)/api/route.ts +++ b/frameworks/nextjs/app/(builder)/api/route.ts @@ -1,7 +1,8 @@ import { getSupabaseAdmin } from "@/app/supabase-admin"; import { registerPageTypes } from "@/page-types"; -import { ChaiActionsRegistry, initChaiBuilderActionHandler } from "@chaibuilder/sdk/actions"; +import { ChaiActionsRegistry } from "@chaibuilder/sdk/actions"; import { SupabaseAuthActions, SupabaseStorageActions } from "@chaibuilder/sdk/actions/supabase"; +import { initChaiBuilderNextJSActionHandler } from "@/package/actions"; import { NextRequest, NextResponse } from "next/server"; registerPageTypes(); @@ -31,39 +32,8 @@ export async function POST(req: NextRequest) { } const userId = supabaseUser.data.user?.id || ""; - const actionHandler = initChaiBuilderActionHandler({ apiKey, userId }); - const response = await actionHandler(body); - // Handle streaming responses - if (response?._streamingResponse && response?._streamResult) { - const result = response._streamResult; - - if (!result?.textStream) { - return NextResponse.json({ error: "No streaming response available" }, { status: 500 }); - } - - // Create a ReadableStream for streaming response - const stream = new ReadableStream({ - async start(controller) { - const encoder = new TextEncoder(); - try { - for await (const chunk of result.textStream) { - if (chunk) { - controller.enqueue(encoder.encode(chunk)); - } - } - controller.close(); - } catch (error) { - controller.error(error); - } - }, - }); - - return new Response(stream, { - headers: { "Content-Type": "text/plain; charset=utf-8", "Cache-Control": "no-cache" }, - }); - } - - return NextResponse.json(response, { status: response.status || 200 }); + const actionHandler = initChaiBuilderNextJSActionHandler({ apiKey, userId }); + return await actionHandler(body); } catch (error) { console.error("Error handling POST request", { message: error instanceof Error ? error.message : String(error), diff --git a/frameworks/nextjs/app/(builder)/editor/editor.tsx b/frameworks/nextjs/app/(builder)/editor/editor.tsx index 5e7aac83..b191d7a3 100644 --- a/frameworks/nextjs/app/(builder)/editor/editor.tsx +++ b/frameworks/nextjs/app/(builder)/editor/editor.tsx @@ -9,6 +9,7 @@ import "@chaibuilder/sdk/styles"; import dynamic from "next/dynamic"; import { useCallback, useEffect, useState } from "react"; import { LoginScreen } from "./login"; +import { updatePages } from "@/package/actions"; const ChaiWebsiteBuilder = dynamic(() => import("@chaibuilder/sdk/pages").then((mod) => mod.ChaiWebsiteBuilder), { ssr: false, }); @@ -116,6 +117,7 @@ export default function Editor() { designTokens: true, ai: true, }} + onPublish={updatePages} currentUser={user} autoSave autoSaveActionsCount={5} diff --git a/frameworks/nextjs/app/(public)/[[...slug]]/page.tsx b/frameworks/nextjs/app/(public)/[[...slug]]/page.tsx index 7588ab40..27f08c78 100644 --- a/frameworks/nextjs/app/(public)/[[...slug]]/page.tsx +++ b/frameworks/nextjs/app/(public)/[[...slug]]/page.tsx @@ -45,7 +45,7 @@ export default async function Page({ params }: { params: Promise<{ slug: string[ pageLang: page.lang, }; return ( - + diff --git a/frameworks/nextjs/package/actions.ts b/frameworks/nextjs/package/actions.ts index b85919a8..0c016c93 100644 --- a/frameworks/nextjs/package/actions.ts +++ b/frameworks/nextjs/package/actions.ts @@ -1 +1,42 @@ +import { initChaiBuilderActionHandler } from "@chaibuilder/sdk/actions"; +import { NextResponse } from "next/server"; +import { updatePages } from "./update-pages"; + export * from "@chaibuilder/sdk/actions"; +export { updatePages }; +export function initChaiBuilderNextJSActionHandler({ apiKey, userId }: { apiKey: string, userId: string }) { + return async function (body: any) { + const actionHandler = initChaiBuilderActionHandler({ apiKey, userId }) + const response: any = await actionHandler(body) + if (response?._streamingResponse && response?._streamResult) { + const result = response._streamResult; + + if (!result?.textStream) { + return NextResponse.json({ error: "No streaming response available" }, { status: 500 }); + } + + // Create a ReadableStream for streaming response + const stream = new ReadableStream({ + async start(controller) { + const encoder = new TextEncoder(); + try { + for await (const chunk of result.textStream) { + if (chunk) { + controller.enqueue(encoder.encode(chunk)); + } + } + controller.close(); + } catch (error) { + controller.error(error); + } + }, + }); + + return new Response(stream, { + headers: { "Content-Type": "text/plain; charset=utf-8", "Cache-Control": "no-cache" }, + }); + } + + return NextResponse.json(response, { status: response.status || 200 }); + } +} \ No newline at end of file diff --git a/frameworks/nextjs/package/update-pages.ts b/frameworks/nextjs/package/update-pages.ts new file mode 100644 index 00000000..2f3e77b1 --- /dev/null +++ b/frameworks/nextjs/package/update-pages.ts @@ -0,0 +1,7 @@ +"use server" + +import { updateTag } from "next/cache"; + +export async function updatePages(tags: string[]) { + await Promise.all(tags.map((tag: string) => updateTag(tag))); +} \ No newline at end of file diff --git a/src/pages/chaibuilder-pages.tsx b/src/pages/chaibuilder-pages.tsx index 6f44c2ee..6fc5f9c9 100644 --- a/src/pages/chaibuilder-pages.tsx +++ b/src/pages/chaibuilder-pages.tsx @@ -280,6 +280,7 @@ const ChaiWebsiteBuilder = (props: ChaiWebsiteBuilderProps) => { "getLoggedInUser", "flags", "currentUser", + "onPublish" ]), ); setTimeout(() => { diff --git a/src/pages/hooks/pages/mutations.ts b/src/pages/hooks/pages/mutations.ts index 48b6e06a..200c3cd1 100644 --- a/src/pages/hooks/pages/mutations.ts +++ b/src/pages/hooks/pages/mutations.ts @@ -3,12 +3,12 @@ import { useSavePage } from "@/hooks/use-save-page"; import { ACTIONS } from "@/pages/constants/ACTIONS"; import { ERRORS } from "@/pages/constants/ERRORS"; import { useCurrentActivePage } from "@/pages/hooks/pages/use-current-page"; -import { useApiUrl } from "@/pages/hooks/project/use-builder-prop"; +import { useApiUrl, usePagesProp } from "@/pages/hooks/project/use-builder-prop"; import { usePageTypes } from "@/pages/hooks/project/use-page-types"; import { useRevisionsEnabled } from "@/pages/hooks/use-revisions-enabled"; import { useFetch } from "@/pages/hooks/utils/use-fetch"; import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { find, get } from "lodash-es"; +import { find, get, noop } from "lodash-es"; import { toast } from "sonner"; export const useCreatePage = () => { @@ -186,6 +186,7 @@ export const usePublishPages = () => { const { savePageAsync } = useSavePage(); const revisionsEnabled = useRevisionsEnabled(); const { handleQuerySync } = useQuerySync(); + const onPublish = usePagesProp('onPublish', noop) return useMutation({ mutationFn: async ({ ids }: { ids: string[] }) => { @@ -196,16 +197,17 @@ export const usePublishPages = () => { data: { ids, revisions: revisionsEnabled }, }); }, - onSuccess: (_data, { ids }) => { + onSuccess: (data, { ids }) => { // Invalidate pages query to reflect cleared changes and updated online status handleQuerySync({ type: "PUBLISH_CHANGES", data: { ids }, sync: true, }); + onPublish(data.tags) }, onError: (error) => { - console.log("##", error); + console.log(error); toast.error("Failed to publish pages."); }, }); diff --git a/src/types/common.ts b/src/types/common.ts index da13f147..9beb8ff3 100644 --- a/src/types/common.ts +++ b/src/types/common.ts @@ -56,6 +56,7 @@ export type ChaiWebsiteBuilderProps = { currentUser: LoggedInUser | null; websocket?: any; realtimeAdapter?: RealtimeAdapter; + onPublish?: (tags: string[]) => void } & Pick< ChaiBuilderEditorProps, | "onError"