From 3cc0870c395697b538054f1177c01c7a21a2173f Mon Sep 17 00:00:00 2001 From: Cody Olsen Date: Thu, 21 Nov 2024 03:49:34 +0100 Subject: [PATCH] test use cache stuff --- next-canary/package.json | 1 + next-canary/sanity-typegen.json | 3 + next-canary/src/app/SanityLive.tsx | 48 ++++++++++++++ next-canary/src/app/ThemeButton.tsx | 22 +++++++ next-canary/src/app/actions.ts | 17 +++++ next-canary/src/app/layout.tsx | 37 ++++++++--- next-canary/src/app/page.tsx | 99 ++++++----------------------- next-canary/src/sanity/client.ts | 8 +++ next-canary/src/sanity/fetch.ts | 19 ++++++ 9 files changed, 167 insertions(+), 87 deletions(-) create mode 100644 next-canary/sanity-typegen.json create mode 100644 next-canary/src/app/SanityLive.tsx create mode 100644 next-canary/src/app/ThemeButton.tsx create mode 100644 next-canary/src/app/actions.ts create mode 100644 next-canary/src/sanity/client.ts create mode 100644 next-canary/src/sanity/fetch.ts diff --git a/next-canary/package.json b/next-canary/package.json index 97312a4..82bee80 100644 --- a/next-canary/package.json +++ b/next-canary/package.json @@ -5,6 +5,7 @@ "scripts": { "build": "next build", "dev": "next dev --turbopack", + "typegen:generate": "sanity typegen generate", "lint": "next lint", "start": "next start" }, diff --git a/next-canary/sanity-typegen.json b/next-canary/sanity-typegen.json new file mode 100644 index 0000000..9cc38d4 --- /dev/null +++ b/next-canary/sanity-typegen.json @@ -0,0 +1,3 @@ +{ + "schema": "../studio/schema.json" +} diff --git a/next-canary/src/app/SanityLive.tsx b/next-canary/src/app/SanityLive.tsx new file mode 100644 index 0000000..f100a20 --- /dev/null +++ b/next-canary/src/app/SanityLive.tsx @@ -0,0 +1,48 @@ +'use client' + +import {client} from '@/sanity/client' +import type {LiveEventMessage, LiveEventRestart, LiveEventWelcome} from '@sanity/client' +import {CorsOriginError} from '@sanity/client' +import {useRouter} from 'next/navigation' +import {useEffect} from 'react' +import {useEffectEvent} from 'use-effect-event' +import {expireTags} from './actions' + +export function SanityLive() { + const router = useRouter() + + const handleLiveEvent = useEffectEvent( + (event: LiveEventMessage | LiveEventRestart | LiveEventWelcome) => { + if (event.type === 'welcome') { + console.info('Sanity is live with automatic invalidation of published content') + } else if (event.type === 'message') { + expireTags(event.tags).then(() => router.refresh()) + } else if (event.type === 'restart') { + router.refresh() + } + }, + ) + useEffect(() => { + const subscription = client.live.events().subscribe({ + next: (event) => { + if (event.type === 'message' || event.type === 'restart' || event.type === 'welcome') { + handleLiveEvent(event) + } + }, + error: (error: unknown) => { + if (error instanceof CorsOriginError) { + console.warn( + `Sanity Live is unable to connect to the Sanity API as the current origin - ${window.origin} - is not in the list of allowed CORS origins for this Sanity Project.`, + error.addOriginUrl && `Add it here:`, + error.addOriginUrl?.toString(), + ) + } else { + console.error(error) + } + }, + }) + return () => subscription.unsubscribe() + }, []) + + return null +} diff --git a/next-canary/src/app/ThemeButton.tsx b/next-canary/src/app/ThemeButton.tsx new file mode 100644 index 0000000..74b37f3 --- /dev/null +++ b/next-canary/src/app/ThemeButton.tsx @@ -0,0 +1,22 @@ +'use client' + +import type {SyncTag} from '@sanity/client' +import {useTransition} from 'react' +import {randomColorTheme} from './actions' + +export function ThemeButton({tags}: {tags: SyncTag[]}) { + const [pending, startTransition] = useTransition() + return ( + + ) +} diff --git a/next-canary/src/app/actions.ts b/next-canary/src/app/actions.ts new file mode 100644 index 0000000..5718f57 --- /dev/null +++ b/next-canary/src/app/actions.ts @@ -0,0 +1,17 @@ +'use server' + +import type {SyncTag} from '@sanity/client' +import {expireTag} from 'next/cache' + +export async function expireTags(tags: SyncTag[]) { + expireTag(...tags) + console.log(` expired tags: ${tags.join(', ')}`) +} + +export async function randomColorTheme(tags: SyncTag[]) { + const res = await fetch('https://lcapi-examples-api.sanity.dev/api/random-color-theme', { + method: 'PUT', + }) + expireTag(...tags) + return res.json() +} diff --git a/next-canary/src/app/layout.tsx b/next-canary/src/app/layout.tsx index f29595d..52c6f15 100644 --- a/next-canary/src/app/layout.tsx +++ b/next-canary/src/app/layout.tsx @@ -1,20 +1,41 @@ -import type {Metadata} from 'next' +import type {Viewport} from 'next' import './globals.css' +import {sanityFetch} from '@/sanity/fetch' +import {defineQuery} from 'groq' +import {SanityLive} from './SanityLive' +import {ThemeButton} from './ThemeButton' -export const metadata: Metadata = { - title: 'Create Next App', - description: 'Generated by create next app', +const THEME_QUERY = defineQuery(`*[_id == "theme"][0]{background,text}`) + +export async function generateViewport(): Promise { + const {data} = await sanityFetch({query: THEME_QUERY}) + return { + themeColor: data?.background, + } } -export default function RootLayout({ +export default async function RootLayout({ children, }: Readonly<{ children: React.ReactNode }>) { + const {data, tags} = await sanityFetch({query: THEME_QUERY}) + return ( - - - {children} + + +
+ {children} + +
+ ) diff --git a/next-canary/src/app/page.tsx b/next-canary/src/app/page.tsx index b34149c..6210a69 100644 --- a/next-canary/src/app/page.tsx +++ b/next-canary/src/app/page.tsx @@ -1,83 +1,24 @@ -import Image from 'next/image' +import {sanityFetch} from '@/sanity/fetch' +import './globals.css' +import {defineQuery} from 'groq' +import type {Metadata} from 'next' -export default function Home() { - return ( -
-
- Next.js logo -
    -
  1. - Get started by editing{' '} - - src/app/page.tsx - - . -
  2. -
  3. Save and see your changes instantly.
  4. -
+const DEMO_QUERY = defineQuery(`*[_type == "demo" && slug.current == $slug][0].title`) +const slug = 'next-canary' + +export async function generateMetadata(): Promise { + const {data} = await sanityFetch({query: DEMO_QUERY, params: {slug}}) + return { + title: data || 'Next Canary', + } +} - -
- -
+export default async function Home() { + const {data} = await sanityFetch({query: DEMO_QUERY, params: {slug}}) + + return ( +

+ {data || 'Next Canary'} +

) } diff --git a/next-canary/src/sanity/client.ts b/next-canary/src/sanity/client.ts new file mode 100644 index 0000000..6712b86 --- /dev/null +++ b/next-canary/src/sanity/client.ts @@ -0,0 +1,8 @@ +import {createClient} from '@sanity/client' + +export const client = createClient({ + projectId: 'hiomol4a', + dataset: 'lcapi', + apiVersion: '2024-09-18', + useCdn: false, +}) diff --git a/next-canary/src/sanity/fetch.ts b/next-canary/src/sanity/fetch.ts new file mode 100644 index 0000000..fc20386 --- /dev/null +++ b/next-canary/src/sanity/fetch.ts @@ -0,0 +1,19 @@ +import {type QueryParams} from '@sanity/client' +import {unstable_cacheTag as cacheTag} from 'next/cache' +import {client} from './client' + +export async function sanityFetch({ + query, + params = {}, +}: { + query: QueryString + params?: QueryParams +}) { + 'use cache' + const {result, syncTags} = await client.fetch(query, params, { + filterResponse: false, + }) + cacheTag(...(syncTags as string[])) + + return {data: result, tags: syncTags} +}