(previews = true)
| 6 | import { BLOG_INDEX_ID, BLOG_INDEX_CACHE } from './server-constants' |
| 7 | |
| 8 | export default async function getBlogIndex(previews = true) { |
| 9 | let postsTable: any = null |
| 10 | const useCache = process.env.USE_CACHE === 'true' |
| 11 | const cacheFile = `${BLOG_INDEX_CACHE}${previews ? '_previews' : ''}` |
| 12 | |
| 13 | if (useCache) { |
| 14 | try { |
| 15 | postsTable = JSON.parse(await readFile(cacheFile, 'utf8')) |
| 16 | } catch (_) { |
| 17 | /* not fatal */ |
| 18 | } |
| 19 | } |
| 20 | |
| 21 | if (!postsTable) { |
| 22 | try { |
| 23 | const data = await rpc('loadPageChunk', { |
| 24 | pageId: BLOG_INDEX_ID, |
| 25 | limit: 100, // TODO: figure out Notion's way of handling pagination |
| 26 | cursor: { stack: [] }, |
| 27 | chunkNumber: 0, |
| 28 | verticalColumns: false, |
| 29 | }) |
| 30 | |
| 31 | // Parse table with posts |
| 32 | const tableBlock = values(data.recordMap.block).find( |
| 33 | (block: any) => block.value.type === 'collection_view' |
| 34 | ) |
| 35 | |
| 36 | postsTable = await getTableData(tableBlock, true) |
| 37 | } catch (err) { |
| 38 | console.warn( |
| 39 | `Failed to load Notion posts, have you run the create-table script?` |
| 40 | ) |
| 41 | return {} |
| 42 | } |
| 43 | |
| 44 | // only get 10 most recent post's previews |
| 45 | const postsKeys = Object.keys(postsTable).splice(0, 10) |
| 46 | |
| 47 | const sema = new Sema(3, { capacity: postsKeys.length }) |
| 48 | |
| 49 | if (previews) { |
| 50 | await Promise.all( |
| 51 | postsKeys |
| 52 | .sort((a, b) => { |
| 53 | const postA = postsTable[a] |
| 54 | const postB = postsTable[b] |
| 55 | const timeA = postA.Date |
| 56 | const timeB = postB.Date |
| 57 | return Math.sign(timeB - timeA) |
| 58 | }) |
| 59 | .map(async (postKey) => { |
| 60 | await sema.acquire() |
| 61 | const post = postsTable[postKey] |
| 62 | post.preview = post.id |
| 63 | ? await getPostPreview(postsTable[postKey].id) |
| 64 | : [] |
| 65 | sema.release() |
no test coverage detected