one 1.1.391 → 1.1.393
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Root.cjs +25 -18
- package/dist/cjs/Root.js +7 -9
- package/dist/cjs/Root.js.map +1 -1
- package/dist/cjs/Root.native.js +44 -39
- package/dist/cjs/Root.native.js.map +2 -2
- package/dist/cjs/cli/build.cjs +21 -18
- package/dist/cjs/cli/build.js +16 -12
- package/dist/cjs/cli/build.js.map +1 -1
- package/dist/cjs/cli/build.native.js +21 -17
- package/dist/cjs/cli/build.native.js.map +2 -2
- package/dist/cjs/constants.cjs +9 -1
- package/dist/cjs/constants.js +7 -1
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/constants.native.js +9 -1
- package/dist/cjs/constants.native.js.map +2 -2
- package/dist/cjs/createApp.cjs +21 -6
- package/dist/cjs/createApp.js +23 -6
- package/dist/cjs/createApp.js.map +1 -1
- package/dist/cjs/fork/_shared.cjs +42 -0
- package/dist/cjs/fork/_shared.js +37 -0
- package/dist/cjs/fork/_shared.js.map +6 -0
- package/dist/cjs/fork/_shared.native.js +49 -0
- package/dist/cjs/fork/_shared.native.js.map +6 -0
- package/dist/cjs/fork/getPathFromState-mods.cjs +8 -10
- package/dist/cjs/fork/getPathFromState-mods.js +7 -6
- package/dist/cjs/fork/getPathFromState-mods.js.map +1 -1
- package/dist/cjs/fork/getPathFromState-mods.native.js +10 -14
- package/dist/cjs/fork/getPathFromState-mods.native.js.map +2 -2
- package/dist/cjs/fork/getPathFromState.cjs +19 -8
- package/dist/cjs/fork/getPathFromState.js +14 -6
- package/dist/cjs/fork/getPathFromState.js.map +1 -1
- package/dist/cjs/fork/getPathFromState.native.js +14 -8
- package/dist/cjs/fork/getPathFromState.native.js.map +2 -2
- package/dist/cjs/fork/getStateFromPath-mods.cjs +0 -8
- package/dist/cjs/fork/getStateFromPath-mods.js +0 -8
- package/dist/cjs/fork/getStateFromPath-mods.js.map +1 -1
- package/dist/cjs/fork/getStateFromPath-mods.native.js +0 -11
- package/dist/cjs/fork/getStateFromPath-mods.native.js.map +2 -2
- package/dist/cjs/fork/getStateFromPath.cjs +6 -5
- package/dist/cjs/fork/getStateFromPath.js +5 -5
- package/dist/cjs/fork/getStateFromPath.js.map +1 -1
- package/dist/cjs/fork/getStateFromPath.native.js +5 -5
- package/dist/cjs/fork/getStateFromPath.native.js.map +2 -2
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.js +2 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/index.native.js +3 -1
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/server/oneServe.cjs +31 -3
- package/dist/cjs/server/oneServe.js +24 -3
- package/dist/cjs/server/oneServe.js.map +1 -1
- package/dist/cjs/server/oneServe.native.js +37 -3
- package/dist/cjs/server/oneServe.native.js.map +2 -2
- package/dist/cjs/useServerHeadInsertion.cjs +40 -0
- package/dist/cjs/useServerHeadInsertion.js +32 -0
- package/dist/cjs/useServerHeadInsertion.js.map +6 -0
- package/dist/cjs/useServerHeadInsertion.native.js +38 -0
- package/dist/cjs/useServerHeadInsertion.native.js.map +6 -0
- package/dist/cjs/utils/serverContext.cjs +7 -7
- package/dist/cjs/utils/serverContext.js +7 -7
- package/dist/cjs/utils/serverContext.js.map +1 -1
- package/dist/cjs/utils/serverContext.native.js +5 -5
- package/dist/cjs/utils/serverContext.native.js.map +2 -2
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.cjs +6 -6
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.js +3 -4
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.js.map +2 -2
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.native.js +3 -4
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.native.js.map +2 -2
- package/dist/esm/Root.js +8 -9
- package/dist/esm/Root.js.map +1 -1
- package/dist/esm/Root.mjs +26 -19
- package/dist/esm/Root.mjs.map +1 -1
- package/dist/esm/Root.native.js +45 -39
- package/dist/esm/Root.native.js.map +2 -2
- package/dist/esm/cli/build.js +16 -12
- package/dist/esm/cli/build.js.map +1 -1
- package/dist/esm/cli/build.mjs +21 -18
- package/dist/esm/cli/build.mjs.map +1 -1
- package/dist/esm/cli/build.native.js +21 -17
- package/dist/esm/cli/build.native.js.map +2 -2
- package/dist/esm/constants.js +7 -1
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/constants.mjs +8 -2
- package/dist/esm/constants.mjs.map +1 -1
- package/dist/esm/constants.native.js +7 -1
- package/dist/esm/constants.native.js.map +2 -2
- package/dist/esm/createApp.js +25 -6
- package/dist/esm/createApp.js.map +1 -1
- package/dist/esm/createApp.mjs +22 -7
- package/dist/esm/createApp.mjs.map +1 -1
- package/dist/esm/fork/_shared.js +21 -0
- package/dist/esm/fork/_shared.js.map +6 -0
- package/dist/esm/fork/_shared.mjs +16 -0
- package/dist/esm/fork/_shared.mjs.map +1 -0
- package/dist/esm/fork/_shared.native.js +25 -0
- package/dist/esm/fork/_shared.native.js.map +6 -0
- package/dist/esm/fork/getPathFromState-mods.js +6 -4
- package/dist/esm/fork/getPathFromState-mods.js.map +1 -1
- package/dist/esm/fork/getPathFromState-mods.mjs +7 -8
- package/dist/esm/fork/getPathFromState-mods.mjs.map +1 -1
- package/dist/esm/fork/getPathFromState-mods.native.js +9 -11
- package/dist/esm/fork/getPathFromState-mods.native.js.map +2 -2
- package/dist/esm/fork/getPathFromState.js +4 -3
- package/dist/esm/fork/getPathFromState.js.map +1 -1
- package/dist/esm/fork/getPathFromState.mjs +4 -4
- package/dist/esm/fork/getPathFromState.mjs.map +1 -1
- package/dist/esm/fork/getPathFromState.native.js +4 -5
- package/dist/esm/fork/getPathFromState.native.js.map +2 -2
- package/dist/esm/fork/getStateFromPath-mods.js +0 -8
- package/dist/esm/fork/getStateFromPath-mods.js.map +1 -1
- package/dist/esm/fork/getStateFromPath-mods.mjs +1 -8
- package/dist/esm/fork/getStateFromPath-mods.mjs.map +1 -1
- package/dist/esm/fork/getStateFromPath-mods.native.js +0 -10
- package/dist/esm/fork/getStateFromPath-mods.native.js.map +2 -2
- package/dist/esm/fork/getStateFromPath.js +4 -4
- package/dist/esm/fork/getStateFromPath.js.map +1 -1
- package/dist/esm/fork/getStateFromPath.mjs +5 -4
- package/dist/esm/fork/getStateFromPath.mjs.map +1 -1
- package/dist/esm/fork/getStateFromPath.native.js +5 -4
- package/dist/esm/fork/getStateFromPath.native.js.map +2 -2
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.mjs +2 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +2 -0
- package/dist/esm/index.native.js.map +2 -2
- package/dist/esm/server/oneServe.js +24 -3
- package/dist/esm/server/oneServe.js.map +1 -1
- package/dist/esm/server/oneServe.mjs +31 -3
- package/dist/esm/server/oneServe.mjs.map +1 -1
- package/dist/esm/server/oneServe.native.js +37 -3
- package/dist/esm/server/oneServe.native.js.map +2 -2
- package/dist/esm/useServerHeadInsertion.js +16 -0
- package/dist/esm/useServerHeadInsertion.js.map +6 -0
- package/dist/esm/useServerHeadInsertion.mjs +15 -0
- package/dist/esm/useServerHeadInsertion.mjs.map +1 -0
- package/dist/esm/useServerHeadInsertion.native.js +16 -0
- package/dist/esm/useServerHeadInsertion.native.js.map +6 -0
- package/dist/esm/utils/serverContext.js +2 -1
- package/dist/esm/utils/serverContext.js.map +1 -1
- package/dist/esm/utils/serverContext.mjs +1 -1
- package/dist/esm/utils/serverContext.mjs.map +1 -1
- package/dist/esm/utils/serverContext.native.js +2 -1
- package/dist/esm/utils/serverContext.native.js.map +2 -2
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.js +3 -3
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.js.map +1 -1
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.mjs +3 -3
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.mjs.map +1 -1
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.native.js +3 -3
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.native.js.map +2 -2
- package/package.json +8 -8
- package/src/Root.tsx +44 -40
- package/src/cli/build.ts +17 -14
- package/src/constants.ts +8 -0
- package/src/createApp.tsx +35 -4
- package/src/fork/_shared.ts +22 -0
- package/src/fork/getPathFromState-mods.ts +22 -7
- package/src/fork/getPathFromState.ts +3 -2
- package/src/fork/getStateFromPath-mods.ts +0 -9
- package/src/fork/getStateFromPath.ts +8 -5
- package/src/index.ts +1 -0
- package/src/server/oneServe.ts +47 -4
- package/src/useServerHeadInsertion.tsx +25 -0
- package/src/utils/serverContext.tsx +3 -1
- package/src/vite/plugins/fileSystemRouterPlugin.tsx +3 -3
- package/types/Root.d.ts +1 -0
- package/types/Root.d.ts.map +1 -1
- package/types/cli/build.d.ts.map +1 -1
- package/types/constants.d.ts +2 -0
- package/types/constants.d.ts.map +1 -1
- package/types/createApp.d.ts.map +1 -1
- package/types/fork/_shared.d.ts +8 -0
- package/types/fork/_shared.d.ts.map +1 -0
- package/types/fork/getPathFromState-mods.d.ts +0 -1
- package/types/fork/getPathFromState-mods.d.ts.map +1 -1
- package/types/fork/getPathFromState.d.ts.map +1 -1
- package/types/fork/getStateFromPath-mods.d.ts +0 -1
- package/types/fork/getStateFromPath-mods.d.ts.map +1 -1
- package/types/fork/getStateFromPath.d.ts.map +1 -1
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/serve.d.ts +6 -6
- package/types/serve.d.ts.map +1 -1
- package/types/server/oneServe.d.ts.map +1 -1
- package/types/useServerHeadInsertion.d.ts +5 -0
- package/types/useServerHeadInsertion.d.ts.map +1 -0
- package/types/utils/serverContext.d.ts.map +1 -1
- package/types/vite/plugins/fileSystemRouterPlugin.d.ts.map +1 -1
package/src/Root.tsx
CHANGED
@@ -5,7 +5,7 @@ import {
|
|
5
5
|
type NavigationContainerProps,
|
6
6
|
} from '@react-navigation/native'
|
7
7
|
import { useColorScheme } from '@vxrn/universal-color-scheme'
|
8
|
-
import { useEffect, useState, type FunctionComponent, type ReactNode } from 'react'
|
8
|
+
import { useEffect, useId, useState, type FunctionComponent, type ReactNode } from 'react'
|
9
9
|
import { NavigationContainer as UpstreamNavigationContainer } from './fork/NavigationContainer'
|
10
10
|
import { getURL } from './getURL'
|
11
11
|
import { ServerLocationContext } from './router/serverLocationContext'
|
@@ -17,18 +17,16 @@ import { PreloadLinks } from './views/PreloadLinks'
|
|
17
17
|
import { RootErrorBoundary } from './views/RootErrorBoundary'
|
18
18
|
import { ScrollRestoration } from './views/ScrollRestoration'
|
19
19
|
import type { One } from './vite/types'
|
20
|
+
import { ServerRenderID } from './useServerHeadInsertion'
|
20
21
|
// import { SplashScreen } from './views/Splash'
|
21
22
|
|
22
23
|
if (typeof window !== 'undefined') {
|
23
24
|
// @ts-ignore TODO: hard coded for demo app
|
24
|
-
window.__getReactRefreshIgnoredExports = () => [
|
25
|
-
'feedCardQuery',
|
26
|
-
'feedCardReplyQuery',
|
27
|
-
'loader',
|
28
|
-
]
|
25
|
+
window.__getReactRefreshIgnoredExports = () => ['feedCardQuery', 'feedCardReplyQuery', 'loader']
|
29
26
|
}
|
30
27
|
|
31
28
|
type RootProps = Omit<InnerProps, 'context'> & {
|
29
|
+
onRenderId?: (id: string) => void
|
32
30
|
path: string
|
33
31
|
isClient?: boolean
|
34
32
|
routes: GlobbedRouteImports
|
@@ -55,7 +53,7 @@ type InnerProps = {
|
|
55
53
|
}
|
56
54
|
|
57
55
|
export function Root(props: RootProps) {
|
58
|
-
const { path, routes, routeOptions, isClient, navigationContainerProps } = props
|
56
|
+
const { path, routes, routeOptions, isClient, navigationContainerProps, onRenderId } = props
|
59
57
|
|
60
58
|
// ⚠️ <StrictMode> breaks routing!
|
61
59
|
const context = useViteRoutes(routes, routeOptions, globalThis['__vxrnVersion'])
|
@@ -75,41 +73,47 @@ export function Root(props: RootProps) {
|
|
75
73
|
throw new Error(`No root component found`)
|
76
74
|
}
|
77
75
|
|
76
|
+
const id = useId()
|
77
|
+
|
78
|
+
onRenderId?.(id)
|
79
|
+
|
78
80
|
const contents = (
|
79
81
|
// <StrictMode>
|
80
|
-
<
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
82
|
+
<ServerRenderID.Provider value={id}>
|
83
|
+
<RootErrorBoundary>
|
84
|
+
{/* for some reason warning if no key here */}
|
85
|
+
<UpstreamNavigationContainer
|
86
|
+
ref={store.navigationRef}
|
87
|
+
initialState={store.initialState}
|
88
|
+
linking={store.linking}
|
89
|
+
onUnhandledAction={onUnhandledAction}
|
90
|
+
theme={colorScheme === 'dark' ? DarkTheme : DefaultTheme}
|
91
|
+
documentTitle={{
|
92
|
+
enabled: false,
|
93
|
+
}}
|
94
|
+
{...navigationContainerProps}
|
95
|
+
>
|
96
|
+
<ServerLocationContext.Provider value={location}>
|
97
|
+
{/* <GestureHandlerRootView> */}
|
98
|
+
{/*
|
99
|
+
* Due to static rendering we need to wrap these top level views in second wrapper
|
100
|
+
* View's like <GestureHandlerRootView /> generate a <div> so if the parent wrapper
|
101
|
+
* is a HTML document, we need to ensure its inside the <body>
|
102
|
+
*/}
|
103
|
+
<>
|
104
|
+
{/* default scroll restoration to on, but users can configure it by importing and using themselves */}
|
105
|
+
<ScrollRestoration />
|
106
|
+
<Component />
|
107
|
+
|
108
|
+
{/* Users can override this by adding another StatusBar element anywhere higher in the component tree. */}
|
109
|
+
</>
|
110
|
+
{/* {!hasViewControllerBasedStatusBarAppearance && <StatusBar style="auto" />} */}
|
111
|
+
{/* </GestureHandlerRootView> */}
|
112
|
+
</ServerLocationContext.Provider>
|
113
|
+
</UpstreamNavigationContainer>
|
114
|
+
<PreloadLinks key="preload-links" />
|
115
|
+
</RootErrorBoundary>
|
116
|
+
</ServerRenderID.Provider>
|
113
117
|
// </StrictMode>
|
114
118
|
)
|
115
119
|
|
package/src/cli/build.ts
CHANGED
@@ -12,10 +12,10 @@ import {
|
|
12
12
|
build as vxrnBuild,
|
13
13
|
type ClientManifestEntry,
|
14
14
|
} from 'vxrn'
|
15
|
-
import { getLoaderPath, getPreloadPath } from '../utils/cleanUrl'
|
16
15
|
import * as constants from '../constants'
|
17
16
|
import type { RouteInfo } from '../server/createRoutesManifest'
|
18
17
|
import type { LoaderProps, RenderApp } from '../types'
|
18
|
+
import { getLoaderPath, getPreloadPath } from '../utils/cleanUrl'
|
19
19
|
import { toAbsolute } from '../utils/toAbsolute'
|
20
20
|
import { getManifest } from '../vite/getManifest'
|
21
21
|
import { loadUserOneOptions } from '../vite/loadConfig'
|
@@ -462,6 +462,21 @@ export async function build(args: {
|
|
462
462
|
preloads,
|
463
463
|
})
|
464
464
|
|
465
|
+
if (exported.loader) {
|
466
|
+
loaderData = (await exported.loader?.({ path, params })) ?? null
|
467
|
+
const code = await readFile(clientJsPath, 'utf-8')
|
468
|
+
const withLoader =
|
469
|
+
// super dirty to quickly make ssr loaders work until we have better
|
470
|
+
`
|
471
|
+
if (typeof document === 'undefined') globalThis.document = {}
|
472
|
+
` + replaceLoader({
|
473
|
+
code,
|
474
|
+
loaderData,
|
475
|
+
})
|
476
|
+
const loaderPartialPath = join(clientDir, getLoaderPath(path))
|
477
|
+
await outputFile(loaderPartialPath, withLoader)
|
478
|
+
}
|
479
|
+
|
465
480
|
// ssr, we basically skip at build-time and just compile it the js we need
|
466
481
|
if (foundRoute.type !== 'ssr') {
|
467
482
|
const loaderProps: LoaderProps = { path, params }
|
@@ -469,17 +484,6 @@ export async function build(args: {
|
|
469
484
|
// importing resetState causes issues :/
|
470
485
|
globalThis['__vxrnresetState']?.()
|
471
486
|
|
472
|
-
if (exported.loader) {
|
473
|
-
loaderData = (await exported.loader?.({ path, params })) ?? null
|
474
|
-
const code = await readFile(clientJsPath, 'utf-8')
|
475
|
-
const withLoader = replaceLoader({
|
476
|
-
code,
|
477
|
-
loaderData,
|
478
|
-
})
|
479
|
-
const loaderPartialPath = join(clientDir, getLoaderPath(path))
|
480
|
-
await outputFile(loaderPartialPath, withLoader)
|
481
|
-
}
|
482
|
-
|
483
487
|
if (foundRoute.type === 'ssg') {
|
484
488
|
const html = await render({
|
485
489
|
path,
|
@@ -497,8 +501,7 @@ export async function build(args: {
|
|
497
501
|
await outputFile(
|
498
502
|
htmlOutPath,
|
499
503
|
`<html><head>
|
500
|
-
|
501
|
-
<script>globalThis['__vxrnIsSPA'] = true</script>
|
504
|
+
${constants.SPA_HEADER_ELEMENTS}
|
502
505
|
${preloads
|
503
506
|
.map((preload) => ` <script type="module" src="${preload}"></script>`)
|
504
507
|
.join('\n')}
|
package/src/constants.ts
CHANGED
@@ -14,3 +14,11 @@ export const PRELOAD_JS_POSTFIX = `_${CACHE_KEY}_preload.js`
|
|
14
14
|
// safari insanely aggressive caching
|
15
15
|
export const VIRTUAL_SSR_CSS_ENTRY = `virtual:ssr-css.css`
|
16
16
|
export const VIRTUAL_SSR_CSS_HREF = `/@id/__x00__${VIRTUAL_SSR_CSS_ENTRY}`
|
17
|
+
|
18
|
+
export const SERVER_CONTEXT_KEY = '__one_server_context__'
|
19
|
+
|
20
|
+
export const SPA_HEADER_ELEMENTS = `
|
21
|
+
<script>globalThis['global'] = globalThis</script>
|
22
|
+
<script>globalThis['__vxrnIsSPA'] = true</script>
|
23
|
+
<script>globalThis["${SERVER_CONTEXT_KEY}"] = {}</script>
|
24
|
+
`
|
package/src/createApp.tsx
CHANGED
@@ -13,6 +13,9 @@ import {
|
|
13
13
|
SERVER_CONTEXT_POST_RENDER_STRING,
|
14
14
|
setServerContext,
|
15
15
|
} from './utils/serverContext'
|
16
|
+
import { cloneElement, useId } from 'react'
|
17
|
+
import { ensureExists } from './utils/ensureExists'
|
18
|
+
import { getServerHeadInsertions } from './useServerHeadInsertion'
|
16
19
|
|
17
20
|
export type CreateAppProps = { routes: Record<string, () => Promise<unknown>> }
|
18
21
|
|
@@ -31,8 +34,18 @@ export function createApp(options: CreateAppProps) {
|
|
31
34
|
css,
|
32
35
|
})
|
33
36
|
|
37
|
+
let renderId: string | undefined
|
38
|
+
|
34
39
|
const App = () => {
|
35
|
-
return
|
40
|
+
return (
|
41
|
+
<Root
|
42
|
+
onRenderId={(id) => {
|
43
|
+
renderId = id
|
44
|
+
}}
|
45
|
+
routes={options.routes}
|
46
|
+
{...props}
|
47
|
+
/>
|
48
|
+
)
|
36
49
|
}
|
37
50
|
|
38
51
|
AppRegistry.registerComponent('App', () => App)
|
@@ -48,11 +61,29 @@ export function createApp(options: CreateAppProps) {
|
|
48
61
|
})
|
49
62
|
|
50
63
|
try {
|
64
|
+
const extraHeadElements: React.ReactElement[] = []
|
65
|
+
|
51
66
|
const styleTag = Application.getStyleElement({ nonce: process.env.ONE_NONCE })
|
52
67
|
if (styleTag) {
|
53
|
-
|
54
|
-
|
55
|
-
|
68
|
+
extraHeadElements.push(styleTag)
|
69
|
+
}
|
70
|
+
|
71
|
+
ensureExists(renderId)
|
72
|
+
const insertions = getServerHeadInsertions(renderId)
|
73
|
+
if (insertions) {
|
74
|
+
for (const insertion of insertions) {
|
75
|
+
const out = insertion()
|
76
|
+
if (out) {
|
77
|
+
extraHeadElements.push(out)
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
if (extraHeadElements.length) {
|
83
|
+
const extraHeadHTML = ReactDOMServer.renderToStaticMarkup(<>{extraHeadElements}</>)
|
84
|
+
|
85
|
+
if (extraHeadHTML) {
|
86
|
+
html = html.replace(`</head>`, `${extraHeadHTML}</head>`)
|
56
87
|
}
|
57
88
|
}
|
58
89
|
} catch (err) {
|
@@ -0,0 +1,22 @@
|
|
1
|
+
/**
|
2
|
+
* Shared utilities for modifications in the fork.
|
3
|
+
*/
|
4
|
+
|
5
|
+
export const getParamName = (pattern: string) => pattern.replace(/^[:*]/, '').replace(/\?$/, '')
|
6
|
+
|
7
|
+
export function getParamValue(p: string, value: string) {
|
8
|
+
if (p.startsWith('*')) {
|
9
|
+
const values = value.split('/').filter((v) => v !== '')
|
10
|
+
return values.length === 0 && p.endsWith('?') ? undefined : values
|
11
|
+
}
|
12
|
+
|
13
|
+
return value
|
14
|
+
}
|
15
|
+
|
16
|
+
export function isDynamicPart(p: string) {
|
17
|
+
return p.length > 1 && (p.startsWith(':') || p.startsWith('*'))
|
18
|
+
}
|
19
|
+
|
20
|
+
export function replacePart(p: string) {
|
21
|
+
return p.replace(/^[:*]/, '').replace(/\?$/, '')
|
22
|
+
}
|
@@ -7,6 +7,7 @@
|
|
7
7
|
import type { Route } from '@react-navigation/core'
|
8
8
|
|
9
9
|
import { matchDeepDynamicRouteName, matchDynamicName, matchGroupName } from '../router/matchers'
|
10
|
+
import { getParamName } from './_shared'
|
10
11
|
|
11
12
|
export type AdditionalOptions = {
|
12
13
|
preserveDynamicRoutes?: boolean
|
@@ -33,12 +34,12 @@ export function getPathWithConventionsCollapsed({
|
|
33
34
|
params: Record<string, any>
|
34
35
|
initialRouteName?: string
|
35
36
|
}) {
|
36
|
-
const segments = pattern.split('/')
|
37
|
-
|
37
|
+
const segments = pattern.split('/')
|
38
38
|
return segments
|
39
39
|
.map((p, i) => {
|
40
40
|
const name = getParamName(p)
|
41
41
|
|
42
|
+
// We don't know what to show for wildcard patterns
|
42
43
|
// Showing the route name seems ok, though whatever we show here will be incorrect
|
43
44
|
// Since the page doesn't actually exist
|
44
45
|
if (p.startsWith('*')) {
|
@@ -61,11 +62,21 @@ export function getPathWithConventionsCollapsed({
|
|
61
62
|
return ''
|
62
63
|
}
|
63
64
|
|
65
|
+
if (i === 0) {
|
66
|
+
// This can occur when a wildcard matches all routes and the given path was `/`.
|
67
|
+
return route
|
68
|
+
}
|
69
|
+
|
64
70
|
if (p === '*not-found') {
|
65
71
|
return ''
|
66
72
|
}
|
67
|
-
|
73
|
+
// remove existing segments from route.path and return it
|
74
|
+
// this is used for nested wildcard routes. Without this, the path would add
|
75
|
+
// all nested segments to the beginning of the wildcard route.
|
68
76
|
return route.name
|
77
|
+
?.split('/')
|
78
|
+
.slice(i + 1)
|
79
|
+
.join('/')
|
69
80
|
}
|
70
81
|
|
71
82
|
// If the path has a pattern for a param, put the param in the path
|
@@ -79,6 +90,7 @@ export function getPathWithConventionsCollapsed({
|
|
79
90
|
return
|
80
91
|
}
|
81
92
|
|
93
|
+
// return params[name]
|
82
94
|
return (shouldEncodeURISegment ? encodeURISegment(value) : value) ?? 'undefined'
|
83
95
|
}
|
84
96
|
|
@@ -92,21 +104,24 @@ export function getPathWithConventionsCollapsed({
|
|
92
104
|
if (segmentMatchesConvention(initialRouteName)) {
|
93
105
|
return ''
|
94
106
|
}
|
107
|
+
|
95
108
|
return shouldEncodeURISegment
|
96
|
-
?
|
109
|
+
? encodeURIComponentPreservingBrackets(initialRouteName)
|
97
110
|
: initialRouteName
|
98
111
|
}
|
99
112
|
}
|
100
113
|
return ''
|
101
114
|
}
|
102
|
-
|
103
|
-
return shouldEncodeURISegment ?
|
115
|
+
|
116
|
+
return shouldEncodeURISegment ? encodeURIComponentPreservingBrackets(p) : p
|
104
117
|
})
|
105
118
|
.map((v) => v ?? '')
|
106
119
|
.join('/')
|
107
120
|
}
|
108
121
|
|
109
|
-
|
122
|
+
function encodeURIComponentPreservingBrackets(str: string) {
|
123
|
+
return encodeURIComponent(str).replace(/%5B/g, '[').replace(/%5D/g, ']')
|
124
|
+
}
|
110
125
|
|
111
126
|
export function appendBaseUrl(
|
112
127
|
path: string,
|
@@ -13,6 +13,7 @@ import {
|
|
13
13
|
appendBaseUrl,
|
14
14
|
type AdditionalOptions,
|
15
15
|
} from './getPathFromState-mods'
|
16
|
+
import * as sharedModUtils from './_shared'
|
16
17
|
// @modified - end
|
17
18
|
|
18
19
|
import type { NavigationState, PartialState, Route } from '@react-navigation/routers'
|
@@ -198,10 +199,10 @@ export function getPathDataFromState<ParamList extends {}>(
|
|
198
199
|
|
199
200
|
pattern
|
200
201
|
?.split('/')
|
201
|
-
.filter((p) =>
|
202
|
+
.filter((p) => sharedModUtils.isDynamicPart(p)) // @modified
|
202
203
|
// eslint-disable-next-line no-loop-func
|
203
204
|
.forEach((p) => {
|
204
|
-
const name = getParamName(p)
|
205
|
+
const name = sharedModUtils.getParamName(p) // @modified: use our customized `getParamName`
|
205
206
|
|
206
207
|
// Remove the params present in the pattern since we'll only use the rest for query string
|
207
208
|
if (focusedParams) {
|
@@ -291,15 +291,6 @@ export function decodeURIComponentSafe(str: string) {
|
|
291
291
|
}
|
292
292
|
}
|
293
293
|
|
294
|
-
export function getParamValue(p: string, value: string) {
|
295
|
-
if (p.startsWith('*')) {
|
296
|
-
const values = value.split('/').filter((v) => v !== '')
|
297
|
-
return values.length === 0 && p.endsWith('?') ? undefined : values
|
298
|
-
}
|
299
|
-
|
300
|
-
return value
|
301
|
-
}
|
302
|
-
|
303
294
|
/**
|
304
295
|
* In One, the params are available at all levels of the routing config
|
305
296
|
*/
|
@@ -20,13 +20,13 @@ import {
|
|
20
20
|
createConfigItemAdditionalProperties,
|
21
21
|
decodeURIComponentSafe,
|
22
22
|
formatRegexPattern,
|
23
|
-
getParamValue,
|
24
23
|
getRouteConfigSorter,
|
25
24
|
getUrlWithReactNavigationConcessions,
|
26
25
|
matchForEmptyPath,
|
27
26
|
parseQueryParamsExtended,
|
28
27
|
populateParams,
|
29
28
|
} from './getStateFromPath-mods'
|
29
|
+
import { getParamValue, isDynamicPart, replacePart } from './_shared'
|
30
30
|
|
31
31
|
type Options<ParamList extends {}> = {
|
32
32
|
path?: string
|
@@ -263,7 +263,7 @@ function getNormalizedConfigs(
|
|
263
263
|
createNormalizedConfigs(key, screens as PathConfigMap<object>, [], initialRoutes, [])
|
264
264
|
)
|
265
265
|
)
|
266
|
-
|
266
|
+
/* @modified - start */
|
267
267
|
// .sort((a, b) => {
|
268
268
|
// // Sort config so that:
|
269
269
|
// // - the most exhaustive ones are always at the beginning
|
@@ -391,7 +391,7 @@ const matchAgainstConfigs = (remaining: string, configs: RouteConfig[]) => {
|
|
391
391
|
matchedParams: Record<string, Record<string, string>> // The extracted params
|
392
392
|
}>(
|
393
393
|
(acc, p, index) => {
|
394
|
-
if (!p
|
394
|
+
if (!isDynamicPart(p) /* @modified */) {
|
395
395
|
return acc
|
396
396
|
}
|
397
397
|
|
@@ -437,7 +437,7 @@ const matchAgainstConfigs = (remaining: string, configs: RouteConfig[]) => {
|
|
437
437
|
const params = normalizedPath
|
438
438
|
?.split('/')
|
439
439
|
.reduce<Record<string, unknown>>((acc, p, index) => {
|
440
|
-
if (!p
|
440
|
+
if (!isDynamicPart(p) /* @modified */) {
|
441
441
|
return acc
|
442
442
|
}
|
443
443
|
|
@@ -450,7 +450,10 @@ const matchAgainstConfigs = (remaining: string, configs: RouteConfig[]) => {
|
|
450
450
|
// @modified - end
|
451
451
|
|
452
452
|
if (value) {
|
453
|
-
|
453
|
+
// @modified - start
|
454
|
+
// const key = p.replace(/^:/, '').replace(/\?$/, '')
|
455
|
+
const key = replacePart(p)
|
456
|
+
// @modified - end
|
454
457
|
acc[key] = routeConfig?.parse?.[key] ? routeConfig.parse[key](value as any) : value
|
455
458
|
}
|
456
459
|
|
package/src/index.ts
CHANGED
package/src/server/oneServe.ts
CHANGED
@@ -3,7 +3,7 @@ import type { BlankEnv } from 'hono/types'
|
|
3
3
|
import { extname, join } from 'node:path'
|
4
4
|
import { getServerEntry } from 'vxrn/serve'
|
5
5
|
import { getPathFromLoaderPath } from '../utils/cleanUrl'
|
6
|
-
import { LOADER_JS_POSTFIX_UNCACHED } from '../constants'
|
6
|
+
import { LOADER_JS_POSTFIX_REGEX, LOADER_JS_POSTFIX_UNCACHED } from '../constants'
|
7
7
|
import { compileManifest, getURLfromRequestURL, type RequestHandlers } from '../createHandleRequest'
|
8
8
|
import type { RenderAppProps } from '../types'
|
9
9
|
import { toAbsolute } from '../utils/toAbsolute'
|
@@ -71,6 +71,11 @@ export async function oneServe(
|
|
71
71
|
return await import(toAbsolute(route.contextKey))
|
72
72
|
},
|
73
73
|
|
74
|
+
async handleLoader({ request, route, url, loaderProps }) {
|
75
|
+
// TODO this shouldn't be in dist/client right? we should build a dist/server version?
|
76
|
+
return await import(toAbsolute(join('./', 'dist/client', route.file)))
|
77
|
+
},
|
78
|
+
|
74
79
|
async handlePage({ route, url, loaderProps }) {
|
75
80
|
const buildInfo = routeToBuildInfo[route.file]
|
76
81
|
|
@@ -125,7 +130,7 @@ url: ${url}`)
|
|
125
130
|
return async (context, next) => {
|
126
131
|
// assets we ignore
|
127
132
|
if (extname(context.req.path)) {
|
128
|
-
return
|
133
|
+
return next()
|
129
134
|
}
|
130
135
|
|
131
136
|
try {
|
@@ -133,6 +138,7 @@ url: ${url}`)
|
|
133
138
|
const url = getURLfromRequestURL(request)
|
134
139
|
|
135
140
|
const response = await (() => {
|
141
|
+
// this handles the ...rest style routes
|
136
142
|
// where to put this best? can likely be after some of the switch?
|
137
143
|
if (url.pathname.endsWith(LOADER_JS_POSTFIX_UNCACHED)) {
|
138
144
|
const originalUrl = getPathFromLoaderPath(url.pathname)
|
@@ -182,13 +188,13 @@ url: ${url}`)
|
|
182
188
|
return response as Response
|
183
189
|
}
|
184
190
|
|
185
|
-
return
|
191
|
+
return next()
|
186
192
|
}
|
187
193
|
} catch (err) {
|
188
194
|
console.error(` [one] Error handling request: ${(err as any)['stack']}`)
|
189
195
|
}
|
190
196
|
|
191
|
-
return
|
197
|
+
return next()
|
192
198
|
}
|
193
199
|
}
|
194
200
|
|
@@ -205,4 +211,41 @@ url: ${url}`)
|
|
205
211
|
for (const route of compiledManifest.pageRoutes) {
|
206
212
|
app.get(route.honoPath, createHonoHandler(route))
|
207
213
|
}
|
214
|
+
|
215
|
+
// TODO make this inside each page, need to make loader urls just be REGULAR_URL + loaderpostfix
|
216
|
+
app.get('*', async (c, next) => {
|
217
|
+
if (
|
218
|
+
c.req.path.endsWith(LOADER_JS_POSTFIX_UNCACHED) &&
|
219
|
+
// if it includes /assets its a static loader
|
220
|
+
!c.req.path.includes('/assets/')
|
221
|
+
) {
|
222
|
+
const request = c.req.raw
|
223
|
+
const url = getURLfromRequestURL(request)
|
224
|
+
const originalUrl = getPathFromLoaderPath(c.req.path)
|
225
|
+
|
226
|
+
for (const route of compiledManifest.pageRoutes) {
|
227
|
+
if (route.file === '') {
|
228
|
+
// ignore not found route
|
229
|
+
continue
|
230
|
+
}
|
231
|
+
|
232
|
+
if (!route.compiledRegex.test(originalUrl)) {
|
233
|
+
continue
|
234
|
+
}
|
235
|
+
|
236
|
+
// for now just change this
|
237
|
+
route.file = c.req.path
|
238
|
+
|
239
|
+
const finalUrl = new URL(originalUrl, url.origin)
|
240
|
+
try {
|
241
|
+
return resolveLoaderRoute(requestHandlers, request, finalUrl, route)
|
242
|
+
} catch (err) {
|
243
|
+
console.error(`Error running loader: ${err}`)
|
244
|
+
return next()
|
245
|
+
}
|
246
|
+
}
|
247
|
+
}
|
248
|
+
|
249
|
+
return next()
|
250
|
+
})
|
208
251
|
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import { createContext, useContext, useId } from 'react'
|
2
|
+
|
3
|
+
export type ServerHeadInsertionCallback = () => React.ReactElement
|
4
|
+
|
5
|
+
const ServerHeadInsertions: Record<
|
6
|
+
string,
|
7
|
+
undefined | Record<string, ServerHeadInsertionCallback>
|
8
|
+
> = {}
|
9
|
+
|
10
|
+
export const getServerHeadInsertions = (id: string) => {
|
11
|
+
if (ServerHeadInsertions[id]) {
|
12
|
+
return Object.values(ServerHeadInsertions[id])
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
export const ServerRenderID = createContext('')
|
17
|
+
|
18
|
+
export const useServerHeadInsertion = (callback: ServerHeadInsertionCallback) => {
|
19
|
+
if (typeof window == 'undefined') {
|
20
|
+
const insertionID = useId()
|
21
|
+
const id = useContext(ServerRenderID)
|
22
|
+
ServerHeadInsertions[id] ||= {}
|
23
|
+
ServerHeadInsertions[id][insertionID] = callback
|
24
|
+
}
|
25
|
+
}
|
@@ -1,3 +1,5 @@
|
|
1
|
+
import { SERVER_CONTEXT_KEY } from '../constants'
|
2
|
+
|
1
3
|
type ServerContext = {
|
2
4
|
css?: string[]
|
3
5
|
postRenderData?: any
|
@@ -9,7 +11,7 @@ type ServerContext = {
|
|
9
11
|
type MaybeServerContext = null | ServerContext
|
10
12
|
|
11
13
|
export const SERVER_CONTEXT_POST_RENDER_STRING = `_one_post_render_data_`
|
12
|
-
|
14
|
+
|
13
15
|
const isClient = typeof document !== 'undefined'
|
14
16
|
|
15
17
|
let serverContext: MaybeServerContext = globalThis[SERVER_CONTEXT_KEY] || null
|
@@ -3,16 +3,17 @@ import { debounce } from 'perfect-debounce'
|
|
3
3
|
import type { Connect, Plugin, ViteDevServer } from 'vite'
|
4
4
|
import { createServerModuleRunner } from 'vite'
|
5
5
|
import type { ModuleRunner } from 'vite/module-runner'
|
6
|
+
import { SPA_HEADER_ELEMENTS } from '../../constants'
|
6
7
|
import { createHandleRequest } from '../../createHandleRequest'
|
7
8
|
import type { RenderAppProps } from '../../types'
|
8
9
|
import { isResponse } from '../../utils/isResponse'
|
9
10
|
import { isStatusRedirect } from '../../utils/isStatus'
|
10
11
|
import { promiseWithResolvers } from '../../utils/promiseWithResolvers'
|
12
|
+
import { setServerContext } from '../../utils/serverContext'
|
11
13
|
import { LoaderDataCache } from '../../vite/constants'
|
12
14
|
import { replaceLoader } from '../../vite/replaceLoader'
|
13
15
|
import type { One } from '../../vite/types'
|
14
16
|
import { virtalEntryIdClient, virtualEntryId } from './virtualEntryConstants'
|
15
|
-
import { setServerContext } from '../../utils/serverContext'
|
16
17
|
|
17
18
|
// server needs better dep optimization
|
18
19
|
const USE_SERVER_ENV = false //!!process.env.USE_SERVER_ENV
|
@@ -37,8 +38,7 @@ export function createFileSystemRouterPlugin(options: One.PluginOptions): Plugin
|
|
37
38
|
if (route.type === 'spa') {
|
38
39
|
// render just the layouts? route.layouts
|
39
40
|
return `<html><head>
|
40
|
-
|
41
|
-
<script>globalThis['__vxrnIsSPA'] = true</script>
|
41
|
+
${SPA_HEADER_ELEMENTS}
|
42
42
|
<script type="module">
|
43
43
|
import { injectIntoGlobalHook } from "/@react-refresh";
|
44
44
|
injectIntoGlobalHook(window);
|
package/types/Root.d.ts
CHANGED
@@ -3,6 +3,7 @@ import { type FunctionComponent, type ReactNode } from 'react';
|
|
3
3
|
import type { GlobbedRouteImports } from './types';
|
4
4
|
import type { One } from './vite/types';
|
5
5
|
type RootProps = Omit<InnerProps, 'context'> & {
|
6
|
+
onRenderId?: (id: string) => void;
|
6
7
|
path: string;
|
7
8
|
isClient?: boolean;
|
8
9
|
routes: GlobbedRouteImports;
|
package/types/Root.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"Root.d.ts","sourceRoot":"","sources":["../src/Root.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,wBAAwB,EAC9B,MAAM,0BAA0B,CAAA;AAEjC,OAAO,
|
1
|
+
{"version":3,"file":"Root.d.ts","sourceRoot":"","sources":["../src/Root.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,wBAAwB,EAC9B,MAAM,0BAA0B,CAAA;AAEjC,OAAO,EAA8B,KAAK,iBAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAM1F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAKlD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AASvC,KAAK,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,GAAG;IAC7C,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,EAAE,mBAAmB,CAAA;IAC3B,YAAY,CAAC,EAAE,GAAG,CAAC,YAAY,CAAA;CAChC,CAAA;AAED,KAAK,UAAU,GAAG;IAChB,OAAO,EAAE,GAAG,CAAC,YAAY,CAAA;IACzB,QAAQ,CAAC,EAAE,GAAG,CAAA;IACd,OAAO,CAAC,EAAE,iBAAiB,CAAC;QAAE,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAA;IACpD,wBAAwB,CAAC,EAAE,wBAAwB,GAAG;QACpD,KAAK,CAAC,EAAE;YACN,IAAI,EAAE,OAAO,CAAA;YACb,MAAM,EAAE;gBACN,OAAO,EAAE,MAAM,CAAA;gBACf,UAAU,EAAE,MAAM,CAAA;gBAClB,IAAI,EAAE,MAAM,CAAA;gBACZ,IAAI,EAAE,MAAM,CAAA;gBACZ,MAAM,EAAE,MAAM,CAAA;gBACd,YAAY,EAAE,MAAM,CAAA;aACrB,CAAA;SACF,CAAA;KACF,CAAA;CACF,CAAA;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,kDAiFpC"}
|
package/types/cli/build.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"AA+BA,wBAAsB,KAAK,CAAC,IAAI,EAAE;IAChC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"AA+BA,wBAAsB,KAAK,CAAC,IAAI,EAAE;IAChC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,iBAylBA"}
|
package/types/constants.d.ts
CHANGED
@@ -9,4 +9,6 @@ export declare const LOADER_JS_POSTFIX: string;
|
|
9
9
|
export declare const PRELOAD_JS_POSTFIX: string;
|
10
10
|
export declare const VIRTUAL_SSR_CSS_ENTRY = "virtual:ssr-css.css";
|
11
11
|
export declare const VIRTUAL_SSR_CSS_HREF = "/@id/__x00__virtual:ssr-css.css";
|
12
|
+
export declare const SERVER_CONTEXT_KEY = "__one_server_context__";
|
13
|
+
export declare const SPA_HEADER_ELEMENTS = "\n <script>globalThis['global'] = globalThis</script>\n <script>globalThis['__vxrnIsSPA'] = true</script>\n <script>globalThis[\"__one_server_context__\"] = {}</script>\n";
|
12
14
|
//# sourceMappingURL=constants.d.ts.map
|