From 4500228b8e4207a3f8b43ae629ddaef44cc48103 Mon Sep 17 00:00:00 2001 From: Nathan Arthur Date: Wed, 1 Jan 2025 09:53:25 -0500 Subject: [PATCH 1/2] work on fixing vercel timeouts --- .gitignore | 1 + .../organisms/passageNavigation/bookGrid.tsx | 3 +- .../organisms/passageNavigation/bookList.tsx | 3 +- .../passageNavigation/chapterGrid.tsx | 3 +- .../organisms/passageNavigation/index.graphql | 22 ++++- .../organisms/passageNavigation/index.tsx | 20 +++-- src/containers/bible/index.graphql | 2 +- src/lib/api/fetchApi.ts | 84 +++++++++++-------- src/lib/getBibles.ts | 6 +- src/pages/[language]/bibles/index.tsx | 5 ++ 10 files changed, 100 insertions(+), 49 deletions(-) diff --git a/.gitignore b/.gitignore index 84c5d7d1e..9506d554d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ /graphql-codegen/dist **/__generated__ **/__generated__/** +.temp* # next-pwa /public/sw.js diff --git a/src/components/organisms/passageNavigation/bookGrid.tsx b/src/components/organisms/passageNavigation/bookGrid.tsx index 0e7343c6a..ee3952668 100644 --- a/src/components/organisms/passageNavigation/bookGrid.tsx +++ b/src/components/organisms/passageNavigation/bookGrid.tsx @@ -2,12 +2,11 @@ import clsx from 'clsx'; import React from 'react'; import { Book } from '.'; -import { PassageNavigationFragment } from './__generated__/index'; import styles from './bookGrid.module.scss'; import ChapterGrid, { ChapterId } from './chapterGrid'; type Props = { - books: Array; + books: Array; selectedBook: Book; selectBook: (book: Book) => void; chapterId: ChapterId; diff --git a/src/components/organisms/passageNavigation/bookList.tsx b/src/components/organisms/passageNavigation/bookList.tsx index 13efdf2ae..fb19693ad 100644 --- a/src/components/organisms/passageNavigation/bookList.tsx +++ b/src/components/organisms/passageNavigation/bookList.tsx @@ -2,12 +2,11 @@ import clsx from 'clsx'; import React from 'react'; import { Book } from '.'; -import { PassageNavigationFragment } from './__generated__/index'; import styles from './bookList.module.scss'; import ChapterGrid, { ChapterId } from './chapterGrid'; type Props = { - books: Array; + books: Array; selectedBook: Book; selectBook: (book: Book) => void; chapterId: ChapterId; diff --git a/src/components/organisms/passageNavigation/chapterGrid.tsx b/src/components/organisms/passageNavigation/chapterGrid.tsx index dd9f65ba2..4ff8b968a 100644 --- a/src/components/organisms/passageNavigation/chapterGrid.tsx +++ b/src/components/organisms/passageNavigation/chapterGrid.tsx @@ -2,10 +2,9 @@ import React from 'react'; import Link from '~components/atoms/linkWithoutPrefetch'; -import { PassageNavigationFragment } from './__generated__/index'; +import { Chapter } from '.'; import styles from './chapterGrid.module.scss'; -type Chapter = NonNullable[0]; export type ChapterId = Chapter['id'] | null; type Props = { diff --git a/src/components/organisms/passageNavigation/index.graphql b/src/components/organisms/passageNavigation/index.graphql index 84c27e73e..1494d1f23 100644 --- a/src/components/organisms/passageNavigation/index.graphql +++ b/src/components/organisms/passageNavigation/index.graphql @@ -1,4 +1,4 @@ -fragment passageNavigation on Sequence { +fragment passageNavigationBook on Sequence { id title recordings(first: 150) { @@ -9,3 +9,23 @@ fragment passageNavigation on Sequence { } } } + +fragment passageNavigationVersion on Collection { + id + title + sequences { + nodes { + ...passageNavigationBook + } + } +} + +fragment passageNavigationChapter on Recording { + id + title + canonicalPath(useFuturePath: true) + collection { + id + contentType + } +} diff --git a/src/components/organisms/passageNavigation/index.tsx b/src/components/organisms/passageNavigation/index.tsx index cdf7b9f48..d01f24826 100644 --- a/src/components/organisms/passageNavigation/index.tsx +++ b/src/components/organisms/passageNavigation/index.tsx @@ -18,20 +18,28 @@ import BibleVersionTypeLockup from '~src/components/molecules/bibleVersionTypeLo import Button from '~src/components/molecules/button'; import Dropdown from '~src/components/molecules/dropdown'; import { PlaybackContext } from '~src/components/templates/andPlaybackContext'; -import { GetAudiobibleIndexDataQuery } from '~src/containers/bible/__generated__'; import { BIBLE_BOOKS } from '~src/lib/constants'; import { getBibleAcronym } from '~src/lib/getBibleAcronym'; import { useLocalStorage } from '~src/lib/hooks/useLocalStorage'; +import { + PassageNavigationBookFragment, + PassageNavigationChapterFragment, + PassageNavigationVersionFragment, +} from './__generated__'; import BookGrid from './bookGrid'; import BookList from './bookList'; import styles from './index.module.scss'; -export type Version = NonNullable< - GetAudiobibleIndexDataQuery['collections']['nodes'] ->[0]; -export type Book = NonNullable[0]; -export type Chapter = NonNullable[0]; +// export type Version = NonNullable< +// GetAudiobibleIndexDataQuery['collections']['nodes'] +// >[0]; +// export type Book = NonNullable[0]; +// export type Chapter = NonNullable[0]; + +export type Version = PassageNavigationVersionFragment; +export type Book = PassageNavigationBookFragment; +export type Chapter = PassageNavigationChapterFragment; type Props = { versions: Array; diff --git a/src/containers/bible/index.graphql b/src/containers/bible/index.graphql index e49df25b3..8f84e5e3b 100644 --- a/src/containers/bible/index.graphql +++ b/src/containers/bible/index.graphql @@ -10,7 +10,7 @@ query getAudiobibleIndexData($language: Language!) { title sequences(first: 66, orderBy: [{ field: ID, direction: ASC }]) { nodes { - ...passageNavigation + ...passageNavigationBook } } } diff --git a/src/lib/api/fetchApi.ts b/src/lib/api/fetchApi.ts index 2eb350296..4bc6e8e43 100644 --- a/src/lib/api/fetchApi.ts +++ b/src/lib/api/fetchApi.ts @@ -1,3 +1,5 @@ +import pMemoize from 'p-memoize'; + import { getCurrentRequest } from '~lib/api/storeRequest'; import { getSessionToken } from '~lib/cookies'; import { sleep } from '~lib/sleep'; @@ -21,6 +23,53 @@ async function getResponse( }); } +const fetchJson = pMemoize( + async ({ + headers, + query, + variables, + }: { + headers: HeadersInit; + query: string; + variables: unknown; + }) => { + let res = await getResponse(headers, query, variables); + let text = await res.text(); + + if (!res.ok) { + await sleep({ ms: 10000 }); + res = await getResponse(headers, query, variables); + text = await res.text(); + } + + if (!res.ok) { + console.error({ text, res, query, variables, headers }); + throw new Error(`HTTP request failed: ${res.status} ${res.statusText}`); + } + + let json; + + try { + json = JSON.parse(text); + } catch (error) { + console.error({ error, text, res, query, variables, headers }); + throw error; + } + + if (json.errors) { + console.error({ + query, + variables, + headers, + errors: json.errors, + }); + throw json; + } + + return json.data; + }, +); + export async function fetchApi( query: string, { variables = {} } = {}, @@ -34,38 +83,5 @@ export async function fetchApi( headers['x-av-session'] = sessionToken; } - let res = await getResponse(headers, query, variables); - let text = await res.text(); - - if (!res.ok) { - await sleep({ ms: 10000 }); - res = await getResponse(headers, query, variables); - text = await res.text(); - } - - if (!res.ok) { - console.error({ text, res, query, variables, headers }); - throw new Error(`HTTP request failed: ${res.status} ${res.statusText}`); - } - - let json; - - try { - json = JSON.parse(text); - } catch (error) { - console.error({ error, text, res, query, variables, headers }); - throw error; - } - - if (json.errors) { - console.error({ - query, - variables, - headers, - errors: json.errors, - }); - throw json; - } - - return json.data; + return fetchJson({ headers, query, variables }); } diff --git a/src/lib/getBibles.ts b/src/lib/getBibles.ts index f013e20f1..184ab7d54 100644 --- a/src/lib/getBibles.ts +++ b/src/lib/getBibles.ts @@ -121,7 +121,11 @@ function concatBibles( ); } -export default async function getBibles(languageId: Language) { +export default async function getBibles(languageId: Language): Promise<{ + fcbh: ApiBible[] | null; + api: ApiBible[] | null; + all: ApiBible[]; +}> { const fcbh = await getFcbhBibles(languageId); const api = await getApiBibles(languageId); const all = concatBibles(fcbh, api); diff --git a/src/pages/[language]/bibles/index.tsx b/src/pages/[language]/bibles/index.tsx index f68a57ebe..ce87f7e83 100644 --- a/src/pages/[language]/bibles/index.tsx +++ b/src/pages/[language]/bibles/index.tsx @@ -1,3 +1,4 @@ +// import fs from 'fs'; import { GetStaticPathsResult, GetStaticPropsContext, @@ -31,6 +32,10 @@ export async function getStaticProps({ }; } + // write `all` to a file + // fs.writeFileSync('.temp.bibles.json', JSON.stringify(all, null, 2)); + // throw new Error('write `all` to a file'); + return { props: { versions: all, From 4a0db8d18d55462996413e05745a4d3774e80cba Mon Sep 17 00:00:00 2001 From: Nathan Arthur Date: Wed, 1 Jan 2025 10:15:05 -0500 Subject: [PATCH 2/2] work on fixing vercel timeouts --- .../organisms/passageNavigation/index.graphql | 24 +++++----- src/lib/getBibles.ts | 48 ++++++++----------- 2 files changed, 30 insertions(+), 42 deletions(-) diff --git a/src/components/organisms/passageNavigation/index.graphql b/src/components/organisms/passageNavigation/index.graphql index 1494d1f23..6a9081a7f 100644 --- a/src/components/organisms/passageNavigation/index.graphql +++ b/src/components/organisms/passageNavigation/index.graphql @@ -1,11 +1,19 @@ +fragment passageNavigationChapter on Recording { + id + title + canonicalPath(useFuturePath: true) + collection { + id + contentType + } +} + fragment passageNavigationBook on Sequence { id title recordings(first: 150) { nodes { - id - title - ...andMiniplayer + ...passageNavigationChapter } } } @@ -19,13 +27,3 @@ fragment passageNavigationVersion on Collection { } } } - -fragment passageNavigationChapter on Recording { - id - title - canonicalPath(useFuturePath: true) - collection { - id - contentType - } -} diff --git a/src/lib/getBibles.ts b/src/lib/getBibles.ts index 184ab7d54..e1e6243a3 100644 --- a/src/lib/getBibles.ts +++ b/src/lib/getBibles.ts @@ -1,9 +1,6 @@ -import { - CollectionContentType, - Language, - RecordingContentType, - SequenceContentType, -} from '~src/__generated__/graphql'; +import pMemoize from 'p-memoize'; + +import { CollectionContentType, Language } from '~src/__generated__/graphql'; import { BibleIndexProps } from '~src/containers/bible'; import { getAudiobibleIndexData } from '~src/containers/bible/__generated__'; import { BOOK_ID_MAP } from '~src/services/fcbh/constants'; @@ -49,23 +46,10 @@ async function transform( .bookId(bookId) .chapterNumber(bbChapter.number) .get(), - duration: bbChapter.duration, - recordingContentType: RecordingContentType.BibleChapter, - sequence: { - id: bbChapter.id, - title, - contentType: SequenceContentType.BibleBook, - }, - audioFiles: [], - videoFiles: [], - videoStreams: [], collection: { id: bible.id, - title: bible.title, contentType: CollectionContentType.BibleVersion, }, - speakers: [], - sponsor: null, }; }, ); @@ -121,14 +105,20 @@ function concatBibles( ); } -export default async function getBibles(languageId: Language): Promise<{ - fcbh: ApiBible[] | null; - api: ApiBible[] | null; - all: ApiBible[]; -}> { - const fcbh = await getFcbhBibles(languageId); - const api = await getApiBibles(languageId); - const all = concatBibles(fcbh, api); +const getBibles = pMemoize( + async ( + languageId: Language, + ): Promise<{ + fcbh: ApiBible[] | null; + api: ApiBible[] | null; + all: ApiBible[]; + }> => { + const fcbh = await getFcbhBibles(languageId); + const api = await getApiBibles(languageId); + const all = concatBibles(fcbh, api); - return { fcbh, api, all }; -} + return { fcbh, api, all }; + }, +); + +export default getBibles;