Skip to content

Commit

Permalink
fix: improve client api implementation
Browse files Browse the repository at this point in the history
fix: #25
  • Loading branch information
csr632 committed Apr 14, 2021
1 parent 9c88906 commit d154c95
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 70 deletions.
31 changes: 0 additions & 31 deletions packages/react-pages/_state_declaration.tsx

This file was deleted.

19 changes: 14 additions & 5 deletions packages/react-pages/client.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
// so that users or themes can:
// import { useStaticData } from "vite-plugin-react-pages/client"

// This module can be imported by theme, which may be optimized by vite
// so this module must be optimizable too.
// should not contains "import initialPages from '/@react-pages/pages'",
// otherwise vite will throw error when optimizing theme: Could not resolve "/@react-pages/pages"
// So this module can't import vite-pages core.
// Otherwise vite will try to optimize vite-pages core during dev.

import type { UseStaticData } from './clientTypes'

const globalObject: any = typeof window !== 'undefined' ? window : global

// users can import { useStaticData } from "vite-plugin-react-pages/client"
// access globalObject['__vite_pages_use_static_data'] lazily
export const useStaticData: UseStaticData = (...params: any[]) => {
const actualUseStaticData: any = globalObject['__vite_pages_use_static_data']
return actualUseStaticData(...params)
}

export type { Theme } from './clientTypes'
// we don't use ./_state_declaration because vite-plugin-react-pages/_state_declaration is an entry of vite optimization
export { useStaticData } from 'vite-plugin-react-pages/_state_declaration'
66 changes: 35 additions & 31 deletions packages/react-pages/src/client/state.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,18 @@
import { useMemo } from 'react'
import { useMemo, createContext } from 'react'
import { dequal } from 'dequal'
import type { SetAtom } from 'jotai/core/types'
import { atom, useAtom } from 'jotai'
import { atomFamily, useAtomValue, useUpdateAtom } from 'jotai/utils'
import type { Theme } from '../../clientTypes'

// import state setter
import {
setUseTheme,
setUsePagePaths,
setUsePageModule,
setUseStaticData,
} from 'vite-plugin-react-pages/_state_declaration'
// re-export state
export {
useTheme,
usePagePaths,
usePageModule,
useStaticData,
} from 'vite-plugin-react-pages/_state_declaration'
import type { PageLoaded, UseStaticData, Theme } from '../../clientTypes'

export let useTheme: () => Theme
export let usePagePaths: () => string[]
export let usePageModule: (path: string) => Promise<PageModule> | undefined
export let useStaticData: UseStaticData

interface PageModule {
['default']: PageLoaded
}

import initialPages from '/@react-pages/pages'
import initialTheme from '/@react-pages/theme'
Expand All @@ -39,11 +33,11 @@ if (import.meta.hot) {
})

const themeAtom = atom({ Theme: initialTheme })
setUseTheme(() => {
useTheme = () => {
const [{ Theme }, set] = useAtom(themeAtom)
setTheme = set
return Theme
})
}

let setPages: SetAtom<any> | undefined
import.meta.hot!.accept('/@react-pages/pages', (module) => {
Expand Down Expand Up @@ -115,17 +109,17 @@ if (import.meta.hot) {
return page?.staticData
})

setUsePagePaths(() => {
usePagePaths = () => {
setPages = useUpdateAtom(setPagesAtom)
return useAtomValue(pagePathsAtom)
})
}

setUsePageModule((pagePath) => {
usePageModule = (pagePath) => {
const data = useAtomValue(dataAtoms(pagePath))
return useMemo(() => data?.data(), [data])
})
}

setUseStaticData((pagePath?: string, selector?: Function) => {
useStaticData = (pagePath?: string, selector?: Function) => {
const staticData = pagePath ? staticDataAtoms(pagePath) : staticDataAtom
if (selector) {
const selection = useMemo(
Expand All @@ -135,25 +129,25 @@ if (import.meta.hot) {
return useAtomValue(selection)
}
return useAtomValue(staticData)
})
}
}

// Static mode
else {
setUseTheme(() => initialTheme)
setUsePagePaths(() => initialPagePaths)
setUsePageModule((path) => {
useTheme = () => initialTheme
usePagePaths = () => initialPagePaths
usePageModule = (path) => {
const page = initialPages[path]
return useMemo(() => page?.data(), [page])
})
setUseStaticData((path?: string, selector?: Function) => {
}
useStaticData = (path?: string, selector?: Function) => {
if (path) {
const page = initialPages[path]
const staticData = page?.staticData || {}
return selector ? selector(staticData) : staticData
}
return toStaticData(initialPages)
})
}
}

function toStaticData(pages: Record<string, any>) {
Expand All @@ -163,3 +157,13 @@ function toStaticData(pages: Record<string, any>) {
}
return staticData
}

const globalObject: any = typeof window !== 'undefined' ? window : global
if (globalObject['__vite_pages_use_static_data']) {
throw new Error(
`[vite-pages] useStaticData already exists on window. There are multiple vite-pages apps in this page. Please report this to vite-pages.`
)
} else {
// make it available to vite-plugin-react-pages/client
globalObject['__vite_pages_use_static_data'] = useStaticData
}
3 changes: 0 additions & 3 deletions packages/react-pages/src/node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ export default function pluginFactory(
'@mdx-js/react',
'jotai',
'jotai/utils',
// it is imported by both core and theme
// optimize it to make sure we only have one copy of it
'vite-plugin-react-pages/_state_declaration',
],
exclude: ['vite-plugin-react-pages'],
},
Expand Down

0 comments on commit d154c95

Please sign in to comment.